]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- removed upstreamed dm-crypt patches
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
7e9cd9fe 1aufs3.x-rcN kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
7e9cd9fe 4index ec35851..a059d62 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
7e9cd9fe
AM
7@@ -218,6 +218,7 @@ source "fs/sysv/Kconfig"
8 source "fs/ufs/Kconfig"
7f207e10 9 source "fs/exofs/Kconfig"
1716fcea 10 source "fs/f2fs/Kconfig"
7f207e10
AM
11+source "fs/aufs/Kconfig"
12
13 endif # MISC_FILESYSTEMS
14
15diff --git a/fs/Makefile b/fs/Makefile
7e9cd9fe 16index a88ac48..162500e 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
c1595e42 19@@ -126,3 +126,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
7e9cd9fe 25index 68ceb97..0352fa4 100644
c06a8ce3
AM
26--- a/include/uapi/linux/Kbuild
27+++ b/include/uapi/linux/Kbuild
7e9cd9fe 28@@ -58,6 +58,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
7e9cd9fe 36aufs3.x-rcN base patch
7f207e10 37
c1595e42 38diff --git a/MAINTAINERS b/MAINTAINERS
7e9cd9fe 39index 1de6afa..082a271 100644
c1595e42
JR
40--- a/MAINTAINERS
41+++ b/MAINTAINERS
7e9cd9fe 42@@ -1865,6 +1865,20 @@ 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
51+T: git://git.code.sf.net/p/aufs/aufs3-linux
52+T: git://github.com/sfjro/aufs3-linux.git
53+S: Supported
54+F: Documentation/filesystems/aufs/
55+F: Documentation/ABI/testing/debugfs-aufs
56+F: Documentation/ABI/testing/sysfs-aufs
57+F: fs/aufs/
58+F: include/uapi/linux/aufs_type.h
59+
60 AUXILIARY DISPLAY DRIVERS
61 M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
62 W: http://miguelojeda.es/auxdisplay.htm
392086de 63diff --git a/drivers/block/loop.c b/drivers/block/loop.c
7e9cd9fe 64index d1f168b..a0da519 100644
392086de
AM
65--- a/drivers/block/loop.c
66+++ b/drivers/block/loop.c
7e9cd9fe 67@@ -592,6 +592,24 @@ static inline int is_loop_device(struct file *file)
392086de
AM
68 return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
69 }
70
71+/*
72+ * for AUFS
73+ * no get/put for file.
74+ */
75+struct file *loop_backing_file(struct super_block *sb)
76+{
77+ struct file *ret;
78+ struct loop_device *l;
79+
80+ ret = NULL;
81+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
82+ l = sb->s_bdev->bd_disk->private_data;
83+ ret = l->lo_backing_file;
84+ }
85+ return ret;
86+}
87+EXPORT_SYMBOL(loop_backing_file);
88+
89 /* loop sysfs attributes */
90
91 static ssize_t loop_attr_show(struct device *dev, char *page,
c1595e42 92diff --git a/fs/dcache.c b/fs/dcache.c
7e9cd9fe 93index c71e373..b93a9f2 100644
c1595e42
JR
94--- a/fs/dcache.c
95+++ b/fs/dcache.c
7e9cd9fe 96@@ -1130,7 +1130,7 @@ enum d_walk_ret {
c1595e42
JR
97 *
98 * The @enter() and @finish() callbacks are called with d_lock held.
99 */
100-static void d_walk(struct dentry *parent, void *data,
101+void d_walk(struct dentry *parent, void *data,
102 enum d_walk_ret (*enter)(void *, struct dentry *),
103 void (*finish)(void *))
104 {
7f207e10 105diff --git a/fs/splice.c b/fs/splice.c
7e9cd9fe 106index 7968da9..beb9993 100644
7f207e10
AM
107--- a/fs/splice.c
108+++ b/fs/splice.c
7e9cd9fe 109@@ -1099,8 +1099,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
110 /*
111 * Attempt to initiate a splice from pipe to file.
112 */
113-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
114- loff_t *ppos, size_t len, unsigned int flags)
115+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
116+ loff_t *ppos, size_t len, unsigned int flags)
117 {
118 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
119 loff_t *, size_t, unsigned int);
7e9cd9fe 120@@ -1116,9 +1116,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
121 /*
122 * Attempt to initiate a splice from a file to a pipe.
123 */
124-static long do_splice_to(struct file *in, loff_t *ppos,
125- struct pipe_inode_info *pipe, size_t len,
126- unsigned int flags)
127+long do_splice_to(struct file *in, loff_t *ppos,
128+ struct pipe_inode_info *pipe, size_t len,
129+ unsigned int flags)
130 {
131 ssize_t (*splice_read)(struct file *, loff_t *,
132 struct pipe_inode_info *, size_t, unsigned int);
1e00d052 133diff --git a/include/linux/splice.h b/include/linux/splice.h
076b876e 134index da2751d..2e0fca6 100644
1e00d052
AM
135--- a/include/linux/splice.h
136+++ b/include/linux/splice.h
076b876e 137@@ -83,4 +83,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
138 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
139
140 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
1e00d052
AM
141+
142+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
143+ loff_t *ppos, size_t len, unsigned int flags);
144+extern long do_splice_to(struct file *in, loff_t *ppos,
145+ struct pipe_inode_info *pipe, size_t len,
146+ unsigned int flags);
147 #endif
7e9cd9fe 148aufs3.x-rcN mmap patch
fb47a38f
JR
149
150diff --git a/fs/buffer.c b/fs/buffer.c
c1595e42 151index 20805db..363569f 100644
fb47a38f
JR
152--- a/fs/buffer.c
153+++ b/fs/buffer.c
c1595e42 154@@ -2450,7 +2450,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
fb47a38f
JR
155 * Update file times before taking page lock. We may end up failing the
156 * fault so this update may be superfluous but who really cares...
157 */
158- file_update_time(vma->vm_file);
159+ vma_file_update_time(vma);
160
161 ret = __block_page_mkwrite(vma, vmf, get_block);
162 sb_end_pagefault(sb);
c1595e42 163diff --git a/fs/proc/base.c b/fs/proc/base.c
2000de60 164index 3f3d7ae..426bcc7 100644
c1595e42
JR
165--- a/fs/proc/base.c
166+++ b/fs/proc/base.c
167@@ -1735,7 +1735,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
168 down_read(&mm->mmap_sem);
169 vma = find_exact_vma(mm, vm_start, vm_end);
170 if (vma && vma->vm_file) {
171- *path = vma->vm_file->f_path;
172+ *path = vma_pr_or_file(vma)->f_path;
173 path_get(path);
174 rc = 0;
175 }
fb47a38f 176diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
076b876e 177index d4a3574..1397181 100644
fb47a38f
JR
178--- a/fs/proc/nommu.c
179+++ b/fs/proc/nommu.c
076b876e 180@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
fb47a38f
JR
181 file = region->vm_file;
182
183 if (file) {
184- struct inode *inode = file_inode(region->vm_file);
185+ struct inode *inode;
076b876e 186+
fb47a38f
JR
187+ file = vmr_pr_or_file(region);
188+ inode = file_inode(file);
189 dev = inode->i_sb->s_dev;
190 ino = inode->i_ino;
191 }
192diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
7e9cd9fe 193index 6dee68d..9afa35d 100644
fb47a38f
JR
194--- a/fs/proc/task_mmu.c
195+++ b/fs/proc/task_mmu.c
7e9cd9fe 196@@ -279,7 +279,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
fb47a38f
JR
197 const char *name = NULL;
198
199 if (file) {
200- struct inode *inode = file_inode(vma->vm_file);
201+ struct inode *inode;
076b876e 202+
fb47a38f
JR
203+ file = vma_pr_or_file(vma);
204+ inode = file_inode(file);
205 dev = inode->i_sb->s_dev;
206 ino = inode->i_ino;
207 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
7e9cd9fe 208@@ -1479,7 +1482,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
076b876e
AM
209 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
210 struct vm_area_struct *vma = v;
211 struct numa_maps *md = &numa_priv->md;
212- struct file *file = vma->vm_file;
213+ struct file *file = vma_pr_or_file(vma);
076b876e 214 struct mm_struct *mm = vma->vm_mm;
7e9cd9fe
AM
215 struct mm_walk walk = {
216 .hugetlb_entry = gather_hugetlb_stats,
fb47a38f 217diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
c1595e42 218index 599ec2e..de6cd6e 100644
fb47a38f
JR
219--- a/fs/proc/task_nommu.c
220+++ b/fs/proc/task_nommu.c
c1595e42 221@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
fb47a38f
JR
222 file = vma->vm_file;
223
224 if (file) {
225- struct inode *inode = file_inode(vma->vm_file);
226+ struct inode *inode;
076b876e 227+
fb47a38f
JR
228+ file = vma_pr_or_file(file);
229+ inode = file_inode(file);
230 dev = inode->i_sb->s_dev;
231 ino = inode->i_ino;
232 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
233diff --git a/include/linux/mm.h b/include/linux/mm.h
7e9cd9fe 234index 47a9392..60bc29c 100644
fb47a38f
JR
235--- a/include/linux/mm.h
236+++ b/include/linux/mm.h
7e9cd9fe 237@@ -1254,6 +1254,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
fb47a38f
JR
238 }
239 #endif
240
076b876e
AM
241+#ifdef CONFIG_MMU
242+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
243+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
244+ int);
245+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
246+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
fb47a38f 247+
fb47a38f
JR
248+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
249+ __LINE__)
250+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
251+ __LINE__)
252+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
253+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
076b876e
AM
254+#else
255+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
256+extern void vmr_do_fput(struct vm_region *, const char[], int);
257+
258+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
259+ __LINE__)
260+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
261+#endif /* CONFIG_MMU */
fb47a38f
JR
262+
263 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
264 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
265 void *buf, int len, int write);
266diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
7e9cd9fe 267index 199a03a..ed38ea3 100644
fb47a38f
JR
268--- a/include/linux/mm_types.h
269+++ b/include/linux/mm_types.h
7e9cd9fe 270@@ -241,6 +241,7 @@ struct vm_region {
fb47a38f
JR
271 unsigned long vm_top; /* region allocated to here */
272 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
273 struct file *vm_file; /* the backing file or NULL */
274+ struct file *vm_prfile; /* the virtual backing file or NULL */
275
276 int vm_usage; /* region usage count (access under nommu_region_sem) */
277 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
7e9cd9fe 278@@ -305,6 +306,7 @@ struct vm_area_struct {
fb47a38f
JR
279 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
280 units, *not* PAGE_CACHE_SIZE */
281 struct file * vm_file; /* File we map to (can be NULL). */
282+ struct file *vm_prfile; /* shadow of vm_file */
283 void * vm_private_data; /* was vm_pte (shared mem) */
284
285 #ifndef CONFIG_MMU
286diff --git a/kernel/fork.c b/kernel/fork.c
7e9cd9fe 287index cf65139..f28a048 100644
fb47a38f
JR
288--- a/kernel/fork.c
289+++ b/kernel/fork.c
c1595e42 290@@ -430,7 +430,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
fb47a38f
JR
291 struct inode *inode = file_inode(file);
292 struct address_space *mapping = file->f_mapping;
293
294- get_file(file);
295+ vma_get_file(tmp);
296 if (tmp->vm_flags & VM_DENYWRITE)
297 atomic_dec(&inode->i_writecount);
2000de60 298 i_mmap_lock_write(mapping);
076b876e 299diff --git a/mm/Makefile b/mm/Makefile
7e9cd9fe 300index 15dbe99..88e25b5 100644
076b876e
AM
301--- a/mm/Makefile
302+++ b/mm/Makefile
7e9cd9fe 303@@ -21,7 +21,7 @@ obj-y := filemap.o mempool.o oom_kill.o \
076b876e 304 mm_init.o mmu_context.o percpu.o slab_common.o \
c1595e42 305 compaction.o vmacache.o \
076b876e 306 interval_tree.o list_lru.o workingset.o \
7e9cd9fe
AM
307- debug.o $(mmu-y)
308+ prfile.o debug.o $(mmu-y)
076b876e
AM
309
310 obj-y += init-mm.o
311
fb47a38f 312diff --git a/mm/filemap.c b/mm/filemap.c
7e9cd9fe 313index ad72420..8885258 100644
fb47a38f
JR
314--- a/mm/filemap.c
315+++ b/mm/filemap.c
7e9cd9fe 316@@ -2064,7 +2064,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
fb47a38f
JR
317 int ret = VM_FAULT_LOCKED;
318
319 sb_start_pagefault(inode->i_sb);
320- file_update_time(vma->vm_file);
321+ vma_file_update_time(vma);
322 lock_page(page);
323 if (page->mapping != inode->i_mapping) {
324 unlock_page(page);
fb47a38f 325diff --git a/mm/madvise.c b/mm/madvise.c
7e9cd9fe 326index d551475..1ebf71b 100644
fb47a38f
JR
327--- a/mm/madvise.c
328+++ b/mm/madvise.c
7e9cd9fe 329@@ -320,12 +320,12 @@ static long madvise_remove(struct vm_area_struct *vma,
fb47a38f
JR
330 * vma's reference to the file) can go away as soon as we drop
331 * mmap_sem.
332 */
333- get_file(f);
334+ vma_get_file(vma);
335 up_read(&current->mm->mmap_sem);
03673fb0 336 error = vfs_fallocate(f,
fb47a38f
JR
337 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
338 offset, end - start);
339- fput(f);
340+ vma_fput(vma);
341 down_read(&current->mm->mmap_sem);
342 return error;
343 }
344diff --git a/mm/memory.c b/mm/memory.c
7e9cd9fe 345index 97839f5..5e5d491 100644
fb47a38f
JR
346--- a/mm/memory.c
347+++ b/mm/memory.c
7e9cd9fe
AM
348@@ -2132,7 +2132,7 @@ reuse:
349 }
2000de60 350
7e9cd9fe 351 if (!page_mkwrite)
fb47a38f
JR
352- file_update_time(vma->vm_file);
353+ vma_file_update_time(vma);
354 }
7e9cd9fe
AM
355
356 return ret;
fb47a38f 357diff --git a/mm/mmap.c b/mm/mmap.c
7e9cd9fe 358index 9ec50a3..4a6a641 100644
fb47a38f
JR
359--- a/mm/mmap.c
360+++ b/mm/mmap.c
7e9cd9fe 361@@ -274,7 +274,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
fb47a38f
JR
362 if (vma->vm_ops && vma->vm_ops->close)
363 vma->vm_ops->close(vma);
364 if (vma->vm_file)
365- fput(vma->vm_file);
366+ vma_fput(vma);
367 mpol_put(vma_policy(vma));
368 kmem_cache_free(vm_area_cachep, vma);
369 return next;
7e9cd9fe 370@@ -886,7 +886,7 @@ again: remove_next = 1 + (end > next->vm_end);
fb47a38f
JR
371 if (remove_next) {
372 if (file) {
373 uprobe_munmap(next, next->vm_start, next->vm_end);
374- fput(file);
375+ vma_fput(vma);
376 }
377 if (next->anon_vma)
378 anon_vma_merge(vma, next);
7e9cd9fe 379@@ -1671,8 +1671,8 @@ out:
35939ee7
JR
380 return addr;
381
fb47a38f 382 unmap_and_free_vma:
fb47a38f
JR
383+ vma_fput(vma);
384 vma->vm_file = NULL;
385- fput(file);
386
387 /* Undo any partial mapping done by a device driver. */
388 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
7e9cd9fe 389@@ -2473,7 +2473,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
390 goto out_free_mpol;
391
392 if (new->vm_file)
393- get_file(new->vm_file);
394+ vma_get_file(new);
395
396 if (new->vm_ops && new->vm_ops->open)
397 new->vm_ops->open(new);
7e9cd9fe 398@@ -2492,7 +2492,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
399 if (new->vm_ops && new->vm_ops->close)
400 new->vm_ops->close(new);
401 if (new->vm_file)
402- fput(new->vm_file);
403+ vma_fput(new);
404 unlink_anon_vmas(new);
405 out_free_mpol:
406 mpol_put(vma_policy(new));
7e9cd9fe
AM
407@@ -2635,7 +2635,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
408 struct vm_area_struct *vma;
409 unsigned long populate = 0;
410 unsigned long ret = -EINVAL;
411- struct file *file;
412
413 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. "
414 "See Documentation/vm/remap_file_pages.txt.\n",
415@@ -2679,10 +2678,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
416 munlock_vma_pages_range(vma, start, start + size);
417 }
418
419- file = get_file(vma->vm_file);
420+ vma_get_file(vma);
421 ret = do_mmap_pgoff(vma->vm_file, start, size,
422 prot, flags, pgoff, &populate);
423- fput(file);
424+ vma_fput(vma);
425 out:
426 up_write(&mm->mmap_sem);
427 if (populate)
428@@ -2950,7 +2949,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
fb47a38f
JR
429 if (anon_vma_clone(new_vma, vma))
430 goto out_free_mempol;
431 if (new_vma->vm_file)
432- get_file(new_vma->vm_file);
433+ vma_get_file(new_vma);
434 if (new_vma->vm_ops && new_vma->vm_ops->open)
435 new_vma->vm_ops->open(new_vma);
436 vma_link(mm, new_vma, prev, rb_link, rb_parent);
437diff --git a/mm/msync.c b/mm/msync.c
7e9cd9fe 438index bb04d53..5c24c54 100644
fb47a38f
JR
439--- a/mm/msync.c
440+++ b/mm/msync.c
7e9cd9fe 441@@ -84,10 +84,10 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
fb47a38f
JR
442 start = vma->vm_end;
443 if ((flags & MS_SYNC) && file &&
444 (vma->vm_flags & VM_SHARED)) {
445- get_file(file);
446+ vma_get_file(vma);
447 up_read(&mm->mmap_sem);
7e9cd9fe 448 error = vfs_fsync_range(file, fstart, fend, 1);
fb47a38f
JR
449- fput(file);
450+ vma_fput(vma);
451 if (error || start >= end)
452 goto out;
453 down_read(&mm->mmap_sem);
454diff --git a/mm/nommu.c b/mm/nommu.c
7e9cd9fe 455index 3fba2dc..870ce96 100644
fb47a38f
JR
456--- a/mm/nommu.c
457+++ b/mm/nommu.c
7e9cd9fe 458@@ -693,7 +693,7 @@ static void __put_nommu_region(struct vm_region *region)
fb47a38f
JR
459 up_write(&nommu_region_sem);
460
461 if (region->vm_file)
462- fput(region->vm_file);
463+ vmr_fput(region);
464
465 /* IO memory and memory shared directly out of the pagecache
466 * from ramfs/tmpfs mustn't be released here */
7e9cd9fe 467@@ -858,7 +858,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
fb47a38f
JR
468 if (vma->vm_ops && vma->vm_ops->close)
469 vma->vm_ops->close(vma);
470 if (vma->vm_file)
471- fput(vma->vm_file);
472+ vma_fput(vma);
473 put_nommu_region(vma->vm_region);
474 kmem_cache_free(vm_area_cachep, vma);
475 }
7e9cd9fe 476@@ -1398,7 +1398,7 @@ unsigned long do_mmap_pgoff(struct file *file,
fb47a38f
JR
477 goto error_just_free;
478 }
479 }
480- fput(region->vm_file);
481+ vmr_fput(region);
482 kmem_cache_free(vm_region_jar, region);
483 region = pregion;
484 result = start;
7e9cd9fe 485@@ -1474,10 +1474,10 @@ error_just_free:
fb47a38f
JR
486 up_write(&nommu_region_sem);
487 error:
488 if (region->vm_file)
489- fput(region->vm_file);
490+ vmr_fput(region);
491 kmem_cache_free(vm_region_jar, region);
492 if (vma->vm_file)
493- fput(vma->vm_file);
494+ vma_fput(vma);
495 kmem_cache_free(vm_area_cachep, vma);
496 kleave(" = %d", ret);
497 return ret;
076b876e
AM
498diff --git a/mm/prfile.c b/mm/prfile.c
499new file mode 100644
7e9cd9fe 500index 0000000..6c145eb
076b876e
AM
501--- /dev/null
502+++ b/mm/prfile.c
503@@ -0,0 +1,86 @@
504+/*
505+ * Mainly for aufs which mmap(2) diffrent file and wants to print different path
506+ * in /proc/PID/maps.
507+ * Call these functions via macros defined in linux/mm.h.
508+ *
509+ * See Documentation/filesystems/aufs/design/06mmap.txt
510+ *
511+ * Copyright (c) 2014 Junjro R. Okajima
512+ * Copyright (c) 2014 Ian Campbell
513+ */
514+
515+#include <linux/mm.h>
516+#include <linux/file.h>
517+#include <linux/fs.h>
518+
519+/* #define PRFILE_TRACE */
520+static inline void prfile_trace(struct file *f, struct file *pr,
521+ const char func[], int line, const char func2[])
522+{
523+#ifdef PRFILE_TRACE
524+ if (pr)
525+ pr_info("%s:%d: %s, %p\n", func, line, func2,
7e9cd9fe 526+ f ? (char *)f->f_path.dentry->d_name.name : "(null)");
076b876e
AM
527+#endif
528+}
529+
530+#ifdef CONFIG_MMU
531+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
532+ int line)
533+{
534+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
535+
536+ prfile_trace(f, pr, func, line, __func__);
537+ file_update_time(f);
538+ if (f && pr)
539+ file_update_time(pr);
540+}
541+
542+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
543+ int line)
544+{
545+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
546+
547+ prfile_trace(f, pr, func, line, __func__);
548+ return (f && pr) ? pr : f;
549+}
550+
551+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
552+{
553+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
554+
555+ prfile_trace(f, pr, func, line, __func__);
556+ get_file(f);
557+ if (f && pr)
558+ get_file(pr);
559+}
560+
561+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
562+{
563+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
564+
565+ prfile_trace(f, pr, func, line, __func__);
566+ fput(f);
567+ if (f && pr)
568+ fput(pr);
569+}
570+#else
571+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
572+ int line)
573+{
574+ struct file *f = region->vm_file, *pr = region->vm_prfile;
575+
576+ prfile_trace(f, pr, func, line, __func__);
577+ return (f && pr) ? pr : f;
578+}
579+
580+void vmr_do_fput(struct vm_region *region, const char func[], int line)
581+{
582+ struct file *f = region->vm_file, *pr = region->vm_prfile;
583+
584+ prfile_trace(f, pr, func, line, __func__);
585+ fput(f);
586+ if (f && pr)
587+ fput(pr);
588+}
589+#endif /* CONFIG_MMU */
7e9cd9fe 590aufs3.x-rcN standalone patch
7f207e10 591
c1595e42 592diff --git a/fs/dcache.c b/fs/dcache.c
7e9cd9fe 593index b93a9f2..5a010ee 100644
c1595e42
JR
594--- a/fs/dcache.c
595+++ b/fs/dcache.c
7e9cd9fe 596@@ -1235,6 +1235,7 @@ rename_retry:
c1595e42
JR
597 seq = 1;
598 goto again;
599 }
600+EXPORT_SYMBOL(d_walk);
601
602 /*
603 * Search for at least 1 mount point in the dentry's subdirs.
1e00d052 604diff --git a/fs/inode.c b/fs/inode.c
7e9cd9fe 605index f00b16f..eb7b8b5 100644
1e00d052
AM
606--- a/fs/inode.c
607+++ b/fs/inode.c
7e9cd9fe 608@@ -58,6 +58,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
4b3da204 609 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
2cbb1c4b
JR
610
611 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
2cbb1c4b 612+EXPORT_SYMBOL(inode_sb_list_lock);
7f207e10
AM
613
614 /*
4b3da204 615 * Empty aops. Can be used for the cases where the user does not
7f207e10 616diff --git a/fs/namespace.c b/fs/namespace.c
7e9cd9fe 617index 82ef140..a3aa4b9 100644
7f207e10
AM
618--- a/fs/namespace.c
619+++ b/fs/namespace.c
7e9cd9fe 620@@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
621 mnt_dec_writers(real_mount(mnt));
622 preempt_enable();
623 }
624+EXPORT_SYMBOL_GPL(__mnt_drop_write);
625
626 /**
627 * mnt_drop_write - give up write access to a mount
7e9cd9fe 628@@ -1718,6 +1719,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
629 }
630 return 0;
631 }
632+EXPORT_SYMBOL(iterate_mounts);
633
7eafdf33 634 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
635 {
636diff --git a/fs/notify/group.c b/fs/notify/group.c
c1595e42 637index d16b62c..06ca6bc 100644
7f207e10
AM
638--- a/fs/notify/group.c
639+++ b/fs/notify/group.c
640@@ -22,6 +22,7 @@
641 #include <linux/srcu.h>
642 #include <linux/rculist.h>
643 #include <linux/wait.h>
644+#include <linux/module.h>
645
646 #include <linux/fsnotify_backend.h>
647 #include "fsnotify.h"
fb47a38f 648@@ -72,6 +73,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea
AM
649 {
650 atomic_inc(&group->refcnt);
651 }
652+EXPORT_SYMBOL(fsnotify_get_group);
653
654 /*
655 * Drop a reference to a group. Free it if it's through.
fb47a38f 656@@ -81,6 +83,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 657 if (atomic_dec_and_test(&group->refcnt))
1716fcea 658 fsnotify_final_destroy_group(group);
7f207e10
AM
659 }
660+EXPORT_SYMBOL(fsnotify_put_group);
661
662 /*
663 * Create a new fsnotify_group and hold a reference for the group returned.
fb47a38f 664@@ -109,6 +112,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
665
666 return group;
667 }
668+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
669
670 int fsnotify_fasync(int fd, struct file *file, int on)
671 {
7f207e10 672diff --git a/fs/notify/mark.c b/fs/notify/mark.c
2000de60 673index 92e48c7..d2c4b68 100644
7f207e10
AM
674--- a/fs/notify/mark.c
675+++ b/fs/notify/mark.c
392086de 676@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 677 mark->free_mark(mark);
1716fcea 678 }
7f207e10
AM
679 }
680+EXPORT_SYMBOL(fsnotify_put_mark);
681
2000de60
JR
682 /* Calculate mask of events for a list of marks */
683 u32 fsnotify_recalc_mask(struct hlist_head *head)
684@@ -202,6 +203,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea
AM
685 fsnotify_destroy_mark_locked(mark, group);
686 mutex_unlock(&group->mark_mutex);
7f207e10
AM
687 }
688+EXPORT_SYMBOL(fsnotify_destroy_mark);
689
2000de60
JR
690 /*
691 * Destroy all marks in the given list. The marks must be already detached from
692@@ -376,6 +378,7 @@ err:
7f207e10
AM
693
694 return ret;
695 }
696+EXPORT_SYMBOL(fsnotify_add_mark);
697
1716fcea
AM
698 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
699 struct inode *inode, struct vfsmount *mnt, int allow_dups)
2000de60 700@@ -455,6 +458,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
701 atomic_set(&mark->refcnt, 1);
702 mark->free_mark = free_mark;
703 }
704+EXPORT_SYMBOL(fsnotify_init_mark);
705
706 static int fsnotify_mark_destroy(void *ignored)
707 {
708diff --git a/fs/open.c b/fs/open.c
7e9cd9fe 709index 33f9cbf..2c8bd72 100644
7f207e10
AM
710--- a/fs/open.c
711+++ b/fs/open.c
523b37e3 712@@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
7f207e10
AM
713 mutex_unlock(&dentry->d_inode->i_mutex);
714 return ret;
715 }
716+EXPORT_SYMBOL(do_truncate);
717
1716fcea 718 long vfs_truncate(struct path *path, loff_t length)
7f207e10
AM
719 {
720diff --git a/fs/splice.c b/fs/splice.c
7e9cd9fe 721index beb9993..813275a 100644
7f207e10
AM
722--- a/fs/splice.c
723+++ b/fs/splice.c
7e9cd9fe 724@@ -1112,6 +1112,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
725
726 return splice_write(pipe, out, ppos, len, flags);
7f207e10
AM
727 }
728+EXPORT_SYMBOL(do_splice_from);
729
730 /*
731 * Attempt to initiate a splice from a file to a pipe.
7e9cd9fe 732@@ -1138,6 +1139,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
733
734 return splice_read(in, ppos, pipe, len, flags);
735 }
736+EXPORT_SYMBOL(do_splice_to);
737
738 /**
739 * splice_direct_to_actor - splices data directly between two non-pipes
c1595e42 740diff --git a/fs/xattr.c b/fs/xattr.c
2000de60 741index 4ef6985..6bb6303 100644
c1595e42
JR
742--- a/fs/xattr.c
743+++ b/fs/xattr.c
744@@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
745 *xattr_value = value;
746 return error;
747 }
748+EXPORT_SYMBOL(vfs_getxattr_alloc);
749
750 /* Compare an extended attribute value with the given value */
751 int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
7f207e10 752diff --git a/security/commoncap.c b/security/commoncap.c
7e9cd9fe 753index f66713b..fd4c4b8 100644
7f207e10
AM
754--- a/security/commoncap.c
755+++ b/security/commoncap.c
7e9cd9fe 756@@ -975,9 +975,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 757 }
7f207e10
AM
758 return ret;
759 }
0c3ec466
AM
760+EXPORT_SYMBOL(cap_mmap_addr);
761
762 int cap_mmap_file(struct file *file, unsigned long reqprot,
763 unsigned long prot, unsigned long flags)
764 {
765 return 0;
766 }
767+EXPORT_SYMBOL(cap_mmap_file);
7f207e10 768diff --git a/security/device_cgroup.c b/security/device_cgroup.c
c1595e42 769index 188c1d2..426d9af 100644
7f207e10
AM
770--- a/security/device_cgroup.c
771+++ b/security/device_cgroup.c
f6c5ef8b
AM
772@@ -7,6 +7,7 @@
773 #include <linux/device_cgroup.h>
774 #include <linux/cgroup.h>
775 #include <linux/ctype.h>
776+#include <linux/export.h>
777 #include <linux/list.h>
778 #include <linux/uaccess.h>
779 #include <linux/seq_file.h>
076b876e 780@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
781 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
782 access);
7f207e10 783 }
2cbb1c4b 784+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
785
786 int devcgroup_inode_mknod(int mode, dev_t dev)
787 {
788diff --git a/security/security.c b/security/security.c
7e9cd9fe 789index e81d5bb..0b7b840 100644
7f207e10
AM
790--- a/security/security.c
791+++ b/security/security.c
7e9cd9fe 792@@ -430,6 +430,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
793 return 0;
794 return security_ops->path_rmdir(dir, dentry);
795 }
796+EXPORT_SYMBOL(security_path_rmdir);
797
798 int security_path_unlink(struct path *dir, struct dentry *dentry)
799 {
7e9cd9fe 800@@ -446,6 +447,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
801 return 0;
802 return security_ops->path_symlink(dir, dentry, old_name);
803 }
804+EXPORT_SYMBOL(security_path_symlink);
805
806 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
807 struct dentry *new_dentry)
7e9cd9fe 808@@ -454,6 +456,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
809 return 0;
810 return security_ops->path_link(old_dentry, new_dir, new_dentry);
811 }
812+EXPORT_SYMBOL(security_path_link);
813
814 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
38d290e6 815 struct path *new_dir, struct dentry *new_dentry,
7e9cd9fe 816@@ -481,6 +484,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
817 return 0;
818 return security_ops->path_truncate(path);
819 }
820+EXPORT_SYMBOL(security_path_truncate);
821
7eafdf33
AM
822 int security_path_chmod(struct path *path, umode_t mode)
823 {
7e9cd9fe 824@@ -488,6 +492,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 825 return 0;
7eafdf33 826 return security_ops->path_chmod(path, mode);
7f207e10
AM
827 }
828+EXPORT_SYMBOL(security_path_chmod);
829
537831f9 830 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 831 {
7e9cd9fe 832@@ -495,6 +500,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
833 return 0;
834 return security_ops->path_chown(path, uid, gid);
835 }
836+EXPORT_SYMBOL(security_path_chown);
837
838 int security_path_chroot(struct path *path)
839 {
7e9cd9fe 840@@ -580,6 +586,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
841 return 0;
842 return security_ops->inode_readlink(dentry);
843 }
844+EXPORT_SYMBOL(security_inode_readlink);
845
846 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
847 {
7e9cd9fe 848@@ -594,6 +601,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 849 return 0;
1e00d052 850 return security_ops->inode_permission(inode, mask);
7f207e10
AM
851 }
852+EXPORT_SYMBOL(security_inode_permission);
853
1e00d052 854 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 855 {
7e9cd9fe 856@@ -716,6 +724,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
857
858 return fsnotify_perm(file, mask);
859 }
860+EXPORT_SYMBOL(security_file_permission);
861
862 int security_file_alloc(struct file *file)
863 {
7e9cd9fe 864@@ -775,6 +784,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
865 return ret;
866 return ima_file_mmap(file, prot);
867 }
0c3ec466 868+EXPORT_SYMBOL(security_mmap_file);
7f207e10 869
0c3ec466
AM
870 int security_mmap_addr(unsigned long addr)
871 {
7f207e10
AM
872diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
873--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 874+++ linux/Documentation/ABI/testing/debugfs-aufs 2015-04-13 15:10:20.773489965 +0200
86dc4139 875@@ -0,0 +1,50 @@
7f207e10
AM
876+What: /debug/aufs/si_<id>/
877+Date: March 2009
f6b6e03d 878+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
879+Description:
880+ Under /debug/aufs, a directory named si_<id> is created
881+ per aufs mount, where <id> is a unique id generated
882+ internally.
1facf9fc 883+
86dc4139
AM
884+What: /debug/aufs/si_<id>/plink
885+Date: Apr 2013
f6b6e03d 886+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
887+Description:
888+ It has three lines and shows the information about the
889+ pseudo-link. The first line is a single number
890+ representing a number of buckets. The second line is a
891+ number of pseudo-links per buckets (separated by a
892+ blank). The last line is a single number representing a
893+ total number of psedo-links.
894+ When the aufs mount option 'noplink' is specified, it
895+ will show "1\n0\n0\n".
896+
7f207e10
AM
897+What: /debug/aufs/si_<id>/xib
898+Date: March 2009
f6b6e03d 899+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
900+Description:
901+ It shows the consumed blocks by xib (External Inode Number
902+ Bitmap), its block size and file size.
903+ When the aufs mount option 'noxino' is specified, it
904+ will be empty. About XINO files, see the aufs manual.
905+
906+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
907+Date: March 2009
f6b6e03d 908+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
909+Description:
910+ It shows the consumed blocks by xino (External Inode Number
911+ Translation Table), its link count, block size and file
912+ size.
913+ When the aufs mount option 'noxino' is specified, it
914+ will be empty. About XINO files, see the aufs manual.
915+
916+What: /debug/aufs/si_<id>/xigen
917+Date: March 2009
f6b6e03d 918+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
919+Description:
920+ It shows the consumed blocks by xigen (External Inode
921+ Generation Table), its block size and file size.
922+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
923+ be created.
924+ When the aufs mount option 'noxino' is specified, it
925+ will be empty. About XINO files, see the aufs manual.
926diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
927--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 928+++ linux/Documentation/ABI/testing/sysfs-aufs 2015-04-13 15:10:20.773489965 +0200
392086de 929@@ -0,0 +1,31 @@
7f207e10
AM
930+What: /sys/fs/aufs/si_<id>/
931+Date: March 2009
f6b6e03d 932+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
933+Description:
934+ Under /sys/fs/aufs, a directory named si_<id> is created
935+ per aufs mount, where <id> is a unique id generated
936+ internally.
937+
938+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
939+Date: March 2009
f6b6e03d 940+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
941+Description:
942+ It shows the abolute path of a member directory (which
943+ is called branch) in aufs, and its permission.
944+
392086de
AM
945+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
946+Date: July 2013
f6b6e03d 947+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
948+Description:
949+ It shows the id of a member directory (which is called
950+ branch) in aufs.
951+
7f207e10
AM
952+What: /sys/fs/aufs/si_<id>/xi_path
953+Date: March 2009
f6b6e03d 954+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
955+Description:
956+ It shows the abolute path of XINO (External Inode Number
957+ Bitmap, Translation Table and Generation Table) file
958+ even if it is the default path.
959+ When the aufs mount option 'noxino' is specified, it
960+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
961diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
962--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
963+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2015-04-13 15:10:20.773489965 +0200
964@@ -0,0 +1,170 @@
53392da6 965+
2000de60 966+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
967+#
968+# This program is free software; you can redistribute it and/or modify
969+# it under the terms of the GNU General Public License as published by
970+# the Free Software Foundation; either version 2 of the License, or
971+# (at your option) any later version.
972+#
973+# This program is distributed in the hope that it will be useful,
974+# but WITHOUT ANY WARRANTY; without even the implied warranty of
975+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
976+# GNU General Public License for more details.
977+#
978+# You should have received a copy of the GNU General Public License
523b37e3 979+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
980+
981+Introduction
982+----------------------------------------
983+
984+aufs [ei ju: ef es] | [a u f s]
985+1. abbrev. for "advanced multi-layered unification filesystem".
986+2. abbrev. for "another unionfs".
987+3. abbrev. for "auf das" in German which means "on the" in English.
988+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
989+ But "Filesystem aufs Filesystem" is hard to understand.
990+
991+AUFS is a filesystem with features:
992+- multi layered stackable unification filesystem, the member directory
993+ is called as a branch.
994+- branch permission and attribute, 'readonly', 'real-readonly',
7e9cd9fe 995+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their
53392da6
AM
996+ combination.
997+- internal "file copy-on-write".
998+- logical deletion, whiteout.
999+- dynamic branch manipulation, adding, deleting and changing permission.
1000+- allow bypassing aufs, user's direct branch access.
1001+- external inode number translation table and bitmap which maintains the
1002+ persistent aufs inode number.
1003+- seekable directory, including NFS readdir.
1004+- file mapping, mmap and sharing pages.
1005+- pseudo-link, hardlink over branches.
1006+- loopback mounted filesystem as a branch.
1007+- several policies to select one among multiple writable branches.
1008+- revert a single systemcall when an error occurs in aufs.
1009+- and more...
1010+
1011+
1012+Multi Layered Stackable Unification Filesystem
1013+----------------------------------------------------------------------
1014+Most people already knows what it is.
1015+It is a filesystem which unifies several directories and provides a
1016+merged single directory. When users access a file, the access will be
1017+passed/re-directed/converted (sorry, I am not sure which English word is
1018+correct) to the real file on the member filesystem. The member
1019+filesystem is called 'lower filesystem' or 'branch' and has a mode
1020+'readonly' and 'readwrite.' And the deletion for a file on the lower
1021+readonly branch is handled by creating 'whiteout' on the upper writable
1022+branch.
1023+
1024+On LKML, there have been discussions about UnionMount (Jan Blunck,
1025+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1026+different approaches to implement the merged-view.
1027+The former tries putting it into VFS, and the latter implements as a
1028+separate filesystem.
1029+(If I misunderstand about these implementations, please let me know and
1030+I shall correct it. Because it is a long time ago when I read their
1031+source files last time).
1032+
1033+UnionMount's approach will be able to small, but may be hard to share
1034+branches between several UnionMount since the whiteout in it is
1035+implemented in the inode on branch filesystem and always
1036+shared. According to Bharata's post, readdir does not seems to be
1037+finished yet.
1038+There are several missing features known in this implementations such as
1039+- for users, the inode number may change silently. eg. copy-up.
1040+- link(2) may break by copy-up.
1041+- read(2) may get an obsoleted filedata (fstat(2) too).
1042+- fcntl(F_SETLK) may be broken by copy-up.
1043+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1044+ open(O_RDWR).
1045+
7e9cd9fe
AM
1046+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was
1047+merged into mainline. This is another implementation of UnionMount as a
1048+separated filesystem. All the limitations and known problems which
1049+UnionMount are equally inherited to "overlay" filesystem.
1050+
1051+Unionfs has a longer history. When I started implementing a stackable
1052+filesystem (Aug 2005), it already existed. It has virtual super_block,
1053+inode, dentry and file objects and they have an array pointing lower
1054+same kind objects. After contributing many patches for Unionfs, I
1055+re-started my project AUFS (Jun 2006).
53392da6
AM
1056+
1057+In AUFS, the structure of filesystem resembles to Unionfs, but I
1058+implemented my own ideas, approaches and enhancements and it became
1059+totally different one.
1060+
1061+Comparing DM snapshot and fs based implementation
1062+- the number of bytes to be copied between devices is much smaller.
1063+- the type of filesystem must be one and only.
1064+- the fs must be writable, no readonly fs, even for the lower original
1065+ device. so the compression fs will not be usable. but if we use
1066+ loopback mount, we may address this issue.
1067+ for instance,
1068+ mount /cdrom/squashfs.img /sq
1069+ losetup /sq/ext2.img
1070+ losetup /somewhere/cow
1071+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1072+- it will be difficult (or needs more operations) to extract the
1073+ difference between the original device and COW.
1074+- DM snapshot-merge may help a lot when users try merging. in the
1075+ fs-layer union, users will use rsync(1).
1076+
7e9cd9fe
AM
1077+You may want to read my old paper "Filesystems in LiveCD"
1078+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf).
53392da6 1079+
7e9cd9fe
AM
1080+
1081+Several characters/aspects/persona of aufs
53392da6
AM
1082+----------------------------------------------------------------------
1083+
7e9cd9fe 1084+Aufs has several characters, aspects or persona.
53392da6
AM
1085+1. a filesystem, callee of VFS helper
1086+2. sub-VFS, caller of VFS helper for branches
1087+3. a virtual filesystem which maintains persistent inode number
1088+4. reader/writer of files on branches such like an application
1089+
1090+1. Callee of VFS Helper
1091+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1092+unlink(2) from an application reaches sys_unlink() kernel function and
1093+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1094+calls filesystem specific unlink operation. Actually aufs implements the
1095+unlink operation but it behaves like a redirector.
1096+
1097+2. Caller of VFS Helper for Branches
1098+aufs_unlink() passes the unlink request to the branch filesystem as if
1099+it were called from VFS. So the called unlink operation of the branch
1100+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1101+every necessary pre/post operation for the branch filesystem.
1102+- acquire the lock for the parent dir on a branch
1103+- lookup in a branch
1104+- revalidate dentry on a branch
1105+- mnt_want_write() for a branch
1106+- vfs_unlink() for a branch
1107+- mnt_drop_write() for a branch
1108+- release the lock on a branch
1109+
1110+3. Persistent Inode Number
1111+One of the most important issue for a filesystem is to maintain inode
1112+numbers. This is particularly important to support exporting a
1113+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1114+backend block device for its own. But some storage is necessary to
7e9cd9fe
AM
1115+keep and maintain the inode numbers. It may be a large space and may not
1116+suit to keep in memory. Aufs rents some space from its first writable
1117+branch filesystem (by default) and creates file(s) on it. These files
1118+are created by aufs internally and removed soon (currently) keeping
1119+opened.
53392da6
AM
1120+Note: Because these files are removed, they are totally gone after
1121+ unmounting aufs. It means the inode numbers are not persistent
1122+ across unmount or reboot. I have a plan to make them really
1123+ persistent which will be important for aufs on NFS server.
1124+
1125+4. Read/Write Files Internally (copy-on-write)
1126+Because a branch can be readonly, when you write a file on it, aufs will
1127+"copy-up" it to the upper writable branch internally. And then write the
1128+originally requested thing to the file. Generally kernel doesn't
1129+open/read/write file actively. In aufs, even a single write may cause a
1130+internal "file copy". This behaviour is very similar to cp(1) command.
1131+
1132+Some people may think it is better to pass such work to user space
1133+helper, instead of doing in kernel space. Actually I am still thinking
1134+about it. But currently I have implemented it in kernel space.
1135diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1136--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
1137+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2015-04-13 15:10:20.773489965 +0200
1138@@ -0,0 +1,258 @@
53392da6 1139+
2000de60 1140+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1141+#
1142+# This program is free software; you can redistribute it and/or modify
1143+# it under the terms of the GNU General Public License as published by
1144+# the Free Software Foundation; either version 2 of the License, or
1145+# (at your option) any later version.
1146+#
1147+# This program is distributed in the hope that it will be useful,
1148+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1149+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1150+# GNU General Public License for more details.
1151+#
1152+# You should have received a copy of the GNU General Public License
523b37e3 1153+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1154+
1155+Basic Aufs Internal Structure
1156+
1157+Superblock/Inode/Dentry/File Objects
1158+----------------------------------------------------------------------
1159+As like an ordinary filesystem, aufs has its own
1160+superblock/inode/dentry/file objects. All these objects have a
1161+dynamically allocated array and store the same kind of pointers to the
1162+lower filesystem, branch.
1163+For example, when you build a union with one readwrite branch and one
1164+readonly, mounted /au, /rw and /ro respectively.
1165+- /au = /rw + /ro
1166+- /ro/fileA exists but /rw/fileA
1167+
1168+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1169+pointers are stored in a aufs dentry. The array in aufs dentry will be,
7e9cd9fe 1170+- [0] = NULL (because /rw/fileA doesn't exist)
53392da6
AM
1171+- [1] = /ro/fileA
1172+
1173+This style of an array is essentially same to the aufs
1174+superblock/inode/dentry/file objects.
1175+
1176+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1177+branches dynamically, these objects has its own generation. When
1178+branches are changed, the generation in aufs superblock is
1179+incremented. And a generation in other object are compared when it is
1180+accessed. When a generation in other objects are obsoleted, aufs
1181+refreshes the internal array.
53392da6
AM
1182+
1183+
1184+Superblock
1185+----------------------------------------------------------------------
1186+Additionally aufs superblock has some data for policies to select one
1187+among multiple writable branches, XIB files, pseudo-links and kobject.
1188+See below in detail.
7e9cd9fe
AM
1189+About the policies which supports copy-down a directory, see
1190+wbr_policy.txt too.
53392da6
AM
1191+
1192+
1193+Branch and XINO(External Inode Number Translation Table)
1194+----------------------------------------------------------------------
1195+Every branch has its own xino (external inode number translation table)
1196+file. The xino file is created and unlinked by aufs internally. When two
1197+members of a union exist on the same filesystem, they share the single
1198+xino file.
1199+The struct of a xino file is simple, just a sequence of aufs inode
1200+numbers which is indexed by the lower inode number.
1201+In the above sample, assume the inode number of /ro/fileA is i111 and
1202+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1203+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1204+
1205+When the inode numbers are not contiguous, the xino file will be sparse
1206+which has a hole in it and doesn't consume as much disk space as it
1207+might appear. If your branch filesystem consumes disk space for such
1208+holes, then you should specify 'xino=' option at mounting aufs.
1209+
7e9cd9fe
AM
1210+Aufs has a mount option to free the disk blocks for such holes in XINO
1211+files on tmpfs or ramdisk. But it is not so effective actually. If you
1212+meet a problem of disk shortage due to XINO files, then you should try
1213+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git.
1214+The patch localizes the assignment inumbers per tmpfs-mount and avoid
1215+the holes in XINO files.
1216+
53392da6 1217+Also a writable branch has three kinds of "whiteout bases". All these
7e9cd9fe 1218+are existed when the branch is joined to aufs, and their names are
53392da6
AM
1219+whiteout-ed doubly, so that users will never see their names in aufs
1220+hierarchy.
7e9cd9fe 1221+1. a regular file which will be hardlinked to all whiteouts.
53392da6 1222+2. a directory to store a pseudo-link.
7e9cd9fe 1223+3. a directory to store an "orphan"-ed file temporary.
53392da6
AM
1224+
1225+1. Whiteout Base
1226+ When you remove a file on a readonly branch, aufs handles it as a
1227+ logical deletion and creates a whiteout on the upper writable branch
1228+ as a hardlink of this file in order not to consume inode on the
1229+ writable branch.
1230+2. Pseudo-link Dir
1231+ See below, Pseudo-link.
1232+3. Step-Parent Dir
1233+ When "fileC" exists on the lower readonly branch only and it is
1234+ opened and removed with its parent dir, and then user writes
1235+ something into it, then aufs copies-up fileC to this
1236+ directory. Because there is no other dir to store fileC. After
1237+ creating a file under this dir, the file is unlinked.
1238+
1239+Because aufs supports manipulating branches, ie. add/delete/change
7e9cd9fe
AM
1240+dynamically, a branch has its own id. When the branch order changes,
1241+aufs finds the new index by searching the branch id.
53392da6
AM
1242+
1243+
1244+Pseudo-link
1245+----------------------------------------------------------------------
1246+Assume "fileA" exists on the lower readonly branch only and it is
1247+hardlinked to "fileB" on the branch. When you write something to fileA,
1248+aufs copies-up it to the upper writable branch. Additionally aufs
1249+creates a hardlink under the Pseudo-link Directory of the writable
1250+branch. The inode of a pseudo-link is kept in aufs super_block as a
1251+simple list. If fileB is read after unlinking fileA, aufs returns
1252+filedata from the pseudo-link instead of the lower readonly
1253+branch. Because the pseudo-link is based upon the inode, to keep the
7e9cd9fe 1254+inode number by xino (see above) is essentially necessary.
53392da6
AM
1255+
1256+All the hardlinks under the Pseudo-link Directory of the writable branch
1257+should be restored in a proper location later. Aufs provides a utility
1258+to do this. The userspace helpers executed at remounting and unmounting
1259+aufs by default.
1260+During this utility is running, it puts aufs into the pseudo-link
1261+maintenance mode. In this mode, only the process which began the
1262+maintenance mode (and its child processes) is allowed to operate in
1263+aufs. Some other processes which are not related to the pseudo-link will
1264+be allowed to run too, but the rest have to return an error or wait
1265+until the maintenance mode ends. If a process already acquires an inode
1266+mutex (in VFS), it has to return an error.
1267+
1268+
1269+XIB(external inode number bitmap)
1270+----------------------------------------------------------------------
1271+Addition to the xino file per a branch, aufs has an external inode number
7e9cd9fe
AM
1272+bitmap in a superblock object. It is also an internal file such like a
1273+xino file.
53392da6
AM
1274+It is a simple bitmap to mark whether the aufs inode number is in-use or
1275+not.
1276+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1277+
7e9cd9fe 1278+As well as XINO files, aufs has a feature to truncate/refresh XIB to
53392da6
AM
1279+reduce the number of consumed disk blocks for these files.
1280+
1281+
1282+Virtual or Vertical Dir, and Readdir in Userspace
1283+----------------------------------------------------------------------
1284+In order to support multiple layers (branches), aufs readdir operation
1285+constructs a virtual dir block on memory. For readdir, aufs calls
1286+vfs_readdir() internally for each dir on branches, merges their entries
1287+with eliminating the whiteout-ed ones, and sets it to file (dir)
1288+object. So the file object has its entry list until it is closed. The
1289+entry list will be updated when the file position is zero and becomes
7e9cd9fe 1290+obsoleted. This decision is made in aufs automatically.
53392da6
AM
1291+
1292+The dynamically allocated memory block for the name of entries has a
1293+unit of 512 bytes (by default) and stores the names contiguously (no
1294+padding). Another block for each entry is handled by kmem_cache too.
1295+During building dir blocks, aufs creates hash list and judging whether
1296+the entry is whiteouted by its upper branch or already listed.
1297+The merged result is cached in the corresponding inode object and
1298+maintained by a customizable life-time option.
1299+
1300+Some people may call it can be a security hole or invite DoS attack
1301+since the opened and once readdir-ed dir (file object) holds its entry
1302+list and becomes a pressure for system memory. But I'd say it is similar
1303+to files under /proc or /sys. The virtual files in them also holds a
1304+memory page (generally) while they are opened. When an idea to reduce
1305+memory for them is introduced, it will be applied to aufs too.
1306+For those who really hate this situation, I've developed readdir(3)
1307+library which operates this merging in userspace. You just need to set
1308+LD_PRELOAD environment variable, and aufs will not consume no memory in
1309+kernel space for readdir(3).
1310+
1311+
1312+Workqueue
1313+----------------------------------------------------------------------
1314+Aufs sometimes requires privilege access to a branch. For instance,
1315+in copy-up/down operation. When a user process is going to make changes
1316+to a file which exists in the lower readonly branch only, and the mode
1317+of one of ancestor directories may not be writable by a user
1318+process. Here aufs copy-up the file with its ancestors and they may
1319+require privilege to set its owner/group/mode/etc.
1320+This is a typical case of a application character of aufs (see
1321+Introduction).
1322+
1323+Aufs uses workqueue synchronously for this case. It creates its own
1324+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1325+passes the request to call mkdir or write (for example), and wait for
1326+its completion. This approach solves a problem of a signal handler
1327+simply.
1328+If aufs didn't adopt the workqueue and changed the privilege of the
7e9cd9fe
AM
1329+process, then the process may receive the unexpected SIGXFSZ or other
1330+signals.
53392da6
AM
1331+
1332+Also aufs uses the system global workqueue ("events" kernel thread) too
1333+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1334+whiteout base and etc. This is unrelated to a privilege.
1335+Most of aufs operation tries acquiring a rw_semaphore for aufs
1336+superblock at the beginning, at the same time waits for the completion
1337+of all queued asynchronous tasks.
1338+
1339+
1340+Whiteout
1341+----------------------------------------------------------------------
1342+The whiteout in aufs is very similar to Unionfs's. That is represented
1343+by its filename. UnionMount takes an approach of a file mode, but I am
1344+afraid several utilities (find(1) or something) will have to support it.
1345+
1346+Basically the whiteout represents "logical deletion" which stops aufs to
1347+lookup further, but also it represents "dir is opaque" which also stop
7e9cd9fe 1348+further lookup.
53392da6
AM
1349+
1350+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1351+In order to make several functions in a single systemcall to be
1352+revertible, aufs adopts an approach to rename a directory to a temporary
1353+unique whiteouted name.
1354+For example, in rename(2) dir where the target dir already existed, aufs
1355+renames the target dir to a temporary unique whiteouted name before the
7e9cd9fe 1356+actual rename on a branch, and then handles other actions (make it opaque,
53392da6
AM
1357+update the attributes, etc). If an error happens in these actions, aufs
1358+simply renames the whiteouted name back and returns an error. If all are
1359+succeeded, aufs registers a function to remove the whiteouted unique
1360+temporary name completely and asynchronously to the system global
1361+workqueue.
1362+
1363+
1364+Copy-up
1365+----------------------------------------------------------------------
1366+It is a well-known feature or concept.
1367+When user modifies a file on a readonly branch, aufs operate "copy-up"
1368+internally and makes change to the new file on the upper writable branch.
1369+When the trigger systemcall does not update the timestamps of the parent
1370+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1371+
1372+
1373+Move-down (aufs3.9 and later)
1374+----------------------------------------------------------------------
1375+"Copy-up" is one of the essential feature in aufs. It copies a file from
1376+the lower readonly branch to the upper writable branch when a user
1377+changes something about the file.
1378+"Move-down" is an opposite action of copy-up. Basically this action is
1379+ran manually instead of automatically and internally.
076b876e
AM
1380+For desgin and implementation, aufs has to consider these issues.
1381+- whiteout for the file may exist on the lower branch.
1382+- ancestor directories may not exist on the lower branch.
1383+- diropq for the ancestor directories may exist on the upper branch.
1384+- free space on the lower branch will reduce.
1385+- another access to the file may happen during moving-down, including
7e9cd9fe 1386+ UDBA (see "Revalidate Dentry and UDBA").
076b876e
AM
1387+- the file should not be hard-linked nor pseudo-linked. they should be
1388+ handled by auplink utility later.
c2b27bf2
AM
1389+
1390+Sometimes users want to move-down a file from the upper writable branch
1391+to the lower readonly or writable branch. For instance,
1392+- the free space of the upper writable branch is going to run out.
1393+- create a new intermediate branch between the upper and lower branch.
1394+- etc.
1395+
1396+For this purpose, use "aumvdown" command in aufs-util.git.
53392da6
AM
1397diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1398--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
1399+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2015-04-13 15:10:20.776823376 +0200
1400@@ -0,0 +1,113 @@
53392da6 1401+
2000de60 1402+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1403+#
1404+# This program is free software; you can redistribute it and/or modify
1405+# it under the terms of the GNU General Public License as published by
1406+# the Free Software Foundation; either version 2 of the License, or
1407+# (at your option) any later version.
1408+#
1409+# This program is distributed in the hope that it will be useful,
1410+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1411+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1412+# GNU General Public License for more details.
1413+#
1414+# You should have received a copy of the GNU General Public License
523b37e3 1415+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1416+
1417+Lookup in a Branch
1418+----------------------------------------------------------------------
1419+Since aufs has a character of sub-VFS (see Introduction), it operates
7e9cd9fe
AM
1420+lookup for branches as VFS does. It may be a heavy work. But almost all
1421+lookup operation in aufs is the simplest case, ie. lookup only an entry
1422+directly connected to its parent. Digging down the directory hierarchy
1423+is unnecessary. VFS has a function lookup_one_len() for that use, and
1424+aufs calls it.
1425+
1426+When a branch is a remote filesystem, aufs basically relies upon its
53392da6
AM
1427+->d_revalidate(), also aufs forces the hardest revalidate tests for
1428+them.
1429+For d_revalidate, aufs implements three levels of revalidate tests. See
1430+"Revalidate Dentry and UDBA" in detail.
1431+
1432+
076b876e
AM
1433+Test Only the Highest One for the Directory Permission (dirperm1 option)
1434+----------------------------------------------------------------------
1435+Let's try case study.
1436+- aufs has two branches, upper readwrite and lower readonly.
1437+ /au = /rw + /ro
1438+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1439+- user invoked "chmod a+rx /au/dirA"
1440+- the internal copy-up is activated and "/rw/dirA" is created and its
7e9cd9fe 1441+ permission bits are set to world readable.
076b876e
AM
1442+- then "/au/dirA" becomes world readable?
1443+
1444+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1445+or it may be a natively readonly filesystem. If aufs respects the lower
1446+branch, it should not respond readdir request from other users. But user
1447+allowed it by chmod. Should really aufs rejects showing the entries
1448+under /ro/dirA?
1449+
7e9cd9fe
AM
1450+To be honest, I don't have a good solution for this case. So aufs
1451+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to
1452+users.
076b876e
AM
1453+When dirperm1 is specified, aufs checks only the highest one for the
1454+directory permission, and shows the entries. Otherwise, as usual, checks
1455+every dir existing on all branches and rejects the request.
1456+
1457+As a side effect, dirperm1 option improves the performance of aufs
1458+because the number of permission check is reduced when the number of
1459+branch is many.
1460+
1461+
53392da6
AM
1462+Revalidate Dentry and UDBA (User's Direct Branch Access)
1463+----------------------------------------------------------------------
1464+Generally VFS helpers re-validate a dentry as a part of lookup.
1465+0. digging down the directory hierarchy.
1466+1. lock the parent dir by its i_mutex.
1467+2. lookup the final (child) entry.
1468+3. revalidate it.
1469+4. call the actual operation (create, unlink, etc.)
1470+5. unlock the parent dir
1471+
1472+If the filesystem implements its ->d_revalidate() (step 3), then it is
1473+called. Actually aufs implements it and checks the dentry on a branch is
1474+still valid.
1475+But it is not enough. Because aufs has to release the lock for the
1476+parent dir on a branch at the end of ->lookup() (step 2) and
1477+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1478+held by VFS.
1479+If the file on a branch is changed directly, eg. bypassing aufs, after
1480+aufs released the lock, then the subsequent operation may cause
1481+something unpleasant result.
1482+
1483+This situation is a result of VFS architecture, ->lookup() and
1484+->d_revalidate() is separated. But I never say it is wrong. It is a good
1485+design from VFS's point of view. It is just not suitable for sub-VFS
1486+character in aufs.
1487+
1488+Aufs supports such case by three level of revalidation which is
1489+selectable by user.
1490+1. Simple Revalidate
1491+ Addition to the native flow in VFS's, confirm the child-parent
1492+ relationship on the branch just after locking the parent dir on the
1493+ branch in the "actual operation" (step 4). When this validation
1494+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1495+ checks the validation of the dentry on branches.
1496+2. Monitor Changes Internally by Inotify/Fsnotify
1497+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1498+ the dentry on the branch, and returns EBUSY if it finds different
1499+ dentry.
1500+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1501+ during it is in cache. When the event is notified, aufs registers a
1502+ function to kernel 'events' thread by schedule_work(). And the
1503+ function sets some special status to the cached aufs dentry and inode
1504+ private data. If they are not cached, then aufs has nothing to
1505+ do. When the same file is accessed through aufs (step 0-3) later,
1506+ aufs will detect the status and refresh all necessary data.
1507+ In this mode, aufs has to ignore the event which is fired by aufs
1508+ itself.
1509+3. No Extra Validation
1510+ This is the simplest test and doesn't add any additional revalidation
7e9cd9fe 1511+ test, and skip the revalidation in step 4. It is useful and improves
53392da6
AM
1512+ aufs performance when system surely hide the aufs branches from user,
1513+ by over-mounting something (or another method).
1514diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1515--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
1516+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2015-04-13 15:10:20.776823376 +0200
1517@@ -0,0 +1,74 @@
53392da6 1518+
2000de60 1519+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1520+#
1521+# This program is free software; you can redistribute it and/or modify
1522+# it under the terms of the GNU General Public License as published by
1523+# the Free Software Foundation; either version 2 of the License, or
1524+# (at your option) any later version.
1525+#
1526+# This program is distributed in the hope that it will be useful,
1527+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1528+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1529+# GNU General Public License for more details.
1530+#
1531+# You should have received a copy of the GNU General Public License
523b37e3 1532+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1533+
1534+Branch Manipulation
1535+
1536+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1537+and changing its permission/attribute, there are a lot of works to do.
1538+
1539+
1540+Add a Branch
1541+----------------------------------------------------------------------
1542+o Confirm the adding dir exists outside of aufs, including loopback
7e9cd9fe 1543+ mount, and its various attributes.
53392da6
AM
1544+o Initialize the xino file and whiteout bases if necessary.
1545+ See struct.txt.
1546+
1547+o Check the owner/group/mode of the directory
1548+ When the owner/group/mode of the adding directory differs from the
1549+ existing branch, aufs issues a warning because it may impose a
1550+ security risk.
1551+ For example, when a upper writable branch has a world writable empty
1552+ top directory, a malicious user can create any files on the writable
1553+ branch directly, like copy-up and modify manually. If something like
1554+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1555+ writable branch, and the writable branch is world-writable, then a
1556+ malicious guy may create /etc/passwd on the writable branch directly
1557+ and the infected file will be valid in aufs.
7e9cd9fe 1558+ I am afraid it can be a security issue, but aufs can do nothing except
53392da6
AM
1559+ producing a warning.
1560+
1561+
1562+Delete a Branch
1563+----------------------------------------------------------------------
1564+o Confirm the deleting branch is not busy
1565+ To be general, there is one merit to adopt "remount" interface to
1566+ manipulate branches. It is to discard caches. At deleting a branch,
1567+ aufs checks the still cached (and connected) dentries and inodes. If
1568+ there are any, then they are all in-use. An inode without its
1569+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1570+
1571+ For the cached one, aufs checks whether the same named entry exists on
1572+ other branches.
1573+ If the cached one is a directory, because aufs provides a merged view
1574+ to users, as long as one dir is left on any branch aufs can show the
1575+ dir to users. In this case, the branch can be removed from aufs.
1576+ Otherwise aufs rejects deleting the branch.
1577+
1578+ If any file on the deleting branch is opened by aufs, then aufs
1579+ rejects deleting.
1580+
1581+
1582+Modify the Permission of a Branch
1583+----------------------------------------------------------------------
1584+o Re-initialize or remove the xino file and whiteout bases if necessary.
1585+ See struct.txt.
1586+
1587+o rw --> ro: Confirm the modifying branch is not busy
1588+ Aufs rejects the request if any of these conditions are true.
1589+ - a file on the branch is mmap-ed.
1590+ - a regular file on the branch is opened for write and there is no
1591+ same named entry on the upper branch.
1592diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1593--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 1594+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2015-04-13 15:10:20.776823376 +0200
523b37e3 1595@@ -0,0 +1,64 @@
53392da6 1596+
2000de60 1597+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1598+#
1599+# This program is free software; you can redistribute it and/or modify
1600+# it under the terms of the GNU General Public License as published by
1601+# the Free Software Foundation; either version 2 of the License, or
1602+# (at your option) any later version.
1603+#
1604+# This program is distributed in the hope that it will be useful,
1605+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1606+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1607+# GNU General Public License for more details.
1608+#
1609+# You should have received a copy of the GNU General Public License
523b37e3 1610+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1611+
1612+Policies to Select One among Multiple Writable Branches
1613+----------------------------------------------------------------------
1614+When the number of writable branch is more than one, aufs has to decide
1615+the target branch for file creation or copy-up. By default, the highest
1616+writable branch which has the parent (or ancestor) dir of the target
1617+file is chosen (top-down-parent policy).
1618+By user's request, aufs implements some other policies to select the
7e9cd9fe
AM
1619+writable branch, for file creation several policies, round-robin,
1620+most-free-space, and other policies. For copy-up, top-down-parent,
1621+bottom-up-parent, bottom-up and others.
53392da6
AM
1622+
1623+As expected, the round-robin policy selects the branch in circular. When
1624+you have two writable branches and creates 10 new files, 5 files will be
1625+created for each branch. mkdir(2) systemcall is an exception. When you
1626+create 10 new directories, all will be created on the same branch.
1627+And the most-free-space policy selects the one which has most free
1628+space among the writable branches. The amount of free space will be
1629+checked by aufs internally, and users can specify its time interval.
1630+
1631+The policies for copy-up is more simple,
1632+top-down-parent is equivalent to the same named on in create policy,
1633+bottom-up-parent selects the writable branch where the parent dir
1634+exists and the nearest upper one from the copyup-source,
1635+bottom-up selects the nearest upper writable branch from the
1636+copyup-source, regardless the existence of the parent dir.
1637+
1638+There are some rules or exceptions to apply these policies.
1639+- If there is a readonly branch above the policy-selected branch and
1640+ the parent dir is marked as opaque (a variation of whiteout), or the
1641+ target (creating) file is whiteout-ed on the upper readonly branch,
1642+ then the result of the policy is ignored and the target file will be
1643+ created on the nearest upper writable branch than the readonly branch.
1644+- If there is a writable branch above the policy-selected branch and
1645+ the parent dir is marked as opaque or the target file is whiteouted
1646+ on the branch, then the result of the policy is ignored and the target
1647+ file will be created on the highest one among the upper writable
1648+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1649+ it as usual.
1650+- link(2) and rename(2) systemcalls are exceptions in every policy.
1651+ They try selecting the branch where the source exists as possible
1652+ since copyup a large file will take long time. If it can't be,
1653+ ie. the branch where the source exists is readonly, then they will
1654+ follow the copyup policy.
1655+- There is an exception for rename(2) when the target exists.
1656+ If the rename target exists, aufs compares the index of the branches
1657+ where the source and the target exists and selects the higher
1658+ one. If the selected branch is readonly, then aufs follows the
1659+ copyup policy.
076b876e
AM
1660diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
1661--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 1662+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2015-04-13 15:10:20.776823376 +0200
076b876e
AM
1663@@ -0,0 +1,120 @@
1664+
2000de60 1665+# Copyright (C) 2011-2015 Junjiro R. Okajima
076b876e
AM
1666+#
1667+# This program is free software; you can redistribute it and/or modify
1668+# it under the terms of the GNU General Public License as published by
1669+# the Free Software Foundation; either version 2 of the License, or
1670+# (at your option) any later version.
1671+#
1672+# This program is distributed in the hope that it will be useful,
1673+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1674+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1675+# GNU General Public License for more details.
1676+#
1677+# You should have received a copy of the GNU General Public License
1678+# along with this program; if not, write to the Free Software
1679+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1680+
1681+
1682+File-based Hierarchical Storage Management (FHSM)
1683+----------------------------------------------------------------------
1684+Hierarchical Storage Management (or HSM) is a well-known feature in the
1685+storage world. Aufs provides this feature as file-based with multiple
7e9cd9fe 1686+writable branches, based upon the principle of "Colder, the Lower".
076b876e 1687+Here the word "colder" means that the less used files, and "lower" means
7e9cd9fe 1688+that the position in the order of the stacked branches vertically.
076b876e
AM
1689+These multiple writable branches are prioritized, ie. the topmost one
1690+should be the fastest drive and be used heavily.
1691+
1692+o Characters in aufs FHSM story
1693+- aufs itself and a new branch attribute.
1694+- a new ioctl interface to move-down and to establish a connection with
1695+ the daemon ("move-down" is a converse of "copy-up").
1696+- userspace tool and daemon.
1697+
1698+The userspace daemon establishes a connection with aufs and waits for
1699+the notification. The notified information is very similar to struct
1700+statfs containing the number of consumed blocks and inodes.
1701+When the consumed blocks/inodes of a branch exceeds the user-specified
1702+upper watermark, the daemon activates its move-down process until the
1703+consumed blocks/inodes reaches the user-specified lower watermark.
1704+
1705+The actual move-down is done by aufs based upon the request from
1706+user-space since we need to maintain the inode number and the internal
1707+pointer arrays in aufs.
1708+
1709+Currently aufs FHSM handles the regular files only. Additionally they
1710+must not be hard-linked nor pseudo-linked.
1711+
1712+
1713+o Cowork of aufs and the user-space daemon
1714+ During the userspace daemon established the connection, aufs sends a
1715+ small notification to it whenever aufs writes something into the
1716+ writable branch. But it may cost high since aufs issues statfs(2)
1717+ internally. So user can specify a new option to cache the
1718+ info. Actually the notification is controlled by these factors.
1719+ + the specified cache time.
1720+ + classified as "force" by aufs internally.
1721+ Until the specified time expires, aufs doesn't send the info
1722+ except the forced cases. When aufs decide forcing, the info is always
1723+ notified to userspace.
1724+ For example, the number of free inodes is generally large enough and
1725+ the shortage of it happens rarely. So aufs doesn't force the
1726+ notification when creating a new file, directory and others. This is
1727+ the typical case which aufs doesn't force.
1728+ When aufs writes the actual filedata and the files consumes any of new
1729+ blocks, the aufs forces notifying.
1730+
1731+
1732+o Interfaces in aufs
1733+- New branch attribute.
1734+ + fhsm
1735+ Specifies that the branch is managed by FHSM feature. In other word,
1736+ participant in the FHSM.
1737+ When nofhsm is set to the branch, it will not be the source/target
1738+ branch of the move-down operation. This attribute is set
1739+ independently from coo and moo attributes, and if you want full
1740+ FHSM, you should specify them as well.
1741+- New mount option.
1742+ + fhsm_sec
1743+ Specifies a second to suppress many less important info to be
1744+ notified.
1745+- New ioctl.
1746+ + AUFS_CTL_FHSM_FD
1747+ create a new file descriptor which userspace can read the notification
1748+ (a subset of struct statfs) from aufs.
1749+- Module parameter 'brs'
1750+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
1751+ be set.
1752+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
1753+ When there are two or more branches with fhsm attributes,
1754+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
1755+ terminates it. As a result of remounting and branch-manipulation, the
1756+ number of branches with fhsm attribute can be one. In this case,
1757+ /sbin/mount.aufs will terminate the user-space daemon.
1758+
1759+
1760+Finally the operation is done as these steps in kernel-space.
1761+- make sure that,
1762+ + no one else is using the file.
1763+ + the file is not hard-linked.
1764+ + the file is not pseudo-linked.
1765+ + the file is a regular file.
1766+ + the parent dir is not opaqued.
1767+- find the target writable branch.
1768+- make sure the file is not whiteout-ed by the upper (than the target)
1769+ branch.
1770+- make the parent dir on the target branch.
1771+- mutex lock the inode on the branch.
1772+- unlink the whiteout on the target branch (if exists).
1773+- lookup and create the whiteout-ed temporary name on the target branch.
1774+- copy the file as the whiteout-ed temporary name on the target branch.
1775+- rename the whiteout-ed temporary name to the original name.
1776+- unlink the file on the source branch.
1777+- maintain the internal pointer array and the external inode number
1778+ table (XINO).
1779+- maintain the timestamps and other attributes of the parent dir and the
1780+ file.
1781+
1782+And of course, in every step, an error may happen. So the operation
1783+should restore the original file state after an error happens.
53392da6
AM
1784diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1785--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 1786+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2015-04-13 15:10:20.776823376 +0200
523b37e3 1787@@ -0,0 +1,46 @@
53392da6 1788+
2000de60 1789+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1790+#
1791+# This program is free software; you can redistribute it and/or modify
1792+# it under the terms of the GNU General Public License as published by
1793+# the Free Software Foundation; either version 2 of the License, or
1794+# (at your option) any later version.
1795+#
1796+# This program is distributed in the hope that it will be useful,
1797+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1798+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1799+# GNU General Public License for more details.
1800+#
1801+# You should have received a copy of the GNU General Public License
523b37e3 1802+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1803+
1804+mmap(2) -- File Memory Mapping
1805+----------------------------------------------------------------------
1806+In aufs, the file-mapped pages are handled by a branch fs directly, no
1807+interaction with aufs. It means aufs_mmap() calls the branch fs's
1808+->mmap().
1809+This approach is simple and good, but there is one problem.
7e9cd9fe 1810+Under /proc, several entries show the mmapped files by its path (with
53392da6
AM
1811+device and inode number), and the printed path will be the path on the
1812+branch fs's instead of virtual aufs's.
1813+This is not a problem in most cases, but some utilities lsof(1) (and its
1814+user) may expect the path on aufs.
1815+
1816+To address this issue, aufs adds a new member called vm_prfile in struct
1817+vm_area_struct (and struct vm_region). The original vm_file points to
1818+the file on the branch fs in order to handle everything correctly as
1819+usual. The new vm_prfile points to a virtual file in aufs, and the
1820+show-functions in procfs refers to vm_prfile if it is set.
1821+Also we need to maintain several other places where touching vm_file
1822+such like
1823+- fork()/clone() copies vma and the reference count of vm_file is
1824+ incremented.
1825+- merging vma maintains the ref count too.
1826+
7e9cd9fe 1827+This is not a good approach. It just fakes the printed path. But it
53392da6
AM
1828+leaves all behaviour around f_mapping unchanged. This is surely an
1829+advantage.
1830+Actually aufs had adopted another complicated approach which calls
1831+generic_file_mmap() and handles struct vm_operations_struct. In this
1832+approach, aufs met a hard problem and I could not solve it without
1833+switching the approach.
c1595e42
JR
1834diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
1835--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 1836+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2015-04-13 15:10:20.776823376 +0200
c1595e42
JR
1837@@ -0,0 +1,96 @@
1838+
2000de60 1839+# Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
1840+#
1841+# This program is free software; you can redistribute it and/or modify
1842+# it under the terms of the GNU General Public License as published by
1843+# the Free Software Foundation; either version 2 of the License, or
1844+# (at your option) any later version.
1845+#
1846+# This program is distributed in the hope that it will be useful,
1847+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1848+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1849+# GNU General Public License for more details.
1850+#
1851+# You should have received a copy of the GNU General Public License
1852+# along with this program; if not, write to the Free Software
1853+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1854+
1855+
1856+Listing XATTR/EA and getting the value
1857+----------------------------------------------------------------------
1858+For the inode standard attributes (owner, group, timestamps, etc.), aufs
1859+shows the values from the topmost existing file. This behaviour is good
7e9cd9fe 1860+for the non-dir entries since the bahaviour exactly matches the shown
c1595e42
JR
1861+information. But for the directories, aufs considers all the same named
1862+entries on the lower branches. Which means, if one of the lower entry
1863+rejects readdir call, then aufs returns an error even if the topmost
1864+entry allows it. This behaviour is necessary to respect the branch fs's
1865+security, but can make users confused since the user-visible standard
1866+attributes don't match the behaviour.
1867+To address this issue, aufs has a mount option called dirperm1 which
1868+checks the permission for the topmost entry only, and ignores the lower
1869+entry's permission.
1870+
1871+A similar issue can happen around XATTR.
1872+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
7e9cd9fe
AM
1873+always set. Otherwise these very unpleasant situation would happen.
1874+- listxattr(2) may return the duplicated entries.
c1595e42
JR
1875+- users may not be able to remove or reset the XATTR forever,
1876+
1877+
1878+XATTR/EA support in the internal (copy,move)-(up,down)
1879+----------------------------------------------------------------------
7e9cd9fe 1880+Generally the extended attributes of inode are categorized as these.
c1595e42
JR
1881+- "security" for LSM and capability.
1882+- "system" for posix ACL, 'acl' mount option is required for the branch
1883+ fs generally.
1884+- "trusted" for userspace, CAP_SYS_ADMIN is required.
1885+- "user" for userspace, 'user_xattr' mount option is required for the
1886+ branch fs generally.
1887+
1888+Moreover there are some other categories. Aufs handles these rather
1889+unpopular categories as the ordinary ones, ie. there is no special
1890+condition nor exception.
1891+
1892+In copy-up, the support for XATTR on the dst branch may differ from the
1893+src branch. In this case, the copy-up operation will get an error and
7e9cd9fe
AM
1894+the original user operation which triggered the copy-up will fail. It
1895+can happen that even all copy-up will fail.
c1595e42
JR
1896+When both of src and dst branches support XATTR and if an error occurs
1897+during copying XATTR, then the copy-up should fail obviously. That is a
1898+good reason and aufs should return an error to userspace. But when only
7e9cd9fe 1899+the src branch support that XATTR, aufs should not return an error.
c1595e42
JR
1900+For example, the src branch supports ACL but the dst branch doesn't
1901+because the dst branch may natively un-support it or temporary
1902+un-support it due to "noacl" mount option. Of course, the dst branch fs
1903+may NOT return an error even if the XATTR is not supported. It is
1904+totally up to the branch fs.
1905+
1906+Anyway when the aufs internal copy-up gets an error from the dst branch
1907+fs, then aufs tries removing the just copied entry and returns the error
1908+to the userspace. The worst case of this situation will be all copy-up
1909+will fail.
1910+
1911+For the copy-up operation, there two basic approaches.
1912+- copy the specified XATTR only (by category above), and return the
7e9cd9fe 1913+ error unconditionally if it happens.
c1595e42
JR
1914+- copy all XATTR, and ignore the error on the specified category only.
1915+
1916+In order to support XATTR and to implement the correct behaviour, aufs
7e9cd9fe
AM
1917+chooses the latter approach and introduces some new branch attributes,
1918+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
c1595e42 1919+They correspond to the XATTR namespaces (see above). Additionally, to be
7e9cd9fe
AM
1920+convenient, "icex" is also provided which means all "icex*" attributes
1921+are set (here the word "icex" stands for "ignore copy-error on XATTR").
c1595e42
JR
1922+
1923+The meaning of these attributes is to ignore the error from setting
1924+XATTR on that branch.
1925+Note that aufs tries copying all XATTR unconditionally, and ignores the
1926+error from the dst branch according to the specified attributes.
1927+
1928+Some XATTR may have its default value. The default value may come from
1929+the parent dir or the environment. If the default value is set at the
1930+file creating-time, it will be overwritten by copy-up.
1931+Some contradiction may happen I am afraid.
1932+Do we need another attribute to stop copying XATTR? I am unsure. For
1933+now, aufs implements the branch attributes to ignore the error.
53392da6
AM
1934diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1935--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 1936+++ linux/Documentation/filesystems/aufs/design/07export.txt 2015-04-13 15:10:20.776823376 +0200
523b37e3 1937@@ -0,0 +1,58 @@
53392da6 1938+
2000de60 1939+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1940+#
1941+# This program is free software; you can redistribute it and/or modify
1942+# it under the terms of the GNU General Public License as published by
1943+# the Free Software Foundation; either version 2 of the License, or
1944+# (at your option) any later version.
1945+#
1946+# This program is distributed in the hope that it will be useful,
1947+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1948+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1949+# GNU General Public License for more details.
1950+#
1951+# You should have received a copy of the GNU General Public License
523b37e3 1952+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1953+
1954+Export Aufs via NFS
1955+----------------------------------------------------------------------
1956+Here is an approach.
1957+- like xino/xib, add a new file 'xigen' which stores aufs inode
1958+ generation.
1959+- iget_locked(): initialize aufs inode generation for a new inode, and
1960+ store it in xigen file.
1961+- destroy_inode(): increment aufs inode generation and store it in xigen
1962+ file. it is necessary even if it is not unlinked, because any data of
1963+ inode may be changed by UDBA.
1964+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1965+ build file handle by
1966+ + branch id (4 bytes)
1967+ + superblock generation (4 bytes)
1968+ + inode number (4 or 8 bytes)
1969+ + parent dir inode number (4 or 8 bytes)
1970+ + inode generation (4 bytes))
1971+ + return value of exportfs_encode_fh() for the parent on a branch (4
1972+ bytes)
1973+ + file handle for a branch (by exportfs_encode_fh())
1974+- fh_to_dentry():
1975+ + find the index of a branch from its id in handle, and check it is
1976+ still exist in aufs.
1977+ + 1st level: get the inode number from handle and search it in cache.
7e9cd9fe
AM
1978+ + 2nd level: if not found in cache, get the parent inode number from
1979+ the handle and search it in cache. and then open the found parent
1980+ dir, find the matching inode number by vfs_readdir() and get its
1981+ name, and call lookup_one_len() for the target dentry.
53392da6
AM
1982+ + 3rd level: if the parent dir is not cached, call
1983+ exportfs_decode_fh() for a branch and get the parent on a branch,
1984+ build a pathname of it, convert it a pathname in aufs, call
1985+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
1986+ the 2nd level.
1987+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1988+ for every branch, but not itself. to get this, (currently) aufs
1989+ searches in current->nsproxy->mnt_ns list. it may not be a good
1990+ idea, but I didn't get other approach.
1991+ + test the generation of the gotten inode.
1992+- every inode operation: they may get EBUSY due to UDBA. in this case,
1993+ convert it into ESTALE for NFSD.
1994+- readdir(): call lockdep_on/off() because filldir in NFSD calls
1995+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
1996diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1997--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 1998+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2015-04-13 15:10:20.776823376 +0200
523b37e3 1999@@ -0,0 +1,52 @@
53392da6 2000+
2000de60 2001+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
2002+#
2003+# This program is free software; you can redistribute it and/or modify
2004+# it under the terms of the GNU General Public License as published by
2005+# the Free Software Foundation; either version 2 of the License, or
2006+# (at your option) any later version.
2007+#
2008+# This program is distributed in the hope that it will be useful,
2009+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2010+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2011+# GNU General Public License for more details.
2012+#
2013+# You should have received a copy of the GNU General Public License
523b37e3 2014+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2015+
2016+Show Whiteout Mode (shwh)
2017+----------------------------------------------------------------------
2018+Generally aufs hides the name of whiteouts. But in some cases, to show
2019+them is very useful for users. For instance, creating a new middle layer
2020+(branch) by merging existing layers.
2021+
2022+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2023+When you have three branches,
2024+- Bottom: 'system', squashfs (underlying base system), read-only
2025+- Middle: 'mods', squashfs, read-only
2026+- Top: 'overlay', ram (tmpfs), read-write
2027+
2028+The top layer is loaded at boot time and saved at shutdown, to preserve
2029+the changes made to the system during the session.
2030+When larger changes have been made, or smaller changes have accumulated,
2031+the size of the saved top layer data grows. At this point, it would be
2032+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2033+and rewrite the 'mods' squashfs, clearing the top layer and thus
2034+restoring save and load speed.
2035+
2036+This merging is simplified by the use of another aufs mount, of just the
2037+two overlay branches using the 'shwh' option.
2038+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2039+ aufs /livesys/merge_union
2040+
2041+A merged view of these two branches is then available at
2042+/livesys/merge_union, and the new feature is that the whiteouts are
2043+visible!
2044+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2045+writing to all branches. Also the default mode for all branches is 'ro'.
2046+It is now possible to save the combined contents of the two overlay
2047+branches to a new squashfs, e.g.:
2048+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2049+
2050+This new squashfs archive can be stored on the boot device and the
2051+initramfs will use it to replace the old one at the next boot.
2052diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2053--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
2054+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2015-04-13 15:10:20.776823376 +0200
2055@@ -0,0 +1,47 @@
53392da6 2056+
2000de60 2057+# Copyright (C) 2010-2015 Junjiro R. Okajima
53392da6
AM
2058+#
2059+# This program is free software; you can redistribute it and/or modify
2060+# it under the terms of the GNU General Public License as published by
2061+# the Free Software Foundation; either version 2 of the License, or
2062+# (at your option) any later version.
2063+#
2064+# This program is distributed in the hope that it will be useful,
2065+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2066+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2067+# GNU General Public License for more details.
2068+#
2069+# You should have received a copy of the GNU General Public License
523b37e3 2070+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2071+
2072+Dynamically customizable FS operations
2073+----------------------------------------------------------------------
2074+Generally FS operations (struct inode_operations, struct
2075+address_space_operations, struct file_operations, etc.) are defined as
2076+"static const", but it never means that FS have only one set of
2077+operation. Some FS have multiple sets of them. For instance, ext2 has
2078+three sets, one for XIP, for NOBH, and for normal.
2079+Since aufs overrides and redirects these operations, sometimes aufs has
7e9cd9fe 2080+to change its behaviour according to the branch FS type. More importantly
53392da6
AM
2081+VFS acts differently if a function (member in the struct) is set or
2082+not. It means aufs should have several sets of operations and select one
2083+among them according to the branch FS definition.
2084+
7e9cd9fe 2085+In order to solve this problem and not to affect the behaviour of VFS,
53392da6 2086+aufs defines these operations dynamically. For instance, aufs defines
7e9cd9fe
AM
2087+dummy direct_IO function for struct address_space_operations, but it may
2088+not be set to the address_space_operations actually. When the branch FS
2089+doesn't have it, aufs doesn't set it to its address_space_operations
2090+while the function definition itself is still alive. So the behaviour
2091+itself will not change, and it will return an error when direct_IO is
2092+not set.
53392da6
AM
2093+
2094+The lifetime of these dynamically generated operation object is
2095+maintained by aufs branch object. When the branch is removed from aufs,
2096+the reference counter of the object is decremented. When it reaches
2097+zero, the dynamically generated operation object will be freed.
2098+
7e9cd9fe
AM
2099+This approach is designed to support AIO (io_submit), Direct I/O and
2100+XIP (DAX) mainly.
2101+Currently this approach is applied to address_space_operations for
2102+regular files only.
53392da6
AM
2103diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
2104--- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
2105+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2015-04-13 15:10:20.776823376 +0200
2106@@ -0,0 +1,57 @@
53392da6 2107+
2000de60 2108+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
2109+#
2110+# This program is free software; you can redistribute it and/or modify
2111+# it under the terms of the GNU General Public License as published by
2112+# the Free Software Foundation; either version 2 of the License, or
2113+# (at your option) any later version.
2114+#
2115+# This program is distributed in the hope that it will be useful,
2116+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2117+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2118+# GNU General Public License for more details.
2119+#
2120+# You should have received a copy of the GNU General Public License
523b37e3 2121+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2122+
2123+Plan
2124+
2125+Restoring some features which was implemented in aufs1.
2126+They were dropped in aufs2 in order to make source files simpler and
2127+easier to be reviewed.
2128+
2129+
53392da6
AM
2130+Being Another Aufs's Readonly Branch (robr)
2131+----------------------------------------------------------------------
2132+Aufs1 allows aufs to be another aufs's readonly branch.
2133+This feature was developed by a user's request. But it may not be used
7e9cd9fe 2134+currently.
53392da6
AM
2135+
2136+
53392da6
AM
2137+Refresh the Opened File (refrof)
2138+----------------------------------------------------------------------
2139+This option is implemented in aufs1 but incomplete.
2140+
2141+When user reads from a file, he expects to get its latest filedata
2142+generally. If the file is removed and a new same named file is created,
2143+the content he gets is unchanged, ie. the unlinked filedata.
2144+
2145+Let's try case study again.
2146+- aufs has two branches.
2147+ /au = /rw + /ro
2148+- "fileA" exists under /ro, but /rw.
2149+- user opened "/au/fileA".
2150+- he or someone else inserts a branch (/new) between /rw and /ro.
2151+ /au = /rw + /new + /ro
7e9cd9fe 2152+- the new branch contains "fileA".
53392da6
AM
2153+- user reads from the opened "fileA"
2154+- which filedata should aufs return, from /ro or /new?
2155+
2156+Some people says it has to be "from /ro" and it is a semantics of Unix.
2157+The others say it should be "from /new" because the file is not removed
2158+and it is equivalent to the case of someone else modifies the file.
2159+
2160+Here again I don't have a best and final answer. I got an idea to
2161+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
2162+Opened File) is specified (by default), aufs returns the filedata from
7e9cd9fe 2163+/new. Otherwise from /ro.
53392da6
AM
2164diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2165--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
2166+++ linux/Documentation/filesystems/aufs/README 2015-04-13 15:10:20.773489965 +0200
2167@@ -0,0 +1,384 @@
53392da6
AM
2168+
2169+Aufs3 -- advanced multi layered unification filesystem version 3.x
2170+http://aufs.sf.net
2171+Junjiro R. Okajima
2172+
2173+
2174+0. Introduction
2175+----------------------------------------
2176+In the early days, aufs was entirely re-designed and re-implemented
7e9cd9fe 2177+Unionfs Version 1.x series. Adding many original ideas, approaches,
53392da6
AM
2178+improvements and implementations, it becomes totally different from
2179+Unionfs while keeping the basic features.
2180+Recently, Unionfs Version 2.x series begin taking some of the same
2181+approaches to aufs1's.
2182+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2183+University and his team.
2184+
2185+Aufs3 supports linux-3.0 and later.
2186+If you want older kernel version support, try aufs2-2.6.git or
2187+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2188+
2189+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2190+ According to Christoph Hellwig, linux rejects all union-type
2191+ filesystems but UnionMount.
53392da6
AM
2192+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2193+
38d290e6
JR
2194+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2195+ UnionMount, and he pointed out an issue around a directory mutex
2196+ lock and aufs addressed it. But it is still unsure whether aufs will
2197+ be merged (or any other union solution).
076b876e 2198+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2199+
53392da6
AM
2200+
2201+1. Features
2202+----------------------------------------
2203+- unite several directories into a single virtual filesystem. The member
2204+ directory is called as a branch.
2205+- you can specify the permission flags to the branch, which are 'readonly',
2206+ 'readwrite' and 'whiteout-able.'
2207+- by upper writable branch, internal copyup and whiteout, files/dirs on
2208+ readonly branch are modifiable logically.
2209+- dynamic branch manipulation, add, del.
2210+- etc...
2211+
7e9cd9fe
AM
2212+Also there are many enhancements in aufs, such as:
2213+- test only the highest one for the directory permission (dirperm1)
2214+- copyup on open (coo=)
2215+- 'move' policy for copy-up between two writable branches, after
2216+ checking free space.
2217+- xattr, acl
53392da6
AM
2218+- readdir(3) in userspace.
2219+- keep inode number by external inode number table
2220+- keep the timestamps of file/dir in internal copyup operation
2221+- seekable directory, supporting NFS readdir.
2222+- whiteout is hardlinked in order to reduce the consumption of inodes
2223+ on branch
2224+- do not copyup, nor create a whiteout when it is unnecessary
2225+- revert a single systemcall when an error occurs in aufs
2226+- remount interface instead of ioctl
2227+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2228+- loopback mounted filesystem as a branch
2229+- kernel thread for removing the dir who has a plenty of whiteouts
2230+- support copyup sparse file (a file which has a 'hole' in it)
2231+- default permission flags for branches
2232+- selectable permission flags for ro branch, whether whiteout can
2233+ exist or not
2234+- export via NFS.
2235+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2236+- support multiple writable branches, some policies to select one
2237+ among multiple writable branches.
2238+- a new semantics for link(2) and rename(2) to support multiple
2239+ writable branches.
2240+- no glibc changes are required.
2241+- pseudo hardlink (hardlink over branches)
2242+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2243+ including NFS or remote filesystem branch.
2244+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2245+- and more...
2246+
2247+Currently these features are dropped temporary from aufs3.
2248+See design/08plan.txt in detail.
53392da6
AM
2249+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2250+ (robr)
2251+- statistics of aufs thread (/sys/fs/aufs/stat)
53392da6
AM
2252+
2253+Features or just an idea in the future (see also design/*.txt),
2254+- reorder the branch index without del/re-add.
2255+- permanent xino files for NFSD
2256+- an option for refreshing the opened files after add/del branches
53392da6
AM
2257+- light version, without branch manipulation. (unnecessary?)
2258+- copyup in userspace
2259+- inotify in userspace
2260+- readv/writev
53392da6
AM
2261+
2262+
2263+2. Download
2264+----------------------------------------
1e00d052
AM
2265+There were three GIT trees for aufs3, aufs3-linux.git,
2266+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
2267+"aufs-util.git."
2268+While the aufs-util is always necessary, you need either of aufs3-linux
2269+or aufs3-standalone.
2270+
2271+The aufs3-linux tree includes the whole linux mainline GIT tree,
2272+git://git.kernel.org/.../torvalds/linux.git.
2273+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
b4510431 2274+build aufs3 as an external kernel module.
2000de60
JR
2275+Several extra patches are not included in this tree. Only
2276+aufs3-standalong tree contains them. They are describe in the later
2277+section "Configuration and Compilation."
1e00d052
AM
2278+
2279+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6 2280+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2000de60 2281+But you need to apply all aufs patches manually.
53392da6
AM
2282+
2283+You will find GIT branches whose name is in form of "aufs3.x" where "x"
2284+represents the linux kernel version, "linux-3.x". For instance,
1e00d052
AM
2285+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
2286+"aufs3.x-rcN" branch.
2287+
2288+o aufs3-linux tree
2289+$ git clone --reference /your/linux/git/tree \
2000de60 2290+ git://git.code.sf.net/p/aufs/aufs3-linux aufs3-linux.git
1e00d052
AM
2291+- if you don't have linux GIT tree, then remove "--reference ..."
2292+$ cd aufs3-linux.git
2293+$ git checkout origin/aufs3.0
53392da6 2294+
2000de60
JR
2295+Or You may want to directly git-pull aufs into your linux GIT tree, and
2296+leave the patch-work to GIT.
2297+$ cd /your/linux/git/tree
2298+$ git remote add aufs3 https://github.com/sfjro/aufs3-linux.git
2299+- aufs3-linux.git tree also exists on github.
2300+$ git fetch aufs3
2301+$ git checkout -b my3.14 v3.14
2302+$ (add your change...)
2303+$ git pull aufs3 aufs3.14
2304+- now you have v3.14 + your_changes + aufs3.14 in you my3.14 branch.
2305+- you may need to solve some conflicts between your_changes and
2306+ aufs3.14. in this case, git-rerere is recommended so that you can
2307+ solve the similar confilicts automatically when you upgrade to 3.15 or
2308+ later in the future.
2309+
53392da6 2310+o aufs3-standalone tree
86dc4139 2311+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
53392da6
AM
2312+ aufs3-standalone.git
2313+$ cd aufs3-standalone.git
2314+$ git checkout origin/aufs3.0
2315+
2316+o aufs-util tree
86dc4139 2317+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
53392da6
AM
2318+ aufs-util.git
2319+$ cd aufs-util.git
2320+$ git checkout origin/aufs3.0
2321+
9dbd164d
AM
2322+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
2323+The minor version number, 'x' in '3.x', of aufs may not always
2324+follow the minor version number of the kernel.
2325+Because changes in the kernel that cause the use of a new
2326+minor version number do not always require changes to aufs-util.
2327+
2328+Since aufs-util has its own minor version number, you may not be
2329+able to find a GIT branch in aufs-util for your kernel's
2330+exact minor version number.
2331+In this case, you should git-checkout the branch for the
53392da6 2332+nearest lower number.
9dbd164d
AM
2333+
2334+For (an unreleased) example:
2335+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 2336+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
2337+or something numerically smaller is the branch for your kernel.
2338+
53392da6
AM
2339+Also you can view all branches by
2340+ $ git branch -a
2341+
2342+
2343+3. Configuration and Compilation
2344+----------------------------------------
2345+Make sure you have git-checkout'ed the correct branch.
2346+
1e00d052 2347+For aufs3-linux tree,
c06a8ce3 2348+- enable CONFIG_AUFS_FS.
1e00d052
AM
2349+- set other aufs configurations if necessary.
2350+
53392da6
AM
2351+For aufs3-standalone tree,
2352+There are several ways to build.
2353+
2354+1.
2355+- apply ./aufs3-kbuild.patch to your kernel source files.
2356+- apply ./aufs3-base.patch too.
523b37e3 2357+- apply ./aufs3-mmap.patch too.
53392da6
AM
2358+- apply ./aufs3-standalone.patch too, if you have a plan to set
2359+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
537831f9
AM
2360+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2361+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2362+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2363+ =m or =y.
2364+- and build your kernel as usual.
2365+- install the built kernel.
c06a8ce3
AM
2366+ Note: Since linux-3.9, every filesystem module requires an alias
2367+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2368+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2369+- install the header files too by "make headers_install" to the
2370+ directory where you specify. By default, it is $PWD/usr.
b4510431 2371+ "make help" shows a brief note for headers_install.
53392da6
AM
2372+- and reboot your system.
2373+
2374+2.
2375+- module only (CONFIG_AUFS_FS=m).
2376+- apply ./aufs3-base.patch to your kernel source files.
523b37e3 2377+- apply ./aufs3-mmap.patch too.
53392da6
AM
2378+- apply ./aufs3-standalone.patch too.
2379+- build your kernel, don't forget "make headers_install", and reboot.
2380+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2381+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2382+ every aufs configurations.
2383+- build the module by simple "make".
c06a8ce3
AM
2384+ Note: Since linux-3.9, every filesystem module requires an alias
2385+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2386+ modules.aliases file.
53392da6
AM
2387+- you can specify ${KDIR} make variable which points to your kernel
2388+ source tree.
2389+- install the files
2390+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2391+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2392+ + run "make install_headers" (instead of headers_install) to install
2393+ the modified aufs header file (you can specify DESTDIR which is
2394+ available in aufs standalone version's Makefile only), or copy
2395+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2396+ you like manually. By default, the target directory is $PWD/usr.
53392da6
AM
2397+- no need to apply aufs3-kbuild.patch, nor copying source files to your
2398+ kernel source tree.
2399+
b4510431 2400+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2401+ as well as "make headers_install" in the kernel source tree.
2402+ headers_install is subject to be forgotten, but it is essentially
2403+ necessary, not only for building aufs-util.
2404+ You may not meet problems without headers_install in some older
2405+ version though.
2406+
2407+And then,
2408+- read README in aufs-util, build and install it
9dbd164d
AM
2409+- note that your distribution may contain an obsoleted version of
2410+ aufs_type.h in /usr/include/linux or something. When you build aufs
2411+ utilities, make sure that your compiler refers the correct aufs header
2412+ file which is built by "make headers_install."
53392da6
AM
2413+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2414+ then run "make install_ulib" too. And refer to the aufs manual in
2415+ detail.
2416+
38d290e6
JR
2417+There several other patches in aufs3-standalone.git. They are all
2418+optional. When you meet some problems, they will help you.
2419+- aufs3-loopback.patch
2420+ Supports a nested loopback mount in a branch-fs. This patch is
2421+ unnecessary until aufs produces a message like "you may want to try
2422+ another patch for loopback file".
2423+- vfs-ino.patch
2424+ Modifies a system global kernel internal function get_next_ino() in
2425+ order to stop assigning 0 for an inode-number. Not directly related to
2426+ aufs, but recommended generally.
2427+- tmpfs-idr.patch
2428+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2429+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2430+ duplication of inode number, which is important for backup tools and
2431+ other utilities. When you find aufs XINO files for tmpfs branch
2432+ growing too much, try this patch.
2433+
53392da6
AM
2434+
2435+4. Usage
2436+----------------------------------------
2437+At first, make sure aufs-util are installed, and please read the aufs
2438+manual, aufs.5 in aufs-util.git tree.
2439+$ man -l aufs.5
2440+
2441+And then,
2442+$ mkdir /tmp/rw /tmp/aufs
2443+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2444+
2445+Here is another example. The result is equivalent.
2446+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2447+ Or
2448+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2449+# mount -o remount,append:${HOME} /tmp/aufs
2450+
2451+Then, you can see whole tree of your home dir through /tmp/aufs. If
2452+you modify a file under /tmp/aufs, the one on your home directory is
2453+not affected, instead the same named file will be newly created under
2454+/tmp/rw. And all of your modification to a file will be applied to
2455+the one under /tmp/rw. This is called the file based Copy on Write
2456+(COW) method.
2457+Aufs mount options are described in aufs.5.
2458+If you run chroot or something and make your aufs as a root directory,
2459+then you need to customize the shutdown script. See the aufs manual in
2460+detail.
2461+
2462+Additionally, there are some sample usages of aufs which are a
2463+diskless system with network booting, and LiveCD over NFS.
2464+See sample dir in CVS tree on SourceForge.
2465+
2466+
2467+5. Contact
2468+----------------------------------------
2469+When you have any problems or strange behaviour in aufs, please let me
2470+know with:
2471+- /proc/mounts (instead of the output of mount(8))
2472+- /sys/module/aufs/*
2473+- /sys/fs/aufs/* (if you have them)
2474+- /debug/aufs/* (if you have them)
2475+- linux kernel version
2476+ if your kernel is not plain, for example modified by distributor,
2477+ the url where i can download its source is necessary too.
2478+- aufs version which was printed at loading the module or booting the
2479+ system, instead of the date you downloaded.
2480+- configuration (define/undefine CONFIG_AUFS_xxx)
2481+- kernel configuration or /proc/config.gz (if you have it)
2482+- behaviour which you think to be incorrect
2483+- actual operation, reproducible one is better
2484+- mailto: aufs-users at lists.sourceforge.net
2485+
2486+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2487+and Feature Requests) on SourceForge. Please join and write to
2488+aufs-users ML.
2489+
2490+
2491+6. Acknowledgements
2492+----------------------------------------
2493+Thanks to everyone who have tried and are using aufs, whoever
2494+have reported a bug or any feedback.
2495+
2496+Especially donators:
2497+Tomas Matejicek(slax.org) made a donation (much more than once).
2498+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2499+ scripts) is making "doubling" donations.
2500+ Unfortunately I cannot list all of the donators, but I really
b4510431 2501+ appreciate.
53392da6
AM
2502+ It ends Aug 2010, but the ordinary donation URL is still available.
2503+ <http://sourceforge.net/donate/index.php?group_id=167503>
2504+Dai Itasaka made a donation (2007/8).
2505+Chuck Smith made a donation (2008/4, 10 and 12).
2506+Henk Schoneveld made a donation (2008/9).
2507+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2508+Francois Dupoux made a donation (2008/11).
2509+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2510+ aufs2 GIT tree (2009/2).
2511+William Grant made a donation (2009/3).
2512+Patrick Lane made a donation (2009/4).
2513+The Mail Archive (mail-archive.com) made donations (2009/5).
2514+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2515+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2516+Pavel Pronskiy made a donation (2011/2).
2517+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2518+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
2519+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2520+11).
1e00d052 2521+Sam Liddicott made a donation (2011/9).
86dc4139
AM
2522+Era Scarecrow made a donation (2013/4).
2523+Bor Ratajc made a donation (2013/4).
2524+Alessandro Gorreta made a donation (2013/4).
2525+POIRETTE Marc made a donation (2013/4).
2526+Alessandro Gorreta made a donation (2013/4).
2527+lauri kasvandik made a donation (2013/5).
392086de 2528+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
2529+The Parted Magic Project made a donation (2013/9 and 11).
2530+Pavel Barta made a donation (2013/10).
38d290e6 2531+Nikolay Pertsev made a donation (2014/5).
076b876e
AM
2532+James B made a donation (2014/7).
2533+Stefano Di Biase made a donation (2014/8).
2000de60 2534+Daniel Epellei made a donation (2015/1).
53392da6
AM
2535+
2536+Thank you very much.
2537+Donations are always, including future donations, very important and
2538+helpful for me to keep on developing aufs.
2539+
2540+
2541+7.
2542+----------------------------------------
2543+If you are an experienced user, no explanation is needed. Aufs is
2544+just a linux filesystem.
2545+
2546+
2547+Enjoy!
2548+
2549+# Local variables: ;
2550+# mode: text;
2551+# End: ;
7f207e10
AM
2552diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
2553--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 2554+++ linux/fs/aufs/aufs.h 2015-04-13 15:10:20.776823376 +0200
523b37e3 2555@@ -0,0 +1,59 @@
7f207e10 2556+/*
2000de60 2557+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
2558+ *
2559+ * This program, aufs is free software; you can redistribute it and/or modify
2560+ * it under the terms of the GNU General Public License as published by
2561+ * the Free Software Foundation; either version 2 of the License, or
2562+ * (at your option) any later version.
2563+ *
2564+ * This program is distributed in the hope that it will be useful,
2565+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2566+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2567+ * GNU General Public License for more details.
2568+ *
2569+ * You should have received a copy of the GNU General Public License
523b37e3 2570+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2571+ */
2572+
2573+/*
2574+ * all header files
2575+ */
2576+
2577+#ifndef __AUFS_H__
2578+#define __AUFS_H__
2579+
2580+#ifdef __KERNEL__
2581+
2582+#define AuStub(type, name, body, ...) \
2583+ static inline type name(__VA_ARGS__) { body; }
2584+
2585+#define AuStubVoid(name, ...) \
2586+ AuStub(void, name, , __VA_ARGS__)
2587+#define AuStubInt0(name, ...) \
2588+ AuStub(int, name, return 0, __VA_ARGS__)
2589+
2590+#include "debug.h"
2591+
2592+#include "branch.h"
2593+#include "cpup.h"
2594+#include "dcsub.h"
2595+#include "dbgaufs.h"
2596+#include "dentry.h"
2597+#include "dir.h"
2598+#include "dynop.h"
2599+#include "file.h"
2600+#include "fstype.h"
2601+#include "inode.h"
2602+#include "loop.h"
2603+#include "module.h"
7f207e10
AM
2604+#include "opts.h"
2605+#include "rwsem.h"
2606+#include "spl.h"
2607+#include "super.h"
2608+#include "sysaufs.h"
2609+#include "vfsub.h"
2610+#include "whout.h"
2611+#include "wkq.h"
2612+
2613+#endif /* __KERNEL__ */
2614+#endif /* __AUFS_H__ */
2615diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
2616--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
2617+++ linux/fs/aufs/branch.c 2015-04-13 15:10:20.780156788 +0200
2618@@ -0,0 +1,1406 @@
7f207e10 2619+/*
2000de60 2620+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
2621+ *
2622+ * This program, aufs is free software; you can redistribute it and/or modify
2623+ * it under the terms of the GNU General Public License as published by
2624+ * the Free Software Foundation; either version 2 of the License, or
2625+ * (at your option) any later version.
2626+ *
2627+ * This program is distributed in the hope that it will be useful,
2628+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2629+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2630+ * GNU General Public License for more details.
2631+ *
2632+ * You should have received a copy of the GNU General Public License
523b37e3 2633+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2634+ */
2635+
2636+/*
2637+ * branch management
2638+ */
2639+
027c5e7a 2640+#include <linux/compat.h>
7f207e10
AM
2641+#include <linux/statfs.h>
2642+#include "aufs.h"
2643+
2644+/*
2645+ * free a single branch
1facf9fc 2646+ */
2647+static void au_br_do_free(struct au_branch *br)
2648+{
2649+ int i;
2650+ struct au_wbr *wbr;
4a4d8108 2651+ struct au_dykey **key;
1facf9fc 2652+
027c5e7a
AM
2653+ au_hnotify_fin_br(br);
2654+
1facf9fc 2655+ if (br->br_xino.xi_file)
2656+ fput(br->br_xino.xi_file);
2657+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
2658+
2659+ AuDebugOn(atomic_read(&br->br_count));
2660+
2661+ wbr = br->br_wbr;
2662+ if (wbr) {
2663+ for (i = 0; i < AuBrWh_Last; i++)
2664+ dput(wbr->wbr_wh[i]);
2665+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 2666+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 2667+ }
2668+
076b876e
AM
2669+ if (br->br_fhsm) {
2670+ au_br_fhsm_fin(br->br_fhsm);
2671+ kfree(br->br_fhsm);
2672+ }
2673+
4a4d8108
AM
2674+ key = br->br_dykey;
2675+ for (i = 0; i < AuBrDynOp; i++, key++)
2676+ if (*key)
2677+ au_dy_put(*key);
2678+ else
2679+ break;
2680+
537831f9
AM
2681+ /* recursive lock, s_umount of branch's */
2682+ lockdep_off();
86dc4139 2683+ path_put(&br->br_path);
537831f9 2684+ lockdep_on();
1facf9fc 2685+ kfree(wbr);
2686+ kfree(br);
2687+}
2688+
2689+/*
2690+ * frees all branches
2691+ */
2692+void au_br_free(struct au_sbinfo *sbinfo)
2693+{
2694+ aufs_bindex_t bmax;
2695+ struct au_branch **br;
2696+
dece6358
AM
2697+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2698+
1facf9fc 2699+ bmax = sbinfo->si_bend + 1;
2700+ br = sbinfo->si_branch;
2701+ while (bmax--)
2702+ au_br_do_free(*br++);
2703+}
2704+
2705+/*
2706+ * find the index of a branch which is specified by @br_id.
2707+ */
2708+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2709+{
2710+ aufs_bindex_t bindex, bend;
2711+
2712+ bend = au_sbend(sb);
2713+ for (bindex = 0; bindex <= bend; bindex++)
2714+ if (au_sbr_id(sb, bindex) == br_id)
2715+ return bindex;
2716+ return -1;
2717+}
2718+
2719+/* ---------------------------------------------------------------------- */
2720+
2721+/*
2722+ * add a branch
2723+ */
2724+
b752ccd1
AM
2725+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2726+ struct dentry *h_root)
1facf9fc 2727+{
b752ccd1
AM
2728+ if (unlikely(h_adding == h_root
2729+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2730+ return 1;
b752ccd1
AM
2731+ if (h_adding->d_sb != h_root->d_sb)
2732+ return 0;
2733+ return au_test_subdir(h_adding, h_root)
2734+ || au_test_subdir(h_root, h_adding);
1facf9fc 2735+}
2736+
2737+/*
2738+ * returns a newly allocated branch. @new_nbranch is a number of branches
2739+ * after adding a branch.
2740+ */
2741+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2742+ int perm)
2743+{
2744+ struct au_branch *add_branch;
2745+ struct dentry *root;
4a4d8108 2746+ int err;
1facf9fc 2747+
4a4d8108 2748+ err = -ENOMEM;
1facf9fc 2749+ root = sb->s_root;
2750+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2751+ if (unlikely(!add_branch))
2752+ goto out;
2753+
027c5e7a
AM
2754+ err = au_hnotify_init_br(add_branch, perm);
2755+ if (unlikely(err))
2756+ goto out_br;
2757+
1facf9fc 2758+ add_branch->br_wbr = NULL;
2759+ if (au_br_writable(perm)) {
2760+ /* may be freed separately at changing the branch permission */
2761+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2762+ GFP_NOFS);
2763+ if (unlikely(!add_branch->br_wbr))
027c5e7a 2764+ goto out_hnotify;
1facf9fc 2765+ }
2766+
076b876e
AM
2767+ add_branch->br_fhsm = NULL;
2768+ if (au_br_fhsm(perm)) {
2769+ err = au_fhsm_br_alloc(add_branch);
2770+ if (unlikely(err))
2771+ goto out_wbr;
2772+ }
2773+
4a4d8108
AM
2774+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2775+ if (!err)
2776+ err = au_di_realloc(au_di(root), new_nbranch);
2777+ if (!err)
2778+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2779+ if (!err)
2780+ return add_branch; /* success */
1facf9fc 2781+
076b876e 2782+out_wbr:
1facf9fc 2783+ kfree(add_branch->br_wbr);
027c5e7a
AM
2784+out_hnotify:
2785+ au_hnotify_fin_br(add_branch);
4f0767ce 2786+out_br:
1facf9fc 2787+ kfree(add_branch);
4f0767ce 2788+out:
4a4d8108 2789+ return ERR_PTR(err);
1facf9fc 2790+}
2791+
2792+/*
2793+ * test if the branch permission is legal or not.
2794+ */
2795+static int test_br(struct inode *inode, int brperm, char *path)
2796+{
2797+ int err;
2798+
4a4d8108
AM
2799+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2800+ if (!err)
2801+ goto out;
1facf9fc 2802+
4a4d8108
AM
2803+ err = -EINVAL;
2804+ pr_err("write permission for readonly mount or inode, %s\n", path);
2805+
4f0767ce 2806+out:
1facf9fc 2807+ return err;
2808+}
2809+
2810+/*
2811+ * returns:
2812+ * 0: success, the caller will add it
2813+ * plus: success, it is already unified, the caller should ignore it
2814+ * minus: error
2815+ */
2816+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2817+{
2818+ int err;
2819+ aufs_bindex_t bend, bindex;
2820+ struct dentry *root;
2821+ struct inode *inode, *h_inode;
2822+
2823+ root = sb->s_root;
2824+ bend = au_sbend(sb);
2825+ if (unlikely(bend >= 0
2826+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2827+ err = 1;
2828+ if (!remount) {
2829+ err = -EINVAL;
4a4d8108 2830+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2831+ }
2832+ goto out;
2833+ }
2834+
2835+ err = -ENOSPC; /* -E2BIG; */
2836+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2837+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2838+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2839+ goto out;
2840+ }
2841+
2842+ err = -EDOM;
2843+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2844+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2845+ goto out;
2846+ }
2847+
2848+ inode = add->path.dentry->d_inode;
2849+ err = -ENOENT;
2850+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2851+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2852+ goto out;
2853+ }
2854+
2855+ err = -EINVAL;
2856+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2857+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2858+ goto out;
2859+ }
2860+
2861+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2862+ pr_err("unsupported filesystem, %s (%s)\n",
2863+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2864+ goto out;
2865+ }
2866+
c1595e42
JR
2867+ if (unlikely(inode->i_sb->s_stack_depth)) {
2868+ pr_err("already stacked, %s (%s)\n",
2869+ add->pathname, au_sbtype(inode->i_sb));
2870+ goto out;
2871+ }
2872+
1facf9fc 2873+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2874+ if (unlikely(err))
2875+ goto out;
2876+
2877+ if (bend < 0)
2878+ return 0; /* success */
2879+
2880+ err = -EINVAL;
2881+ for (bindex = 0; bindex <= bend; bindex++)
2882+ if (unlikely(test_overlap(sb, add->path.dentry,
2883+ au_h_dptr(root, bindex)))) {
4a4d8108 2884+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 2885+ goto out;
2886+ }
2887+
2888+ err = 0;
2889+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2890+ h_inode = au_h_dptr(root, 0)->d_inode;
2891+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
2892+ || !uid_eq(h_inode->i_uid, inode->i_uid)
2893+ || !gid_eq(h_inode->i_gid, inode->i_gid))
2894+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2895+ add->pathname,
2896+ i_uid_read(inode), i_gid_read(inode),
2897+ (inode->i_mode & S_IALLUGO),
2898+ i_uid_read(h_inode), i_gid_read(h_inode),
2899+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 2900+ }
2901+
4f0767ce 2902+out:
1facf9fc 2903+ return err;
2904+}
2905+
2906+/*
2907+ * initialize or clean the whiteouts for an adding branch
2908+ */
2909+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 2910+ int new_perm)
1facf9fc 2911+{
2912+ int err, old_perm;
2913+ aufs_bindex_t bindex;
2914+ struct mutex *h_mtx;
2915+ struct au_wbr *wbr;
2916+ struct au_hinode *hdir;
2917+
86dc4139
AM
2918+ err = vfsub_mnt_want_write(au_br_mnt(br));
2919+ if (unlikely(err))
2920+ goto out;
2921+
1facf9fc 2922+ wbr = br->br_wbr;
2923+ old_perm = br->br_perm;
2924+ br->br_perm = new_perm;
2925+ hdir = NULL;
2926+ h_mtx = NULL;
2927+ bindex = au_br_index(sb, br->br_id);
2928+ if (0 <= bindex) {
2929+ hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 2930+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2931+ } else {
86dc4139 2932+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
1facf9fc 2933+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2934+ }
2935+ if (!wbr)
86dc4139 2936+ err = au_wh_init(br, sb);
1facf9fc 2937+ else {
2938+ wbr_wh_write_lock(wbr);
86dc4139 2939+ err = au_wh_init(br, sb);
1facf9fc 2940+ wbr_wh_write_unlock(wbr);
2941+ }
2942+ if (hdir)
4a4d8108 2943+ au_hn_imtx_unlock(hdir);
1facf9fc 2944+ else
2945+ mutex_unlock(h_mtx);
86dc4139 2946+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 2947+ br->br_perm = old_perm;
2948+
2949+ if (!err && wbr && !au_br_writable(new_perm)) {
2950+ kfree(wbr);
2951+ br->br_wbr = NULL;
2952+ }
2953+
86dc4139 2954+out:
1facf9fc 2955+ return err;
2956+}
2957+
2958+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 2959+ int perm)
1facf9fc 2960+{
2961+ int err;
4a4d8108 2962+ struct kstatfs kst;
1facf9fc 2963+ struct au_wbr *wbr;
2964+
2965+ wbr = br->br_wbr;
dece6358 2966+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 2967+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2968+ atomic_set(&wbr->wbr_wh_running, 0);
2969+ wbr->wbr_bytes = 0;
2970+
4a4d8108
AM
2971+ /*
2972+ * a limit for rmdir/rename a dir
523b37e3 2973+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 2974+ */
86dc4139 2975+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
2976+ if (unlikely(err))
2977+ goto out;
2978+ err = -EINVAL;
2979+ if (kst.f_namelen >= NAME_MAX)
86dc4139 2980+ err = au_br_init_wh(sb, br, perm);
4a4d8108 2981+ else
523b37e3
AM
2982+ pr_err("%pd(%s), unsupported namelen %ld\n",
2983+ au_br_dentry(br),
86dc4139 2984+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 2985+
4f0767ce 2986+out:
1facf9fc 2987+ return err;
2988+}
2989+
c1595e42 2990+/* initialize a new branch */
1facf9fc 2991+static int au_br_init(struct au_branch *br, struct super_block *sb,
2992+ struct au_opt_add *add)
2993+{
2994+ int err;
2995+
2996+ err = 0;
2997+ memset(&br->br_xino, 0, sizeof(br->br_xino));
2998+ mutex_init(&br->br_xino.xi_nondir_mtx);
2999+ br->br_perm = add->perm;
86dc4139 3000+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108
AM
3001+ spin_lock_init(&br->br_dykey_lock);
3002+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 3003+ atomic_set(&br->br_count, 0);
1facf9fc 3004+ atomic_set(&br->br_xino_running, 0);
3005+ br->br_id = au_new_br_id(sb);
7f207e10 3006+ AuDebugOn(br->br_id < 0);
1facf9fc 3007+
3008+ if (au_br_writable(add->perm)) {
86dc4139 3009+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 3010+ if (unlikely(err))
b752ccd1 3011+ goto out_err;
1facf9fc 3012+ }
3013+
3014+ if (au_opt_test(au_mntflags(sb), XINO)) {
3015+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
3016+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
3017+ if (unlikely(err)) {
3018+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 3019+ goto out_err;
1facf9fc 3020+ }
3021+ }
3022+
3023+ sysaufs_br_init(br);
86dc4139 3024+ path_get(&br->br_path);
b752ccd1 3025+ goto out; /* success */
1facf9fc 3026+
4f0767ce 3027+out_err:
86dc4139 3028+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 3029+out:
1facf9fc 3030+ return err;
3031+}
3032+
3033+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
3034+ struct au_branch *br, aufs_bindex_t bend,
3035+ aufs_bindex_t amount)
3036+{
3037+ struct au_branch **brp;
3038+
dece6358
AM
3039+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3040+
1facf9fc 3041+ brp = sbinfo->si_branch + bindex;
3042+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3043+ *brp = br;
3044+ sbinfo->si_bend++;
3045+ if (unlikely(bend < 0))
3046+ sbinfo->si_bend = 0;
3047+}
3048+
3049+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
3050+ aufs_bindex_t bend, aufs_bindex_t amount)
3051+{
3052+ struct au_hdentry *hdp;
3053+
1308ab2a 3054+ AuRwMustWriteLock(&dinfo->di_rwsem);
3055+
1facf9fc 3056+ hdp = dinfo->di_hdentry + bindex;
3057+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3058+ au_h_dentry_init(hdp);
3059+ dinfo->di_bend++;
3060+ if (unlikely(bend < 0))
3061+ dinfo->di_bstart = 0;
3062+}
3063+
3064+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
3065+ aufs_bindex_t bend, aufs_bindex_t amount)
3066+{
3067+ struct au_hinode *hip;
3068+
1308ab2a 3069+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3070+
1facf9fc 3071+ hip = iinfo->ii_hinode + bindex;
3072+ memmove(hip + 1, hip, sizeof(*hip) * amount);
3073+ hip->hi_inode = NULL;
4a4d8108 3074+ au_hn_init(hip);
1facf9fc 3075+ iinfo->ii_bend++;
3076+ if (unlikely(bend < 0))
3077+ iinfo->ii_bstart = 0;
3078+}
3079+
86dc4139
AM
3080+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3081+ aufs_bindex_t bindex)
1facf9fc 3082+{
86dc4139 3083+ struct dentry *root, *h_dentry;
1facf9fc 3084+ struct inode *root_inode;
3085+ aufs_bindex_t bend, amount;
3086+
3087+ root = sb->s_root;
3088+ root_inode = root->d_inode;
1facf9fc 3089+ bend = au_sbend(sb);
3090+ amount = bend + 1 - bindex;
86dc4139 3091+ h_dentry = au_br_dentry(br);
53392da6 3092+ au_sbilist_lock();
1facf9fc 3093+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
3094+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
3095+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
3096+ au_set_h_dptr(root, bindex, dget(h_dentry));
3097+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
3098+ /*flags*/0);
53392da6 3099+ au_sbilist_unlock();
1facf9fc 3100+}
3101+
3102+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3103+{
3104+ int err;
1facf9fc 3105+ aufs_bindex_t bend, add_bindex;
3106+ struct dentry *root, *h_dentry;
3107+ struct inode *root_inode;
3108+ struct au_branch *add_branch;
3109+
3110+ root = sb->s_root;
3111+ root_inode = root->d_inode;
3112+ IMustLock(root_inode);
3113+ err = test_add(sb, add, remount);
3114+ if (unlikely(err < 0))
3115+ goto out;
3116+ if (err) {
3117+ err = 0;
3118+ goto out; /* success */
3119+ }
3120+
3121+ bend = au_sbend(sb);
3122+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
3123+ err = PTR_ERR(add_branch);
3124+ if (IS_ERR(add_branch))
3125+ goto out;
3126+
3127+ err = au_br_init(add_branch, sb, add);
3128+ if (unlikely(err)) {
3129+ au_br_do_free(add_branch);
3130+ goto out;
3131+ }
3132+
3133+ add_bindex = add->bindex;
1facf9fc 3134+ if (!remount)
86dc4139 3135+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3136+ else {
3137+ sysaufs_brs_del(sb, add_bindex);
86dc4139 3138+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3139+ sysaufs_brs_add(sb, add_bindex);
3140+ }
3141+
86dc4139 3142+ h_dentry = add->path.dentry;
1308ab2a 3143+ if (!add_bindex) {
1facf9fc 3144+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3145+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3146+ } else
1facf9fc 3147+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 3148+
3149+ /*
4a4d8108 3150+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 3151+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 3152+ * once detached from aufs.
3153+ */
3154+ if (au_xino_brid(sb) < 0
3155+ && au_br_writable(add_branch->br_perm)
3156+ && !au_test_fs_bad_xino(h_dentry->d_sb)
3157+ && add_branch->br_xino.xi_file
2000de60 3158+ && add_branch->br_xino.xi_file->f_path.dentry->d_parent == h_dentry)
1facf9fc 3159+ au_xino_brid_set(sb, add_branch->br_id);
3160+
4f0767ce 3161+out:
1facf9fc 3162+ return err;
3163+}
3164+
3165+/* ---------------------------------------------------------------------- */
3166+
076b876e
AM
3167+static unsigned long long au_farray_cb(void *a,
3168+ unsigned long long max __maybe_unused,
3169+ void *arg)
3170+{
3171+ unsigned long long n;
3172+ struct file **p, *f;
3173+ struct au_sphlhead *files;
3174+ struct au_finfo *finfo;
3175+ struct super_block *sb = arg;
3176+
3177+ n = 0;
3178+ p = a;
3179+ files = &au_sbi(sb)->si_files;
3180+ spin_lock(&files->spin);
3181+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
3182+ f = finfo->fi_file;
3183+ if (file_count(f)
3184+ && !special_file(file_inode(f)->i_mode)) {
3185+ get_file(f);
3186+ *p++ = f;
3187+ n++;
3188+ AuDebugOn(n > max);
3189+ }
3190+ }
3191+ spin_unlock(&files->spin);
3192+
3193+ return n;
3194+}
3195+
3196+static struct file **au_farray_alloc(struct super_block *sb,
3197+ unsigned long long *max)
3198+{
3199+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
3200+ return au_array_alloc(max, au_farray_cb, sb);
3201+}
3202+
3203+static void au_farray_free(struct file **a, unsigned long long max)
3204+{
3205+ unsigned long long ull;
3206+
3207+ for (ull = 0; ull < max; ull++)
3208+ if (a[ull])
3209+ fput(a[ull]);
3210+ au_array_free(a);
3211+}
3212+
3213+/* ---------------------------------------------------------------------- */
3214+
1facf9fc 3215+/*
3216+ * delete a branch
3217+ */
3218+
3219+/* to show the line number, do not make it inlined function */
4a4d8108 3220+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3221+ if (do_info) \
4a4d8108 3222+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3223+} while (0)
3224+
027c5e7a
AM
3225+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
3226+ aufs_bindex_t bend)
3227+{
3228+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
3229+}
3230+
3231+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
3232+ aufs_bindex_t bend)
3233+{
3234+ return au_test_ibusy(dentry->d_inode, bstart, bend);
3235+}
3236+
1facf9fc 3237+/*
3238+ * test if the branch is deletable or not.
3239+ */
3240+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3241+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3242+{
3243+ int err, i, j, ndentry;
3244+ aufs_bindex_t bstart, bend;
1facf9fc 3245+ struct au_dcsub_pages dpages;
3246+ struct au_dpage *dpage;
3247+ struct dentry *d;
1facf9fc 3248+
3249+ err = au_dpages_init(&dpages, GFP_NOFS);
3250+ if (unlikely(err))
3251+ goto out;
3252+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3253+ if (unlikely(err))
3254+ goto out_dpages;
3255+
1facf9fc 3256+ for (i = 0; !err && i < dpages.ndpage; i++) {
3257+ dpage = dpages.dpages + i;
3258+ ndentry = dpage->ndentry;
3259+ for (j = 0; !err && j < ndentry; j++) {
3260+ d = dpage->dentries[j];
c1595e42 3261+ AuDebugOn(au_dcount(d) <= 0);
027c5e7a 3262+ if (!au_digen_test(d, sigen)) {
1facf9fc 3263+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3264+ if (unlikely(au_dbrange_test(d))) {
3265+ di_read_unlock(d, AuLock_IR);
3266+ continue;
3267+ }
3268+ } else {
1facf9fc 3269+ di_write_lock_child(d);
027c5e7a
AM
3270+ if (unlikely(au_dbrange_test(d))) {
3271+ di_write_unlock(d);
3272+ continue;
3273+ }
1facf9fc 3274+ err = au_reval_dpath(d, sigen);
3275+ if (!err)
3276+ di_downgrade_lock(d, AuLock_IR);
3277+ else {
3278+ di_write_unlock(d);
3279+ break;
3280+ }
3281+ }
3282+
027c5e7a 3283+ /* AuDbgDentry(d); */
1facf9fc 3284+ bstart = au_dbstart(d);
3285+ bend = au_dbend(d);
3286+ if (bstart <= bindex
3287+ && bindex <= bend
3288+ && au_h_dptr(d, bindex)
027c5e7a 3289+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 3290+ err = -EBUSY;
523b37e3 3291+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3292+ AuDbgDentry(d);
1facf9fc 3293+ }
3294+ di_read_unlock(d, AuLock_IR);
3295+ }
3296+ }
3297+
4f0767ce 3298+out_dpages:
1facf9fc 3299+ au_dpages_free(&dpages);
4f0767ce 3300+out:
1facf9fc 3301+ return err;
3302+}
3303+
3304+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3305+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3306+{
3307+ int err;
7f207e10
AM
3308+ unsigned long long max, ull;
3309+ struct inode *i, **array;
1facf9fc 3310+ aufs_bindex_t bstart, bend;
1facf9fc 3311+
7f207e10
AM
3312+ array = au_iarray_alloc(sb, &max);
3313+ err = PTR_ERR(array);
3314+ if (IS_ERR(array))
3315+ goto out;
3316+
1facf9fc 3317+ err = 0;
7f207e10
AM
3318+ AuDbg("b%d\n", bindex);
3319+ for (ull = 0; !err && ull < max; ull++) {
3320+ i = array[ull];
076b876e
AM
3321+ if (unlikely(!i))
3322+ break;
7f207e10 3323+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3324+ continue;
3325+
7f207e10 3326+ /* AuDbgInode(i); */
537831f9 3327+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3328+ ii_read_lock_child(i);
3329+ else {
3330+ ii_write_lock_child(i);
027c5e7a
AM
3331+ err = au_refresh_hinode_self(i);
3332+ au_iigen_dec(i);
1facf9fc 3333+ if (!err)
3334+ ii_downgrade_lock(i);
3335+ else {
3336+ ii_write_unlock(i);
3337+ break;
3338+ }
3339+ }
3340+
3341+ bstart = au_ibstart(i);
3342+ bend = au_ibend(i);
3343+ if (bstart <= bindex
3344+ && bindex <= bend
3345+ && au_h_iptr(i, bindex)
027c5e7a 3346+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 3347+ err = -EBUSY;
3348+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3349+ AuDbgInode(i);
1facf9fc 3350+ }
3351+ ii_read_unlock(i);
3352+ }
7f207e10 3353+ au_iarray_free(array, max);
1facf9fc 3354+
7f207e10 3355+out:
1facf9fc 3356+ return err;
3357+}
3358+
b752ccd1
AM
3359+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3360+ const unsigned int verbose)
1facf9fc 3361+{
3362+ int err;
3363+ unsigned int sigen;
3364+
3365+ sigen = au_sigen(root->d_sb);
3366+ DiMustNoWaiters(root);
3367+ IiMustNoWaiters(root->d_inode);
3368+ di_write_unlock(root);
b752ccd1 3369+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3370+ if (!err)
b752ccd1 3371+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3372+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3373+
3374+ return err;
3375+}
3376+
076b876e
AM
3377+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3378+ struct file **to_free, int *idx)
3379+{
3380+ int err;
c1595e42 3381+ unsigned char matched, root;
076b876e
AM
3382+ aufs_bindex_t bindex, bend;
3383+ struct au_fidir *fidir;
3384+ struct au_hfile *hfile;
3385+
3386+ err = 0;
2000de60 3387+ root = IS_ROOT(file->f_path.dentry);
c1595e42
JR
3388+ if (root) {
3389+ get_file(file);
3390+ to_free[*idx] = file;
3391+ (*idx)++;
3392+ goto out;
3393+ }
3394+
076b876e 3395+ matched = 0;
076b876e
AM
3396+ fidir = au_fi(file)->fi_hdir;
3397+ AuDebugOn(!fidir);
3398+ bend = au_fbend_dir(file);
3399+ for (bindex = au_fbstart(file); bindex <= bend; bindex++) {
3400+ hfile = fidir->fd_hfile + bindex;
3401+ if (!hfile->hf_file)
3402+ continue;
3403+
c1595e42 3404+ if (hfile->hf_br->br_id == br_id) {
076b876e 3405+ matched = 1;
076b876e 3406+ break;
c1595e42 3407+ }
076b876e 3408+ }
c1595e42 3409+ if (matched)
076b876e
AM
3410+ err = -EBUSY;
3411+
3412+out:
3413+ return err;
3414+}
3415+
3416+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3417+ struct file **to_free, int opened)
3418+{
3419+ int err, idx;
3420+ unsigned long long ull, max;
3421+ aufs_bindex_t bstart;
3422+ struct file *file, **array;
076b876e
AM
3423+ struct dentry *root;
3424+ struct au_hfile *hfile;
3425+
3426+ array = au_farray_alloc(sb, &max);
3427+ err = PTR_ERR(array);
3428+ if (IS_ERR(array))
3429+ goto out;
3430+
3431+ err = 0;
3432+ idx = 0;
3433+ root = sb->s_root;
3434+ di_write_unlock(root);
3435+ for (ull = 0; ull < max; ull++) {
3436+ file = array[ull];
3437+ if (unlikely(!file))
3438+ break;
3439+
3440+ /* AuDbg("%pD\n", file); */
3441+ fi_read_lock(file);
3442+ bstart = au_fbstart(file);
2000de60 3443+ if (!d_is_dir(file->f_path.dentry)) {
076b876e
AM
3444+ hfile = &au_fi(file)->fi_htop;
3445+ if (hfile->hf_br->br_id == br_id)
3446+ err = -EBUSY;
3447+ } else
3448+ err = test_dir_busy(file, br_id, to_free, &idx);
3449+ fi_read_unlock(file);
3450+ if (unlikely(err))
3451+ break;
3452+ }
3453+ di_write_lock_child(root);
3454+ au_farray_free(array, max);
3455+ AuDebugOn(idx > opened);
3456+
3457+out:
3458+ return err;
3459+}
3460+
3461+static void br_del_file(struct file **to_free, unsigned long long opened,
3462+ aufs_bindex_t br_id)
3463+{
3464+ unsigned long long ull;
3465+ aufs_bindex_t bindex, bstart, bend, bfound;
3466+ struct file *file;
3467+ struct au_fidir *fidir;
3468+ struct au_hfile *hfile;
3469+
3470+ for (ull = 0; ull < opened; ull++) {
3471+ file = to_free[ull];
3472+ if (unlikely(!file))
3473+ break;
3474+
3475+ /* AuDbg("%pD\n", file); */
2000de60 3476+ AuDebugOn(!d_is_dir(file->f_path.dentry));
076b876e
AM
3477+ bfound = -1;
3478+ fidir = au_fi(file)->fi_hdir;
3479+ AuDebugOn(!fidir);
3480+ fi_write_lock(file);
3481+ bstart = au_fbstart(file);
3482+ bend = au_fbend_dir(file);
3483+ for (bindex = bstart; bindex <= bend; bindex++) {
3484+ hfile = fidir->fd_hfile + bindex;
3485+ if (!hfile->hf_file)
3486+ continue;
3487+
3488+ if (hfile->hf_br->br_id == br_id) {
3489+ bfound = bindex;
3490+ break;
3491+ }
3492+ }
3493+ AuDebugOn(bfound < 0);
3494+ au_set_h_fptr(file, bfound, NULL);
3495+ if (bfound == bstart) {
3496+ for (bstart++; bstart <= bend; bstart++)
3497+ if (au_hf_dir(file, bstart)) {
3498+ au_set_fbstart(file, bstart);
3499+ break;
3500+ }
3501+ }
3502+ fi_write_unlock(file);
3503+ }
3504+}
3505+
1facf9fc 3506+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
3507+ const aufs_bindex_t bindex,
3508+ const aufs_bindex_t bend)
3509+{
3510+ struct au_branch **brp, **p;
3511+
dece6358
AM
3512+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3513+
1facf9fc 3514+ brp = sbinfo->si_branch + bindex;
3515+ if (bindex < bend)
3516+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
3517+ sbinfo->si_branch[0 + bend] = NULL;
3518+ sbinfo->si_bend--;
3519+
53392da6 3520+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3521+ if (p)
3522+ sbinfo->si_branch = p;
4a4d8108 3523+ /* harmless error */
1facf9fc 3524+}
3525+
3526+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
3527+ const aufs_bindex_t bend)
3528+{
3529+ struct au_hdentry *hdp, *p;
3530+
1308ab2a 3531+ AuRwMustWriteLock(&dinfo->di_rwsem);
3532+
4a4d8108 3533+ hdp = dinfo->di_hdentry;
1facf9fc 3534+ if (bindex < bend)
4a4d8108
AM
3535+ memmove(hdp + bindex, hdp + bindex + 1,
3536+ sizeof(*hdp) * (bend - bindex));
3537+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 3538+ dinfo->di_bend--;
3539+
53392da6 3540+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3541+ if (p)
3542+ dinfo->di_hdentry = p;
4a4d8108 3543+ /* harmless error */
1facf9fc 3544+}
3545+
3546+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
3547+ const aufs_bindex_t bend)
3548+{
3549+ struct au_hinode *hip, *p;
3550+
1308ab2a 3551+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3552+
1facf9fc 3553+ hip = iinfo->ii_hinode + bindex;
3554+ if (bindex < bend)
3555+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
3556+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 3557+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 3558+ iinfo->ii_bend--;
3559+
53392da6 3560+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3561+ if (p)
3562+ iinfo->ii_hinode = p;
4a4d8108 3563+ /* harmless error */
1facf9fc 3564+}
3565+
3566+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
3567+ struct au_branch *br)
3568+{
3569+ aufs_bindex_t bend;
3570+ struct au_sbinfo *sbinfo;
53392da6
AM
3571+ struct dentry *root, *h_root;
3572+ struct inode *inode, *h_inode;
3573+ struct au_hinode *hinode;
1facf9fc 3574+
dece6358
AM
3575+ SiMustWriteLock(sb);
3576+
1facf9fc 3577+ root = sb->s_root;
3578+ inode = root->d_inode;
1facf9fc 3579+ sbinfo = au_sbi(sb);
3580+ bend = sbinfo->si_bend;
3581+
53392da6
AM
3582+ h_root = au_h_dptr(root, bindex);
3583+ hinode = au_hi(inode, bindex);
3584+ h_inode = au_igrab(hinode->hi_inode);
3585+ au_hiput(hinode);
1facf9fc 3586+
53392da6 3587+ au_sbilist_lock();
1facf9fc 3588+ au_br_do_del_brp(sbinfo, bindex, bend);
3589+ au_br_do_del_hdp(au_di(root), bindex, bend);
3590+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
3591+ au_sbilist_unlock();
3592+
3593+ dput(h_root);
3594+ iput(h_inode);
3595+ au_br_do_free(br);
1facf9fc 3596+}
3597+
076b876e
AM
3598+static unsigned long long empty_cb(void *array, unsigned long long max,
3599+ void *arg)
3600+{
3601+ return max;
3602+}
3603+
1facf9fc 3604+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
3605+{
3606+ int err, rerr, i;
076b876e 3607+ unsigned long long opened;
1facf9fc 3608+ unsigned int mnt_flags;
3609+ aufs_bindex_t bindex, bend, br_id;
3610+ unsigned char do_wh, verbose;
3611+ struct au_branch *br;
3612+ struct au_wbr *wbr;
076b876e
AM
3613+ struct dentry *root;
3614+ struct file **to_free;
1facf9fc 3615+
3616+ err = 0;
076b876e
AM
3617+ opened = 0;
3618+ to_free = NULL;
3619+ root = sb->s_root;
3620+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 3621+ if (bindex < 0) {
3622+ if (remount)
3623+ goto out; /* success */
3624+ err = -ENOENT;
4a4d8108 3625+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 3626+ goto out;
3627+ }
3628+ AuDbg("bindex b%d\n", bindex);
3629+
3630+ err = -EBUSY;
3631+ mnt_flags = au_mntflags(sb);
3632+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3633+ bend = au_sbend(sb);
3634+ if (unlikely(!bend)) {
3635+ AuVerbose(verbose, "no more branches left\n");
3636+ goto out;
3637+ }
3638+ br = au_sbr(sb, bindex);
86dc4139 3639+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
076b876e
AM
3640+
3641+ br_id = br->br_id;
3642+ opened = atomic_read(&br->br_count);
3643+ if (unlikely(opened)) {
3644+ to_free = au_array_alloc(&opened, empty_cb, NULL);
3645+ err = PTR_ERR(to_free);
3646+ if (IS_ERR(to_free))
3647+ goto out;
3648+
3649+ err = test_file_busy(sb, br_id, to_free, opened);
3650+ if (unlikely(err)) {
3651+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
3652+ goto out;
3653+ }
1facf9fc 3654+ }
3655+
3656+ wbr = br->br_wbr;
3657+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
3658+ if (do_wh) {
1308ab2a 3659+ /* instead of WbrWhMustWriteLock(wbr) */
3660+ SiMustWriteLock(sb);
1facf9fc 3661+ for (i = 0; i < AuBrWh_Last; i++) {
3662+ dput(wbr->wbr_wh[i]);
3663+ wbr->wbr_wh[i] = NULL;
3664+ }
3665+ }
3666+
076b876e 3667+ err = test_children_busy(root, bindex, verbose);
1facf9fc 3668+ if (unlikely(err)) {
3669+ if (do_wh)
3670+ goto out_wh;
3671+ goto out;
3672+ }
3673+
3674+ err = 0;
076b876e
AM
3675+ if (to_free) {
3676+ /*
3677+ * now we confirmed the branch is deletable.
3678+ * let's free the remaining opened dirs on the branch.
3679+ */
3680+ di_write_unlock(root);
3681+ br_del_file(to_free, opened, br_id);
3682+ di_write_lock_child(root);
3683+ }
3684+
1facf9fc 3685+ if (!remount)
3686+ au_br_do_del(sb, bindex, br);
3687+ else {
3688+ sysaufs_brs_del(sb, bindex);
3689+ au_br_do_del(sb, bindex, br);
3690+ sysaufs_brs_add(sb, bindex);
3691+ }
3692+
1308ab2a 3693+ if (!bindex) {
076b876e 3694+ au_cpup_attr_all(root->d_inode, /*force*/1);
1308ab2a 3695+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
3696+ } else
076b876e 3697+ au_sub_nlink(root->d_inode, del->h_path.dentry->d_inode);
1facf9fc 3698+ if (au_opt_test(mnt_flags, PLINK))
3699+ au_plink_half_refresh(sb, br_id);
3700+
b752ccd1 3701+ if (au_xino_brid(sb) == br_id)
1facf9fc 3702+ au_xino_brid_set(sb, -1);
3703+ goto out; /* success */
3704+
4f0767ce 3705+out_wh:
1facf9fc 3706+ /* revert */
86dc4139 3707+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 3708+ if (rerr)
0c3ec466
AM
3709+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
3710+ del->pathname, rerr);
4f0767ce 3711+out:
076b876e
AM
3712+ if (to_free)
3713+ au_farray_free(to_free, opened);
1facf9fc 3714+ return err;
3715+}
3716+
3717+/* ---------------------------------------------------------------------- */
3718+
027c5e7a
AM
3719+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
3720+{
3721+ int err;
3722+ aufs_bindex_t bstart, bend;
3723+ struct aufs_ibusy ibusy;
3724+ struct inode *inode, *h_inode;
3725+
3726+ err = -EPERM;
3727+ if (unlikely(!capable(CAP_SYS_ADMIN)))
3728+ goto out;
3729+
3730+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
3731+ if (!err)
3732+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
3733+ if (unlikely(err)) {
3734+ err = -EFAULT;
3735+ AuTraceErr(err);
3736+ goto out;
3737+ }
3738+
3739+ err = -EINVAL;
3740+ si_read_lock(sb, AuLock_FLUSH);
3741+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
3742+ goto out_unlock;
3743+
3744+ err = 0;
3745+ ibusy.h_ino = 0; /* invalid */
3746+ inode = ilookup(sb, ibusy.ino);
3747+ if (!inode
3748+ || inode->i_ino == AUFS_ROOT_INO
3749+ || is_bad_inode(inode))
3750+ goto out_unlock;
3751+
3752+ ii_read_lock_child(inode);
3753+ bstart = au_ibstart(inode);
3754+ bend = au_ibend(inode);
3755+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
3756+ h_inode = au_h_iptr(inode, ibusy.bindex);
3757+ if (h_inode && au_test_ibusy(inode, bstart, bend))
3758+ ibusy.h_ino = h_inode->i_ino;
3759+ }
3760+ ii_read_unlock(inode);
3761+ iput(inode);
3762+
3763+out_unlock:
3764+ si_read_unlock(sb);
3765+ if (!err) {
3766+ err = __put_user(ibusy.h_ino, &arg->h_ino);
3767+ if (unlikely(err)) {
3768+ err = -EFAULT;
3769+ AuTraceErr(err);
3770+ }
3771+ }
3772+out:
3773+ return err;
3774+}
3775+
3776+long au_ibusy_ioctl(struct file *file, unsigned long arg)
3777+{
2000de60 3778+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
027c5e7a
AM
3779+}
3780+
3781+#ifdef CONFIG_COMPAT
3782+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
3783+{
2000de60 3784+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
027c5e7a
AM
3785+}
3786+#endif
3787+
3788+/* ---------------------------------------------------------------------- */
3789+
1facf9fc 3790+/*
3791+ * change a branch permission
3792+ */
3793+
dece6358
AM
3794+static void au_warn_ima(void)
3795+{
3796+#ifdef CONFIG_IMA
1308ab2a 3797+ /* since it doesn't support mark_files_ro() */
027c5e7a 3798+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
3799+#endif
3800+}
3801+
1facf9fc 3802+static int do_need_sigen_inc(int a, int b)
3803+{
3804+ return au_br_whable(a) && !au_br_whable(b);
3805+}
3806+
3807+static int need_sigen_inc(int old, int new)
3808+{
3809+ return do_need_sigen_inc(old, new)
3810+ || do_need_sigen_inc(new, old);
3811+}
3812+
3813+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
3814+{
7f207e10 3815+ int err, do_warn;
027c5e7a 3816+ unsigned int mnt_flags;
7f207e10 3817+ unsigned long long ull, max;
e49829fe 3818+ aufs_bindex_t br_id;
38d290e6 3819+ unsigned char verbose, writer;
7f207e10 3820+ struct file *file, *hf, **array;
e49829fe 3821+ struct au_hfile *hfile;
1facf9fc 3822+
027c5e7a
AM
3823+ mnt_flags = au_mntflags(sb);
3824+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3825+
7f207e10
AM
3826+ array = au_farray_alloc(sb, &max);
3827+ err = PTR_ERR(array);
3828+ if (IS_ERR(array))
1facf9fc 3829+ goto out;
3830+
7f207e10 3831+ do_warn = 0;
e49829fe 3832+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
3833+ for (ull = 0; ull < max; ull++) {
3834+ file = array[ull];
076b876e
AM
3835+ if (unlikely(!file))
3836+ break;
1facf9fc 3837+
523b37e3 3838+ /* AuDbg("%pD\n", file); */
1facf9fc 3839+ fi_read_lock(file);
3840+ if (unlikely(au_test_mmapped(file))) {
3841+ err = -EBUSY;
523b37e3 3842+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 3843+ AuDbgFile(file);
1facf9fc 3844+ FiMustNoWaiters(file);
3845+ fi_read_unlock(file);
7f207e10 3846+ goto out_array;
1facf9fc 3847+ }
3848+
e49829fe
JR
3849+ hfile = &au_fi(file)->fi_htop;
3850+ hf = hfile->hf_file;
7e9cd9fe 3851+ if (!d_is_reg(file->f_path.dentry)
1facf9fc 3852+ || !(file->f_mode & FMODE_WRITE)
e49829fe 3853+ || hfile->hf_br->br_id != br_id
7f207e10
AM
3854+ || !(hf->f_mode & FMODE_WRITE))
3855+ array[ull] = NULL;
3856+ else {
3857+ do_warn = 1;
3858+ get_file(file);
1facf9fc 3859+ }
3860+
1facf9fc 3861+ FiMustNoWaiters(file);
3862+ fi_read_unlock(file);
7f207e10
AM
3863+ fput(file);
3864+ }
1facf9fc 3865+
3866+ err = 0;
7f207e10 3867+ if (do_warn)
dece6358 3868+ au_warn_ima();
7f207e10
AM
3869+
3870+ for (ull = 0; ull < max; ull++) {
3871+ file = array[ull];
3872+ if (!file)
3873+ continue;
3874+
1facf9fc 3875+ /* todo: already flushed? */
523b37e3
AM
3876+ /*
3877+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
3878+ * approach which resets f_mode and calls mnt_drop_write() and
3879+ * file_release_write() for each file, because the branch
3880+ * attribute in aufs world is totally different from the native
3881+ * fs rw/ro mode.
3882+ */
7f207e10
AM
3883+ /* fi_read_lock(file); */
3884+ hfile = &au_fi(file)->fi_htop;
3885+ hf = hfile->hf_file;
3886+ /* fi_read_unlock(file); */
027c5e7a 3887+ spin_lock(&hf->f_lock);
38d290e6
JR
3888+ writer = !!(hf->f_mode & FMODE_WRITER);
3889+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 3890+ spin_unlock(&hf->f_lock);
38d290e6
JR
3891+ if (writer) {
3892+ put_write_access(file_inode(hf));
c06a8ce3 3893+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 3894+ }
3895+ }
3896+
7f207e10
AM
3897+out_array:
3898+ au_farray_free(array, max);
4f0767ce 3899+out:
7f207e10 3900+ AuTraceErr(err);
1facf9fc 3901+ return err;
3902+}
3903+
3904+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3905+ int *do_refresh)
1facf9fc 3906+{
3907+ int err, rerr;
3908+ aufs_bindex_t bindex;
3909+ struct dentry *root;
3910+ struct au_branch *br;
076b876e 3911+ struct au_br_fhsm *bf;
1facf9fc 3912+
3913+ root = sb->s_root;
1facf9fc 3914+ bindex = au_find_dbindex(root, mod->h_root);
3915+ if (bindex < 0) {
3916+ if (remount)
3917+ return 0; /* success */
3918+ err = -ENOENT;
4a4d8108 3919+ pr_err("%s no such branch\n", mod->path);
1facf9fc 3920+ goto out;
3921+ }
3922+ AuDbg("bindex b%d\n", bindex);
3923+
3924+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3925+ if (unlikely(err))
3926+ goto out;
3927+
3928+ br = au_sbr(sb, bindex);
86dc4139 3929+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 3930+ if (br->br_perm == mod->perm)
3931+ return 0; /* success */
3932+
076b876e
AM
3933+ /* pre-allocate for non-fhsm --> fhsm */
3934+ bf = NULL;
3935+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
3936+ err = au_fhsm_br_alloc(br);
3937+ if (unlikely(err))
3938+ goto out;
3939+ bf = br->br_fhsm;
3940+ br->br_fhsm = NULL;
3941+ }
3942+
1facf9fc 3943+ if (au_br_writable(br->br_perm)) {
3944+ /* remove whiteout base */
86dc4139 3945+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 3946+ if (unlikely(err))
076b876e 3947+ goto out_bf;
1facf9fc 3948+
3949+ if (!au_br_writable(mod->perm)) {
3950+ /* rw --> ro, file might be mmapped */
3951+ DiMustNoWaiters(root);
3952+ IiMustNoWaiters(root->d_inode);
3953+ di_write_unlock(root);
3954+ err = au_br_mod_files_ro(sb, bindex);
3955+ /* aufs_write_lock() calls ..._child() */
3956+ di_write_lock_child(root);
3957+
3958+ if (unlikely(err)) {
3959+ rerr = -ENOMEM;
3960+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
3961+ GFP_NOFS);
86dc4139
AM
3962+ if (br->br_wbr)
3963+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 3964+ if (unlikely(rerr)) {
3965+ AuIOErr("nested error %d (%d)\n",
3966+ rerr, err);
3967+ br->br_perm = mod->perm;
3968+ }
3969+ }
3970+ }
3971+ } else if (au_br_writable(mod->perm)) {
3972+ /* ro --> rw */
3973+ err = -ENOMEM;
3974+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
3975+ if (br->br_wbr) {
86dc4139 3976+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 3977+ if (unlikely(err)) {
3978+ kfree(br->br_wbr);
3979+ br->br_wbr = NULL;
3980+ }
3981+ }
3982+ }
076b876e
AM
3983+ if (unlikely(err))
3984+ goto out_bf;
3985+
3986+ if (au_br_fhsm(br->br_perm)) {
3987+ if (!au_br_fhsm(mod->perm)) {
3988+ /* fhsm --> non-fhsm */
3989+ au_br_fhsm_fin(br->br_fhsm);
3990+ kfree(br->br_fhsm);
3991+ br->br_fhsm = NULL;
3992+ }
3993+ } else if (au_br_fhsm(mod->perm))
3994+ /* non-fhsm --> fhsm */
3995+ br->br_fhsm = bf;
3996+
076b876e
AM
3997+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
3998+ br->br_perm = mod->perm;
3999+ goto out; /* success */
1facf9fc 4000+
076b876e
AM
4001+out_bf:
4002+ kfree(bf);
4003+out:
4004+ AuTraceErr(err);
4005+ return err;
4006+}
4007+
4008+/* ---------------------------------------------------------------------- */
4009+
4010+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4011+{
4012+ int err;
4013+ struct kstatfs kstfs;
4014+
4015+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 4016+ if (!err) {
076b876e
AM
4017+ stfs->f_blocks = kstfs.f_blocks;
4018+ stfs->f_bavail = kstfs.f_bavail;
4019+ stfs->f_files = kstfs.f_files;
4020+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 4021+ }
4022+
1facf9fc 4023+ return err;
4024+}
7f207e10
AM
4025diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4026--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 4027+++ linux/fs/aufs/branch.h 2015-04-13 15:10:20.780156788 +0200
c1595e42 4028@@ -0,0 +1,267 @@
1facf9fc 4029+/*
2000de60 4030+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 4031+ *
4032+ * This program, aufs is free software; you can redistribute it and/or modify
4033+ * it under the terms of the GNU General Public License as published by
4034+ * the Free Software Foundation; either version 2 of the License, or
4035+ * (at your option) any later version.
dece6358
AM
4036+ *
4037+ * This program is distributed in the hope that it will be useful,
4038+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4039+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4040+ * GNU General Public License for more details.
4041+ *
4042+ * You should have received a copy of the GNU General Public License
523b37e3 4043+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4044+ */
4045+
4046+/*
4047+ * branch filesystems and xino for them
4048+ */
4049+
4050+#ifndef __AUFS_BRANCH_H__
4051+#define __AUFS_BRANCH_H__
4052+
4053+#ifdef __KERNEL__
4054+
1facf9fc 4055+#include <linux/mount.h>
4a4d8108 4056+#include "dynop.h"
1facf9fc 4057+#include "rwsem.h"
4058+#include "super.h"
4059+
4060+/* ---------------------------------------------------------------------- */
4061+
4062+/* a xino file */
4063+struct au_xino_file {
4064+ struct file *xi_file;
4065+ struct mutex xi_nondir_mtx;
4066+
4067+ /* todo: make xino files an array to support huge inode number */
4068+
4069+#ifdef CONFIG_DEBUG_FS
4070+ struct dentry *xi_dbgaufs;
4071+#endif
4072+};
4073+
076b876e
AM
4074+/* File-based Hierarchical Storage Management */
4075+struct au_br_fhsm {
4076+#ifdef CONFIG_AUFS_FHSM
4077+ struct mutex bf_lock;
4078+ unsigned long bf_jiffy;
4079+ struct aufs_stfs bf_stfs;
4080+ int bf_readable;
4081+#endif
4082+};
4083+
1facf9fc 4084+/* members for writable branch only */
4085+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4086+struct au_wbr {
dece6358 4087+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4088+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4089+ atomic_t wbr_wh_running;
1facf9fc 4090+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4091+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4092+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4093+
4094+ /* mfs mode */
4095+ unsigned long long wbr_bytes;
4096+};
4097+
4a4d8108
AM
4098+/* ext2 has 3 types of operations at least, ext3 has 4 */
4099+#define AuBrDynOp (AuDyLast * 4)
4100+
1716fcea
AM
4101+#ifdef CONFIG_AUFS_HFSNOTIFY
4102+/* support for asynchronous destruction */
4103+struct au_br_hfsnotify {
4104+ struct fsnotify_group *hfsn_group;
4105+};
4106+#endif
4107+
392086de
AM
4108+/* sysfs entries */
4109+struct au_brsysfs {
4110+ char name[16];
4111+ struct attribute attr;
4112+};
4113+
4114+enum {
4115+ AuBrSysfs_BR,
4116+ AuBrSysfs_BRID,
4117+ AuBrSysfs_Last
4118+};
4119+
1facf9fc 4120+/* protected by superblock rwsem */
4121+struct au_branch {
4122+ struct au_xino_file br_xino;
4123+
4124+ aufs_bindex_t br_id;
4125+
4126+ int br_perm;
86dc4139 4127+ struct path br_path;
4a4d8108
AM
4128+ spinlock_t br_dykey_lock;
4129+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 4130+ atomic_t br_count;
4131+
4132+ struct au_wbr *br_wbr;
076b876e 4133+ struct au_br_fhsm *br_fhsm;
1facf9fc 4134+
4135+ /* xino truncation */
1facf9fc 4136+ atomic_t br_xino_running;
4137+
027c5e7a 4138+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4139+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4140+#endif
4141+
1facf9fc 4142+#ifdef CONFIG_SYSFS
392086de
AM
4143+ /* entries under sysfs per mount-point */
4144+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4145+#endif
4146+};
4147+
4148+/* ---------------------------------------------------------------------- */
4149+
86dc4139
AM
4150+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4151+{
4152+ return br->br_path.mnt;
4153+}
4154+
4155+static inline struct dentry *au_br_dentry(struct au_branch *br)
4156+{
4157+ return br->br_path.dentry;
4158+}
4159+
4160+static inline struct super_block *au_br_sb(struct au_branch *br)
4161+{
4162+ return au_br_mnt(br)->mnt_sb;
4163+}
4164+
1facf9fc 4165+static inline int au_br_rdonly(struct au_branch *br)
4166+{
86dc4139 4167+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 4168+ || !au_br_writable(br->br_perm))
4169+ ? -EROFS : 0;
4170+}
4171+
4a4d8108 4172+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4173+{
4a4d8108 4174+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4175+ return !(brperm & AuBrPerm_RR);
1facf9fc 4176+#else
4177+ return 0;
4178+#endif
4179+}
4180+
4181+/* ---------------------------------------------------------------------- */
4182+
4183+/* branch.c */
4184+struct au_sbinfo;
4185+void au_br_free(struct au_sbinfo *sinfo);
4186+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4187+struct au_opt_add;
4188+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4189+struct au_opt_del;
4190+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4191+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4192+#ifdef CONFIG_COMPAT
4193+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4194+#endif
1facf9fc 4195+struct au_opt_mod;
4196+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4197+ int *do_refresh);
076b876e
AM
4198+struct aufs_stfs;
4199+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4200+
4201+/* xino.c */
4202+static const loff_t au_loff_max = LLONG_MAX;
4203+
4204+int au_xib_trunc(struct super_block *sb);
4205+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
4206+ loff_t *pos);
4207+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
4208+ loff_t *pos);
4209+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
4210+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
4211+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 4212+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4213+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4214+ ino_t ino);
4215+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4216+ ino_t *ino);
4217+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4218+ struct file *base_file, int do_test);
4219+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
4220+
4221+struct au_opt_xino;
4222+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
4223+void au_xino_clr(struct super_block *sb);
4224+struct file *au_xino_def(struct super_block *sb);
4225+int au_xino_path(struct seq_file *seq, struct file *file);
4226+
4227+/* ---------------------------------------------------------------------- */
4228+
4229+/* Superblock to branch */
4230+static inline
4231+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4232+{
4233+ return au_sbr(sb, bindex)->br_id;
4234+}
4235+
4236+static inline
4237+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4238+{
86dc4139 4239+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4240+}
4241+
4242+static inline
4243+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4244+{
86dc4139 4245+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4246+}
4247+
4248+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
4249+{
e49829fe 4250+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 4251+}
4252+
4253+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4254+{
4255+ return au_sbr(sb, bindex)->br_perm;
4256+}
4257+
4258+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4259+{
4260+ return au_br_whable(au_sbr_perm(sb, bindex));
4261+}
4262+
4263+/* ---------------------------------------------------------------------- */
4264+
4265+/*
4266+ * wbr_wh_read_lock, wbr_wh_write_lock
4267+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
4268+ */
4269+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
4270+
dece6358
AM
4271+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
4272+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
4273+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
4274+
076b876e
AM
4275+/* ---------------------------------------------------------------------- */
4276+
4277+#ifdef CONFIG_AUFS_FHSM
4278+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4279+{
4280+ mutex_init(&brfhsm->bf_lock);
4281+ brfhsm->bf_jiffy = 0;
4282+ brfhsm->bf_readable = 0;
4283+}
4284+
4285+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4286+{
4287+ mutex_destroy(&brfhsm->bf_lock);
4288+}
4289+#else
4290+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4291+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4292+#endif
4293+
1facf9fc 4294+#endif /* __KERNEL__ */
4295+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4296diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4297--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 4298+++ linux/fs/aufs/conf.mk 2015-04-13 15:10:20.780156788 +0200
c1595e42 4299@@ -0,0 +1,38 @@
4a4d8108
AM
4300+
4301+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4302+
4303+define AuConf
4304+ifdef ${1}
4305+AuConfStr += ${1}=${${1}}
4306+endif
4307+endef
4308+
b752ccd1 4309+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4310+ SBILIST \
7f207e10 4311+ HNOTIFY HFSNOTIFY \
4a4d8108 4312+ EXPORT INO_T_64 \
c1595e42 4313+ XATTR \
076b876e 4314+ FHSM \
4a4d8108 4315+ RDU \
4a4d8108
AM
4316+ SHWH \
4317+ BR_RAMFS \
4318+ BR_FUSE POLL \
4319+ BR_HFSPLUS \
4320+ BDEV_LOOP \
b752ccd1
AM
4321+ DEBUG MAGIC_SYSRQ
4322+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4323+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4324+
4325+AuConfName = ${obj}/conf.str
4326+${AuConfName}.tmp: FORCE
4327+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4328+${AuConfName}: ${AuConfName}.tmp
4329+ @diff -q $< $@ > /dev/null 2>&1 || { \
4330+ echo ' GEN ' $@; \
4331+ cp -p $< $@; \
4332+ }
4333+FORCE:
4334+clean-files += ${AuConfName} ${AuConfName}.tmp
4335+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4336+
4337+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4338diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4339--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
4340+++ linux/fs/aufs/cpup.c 2015-04-13 15:10:20.780156788 +0200
4341@@ -0,0 +1,1308 @@
1facf9fc 4342+/*
2000de60 4343+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 4344+ *
4345+ * This program, aufs is free software; you can redistribute it and/or modify
4346+ * it under the terms of the GNU General Public License as published by
4347+ * the Free Software Foundation; either version 2 of the License, or
4348+ * (at your option) any later version.
dece6358
AM
4349+ *
4350+ * This program is distributed in the hope that it will be useful,
4351+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4352+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4353+ * GNU General Public License for more details.
4354+ *
4355+ * You should have received a copy of the GNU General Public License
523b37e3 4356+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4357+ */
4358+
4359+/*
4360+ * copy-up functions, see wbr_policy.c for copy-down
4361+ */
4362+
4363+#include <linux/fs_stack.h>
dece6358 4364+#include <linux/mm.h>
1facf9fc 4365+#include "aufs.h"
4366+
86dc4139 4367+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4368+{
4369+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4370+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4371+
86dc4139
AM
4372+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4373+
4374+ dst->i_flags |= iflags & ~mask;
1facf9fc 4375+ if (au_test_fs_notime(dst->i_sb))
4376+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4377+}
4378+
4379+void au_cpup_attr_timesizes(struct inode *inode)
4380+{
4381+ struct inode *h_inode;
4382+
4383+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4384+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 4385+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 4386+}
4387+
4388+void au_cpup_attr_nlink(struct inode *inode, int force)
4389+{
4390+ struct inode *h_inode;
4391+ struct super_block *sb;
4392+ aufs_bindex_t bindex, bend;
4393+
4394+ sb = inode->i_sb;
4395+ bindex = au_ibstart(inode);
4396+ h_inode = au_h_iptr(inode, bindex);
4397+ if (!force
4398+ && !S_ISDIR(h_inode->i_mode)
4399+ && au_opt_test(au_mntflags(sb), PLINK)
4400+ && au_plink_test(inode))
4401+ return;
4402+
7eafdf33
AM
4403+ /*
4404+ * 0 can happen in revalidating.
38d290e6
JR
4405+ * h_inode->i_mutex may not be held here, but it is harmless since once
4406+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
4407+ * case.
4408+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
4409+ * the incorrect link count.
7eafdf33 4410+ */
92d182d2 4411+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 4412+
4413+ /*
4414+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
4415+ * it may includes whplink directory.
4416+ */
4417+ if (S_ISDIR(h_inode->i_mode)) {
4418+ bend = au_ibend(inode);
4419+ for (bindex++; bindex <= bend; bindex++) {
4420+ h_inode = au_h_iptr(inode, bindex);
4421+ if (h_inode)
4422+ au_add_nlink(inode, h_inode);
4423+ }
4424+ }
4425+}
4426+
4427+void au_cpup_attr_changeable(struct inode *inode)
4428+{
4429+ struct inode *h_inode;
4430+
4431+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4432+ inode->i_mode = h_inode->i_mode;
4433+ inode->i_uid = h_inode->i_uid;
4434+ inode->i_gid = h_inode->i_gid;
4435+ au_cpup_attr_timesizes(inode);
86dc4139 4436+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 4437+}
4438+
4439+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
4440+{
4441+ struct au_iinfo *iinfo = au_ii(inode);
4442+
1308ab2a 4443+ IiMustWriteLock(inode);
4444+
1facf9fc 4445+ iinfo->ii_higen = h_inode->i_generation;
4446+ iinfo->ii_hsb1 = h_inode->i_sb;
4447+}
4448+
4449+void au_cpup_attr_all(struct inode *inode, int force)
4450+{
4451+ struct inode *h_inode;
4452+
4453+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4454+ au_cpup_attr_changeable(inode);
4455+ if (inode->i_nlink > 0)
4456+ au_cpup_attr_nlink(inode, force);
4457+ inode->i_rdev = h_inode->i_rdev;
4458+ inode->i_blkbits = h_inode->i_blkbits;
4459+ au_cpup_igen(inode, h_inode);
4460+}
4461+
4462+/* ---------------------------------------------------------------------- */
4463+
4464+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
4465+
4466+/* keep the timestamps of the parent dir when cpup */
4467+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4468+ struct path *h_path)
4469+{
4470+ struct inode *h_inode;
4471+
4472+ dt->dt_dentry = dentry;
4473+ dt->dt_h_path = *h_path;
4474+ h_inode = h_path->dentry->d_inode;
4475+ dt->dt_atime = h_inode->i_atime;
4476+ dt->dt_mtime = h_inode->i_mtime;
4477+ /* smp_mb(); */
4478+}
4479+
4480+void au_dtime_revert(struct au_dtime *dt)
4481+{
4482+ struct iattr attr;
4483+ int err;
4484+
4485+ attr.ia_atime = dt->dt_atime;
4486+ attr.ia_mtime = dt->dt_mtime;
4487+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
4488+ | ATTR_ATIME | ATTR_ATIME_SET;
4489+
523b37e3
AM
4490+ /* no delegation since this is a directory */
4491+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 4492+ if (unlikely(err))
0c3ec466 4493+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 4494+}
4495+
4496+/* ---------------------------------------------------------------------- */
4497+
86dc4139
AM
4498+/* internal use only */
4499+struct au_cpup_reg_attr {
4500+ int valid;
4501+ struct kstat st;
4502+ unsigned int iflags; /* inode->i_flags */
4503+};
4504+
1facf9fc 4505+static noinline_for_stack
86dc4139
AM
4506+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
4507+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4508+{
c1595e42 4509+ int err, sbits, icex;
7e9cd9fe
AM
4510+ unsigned int mnt_flags;
4511+ unsigned char verbose;
1facf9fc 4512+ struct iattr ia;
4513+ struct path h_path;
1308ab2a 4514+ struct inode *h_isrc, *h_idst;
86dc4139 4515+ struct kstat *h_st;
c1595e42 4516+ struct au_branch *br;
1facf9fc 4517+
4518+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 4519+ h_idst = h_path.dentry->d_inode;
c1595e42
JR
4520+ br = au_sbr(dst->d_sb, bindex);
4521+ h_path.mnt = au_br_mnt(br);
1facf9fc 4522+ h_isrc = h_src->d_inode;
1308ab2a 4523+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 4524+ | ATTR_ATIME | ATTR_MTIME
4525+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
4526+ if (h_src_attr && h_src_attr->valid) {
4527+ h_st = &h_src_attr->st;
4528+ ia.ia_uid = h_st->uid;
4529+ ia.ia_gid = h_st->gid;
4530+ ia.ia_atime = h_st->atime;
4531+ ia.ia_mtime = h_st->mtime;
4532+ if (h_idst->i_mode != h_st->mode
4533+ && !S_ISLNK(h_idst->i_mode)) {
4534+ ia.ia_valid |= ATTR_MODE;
4535+ ia.ia_mode = h_st->mode;
4536+ }
4537+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
4538+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
4539+ } else {
4540+ ia.ia_uid = h_isrc->i_uid;
4541+ ia.ia_gid = h_isrc->i_gid;
4542+ ia.ia_atime = h_isrc->i_atime;
4543+ ia.ia_mtime = h_isrc->i_mtime;
4544+ if (h_idst->i_mode != h_isrc->i_mode
4545+ && !S_ISLNK(h_idst->i_mode)) {
4546+ ia.ia_valid |= ATTR_MODE;
4547+ ia.ia_mode = h_isrc->i_mode;
4548+ }
4549+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
4550+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 4551+ }
523b37e3
AM
4552+ /* no delegation since it is just created */
4553+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4554+
4555+ /* is this nfs only? */
4556+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
4557+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
4558+ ia.ia_mode = h_isrc->i_mode;
523b37e3 4559+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4560+ }
4561+
c1595e42 4562+ icex = br->br_perm & AuBrAttr_ICEX;
7e9cd9fe
AM
4563+ if (!err) {
4564+ mnt_flags = au_mntflags(dst->d_sb);
4565+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
4566+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose);
4567+ }
c1595e42 4568+
1facf9fc 4569+ return err;
4570+}
4571+
4572+/* ---------------------------------------------------------------------- */
4573+
4574+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
4575+ char *buf, unsigned long blksize)
4576+{
4577+ int err;
4578+ size_t sz, rbytes, wbytes;
4579+ unsigned char all_zero;
4580+ char *p, *zp;
4581+ struct mutex *h_mtx;
4582+ /* reduce stack usage */
4583+ struct iattr *ia;
4584+
4585+ zp = page_address(ZERO_PAGE(0));
4586+ if (unlikely(!zp))
4587+ return -ENOMEM; /* possible? */
4588+
4589+ err = 0;
4590+ all_zero = 0;
4591+ while (len) {
4592+ AuDbg("len %lld\n", len);
4593+ sz = blksize;
4594+ if (len < blksize)
4595+ sz = len;
4596+
4597+ rbytes = 0;
4598+ /* todo: signal_pending? */
4599+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
4600+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
4601+ err = rbytes;
4602+ }
4603+ if (unlikely(err < 0))
4604+ break;
4605+
4606+ all_zero = 0;
4607+ if (len >= rbytes && rbytes == blksize)
4608+ all_zero = !memcmp(buf, zp, rbytes);
4609+ if (!all_zero) {
4610+ wbytes = rbytes;
4611+ p = buf;
4612+ while (wbytes) {
4613+ size_t b;
4614+
4615+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
4616+ err = b;
4617+ /* todo: signal_pending? */
4618+ if (unlikely(err == -EAGAIN || err == -EINTR))
4619+ continue;
4620+ if (unlikely(err < 0))
4621+ break;
4622+ wbytes -= b;
4623+ p += b;
4624+ }
392086de
AM
4625+ if (unlikely(err < 0))
4626+ break;
1facf9fc 4627+ } else {
4628+ loff_t res;
4629+
4630+ AuLabel(hole);
4631+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
4632+ err = res;
4633+ if (unlikely(res < 0))
4634+ break;
4635+ }
4636+ len -= rbytes;
4637+ err = 0;
4638+ }
4639+
4640+ /* the last block may be a hole */
4641+ if (!err && all_zero) {
4642+ AuLabel(last hole);
4643+
4644+ err = 1;
2000de60 4645+ if (au_test_nfs(dst->f_path.dentry->d_sb)) {
1facf9fc 4646+ /* nfs requires this step to make last hole */
4647+ /* is this only nfs? */
4648+ do {
4649+ /* todo: signal_pending? */
4650+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
4651+ } while (err == -EAGAIN || err == -EINTR);
4652+ if (err == 1)
4653+ dst->f_pos--;
4654+ }
4655+
4656+ if (err == 1) {
4657+ ia = (void *)buf;
4658+ ia->ia_size = dst->f_pos;
4659+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
4660+ ia->ia_file = dst;
c06a8ce3 4661+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 4662+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
523b37e3
AM
4663+ /* no delegation since it is just created */
4664+ err = vfsub_notify_change(&dst->f_path, ia,
4665+ /*delegated*/NULL);
1facf9fc 4666+ mutex_unlock(h_mtx);
4667+ }
4668+ }
4669+
4670+ return err;
4671+}
4672+
4673+int au_copy_file(struct file *dst, struct file *src, loff_t len)
4674+{
4675+ int err;
4676+ unsigned long blksize;
4677+ unsigned char do_kfree;
4678+ char *buf;
4679+
4680+ err = -ENOMEM;
2000de60 4681+ blksize = dst->f_path.dentry->d_sb->s_blocksize;
1facf9fc 4682+ if (!blksize || PAGE_SIZE < blksize)
4683+ blksize = PAGE_SIZE;
4684+ AuDbg("blksize %lu\n", blksize);
4685+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
4686+ if (do_kfree)
4687+ buf = kmalloc(blksize, GFP_NOFS);
4688+ else
4689+ buf = (void *)__get_free_page(GFP_NOFS);
4690+ if (unlikely(!buf))
4691+ goto out;
4692+
4693+ if (len > (1 << 22))
4694+ AuDbg("copying a large file %lld\n", (long long)len);
4695+
4696+ src->f_pos = 0;
4697+ dst->f_pos = 0;
4698+ err = au_do_copy_file(dst, src, len, buf, blksize);
4699+ if (do_kfree)
4700+ kfree(buf);
4701+ else
4702+ free_page((unsigned long)buf);
4703+
4f0767ce 4704+out:
1facf9fc 4705+ return err;
4706+}
4707+
4708+/*
4709+ * to support a sparse file which is opened with O_APPEND,
4710+ * we need to close the file.
4711+ */
c2b27bf2 4712+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 4713+{
4714+ int err, i;
4715+ enum { SRC, DST };
4716+ struct {
4717+ aufs_bindex_t bindex;
4718+ unsigned int flags;
4719+ struct dentry *dentry;
392086de 4720+ int force_wr;
1facf9fc 4721+ struct file *file;
523b37e3 4722+ void *label;
1facf9fc 4723+ } *f, file[] = {
4724+ {
c2b27bf2 4725+ .bindex = cpg->bsrc,
1facf9fc 4726+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 4727+ .label = &&out
1facf9fc 4728+ },
4729+ {
c2b27bf2 4730+ .bindex = cpg->bdst,
1facf9fc 4731+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 4732+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 4733+ .label = &&out_src
1facf9fc 4734+ }
4735+ };
4736+ struct super_block *sb;
4737+
4738+ /* bsrc branch can be ro/rw. */
c2b27bf2 4739+ sb = cpg->dentry->d_sb;
1facf9fc 4740+ f = file;
4741+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
4742+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
4743+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 4744+ /*file*/NULL, f->force_wr);
1facf9fc 4745+ err = PTR_ERR(f->file);
4746+ if (IS_ERR(f->file))
4747+ goto *f->label;
1facf9fc 4748+ }
4749+
4750+ /* try stopping to update while we copyup */
4751+ IMustLock(file[SRC].dentry->d_inode);
c2b27bf2 4752+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 4753+
1facf9fc 4754+ fput(file[DST].file);
4755+ au_sbr_put(sb, file[DST].bindex);
523b37e3 4756+
4f0767ce 4757+out_src:
1facf9fc 4758+ fput(file[SRC].file);
4759+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 4760+out:
1facf9fc 4761+ return err;
4762+}
4763+
c2b27bf2 4764+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 4765+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4766+{
4767+ int err, rerr;
4768+ loff_t l;
86dc4139 4769+ struct path h_path;
38d290e6 4770+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 4771+
4772+ err = 0;
c2b27bf2 4773+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
86dc4139 4774+ l = i_size_read(h_src_inode);
c2b27bf2
AM
4775+ if (cpg->len == -1 || l < cpg->len)
4776+ cpg->len = l;
4777+ if (cpg->len) {
86dc4139
AM
4778+ /* try stopping to update while we are referencing */
4779+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2 4780+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 4781+
c2b27bf2
AM
4782+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
4783+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139
AM
4784+ h_src_attr->iflags = h_src_inode->i_flags;
4785+ err = vfs_getattr(&h_path, &h_src_attr->st);
4786+ if (unlikely(err)) {
4787+ mutex_unlock(&h_src_inode->i_mutex);
4788+ goto out;
4789+ }
4790+ h_src_attr->valid = 1;
c2b27bf2 4791+ err = au_cp_regular(cpg);
86dc4139 4792+ mutex_unlock(&h_src_inode->i_mutex);
c2b27bf2 4793+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
4794+ if (!err && rerr)
4795+ err = rerr;
1facf9fc 4796+ }
38d290e6
JR
4797+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
4798+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
4799+ h_dst_inode = h_path.dentry->d_inode;
4800+ spin_lock(&h_dst_inode->i_lock);
4801+ h_dst_inode->i_state |= I_LINKABLE;
4802+ spin_unlock(&h_dst_inode->i_lock);
4803+ }
1facf9fc 4804+
4f0767ce 4805+out:
1facf9fc 4806+ return err;
4807+}
4808+
4809+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
4810+ struct inode *h_dir)
4811+{
4812+ int err, symlen;
4813+ mm_segment_t old_fs;
b752ccd1
AM
4814+ union {
4815+ char *k;
4816+ char __user *u;
4817+ } sym;
1facf9fc 4818+
4819+ err = -ENOSYS;
4820+ if (unlikely(!h_src->d_inode->i_op->readlink))
4821+ goto out;
4822+
4823+ err = -ENOMEM;
537831f9 4824+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 4825+ if (unlikely(!sym.k))
1facf9fc 4826+ goto out;
4827+
9dbd164d 4828+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 4829+ old_fs = get_fs();
4830+ set_fs(KERNEL_DS);
b752ccd1 4831+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 4832+ err = symlen;
4833+ set_fs(old_fs);
4834+
4835+ if (symlen > 0) {
b752ccd1
AM
4836+ sym.k[symlen] = 0;
4837+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 4838+ }
537831f9 4839+ free_page((unsigned long)sym.k);
1facf9fc 4840+
4f0767ce 4841+out:
1facf9fc 4842+ return err;
4843+}
4844+
1facf9fc 4845+static noinline_for_stack
c2b27bf2 4846+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 4847+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4848+{
4849+ int err;
4850+ umode_t mode;
4851+ unsigned int mnt_flags;
076b876e 4852+ unsigned char isdir, isreg, force;
c2b27bf2 4853+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4854+ struct au_dtime dt;
4855+ struct path h_path;
4856+ struct dentry *h_src, *h_dst, *h_parent;
4857+ struct inode *h_inode, *h_dir;
4858+ struct super_block *sb;
4859+
4860+ /* bsrc branch can be ro/rw. */
c2b27bf2 4861+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
1facf9fc 4862+ h_inode = h_src->d_inode;
c2b27bf2 4863+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
1facf9fc 4864+
4865+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
4866+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
4867+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
4868+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
4869+ AUFS_WH_PFX_LEN));
1facf9fc 4870+ h_parent = h_dst->d_parent; /* dir inode is locked */
4871+ h_dir = h_parent->d_inode;
4872+ IMustLock(h_dir);
4873+ AuDebugOn(h_parent != h_dst->d_parent);
4874+
c2b27bf2
AM
4875+ sb = cpg->dentry->d_sb;
4876+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 4877+ if (do_dt) {
4878+ h_path.dentry = h_parent;
4879+ au_dtime_store(&dt, dst_parent, &h_path);
4880+ }
4881+ h_path.dentry = h_dst;
4882+
076b876e 4883+ isreg = 0;
1facf9fc 4884+ isdir = 0;
4885+ mode = h_inode->i_mode;
4886+ switch (mode & S_IFMT) {
4887+ case S_IFREG:
076b876e 4888+ isreg = 1;
b4510431
AM
4889+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
4890+ /*want_excl*/true);
1facf9fc 4891+ if (!err)
c2b27bf2 4892+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 4893+ break;
4894+ case S_IFDIR:
4895+ isdir = 1;
4896+ err = vfsub_mkdir(h_dir, &h_path, mode);
4897+ if (!err) {
4898+ /*
4899+ * strange behaviour from the users view,
4900+ * particularry setattr case
4901+ */
c2b27bf2 4902+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
1facf9fc 4903+ au_cpup_attr_nlink(dst_parent->d_inode,
4904+ /*force*/1);
c2b27bf2 4905+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
1facf9fc 4906+ }
4907+ break;
4908+ case S_IFLNK:
4909+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
4910+ break;
4911+ case S_IFCHR:
4912+ case S_IFBLK:
4913+ AuDebugOn(!capable(CAP_MKNOD));
4914+ /*FALLTHROUGH*/
4915+ case S_IFIFO:
4916+ case S_IFSOCK:
4917+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
4918+ break;
4919+ default:
4920+ AuIOErr("Unknown inode type 0%o\n", mode);
4921+ err = -EIO;
4922+ }
4923+
4924+ mnt_flags = au_mntflags(sb);
4925+ if (!au_opt_test(mnt_flags, UDBA_NONE)
4926+ && !isdir
4927+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
4928+ && (h_inode->i_nlink == 1
4929+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 4930+ /* todo: unnecessary? */
c2b27bf2
AM
4931+ /* && cpg->dentry->d_inode->i_nlink == 1 */
4932+ && cpg->bdst < cpg->bsrc
4933+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
4934+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 4935+ /* ignore this error */
4936+
076b876e
AM
4937+ if (!err) {
4938+ force = 0;
4939+ if (isreg) {
4940+ force = !!cpg->len;
4941+ if (cpg->len == -1)
4942+ force = !!i_size_read(h_inode);
4943+ }
4944+ au_fhsm_wrote(sb, cpg->bdst, force);
4945+ }
4946+
1facf9fc 4947+ if (do_dt)
4948+ au_dtime_revert(&dt);
4949+ return err;
4950+}
4951+
392086de 4952+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
4953+{
4954+ int err;
392086de 4955+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 4956+ struct inode *h_dir;
392086de 4957+ aufs_bindex_t bdst;
86dc4139 4958+
392086de
AM
4959+ dentry = cpg->dentry;
4960+ bdst = cpg->bdst;
4961+ h_dentry = au_h_dptr(dentry, bdst);
4962+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
4963+ dget(h_dentry);
4964+ au_set_h_dptr(dentry, bdst, NULL);
4965+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
4966+ if (!err)
4967+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 4968+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
4969+ } else {
4970+ err = 0;
4971+ parent = dget_parent(dentry);
4972+ h_parent = au_h_dptr(parent, bdst);
4973+ dput(parent);
4974+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
4975+ if (IS_ERR(h_path->dentry))
4976+ err = PTR_ERR(h_path->dentry);
86dc4139 4977+ }
392086de
AM
4978+ if (unlikely(err))
4979+ goto out;
86dc4139 4980+
86dc4139
AM
4981+ h_parent = h_dentry->d_parent; /* dir inode is locked */
4982+ h_dir = h_parent->d_inode;
4983+ IMustLock(h_dir);
523b37e3
AM
4984+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
4985+ /* no delegation since it is just created */
4986+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL);
86dc4139
AM
4987+ dput(h_path->dentry);
4988+
4989+out:
4990+ return err;
4991+}
4992+
1facf9fc 4993+/*
4994+ * copyup the @dentry from @bsrc to @bdst.
4995+ * the caller must set the both of lower dentries.
4996+ * @len is for truncating when it is -1 copyup the entire file.
4997+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 4998+ * basic->bsrc can be larger than basic->bdst.
1facf9fc 4999+ */
c2b27bf2 5000+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5001+{
5002+ int err, rerr;
5003+ aufs_bindex_t old_ibstart;
5004+ unsigned char isdir, plink;
1facf9fc 5005+ struct dentry *h_src, *h_dst, *h_parent;
523b37e3 5006+ struct inode *dst_inode, *h_dir, *inode, *delegated;
1facf9fc 5007+ struct super_block *sb;
86dc4139 5008+ struct au_branch *br;
c2b27bf2
AM
5009+ /* to reuduce stack size */
5010+ struct {
5011+ struct au_dtime dt;
5012+ struct path h_path;
5013+ struct au_cpup_reg_attr h_src_attr;
5014+ } *a;
1facf9fc 5015+
c2b27bf2
AM
5016+ err = -ENOMEM;
5017+ a = kmalloc(sizeof(*a), GFP_NOFS);
5018+ if (unlikely(!a))
5019+ goto out;
5020+ a->h_src_attr.valid = 0;
1facf9fc 5021+
c2b27bf2
AM
5022+ sb = cpg->dentry->d_sb;
5023+ br = au_sbr(sb, cpg->bdst);
5024+ a->h_path.mnt = au_br_mnt(br);
5025+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 5026+ h_parent = h_dst->d_parent; /* dir inode is locked */
5027+ h_dir = h_parent->d_inode;
5028+ IMustLock(h_dir);
5029+
c2b27bf2
AM
5030+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5031+ inode = cpg->dentry->d_inode;
1facf9fc 5032+
5033+ if (!dst_parent)
c2b27bf2 5034+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 5035+ else
5036+ dget(dst_parent);
5037+
5038+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 5039+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 5040+ if (dst_inode) {
5041+ if (unlikely(!plink)) {
5042+ err = -EIO;
027c5e7a
AM
5043+ AuIOErr("hi%lu(i%lu) exists on b%d "
5044+ "but plink is disabled\n",
c2b27bf2
AM
5045+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5046+ goto out_parent;
1facf9fc 5047+ }
5048+
5049+ if (dst_inode->i_nlink) {
c2b27bf2 5050+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5051+
c2b27bf2 5052+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 5053+ err = PTR_ERR(h_src);
5054+ if (IS_ERR(h_src))
c2b27bf2 5055+ goto out_parent;
1facf9fc 5056+ if (unlikely(!h_src->d_inode)) {
5057+ err = -EIO;
5058+ AuIOErr("i%lu exists on a upper branch "
027c5e7a
AM
5059+ "but not pseudo-linked\n",
5060+ inode->i_ino);
1facf9fc 5061+ dput(h_src);
c2b27bf2 5062+ goto out_parent;
1facf9fc 5063+ }
5064+
5065+ if (do_dt) {
c2b27bf2
AM
5066+ a->h_path.dentry = h_parent;
5067+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 5068+ }
86dc4139 5069+
c2b27bf2 5070+ a->h_path.dentry = h_dst;
523b37e3
AM
5071+ delegated = NULL;
5072+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 5073+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 5074+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 5075+ if (do_dt)
c2b27bf2 5076+ au_dtime_revert(&a->dt);
523b37e3
AM
5077+ if (unlikely(err == -EWOULDBLOCK)) {
5078+ pr_warn("cannot retry for NFSv4 delegation"
5079+ " for an internal link\n");
5080+ iput(delegated);
5081+ }
1facf9fc 5082+ dput(h_src);
c2b27bf2 5083+ goto out_parent;
1facf9fc 5084+ } else
5085+ /* todo: cpup_wh_file? */
5086+ /* udba work */
4a4d8108 5087+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 5088+ }
5089+
86dc4139 5090+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 5091+ old_ibstart = au_ibstart(inode);
c2b27bf2 5092+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 5093+ if (unlikely(err))
86dc4139 5094+ goto out_rev;
1facf9fc 5095+ dst_inode = h_dst->d_inode;
5096+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139 5097+ /* todo: necessary? */
c2b27bf2 5098+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5099+
c2b27bf2 5100+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5101+ if (unlikely(err)) {
5102+ /* todo: necessary? */
c2b27bf2 5103+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
86dc4139
AM
5104+ mutex_unlock(&dst_inode->i_mutex);
5105+ goto out_rev;
5106+ }
5107+
c2b27bf2 5108+ if (cpg->bdst < old_ibstart) {
86dc4139 5109+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5110+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5111+ if (unlikely(err)) {
c2b27bf2
AM
5112+ /* ignore an error */
5113+ /* au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5114+ mutex_unlock(&dst_inode->i_mutex);
5115+ goto out_rev;
4a4d8108 5116+ }
4a4d8108 5117+ }
c2b27bf2
AM
5118+ au_set_ibstart(inode, cpg->bdst);
5119+ } else
5120+ au_set_ibend(inode, cpg->bdst);
5121+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5122+ au_hi_flags(inode, isdir));
5123+
5124+ /* todo: necessary? */
c2b27bf2 5125+ /* err = au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5126+ mutex_unlock(&dst_inode->i_mutex);
5127+ if (unlikely(err))
5128+ goto out_rev;
5129+
5130+ if (!isdir
38d290e6
JR
5131+ && (h_src->d_inode->i_nlink > 1
5132+ || h_src->d_inode->i_state & I_LINKABLE)
86dc4139 5133+ && plink)
c2b27bf2 5134+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5135+
c2b27bf2
AM
5136+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5137+ a->h_path.dentry = h_dst;
392086de 5138+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5139+ }
5140+ if (!err)
c2b27bf2 5141+ goto out_parent; /* success */
1facf9fc 5142+
5143+ /* revert */
4a4d8108 5144+out_rev:
c2b27bf2
AM
5145+ a->h_path.dentry = h_parent;
5146+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5147+ a->h_path.dentry = h_dst;
86dc4139
AM
5148+ rerr = 0;
5149+ if (h_dst->d_inode) {
523b37e3
AM
5150+ if (!isdir) {
5151+ /* no delegation since it is just created */
5152+ rerr = vfsub_unlink(h_dir, &a->h_path,
5153+ /*delegated*/NULL, /*force*/0);
5154+ } else
c2b27bf2 5155+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5156+ }
c2b27bf2 5157+ au_dtime_revert(&a->dt);
1facf9fc 5158+ if (rerr) {
5159+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5160+ err = -EIO;
5161+ }
c2b27bf2 5162+out_parent:
1facf9fc 5163+ dput(dst_parent);
c2b27bf2
AM
5164+ kfree(a);
5165+out:
1facf9fc 5166+ return err;
5167+}
5168+
7e9cd9fe 5169+#if 0 /* reserved */
1facf9fc 5170+struct au_cpup_single_args {
5171+ int *errp;
c2b27bf2 5172+ struct au_cp_generic *cpg;
1facf9fc 5173+ struct dentry *dst_parent;
5174+};
5175+
5176+static void au_call_cpup_single(void *args)
5177+{
5178+ struct au_cpup_single_args *a = args;
86dc4139 5179+
c2b27bf2
AM
5180+ au_pin_hdir_acquire_nest(a->cpg->pin);
5181+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5182+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5183+}
c2b27bf2 5184+#endif
1facf9fc 5185+
53392da6
AM
5186+/*
5187+ * prevent SIGXFSZ in copy-up.
5188+ * testing CAP_MKNOD is for generic fs,
5189+ * but CAP_FSETID is for xfs only, currently.
5190+ */
86dc4139 5191+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5192+{
5193+ int do_sio;
86dc4139
AM
5194+ struct super_block *sb;
5195+ struct inode *h_dir;
53392da6
AM
5196+
5197+ do_sio = 0;
86dc4139 5198+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5199+ if (!au_wkq_test()
5200+ && (!au_sbi(sb)->si_plink_maint_pid
5201+ || au_plink_maint(sb, AuLock_NOPLM))) {
5202+ switch (mode & S_IFMT) {
5203+ case S_IFREG:
5204+ /* no condition about RLIMIT_FSIZE and the file size */
5205+ do_sio = 1;
5206+ break;
5207+ case S_IFCHR:
5208+ case S_IFBLK:
5209+ do_sio = !capable(CAP_MKNOD);
5210+ break;
5211+ }
5212+ if (!do_sio)
5213+ do_sio = ((mode & (S_ISUID | S_ISGID))
5214+ && !capable(CAP_FSETID));
86dc4139
AM
5215+ /* this workaround may be removed in the future */
5216+ if (!do_sio) {
5217+ h_dir = au_pinned_h_dir(pin);
5218+ do_sio = h_dir->i_mode & S_ISVTX;
5219+ }
53392da6
AM
5220+ }
5221+
5222+ return do_sio;
5223+}
5224+
7e9cd9fe 5225+#if 0 /* reserved */
c2b27bf2 5226+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5227+{
5228+ int err, wkq_err;
1facf9fc 5229+ struct dentry *h_dentry;
5230+
c2b27bf2 5231+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
86dc4139 5232+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
c2b27bf2 5233+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 5234+ else {
5235+ struct au_cpup_single_args args = {
5236+ .errp = &err,
c2b27bf2
AM
5237+ .cpg = cpg,
5238+ .dst_parent = dst_parent
1facf9fc 5239+ };
5240+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5241+ if (unlikely(wkq_err))
5242+ err = wkq_err;
5243+ }
5244+
5245+ return err;
5246+}
c2b27bf2 5247+#endif
1facf9fc 5248+
5249+/*
5250+ * copyup the @dentry from the first active lower branch to @bdst,
5251+ * using au_cpup_single().
5252+ */
c2b27bf2 5253+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5254+{
5255+ int err;
c2b27bf2
AM
5256+ unsigned int flags_orig;
5257+ struct dentry *dentry;
5258+
5259+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 5260+
c2b27bf2 5261+ dentry = cpg->dentry;
86dc4139 5262+ DiMustWriteLock(dentry);
1facf9fc 5263+
c2b27bf2 5264+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 5265+ if (!err) {
c2b27bf2
AM
5266+ flags_orig = cpg->flags;
5267+ au_fset_cpup(cpg->flags, RENAME);
5268+ err = au_cpup_single(cpg, NULL);
5269+ cpg->flags = flags_orig;
1facf9fc 5270+ if (!err)
5271+ return 0; /* success */
5272+
5273+ /* revert */
c2b27bf2
AM
5274+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5275+ au_set_dbstart(dentry, cpg->bsrc);
1facf9fc 5276+ }
5277+
5278+ return err;
5279+}
5280+
5281+struct au_cpup_simple_args {
5282+ int *errp;
c2b27bf2 5283+ struct au_cp_generic *cpg;
1facf9fc 5284+};
5285+
5286+static void au_call_cpup_simple(void *args)
5287+{
5288+ struct au_cpup_simple_args *a = args;
86dc4139 5289+
c2b27bf2
AM
5290+ au_pin_hdir_acquire_nest(a->cpg->pin);
5291+ *a->errp = au_cpup_simple(a->cpg);
5292+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5293+}
5294+
c2b27bf2 5295+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5296+{
5297+ int err, wkq_err;
c2b27bf2
AM
5298+ struct dentry *dentry, *parent;
5299+ struct file *h_file;
1facf9fc 5300+ struct inode *h_dir;
5301+
c2b27bf2
AM
5302+ dentry = cpg->dentry;
5303+ h_file = NULL;
5304+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
5305+ AuDebugOn(cpg->bsrc < 0);
392086de 5306+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
5307+ err = PTR_ERR(h_file);
5308+ if (IS_ERR(h_file))
5309+ goto out;
5310+ }
5311+
1facf9fc 5312+ parent = dget_parent(dentry);
c2b27bf2 5313+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
53392da6 5314+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
5315+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
5316+ err = au_cpup_simple(cpg);
1facf9fc 5317+ else {
5318+ struct au_cpup_simple_args args = {
5319+ .errp = &err,
c2b27bf2 5320+ .cpg = cpg
1facf9fc 5321+ };
5322+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
5323+ if (unlikely(wkq_err))
5324+ err = wkq_err;
5325+ }
5326+
5327+ dput(parent);
c2b27bf2
AM
5328+ if (h_file)
5329+ au_h_open_post(dentry, cpg->bsrc, h_file);
5330+
5331+out:
1facf9fc 5332+ return err;
5333+}
5334+
c2b27bf2 5335+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 5336+{
c2b27bf2
AM
5337+ aufs_bindex_t bsrc, bend;
5338+ struct dentry *dentry, *h_dentry;
367653fa 5339+
c2b27bf2
AM
5340+ if (cpg->bsrc < 0) {
5341+ dentry = cpg->dentry;
5342+ bend = au_dbend(dentry);
5343+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
5344+ h_dentry = au_h_dptr(dentry, bsrc);
5345+ if (h_dentry) {
5346+ AuDebugOn(!h_dentry->d_inode);
5347+ break;
5348+ }
5349+ }
5350+ AuDebugOn(bsrc > bend);
5351+ cpg->bsrc = bsrc;
367653fa 5352+ }
c2b27bf2
AM
5353+ AuDebugOn(cpg->bsrc <= cpg->bdst);
5354+ return au_do_sio_cpup_simple(cpg);
5355+}
367653fa 5356+
c2b27bf2
AM
5357+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
5358+{
5359+ AuDebugOn(cpg->bdst <= cpg->bsrc);
5360+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
5361+}
5362+
1facf9fc 5363+/* ---------------------------------------------------------------------- */
5364+
5365+/*
5366+ * copyup the deleted file for writing.
5367+ */
c2b27bf2
AM
5368+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
5369+ struct file *file)
1facf9fc 5370+{
5371+ int err;
c2b27bf2
AM
5372+ unsigned int flags_orig;
5373+ aufs_bindex_t bsrc_orig;
1facf9fc 5374+ struct dentry *h_d_dst, *h_d_start;
c2b27bf2 5375+ struct au_dinfo *dinfo;
4a4d8108 5376+ struct au_hdentry *hdp;
1facf9fc 5377+
c2b27bf2 5378+ dinfo = au_di(cpg->dentry);
1308ab2a 5379+ AuRwMustWriteLock(&dinfo->di_rwsem);
5380+
c2b27bf2
AM
5381+ bsrc_orig = cpg->bsrc;
5382+ cpg->bsrc = dinfo->di_bstart;
4a4d8108 5383+ hdp = dinfo->di_hdentry;
c2b27bf2
AM
5384+ h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
5385+ dinfo->di_bstart = cpg->bdst;
5386+ hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
86dc4139 5387+ h_d_start = NULL;
027c5e7a 5388+ if (file) {
c2b27bf2 5389+ h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
2000de60 5390+ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_path.dentry;
027c5e7a 5391+ }
c2b27bf2
AM
5392+ flags_orig = cpg->flags;
5393+ cpg->flags = !AuCpup_DTIME;
5394+ err = au_cpup_single(cpg, /*h_parent*/NULL);
5395+ cpg->flags = flags_orig;
027c5e7a
AM
5396+ if (file) {
5397+ if (!err)
5398+ err = au_reopen_nondir(file);
c2b27bf2 5399+ hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
1facf9fc 5400+ }
c2b27bf2
AM
5401+ hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
5402+ dinfo->di_bstart = cpg->bsrc;
5403+ cpg->bsrc = bsrc_orig;
1facf9fc 5404+
5405+ return err;
5406+}
5407+
c2b27bf2 5408+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5409+{
5410+ int err;
c2b27bf2 5411+ aufs_bindex_t bdst;
1facf9fc 5412+ struct au_dtime dt;
c2b27bf2 5413+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 5414+ struct au_branch *br;
5415+ struct path h_path;
5416+
c2b27bf2
AM
5417+ dentry = cpg->dentry;
5418+ bdst = cpg->bdst;
1facf9fc 5419+ br = au_sbr(dentry->d_sb, bdst);
5420+ parent = dget_parent(dentry);
5421+ h_parent = au_h_dptr(parent, bdst);
5422+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
5423+ err = PTR_ERR(wh_dentry);
5424+ if (IS_ERR(wh_dentry))
5425+ goto out;
5426+
5427+ h_path.dentry = h_parent;
86dc4139 5428+ h_path.mnt = au_br_mnt(br);
1facf9fc 5429+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 5430+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 5431+ if (unlikely(err))
5432+ goto out_wh;
5433+
5434+ dget(wh_dentry);
5435+ h_path.dentry = wh_dentry;
2000de60 5436+ if (!d_is_dir(wh_dentry)) {
523b37e3
AM
5437+ /* no delegation since it is just created */
5438+ err = vfsub_unlink(h_parent->d_inode, &h_path,
5439+ /*delegated*/NULL, /*force*/0);
5440+ } else
4a4d8108 5441+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
1facf9fc 5442+ if (unlikely(err)) {
523b37e3
AM
5443+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
5444+ wh_dentry, err);
1facf9fc 5445+ err = -EIO;
5446+ }
5447+ au_dtime_revert(&dt);
5448+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
5449+
4f0767ce 5450+out_wh:
1facf9fc 5451+ dput(wh_dentry);
4f0767ce 5452+out:
1facf9fc 5453+ dput(parent);
5454+ return err;
5455+}
5456+
5457+struct au_cpup_wh_args {
5458+ int *errp;
c2b27bf2 5459+ struct au_cp_generic *cpg;
1facf9fc 5460+ struct file *file;
5461+};
5462+
5463+static void au_call_cpup_wh(void *args)
5464+{
5465+ struct au_cpup_wh_args *a = args;
86dc4139 5466+
c2b27bf2
AM
5467+ au_pin_hdir_acquire_nest(a->cpg->pin);
5468+ *a->errp = au_cpup_wh(a->cpg, a->file);
5469+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5470+}
5471+
c2b27bf2 5472+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5473+{
5474+ int err, wkq_err;
c2b27bf2 5475+ aufs_bindex_t bdst;
c1595e42 5476+ struct dentry *dentry, *parent, *h_orph, *h_parent;
86dc4139 5477+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 5478+ struct au_wbr *wbr;
c2b27bf2 5479+ struct au_pin wh_pin, *pin_orig;
1facf9fc 5480+
c2b27bf2
AM
5481+ dentry = cpg->dentry;
5482+ bdst = cpg->bdst;
1facf9fc 5483+ parent = dget_parent(dentry);
5484+ dir = parent->d_inode;
5485+ h_orph = NULL;
5486+ h_parent = NULL;
5487+ h_dir = au_igrab(au_h_iptr(dir, bdst));
5488+ h_tmpdir = h_dir;
c2b27bf2 5489+ pin_orig = NULL;
1facf9fc 5490+ if (!h_dir->i_nlink) {
5491+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
5492+ h_orph = wbr->wbr_orph;
5493+
5494+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 5495+ au_set_h_dptr(parent, bdst, dget(h_orph));
5496+ h_tmpdir = h_orph->d_inode;
1facf9fc 5497+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
5498+
dece6358 5499+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 5500+ /* todo: au_h_open_pre()? */
86dc4139 5501+
c2b27bf2 5502+ pin_orig = cpg->pin;
86dc4139 5503+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
5504+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
5505+ cpg->pin = &wh_pin;
1facf9fc 5506+ }
5507+
53392da6 5508+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
5509+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
5510+ err = au_cpup_wh(cpg, file);
1facf9fc 5511+ else {
5512+ struct au_cpup_wh_args args = {
5513+ .errp = &err,
c2b27bf2
AM
5514+ .cpg = cpg,
5515+ .file = file
1facf9fc 5516+ };
5517+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
5518+ if (unlikely(wkq_err))
5519+ err = wkq_err;
5520+ }
5521+
5522+ if (h_orph) {
5523+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 5524+ /* todo: au_h_open_post()? */
1facf9fc 5525+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 5526+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
5527+ AuDebugOn(!pin_orig);
5528+ cpg->pin = pin_orig;
1facf9fc 5529+ }
5530+ iput(h_dir);
5531+ dput(parent);
5532+
5533+ return err;
5534+}
5535+
5536+/* ---------------------------------------------------------------------- */
5537+
5538+/*
5539+ * generic routine for both of copy-up and copy-down.
5540+ */
5541+/* cf. revalidate function in file.c */
5542+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5543+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5544+ struct au_pin *pin,
1facf9fc 5545+ struct dentry *h_parent, void *arg),
5546+ void *arg)
5547+{
5548+ int err;
5549+ struct au_pin pin;
5550+ struct dentry *d, *parent, *h_parent, *real_parent;
5551+
5552+ err = 0;
5553+ parent = dget_parent(dentry);
5554+ if (IS_ROOT(parent))
5555+ goto out;
5556+
5557+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
5558+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
5559+
5560+ /* do not use au_dpage */
5561+ real_parent = parent;
5562+ while (1) {
5563+ dput(parent);
5564+ parent = dget_parent(dentry);
5565+ h_parent = au_h_dptr(parent, bdst);
5566+ if (h_parent)
5567+ goto out; /* success */
5568+
5569+ /* find top dir which is necessary to cpup */
5570+ do {
5571+ d = parent;
5572+ dput(parent);
5573+ parent = dget_parent(d);
5574+ di_read_lock_parent3(parent, !AuLock_IR);
5575+ h_parent = au_h_dptr(parent, bdst);
5576+ di_read_unlock(parent, !AuLock_IR);
5577+ } while (!h_parent);
5578+
5579+ if (d != real_parent)
5580+ di_write_lock_child3(d);
5581+
5582+ /* somebody else might create while we were sleeping */
5583+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
5584+ if (au_h_dptr(d, bdst))
5585+ au_update_dbstart(d);
5586+
5587+ au_pin_set_dentry(&pin, d);
5588+ err = au_do_pin(&pin);
5589+ if (!err) {
86dc4139 5590+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 5591+ au_unpin(&pin);
5592+ }
5593+ }
5594+
5595+ if (d != real_parent)
5596+ di_write_unlock(d);
5597+ if (unlikely(err))
5598+ break;
5599+ }
5600+
4f0767ce 5601+out:
1facf9fc 5602+ dput(parent);
5603+ return err;
5604+}
5605+
5606+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5607+ struct au_pin *pin,
2000de60 5608+ struct dentry *h_parent __maybe_unused,
1facf9fc 5609+ void *arg __maybe_unused)
5610+{
c2b27bf2
AM
5611+ struct au_cp_generic cpg = {
5612+ .dentry = dentry,
5613+ .bdst = bdst,
5614+ .bsrc = -1,
5615+ .len = 0,
5616+ .pin = pin,
5617+ .flags = AuCpup_DTIME
5618+ };
5619+ return au_sio_cpup_simple(&cpg);
1facf9fc 5620+}
5621+
5622+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5623+{
5624+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
5625+}
5626+
5627+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5628+{
5629+ int err;
5630+ struct dentry *parent;
5631+ struct inode *dir;
5632+
5633+ parent = dget_parent(dentry);
5634+ dir = parent->d_inode;
5635+ err = 0;
5636+ if (au_h_iptr(dir, bdst))
5637+ goto out;
5638+
5639+ di_read_unlock(parent, AuLock_IR);
5640+ di_write_lock_parent(parent);
5641+ /* someone else might change our inode while we were sleeping */
5642+ if (!au_h_iptr(dir, bdst))
5643+ err = au_cpup_dirs(dentry, bdst);
5644+ di_downgrade_lock(parent, AuLock_IR);
5645+
4f0767ce 5646+out:
1facf9fc 5647+ dput(parent);
5648+ return err;
5649+}
7f207e10
AM
5650diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
5651--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 5652+++ linux/fs/aufs/cpup.h 2015-04-13 15:10:20.780156788 +0200
523b37e3 5653@@ -0,0 +1,94 @@
1facf9fc 5654+/*
2000de60 5655+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 5656+ *
5657+ * This program, aufs is free software; you can redistribute it and/or modify
5658+ * it under the terms of the GNU General Public License as published by
5659+ * the Free Software Foundation; either version 2 of the License, or
5660+ * (at your option) any later version.
dece6358
AM
5661+ *
5662+ * This program is distributed in the hope that it will be useful,
5663+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5664+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5665+ * GNU General Public License for more details.
5666+ *
5667+ * You should have received a copy of the GNU General Public License
523b37e3 5668+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5669+ */
5670+
5671+/*
5672+ * copy-up/down functions
5673+ */
5674+
5675+#ifndef __AUFS_CPUP_H__
5676+#define __AUFS_CPUP_H__
5677+
5678+#ifdef __KERNEL__
5679+
dece6358 5680+#include <linux/path.h>
1facf9fc 5681+
dece6358
AM
5682+struct inode;
5683+struct file;
86dc4139 5684+struct au_pin;
dece6358 5685+
86dc4139 5686+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 5687+void au_cpup_attr_timesizes(struct inode *inode);
5688+void au_cpup_attr_nlink(struct inode *inode, int force);
5689+void au_cpup_attr_changeable(struct inode *inode);
5690+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
5691+void au_cpup_attr_all(struct inode *inode, int force);
5692+
5693+/* ---------------------------------------------------------------------- */
5694+
c2b27bf2
AM
5695+struct au_cp_generic {
5696+ struct dentry *dentry;
5697+ aufs_bindex_t bdst, bsrc;
5698+ loff_t len;
5699+ struct au_pin *pin;
5700+ unsigned int flags;
5701+};
5702+
1facf9fc 5703+/* cpup flags */
392086de
AM
5704+#define AuCpup_DTIME 1 /* do dtime_store/revert */
5705+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
5706+ for link(2) */
5707+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
5708+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
5709+ cpup */
5710+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
5711+ existing entry */
5712+#define AuCpup_RWDST (1 << 5) /* force write target even if
5713+ the branch is marked as RO */
c2b27bf2 5714+
1facf9fc 5715+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
5716+#define au_fset_cpup(flags, name) \
5717+ do { (flags) |= AuCpup_##name; } while (0)
5718+#define au_fclr_cpup(flags, name) \
5719+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 5720+
5721+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
5722+int au_sio_cpup_simple(struct au_cp_generic *cpg);
5723+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
5724+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 5725+
5726+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5727+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5728+ struct au_pin *pin,
1facf9fc 5729+ struct dentry *h_parent, void *arg),
5730+ void *arg);
5731+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5732+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5733+
5734+/* ---------------------------------------------------------------------- */
5735+
5736+/* keep timestamps when copyup */
5737+struct au_dtime {
5738+ struct dentry *dt_dentry;
5739+ struct path dt_h_path;
5740+ struct timespec dt_atime, dt_mtime;
5741+};
5742+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5743+ struct path *h_path);
5744+void au_dtime_revert(struct au_dtime *dt);
5745+
5746+#endif /* __KERNEL__ */
5747+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
5748diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
5749--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 5750+++ linux/fs/aufs/dbgaufs.c 2015-04-13 15:10:20.780156788 +0200
523b37e3 5751@@ -0,0 +1,432 @@
1facf9fc 5752+/*
2000de60 5753+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 5754+ *
5755+ * This program, aufs is free software; you can redistribute it and/or modify
5756+ * it under the terms of the GNU General Public License as published by
5757+ * the Free Software Foundation; either version 2 of the License, or
5758+ * (at your option) any later version.
dece6358
AM
5759+ *
5760+ * This program is distributed in the hope that it will be useful,
5761+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5762+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5763+ * GNU General Public License for more details.
5764+ *
5765+ * You should have received a copy of the GNU General Public License
523b37e3 5766+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5767+ */
5768+
5769+/*
5770+ * debugfs interface
5771+ */
5772+
5773+#include <linux/debugfs.h>
5774+#include "aufs.h"
5775+
5776+#ifndef CONFIG_SYSFS
5777+#error DEBUG_FS depends upon SYSFS
5778+#endif
5779+
5780+static struct dentry *dbgaufs;
5781+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
5782+
5783+/* 20 is max digits length of ulong 64 */
5784+struct dbgaufs_arg {
5785+ int n;
5786+ char a[20 * 4];
5787+};
5788+
5789+/*
5790+ * common function for all XINO files
5791+ */
5792+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
5793+ struct file *file)
5794+{
5795+ kfree(file->private_data);
5796+ return 0;
5797+}
5798+
5799+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
5800+{
5801+ int err;
5802+ struct kstat st;
5803+ struct dbgaufs_arg *p;
5804+
5805+ err = -ENOMEM;
5806+ p = kmalloc(sizeof(*p), GFP_NOFS);
5807+ if (unlikely(!p))
5808+ goto out;
5809+
5810+ err = 0;
5811+ p->n = 0;
5812+ file->private_data = p;
5813+ if (!xf)
5814+ goto out;
5815+
c06a8ce3 5816+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 5817+ if (!err) {
5818+ if (do_fcnt)
5819+ p->n = snprintf
5820+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
5821+ (long)file_count(xf), st.blocks, st.blksize,
5822+ (long long)st.size);
5823+ else
5824+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
5825+ st.blocks, st.blksize,
5826+ (long long)st.size);
5827+ AuDebugOn(p->n >= sizeof(p->a));
5828+ } else {
5829+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
5830+ err = 0;
5831+ }
5832+
4f0767ce 5833+out:
1facf9fc 5834+ return err;
5835+
5836+}
5837+
5838+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
5839+ size_t count, loff_t *ppos)
5840+{
5841+ struct dbgaufs_arg *p;
5842+
5843+ p = file->private_data;
5844+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5845+}
5846+
5847+/* ---------------------------------------------------------------------- */
5848+
86dc4139
AM
5849+struct dbgaufs_plink_arg {
5850+ int n;
5851+ char a[];
5852+};
5853+
5854+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
5855+ struct file *file)
5856+{
5857+ free_page((unsigned long)file->private_data);
5858+ return 0;
5859+}
5860+
5861+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
5862+{
5863+ int err, i, limit;
5864+ unsigned long n, sum;
5865+ struct dbgaufs_plink_arg *p;
5866+ struct au_sbinfo *sbinfo;
5867+ struct super_block *sb;
5868+ struct au_sphlhead *sphl;
5869+
5870+ err = -ENOMEM;
5871+ p = (void *)get_zeroed_page(GFP_NOFS);
5872+ if (unlikely(!p))
5873+ goto out;
5874+
5875+ err = -EFBIG;
5876+ sbinfo = inode->i_private;
5877+ sb = sbinfo->si_sb;
5878+ si_noflush_read_lock(sb);
5879+ if (au_opt_test(au_mntflags(sb), PLINK)) {
5880+ limit = PAGE_SIZE - sizeof(p->n);
5881+
5882+ /* the number of buckets */
5883+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
5884+ p->n += n;
5885+ limit -= n;
5886+
5887+ sum = 0;
5888+ for (i = 0, sphl = sbinfo->si_plink;
5889+ i < AuPlink_NHASH;
5890+ i++, sphl++) {
5891+ n = au_sphl_count(sphl);
5892+ sum += n;
5893+
5894+ n = snprintf(p->a + p->n, limit, "%lu ", n);
5895+ p->n += n;
5896+ limit -= n;
5897+ if (unlikely(limit <= 0))
5898+ goto out_free;
5899+ }
5900+ p->a[p->n - 1] = '\n';
5901+
5902+ /* the sum of plinks */
5903+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
5904+ p->n += n;
5905+ limit -= n;
5906+ if (unlikely(limit <= 0))
5907+ goto out_free;
5908+ } else {
5909+#define str "1\n0\n0\n"
5910+ p->n = sizeof(str) - 1;
5911+ strcpy(p->a, str);
5912+#undef str
5913+ }
5914+ si_read_unlock(sb);
5915+
5916+ err = 0;
5917+ file->private_data = p;
5918+ goto out; /* success */
5919+
5920+out_free:
5921+ free_page((unsigned long)p);
5922+out:
5923+ return err;
5924+}
5925+
5926+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
5927+ size_t count, loff_t *ppos)
5928+{
5929+ struct dbgaufs_plink_arg *p;
5930+
5931+ p = file->private_data;
5932+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5933+}
5934+
5935+static const struct file_operations dbgaufs_plink_fop = {
5936+ .owner = THIS_MODULE,
5937+ .open = dbgaufs_plink_open,
5938+ .release = dbgaufs_plink_release,
5939+ .read = dbgaufs_plink_read
5940+};
5941+
5942+/* ---------------------------------------------------------------------- */
5943+
1facf9fc 5944+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
5945+{
5946+ int err;
5947+ struct au_sbinfo *sbinfo;
5948+ struct super_block *sb;
5949+
5950+ sbinfo = inode->i_private;
5951+ sb = sbinfo->si_sb;
5952+ si_noflush_read_lock(sb);
5953+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
5954+ si_read_unlock(sb);
5955+ return err;
5956+}
5957+
5958+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 5959+ .owner = THIS_MODULE,
1facf9fc 5960+ .open = dbgaufs_xib_open,
5961+ .release = dbgaufs_xi_release,
5962+ .read = dbgaufs_xi_read
5963+};
5964+
5965+/* ---------------------------------------------------------------------- */
5966+
5967+#define DbgaufsXi_PREFIX "xi"
5968+
5969+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
5970+{
5971+ int err;
5972+ long l;
5973+ struct au_sbinfo *sbinfo;
5974+ struct super_block *sb;
5975+ struct file *xf;
5976+ struct qstr *name;
5977+
5978+ err = -ENOENT;
5979+ xf = NULL;
2000de60 5980+ name = &file->f_path.dentry->d_name;
1facf9fc 5981+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
5982+ || memcmp(name->name, DbgaufsXi_PREFIX,
5983+ sizeof(DbgaufsXi_PREFIX) - 1)))
5984+ goto out;
9dbd164d 5985+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 5986+ if (unlikely(err))
5987+ goto out;
5988+
5989+ sbinfo = inode->i_private;
5990+ sb = sbinfo->si_sb;
5991+ si_noflush_read_lock(sb);
5992+ if (l <= au_sbend(sb)) {
5993+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
5994+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
5995+ } else
5996+ err = -ENOENT;
5997+ si_read_unlock(sb);
5998+
4f0767ce 5999+out:
1facf9fc 6000+ return err;
6001+}
6002+
6003+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 6004+ .owner = THIS_MODULE,
1facf9fc 6005+ .open = dbgaufs_xino_open,
6006+ .release = dbgaufs_xi_release,
6007+ .read = dbgaufs_xi_read
6008+};
6009+
6010+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6011+{
6012+ aufs_bindex_t bend;
6013+ struct au_branch *br;
6014+ struct au_xino_file *xi;
6015+
6016+ if (!au_sbi(sb)->si_dbgaufs)
6017+ return;
6018+
6019+ bend = au_sbend(sb);
6020+ for (; bindex <= bend; bindex++) {
6021+ br = au_sbr(sb, bindex);
6022+ xi = &br->br_xino;
c06a8ce3
AM
6023+ debugfs_remove(xi->xi_dbgaufs);
6024+ xi->xi_dbgaufs = NULL;
1facf9fc 6025+ }
6026+}
6027+
6028+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
6029+{
6030+ struct au_sbinfo *sbinfo;
6031+ struct dentry *parent;
6032+ struct au_branch *br;
6033+ struct au_xino_file *xi;
6034+ aufs_bindex_t bend;
6035+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
6036+
6037+ sbinfo = au_sbi(sb);
6038+ parent = sbinfo->si_dbgaufs;
6039+ if (!parent)
6040+ return;
6041+
6042+ bend = au_sbend(sb);
6043+ for (; bindex <= bend; bindex++) {
6044+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6045+ br = au_sbr(sb, bindex);
6046+ xi = &br->br_xino;
6047+ AuDebugOn(xi->xi_dbgaufs);
6048+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6049+ sbinfo, &dbgaufs_xino_fop);
6050+ /* ignore an error */
6051+ if (unlikely(!xi->xi_dbgaufs))
6052+ AuWarn1("failed %s under debugfs\n", name);
6053+ }
6054+}
6055+
6056+/* ---------------------------------------------------------------------- */
6057+
6058+#ifdef CONFIG_AUFS_EXPORT
6059+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6060+{
6061+ int err;
6062+ struct au_sbinfo *sbinfo;
6063+ struct super_block *sb;
6064+
6065+ sbinfo = inode->i_private;
6066+ sb = sbinfo->si_sb;
6067+ si_noflush_read_lock(sb);
6068+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
6069+ si_read_unlock(sb);
6070+ return err;
6071+}
6072+
6073+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 6074+ .owner = THIS_MODULE,
1facf9fc 6075+ .open = dbgaufs_xigen_open,
6076+ .release = dbgaufs_xi_release,
6077+ .read = dbgaufs_xi_read
6078+};
6079+
6080+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6081+{
6082+ int err;
6083+
dece6358 6084+ /*
c1595e42 6085+ * This function is a dynamic '__init' function actually,
dece6358
AM
6086+ * so the tiny check for si_rwsem is unnecessary.
6087+ */
6088+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6089+
1facf9fc 6090+ err = -EIO;
6091+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6092+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6093+ &dbgaufs_xigen_fop);
6094+ if (sbinfo->si_dbgaufs_xigen)
6095+ err = 0;
6096+
6097+ return err;
6098+}
6099+#else
6100+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6101+{
6102+ return 0;
6103+}
6104+#endif /* CONFIG_AUFS_EXPORT */
6105+
6106+/* ---------------------------------------------------------------------- */
6107+
6108+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6109+{
dece6358 6110+ /*
7e9cd9fe 6111+ * This function is a dynamic '__fin' function actually,
dece6358
AM
6112+ * so the tiny check for si_rwsem is unnecessary.
6113+ */
6114+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6115+
1facf9fc 6116+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6117+ sbinfo->si_dbgaufs = NULL;
6118+ kobject_put(&sbinfo->si_kobj);
6119+}
6120+
6121+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6122+{
6123+ int err;
6124+ char name[SysaufsSiNameLen];
6125+
dece6358 6126+ /*
c1595e42 6127+ * This function is a dynamic '__init' function actually,
dece6358
AM
6128+ * so the tiny check for si_rwsem is unnecessary.
6129+ */
6130+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6131+
1facf9fc 6132+ err = -ENOENT;
6133+ if (!dbgaufs) {
6134+ AuErr1("/debug/aufs is uninitialized\n");
6135+ goto out;
6136+ }
6137+
6138+ err = -EIO;
6139+ sysaufs_name(sbinfo, name);
6140+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6141+ if (unlikely(!sbinfo->si_dbgaufs))
6142+ goto out;
6143+ kobject_get(&sbinfo->si_kobj);
6144+
6145+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6146+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6147+ &dbgaufs_xib_fop);
6148+ if (unlikely(!sbinfo->si_dbgaufs_xib))
6149+ goto out_dir;
6150+
86dc4139
AM
6151+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6152+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6153+ &dbgaufs_plink_fop);
6154+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6155+ goto out_dir;
6156+
1facf9fc 6157+ err = dbgaufs_xigen_init(sbinfo);
6158+ if (!err)
6159+ goto out; /* success */
6160+
4f0767ce 6161+out_dir:
1facf9fc 6162+ dbgaufs_si_fin(sbinfo);
4f0767ce 6163+out:
1facf9fc 6164+ return err;
6165+}
6166+
6167+/* ---------------------------------------------------------------------- */
6168+
6169+void dbgaufs_fin(void)
6170+{
6171+ debugfs_remove(dbgaufs);
6172+}
6173+
6174+int __init dbgaufs_init(void)
6175+{
6176+ int err;
6177+
6178+ err = -EIO;
6179+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
6180+ if (dbgaufs)
6181+ err = 0;
6182+ return err;
6183+}
7f207e10
AM
6184diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
6185--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 6186+++ linux/fs/aufs/dbgaufs.h 2015-04-13 15:10:20.780156788 +0200
523b37e3 6187@@ -0,0 +1,48 @@
1facf9fc 6188+/*
2000de60 6189+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6190+ *
6191+ * This program, aufs is free software; you can redistribute it and/or modify
6192+ * it under the terms of the GNU General Public License as published by
6193+ * the Free Software Foundation; either version 2 of the License, or
6194+ * (at your option) any later version.
dece6358
AM
6195+ *
6196+ * This program is distributed in the hope that it will be useful,
6197+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6198+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6199+ * GNU General Public License for more details.
6200+ *
6201+ * You should have received a copy of the GNU General Public License
523b37e3 6202+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6203+ */
6204+
6205+/*
6206+ * debugfs interface
6207+ */
6208+
6209+#ifndef __DBGAUFS_H__
6210+#define __DBGAUFS_H__
6211+
6212+#ifdef __KERNEL__
6213+
dece6358 6214+struct super_block;
1facf9fc 6215+struct au_sbinfo;
dece6358 6216+
1facf9fc 6217+#ifdef CONFIG_DEBUG_FS
6218+/* dbgaufs.c */
6219+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
6220+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
6221+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
6222+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
6223+void dbgaufs_fin(void);
6224+int __init dbgaufs_init(void);
1facf9fc 6225+#else
4a4d8108
AM
6226+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
6227+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
6228+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
6229+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
6230+AuStubVoid(dbgaufs_fin, void)
6231+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 6232+#endif /* CONFIG_DEBUG_FS */
6233+
6234+#endif /* __KERNEL__ */
6235+#endif /* __DBGAUFS_H__ */
7f207e10
AM
6236diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
6237--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 6238+++ linux/fs/aufs/dcsub.c 2015-04-13 15:10:20.780156788 +0200
c1595e42 6239@@ -0,0 +1,224 @@
1facf9fc 6240+/*
2000de60 6241+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6242+ *
6243+ * This program, aufs is free software; you can redistribute it and/or modify
6244+ * it under the terms of the GNU General Public License as published by
6245+ * the Free Software Foundation; either version 2 of the License, or
6246+ * (at your option) any later version.
dece6358
AM
6247+ *
6248+ * This program is distributed in the hope that it will be useful,
6249+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6250+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6251+ * GNU General Public License for more details.
6252+ *
6253+ * You should have received a copy of the GNU General Public License
523b37e3 6254+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6255+ */
6256+
6257+/*
6258+ * sub-routines for dentry cache
6259+ */
6260+
6261+#include "aufs.h"
6262+
6263+static void au_dpage_free(struct au_dpage *dpage)
6264+{
6265+ int i;
6266+ struct dentry **p;
6267+
6268+ p = dpage->dentries;
6269+ for (i = 0; i < dpage->ndentry; i++)
6270+ dput(*p++);
6271+ free_page((unsigned long)dpage->dentries);
6272+}
6273+
6274+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
6275+{
6276+ int err;
6277+ void *p;
6278+
6279+ err = -ENOMEM;
6280+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
6281+ if (unlikely(!dpages->dpages))
6282+ goto out;
6283+
6284+ p = (void *)__get_free_page(gfp);
6285+ if (unlikely(!p))
6286+ goto out_dpages;
6287+
6288+ dpages->dpages[0].ndentry = 0;
6289+ dpages->dpages[0].dentries = p;
6290+ dpages->ndpage = 1;
6291+ return 0; /* success */
6292+
4f0767ce 6293+out_dpages:
1facf9fc 6294+ kfree(dpages->dpages);
4f0767ce 6295+out:
1facf9fc 6296+ return err;
6297+}
6298+
6299+void au_dpages_free(struct au_dcsub_pages *dpages)
6300+{
6301+ int i;
6302+ struct au_dpage *p;
6303+
6304+ p = dpages->dpages;
6305+ for (i = 0; i < dpages->ndpage; i++)
6306+ au_dpage_free(p++);
6307+ kfree(dpages->dpages);
6308+}
6309+
6310+static int au_dpages_append(struct au_dcsub_pages *dpages,
6311+ struct dentry *dentry, gfp_t gfp)
6312+{
6313+ int err, sz;
6314+ struct au_dpage *dpage;
6315+ void *p;
6316+
6317+ dpage = dpages->dpages + dpages->ndpage - 1;
6318+ sz = PAGE_SIZE / sizeof(dentry);
6319+ if (unlikely(dpage->ndentry >= sz)) {
6320+ AuLabel(new dpage);
6321+ err = -ENOMEM;
6322+ sz = dpages->ndpage * sizeof(*dpages->dpages);
6323+ p = au_kzrealloc(dpages->dpages, sz,
6324+ sz + sizeof(*dpages->dpages), gfp);
6325+ if (unlikely(!p))
6326+ goto out;
6327+
6328+ dpages->dpages = p;
6329+ dpage = dpages->dpages + dpages->ndpage;
6330+ p = (void *)__get_free_page(gfp);
6331+ if (unlikely(!p))
6332+ goto out;
6333+
6334+ dpage->ndentry = 0;
6335+ dpage->dentries = p;
6336+ dpages->ndpage++;
6337+ }
6338+
c1595e42 6339+ AuDebugOn(au_dcount(dentry) <= 0);
027c5e7a 6340+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 6341+ return 0; /* success */
6342+
4f0767ce 6343+out:
1facf9fc 6344+ return err;
6345+}
6346+
c1595e42
JR
6347+/* todo: BAD approach */
6348+/* copied from linux/fs/dcache.c */
6349+enum d_walk_ret {
6350+ D_WALK_CONTINUE,
6351+ D_WALK_QUIT,
6352+ D_WALK_NORETRY,
6353+ D_WALK_SKIP,
6354+};
6355+
6356+extern void d_walk(struct dentry *parent, void *data,
6357+ enum d_walk_ret (*enter)(void *, struct dentry *),
6358+ void (*finish)(void *));
6359+
6360+struct ac_dpages_arg {
1facf9fc 6361+ int err;
c1595e42
JR
6362+ struct au_dcsub_pages *dpages;
6363+ struct super_block *sb;
6364+ au_dpages_test test;
6365+ void *arg;
6366+};
1facf9fc 6367+
c1595e42
JR
6368+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
6369+{
6370+ enum d_walk_ret ret;
6371+ struct ac_dpages_arg *arg = _arg;
1facf9fc 6372+
c1595e42
JR
6373+ ret = D_WALK_CONTINUE;
6374+ if (dentry->d_sb == arg->sb
6375+ && !IS_ROOT(dentry)
6376+ && au_dcount(dentry) > 0
6377+ && au_di(dentry)
6378+ && (!arg->test || arg->test(dentry, arg->arg))) {
6379+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
6380+ if (unlikely(arg->err))
6381+ ret = D_WALK_QUIT;
1facf9fc 6382+ }
6383+
c1595e42
JR
6384+ return ret;
6385+}
027c5e7a 6386+
c1595e42
JR
6387+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6388+ au_dpages_test test, void *arg)
6389+{
6390+ struct ac_dpages_arg args = {
6391+ .err = 0,
6392+ .dpages = dpages,
6393+ .sb = root->d_sb,
6394+ .test = test,
6395+ .arg = arg
6396+ };
027c5e7a 6397+
c1595e42
JR
6398+ d_walk(root, &args, au_call_dpages_append, NULL);
6399+
6400+ return args.err;
1facf9fc 6401+}
6402+
6403+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6404+ int do_include, au_dpages_test test, void *arg)
6405+{
6406+ int err;
6407+
6408+ err = 0;
027c5e7a
AM
6409+ write_seqlock(&rename_lock);
6410+ spin_lock(&dentry->d_lock);
6411+ if (do_include
c1595e42 6412+ && au_dcount(dentry) > 0
027c5e7a 6413+ && (!test || test(dentry, arg)))
1facf9fc 6414+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6415+ spin_unlock(&dentry->d_lock);
6416+ if (unlikely(err))
6417+ goto out;
6418+
6419+ /*
523b37e3 6420+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
6421+ * mount
6422+ */
1facf9fc 6423+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
6424+ dentry = dentry->d_parent; /* rename_lock is locked */
6425+ spin_lock(&dentry->d_lock);
c1595e42 6426+ if (au_dcount(dentry) > 0
027c5e7a 6427+ && (!test || test(dentry, arg)))
1facf9fc 6428+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6429+ spin_unlock(&dentry->d_lock);
6430+ if (unlikely(err))
6431+ break;
1facf9fc 6432+ }
6433+
4f0767ce 6434+out:
027c5e7a 6435+ write_sequnlock(&rename_lock);
1facf9fc 6436+ return err;
6437+}
6438+
027c5e7a
AM
6439+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
6440+{
6441+ return au_di(dentry) && dentry->d_sb == arg;
6442+}
6443+
6444+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6445+ struct dentry *dentry, int do_include)
6446+{
6447+ return au_dcsub_pages_rev(dpages, dentry, do_include,
6448+ au_dcsub_dpages_aufs, dentry->d_sb);
6449+}
6450+
4a4d8108 6451+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 6452+{
4a4d8108
AM
6453+ struct path path[2] = {
6454+ {
6455+ .dentry = d1
6456+ },
6457+ {
6458+ .dentry = d2
6459+ }
6460+ };
1facf9fc 6461+
4a4d8108 6462+ return path_is_under(path + 0, path + 1);
1facf9fc 6463+}
7f207e10
AM
6464diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
6465--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
6466+++ linux/fs/aufs/dcsub.h 2015-04-13 15:10:20.780156788 +0200
6467@@ -0,0 +1,132 @@
1facf9fc 6468+/*
2000de60 6469+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6470+ *
6471+ * This program, aufs is free software; you can redistribute it and/or modify
6472+ * it under the terms of the GNU General Public License as published by
6473+ * the Free Software Foundation; either version 2 of the License, or
6474+ * (at your option) any later version.
dece6358
AM
6475+ *
6476+ * This program is distributed in the hope that it will be useful,
6477+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6478+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6479+ * GNU General Public License for more details.
6480+ *
6481+ * You should have received a copy of the GNU General Public License
523b37e3 6482+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6483+ */
6484+
6485+/*
6486+ * sub-routines for dentry cache
6487+ */
6488+
6489+#ifndef __AUFS_DCSUB_H__
6490+#define __AUFS_DCSUB_H__
6491+
6492+#ifdef __KERNEL__
6493+
7f207e10 6494+#include <linux/dcache.h>
027c5e7a 6495+#include <linux/fs.h>
dece6358 6496+
1facf9fc 6497+struct au_dpage {
6498+ int ndentry;
6499+ struct dentry **dentries;
6500+};
6501+
6502+struct au_dcsub_pages {
6503+ int ndpage;
6504+ struct au_dpage *dpages;
6505+};
6506+
6507+/* ---------------------------------------------------------------------- */
6508+
7f207e10 6509+/* dcsub.c */
1facf9fc 6510+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
6511+void au_dpages_free(struct au_dcsub_pages *dpages);
6512+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
6513+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6514+ au_dpages_test test, void *arg);
6515+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6516+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
6517+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6518+ struct dentry *dentry, int do_include);
4a4d8108 6519+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 6520+
7f207e10
AM
6521+/* ---------------------------------------------------------------------- */
6522+
523b37e3
AM
6523+/*
6524+ * todo: in linux-3.13, several similar (but faster) helpers are added to
6525+ * include/linux/dcache.h. Try them (in the future).
6526+ */
6527+
027c5e7a
AM
6528+static inline int au_d_hashed_positive(struct dentry *d)
6529+{
6530+ int err;
6531+ struct inode *inode = d->d_inode;
076b876e 6532+
027c5e7a
AM
6533+ err = 0;
6534+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
6535+ err = -ENOENT;
6536+ return err;
6537+}
6538+
38d290e6
JR
6539+static inline int au_d_linkable(struct dentry *d)
6540+{
6541+ int err;
6542+ struct inode *inode = d->d_inode;
076b876e 6543+
38d290e6
JR
6544+ err = au_d_hashed_positive(d);
6545+ if (err
6546+ && inode
6547+ && (inode->i_state & I_LINKABLE))
6548+ err = 0;
6549+ return err;
6550+}
6551+
027c5e7a
AM
6552+static inline int au_d_alive(struct dentry *d)
6553+{
6554+ int err;
6555+ struct inode *inode;
076b876e 6556+
027c5e7a
AM
6557+ err = 0;
6558+ if (!IS_ROOT(d))
6559+ err = au_d_hashed_positive(d);
6560+ else {
6561+ inode = d->d_inode;
6562+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
6563+ err = -ENOENT;
6564+ }
6565+ return err;
6566+}
6567+
6568+static inline int au_alive_dir(struct dentry *d)
7f207e10 6569+{
027c5e7a 6570+ int err;
076b876e 6571+
027c5e7a
AM
6572+ err = au_d_alive(d);
6573+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
6574+ err = -ENOENT;
6575+ return err;
7f207e10
AM
6576+}
6577+
38d290e6
JR
6578+static inline int au_qstreq(struct qstr *a, struct qstr *b)
6579+{
6580+ return a->len == b->len
6581+ && !memcmp(a->name, b->name, a->len);
6582+}
6583+
7e9cd9fe
AM
6584+/*
6585+ * by the commit
6586+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without
6587+ * taking d_lock
6588+ * the type of d_lockref.count became int, but the inlined function d_count()
6589+ * still returns unsigned int.
6590+ * I don't know why. Maybe it is for every d_count() users?
6591+ * Anyway au_dcount() lives on.
6592+ */
c1595e42
JR
6593+static inline int au_dcount(struct dentry *d)
6594+{
6595+ return (int)d_count(d);
6596+}
6597+
1facf9fc 6598+#endif /* __KERNEL__ */
6599+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
6600diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
6601--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
6602+++ linux/fs/aufs/debug.c 2015-04-13 15:10:20.780156788 +0200
6603@@ -0,0 +1,438 @@
1facf9fc 6604+/*
2000de60 6605+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6606+ *
6607+ * This program, aufs is free software; you can redistribute it and/or modify
6608+ * it under the terms of the GNU General Public License as published by
6609+ * the Free Software Foundation; either version 2 of the License, or
6610+ * (at your option) any later version.
dece6358
AM
6611+ *
6612+ * This program is distributed in the hope that it will be useful,
6613+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6614+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6615+ * GNU General Public License for more details.
6616+ *
6617+ * You should have received a copy of the GNU General Public License
523b37e3 6618+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6619+ */
6620+
6621+/*
6622+ * debug print functions
6623+ */
6624+
6625+#include "aufs.h"
6626+
392086de
AM
6627+/* Returns 0, or -errno. arg is in kp->arg. */
6628+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
6629+{
6630+ int err, n;
6631+
6632+ err = kstrtoint(val, 0, &n);
6633+ if (!err) {
6634+ if (n > 0)
6635+ au_debug_on();
6636+ else
6637+ au_debug_off();
6638+ }
6639+ return err;
6640+}
6641+
6642+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
6643+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
6644+{
6645+ atomic_t *a;
6646+
6647+ a = kp->arg;
6648+ return sprintf(buffer, "%d", atomic_read(a));
6649+}
6650+
6651+static struct kernel_param_ops param_ops_atomic_t = {
6652+ .set = param_atomic_t_set,
6653+ .get = param_atomic_t_get
6654+ /* void (*free)(void *arg) */
6655+};
6656+
6657+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 6658+MODULE_PARM_DESC(debug, "debug print");
392086de 6659+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 6660+
c1595e42 6661+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
1facf9fc 6662+char *au_plevel = KERN_DEBUG;
e49829fe
JR
6663+#define dpri(fmt, ...) do { \
6664+ if ((au_plevel \
6665+ && strcmp(au_plevel, KERN_DEBUG)) \
6666+ || au_debug_test()) \
6667+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 6668+} while (0)
6669+
6670+/* ---------------------------------------------------------------------- */
6671+
6672+void au_dpri_whlist(struct au_nhash *whlist)
6673+{
6674+ unsigned long ul, n;
6675+ struct hlist_head *head;
c06a8ce3 6676+ struct au_vdir_wh *pos;
1facf9fc 6677+
6678+ n = whlist->nh_num;
6679+ head = whlist->nh_head;
6680+ for (ul = 0; ul < n; ul++) {
c06a8ce3 6681+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 6682+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
6683+ pos->wh_bindex,
6684+ pos->wh_str.len, pos->wh_str.name,
6685+ pos->wh_str.len);
1facf9fc 6686+ head++;
6687+ }
6688+}
6689+
6690+void au_dpri_vdir(struct au_vdir *vdir)
6691+{
6692+ unsigned long ul;
6693+ union au_vdir_deblk_p p;
6694+ unsigned char *o;
6695+
6696+ if (!vdir || IS_ERR(vdir)) {
6697+ dpri("err %ld\n", PTR_ERR(vdir));
6698+ return;
6699+ }
6700+
6701+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
6702+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
6703+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
6704+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
6705+ p.deblk = vdir->vd_deblk[ul];
6706+ o = p.deblk;
6707+ dpri("[%lu]: %p\n", ul, o);
6708+ }
6709+}
6710+
53392da6 6711+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 6712+ struct dentry *wh)
6713+{
6714+ char *n = NULL;
6715+ int l = 0;
6716+
6717+ if (!inode || IS_ERR(inode)) {
6718+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
6719+ return -1;
6720+ }
6721+
c2b27bf2 6722+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 6723+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
6724+ && sizeof(inode->i_blocks) != sizeof(u64));
6725+ if (wh) {
6726+ n = (void *)wh->d_name.name;
6727+ l = wh->d_name.len;
6728+ }
6729+
53392da6
AM
6730+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
6731+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
6732+ bindex, inode,
1facf9fc 6733+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
6734+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
6735+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 6736+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 6737+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
6738+ inode->i_state, inode->i_flags, inode->i_version,
6739+ inode->i_generation,
1facf9fc 6740+ l ? ", wh " : "", l, n);
6741+ return 0;
6742+}
6743+
6744+void au_dpri_inode(struct inode *inode)
6745+{
6746+ struct au_iinfo *iinfo;
6747+ aufs_bindex_t bindex;
53392da6 6748+ int err, hn;
1facf9fc 6749+
53392da6 6750+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 6751+ if (err || !au_test_aufs(inode->i_sb))
6752+ return;
6753+
6754+ iinfo = au_ii(inode);
6755+ if (!iinfo)
6756+ return;
6757+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 6758+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 6759+ if (iinfo->ii_bstart < 0)
6760+ return;
53392da6
AM
6761+ hn = 0;
6762+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
6763+ hn = !!au_hn(iinfo->ii_hinode + bindex);
6764+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 6765+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 6766+ }
1facf9fc 6767+}
6768+
2cbb1c4b
JR
6769+void au_dpri_dalias(struct inode *inode)
6770+{
6771+ struct dentry *d;
6772+
6773+ spin_lock(&inode->i_lock);
c1595e42 6774+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
2cbb1c4b
JR
6775+ au_dpri_dentry(d);
6776+ spin_unlock(&inode->i_lock);
6777+}
6778+
1facf9fc 6779+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
6780+{
6781+ struct dentry *wh = NULL;
53392da6 6782+ int hn;
076b876e 6783+ struct au_iinfo *iinfo;
1facf9fc 6784+
6785+ if (!dentry || IS_ERR(dentry)) {
6786+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
6787+ return -1;
6788+ }
6789+ /* do not call dget_parent() here */
027c5e7a 6790+ /* note: access d_xxx without d_lock */
523b37e3
AM
6791+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
6792+ bindex, dentry, dentry,
1facf9fc 6793+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
c1595e42 6794+ au_dcount(dentry), dentry->d_flags,
523b37e3 6795+ d_unhashed(dentry) ? "un" : "");
53392da6 6796+ hn = -1;
1facf9fc 6797+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
076b876e 6798+ iinfo = au_ii(dentry->d_inode);
53392da6
AM
6799+ if (iinfo) {
6800+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 6801+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 6802+ }
1facf9fc 6803+ }
53392da6 6804+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 6805+ return 0;
6806+}
6807+
6808+void au_dpri_dentry(struct dentry *dentry)
6809+{
6810+ struct au_dinfo *dinfo;
6811+ aufs_bindex_t bindex;
6812+ int err;
4a4d8108 6813+ struct au_hdentry *hdp;
1facf9fc 6814+
6815+ err = do_pri_dentry(-1, dentry);
6816+ if (err || !au_test_aufs(dentry->d_sb))
6817+ return;
6818+
6819+ dinfo = au_di(dentry);
6820+ if (!dinfo)
6821+ return;
38d290e6 6822+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
1facf9fc 6823+ dinfo->di_bstart, dinfo->di_bend,
38d290e6
JR
6824+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
6825+ dinfo->di_tmpfile);
1facf9fc 6826+ if (dinfo->di_bstart < 0)
6827+ return;
4a4d8108 6828+ hdp = dinfo->di_hdentry;
1facf9fc 6829+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 6830+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 6831+}
6832+
6833+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
6834+{
6835+ char a[32];
6836+
6837+ if (!file || IS_ERR(file)) {
6838+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
6839+ return -1;
6840+ }
6841+ a[0] = 0;
6842+ if (bindex < 0
2000de60
JR
6843+ && file->f_path.dentry
6844+ && au_test_aufs(file->f_path.dentry->d_sb)
1facf9fc 6845+ && au_fi(file))
e49829fe 6846+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 6847+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 6848+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 6849+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 6850+ file->f_version, file->f_pos, a);
2000de60
JR
6851+ if (file->f_path.dentry)
6852+ do_pri_dentry(bindex, file->f_path.dentry);
1facf9fc 6853+ return 0;
6854+}
6855+
6856+void au_dpri_file(struct file *file)
6857+{
6858+ struct au_finfo *finfo;
4a4d8108
AM
6859+ struct au_fidir *fidir;
6860+ struct au_hfile *hfile;
1facf9fc 6861+ aufs_bindex_t bindex;
6862+ int err;
6863+
6864+ err = do_pri_file(-1, file);
2000de60
JR
6865+ if (err
6866+ || !file->f_path.dentry
6867+ || !au_test_aufs(file->f_path.dentry->d_sb))
1facf9fc 6868+ return;
6869+
6870+ finfo = au_fi(file);
6871+ if (!finfo)
6872+ return;
4a4d8108 6873+ if (finfo->fi_btop < 0)
1facf9fc 6874+ return;
4a4d8108
AM
6875+ fidir = finfo->fi_hdir;
6876+ if (!fidir)
6877+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
6878+ else
e49829fe
JR
6879+ for (bindex = finfo->fi_btop;
6880+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
6881+ bindex++) {
6882+ hfile = fidir->fd_hfile + bindex;
6883+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
6884+ }
1facf9fc 6885+}
6886+
6887+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
6888+{
6889+ struct vfsmount *mnt;
6890+ struct super_block *sb;
6891+
6892+ if (!br || IS_ERR(br))
6893+ goto out;
86dc4139 6894+ mnt = au_br_mnt(br);
1facf9fc 6895+ if (!mnt || IS_ERR(mnt))
6896+ goto out;
6897+ sb = mnt->mnt_sb;
6898+ if (!sb || IS_ERR(sb))
6899+ goto out;
6900+
1e00d052 6901+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 6902+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 6903+ "xino %d\n",
1e00d052
AM
6904+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
6905+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 6906+ sb->s_flags, sb->s_count,
1facf9fc 6907+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
6908+ return 0;
6909+
4f0767ce 6910+out:
1facf9fc 6911+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
6912+ return -1;
6913+}
6914+
6915+void au_dpri_sb(struct super_block *sb)
6916+{
6917+ struct au_sbinfo *sbinfo;
6918+ aufs_bindex_t bindex;
6919+ int err;
6920+ /* to reuduce stack size */
6921+ struct {
6922+ struct vfsmount mnt;
6923+ struct au_branch fake;
6924+ } *a;
6925+
6926+ /* this function can be called from magic sysrq */
6927+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
6928+ if (unlikely(!a)) {
6929+ dpri("no memory\n");
6930+ return;
6931+ }
6932+
6933+ a->mnt.mnt_sb = sb;
6934+ a->fake.br_perm = 0;
86dc4139 6935+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 6936+ a->fake.br_xino.xi_file = NULL;
6937+ atomic_set(&a->fake.br_count, 0);
6938+ smp_mb(); /* atomic_set */
6939+ err = do_pri_br(-1, &a->fake);
6940+ kfree(a);
6941+ dpri("dev 0x%x\n", sb->s_dev);
6942+ if (err || !au_test_aufs(sb))
6943+ return;
6944+
6945+ sbinfo = au_sbi(sb);
6946+ if (!sbinfo)
6947+ return;
6948+ dpri("nw %d, gen %u, kobj %d\n",
6949+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
6950+ atomic_read(&sbinfo->si_kobj.kref.refcount));
6951+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
6952+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
6953+}
6954+
6955+/* ---------------------------------------------------------------------- */
6956+
027c5e7a
AM
6957+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
6958+{
6959+ struct inode *h_inode, *inode = dentry->d_inode;
6960+ struct dentry *h_dentry;
6961+ aufs_bindex_t bindex, bend, bi;
6962+
6963+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
6964+ return;
6965+
6966+ bend = au_dbend(dentry);
6967+ bi = au_ibend(inode);
6968+ if (bi < bend)
6969+ bend = bi;
6970+ bindex = au_dbstart(dentry);
6971+ bi = au_ibstart(inode);
6972+ if (bi > bindex)
6973+ bindex = bi;
6974+
6975+ for (; bindex <= bend; bindex++) {
6976+ h_dentry = au_h_dptr(dentry, bindex);
6977+ if (!h_dentry)
6978+ continue;
6979+ h_inode = au_h_iptr(inode, bindex);
6980+ if (unlikely(h_inode != h_dentry->d_inode)) {
392086de 6981+ au_debug_on();
027c5e7a
AM
6982+ AuDbg("b%d, %s:%d\n", bindex, func, line);
6983+ AuDbgDentry(dentry);
6984+ AuDbgInode(inode);
392086de 6985+ au_debug_off();
027c5e7a
AM
6986+ BUG();
6987+ }
6988+ }
6989+}
6990+
1facf9fc 6991+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
6992+{
6993+ int err, i, j;
6994+ struct au_dcsub_pages dpages;
6995+ struct au_dpage *dpage;
6996+ struct dentry **dentries;
6997+
6998+ err = au_dpages_init(&dpages, GFP_NOFS);
6999+ AuDebugOn(err);
027c5e7a 7000+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 7001+ AuDebugOn(err);
7002+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7003+ dpage = dpages.dpages + i;
7004+ dentries = dpage->dentries;
7005+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 7006+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 7007+ }
7008+ au_dpages_free(&dpages);
7009+}
7010+
1facf9fc 7011+void au_dbg_verify_kthread(void)
7012+{
53392da6 7013+ if (au_wkq_test()) {
1facf9fc 7014+ au_dbg_blocked();
1e00d052
AM
7015+ /*
7016+ * It may be recursive, but udba=notify between two aufs mounts,
7017+ * where a single ro branch is shared, is not a problem.
7018+ */
7019+ /* WARN_ON(1); */
1facf9fc 7020+ }
7021+}
7022+
7023+/* ---------------------------------------------------------------------- */
7024+
1facf9fc 7025+int __init au_debug_init(void)
7026+{
7027+ aufs_bindex_t bindex;
7028+ struct au_vdir_destr destr;
7029+
7030+ bindex = -1;
7031+ AuDebugOn(bindex >= 0);
7032+
7033+ destr.len = -1;
7034+ AuDebugOn(destr.len < NAME_MAX);
7035+
7036+#ifdef CONFIG_4KSTACKS
0c3ec466 7037+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7038+#endif
7039+
1facf9fc 7040+ return 0;
7041+}
7f207e10
AM
7042diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7043--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
7044+++ linux/fs/aufs/debug.h 2015-04-13 15:10:20.780156788 +0200
7045@@ -0,0 +1,228 @@
1facf9fc 7046+/*
2000de60 7047+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 7048+ *
7049+ * This program, aufs is free software; you can redistribute it and/or modify
7050+ * it under the terms of the GNU General Public License as published by
7051+ * the Free Software Foundation; either version 2 of the License, or
7052+ * (at your option) any later version.
dece6358
AM
7053+ *
7054+ * This program is distributed in the hope that it will be useful,
7055+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7056+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7057+ * GNU General Public License for more details.
7058+ *
7059+ * You should have received a copy of the GNU General Public License
523b37e3 7060+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7061+ */
7062+
7063+/*
7064+ * debug print functions
7065+ */
7066+
7067+#ifndef __AUFS_DEBUG_H__
7068+#define __AUFS_DEBUG_H__
7069+
7070+#ifdef __KERNEL__
7071+
392086de 7072+#include <linux/atomic.h>
4a4d8108
AM
7073+#include <linux/module.h>
7074+#include <linux/kallsyms.h>
1facf9fc 7075+#include <linux/sysrq.h>
4a4d8108 7076+
1facf9fc 7077+#ifdef CONFIG_AUFS_DEBUG
7078+#define AuDebugOn(a) BUG_ON(a)
7079+
7080+/* module parameter */
392086de
AM
7081+extern atomic_t aufs_debug;
7082+static inline void au_debug_on(void)
1facf9fc 7083+{
392086de
AM
7084+ atomic_inc(&aufs_debug);
7085+}
7086+static inline void au_debug_off(void)
7087+{
7088+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7089+}
7090+
7091+static inline int au_debug_test(void)
7092+{
392086de 7093+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7094+}
7095+#else
7096+#define AuDebugOn(a) do {} while (0)
392086de
AM
7097+AuStubVoid(au_debug_on, void)
7098+AuStubVoid(au_debug_off, void)
4a4d8108 7099+AuStubInt0(au_debug_test, void)
1facf9fc 7100+#endif /* CONFIG_AUFS_DEBUG */
7101+
392086de
AM
7102+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7103+
1facf9fc 7104+/* ---------------------------------------------------------------------- */
7105+
7106+/* debug print */
7107+
4a4d8108 7108+#define AuDbg(fmt, ...) do { \
1facf9fc 7109+ if (au_debug_test()) \
4a4d8108 7110+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7111+} while (0)
4a4d8108
AM
7112+#define AuLabel(l) AuDbg(#l "\n")
7113+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7114+#define AuWarn1(fmt, ...) do { \
1facf9fc 7115+ static unsigned char _c; \
7116+ if (!_c++) \
0c3ec466 7117+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 7118+} while (0)
7119+
4a4d8108 7120+#define AuErr1(fmt, ...) do { \
1facf9fc 7121+ static unsigned char _c; \
7122+ if (!_c++) \
4a4d8108 7123+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 7124+} while (0)
7125+
4a4d8108 7126+#define AuIOErr1(fmt, ...) do { \
1facf9fc 7127+ static unsigned char _c; \
7128+ if (!_c++) \
4a4d8108 7129+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 7130+} while (0)
7131+
7132+#define AuUnsupportMsg "This operation is not supported." \
7133+ " Please report this application to aufs-users ML."
4a4d8108
AM
7134+#define AuUnsupport(fmt, ...) do { \
7135+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 7136+ dump_stack(); \
7137+} while (0)
7138+
7139+#define AuTraceErr(e) do { \
7140+ if (unlikely((e) < 0)) \
7141+ AuDbg("err %d\n", (int)(e)); \
7142+} while (0)
7143+
7144+#define AuTraceErrPtr(p) do { \
7145+ if (IS_ERR(p)) \
7146+ AuDbg("err %ld\n", PTR_ERR(p)); \
7147+} while (0)
7148+
7149+/* dirty macros for debug print, use with "%.*s" and caution */
7150+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 7151+
7152+/* ---------------------------------------------------------------------- */
7153+
dece6358 7154+struct dentry;
1facf9fc 7155+#ifdef CONFIG_AUFS_DEBUG
c1595e42 7156+extern struct mutex au_dbg_mtx;
1facf9fc 7157+extern char *au_plevel;
7158+struct au_nhash;
7159+void au_dpri_whlist(struct au_nhash *whlist);
7160+struct au_vdir;
7161+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 7162+struct inode;
1facf9fc 7163+void au_dpri_inode(struct inode *inode);
2cbb1c4b 7164+void au_dpri_dalias(struct inode *inode);
1facf9fc 7165+void au_dpri_dentry(struct dentry *dentry);
dece6358 7166+struct file;
1facf9fc 7167+void au_dpri_file(struct file *filp);
dece6358 7168+struct super_block;
1facf9fc 7169+void au_dpri_sb(struct super_block *sb);
7170+
027c5e7a
AM
7171+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
7172+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 7173+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 7174+void au_dbg_verify_kthread(void);
7175+
7176+int __init au_debug_init(void);
7e9cd9fe 7177+
1facf9fc 7178+#define AuDbgWhlist(w) do { \
c1595e42 7179+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7180+ AuDbg(#w "\n"); \
7181+ au_dpri_whlist(w); \
c1595e42 7182+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7183+} while (0)
7184+
7185+#define AuDbgVdir(v) do { \
c1595e42 7186+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7187+ AuDbg(#v "\n"); \
7188+ au_dpri_vdir(v); \
c1595e42 7189+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7190+} while (0)
7191+
7192+#define AuDbgInode(i) do { \
c1595e42 7193+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7194+ AuDbg(#i "\n"); \
7195+ au_dpri_inode(i); \
c1595e42 7196+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7197+} while (0)
7198+
2cbb1c4b 7199+#define AuDbgDAlias(i) do { \
c1595e42 7200+ mutex_lock(&au_dbg_mtx); \
2cbb1c4b
JR
7201+ AuDbg(#i "\n"); \
7202+ au_dpri_dalias(i); \
c1595e42 7203+ mutex_unlock(&au_dbg_mtx); \
2cbb1c4b
JR
7204+} while (0)
7205+
1facf9fc 7206+#define AuDbgDentry(d) do { \
c1595e42 7207+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7208+ AuDbg(#d "\n"); \
7209+ au_dpri_dentry(d); \
c1595e42 7210+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7211+} while (0)
7212+
7213+#define AuDbgFile(f) do { \
c1595e42 7214+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7215+ AuDbg(#f "\n"); \
7216+ au_dpri_file(f); \
c1595e42 7217+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7218+} while (0)
7219+
7220+#define AuDbgSb(sb) do { \
c1595e42 7221+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7222+ AuDbg(#sb "\n"); \
7223+ au_dpri_sb(sb); \
c1595e42 7224+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7225+} while (0)
7226+
4a4d8108
AM
7227+#define AuDbgSym(addr) do { \
7228+ char sym[KSYM_SYMBOL_LEN]; \
7229+ sprint_symbol(sym, (unsigned long)addr); \
7230+ AuDbg("%s\n", sym); \
7231+} while (0)
1facf9fc 7232+#else
027c5e7a 7233+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
7234+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
7235+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
7236+ unsigned int sigen)
7237+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
7238+AuStubVoid(au_dbg_verify_kthread, void)
7239+AuStubInt0(__init au_debug_init, void)
1facf9fc 7240+
1facf9fc 7241+#define AuDbgWhlist(w) do {} while (0)
7242+#define AuDbgVdir(v) do {} while (0)
7243+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 7244+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 7245+#define AuDbgDentry(d) do {} while (0)
7246+#define AuDbgFile(f) do {} while (0)
7247+#define AuDbgSb(sb) do {} while (0)
4a4d8108 7248+#define AuDbgSym(addr) do {} while (0)
1facf9fc 7249+#endif /* CONFIG_AUFS_DEBUG */
7250+
7251+/* ---------------------------------------------------------------------- */
7252+
7253+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
7254+int __init au_sysrq_init(void);
7255+void au_sysrq_fin(void);
7256+
7257+#ifdef CONFIG_HW_CONSOLE
7258+#define au_dbg_blocked() do { \
7259+ WARN_ON(1); \
0c5527e5 7260+ handle_sysrq('w'); \
1facf9fc 7261+} while (0)
7262+#else
4a4d8108 7263+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7264+#endif
7265+
7266+#else
4a4d8108
AM
7267+AuStubInt0(__init au_sysrq_init, void)
7268+AuStubVoid(au_sysrq_fin, void)
7269+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7270+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
7271+
7272+#endif /* __KERNEL__ */
7273+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
7274diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
7275--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 7276+++ linux/fs/aufs/dentry.c 2015-04-13 15:10:20.780156788 +0200
2000de60 7277@@ -0,0 +1,1097 @@
1facf9fc 7278+/*
2000de60 7279+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 7280+ *
7281+ * This program, aufs is free software; you can redistribute it and/or modify
7282+ * it under the terms of the GNU General Public License as published by
7283+ * the Free Software Foundation; either version 2 of the License, or
7284+ * (at your option) any later version.
dece6358
AM
7285+ *
7286+ * This program is distributed in the hope that it will be useful,
7287+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7288+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7289+ * GNU General Public License for more details.
7290+ *
7291+ * You should have received a copy of the GNU General Public License
523b37e3 7292+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7293+ */
7294+
7295+/*
7296+ * lookup and dentry operations
7297+ */
7298+
dece6358 7299+#include <linux/namei.h>
1facf9fc 7300+#include "aufs.h"
7301+
1facf9fc 7302+#define AuLkup_ALLOW_NEG 1
076b876e 7303+#define AuLkup_IGNORE_PERM (1 << 1)
1facf9fc 7304+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
7305+#define au_fset_lkup(flags, name) \
7306+ do { (flags) |= AuLkup_##name; } while (0)
7307+#define au_fclr_lkup(flags, name) \
7308+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 7309+
7310+struct au_do_lookup_args {
7311+ unsigned int flags;
7312+ mode_t type;
1facf9fc 7313+};
7314+
7315+/*
7316+ * returns positive/negative dentry, NULL or an error.
7317+ * NULL means whiteout-ed or not-found.
7318+ */
7319+static struct dentry*
7320+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
7321+ aufs_bindex_t bindex, struct qstr *wh_name,
7322+ struct au_do_lookup_args *args)
7323+{
7324+ struct dentry *h_dentry;
2000de60 7325+ struct inode *h_inode;
1facf9fc 7326+ struct au_branch *br;
7327+ int wh_found, opq;
7328+ unsigned char wh_able;
7329+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
7330+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
7331+ IGNORE_PERM);
1facf9fc 7332+
1facf9fc 7333+ wh_found = 0;
7334+ br = au_sbr(dentry->d_sb, bindex);
7335+ wh_able = !!au_br_whable(br->br_perm);
7336+ if (wh_able)
076b876e 7337+ wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0);
1facf9fc 7338+ h_dentry = ERR_PTR(wh_found);
7339+ if (!wh_found)
7340+ goto real_lookup;
7341+ if (unlikely(wh_found < 0))
7342+ goto out;
7343+
7344+ /* We found a whiteout */
7345+ /* au_set_dbend(dentry, bindex); */
7346+ au_set_dbwh(dentry, bindex);
7347+ if (!allow_neg)
7348+ return NULL; /* success */
7349+
4f0767ce 7350+real_lookup:
076b876e
AM
7351+ if (!ignore_perm)
7352+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
7353+ else
7354+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
2000de60
JR
7355+ if (IS_ERR(h_dentry)) {
7356+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
7357+ && !allow_neg)
7358+ h_dentry = NULL;
1facf9fc 7359+ goto out;
2000de60 7360+ }
1facf9fc 7361+
7362+ h_inode = h_dentry->d_inode;
7363+ if (!h_inode) {
7364+ if (!allow_neg)
7365+ goto out_neg;
7366+ } else if (wh_found
7367+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
7368+ goto out_neg;
7369+
7370+ if (au_dbend(dentry) <= bindex)
7371+ au_set_dbend(dentry, bindex);
7372+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7373+ au_set_dbstart(dentry, bindex);
7374+ au_set_h_dptr(dentry, bindex, h_dentry);
7375+
2000de60
JR
7376+ if (!d_is_dir(h_dentry)
7377+ || !wh_able
7378+ || (d_is_positive(dentry) && !d_is_dir(dentry)))
1facf9fc 7379+ goto out; /* success */
7380+
7381+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
076b876e 7382+ opq = au_diropq_test(h_dentry);
1facf9fc 7383+ mutex_unlock(&h_inode->i_mutex);
7384+ if (opq > 0)
7385+ au_set_dbdiropq(dentry, bindex);
7386+ else if (unlikely(opq < 0)) {
7387+ au_set_h_dptr(dentry, bindex, NULL);
7388+ h_dentry = ERR_PTR(opq);
7389+ }
7390+ goto out;
7391+
4f0767ce 7392+out_neg:
1facf9fc 7393+ dput(h_dentry);
7394+ h_dentry = NULL;
4f0767ce 7395+out:
1facf9fc 7396+ return h_dentry;
7397+}
7398+
dece6358
AM
7399+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
7400+{
7401+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
7402+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
7403+ return -EPERM;
7404+ return 0;
7405+}
7406+
1facf9fc 7407+/*
7408+ * returns the number of lower positive dentries,
7409+ * otherwise an error.
7410+ * can be called at unlinking with @type is zero.
7411+ */
537831f9 7412+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 7413+{
7414+ int npositive, err;
7415+ aufs_bindex_t bindex, btail, bdiropq;
076b876e 7416+ unsigned char isdir, dirperm1;
1facf9fc 7417+ struct qstr whname;
7418+ struct au_do_lookup_args args = {
b4510431 7419+ .flags = 0,
537831f9 7420+ .type = type
1facf9fc 7421+ };
7422+ const struct qstr *name = &dentry->d_name;
7423+ struct dentry *parent;
7424+ struct inode *inode;
076b876e 7425+ struct super_block *sb;
1facf9fc 7426+
076b876e
AM
7427+ sb = dentry->d_sb;
7428+ err = au_test_shwh(sb, name);
dece6358 7429+ if (unlikely(err))
1facf9fc 7430+ goto out;
7431+
7432+ err = au_wh_name_alloc(&whname, name);
7433+ if (unlikely(err))
7434+ goto out;
7435+
7436+ inode = dentry->d_inode;
2000de60 7437+ isdir = !!d_is_dir(dentry);
1facf9fc 7438+ if (!type)
7439+ au_fset_lkup(args.flags, ALLOW_NEG);
076b876e 7440+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
1facf9fc 7441+
7442+ npositive = 0;
4a4d8108 7443+ parent = dget_parent(dentry);
1facf9fc 7444+ btail = au_dbtaildir(parent);
7445+ for (bindex = bstart; bindex <= btail; bindex++) {
7446+ struct dentry *h_parent, *h_dentry;
7447+ struct inode *h_inode, *h_dir;
7448+
7449+ h_dentry = au_h_dptr(dentry, bindex);
7450+ if (h_dentry) {
7451+ if (h_dentry->d_inode)
7452+ npositive++;
7453+ if (type != S_IFDIR)
7454+ break;
7455+ continue;
7456+ }
7457+ h_parent = au_h_dptr(parent, bindex);
2000de60 7458+ if (!h_parent || !d_is_dir(h_parent))
1facf9fc 7459+ continue;
7460+
2000de60 7461+ h_dir = h_parent->d_inode;
1facf9fc 7462+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
7463+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
7464+ &args);
7465+ mutex_unlock(&h_dir->i_mutex);
7466+ err = PTR_ERR(h_dentry);
7467+ if (IS_ERR(h_dentry))
4a4d8108 7468+ goto out_parent;
2000de60
JR
7469+ if (h_dentry)
7470+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
7471+ if (dirperm1)
7472+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 7473+
7474+ if (au_dbwh(dentry) >= 0)
7475+ break;
7476+ if (!h_dentry)
7477+ continue;
7478+ h_inode = h_dentry->d_inode;
7479+ if (!h_inode)
7480+ continue;
7481+ npositive++;
7482+ if (!args.type)
7483+ args.type = h_inode->i_mode & S_IFMT;
7484+ if (args.type != S_IFDIR)
7485+ break;
7486+ else if (isdir) {
7487+ /* the type of lower may be different */
7488+ bdiropq = au_dbdiropq(dentry);
7489+ if (bdiropq >= 0 && bdiropq <= bindex)
7490+ break;
7491+ }
7492+ }
7493+
7494+ if (npositive) {
7495+ AuLabel(positive);
7496+ au_update_dbstart(dentry);
7497+ }
7498+ err = npositive;
076b876e 7499+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
027c5e7a 7500+ && au_dbstart(dentry) < 0)) {
1facf9fc 7501+ err = -EIO;
523b37e3
AM
7502+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
7503+ dentry, err);
027c5e7a 7504+ }
1facf9fc 7505+
4f0767ce 7506+out_parent:
4a4d8108 7507+ dput(parent);
1facf9fc 7508+ kfree(whname.name);
4f0767ce 7509+out:
1facf9fc 7510+ return err;
7511+}
7512+
076b876e 7513+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 7514+{
7515+ struct dentry *dentry;
7516+ int wkq_err;
7517+
7518+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
b4510431 7519+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 7520+ else {
b4510431
AM
7521+ struct vfsub_lkup_one_args args = {
7522+ .errp = &dentry,
7523+ .name = name,
7524+ .parent = parent
1facf9fc 7525+ };
7526+
b4510431 7527+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 7528+ if (unlikely(wkq_err))
7529+ dentry = ERR_PTR(wkq_err);
7530+ }
7531+
7532+ return dentry;
7533+}
7534+
7535+/*
7536+ * lookup @dentry on @bindex which should be negative.
7537+ */
86dc4139 7538+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 7539+{
7540+ int err;
7541+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 7542+ struct au_branch *br;
1facf9fc 7543+
1facf9fc 7544+ parent = dget_parent(dentry);
7545+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
7546+ br = au_sbr(dentry->d_sb, bindex);
7547+ if (wh)
7548+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
7549+ else
076b876e 7550+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 7551+ err = PTR_ERR(h_dentry);
7552+ if (IS_ERR(h_dentry))
7553+ goto out;
7554+ if (unlikely(h_dentry->d_inode)) {
7555+ err = -EIO;
523b37e3 7556+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 7557+ dput(h_dentry);
7558+ goto out;
7559+ }
7560+
4a4d8108 7561+ err = 0;
1facf9fc 7562+ if (bindex < au_dbstart(dentry))
7563+ au_set_dbstart(dentry, bindex);
7564+ if (au_dbend(dentry) < bindex)
7565+ au_set_dbend(dentry, bindex);
7566+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 7567+
4f0767ce 7568+out:
1facf9fc 7569+ dput(parent);
7570+ return err;
7571+}
7572+
7573+/* ---------------------------------------------------------------------- */
7574+
7575+/* subset of struct inode */
7576+struct au_iattr {
7577+ unsigned long i_ino;
7578+ /* unsigned int i_nlink; */
0c3ec466
AM
7579+ kuid_t i_uid;
7580+ kgid_t i_gid;
1facf9fc 7581+ u64 i_version;
7582+/*
7583+ loff_t i_size;
7584+ blkcnt_t i_blocks;
7585+*/
7586+ umode_t i_mode;
7587+};
7588+
7589+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
7590+{
7591+ ia->i_ino = h_inode->i_ino;
7592+ /* ia->i_nlink = h_inode->i_nlink; */
7593+ ia->i_uid = h_inode->i_uid;
7594+ ia->i_gid = h_inode->i_gid;
7595+ ia->i_version = h_inode->i_version;
7596+/*
7597+ ia->i_size = h_inode->i_size;
7598+ ia->i_blocks = h_inode->i_blocks;
7599+*/
7600+ ia->i_mode = (h_inode->i_mode & S_IFMT);
7601+}
7602+
7603+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
7604+{
7605+ return ia->i_ino != h_inode->i_ino
7606+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 7607+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 7608+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 7609+ || ia->i_version != h_inode->i_version
7610+/*
7611+ || ia->i_size != h_inode->i_size
7612+ || ia->i_blocks != h_inode->i_blocks
7613+*/
7614+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
7615+}
7616+
7617+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
7618+ struct au_branch *br)
7619+{
7620+ int err;
7621+ struct au_iattr ia;
7622+ struct inode *h_inode;
7623+ struct dentry *h_d;
7624+ struct super_block *h_sb;
7625+
7626+ err = 0;
7627+ memset(&ia, -1, sizeof(ia));
7628+ h_sb = h_dentry->d_sb;
7629+ h_inode = h_dentry->d_inode;
7630+ if (h_inode)
7631+ au_iattr_save(&ia, h_inode);
7632+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
7633+ /* nfs d_revalidate may return 0 for negative dentry */
7634+ /* fuse d_revalidate always return 0 for negative dentry */
7635+ goto out;
7636+
7637+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 7638+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 7639+ err = PTR_ERR(h_d);
7640+ if (IS_ERR(h_d))
7641+ goto out;
7642+
7643+ err = 0;
7644+ if (unlikely(h_d != h_dentry
7645+ || h_d->d_inode != h_inode
7646+ || (h_inode && au_iattr_test(&ia, h_inode))))
7647+ err = au_busy_or_stale();
7648+ dput(h_d);
7649+
4f0767ce 7650+out:
1facf9fc 7651+ AuTraceErr(err);
7652+ return err;
7653+}
7654+
7655+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7656+ struct dentry *h_parent, struct au_branch *br)
7657+{
7658+ int err;
7659+
7660+ err = 0;
027c5e7a
AM
7661+ if (udba == AuOpt_UDBA_REVAL
7662+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 7663+ IMustLock(h_dir);
7664+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 7665+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 7666+ err = au_h_verify_dentry(h_dentry, h_parent, br);
7667+
7668+ return err;
7669+}
7670+
7671+/* ---------------------------------------------------------------------- */
7672+
027c5e7a 7673+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 7674+{
027c5e7a 7675+ int err;
1facf9fc 7676+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
7677+ struct au_hdentry tmp, *p, *q;
7678+ struct au_dinfo *dinfo;
7679+ struct super_block *sb;
1facf9fc 7680+
027c5e7a 7681+ DiMustWriteLock(dentry);
1308ab2a 7682+
027c5e7a
AM
7683+ sb = dentry->d_sb;
7684+ dinfo = au_di(dentry);
1facf9fc 7685+ bend = dinfo->di_bend;
7686+ bwh = dinfo->di_bwh;
7687+ bdiropq = dinfo->di_bdiropq;
027c5e7a 7688+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 7689+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 7690+ if (!p->hd_dentry)
1facf9fc 7691+ continue;
7692+
027c5e7a
AM
7693+ new_bindex = au_br_index(sb, p->hd_id);
7694+ if (new_bindex == bindex)
1facf9fc 7695+ continue;
1facf9fc 7696+
1facf9fc 7697+ if (dinfo->di_bwh == bindex)
7698+ bwh = new_bindex;
7699+ if (dinfo->di_bdiropq == bindex)
7700+ bdiropq = new_bindex;
7701+ if (new_bindex < 0) {
7702+ au_hdput(p);
7703+ p->hd_dentry = NULL;
7704+ continue;
7705+ }
7706+
7707+ /* swap two lower dentries, and loop again */
7708+ q = dinfo->di_hdentry + new_bindex;
7709+ tmp = *q;
7710+ *q = *p;
7711+ *p = tmp;
7712+ if (tmp.hd_dentry) {
7713+ bindex--;
7714+ p--;
7715+ }
7716+ }
7717+
1facf9fc 7718+ dinfo->di_bwh = -1;
7719+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
7720+ dinfo->di_bwh = bwh;
7721+
7722+ dinfo->di_bdiropq = -1;
7723+ if (bdiropq >= 0
7724+ && bdiropq <= au_sbend(sb)
7725+ && au_sbr_whable(sb, bdiropq))
7726+ dinfo->di_bdiropq = bdiropq;
7727+
027c5e7a
AM
7728+ err = -EIO;
7729+ dinfo->di_bstart = -1;
7730+ dinfo->di_bend = -1;
1facf9fc 7731+ bend = au_dbend(parent);
7732+ p = dinfo->di_hdentry;
7733+ for (bindex = 0; bindex <= bend; bindex++, p++)
7734+ if (p->hd_dentry) {
7735+ dinfo->di_bstart = bindex;
7736+ break;
7737+ }
7738+
027c5e7a
AM
7739+ if (dinfo->di_bstart >= 0) {
7740+ p = dinfo->di_hdentry + bend;
7741+ for (bindex = bend; bindex >= 0; bindex--, p--)
7742+ if (p->hd_dentry) {
7743+ dinfo->di_bend = bindex;
7744+ err = 0;
7745+ break;
7746+ }
7747+ }
7748+
7749+ return err;
1facf9fc 7750+}
7751+
027c5e7a 7752+static void au_do_hide(struct dentry *dentry)
1facf9fc 7753+{
027c5e7a 7754+ struct inode *inode;
1facf9fc 7755+
027c5e7a
AM
7756+ inode = dentry->d_inode;
7757+ if (inode) {
7758+ if (!S_ISDIR(inode->i_mode)) {
7759+ if (inode->i_nlink && !d_unhashed(dentry))
7760+ drop_nlink(inode);
7761+ } else {
7762+ clear_nlink(inode);
7763+ /* stop next lookup */
7764+ inode->i_flags |= S_DEAD;
7765+ }
7766+ smp_mb(); /* necessary? */
7767+ }
7768+ d_drop(dentry);
7769+}
1308ab2a 7770+
027c5e7a
AM
7771+static int au_hide_children(struct dentry *parent)
7772+{
7773+ int err, i, j, ndentry;
7774+ struct au_dcsub_pages dpages;
7775+ struct au_dpage *dpage;
7776+ struct dentry *dentry;
1facf9fc 7777+
027c5e7a 7778+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 7779+ if (unlikely(err))
7780+ goto out;
027c5e7a
AM
7781+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
7782+ if (unlikely(err))
7783+ goto out_dpages;
1facf9fc 7784+
027c5e7a
AM
7785+ /* in reverse order */
7786+ for (i = dpages.ndpage - 1; i >= 0; i--) {
7787+ dpage = dpages.dpages + i;
7788+ ndentry = dpage->ndentry;
7789+ for (j = ndentry - 1; j >= 0; j--) {
7790+ dentry = dpage->dentries[j];
7791+ if (dentry != parent)
7792+ au_do_hide(dentry);
7793+ }
7794+ }
1facf9fc 7795+
027c5e7a
AM
7796+out_dpages:
7797+ au_dpages_free(&dpages);
4f0767ce 7798+out:
027c5e7a 7799+ return err;
1facf9fc 7800+}
7801+
027c5e7a 7802+static void au_hide(struct dentry *dentry)
1facf9fc 7803+{
027c5e7a 7804+ int err;
1facf9fc 7805+
027c5e7a 7806+ AuDbgDentry(dentry);
2000de60 7807+ if (d_is_dir(dentry)) {
027c5e7a
AM
7808+ /* shrink_dcache_parent(dentry); */
7809+ err = au_hide_children(dentry);
7810+ if (unlikely(err))
523b37e3
AM
7811+ AuIOErr("%pd, failed hiding children, ignored %d\n",
7812+ dentry, err);
027c5e7a
AM
7813+ }
7814+ au_do_hide(dentry);
7815+}
1facf9fc 7816+
027c5e7a
AM
7817+/*
7818+ * By adding a dirty branch, a cached dentry may be affected in various ways.
7819+ *
7820+ * a dirty branch is added
7821+ * - on the top of layers
7822+ * - in the middle of layers
7823+ * - to the bottom of layers
7824+ *
7825+ * on the added branch there exists
7826+ * - a whiteout
7827+ * - a diropq
7828+ * - a same named entry
7829+ * + exist
7830+ * * negative --> positive
7831+ * * positive --> positive
7832+ * - type is unchanged
7833+ * - type is changed
7834+ * + doesn't exist
7835+ * * negative --> negative
7836+ * * positive --> negative (rejected by au_br_del() for non-dir case)
7837+ * - none
7838+ */
7839+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
7840+ struct au_dinfo *tmp)
7841+{
7842+ int err;
7843+ aufs_bindex_t bindex, bend;
7844+ struct {
7845+ struct dentry *dentry;
7846+ struct inode *inode;
7847+ mode_t mode;
7848+ } orig_h, tmp_h;
7849+ struct au_hdentry *hd;
7850+ struct inode *inode, *h_inode;
7851+ struct dentry *h_dentry;
7852+
7853+ err = 0;
7854+ AuDebugOn(dinfo->di_bstart < 0);
7855+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
7856+ orig_h.inode = orig_h.dentry->d_inode;
7857+ orig_h.mode = 0;
7858+ if (orig_h.inode)
7859+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
7860+ memset(&tmp_h, 0, sizeof(tmp_h));
7861+ if (tmp->di_bstart >= 0) {
7862+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
7863+ tmp_h.inode = tmp_h.dentry->d_inode;
7864+ if (tmp_h.inode)
7865+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
7866+ }
7867+
7868+ inode = dentry->d_inode;
7869+ if (!orig_h.inode) {
7870+ AuDbg("nagative originally\n");
7871+ if (inode) {
7872+ au_hide(dentry);
7873+ goto out;
7874+ }
7875+ AuDebugOn(inode);
7876+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7877+ AuDebugOn(dinfo->di_bdiropq != -1);
7878+
7879+ if (!tmp_h.inode) {
7880+ AuDbg("negative --> negative\n");
7881+ /* should have only one negative lower */
7882+ if (tmp->di_bstart >= 0
7883+ && tmp->di_bstart < dinfo->di_bstart) {
7884+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
7885+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7886+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
7887+ au_di_cp(dinfo, tmp);
7888+ hd = tmp->di_hdentry + tmp->di_bstart;
7889+ au_set_h_dptr(dentry, tmp->di_bstart,
7890+ dget(hd->hd_dentry));
7891+ }
7892+ au_dbg_verify_dinode(dentry);
7893+ } else {
7894+ AuDbg("negative --> positive\n");
7895+ /*
7896+ * similar to the behaviour of creating with bypassing
7897+ * aufs.
7898+ * unhash it in order to force an error in the
7899+ * succeeding create operation.
7900+ * we should not set S_DEAD here.
7901+ */
7902+ d_drop(dentry);
7903+ /* au_di_swap(tmp, dinfo); */
7904+ au_dbg_verify_dinode(dentry);
7905+ }
7906+ } else {
7907+ AuDbg("positive originally\n");
7908+ /* inode may be NULL */
7909+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
7910+ if (!tmp_h.inode) {
7911+ AuDbg("positive --> negative\n");
7912+ /* or bypassing aufs */
7913+ au_hide(dentry);
7914+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
7915+ dinfo->di_bwh = tmp->di_bwh;
7916+ if (inode)
7917+ err = au_refresh_hinode_self(inode);
7918+ au_dbg_verify_dinode(dentry);
7919+ } else if (orig_h.mode == tmp_h.mode) {
7920+ AuDbg("positive --> positive, same type\n");
7921+ if (!S_ISDIR(orig_h.mode)
7922+ && dinfo->di_bstart > tmp->di_bstart) {
7923+ /*
7924+ * similar to the behaviour of removing and
7925+ * creating.
7926+ */
7927+ au_hide(dentry);
7928+ if (inode)
7929+ err = au_refresh_hinode_self(inode);
7930+ au_dbg_verify_dinode(dentry);
7931+ } else {
7932+ /* fill empty slots */
7933+ if (dinfo->di_bstart > tmp->di_bstart)
7934+ dinfo->di_bstart = tmp->di_bstart;
7935+ if (dinfo->di_bend < tmp->di_bend)
7936+ dinfo->di_bend = tmp->di_bend;
7937+ dinfo->di_bwh = tmp->di_bwh;
7938+ dinfo->di_bdiropq = tmp->di_bdiropq;
7939+ hd = tmp->di_hdentry;
7940+ bend = dinfo->di_bend;
7941+ for (bindex = tmp->di_bstart; bindex <= bend;
7942+ bindex++) {
7943+ if (au_h_dptr(dentry, bindex))
7944+ continue;
7945+ h_dentry = hd[bindex].hd_dentry;
7946+ if (!h_dentry)
7947+ continue;
7948+ h_inode = h_dentry->d_inode;
7949+ AuDebugOn(!h_inode);
7950+ AuDebugOn(orig_h.mode
7951+ != (h_inode->i_mode
7952+ & S_IFMT));
7953+ au_set_h_dptr(dentry, bindex,
7954+ dget(h_dentry));
7955+ }
7956+ err = au_refresh_hinode(inode, dentry);
7957+ au_dbg_verify_dinode(dentry);
7958+ }
7959+ } else {
7960+ AuDbg("positive --> positive, different type\n");
7961+ /* similar to the behaviour of removing and creating */
7962+ au_hide(dentry);
7963+ if (inode)
7964+ err = au_refresh_hinode_self(inode);
7965+ au_dbg_verify_dinode(dentry);
7966+ }
7967+ }
7968+
7969+out:
7970+ return err;
7971+}
7972+
7973+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
7974+{
7975+ int err, ebrange;
7976+ unsigned int sigen;
7977+ struct au_dinfo *dinfo, *tmp;
7978+ struct super_block *sb;
7979+ struct inode *inode;
7980+
7981+ DiMustWriteLock(dentry);
7982+ AuDebugOn(IS_ROOT(dentry));
7983+ AuDebugOn(!parent->d_inode);
7984+
7985+ sb = dentry->d_sb;
7986+ inode = dentry->d_inode;
7987+ sigen = au_sigen(sb);
7988+ err = au_digen_test(parent, sigen);
7989+ if (unlikely(err))
7990+ goto out;
7991+
7992+ dinfo = au_di(dentry);
7993+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
7994+ if (unlikely(err))
7995+ goto out;
7996+ ebrange = au_dbrange_test(dentry);
7997+ if (!ebrange)
7998+ ebrange = au_do_refresh_hdentry(dentry, parent);
7999+
38d290e6 8000+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
027c5e7a
AM
8001+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
8002+ if (inode)
8003+ err = au_refresh_hinode_self(inode);
8004+ au_dbg_verify_dinode(dentry);
8005+ if (!err)
8006+ goto out_dgen; /* success */
8007+ goto out;
8008+ }
8009+
8010+ /* temporary dinfo */
8011+ AuDbgDentry(dentry);
8012+ err = -ENOMEM;
8013+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8014+ if (unlikely(!tmp))
8015+ goto out;
8016+ au_di_swap(tmp, dinfo);
8017+ /* returns the number of positive dentries */
8018+ /*
8019+ * if current working dir is removed, it returns an error.
8020+ * but the dentry is legal.
8021+ */
537831f9 8022+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
8023+ AuDbgDentry(dentry);
8024+ au_di_swap(tmp, dinfo);
8025+ if (err == -ENOENT)
8026+ err = 0;
8027+ if (err >= 0) {
8028+ /* compare/refresh by dinfo */
8029+ AuDbgDentry(dentry);
8030+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8031+ au_dbg_verify_dinode(dentry);
8032+ AuTraceErr(err);
8033+ }
8034+ au_rw_write_unlock(&tmp->di_rwsem);
8035+ au_di_free(tmp);
8036+ if (unlikely(err))
8037+ goto out;
8038+
8039+out_dgen:
8040+ au_update_digen(dentry);
8041+out:
8042+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8043+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8044+ AuDbgDentry(dentry);
8045+ }
8046+ AuTraceErr(err);
8047+ return err;
8048+}
8049+
b4510431
AM
8050+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8051+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8052+{
8053+ int err, valid;
027c5e7a
AM
8054+
8055+ err = 0;
8056+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8057+ goto out;
027c5e7a
AM
8058+
8059+ AuDbg("b%d\n", bindex);
b4510431
AM
8060+ /*
8061+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8062+ * due to whiteout and branch permission.
8063+ */
8064+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8065+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8066+ /* it may return tri-state */
8067+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8068+
8069+ if (unlikely(valid < 0))
8070+ err = valid;
8071+ else if (!valid)
8072+ err = -EINVAL;
8073+
4f0767ce 8074+out:
1facf9fc 8075+ AuTraceErr(err);
8076+ return err;
8077+}
8078+
8079+/* todo: remove this */
8080+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 8081+ unsigned int flags, int do_udba)
1facf9fc 8082+{
8083+ int err;
8084+ umode_t mode, h_mode;
8085+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
38d290e6 8086+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 8087+ struct inode *h_inode, *h_cached_inode;
1facf9fc 8088+ struct dentry *h_dentry;
8089+ struct qstr *name, *h_name;
8090+
8091+ err = 0;
8092+ plus = 0;
8093+ mode = 0;
1facf9fc 8094+ ibs = -1;
8095+ ibe = -1;
8096+ unhashed = !!d_unhashed(dentry);
8097+ is_root = !!IS_ROOT(dentry);
8098+ name = &dentry->d_name;
38d290e6 8099+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 8100+
8101+ /*
7f207e10
AM
8102+ * Theoretically, REVAL test should be unnecessary in case of
8103+ * {FS,I}NOTIFY.
8104+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 8105+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 8106+ * Let's do REVAL test too.
8107+ */
8108+ if (do_udba && inode) {
8109+ mode = (inode->i_mode & S_IFMT);
8110+ plus = (inode->i_nlink > 0);
1facf9fc 8111+ ibs = au_ibstart(inode);
8112+ ibe = au_ibend(inode);
8113+ }
8114+
8115+ bstart = au_dbstart(dentry);
8116+ btail = bstart;
8117+ if (inode && S_ISDIR(inode->i_mode))
8118+ btail = au_dbtaildir(dentry);
8119+ for (bindex = bstart; bindex <= btail; bindex++) {
8120+ h_dentry = au_h_dptr(dentry, bindex);
8121+ if (!h_dentry)
8122+ continue;
8123+
523b37e3
AM
8124+ AuDbg("b%d, %pd\n", bindex, h_dentry);
8125+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 8126+ spin_lock(&h_dentry->d_lock);
1facf9fc 8127+ h_name = &h_dentry->d_name;
8128+ if (unlikely(do_udba
8129+ && !is_root
523b37e3
AM
8130+ && ((!h_nfs
8131+ && (unhashed != !!d_unhashed(h_dentry)
38d290e6
JR
8132+ || (!tmpfile
8133+ && !au_qstreq(name, h_name))
8134+ ))
523b37e3
AM
8135+ || (h_nfs
8136+ && !(flags & LOOKUP_OPEN)
8137+ && (h_dentry->d_flags
8138+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 8139+ )) {
38d290e6
JR
8140+ int h_unhashed;
8141+
8142+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 8143+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
8144+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
8145+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 8146+ goto err;
8147+ }
027c5e7a 8148+ spin_unlock(&h_dentry->d_lock);
1facf9fc 8149+
b4510431 8150+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 8151+ if (unlikely(err))
8152+ /* do not goto err, to keep the errno */
8153+ break;
8154+
8155+ /* todo: plink too? */
8156+ if (!do_udba)
8157+ continue;
8158+
8159+ /* UDBA tests */
8160+ h_inode = h_dentry->d_inode;
8161+ if (unlikely(!!inode != !!h_inode))
8162+ goto err;
8163+
8164+ h_plus = plus;
8165+ h_mode = mode;
8166+ h_cached_inode = h_inode;
8167+ if (h_inode) {
8168+ h_mode = (h_inode->i_mode & S_IFMT);
8169+ h_plus = (h_inode->i_nlink > 0);
8170+ }
8171+ if (inode && ibs <= bindex && bindex <= ibe)
8172+ h_cached_inode = au_h_iptr(inode, bindex);
8173+
523b37e3 8174+ if (!h_nfs) {
38d290e6 8175+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
8176+ goto err;
8177+ } else {
8178+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
8179+ && !is_root
8180+ && !IS_ROOT(h_dentry)
8181+ && unhashed != d_unhashed(h_dentry)))
8182+ goto err;
8183+ }
8184+ if (unlikely(mode != h_mode
1facf9fc 8185+ || h_cached_inode != h_inode))
8186+ goto err;
8187+ continue;
8188+
f6b6e03d 8189+err:
1facf9fc 8190+ err = -EINVAL;
8191+ break;
8192+ }
8193+
523b37e3 8194+ AuTraceErr(err);
1facf9fc 8195+ return err;
8196+}
8197+
027c5e7a 8198+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 8199+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
8200+{
8201+ int err;
8202+ struct dentry *parent;
1facf9fc 8203+
027c5e7a 8204+ if (!au_digen_test(dentry, sigen))
1facf9fc 8205+ return 0;
8206+
8207+ parent = dget_parent(dentry);
8208+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8209+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 8210+ au_dbg_verify_gen(parent, sigen);
027c5e7a 8211+ err = au_refresh_dentry(dentry, parent);
1facf9fc 8212+ di_read_unlock(parent, AuLock_IR);
8213+ dput(parent);
027c5e7a 8214+ AuTraceErr(err);
1facf9fc 8215+ return err;
8216+}
8217+
8218+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
8219+{
8220+ int err;
8221+ struct dentry *d, *parent;
8222+ struct inode *inode;
8223+
027c5e7a 8224+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 8225+ return simple_reval_dpath(dentry, sigen);
8226+
8227+ /* slow loop, keep it simple and stupid */
8228+ /* cf: au_cpup_dirs() */
8229+ err = 0;
8230+ parent = NULL;
027c5e7a 8231+ while (au_digen_test(dentry, sigen)) {
1facf9fc 8232+ d = dentry;
8233+ while (1) {
8234+ dput(parent);
8235+ parent = dget_parent(d);
027c5e7a 8236+ if (!au_digen_test(parent, sigen))
1facf9fc 8237+ break;
8238+ d = parent;
8239+ }
8240+
8241+ inode = d->d_inode;
8242+ if (d != dentry)
027c5e7a 8243+ di_write_lock_child2(d);
1facf9fc 8244+
8245+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
8246+ if (au_digen_test(d, sigen)) {
8247+ /*
8248+ * todo: consolidate with simple_reval_dpath(),
8249+ * do_refresh() and au_reval_for_attr().
8250+ */
1facf9fc 8251+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8252+ err = au_refresh_dentry(d, parent);
1facf9fc 8253+ di_read_unlock(parent, AuLock_IR);
8254+ }
8255+
8256+ if (d != dentry)
8257+ di_write_unlock(d);
8258+ dput(parent);
8259+ if (unlikely(err))
8260+ break;
8261+ }
8262+
8263+ return err;
8264+}
8265+
8266+/*
8267+ * if valid returns 1, otherwise 0.
8268+ */
b4510431 8269+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 8270+{
8271+ int valid, err;
8272+ unsigned int sigen;
8273+ unsigned char do_udba;
8274+ struct super_block *sb;
8275+ struct inode *inode;
8276+
027c5e7a 8277+ /* todo: support rcu-walk? */
b4510431 8278+ if (flags & LOOKUP_RCU)
027c5e7a
AM
8279+ return -ECHILD;
8280+
8281+ valid = 0;
8282+ if (unlikely(!au_di(dentry)))
8283+ goto out;
8284+
e49829fe 8285+ valid = 1;
1facf9fc 8286+ sb = dentry->d_sb;
e49829fe
JR
8287+ /*
8288+ * todo: very ugly
8289+ * i_mutex of parent dir may be held,
8290+ * but we should not return 'invalid' due to busy.
8291+ */
8292+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
8293+ if (unlikely(err)) {
8294+ valid = err;
027c5e7a 8295+ AuTraceErr(err);
e49829fe
JR
8296+ goto out;
8297+ }
c1595e42
JR
8298+ inode = dentry->d_inode;
8299+ if (unlikely(inode && is_bad_inode(inode))) {
8300+ err = -EINVAL;
8301+ AuTraceErr(err);
8302+ goto out_dgrade;
8303+ }
027c5e7a
AM
8304+ if (unlikely(au_dbrange_test(dentry))) {
8305+ err = -EINVAL;
8306+ AuTraceErr(err);
8307+ goto out_dgrade;
1facf9fc 8308+ }
027c5e7a
AM
8309+
8310+ sigen = au_sigen(sb);
8311+ if (au_digen_test(dentry, sigen)) {
1facf9fc 8312+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
8313+ err = au_reval_dpath(dentry, sigen);
8314+ if (unlikely(err)) {
8315+ AuTraceErr(err);
1facf9fc 8316+ goto out_dgrade;
027c5e7a 8317+ }
1facf9fc 8318+ }
8319+ di_downgrade_lock(dentry, AuLock_IR);
8320+
1facf9fc 8321+ err = -EINVAL;
c1595e42 8322+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
523b37e3 8323+ && inode
38d290e6 8324+ && !(inode->i_state && I_LINKABLE)
523b37e3 8325+ && (IS_DEADDIR(inode) || !inode->i_nlink))
027c5e7a
AM
8326+ goto out_inval;
8327+
1facf9fc 8328+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
8329+ if (do_udba && inode) {
8330+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 8331+ struct inode *h_inode;
1facf9fc 8332+
027c5e7a
AM
8333+ if (bstart >= 0) {
8334+ h_inode = au_h_iptr(inode, bstart);
8335+ if (h_inode && au_test_higen(inode, h_inode))
8336+ goto out_inval;
8337+ }
1facf9fc 8338+ }
8339+
b4510431 8340+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 8341+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 8342+ err = -EIO;
523b37e3
AM
8343+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
8344+ dentry, err);
027c5e7a 8345+ }
e49829fe 8346+ goto out_inval;
1facf9fc 8347+
4f0767ce 8348+out_dgrade:
1facf9fc 8349+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 8350+out_inval:
1facf9fc 8351+ aufs_read_unlock(dentry, AuLock_IR);
8352+ AuTraceErr(err);
8353+ valid = !err;
e49829fe 8354+out:
027c5e7a 8355+ if (!valid) {
523b37e3 8356+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
8357+ d_drop(dentry);
8358+ }
1facf9fc 8359+ return valid;
8360+}
8361+
8362+static void aufs_d_release(struct dentry *dentry)
8363+{
027c5e7a 8364+ if (au_di(dentry)) {
4a4d8108
AM
8365+ au_di_fin(dentry);
8366+ au_hn_di_reinit(dentry);
1facf9fc 8367+ }
1facf9fc 8368+}
8369+
4a4d8108 8370+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
8371+ .d_revalidate = aufs_d_revalidate,
8372+ .d_weak_revalidate = aufs_d_revalidate,
8373+ .d_release = aufs_d_release
1facf9fc 8374+};
7f207e10
AM
8375diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
8376--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 8377+++ linux/fs/aufs/dentry.h 2015-04-13 15:10:20.780156788 +0200
076b876e 8378@@ -0,0 +1,233 @@
1facf9fc 8379+/*
2000de60 8380+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 8381+ *
8382+ * This program, aufs is free software; you can redistribute it and/or modify
8383+ * it under the terms of the GNU General Public License as published by
8384+ * the Free Software Foundation; either version 2 of the License, or
8385+ * (at your option) any later version.
dece6358
AM
8386+ *
8387+ * This program is distributed in the hope that it will be useful,
8388+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8389+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8390+ * GNU General Public License for more details.
8391+ *
8392+ * You should have received a copy of the GNU General Public License
523b37e3 8393+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8394+ */
8395+
8396+/*
8397+ * lookup and dentry operations
8398+ */
8399+
8400+#ifndef __AUFS_DENTRY_H__
8401+#define __AUFS_DENTRY_H__
8402+
8403+#ifdef __KERNEL__
8404+
dece6358 8405+#include <linux/dcache.h>
1facf9fc 8406+#include "rwsem.h"
8407+
1facf9fc 8408+struct au_hdentry {
8409+ struct dentry *hd_dentry;
027c5e7a 8410+ aufs_bindex_t hd_id;
1facf9fc 8411+};
8412+
8413+struct au_dinfo {
8414+ atomic_t di_generation;
8415+
dece6358 8416+ struct au_rwsem di_rwsem;
1facf9fc 8417+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
38d290e6 8418+ unsigned char di_tmpfile; /* to allow the different name */
1facf9fc 8419+ struct au_hdentry *di_hdentry;
4a4d8108 8420+} ____cacheline_aligned_in_smp;
1facf9fc 8421+
8422+/* ---------------------------------------------------------------------- */
8423+
8424+/* dentry.c */
4a4d8108 8425+extern const struct dentry_operations aufs_dop;
1facf9fc 8426+struct au_branch;
076b876e 8427+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 8428+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8429+ struct dentry *h_parent, struct au_branch *br);
8430+
537831f9 8431+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 8432+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 8433+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 8434+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
8435+
8436+/* dinfo.c */
4a4d8108 8437+void au_di_init_once(void *_di);
027c5e7a
AM
8438+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
8439+void au_di_free(struct au_dinfo *dinfo);
8440+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
8441+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
8442+int au_di_init(struct dentry *dentry);
8443+void au_di_fin(struct dentry *dentry);
1facf9fc 8444+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
8445+
8446+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
8447+void di_read_unlock(struct dentry *d, int flags);
8448+void di_downgrade_lock(struct dentry *d, int flags);
8449+void di_write_lock(struct dentry *d, unsigned int lsc);
8450+void di_write_unlock(struct dentry *d);
8451+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
8452+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
8453+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
8454+
8455+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 8456+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 8457+aufs_bindex_t au_dbtail(struct dentry *dentry);
8458+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
8459+
8460+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8461+ struct dentry *h_dentry);
027c5e7a
AM
8462+int au_digen_test(struct dentry *dentry, unsigned int sigen);
8463+int au_dbrange_test(struct dentry *dentry);
1facf9fc 8464+void au_update_digen(struct dentry *dentry);
8465+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
8466+void au_update_dbstart(struct dentry *dentry);
8467+void au_update_dbend(struct dentry *dentry);
8468+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
8469+
8470+/* ---------------------------------------------------------------------- */
8471+
8472+static inline struct au_dinfo *au_di(struct dentry *dentry)
8473+{
8474+ return dentry->d_fsdata;
8475+}
8476+
8477+/* ---------------------------------------------------------------------- */
8478+
8479+/* lock subclass for dinfo */
8480+enum {
8481+ AuLsc_DI_CHILD, /* child first */
4a4d8108 8482+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 8483+ AuLsc_DI_CHILD3, /* copyup dirs */
8484+ AuLsc_DI_PARENT,
8485+ AuLsc_DI_PARENT2,
027c5e7a
AM
8486+ AuLsc_DI_PARENT3,
8487+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 8488+};
8489+
8490+/*
8491+ * di_read_lock_child, di_write_lock_child,
8492+ * di_read_lock_child2, di_write_lock_child2,
8493+ * di_read_lock_child3, di_write_lock_child3,
8494+ * di_read_lock_parent, di_write_lock_parent,
8495+ * di_read_lock_parent2, di_write_lock_parent2,
8496+ * di_read_lock_parent3, di_write_lock_parent3,
8497+ */
8498+#define AuReadLockFunc(name, lsc) \
8499+static inline void di_read_lock_##name(struct dentry *d, int flags) \
8500+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
8501+
8502+#define AuWriteLockFunc(name, lsc) \
8503+static inline void di_write_lock_##name(struct dentry *d) \
8504+{ di_write_lock(d, AuLsc_DI_##lsc); }
8505+
8506+#define AuRWLockFuncs(name, lsc) \
8507+ AuReadLockFunc(name, lsc) \
8508+ AuWriteLockFunc(name, lsc)
8509+
8510+AuRWLockFuncs(child, CHILD);
8511+AuRWLockFuncs(child2, CHILD2);
8512+AuRWLockFuncs(child3, CHILD3);
8513+AuRWLockFuncs(parent, PARENT);
8514+AuRWLockFuncs(parent2, PARENT2);
8515+AuRWLockFuncs(parent3, PARENT3);
8516+
8517+#undef AuReadLockFunc
8518+#undef AuWriteLockFunc
8519+#undef AuRWLockFuncs
8520+
8521+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
8522+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
8523+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 8524+
8525+/* ---------------------------------------------------------------------- */
8526+
8527+/* todo: memory barrier? */
8528+static inline unsigned int au_digen(struct dentry *d)
8529+{
8530+ return atomic_read(&au_di(d)->di_generation);
8531+}
8532+
8533+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
8534+{
8535+ hdentry->hd_dentry = NULL;
8536+}
8537+
8538+static inline void au_hdput(struct au_hdentry *hd)
8539+{
4a4d8108
AM
8540+ if (hd)
8541+ dput(hd->hd_dentry);
1facf9fc 8542+}
8543+
8544+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
8545+{
1308ab2a 8546+ DiMustAnyLock(dentry);
1facf9fc 8547+ return au_di(dentry)->di_bstart;
8548+}
8549+
8550+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
8551+{
1308ab2a 8552+ DiMustAnyLock(dentry);
1facf9fc 8553+ return au_di(dentry)->di_bend;
8554+}
8555+
8556+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
8557+{
1308ab2a 8558+ DiMustAnyLock(dentry);
1facf9fc 8559+ return au_di(dentry)->di_bwh;
8560+}
8561+
8562+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
8563+{
1308ab2a 8564+ DiMustAnyLock(dentry);
1facf9fc 8565+ return au_di(dentry)->di_bdiropq;
8566+}
8567+
8568+/* todo: hard/soft set? */
8569+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
8570+{
1308ab2a 8571+ DiMustWriteLock(dentry);
1facf9fc 8572+ au_di(dentry)->di_bstart = bindex;
8573+}
8574+
8575+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
8576+{
1308ab2a 8577+ DiMustWriteLock(dentry);
1facf9fc 8578+ au_di(dentry)->di_bend = bindex;
8579+}
8580+
8581+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
8582+{
1308ab2a 8583+ DiMustWriteLock(dentry);
1facf9fc 8584+ /* dbwh can be outside of bstart - bend range */
8585+ au_di(dentry)->di_bwh = bindex;
8586+}
8587+
8588+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
8589+{
1308ab2a 8590+ DiMustWriteLock(dentry);
1facf9fc 8591+ au_di(dentry)->di_bdiropq = bindex;
8592+}
8593+
8594+/* ---------------------------------------------------------------------- */
8595+
4a4d8108 8596+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 8597+static inline void au_digen_dec(struct dentry *d)
8598+{
e49829fe 8599+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 8600+}
8601+
4a4d8108 8602+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 8603+{
8604+ dentry->d_fsdata = NULL;
8605+}
8606+#else
4a4d8108
AM
8607+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
8608+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 8609+
8610+#endif /* __KERNEL__ */
8611+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
8612diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
8613--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 8614+++ linux/fs/aufs/dinfo.c 2015-04-13 15:10:20.783490201 +0200
38d290e6 8615@@ -0,0 +1,544 @@
1facf9fc 8616+/*
2000de60 8617+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 8618+ *
8619+ * This program, aufs is free software; you can redistribute it and/or modify
8620+ * it under the terms of the GNU General Public License as published by
8621+ * the Free Software Foundation; either version 2 of the License, or
8622+ * (at your option) any later version.
dece6358
AM
8623+ *
8624+ * This program is distributed in the hope that it will be useful,
8625+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8626+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8627+ * GNU General Public License for more details.
8628+ *
8629+ * You should have received a copy of the GNU General Public License
523b37e3 8630+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8631+ */
8632+
8633+/*
8634+ * dentry private data
8635+ */
8636+
8637+#include "aufs.h"
8638+
e49829fe 8639+void au_di_init_once(void *_dinfo)
4a4d8108 8640+{
e49829fe
JR
8641+ struct au_dinfo *dinfo = _dinfo;
8642+ static struct lock_class_key aufs_di;
4a4d8108 8643+
e49829fe
JR
8644+ au_rw_init(&dinfo->di_rwsem);
8645+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
8646+}
8647+
027c5e7a 8648+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 8649+{
8650+ struct au_dinfo *dinfo;
027c5e7a 8651+ int nbr, i;
1facf9fc 8652+
8653+ dinfo = au_cache_alloc_dinfo();
8654+ if (unlikely(!dinfo))
8655+ goto out;
8656+
1facf9fc 8657+ nbr = au_sbend(sb) + 1;
8658+ if (nbr <= 0)
8659+ nbr = 1;
8660+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
8661+ if (dinfo->di_hdentry) {
8662+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
8663+ dinfo->di_bstart = -1;
8664+ dinfo->di_bend = -1;
8665+ dinfo->di_bwh = -1;
8666+ dinfo->di_bdiropq = -1;
38d290e6 8667+ dinfo->di_tmpfile = 0;
027c5e7a
AM
8668+ for (i = 0; i < nbr; i++)
8669+ dinfo->di_hdentry[i].hd_id = -1;
8670+ goto out;
8671+ }
1facf9fc 8672+
1facf9fc 8673+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
8674+ dinfo = NULL;
8675+
4f0767ce 8676+out:
027c5e7a 8677+ return dinfo;
1facf9fc 8678+}
8679+
027c5e7a 8680+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 8681+{
4a4d8108
AM
8682+ struct au_hdentry *p;
8683+ aufs_bindex_t bend, bindex;
8684+
8685+ /* dentry may not be revalidated */
027c5e7a 8686+ bindex = dinfo->di_bstart;
4a4d8108 8687+ if (bindex >= 0) {
027c5e7a
AM
8688+ bend = dinfo->di_bend;
8689+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
8690+ while (bindex++ <= bend)
8691+ au_hdput(p++);
8692+ }
027c5e7a
AM
8693+ kfree(dinfo->di_hdentry);
8694+ au_cache_free_dinfo(dinfo);
8695+}
8696+
8697+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
8698+{
8699+ struct au_hdentry *p;
8700+ aufs_bindex_t bi;
8701+
8702+ AuRwMustWriteLock(&a->di_rwsem);
8703+ AuRwMustWriteLock(&b->di_rwsem);
8704+
8705+#define DiSwap(v, name) \
8706+ do { \
8707+ v = a->di_##name; \
8708+ a->di_##name = b->di_##name; \
8709+ b->di_##name = v; \
8710+ } while (0)
8711+
8712+ DiSwap(p, hdentry);
8713+ DiSwap(bi, bstart);
8714+ DiSwap(bi, bend);
8715+ DiSwap(bi, bwh);
8716+ DiSwap(bi, bdiropq);
8717+ /* smp_mb(); */
8718+
8719+#undef DiSwap
8720+}
8721+
8722+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
8723+{
8724+ AuRwMustWriteLock(&dst->di_rwsem);
8725+ AuRwMustWriteLock(&src->di_rwsem);
8726+
8727+ dst->di_bstart = src->di_bstart;
8728+ dst->di_bend = src->di_bend;
8729+ dst->di_bwh = src->di_bwh;
8730+ dst->di_bdiropq = src->di_bdiropq;
8731+ /* smp_mb(); */
8732+}
8733+
8734+int au_di_init(struct dentry *dentry)
8735+{
8736+ int err;
8737+ struct super_block *sb;
8738+ struct au_dinfo *dinfo;
8739+
8740+ err = 0;
8741+ sb = dentry->d_sb;
8742+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
8743+ if (dinfo) {
8744+ atomic_set(&dinfo->di_generation, au_sigen(sb));
8745+ /* smp_mb(); */ /* atomic_set */
8746+ dentry->d_fsdata = dinfo;
8747+ } else
8748+ err = -ENOMEM;
8749+
8750+ return err;
8751+}
8752+
8753+void au_di_fin(struct dentry *dentry)
8754+{
8755+ struct au_dinfo *dinfo;
8756+
8757+ dinfo = au_di(dentry);
8758+ AuRwDestroy(&dinfo->di_rwsem);
8759+ au_di_free(dinfo);
4a4d8108
AM
8760+}
8761+
1facf9fc 8762+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
8763+{
8764+ int err, sz;
8765+ struct au_hdentry *hdp;
8766+
1308ab2a 8767+ AuRwMustWriteLock(&dinfo->di_rwsem);
8768+
1facf9fc 8769+ err = -ENOMEM;
8770+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
8771+ if (!sz)
8772+ sz = sizeof(*hdp);
8773+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
8774+ if (hdp) {
8775+ dinfo->di_hdentry = hdp;
8776+ err = 0;
8777+ }
8778+
8779+ return err;
8780+}
8781+
8782+/* ---------------------------------------------------------------------- */
8783+
8784+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
8785+{
8786+ switch (lsc) {
8787+ case AuLsc_DI_CHILD:
8788+ ii_write_lock_child(inode);
8789+ break;
8790+ case AuLsc_DI_CHILD2:
8791+ ii_write_lock_child2(inode);
8792+ break;
8793+ case AuLsc_DI_CHILD3:
8794+ ii_write_lock_child3(inode);
8795+ break;
8796+ case AuLsc_DI_PARENT:
8797+ ii_write_lock_parent(inode);
8798+ break;
8799+ case AuLsc_DI_PARENT2:
8800+ ii_write_lock_parent2(inode);
8801+ break;
8802+ case AuLsc_DI_PARENT3:
8803+ ii_write_lock_parent3(inode);
8804+ break;
8805+ default:
8806+ BUG();
8807+ }
8808+}
8809+
8810+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
8811+{
8812+ switch (lsc) {
8813+ case AuLsc_DI_CHILD:
8814+ ii_read_lock_child(inode);
8815+ break;
8816+ case AuLsc_DI_CHILD2:
8817+ ii_read_lock_child2(inode);
8818+ break;
8819+ case AuLsc_DI_CHILD3:
8820+ ii_read_lock_child3(inode);
8821+ break;
8822+ case AuLsc_DI_PARENT:
8823+ ii_read_lock_parent(inode);
8824+ break;
8825+ case AuLsc_DI_PARENT2:
8826+ ii_read_lock_parent2(inode);
8827+ break;
8828+ case AuLsc_DI_PARENT3:
8829+ ii_read_lock_parent3(inode);
8830+ break;
8831+ default:
8832+ BUG();
8833+ }
8834+}
8835+
8836+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
8837+{
dece6358 8838+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8839+ if (d->d_inode) {
8840+ if (au_ftest_lock(flags, IW))
8841+ do_ii_write_lock(d->d_inode, lsc);
8842+ else if (au_ftest_lock(flags, IR))
8843+ do_ii_read_lock(d->d_inode, lsc);
8844+ }
8845+}
8846+
8847+void di_read_unlock(struct dentry *d, int flags)
8848+{
8849+ if (d->d_inode) {
027c5e7a
AM
8850+ if (au_ftest_lock(flags, IW)) {
8851+ au_dbg_verify_dinode(d);
1facf9fc 8852+ ii_write_unlock(d->d_inode);
027c5e7a
AM
8853+ } else if (au_ftest_lock(flags, IR)) {
8854+ au_dbg_verify_dinode(d);
1facf9fc 8855+ ii_read_unlock(d->d_inode);
027c5e7a 8856+ }
1facf9fc 8857+ }
dece6358 8858+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 8859+}
8860+
8861+void di_downgrade_lock(struct dentry *d, int flags)
8862+{
1facf9fc 8863+ if (d->d_inode && au_ftest_lock(flags, IR))
8864+ ii_downgrade_lock(d->d_inode);
dece6358 8865+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 8866+}
8867+
8868+void di_write_lock(struct dentry *d, unsigned int lsc)
8869+{
dece6358 8870+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8871+ if (d->d_inode)
8872+ do_ii_write_lock(d->d_inode, lsc);
8873+}
8874+
8875+void di_write_unlock(struct dentry *d)
8876+{
027c5e7a 8877+ au_dbg_verify_dinode(d);
1facf9fc 8878+ if (d->d_inode)
8879+ ii_write_unlock(d->d_inode);
dece6358 8880+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 8881+}
8882+
8883+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
8884+{
8885+ AuDebugOn(d1 == d2
8886+ || d1->d_inode == d2->d_inode
8887+ || d1->d_sb != d2->d_sb);
8888+
8889+ if (isdir && au_test_subdir(d1, d2)) {
8890+ di_write_lock_child(d1);
8891+ di_write_lock_child2(d2);
8892+ } else {
8893+ /* there should be no races */
8894+ di_write_lock_child(d2);
8895+ di_write_lock_child2(d1);
8896+ }
8897+}
8898+
8899+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
8900+{
8901+ AuDebugOn(d1 == d2
8902+ || d1->d_inode == d2->d_inode
8903+ || d1->d_sb != d2->d_sb);
8904+
8905+ if (isdir && au_test_subdir(d1, d2)) {
8906+ di_write_lock_parent(d1);
8907+ di_write_lock_parent2(d2);
8908+ } else {
8909+ /* there should be no races */
8910+ di_write_lock_parent(d2);
8911+ di_write_lock_parent2(d1);
8912+ }
8913+}
8914+
8915+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
8916+{
8917+ di_write_unlock(d1);
8918+ if (d1->d_inode == d2->d_inode)
dece6358 8919+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 8920+ else
8921+ di_write_unlock(d2);
8922+}
8923+
8924+/* ---------------------------------------------------------------------- */
8925+
8926+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
8927+{
8928+ struct dentry *d;
8929+
1308ab2a 8930+ DiMustAnyLock(dentry);
8931+
1facf9fc 8932+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
8933+ return NULL;
8934+ AuDebugOn(bindex < 0);
8935+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
c1595e42 8936+ AuDebugOn(d && au_dcount(d) <= 0);
1facf9fc 8937+ return d;
8938+}
8939+
2cbb1c4b
JR
8940+/*
8941+ * extended version of au_h_dptr().
38d290e6
JR
8942+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
8943+ * error.
2cbb1c4b
JR
8944+ */
8945+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
8946+{
8947+ struct dentry *h_dentry;
8948+ struct inode *inode, *h_inode;
8949+
8950+ inode = dentry->d_inode;
8951+ AuDebugOn(!inode);
8952+
8953+ h_dentry = NULL;
8954+ if (au_dbstart(dentry) <= bindex
8955+ && bindex <= au_dbend(dentry))
8956+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 8957+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
8958+ dget(h_dentry);
8959+ goto out; /* success */
8960+ }
8961+
8962+ AuDebugOn(bindex < au_ibstart(inode));
8963+ AuDebugOn(au_ibend(inode) < bindex);
8964+ h_inode = au_h_iptr(inode, bindex);
8965+ h_dentry = d_find_alias(h_inode);
8966+ if (h_dentry) {
8967+ if (!IS_ERR(h_dentry)) {
38d290e6 8968+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
8969+ goto out; /* success */
8970+ dput(h_dentry);
8971+ } else
8972+ goto out;
8973+ }
8974+
8975+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
8976+ h_dentry = au_plink_lkup(inode, bindex);
8977+ AuDebugOn(!h_dentry);
8978+ if (!IS_ERR(h_dentry)) {
8979+ if (!au_d_hashed_positive(h_dentry))
8980+ goto out; /* success */
8981+ dput(h_dentry);
8982+ h_dentry = NULL;
8983+ }
8984+ }
8985+
8986+out:
8987+ AuDbgDentry(h_dentry);
8988+ return h_dentry;
8989+}
8990+
1facf9fc 8991+aufs_bindex_t au_dbtail(struct dentry *dentry)
8992+{
8993+ aufs_bindex_t bend, bwh;
8994+
8995+ bend = au_dbend(dentry);
8996+ if (0 <= bend) {
8997+ bwh = au_dbwh(dentry);
8998+ if (!bwh)
8999+ return bwh;
9000+ if (0 < bwh && bwh < bend)
9001+ return bwh - 1;
9002+ }
9003+ return bend;
9004+}
9005+
9006+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9007+{
9008+ aufs_bindex_t bend, bopq;
9009+
9010+ bend = au_dbtail(dentry);
9011+ if (0 <= bend) {
9012+ bopq = au_dbdiropq(dentry);
9013+ if (0 <= bopq && bopq < bend)
9014+ bend = bopq;
9015+ }
9016+ return bend;
9017+}
9018+
9019+/* ---------------------------------------------------------------------- */
9020+
9021+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9022+ struct dentry *h_dentry)
9023+{
9024+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 9025+ struct au_branch *br;
1facf9fc 9026+
1308ab2a 9027+ DiMustWriteLock(dentry);
9028+
4a4d8108 9029+ au_hdput(hd);
1facf9fc 9030+ hd->hd_dentry = h_dentry;
027c5e7a
AM
9031+ if (h_dentry) {
9032+ br = au_sbr(dentry->d_sb, bindex);
9033+ hd->hd_id = br->br_id;
9034+ }
9035+}
9036+
9037+int au_dbrange_test(struct dentry *dentry)
9038+{
9039+ int err;
9040+ aufs_bindex_t bstart, bend;
9041+
9042+ err = 0;
9043+ bstart = au_dbstart(dentry);
9044+ bend = au_dbend(dentry);
9045+ if (bstart >= 0)
9046+ AuDebugOn(bend < 0 && bstart > bend);
9047+ else {
9048+ err = -EIO;
9049+ AuDebugOn(bend >= 0);
9050+ }
9051+
9052+ return err;
9053+}
9054+
9055+int au_digen_test(struct dentry *dentry, unsigned int sigen)
9056+{
9057+ int err;
9058+
9059+ err = 0;
9060+ if (unlikely(au_digen(dentry) != sigen
9061+ || au_iigen_test(dentry->d_inode, sigen)))
9062+ err = -EIO;
9063+
9064+ return err;
1facf9fc 9065+}
9066+
9067+void au_update_digen(struct dentry *dentry)
9068+{
9069+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
9070+ /* smp_mb(); */ /* atomic_set */
9071+}
9072+
9073+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
9074+{
9075+ struct au_dinfo *dinfo;
9076+ struct dentry *h_d;
4a4d8108 9077+ struct au_hdentry *hdp;
1facf9fc 9078+
1308ab2a 9079+ DiMustWriteLock(dentry);
9080+
1facf9fc 9081+ dinfo = au_di(dentry);
9082+ if (!dinfo || dinfo->di_bstart < 0)
9083+ return;
9084+
4a4d8108 9085+ hdp = dinfo->di_hdentry;
1facf9fc 9086+ if (do_put_zero) {
9087+ aufs_bindex_t bindex, bend;
9088+
9089+ bend = dinfo->di_bend;
9090+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 9091+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 9092+ if (h_d && !h_d->d_inode)
9093+ au_set_h_dptr(dentry, bindex, NULL);
9094+ }
9095+ }
9096+
9097+ dinfo->di_bstart = -1;
9098+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 9099+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 9100+ break;
9101+ if (dinfo->di_bstart > dinfo->di_bend) {
9102+ dinfo->di_bstart = -1;
9103+ dinfo->di_bend = -1;
9104+ return;
9105+ }
9106+
9107+ dinfo->di_bend++;
9108+ while (0 <= --dinfo->di_bend)
4a4d8108 9109+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 9110+ break;
9111+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
9112+}
9113+
9114+void au_update_dbstart(struct dentry *dentry)
9115+{
9116+ aufs_bindex_t bindex, bend;
9117+ struct dentry *h_dentry;
9118+
9119+ bend = au_dbend(dentry);
9120+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
9121+ h_dentry = au_h_dptr(dentry, bindex);
9122+ if (!h_dentry)
9123+ continue;
9124+ if (h_dentry->d_inode) {
9125+ au_set_dbstart(dentry, bindex);
9126+ return;
9127+ }
9128+ au_set_h_dptr(dentry, bindex, NULL);
9129+ }
9130+}
9131+
9132+void au_update_dbend(struct dentry *dentry)
9133+{
9134+ aufs_bindex_t bindex, bstart;
9135+ struct dentry *h_dentry;
9136+
9137+ bstart = au_dbstart(dentry);
7f207e10 9138+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 9139+ h_dentry = au_h_dptr(dentry, bindex);
9140+ if (!h_dentry)
9141+ continue;
9142+ if (h_dentry->d_inode) {
9143+ au_set_dbend(dentry, bindex);
9144+ return;
9145+ }
9146+ au_set_h_dptr(dentry, bindex, NULL);
9147+ }
9148+}
9149+
9150+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
9151+{
9152+ aufs_bindex_t bindex, bend;
9153+
9154+ bend = au_dbend(dentry);
9155+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
9156+ if (au_h_dptr(dentry, bindex) == h_dentry)
9157+ return bindex;
9158+ return -1;
9159+}
7f207e10
AM
9160diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
9161--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 9162+++ linux/fs/aufs/dir.c 2015-04-13 15:10:20.783490201 +0200
2000de60 9163@@ -0,0 +1,643 @@
1facf9fc 9164+/*
2000de60 9165+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 9166+ *
9167+ * This program, aufs is free software; you can redistribute it and/or modify
9168+ * it under the terms of the GNU General Public License as published by
9169+ * the Free Software Foundation; either version 2 of the License, or
9170+ * (at your option) any later version.
dece6358
AM
9171+ *
9172+ * This program is distributed in the hope that it will be useful,
9173+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9174+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9175+ * GNU General Public License for more details.
9176+ *
9177+ * You should have received a copy of the GNU General Public License
523b37e3 9178+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9179+ */
9180+
9181+/*
9182+ * directory operations
9183+ */
9184+
9185+#include <linux/fs_stack.h>
9186+#include "aufs.h"
9187+
9188+void au_add_nlink(struct inode *dir, struct inode *h_dir)
9189+{
9dbd164d
AM
9190+ unsigned int nlink;
9191+
1facf9fc 9192+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9193+
9dbd164d
AM
9194+ nlink = dir->i_nlink;
9195+ nlink += h_dir->i_nlink - 2;
1facf9fc 9196+ if (h_dir->i_nlink < 2)
9dbd164d 9197+ nlink += 2;
f6b6e03d 9198+ smp_mb(); /* for i_nlink */
7eafdf33 9199+ /* 0 can happen in revaliding */
92d182d2 9200+ set_nlink(dir, nlink);
1facf9fc 9201+}
9202+
9203+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
9204+{
9dbd164d
AM
9205+ unsigned int nlink;
9206+
1facf9fc 9207+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9208+
9dbd164d
AM
9209+ nlink = dir->i_nlink;
9210+ nlink -= h_dir->i_nlink - 2;
1facf9fc 9211+ if (h_dir->i_nlink < 2)
9dbd164d 9212+ nlink -= 2;
f6b6e03d 9213+ smp_mb(); /* for i_nlink */
92d182d2 9214+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 9215+ set_nlink(dir, nlink);
1facf9fc 9216+}
9217+
1308ab2a 9218+loff_t au_dir_size(struct file *file, struct dentry *dentry)
9219+{
9220+ loff_t sz;
9221+ aufs_bindex_t bindex, bend;
9222+ struct file *h_file;
9223+ struct dentry *h_dentry;
9224+
9225+ sz = 0;
9226+ if (file) {
2000de60 9227+ AuDebugOn(!d_is_dir(file->f_path.dentry));
1308ab2a 9228+
4a4d8108 9229+ bend = au_fbend_dir(file);
1308ab2a 9230+ for (bindex = au_fbstart(file);
9231+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9232+ bindex++) {
4a4d8108 9233+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
9234+ if (h_file && file_inode(h_file))
9235+ sz += vfsub_f_size_read(h_file);
1308ab2a 9236+ }
9237+ } else {
9238+ AuDebugOn(!dentry);
2000de60 9239+ AuDebugOn(!d_is_dir(dentry));
1308ab2a 9240+
9241+ bend = au_dbtaildir(dentry);
9242+ for (bindex = au_dbstart(dentry);
9243+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9244+ bindex++) {
9245+ h_dentry = au_h_dptr(dentry, bindex);
9246+ if (h_dentry && h_dentry->d_inode)
9247+ sz += i_size_read(h_dentry->d_inode);
9248+ }
9249+ }
9250+ if (sz < KMALLOC_MAX_SIZE)
9251+ sz = roundup_pow_of_two(sz);
9252+ if (sz > KMALLOC_MAX_SIZE)
9253+ sz = KMALLOC_MAX_SIZE;
9254+ else if (sz < NAME_MAX) {
9255+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
9256+ sz = AUFS_RDBLK_DEF;
9257+ }
9258+ return sz;
9259+}
9260+
1facf9fc 9261+/* ---------------------------------------------------------------------- */
9262+
9263+static int reopen_dir(struct file *file)
9264+{
9265+ int err;
9266+ unsigned int flags;
9267+ aufs_bindex_t bindex, btail, bstart;
9268+ struct dentry *dentry, *h_dentry;
9269+ struct file *h_file;
9270+
9271+ /* open all lower dirs */
2000de60 9272+ dentry = file->f_path.dentry;
1facf9fc 9273+ bstart = au_dbstart(dentry);
9274+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
9275+ au_set_h_fptr(file, bindex, NULL);
9276+ au_set_fbstart(file, bstart);
9277+
9278+ btail = au_dbtaildir(dentry);
4a4d8108 9279+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 9280+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 9281+ au_set_fbend_dir(file, btail);
1facf9fc 9282+
4a4d8108 9283+ flags = vfsub_file_flags(file);
1facf9fc 9284+ for (bindex = bstart; bindex <= btail; bindex++) {
9285+ h_dentry = au_h_dptr(dentry, bindex);
9286+ if (!h_dentry)
9287+ continue;
4a4d8108 9288+ h_file = au_hf_dir(file, bindex);
1facf9fc 9289+ if (h_file)
9290+ continue;
9291+
392086de 9292+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9293+ err = PTR_ERR(h_file);
9294+ if (IS_ERR(h_file))
9295+ goto out; /* close all? */
9296+ au_set_h_fptr(file, bindex, h_file);
9297+ }
9298+ au_update_figen(file);
9299+ /* todo: necessary? */
9300+ /* file->f_ra = h_file->f_ra; */
9301+ err = 0;
9302+
4f0767ce 9303+out:
1facf9fc 9304+ return err;
9305+}
9306+
9307+static int do_open_dir(struct file *file, int flags)
9308+{
9309+ int err;
9310+ aufs_bindex_t bindex, btail;
9311+ struct dentry *dentry, *h_dentry;
9312+ struct file *h_file;
9313+
1308ab2a 9314+ FiMustWriteLock(file);
9315+
523b37e3 9316+ err = 0;
2000de60 9317+ dentry = file->f_path.dentry;
1facf9fc 9318+ file->f_version = dentry->d_inode->i_version;
9319+ bindex = au_dbstart(dentry);
9320+ au_set_fbstart(file, bindex);
9321+ btail = au_dbtaildir(dentry);
4a4d8108 9322+ au_set_fbend_dir(file, btail);
1facf9fc 9323+ for (; !err && bindex <= btail; bindex++) {
9324+ h_dentry = au_h_dptr(dentry, bindex);
9325+ if (!h_dentry)
9326+ continue;
9327+
392086de 9328+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9329+ if (IS_ERR(h_file)) {
9330+ err = PTR_ERR(h_file);
9331+ break;
9332+ }
9333+ au_set_h_fptr(file, bindex, h_file);
9334+ }
9335+ au_update_figen(file);
9336+ /* todo: necessary? */
9337+ /* file->f_ra = h_file->f_ra; */
9338+ if (!err)
9339+ return 0; /* success */
9340+
9341+ /* close all */
9342+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
9343+ au_set_h_fptr(file, bindex, NULL);
9344+ au_set_fbstart(file, -1);
4a4d8108
AM
9345+ au_set_fbend_dir(file, -1);
9346+
1facf9fc 9347+ return err;
9348+}
9349+
9350+static int aufs_open_dir(struct inode *inode __maybe_unused,
9351+ struct file *file)
9352+{
4a4d8108
AM
9353+ int err;
9354+ struct super_block *sb;
9355+ struct au_fidir *fidir;
9356+
9357+ err = -ENOMEM;
2000de60 9358+ sb = file->f_path.dentry->d_sb;
4a4d8108 9359+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 9360+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
9361+ if (fidir) {
9362+ err = au_do_open(file, do_open_dir, fidir);
9363+ if (unlikely(err))
9364+ kfree(fidir);
9365+ }
9366+ si_read_unlock(sb);
9367+ return err;
1facf9fc 9368+}
9369+
9370+static int aufs_release_dir(struct inode *inode __maybe_unused,
9371+ struct file *file)
9372+{
9373+ struct au_vdir *vdir_cache;
4a4d8108
AM
9374+ struct au_finfo *finfo;
9375+ struct au_fidir *fidir;
9376+ aufs_bindex_t bindex, bend;
1facf9fc 9377+
4a4d8108
AM
9378+ finfo = au_fi(file);
9379+ fidir = finfo->fi_hdir;
9380+ if (fidir) {
076b876e 9381+ au_sphl_del(&finfo->fi_hlist,
2000de60 9382+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108
AM
9383+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
9384+ if (vdir_cache)
9385+ au_vdir_free(vdir_cache);
9386+
9387+ bindex = finfo->fi_btop;
9388+ if (bindex >= 0) {
9389+ /*
9390+ * calls fput() instead of filp_close(),
9391+ * since no dnotify or lock for the lower file.
9392+ */
9393+ bend = fidir->fd_bbot;
9394+ for (; bindex <= bend; bindex++)
9395+ au_set_h_fptr(file, bindex, NULL);
9396+ }
9397+ kfree(fidir);
9398+ finfo->fi_hdir = NULL;
1facf9fc 9399+ }
1facf9fc 9400+ au_finfo_fin(file);
1facf9fc 9401+ return 0;
9402+}
9403+
9404+/* ---------------------------------------------------------------------- */
9405+
4a4d8108
AM
9406+static int au_do_flush_dir(struct file *file, fl_owner_t id)
9407+{
9408+ int err;
9409+ aufs_bindex_t bindex, bend;
9410+ struct file *h_file;
9411+
9412+ err = 0;
9413+ bend = au_fbend_dir(file);
9414+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
9415+ h_file = au_hf_dir(file, bindex);
9416+ if (h_file)
9417+ err = vfsub_flush(h_file, id);
9418+ }
9419+ return err;
9420+}
9421+
9422+static int aufs_flush_dir(struct file *file, fl_owner_t id)
9423+{
9424+ return au_do_flush(file, id, au_do_flush_dir);
9425+}
9426+
9427+/* ---------------------------------------------------------------------- */
9428+
1facf9fc 9429+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
9430+{
9431+ int err;
9432+ aufs_bindex_t bend, bindex;
9433+ struct inode *inode;
9434+ struct super_block *sb;
9435+
9436+ err = 0;
9437+ sb = dentry->d_sb;
9438+ inode = dentry->d_inode;
9439+ IMustLock(inode);
9440+ bend = au_dbend(dentry);
9441+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
9442+ struct path h_path;
1facf9fc 9443+
9444+ if (au_test_ro(sb, bindex, inode))
9445+ continue;
9446+ h_path.dentry = au_h_dptr(dentry, bindex);
9447+ if (!h_path.dentry)
9448+ continue;
1facf9fc 9449+
1facf9fc 9450+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 9451+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 9452+ }
9453+
9454+ return err;
9455+}
9456+
9457+static int au_do_fsync_dir(struct file *file, int datasync)
9458+{
9459+ int err;
9460+ aufs_bindex_t bend, bindex;
9461+ struct file *h_file;
9462+ struct super_block *sb;
9463+ struct inode *inode;
1facf9fc 9464+
9465+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9466+ if (unlikely(err))
9467+ goto out;
9468+
2000de60 9469+ sb = file->f_path.dentry->d_sb;
c06a8ce3 9470+ inode = file_inode(file);
4a4d8108 9471+ bend = au_fbend_dir(file);
1facf9fc 9472+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 9473+ h_file = au_hf_dir(file, bindex);
1facf9fc 9474+ if (!h_file || au_test_ro(sb, bindex, inode))
9475+ continue;
9476+
53392da6 9477+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 9478+ }
9479+
4f0767ce 9480+out:
1facf9fc 9481+ return err;
9482+}
9483+
9484+/*
9485+ * @file may be NULL
9486+ */
1e00d052
AM
9487+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
9488+ int datasync)
1facf9fc 9489+{
9490+ int err;
b752ccd1 9491+ struct dentry *dentry;
1facf9fc 9492+ struct super_block *sb;
1e00d052 9493+ struct mutex *mtx;
1facf9fc 9494+
9495+ err = 0;
2000de60 9496+ dentry = file->f_path.dentry;
1e00d052
AM
9497+ mtx = &dentry->d_inode->i_mutex;
9498+ mutex_lock(mtx);
1facf9fc 9499+ sb = dentry->d_sb;
9500+ si_noflush_read_lock(sb);
9501+ if (file)
9502+ err = au_do_fsync_dir(file, datasync);
9503+ else {
9504+ di_write_lock_child(dentry);
9505+ err = au_do_fsync_dir_no_file(dentry, datasync);
9506+ }
9507+ au_cpup_attr_timesizes(dentry->d_inode);
9508+ di_write_unlock(dentry);
9509+ if (file)
9510+ fi_write_unlock(file);
9511+
9512+ si_read_unlock(sb);
1e00d052 9513+ mutex_unlock(mtx);
1facf9fc 9514+ return err;
9515+}
9516+
9517+/* ---------------------------------------------------------------------- */
9518+
392086de 9519+static int aufs_iterate(struct file *file, struct dir_context *ctx)
1facf9fc 9520+{
9521+ int err;
9522+ struct dentry *dentry;
9dbd164d 9523+ struct inode *inode, *h_inode;
1facf9fc 9524+ struct super_block *sb;
9525+
523b37e3 9526+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 9527+
2000de60 9528+ dentry = file->f_path.dentry;
1facf9fc 9529+ inode = dentry->d_inode;
9530+ IMustLock(inode);
9531+
9532+ sb = dentry->d_sb;
9533+ si_read_lock(sb, AuLock_FLUSH);
9534+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9535+ if (unlikely(err))
9536+ goto out;
027c5e7a
AM
9537+ err = au_alive_dir(dentry);
9538+ if (!err)
9539+ err = au_vdir_init(file);
1facf9fc 9540+ di_downgrade_lock(dentry, AuLock_IR);
9541+ if (unlikely(err))
9542+ goto out_unlock;
9543+
9dbd164d 9544+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 9545+ if (!au_test_nfsd()) {
392086de 9546+ err = au_vdir_fill_de(file, ctx);
9dbd164d 9547+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 9548+ } else {
9549+ /*
9550+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
9551+ * encode_fh() and others.
9552+ */
9dbd164d 9553+ atomic_inc(&h_inode->i_count);
1facf9fc 9554+ di_read_unlock(dentry, AuLock_IR);
9555+ si_read_unlock(sb);
392086de 9556+ err = au_vdir_fill_de(file, ctx);
1facf9fc 9557+ fsstack_copy_attr_atime(inode, h_inode);
9558+ fi_write_unlock(file);
9dbd164d 9559+ iput(h_inode);
1facf9fc 9560+
9561+ AuTraceErr(err);
9562+ return err;
9563+ }
9564+
4f0767ce 9565+out_unlock:
1facf9fc 9566+ di_read_unlock(dentry, AuLock_IR);
9567+ fi_write_unlock(file);
4f0767ce 9568+out:
1facf9fc 9569+ si_read_unlock(sb);
9570+ return err;
9571+}
9572+
9573+/* ---------------------------------------------------------------------- */
9574+
9575+#define AuTestEmpty_WHONLY 1
dece6358
AM
9576+#define AuTestEmpty_CALLED (1 << 1)
9577+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 9578+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
9579+#define au_fset_testempty(flags, name) \
9580+ do { (flags) |= AuTestEmpty_##name; } while (0)
9581+#define au_fclr_testempty(flags, name) \
9582+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 9583+
dece6358
AM
9584+#ifndef CONFIG_AUFS_SHWH
9585+#undef AuTestEmpty_SHWH
9586+#define AuTestEmpty_SHWH 0
9587+#endif
9588+
1facf9fc 9589+struct test_empty_arg {
392086de 9590+ struct dir_context ctx;
1308ab2a 9591+ struct au_nhash *whlist;
1facf9fc 9592+ unsigned int flags;
9593+ int err;
9594+ aufs_bindex_t bindex;
9595+};
9596+
392086de
AM
9597+static int test_empty_cb(struct dir_context *ctx, const char *__name,
9598+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 9599+ unsigned int d_type)
1facf9fc 9600+{
392086de
AM
9601+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
9602+ ctx);
1facf9fc 9603+ char *name = (void *)__name;
9604+
9605+ arg->err = 0;
9606+ au_fset_testempty(arg->flags, CALLED);
9607+ /* smp_mb(); */
9608+ if (name[0] == '.'
9609+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
9610+ goto out; /* success */
9611+
9612+ if (namelen <= AUFS_WH_PFX_LEN
9613+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
9614+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 9615+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9616+ arg->err = -ENOTEMPTY;
9617+ goto out;
9618+ }
9619+
9620+ name += AUFS_WH_PFX_LEN;
9621+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 9622+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9623+ arg->err = au_nhash_append_wh
1308ab2a 9624+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 9625+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 9626+
4f0767ce 9627+out:
1facf9fc 9628+ /* smp_mb(); */
9629+ AuTraceErr(arg->err);
9630+ return arg->err;
9631+}
9632+
9633+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9634+{
9635+ int err;
9636+ struct file *h_file;
9637+
9638+ h_file = au_h_open(dentry, arg->bindex,
9639+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 9640+ /*file*/NULL, /*force_wr*/0);
1facf9fc 9641+ err = PTR_ERR(h_file);
9642+ if (IS_ERR(h_file))
9643+ goto out;
9644+
9645+ err = 0;
9646+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 9647+ && !file_inode(h_file)->i_nlink)
1facf9fc 9648+ goto out_put;
9649+
9650+ do {
9651+ arg->err = 0;
9652+ au_fclr_testempty(arg->flags, CALLED);
9653+ /* smp_mb(); */
392086de 9654+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 9655+ if (err >= 0)
9656+ err = arg->err;
9657+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
9658+
4f0767ce 9659+out_put:
1facf9fc 9660+ fput(h_file);
9661+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 9662+out:
1facf9fc 9663+ return err;
9664+}
9665+
9666+struct do_test_empty_args {
9667+ int *errp;
9668+ struct dentry *dentry;
9669+ struct test_empty_arg *arg;
9670+};
9671+
9672+static void call_do_test_empty(void *args)
9673+{
9674+ struct do_test_empty_args *a = args;
9675+ *a->errp = do_test_empty(a->dentry, a->arg);
9676+}
9677+
9678+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9679+{
9680+ int err, wkq_err;
9681+ struct dentry *h_dentry;
9682+ struct inode *h_inode;
9683+
9684+ h_dentry = au_h_dptr(dentry, arg->bindex);
9685+ h_inode = h_dentry->d_inode;
53392da6 9686+ /* todo: i_mode changes anytime? */
1facf9fc 9687+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
9688+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
9689+ mutex_unlock(&h_inode->i_mutex);
9690+ if (!err)
9691+ err = do_test_empty(dentry, arg);
9692+ else {
9693+ struct do_test_empty_args args = {
9694+ .errp = &err,
9695+ .dentry = dentry,
9696+ .arg = arg
9697+ };
9698+ unsigned int flags = arg->flags;
9699+
9700+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
9701+ if (unlikely(wkq_err))
9702+ err = wkq_err;
9703+ arg->flags = flags;
9704+ }
9705+
9706+ return err;
9707+}
9708+
9709+int au_test_empty_lower(struct dentry *dentry)
9710+{
9711+ int err;
1308ab2a 9712+ unsigned int rdhash;
1facf9fc 9713+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 9714+ struct au_nhash whlist;
392086de
AM
9715+ struct test_empty_arg arg = {
9716+ .ctx = {
2000de60 9717+ .actor = test_empty_cb
392086de
AM
9718+ }
9719+ };
076b876e 9720+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 9721+
dece6358
AM
9722+ SiMustAnyLock(dentry->d_sb);
9723+
1308ab2a 9724+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
9725+ if (!rdhash)
9726+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
9727+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 9728+ if (unlikely(err))
1facf9fc 9729+ goto out;
9730+
1facf9fc 9731+ arg.flags = 0;
1308ab2a 9732+ arg.whlist = &whlist;
9733+ bstart = au_dbstart(dentry);
dece6358
AM
9734+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9735+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
9736+ test_empty = do_test_empty;
9737+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
9738+ test_empty = sio_test_empty;
1facf9fc 9739+ arg.bindex = bstart;
076b876e 9740+ err = test_empty(dentry, &arg);
1facf9fc 9741+ if (unlikely(err))
9742+ goto out_whlist;
9743+
9744+ au_fset_testempty(arg.flags, WHONLY);
9745+ btail = au_dbtaildir(dentry);
9746+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
9747+ struct dentry *h_dentry;
9748+
9749+ h_dentry = au_h_dptr(dentry, bindex);
9750+ if (h_dentry && h_dentry->d_inode) {
9751+ arg.bindex = bindex;
076b876e 9752+ err = test_empty(dentry, &arg);
1facf9fc 9753+ }
9754+ }
9755+
4f0767ce 9756+out_whlist:
1308ab2a 9757+ au_nhash_wh_free(&whlist);
4f0767ce 9758+out:
1facf9fc 9759+ return err;
9760+}
9761+
9762+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
9763+{
9764+ int err;
392086de
AM
9765+ struct test_empty_arg arg = {
9766+ .ctx = {
2000de60 9767+ .actor = test_empty_cb
392086de
AM
9768+ }
9769+ };
1facf9fc 9770+ aufs_bindex_t bindex, btail;
9771+
9772+ err = 0;
1308ab2a 9773+ arg.whlist = whlist;
1facf9fc 9774+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
9775+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9776+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 9777+ btail = au_dbtaildir(dentry);
9778+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
9779+ struct dentry *h_dentry;
9780+
9781+ h_dentry = au_h_dptr(dentry, bindex);
9782+ if (h_dentry && h_dentry->d_inode) {
9783+ arg.bindex = bindex;
9784+ err = sio_test_empty(dentry, &arg);
9785+ }
9786+ }
9787+
9788+ return err;
9789+}
9790+
9791+/* ---------------------------------------------------------------------- */
9792+
9793+const struct file_operations aufs_dir_fop = {
4a4d8108 9794+ .owner = THIS_MODULE,
027c5e7a 9795+ .llseek = default_llseek,
1facf9fc 9796+ .read = generic_read_dir,
392086de 9797+ .iterate = aufs_iterate,
1facf9fc 9798+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
9799+#ifdef CONFIG_COMPAT
9800+ .compat_ioctl = aufs_compat_ioctl_dir,
9801+#endif
1facf9fc 9802+ .open = aufs_open_dir,
9803+ .release = aufs_release_dir,
4a4d8108 9804+ .flush = aufs_flush_dir,
1facf9fc 9805+ .fsync = aufs_fsync_dir
9806+};
7f207e10
AM
9807diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
9808--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 9809+++ linux/fs/aufs/dir.h 2015-04-13 15:10:20.783490201 +0200
c1595e42 9810@@ -0,0 +1,130 @@
1facf9fc 9811+/*
2000de60 9812+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 9813+ *
9814+ * This program, aufs is free software; you can redistribute it and/or modify
9815+ * it under the terms of the GNU General Public License as published by
9816+ * the Free Software Foundation; either version 2 of the License, or
9817+ * (at your option) any later version.
dece6358
AM
9818+ *
9819+ * This program is distributed in the hope that it will be useful,
9820+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9821+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9822+ * GNU General Public License for more details.
9823+ *
9824+ * You should have received a copy of the GNU General Public License
523b37e3 9825+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9826+ */
9827+
9828+/*
9829+ * directory operations
9830+ */
9831+
9832+#ifndef __AUFS_DIR_H__
9833+#define __AUFS_DIR_H__
9834+
9835+#ifdef __KERNEL__
9836+
9837+#include <linux/fs.h>
1facf9fc 9838+
9839+/* ---------------------------------------------------------------------- */
9840+
9841+/* need to be faster and smaller */
9842+
9843+struct au_nhash {
dece6358
AM
9844+ unsigned int nh_num;
9845+ struct hlist_head *nh_head;
1facf9fc 9846+};
9847+
9848+struct au_vdir_destr {
9849+ unsigned char len;
9850+ unsigned char name[0];
9851+} __packed;
9852+
9853+struct au_vdir_dehstr {
9854+ struct hlist_node hash;
9855+ struct au_vdir_destr *str;
4a4d8108 9856+} ____cacheline_aligned_in_smp;
1facf9fc 9857+
9858+struct au_vdir_de {
9859+ ino_t de_ino;
9860+ unsigned char de_type;
9861+ /* caution: packed */
9862+ struct au_vdir_destr de_str;
9863+} __packed;
9864+
9865+struct au_vdir_wh {
9866+ struct hlist_node wh_hash;
dece6358
AM
9867+#ifdef CONFIG_AUFS_SHWH
9868+ ino_t wh_ino;
1facf9fc 9869+ aufs_bindex_t wh_bindex;
dece6358
AM
9870+ unsigned char wh_type;
9871+#else
9872+ aufs_bindex_t wh_bindex;
9873+#endif
9874+ /* caution: packed */
1facf9fc 9875+ struct au_vdir_destr wh_str;
9876+} __packed;
9877+
9878+union au_vdir_deblk_p {
9879+ unsigned char *deblk;
9880+ struct au_vdir_de *de;
9881+};
9882+
9883+struct au_vdir {
9884+ unsigned char **vd_deblk;
9885+ unsigned long vd_nblk;
1facf9fc 9886+ struct {
9887+ unsigned long ul;
9888+ union au_vdir_deblk_p p;
9889+ } vd_last;
9890+
9891+ unsigned long vd_version;
dece6358 9892+ unsigned int vd_deblk_sz;
1facf9fc 9893+ unsigned long vd_jiffy;
4a4d8108 9894+} ____cacheline_aligned_in_smp;
1facf9fc 9895+
9896+/* ---------------------------------------------------------------------- */
9897+
9898+/* dir.c */
9899+extern const struct file_operations aufs_dir_fop;
9900+void au_add_nlink(struct inode *dir, struct inode *h_dir);
9901+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 9902+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 9903+int au_test_empty_lower(struct dentry *dentry);
9904+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
9905+
9906+/* vdir.c */
1308ab2a 9907+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
9908+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
9909+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 9910+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
9911+ int limit);
dece6358
AM
9912+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
9913+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
9914+ unsigned int d_type, aufs_bindex_t bindex,
9915+ unsigned char shwh);
1facf9fc 9916+void au_vdir_free(struct au_vdir *vdir);
9917+int au_vdir_init(struct file *file);
392086de 9918+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 9919+
9920+/* ioctl.c */
9921+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
9922+
1308ab2a 9923+#ifdef CONFIG_AUFS_RDU
9924+/* rdu.c */
9925+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
9926+#ifdef CONFIG_COMPAT
9927+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9928+ unsigned long arg);
9929+#endif
1308ab2a 9930+#else
c1595e42
JR
9931+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
9932+ unsigned int cmd, unsigned long arg)
b752ccd1 9933+#ifdef CONFIG_COMPAT
c1595e42
JR
9934+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
9935+ unsigned int cmd, unsigned long arg)
b752ccd1 9936+#endif
1308ab2a 9937+#endif
9938+
1facf9fc 9939+#endif /* __KERNEL__ */
9940+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
9941diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
9942--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
9943+++ linux/fs/aufs/dynop.c 2015-04-13 15:10:20.783490201 +0200
9944@@ -0,0 +1,369 @@
1facf9fc 9945+/*
2000de60 9946+ * Copyright (C) 2010-2015 Junjiro R. Okajima
1facf9fc 9947+ *
9948+ * This program, aufs is free software; you can redistribute it and/or modify
9949+ * it under the terms of the GNU General Public License as published by
9950+ * the Free Software Foundation; either version 2 of the License, or
9951+ * (at your option) any later version.
dece6358
AM
9952+ *
9953+ * This program is distributed in the hope that it will be useful,
9954+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9955+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9956+ * GNU General Public License for more details.
9957+ *
9958+ * You should have received a copy of the GNU General Public License
523b37e3 9959+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9960+ */
9961+
9962+/*
4a4d8108 9963+ * dynamically customizable operations for regular files
1facf9fc 9964+ */
9965+
1facf9fc 9966+#include "aufs.h"
9967+
4a4d8108 9968+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 9969+
4a4d8108
AM
9970+/*
9971+ * How large will these lists be?
9972+ * Usually just a few elements, 20-30 at most for each, I guess.
9973+ */
9974+static struct au_splhead dynop[AuDyLast];
9975+
9976+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 9977+{
4a4d8108
AM
9978+ struct au_dykey *key, *tmp;
9979+ struct list_head *head;
1facf9fc 9980+
4a4d8108
AM
9981+ key = NULL;
9982+ head = &spl->head;
9983+ rcu_read_lock();
9984+ list_for_each_entry_rcu(tmp, head, dk_list)
9985+ if (tmp->dk_op.dy_hop == h_op) {
9986+ key = tmp;
9987+ kref_get(&key->dk_kref);
9988+ break;
9989+ }
9990+ rcu_read_unlock();
9991+
9992+ return key;
1facf9fc 9993+}
9994+
4a4d8108 9995+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 9996+{
4a4d8108
AM
9997+ struct au_dykey **k, *found;
9998+ const void *h_op = key->dk_op.dy_hop;
9999+ int i;
1facf9fc 10000+
4a4d8108
AM
10001+ found = NULL;
10002+ k = br->br_dykey;
10003+ for (i = 0; i < AuBrDynOp; i++)
10004+ if (k[i]) {
10005+ if (k[i]->dk_op.dy_hop == h_op) {
10006+ found = k[i];
10007+ break;
10008+ }
10009+ } else
10010+ break;
10011+ if (!found) {
10012+ spin_lock(&br->br_dykey_lock);
10013+ for (; i < AuBrDynOp; i++)
10014+ if (k[i]) {
10015+ if (k[i]->dk_op.dy_hop == h_op) {
10016+ found = k[i];
10017+ break;
10018+ }
10019+ } else {
10020+ k[i] = key;
10021+ break;
10022+ }
10023+ spin_unlock(&br->br_dykey_lock);
10024+ BUG_ON(i == AuBrDynOp); /* expand the array */
10025+ }
10026+
10027+ return found;
1facf9fc 10028+}
10029+
4a4d8108
AM
10030+/* kref_get() if @key is already added */
10031+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
10032+{
10033+ struct au_dykey *tmp, *found;
10034+ struct list_head *head;
10035+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 10036+
4a4d8108
AM
10037+ found = NULL;
10038+ head = &spl->head;
10039+ spin_lock(&spl->spin);
10040+ list_for_each_entry(tmp, head, dk_list)
10041+ if (tmp->dk_op.dy_hop == h_op) {
10042+ kref_get(&tmp->dk_kref);
10043+ found = tmp;
10044+ break;
10045+ }
10046+ if (!found)
10047+ list_add_rcu(&key->dk_list, head);
10048+ spin_unlock(&spl->spin);
1facf9fc 10049+
4a4d8108
AM
10050+ if (!found)
10051+ DyPrSym(key);
10052+ return found;
10053+}
10054+
10055+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 10056+{
4a4d8108
AM
10057+ struct au_dykey *key;
10058+
10059+ key = container_of(rcu, struct au_dykey, dk_rcu);
10060+ DyPrSym(key);
10061+ kfree(key);
1facf9fc 10062+}
10063+
4a4d8108
AM
10064+static void dy_free(struct kref *kref)
10065+{
10066+ struct au_dykey *key;
10067+ struct au_splhead *spl;
1facf9fc 10068+
4a4d8108
AM
10069+ key = container_of(kref, struct au_dykey, dk_kref);
10070+ spl = dynop + key->dk_op.dy_type;
10071+ au_spl_del_rcu(&key->dk_list, spl);
10072+ call_rcu(&key->dk_rcu, dy_free_rcu);
10073+}
10074+
10075+void au_dy_put(struct au_dykey *key)
1facf9fc 10076+{
4a4d8108
AM
10077+ kref_put(&key->dk_kref, dy_free);
10078+}
1facf9fc 10079+
4a4d8108
AM
10080+/* ---------------------------------------------------------------------- */
10081+
10082+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
10083+
10084+#ifdef CONFIG_AUFS_DEBUG
10085+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 10086+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
10087+#else
10088+#define DyDbgDeclare(cnt) do {} while (0)
10089+#define DyDbgInc(cnt) do {} while (0)
10090+#endif
10091+
10092+#define DySet(func, dst, src, h_op, h_sb) do { \
10093+ DyDbgInc(cnt); \
10094+ if (h_op->func) { \
10095+ if (src.func) \
10096+ dst.func = src.func; \
10097+ else \
10098+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
10099+ } \
10100+} while (0)
10101+
10102+#define DySetForce(func, dst, src) do { \
10103+ AuDebugOn(!src.func); \
10104+ DyDbgInc(cnt); \
10105+ dst.func = src.func; \
10106+} while (0)
10107+
10108+#define DySetAop(func) \
10109+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
10110+#define DySetAopForce(func) \
10111+ DySetForce(func, dyaop->da_op, aufs_aop)
10112+
10113+static void dy_aop(struct au_dykey *key, const void *h_op,
10114+ struct super_block *h_sb __maybe_unused)
10115+{
10116+ struct au_dyaop *dyaop = (void *)key;
10117+ const struct address_space_operations *h_aop = h_op;
10118+ DyDbgDeclare(cnt);
10119+
10120+ AuDbg("%s\n", au_sbtype(h_sb));
10121+
10122+ DySetAop(writepage);
10123+ DySetAopForce(readpage); /* force */
4a4d8108
AM
10124+ DySetAop(writepages);
10125+ DySetAop(set_page_dirty);
10126+ DySetAop(readpages);
10127+ DySetAop(write_begin);
10128+ DySetAop(write_end);
10129+ DySetAop(bmap);
10130+ DySetAop(invalidatepage);
10131+ DySetAop(releasepage);
027c5e7a 10132+ DySetAop(freepage);
7e9cd9fe 10133+ /* this one will be changed according to an aufs mount option */
4a4d8108 10134+ DySetAop(direct_IO);
4a4d8108
AM
10135+ DySetAop(migratepage);
10136+ DySetAop(launder_page);
10137+ DySetAop(is_partially_uptodate);
392086de 10138+ DySetAop(is_dirty_writeback);
4a4d8108 10139+ DySetAop(error_remove_page);
b4510431
AM
10140+ DySetAop(swap_activate);
10141+ DySetAop(swap_deactivate);
4a4d8108
AM
10142+
10143+ DyDbgSize(cnt, *h_aop);
4a4d8108
AM
10144+}
10145+
4a4d8108
AM
10146+/* ---------------------------------------------------------------------- */
10147+
10148+static void dy_bug(struct kref *kref)
10149+{
10150+ BUG();
10151+}
10152+
10153+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
10154+{
10155+ struct au_dykey *key, *old;
10156+ struct au_splhead *spl;
b752ccd1 10157+ struct op {
4a4d8108 10158+ unsigned int sz;
b752ccd1
AM
10159+ void (*set)(struct au_dykey *key, const void *h_op,
10160+ struct super_block *h_sb __maybe_unused);
10161+ };
10162+ static const struct op a[] = {
4a4d8108
AM
10163+ [AuDy_AOP] = {
10164+ .sz = sizeof(struct au_dyaop),
b752ccd1 10165+ .set = dy_aop
4a4d8108 10166+ }
b752ccd1
AM
10167+ };
10168+ const struct op *p;
4a4d8108
AM
10169+
10170+ spl = dynop + op->dy_type;
10171+ key = dy_gfind_get(spl, op->dy_hop);
10172+ if (key)
10173+ goto out_add; /* success */
10174+
10175+ p = a + op->dy_type;
10176+ key = kzalloc(p->sz, GFP_NOFS);
10177+ if (unlikely(!key)) {
10178+ key = ERR_PTR(-ENOMEM);
10179+ goto out;
10180+ }
10181+
10182+ key->dk_op.dy_hop = op->dy_hop;
10183+ kref_init(&key->dk_kref);
86dc4139 10184+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
10185+ old = dy_gadd(spl, key);
10186+ if (old) {
10187+ kfree(key);
10188+ key = old;
10189+ }
10190+
10191+out_add:
10192+ old = dy_bradd(br, key);
10193+ if (old)
10194+ /* its ref-count should never be zero here */
10195+ kref_put(&key->dk_kref, dy_bug);
10196+out:
10197+ return key;
10198+}
10199+
10200+/* ---------------------------------------------------------------------- */
10201+/*
10202+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
c1595e42 10203+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
4a4d8108
AM
10204+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
10205+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
10206+ * See the aufs manual in detail.
4a4d8108
AM
10207+ */
10208+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
10209+{
7e9cd9fe 10210+ if (!do_dx)
4a4d8108 10211+ dyaop->da_op.direct_IO = NULL;
7e9cd9fe 10212+ else
4a4d8108 10213+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
4a4d8108
AM
10214+}
10215+
10216+static struct au_dyaop *dy_aget(struct au_branch *br,
10217+ const struct address_space_operations *h_aop,
10218+ int do_dx)
10219+{
10220+ struct au_dyaop *dyaop;
10221+ struct au_dynop op;
10222+
10223+ op.dy_type = AuDy_AOP;
10224+ op.dy_haop = h_aop;
10225+ dyaop = (void *)dy_get(&op, br);
10226+ if (IS_ERR(dyaop))
10227+ goto out;
10228+ dy_adx(dyaop, do_dx);
10229+
10230+out:
10231+ return dyaop;
10232+}
10233+
10234+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10235+ struct inode *h_inode)
10236+{
10237+ int err, do_dx;
10238+ struct super_block *sb;
10239+ struct au_branch *br;
10240+ struct au_dyaop *dyaop;
10241+
10242+ AuDebugOn(!S_ISREG(h_inode->i_mode));
10243+ IiMustWriteLock(inode);
10244+
10245+ sb = inode->i_sb;
10246+ br = au_sbr(sb, bindex);
10247+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
10248+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
10249+ err = PTR_ERR(dyaop);
10250+ if (IS_ERR(dyaop))
10251+ /* unnecessary to call dy_fput() */
10252+ goto out;
10253+
10254+ err = 0;
10255+ inode->i_mapping->a_ops = &dyaop->da_op;
10256+
10257+out:
10258+ return err;
10259+}
10260+
b752ccd1
AM
10261+/*
10262+ * Is it safe to replace a_ops during the inode/file is in operation?
10263+ * Yes, I hope so.
10264+ */
10265+int au_dy_irefresh(struct inode *inode)
10266+{
10267+ int err;
10268+ aufs_bindex_t bstart;
10269+ struct inode *h_inode;
10270+
10271+ err = 0;
10272+ if (S_ISREG(inode->i_mode)) {
10273+ bstart = au_ibstart(inode);
10274+ h_inode = au_h_iptr(inode, bstart);
10275+ err = au_dy_iaop(inode, bstart, h_inode);
10276+ }
10277+ return err;
10278+}
10279+
4a4d8108
AM
10280+void au_dy_arefresh(int do_dx)
10281+{
10282+ struct au_splhead *spl;
10283+ struct list_head *head;
10284+ struct au_dykey *key;
10285+
10286+ spl = dynop + AuDy_AOP;
10287+ head = &spl->head;
10288+ spin_lock(&spl->spin);
10289+ list_for_each_entry(key, head, dk_list)
10290+ dy_adx((void *)key, do_dx);
10291+ spin_unlock(&spl->spin);
10292+}
10293+
4a4d8108
AM
10294+/* ---------------------------------------------------------------------- */
10295+
10296+void __init au_dy_init(void)
10297+{
10298+ int i;
10299+
10300+ /* make sure that 'struct au_dykey *' can be any type */
10301+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
10302+
10303+ for (i = 0; i < AuDyLast; i++)
10304+ au_spl_init(dynop + i);
10305+}
10306+
10307+void au_dy_fin(void)
10308+{
10309+ int i;
10310+
10311+ for (i = 0; i < AuDyLast; i++)
10312+ WARN_ON(!list_empty(&dynop[i].head));
10313+}
7f207e10
AM
10314diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
10315--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
10316+++ linux/fs/aufs/dynop.h 2015-04-13 15:10:20.783490201 +0200
10317@@ -0,0 +1,74 @@
4a4d8108 10318+/*
2000de60 10319+ * Copyright (C) 2010-2015 Junjiro R. Okajima
4a4d8108
AM
10320+ *
10321+ * This program, aufs is free software; you can redistribute it and/or modify
10322+ * it under the terms of the GNU General Public License as published by
10323+ * the Free Software Foundation; either version 2 of the License, or
10324+ * (at your option) any later version.
10325+ *
10326+ * This program is distributed in the hope that it will be useful,
10327+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10328+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10329+ * GNU General Public License for more details.
10330+ *
10331+ * You should have received a copy of the GNU General Public License
523b37e3 10332+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10333+ */
10334+
10335+/*
10336+ * dynamically customizable operations (for regular files only)
10337+ */
10338+
10339+#ifndef __AUFS_DYNOP_H__
10340+#define __AUFS_DYNOP_H__
10341+
10342+#ifdef __KERNEL__
10343+
7e9cd9fe
AM
10344+#include <linux/fs.h>
10345+#include <linux/kref.h>
4a4d8108 10346+
2cbb1c4b 10347+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
10348+
10349+struct au_dynop {
10350+ int dy_type;
10351+ union {
10352+ const void *dy_hop;
10353+ const struct address_space_operations *dy_haop;
4a4d8108
AM
10354+ };
10355+};
10356+
10357+struct au_dykey {
10358+ union {
10359+ struct list_head dk_list;
10360+ struct rcu_head dk_rcu;
10361+ };
10362+ struct au_dynop dk_op;
10363+
10364+ /*
10365+ * during I am in the branch local array, kref is gotten. when the
10366+ * branch is removed, kref is put.
10367+ */
10368+ struct kref dk_kref;
10369+};
10370+
10371+/* stop unioning since their sizes are very different from each other */
10372+struct au_dyaop {
10373+ struct au_dykey da_key;
10374+ struct address_space_operations da_op; /* not const */
4a4d8108
AM
10375+};
10376+
4a4d8108
AM
10377+/* ---------------------------------------------------------------------- */
10378+
10379+/* dynop.c */
10380+struct au_branch;
10381+void au_dy_put(struct au_dykey *key);
10382+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10383+ struct inode *h_inode);
b752ccd1 10384+int au_dy_irefresh(struct inode *inode);
4a4d8108 10385+void au_dy_arefresh(int do_dio);
4a4d8108
AM
10386+
10387+void __init au_dy_init(void);
10388+void au_dy_fin(void);
10389+
4a4d8108
AM
10390+#endif /* __KERNEL__ */
10391+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
10392diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
10393--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 10394+++ linux/fs/aufs/export.c 2015-04-13 15:10:20.783490201 +0200
523b37e3 10395@@ -0,0 +1,831 @@
4a4d8108 10396+/*
2000de60 10397+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
10398+ *
10399+ * This program, aufs is free software; you can redistribute it and/or modify
10400+ * it under the terms of the GNU General Public License as published by
10401+ * the Free Software Foundation; either version 2 of the License, or
10402+ * (at your option) any later version.
10403+ *
10404+ * This program is distributed in the hope that it will be useful,
10405+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10406+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10407+ * GNU General Public License for more details.
10408+ *
10409+ * You should have received a copy of the GNU General Public License
523b37e3 10410+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10411+ */
10412+
10413+/*
10414+ * export via nfs
10415+ */
10416+
10417+#include <linux/exportfs.h>
7eafdf33 10418+#include <linux/fs_struct.h>
4a4d8108
AM
10419+#include <linux/namei.h>
10420+#include <linux/nsproxy.h>
10421+#include <linux/random.h>
10422+#include <linux/writeback.h>
7eafdf33 10423+#include "../fs/mount.h"
4a4d8108
AM
10424+#include "aufs.h"
10425+
10426+union conv {
10427+#ifdef CONFIG_AUFS_INO_T_64
10428+ __u32 a[2];
10429+#else
10430+ __u32 a[1];
10431+#endif
10432+ ino_t ino;
10433+};
10434+
10435+static ino_t decode_ino(__u32 *a)
10436+{
10437+ union conv u;
10438+
10439+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
10440+ u.a[0] = a[0];
10441+#ifdef CONFIG_AUFS_INO_T_64
10442+ u.a[1] = a[1];
10443+#endif
10444+ return u.ino;
10445+}
10446+
10447+static void encode_ino(__u32 *a, ino_t ino)
10448+{
10449+ union conv u;
10450+
10451+ u.ino = ino;
10452+ a[0] = u.a[0];
10453+#ifdef CONFIG_AUFS_INO_T_64
10454+ a[1] = u.a[1];
10455+#endif
10456+}
10457+
10458+/* NFS file handle */
10459+enum {
10460+ Fh_br_id,
10461+ Fh_sigen,
10462+#ifdef CONFIG_AUFS_INO_T_64
10463+ /* support 64bit inode number */
10464+ Fh_ino1,
10465+ Fh_ino2,
10466+ Fh_dir_ino1,
10467+ Fh_dir_ino2,
10468+#else
10469+ Fh_ino1,
10470+ Fh_dir_ino1,
10471+#endif
10472+ Fh_igen,
10473+ Fh_h_type,
10474+ Fh_tail,
10475+
10476+ Fh_ino = Fh_ino1,
10477+ Fh_dir_ino = Fh_dir_ino1
10478+};
10479+
10480+static int au_test_anon(struct dentry *dentry)
10481+{
027c5e7a 10482+ /* note: read d_flags without d_lock */
4a4d8108
AM
10483+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
10484+}
10485+
a2a7ad62
AM
10486+int au_test_nfsd(void)
10487+{
10488+ int ret;
10489+ struct task_struct *tsk = current;
10490+ char comm[sizeof(tsk->comm)];
10491+
10492+ ret = 0;
10493+ if (tsk->flags & PF_KTHREAD) {
10494+ get_task_comm(comm, tsk);
10495+ ret = !strcmp(comm, "nfsd");
10496+ }
10497+
10498+ return ret;
10499+}
10500+
4a4d8108
AM
10501+/* ---------------------------------------------------------------------- */
10502+/* inode generation external table */
10503+
b752ccd1 10504+void au_xigen_inc(struct inode *inode)
4a4d8108 10505+{
4a4d8108
AM
10506+ loff_t pos;
10507+ ssize_t sz;
10508+ __u32 igen;
10509+ struct super_block *sb;
10510+ struct au_sbinfo *sbinfo;
10511+
4a4d8108 10512+ sb = inode->i_sb;
b752ccd1 10513+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 10514+
b752ccd1 10515+ sbinfo = au_sbi(sb);
1facf9fc 10516+ pos = inode->i_ino;
10517+ pos *= sizeof(igen);
10518+ igen = inode->i_generation + 1;
1facf9fc 10519+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
10520+ sizeof(igen), &pos);
10521+ if (sz == sizeof(igen))
b752ccd1 10522+ return; /* success */
1facf9fc 10523+
b752ccd1 10524+ if (unlikely(sz >= 0))
1facf9fc 10525+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 10526+}
10527+
10528+int au_xigen_new(struct inode *inode)
10529+{
10530+ int err;
10531+ loff_t pos;
10532+ ssize_t sz;
10533+ struct super_block *sb;
10534+ struct au_sbinfo *sbinfo;
10535+ struct file *file;
10536+
10537+ err = 0;
10538+ /* todo: dirty, at mount time */
10539+ if (inode->i_ino == AUFS_ROOT_INO)
10540+ goto out;
10541+ sb = inode->i_sb;
dece6358 10542+ SiMustAnyLock(sb);
1facf9fc 10543+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10544+ goto out;
10545+
10546+ err = -EFBIG;
10547+ pos = inode->i_ino;
10548+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
10549+ AuIOErr1("too large i%lld\n", pos);
10550+ goto out;
10551+ }
10552+ pos *= sizeof(inode->i_generation);
10553+
10554+ err = 0;
10555+ sbinfo = au_sbi(sb);
10556+ file = sbinfo->si_xigen;
10557+ BUG_ON(!file);
10558+
c06a8ce3 10559+ if (vfsub_f_size_read(file)
1facf9fc 10560+ < pos + sizeof(inode->i_generation)) {
10561+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
10562+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
10563+ sizeof(inode->i_generation), &pos);
10564+ } else
10565+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
10566+ sizeof(inode->i_generation), &pos);
10567+ if (sz == sizeof(inode->i_generation))
10568+ goto out; /* success */
10569+
10570+ err = sz;
10571+ if (unlikely(sz >= 0)) {
10572+ err = -EIO;
10573+ AuIOErr("xigen error (%zd)\n", sz);
10574+ }
10575+
4f0767ce 10576+out:
1facf9fc 10577+ return err;
10578+}
10579+
10580+int au_xigen_set(struct super_block *sb, struct file *base)
10581+{
10582+ int err;
10583+ struct au_sbinfo *sbinfo;
10584+ struct file *file;
10585+
dece6358
AM
10586+ SiMustWriteLock(sb);
10587+
1facf9fc 10588+ sbinfo = au_sbi(sb);
10589+ file = au_xino_create2(base, sbinfo->si_xigen);
10590+ err = PTR_ERR(file);
10591+ if (IS_ERR(file))
10592+ goto out;
10593+ err = 0;
10594+ if (sbinfo->si_xigen)
10595+ fput(sbinfo->si_xigen);
10596+ sbinfo->si_xigen = file;
10597+
4f0767ce 10598+out:
1facf9fc 10599+ return err;
10600+}
10601+
10602+void au_xigen_clr(struct super_block *sb)
10603+{
10604+ struct au_sbinfo *sbinfo;
10605+
dece6358
AM
10606+ SiMustWriteLock(sb);
10607+
1facf9fc 10608+ sbinfo = au_sbi(sb);
10609+ if (sbinfo->si_xigen) {
10610+ fput(sbinfo->si_xigen);
10611+ sbinfo->si_xigen = NULL;
10612+ }
10613+}
10614+
10615+/* ---------------------------------------------------------------------- */
10616+
10617+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
10618+ ino_t dir_ino)
10619+{
10620+ struct dentry *dentry, *d;
10621+ struct inode *inode;
10622+ unsigned int sigen;
10623+
10624+ dentry = NULL;
10625+ inode = ilookup(sb, ino);
10626+ if (!inode)
10627+ goto out;
10628+
10629+ dentry = ERR_PTR(-ESTALE);
10630+ sigen = au_sigen(sb);
10631+ if (unlikely(is_bad_inode(inode)
10632+ || IS_DEADDIR(inode)
537831f9 10633+ || sigen != au_iigen(inode, NULL)))
1facf9fc 10634+ goto out_iput;
10635+
10636+ dentry = NULL;
10637+ if (!dir_ino || S_ISDIR(inode->i_mode))
10638+ dentry = d_find_alias(inode);
10639+ else {
027c5e7a 10640+ spin_lock(&inode->i_lock);
c1595e42 10641+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 10642+ spin_lock(&d->d_lock);
1facf9fc 10643+ if (!au_test_anon(d)
10644+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
10645+ dentry = dget_dlock(d);
10646+ spin_unlock(&d->d_lock);
1facf9fc 10647+ break;
10648+ }
027c5e7a
AM
10649+ spin_unlock(&d->d_lock);
10650+ }
10651+ spin_unlock(&inode->i_lock);
1facf9fc 10652+ }
027c5e7a 10653+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 10654+ /* need to refresh */
1facf9fc 10655+ dput(dentry);
2cbb1c4b 10656+ dentry = NULL;
1facf9fc 10657+ }
10658+
4f0767ce 10659+out_iput:
1facf9fc 10660+ iput(inode);
4f0767ce 10661+out:
2cbb1c4b 10662+ AuTraceErrPtr(dentry);
1facf9fc 10663+ return dentry;
10664+}
10665+
10666+/* ---------------------------------------------------------------------- */
10667+
10668+/* todo: dirty? */
10669+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
10670+
10671+struct au_compare_mnt_args {
10672+ /* input */
10673+ struct super_block *sb;
10674+
10675+ /* output */
10676+ struct vfsmount *mnt;
10677+};
10678+
10679+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
10680+{
10681+ struct au_compare_mnt_args *a = arg;
10682+
10683+ if (mnt->mnt_sb != a->sb)
10684+ return 0;
10685+ a->mnt = mntget(mnt);
10686+ return 1;
10687+}
10688+
1facf9fc 10689+static struct vfsmount *au_mnt_get(struct super_block *sb)
10690+{
4a4d8108 10691+ int err;
7eafdf33 10692+ struct path root;
4a4d8108
AM
10693+ struct au_compare_mnt_args args = {
10694+ .sb = sb
10695+ };
1facf9fc 10696+
7eafdf33 10697+ get_fs_root(current->fs, &root);
523b37e3 10698+ rcu_read_lock();
7eafdf33 10699+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 10700+ rcu_read_unlock();
7eafdf33 10701+ path_put(&root);
4a4d8108
AM
10702+ AuDebugOn(!err);
10703+ AuDebugOn(!args.mnt);
10704+ return args.mnt;
1facf9fc 10705+}
10706+
10707+struct au_nfsd_si_lock {
4a4d8108 10708+ unsigned int sigen;
027c5e7a 10709+ aufs_bindex_t bindex, br_id;
1facf9fc 10710+ unsigned char force_lock;
10711+};
10712+
027c5e7a
AM
10713+static int si_nfsd_read_lock(struct super_block *sb,
10714+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10715+{
027c5e7a 10716+ int err;
1facf9fc 10717+ aufs_bindex_t bindex;
10718+
10719+ si_read_lock(sb, AuLock_FLUSH);
10720+
10721+ /* branch id may be wrapped around */
027c5e7a 10722+ err = 0;
1facf9fc 10723+ bindex = au_br_index(sb, nsi_lock->br_id);
10724+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
10725+ goto out; /* success */
10726+
027c5e7a
AM
10727+ err = -ESTALE;
10728+ bindex = -1;
1facf9fc 10729+ if (!nsi_lock->force_lock)
10730+ si_read_unlock(sb);
1facf9fc 10731+
4f0767ce 10732+out:
027c5e7a
AM
10733+ nsi_lock->bindex = bindex;
10734+ return err;
1facf9fc 10735+}
10736+
10737+struct find_name_by_ino {
392086de 10738+ struct dir_context ctx;
1facf9fc 10739+ int called, found;
10740+ ino_t ino;
10741+ char *name;
10742+ int namelen;
10743+};
10744+
10745+static int
392086de
AM
10746+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
10747+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 10748+{
392086de
AM
10749+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
10750+ ctx);
1facf9fc 10751+
10752+ a->called++;
10753+ if (a->ino != ino)
10754+ return 0;
10755+
10756+ memcpy(a->name, name, namelen);
10757+ a->namelen = namelen;
10758+ a->found = 1;
10759+ return 1;
10760+}
10761+
10762+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
10763+ struct au_nfsd_si_lock *nsi_lock)
10764+{
10765+ struct dentry *dentry, *parent;
10766+ struct file *file;
10767+ struct inode *dir;
392086de
AM
10768+ struct find_name_by_ino arg = {
10769+ .ctx = {
2000de60 10770+ .actor = find_name_by_ino
392086de
AM
10771+ }
10772+ };
1facf9fc 10773+ int err;
10774+
10775+ parent = path->dentry;
10776+ if (nsi_lock)
10777+ si_read_unlock(parent->d_sb);
4a4d8108 10778+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 10779+ dentry = (void *)file;
10780+ if (IS_ERR(file))
10781+ goto out;
10782+
10783+ dentry = ERR_PTR(-ENOMEM);
537831f9 10784+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 10785+ if (unlikely(!arg.name))
10786+ goto out_file;
10787+ arg.ino = ino;
10788+ arg.found = 0;
10789+ do {
10790+ arg.called = 0;
10791+ /* smp_mb(); */
392086de 10792+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 10793+ } while (!err && !arg.found && arg.called);
10794+ dentry = ERR_PTR(err);
10795+ if (unlikely(err))
10796+ goto out_name;
1716fcea
AM
10797+ /* instead of ENOENT */
10798+ dentry = ERR_PTR(-ESTALE);
1facf9fc 10799+ if (!arg.found)
10800+ goto out_name;
10801+
b4510431 10802+ /* do not call vfsub_lkup_one() */
1facf9fc 10803+ dir = parent->d_inode;
10804+ mutex_lock(&dir->i_mutex);
10805+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
10806+ mutex_unlock(&dir->i_mutex);
10807+ AuTraceErrPtr(dentry);
10808+ if (IS_ERR(dentry))
10809+ goto out_name;
10810+ AuDebugOn(au_test_anon(dentry));
10811+ if (unlikely(!dentry->d_inode)) {
10812+ dput(dentry);
10813+ dentry = ERR_PTR(-ENOENT);
10814+ }
10815+
4f0767ce 10816+out_name:
537831f9 10817+ free_page((unsigned long)arg.name);
4f0767ce 10818+out_file:
1facf9fc 10819+ fput(file);
4f0767ce 10820+out:
1facf9fc 10821+ if (unlikely(nsi_lock
10822+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
10823+ if (!IS_ERR(dentry)) {
10824+ dput(dentry);
10825+ dentry = ERR_PTR(-ESTALE);
10826+ }
10827+ AuTraceErrPtr(dentry);
10828+ return dentry;
10829+}
10830+
10831+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
10832+ ino_t dir_ino,
10833+ struct au_nfsd_si_lock *nsi_lock)
10834+{
10835+ struct dentry *dentry;
10836+ struct path path;
10837+
10838+ if (dir_ino != AUFS_ROOT_INO) {
10839+ path.dentry = decode_by_ino(sb, dir_ino, 0);
10840+ dentry = path.dentry;
10841+ if (!path.dentry || IS_ERR(path.dentry))
10842+ goto out;
10843+ AuDebugOn(au_test_anon(path.dentry));
10844+ } else
10845+ path.dentry = dget(sb->s_root);
10846+
10847+ path.mnt = au_mnt_get(sb);
10848+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
10849+ path_put(&path);
10850+
4f0767ce 10851+out:
1facf9fc 10852+ AuTraceErrPtr(dentry);
10853+ return dentry;
10854+}
10855+
10856+/* ---------------------------------------------------------------------- */
10857+
10858+static int h_acceptable(void *expv, struct dentry *dentry)
10859+{
10860+ return 1;
10861+}
10862+
10863+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
10864+ char *buf, int len, struct super_block *sb)
10865+{
10866+ char *p;
10867+ int n;
10868+ struct path path;
10869+
10870+ p = d_path(h_rootpath, buf, len);
10871+ if (IS_ERR(p))
10872+ goto out;
10873+ n = strlen(p);
10874+
10875+ path.mnt = h_rootpath->mnt;
10876+ path.dentry = h_parent;
10877+ p = d_path(&path, buf, len);
10878+ if (IS_ERR(p))
10879+ goto out;
10880+ if (n != 1)
10881+ p += n;
10882+
10883+ path.mnt = au_mnt_get(sb);
10884+ path.dentry = sb->s_root;
10885+ p = d_path(&path, buf, len - strlen(p));
10886+ mntput(path.mnt);
10887+ if (IS_ERR(p))
10888+ goto out;
10889+ if (n != 1)
10890+ p[strlen(p)] = '/';
10891+
4f0767ce 10892+out:
1facf9fc 10893+ AuTraceErrPtr(p);
10894+ return p;
10895+}
10896+
10897+static
027c5e7a
AM
10898+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
10899+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10900+{
10901+ struct dentry *dentry, *h_parent, *root;
10902+ struct super_block *h_sb;
10903+ char *pathname, *p;
10904+ struct vfsmount *h_mnt;
10905+ struct au_branch *br;
10906+ int err;
10907+ struct path path;
10908+
027c5e7a 10909+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 10910+ h_mnt = au_br_mnt(br);
1facf9fc 10911+ h_sb = h_mnt->mnt_sb;
10912+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
10913+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
10914+ fh_len - Fh_tail, fh[Fh_h_type],
10915+ h_acceptable, /*context*/NULL);
10916+ dentry = h_parent;
10917+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
10918+ AuWarn1("%s decode_fh failed, %ld\n",
10919+ au_sbtype(h_sb), PTR_ERR(h_parent));
10920+ goto out;
10921+ }
10922+ dentry = NULL;
10923+ if (unlikely(au_test_anon(h_parent))) {
10924+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
10925+ au_sbtype(h_sb));
10926+ goto out_h_parent;
10927+ }
10928+
10929+ dentry = ERR_PTR(-ENOMEM);
10930+ pathname = (void *)__get_free_page(GFP_NOFS);
10931+ if (unlikely(!pathname))
10932+ goto out_h_parent;
10933+
10934+ root = sb->s_root;
10935+ path.mnt = h_mnt;
10936+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 10937+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 10938+ di_read_unlock(root, !AuLock_IR);
10939+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
10940+ dentry = (void *)p;
10941+ if (IS_ERR(p))
10942+ goto out_pathname;
10943+
10944+ si_read_unlock(sb);
10945+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
10946+ dentry = ERR_PTR(err);
10947+ if (unlikely(err))
10948+ goto out_relock;
10949+
10950+ dentry = ERR_PTR(-ENOENT);
10951+ AuDebugOn(au_test_anon(path.dentry));
10952+ if (unlikely(!path.dentry->d_inode))
10953+ goto out_path;
10954+
10955+ if (ino != path.dentry->d_inode->i_ino)
10956+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
10957+ else
10958+ dentry = dget(path.dentry);
10959+
4f0767ce 10960+out_path:
1facf9fc 10961+ path_put(&path);
4f0767ce 10962+out_relock:
1facf9fc 10963+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
10964+ if (!IS_ERR(dentry)) {
10965+ dput(dentry);
10966+ dentry = ERR_PTR(-ESTALE);
10967+ }
4f0767ce 10968+out_pathname:
1facf9fc 10969+ free_page((unsigned long)pathname);
4f0767ce 10970+out_h_parent:
1facf9fc 10971+ dput(h_parent);
4f0767ce 10972+out:
1facf9fc 10973+ AuTraceErrPtr(dentry);
10974+ return dentry;
10975+}
10976+
10977+/* ---------------------------------------------------------------------- */
10978+
10979+static struct dentry *
10980+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
10981+ int fh_type)
10982+{
10983+ struct dentry *dentry;
10984+ __u32 *fh = fid->raw;
027c5e7a 10985+ struct au_branch *br;
1facf9fc 10986+ ino_t ino, dir_ino;
1facf9fc 10987+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 10988+ .force_lock = 0
10989+ };
10990+
1facf9fc 10991+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
10992+ /* it should never happen, but the file handle is unreliable */
10993+ if (unlikely(fh_len < Fh_tail))
10994+ goto out;
10995+ nsi_lock.sigen = fh[Fh_sigen];
10996+ nsi_lock.br_id = fh[Fh_br_id];
10997+
1facf9fc 10998+ /* branch id may be wrapped around */
027c5e7a
AM
10999+ br = NULL;
11000+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 11001+ goto out;
11002+ nsi_lock.force_lock = 1;
11003+
11004+ /* is this inode still cached? */
11005+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
11006+ /* it should never happen */
11007+ if (unlikely(ino == AUFS_ROOT_INO))
11008+ goto out;
11009+
1facf9fc 11010+ dir_ino = decode_ino(fh + Fh_dir_ino);
11011+ dentry = decode_by_ino(sb, ino, dir_ino);
11012+ if (IS_ERR(dentry))
11013+ goto out_unlock;
11014+ if (dentry)
11015+ goto accept;
11016+
11017+ /* is the parent dir cached? */
027c5e7a
AM
11018+ br = au_sbr(sb, nsi_lock.bindex);
11019+ atomic_inc(&br->br_count);
1facf9fc 11020+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
11021+ if (IS_ERR(dentry))
11022+ goto out_unlock;
11023+ if (dentry)
11024+ goto accept;
11025+
11026+ /* lookup path */
027c5e7a 11027+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 11028+ if (IS_ERR(dentry))
11029+ goto out_unlock;
11030+ if (unlikely(!dentry))
11031+ /* todo?: make it ESTALE */
11032+ goto out_unlock;
11033+
4f0767ce 11034+accept:
027c5e7a
AM
11035+ if (!au_digen_test(dentry, au_sigen(sb))
11036+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 11037+ goto out_unlock; /* success */
11038+
11039+ dput(dentry);
11040+ dentry = ERR_PTR(-ESTALE);
4f0767ce 11041+out_unlock:
027c5e7a
AM
11042+ if (br)
11043+ atomic_dec(&br->br_count);
1facf9fc 11044+ si_read_unlock(sb);
4f0767ce 11045+out:
1facf9fc 11046+ AuTraceErrPtr(dentry);
11047+ return dentry;
11048+}
11049+
11050+#if 0 /* reserved for future use */
11051+/* support subtreecheck option */
11052+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
11053+ int fh_len, int fh_type)
11054+{
11055+ struct dentry *parent;
11056+ __u32 *fh = fid->raw;
11057+ ino_t dir_ino;
11058+
11059+ dir_ino = decode_ino(fh + Fh_dir_ino);
11060+ parent = decode_by_ino(sb, dir_ino, 0);
11061+ if (IS_ERR(parent))
11062+ goto out;
11063+ if (!parent)
11064+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
11065+ dir_ino, fh, fh_len);
11066+
4f0767ce 11067+out:
1facf9fc 11068+ AuTraceErrPtr(parent);
11069+ return parent;
11070+}
11071+#endif
11072+
11073+/* ---------------------------------------------------------------------- */
11074+
0c3ec466
AM
11075+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
11076+ struct inode *dir)
1facf9fc 11077+{
11078+ int err;
0c3ec466 11079+ aufs_bindex_t bindex;
1facf9fc 11080+ struct super_block *sb, *h_sb;
0c3ec466
AM
11081+ struct dentry *dentry, *parent, *h_parent;
11082+ struct inode *h_dir;
1facf9fc 11083+ struct au_branch *br;
11084+
1facf9fc 11085+ err = -ENOSPC;
11086+ if (unlikely(*max_len <= Fh_tail)) {
11087+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
11088+ goto out;
11089+ }
11090+
11091+ err = FILEID_ROOT;
0c3ec466
AM
11092+ if (inode->i_ino == AUFS_ROOT_INO) {
11093+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 11094+ goto out;
11095+ }
11096+
1facf9fc 11097+ h_parent = NULL;
0c3ec466
AM
11098+ sb = inode->i_sb;
11099+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
11100+ if (unlikely(err))
11101+ goto out;
11102+
1facf9fc 11103+#ifdef CONFIG_AUFS_DEBUG
11104+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
11105+ AuWarn1("NFS-exporting requires xino\n");
11106+#endif
027c5e7a 11107+ err = -EIO;
0c3ec466
AM
11108+ parent = NULL;
11109+ ii_read_lock_child(inode);
11110+ bindex = au_ibstart(inode);
11111+ if (!dir) {
c1595e42 11112+ dentry = d_find_any_alias(inode);
0c3ec466
AM
11113+ if (unlikely(!dentry))
11114+ goto out_unlock;
11115+ AuDebugOn(au_test_anon(dentry));
11116+ parent = dget_parent(dentry);
11117+ dput(dentry);
11118+ if (unlikely(!parent))
11119+ goto out_unlock;
11120+ dir = parent->d_inode;
1facf9fc 11121+ }
0c3ec466
AM
11122+
11123+ ii_read_lock_parent(dir);
11124+ h_dir = au_h_iptr(dir, bindex);
11125+ ii_read_unlock(dir);
11126+ if (unlikely(!h_dir))
11127+ goto out_parent;
c1595e42 11128+ h_parent = d_find_any_alias(h_dir);
1facf9fc 11129+ if (unlikely(!h_parent))
0c3ec466 11130+ goto out_hparent;
1facf9fc 11131+
11132+ err = -EPERM;
11133+ br = au_sbr(sb, bindex);
86dc4139 11134+ h_sb = au_br_sb(br);
1facf9fc 11135+ if (unlikely(!h_sb->s_export_op)) {
11136+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 11137+ goto out_hparent;
1facf9fc 11138+ }
11139+
11140+ fh[Fh_br_id] = br->br_id;
11141+ fh[Fh_sigen] = au_sigen(sb);
11142+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 11143+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 11144+ fh[Fh_igen] = inode->i_generation;
11145+
11146+ *max_len -= Fh_tail;
11147+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
11148+ max_len,
11149+ /*connectable or subtreecheck*/0);
11150+ err = fh[Fh_h_type];
11151+ *max_len += Fh_tail;
11152+ /* todo: macros? */
1716fcea 11153+ if (err != FILEID_INVALID)
1facf9fc 11154+ err = 99;
11155+ else
11156+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
11157+
0c3ec466 11158+out_hparent:
1facf9fc 11159+ dput(h_parent);
0c3ec466 11160+out_parent:
1facf9fc 11161+ dput(parent);
0c3ec466
AM
11162+out_unlock:
11163+ ii_read_unlock(inode);
11164+ si_read_unlock(sb);
4f0767ce 11165+out:
1facf9fc 11166+ if (unlikely(err < 0))
1716fcea 11167+ err = FILEID_INVALID;
1facf9fc 11168+ return err;
11169+}
11170+
11171+/* ---------------------------------------------------------------------- */
11172+
4a4d8108
AM
11173+static int aufs_commit_metadata(struct inode *inode)
11174+{
11175+ int err;
11176+ aufs_bindex_t bindex;
11177+ struct super_block *sb;
11178+ struct inode *h_inode;
11179+ int (*f)(struct inode *inode);
11180+
11181+ sb = inode->i_sb;
e49829fe 11182+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11183+ ii_write_lock_child(inode);
11184+ bindex = au_ibstart(inode);
11185+ AuDebugOn(bindex < 0);
11186+ h_inode = au_h_iptr(inode, bindex);
11187+
11188+ f = h_inode->i_sb->s_export_op->commit_metadata;
11189+ if (f)
11190+ err = f(h_inode);
11191+ else {
11192+ struct writeback_control wbc = {
11193+ .sync_mode = WB_SYNC_ALL,
11194+ .nr_to_write = 0 /* metadata only */
11195+ };
11196+
11197+ err = sync_inode(h_inode, &wbc);
11198+ }
11199+
11200+ au_cpup_attr_timesizes(inode);
11201+ ii_write_unlock(inode);
11202+ si_read_unlock(sb);
11203+ return err;
11204+}
11205+
11206+/* ---------------------------------------------------------------------- */
11207+
1facf9fc 11208+static struct export_operations aufs_export_op = {
4a4d8108 11209+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 11210+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
11211+ .encode_fh = aufs_encode_fh,
11212+ .commit_metadata = aufs_commit_metadata
1facf9fc 11213+};
11214+
11215+void au_export_init(struct super_block *sb)
11216+{
11217+ struct au_sbinfo *sbinfo;
11218+ __u32 u;
11219+
11220+ sb->s_export_op = &aufs_export_op;
11221+ sbinfo = au_sbi(sb);
11222+ sbinfo->si_xigen = NULL;
11223+ get_random_bytes(&u, sizeof(u));
11224+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
11225+ atomic_set(&sbinfo->si_xigen_next, u);
11226+}
076b876e
AM
11227diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
11228--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 11229+++ linux/fs/aufs/fhsm.c 2015-04-13 15:10:20.783490201 +0200
c1595e42 11230@@ -0,0 +1,426 @@
076b876e 11231+/*
2000de60 11232+ * Copyright (C) 2011-2015 Junjiro R. Okajima
076b876e
AM
11233+ *
11234+ * This program, aufs is free software; you can redistribute it and/or modify
11235+ * it under the terms of the GNU General Public License as published by
11236+ * the Free Software Foundation; either version 2 of the License, or
11237+ * (at your option) any later version.
11238+ *
11239+ * This program is distributed in the hope that it will be useful,
11240+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11241+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11242+ * GNU General Public License for more details.
11243+ *
11244+ * You should have received a copy of the GNU General Public License
11245+ * along with this program; if not, write to the Free Software
11246+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11247+ */
11248+
11249+/*
11250+ * File-based Hierarchy Storage Management
11251+ */
11252+
11253+#include <linux/anon_inodes.h>
11254+#include <linux/poll.h>
11255+#include <linux/seq_file.h>
11256+#include <linux/statfs.h>
11257+#include "aufs.h"
11258+
c1595e42
JR
11259+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
11260+{
11261+ struct au_sbinfo *sbinfo;
11262+ struct au_fhsm *fhsm;
11263+
11264+ SiMustAnyLock(sb);
11265+
11266+ sbinfo = au_sbi(sb);
11267+ fhsm = &sbinfo->si_fhsm;
11268+ AuDebugOn(!fhsm);
11269+ return fhsm->fhsm_bottom;
11270+}
11271+
11272+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
11273+{
11274+ struct au_sbinfo *sbinfo;
11275+ struct au_fhsm *fhsm;
11276+
11277+ SiMustWriteLock(sb);
11278+
11279+ sbinfo = au_sbi(sb);
11280+ fhsm = &sbinfo->si_fhsm;
11281+ AuDebugOn(!fhsm);
11282+ fhsm->fhsm_bottom = bindex;
11283+}
11284+
11285+/* ---------------------------------------------------------------------- */
11286+
076b876e
AM
11287+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
11288+{
11289+ struct au_br_fhsm *bf;
11290+
11291+ bf = br->br_fhsm;
11292+ MtxMustLock(&bf->bf_lock);
11293+
11294+ return !bf->bf_readable
11295+ || time_after(jiffies,
11296+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
11297+}
11298+
11299+/* ---------------------------------------------------------------------- */
11300+
11301+static void au_fhsm_notify(struct super_block *sb, int val)
11302+{
11303+ struct au_sbinfo *sbinfo;
11304+ struct au_fhsm *fhsm;
11305+
11306+ SiMustAnyLock(sb);
11307+
11308+ sbinfo = au_sbi(sb);
11309+ fhsm = &sbinfo->si_fhsm;
11310+ if (au_fhsm_pid(fhsm)
11311+ && atomic_read(&fhsm->fhsm_readable) != -1) {
11312+ atomic_set(&fhsm->fhsm_readable, val);
11313+ if (val)
11314+ wake_up(&fhsm->fhsm_wqh);
11315+ }
11316+}
11317+
11318+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
11319+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
11320+{
11321+ int err;
11322+ struct au_branch *br;
11323+ struct au_br_fhsm *bf;
11324+
11325+ br = au_sbr(sb, bindex);
11326+ AuDebugOn(au_br_rdonly(br));
11327+ bf = br->br_fhsm;
11328+ AuDebugOn(!bf);
11329+
11330+ if (do_lock)
11331+ mutex_lock(&bf->bf_lock);
11332+ else
11333+ MtxMustLock(&bf->bf_lock);
11334+
11335+ /* sb->s_root for NFS is unreliable */
11336+ err = au_br_stfs(br, &bf->bf_stfs);
11337+ if (unlikely(err)) {
11338+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
11339+ goto out;
11340+ }
11341+
11342+ bf->bf_jiffy = jiffies;
11343+ bf->bf_readable = 1;
11344+ if (do_notify)
11345+ au_fhsm_notify(sb, /*val*/1);
11346+ if (rstfs)
11347+ *rstfs = bf->bf_stfs;
11348+
11349+out:
11350+ if (do_lock)
11351+ mutex_unlock(&bf->bf_lock);
11352+ au_fhsm_notify(sb, /*val*/1);
11353+
11354+ return err;
11355+}
11356+
11357+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
11358+{
11359+ int err;
076b876e
AM
11360+ struct au_sbinfo *sbinfo;
11361+ struct au_fhsm *fhsm;
11362+ struct au_branch *br;
11363+ struct au_br_fhsm *bf;
11364+
11365+ AuDbg("b%d, force %d\n", bindex, force);
11366+ SiMustAnyLock(sb);
11367+
11368+ sbinfo = au_sbi(sb);
11369+ fhsm = &sbinfo->si_fhsm;
c1595e42
JR
11370+ if (!au_ftest_si(sbinfo, FHSM)
11371+ || fhsm->fhsm_bottom == bindex)
076b876e
AM
11372+ return;
11373+
11374+ br = au_sbr(sb, bindex);
11375+ bf = br->br_fhsm;
11376+ AuDebugOn(!bf);
11377+ mutex_lock(&bf->bf_lock);
11378+ if (force
11379+ || au_fhsm_pid(fhsm)
11380+ || au_fhsm_test_jiffy(sbinfo, br))
11381+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
11382+ /*do_notify*/1);
11383+ mutex_unlock(&bf->bf_lock);
11384+}
11385+
11386+void au_fhsm_wrote_all(struct super_block *sb, int force)
11387+{
11388+ aufs_bindex_t bindex, bend;
11389+ struct au_branch *br;
11390+
11391+ /* exclude the bottom */
c1595e42 11392+ bend = au_fhsm_bottom(sb);
076b876e
AM
11393+ for (bindex = 0; bindex < bend; bindex++) {
11394+ br = au_sbr(sb, bindex);
11395+ if (au_br_fhsm(br->br_perm))
11396+ au_fhsm_wrote(sb, bindex, force);
11397+ }
11398+}
11399+
11400+/* ---------------------------------------------------------------------- */
11401+
11402+static unsigned int au_fhsm_poll(struct file *file,
11403+ struct poll_table_struct *wait)
11404+{
11405+ unsigned int mask;
11406+ struct au_sbinfo *sbinfo;
11407+ struct au_fhsm *fhsm;
11408+
11409+ mask = 0;
11410+ sbinfo = file->private_data;
11411+ fhsm = &sbinfo->si_fhsm;
11412+ poll_wait(file, &fhsm->fhsm_wqh, wait);
11413+ if (atomic_read(&fhsm->fhsm_readable))
11414+ mask = POLLIN /* | POLLRDNORM */;
11415+
11416+ AuTraceErr((int)mask);
11417+ return mask;
11418+}
11419+
11420+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
11421+ struct aufs_stfs *stfs, __s16 brid)
11422+{
11423+ int err;
11424+
11425+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
11426+ if (!err)
11427+ err = __put_user(brid, &stbr->brid);
11428+ if (unlikely(err))
11429+ err = -EFAULT;
11430+
11431+ return err;
11432+}
11433+
11434+static ssize_t au_fhsm_do_read(struct super_block *sb,
11435+ struct aufs_stbr __user *stbr, size_t count)
11436+{
11437+ ssize_t err;
11438+ int nstbr;
11439+ aufs_bindex_t bindex, bend;
11440+ struct au_branch *br;
11441+ struct au_br_fhsm *bf;
11442+
11443+ /* except the bottom branch */
11444+ err = 0;
11445+ nstbr = 0;
c1595e42 11446+ bend = au_fhsm_bottom(sb);
076b876e
AM
11447+ for (bindex = 0; !err && bindex < bend; bindex++) {
11448+ br = au_sbr(sb, bindex);
11449+ if (!au_br_fhsm(br->br_perm))
11450+ continue;
11451+
11452+ bf = br->br_fhsm;
11453+ mutex_lock(&bf->bf_lock);
11454+ if (bf->bf_readable) {
11455+ err = -EFAULT;
11456+ if (count >= sizeof(*stbr))
11457+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
11458+ br->br_id);
11459+ if (!err) {
11460+ bf->bf_readable = 0;
11461+ count -= sizeof(*stbr);
11462+ nstbr++;
11463+ }
11464+ }
11465+ mutex_unlock(&bf->bf_lock);
11466+ }
11467+ if (!err)
11468+ err = sizeof(*stbr) * nstbr;
11469+
11470+ return err;
11471+}
11472+
11473+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
11474+ loff_t *pos)
11475+{
11476+ ssize_t err;
11477+ int readable;
11478+ aufs_bindex_t nfhsm, bindex, bend;
11479+ struct au_sbinfo *sbinfo;
11480+ struct au_fhsm *fhsm;
11481+ struct au_branch *br;
11482+ struct super_block *sb;
11483+
11484+ err = 0;
11485+ sbinfo = file->private_data;
11486+ fhsm = &sbinfo->si_fhsm;
11487+need_data:
11488+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
11489+ if (!atomic_read(&fhsm->fhsm_readable)) {
11490+ if (vfsub_file_flags(file) & O_NONBLOCK)
11491+ err = -EAGAIN;
11492+ else
11493+ err = wait_event_interruptible_locked_irq
11494+ (fhsm->fhsm_wqh,
11495+ atomic_read(&fhsm->fhsm_readable));
11496+ }
11497+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
11498+ if (unlikely(err))
11499+ goto out;
11500+
11501+ /* sb may already be dead */
11502+ au_rw_read_lock(&sbinfo->si_rwsem);
11503+ readable = atomic_read(&fhsm->fhsm_readable);
11504+ if (readable > 0) {
11505+ sb = sbinfo->si_sb;
11506+ AuDebugOn(!sb);
11507+ /* exclude the bottom branch */
11508+ nfhsm = 0;
c1595e42 11509+ bend = au_fhsm_bottom(sb);
076b876e
AM
11510+ for (bindex = 0; bindex < bend; bindex++) {
11511+ br = au_sbr(sb, bindex);
11512+ if (au_br_fhsm(br->br_perm))
11513+ nfhsm++;
11514+ }
11515+ err = -EMSGSIZE;
11516+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
11517+ atomic_set(&fhsm->fhsm_readable, 0);
11518+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
11519+ count);
11520+ }
11521+ }
11522+ au_rw_read_unlock(&sbinfo->si_rwsem);
11523+ if (!readable)
11524+ goto need_data;
11525+
11526+out:
11527+ return err;
11528+}
11529+
11530+static int au_fhsm_release(struct inode *inode, struct file *file)
11531+{
11532+ struct au_sbinfo *sbinfo;
11533+ struct au_fhsm *fhsm;
11534+
11535+ /* sb may already be dead */
11536+ sbinfo = file->private_data;
11537+ fhsm = &sbinfo->si_fhsm;
11538+ spin_lock(&fhsm->fhsm_spin);
11539+ fhsm->fhsm_pid = 0;
11540+ spin_unlock(&fhsm->fhsm_spin);
11541+ kobject_put(&sbinfo->si_kobj);
11542+
11543+ return 0;
11544+}
11545+
11546+static const struct file_operations au_fhsm_fops = {
11547+ .owner = THIS_MODULE,
11548+ .llseek = noop_llseek,
11549+ .read = au_fhsm_read,
11550+ .poll = au_fhsm_poll,
11551+ .release = au_fhsm_release
11552+};
11553+
11554+int au_fhsm_fd(struct super_block *sb, int oflags)
11555+{
11556+ int err, fd;
11557+ struct au_sbinfo *sbinfo;
11558+ struct au_fhsm *fhsm;
11559+
11560+ err = -EPERM;
11561+ if (unlikely(!capable(CAP_SYS_ADMIN)))
11562+ goto out;
11563+
11564+ err = -EINVAL;
11565+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
11566+ goto out;
11567+
11568+ err = 0;
11569+ sbinfo = au_sbi(sb);
11570+ fhsm = &sbinfo->si_fhsm;
11571+ spin_lock(&fhsm->fhsm_spin);
11572+ if (!fhsm->fhsm_pid)
11573+ fhsm->fhsm_pid = current->pid;
11574+ else
11575+ err = -EBUSY;
11576+ spin_unlock(&fhsm->fhsm_spin);
11577+ if (unlikely(err))
11578+ goto out;
11579+
11580+ oflags |= O_RDONLY;
11581+ /* oflags |= FMODE_NONOTIFY; */
11582+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
11583+ err = fd;
11584+ if (unlikely(fd < 0))
11585+ goto out_pid;
11586+
11587+ /* succeed reglardless 'fhsm' status */
11588+ kobject_get(&sbinfo->si_kobj);
11589+ si_noflush_read_lock(sb);
11590+ if (au_ftest_si(sbinfo, FHSM))
11591+ au_fhsm_wrote_all(sb, /*force*/0);
11592+ si_read_unlock(sb);
11593+ goto out; /* success */
11594+
11595+out_pid:
11596+ spin_lock(&fhsm->fhsm_spin);
11597+ fhsm->fhsm_pid = 0;
11598+ spin_unlock(&fhsm->fhsm_spin);
11599+out:
11600+ AuTraceErr(err);
11601+ return err;
11602+}
11603+
11604+/* ---------------------------------------------------------------------- */
11605+
11606+int au_fhsm_br_alloc(struct au_branch *br)
11607+{
11608+ int err;
11609+
11610+ err = 0;
11611+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
11612+ if (br->br_fhsm)
11613+ au_br_fhsm_init(br->br_fhsm);
11614+ else
11615+ err = -ENOMEM;
11616+
11617+ return err;
11618+}
11619+
11620+/* ---------------------------------------------------------------------- */
11621+
11622+void au_fhsm_fin(struct super_block *sb)
11623+{
11624+ au_fhsm_notify(sb, /*val*/-1);
11625+}
11626+
11627+void au_fhsm_init(struct au_sbinfo *sbinfo)
11628+{
11629+ struct au_fhsm *fhsm;
11630+
11631+ fhsm = &sbinfo->si_fhsm;
11632+ spin_lock_init(&fhsm->fhsm_spin);
11633+ init_waitqueue_head(&fhsm->fhsm_wqh);
11634+ atomic_set(&fhsm->fhsm_readable, 0);
11635+ fhsm->fhsm_expire
11636+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
c1595e42 11637+ fhsm->fhsm_bottom = -1;
076b876e
AM
11638+}
11639+
11640+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
11641+{
11642+ sbinfo->si_fhsm.fhsm_expire
11643+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
11644+}
11645+
11646+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
11647+{
11648+ unsigned int u;
11649+
11650+ if (!au_ftest_si(sbinfo, FHSM))
11651+ return;
11652+
11653+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
11654+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
11655+ seq_printf(seq, ",fhsm_sec=%u", u);
11656+}
7f207e10
AM
11657diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
11658--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
11659+++ linux/fs/aufs/file.c 2015-04-13 15:10:20.783490201 +0200
11660@@ -0,0 +1,819 @@
1facf9fc 11661+/*
2000de60 11662+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 11663+ *
11664+ * This program, aufs is free software; you can redistribute it and/or modify
11665+ * it under the terms of the GNU General Public License as published by
11666+ * the Free Software Foundation; either version 2 of the License, or
11667+ * (at your option) any later version.
dece6358
AM
11668+ *
11669+ * This program is distributed in the hope that it will be useful,
11670+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11671+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11672+ * GNU General Public License for more details.
11673+ *
11674+ * You should have received a copy of the GNU General Public License
523b37e3 11675+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 11676+ */
11677+
11678+/*
4a4d8108 11679+ * handling file/dir, and address_space operation
1facf9fc 11680+ */
11681+
7eafdf33
AM
11682+#ifdef CONFIG_AUFS_DEBUG
11683+#include <linux/migrate.h>
11684+#endif
4a4d8108 11685+#include <linux/pagemap.h>
1facf9fc 11686+#include "aufs.h"
11687+
4a4d8108
AM
11688+/* drop flags for writing */
11689+unsigned int au_file_roflags(unsigned int flags)
11690+{
11691+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
11692+ flags |= O_RDONLY | O_NOATIME;
11693+ return flags;
11694+}
11695+
11696+/* common functions to regular file and dir */
11697+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 11698+ struct file *file, int force_wr)
1facf9fc 11699+{
1308ab2a 11700+ struct file *h_file;
4a4d8108
AM
11701+ struct dentry *h_dentry;
11702+ struct inode *h_inode;
11703+ struct super_block *sb;
11704+ struct au_branch *br;
11705+ struct path h_path;
11706+ int err, exec_flag;
1facf9fc 11707+
4a4d8108
AM
11708+ /* a race condition can happen between open and unlink/rmdir */
11709+ h_file = ERR_PTR(-ENOENT);
11710+ h_dentry = au_h_dptr(dentry, bindex);
b752ccd1 11711+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
11712+ goto out;
11713+ h_inode = h_dentry->d_inode;
b752ccd1 11714+ if (au_test_nfsd() && !h_inode)
4a4d8108 11715+ goto out;
027c5e7a
AM
11716+ spin_lock(&h_dentry->d_lock);
11717+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
11718+ || !h_inode
11719+ /* || !dentry->d_inode->i_nlink */
11720+ ;
11721+ spin_unlock(&h_dentry->d_lock);
11722+ if (unlikely(err))
4a4d8108 11723+ goto out;
1facf9fc 11724+
4a4d8108
AM
11725+ sb = dentry->d_sb;
11726+ br = au_sbr(sb, bindex);
11727+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 11728+ exec_flag = flags & __FMODE_EXEC;
86dc4139 11729+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
027c5e7a 11730+ goto out;
1facf9fc 11731+
4a4d8108 11732+ /* drop flags for writing */
392086de
AM
11733+ if (au_test_ro(sb, bindex, dentry->d_inode)) {
11734+ if (force_wr && !(flags & O_WRONLY))
11735+ force_wr = 0;
4a4d8108 11736+ flags = au_file_roflags(flags);
392086de
AM
11737+ if (force_wr) {
11738+ h_file = ERR_PTR(-EROFS);
11739+ flags = au_file_roflags(flags);
11740+ if (unlikely(vfsub_native_ro(h_inode)
11741+ || IS_APPEND(h_inode)))
11742+ goto out;
11743+ flags &= ~O_ACCMODE;
11744+ flags |= O_WRONLY;
11745+ }
11746+ }
4a4d8108
AM
11747+ flags &= ~O_CREAT;
11748+ atomic_inc(&br->br_count);
11749+ h_path.dentry = h_dentry;
86dc4139 11750+ h_path.mnt = au_br_mnt(br);
38d290e6 11751+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
11752+ if (IS_ERR(h_file))
11753+ goto out_br;
dece6358 11754+
4a4d8108
AM
11755+ if (exec_flag) {
11756+ err = deny_write_access(h_file);
11757+ if (unlikely(err)) {
11758+ fput(h_file);
11759+ h_file = ERR_PTR(err);
11760+ goto out_br;
11761+ }
11762+ }
953406b4 11763+ fsnotify_open(h_file);
4a4d8108 11764+ goto out; /* success */
1facf9fc 11765+
4f0767ce 11766+out_br:
4a4d8108 11767+ atomic_dec(&br->br_count);
4f0767ce 11768+out:
4a4d8108
AM
11769+ return h_file;
11770+}
1308ab2a 11771+
076b876e
AM
11772+static int au_cmoo(struct dentry *dentry)
11773+{
11774+ int err, cmoo;
11775+ unsigned int udba;
11776+ struct path h_path;
11777+ struct au_pin pin;
11778+ struct au_cp_generic cpg = {
11779+ .dentry = dentry,
11780+ .bdst = -1,
11781+ .bsrc = -1,
11782+ .len = -1,
11783+ .pin = &pin,
11784+ .flags = AuCpup_DTIME | AuCpup_HOPEN
11785+ };
7e9cd9fe 11786+ struct inode *delegated;
076b876e
AM
11787+ struct super_block *sb;
11788+ struct au_sbinfo *sbinfo;
11789+ struct au_fhsm *fhsm;
11790+ pid_t pid;
11791+ struct au_branch *br;
11792+ struct dentry *parent;
11793+ struct au_hinode *hdir;
11794+
11795+ DiMustWriteLock(dentry);
7e9cd9fe 11796+ IiMustWriteLock(dentry->d_inode);
076b876e
AM
11797+
11798+ err = 0;
11799+ if (IS_ROOT(dentry))
11800+ goto out;
11801+ cpg.bsrc = au_dbstart(dentry);
11802+ if (!cpg.bsrc)
11803+ goto out;
11804+
11805+ sb = dentry->d_sb;
11806+ sbinfo = au_sbi(sb);
11807+ fhsm = &sbinfo->si_fhsm;
11808+ pid = au_fhsm_pid(fhsm);
11809+ if (pid
11810+ && (current->pid == pid
11811+ || current->real_parent->pid == pid))
11812+ goto out;
11813+
11814+ br = au_sbr(sb, cpg.bsrc);
11815+ cmoo = au_br_cmoo(br->br_perm);
11816+ if (!cmoo)
11817+ goto out;
7e9cd9fe 11818+ if (!d_is_reg(dentry))
076b876e
AM
11819+ cmoo &= AuBrAttr_COO_ALL;
11820+ if (!cmoo)
11821+ goto out;
11822+
11823+ parent = dget_parent(dentry);
11824+ di_write_lock_parent(parent);
11825+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
11826+ cpg.bdst = err;
11827+ if (unlikely(err < 0)) {
11828+ err = 0; /* there is no upper writable branch */
11829+ goto out_dgrade;
11830+ }
11831+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
11832+
11833+ /* do not respect the coo attrib for the target branch */
11834+ err = au_cpup_dirs(dentry, cpg.bdst);
11835+ if (unlikely(err))
11836+ goto out_dgrade;
11837+
11838+ di_downgrade_lock(parent, AuLock_IR);
11839+ udba = au_opt_udba(sb);
11840+ err = au_pin(&pin, dentry, cpg.bdst, udba,
11841+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
11842+ if (unlikely(err))
11843+ goto out_parent;
11844+
11845+ err = au_sio_cpup_simple(&cpg);
11846+ au_unpin(&pin);
11847+ if (unlikely(err))
11848+ goto out_parent;
11849+ if (!(cmoo & AuBrWAttr_MOO))
11850+ goto out_parent; /* success */
11851+
11852+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
11853+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
11854+ if (unlikely(err))
11855+ goto out_parent;
11856+
11857+ h_path.mnt = au_br_mnt(br);
11858+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
11859+ hdir = au_hi(parent->d_inode, cpg.bsrc);
11860+ delegated = NULL;
11861+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
11862+ au_unpin(&pin);
11863+ /* todo: keep h_dentry or not? */
11864+ if (unlikely(err == -EWOULDBLOCK)) {
11865+ pr_warn("cannot retry for NFSv4 delegation"
11866+ " for an internal unlink\n");
11867+ iput(delegated);
11868+ }
11869+ if (unlikely(err)) {
11870+ pr_err("unlink %pd after coo failed (%d), ignored\n",
11871+ dentry, err);
11872+ err = 0;
11873+ }
11874+ goto out_parent; /* success */
11875+
11876+out_dgrade:
11877+ di_downgrade_lock(parent, AuLock_IR);
11878+out_parent:
11879+ di_read_unlock(parent, AuLock_IR);
11880+ dput(parent);
11881+out:
11882+ AuTraceErr(err);
11883+ return err;
11884+}
11885+
4a4d8108
AM
11886+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
11887+ struct au_fidir *fidir)
1facf9fc 11888+{
dece6358 11889+ int err;
1facf9fc 11890+ struct dentry *dentry;
076b876e 11891+ struct au_finfo *finfo;
1308ab2a 11892+
4a4d8108
AM
11893+ err = au_finfo_init(file, fidir);
11894+ if (unlikely(err))
11895+ goto out;
1facf9fc 11896+
2000de60 11897+ dentry = file->f_path.dentry;
076b876e
AM
11898+ di_write_lock_child(dentry);
11899+ err = au_cmoo(dentry);
11900+ di_downgrade_lock(dentry, AuLock_IR);
11901+ if (!err)
11902+ err = open(file, vfsub_file_flags(file));
4a4d8108 11903+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 11904+
076b876e
AM
11905+ finfo = au_fi(file);
11906+ if (!err) {
11907+ finfo->fi_file = file;
11908+ au_sphl_add(&finfo->fi_hlist,
2000de60 11909+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
076b876e 11910+ }
4a4d8108
AM
11911+ fi_write_unlock(file);
11912+ if (unlikely(err)) {
076b876e 11913+ finfo->fi_hdir = NULL;
4a4d8108 11914+ au_finfo_fin(file);
1308ab2a 11915+ }
4a4d8108 11916+
4f0767ce 11917+out:
1308ab2a 11918+ return err;
11919+}
dece6358 11920+
4a4d8108 11921+int au_reopen_nondir(struct file *file)
1308ab2a 11922+{
4a4d8108
AM
11923+ int err;
11924+ aufs_bindex_t bstart;
11925+ struct dentry *dentry;
11926+ struct file *h_file, *h_file_tmp;
1308ab2a 11927+
2000de60 11928+ dentry = file->f_path.dentry;
4a4d8108
AM
11929+ bstart = au_dbstart(dentry);
11930+ h_file_tmp = NULL;
11931+ if (au_fbstart(file) == bstart) {
11932+ h_file = au_hf_top(file);
11933+ if (file->f_mode == h_file->f_mode)
11934+ return 0; /* success */
11935+ h_file_tmp = h_file;
11936+ get_file(h_file_tmp);
11937+ au_set_h_fptr(file, bstart, NULL);
11938+ }
11939+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
11940+ /*
11941+ * it can happen
11942+ * file exists on both of rw and ro
11943+ * open --> dbstart and fbstart are both 0
11944+ * prepend a branch as rw, "rw" become ro
11945+ * remove rw/file
11946+ * delete the top branch, "rw" becomes rw again
11947+ * --> dbstart is 1, fbstart is still 0
11948+ * write --> fbstart is 0 but dbstart is 1
11949+ */
11950+ /* AuDebugOn(au_fbstart(file) < bstart); */
1308ab2a 11951+
4a4d8108 11952+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
392086de 11953+ file, /*force_wr*/0);
4a4d8108 11954+ err = PTR_ERR(h_file);
86dc4139
AM
11955+ if (IS_ERR(h_file)) {
11956+ if (h_file_tmp) {
11957+ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
11958+ au_set_h_fptr(file, bstart, h_file_tmp);
11959+ h_file_tmp = NULL;
11960+ }
4a4d8108 11961+ goto out; /* todo: close all? */
86dc4139 11962+ }
4a4d8108
AM
11963+
11964+ err = 0;
11965+ au_set_fbstart(file, bstart);
11966+ au_set_h_fptr(file, bstart, h_file);
11967+ au_update_figen(file);
11968+ /* todo: necessary? */
11969+ /* file->f_ra = h_file->f_ra; */
11970+
4f0767ce 11971+out:
4a4d8108
AM
11972+ if (h_file_tmp)
11973+ fput(h_file_tmp);
11974+ return err;
1facf9fc 11975+}
11976+
1308ab2a 11977+/* ---------------------------------------------------------------------- */
11978+
4a4d8108
AM
11979+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
11980+ struct dentry *hi_wh)
1facf9fc 11981+{
4a4d8108
AM
11982+ int err;
11983+ aufs_bindex_t bstart;
11984+ struct au_dinfo *dinfo;
11985+ struct dentry *h_dentry;
11986+ struct au_hdentry *hdp;
1facf9fc 11987+
2000de60 11988+ dinfo = au_di(file->f_path.dentry);
4a4d8108 11989+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 11990+
4a4d8108
AM
11991+ bstart = dinfo->di_bstart;
11992+ dinfo->di_bstart = btgt;
11993+ hdp = dinfo->di_hdentry;
11994+ h_dentry = hdp[0 + btgt].hd_dentry;
11995+ hdp[0 + btgt].hd_dentry = hi_wh;
11996+ err = au_reopen_nondir(file);
11997+ hdp[0 + btgt].hd_dentry = h_dentry;
11998+ dinfo->di_bstart = bstart;
1facf9fc 11999+
1facf9fc 12000+ return err;
12001+}
12002+
4a4d8108 12003+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 12004+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 12005+{
4a4d8108 12006+ int err;
027c5e7a 12007+ struct inode *inode, *h_inode;
c2b27bf2
AM
12008+ struct dentry *h_dentry, *hi_wh;
12009+ struct au_cp_generic cpg = {
2000de60 12010+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12011+ .bdst = bcpup,
12012+ .bsrc = -1,
12013+ .len = len,
12014+ .pin = pin
12015+ };
1facf9fc 12016+
c2b27bf2
AM
12017+ au_update_dbstart(cpg.dentry);
12018+ inode = cpg.dentry->d_inode;
027c5e7a 12019+ h_inode = NULL;
c2b27bf2
AM
12020+ if (au_dbstart(cpg.dentry) <= bcpup
12021+ && au_dbend(cpg.dentry) >= bcpup) {
12022+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
027c5e7a
AM
12023+ if (h_dentry)
12024+ h_inode = h_dentry->d_inode;
12025+ }
4a4d8108 12026+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 12027+ if (!hi_wh && !h_inode)
c2b27bf2 12028+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
12029+ else
12030+ /* already copied-up after unlink */
12031+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 12032+
4a4d8108 12033+ if (!err
38d290e6
JR
12034+ && (inode->i_nlink > 1
12035+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
12036+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
12037+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 12038+
dece6358 12039+ return err;
1facf9fc 12040+}
12041+
4a4d8108
AM
12042+/*
12043+ * prepare the @file for writing.
12044+ */
12045+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 12046+{
4a4d8108 12047+ int err;
c2b27bf2 12048+ aufs_bindex_t dbstart;
c1595e42 12049+ struct dentry *parent;
86dc4139 12050+ struct inode *inode;
1facf9fc 12051+ struct super_block *sb;
4a4d8108 12052+ struct file *h_file;
c2b27bf2 12053+ struct au_cp_generic cpg = {
2000de60 12054+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12055+ .bdst = -1,
12056+ .bsrc = -1,
12057+ .len = len,
12058+ .pin = pin,
12059+ .flags = AuCpup_DTIME
12060+ };
1facf9fc 12061+
c2b27bf2
AM
12062+ sb = cpg.dentry->d_sb;
12063+ inode = cpg.dentry->d_inode;
c2b27bf2
AM
12064+ cpg.bsrc = au_fbstart(file);
12065+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 12066+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
12067+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
12068+ /*flags*/0);
1facf9fc 12069+ goto out;
4a4d8108 12070+ }
1facf9fc 12071+
027c5e7a 12072+ /* need to cpup or reopen */
c2b27bf2 12073+ parent = dget_parent(cpg.dentry);
4a4d8108 12074+ di_write_lock_parent(parent);
c2b27bf2
AM
12075+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12076+ cpg.bdst = err;
4a4d8108
AM
12077+ if (unlikely(err < 0))
12078+ goto out_dgrade;
12079+ err = 0;
12080+
c2b27bf2
AM
12081+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
12082+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 12083+ if (unlikely(err))
4a4d8108
AM
12084+ goto out_dgrade;
12085+ }
12086+
c2b27bf2 12087+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
12088+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12089+ if (unlikely(err))
12090+ goto out_dgrade;
12091+
c2b27bf2 12092+ dbstart = au_dbstart(cpg.dentry);
c1595e42 12093+ if (dbstart <= cpg.bdst)
c2b27bf2 12094+ cpg.bsrc = cpg.bdst;
027c5e7a 12095+
c2b27bf2
AM
12096+ if (dbstart <= cpg.bdst /* just reopen */
12097+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 12098+ ) {
392086de 12099+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 12100+ if (IS_ERR(h_file))
027c5e7a 12101+ err = PTR_ERR(h_file);
86dc4139 12102+ else {
027c5e7a 12103+ di_downgrade_lock(parent, AuLock_IR);
c2b27bf2
AM
12104+ if (dbstart > cpg.bdst)
12105+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
12106+ if (!err)
12107+ err = au_reopen_nondir(file);
c2b27bf2 12108+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 12109+ }
027c5e7a
AM
12110+ } else { /* copyup as wh and reopen */
12111+ /*
12112+ * since writable hfsplus branch is not supported,
12113+ * h_open_pre/post() are unnecessary.
12114+ */
c2b27bf2 12115+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 12116+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 12117+ }
4a4d8108
AM
12118+
12119+ if (!err) {
12120+ au_pin_set_parent_lflag(pin, /*lflag*/0);
12121+ goto out_dput; /* success */
12122+ }
12123+ au_unpin(pin);
12124+ goto out_unlock;
1facf9fc 12125+
4f0767ce 12126+out_dgrade:
4a4d8108 12127+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 12128+out_unlock:
4a4d8108 12129+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12130+out_dput:
4a4d8108 12131+ dput(parent);
4f0767ce 12132+out:
1facf9fc 12133+ return err;
12134+}
12135+
4a4d8108
AM
12136+/* ---------------------------------------------------------------------- */
12137+
12138+int au_do_flush(struct file *file, fl_owner_t id,
12139+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 12140+{
4a4d8108 12141+ int err;
1facf9fc 12142+ struct super_block *sb;
4a4d8108 12143+ struct inode *inode;
1facf9fc 12144+
c06a8ce3
AM
12145+ inode = file_inode(file);
12146+ sb = inode->i_sb;
4a4d8108
AM
12147+ si_noflush_read_lock(sb);
12148+ fi_read_lock(file);
b752ccd1 12149+ ii_read_lock_child(inode);
1facf9fc 12150+
4a4d8108
AM
12151+ err = flush(file, id);
12152+ au_cpup_attr_timesizes(inode);
1facf9fc 12153+
b752ccd1 12154+ ii_read_unlock(inode);
4a4d8108 12155+ fi_read_unlock(file);
1308ab2a 12156+ si_read_unlock(sb);
dece6358 12157+ return err;
1facf9fc 12158+}
12159+
4a4d8108
AM
12160+/* ---------------------------------------------------------------------- */
12161+
12162+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 12163+{
4a4d8108 12164+ int err;
4a4d8108
AM
12165+ struct au_pin pin;
12166+ struct au_finfo *finfo;
c2b27bf2 12167+ struct dentry *parent, *hi_wh;
4a4d8108 12168+ struct inode *inode;
1facf9fc 12169+ struct super_block *sb;
c2b27bf2 12170+ struct au_cp_generic cpg = {
2000de60 12171+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12172+ .bdst = -1,
12173+ .bsrc = -1,
12174+ .len = -1,
12175+ .pin = &pin,
12176+ .flags = AuCpup_DTIME
12177+ };
1facf9fc 12178+
4a4d8108
AM
12179+ FiMustWriteLock(file);
12180+
12181+ err = 0;
12182+ finfo = au_fi(file);
c2b27bf2
AM
12183+ sb = cpg.dentry->d_sb;
12184+ inode = cpg.dentry->d_inode;
12185+ cpg.bdst = au_ibstart(inode);
12186+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 12187+ goto out;
dece6358 12188+
c2b27bf2
AM
12189+ parent = dget_parent(cpg.dentry);
12190+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 12191+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
12192+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12193+ cpg.bdst = err;
4a4d8108
AM
12194+ di_read_unlock(parent, !AuLock_IR);
12195+ if (unlikely(err < 0))
12196+ goto out_parent;
12197+ err = 0;
1facf9fc 12198+ }
1facf9fc 12199+
4a4d8108 12200+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 12201+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
12202+ if (!S_ISDIR(inode->i_mode)
12203+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 12204+ && au_plink_test(inode)
c2b27bf2
AM
12205+ && !d_unhashed(cpg.dentry)
12206+ && cpg.bdst < au_dbstart(cpg.dentry)) {
12207+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
12208+ if (unlikely(err))
12209+ goto out_unlock;
12210+
12211+ /* always superio. */
c2b27bf2 12212+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 12213+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 12214+ if (!err) {
c2b27bf2 12215+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
12216+ au_unpin(&pin);
12217+ }
4a4d8108
AM
12218+ } else if (hi_wh) {
12219+ /* already copied-up after unlink */
c2b27bf2 12220+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
12221+ *need_reopen = 0;
12222+ }
1facf9fc 12223+
4f0767ce 12224+out_unlock:
4a4d8108 12225+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12226+out_parent:
4a4d8108 12227+ dput(parent);
4f0767ce 12228+out:
1308ab2a 12229+ return err;
dece6358 12230+}
1facf9fc 12231+
4a4d8108 12232+static void au_do_refresh_dir(struct file *file)
dece6358 12233+{
4a4d8108
AM
12234+ aufs_bindex_t bindex, bend, new_bindex, brid;
12235+ struct au_hfile *p, tmp, *q;
12236+ struct au_finfo *finfo;
1308ab2a 12237+ struct super_block *sb;
4a4d8108 12238+ struct au_fidir *fidir;
1facf9fc 12239+
4a4d8108 12240+ FiMustWriteLock(file);
1facf9fc 12241+
2000de60 12242+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
12243+ finfo = au_fi(file);
12244+ fidir = finfo->fi_hdir;
12245+ AuDebugOn(!fidir);
12246+ p = fidir->fd_hfile + finfo->fi_btop;
12247+ brid = p->hf_br->br_id;
12248+ bend = fidir->fd_bbot;
12249+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
12250+ if (!p->hf_file)
12251+ continue;
1308ab2a 12252+
4a4d8108
AM
12253+ new_bindex = au_br_index(sb, p->hf_br->br_id);
12254+ if (new_bindex == bindex)
12255+ continue;
12256+ if (new_bindex < 0) {
12257+ au_set_h_fptr(file, bindex, NULL);
12258+ continue;
12259+ }
1308ab2a 12260+
4a4d8108
AM
12261+ /* swap two lower inode, and loop again */
12262+ q = fidir->fd_hfile + new_bindex;
12263+ tmp = *q;
12264+ *q = *p;
12265+ *p = tmp;
12266+ if (tmp.hf_file) {
12267+ bindex--;
12268+ p--;
12269+ }
12270+ }
1308ab2a 12271+
4a4d8108 12272+ p = fidir->fd_hfile;
2000de60 12273+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
4a4d8108
AM
12274+ bend = au_sbend(sb);
12275+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
12276+ finfo->fi_btop++, p++)
12277+ if (p->hf_file) {
c06a8ce3 12278+ if (file_inode(p->hf_file))
4a4d8108 12279+ break;
c1595e42 12280+ au_hfput(p, file);
4a4d8108
AM
12281+ }
12282+ } else {
12283+ bend = au_br_index(sb, brid);
12284+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
12285+ finfo->fi_btop++, p++)
12286+ if (p->hf_file)
12287+ au_hfput(p, file);
12288+ bend = au_sbend(sb);
12289+ }
1308ab2a 12290+
4a4d8108
AM
12291+ p = fidir->fd_hfile + bend;
12292+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
12293+ fidir->fd_bbot--, p--)
12294+ if (p->hf_file) {
c06a8ce3 12295+ if (file_inode(p->hf_file))
4a4d8108 12296+ break;
c1595e42 12297+ au_hfput(p, file);
4a4d8108
AM
12298+ }
12299+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 12300+}
12301+
4a4d8108
AM
12302+/*
12303+ * after branch manipulating, refresh the file.
12304+ */
12305+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 12306+{
4a4d8108
AM
12307+ int err, need_reopen;
12308+ aufs_bindex_t bend, bindex;
12309+ struct dentry *dentry;
1308ab2a 12310+ struct au_finfo *finfo;
4a4d8108 12311+ struct au_hfile *hfile;
1facf9fc 12312+
2000de60 12313+ dentry = file->f_path.dentry;
1308ab2a 12314+ finfo = au_fi(file);
4a4d8108
AM
12315+ if (!finfo->fi_hdir) {
12316+ hfile = &finfo->fi_htop;
12317+ AuDebugOn(!hfile->hf_file);
12318+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
12319+ AuDebugOn(bindex < 0);
12320+ if (bindex != finfo->fi_btop)
12321+ au_set_fbstart(file, bindex);
12322+ } else {
12323+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
12324+ if (unlikely(err))
12325+ goto out;
12326+ au_do_refresh_dir(file);
12327+ }
1facf9fc 12328+
4a4d8108
AM
12329+ err = 0;
12330+ need_reopen = 1;
12331+ if (!au_test_mmapped(file))
12332+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 12333+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
12334+ err = reopen(file);
12335+ if (!err) {
12336+ au_update_figen(file);
12337+ goto out; /* success */
12338+ }
12339+
12340+ /* error, close all lower files */
12341+ if (finfo->fi_hdir) {
12342+ bend = au_fbend_dir(file);
12343+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
12344+ au_set_h_fptr(file, bindex, NULL);
12345+ }
1facf9fc 12346+
4f0767ce 12347+out:
1facf9fc 12348+ return err;
12349+}
12350+
4a4d8108
AM
12351+/* common function to regular file and dir */
12352+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12353+ int wlock)
dece6358 12354+{
1308ab2a 12355+ int err;
4a4d8108
AM
12356+ unsigned int sigen, figen;
12357+ aufs_bindex_t bstart;
12358+ unsigned char pseudo_link;
12359+ struct dentry *dentry;
12360+ struct inode *inode;
1facf9fc 12361+
4a4d8108 12362+ err = 0;
2000de60 12363+ dentry = file->f_path.dentry;
4a4d8108 12364+ inode = dentry->d_inode;
4a4d8108
AM
12365+ sigen = au_sigen(dentry->d_sb);
12366+ fi_write_lock(file);
12367+ figen = au_figen(file);
12368+ di_write_lock_child(dentry);
12369+ bstart = au_dbstart(dentry);
12370+ pseudo_link = (bstart != au_ibstart(inode));
12371+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
12372+ if (!wlock) {
12373+ di_downgrade_lock(dentry, AuLock_IR);
12374+ fi_downgrade_lock(file);
12375+ }
12376+ goto out; /* success */
12377+ }
dece6358 12378+
4a4d8108 12379+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 12380+ if (au_digen_test(dentry, sigen)) {
4a4d8108 12381+ err = au_reval_dpath(dentry, sigen);
027c5e7a 12382+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 12383+ }
dece6358 12384+
027c5e7a
AM
12385+ if (!err)
12386+ err = refresh_file(file, reopen);
4a4d8108
AM
12387+ if (!err) {
12388+ if (!wlock) {
12389+ di_downgrade_lock(dentry, AuLock_IR);
12390+ fi_downgrade_lock(file);
12391+ }
12392+ } else {
12393+ di_write_unlock(dentry);
12394+ fi_write_unlock(file);
12395+ }
1facf9fc 12396+
4f0767ce 12397+out:
1308ab2a 12398+ return err;
12399+}
1facf9fc 12400+
4a4d8108
AM
12401+/* ---------------------------------------------------------------------- */
12402+
12403+/* cf. aufs_nopage() */
12404+/* for madvise(2) */
12405+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 12406+{
4a4d8108
AM
12407+ unlock_page(page);
12408+ return 0;
12409+}
1facf9fc 12410+
4a4d8108
AM
12411+/* it will never be called, but necessary to support O_DIRECT */
12412+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
076b876e 12413+ struct iov_iter *iter, loff_t offset)
4a4d8108 12414+{ BUG(); return 0; }
1facf9fc 12415+
4a4d8108
AM
12416+/* they will never be called. */
12417+#ifdef CONFIG_AUFS_DEBUG
12418+static int aufs_write_begin(struct file *file, struct address_space *mapping,
12419+ loff_t pos, unsigned len, unsigned flags,
12420+ struct page **pagep, void **fsdata)
12421+{ AuUnsupport(); return 0; }
12422+static int aufs_write_end(struct file *file, struct address_space *mapping,
12423+ loff_t pos, unsigned len, unsigned copied,
12424+ struct page *page, void *fsdata)
12425+{ AuUnsupport(); return 0; }
12426+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
12427+{ AuUnsupport(); return 0; }
1308ab2a 12428+
4a4d8108
AM
12429+static int aufs_set_page_dirty(struct page *page)
12430+{ AuUnsupport(); return 0; }
392086de
AM
12431+static void aufs_invalidatepage(struct page *page, unsigned int offset,
12432+ unsigned int length)
4a4d8108
AM
12433+{ AuUnsupport(); }
12434+static int aufs_releasepage(struct page *page, gfp_t gfp)
12435+{ AuUnsupport(); return 0; }
12436+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 12437+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
12438+{ AuUnsupport(); return 0; }
12439+static int aufs_launder_page(struct page *page)
12440+{ AuUnsupport(); return 0; }
12441+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
12442+ unsigned long from,
12443+ unsigned long count)
4a4d8108 12444+{ AuUnsupport(); return 0; }
392086de
AM
12445+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
12446+ bool *writeback)
12447+{ AuUnsupport(); }
4a4d8108
AM
12448+static int aufs_error_remove_page(struct address_space *mapping,
12449+ struct page *page)
12450+{ AuUnsupport(); return 0; }
b4510431
AM
12451+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
12452+ sector_t *span)
12453+{ AuUnsupport(); return 0; }
12454+static void aufs_swap_deactivate(struct file *file)
12455+{ AuUnsupport(); }
4a4d8108
AM
12456+#endif /* CONFIG_AUFS_DEBUG */
12457+
12458+const struct address_space_operations aufs_aop = {
12459+ .readpage = aufs_readpage,
12460+ .direct_IO = aufs_direct_IO,
4a4d8108
AM
12461+#ifdef CONFIG_AUFS_DEBUG
12462+ .writepage = aufs_writepage,
4a4d8108
AM
12463+ /* no writepages, because of writepage */
12464+ .set_page_dirty = aufs_set_page_dirty,
12465+ /* no readpages, because of readpage */
12466+ .write_begin = aufs_write_begin,
12467+ .write_end = aufs_write_end,
12468+ /* no bmap, no block device */
12469+ .invalidatepage = aufs_invalidatepage,
12470+ .releasepage = aufs_releasepage,
12471+ .migratepage = aufs_migratepage,
12472+ .launder_page = aufs_launder_page,
12473+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 12474+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
12475+ .error_remove_page = aufs_error_remove_page,
12476+ .swap_activate = aufs_swap_activate,
12477+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 12478+#endif /* CONFIG_AUFS_DEBUG */
dece6358 12479+};
7f207e10
AM
12480diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
12481--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 12482+++ linux/fs/aufs/file.h 2015-04-13 15:10:20.783490201 +0200
c1595e42 12483@@ -0,0 +1,284 @@
4a4d8108 12484+/*
2000de60 12485+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
12486+ *
12487+ * This program, aufs is free software; you can redistribute it and/or modify
12488+ * it under the terms of the GNU General Public License as published by
12489+ * the Free Software Foundation; either version 2 of the License, or
12490+ * (at your option) any later version.
12491+ *
12492+ * This program is distributed in the hope that it will be useful,
12493+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12494+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12495+ * GNU General Public License for more details.
12496+ *
12497+ * You should have received a copy of the GNU General Public License
523b37e3 12498+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12499+ */
1facf9fc 12500+
4a4d8108
AM
12501+/*
12502+ * file operations
12503+ */
1facf9fc 12504+
4a4d8108
AM
12505+#ifndef __AUFS_FILE_H__
12506+#define __AUFS_FILE_H__
1facf9fc 12507+
4a4d8108 12508+#ifdef __KERNEL__
1facf9fc 12509+
2cbb1c4b 12510+#include <linux/file.h>
4a4d8108
AM
12511+#include <linux/fs.h>
12512+#include <linux/poll.h>
4a4d8108 12513+#include "rwsem.h"
1facf9fc 12514+
4a4d8108
AM
12515+struct au_branch;
12516+struct au_hfile {
12517+ struct file *hf_file;
12518+ struct au_branch *hf_br;
12519+};
1facf9fc 12520+
4a4d8108
AM
12521+struct au_vdir;
12522+struct au_fidir {
12523+ aufs_bindex_t fd_bbot;
12524+ aufs_bindex_t fd_nent;
12525+ struct au_vdir *fd_vdir_cache;
12526+ struct au_hfile fd_hfile[];
12527+};
1facf9fc 12528+
4a4d8108 12529+static inline int au_fidir_sz(int nent)
dece6358 12530+{
4f0767ce
JR
12531+ AuDebugOn(nent < 0);
12532+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 12533+}
1facf9fc 12534+
4a4d8108
AM
12535+struct au_finfo {
12536+ atomic_t fi_generation;
dece6358 12537+
4a4d8108
AM
12538+ struct au_rwsem fi_rwsem;
12539+ aufs_bindex_t fi_btop;
12540+
12541+ /* do not union them */
12542+ struct { /* for non-dir */
12543+ struct au_hfile fi_htop;
2cbb1c4b 12544+ atomic_t fi_mmapped;
4a4d8108
AM
12545+ };
12546+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3
AM
12547+
12548+ struct hlist_node fi_hlist;
12549+ struct file *fi_file; /* very ugly */
4a4d8108 12550+} ____cacheline_aligned_in_smp;
1facf9fc 12551+
4a4d8108 12552+/* ---------------------------------------------------------------------- */
1facf9fc 12553+
4a4d8108
AM
12554+/* file.c */
12555+extern const struct address_space_operations aufs_aop;
12556+unsigned int au_file_roflags(unsigned int flags);
12557+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 12558+ struct file *file, int force_wr);
4a4d8108
AM
12559+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
12560+ struct au_fidir *fidir);
12561+int au_reopen_nondir(struct file *file);
12562+struct au_pin;
12563+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
12564+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12565+ int wlock);
12566+int au_do_flush(struct file *file, fl_owner_t id,
12567+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 12568+
4a4d8108
AM
12569+/* poll.c */
12570+#ifdef CONFIG_AUFS_POLL
12571+unsigned int aufs_poll(struct file *file, poll_table *wait);
12572+#endif
1facf9fc 12573+
4a4d8108
AM
12574+#ifdef CONFIG_AUFS_BR_HFSPLUS
12575+/* hfsplus.c */
392086de
AM
12576+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
12577+ int force_wr);
4a4d8108
AM
12578+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
12579+ struct file *h_file);
12580+#else
c1595e42
JR
12581+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
12582+ aufs_bindex_t bindex, int force_wr)
4a4d8108
AM
12583+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
12584+ struct file *h_file);
12585+#endif
1facf9fc 12586+
4a4d8108
AM
12587+/* f_op.c */
12588+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
12589+int au_do_open_nondir(struct file *file, int flags);
12590+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
12591+
4a4d8108
AM
12592+/* finfo.c */
12593+void au_hfput(struct au_hfile *hf, struct file *file);
12594+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
12595+ struct file *h_file);
1facf9fc 12596+
4a4d8108 12597+void au_update_figen(struct file *file);
4a4d8108
AM
12598+struct au_fidir *au_fidir_alloc(struct super_block *sb);
12599+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 12600+
4a4d8108
AM
12601+void au_fi_init_once(void *_fi);
12602+void au_finfo_fin(struct file *file);
12603+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 12604+
4a4d8108
AM
12605+/* ioctl.c */
12606+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
12607+#ifdef CONFIG_COMPAT
12608+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
12609+ unsigned long arg);
c2b27bf2
AM
12610+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
12611+ unsigned long arg);
b752ccd1 12612+#endif
1facf9fc 12613+
4a4d8108 12614+/* ---------------------------------------------------------------------- */
1facf9fc 12615+
4a4d8108
AM
12616+static inline struct au_finfo *au_fi(struct file *file)
12617+{
38d290e6 12618+ return file->private_data;
4a4d8108 12619+}
1facf9fc 12620+
4a4d8108 12621+/* ---------------------------------------------------------------------- */
1facf9fc 12622+
4a4d8108
AM
12623+/*
12624+ * fi_read_lock, fi_write_lock,
12625+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
12626+ */
12627+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 12628+
4a4d8108
AM
12629+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
12630+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
12631+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 12632+
1308ab2a 12633+/* ---------------------------------------------------------------------- */
12634+
4a4d8108
AM
12635+/* todo: hard/soft set? */
12636+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 12637+{
4a4d8108
AM
12638+ FiMustAnyLock(file);
12639+ return au_fi(file)->fi_btop;
12640+}
dece6358 12641+
4a4d8108
AM
12642+static inline aufs_bindex_t au_fbend_dir(struct file *file)
12643+{
12644+ FiMustAnyLock(file);
12645+ AuDebugOn(!au_fi(file)->fi_hdir);
12646+ return au_fi(file)->fi_hdir->fd_bbot;
12647+}
1facf9fc 12648+
4a4d8108
AM
12649+static inline struct au_vdir *au_fvdir_cache(struct file *file)
12650+{
12651+ FiMustAnyLock(file);
12652+ AuDebugOn(!au_fi(file)->fi_hdir);
12653+ return au_fi(file)->fi_hdir->fd_vdir_cache;
12654+}
1facf9fc 12655+
4a4d8108
AM
12656+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
12657+{
12658+ FiMustWriteLock(file);
12659+ au_fi(file)->fi_btop = bindex;
12660+}
1facf9fc 12661+
4a4d8108
AM
12662+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
12663+{
12664+ FiMustWriteLock(file);
12665+ AuDebugOn(!au_fi(file)->fi_hdir);
12666+ au_fi(file)->fi_hdir->fd_bbot = bindex;
12667+}
1308ab2a 12668+
4a4d8108
AM
12669+static inline void au_set_fvdir_cache(struct file *file,
12670+ struct au_vdir *vdir_cache)
12671+{
12672+ FiMustWriteLock(file);
12673+ AuDebugOn(!au_fi(file)->fi_hdir);
12674+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
12675+}
dece6358 12676+
4a4d8108
AM
12677+static inline struct file *au_hf_top(struct file *file)
12678+{
12679+ FiMustAnyLock(file);
12680+ AuDebugOn(au_fi(file)->fi_hdir);
12681+ return au_fi(file)->fi_htop.hf_file;
12682+}
1facf9fc 12683+
4a4d8108
AM
12684+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
12685+{
12686+ FiMustAnyLock(file);
12687+ AuDebugOn(!au_fi(file)->fi_hdir);
12688+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
12689+}
12690+
4a4d8108
AM
12691+/* todo: memory barrier? */
12692+static inline unsigned int au_figen(struct file *f)
dece6358 12693+{
4a4d8108
AM
12694+ return atomic_read(&au_fi(f)->fi_generation);
12695+}
dece6358 12696+
2cbb1c4b
JR
12697+static inline void au_set_mmapped(struct file *f)
12698+{
12699+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
12700+ return;
0c3ec466 12701+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
12702+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
12703+ ;
12704+}
12705+
12706+static inline void au_unset_mmapped(struct file *f)
12707+{
12708+ atomic_dec(&au_fi(f)->fi_mmapped);
12709+}
12710+
4a4d8108
AM
12711+static inline int au_test_mmapped(struct file *f)
12712+{
2cbb1c4b
JR
12713+ return atomic_read(&au_fi(f)->fi_mmapped);
12714+}
12715+
12716+/* customize vma->vm_file */
12717+
12718+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
12719+ struct file *file)
12720+{
53392da6
AM
12721+ struct file *f;
12722+
12723+ f = vma->vm_file;
2cbb1c4b
JR
12724+ get_file(file);
12725+ vma->vm_file = file;
53392da6 12726+ fput(f);
2cbb1c4b
JR
12727+}
12728+
12729+#ifdef CONFIG_MMU
12730+#define AuDbgVmRegion(file, vma) do {} while (0)
12731+
12732+static inline void au_vm_file_reset(struct vm_area_struct *vma,
12733+ struct file *file)
12734+{
12735+ au_do_vm_file_reset(vma, file);
12736+}
12737+#else
12738+#define AuDbgVmRegion(file, vma) \
12739+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
12740+
12741+static inline void au_vm_file_reset(struct vm_area_struct *vma,
12742+ struct file *file)
12743+{
53392da6
AM
12744+ struct file *f;
12745+
2cbb1c4b 12746+ au_do_vm_file_reset(vma, file);
53392da6 12747+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
12748+ get_file(file);
12749+ vma->vm_region->vm_file = file;
53392da6 12750+ fput(f);
2cbb1c4b
JR
12751+}
12752+#endif /* CONFIG_MMU */
12753+
12754+/* handle vma->vm_prfile */
fb47a38f 12755+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
12756+ struct file *file)
12757+{
2cbb1c4b
JR
12758+ get_file(file);
12759+ vma->vm_prfile = file;
12760+#ifndef CONFIG_MMU
12761+ get_file(file);
12762+ vma->vm_region->vm_prfile = file;
12763+#endif
fb47a38f 12764+}
1308ab2a 12765+
4a4d8108
AM
12766+#endif /* __KERNEL__ */
12767+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
12768diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
12769--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 12770+++ linux/fs/aufs/finfo.c 2015-04-13 15:10:20.783490201 +0200
523b37e3 12771@@ -0,0 +1,156 @@
4a4d8108 12772+/*
2000de60 12773+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
12774+ *
12775+ * This program, aufs is free software; you can redistribute it and/or modify
12776+ * it under the terms of the GNU General Public License as published by
12777+ * the Free Software Foundation; either version 2 of the License, or
12778+ * (at your option) any later version.
12779+ *
12780+ * This program is distributed in the hope that it will be useful,
12781+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12782+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12783+ * GNU General Public License for more details.
12784+ *
12785+ * You should have received a copy of the GNU General Public License
523b37e3 12786+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12787+ */
1308ab2a 12788+
4a4d8108
AM
12789+/*
12790+ * file private data
12791+ */
1facf9fc 12792+
4a4d8108 12793+#include "aufs.h"
1facf9fc 12794+
4a4d8108
AM
12795+void au_hfput(struct au_hfile *hf, struct file *file)
12796+{
12797+ /* todo: direct access f_flags */
2cbb1c4b 12798+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
12799+ allow_write_access(hf->hf_file);
12800+ fput(hf->hf_file);
12801+ hf->hf_file = NULL;
e49829fe 12802+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
12803+ hf->hf_br = NULL;
12804+}
1facf9fc 12805+
4a4d8108
AM
12806+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
12807+{
12808+ struct au_finfo *finfo = au_fi(file);
12809+ struct au_hfile *hf;
12810+ struct au_fidir *fidir;
12811+
12812+ fidir = finfo->fi_hdir;
12813+ if (!fidir) {
12814+ AuDebugOn(finfo->fi_btop != bindex);
12815+ hf = &finfo->fi_htop;
12816+ } else
12817+ hf = fidir->fd_hfile + bindex;
12818+
12819+ if (hf && hf->hf_file)
12820+ au_hfput(hf, file);
12821+ if (val) {
12822+ FiMustWriteLock(file);
12823+ hf->hf_file = val;
2000de60 12824+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
1308ab2a 12825+ }
4a4d8108 12826+}
1facf9fc 12827+
4a4d8108
AM
12828+void au_update_figen(struct file *file)
12829+{
2000de60 12830+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
4a4d8108 12831+ /* smp_mb(); */ /* atomic_set */
1facf9fc 12832+}
12833+
4a4d8108
AM
12834+/* ---------------------------------------------------------------------- */
12835+
4a4d8108
AM
12836+struct au_fidir *au_fidir_alloc(struct super_block *sb)
12837+{
12838+ struct au_fidir *fidir;
12839+ int nbr;
12840+
12841+ nbr = au_sbend(sb) + 1;
12842+ if (nbr < 2)
12843+ nbr = 2; /* initial allocate for 2 branches */
12844+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
12845+ if (fidir) {
12846+ fidir->fd_bbot = -1;
12847+ fidir->fd_nent = nbr;
12848+ fidir->fd_vdir_cache = NULL;
12849+ }
12850+
12851+ return fidir;
12852+}
12853+
12854+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
12855+{
12856+ int err;
12857+ struct au_fidir *fidir, *p;
12858+
12859+ AuRwMustWriteLock(&finfo->fi_rwsem);
12860+ fidir = finfo->fi_hdir;
12861+ AuDebugOn(!fidir);
12862+
12863+ err = -ENOMEM;
12864+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
12865+ GFP_NOFS);
12866+ if (p) {
12867+ p->fd_nent = nbr;
12868+ finfo->fi_hdir = p;
12869+ err = 0;
12870+ }
1facf9fc 12871+
dece6358 12872+ return err;
1facf9fc 12873+}
1308ab2a 12874+
12875+/* ---------------------------------------------------------------------- */
12876+
4a4d8108 12877+void au_finfo_fin(struct file *file)
1308ab2a 12878+{
4a4d8108
AM
12879+ struct au_finfo *finfo;
12880+
2000de60 12881+ au_nfiles_dec(file->f_path.dentry->d_sb);
7f207e10 12882+
4a4d8108
AM
12883+ finfo = au_fi(file);
12884+ AuDebugOn(finfo->fi_hdir);
12885+ AuRwDestroy(&finfo->fi_rwsem);
12886+ au_cache_free_finfo(finfo);
1308ab2a 12887+}
1308ab2a 12888+
e49829fe 12889+void au_fi_init_once(void *_finfo)
4a4d8108 12890+{
e49829fe 12891+ struct au_finfo *finfo = _finfo;
2cbb1c4b 12892+ static struct lock_class_key aufs_fi;
1308ab2a 12893+
e49829fe
JR
12894+ au_rw_init(&finfo->fi_rwsem);
12895+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 12896+}
1308ab2a 12897+
4a4d8108
AM
12898+int au_finfo_init(struct file *file, struct au_fidir *fidir)
12899+{
1716fcea 12900+ int err;
4a4d8108
AM
12901+ struct au_finfo *finfo;
12902+ struct dentry *dentry;
12903+
12904+ err = -ENOMEM;
2000de60 12905+ dentry = file->f_path.dentry;
4a4d8108
AM
12906+ finfo = au_cache_alloc_finfo();
12907+ if (unlikely(!finfo))
12908+ goto out;
12909+
12910+ err = 0;
7f207e10 12911+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
12912+ /* verbose coding for lock class name */
12913+ if (!fidir)
12914+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
12915+ else
12916+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
12917+ au_rw_write_lock(&finfo->fi_rwsem);
12918+ finfo->fi_btop = -1;
12919+ finfo->fi_hdir = fidir;
12920+ atomic_set(&finfo->fi_generation, au_digen(dentry));
12921+ /* smp_mb(); */ /* atomic_set */
12922+
12923+ file->private_data = finfo;
12924+
12925+out:
12926+ return err;
12927+}
7f207e10
AM
12928diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
12929--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 12930+++ linux/fs/aufs/f_op.c 2015-04-13 15:10:20.783490201 +0200
2000de60 12931@@ -0,0 +1,814 @@
dece6358 12932+/*
2000de60 12933+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
12934+ *
12935+ * This program, aufs is free software; you can redistribute it and/or modify
12936+ * it under the terms of the GNU General Public License as published by
12937+ * the Free Software Foundation; either version 2 of the License, or
12938+ * (at your option) any later version.
12939+ *
12940+ * This program is distributed in the hope that it will be useful,
12941+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12942+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12943+ * GNU General Public License for more details.
12944+ *
12945+ * You should have received a copy of the GNU General Public License
523b37e3 12946+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 12947+ */
1facf9fc 12948+
12949+/*
4a4d8108 12950+ * file and vm operations
1facf9fc 12951+ */
dece6358 12952+
86dc4139 12953+#include <linux/aio.h>
4a4d8108
AM
12954+#include <linux/fs_stack.h>
12955+#include <linux/mman.h>
4a4d8108 12956+#include <linux/security.h>
dece6358
AM
12957+#include "aufs.h"
12958+
4a4d8108 12959+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 12960+{
4a4d8108
AM
12961+ int err;
12962+ aufs_bindex_t bindex;
12963+ struct file *h_file;
12964+ struct dentry *dentry;
12965+ struct au_finfo *finfo;
38d290e6 12966+ struct inode *h_inode;
4a4d8108
AM
12967+
12968+ FiMustWriteLock(file);
12969+
523b37e3 12970+ err = 0;
2000de60 12971+ dentry = file->f_path.dentry;
4a4d8108
AM
12972+ finfo = au_fi(file);
12973+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 12974+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108 12975+ bindex = au_dbstart(dentry);
392086de 12976+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
4a4d8108
AM
12977+ if (IS_ERR(h_file))
12978+ err = PTR_ERR(h_file);
12979+ else {
38d290e6
JR
12980+ if ((flags & __O_TMPFILE)
12981+ && !(flags & O_EXCL)) {
12982+ h_inode = file_inode(h_file);
12983+ spin_lock(&h_inode->i_lock);
12984+ h_inode->i_state |= I_LINKABLE;
12985+ spin_unlock(&h_inode->i_lock);
12986+ }
4a4d8108
AM
12987+ au_set_fbstart(file, bindex);
12988+ au_set_h_fptr(file, bindex, h_file);
12989+ au_update_figen(file);
12990+ /* todo: necessary? */
12991+ /* file->f_ra = h_file->f_ra; */
12992+ }
027c5e7a 12993+
4a4d8108 12994+ return err;
1facf9fc 12995+}
12996+
4a4d8108
AM
12997+static int aufs_open_nondir(struct inode *inode __maybe_unused,
12998+ struct file *file)
1facf9fc 12999+{
4a4d8108 13000+ int err;
1308ab2a 13001+ struct super_block *sb;
1facf9fc 13002+
523b37e3
AM
13003+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
13004+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 13005+
2000de60 13006+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
13007+ si_read_lock(sb, AuLock_FLUSH);
13008+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
13009+ si_read_unlock(sb);
13010+ return err;
13011+}
1facf9fc 13012+
4a4d8108
AM
13013+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
13014+{
13015+ struct au_finfo *finfo;
13016+ aufs_bindex_t bindex;
1facf9fc 13017+
4a4d8108 13018+ finfo = au_fi(file);
2000de60
JR
13019+ au_sphl_del(&finfo->fi_hlist,
13020+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108 13021+ bindex = finfo->fi_btop;
b4510431 13022+ if (bindex >= 0)
4a4d8108 13023+ au_set_h_fptr(file, bindex, NULL);
7f207e10 13024+
4a4d8108
AM
13025+ au_finfo_fin(file);
13026+ return 0;
1facf9fc 13027+}
13028+
4a4d8108
AM
13029+/* ---------------------------------------------------------------------- */
13030+
13031+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 13032+{
1308ab2a 13033+ int err;
4a4d8108
AM
13034+ struct file *h_file;
13035+
13036+ err = 0;
13037+ h_file = au_hf_top(file);
13038+ if (h_file)
13039+ err = vfsub_flush(h_file, id);
13040+ return err;
13041+}
13042+
13043+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
13044+{
13045+ return au_do_flush(file, id, au_do_flush_nondir);
13046+}
13047+
13048+/* ---------------------------------------------------------------------- */
9dbd164d
AM
13049+/*
13050+ * read and write functions acquire [fdi]_rwsem once, but release before
13051+ * mmap_sem. This is because to stop a race condition between mmap(2).
13052+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
13053+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
13054+ * read functions after [fdi]_rwsem are released, but it should be harmless.
13055+ */
4a4d8108
AM
13056+
13057+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
13058+ loff_t *ppos)
13059+{
13060+ ssize_t err;
dece6358 13061+ struct dentry *dentry;
4a4d8108 13062+ struct file *h_file;
dece6358 13063+ struct super_block *sb;
1facf9fc 13064+
2000de60 13065+ dentry = file->f_path.dentry;
dece6358 13066+ sb = dentry->d_sb;
e49829fe 13067+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 13068+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
13069+ if (unlikely(err))
13070+ goto out;
1facf9fc 13071+
4a4d8108 13072+ h_file = au_hf_top(file);
9dbd164d
AM
13073+ get_file(h_file);
13074+ di_read_unlock(dentry, AuLock_IR);
13075+ fi_read_unlock(file);
13076+
13077+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
13078+ err = vfsub_read_u(h_file, buf, count, ppos);
13079+ /* todo: necessary? */
13080+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13081+ /* update without lock, I don't think it a problem */
c06a8ce3 13082+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13083+ fput(h_file);
1308ab2a 13084+
4f0767ce 13085+out:
dece6358
AM
13086+ si_read_unlock(sb);
13087+ return err;
13088+}
1facf9fc 13089+
e49829fe
JR
13090+/*
13091+ * todo: very ugly
13092+ * it locks both of i_mutex and si_rwsem for read in safe.
13093+ * if the plink maintenance mode continues forever (that is the problem),
13094+ * may loop forever.
13095+ */
13096+static void au_mtx_and_read_lock(struct inode *inode)
13097+{
13098+ int err;
13099+ struct super_block *sb = inode->i_sb;
13100+
13101+ while (1) {
13102+ mutex_lock(&inode->i_mutex);
13103+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13104+ if (!err)
13105+ break;
13106+ mutex_unlock(&inode->i_mutex);
13107+ si_read_lock(sb, AuLock_NOPLMW);
13108+ si_read_unlock(sb);
13109+ }
13110+}
13111+
4a4d8108
AM
13112+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
13113+ size_t count, loff_t *ppos)
dece6358 13114+{
4a4d8108 13115+ ssize_t err;
076b876e
AM
13116+ blkcnt_t blks;
13117+ aufs_bindex_t bstart;
4a4d8108 13118+ struct au_pin pin;
dece6358 13119+ struct dentry *dentry;
076b876e 13120+ struct inode *inode, *h_inode;
9dbd164d 13121+ struct super_block *sb;
4a4d8108
AM
13122+ struct file *h_file;
13123+ char __user *buf = (char __user *)ubuf;
1facf9fc 13124+
2000de60 13125+ dentry = file->f_path.dentry;
9dbd164d 13126+ sb = dentry->d_sb;
4a4d8108 13127+ inode = dentry->d_inode;
e49829fe 13128+ au_mtx_and_read_lock(inode);
1facf9fc 13129+
4a4d8108
AM
13130+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13131+ if (unlikely(err))
13132+ goto out;
1facf9fc 13133+
4a4d8108
AM
13134+ err = au_ready_to_write(file, -1, &pin);
13135+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13136+ if (unlikely(err)) {
13137+ di_read_unlock(dentry, AuLock_IR);
13138+ fi_write_unlock(file);
13139+ goto out;
13140+ }
1facf9fc 13141+
076b876e 13142+ bstart = au_fbstart(file);
4a4d8108 13143+ h_file = au_hf_top(file);
9dbd164d 13144+ get_file(h_file);
c1595e42 13145+ h_inode = file_inode(h_file);
076b876e 13146+ blks = h_inode->i_blocks;
4a4d8108 13147+ au_unpin(&pin);
9dbd164d
AM
13148+ di_read_unlock(dentry, AuLock_IR);
13149+ fi_write_unlock(file);
13150+
4a4d8108 13151+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 13152+ ii_write_lock_child(inode);
4a4d8108 13153+ au_cpup_attr_timesizes(inode);
c06a8ce3 13154+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13155+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13156+ if (err > 0)
13157+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13158+ ii_write_unlock(inode);
13159+ fput(h_file);
1facf9fc 13160+
4f0767ce 13161+out:
9dbd164d 13162+ si_read_unlock(sb);
4a4d8108 13163+ mutex_unlock(&inode->i_mutex);
dece6358
AM
13164+ return err;
13165+}
1facf9fc 13166+
076b876e
AM
13167+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
13168+ struct iov_iter *iov_iter)
dece6358 13169+{
4a4d8108
AM
13170+ ssize_t err;
13171+ struct file *file;
076b876e
AM
13172+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
13173+ ssize_t (*aio)(struct kiocb *, const struct iovec *, unsigned long,
13174+ loff_t);
1facf9fc 13175+
4a4d8108
AM
13176+ err = security_file_permission(h_file, rw);
13177+ if (unlikely(err))
13178+ goto out;
1facf9fc 13179+
4a4d8108 13180+ err = -ENOSYS;
076b876e
AM
13181+ iter = NULL;
13182+ aio = NULL;
13183+ if (rw == MAY_READ) {
13184+ iter = h_file->f_op->read_iter;
13185+ aio = h_file->f_op->aio_read;
13186+ } else if (rw == MAY_WRITE) {
13187+ iter = h_file->f_op->write_iter;
13188+ aio = h_file->f_op->aio_write;
13189+ }
13190+
13191+ file = kio->ki_filp;
13192+ kio->ki_filp = h_file;
13193+ if (iter) {
2cbb1c4b 13194+ lockdep_off();
076b876e
AM
13195+ err = iter(kio, iov_iter);
13196+ lockdep_on();
13197+ } else if (aio) {
13198+ lockdep_off();
13199+ err = aio(kio, iov_iter->iov, iov_iter->nr_segs, kio->ki_pos);
2cbb1c4b 13200+ lockdep_on();
4a4d8108
AM
13201+ } else
13202+ /* currently there is no such fs */
13203+ WARN_ON_ONCE(1);
076b876e 13204+ kio->ki_filp = file;
1facf9fc 13205+
4f0767ce 13206+out:
dece6358
AM
13207+ return err;
13208+}
1facf9fc 13209+
076b876e 13210+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 13211+{
4a4d8108
AM
13212+ ssize_t err;
13213+ struct file *file, *h_file;
13214+ struct dentry *dentry;
dece6358 13215+ struct super_block *sb;
1facf9fc 13216+
4a4d8108 13217+ file = kio->ki_filp;
2000de60 13218+ dentry = file->f_path.dentry;
1308ab2a 13219+ sb = dentry->d_sb;
e49829fe 13220+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13221+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13222+ if (unlikely(err))
13223+ goto out;
13224+
13225+ h_file = au_hf_top(file);
9dbd164d
AM
13226+ get_file(h_file);
13227+ di_read_unlock(dentry, AuLock_IR);
13228+ fi_read_unlock(file);
13229+
076b876e 13230+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
13231+ /* todo: necessary? */
13232+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13233+ /* update without lock, I don't think it a problem */
c06a8ce3 13234+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13235+ fput(h_file);
1facf9fc 13236+
4f0767ce 13237+out:
4a4d8108 13238+ si_read_unlock(sb);
1308ab2a 13239+ return err;
13240+}
1facf9fc 13241+
076b876e 13242+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 13243+{
4a4d8108 13244+ ssize_t err;
076b876e
AM
13245+ blkcnt_t blks;
13246+ aufs_bindex_t bstart;
4a4d8108
AM
13247+ struct au_pin pin;
13248+ struct dentry *dentry;
076b876e 13249+ struct inode *inode, *h_inode;
4a4d8108 13250+ struct file *file, *h_file;
9dbd164d 13251+ struct super_block *sb;
1308ab2a 13252+
4a4d8108 13253+ file = kio->ki_filp;
2000de60 13254+ dentry = file->f_path.dentry;
9dbd164d 13255+ sb = dentry->d_sb;
1308ab2a 13256+ inode = dentry->d_inode;
e49829fe
JR
13257+ au_mtx_and_read_lock(inode);
13258+
4a4d8108
AM
13259+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13260+ if (unlikely(err))
1308ab2a 13261+ goto out;
1facf9fc 13262+
4a4d8108
AM
13263+ err = au_ready_to_write(file, -1, &pin);
13264+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13265+ if (unlikely(err)) {
13266+ di_read_unlock(dentry, AuLock_IR);
13267+ fi_write_unlock(file);
13268+ goto out;
13269+ }
1facf9fc 13270+
076b876e 13271+ bstart = au_fbstart(file);
4a4d8108 13272+ h_file = au_hf_top(file);
9dbd164d 13273+ get_file(h_file);
c1595e42 13274+ h_inode = file_inode(h_file);
076b876e 13275+ blks = h_inode->i_blocks;
9dbd164d
AM
13276+ au_unpin(&pin);
13277+ di_read_unlock(dentry, AuLock_IR);
13278+ fi_write_unlock(file);
13279+
076b876e 13280+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
9dbd164d 13281+ ii_write_lock_child(inode);
4a4d8108 13282+ au_cpup_attr_timesizes(inode);
c06a8ce3 13283+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13284+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13285+ if (err > 0)
13286+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13287+ ii_write_unlock(inode);
13288+ fput(h_file);
1facf9fc 13289+
4f0767ce 13290+out:
9dbd164d 13291+ si_read_unlock(sb);
4a4d8108 13292+ mutex_unlock(&inode->i_mutex);
dece6358 13293+ return err;
1facf9fc 13294+}
13295+
4a4d8108
AM
13296+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
13297+ struct pipe_inode_info *pipe, size_t len,
13298+ unsigned int flags)
1facf9fc 13299+{
4a4d8108
AM
13300+ ssize_t err;
13301+ struct file *h_file;
13302+ struct dentry *dentry;
dece6358 13303+ struct super_block *sb;
1facf9fc 13304+
2000de60 13305+ dentry = file->f_path.dentry;
dece6358 13306+ sb = dentry->d_sb;
e49829fe 13307+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13308+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13309+ if (unlikely(err))
dece6358 13310+ goto out;
1facf9fc 13311+
4a4d8108
AM
13312+ err = -EINVAL;
13313+ h_file = au_hf_top(file);
9dbd164d 13314+ get_file(h_file);
4a4d8108 13315+ if (au_test_loopback_kthread()) {
2000de60 13316+ au_warn_loopback(h_file->f_path.dentry->d_sb);
87a755f4
AM
13317+ if (file->f_mapping != h_file->f_mapping) {
13318+ file->f_mapping = h_file->f_mapping;
13319+ smp_mb(); /* unnecessary? */
13320+ }
1308ab2a 13321+ }
9dbd164d
AM
13322+ di_read_unlock(dentry, AuLock_IR);
13323+ fi_read_unlock(file);
13324+
4a4d8108
AM
13325+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
13326+ /* todo: necessasry? */
13327+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13328+ /* update without lock, I don't think it a problem */
c06a8ce3 13329+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13330+ fput(h_file);
1facf9fc 13331+
4f0767ce 13332+out:
4a4d8108 13333+ si_read_unlock(sb);
dece6358 13334+ return err;
1facf9fc 13335+}
13336+
4a4d8108
AM
13337+static ssize_t
13338+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
13339+ size_t len, unsigned int flags)
1facf9fc 13340+{
4a4d8108 13341+ ssize_t err;
076b876e
AM
13342+ blkcnt_t blks;
13343+ aufs_bindex_t bstart;
4a4d8108
AM
13344+ struct au_pin pin;
13345+ struct dentry *dentry;
076b876e 13346+ struct inode *inode, *h_inode;
9dbd164d 13347+ struct super_block *sb;
076b876e 13348+ struct file *h_file;
1facf9fc 13349+
2000de60 13350+ dentry = file->f_path.dentry;
9dbd164d 13351+ sb = dentry->d_sb;
4a4d8108 13352+ inode = dentry->d_inode;
e49829fe 13353+ au_mtx_and_read_lock(inode);
9dbd164d 13354+
4a4d8108
AM
13355+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13356+ if (unlikely(err))
13357+ goto out;
1facf9fc 13358+
4a4d8108
AM
13359+ err = au_ready_to_write(file, -1, &pin);
13360+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13361+ if (unlikely(err)) {
13362+ di_read_unlock(dentry, AuLock_IR);
13363+ fi_write_unlock(file);
13364+ goto out;
13365+ }
1facf9fc 13366+
076b876e 13367+ bstart = au_fbstart(file);
4a4d8108 13368+ h_file = au_hf_top(file);
9dbd164d 13369+ get_file(h_file);
c1595e42 13370+ h_inode = file_inode(h_file);
076b876e 13371+ blks = h_inode->i_blocks;
4a4d8108 13372+ au_unpin(&pin);
9dbd164d
AM
13373+ di_read_unlock(dentry, AuLock_IR);
13374+ fi_write_unlock(file);
13375+
4a4d8108 13376+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 13377+ ii_write_lock_child(inode);
4a4d8108 13378+ au_cpup_attr_timesizes(inode);
c06a8ce3 13379+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13380+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13381+ if (err > 0)
13382+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13383+ ii_write_unlock(inode);
13384+ fput(h_file);
1facf9fc 13385+
4f0767ce 13386+out:
9dbd164d 13387+ si_read_unlock(sb);
4a4d8108
AM
13388+ mutex_unlock(&inode->i_mutex);
13389+ return err;
13390+}
1facf9fc 13391+
38d290e6
JR
13392+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
13393+ loff_t len)
13394+{
13395+ long err;
13396+ struct au_pin pin;
13397+ struct dentry *dentry;
13398+ struct super_block *sb;
13399+ struct inode *inode;
13400+ struct file *h_file;
13401+
2000de60 13402+ dentry = file->f_path.dentry;
38d290e6
JR
13403+ sb = dentry->d_sb;
13404+ inode = dentry->d_inode;
13405+ au_mtx_and_read_lock(inode);
13406+
13407+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13408+ if (unlikely(err))
13409+ goto out;
13410+
13411+ err = au_ready_to_write(file, -1, &pin);
13412+ di_downgrade_lock(dentry, AuLock_IR);
13413+ if (unlikely(err)) {
13414+ di_read_unlock(dentry, AuLock_IR);
13415+ fi_write_unlock(file);
13416+ goto out;
13417+ }
13418+
13419+ h_file = au_hf_top(file);
13420+ get_file(h_file);
13421+ au_unpin(&pin);
13422+ di_read_unlock(dentry, AuLock_IR);
13423+ fi_write_unlock(file);
13424+
13425+ lockdep_off();
03673fb0 13426+ err = vfs_fallocate(h_file, mode, offset, len);
38d290e6
JR
13427+ lockdep_on();
13428+ ii_write_lock_child(inode);
13429+ au_cpup_attr_timesizes(inode);
13430+ inode->i_mode = file_inode(h_file)->i_mode;
13431+ ii_write_unlock(inode);
13432+ fput(h_file);
13433+
13434+out:
13435+ si_read_unlock(sb);
13436+ mutex_unlock(&inode->i_mutex);
13437+ return err;
13438+}
13439+
4a4d8108
AM
13440+/* ---------------------------------------------------------------------- */
13441+
9dbd164d
AM
13442+/*
13443+ * The locking order around current->mmap_sem.
13444+ * - in most and regular cases
13445+ * file I/O syscall -- aufs_read() or something
13446+ * -- si_rwsem for read -- mmap_sem
13447+ * (Note that [fdi]i_rwsem are released before mmap_sem).
13448+ * - in mmap case
13449+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
13450+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
13451+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
13452+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
13453+ * It means that when aufs acquires si_rwsem for write, the process should never
13454+ * acquire mmap_sem.
13455+ *
392086de 13456+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
13457+ * problem either since any directory is not able to be mmap-ed.
13458+ * The similar scenario is applied to aufs_readlink() too.
13459+ */
13460+
38d290e6 13461+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
13462+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
13463+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
13464+
13465+static unsigned long au_arch_prot_conv(unsigned long flags)
13466+{
13467+ /* currently ppc64 only */
13468+#ifdef CONFIG_PPC64
13469+ /* cf. linux/arch/powerpc/include/asm/mman.h */
13470+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
13471+ return AuConv_VM_PROT(flags, SAO);
13472+#else
13473+ AuDebugOn(arch_calc_vm_prot_bits(-1));
13474+ return 0;
13475+#endif
13476+}
13477+
13478+static unsigned long au_prot_conv(unsigned long flags)
13479+{
13480+ return AuConv_VM_PROT(flags, READ)
13481+ | AuConv_VM_PROT(flags, WRITE)
13482+ | AuConv_VM_PROT(flags, EXEC)
13483+ | au_arch_prot_conv(flags);
13484+}
13485+
13486+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
13487+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
13488+
13489+static unsigned long au_flag_conv(unsigned long flags)
13490+{
13491+ return AuConv_VM_MAP(flags, GROWSDOWN)
13492+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
13493+ | AuConv_VM_MAP(flags, LOCKED);
13494+}
38d290e6 13495+#endif
2dfbb274 13496+
9dbd164d 13497+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 13498+{
4a4d8108
AM
13499+ int err;
13500+ aufs_bindex_t bstart;
13501+ const unsigned char wlock
9dbd164d 13502+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
13503+ struct dentry *dentry;
13504+ struct super_block *sb;
9dbd164d
AM
13505+ struct file *h_file;
13506+ struct au_branch *br;
13507+ struct au_pin pin;
13508+
13509+ AuDbgVmRegion(file, vma);
1308ab2a 13510+
2000de60 13511+ dentry = file->f_path.dentry;
4a4d8108 13512+ sb = dentry->d_sb;
9dbd164d 13513+ lockdep_off();
e49829fe 13514+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
13515+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13516+ if (unlikely(err))
13517+ goto out;
13518+
4a4d8108 13519+ if (wlock) {
4a4d8108
AM
13520+ err = au_ready_to_write(file, -1, &pin);
13521+ di_write_unlock(dentry);
9dbd164d
AM
13522+ if (unlikely(err)) {
13523+ fi_write_unlock(file);
13524+ goto out;
13525+ }
4a4d8108
AM
13526+ au_unpin(&pin);
13527+ } else
13528+ di_write_unlock(dentry);
9dbd164d 13529+
4a4d8108 13530+ bstart = au_fbstart(file);
9dbd164d
AM
13531+ br = au_sbr(sb, bstart);
13532+ h_file = au_hf_top(file);
13533+ get_file(h_file);
2cbb1c4b 13534+ au_set_mmapped(file);
4a4d8108 13535+ fi_write_unlock(file);
9dbd164d 13536+ lockdep_on();
1308ab2a 13537+
9dbd164d 13538+ au_vm_file_reset(vma, h_file);
38d290e6
JR
13539+ /*
13540+ * we cannot call security_mmap_file() here since it may acquire
13541+ * mmap_sem or i_mutex.
13542+ *
13543+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
13544+ * au_flag_conv(vma->vm_flags));
13545+ */
9dbd164d
AM
13546+ if (!err)
13547+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
13548+ if (unlikely(err))
13549+ goto out_reset;
4a4d8108 13550+
fb47a38f 13551+ au_vm_prfile_set(vma, file);
4a4d8108 13552+ /* update without lock, I don't think it a problem */
c06a8ce3 13553+ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
2cbb1c4b 13554+ goto out_fput; /* success */
4a4d8108 13555+
2cbb1c4b
JR
13556+out_reset:
13557+ au_unset_mmapped(file);
13558+ au_vm_file_reset(vma, file);
13559+out_fput:
9dbd164d
AM
13560+ fput(h_file);
13561+ lockdep_off();
4f0767ce 13562+out:
9dbd164d
AM
13563+ si_read_unlock(sb);
13564+ lockdep_on();
13565+ AuTraceErr(err);
4a4d8108
AM
13566+ return err;
13567+}
13568+
13569+/* ---------------------------------------------------------------------- */
13570+
1e00d052
AM
13571+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
13572+ int datasync)
4a4d8108
AM
13573+{
13574+ int err;
13575+ struct au_pin pin;
b752ccd1 13576+ struct dentry *dentry;
4a4d8108
AM
13577+ struct inode *inode;
13578+ struct file *h_file;
13579+ struct super_block *sb;
13580+
2000de60 13581+ dentry = file->f_path.dentry;
4a4d8108 13582+ inode = dentry->d_inode;
4a4d8108 13583+ sb = dentry->d_sb;
1e00d052 13584+ mutex_lock(&inode->i_mutex);
e49829fe
JR
13585+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13586+ if (unlikely(err))
13587+ goto out;
4a4d8108
AM
13588+
13589+ err = 0; /* -EBADF; */ /* posix? */
13590+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 13591+ goto out_si;
4a4d8108
AM
13592+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13593+ if (unlikely(err))
e49829fe 13594+ goto out_si;
4a4d8108
AM
13595+
13596+ err = au_ready_to_write(file, -1, &pin);
13597+ di_downgrade_lock(dentry, AuLock_IR);
13598+ if (unlikely(err))
13599+ goto out_unlock;
13600+ au_unpin(&pin);
13601+
13602+ err = -EINVAL;
13603+ h_file = au_hf_top(file);
53392da6
AM
13604+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
13605+ au_cpup_attr_timesizes(inode);
4a4d8108 13606+
4f0767ce 13607+out_unlock:
4a4d8108 13608+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 13609+ fi_write_unlock(file);
e49829fe 13610+out_si:
953406b4 13611+ si_read_unlock(sb);
e49829fe 13612+out:
1e00d052 13613+ mutex_unlock(&inode->i_mutex);
4a4d8108 13614+ return err;
dece6358
AM
13615+}
13616+
4a4d8108
AM
13617+/* no one supports this operation, currently */
13618+#if 0
13619+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 13620+{
4a4d8108
AM
13621+ int err;
13622+ struct au_pin pin;
1308ab2a 13623+ struct dentry *dentry;
4a4d8108
AM
13624+ struct inode *inode;
13625+ struct file *file, *h_file;
1308ab2a 13626+
4a4d8108 13627+ file = kio->ki_filp;
2000de60 13628+ dentry = file->f_path.dentry;
4a4d8108 13629+ inode = dentry->d_inode;
e49829fe 13630+ au_mtx_and_read_lock(inode);
4a4d8108
AM
13631+
13632+ err = 0; /* -EBADF; */ /* posix? */
13633+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
13634+ goto out;
13635+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13636+ if (unlikely(err))
1308ab2a 13637+ goto out;
13638+
4a4d8108
AM
13639+ err = au_ready_to_write(file, -1, &pin);
13640+ di_downgrade_lock(dentry, AuLock_IR);
13641+ if (unlikely(err))
13642+ goto out_unlock;
13643+ au_unpin(&pin);
1308ab2a 13644+
4a4d8108
AM
13645+ err = -ENOSYS;
13646+ h_file = au_hf_top(file);
523b37e3 13647+ if (h_file->f_op->aio_fsync) {
4a4d8108 13648+ struct mutex *h_mtx;
1308ab2a 13649+
c06a8ce3 13650+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
13651+ if (!is_sync_kiocb(kio)) {
13652+ get_file(h_file);
13653+ fput(file);
13654+ }
13655+ kio->ki_filp = h_file;
13656+ err = h_file->f_op->aio_fsync(kio, datasync);
13657+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
13658+ if (!err)
13659+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
13660+ /*ignore*/
13661+ au_cpup_attr_timesizes(inode);
13662+ mutex_unlock(h_mtx);
13663+ }
1308ab2a 13664+
4f0767ce 13665+out_unlock:
4a4d8108
AM
13666+ di_read_unlock(dentry, AuLock_IR);
13667+ fi_write_unlock(file);
4f0767ce 13668+out:
e49829fe 13669+ si_read_unlock(inode->sb);
4a4d8108
AM
13670+ mutex_unlock(&inode->i_mutex);
13671+ return err;
dece6358 13672+}
4a4d8108 13673+#endif
dece6358 13674+
4a4d8108 13675+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 13676+{
4a4d8108
AM
13677+ int err;
13678+ struct file *h_file;
13679+ struct dentry *dentry;
13680+ struct super_block *sb;
1308ab2a 13681+
2000de60 13682+ dentry = file->f_path.dentry;
4a4d8108 13683+ sb = dentry->d_sb;
e49829fe 13684+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13685+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13686+ if (unlikely(err))
13687+ goto out;
13688+
13689+ h_file = au_hf_top(file);
523b37e3 13690+ if (h_file->f_op->fasync)
4a4d8108
AM
13691+ err = h_file->f_op->fasync(fd, h_file, flag);
13692+
13693+ di_read_unlock(dentry, AuLock_IR);
13694+ fi_read_unlock(file);
1308ab2a 13695+
4f0767ce 13696+out:
4a4d8108 13697+ si_read_unlock(sb);
1308ab2a 13698+ return err;
dece6358 13699+}
4a4d8108
AM
13700+
13701+/* ---------------------------------------------------------------------- */
13702+
13703+/* no one supports this operation, currently */
13704+#if 0
13705+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
2000de60 13706+ size_t len, loff_t *pos, int more)
4a4d8108
AM
13707+{
13708+}
13709+#endif
13710+
13711+/* ---------------------------------------------------------------------- */
13712+
13713+const struct file_operations aufs_file_fop = {
13714+ .owner = THIS_MODULE,
2cbb1c4b 13715+
027c5e7a 13716+ .llseek = default_llseek,
4a4d8108
AM
13717+
13718+ .read = aufs_read,
13719+ .write = aufs_write,
076b876e
AM
13720+ .read_iter = aufs_read_iter,
13721+ .write_iter = aufs_write_iter,
13722+
4a4d8108
AM
13723+#ifdef CONFIG_AUFS_POLL
13724+ .poll = aufs_poll,
13725+#endif
13726+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 13727+#ifdef CONFIG_COMPAT
c2b27bf2 13728+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 13729+#endif
4a4d8108
AM
13730+ .mmap = aufs_mmap,
13731+ .open = aufs_open_nondir,
13732+ .flush = aufs_flush_nondir,
13733+ .release = aufs_release_nondir,
13734+ .fsync = aufs_fsync_nondir,
13735+ /* .aio_fsync = aufs_aio_fsync_nondir, */
13736+ .fasync = aufs_fasync,
13737+ /* .sendpage = aufs_sendpage, */
13738+ .splice_write = aufs_splice_write,
13739+ .splice_read = aufs_splice_read,
13740+#if 0
13741+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 13742+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 13743+#endif
38d290e6 13744+ .fallocate = aufs_fallocate
4a4d8108 13745+};
7f207e10
AM
13746diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
13747--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
13748+++ linux/fs/aufs/fstype.h 2015-04-13 15:10:20.783490201 +0200
13749@@ -0,0 +1,388 @@
4a4d8108 13750+/*
2000de60 13751+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
13752+ *
13753+ * This program, aufs is free software; you can redistribute it and/or modify
13754+ * it under the terms of the GNU General Public License as published by
13755+ * the Free Software Foundation; either version 2 of the License, or
13756+ * (at your option) any later version.
13757+ *
13758+ * This program is distributed in the hope that it will be useful,
13759+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13760+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13761+ * GNU General Public License for more details.
13762+ *
13763+ * You should have received a copy of the GNU General Public License
523b37e3 13764+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
13765+ */
13766+
13767+/*
13768+ * judging filesystem type
13769+ */
13770+
13771+#ifndef __AUFS_FSTYPE_H__
13772+#define __AUFS_FSTYPE_H__
13773+
13774+#ifdef __KERNEL__
13775+
13776+#include <linux/fs.h>
13777+#include <linux/magic.h>
13778+#include <linux/romfs_fs.h>
4a4d8108
AM
13779+
13780+static inline int au_test_aufs(struct super_block *sb)
13781+{
13782+ return sb->s_magic == AUFS_SUPER_MAGIC;
13783+}
13784+
13785+static inline const char *au_sbtype(struct super_block *sb)
13786+{
13787+ return sb->s_type->name;
13788+}
1308ab2a 13789+
13790+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
13791+{
2000de60
JR
13792+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
13793+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
13794+#else
13795+ return 0;
13796+#endif
13797+}
13798+
1308ab2a 13799+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 13800+{
2000de60
JR
13801+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
13802+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
13803+#else
13804+ return 0;
13805+#endif
13806+}
13807+
1308ab2a 13808+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 13809+{
1308ab2a 13810+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
13811+ return sb->s_magic == CRAMFS_MAGIC;
13812+#endif
13813+ return 0;
13814+}
13815+
13816+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
13817+{
13818+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
13819+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
13820+#else
13821+ return 0;
13822+#endif
13823+}
13824+
1308ab2a 13825+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 13826+{
1308ab2a 13827+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
13828+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
13829+#else
13830+ return 0;
13831+#endif
13832+}
13833+
1308ab2a 13834+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 13835+{
1308ab2a 13836+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
13837+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
13838+#else
13839+ return 0;
13840+#endif
13841+}
13842+
1308ab2a 13843+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 13844+{
1308ab2a 13845+#ifdef CONFIG_TMPFS
13846+ return sb->s_magic == TMPFS_MAGIC;
13847+#else
13848+ return 0;
dece6358 13849+#endif
dece6358
AM
13850+}
13851+
1308ab2a 13852+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 13853+{
1308ab2a 13854+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
13855+ return !strcmp(au_sbtype(sb), "ecryptfs");
13856+#else
13857+ return 0;
13858+#endif
1facf9fc 13859+}
13860+
1308ab2a 13861+static inline int au_test_ramfs(struct super_block *sb)
13862+{
13863+ return sb->s_magic == RAMFS_MAGIC;
13864+}
13865+
13866+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
13867+{
13868+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
13869+ return sb->s_magic == UBIFS_SUPER_MAGIC;
13870+#else
13871+ return 0;
13872+#endif
13873+}
13874+
13875+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
13876+{
13877+#ifdef CONFIG_PROC_FS
13878+ return sb->s_magic == PROC_SUPER_MAGIC;
13879+#else
13880+ return 0;
13881+#endif
13882+}
13883+
13884+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
13885+{
13886+#ifdef CONFIG_SYSFS
13887+ return sb->s_magic == SYSFS_MAGIC;
13888+#else
13889+ return 0;
13890+#endif
13891+}
13892+
13893+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
13894+{
13895+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
13896+ return sb->s_magic == CONFIGFS_MAGIC;
13897+#else
13898+ return 0;
13899+#endif
13900+}
13901+
13902+static inline int au_test_minix(struct super_block *sb __maybe_unused)
13903+{
13904+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
13905+ return sb->s_magic == MINIX3_SUPER_MAGIC
13906+ || sb->s_magic == MINIX2_SUPER_MAGIC
13907+ || sb->s_magic == MINIX2_SUPER_MAGIC2
13908+ || sb->s_magic == MINIX_SUPER_MAGIC
13909+ || sb->s_magic == MINIX_SUPER_MAGIC2;
13910+#else
13911+ return 0;
13912+#endif
13913+}
13914+
1308ab2a 13915+static inline int au_test_fat(struct super_block *sb __maybe_unused)
13916+{
13917+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
13918+ return sb->s_magic == MSDOS_SUPER_MAGIC;
13919+#else
13920+ return 0;
13921+#endif
13922+}
13923+
13924+static inline int au_test_msdos(struct super_block *sb)
13925+{
13926+ return au_test_fat(sb);
13927+}
13928+
13929+static inline int au_test_vfat(struct super_block *sb)
13930+{
13931+ return au_test_fat(sb);
13932+}
13933+
13934+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
13935+{
13936+#ifdef CONFIG_SECURITYFS
13937+ return sb->s_magic == SECURITYFS_MAGIC;
13938+#else
13939+ return 0;
13940+#endif
13941+}
13942+
13943+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
13944+{
13945+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
13946+ return sb->s_magic == SQUASHFS_MAGIC;
13947+#else
13948+ return 0;
13949+#endif
13950+}
13951+
13952+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
13953+{
13954+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
13955+ return sb->s_magic == BTRFS_SUPER_MAGIC;
13956+#else
13957+ return 0;
13958+#endif
13959+}
13960+
13961+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
13962+{
13963+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
13964+ return sb->s_magic == XENFS_SUPER_MAGIC;
13965+#else
13966+ return 0;
13967+#endif
13968+}
13969+
13970+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
13971+{
13972+#ifdef CONFIG_DEBUG_FS
13973+ return sb->s_magic == DEBUGFS_MAGIC;
13974+#else
13975+ return 0;
13976+#endif
13977+}
13978+
13979+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
13980+{
13981+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
13982+ return sb->s_magic == NILFS_SUPER_MAGIC;
13983+#else
13984+ return 0;
13985+#endif
13986+}
13987+
4a4d8108
AM
13988+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
13989+{
13990+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
13991+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
13992+#else
13993+ return 0;
13994+#endif
13995+}
13996+
1308ab2a 13997+/* ---------------------------------------------------------------------- */
13998+/*
13999+ * they can't be an aufs branch.
14000+ */
14001+static inline int au_test_fs_unsuppoted(struct super_block *sb)
14002+{
14003+ return
14004+#ifndef CONFIG_AUFS_BR_RAMFS
14005+ au_test_ramfs(sb) ||
14006+#endif
14007+ au_test_procfs(sb)
14008+ || au_test_sysfs(sb)
14009+ || au_test_configfs(sb)
14010+ || au_test_debugfs(sb)
14011+ || au_test_securityfs(sb)
14012+ || au_test_xenfs(sb)
14013+ || au_test_ecryptfs(sb)
14014+ /* || !strcmp(au_sbtype(sb), "unionfs") */
14015+ || au_test_aufs(sb); /* will be supported in next version */
14016+}
14017+
1308ab2a 14018+static inline int au_test_fs_remote(struct super_block *sb)
14019+{
14020+ return !au_test_tmpfs(sb)
14021+#ifdef CONFIG_AUFS_BR_RAMFS
14022+ && !au_test_ramfs(sb)
14023+#endif
14024+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
14025+}
14026+
14027+/* ---------------------------------------------------------------------- */
14028+
14029+/*
14030+ * Note: these functions (below) are created after reading ->getattr() in all
14031+ * filesystems under linux/fs. it means we have to do so in every update...
14032+ */
14033+
14034+/*
14035+ * some filesystems require getattr to refresh the inode attributes before
14036+ * referencing.
14037+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
14038+ * and leave the work for d_revalidate()
14039+ */
14040+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
14041+{
14042+ return au_test_nfs(sb)
14043+ || au_test_fuse(sb)
1308ab2a 14044+ /* || au_test_btrfs(sb) */ /* untested */
1308ab2a 14045+ ;
14046+}
14047+
14048+/*
14049+ * filesystems which don't maintain i_size or i_blocks.
14050+ */
14051+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
14052+{
14053+ return au_test_xfs(sb)
4a4d8108
AM
14054+ || au_test_btrfs(sb)
14055+ || au_test_ubifs(sb)
14056+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 14057+ /* || au_test_minix(sb) */ /* untested */
14058+ ;
14059+}
14060+
14061+/*
14062+ * filesystems which don't store the correct value in some of their inode
14063+ * attributes.
14064+ */
14065+static inline int au_test_fs_bad_iattr(struct super_block *sb)
14066+{
14067+ return au_test_fs_bad_iattr_size(sb)
1308ab2a 14068+ || au_test_fat(sb)
14069+ || au_test_msdos(sb)
14070+ || au_test_vfat(sb);
1facf9fc 14071+}
14072+
14073+/* they don't check i_nlink in link(2) */
14074+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
14075+{
14076+ return au_test_tmpfs(sb)
14077+#ifdef CONFIG_AUFS_BR_RAMFS
14078+ || au_test_ramfs(sb)
14079+#endif
4a4d8108 14080+ || au_test_ubifs(sb)
4a4d8108 14081+ || au_test_hfsplus(sb);
1facf9fc 14082+}
14083+
14084+/*
14085+ * filesystems which sets S_NOATIME and S_NOCMTIME.
14086+ */
14087+static inline int au_test_fs_notime(struct super_block *sb)
14088+{
14089+ return au_test_nfs(sb)
14090+ || au_test_fuse(sb)
dece6358 14091+ || au_test_ubifs(sb)
1facf9fc 14092+ ;
14093+}
14094+
1facf9fc 14095+/* temporary support for i#1 in cramfs */
14096+static inline int au_test_fs_unique_ino(struct inode *inode)
14097+{
14098+ if (au_test_cramfs(inode->i_sb))
14099+ return inode->i_ino != 1;
14100+ return 1;
14101+}
14102+
14103+/* ---------------------------------------------------------------------- */
14104+
14105+/*
14106+ * the filesystem where the xino files placed must support i/o after unlink and
14107+ * maintain i_size and i_blocks.
14108+ */
14109+static inline int au_test_fs_bad_xino(struct super_block *sb)
14110+{
14111+ return au_test_fs_remote(sb)
14112+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 14113+ /* don't want unnecessary work for xino */
14114+ || au_test_aufs(sb)
1308ab2a 14115+ || au_test_ecryptfs(sb)
14116+ || au_test_nilfs(sb);
1facf9fc 14117+}
14118+
14119+static inline int au_test_fs_trunc_xino(struct super_block *sb)
14120+{
14121+ return au_test_tmpfs(sb)
14122+ || au_test_ramfs(sb);
14123+}
14124+
14125+/*
14126+ * test if the @sb is real-readonly.
14127+ */
14128+static inline int au_test_fs_rr(struct super_block *sb)
14129+{
14130+ return au_test_squashfs(sb)
14131+ || au_test_iso9660(sb)
14132+ || au_test_cramfs(sb)
14133+ || au_test_romfs(sb);
14134+}
14135+
14136+#endif /* __KERNEL__ */
14137+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
14138diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
14139--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 14140+++ linux/fs/aufs/hfsnotify.c 2015-04-13 15:10:20.783490201 +0200
c1595e42 14141@@ -0,0 +1,288 @@
1facf9fc 14142+/*
2000de60 14143+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 14144+ *
14145+ * This program, aufs is free software; you can redistribute it and/or modify
14146+ * it under the terms of the GNU General Public License as published by
14147+ * the Free Software Foundation; either version 2 of the License, or
14148+ * (at your option) any later version.
dece6358
AM
14149+ *
14150+ * This program is distributed in the hope that it will be useful,
14151+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14152+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14153+ * GNU General Public License for more details.
14154+ *
14155+ * You should have received a copy of the GNU General Public License
523b37e3 14156+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14157+ */
14158+
14159+/*
4a4d8108 14160+ * fsnotify for the lower directories
1facf9fc 14161+ */
14162+
14163+#include "aufs.h"
14164+
4a4d8108
AM
14165+/* FS_IN_IGNORED is unnecessary */
14166+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
14167+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 14168+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 14169+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 14170+
0c5527e5 14171+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 14172+{
0c5527e5
AM
14173+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
14174+ hn_mark);
4a4d8108 14175+ AuDbg("here\n");
7eafdf33 14176+ au_cache_free_hnotify(hn);
076b876e 14177+ smp_mb__before_atomic();
1716fcea
AM
14178+ if (atomic64_dec_and_test(&au_hfsn_ifree))
14179+ wake_up(&au_hfsn_wq);
4a4d8108 14180+}
1facf9fc 14181+
027c5e7a 14182+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 14183+{
1716fcea 14184+ int err;
027c5e7a
AM
14185+ struct au_hnotify *hn;
14186+ struct super_block *sb;
14187+ struct au_branch *br;
0c5527e5 14188+ struct fsnotify_mark *mark;
027c5e7a 14189+ aufs_bindex_t bindex;
1facf9fc 14190+
027c5e7a
AM
14191+ hn = hinode->hi_notify;
14192+ sb = hn->hn_aufs_inode->i_sb;
14193+ bindex = au_br_index(sb, hinode->hi_id);
14194+ br = au_sbr(sb, bindex);
1716fcea
AM
14195+ AuDebugOn(!br->br_hfsn);
14196+
0c5527e5
AM
14197+ mark = &hn->hn_mark;
14198+ fsnotify_init_mark(mark, au_hfsn_free_mark);
14199+ mark->mask = AuHfsnMask;
7f207e10
AM
14200+ /*
14201+ * by udba rename or rmdir, aufs assign a new inode to the known
14202+ * h_inode, so specify 1 to allow dups.
14203+ */
c1595e42 14204+ lockdep_off();
1716fcea 14205+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 14206+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
14207+ /* even if err */
14208+ fsnotify_put_mark(mark);
c1595e42 14209+ lockdep_on();
1716fcea
AM
14210+
14211+ return err;
1facf9fc 14212+}
14213+
7eafdf33 14214+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 14215+{
0c5527e5 14216+ struct fsnotify_mark *mark;
7eafdf33 14217+ unsigned long long ull;
1716fcea 14218+ struct fsnotify_group *group;
7eafdf33
AM
14219+
14220+ ull = atomic64_inc_return(&au_hfsn_ifree);
14221+ BUG_ON(!ull);
953406b4 14222+
0c5527e5 14223+ mark = &hn->hn_mark;
1716fcea
AM
14224+ spin_lock(&mark->lock);
14225+ group = mark->group;
14226+ fsnotify_get_group(group);
14227+ spin_unlock(&mark->lock);
c1595e42 14228+ lockdep_off();
1716fcea
AM
14229+ fsnotify_destroy_mark(mark, group);
14230+ fsnotify_put_group(group);
c1595e42 14231+ lockdep_on();
7f207e10 14232+
7eafdf33
AM
14233+ /* free hn by myself */
14234+ return 0;
1facf9fc 14235+}
14236+
14237+/* ---------------------------------------------------------------------- */
14238+
4a4d8108 14239+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 14240+{
0c5527e5 14241+ struct fsnotify_mark *mark;
1facf9fc 14242+
0c5527e5
AM
14243+ mark = &hinode->hi_notify->hn_mark;
14244+ spin_lock(&mark->lock);
1facf9fc 14245+ if (do_set) {
0c5527e5
AM
14246+ AuDebugOn(mark->mask & AuHfsnMask);
14247+ mark->mask |= AuHfsnMask;
1facf9fc 14248+ } else {
0c5527e5
AM
14249+ AuDebugOn(!(mark->mask & AuHfsnMask));
14250+ mark->mask &= ~AuHfsnMask;
1facf9fc 14251+ }
0c5527e5 14252+ spin_unlock(&mark->lock);
4a4d8108 14253+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 14254+}
14255+
4a4d8108 14256+/* ---------------------------------------------------------------------- */
1facf9fc 14257+
4a4d8108
AM
14258+/* #define AuDbgHnotify */
14259+#ifdef AuDbgHnotify
14260+static char *au_hfsn_name(u32 mask)
14261+{
14262+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
14263+#define test_ret(flag) \
14264+ do { \
14265+ if (mask & flag) \
14266+ return #flag; \
14267+ } while (0)
4a4d8108
AM
14268+ test_ret(FS_ACCESS);
14269+ test_ret(FS_MODIFY);
14270+ test_ret(FS_ATTRIB);
14271+ test_ret(FS_CLOSE_WRITE);
14272+ test_ret(FS_CLOSE_NOWRITE);
14273+ test_ret(FS_OPEN);
14274+ test_ret(FS_MOVED_FROM);
14275+ test_ret(FS_MOVED_TO);
14276+ test_ret(FS_CREATE);
14277+ test_ret(FS_DELETE);
14278+ test_ret(FS_DELETE_SELF);
14279+ test_ret(FS_MOVE_SELF);
14280+ test_ret(FS_UNMOUNT);
14281+ test_ret(FS_Q_OVERFLOW);
14282+ test_ret(FS_IN_IGNORED);
14283+ test_ret(FS_IN_ISDIR);
14284+ test_ret(FS_IN_ONESHOT);
14285+ test_ret(FS_EVENT_ON_CHILD);
14286+ return "";
14287+#undef test_ret
14288+#else
14289+ return "??";
14290+#endif
1facf9fc 14291+}
4a4d8108 14292+#endif
1facf9fc 14293+
14294+/* ---------------------------------------------------------------------- */
14295+
1716fcea
AM
14296+static void au_hfsn_free_group(struct fsnotify_group *group)
14297+{
14298+ struct au_br_hfsnotify *hfsn = group->private;
14299+
14300+ AuDbg("here\n");
14301+ kfree(hfsn);
14302+}
14303+
4a4d8108 14304+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 14305+ struct inode *inode,
0c5527e5
AM
14306+ struct fsnotify_mark *inode_mark,
14307+ struct fsnotify_mark *vfsmount_mark,
fb47a38f
JR
14308+ u32 mask, void *data, int data_type,
14309+ const unsigned char *file_name, u32 cookie)
1facf9fc 14310+{
14311+ int err;
4a4d8108
AM
14312+ struct au_hnotify *hnotify;
14313+ struct inode *h_dir, *h_inode;
fb47a38f 14314+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
4a4d8108 14315+
fb47a38f 14316+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 14317+
14318+ err = 0;
0c5527e5 14319+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 14320+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 14321+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 14322+ goto out;
1facf9fc 14323+
fb47a38f
JR
14324+ h_dir = inode;
14325+ h_inode = NULL;
4a4d8108 14326+#ifdef AuDbgHnotify
392086de 14327+ au_debug_on();
4a4d8108
AM
14328+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
14329+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
14330+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
14331+ h_dir->i_ino, mask, au_hfsn_name(mask),
14332+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
14333+ /* WARN_ON(1); */
1facf9fc 14334+ }
392086de 14335+ au_debug_off();
1facf9fc 14336+#endif
4a4d8108 14337+
0c5527e5
AM
14338+ AuDebugOn(!inode_mark);
14339+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
14340+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 14341+
4a4d8108
AM
14342+out:
14343+ return err;
14344+}
1facf9fc 14345+
4a4d8108 14346+static struct fsnotify_ops au_hfsn_ops = {
1716fcea
AM
14347+ .handle_event = au_hfsn_handle_event,
14348+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
14349+};
14350+
14351+/* ---------------------------------------------------------------------- */
14352+
027c5e7a
AM
14353+static void au_hfsn_fin_br(struct au_branch *br)
14354+{
1716fcea 14355+ struct au_br_hfsnotify *hfsn;
027c5e7a 14356+
1716fcea 14357+ hfsn = br->br_hfsn;
c1595e42
JR
14358+ if (hfsn) {
14359+ lockdep_off();
1716fcea 14360+ fsnotify_put_group(hfsn->hfsn_group);
c1595e42
JR
14361+ lockdep_on();
14362+ }
027c5e7a
AM
14363+}
14364+
1716fcea 14365+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
14366+{
14367+ int err;
1716fcea
AM
14368+ struct fsnotify_group *group;
14369+ struct au_br_hfsnotify *hfsn;
1facf9fc 14370+
4a4d8108 14371+ err = 0;
1716fcea
AM
14372+ br->br_hfsn = NULL;
14373+ if (!au_br_hnotifyable(perm))
027c5e7a 14374+ goto out;
027c5e7a 14375+
1716fcea
AM
14376+ err = -ENOMEM;
14377+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
14378+ if (unlikely(!hfsn))
027c5e7a
AM
14379+ goto out;
14380+
1716fcea
AM
14381+ err = 0;
14382+ group = fsnotify_alloc_group(&au_hfsn_ops);
14383+ if (IS_ERR(group)) {
14384+ err = PTR_ERR(group);
0c5527e5 14385+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 14386+ goto out_hfsn;
4a4d8108 14387+ }
1facf9fc 14388+
1716fcea
AM
14389+ group->private = hfsn;
14390+ hfsn->hfsn_group = group;
14391+ br->br_hfsn = hfsn;
14392+ goto out; /* success */
14393+
14394+out_hfsn:
14395+ kfree(hfsn);
027c5e7a 14396+out:
1716fcea
AM
14397+ return err;
14398+}
14399+
14400+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
14401+{
14402+ int err;
14403+
14404+ err = 0;
14405+ if (!br->br_hfsn)
14406+ err = au_hfsn_init_br(br, perm);
14407+
1facf9fc 14408+ return err;
14409+}
14410+
7eafdf33
AM
14411+/* ---------------------------------------------------------------------- */
14412+
14413+static void au_hfsn_fin(void)
14414+{
14415+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
14416+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
14417+}
14418+
4a4d8108
AM
14419+const struct au_hnotify_op au_hnotify_op = {
14420+ .ctl = au_hfsn_ctl,
14421+ .alloc = au_hfsn_alloc,
14422+ .free = au_hfsn_free,
1facf9fc 14423+
7eafdf33
AM
14424+ .fin = au_hfsn_fin,
14425+
027c5e7a
AM
14426+ .reset_br = au_hfsn_reset_br,
14427+ .fin_br = au_hfsn_fin_br,
14428+ .init_br = au_hfsn_init_br
4a4d8108 14429+};
7f207e10
AM
14430diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
14431--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 14432+++ linux/fs/aufs/hfsplus.c 2015-04-13 15:10:20.783490201 +0200
523b37e3 14433@@ -0,0 +1,56 @@
4a4d8108 14434+/*
2000de60 14435+ * Copyright (C) 2010-2015 Junjiro R. Okajima
4a4d8108
AM
14436+ *
14437+ * This program, aufs is free software; you can redistribute it and/or modify
14438+ * it under the terms of the GNU General Public License as published by
14439+ * the Free Software Foundation; either version 2 of the License, or
14440+ * (at your option) any later version.
14441+ *
14442+ * This program is distributed in the hope that it will be useful,
14443+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14444+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14445+ * GNU General Public License for more details.
14446+ *
14447+ * You should have received a copy of the GNU General Public License
523b37e3 14448+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 14449+ */
1facf9fc 14450+
4a4d8108
AM
14451+/*
14452+ * special support for filesystems which aqucires an inode mutex
14453+ * at final closing a file, eg, hfsplus.
14454+ *
14455+ * This trick is very simple and stupid, just to open the file before really
14456+ * neceeary open to tell hfsplus that this is not the final closing.
14457+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
14458+ * and au_h_open_post() after releasing it.
14459+ */
1facf9fc 14460+
4a4d8108 14461+#include "aufs.h"
1facf9fc 14462+
392086de
AM
14463+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
14464+ int force_wr)
4a4d8108
AM
14465+{
14466+ struct file *h_file;
14467+ struct dentry *h_dentry;
1facf9fc 14468+
4a4d8108
AM
14469+ h_dentry = au_h_dptr(dentry, bindex);
14470+ AuDebugOn(!h_dentry);
14471+ AuDebugOn(!h_dentry->d_inode);
4a4d8108
AM
14472+
14473+ h_file = NULL;
14474+ if (au_test_hfsplus(h_dentry->d_sb)
7e9cd9fe 14475+ && d_is_reg(h_dentry))
4a4d8108
AM
14476+ h_file = au_h_open(dentry, bindex,
14477+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 14478+ /*file*/NULL, force_wr);
4a4d8108 14479+ return h_file;
1facf9fc 14480+}
14481+
4a4d8108
AM
14482+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
14483+ struct file *h_file)
14484+{
14485+ if (h_file) {
14486+ fput(h_file);
14487+ au_sbr_put(dentry->d_sb, bindex);
14488+ }
14489+}
7f207e10
AM
14490diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
14491--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 14492+++ linux/fs/aufs/hnotify.c 2015-04-13 15:10:20.783490201 +0200
076b876e 14493@@ -0,0 +1,714 @@
e49829fe 14494+/*
2000de60 14495+ * Copyright (C) 2005-2015 Junjiro R. Okajima
e49829fe
JR
14496+ *
14497+ * This program, aufs is free software; you can redistribute it and/or modify
14498+ * it under the terms of the GNU General Public License as published by
14499+ * the Free Software Foundation; either version 2 of the License, or
14500+ * (at your option) any later version.
14501+ *
14502+ * This program is distributed in the hope that it will be useful,
14503+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14504+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14505+ * GNU General Public License for more details.
14506+ *
14507+ * You should have received a copy of the GNU General Public License
523b37e3 14508+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
14509+ */
14510+
14511+/*
7f207e10 14512+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
14513+ */
14514+
14515+#include "aufs.h"
14516+
027c5e7a 14517+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
14518+{
14519+ int err;
7f207e10 14520+ struct au_hnotify *hn;
1facf9fc 14521+
4a4d8108
AM
14522+ err = -ENOMEM;
14523+ hn = au_cache_alloc_hnotify();
14524+ if (hn) {
14525+ hn->hn_aufs_inode = inode;
027c5e7a
AM
14526+ hinode->hi_notify = hn;
14527+ err = au_hnotify_op.alloc(hinode);
14528+ AuTraceErr(err);
14529+ if (unlikely(err)) {
14530+ hinode->hi_notify = NULL;
4a4d8108
AM
14531+ au_cache_free_hnotify(hn);
14532+ /*
14533+ * The upper dir was removed by udba, but the same named
14534+ * dir left. In this case, aufs assignes a new inode
14535+ * number and set the monitor again.
14536+ * For the lower dir, the old monitnor is still left.
14537+ */
14538+ if (err == -EEXIST)
14539+ err = 0;
14540+ }
1308ab2a 14541+ }
1308ab2a 14542+
027c5e7a 14543+ AuTraceErr(err);
1308ab2a 14544+ return err;
dece6358 14545+}
1facf9fc 14546+
4a4d8108 14547+void au_hn_free(struct au_hinode *hinode)
dece6358 14548+{
4a4d8108 14549+ struct au_hnotify *hn;
1facf9fc 14550+
4a4d8108
AM
14551+ hn = hinode->hi_notify;
14552+ if (hn) {
4a4d8108 14553+ hinode->hi_notify = NULL;
7eafdf33
AM
14554+ if (au_hnotify_op.free(hinode, hn))
14555+ au_cache_free_hnotify(hn);
4a4d8108
AM
14556+ }
14557+}
dece6358 14558+
4a4d8108 14559+/* ---------------------------------------------------------------------- */
dece6358 14560+
4a4d8108
AM
14561+void au_hn_ctl(struct au_hinode *hinode, int do_set)
14562+{
14563+ if (hinode->hi_notify)
14564+ au_hnotify_op.ctl(hinode, do_set);
14565+}
14566+
14567+void au_hn_reset(struct inode *inode, unsigned int flags)
14568+{
14569+ aufs_bindex_t bindex, bend;
14570+ struct inode *hi;
14571+ struct dentry *iwhdentry;
1facf9fc 14572+
1308ab2a 14573+ bend = au_ibend(inode);
4a4d8108
AM
14574+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14575+ hi = au_h_iptr(inode, bindex);
14576+ if (!hi)
14577+ continue;
1308ab2a 14578+
4a4d8108
AM
14579+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
14580+ iwhdentry = au_hi_wh(inode, bindex);
14581+ if (iwhdentry)
14582+ dget(iwhdentry);
14583+ au_igrab(hi);
14584+ au_set_h_iptr(inode, bindex, NULL, 0);
14585+ au_set_h_iptr(inode, bindex, au_igrab(hi),
14586+ flags & ~AuHi_XINO);
14587+ iput(hi);
14588+ dput(iwhdentry);
14589+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 14590+ }
1facf9fc 14591+}
14592+
1308ab2a 14593+/* ---------------------------------------------------------------------- */
1facf9fc 14594+
4a4d8108 14595+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 14596+{
4a4d8108
AM
14597+ int err;
14598+ aufs_bindex_t bindex, bend, bfound, bstart;
14599+ struct inode *h_i;
1facf9fc 14600+
4a4d8108
AM
14601+ err = 0;
14602+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14603+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14604+ goto out;
14605+ }
1facf9fc 14606+
4a4d8108
AM
14607+ bfound = -1;
14608+ bend = au_ibend(inode);
14609+ bstart = au_ibstart(inode);
14610+#if 0 /* reserved for future use */
14611+ if (bindex == bend) {
14612+ /* keep this ino in rename case */
14613+ goto out;
14614+ }
14615+#endif
14616+ for (bindex = bstart; bindex <= bend; bindex++)
14617+ if (au_h_iptr(inode, bindex) == h_inode) {
14618+ bfound = bindex;
14619+ break;
14620+ }
14621+ if (bfound < 0)
1308ab2a 14622+ goto out;
1facf9fc 14623+
4a4d8108
AM
14624+ for (bindex = bstart; bindex <= bend; bindex++) {
14625+ h_i = au_h_iptr(inode, bindex);
14626+ if (!h_i)
14627+ continue;
1facf9fc 14628+
4a4d8108
AM
14629+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
14630+ /* ignore this error */
14631+ /* bad action? */
1facf9fc 14632+ }
1facf9fc 14633+
4a4d8108 14634+ /* children inode number will be broken */
1facf9fc 14635+
4f0767ce 14636+out:
4a4d8108
AM
14637+ AuTraceErr(err);
14638+ return err;
1facf9fc 14639+}
14640+
4a4d8108 14641+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 14642+{
4a4d8108
AM
14643+ int err, i, j, ndentry;
14644+ struct au_dcsub_pages dpages;
14645+ struct au_dpage *dpage;
14646+ struct dentry **dentries;
1facf9fc 14647+
4a4d8108
AM
14648+ err = au_dpages_init(&dpages, GFP_NOFS);
14649+ if (unlikely(err))
14650+ goto out;
14651+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
14652+ if (unlikely(err))
14653+ goto out_dpages;
1facf9fc 14654+
4a4d8108
AM
14655+ for (i = 0; i < dpages.ndpage; i++) {
14656+ dpage = dpages.dpages + i;
14657+ dentries = dpage->dentries;
14658+ ndentry = dpage->ndentry;
14659+ for (j = 0; j < ndentry; j++) {
14660+ struct dentry *d;
14661+
14662+ d = dentries[j];
14663+ if (IS_ROOT(d))
14664+ continue;
14665+
4a4d8108
AM
14666+ au_digen_dec(d);
14667+ if (d->d_inode)
14668+ /* todo: reset children xino?
14669+ cached children only? */
14670+ au_iigen_dec(d->d_inode);
1308ab2a 14671+ }
dece6358 14672+ }
1facf9fc 14673+
4f0767ce 14674+out_dpages:
4a4d8108 14675+ au_dpages_free(&dpages);
dece6358 14676+
027c5e7a 14677+#if 0
4a4d8108
AM
14678+ /* discard children */
14679+ dentry_unhash(dentry);
14680+ dput(dentry);
027c5e7a 14681+#endif
4f0767ce 14682+out:
dece6358
AM
14683+ return err;
14684+}
14685+
1308ab2a 14686+/*
4a4d8108 14687+ * return 0 if processed.
1308ab2a 14688+ */
4a4d8108
AM
14689+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
14690+ const unsigned int isdir)
dece6358 14691+{
1308ab2a 14692+ int err;
4a4d8108
AM
14693+ struct dentry *d;
14694+ struct qstr *dname;
1facf9fc 14695+
4a4d8108
AM
14696+ err = 1;
14697+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14698+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14699+ err = 0;
14700+ goto out;
14701+ }
dece6358 14702+
4a4d8108
AM
14703+ if (!isdir) {
14704+ AuDebugOn(!name);
14705+ au_iigen_dec(inode);
027c5e7a 14706+ spin_lock(&inode->i_lock);
c1595e42 14707+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 14708+ spin_lock(&d->d_lock);
4a4d8108
AM
14709+ dname = &d->d_name;
14710+ if (dname->len != nlen
027c5e7a
AM
14711+ && memcmp(dname->name, name, nlen)) {
14712+ spin_unlock(&d->d_lock);
4a4d8108 14713+ continue;
027c5e7a 14714+ }
4a4d8108 14715+ err = 0;
4a4d8108
AM
14716+ au_digen_dec(d);
14717+ spin_unlock(&d->d_lock);
14718+ break;
1facf9fc 14719+ }
027c5e7a 14720+ spin_unlock(&inode->i_lock);
1308ab2a 14721+ } else {
027c5e7a 14722+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
c1595e42 14723+ d = d_find_any_alias(inode);
4a4d8108
AM
14724+ if (!d) {
14725+ au_iigen_dec(inode);
14726+ goto out;
14727+ }
1facf9fc 14728+
027c5e7a 14729+ spin_lock(&d->d_lock);
4a4d8108 14730+ dname = &d->d_name;
027c5e7a
AM
14731+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
14732+ spin_unlock(&d->d_lock);
4a4d8108 14733+ err = hn_gen_tree(d);
027c5e7a
AM
14734+ spin_lock(&d->d_lock);
14735+ }
14736+ spin_unlock(&d->d_lock);
4a4d8108
AM
14737+ dput(d);
14738+ }
1facf9fc 14739+
4f0767ce 14740+out:
4a4d8108 14741+ AuTraceErr(err);
1308ab2a 14742+ return err;
14743+}
dece6358 14744+
4a4d8108 14745+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 14746+{
4a4d8108
AM
14747+ int err;
14748+ struct inode *inode;
1facf9fc 14749+
4a4d8108
AM
14750+ inode = dentry->d_inode;
14751+ if (IS_ROOT(dentry)
14752+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
14753+ ) {
0c3ec466 14754+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14755+ return 0;
14756+ }
1308ab2a 14757+
4a4d8108
AM
14758+ err = 0;
14759+ if (!isdir) {
4a4d8108
AM
14760+ au_digen_dec(dentry);
14761+ if (inode)
14762+ au_iigen_dec(inode);
14763+ } else {
027c5e7a 14764+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
14765+ if (inode)
14766+ err = hn_gen_tree(dentry);
14767+ }
14768+
14769+ AuTraceErr(err);
14770+ return err;
1facf9fc 14771+}
14772+
4a4d8108 14773+/* ---------------------------------------------------------------------- */
1facf9fc 14774+
4a4d8108
AM
14775+/* hnotify job flags */
14776+#define AuHnJob_XINO0 1
14777+#define AuHnJob_GEN (1 << 1)
14778+#define AuHnJob_DIRENT (1 << 2)
14779+#define AuHnJob_ISDIR (1 << 3)
14780+#define AuHnJob_TRYXINO0 (1 << 4)
14781+#define AuHnJob_MNTPNT (1 << 5)
14782+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
14783+#define au_fset_hnjob(flags, name) \
14784+ do { (flags) |= AuHnJob_##name; } while (0)
14785+#define au_fclr_hnjob(flags, name) \
14786+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 14787+
4a4d8108
AM
14788+enum {
14789+ AuHn_CHILD,
14790+ AuHn_PARENT,
14791+ AuHnLast
14792+};
1facf9fc 14793+
4a4d8108
AM
14794+struct au_hnotify_args {
14795+ struct inode *h_dir, *dir, *h_child_inode;
14796+ u32 mask;
14797+ unsigned int flags[AuHnLast];
14798+ unsigned int h_child_nlen;
14799+ char h_child_name[];
14800+};
1facf9fc 14801+
4a4d8108
AM
14802+struct hn_job_args {
14803+ unsigned int flags;
14804+ struct inode *inode, *h_inode, *dir, *h_dir;
14805+ struct dentry *dentry;
14806+ char *h_name;
14807+ int h_nlen;
14808+};
1308ab2a 14809+
4a4d8108
AM
14810+static int hn_job(struct hn_job_args *a)
14811+{
14812+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 14813+ int e;
1308ab2a 14814+
4a4d8108
AM
14815+ /* reset xino */
14816+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
14817+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 14818+
4a4d8108
AM
14819+ if (au_ftest_hnjob(a->flags, TRYXINO0)
14820+ && a->inode
14821+ && a->h_inode) {
14822+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
38d290e6
JR
14823+ if (!a->h_inode->i_nlink
14824+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108
AM
14825+ hn_xino(a->inode, a->h_inode); /* ignore this error */
14826+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 14827+ }
1facf9fc 14828+
4a4d8108
AM
14829+ /* make the generation obsolete */
14830+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 14831+ e = -1;
4a4d8108 14832+ if (a->inode)
076b876e 14833+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 14834+ isdir);
076b876e 14835+ if (e && a->dentry)
4a4d8108
AM
14836+ hn_gen_by_name(a->dentry, isdir);
14837+ /* ignore this error */
1facf9fc 14838+ }
1facf9fc 14839+
4a4d8108
AM
14840+ /* make dir entries obsolete */
14841+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
14842+ struct au_vdir *vdir;
1facf9fc 14843+
4a4d8108
AM
14844+ vdir = au_ivdir(a->inode);
14845+ if (vdir)
14846+ vdir->vd_jiffy = 0;
14847+ /* IMustLock(a->inode); */
14848+ /* a->inode->i_version++; */
14849+ }
1facf9fc 14850+
4a4d8108
AM
14851+ /* can do nothing but warn */
14852+ if (au_ftest_hnjob(a->flags, MNTPNT)
14853+ && a->dentry
14854+ && d_mountpoint(a->dentry))
523b37e3 14855+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 14856+
4a4d8108 14857+ return 0;
1308ab2a 14858+}
1facf9fc 14859+
1308ab2a 14860+/* ---------------------------------------------------------------------- */
1facf9fc 14861+
4a4d8108
AM
14862+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
14863+ struct inode *dir)
1308ab2a 14864+{
4a4d8108
AM
14865+ struct dentry *dentry, *d, *parent;
14866+ struct qstr *dname;
1308ab2a 14867+
c1595e42 14868+ parent = d_find_any_alias(dir);
4a4d8108
AM
14869+ if (!parent)
14870+ return NULL;
1308ab2a 14871+
4a4d8108 14872+ dentry = NULL;
027c5e7a 14873+ spin_lock(&parent->d_lock);
c1595e42 14874+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
523b37e3 14875+ /* AuDbg("%pd\n", d); */
027c5e7a 14876+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
14877+ dname = &d->d_name;
14878+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
14879+ goto cont_unlock;
14880+ if (au_di(d))
14881+ au_digen_dec(d);
14882+ else
14883+ goto cont_unlock;
c1595e42 14884+ if (au_dcount(d) > 0) {
027c5e7a 14885+ dentry = dget_dlock(d);
4a4d8108 14886+ spin_unlock(&d->d_lock);
027c5e7a 14887+ break;
dece6358 14888+ }
1facf9fc 14889+
f6b6e03d 14890+cont_unlock:
027c5e7a 14891+ spin_unlock(&d->d_lock);
1308ab2a 14892+ }
027c5e7a 14893+ spin_unlock(&parent->d_lock);
4a4d8108 14894+ dput(parent);
1facf9fc 14895+
4a4d8108
AM
14896+ if (dentry)
14897+ di_write_lock_child(dentry);
1308ab2a 14898+
4a4d8108
AM
14899+ return dentry;
14900+}
dece6358 14901+
4a4d8108
AM
14902+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
14903+ aufs_bindex_t bindex, ino_t h_ino)
14904+{
14905+ struct inode *inode;
14906+ ino_t ino;
14907+ int err;
14908+
14909+ inode = NULL;
14910+ err = au_xino_read(sb, bindex, h_ino, &ino);
14911+ if (!err && ino)
14912+ inode = ilookup(sb, ino);
14913+ if (!inode)
14914+ goto out;
14915+
14916+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14917+ pr_warn("wrong root branch\n");
4a4d8108
AM
14918+ iput(inode);
14919+ inode = NULL;
14920+ goto out;
1308ab2a 14921+ }
14922+
4a4d8108 14923+ ii_write_lock_child(inode);
1308ab2a 14924+
4f0767ce 14925+out:
4a4d8108 14926+ return inode;
dece6358
AM
14927+}
14928+
4a4d8108 14929+static void au_hn_bh(void *_args)
1facf9fc 14930+{
4a4d8108
AM
14931+ struct au_hnotify_args *a = _args;
14932+ struct super_block *sb;
14933+ aufs_bindex_t bindex, bend, bfound;
14934+ unsigned char xino, try_iput;
1facf9fc 14935+ int err;
1308ab2a 14936+ struct inode *inode;
4a4d8108
AM
14937+ ino_t h_ino;
14938+ struct hn_job_args args;
14939+ struct dentry *dentry;
14940+ struct au_sbinfo *sbinfo;
1facf9fc 14941+
4a4d8108
AM
14942+ AuDebugOn(!_args);
14943+ AuDebugOn(!a->h_dir);
14944+ AuDebugOn(!a->dir);
14945+ AuDebugOn(!a->mask);
14946+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
14947+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
14948+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 14949+
4a4d8108
AM
14950+ inode = NULL;
14951+ dentry = NULL;
14952+ /*
14953+ * do not lock a->dir->i_mutex here
14954+ * because of d_revalidate() may cause a deadlock.
14955+ */
14956+ sb = a->dir->i_sb;
14957+ AuDebugOn(!sb);
14958+ sbinfo = au_sbi(sb);
14959+ AuDebugOn(!sbinfo);
7f207e10 14960+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 14961+
4a4d8108
AM
14962+ ii_read_lock_parent(a->dir);
14963+ bfound = -1;
14964+ bend = au_ibend(a->dir);
14965+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
14966+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
14967+ bfound = bindex;
14968+ break;
14969+ }
14970+ ii_read_unlock(a->dir);
14971+ if (unlikely(bfound < 0))
14972+ goto out;
1facf9fc 14973+
4a4d8108
AM
14974+ xino = !!au_opt_test(au_mntflags(sb), XINO);
14975+ h_ino = 0;
14976+ if (a->h_child_inode)
14977+ h_ino = a->h_child_inode->i_ino;
1facf9fc 14978+
4a4d8108
AM
14979+ if (a->h_child_nlen
14980+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
14981+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
14982+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
14983+ a->dir);
14984+ try_iput = 0;
14985+ if (dentry)
14986+ inode = dentry->d_inode;
14987+ if (xino && !inode && h_ino
14988+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
14989+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
14990+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
14991+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
14992+ try_iput = 1;
14993+ }
1facf9fc 14994+
4a4d8108
AM
14995+ args.flags = a->flags[AuHn_CHILD];
14996+ args.dentry = dentry;
14997+ args.inode = inode;
14998+ args.h_inode = a->h_child_inode;
14999+ args.dir = a->dir;
15000+ args.h_dir = a->h_dir;
15001+ args.h_name = a->h_child_name;
15002+ args.h_nlen = a->h_child_nlen;
15003+ err = hn_job(&args);
15004+ if (dentry) {
027c5e7a 15005+ if (au_di(dentry))
4a4d8108
AM
15006+ di_write_unlock(dentry);
15007+ dput(dentry);
15008+ }
15009+ if (inode && try_iput) {
15010+ ii_write_unlock(inode);
15011+ iput(inode);
15012+ }
1facf9fc 15013+
4a4d8108
AM
15014+ ii_write_lock_parent(a->dir);
15015+ args.flags = a->flags[AuHn_PARENT];
15016+ args.dentry = NULL;
15017+ args.inode = a->dir;
15018+ args.h_inode = a->h_dir;
15019+ args.dir = NULL;
15020+ args.h_dir = NULL;
15021+ args.h_name = NULL;
15022+ args.h_nlen = 0;
15023+ err = hn_job(&args);
15024+ ii_write_unlock(a->dir);
1facf9fc 15025+
4f0767ce 15026+out:
4a4d8108
AM
15027+ iput(a->h_child_inode);
15028+ iput(a->h_dir);
15029+ iput(a->dir);
027c5e7a
AM
15030+ si_write_unlock(sb);
15031+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 15032+ kfree(a);
dece6358 15033+}
1facf9fc 15034+
4a4d8108
AM
15035+/* ---------------------------------------------------------------------- */
15036+
15037+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15038+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 15039+{
4a4d8108 15040+ int err, len;
53392da6 15041+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
15042+ unsigned char isdir, isroot, wh;
15043+ struct inode *dir;
15044+ struct au_hnotify_args *args;
15045+ char *p, *h_child_name;
dece6358 15046+
1308ab2a 15047+ err = 0;
4a4d8108
AM
15048+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
15049+ dir = igrab(hnotify->hn_aufs_inode);
15050+ if (!dir)
15051+ goto out;
1facf9fc 15052+
4a4d8108
AM
15053+ isroot = (dir->i_ino == AUFS_ROOT_INO);
15054+ wh = 0;
15055+ h_child_name = (void *)h_child_qstr->name;
15056+ len = h_child_qstr->len;
15057+ if (h_child_name) {
15058+ if (len > AUFS_WH_PFX_LEN
15059+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
15060+ h_child_name += AUFS_WH_PFX_LEN;
15061+ len -= AUFS_WH_PFX_LEN;
15062+ wh = 1;
15063+ }
1facf9fc 15064+ }
dece6358 15065+
4a4d8108
AM
15066+ isdir = 0;
15067+ if (h_child_inode)
15068+ isdir = !!S_ISDIR(h_child_inode->i_mode);
15069+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
15070+ flags[AuHn_CHILD] = 0;
15071+ if (isdir)
15072+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
15073+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
15074+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
15075+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
15076+ case FS_MOVED_FROM:
15077+ case FS_MOVED_TO:
15078+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
15079+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15080+ /*FALLTHROUGH*/
15081+ case FS_CREATE:
fb47a38f 15082+ AuDebugOn(!h_child_name);
4a4d8108 15083+ break;
1facf9fc 15084+
4a4d8108
AM
15085+ case FS_DELETE:
15086+ /*
15087+ * aufs never be able to get this child inode.
15088+ * revalidation should be in d_revalidate()
15089+ * by checking i_nlink, i_generation or d_unhashed().
15090+ */
15091+ AuDebugOn(!h_child_name);
15092+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
15093+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15094+ break;
dece6358 15095+
4a4d8108
AM
15096+ default:
15097+ AuDebugOn(1);
15098+ }
1308ab2a 15099+
4a4d8108
AM
15100+ if (wh)
15101+ h_child_inode = NULL;
1308ab2a 15102+
4a4d8108
AM
15103+ err = -ENOMEM;
15104+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 15105+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
15106+ if (unlikely(!args)) {
15107+ AuErr1("no memory\n");
15108+ iput(dir);
15109+ goto out;
15110+ }
15111+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
15112+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
15113+ args->mask = mask;
15114+ args->dir = dir;
15115+ args->h_dir = igrab(h_dir);
15116+ if (h_child_inode)
15117+ h_child_inode = igrab(h_child_inode); /* can be NULL */
15118+ args->h_child_inode = h_child_inode;
15119+ args->h_child_nlen = len;
15120+ if (len) {
15121+ p = (void *)args;
15122+ p += sizeof(*args);
15123+ memcpy(p, h_child_name, len);
15124+ p[len] = 0;
1308ab2a 15125+ }
1308ab2a 15126+
38d290e6 15127+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 15128+ f = 0;
38d290e6
JR
15129+ if (!dir->i_nlink
15130+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
15131+ f = AuWkq_NEST;
15132+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
15133+ if (unlikely(err)) {
15134+ pr_err("wkq %d\n", err);
15135+ iput(args->h_child_inode);
15136+ iput(args->h_dir);
15137+ iput(args->dir);
15138+ kfree(args);
1facf9fc 15139+ }
1facf9fc 15140+
4a4d8108 15141+out:
1facf9fc 15142+ return err;
15143+}
15144+
027c5e7a
AM
15145+/* ---------------------------------------------------------------------- */
15146+
15147+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
15148+{
15149+ int err;
15150+
15151+ AuDebugOn(!(udba & AuOptMask_UDBA));
15152+
15153+ err = 0;
15154+ if (au_hnotify_op.reset_br)
15155+ err = au_hnotify_op.reset_br(udba, br, perm);
15156+
15157+ return err;
15158+}
15159+
15160+int au_hnotify_init_br(struct au_branch *br, int perm)
15161+{
15162+ int err;
15163+
15164+ err = 0;
15165+ if (au_hnotify_op.init_br)
15166+ err = au_hnotify_op.init_br(br, perm);
15167+
15168+ return err;
15169+}
15170+
15171+void au_hnotify_fin_br(struct au_branch *br)
15172+{
15173+ if (au_hnotify_op.fin_br)
15174+ au_hnotify_op.fin_br(br);
15175+}
15176+
4a4d8108
AM
15177+static void au_hn_destroy_cache(void)
15178+{
15179+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
15180+ au_cachep[AuCache_HNOTIFY] = NULL;
15181+}
1308ab2a 15182+
4a4d8108 15183+int __init au_hnotify_init(void)
1facf9fc 15184+{
1308ab2a 15185+ int err;
1308ab2a 15186+
4a4d8108
AM
15187+ err = -ENOMEM;
15188+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
15189+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
15190+ err = 0;
15191+ if (au_hnotify_op.init)
15192+ err = au_hnotify_op.init();
4a4d8108
AM
15193+ if (unlikely(err))
15194+ au_hn_destroy_cache();
1308ab2a 15195+ }
1308ab2a 15196+ AuTraceErr(err);
4a4d8108 15197+ return err;
1308ab2a 15198+}
15199+
4a4d8108 15200+void au_hnotify_fin(void)
1308ab2a 15201+{
027c5e7a
AM
15202+ if (au_hnotify_op.fin)
15203+ au_hnotify_op.fin();
4a4d8108
AM
15204+ /* cf. au_cache_fin() */
15205+ if (au_cachep[AuCache_HNOTIFY])
15206+ au_hn_destroy_cache();
dece6358 15207+}
7f207e10
AM
15208diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
15209--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 15210+++ linux/fs/aufs/iinfo.c 2015-04-13 15:10:20.786823613 +0200
38d290e6 15211@@ -0,0 +1,277 @@
dece6358 15212+/*
2000de60 15213+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
15214+ *
15215+ * This program, aufs is free software; you can redistribute it and/or modify
15216+ * it under the terms of the GNU General Public License as published by
15217+ * the Free Software Foundation; either version 2 of the License, or
15218+ * (at your option) any later version.
15219+ *
15220+ * This program is distributed in the hope that it will be useful,
15221+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15222+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15223+ * GNU General Public License for more details.
15224+ *
15225+ * You should have received a copy of the GNU General Public License
523b37e3 15226+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15227+ */
1facf9fc 15228+
dece6358 15229+/*
4a4d8108 15230+ * inode private data
dece6358 15231+ */
1facf9fc 15232+
1308ab2a 15233+#include "aufs.h"
1facf9fc 15234+
4a4d8108 15235+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15236+{
4a4d8108 15237+ struct inode *h_inode;
1facf9fc 15238+
4a4d8108 15239+ IiMustAnyLock(inode);
1facf9fc 15240+
4a4d8108
AM
15241+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
15242+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15243+ return h_inode;
15244+}
1facf9fc 15245+
4a4d8108
AM
15246+/* todo: hard/soft set? */
15247+void au_hiput(struct au_hinode *hinode)
15248+{
15249+ au_hn_free(hinode);
15250+ dput(hinode->hi_whdentry);
15251+ iput(hinode->hi_inode);
15252+}
1facf9fc 15253+
4a4d8108
AM
15254+unsigned int au_hi_flags(struct inode *inode, int isdir)
15255+{
15256+ unsigned int flags;
15257+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 15258+
4a4d8108
AM
15259+ flags = 0;
15260+ if (au_opt_test(mnt_flags, XINO))
15261+ au_fset_hi(flags, XINO);
15262+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
15263+ au_fset_hi(flags, HNOTIFY);
15264+ return flags;
1facf9fc 15265+}
15266+
4a4d8108
AM
15267+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15268+ struct inode *h_inode, unsigned int flags)
1308ab2a 15269+{
4a4d8108
AM
15270+ struct au_hinode *hinode;
15271+ struct inode *hi;
15272+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 15273+
4a4d8108 15274+ IiMustWriteLock(inode);
dece6358 15275+
4a4d8108
AM
15276+ hinode = iinfo->ii_hinode + bindex;
15277+ hi = hinode->hi_inode;
15278+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15279+
15280+ if (hi)
15281+ au_hiput(hinode);
15282+ hinode->hi_inode = h_inode;
15283+ if (h_inode) {
15284+ int err;
15285+ struct super_block *sb = inode->i_sb;
15286+ struct au_branch *br;
15287+
027c5e7a
AM
15288+ AuDebugOn(inode->i_mode
15289+ && (h_inode->i_mode & S_IFMT)
15290+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
15291+ if (bindex == iinfo->ii_bstart)
15292+ au_cpup_igen(inode, h_inode);
15293+ br = au_sbr(sb, bindex);
15294+ hinode->hi_id = br->br_id;
15295+ if (au_ftest_hi(flags, XINO)) {
15296+ err = au_xino_write(sb, bindex, h_inode->i_ino,
15297+ inode->i_ino);
15298+ if (unlikely(err))
15299+ AuIOErr1("failed au_xino_write() %d\n", err);
15300+ }
15301+
15302+ if (au_ftest_hi(flags, HNOTIFY)
15303+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 15304+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
15305+ if (unlikely(err))
15306+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 15307+ }
15308+ }
4a4d8108 15309+}
dece6358 15310+
4a4d8108
AM
15311+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15312+ struct dentry *h_wh)
15313+{
15314+ struct au_hinode *hinode;
dece6358 15315+
4a4d8108
AM
15316+ IiMustWriteLock(inode);
15317+
15318+ hinode = au_ii(inode)->ii_hinode + bindex;
15319+ AuDebugOn(hinode->hi_whdentry);
15320+ hinode->hi_whdentry = h_wh;
1facf9fc 15321+}
15322+
537831f9 15323+void au_update_iigen(struct inode *inode, int half)
1308ab2a 15324+{
537831f9
AM
15325+ struct au_iinfo *iinfo;
15326+ struct au_iigen *iigen;
15327+ unsigned int sigen;
15328+
15329+ sigen = au_sigen(inode->i_sb);
15330+ iinfo = au_ii(inode);
15331+ iigen = &iinfo->ii_generation;
15332+ spin_lock(&iinfo->ii_genspin);
15333+ iigen->ig_generation = sigen;
15334+ if (half)
15335+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
15336+ else
15337+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
15338+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 15339+}
1facf9fc 15340+
4a4d8108
AM
15341+/* it may be called at remount time, too */
15342+void au_update_ibrange(struct inode *inode, int do_put_zero)
15343+{
15344+ struct au_iinfo *iinfo;
027c5e7a 15345+ aufs_bindex_t bindex, bend;
1facf9fc 15346+
4a4d8108 15347+ iinfo = au_ii(inode);
027c5e7a 15348+ if (!iinfo)
4a4d8108 15349+ return;
1facf9fc 15350+
4a4d8108 15351+ IiMustWriteLock(inode);
1facf9fc 15352+
027c5e7a 15353+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
15354+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15355+ bindex++) {
15356+ struct inode *h_i;
1facf9fc 15357+
4a4d8108 15358+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
38d290e6
JR
15359+ if (h_i
15360+ && !h_i->i_nlink
15361+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
15362+ au_set_h_iptr(inode, bindex, NULL, 0);
15363+ }
4a4d8108
AM
15364+ }
15365+
027c5e7a
AM
15366+ iinfo->ii_bstart = -1;
15367+ iinfo->ii_bend = -1;
15368+ bend = au_sbend(inode->i_sb);
15369+ for (bindex = 0; bindex <= bend; bindex++)
15370+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15371+ iinfo->ii_bstart = bindex;
4a4d8108 15372+ break;
027c5e7a
AM
15373+ }
15374+ if (iinfo->ii_bstart >= 0)
15375+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
15376+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15377+ iinfo->ii_bend = bindex;
15378+ break;
15379+ }
15380+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 15381+}
1facf9fc 15382+
dece6358 15383+/* ---------------------------------------------------------------------- */
1facf9fc 15384+
4a4d8108 15385+void au_icntnr_init_once(void *_c)
dece6358 15386+{
4a4d8108
AM
15387+ struct au_icntnr *c = _c;
15388+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 15389+ static struct lock_class_key aufs_ii;
1facf9fc 15390+
537831f9 15391+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 15392+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 15393+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
15394+ inode_init_once(&c->vfs_inode);
15395+}
1facf9fc 15396+
4a4d8108
AM
15397+int au_iinfo_init(struct inode *inode)
15398+{
15399+ struct au_iinfo *iinfo;
15400+ struct super_block *sb;
15401+ int nbr, i;
1facf9fc 15402+
4a4d8108
AM
15403+ sb = inode->i_sb;
15404+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
15405+ nbr = au_sbend(sb) + 1;
15406+ if (unlikely(nbr <= 0))
15407+ nbr = 1;
15408+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
15409+ if (iinfo->ii_hinode) {
7f207e10 15410+ au_ninodes_inc(sb);
4a4d8108
AM
15411+ for (i = 0; i < nbr; i++)
15412+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 15413+
537831f9 15414+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
15415+ iinfo->ii_bstart = -1;
15416+ iinfo->ii_bend = -1;
15417+ iinfo->ii_vdir = NULL;
15418+ return 0;
1308ab2a 15419+ }
4a4d8108
AM
15420+ return -ENOMEM;
15421+}
1facf9fc 15422+
4a4d8108
AM
15423+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
15424+{
15425+ int err, sz;
15426+ struct au_hinode *hip;
1facf9fc 15427+
4a4d8108
AM
15428+ AuRwMustWriteLock(&iinfo->ii_rwsem);
15429+
15430+ err = -ENOMEM;
15431+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
15432+ if (!sz)
15433+ sz = sizeof(*hip);
15434+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
15435+ if (hip) {
15436+ iinfo->ii_hinode = hip;
15437+ err = 0;
1308ab2a 15438+ }
4a4d8108 15439+
1308ab2a 15440+ return err;
1facf9fc 15441+}
15442+
4a4d8108 15443+void au_iinfo_fin(struct inode *inode)
1facf9fc 15444+{
4a4d8108
AM
15445+ struct au_iinfo *iinfo;
15446+ struct au_hinode *hi;
15447+ struct super_block *sb;
b752ccd1
AM
15448+ aufs_bindex_t bindex, bend;
15449+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 15450+
4a4d8108
AM
15451+ iinfo = au_ii(inode);
15452+ /* bad_inode case */
15453+ if (!iinfo)
15454+ return;
1308ab2a 15455+
b752ccd1 15456+ sb = inode->i_sb;
7f207e10 15457+ au_ninodes_dec(sb);
b752ccd1
AM
15458+ if (si_pid_test(sb))
15459+ au_xino_delete_inode(inode, unlinked);
15460+ else {
15461+ /*
15462+ * it is safe to hide the dependency between sbinfo and
15463+ * sb->s_umount.
15464+ */
15465+ lockdep_off();
15466+ si_noflush_read_lock(sb);
15467+ au_xino_delete_inode(inode, unlinked);
15468+ si_read_unlock(sb);
15469+ lockdep_on();
15470+ }
15471+
4a4d8108
AM
15472+ if (iinfo->ii_vdir)
15473+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 15474+
b752ccd1
AM
15475+ bindex = iinfo->ii_bstart;
15476+ if (bindex >= 0) {
15477+ hi = iinfo->ii_hinode + bindex;
4a4d8108 15478+ bend = iinfo->ii_bend;
b752ccd1
AM
15479+ while (bindex++ <= bend) {
15480+ if (hi->hi_inode)
4a4d8108 15481+ au_hiput(hi);
4a4d8108
AM
15482+ hi++;
15483+ }
15484+ }
4a4d8108 15485+ kfree(iinfo->ii_hinode);
027c5e7a 15486+ iinfo->ii_hinode = NULL;
4a4d8108 15487+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 15488+}
7f207e10
AM
15489diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
15490--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 15491+++ linux/fs/aufs/inode.c 2015-04-13 15:10:20.786823613 +0200
2000de60 15492@@ -0,0 +1,495 @@
4a4d8108 15493+/*
2000de60 15494+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
15495+ *
15496+ * This program, aufs is free software; you can redistribute it and/or modify
15497+ * it under the terms of the GNU General Public License as published by
15498+ * the Free Software Foundation; either version 2 of the License, or
15499+ * (at your option) any later version.
15500+ *
15501+ * This program is distributed in the hope that it will be useful,
15502+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15503+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15504+ * GNU General Public License for more details.
15505+ *
15506+ * You should have received a copy of the GNU General Public License
523b37e3 15507+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15508+ */
1facf9fc 15509+
4a4d8108
AM
15510+/*
15511+ * inode functions
15512+ */
1facf9fc 15513+
4a4d8108 15514+#include "aufs.h"
1308ab2a 15515+
4a4d8108
AM
15516+struct inode *au_igrab(struct inode *inode)
15517+{
15518+ if (inode) {
15519+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 15520+ ihold(inode);
1facf9fc 15521+ }
4a4d8108
AM
15522+ return inode;
15523+}
1facf9fc 15524+
4a4d8108
AM
15525+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
15526+{
15527+ au_cpup_attr_all(inode, /*force*/0);
537831f9 15528+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
15529+ if (do_version)
15530+ inode->i_version++;
dece6358 15531+}
1facf9fc 15532+
027c5e7a 15533+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 15534+{
4a4d8108 15535+ int err, e;
027c5e7a 15536+ umode_t type;
4a4d8108 15537+ aufs_bindex_t bindex, new_bindex;
1308ab2a 15538+ struct super_block *sb;
4a4d8108 15539+ struct au_iinfo *iinfo;
027c5e7a 15540+ struct au_hinode *p, *q, tmp;
1facf9fc 15541+
4a4d8108 15542+ IiMustWriteLock(inode);
1facf9fc 15543+
027c5e7a 15544+ *update = 0;
4a4d8108 15545+ sb = inode->i_sb;
027c5e7a 15546+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
15547+ iinfo = au_ii(inode);
15548+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
15549+ if (unlikely(err))
1308ab2a 15550+ goto out;
1facf9fc 15551+
027c5e7a 15552+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 15553+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
15554+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15555+ bindex++, p++) {
15556+ if (!p->hi_inode)
15557+ continue;
1facf9fc 15558+
027c5e7a 15559+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
15560+ new_bindex = au_br_index(sb, p->hi_id);
15561+ if (new_bindex == bindex)
15562+ continue;
1facf9fc 15563+
4a4d8108 15564+ if (new_bindex < 0) {
027c5e7a 15565+ *update = 1;
4a4d8108
AM
15566+ au_hiput(p);
15567+ p->hi_inode = NULL;
15568+ continue;
1308ab2a 15569+ }
4a4d8108
AM
15570+
15571+ if (new_bindex < iinfo->ii_bstart)
15572+ iinfo->ii_bstart = new_bindex;
15573+ if (iinfo->ii_bend < new_bindex)
15574+ iinfo->ii_bend = new_bindex;
15575+ /* swap two lower inode, and loop again */
15576+ q = iinfo->ii_hinode + new_bindex;
15577+ tmp = *q;
15578+ *q = *p;
15579+ *p = tmp;
15580+ if (tmp.hi_inode) {
15581+ bindex--;
15582+ p--;
1308ab2a 15583+ }
15584+ }
4a4d8108
AM
15585+ au_update_ibrange(inode, /*do_put_zero*/0);
15586+ e = au_dy_irefresh(inode);
15587+ if (unlikely(e && !err))
15588+ err = e;
1facf9fc 15589+
4f0767ce 15590+out:
027c5e7a
AM
15591+ AuTraceErr(err);
15592+ return err;
15593+}
15594+
15595+int au_refresh_hinode_self(struct inode *inode)
15596+{
15597+ int err, update;
15598+
15599+ err = au_ii_refresh(inode, &update);
15600+ if (!err)
15601+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
15602+
15603+ AuTraceErr(err);
4a4d8108
AM
15604+ return err;
15605+}
1facf9fc 15606+
4a4d8108
AM
15607+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
15608+{
027c5e7a 15609+ int err, e, update;
4a4d8108 15610+ unsigned int flags;
027c5e7a 15611+ umode_t mode;
4a4d8108 15612+ aufs_bindex_t bindex, bend;
027c5e7a 15613+ unsigned char isdir;
4a4d8108
AM
15614+ struct au_hinode *p;
15615+ struct au_iinfo *iinfo;
1facf9fc 15616+
027c5e7a 15617+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
15618+ if (unlikely(err))
15619+ goto out;
15620+
15621+ update = 0;
15622+ iinfo = au_ii(inode);
15623+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
15624+ mode = (inode->i_mode & S_IFMT);
15625+ isdir = S_ISDIR(mode);
4a4d8108
AM
15626+ flags = au_hi_flags(inode, isdir);
15627+ bend = au_dbend(dentry);
15628+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
15629+ struct inode *h_i;
15630+ struct dentry *h_d;
15631+
15632+ h_d = au_h_dptr(dentry, bindex);
15633+ if (!h_d || !h_d->d_inode)
15634+ continue;
15635+
027c5e7a 15636+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
15637+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
15638+ h_i = au_h_iptr(inode, bindex);
15639+ if (h_i) {
15640+ if (h_i == h_d->d_inode)
15641+ continue;
15642+ err = -EIO;
15643+ break;
15644+ }
15645+ }
15646+ if (bindex < iinfo->ii_bstart)
15647+ iinfo->ii_bstart = bindex;
15648+ if (iinfo->ii_bend < bindex)
15649+ iinfo->ii_bend = bindex;
15650+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
15651+ update = 1;
1308ab2a 15652+ }
4a4d8108
AM
15653+ au_update_ibrange(inode, /*do_put_zero*/0);
15654+ e = au_dy_irefresh(inode);
15655+ if (unlikely(e && !err))
15656+ err = e;
027c5e7a
AM
15657+ if (!err)
15658+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 15659+
4f0767ce 15660+out:
4a4d8108 15661+ AuTraceErr(err);
1308ab2a 15662+ return err;
dece6358
AM
15663+}
15664+
4a4d8108 15665+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 15666+{
4a4d8108
AM
15667+ int err;
15668+ unsigned int flags;
15669+ umode_t mode;
15670+ aufs_bindex_t bindex, bstart, btail;
15671+ unsigned char isdir;
15672+ struct dentry *h_dentry;
15673+ struct inode *h_inode;
15674+ struct au_iinfo *iinfo;
dece6358 15675+
4a4d8108 15676+ IiMustWriteLock(inode);
dece6358 15677+
4a4d8108
AM
15678+ err = 0;
15679+ isdir = 0;
15680+ bstart = au_dbstart(dentry);
15681+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
15682+ mode = h_inode->i_mode;
15683+ switch (mode & S_IFMT) {
15684+ case S_IFREG:
15685+ btail = au_dbtail(dentry);
15686+ inode->i_op = &aufs_iop;
15687+ inode->i_fop = &aufs_file_fop;
15688+ err = au_dy_iaop(inode, bstart, h_inode);
15689+ if (unlikely(err))
15690+ goto out;
15691+ break;
15692+ case S_IFDIR:
15693+ isdir = 1;
15694+ btail = au_dbtaildir(dentry);
15695+ inode->i_op = &aufs_dir_iop;
15696+ inode->i_fop = &aufs_dir_fop;
15697+ break;
15698+ case S_IFLNK:
15699+ btail = au_dbtail(dentry);
15700+ inode->i_op = &aufs_symlink_iop;
15701+ break;
15702+ case S_IFBLK:
15703+ case S_IFCHR:
15704+ case S_IFIFO:
15705+ case S_IFSOCK:
15706+ btail = au_dbtail(dentry);
15707+ inode->i_op = &aufs_iop;
38d290e6 15708+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
15709+ break;
15710+ default:
15711+ AuIOErr("Unknown file type 0%o\n", mode);
15712+ err = -EIO;
1308ab2a 15713+ goto out;
4a4d8108 15714+ }
dece6358 15715+
4a4d8108
AM
15716+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
15717+ flags = au_hi_flags(inode, isdir);
15718+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
15719+ && au_ftest_hi(flags, HNOTIFY)
15720+ && dentry->d_name.len > AUFS_WH_PFX_LEN
15721+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
15722+ au_fclr_hi(flags, HNOTIFY);
15723+ iinfo = au_ii(inode);
15724+ iinfo->ii_bstart = bstart;
15725+ iinfo->ii_bend = btail;
15726+ for (bindex = bstart; bindex <= btail; bindex++) {
15727+ h_dentry = au_h_dptr(dentry, bindex);
15728+ if (h_dentry)
15729+ au_set_h_iptr(inode, bindex,
15730+ au_igrab(h_dentry->d_inode), flags);
15731+ }
15732+ au_cpup_attr_all(inode, /*force*/1);
c1595e42
JR
15733+ /*
15734+ * to force calling aufs_get_acl() every time,
15735+ * do not call cache_no_acl() for aufs inode.
15736+ */
dece6358 15737+
4f0767ce 15738+out:
4a4d8108
AM
15739+ return err;
15740+}
dece6358 15741+
027c5e7a
AM
15742+/*
15743+ * successful returns with iinfo write_locked
15744+ * minus: errno
15745+ * zero: success, matched
15746+ * plus: no error, but unmatched
15747+ */
15748+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
15749+{
15750+ int err;
537831f9
AM
15751+ unsigned int gen;
15752+ struct au_iigen iigen;
4a4d8108
AM
15753+ aufs_bindex_t bindex, bend;
15754+ struct inode *h_inode, *h_dinode;
dece6358 15755+
4a4d8108
AM
15756+ /*
15757+ * before this function, if aufs got any iinfo lock, it must be only
15758+ * one, the parent dir.
15759+ * it can happen by UDBA and the obsoleted inode number.
15760+ */
15761+ err = -EIO;
15762+ if (unlikely(inode->i_ino == parent_ino(dentry)))
15763+ goto out;
15764+
027c5e7a 15765+ err = 1;
4a4d8108
AM
15766+ ii_write_lock_new_child(inode);
15767+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
15768+ bend = au_ibend(inode);
15769+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
15770+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
15771+ if (!h_inode || h_inode != h_dinode)
15772+ continue;
15773+
15774+ err = 0;
15775+ gen = au_iigen(inode, &iigen);
15776+ if (gen == au_digen(dentry)
15777+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 15778+ break;
537831f9
AM
15779+
15780+ /* fully refresh inode using dentry */
15781+ err = au_refresh_hinode(inode, dentry);
15782+ if (!err)
15783+ au_update_iigen(inode, /*half*/0);
15784+ break;
1facf9fc 15785+ }
dece6358 15786+
4a4d8108
AM
15787+ if (unlikely(err))
15788+ ii_write_unlock(inode);
4f0767ce 15789+out:
1facf9fc 15790+ return err;
15791+}
1facf9fc 15792+
4a4d8108
AM
15793+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
15794+ unsigned int d_type, ino_t *ino)
1facf9fc 15795+{
4a4d8108
AM
15796+ int err;
15797+ struct mutex *mtx;
1facf9fc 15798+
b752ccd1 15799+ /* prevent hardlinked inode number from race condition */
4a4d8108 15800+ mtx = NULL;
b752ccd1 15801+ if (d_type != DT_DIR) {
4a4d8108
AM
15802+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
15803+ mutex_lock(mtx);
15804+ }
15805+ err = au_xino_read(sb, bindex, h_ino, ino);
15806+ if (unlikely(err))
15807+ goto out;
1308ab2a 15808+
4a4d8108
AM
15809+ if (!*ino) {
15810+ err = -EIO;
15811+ *ino = au_xino_new_ino(sb);
15812+ if (unlikely(!*ino))
1facf9fc 15813+ goto out;
4a4d8108
AM
15814+ err = au_xino_write(sb, bindex, h_ino, *ino);
15815+ if (unlikely(err))
1308ab2a 15816+ goto out;
1308ab2a 15817+ }
1facf9fc 15818+
4f0767ce 15819+out:
b752ccd1 15820+ if (mtx)
4a4d8108 15821+ mutex_unlock(mtx);
1facf9fc 15822+ return err;
15823+}
15824+
4a4d8108
AM
15825+/* successful returns with iinfo write_locked */
15826+/* todo: return with unlocked? */
15827+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 15828+{
2000de60 15829+ struct inode *inode;
4a4d8108
AM
15830+ struct dentry *h_dentry;
15831+ struct super_block *sb;
b752ccd1 15832+ struct mutex *mtx;
4a4d8108 15833+ ino_t h_ino, ino;
1716fcea 15834+ int err;
4a4d8108 15835+ aufs_bindex_t bstart;
1facf9fc 15836+
4a4d8108
AM
15837+ sb = dentry->d_sb;
15838+ bstart = au_dbstart(dentry);
15839+ h_dentry = au_h_dptr(dentry, bstart);
2000de60 15840+ h_ino = h_dentry->d_inode->i_ino;
b752ccd1
AM
15841+
15842+ /*
15843+ * stop 'race'-ing between hardlinks under different
15844+ * parents.
15845+ */
15846+ mtx = NULL;
2000de60 15847+ if (!d_is_dir(h_dentry))
b752ccd1
AM
15848+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
15849+
4f0767ce 15850+new_ino:
b752ccd1
AM
15851+ if (mtx)
15852+ mutex_lock(mtx);
4a4d8108
AM
15853+ err = au_xino_read(sb, bstart, h_ino, &ino);
15854+ inode = ERR_PTR(err);
15855+ if (unlikely(err))
15856+ goto out;
b752ccd1 15857+
4a4d8108
AM
15858+ if (!ino) {
15859+ ino = au_xino_new_ino(sb);
15860+ if (unlikely(!ino)) {
15861+ inode = ERR_PTR(-EIO);
dece6358
AM
15862+ goto out;
15863+ }
15864+ }
1facf9fc 15865+
4a4d8108
AM
15866+ AuDbg("i%lu\n", (unsigned long)ino);
15867+ inode = au_iget_locked(sb, ino);
15868+ err = PTR_ERR(inode);
15869+ if (IS_ERR(inode))
1facf9fc 15870+ goto out;
1facf9fc 15871+
4a4d8108
AM
15872+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
15873+ if (inode->i_state & I_NEW) {
1716fcea 15874+ /* verbose coding for lock class name */
2000de60 15875+ if (unlikely(d_is_symlink(h_dentry)))
1716fcea
AM
15876+ au_rw_class(&au_ii(inode)->ii_rwsem,
15877+ au_lc_key + AuLcSymlink_IIINFO);
2000de60 15878+ else if (unlikely(d_is_dir(h_dentry)))
1716fcea
AM
15879+ au_rw_class(&au_ii(inode)->ii_rwsem,
15880+ au_lc_key + AuLcDir_IIINFO);
15881+ else /* likely */
15882+ au_rw_class(&au_ii(inode)->ii_rwsem,
15883+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 15884+
4a4d8108
AM
15885+ ii_write_lock_new_child(inode);
15886+ err = set_inode(inode, dentry);
15887+ if (!err) {
15888+ unlock_new_inode(inode);
15889+ goto out; /* success */
15890+ }
1308ab2a 15891+
027c5e7a
AM
15892+ /*
15893+ * iget_failed() calls iput(), but we need to call
15894+ * ii_write_unlock() after iget_failed(). so dirty hack for
15895+ * i_count.
15896+ */
15897+ atomic_inc(&inode->i_count);
4a4d8108 15898+ iget_failed(inode);
027c5e7a
AM
15899+ ii_write_unlock(inode);
15900+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
15901+ /* ignore this error */
15902+ goto out_iput;
15903+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
15904+ /*
15905+ * horrible race condition between lookup, readdir and copyup
15906+ * (or something).
15907+ */
15908+ if (mtx)
15909+ mutex_unlock(mtx);
027c5e7a
AM
15910+ err = reval_inode(inode, dentry);
15911+ if (unlikely(err < 0)) {
15912+ mtx = NULL;
15913+ goto out_iput;
15914+ }
15915+
b752ccd1
AM
15916+ if (!err) {
15917+ mtx = NULL;
4a4d8108 15918+ goto out; /* success */
b752ccd1
AM
15919+ } else if (mtx)
15920+ mutex_lock(mtx);
4a4d8108
AM
15921+ }
15922+
15923+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
15924+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3
AM
15925+ " b%d, %s, %pd, hi%lu, i%lu.\n",
15926+ bstart, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
15927+ (unsigned long)h_ino, (unsigned long)ino);
15928+ ino = 0;
15929+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
15930+ if (!err) {
15931+ iput(inode);
b752ccd1
AM
15932+ if (mtx)
15933+ mutex_unlock(mtx);
4a4d8108
AM
15934+ goto new_ino;
15935+ }
1308ab2a 15936+
4f0767ce 15937+out_iput:
4a4d8108 15938+ iput(inode);
4a4d8108 15939+ inode = ERR_PTR(err);
4f0767ce 15940+out:
b752ccd1
AM
15941+ if (mtx)
15942+ mutex_unlock(mtx);
4a4d8108 15943+ return inode;
1facf9fc 15944+}
15945+
4a4d8108 15946+/* ---------------------------------------------------------------------- */
1facf9fc 15947+
4a4d8108
AM
15948+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
15949+ struct inode *inode)
15950+{
15951+ int err;
076b876e 15952+ struct inode *hi;
1facf9fc 15953+
4a4d8108 15954+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 15955+
4a4d8108
AM
15956+ /* pseudo-link after flushed may happen out of bounds */
15957+ if (!err
15958+ && inode
15959+ && au_ibstart(inode) <= bindex
15960+ && bindex <= au_ibend(inode)) {
15961+ /*
15962+ * permission check is unnecessary since vfsub routine
15963+ * will be called later
15964+ */
076b876e 15965+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
15966+ if (hi)
15967+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 15968+ }
15969+
4a4d8108
AM
15970+ return err;
15971+}
dece6358 15972+
4a4d8108
AM
15973+int au_test_h_perm(struct inode *h_inode, int mask)
15974+{
2dfbb274 15975+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
15976+ return 0;
15977+ return inode_permission(h_inode, mask);
15978+}
1facf9fc 15979+
4a4d8108
AM
15980+int au_test_h_perm_sio(struct inode *h_inode, int mask)
15981+{
15982+ if (au_test_nfs(h_inode->i_sb)
15983+ && (mask & MAY_WRITE)
15984+ && S_ISDIR(h_inode->i_mode))
15985+ mask |= MAY_READ; /* force permission check */
15986+ return au_test_h_perm(h_inode, mask);
1facf9fc 15987+}
7f207e10
AM
15988diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
15989--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
15990+++ linux/fs/aufs/inode.h 2015-04-13 15:10:20.786823613 +0200
15991@@ -0,0 +1,670 @@
4a4d8108 15992+/*
2000de60 15993+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
15994+ *
15995+ * This program, aufs is free software; you can redistribute it and/or modify
15996+ * it under the terms of the GNU General Public License as published by
15997+ * the Free Software Foundation; either version 2 of the License, or
15998+ * (at your option) any later version.
15999+ *
16000+ * This program is distributed in the hope that it will be useful,
16001+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16002+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16003+ * GNU General Public License for more details.
16004+ *
16005+ * You should have received a copy of the GNU General Public License
523b37e3 16006+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16007+ */
1facf9fc 16008+
1308ab2a 16009+/*
4a4d8108 16010+ * inode operations
1308ab2a 16011+ */
dece6358 16012+
4a4d8108
AM
16013+#ifndef __AUFS_INODE_H__
16014+#define __AUFS_INODE_H__
dece6358 16015+
4a4d8108 16016+#ifdef __KERNEL__
1308ab2a 16017+
4a4d8108 16018+#include <linux/fsnotify.h>
4a4d8108 16019+#include "rwsem.h"
1308ab2a 16020+
4a4d8108 16021+struct vfsmount;
1facf9fc 16022+
4a4d8108
AM
16023+struct au_hnotify {
16024+#ifdef CONFIG_AUFS_HNOTIFY
16025+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 16026+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 16027+ struct fsnotify_mark hn_mark;
4a4d8108 16028+#endif
7f207e10 16029+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
16030+#endif
16031+} ____cacheline_aligned_in_smp;
1facf9fc 16032+
4a4d8108
AM
16033+struct au_hinode {
16034+ struct inode *hi_inode;
16035+ aufs_bindex_t hi_id;
16036+#ifdef CONFIG_AUFS_HNOTIFY
16037+ struct au_hnotify *hi_notify;
16038+#endif
dece6358 16039+
4a4d8108
AM
16040+ /* reference to the copied-up whiteout with get/put */
16041+ struct dentry *hi_whdentry;
16042+};
dece6358 16043+
537831f9
AM
16044+/* ig_flags */
16045+#define AuIG_HALF_REFRESHED 1
16046+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
16047+#define au_ig_fset(flags, name) \
16048+ do { (flags) |= AuIG_##name; } while (0)
16049+#define au_ig_fclr(flags, name) \
16050+ do { (flags) &= ~AuIG_##name; } while (0)
16051+
16052+struct au_iigen {
16053+ __u32 ig_generation, ig_flags;
16054+};
16055+
4a4d8108
AM
16056+struct au_vdir;
16057+struct au_iinfo {
537831f9 16058+ spinlock_t ii_genspin;
7a9e40b8 16059+ struct au_iigen ii_generation;
4a4d8108 16060+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 16061+
4a4d8108
AM
16062+ struct au_rwsem ii_rwsem;
16063+ aufs_bindex_t ii_bstart, ii_bend;
16064+ __u32 ii_higen;
16065+ struct au_hinode *ii_hinode;
16066+ struct au_vdir *ii_vdir;
16067+};
1facf9fc 16068+
4a4d8108
AM
16069+struct au_icntnr {
16070+ struct au_iinfo iinfo;
16071+ struct inode vfs_inode;
16072+} ____cacheline_aligned_in_smp;
1308ab2a 16073+
4a4d8108
AM
16074+/* au_pin flags */
16075+#define AuPin_DI_LOCKED 1
16076+#define AuPin_MNT_WRITE (1 << 1)
16077+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
16078+#define au_fset_pin(flags, name) \
16079+ do { (flags) |= AuPin_##name; } while (0)
16080+#define au_fclr_pin(flags, name) \
16081+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
16082+
16083+struct au_pin {
16084+ /* input */
16085+ struct dentry *dentry;
16086+ unsigned int udba;
16087+ unsigned char lsc_di, lsc_hi, flags;
16088+ aufs_bindex_t bindex;
16089+
16090+ /* output */
16091+ struct dentry *parent;
16092+ struct au_hinode *hdir;
16093+ struct vfsmount *h_mnt;
86dc4139
AM
16094+
16095+ /* temporary unlock/relock for copyup */
16096+ struct dentry *h_dentry, *h_parent;
16097+ struct au_branch *br;
16098+ struct task_struct *task;
4a4d8108 16099+};
1facf9fc 16100+
86dc4139 16101+void au_pin_hdir_unlock(struct au_pin *p);
c1595e42 16102+int au_pin_hdir_lock(struct au_pin *p);
86dc4139
AM
16103+int au_pin_hdir_relock(struct au_pin *p);
16104+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
16105+void au_pin_hdir_acquire_nest(struct au_pin *p);
16106+void au_pin_hdir_release(struct au_pin *p);
16107+
1308ab2a 16108+/* ---------------------------------------------------------------------- */
16109+
4a4d8108 16110+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 16111+{
4a4d8108 16112+ struct au_iinfo *iinfo;
1facf9fc 16113+
4a4d8108
AM
16114+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
16115+ if (iinfo->ii_hinode)
16116+ return iinfo;
16117+ return NULL; /* debugging bad_inode case */
16118+}
1facf9fc 16119+
4a4d8108 16120+/* ---------------------------------------------------------------------- */
1facf9fc 16121+
4a4d8108
AM
16122+/* inode.c */
16123+struct inode *au_igrab(struct inode *inode);
027c5e7a 16124+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
16125+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
16126+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16127+ unsigned int d_type, ino_t *ino);
16128+struct inode *au_new_inode(struct dentry *dentry, int must_new);
16129+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16130+ struct inode *inode);
16131+int au_test_h_perm(struct inode *h_inode, int mask);
16132+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 16133+
4a4d8108
AM
16134+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
16135+ ino_t h_ino, unsigned int d_type, ino_t *ino)
16136+{
16137+#ifdef CONFIG_AUFS_SHWH
16138+ return au_ino(sb, bindex, h_ino, d_type, ino);
16139+#else
16140+ return 0;
16141+#endif
16142+}
1facf9fc 16143+
4a4d8108
AM
16144+/* i_op.c */
16145+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 16146+
4a4d8108
AM
16147+/* au_wr_dir flags */
16148+#define AuWrDir_ADD_ENTRY 1
7e9cd9fe
AM
16149+#define AuWrDir_ISDIR (1 << 1)
16150+#define AuWrDir_TMPFILE (1 << 2)
4a4d8108 16151+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
16152+#define au_fset_wrdir(flags, name) \
16153+ do { (flags) |= AuWrDir_##name; } while (0)
16154+#define au_fclr_wrdir(flags, name) \
16155+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 16156+
4a4d8108
AM
16157+struct au_wr_dir_args {
16158+ aufs_bindex_t force_btgt;
16159+ unsigned char flags;
16160+};
16161+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16162+ struct au_wr_dir_args *args);
dece6358 16163+
4a4d8108
AM
16164+struct dentry *au_pinned_h_parent(struct au_pin *pin);
16165+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
16166+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16167+ unsigned int udba, unsigned char flags);
16168+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16169+ unsigned int udba, unsigned char flags) __must_check;
16170+int au_do_pin(struct au_pin *pin) __must_check;
16171+void au_unpin(struct au_pin *pin);
c1595e42
JR
16172+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
16173+
16174+#define AuIcpup_DID_CPUP 1
16175+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
16176+#define au_fset_icpup(flags, name) \
16177+ do { (flags) |= AuIcpup_##name; } while (0)
16178+#define au_fclr_icpup(flags, name) \
16179+ do { (flags) &= ~AuIcpup_##name; } while (0)
16180+
16181+struct au_icpup_args {
16182+ unsigned char flags;
16183+ unsigned char pin_flags;
16184+ aufs_bindex_t btgt;
16185+ unsigned int udba;
16186+ struct au_pin pin;
16187+ struct path h_path;
16188+ struct inode *h_inode;
16189+};
16190+
16191+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
16192+ struct au_icpup_args *a);
16193+
16194+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path);
1facf9fc 16195+
4a4d8108
AM
16196+/* i_op_add.c */
16197+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
16198+ struct dentry *h_parent, int isdir);
7eafdf33
AM
16199+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
16200+ dev_t dev);
4a4d8108 16201+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 16202+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 16203+ bool want_excl);
38d290e6 16204+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
16205+int aufs_link(struct dentry *src_dentry, struct inode *dir,
16206+ struct dentry *dentry);
7eafdf33 16207+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 16208+
4a4d8108
AM
16209+/* i_op_del.c */
16210+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
16211+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
16212+ struct dentry *h_parent, int isdir);
16213+int aufs_unlink(struct inode *dir, struct dentry *dentry);
16214+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 16215+
4a4d8108
AM
16216+/* i_op_ren.c */
16217+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
16218+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
16219+ struct inode *dir, struct dentry *dentry);
1facf9fc 16220+
4a4d8108
AM
16221+/* iinfo.c */
16222+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
16223+void au_hiput(struct au_hinode *hinode);
16224+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
16225+ struct dentry *h_wh);
16226+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 16227+
4a4d8108
AM
16228+/* hinode flags */
16229+#define AuHi_XINO 1
16230+#define AuHi_HNOTIFY (1 << 1)
16231+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
16232+#define au_fset_hi(flags, name) \
16233+ do { (flags) |= AuHi_##name; } while (0)
16234+#define au_fclr_hi(flags, name) \
16235+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 16236+
4a4d8108
AM
16237+#ifndef CONFIG_AUFS_HNOTIFY
16238+#undef AuHi_HNOTIFY
16239+#define AuHi_HNOTIFY 0
16240+#endif
1facf9fc 16241+
4a4d8108
AM
16242+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
16243+ struct inode *h_inode, unsigned int flags);
1facf9fc 16244+
537831f9 16245+void au_update_iigen(struct inode *inode, int half);
4a4d8108 16246+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 16247+
4a4d8108
AM
16248+void au_icntnr_init_once(void *_c);
16249+int au_iinfo_init(struct inode *inode);
16250+void au_iinfo_fin(struct inode *inode);
16251+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 16252+
e49829fe 16253+#ifdef CONFIG_PROC_FS
4a4d8108 16254+/* plink.c */
e49829fe 16255+int au_plink_maint(struct super_block *sb, int flags);
7e9cd9fe 16256+struct au_sbinfo;
e49829fe
JR
16257+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
16258+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
16259+#ifdef CONFIG_AUFS_DEBUG
16260+void au_plink_list(struct super_block *sb);
16261+#else
16262+AuStubVoid(au_plink_list, struct super_block *sb)
16263+#endif
16264+int au_plink_test(struct inode *inode);
16265+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
16266+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
16267+ struct dentry *h_dentry);
e49829fe
JR
16268+void au_plink_put(struct super_block *sb, int verbose);
16269+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 16270+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
16271+#else
16272+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
16273+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
16274+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
16275+AuStubVoid(au_plink_list, struct super_block *sb);
16276+AuStubInt0(au_plink_test, struct inode *inode);
16277+AuStub(struct dentry *, au_plink_lkup, return NULL,
16278+ struct inode *inode, aufs_bindex_t bindex);
16279+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
16280+ struct dentry *h_dentry);
16281+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
16282+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
16283+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
16284+#endif /* CONFIG_PROC_FS */
1facf9fc 16285+
c1595e42
JR
16286+#ifdef CONFIG_AUFS_XATTR
16287+/* xattr.c */
7e9cd9fe
AM
16288+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
16289+ unsigned int verbose);
c1595e42
JR
16290+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
16291+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
16292+ size_t size);
16293+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
16294+ size_t size, int flags);
16295+int aufs_removexattr(struct dentry *dentry, const char *name);
16296+
16297+/* void au_xattr_init(struct super_block *sb); */
16298+#else
16299+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe 16300+ int ignore_flags, unsigned int verbose);
c1595e42
JR
16301+/* AuStubVoid(au_xattr_init, struct super_block *sb); */
16302+#endif
16303+
16304+#ifdef CONFIG_FS_POSIX_ACL
16305+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
16306+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
16307+#endif
16308+
16309+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
16310+enum {
16311+ AU_XATTR_SET,
16312+ AU_XATTR_REMOVE,
16313+ AU_ACL_SET
16314+};
16315+
16316+struct au_srxattr {
16317+ int type;
16318+ union {
16319+ struct {
16320+ const char *name;
16321+ const void *value;
16322+ size_t size;
16323+ int flags;
16324+ } set;
16325+ struct {
16326+ const char *name;
16327+ } remove;
16328+ struct {
16329+ struct posix_acl *acl;
16330+ int type;
16331+ } acl_set;
16332+ } u;
16333+};
16334+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg);
16335+#endif
16336+
4a4d8108 16337+/* ---------------------------------------------------------------------- */
1308ab2a 16338+
4a4d8108
AM
16339+/* lock subclass for iinfo */
16340+enum {
16341+ AuLsc_II_CHILD, /* child first */
16342+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
16343+ AuLsc_II_CHILD3, /* copyup dirs */
16344+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
16345+ AuLsc_II_PARENT2,
16346+ AuLsc_II_PARENT3, /* copyup dirs */
16347+ AuLsc_II_NEW_CHILD
16348+};
1308ab2a 16349+
1facf9fc 16350+/*
4a4d8108
AM
16351+ * ii_read_lock_child, ii_write_lock_child,
16352+ * ii_read_lock_child2, ii_write_lock_child2,
16353+ * ii_read_lock_child3, ii_write_lock_child3,
16354+ * ii_read_lock_parent, ii_write_lock_parent,
16355+ * ii_read_lock_parent2, ii_write_lock_parent2,
16356+ * ii_read_lock_parent3, ii_write_lock_parent3,
16357+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 16358+ */
4a4d8108
AM
16359+#define AuReadLockFunc(name, lsc) \
16360+static inline void ii_read_lock_##name(struct inode *i) \
16361+{ \
16362+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16363+}
16364+
16365+#define AuWriteLockFunc(name, lsc) \
16366+static inline void ii_write_lock_##name(struct inode *i) \
16367+{ \
16368+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16369+}
16370+
16371+#define AuRWLockFuncs(name, lsc) \
16372+ AuReadLockFunc(name, lsc) \
16373+ AuWriteLockFunc(name, lsc)
16374+
16375+AuRWLockFuncs(child, CHILD);
16376+AuRWLockFuncs(child2, CHILD2);
16377+AuRWLockFuncs(child3, CHILD3);
16378+AuRWLockFuncs(parent, PARENT);
16379+AuRWLockFuncs(parent2, PARENT2);
16380+AuRWLockFuncs(parent3, PARENT3);
16381+AuRWLockFuncs(new_child, NEW_CHILD);
16382+
16383+#undef AuReadLockFunc
16384+#undef AuWriteLockFunc
16385+#undef AuRWLockFuncs
1facf9fc 16386+
16387+/*
4a4d8108 16388+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 16389+ */
4a4d8108 16390+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 16391+
4a4d8108
AM
16392+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
16393+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
16394+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 16395+
4a4d8108 16396+/* ---------------------------------------------------------------------- */
1308ab2a 16397+
027c5e7a
AM
16398+static inline void au_icntnr_init(struct au_icntnr *c)
16399+{
16400+#ifdef CONFIG_AUFS_DEBUG
16401+ c->vfs_inode.i_mode = 0;
16402+#endif
16403+}
16404+
537831f9 16405+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 16406+{
537831f9
AM
16407+ unsigned int gen;
16408+ struct au_iinfo *iinfo;
16409+
16410+ iinfo = au_ii(inode);
16411+ spin_lock(&iinfo->ii_genspin);
16412+ if (iigen)
16413+ *iigen = iinfo->ii_generation;
16414+ gen = iinfo->ii_generation.ig_generation;
16415+ spin_unlock(&iinfo->ii_genspin);
16416+
16417+ return gen;
4a4d8108 16418+}
1308ab2a 16419+
4a4d8108
AM
16420+/* tiny test for inode number */
16421+/* tmpfs generation is too rough */
16422+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
16423+{
16424+ struct au_iinfo *iinfo;
1308ab2a 16425+
4a4d8108
AM
16426+ iinfo = au_ii(inode);
16427+ AuRwMustAnyLock(&iinfo->ii_rwsem);
16428+ return !(iinfo->ii_hsb1 == h_inode->i_sb
16429+ && iinfo->ii_higen == h_inode->i_generation);
16430+}
1308ab2a 16431+
4a4d8108
AM
16432+static inline void au_iigen_dec(struct inode *inode)
16433+{
537831f9
AM
16434+ struct au_iinfo *iinfo;
16435+
16436+ iinfo = au_ii(inode);
16437+ spin_lock(&iinfo->ii_genspin);
16438+ iinfo->ii_generation.ig_generation--;
16439+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
16440+}
16441+
16442+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
16443+{
16444+ int err;
16445+
16446+ err = 0;
537831f9 16447+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
16448+ err = -EIO;
16449+
16450+ return err;
4a4d8108 16451+}
1308ab2a 16452+
4a4d8108 16453+/* ---------------------------------------------------------------------- */
1308ab2a 16454+
4a4d8108
AM
16455+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
16456+ aufs_bindex_t bindex)
16457+{
16458+ IiMustAnyLock(inode);
16459+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
16460+}
1308ab2a 16461+
4a4d8108
AM
16462+static inline aufs_bindex_t au_ibstart(struct inode *inode)
16463+{
16464+ IiMustAnyLock(inode);
16465+ return au_ii(inode)->ii_bstart;
16466+}
1308ab2a 16467+
4a4d8108
AM
16468+static inline aufs_bindex_t au_ibend(struct inode *inode)
16469+{
16470+ IiMustAnyLock(inode);
16471+ return au_ii(inode)->ii_bend;
16472+}
1308ab2a 16473+
4a4d8108
AM
16474+static inline struct au_vdir *au_ivdir(struct inode *inode)
16475+{
16476+ IiMustAnyLock(inode);
16477+ return au_ii(inode)->ii_vdir;
16478+}
1308ab2a 16479+
4a4d8108
AM
16480+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
16481+{
16482+ IiMustAnyLock(inode);
16483+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
16484+}
1308ab2a 16485+
4a4d8108 16486+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16487+{
4a4d8108
AM
16488+ IiMustWriteLock(inode);
16489+ au_ii(inode)->ii_bstart = bindex;
16490+}
1308ab2a 16491+
4a4d8108
AM
16492+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
16493+{
16494+ IiMustWriteLock(inode);
16495+ au_ii(inode)->ii_bend = bindex;
1308ab2a 16496+}
16497+
4a4d8108
AM
16498+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
16499+{
16500+ IiMustWriteLock(inode);
16501+ au_ii(inode)->ii_vdir = vdir;
16502+}
1facf9fc 16503+
4a4d8108 16504+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16505+{
4a4d8108
AM
16506+ IiMustAnyLock(inode);
16507+ return au_ii(inode)->ii_hinode + bindex;
16508+}
dece6358 16509+
4a4d8108 16510+/* ---------------------------------------------------------------------- */
1facf9fc 16511+
4a4d8108
AM
16512+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
16513+{
16514+ if (pin)
16515+ return pin->parent;
16516+ return NULL;
1facf9fc 16517+}
16518+
4a4d8108 16519+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 16520+{
4a4d8108
AM
16521+ if (pin && pin->hdir)
16522+ return pin->hdir->hi_inode;
16523+ return NULL;
1308ab2a 16524+}
1facf9fc 16525+
4a4d8108
AM
16526+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
16527+{
16528+ if (pin)
16529+ return pin->hdir;
16530+ return NULL;
16531+}
1facf9fc 16532+
4a4d8108 16533+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 16534+{
4a4d8108
AM
16535+ if (pin)
16536+ pin->dentry = dentry;
16537+}
1308ab2a 16538+
4a4d8108
AM
16539+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
16540+ unsigned char lflag)
16541+{
16542+ if (pin) {
7f207e10 16543+ if (lflag)
4a4d8108 16544+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 16545+ else
4a4d8108 16546+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 16547+ }
4a4d8108
AM
16548+}
16549+
7e9cd9fe 16550+#if 0 /* reserved */
4a4d8108
AM
16551+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
16552+{
16553+ if (pin) {
16554+ dput(pin->parent);
16555+ pin->parent = dget(parent);
1facf9fc 16556+ }
4a4d8108 16557+}
7e9cd9fe 16558+#endif
1facf9fc 16559+
4a4d8108
AM
16560+/* ---------------------------------------------------------------------- */
16561+
027c5e7a 16562+struct au_branch;
4a4d8108
AM
16563+#ifdef CONFIG_AUFS_HNOTIFY
16564+struct au_hnotify_op {
16565+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 16566+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
16567+
16568+ /*
16569+ * if it returns true, the the caller should free hinode->hi_notify,
16570+ * otherwise ->free() frees it.
16571+ */
16572+ int (*free)(struct au_hinode *hinode,
16573+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
16574+
16575+ void (*fin)(void);
16576+ int (*init)(void);
027c5e7a
AM
16577+
16578+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
16579+ void (*fin_br)(struct au_branch *br);
16580+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
16581+};
16582+
16583+/* hnotify.c */
027c5e7a 16584+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
16585+void au_hn_free(struct au_hinode *hinode);
16586+void au_hn_ctl(struct au_hinode *hinode, int do_set);
16587+void au_hn_reset(struct inode *inode, unsigned int flags);
16588+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
16589+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
16590+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
16591+int au_hnotify_init_br(struct au_branch *br, int perm);
16592+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
16593+int __init au_hnotify_init(void);
16594+void au_hnotify_fin(void);
16595+
7f207e10 16596+/* hfsnotify.c */
4a4d8108
AM
16597+extern const struct au_hnotify_op au_hnotify_op;
16598+
16599+static inline
16600+void au_hn_init(struct au_hinode *hinode)
16601+{
16602+ hinode->hi_notify = NULL;
1308ab2a 16603+}
16604+
53392da6
AM
16605+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
16606+{
16607+ return hinode->hi_notify;
16608+}
16609+
4a4d8108 16610+#else
c1595e42
JR
16611+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
16612+ struct au_hinode *hinode __maybe_unused,
16613+ struct inode *inode __maybe_unused)
16614+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
4a4d8108
AM
16615+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
16616+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
16617+ int do_set __maybe_unused)
16618+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
16619+ unsigned int flags __maybe_unused)
027c5e7a
AM
16620+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
16621+ struct au_branch *br __maybe_unused,
16622+ int perm __maybe_unused)
16623+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
16624+ int perm __maybe_unused)
16625+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
16626+AuStubInt0(__init au_hnotify_init, void)
16627+AuStubVoid(au_hnotify_fin, void)
16628+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
16629+#endif /* CONFIG_AUFS_HNOTIFY */
16630+
16631+static inline void au_hn_suspend(struct au_hinode *hdir)
16632+{
16633+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 16634+}
16635+
4a4d8108 16636+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 16637+{
4a4d8108
AM
16638+ au_hn_ctl(hdir, /*do_set*/1);
16639+}
1308ab2a 16640+
4a4d8108
AM
16641+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
16642+{
16643+ mutex_lock(&hdir->hi_inode->i_mutex);
16644+ au_hn_suspend(hdir);
16645+}
dece6358 16646+
4a4d8108
AM
16647+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
16648+ unsigned int sc __maybe_unused)
16649+{
16650+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
16651+ au_hn_suspend(hdir);
1facf9fc 16652+}
1facf9fc 16653+
4a4d8108
AM
16654+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
16655+{
16656+ au_hn_resume(hdir);
16657+ mutex_unlock(&hdir->hi_inode->i_mutex);
16658+}
16659+
16660+#endif /* __KERNEL__ */
16661+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
16662diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
16663--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 16664+++ linux/fs/aufs/ioctl.c 2015-04-13 15:10:20.786823613 +0200
c1595e42 16665@@ -0,0 +1,219 @@
4a4d8108 16666+/*
2000de60 16667+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
16668+ *
16669+ * This program, aufs is free software; you can redistribute it and/or modify
16670+ * it under the terms of the GNU General Public License as published by
16671+ * the Free Software Foundation; either version 2 of the License, or
16672+ * (at your option) any later version.
16673+ *
16674+ * This program is distributed in the hope that it will be useful,
16675+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16676+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16677+ * GNU General Public License for more details.
16678+ *
16679+ * You should have received a copy of the GNU General Public License
523b37e3 16680+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16681+ */
16682+
16683+/*
16684+ * ioctl
16685+ * plink-management and readdir in userspace.
16686+ * assist the pathconf(3) wrapper library.
c2b27bf2 16687+ * move-down
076b876e 16688+ * File-based Hierarchical Storage Management.
4a4d8108
AM
16689+ */
16690+
c2b27bf2
AM
16691+#include <linux/compat.h>
16692+#include <linux/file.h>
4a4d8108
AM
16693+#include "aufs.h"
16694+
1e00d052 16695+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
16696+{
16697+ int err, fd;
16698+ aufs_bindex_t wbi, bindex, bend;
16699+ struct file *h_file;
16700+ struct super_block *sb;
16701+ struct dentry *root;
1e00d052
AM
16702+ struct au_branch *br;
16703+ struct aufs_wbr_fd wbrfd = {
16704+ .oflags = au_dir_roflags,
16705+ .brid = -1
16706+ };
16707+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
16708+ | O_NOATIME | O_CLOEXEC;
4a4d8108 16709+
1e00d052
AM
16710+ AuDebugOn(wbrfd.oflags & ~valid);
16711+
16712+ if (arg) {
16713+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
16714+ if (unlikely(err)) {
16715+ err = -EFAULT;
16716+ goto out;
16717+ }
16718+
16719+ err = -EINVAL;
16720+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
16721+ wbrfd.oflags |= au_dir_roflags;
16722+ AuDbg("0%o\n", wbrfd.oflags);
16723+ if (unlikely(wbrfd.oflags & ~valid))
16724+ goto out;
16725+ }
16726+
2000de60 16727+ fd = get_unused_fd_flags(0);
1e00d052
AM
16728+ err = fd;
16729+ if (unlikely(fd < 0))
4a4d8108 16730+ goto out;
4a4d8108 16731+
1e00d052 16732+ h_file = ERR_PTR(-EINVAL);
4a4d8108 16733+ wbi = 0;
1e00d052 16734+ br = NULL;
4a4d8108
AM
16735+ sb = path->dentry->d_sb;
16736+ root = sb->s_root;
16737+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
16738+ bend = au_sbend(sb);
16739+ if (wbrfd.brid >= 0) {
16740+ wbi = au_br_index(sb, wbrfd.brid);
16741+ if (unlikely(wbi < 0 || wbi > bend))
16742+ goto out_unlock;
16743+ }
16744+
16745+ h_file = ERR_PTR(-ENOENT);
16746+ br = au_sbr(sb, wbi);
16747+ if (!au_br_writable(br->br_perm)) {
16748+ if (arg)
16749+ goto out_unlock;
16750+
16751+ bindex = wbi + 1;
16752+ wbi = -1;
16753+ for (; bindex <= bend; bindex++) {
16754+ br = au_sbr(sb, bindex);
16755+ if (au_br_writable(br->br_perm)) {
4a4d8108 16756+ wbi = bindex;
1e00d052 16757+ br = au_sbr(sb, wbi);
4a4d8108
AM
16758+ break;
16759+ }
16760+ }
4a4d8108
AM
16761+ }
16762+ AuDbg("wbi %d\n", wbi);
1e00d052 16763+ if (wbi >= 0)
392086de
AM
16764+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
16765+ /*force_wr*/0);
1e00d052
AM
16766+
16767+out_unlock:
4a4d8108
AM
16768+ aufs_read_unlock(root, AuLock_IR);
16769+ err = PTR_ERR(h_file);
16770+ if (IS_ERR(h_file))
16771+ goto out_fd;
16772+
1e00d052 16773+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
16774+ fd_install(fd, h_file);
16775+ err = fd;
16776+ goto out; /* success */
16777+
4f0767ce 16778+out_fd:
4a4d8108 16779+ put_unused_fd(fd);
4f0767ce 16780+out:
1e00d052 16781+ AuTraceErr(err);
4a4d8108
AM
16782+ return err;
16783+}
16784+
16785+/* ---------------------------------------------------------------------- */
16786+
16787+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
16788+{
16789+ long err;
c1595e42 16790+ struct dentry *dentry;
4a4d8108
AM
16791+
16792+ switch (cmd) {
4a4d8108
AM
16793+ case AUFS_CTL_RDU:
16794+ case AUFS_CTL_RDU_INO:
16795+ err = au_rdu_ioctl(file, cmd, arg);
16796+ break;
16797+
16798+ case AUFS_CTL_WBR_FD:
1e00d052 16799+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
16800+ break;
16801+
027c5e7a
AM
16802+ case AUFS_CTL_IBUSY:
16803+ err = au_ibusy_ioctl(file, arg);
16804+ break;
16805+
076b876e
AM
16806+ case AUFS_CTL_BRINFO:
16807+ err = au_brinfo_ioctl(file, arg);
16808+ break;
16809+
16810+ case AUFS_CTL_FHSM_FD:
2000de60 16811+ dentry = file->f_path.dentry;
c1595e42
JR
16812+ if (IS_ROOT(dentry))
16813+ err = au_fhsm_fd(dentry->d_sb, arg);
16814+ else
16815+ err = -ENOTTY;
076b876e
AM
16816+ break;
16817+
4a4d8108
AM
16818+ default:
16819+ /* do not call the lower */
16820+ AuDbg("0x%x\n", cmd);
16821+ err = -ENOTTY;
16822+ }
16823+
16824+ AuTraceErr(err);
16825+ return err;
16826+}
16827+
16828+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
16829+{
16830+ long err;
16831+
16832+ switch (cmd) {
c2b27bf2 16833+ case AUFS_CTL_MVDOWN:
2000de60 16834+ err = au_mvdown(file->f_path.dentry, (void __user *)arg);
c2b27bf2
AM
16835+ break;
16836+
4a4d8108 16837+ case AUFS_CTL_WBR_FD:
1e00d052 16838+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
16839+ break;
16840+
16841+ default:
16842+ /* do not call the lower */
16843+ AuDbg("0x%x\n", cmd);
16844+ err = -ENOTTY;
16845+ }
16846+
16847+ AuTraceErr(err);
16848+ return err;
16849+}
b752ccd1
AM
16850+
16851+#ifdef CONFIG_COMPAT
16852+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
16853+ unsigned long arg)
16854+{
16855+ long err;
16856+
16857+ switch (cmd) {
16858+ case AUFS_CTL_RDU:
16859+ case AUFS_CTL_RDU_INO:
16860+ err = au_rdu_compat_ioctl(file, cmd, arg);
16861+ break;
16862+
027c5e7a
AM
16863+ case AUFS_CTL_IBUSY:
16864+ err = au_ibusy_compat_ioctl(file, arg);
16865+ break;
16866+
076b876e
AM
16867+ case AUFS_CTL_BRINFO:
16868+ err = au_brinfo_compat_ioctl(file, arg);
16869+ break;
16870+
b752ccd1
AM
16871+ default:
16872+ err = aufs_ioctl_dir(file, cmd, arg);
16873+ }
16874+
16875+ AuTraceErr(err);
16876+ return err;
16877+}
16878+
b752ccd1
AM
16879+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
16880+ unsigned long arg)
16881+{
16882+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
16883+}
16884+#endif
7f207e10
AM
16885diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
16886--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 16887+++ linux/fs/aufs/i_op_add.c 2015-04-13 15:10:20.786823613 +0200
2000de60 16888@@ -0,0 +1,896 @@
4a4d8108 16889+/*
2000de60 16890+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
16891+ *
16892+ * This program, aufs is free software; you can redistribute it and/or modify
16893+ * it under the terms of the GNU General Public License as published by
16894+ * the Free Software Foundation; either version 2 of the License, or
16895+ * (at your option) any later version.
16896+ *
16897+ * This program is distributed in the hope that it will be useful,
16898+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16899+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16900+ * GNU General Public License for more details.
16901+ *
16902+ * You should have received a copy of the GNU General Public License
523b37e3 16903+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16904+ */
16905+
16906+/*
16907+ * inode operations (add entry)
16908+ */
16909+
16910+#include "aufs.h"
16911+
16912+/*
16913+ * final procedure of adding a new entry, except link(2).
16914+ * remove whiteout, instantiate, copyup the parent dir's times and size
16915+ * and update version.
16916+ * if it failed, re-create the removed whiteout.
16917+ */
16918+static int epilog(struct inode *dir, aufs_bindex_t bindex,
16919+ struct dentry *wh_dentry, struct dentry *dentry)
16920+{
16921+ int err, rerr;
16922+ aufs_bindex_t bwh;
16923+ struct path h_path;
076b876e 16924+ struct super_block *sb;
4a4d8108
AM
16925+ struct inode *inode, *h_dir;
16926+ struct dentry *wh;
16927+
16928+ bwh = -1;
076b876e 16929+ sb = dir->i_sb;
4a4d8108
AM
16930+ if (wh_dentry) {
16931+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
16932+ IMustLock(h_dir);
16933+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
16934+ bwh = au_dbwh(dentry);
16935+ h_path.dentry = wh_dentry;
076b876e 16936+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
16937+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
16938+ dentry);
16939+ if (unlikely(err))
16940+ goto out;
16941+ }
16942+
16943+ inode = au_new_inode(dentry, /*must_new*/1);
16944+ if (!IS_ERR(inode)) {
16945+ d_instantiate(dentry, inode);
16946+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
16947+ IMustLock(dir);
16948+ if (au_ibstart(dir) == au_dbstart(dentry))
16949+ au_cpup_attr_timesizes(dir);
16950+ dir->i_version++;
076b876e 16951+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
16952+ return 0; /* success */
16953+ }
16954+
16955+ err = PTR_ERR(inode);
16956+ if (!wh_dentry)
16957+ goto out;
16958+
16959+ /* revert */
16960+ /* dir inode is locked */
16961+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
16962+ rerr = PTR_ERR(wh);
16963+ if (IS_ERR(wh)) {
523b37e3
AM
16964+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
16965+ dentry, err, rerr);
4a4d8108
AM
16966+ err = -EIO;
16967+ } else
16968+ dput(wh);
16969+
4f0767ce 16970+out:
4a4d8108
AM
16971+ return err;
16972+}
16973+
027c5e7a
AM
16974+static int au_d_may_add(struct dentry *dentry)
16975+{
16976+ int err;
16977+
16978+ err = 0;
16979+ if (unlikely(d_unhashed(dentry)))
16980+ err = -ENOENT;
16981+ if (unlikely(dentry->d_inode))
16982+ err = -EEXIST;
16983+ return err;
16984+}
16985+
4a4d8108
AM
16986+/*
16987+ * simple tests for the adding inode operations.
16988+ * following the checks in vfs, plus the parent-child relationship.
16989+ */
16990+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
16991+ struct dentry *h_parent, int isdir)
16992+{
16993+ int err;
16994+ umode_t h_mode;
16995+ struct dentry *h_dentry;
16996+ struct inode *h_inode;
16997+
16998+ err = -ENAMETOOLONG;
16999+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17000+ goto out;
17001+
17002+ h_dentry = au_h_dptr(dentry, bindex);
17003+ h_inode = h_dentry->d_inode;
17004+ if (!dentry->d_inode) {
17005+ err = -EEXIST;
17006+ if (unlikely(h_inode))
17007+ goto out;
17008+ } else {
17009+ /* rename(2) case */
17010+ err = -EIO;
17011+ if (unlikely(!h_inode || !h_inode->i_nlink))
17012+ goto out;
17013+
17014+ h_mode = h_inode->i_mode;
17015+ if (!isdir) {
17016+ err = -EISDIR;
17017+ if (unlikely(S_ISDIR(h_mode)))
17018+ goto out;
17019+ } else if (unlikely(!S_ISDIR(h_mode))) {
17020+ err = -ENOTDIR;
17021+ goto out;
17022+ }
17023+ }
17024+
17025+ err = 0;
17026+ /* expected parent dir is locked */
17027+ if (unlikely(h_parent != h_dentry->d_parent))
17028+ err = -EIO;
17029+
4f0767ce 17030+out:
4a4d8108
AM
17031+ AuTraceErr(err);
17032+ return err;
17033+}
17034+
17035+/*
17036+ * initial procedure of adding a new entry.
17037+ * prepare writable branch and the parent dir, lock it,
17038+ * and lookup whiteout for the new entry.
17039+ */
17040+static struct dentry*
17041+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
17042+ struct dentry *src_dentry, struct au_pin *pin,
17043+ struct au_wr_dir_args *wr_dir_args)
17044+{
17045+ struct dentry *wh_dentry, *h_parent;
17046+ struct super_block *sb;
17047+ struct au_branch *br;
17048+ int err;
17049+ unsigned int udba;
17050+ aufs_bindex_t bcpup;
17051+
523b37e3 17052+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17053+
17054+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
17055+ bcpup = err;
17056+ wh_dentry = ERR_PTR(err);
17057+ if (unlikely(err < 0))
17058+ goto out;
17059+
17060+ sb = dentry->d_sb;
17061+ udba = au_opt_udba(sb);
17062+ err = au_pin(pin, dentry, bcpup, udba,
17063+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17064+ wh_dentry = ERR_PTR(err);
17065+ if (unlikely(err))
17066+ goto out;
17067+
17068+ h_parent = au_pinned_h_parent(pin);
17069+ if (udba != AuOpt_UDBA_NONE
17070+ && au_dbstart(dentry) == bcpup)
17071+ err = au_may_add(dentry, bcpup, h_parent,
17072+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
17073+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17074+ err = -ENAMETOOLONG;
17075+ wh_dentry = ERR_PTR(err);
17076+ if (unlikely(err))
17077+ goto out_unpin;
17078+
17079+ br = au_sbr(sb, bcpup);
17080+ if (dt) {
17081+ struct path tmp = {
17082+ .dentry = h_parent,
86dc4139 17083+ .mnt = au_br_mnt(br)
4a4d8108
AM
17084+ };
17085+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
17086+ }
17087+
17088+ wh_dentry = NULL;
17089+ if (bcpup != au_dbwh(dentry))
17090+ goto out; /* success */
17091+
2000de60
JR
17092+ /*
17093+ * ENAMETOOLONG here means that if we allowed create such name, then it
17094+ * would not be able to removed in the future. So we don't allow such
17095+ * name here and we don't handle ENAMETOOLONG differently here.
17096+ */
4a4d8108
AM
17097+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
17098+
4f0767ce 17099+out_unpin:
4a4d8108
AM
17100+ if (IS_ERR(wh_dentry))
17101+ au_unpin(pin);
4f0767ce 17102+out:
4a4d8108
AM
17103+ return wh_dentry;
17104+}
17105+
17106+/* ---------------------------------------------------------------------- */
17107+
17108+enum { Mknod, Symlink, Creat };
17109+struct simple_arg {
17110+ int type;
17111+ union {
17112+ struct {
7eafdf33 17113+ umode_t mode;
b4510431 17114+ bool want_excl;
4a4d8108
AM
17115+ } c;
17116+ struct {
17117+ const char *symname;
17118+ } s;
17119+ struct {
7eafdf33 17120+ umode_t mode;
4a4d8108
AM
17121+ dev_t dev;
17122+ } m;
17123+ } u;
17124+};
17125+
17126+static int add_simple(struct inode *dir, struct dentry *dentry,
17127+ struct simple_arg *arg)
17128+{
076b876e 17129+ int err, rerr;
4a4d8108
AM
17130+ aufs_bindex_t bstart;
17131+ unsigned char created;
4a4d8108
AM
17132+ struct dentry *wh_dentry, *parent;
17133+ struct inode *h_dir;
c2b27bf2
AM
17134+ /* to reuduce stack size */
17135+ struct {
17136+ struct au_dtime dt;
17137+ struct au_pin pin;
17138+ struct path h_path;
17139+ struct au_wr_dir_args wr_dir_args;
17140+ } *a;
4a4d8108 17141+
523b37e3 17142+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17143+ IMustLock(dir);
17144+
c2b27bf2
AM
17145+ err = -ENOMEM;
17146+ a = kmalloc(sizeof(*a), GFP_NOFS);
17147+ if (unlikely(!a))
17148+ goto out;
17149+ a->wr_dir_args.force_btgt = -1;
17150+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
17151+
4a4d8108 17152+ parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17153+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17154+ if (unlikely(err))
c2b27bf2 17155+ goto out_free;
027c5e7a
AM
17156+ err = au_d_may_add(dentry);
17157+ if (unlikely(err))
17158+ goto out_unlock;
4a4d8108 17159+ di_write_lock_parent(parent);
c2b27bf2
AM
17160+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17161+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
17162+ err = PTR_ERR(wh_dentry);
17163+ if (IS_ERR(wh_dentry))
027c5e7a 17164+ goto out_parent;
4a4d8108
AM
17165+
17166+ bstart = au_dbstart(dentry);
c2b27bf2
AM
17167+ a->h_path.dentry = au_h_dptr(dentry, bstart);
17168+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
17169+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
17170+ switch (arg->type) {
17171+ case Creat:
c2b27bf2 17172+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
537831f9 17173+ arg->u.c.want_excl);
4a4d8108
AM
17174+ break;
17175+ case Symlink:
c2b27bf2 17176+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
17177+ break;
17178+ case Mknod:
c2b27bf2
AM
17179+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
17180+ arg->u.m.dev);
4a4d8108
AM
17181+ break;
17182+ default:
17183+ BUG();
17184+ }
17185+ created = !err;
17186+ if (!err)
17187+ err = epilog(dir, bstart, wh_dentry, dentry);
17188+
17189+ /* revert */
c2b27bf2 17190+ if (unlikely(created && err && a->h_path.dentry->d_inode)) {
523b37e3
AM
17191+ /* no delegation since it is just created */
17192+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
17193+ /*force*/0);
4a4d8108 17194+ if (rerr) {
523b37e3
AM
17195+ AuIOErr("%pd revert failure(%d, %d)\n",
17196+ dentry, err, rerr);
4a4d8108
AM
17197+ err = -EIO;
17198+ }
c2b27bf2 17199+ au_dtime_revert(&a->dt);
4a4d8108
AM
17200+ }
17201+
c2b27bf2 17202+ au_unpin(&a->pin);
4a4d8108
AM
17203+ dput(wh_dentry);
17204+
027c5e7a
AM
17205+out_parent:
17206+ di_write_unlock(parent);
17207+out_unlock:
4a4d8108
AM
17208+ if (unlikely(err)) {
17209+ au_update_dbstart(dentry);
17210+ d_drop(dentry);
17211+ }
4a4d8108 17212+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
17213+out_free:
17214+ kfree(a);
027c5e7a 17215+out:
4a4d8108
AM
17216+ return err;
17217+}
17218+
7eafdf33
AM
17219+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
17220+ dev_t dev)
4a4d8108
AM
17221+{
17222+ struct simple_arg arg = {
17223+ .type = Mknod,
17224+ .u.m = {
17225+ .mode = mode,
17226+ .dev = dev
17227+ }
17228+ };
17229+ return add_simple(dir, dentry, &arg);
17230+}
17231+
17232+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
17233+{
17234+ struct simple_arg arg = {
17235+ .type = Symlink,
17236+ .u.s.symname = symname
17237+ };
17238+ return add_simple(dir, dentry, &arg);
17239+}
17240+
7eafdf33 17241+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 17242+ bool want_excl)
4a4d8108
AM
17243+{
17244+ struct simple_arg arg = {
17245+ .type = Creat,
17246+ .u.c = {
b4510431
AM
17247+ .mode = mode,
17248+ .want_excl = want_excl
4a4d8108
AM
17249+ }
17250+ };
17251+ return add_simple(dir, dentry, &arg);
17252+}
17253+
38d290e6
JR
17254+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
17255+{
17256+ int err;
17257+ aufs_bindex_t bindex;
17258+ struct super_block *sb;
17259+ struct dentry *parent, *h_parent, *h_dentry;
17260+ struct inode *h_dir, *inode;
17261+ struct vfsmount *h_mnt;
17262+ struct au_wr_dir_args wr_dir_args = {
17263+ .force_btgt = -1,
17264+ .flags = AuWrDir_TMPFILE
17265+ };
17266+
17267+ /* copy-up may happen */
17268+ mutex_lock(&dir->i_mutex);
17269+
17270+ sb = dir->i_sb;
17271+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17272+ if (unlikely(err))
17273+ goto out;
17274+
17275+ err = au_di_init(dentry);
17276+ if (unlikely(err))
17277+ goto out_si;
17278+
17279+ err = -EBUSY;
17280+ parent = d_find_any_alias(dir);
17281+ AuDebugOn(!parent);
17282+ di_write_lock_parent(parent);
17283+ if (unlikely(parent->d_inode != dir))
17284+ goto out_parent;
17285+
17286+ err = au_digen_test(parent, au_sigen(sb));
17287+ if (unlikely(err))
17288+ goto out_parent;
17289+
17290+ bindex = au_dbstart(parent);
17291+ au_set_dbstart(dentry, bindex);
17292+ au_set_dbend(dentry, bindex);
17293+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17294+ bindex = err;
17295+ if (unlikely(err < 0))
17296+ goto out_parent;
17297+
17298+ err = -EOPNOTSUPP;
17299+ h_dir = au_h_iptr(dir, bindex);
17300+ if (unlikely(!h_dir->i_op->tmpfile))
17301+ goto out_parent;
17302+
17303+ h_mnt = au_sbr_mnt(sb, bindex);
17304+ err = vfsub_mnt_want_write(h_mnt);
17305+ if (unlikely(err))
17306+ goto out_parent;
17307+
17308+ h_parent = au_h_dptr(parent, bindex);
17309+ err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC);
17310+ if (unlikely(err))
17311+ goto out_mnt;
17312+
17313+ err = -ENOMEM;
17314+ h_dentry = d_alloc(h_parent, &dentry->d_name);
17315+ if (unlikely(!h_dentry))
17316+ goto out_mnt;
17317+
17318+ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode);
17319+ if (unlikely(err))
17320+ goto out_dentry;
17321+
17322+ au_set_dbstart(dentry, bindex);
17323+ au_set_dbend(dentry, bindex);
17324+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
17325+ inode = au_new_inode(dentry, /*must_new*/1);
17326+ if (IS_ERR(inode)) {
17327+ err = PTR_ERR(inode);
17328+ au_set_h_dptr(dentry, bindex, NULL);
17329+ au_set_dbstart(dentry, -1);
17330+ au_set_dbend(dentry, -1);
17331+ } else {
17332+ if (!inode->i_nlink)
17333+ set_nlink(inode, 1);
17334+ d_tmpfile(dentry, inode);
17335+ au_di(dentry)->di_tmpfile = 1;
17336+
17337+ /* update without i_mutex */
17338+ if (au_ibstart(dir) == au_dbstart(dentry))
17339+ au_cpup_attr_timesizes(dir);
17340+ }
17341+
17342+out_dentry:
17343+ dput(h_dentry);
17344+out_mnt:
17345+ vfsub_mnt_drop_write(h_mnt);
17346+out_parent:
17347+ di_write_unlock(parent);
17348+ dput(parent);
17349+ di_write_unlock(dentry);
17350+ if (!err)
17351+#if 0
17352+ /* verbose coding for lock class name */
17353+ au_rw_class(&au_di(dentry)->di_rwsem,
17354+ au_lc_key + AuLcNonDir_DIINFO);
17355+#else
17356+ ;
17357+#endif
17358+ else {
17359+ au_di_fin(dentry);
17360+ dentry->d_fsdata = NULL;
17361+ }
17362+out_si:
17363+ si_read_unlock(sb);
17364+out:
17365+ mutex_unlock(&dir->i_mutex);
17366+ return err;
17367+}
17368+
4a4d8108
AM
17369+/* ---------------------------------------------------------------------- */
17370+
17371+struct au_link_args {
17372+ aufs_bindex_t bdst, bsrc;
17373+ struct au_pin pin;
17374+ struct path h_path;
17375+ struct dentry *src_parent, *parent;
17376+};
17377+
17378+static int au_cpup_before_link(struct dentry *src_dentry,
17379+ struct au_link_args *a)
17380+{
17381+ int err;
17382+ struct dentry *h_src_dentry;
c2b27bf2
AM
17383+ struct au_cp_generic cpg = {
17384+ .dentry = src_dentry,
17385+ .bdst = a->bdst,
17386+ .bsrc = a->bsrc,
17387+ .len = -1,
17388+ .pin = &a->pin,
17389+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
17390+ };
4a4d8108
AM
17391+
17392+ di_read_lock_parent(a->src_parent, AuLock_IR);
17393+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
17394+ if (unlikely(err))
17395+ goto out;
17396+
17397+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
17398+ err = au_pin(&a->pin, src_dentry, a->bdst,
17399+ au_opt_udba(src_dentry->d_sb),
17400+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17401+ if (unlikely(err))
17402+ goto out;
367653fa 17403+
c2b27bf2 17404+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
17405+ au_unpin(&a->pin);
17406+
4f0767ce 17407+out:
4a4d8108
AM
17408+ di_read_unlock(a->src_parent, AuLock_IR);
17409+ return err;
17410+}
17411+
86dc4139
AM
17412+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
17413+ struct au_link_args *a)
4a4d8108
AM
17414+{
17415+ int err;
17416+ unsigned char plink;
86dc4139 17417+ aufs_bindex_t bend;
4a4d8108 17418+ struct dentry *h_src_dentry;
523b37e3 17419+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
17420+ struct super_block *sb;
17421+ struct file *h_file;
17422+
17423+ plink = 0;
17424+ h_inode = NULL;
17425+ sb = src_dentry->d_sb;
17426+ inode = src_dentry->d_inode;
17427+ if (au_ibstart(inode) <= a->bdst)
17428+ h_inode = au_h_iptr(inode, a->bdst);
17429+ if (!h_inode || !h_inode->i_nlink) {
17430+ /* copyup src_dentry as the name of dentry. */
86dc4139
AM
17431+ bend = au_dbend(dentry);
17432+ if (bend < a->bsrc)
17433+ au_set_dbend(dentry, a->bsrc);
17434+ au_set_h_dptr(dentry, a->bsrc,
17435+ dget(au_h_dptr(src_dentry, a->bsrc)));
17436+ dget(a->h_path.dentry);
17437+ au_set_h_dptr(dentry, a->bdst, NULL);
c1595e42
JR
17438+ AuDbg("temporary d_inode...\n");
17439+ spin_lock(&dentry->d_lock);
86dc4139 17440+ dentry->d_inode = src_dentry->d_inode; /* tmp */
c1595e42 17441+ spin_unlock(&dentry->d_lock);
392086de 17442+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 17443+ if (IS_ERR(h_file))
4a4d8108 17444+ err = PTR_ERR(h_file);
86dc4139 17445+ else {
c2b27bf2
AM
17446+ struct au_cp_generic cpg = {
17447+ .dentry = dentry,
17448+ .bdst = a->bdst,
17449+ .bsrc = -1,
17450+ .len = -1,
17451+ .pin = &a->pin,
17452+ .flags = AuCpup_KEEPLINO
17453+ };
17454+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
17455+ au_h_open_post(dentry, a->bsrc, h_file);
17456+ if (!err) {
17457+ dput(a->h_path.dentry);
17458+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17459+ } else
17460+ au_set_h_dptr(dentry, a->bdst,
17461+ a->h_path.dentry);
17462+ }
c1595e42 17463+ spin_lock(&dentry->d_lock);
86dc4139 17464+ dentry->d_inode = NULL; /* restore */
c1595e42
JR
17465+ spin_unlock(&dentry->d_lock);
17466+ AuDbg("temporary d_inode...done\n");
86dc4139
AM
17467+ au_set_h_dptr(dentry, a->bsrc, NULL);
17468+ au_set_dbend(dentry, bend);
4a4d8108
AM
17469+ } else {
17470+ /* the inode of src_dentry already exists on a.bdst branch */
17471+ h_src_dentry = d_find_alias(h_inode);
17472+ if (!h_src_dentry && au_plink_test(inode)) {
17473+ plink = 1;
17474+ h_src_dentry = au_plink_lkup(inode, a->bdst);
17475+ err = PTR_ERR(h_src_dentry);
17476+ if (IS_ERR(h_src_dentry))
17477+ goto out;
17478+
17479+ if (unlikely(!h_src_dentry->d_inode)) {
17480+ dput(h_src_dentry);
17481+ h_src_dentry = NULL;
17482+ }
17483+
17484+ }
17485+ if (h_src_dentry) {
523b37e3 17486+ delegated = NULL;
4a4d8108 17487+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17488+ &a->h_path, &delegated);
17489+ if (unlikely(err == -EWOULDBLOCK)) {
17490+ pr_warn("cannot retry for NFSv4 delegation"
17491+ " for an internal link\n");
17492+ iput(delegated);
17493+ }
4a4d8108
AM
17494+ dput(h_src_dentry);
17495+ } else {
17496+ AuIOErr("no dentry found for hi%lu on b%d\n",
17497+ h_inode->i_ino, a->bdst);
17498+ err = -EIO;
17499+ }
17500+ }
17501+
17502+ if (!err && !plink)
17503+ au_plink_append(inode, a->bdst, a->h_path.dentry);
17504+
17505+out:
2cbb1c4b 17506+ AuTraceErr(err);
4a4d8108
AM
17507+ return err;
17508+}
17509+
17510+int aufs_link(struct dentry *src_dentry, struct inode *dir,
17511+ struct dentry *dentry)
17512+{
17513+ int err, rerr;
17514+ struct au_dtime dt;
17515+ struct au_link_args *a;
17516+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 17517+ struct inode *inode, *delegated;
4a4d8108
AM
17518+ struct super_block *sb;
17519+ struct au_wr_dir_args wr_dir_args = {
17520+ /* .force_btgt = -1, */
17521+ .flags = AuWrDir_ADD_ENTRY
17522+ };
17523+
17524+ IMustLock(dir);
17525+ inode = src_dentry->d_inode;
17526+ IMustLock(inode);
17527+
4a4d8108
AM
17528+ err = -ENOMEM;
17529+ a = kzalloc(sizeof(*a), GFP_NOFS);
17530+ if (unlikely(!a))
17531+ goto out;
17532+
17533+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17534+ err = aufs_read_and_write_lock2(dentry, src_dentry,
17535+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
17536+ if (unlikely(err))
17537+ goto out_kfree;
38d290e6 17538+ err = au_d_linkable(src_dentry);
027c5e7a
AM
17539+ if (unlikely(err))
17540+ goto out_unlock;
17541+ err = au_d_may_add(dentry);
17542+ if (unlikely(err))
17543+ goto out_unlock;
e49829fe 17544+
4a4d8108 17545+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 17546+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
17547+
17548+ di_write_lock_parent(a->parent);
17549+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
17550+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
17551+ &wr_dir_args);
17552+ err = PTR_ERR(wh_dentry);
17553+ if (IS_ERR(wh_dentry))
027c5e7a 17554+ goto out_parent;
4a4d8108
AM
17555+
17556+ err = 0;
17557+ sb = dentry->d_sb;
17558+ a->bdst = au_dbstart(dentry);
17559+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17560+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
17561+ a->bsrc = au_ibstart(inode);
17562+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
17563+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
17564+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b
JR
17565+ if (!h_src_dentry) {
17566+ a->bsrc = au_dbstart(src_dentry);
17567+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
17568+ AuDebugOn(!h_src_dentry);
38d290e6
JR
17569+ } else if (IS_ERR(h_src_dentry)) {
17570+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 17571+ goto out_parent;
38d290e6 17572+ }
2cbb1c4b 17573+
4a4d8108
AM
17574+ if (au_opt_test(au_mntflags(sb), PLINK)) {
17575+ if (a->bdst < a->bsrc
17576+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 17577+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
17578+ else {
17579+ delegated = NULL;
4a4d8108 17580+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17581+ &a->h_path, &delegated);
17582+ if (unlikely(err == -EWOULDBLOCK)) {
17583+ pr_warn("cannot retry for NFSv4 delegation"
17584+ " for an internal link\n");
17585+ iput(delegated);
17586+ }
17587+ }
2cbb1c4b 17588+ dput(h_src_dentry);
4a4d8108
AM
17589+ } else {
17590+ /*
17591+ * copyup src_dentry to the branch we process,
17592+ * and then link(2) to it.
17593+ */
2cbb1c4b 17594+ dput(h_src_dentry);
4a4d8108
AM
17595+ if (a->bdst < a->bsrc
17596+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
17597+ au_unpin(&a->pin);
17598+ di_write_unlock(a->parent);
17599+ err = au_cpup_before_link(src_dentry, a);
17600+ di_write_lock_parent(a->parent);
17601+ if (!err)
17602+ err = au_pin(&a->pin, dentry, a->bdst,
17603+ au_opt_udba(sb),
17604+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17605+ if (unlikely(err))
17606+ goto out_wh;
17607+ }
17608+ if (!err) {
17609+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
17610+ err = -ENOENT;
523b37e3
AM
17611+ if (h_src_dentry && h_src_dentry->d_inode) {
17612+ delegated = NULL;
4a4d8108
AM
17613+ err = vfsub_link(h_src_dentry,
17614+ au_pinned_h_dir(&a->pin),
523b37e3
AM
17615+ &a->h_path, &delegated);
17616+ if (unlikely(err == -EWOULDBLOCK)) {
17617+ pr_warn("cannot retry"
17618+ " for NFSv4 delegation"
17619+ " for an internal link\n");
17620+ iput(delegated);
17621+ }
17622+ }
4a4d8108
AM
17623+ }
17624+ }
17625+ if (unlikely(err))
17626+ goto out_unpin;
17627+
17628+ if (wh_dentry) {
17629+ a->h_path.dentry = wh_dentry;
17630+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
17631+ dentry);
17632+ if (unlikely(err))
17633+ goto out_revert;
17634+ }
17635+
17636+ dir->i_version++;
17637+ if (au_ibstart(dir) == au_dbstart(dentry))
17638+ au_cpup_attr_timesizes(dir);
17639+ inc_nlink(inode);
17640+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
17641+ d_instantiate(dentry, au_igrab(inode));
17642+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
17643+ /* some filesystem calls d_drop() */
17644+ d_drop(dentry);
076b876e
AM
17645+ /* some filesystems consume an inode even hardlink */
17646+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
17647+ goto out_unpin; /* success */
17648+
4f0767ce 17649+out_revert:
523b37e3
AM
17650+ /* no delegation since it is just created */
17651+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
17652+ /*delegated*/NULL, /*force*/0);
027c5e7a 17653+ if (unlikely(rerr)) {
523b37e3 17654+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
17655+ err = -EIO;
17656+ }
4a4d8108 17657+ au_dtime_revert(&dt);
4f0767ce 17658+out_unpin:
4a4d8108 17659+ au_unpin(&a->pin);
4f0767ce 17660+out_wh:
4a4d8108 17661+ dput(wh_dentry);
027c5e7a
AM
17662+out_parent:
17663+ di_write_unlock(a->parent);
17664+ dput(a->src_parent);
4f0767ce 17665+out_unlock:
4a4d8108
AM
17666+ if (unlikely(err)) {
17667+ au_update_dbstart(dentry);
17668+ d_drop(dentry);
17669+ }
4a4d8108 17670+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 17671+out_kfree:
4a4d8108 17672+ kfree(a);
4f0767ce 17673+out:
86dc4139 17674+ AuTraceErr(err);
4a4d8108
AM
17675+ return err;
17676+}
17677+
7eafdf33 17678+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
17679+{
17680+ int err, rerr;
17681+ aufs_bindex_t bindex;
17682+ unsigned char diropq;
17683+ struct path h_path;
17684+ struct dentry *wh_dentry, *parent, *opq_dentry;
17685+ struct mutex *h_mtx;
17686+ struct super_block *sb;
17687+ struct {
17688+ struct au_pin pin;
17689+ struct au_dtime dt;
17690+ } *a; /* reduce the stack usage */
17691+ struct au_wr_dir_args wr_dir_args = {
17692+ .force_btgt = -1,
17693+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
17694+ };
17695+
17696+ IMustLock(dir);
17697+
17698+ err = -ENOMEM;
17699+ a = kmalloc(sizeof(*a), GFP_NOFS);
17700+ if (unlikely(!a))
17701+ goto out;
17702+
027c5e7a
AM
17703+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17704+ if (unlikely(err))
17705+ goto out_free;
17706+ err = au_d_may_add(dentry);
17707+ if (unlikely(err))
17708+ goto out_unlock;
17709+
4a4d8108
AM
17710+ parent = dentry->d_parent; /* dir inode is locked */
17711+ di_write_lock_parent(parent);
17712+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17713+ &a->pin, &wr_dir_args);
17714+ err = PTR_ERR(wh_dentry);
17715+ if (IS_ERR(wh_dentry))
027c5e7a 17716+ goto out_parent;
4a4d8108
AM
17717+
17718+ sb = dentry->d_sb;
17719+ bindex = au_dbstart(dentry);
17720+ h_path.dentry = au_h_dptr(dentry, bindex);
17721+ h_path.mnt = au_sbr_mnt(sb, bindex);
17722+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
17723+ if (unlikely(err))
027c5e7a 17724+ goto out_unpin;
4a4d8108
AM
17725+
17726+ /* make the dir opaque */
17727+ diropq = 0;
17728+ h_mtx = &h_path.dentry->d_inode->i_mutex;
17729+ if (wh_dentry
17730+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
17731+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17732+ opq_dentry = au_diropq_create(dentry, bindex);
17733+ mutex_unlock(h_mtx);
17734+ err = PTR_ERR(opq_dentry);
17735+ if (IS_ERR(opq_dentry))
17736+ goto out_dir;
17737+ dput(opq_dentry);
17738+ diropq = 1;
17739+ }
17740+
17741+ err = epilog(dir, bindex, wh_dentry, dentry);
17742+ if (!err) {
17743+ inc_nlink(dir);
027c5e7a 17744+ goto out_unpin; /* success */
4a4d8108
AM
17745+ }
17746+
17747+ /* revert */
17748+ if (diropq) {
17749+ AuLabel(revert opq);
17750+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17751+ rerr = au_diropq_remove(dentry, bindex);
17752+ mutex_unlock(h_mtx);
17753+ if (rerr) {
523b37e3
AM
17754+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
17755+ dentry, err, rerr);
4a4d8108
AM
17756+ err = -EIO;
17757+ }
17758+ }
17759+
4f0767ce 17760+out_dir:
4a4d8108
AM
17761+ AuLabel(revert dir);
17762+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
17763+ if (rerr) {
523b37e3
AM
17764+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
17765+ dentry, err, rerr);
4a4d8108
AM
17766+ err = -EIO;
17767+ }
4a4d8108 17768+ au_dtime_revert(&a->dt);
027c5e7a 17769+out_unpin:
4a4d8108
AM
17770+ au_unpin(&a->pin);
17771+ dput(wh_dentry);
027c5e7a
AM
17772+out_parent:
17773+ di_write_unlock(parent);
17774+out_unlock:
4a4d8108
AM
17775+ if (unlikely(err)) {
17776+ au_update_dbstart(dentry);
17777+ d_drop(dentry);
17778+ }
4a4d8108 17779+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 17780+out_free:
4a4d8108 17781+ kfree(a);
4f0767ce 17782+out:
4a4d8108
AM
17783+ return err;
17784+}
7f207e10
AM
17785diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
17786--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
17787+++ linux/fs/aufs/i_op.c 2015-04-13 15:10:20.786823613 +0200
17788@@ -0,0 +1,1297 @@
4a4d8108 17789+/*
2000de60 17790+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
17791+ *
17792+ * This program, aufs is free software; you can redistribute it and/or modify
17793+ * it under the terms of the GNU General Public License as published by
17794+ * the Free Software Foundation; either version 2 of the License, or
17795+ * (at your option) any later version.
17796+ *
17797+ * This program is distributed in the hope that it will be useful,
17798+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17799+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17800+ * GNU General Public License for more details.
17801+ *
17802+ * You should have received a copy of the GNU General Public License
523b37e3 17803+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 17804+ */
1facf9fc 17805+
1308ab2a 17806+/*
4a4d8108 17807+ * inode operations (except add/del/rename)
1308ab2a 17808+ */
4a4d8108
AM
17809+
17810+#include <linux/device_cgroup.h>
17811+#include <linux/fs_stack.h>
92d182d2 17812+#include <linux/mm.h>
4a4d8108
AM
17813+#include <linux/namei.h>
17814+#include <linux/security.h>
4a4d8108
AM
17815+#include "aufs.h"
17816+
1e00d052 17817+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 17818+ struct vfsmount *h_mnt, int brperm)
1facf9fc 17819+{
1308ab2a 17820+ int err;
4a4d8108 17821+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 17822+
4a4d8108
AM
17823+ err = -EACCES;
17824+ if ((write_mask && IS_IMMUTABLE(h_inode))
17825+ || ((mask & MAY_EXEC)
17826+ && S_ISREG(h_inode->i_mode)
17827+ && ((h_mnt->mnt_flags & MNT_NOEXEC)
17828+ || !(h_inode->i_mode & S_IXUGO))))
17829+ goto out;
17830+
17831+ /*
17832+ * - skip the lower fs test in the case of write to ro branch.
17833+ * - nfs dir permission write check is optimized, but a policy for
17834+ * link/rename requires a real check.
17835+ */
17836+ if ((write_mask && !au_br_writable(brperm))
17837+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
17838+ && write_mask && !(mask & MAY_READ))
17839+ || !h_inode->i_op->permission) {
17840+ /* AuLabel(generic_permission); */
1e00d052 17841+ err = generic_permission(h_inode, mask);
1308ab2a 17842+ } else {
4a4d8108 17843+ /* AuLabel(h_inode->permission); */
1e00d052 17844+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
17845+ AuTraceErr(err);
17846+ }
1facf9fc 17847+
4a4d8108
AM
17848+ if (!err)
17849+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 17850+ if (!err)
4a4d8108 17851+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
17852+
17853+#if 0
17854+ if (!err) {
17855+ /* todo: do we need to call ima_path_check()? */
17856+ struct path h_path = {
17857+ .dentry =
17858+ .mnt = h_mnt
17859+ };
17860+ err = ima_path_check(&h_path,
17861+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
17862+ IMA_COUNT_LEAVE);
1308ab2a 17863+ }
4a4d8108 17864+#endif
dece6358 17865+
4f0767ce 17866+out:
1308ab2a 17867+ return err;
17868+}
dece6358 17869+
1e00d052 17870+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 17871+{
17872+ int err;
4a4d8108
AM
17873+ aufs_bindex_t bindex, bend;
17874+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
17875+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
17876+ struct inode *h_inode;
17877+ struct super_block *sb;
17878+ struct au_branch *br;
1facf9fc 17879+
027c5e7a 17880+ /* todo: support rcu-walk? */
1e00d052 17881+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
17882+ return -ECHILD;
17883+
4a4d8108
AM
17884+ sb = inode->i_sb;
17885+ si_read_lock(sb, AuLock_FLUSH);
17886+ ii_read_lock_child(inode);
027c5e7a
AM
17887+#if 0
17888+ err = au_iigen_test(inode, au_sigen(sb));
17889+ if (unlikely(err))
17890+ goto out;
17891+#endif
dece6358 17892+
076b876e
AM
17893+ if (!isdir
17894+ || write_mask
17895+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108
AM
17896+ err = au_busy_or_stale();
17897+ h_inode = au_h_iptr(inode, au_ibstart(inode));
17898+ if (unlikely(!h_inode
17899+ || (h_inode->i_mode & S_IFMT)
17900+ != (inode->i_mode & S_IFMT)))
17901+ goto out;
1facf9fc 17902+
4a4d8108
AM
17903+ err = 0;
17904+ bindex = au_ibstart(inode);
17905+ br = au_sbr(sb, bindex);
86dc4139 17906+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
4a4d8108
AM
17907+ if (write_mask
17908+ && !err
17909+ && !special_file(h_inode->i_mode)) {
17910+ /* test whether the upper writable branch exists */
17911+ err = -EROFS;
17912+ for (; bindex >= 0; bindex--)
17913+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
17914+ err = 0;
17915+ break;
17916+ }
17917+ }
17918+ goto out;
17919+ }
dece6358 17920+
4a4d8108 17921+ /* non-write to dir */
1308ab2a 17922+ err = 0;
4a4d8108
AM
17923+ bend = au_ibend(inode);
17924+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
17925+ h_inode = au_h_iptr(inode, bindex);
17926+ if (h_inode) {
17927+ err = au_busy_or_stale();
17928+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
17929+ break;
17930+
17931+ br = au_sbr(sb, bindex);
86dc4139 17932+ err = h_permission(h_inode, mask, au_br_mnt(br),
4a4d8108
AM
17933+ br->br_perm);
17934+ }
17935+ }
1308ab2a 17936+
4f0767ce 17937+out:
4a4d8108
AM
17938+ ii_read_unlock(inode);
17939+ si_read_unlock(sb);
1308ab2a 17940+ return err;
17941+}
17942+
4a4d8108 17943+/* ---------------------------------------------------------------------- */
1facf9fc 17944+
4a4d8108 17945+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 17946+ unsigned int flags)
4a4d8108
AM
17947+{
17948+ struct dentry *ret, *parent;
b752ccd1 17949+ struct inode *inode;
4a4d8108 17950+ struct super_block *sb;
1716fcea 17951+ int err, npositive;
dece6358 17952+
4a4d8108 17953+ IMustLock(dir);
1308ab2a 17954+
537831f9
AM
17955+ /* todo: support rcu-walk? */
17956+ ret = ERR_PTR(-ECHILD);
17957+ if (flags & LOOKUP_RCU)
17958+ goto out;
17959+
17960+ ret = ERR_PTR(-ENAMETOOLONG);
17961+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17962+ goto out;
17963+
4a4d8108 17964+ sb = dir->i_sb;
7f207e10
AM
17965+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17966+ ret = ERR_PTR(err);
17967+ if (unlikely(err))
17968+ goto out;
17969+
4a4d8108
AM
17970+ err = au_di_init(dentry);
17971+ ret = ERR_PTR(err);
17972+ if (unlikely(err))
7f207e10 17973+ goto out_si;
1308ab2a 17974+
9dbd164d 17975+ inode = NULL;
027c5e7a 17976+ npositive = 0; /* suppress a warning */
4a4d8108
AM
17977+ parent = dentry->d_parent; /* dir inode is locked */
17978+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
17979+ err = au_alive_dir(parent);
17980+ if (!err)
17981+ err = au_digen_test(parent, au_sigen(sb));
17982+ if (!err) {
17983+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 17984+ /*type*/0);
027c5e7a
AM
17985+ err = npositive;
17986+ }
4a4d8108 17987+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
17988+ ret = ERR_PTR(err);
17989+ if (unlikely(err < 0))
17990+ goto out_unlock;
1308ab2a 17991+
4a4d8108 17992+ if (npositive) {
b752ccd1 17993+ inode = au_new_inode(dentry, /*must_new*/0);
c1595e42
JR
17994+ if (IS_ERR(inode)) {
17995+ ret = (void *)inode;
17996+ inode = NULL;
17997+ goto out_unlock;
17998+ }
9dbd164d 17999+ }
4a4d8108 18000+
c1595e42
JR
18001+ if (inode)
18002+ atomic_inc(&inode->i_count);
4a4d8108 18003+ ret = d_splice_alias(inode, dentry);
537831f9
AM
18004+#if 0
18005+ if (unlikely(d_need_lookup(dentry))) {
18006+ spin_lock(&dentry->d_lock);
18007+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
18008+ spin_unlock(&dentry->d_lock);
18009+ } else
18010+#endif
c1595e42 18011+ if (inode) {
2000de60 18012+ if (!IS_ERR(ret)) {
c1595e42 18013+ iput(inode);
2000de60
JR
18014+ if (ret && ret != dentry)
18015+ ii_write_unlock(inode);
18016+ } else {
c1595e42
JR
18017+ ii_write_unlock(inode);
18018+ iput(inode);
18019+ inode = NULL;
18020+ }
7f207e10 18021+ }
1facf9fc 18022+
4f0767ce 18023+out_unlock:
4a4d8108 18024+ di_write_unlock(dentry);
2dfbb274 18025+ if (inode) {
1716fcea
AM
18026+ /* verbose coding for lock class name */
18027+ if (unlikely(S_ISLNK(inode->i_mode)))
18028+ au_rw_class(&au_di(dentry)->di_rwsem,
18029+ au_lc_key + AuLcSymlink_DIINFO);
18030+ else if (unlikely(S_ISDIR(inode->i_mode)))
18031+ au_rw_class(&au_di(dentry)->di_rwsem,
18032+ au_lc_key + AuLcDir_DIINFO);
18033+ else /* likely */
18034+ au_rw_class(&au_di(dentry)->di_rwsem,
18035+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 18036+ }
7f207e10 18037+out_si:
4a4d8108 18038+ si_read_unlock(sb);
7f207e10 18039+out:
4a4d8108
AM
18040+ return ret;
18041+}
1facf9fc 18042+
4a4d8108 18043+/* ---------------------------------------------------------------------- */
1facf9fc 18044+
4a4d8108
AM
18045+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
18046+ const unsigned char add_entry, aufs_bindex_t bcpup,
18047+ aufs_bindex_t bstart)
18048+{
18049+ int err;
18050+ struct dentry *h_parent;
18051+ struct inode *h_dir;
1facf9fc 18052+
027c5e7a 18053+ if (add_entry)
4a4d8108 18054+ IMustLock(parent->d_inode);
027c5e7a 18055+ else
4a4d8108
AM
18056+ di_write_lock_parent(parent);
18057+
18058+ err = 0;
18059+ if (!au_h_dptr(parent, bcpup)) {
c2b27bf2
AM
18060+ if (bstart > bcpup)
18061+ err = au_cpup_dirs(dentry, bcpup);
18062+ else if (bstart < bcpup)
4a4d8108
AM
18063+ err = au_cpdown_dirs(dentry, bcpup);
18064+ else
c2b27bf2 18065+ BUG();
4a4d8108 18066+ }
38d290e6 18067+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108
AM
18068+ h_parent = au_h_dptr(parent, bcpup);
18069+ h_dir = h_parent->d_inode;
18070+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
7e9cd9fe 18071+ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
4a4d8108
AM
18072+ /* todo: no unlock here */
18073+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
18074+
18075+ AuDbg("bcpup %d\n", bcpup);
18076+ if (!err) {
18077+ if (!dentry->d_inode)
18078+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
18079+ au_update_dbrange(dentry, /*do_put_zero*/0);
18080+ }
1308ab2a 18081+ }
1facf9fc 18082+
4a4d8108
AM
18083+ if (!add_entry)
18084+ di_write_unlock(parent);
18085+ if (!err)
18086+ err = bcpup; /* success */
1308ab2a 18087+
027c5e7a 18088+ AuTraceErr(err);
4a4d8108
AM
18089+ return err;
18090+}
1facf9fc 18091+
4a4d8108
AM
18092+/*
18093+ * decide the branch and the parent dir where we will create a new entry.
18094+ * returns new bindex or an error.
18095+ * copyup the parent dir if needed.
18096+ */
18097+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18098+ struct au_wr_dir_args *args)
18099+{
18100+ int err;
392086de 18101+ unsigned int flags;
4a4d8108 18102+ aufs_bindex_t bcpup, bstart, src_bstart;
86dc4139
AM
18103+ const unsigned char add_entry
18104+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6 18105+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
18106+ struct super_block *sb;
18107+ struct dentry *parent;
18108+ struct au_sbinfo *sbinfo;
1facf9fc 18109+
4a4d8108
AM
18110+ sb = dentry->d_sb;
18111+ sbinfo = au_sbi(sb);
18112+ parent = dget_parent(dentry);
18113+ bstart = au_dbstart(dentry);
18114+ bcpup = bstart;
18115+ if (args->force_btgt < 0) {
18116+ if (src_dentry) {
18117+ src_bstart = au_dbstart(src_dentry);
18118+ if (src_bstart < bstart)
18119+ bcpup = src_bstart;
18120+ } else if (add_entry) {
392086de
AM
18121+ flags = 0;
18122+ if (au_ftest_wrdir(args->flags, ISDIR))
18123+ au_fset_wbr(flags, DIR);
18124+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
18125+ bcpup = err;
18126+ }
1facf9fc 18127+
4a4d8108
AM
18128+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
18129+ if (add_entry)
18130+ err = AuWbrCopyup(sbinfo, dentry);
18131+ else {
18132+ if (!IS_ROOT(dentry)) {
18133+ di_read_lock_parent(parent, !AuLock_IR);
18134+ err = AuWbrCopyup(sbinfo, dentry);
18135+ di_read_unlock(parent, !AuLock_IR);
18136+ } else
18137+ err = AuWbrCopyup(sbinfo, dentry);
18138+ }
18139+ bcpup = err;
18140+ if (unlikely(err < 0))
18141+ goto out;
18142+ }
18143+ } else {
18144+ bcpup = args->force_btgt;
18145+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
1308ab2a 18146+ }
027c5e7a 18147+
4a4d8108
AM
18148+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
18149+ err = bcpup;
18150+ if (bcpup == bstart)
18151+ goto out; /* success */
4a4d8108
AM
18152+
18153+ /* copyup the new parent into the branch we process */
18154+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
18155+ if (err >= 0) {
18156+ if (!dentry->d_inode) {
18157+ au_set_h_dptr(dentry, bstart, NULL);
18158+ au_set_dbstart(dentry, bcpup);
18159+ au_set_dbend(dentry, bcpup);
18160+ }
38d290e6
JR
18161+ AuDebugOn(add_entry
18162+ && !au_ftest_wrdir(args->flags, TMPFILE)
18163+ && !au_h_dptr(dentry, bcpup));
027c5e7a 18164+ }
86dc4139
AM
18165+
18166+out:
18167+ dput(parent);
18168+ return err;
18169+}
18170+
18171+/* ---------------------------------------------------------------------- */
18172+
18173+void au_pin_hdir_unlock(struct au_pin *p)
18174+{
18175+ if (p->hdir)
18176+ au_hn_imtx_unlock(p->hdir);
18177+}
18178+
c1595e42 18179+int au_pin_hdir_lock(struct au_pin *p)
86dc4139
AM
18180+{
18181+ int err;
18182+
18183+ err = 0;
18184+ if (!p->hdir)
18185+ goto out;
18186+
18187+ /* even if an error happens later, keep this lock */
18188+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
18189+
18190+ err = -EBUSY;
18191+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
18192+ goto out;
18193+
18194+ err = 0;
18195+ if (p->h_dentry)
18196+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
18197+ p->h_parent, p->br);
18198+
18199+out:
18200+ return err;
18201+}
18202+
18203+int au_pin_hdir_relock(struct au_pin *p)
18204+{
18205+ int err, i;
18206+ struct inode *h_i;
18207+ struct dentry *h_d[] = {
18208+ p->h_dentry,
18209+ p->h_parent
18210+ };
18211+
18212+ err = au_pin_hdir_lock(p);
18213+ if (unlikely(err))
18214+ goto out;
18215+
18216+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
18217+ if (!h_d[i])
18218+ continue;
18219+ h_i = h_d[i]->d_inode;
18220+ if (h_i)
18221+ err = !h_i->i_nlink;
18222+ }
18223+
18224+out:
18225+ return err;
18226+}
18227+
18228+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
18229+{
18230+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
18231+ p->hdir->hi_inode->i_mutex.owner = task;
18232+#endif
18233+}
18234+
18235+void au_pin_hdir_acquire_nest(struct au_pin *p)
18236+{
18237+ if (p->hdir) {
18238+ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
18239+ p->lsc_hi, 0, NULL, _RET_IP_);
18240+ au_pin_hdir_set_owner(p, current);
18241+ }
dece6358 18242+}
1facf9fc 18243+
86dc4139
AM
18244+void au_pin_hdir_release(struct au_pin *p)
18245+{
18246+ if (p->hdir) {
18247+ au_pin_hdir_set_owner(p, p->task);
18248+ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
18249+ }
18250+}
1308ab2a 18251+
4a4d8108 18252+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 18253+{
4a4d8108
AM
18254+ if (pin && pin->parent)
18255+ return au_h_dptr(pin->parent, pin->bindex);
18256+ return NULL;
dece6358 18257+}
1facf9fc 18258+
4a4d8108 18259+void au_unpin(struct au_pin *p)
dece6358 18260+{
86dc4139
AM
18261+ if (p->hdir)
18262+ au_pin_hdir_unlock(p);
e49829fe 18263+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 18264+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
18265+ if (!p->hdir)
18266+ return;
1facf9fc 18267+
4a4d8108
AM
18268+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18269+ di_read_unlock(p->parent, AuLock_IR);
18270+ iput(p->hdir->hi_inode);
18271+ dput(p->parent);
18272+ p->parent = NULL;
18273+ p->hdir = NULL;
18274+ p->h_mnt = NULL;
86dc4139 18275+ /* do not clear p->task */
4a4d8108 18276+}
1308ab2a 18277+
4a4d8108
AM
18278+int au_do_pin(struct au_pin *p)
18279+{
18280+ int err;
18281+ struct super_block *sb;
4a4d8108
AM
18282+ struct inode *h_dir;
18283+
18284+ err = 0;
18285+ sb = p->dentry->d_sb;
86dc4139 18286+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
18287+ if (IS_ROOT(p->dentry)) {
18288+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18289+ p->h_mnt = au_br_mnt(p->br);
b4510431 18290+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
18291+ if (unlikely(err)) {
18292+ au_fclr_pin(p->flags, MNT_WRITE);
18293+ goto out_err;
18294+ }
18295+ }
dece6358 18296+ goto out;
1facf9fc 18297+ }
18298+
86dc4139 18299+ p->h_dentry = NULL;
4a4d8108 18300+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 18301+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 18302+
4a4d8108
AM
18303+ p->parent = dget_parent(p->dentry);
18304+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18305+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 18306+
4a4d8108 18307+ h_dir = NULL;
86dc4139 18308+ p->h_parent = au_h_dptr(p->parent, p->bindex);
4a4d8108
AM
18309+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
18310+ if (p->hdir)
18311+ h_dir = p->hdir->hi_inode;
dece6358 18312+
b752ccd1
AM
18313+ /*
18314+ * udba case, or
18315+ * if DI_LOCKED is not set, then p->parent may be different
18316+ * and h_parent can be NULL.
18317+ */
86dc4139 18318+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 18319+ err = -EBUSY;
4a4d8108
AM
18320+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18321+ di_read_unlock(p->parent, AuLock_IR);
18322+ dput(p->parent);
18323+ p->parent = NULL;
18324+ goto out_err;
18325+ }
1308ab2a 18326+
4a4d8108 18327+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18328+ p->h_mnt = au_br_mnt(p->br);
b4510431 18329+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 18330+ if (unlikely(err)) {
4a4d8108 18331+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
18332+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18333+ di_read_unlock(p->parent, AuLock_IR);
18334+ dput(p->parent);
18335+ p->parent = NULL;
18336+ goto out_err;
dece6358
AM
18337+ }
18338+ }
4a4d8108 18339+
86dc4139
AM
18340+ au_igrab(h_dir);
18341+ err = au_pin_hdir_lock(p);
18342+ if (!err)
18343+ goto out; /* success */
18344+
076b876e
AM
18345+ au_unpin(p);
18346+
4f0767ce 18347+out_err:
4a4d8108
AM
18348+ pr_err("err %d\n", err);
18349+ err = au_busy_or_stale();
4f0767ce 18350+out:
1facf9fc 18351+ return err;
18352+}
18353+
4a4d8108
AM
18354+void au_pin_init(struct au_pin *p, struct dentry *dentry,
18355+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18356+ unsigned int udba, unsigned char flags)
18357+{
18358+ p->dentry = dentry;
18359+ p->udba = udba;
18360+ p->lsc_di = lsc_di;
18361+ p->lsc_hi = lsc_hi;
18362+ p->flags = flags;
18363+ p->bindex = bindex;
18364+
18365+ p->parent = NULL;
18366+ p->hdir = NULL;
18367+ p->h_mnt = NULL;
86dc4139
AM
18368+
18369+ p->h_dentry = NULL;
18370+ p->h_parent = NULL;
18371+ p->br = NULL;
18372+ p->task = current;
4a4d8108
AM
18373+}
18374+
18375+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18376+ unsigned int udba, unsigned char flags)
18377+{
18378+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
18379+ udba, flags);
18380+ return au_do_pin(pin);
18381+}
18382+
dece6358
AM
18383+/* ---------------------------------------------------------------------- */
18384+
1308ab2a 18385+/*
4a4d8108
AM
18386+ * ->setattr() and ->getattr() are called in various cases.
18387+ * chmod, stat: dentry is revalidated.
18388+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
18389+ * unhashed.
18390+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 18391+ */
027c5e7a 18392+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
c1595e42 18393+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 18394+{
4a4d8108
AM
18395+ int err;
18396+ struct inode *inode;
18397+ struct dentry *parent;
1facf9fc 18398+
1308ab2a 18399+ err = 0;
4a4d8108 18400+ inode = dentry->d_inode;
027c5e7a 18401+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
18402+ parent = dget_parent(dentry);
18403+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 18404+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
18405+ di_read_unlock(parent, AuLock_IR);
18406+ dput(parent);
dece6358 18407+ }
1facf9fc 18408+
4a4d8108 18409+ AuTraceErr(err);
1308ab2a 18410+ return err;
18411+}
dece6358 18412+
c1595e42
JR
18413+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
18414+ struct au_icpup_args *a)
1308ab2a 18415+{
18416+ int err;
4a4d8108 18417+ loff_t sz;
e49829fe 18418+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
18419+ struct dentry *hi_wh, *parent;
18420+ struct inode *inode;
4a4d8108
AM
18421+ struct au_wr_dir_args wr_dir_args = {
18422+ .force_btgt = -1,
18423+ .flags = 0
18424+ };
18425+
2000de60 18426+ if (d_is_dir(dentry))
4a4d8108
AM
18427+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
18428+ /* plink or hi_wh() case */
2000de60
JR
18429+ bstart = au_dbstart(dentry);
18430+ inode = dentry->d_inode;
e49829fe 18431+ ibstart = au_ibstart(inode);
027c5e7a 18432+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 18433+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
18434+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
18435+ if (unlikely(err < 0))
18436+ goto out;
18437+ a->btgt = err;
18438+ if (err != bstart)
18439+ au_fset_icpup(a->flags, DID_CPUP);
18440+
18441+ err = 0;
18442+ a->pin_flags = AuPin_MNT_WRITE;
18443+ parent = NULL;
18444+ if (!IS_ROOT(dentry)) {
18445+ au_fset_pin(a->pin_flags, DI_LOCKED);
18446+ parent = dget_parent(dentry);
18447+ di_write_lock_parent(parent);
18448+ }
18449+
18450+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
18451+ if (unlikely(err))
18452+ goto out_parent;
18453+
18454+ a->h_path.dentry = au_h_dptr(dentry, bstart);
18455+ a->h_inode = a->h_path.dentry->d_inode;
4a4d8108 18456+ sz = -1;
c1595e42
JR
18457+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
18458+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
18459+ if (ia->ia_size < i_size_read(a->h_inode))
18460+ sz = ia->ia_size;
18461+ mutex_unlock(&a->h_inode->i_mutex);
18462+ }
4a4d8108 18463+
4a4d8108 18464+ hi_wh = NULL;
027c5e7a 18465+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
18466+ hi_wh = au_hi_wh(inode, a->btgt);
18467+ if (!hi_wh) {
c2b27bf2
AM
18468+ struct au_cp_generic cpg = {
18469+ .dentry = dentry,
18470+ .bdst = a->btgt,
18471+ .bsrc = -1,
18472+ .len = sz,
18473+ .pin = &a->pin
18474+ };
18475+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
18476+ if (unlikely(err))
18477+ goto out_unlock;
18478+ hi_wh = au_hi_wh(inode, a->btgt);
18479+ /* todo: revalidate hi_wh? */
18480+ }
18481+ }
18482+
18483+ if (parent) {
18484+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
18485+ di_downgrade_lock(parent, AuLock_IR);
18486+ dput(parent);
18487+ parent = NULL;
18488+ }
18489+ if (!au_ftest_icpup(a->flags, DID_CPUP))
18490+ goto out; /* success */
18491+
18492+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
18493+ struct au_cp_generic cpg = {
18494+ .dentry = dentry,
18495+ .bdst = a->btgt,
18496+ .bsrc = bstart,
18497+ .len = sz,
18498+ .pin = &a->pin,
18499+ .flags = AuCpup_DTIME | AuCpup_HOPEN
18500+ };
18501+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
18502+ if (!err)
18503+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18504+ } else if (!hi_wh)
18505+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18506+ else
18507+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 18508+
4f0767ce 18509+out_unlock:
4a4d8108 18510+ a->h_inode = a->h_path.dentry->d_inode;
86dc4139 18511+ if (!err)
dece6358 18512+ goto out; /* success */
4a4d8108 18513+ au_unpin(&a->pin);
4f0767ce 18514+out_parent:
4a4d8108
AM
18515+ if (parent) {
18516+ di_write_unlock(parent);
18517+ dput(parent);
18518+ }
4f0767ce 18519+out:
86dc4139
AM
18520+ if (!err)
18521+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 18522+ return err;
18523+}
18524+
4a4d8108 18525+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 18526+{
4a4d8108 18527+ int err;
523b37e3 18528+ struct inode *inode, *delegated;
4a4d8108
AM
18529+ struct super_block *sb;
18530+ struct file *file;
18531+ struct au_icpup_args *a;
1facf9fc 18532+
4a4d8108
AM
18533+ inode = dentry->d_inode;
18534+ IMustLock(inode);
dece6358 18535+
4a4d8108
AM
18536+ err = -ENOMEM;
18537+ a = kzalloc(sizeof(*a), GFP_NOFS);
18538+ if (unlikely(!a))
18539+ goto out;
1facf9fc 18540+
4a4d8108
AM
18541+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
18542+ ia->ia_valid &= ~ATTR_MODE;
dece6358 18543+
4a4d8108
AM
18544+ file = NULL;
18545+ sb = dentry->d_sb;
e49829fe
JR
18546+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18547+ if (unlikely(err))
18548+ goto out_kfree;
18549+
4a4d8108
AM
18550+ if (ia->ia_valid & ATTR_FILE) {
18551+ /* currently ftruncate(2) only */
7e9cd9fe 18552+ AuDebugOn(!d_is_reg(dentry));
4a4d8108
AM
18553+ file = ia->ia_file;
18554+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
18555+ if (unlikely(err))
18556+ goto out_si;
18557+ ia->ia_file = au_hf_top(file);
18558+ a->udba = AuOpt_UDBA_NONE;
18559+ } else {
18560+ /* fchmod() doesn't pass ia_file */
18561+ a->udba = au_opt_udba(sb);
027c5e7a
AM
18562+ di_write_lock_child(dentry);
18563+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
18564+ if (d_unhashed(dentry))
18565+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
18566+ if (a->udba != AuOpt_UDBA_NONE) {
18567+ AuDebugOn(IS_ROOT(dentry));
18568+ err = au_reval_for_attr(dentry, au_sigen(sb));
18569+ if (unlikely(err))
18570+ goto out_dentry;
18571+ }
dece6358 18572+ }
dece6358 18573+
4a4d8108
AM
18574+ err = au_pin_and_icpup(dentry, ia, a);
18575+ if (unlikely(err < 0))
18576+ goto out_dentry;
18577+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
18578+ ia->ia_file = NULL;
18579+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 18580+ }
dece6358 18581+
4a4d8108
AM
18582+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
18583+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
18584+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 18585+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
18586+ if (unlikely(err))
18587+ goto out_unlock;
18588+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
18589+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 18590+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
18591+ if (unlikely(err))
18592+ goto out_unlock;
18593+ }
dece6358 18594+
4a4d8108
AM
18595+ if (ia->ia_valid & ATTR_SIZE) {
18596+ struct file *f;
1308ab2a 18597+
953406b4 18598+ if (ia->ia_size < i_size_read(inode))
4a4d8108 18599+ /* unmap only */
953406b4 18600+ truncate_setsize(inode, ia->ia_size);
1308ab2a 18601+
4a4d8108
AM
18602+ f = NULL;
18603+ if (ia->ia_valid & ATTR_FILE)
18604+ f = ia->ia_file;
18605+ mutex_unlock(&a->h_inode->i_mutex);
18606+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
18607+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
523b37e3
AM
18608+ } else {
18609+ delegated = NULL;
18610+ while (1) {
18611+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
18612+ if (delegated) {
18613+ err = break_deleg_wait(&delegated);
18614+ if (!err)
18615+ continue;
18616+ }
18617+ break;
18618+ }
18619+ }
4a4d8108
AM
18620+ if (!err)
18621+ au_cpup_attr_changeable(inode);
1308ab2a 18622+
4f0767ce 18623+out_unlock:
4a4d8108
AM
18624+ mutex_unlock(&a->h_inode->i_mutex);
18625+ au_unpin(&a->pin);
027c5e7a
AM
18626+ if (unlikely(err))
18627+ au_update_dbstart(dentry);
4f0767ce 18628+out_dentry:
4a4d8108
AM
18629+ di_write_unlock(dentry);
18630+ if (file) {
18631+ fi_write_unlock(file);
18632+ ia->ia_file = file;
18633+ ia->ia_valid |= ATTR_FILE;
18634+ }
4f0767ce 18635+out_si:
4a4d8108 18636+ si_read_unlock(sb);
e49829fe 18637+out_kfree:
4a4d8108 18638+ kfree(a);
4f0767ce 18639+out:
4a4d8108
AM
18640+ AuTraceErr(err);
18641+ return err;
1facf9fc 18642+}
18643+
c1595e42
JR
18644+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
18645+static int au_h_path_to_set_attr(struct dentry *dentry,
18646+ struct au_icpup_args *a, struct path *h_path)
18647+{
18648+ int err;
18649+ struct super_block *sb;
18650+
18651+ sb = dentry->d_sb;
18652+ a->udba = au_opt_udba(sb);
18653+ /* no d_unlinked(), to set UDBA_NONE for root */
18654+ if (d_unhashed(dentry))
18655+ a->udba = AuOpt_UDBA_NONE;
18656+ if (a->udba != AuOpt_UDBA_NONE) {
18657+ AuDebugOn(IS_ROOT(dentry));
18658+ err = au_reval_for_attr(dentry, au_sigen(sb));
18659+ if (unlikely(err))
18660+ goto out;
18661+ }
18662+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
18663+ if (unlikely(err < 0))
18664+ goto out;
18665+
18666+ h_path->dentry = a->h_path.dentry;
18667+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
18668+
18669+out:
18670+ return err;
18671+}
18672+
18673+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg)
18674+{
18675+ int err;
18676+ struct path h_path;
18677+ struct super_block *sb;
18678+ struct au_icpup_args *a;
18679+ struct inode *inode, *h_inode;
18680+
18681+ inode = dentry->d_inode;
18682+ IMustLock(inode);
18683+
18684+ err = -ENOMEM;
18685+ a = kzalloc(sizeof(*a), GFP_NOFS);
18686+ if (unlikely(!a))
18687+ goto out;
18688+
18689+ sb = dentry->d_sb;
18690+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18691+ if (unlikely(err))
18692+ goto out_kfree;
18693+
18694+ h_path.dentry = NULL; /* silence gcc */
18695+ di_write_lock_child(dentry);
18696+ err = au_h_path_to_set_attr(dentry, a, &h_path);
18697+ if (unlikely(err))
18698+ goto out_di;
18699+
18700+ mutex_unlock(&a->h_inode->i_mutex);
18701+ switch (arg->type) {
18702+ case AU_XATTR_SET:
18703+ err = vfsub_setxattr(h_path.dentry,
18704+ arg->u.set.name, arg->u.set.value,
18705+ arg->u.set.size, arg->u.set.flags);
18706+ break;
18707+ case AU_XATTR_REMOVE:
18708+ err = vfsub_removexattr(h_path.dentry, arg->u.remove.name);
18709+ break;
18710+ case AU_ACL_SET:
18711+ err = -EOPNOTSUPP;
18712+ h_inode = h_path.dentry->d_inode;
18713+ if (h_inode->i_op->set_acl)
18714+ err = h_inode->i_op->set_acl(h_inode,
18715+ arg->u.acl_set.acl,
18716+ arg->u.acl_set.type);
18717+ break;
18718+ }
18719+ if (!err)
18720+ au_cpup_attr_timesizes(inode);
18721+
18722+ au_unpin(&a->pin);
18723+ if (unlikely(err))
18724+ au_update_dbstart(dentry);
18725+
18726+out_di:
18727+ di_write_unlock(dentry);
18728+ si_read_unlock(sb);
18729+out_kfree:
18730+ kfree(a);
18731+out:
18732+ AuTraceErr(err);
18733+ return err;
18734+}
18735+#endif
18736+
4a4d8108
AM
18737+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
18738+ unsigned int nlink)
1facf9fc 18739+{
9dbd164d
AM
18740+ unsigned int n;
18741+
4a4d8108 18742+ inode->i_mode = st->mode;
86dc4139
AM
18743+ /* don't i_[ug]id_write() here */
18744+ inode->i_uid = st->uid;
18745+ inode->i_gid = st->gid;
4a4d8108
AM
18746+ inode->i_atime = st->atime;
18747+ inode->i_mtime = st->mtime;
18748+ inode->i_ctime = st->ctime;
1facf9fc 18749+
4a4d8108
AM
18750+ au_cpup_attr_nlink(inode, /*force*/0);
18751+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
18752+ n = inode->i_nlink;
18753+ n -= nlink;
18754+ n += st->nlink;
f6b6e03d 18755+ smp_mb(); /* for i_nlink */
7eafdf33 18756+ /* 0 can happen */
92d182d2 18757+ set_nlink(inode, n);
4a4d8108 18758+ }
1facf9fc 18759+
4a4d8108
AM
18760+ spin_lock(&inode->i_lock);
18761+ inode->i_blocks = st->blocks;
18762+ i_size_write(inode, st->size);
18763+ spin_unlock(&inode->i_lock);
1facf9fc 18764+}
18765+
c1595e42
JR
18766+/*
18767+ * common routine for aufs_getattr() and aufs_getxattr().
18768+ * returns zero or negative (an error).
18769+ * @dentry will be read-locked in success.
18770+ */
18771+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path)
1facf9fc 18772+{
4a4d8108 18773+ int err;
076b876e 18774+ unsigned int mnt_flags, sigen;
c1595e42 18775+ unsigned char udba_none;
4a4d8108 18776+ aufs_bindex_t bindex;
4a4d8108
AM
18777+ struct super_block *sb, *h_sb;
18778+ struct inode *inode;
1facf9fc 18779+
c1595e42
JR
18780+ h_path->mnt = NULL;
18781+ h_path->dentry = NULL;
18782+
18783+ err = 0;
4a4d8108 18784+ sb = dentry->d_sb;
4a4d8108
AM
18785+ mnt_flags = au_mntflags(sb);
18786+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 18787+
4a4d8108 18788+ /* support fstat(2) */
027c5e7a 18789+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 18790+ sigen = au_sigen(sb);
027c5e7a
AM
18791+ err = au_digen_test(dentry, sigen);
18792+ if (!err) {
4a4d8108 18793+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a 18794+ err = au_dbrange_test(dentry);
c1595e42
JR
18795+ if (unlikely(err)) {
18796+ di_read_unlock(dentry, AuLock_IR);
18797+ goto out;
18798+ }
027c5e7a 18799+ } else {
4a4d8108
AM
18800+ AuDebugOn(IS_ROOT(dentry));
18801+ di_write_lock_child(dentry);
027c5e7a
AM
18802+ err = au_dbrange_test(dentry);
18803+ if (!err)
18804+ err = au_reval_for_attr(dentry, sigen);
c1595e42
JR
18805+ if (!err)
18806+ di_downgrade_lock(dentry, AuLock_IR);
18807+ else {
18808+ di_write_unlock(dentry);
18809+ goto out;
18810+ }
4a4d8108
AM
18811+ }
18812+ } else
18813+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 18814+
c1595e42 18815+ inode = dentry->d_inode;
4a4d8108 18816+ bindex = au_ibstart(inode);
c1595e42
JR
18817+ h_path->mnt = au_sbr_mnt(sb, bindex);
18818+ h_sb = h_path->mnt->mnt_sb;
18819+ if (!force
18820+ && !au_test_fs_bad_iattr(h_sb)
18821+ && udba_none)
18822+ goto out; /* success */
1facf9fc 18823+
4a4d8108 18824+ if (au_dbstart(dentry) == bindex)
c1595e42 18825+ h_path->dentry = au_h_dptr(dentry, bindex);
4a4d8108 18826+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c1595e42
JR
18827+ h_path->dentry = au_plink_lkup(inode, bindex);
18828+ if (IS_ERR(h_path->dentry))
18829+ /* pretending success */
18830+ h_path->dentry = NULL;
18831+ else
18832+ dput(h_path->dentry);
4a4d8108 18833+ }
c1595e42
JR
18834+
18835+out:
18836+ return err;
18837+}
18838+
18839+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
18840+ struct dentry *dentry, struct kstat *st)
18841+{
18842+ int err;
18843+ unsigned char positive;
18844+ struct path h_path;
18845+ struct inode *inode;
18846+ struct super_block *sb;
18847+
18848+ inode = dentry->d_inode;
18849+ sb = dentry->d_sb;
18850+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18851+ if (unlikely(err))
18852+ goto out;
18853+ err = au_h_path_getattr(dentry, /*force*/0, &h_path);
18854+ if (unlikely(err))
18855+ goto out_si;
c06a8ce3 18856+ if (unlikely(!h_path.dentry))
c1595e42 18857+ /* illegally overlapped or something */
4a4d8108
AM
18858+ goto out_fill; /* pretending success */
18859+
c06a8ce3 18860+ positive = !!h_path.dentry->d_inode;
4a4d8108 18861+ if (positive)
c06a8ce3 18862+ err = vfs_getattr(&h_path, st);
4a4d8108
AM
18863+ if (!err) {
18864+ if (positive)
c06a8ce3
AM
18865+ au_refresh_iattr(inode, st,
18866+ h_path.dentry->d_inode->i_nlink);
4a4d8108 18867+ goto out_fill; /* success */
1facf9fc 18868+ }
7f207e10 18869+ AuTraceErr(err);
c1595e42 18870+ goto out_di;
4a4d8108 18871+
4f0767ce 18872+out_fill:
4a4d8108 18873+ generic_fillattr(inode, st);
c1595e42 18874+out_di:
4a4d8108 18875+ di_read_unlock(dentry, AuLock_IR);
c1595e42 18876+out_si:
4a4d8108 18877+ si_read_unlock(sb);
7f207e10
AM
18878+out:
18879+ AuTraceErr(err);
4a4d8108 18880+ return err;
1facf9fc 18881+}
18882+
18883+/* ---------------------------------------------------------------------- */
18884+
4a4d8108
AM
18885+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
18886+ int bufsiz)
1facf9fc 18887+{
18888+ int err;
4a4d8108
AM
18889+ struct super_block *sb;
18890+ struct dentry *h_dentry;
1facf9fc 18891+
4a4d8108
AM
18892+ err = -EINVAL;
18893+ h_dentry = au_h_dptr(dentry, bindex);
18894+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
18895+ goto out;
1facf9fc 18896+
4a4d8108
AM
18897+ err = security_inode_readlink(h_dentry);
18898+ if (unlikely(err))
dece6358 18899+ goto out;
1facf9fc 18900+
4a4d8108
AM
18901+ sb = dentry->d_sb;
18902+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
18903+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
18904+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
1facf9fc 18905+ }
4a4d8108 18906+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 18907+
4f0767ce 18908+out:
4a4d8108
AM
18909+ return err;
18910+}
1facf9fc 18911+
4a4d8108
AM
18912+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
18913+{
18914+ int err;
1facf9fc 18915+
027c5e7a
AM
18916+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
18917+ if (unlikely(err))
18918+ goto out;
18919+ err = au_d_hashed_positive(dentry);
18920+ if (!err)
18921+ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
4a4d8108 18922+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 18923+
027c5e7a 18924+out:
4a4d8108
AM
18925+ return err;
18926+}
1facf9fc 18927+
4a4d8108
AM
18928+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
18929+{
18930+ int err;
4a4d8108 18931+ mm_segment_t old_fs;
b752ccd1
AM
18932+ union {
18933+ char *k;
18934+ char __user *u;
18935+ } buf;
1facf9fc 18936+
4a4d8108 18937+ err = -ENOMEM;
537831f9 18938+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 18939+ if (unlikely(!buf.k))
4a4d8108 18940+ goto out;
1facf9fc 18941+
027c5e7a
AM
18942+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
18943+ if (unlikely(err))
18944+ goto out_name;
18945+
18946+ err = au_d_hashed_positive(dentry);
18947+ if (!err) {
18948+ old_fs = get_fs();
18949+ set_fs(KERNEL_DS);
18950+ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
18951+ set_fs(old_fs);
18952+ }
4a4d8108 18953+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 18954+
4a4d8108 18955+ if (err >= 0) {
b752ccd1 18956+ buf.k[err] = 0;
4a4d8108 18957+ /* will be freed by put_link */
b752ccd1 18958+ nd_set_link(nd, buf.k);
4a4d8108 18959+ return NULL; /* success */
1308ab2a 18960+ }
1facf9fc 18961+
027c5e7a 18962+out_name:
537831f9 18963+ free_page((unsigned long)buf.k);
4f0767ce 18964+out:
4a4d8108
AM
18965+ AuTraceErr(err);
18966+ return ERR_PTR(err);
18967+}
1facf9fc 18968+
4a4d8108
AM
18969+static void aufs_put_link(struct dentry *dentry __maybe_unused,
18970+ struct nameidata *nd, void *cookie __maybe_unused)
18971+{
537831f9
AM
18972+ char *p;
18973+
18974+ p = nd_get_link(nd);
18975+ if (!IS_ERR_OR_NULL(p))
18976+ free_page((unsigned long)p);
4a4d8108 18977+}
1facf9fc 18978+
4a4d8108 18979+/* ---------------------------------------------------------------------- */
1facf9fc 18980+
0c3ec466 18981+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 18982+{
0c3ec466
AM
18983+ int err;
18984+ struct super_block *sb;
18985+ struct inode *h_inode;
18986+
18987+ sb = inode->i_sb;
18988+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
18989+ lockdep_off();
18990+ si_read_lock(sb, AuLock_FLUSH);
18991+ ii_write_lock_child(inode);
18992+ lockdep_on();
18993+ h_inode = au_h_iptr(inode, au_ibstart(inode));
18994+ err = vfsub_update_time(h_inode, ts, flags);
18995+ lockdep_off();
38d290e6
JR
18996+ if (!err)
18997+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
18998+ ii_write_unlock(inode);
18999+ si_read_unlock(sb);
19000+ lockdep_on();
38d290e6
JR
19001+
19002+ if (!err && (flags & S_VERSION))
19003+ inode_inc_iversion(inode);
19004+
0c3ec466 19005+ return err;
4a4d8108 19006+}
1facf9fc 19007+
4a4d8108 19008+/* ---------------------------------------------------------------------- */
1308ab2a 19009+
4a4d8108
AM
19010+struct inode_operations aufs_symlink_iop = {
19011+ .permission = aufs_permission,
c1595e42
JR
19012+#ifdef CONFIG_FS_POSIX_ACL
19013+ .get_acl = aufs_get_acl,
19014+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
19015+#endif
19016+
4a4d8108
AM
19017+ .setattr = aufs_setattr,
19018+ .getattr = aufs_getattr,
0c3ec466 19019+
c1595e42
JR
19020+#ifdef CONFIG_AUFS_XATTR
19021+ .setxattr = aufs_setxattr,
19022+ .getxattr = aufs_getxattr,
19023+ .listxattr = aufs_listxattr,
19024+ .removexattr = aufs_removexattr,
19025+#endif
19026+
4a4d8108
AM
19027+ .readlink = aufs_readlink,
19028+ .follow_link = aufs_follow_link,
0c3ec466
AM
19029+ .put_link = aufs_put_link,
19030+
19031+ /* .update_time = aufs_update_time */
4a4d8108
AM
19032+};
19033+
19034+struct inode_operations aufs_dir_iop = {
19035+ .create = aufs_create,
19036+ .lookup = aufs_lookup,
19037+ .link = aufs_link,
19038+ .unlink = aufs_unlink,
19039+ .symlink = aufs_symlink,
19040+ .mkdir = aufs_mkdir,
19041+ .rmdir = aufs_rmdir,
19042+ .mknod = aufs_mknod,
19043+ .rename = aufs_rename,
19044+
19045+ .permission = aufs_permission,
c1595e42
JR
19046+#ifdef CONFIG_FS_POSIX_ACL
19047+ .get_acl = aufs_get_acl,
19048+ .set_acl = aufs_set_acl,
19049+#endif
19050+
4a4d8108 19051+ .setattr = aufs_setattr,
0c3ec466
AM
19052+ .getattr = aufs_getattr,
19053+
c1595e42
JR
19054+#ifdef CONFIG_AUFS_XATTR
19055+ .setxattr = aufs_setxattr,
19056+ .getxattr = aufs_getxattr,
19057+ .listxattr = aufs_listxattr,
19058+ .removexattr = aufs_removexattr,
19059+#endif
19060+
38d290e6 19061+ .update_time = aufs_update_time,
b4510431 19062+ /* no support for atomic_open() */
38d290e6
JR
19063+
19064+ .tmpfile = aufs_tmpfile
4a4d8108
AM
19065+};
19066+
19067+struct inode_operations aufs_iop = {
19068+ .permission = aufs_permission,
c1595e42
JR
19069+#ifdef CONFIG_FS_POSIX_ACL
19070+ .get_acl = aufs_get_acl,
19071+ .set_acl = aufs_set_acl,
19072+#endif
19073+
4a4d8108
AM
19074+ .setattr = aufs_setattr,
19075+ .getattr = aufs_getattr,
0c3ec466 19076+
c1595e42
JR
19077+#ifdef CONFIG_AUFS_XATTR
19078+ .setxattr = aufs_setxattr,
19079+ .getxattr = aufs_getxattr,
19080+ .listxattr = aufs_listxattr,
19081+ .removexattr = aufs_removexattr,
19082+#endif
19083+
0c3ec466 19084+ .update_time = aufs_update_time
4a4d8108 19085+};
7f207e10
AM
19086diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
19087--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 19088+++ linux/fs/aufs/i_op_del.c 2015-04-13 15:10:20.786823613 +0200
076b876e 19089@@ -0,0 +1,507 @@
1facf9fc 19090+/*
2000de60 19091+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 19092+ *
19093+ * This program, aufs is free software; you can redistribute it and/or modify
19094+ * it under the terms of the GNU General Public License as published by
19095+ * the Free Software Foundation; either version 2 of the License, or
19096+ * (at your option) any later version.
dece6358
AM
19097+ *
19098+ * This program is distributed in the hope that it will be useful,
19099+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19100+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19101+ * GNU General Public License for more details.
19102+ *
19103+ * You should have received a copy of the GNU General Public License
523b37e3 19104+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19105+ */
19106+
19107+/*
4a4d8108 19108+ * inode operations (del entry)
1308ab2a 19109+ */
dece6358 19110+
1308ab2a 19111+#include "aufs.h"
dece6358 19112+
4a4d8108
AM
19113+/*
19114+ * decide if a new whiteout for @dentry is necessary or not.
19115+ * when it is necessary, prepare the parent dir for the upper branch whose
19116+ * branch index is @bcpup for creation. the actual creation of the whiteout will
19117+ * be done by caller.
19118+ * return value:
19119+ * 0: wh is unnecessary
19120+ * plus: wh is necessary
19121+ * minus: error
19122+ */
19123+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 19124+{
4a4d8108
AM
19125+ int need_wh, err;
19126+ aufs_bindex_t bstart;
19127+ struct super_block *sb;
dece6358 19128+
4a4d8108
AM
19129+ sb = dentry->d_sb;
19130+ bstart = au_dbstart(dentry);
19131+ if (*bcpup < 0) {
19132+ *bcpup = bstart;
19133+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
19134+ err = AuWbrCopyup(au_sbi(sb), dentry);
19135+ *bcpup = err;
19136+ if (unlikely(err < 0))
19137+ goto out;
19138+ }
19139+ } else
19140+ AuDebugOn(bstart < *bcpup
19141+ || au_test_ro(sb, *bcpup, dentry->d_inode));
19142+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 19143+
4a4d8108
AM
19144+ if (*bcpup != bstart) {
19145+ err = au_cpup_dirs(dentry, *bcpup);
19146+ if (unlikely(err))
19147+ goto out;
19148+ need_wh = 1;
19149+ } else {
027c5e7a 19150+ struct au_dinfo *dinfo, *tmp;
4a4d8108 19151+
027c5e7a
AM
19152+ need_wh = -ENOMEM;
19153+ dinfo = au_di(dentry);
19154+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
19155+ if (tmp) {
19156+ au_di_cp(tmp, dinfo);
19157+ au_di_swap(tmp, dinfo);
19158+ /* returns the number of positive dentries */
537831f9 19159+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
19160+ au_di_swap(tmp, dinfo);
19161+ au_rw_write_unlock(&tmp->di_rwsem);
19162+ au_di_free(tmp);
4a4d8108
AM
19163+ }
19164+ }
19165+ AuDbg("need_wh %d\n", need_wh);
19166+ err = need_wh;
19167+
4f0767ce 19168+out:
4a4d8108 19169+ return err;
1facf9fc 19170+}
19171+
4a4d8108
AM
19172+/*
19173+ * simple tests for the del-entry operations.
19174+ * following the checks in vfs, plus the parent-child relationship.
19175+ */
19176+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
19177+ struct dentry *h_parent, int isdir)
1facf9fc 19178+{
4a4d8108
AM
19179+ int err;
19180+ umode_t h_mode;
19181+ struct dentry *h_dentry, *h_latest;
1308ab2a 19182+ struct inode *h_inode;
1facf9fc 19183+
4a4d8108
AM
19184+ h_dentry = au_h_dptr(dentry, bindex);
19185+ h_inode = h_dentry->d_inode;
19186+ if (dentry->d_inode) {
19187+ err = -ENOENT;
19188+ if (unlikely(!h_inode || !h_inode->i_nlink))
19189+ goto out;
1facf9fc 19190+
4a4d8108
AM
19191+ h_mode = h_inode->i_mode;
19192+ if (!isdir) {
19193+ err = -EISDIR;
19194+ if (unlikely(S_ISDIR(h_mode)))
19195+ goto out;
19196+ } else if (unlikely(!S_ISDIR(h_mode))) {
19197+ err = -ENOTDIR;
19198+ goto out;
19199+ }
19200+ } else {
19201+ /* rename(2) case */
19202+ err = -EIO;
19203+ if (unlikely(h_inode))
19204+ goto out;
19205+ }
1facf9fc 19206+
4a4d8108
AM
19207+ err = -ENOENT;
19208+ /* expected parent dir is locked */
19209+ if (unlikely(h_parent != h_dentry->d_parent))
19210+ goto out;
19211+ err = 0;
19212+
19213+ /*
19214+ * rmdir a dir may break the consistency on some filesystem.
19215+ * let's try heavy test.
19216+ */
19217+ err = -EACCES;
076b876e
AM
19218+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
19219+ && au_test_h_perm(h_parent->d_inode,
19220+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
19221+ goto out;
19222+
076b876e 19223+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
19224+ err = -EIO;
19225+ if (IS_ERR(h_latest))
19226+ goto out;
19227+ if (h_latest == h_dentry)
19228+ err = 0;
19229+ dput(h_latest);
19230+
4f0767ce 19231+out:
4a4d8108 19232+ return err;
1308ab2a 19233+}
1facf9fc 19234+
4a4d8108
AM
19235+/*
19236+ * decide the branch where we operate for @dentry. the branch index will be set
19237+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
19238+ * dir for reverting.
19239+ * when a new whiteout is necessary, create it.
19240+ */
19241+static struct dentry*
19242+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
19243+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 19244+{
4a4d8108
AM
19245+ struct dentry *wh_dentry;
19246+ struct super_block *sb;
19247+ struct path h_path;
19248+ int err, need_wh;
19249+ unsigned int udba;
19250+ aufs_bindex_t bcpup;
dece6358 19251+
4a4d8108
AM
19252+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
19253+ wh_dentry = ERR_PTR(need_wh);
19254+ if (unlikely(need_wh < 0))
19255+ goto out;
19256+
19257+ sb = dentry->d_sb;
19258+ udba = au_opt_udba(sb);
19259+ bcpup = *rbcpup;
19260+ err = au_pin(pin, dentry, bcpup, udba,
19261+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19262+ wh_dentry = ERR_PTR(err);
19263+ if (unlikely(err))
19264+ goto out;
19265+
19266+ h_path.dentry = au_pinned_h_parent(pin);
19267+ if (udba != AuOpt_UDBA_NONE
19268+ && au_dbstart(dentry) == bcpup) {
19269+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
19270+ wh_dentry = ERR_PTR(err);
19271+ if (unlikely(err))
19272+ goto out_unpin;
19273+ }
19274+
19275+ h_path.mnt = au_sbr_mnt(sb, bcpup);
19276+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
19277+ wh_dentry = NULL;
19278+ if (!need_wh)
19279+ goto out; /* success, no need to create whiteout */
19280+
19281+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
19282+ if (IS_ERR(wh_dentry))
19283+ goto out_unpin;
19284+
19285+ /* returns with the parent is locked and wh_dentry is dget-ed */
19286+ goto out; /* success */
19287+
4f0767ce 19288+out_unpin:
4a4d8108 19289+ au_unpin(pin);
4f0767ce 19290+out:
4a4d8108 19291+ return wh_dentry;
1facf9fc 19292+}
19293+
4a4d8108
AM
19294+/*
19295+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
19296+ * in order to be revertible and save time for removing many child whiteouts
19297+ * under the dir.
19298+ * returns 1 when there are too many child whiteout and caller should remove
19299+ * them asynchronously. returns 0 when the number of children is enough small to
19300+ * remove now or the branch fs is a remote fs.
19301+ * otherwise return an error.
19302+ */
19303+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
19304+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 19305+{
4a4d8108
AM
19306+ int rmdir_later, err, dirwh;
19307+ struct dentry *h_dentry;
19308+ struct super_block *sb;
19309+
19310+ sb = dentry->d_sb;
19311+ SiMustAnyLock(sb);
19312+ h_dentry = au_h_dptr(dentry, bindex);
19313+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
19314+ if (unlikely(err))
19315+ goto out;
19316+
19317+ /* stop monitoring */
19318+ au_hn_free(au_hi(dentry->d_inode, bindex));
19319+
19320+ if (!au_test_fs_remote(h_dentry->d_sb)) {
19321+ dirwh = au_sbi(sb)->si_dirwh;
19322+ rmdir_later = (dirwh <= 1);
19323+ if (!rmdir_later)
19324+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
19325+ dirwh);
19326+ if (rmdir_later)
19327+ return rmdir_later;
19328+ }
1facf9fc 19329+
4a4d8108
AM
19330+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
19331+ if (unlikely(err)) {
523b37e3
AM
19332+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
19333+ h_dentry, bindex, err);
4a4d8108
AM
19334+ err = 0;
19335+ }
dece6358 19336+
4f0767ce 19337+out:
4a4d8108
AM
19338+ AuTraceErr(err);
19339+ return err;
19340+}
1308ab2a 19341+
4a4d8108
AM
19342+/*
19343+ * final procedure for deleting a entry.
19344+ * maintain dentry and iattr.
19345+ */
19346+static void epilog(struct inode *dir, struct dentry *dentry,
19347+ aufs_bindex_t bindex)
19348+{
19349+ struct inode *inode;
1308ab2a 19350+
4a4d8108
AM
19351+ inode = dentry->d_inode;
19352+ d_drop(dentry);
19353+ inode->i_ctime = dir->i_ctime;
1308ab2a 19354+
4a4d8108
AM
19355+ if (au_ibstart(dir) == bindex)
19356+ au_cpup_attr_timesizes(dir);
19357+ dir->i_version++;
1facf9fc 19358+}
19359+
4a4d8108
AM
19360+/*
19361+ * when an error happened, remove the created whiteout and revert everything.
19362+ */
7f207e10
AM
19363+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
19364+ aufs_bindex_t bwh, struct dentry *wh_dentry,
19365+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 19366+{
4a4d8108
AM
19367+ int rerr;
19368+ struct path h_path = {
19369+ .dentry = wh_dentry,
7f207e10 19370+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 19371+ };
dece6358 19372+
7f207e10 19373+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
19374+ if (!rerr) {
19375+ au_set_dbwh(dentry, bwh);
19376+ au_dtime_revert(dt);
19377+ return 0;
19378+ }
dece6358 19379+
523b37e3 19380+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 19381+ return -EIO;
1facf9fc 19382+}
19383+
4a4d8108 19384+/* ---------------------------------------------------------------------- */
1facf9fc 19385+
4a4d8108 19386+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 19387+{
4a4d8108
AM
19388+ int err;
19389+ aufs_bindex_t bwh, bindex, bstart;
523b37e3 19390+ struct inode *inode, *h_dir, *delegated;
4a4d8108 19391+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
19392+ /* to reuduce stack size */
19393+ struct {
19394+ struct au_dtime dt;
19395+ struct au_pin pin;
19396+ struct path h_path;
19397+ } *a;
1facf9fc 19398+
4a4d8108 19399+ IMustLock(dir);
027c5e7a 19400+
c2b27bf2
AM
19401+ err = -ENOMEM;
19402+ a = kmalloc(sizeof(*a), GFP_NOFS);
19403+ if (unlikely(!a))
19404+ goto out;
19405+
027c5e7a
AM
19406+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
19407+ if (unlikely(err))
c2b27bf2 19408+ goto out_free;
027c5e7a
AM
19409+ err = au_d_hashed_positive(dentry);
19410+ if (unlikely(err))
19411+ goto out_unlock;
4a4d8108 19412+ inode = dentry->d_inode;
4a4d8108 19413+ IMustLock(inode);
027c5e7a 19414+ err = -EISDIR;
2000de60 19415+ if (unlikely(d_is_dir(dentry)))
027c5e7a 19416+ goto out_unlock; /* possible? */
1facf9fc 19417+
4a4d8108
AM
19418+ bstart = au_dbstart(dentry);
19419+ bwh = au_dbwh(dentry);
19420+ bindex = -1;
027c5e7a
AM
19421+ parent = dentry->d_parent; /* dir inode is locked */
19422+ di_write_lock_parent(parent);
c2b27bf2
AM
19423+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
19424+ &a->pin);
4a4d8108
AM
19425+ err = PTR_ERR(wh_dentry);
19426+ if (IS_ERR(wh_dentry))
027c5e7a 19427+ goto out_parent;
1facf9fc 19428+
c2b27bf2
AM
19429+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
19430+ a->h_path.dentry = au_h_dptr(dentry, bstart);
19431+ dget(a->h_path.dentry);
4a4d8108 19432+ if (bindex == bstart) {
c2b27bf2 19433+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
19434+ delegated = NULL;
19435+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
19436+ if (unlikely(err == -EWOULDBLOCK)) {
19437+ pr_warn("cannot retry for NFSv4 delegation"
19438+ " for an internal unlink\n");
19439+ iput(delegated);
19440+ }
4a4d8108
AM
19441+ } else {
19442+ /* dir inode is locked */
19443+ h_dir = wh_dentry->d_parent->d_inode;
19444+ IMustLock(h_dir);
19445+ err = 0;
19446+ }
dece6358 19447+
4a4d8108 19448+ if (!err) {
7f207e10 19449+ vfsub_drop_nlink(inode);
4a4d8108
AM
19450+ epilog(dir, dentry, bindex);
19451+
19452+ /* update target timestamps */
19453+ if (bindex == bstart) {
c2b27bf2
AM
19454+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
19455+ /*ignore*/
19456+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
4a4d8108
AM
19457+ } else
19458+ /* todo: this timestamp may be reverted later */
19459+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 19460+ goto out_unpin; /* success */
1facf9fc 19461+ }
19462+
4a4d8108
AM
19463+ /* revert */
19464+ if (wh_dentry) {
19465+ int rerr;
19466+
c2b27bf2
AM
19467+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19468+ &a->dt);
4a4d8108
AM
19469+ if (rerr)
19470+ err = rerr;
dece6358 19471+ }
1facf9fc 19472+
027c5e7a 19473+out_unpin:
c2b27bf2 19474+ au_unpin(&a->pin);
4a4d8108 19475+ dput(wh_dentry);
c2b27bf2 19476+ dput(a->h_path.dentry);
027c5e7a 19477+out_parent:
4a4d8108 19478+ di_write_unlock(parent);
027c5e7a 19479+out_unlock:
4a4d8108 19480+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19481+out_free:
19482+ kfree(a);
027c5e7a 19483+out:
4a4d8108 19484+ return err;
dece6358
AM
19485+}
19486+
4a4d8108 19487+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 19488+{
4a4d8108
AM
19489+ int err, rmdir_later;
19490+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
19491+ struct inode *inode;
19492+ struct dentry *parent, *wh_dentry, *h_dentry;
19493+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
19494+ /* to reuduce stack size */
19495+ struct {
19496+ struct au_dtime dt;
19497+ struct au_pin pin;
19498+ } *a;
1facf9fc 19499+
4a4d8108 19500+ IMustLock(dir);
027c5e7a 19501+
c2b27bf2
AM
19502+ err = -ENOMEM;
19503+ a = kmalloc(sizeof(*a), GFP_NOFS);
19504+ if (unlikely(!a))
19505+ goto out;
19506+
027c5e7a
AM
19507+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
19508+ if (unlikely(err))
c2b27bf2 19509+ goto out_free;
53392da6
AM
19510+ err = au_alive_dir(dentry);
19511+ if (unlikely(err))
027c5e7a 19512+ goto out_unlock;
53392da6 19513+ inode = dentry->d_inode;
4a4d8108 19514+ IMustLock(inode);
027c5e7a 19515+ err = -ENOTDIR;
2000de60 19516+ if (unlikely(!d_is_dir(dentry)))
027c5e7a 19517+ goto out_unlock; /* possible? */
dece6358 19518+
4a4d8108
AM
19519+ err = -ENOMEM;
19520+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
19521+ if (unlikely(!args))
19522+ goto out_unlock;
dece6358 19523+
4a4d8108
AM
19524+ parent = dentry->d_parent; /* dir inode is locked */
19525+ di_write_lock_parent(parent);
19526+ err = au_test_empty(dentry, &args->whlist);
19527+ if (unlikely(err))
027c5e7a 19528+ goto out_parent;
1facf9fc 19529+
4a4d8108
AM
19530+ bstart = au_dbstart(dentry);
19531+ bwh = au_dbwh(dentry);
19532+ bindex = -1;
c2b27bf2
AM
19533+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
19534+ &a->pin);
4a4d8108
AM
19535+ err = PTR_ERR(wh_dentry);
19536+ if (IS_ERR(wh_dentry))
027c5e7a 19537+ goto out_parent;
1facf9fc 19538+
4a4d8108
AM
19539+ h_dentry = au_h_dptr(dentry, bstart);
19540+ dget(h_dentry);
19541+ rmdir_later = 0;
19542+ if (bindex == bstart) {
19543+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
19544+ if (err > 0) {
19545+ rmdir_later = err;
19546+ err = 0;
19547+ }
19548+ } else {
19549+ /* stop monitoring */
19550+ au_hn_free(au_hi(inode, bstart));
19551+
19552+ /* dir inode is locked */
19553+ IMustLock(wh_dentry->d_parent->d_inode);
1facf9fc 19554+ err = 0;
19555+ }
19556+
4a4d8108 19557+ if (!err) {
027c5e7a 19558+ vfsub_dead_dir(inode);
4a4d8108
AM
19559+ au_set_dbdiropq(dentry, -1);
19560+ epilog(dir, dentry, bindex);
1308ab2a 19561+
4a4d8108
AM
19562+ if (rmdir_later) {
19563+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
19564+ args = NULL;
19565+ }
1308ab2a 19566+
4a4d8108 19567+ goto out_unpin; /* success */
1facf9fc 19568+ }
19569+
4a4d8108
AM
19570+ /* revert */
19571+ AuLabel(revert);
19572+ if (wh_dentry) {
19573+ int rerr;
1308ab2a 19574+
c2b27bf2
AM
19575+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19576+ &a->dt);
4a4d8108
AM
19577+ if (rerr)
19578+ err = rerr;
1facf9fc 19579+ }
19580+
4f0767ce 19581+out_unpin:
c2b27bf2 19582+ au_unpin(&a->pin);
4a4d8108
AM
19583+ dput(wh_dentry);
19584+ dput(h_dentry);
027c5e7a 19585+out_parent:
4a4d8108
AM
19586+ di_write_unlock(parent);
19587+ if (args)
19588+ au_whtmp_rmdir_free(args);
4f0767ce 19589+out_unlock:
4a4d8108 19590+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19591+out_free:
19592+ kfree(a);
4f0767ce 19593+out:
4a4d8108
AM
19594+ AuTraceErr(err);
19595+ return err;
dece6358 19596+}
7f207e10
AM
19597diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
19598--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
19599+++ linux/fs/aufs/i_op_ren.c 2015-04-13 15:10:20.786823613 +0200
19600@@ -0,0 +1,1017 @@
1facf9fc 19601+/*
2000de60 19602+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 19603+ *
19604+ * This program, aufs is free software; you can redistribute it and/or modify
19605+ * it under the terms of the GNU General Public License as published by
19606+ * the Free Software Foundation; either version 2 of the License, or
19607+ * (at your option) any later version.
dece6358
AM
19608+ *
19609+ * This program is distributed in the hope that it will be useful,
19610+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19611+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19612+ * GNU General Public License for more details.
19613+ *
19614+ * You should have received a copy of the GNU General Public License
523b37e3 19615+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19616+ */
19617+
19618+/*
4a4d8108
AM
19619+ * inode operation (rename entry)
19620+ * todo: this is crazy monster
1facf9fc 19621+ */
19622+
19623+#include "aufs.h"
19624+
4a4d8108
AM
19625+enum { AuSRC, AuDST, AuSrcDst };
19626+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 19627+
4a4d8108
AM
19628+#define AuRen_ISDIR 1
19629+#define AuRen_ISSAMEDIR (1 << 1)
19630+#define AuRen_WHSRC (1 << 2)
19631+#define AuRen_WHDST (1 << 3)
19632+#define AuRen_MNT_WRITE (1 << 4)
19633+#define AuRen_DT_DSTDIR (1 << 5)
19634+#define AuRen_DIROPQ (1 << 6)
4a4d8108 19635+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
19636+#define au_fset_ren(flags, name) \
19637+ do { (flags) |= AuRen_##name; } while (0)
19638+#define au_fclr_ren(flags, name) \
19639+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 19640+
4a4d8108
AM
19641+struct au_ren_args {
19642+ struct {
19643+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
19644+ *wh_dentry;
19645+ struct inode *dir, *inode;
19646+ struct au_hinode *hdir;
19647+ struct au_dtime dt[AuParentChild];
19648+ aufs_bindex_t bstart;
19649+ } sd[AuSrcDst];
1facf9fc 19650+
4a4d8108
AM
19651+#define src_dentry sd[AuSRC].dentry
19652+#define src_dir sd[AuSRC].dir
19653+#define src_inode sd[AuSRC].inode
19654+#define src_h_dentry sd[AuSRC].h_dentry
19655+#define src_parent sd[AuSRC].parent
19656+#define src_h_parent sd[AuSRC].h_parent
19657+#define src_wh_dentry sd[AuSRC].wh_dentry
19658+#define src_hdir sd[AuSRC].hdir
19659+#define src_h_dir sd[AuSRC].hdir->hi_inode
19660+#define src_dt sd[AuSRC].dt
19661+#define src_bstart sd[AuSRC].bstart
1facf9fc 19662+
4a4d8108
AM
19663+#define dst_dentry sd[AuDST].dentry
19664+#define dst_dir sd[AuDST].dir
19665+#define dst_inode sd[AuDST].inode
19666+#define dst_h_dentry sd[AuDST].h_dentry
19667+#define dst_parent sd[AuDST].parent
19668+#define dst_h_parent sd[AuDST].h_parent
19669+#define dst_wh_dentry sd[AuDST].wh_dentry
19670+#define dst_hdir sd[AuDST].hdir
19671+#define dst_h_dir sd[AuDST].hdir->hi_inode
19672+#define dst_dt sd[AuDST].dt
19673+#define dst_bstart sd[AuDST].bstart
19674+
19675+ struct dentry *h_trap;
19676+ struct au_branch *br;
19677+ struct au_hinode *src_hinode;
19678+ struct path h_path;
19679+ struct au_nhash whlist;
027c5e7a 19680+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 19681+
1308ab2a 19682+ unsigned int flags;
1facf9fc 19683+
4a4d8108
AM
19684+ struct au_whtmp_rmdir *thargs;
19685+ struct dentry *h_dst;
19686+};
1308ab2a 19687+
4a4d8108 19688+/* ---------------------------------------------------------------------- */
1308ab2a 19689+
4a4d8108
AM
19690+/*
19691+ * functions for reverting.
19692+ * when an error happened in a single rename systemcall, we should revert
19693+ * everything as if nothing happend.
19694+ * we don't need to revert the copied-up/down the parent dir since they are
19695+ * harmless.
19696+ */
1facf9fc 19697+
4a4d8108
AM
19698+#define RevertFailure(fmt, ...) do { \
19699+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
19700+ ##__VA_ARGS__, err, rerr); \
19701+ err = -EIO; \
19702+} while (0)
1facf9fc 19703+
4a4d8108 19704+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 19705+{
4a4d8108 19706+ int rerr;
1facf9fc 19707+
4a4d8108
AM
19708+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
19709+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
19710+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 19711+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108 19712+ if (rerr)
523b37e3 19713+ RevertFailure("remove diropq %pd", a->src_dentry);
4a4d8108 19714+}
1facf9fc 19715+
4a4d8108
AM
19716+static void au_ren_rev_rename(int err, struct au_ren_args *a)
19717+{
19718+ int rerr;
523b37e3 19719+ struct inode *delegated;
1facf9fc 19720+
b4510431
AM
19721+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
19722+ a->src_h_parent);
4a4d8108
AM
19723+ rerr = PTR_ERR(a->h_path.dentry);
19724+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 19725+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 19726+ return;
1facf9fc 19727+ }
19728+
523b37e3 19729+ delegated = NULL;
4a4d8108
AM
19730+ rerr = vfsub_rename(a->dst_h_dir,
19731+ au_h_dptr(a->src_dentry, a->btgt),
523b37e3
AM
19732+ a->src_h_dir, &a->h_path, &delegated);
19733+ if (unlikely(rerr == -EWOULDBLOCK)) {
19734+ pr_warn("cannot retry for NFSv4 delegation"
19735+ " for an internal rename\n");
19736+ iput(delegated);
19737+ }
4a4d8108
AM
19738+ d_drop(a->h_path.dentry);
19739+ dput(a->h_path.dentry);
19740+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
19741+ if (rerr)
523b37e3 19742+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 19743+}
19744+
4a4d8108 19745+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 19746+{
4a4d8108 19747+ int rerr;
523b37e3 19748+ struct inode *delegated;
dece6358 19749+
b4510431
AM
19750+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
19751+ a->dst_h_parent);
4a4d8108
AM
19752+ rerr = PTR_ERR(a->h_path.dentry);
19753+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 19754+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
19755+ return;
19756+ }
19757+ if (a->h_path.dentry->d_inode) {
19758+ d_drop(a->h_path.dentry);
19759+ dput(a->h_path.dentry);
19760+ return;
dece6358
AM
19761+ }
19762+
523b37e3
AM
19763+ delegated = NULL;
19764+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
19765+ &delegated);
19766+ if (unlikely(rerr == -EWOULDBLOCK)) {
19767+ pr_warn("cannot retry for NFSv4 delegation"
19768+ " for an internal rename\n");
19769+ iput(delegated);
19770+ }
4a4d8108
AM
19771+ d_drop(a->h_path.dentry);
19772+ dput(a->h_path.dentry);
19773+ if (!rerr)
19774+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
19775+ else
523b37e3 19776+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 19777+}
1308ab2a 19778+
4a4d8108
AM
19779+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
19780+{
19781+ int rerr;
1308ab2a 19782+
4a4d8108
AM
19783+ a->h_path.dentry = a->src_wh_dentry;
19784+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 19785+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 19786+ if (rerr)
523b37e3 19787+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 19788+}
4a4d8108 19789+#undef RevertFailure
1facf9fc 19790+
1308ab2a 19791+/* ---------------------------------------------------------------------- */
19792+
4a4d8108
AM
19793+/*
19794+ * when we have to copyup the renaming entry, do it with the rename-target name
19795+ * in order to minimize the cost (the later actual rename is unnecessary).
19796+ * otherwise rename it on the target branch.
19797+ */
19798+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 19799+{
dece6358 19800+ int err;
4a4d8108 19801+ struct dentry *d;
523b37e3 19802+ struct inode *delegated;
1facf9fc 19803+
4a4d8108
AM
19804+ d = a->src_dentry;
19805+ if (au_dbstart(d) == a->btgt) {
19806+ a->h_path.dentry = a->dst_h_dentry;
19807+ if (au_ftest_ren(a->flags, DIROPQ)
19808+ && au_dbdiropq(d) == a->btgt)
19809+ au_fclr_ren(a->flags, DIROPQ);
19810+ AuDebugOn(au_dbstart(d) != a->btgt);
523b37e3 19811+ delegated = NULL;
4a4d8108 19812+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
523b37e3
AM
19813+ a->dst_h_dir, &a->h_path, &delegated);
19814+ if (unlikely(err == -EWOULDBLOCK)) {
19815+ pr_warn("cannot retry for NFSv4 delegation"
19816+ " for an internal rename\n");
19817+ iput(delegated);
19818+ }
c2b27bf2 19819+ } else
86dc4139 19820+ BUG();
1308ab2a 19821+
027c5e7a
AM
19822+ if (!err && a->h_dst)
19823+ /* it will be set to dinfo later */
19824+ dget(a->h_dst);
1facf9fc 19825+
dece6358
AM
19826+ return err;
19827+}
1facf9fc 19828+
4a4d8108
AM
19829+/* cf. aufs_rmdir() */
19830+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 19831+{
4a4d8108
AM
19832+ int err;
19833+ struct inode *dir;
1facf9fc 19834+
4a4d8108
AM
19835+ dir = a->dst_dir;
19836+ SiMustAnyLock(dir->i_sb);
19837+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
19838+ au_sbi(dir->i_sb)->si_dirwh)
19839+ || au_test_fs_remote(a->h_dst->d_sb)) {
19840+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
19841+ if (unlikely(err))
523b37e3
AM
19842+ pr_warn("failed removing whtmp dir %pd (%d), "
19843+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
19844+ } else {
19845+ au_nhash_wh_free(&a->thargs->whlist);
19846+ a->thargs->whlist = a->whlist;
19847+ a->whlist.nh_num = 0;
19848+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
19849+ dput(a->h_dst);
19850+ a->thargs = NULL;
19851+ }
19852+
19853+ return 0;
1308ab2a 19854+}
1facf9fc 19855+
4a4d8108
AM
19856+/* make it 'opaque' dir. */
19857+static int au_ren_diropq(struct au_ren_args *a)
19858+{
19859+ int err;
19860+ struct dentry *diropq;
1facf9fc 19861+
4a4d8108 19862+ err = 0;
027c5e7a 19863+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
19864+ a->src_hinode = au_hi(a->src_inode, a->btgt);
19865+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
19866+ diropq = au_diropq_create(a->src_dentry, a->btgt);
19867+ au_hn_imtx_unlock(a->src_hinode);
19868+ if (IS_ERR(diropq))
19869+ err = PTR_ERR(diropq);
076b876e
AM
19870+ else
19871+ dput(diropq);
1facf9fc 19872+
4a4d8108
AM
19873+ return err;
19874+}
1facf9fc 19875+
4a4d8108
AM
19876+static int do_rename(struct au_ren_args *a)
19877+{
19878+ int err;
19879+ struct dentry *d, *h_d;
1facf9fc 19880+
4a4d8108
AM
19881+ /* prepare workqueue args for asynchronous rmdir */
19882+ h_d = a->dst_h_dentry;
19883+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
19884+ err = -ENOMEM;
19885+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
19886+ if (unlikely(!a->thargs))
19887+ goto out;
19888+ a->h_dst = dget(h_d);
19889+ }
1facf9fc 19890+
4a4d8108
AM
19891+ /* create whiteout for src_dentry */
19892+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
19893+ a->src_bwh = au_dbwh(a->src_dentry);
19894+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
19895+ a->src_wh_dentry
19896+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
19897+ err = PTR_ERR(a->src_wh_dentry);
19898+ if (IS_ERR(a->src_wh_dentry))
19899+ goto out_thargs;
19900+ }
1facf9fc 19901+
4a4d8108
AM
19902+ /* lookup whiteout for dentry */
19903+ if (au_ftest_ren(a->flags, WHDST)) {
19904+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
19905+ a->br);
19906+ err = PTR_ERR(h_d);
19907+ if (IS_ERR(h_d))
19908+ goto out_whsrc;
19909+ if (!h_d->d_inode)
19910+ dput(h_d);
19911+ else
19912+ a->dst_wh_dentry = h_d;
19913+ }
1facf9fc 19914+
4a4d8108
AM
19915+ /* rename dentry to tmpwh */
19916+ if (a->thargs) {
19917+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
19918+ if (unlikely(err))
19919+ goto out_whdst;
dece6358 19920+
4a4d8108
AM
19921+ d = a->dst_dentry;
19922+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 19923+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
19924+ if (unlikely(err))
19925+ goto out_whtmp;
19926+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
19927+ }
1facf9fc 19928+
c2b27bf2 19929+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
1facf9fc 19930+
4a4d8108
AM
19931+ /* rename by vfs_rename or cpup */
19932+ d = a->dst_dentry;
19933+ if (au_ftest_ren(a->flags, ISDIR)
19934+ && (a->dst_wh_dentry
19935+ || au_dbdiropq(d) == a->btgt
19936+ /* hide the lower to keep xino */
19937+ || a->btgt < au_dbend(d)
19938+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
19939+ au_fset_ren(a->flags, DIROPQ);
19940+ err = au_ren_or_cpup(a);
19941+ if (unlikely(err))
19942+ /* leave the copied-up one */
19943+ goto out_whtmp;
1308ab2a 19944+
4a4d8108
AM
19945+ /* make dir opaque */
19946+ if (au_ftest_ren(a->flags, DIROPQ)) {
19947+ err = au_ren_diropq(a);
19948+ if (unlikely(err))
19949+ goto out_rename;
19950+ }
1308ab2a 19951+
4a4d8108
AM
19952+ /* update target timestamps */
19953+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
19954+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
19955+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
19956+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
1facf9fc 19957+
4a4d8108
AM
19958+ /* remove whiteout for dentry */
19959+ if (a->dst_wh_dentry) {
19960+ a->h_path.dentry = a->dst_wh_dentry;
19961+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
19962+ a->dst_dentry);
19963+ if (unlikely(err))
19964+ goto out_diropq;
19965+ }
1facf9fc 19966+
4a4d8108
AM
19967+ /* remove whtmp */
19968+ if (a->thargs)
19969+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 19970+
076b876e 19971+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
4a4d8108
AM
19972+ err = 0;
19973+ goto out_success;
19974+
4f0767ce 19975+out_diropq:
4a4d8108
AM
19976+ if (au_ftest_ren(a->flags, DIROPQ))
19977+ au_ren_rev_diropq(err, a);
4f0767ce 19978+out_rename:
7e9cd9fe 19979+ au_ren_rev_rename(err, a);
027c5e7a 19980+ dput(a->h_dst);
4f0767ce 19981+out_whtmp:
4a4d8108
AM
19982+ if (a->thargs)
19983+ au_ren_rev_whtmp(err, a);
4f0767ce 19984+out_whdst:
4a4d8108
AM
19985+ dput(a->dst_wh_dentry);
19986+ a->dst_wh_dentry = NULL;
4f0767ce 19987+out_whsrc:
4a4d8108
AM
19988+ if (a->src_wh_dentry)
19989+ au_ren_rev_whsrc(err, a);
4f0767ce 19990+out_success:
4a4d8108
AM
19991+ dput(a->src_wh_dentry);
19992+ dput(a->dst_wh_dentry);
4f0767ce 19993+out_thargs:
4a4d8108
AM
19994+ if (a->thargs) {
19995+ dput(a->h_dst);
19996+ au_whtmp_rmdir_free(a->thargs);
19997+ a->thargs = NULL;
19998+ }
4f0767ce 19999+out:
4a4d8108 20000+ return err;
dece6358 20001+}
1facf9fc 20002+
1308ab2a 20003+/* ---------------------------------------------------------------------- */
1facf9fc 20004+
4a4d8108
AM
20005+/*
20006+ * test if @dentry dir can be rename destination or not.
20007+ * success means, it is a logically empty dir.
20008+ */
20009+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 20010+{
4a4d8108 20011+ return au_test_empty(dentry, whlist);
1308ab2a 20012+}
1facf9fc 20013+
4a4d8108
AM
20014+/*
20015+ * test if @dentry dir can be rename source or not.
20016+ * if it can, return 0 and @children is filled.
20017+ * success means,
20018+ * - it is a logically empty dir.
20019+ * - or, it exists on writable branch and has no children including whiteouts
20020+ * on the lower branch.
20021+ */
20022+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
20023+{
20024+ int err;
20025+ unsigned int rdhash;
20026+ aufs_bindex_t bstart;
1facf9fc 20027+
4a4d8108
AM
20028+ bstart = au_dbstart(dentry);
20029+ if (bstart != btgt) {
20030+ struct au_nhash whlist;
dece6358 20031+
4a4d8108
AM
20032+ SiMustAnyLock(dentry->d_sb);
20033+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
20034+ if (!rdhash)
20035+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
20036+ dentry));
20037+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
20038+ if (unlikely(err))
20039+ goto out;
20040+ err = au_test_empty(dentry, &whlist);
20041+ au_nhash_wh_free(&whlist);
20042+ goto out;
20043+ }
dece6358 20044+
4a4d8108
AM
20045+ if (bstart == au_dbtaildir(dentry))
20046+ return 0; /* success */
dece6358 20047+
4a4d8108 20048+ err = au_test_empty_lower(dentry);
1facf9fc 20049+
4f0767ce 20050+out:
4a4d8108
AM
20051+ if (err == -ENOTEMPTY) {
20052+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
20053+ " is not supported\n");
20054+ err = -EXDEV;
20055+ }
20056+ return err;
20057+}
1308ab2a 20058+
4a4d8108
AM
20059+/* side effect: sets whlist and h_dentry */
20060+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 20061+{
4a4d8108
AM
20062+ int err;
20063+ unsigned int rdhash;
20064+ struct dentry *d;
1facf9fc 20065+
4a4d8108
AM
20066+ d = a->dst_dentry;
20067+ SiMustAnyLock(d->d_sb);
1facf9fc 20068+
4a4d8108
AM
20069+ err = 0;
20070+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
20071+ rdhash = au_sbi(d->d_sb)->si_rdhash;
20072+ if (!rdhash)
20073+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
20074+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
20075+ if (unlikely(err))
20076+ goto out;
1308ab2a 20077+
4a4d8108
AM
20078+ au_set_dbstart(d, a->dst_bstart);
20079+ err = may_rename_dstdir(d, &a->whlist);
20080+ au_set_dbstart(d, a->btgt);
20081+ }
20082+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
20083+ if (unlikely(err))
20084+ goto out;
20085+
20086+ d = a->src_dentry;
20087+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
20088+ if (au_ftest_ren(a->flags, ISDIR)) {
20089+ err = may_rename_srcdir(d, a->btgt);
20090+ if (unlikely(err)) {
20091+ au_nhash_wh_free(&a->whlist);
20092+ a->whlist.nh_num = 0;
20093+ }
20094+ }
4f0767ce 20095+out:
4a4d8108 20096+ return err;
1facf9fc 20097+}
20098+
4a4d8108 20099+/* ---------------------------------------------------------------------- */
1facf9fc 20100+
4a4d8108
AM
20101+/*
20102+ * simple tests for rename.
20103+ * following the checks in vfs, plus the parent-child relationship.
20104+ */
20105+static int au_may_ren(struct au_ren_args *a)
20106+{
20107+ int err, isdir;
20108+ struct inode *h_inode;
1facf9fc 20109+
4a4d8108
AM
20110+ if (a->src_bstart == a->btgt) {
20111+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
20112+ au_ftest_ren(a->flags, ISDIR));
20113+ if (unlikely(err))
20114+ goto out;
20115+ err = -EINVAL;
20116+ if (unlikely(a->src_h_dentry == a->h_trap))
20117+ goto out;
20118+ }
1facf9fc 20119+
4a4d8108
AM
20120+ err = 0;
20121+ if (a->dst_bstart != a->btgt)
20122+ goto out;
1facf9fc 20123+
027c5e7a
AM
20124+ err = -ENOTEMPTY;
20125+ if (unlikely(a->dst_h_dentry == a->h_trap))
20126+ goto out;
20127+
4a4d8108
AM
20128+ err = -EIO;
20129+ h_inode = a->dst_h_dentry->d_inode;
20130+ isdir = !!au_ftest_ren(a->flags, ISDIR);
20131+ if (!a->dst_dentry->d_inode) {
20132+ if (unlikely(h_inode))
20133+ goto out;
20134+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
20135+ isdir);
20136+ } else {
20137+ if (unlikely(!h_inode || !h_inode->i_nlink))
20138+ goto out;
20139+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
20140+ isdir);
20141+ if (unlikely(err))
20142+ goto out;
4a4d8108 20143+ }
1facf9fc 20144+
4f0767ce 20145+out:
4a4d8108
AM
20146+ if (unlikely(err == -ENOENT || err == -EEXIST))
20147+ err = -EIO;
20148+ AuTraceErr(err);
20149+ return err;
20150+}
1facf9fc 20151+
1308ab2a 20152+/* ---------------------------------------------------------------------- */
1facf9fc 20153+
4a4d8108
AM
20154+/*
20155+ * locking order
20156+ * (VFS)
20157+ * - src_dir and dir by lock_rename()
20158+ * - inode if exitsts
20159+ * (aufs)
20160+ * - lock all
20161+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
20162+ * + si_read_lock
20163+ * + di_write_lock2_child()
20164+ * + di_write_lock_child()
20165+ * + ii_write_lock_child()
20166+ * + di_write_lock_child2()
20167+ * + ii_write_lock_child2()
20168+ * + src_parent and parent
20169+ * + di_write_lock_parent()
20170+ * + ii_write_lock_parent()
20171+ * + di_write_lock_parent2()
20172+ * + ii_write_lock_parent2()
20173+ * + lower src_dir and dir by vfsub_lock_rename()
20174+ * + verify the every relationships between child and parent. if any
20175+ * of them failed, unlock all and return -EBUSY.
20176+ */
20177+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 20178+{
4a4d8108
AM
20179+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
20180+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
20181+ if (au_ftest_ren(a->flags, MNT_WRITE))
20182+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 20183+}
20184+
4a4d8108 20185+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 20186+{
4a4d8108
AM
20187+ int err;
20188+ unsigned int udba;
1308ab2a 20189+
4a4d8108
AM
20190+ err = 0;
20191+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
20192+ a->src_hdir = au_hi(a->src_dir, a->btgt);
20193+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
20194+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
20195+
20196+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
20197+ if (unlikely(err))
20198+ goto out;
20199+ au_fset_ren(a->flags, MNT_WRITE);
4a4d8108
AM
20200+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
20201+ a->dst_h_parent, a->dst_hdir);
20202+ udba = au_opt_udba(a->src_dentry->d_sb);
20203+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
20204+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
20205+ err = au_busy_or_stale();
20206+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
20207+ err = au_h_verify(a->src_h_dentry, udba,
20208+ a->src_h_parent->d_inode, a->src_h_parent,
20209+ a->br);
20210+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
20211+ err = au_h_verify(a->dst_h_dentry, udba,
20212+ a->dst_h_parent->d_inode, a->dst_h_parent,
20213+ a->br);
86dc4139 20214+ if (!err)
4a4d8108 20215+ goto out; /* success */
4a4d8108
AM
20216+
20217+ err = au_busy_or_stale();
4a4d8108 20218+ au_ren_unlock(a);
86dc4139 20219+
4f0767ce 20220+out:
4a4d8108 20221+ return err;
1facf9fc 20222+}
20223+
20224+/* ---------------------------------------------------------------------- */
20225+
4a4d8108 20226+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 20227+{
4a4d8108 20228+ struct inode *dir;
dece6358 20229+
4a4d8108
AM
20230+ dir = a->dst_dir;
20231+ dir->i_version++;
20232+ if (au_ftest_ren(a->flags, ISDIR)) {
20233+ /* is this updating defined in POSIX? */
20234+ au_cpup_attr_timesizes(a->src_inode);
20235+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 20236+ }
027c5e7a 20237+
4a4d8108
AM
20238+ if (au_ibstart(dir) == a->btgt)
20239+ au_cpup_attr_timesizes(dir);
dece6358 20240+
4a4d8108
AM
20241+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20242+ return;
dece6358 20243+
4a4d8108
AM
20244+ dir = a->src_dir;
20245+ dir->i_version++;
20246+ if (au_ftest_ren(a->flags, ISDIR))
20247+ au_cpup_attr_nlink(dir, /*force*/1);
20248+ if (au_ibstart(dir) == a->btgt)
20249+ au_cpup_attr_timesizes(dir);
1facf9fc 20250+}
20251+
4a4d8108 20252+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 20253+{
4a4d8108
AM
20254+ aufs_bindex_t bend, bindex;
20255+ struct dentry *d, *h_d;
20256+ struct inode *i, *h_i;
20257+ struct super_block *sb;
dece6358 20258+
027c5e7a
AM
20259+ d = a->dst_dentry;
20260+ d_drop(d);
20261+ if (a->h_dst)
20262+ /* already dget-ed by au_ren_or_cpup() */
20263+ au_set_h_dptr(d, a->btgt, a->h_dst);
20264+
20265+ i = a->dst_inode;
20266+ if (i) {
20267+ if (!au_ftest_ren(a->flags, ISDIR))
20268+ vfsub_drop_nlink(i);
20269+ else {
20270+ vfsub_dead_dir(i);
20271+ au_cpup_attr_timesizes(i);
20272+ }
20273+ au_update_dbrange(d, /*do_put_zero*/1);
20274+ } else {
20275+ bend = a->btgt;
20276+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
20277+ au_set_h_dptr(d, bindex, NULL);
20278+ bend = au_dbend(d);
20279+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
20280+ au_set_h_dptr(d, bindex, NULL);
20281+ au_update_dbrange(d, /*do_put_zero*/0);
20282+ }
20283+
4a4d8108
AM
20284+ d = a->src_dentry;
20285+ au_set_dbwh(d, -1);
20286+ bend = au_dbend(d);
20287+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20288+ h_d = au_h_dptr(d, bindex);
20289+ if (h_d)
20290+ au_set_h_dptr(d, bindex, NULL);
20291+ }
20292+ au_set_dbend(d, a->btgt);
20293+
20294+ sb = d->d_sb;
20295+ i = a->src_inode;
20296+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
20297+ return; /* success */
20298+
20299+ bend = au_ibend(i);
20300+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20301+ h_i = au_h_iptr(i, bindex);
20302+ if (h_i) {
20303+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
20304+ /* ignore this error */
20305+ au_set_h_iptr(i, bindex, NULL, 0);
20306+ }
20307+ }
20308+ au_set_ibend(i, a->btgt);
1308ab2a 20309+}
dece6358 20310+
4a4d8108
AM
20311+/* ---------------------------------------------------------------------- */
20312+
20313+/* mainly for link(2) and rename(2) */
20314+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 20315+{
4a4d8108
AM
20316+ aufs_bindex_t bdiropq, bwh;
20317+ struct dentry *parent;
20318+ struct au_branch *br;
20319+
20320+ parent = dentry->d_parent;
20321+ IMustLock(parent->d_inode); /* dir is locked */
20322+
20323+ bdiropq = au_dbdiropq(parent);
20324+ bwh = au_dbwh(dentry);
20325+ br = au_sbr(dentry->d_sb, btgt);
20326+ if (au_br_rdonly(br)
20327+ || (0 <= bdiropq && bdiropq < btgt)
20328+ || (0 <= bwh && bwh < btgt))
20329+ btgt = -1;
20330+
20331+ AuDbg("btgt %d\n", btgt);
20332+ return btgt;
1facf9fc 20333+}
20334+
4a4d8108
AM
20335+/* sets src_bstart, dst_bstart and btgt */
20336+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 20337+{
4a4d8108
AM
20338+ int err;
20339+ struct au_wr_dir_args wr_dir_args = {
20340+ /* .force_btgt = -1, */
20341+ .flags = AuWrDir_ADD_ENTRY
20342+ };
dece6358 20343+
4a4d8108
AM
20344+ a->src_bstart = au_dbstart(a->src_dentry);
20345+ a->dst_bstart = au_dbstart(a->dst_dentry);
20346+ if (au_ftest_ren(a->flags, ISDIR))
20347+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
20348+ wr_dir_args.force_btgt = a->src_bstart;
20349+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
20350+ wr_dir_args.force_btgt = a->dst_bstart;
20351+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
20352+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
20353+ a->btgt = err;
dece6358 20354+
4a4d8108 20355+ return err;
1facf9fc 20356+}
20357+
4a4d8108 20358+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 20359+{
4a4d8108
AM
20360+ a->h_path.dentry = a->src_h_parent;
20361+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
20362+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
20363+ a->h_path.dentry = a->dst_h_parent;
20364+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
20365+ }
1facf9fc 20366+
4a4d8108
AM
20367+ au_fclr_ren(a->flags, DT_DSTDIR);
20368+ if (!au_ftest_ren(a->flags, ISDIR))
20369+ return;
dece6358 20370+
4a4d8108
AM
20371+ a->h_path.dentry = a->src_h_dentry;
20372+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
20373+ if (a->dst_h_dentry->d_inode) {
20374+ au_fset_ren(a->flags, DT_DSTDIR);
20375+ a->h_path.dentry = a->dst_h_dentry;
20376+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
20377+ }
1308ab2a 20378+}
dece6358 20379+
4a4d8108 20380+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 20381+{
4a4d8108
AM
20382+ struct dentry *h_d;
20383+ struct mutex *h_mtx;
20384+
20385+ au_dtime_revert(a->src_dt + AuPARENT);
20386+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
20387+ au_dtime_revert(a->dst_dt + AuPARENT);
20388+
20389+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
20390+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
20391+ h_mtx = &h_d->d_inode->i_mutex;
20392+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20393+ au_dtime_revert(a->src_dt + AuCHILD);
20394+ mutex_unlock(h_mtx);
20395+
20396+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
20397+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
20398+ h_mtx = &h_d->d_inode->i_mutex;
20399+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20400+ au_dtime_revert(a->dst_dt + AuCHILD);
20401+ mutex_unlock(h_mtx);
1facf9fc 20402+ }
20403+ }
20404+}
20405+
4a4d8108
AM
20406+/* ---------------------------------------------------------------------- */
20407+
20408+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
20409+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 20410+{
e49829fe 20411+ int err, flags;
4a4d8108
AM
20412+ /* reduce stack space */
20413+ struct au_ren_args *a;
20414+
523b37e3 20415+ AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry);
4a4d8108
AM
20416+ IMustLock(_src_dir);
20417+ IMustLock(_dst_dir);
20418+
20419+ err = -ENOMEM;
20420+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
20421+ a = kzalloc(sizeof(*a), GFP_NOFS);
20422+ if (unlikely(!a))
20423+ goto out;
20424+
20425+ a->src_dir = _src_dir;
20426+ a->src_dentry = _src_dentry;
20427+ a->src_inode = a->src_dentry->d_inode;
20428+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
20429+ a->dst_dir = _dst_dir;
20430+ a->dst_dentry = _dst_dentry;
20431+ a->dst_inode = a->dst_dentry->d_inode;
20432+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
20433+ if (a->dst_inode) {
20434+ IMustLock(a->dst_inode);
20435+ au_igrab(a->dst_inode);
1facf9fc 20436+ }
1facf9fc 20437+
4a4d8108 20438+ err = -ENOTDIR;
027c5e7a 20439+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
2000de60 20440+ if (d_is_dir(a->src_dentry)) {
4a4d8108 20441+ au_fset_ren(a->flags, ISDIR);
2000de60
JR
20442+ if (unlikely(d_is_positive(a->dst_dentry)
20443+ && !d_is_dir(a->dst_dentry)))
4a4d8108 20444+ goto out_free;
e49829fe
JR
20445+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20446+ AuLock_DIR | flags);
4a4d8108 20447+ } else
e49829fe
JR
20448+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20449+ flags);
20450+ if (unlikely(err))
20451+ goto out_free;
1facf9fc 20452+
027c5e7a
AM
20453+ err = au_d_hashed_positive(a->src_dentry);
20454+ if (unlikely(err))
20455+ goto out_unlock;
20456+ err = -ENOENT;
20457+ if (a->dst_inode) {
20458+ /*
20459+ * If it is a dir, VFS unhash dst_dentry before this
20460+ * function. It means we cannot rely upon d_unhashed().
20461+ */
20462+ if (unlikely(!a->dst_inode->i_nlink))
20463+ goto out_unlock;
20464+ if (!S_ISDIR(a->dst_inode->i_mode)) {
20465+ err = au_d_hashed_positive(a->dst_dentry);
20466+ if (unlikely(err))
20467+ goto out_unlock;
20468+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
20469+ goto out_unlock;
20470+ } else if (unlikely(d_unhashed(a->dst_dentry)))
20471+ goto out_unlock;
20472+
7eafdf33
AM
20473+ /*
20474+ * is it possible?
20475+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
20476+ * there may exist a problem somewhere else.
20477+ */
20478+ err = -EINVAL;
20479+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
20480+ goto out_unlock;
20481+
4a4d8108
AM
20482+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
20483+ di_write_lock_parent(a->dst_parent);
1facf9fc 20484+
4a4d8108
AM
20485+ /* which branch we process */
20486+ err = au_ren_wbr(a);
20487+ if (unlikely(err < 0))
027c5e7a 20488+ goto out_parent;
4a4d8108 20489+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 20490+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 20491+
4a4d8108
AM
20492+ /* are they available to be renamed */
20493+ err = au_ren_may_dir(a);
20494+ if (unlikely(err))
20495+ goto out_children;
1facf9fc 20496+
4a4d8108
AM
20497+ /* prepare the writable parent dir on the same branch */
20498+ if (a->dst_bstart == a->btgt) {
20499+ au_fset_ren(a->flags, WHDST);
20500+ } else {
20501+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
20502+ if (unlikely(err))
20503+ goto out_children;
20504+ }
1facf9fc 20505+
4a4d8108
AM
20506+ if (a->src_dir != a->dst_dir) {
20507+ /*
20508+ * this temporary unlock is safe,
20509+ * because both dir->i_mutex are locked.
20510+ */
20511+ di_write_unlock(a->dst_parent);
20512+ di_write_lock_parent(a->src_parent);
20513+ err = au_wr_dir_need_wh(a->src_dentry,
20514+ au_ftest_ren(a->flags, ISDIR),
20515+ &a->btgt);
20516+ di_write_unlock(a->src_parent);
20517+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
20518+ au_fclr_ren(a->flags, ISSAMEDIR);
20519+ } else
20520+ err = au_wr_dir_need_wh(a->src_dentry,
20521+ au_ftest_ren(a->flags, ISDIR),
20522+ &a->btgt);
20523+ if (unlikely(err < 0))
20524+ goto out_children;
20525+ if (err)
20526+ au_fset_ren(a->flags, WHSRC);
1facf9fc 20527+
86dc4139
AM
20528+ /* cpup src */
20529+ if (a->src_bstart != a->btgt) {
86dc4139
AM
20530+ struct au_pin pin;
20531+
20532+ err = au_pin(&pin, a->src_dentry, a->btgt,
20533+ au_opt_udba(a->src_dentry->d_sb),
20534+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 20535+ if (!err) {
c2b27bf2
AM
20536+ struct au_cp_generic cpg = {
20537+ .dentry = a->src_dentry,
20538+ .bdst = a->btgt,
20539+ .bsrc = a->src_bstart,
20540+ .len = -1,
20541+ .pin = &pin,
20542+ .flags = AuCpup_DTIME | AuCpup_HOPEN
20543+ };
367653fa 20544+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
c2b27bf2 20545+ err = au_sio_cpup_simple(&cpg);
367653fa 20546+ au_unpin(&pin);
86dc4139 20547+ }
86dc4139
AM
20548+ if (unlikely(err))
20549+ goto out_children;
20550+ a->src_bstart = a->btgt;
20551+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
20552+ au_fset_ren(a->flags, WHSRC);
20553+ }
20554+
4a4d8108
AM
20555+ /* lock them all */
20556+ err = au_ren_lock(a);
20557+ if (unlikely(err))
86dc4139 20558+ /* leave the copied-up one */
4a4d8108 20559+ goto out_children;
1facf9fc 20560+
4a4d8108
AM
20561+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
20562+ err = au_may_ren(a);
20563+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
20564+ err = -ENAMETOOLONG;
20565+ if (unlikely(err))
20566+ goto out_hdir;
1facf9fc 20567+
4a4d8108
AM
20568+ /* store timestamps to be revertible */
20569+ au_ren_dt(a);
1facf9fc 20570+
4a4d8108
AM
20571+ /* here we go */
20572+ err = do_rename(a);
20573+ if (unlikely(err))
20574+ goto out_dt;
20575+
20576+ /* update dir attributes */
20577+ au_ren_refresh_dir(a);
20578+
20579+ /* dput/iput all lower dentries */
20580+ au_ren_refresh(a);
20581+
20582+ goto out_hdir; /* success */
20583+
4f0767ce 20584+out_dt:
4a4d8108 20585+ au_ren_rev_dt(err, a);
4f0767ce 20586+out_hdir:
4a4d8108 20587+ au_ren_unlock(a);
4f0767ce 20588+out_children:
4a4d8108 20589+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
20590+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
20591+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
20592+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
20593+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 20594+ }
027c5e7a 20595+out_parent:
4a4d8108
AM
20596+ if (!err)
20597+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
20598+ else {
20599+ au_update_dbstart(a->dst_dentry);
20600+ if (!a->dst_inode)
20601+ d_drop(a->dst_dentry);
20602+ }
4a4d8108
AM
20603+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20604+ di_write_unlock(a->dst_parent);
20605+ else
20606+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 20607+out_unlock:
4a4d8108 20608+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 20609+out_free:
4a4d8108
AM
20610+ iput(a->dst_inode);
20611+ if (a->thargs)
20612+ au_whtmp_rmdir_free(a->thargs);
20613+ kfree(a);
4f0767ce 20614+out:
4a4d8108
AM
20615+ AuTraceErr(err);
20616+ return err;
1308ab2a 20617+}
7f207e10
AM
20618diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
20619--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 20620+++ linux/fs/aufs/Kconfig 2015-04-13 15:10:20.776823376 +0200
c1595e42 20621@@ -0,0 +1,185 @@
4a4d8108
AM
20622+config AUFS_FS
20623+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
20624+ help
20625+ Aufs is a stackable unification filesystem such as Unionfs,
20626+ which unifies several directories and provides a merged single
20627+ directory.
20628+ In the early days, aufs was entirely re-designed and
20629+ re-implemented Unionfs Version 1.x series. Introducing many
20630+ original ideas, approaches and improvements, it becomes totally
20631+ different from Unionfs while keeping the basic features.
1facf9fc 20632+
4a4d8108
AM
20633+if AUFS_FS
20634+choice
20635+ prompt "Maximum number of branches"
20636+ default AUFS_BRANCH_MAX_127
20637+ help
20638+ Specifies the maximum number of branches (or member directories)
20639+ in a single aufs. The larger value consumes more system
20640+ resources and has a minor impact to performance.
20641+config AUFS_BRANCH_MAX_127
20642+ bool "127"
20643+ help
20644+ Specifies the maximum number of branches (or member directories)
20645+ in a single aufs. The larger value consumes more system
20646+ resources and has a minor impact to performance.
20647+config AUFS_BRANCH_MAX_511
20648+ bool "511"
20649+ help
20650+ Specifies the maximum number of branches (or member directories)
20651+ in a single aufs. The larger value consumes more system
20652+ resources and has a minor impact to performance.
20653+config AUFS_BRANCH_MAX_1023
20654+ bool "1023"
20655+ help
20656+ Specifies the maximum number of branches (or member directories)
20657+ in a single aufs. The larger value consumes more system
20658+ resources and has a minor impact to performance.
20659+config AUFS_BRANCH_MAX_32767
20660+ bool "32767"
20661+ help
20662+ Specifies the maximum number of branches (or member directories)
20663+ in a single aufs. The larger value consumes more system
20664+ resources and has a minor impact to performance.
20665+endchoice
1facf9fc 20666+
e49829fe
JR
20667+config AUFS_SBILIST
20668+ bool
20669+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
20670+ default y
20671+ help
20672+ Automatic configuration for internal use.
20673+ When aufs supports Magic SysRq or /proc, enabled automatically.
20674+
4a4d8108
AM
20675+config AUFS_HNOTIFY
20676+ bool "Detect direct branch access (bypassing aufs)"
20677+ help
20678+ If you want to modify files on branches directly, eg. bypassing aufs,
20679+ and want aufs to detect the changes of them fully, then enable this
20680+ option and use 'udba=notify' mount option.
7f207e10 20681+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
20682+ It will have a negative impact to the performance.
20683+ See detail in aufs.5.
dece6358 20684+
4a4d8108
AM
20685+choice
20686+ prompt "method" if AUFS_HNOTIFY
20687+ default AUFS_HFSNOTIFY
20688+config AUFS_HFSNOTIFY
20689+ bool "fsnotify"
20690+ select FSNOTIFY
4a4d8108 20691+endchoice
1facf9fc 20692+
4a4d8108
AM
20693+config AUFS_EXPORT
20694+ bool "NFS-exportable aufs"
2cbb1c4b 20695+ depends on EXPORTFS
4a4d8108
AM
20696+ help
20697+ If you want to export your mounted aufs via NFS, then enable this
20698+ option. There are several requirements for this configuration.
20699+ See detail in aufs.5.
1facf9fc 20700+
4a4d8108
AM
20701+config AUFS_INO_T_64
20702+ bool
20703+ depends on AUFS_EXPORT
20704+ depends on 64BIT && !(ALPHA || S390)
20705+ default y
20706+ help
20707+ Automatic configuration for internal use.
20708+ /* typedef unsigned long/int __kernel_ino_t */
20709+ /* alpha and s390x are int */
1facf9fc 20710+
c1595e42
JR
20711+config AUFS_XATTR
20712+ bool "support for XATTR/EA (including Security Labels)"
20713+ help
20714+ If your branch fs supports XATTR/EA and you want to make them
20715+ available in aufs too, then enable this opsion and specify the
20716+ branch attributes for EA.
20717+ See detail in aufs.5.
20718+
076b876e
AM
20719+config AUFS_FHSM
20720+ bool "File-based Hierarchical Storage Management"
20721+ help
20722+ Hierarchical Storage Management (or HSM) is a well-known feature
20723+ in the storage world. Aufs provides this feature as file-based.
20724+ with multiple branches.
20725+ These multiple branches are prioritized, ie. the topmost one
20726+ should be the fastest drive and be used heavily.
20727+
4a4d8108
AM
20728+config AUFS_RDU
20729+ bool "Readdir in userspace"
20730+ help
20731+ Aufs has two methods to provide a merged view for a directory,
20732+ by a user-space library and by kernel-space natively. The latter
20733+ is always enabled but sometimes large and slow.
20734+ If you enable this option, install the library in aufs2-util
20735+ package, and set some environment variables for your readdir(3),
20736+ then the work will be handled in user-space which generally
20737+ shows better performance in most cases.
20738+ See detail in aufs.5.
1facf9fc 20739+
4a4d8108
AM
20740+config AUFS_SHWH
20741+ bool "Show whiteouts"
20742+ help
20743+ If you want to make the whiteouts in aufs visible, then enable
20744+ this option and specify 'shwh' mount option. Although it may
20745+ sounds like philosophy or something, but in technically it
20746+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 20747+
4a4d8108
AM
20748+config AUFS_BR_RAMFS
20749+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
20750+ help
20751+ If you want to use ramfs as an aufs branch fs, then enable this
20752+ option. Generally tmpfs is recommended.
20753+ Aufs prohibited them to be a branch fs by default, because
20754+ initramfs becomes unusable after switch_root or something
20755+ generally. If you sets initramfs as an aufs branch and boot your
20756+ system by switch_root, you will meet a problem easily since the
20757+ files in initramfs may be inaccessible.
20758+ Unless you are going to use ramfs as an aufs branch fs without
20759+ switch_root or something, leave it N.
1facf9fc 20760+
4a4d8108
AM
20761+config AUFS_BR_FUSE
20762+ bool "Fuse fs as an aufs branch"
20763+ depends on FUSE_FS
20764+ select AUFS_POLL
20765+ help
20766+ If you want to use fuse-based userspace filesystem as an aufs
20767+ branch fs, then enable this option.
20768+ It implements the internal poll(2) operation which is
20769+ implemented by fuse only (curretnly).
1facf9fc 20770+
4a4d8108
AM
20771+config AUFS_POLL
20772+ bool
20773+ help
20774+ Automatic configuration for internal use.
1facf9fc 20775+
4a4d8108
AM
20776+config AUFS_BR_HFSPLUS
20777+ bool "Hfsplus as an aufs branch"
20778+ depends on HFSPLUS_FS
20779+ default y
20780+ help
20781+ If you want to use hfsplus fs as an aufs branch fs, then enable
20782+ this option. This option introduces a small overhead at
20783+ copying-up a file on hfsplus.
1facf9fc 20784+
4a4d8108
AM
20785+config AUFS_BDEV_LOOP
20786+ bool
20787+ depends on BLK_DEV_LOOP
20788+ default y
20789+ help
20790+ Automatic configuration for internal use.
20791+ Convert =[ym] into =y.
1308ab2a 20792+
4a4d8108
AM
20793+config AUFS_DEBUG
20794+ bool "Debug aufs"
20795+ help
20796+ Enable this to compile aufs internal debug code.
20797+ It will have a negative impact to the performance.
20798+
20799+config AUFS_MAGIC_SYSRQ
20800+ bool
20801+ depends on AUFS_DEBUG && MAGIC_SYSRQ
20802+ default y
20803+ help
20804+ Automatic configuration for internal use.
20805+ When aufs supports Magic SysRq, enabled automatically.
20806+endif
7f207e10
AM
20807diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
20808--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 20809+++ linux/fs/aufs/loop.c 2015-04-13 15:10:20.786823613 +0200
523b37e3 20810@@ -0,0 +1,145 @@
1facf9fc 20811+/*
2000de60 20812+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 20813+ *
20814+ * This program, aufs is free software; you can redistribute it and/or modify
20815+ * it under the terms of the GNU General Public License as published by
20816+ * the Free Software Foundation; either version 2 of the License, or
20817+ * (at your option) any later version.
dece6358
AM
20818+ *
20819+ * This program is distributed in the hope that it will be useful,
20820+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20821+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20822+ * GNU General Public License for more details.
20823+ *
20824+ * You should have received a copy of the GNU General Public License
523b37e3 20825+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20826+ */
20827+
20828+/*
20829+ * support for loopback block device as a branch
20830+ */
20831+
1facf9fc 20832+#include "aufs.h"
20833+
392086de
AM
20834+/* added into drivers/block/loop.c */
20835+static struct file *(*backing_file_func)(struct super_block *sb);
20836+
1facf9fc 20837+/*
20838+ * test if two lower dentries have overlapping branches.
20839+ */
b752ccd1 20840+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 20841+{
b752ccd1 20842+ struct super_block *h_sb;
392086de
AM
20843+ struct file *backing_file;
20844+
20845+ if (unlikely(!backing_file_func)) {
20846+ /* don't load "loop" module here */
20847+ backing_file_func = symbol_get(loop_backing_file);
20848+ if (unlikely(!backing_file_func))
20849+ /* "loop" module is not loaded */
20850+ return 0;
20851+ }
1facf9fc 20852+
b752ccd1 20853+ h_sb = h_adding->d_sb;
392086de
AM
20854+ backing_file = backing_file_func(h_sb);
20855+ if (!backing_file)
1facf9fc 20856+ return 0;
20857+
2000de60 20858+ h_adding = backing_file->f_path.dentry;
b752ccd1
AM
20859+ /*
20860+ * h_adding can be local NFS.
20861+ * in this case aufs cannot detect the loop.
20862+ */
20863+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 20864+ return 1;
b752ccd1 20865+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 20866+}
20867+
20868+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
20869+int au_test_loopback_kthread(void)
20870+{
b752ccd1
AM
20871+ int ret;
20872+ struct task_struct *tsk = current;
a2a7ad62 20873+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
20874+
20875+ ret = 0;
20876+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
20877+ get_task_comm(comm, tsk);
20878+ c = comm[4];
b752ccd1 20879+ ret = ('0' <= c && c <= '9'
a2a7ad62 20880+ && !strncmp(comm, "loop", 4));
b752ccd1 20881+ }
1facf9fc 20882+
b752ccd1 20883+ return ret;
1facf9fc 20884+}
87a755f4
AM
20885+
20886+/* ---------------------------------------------------------------------- */
20887+
20888+#define au_warn_loopback_step 16
20889+static int au_warn_loopback_nelem = au_warn_loopback_step;
20890+static unsigned long *au_warn_loopback_array;
20891+
20892+void au_warn_loopback(struct super_block *h_sb)
20893+{
20894+ int i, new_nelem;
20895+ unsigned long *a, magic;
20896+ static DEFINE_SPINLOCK(spin);
20897+
20898+ magic = h_sb->s_magic;
20899+ spin_lock(&spin);
20900+ a = au_warn_loopback_array;
20901+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
20902+ if (a[i] == magic) {
20903+ spin_unlock(&spin);
20904+ return;
20905+ }
20906+
20907+ /* h_sb is new to us, print it */
20908+ if (i < au_warn_loopback_nelem) {
20909+ a[i] = magic;
20910+ goto pr;
20911+ }
20912+
20913+ /* expand the array */
20914+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
20915+ a = au_kzrealloc(au_warn_loopback_array,
20916+ au_warn_loopback_nelem * sizeof(unsigned long),
20917+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
20918+ if (a) {
20919+ au_warn_loopback_nelem = new_nelem;
20920+ au_warn_loopback_array = a;
20921+ a[i] = magic;
20922+ goto pr;
20923+ }
20924+
20925+ spin_unlock(&spin);
20926+ AuWarn1("realloc failed, ignored\n");
20927+ return;
20928+
20929+pr:
20930+ spin_unlock(&spin);
0c3ec466
AM
20931+ pr_warn("you may want to try another patch for loopback file "
20932+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
20933+}
20934+
20935+int au_loopback_init(void)
20936+{
20937+ int err;
20938+ struct super_block *sb __maybe_unused;
20939+
20940+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
20941+
20942+ err = 0;
20943+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
20944+ sizeof(unsigned long), GFP_NOFS);
20945+ if (unlikely(!au_warn_loopback_array))
20946+ err = -ENOMEM;
20947+
20948+ return err;
20949+}
20950+
20951+void au_loopback_fin(void)
20952+{
392086de 20953+ symbol_put(loop_backing_file);
87a755f4
AM
20954+ kfree(au_warn_loopback_array);
20955+}
7f207e10
AM
20956diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
20957--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 20958+++ linux/fs/aufs/loop.h 2015-04-13 15:10:20.786823613 +0200
523b37e3 20959@@ -0,0 +1,52 @@
1facf9fc 20960+/*
2000de60 20961+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 20962+ *
20963+ * This program, aufs is free software; you can redistribute it and/or modify
20964+ * it under the terms of the GNU General Public License as published by
20965+ * the Free Software Foundation; either version 2 of the License, or
20966+ * (at your option) any later version.
dece6358
AM
20967+ *
20968+ * This program is distributed in the hope that it will be useful,
20969+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20970+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20971+ * GNU General Public License for more details.
20972+ *
20973+ * You should have received a copy of the GNU General Public License
523b37e3 20974+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20975+ */
20976+
20977+/*
20978+ * support for loopback mount as a branch
20979+ */
20980+
20981+#ifndef __AUFS_LOOP_H__
20982+#define __AUFS_LOOP_H__
20983+
20984+#ifdef __KERNEL__
20985+
dece6358
AM
20986+struct dentry;
20987+struct super_block;
1facf9fc 20988+
20989+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
20990+/* drivers/block/loop.c */
20991+struct file *loop_backing_file(struct super_block *sb);
20992+
1facf9fc 20993+/* loop.c */
b752ccd1 20994+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 20995+int au_test_loopback_kthread(void);
87a755f4
AM
20996+void au_warn_loopback(struct super_block *h_sb);
20997+
20998+int au_loopback_init(void);
20999+void au_loopback_fin(void);
1facf9fc 21000+#else
4a4d8108 21001+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 21002+ struct dentry *h_adding)
4a4d8108 21003+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
21004+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
21005+
21006+AuStubInt0(au_loopback_init, void)
21007+AuStubVoid(au_loopback_fin, void)
1facf9fc 21008+#endif /* BLK_DEV_LOOP */
21009+
21010+#endif /* __KERNEL__ */
21011+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
21012diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
21013--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
21014+++ linux/fs/aufs/magic.mk 2015-04-13 15:10:20.786823613 +0200
21015@@ -0,0 +1,30 @@
1facf9fc 21016+
21017+# defined in ${srctree}/fs/fuse/inode.c
21018+# tristate
21019+ifdef CONFIG_FUSE_FS
21020+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
21021+endif
21022+
1facf9fc 21023+# defined in ${srctree}/fs/xfs/xfs_sb.h
21024+# tristate
21025+ifdef CONFIG_XFS_FS
21026+ccflags-y += -DXFS_SB_MAGIC=0x58465342
21027+endif
21028+
21029+# defined in ${srctree}/fs/configfs/mount.c
21030+# tristate
21031+ifdef CONFIG_CONFIGFS_FS
21032+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
21033+endif
21034+
1facf9fc 21035+# defined in ${srctree}/fs/ubifs/ubifs.h
21036+# tristate
21037+ifdef CONFIG_UBIFS_FS
21038+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
21039+endif
4a4d8108
AM
21040+
21041+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
21042+# tristate
21043+ifdef CONFIG_HFSPLUS_FS
21044+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
21045+endif
7f207e10
AM
21046diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
21047--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 21048+++ linux/fs/aufs/Makefile 2015-04-13 15:10:20.776823376 +0200
c1595e42 21049@@ -0,0 +1,44 @@
4a4d8108
AM
21050+
21051+include ${src}/magic.mk
21052+ifeq (${CONFIG_AUFS_FS},m)
21053+include ${src}/conf.mk
21054+endif
21055+-include ${src}/priv_def.mk
21056+
21057+# cf. include/linux/kernel.h
21058+# enable pr_debug
21059+ccflags-y += -DDEBUG
f6c5ef8b
AM
21060+# sparse requires the full pathname
21061+ifdef M
523b37e3 21062+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 21063+else
523b37e3 21064+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 21065+endif
4a4d8108
AM
21066+
21067+obj-$(CONFIG_AUFS_FS) += aufs.o
21068+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
21069+ wkq.o vfsub.o dcsub.o \
e49829fe 21070+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
21071+ dinfo.o dentry.o \
21072+ dynop.o \
21073+ finfo.o file.o f_op.o \
21074+ dir.o vdir.o \
21075+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 21076+ mvdown.o ioctl.o
4a4d8108
AM
21077+
21078+# all are boolean
e49829fe 21079+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
21080+aufs-$(CONFIG_SYSFS) += sysfs.o
21081+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
21082+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
21083+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
21084+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 21085+aufs-$(CONFIG_AUFS_EXPORT) += export.o
c1595e42
JR
21086+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
21087+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
076b876e 21088+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
21089+aufs-$(CONFIG_AUFS_POLL) += poll.o
21090+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
21091+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
21092+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
21093+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
21094diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
21095--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 21096+++ linux/fs/aufs/module.c 2015-04-13 15:10:20.786823613 +0200
076b876e 21097@@ -0,0 +1,210 @@
1facf9fc 21098+/*
2000de60 21099+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21100+ *
21101+ * This program, aufs is free software; you can redistribute it and/or modify
21102+ * it under the terms of the GNU General Public License as published by
21103+ * the Free Software Foundation; either version 2 of the License, or
21104+ * (at your option) any later version.
dece6358
AM
21105+ *
21106+ * This program is distributed in the hope that it will be useful,
21107+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21108+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21109+ * GNU General Public License for more details.
21110+ *
21111+ * You should have received a copy of the GNU General Public License
523b37e3 21112+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21113+ */
21114+
21115+/*
21116+ * module global variables and operations
21117+ */
21118+
21119+#include <linux/module.h>
21120+#include <linux/seq_file.h>
21121+#include "aufs.h"
21122+
21123+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
21124+{
21125+ if (new_sz <= nused)
21126+ return p;
21127+
21128+ p = krealloc(p, new_sz, gfp);
21129+ if (p)
21130+ memset(p + nused, 0, new_sz - nused);
21131+ return p;
21132+}
21133+
21134+/* ---------------------------------------------------------------------- */
21135+
21136+/*
21137+ * aufs caches
21138+ */
21139+struct kmem_cache *au_cachep[AuCache_Last];
21140+static int __init au_cache_init(void)
21141+{
4a4d8108 21142+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 21143+ if (au_cachep[AuCache_DINFO])
027c5e7a 21144+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
21145+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
21146+ au_icntnr_init_once);
1facf9fc 21147+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
21148+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
21149+ au_fi_init_once);
1facf9fc 21150+ if (au_cachep[AuCache_FINFO])
21151+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
21152+ if (au_cachep[AuCache_VDIR])
21153+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
21154+ if (au_cachep[AuCache_DEHSTR])
21155+ return 0;
21156+
21157+ return -ENOMEM;
21158+}
21159+
21160+static void au_cache_fin(void)
21161+{
21162+ int i;
4a4d8108 21163+
537831f9
AM
21164+ /*
21165+ * Make sure all delayed rcu free inodes are flushed before we
21166+ * destroy cache.
21167+ */
21168+ rcu_barrier();
21169+
7eafdf33
AM
21170+ /* excluding AuCache_HNOTIFY */
21171+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
21172+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 21173+ if (au_cachep[i]) {
21174+ kmem_cache_destroy(au_cachep[i]);
21175+ au_cachep[i] = NULL;
21176+ }
21177+}
21178+
21179+/* ---------------------------------------------------------------------- */
21180+
21181+int au_dir_roflags;
21182+
e49829fe 21183+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
21184+/*
21185+ * iterate_supers_type() doesn't protect us from
21186+ * remounting (branch management)
21187+ */
e49829fe
JR
21188+struct au_splhead au_sbilist;
21189+#endif
21190+
9dbd164d
AM
21191+struct lock_class_key au_lc_key[AuLcKey_Last];
21192+
1facf9fc 21193+/*
21194+ * functions for module interface.
21195+ */
21196+MODULE_LICENSE("GPL");
21197+/* MODULE_LICENSE("GPL v2"); */
dece6358 21198+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 21199+MODULE_DESCRIPTION(AUFS_NAME
21200+ " -- Advanced multi layered unification filesystem");
21201+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 21202+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 21203+
1facf9fc 21204+/* this module parameter has no meaning when SYSFS is disabled */
21205+int sysaufs_brs = 1;
21206+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
21207+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
21208+
076b876e
AM
21209+/* this module parameter has no meaning when USER_NS is disabled */
21210+static bool au_userns;
21211+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
21212+module_param_named(allow_userns, au_userns, bool, S_IRUGO);
21213+
1facf9fc 21214+/* ---------------------------------------------------------------------- */
21215+
21216+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
21217+
21218+int au_seq_path(struct seq_file *seq, struct path *path)
21219+{
21220+ return seq_path(seq, path, au_esc_chars);
21221+}
21222+
21223+/* ---------------------------------------------------------------------- */
21224+
21225+static int __init aufs_init(void)
21226+{
21227+ int err, i;
21228+ char *p;
21229+
21230+ p = au_esc_chars;
21231+ for (i = 1; i <= ' '; i++)
21232+ *p++ = i;
21233+ *p++ = '\\';
21234+ *p++ = '\x7f';
21235+ *p = 0;
21236+
21237+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
21238+
e49829fe 21239+ au_sbilist_init();
1facf9fc 21240+ sysaufs_brs_init();
21241+ au_debug_init();
4a4d8108 21242+ au_dy_init();
1facf9fc 21243+ err = sysaufs_init();
21244+ if (unlikely(err))
21245+ goto out;
e49829fe 21246+ err = au_procfs_init();
4f0767ce 21247+ if (unlikely(err))
953406b4 21248+ goto out_sysaufs;
e49829fe
JR
21249+ err = au_wkq_init();
21250+ if (unlikely(err))
21251+ goto out_procfs;
87a755f4 21252+ err = au_loopback_init();
1facf9fc 21253+ if (unlikely(err))
21254+ goto out_wkq;
87a755f4
AM
21255+ err = au_hnotify_init();
21256+ if (unlikely(err))
21257+ goto out_loopback;
1facf9fc 21258+ err = au_sysrq_init();
21259+ if (unlikely(err))
21260+ goto out_hin;
21261+ err = au_cache_init();
21262+ if (unlikely(err))
21263+ goto out_sysrq;
076b876e
AM
21264+
21265+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 21266+ err = register_filesystem(&aufs_fs_type);
21267+ if (unlikely(err))
21268+ goto out_cache;
076b876e 21269+
4a4d8108
AM
21270+ /* since we define pr_fmt, call printk directly */
21271+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 21272+ goto out; /* success */
21273+
4f0767ce 21274+out_cache:
1facf9fc 21275+ au_cache_fin();
4f0767ce 21276+out_sysrq:
1facf9fc 21277+ au_sysrq_fin();
4f0767ce 21278+out_hin:
4a4d8108 21279+ au_hnotify_fin();
87a755f4
AM
21280+out_loopback:
21281+ au_loopback_fin();
4f0767ce 21282+out_wkq:
1facf9fc 21283+ au_wkq_fin();
e49829fe
JR
21284+out_procfs:
21285+ au_procfs_fin();
4f0767ce 21286+out_sysaufs:
1facf9fc 21287+ sysaufs_fin();
4a4d8108 21288+ au_dy_fin();
4f0767ce 21289+out:
1facf9fc 21290+ return err;
21291+}
21292+
21293+static void __exit aufs_exit(void)
21294+{
21295+ unregister_filesystem(&aufs_fs_type);
21296+ au_cache_fin();
21297+ au_sysrq_fin();
4a4d8108 21298+ au_hnotify_fin();
87a755f4 21299+ au_loopback_fin();
1facf9fc 21300+ au_wkq_fin();
e49829fe 21301+ au_procfs_fin();
1facf9fc 21302+ sysaufs_fin();
4a4d8108 21303+ au_dy_fin();
1facf9fc 21304+}
21305+
21306+module_init(aufs_init);
21307+module_exit(aufs_exit);
7f207e10
AM
21308diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
21309--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 21310+++ linux/fs/aufs/module.h 2015-04-13 15:10:20.786823613 +0200
523b37e3 21311@@ -0,0 +1,104 @@
1facf9fc 21312+/*
2000de60 21313+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21314+ *
21315+ * This program, aufs is free software; you can redistribute it and/or modify
21316+ * it under the terms of the GNU General Public License as published by
21317+ * the Free Software Foundation; either version 2 of the License, or
21318+ * (at your option) any later version.
dece6358
AM
21319+ *
21320+ * This program is distributed in the hope that it will be useful,
21321+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21322+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21323+ * GNU General Public License for more details.
21324+ *
21325+ * You should have received a copy of the GNU General Public License
523b37e3 21326+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21327+ */
21328+
21329+/*
21330+ * module initialization and module-global
21331+ */
21332+
21333+#ifndef __AUFS_MODULE_H__
21334+#define __AUFS_MODULE_H__
21335+
21336+#ifdef __KERNEL__
21337+
21338+#include <linux/slab.h>
21339+
dece6358
AM
21340+struct path;
21341+struct seq_file;
21342+
1facf9fc 21343+/* module parameters */
1facf9fc 21344+extern int sysaufs_brs;
21345+
21346+/* ---------------------------------------------------------------------- */
21347+
21348+extern int au_dir_roflags;
21349+
9dbd164d
AM
21350+enum {
21351+ AuLcNonDir_FIINFO,
21352+ AuLcNonDir_DIINFO,
21353+ AuLcNonDir_IIINFO,
21354+
21355+ AuLcDir_FIINFO,
21356+ AuLcDir_DIINFO,
21357+ AuLcDir_IIINFO,
21358+
21359+ AuLcSymlink_DIINFO,
21360+ AuLcSymlink_IIINFO,
21361+
21362+ AuLcKey_Last
21363+};
21364+extern struct lock_class_key au_lc_key[AuLcKey_Last];
21365+
1facf9fc 21366+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
21367+int au_seq_path(struct seq_file *seq, struct path *path);
21368+
e49829fe
JR
21369+#ifdef CONFIG_PROC_FS
21370+/* procfs.c */
21371+int __init au_procfs_init(void);
21372+void au_procfs_fin(void);
21373+#else
21374+AuStubInt0(au_procfs_init, void);
21375+AuStubVoid(au_procfs_fin, void);
21376+#endif
21377+
4f0767ce
JR
21378+/* ---------------------------------------------------------------------- */
21379+
21380+/* kmem cache */
1facf9fc 21381+enum {
21382+ AuCache_DINFO,
21383+ AuCache_ICNTNR,
21384+ AuCache_FINFO,
21385+ AuCache_VDIR,
21386+ AuCache_DEHSTR,
7eafdf33 21387+ AuCache_HNOTIFY, /* must be last */
1facf9fc 21388+ AuCache_Last
21389+};
21390+
4a4d8108
AM
21391+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
21392+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
21393+#define AuCacheCtor(type, ctor) \
21394+ kmem_cache_create(#type, sizeof(struct type), \
21395+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 21396+
21397+extern struct kmem_cache *au_cachep[];
21398+
21399+#define AuCacheFuncs(name, index) \
4a4d8108 21400+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 21401+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 21402+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 21403+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
21404+
21405+AuCacheFuncs(dinfo, DINFO);
21406+AuCacheFuncs(icntnr, ICNTNR);
21407+AuCacheFuncs(finfo, FINFO);
21408+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
21409+AuCacheFuncs(vdir_dehstr, DEHSTR);
21410+#ifdef CONFIG_AUFS_HNOTIFY
21411+AuCacheFuncs(hnotify, HNOTIFY);
21412+#endif
1facf9fc 21413+
4a4d8108
AM
21414+#endif /* __KERNEL__ */
21415+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
21416diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
21417--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 21418+++ linux/fs/aufs/mvdown.c 2015-04-13 15:10:20.786823613 +0200
c1595e42 21419@@ -0,0 +1,694 @@
c2b27bf2 21420+/*
2000de60 21421+ * Copyright (C) 2011-2015 Junjiro R. Okajima
c2b27bf2
AM
21422+ *
21423+ * This program, aufs is free software; you can redistribute it and/or modify
21424+ * it under the terms of the GNU General Public License as published by
21425+ * the Free Software Foundation; either version 2 of the License, or
21426+ * (at your option) any later version.
21427+ *
21428+ * This program is distributed in the hope that it will be useful,
21429+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21430+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21431+ * GNU General Public License for more details.
21432+ *
21433+ * You should have received a copy of the GNU General Public License
523b37e3
AM
21434+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21435+ */
21436+
21437+/*
21438+ * move-down, opposite of copy-up
c2b27bf2
AM
21439+ */
21440+
21441+#include "aufs.h"
21442+
c2b27bf2
AM
21443+struct au_mvd_args {
21444+ struct {
c2b27bf2
AM
21445+ struct super_block *h_sb;
21446+ struct dentry *h_parent;
21447+ struct au_hinode *hdir;
392086de 21448+ struct inode *h_dir, *h_inode;
c1595e42 21449+ struct au_pin pin;
c2b27bf2
AM
21450+ } info[AUFS_MVDOWN_NARRAY];
21451+
21452+ struct aufs_mvdown mvdown;
21453+ struct dentry *dentry, *parent;
21454+ struct inode *inode, *dir;
21455+ struct super_block *sb;
21456+ aufs_bindex_t bopq, bwh, bfound;
21457+ unsigned char rename_lock;
c2b27bf2
AM
21458+};
21459+
392086de 21460+#define mvd_errno mvdown.au_errno
076b876e
AM
21461+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
21462+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
21463+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
21464+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 21465+
392086de
AM
21466+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
21467+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
21468+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
21469+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
21470+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
c1595e42 21471+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
392086de
AM
21472+
21473+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
21474+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
21475+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
21476+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
21477+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c1595e42 21478+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
c2b27bf2
AM
21479+
21480+#define AU_MVD_PR(flag, ...) do { \
21481+ if (flag) \
21482+ pr_err(__VA_ARGS__); \
21483+ } while (0)
21484+
076b876e
AM
21485+static int find_lower_writable(struct au_mvd_args *a)
21486+{
21487+ struct super_block *sb;
21488+ aufs_bindex_t bindex, bend;
21489+ struct au_branch *br;
21490+
21491+ sb = a->sb;
21492+ bindex = a->mvd_bsrc;
21493+ bend = au_sbend(sb);
21494+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
21495+ for (bindex++; bindex <= bend; bindex++) {
21496+ br = au_sbr(sb, bindex);
21497+ if (au_br_fhsm(br->br_perm)
21498+ && (!(au_br_sb(br)->s_flags & MS_RDONLY)))
21499+ return bindex;
21500+ }
21501+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
21502+ for (bindex++; bindex <= bend; bindex++) {
21503+ br = au_sbr(sb, bindex);
21504+ if (!au_br_rdonly(br))
21505+ return bindex;
21506+ }
21507+ else
21508+ for (bindex++; bindex <= bend; bindex++) {
21509+ br = au_sbr(sb, bindex);
21510+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
21511+ if (au_br_rdonly(br))
21512+ a->mvdown.flags
21513+ |= AUFS_MVDOWN_ROLOWER_R;
21514+ return bindex;
21515+ }
21516+ }
21517+
21518+ return -1;
21519+}
21520+
c2b27bf2 21521+/* make the parent dir on bdst */
392086de 21522+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21523+{
21524+ int err;
21525+
21526+ err = 0;
21527+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
21528+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
21529+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
21530+ a->mvd_h_dst_parent = NULL;
21531+ if (au_dbend(a->parent) >= a->mvd_bdst)
21532+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
21533+ if (!a->mvd_h_dst_parent) {
21534+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
21535+ if (unlikely(err)) {
392086de 21536+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
21537+ goto out;
21538+ }
21539+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
21540+ }
21541+
21542+out:
21543+ AuTraceErr(err);
21544+ return err;
21545+}
21546+
21547+/* lock them all */
392086de 21548+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21549+{
21550+ int err;
21551+ struct dentry *h_trap;
21552+
21553+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
21554+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
c1595e42
JR
21555+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
21556+ au_opt_udba(a->sb),
21557+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21558+ AuTraceErr(err);
21559+ if (unlikely(err)) {
21560+ AU_MVD_PR(dmsg, "pin_dst failed\n");
21561+ goto out;
21562+ }
21563+
c2b27bf2
AM
21564+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
21565+ a->rename_lock = 0;
c1595e42
JR
21566+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
21567+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
21568+ au_opt_udba(a->sb),
21569+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21570+ err = au_do_pin(&a->mvd_pin_src);
21571+ AuTraceErr(err);
21572+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
21573+ if (unlikely(err)) {
21574+ AU_MVD_PR(dmsg, "pin_src failed\n");
21575+ goto out_dst;
21576+ }
21577+ goto out; /* success */
c2b27bf2
AM
21578+ }
21579+
c2b27bf2 21580+ a->rename_lock = 1;
c1595e42
JR
21581+ au_pin_hdir_unlock(&a->mvd_pin_dst);
21582+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
21583+ au_opt_udba(a->sb),
21584+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21585+ AuTraceErr(err);
21586+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
21587+ if (unlikely(err)) {
21588+ AU_MVD_PR(dmsg, "pin_src failed\n");
21589+ au_pin_hdir_lock(&a->mvd_pin_dst);
21590+ goto out_dst;
21591+ }
21592+ au_pin_hdir_unlock(&a->mvd_pin_src);
c2b27bf2
AM
21593+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21594+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
21595+ if (h_trap) {
21596+ err = (h_trap != a->mvd_h_src_parent);
21597+ if (err)
21598+ err = (h_trap != a->mvd_h_dst_parent);
21599+ }
21600+ BUG_ON(err); /* it should never happen */
c1595e42
JR
21601+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
21602+ err = -EBUSY;
21603+ AuTraceErr(err);
21604+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21605+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
21606+ au_pin_hdir_lock(&a->mvd_pin_src);
21607+ au_unpin(&a->mvd_pin_src);
21608+ au_pin_hdir_lock(&a->mvd_pin_dst);
21609+ goto out_dst;
21610+ }
21611+ goto out; /* success */
c2b27bf2 21612+
c1595e42
JR
21613+out_dst:
21614+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
21615+out:
21616+ AuTraceErr(err);
21617+ return err;
21618+}
21619+
392086de 21620+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2 21621+{
c1595e42
JR
21622+ if (!a->rename_lock)
21623+ au_unpin(&a->mvd_pin_src);
21624+ else {
c2b27bf2
AM
21625+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21626+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
c1595e42
JR
21627+ au_pin_hdir_lock(&a->mvd_pin_src);
21628+ au_unpin(&a->mvd_pin_src);
21629+ au_pin_hdir_lock(&a->mvd_pin_dst);
21630+ }
21631+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
21632+}
21633+
21634+/* copy-down the file */
392086de 21635+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21636+{
21637+ int err;
21638+ struct au_cp_generic cpg = {
21639+ .dentry = a->dentry,
21640+ .bdst = a->mvd_bdst,
21641+ .bsrc = a->mvd_bsrc,
21642+ .len = -1,
c1595e42 21643+ .pin = &a->mvd_pin_dst,
c2b27bf2
AM
21644+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21645+ };
21646+
21647+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
21648+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
21649+ au_fset_cpup(cpg.flags, OVERWRITE);
21650+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
21651+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
21652+ err = au_sio_cpdown_simple(&cpg);
21653+ if (unlikely(err))
392086de 21654+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
21655+
21656+ AuTraceErr(err);
21657+ return err;
21658+}
21659+
21660+/*
21661+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
21662+ * were sleeping
21663+ */
392086de 21664+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21665+{
21666+ int err;
21667+ struct path h_path;
21668+ struct au_branch *br;
523b37e3 21669+ struct inode *delegated;
c2b27bf2
AM
21670+
21671+ br = au_sbr(a->sb, a->mvd_bdst);
21672+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
21673+ err = PTR_ERR(h_path.dentry);
21674+ if (IS_ERR(h_path.dentry)) {
392086de 21675+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
21676+ goto out;
21677+ }
21678+
21679+ err = 0;
21680+ if (h_path.dentry->d_inode) {
21681+ h_path.mnt = au_br_mnt(br);
523b37e3 21682+ delegated = NULL;
c2b27bf2 21683+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
523b37e3
AM
21684+ &delegated, /*force*/0);
21685+ if (unlikely(err == -EWOULDBLOCK)) {
21686+ pr_warn("cannot retry for NFSv4 delegation"
21687+ " for an internal unlink\n");
21688+ iput(delegated);
21689+ }
c2b27bf2 21690+ if (unlikely(err))
392086de 21691+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
21692+ }
21693+ dput(h_path.dentry);
21694+
21695+out:
21696+ AuTraceErr(err);
21697+ return err;
21698+}
21699+
21700+/*
21701+ * unlink the topmost h_dentry
c2b27bf2 21702+ */
392086de 21703+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21704+{
21705+ int err;
21706+ struct path h_path;
523b37e3 21707+ struct inode *delegated;
c2b27bf2
AM
21708+
21709+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
21710+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
21711+ delegated = NULL;
21712+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
21713+ if (unlikely(err == -EWOULDBLOCK)) {
21714+ pr_warn("cannot retry for NFSv4 delegation"
21715+ " for an internal unlink\n");
21716+ iput(delegated);
21717+ }
c2b27bf2 21718+ if (unlikely(err))
392086de 21719+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
21720+
21721+ AuTraceErr(err);
21722+ return err;
21723+}
21724+
076b876e
AM
21725+/* Since mvdown succeeded, we ignore an error of this function */
21726+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
21727+{
21728+ int err;
21729+ struct au_branch *br;
21730+
21731+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
21732+ br = au_sbr(a->sb, a->mvd_bsrc);
21733+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
21734+ if (!err) {
21735+ br = au_sbr(a->sb, a->mvd_bdst);
21736+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
21737+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
21738+ }
21739+ if (!err)
21740+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
21741+ else
21742+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
21743+}
21744+
c2b27bf2
AM
21745+/*
21746+ * copy-down the file and unlink the bsrc file.
21747+ * - unlink the bdst whout if exist
21748+ * - copy-down the file (with whtmp name and rename)
21749+ * - unlink the bsrc file
21750+ */
392086de 21751+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21752+{
21753+ int err;
21754+
392086de 21755+ err = au_do_mkdir(dmsg, a);
c2b27bf2 21756+ if (!err)
392086de 21757+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
21758+ if (unlikely(err))
21759+ goto out;
21760+
21761+ /*
21762+ * do not revert the activities we made on bdst since they should be
21763+ * harmless in aufs.
21764+ */
21765+
392086de 21766+ err = au_do_cpdown(dmsg, a);
c2b27bf2 21767+ if (!err)
392086de
AM
21768+ err = au_do_unlink_wh(dmsg, a);
21769+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
21770+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
21771+ if (unlikely(err))
21772+ goto out_unlock;
21773+
c1595e42
JR
21774+ AuDbg("%pd2, 0x%x, %d --> %d\n",
21775+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
076b876e
AM
21776+ if (find_lower_writable(a) < 0)
21777+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
21778+
21779+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
21780+ au_do_stfs(dmsg, a);
21781+
c2b27bf2 21782+ /* maintain internal array */
392086de
AM
21783+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
21784+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
21785+ au_set_dbstart(a->dentry, a->mvd_bdst);
21786+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
21787+ au_set_ibstart(a->inode, a->mvd_bdst);
21788+ }
c2b27bf2
AM
21789+ if (au_dbend(a->dentry) < a->mvd_bdst)
21790+ au_set_dbend(a->dentry, a->mvd_bdst);
c2b27bf2
AM
21791+ if (au_ibend(a->inode) < a->mvd_bdst)
21792+ au_set_ibend(a->inode, a->mvd_bdst);
21793+
21794+out_unlock:
392086de 21795+ au_do_unlock(dmsg, a);
c2b27bf2
AM
21796+out:
21797+ AuTraceErr(err);
21798+ return err;
21799+}
21800+
21801+/* ---------------------------------------------------------------------- */
21802+
c2b27bf2 21803+/* make sure the file is idle */
392086de 21804+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21805+{
21806+ int err, plinked;
c2b27bf2
AM
21807+
21808+ err = 0;
c2b27bf2
AM
21809+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
21810+ if (au_dbstart(a->dentry) == a->mvd_bsrc
c1595e42 21811+ && au_dcount(a->dentry) == 1
c2b27bf2 21812+ && atomic_read(&a->inode->i_count) == 1
392086de 21813+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
21814+ && (!plinked || !au_plink_test(a->inode))
21815+ && a->inode->i_nlink == 1)
21816+ goto out;
21817+
21818+ err = -EBUSY;
392086de 21819+ AU_MVD_PR(dmsg,
c1595e42
JR
21820+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
21821+ a->mvd_bsrc, au_dbstart(a->dentry), au_dcount(a->dentry),
c2b27bf2 21822+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 21823+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
21824+ plinked, plinked ? au_plink_test(a->inode) : 0);
21825+
21826+out:
21827+ AuTraceErr(err);
21828+ return err;
21829+}
21830+
21831+/* make sure the parent dir is fine */
392086de 21832+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
21833+ struct au_mvd_args *a)
21834+{
21835+ int err;
21836+ aufs_bindex_t bindex;
21837+
21838+ err = 0;
21839+ if (unlikely(au_alive_dir(a->parent))) {
21840+ err = -ENOENT;
392086de 21841+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
21842+ goto out;
21843+ }
21844+
21845+ a->bopq = au_dbdiropq(a->parent);
21846+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
21847+ AuDbg("b%d\n", bindex);
21848+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
21849+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
21850+ err = -EINVAL;
392086de
AM
21851+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
21852+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
21853+ a->bopq, a->mvd_bdst);
21854+ }
21855+
21856+out:
21857+ AuTraceErr(err);
21858+ return err;
21859+}
21860+
392086de 21861+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
21862+ struct au_mvd_args *a)
21863+{
21864+ int err;
21865+ struct au_dinfo *dinfo, *tmp;
21866+
21867+ /* lookup the next lower positive entry */
21868+ err = -ENOMEM;
21869+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
21870+ if (unlikely(!tmp))
21871+ goto out;
21872+
21873+ a->bfound = -1;
21874+ a->bwh = -1;
21875+ dinfo = au_di(a->dentry);
21876+ au_di_cp(tmp, dinfo);
21877+ au_di_swap(tmp, dinfo);
21878+
21879+ /* returns the number of positive dentries */
21880+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
21881+ if (!err)
21882+ a->bwh = au_dbwh(a->dentry);
21883+ else if (err > 0)
21884+ a->bfound = au_dbstart(a->dentry);
21885+
21886+ au_di_swap(tmp, dinfo);
21887+ au_rw_write_unlock(&tmp->di_rwsem);
21888+ au_di_free(tmp);
21889+ if (unlikely(err < 0))
392086de 21890+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
21891+
21892+ /*
21893+ * here, we have these cases.
21894+ * bfound == -1
21895+ * no positive dentry under bsrc. there are more sub-cases.
21896+ * bwh < 0
21897+ * there no whiteout, we can safely move-down.
21898+ * bwh <= bsrc
21899+ * impossible
21900+ * bsrc < bwh && bwh < bdst
21901+ * there is a whiteout on RO branch. cannot proceed.
21902+ * bwh == bdst
21903+ * there is a whiteout on the RW target branch. it should
21904+ * be removed.
21905+ * bdst < bwh
21906+ * there is a whiteout somewhere unrelated branch.
21907+ * -1 < bfound && bfound <= bsrc
21908+ * impossible.
21909+ * bfound < bdst
21910+ * found, but it is on RO branch between bsrc and bdst. cannot
21911+ * proceed.
21912+ * bfound == bdst
21913+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
21914+ * error.
21915+ * bdst < bfound
21916+ * found, after we create the file on bdst, it will be hidden.
21917+ */
21918+
21919+ AuDebugOn(a->bfound == -1
21920+ && a->bwh != -1
21921+ && a->bwh <= a->mvd_bsrc);
21922+ AuDebugOn(-1 < a->bfound
21923+ && a->bfound <= a->mvd_bsrc);
21924+
21925+ err = -EINVAL;
21926+ if (a->bfound == -1
21927+ && a->mvd_bsrc < a->bwh
21928+ && a->bwh != -1
21929+ && a->bwh < a->mvd_bdst) {
392086de
AM
21930+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
21931+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
21932+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
21933+ goto out;
21934+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
21935+ a->mvd_errno = EAU_MVDOWN_UPPER;
21936+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
21937+ a->mvd_bdst, a->bfound);
21938+ goto out;
21939+ }
21940+
21941+ err = 0; /* success */
21942+
21943+out:
21944+ AuTraceErr(err);
21945+ return err;
21946+}
21947+
392086de 21948+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21949+{
21950+ int err;
21951+
392086de
AM
21952+ err = 0;
21953+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
21954+ && a->bfound == a->mvd_bdst)
21955+ err = -EEXIST;
c2b27bf2
AM
21956+ AuTraceErr(err);
21957+ return err;
21958+}
21959+
392086de 21960+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21961+{
21962+ int err;
21963+ struct au_branch *br;
21964+
21965+ err = -EISDIR;
21966+ if (unlikely(S_ISDIR(a->inode->i_mode)))
21967+ goto out;
21968+
21969+ err = -EINVAL;
392086de
AM
21970+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
21971+ a->mvd_bsrc = au_ibstart(a->inode);
21972+ else {
21973+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
21974+ if (unlikely(a->mvd_bsrc < 0
21975+ || (a->mvd_bsrc < au_dbstart(a->dentry)
21976+ || au_dbend(a->dentry) < a->mvd_bsrc
21977+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
21978+ || (a->mvd_bsrc < au_ibstart(a->inode)
21979+ || au_ibend(a->inode) < a->mvd_bsrc
21980+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
21981+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
21982+ AU_MVD_PR(dmsg, "no upper\n");
21983+ goto out;
21984+ }
21985+ }
c2b27bf2 21986+ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
392086de
AM
21987+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
21988+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
21989+ goto out;
21990+ }
392086de 21991+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
21992+ br = au_sbr(a->sb, a->mvd_bsrc);
21993+ err = au_br_rdonly(br);
392086de
AM
21994+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
21995+ if (unlikely(err))
21996+ goto out;
21997+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
21998+ || IS_APPEND(a->mvd_h_src_inode))) {
21999+ if (err)
22000+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
22001+ /* go on */
22002+ } else
c2b27bf2
AM
22003+ goto out;
22004+
22005+ err = -EINVAL;
392086de
AM
22006+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
22007+ a->mvd_bdst = find_lower_writable(a);
22008+ if (unlikely(a->mvd_bdst < 0)) {
22009+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
22010+ AU_MVD_PR(dmsg, "no writable lower branch\n");
22011+ goto out;
22012+ }
22013+ } else {
22014+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
22015+ if (unlikely(a->mvd_bdst < 0
22016+ || au_sbend(a->sb) < a->mvd_bdst)) {
22017+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
22018+ AU_MVD_PR(dmsg, "no lower brid\n");
22019+ goto out;
22020+ }
c2b27bf2
AM
22021+ }
22022+
392086de 22023+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 22024+ if (!err)
392086de 22025+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 22026+ if (!err)
392086de 22027+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 22028+ if (!err)
392086de 22029+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
22030+ if (!err)
22031+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
22032+
22033+out:
22034+ AuTraceErr(err);
22035+ return err;
22036+}
22037+
22038+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
22039+{
392086de
AM
22040+ int err, e;
22041+ unsigned char dmsg;
22042+ struct au_mvd_args *args;
c2b27bf2
AM
22043+
22044+ err = -EPERM;
22045+ if (unlikely(!capable(CAP_SYS_ADMIN)))
22046+ goto out;
22047+
392086de
AM
22048+ err = -ENOMEM;
22049+ args = kmalloc(sizeof(*args), GFP_NOFS);
22050+ if (unlikely(!args))
22051+ goto out;
22052+
22053+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
22054+ if (!err)
22055+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
22056+ if (unlikely(err)) {
22057+ err = -EFAULT;
392086de
AM
22058+ AuTraceErr(err);
22059+ goto out_free;
c2b27bf2 22060+ }
392086de
AM
22061+ AuDbg("flags 0x%x\n", args->mvdown.flags);
22062+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
22063+ args->mvdown.au_errno = 0;
22064+ args->dentry = dentry;
22065+ args->inode = dentry->d_inode;
22066+ args->sb = dentry->d_sb;
c2b27bf2 22067+
392086de
AM
22068+ err = -ENOENT;
22069+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
22070+ args->parent = dget_parent(dentry);
22071+ args->dir = args->parent->d_inode;
22072+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
22073+ dput(args->parent);
22074+ if (unlikely(args->parent != dentry->d_parent)) {
22075+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
22076+ goto out_dir;
22077+ }
22078+
392086de 22079+ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
c2b27bf2
AM
22080+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
22081+ if (unlikely(err))
22082+ goto out_inode;
22083+
392086de
AM
22084+ di_write_lock_parent(args->parent);
22085+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
22086+ if (unlikely(err))
22087+ goto out_parent;
22088+
392086de 22089+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
22090+ if (unlikely(err))
22091+ goto out_parent;
c2b27bf2 22092+
392086de
AM
22093+ au_cpup_attr_timesizes(args->dir);
22094+ au_cpup_attr_timesizes(args->inode);
22095+ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
c2b27bf2
AM
22096+ /* au_digen_dec(dentry); */
22097+
22098+out_parent:
392086de 22099+ di_write_unlock(args->parent);
c2b27bf2
AM
22100+ aufs_read_unlock(dentry, AuLock_DW);
22101+out_inode:
392086de 22102+ mutex_unlock(&args->inode->i_mutex);
c2b27bf2 22103+out_dir:
392086de
AM
22104+ mutex_unlock(&args->dir->i_mutex);
22105+out_free:
22106+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
22107+ if (unlikely(e))
22108+ err = -EFAULT;
22109+ kfree(args);
c2b27bf2
AM
22110+out:
22111+ AuTraceErr(err);
22112+ return err;
22113+}
22114diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
22115--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
22116+++ linux/fs/aufs/opts.c 2015-04-13 15:10:20.786823613 +0200
22117@@ -0,0 +1,1854 @@
1facf9fc 22118+/*
2000de60 22119+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 22120+ *
22121+ * This program, aufs is free software; you can redistribute it and/or modify
22122+ * it under the terms of the GNU General Public License as published by
22123+ * the Free Software Foundation; either version 2 of the License, or
22124+ * (at your option) any later version.
dece6358
AM
22125+ *
22126+ * This program is distributed in the hope that it will be useful,
22127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22129+ * GNU General Public License for more details.
22130+ *
22131+ * You should have received a copy of the GNU General Public License
523b37e3 22132+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22133+ */
22134+
22135+/*
22136+ * mount options/flags
22137+ */
22138+
dece6358 22139+#include <linux/namei.h>
1facf9fc 22140+#include <linux/types.h> /* a distribution requires */
22141+#include <linux/parser.h>
22142+#include "aufs.h"
22143+
22144+/* ---------------------------------------------------------------------- */
22145+
22146+enum {
22147+ Opt_br,
7e9cd9fe
AM
22148+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend,
22149+ Opt_idel, Opt_imod,
22150+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash,
dece6358 22151+ Opt_rdblk_def, Opt_rdhash_def,
7e9cd9fe 22152+ Opt_xino, Opt_noxino,
1facf9fc 22153+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
22154+ Opt_trunc_xino_path, Opt_itrunc_xino,
22155+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 22156+ Opt_shwh, Opt_noshwh,
1facf9fc 22157+ Opt_plink, Opt_noplink, Opt_list_plink,
22158+ Opt_udba,
4a4d8108 22159+ Opt_dio, Opt_nodio,
1facf9fc 22160+ Opt_diropq_a, Opt_diropq_w,
22161+ Opt_warn_perm, Opt_nowarn_perm,
22162+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 22163+ Opt_fhsm_sec,
1facf9fc 22164+ Opt_refrof, Opt_norefrof,
22165+ Opt_verbose, Opt_noverbose,
22166+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 22167+ Opt_dirperm1, Opt_nodirperm1,
c1595e42 22168+ Opt_acl, Opt_noacl,
1facf9fc 22169+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
22170+};
22171+
22172+static match_table_t options = {
22173+ {Opt_br, "br=%s"},
22174+ {Opt_br, "br:%s"},
22175+
22176+ {Opt_add, "add=%d:%s"},
22177+ {Opt_add, "add:%d:%s"},
22178+ {Opt_add, "ins=%d:%s"},
22179+ {Opt_add, "ins:%d:%s"},
22180+ {Opt_append, "append=%s"},
22181+ {Opt_append, "append:%s"},
22182+ {Opt_prepend, "prepend=%s"},
22183+ {Opt_prepend, "prepend:%s"},
22184+
22185+ {Opt_del, "del=%s"},
22186+ {Opt_del, "del:%s"},
22187+ /* {Opt_idel, "idel:%d"}, */
22188+ {Opt_mod, "mod=%s"},
22189+ {Opt_mod, "mod:%s"},
22190+ /* {Opt_imod, "imod:%d:%s"}, */
22191+
22192+ {Opt_dirwh, "dirwh=%d"},
22193+
22194+ {Opt_xino, "xino=%s"},
22195+ {Opt_noxino, "noxino"},
22196+ {Opt_trunc_xino, "trunc_xino"},
22197+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
22198+ {Opt_notrunc_xino, "notrunc_xino"},
22199+ {Opt_trunc_xino_path, "trunc_xino=%s"},
22200+ {Opt_itrunc_xino, "itrunc_xino=%d"},
22201+ /* {Opt_zxino, "zxino=%s"}, */
22202+ {Opt_trunc_xib, "trunc_xib"},
22203+ {Opt_notrunc_xib, "notrunc_xib"},
22204+
e49829fe 22205+#ifdef CONFIG_PROC_FS
1facf9fc 22206+ {Opt_plink, "plink"},
e49829fe
JR
22207+#else
22208+ {Opt_ignore_silent, "plink"},
22209+#endif
22210+
1facf9fc 22211+ {Opt_noplink, "noplink"},
e49829fe 22212+
1facf9fc 22213+#ifdef CONFIG_AUFS_DEBUG
22214+ {Opt_list_plink, "list_plink"},
22215+#endif
22216+
22217+ {Opt_udba, "udba=%s"},
22218+
4a4d8108
AM
22219+ {Opt_dio, "dio"},
22220+ {Opt_nodio, "nodio"},
22221+
076b876e
AM
22222+#ifdef CONFIG_AUFS_FHSM
22223+ {Opt_fhsm_sec, "fhsm_sec=%d"},
22224+#else
22225+ {Opt_ignore_silent, "fhsm_sec=%d"},
22226+#endif
22227+
1facf9fc 22228+ {Opt_diropq_a, "diropq=always"},
22229+ {Opt_diropq_a, "diropq=a"},
22230+ {Opt_diropq_w, "diropq=whiteouted"},
22231+ {Opt_diropq_w, "diropq=w"},
22232+
22233+ {Opt_warn_perm, "warn_perm"},
22234+ {Opt_nowarn_perm, "nowarn_perm"},
22235+
22236+ /* keep them temporary */
1facf9fc 22237+ {Opt_ignore_silent, "nodlgt"},
1facf9fc 22238+ {Opt_ignore_silent, "clean_plink"},
22239+
dece6358
AM
22240+#ifdef CONFIG_AUFS_SHWH
22241+ {Opt_shwh, "shwh"},
22242+#endif
22243+ {Opt_noshwh, "noshwh"},
22244+
076b876e
AM
22245+ {Opt_dirperm1, "dirperm1"},
22246+ {Opt_nodirperm1, "nodirperm1"},
22247+
1facf9fc 22248+ {Opt_refrof, "refrof"},
22249+ {Opt_norefrof, "norefrof"},
22250+
22251+ {Opt_verbose, "verbose"},
22252+ {Opt_verbose, "v"},
22253+ {Opt_noverbose, "noverbose"},
22254+ {Opt_noverbose, "quiet"},
22255+ {Opt_noverbose, "q"},
22256+ {Opt_noverbose, "silent"},
22257+
22258+ {Opt_sum, "sum"},
22259+ {Opt_nosum, "nosum"},
22260+ {Opt_wsum, "wsum"},
22261+
22262+ {Opt_rdcache, "rdcache=%d"},
22263+ {Opt_rdblk, "rdblk=%d"},
dece6358 22264+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 22265+ {Opt_rdhash, "rdhash=%d"},
dece6358 22266+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 22267+
22268+ {Opt_wbr_create, "create=%s"},
22269+ {Opt_wbr_create, "create_policy=%s"},
22270+ {Opt_wbr_copyup, "cpup=%s"},
22271+ {Opt_wbr_copyup, "copyup=%s"},
22272+ {Opt_wbr_copyup, "copyup_policy=%s"},
22273+
c1595e42
JR
22274+ /* generic VFS flag */
22275+#ifdef CONFIG_FS_POSIX_ACL
22276+ {Opt_acl, "acl"},
22277+ {Opt_noacl, "noacl"},
22278+#else
22279+ {Opt_ignore_silent, "acl"},
22280+ {Opt_ignore_silent, "noacl"},
22281+#endif
22282+
1facf9fc 22283+ /* internal use for the scripts */
22284+ {Opt_ignore_silent, "si=%s"},
22285+
22286+ {Opt_br, "dirs=%s"},
22287+ {Opt_ignore, "debug=%d"},
22288+ {Opt_ignore, "delete=whiteout"},
22289+ {Opt_ignore, "delete=all"},
22290+ {Opt_ignore, "imap=%s"},
22291+
1308ab2a 22292+ /* temporary workaround, due to old mount(8)? */
22293+ {Opt_ignore_silent, "relatime"},
22294+
1facf9fc 22295+ {Opt_err, NULL}
22296+};
22297+
22298+/* ---------------------------------------------------------------------- */
22299+
076b876e 22300+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 22301+{
076b876e
AM
22302+ struct match_token *p;
22303+
22304+ p = tbl;
22305+ while (p->pattern) {
22306+ if (p->token == val)
22307+ return p->pattern;
22308+ p++;
1facf9fc 22309+ }
22310+ BUG();
22311+ return "??";
22312+}
22313+
076b876e
AM
22314+static const char *au_optstr(int *val, match_table_t tbl)
22315+{
22316+ struct match_token *p;
22317+ int v;
22318+
22319+ v = *val;
2000de60
JR
22320+ if (!v)
22321+ goto out;
076b876e 22322+ p = tbl;
2000de60
JR
22323+ while (p->pattern) {
22324+ if (p->token
22325+ && (v & p->token) == p->token) {
076b876e
AM
22326+ *val &= ~p->token;
22327+ return p->pattern;
22328+ }
22329+ p++;
22330+ }
2000de60
JR
22331+
22332+out:
076b876e
AM
22333+ return NULL;
22334+}
22335+
1facf9fc 22336+/* ---------------------------------------------------------------------- */
22337+
1e00d052 22338+static match_table_t brperm = {
1facf9fc 22339+ {AuBrPerm_RO, AUFS_BRPERM_RO},
22340+ {AuBrPerm_RR, AUFS_BRPERM_RR},
22341+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
22342+ {0, NULL}
22343+};
1facf9fc 22344+
86dc4139 22345+static match_table_t brattr = {
076b876e
AM
22346+ /* general */
22347+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
22348+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
c1595e42 22349+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
86dc4139 22350+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
2000de60 22351+#ifdef CONFIG_AUFS_FHSM
076b876e 22352+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
2000de60
JR
22353+#endif
22354+#ifdef CONFIG_AUFS_XATTR
c1595e42
JR
22355+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
22356+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
22357+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
22358+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
22359+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
22360+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
2000de60 22361+#endif
076b876e
AM
22362+
22363+ /* ro/rr branch */
1e00d052 22364+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
22365+
22366+ /* rw branch */
22367+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 22368+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 22369+
1e00d052 22370+ {0, NULL}
1facf9fc 22371+};
22372+
1e00d052
AM
22373+static int br_attr_val(char *str, match_table_t table, substring_t args[])
22374+{
22375+ int attr, v;
22376+ char *p;
22377+
22378+ attr = 0;
22379+ do {
22380+ p = strchr(str, '+');
22381+ if (p)
22382+ *p = 0;
22383+ v = match_token(str, table, args);
076b876e
AM
22384+ if (v) {
22385+ if (v & AuBrAttr_CMOO_Mask)
22386+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 22387+ attr |= v;
076b876e 22388+ } else {
1e00d052
AM
22389+ if (p)
22390+ *p = '+';
0c3ec466 22391+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
22392+ break;
22393+ }
22394+ if (p)
22395+ str = p + 1;
22396+ } while (p);
22397+
22398+ return attr;
22399+}
22400+
076b876e
AM
22401+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
22402+{
22403+ int sz;
22404+ const char *p;
22405+ char *q;
22406+
076b876e
AM
22407+ q = str->a;
22408+ *q = 0;
22409+ p = au_optstr(&perm, brattr);
22410+ if (p) {
22411+ sz = strlen(p);
22412+ memcpy(q, p, sz + 1);
22413+ q += sz;
22414+ } else
22415+ goto out;
22416+
22417+ do {
22418+ p = au_optstr(&perm, brattr);
22419+ if (p) {
22420+ *q++ = '+';
22421+ sz = strlen(p);
22422+ memcpy(q, p, sz + 1);
22423+ q += sz;
22424+ }
22425+ } while (p);
22426+
22427+out:
c1595e42 22428+ return q - str->a;
076b876e
AM
22429+}
22430+
4a4d8108 22431+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 22432+{
076b876e
AM
22433+ int val, bad, sz;
22434+ char *p;
1facf9fc 22435+ substring_t args[MAX_OPT_ARGS];
076b876e 22436+ au_br_perm_str_t attr;
1facf9fc 22437+
1e00d052
AM
22438+ p = strchr(perm, '+');
22439+ if (p)
22440+ *p = 0;
22441+ val = match_token(perm, brperm, args);
22442+ if (!val) {
22443+ if (p)
22444+ *p = '+';
0c3ec466 22445+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
22446+ val = AuBrPerm_RO;
22447+ goto out;
22448+ }
22449+ if (!p)
22450+ goto out;
22451+
076b876e
AM
22452+ val |= br_attr_val(p + 1, brattr, args);
22453+
22454+ bad = 0;
86dc4139 22455+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
22456+ case AuBrPerm_RO:
22457+ case AuBrPerm_RR:
076b876e
AM
22458+ bad = val & AuBrWAttr_Mask;
22459+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
22460+ break;
22461+ case AuBrPerm_RW:
076b876e
AM
22462+ bad = val & AuBrRAttr_Mask;
22463+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
22464+ break;
22465+ }
c1595e42
JR
22466+
22467+ /*
22468+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
22469+ * does not treat it as an error, just warning.
22470+ * this is a tiny guard for the user operation.
22471+ */
22472+ if (val & AuBrAttr_UNPIN) {
22473+ bad |= AuBrAttr_UNPIN;
22474+ val &= ~AuBrAttr_UNPIN;
22475+ }
22476+
076b876e
AM
22477+ if (unlikely(bad)) {
22478+ sz = au_do_optstr_br_attr(&attr, bad);
22479+ AuDebugOn(!sz);
22480+ pr_warn("ignored branch attribute %s\n", attr.a);
22481+ }
1e00d052
AM
22482+
22483+out:
1facf9fc 22484+ return val;
22485+}
22486+
076b876e 22487+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 22488+{
076b876e
AM
22489+ au_br_perm_str_t attr;
22490+ const char *p;
22491+ char *q;
1e00d052
AM
22492+ int sz;
22493+
076b876e
AM
22494+ q = str->a;
22495+ p = au_optstr(&perm, brperm);
22496+ AuDebugOn(!p || !*p);
22497+ sz = strlen(p);
22498+ memcpy(q, p, sz + 1);
22499+ q += sz;
1e00d052 22500+
076b876e
AM
22501+ sz = au_do_optstr_br_attr(&attr, perm);
22502+ if (sz) {
22503+ *q++ = '+';
22504+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
22505+ }
22506+
076b876e 22507+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 22508+}
22509+
22510+/* ---------------------------------------------------------------------- */
22511+
22512+static match_table_t udbalevel = {
22513+ {AuOpt_UDBA_REVAL, "reval"},
22514+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
22515+#ifdef CONFIG_AUFS_HNOTIFY
22516+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
22517+#ifdef CONFIG_AUFS_HFSNOTIFY
22518+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 22519+#endif
1facf9fc 22520+#endif
22521+ {-1, NULL}
22522+};
22523+
4a4d8108 22524+static int noinline_for_stack udba_val(char *str)
1facf9fc 22525+{
22526+ substring_t args[MAX_OPT_ARGS];
22527+
7f207e10 22528+ return match_token(str, udbalevel, args);
1facf9fc 22529+}
22530+
22531+const char *au_optstr_udba(int udba)
22532+{
076b876e 22533+ return au_parser_pattern(udba, udbalevel);
1facf9fc 22534+}
22535+
22536+/* ---------------------------------------------------------------------- */
22537+
22538+static match_table_t au_wbr_create_policy = {
22539+ {AuWbrCreate_TDP, "tdp"},
22540+ {AuWbrCreate_TDP, "top-down-parent"},
22541+ {AuWbrCreate_RR, "rr"},
22542+ {AuWbrCreate_RR, "round-robin"},
22543+ {AuWbrCreate_MFS, "mfs"},
22544+ {AuWbrCreate_MFS, "most-free-space"},
22545+ {AuWbrCreate_MFSV, "mfs:%d"},
22546+ {AuWbrCreate_MFSV, "most-free-space:%d"},
22547+
22548+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
22549+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
22550+ {AuWbrCreate_PMFS, "pmfs"},
22551+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
22552+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
22553+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 22554+
22555+ {-1, NULL}
22556+};
22557+
dece6358
AM
22558+/*
22559+ * cf. linux/lib/parser.c and cmdline.c
22560+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 22561+ * kstrto...().
dece6358 22562+ */
4a4d8108
AM
22563+static int noinline_for_stack
22564+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 22565+{
22566+ int err;
22567+ unsigned int len;
22568+ char a[32];
22569+
22570+ err = -ERANGE;
22571+ len = s->to - s->from;
22572+ if (len + 1 <= sizeof(a)) {
22573+ memcpy(a, s->from, len);
22574+ a[len] = '\0';
9dbd164d 22575+ err = kstrtoull(a, 0, result);
1facf9fc 22576+ }
22577+ return err;
22578+}
22579+
22580+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
22581+ struct au_opt_wbr_create *create)
22582+{
22583+ int err;
22584+ unsigned long long ull;
22585+
22586+ err = 0;
22587+ if (!au_match_ull(arg, &ull))
22588+ create->mfsrr_watermark = ull;
22589+ else {
4a4d8108 22590+ pr_err("bad integer in %s\n", str);
1facf9fc 22591+ err = -EINVAL;
22592+ }
22593+
22594+ return err;
22595+}
22596+
22597+static int au_wbr_mfs_sec(substring_t *arg, char *str,
22598+ struct au_opt_wbr_create *create)
22599+{
22600+ int n, err;
22601+
22602+ err = 0;
027c5e7a 22603+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 22604+ create->mfs_second = n;
22605+ else {
4a4d8108 22606+ pr_err("bad integer in %s\n", str);
1facf9fc 22607+ err = -EINVAL;
22608+ }
22609+
22610+ return err;
22611+}
22612+
4a4d8108
AM
22613+static int noinline_for_stack
22614+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 22615+{
22616+ int err, e;
22617+ substring_t args[MAX_OPT_ARGS];
22618+
22619+ err = match_token(str, au_wbr_create_policy, args);
22620+ create->wbr_create = err;
22621+ switch (err) {
22622+ case AuWbrCreate_MFSRRV:
392086de 22623+ case AuWbrCreate_PMFSRRV:
1facf9fc 22624+ e = au_wbr_mfs_wmark(&args[0], str, create);
22625+ if (!e)
22626+ e = au_wbr_mfs_sec(&args[1], str, create);
22627+ if (unlikely(e))
22628+ err = e;
22629+ break;
22630+ case AuWbrCreate_MFSRR:
392086de 22631+ case AuWbrCreate_PMFSRR:
1facf9fc 22632+ e = au_wbr_mfs_wmark(&args[0], str, create);
22633+ if (unlikely(e)) {
22634+ err = e;
22635+ break;
22636+ }
22637+ /*FALLTHROUGH*/
22638+ case AuWbrCreate_MFS:
22639+ case AuWbrCreate_PMFS:
027c5e7a 22640+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 22641+ break;
22642+ case AuWbrCreate_MFSV:
22643+ case AuWbrCreate_PMFSV:
22644+ e = au_wbr_mfs_sec(&args[0], str, create);
22645+ if (unlikely(e))
22646+ err = e;
22647+ break;
22648+ }
22649+
22650+ return err;
22651+}
22652+
22653+const char *au_optstr_wbr_create(int wbr_create)
22654+{
076b876e 22655+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 22656+}
22657+
22658+static match_table_t au_wbr_copyup_policy = {
22659+ {AuWbrCopyup_TDP, "tdp"},
22660+ {AuWbrCopyup_TDP, "top-down-parent"},
22661+ {AuWbrCopyup_BUP, "bup"},
22662+ {AuWbrCopyup_BUP, "bottom-up-parent"},
22663+ {AuWbrCopyup_BU, "bu"},
22664+ {AuWbrCopyup_BU, "bottom-up"},
22665+ {-1, NULL}
22666+};
22667+
4a4d8108 22668+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 22669+{
22670+ substring_t args[MAX_OPT_ARGS];
22671+
22672+ return match_token(str, au_wbr_copyup_policy, args);
22673+}
22674+
22675+const char *au_optstr_wbr_copyup(int wbr_copyup)
22676+{
076b876e 22677+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 22678+}
22679+
22680+/* ---------------------------------------------------------------------- */
22681+
22682+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
22683+
22684+static void dump_opts(struct au_opts *opts)
22685+{
22686+#ifdef CONFIG_AUFS_DEBUG
22687+ /* reduce stack space */
22688+ union {
22689+ struct au_opt_add *add;
22690+ struct au_opt_del *del;
22691+ struct au_opt_mod *mod;
22692+ struct au_opt_xino *xino;
22693+ struct au_opt_xino_itrunc *xino_itrunc;
22694+ struct au_opt_wbr_create *create;
22695+ } u;
22696+ struct au_opt *opt;
22697+
22698+ opt = opts->opt;
22699+ while (opt->type != Opt_tail) {
22700+ switch (opt->type) {
22701+ case Opt_add:
22702+ u.add = &opt->add;
22703+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
22704+ u.add->bindex, u.add->pathname, u.add->perm,
22705+ u.add->path.dentry);
22706+ break;
22707+ case Opt_del:
22708+ case Opt_idel:
22709+ u.del = &opt->del;
22710+ AuDbg("del {%s, %p}\n",
22711+ u.del->pathname, u.del->h_path.dentry);
22712+ break;
22713+ case Opt_mod:
22714+ case Opt_imod:
22715+ u.mod = &opt->mod;
22716+ AuDbg("mod {%s, 0x%x, %p}\n",
22717+ u.mod->path, u.mod->perm, u.mod->h_root);
22718+ break;
22719+ case Opt_append:
22720+ u.add = &opt->add;
22721+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
22722+ u.add->bindex, u.add->pathname, u.add->perm,
22723+ u.add->path.dentry);
22724+ break;
22725+ case Opt_prepend:
22726+ u.add = &opt->add;
22727+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
22728+ u.add->bindex, u.add->pathname, u.add->perm,
22729+ u.add->path.dentry);
22730+ break;
22731+ case Opt_dirwh:
22732+ AuDbg("dirwh %d\n", opt->dirwh);
22733+ break;
22734+ case Opt_rdcache:
22735+ AuDbg("rdcache %d\n", opt->rdcache);
22736+ break;
22737+ case Opt_rdblk:
22738+ AuDbg("rdblk %u\n", opt->rdblk);
22739+ break;
dece6358
AM
22740+ case Opt_rdblk_def:
22741+ AuDbg("rdblk_def\n");
22742+ break;
1facf9fc 22743+ case Opt_rdhash:
22744+ AuDbg("rdhash %u\n", opt->rdhash);
22745+ break;
dece6358
AM
22746+ case Opt_rdhash_def:
22747+ AuDbg("rdhash_def\n");
22748+ break;
1facf9fc 22749+ case Opt_xino:
22750+ u.xino = &opt->xino;
523b37e3 22751+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 22752+ break;
22753+ case Opt_trunc_xino:
22754+ AuLabel(trunc_xino);
22755+ break;
22756+ case Opt_notrunc_xino:
22757+ AuLabel(notrunc_xino);
22758+ break;
22759+ case Opt_trunc_xino_path:
22760+ case Opt_itrunc_xino:
22761+ u.xino_itrunc = &opt->xino_itrunc;
22762+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
22763+ break;
1facf9fc 22764+ case Opt_noxino:
22765+ AuLabel(noxino);
22766+ break;
22767+ case Opt_trunc_xib:
22768+ AuLabel(trunc_xib);
22769+ break;
22770+ case Opt_notrunc_xib:
22771+ AuLabel(notrunc_xib);
22772+ break;
dece6358
AM
22773+ case Opt_shwh:
22774+ AuLabel(shwh);
22775+ break;
22776+ case Opt_noshwh:
22777+ AuLabel(noshwh);
22778+ break;
076b876e
AM
22779+ case Opt_dirperm1:
22780+ AuLabel(dirperm1);
22781+ break;
22782+ case Opt_nodirperm1:
22783+ AuLabel(nodirperm1);
22784+ break;
1facf9fc 22785+ case Opt_plink:
22786+ AuLabel(plink);
22787+ break;
22788+ case Opt_noplink:
22789+ AuLabel(noplink);
22790+ break;
22791+ case Opt_list_plink:
22792+ AuLabel(list_plink);
22793+ break;
22794+ case Opt_udba:
22795+ AuDbg("udba %d, %s\n",
22796+ opt->udba, au_optstr_udba(opt->udba));
22797+ break;
4a4d8108
AM
22798+ case Opt_dio:
22799+ AuLabel(dio);
22800+ break;
22801+ case Opt_nodio:
22802+ AuLabel(nodio);
22803+ break;
1facf9fc 22804+ case Opt_diropq_a:
22805+ AuLabel(diropq_a);
22806+ break;
22807+ case Opt_diropq_w:
22808+ AuLabel(diropq_w);
22809+ break;
22810+ case Opt_warn_perm:
22811+ AuLabel(warn_perm);
22812+ break;
22813+ case Opt_nowarn_perm:
22814+ AuLabel(nowarn_perm);
22815+ break;
22816+ case Opt_refrof:
22817+ AuLabel(refrof);
22818+ break;
22819+ case Opt_norefrof:
22820+ AuLabel(norefrof);
22821+ break;
22822+ case Opt_verbose:
22823+ AuLabel(verbose);
22824+ break;
22825+ case Opt_noverbose:
22826+ AuLabel(noverbose);
22827+ break;
22828+ case Opt_sum:
22829+ AuLabel(sum);
22830+ break;
22831+ case Opt_nosum:
22832+ AuLabel(nosum);
22833+ break;
22834+ case Opt_wsum:
22835+ AuLabel(wsum);
22836+ break;
22837+ case Opt_wbr_create:
22838+ u.create = &opt->wbr_create;
22839+ AuDbg("create %d, %s\n", u.create->wbr_create,
22840+ au_optstr_wbr_create(u.create->wbr_create));
22841+ switch (u.create->wbr_create) {
22842+ case AuWbrCreate_MFSV:
22843+ case AuWbrCreate_PMFSV:
22844+ AuDbg("%d sec\n", u.create->mfs_second);
22845+ break;
22846+ case AuWbrCreate_MFSRR:
22847+ AuDbg("%llu watermark\n",
22848+ u.create->mfsrr_watermark);
22849+ break;
22850+ case AuWbrCreate_MFSRRV:
392086de 22851+ case AuWbrCreate_PMFSRRV:
1facf9fc 22852+ AuDbg("%llu watermark, %d sec\n",
22853+ u.create->mfsrr_watermark,
22854+ u.create->mfs_second);
22855+ break;
22856+ }
22857+ break;
22858+ case Opt_wbr_copyup:
22859+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
22860+ au_optstr_wbr_copyup(opt->wbr_copyup));
22861+ break;
076b876e
AM
22862+ case Opt_fhsm_sec:
22863+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
22864+ break;
c1595e42
JR
22865+ case Opt_acl:
22866+ AuLabel(acl);
22867+ break;
22868+ case Opt_noacl:
22869+ AuLabel(noacl);
22870+ break;
1facf9fc 22871+ default:
22872+ BUG();
22873+ }
22874+ opt++;
22875+ }
22876+#endif
22877+}
22878+
22879+void au_opts_free(struct au_opts *opts)
22880+{
22881+ struct au_opt *opt;
22882+
22883+ opt = opts->opt;
22884+ while (opt->type != Opt_tail) {
22885+ switch (opt->type) {
22886+ case Opt_add:
22887+ case Opt_append:
22888+ case Opt_prepend:
22889+ path_put(&opt->add.path);
22890+ break;
22891+ case Opt_del:
22892+ case Opt_idel:
22893+ path_put(&opt->del.h_path);
22894+ break;
22895+ case Opt_mod:
22896+ case Opt_imod:
22897+ dput(opt->mod.h_root);
22898+ break;
22899+ case Opt_xino:
22900+ fput(opt->xino.file);
22901+ break;
22902+ }
22903+ opt++;
22904+ }
22905+}
22906+
22907+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
22908+ aufs_bindex_t bindex)
22909+{
22910+ int err;
22911+ struct au_opt_add *add = &opt->add;
22912+ char *p;
22913+
22914+ add->bindex = bindex;
1e00d052 22915+ add->perm = AuBrPerm_RO;
1facf9fc 22916+ add->pathname = opt_str;
22917+ p = strchr(opt_str, '=');
22918+ if (p) {
22919+ *p++ = 0;
22920+ if (*p)
22921+ add->perm = br_perm_val(p);
22922+ }
22923+
22924+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
22925+ if (!err) {
22926+ if (!p) {
22927+ add->perm = AuBrPerm_RO;
22928+ if (au_test_fs_rr(add->path.dentry->d_sb))
22929+ add->perm = AuBrPerm_RR;
22930+ else if (!bindex && !(sb_flags & MS_RDONLY))
22931+ add->perm = AuBrPerm_RW;
22932+ }
22933+ opt->type = Opt_add;
22934+ goto out;
22935+ }
4a4d8108 22936+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 22937+ err = -EINVAL;
22938+
4f0767ce 22939+out:
1facf9fc 22940+ return err;
22941+}
22942+
22943+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
22944+{
22945+ int err;
22946+
22947+ del->pathname = args[0].from;
22948+ AuDbg("del path %s\n", del->pathname);
22949+
22950+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
22951+ if (unlikely(err))
4a4d8108 22952+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 22953+
22954+ return err;
22955+}
22956+
22957+#if 0 /* reserved for future use */
22958+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
22959+ struct au_opt_del *del, substring_t args[])
22960+{
22961+ int err;
22962+ struct dentry *root;
22963+
22964+ err = -EINVAL;
22965+ root = sb->s_root;
22966+ aufs_read_lock(root, AuLock_FLUSH);
22967+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 22968+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 22969+ goto out;
22970+ }
22971+
22972+ err = 0;
22973+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
22974+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
22975+
4f0767ce 22976+out:
1facf9fc 22977+ aufs_read_unlock(root, !AuLock_IR);
22978+ return err;
22979+}
22980+#endif
22981+
4a4d8108
AM
22982+static int noinline_for_stack
22983+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 22984+{
22985+ int err;
22986+ struct path path;
22987+ char *p;
22988+
22989+ err = -EINVAL;
22990+ mod->path = args[0].from;
22991+ p = strchr(mod->path, '=');
22992+ if (unlikely(!p)) {
4a4d8108 22993+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 22994+ goto out;
22995+ }
22996+
22997+ *p++ = 0;
22998+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
22999+ if (unlikely(err)) {
4a4d8108 23000+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 23001+ goto out;
23002+ }
23003+
23004+ mod->perm = br_perm_val(p);
23005+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
23006+ mod->h_root = dget(path.dentry);
23007+ path_put(&path);
23008+
4f0767ce 23009+out:
1facf9fc 23010+ return err;
23011+}
23012+
23013+#if 0 /* reserved for future use */
23014+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
23015+ struct au_opt_mod *mod, substring_t args[])
23016+{
23017+ int err;
23018+ struct dentry *root;
23019+
23020+ err = -EINVAL;
23021+ root = sb->s_root;
23022+ aufs_read_lock(root, AuLock_FLUSH);
23023+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 23024+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 23025+ goto out;
23026+ }
23027+
23028+ err = 0;
23029+ mod->perm = br_perm_val(args[1].from);
23030+ AuDbg("mod path %s, perm 0x%x, %s\n",
23031+ mod->path, mod->perm, args[1].from);
23032+ mod->h_root = dget(au_h_dptr(root, bindex));
23033+
4f0767ce 23034+out:
1facf9fc 23035+ aufs_read_unlock(root, !AuLock_IR);
23036+ return err;
23037+}
23038+#endif
23039+
23040+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
23041+ substring_t args[])
23042+{
23043+ int err;
23044+ struct file *file;
23045+
23046+ file = au_xino_create(sb, args[0].from, /*silent*/0);
23047+ err = PTR_ERR(file);
23048+ if (IS_ERR(file))
23049+ goto out;
23050+
23051+ err = -EINVAL;
2000de60 23052+ if (unlikely(file->f_path.dentry->d_sb == sb)) {
1facf9fc 23053+ fput(file);
4a4d8108 23054+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 23055+ goto out;
23056+ }
23057+
23058+ err = 0;
23059+ xino->file = file;
23060+ xino->path = args[0].from;
23061+
4f0767ce 23062+out:
1facf9fc 23063+ return err;
23064+}
23065+
4a4d8108
AM
23066+static int noinline_for_stack
23067+au_opts_parse_xino_itrunc_path(struct super_block *sb,
23068+ struct au_opt_xino_itrunc *xino_itrunc,
23069+ substring_t args[])
1facf9fc 23070+{
23071+ int err;
23072+ aufs_bindex_t bend, bindex;
23073+ struct path path;
23074+ struct dentry *root;
23075+
23076+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
23077+ if (unlikely(err)) {
4a4d8108 23078+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 23079+ goto out;
23080+ }
23081+
23082+ xino_itrunc->bindex = -1;
23083+ root = sb->s_root;
23084+ aufs_read_lock(root, AuLock_FLUSH);
23085+ bend = au_sbend(sb);
23086+ for (bindex = 0; bindex <= bend; bindex++) {
23087+ if (au_h_dptr(root, bindex) == path.dentry) {
23088+ xino_itrunc->bindex = bindex;
23089+ break;
23090+ }
23091+ }
23092+ aufs_read_unlock(root, !AuLock_IR);
23093+ path_put(&path);
23094+
23095+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 23096+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 23097+ err = -EINVAL;
23098+ }
23099+
4f0767ce 23100+out:
1facf9fc 23101+ return err;
23102+}
23103+
23104+/* called without aufs lock */
23105+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
23106+{
23107+ int err, n, token;
23108+ aufs_bindex_t bindex;
23109+ unsigned char skipped;
23110+ struct dentry *root;
23111+ struct au_opt *opt, *opt_tail;
23112+ char *opt_str;
23113+ /* reduce the stack space */
23114+ union {
23115+ struct au_opt_xino_itrunc *xino_itrunc;
23116+ struct au_opt_wbr_create *create;
23117+ } u;
23118+ struct {
23119+ substring_t args[MAX_OPT_ARGS];
23120+ } *a;
23121+
23122+ err = -ENOMEM;
23123+ a = kmalloc(sizeof(*a), GFP_NOFS);
23124+ if (unlikely(!a))
23125+ goto out;
23126+
23127+ root = sb->s_root;
23128+ err = 0;
23129+ bindex = 0;
23130+ opt = opts->opt;
23131+ opt_tail = opt + opts->max_opt - 1;
23132+ opt->type = Opt_tail;
23133+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
23134+ err = -EINVAL;
23135+ skipped = 0;
23136+ token = match_token(opt_str, options, a->args);
23137+ switch (token) {
23138+ case Opt_br:
23139+ err = 0;
23140+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
23141+ && *opt_str) {
23142+ err = opt_add(opt, opt_str, opts->sb_flags,
23143+ bindex++);
23144+ if (unlikely(!err && ++opt > opt_tail)) {
23145+ err = -E2BIG;
23146+ break;
23147+ }
23148+ opt->type = Opt_tail;
23149+ skipped = 1;
23150+ }
23151+ break;
23152+ case Opt_add:
23153+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23154+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23155+ break;
23156+ }
23157+ bindex = n;
23158+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
23159+ bindex);
23160+ if (!err)
23161+ opt->type = token;
23162+ break;
23163+ case Opt_append:
23164+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
23165+ /*dummy bindex*/1);
23166+ if (!err)
23167+ opt->type = token;
23168+ break;
23169+ case Opt_prepend:
23170+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
23171+ /*bindex*/0);
23172+ if (!err)
23173+ opt->type = token;
23174+ break;
23175+ case Opt_del:
23176+ err = au_opts_parse_del(&opt->del, a->args);
23177+ if (!err)
23178+ opt->type = token;
23179+ break;
23180+#if 0 /* reserved for future use */
23181+ case Opt_idel:
23182+ del->pathname = "(indexed)";
23183+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 23184+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23185+ break;
23186+ }
23187+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
23188+ if (!err)
23189+ opt->type = token;
23190+ break;
23191+#endif
23192+ case Opt_mod:
23193+ err = au_opts_parse_mod(&opt->mod, a->args);
23194+ if (!err)
23195+ opt->type = token;
23196+ break;
23197+#ifdef IMOD /* reserved for future use */
23198+ case Opt_imod:
23199+ u.mod->path = "(indexed)";
23200+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23201+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23202+ break;
23203+ }
23204+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
23205+ if (!err)
23206+ opt->type = token;
23207+ break;
23208+#endif
23209+ case Opt_xino:
23210+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
23211+ if (!err)
23212+ opt->type = token;
23213+ break;
23214+
23215+ case Opt_trunc_xino_path:
23216+ err = au_opts_parse_xino_itrunc_path
23217+ (sb, &opt->xino_itrunc, a->args);
23218+ if (!err)
23219+ opt->type = token;
23220+ break;
23221+
23222+ case Opt_itrunc_xino:
23223+ u.xino_itrunc = &opt->xino_itrunc;
23224+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23225+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23226+ break;
23227+ }
23228+ u.xino_itrunc->bindex = n;
23229+ aufs_read_lock(root, AuLock_FLUSH);
23230+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 23231+ pr_err("out of bounds, %d\n", n);
1facf9fc 23232+ aufs_read_unlock(root, !AuLock_IR);
23233+ break;
23234+ }
23235+ aufs_read_unlock(root, !AuLock_IR);
23236+ err = 0;
23237+ opt->type = token;
23238+ break;
23239+
23240+ case Opt_dirwh:
23241+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
23242+ break;
23243+ err = 0;
23244+ opt->type = token;
23245+ break;
23246+
23247+ case Opt_rdcache:
027c5e7a
AM
23248+ if (unlikely(match_int(&a->args[0], &n))) {
23249+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23250+ break;
027c5e7a
AM
23251+ }
23252+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
23253+ pr_err("rdcache must be smaller than %d\n",
23254+ AUFS_RDCACHE_MAX);
23255+ break;
23256+ }
23257+ opt->rdcache = n;
1facf9fc 23258+ err = 0;
23259+ opt->type = token;
23260+ break;
23261+ case Opt_rdblk:
23262+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23263+ || n < 0
1facf9fc 23264+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 23265+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23266+ break;
23267+ }
1308ab2a 23268+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
23269+ pr_err("rdblk must be larger than %d\n",
23270+ NAME_MAX);
1facf9fc 23271+ break;
23272+ }
23273+ opt->rdblk = n;
23274+ err = 0;
23275+ opt->type = token;
23276+ break;
23277+ case Opt_rdhash:
23278+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23279+ || n < 0
1facf9fc 23280+ || n * sizeof(struct hlist_head)
23281+ > KMALLOC_MAX_SIZE)) {
4a4d8108 23282+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23283+ break;
23284+ }
23285+ opt->rdhash = n;
23286+ err = 0;
23287+ opt->type = token;
23288+ break;
23289+
23290+ case Opt_trunc_xino:
23291+ case Opt_notrunc_xino:
23292+ case Opt_noxino:
23293+ case Opt_trunc_xib:
23294+ case Opt_notrunc_xib:
dece6358
AM
23295+ case Opt_shwh:
23296+ case Opt_noshwh:
076b876e
AM
23297+ case Opt_dirperm1:
23298+ case Opt_nodirperm1:
1facf9fc 23299+ case Opt_plink:
23300+ case Opt_noplink:
23301+ case Opt_list_plink:
4a4d8108
AM
23302+ case Opt_dio:
23303+ case Opt_nodio:
1facf9fc 23304+ case Opt_diropq_a:
23305+ case Opt_diropq_w:
23306+ case Opt_warn_perm:
23307+ case Opt_nowarn_perm:
23308+ case Opt_refrof:
23309+ case Opt_norefrof:
23310+ case Opt_verbose:
23311+ case Opt_noverbose:
23312+ case Opt_sum:
23313+ case Opt_nosum:
23314+ case Opt_wsum:
dece6358
AM
23315+ case Opt_rdblk_def:
23316+ case Opt_rdhash_def:
c1595e42
JR
23317+ case Opt_acl:
23318+ case Opt_noacl:
1facf9fc 23319+ err = 0;
23320+ opt->type = token;
23321+ break;
23322+
23323+ case Opt_udba:
23324+ opt->udba = udba_val(a->args[0].from);
23325+ if (opt->udba >= 0) {
23326+ err = 0;
23327+ opt->type = token;
23328+ } else
4a4d8108 23329+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23330+ break;
23331+
23332+ case Opt_wbr_create:
23333+ u.create = &opt->wbr_create;
23334+ u.create->wbr_create
23335+ = au_wbr_create_val(a->args[0].from, u.create);
23336+ if (u.create->wbr_create >= 0) {
23337+ err = 0;
23338+ opt->type = token;
23339+ } else
4a4d8108 23340+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23341+ break;
23342+ case Opt_wbr_copyup:
23343+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
23344+ if (opt->wbr_copyup >= 0) {
23345+ err = 0;
23346+ opt->type = token;
23347+ } else
4a4d8108 23348+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23349+ break;
23350+
076b876e
AM
23351+ case Opt_fhsm_sec:
23352+ if (unlikely(match_int(&a->args[0], &n)
23353+ || n < 0)) {
23354+ pr_err("bad integer in %s\n", opt_str);
23355+ break;
23356+ }
23357+ if (sysaufs_brs) {
23358+ opt->fhsm_second = n;
23359+ opt->type = token;
23360+ } else
23361+ pr_warn("ignored %s\n", opt_str);
23362+ err = 0;
23363+ break;
23364+
1facf9fc 23365+ case Opt_ignore:
0c3ec466 23366+ pr_warn("ignored %s\n", opt_str);
1facf9fc 23367+ /*FALLTHROUGH*/
23368+ case Opt_ignore_silent:
23369+ skipped = 1;
23370+ err = 0;
23371+ break;
23372+ case Opt_err:
4a4d8108 23373+ pr_err("unknown option %s\n", opt_str);
1facf9fc 23374+ break;
23375+ }
23376+
23377+ if (!err && !skipped) {
23378+ if (unlikely(++opt > opt_tail)) {
23379+ err = -E2BIG;
23380+ opt--;
23381+ opt->type = Opt_tail;
23382+ break;
23383+ }
23384+ opt->type = Opt_tail;
23385+ }
23386+ }
23387+
23388+ kfree(a);
23389+ dump_opts(opts);
23390+ if (unlikely(err))
23391+ au_opts_free(opts);
23392+
4f0767ce 23393+out:
1facf9fc 23394+ return err;
23395+}
23396+
23397+static int au_opt_wbr_create(struct super_block *sb,
23398+ struct au_opt_wbr_create *create)
23399+{
23400+ int err;
23401+ struct au_sbinfo *sbinfo;
23402+
dece6358
AM
23403+ SiMustWriteLock(sb);
23404+
1facf9fc 23405+ err = 1; /* handled */
23406+ sbinfo = au_sbi(sb);
23407+ if (sbinfo->si_wbr_create_ops->fin) {
23408+ err = sbinfo->si_wbr_create_ops->fin(sb);
23409+ if (!err)
23410+ err = 1;
23411+ }
23412+
23413+ sbinfo->si_wbr_create = create->wbr_create;
23414+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
23415+ switch (create->wbr_create) {
23416+ case AuWbrCreate_MFSRRV:
23417+ case AuWbrCreate_MFSRR:
392086de
AM
23418+ case AuWbrCreate_PMFSRR:
23419+ case AuWbrCreate_PMFSRRV:
1facf9fc 23420+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
23421+ /*FALLTHROUGH*/
23422+ case AuWbrCreate_MFS:
23423+ case AuWbrCreate_MFSV:
23424+ case AuWbrCreate_PMFS:
23425+ case AuWbrCreate_PMFSV:
e49829fe
JR
23426+ sbinfo->si_wbr_mfs.mfs_expire
23427+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 23428+ break;
23429+ }
23430+
23431+ if (sbinfo->si_wbr_create_ops->init)
23432+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
23433+
23434+ return err;
23435+}
23436+
23437+/*
23438+ * returns,
23439+ * plus: processed without an error
23440+ * zero: unprocessed
23441+ */
23442+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
23443+ struct au_opts *opts)
23444+{
23445+ int err;
23446+ struct au_sbinfo *sbinfo;
23447+
dece6358
AM
23448+ SiMustWriteLock(sb);
23449+
1facf9fc 23450+ err = 1; /* handled */
23451+ sbinfo = au_sbi(sb);
23452+ switch (opt->type) {
23453+ case Opt_udba:
23454+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
23455+ sbinfo->si_mntflags |= opt->udba;
23456+ opts->given_udba |= opt->udba;
23457+ break;
23458+
23459+ case Opt_plink:
23460+ au_opt_set(sbinfo->si_mntflags, PLINK);
23461+ break;
23462+ case Opt_noplink:
23463+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 23464+ au_plink_put(sb, /*verbose*/1);
1facf9fc 23465+ au_opt_clr(sbinfo->si_mntflags, PLINK);
23466+ break;
23467+ case Opt_list_plink:
23468+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
23469+ au_plink_list(sb);
23470+ break;
23471+
4a4d8108
AM
23472+ case Opt_dio:
23473+ au_opt_set(sbinfo->si_mntflags, DIO);
23474+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23475+ break;
23476+ case Opt_nodio:
23477+ au_opt_clr(sbinfo->si_mntflags, DIO);
23478+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23479+ break;
23480+
076b876e
AM
23481+ case Opt_fhsm_sec:
23482+ au_fhsm_set(sbinfo, opt->fhsm_second);
23483+ break;
23484+
1facf9fc 23485+ case Opt_diropq_a:
23486+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
23487+ break;
23488+ case Opt_diropq_w:
23489+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
23490+ break;
23491+
23492+ case Opt_warn_perm:
23493+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
23494+ break;
23495+ case Opt_nowarn_perm:
23496+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
23497+ break;
23498+
23499+ case Opt_refrof:
23500+ au_opt_set(sbinfo->si_mntflags, REFROF);
23501+ break;
23502+ case Opt_norefrof:
23503+ au_opt_clr(sbinfo->si_mntflags, REFROF);
23504+ break;
23505+
23506+ case Opt_verbose:
23507+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
23508+ break;
23509+ case Opt_noverbose:
23510+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
23511+ break;
23512+
23513+ case Opt_sum:
23514+ au_opt_set(sbinfo->si_mntflags, SUM);
23515+ break;
23516+ case Opt_wsum:
23517+ au_opt_clr(sbinfo->si_mntflags, SUM);
23518+ au_opt_set(sbinfo->si_mntflags, SUM_W);
23519+ case Opt_nosum:
23520+ au_opt_clr(sbinfo->si_mntflags, SUM);
23521+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
23522+ break;
23523+
23524+ case Opt_wbr_create:
23525+ err = au_opt_wbr_create(sb, &opt->wbr_create);
23526+ break;
23527+ case Opt_wbr_copyup:
23528+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
23529+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
23530+ break;
23531+
23532+ case Opt_dirwh:
23533+ sbinfo->si_dirwh = opt->dirwh;
23534+ break;
23535+
23536+ case Opt_rdcache:
e49829fe
JR
23537+ sbinfo->si_rdcache
23538+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 23539+ break;
23540+ case Opt_rdblk:
23541+ sbinfo->si_rdblk = opt->rdblk;
23542+ break;
dece6358
AM
23543+ case Opt_rdblk_def:
23544+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
23545+ break;
1facf9fc 23546+ case Opt_rdhash:
23547+ sbinfo->si_rdhash = opt->rdhash;
23548+ break;
dece6358
AM
23549+ case Opt_rdhash_def:
23550+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
23551+ break;
23552+
23553+ case Opt_shwh:
23554+ au_opt_set(sbinfo->si_mntflags, SHWH);
23555+ break;
23556+ case Opt_noshwh:
23557+ au_opt_clr(sbinfo->si_mntflags, SHWH);
23558+ break;
1facf9fc 23559+
076b876e
AM
23560+ case Opt_dirperm1:
23561+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
23562+ break;
23563+ case Opt_nodirperm1:
23564+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
23565+ break;
23566+
1facf9fc 23567+ case Opt_trunc_xino:
23568+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
23569+ break;
23570+ case Opt_notrunc_xino:
23571+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
23572+ break;
23573+
23574+ case Opt_trunc_xino_path:
23575+ case Opt_itrunc_xino:
23576+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
23577+ if (!err)
23578+ err = 1;
23579+ break;
23580+
23581+ case Opt_trunc_xib:
23582+ au_fset_opts(opts->flags, TRUNC_XIB);
23583+ break;
23584+ case Opt_notrunc_xib:
23585+ au_fclr_opts(opts->flags, TRUNC_XIB);
23586+ break;
23587+
c1595e42
JR
23588+ case Opt_acl:
23589+ sb->s_flags |= MS_POSIXACL;
23590+ break;
23591+ case Opt_noacl:
23592+ sb->s_flags &= ~MS_POSIXACL;
23593+ break;
23594+
1facf9fc 23595+ default:
23596+ err = 0;
23597+ break;
23598+ }
23599+
23600+ return err;
23601+}
23602+
23603+/*
23604+ * returns tri-state.
23605+ * plus: processed without an error
23606+ * zero: unprocessed
23607+ * minus: error
23608+ */
23609+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
23610+ struct au_opts *opts)
23611+{
23612+ int err, do_refresh;
23613+
23614+ err = 0;
23615+ switch (opt->type) {
23616+ case Opt_append:
23617+ opt->add.bindex = au_sbend(sb) + 1;
23618+ if (opt->add.bindex < 0)
23619+ opt->add.bindex = 0;
23620+ goto add;
23621+ case Opt_prepend:
23622+ opt->add.bindex = 0;
f6b6e03d 23623+ add: /* indented label */
1facf9fc 23624+ case Opt_add:
23625+ err = au_br_add(sb, &opt->add,
23626+ au_ftest_opts(opts->flags, REMOUNT));
23627+ if (!err) {
23628+ err = 1;
027c5e7a 23629+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23630+ }
23631+ break;
23632+
23633+ case Opt_del:
23634+ case Opt_idel:
23635+ err = au_br_del(sb, &opt->del,
23636+ au_ftest_opts(opts->flags, REMOUNT));
23637+ if (!err) {
23638+ err = 1;
23639+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 23640+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23641+ }
23642+ break;
23643+
23644+ case Opt_mod:
23645+ case Opt_imod:
23646+ err = au_br_mod(sb, &opt->mod,
23647+ au_ftest_opts(opts->flags, REMOUNT),
23648+ &do_refresh);
23649+ if (!err) {
23650+ err = 1;
027c5e7a
AM
23651+ if (do_refresh)
23652+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23653+ }
23654+ break;
23655+ }
23656+
23657+ return err;
23658+}
23659+
23660+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
23661+ struct au_opt_xino **opt_xino,
23662+ struct au_opts *opts)
23663+{
23664+ int err;
23665+ aufs_bindex_t bend, bindex;
23666+ struct dentry *root, *parent, *h_root;
23667+
23668+ err = 0;
23669+ switch (opt->type) {
23670+ case Opt_xino:
23671+ err = au_xino_set(sb, &opt->xino,
23672+ !!au_ftest_opts(opts->flags, REMOUNT));
23673+ if (unlikely(err))
23674+ break;
23675+
23676+ *opt_xino = &opt->xino;
23677+ au_xino_brid_set(sb, -1);
23678+
23679+ /* safe d_parent access */
2000de60 23680+ parent = opt->xino.file->f_path.dentry->d_parent;
1facf9fc 23681+ root = sb->s_root;
23682+ bend = au_sbend(sb);
23683+ for (bindex = 0; bindex <= bend; bindex++) {
23684+ h_root = au_h_dptr(root, bindex);
23685+ if (h_root == parent) {
23686+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
23687+ break;
23688+ }
23689+ }
23690+ break;
23691+
23692+ case Opt_noxino:
23693+ au_xino_clr(sb);
23694+ au_xino_brid_set(sb, -1);
23695+ *opt_xino = (void *)-1;
23696+ break;
23697+ }
23698+
23699+ return err;
23700+}
23701+
23702+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
23703+ unsigned int pending)
23704+{
076b876e 23705+ int err, fhsm;
1facf9fc 23706+ aufs_bindex_t bindex, bend;
23707+ unsigned char do_plink, skip, do_free;
23708+ struct au_branch *br;
23709+ struct au_wbr *wbr;
23710+ struct dentry *root;
23711+ struct inode *dir, *h_dir;
23712+ struct au_sbinfo *sbinfo;
23713+ struct au_hinode *hdir;
23714+
dece6358
AM
23715+ SiMustAnyLock(sb);
23716+
1facf9fc 23717+ sbinfo = au_sbi(sb);
23718+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
23719+
dece6358
AM
23720+ if (!(sb_flags & MS_RDONLY)) {
23721+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 23722+ pr_warn("first branch should be rw\n");
dece6358 23723+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 23724+ pr_warn("shwh should be used with ro\n");
dece6358 23725+ }
1facf9fc 23726+
4a4d8108 23727+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 23728+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 23729+ pr_warn("udba=*notify requires xino\n");
1facf9fc 23730+
076b876e
AM
23731+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
23732+ pr_warn("dirperm1 breaks the protection"
23733+ " by the permission bits on the lower branch\n");
23734+
1facf9fc 23735+ err = 0;
076b876e 23736+ fhsm = 0;
1facf9fc 23737+ root = sb->s_root;
4a4d8108 23738+ dir = root->d_inode;
1facf9fc 23739+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
23740+ bend = au_sbend(sb);
23741+ for (bindex = 0; !err && bindex <= bend; bindex++) {
23742+ skip = 0;
23743+ h_dir = au_h_iptr(dir, bindex);
23744+ br = au_sbr(sb, bindex);
1facf9fc 23745+
c1595e42
JR
23746+ if ((br->br_perm & AuBrAttr_ICEX)
23747+ && !h_dir->i_op->listxattr)
23748+ br->br_perm &= ~AuBrAttr_ICEX;
23749+#if 0
23750+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
23751+ && (au_br_sb(br)->s_flags & MS_NOSEC))
23752+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
23753+#endif
23754+
23755+ do_free = 0;
1facf9fc 23756+ wbr = br->br_wbr;
23757+ if (wbr)
23758+ wbr_wh_read_lock(wbr);
23759+
1e00d052 23760+ if (!au_br_writable(br->br_perm)) {
1facf9fc 23761+ do_free = !!wbr;
23762+ skip = (!wbr
23763+ || (!wbr->wbr_whbase
23764+ && !wbr->wbr_plink
23765+ && !wbr->wbr_orph));
1e00d052 23766+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 23767+ /* skip = (!br->br_whbase && !br->br_orph); */
23768+ skip = (!wbr || !wbr->wbr_whbase);
23769+ if (skip && wbr) {
23770+ if (do_plink)
23771+ skip = !!wbr->wbr_plink;
23772+ else
23773+ skip = !wbr->wbr_plink;
23774+ }
1e00d052 23775+ } else {
1facf9fc 23776+ /* skip = (br->br_whbase && br->br_ohph); */
23777+ skip = (wbr && wbr->wbr_whbase);
23778+ if (skip) {
23779+ if (do_plink)
23780+ skip = !!wbr->wbr_plink;
23781+ else
23782+ skip = !wbr->wbr_plink;
23783+ }
1facf9fc 23784+ }
23785+ if (wbr)
23786+ wbr_wh_read_unlock(wbr);
23787+
076b876e
AM
23788+ if (au_br_fhsm(br->br_perm)) {
23789+ fhsm++;
23790+ AuDebugOn(!br->br_fhsm);
23791+ }
23792+
1facf9fc 23793+ if (skip)
23794+ continue;
23795+
23796+ hdir = au_hi(dir, bindex);
4a4d8108 23797+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 23798+ if (wbr)
23799+ wbr_wh_write_lock(wbr);
86dc4139 23800+ err = au_wh_init(br, sb);
1facf9fc 23801+ if (wbr)
23802+ wbr_wh_write_unlock(wbr);
4a4d8108 23803+ au_hn_imtx_unlock(hdir);
1facf9fc 23804+
23805+ if (!err && do_free) {
23806+ kfree(wbr);
23807+ br->br_wbr = NULL;
23808+ }
23809+ }
23810+
c1595e42 23811+ if (fhsm >= 2) {
076b876e 23812+ au_fset_si(sbinfo, FHSM);
c1595e42
JR
23813+ for (bindex = bend; bindex >= 0; bindex--) {
23814+ br = au_sbr(sb, bindex);
23815+ if (au_br_fhsm(br->br_perm)) {
23816+ au_fhsm_set_bottom(sb, bindex);
23817+ break;
23818+ }
23819+ }
23820+ } else {
076b876e 23821+ au_fclr_si(sbinfo, FHSM);
c1595e42
JR
23822+ au_fhsm_set_bottom(sb, -1);
23823+ }
076b876e 23824+
1facf9fc 23825+ return err;
23826+}
23827+
23828+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
23829+{
23830+ int err;
23831+ unsigned int tmp;
027c5e7a 23832+ aufs_bindex_t bindex, bend;
1facf9fc 23833+ struct au_opt *opt;
23834+ struct au_opt_xino *opt_xino, xino;
23835+ struct au_sbinfo *sbinfo;
027c5e7a 23836+ struct au_branch *br;
076b876e 23837+ struct inode *dir;
1facf9fc 23838+
dece6358
AM
23839+ SiMustWriteLock(sb);
23840+
1facf9fc 23841+ err = 0;
23842+ opt_xino = NULL;
23843+ opt = opts->opt;
23844+ while (err >= 0 && opt->type != Opt_tail)
23845+ err = au_opt_simple(sb, opt++, opts);
23846+ if (err > 0)
23847+ err = 0;
23848+ else if (unlikely(err < 0))
23849+ goto out;
23850+
23851+ /* disable xino and udba temporary */
23852+ sbinfo = au_sbi(sb);
23853+ tmp = sbinfo->si_mntflags;
23854+ au_opt_clr(sbinfo->si_mntflags, XINO);
23855+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
23856+
23857+ opt = opts->opt;
23858+ while (err >= 0 && opt->type != Opt_tail)
23859+ err = au_opt_br(sb, opt++, opts);
23860+ if (err > 0)
23861+ err = 0;
23862+ else if (unlikely(err < 0))
23863+ goto out;
23864+
23865+ bend = au_sbend(sb);
23866+ if (unlikely(bend < 0)) {
23867+ err = -EINVAL;
4a4d8108 23868+ pr_err("no branches\n");
1facf9fc 23869+ goto out;
23870+ }
23871+
23872+ if (au_opt_test(tmp, XINO))
23873+ au_opt_set(sbinfo->si_mntflags, XINO);
23874+ opt = opts->opt;
23875+ while (!err && opt->type != Opt_tail)
23876+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
23877+ if (unlikely(err))
23878+ goto out;
23879+
23880+ err = au_opts_verify(sb, sb->s_flags, tmp);
23881+ if (unlikely(err))
23882+ goto out;
23883+
23884+ /* restore xino */
23885+ if (au_opt_test(tmp, XINO) && !opt_xino) {
23886+ xino.file = au_xino_def(sb);
23887+ err = PTR_ERR(xino.file);
23888+ if (IS_ERR(xino.file))
23889+ goto out;
23890+
23891+ err = au_xino_set(sb, &xino, /*remount*/0);
23892+ fput(xino.file);
23893+ if (unlikely(err))
23894+ goto out;
23895+ }
23896+
23897+ /* restore udba */
027c5e7a 23898+ tmp &= AuOptMask_UDBA;
1facf9fc 23899+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
23900+ sbinfo->si_mntflags |= tmp;
23901+ bend = au_sbend(sb);
23902+ for (bindex = 0; bindex <= bend; bindex++) {
23903+ br = au_sbr(sb, bindex);
23904+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
23905+ if (unlikely(err))
23906+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
23907+ bindex, err);
23908+ /* go on even if err */
23909+ }
4a4d8108 23910+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
076b876e 23911+ dir = sb->s_root->d_inode;
4a4d8108 23912+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 23913+ }
23914+
4f0767ce 23915+out:
1facf9fc 23916+ return err;
23917+}
23918+
23919+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
23920+{
23921+ int err, rerr;
23922+ struct inode *dir;
23923+ struct au_opt_xino *opt_xino;
23924+ struct au_opt *opt;
23925+ struct au_sbinfo *sbinfo;
23926+
dece6358
AM
23927+ SiMustWriteLock(sb);
23928+
1facf9fc 23929+ dir = sb->s_root->d_inode;
23930+ sbinfo = au_sbi(sb);
23931+ err = 0;
23932+ opt_xino = NULL;
23933+ opt = opts->opt;
23934+ while (err >= 0 && opt->type != Opt_tail) {
23935+ err = au_opt_simple(sb, opt, opts);
23936+ if (!err)
23937+ err = au_opt_br(sb, opt, opts);
23938+ if (!err)
23939+ err = au_opt_xino(sb, opt, &opt_xino, opts);
23940+ opt++;
23941+ }
23942+ if (err > 0)
23943+ err = 0;
23944+ AuTraceErr(err);
23945+ /* go on even err */
23946+
23947+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
23948+ if (unlikely(rerr && !err))
23949+ err = rerr;
23950+
23951+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
23952+ rerr = au_xib_trunc(sb);
23953+ if (unlikely(rerr && !err))
23954+ err = rerr;
23955+ }
23956+
23957+ /* will be handled by the caller */
027c5e7a 23958+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 23959+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 23960+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23961+
23962+ AuDbg("status 0x%x\n", opts->flags);
23963+ return err;
23964+}
23965+
23966+/* ---------------------------------------------------------------------- */
23967+
23968+unsigned int au_opt_udba(struct super_block *sb)
23969+{
23970+ return au_mntflags(sb) & AuOptMask_UDBA;
23971+}
7f207e10
AM
23972diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
23973--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
23974+++ linux/fs/aufs/opts.h 2015-04-13 15:10:20.786823613 +0200
23975@@ -0,0 +1,211 @@
1facf9fc 23976+/*
2000de60 23977+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 23978+ *
23979+ * This program, aufs is free software; you can redistribute it and/or modify
23980+ * it under the terms of the GNU General Public License as published by
23981+ * the Free Software Foundation; either version 2 of the License, or
23982+ * (at your option) any later version.
dece6358
AM
23983+ *
23984+ * This program is distributed in the hope that it will be useful,
23985+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23986+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23987+ * GNU General Public License for more details.
23988+ *
23989+ * You should have received a copy of the GNU General Public License
523b37e3 23990+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 23991+ */
23992+
23993+/*
23994+ * mount options/flags
23995+ */
23996+
23997+#ifndef __AUFS_OPTS_H__
23998+#define __AUFS_OPTS_H__
23999+
24000+#ifdef __KERNEL__
24001+
dece6358 24002+#include <linux/path.h>
1facf9fc 24003+
dece6358
AM
24004+struct file;
24005+struct super_block;
24006+
1facf9fc 24007+/* ---------------------------------------------------------------------- */
24008+
24009+/* mount flags */
24010+#define AuOpt_XINO 1 /* external inode number bitmap
24011+ and translation table */
24012+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
24013+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
24014+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 24015+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
24016+#define AuOpt_SHWH (1 << 5) /* show whiteout */
24017+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
24018+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
24019+ bits */
dece6358
AM
24020+#define AuOpt_REFROF (1 << 8) /* unimplemented */
24021+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
24022+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
24023+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
24024+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
24025+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 24026+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 24027+
4a4d8108
AM
24028+#ifndef CONFIG_AUFS_HNOTIFY
24029+#undef AuOpt_UDBA_HNOTIFY
24030+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 24031+#endif
dece6358
AM
24032+#ifndef CONFIG_AUFS_SHWH
24033+#undef AuOpt_SHWH
24034+#define AuOpt_SHWH 0
24035+#endif
1facf9fc 24036+
24037+#define AuOpt_Def (AuOpt_XINO \
24038+ | AuOpt_UDBA_REVAL \
24039+ | AuOpt_PLINK \
24040+ /* | AuOpt_DIRPERM1 */ \
24041+ | AuOpt_WARN_PERM)
24042+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
24043+ | AuOpt_UDBA_REVAL \
4a4d8108 24044+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 24045+
24046+#define au_opt_test(flags, name) (flags & AuOpt_##name)
24047+#define au_opt_set(flags, name) do { \
24048+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
24049+ ((flags) |= AuOpt_##name); \
24050+} while (0)
24051+#define au_opt_set_udba(flags, name) do { \
24052+ (flags) &= ~AuOptMask_UDBA; \
24053+ ((flags) |= AuOpt_##name); \
24054+} while (0)
7f207e10
AM
24055+#define au_opt_clr(flags, name) do { \
24056+ ((flags) &= ~AuOpt_##name); \
24057+} while (0)
1facf9fc 24058+
e49829fe
JR
24059+static inline unsigned int au_opts_plink(unsigned int mntflags)
24060+{
24061+#ifdef CONFIG_PROC_FS
24062+ return mntflags;
24063+#else
24064+ return mntflags & ~AuOpt_PLINK;
24065+#endif
24066+}
24067+
1facf9fc 24068+/* ---------------------------------------------------------------------- */
24069+
24070+/* policies to select one among multiple writable branches */
24071+enum {
24072+ AuWbrCreate_TDP, /* top down parent */
24073+ AuWbrCreate_RR, /* round robin */
24074+ AuWbrCreate_MFS, /* most free space */
24075+ AuWbrCreate_MFSV, /* mfs with seconds */
24076+ AuWbrCreate_MFSRR, /* mfs then rr */
24077+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
24078+ AuWbrCreate_PMFS, /* parent and mfs */
24079+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
24080+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
24081+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 24082+
24083+ AuWbrCreate_Def = AuWbrCreate_TDP
24084+};
24085+
24086+enum {
24087+ AuWbrCopyup_TDP, /* top down parent */
24088+ AuWbrCopyup_BUP, /* bottom up parent */
24089+ AuWbrCopyup_BU, /* bottom up */
24090+
24091+ AuWbrCopyup_Def = AuWbrCopyup_TDP
24092+};
24093+
24094+/* ---------------------------------------------------------------------- */
24095+
24096+struct au_opt_add {
24097+ aufs_bindex_t bindex;
24098+ char *pathname;
24099+ int perm;
24100+ struct path path;
24101+};
24102+
24103+struct au_opt_del {
24104+ char *pathname;
24105+ struct path h_path;
24106+};
24107+
24108+struct au_opt_mod {
24109+ char *path;
24110+ int perm;
24111+ struct dentry *h_root;
24112+};
24113+
24114+struct au_opt_xino {
24115+ char *path;
24116+ struct file *file;
24117+};
24118+
24119+struct au_opt_xino_itrunc {
24120+ aufs_bindex_t bindex;
24121+};
24122+
24123+struct au_opt_wbr_create {
24124+ int wbr_create;
24125+ int mfs_second;
24126+ unsigned long long mfsrr_watermark;
24127+};
24128+
24129+struct au_opt {
24130+ int type;
24131+ union {
24132+ struct au_opt_xino xino;
24133+ struct au_opt_xino_itrunc xino_itrunc;
24134+ struct au_opt_add add;
24135+ struct au_opt_del del;
24136+ struct au_opt_mod mod;
24137+ int dirwh;
24138+ int rdcache;
24139+ unsigned int rdblk;
24140+ unsigned int rdhash;
24141+ int udba;
24142+ struct au_opt_wbr_create wbr_create;
24143+ int wbr_copyup;
076b876e 24144+ unsigned int fhsm_second;
1facf9fc 24145+ };
24146+};
24147+
24148+/* opts flags */
24149+#define AuOpts_REMOUNT 1
027c5e7a
AM
24150+#define AuOpts_REFRESH (1 << 1)
24151+#define AuOpts_TRUNC_XIB (1 << 2)
24152+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 24153+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
24154+#define au_fset_opts(flags, name) \
24155+ do { (flags) |= AuOpts_##name; } while (0)
24156+#define au_fclr_opts(flags, name) \
24157+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 24158+
24159+struct au_opts {
24160+ struct au_opt *opt;
24161+ int max_opt;
24162+
24163+ unsigned int given_udba;
24164+ unsigned int flags;
24165+ unsigned long sb_flags;
24166+};
24167+
24168+/* ---------------------------------------------------------------------- */
24169+
7e9cd9fe 24170+/* opts.c */
076b876e 24171+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 24172+const char *au_optstr_udba(int udba);
24173+const char *au_optstr_wbr_copyup(int wbr_copyup);
24174+const char *au_optstr_wbr_create(int wbr_create);
24175+
24176+void au_opts_free(struct au_opts *opts);
24177+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
24178+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
24179+ unsigned int pending);
24180+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
24181+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
24182+
24183+unsigned int au_opt_udba(struct super_block *sb);
24184+
1facf9fc 24185+#endif /* __KERNEL__ */
24186+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
24187diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
24188--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 24189+++ linux/fs/aufs/plink.c 2015-04-13 15:10:20.790157026 +0200
523b37e3 24190@@ -0,0 +1,532 @@
1facf9fc 24191+/*
2000de60 24192+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 24193+ *
24194+ * This program, aufs is free software; you can redistribute it and/or modify
24195+ * it under the terms of the GNU General Public License as published by
24196+ * the Free Software Foundation; either version 2 of the License, or
24197+ * (at your option) any later version.
dece6358
AM
24198+ *
24199+ * This program is distributed in the hope that it will be useful,
24200+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24201+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24202+ * GNU General Public License for more details.
24203+ *
24204+ * You should have received a copy of the GNU General Public License
523b37e3 24205+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24206+ */
24207+
24208+/*
24209+ * pseudo-link
24210+ */
24211+
24212+#include "aufs.h"
24213+
24214+/*
e49829fe 24215+ * the pseudo-link maintenance mode.
1facf9fc 24216+ * during a user process maintains the pseudo-links,
24217+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
24218+ *
24219+ * Flags
24220+ * NOPLM:
24221+ * For entry functions which will handle plink, and i_mutex is already held
24222+ * in VFS.
24223+ * They cannot wait and should return an error at once.
24224+ * Callers has to check the error.
24225+ * NOPLMW:
24226+ * For entry functions which will handle plink, but i_mutex is not held
24227+ * in VFS.
24228+ * They can wait the plink maintenance mode to finish.
24229+ *
24230+ * They behave like F_SETLK and F_SETLKW.
24231+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 24232+ */
e49829fe
JR
24233+
24234+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 24235+{
e49829fe
JR
24236+ int err;
24237+ pid_t pid, ppid;
24238+ struct au_sbinfo *sbi;
dece6358
AM
24239+
24240+ SiMustAnyLock(sb);
24241+
e49829fe
JR
24242+ err = 0;
24243+ if (!au_opt_test(au_mntflags(sb), PLINK))
24244+ goto out;
24245+
24246+ sbi = au_sbi(sb);
24247+ pid = sbi->si_plink_maint_pid;
24248+ if (!pid || pid == current->pid)
24249+ goto out;
24250+
24251+ /* todo: it highly depends upon /sbin/mount.aufs */
24252+ rcu_read_lock();
24253+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
24254+ rcu_read_unlock();
24255+ if (pid == ppid)
24256+ goto out;
24257+
24258+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
24259+ /* if there is no i_mutex lock in VFS, we don't need to wait */
24260+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
24261+ while (sbi->si_plink_maint_pid) {
24262+ si_read_unlock(sb);
24263+ /* gave up wake_up_bit() */
24264+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
24265+
24266+ if (au_ftest_lock(flags, FLUSH))
24267+ au_nwt_flush(&sbi->si_nowait);
24268+ si_noflush_read_lock(sb);
24269+ }
24270+ } else if (au_ftest_lock(flags, NOPLM)) {
24271+ AuDbg("ppid %d, pid %d\n", ppid, pid);
24272+ err = -EAGAIN;
24273+ }
24274+
24275+out:
24276+ return err;
4a4d8108
AM
24277+}
24278+
e49829fe 24279+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 24280+{
4a4d8108 24281+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 24282+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 24283+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 24284+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
24285+}
24286+
e49829fe 24287+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
24288+{
24289+ int err;
4a4d8108
AM
24290+ struct au_sbinfo *sbinfo;
24291+
24292+ err = 0;
4a4d8108
AM
24293+ sbinfo = au_sbi(sb);
24294+ /* make sure i am the only one in this fs */
e49829fe
JR
24295+ si_write_lock(sb, AuLock_FLUSH);
24296+ if (au_opt_test(au_mntflags(sb), PLINK)) {
24297+ spin_lock(&sbinfo->si_plink_maint_lock);
24298+ if (!sbinfo->si_plink_maint_pid)
24299+ sbinfo->si_plink_maint_pid = current->pid;
24300+ else
24301+ err = -EBUSY;
24302+ spin_unlock(&sbinfo->si_plink_maint_lock);
24303+ }
4a4d8108
AM
24304+ si_write_unlock(sb);
24305+
24306+ return err;
1facf9fc 24307+}
24308+
24309+/* ---------------------------------------------------------------------- */
24310+
1facf9fc 24311+#ifdef CONFIG_AUFS_DEBUG
24312+void au_plink_list(struct super_block *sb)
24313+{
86dc4139 24314+ int i;
1facf9fc 24315+ struct au_sbinfo *sbinfo;
86dc4139 24316+ struct hlist_head *plink_hlist;
1facf9fc 24317+ struct pseudo_link *plink;
24318+
dece6358
AM
24319+ SiMustAnyLock(sb);
24320+
1facf9fc 24321+ sbinfo = au_sbi(sb);
24322+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24323+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24324+
86dc4139
AM
24325+ for (i = 0; i < AuPlink_NHASH; i++) {
24326+ plink_hlist = &sbinfo->si_plink[i].head;
24327+ rcu_read_lock();
24328+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
24329+ AuDbg("%lu\n", plink->inode->i_ino);
24330+ rcu_read_unlock();
24331+ }
1facf9fc 24332+}
24333+#endif
24334+
24335+/* is the inode pseudo-linked? */
24336+int au_plink_test(struct inode *inode)
24337+{
86dc4139 24338+ int found, i;
1facf9fc 24339+ struct au_sbinfo *sbinfo;
86dc4139 24340+ struct hlist_head *plink_hlist;
1facf9fc 24341+ struct pseudo_link *plink;
24342+
24343+ sbinfo = au_sbi(inode->i_sb);
dece6358 24344+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 24345+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 24346+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 24347+
24348+ found = 0;
86dc4139
AM
24349+ i = au_plink_hash(inode->i_ino);
24350+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 24351+ rcu_read_lock();
86dc4139 24352+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 24353+ if (plink->inode == inode) {
24354+ found = 1;
24355+ break;
24356+ }
4a4d8108 24357+ rcu_read_unlock();
1facf9fc 24358+ return found;
24359+}
24360+
24361+/* ---------------------------------------------------------------------- */
24362+
24363+/*
24364+ * generate a name for plink.
24365+ * the file will be stored under AUFS_WH_PLINKDIR.
24366+ */
24367+/* 20 is max digits length of ulong 64 */
24368+#define PLINK_NAME_LEN ((20 + 1) * 2)
24369+
24370+static int plink_name(char *name, int len, struct inode *inode,
24371+ aufs_bindex_t bindex)
24372+{
24373+ int rlen;
24374+ struct inode *h_inode;
24375+
24376+ h_inode = au_h_iptr(inode, bindex);
24377+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
24378+ return rlen;
24379+}
24380+
7f207e10
AM
24381+struct au_do_plink_lkup_args {
24382+ struct dentry **errp;
24383+ struct qstr *tgtname;
24384+ struct dentry *h_parent;
24385+ struct au_branch *br;
24386+};
24387+
24388+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
24389+ struct dentry *h_parent,
24390+ struct au_branch *br)
24391+{
24392+ struct dentry *h_dentry;
24393+ struct mutex *h_mtx;
24394+
24395+ h_mtx = &h_parent->d_inode->i_mutex;
24396+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 24397+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
24398+ mutex_unlock(h_mtx);
24399+ return h_dentry;
24400+}
24401+
24402+static void au_call_do_plink_lkup(void *args)
24403+{
24404+ struct au_do_plink_lkup_args *a = args;
24405+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
24406+}
24407+
1facf9fc 24408+/* lookup the plink-ed @inode under the branch at @bindex */
24409+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
24410+{
24411+ struct dentry *h_dentry, *h_parent;
24412+ struct au_branch *br;
24413+ struct inode *h_dir;
7f207e10 24414+ int wkq_err;
1facf9fc 24415+ char a[PLINK_NAME_LEN];
0c3ec466 24416+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24417+
e49829fe
JR
24418+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
24419+
1facf9fc 24420+ br = au_sbr(inode->i_sb, bindex);
24421+ h_parent = br->br_wbr->wbr_plink;
24422+ h_dir = h_parent->d_inode;
24423+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24424+
2dfbb274 24425+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
24426+ struct au_do_plink_lkup_args args = {
24427+ .errp = &h_dentry,
24428+ .tgtname = &tgtname,
24429+ .h_parent = h_parent,
24430+ .br = br
24431+ };
24432+
24433+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
24434+ if (unlikely(wkq_err))
24435+ h_dentry = ERR_PTR(wkq_err);
24436+ } else
24437+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
24438+
1facf9fc 24439+ return h_dentry;
24440+}
24441+
24442+/* create a pseudo-link */
24443+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
24444+ struct dentry *h_dentry, struct au_branch *br)
24445+{
24446+ int err;
24447+ struct path h_path = {
86dc4139 24448+ .mnt = au_br_mnt(br)
1facf9fc 24449+ };
523b37e3 24450+ struct inode *h_dir, *delegated;
1facf9fc 24451+
24452+ h_dir = h_parent->d_inode;
7f207e10 24453+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 24454+again:
b4510431 24455+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 24456+ err = PTR_ERR(h_path.dentry);
24457+ if (IS_ERR(h_path.dentry))
24458+ goto out;
24459+
24460+ err = 0;
24461+ /* wh.plink dir is not monitored */
7f207e10 24462+ /* todo: is it really safe? */
1facf9fc 24463+ if (h_path.dentry->d_inode
24464+ && h_path.dentry->d_inode != h_dentry->d_inode) {
523b37e3
AM
24465+ delegated = NULL;
24466+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
24467+ if (unlikely(err == -EWOULDBLOCK)) {
24468+ pr_warn("cannot retry for NFSv4 delegation"
24469+ " for an internal unlink\n");
24470+ iput(delegated);
24471+ }
1facf9fc 24472+ dput(h_path.dentry);
24473+ h_path.dentry = NULL;
24474+ if (!err)
24475+ goto again;
24476+ }
523b37e3
AM
24477+ if (!err && !h_path.dentry->d_inode) {
24478+ delegated = NULL;
24479+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
24480+ if (unlikely(err == -EWOULDBLOCK)) {
24481+ pr_warn("cannot retry for NFSv4 delegation"
24482+ " for an internal link\n");
24483+ iput(delegated);
24484+ }
24485+ }
1facf9fc 24486+ dput(h_path.dentry);
24487+
4f0767ce 24488+out:
7f207e10 24489+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 24490+ return err;
24491+}
24492+
24493+struct do_whplink_args {
24494+ int *errp;
24495+ struct qstr *tgt;
24496+ struct dentry *h_parent;
24497+ struct dentry *h_dentry;
24498+ struct au_branch *br;
24499+};
24500+
24501+static void call_do_whplink(void *args)
24502+{
24503+ struct do_whplink_args *a = args;
24504+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
24505+}
24506+
24507+static int whplink(struct dentry *h_dentry, struct inode *inode,
24508+ aufs_bindex_t bindex, struct au_branch *br)
24509+{
24510+ int err, wkq_err;
24511+ struct au_wbr *wbr;
24512+ struct dentry *h_parent;
24513+ struct inode *h_dir;
24514+ char a[PLINK_NAME_LEN];
0c3ec466 24515+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24516+
24517+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
24518+ h_parent = wbr->wbr_plink;
24519+ h_dir = h_parent->d_inode;
24520+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24521+
24522+ /* always superio. */
2dfbb274 24523+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 24524+ struct do_whplink_args args = {
24525+ .errp = &err,
24526+ .tgt = &tgtname,
24527+ .h_parent = h_parent,
24528+ .h_dentry = h_dentry,
24529+ .br = br
24530+ };
24531+ wkq_err = au_wkq_wait(call_do_whplink, &args);
24532+ if (unlikely(wkq_err))
24533+ err = wkq_err;
24534+ } else
24535+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 24536+
24537+ return err;
24538+}
24539+
24540+/* free a single plink */
24541+static void do_put_plink(struct pseudo_link *plink, int do_del)
24542+{
1facf9fc 24543+ if (do_del)
86dc4139 24544+ hlist_del(&plink->hlist);
4a4d8108
AM
24545+ iput(plink->inode);
24546+ kfree(plink);
24547+}
24548+
24549+static void do_put_plink_rcu(struct rcu_head *rcu)
24550+{
24551+ struct pseudo_link *plink;
24552+
24553+ plink = container_of(rcu, struct pseudo_link, rcu);
24554+ iput(plink->inode);
1facf9fc 24555+ kfree(plink);
24556+}
24557+
24558+/*
24559+ * create a new pseudo-link for @h_dentry on @bindex.
24560+ * the linked inode is held in aufs @inode.
24561+ */
24562+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
24563+ struct dentry *h_dentry)
24564+{
24565+ struct super_block *sb;
24566+ struct au_sbinfo *sbinfo;
86dc4139 24567+ struct hlist_head *plink_hlist;
4a4d8108 24568+ struct pseudo_link *plink, *tmp;
86dc4139
AM
24569+ struct au_sphlhead *sphl;
24570+ int found, err, cnt, i;
1facf9fc 24571+
24572+ sb = inode->i_sb;
24573+ sbinfo = au_sbi(sb);
24574+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24575+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24576+
86dc4139 24577+ found = au_plink_test(inode);
4a4d8108 24578+ if (found)
1facf9fc 24579+ return;
4a4d8108 24580+
86dc4139
AM
24581+ i = au_plink_hash(inode->i_ino);
24582+ sphl = sbinfo->si_plink + i;
24583+ plink_hlist = &sphl->head;
4a4d8108
AM
24584+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
24585+ if (tmp)
24586+ tmp->inode = au_igrab(inode);
24587+ else {
24588+ err = -ENOMEM;
24589+ goto out;
1facf9fc 24590+ }
24591+
86dc4139
AM
24592+ spin_lock(&sphl->spin);
24593+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
24594+ if (plink->inode == inode) {
24595+ found = 1;
24596+ break;
24597+ }
1facf9fc 24598+ }
4a4d8108 24599+ if (!found)
86dc4139
AM
24600+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
24601+ spin_unlock(&sphl->spin);
4a4d8108 24602+ if (!found) {
86dc4139
AM
24603+ cnt = au_sphl_count(sphl);
24604+#define msg "unexpectedly unblanced or too many pseudo-links"
24605+ if (cnt > AUFS_PLINK_WARN)
24606+ AuWarn1(msg ", %d\n", cnt);
24607+#undef msg
1facf9fc 24608+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
24609+ } else {
24610+ do_put_plink(tmp, 0);
24611+ return;
1facf9fc 24612+ }
24613+
4a4d8108 24614+out:
1facf9fc 24615+ if (unlikely(err)) {
0c3ec466 24616+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 24617+ if (tmp) {
86dc4139 24618+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
24619+ call_rcu(&tmp->rcu, do_put_plink_rcu);
24620+ }
1facf9fc 24621+ }
24622+}
24623+
24624+/* free all plinks */
e49829fe 24625+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 24626+{
86dc4139 24627+ int i, warned;
1facf9fc 24628+ struct au_sbinfo *sbinfo;
86dc4139
AM
24629+ struct hlist_head *plink_hlist;
24630+ struct hlist_node *tmp;
24631+ struct pseudo_link *plink;
1facf9fc 24632+
dece6358
AM
24633+ SiMustWriteLock(sb);
24634+
1facf9fc 24635+ sbinfo = au_sbi(sb);
24636+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24637+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24638+
1facf9fc 24639+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
24640+ warned = 0;
24641+ for (i = 0; i < AuPlink_NHASH; i++) {
24642+ plink_hlist = &sbinfo->si_plink[i].head;
24643+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
24644+ pr_warn("pseudo-link is not flushed");
24645+ warned = 1;
24646+ }
24647+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
24648+ do_put_plink(plink, 0);
24649+ INIT_HLIST_HEAD(plink_hlist);
24650+ }
1facf9fc 24651+}
24652+
e49829fe
JR
24653+void au_plink_clean(struct super_block *sb, int verbose)
24654+{
24655+ struct dentry *root;
24656+
24657+ root = sb->s_root;
24658+ aufs_write_lock(root);
24659+ if (au_opt_test(au_mntflags(sb), PLINK))
24660+ au_plink_put(sb, verbose);
24661+ aufs_write_unlock(root);
24662+}
24663+
86dc4139
AM
24664+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
24665+{
24666+ int do_put;
24667+ aufs_bindex_t bstart, bend, bindex;
24668+
24669+ do_put = 0;
24670+ bstart = au_ibstart(inode);
24671+ bend = au_ibend(inode);
24672+ if (bstart >= 0) {
24673+ for (bindex = bstart; bindex <= bend; bindex++) {
24674+ if (!au_h_iptr(inode, bindex)
24675+ || au_ii_br_id(inode, bindex) != br_id)
24676+ continue;
24677+ au_set_h_iptr(inode, bindex, NULL, 0);
24678+ do_put = 1;
24679+ break;
24680+ }
24681+ if (do_put)
24682+ for (bindex = bstart; bindex <= bend; bindex++)
24683+ if (au_h_iptr(inode, bindex)) {
24684+ do_put = 0;
24685+ break;
24686+ }
24687+ } else
24688+ do_put = 1;
24689+
24690+ return do_put;
24691+}
24692+
1facf9fc 24693+/* free the plinks on a branch specified by @br_id */
24694+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
24695+{
24696+ struct au_sbinfo *sbinfo;
86dc4139
AM
24697+ struct hlist_head *plink_hlist;
24698+ struct hlist_node *tmp;
24699+ struct pseudo_link *plink;
1facf9fc 24700+ struct inode *inode;
86dc4139 24701+ int i, do_put;
1facf9fc 24702+
dece6358
AM
24703+ SiMustWriteLock(sb);
24704+
1facf9fc 24705+ sbinfo = au_sbi(sb);
24706+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24707+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24708+
1facf9fc 24709+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
24710+ for (i = 0; i < AuPlink_NHASH; i++) {
24711+ plink_hlist = &sbinfo->si_plink[i].head;
24712+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
24713+ inode = au_igrab(plink->inode);
24714+ ii_write_lock_child(inode);
24715+ do_put = au_plink_do_half_refresh(inode, br_id);
dece6358
AM
24716+ if (do_put)
24717+ do_put_plink(plink, 1);
86dc4139
AM
24718+ ii_write_unlock(inode);
24719+ iput(inode);
dece6358 24720+ }
dece6358
AM
24721+ }
24722+}
7f207e10
AM
24723diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
24724--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 24725+++ linux/fs/aufs/poll.c 2015-04-13 15:10:20.790157026 +0200
523b37e3 24726@@ -0,0 +1,55 @@
dece6358 24727+/*
2000de60 24728+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
24729+ *
24730+ * This program, aufs is free software; you can redistribute it and/or modify
24731+ * it under the terms of the GNU General Public License as published by
24732+ * the Free Software Foundation; either version 2 of the License, or
24733+ * (at your option) any later version.
24734+ *
24735+ * This program is distributed in the hope that it will be useful,
24736+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24737+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24738+ * GNU General Public License for more details.
24739+ *
24740+ * You should have received a copy of the GNU General Public License
523b37e3 24741+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
24742+ */
24743+
1308ab2a 24744+/*
24745+ * poll operation
24746+ * There is only one filesystem which implements ->poll operation, currently.
24747+ */
24748+
24749+#include "aufs.h"
24750+
24751+unsigned int aufs_poll(struct file *file, poll_table *wait)
24752+{
24753+ unsigned int mask;
24754+ int err;
24755+ struct file *h_file;
24756+ struct dentry *dentry;
24757+ struct super_block *sb;
24758+
24759+ /* We should pretend an error happened. */
24760+ mask = POLLERR /* | POLLIN | POLLOUT */;
2000de60 24761+ dentry = file->f_path.dentry;
1308ab2a 24762+ sb = dentry->d_sb;
e49829fe 24763+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 24764+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
24765+ if (unlikely(err))
24766+ goto out;
24767+
24768+ /* it is not an error if h_file has no operation */
24769+ mask = DEFAULT_POLLMASK;
4a4d8108 24770+ h_file = au_hf_top(file);
523b37e3 24771+ if (h_file->f_op->poll)
1308ab2a 24772+ mask = h_file->f_op->poll(h_file, wait);
24773+
24774+ di_read_unlock(dentry, AuLock_IR);
24775+ fi_read_unlock(file);
24776+
4f0767ce 24777+out:
1308ab2a 24778+ si_read_unlock(sb);
24779+ AuTraceErr((int)mask);
24780+ return mask;
24781+}
c1595e42
JR
24782diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
24783--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 24784+++ linux/fs/aufs/posix_acl.c 2015-04-13 15:10:20.790157026 +0200
c1595e42
JR
24785@@ -0,0 +1,99 @@
24786+/*
2000de60 24787+ * Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
24788+ *
24789+ * This program, aufs is free software; you can redistribute it and/or modify
24790+ * it under the terms of the GNU General Public License as published by
24791+ * the Free Software Foundation; either version 2 of the License, or
24792+ * (at your option) any later version.
24793+ *
24794+ * This program is distributed in the hope that it will be useful,
24795+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24796+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24797+ * GNU General Public License for more details.
24798+ *
24799+ * You should have received a copy of the GNU General Public License
24800+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24801+ */
24802+
24803+/*
24804+ * posix acl operations
24805+ */
24806+
24807+#include <linux/fs.h>
24808+#include <linux/posix_acl.h>
24809+#include "aufs.h"
24810+
24811+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
24812+{
24813+ struct posix_acl *acl;
24814+ int err;
24815+ aufs_bindex_t bindex;
24816+ struct inode *h_inode;
24817+ struct super_block *sb;
24818+
24819+ acl = NULL;
24820+ sb = inode->i_sb;
24821+ si_read_lock(sb, AuLock_FLUSH);
24822+ ii_read_lock_child(inode);
24823+ if (!(sb->s_flags & MS_POSIXACL))
24824+ goto out;
24825+
24826+ bindex = au_ibstart(inode);
24827+ h_inode = au_h_iptr(inode, bindex);
24828+ if (unlikely(!h_inode
24829+ || ((h_inode->i_mode & S_IFMT)
24830+ != (inode->i_mode & S_IFMT)))) {
24831+ err = au_busy_or_stale();
24832+ acl = ERR_PTR(err);
24833+ goto out;
24834+ }
24835+
24836+ /* always topmost only */
24837+ acl = get_acl(h_inode, type);
24838+
24839+out:
24840+ ii_read_unlock(inode);
24841+ si_read_unlock(sb);
24842+
24843+ AuTraceErrPtr(acl);
24844+ return acl;
24845+}
24846+
24847+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
24848+{
24849+ int err;
24850+ ssize_t ssz;
24851+ struct dentry *dentry;
24852+ struct au_srxattr arg = {
24853+ .type = AU_ACL_SET,
24854+ .u.acl_set = {
24855+ .acl = acl,
24856+ .type = type
24857+ },
24858+ };
24859+
24860+ mutex_lock(&inode->i_mutex);
24861+ if (inode->i_ino == AUFS_ROOT_INO)
24862+ dentry = dget(inode->i_sb->s_root);
24863+ else {
24864+ dentry = d_find_alias(inode);
24865+ if (!dentry)
24866+ dentry = d_find_any_alias(inode);
24867+ if (!dentry) {
24868+ pr_warn("cannot handle this inode, "
24869+ "please report to aufs-users ML\n");
24870+ err = -ENOENT;
24871+ goto out;
24872+ }
24873+ }
24874+
24875+ ssz = au_srxattr(dentry, &arg);
24876+ dput(dentry);
24877+ err = ssz;
24878+ if (ssz >= 0)
24879+ err = 0;
24880+
24881+out:
24882+ mutex_unlock(&inode->i_mutex);
24883+ return err;
24884+}
7f207e10
AM
24885diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
24886--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 24887+++ linux/fs/aufs/procfs.c 2015-04-13 15:10:20.790157026 +0200
523b37e3 24888@@ -0,0 +1,169 @@
e49829fe 24889+/*
2000de60 24890+ * Copyright (C) 2010-2015 Junjiro R. Okajima
e49829fe
JR
24891+ *
24892+ * This program, aufs is free software; you can redistribute it and/or modify
24893+ * it under the terms of the GNU General Public License as published by
24894+ * the Free Software Foundation; either version 2 of the License, or
24895+ * (at your option) any later version.
24896+ *
24897+ * This program is distributed in the hope that it will be useful,
24898+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24899+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24900+ * GNU General Public License for more details.
24901+ *
24902+ * You should have received a copy of the GNU General Public License
523b37e3 24903+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
24904+ */
24905+
24906+/*
24907+ * procfs interfaces
24908+ */
24909+
24910+#include <linux/proc_fs.h>
24911+#include "aufs.h"
24912+
24913+static int au_procfs_plm_release(struct inode *inode, struct file *file)
24914+{
24915+ struct au_sbinfo *sbinfo;
24916+
24917+ sbinfo = file->private_data;
24918+ if (sbinfo) {
24919+ au_plink_maint_leave(sbinfo);
24920+ kobject_put(&sbinfo->si_kobj);
24921+ }
24922+
24923+ return 0;
24924+}
24925+
24926+static void au_procfs_plm_write_clean(struct file *file)
24927+{
24928+ struct au_sbinfo *sbinfo;
24929+
24930+ sbinfo = file->private_data;
24931+ if (sbinfo)
24932+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
24933+}
24934+
24935+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
24936+{
24937+ int err;
24938+ struct super_block *sb;
24939+ struct au_sbinfo *sbinfo;
24940+
24941+ err = -EBUSY;
24942+ if (unlikely(file->private_data))
24943+ goto out;
24944+
24945+ sb = NULL;
53392da6 24946+ /* don't use au_sbilist_lock() here */
e49829fe
JR
24947+ spin_lock(&au_sbilist.spin);
24948+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
24949+ if (id == sysaufs_si_id(sbinfo)) {
24950+ kobject_get(&sbinfo->si_kobj);
24951+ sb = sbinfo->si_sb;
24952+ break;
24953+ }
24954+ spin_unlock(&au_sbilist.spin);
24955+
24956+ err = -EINVAL;
24957+ if (unlikely(!sb))
24958+ goto out;
24959+
24960+ err = au_plink_maint_enter(sb);
24961+ if (!err)
24962+ /* keep kobject_get() */
24963+ file->private_data = sbinfo;
24964+ else
24965+ kobject_put(&sbinfo->si_kobj);
24966+out:
24967+ return err;
24968+}
24969+
24970+/*
24971+ * Accept a valid "si=xxxx" only.
24972+ * Once it is accepted successfully, accept "clean" too.
24973+ */
24974+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
24975+ size_t count, loff_t *ppos)
24976+{
24977+ ssize_t err;
24978+ unsigned long id;
24979+ /* last newline is allowed */
24980+ char buf[3 + sizeof(unsigned long) * 2 + 1];
24981+
24982+ err = -EACCES;
24983+ if (unlikely(!capable(CAP_SYS_ADMIN)))
24984+ goto out;
24985+
24986+ err = -EINVAL;
24987+ if (unlikely(count > sizeof(buf)))
24988+ goto out;
24989+
24990+ err = copy_from_user(buf, ubuf, count);
24991+ if (unlikely(err)) {
24992+ err = -EFAULT;
24993+ goto out;
24994+ }
24995+ buf[count] = 0;
24996+
24997+ err = -EINVAL;
24998+ if (!strcmp("clean", buf)) {
24999+ au_procfs_plm_write_clean(file);
25000+ goto out_success;
25001+ } else if (unlikely(strncmp("si=", buf, 3)))
25002+ goto out;
25003+
9dbd164d 25004+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
25005+ if (unlikely(err))
25006+ goto out;
25007+
25008+ err = au_procfs_plm_write_si(file, id);
25009+ if (unlikely(err))
25010+ goto out;
25011+
25012+out_success:
25013+ err = count; /* success */
25014+out:
25015+ return err;
25016+}
25017+
25018+static const struct file_operations au_procfs_plm_fop = {
25019+ .write = au_procfs_plm_write,
25020+ .release = au_procfs_plm_release,
25021+ .owner = THIS_MODULE
25022+};
25023+
25024+/* ---------------------------------------------------------------------- */
25025+
25026+static struct proc_dir_entry *au_procfs_dir;
25027+
25028+void au_procfs_fin(void)
25029+{
25030+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
25031+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
25032+}
25033+
25034+int __init au_procfs_init(void)
25035+{
25036+ int err;
25037+ struct proc_dir_entry *entry;
25038+
25039+ err = -ENOMEM;
25040+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
25041+ if (unlikely(!au_procfs_dir))
25042+ goto out;
25043+
25044+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
25045+ au_procfs_dir, &au_procfs_plm_fop);
25046+ if (unlikely(!entry))
25047+ goto out_dir;
25048+
25049+ err = 0;
25050+ goto out; /* success */
25051+
25052+
25053+out_dir:
25054+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
25055+out:
25056+ return err;
25057+}
7f207e10
AM
25058diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
25059--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 25060+++ linux/fs/aufs/rdu.c 2015-04-13 15:10:20.790157026 +0200
523b37e3 25061@@ -0,0 +1,388 @@
1308ab2a 25062+/*
2000de60 25063+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1308ab2a 25064+ *
25065+ * This program, aufs is free software; you can redistribute it and/or modify
25066+ * it under the terms of the GNU General Public License as published by
25067+ * the Free Software Foundation; either version 2 of the License, or
25068+ * (at your option) any later version.
25069+ *
25070+ * This program is distributed in the hope that it will be useful,
25071+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25072+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25073+ * GNU General Public License for more details.
25074+ *
25075+ * You should have received a copy of the GNU General Public License
523b37e3 25076+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 25077+ */
25078+
25079+/*
25080+ * readdir in userspace.
25081+ */
25082+
b752ccd1 25083+#include <linux/compat.h>
4a4d8108 25084+#include <linux/fs_stack.h>
1308ab2a 25085+#include <linux/security.h>
1308ab2a 25086+#include "aufs.h"
25087+
25088+/* bits for struct aufs_rdu.flags */
25089+#define AuRdu_CALLED 1
25090+#define AuRdu_CONT (1 << 1)
25091+#define AuRdu_FULL (1 << 2)
25092+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
25093+#define au_fset_rdu(flags, name) \
25094+ do { (flags) |= AuRdu_##name; } while (0)
25095+#define au_fclr_rdu(flags, name) \
25096+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 25097+
25098+struct au_rdu_arg {
392086de 25099+ struct dir_context ctx;
1308ab2a 25100+ struct aufs_rdu *rdu;
25101+ union au_rdu_ent_ul ent;
25102+ unsigned long end;
25103+
25104+ struct super_block *sb;
25105+ int err;
25106+};
25107+
392086de 25108+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 25109+ loff_t offset, u64 h_ino, unsigned int d_type)
25110+{
25111+ int err, len;
392086de 25112+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 25113+ struct aufs_rdu *rdu = arg->rdu;
25114+ struct au_rdu_ent ent;
25115+
25116+ err = 0;
25117+ arg->err = 0;
25118+ au_fset_rdu(rdu->cookie.flags, CALLED);
25119+ len = au_rdu_len(nlen);
25120+ if (arg->ent.ul + len < arg->end) {
25121+ ent.ino = h_ino;
25122+ ent.bindex = rdu->cookie.bindex;
25123+ ent.type = d_type;
25124+ ent.nlen = nlen;
4a4d8108
AM
25125+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
25126+ ent.type = DT_UNKNOWN;
1308ab2a 25127+
9dbd164d 25128+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25129+ err = -EFAULT;
25130+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
25131+ goto out;
25132+ if (copy_to_user(arg->ent.e->name, name, nlen))
25133+ goto out;
25134+ /* the terminating NULL */
25135+ if (__put_user(0, arg->ent.e->name + nlen))
25136+ goto out;
25137+ err = 0;
25138+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
25139+ arg->ent.ul += len;
25140+ rdu->rent++;
25141+ } else {
25142+ err = -EFAULT;
25143+ au_fset_rdu(rdu->cookie.flags, FULL);
25144+ rdu->full = 1;
25145+ rdu->tail = arg->ent;
25146+ }
25147+
4f0767ce 25148+out:
1308ab2a 25149+ /* AuTraceErr(err); */
25150+ return err;
25151+}
25152+
25153+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
25154+{
25155+ int err;
25156+ loff_t offset;
25157+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
25158+
92d182d2 25159+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 25160+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
25161+ err = offset;
25162+ if (unlikely(offset != cookie->h_pos))
25163+ goto out;
25164+
25165+ err = 0;
25166+ do {
25167+ arg->err = 0;
25168+ au_fclr_rdu(cookie->flags, CALLED);
25169+ /* smp_mb(); */
392086de 25170+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 25171+ if (err >= 0)
25172+ err = arg->err;
25173+ } while (!err
25174+ && au_ftest_rdu(cookie->flags, CALLED)
25175+ && !au_ftest_rdu(cookie->flags, FULL));
25176+ cookie->h_pos = h_file->f_pos;
25177+
4f0767ce 25178+out:
1308ab2a 25179+ AuTraceErr(err);
25180+ return err;
25181+}
25182+
25183+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
25184+{
25185+ int err;
25186+ aufs_bindex_t bend;
392086de
AM
25187+ struct au_rdu_arg arg = {
25188+ .ctx = {
2000de60 25189+ .actor = au_rdu_fill
392086de
AM
25190+ }
25191+ };
1308ab2a 25192+ struct dentry *dentry;
25193+ struct inode *inode;
25194+ struct file *h_file;
25195+ struct au_rdu_cookie *cookie = &rdu->cookie;
25196+
25197+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
25198+ if (unlikely(err)) {
25199+ err = -EFAULT;
25200+ AuTraceErr(err);
25201+ goto out;
25202+ }
25203+ rdu->rent = 0;
25204+ rdu->tail = rdu->ent;
25205+ rdu->full = 0;
25206+ arg.rdu = rdu;
25207+ arg.ent = rdu->ent;
25208+ arg.end = arg.ent.ul;
25209+ arg.end += rdu->sz;
25210+
25211+ err = -ENOTDIR;
523b37e3 25212+ if (unlikely(!file->f_op->iterate))
1308ab2a 25213+ goto out;
25214+
25215+ err = security_file_permission(file, MAY_READ);
25216+ AuTraceErr(err);
25217+ if (unlikely(err))
25218+ goto out;
25219+
2000de60 25220+ dentry = file->f_path.dentry;
1308ab2a 25221+ inode = dentry->d_inode;
25222+#if 1
25223+ mutex_lock(&inode->i_mutex);
25224+#else
25225+ err = mutex_lock_killable(&inode->i_mutex);
25226+ AuTraceErr(err);
25227+ if (unlikely(err))
25228+ goto out;
25229+#endif
1308ab2a 25230+
25231+ arg.sb = inode->i_sb;
e49829fe
JR
25232+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
25233+ if (unlikely(err))
25234+ goto out_mtx;
027c5e7a
AM
25235+ err = au_alive_dir(dentry);
25236+ if (unlikely(err))
25237+ goto out_si;
e49829fe 25238+ /* todo: reval? */
1308ab2a 25239+ fi_read_lock(file);
25240+
25241+ err = -EAGAIN;
25242+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
25243+ && cookie->generation != au_figen(file)))
25244+ goto out_unlock;
25245+
25246+ err = 0;
25247+ if (!rdu->blk) {
25248+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
25249+ if (!rdu->blk)
25250+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
25251+ }
25252+ bend = au_fbstart(file);
25253+ if (cookie->bindex < bend)
25254+ cookie->bindex = bend;
4a4d8108 25255+ bend = au_fbend_dir(file);
1308ab2a 25256+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
25257+ for (; !err && cookie->bindex <= bend;
25258+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 25259+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 25260+ if (!h_file)
25261+ continue;
25262+
25263+ au_fclr_rdu(cookie->flags, FULL);
25264+ err = au_rdu_do(h_file, &arg);
25265+ AuTraceErr(err);
25266+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
25267+ break;
25268+ }
25269+ AuDbg("rent %llu\n", rdu->rent);
25270+
25271+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
25272+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
25273+ au_fset_rdu(cookie->flags, CONT);
25274+ cookie->generation = au_figen(file);
25275+ }
25276+
25277+ ii_read_lock_child(inode);
25278+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
25279+ ii_read_unlock(inode);
25280+
4f0767ce 25281+out_unlock:
1308ab2a 25282+ fi_read_unlock(file);
027c5e7a 25283+out_si:
1308ab2a 25284+ si_read_unlock(arg.sb);
4f0767ce 25285+out_mtx:
1308ab2a 25286+ mutex_unlock(&inode->i_mutex);
4f0767ce 25287+out:
1308ab2a 25288+ AuTraceErr(err);
25289+ return err;
25290+}
25291+
25292+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
25293+{
25294+ int err;
25295+ ino_t ino;
25296+ unsigned long long nent;
25297+ union au_rdu_ent_ul *u;
25298+ struct au_rdu_ent ent;
25299+ struct super_block *sb;
25300+
25301+ err = 0;
25302+ nent = rdu->nent;
25303+ u = &rdu->ent;
2000de60 25304+ sb = file->f_path.dentry->d_sb;
1308ab2a 25305+ si_read_lock(sb, AuLock_FLUSH);
25306+ while (nent-- > 0) {
9dbd164d 25307+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25308+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
25309+ if (!err)
25310+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 25311+ if (unlikely(err)) {
25312+ err = -EFAULT;
25313+ AuTraceErr(err);
25314+ break;
25315+ }
25316+
25317+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
25318+ if (!ent.wh)
25319+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
25320+ else
25321+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
25322+ &ino);
25323+ if (unlikely(err)) {
25324+ AuTraceErr(err);
25325+ break;
25326+ }
25327+
25328+ err = __put_user(ino, &u->e->ino);
25329+ if (unlikely(err)) {
25330+ err = -EFAULT;
25331+ AuTraceErr(err);
25332+ break;
25333+ }
25334+ u->ul += au_rdu_len(ent.nlen);
25335+ }
25336+ si_read_unlock(sb);
25337+
25338+ return err;
25339+}
25340+
25341+/* ---------------------------------------------------------------------- */
25342+
25343+static int au_rdu_verify(struct aufs_rdu *rdu)
25344+{
b752ccd1 25345+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 25346+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 25347+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 25348+ rdu->blk,
25349+ rdu->rent, rdu->shwh, rdu->full,
25350+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
25351+ rdu->cookie.generation);
dece6358 25352+
b752ccd1 25353+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 25354+ return 0;
dece6358 25355+
b752ccd1
AM
25356+ AuDbg("%u:%u\n",
25357+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 25358+ return -EINVAL;
25359+}
25360+
25361+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 25362+{
1308ab2a 25363+ long err, e;
25364+ struct aufs_rdu rdu;
25365+ void __user *p = (void __user *)arg;
dece6358 25366+
1308ab2a 25367+ err = copy_from_user(&rdu, p, sizeof(rdu));
25368+ if (unlikely(err)) {
25369+ err = -EFAULT;
25370+ AuTraceErr(err);
25371+ goto out;
25372+ }
25373+ err = au_rdu_verify(&rdu);
dece6358
AM
25374+ if (unlikely(err))
25375+ goto out;
25376+
1308ab2a 25377+ switch (cmd) {
25378+ case AUFS_CTL_RDU:
25379+ err = au_rdu(file, &rdu);
25380+ if (unlikely(err))
25381+ break;
dece6358 25382+
1308ab2a 25383+ e = copy_to_user(p, &rdu, sizeof(rdu));
25384+ if (unlikely(e)) {
25385+ err = -EFAULT;
25386+ AuTraceErr(err);
25387+ }
25388+ break;
25389+ case AUFS_CTL_RDU_INO:
25390+ err = au_rdu_ino(file, &rdu);
25391+ break;
25392+
25393+ default:
4a4d8108 25394+ /* err = -ENOTTY; */
1308ab2a 25395+ err = -EINVAL;
25396+ }
dece6358 25397+
4f0767ce 25398+out:
1308ab2a 25399+ AuTraceErr(err);
25400+ return err;
1facf9fc 25401+}
b752ccd1
AM
25402+
25403+#ifdef CONFIG_COMPAT
25404+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
25405+{
25406+ long err, e;
25407+ struct aufs_rdu rdu;
25408+ void __user *p = compat_ptr(arg);
25409+
25410+ /* todo: get_user()? */
25411+ err = copy_from_user(&rdu, p, sizeof(rdu));
25412+ if (unlikely(err)) {
25413+ err = -EFAULT;
25414+ AuTraceErr(err);
25415+ goto out;
25416+ }
25417+ rdu.ent.e = compat_ptr(rdu.ent.ul);
25418+ err = au_rdu_verify(&rdu);
25419+ if (unlikely(err))
25420+ goto out;
25421+
25422+ switch (cmd) {
25423+ case AUFS_CTL_RDU:
25424+ err = au_rdu(file, &rdu);
25425+ if (unlikely(err))
25426+ break;
25427+
25428+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
25429+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
25430+ e = copy_to_user(p, &rdu, sizeof(rdu));
25431+ if (unlikely(e)) {
25432+ err = -EFAULT;
25433+ AuTraceErr(err);
25434+ }
25435+ break;
25436+ case AUFS_CTL_RDU_INO:
25437+ err = au_rdu_ino(file, &rdu);
25438+ break;
25439+
25440+ default:
25441+ /* err = -ENOTTY; */
25442+ err = -EINVAL;
25443+ }
25444+
4f0767ce 25445+out:
b752ccd1
AM
25446+ AuTraceErr(err);
25447+ return err;
25448+}
25449+#endif
7f207e10
AM
25450diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
25451--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 25452+++ linux/fs/aufs/rwsem.h 2015-04-13 15:10:20.790157026 +0200
076b876e 25453@@ -0,0 +1,191 @@
1facf9fc 25454+/*
2000de60 25455+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 25456+ *
25457+ * This program, aufs is free software; you can redistribute it and/or modify
25458+ * it under the terms of the GNU General Public License as published by
25459+ * the Free Software Foundation; either version 2 of the License, or
25460+ * (at your option) any later version.
dece6358
AM
25461+ *
25462+ * This program is distributed in the hope that it will be useful,
25463+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25464+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25465+ * GNU General Public License for more details.
25466+ *
25467+ * You should have received a copy of the GNU General Public License
523b37e3 25468+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25469+ */
25470+
25471+/*
25472+ * simple read-write semaphore wrappers
25473+ */
25474+
25475+#ifndef __AUFS_RWSEM_H__
25476+#define __AUFS_RWSEM_H__
25477+
25478+#ifdef __KERNEL__
25479+
4a4d8108 25480+#include "debug.h"
dece6358
AM
25481+
25482+struct au_rwsem {
25483+ struct rw_semaphore rwsem;
25484+#ifdef CONFIG_AUFS_DEBUG
25485+ /* just for debugging, not almighty counter */
25486+ atomic_t rcnt, wcnt;
25487+#endif
25488+};
25489+
25490+#ifdef CONFIG_AUFS_DEBUG
25491+#define AuDbgCntInit(rw) do { \
25492+ atomic_set(&(rw)->rcnt, 0); \
25493+ atomic_set(&(rw)->wcnt, 0); \
25494+ smp_mb(); /* atomic set */ \
25495+} while (0)
25496+
e49829fe 25497+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 25498+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 25499+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
25500+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
25501+#else
25502+#define AuDbgCntInit(rw) do {} while (0)
25503+#define AuDbgRcntInc(rw) do {} while (0)
25504+#define AuDbgRcntDec(rw) do {} while (0)
25505+#define AuDbgWcntInc(rw) do {} while (0)
25506+#define AuDbgWcntDec(rw) do {} while (0)
25507+#endif /* CONFIG_AUFS_DEBUG */
25508+
25509+/* to debug easier, do not make them inlined functions */
25510+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
25511+/* rwsem_is_locked() is unusable */
25512+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
25513+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
25514+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
25515+ && atomic_read(&(rw)->wcnt) <= 0)
25516+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
25517+ || atomic_read(&(rw)->wcnt))
25518+
e49829fe
JR
25519+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
25520+
dece6358
AM
25521+static inline void au_rw_init(struct au_rwsem *rw)
25522+{
25523+ AuDbgCntInit(rw);
25524+ init_rwsem(&rw->rwsem);
25525+}
25526+
25527+static inline void au_rw_init_wlock(struct au_rwsem *rw)
25528+{
25529+ au_rw_init(rw);
25530+ down_write(&rw->rwsem);
25531+ AuDbgWcntInc(rw);
25532+}
25533+
25534+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
25535+ unsigned int lsc)
25536+{
25537+ au_rw_init(rw);
25538+ down_write_nested(&rw->rwsem, lsc);
25539+ AuDbgWcntInc(rw);
25540+}
25541+
25542+static inline void au_rw_read_lock(struct au_rwsem *rw)
25543+{
25544+ down_read(&rw->rwsem);
25545+ AuDbgRcntInc(rw);
25546+}
25547+
25548+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
25549+{
25550+ down_read_nested(&rw->rwsem, lsc);
25551+ AuDbgRcntInc(rw);
25552+}
25553+
25554+static inline void au_rw_read_unlock(struct au_rwsem *rw)
25555+{
25556+ AuRwMustReadLock(rw);
25557+ AuDbgRcntDec(rw);
25558+ up_read(&rw->rwsem);
25559+}
25560+
25561+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
25562+{
25563+ AuRwMustWriteLock(rw);
25564+ AuDbgRcntInc(rw);
25565+ AuDbgWcntDec(rw);
25566+ downgrade_write(&rw->rwsem);
25567+}
25568+
25569+static inline void au_rw_write_lock(struct au_rwsem *rw)
25570+{
25571+ down_write(&rw->rwsem);
25572+ AuDbgWcntInc(rw);
25573+}
25574+
25575+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
25576+ unsigned int lsc)
25577+{
25578+ down_write_nested(&rw->rwsem, lsc);
25579+ AuDbgWcntInc(rw);
25580+}
1facf9fc 25581+
dece6358
AM
25582+static inline void au_rw_write_unlock(struct au_rwsem *rw)
25583+{
25584+ AuRwMustWriteLock(rw);
25585+ AuDbgWcntDec(rw);
25586+ up_write(&rw->rwsem);
25587+}
25588+
25589+/* why is not _nested version defined */
25590+static inline int au_rw_read_trylock(struct au_rwsem *rw)
25591+{
076b876e
AM
25592+ int ret;
25593+
25594+ ret = down_read_trylock(&rw->rwsem);
dece6358
AM
25595+ if (ret)
25596+ AuDbgRcntInc(rw);
25597+ return ret;
25598+}
25599+
25600+static inline int au_rw_write_trylock(struct au_rwsem *rw)
25601+{
076b876e
AM
25602+ int ret;
25603+
25604+ ret = down_write_trylock(&rw->rwsem);
dece6358
AM
25605+ if (ret)
25606+ AuDbgWcntInc(rw);
25607+ return ret;
25608+}
25609+
25610+#undef AuDbgCntInit
25611+#undef AuDbgRcntInc
25612+#undef AuDbgRcntDec
25613+#undef AuDbgWcntInc
25614+#undef AuDbgWcntDec
1facf9fc 25615+
25616+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
25617+static inline void prefix##_read_lock(param) \
dece6358 25618+{ au_rw_read_lock(rwsem); } \
1facf9fc 25619+static inline void prefix##_write_lock(param) \
dece6358 25620+{ au_rw_write_lock(rwsem); } \
1facf9fc 25621+static inline int prefix##_read_trylock(param) \
dece6358 25622+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 25623+static inline int prefix##_write_trylock(param) \
dece6358 25624+{ return au_rw_write_trylock(rwsem); }
1facf9fc 25625+/* why is not _nested version defined */
25626+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 25627+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 25628+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 25629+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 25630+
25631+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
25632+static inline void prefix##_read_unlock(param) \
dece6358 25633+{ au_rw_read_unlock(rwsem); } \
1facf9fc 25634+static inline void prefix##_write_unlock(param) \
dece6358 25635+{ au_rw_write_unlock(rwsem); } \
1facf9fc 25636+static inline void prefix##_downgrade_lock(param) \
dece6358 25637+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 25638+
25639+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
25640+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
25641+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
25642+
25643+#endif /* __KERNEL__ */
25644+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
25645diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
25646--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
25647+++ linux/fs/aufs/sbinfo.c 2015-04-13 15:10:20.790157026 +0200
25648@@ -0,0 +1,352 @@
1facf9fc 25649+/*
2000de60 25650+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 25651+ *
25652+ * This program, aufs is free software; you can redistribute it and/or modify
25653+ * it under the terms of the GNU General Public License as published by
25654+ * the Free Software Foundation; either version 2 of the License, or
25655+ * (at your option) any later version.
dece6358
AM
25656+ *
25657+ * This program is distributed in the hope that it will be useful,
25658+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25659+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25660+ * GNU General Public License for more details.
25661+ *
25662+ * You should have received a copy of the GNU General Public License
523b37e3 25663+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25664+ */
25665+
25666+/*
25667+ * superblock private data
25668+ */
25669+
25670+#include "aufs.h"
25671+
25672+/*
25673+ * they are necessary regardless sysfs is disabled.
25674+ */
25675+void au_si_free(struct kobject *kobj)
25676+{
86dc4139 25677+ int i;
1facf9fc 25678+ struct au_sbinfo *sbinfo;
b752ccd1 25679+ char *locked __maybe_unused; /* debug only */
1facf9fc 25680+
25681+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
25682+ for (i = 0; i < AuPlink_NHASH; i++)
25683+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 25684+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 25685+
e49829fe 25686+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 25687+ au_br_free(sbinfo);
e49829fe 25688+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
25689+
25690+ AuDebugOn(radix_tree_gang_lookup
25691+ (&sbinfo->au_si_pid.tree, (void **)&locked,
25692+ /*first_index*/PID_MAX_DEFAULT - 1,
25693+ /*max_items*/sizeof(locked)/sizeof(*locked)));
25694+
1facf9fc 25695+ kfree(sbinfo->si_branch);
b752ccd1 25696+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 25697+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 25698+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 25699+
25700+ kfree(sbinfo);
25701+}
25702+
25703+int au_si_alloc(struct super_block *sb)
25704+{
86dc4139 25705+ int err, i;
1facf9fc 25706+ struct au_sbinfo *sbinfo;
e49829fe 25707+ static struct lock_class_key aufs_si;
1facf9fc 25708+
25709+ err = -ENOMEM;
4a4d8108 25710+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 25711+ if (unlikely(!sbinfo))
25712+ goto out;
25713+
b752ccd1
AM
25714+ BUILD_BUG_ON(sizeof(unsigned long) !=
25715+ sizeof(*sbinfo->au_si_pid.bitmap));
25716+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
25717+ sizeof(*sbinfo->au_si_pid.bitmap),
25718+ GFP_NOFS);
25719+ if (unlikely(!sbinfo->au_si_pid.bitmap))
25720+ goto out_sbinfo;
25721+
1facf9fc 25722+ /* will be reallocated separately */
25723+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
25724+ if (unlikely(!sbinfo->si_branch))
b752ccd1 25725+ goto out_pidmap;
1facf9fc 25726+
1facf9fc 25727+ err = sysaufs_si_init(sbinfo);
25728+ if (unlikely(err))
25729+ goto out_br;
25730+
25731+ au_nwt_init(&sbinfo->si_nowait);
dece6358 25732+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 25733+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
25734+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
25735+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
25736+
7f207e10 25737+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
25738+ atomic_long_set(&sbinfo->si_nfiles, 0);
25739+
1facf9fc 25740+ sbinfo->si_bend = -1;
392086de 25741+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 25742+
25743+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
25744+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
25745+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
25746+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 25747+
076b876e
AM
25748+ au_fhsm_init(sbinfo);
25749+
e49829fe 25750+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 25751+
392086de
AM
25752+ sbinfo->si_xino_jiffy = jiffies;
25753+ sbinfo->si_xino_expire
25754+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 25755+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 25756+ sbinfo->si_xino_brid = -1;
25757+ /* leave si_xib_last_pindex and si_xib_next_bit */
25758+
e49829fe 25759+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 25760+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
25761+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
25762+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
25763+
86dc4139
AM
25764+ for (i = 0; i < AuPlink_NHASH; i++)
25765+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 25766+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 25767+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 25768+
523b37e3
AM
25769+ au_sphl_init(&sbinfo->si_files);
25770+
1facf9fc 25771+ /* leave other members for sysaufs and si_mnt. */
25772+ sbinfo->si_sb = sb;
25773+ sb->s_fs_info = sbinfo;
b752ccd1 25774+ si_pid_set(sb);
1facf9fc 25775+ return 0; /* success */
25776+
4f0767ce 25777+out_br:
1facf9fc 25778+ kfree(sbinfo->si_branch);
4f0767ce 25779+out_pidmap:
b752ccd1 25780+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 25781+out_sbinfo:
1facf9fc 25782+ kfree(sbinfo);
4f0767ce 25783+out:
1facf9fc 25784+ return err;
25785+}
25786+
25787+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
25788+{
25789+ int err, sz;
25790+ struct au_branch **brp;
25791+
dece6358
AM
25792+ AuRwMustWriteLock(&sbinfo->si_rwsem);
25793+
1facf9fc 25794+ err = -ENOMEM;
25795+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
25796+ if (unlikely(!sz))
25797+ sz = sizeof(*brp);
25798+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
25799+ if (brp) {
25800+ sbinfo->si_branch = brp;
25801+ err = 0;
25802+ }
25803+
25804+ return err;
25805+}
25806+
25807+/* ---------------------------------------------------------------------- */
25808+
25809+unsigned int au_sigen_inc(struct super_block *sb)
25810+{
25811+ unsigned int gen;
25812+
dece6358
AM
25813+ SiMustWriteLock(sb);
25814+
1facf9fc 25815+ gen = ++au_sbi(sb)->si_generation;
25816+ au_update_digen(sb->s_root);
537831f9 25817+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 25818+ sb->s_root->d_inode->i_version++;
25819+ return gen;
25820+}
25821+
25822+aufs_bindex_t au_new_br_id(struct super_block *sb)
25823+{
25824+ aufs_bindex_t br_id;
25825+ int i;
25826+ struct au_sbinfo *sbinfo;
25827+
dece6358
AM
25828+ SiMustWriteLock(sb);
25829+
1facf9fc 25830+ sbinfo = au_sbi(sb);
25831+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
25832+ br_id = ++sbinfo->si_last_br_id;
7f207e10 25833+ AuDebugOn(br_id < 0);
1facf9fc 25834+ if (br_id && au_br_index(sb, br_id) < 0)
25835+ return br_id;
25836+ }
25837+
25838+ return -1;
25839+}
25840+
25841+/* ---------------------------------------------------------------------- */
25842+
e49829fe
JR
25843+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
25844+int si_read_lock(struct super_block *sb, int flags)
25845+{
25846+ int err;
25847+
25848+ err = 0;
25849+ if (au_ftest_lock(flags, FLUSH))
25850+ au_nwt_flush(&au_sbi(sb)->si_nowait);
25851+
25852+ si_noflush_read_lock(sb);
25853+ err = au_plink_maint(sb, flags);
25854+ if (unlikely(err))
25855+ si_read_unlock(sb);
25856+
25857+ return err;
25858+}
25859+
25860+int si_write_lock(struct super_block *sb, int flags)
25861+{
25862+ int err;
25863+
25864+ if (au_ftest_lock(flags, FLUSH))
25865+ au_nwt_flush(&au_sbi(sb)->si_nowait);
25866+
25867+ si_noflush_write_lock(sb);
25868+ err = au_plink_maint(sb, flags);
25869+ if (unlikely(err))
25870+ si_write_unlock(sb);
25871+
25872+ return err;
25873+}
25874+
1facf9fc 25875+/* dentry and super_block lock. call at entry point */
e49829fe 25876+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 25877+{
e49829fe 25878+ int err;
027c5e7a 25879+ struct super_block *sb;
e49829fe 25880+
027c5e7a
AM
25881+ sb = dentry->d_sb;
25882+ err = si_read_lock(sb, flags);
25883+ if (unlikely(err))
25884+ goto out;
25885+
25886+ if (au_ftest_lock(flags, DW))
25887+ di_write_lock_child(dentry);
25888+ else
25889+ di_read_lock_child(dentry, flags);
25890+
25891+ if (au_ftest_lock(flags, GEN)) {
25892+ err = au_digen_test(dentry, au_sigen(sb));
25893+ AuDebugOn(!err && au_dbrange_test(dentry));
25894+ if (unlikely(err))
25895+ aufs_read_unlock(dentry, flags);
e49829fe
JR
25896+ }
25897+
027c5e7a 25898+out:
e49829fe 25899+ return err;
1facf9fc 25900+}
25901+
25902+void aufs_read_unlock(struct dentry *dentry, int flags)
25903+{
25904+ if (au_ftest_lock(flags, DW))
25905+ di_write_unlock(dentry);
25906+ else
25907+ di_read_unlock(dentry, flags);
25908+ si_read_unlock(dentry->d_sb);
25909+}
25910+
25911+void aufs_write_lock(struct dentry *dentry)
25912+{
e49829fe 25913+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 25914+ di_write_lock_child(dentry);
25915+}
25916+
25917+void aufs_write_unlock(struct dentry *dentry)
25918+{
25919+ di_write_unlock(dentry);
25920+ si_write_unlock(dentry->d_sb);
25921+}
25922+
e49829fe 25923+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 25924+{
e49829fe 25925+ int err;
027c5e7a
AM
25926+ unsigned int sigen;
25927+ struct super_block *sb;
e49829fe 25928+
027c5e7a
AM
25929+ sb = d1->d_sb;
25930+ err = si_read_lock(sb, flags);
25931+ if (unlikely(err))
25932+ goto out;
25933+
25934+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
25935+
25936+ if (au_ftest_lock(flags, GEN)) {
25937+ sigen = au_sigen(sb);
25938+ err = au_digen_test(d1, sigen);
25939+ AuDebugOn(!err && au_dbrange_test(d1));
25940+ if (!err) {
25941+ err = au_digen_test(d2, sigen);
25942+ AuDebugOn(!err && au_dbrange_test(d2));
25943+ }
25944+ if (unlikely(err))
25945+ aufs_read_and_write_unlock2(d1, d2);
25946+ }
25947+
25948+out:
e49829fe 25949+ return err;
1facf9fc 25950+}
25951+
25952+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
25953+{
25954+ di_write_unlock2(d1, d2);
25955+ si_read_unlock(d1->d_sb);
25956+}
b752ccd1
AM
25957+
25958+/* ---------------------------------------------------------------------- */
25959+
25960+int si_pid_test_slow(struct super_block *sb)
25961+{
25962+ void *p;
25963+
25964+ rcu_read_lock();
25965+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
25966+ rcu_read_unlock();
25967+
027c5e7a 25968+ return (long)!!p;
b752ccd1
AM
25969+}
25970+
25971+void si_pid_set_slow(struct super_block *sb)
25972+{
25973+ int err;
25974+ struct au_sbinfo *sbinfo;
25975+
25976+ AuDebugOn(si_pid_test_slow(sb));
25977+
25978+ sbinfo = au_sbi(sb);
25979+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
25980+ AuDebugOn(err);
25981+ spin_lock(&sbinfo->au_si_pid.tree_lock);
25982+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 25983+ /*any valid ptr*/sb);
b752ccd1
AM
25984+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
25985+ AuDebugOn(err);
25986+ radix_tree_preload_end();
25987+}
25988+
25989+void si_pid_clr_slow(struct super_block *sb)
25990+{
25991+ void *p;
25992+ struct au_sbinfo *sbinfo;
25993+
25994+ AuDebugOn(!si_pid_test_slow(sb));
25995+
25996+ sbinfo = au_sbi(sb);
25997+ spin_lock(&sbinfo->au_si_pid.tree_lock);
25998+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
25999+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 26000+}
7f207e10
AM
26001diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
26002--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 26003+++ linux/fs/aufs/spl.h 2015-04-13 15:10:20.790157026 +0200
523b37e3 26004@@ -0,0 +1,111 @@
1facf9fc 26005+/*
2000de60 26006+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 26007+ *
26008+ * This program, aufs is free software; you can redistribute it and/or modify
26009+ * it under the terms of the GNU General Public License as published by
26010+ * the Free Software Foundation; either version 2 of the License, or
26011+ * (at your option) any later version.
dece6358
AM
26012+ *
26013+ * This program is distributed in the hope that it will be useful,
26014+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26015+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26016+ * GNU General Public License for more details.
26017+ *
26018+ * You should have received a copy of the GNU General Public License
523b37e3 26019+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26020+ */
26021+
26022+/*
26023+ * simple list protected by a spinlock
26024+ */
26025+
26026+#ifndef __AUFS_SPL_H__
26027+#define __AUFS_SPL_H__
26028+
26029+#ifdef __KERNEL__
26030+
1facf9fc 26031+struct au_splhead {
26032+ spinlock_t spin;
26033+ struct list_head head;
26034+};
26035+
26036+static inline void au_spl_init(struct au_splhead *spl)
26037+{
26038+ spin_lock_init(&spl->spin);
26039+ INIT_LIST_HEAD(&spl->head);
26040+}
26041+
26042+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
26043+{
26044+ spin_lock(&spl->spin);
26045+ list_add(list, &spl->head);
26046+ spin_unlock(&spl->spin);
26047+}
26048+
26049+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
26050+{
26051+ spin_lock(&spl->spin);
26052+ list_del(list);
26053+ spin_unlock(&spl->spin);
26054+}
26055+
4a4d8108
AM
26056+static inline void au_spl_del_rcu(struct list_head *list,
26057+ struct au_splhead *spl)
26058+{
26059+ spin_lock(&spl->spin);
26060+ list_del_rcu(list);
26061+ spin_unlock(&spl->spin);
26062+}
26063+
86dc4139
AM
26064+/* ---------------------------------------------------------------------- */
26065+
26066+struct au_sphlhead {
26067+ spinlock_t spin;
26068+ struct hlist_head head;
26069+};
26070+
26071+static inline void au_sphl_init(struct au_sphlhead *sphl)
26072+{
26073+ spin_lock_init(&sphl->spin);
26074+ INIT_HLIST_HEAD(&sphl->head);
26075+}
26076+
26077+static inline void au_sphl_add(struct hlist_node *hlist,
26078+ struct au_sphlhead *sphl)
26079+{
26080+ spin_lock(&sphl->spin);
26081+ hlist_add_head(hlist, &sphl->head);
26082+ spin_unlock(&sphl->spin);
26083+}
26084+
26085+static inline void au_sphl_del(struct hlist_node *hlist,
26086+ struct au_sphlhead *sphl)
26087+{
26088+ spin_lock(&sphl->spin);
26089+ hlist_del(hlist);
26090+ spin_unlock(&sphl->spin);
26091+}
26092+
26093+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
26094+ struct au_sphlhead *sphl)
26095+{
26096+ spin_lock(&sphl->spin);
26097+ hlist_del_rcu(hlist);
26098+ spin_unlock(&sphl->spin);
26099+}
26100+
26101+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
26102+{
26103+ unsigned long cnt;
26104+ struct hlist_node *pos;
26105+
26106+ cnt = 0;
26107+ spin_lock(&sphl->spin);
26108+ hlist_for_each(pos, &sphl->head)
26109+ cnt++;
26110+ spin_unlock(&sphl->spin);
26111+ return cnt;
26112+}
26113+
1facf9fc 26114+#endif /* __KERNEL__ */
26115+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
26116diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
26117--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
26118+++ linux/fs/aufs/super.c 2015-04-13 15:10:20.790157026 +0200
26119@@ -0,0 +1,1007 @@
1facf9fc 26120+/*
2000de60 26121+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 26122+ *
26123+ * This program, aufs is free software; you can redistribute it and/or modify
26124+ * it under the terms of the GNU General Public License as published by
26125+ * the Free Software Foundation; either version 2 of the License, or
26126+ * (at your option) any later version.
dece6358
AM
26127+ *
26128+ * This program is distributed in the hope that it will be useful,
26129+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26130+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26131+ * GNU General Public License for more details.
26132+ *
26133+ * You should have received a copy of the GNU General Public License
523b37e3 26134+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26135+ */
26136+
26137+/*
26138+ * mount and super_block operations
26139+ */
26140+
f6c5ef8b 26141+#include <linux/mm.h>
1facf9fc 26142+#include <linux/seq_file.h>
26143+#include <linux/statfs.h>
7f207e10 26144+#include <linux/vmalloc.h>
1facf9fc 26145+#include "aufs.h"
26146+
26147+/*
26148+ * super_operations
26149+ */
26150+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
26151+{
26152+ struct au_icntnr *c;
26153+
26154+ c = au_cache_alloc_icntnr();
26155+ if (c) {
027c5e7a 26156+ au_icntnr_init(c);
1facf9fc 26157+ c->vfs_inode.i_version = 1; /* sigen(sb); */
26158+ c->iinfo.ii_hinode = NULL;
26159+ return &c->vfs_inode;
26160+ }
26161+ return NULL;
26162+}
26163+
027c5e7a
AM
26164+static void aufs_destroy_inode_cb(struct rcu_head *head)
26165+{
26166+ struct inode *inode = container_of(head, struct inode, i_rcu);
26167+
b4510431 26168+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
26169+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
26170+}
26171+
1facf9fc 26172+static void aufs_destroy_inode(struct inode *inode)
26173+{
26174+ au_iinfo_fin(inode);
027c5e7a 26175+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 26176+}
26177+
26178+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
26179+{
26180+ struct inode *inode;
26181+ int err;
26182+
26183+ inode = iget_locked(sb, ino);
26184+ if (unlikely(!inode)) {
26185+ inode = ERR_PTR(-ENOMEM);
26186+ goto out;
26187+ }
26188+ if (!(inode->i_state & I_NEW))
26189+ goto out;
26190+
26191+ err = au_xigen_new(inode);
26192+ if (!err)
26193+ err = au_iinfo_init(inode);
26194+ if (!err)
26195+ inode->i_version++;
26196+ else {
26197+ iget_failed(inode);
26198+ inode = ERR_PTR(err);
26199+ }
26200+
4f0767ce 26201+out:
1facf9fc 26202+ /* never return NULL */
26203+ AuDebugOn(!inode);
26204+ AuTraceErrPtr(inode);
26205+ return inode;
26206+}
26207+
26208+/* lock free root dinfo */
26209+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
26210+{
26211+ int err;
26212+ aufs_bindex_t bindex, bend;
26213+ struct path path;
4a4d8108 26214+ struct au_hdentry *hdp;
1facf9fc 26215+ struct au_branch *br;
076b876e 26216+ au_br_perm_str_t perm;
1facf9fc 26217+
26218+ err = 0;
26219+ bend = au_sbend(sb);
4a4d8108 26220+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 26221+ for (bindex = 0; !err && bindex <= bend; bindex++) {
26222+ br = au_sbr(sb, bindex);
86dc4139 26223+ path.mnt = au_br_mnt(br);
4a4d8108 26224+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 26225+ err = au_seq_path(seq, &path);
1e00d052 26226+ if (err > 0) {
076b876e
AM
26227+ au_optstr_br_perm(&perm, br->br_perm);
26228+ err = seq_printf(seq, "=%s", perm.a);
26229+ if (err == -1)
26230+ err = -E2BIG;
1e00d052 26231+ }
1facf9fc 26232+ if (!err && bindex != bend)
26233+ err = seq_putc(seq, ':');
26234+ }
26235+
26236+ return err;
26237+}
26238+
26239+static void au_show_wbr_create(struct seq_file *m, int v,
26240+ struct au_sbinfo *sbinfo)
26241+{
26242+ const char *pat;
26243+
dece6358
AM
26244+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26245+
c2b27bf2 26246+ seq_puts(m, ",create=");
1facf9fc 26247+ pat = au_optstr_wbr_create(v);
26248+ switch (v) {
26249+ case AuWbrCreate_TDP:
26250+ case AuWbrCreate_RR:
26251+ case AuWbrCreate_MFS:
26252+ case AuWbrCreate_PMFS:
c2b27bf2 26253+ seq_puts(m, pat);
1facf9fc 26254+ break;
26255+ case AuWbrCreate_MFSV:
26256+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
26257+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26258+ / MSEC_PER_SEC);
1facf9fc 26259+ break;
26260+ case AuWbrCreate_PMFSV:
26261+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
26262+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26263+ / MSEC_PER_SEC);
1facf9fc 26264+ break;
26265+ case AuWbrCreate_MFSRR:
26266+ seq_printf(m, /*pat*/"mfsrr:%llu",
26267+ sbinfo->si_wbr_mfs.mfsrr_watermark);
26268+ break;
26269+ case AuWbrCreate_MFSRRV:
26270+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
26271+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
26272+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26273+ / MSEC_PER_SEC);
1facf9fc 26274+ break;
392086de
AM
26275+ case AuWbrCreate_PMFSRR:
26276+ seq_printf(m, /*pat*/"pmfsrr:%llu",
26277+ sbinfo->si_wbr_mfs.mfsrr_watermark);
26278+ break;
26279+ case AuWbrCreate_PMFSRRV:
26280+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
26281+ sbinfo->si_wbr_mfs.mfsrr_watermark,
26282+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26283+ / MSEC_PER_SEC);
26284+ break;
1facf9fc 26285+ }
26286+}
26287+
7eafdf33 26288+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 26289+{
26290+#ifdef CONFIG_SYSFS
26291+ return 0;
26292+#else
26293+ int err;
26294+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
26295+ aufs_bindex_t bindex, brid;
1facf9fc 26296+ struct qstr *name;
26297+ struct file *f;
26298+ struct dentry *d, *h_root;
4a4d8108 26299+ struct au_hdentry *hdp;
1facf9fc 26300+
dece6358
AM
26301+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26302+
1facf9fc 26303+ err = 0;
1facf9fc 26304+ f = au_sbi(sb)->si_xib;
26305+ if (!f)
26306+ goto out;
26307+
26308+ /* stop printing the default xino path on the first writable branch */
26309+ h_root = NULL;
26310+ brid = au_xino_brid(sb);
26311+ if (brid >= 0) {
26312+ bindex = au_br_index(sb, brid);
4a4d8108
AM
26313+ hdp = au_di(sb->s_root)->di_hdentry;
26314+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 26315+ }
2000de60 26316+ d = f->f_path.dentry;
1facf9fc 26317+ name = &d->d_name;
26318+ /* safe ->d_parent because the file is unlinked */
26319+ if (d->d_parent == h_root
26320+ && name->len == len
26321+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
26322+ goto out;
26323+
26324+ seq_puts(seq, ",xino=");
26325+ err = au_xino_path(seq, f);
26326+
4f0767ce 26327+out:
1facf9fc 26328+ return err;
26329+#endif
26330+}
26331+
26332+/* seq_file will re-call me in case of too long string */
7eafdf33 26333+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 26334+{
027c5e7a 26335+ int err;
1facf9fc 26336+ unsigned int mnt_flags, v;
26337+ struct super_block *sb;
26338+ struct au_sbinfo *sbinfo;
26339+
26340+#define AuBool(name, str) do { \
26341+ v = au_opt_test(mnt_flags, name); \
26342+ if (v != au_opt_test(AuOpt_Def, name)) \
26343+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
26344+} while (0)
26345+
26346+#define AuStr(name, str) do { \
26347+ v = mnt_flags & AuOptMask_##name; \
26348+ if (v != (AuOpt_Def & AuOptMask_##name)) \
26349+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
26350+} while (0)
26351+
26352+#define AuUInt(name, str, val) do { \
26353+ if (val != AUFS_##name##_DEF) \
26354+ seq_printf(m, "," #str "=%u", val); \
26355+} while (0)
26356+
7eafdf33 26357+ sb = dentry->d_sb;
c1595e42
JR
26358+ if (sb->s_flags & MS_POSIXACL)
26359+ seq_puts(m, ",acl");
26360+
26361+ /* lock free root dinfo */
1facf9fc 26362+ si_noflush_read_lock(sb);
26363+ sbinfo = au_sbi(sb);
26364+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
26365+
26366+ mnt_flags = au_mntflags(sb);
26367+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 26368+ err = au_show_xino(m, sb);
1facf9fc 26369+ if (unlikely(err))
26370+ goto out;
26371+ } else
26372+ seq_puts(m, ",noxino");
26373+
26374+ AuBool(TRUNC_XINO, trunc_xino);
26375+ AuStr(UDBA, udba);
dece6358 26376+ AuBool(SHWH, shwh);
1facf9fc 26377+ AuBool(PLINK, plink);
4a4d8108 26378+ AuBool(DIO, dio);
076b876e 26379+ AuBool(DIRPERM1, dirperm1);
1facf9fc 26380+ /* AuBool(REFROF, refrof); */
26381+
26382+ v = sbinfo->si_wbr_create;
26383+ if (v != AuWbrCreate_Def)
26384+ au_show_wbr_create(m, v, sbinfo);
26385+
26386+ v = sbinfo->si_wbr_copyup;
26387+ if (v != AuWbrCopyup_Def)
26388+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
26389+
26390+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
26391+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
26392+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
26393+
26394+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
26395+
027c5e7a
AM
26396+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
26397+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 26398+
26399+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
26400+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
26401+
076b876e
AM
26402+ au_fhsm_show(m, sbinfo);
26403+
1facf9fc 26404+ AuBool(SUM, sum);
26405+ /* AuBool(SUM_W, wsum); */
26406+ AuBool(WARN_PERM, warn_perm);
26407+ AuBool(VERBOSE, verbose);
26408+
4f0767ce 26409+out:
1facf9fc 26410+ /* be sure to print "br:" last */
26411+ if (!sysaufs_brs) {
26412+ seq_puts(m, ",br:");
26413+ au_show_brs(m, sb);
26414+ }
26415+ si_read_unlock(sb);
26416+ return 0;
26417+
1facf9fc 26418+#undef AuBool
26419+#undef AuStr
4a4d8108 26420+#undef AuUInt
1facf9fc 26421+}
26422+
26423+/* ---------------------------------------------------------------------- */
26424+
26425+/* sum mode which returns the summation for statfs(2) */
26426+
26427+static u64 au_add_till_max(u64 a, u64 b)
26428+{
26429+ u64 old;
26430+
26431+ old = a;
26432+ a += b;
92d182d2
AM
26433+ if (old <= a)
26434+ return a;
26435+ return ULLONG_MAX;
26436+}
26437+
26438+static u64 au_mul_till_max(u64 a, long mul)
26439+{
26440+ u64 old;
26441+
26442+ old = a;
26443+ a *= mul;
26444+ if (old <= a)
1facf9fc 26445+ return a;
26446+ return ULLONG_MAX;
26447+}
26448+
26449+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
26450+{
26451+ int err;
92d182d2 26452+ long bsize, factor;
1facf9fc 26453+ u64 blocks, bfree, bavail, files, ffree;
26454+ aufs_bindex_t bend, bindex, i;
26455+ unsigned char shared;
7f207e10 26456+ struct path h_path;
1facf9fc 26457+ struct super_block *h_sb;
26458+
92d182d2
AM
26459+ err = 0;
26460+ bsize = LONG_MAX;
26461+ files = 0;
26462+ ffree = 0;
1facf9fc 26463+ blocks = 0;
26464+ bfree = 0;
26465+ bavail = 0;
1facf9fc 26466+ bend = au_sbend(sb);
92d182d2 26467+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
26468+ h_path.mnt = au_sbr_mnt(sb, bindex);
26469+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 26470+ shared = 0;
92d182d2 26471+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 26472+ shared = (au_sbr_sb(sb, i) == h_sb);
26473+ if (shared)
26474+ continue;
26475+
26476+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
26477+ h_path.dentry = h_path.mnt->mnt_root;
26478+ err = vfs_statfs(&h_path, buf);
1facf9fc 26479+ if (unlikely(err))
26480+ goto out;
26481+
92d182d2
AM
26482+ if (bsize > buf->f_bsize) {
26483+ /*
26484+ * we will reduce bsize, so we have to expand blocks
26485+ * etc. to match them again
26486+ */
26487+ factor = (bsize / buf->f_bsize);
26488+ blocks = au_mul_till_max(blocks, factor);
26489+ bfree = au_mul_till_max(bfree, factor);
26490+ bavail = au_mul_till_max(bavail, factor);
26491+ bsize = buf->f_bsize;
26492+ }
26493+
26494+ factor = (buf->f_bsize / bsize);
26495+ blocks = au_add_till_max(blocks,
26496+ au_mul_till_max(buf->f_blocks, factor));
26497+ bfree = au_add_till_max(bfree,
26498+ au_mul_till_max(buf->f_bfree, factor));
26499+ bavail = au_add_till_max(bavail,
26500+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 26501+ files = au_add_till_max(files, buf->f_files);
26502+ ffree = au_add_till_max(ffree, buf->f_ffree);
26503+ }
26504+
92d182d2 26505+ buf->f_bsize = bsize;
1facf9fc 26506+ buf->f_blocks = blocks;
26507+ buf->f_bfree = bfree;
26508+ buf->f_bavail = bavail;
26509+ buf->f_files = files;
26510+ buf->f_ffree = ffree;
92d182d2 26511+ buf->f_frsize = 0;
1facf9fc 26512+
4f0767ce 26513+out:
1facf9fc 26514+ return err;
26515+}
26516+
26517+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
26518+{
26519+ int err;
7f207e10 26520+ struct path h_path;
1facf9fc 26521+ struct super_block *sb;
26522+
26523+ /* lock free root dinfo */
26524+ sb = dentry->d_sb;
26525+ si_noflush_read_lock(sb);
7f207e10 26526+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 26527+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
26528+ h_path.mnt = au_sbr_mnt(sb, 0);
26529+ h_path.dentry = h_path.mnt->mnt_root;
26530+ err = vfs_statfs(&h_path, buf);
26531+ } else
1facf9fc 26532+ err = au_statfs_sum(sb, buf);
26533+ si_read_unlock(sb);
26534+
26535+ if (!err) {
26536+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 26537+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 26538+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
26539+ }
26540+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
26541+
26542+ return err;
26543+}
26544+
26545+/* ---------------------------------------------------------------------- */
26546+
537831f9
AM
26547+static int aufs_sync_fs(struct super_block *sb, int wait)
26548+{
26549+ int err, e;
26550+ aufs_bindex_t bend, bindex;
26551+ struct au_branch *br;
26552+ struct super_block *h_sb;
26553+
26554+ err = 0;
26555+ si_noflush_read_lock(sb);
26556+ bend = au_sbend(sb);
26557+ for (bindex = 0; bindex <= bend; bindex++) {
26558+ br = au_sbr(sb, bindex);
26559+ if (!au_br_writable(br->br_perm))
26560+ continue;
26561+
26562+ h_sb = au_sbr_sb(sb, bindex);
26563+ if (h_sb->s_op->sync_fs) {
26564+ e = h_sb->s_op->sync_fs(h_sb, wait);
26565+ if (unlikely(e && !err))
26566+ err = e;
26567+ /* go on even if an error happens */
26568+ }
26569+ }
26570+ si_read_unlock(sb);
26571+
26572+ return err;
26573+}
26574+
26575+/* ---------------------------------------------------------------------- */
26576+
1facf9fc 26577+/* final actions when unmounting a file system */
26578+static void aufs_put_super(struct super_block *sb)
26579+{
26580+ struct au_sbinfo *sbinfo;
26581+
26582+ sbinfo = au_sbi(sb);
26583+ if (!sbinfo)
26584+ return;
26585+
1facf9fc 26586+ dbgaufs_si_fin(sbinfo);
26587+ kobject_put(&sbinfo->si_kobj);
26588+}
26589+
26590+/* ---------------------------------------------------------------------- */
26591+
7f207e10
AM
26592+void au_array_free(void *array)
26593+{
26594+ if (array) {
26595+ if (!is_vmalloc_addr(array))
26596+ kfree(array);
26597+ else
26598+ vfree(array);
26599+ }
26600+}
26601+
26602+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
26603+{
26604+ void *array;
076b876e 26605+ unsigned long long n, sz;
7f207e10
AM
26606+
26607+ array = NULL;
26608+ n = 0;
26609+ if (!*hint)
26610+ goto out;
26611+
26612+ if (*hint > ULLONG_MAX / sizeof(array)) {
26613+ array = ERR_PTR(-EMFILE);
26614+ pr_err("hint %llu\n", *hint);
26615+ goto out;
26616+ }
26617+
076b876e
AM
26618+ sz = sizeof(array) * *hint;
26619+ array = kzalloc(sz, GFP_NOFS);
7f207e10 26620+ if (unlikely(!array))
076b876e 26621+ array = vzalloc(sz);
7f207e10
AM
26622+ if (unlikely(!array)) {
26623+ array = ERR_PTR(-ENOMEM);
26624+ goto out;
26625+ }
26626+
26627+ n = cb(array, *hint, arg);
26628+ AuDebugOn(n > *hint);
26629+
26630+out:
26631+ *hint = n;
26632+ return array;
26633+}
26634+
26635+static unsigned long long au_iarray_cb(void *a,
26636+ unsigned long long max __maybe_unused,
26637+ void *arg)
26638+{
26639+ unsigned long long n;
26640+ struct inode **p, *inode;
26641+ struct list_head *head;
26642+
26643+ n = 0;
26644+ p = a;
26645+ head = arg;
2cbb1c4b 26646+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
26647+ list_for_each_entry(inode, head, i_sb_list) {
26648+ if (!is_bad_inode(inode)
26649+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
26650+ spin_lock(&inode->i_lock);
26651+ if (atomic_read(&inode->i_count)) {
26652+ au_igrab(inode);
26653+ *p++ = inode;
26654+ n++;
26655+ AuDebugOn(n > max);
26656+ }
26657+ spin_unlock(&inode->i_lock);
7f207e10
AM
26658+ }
26659+ }
2cbb1c4b 26660+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
26661+
26662+ return n;
26663+}
26664+
26665+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
26666+{
26667+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
26668+ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
26669+}
26670+
26671+void au_iarray_free(struct inode **a, unsigned long long max)
26672+{
26673+ unsigned long long ull;
26674+
26675+ for (ull = 0; ull < max; ull++)
26676+ iput(a[ull]);
26677+ au_array_free(a);
26678+}
26679+
26680+/* ---------------------------------------------------------------------- */
26681+
1facf9fc 26682+/*
26683+ * refresh dentry and inode at remount time.
26684+ */
027c5e7a
AM
26685+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
26686+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
26687+ struct dentry *parent)
1facf9fc 26688+{
26689+ int err;
1facf9fc 26690+
26691+ di_write_lock_child(dentry);
1facf9fc 26692+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
26693+ err = au_refresh_dentry(dentry, parent);
26694+ if (!err && dir_flags)
26695+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 26696+ di_read_unlock(parent, AuLock_IR);
1facf9fc 26697+ di_write_unlock(dentry);
26698+
26699+ return err;
26700+}
26701+
027c5e7a
AM
26702+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
26703+ struct au_sbinfo *sbinfo,
26704+ const unsigned int dir_flags)
1facf9fc 26705+{
027c5e7a
AM
26706+ int err;
26707+ struct dentry *parent;
26708+ struct inode *inode;
26709+
26710+ err = 0;
26711+ parent = dget_parent(dentry);
26712+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
26713+ inode = dentry->d_inode;
26714+ if (inode) {
26715+ if (!S_ISDIR(inode->i_mode))
26716+ err = au_do_refresh(dentry, /*dir_flags*/0,
26717+ parent);
26718+ else {
26719+ err = au_do_refresh(dentry, dir_flags, parent);
26720+ if (unlikely(err))
26721+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
26722+ }
26723+ } else
26724+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
26725+ AuDbgDentry(dentry);
26726+ }
26727+ dput(parent);
26728+
26729+ AuTraceErr(err);
26730+ return err;
1facf9fc 26731+}
26732+
027c5e7a 26733+static int au_refresh_d(struct super_block *sb)
1facf9fc 26734+{
26735+ int err, i, j, ndentry, e;
027c5e7a 26736+ unsigned int sigen;
1facf9fc 26737+ struct au_dcsub_pages dpages;
26738+ struct au_dpage *dpage;
027c5e7a
AM
26739+ struct dentry **dentries, *d;
26740+ struct au_sbinfo *sbinfo;
26741+ struct dentry *root = sb->s_root;
26742+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
1facf9fc 26743+
027c5e7a
AM
26744+ err = au_dpages_init(&dpages, GFP_NOFS);
26745+ if (unlikely(err))
1facf9fc 26746+ goto out;
027c5e7a
AM
26747+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
26748+ if (unlikely(err))
1facf9fc 26749+ goto out_dpages;
1facf9fc 26750+
027c5e7a
AM
26751+ sigen = au_sigen(sb);
26752+ sbinfo = au_sbi(sb);
26753+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 26754+ dpage = dpages.dpages + i;
26755+ dentries = dpage->dentries;
26756+ ndentry = dpage->ndentry;
027c5e7a 26757+ for (j = 0; j < ndentry; j++) {
1facf9fc 26758+ d = dentries[j];
027c5e7a
AM
26759+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
26760+ if (unlikely(e && !err))
26761+ err = e;
26762+ /* go on even err */
1facf9fc 26763+ }
26764+ }
26765+
4f0767ce 26766+out_dpages:
1facf9fc 26767+ au_dpages_free(&dpages);
4f0767ce 26768+out:
1facf9fc 26769+ return err;
26770+}
26771+
027c5e7a 26772+static int au_refresh_i(struct super_block *sb)
1facf9fc 26773+{
027c5e7a
AM
26774+ int err, e;
26775+ unsigned int sigen;
26776+ unsigned long long max, ull;
26777+ struct inode *inode, **array;
1facf9fc 26778+
027c5e7a
AM
26779+ array = au_iarray_alloc(sb, &max);
26780+ err = PTR_ERR(array);
26781+ if (IS_ERR(array))
26782+ goto out;
1facf9fc 26783+
26784+ err = 0;
027c5e7a
AM
26785+ sigen = au_sigen(sb);
26786+ for (ull = 0; ull < max; ull++) {
26787+ inode = array[ull];
076b876e
AM
26788+ if (unlikely(!inode))
26789+ break;
537831f9 26790+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 26791+ ii_write_lock_child(inode);
027c5e7a 26792+ e = au_refresh_hinode_self(inode);
1facf9fc 26793+ ii_write_unlock(inode);
26794+ if (unlikely(e)) {
027c5e7a 26795+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 26796+ if (!err)
26797+ err = e;
26798+ /* go on even if err */
26799+ }
26800+ }
1facf9fc 26801+ }
26802+
027c5e7a 26803+ au_iarray_free(array, max);
1facf9fc 26804+
4f0767ce 26805+out:
1facf9fc 26806+ return err;
26807+}
26808+
027c5e7a 26809+static void au_remount_refresh(struct super_block *sb)
1facf9fc 26810+{
027c5e7a
AM
26811+ int err, e;
26812+ unsigned int udba;
26813+ aufs_bindex_t bindex, bend;
1facf9fc 26814+ struct dentry *root;
26815+ struct inode *inode;
027c5e7a 26816+ struct au_branch *br;
1facf9fc 26817+
26818+ au_sigen_inc(sb);
027c5e7a 26819+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 26820+
26821+ root = sb->s_root;
26822+ DiMustNoWaiters(root);
26823+ inode = root->d_inode;
26824+ IiMustNoWaiters(inode);
1facf9fc 26825+
027c5e7a
AM
26826+ udba = au_opt_udba(sb);
26827+ bend = au_sbend(sb);
26828+ for (bindex = 0; bindex <= bend; bindex++) {
26829+ br = au_sbr(sb, bindex);
26830+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 26831+ if (unlikely(err))
027c5e7a
AM
26832+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
26833+ bindex, err);
26834+ /* go on even if err */
1facf9fc 26835+ }
027c5e7a 26836+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 26837+
027c5e7a
AM
26838+ di_write_unlock(root);
26839+ err = au_refresh_d(sb);
26840+ e = au_refresh_i(sb);
26841+ if (unlikely(e && !err))
26842+ err = e;
1facf9fc 26843+ /* aufs_write_lock() calls ..._child() */
26844+ di_write_lock_child(root);
027c5e7a
AM
26845+
26846+ au_cpup_attr_all(inode, /*force*/1);
26847+
26848+ if (unlikely(err))
26849+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 26850+}
26851+
26852+/* stop extra interpretation of errno in mount(8), and strange error messages */
26853+static int cvt_err(int err)
26854+{
26855+ AuTraceErr(err);
26856+
26857+ switch (err) {
26858+ case -ENOENT:
26859+ case -ENOTDIR:
26860+ case -EEXIST:
26861+ case -EIO:
26862+ err = -EINVAL;
26863+ }
26864+ return err;
26865+}
26866+
26867+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
26868+{
4a4d8108
AM
26869+ int err, do_dx;
26870+ unsigned int mntflags;
1facf9fc 26871+ struct au_opts opts;
26872+ struct dentry *root;
26873+ struct inode *inode;
26874+ struct au_sbinfo *sbinfo;
26875+
26876+ err = 0;
26877+ root = sb->s_root;
26878+ if (!data || !*data) {
e49829fe
JR
26879+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
26880+ if (!err) {
26881+ di_write_lock_child(root);
26882+ err = au_opts_verify(sb, *flags, /*pending*/0);
26883+ aufs_write_unlock(root);
26884+ }
1facf9fc 26885+ goto out;
26886+ }
26887+
26888+ err = -ENOMEM;
26889+ memset(&opts, 0, sizeof(opts));
26890+ opts.opt = (void *)__get_free_page(GFP_NOFS);
26891+ if (unlikely(!opts.opt))
26892+ goto out;
26893+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
26894+ opts.flags = AuOpts_REMOUNT;
26895+ opts.sb_flags = *flags;
26896+
26897+ /* parse it before aufs lock */
26898+ err = au_opts_parse(sb, data, &opts);
26899+ if (unlikely(err))
26900+ goto out_opts;
26901+
26902+ sbinfo = au_sbi(sb);
26903+ inode = root->d_inode;
26904+ mutex_lock(&inode->i_mutex);
e49829fe
JR
26905+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
26906+ if (unlikely(err))
26907+ goto out_mtx;
26908+ di_write_lock_child(root);
1facf9fc 26909+
26910+ /* au_opts_remount() may return an error */
26911+ err = au_opts_remount(sb, &opts);
26912+ au_opts_free(&opts);
26913+
027c5e7a
AM
26914+ if (au_ftest_opts(opts.flags, REFRESH))
26915+ au_remount_refresh(sb);
1facf9fc 26916+
4a4d8108
AM
26917+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
26918+ mntflags = au_mntflags(sb);
26919+ do_dx = !!au_opt_test(mntflags, DIO);
26920+ au_dy_arefresh(do_dx);
26921+ }
26922+
076b876e 26923+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 26924+ aufs_write_unlock(root);
953406b4 26925+
e49829fe
JR
26926+out_mtx:
26927+ mutex_unlock(&inode->i_mutex);
4f0767ce 26928+out_opts:
1facf9fc 26929+ free_page((unsigned long)opts.opt);
4f0767ce 26930+out:
1facf9fc 26931+ err = cvt_err(err);
26932+ AuTraceErr(err);
26933+ return err;
26934+}
26935+
4a4d8108 26936+static const struct super_operations aufs_sop = {
1facf9fc 26937+ .alloc_inode = aufs_alloc_inode,
26938+ .destroy_inode = aufs_destroy_inode,
b752ccd1 26939+ /* always deleting, no clearing */
1facf9fc 26940+ .drop_inode = generic_delete_inode,
26941+ .show_options = aufs_show_options,
26942+ .statfs = aufs_statfs,
26943+ .put_super = aufs_put_super,
537831f9 26944+ .sync_fs = aufs_sync_fs,
1facf9fc 26945+ .remount_fs = aufs_remount_fs
26946+};
26947+
26948+/* ---------------------------------------------------------------------- */
26949+
26950+static int alloc_root(struct super_block *sb)
26951+{
26952+ int err;
26953+ struct inode *inode;
26954+ struct dentry *root;
26955+
26956+ err = -ENOMEM;
26957+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
26958+ err = PTR_ERR(inode);
26959+ if (IS_ERR(inode))
26960+ goto out;
26961+
26962+ inode->i_op = &aufs_dir_iop;
26963+ inode->i_fop = &aufs_dir_fop;
26964+ inode->i_mode = S_IFDIR;
9dbd164d 26965+ set_nlink(inode, 2);
1facf9fc 26966+ unlock_new_inode(inode);
26967+
92d182d2 26968+ root = d_make_root(inode);
1facf9fc 26969+ if (unlikely(!root))
92d182d2 26970+ goto out;
1facf9fc 26971+ err = PTR_ERR(root);
26972+ if (IS_ERR(root))
92d182d2 26973+ goto out;
1facf9fc 26974+
4a4d8108 26975+ err = au_di_init(root);
1facf9fc 26976+ if (!err) {
26977+ sb->s_root = root;
26978+ return 0; /* success */
26979+ }
26980+ dput(root);
1facf9fc 26981+
4f0767ce 26982+out:
1facf9fc 26983+ return err;
1facf9fc 26984+}
26985+
26986+static int aufs_fill_super(struct super_block *sb, void *raw_data,
26987+ int silent __maybe_unused)
26988+{
26989+ int err;
26990+ struct au_opts opts;
26991+ struct dentry *root;
26992+ struct inode *inode;
26993+ char *arg = raw_data;
26994+
26995+ if (unlikely(!arg || !*arg)) {
26996+ err = -EINVAL;
4a4d8108 26997+ pr_err("no arg\n");
1facf9fc 26998+ goto out;
26999+ }
27000+
27001+ err = -ENOMEM;
27002+ memset(&opts, 0, sizeof(opts));
27003+ opts.opt = (void *)__get_free_page(GFP_NOFS);
27004+ if (unlikely(!opts.opt))
27005+ goto out;
27006+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
27007+ opts.sb_flags = sb->s_flags;
27008+
27009+ err = au_si_alloc(sb);
27010+ if (unlikely(err))
27011+ goto out_opts;
27012+
27013+ /* all timestamps always follow the ones on the branch */
27014+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
27015+ sb->s_op = &aufs_sop;
027c5e7a 27016+ sb->s_d_op = &aufs_dop;
1facf9fc 27017+ sb->s_magic = AUFS_SUPER_MAGIC;
27018+ sb->s_maxbytes = 0;
c1595e42 27019+ sb->s_stack_depth = 1;
1facf9fc 27020+ au_export_init(sb);
c1595e42 27021+ /* au_xattr_init(sb); */
1facf9fc 27022+
27023+ err = alloc_root(sb);
27024+ if (unlikely(err)) {
27025+ si_write_unlock(sb);
27026+ goto out_info;
27027+ }
27028+ root = sb->s_root;
27029+ inode = root->d_inode;
27030+
27031+ /*
27032+ * actually we can parse options regardless aufs lock here.
27033+ * but at remount time, parsing must be done before aufs lock.
27034+ * so we follow the same rule.
27035+ */
27036+ ii_write_lock_parent(inode);
27037+ aufs_write_unlock(root);
27038+ err = au_opts_parse(sb, arg, &opts);
27039+ if (unlikely(err))
27040+ goto out_root;
27041+
27042+ /* lock vfs_inode first, then aufs. */
27043+ mutex_lock(&inode->i_mutex);
1facf9fc 27044+ aufs_write_lock(root);
27045+ err = au_opts_mount(sb, &opts);
27046+ au_opts_free(&opts);
1facf9fc 27047+ aufs_write_unlock(root);
27048+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
27049+ if (!err)
27050+ goto out_opts; /* success */
1facf9fc 27051+
4f0767ce 27052+out_root:
1facf9fc 27053+ dput(root);
27054+ sb->s_root = NULL;
4f0767ce 27055+out_info:
2cbb1c4b 27056+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 27057+ kobject_put(&au_sbi(sb)->si_kobj);
27058+ sb->s_fs_info = NULL;
4f0767ce 27059+out_opts:
1facf9fc 27060+ free_page((unsigned long)opts.opt);
4f0767ce 27061+out:
1facf9fc 27062+ AuTraceErr(err);
27063+ err = cvt_err(err);
27064+ AuTraceErr(err);
27065+ return err;
27066+}
27067+
27068+/* ---------------------------------------------------------------------- */
27069+
027c5e7a
AM
27070+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
27071+ const char *dev_name __maybe_unused,
27072+ void *raw_data)
1facf9fc 27073+{
027c5e7a 27074+ struct dentry *root;
1facf9fc 27075+ struct super_block *sb;
27076+
27077+ /* all timestamps always follow the ones on the branch */
27078+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
27079+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
27080+ if (IS_ERR(root))
27081+ goto out;
27082+
27083+ sb = root->d_sb;
27084+ si_write_lock(sb, !AuLock_FLUSH);
27085+ sysaufs_brs_add(sb, 0);
27086+ si_write_unlock(sb);
27087+ au_sbilist_add(sb);
27088+
27089+out:
27090+ return root;
1facf9fc 27091+}
27092+
e49829fe
JR
27093+static void aufs_kill_sb(struct super_block *sb)
27094+{
27095+ struct au_sbinfo *sbinfo;
27096+
27097+ sbinfo = au_sbi(sb);
27098+ if (sbinfo) {
27099+ au_sbilist_del(sb);
27100+ aufs_write_lock(sb->s_root);
076b876e 27101+ au_fhsm_fin(sb);
e49829fe
JR
27102+ if (sbinfo->si_wbr_create_ops->fin)
27103+ sbinfo->si_wbr_create_ops->fin(sb);
27104+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
27105+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
027c5e7a 27106+ au_remount_refresh(sb);
e49829fe
JR
27107+ }
27108+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
27109+ au_plink_put(sb, /*verbose*/1);
27110+ au_xino_clr(sb);
1e00d052 27111+ sbinfo->si_sb = NULL;
e49829fe 27112+ aufs_write_unlock(sb->s_root);
e49829fe
JR
27113+ au_nwt_flush(&sbinfo->si_nowait);
27114+ }
98d9a5b1 27115+ kill_anon_super(sb);
e49829fe
JR
27116+}
27117+
1facf9fc 27118+struct file_system_type aufs_fs_type = {
27119+ .name = AUFS_FSTYPE,
c06a8ce3
AM
27120+ /* a race between rename and others */
27121+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 27122+ .mount = aufs_mount,
e49829fe 27123+ .kill_sb = aufs_kill_sb,
1facf9fc 27124+ /* no need to __module_get() and module_put(). */
27125+ .owner = THIS_MODULE,
27126+};
7f207e10
AM
27127diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
27128--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
27129+++ linux/fs/aufs/super.h 2015-04-13 15:10:20.790157026 +0200
27130@@ -0,0 +1,635 @@
1facf9fc 27131+/*
2000de60 27132+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 27133+ *
27134+ * This program, aufs is free software; you can redistribute it and/or modify
27135+ * it under the terms of the GNU General Public License as published by
27136+ * the Free Software Foundation; either version 2 of the License, or
27137+ * (at your option) any later version.
dece6358
AM
27138+ *
27139+ * This program is distributed in the hope that it will be useful,
27140+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27141+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27142+ * GNU General Public License for more details.
27143+ *
27144+ * You should have received a copy of the GNU General Public License
523b37e3 27145+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27146+ */
27147+
27148+/*
27149+ * super_block operations
27150+ */
27151+
27152+#ifndef __AUFS_SUPER_H__
27153+#define __AUFS_SUPER_H__
27154+
27155+#ifdef __KERNEL__
27156+
27157+#include <linux/fs.h>
1facf9fc 27158+#include "rwsem.h"
27159+#include "spl.h"
27160+#include "wkq.h"
27161+
27162+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
27163+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
27164+ loff_t *);
27165+
27166+/* policies to select one among multiple writable branches */
27167+struct au_wbr_copyup_operations {
27168+ int (*copyup)(struct dentry *dentry);
27169+};
27170+
392086de
AM
27171+#define AuWbr_DIR 1 /* target is a dir */
27172+#define AuWbr_PARENT (1 << 1) /* always require a parent */
27173+
27174+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
27175+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
27176+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
27177+
1facf9fc 27178+struct au_wbr_create_operations {
392086de 27179+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 27180+ int (*init)(struct super_block *sb);
27181+ int (*fin)(struct super_block *sb);
27182+};
27183+
27184+struct au_wbr_mfs {
27185+ struct mutex mfs_lock; /* protect this structure */
27186+ unsigned long mfs_jiffy;
27187+ unsigned long mfs_expire;
27188+ aufs_bindex_t mfs_bindex;
27189+
27190+ unsigned long long mfsrr_bytes;
27191+ unsigned long long mfsrr_watermark;
27192+};
27193+
86dc4139
AM
27194+struct pseudo_link {
27195+ union {
27196+ struct hlist_node hlist;
27197+ struct rcu_head rcu;
27198+ };
27199+ struct inode *inode;
27200+};
27201+
27202+#define AuPlink_NHASH 100
27203+static inline int au_plink_hash(ino_t ino)
27204+{
27205+ return ino % AuPlink_NHASH;
27206+}
27207+
076b876e
AM
27208+/* File-based Hierarchical Storage Management */
27209+struct au_fhsm {
27210+#ifdef CONFIG_AUFS_FHSM
27211+ /* allow only one process who can receive the notification */
27212+ spinlock_t fhsm_spin;
27213+ pid_t fhsm_pid;
27214+ wait_queue_head_t fhsm_wqh;
27215+ atomic_t fhsm_readable;
27216+
c1595e42 27217+ /* these are protected by si_rwsem */
076b876e 27218+ unsigned long fhsm_expire;
c1595e42 27219+ aufs_bindex_t fhsm_bottom;
076b876e
AM
27220+#endif
27221+};
27222+
1facf9fc 27223+struct au_branch;
27224+struct au_sbinfo {
27225+ /* nowait tasks in the system-wide workqueue */
27226+ struct au_nowait_tasks si_nowait;
27227+
b752ccd1
AM
27228+ /*
27229+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
27230+ * rwsem for au_sbinfo is necessary.
27231+ */
dece6358 27232+ struct au_rwsem si_rwsem;
1facf9fc 27233+
b752ccd1
AM
27234+ /* prevent recursive locking in deleting inode */
27235+ struct {
27236+ unsigned long *bitmap;
27237+ spinlock_t tree_lock;
27238+ struct radix_tree_root tree;
27239+ } au_si_pid;
27240+
7f207e10 27241+ /*
523b37e3
AM
27242+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
27243+ * remount.
7f207e10
AM
27244+ */
27245+ atomic_long_t si_ninodes, si_nfiles;
27246+
1facf9fc 27247+ /* branch management */
27248+ unsigned int si_generation;
27249+
2000de60 27250+ /* see AuSi_ flags */
1facf9fc 27251+ unsigned char au_si_status;
27252+
27253+ aufs_bindex_t si_bend;
7f207e10
AM
27254+
27255+ /* dirty trick to keep br_id plus */
27256+ unsigned int si_last_br_id :
27257+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 27258+ struct au_branch **si_branch;
27259+
27260+ /* policy to select a writable branch */
27261+ unsigned char si_wbr_copyup;
27262+ unsigned char si_wbr_create;
27263+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
27264+ struct au_wbr_create_operations *si_wbr_create_ops;
27265+
27266+ /* round robin */
27267+ atomic_t si_wbr_rr_next;
27268+
27269+ /* most free space */
27270+ struct au_wbr_mfs si_wbr_mfs;
27271+
076b876e
AM
27272+ /* File-based Hierarchical Storage Management */
27273+ struct au_fhsm si_fhsm;
27274+
1facf9fc 27275+ /* mount flags */
27276+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
27277+ unsigned int si_mntflags;
27278+
27279+ /* external inode number (bitmap and translation table) */
27280+ au_readf_t si_xread;
27281+ au_writef_t si_xwrite;
27282+ struct file *si_xib;
27283+ struct mutex si_xib_mtx; /* protect xib members */
27284+ unsigned long *si_xib_buf;
27285+ unsigned long si_xib_last_pindex;
27286+ int si_xib_next_bit;
27287+ aufs_bindex_t si_xino_brid;
392086de
AM
27288+ unsigned long si_xino_jiffy;
27289+ unsigned long si_xino_expire;
1facf9fc 27290+ /* reserved for future use */
27291+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
27292+
27293+#ifdef CONFIG_AUFS_EXPORT
27294+ /* i_generation */
27295+ struct file *si_xigen;
27296+ atomic_t si_xigen_next;
27297+#endif
27298+
27299+ /* vdir parameters */
e49829fe 27300+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 27301+ unsigned int si_rdblk; /* deblk size */
27302+ unsigned int si_rdhash; /* hash size */
27303+
27304+ /*
27305+ * If the number of whiteouts are larger than si_dirwh, leave all of
27306+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
27307+ * future fsck.aufs or kernel thread will remove them later.
27308+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
27309+ */
27310+ unsigned int si_dirwh;
27311+
1facf9fc 27312+ /* pseudo_link list */
86dc4139 27313+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 27314+ wait_queue_head_t si_plink_wq;
4a4d8108 27315+ spinlock_t si_plink_maint_lock;
e49829fe 27316+ pid_t si_plink_maint_pid;
1facf9fc 27317+
523b37e3
AM
27318+ /* file list */
27319+ struct au_sphlhead si_files;
27320+
1facf9fc 27321+ /*
27322+ * sysfs and lifetime management.
27323+ * this is not a small structure and it may be a waste of memory in case
27324+ * of sysfs is disabled, particulary when many aufs-es are mounted.
27325+ * but using sysfs is majority.
27326+ */
27327+ struct kobject si_kobj;
27328+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
27329+ struct dentry *si_dbgaufs;
27330+ struct dentry *si_dbgaufs_plink;
27331+ struct dentry *si_dbgaufs_xib;
1facf9fc 27332+#ifdef CONFIG_AUFS_EXPORT
27333+ struct dentry *si_dbgaufs_xigen;
27334+#endif
27335+#endif
27336+
e49829fe
JR
27337+#ifdef CONFIG_AUFS_SBILIST
27338+ struct list_head si_list;
27339+#endif
27340+
1facf9fc 27341+ /* dirty, necessary for unmounting, sysfs and sysrq */
27342+ struct super_block *si_sb;
27343+};
27344+
dece6358
AM
27345+/* sbinfo status flags */
27346+/*
27347+ * set true when refresh_dirs() failed at remount time.
27348+ * then try refreshing dirs at access time again.
27349+ * if it is false, refreshing dirs at access time is unnecesary
27350+ */
027c5e7a 27351+#define AuSi_FAILED_REFRESH_DIR 1
076b876e
AM
27352+
27353+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
27354+
27355+#ifndef CONFIG_AUFS_FHSM
27356+#undef AuSi_FHSM
27357+#define AuSi_FHSM 0
27358+#endif
27359+
dece6358
AM
27360+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
27361+ unsigned int flag)
27362+{
27363+ AuRwMustAnyLock(&sbi->si_rwsem);
27364+ return sbi->au_si_status & flag;
27365+}
27366+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
27367+#define au_fset_si(sbinfo, name) do { \
27368+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27369+ (sbinfo)->au_si_status |= AuSi_##name; \
27370+} while (0)
27371+#define au_fclr_si(sbinfo, name) do { \
27372+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27373+ (sbinfo)->au_si_status &= ~AuSi_##name; \
27374+} while (0)
27375+
1facf9fc 27376+/* ---------------------------------------------------------------------- */
27377+
27378+/* policy to select one among writable branches */
4a4d8108
AM
27379+#define AuWbrCopyup(sbinfo, ...) \
27380+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
27381+#define AuWbrCreate(sbinfo, ...) \
27382+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 27383+
27384+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
27385+#define AuLock_DW 1 /* write-lock dentry */
27386+#define AuLock_IR (1 << 1) /* read-lock inode */
27387+#define AuLock_IW (1 << 2) /* write-lock inode */
27388+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
27389+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
27390+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
27391+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 27392+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 27393+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
27394+#define au_fset_lock(flags, name) \
27395+ do { (flags) |= AuLock_##name; } while (0)
27396+#define au_fclr_lock(flags, name) \
27397+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 27398+
27399+/* ---------------------------------------------------------------------- */
27400+
27401+/* super.c */
27402+extern struct file_system_type aufs_fs_type;
27403+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
7f207e10
AM
27404+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
27405+ void *arg);
27406+void au_array_free(void *array);
27407+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
27408+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
27409+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 27410+
27411+/* sbinfo.c */
27412+void au_si_free(struct kobject *kobj);
27413+int au_si_alloc(struct super_block *sb);
27414+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
27415+
27416+unsigned int au_sigen_inc(struct super_block *sb);
27417+aufs_bindex_t au_new_br_id(struct super_block *sb);
27418+
e49829fe
JR
27419+int si_read_lock(struct super_block *sb, int flags);
27420+int si_write_lock(struct super_block *sb, int flags);
27421+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 27422+void aufs_read_unlock(struct dentry *dentry, int flags);
27423+void aufs_write_lock(struct dentry *dentry);
27424+void aufs_write_unlock(struct dentry *dentry);
e49829fe 27425+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 27426+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
27427+
b752ccd1
AM
27428+int si_pid_test_slow(struct super_block *sb);
27429+void si_pid_set_slow(struct super_block *sb);
27430+void si_pid_clr_slow(struct super_block *sb);
27431+
1facf9fc 27432+/* wbr_policy.c */
27433+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
27434+extern struct au_wbr_create_operations au_wbr_create_ops[];
27435+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 27436+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
076b876e 27437+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart);
c2b27bf2
AM
27438+
27439+/* mvdown.c */
27440+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 27441+
076b876e
AM
27442+#ifdef CONFIG_AUFS_FHSM
27443+/* fhsm.c */
27444+
27445+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
27446+{
27447+ pid_t pid;
27448+
27449+ spin_lock(&fhsm->fhsm_spin);
27450+ pid = fhsm->fhsm_pid;
27451+ spin_unlock(&fhsm->fhsm_spin);
27452+
27453+ return pid;
27454+}
27455+
27456+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
27457+void au_fhsm_wrote_all(struct super_block *sb, int force);
27458+int au_fhsm_fd(struct super_block *sb, int oflags);
27459+int au_fhsm_br_alloc(struct au_branch *br);
c1595e42 27460+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
076b876e
AM
27461+void au_fhsm_fin(struct super_block *sb);
27462+void au_fhsm_init(struct au_sbinfo *sbinfo);
27463+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
27464+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
27465+#else
27466+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
27467+ int force)
27468+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
27469+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
c1595e42
JR
27470+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
27471+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
27472+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
076b876e
AM
27473+AuStubVoid(au_fhsm_fin, struct super_block *sb)
27474+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
27475+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
27476+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
27477+#endif
27478+
1facf9fc 27479+/* ---------------------------------------------------------------------- */
27480+
27481+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
27482+{
27483+ return sb->s_fs_info;
27484+}
27485+
27486+/* ---------------------------------------------------------------------- */
27487+
27488+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 27489+int au_test_nfsd(void);
1facf9fc 27490+void au_export_init(struct super_block *sb);
b752ccd1 27491+void au_xigen_inc(struct inode *inode);
1facf9fc 27492+int au_xigen_new(struct inode *inode);
27493+int au_xigen_set(struct super_block *sb, struct file *base);
27494+void au_xigen_clr(struct super_block *sb);
27495+
27496+static inline int au_busy_or_stale(void)
27497+{
b752ccd1 27498+ if (!au_test_nfsd())
1facf9fc 27499+ return -EBUSY;
27500+ return -ESTALE;
27501+}
27502+#else
b752ccd1 27503+AuStubInt0(au_test_nfsd, void)
a2a7ad62 27504+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 27505+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
27506+AuStubInt0(au_xigen_new, struct inode *inode)
27507+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
27508+AuStubVoid(au_xigen_clr, struct super_block *sb)
c1595e42 27509+AuStub(int, au_busy_or_stale, return -EBUSY, void)
1facf9fc 27510+#endif /* CONFIG_AUFS_EXPORT */
27511+
27512+/* ---------------------------------------------------------------------- */
27513+
e49829fe
JR
27514+#ifdef CONFIG_AUFS_SBILIST
27515+/* module.c */
27516+extern struct au_splhead au_sbilist;
27517+
27518+static inline void au_sbilist_init(void)
27519+{
27520+ au_spl_init(&au_sbilist);
27521+}
27522+
27523+static inline void au_sbilist_add(struct super_block *sb)
27524+{
27525+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
27526+}
27527+
27528+static inline void au_sbilist_del(struct super_block *sb)
27529+{
27530+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
27531+}
53392da6
AM
27532+
27533+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
27534+static inline void au_sbilist_lock(void)
27535+{
27536+ spin_lock(&au_sbilist.spin);
27537+}
27538+
27539+static inline void au_sbilist_unlock(void)
27540+{
27541+ spin_unlock(&au_sbilist.spin);
27542+}
27543+#define AuGFP_SBILIST GFP_ATOMIC
27544+#else
27545+AuStubVoid(au_sbilist_lock, void)
27546+AuStubVoid(au_sbilist_unlock, void)
27547+#define AuGFP_SBILIST GFP_NOFS
27548+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
27549+#else
27550+AuStubVoid(au_sbilist_init, void)
c1595e42
JR
27551+AuStubVoid(au_sbilist_add, struct super_block *sb)
27552+AuStubVoid(au_sbilist_del, struct super_block *sb)
53392da6
AM
27553+AuStubVoid(au_sbilist_lock, void)
27554+AuStubVoid(au_sbilist_unlock, void)
27555+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
27556+#endif
27557+
27558+/* ---------------------------------------------------------------------- */
27559+
1facf9fc 27560+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
27561+{
dece6358 27562+ /*
c1595e42 27563+ * This function is a dynamic '__init' function actually,
dece6358
AM
27564+ * so the tiny check for si_rwsem is unnecessary.
27565+ */
27566+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 27567+#ifdef CONFIG_DEBUG_FS
27568+ sbinfo->si_dbgaufs = NULL;
86dc4139 27569+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 27570+ sbinfo->si_dbgaufs_xib = NULL;
27571+#ifdef CONFIG_AUFS_EXPORT
27572+ sbinfo->si_dbgaufs_xigen = NULL;
27573+#endif
27574+#endif
27575+}
27576+
27577+/* ---------------------------------------------------------------------- */
27578+
b752ccd1
AM
27579+static inline pid_t si_pid_bit(void)
27580+{
27581+ /* the origin of pid is 1, but the bitmap's is 0 */
27582+ return current->pid - 1;
27583+}
27584+
27585+static inline int si_pid_test(struct super_block *sb)
27586+{
076b876e
AM
27587+ pid_t bit;
27588+
27589+ bit = si_pid_bit();
b752ccd1
AM
27590+ if (bit < PID_MAX_DEFAULT)
27591+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
c1595e42 27592+ return si_pid_test_slow(sb);
b752ccd1
AM
27593+}
27594+
27595+static inline void si_pid_set(struct super_block *sb)
27596+{
076b876e
AM
27597+ pid_t bit;
27598+
27599+ bit = si_pid_bit();
b752ccd1
AM
27600+ if (bit < PID_MAX_DEFAULT) {
27601+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
27602+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27603+ /* smp_mb(); */
27604+ } else
27605+ si_pid_set_slow(sb);
27606+}
27607+
27608+static inline void si_pid_clr(struct super_block *sb)
27609+{
076b876e
AM
27610+ pid_t bit;
27611+
27612+ bit = si_pid_bit();
b752ccd1
AM
27613+ if (bit < PID_MAX_DEFAULT) {
27614+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
27615+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27616+ /* smp_mb(); */
27617+ } else
27618+ si_pid_clr_slow(sb);
27619+}
27620+
27621+/* ---------------------------------------------------------------------- */
27622+
1facf9fc 27623+/* lock superblock. mainly for entry point functions */
27624+/*
b752ccd1
AM
27625+ * __si_read_lock, __si_write_lock,
27626+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 27627+ */
b752ccd1 27628+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 27629+
dece6358
AM
27630+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
27631+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
27632+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
27633+
b752ccd1
AM
27634+static inline void si_noflush_read_lock(struct super_block *sb)
27635+{
27636+ __si_read_lock(sb);
27637+ si_pid_set(sb);
27638+}
27639+
27640+static inline int si_noflush_read_trylock(struct super_block *sb)
27641+{
076b876e
AM
27642+ int locked;
27643+
27644+ locked = __si_read_trylock(sb);
b752ccd1
AM
27645+ if (locked)
27646+ si_pid_set(sb);
27647+ return locked;
27648+}
27649+
27650+static inline void si_noflush_write_lock(struct super_block *sb)
27651+{
27652+ __si_write_lock(sb);
27653+ si_pid_set(sb);
27654+}
27655+
27656+static inline int si_noflush_write_trylock(struct super_block *sb)
27657+{
076b876e
AM
27658+ int locked;
27659+
27660+ locked = __si_write_trylock(sb);
b752ccd1
AM
27661+ if (locked)
27662+ si_pid_set(sb);
27663+ return locked;
27664+}
27665+
7e9cd9fe 27666+#if 0 /* reserved */
1facf9fc 27667+static inline int si_read_trylock(struct super_block *sb, int flags)
27668+{
27669+ if (au_ftest_lock(flags, FLUSH))
27670+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27671+ return si_noflush_read_trylock(sb);
27672+}
e49829fe 27673+#endif
1facf9fc 27674+
b752ccd1
AM
27675+static inline void si_read_unlock(struct super_block *sb)
27676+{
27677+ si_pid_clr(sb);
27678+ __si_read_unlock(sb);
27679+}
27680+
7e9cd9fe 27681+#if 0 /* reserved */
1facf9fc 27682+static inline int si_write_trylock(struct super_block *sb, int flags)
27683+{
27684+ if (au_ftest_lock(flags, FLUSH))
27685+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27686+ return si_noflush_write_trylock(sb);
27687+}
b752ccd1
AM
27688+#endif
27689+
27690+static inline void si_write_unlock(struct super_block *sb)
27691+{
27692+ si_pid_clr(sb);
27693+ __si_write_unlock(sb);
27694+}
27695+
7e9cd9fe 27696+#if 0 /* reserved */
b752ccd1
AM
27697+static inline void si_downgrade_lock(struct super_block *sb)
27698+{
27699+ __si_downgrade_lock(sb);
27700+}
27701+#endif
1facf9fc 27702+
27703+/* ---------------------------------------------------------------------- */
27704+
27705+static inline aufs_bindex_t au_sbend(struct super_block *sb)
27706+{
dece6358 27707+ SiMustAnyLock(sb);
1facf9fc 27708+ return au_sbi(sb)->si_bend;
27709+}
27710+
27711+static inline unsigned int au_mntflags(struct super_block *sb)
27712+{
dece6358 27713+ SiMustAnyLock(sb);
1facf9fc 27714+ return au_sbi(sb)->si_mntflags;
27715+}
27716+
27717+static inline unsigned int au_sigen(struct super_block *sb)
27718+{
dece6358 27719+ SiMustAnyLock(sb);
1facf9fc 27720+ return au_sbi(sb)->si_generation;
27721+}
27722+
7f207e10
AM
27723+static inline void au_ninodes_inc(struct super_block *sb)
27724+{
27725+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
27726+}
27727+
27728+static inline void au_ninodes_dec(struct super_block *sb)
27729+{
27730+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
27731+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
27732+}
27733+
27734+static inline void au_nfiles_inc(struct super_block *sb)
27735+{
27736+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
27737+}
27738+
27739+static inline void au_nfiles_dec(struct super_block *sb)
27740+{
27741+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
27742+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
27743+}
27744+
1facf9fc 27745+static inline struct au_branch *au_sbr(struct super_block *sb,
27746+ aufs_bindex_t bindex)
27747+{
dece6358 27748+ SiMustAnyLock(sb);
1facf9fc 27749+ return au_sbi(sb)->si_branch[0 + bindex];
27750+}
27751+
27752+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
27753+{
dece6358 27754+ SiMustWriteLock(sb);
1facf9fc 27755+ au_sbi(sb)->si_xino_brid = brid;
27756+}
27757+
27758+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
27759+{
dece6358 27760+ SiMustAnyLock(sb);
1facf9fc 27761+ return au_sbi(sb)->si_xino_brid;
27762+}
27763+
27764+#endif /* __KERNEL__ */
27765+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
27766diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
27767--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 27768+++ linux/fs/aufs/sysaufs.c 2015-04-13 15:10:20.790157026 +0200
523b37e3 27769@@ -0,0 +1,104 @@
1facf9fc 27770+/*
2000de60 27771+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 27772+ *
27773+ * This program, aufs is free software; you can redistribute it and/or modify
27774+ * it under the terms of the GNU General Public License as published by
27775+ * the Free Software Foundation; either version 2 of the License, or
27776+ * (at your option) any later version.
dece6358
AM
27777+ *
27778+ * This program is distributed in the hope that it will be useful,
27779+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27780+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27781+ * GNU General Public License for more details.
27782+ *
27783+ * You should have received a copy of the GNU General Public License
523b37e3 27784+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27785+ */
27786+
27787+/*
27788+ * sysfs interface and lifetime management
27789+ * they are necessary regardless sysfs is disabled.
27790+ */
27791+
1facf9fc 27792+#include <linux/random.h>
1facf9fc 27793+#include "aufs.h"
27794+
27795+unsigned long sysaufs_si_mask;
e49829fe 27796+struct kset *sysaufs_kset;
1facf9fc 27797+
27798+#define AuSiAttr(_name) { \
27799+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
27800+ .show = sysaufs_si_##_name, \
27801+}
27802+
27803+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
27804+struct attribute *sysaufs_si_attrs[] = {
27805+ &sysaufs_si_attr_xi_path.attr,
27806+ NULL,
27807+};
27808+
4a4d8108 27809+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 27810+ .show = sysaufs_si_show
27811+};
27812+
27813+static struct kobj_type au_sbi_ktype = {
27814+ .release = au_si_free,
27815+ .sysfs_ops = &au_sbi_ops,
27816+ .default_attrs = sysaufs_si_attrs
27817+};
27818+
27819+/* ---------------------------------------------------------------------- */
27820+
27821+int sysaufs_si_init(struct au_sbinfo *sbinfo)
27822+{
27823+ int err;
27824+
e49829fe 27825+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 27826+ /* cf. sysaufs_name() */
27827+ err = kobject_init_and_add
e49829fe 27828+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 27829+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
27830+
27831+ dbgaufs_si_null(sbinfo);
27832+ if (!err) {
27833+ err = dbgaufs_si_init(sbinfo);
27834+ if (unlikely(err))
27835+ kobject_put(&sbinfo->si_kobj);
27836+ }
27837+ return err;
27838+}
27839+
27840+void sysaufs_fin(void)
27841+{
27842+ dbgaufs_fin();
e49829fe
JR
27843+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
27844+ kset_unregister(sysaufs_kset);
1facf9fc 27845+}
27846+
27847+int __init sysaufs_init(void)
27848+{
27849+ int err;
27850+
27851+ do {
27852+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
27853+ } while (!sysaufs_si_mask);
27854+
4a4d8108 27855+ err = -EINVAL;
e49829fe
JR
27856+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
27857+ if (unlikely(!sysaufs_kset))
4a4d8108 27858+ goto out;
e49829fe
JR
27859+ err = PTR_ERR(sysaufs_kset);
27860+ if (IS_ERR(sysaufs_kset))
1facf9fc 27861+ goto out;
e49829fe 27862+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 27863+ if (unlikely(err)) {
e49829fe 27864+ kset_unregister(sysaufs_kset);
1facf9fc 27865+ goto out;
27866+ }
27867+
27868+ err = dbgaufs_init();
27869+ if (unlikely(err))
27870+ sysaufs_fin();
4f0767ce 27871+out:
1facf9fc 27872+ return err;
27873+}
7f207e10
AM
27874diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
27875--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 27876+++ linux/fs/aufs/sysaufs.h 2015-04-13 15:10:20.790157026 +0200
c1595e42 27877@@ -0,0 +1,101 @@
1facf9fc 27878+/*
2000de60 27879+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 27880+ *
27881+ * This program, aufs is free software; you can redistribute it and/or modify
27882+ * it under the terms of the GNU General Public License as published by
27883+ * the Free Software Foundation; either version 2 of the License, or
27884+ * (at your option) any later version.
dece6358
AM
27885+ *
27886+ * This program is distributed in the hope that it will be useful,
27887+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27888+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27889+ * GNU General Public License for more details.
27890+ *
27891+ * You should have received a copy of the GNU General Public License
523b37e3 27892+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27893+ */
27894+
27895+/*
27896+ * sysfs interface and mount lifetime management
27897+ */
27898+
27899+#ifndef __SYSAUFS_H__
27900+#define __SYSAUFS_H__
27901+
27902+#ifdef __KERNEL__
27903+
1facf9fc 27904+#include <linux/sysfs.h>
1facf9fc 27905+#include "module.h"
27906+
dece6358
AM
27907+struct super_block;
27908+struct au_sbinfo;
27909+
1facf9fc 27910+struct sysaufs_si_attr {
27911+ struct attribute attr;
27912+ int (*show)(struct seq_file *seq, struct super_block *sb);
27913+};
27914+
27915+/* ---------------------------------------------------------------------- */
27916+
27917+/* sysaufs.c */
27918+extern unsigned long sysaufs_si_mask;
e49829fe 27919+extern struct kset *sysaufs_kset;
1facf9fc 27920+extern struct attribute *sysaufs_si_attrs[];
27921+int sysaufs_si_init(struct au_sbinfo *sbinfo);
27922+int __init sysaufs_init(void);
27923+void sysaufs_fin(void);
27924+
27925+/* ---------------------------------------------------------------------- */
27926+
27927+/* some people doesn't like to show a pointer in kernel */
27928+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
27929+{
27930+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
27931+}
27932+
27933+#define SysaufsSiNamePrefix "si_"
27934+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
27935+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
27936+{
27937+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
27938+ sysaufs_si_id(sbinfo));
27939+}
27940+
27941+struct au_branch;
27942+#ifdef CONFIG_SYSFS
27943+/* sysfs.c */
27944+extern struct attribute_group *sysaufs_attr_group;
27945+
27946+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
27947+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
27948+ char *buf);
076b876e
AM
27949+long au_brinfo_ioctl(struct file *file, unsigned long arg);
27950+#ifdef CONFIG_COMPAT
27951+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
27952+#endif
1facf9fc 27953+
27954+void sysaufs_br_init(struct au_branch *br);
27955+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
27956+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
27957+
27958+#define sysaufs_brs_init() do {} while (0)
27959+
27960+#else
27961+#define sysaufs_attr_group NULL
27962+
4a4d8108 27963+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
c1595e42
JR
27964+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
27965+ struct attribute *attr, char *buf)
4a4d8108
AM
27966+AuStubVoid(sysaufs_br_init, struct au_branch *br)
27967+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
27968+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 27969+
27970+static inline void sysaufs_brs_init(void)
27971+{
27972+ sysaufs_brs = 0;
27973+}
27974+
27975+#endif /* CONFIG_SYSFS */
27976+
27977+#endif /* __KERNEL__ */
27978+#endif /* __SYSAUFS_H__ */
7f207e10
AM
27979diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
27980--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 27981+++ linux/fs/aufs/sysfs.c 2015-04-13 15:10:20.790157026 +0200
076b876e 27982@@ -0,0 +1,372 @@
1facf9fc 27983+/*
2000de60 27984+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 27985+ *
27986+ * This program, aufs is free software; you can redistribute it and/or modify
27987+ * it under the terms of the GNU General Public License as published by
27988+ * the Free Software Foundation; either version 2 of the License, or
27989+ * (at your option) any later version.
dece6358
AM
27990+ *
27991+ * This program is distributed in the hope that it will be useful,
27992+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27993+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27994+ * GNU General Public License for more details.
27995+ *
27996+ * You should have received a copy of the GNU General Public License
523b37e3 27997+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27998+ */
27999+
28000+/*
28001+ * sysfs interface
28002+ */
28003+
076b876e 28004+#include <linux/compat.h>
1facf9fc 28005+#include <linux/seq_file.h>
1facf9fc 28006+#include "aufs.h"
28007+
4a4d8108
AM
28008+#ifdef CONFIG_AUFS_FS_MODULE
28009+/* this entry violates the "one line per file" policy of sysfs */
28010+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
28011+ char *buf)
28012+{
28013+ ssize_t err;
28014+ static char *conf =
28015+/* this file is generated at compiling */
28016+#include "conf.str"
28017+ ;
28018+
28019+ err = snprintf(buf, PAGE_SIZE, conf);
28020+ if (unlikely(err >= PAGE_SIZE))
28021+ err = -EFBIG;
28022+ return err;
28023+}
28024+
28025+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
28026+#endif
28027+
1facf9fc 28028+static struct attribute *au_attr[] = {
4a4d8108
AM
28029+#ifdef CONFIG_AUFS_FS_MODULE
28030+ &au_config_attr.attr,
28031+#endif
1facf9fc 28032+ NULL, /* need to NULL terminate the list of attributes */
28033+};
28034+
28035+static struct attribute_group sysaufs_attr_group_body = {
28036+ .attrs = au_attr
28037+};
28038+
28039+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
28040+
28041+/* ---------------------------------------------------------------------- */
28042+
28043+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
28044+{
28045+ int err;
28046+
dece6358
AM
28047+ SiMustAnyLock(sb);
28048+
1facf9fc 28049+ err = 0;
28050+ if (au_opt_test(au_mntflags(sb), XINO)) {
28051+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
28052+ seq_putc(seq, '\n');
28053+ }
28054+ return err;
28055+}
28056+
28057+/*
28058+ * the lifetime of branch is independent from the entry under sysfs.
28059+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
28060+ * unlinked.
28061+ */
28062+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 28063+ aufs_bindex_t bindex, int idx)
1facf9fc 28064+{
1e00d052 28065+ int err;
1facf9fc 28066+ struct path path;
28067+ struct dentry *root;
28068+ struct au_branch *br;
076b876e 28069+ au_br_perm_str_t perm;
1facf9fc 28070+
28071+ AuDbg("b%d\n", bindex);
28072+
1e00d052 28073+ err = 0;
1facf9fc 28074+ root = sb->s_root;
28075+ di_read_lock_parent(root, !AuLock_IR);
28076+ br = au_sbr(sb, bindex);
392086de
AM
28077+
28078+ switch (idx) {
28079+ case AuBrSysfs_BR:
28080+ path.mnt = au_br_mnt(br);
28081+ path.dentry = au_h_dptr(root, bindex);
28082+ au_seq_path(seq, &path);
076b876e
AM
28083+ au_optstr_br_perm(&perm, br->br_perm);
28084+ err = seq_printf(seq, "=%s\n", perm.a);
392086de
AM
28085+ break;
28086+ case AuBrSysfs_BRID:
28087+ err = seq_printf(seq, "%d\n", br->br_id);
392086de
AM
28088+ break;
28089+ }
076b876e
AM
28090+ di_read_unlock(root, !AuLock_IR);
28091+ if (err == -1)
28092+ err = -E2BIG;
392086de 28093+
1e00d052 28094+ return err;
1facf9fc 28095+}
28096+
28097+/* ---------------------------------------------------------------------- */
28098+
28099+static struct seq_file *au_seq(char *p, ssize_t len)
28100+{
28101+ struct seq_file *seq;
28102+
28103+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
28104+ if (seq) {
28105+ /* mutex_init(&seq.lock); */
28106+ seq->buf = p;
28107+ seq->size = len;
28108+ return seq; /* success */
28109+ }
28110+
28111+ seq = ERR_PTR(-ENOMEM);
28112+ return seq;
28113+}
28114+
392086de
AM
28115+#define SysaufsBr_PREFIX "br"
28116+#define SysaufsBrid_PREFIX "brid"
1facf9fc 28117+
28118+/* todo: file size may exceed PAGE_SIZE */
28119+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 28120+ char *buf)
1facf9fc 28121+{
28122+ ssize_t err;
392086de 28123+ int idx;
1facf9fc 28124+ long l;
28125+ aufs_bindex_t bend;
28126+ struct au_sbinfo *sbinfo;
28127+ struct super_block *sb;
28128+ struct seq_file *seq;
28129+ char *name;
28130+ struct attribute **cattr;
28131+
28132+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
28133+ sb = sbinfo->si_sb;
1308ab2a 28134+
28135+ /*
28136+ * prevent a race condition between sysfs and aufs.
28137+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
28138+ * prohibits maintaining the sysfs entries.
28139+ * hew we acquire read lock after sysfs_get_active_two().
28140+ * on the other hand, the remount process may maintain the sysfs/aufs
28141+ * entries after acquiring write lock.
28142+ * it can cause a deadlock.
28143+ * simply we gave up processing read here.
28144+ */
28145+ err = -EBUSY;
28146+ if (unlikely(!si_noflush_read_trylock(sb)))
28147+ goto out;
1facf9fc 28148+
28149+ seq = au_seq(buf, PAGE_SIZE);
28150+ err = PTR_ERR(seq);
28151+ if (IS_ERR(seq))
1308ab2a 28152+ goto out_unlock;
1facf9fc 28153+
28154+ name = (void *)attr->name;
28155+ cattr = sysaufs_si_attrs;
28156+ while (*cattr) {
28157+ if (!strcmp(name, (*cattr)->name)) {
28158+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
28159+ ->show(seq, sb);
28160+ goto out_seq;
28161+ }
28162+ cattr++;
28163+ }
28164+
392086de
AM
28165+ if (!strncmp(name, SysaufsBrid_PREFIX,
28166+ sizeof(SysaufsBrid_PREFIX) - 1)) {
28167+ idx = AuBrSysfs_BRID;
28168+ name += sizeof(SysaufsBrid_PREFIX) - 1;
28169+ } else if (!strncmp(name, SysaufsBr_PREFIX,
28170+ sizeof(SysaufsBr_PREFIX) - 1)) {
28171+ idx = AuBrSysfs_BR;
1facf9fc 28172+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
28173+ } else
28174+ BUG();
28175+
28176+ err = kstrtol(name, 10, &l);
28177+ if (!err) {
28178+ bend = au_sbend(sb);
28179+ if (l <= bend)
28180+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
28181+ else
28182+ err = -ENOENT;
1facf9fc 28183+ }
1facf9fc 28184+
4f0767ce 28185+out_seq:
1facf9fc 28186+ if (!err) {
28187+ err = seq->count;
28188+ /* sysfs limit */
28189+ if (unlikely(err == PAGE_SIZE))
28190+ err = -EFBIG;
28191+ }
28192+ kfree(seq);
4f0767ce 28193+out_unlock:
1facf9fc 28194+ si_read_unlock(sb);
4f0767ce 28195+out:
1facf9fc 28196+ return err;
28197+}
28198+
28199+/* ---------------------------------------------------------------------- */
28200+
076b876e
AM
28201+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
28202+{
28203+ int err;
28204+ int16_t brid;
28205+ aufs_bindex_t bindex, bend;
28206+ size_t sz;
28207+ char *buf;
28208+ struct seq_file *seq;
28209+ struct au_branch *br;
28210+
28211+ si_read_lock(sb, AuLock_FLUSH);
28212+ bend = au_sbend(sb);
28213+ err = bend + 1;
28214+ if (!arg)
28215+ goto out;
28216+
28217+ err = -ENOMEM;
28218+ buf = (void *)__get_free_page(GFP_NOFS);
28219+ if (unlikely(!buf))
28220+ goto out;
28221+
28222+ seq = au_seq(buf, PAGE_SIZE);
28223+ err = PTR_ERR(seq);
28224+ if (IS_ERR(seq))
28225+ goto out_buf;
28226+
28227+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
28228+ for (bindex = 0; bindex <= bend; bindex++, arg++) {
28229+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
28230+ if (unlikely(err))
28231+ break;
28232+
28233+ br = au_sbr(sb, bindex);
28234+ brid = br->br_id;
28235+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
28236+ err = __put_user(brid, &arg->id);
28237+ if (unlikely(err))
28238+ break;
28239+
28240+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
28241+ err = __put_user(br->br_perm, &arg->perm);
28242+ if (unlikely(err))
28243+ break;
28244+
28245+ au_seq_path(seq, &br->br_path);
28246+ err = seq_putc(seq, '\0');
28247+ if (!err && seq->count <= sz) {
28248+ err = copy_to_user(arg->path, seq->buf, seq->count);
28249+ seq->count = 0;
28250+ if (unlikely(err))
28251+ break;
28252+ } else {
28253+ err = -E2BIG;
28254+ goto out_seq;
28255+ }
28256+ }
28257+ if (unlikely(err))
28258+ err = -EFAULT;
28259+
28260+out_seq:
28261+ kfree(seq);
28262+out_buf:
28263+ free_page((unsigned long)buf);
28264+out:
28265+ si_read_unlock(sb);
28266+ return err;
28267+}
28268+
28269+long au_brinfo_ioctl(struct file *file, unsigned long arg)
28270+{
2000de60 28271+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
076b876e
AM
28272+}
28273+
28274+#ifdef CONFIG_COMPAT
28275+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
28276+{
2000de60 28277+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
076b876e
AM
28278+}
28279+#endif
28280+
28281+/* ---------------------------------------------------------------------- */
28282+
1facf9fc 28283+void sysaufs_br_init(struct au_branch *br)
28284+{
392086de
AM
28285+ int i;
28286+ struct au_brsysfs *br_sysfs;
28287+ struct attribute *attr;
4a4d8108 28288+
392086de
AM
28289+ br_sysfs = br->br_sysfs;
28290+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28291+ attr = &br_sysfs->attr;
28292+ sysfs_attr_init(attr);
28293+ attr->name = br_sysfs->name;
28294+ attr->mode = S_IRUGO;
28295+ br_sysfs++;
28296+ }
1facf9fc 28297+}
28298+
28299+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
28300+{
28301+ struct au_branch *br;
28302+ struct kobject *kobj;
392086de
AM
28303+ struct au_brsysfs *br_sysfs;
28304+ int i;
1facf9fc 28305+ aufs_bindex_t bend;
28306+
28307+ dbgaufs_brs_del(sb, bindex);
28308+
28309+ if (!sysaufs_brs)
28310+ return;
28311+
28312+ kobj = &au_sbi(sb)->si_kobj;
28313+ bend = au_sbend(sb);
28314+ for (; bindex <= bend; bindex++) {
28315+ br = au_sbr(sb, bindex);
392086de
AM
28316+ br_sysfs = br->br_sysfs;
28317+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28318+ sysfs_remove_file(kobj, &br_sysfs->attr);
28319+ br_sysfs++;
28320+ }
1facf9fc 28321+ }
28322+}
28323+
28324+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
28325+{
392086de 28326+ int err, i;
1facf9fc 28327+ aufs_bindex_t bend;
28328+ struct kobject *kobj;
28329+ struct au_branch *br;
392086de 28330+ struct au_brsysfs *br_sysfs;
1facf9fc 28331+
28332+ dbgaufs_brs_add(sb, bindex);
28333+
28334+ if (!sysaufs_brs)
28335+ return;
28336+
28337+ kobj = &au_sbi(sb)->si_kobj;
28338+ bend = au_sbend(sb);
28339+ for (; bindex <= bend; bindex++) {
28340+ br = au_sbr(sb, bindex);
392086de
AM
28341+ br_sysfs = br->br_sysfs;
28342+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
28343+ SysaufsBr_PREFIX "%d", bindex);
28344+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
28345+ SysaufsBrid_PREFIX "%d", bindex);
28346+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28347+ err = sysfs_create_file(kobj, &br_sysfs->attr);
28348+ if (unlikely(err))
28349+ pr_warn("failed %s under sysfs(%d)\n",
28350+ br_sysfs->name, err);
28351+ br_sysfs++;
28352+ }
1facf9fc 28353+ }
28354+}
7f207e10
AM
28355diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
28356--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 28357+++ linux/fs/aufs/sysrq.c 2015-04-13 15:10:20.790157026 +0200
076b876e 28358@@ -0,0 +1,157 @@
1facf9fc 28359+/*
2000de60 28360+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28361+ *
28362+ * This program, aufs is free software; you can redistribute it and/or modify
28363+ * it under the terms of the GNU General Public License as published by
28364+ * the Free Software Foundation; either version 2 of the License, or
28365+ * (at your option) any later version.
dece6358
AM
28366+ *
28367+ * This program is distributed in the hope that it will be useful,
28368+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28369+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28370+ * GNU General Public License for more details.
28371+ *
28372+ * You should have received a copy of the GNU General Public License
523b37e3 28373+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28374+ */
28375+
28376+/*
28377+ * magic sysrq hanlder
28378+ */
28379+
1facf9fc 28380+/* #include <linux/sysrq.h> */
027c5e7a 28381+#include <linux/writeback.h>
1facf9fc 28382+#include "aufs.h"
28383+
28384+/* ---------------------------------------------------------------------- */
28385+
28386+static void sysrq_sb(struct super_block *sb)
28387+{
28388+ char *plevel;
28389+ struct au_sbinfo *sbinfo;
28390+ struct file *file;
523b37e3
AM
28391+ struct au_sphlhead *files;
28392+ struct au_finfo *finfo;
1facf9fc 28393+
28394+ plevel = au_plevel;
28395+ au_plevel = KERN_WARNING;
1facf9fc 28396+
4a4d8108 28397+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
28398+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
28399+
28400+ sbinfo = au_sbi(sb);
4a4d8108 28401+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 28402+ pr("superblock\n");
1facf9fc 28403+ au_dpri_sb(sb);
027c5e7a
AM
28404+
28405+#if 0
c06a8ce3 28406+ pr("root dentry\n");
1facf9fc 28407+ au_dpri_dentry(sb->s_root);
c06a8ce3 28408+ pr("root inode\n");
1facf9fc 28409+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
28410+#endif
28411+
1facf9fc 28412+#if 0
027c5e7a
AM
28413+ do {
28414+ int err, i, j, ndentry;
28415+ struct au_dcsub_pages dpages;
28416+ struct au_dpage *dpage;
28417+
28418+ err = au_dpages_init(&dpages, GFP_ATOMIC);
28419+ if (unlikely(err))
28420+ break;
28421+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
28422+ if (!err)
28423+ for (i = 0; i < dpages.ndpage; i++) {
28424+ dpage = dpages.dpages + i;
28425+ ndentry = dpage->ndentry;
28426+ for (j = 0; j < ndentry; j++)
28427+ au_dpri_dentry(dpage->dentries[j]);
28428+ }
28429+ au_dpages_free(&dpages);
28430+ } while (0);
28431+#endif
28432+
28433+#if 1
28434+ {
28435+ struct inode *i;
076b876e 28436+
c06a8ce3 28437+ pr("isolated inode\n");
2cbb1c4b
JR
28438+ spin_lock(&inode_sb_list_lock);
28439+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
28440+ spin_lock(&i->i_lock);
b4510431 28441+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 28442+ au_dpri_inode(i);
2cbb1c4b
JR
28443+ spin_unlock(&i->i_lock);
28444+ }
28445+ spin_unlock(&inode_sb_list_lock);
027c5e7a 28446+ }
1facf9fc 28447+#endif
c06a8ce3 28448+ pr("files\n");
523b37e3
AM
28449+ files = &au_sbi(sb)->si_files;
28450+ spin_lock(&files->spin);
28451+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
4a4d8108 28452+ umode_t mode;
076b876e 28453+
523b37e3 28454+ file = finfo->fi_file;
c06a8ce3 28455+ mode = file_inode(file)->i_mode;
38d290e6 28456+ if (!special_file(mode))
1facf9fc 28457+ au_dpri_file(file);
523b37e3
AM
28458+ }
28459+ spin_unlock(&files->spin);
c06a8ce3 28460+ pr("done\n");
1facf9fc 28461+
c06a8ce3 28462+#undef pr
1facf9fc 28463+ au_plevel = plevel;
1facf9fc 28464+}
28465+
28466+/* ---------------------------------------------------------------------- */
28467+
28468+/* module parameter */
28469+static char *aufs_sysrq_key = "a";
28470+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
28471+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
28472+
0c5527e5 28473+static void au_sysrq(int key __maybe_unused)
1facf9fc 28474+{
1facf9fc 28475+ struct au_sbinfo *sbinfo;
28476+
027c5e7a 28477+ lockdep_off();
53392da6 28478+ au_sbilist_lock();
e49829fe 28479+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 28480+ sysrq_sb(sbinfo->si_sb);
53392da6 28481+ au_sbilist_unlock();
027c5e7a 28482+ lockdep_on();
1facf9fc 28483+}
28484+
28485+static struct sysrq_key_op au_sysrq_op = {
28486+ .handler = au_sysrq,
28487+ .help_msg = "Aufs",
28488+ .action_msg = "Aufs",
28489+ .enable_mask = SYSRQ_ENABLE_DUMP
28490+};
28491+
28492+/* ---------------------------------------------------------------------- */
28493+
28494+int __init au_sysrq_init(void)
28495+{
28496+ int err;
28497+ char key;
28498+
28499+ err = -1;
28500+ key = *aufs_sysrq_key;
28501+ if ('a' <= key && key <= 'z')
28502+ err = register_sysrq_key(key, &au_sysrq_op);
28503+ if (unlikely(err))
4a4d8108 28504+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 28505+ return err;
28506+}
28507+
28508+void au_sysrq_fin(void)
28509+{
28510+ int err;
076b876e 28511+
1facf9fc 28512+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
28513+ if (unlikely(err))
4a4d8108 28514+ pr_err("err %d (ignored)\n", err);
1facf9fc 28515+}
7f207e10
AM
28516diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
28517--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 28518+++ linux/fs/aufs/vdir.c 2015-04-13 15:10:20.790157026 +0200
076b876e 28519@@ -0,0 +1,889 @@
1facf9fc 28520+/*
2000de60 28521+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28522+ *
28523+ * This program, aufs is free software; you can redistribute it and/or modify
28524+ * it under the terms of the GNU General Public License as published by
28525+ * the Free Software Foundation; either version 2 of the License, or
28526+ * (at your option) any later version.
dece6358
AM
28527+ *
28528+ * This program is distributed in the hope that it will be useful,
28529+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28530+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28531+ * GNU General Public License for more details.
28532+ *
28533+ * You should have received a copy of the GNU General Public License
523b37e3 28534+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28535+ */
28536+
28537+/*
28538+ * virtual or vertical directory
28539+ */
28540+
28541+#include "aufs.h"
28542+
dece6358 28543+static unsigned int calc_size(int nlen)
1facf9fc 28544+{
dece6358 28545+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 28546+}
28547+
28548+static int set_deblk_end(union au_vdir_deblk_p *p,
28549+ union au_vdir_deblk_p *deblk_end)
28550+{
28551+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
28552+ p->de->de_str.len = 0;
28553+ /* smp_mb(); */
28554+ return 0;
28555+ }
28556+ return -1; /* error */
28557+}
28558+
28559+/* returns true or false */
28560+static int is_deblk_end(union au_vdir_deblk_p *p,
28561+ union au_vdir_deblk_p *deblk_end)
28562+{
28563+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
28564+ return !p->de->de_str.len;
28565+ return 1;
28566+}
28567+
28568+static unsigned char *last_deblk(struct au_vdir *vdir)
28569+{
28570+ return vdir->vd_deblk[vdir->vd_nblk - 1];
28571+}
28572+
28573+/* ---------------------------------------------------------------------- */
28574+
1308ab2a 28575+/* estimate the apropriate size for name hash table */
28576+unsigned int au_rdhash_est(loff_t sz)
28577+{
28578+ unsigned int n;
28579+
28580+ n = UINT_MAX;
28581+ sz >>= 10;
28582+ if (sz < n)
28583+ n = sz;
28584+ if (sz < AUFS_RDHASH_DEF)
28585+ n = AUFS_RDHASH_DEF;
4a4d8108 28586+ /* pr_info("n %u\n", n); */
1308ab2a 28587+ return n;
28588+}
28589+
1facf9fc 28590+/*
28591+ * the allocated memory has to be freed by
dece6358 28592+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 28593+ */
dece6358 28594+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 28595+{
1facf9fc 28596+ struct hlist_head *head;
dece6358 28597+ unsigned int u;
076b876e 28598+ size_t sz;
1facf9fc 28599+
076b876e
AM
28600+ sz = sizeof(*nhash->nh_head) * num_hash;
28601+ head = kmalloc(sz, gfp);
dece6358
AM
28602+ if (head) {
28603+ nhash->nh_num = num_hash;
28604+ nhash->nh_head = head;
28605+ for (u = 0; u < num_hash; u++)
1facf9fc 28606+ INIT_HLIST_HEAD(head++);
dece6358 28607+ return 0; /* success */
1facf9fc 28608+ }
1facf9fc 28609+
dece6358 28610+ return -ENOMEM;
1facf9fc 28611+}
28612+
dece6358
AM
28613+static void nhash_count(struct hlist_head *head)
28614+{
28615+#if 0
28616+ unsigned long n;
28617+ struct hlist_node *pos;
28618+
28619+ n = 0;
28620+ hlist_for_each(pos, head)
28621+ n++;
4a4d8108 28622+ pr_info("%lu\n", n);
dece6358
AM
28623+#endif
28624+}
28625+
28626+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 28627+{
c06a8ce3
AM
28628+ struct au_vdir_wh *pos;
28629+ struct hlist_node *node;
1facf9fc 28630+
c06a8ce3
AM
28631+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
28632+ kfree(pos);
1facf9fc 28633+}
28634+
dece6358 28635+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 28636+{
c06a8ce3
AM
28637+ struct au_vdir_dehstr *pos;
28638+ struct hlist_node *node;
1facf9fc 28639+
c06a8ce3
AM
28640+ hlist_for_each_entry_safe(pos, node, head, hash)
28641+ au_cache_free_vdir_dehstr(pos);
1facf9fc 28642+}
28643+
dece6358
AM
28644+static void au_nhash_do_free(struct au_nhash *nhash,
28645+ void (*free)(struct hlist_head *head))
1facf9fc 28646+{
1308ab2a 28647+ unsigned int n;
1facf9fc 28648+ struct hlist_head *head;
1facf9fc 28649+
dece6358 28650+ n = nhash->nh_num;
1308ab2a 28651+ if (!n)
28652+ return;
28653+
dece6358 28654+ head = nhash->nh_head;
1308ab2a 28655+ while (n-- > 0) {
dece6358
AM
28656+ nhash_count(head);
28657+ free(head++);
1facf9fc 28658+ }
dece6358 28659+ kfree(nhash->nh_head);
1facf9fc 28660+}
28661+
dece6358 28662+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 28663+{
dece6358
AM
28664+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
28665+}
1facf9fc 28666+
dece6358
AM
28667+static void au_nhash_de_free(struct au_nhash *delist)
28668+{
28669+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 28670+}
28671+
28672+/* ---------------------------------------------------------------------- */
28673+
28674+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
28675+ int limit)
28676+{
28677+ int num;
28678+ unsigned int u, n;
28679+ struct hlist_head *head;
c06a8ce3 28680+ struct au_vdir_wh *pos;
1facf9fc 28681+
28682+ num = 0;
28683+ n = whlist->nh_num;
28684+ head = whlist->nh_head;
1308ab2a 28685+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
28686+ hlist_for_each_entry(pos, head, wh_hash)
28687+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 28688+ return 1;
1facf9fc 28689+ return 0;
28690+}
28691+
28692+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 28693+ unsigned char *name,
1facf9fc 28694+ unsigned int len)
28695+{
dece6358
AM
28696+ unsigned int v;
28697+ /* const unsigned int magic_bit = 12; */
28698+
1308ab2a 28699+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
28700+
dece6358
AM
28701+ v = 0;
28702+ while (len--)
28703+ v += *name++;
28704+ /* v = hash_long(v, magic_bit); */
28705+ v %= nhash->nh_num;
28706+ return nhash->nh_head + v;
28707+}
28708+
28709+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
28710+ int nlen)
28711+{
28712+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 28713+}
28714+
28715+/* returns found or not */
dece6358 28716+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 28717+{
28718+ struct hlist_head *head;
c06a8ce3 28719+ struct au_vdir_wh *pos;
1facf9fc 28720+ struct au_vdir_destr *str;
28721+
dece6358 28722+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
28723+ hlist_for_each_entry(pos, head, wh_hash) {
28724+ str = &pos->wh_str;
1facf9fc 28725+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
28726+ if (au_nhash_test_name(str, name, nlen))
28727+ return 1;
28728+ }
28729+ return 0;
28730+}
28731+
28732+/* returns found(true) or not */
28733+static int test_known(struct au_nhash *delist, char *name, int nlen)
28734+{
28735+ struct hlist_head *head;
c06a8ce3 28736+ struct au_vdir_dehstr *pos;
dece6358
AM
28737+ struct au_vdir_destr *str;
28738+
28739+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
28740+ hlist_for_each_entry(pos, head, hash) {
28741+ str = pos->str;
dece6358
AM
28742+ AuDbg("%.*s\n", str->len, str->name);
28743+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 28744+ return 1;
28745+ }
28746+ return 0;
28747+}
28748+
dece6358
AM
28749+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
28750+ unsigned char d_type)
28751+{
28752+#ifdef CONFIG_AUFS_SHWH
28753+ wh->wh_ino = ino;
28754+ wh->wh_type = d_type;
28755+#endif
28756+}
28757+
28758+/* ---------------------------------------------------------------------- */
28759+
28760+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
28761+ unsigned int d_type, aufs_bindex_t bindex,
28762+ unsigned char shwh)
1facf9fc 28763+{
28764+ int err;
28765+ struct au_vdir_destr *str;
28766+ struct au_vdir_wh *wh;
28767+
dece6358 28768+ AuDbg("%.*s\n", nlen, name);
1308ab2a 28769+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
28770+
1facf9fc 28771+ err = -ENOMEM;
dece6358 28772+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 28773+ if (unlikely(!wh))
28774+ goto out;
28775+
28776+ err = 0;
28777+ wh->wh_bindex = bindex;
dece6358
AM
28778+ if (shwh)
28779+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 28780+ str = &wh->wh_str;
dece6358
AM
28781+ str->len = nlen;
28782+ memcpy(str->name, name, nlen);
28783+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 28784+ /* smp_mb(); */
28785+
4f0767ce 28786+out:
1facf9fc 28787+ return err;
28788+}
28789+
1facf9fc 28790+static int append_deblk(struct au_vdir *vdir)
28791+{
28792+ int err;
dece6358 28793+ unsigned long ul;
1facf9fc 28794+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
28795+ union au_vdir_deblk_p p, deblk_end;
28796+ unsigned char **o;
28797+
28798+ err = -ENOMEM;
dece6358
AM
28799+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
28800+ GFP_NOFS);
1facf9fc 28801+ if (unlikely(!o))
28802+ goto out;
28803+
28804+ vdir->vd_deblk = o;
28805+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
28806+ if (p.deblk) {
28807+ ul = vdir->vd_nblk++;
28808+ vdir->vd_deblk[ul] = p.deblk;
28809+ vdir->vd_last.ul = ul;
28810+ vdir->vd_last.p.deblk = p.deblk;
28811+ deblk_end.deblk = p.deblk + deblk_sz;
28812+ err = set_deblk_end(&p, &deblk_end);
28813+ }
28814+
4f0767ce 28815+out:
1facf9fc 28816+ return err;
28817+}
28818+
dece6358
AM
28819+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
28820+ unsigned int d_type, struct au_nhash *delist)
28821+{
28822+ int err;
28823+ unsigned int sz;
28824+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
28825+ union au_vdir_deblk_p p, *room, deblk_end;
28826+ struct au_vdir_dehstr *dehstr;
28827+
28828+ p.deblk = last_deblk(vdir);
28829+ deblk_end.deblk = p.deblk + deblk_sz;
28830+ room = &vdir->vd_last.p;
28831+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
28832+ || !is_deblk_end(room, &deblk_end));
28833+
28834+ sz = calc_size(nlen);
28835+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
28836+ err = append_deblk(vdir);
28837+ if (unlikely(err))
28838+ goto out;
28839+
28840+ p.deblk = last_deblk(vdir);
28841+ deblk_end.deblk = p.deblk + deblk_sz;
28842+ /* smp_mb(); */
28843+ AuDebugOn(room->deblk != p.deblk);
28844+ }
28845+
28846+ err = -ENOMEM;
4a4d8108 28847+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
28848+ if (unlikely(!dehstr))
28849+ goto out;
28850+
28851+ dehstr->str = &room->de->de_str;
28852+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
28853+ room->de->de_ino = ino;
28854+ room->de->de_type = d_type;
28855+ room->de->de_str.len = nlen;
28856+ memcpy(room->de->de_str.name, name, nlen);
28857+
28858+ err = 0;
28859+ room->deblk += sz;
28860+ if (unlikely(set_deblk_end(room, &deblk_end)))
28861+ err = append_deblk(vdir);
28862+ /* smp_mb(); */
28863+
4f0767ce 28864+out:
dece6358
AM
28865+ return err;
28866+}
28867+
28868+/* ---------------------------------------------------------------------- */
28869+
28870+void au_vdir_free(struct au_vdir *vdir)
28871+{
28872+ unsigned char **deblk;
28873+
28874+ deblk = vdir->vd_deblk;
28875+ while (vdir->vd_nblk--)
28876+ kfree(*deblk++);
28877+ kfree(vdir->vd_deblk);
28878+ au_cache_free_vdir(vdir);
28879+}
28880+
1308ab2a 28881+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 28882+{
28883+ struct au_vdir *vdir;
1308ab2a 28884+ struct super_block *sb;
1facf9fc 28885+ int err;
28886+
2000de60 28887+ sb = file->f_path.dentry->d_sb;
dece6358
AM
28888+ SiMustAnyLock(sb);
28889+
1facf9fc 28890+ err = -ENOMEM;
28891+ vdir = au_cache_alloc_vdir();
28892+ if (unlikely(!vdir))
28893+ goto out;
28894+
28895+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
28896+ if (unlikely(!vdir->vd_deblk))
28897+ goto out_free;
28898+
28899+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 28900+ if (!vdir->vd_deblk_sz) {
28901+ /* estimate the apropriate size for deblk */
28902+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 28903+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 28904+ }
1facf9fc 28905+ vdir->vd_nblk = 0;
28906+ vdir->vd_version = 0;
28907+ vdir->vd_jiffy = 0;
28908+ err = append_deblk(vdir);
28909+ if (!err)
28910+ return vdir; /* success */
28911+
28912+ kfree(vdir->vd_deblk);
28913+
4f0767ce 28914+out_free:
1facf9fc 28915+ au_cache_free_vdir(vdir);
4f0767ce 28916+out:
1facf9fc 28917+ vdir = ERR_PTR(err);
28918+ return vdir;
28919+}
28920+
28921+static int reinit_vdir(struct au_vdir *vdir)
28922+{
28923+ int err;
28924+ union au_vdir_deblk_p p, deblk_end;
28925+
28926+ while (vdir->vd_nblk > 1) {
28927+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
28928+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
28929+ vdir->vd_nblk--;
28930+ }
28931+ p.deblk = vdir->vd_deblk[0];
28932+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
28933+ err = set_deblk_end(&p, &deblk_end);
28934+ /* keep vd_dblk_sz */
28935+ vdir->vd_last.ul = 0;
28936+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
28937+ vdir->vd_version = 0;
28938+ vdir->vd_jiffy = 0;
28939+ /* smp_mb(); */
28940+ return err;
28941+}
28942+
28943+/* ---------------------------------------------------------------------- */
28944+
1facf9fc 28945+#define AuFillVdir_CALLED 1
28946+#define AuFillVdir_WHABLE (1 << 1)
dece6358 28947+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 28948+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
28949+#define au_fset_fillvdir(flags, name) \
28950+ do { (flags) |= AuFillVdir_##name; } while (0)
28951+#define au_fclr_fillvdir(flags, name) \
28952+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 28953+
dece6358
AM
28954+#ifndef CONFIG_AUFS_SHWH
28955+#undef AuFillVdir_SHWH
28956+#define AuFillVdir_SHWH 0
28957+#endif
28958+
1facf9fc 28959+struct fillvdir_arg {
392086de 28960+ struct dir_context ctx;
1facf9fc 28961+ struct file *file;
28962+ struct au_vdir *vdir;
dece6358
AM
28963+ struct au_nhash delist;
28964+ struct au_nhash whlist;
1facf9fc 28965+ aufs_bindex_t bindex;
28966+ unsigned int flags;
28967+ int err;
28968+};
28969+
392086de 28970+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 28971+ loff_t offset __maybe_unused, u64 h_ino,
28972+ unsigned int d_type)
28973+{
392086de 28974+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 28975+ char *name = (void *)__name;
28976+ struct super_block *sb;
1facf9fc 28977+ ino_t ino;
dece6358 28978+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 28979+
1facf9fc 28980+ arg->err = 0;
2000de60 28981+ sb = arg->file->f_path.dentry->d_sb;
1facf9fc 28982+ au_fset_fillvdir(arg->flags, CALLED);
28983+ /* smp_mb(); */
dece6358 28984+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 28985+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
28986+ if (test_known(&arg->delist, name, nlen)
28987+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
28988+ goto out; /* already exists or whiteouted */
1facf9fc 28989+
2000de60 28990+ sb = arg->file->f_path.dentry->d_sb;
dece6358 28991+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
28992+ if (!arg->err) {
28993+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
28994+ d_type = DT_UNKNOWN;
dece6358
AM
28995+ arg->err = append_de(arg->vdir, name, nlen, ino,
28996+ d_type, &arg->delist);
4a4d8108 28997+ }
1facf9fc 28998+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
28999+ name += AUFS_WH_PFX_LEN;
dece6358
AM
29000+ nlen -= AUFS_WH_PFX_LEN;
29001+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
29002+ goto out; /* already whiteouted */
1facf9fc 29003+
dece6358
AM
29004+ if (shwh)
29005+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
29006+ &ino);
4a4d8108
AM
29007+ if (!arg->err) {
29008+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
29009+ d_type = DT_UNKNOWN;
1facf9fc 29010+ arg->err = au_nhash_append_wh
dece6358
AM
29011+ (&arg->whlist, name, nlen, ino, d_type,
29012+ arg->bindex, shwh);
4a4d8108 29013+ }
1facf9fc 29014+ }
29015+
4f0767ce 29016+out:
1facf9fc 29017+ if (!arg->err)
29018+ arg->vdir->vd_jiffy = jiffies;
29019+ /* smp_mb(); */
29020+ AuTraceErr(arg->err);
29021+ return arg->err;
29022+}
29023+
dece6358
AM
29024+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
29025+ struct au_nhash *whlist, struct au_nhash *delist)
29026+{
29027+#ifdef CONFIG_AUFS_SHWH
29028+ int err;
29029+ unsigned int nh, u;
29030+ struct hlist_head *head;
c06a8ce3
AM
29031+ struct au_vdir_wh *pos;
29032+ struct hlist_node *n;
dece6358
AM
29033+ char *p, *o;
29034+ struct au_vdir_destr *destr;
29035+
29036+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
29037+
29038+ err = -ENOMEM;
537831f9 29039+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
29040+ if (unlikely(!p))
29041+ goto out;
29042+
29043+ err = 0;
29044+ nh = whlist->nh_num;
29045+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29046+ p += AUFS_WH_PFX_LEN;
29047+ for (u = 0; u < nh; u++) {
29048+ head = whlist->nh_head + u;
c06a8ce3
AM
29049+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
29050+ destr = &pos->wh_str;
dece6358
AM
29051+ memcpy(p, destr->name, destr->len);
29052+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 29053+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
29054+ if (unlikely(err))
29055+ break;
29056+ }
29057+ }
29058+
537831f9 29059+ free_page((unsigned long)o);
dece6358 29060+
4f0767ce 29061+out:
dece6358
AM
29062+ AuTraceErr(err);
29063+ return err;
29064+#else
29065+ return 0;
29066+#endif
29067+}
29068+
1facf9fc 29069+static int au_do_read_vdir(struct fillvdir_arg *arg)
29070+{
29071+ int err;
dece6358 29072+ unsigned int rdhash;
1facf9fc 29073+ loff_t offset;
dece6358
AM
29074+ aufs_bindex_t bend, bindex, bstart;
29075+ unsigned char shwh;
1facf9fc 29076+ struct file *hf, *file;
29077+ struct super_block *sb;
29078+
1facf9fc 29079+ file = arg->file;
2000de60 29080+ sb = file->f_path.dentry->d_sb;
dece6358
AM
29081+ SiMustAnyLock(sb);
29082+
29083+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 29084+ if (!rdhash)
29085+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
29086+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
29087+ if (unlikely(err))
1facf9fc 29088+ goto out;
dece6358
AM
29089+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
29090+ if (unlikely(err))
1facf9fc 29091+ goto out_delist;
29092+
29093+ err = 0;
29094+ arg->flags = 0;
dece6358
AM
29095+ shwh = 0;
29096+ if (au_opt_test(au_mntflags(sb), SHWH)) {
29097+ shwh = 1;
29098+ au_fset_fillvdir(arg->flags, SHWH);
29099+ }
29100+ bstart = au_fbstart(file);
4a4d8108 29101+ bend = au_fbend_dir(file);
dece6358 29102+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 29103+ hf = au_hf_dir(file, bindex);
1facf9fc 29104+ if (!hf)
29105+ continue;
29106+
29107+ offset = vfsub_llseek(hf, 0, SEEK_SET);
29108+ err = offset;
29109+ if (unlikely(offset))
29110+ break;
29111+
29112+ arg->bindex = bindex;
29113+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
29114+ if (shwh
29115+ || (bindex != bend
29116+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 29117+ au_fset_fillvdir(arg->flags, WHABLE);
29118+ do {
29119+ arg->err = 0;
29120+ au_fclr_fillvdir(arg->flags, CALLED);
29121+ /* smp_mb(); */
392086de 29122+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 29123+ if (err >= 0)
29124+ err = arg->err;
29125+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
29126+
29127+ /*
29128+ * dir_relax() may be good for concurrency, but aufs should not
29129+ * use it since it will cause a lockdep problem.
29130+ */
1facf9fc 29131+ }
dece6358
AM
29132+
29133+ if (!err && shwh)
29134+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
29135+
29136+ au_nhash_wh_free(&arg->whlist);
1facf9fc 29137+
4f0767ce 29138+out_delist:
dece6358 29139+ au_nhash_de_free(&arg->delist);
4f0767ce 29140+out:
1facf9fc 29141+ return err;
29142+}
29143+
29144+static int read_vdir(struct file *file, int may_read)
29145+{
29146+ int err;
29147+ unsigned long expire;
29148+ unsigned char do_read;
392086de
AM
29149+ struct fillvdir_arg arg = {
29150+ .ctx = {
2000de60 29151+ .actor = fillvdir
392086de
AM
29152+ }
29153+ };
1facf9fc 29154+ struct inode *inode;
29155+ struct au_vdir *vdir, *allocated;
29156+
29157+ err = 0;
c06a8ce3 29158+ inode = file_inode(file);
1facf9fc 29159+ IMustLock(inode);
dece6358
AM
29160+ SiMustAnyLock(inode->i_sb);
29161+
1facf9fc 29162+ allocated = NULL;
29163+ do_read = 0;
29164+ expire = au_sbi(inode->i_sb)->si_rdcache;
29165+ vdir = au_ivdir(inode);
29166+ if (!vdir) {
29167+ do_read = 1;
1308ab2a 29168+ vdir = alloc_vdir(file);
1facf9fc 29169+ err = PTR_ERR(vdir);
29170+ if (IS_ERR(vdir))
29171+ goto out;
29172+ err = 0;
29173+ allocated = vdir;
29174+ } else if (may_read
29175+ && (inode->i_version != vdir->vd_version
29176+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
29177+ do_read = 1;
29178+ err = reinit_vdir(vdir);
29179+ if (unlikely(err))
29180+ goto out;
29181+ }
29182+
29183+ if (!do_read)
29184+ return 0; /* success */
29185+
29186+ arg.file = file;
29187+ arg.vdir = vdir;
29188+ err = au_do_read_vdir(&arg);
29189+ if (!err) {
392086de 29190+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 29191+ vdir->vd_version = inode->i_version;
29192+ vdir->vd_last.ul = 0;
29193+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
29194+ if (allocated)
29195+ au_set_ivdir(inode, allocated);
29196+ } else if (allocated)
29197+ au_vdir_free(allocated);
29198+
4f0767ce 29199+out:
1facf9fc 29200+ return err;
29201+}
29202+
29203+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
29204+{
29205+ int err, rerr;
29206+ unsigned long ul, n;
29207+ const unsigned int deblk_sz = src->vd_deblk_sz;
29208+
29209+ AuDebugOn(tgt->vd_nblk != 1);
29210+
29211+ err = -ENOMEM;
29212+ if (tgt->vd_nblk < src->vd_nblk) {
29213+ unsigned char **p;
29214+
dece6358
AM
29215+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
29216+ GFP_NOFS);
1facf9fc 29217+ if (unlikely(!p))
29218+ goto out;
29219+ tgt->vd_deblk = p;
29220+ }
29221+
1308ab2a 29222+ if (tgt->vd_deblk_sz != deblk_sz) {
29223+ unsigned char *p;
29224+
29225+ tgt->vd_deblk_sz = deblk_sz;
29226+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
29227+ if (unlikely(!p))
29228+ goto out;
29229+ tgt->vd_deblk[0] = p;
29230+ }
1facf9fc 29231+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 29232+ tgt->vd_version = src->vd_version;
29233+ tgt->vd_jiffy = src->vd_jiffy;
29234+
29235+ n = src->vd_nblk;
29236+ for (ul = 1; ul < n; ul++) {
dece6358
AM
29237+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
29238+ GFP_NOFS);
29239+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 29240+ goto out;
1308ab2a 29241+ tgt->vd_nblk++;
1facf9fc 29242+ }
1308ab2a 29243+ tgt->vd_nblk = n;
29244+ tgt->vd_last.ul = tgt->vd_last.ul;
29245+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
29246+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
29247+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 29248+ /* smp_mb(); */
29249+ return 0; /* success */
29250+
4f0767ce 29251+out:
1facf9fc 29252+ rerr = reinit_vdir(tgt);
29253+ BUG_ON(rerr);
29254+ return err;
29255+}
29256+
29257+int au_vdir_init(struct file *file)
29258+{
29259+ int err;
29260+ struct inode *inode;
29261+ struct au_vdir *vdir_cache, *allocated;
29262+
392086de 29263+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 29264+ err = read_vdir(file, !file->f_pos);
29265+ if (unlikely(err))
29266+ goto out;
29267+
29268+ allocated = NULL;
29269+ vdir_cache = au_fvdir_cache(file);
29270+ if (!vdir_cache) {
1308ab2a 29271+ vdir_cache = alloc_vdir(file);
1facf9fc 29272+ err = PTR_ERR(vdir_cache);
29273+ if (IS_ERR(vdir_cache))
29274+ goto out;
29275+ allocated = vdir_cache;
29276+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 29277+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 29278+ err = reinit_vdir(vdir_cache);
29279+ if (unlikely(err))
29280+ goto out;
29281+ } else
29282+ return 0; /* success */
29283+
c06a8ce3 29284+ inode = file_inode(file);
1facf9fc 29285+ err = copy_vdir(vdir_cache, au_ivdir(inode));
29286+ if (!err) {
29287+ file->f_version = inode->i_version;
29288+ if (allocated)
29289+ au_set_fvdir_cache(file, allocated);
29290+ } else if (allocated)
29291+ au_vdir_free(allocated);
29292+
4f0767ce 29293+out:
1facf9fc 29294+ return err;
29295+}
29296+
29297+static loff_t calc_offset(struct au_vdir *vdir)
29298+{
29299+ loff_t offset;
29300+ union au_vdir_deblk_p p;
29301+
29302+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
29303+ offset = vdir->vd_last.p.deblk - p.deblk;
29304+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
29305+ return offset;
29306+}
29307+
29308+/* returns true or false */
392086de 29309+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 29310+{
29311+ int valid;
29312+ unsigned int deblk_sz;
29313+ unsigned long ul, n;
29314+ loff_t offset;
29315+ union au_vdir_deblk_p p, deblk_end;
29316+ struct au_vdir *vdir_cache;
29317+
29318+ valid = 1;
29319+ vdir_cache = au_fvdir_cache(file);
29320+ offset = calc_offset(vdir_cache);
29321+ AuDbg("offset %lld\n", offset);
392086de 29322+ if (ctx->pos == offset)
1facf9fc 29323+ goto out;
29324+
29325+ vdir_cache->vd_last.ul = 0;
29326+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 29327+ if (!ctx->pos)
1facf9fc 29328+ goto out;
29329+
29330+ valid = 0;
29331+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 29332+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 29333+ AuDbg("ul %lu\n", ul);
29334+ if (ul >= vdir_cache->vd_nblk)
29335+ goto out;
29336+
29337+ n = vdir_cache->vd_nblk;
29338+ for (; ul < n; ul++) {
29339+ p.deblk = vdir_cache->vd_deblk[ul];
29340+ deblk_end.deblk = p.deblk + deblk_sz;
29341+ offset = ul;
29342+ offset *= deblk_sz;
392086de 29343+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 29344+ unsigned int l;
29345+
29346+ l = calc_size(p.de->de_str.len);
29347+ offset += l;
29348+ p.deblk += l;
29349+ }
29350+ if (!is_deblk_end(&p, &deblk_end)) {
29351+ valid = 1;
29352+ vdir_cache->vd_last.ul = ul;
29353+ vdir_cache->vd_last.p = p;
29354+ break;
29355+ }
29356+ }
29357+
4f0767ce 29358+out:
1facf9fc 29359+ /* smp_mb(); */
29360+ AuTraceErr(!valid);
29361+ return valid;
29362+}
29363+
392086de 29364+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 29365+{
1facf9fc 29366+ unsigned int l, deblk_sz;
29367+ union au_vdir_deblk_p deblk_end;
29368+ struct au_vdir *vdir_cache;
29369+ struct au_vdir_de *de;
29370+
29371+ vdir_cache = au_fvdir_cache(file);
392086de 29372+ if (!seek_vdir(file, ctx))
1facf9fc 29373+ return 0;
29374+
29375+ deblk_sz = vdir_cache->vd_deblk_sz;
29376+ while (1) {
29377+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
29378+ deblk_end.deblk += deblk_sz;
29379+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
29380+ de = vdir_cache->vd_last.p.de;
29381+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 29382+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 29383+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
29384+ if (unlikely(!dir_emit(ctx, de->de_str.name,
29385+ de->de_str.len, de->de_ino,
29386+ de->de_type))) {
1facf9fc 29387+ /* todo: ignore the error caused by udba? */
29388+ /* return err; */
29389+ return 0;
29390+ }
29391+
29392+ l = calc_size(de->de_str.len);
29393+ vdir_cache->vd_last.p.deblk += l;
392086de 29394+ ctx->pos += l;
1facf9fc 29395+ }
29396+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
29397+ vdir_cache->vd_last.ul++;
29398+ vdir_cache->vd_last.p.deblk
29399+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 29400+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 29401+ continue;
29402+ }
29403+ break;
29404+ }
29405+
29406+ /* smp_mb(); */
29407+ return 0;
29408+}
7f207e10
AM
29409diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
29410--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
29411+++ linux/fs/aufs/vfsub.c 2015-04-13 15:10:20.790157026 +0200
29412@@ -0,0 +1,795 @@
1facf9fc 29413+/*
2000de60 29414+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 29415+ *
29416+ * This program, aufs is free software; you can redistribute it and/or modify
29417+ * it under the terms of the GNU General Public License as published by
29418+ * the Free Software Foundation; either version 2 of the License, or
29419+ * (at your option) any later version.
dece6358
AM
29420+ *
29421+ * This program is distributed in the hope that it will be useful,
29422+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29423+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29424+ * GNU General Public License for more details.
29425+ *
29426+ * You should have received a copy of the GNU General Public License
523b37e3 29427+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29428+ */
29429+
29430+/*
29431+ * sub-routines for VFS
29432+ */
29433+
dece6358
AM
29434+#include <linux/namei.h>
29435+#include <linux/security.h>
29436+#include <linux/splice.h>
1facf9fc 29437+#include "aufs.h"
29438+
29439+int vfsub_update_h_iattr(struct path *h_path, int *did)
29440+{
29441+ int err;
29442+ struct kstat st;
29443+ struct super_block *h_sb;
29444+
29445+ /* for remote fs, leave work for its getattr or d_revalidate */
29446+ /* for bad i_attr fs, handle them in aufs_getattr() */
29447+ /* still some fs may acquire i_mutex. we need to skip them */
29448+ err = 0;
29449+ if (!did)
29450+ did = &err;
29451+ h_sb = h_path->dentry->d_sb;
29452+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
29453+ if (*did)
c06a8ce3 29454+ err = vfs_getattr(h_path, &st);
1facf9fc 29455+
29456+ return err;
29457+}
29458+
29459+/* ---------------------------------------------------------------------- */
29460+
4a4d8108 29461+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 29462+{
29463+ struct file *file;
29464+
b4510431 29465+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 29466+ current_cred());
2cbb1c4b
JR
29467+ if (!IS_ERR_OR_NULL(file)
29468+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
29469+ i_readcount_inc(path->dentry->d_inode);
4a4d8108 29470+
1308ab2a 29471+ return file;
29472+}
29473+
1facf9fc 29474+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
29475+{
29476+ struct file *file;
29477+
2cbb1c4b 29478+ lockdep_off();
7f207e10 29479+ file = filp_open(path,
2cbb1c4b 29480+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 29481+ mode);
2cbb1c4b 29482+ lockdep_on();
1facf9fc 29483+ if (IS_ERR(file))
29484+ goto out;
29485+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29486+
4f0767ce 29487+out:
1facf9fc 29488+ return file;
29489+}
29490+
29491+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
29492+{
29493+ int err;
29494+
1facf9fc 29495+ err = kern_path(name, flags, path);
1facf9fc 29496+ if (!err && path->dentry->d_inode)
29497+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
29498+ return err;
29499+}
29500+
29501+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
29502+ int len)
29503+{
29504+ struct path path = {
29505+ .mnt = NULL
29506+ };
29507+
1308ab2a 29508+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 29509+ IMustLock(parent->d_inode);
29510+
29511+ path.dentry = lookup_one_len(name, parent, len);
29512+ if (IS_ERR(path.dentry))
29513+ goto out;
29514+ if (path.dentry->d_inode)
29515+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
29516+
4f0767ce 29517+out:
4a4d8108 29518+ AuTraceErrPtr(path.dentry);
1facf9fc 29519+ return path.dentry;
29520+}
29521+
b4510431 29522+void vfsub_call_lkup_one(void *args)
2cbb1c4b 29523+{
b4510431
AM
29524+ struct vfsub_lkup_one_args *a = args;
29525+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
29526+}
29527+
1facf9fc 29528+/* ---------------------------------------------------------------------- */
29529+
29530+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
29531+ struct dentry *d2, struct au_hinode *hdir2)
29532+{
29533+ struct dentry *d;
29534+
2cbb1c4b 29535+ lockdep_off();
1facf9fc 29536+ d = lock_rename(d1, d2);
2cbb1c4b 29537+ lockdep_on();
4a4d8108 29538+ au_hn_suspend(hdir1);
1facf9fc 29539+ if (hdir1 != hdir2)
4a4d8108 29540+ au_hn_suspend(hdir2);
1facf9fc 29541+
29542+ return d;
29543+}
29544+
29545+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
29546+ struct dentry *d2, struct au_hinode *hdir2)
29547+{
4a4d8108 29548+ au_hn_resume(hdir1);
1facf9fc 29549+ if (hdir1 != hdir2)
4a4d8108 29550+ au_hn_resume(hdir2);
2cbb1c4b 29551+ lockdep_off();
1facf9fc 29552+ unlock_rename(d1, d2);
2cbb1c4b 29553+ lockdep_on();
1facf9fc 29554+}
29555+
29556+/* ---------------------------------------------------------------------- */
29557+
b4510431 29558+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 29559+{
29560+ int err;
29561+ struct dentry *d;
29562+
29563+ IMustLock(dir);
29564+
29565+ d = path->dentry;
29566+ path->dentry = d->d_parent;
b752ccd1 29567+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 29568+ path->dentry = d;
29569+ if (unlikely(err))
29570+ goto out;
29571+
c1595e42 29572+ lockdep_off();
b4510431 29573+ err = vfs_create(dir, path->dentry, mode, want_excl);
c1595e42 29574+ lockdep_on();
1facf9fc 29575+ if (!err) {
29576+ struct path tmp = *path;
29577+ int did;
29578+
29579+ vfsub_update_h_iattr(&tmp, &did);
29580+ if (did) {
29581+ tmp.dentry = path->dentry->d_parent;
29582+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29583+ }
29584+ /*ignore*/
29585+ }
29586+
4f0767ce 29587+out:
1facf9fc 29588+ return err;
29589+}
29590+
29591+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
29592+{
29593+ int err;
29594+ struct dentry *d;
29595+
29596+ IMustLock(dir);
29597+
29598+ d = path->dentry;
29599+ path->dentry = d->d_parent;
b752ccd1 29600+ err = security_path_symlink(path, d, symname);
1facf9fc 29601+ path->dentry = d;
29602+ if (unlikely(err))
29603+ goto out;
29604+
c1595e42 29605+ lockdep_off();
1facf9fc 29606+ err = vfs_symlink(dir, path->dentry, symname);
c1595e42 29607+ lockdep_on();
1facf9fc 29608+ if (!err) {
29609+ struct path tmp = *path;
29610+ int did;
29611+
29612+ vfsub_update_h_iattr(&tmp, &did);
29613+ if (did) {
29614+ tmp.dentry = path->dentry->d_parent;
29615+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29616+ }
29617+ /*ignore*/
29618+ }
29619+
4f0767ce 29620+out:
1facf9fc 29621+ return err;
29622+}
29623+
29624+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
29625+{
29626+ int err;
29627+ struct dentry *d;
29628+
29629+ IMustLock(dir);
29630+
29631+ d = path->dentry;
29632+ path->dentry = d->d_parent;
027c5e7a 29633+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 29634+ path->dentry = d;
29635+ if (unlikely(err))
29636+ goto out;
29637+
c1595e42 29638+ lockdep_off();
1facf9fc 29639+ err = vfs_mknod(dir, path->dentry, mode, dev);
c1595e42 29640+ lockdep_on();
1facf9fc 29641+ if (!err) {
29642+ struct path tmp = *path;
29643+ int did;
29644+
29645+ vfsub_update_h_iattr(&tmp, &did);
29646+ if (did) {
29647+ tmp.dentry = path->dentry->d_parent;
29648+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29649+ }
29650+ /*ignore*/
29651+ }
29652+
4f0767ce 29653+out:
1facf9fc 29654+ return err;
29655+}
29656+
29657+static int au_test_nlink(struct inode *inode)
29658+{
29659+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
29660+
29661+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
29662+ || inode->i_nlink < link_max)
29663+ return 0;
29664+ return -EMLINK;
29665+}
29666+
523b37e3
AM
29667+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
29668+ struct inode **delegated_inode)
1facf9fc 29669+{
29670+ int err;
29671+ struct dentry *d;
29672+
29673+ IMustLock(dir);
29674+
29675+ err = au_test_nlink(src_dentry->d_inode);
29676+ if (unlikely(err))
29677+ return err;
29678+
b4510431 29679+ /* we don't call may_linkat() */
1facf9fc 29680+ d = path->dentry;
29681+ path->dentry = d->d_parent;
b752ccd1 29682+ err = security_path_link(src_dentry, path, d);
1facf9fc 29683+ path->dentry = d;
29684+ if (unlikely(err))
29685+ goto out;
29686+
2cbb1c4b 29687+ lockdep_off();
523b37e3 29688+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 29689+ lockdep_on();
1facf9fc 29690+ if (!err) {
29691+ struct path tmp = *path;
29692+ int did;
29693+
29694+ /* fuse has different memory inode for the same inumber */
29695+ vfsub_update_h_iattr(&tmp, &did);
29696+ if (did) {
29697+ tmp.dentry = path->dentry->d_parent;
29698+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29699+ tmp.dentry = src_dentry;
29700+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29701+ }
29702+ /*ignore*/
29703+ }
29704+
4f0767ce 29705+out:
1facf9fc 29706+ return err;
29707+}
29708+
29709+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3
AM
29710+ struct inode *dir, struct path *path,
29711+ struct inode **delegated_inode)
1facf9fc 29712+{
29713+ int err;
29714+ struct path tmp = {
29715+ .mnt = path->mnt
29716+ };
29717+ struct dentry *d;
29718+
29719+ IMustLock(dir);
29720+ IMustLock(src_dir);
29721+
29722+ d = path->dentry;
29723+ path->dentry = d->d_parent;
29724+ tmp.dentry = src_dentry->d_parent;
38d290e6 29725+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 29726+ path->dentry = d;
29727+ if (unlikely(err))
29728+ goto out;
29729+
2cbb1c4b 29730+ lockdep_off();
523b37e3 29731+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
38d290e6 29732+ delegated_inode, /*flags*/0);
2cbb1c4b 29733+ lockdep_on();
1facf9fc 29734+ if (!err) {
29735+ int did;
29736+
29737+ tmp.dentry = d->d_parent;
29738+ vfsub_update_h_iattr(&tmp, &did);
29739+ if (did) {
29740+ tmp.dentry = src_dentry;
29741+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29742+ tmp.dentry = src_dentry->d_parent;
29743+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29744+ }
29745+ /*ignore*/
29746+ }
29747+
4f0767ce 29748+out:
1facf9fc 29749+ return err;
29750+}
29751+
29752+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
29753+{
29754+ int err;
29755+ struct dentry *d;
29756+
29757+ IMustLock(dir);
29758+
29759+ d = path->dentry;
29760+ path->dentry = d->d_parent;
b752ccd1 29761+ err = security_path_mkdir(path, d, mode);
1facf9fc 29762+ path->dentry = d;
29763+ if (unlikely(err))
29764+ goto out;
29765+
c1595e42 29766+ lockdep_off();
1facf9fc 29767+ err = vfs_mkdir(dir, path->dentry, mode);
c1595e42 29768+ lockdep_on();
1facf9fc 29769+ if (!err) {
29770+ struct path tmp = *path;
29771+ int did;
29772+
29773+ vfsub_update_h_iattr(&tmp, &did);
29774+ if (did) {
29775+ tmp.dentry = path->dentry->d_parent;
29776+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29777+ }
29778+ /*ignore*/
29779+ }
29780+
4f0767ce 29781+out:
1facf9fc 29782+ return err;
29783+}
29784+
29785+int vfsub_rmdir(struct inode *dir, struct path *path)
29786+{
29787+ int err;
29788+ struct dentry *d;
29789+
29790+ IMustLock(dir);
29791+
29792+ d = path->dentry;
29793+ path->dentry = d->d_parent;
b752ccd1 29794+ err = security_path_rmdir(path, d);
1facf9fc 29795+ path->dentry = d;
29796+ if (unlikely(err))
29797+ goto out;
29798+
2cbb1c4b 29799+ lockdep_off();
1facf9fc 29800+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 29801+ lockdep_on();
1facf9fc 29802+ if (!err) {
29803+ struct path tmp = {
29804+ .dentry = path->dentry->d_parent,
29805+ .mnt = path->mnt
29806+ };
29807+
29808+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
29809+ }
29810+
4f0767ce 29811+out:
1facf9fc 29812+ return err;
29813+}
29814+
29815+/* ---------------------------------------------------------------------- */
29816+
9dbd164d 29817+/* todo: support mmap_sem? */
1facf9fc 29818+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
29819+ loff_t *ppos)
29820+{
29821+ ssize_t err;
29822+
2cbb1c4b 29823+ lockdep_off();
1facf9fc 29824+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 29825+ lockdep_on();
1facf9fc 29826+ if (err >= 0)
29827+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29828+ return err;
29829+}
29830+
29831+/* todo: kernel_read()? */
29832+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
29833+ loff_t *ppos)
29834+{
29835+ ssize_t err;
29836+ mm_segment_t oldfs;
b752ccd1
AM
29837+ union {
29838+ void *k;
29839+ char __user *u;
29840+ } buf;
1facf9fc 29841+
b752ccd1 29842+ buf.k = kbuf;
1facf9fc 29843+ oldfs = get_fs();
29844+ set_fs(KERNEL_DS);
b752ccd1 29845+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 29846+ set_fs(oldfs);
29847+ return err;
29848+}
29849+
29850+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
29851+ loff_t *ppos)
29852+{
29853+ ssize_t err;
29854+
2cbb1c4b 29855+ lockdep_off();
1facf9fc 29856+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 29857+ lockdep_on();
1facf9fc 29858+ if (err >= 0)
29859+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29860+ return err;
29861+}
29862+
29863+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
29864+{
29865+ ssize_t err;
29866+ mm_segment_t oldfs;
b752ccd1
AM
29867+ union {
29868+ void *k;
29869+ const char __user *u;
29870+ } buf;
1facf9fc 29871+
b752ccd1 29872+ buf.k = kbuf;
1facf9fc 29873+ oldfs = get_fs();
29874+ set_fs(KERNEL_DS);
b752ccd1 29875+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 29876+ set_fs(oldfs);
29877+ return err;
29878+}
29879+
4a4d8108
AM
29880+int vfsub_flush(struct file *file, fl_owner_t id)
29881+{
29882+ int err;
29883+
29884+ err = 0;
523b37e3 29885+ if (file->f_op->flush) {
2000de60 29886+ if (!au_test_nfs(file->f_path.dentry->d_sb))
2cbb1c4b
JR
29887+ err = file->f_op->flush(file, id);
29888+ else {
29889+ lockdep_off();
29890+ err = file->f_op->flush(file, id);
29891+ lockdep_on();
29892+ }
4a4d8108
AM
29893+ if (!err)
29894+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
29895+ /*ignore*/
29896+ }
29897+ return err;
29898+}
29899+
392086de 29900+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 29901+{
29902+ int err;
29903+
523b37e3 29904+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 29905+
2cbb1c4b 29906+ lockdep_off();
392086de 29907+ err = iterate_dir(file, ctx);
2cbb1c4b 29908+ lockdep_on();
1facf9fc 29909+ if (err >= 0)
29910+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29911+ return err;
29912+}
29913+
29914+long vfsub_splice_to(struct file *in, loff_t *ppos,
29915+ struct pipe_inode_info *pipe, size_t len,
29916+ unsigned int flags)
29917+{
29918+ long err;
29919+
2cbb1c4b 29920+ lockdep_off();
0fc653ad 29921+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 29922+ lockdep_on();
4a4d8108 29923+ file_accessed(in);
1facf9fc 29924+ if (err >= 0)
29925+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
29926+ return err;
29927+}
29928+
29929+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
29930+ loff_t *ppos, size_t len, unsigned int flags)
29931+{
29932+ long err;
29933+
2cbb1c4b 29934+ lockdep_off();
0fc653ad 29935+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 29936+ lockdep_on();
1facf9fc 29937+ if (err >= 0)
29938+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
29939+ return err;
29940+}
29941+
53392da6
AM
29942+int vfsub_fsync(struct file *file, struct path *path, int datasync)
29943+{
29944+ int err;
29945+
29946+ /* file can be NULL */
29947+ lockdep_off();
29948+ err = vfs_fsync(file, datasync);
29949+ lockdep_on();
29950+ if (!err) {
29951+ if (!path) {
29952+ AuDebugOn(!file);
29953+ path = &file->f_path;
29954+ }
29955+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
29956+ }
29957+ return err;
29958+}
29959+
1facf9fc 29960+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
29961+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
29962+ struct file *h_file)
29963+{
29964+ int err;
29965+ struct inode *h_inode;
c06a8ce3 29966+ struct super_block *h_sb;
1facf9fc 29967+
1facf9fc 29968+ if (!h_file) {
c06a8ce3
AM
29969+ err = vfsub_truncate(h_path, length);
29970+ goto out;
1facf9fc 29971+ }
29972+
c06a8ce3
AM
29973+ h_inode = h_path->dentry->d_inode;
29974+ h_sb = h_inode->i_sb;
29975+ lockdep_off();
29976+ sb_start_write(h_sb);
29977+ lockdep_on();
1facf9fc 29978+ err = locks_verify_truncate(h_inode, h_file, length);
29979+ if (!err)
953406b4 29980+ err = security_path_truncate(h_path);
2cbb1c4b
JR
29981+ if (!err) {
29982+ lockdep_off();
1facf9fc 29983+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
29984+ lockdep_on();
29985+ }
c06a8ce3
AM
29986+ lockdep_off();
29987+ sb_end_write(h_sb);
29988+ lockdep_on();
1facf9fc 29989+
4f0767ce 29990+out:
1facf9fc 29991+ return err;
29992+}
29993+
29994+/* ---------------------------------------------------------------------- */
29995+
29996+struct au_vfsub_mkdir_args {
29997+ int *errp;
29998+ struct inode *dir;
29999+ struct path *path;
30000+ int mode;
30001+};
30002+
30003+static void au_call_vfsub_mkdir(void *args)
30004+{
30005+ struct au_vfsub_mkdir_args *a = args;
30006+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
30007+}
30008+
30009+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
30010+{
30011+ int err, do_sio, wkq_err;
30012+
30013+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
30014+ if (!do_sio) {
30015+ lockdep_off();
1facf9fc 30016+ err = vfsub_mkdir(dir, path, mode);
c1595e42
JR
30017+ lockdep_on();
30018+ } else {
1facf9fc 30019+ struct au_vfsub_mkdir_args args = {
30020+ .errp = &err,
30021+ .dir = dir,
30022+ .path = path,
30023+ .mode = mode
30024+ };
30025+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
30026+ if (unlikely(wkq_err))
30027+ err = wkq_err;
30028+ }
30029+
30030+ return err;
30031+}
30032+
30033+struct au_vfsub_rmdir_args {
30034+ int *errp;
30035+ struct inode *dir;
30036+ struct path *path;
30037+};
30038+
30039+static void au_call_vfsub_rmdir(void *args)
30040+{
30041+ struct au_vfsub_rmdir_args *a = args;
30042+ *a->errp = vfsub_rmdir(a->dir, a->path);
30043+}
30044+
30045+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
30046+{
30047+ int err, do_sio, wkq_err;
30048+
30049+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
30050+ if (!do_sio) {
30051+ lockdep_off();
1facf9fc 30052+ err = vfsub_rmdir(dir, path);
c1595e42
JR
30053+ lockdep_on();
30054+ } else {
1facf9fc 30055+ struct au_vfsub_rmdir_args args = {
30056+ .errp = &err,
30057+ .dir = dir,
30058+ .path = path
30059+ };
30060+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
30061+ if (unlikely(wkq_err))
30062+ err = wkq_err;
30063+ }
30064+
30065+ return err;
30066+}
30067+
30068+/* ---------------------------------------------------------------------- */
30069+
30070+struct notify_change_args {
30071+ int *errp;
30072+ struct path *path;
30073+ struct iattr *ia;
523b37e3 30074+ struct inode **delegated_inode;
1facf9fc 30075+};
30076+
30077+static void call_notify_change(void *args)
30078+{
30079+ struct notify_change_args *a = args;
30080+ struct inode *h_inode;
30081+
30082+ h_inode = a->path->dentry->d_inode;
30083+ IMustLock(h_inode);
30084+
30085+ *a->errp = -EPERM;
30086+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
c1595e42 30087+ lockdep_off();
523b37e3
AM
30088+ *a->errp = notify_change(a->path->dentry, a->ia,
30089+ a->delegated_inode);
c1595e42 30090+ lockdep_on();
1facf9fc 30091+ if (!*a->errp)
30092+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
30093+ }
30094+ AuTraceErr(*a->errp);
30095+}
30096+
523b37e3
AM
30097+int vfsub_notify_change(struct path *path, struct iattr *ia,
30098+ struct inode **delegated_inode)
1facf9fc 30099+{
30100+ int err;
30101+ struct notify_change_args args = {
523b37e3
AM
30102+ .errp = &err,
30103+ .path = path,
30104+ .ia = ia,
30105+ .delegated_inode = delegated_inode
1facf9fc 30106+ };
30107+
30108+ call_notify_change(&args);
30109+
30110+ return err;
30111+}
30112+
523b37e3
AM
30113+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
30114+ struct inode **delegated_inode)
1facf9fc 30115+{
30116+ int err, wkq_err;
30117+ struct notify_change_args args = {
523b37e3
AM
30118+ .errp = &err,
30119+ .path = path,
30120+ .ia = ia,
30121+ .delegated_inode = delegated_inode
1facf9fc 30122+ };
30123+
30124+ wkq_err = au_wkq_wait(call_notify_change, &args);
30125+ if (unlikely(wkq_err))
30126+ err = wkq_err;
30127+
30128+ return err;
30129+}
30130+
30131+/* ---------------------------------------------------------------------- */
30132+
30133+struct unlink_args {
30134+ int *errp;
30135+ struct inode *dir;
30136+ struct path *path;
523b37e3 30137+ struct inode **delegated_inode;
1facf9fc 30138+};
30139+
30140+static void call_unlink(void *args)
30141+{
30142+ struct unlink_args *a = args;
30143+ struct dentry *d = a->path->dentry;
30144+ struct inode *h_inode;
30145+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
c1595e42 30146+ && au_dcount(d) == 1);
1facf9fc 30147+
30148+ IMustLock(a->dir);
30149+
30150+ a->path->dentry = d->d_parent;
30151+ *a->errp = security_path_unlink(a->path, d);
30152+ a->path->dentry = d;
30153+ if (unlikely(*a->errp))
30154+ return;
30155+
30156+ if (!stop_sillyrename)
30157+ dget(d);
30158+ h_inode = d->d_inode;
30159+ if (h_inode)
027c5e7a 30160+ ihold(h_inode);
1facf9fc 30161+
2cbb1c4b 30162+ lockdep_off();
523b37e3 30163+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 30164+ lockdep_on();
1facf9fc 30165+ if (!*a->errp) {
30166+ struct path tmp = {
30167+ .dentry = d->d_parent,
30168+ .mnt = a->path->mnt
30169+ };
30170+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
30171+ }
30172+
30173+ if (!stop_sillyrename)
30174+ dput(d);
30175+ if (h_inode)
30176+ iput(h_inode);
30177+
30178+ AuTraceErr(*a->errp);
30179+}
30180+
30181+/*
30182+ * @dir: must be locked.
30183+ * @dentry: target dentry.
30184+ */
523b37e3
AM
30185+int vfsub_unlink(struct inode *dir, struct path *path,
30186+ struct inode **delegated_inode, int force)
1facf9fc 30187+{
30188+ int err;
30189+ struct unlink_args args = {
523b37e3
AM
30190+ .errp = &err,
30191+ .dir = dir,
30192+ .path = path,
30193+ .delegated_inode = delegated_inode
1facf9fc 30194+ };
30195+
30196+ if (!force)
30197+ call_unlink(&args);
30198+ else {
30199+ int wkq_err;
30200+
30201+ wkq_err = au_wkq_wait(call_unlink, &args);
30202+ if (unlikely(wkq_err))
30203+ err = wkq_err;
30204+ }
30205+
30206+ return err;
30207+}
7f207e10
AM
30208diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
30209--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
30210+++ linux/fs/aufs/vfsub.h 2015-04-13 15:10:20.790157026 +0200
30211@@ -0,0 +1,276 @@
1facf9fc 30212+/*
2000de60 30213+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 30214+ *
30215+ * This program, aufs is free software; you can redistribute it and/or modify
30216+ * it under the terms of the GNU General Public License as published by
30217+ * the Free Software Foundation; either version 2 of the License, or
30218+ * (at your option) any later version.
dece6358
AM
30219+ *
30220+ * This program is distributed in the hope that it will be useful,
30221+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30222+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30223+ * GNU General Public License for more details.
30224+ *
30225+ * You should have received a copy of the GNU General Public License
523b37e3 30226+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30227+ */
30228+
30229+/*
30230+ * sub-routines for VFS
30231+ */
30232+
30233+#ifndef __AUFS_VFSUB_H__
30234+#define __AUFS_VFSUB_H__
30235+
30236+#ifdef __KERNEL__
30237+
30238+#include <linux/fs.h>
b4510431 30239+#include <linux/mount.h>
c1595e42 30240+#include <linux/xattr.h>
7f207e10 30241+#include "debug.h"
1facf9fc 30242+
7f207e10 30243+/* copied from linux/fs/internal.h */
2cbb1c4b 30244+/* todo: BAD approach!! */
c06a8ce3 30245+extern void __mnt_drop_write(struct vfsmount *);
2cbb1c4b 30246+extern spinlock_t inode_sb_list_lock;
7f207e10
AM
30247+
30248+/* ---------------------------------------------------------------------- */
1facf9fc 30249+
30250+/* lock subclass for lower inode */
30251+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
30252+/* reduce? gave up. */
30253+enum {
c1595e42 30254+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
1facf9fc 30255+ AuLsc_I_PARENT, /* lower inode, parent first */
30256+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 30257+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 30258+ AuLsc_I_CHILD,
30259+ AuLsc_I_CHILD2,
30260+ AuLsc_I_End
30261+};
30262+
30263+/* to debug easier, do not make them inlined functions */
30264+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
30265+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
30266+
30267+/* ---------------------------------------------------------------------- */
30268+
7f207e10
AM
30269+static inline void vfsub_drop_nlink(struct inode *inode)
30270+{
30271+ AuDebugOn(!inode->i_nlink);
30272+ drop_nlink(inode);
30273+}
30274+
027c5e7a
AM
30275+static inline void vfsub_dead_dir(struct inode *inode)
30276+{
30277+ AuDebugOn(!S_ISDIR(inode->i_mode));
30278+ inode->i_flags |= S_DEAD;
30279+ clear_nlink(inode);
30280+}
30281+
392086de
AM
30282+static inline int vfsub_native_ro(struct inode *inode)
30283+{
30284+ return (inode->i_sb->s_flags & MS_RDONLY)
30285+ || IS_RDONLY(inode)
30286+ /* || IS_APPEND(inode) */
30287+ || IS_IMMUTABLE(inode);
30288+}
30289+
7f207e10
AM
30290+/* ---------------------------------------------------------------------- */
30291+
30292+int vfsub_update_h_iattr(struct path *h_path, int *did);
30293+struct file *vfsub_dentry_open(struct path *path, int flags);
30294+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
1facf9fc 30295+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 30296+
1facf9fc 30297+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
30298+ int len);
b4510431
AM
30299+
30300+struct vfsub_lkup_one_args {
30301+ struct dentry **errp;
30302+ struct qstr *name;
30303+ struct dentry *parent;
30304+};
30305+
30306+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
30307+ struct dentry *parent)
30308+{
30309+ return vfsub_lookup_one_len(name->name, parent, name->len);
30310+}
30311+
30312+void vfsub_call_lkup_one(void *args);
30313+
30314+/* ---------------------------------------------------------------------- */
30315+
30316+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
30317+{
30318+ int err;
076b876e 30319+
b4510431
AM
30320+ lockdep_off();
30321+ err = mnt_want_write(mnt);
30322+ lockdep_on();
30323+ return err;
30324+}
30325+
30326+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
30327+{
30328+ lockdep_off();
30329+ mnt_drop_write(mnt);
30330+ lockdep_on();
30331+}
1facf9fc 30332+
7e9cd9fe 30333+#if 0 /* reserved */
c06a8ce3
AM
30334+static inline void vfsub_mnt_drop_write_file(struct file *file)
30335+{
30336+ lockdep_off();
30337+ mnt_drop_write_file(file);
30338+ lockdep_on();
30339+}
7e9cd9fe 30340+#endif
c06a8ce3 30341+
1facf9fc 30342+/* ---------------------------------------------------------------------- */
30343+
30344+struct au_hinode;
30345+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
30346+ struct dentry *d2, struct au_hinode *hdir2);
30347+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
30348+ struct dentry *d2, struct au_hinode *hdir2);
30349+
537831f9
AM
30350+int vfsub_create(struct inode *dir, struct path *path, int mode,
30351+ bool want_excl);
1facf9fc 30352+int vfsub_symlink(struct inode *dir, struct path *path,
30353+ const char *symname);
30354+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
30355+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 30356+ struct path *path, struct inode **delegated_inode);
1facf9fc 30357+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3
AM
30358+ struct inode *hdir, struct path *path,
30359+ struct inode **delegated_inode);
1facf9fc 30360+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
30361+int vfsub_rmdir(struct inode *dir, struct path *path);
30362+
30363+/* ---------------------------------------------------------------------- */
30364+
30365+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
30366+ loff_t *ppos);
30367+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
30368+ loff_t *ppos);
30369+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
30370+ loff_t *ppos);
30371+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
30372+ loff_t *ppos);
4a4d8108 30373+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
30374+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
30375+
c06a8ce3
AM
30376+static inline loff_t vfsub_f_size_read(struct file *file)
30377+{
30378+ return i_size_read(file_inode(file));
30379+}
30380+
4a4d8108
AM
30381+static inline unsigned int vfsub_file_flags(struct file *file)
30382+{
30383+ unsigned int flags;
30384+
30385+ spin_lock(&file->f_lock);
30386+ flags = file->f_flags;
30387+ spin_unlock(&file->f_lock);
30388+
30389+ return flags;
30390+}
1308ab2a 30391+
7e9cd9fe 30392+#if 0 /* reserved */
1facf9fc 30393+static inline void vfsub_file_accessed(struct file *h_file)
30394+{
30395+ file_accessed(h_file);
30396+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
30397+}
7e9cd9fe 30398+#endif
1facf9fc 30399+
30400+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
30401+ struct dentry *h_dentry)
30402+{
30403+ struct path h_path = {
30404+ .dentry = h_dentry,
30405+ .mnt = h_mnt
30406+ };
92d182d2 30407+ touch_atime(&h_path);
1facf9fc 30408+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
30409+}
30410+
0c3ec466
AM
30411+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
30412+ int flags)
30413+{
7e9cd9fe 30414+ return generic_update_time(h_inode, ts, flags);
0c3ec466
AM
30415+ /* no vfsub_update_h_iattr() since we don't have struct path */
30416+}
30417+
4a4d8108
AM
30418+long vfsub_splice_to(struct file *in, loff_t *ppos,
30419+ struct pipe_inode_info *pipe, size_t len,
30420+ unsigned int flags);
30421+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
30422+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
30423+
30424+static inline long vfsub_truncate(struct path *path, loff_t length)
30425+{
30426+ long err;
076b876e 30427+
c06a8ce3
AM
30428+ lockdep_off();
30429+ err = vfs_truncate(path, length);
30430+ lockdep_on();
30431+ return err;
30432+}
30433+
4a4d8108
AM
30434+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
30435+ struct file *h_file);
53392da6 30436+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 30437+
1facf9fc 30438+/* ---------------------------------------------------------------------- */
30439+
30440+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
30441+{
30442+ loff_t err;
30443+
2cbb1c4b 30444+ lockdep_off();
1facf9fc 30445+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 30446+ lockdep_on();
1facf9fc 30447+ return err;
30448+}
30449+
30450+/* ---------------------------------------------------------------------- */
30451+
4a4d8108
AM
30452+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
30453+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
30454+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
30455+ struct inode **delegated_inode);
30456+int vfsub_notify_change(struct path *path, struct iattr *ia,
30457+ struct inode **delegated_inode);
30458+int vfsub_unlink(struct inode *dir, struct path *path,
30459+ struct inode **delegated_inode, int force);
4a4d8108 30460+
c1595e42
JR
30461+/* ---------------------------------------------------------------------- */
30462+
30463+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
30464+ const void *value, size_t size, int flags)
30465+{
30466+ int err;
30467+
30468+ lockdep_off();
30469+ err = vfs_setxattr(dentry, name, value, size, flags);
30470+ lockdep_on();
30471+
30472+ return err;
30473+}
30474+
30475+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
30476+{
30477+ int err;
30478+
30479+ lockdep_off();
30480+ err = vfs_removexattr(dentry, name);
30481+ lockdep_on();
30482+
30483+ return err;
30484+}
30485+
1facf9fc 30486+#endif /* __KERNEL__ */
30487+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
30488diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
30489--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 30490+++ linux/fs/aufs/wbr_policy.c 2015-04-13 15:10:20.790157026 +0200
076b876e 30491@@ -0,0 +1,765 @@
1facf9fc 30492+/*
2000de60 30493+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 30494+ *
30495+ * This program, aufs is free software; you can redistribute it and/or modify
30496+ * it under the terms of the GNU General Public License as published by
30497+ * the Free Software Foundation; either version 2 of the License, or
30498+ * (at your option) any later version.
dece6358
AM
30499+ *
30500+ * This program is distributed in the hope that it will be useful,
30501+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30502+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30503+ * GNU General Public License for more details.
30504+ *
30505+ * You should have received a copy of the GNU General Public License
523b37e3 30506+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30507+ */
30508+
30509+/*
30510+ * policies for selecting one among multiple writable branches
30511+ */
30512+
30513+#include <linux/statfs.h>
30514+#include "aufs.h"
30515+
30516+/* subset of cpup_attr() */
30517+static noinline_for_stack
30518+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
30519+{
30520+ int err, sbits;
30521+ struct iattr ia;
30522+ struct inode *h_isrc;
30523+
30524+ h_isrc = h_src->d_inode;
30525+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
30526+ ia.ia_mode = h_isrc->i_mode;
30527+ ia.ia_uid = h_isrc->i_uid;
30528+ ia.ia_gid = h_isrc->i_gid;
30529+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
86dc4139 30530+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
523b37e3
AM
30531+ /* no delegation since it is just created */
30532+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 30533+
30534+ /* is this nfs only? */
30535+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
30536+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
30537+ ia.ia_mode = h_isrc->i_mode;
523b37e3 30538+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 30539+ }
30540+
30541+ return err;
30542+}
30543+
30544+#define AuCpdown_PARENT_OPQ 1
30545+#define AuCpdown_WHED (1 << 1)
30546+#define AuCpdown_MADE_DIR (1 << 2)
30547+#define AuCpdown_DIROPQ (1 << 3)
30548+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
30549+#define au_fset_cpdown(flags, name) \
30550+ do { (flags) |= AuCpdown_##name; } while (0)
30551+#define au_fclr_cpdown(flags, name) \
30552+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 30553+
1facf9fc 30554+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 30555+ unsigned int *flags)
1facf9fc 30556+{
30557+ int err;
30558+ struct dentry *opq_dentry;
30559+
30560+ opq_dentry = au_diropq_create(dentry, bdst);
30561+ err = PTR_ERR(opq_dentry);
30562+ if (IS_ERR(opq_dentry))
30563+ goto out;
30564+ dput(opq_dentry);
c2b27bf2 30565+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 30566+
4f0767ce 30567+out:
1facf9fc 30568+ return err;
30569+}
30570+
30571+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
30572+ struct inode *dir, aufs_bindex_t bdst)
30573+{
30574+ int err;
30575+ struct path h_path;
30576+ struct au_branch *br;
30577+
30578+ br = au_sbr(dentry->d_sb, bdst);
30579+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
30580+ err = PTR_ERR(h_path.dentry);
30581+ if (IS_ERR(h_path.dentry))
30582+ goto out;
30583+
30584+ err = 0;
30585+ if (h_path.dentry->d_inode) {
86dc4139 30586+ h_path.mnt = au_br_mnt(br);
1facf9fc 30587+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
30588+ dentry);
30589+ }
30590+ dput(h_path.dentry);
30591+
4f0767ce 30592+out:
1facf9fc 30593+ return err;
30594+}
30595+
30596+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 30597+ struct au_pin *pin,
1facf9fc 30598+ struct dentry *h_parent, void *arg)
30599+{
30600+ int err, rerr;
4a4d8108 30601+ aufs_bindex_t bopq, bstart;
1facf9fc 30602+ struct path h_path;
30603+ struct dentry *parent;
30604+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 30605+ unsigned int *flags = arg;
1facf9fc 30606+
30607+ bstart = au_dbstart(dentry);
30608+ /* dentry is di-locked */
30609+ parent = dget_parent(dentry);
30610+ dir = parent->d_inode;
30611+ h_dir = h_parent->d_inode;
30612+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
30613+ IMustLock(h_dir);
30614+
86dc4139 30615+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 30616+ if (unlikely(err < 0))
30617+ goto out;
30618+ h_path.dentry = au_h_dptr(dentry, bdst);
30619+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
30620+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
30621+ S_IRWXU | S_IRUGO | S_IXUGO);
30622+ if (unlikely(err))
30623+ goto out_put;
c2b27bf2 30624+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 30625+
1facf9fc 30626+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
30627+ au_fclr_cpdown(*flags, WHED);
30628+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 30629+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
30630+ au_fset_cpdown(*flags, WHED);
30631+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
30632+ au_fset_cpdown(*flags, PARENT_OPQ);
1facf9fc 30633+ h_inode = h_path.dentry->d_inode;
30634+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2
AM
30635+ if (au_ftest_cpdown(*flags, WHED)) {
30636+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 30637+ if (unlikely(err)) {
30638+ mutex_unlock(&h_inode->i_mutex);
30639+ goto out_dir;
30640+ }
30641+ }
30642+
30643+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
30644+ mutex_unlock(&h_inode->i_mutex);
30645+ if (unlikely(err))
30646+ goto out_opq;
30647+
c2b27bf2 30648+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 30649+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
30650+ if (unlikely(err))
30651+ goto out_opq;
30652+ }
30653+
30654+ inode = dentry->d_inode;
30655+ if (au_ibend(inode) < bdst)
30656+ au_set_ibend(inode, bdst);
30657+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
30658+ au_hi_flags(inode, /*isdir*/1));
076b876e 30659+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 30660+ goto out; /* success */
30661+
30662+ /* revert */
4f0767ce 30663+out_opq:
c2b27bf2 30664+ if (au_ftest_cpdown(*flags, DIROPQ)) {
1facf9fc 30665+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
30666+ rerr = au_diropq_remove(dentry, bdst);
30667+ mutex_unlock(&h_inode->i_mutex);
30668+ if (unlikely(rerr)) {
523b37e3
AM
30669+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
30670+ dentry, bdst, rerr);
1facf9fc 30671+ err = -EIO;
30672+ goto out;
30673+ }
30674+ }
4f0767ce 30675+out_dir:
c2b27bf2 30676+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 30677+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
30678+ if (unlikely(rerr)) {
523b37e3
AM
30679+ AuIOErr("failed removing %pd b%d (%d)\n",
30680+ dentry, bdst, rerr);
1facf9fc 30681+ err = -EIO;
30682+ }
30683+ }
4f0767ce 30684+out_put:
1facf9fc 30685+ au_set_h_dptr(dentry, bdst, NULL);
30686+ if (au_dbend(dentry) == bdst)
30687+ au_update_dbend(dentry);
4f0767ce 30688+out:
1facf9fc 30689+ dput(parent);
30690+ return err;
30691+}
30692+
30693+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
30694+{
30695+ int err;
c2b27bf2 30696+ unsigned int flags;
1facf9fc 30697+
c2b27bf2
AM
30698+ flags = 0;
30699+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 30700+
30701+ return err;
30702+}
30703+
30704+/* ---------------------------------------------------------------------- */
30705+
30706+/* policies for create */
30707+
c2b27bf2 30708+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
30709+{
30710+ int err, i, j, ndentry;
30711+ aufs_bindex_t bopq;
30712+ struct au_dcsub_pages dpages;
30713+ struct au_dpage *dpage;
30714+ struct dentry **dentries, *parent, *d;
30715+
30716+ err = au_dpages_init(&dpages, GFP_NOFS);
30717+ if (unlikely(err))
30718+ goto out;
30719+ parent = dget_parent(dentry);
027c5e7a 30720+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
30721+ if (unlikely(err))
30722+ goto out_free;
30723+
30724+ err = bindex;
30725+ for (i = 0; i < dpages.ndpage; i++) {
30726+ dpage = dpages.dpages + i;
30727+ dentries = dpage->dentries;
30728+ ndentry = dpage->ndentry;
30729+ for (j = 0; j < ndentry; j++) {
30730+ d = dentries[j];
30731+ di_read_lock_parent2(d, !AuLock_IR);
30732+ bopq = au_dbdiropq(d);
30733+ di_read_unlock(d, !AuLock_IR);
30734+ if (bopq >= 0 && bopq < err)
30735+ err = bopq;
30736+ }
30737+ }
30738+
30739+out_free:
30740+ dput(parent);
30741+ au_dpages_free(&dpages);
30742+out:
30743+ return err;
30744+}
30745+
1facf9fc 30746+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
30747+{
30748+ for (; bindex >= 0; bindex--)
30749+ if (!au_br_rdonly(au_sbr(sb, bindex)))
30750+ return bindex;
30751+ return -EROFS;
30752+}
30753+
30754+/* top down parent */
392086de
AM
30755+static int au_wbr_create_tdp(struct dentry *dentry,
30756+ unsigned int flags __maybe_unused)
1facf9fc 30757+{
30758+ int err;
30759+ aufs_bindex_t bstart, bindex;
30760+ struct super_block *sb;
30761+ struct dentry *parent, *h_parent;
30762+
30763+ sb = dentry->d_sb;
30764+ bstart = au_dbstart(dentry);
30765+ err = bstart;
30766+ if (!au_br_rdonly(au_sbr(sb, bstart)))
30767+ goto out;
30768+
30769+ err = -EROFS;
30770+ parent = dget_parent(dentry);
30771+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
30772+ h_parent = au_h_dptr(parent, bindex);
30773+ if (!h_parent || !h_parent->d_inode)
30774+ continue;
30775+
30776+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
30777+ err = bindex;
30778+ break;
30779+ }
30780+ }
30781+ dput(parent);
30782+
30783+ /* bottom up here */
4a4d8108 30784+ if (unlikely(err < 0)) {
1facf9fc 30785+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
30786+ if (err >= 0)
30787+ err = au_wbr_nonopq(dentry, err);
30788+ }
1facf9fc 30789+
4f0767ce 30790+out:
1facf9fc 30791+ AuDbg("b%d\n", err);
30792+ return err;
30793+}
30794+
30795+/* ---------------------------------------------------------------------- */
30796+
30797+/* an exception for the policy other than tdp */
30798+static int au_wbr_create_exp(struct dentry *dentry)
30799+{
30800+ int err;
30801+ aufs_bindex_t bwh, bdiropq;
30802+ struct dentry *parent;
30803+
30804+ err = -1;
30805+ bwh = au_dbwh(dentry);
30806+ parent = dget_parent(dentry);
30807+ bdiropq = au_dbdiropq(parent);
30808+ if (bwh >= 0) {
30809+ if (bdiropq >= 0)
30810+ err = min(bdiropq, bwh);
30811+ else
30812+ err = bwh;
30813+ AuDbg("%d\n", err);
30814+ } else if (bdiropq >= 0) {
30815+ err = bdiropq;
30816+ AuDbg("%d\n", err);
30817+ }
30818+ dput(parent);
30819+
4a4d8108
AM
30820+ if (err >= 0)
30821+ err = au_wbr_nonopq(dentry, err);
30822+
1facf9fc 30823+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
30824+ err = -1;
30825+
30826+ AuDbg("%d\n", err);
30827+ return err;
30828+}
30829+
30830+/* ---------------------------------------------------------------------- */
30831+
30832+/* round robin */
30833+static int au_wbr_create_init_rr(struct super_block *sb)
30834+{
30835+ int err;
30836+
30837+ err = au_wbr_bu(sb, au_sbend(sb));
30838+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 30839+ /* smp_mb(); */
1facf9fc 30840+
30841+ AuDbg("b%d\n", err);
30842+ return err;
30843+}
30844+
392086de 30845+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 30846+{
30847+ int err, nbr;
30848+ unsigned int u;
30849+ aufs_bindex_t bindex, bend;
30850+ struct super_block *sb;
30851+ atomic_t *next;
30852+
30853+ err = au_wbr_create_exp(dentry);
30854+ if (err >= 0)
30855+ goto out;
30856+
30857+ sb = dentry->d_sb;
30858+ next = &au_sbi(sb)->si_wbr_rr_next;
30859+ bend = au_sbend(sb);
30860+ nbr = bend + 1;
30861+ for (bindex = 0; bindex <= bend; bindex++) {
392086de 30862+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 30863+ err = atomic_dec_return(next) + 1;
30864+ /* modulo for 0 is meaningless */
30865+ if (unlikely(!err))
30866+ err = atomic_dec_return(next) + 1;
30867+ } else
30868+ err = atomic_read(next);
30869+ AuDbg("%d\n", err);
30870+ u = err;
30871+ err = u % nbr;
30872+ AuDbg("%d\n", err);
30873+ if (!au_br_rdonly(au_sbr(sb, err)))
30874+ break;
30875+ err = -EROFS;
30876+ }
30877+
4a4d8108
AM
30878+ if (err >= 0)
30879+ err = au_wbr_nonopq(dentry, err);
30880+
4f0767ce 30881+out:
1facf9fc 30882+ AuDbg("%d\n", err);
30883+ return err;
30884+}
30885+
30886+/* ---------------------------------------------------------------------- */
30887+
30888+/* most free space */
392086de 30889+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 30890+{
30891+ struct super_block *sb;
30892+ struct au_branch *br;
30893+ struct au_wbr_mfs *mfs;
392086de 30894+ struct dentry *h_parent;
1facf9fc 30895+ aufs_bindex_t bindex, bend;
30896+ int err;
30897+ unsigned long long b, bavail;
7f207e10 30898+ struct path h_path;
1facf9fc 30899+ /* reduce the stack usage */
30900+ struct kstatfs *st;
30901+
30902+ st = kmalloc(sizeof(*st), GFP_NOFS);
30903+ if (unlikely(!st)) {
30904+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
30905+ return;
30906+ }
30907+
30908+ bavail = 0;
30909+ sb = dentry->d_sb;
30910+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 30911+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 30912+ mfs->mfs_bindex = -EROFS;
30913+ mfs->mfsrr_bytes = 0;
392086de
AM
30914+ if (!parent) {
30915+ bindex = 0;
30916+ bend = au_sbend(sb);
30917+ } else {
30918+ bindex = au_dbstart(parent);
30919+ bend = au_dbtaildir(parent);
30920+ }
30921+
30922+ for (; bindex <= bend; bindex++) {
30923+ if (parent) {
30924+ h_parent = au_h_dptr(parent, bindex);
30925+ if (!h_parent || !h_parent->d_inode)
30926+ continue;
30927+ }
1facf9fc 30928+ br = au_sbr(sb, bindex);
30929+ if (au_br_rdonly(br))
30930+ continue;
30931+
30932+ /* sb->s_root for NFS is unreliable */
86dc4139 30933+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
30934+ h_path.dentry = h_path.mnt->mnt_root;
30935+ err = vfs_statfs(&h_path, st);
1facf9fc 30936+ if (unlikely(err)) {
30937+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
30938+ continue;
30939+ }
30940+
30941+ /* when the available size is equal, select the lower one */
30942+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
30943+ || sizeof(b) < sizeof(st->f_bsize));
30944+ b = st->f_bavail * st->f_bsize;
30945+ br->br_wbr->wbr_bytes = b;
30946+ if (b >= bavail) {
30947+ bavail = b;
30948+ mfs->mfs_bindex = bindex;
30949+ mfs->mfs_jiffy = jiffies;
30950+ }
30951+ }
30952+
30953+ mfs->mfsrr_bytes = bavail;
30954+ AuDbg("b%d\n", mfs->mfs_bindex);
30955+ kfree(st);
30956+}
30957+
392086de 30958+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 30959+{
30960+ int err;
392086de 30961+ struct dentry *parent;
1facf9fc 30962+ struct super_block *sb;
30963+ struct au_wbr_mfs *mfs;
30964+
30965+ err = au_wbr_create_exp(dentry);
30966+ if (err >= 0)
30967+ goto out;
30968+
30969+ sb = dentry->d_sb;
392086de
AM
30970+ parent = NULL;
30971+ if (au_ftest_wbr(flags, PARENT))
30972+ parent = dget_parent(dentry);
1facf9fc 30973+ mfs = &au_sbi(sb)->si_wbr_mfs;
30974+ mutex_lock(&mfs->mfs_lock);
30975+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
30976+ || mfs->mfs_bindex < 0
30977+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 30978+ au_mfs(dentry, parent);
1facf9fc 30979+ mutex_unlock(&mfs->mfs_lock);
30980+ err = mfs->mfs_bindex;
392086de 30981+ dput(parent);
1facf9fc 30982+
4a4d8108
AM
30983+ if (err >= 0)
30984+ err = au_wbr_nonopq(dentry, err);
30985+
4f0767ce 30986+out:
1facf9fc 30987+ AuDbg("b%d\n", err);
30988+ return err;
30989+}
30990+
30991+static int au_wbr_create_init_mfs(struct super_block *sb)
30992+{
30993+ struct au_wbr_mfs *mfs;
30994+
30995+ mfs = &au_sbi(sb)->si_wbr_mfs;
30996+ mutex_init(&mfs->mfs_lock);
30997+ mfs->mfs_jiffy = 0;
30998+ mfs->mfs_bindex = -EROFS;
30999+
31000+ return 0;
31001+}
31002+
31003+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
31004+{
31005+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
31006+ return 0;
31007+}
31008+
31009+/* ---------------------------------------------------------------------- */
31010+
31011+/* most free space and then round robin */
392086de 31012+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 31013+{
31014+ int err;
31015+ struct au_wbr_mfs *mfs;
31016+
392086de 31017+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 31018+ if (err >= 0) {
31019+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 31020+ mutex_lock(&mfs->mfs_lock);
1facf9fc 31021+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 31022+ err = au_wbr_create_rr(dentry, flags);
dece6358 31023+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 31024+ }
31025+
31026+ AuDbg("b%d\n", err);
31027+ return err;
31028+}
31029+
31030+static int au_wbr_create_init_mfsrr(struct super_block *sb)
31031+{
31032+ int err;
31033+
31034+ au_wbr_create_init_mfs(sb); /* ignore */
31035+ err = au_wbr_create_init_rr(sb);
31036+
31037+ return err;
31038+}
31039+
31040+/* ---------------------------------------------------------------------- */
31041+
31042+/* top down parent and most free space */
392086de 31043+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 31044+{
31045+ int err, e2;
31046+ unsigned long long b;
31047+ aufs_bindex_t bindex, bstart, bend;
31048+ struct super_block *sb;
31049+ struct dentry *parent, *h_parent;
31050+ struct au_branch *br;
31051+
392086de 31052+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 31053+ if (unlikely(err < 0))
31054+ goto out;
31055+ parent = dget_parent(dentry);
31056+ bstart = au_dbstart(parent);
31057+ bend = au_dbtaildir(parent);
31058+ if (bstart == bend)
31059+ goto out_parent; /* success */
31060+
392086de 31061+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 31062+ if (e2 < 0)
31063+ goto out_parent; /* success */
31064+
31065+ /* when the available size is equal, select upper one */
31066+ sb = dentry->d_sb;
31067+ br = au_sbr(sb, err);
31068+ b = br->br_wbr->wbr_bytes;
31069+ AuDbg("b%d, %llu\n", err, b);
31070+
31071+ for (bindex = bstart; bindex <= bend; bindex++) {
31072+ h_parent = au_h_dptr(parent, bindex);
31073+ if (!h_parent || !h_parent->d_inode)
31074+ continue;
31075+
31076+ br = au_sbr(sb, bindex);
31077+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
31078+ b = br->br_wbr->wbr_bytes;
31079+ err = bindex;
31080+ AuDbg("b%d, %llu\n", err, b);
31081+ }
31082+ }
31083+
4a4d8108
AM
31084+ if (err >= 0)
31085+ err = au_wbr_nonopq(dentry, err);
31086+
4f0767ce 31087+out_parent:
1facf9fc 31088+ dput(parent);
4f0767ce 31089+out:
1facf9fc 31090+ AuDbg("b%d\n", err);
31091+ return err;
31092+}
31093+
31094+/* ---------------------------------------------------------------------- */
31095+
392086de
AM
31096+/*
31097+ * - top down parent
31098+ * - most free space with parent
31099+ * - most free space round-robin regardless parent
31100+ */
31101+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
31102+{
31103+ int err;
31104+ unsigned long long watermark;
31105+ struct super_block *sb;
31106+ struct au_branch *br;
31107+ struct au_wbr_mfs *mfs;
31108+
31109+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
31110+ if (unlikely(err < 0))
31111+ goto out;
31112+
31113+ sb = dentry->d_sb;
31114+ br = au_sbr(sb, err);
31115+ mfs = &au_sbi(sb)->si_wbr_mfs;
31116+ mutex_lock(&mfs->mfs_lock);
31117+ watermark = mfs->mfsrr_watermark;
31118+ mutex_unlock(&mfs->mfs_lock);
31119+ if (br->br_wbr->wbr_bytes < watermark)
31120+ /* regardless the parent dir */
31121+ err = au_wbr_create_mfsrr(dentry, flags);
31122+
31123+out:
31124+ AuDbg("b%d\n", err);
31125+ return err;
31126+}
31127+
31128+/* ---------------------------------------------------------------------- */
31129+
1facf9fc 31130+/* policies for copyup */
31131+
31132+/* top down parent */
31133+static int au_wbr_copyup_tdp(struct dentry *dentry)
31134+{
392086de 31135+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 31136+}
31137+
31138+/* bottom up parent */
31139+static int au_wbr_copyup_bup(struct dentry *dentry)
31140+{
31141+ int err;
31142+ aufs_bindex_t bindex, bstart;
31143+ struct dentry *parent, *h_parent;
31144+ struct super_block *sb;
31145+
31146+ err = -EROFS;
31147+ sb = dentry->d_sb;
31148+ parent = dget_parent(dentry);
31149+ bstart = au_dbstart(parent);
31150+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
31151+ h_parent = au_h_dptr(parent, bindex);
31152+ if (!h_parent || !h_parent->d_inode)
31153+ continue;
31154+
31155+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
31156+ err = bindex;
31157+ break;
31158+ }
31159+ }
31160+ dput(parent);
31161+
31162+ /* bottom up here */
31163+ if (unlikely(err < 0))
31164+ err = au_wbr_bu(sb, bstart - 1);
31165+
31166+ AuDbg("b%d\n", err);
31167+ return err;
31168+}
31169+
31170+/* bottom up */
076b876e 31171+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart)
1facf9fc 31172+{
31173+ int err;
31174+
4a4d8108
AM
31175+ err = au_wbr_bu(dentry->d_sb, bstart);
31176+ AuDbg("b%d\n", err);
31177+ if (err > bstart)
31178+ err = au_wbr_nonopq(dentry, err);
1facf9fc 31179+
31180+ AuDbg("b%d\n", err);
31181+ return err;
31182+}
31183+
076b876e
AM
31184+static int au_wbr_copyup_bu(struct dentry *dentry)
31185+{
31186+ int err;
31187+ aufs_bindex_t bstart;
31188+
31189+ bstart = au_dbstart(dentry);
31190+ err = au_wbr_do_copyup_bu(dentry, bstart);
31191+ return err;
31192+}
31193+
1facf9fc 31194+/* ---------------------------------------------------------------------- */
31195+
31196+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
31197+ [AuWbrCopyup_TDP] = {
31198+ .copyup = au_wbr_copyup_tdp
31199+ },
31200+ [AuWbrCopyup_BUP] = {
31201+ .copyup = au_wbr_copyup_bup
31202+ },
31203+ [AuWbrCopyup_BU] = {
31204+ .copyup = au_wbr_copyup_bu
31205+ }
31206+};
31207+
31208+struct au_wbr_create_operations au_wbr_create_ops[] = {
31209+ [AuWbrCreate_TDP] = {
31210+ .create = au_wbr_create_tdp
31211+ },
31212+ [AuWbrCreate_RR] = {
31213+ .create = au_wbr_create_rr,
31214+ .init = au_wbr_create_init_rr
31215+ },
31216+ [AuWbrCreate_MFS] = {
31217+ .create = au_wbr_create_mfs,
31218+ .init = au_wbr_create_init_mfs,
31219+ .fin = au_wbr_create_fin_mfs
31220+ },
31221+ [AuWbrCreate_MFSV] = {
31222+ .create = au_wbr_create_mfs,
31223+ .init = au_wbr_create_init_mfs,
31224+ .fin = au_wbr_create_fin_mfs
31225+ },
31226+ [AuWbrCreate_MFSRR] = {
31227+ .create = au_wbr_create_mfsrr,
31228+ .init = au_wbr_create_init_mfsrr,
31229+ .fin = au_wbr_create_fin_mfs
31230+ },
31231+ [AuWbrCreate_MFSRRV] = {
31232+ .create = au_wbr_create_mfsrr,
31233+ .init = au_wbr_create_init_mfsrr,
31234+ .fin = au_wbr_create_fin_mfs
31235+ },
31236+ [AuWbrCreate_PMFS] = {
31237+ .create = au_wbr_create_pmfs,
31238+ .init = au_wbr_create_init_mfs,
31239+ .fin = au_wbr_create_fin_mfs
31240+ },
31241+ [AuWbrCreate_PMFSV] = {
31242+ .create = au_wbr_create_pmfs,
31243+ .init = au_wbr_create_init_mfs,
31244+ .fin = au_wbr_create_fin_mfs
392086de
AM
31245+ },
31246+ [AuWbrCreate_PMFSRR] = {
31247+ .create = au_wbr_create_pmfsrr,
31248+ .init = au_wbr_create_init_mfsrr,
31249+ .fin = au_wbr_create_fin_mfs
31250+ },
31251+ [AuWbrCreate_PMFSRRV] = {
31252+ .create = au_wbr_create_pmfsrr,
31253+ .init = au_wbr_create_init_mfsrr,
31254+ .fin = au_wbr_create_fin_mfs
1facf9fc 31255+ }
31256+};
7f207e10
AM
31257diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
31258--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 31259+++ linux/fs/aufs/whout.c 2015-04-13 15:10:20.790157026 +0200
2000de60 31260@@ -0,0 +1,1064 @@
1facf9fc 31261+/*
2000de60 31262+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 31263+ *
31264+ * This program, aufs is free software; you can redistribute it and/or modify
31265+ * it under the terms of the GNU General Public License as published by
31266+ * the Free Software Foundation; either version 2 of the License, or
31267+ * (at your option) any later version.
dece6358
AM
31268+ *
31269+ * This program is distributed in the hope that it will be useful,
31270+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31271+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31272+ * GNU General Public License for more details.
31273+ *
31274+ * You should have received a copy of the GNU General Public License
523b37e3 31275+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31276+ */
31277+
31278+/*
31279+ * whiteout for logical deletion and opaque directory
31280+ */
31281+
1facf9fc 31282+#include "aufs.h"
31283+
31284+#define WH_MASK S_IRUGO
31285+
31286+/*
31287+ * If a directory contains this file, then it is opaque. We start with the
31288+ * .wh. flag so that it is blocked by lookup.
31289+ */
0c3ec466
AM
31290+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
31291+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 31292+
31293+/*
31294+ * generate whiteout name, which is NOT terminated by NULL.
31295+ * @name: original d_name.name
31296+ * @len: original d_name.len
31297+ * @wh: whiteout qstr
31298+ * returns zero when succeeds, otherwise error.
31299+ * succeeded value as wh->name should be freed by kfree().
31300+ */
31301+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
31302+{
31303+ char *p;
31304+
31305+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
31306+ return -ENAMETOOLONG;
31307+
31308+ wh->len = name->len + AUFS_WH_PFX_LEN;
31309+ p = kmalloc(wh->len, GFP_NOFS);
31310+ wh->name = p;
31311+ if (p) {
31312+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
31313+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
31314+ /* smp_mb(); */
31315+ return 0;
31316+ }
31317+ return -ENOMEM;
31318+}
31319+
31320+/* ---------------------------------------------------------------------- */
31321+
31322+/*
31323+ * test if the @wh_name exists under @h_parent.
31324+ * @try_sio specifies the necessary of super-io.
31325+ */
076b876e 31326+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 31327+{
31328+ int err;
31329+ struct dentry *wh_dentry;
1facf9fc 31330+
1facf9fc 31331+ if (!try_sio)
b4510431 31332+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 31333+ else
076b876e 31334+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 31335+ err = PTR_ERR(wh_dentry);
2000de60
JR
31336+ if (IS_ERR(wh_dentry)) {
31337+ if (err == -ENAMETOOLONG)
31338+ err = 0;
1facf9fc 31339+ goto out;
2000de60 31340+ }
1facf9fc 31341+
31342+ err = 0;
31343+ if (!wh_dentry->d_inode)
31344+ goto out_wh; /* success */
31345+
31346+ err = 1;
7e9cd9fe 31347+ if (d_is_reg(wh_dentry))
1facf9fc 31348+ goto out_wh; /* success */
31349+
31350+ err = -EIO;
523b37e3
AM
31351+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
31352+ wh_dentry, wh_dentry->d_inode->i_mode);
1facf9fc 31353+
4f0767ce 31354+out_wh:
1facf9fc 31355+ dput(wh_dentry);
4f0767ce 31356+out:
1facf9fc 31357+ return err;
31358+}
31359+
31360+/*
31361+ * test if the @h_dentry sets opaque or not.
31362+ */
076b876e 31363+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 31364+{
31365+ int err;
31366+ struct inode *h_dir;
31367+
31368+ h_dir = h_dentry->d_inode;
076b876e 31369+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 31370+ au_test_h_perm_sio(h_dir, MAY_EXEC));
31371+ return err;
31372+}
31373+
31374+/*
31375+ * returns a negative dentry whose name is unique and temporary.
31376+ */
31377+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
31378+ struct qstr *prefix)
31379+{
1facf9fc 31380+ struct dentry *dentry;
31381+ int i;
027c5e7a 31382+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 31383+ *name, *p;
027c5e7a 31384+ /* strict atomic_t is unnecessary here */
1facf9fc 31385+ static unsigned short cnt;
31386+ struct qstr qs;
31387+
4a4d8108
AM
31388+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
31389+
1facf9fc 31390+ name = defname;
027c5e7a
AM
31391+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
31392+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 31393+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 31394+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 31395+ goto out;
31396+ dentry = ERR_PTR(-ENOMEM);
31397+ name = kmalloc(qs.len + 1, GFP_NOFS);
31398+ if (unlikely(!name))
31399+ goto out;
31400+ }
31401+
31402+ /* doubly whiteout-ed */
31403+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
31404+ p = name + AUFS_WH_PFX_LEN * 2;
31405+ memcpy(p, prefix->name, prefix->len);
31406+ p += prefix->len;
31407+ *p++ = '.';
4a4d8108 31408+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 31409+
31410+ qs.name = name;
31411+ for (i = 0; i < 3; i++) {
b752ccd1 31412+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 31413+ dentry = au_sio_lkup_one(&qs, h_parent);
1facf9fc 31414+ if (IS_ERR(dentry) || !dentry->d_inode)
31415+ goto out_name;
31416+ dput(dentry);
31417+ }
0c3ec466 31418+ /* pr_warn("could not get random name\n"); */
1facf9fc 31419+ dentry = ERR_PTR(-EEXIST);
31420+ AuDbg("%.*s\n", AuLNPair(&qs));
31421+ BUG();
31422+
4f0767ce 31423+out_name:
1facf9fc 31424+ if (name != defname)
31425+ kfree(name);
4f0767ce 31426+out:
4a4d8108 31427+ AuTraceErrPtr(dentry);
1facf9fc 31428+ return dentry;
1facf9fc 31429+}
31430+
31431+/*
31432+ * rename the @h_dentry on @br to the whiteouted temporary name.
31433+ */
31434+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
31435+{
31436+ int err;
31437+ struct path h_path = {
86dc4139 31438+ .mnt = au_br_mnt(br)
1facf9fc 31439+ };
523b37e3 31440+ struct inode *h_dir, *delegated;
1facf9fc 31441+ struct dentry *h_parent;
31442+
31443+ h_parent = h_dentry->d_parent; /* dir inode is locked */
31444+ h_dir = h_parent->d_inode;
31445+ IMustLock(h_dir);
31446+
31447+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
31448+ err = PTR_ERR(h_path.dentry);
31449+ if (IS_ERR(h_path.dentry))
31450+ goto out;
31451+
31452+ /* under the same dir, no need to lock_rename() */
523b37e3
AM
31453+ delegated = NULL;
31454+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated);
1facf9fc 31455+ AuTraceErr(err);
523b37e3
AM
31456+ if (unlikely(err == -EWOULDBLOCK)) {
31457+ pr_warn("cannot retry for NFSv4 delegation"
31458+ " for an internal rename\n");
31459+ iput(delegated);
31460+ }
1facf9fc 31461+ dput(h_path.dentry);
31462+
4f0767ce 31463+out:
4a4d8108 31464+ AuTraceErr(err);
1facf9fc 31465+ return err;
31466+}
31467+
31468+/* ---------------------------------------------------------------------- */
31469+/*
31470+ * functions for removing a whiteout
31471+ */
31472+
31473+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
31474+{
523b37e3
AM
31475+ int err, force;
31476+ struct inode *delegated;
1facf9fc 31477+
31478+ /*
31479+ * forces superio when the dir has a sticky bit.
31480+ * this may be a violation of unix fs semantics.
31481+ */
31482+ force = (h_dir->i_mode & S_ISVTX)
0c3ec466 31483+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
523b37e3
AM
31484+ delegated = NULL;
31485+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
31486+ if (unlikely(err == -EWOULDBLOCK)) {
31487+ pr_warn("cannot retry for NFSv4 delegation"
31488+ " for an internal unlink\n");
31489+ iput(delegated);
31490+ }
31491+ return err;
1facf9fc 31492+}
31493+
31494+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
31495+ struct dentry *dentry)
31496+{
31497+ int err;
31498+
31499+ err = do_unlink_wh(h_dir, h_path);
31500+ if (!err && dentry)
31501+ au_set_dbwh(dentry, -1);
31502+
31503+ return err;
31504+}
31505+
31506+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
31507+ struct au_branch *br)
31508+{
31509+ int err;
31510+ struct path h_path = {
86dc4139 31511+ .mnt = au_br_mnt(br)
1facf9fc 31512+ };
31513+
31514+ err = 0;
b4510431 31515+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 31516+ if (IS_ERR(h_path.dentry))
31517+ err = PTR_ERR(h_path.dentry);
31518+ else {
31519+ if (h_path.dentry->d_inode
7e9cd9fe 31520+ && d_is_reg(h_path.dentry))
1facf9fc 31521+ err = do_unlink_wh(h_parent->d_inode, &h_path);
31522+ dput(h_path.dentry);
31523+ }
31524+
31525+ return err;
31526+}
31527+
31528+/* ---------------------------------------------------------------------- */
31529+/*
31530+ * initialize/clean whiteout for a branch
31531+ */
31532+
31533+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
31534+ const int isdir)
31535+{
31536+ int err;
523b37e3 31537+ struct inode *delegated;
1facf9fc 31538+
31539+ if (!whpath->dentry->d_inode)
31540+ return;
31541+
86dc4139
AM
31542+ if (isdir)
31543+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
31544+ else {
31545+ delegated = NULL;
31546+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
31547+ if (unlikely(err == -EWOULDBLOCK)) {
31548+ pr_warn("cannot retry for NFSv4 delegation"
31549+ " for an internal unlink\n");
31550+ iput(delegated);
31551+ }
31552+ }
1facf9fc 31553+ if (unlikely(err))
523b37e3
AM
31554+ pr_warn("failed removing %pd (%d), ignored.\n",
31555+ whpath->dentry, err);
1facf9fc 31556+}
31557+
31558+static int test_linkable(struct dentry *h_root)
31559+{
31560+ struct inode *h_dir = h_root->d_inode;
31561+
31562+ if (h_dir->i_op->link)
31563+ return 0;
31564+
523b37e3
AM
31565+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
31566+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 31567+ return -ENOSYS;
31568+}
31569+
31570+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
31571+static int au_whdir(struct inode *h_dir, struct path *path)
31572+{
31573+ int err;
31574+
31575+ err = -EEXIST;
31576+ if (!path->dentry->d_inode) {
31577+ int mode = S_IRWXU;
31578+
31579+ if (au_test_nfs(path->dentry->d_sb))
31580+ mode |= S_IXUGO;
86dc4139 31581+ err = vfsub_mkdir(h_dir, path, mode);
2000de60 31582+ } else if (d_is_dir(path->dentry))
1facf9fc 31583+ err = 0;
31584+ else
523b37e3 31585+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 31586+
31587+ return err;
31588+}
31589+
31590+struct au_wh_base {
31591+ const struct qstr *name;
31592+ struct dentry *dentry;
31593+};
31594+
31595+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
31596+ struct path *h_path)
31597+{
31598+ h_path->dentry = base[AuBrWh_BASE].dentry;
31599+ au_wh_clean(h_dir, h_path, /*isdir*/0);
31600+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31601+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31602+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31603+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31604+}
31605+
31606+/*
31607+ * returns tri-state,
c1595e42 31608+ * minus: error, caller should print the message
1facf9fc 31609+ * zero: succuess
c1595e42 31610+ * plus: error, caller should NOT print the message
1facf9fc 31611+ */
31612+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
31613+ int do_plink, struct au_wh_base base[],
31614+ struct path *h_path)
31615+{
31616+ int err;
31617+ struct inode *h_dir;
31618+
31619+ h_dir = h_root->d_inode;
31620+ h_path->dentry = base[AuBrWh_BASE].dentry;
31621+ au_wh_clean(h_dir, h_path, /*isdir*/0);
31622+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31623+ if (do_plink) {
31624+ err = test_linkable(h_root);
31625+ if (unlikely(err)) {
31626+ err = 1;
31627+ goto out;
31628+ }
31629+
31630+ err = au_whdir(h_dir, h_path);
31631+ if (unlikely(err))
31632+ goto out;
31633+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
31634+ } else
31635+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31636+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31637+ err = au_whdir(h_dir, h_path);
31638+ if (unlikely(err))
31639+ goto out;
31640+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
31641+
4f0767ce 31642+out:
1facf9fc 31643+ return err;
31644+}
31645+
31646+/*
31647+ * for the moment, aufs supports the branch filesystem which does not support
31648+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
31649+ * copyup failed. finally, such filesystem will not be used as the writable
31650+ * branch.
31651+ *
31652+ * returns tri-state, see above.
31653+ */
31654+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
31655+ int do_plink, struct au_wh_base base[],
31656+ struct path *h_path)
31657+{
31658+ int err;
31659+ struct inode *h_dir;
31660+
1308ab2a 31661+ WbrWhMustWriteLock(wbr);
31662+
1facf9fc 31663+ err = test_linkable(h_root);
31664+ if (unlikely(err)) {
31665+ err = 1;
31666+ goto out;
31667+ }
31668+
31669+ /*
31670+ * todo: should this create be done in /sbin/mount.aufs helper?
31671+ */
31672+ err = -EEXIST;
31673+ h_dir = h_root->d_inode;
31674+ if (!base[AuBrWh_BASE].dentry->d_inode) {
86dc4139
AM
31675+ h_path->dentry = base[AuBrWh_BASE].dentry;
31676+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
7e9cd9fe 31677+ } else if (d_is_reg(base[AuBrWh_BASE].dentry))
1facf9fc 31678+ err = 0;
31679+ else
523b37e3 31680+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 31681+ if (unlikely(err))
31682+ goto out;
31683+
31684+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31685+ if (do_plink) {
31686+ err = au_whdir(h_dir, h_path);
31687+ if (unlikely(err))
31688+ goto out;
31689+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
31690+ } else
31691+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31692+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
31693+
31694+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31695+ err = au_whdir(h_dir, h_path);
31696+ if (unlikely(err))
31697+ goto out;
31698+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
31699+
4f0767ce 31700+out:
1facf9fc 31701+ return err;
31702+}
31703+
31704+/*
31705+ * initialize the whiteout base file/dir for @br.
31706+ */
86dc4139 31707+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 31708+{
31709+ int err, i;
31710+ const unsigned char do_plink
31711+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 31712+ struct inode *h_dir;
86dc4139
AM
31713+ struct path path = br->br_path;
31714+ struct dentry *h_root = path.dentry;
1facf9fc 31715+ struct au_wbr *wbr = br->br_wbr;
31716+ static const struct qstr base_name[] = {
0c3ec466
AM
31717+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
31718+ sizeof(AUFS_BASE_NAME) - 1),
31719+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
31720+ sizeof(AUFS_PLINKDIR_NAME) - 1),
31721+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
31722+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 31723+ };
31724+ struct au_wh_base base[] = {
31725+ [AuBrWh_BASE] = {
31726+ .name = base_name + AuBrWh_BASE,
31727+ .dentry = NULL
31728+ },
31729+ [AuBrWh_PLINK] = {
31730+ .name = base_name + AuBrWh_PLINK,
31731+ .dentry = NULL
31732+ },
31733+ [AuBrWh_ORPH] = {
31734+ .name = base_name + AuBrWh_ORPH,
31735+ .dentry = NULL
31736+ }
31737+ };
31738+
1308ab2a 31739+ if (wbr)
31740+ WbrWhMustWriteLock(wbr);
1facf9fc 31741+
1facf9fc 31742+ for (i = 0; i < AuBrWh_Last; i++) {
31743+ /* doubly whiteouted */
31744+ struct dentry *d;
31745+
31746+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
31747+ err = PTR_ERR(d);
31748+ if (IS_ERR(d))
31749+ goto out;
31750+
31751+ base[i].dentry = d;
31752+ AuDebugOn(wbr
31753+ && wbr->wbr_wh[i]
31754+ && wbr->wbr_wh[i] != base[i].dentry);
31755+ }
31756+
31757+ if (wbr)
31758+ for (i = 0; i < AuBrWh_Last; i++) {
31759+ dput(wbr->wbr_wh[i]);
31760+ wbr->wbr_wh[i] = NULL;
31761+ }
31762+
31763+ err = 0;
1e00d052 31764+ if (!au_br_writable(br->br_perm)) {
4a4d8108 31765+ h_dir = h_root->d_inode;
1facf9fc 31766+ au_wh_init_ro(h_dir, base, &path);
1e00d052 31767+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 31768+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
31769+ if (err > 0)
31770+ goto out;
31771+ else if (err)
31772+ goto out_err;
1e00d052 31773+ } else {
1facf9fc 31774+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
31775+ if (err > 0)
31776+ goto out;
31777+ else if (err)
31778+ goto out_err;
1facf9fc 31779+ }
31780+ goto out; /* success */
31781+
4f0767ce 31782+out_err:
523b37e3
AM
31783+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
31784+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 31785+out:
1facf9fc 31786+ for (i = 0; i < AuBrWh_Last; i++)
31787+ dput(base[i].dentry);
31788+ return err;
31789+}
31790+
31791+/* ---------------------------------------------------------------------- */
31792+/*
31793+ * whiteouts are all hard-linked usually.
31794+ * when its link count reaches a ceiling, we create a new whiteout base
31795+ * asynchronously.
31796+ */
31797+
31798+struct reinit_br_wh {
31799+ struct super_block *sb;
31800+ struct au_branch *br;
31801+};
31802+
31803+static void reinit_br_wh(void *arg)
31804+{
31805+ int err;
31806+ aufs_bindex_t bindex;
31807+ struct path h_path;
31808+ struct reinit_br_wh *a = arg;
31809+ struct au_wbr *wbr;
523b37e3 31810+ struct inode *dir, *delegated;
1facf9fc 31811+ struct dentry *h_root;
31812+ struct au_hinode *hdir;
31813+
31814+ err = 0;
31815+ wbr = a->br->br_wbr;
31816+ /* big aufs lock */
31817+ si_noflush_write_lock(a->sb);
31818+ if (!au_br_writable(a->br->br_perm))
31819+ goto out;
31820+ bindex = au_br_index(a->sb, a->br->br_id);
31821+ if (unlikely(bindex < 0))
31822+ goto out;
31823+
1308ab2a 31824+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 31825+ dir = a->sb->s_root->d_inode;
1facf9fc 31826+ hdir = au_hi(dir, bindex);
31827+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 31828+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 31829+
4a4d8108 31830+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 31831+ wbr_wh_write_lock(wbr);
31832+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
31833+ h_root, a->br);
31834+ if (!err) {
86dc4139
AM
31835+ h_path.dentry = wbr->wbr_whbase;
31836+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
31837+ delegated = NULL;
31838+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
31839+ /*force*/0);
31840+ if (unlikely(err == -EWOULDBLOCK)) {
31841+ pr_warn("cannot retry for NFSv4 delegation"
31842+ " for an internal unlink\n");
31843+ iput(delegated);
31844+ }
1facf9fc 31845+ } else {
523b37e3 31846+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 31847+ err = 0;
31848+ }
31849+ dput(wbr->wbr_whbase);
31850+ wbr->wbr_whbase = NULL;
31851+ if (!err)
86dc4139 31852+ err = au_wh_init(a->br, a->sb);
1facf9fc 31853+ wbr_wh_write_unlock(wbr);
4a4d8108 31854+ au_hn_imtx_unlock(hdir);
1308ab2a 31855+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
31856+ if (!err)
31857+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 31858+
4f0767ce 31859+out:
1facf9fc 31860+ if (wbr)
31861+ atomic_dec(&wbr->wbr_wh_running);
31862+ atomic_dec(&a->br->br_count);
1facf9fc 31863+ si_write_unlock(a->sb);
027c5e7a 31864+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 31865+ kfree(arg);
31866+ if (unlikely(err))
31867+ AuIOErr("err %d\n", err);
31868+}
31869+
31870+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
31871+{
31872+ int do_dec, wkq_err;
31873+ struct reinit_br_wh *arg;
31874+
31875+ do_dec = 1;
31876+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
31877+ goto out;
31878+
31879+ /* ignore ENOMEM */
31880+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
31881+ if (arg) {
31882+ /*
31883+ * dec(wh_running), kfree(arg) and dec(br_count)
31884+ * in reinit function
31885+ */
31886+ arg->sb = sb;
31887+ arg->br = br;
31888+ atomic_inc(&br->br_count);
53392da6 31889+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 31890+ if (unlikely(wkq_err)) {
31891+ atomic_dec(&br->br_wbr->wbr_wh_running);
31892+ atomic_dec(&br->br_count);
31893+ kfree(arg);
31894+ }
31895+ do_dec = 0;
31896+ }
31897+
4f0767ce 31898+out:
1facf9fc 31899+ if (do_dec)
31900+ atomic_dec(&br->br_wbr->wbr_wh_running);
31901+}
31902+
31903+/* ---------------------------------------------------------------------- */
31904+
31905+/*
31906+ * create the whiteout @wh.
31907+ */
31908+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
31909+ struct dentry *wh)
31910+{
31911+ int err;
31912+ struct path h_path = {
31913+ .dentry = wh
31914+ };
31915+ struct au_branch *br;
31916+ struct au_wbr *wbr;
31917+ struct dentry *h_parent;
523b37e3 31918+ struct inode *h_dir, *delegated;
1facf9fc 31919+
31920+ h_parent = wh->d_parent; /* dir inode is locked */
31921+ h_dir = h_parent->d_inode;
31922+ IMustLock(h_dir);
31923+
31924+ br = au_sbr(sb, bindex);
86dc4139 31925+ h_path.mnt = au_br_mnt(br);
1facf9fc 31926+ wbr = br->br_wbr;
31927+ wbr_wh_read_lock(wbr);
31928+ if (wbr->wbr_whbase) {
523b37e3
AM
31929+ delegated = NULL;
31930+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
31931+ if (unlikely(err == -EWOULDBLOCK)) {
31932+ pr_warn("cannot retry for NFSv4 delegation"
31933+ " for an internal link\n");
31934+ iput(delegated);
31935+ }
1facf9fc 31936+ if (!err || err != -EMLINK)
31937+ goto out;
31938+
31939+ /* link count full. re-initialize br_whbase. */
31940+ kick_reinit_br_wh(sb, br);
31941+ }
31942+
31943+ /* return this error in this context */
b4510431 31944+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
31945+ if (!err)
31946+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 31947+
4f0767ce 31948+out:
1facf9fc 31949+ wbr_wh_read_unlock(wbr);
31950+ return err;
31951+}
31952+
31953+/* ---------------------------------------------------------------------- */
31954+
31955+/*
31956+ * create or remove the diropq.
31957+ */
31958+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
31959+ unsigned int flags)
31960+{
31961+ struct dentry *opq_dentry, *h_dentry;
31962+ struct super_block *sb;
31963+ struct au_branch *br;
31964+ int err;
31965+
31966+ sb = dentry->d_sb;
31967+ br = au_sbr(sb, bindex);
31968+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 31969+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 31970+ if (IS_ERR(opq_dentry))
31971+ goto out;
31972+
31973+ if (au_ftest_diropq(flags, CREATE)) {
31974+ err = link_or_create_wh(sb, bindex, opq_dentry);
31975+ if (!err) {
31976+ au_set_dbdiropq(dentry, bindex);
31977+ goto out; /* success */
31978+ }
31979+ } else {
31980+ struct path tmp = {
31981+ .dentry = opq_dentry,
86dc4139 31982+ .mnt = au_br_mnt(br)
1facf9fc 31983+ };
31984+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
31985+ if (!err)
31986+ au_set_dbdiropq(dentry, -1);
31987+ }
31988+ dput(opq_dentry);
31989+ opq_dentry = ERR_PTR(err);
31990+
4f0767ce 31991+out:
1facf9fc 31992+ return opq_dentry;
31993+}
31994+
31995+struct do_diropq_args {
31996+ struct dentry **errp;
31997+ struct dentry *dentry;
31998+ aufs_bindex_t bindex;
31999+ unsigned int flags;
32000+};
32001+
32002+static void call_do_diropq(void *args)
32003+{
32004+ struct do_diropq_args *a = args;
32005+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
32006+}
32007+
32008+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
32009+ unsigned int flags)
32010+{
32011+ struct dentry *diropq, *h_dentry;
32012+
32013+ h_dentry = au_h_dptr(dentry, bindex);
32014+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
32015+ diropq = do_diropq(dentry, bindex, flags);
32016+ else {
32017+ int wkq_err;
32018+ struct do_diropq_args args = {
32019+ .errp = &diropq,
32020+ .dentry = dentry,
32021+ .bindex = bindex,
32022+ .flags = flags
32023+ };
32024+
32025+ wkq_err = au_wkq_wait(call_do_diropq, &args);
32026+ if (unlikely(wkq_err))
32027+ diropq = ERR_PTR(wkq_err);
32028+ }
32029+
32030+ return diropq;
32031+}
32032+
32033+/* ---------------------------------------------------------------------- */
32034+
32035+/*
32036+ * lookup whiteout dentry.
32037+ * @h_parent: lower parent dentry which must exist and be locked
32038+ * @base_name: name of dentry which will be whiteouted
32039+ * returns dentry for whiteout.
32040+ */
32041+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
32042+ struct au_branch *br)
32043+{
32044+ int err;
32045+ struct qstr wh_name;
32046+ struct dentry *wh_dentry;
32047+
32048+ err = au_wh_name_alloc(&wh_name, base_name);
32049+ wh_dentry = ERR_PTR(err);
32050+ if (!err) {
b4510431 32051+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 32052+ kfree(wh_name.name);
32053+ }
32054+ return wh_dentry;
32055+}
32056+
32057+/*
32058+ * link/create a whiteout for @dentry on @bindex.
32059+ */
32060+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
32061+ struct dentry *h_parent)
32062+{
32063+ struct dentry *wh_dentry;
32064+ struct super_block *sb;
32065+ int err;
32066+
32067+ sb = dentry->d_sb;
32068+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
32069+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
32070+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 32071+ if (!err) {
1facf9fc 32072+ au_set_dbwh(dentry, bindex);
076b876e
AM
32073+ au_fhsm_wrote(sb, bindex, /*force*/0);
32074+ } else {
1facf9fc 32075+ dput(wh_dentry);
32076+ wh_dentry = ERR_PTR(err);
32077+ }
32078+ }
32079+
32080+ return wh_dentry;
32081+}
32082+
32083+/* ---------------------------------------------------------------------- */
32084+
32085+/* Delete all whiteouts in this directory on branch bindex. */
32086+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
32087+ aufs_bindex_t bindex, struct au_branch *br)
32088+{
32089+ int err;
32090+ unsigned long ul, n;
32091+ struct qstr wh_name;
32092+ char *p;
32093+ struct hlist_head *head;
c06a8ce3 32094+ struct au_vdir_wh *pos;
1facf9fc 32095+ struct au_vdir_destr *str;
32096+
32097+ err = -ENOMEM;
537831f9 32098+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 32099+ wh_name.name = p;
32100+ if (unlikely(!wh_name.name))
32101+ goto out;
32102+
32103+ err = 0;
32104+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32105+ p += AUFS_WH_PFX_LEN;
32106+ n = whlist->nh_num;
32107+ head = whlist->nh_head;
32108+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
32109+ hlist_for_each_entry(pos, head, wh_hash) {
32110+ if (pos->wh_bindex != bindex)
1facf9fc 32111+ continue;
32112+
c06a8ce3 32113+ str = &pos->wh_str;
1facf9fc 32114+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
32115+ memcpy(p, str->name, str->len);
32116+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
32117+ err = unlink_wh_name(h_dentry, &wh_name, br);
32118+ if (!err)
32119+ continue;
32120+ break;
32121+ }
32122+ AuIOErr("whiteout name too long %.*s\n",
32123+ str->len, str->name);
32124+ err = -EIO;
32125+ break;
32126+ }
32127+ }
537831f9 32128+ free_page((unsigned long)wh_name.name);
1facf9fc 32129+
4f0767ce 32130+out:
1facf9fc 32131+ return err;
32132+}
32133+
32134+struct del_wh_children_args {
32135+ int *errp;
32136+ struct dentry *h_dentry;
1308ab2a 32137+ struct au_nhash *whlist;
1facf9fc 32138+ aufs_bindex_t bindex;
32139+ struct au_branch *br;
32140+};
32141+
32142+static void call_del_wh_children(void *args)
32143+{
32144+ struct del_wh_children_args *a = args;
1308ab2a 32145+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 32146+}
32147+
32148+/* ---------------------------------------------------------------------- */
32149+
32150+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
32151+{
32152+ struct au_whtmp_rmdir *whtmp;
dece6358 32153+ int err;
1308ab2a 32154+ unsigned int rdhash;
dece6358
AM
32155+
32156+ SiMustAnyLock(sb);
1facf9fc 32157+
32158+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
32159+ if (unlikely(!whtmp)) {
32160+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 32161+ goto out;
dece6358 32162+ }
1facf9fc 32163+
32164+ whtmp->dir = NULL;
027c5e7a 32165+ whtmp->br = NULL;
1facf9fc 32166+ whtmp->wh_dentry = NULL;
1308ab2a 32167+ /* no estimation for dir size */
32168+ rdhash = au_sbi(sb)->si_rdhash;
32169+ if (!rdhash)
32170+ rdhash = AUFS_RDHASH_DEF;
32171+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
32172+ if (unlikely(err)) {
32173+ kfree(whtmp);
32174+ whtmp = ERR_PTR(err);
32175+ }
dece6358 32176+
4f0767ce 32177+out:
dece6358 32178+ return whtmp;
1facf9fc 32179+}
32180+
32181+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
32182+{
027c5e7a
AM
32183+ if (whtmp->br)
32184+ atomic_dec(&whtmp->br->br_count);
1facf9fc 32185+ dput(whtmp->wh_dentry);
32186+ iput(whtmp->dir);
dece6358 32187+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 32188+ kfree(whtmp);
32189+}
32190+
32191+/*
32192+ * rmdir the whiteouted temporary named dir @h_dentry.
32193+ * @whlist: whiteouted children.
32194+ */
32195+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
32196+ struct dentry *wh_dentry, struct au_nhash *whlist)
32197+{
32198+ int err;
2000de60 32199+ unsigned int h_nlink;
1facf9fc 32200+ struct path h_tmp;
32201+ struct inode *wh_inode, *h_dir;
32202+ struct au_branch *br;
32203+
32204+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
32205+ IMustLock(h_dir);
32206+
32207+ br = au_sbr(dir->i_sb, bindex);
32208+ wh_inode = wh_dentry->d_inode;
32209+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
32210+
32211+ /*
32212+ * someone else might change some whiteouts while we were sleeping.
32213+ * it means this whlist may have an obsoleted entry.
32214+ */
32215+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
32216+ err = del_wh_children(wh_dentry, whlist, bindex, br);
32217+ else {
32218+ int wkq_err;
32219+ struct del_wh_children_args args = {
32220+ .errp = &err,
32221+ .h_dentry = wh_dentry,
1308ab2a 32222+ .whlist = whlist,
1facf9fc 32223+ .bindex = bindex,
32224+ .br = br
32225+ };
32226+
32227+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
32228+ if (unlikely(wkq_err))
32229+ err = wkq_err;
32230+ }
32231+ mutex_unlock(&wh_inode->i_mutex);
32232+
32233+ if (!err) {
32234+ h_tmp.dentry = wh_dentry;
86dc4139 32235+ h_tmp.mnt = au_br_mnt(br);
2000de60 32236+ h_nlink = h_dir->i_nlink;
1facf9fc 32237+ err = vfsub_rmdir(h_dir, &h_tmp);
2000de60
JR
32238+ /* some fs doesn't change the parent nlink in some cases */
32239+ h_nlink -= h_dir->i_nlink;
1facf9fc 32240+ }
32241+
32242+ if (!err) {
32243+ if (au_ibstart(dir) == bindex) {
7f207e10 32244+ /* todo: dir->i_mutex is necessary */
1facf9fc 32245+ au_cpup_attr_timesizes(dir);
2000de60
JR
32246+ if (h_nlink)
32247+ vfsub_drop_nlink(dir);
1facf9fc 32248+ }
32249+ return 0; /* success */
32250+ }
32251+
523b37e3 32252+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 32253+ return err;
32254+}
32255+
32256+static void call_rmdir_whtmp(void *args)
32257+{
32258+ int err;
e49829fe 32259+ aufs_bindex_t bindex;
1facf9fc 32260+ struct au_whtmp_rmdir *a = args;
32261+ struct super_block *sb;
32262+ struct dentry *h_parent;
32263+ struct inode *h_dir;
1facf9fc 32264+ struct au_hinode *hdir;
32265+
32266+ /* rmdir by nfsd may cause deadlock with this i_mutex */
32267+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 32268+ err = -EROFS;
1facf9fc 32269+ sb = a->dir->i_sb;
e49829fe
JR
32270+ si_read_lock(sb, !AuLock_FLUSH);
32271+ if (!au_br_writable(a->br->br_perm))
32272+ goto out;
32273+ bindex = au_br_index(sb, a->br->br_id);
32274+ if (unlikely(bindex < 0))
1facf9fc 32275+ goto out;
32276+
32277+ err = -EIO;
1facf9fc 32278+ ii_write_lock_parent(a->dir);
32279+ h_parent = dget_parent(a->wh_dentry);
32280+ h_dir = h_parent->d_inode;
e49829fe 32281+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
32282+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
32283+ if (unlikely(err))
32284+ goto out_mnt;
4a4d8108 32285+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
32286+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
32287+ a->br);
86dc4139
AM
32288+ if (!err)
32289+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 32290+ au_hn_imtx_unlock(hdir);
86dc4139
AM
32291+ vfsub_mnt_drop_write(au_br_mnt(a->br));
32292+
32293+out_mnt:
1facf9fc 32294+ dput(h_parent);
32295+ ii_write_unlock(a->dir);
4f0767ce 32296+out:
1facf9fc 32297+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 32298+ au_whtmp_rmdir_free(a);
027c5e7a
AM
32299+ si_read_unlock(sb);
32300+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32301+ if (unlikely(err))
32302+ AuIOErr("err %d\n", err);
32303+}
32304+
32305+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
32306+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
32307+{
32308+ int wkq_err;
e49829fe 32309+ struct super_block *sb;
1facf9fc 32310+
32311+ IMustLock(dir);
32312+
32313+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 32314+ sb = dir->i_sb;
1facf9fc 32315+ args->dir = au_igrab(dir);
e49829fe
JR
32316+ args->br = au_sbr(sb, bindex);
32317+ atomic_inc(&args->br->br_count);
1facf9fc 32318+ args->wh_dentry = dget(wh_dentry);
53392da6 32319+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 32320+ if (unlikely(wkq_err)) {
523b37e3 32321+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 32322+ au_whtmp_rmdir_free(args);
32323+ }
32324+}
7f207e10
AM
32325diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
32326--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 32327+++ linux/fs/aufs/whout.h 2015-04-13 15:10:20.790157026 +0200
076b876e 32328@@ -0,0 +1,85 @@
1facf9fc 32329+/*
2000de60 32330+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 32331+ *
32332+ * This program, aufs is free software; you can redistribute it and/or modify
32333+ * it under the terms of the GNU General Public License as published by
32334+ * the Free Software Foundation; either version 2 of the License, or
32335+ * (at your option) any later version.
dece6358
AM
32336+ *
32337+ * This program is distributed in the hope that it will be useful,
32338+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32339+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32340+ * GNU General Public License for more details.
32341+ *
32342+ * You should have received a copy of the GNU General Public License
523b37e3 32343+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32344+ */
32345+
32346+/*
32347+ * whiteout for logical deletion and opaque directory
32348+ */
32349+
32350+#ifndef __AUFS_WHOUT_H__
32351+#define __AUFS_WHOUT_H__
32352+
32353+#ifdef __KERNEL__
32354+
1facf9fc 32355+#include "dir.h"
32356+
32357+/* whout.c */
32358+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
076b876e
AM
32359+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
32360+int au_diropq_test(struct dentry *h_dentry);
7e9cd9fe 32361+struct au_branch;
1facf9fc 32362+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
32363+ struct qstr *prefix);
32364+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
32365+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
32366+ struct dentry *dentry);
86dc4139 32367+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 32368+
32369+/* diropq flags */
32370+#define AuDiropq_CREATE 1
32371+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
32372+#define au_fset_diropq(flags, name) \
32373+ do { (flags) |= AuDiropq_##name; } while (0)
32374+#define au_fclr_diropq(flags, name) \
32375+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 32376+
32377+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
32378+ unsigned int flags);
32379+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
32380+ struct au_branch *br);
32381+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
32382+ struct dentry *h_parent);
32383+
32384+/* real rmdir for the whiteout-ed dir */
32385+struct au_whtmp_rmdir {
32386+ struct inode *dir;
e49829fe 32387+ struct au_branch *br;
1facf9fc 32388+ struct dentry *wh_dentry;
dece6358 32389+ struct au_nhash whlist;
1facf9fc 32390+};
32391+
32392+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
32393+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
32394+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
32395+ struct dentry *wh_dentry, struct au_nhash *whlist);
32396+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
32397+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
32398+
32399+/* ---------------------------------------------------------------------- */
32400+
32401+static inline struct dentry *au_diropq_create(struct dentry *dentry,
32402+ aufs_bindex_t bindex)
32403+{
32404+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
32405+}
32406+
32407+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
32408+{
32409+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
32410+}
32411+
32412+#endif /* __KERNEL__ */
32413+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
32414diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
32415--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 32416+++ linux/fs/aufs/wkq.c 2015-04-13 15:10:20.790157026 +0200
38d290e6 32417@@ -0,0 +1,213 @@
1facf9fc 32418+/*
2000de60 32419+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 32420+ *
32421+ * This program, aufs is free software; you can redistribute it and/or modify
32422+ * it under the terms of the GNU General Public License as published by
32423+ * the Free Software Foundation; either version 2 of the License, or
32424+ * (at your option) any later version.
dece6358
AM
32425+ *
32426+ * This program is distributed in the hope that it will be useful,
32427+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32428+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32429+ * GNU General Public License for more details.
32430+ *
32431+ * You should have received a copy of the GNU General Public License
523b37e3 32432+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32433+ */
32434+
32435+/*
32436+ * workqueue for asynchronous/super-io operations
32437+ * todo: try new dredential scheme
32438+ */
32439+
dece6358 32440+#include <linux/module.h>
1facf9fc 32441+#include "aufs.h"
32442+
9dbd164d 32443+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 32444+
9dbd164d 32445+static struct workqueue_struct *au_wkq;
1facf9fc 32446+
32447+struct au_wkinfo {
32448+ struct work_struct wk;
7f207e10 32449+ struct kobject *kobj;
1facf9fc 32450+
32451+ unsigned int flags; /* see wkq.h */
32452+
32453+ au_wkq_func_t func;
32454+ void *args;
32455+
1facf9fc 32456+ struct completion *comp;
32457+};
32458+
32459+/* ---------------------------------------------------------------------- */
32460+
1facf9fc 32461+static void wkq_func(struct work_struct *wk)
32462+{
32463+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
32464+
2dfbb274 32465+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
32466+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
32467+
1facf9fc 32468+ wkinfo->func(wkinfo->args);
1facf9fc 32469+ if (au_ftest_wkq(wkinfo->flags, WAIT))
32470+ complete(wkinfo->comp);
32471+ else {
7f207e10 32472+ kobject_put(wkinfo->kobj);
9dbd164d 32473+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 32474+ kfree(wkinfo);
32475+ }
32476+}
32477+
32478+/*
32479+ * Since struct completion is large, try allocating it dynamically.
32480+ */
c2b27bf2 32481+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 32482+#define AuWkqCompDeclare(name) struct completion *comp = NULL
32483+
32484+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
32485+{
32486+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
32487+ if (*comp) {
32488+ init_completion(*comp);
32489+ wkinfo->comp = *comp;
32490+ return 0;
32491+ }
32492+ return -ENOMEM;
32493+}
32494+
32495+static void au_wkq_comp_free(struct completion *comp)
32496+{
32497+ kfree(comp);
32498+}
32499+
32500+#else
32501+
32502+/* no braces */
32503+#define AuWkqCompDeclare(name) \
32504+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
32505+ struct completion *comp = &_ ## name
32506+
32507+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
32508+{
32509+ wkinfo->comp = *comp;
32510+ return 0;
32511+}
32512+
32513+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
32514+{
32515+ /* empty */
32516+}
32517+#endif /* 4KSTACKS */
32518+
53392da6 32519+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 32520+{
53392da6
AM
32521+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
32522+ if (au_wkq_test()) {
38d290e6
JR
32523+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
32524+ " due to a dead dir by UDBA?\n");
53392da6
AM
32525+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
32526+ }
32527+ } else
32528+ au_dbg_verify_kthread();
32529+
32530+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 32531+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 32532+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
32533+ } else {
32534+ INIT_WORK(&wkinfo->wk, wkq_func);
32535+ schedule_work(&wkinfo->wk);
32536+ }
1facf9fc 32537+}
32538+
7f207e10
AM
32539+/*
32540+ * Be careful. It is easy to make deadlock happen.
32541+ * processA: lock, wkq and wait
32542+ * processB: wkq and wait, lock in wkq
32543+ * --> deadlock
32544+ */
b752ccd1 32545+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 32546+{
32547+ int err;
32548+ AuWkqCompDeclare(comp);
32549+ struct au_wkinfo wkinfo = {
b752ccd1 32550+ .flags = flags,
1facf9fc 32551+ .func = func,
32552+ .args = args
32553+ };
32554+
32555+ err = au_wkq_comp_alloc(&wkinfo, &comp);
32556+ if (!err) {
53392da6 32557+ au_wkq_run(&wkinfo);
1facf9fc 32558+ /* no timeout, no interrupt */
32559+ wait_for_completion(wkinfo.comp);
32560+ au_wkq_comp_free(comp);
4a4d8108 32561+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 32562+ }
32563+
32564+ return err;
32565+
32566+}
32567+
027c5e7a
AM
32568+/*
32569+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
32570+ * problem in a concurrent umounting.
32571+ */
53392da6
AM
32572+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
32573+ unsigned int flags)
1facf9fc 32574+{
32575+ int err;
32576+ struct au_wkinfo *wkinfo;
32577+
32578+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
32579+
32580+ /*
32581+ * wkq_func() must free this wkinfo.
32582+ * it highly depends upon the implementation of workqueue.
32583+ */
32584+ err = 0;
32585+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
32586+ if (wkinfo) {
7f207e10 32587+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 32588+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 32589+ wkinfo->func = func;
32590+ wkinfo->args = args;
32591+ wkinfo->comp = NULL;
7f207e10 32592+ kobject_get(wkinfo->kobj);
9dbd164d 32593+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 32594+
53392da6 32595+ au_wkq_run(wkinfo);
1facf9fc 32596+ } else {
32597+ err = -ENOMEM;
e49829fe 32598+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32599+ }
32600+
32601+ return err;
32602+}
32603+
32604+/* ---------------------------------------------------------------------- */
32605+
32606+void au_nwt_init(struct au_nowait_tasks *nwt)
32607+{
32608+ atomic_set(&nwt->nw_len, 0);
4a4d8108 32609+ /* smp_mb(); */ /* atomic_set */
1facf9fc 32610+ init_waitqueue_head(&nwt->nw_wq);
32611+}
32612+
32613+void au_wkq_fin(void)
32614+{
9dbd164d 32615+ destroy_workqueue(au_wkq);
1facf9fc 32616+}
32617+
32618+int __init au_wkq_init(void)
32619+{
9dbd164d 32620+ int err;
b752ccd1
AM
32621+
32622+ err = 0;
86dc4139 32623+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
32624+ if (IS_ERR(au_wkq))
32625+ err = PTR_ERR(au_wkq);
32626+ else if (!au_wkq)
32627+ err = -ENOMEM;
b752ccd1
AM
32628+
32629+ return err;
1facf9fc 32630+}
7f207e10
AM
32631diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
32632--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 32633+++ linux/fs/aufs/wkq.h 2015-04-13 15:10:20.790157026 +0200
523b37e3 32634@@ -0,0 +1,91 @@
1facf9fc 32635+/*
2000de60 32636+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 32637+ *
32638+ * This program, aufs is free software; you can redistribute it and/or modify
32639+ * it under the terms of the GNU General Public License as published by
32640+ * the Free Software Foundation; either version 2 of the License, or
32641+ * (at your option) any later version.
dece6358
AM
32642+ *
32643+ * This program is distributed in the hope that it will be useful,
32644+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32645+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32646+ * GNU General Public License for more details.
32647+ *
32648+ * You should have received a copy of the GNU General Public License
523b37e3 32649+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32650+ */
32651+
32652+/*
32653+ * workqueue for asynchronous/super-io operations
32654+ * todo: try new credentials management scheme
32655+ */
32656+
32657+#ifndef __AUFS_WKQ_H__
32658+#define __AUFS_WKQ_H__
32659+
32660+#ifdef __KERNEL__
32661+
dece6358
AM
32662+struct super_block;
32663+
1facf9fc 32664+/* ---------------------------------------------------------------------- */
32665+
32666+/*
32667+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
32668+ */
32669+struct au_nowait_tasks {
32670+ atomic_t nw_len;
32671+ wait_queue_head_t nw_wq;
32672+};
32673+
32674+/* ---------------------------------------------------------------------- */
32675+
32676+typedef void (*au_wkq_func_t)(void *args);
32677+
32678+/* wkq flags */
32679+#define AuWkq_WAIT 1
9dbd164d 32680+#define AuWkq_NEST (1 << 1)
1facf9fc 32681+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
32682+#define au_fset_wkq(flags, name) \
32683+ do { (flags) |= AuWkq_##name; } while (0)
32684+#define au_fclr_wkq(flags, name) \
32685+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 32686+
9dbd164d
AM
32687+#ifndef CONFIG_AUFS_HNOTIFY
32688+#undef AuWkq_NEST
32689+#define AuWkq_NEST 0
32690+#endif
32691+
1facf9fc 32692+/* wkq.c */
b752ccd1 32693+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
32694+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
32695+ unsigned int flags);
1facf9fc 32696+void au_nwt_init(struct au_nowait_tasks *nwt);
32697+int __init au_wkq_init(void);
32698+void au_wkq_fin(void);
32699+
32700+/* ---------------------------------------------------------------------- */
32701+
53392da6
AM
32702+static inline int au_wkq_test(void)
32703+{
32704+ return current->flags & PF_WQ_WORKER;
32705+}
32706+
b752ccd1 32707+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 32708+{
b752ccd1 32709+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 32710+}
32711+
32712+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
32713+{
e49829fe 32714+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 32715+ wake_up_all(&nwt->nw_wq);
32716+}
32717+
32718+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
32719+{
32720+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
32721+ return 0;
32722+}
32723+
32724+#endif /* __KERNEL__ */
32725+#endif /* __AUFS_WKQ_H__ */
c1595e42
JR
32726diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
32727--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe
AM
32728+++ linux/fs/aufs/xattr.c 2015-04-13 15:10:20.790157026 +0200
32729@@ -0,0 +1,338 @@
c1595e42 32730+/*
2000de60 32731+ * Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
32732+ *
32733+ * This program, aufs is free software; you can redistribute it and/or modify
32734+ * it under the terms of the GNU General Public License as published by
32735+ * the Free Software Foundation; either version 2 of the License, or
32736+ * (at your option) any later version.
32737+ *
32738+ * This program is distributed in the hope that it will be useful,
32739+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32740+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32741+ * GNU General Public License for more details.
32742+ *
32743+ * You should have received a copy of the GNU General Public License
32744+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
32745+ */
32746+
32747+/*
32748+ * handling xattr functions
32749+ */
32750+
32751+#include <linux/xattr.h>
32752+#include "aufs.h"
32753+
32754+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
32755+{
32756+ if (!ignore_flags)
32757+ goto out;
32758+ switch (err) {
32759+ case -ENOMEM:
32760+ case -EDQUOT:
32761+ goto out;
32762+ }
32763+
32764+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
32765+ err = 0;
32766+ goto out;
32767+ }
32768+
32769+#define cmp(brattr, prefix) do { \
32770+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
32771+ XATTR_##prefix##_PREFIX_LEN)) { \
32772+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
32773+ err = 0; \
32774+ goto out; \
32775+ } \
32776+ } while (0)
32777+
32778+ cmp(SEC, SECURITY);
32779+ cmp(SYS, SYSTEM);
32780+ cmp(TR, TRUSTED);
32781+ cmp(USR, USER);
32782+#undef cmp
32783+
32784+ if (ignore_flags & AuBrAttr_ICEX_OTH)
32785+ err = 0;
32786+
32787+out:
32788+ return err;
32789+}
32790+
32791+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
32792+
32793+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
7e9cd9fe
AM
32794+ char *name, char **buf, unsigned int ignore_flags,
32795+ unsigned int verbose)
c1595e42
JR
32796+{
32797+ int err;
32798+ ssize_t ssz;
32799+ struct inode *h_idst;
32800+
32801+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
32802+ err = ssz;
32803+ if (unlikely(err <= 0)) {
32804+ AuTraceErr(err);
32805+ if (err == -ENODATA
32806+ || (err == -EOPNOTSUPP
32807+ && (ignore_flags & au_xattr_out_of_list)))
32808+ err = 0;
32809+ goto out;
32810+ }
32811+
32812+ /* unlock it temporary */
32813+ h_idst = h_dst->d_inode;
32814+ mutex_unlock(&h_idst->i_mutex);
32815+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
32816+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
32817+ if (unlikely(err)) {
7e9cd9fe
AM
32818+ if (verbose || au_debug_test())
32819+ pr_err("%s, err %d\n", name, err);
c1595e42
JR
32820+ err = au_xattr_ignore(err, name, ignore_flags);
32821+ }
32822+
32823+out:
32824+ return err;
32825+}
32826+
7e9cd9fe
AM
32827+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
32828+ unsigned int verbose)
c1595e42
JR
32829+{
32830+ int err, unlocked, acl_access, acl_default;
32831+ ssize_t ssz;
32832+ struct inode *h_isrc, *h_idst;
32833+ char *value, *p, *o, *e;
32834+
32835+ /* try stopping to update the source inode while we are referencing */
7e9cd9fe 32836+ /* there should not be the parent-child relationship between them */
c1595e42
JR
32837+ h_isrc = h_src->d_inode;
32838+ h_idst = h_dst->d_inode;
32839+ mutex_unlock(&h_idst->i_mutex);
32840+ mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
32841+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
32842+ unlocked = 0;
32843+
32844+ /* some filesystems don't list POSIX ACL, for example tmpfs */
32845+ ssz = vfs_listxattr(h_src, NULL, 0);
32846+ err = ssz;
32847+ if (unlikely(err < 0)) {
32848+ AuTraceErr(err);
32849+ if (err == -ENODATA
32850+ || err == -EOPNOTSUPP)
32851+ err = 0; /* ignore */
32852+ goto out;
32853+ }
32854+
32855+ err = 0;
32856+ p = NULL;
32857+ o = NULL;
32858+ if (ssz) {
32859+ err = -ENOMEM;
32860+ p = kmalloc(ssz, GFP_NOFS);
32861+ o = p;
32862+ if (unlikely(!p))
32863+ goto out;
32864+ err = vfs_listxattr(h_src, p, ssz);
32865+ }
32866+ mutex_unlock(&h_isrc->i_mutex);
32867+ unlocked = 1;
32868+ AuDbg("err %d, ssz %zd\n", err, ssz);
32869+ if (unlikely(err < 0))
32870+ goto out_free;
32871+
32872+ err = 0;
32873+ e = p + ssz;
32874+ value = NULL;
32875+ acl_access = 0;
32876+ acl_default = 0;
32877+ while (!err && p < e) {
32878+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
32879+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
32880+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
32881+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
32882+ - 1);
7e9cd9fe
AM
32883+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
32884+ verbose);
c1595e42
JR
32885+ p += strlen(p) + 1;
32886+ }
32887+ AuTraceErr(err);
32888+ ignore_flags |= au_xattr_out_of_list;
32889+ if (!err && !acl_access) {
32890+ err = au_do_cpup_xattr(h_dst, h_src,
32891+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
7e9cd9fe 32892+ ignore_flags, verbose);
c1595e42
JR
32893+ AuTraceErr(err);
32894+ }
32895+ if (!err && !acl_default) {
32896+ err = au_do_cpup_xattr(h_dst, h_src,
32897+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
7e9cd9fe 32898+ ignore_flags, verbose);
c1595e42
JR
32899+ AuTraceErr(err);
32900+ }
32901+
32902+ kfree(value);
32903+
32904+out_free:
32905+ kfree(o);
32906+out:
32907+ if (!unlocked)
32908+ mutex_unlock(&h_isrc->i_mutex);
32909+ AuTraceErr(err);
32910+ return err;
32911+}
32912+
32913+/* ---------------------------------------------------------------------- */
32914+
32915+enum {
32916+ AU_XATTR_LIST,
32917+ AU_XATTR_GET
32918+};
32919+
32920+struct au_lgxattr {
32921+ int type;
32922+ union {
32923+ struct {
32924+ char *list;
32925+ size_t size;
32926+ } list;
32927+ struct {
32928+ const char *name;
32929+ void *value;
32930+ size_t size;
32931+ } get;
32932+ } u;
32933+};
32934+
32935+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
32936+{
32937+ ssize_t err;
32938+ struct path h_path;
32939+ struct super_block *sb;
32940+
32941+ sb = dentry->d_sb;
32942+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
32943+ if (unlikely(err))
32944+ goto out;
32945+ err = au_h_path_getattr(dentry, /*force*/1, &h_path);
32946+ if (unlikely(err))
32947+ goto out_si;
32948+ if (unlikely(!h_path.dentry))
32949+ /* illegally overlapped or something */
32950+ goto out_di; /* pretending success */
32951+
32952+ /* always topmost entry only */
32953+ switch (arg->type) {
32954+ case AU_XATTR_LIST:
32955+ err = vfs_listxattr(h_path.dentry,
32956+ arg->u.list.list, arg->u.list.size);
32957+ break;
32958+ case AU_XATTR_GET:
32959+ err = vfs_getxattr(h_path.dentry,
32960+ arg->u.get.name, arg->u.get.value,
32961+ arg->u.get.size);
32962+ break;
32963+ }
32964+
32965+out_di:
32966+ di_read_unlock(dentry, AuLock_IR);
32967+out_si:
32968+ si_read_unlock(sb);
32969+out:
32970+ AuTraceErr(err);
32971+ return err;
32972+}
32973+
32974+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
32975+{
32976+ struct au_lgxattr arg = {
32977+ .type = AU_XATTR_LIST,
32978+ .u.list = {
32979+ .list = list,
32980+ .size = size
32981+ },
32982+ };
32983+
32984+ return au_lgxattr(dentry, &arg);
32985+}
32986+
32987+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
32988+ size_t size)
32989+{
32990+ struct au_lgxattr arg = {
32991+ .type = AU_XATTR_GET,
32992+ .u.get = {
32993+ .name = name,
32994+ .value = value,
32995+ .size = size
32996+ },
32997+ };
32998+
32999+ return au_lgxattr(dentry, &arg);
33000+}
33001+
33002+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
33003+ size_t size, int flags)
33004+{
33005+ struct au_srxattr arg = {
33006+ .type = AU_XATTR_SET,
33007+ .u.set = {
33008+ .name = name,
33009+ .value = value,
33010+ .size = size,
33011+ .flags = flags
33012+ },
33013+ };
33014+
33015+ return au_srxattr(dentry, &arg);
33016+}
33017+
33018+int aufs_removexattr(struct dentry *dentry, const char *name)
33019+{
33020+ struct au_srxattr arg = {
33021+ .type = AU_XATTR_REMOVE,
33022+ .u.remove = {
33023+ .name = name
33024+ },
33025+ };
33026+
33027+ return au_srxattr(dentry, &arg);
33028+}
33029+
33030+/* ---------------------------------------------------------------------- */
33031+
33032+#if 0
33033+static size_t au_xattr_list(struct dentry *dentry, char *list, size_t list_size,
33034+ const char *name, size_t name_len, int type)
33035+{
33036+ return aufs_listxattr(dentry, list, list_size);
33037+}
33038+
33039+static int au_xattr_get(struct dentry *dentry, const char *name, void *buffer,
33040+ size_t size, int type)
33041+{
33042+ return aufs_getxattr(dentry, name, buffer, size);
33043+}
33044+
33045+static int au_xattr_set(struct dentry *dentry, const char *name,
33046+ const void *value, size_t size, int flags, int type)
33047+{
33048+ return aufs_setxattr(dentry, name, value, size, flags);
33049+}
33050+
33051+static const struct xattr_handler au_xattr_handler = {
33052+ /* no prefix, no flags */
33053+ .list = au_xattr_list,
33054+ .get = au_xattr_get,
33055+ .set = au_xattr_set
33056+ /* why no remove? */
33057+};
33058+
33059+static const struct xattr_handler *au_xattr_handlers[] = {
33060+ &au_xattr_handler
33061+};
33062+
33063+void au_xattr_init(struct super_block *sb)
33064+{
33065+ /* sb->s_xattr = au_xattr_handlers; */
33066+}
33067+#endif
7f207e10
AM
33068diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
33069--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 33070+++ linux/fs/aufs/xino.c 2015-04-13 15:10:20.790157026 +0200
c1595e42 33071@@ -0,0 +1,1318 @@
1facf9fc 33072+/*
2000de60 33073+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 33074+ *
33075+ * This program, aufs is free software; you can redistribute it and/or modify
33076+ * it under the terms of the GNU General Public License as published by
33077+ * the Free Software Foundation; either version 2 of the License, or
33078+ * (at your option) any later version.
dece6358
AM
33079+ *
33080+ * This program is distributed in the hope that it will be useful,
33081+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33082+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33083+ * GNU General Public License for more details.
33084+ *
33085+ * You should have received a copy of the GNU General Public License
523b37e3 33086+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33087+ */
33088+
33089+/*
33090+ * external inode number translation table and bitmap
33091+ */
33092+
33093+#include <linux/seq_file.h>
392086de 33094+#include <linux/statfs.h>
1facf9fc 33095+#include "aufs.h"
33096+
9dbd164d 33097+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 33098+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 33099+ loff_t *pos)
33100+{
33101+ ssize_t err;
33102+ mm_segment_t oldfs;
b752ccd1
AM
33103+ union {
33104+ void *k;
33105+ char __user *u;
33106+ } buf;
1facf9fc 33107+
b752ccd1 33108+ buf.k = kbuf;
1facf9fc 33109+ oldfs = get_fs();
33110+ set_fs(KERNEL_DS);
33111+ do {
33112+ /* todo: signal_pending? */
b752ccd1 33113+ err = func(file, buf.u, size, pos);
1facf9fc 33114+ } while (err == -EAGAIN || err == -EINTR);
33115+ set_fs(oldfs);
33116+
33117+#if 0 /* reserved for future use */
33118+ if (err > 0)
2000de60 33119+ fsnotify_access(file->f_path.dentry);
1facf9fc 33120+#endif
33121+
33122+ return err;
33123+}
33124+
33125+/* ---------------------------------------------------------------------- */
33126+
b752ccd1 33127+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 33128+ size_t size, loff_t *pos)
33129+{
33130+ ssize_t err;
33131+ mm_segment_t oldfs;
b752ccd1
AM
33132+ union {
33133+ void *k;
33134+ const char __user *u;
33135+ } buf;
1facf9fc 33136+
b752ccd1 33137+ buf.k = kbuf;
1facf9fc 33138+ oldfs = get_fs();
33139+ set_fs(KERNEL_DS);
1facf9fc 33140+ do {
33141+ /* todo: signal_pending? */
b752ccd1 33142+ err = func(file, buf.u, size, pos);
1facf9fc 33143+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 33144+ set_fs(oldfs);
33145+
33146+#if 0 /* reserved for future use */
33147+ if (err > 0)
2000de60 33148+ fsnotify_modify(file->f_path.dentry);
1facf9fc 33149+#endif
33150+
33151+ return err;
33152+}
33153+
33154+struct do_xino_fwrite_args {
33155+ ssize_t *errp;
33156+ au_writef_t func;
33157+ struct file *file;
33158+ void *buf;
33159+ size_t size;
33160+ loff_t *pos;
33161+};
33162+
33163+static void call_do_xino_fwrite(void *args)
33164+{
33165+ struct do_xino_fwrite_args *a = args;
33166+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
33167+}
33168+
33169+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
33170+ loff_t *pos)
33171+{
33172+ ssize_t err;
33173+
33174+ /* todo: signal block and no wkq? */
b752ccd1
AM
33175+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
33176+ lockdep_off();
33177+ err = do_xino_fwrite(func, file, buf, size, pos);
33178+ lockdep_on();
33179+ } else {
33180+ /*
33181+ * it breaks RLIMIT_FSIZE and normal user's limit,
33182+ * users should care about quota and real 'filesystem full.'
33183+ */
1facf9fc 33184+ int wkq_err;
33185+ struct do_xino_fwrite_args args = {
33186+ .errp = &err,
33187+ .func = func,
33188+ .file = file,
33189+ .buf = buf,
33190+ .size = size,
33191+ .pos = pos
33192+ };
33193+
33194+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
33195+ if (unlikely(wkq_err))
33196+ err = wkq_err;
b752ccd1 33197+ }
1facf9fc 33198+
33199+ return err;
33200+}
33201+
33202+/* ---------------------------------------------------------------------- */
33203+
33204+/*
33205+ * create a new xinofile at the same place/path as @base_file.
33206+ */
33207+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
33208+{
33209+ struct file *file;
4a4d8108 33210+ struct dentry *base, *parent;
523b37e3 33211+ struct inode *dir, *delegated;
1facf9fc 33212+ struct qstr *name;
1308ab2a 33213+ struct path path;
4a4d8108 33214+ int err;
1facf9fc 33215+
2000de60 33216+ base = base_file->f_path.dentry;
1facf9fc 33217+ parent = base->d_parent; /* dir inode is locked */
33218+ dir = parent->d_inode;
33219+ IMustLock(dir);
33220+
33221+ file = ERR_PTR(-EINVAL);
33222+ name = &base->d_name;
4a4d8108
AM
33223+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
33224+ if (IS_ERR(path.dentry)) {
33225+ file = (void *)path.dentry;
523b37e3
AM
33226+ pr_err("%pd lookup err %ld\n",
33227+ base, PTR_ERR(path.dentry));
1facf9fc 33228+ goto out;
33229+ }
33230+
33231+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 33232+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 33233+ if (unlikely(err)) {
33234+ file = ERR_PTR(err);
523b37e3 33235+ pr_err("%pd create err %d\n", base, err);
1facf9fc 33236+ goto out_dput;
33237+ }
33238+
c06a8ce3 33239+ path.mnt = base_file->f_path.mnt;
4a4d8108 33240+ file = vfsub_dentry_open(&path,
7f207e10 33241+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 33242+ /* | __FMODE_NONOTIFY */);
1facf9fc 33243+ if (IS_ERR(file)) {
523b37e3 33244+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 33245+ goto out_dput;
33246+ }
33247+
523b37e3
AM
33248+ delegated = NULL;
33249+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
33250+ if (unlikely(err == -EWOULDBLOCK)) {
33251+ pr_warn("cannot retry for NFSv4 delegation"
33252+ " for an internal unlink\n");
33253+ iput(delegated);
33254+ }
1facf9fc 33255+ if (unlikely(err)) {
523b37e3 33256+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 33257+ goto out_fput;
33258+ }
33259+
33260+ if (copy_src) {
33261+ /* no one can touch copy_src xino */
c06a8ce3 33262+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 33263+ if (unlikely(err)) {
523b37e3 33264+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 33265+ goto out_fput;
33266+ }
33267+ }
33268+ goto out_dput; /* success */
33269+
4f0767ce 33270+out_fput:
1facf9fc 33271+ fput(file);
33272+ file = ERR_PTR(err);
4f0767ce 33273+out_dput:
4a4d8108 33274+ dput(path.dentry);
4f0767ce 33275+out:
1facf9fc 33276+ return file;
33277+}
33278+
33279+struct au_xino_lock_dir {
33280+ struct au_hinode *hdir;
33281+ struct dentry *parent;
33282+ struct mutex *mtx;
33283+};
33284+
33285+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
33286+ struct au_xino_lock_dir *ldir)
33287+{
33288+ aufs_bindex_t brid, bindex;
33289+
33290+ ldir->hdir = NULL;
33291+ bindex = -1;
33292+ brid = au_xino_brid(sb);
33293+ if (brid >= 0)
33294+ bindex = au_br_index(sb, brid);
33295+ if (bindex >= 0) {
33296+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 33297+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 33298+ } else {
2000de60 33299+ ldir->parent = dget_parent(xino->f_path.dentry);
1facf9fc 33300+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
33301+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
33302+ }
33303+}
33304+
33305+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
33306+{
33307+ if (ldir->hdir)
4a4d8108 33308+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 33309+ else {
33310+ mutex_unlock(ldir->mtx);
33311+ dput(ldir->parent);
33312+ }
33313+}
33314+
33315+/* ---------------------------------------------------------------------- */
33316+
33317+/* trucate xino files asynchronously */
33318+
33319+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
33320+{
33321+ int err;
392086de
AM
33322+ unsigned long jiffy;
33323+ blkcnt_t blocks;
1facf9fc 33324+ aufs_bindex_t bi, bend;
392086de 33325+ struct kstatfs *st;
1facf9fc 33326+ struct au_branch *br;
33327+ struct file *new_xino, *file;
33328+ struct super_block *h_sb;
33329+ struct au_xino_lock_dir ldir;
33330+
392086de
AM
33331+ err = -ENOMEM;
33332+ st = kzalloc(sizeof(*st), GFP_NOFS);
33333+ if (unlikely(!st))
33334+ goto out;
33335+
1facf9fc 33336+ err = -EINVAL;
33337+ bend = au_sbend(sb);
33338+ if (unlikely(bindex < 0 || bend < bindex))
392086de 33339+ goto out_st;
1facf9fc 33340+ br = au_sbr(sb, bindex);
33341+ file = br->br_xino.xi_file;
33342+ if (!file)
392086de
AM
33343+ goto out_st;
33344+
33345+ err = vfs_statfs(&file->f_path, st);
33346+ if (unlikely(err))
33347+ AuErr1("statfs err %d, ignored\n", err);
33348+ jiffy = jiffies;
33349+ blocks = file_inode(file)->i_blocks;
33350+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
33351+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 33352+
33353+ au_xino_lock_dir(sb, file, &ldir);
33354+ /* mnt_want_write() is unnecessary here */
33355+ new_xino = au_xino_create2(file, file);
33356+ au_xino_unlock_dir(&ldir);
33357+ err = PTR_ERR(new_xino);
392086de
AM
33358+ if (IS_ERR(new_xino)) {
33359+ pr_err("err %d, ignored\n", err);
33360+ goto out_st;
33361+ }
1facf9fc 33362+ err = 0;
33363+ fput(file);
33364+ br->br_xino.xi_file = new_xino;
33365+
86dc4139 33366+ h_sb = au_br_sb(br);
1facf9fc 33367+ for (bi = 0; bi <= bend; bi++) {
33368+ if (unlikely(bi == bindex))
33369+ continue;
33370+ br = au_sbr(sb, bi);
86dc4139 33371+ if (au_br_sb(br) != h_sb)
1facf9fc 33372+ continue;
33373+
33374+ fput(br->br_xino.xi_file);
33375+ br->br_xino.xi_file = new_xino;
33376+ get_file(new_xino);
33377+ }
33378+
392086de
AM
33379+ err = vfs_statfs(&new_xino->f_path, st);
33380+ if (!err) {
33381+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
33382+ bindex, (u64)file_inode(new_xino)->i_blocks,
33383+ st->f_bfree, st->f_blocks);
33384+ if (file_inode(new_xino)->i_blocks < blocks)
33385+ au_sbi(sb)->si_xino_jiffy = jiffy;
33386+ } else
33387+ AuErr1("statfs err %d, ignored\n", err);
33388+
33389+out_st:
33390+ kfree(st);
4f0767ce 33391+out:
1facf9fc 33392+ return err;
33393+}
33394+
33395+struct xino_do_trunc_args {
33396+ struct super_block *sb;
33397+ struct au_branch *br;
33398+};
33399+
33400+static void xino_do_trunc(void *_args)
33401+{
33402+ struct xino_do_trunc_args *args = _args;
33403+ struct super_block *sb;
33404+ struct au_branch *br;
33405+ struct inode *dir;
33406+ int err;
33407+ aufs_bindex_t bindex;
33408+
33409+ err = 0;
33410+ sb = args->sb;
33411+ dir = sb->s_root->d_inode;
33412+ br = args->br;
33413+
33414+ si_noflush_write_lock(sb);
33415+ ii_read_lock_parent(dir);
33416+ bindex = au_br_index(sb, br->br_id);
33417+ err = au_xino_trunc(sb, bindex);
1facf9fc 33418+ ii_read_unlock(dir);
33419+ if (unlikely(err))
392086de 33420+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 33421+ atomic_dec(&br->br_xino_running);
33422+ atomic_dec(&br->br_count);
1facf9fc 33423+ si_write_unlock(sb);
027c5e7a 33424+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 33425+ kfree(args);
33426+}
33427+
392086de
AM
33428+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
33429+{
33430+ int err;
33431+ struct kstatfs st;
33432+ struct au_sbinfo *sbinfo;
33433+
33434+ /* todo: si_xino_expire and the ratio should be customizable */
33435+ sbinfo = au_sbi(sb);
33436+ if (time_before(jiffies,
33437+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
33438+ return 0;
33439+
33440+ /* truncation border */
33441+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
33442+ if (unlikely(err)) {
33443+ AuErr1("statfs err %d, ignored\n", err);
33444+ return 0;
33445+ }
33446+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
33447+ return 0;
33448+
33449+ return 1;
33450+}
33451+
1facf9fc 33452+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
33453+{
33454+ struct xino_do_trunc_args *args;
33455+ int wkq_err;
33456+
392086de 33457+ if (!xino_trunc_test(sb, br))
1facf9fc 33458+ return;
33459+
33460+ if (atomic_inc_return(&br->br_xino_running) > 1)
33461+ goto out;
33462+
33463+ /* lock and kfree() will be called in trunc_xino() */
33464+ args = kmalloc(sizeof(*args), GFP_NOFS);
33465+ if (unlikely(!args)) {
33466+ AuErr1("no memory\n");
33467+ goto out_args;
33468+ }
33469+
e49829fe 33470+ atomic_inc(&br->br_count);
1facf9fc 33471+ args->sb = sb;
33472+ args->br = br;
53392da6 33473+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 33474+ if (!wkq_err)
33475+ return; /* success */
33476+
4a4d8108 33477+ pr_err("wkq %d\n", wkq_err);
e49829fe 33478+ atomic_dec(&br->br_count);
1facf9fc 33479+
4f0767ce 33480+out_args:
1facf9fc 33481+ kfree(args);
4f0767ce 33482+out:
e49829fe 33483+ atomic_dec(&br->br_xino_running);
1facf9fc 33484+}
33485+
33486+/* ---------------------------------------------------------------------- */
33487+
33488+static int au_xino_do_write(au_writef_t write, struct file *file,
33489+ ino_t h_ino, ino_t ino)
33490+{
33491+ loff_t pos;
33492+ ssize_t sz;
33493+
33494+ pos = h_ino;
33495+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
33496+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
33497+ return -EFBIG;
33498+ }
33499+ pos *= sizeof(ino);
33500+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
33501+ if (sz == sizeof(ino))
33502+ return 0; /* success */
33503+
33504+ AuIOErr("write failed (%zd)\n", sz);
33505+ return -EIO;
33506+}
33507+
33508+/*
33509+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
33510+ * at the position of @h_ino.
33511+ * even if @ino is zero, it is written to the xinofile and means no entry.
33512+ * if the size of the xino file on a specific filesystem exceeds the watermark,
33513+ * try truncating it.
33514+ */
33515+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
33516+ ino_t ino)
33517+{
33518+ int err;
33519+ unsigned int mnt_flags;
33520+ struct au_branch *br;
33521+
33522+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
33523+ || ((loff_t)-1) > 0);
dece6358 33524+ SiMustAnyLock(sb);
1facf9fc 33525+
33526+ mnt_flags = au_mntflags(sb);
33527+ if (!au_opt_test(mnt_flags, XINO))
33528+ return 0;
33529+
33530+ br = au_sbr(sb, bindex);
33531+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
33532+ h_ino, ino);
33533+ if (!err) {
33534+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 33535+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 33536+ xino_try_trunc(sb, br);
33537+ return 0; /* success */
33538+ }
33539+
33540+ AuIOErr("write failed (%d)\n", err);
33541+ return -EIO;
33542+}
33543+
33544+/* ---------------------------------------------------------------------- */
33545+
33546+/* aufs inode number bitmap */
33547+
33548+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
33549+static ino_t xib_calc_ino(unsigned long pindex, int bit)
33550+{
33551+ ino_t ino;
33552+
33553+ AuDebugOn(bit < 0 || page_bits <= bit);
33554+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
33555+ return ino;
33556+}
33557+
33558+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
33559+{
33560+ AuDebugOn(ino < AUFS_FIRST_INO);
33561+ ino -= AUFS_FIRST_INO;
33562+ *pindex = ino / page_bits;
33563+ *bit = ino % page_bits;
33564+}
33565+
33566+static int xib_pindex(struct super_block *sb, unsigned long pindex)
33567+{
33568+ int err;
33569+ loff_t pos;
33570+ ssize_t sz;
33571+ struct au_sbinfo *sbinfo;
33572+ struct file *xib;
33573+ unsigned long *p;
33574+
33575+ sbinfo = au_sbi(sb);
33576+ MtxMustLock(&sbinfo->si_xib_mtx);
33577+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
33578+ || !au_opt_test(sbinfo->si_mntflags, XINO));
33579+
33580+ if (pindex == sbinfo->si_xib_last_pindex)
33581+ return 0;
33582+
33583+ xib = sbinfo->si_xib;
33584+ p = sbinfo->si_xib_buf;
33585+ pos = sbinfo->si_xib_last_pindex;
33586+ pos *= PAGE_SIZE;
33587+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
33588+ if (unlikely(sz != PAGE_SIZE))
33589+ goto out;
33590+
33591+ pos = pindex;
33592+ pos *= PAGE_SIZE;
c06a8ce3 33593+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 33594+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
33595+ else {
33596+ memset(p, 0, PAGE_SIZE);
33597+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
33598+ }
33599+ if (sz == PAGE_SIZE) {
33600+ sbinfo->si_xib_last_pindex = pindex;
33601+ return 0; /* success */
33602+ }
33603+
4f0767ce 33604+out:
b752ccd1
AM
33605+ AuIOErr1("write failed (%zd)\n", sz);
33606+ err = sz;
33607+ if (sz >= 0)
33608+ err = -EIO;
33609+ return err;
33610+}
33611+
33612+/* ---------------------------------------------------------------------- */
33613+
33614+static void au_xib_clear_bit(struct inode *inode)
33615+{
33616+ int err, bit;
33617+ unsigned long pindex;
33618+ struct super_block *sb;
33619+ struct au_sbinfo *sbinfo;
33620+
33621+ AuDebugOn(inode->i_nlink);
33622+
33623+ sb = inode->i_sb;
33624+ xib_calc_bit(inode->i_ino, &pindex, &bit);
33625+ AuDebugOn(page_bits <= bit);
33626+ sbinfo = au_sbi(sb);
33627+ mutex_lock(&sbinfo->si_xib_mtx);
33628+ err = xib_pindex(sb, pindex);
33629+ if (!err) {
33630+ clear_bit(bit, sbinfo->si_xib_buf);
33631+ sbinfo->si_xib_next_bit = bit;
33632+ }
33633+ mutex_unlock(&sbinfo->si_xib_mtx);
33634+}
33635+
33636+/* for s_op->delete_inode() */
33637+void au_xino_delete_inode(struct inode *inode, const int unlinked)
33638+{
33639+ int err;
33640+ unsigned int mnt_flags;
33641+ aufs_bindex_t bindex, bend, bi;
33642+ unsigned char try_trunc;
33643+ struct au_iinfo *iinfo;
33644+ struct super_block *sb;
33645+ struct au_hinode *hi;
33646+ struct inode *h_inode;
33647+ struct au_branch *br;
33648+ au_writef_t xwrite;
33649+
33650+ sb = inode->i_sb;
33651+ mnt_flags = au_mntflags(sb);
33652+ if (!au_opt_test(mnt_flags, XINO)
33653+ || inode->i_ino == AUFS_ROOT_INO)
33654+ return;
33655+
33656+ if (unlinked) {
33657+ au_xigen_inc(inode);
33658+ au_xib_clear_bit(inode);
33659+ }
33660+
33661+ iinfo = au_ii(inode);
33662+ if (!iinfo)
33663+ return;
1facf9fc 33664+
b752ccd1
AM
33665+ bindex = iinfo->ii_bstart;
33666+ if (bindex < 0)
33667+ return;
1facf9fc 33668+
b752ccd1
AM
33669+ xwrite = au_sbi(sb)->si_xwrite;
33670+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
33671+ hi = iinfo->ii_hinode + bindex;
33672+ bend = iinfo->ii_bend;
33673+ for (; bindex <= bend; bindex++, hi++) {
33674+ h_inode = hi->hi_inode;
33675+ if (!h_inode
33676+ || (!unlinked && h_inode->i_nlink))
33677+ continue;
1facf9fc 33678+
b752ccd1
AM
33679+ /* inode may not be revalidated */
33680+ bi = au_br_index(sb, hi->hi_id);
33681+ if (bi < 0)
33682+ continue;
1facf9fc 33683+
b752ccd1
AM
33684+ br = au_sbr(sb, bi);
33685+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
33686+ h_inode->i_ino, /*ino*/0);
33687+ if (!err && try_trunc
86dc4139 33688+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 33689+ xino_try_trunc(sb, br);
1facf9fc 33690+ }
1facf9fc 33691+}
33692+
33693+/* get an unused inode number from bitmap */
33694+ino_t au_xino_new_ino(struct super_block *sb)
33695+{
33696+ ino_t ino;
33697+ unsigned long *p, pindex, ul, pend;
33698+ struct au_sbinfo *sbinfo;
33699+ struct file *file;
33700+ int free_bit, err;
33701+
33702+ if (!au_opt_test(au_mntflags(sb), XINO))
33703+ return iunique(sb, AUFS_FIRST_INO);
33704+
33705+ sbinfo = au_sbi(sb);
33706+ mutex_lock(&sbinfo->si_xib_mtx);
33707+ p = sbinfo->si_xib_buf;
33708+ free_bit = sbinfo->si_xib_next_bit;
33709+ if (free_bit < page_bits && !test_bit(free_bit, p))
33710+ goto out; /* success */
33711+ free_bit = find_first_zero_bit(p, page_bits);
33712+ if (free_bit < page_bits)
33713+ goto out; /* success */
33714+
33715+ pindex = sbinfo->si_xib_last_pindex;
33716+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
33717+ err = xib_pindex(sb, ul);
33718+ if (unlikely(err))
33719+ goto out_err;
33720+ free_bit = find_first_zero_bit(p, page_bits);
33721+ if (free_bit < page_bits)
33722+ goto out; /* success */
33723+ }
33724+
33725+ file = sbinfo->si_xib;
c06a8ce3 33726+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 33727+ for (ul = pindex + 1; ul <= pend; ul++) {
33728+ err = xib_pindex(sb, ul);
33729+ if (unlikely(err))
33730+ goto out_err;
33731+ free_bit = find_first_zero_bit(p, page_bits);
33732+ if (free_bit < page_bits)
33733+ goto out; /* success */
33734+ }
33735+ BUG();
33736+
4f0767ce 33737+out:
1facf9fc 33738+ set_bit(free_bit, p);
7f207e10 33739+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 33740+ pindex = sbinfo->si_xib_last_pindex;
33741+ mutex_unlock(&sbinfo->si_xib_mtx);
33742+ ino = xib_calc_ino(pindex, free_bit);
33743+ AuDbg("i%lu\n", (unsigned long)ino);
33744+ return ino;
4f0767ce 33745+out_err:
1facf9fc 33746+ mutex_unlock(&sbinfo->si_xib_mtx);
33747+ AuDbg("i0\n");
33748+ return 0;
33749+}
33750+
33751+/*
33752+ * read @ino from xinofile for the specified branch{@sb, @bindex}
33753+ * at the position of @h_ino.
33754+ * if @ino does not exist and @do_new is true, get new one.
33755+ */
33756+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
33757+ ino_t *ino)
33758+{
33759+ int err;
33760+ ssize_t sz;
33761+ loff_t pos;
33762+ struct file *file;
33763+ struct au_sbinfo *sbinfo;
33764+
33765+ *ino = 0;
33766+ if (!au_opt_test(au_mntflags(sb), XINO))
33767+ return 0; /* no xino */
33768+
33769+ err = 0;
33770+ sbinfo = au_sbi(sb);
33771+ pos = h_ino;
33772+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
33773+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
33774+ return -EFBIG;
33775+ }
33776+ pos *= sizeof(*ino);
33777+
33778+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 33779+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 33780+ return 0; /* no ino */
33781+
33782+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
33783+ if (sz == sizeof(*ino))
33784+ return 0; /* success */
33785+
33786+ err = sz;
33787+ if (unlikely(sz >= 0)) {
33788+ err = -EIO;
33789+ AuIOErr("xino read error (%zd)\n", sz);
33790+ }
33791+
33792+ return err;
33793+}
33794+
33795+/* ---------------------------------------------------------------------- */
33796+
33797+/* create and set a new xino file */
33798+
33799+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
33800+{
33801+ struct file *file;
33802+ struct dentry *h_parent, *d;
33803+ struct inode *h_dir;
33804+ int err;
33805+
33806+ /*
33807+ * at mount-time, and the xino file is the default path,
4a4d8108 33808+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 33809+ * when a user specified the xino, we cannot get au_hdir to be ignored.
33810+ */
7f207e10 33811+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 33812+ /* | __FMODE_NONOTIFY */,
1facf9fc 33813+ S_IRUGO | S_IWUGO);
33814+ if (IS_ERR(file)) {
33815+ if (!silent)
4a4d8108 33816+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 33817+ return file;
33818+ }
33819+
33820+ /* keep file count */
2000de60 33821+ h_parent = dget_parent(file->f_path.dentry);
1facf9fc 33822+ h_dir = h_parent->d_inode;
33823+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
33824+ /* mnt_want_write() is unnecessary here */
523b37e3
AM
33825+ /* no delegation since it is just created */
33826+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, /*force*/0);
1facf9fc 33827+ mutex_unlock(&h_dir->i_mutex);
33828+ dput(h_parent);
33829+ if (unlikely(err)) {
33830+ if (!silent)
4a4d8108 33831+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 33832+ goto out;
33833+ }
33834+
33835+ err = -EINVAL;
2000de60 33836+ d = file->f_path.dentry;
1facf9fc 33837+ if (unlikely(sb == d->d_sb)) {
33838+ if (!silent)
4a4d8108 33839+ pr_err("%s must be outside\n", fname);
1facf9fc 33840+ goto out;
33841+ }
33842+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
33843+ if (!silent)
4a4d8108
AM
33844+ pr_err("xino doesn't support %s(%s)\n",
33845+ fname, au_sbtype(d->d_sb));
1facf9fc 33846+ goto out;
33847+ }
33848+ return file; /* success */
33849+
4f0767ce 33850+out:
1facf9fc 33851+ fput(file);
33852+ file = ERR_PTR(err);
33853+ return file;
33854+}
33855+
33856+/*
33857+ * find another branch who is on the same filesystem of the specified
33858+ * branch{@btgt}. search until @bend.
33859+ */
33860+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
33861+ aufs_bindex_t bend)
33862+{
33863+ aufs_bindex_t bindex;
33864+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
33865+
33866+ for (bindex = 0; bindex < btgt; bindex++)
33867+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
33868+ return bindex;
33869+ for (bindex++; bindex <= bend; bindex++)
33870+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
33871+ return bindex;
33872+ return -1;
33873+}
33874+
33875+/* ---------------------------------------------------------------------- */
33876+
33877+/*
33878+ * initialize the xinofile for the specified branch @br
33879+ * at the place/path where @base_file indicates.
33880+ * test whether another branch is on the same filesystem or not,
33881+ * if @do_test is true.
33882+ */
33883+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
33884+ struct file *base_file, int do_test)
33885+{
33886+ int err;
33887+ ino_t ino;
33888+ aufs_bindex_t bend, bindex;
33889+ struct au_branch *shared_br, *b;
33890+ struct file *file;
33891+ struct super_block *tgt_sb;
33892+
33893+ shared_br = NULL;
33894+ bend = au_sbend(sb);
33895+ if (do_test) {
86dc4139 33896+ tgt_sb = au_br_sb(br);
1facf9fc 33897+ for (bindex = 0; bindex <= bend; bindex++) {
33898+ b = au_sbr(sb, bindex);
86dc4139 33899+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 33900+ shared_br = b;
33901+ break;
33902+ }
33903+ }
33904+ }
33905+
33906+ if (!shared_br || !shared_br->br_xino.xi_file) {
33907+ struct au_xino_lock_dir ldir;
33908+
33909+ au_xino_lock_dir(sb, base_file, &ldir);
33910+ /* mnt_want_write() is unnecessary here */
33911+ file = au_xino_create2(base_file, NULL);
33912+ au_xino_unlock_dir(&ldir);
33913+ err = PTR_ERR(file);
33914+ if (IS_ERR(file))
33915+ goto out;
33916+ br->br_xino.xi_file = file;
33917+ } else {
33918+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
33919+ get_file(br->br_xino.xi_file);
33920+ }
33921+
33922+ ino = AUFS_ROOT_INO;
33923+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
33924+ h_ino, ino);
b752ccd1
AM
33925+ if (unlikely(err)) {
33926+ fput(br->br_xino.xi_file);
33927+ br->br_xino.xi_file = NULL;
33928+ }
1facf9fc 33929+
4f0767ce 33930+out:
1facf9fc 33931+ return err;
33932+}
33933+
33934+/* ---------------------------------------------------------------------- */
33935+
33936+/* trucate a xino bitmap file */
33937+
33938+/* todo: slow */
33939+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
33940+{
33941+ int err, bit;
33942+ ssize_t sz;
33943+ unsigned long pindex;
33944+ loff_t pos, pend;
33945+ struct au_sbinfo *sbinfo;
33946+ au_readf_t func;
33947+ ino_t *ino;
33948+ unsigned long *p;
33949+
33950+ err = 0;
33951+ sbinfo = au_sbi(sb);
dece6358 33952+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 33953+ p = sbinfo->si_xib_buf;
33954+ func = sbinfo->si_xread;
c06a8ce3 33955+ pend = vfsub_f_size_read(file);
1facf9fc 33956+ pos = 0;
33957+ while (pos < pend) {
33958+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
33959+ err = sz;
33960+ if (unlikely(sz <= 0))
33961+ goto out;
33962+
33963+ err = 0;
33964+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
33965+ if (unlikely(*ino < AUFS_FIRST_INO))
33966+ continue;
33967+
33968+ xib_calc_bit(*ino, &pindex, &bit);
33969+ AuDebugOn(page_bits <= bit);
33970+ err = xib_pindex(sb, pindex);
33971+ if (!err)
33972+ set_bit(bit, p);
33973+ else
33974+ goto out;
33975+ }
33976+ }
33977+
4f0767ce 33978+out:
1facf9fc 33979+ return err;
33980+}
33981+
33982+static int xib_restore(struct super_block *sb)
33983+{
33984+ int err;
33985+ aufs_bindex_t bindex, bend;
33986+ void *page;
33987+
33988+ err = -ENOMEM;
33989+ page = (void *)__get_free_page(GFP_NOFS);
33990+ if (unlikely(!page))
33991+ goto out;
33992+
33993+ err = 0;
33994+ bend = au_sbend(sb);
33995+ for (bindex = 0; !err && bindex <= bend; bindex++)
33996+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
33997+ err = do_xib_restore
33998+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
33999+ else
34000+ AuDbg("b%d\n", bindex);
34001+ free_page((unsigned long)page);
34002+
4f0767ce 34003+out:
1facf9fc 34004+ return err;
34005+}
34006+
34007+int au_xib_trunc(struct super_block *sb)
34008+{
34009+ int err;
34010+ ssize_t sz;
34011+ loff_t pos;
34012+ struct au_xino_lock_dir ldir;
34013+ struct au_sbinfo *sbinfo;
34014+ unsigned long *p;
34015+ struct file *file;
34016+
dece6358
AM
34017+ SiMustWriteLock(sb);
34018+
1facf9fc 34019+ err = 0;
34020+ sbinfo = au_sbi(sb);
34021+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
34022+ goto out;
34023+
34024+ file = sbinfo->si_xib;
c06a8ce3 34025+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 34026+ goto out;
34027+
34028+ au_xino_lock_dir(sb, file, &ldir);
34029+ /* mnt_want_write() is unnecessary here */
34030+ file = au_xino_create2(sbinfo->si_xib, NULL);
34031+ au_xino_unlock_dir(&ldir);
34032+ err = PTR_ERR(file);
34033+ if (IS_ERR(file))
34034+ goto out;
34035+ fput(sbinfo->si_xib);
34036+ sbinfo->si_xib = file;
34037+
34038+ p = sbinfo->si_xib_buf;
34039+ memset(p, 0, PAGE_SIZE);
34040+ pos = 0;
34041+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
34042+ if (unlikely(sz != PAGE_SIZE)) {
34043+ err = sz;
34044+ AuIOErr("err %d\n", err);
34045+ if (sz >= 0)
34046+ err = -EIO;
34047+ goto out;
34048+ }
34049+
34050+ mutex_lock(&sbinfo->si_xib_mtx);
34051+ /* mnt_want_write() is unnecessary here */
34052+ err = xib_restore(sb);
34053+ mutex_unlock(&sbinfo->si_xib_mtx);
34054+
34055+out:
34056+ return err;
34057+}
34058+
34059+/* ---------------------------------------------------------------------- */
34060+
34061+/*
34062+ * xino mount option handlers
34063+ */
34064+static au_readf_t find_readf(struct file *h_file)
34065+{
34066+ const struct file_operations *fop = h_file->f_op;
34067+
523b37e3
AM
34068+ if (fop->read)
34069+ return fop->read;
34070+ if (fop->aio_read)
34071+ return do_sync_read;
076b876e
AM
34072+ if (fop->read_iter)
34073+ return new_sync_read;
1facf9fc 34074+ return ERR_PTR(-ENOSYS);
34075+}
34076+
34077+static au_writef_t find_writef(struct file *h_file)
34078+{
34079+ const struct file_operations *fop = h_file->f_op;
34080+
523b37e3
AM
34081+ if (fop->write)
34082+ return fop->write;
34083+ if (fop->aio_write)
34084+ return do_sync_write;
076b876e
AM
34085+ if (fop->write_iter)
34086+ return new_sync_write;
1facf9fc 34087+ return ERR_PTR(-ENOSYS);
34088+}
34089+
34090+/* xino bitmap */
34091+static void xino_clear_xib(struct super_block *sb)
34092+{
34093+ struct au_sbinfo *sbinfo;
34094+
dece6358
AM
34095+ SiMustWriteLock(sb);
34096+
1facf9fc 34097+ sbinfo = au_sbi(sb);
34098+ sbinfo->si_xread = NULL;
34099+ sbinfo->si_xwrite = NULL;
34100+ if (sbinfo->si_xib)
34101+ fput(sbinfo->si_xib);
34102+ sbinfo->si_xib = NULL;
34103+ free_page((unsigned long)sbinfo->si_xib_buf);
34104+ sbinfo->si_xib_buf = NULL;
34105+}
34106+
34107+static int au_xino_set_xib(struct super_block *sb, struct file *base)
34108+{
34109+ int err;
34110+ loff_t pos;
34111+ struct au_sbinfo *sbinfo;
34112+ struct file *file;
34113+
dece6358
AM
34114+ SiMustWriteLock(sb);
34115+
1facf9fc 34116+ sbinfo = au_sbi(sb);
34117+ file = au_xino_create2(base, sbinfo->si_xib);
34118+ err = PTR_ERR(file);
34119+ if (IS_ERR(file))
34120+ goto out;
34121+ if (sbinfo->si_xib)
34122+ fput(sbinfo->si_xib);
34123+ sbinfo->si_xib = file;
34124+ sbinfo->si_xread = find_readf(file);
34125+ sbinfo->si_xwrite = find_writef(file);
34126+
34127+ err = -ENOMEM;
34128+ if (!sbinfo->si_xib_buf)
34129+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
34130+ if (unlikely(!sbinfo->si_xib_buf))
34131+ goto out_unset;
34132+
34133+ sbinfo->si_xib_last_pindex = 0;
34134+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 34135+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 34136+ pos = 0;
34137+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
34138+ PAGE_SIZE, &pos);
34139+ if (unlikely(err != PAGE_SIZE))
34140+ goto out_free;
34141+ }
34142+ err = 0;
34143+ goto out; /* success */
34144+
4f0767ce 34145+out_free:
1facf9fc 34146+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
34147+ sbinfo->si_xib_buf = NULL;
34148+ if (err >= 0)
34149+ err = -EIO;
4f0767ce 34150+out_unset:
b752ccd1
AM
34151+ fput(sbinfo->si_xib);
34152+ sbinfo->si_xib = NULL;
34153+ sbinfo->si_xread = NULL;
34154+ sbinfo->si_xwrite = NULL;
4f0767ce 34155+out:
b752ccd1 34156+ return err;
1facf9fc 34157+}
34158+
b752ccd1
AM
34159+/* xino for each branch */
34160+static void xino_clear_br(struct super_block *sb)
34161+{
34162+ aufs_bindex_t bindex, bend;
34163+ struct au_branch *br;
1facf9fc 34164+
b752ccd1
AM
34165+ bend = au_sbend(sb);
34166+ for (bindex = 0; bindex <= bend; bindex++) {
34167+ br = au_sbr(sb, bindex);
34168+ if (!br || !br->br_xino.xi_file)
34169+ continue;
34170+
34171+ fput(br->br_xino.xi_file);
34172+ br->br_xino.xi_file = NULL;
34173+ }
34174+}
34175+
34176+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 34177+{
34178+ int err;
b752ccd1
AM
34179+ ino_t ino;
34180+ aufs_bindex_t bindex, bend, bshared;
34181+ struct {
34182+ struct file *old, *new;
34183+ } *fpair, *p;
34184+ struct au_branch *br;
34185+ struct inode *inode;
34186+ au_writef_t writef;
1facf9fc 34187+
b752ccd1
AM
34188+ SiMustWriteLock(sb);
34189+
34190+ err = -ENOMEM;
34191+ bend = au_sbend(sb);
34192+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
34193+ if (unlikely(!fpair))
1facf9fc 34194+ goto out;
34195+
b752ccd1
AM
34196+ inode = sb->s_root->d_inode;
34197+ ino = AUFS_ROOT_INO;
34198+ writef = au_sbi(sb)->si_xwrite;
34199+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
34200+ br = au_sbr(sb, bindex);
34201+ bshared = is_sb_shared(sb, bindex, bindex - 1);
34202+ if (bshared >= 0) {
34203+ /* shared xino */
34204+ *p = fpair[bshared];
34205+ get_file(p->new);
34206+ }
34207+
34208+ if (!p->new) {
34209+ /* new xino */
34210+ p->old = br->br_xino.xi_file;
34211+ p->new = au_xino_create2(base, br->br_xino.xi_file);
34212+ err = PTR_ERR(p->new);
34213+ if (IS_ERR(p->new)) {
34214+ p->new = NULL;
34215+ goto out_pair;
34216+ }
34217+ }
34218+
34219+ err = au_xino_do_write(writef, p->new,
34220+ au_h_iptr(inode, bindex)->i_ino, ino);
34221+ if (unlikely(err))
34222+ goto out_pair;
34223+ }
34224+
34225+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
34226+ br = au_sbr(sb, bindex);
34227+ if (br->br_xino.xi_file)
34228+ fput(br->br_xino.xi_file);
34229+ get_file(p->new);
34230+ br->br_xino.xi_file = p->new;
34231+ }
1facf9fc 34232+
4f0767ce 34233+out_pair:
b752ccd1
AM
34234+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
34235+ if (p->new)
34236+ fput(p->new);
34237+ else
34238+ break;
34239+ kfree(fpair);
4f0767ce 34240+out:
1facf9fc 34241+ return err;
34242+}
b752ccd1
AM
34243+
34244+void au_xino_clr(struct super_block *sb)
34245+{
34246+ struct au_sbinfo *sbinfo;
34247+
34248+ au_xigen_clr(sb);
34249+ xino_clear_xib(sb);
34250+ xino_clear_br(sb);
34251+ sbinfo = au_sbi(sb);
34252+ /* lvalue, do not call au_mntflags() */
34253+ au_opt_clr(sbinfo->si_mntflags, XINO);
34254+}
34255+
34256+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
34257+{
34258+ int err, skip;
34259+ struct dentry *parent, *cur_parent;
34260+ struct qstr *dname, *cur_name;
34261+ struct file *cur_xino;
34262+ struct inode *dir;
34263+ struct au_sbinfo *sbinfo;
34264+
34265+ SiMustWriteLock(sb);
34266+
34267+ err = 0;
34268+ sbinfo = au_sbi(sb);
2000de60 34269+ parent = dget_parent(xino->file->f_path.dentry);
b752ccd1
AM
34270+ if (remount) {
34271+ skip = 0;
2000de60 34272+ dname = &xino->file->f_path.dentry->d_name;
b752ccd1
AM
34273+ cur_xino = sbinfo->si_xib;
34274+ if (cur_xino) {
2000de60
JR
34275+ cur_parent = dget_parent(cur_xino->f_path.dentry);
34276+ cur_name = &cur_xino->f_path.dentry->d_name;
b752ccd1 34277+ skip = (cur_parent == parent
38d290e6 34278+ && au_qstreq(dname, cur_name));
b752ccd1
AM
34279+ dput(cur_parent);
34280+ }
34281+ if (skip)
34282+ goto out;
34283+ }
34284+
34285+ au_opt_set(sbinfo->si_mntflags, XINO);
34286+ dir = parent->d_inode;
34287+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
34288+ /* mnt_want_write() is unnecessary here */
34289+ err = au_xino_set_xib(sb, xino->file);
34290+ if (!err)
34291+ err = au_xigen_set(sb, xino->file);
34292+ if (!err)
34293+ err = au_xino_set_br(sb, xino->file);
34294+ mutex_unlock(&dir->i_mutex);
34295+ if (!err)
34296+ goto out; /* success */
34297+
34298+ /* reset all */
34299+ AuIOErr("failed creating xino(%d).\n", err);
c1595e42
JR
34300+ au_xigen_clr(sb);
34301+ xino_clear_xib(sb);
b752ccd1 34302+
4f0767ce 34303+out:
b752ccd1
AM
34304+ dput(parent);
34305+ return err;
34306+}
34307+
34308+/* ---------------------------------------------------------------------- */
34309+
34310+/*
34311+ * create a xinofile at the default place/path.
34312+ */
34313+struct file *au_xino_def(struct super_block *sb)
34314+{
34315+ struct file *file;
34316+ char *page, *p;
34317+ struct au_branch *br;
34318+ struct super_block *h_sb;
34319+ struct path path;
34320+ aufs_bindex_t bend, bindex, bwr;
34321+
34322+ br = NULL;
34323+ bend = au_sbend(sb);
34324+ bwr = -1;
34325+ for (bindex = 0; bindex <= bend; bindex++) {
34326+ br = au_sbr(sb, bindex);
34327+ if (au_br_writable(br->br_perm)
86dc4139 34328+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
34329+ bwr = bindex;
34330+ break;
34331+ }
34332+ }
34333+
7f207e10
AM
34334+ if (bwr >= 0) {
34335+ file = ERR_PTR(-ENOMEM);
537831f9 34336+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
34337+ if (unlikely(!page))
34338+ goto out;
86dc4139 34339+ path.mnt = au_br_mnt(br);
7f207e10
AM
34340+ path.dentry = au_h_dptr(sb->s_root, bwr);
34341+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
34342+ file = (void *)p;
34343+ if (!IS_ERR(p)) {
34344+ strcat(p, "/" AUFS_XINO_FNAME);
34345+ AuDbg("%s\n", p);
34346+ file = au_xino_create(sb, p, /*silent*/0);
34347+ if (!IS_ERR(file))
34348+ au_xino_brid_set(sb, br->br_id);
34349+ }
537831f9 34350+ free_page((unsigned long)page);
7f207e10
AM
34351+ } else {
34352+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
34353+ if (IS_ERR(file))
34354+ goto out;
2000de60 34355+ h_sb = file->f_path.dentry->d_sb;
7f207e10
AM
34356+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
34357+ pr_err("xino doesn't support %s(%s)\n",
34358+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
34359+ fput(file);
34360+ file = ERR_PTR(-EINVAL);
34361+ }
34362+ if (!IS_ERR(file))
34363+ au_xino_brid_set(sb, -1);
34364+ }
0c5527e5 34365+
7f207e10
AM
34366+out:
34367+ return file;
34368+}
34369+
34370+/* ---------------------------------------------------------------------- */
34371+
34372+int au_xino_path(struct seq_file *seq, struct file *file)
34373+{
34374+ int err;
34375+
34376+ err = au_seq_path(seq, &file->f_path);
34377+ if (unlikely(err < 0))
34378+ goto out;
34379+
34380+ err = 0;
34381+#define Deleted "\\040(deleted)"
34382+ seq->count -= sizeof(Deleted) - 1;
34383+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
34384+ sizeof(Deleted) - 1));
34385+#undef Deleted
34386+
34387+out:
34388+ return err;
34389+}
537831f9
AM
34390diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
34391--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
7e9cd9fe 34392+++ linux/include/uapi/linux/aufs_type.h 2015-04-13 15:10:20.790157026 +0200
c1595e42 34393@@ -0,0 +1,419 @@
7f207e10 34394+/*
2000de60 34395+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
34396+ *
34397+ * This program, aufs is free software; you can redistribute it and/or modify
34398+ * it under the terms of the GNU General Public License as published by
34399+ * the Free Software Foundation; either version 2 of the License, or
34400+ * (at your option) any later version.
34401+ *
34402+ * This program is distributed in the hope that it will be useful,
34403+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34404+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34405+ * GNU General Public License for more details.
34406+ *
34407+ * You should have received a copy of the GNU General Public License
523b37e3 34408+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
34409+ */
34410+
34411+#ifndef __AUFS_TYPE_H__
34412+#define __AUFS_TYPE_H__
34413+
f6c5ef8b
AM
34414+#define AUFS_NAME "aufs"
34415+
9dbd164d 34416+#ifdef __KERNEL__
f6c5ef8b
AM
34417+/*
34418+ * define it before including all other headers.
34419+ * sched.h may use pr_* macros before defining "current", so define the
34420+ * no-current version first, and re-define later.
34421+ */
34422+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
34423+#include <linux/sched.h>
34424+#undef pr_fmt
a2a7ad62
AM
34425+#define pr_fmt(fmt) \
34426+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
34427+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
34428+#else
34429+#include <stdint.h>
34430+#include <sys/types.h>
f6c5ef8b 34431+#endif /* __KERNEL__ */
7f207e10 34432+
f6c5ef8b
AM
34433+#include <linux/limits.h>
34434+
7e9cd9fe 34435+#define AUFS_VERSION "3.x-rcN-20150406"
7f207e10
AM
34436+
34437+/* todo? move this to linux-2.6.19/include/magic.h */
34438+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
34439+
34440+/* ---------------------------------------------------------------------- */
34441+
34442+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 34443+typedef int8_t aufs_bindex_t;
7f207e10
AM
34444+#define AUFS_BRANCH_MAX 127
34445+#else
9dbd164d 34446+typedef int16_t aufs_bindex_t;
7f207e10
AM
34447+#ifdef CONFIG_AUFS_BRANCH_MAX_511
34448+#define AUFS_BRANCH_MAX 511
34449+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
34450+#define AUFS_BRANCH_MAX 1023
34451+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
34452+#define AUFS_BRANCH_MAX 32767
34453+#endif
34454+#endif
34455+
34456+#ifdef __KERNEL__
34457+#ifndef AUFS_BRANCH_MAX
34458+#error unknown CONFIG_AUFS_BRANCH_MAX value
34459+#endif
34460+#endif /* __KERNEL__ */
34461+
34462+/* ---------------------------------------------------------------------- */
34463+
7f207e10
AM
34464+#define AUFS_FSTYPE AUFS_NAME
34465+
34466+#define AUFS_ROOT_INO 2
34467+#define AUFS_FIRST_INO 11
34468+
34469+#define AUFS_WH_PFX ".wh."
34470+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
34471+#define AUFS_WH_TMP_LEN 4
86dc4139 34472+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
34473+#define AUFS_MAX_NAMELEN (NAME_MAX \
34474+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
34475+ - 1 /* dot */\
34476+ - AUFS_WH_TMP_LEN) /* hex */
34477+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
34478+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
34479+#define AUFS_XINO_DEF_SEC 30 /* seconds */
34480+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
34481+#define AUFS_DIRWH_DEF 3
34482+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 34483+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
34484+#define AUFS_RDBLK_DEF 512 /* bytes */
34485+#define AUFS_RDHASH_DEF 32
34486+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
34487+#define AUFS_MFS_DEF_SEC 30 /* seconds */
34488+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 34489+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 34490+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
34491+
34492+/* pseudo-link maintenace under /proc */
34493+#define AUFS_PLINK_MAINT_NAME "plink_maint"
34494+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
34495+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
34496+
34497+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
34498+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
34499+
34500+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
34501+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
34502+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
34503+
34504+/* doubly whiteouted */
34505+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
34506+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
34507+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
34508+
1e00d052 34509+/* branch permissions and attributes */
7f207e10
AM
34510+#define AUFS_BRPERM_RW "rw"
34511+#define AUFS_BRPERM_RO "ro"
34512+#define AUFS_BRPERM_RR "rr"
076b876e
AM
34513+#define AUFS_BRATTR_COO_REG "coo_reg"
34514+#define AUFS_BRATTR_COO_ALL "coo_all"
34515+#define AUFS_BRATTR_FHSM "fhsm"
34516+#define AUFS_BRATTR_UNPIN "unpin"
c1595e42
JR
34517+#define AUFS_BRATTR_ICEX "icex"
34518+#define AUFS_BRATTR_ICEX_SEC "icexsec"
34519+#define AUFS_BRATTR_ICEX_SYS "icexsys"
34520+#define AUFS_BRATTR_ICEX_TR "icextr"
34521+#define AUFS_BRATTR_ICEX_USR "icexusr"
34522+#define AUFS_BRATTR_ICEX_OTH "icexoth"
1e00d052
AM
34523+#define AUFS_BRRATTR_WH "wh"
34524+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
34525+#define AUFS_BRWATTR_MOO "moo"
34526+
34527+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
34528+#define AuBrPerm_RO (1 << 1) /* readonly */
34529+#define AuBrPerm_RR (1 << 2) /* natively readonly */
34530+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
34531+
34532+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
34533+#define AuBrAttr_COO_ALL (1 << 4)
34534+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
34535+
34536+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
34537+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
c1595e42
JR
34538+ branch. meaningless since
34539+ linux-3.18-rc1 */
34540+
34541+/* ignore error in copying XATTR */
34542+#define AuBrAttr_ICEX_SEC (1 << 7)
34543+#define AuBrAttr_ICEX_SYS (1 << 8)
34544+#define AuBrAttr_ICEX_TR (1 << 9)
34545+#define AuBrAttr_ICEX_USR (1 << 10)
34546+#define AuBrAttr_ICEX_OTH (1 << 11)
34547+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
34548+ | AuBrAttr_ICEX_SYS \
34549+ | AuBrAttr_ICEX_TR \
34550+ | AuBrAttr_ICEX_USR \
34551+ | AuBrAttr_ICEX_OTH)
34552+
34553+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
076b876e
AM
34554+#define AuBrRAttr_Mask AuBrRAttr_WH
34555+
c1595e42
JR
34556+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
34557+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
076b876e
AM
34558+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
34559+
34560+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
34561+
c1595e42 34562+/* #warning test userspace */
076b876e
AM
34563+#ifdef __KERNEL__
34564+#ifndef CONFIG_AUFS_FHSM
34565+#undef AuBrAttr_FHSM
34566+#define AuBrAttr_FHSM 0
34567+#endif
c1595e42
JR
34568+#ifndef CONFIG_AUFS_XATTR
34569+#undef AuBrAttr_ICEX
34570+#define AuBrAttr_ICEX 0
34571+#undef AuBrAttr_ICEX_SEC
34572+#define AuBrAttr_ICEX_SEC 0
34573+#undef AuBrAttr_ICEX_SYS
34574+#define AuBrAttr_ICEX_SYS 0
34575+#undef AuBrAttr_ICEX_TR
34576+#define AuBrAttr_ICEX_TR 0
34577+#undef AuBrAttr_ICEX_USR
34578+#define AuBrAttr_ICEX_USR 0
34579+#undef AuBrAttr_ICEX_OTH
34580+#define AuBrAttr_ICEX_OTH 0
34581+#endif
076b876e
AM
34582+#endif
34583+
34584+/* the longest combination */
c1595e42
JR
34585+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
34586+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
34587+ "+" AUFS_BRATTR_COO_REG \
34588+ "+" AUFS_BRATTR_FHSM \
34589+ "+" AUFS_BRATTR_UNPIN \
7e9cd9fe
AM
34590+ "+" AUFS_BRATTR_ICEX_SEC \
34591+ "+" AUFS_BRATTR_ICEX_SYS \
34592+ "+" AUFS_BRATTR_ICEX_USR \
34593+ "+" AUFS_BRATTR_ICEX_OTH \
076b876e
AM
34594+ "+" AUFS_BRWATTR_NLWH)
34595+
34596+typedef struct {
34597+ char a[AuBrPermStrSz];
34598+} au_br_perm_str_t;
34599+
34600+static inline int au_br_writable(int brperm)
34601+{
34602+ return brperm & AuBrPerm_RW;
34603+}
34604+
34605+static inline int au_br_whable(int brperm)
34606+{
34607+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
34608+}
34609+
34610+static inline int au_br_wh_linkable(int brperm)
34611+{
34612+ return !(brperm & AuBrWAttr_NoLinkWH);
34613+}
34614+
34615+static inline int au_br_cmoo(int brperm)
34616+{
34617+ return brperm & AuBrAttr_CMOO_Mask;
34618+}
34619+
34620+static inline int au_br_fhsm(int brperm)
34621+{
34622+ return brperm & AuBrAttr_FHSM;
34623+}
7f207e10
AM
34624+
34625+/* ---------------------------------------------------------------------- */
34626+
34627+/* ioctl */
34628+enum {
34629+ /* readdir in userspace */
34630+ AuCtl_RDU,
34631+ AuCtl_RDU_INO,
34632+
076b876e
AM
34633+ AuCtl_WBR_FD, /* pathconf wrapper */
34634+ AuCtl_IBUSY, /* busy inode */
34635+ AuCtl_MVDOWN, /* move-down */
34636+ AuCtl_BR, /* info about branches */
34637+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
34638+};
34639+
34640+/* borrowed from linux/include/linux/kernel.h */
34641+#ifndef ALIGN
34642+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
34643+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
34644+#endif
34645+
34646+/* borrowed from linux/include/linux/compiler-gcc3.h */
34647+#ifndef __aligned
34648+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
34649+#endif
34650+
34651+#ifdef __KERNEL__
34652+#ifndef __packed
7f207e10
AM
34653+#define __packed __attribute__((packed))
34654+#endif
53392da6 34655+#endif
7f207e10
AM
34656+
34657+struct au_rdu_cookie {
9dbd164d
AM
34658+ uint64_t h_pos;
34659+ int16_t bindex;
34660+ uint8_t flags;
34661+ uint8_t pad;
34662+ uint32_t generation;
7f207e10
AM
34663+} __aligned(8);
34664+
34665+struct au_rdu_ent {
9dbd164d
AM
34666+ uint64_t ino;
34667+ int16_t bindex;
34668+ uint8_t type;
34669+ uint8_t nlen;
34670+ uint8_t wh;
7f207e10
AM
34671+ char name[0];
34672+} __aligned(8);
34673+
34674+static inline int au_rdu_len(int nlen)
34675+{
34676+ /* include the terminating NULL */
34677+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 34678+ sizeof(uint64_t));
7f207e10
AM
34679+}
34680+
34681+union au_rdu_ent_ul {
34682+ struct au_rdu_ent __user *e;
9dbd164d 34683+ uint64_t ul;
7f207e10
AM
34684+};
34685+
34686+enum {
34687+ AufsCtlRduV_SZ,
34688+ AufsCtlRduV_End
34689+};
34690+
34691+struct aufs_rdu {
34692+ /* input */
34693+ union {
9dbd164d
AM
34694+ uint64_t sz; /* AuCtl_RDU */
34695+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
34696+ };
34697+ union au_rdu_ent_ul ent;
9dbd164d 34698+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
34699+
34700+ /* input/output */
9dbd164d 34701+ uint32_t blk;
7f207e10
AM
34702+
34703+ /* output */
34704+ union au_rdu_ent_ul tail;
34705+ /* number of entries which were added in a single call */
9dbd164d
AM
34706+ uint64_t rent;
34707+ uint8_t full;
34708+ uint8_t shwh;
7f207e10
AM
34709+
34710+ struct au_rdu_cookie cookie;
34711+} __aligned(8);
34712+
1e00d052
AM
34713+/* ---------------------------------------------------------------------- */
34714+
34715+struct aufs_wbr_fd {
9dbd164d
AM
34716+ uint32_t oflags;
34717+ int16_t brid;
1e00d052
AM
34718+} __aligned(8);
34719+
34720+/* ---------------------------------------------------------------------- */
34721+
027c5e7a 34722+struct aufs_ibusy {
9dbd164d
AM
34723+ uint64_t ino, h_ino;
34724+ int16_t bindex;
027c5e7a
AM
34725+} __aligned(8);
34726+
1e00d052
AM
34727+/* ---------------------------------------------------------------------- */
34728+
392086de
AM
34729+/* error code for move-down */
34730+/* the actual message strings are implemented in aufs-util.git */
34731+enum {
34732+ EAU_MVDOWN_OPAQUE = 1,
34733+ EAU_MVDOWN_WHITEOUT,
34734+ EAU_MVDOWN_UPPER,
34735+ EAU_MVDOWN_BOTTOM,
34736+ EAU_MVDOWN_NOUPPER,
34737+ EAU_MVDOWN_NOLOWERBR,
34738+ EAU_Last
34739+};
34740+
c2b27bf2 34741+/* flags for move-down */
392086de
AM
34742+#define AUFS_MVDOWN_DMSG 1
34743+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
34744+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
34745+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
34746+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
34747+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
34748+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
34749+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
34750+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
34751+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
34752+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
34753+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
34754+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 34755+
076b876e 34756+/* index for move-down */
392086de
AM
34757+enum {
34758+ AUFS_MVDOWN_UPPER,
34759+ AUFS_MVDOWN_LOWER,
34760+ AUFS_MVDOWN_NARRAY
34761+};
34762+
076b876e
AM
34763+/*
34764+ * additional info of move-down
34765+ * number of free blocks and inodes.
34766+ * subset of struct kstatfs, but smaller and always 64bit.
34767+ */
34768+struct aufs_stfs {
34769+ uint64_t f_blocks;
34770+ uint64_t f_bavail;
34771+ uint64_t f_files;
34772+ uint64_t f_ffree;
34773+};
34774+
34775+struct aufs_stbr {
34776+ int16_t brid; /* optional input */
34777+ int16_t bindex; /* output */
34778+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
34779+} __aligned(8);
34780+
c2b27bf2 34781+struct aufs_mvdown {
076b876e
AM
34782+ uint32_t flags; /* input/output */
34783+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
34784+ int8_t au_errno; /* output */
34785+} __aligned(8);
34786+
34787+/* ---------------------------------------------------------------------- */
34788+
34789+union aufs_brinfo {
34790+ /* PATH_MAX may differ between kernel-space and user-space */
34791+ char _spacer[4096];
392086de 34792+ struct {
076b876e
AM
34793+ int16_t id;
34794+ int perm;
34795+ char path[0];
34796+ };
c2b27bf2
AM
34797+} __aligned(8);
34798+
34799+/* ---------------------------------------------------------------------- */
34800+
7f207e10
AM
34801+#define AuCtlType 'A'
34802+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
34803+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
34804+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
34805+ struct aufs_wbr_fd)
027c5e7a 34806+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
34807+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
34808+ struct aufs_mvdown)
076b876e
AM
34809+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
34810+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
34811+
34812+#endif /* __AUFS_TYPE_H__ */
7e9cd9fe 34813aufs3.x-rcN loopback patch
93a1a2a2
JR
34814
34815diff --git a/drivers/block/loop.c b/drivers/block/loop.c
7e9cd9fe 34816index a0da519..ffef6c0 100644
93a1a2a2
JR
34817--- a/drivers/block/loop.c
34818+++ b/drivers/block/loop.c
7e9cd9fe 34819@@ -471,7 +471,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
93a1a2a2
JR
34820 }
34821
34822 struct switch_request {
34823- struct file *file;
34824+ struct file *file, *virt_file;
34825 struct completion wait;
34826 };
34827
7e9cd9fe
AM
34828@@ -491,6 +491,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
34829 mapping = file->f_mapping;
34830 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
34831 lo->lo_backing_file = file;
34832+ lo->lo_backing_virt_file = p->virt_file;
34833 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
34834 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
34835 lo->old_gfp_mask = mapping_gfp_mask(mapping);
34836@@ -502,11 +503,13 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
93a1a2a2
JR
34837 * First it needs to flush existing IO, it does this by sending a magic
34838 * BIO down the pipe. The completion of this BIO does the actual switch.
34839 */
34840-static int loop_switch(struct loop_device *lo, struct file *file)
34841+static int loop_switch(struct loop_device *lo, struct file *file,
34842+ struct file *virt_file)
34843 {
34844 struct switch_request w;
7e9cd9fe 34845
93a1a2a2
JR
34846 w.file = file;
34847+ w.virt_file = virt_file;
93a1a2a2 34848
7e9cd9fe
AM
34849 /* freeze queue and wait for completion of scheduled requests */
34850 blk_mq_freeze_queue(lo->lo_queue);
34851@@ -525,7 +528,16 @@ static int loop_switch(struct loop_device *lo, struct file *file)
34852 */
34853 static int loop_flush(struct loop_device *lo)
34854 {
93a1a2a2
JR
34855- return loop_switch(lo, NULL);
34856+ return loop_switch(lo, NULL, NULL);
7e9cd9fe
AM
34857+}
34858+
93a1a2a2
JR
34859+static struct file *loop_real_file(struct file *file)
34860+{
34861+ struct file *f = NULL;
7e9cd9fe 34862+
2000de60
JR
34863+ if (file->f_path.dentry->d_sb->s_op->real_loop)
34864+ f = file->f_path.dentry->d_sb->s_op->real_loop(file);
93a1a2a2 34865+ return f;
7e9cd9fe 34866 }
93a1a2a2
JR
34867
34868 /*
7e9cd9fe 34869@@ -540,6 +552,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
93a1a2a2
JR
34870 unsigned int arg)
34871 {
34872 struct file *file, *old_file;
34873+ struct file *f, *virt_file = NULL, *old_virt_file;
34874 struct inode *inode;
34875 int error;
34876
7e9cd9fe 34877@@ -556,9 +569,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
93a1a2a2
JR
34878 file = fget(arg);
34879 if (!file)
34880 goto out;
34881+ f = loop_real_file(file);
34882+ if (f) {
34883+ virt_file = file;
34884+ file = f;
34885+ get_file(file);
34886+ }
34887
34888 inode = file->f_mapping->host;
34889 old_file = lo->lo_backing_file;
34890+ old_virt_file = lo->lo_backing_virt_file;
34891
34892 error = -EINVAL;
34893
7e9cd9fe 34894@@ -570,17 +590,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
93a1a2a2
JR
34895 goto out_putf;
34896
34897 /* and ... switch */
34898- error = loop_switch(lo, file);
34899+ error = loop_switch(lo, file, virt_file);
34900 if (error)
34901 goto out_putf;
34902
34903 fput(old_file);
34904+ if (old_virt_file)
34905+ fput(old_virt_file);
34906 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
34907 ioctl_by_bdev(bdev, BLKRRPART, 0);
34908 return 0;
34909
34910 out_putf:
34911 fput(file);
34912+ if (virt_file)
34913+ fput(virt_file);
34914 out:
34915 return error;
34916 }
7e9cd9fe 34917@@ -741,7 +765,7 @@ static void loop_config_discard(struct loop_device *lo)
93a1a2a2
JR
34918 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
34919 struct block_device *bdev, unsigned int arg)
34920 {
34921- struct file *file, *f;
34922+ struct file *file, *f, *virt_file = NULL;
34923 struct inode *inode;
34924 struct address_space *mapping;
34925 unsigned lo_blocksize;
7e9cd9fe 34926@@ -756,6 +780,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
93a1a2a2
JR
34927 file = fget(arg);
34928 if (!file)
34929 goto out;
34930+ f = loop_real_file(file);
34931+ if (f) {
34932+ virt_file = file;
34933+ file = f;
34934+ get_file(file);
34935+ }
34936
34937 error = -EBUSY;
34938 if (lo->lo_state != Lo_unbound)
7e9cd9fe 34939@@ -804,6 +834,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
93a1a2a2
JR
34940 lo->lo_device = bdev;
34941 lo->lo_flags = lo_flags;
34942 lo->lo_backing_file = file;
34943+ lo->lo_backing_virt_file = virt_file;
34944 lo->transfer = transfer_none;
34945 lo->ioctl = NULL;
34946 lo->lo_sizelimit = 0;
7e9cd9fe
AM
34947@@ -835,6 +866,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
34948
93a1a2a2
JR
34949 out_putf:
34950 fput(file);
34951+ if (virt_file)
34952+ fput(virt_file);
34953 out:
34954 /* This is safe: open() is still holding a reference. */
34955 module_put(THIS_MODULE);
7e9cd9fe 34956@@ -881,6 +914,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
93a1a2a2
JR
34957 static int loop_clr_fd(struct loop_device *lo)
34958 {
34959 struct file *filp = lo->lo_backing_file;
34960+ struct file *virt_filp = lo->lo_backing_virt_file;
34961 gfp_t gfp = lo->old_gfp_mask;
34962 struct block_device *bdev = lo->lo_device;
34963
7e9cd9fe 34964@@ -909,6 +943,7 @@ static int loop_clr_fd(struct loop_device *lo)
93a1a2a2 34965 spin_lock_irq(&lo->lo_lock);
7e9cd9fe 34966 lo->lo_state = Lo_rundown;
93a1a2a2
JR
34967 lo->lo_backing_file = NULL;
34968+ lo->lo_backing_virt_file = NULL;
34969 spin_unlock_irq(&lo->lo_lock);
34970
34971 loop_release_xfer(lo);
7e9cd9fe 34972@@ -950,6 +985,8 @@ static int loop_clr_fd(struct loop_device *lo)
93a1a2a2
JR
34973 * bd_mutex which is usually taken before lo_ctl_mutex.
34974 */
34975 fput(filp);
34976+ if (virt_filp)
34977+ fput(virt_filp);
34978 return 0;
34979 }
34980
34981diff --git a/drivers/block/loop.h b/drivers/block/loop.h
7e9cd9fe 34982index 301c27f..df84aa0 100644
93a1a2a2
JR
34983--- a/drivers/block/loop.h
34984+++ b/drivers/block/loop.h
7e9cd9fe 34985@@ -46,7 +46,7 @@ struct loop_device {
93a1a2a2
JR
34986 int (*ioctl)(struct loop_device *, int cmd,
34987 unsigned long arg);
34988
34989- struct file * lo_backing_file;
34990+ struct file * lo_backing_file, *lo_backing_virt_file;
34991 struct block_device *lo_device;
34992 unsigned lo_blocksize;
34993 void *key_data;
34994diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
2000de60 34995index 41c4c4a..6a68365 100644
93a1a2a2
JR
34996--- a/fs/aufs/f_op.c
34997+++ b/fs/aufs/f_op.c
2000de60 34998@@ -368,7 +368,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
93a1a2a2
JR
34999 err = -EINVAL;
35000 h_file = au_hf_top(file);
35001 get_file(h_file);
35002- if (au_test_loopback_kthread()) {
35003+ if (0 && au_test_loopback_kthread()) {
2000de60 35004 au_warn_loopback(h_file->f_path.dentry->d_sb);
93a1a2a2
JR
35005 if (file->f_mapping != h_file->f_mapping) {
35006 file->f_mapping = h_file->f_mapping;
35007diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
2000de60 35008index 69f7e96..7941063 100644
93a1a2a2
JR
35009--- a/fs/aufs/loop.c
35010+++ b/fs/aufs/loop.c
35011@@ -130,3 +130,19 @@ void au_loopback_fin(void)
35012 symbol_put(loop_backing_file);
35013 kfree(au_warn_loopback_array);
35014 }
35015+
35016+/* ---------------------------------------------------------------------- */
35017+
35018+/* support the loopback block device insude aufs */
35019+
35020+struct file *aufs_real_loop(struct file *file)
35021+{
35022+ struct file *f;
35023+
2000de60 35024+ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
93a1a2a2
JR
35025+ fi_read_lock(file);
35026+ f = au_hf_top(file);
35027+ fi_read_unlock(file);
35028+ AuDebugOn(!f);
35029+ return f;
35030+}
35031diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
2000de60 35032index 6d9864d..3322557 100644
93a1a2a2
JR
35033--- a/fs/aufs/loop.h
35034+++ b/fs/aufs/loop.h
35035@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
35036
35037 int au_loopback_init(void);
35038 void au_loopback_fin(void);
35039+
35040+struct file *aufs_real_loop(struct file *file);
35041 #else
35042+AuStub(struct file *, loop_backing_file, return NULL)
35043+
35044 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
35045 struct dentry *h_adding)
35046 AuStubInt0(au_test_loopback_kthread, void)
35047@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
35048
35049 AuStubInt0(au_loopback_init, void)
35050 AuStubVoid(au_loopback_fin, void)
35051+
35052+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
35053 #endif /* BLK_DEV_LOOP */
35054
35055 #endif /* __KERNEL__ */
35056diff --git a/fs/aufs/super.c b/fs/aufs/super.c
7e9cd9fe 35057index 98dc945..5da1392 100644
93a1a2a2
JR
35058--- a/fs/aufs/super.c
35059+++ b/fs/aufs/super.c
7e9cd9fe 35060@@ -810,7 +810,10 @@ static const struct super_operations aufs_sop = {
93a1a2a2
JR
35061 .statfs = aufs_statfs,
35062 .put_super = aufs_put_super,
35063 .sync_fs = aufs_sync_fs,
35064- .remount_fs = aufs_remount_fs
35065+ .remount_fs = aufs_remount_fs,
35066+#ifdef CONFIG_AUFS_BDEV_LOOP
35067+ .real_loop = aufs_real_loop
35068+#endif
35069 };
35070
35071 /* ---------------------------------------------------------------------- */
35072diff --git a/include/linux/fs.h b/include/linux/fs.h
7e9cd9fe 35073index b4d71b5..328c21d 100644
93a1a2a2
JR
35074--- a/include/linux/fs.h
35075+++ b/include/linux/fs.h
7e9cd9fe
AM
35076@@ -1655,6 +1655,10 @@ struct super_operations {
35077 struct shrink_control *);
35078 long (*free_cached_objects)(struct super_block *,
35079 struct shrink_control *);
93a1a2a2
JR
35080+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
35081+ /* and aufs */
35082+ struct file *(*real_loop)(struct file *);
35083+#endif
35084 };
35085
35086 /*
This page took 5.311699 seconds and 4 git commands to generate.