]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- fix vserver patch for 3.14.5
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
fb47a38f 1aufs3.14 kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
fb47a38f 4index 7385e54..d5c769c 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
fb47a38f 7@@ -208,6 +208,7 @@ source "fs/ufs/Kconfig"
7f207e10 8 source "fs/exofs/Kconfig"
1716fcea 9 source "fs/f2fs/Kconfig"
c06a8ce3 10 source "fs/efivarfs/Kconfig"
7f207e10
AM
11+source "fs/aufs/Kconfig"
12
13 endif # MISC_FILESYSTEMS
14
15diff --git a/fs/Makefile b/fs/Makefile
fb47a38f 16index 47ac07b..0c6a294 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
fb47a38f 19@@ -125,3 +125,4 @@ obj-y += exofs/ # Multiple modules
7f207e10 20 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 21 obj-$(CONFIG_PSTORE) += pstore/
c06a8ce3 22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
86dc4139 23+obj-$(CONFIG_AUFS_FS) += aufs/
c06a8ce3 24diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
fb47a38f 25index 3ce25b5..9faebdc 100644
c06a8ce3
AM
26--- a/include/uapi/linux/Kbuild
27+++ b/include/uapi/linux/Kbuild
28@@ -56,6 +56,7 @@ header-y += atmppp.h
29 header-y += atmsap.h
30 header-y += atmsvc.h
31 header-y += audit.h
32+header-y += aufs_type.h
33 header-y += auto_fs.h
34 header-y += auto_fs4.h
35 header-y += auxvec.h
fb47a38f 36aufs3.14 base patch
7f207e10 37
392086de 38diff --git a/drivers/block/loop.c b/drivers/block/loop.c
fb47a38f 39index 66e8c3b..ec278ac 100644
392086de
AM
40--- a/drivers/block/loop.c
41+++ b/drivers/block/loop.c
fb47a38f 42@@ -692,6 +692,24 @@ static inline int is_loop_device(struct file *file)
392086de
AM
43 return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
44 }
45
46+/*
47+ * for AUFS
48+ * no get/put for file.
49+ */
50+struct file *loop_backing_file(struct super_block *sb)
51+{
52+ struct file *ret;
53+ struct loop_device *l;
54+
55+ ret = NULL;
56+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
57+ l = sb->s_bdev->bd_disk->private_data;
58+ ret = l->lo_backing_file;
59+ }
60+ return ret;
61+}
62+EXPORT_SYMBOL(loop_backing_file);
63+
64 /* loop sysfs attributes */
65
66 static ssize_t loop_attr_show(struct device *dev, char *page,
0c3ec466 67diff --git a/fs/inode.c b/fs/inode.c
523b37e3 68index 4bcdad3..bc83168 100644
0c3ec466
AM
69--- a/fs/inode.c
70+++ b/fs/inode.c
523b37e3 71@@ -1497,7 +1497,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
0c3ec466
AM
72 * This does the actual work of updating an inodes time or version. Must have
73 * had called mnt_want_write() before calling this.
74 */
75-static int update_time(struct inode *inode, struct timespec *time, int flags)
76+int update_time(struct inode *inode, struct timespec *time, int flags)
77 {
78 if (inode->i_op->update_time)
79 return inode->i_op->update_time(inode, time, flags);
7f207e10 80diff --git a/fs/splice.c b/fs/splice.c
fb47a38f 81index 12028fa..f26cbaf 100644
7f207e10
AM
82--- a/fs/splice.c
83+++ b/fs/splice.c
fb47a38f 84@@ -1111,8 +1111,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
85 /*
86 * Attempt to initiate a splice from pipe to file.
87 */
88-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
89- loff_t *ppos, size_t len, unsigned int flags)
90+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
91+ loff_t *ppos, size_t len, unsigned int flags)
92 {
93 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
94 loff_t *, size_t, unsigned int);
fb47a38f 95@@ -1128,9 +1128,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
96 /*
97 * Attempt to initiate a splice from a file to a pipe.
98 */
99-static long do_splice_to(struct file *in, loff_t *ppos,
100- struct pipe_inode_info *pipe, size_t len,
101- unsigned int flags)
102+long do_splice_to(struct file *in, loff_t *ppos,
103+ struct pipe_inode_info *pipe, size_t len,
104+ unsigned int flags)
105 {
106 ssize_t (*splice_read)(struct file *, loff_t *,
107 struct pipe_inode_info *, size_t, unsigned int);
0c3ec466 108diff --git a/include/linux/fs.h b/include/linux/fs.h
fb47a38f 109index 23b2a35..f3f635c 100644
0c3ec466
AM
110--- a/include/linux/fs.h
111+++ b/include/linux/fs.h
fb47a38f 112@@ -2669,6 +2669,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
0c3ec466
AM
113 extern int inode_newsize_ok(const struct inode *, loff_t offset);
114 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
115
116+extern int update_time(struct inode *, struct timespec *, int);
117 extern int file_update_time(struct file *file);
118
119 extern int generic_show_options(struct seq_file *m, struct dentry *root);
1e00d052 120diff --git a/include/linux/splice.h b/include/linux/splice.h
fb47a38f 121index 0e43906..304169e 100644
1e00d052
AM
122--- a/include/linux/splice.h
123+++ b/include/linux/splice.h
fb47a38f 124@@ -93,4 +93,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
125 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
126
127 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
1e00d052
AM
128+
129+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
130+ loff_t *ppos, size_t len, unsigned int flags);
131+extern long do_splice_to(struct file *in, loff_t *ppos,
132+ struct pipe_inode_info *pipe, size_t len,
133+ unsigned int flags);
134 #endif
fb47a38f
JR
135aufs3.14 mmap patch
136
137diff --git a/fs/buffer.c b/fs/buffer.c
138index 27265a8..75427a6 100644
139--- a/fs/buffer.c
140+++ b/fs/buffer.c
141@@ -2448,7 +2448,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
142 * Update file times before taking page lock. We may end up failing the
143 * fault so this update may be superfluous but who really cares...
144 */
145- file_update_time(vma->vm_file);
146+ vma_file_update_time(vma);
147
148 ret = __block_page_mkwrite(vma, vmf, get_block);
149 sb_end_pagefault(sb);
150diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
151index d4a3574..e44a744 100644
152--- a/fs/proc/nommu.c
153+++ b/fs/proc/nommu.c
154@@ -45,7 +45,9 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
155 file = region->vm_file;
156
157 if (file) {
158- struct inode *inode = file_inode(region->vm_file);
159+ struct inode *inode;
160+ file = vmr_pr_or_file(region);
161+ inode = file_inode(file);
162 dev = inode->i_sb->s_dev;
163 ino = inode->i_ino;
164 }
165diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
166index fb52b54..1aca72e 100644
167--- a/fs/proc/task_mmu.c
168+++ b/fs/proc/task_mmu.c
169@@ -264,7 +264,9 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
170 const char *name = NULL;
171
172 if (file) {
173- struct inode *inode = file_inode(vma->vm_file);
174+ struct inode *inode;
175+ file = vma_pr_or_file(vma);
176+ inode = file_inode(file);
177 dev = inode->i_sb->s_dev;
178 ino = inode->i_ino;
179 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
180@@ -1407,6 +1409,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
181 seq_printf(m, "%08lx %s", vma->vm_start, buffer);
182
183 if (file) {
184+ file = vma_pr_or_file(vma);
185 seq_printf(m, " file=");
186 seq_path(m, &file->f_path, "\n\t= ");
187 } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
188diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
189index 678455d..ad0ce45 100644
190--- a/fs/proc/task_nommu.c
191+++ b/fs/proc/task_nommu.c
192@@ -141,7 +141,9 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
193 file = vma->vm_file;
194
195 if (file) {
196- struct inode *inode = file_inode(vma->vm_file);
197+ struct inode *inode;
198+ file = vma_pr_or_file(file);
199+ inode = file_inode(file);
200 dev = inode->i_sb->s_dev;
201 ino = inode->i_ino;
202 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
203diff --git a/include/linux/mm.h b/include/linux/mm.h
204index c1b7414..02036e0 100644
205--- a/include/linux/mm.h
206+++ b/include/linux/mm.h
207@@ -18,6 +18,9 @@
208 #include <linux/pfn.h>
209 #include <linux/bit_spinlock.h>
210 #include <linux/shrinker.h>
211+#include <linux/dcache.h>
212+#include <linux/file.h>
213+#include <linux/fs.h>
214
215 struct mempolicy;
216 struct anon_vma;
217@@ -1152,6 +1155,87 @@ static inline int fixup_user_fault(struct task_struct *tsk,
218 }
219 #endif
220
221+/*
222+ * Mainly for aufs which mmap(2) diffrent file and wants to print different path
223+ * in /proc/PID/maps.
224+ */
225+/* #define AUFS_DEBUG_MMAP */
226+static inline void aufs_trace(struct file *f, struct file *pr,
227+ const char func[], int line, const char func2[])
228+{
229+#ifdef AUFS_DEBUG_MMAP
230+ if (pr)
231+ pr_info("%s:%d: %s, %p\n", func, line, func2,
232+ f ? (char *)f->f_dentry->d_name.name : "(null)");
233+#endif
234+}
235+
236+static inline struct file *vmr_do_pr_or_file(struct vm_region *region,
237+ const char func[], int line)
238+{
239+ struct file *f = region->vm_file, *pr = region->vm_prfile;
240+ aufs_trace(f, pr, func, line, __func__);
241+ return (f && pr) ? pr : f;
242+}
243+
244+static inline void vmr_do_fput(struct vm_region *region,
245+ const char func[], int line)
246+{
247+ struct file *f = region->vm_file, *pr = region->vm_prfile;
248+ aufs_trace(f, pr, func, line, __func__);
249+ fput(f);
250+ if (f && pr)
251+ fput(pr);
252+}
253+
254+static inline void vma_do_file_update_time(struct vm_area_struct *vma,
255+ const char func[], int line)
256+{
257+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
258+ aufs_trace(f, pr, func, line, __func__);
259+ file_update_time(f);
260+ if (f && pr)
261+ file_update_time(pr);
262+}
263+
264+static inline struct file *vma_do_pr_or_file(struct vm_area_struct *vma,
265+ const char func[], int line)
266+{
267+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
268+ aufs_trace(f, pr, func, line, __func__);
269+ return (f && pr) ? pr : f;
270+}
271+
272+static inline void vma_do_get_file(struct vm_area_struct *vma,
273+ const char func[], int line)
274+{
275+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
276+ aufs_trace(f, pr, func, line, __func__);
277+ get_file(f);
278+ if (f && pr)
279+ get_file(pr);
280+}
281+
282+static inline void vma_do_fput(struct vm_area_struct *vma,
283+ const char func[], int line)
284+{
285+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
286+ aufs_trace(f, pr, func, line, __func__);
287+ fput(f);
288+ if (f && pr)
289+ fput(pr);
290+}
291+
292+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
293+ __LINE__)
294+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
295+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
296+ __LINE__)
297+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
298+ __LINE__)
299+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
300+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
301+
302 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
303 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
304 void *buf, int len, int write);
305diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
306index 290901a..c21588b 100644
307--- a/include/linux/mm_types.h
308+++ b/include/linux/mm_types.h
309@@ -231,6 +231,7 @@ struct vm_region {
310 unsigned long vm_top; /* region allocated to here */
311 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
312 struct file *vm_file; /* the backing file or NULL */
313+ struct file *vm_prfile; /* the virtual backing file or NULL */
314
315 int vm_usage; /* region usage count (access under nommu_region_sem) */
316 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
317@@ -299,6 +300,7 @@ struct vm_area_struct {
318 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
319 units, *not* PAGE_CACHE_SIZE */
320 struct file * vm_file; /* File we map to (can be NULL). */
321+ struct file *vm_prfile; /* shadow of vm_file */
322 void * vm_private_data; /* was vm_pte (shared mem) */
323
324 #ifndef CONFIG_MMU
325diff --git a/kernel/fork.c b/kernel/fork.c
326index a17621c..40d9f6a 100644
327--- a/kernel/fork.c
328+++ b/kernel/fork.c
329@@ -412,7 +412,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
330 struct inode *inode = file_inode(file);
331 struct address_space *mapping = file->f_mapping;
332
333- get_file(file);
334+ vma_get_file(tmp);
335 if (tmp->vm_flags & VM_DENYWRITE)
336 atomic_dec(&inode->i_writecount);
337 mutex_lock(&mapping->i_mmap_mutex);
338diff --git a/mm/filemap.c b/mm/filemap.c
339index 7a13f6a..f1805df 100644
340--- a/mm/filemap.c
341+++ b/mm/filemap.c
342@@ -1733,7 +1733,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
343 int ret = VM_FAULT_LOCKED;
344
345 sb_start_pagefault(inode->i_sb);
346- file_update_time(vma->vm_file);
347+ vma_file_update_time(vma);
348 lock_page(page);
349 if (page->mapping != inode->i_mapping) {
350 unlock_page(page);
351diff --git a/mm/fremap.c b/mm/fremap.c
352index 34feba6..d857364 100644
353--- a/mm/fremap.c
354+++ b/mm/fremap.c
355@@ -227,7 +227,9 @@ get_write_lock:
356 /* mmap_region may free vma; grab the info now */
357 vm_flags = vma->vm_flags;
358
359+ vma_get_file(vma);
360 addr = mmap_region(file, start, size, vm_flags, pgoff);
361+ vma_fput(vma);
362 fput(file);
363 if (IS_ERR_VALUE(addr)) {
364 err = addr;
365diff --git a/mm/madvise.c b/mm/madvise.c
366index 539eeb9..5e700b1 100644
367--- a/mm/madvise.c
368+++ b/mm/madvise.c
369@@ -327,12 +327,12 @@ static long madvise_remove(struct vm_area_struct *vma,
370 * vma's reference to the file) can go away as soon as we drop
371 * mmap_sem.
372 */
373- get_file(f);
374+ vma_get_file(vma);
375 up_read(&current->mm->mmap_sem);
376 error = do_fallocate(f,
377 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
378 offset, end - start);
379- fput(f);
380+ vma_fput(vma);
381 down_read(&current->mm->mmap_sem);
382 return error;
383 }
384diff --git a/mm/memory.c b/mm/memory.c
385index 22dfa61..81813d9 100644
386--- a/mm/memory.c
387+++ b/mm/memory.c
388@@ -2755,7 +2755,7 @@ reuse:
389 set_page_dirty_balance(dirty_page, page_mkwrite);
390 /* file_update_time outside page_lock */
391 if (vma->vm_file)
392- file_update_time(vma->vm_file);
393+ vma_file_update_time(vma);
394 }
395 put_page(dirty_page);
396 if (page_mkwrite) {
397@@ -3467,7 +3467,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
398
399 /* file_update_time outside page_lock */
400 if (vma->vm_file && !page_mkwrite)
401- file_update_time(vma->vm_file);
402+ vma_file_update_time(vma);
403 } else {
404 unlock_page(vmf.page);
405 if (anon)
406diff --git a/mm/mmap.c b/mm/mmap.c
407index 20ff0c3..f743033 100644
408--- a/mm/mmap.c
409+++ b/mm/mmap.c
410@@ -249,7 +249,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
411 if (vma->vm_ops && vma->vm_ops->close)
412 vma->vm_ops->close(vma);
413 if (vma->vm_file)
414- fput(vma->vm_file);
415+ vma_fput(vma);
416 mpol_put(vma_policy(vma));
417 kmem_cache_free(vm_area_cachep, vma);
418 return next;
419@@ -859,7 +859,7 @@ again: remove_next = 1 + (end > next->vm_end);
420 if (remove_next) {
421 if (file) {
422 uprobe_munmap(next, next->vm_start, next->vm_end);
423- fput(file);
424+ vma_fput(vma);
425 }
426 if (next->anon_vma)
427 anon_vma_merge(vma, next);
428@@ -1639,8 +1639,8 @@ out:
429 unmap_and_free_vma:
430 if (vm_flags & VM_DENYWRITE)
431 allow_write_access(file);
432+ vma_fput(vma);
433 vma->vm_file = NULL;
434- fput(file);
435
436 /* Undo any partial mapping done by a device driver. */
437 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
438@@ -2429,7 +2429,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
439 goto out_free_mpol;
440
441 if (new->vm_file)
442- get_file(new->vm_file);
443+ vma_get_file(new);
444
445 if (new->vm_ops && new->vm_ops->open)
446 new->vm_ops->open(new);
447@@ -2448,7 +2448,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
448 if (new->vm_ops && new->vm_ops->close)
449 new->vm_ops->close(new);
450 if (new->vm_file)
451- fput(new->vm_file);
452+ vma_fput(new);
453 unlink_anon_vmas(new);
454 out_free_mpol:
455 mpol_put(vma_policy(new));
456@@ -2837,7 +2837,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
457 if (anon_vma_clone(new_vma, vma))
458 goto out_free_mempol;
459 if (new_vma->vm_file)
460- get_file(new_vma->vm_file);
461+ vma_get_file(new_vma);
462 if (new_vma->vm_ops && new_vma->vm_ops->open)
463 new_vma->vm_ops->open(new_vma);
464 vma_link(mm, new_vma, prev, rb_link, rb_parent);
465diff --git a/mm/msync.c b/mm/msync.c
466index 632df45..02d770e 100644
467--- a/mm/msync.c
468+++ b/mm/msync.c
469@@ -80,10 +80,10 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
470 start = vma->vm_end;
471 if ((flags & MS_SYNC) && file &&
472 (vma->vm_flags & VM_SHARED)) {
473- get_file(file);
474+ vma_get_file(vma);
475 up_read(&mm->mmap_sem);
476 error = vfs_fsync(file, 0);
477- fput(file);
478+ vma_fput(vma);
479 if (error || start >= end)
480 goto out;
481 down_read(&mm->mmap_sem);
482diff --git a/mm/nommu.c b/mm/nommu.c
483index 8740213..ea7e336 100644
484--- a/mm/nommu.c
485+++ b/mm/nommu.c
486@@ -653,7 +653,7 @@ static void __put_nommu_region(struct vm_region *region)
487 up_write(&nommu_region_sem);
488
489 if (region->vm_file)
490- fput(region->vm_file);
491+ vmr_fput(region);
492
493 /* IO memory and memory shared directly out of the pagecache
494 * from ramfs/tmpfs mustn't be released here */
495@@ -811,7 +811,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
496 if (vma->vm_ops && vma->vm_ops->close)
497 vma->vm_ops->close(vma);
498 if (vma->vm_file)
499- fput(vma->vm_file);
500+ vma_fput(vma);
501 put_nommu_region(vma->vm_region);
502 kmem_cache_free(vm_area_cachep, vma);
503 }
504@@ -1377,7 +1377,7 @@ unsigned long do_mmap_pgoff(struct file *file,
505 goto error_just_free;
506 }
507 }
508- fput(region->vm_file);
509+ vmr_fput(region);
510 kmem_cache_free(vm_region_jar, region);
511 region = pregion;
512 result = start;
513@@ -1453,10 +1453,10 @@ error_just_free:
514 up_write(&nommu_region_sem);
515 error:
516 if (region->vm_file)
517- fput(region->vm_file);
518+ vmr_fput(region);
519 kmem_cache_free(vm_region_jar, region);
520 if (vma->vm_file)
521- fput(vma->vm_file);
522+ vma_fput(vma);
523 kmem_cache_free(vm_area_cachep, vma);
524 kleave(" = %d", ret);
525 return ret;
526aufs3.14 standalone patch
7f207e10 527
1e00d052 528diff --git a/fs/inode.c b/fs/inode.c
523b37e3 529index bc83168..6dd1207 100644
1e00d052
AM
530--- a/fs/inode.c
531+++ b/fs/inode.c
392086de 532@@ -57,6 +57,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
4b3da204 533 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
2cbb1c4b
JR
534
535 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
2cbb1c4b 536+EXPORT_SYMBOL(inode_sb_list_lock);
7f207e10
AM
537
538 /*
4b3da204 539 * Empty aops. Can be used for the cases where the user does not
523b37e3 540@@ -1513,6 +1514,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
0c3ec466
AM
541 mark_inode_dirty_sync(inode);
542 return 0;
543 }
544+EXPORT_SYMBOL(update_time);
545
546 /**
547 * touch_atime - update the access time
7f207e10 548diff --git a/fs/namespace.c b/fs/namespace.c
fb47a38f 549index 2ffc5a2..785a51f 100644
7f207e10
AM
550--- a/fs/namespace.c
551+++ b/fs/namespace.c
fb47a38f 552@@ -455,6 +455,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
553 mnt_dec_writers(real_mount(mnt));
554 preempt_enable();
555 }
556+EXPORT_SYMBOL_GPL(__mnt_drop_write);
557
558 /**
559 * mnt_drop_write - give up write access to a mount
fb47a38f 560@@ -1555,6 +1556,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
561 }
562 return 0;
563 }
564+EXPORT_SYMBOL(iterate_mounts);
565
7eafdf33 566 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
567 {
568diff --git a/fs/notify/group.c b/fs/notify/group.c
fb47a38f 569index ad19959..adf290d 100644
7f207e10
AM
570--- a/fs/notify/group.c
571+++ b/fs/notify/group.c
572@@ -22,6 +22,7 @@
573 #include <linux/srcu.h>
574 #include <linux/rculist.h>
575 #include <linux/wait.h>
576+#include <linux/module.h>
577
578 #include <linux/fsnotify_backend.h>
579 #include "fsnotify.h"
fb47a38f 580@@ -72,6 +73,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea
AM
581 {
582 atomic_inc(&group->refcnt);
583 }
584+EXPORT_SYMBOL(fsnotify_get_group);
585
586 /*
587 * Drop a reference to a group. Free it if it's through.
fb47a38f 588@@ -81,6 +83,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 589 if (atomic_dec_and_test(&group->refcnt))
1716fcea 590 fsnotify_final_destroy_group(group);
7f207e10
AM
591 }
592+EXPORT_SYMBOL(fsnotify_put_group);
593
594 /*
595 * Create a new fsnotify_group and hold a reference for the group returned.
fb47a38f 596@@ -109,6 +112,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
597
598 return group;
599 }
600+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
601
602 int fsnotify_fasync(int fd, struct file *file, int on)
603 {
7f207e10 604diff --git a/fs/notify/mark.c b/fs/notify/mark.c
392086de 605index 923fe4a..176b435 100644
7f207e10
AM
606--- a/fs/notify/mark.c
607+++ b/fs/notify/mark.c
392086de 608@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 609 mark->free_mark(mark);
1716fcea 610 }
7f207e10
AM
611 }
612+EXPORT_SYMBOL(fsnotify_put_mark);
613
614 /*
615 * Any time a mark is getting freed we end up here.
392086de 616@@ -191,6 +192,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea
AM
617 fsnotify_destroy_mark_locked(mark, group);
618 mutex_unlock(&group->mark_mutex);
7f207e10
AM
619 }
620+EXPORT_SYMBOL(fsnotify_destroy_mark);
621
622 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
623 {
392086de 624@@ -275,6 +277,7 @@ err:
7f207e10
AM
625
626 return ret;
627 }
628+EXPORT_SYMBOL(fsnotify_add_mark);
629
1716fcea
AM
630 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
631 struct inode *inode, struct vfsmount *mnt, int allow_dups)
392086de 632@@ -336,6 +339,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
633 atomic_set(&mark->refcnt, 1);
634 mark->free_mark = free_mark;
635 }
636+EXPORT_SYMBOL(fsnotify_init_mark);
637
638 static int fsnotify_mark_destroy(void *ignored)
639 {
640diff --git a/fs/open.c b/fs/open.c
fb47a38f 641index b9ed8b2..3ea66972 100644
7f207e10
AM
642--- a/fs/open.c
643+++ b/fs/open.c
523b37e3 644@@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
7f207e10
AM
645 mutex_unlock(&dentry->d_inode->i_mutex);
646 return ret;
647 }
648+EXPORT_SYMBOL(do_truncate);
649
1716fcea 650 long vfs_truncate(struct path *path, loff_t length)
7f207e10
AM
651 {
652diff --git a/fs/splice.c b/fs/splice.c
fb47a38f 653index f26cbaf..ac02366 100644
7f207e10
AM
654--- a/fs/splice.c
655+++ b/fs/splice.c
fb47a38f 656@@ -1124,6 +1124,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
657
658 return splice_write(pipe, out, ppos, len, flags);
7f207e10
AM
659 }
660+EXPORT_SYMBOL(do_splice_from);
661
662 /*
663 * Attempt to initiate a splice from a file to a pipe.
fb47a38f 664@@ -1150,6 +1151,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
665
666 return splice_read(in, ppos, pipe, len, flags);
667 }
668+EXPORT_SYMBOL(do_splice_to);
669
670 /**
671 * splice_direct_to_actor - splices data directly between two non-pipes
672diff --git a/security/commoncap.c b/security/commoncap.c
392086de 673index b9d613e..ba3b618 100644
7f207e10
AM
674--- a/security/commoncap.c
675+++ b/security/commoncap.c
1716fcea 676@@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 677 }
7f207e10
AM
678 return ret;
679 }
0c3ec466
AM
680+EXPORT_SYMBOL(cap_mmap_addr);
681
682 int cap_mmap_file(struct file *file, unsigned long reqprot,
683 unsigned long prot, unsigned long flags)
684 {
685 return 0;
686 }
687+EXPORT_SYMBOL(cap_mmap_file);
7f207e10 688diff --git a/security/device_cgroup.c b/security/device_cgroup.c
fb47a38f 689index d3b6d2c..5076912 100644
7f207e10
AM
690--- a/security/device_cgroup.c
691+++ b/security/device_cgroup.c
f6c5ef8b
AM
692@@ -7,6 +7,7 @@
693 #include <linux/device_cgroup.h>
694 #include <linux/cgroup.h>
695 #include <linux/ctype.h>
696+#include <linux/export.h>
697 #include <linux/list.h>
698 #include <linux/uaccess.h>
699 #include <linux/seq_file.h>
fb47a38f 700@@ -744,6 +745,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
701 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
702 access);
7f207e10 703 }
2cbb1c4b 704+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
705
706 int devcgroup_inode_mknod(int mode, dev_t dev)
707 {
708diff --git a/security/security.c b/security/security.c
fb47a38f 709index 919cad9..f9e9e17 100644
7f207e10
AM
710--- a/security/security.c
711+++ b/security/security.c
392086de 712@@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
713 return 0;
714 return security_ops->path_rmdir(dir, dentry);
715 }
716+EXPORT_SYMBOL(security_path_rmdir);
717
718 int security_path_unlink(struct path *dir, struct dentry *dentry)
719 {
392086de 720@@ -423,6 +424,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
721 return 0;
722 return security_ops->path_symlink(dir, dentry, old_name);
723 }
724+EXPORT_SYMBOL(security_path_symlink);
725
726 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
727 struct dentry *new_dentry)
392086de 728@@ -431,6 +433,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
729 return 0;
730 return security_ops->path_link(old_dentry, new_dir, new_dentry);
731 }
732+EXPORT_SYMBOL(security_path_link);
733
734 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
735 struct path *new_dir, struct dentry *new_dentry)
392086de 736@@ -449,6 +452,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
737 return 0;
738 return security_ops->path_truncate(path);
739 }
740+EXPORT_SYMBOL(security_path_truncate);
741
7eafdf33
AM
742 int security_path_chmod(struct path *path, umode_t mode)
743 {
392086de 744@@ -456,6 +460,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 745 return 0;
7eafdf33 746 return security_ops->path_chmod(path, mode);
7f207e10
AM
747 }
748+EXPORT_SYMBOL(security_path_chmod);
749
537831f9 750 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 751 {
392086de 752@@ -463,6 +468,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
753 return 0;
754 return security_ops->path_chown(path, uid, gid);
755 }
756+EXPORT_SYMBOL(security_path_chown);
757
758 int security_path_chroot(struct path *path)
759 {
392086de 760@@ -539,6 +545,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
761 return 0;
762 return security_ops->inode_readlink(dentry);
763 }
764+EXPORT_SYMBOL(security_inode_readlink);
765
766 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
767 {
392086de 768@@ -553,6 +560,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 769 return 0;
1e00d052 770 return security_ops->inode_permission(inode, mask);
7f207e10
AM
771 }
772+EXPORT_SYMBOL(security_inode_permission);
773
1e00d052 774 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 775 {
392086de 776@@ -675,6 +683,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
777
778 return fsnotify_perm(file, mask);
779 }
780+EXPORT_SYMBOL(security_file_permission);
781
782 int security_file_alloc(struct file *file)
783 {
392086de 784@@ -735,6 +744,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
785 return ret;
786 return ima_file_mmap(file, prot);
787 }
0c3ec466 788+EXPORT_SYMBOL(security_mmap_file);
7f207e10 789
0c3ec466
AM
790 int security_mmap_addr(unsigned long addr)
791 {
7f207e10
AM
792diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
793--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
fb47a38f 794+++ linux/Documentation/ABI/testing/debugfs-aufs 2014-04-24 22:11:10.471931783 +0200
86dc4139 795@@ -0,0 +1,50 @@
7f207e10
AM
796+What: /debug/aufs/si_<id>/
797+Date: March 2009
f6b6e03d 798+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
799+Description:
800+ Under /debug/aufs, a directory named si_<id> is created
801+ per aufs mount, where <id> is a unique id generated
802+ internally.
1facf9fc 803+
86dc4139
AM
804+What: /debug/aufs/si_<id>/plink
805+Date: Apr 2013
f6b6e03d 806+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
807+Description:
808+ It has three lines and shows the information about the
809+ pseudo-link. The first line is a single number
810+ representing a number of buckets. The second line is a
811+ number of pseudo-links per buckets (separated by a
812+ blank). The last line is a single number representing a
813+ total number of psedo-links.
814+ When the aufs mount option 'noplink' is specified, it
815+ will show "1\n0\n0\n".
816+
7f207e10
AM
817+What: /debug/aufs/si_<id>/xib
818+Date: March 2009
f6b6e03d 819+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
820+Description:
821+ It shows the consumed blocks by xib (External Inode Number
822+ Bitmap), its block size and file size.
823+ When the aufs mount option 'noxino' is specified, it
824+ will be empty. About XINO files, see the aufs manual.
825+
826+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
827+Date: March 2009
f6b6e03d 828+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
829+Description:
830+ It shows the consumed blocks by xino (External Inode Number
831+ Translation Table), its link count, block size and file
832+ size.
833+ When the aufs mount option 'noxino' is specified, it
834+ will be empty. About XINO files, see the aufs manual.
835+
836+What: /debug/aufs/si_<id>/xigen
837+Date: March 2009
f6b6e03d 838+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
839+Description:
840+ It shows the consumed blocks by xigen (External Inode
841+ Generation Table), its block size and file size.
842+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
843+ be created.
844+ When the aufs mount option 'noxino' is specified, it
845+ will be empty. About XINO files, see the aufs manual.
846diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
847--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
fb47a38f 848+++ linux/Documentation/ABI/testing/sysfs-aufs 2014-04-24 22:11:10.471931783 +0200
392086de 849@@ -0,0 +1,31 @@
7f207e10
AM
850+What: /sys/fs/aufs/si_<id>/
851+Date: March 2009
f6b6e03d 852+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
853+Description:
854+ Under /sys/fs/aufs, a directory named si_<id> is created
855+ per aufs mount, where <id> is a unique id generated
856+ internally.
857+
858+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
859+Date: March 2009
f6b6e03d 860+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
861+Description:
862+ It shows the abolute path of a member directory (which
863+ is called branch) in aufs, and its permission.
864+
392086de
AM
865+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
866+Date: July 2013
f6b6e03d 867+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
868+Description:
869+ It shows the id of a member directory (which is called
870+ branch) in aufs.
871+
7f207e10
AM
872+What: /sys/fs/aufs/si_<id>/xi_path
873+Date: March 2009
f6b6e03d 874+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
875+Description:
876+ It shows the abolute path of XINO (External Inode Number
877+ Bitmap, Translation Table and Generation Table) file
878+ even if it is the default path.
879+ When the aufs mount option 'noxino' is specified, it
880+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
881diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
882--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 883+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 884@@ -0,0 +1,161 @@
53392da6 885+
523b37e3 886+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
887+#
888+# This program is free software; you can redistribute it and/or modify
889+# it under the terms of the GNU General Public License as published by
890+# the Free Software Foundation; either version 2 of the License, or
891+# (at your option) any later version.
892+#
893+# This program is distributed in the hope that it will be useful,
894+# but WITHOUT ANY WARRANTY; without even the implied warranty of
895+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
896+# GNU General Public License for more details.
897+#
898+# You should have received a copy of the GNU General Public License
523b37e3 899+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
900+
901+Introduction
902+----------------------------------------
903+
904+aufs [ei ju: ef es] | [a u f s]
905+1. abbrev. for "advanced multi-layered unification filesystem".
906+2. abbrev. for "another unionfs".
907+3. abbrev. for "auf das" in German which means "on the" in English.
908+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
909+ But "Filesystem aufs Filesystem" is hard to understand.
910+
911+AUFS is a filesystem with features:
912+- multi layered stackable unification filesystem, the member directory
913+ is called as a branch.
914+- branch permission and attribute, 'readonly', 'real-readonly',
915+ 'readwrite', 'whiteout-able', 'link-able whiteout' and their
916+ combination.
917+- internal "file copy-on-write".
918+- logical deletion, whiteout.
919+- dynamic branch manipulation, adding, deleting and changing permission.
920+- allow bypassing aufs, user's direct branch access.
921+- external inode number translation table and bitmap which maintains the
922+ persistent aufs inode number.
923+- seekable directory, including NFS readdir.
924+- file mapping, mmap and sharing pages.
925+- pseudo-link, hardlink over branches.
926+- loopback mounted filesystem as a branch.
927+- several policies to select one among multiple writable branches.
928+- revert a single systemcall when an error occurs in aufs.
929+- and more...
930+
931+
932+Multi Layered Stackable Unification Filesystem
933+----------------------------------------------------------------------
934+Most people already knows what it is.
935+It is a filesystem which unifies several directories and provides a
936+merged single directory. When users access a file, the access will be
937+passed/re-directed/converted (sorry, I am not sure which English word is
938+correct) to the real file on the member filesystem. The member
939+filesystem is called 'lower filesystem' or 'branch' and has a mode
940+'readonly' and 'readwrite.' And the deletion for a file on the lower
941+readonly branch is handled by creating 'whiteout' on the upper writable
942+branch.
943+
944+On LKML, there have been discussions about UnionMount (Jan Blunck,
945+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
946+different approaches to implement the merged-view.
947+The former tries putting it into VFS, and the latter implements as a
948+separate filesystem.
949+(If I misunderstand about these implementations, please let me know and
950+I shall correct it. Because it is a long time ago when I read their
951+source files last time).
952+
953+UnionMount's approach will be able to small, but may be hard to share
954+branches between several UnionMount since the whiteout in it is
955+implemented in the inode on branch filesystem and always
956+shared. According to Bharata's post, readdir does not seems to be
957+finished yet.
958+There are several missing features known in this implementations such as
959+- for users, the inode number may change silently. eg. copy-up.
960+- link(2) may break by copy-up.
961+- read(2) may get an obsoleted filedata (fstat(2) too).
962+- fcntl(F_SETLK) may be broken by copy-up.
963+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
964+ open(O_RDWR).
965+
966+Unionfs has a longer history. When I started implementing a stacking filesystem
967+(Aug 2005), it already existed. It has virtual super_block, inode,
968+dentry and file objects and they have an array pointing lower same kind
969+objects. After contributing many patches for Unionfs, I re-started my
970+project AUFS (Jun 2006).
971+
972+In AUFS, the structure of filesystem resembles to Unionfs, but I
973+implemented my own ideas, approaches and enhancements and it became
974+totally different one.
975+
976+Comparing DM snapshot and fs based implementation
977+- the number of bytes to be copied between devices is much smaller.
978+- the type of filesystem must be one and only.
979+- the fs must be writable, no readonly fs, even for the lower original
980+ device. so the compression fs will not be usable. but if we use
981+ loopback mount, we may address this issue.
982+ for instance,
983+ mount /cdrom/squashfs.img /sq
984+ losetup /sq/ext2.img
985+ losetup /somewhere/cow
986+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
987+- it will be difficult (or needs more operations) to extract the
988+ difference between the original device and COW.
989+- DM snapshot-merge may help a lot when users try merging. in the
990+ fs-layer union, users will use rsync(1).
991+
992+
993+Several characters/aspects of aufs
994+----------------------------------------------------------------------
995+
996+Aufs has several characters or aspects.
997+1. a filesystem, callee of VFS helper
998+2. sub-VFS, caller of VFS helper for branches
999+3. a virtual filesystem which maintains persistent inode number
1000+4. reader/writer of files on branches such like an application
1001+
1002+1. Callee of VFS Helper
1003+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1004+unlink(2) from an application reaches sys_unlink() kernel function and
1005+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1006+calls filesystem specific unlink operation. Actually aufs implements the
1007+unlink operation but it behaves like a redirector.
1008+
1009+2. Caller of VFS Helper for Branches
1010+aufs_unlink() passes the unlink request to the branch filesystem as if
1011+it were called from VFS. So the called unlink operation of the branch
1012+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1013+every necessary pre/post operation for the branch filesystem.
1014+- acquire the lock for the parent dir on a branch
1015+- lookup in a branch
1016+- revalidate dentry on a branch
1017+- mnt_want_write() for a branch
1018+- vfs_unlink() for a branch
1019+- mnt_drop_write() for a branch
1020+- release the lock on a branch
1021+
1022+3. Persistent Inode Number
1023+One of the most important issue for a filesystem is to maintain inode
1024+numbers. This is particularly important to support exporting a
1025+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1026+backend block device for its own. But some storage is necessary to
1027+maintain inode number. It may be a large space and may not suit to keep
1028+in memory. Aufs rents some space from its first writable branch
1029+filesystem (by default) and creates file(s) on it. These files are
1030+created by aufs internally and removed soon (currently) keeping opened.
1031+Note: Because these files are removed, they are totally gone after
1032+ unmounting aufs. It means the inode numbers are not persistent
1033+ across unmount or reboot. I have a plan to make them really
1034+ persistent which will be important for aufs on NFS server.
1035+
1036+4. Read/Write Files Internally (copy-on-write)
1037+Because a branch can be readonly, when you write a file on it, aufs will
1038+"copy-up" it to the upper writable branch internally. And then write the
1039+originally requested thing to the file. Generally kernel doesn't
1040+open/read/write file actively. In aufs, even a single write may cause a
1041+internal "file copy". This behaviour is very similar to cp(1) command.
1042+
1043+Some people may think it is better to pass such work to user space
1044+helper, instead of doing in kernel space. Actually I am still thinking
1045+about it. But currently I have implemented it in kernel space.
1046diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1047--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1048+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1049@@ -0,0 +1,242 @@
53392da6 1050+
523b37e3 1051+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1052+#
1053+# This program is free software; you can redistribute it and/or modify
1054+# it under the terms of the GNU General Public License as published by
1055+# the Free Software Foundation; either version 2 of the License, or
1056+# (at your option) any later version.
1057+#
1058+# This program is distributed in the hope that it will be useful,
1059+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1060+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1061+# GNU General Public License for more details.
1062+#
1063+# You should have received a copy of the GNU General Public License
523b37e3 1064+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1065+
1066+Basic Aufs Internal Structure
1067+
1068+Superblock/Inode/Dentry/File Objects
1069+----------------------------------------------------------------------
1070+As like an ordinary filesystem, aufs has its own
1071+superblock/inode/dentry/file objects. All these objects have a
1072+dynamically allocated array and store the same kind of pointers to the
1073+lower filesystem, branch.
1074+For example, when you build a union with one readwrite branch and one
1075+readonly, mounted /au, /rw and /ro respectively.
1076+- /au = /rw + /ro
1077+- /ro/fileA exists but /rw/fileA
1078+
1079+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1080+pointers are stored in a aufs dentry. The array in aufs dentry will be,
1081+- [0] = NULL
1082+- [1] = /ro/fileA
1083+
1084+This style of an array is essentially same to the aufs
1085+superblock/inode/dentry/file objects.
1086+
1087+Because aufs supports manipulating branches, ie. add/delete/change
1088+dynamically, these objects has its own generation. When branches are
1089+changed, the generation in aufs superblock is incremented. And a
1090+generation in other object are compared when it is accessed.
1091+When a generation in other objects are obsoleted, aufs refreshes the
1092+internal array.
1093+
1094+
1095+Superblock
1096+----------------------------------------------------------------------
1097+Additionally aufs superblock has some data for policies to select one
1098+among multiple writable branches, XIB files, pseudo-links and kobject.
1099+See below in detail.
1100+About the policies which supports copy-down a directory, see policy.txt
1101+too.
1102+
1103+
1104+Branch and XINO(External Inode Number Translation Table)
1105+----------------------------------------------------------------------
1106+Every branch has its own xino (external inode number translation table)
1107+file. The xino file is created and unlinked by aufs internally. When two
1108+members of a union exist on the same filesystem, they share the single
1109+xino file.
1110+The struct of a xino file is simple, just a sequence of aufs inode
1111+numbers which is indexed by the lower inode number.
1112+In the above sample, assume the inode number of /ro/fileA is i111 and
1113+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1114+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1115+
1116+When the inode numbers are not contiguous, the xino file will be sparse
1117+which has a hole in it and doesn't consume as much disk space as it
1118+might appear. If your branch filesystem consumes disk space for such
1119+holes, then you should specify 'xino=' option at mounting aufs.
1120+
1121+Also a writable branch has three kinds of "whiteout bases". All these
1122+are existed when the branch is joined to aufs and the names are
1123+whiteout-ed doubly, so that users will never see their names in aufs
1124+hierarchy.
1125+1. a regular file which will be linked to all whiteouts.
1126+2. a directory to store a pseudo-link.
1127+3. a directory to store an "orphan-ed" file temporary.
1128+
1129+1. Whiteout Base
1130+ When you remove a file on a readonly branch, aufs handles it as a
1131+ logical deletion and creates a whiteout on the upper writable branch
1132+ as a hardlink of this file in order not to consume inode on the
1133+ writable branch.
1134+2. Pseudo-link Dir
1135+ See below, Pseudo-link.
1136+3. Step-Parent Dir
1137+ When "fileC" exists on the lower readonly branch only and it is
1138+ opened and removed with its parent dir, and then user writes
1139+ something into it, then aufs copies-up fileC to this
1140+ directory. Because there is no other dir to store fileC. After
1141+ creating a file under this dir, the file is unlinked.
1142+
1143+Because aufs supports manipulating branches, ie. add/delete/change
1144+dynamically, a branch has its own id. When the branch order changes, aufs
1145+finds the new index by searching the branch id.
1146+
1147+
1148+Pseudo-link
1149+----------------------------------------------------------------------
1150+Assume "fileA" exists on the lower readonly branch only and it is
1151+hardlinked to "fileB" on the branch. When you write something to fileA,
1152+aufs copies-up it to the upper writable branch. Additionally aufs
1153+creates a hardlink under the Pseudo-link Directory of the writable
1154+branch. The inode of a pseudo-link is kept in aufs super_block as a
1155+simple list. If fileB is read after unlinking fileA, aufs returns
1156+filedata from the pseudo-link instead of the lower readonly
1157+branch. Because the pseudo-link is based upon the inode, to keep the
1158+inode number by xino (see above) is important.
1159+
1160+All the hardlinks under the Pseudo-link Directory of the writable branch
1161+should be restored in a proper location later. Aufs provides a utility
1162+to do this. The userspace helpers executed at remounting and unmounting
1163+aufs by default.
1164+During this utility is running, it puts aufs into the pseudo-link
1165+maintenance mode. In this mode, only the process which began the
1166+maintenance mode (and its child processes) is allowed to operate in
1167+aufs. Some other processes which are not related to the pseudo-link will
1168+be allowed to run too, but the rest have to return an error or wait
1169+until the maintenance mode ends. If a process already acquires an inode
1170+mutex (in VFS), it has to return an error.
1171+
1172+
1173+XIB(external inode number bitmap)
1174+----------------------------------------------------------------------
1175+Addition to the xino file per a branch, aufs has an external inode number
1176+bitmap in a superblock object. It is also a file such like a xino file.
1177+It is a simple bitmap to mark whether the aufs inode number is in-use or
1178+not.
1179+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1180+
1181+Aufs implements a feature to truncate/refresh both of xino and xib to
1182+reduce the number of consumed disk blocks for these files.
1183+
1184+
1185+Virtual or Vertical Dir, and Readdir in Userspace
1186+----------------------------------------------------------------------
1187+In order to support multiple layers (branches), aufs readdir operation
1188+constructs a virtual dir block on memory. For readdir, aufs calls
1189+vfs_readdir() internally for each dir on branches, merges their entries
1190+with eliminating the whiteout-ed ones, and sets it to file (dir)
1191+object. So the file object has its entry list until it is closed. The
1192+entry list will be updated when the file position is zero and becomes
1193+old. This decision is made in aufs automatically.
1194+
1195+The dynamically allocated memory block for the name of entries has a
1196+unit of 512 bytes (by default) and stores the names contiguously (no
1197+padding). Another block for each entry is handled by kmem_cache too.
1198+During building dir blocks, aufs creates hash list and judging whether
1199+the entry is whiteouted by its upper branch or already listed.
1200+The merged result is cached in the corresponding inode object and
1201+maintained by a customizable life-time option.
1202+
1203+Some people may call it can be a security hole or invite DoS attack
1204+since the opened and once readdir-ed dir (file object) holds its entry
1205+list and becomes a pressure for system memory. But I'd say it is similar
1206+to files under /proc or /sys. The virtual files in them also holds a
1207+memory page (generally) while they are opened. When an idea to reduce
1208+memory for them is introduced, it will be applied to aufs too.
1209+For those who really hate this situation, I've developed readdir(3)
1210+library which operates this merging in userspace. You just need to set
1211+LD_PRELOAD environment variable, and aufs will not consume no memory in
1212+kernel space for readdir(3).
1213+
1214+
1215+Workqueue
1216+----------------------------------------------------------------------
1217+Aufs sometimes requires privilege access to a branch. For instance,
1218+in copy-up/down operation. When a user process is going to make changes
1219+to a file which exists in the lower readonly branch only, and the mode
1220+of one of ancestor directories may not be writable by a user
1221+process. Here aufs copy-up the file with its ancestors and they may
1222+require privilege to set its owner/group/mode/etc.
1223+This is a typical case of a application character of aufs (see
1224+Introduction).
1225+
1226+Aufs uses workqueue synchronously for this case. It creates its own
1227+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1228+passes the request to call mkdir or write (for example), and wait for
1229+its completion. This approach solves a problem of a signal handler
1230+simply.
1231+If aufs didn't adopt the workqueue and changed the privilege of the
1232+process, and if the mkdir/write call arises SIGXFSZ or other signal,
1233+then the user process might gain a privilege or the generated core file
1234+was owned by a superuser.
1235+
1236+Also aufs uses the system global workqueue ("events" kernel thread) too
1237+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1238+whiteout base and etc. This is unrelated to a privilege.
1239+Most of aufs operation tries acquiring a rw_semaphore for aufs
1240+superblock at the beginning, at the same time waits for the completion
1241+of all queued asynchronous tasks.
1242+
1243+
1244+Whiteout
1245+----------------------------------------------------------------------
1246+The whiteout in aufs is very similar to Unionfs's. That is represented
1247+by its filename. UnionMount takes an approach of a file mode, but I am
1248+afraid several utilities (find(1) or something) will have to support it.
1249+
1250+Basically the whiteout represents "logical deletion" which stops aufs to
1251+lookup further, but also it represents "dir is opaque" which also stop
1252+lookup.
1253+
1254+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1255+In order to make several functions in a single systemcall to be
1256+revertible, aufs adopts an approach to rename a directory to a temporary
1257+unique whiteouted name.
1258+For example, in rename(2) dir where the target dir already existed, aufs
1259+renames the target dir to a temporary unique whiteouted name before the
1260+actual rename on a branch and then handles other actions (make it opaque,
1261+update the attributes, etc). If an error happens in these actions, aufs
1262+simply renames the whiteouted name back and returns an error. If all are
1263+succeeded, aufs registers a function to remove the whiteouted unique
1264+temporary name completely and asynchronously to the system global
1265+workqueue.
1266+
1267+
1268+Copy-up
1269+----------------------------------------------------------------------
1270+It is a well-known feature or concept.
1271+When user modifies a file on a readonly branch, aufs operate "copy-up"
1272+internally and makes change to the new file on the upper writable branch.
1273+When the trigger systemcall does not update the timestamps of the parent
1274+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1275+
1276+
1277+Move-down (aufs3.9 and later)
1278+----------------------------------------------------------------------
1279+"Copy-up" is one of the essential feature in aufs. It copies a file from
1280+the lower readonly branch to the upper writable branch when a user
1281+changes something about the file.
1282+"Move-down" is an opposite action of copy-up. Basically this action is
1283+ran manually instead of automatically and internally.
1284+
1285+Sometimes users want to move-down a file from the upper writable branch
1286+to the lower readonly or writable branch. For instance,
1287+- the free space of the upper writable branch is going to run out.
1288+- create a new intermediate branch between the upper and lower branch.
1289+- etc.
1290+
1291+For this purpose, use "aumvdown" command in aufs-util.git.
53392da6
AM
1292diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1293--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1294+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1295@@ -0,0 +1,105 @@
53392da6 1296+
523b37e3 1297+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1298+#
1299+# This program is free software; you can redistribute it and/or modify
1300+# it under the terms of the GNU General Public License as published by
1301+# the Free Software Foundation; either version 2 of the License, or
1302+# (at your option) any later version.
1303+#
1304+# This program is distributed in the hope that it will be useful,
1305+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1306+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1307+# GNU General Public License for more details.
1308+#
1309+# You should have received a copy of the GNU General Public License
523b37e3 1310+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1311+
1312+Lookup in a Branch
1313+----------------------------------------------------------------------
1314+Since aufs has a character of sub-VFS (see Introduction), it operates
1315+lookup for branches as VFS does. It may be a heavy work. Generally
1316+speaking struct nameidata is a bigger structure and includes many
1317+information. But almost all lookup operation in aufs is the simplest
1318+case, ie. lookup only an entry directly connected to its parent. Digging
1319+down the directory hierarchy is unnecessary.
1320+
1321+VFS has a function lookup_one_len() for that use, but it is not usable
1322+for a branch filesystem which requires struct nameidata. So aufs
1323+implements a simple lookup wrapper function. When a branch filesystem
1324+allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
1325+a simplest nameidata and calls lookup_hash().
1326+Here aufs applies "a principle in NFSD", ie. if the filesystem supports
1327+NFS-export, then it has to support NULL as a nameidata parameter for
1328+->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
1329+aufs tests if ->s_export_op in the branch is NULL or not.
1330+
1331+When a branch is a remote filesystem, aufs basically trusts its
1332+->d_revalidate(), also aufs forces the hardest revalidate tests for
1333+them.
1334+For d_revalidate, aufs implements three levels of revalidate tests. See
1335+"Revalidate Dentry and UDBA" in detail.
1336+
1337+
1338+Loopback Mount
1339+----------------------------------------------------------------------
1340+Basically aufs supports any type of filesystem and block device for a
1341+branch (actually there are some exceptions). But it is prohibited to add
1342+a loopback mounted one whose backend file exists in a filesystem which is
1343+already added to aufs. The reason is to protect aufs from a recursive
1344+lookup. If it was allowed, the aufs lookup operation might re-enter a
1345+lookup for the loopback mounted branch in the same context, and will
1346+cause a deadlock.
1347+
1348+
1349+Revalidate Dentry and UDBA (User's Direct Branch Access)
1350+----------------------------------------------------------------------
1351+Generally VFS helpers re-validate a dentry as a part of lookup.
1352+0. digging down the directory hierarchy.
1353+1. lock the parent dir by its i_mutex.
1354+2. lookup the final (child) entry.
1355+3. revalidate it.
1356+4. call the actual operation (create, unlink, etc.)
1357+5. unlock the parent dir
1358+
1359+If the filesystem implements its ->d_revalidate() (step 3), then it is
1360+called. Actually aufs implements it and checks the dentry on a branch is
1361+still valid.
1362+But it is not enough. Because aufs has to release the lock for the
1363+parent dir on a branch at the end of ->lookup() (step 2) and
1364+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1365+held by VFS.
1366+If the file on a branch is changed directly, eg. bypassing aufs, after
1367+aufs released the lock, then the subsequent operation may cause
1368+something unpleasant result.
1369+
1370+This situation is a result of VFS architecture, ->lookup() and
1371+->d_revalidate() is separated. But I never say it is wrong. It is a good
1372+design from VFS's point of view. It is just not suitable for sub-VFS
1373+character in aufs.
1374+
1375+Aufs supports such case by three level of revalidation which is
1376+selectable by user.
1377+1. Simple Revalidate
1378+ Addition to the native flow in VFS's, confirm the child-parent
1379+ relationship on the branch just after locking the parent dir on the
1380+ branch in the "actual operation" (step 4). When this validation
1381+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1382+ checks the validation of the dentry on branches.
1383+2. Monitor Changes Internally by Inotify/Fsnotify
1384+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1385+ the dentry on the branch, and returns EBUSY if it finds different
1386+ dentry.
1387+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1388+ during it is in cache. When the event is notified, aufs registers a
1389+ function to kernel 'events' thread by schedule_work(). And the
1390+ function sets some special status to the cached aufs dentry and inode
1391+ private data. If they are not cached, then aufs has nothing to
1392+ do. When the same file is accessed through aufs (step 0-3) later,
1393+ aufs will detect the status and refresh all necessary data.
1394+ In this mode, aufs has to ignore the event which is fired by aufs
1395+ itself.
1396+3. No Extra Validation
1397+ This is the simplest test and doesn't add any additional revalidation
1398+ test, and skip therevalidatin in step 4. It is useful and improves
1399+ aufs performance when system surely hide the aufs branches from user,
1400+ by over-mounting something (or another method).
1401diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1402--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1403+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1404@@ -0,0 +1,75 @@
53392da6 1405+
523b37e3 1406+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1407+#
1408+# This program is free software; you can redistribute it and/or modify
1409+# it under the terms of the GNU General Public License as published by
1410+# the Free Software Foundation; either version 2 of the License, or
1411+# (at your option) any later version.
1412+#
1413+# This program is distributed in the hope that it will be useful,
1414+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1415+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1416+# GNU General Public License for more details.
1417+#
1418+# You should have received a copy of the GNU General Public License
523b37e3 1419+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1420+
1421+Branch Manipulation
1422+
1423+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1424+and changing its permission/attribute, there are a lot of works to do.
1425+
1426+
1427+Add a Branch
1428+----------------------------------------------------------------------
1429+o Confirm the adding dir exists outside of aufs, including loopback
1430+ mount.
1431+- and other various attributes...
1432+o Initialize the xino file and whiteout bases if necessary.
1433+ See struct.txt.
1434+
1435+o Check the owner/group/mode of the directory
1436+ When the owner/group/mode of the adding directory differs from the
1437+ existing branch, aufs issues a warning because it may impose a
1438+ security risk.
1439+ For example, when a upper writable branch has a world writable empty
1440+ top directory, a malicious user can create any files on the writable
1441+ branch directly, like copy-up and modify manually. If something like
1442+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1443+ writable branch, and the writable branch is world-writable, then a
1444+ malicious guy may create /etc/passwd on the writable branch directly
1445+ and the infected file will be valid in aufs.
1446+ I am afraid it can be a security issue, but nothing to do except
1447+ producing a warning.
1448+
1449+
1450+Delete a Branch
1451+----------------------------------------------------------------------
1452+o Confirm the deleting branch is not busy
1453+ To be general, there is one merit to adopt "remount" interface to
1454+ manipulate branches. It is to discard caches. At deleting a branch,
1455+ aufs checks the still cached (and connected) dentries and inodes. If
1456+ there are any, then they are all in-use. An inode without its
1457+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1458+
1459+ For the cached one, aufs checks whether the same named entry exists on
1460+ other branches.
1461+ If the cached one is a directory, because aufs provides a merged view
1462+ to users, as long as one dir is left on any branch aufs can show the
1463+ dir to users. In this case, the branch can be removed from aufs.
1464+ Otherwise aufs rejects deleting the branch.
1465+
1466+ If any file on the deleting branch is opened by aufs, then aufs
1467+ rejects deleting.
1468+
1469+
1470+Modify the Permission of a Branch
1471+----------------------------------------------------------------------
1472+o Re-initialize or remove the xino file and whiteout bases if necessary.
1473+ See struct.txt.
1474+
1475+o rw --> ro: Confirm the modifying branch is not busy
1476+ Aufs rejects the request if any of these conditions are true.
1477+ - a file on the branch is mmap-ed.
1478+ - a regular file on the branch is opened for write and there is no
1479+ same named entry on the upper branch.
1480diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1481--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1482+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1483@@ -0,0 +1,64 @@
53392da6 1484+
523b37e3 1485+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1486+#
1487+# This program is free software; you can redistribute it and/or modify
1488+# it under the terms of the GNU General Public License as published by
1489+# the Free Software Foundation; either version 2 of the License, or
1490+# (at your option) any later version.
1491+#
1492+# This program is distributed in the hope that it will be useful,
1493+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1494+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1495+# GNU General Public License for more details.
1496+#
1497+# You should have received a copy of the GNU General Public License
523b37e3 1498+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1499+
1500+Policies to Select One among Multiple Writable Branches
1501+----------------------------------------------------------------------
1502+When the number of writable branch is more than one, aufs has to decide
1503+the target branch for file creation or copy-up. By default, the highest
1504+writable branch which has the parent (or ancestor) dir of the target
1505+file is chosen (top-down-parent policy).
1506+By user's request, aufs implements some other policies to select the
1507+writable branch, for file creation two policies, round-robin and
1508+most-free-space policies. For copy-up three policies, top-down-parent,
1509+bottom-up-parent and bottom-up policies.
1510+
1511+As expected, the round-robin policy selects the branch in circular. When
1512+you have two writable branches and creates 10 new files, 5 files will be
1513+created for each branch. mkdir(2) systemcall is an exception. When you
1514+create 10 new directories, all will be created on the same branch.
1515+And the most-free-space policy selects the one which has most free
1516+space among the writable branches. The amount of free space will be
1517+checked by aufs internally, and users can specify its time interval.
1518+
1519+The policies for copy-up is more simple,
1520+top-down-parent is equivalent to the same named on in create policy,
1521+bottom-up-parent selects the writable branch where the parent dir
1522+exists and the nearest upper one from the copyup-source,
1523+bottom-up selects the nearest upper writable branch from the
1524+copyup-source, regardless the existence of the parent dir.
1525+
1526+There are some rules or exceptions to apply these policies.
1527+- If there is a readonly branch above the policy-selected branch and
1528+ the parent dir is marked as opaque (a variation of whiteout), or the
1529+ target (creating) file is whiteout-ed on the upper readonly branch,
1530+ then the result of the policy is ignored and the target file will be
1531+ created on the nearest upper writable branch than the readonly branch.
1532+- If there is a writable branch above the policy-selected branch and
1533+ the parent dir is marked as opaque or the target file is whiteouted
1534+ on the branch, then the result of the policy is ignored and the target
1535+ file will be created on the highest one among the upper writable
1536+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1537+ it as usual.
1538+- link(2) and rename(2) systemcalls are exceptions in every policy.
1539+ They try selecting the branch where the source exists as possible
1540+ since copyup a large file will take long time. If it can't be,
1541+ ie. the branch where the source exists is readonly, then they will
1542+ follow the copyup policy.
1543+- There is an exception for rename(2) when the target exists.
1544+ If the rename target exists, aufs compares the index of the branches
1545+ where the source and the target exists and selects the higher
1546+ one. If the selected branch is readonly, then aufs follows the
1547+ copyup policy.
1548diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1549--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1550+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1551@@ -0,0 +1,46 @@
53392da6 1552+
523b37e3 1553+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1554+#
1555+# This program is free software; you can redistribute it and/or modify
1556+# it under the terms of the GNU General Public License as published by
1557+# the Free Software Foundation; either version 2 of the License, or
1558+# (at your option) any later version.
1559+#
1560+# This program is distributed in the hope that it will be useful,
1561+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1562+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1563+# GNU General Public License for more details.
1564+#
1565+# You should have received a copy of the GNU General Public License
523b37e3 1566+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1567+
1568+mmap(2) -- File Memory Mapping
1569+----------------------------------------------------------------------
1570+In aufs, the file-mapped pages are handled by a branch fs directly, no
1571+interaction with aufs. It means aufs_mmap() calls the branch fs's
1572+->mmap().
1573+This approach is simple and good, but there is one problem.
1574+Under /proc, several entries show the mmap-ped files by its path (with
1575+device and inode number), and the printed path will be the path on the
1576+branch fs's instead of virtual aufs's.
1577+This is not a problem in most cases, but some utilities lsof(1) (and its
1578+user) may expect the path on aufs.
1579+
1580+To address this issue, aufs adds a new member called vm_prfile in struct
1581+vm_area_struct (and struct vm_region). The original vm_file points to
1582+the file on the branch fs in order to handle everything correctly as
1583+usual. The new vm_prfile points to a virtual file in aufs, and the
1584+show-functions in procfs refers to vm_prfile if it is set.
1585+Also we need to maintain several other places where touching vm_file
1586+such like
1587+- fork()/clone() copies vma and the reference count of vm_file is
1588+ incremented.
1589+- merging vma maintains the ref count too.
1590+
1591+This is not a good approach. It just faking the printed path. But it
1592+leaves all behaviour around f_mapping unchanged. This is surely an
1593+advantage.
1594+Actually aufs had adopted another complicated approach which calls
1595+generic_file_mmap() and handles struct vm_operations_struct. In this
1596+approach, aufs met a hard problem and I could not solve it without
1597+switching the approach.
1598diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1599--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1600+++ linux/Documentation/filesystems/aufs/design/07export.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1601@@ -0,0 +1,58 @@
53392da6 1602+
523b37e3 1603+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1604+#
1605+# This program is free software; you can redistribute it and/or modify
1606+# it under the terms of the GNU General Public License as published by
1607+# the Free Software Foundation; either version 2 of the License, or
1608+# (at your option) any later version.
1609+#
1610+# This program is distributed in the hope that it will be useful,
1611+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1612+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1613+# GNU General Public License for more details.
1614+#
1615+# You should have received a copy of the GNU General Public License
523b37e3 1616+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1617+
1618+Export Aufs via NFS
1619+----------------------------------------------------------------------
1620+Here is an approach.
1621+- like xino/xib, add a new file 'xigen' which stores aufs inode
1622+ generation.
1623+- iget_locked(): initialize aufs inode generation for a new inode, and
1624+ store it in xigen file.
1625+- destroy_inode(): increment aufs inode generation and store it in xigen
1626+ file. it is necessary even if it is not unlinked, because any data of
1627+ inode may be changed by UDBA.
1628+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1629+ build file handle by
1630+ + branch id (4 bytes)
1631+ + superblock generation (4 bytes)
1632+ + inode number (4 or 8 bytes)
1633+ + parent dir inode number (4 or 8 bytes)
1634+ + inode generation (4 bytes))
1635+ + return value of exportfs_encode_fh() for the parent on a branch (4
1636+ bytes)
1637+ + file handle for a branch (by exportfs_encode_fh())
1638+- fh_to_dentry():
1639+ + find the index of a branch from its id in handle, and check it is
1640+ still exist in aufs.
1641+ + 1st level: get the inode number from handle and search it in cache.
1642+ + 2nd level: if not found, get the parent inode number from handle and
1643+ search it in cache. and then open the parent dir, find the matching
1644+ inode number by vfs_readdir() and get its name, and call
1645+ lookup_one_len() for the target dentry.
1646+ + 3rd level: if the parent dir is not cached, call
1647+ exportfs_decode_fh() for a branch and get the parent on a branch,
1648+ build a pathname of it, convert it a pathname in aufs, call
1649+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
1650+ the 2nd level.
1651+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1652+ for every branch, but not itself. to get this, (currently) aufs
1653+ searches in current->nsproxy->mnt_ns list. it may not be a good
1654+ idea, but I didn't get other approach.
1655+ + test the generation of the gotten inode.
1656+- every inode operation: they may get EBUSY due to UDBA. in this case,
1657+ convert it into ESTALE for NFSD.
1658+- readdir(): call lockdep_on/off() because filldir in NFSD calls
1659+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
1660diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1661--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1662+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1663@@ -0,0 +1,52 @@
53392da6 1664+
523b37e3 1665+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
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
523b37e3 1678+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1679+
1680+Show Whiteout Mode (shwh)
1681+----------------------------------------------------------------------
1682+Generally aufs hides the name of whiteouts. But in some cases, to show
1683+them is very useful for users. For instance, creating a new middle layer
1684+(branch) by merging existing layers.
1685+
1686+(borrowing aufs1 HOW-TO from a user, Michael Towers)
1687+When you have three branches,
1688+- Bottom: 'system', squashfs (underlying base system), read-only
1689+- Middle: 'mods', squashfs, read-only
1690+- Top: 'overlay', ram (tmpfs), read-write
1691+
1692+The top layer is loaded at boot time and saved at shutdown, to preserve
1693+the changes made to the system during the session.
1694+When larger changes have been made, or smaller changes have accumulated,
1695+the size of the saved top layer data grows. At this point, it would be
1696+nice to be able to merge the two overlay branches ('mods' and 'overlay')
1697+and rewrite the 'mods' squashfs, clearing the top layer and thus
1698+restoring save and load speed.
1699+
1700+This merging is simplified by the use of another aufs mount, of just the
1701+two overlay branches using the 'shwh' option.
1702+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
1703+ aufs /livesys/merge_union
1704+
1705+A merged view of these two branches is then available at
1706+/livesys/merge_union, and the new feature is that the whiteouts are
1707+visible!
1708+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
1709+writing to all branches. Also the default mode for all branches is 'ro'.
1710+It is now possible to save the combined contents of the two overlay
1711+branches to a new squashfs, e.g.:
1712+# mksquashfs /livesys/merge_union /path/to/newmods.squash
1713+
1714+This new squashfs archive can be stored on the boot device and the
1715+initramfs will use it to replace the old one at the next boot.
1716diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
1717--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1718+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1719@@ -0,0 +1,46 @@
53392da6 1720+
523b37e3 1721+# Copyright (C) 2010-2014 Junjiro R. Okajima
53392da6
AM
1722+#
1723+# This program is free software; you can redistribute it and/or modify
1724+# it under the terms of the GNU General Public License as published by
1725+# the Free Software Foundation; either version 2 of the License, or
1726+# (at your option) any later version.
1727+#
1728+# This program is distributed in the hope that it will be useful,
1729+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1730+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1731+# GNU General Public License for more details.
1732+#
1733+# You should have received a copy of the GNU General Public License
523b37e3 1734+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1735+
1736+Dynamically customizable FS operations
1737+----------------------------------------------------------------------
1738+Generally FS operations (struct inode_operations, struct
1739+address_space_operations, struct file_operations, etc.) are defined as
1740+"static const", but it never means that FS have only one set of
1741+operation. Some FS have multiple sets of them. For instance, ext2 has
1742+three sets, one for XIP, for NOBH, and for normal.
1743+Since aufs overrides and redirects these operations, sometimes aufs has
1744+to change its behaviour according to the branch FS type. More imporantly
1745+VFS acts differently if a function (member in the struct) is set or
1746+not. It means aufs should have several sets of operations and select one
1747+among them according to the branch FS definition.
1748+
1749+In order to solve this problem and not to affect the behavour of VFS,
1750+aufs defines these operations dynamically. For instance, aufs defines
1751+aio_read function for struct file_operations, but it may not be set to
1752+the file_operations. When the branch FS doesn't have it, aufs doesn't
1753+set it to its file_operations while the function definition itself is
1754+still alive. So the behaviour of io_submit(2) will not change, and it
1755+will return an error when aio_read is not defined.
1756+
1757+The lifetime of these dynamically generated operation object is
1758+maintained by aufs branch object. When the branch is removed from aufs,
1759+the reference counter of the object is decremented. When it reaches
1760+zero, the dynamically generated operation object will be freed.
1761+
1762+This approach is designed to support AIO (io_submit), Direcit I/O and
1763+XIP mainly.
1764+Currently this approach is applied to file_operations and
1765+vm_operations_struct for regular files only.
1766diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
1767--- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1768+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2014-04-24 22:11:10.471931783 +0200
523b37e3 1769@@ -0,0 +1,95 @@
53392da6 1770+
523b37e3 1771+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1772+#
1773+# This program is free software; you can redistribute it and/or modify
1774+# it under the terms of the GNU General Public License as published by
1775+# the Free Software Foundation; either version 2 of the License, or
1776+# (at your option) any later version.
1777+#
1778+# This program is distributed in the hope that it will be useful,
1779+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1780+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1781+# GNU General Public License for more details.
1782+#
1783+# You should have received a copy of the GNU General Public License
523b37e3 1784+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1785+
1786+Plan
1787+
1788+Restoring some features which was implemented in aufs1.
1789+They were dropped in aufs2 in order to make source files simpler and
1790+easier to be reviewed.
1791+
1792+
1793+Test Only the Highest One for the Directory Permission (dirperm1 option)
1794+----------------------------------------------------------------------
1795+Let's try case study.
1796+- aufs has two branches, upper readwrite and lower readonly.
1797+ /au = /rw + /ro
1798+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1799+- user invoked "chmod a+rx /au/dirA"
1800+- then "dirA" becomes world readable?
1801+
1802+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1803+or it may be a natively readonly filesystem. If aufs respects the lower
1804+branch, it should not respond readdir request from other users. But user
1805+allowed it by chmod. Should really aufs rejects showing the entries
1806+under /ro/dirA?
1807+
1808+To be honest, I don't have a best solution for this case. So I
1809+implemented 'dirperm1' and 'nodirperm1' option in aufs1, and leave it to
1810+users.
1811+When dirperm1 is specified, aufs checks only the highest one for the
1812+directory permission, and shows the entries. Otherwise, as usual, checks
1813+every dir existing on all branches and rejects the request.
1814+
1815+As a side effect, dirperm1 option improves the performance of aufs
1816+because the number of permission check is reduced.
1817+
1818+
1819+Being Another Aufs's Readonly Branch (robr)
1820+----------------------------------------------------------------------
1821+Aufs1 allows aufs to be another aufs's readonly branch.
1822+This feature was developed by a user's request. But it may not be used
1823+currecnly.
1824+
1825+
1826+Copy-up on Open (coo=)
1827+----------------------------------------------------------------------
1828+By default the internal copy-up is executed when it is really necessary.
1829+It is not done when a file is opened for writing, but when write(2) is
1830+done. Users who have many (over 100) branches want to know and analyse
1831+when and what file is copied-up. To insert a new upper branch which
1832+contains such files only may improve the performance of aufs.
1833+
1834+Aufs1 implemented "coo=none | leaf | all" option.
1835+
1836+
1837+Refresh the Opened File (refrof)
1838+----------------------------------------------------------------------
1839+This option is implemented in aufs1 but incomplete.
1840+
1841+When user reads from a file, he expects to get its latest filedata
1842+generally. If the file is removed and a new same named file is created,
1843+the content he gets is unchanged, ie. the unlinked filedata.
1844+
1845+Let's try case study again.
1846+- aufs has two branches.
1847+ /au = /rw + /ro
1848+- "fileA" exists under /ro, but /rw.
1849+- user opened "/au/fileA".
1850+- he or someone else inserts a branch (/new) between /rw and /ro.
1851+ /au = /rw + /new + /ro
1852+- the new branch has "fileA".
1853+- user reads from the opened "fileA"
1854+- which filedata should aufs return, from /ro or /new?
1855+
1856+Some people says it has to be "from /ro" and it is a semantics of Unix.
1857+The others say it should be "from /new" because the file is not removed
1858+and it is equivalent to the case of someone else modifies the file.
1859+
1860+Here again I don't have a best and final answer. I got an idea to
1861+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
1862+Opened File) is specified (by default), aufs returns the filedata from
1863+/new.
1864+Otherwise from /new.
1865diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
1866--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
fb47a38f 1867+++ linux/Documentation/filesystems/aufs/README 2014-04-24 22:11:10.471931783 +0200
523b37e3 1868@@ -0,0 +1,344 @@
53392da6
AM
1869+
1870+Aufs3 -- advanced multi layered unification filesystem version 3.x
1871+http://aufs.sf.net
1872+Junjiro R. Okajima
1873+
1874+
1875+0. Introduction
1876+----------------------------------------
1877+In the early days, aufs was entirely re-designed and re-implemented
1878+Unionfs Version 1.x series. After many original ideas, approaches,
1879+improvements and implementations, it becomes totally different from
1880+Unionfs while keeping the basic features.
1881+Recently, Unionfs Version 2.x series begin taking some of the same
1882+approaches to aufs1's.
1883+Unionfs is being developed by Professor Erez Zadok at Stony Brook
1884+University and his team.
1885+
1886+Aufs3 supports linux-3.0 and later.
1887+If you want older kernel version support, try aufs2-2.6.git or
1888+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
1889+
1890+Note: it becomes clear that "Aufs was rejected. Let's give it up."
1891+According to Christoph Hellwig, linux rejects all union-type filesystems
1892+but UnionMount.
1893+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
1894+
1895+
1896+1. Features
1897+----------------------------------------
1898+- unite several directories into a single virtual filesystem. The member
1899+ directory is called as a branch.
1900+- you can specify the permission flags to the branch, which are 'readonly',
1901+ 'readwrite' and 'whiteout-able.'
1902+- by upper writable branch, internal copyup and whiteout, files/dirs on
1903+ readonly branch are modifiable logically.
1904+- dynamic branch manipulation, add, del.
1905+- etc...
1906+
1907+Also there are many enhancements in aufs1, such as:
1908+- readdir(3) in userspace.
1909+- keep inode number by external inode number table
1910+- keep the timestamps of file/dir in internal copyup operation
1911+- seekable directory, supporting NFS readdir.
1912+- whiteout is hardlinked in order to reduce the consumption of inodes
1913+ on branch
1914+- do not copyup, nor create a whiteout when it is unnecessary
1915+- revert a single systemcall when an error occurs in aufs
1916+- remount interface instead of ioctl
1917+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
1918+- loopback mounted filesystem as a branch
1919+- kernel thread for removing the dir who has a plenty of whiteouts
1920+- support copyup sparse file (a file which has a 'hole' in it)
1921+- default permission flags for branches
1922+- selectable permission flags for ro branch, whether whiteout can
1923+ exist or not
1924+- export via NFS.
1925+- support <sysfs>/fs/aufs and <debugfs>/aufs.
1926+- support multiple writable branches, some policies to select one
1927+ among multiple writable branches.
1928+- a new semantics for link(2) and rename(2) to support multiple
1929+ writable branches.
1930+- no glibc changes are required.
1931+- pseudo hardlink (hardlink over branches)
1932+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
1933+ including NFS or remote filesystem branch.
1934+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
1935+- and more...
1936+
1937+Currently these features are dropped temporary from aufs3.
1938+See design/08plan.txt in detail.
1939+- test only the highest one for the directory permission (dirperm1)
1940+- copyup on open (coo=)
1941+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
1942+ (robr)
1943+- statistics of aufs thread (/sys/fs/aufs/stat)
1944+- delegation mode (dlgt)
1945+ a delegation of the internal branch access to support task I/O
1946+ accounting, which also supports Linux Security Modules (LSM) mainly
1947+ for Suse AppArmor.
1948+- intent.open/create (file open in a single lookup)
1949+
1950+Features or just an idea in the future (see also design/*.txt),
1951+- reorder the branch index without del/re-add.
1952+- permanent xino files for NFSD
1953+- an option for refreshing the opened files after add/del branches
1954+- 'move' policy for copy-up between two writable branches, after
1955+ checking free space.
1956+- light version, without branch manipulation. (unnecessary?)
1957+- copyup in userspace
1958+- inotify in userspace
1959+- readv/writev
1960+- xattr, acl
1961+
1962+
1963+2. Download
1964+----------------------------------------
1e00d052
AM
1965+There were three GIT trees for aufs3, aufs3-linux.git,
1966+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
1967+"aufs-util.git."
1968+While the aufs-util is always necessary, you need either of aufs3-linux
1969+or aufs3-standalone.
1970+
1971+The aufs3-linux tree includes the whole linux mainline GIT tree,
1972+git://git.kernel.org/.../torvalds/linux.git.
1973+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
b4510431 1974+build aufs3 as an external kernel module.
1e00d052
AM
1975+
1976+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6
AM
1977+and necessary patches, and you can select CONFIG_AUFS_FS=m.
1978+
1979+You will find GIT branches whose name is in form of "aufs3.x" where "x"
1980+represents the linux kernel version, "linux-3.x". For instance,
1e00d052
AM
1981+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
1982+"aufs3.x-rcN" branch.
1983+
1984+o aufs3-linux tree
1985+$ git clone --reference /your/linux/git/tree \
86dc4139 1986+ git://git.code.sf.net/p/aufs/aufs3-linux aufs-aufs3-linux \
1e00d052
AM
1987+ aufs3-linux.git
1988+- if you don't have linux GIT tree, then remove "--reference ..."
1989+$ cd aufs3-linux.git
1990+$ git checkout origin/aufs3.0
53392da6
AM
1991+
1992+o aufs3-standalone tree
86dc4139 1993+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
53392da6
AM
1994+ aufs3-standalone.git
1995+$ cd aufs3-standalone.git
1996+$ git checkout origin/aufs3.0
1997+
1998+o aufs-util tree
86dc4139 1999+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
53392da6
AM
2000+ aufs-util.git
2001+$ cd aufs-util.git
2002+$ git checkout origin/aufs3.0
2003+
9dbd164d
AM
2004+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
2005+The minor version number, 'x' in '3.x', of aufs may not always
2006+follow the minor version number of the kernel.
2007+Because changes in the kernel that cause the use of a new
2008+minor version number do not always require changes to aufs-util.
2009+
2010+Since aufs-util has its own minor version number, you may not be
2011+able to find a GIT branch in aufs-util for your kernel's
2012+exact minor version number.
2013+In this case, you should git-checkout the branch for the
53392da6 2014+nearest lower number.
9dbd164d
AM
2015+
2016+For (an unreleased) example:
2017+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 2018+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
2019+or something numerically smaller is the branch for your kernel.
2020+
53392da6
AM
2021+Also you can view all branches by
2022+ $ git branch -a
2023+
2024+
2025+3. Configuration and Compilation
2026+----------------------------------------
2027+Make sure you have git-checkout'ed the correct branch.
2028+
1e00d052 2029+For aufs3-linux tree,
c06a8ce3 2030+- enable CONFIG_AUFS_FS.
1e00d052
AM
2031+- set other aufs configurations if necessary.
2032+
53392da6
AM
2033+For aufs3-standalone tree,
2034+There are several ways to build.
2035+
2036+1.
2037+- apply ./aufs3-kbuild.patch to your kernel source files.
2038+- apply ./aufs3-base.patch too.
523b37e3 2039+- apply ./aufs3-mmap.patch too.
53392da6
AM
2040+- apply ./aufs3-standalone.patch too, if you have a plan to set
2041+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
537831f9
AM
2042+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2043+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2044+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2045+ =m or =y.
2046+- and build your kernel as usual.
2047+- install the built kernel.
c06a8ce3
AM
2048+ Note: Since linux-3.9, every filesystem module requires an alias
2049+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2050+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2051+- install the header files too by "make headers_install" to the
2052+ directory where you specify. By default, it is $PWD/usr.
b4510431 2053+ "make help" shows a brief note for headers_install.
53392da6
AM
2054+- and reboot your system.
2055+
2056+2.
2057+- module only (CONFIG_AUFS_FS=m).
2058+- apply ./aufs3-base.patch to your kernel source files.
523b37e3 2059+- apply ./aufs3-mmap.patch too.
53392da6
AM
2060+- apply ./aufs3-standalone.patch too.
2061+- build your kernel, don't forget "make headers_install", and reboot.
2062+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2063+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2064+ every aufs configurations.
2065+- build the module by simple "make".
c06a8ce3
AM
2066+ Note: Since linux-3.9, every filesystem module requires an alias
2067+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2068+ modules.aliases file.
53392da6
AM
2069+- you can specify ${KDIR} make variable which points to your kernel
2070+ source tree.
2071+- install the files
2072+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2073+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2074+ + run "make install_headers" (instead of headers_install) to install
2075+ the modified aufs header file (you can specify DESTDIR which is
2076+ available in aufs standalone version's Makefile only), or copy
2077+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2078+ you like manually. By default, the target directory is $PWD/usr.
53392da6
AM
2079+- no need to apply aufs3-kbuild.patch, nor copying source files to your
2080+ kernel source tree.
2081+
b4510431 2082+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2083+ as well as "make headers_install" in the kernel source tree.
2084+ headers_install is subject to be forgotten, but it is essentially
2085+ necessary, not only for building aufs-util.
2086+ You may not meet problems without headers_install in some older
2087+ version though.
2088+
2089+And then,
2090+- read README in aufs-util, build and install it
9dbd164d
AM
2091+- note that your distribution may contain an obsoleted version of
2092+ aufs_type.h in /usr/include/linux or something. When you build aufs
2093+ utilities, make sure that your compiler refers the correct aufs header
2094+ file which is built by "make headers_install."
53392da6
AM
2095+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2096+ then run "make install_ulib" too. And refer to the aufs manual in
2097+ detail.
2098+
2099+
2100+4. Usage
2101+----------------------------------------
2102+At first, make sure aufs-util are installed, and please read the aufs
2103+manual, aufs.5 in aufs-util.git tree.
2104+$ man -l aufs.5
2105+
2106+And then,
2107+$ mkdir /tmp/rw /tmp/aufs
2108+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2109+
2110+Here is another example. The result is equivalent.
2111+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2112+ Or
2113+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2114+# mount -o remount,append:${HOME} /tmp/aufs
2115+
2116+Then, you can see whole tree of your home dir through /tmp/aufs. If
2117+you modify a file under /tmp/aufs, the one on your home directory is
2118+not affected, instead the same named file will be newly created under
2119+/tmp/rw. And all of your modification to a file will be applied to
2120+the one under /tmp/rw. This is called the file based Copy on Write
2121+(COW) method.
2122+Aufs mount options are described in aufs.5.
2123+If you run chroot or something and make your aufs as a root directory,
2124+then you need to customize the shutdown script. See the aufs manual in
2125+detail.
2126+
2127+Additionally, there are some sample usages of aufs which are a
2128+diskless system with network booting, and LiveCD over NFS.
2129+See sample dir in CVS tree on SourceForge.
2130+
2131+
2132+5. Contact
2133+----------------------------------------
2134+When you have any problems or strange behaviour in aufs, please let me
2135+know with:
2136+- /proc/mounts (instead of the output of mount(8))
2137+- /sys/module/aufs/*
2138+- /sys/fs/aufs/* (if you have them)
2139+- /debug/aufs/* (if you have them)
2140+- linux kernel version
2141+ if your kernel is not plain, for example modified by distributor,
2142+ the url where i can download its source is necessary too.
2143+- aufs version which was printed at loading the module or booting the
2144+ system, instead of the date you downloaded.
2145+- configuration (define/undefine CONFIG_AUFS_xxx)
2146+- kernel configuration or /proc/config.gz (if you have it)
2147+- behaviour which you think to be incorrect
2148+- actual operation, reproducible one is better
2149+- mailto: aufs-users at lists.sourceforge.net
2150+
2151+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2152+and Feature Requests) on SourceForge. Please join and write to
2153+aufs-users ML.
2154+
2155+
2156+6. Acknowledgements
2157+----------------------------------------
2158+Thanks to everyone who have tried and are using aufs, whoever
2159+have reported a bug or any feedback.
2160+
2161+Especially donators:
2162+Tomas Matejicek(slax.org) made a donation (much more than once).
2163+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2164+ scripts) is making "doubling" donations.
2165+ Unfortunately I cannot list all of the donators, but I really
b4510431 2166+ appreciate.
53392da6
AM
2167+ It ends Aug 2010, but the ordinary donation URL is still available.
2168+ <http://sourceforge.net/donate/index.php?group_id=167503>
2169+Dai Itasaka made a donation (2007/8).
2170+Chuck Smith made a donation (2008/4, 10 and 12).
2171+Henk Schoneveld made a donation (2008/9).
2172+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2173+Francois Dupoux made a donation (2008/11).
2174+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2175+ aufs2 GIT tree (2009/2).
2176+William Grant made a donation (2009/3).
2177+Patrick Lane made a donation (2009/4).
2178+The Mail Archive (mail-archive.com) made donations (2009/5).
2179+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2180+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2181+Pavel Pronskiy made a donation (2011/2).
2182+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2183+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
2184+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2185+11).
1e00d052 2186+Sam Liddicott made a donation (2011/9).
86dc4139
AM
2187+Era Scarecrow made a donation (2013/4).
2188+Bor Ratajc made a donation (2013/4).
2189+Alessandro Gorreta made a donation (2013/4).
2190+POIRETTE Marc made a donation (2013/4).
2191+Alessandro Gorreta made a donation (2013/4).
2192+lauri kasvandik made a donation (2013/5).
392086de 2193+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
2194+The Parted Magic Project made a donation (2013/9 and 11).
2195+Pavel Barta made a donation (2013/10).
53392da6
AM
2196+
2197+Thank you very much.
2198+Donations are always, including future donations, very important and
2199+helpful for me to keep on developing aufs.
2200+
2201+
2202+7.
2203+----------------------------------------
2204+If you are an experienced user, no explanation is needed. Aufs is
2205+just a linux filesystem.
2206+
2207+
2208+Enjoy!
2209+
2210+# Local variables: ;
2211+# mode: text;
2212+# End: ;
7f207e10
AM
2213diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
2214--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 2215+++ linux/fs/aufs/aufs.h 2014-04-24 22:11:10.848602379 +0200
523b37e3 2216@@ -0,0 +1,59 @@
7f207e10 2217+/*
523b37e3 2218+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
2219+ *
2220+ * This program, aufs is free software; you can redistribute it and/or modify
2221+ * it under the terms of the GNU General Public License as published by
2222+ * the Free Software Foundation; either version 2 of the License, or
2223+ * (at your option) any later version.
2224+ *
2225+ * This program is distributed in the hope that it will be useful,
2226+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2227+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2228+ * GNU General Public License for more details.
2229+ *
2230+ * You should have received a copy of the GNU General Public License
523b37e3 2231+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2232+ */
2233+
2234+/*
2235+ * all header files
2236+ */
2237+
2238+#ifndef __AUFS_H__
2239+#define __AUFS_H__
2240+
2241+#ifdef __KERNEL__
2242+
2243+#define AuStub(type, name, body, ...) \
2244+ static inline type name(__VA_ARGS__) { body; }
2245+
2246+#define AuStubVoid(name, ...) \
2247+ AuStub(void, name, , __VA_ARGS__)
2248+#define AuStubInt0(name, ...) \
2249+ AuStub(int, name, return 0, __VA_ARGS__)
2250+
2251+#include "debug.h"
2252+
2253+#include "branch.h"
2254+#include "cpup.h"
2255+#include "dcsub.h"
2256+#include "dbgaufs.h"
2257+#include "dentry.h"
2258+#include "dir.h"
2259+#include "dynop.h"
2260+#include "file.h"
2261+#include "fstype.h"
2262+#include "inode.h"
2263+#include "loop.h"
2264+#include "module.h"
7f207e10
AM
2265+#include "opts.h"
2266+#include "rwsem.h"
2267+#include "spl.h"
2268+#include "super.h"
2269+#include "sysaufs.h"
2270+#include "vfsub.h"
2271+#include "whout.h"
2272+#include "wkq.h"
2273+
2274+#endif /* __KERNEL__ */
2275+#endif /* __AUFS_H__ */
2276diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
2277--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 2278+++ linux/fs/aufs/branch.c 2014-04-24 22:11:10.848602379 +0200
523b37e3 2279@@ -0,0 +1,1219 @@
7f207e10 2280+/*
523b37e3 2281+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
2282+ *
2283+ * This program, aufs is free software; you can redistribute it and/or modify
2284+ * it under the terms of the GNU General Public License as published by
2285+ * the Free Software Foundation; either version 2 of the License, or
2286+ * (at your option) any later version.
2287+ *
2288+ * This program is distributed in the hope that it will be useful,
2289+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2290+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2291+ * GNU General Public License for more details.
2292+ *
2293+ * You should have received a copy of the GNU General Public License
523b37e3 2294+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2295+ */
2296+
2297+/*
2298+ * branch management
2299+ */
2300+
027c5e7a 2301+#include <linux/compat.h>
7f207e10
AM
2302+#include <linux/statfs.h>
2303+#include "aufs.h"
2304+
2305+/*
2306+ * free a single branch
1facf9fc 2307+ */
86dc4139
AM
2308+
2309+/* prohibit rmdir to the root of the branch */
2310+/* todo: another new flag? */
2311+static void au_br_dflags_force(struct au_branch *br)
2312+{
2313+ struct dentry *h_dentry;
2314+
2315+ h_dentry = au_br_dentry(br);
2316+ spin_lock(&h_dentry->d_lock);
2317+ br->br_dflags = h_dentry->d_flags & DCACHE_MOUNTED;
2318+ h_dentry->d_flags |= DCACHE_MOUNTED;
2319+ spin_unlock(&h_dentry->d_lock);
2320+}
2321+
2322+/* restore its d_flags */
2323+static void au_br_dflags_restore(struct au_branch *br)
2324+{
2325+ struct dentry *h_dentry;
2326+
2327+ if (br->br_dflags)
2328+ return;
2329+
2330+ h_dentry = au_br_dentry(br);
2331+ spin_lock(&h_dentry->d_lock);
2332+ h_dentry->d_flags &= ~DCACHE_MOUNTED;
2333+ spin_unlock(&h_dentry->d_lock);
2334+}
2335+
1facf9fc 2336+static void au_br_do_free(struct au_branch *br)
2337+{
2338+ int i;
2339+ struct au_wbr *wbr;
4a4d8108 2340+ struct au_dykey **key;
1facf9fc 2341+
027c5e7a
AM
2342+ au_hnotify_fin_br(br);
2343+
1facf9fc 2344+ if (br->br_xino.xi_file)
2345+ fput(br->br_xino.xi_file);
2346+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
2347+
2348+ AuDebugOn(atomic_read(&br->br_count));
2349+
2350+ wbr = br->br_wbr;
2351+ if (wbr) {
2352+ for (i = 0; i < AuBrWh_Last; i++)
2353+ dput(wbr->wbr_wh[i]);
2354+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 2355+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 2356+ }
2357+
4a4d8108
AM
2358+ key = br->br_dykey;
2359+ for (i = 0; i < AuBrDynOp; i++, key++)
2360+ if (*key)
2361+ au_dy_put(*key);
2362+ else
2363+ break;
2364+
86dc4139
AM
2365+ au_br_dflags_restore(br);
2366+
537831f9
AM
2367+ /* recursive lock, s_umount of branch's */
2368+ lockdep_off();
86dc4139 2369+ path_put(&br->br_path);
537831f9 2370+ lockdep_on();
1facf9fc 2371+ kfree(wbr);
2372+ kfree(br);
2373+}
2374+
2375+/*
2376+ * frees all branches
2377+ */
2378+void au_br_free(struct au_sbinfo *sbinfo)
2379+{
2380+ aufs_bindex_t bmax;
2381+ struct au_branch **br;
2382+
dece6358
AM
2383+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2384+
1facf9fc 2385+ bmax = sbinfo->si_bend + 1;
2386+ br = sbinfo->si_branch;
2387+ while (bmax--)
2388+ au_br_do_free(*br++);
2389+}
2390+
2391+/*
2392+ * find the index of a branch which is specified by @br_id.
2393+ */
2394+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2395+{
2396+ aufs_bindex_t bindex, bend;
2397+
2398+ bend = au_sbend(sb);
2399+ for (bindex = 0; bindex <= bend; bindex++)
2400+ if (au_sbr_id(sb, bindex) == br_id)
2401+ return bindex;
2402+ return -1;
2403+}
2404+
2405+/* ---------------------------------------------------------------------- */
2406+
2407+/*
2408+ * add a branch
2409+ */
2410+
b752ccd1
AM
2411+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2412+ struct dentry *h_root)
1facf9fc 2413+{
b752ccd1
AM
2414+ if (unlikely(h_adding == h_root
2415+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2416+ return 1;
b752ccd1
AM
2417+ if (h_adding->d_sb != h_root->d_sb)
2418+ return 0;
2419+ return au_test_subdir(h_adding, h_root)
2420+ || au_test_subdir(h_root, h_adding);
1facf9fc 2421+}
2422+
2423+/*
2424+ * returns a newly allocated branch. @new_nbranch is a number of branches
2425+ * after adding a branch.
2426+ */
2427+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2428+ int perm)
2429+{
2430+ struct au_branch *add_branch;
2431+ struct dentry *root;
4a4d8108 2432+ int err;
1facf9fc 2433+
4a4d8108 2434+ err = -ENOMEM;
1facf9fc 2435+ root = sb->s_root;
2436+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2437+ if (unlikely(!add_branch))
2438+ goto out;
2439+
027c5e7a
AM
2440+ err = au_hnotify_init_br(add_branch, perm);
2441+ if (unlikely(err))
2442+ goto out_br;
2443+
1facf9fc 2444+ add_branch->br_wbr = NULL;
2445+ if (au_br_writable(perm)) {
2446+ /* may be freed separately at changing the branch permission */
2447+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2448+ GFP_NOFS);
2449+ if (unlikely(!add_branch->br_wbr))
027c5e7a 2450+ goto out_hnotify;
1facf9fc 2451+ }
2452+
4a4d8108
AM
2453+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2454+ if (!err)
2455+ err = au_di_realloc(au_di(root), new_nbranch);
2456+ if (!err)
2457+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2458+ if (!err)
2459+ return add_branch; /* success */
1facf9fc 2460+
1facf9fc 2461+ kfree(add_branch->br_wbr);
4a4d8108 2462+
027c5e7a
AM
2463+out_hnotify:
2464+ au_hnotify_fin_br(add_branch);
4f0767ce 2465+out_br:
1facf9fc 2466+ kfree(add_branch);
4f0767ce 2467+out:
4a4d8108 2468+ return ERR_PTR(err);
1facf9fc 2469+}
2470+
2471+/*
2472+ * test if the branch permission is legal or not.
2473+ */
2474+static int test_br(struct inode *inode, int brperm, char *path)
2475+{
2476+ int err;
2477+
4a4d8108
AM
2478+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2479+ if (!err)
2480+ goto out;
1facf9fc 2481+
4a4d8108
AM
2482+ err = -EINVAL;
2483+ pr_err("write permission for readonly mount or inode, %s\n", path);
2484+
4f0767ce 2485+out:
1facf9fc 2486+ return err;
2487+}
2488+
2489+/*
2490+ * returns:
2491+ * 0: success, the caller will add it
2492+ * plus: success, it is already unified, the caller should ignore it
2493+ * minus: error
2494+ */
2495+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2496+{
2497+ int err;
2498+ aufs_bindex_t bend, bindex;
2499+ struct dentry *root;
2500+ struct inode *inode, *h_inode;
2501+
2502+ root = sb->s_root;
2503+ bend = au_sbend(sb);
2504+ if (unlikely(bend >= 0
2505+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2506+ err = 1;
2507+ if (!remount) {
2508+ err = -EINVAL;
4a4d8108 2509+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2510+ }
2511+ goto out;
2512+ }
2513+
2514+ err = -ENOSPC; /* -E2BIG; */
2515+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2516+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2517+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2518+ goto out;
2519+ }
2520+
2521+ err = -EDOM;
2522+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2523+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2524+ goto out;
2525+ }
2526+
2527+ inode = add->path.dentry->d_inode;
2528+ err = -ENOENT;
2529+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2530+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2531+ goto out;
2532+ }
2533+
2534+ err = -EINVAL;
2535+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2536+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2537+ goto out;
2538+ }
2539+
2540+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2541+ pr_err("unsupported filesystem, %s (%s)\n",
2542+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2543+ goto out;
2544+ }
2545+
2546+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2547+ if (unlikely(err))
2548+ goto out;
2549+
2550+ if (bend < 0)
2551+ return 0; /* success */
2552+
2553+ err = -EINVAL;
2554+ for (bindex = 0; bindex <= bend; bindex++)
2555+ if (unlikely(test_overlap(sb, add->path.dentry,
2556+ au_h_dptr(root, bindex)))) {
4a4d8108 2557+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 2558+ goto out;
2559+ }
2560+
2561+ err = 0;
2562+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2563+ h_inode = au_h_dptr(root, 0)->d_inode;
2564+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
2565+ || !uid_eq(h_inode->i_uid, inode->i_uid)
2566+ || !gid_eq(h_inode->i_gid, inode->i_gid))
2567+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2568+ add->pathname,
2569+ i_uid_read(inode), i_gid_read(inode),
2570+ (inode->i_mode & S_IALLUGO),
2571+ i_uid_read(h_inode), i_gid_read(h_inode),
2572+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 2573+ }
2574+
4f0767ce 2575+out:
1facf9fc 2576+ return err;
2577+}
2578+
2579+/*
2580+ * initialize or clean the whiteouts for an adding branch
2581+ */
2582+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 2583+ int new_perm)
1facf9fc 2584+{
2585+ int err, old_perm;
2586+ aufs_bindex_t bindex;
2587+ struct mutex *h_mtx;
2588+ struct au_wbr *wbr;
2589+ struct au_hinode *hdir;
2590+
86dc4139
AM
2591+ err = vfsub_mnt_want_write(au_br_mnt(br));
2592+ if (unlikely(err))
2593+ goto out;
2594+
1facf9fc 2595+ wbr = br->br_wbr;
2596+ old_perm = br->br_perm;
2597+ br->br_perm = new_perm;
2598+ hdir = NULL;
2599+ h_mtx = NULL;
2600+ bindex = au_br_index(sb, br->br_id);
2601+ if (0 <= bindex) {
2602+ hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 2603+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2604+ } else {
86dc4139 2605+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
1facf9fc 2606+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2607+ }
2608+ if (!wbr)
86dc4139 2609+ err = au_wh_init(br, sb);
1facf9fc 2610+ else {
2611+ wbr_wh_write_lock(wbr);
86dc4139 2612+ err = au_wh_init(br, sb);
1facf9fc 2613+ wbr_wh_write_unlock(wbr);
2614+ }
2615+ if (hdir)
4a4d8108 2616+ au_hn_imtx_unlock(hdir);
1facf9fc 2617+ else
2618+ mutex_unlock(h_mtx);
86dc4139 2619+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 2620+ br->br_perm = old_perm;
2621+
2622+ if (!err && wbr && !au_br_writable(new_perm)) {
2623+ kfree(wbr);
2624+ br->br_wbr = NULL;
2625+ }
2626+
86dc4139 2627+out:
1facf9fc 2628+ return err;
2629+}
2630+
2631+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 2632+ int perm)
1facf9fc 2633+{
2634+ int err;
4a4d8108 2635+ struct kstatfs kst;
1facf9fc 2636+ struct au_wbr *wbr;
2637+
2638+ wbr = br->br_wbr;
dece6358 2639+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 2640+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2641+ atomic_set(&wbr->wbr_wh_running, 0);
2642+ wbr->wbr_bytes = 0;
2643+
4a4d8108
AM
2644+ /*
2645+ * a limit for rmdir/rename a dir
523b37e3 2646+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 2647+ */
86dc4139 2648+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
2649+ if (unlikely(err))
2650+ goto out;
2651+ err = -EINVAL;
2652+ if (kst.f_namelen >= NAME_MAX)
86dc4139 2653+ err = au_br_init_wh(sb, br, perm);
4a4d8108 2654+ else
523b37e3
AM
2655+ pr_err("%pd(%s), unsupported namelen %ld\n",
2656+ au_br_dentry(br),
86dc4139 2657+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 2658+
4f0767ce 2659+out:
1facf9fc 2660+ return err;
2661+}
2662+
2663+/* intialize a new branch */
2664+static int au_br_init(struct au_branch *br, struct super_block *sb,
2665+ struct au_opt_add *add)
2666+{
2667+ int err;
2668+
2669+ err = 0;
2670+ memset(&br->br_xino, 0, sizeof(br->br_xino));
2671+ mutex_init(&br->br_xino.xi_nondir_mtx);
2672+ br->br_perm = add->perm;
86dc4139
AM
2673+ BUILD_BUG_ON(sizeof(br->br_dflags)
2674+ != sizeof(br->br_path.dentry->d_flags));
2675+ br->br_dflags = DCACHE_MOUNTED;
2676+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108
AM
2677+ spin_lock_init(&br->br_dykey_lock);
2678+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 2679+ atomic_set(&br->br_count, 0);
1facf9fc 2680+ atomic_set(&br->br_xino_running, 0);
2681+ br->br_id = au_new_br_id(sb);
7f207e10 2682+ AuDebugOn(br->br_id < 0);
1facf9fc 2683+
2684+ if (au_br_writable(add->perm)) {
86dc4139 2685+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 2686+ if (unlikely(err))
b752ccd1 2687+ goto out_err;
1facf9fc 2688+ }
2689+
2690+ if (au_opt_test(au_mntflags(sb), XINO)) {
2691+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
2692+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
2693+ if (unlikely(err)) {
2694+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 2695+ goto out_err;
1facf9fc 2696+ }
2697+ }
2698+
2699+ sysaufs_br_init(br);
86dc4139 2700+ path_get(&br->br_path);
b752ccd1 2701+ goto out; /* success */
1facf9fc 2702+
4f0767ce 2703+out_err:
86dc4139 2704+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 2705+out:
1facf9fc 2706+ return err;
2707+}
2708+
2709+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
2710+ struct au_branch *br, aufs_bindex_t bend,
2711+ aufs_bindex_t amount)
2712+{
2713+ struct au_branch **brp;
2714+
dece6358
AM
2715+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2716+
1facf9fc 2717+ brp = sbinfo->si_branch + bindex;
2718+ memmove(brp + 1, brp, sizeof(*brp) * amount);
2719+ *brp = br;
2720+ sbinfo->si_bend++;
2721+ if (unlikely(bend < 0))
2722+ sbinfo->si_bend = 0;
2723+}
2724+
2725+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
2726+ aufs_bindex_t bend, aufs_bindex_t amount)
2727+{
2728+ struct au_hdentry *hdp;
2729+
1308ab2a 2730+ AuRwMustWriteLock(&dinfo->di_rwsem);
2731+
1facf9fc 2732+ hdp = dinfo->di_hdentry + bindex;
2733+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
2734+ au_h_dentry_init(hdp);
2735+ dinfo->di_bend++;
2736+ if (unlikely(bend < 0))
2737+ dinfo->di_bstart = 0;
2738+}
2739+
2740+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
2741+ aufs_bindex_t bend, aufs_bindex_t amount)
2742+{
2743+ struct au_hinode *hip;
2744+
1308ab2a 2745+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2746+
1facf9fc 2747+ hip = iinfo->ii_hinode + bindex;
2748+ memmove(hip + 1, hip, sizeof(*hip) * amount);
2749+ hip->hi_inode = NULL;
4a4d8108 2750+ au_hn_init(hip);
1facf9fc 2751+ iinfo->ii_bend++;
2752+ if (unlikely(bend < 0))
2753+ iinfo->ii_bstart = 0;
2754+}
2755+
86dc4139
AM
2756+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
2757+ aufs_bindex_t bindex)
1facf9fc 2758+{
86dc4139 2759+ struct dentry *root, *h_dentry;
1facf9fc 2760+ struct inode *root_inode;
2761+ aufs_bindex_t bend, amount;
2762+
86dc4139
AM
2763+ au_br_dflags_force(br);
2764+
1facf9fc 2765+ root = sb->s_root;
2766+ root_inode = root->d_inode;
1facf9fc 2767+ bend = au_sbend(sb);
2768+ amount = bend + 1 - bindex;
86dc4139 2769+ h_dentry = au_br_dentry(br);
53392da6 2770+ au_sbilist_lock();
1facf9fc 2771+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
2772+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
2773+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
2774+ au_set_h_dptr(root, bindex, dget(h_dentry));
2775+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
2776+ /*flags*/0);
53392da6 2777+ au_sbilist_unlock();
1facf9fc 2778+}
2779+
2780+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
2781+{
2782+ int err;
1facf9fc 2783+ aufs_bindex_t bend, add_bindex;
2784+ struct dentry *root, *h_dentry;
2785+ struct inode *root_inode;
2786+ struct au_branch *add_branch;
2787+
2788+ root = sb->s_root;
2789+ root_inode = root->d_inode;
2790+ IMustLock(root_inode);
2791+ err = test_add(sb, add, remount);
2792+ if (unlikely(err < 0))
2793+ goto out;
2794+ if (err) {
2795+ err = 0;
2796+ goto out; /* success */
2797+ }
2798+
2799+ bend = au_sbend(sb);
2800+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
2801+ err = PTR_ERR(add_branch);
2802+ if (IS_ERR(add_branch))
2803+ goto out;
2804+
2805+ err = au_br_init(add_branch, sb, add);
2806+ if (unlikely(err)) {
2807+ au_br_do_free(add_branch);
2808+ goto out;
2809+ }
2810+
2811+ add_bindex = add->bindex;
1facf9fc 2812+ if (!remount)
86dc4139 2813+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 2814+ else {
2815+ sysaufs_brs_del(sb, add_bindex);
86dc4139 2816+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 2817+ sysaufs_brs_add(sb, add_bindex);
2818+ }
2819+
86dc4139 2820+ h_dentry = add->path.dentry;
1308ab2a 2821+ if (!add_bindex) {
1facf9fc 2822+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 2823+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
2824+ } else
1facf9fc 2825+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 2826+
2827+ /*
4a4d8108 2828+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 2829+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 2830+ * once detached from aufs.
2831+ */
2832+ if (au_xino_brid(sb) < 0
2833+ && au_br_writable(add_branch->br_perm)
2834+ && !au_test_fs_bad_xino(h_dentry->d_sb)
2835+ && add_branch->br_xino.xi_file
2836+ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
2837+ au_xino_brid_set(sb, add_branch->br_id);
2838+
4f0767ce 2839+out:
1facf9fc 2840+ return err;
2841+}
2842+
2843+/* ---------------------------------------------------------------------- */
2844+
2845+/*
2846+ * delete a branch
2847+ */
2848+
2849+/* to show the line number, do not make it inlined function */
4a4d8108 2850+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 2851+ if (do_info) \
4a4d8108 2852+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 2853+} while (0)
2854+
027c5e7a
AM
2855+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
2856+ aufs_bindex_t bend)
2857+{
2858+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
2859+}
2860+
2861+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
2862+ aufs_bindex_t bend)
2863+{
2864+ return au_test_ibusy(dentry->d_inode, bstart, bend);
2865+}
2866+
1facf9fc 2867+/*
2868+ * test if the branch is deletable or not.
2869+ */
2870+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 2871+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2872+{
2873+ int err, i, j, ndentry;
2874+ aufs_bindex_t bstart, bend;
1facf9fc 2875+ struct au_dcsub_pages dpages;
2876+ struct au_dpage *dpage;
2877+ struct dentry *d;
1facf9fc 2878+
2879+ err = au_dpages_init(&dpages, GFP_NOFS);
2880+ if (unlikely(err))
2881+ goto out;
2882+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
2883+ if (unlikely(err))
2884+ goto out_dpages;
2885+
1facf9fc 2886+ for (i = 0; !err && i < dpages.ndpage; i++) {
2887+ dpage = dpages.dpages + i;
2888+ ndentry = dpage->ndentry;
2889+ for (j = 0; !err && j < ndentry; j++) {
2890+ d = dpage->dentries[j];
392086de 2891+ AuDebugOn(!d_count(d));
027c5e7a 2892+ if (!au_digen_test(d, sigen)) {
1facf9fc 2893+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
2894+ if (unlikely(au_dbrange_test(d))) {
2895+ di_read_unlock(d, AuLock_IR);
2896+ continue;
2897+ }
2898+ } else {
1facf9fc 2899+ di_write_lock_child(d);
027c5e7a
AM
2900+ if (unlikely(au_dbrange_test(d))) {
2901+ di_write_unlock(d);
2902+ continue;
2903+ }
1facf9fc 2904+ err = au_reval_dpath(d, sigen);
2905+ if (!err)
2906+ di_downgrade_lock(d, AuLock_IR);
2907+ else {
2908+ di_write_unlock(d);
2909+ break;
2910+ }
2911+ }
2912+
027c5e7a 2913+ /* AuDbgDentry(d); */
1facf9fc 2914+ bstart = au_dbstart(d);
2915+ bend = au_dbend(d);
2916+ if (bstart <= bindex
2917+ && bindex <= bend
2918+ && au_h_dptr(d, bindex)
027c5e7a 2919+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 2920+ err = -EBUSY;
523b37e3 2921+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 2922+ AuDbgDentry(d);
1facf9fc 2923+ }
2924+ di_read_unlock(d, AuLock_IR);
2925+ }
2926+ }
2927+
4f0767ce 2928+out_dpages:
1facf9fc 2929+ au_dpages_free(&dpages);
4f0767ce 2930+out:
1facf9fc 2931+ return err;
2932+}
2933+
2934+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 2935+ unsigned int sigen, const unsigned int verbose)
1facf9fc 2936+{
2937+ int err;
7f207e10
AM
2938+ unsigned long long max, ull;
2939+ struct inode *i, **array;
1facf9fc 2940+ aufs_bindex_t bstart, bend;
1facf9fc 2941+
7f207e10
AM
2942+ array = au_iarray_alloc(sb, &max);
2943+ err = PTR_ERR(array);
2944+ if (IS_ERR(array))
2945+ goto out;
2946+
1facf9fc 2947+ err = 0;
7f207e10
AM
2948+ AuDbg("b%d\n", bindex);
2949+ for (ull = 0; !err && ull < max; ull++) {
2950+ i = array[ull];
2951+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 2952+ continue;
2953+
7f207e10 2954+ /* AuDbgInode(i); */
537831f9 2955+ if (au_iigen(i, NULL) == sigen)
1facf9fc 2956+ ii_read_lock_child(i);
2957+ else {
2958+ ii_write_lock_child(i);
027c5e7a
AM
2959+ err = au_refresh_hinode_self(i);
2960+ au_iigen_dec(i);
1facf9fc 2961+ if (!err)
2962+ ii_downgrade_lock(i);
2963+ else {
2964+ ii_write_unlock(i);
2965+ break;
2966+ }
2967+ }
2968+
2969+ bstart = au_ibstart(i);
2970+ bend = au_ibend(i);
2971+ if (bstart <= bindex
2972+ && bindex <= bend
2973+ && au_h_iptr(i, bindex)
027c5e7a 2974+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 2975+ err = -EBUSY;
2976+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 2977+ AuDbgInode(i);
1facf9fc 2978+ }
2979+ ii_read_unlock(i);
2980+ }
7f207e10 2981+ au_iarray_free(array, max);
1facf9fc 2982+
7f207e10 2983+out:
1facf9fc 2984+ return err;
2985+}
2986+
b752ccd1
AM
2987+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
2988+ const unsigned int verbose)
1facf9fc 2989+{
2990+ int err;
2991+ unsigned int sigen;
2992+
2993+ sigen = au_sigen(root->d_sb);
2994+ DiMustNoWaiters(root);
2995+ IiMustNoWaiters(root->d_inode);
2996+ di_write_unlock(root);
b752ccd1 2997+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 2998+ if (!err)
b752ccd1 2999+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3000+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3001+
3002+ return err;
3003+}
3004+
3005+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
3006+ const aufs_bindex_t bindex,
3007+ const aufs_bindex_t bend)
3008+{
3009+ struct au_branch **brp, **p;
3010+
dece6358
AM
3011+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3012+
1facf9fc 3013+ brp = sbinfo->si_branch + bindex;
3014+ if (bindex < bend)
3015+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
3016+ sbinfo->si_branch[0 + bend] = NULL;
3017+ sbinfo->si_bend--;
3018+
53392da6 3019+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3020+ if (p)
3021+ sbinfo->si_branch = p;
4a4d8108 3022+ /* harmless error */
1facf9fc 3023+}
3024+
3025+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
3026+ const aufs_bindex_t bend)
3027+{
3028+ struct au_hdentry *hdp, *p;
3029+
1308ab2a 3030+ AuRwMustWriteLock(&dinfo->di_rwsem);
3031+
4a4d8108 3032+ hdp = dinfo->di_hdentry;
1facf9fc 3033+ if (bindex < bend)
4a4d8108
AM
3034+ memmove(hdp + bindex, hdp + bindex + 1,
3035+ sizeof(*hdp) * (bend - bindex));
3036+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 3037+ dinfo->di_bend--;
3038+
53392da6 3039+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3040+ if (p)
3041+ dinfo->di_hdentry = p;
4a4d8108 3042+ /* harmless error */
1facf9fc 3043+}
3044+
3045+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
3046+ const aufs_bindex_t bend)
3047+{
3048+ struct au_hinode *hip, *p;
3049+
1308ab2a 3050+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3051+
1facf9fc 3052+ hip = iinfo->ii_hinode + bindex;
3053+ if (bindex < bend)
3054+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
3055+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 3056+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 3057+ iinfo->ii_bend--;
3058+
53392da6 3059+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3060+ if (p)
3061+ iinfo->ii_hinode = p;
4a4d8108 3062+ /* harmless error */
1facf9fc 3063+}
3064+
3065+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
3066+ struct au_branch *br)
3067+{
3068+ aufs_bindex_t bend;
3069+ struct au_sbinfo *sbinfo;
53392da6
AM
3070+ struct dentry *root, *h_root;
3071+ struct inode *inode, *h_inode;
3072+ struct au_hinode *hinode;
1facf9fc 3073+
dece6358
AM
3074+ SiMustWriteLock(sb);
3075+
1facf9fc 3076+ root = sb->s_root;
3077+ inode = root->d_inode;
1facf9fc 3078+ sbinfo = au_sbi(sb);
3079+ bend = sbinfo->si_bend;
3080+
53392da6
AM
3081+ h_root = au_h_dptr(root, bindex);
3082+ hinode = au_hi(inode, bindex);
3083+ h_inode = au_igrab(hinode->hi_inode);
3084+ au_hiput(hinode);
1facf9fc 3085+
53392da6 3086+ au_sbilist_lock();
1facf9fc 3087+ au_br_do_del_brp(sbinfo, bindex, bend);
3088+ au_br_do_del_hdp(au_di(root), bindex, bend);
3089+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
3090+ au_sbilist_unlock();
3091+
3092+ dput(h_root);
3093+ iput(h_inode);
3094+ au_br_do_free(br);
1facf9fc 3095+}
3096+
3097+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
3098+{
3099+ int err, rerr, i;
3100+ unsigned int mnt_flags;
3101+ aufs_bindex_t bindex, bend, br_id;
3102+ unsigned char do_wh, verbose;
3103+ struct au_branch *br;
3104+ struct au_wbr *wbr;
3105+
3106+ err = 0;
3107+ bindex = au_find_dbindex(sb->s_root, del->h_path.dentry);
3108+ if (bindex < 0) {
3109+ if (remount)
3110+ goto out; /* success */
3111+ err = -ENOENT;
4a4d8108 3112+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 3113+ goto out;
3114+ }
3115+ AuDbg("bindex b%d\n", bindex);
3116+
3117+ err = -EBUSY;
3118+ mnt_flags = au_mntflags(sb);
3119+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3120+ bend = au_sbend(sb);
3121+ if (unlikely(!bend)) {
3122+ AuVerbose(verbose, "no more branches left\n");
3123+ goto out;
3124+ }
3125+ br = au_sbr(sb, bindex);
86dc4139 3126+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
1facf9fc 3127+ i = atomic_read(&br->br_count);
3128+ if (unlikely(i)) {
3129+ AuVerbose(verbose, "%d file(s) opened\n", i);
e49829fe 3130+ goto out;
1facf9fc 3131+ }
3132+
3133+ wbr = br->br_wbr;
3134+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
3135+ if (do_wh) {
1308ab2a 3136+ /* instead of WbrWhMustWriteLock(wbr) */
3137+ SiMustWriteLock(sb);
1facf9fc 3138+ for (i = 0; i < AuBrWh_Last; i++) {
3139+ dput(wbr->wbr_wh[i]);
3140+ wbr->wbr_wh[i] = NULL;
3141+ }
3142+ }
3143+
b752ccd1 3144+ err = test_children_busy(sb->s_root, bindex, verbose);
1facf9fc 3145+ if (unlikely(err)) {
3146+ if (do_wh)
3147+ goto out_wh;
3148+ goto out;
3149+ }
3150+
3151+ err = 0;
3152+ br_id = br->br_id;
3153+ if (!remount)
3154+ au_br_do_del(sb, bindex, br);
3155+ else {
3156+ sysaufs_brs_del(sb, bindex);
3157+ au_br_do_del(sb, bindex, br);
3158+ sysaufs_brs_add(sb, bindex);
3159+ }
3160+
1308ab2a 3161+ if (!bindex) {
1facf9fc 3162+ au_cpup_attr_all(sb->s_root->d_inode, /*force*/1);
1308ab2a 3163+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
3164+ } else
1facf9fc 3165+ au_sub_nlink(sb->s_root->d_inode, del->h_path.dentry->d_inode);
3166+ if (au_opt_test(mnt_flags, PLINK))
3167+ au_plink_half_refresh(sb, br_id);
3168+
b752ccd1 3169+ if (au_xino_brid(sb) == br_id)
1facf9fc 3170+ au_xino_brid_set(sb, -1);
3171+ goto out; /* success */
3172+
4f0767ce 3173+out_wh:
1facf9fc 3174+ /* revert */
86dc4139 3175+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 3176+ if (rerr)
0c3ec466
AM
3177+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
3178+ del->pathname, rerr);
4f0767ce 3179+out:
1facf9fc 3180+ return err;
3181+}
3182+
3183+/* ---------------------------------------------------------------------- */
3184+
027c5e7a
AM
3185+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
3186+{
3187+ int err;
3188+ aufs_bindex_t bstart, bend;
3189+ struct aufs_ibusy ibusy;
3190+ struct inode *inode, *h_inode;
3191+
3192+ err = -EPERM;
3193+ if (unlikely(!capable(CAP_SYS_ADMIN)))
3194+ goto out;
3195+
3196+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
3197+ if (!err)
3198+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
3199+ if (unlikely(err)) {
3200+ err = -EFAULT;
3201+ AuTraceErr(err);
3202+ goto out;
3203+ }
3204+
3205+ err = -EINVAL;
3206+ si_read_lock(sb, AuLock_FLUSH);
3207+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
3208+ goto out_unlock;
3209+
3210+ err = 0;
3211+ ibusy.h_ino = 0; /* invalid */
3212+ inode = ilookup(sb, ibusy.ino);
3213+ if (!inode
3214+ || inode->i_ino == AUFS_ROOT_INO
3215+ || is_bad_inode(inode))
3216+ goto out_unlock;
3217+
3218+ ii_read_lock_child(inode);
3219+ bstart = au_ibstart(inode);
3220+ bend = au_ibend(inode);
3221+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
3222+ h_inode = au_h_iptr(inode, ibusy.bindex);
3223+ if (h_inode && au_test_ibusy(inode, bstart, bend))
3224+ ibusy.h_ino = h_inode->i_ino;
3225+ }
3226+ ii_read_unlock(inode);
3227+ iput(inode);
3228+
3229+out_unlock:
3230+ si_read_unlock(sb);
3231+ if (!err) {
3232+ err = __put_user(ibusy.h_ino, &arg->h_ino);
3233+ if (unlikely(err)) {
3234+ err = -EFAULT;
3235+ AuTraceErr(err);
3236+ }
3237+ }
3238+out:
3239+ return err;
3240+}
3241+
3242+long au_ibusy_ioctl(struct file *file, unsigned long arg)
3243+{
3244+ return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
3245+}
3246+
3247+#ifdef CONFIG_COMPAT
3248+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
3249+{
3250+ return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
3251+}
3252+#endif
3253+
3254+/* ---------------------------------------------------------------------- */
3255+
1facf9fc 3256+/*
3257+ * change a branch permission
3258+ */
3259+
dece6358
AM
3260+static void au_warn_ima(void)
3261+{
3262+#ifdef CONFIG_IMA
1308ab2a 3263+ /* since it doesn't support mark_files_ro() */
027c5e7a 3264+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
3265+#endif
3266+}
3267+
1facf9fc 3268+static int do_need_sigen_inc(int a, int b)
3269+{
3270+ return au_br_whable(a) && !au_br_whable(b);
3271+}
3272+
3273+static int need_sigen_inc(int old, int new)
3274+{
3275+ return do_need_sigen_inc(old, new)
3276+ || do_need_sigen_inc(new, old);
3277+}
3278+
7f207e10
AM
3279+static unsigned long long au_farray_cb(void *a,
3280+ unsigned long long max __maybe_unused,
3281+ void *arg)
3282+{
3283+ unsigned long long n;
3284+ struct file **p, *f;
523b37e3
AM
3285+ struct au_sphlhead *files;
3286+ struct au_finfo *finfo;
7f207e10
AM
3287+ struct super_block *sb = arg;
3288+
3289+ n = 0;
3290+ p = a;
523b37e3
AM
3291+ files = &au_sbi(sb)->si_files;
3292+ spin_lock(&files->spin);
3293+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
3294+ f = finfo->fi_file;
3295+ if (file_count(f)
c06a8ce3 3296+ && !special_file(file_inode(f)->i_mode)) {
7f207e10
AM
3297+ get_file(f);
3298+ *p++ = f;
3299+ n++;
3300+ AuDebugOn(n > max);
3301+ }
523b37e3
AM
3302+ }
3303+ spin_unlock(&files->spin);
7f207e10
AM
3304+
3305+ return n;
3306+}
3307+
3308+static struct file **au_farray_alloc(struct super_block *sb,
3309+ unsigned long long *max)
3310+{
3311+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
3312+ return au_array_alloc(max, au_farray_cb, sb);
3313+}
3314+
3315+static void au_farray_free(struct file **a, unsigned long long max)
3316+{
3317+ unsigned long long ull;
3318+
3319+ for (ull = 0; ull < max; ull++)
3320+ if (a[ull])
3321+ fput(a[ull]);
3322+ au_array_free(a);
3323+}
3324+
1facf9fc 3325+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
3326+{
7f207e10 3327+ int err, do_warn;
027c5e7a 3328+ unsigned int mnt_flags;
7f207e10 3329+ unsigned long long ull, max;
e49829fe 3330+ aufs_bindex_t br_id;
027c5e7a 3331+ unsigned char verbose;
7f207e10 3332+ struct file *file, *hf, **array;
e49829fe
JR
3333+ struct inode *inode;
3334+ struct au_hfile *hfile;
1facf9fc 3335+
027c5e7a
AM
3336+ mnt_flags = au_mntflags(sb);
3337+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3338+
7f207e10
AM
3339+ array = au_farray_alloc(sb, &max);
3340+ err = PTR_ERR(array);
3341+ if (IS_ERR(array))
1facf9fc 3342+ goto out;
3343+
7f207e10 3344+ do_warn = 0;
e49829fe 3345+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
3346+ for (ull = 0; ull < max; ull++) {
3347+ file = array[ull];
1facf9fc 3348+
523b37e3 3349+ /* AuDbg("%pD\n", file); */
1facf9fc 3350+ fi_read_lock(file);
3351+ if (unlikely(au_test_mmapped(file))) {
3352+ err = -EBUSY;
523b37e3 3353+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 3354+ AuDbgFile(file);
1facf9fc 3355+ FiMustNoWaiters(file);
3356+ fi_read_unlock(file);
7f207e10 3357+ goto out_array;
1facf9fc 3358+ }
3359+
c06a8ce3 3360+ inode = file_inode(file);
e49829fe
JR
3361+ hfile = &au_fi(file)->fi_htop;
3362+ hf = hfile->hf_file;
3363+ if (!S_ISREG(inode->i_mode)
1facf9fc 3364+ || !(file->f_mode & FMODE_WRITE)
e49829fe 3365+ || hfile->hf_br->br_id != br_id
7f207e10
AM
3366+ || !(hf->f_mode & FMODE_WRITE))
3367+ array[ull] = NULL;
3368+ else {
3369+ do_warn = 1;
3370+ get_file(file);
1facf9fc 3371+ }
3372+
1facf9fc 3373+ FiMustNoWaiters(file);
3374+ fi_read_unlock(file);
7f207e10
AM
3375+ fput(file);
3376+ }
1facf9fc 3377+
3378+ err = 0;
7f207e10 3379+ if (do_warn)
dece6358 3380+ au_warn_ima();
7f207e10
AM
3381+
3382+ for (ull = 0; ull < max; ull++) {
3383+ file = array[ull];
3384+ if (!file)
3385+ continue;
3386+
1facf9fc 3387+ /* todo: already flushed? */
523b37e3
AM
3388+ /*
3389+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
3390+ * approach which resets f_mode and calls mnt_drop_write() and
3391+ * file_release_write() for each file, because the branch
3392+ * attribute in aufs world is totally different from the native
3393+ * fs rw/ro mode.
3394+ */
7f207e10
AM
3395+ /* fi_read_lock(file); */
3396+ hfile = &au_fi(file)->fi_htop;
3397+ hf = hfile->hf_file;
3398+ /* fi_read_unlock(file); */
027c5e7a 3399+ spin_lock(&hf->f_lock);
1facf9fc 3400+ hf->f_mode &= ~FMODE_WRITE;
027c5e7a 3401+ spin_unlock(&hf->f_lock);
1facf9fc 3402+ if (!file_check_writeable(hf)) {
c06a8ce3 3403+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 3404+ file_release_write(hf);
1facf9fc 3405+ }
3406+ }
3407+
7f207e10
AM
3408+out_array:
3409+ au_farray_free(array, max);
4f0767ce 3410+out:
7f207e10 3411+ AuTraceErr(err);
1facf9fc 3412+ return err;
3413+}
3414+
3415+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3416+ int *do_refresh)
1facf9fc 3417+{
3418+ int err, rerr;
3419+ aufs_bindex_t bindex;
3420+ struct dentry *root;
3421+ struct au_branch *br;
3422+
3423+ root = sb->s_root;
1facf9fc 3424+ bindex = au_find_dbindex(root, mod->h_root);
3425+ if (bindex < 0) {
3426+ if (remount)
3427+ return 0; /* success */
3428+ err = -ENOENT;
4a4d8108 3429+ pr_err("%s no such branch\n", mod->path);
1facf9fc 3430+ goto out;
3431+ }
3432+ AuDbg("bindex b%d\n", bindex);
3433+
3434+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3435+ if (unlikely(err))
3436+ goto out;
3437+
3438+ br = au_sbr(sb, bindex);
86dc4139 3439+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 3440+ if (br->br_perm == mod->perm)
3441+ return 0; /* success */
3442+
3443+ if (au_br_writable(br->br_perm)) {
3444+ /* remove whiteout base */
86dc4139 3445+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 3446+ if (unlikely(err))
3447+ goto out;
3448+
3449+ if (!au_br_writable(mod->perm)) {
3450+ /* rw --> ro, file might be mmapped */
3451+ DiMustNoWaiters(root);
3452+ IiMustNoWaiters(root->d_inode);
3453+ di_write_unlock(root);
3454+ err = au_br_mod_files_ro(sb, bindex);
3455+ /* aufs_write_lock() calls ..._child() */
3456+ di_write_lock_child(root);
3457+
3458+ if (unlikely(err)) {
3459+ rerr = -ENOMEM;
3460+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
3461+ GFP_NOFS);
86dc4139
AM
3462+ if (br->br_wbr)
3463+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 3464+ if (unlikely(rerr)) {
3465+ AuIOErr("nested error %d (%d)\n",
3466+ rerr, err);
3467+ br->br_perm = mod->perm;
3468+ }
3469+ }
3470+ }
3471+ } else if (au_br_writable(mod->perm)) {
3472+ /* ro --> rw */
3473+ err = -ENOMEM;
3474+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
3475+ if (br->br_wbr) {
86dc4139 3476+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 3477+ if (unlikely(err)) {
3478+ kfree(br->br_wbr);
3479+ br->br_wbr = NULL;
3480+ }
3481+ }
3482+ }
3483+
3484+ if (!err) {
86dc4139
AM
3485+ if ((br->br_perm & AuBrAttr_UNPIN)
3486+ && !(mod->perm & AuBrAttr_UNPIN))
3487+ au_br_dflags_force(br);
3488+ else if (!(br->br_perm & AuBrAttr_UNPIN)
3489+ && (mod->perm & AuBrAttr_UNPIN))
3490+ au_br_dflags_restore(br);
7f207e10 3491+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
1facf9fc 3492+ br->br_perm = mod->perm;
3493+ }
3494+
4f0767ce 3495+out:
7f207e10 3496+ AuTraceErr(err);
1facf9fc 3497+ return err;
3498+}
7f207e10
AM
3499diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
3500--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 3501+++ linux/fs/aufs/branch.h 2014-04-24 22:11:10.848602379 +0200
523b37e3 3502@@ -0,0 +1,264 @@
1facf9fc 3503+/*
523b37e3 3504+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 3505+ *
3506+ * This program, aufs is free software; you can redistribute it and/or modify
3507+ * it under the terms of the GNU General Public License as published by
3508+ * the Free Software Foundation; either version 2 of the License, or
3509+ * (at your option) any later version.
dece6358
AM
3510+ *
3511+ * This program is distributed in the hope that it will be useful,
3512+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3513+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3514+ * GNU General Public License for more details.
3515+ *
3516+ * You should have received a copy of the GNU General Public License
523b37e3 3517+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 3518+ */
3519+
3520+/*
3521+ * branch filesystems and xino for them
3522+ */
3523+
3524+#ifndef __AUFS_BRANCH_H__
3525+#define __AUFS_BRANCH_H__
3526+
3527+#ifdef __KERNEL__
3528+
1facf9fc 3529+#include <linux/mount.h>
4a4d8108 3530+#include "dynop.h"
1facf9fc 3531+#include "rwsem.h"
3532+#include "super.h"
3533+
3534+/* ---------------------------------------------------------------------- */
3535+
3536+/* a xino file */
3537+struct au_xino_file {
3538+ struct file *xi_file;
3539+ struct mutex xi_nondir_mtx;
3540+
3541+ /* todo: make xino files an array to support huge inode number */
3542+
3543+#ifdef CONFIG_DEBUG_FS
3544+ struct dentry *xi_dbgaufs;
3545+#endif
3546+};
3547+
3548+/* members for writable branch only */
3549+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
3550+struct au_wbr {
dece6358 3551+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 3552+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 3553+ atomic_t wbr_wh_running;
1facf9fc 3554+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
3555+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
3556+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
3557+
3558+ /* mfs mode */
3559+ unsigned long long wbr_bytes;
3560+};
3561+
4a4d8108
AM
3562+/* ext2 has 3 types of operations at least, ext3 has 4 */
3563+#define AuBrDynOp (AuDyLast * 4)
3564+
1716fcea
AM
3565+#ifdef CONFIG_AUFS_HFSNOTIFY
3566+/* support for asynchronous destruction */
3567+struct au_br_hfsnotify {
3568+ struct fsnotify_group *hfsn_group;
3569+};
3570+#endif
3571+
392086de
AM
3572+/* sysfs entries */
3573+struct au_brsysfs {
3574+ char name[16];
3575+ struct attribute attr;
3576+};
3577+
3578+enum {
3579+ AuBrSysfs_BR,
3580+ AuBrSysfs_BRID,
3581+ AuBrSysfs_Last
3582+};
3583+
1facf9fc 3584+/* protected by superblock rwsem */
3585+struct au_branch {
3586+ struct au_xino_file br_xino;
3587+
3588+ aufs_bindex_t br_id;
3589+
3590+ int br_perm;
86dc4139
AM
3591+ unsigned int br_dflags;
3592+ struct path br_path;
4a4d8108
AM
3593+ spinlock_t br_dykey_lock;
3594+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 3595+ atomic_t br_count;
3596+
3597+ struct au_wbr *br_wbr;
3598+
3599+ /* xino truncation */
1facf9fc 3600+ atomic_t br_xino_running;
3601+
027c5e7a 3602+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 3603+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
3604+#endif
3605+
1facf9fc 3606+#ifdef CONFIG_SYSFS
392086de
AM
3607+ /* entries under sysfs per mount-point */
3608+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 3609+#endif
3610+};
3611+
3612+/* ---------------------------------------------------------------------- */
3613+
86dc4139
AM
3614+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
3615+{
3616+ return br->br_path.mnt;
3617+}
3618+
3619+static inline struct dentry *au_br_dentry(struct au_branch *br)
3620+{
3621+ return br->br_path.dentry;
3622+}
3623+
3624+static inline struct super_block *au_br_sb(struct au_branch *br)
3625+{
3626+ return au_br_mnt(br)->mnt_sb;
3627+}
3628+
1e00d052
AM
3629+/* branch permissions and attributes */
3630+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
3631+#define AuBrPerm_RO (1 << 1) /* readonly */
3632+#define AuBrPerm_RR (1 << 2) /* natively readonly */
3633+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
1facf9fc 3634+
1e00d052 3635+#define AuBrRAttr_WH (1 << 3) /* whiteout-able */
1facf9fc 3636+
1e00d052 3637+#define AuBrWAttr_NoLinkWH (1 << 4) /* un-hardlinkable whiteouts */
1facf9fc 3638+
86dc4139
AM
3639+#define AuBrAttr_UNPIN (1 << 5) /* rename-able top dir of
3640+ branch */
3641+
1facf9fc 3642+static inline int au_br_writable(int brperm)
3643+{
1e00d052 3644+ return brperm & AuBrPerm_RW;
1facf9fc 3645+}
3646+
3647+static inline int au_br_whable(int brperm)
3648+{
1e00d052
AM
3649+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
3650+}
3651+
3652+static inline int au_br_wh_linkable(int brperm)
3653+{
3654+ return !(brperm & AuBrWAttr_NoLinkWH);
1facf9fc 3655+}
3656+
3657+static inline int au_br_rdonly(struct au_branch *br)
3658+{
86dc4139 3659+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 3660+ || !au_br_writable(br->br_perm))
3661+ ? -EROFS : 0;
3662+}
3663+
4a4d8108 3664+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 3665+{
4a4d8108 3666+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 3667+ return !(brperm & AuBrPerm_RR);
1facf9fc 3668+#else
3669+ return 0;
3670+#endif
3671+}
3672+
3673+/* ---------------------------------------------------------------------- */
3674+
3675+/* branch.c */
3676+struct au_sbinfo;
3677+void au_br_free(struct au_sbinfo *sinfo);
3678+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
3679+struct au_opt_add;
3680+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
3681+struct au_opt_del;
3682+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
3683+long au_ibusy_ioctl(struct file *file, unsigned long arg);
3684+#ifdef CONFIG_COMPAT
3685+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
3686+#endif
1facf9fc 3687+struct au_opt_mod;
3688+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3689+ int *do_refresh);
1facf9fc 3690+
3691+/* xino.c */
3692+static const loff_t au_loff_max = LLONG_MAX;
3693+
3694+int au_xib_trunc(struct super_block *sb);
3695+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
3696+ loff_t *pos);
3697+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
3698+ loff_t *pos);
3699+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
3700+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
3701+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 3702+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 3703+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3704+ ino_t ino);
3705+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
3706+ ino_t *ino);
3707+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
3708+ struct file *base_file, int do_test);
3709+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
3710+
3711+struct au_opt_xino;
3712+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
3713+void au_xino_clr(struct super_block *sb);
3714+struct file *au_xino_def(struct super_block *sb);
3715+int au_xino_path(struct seq_file *seq, struct file *file);
3716+
3717+/* ---------------------------------------------------------------------- */
3718+
3719+/* Superblock to branch */
3720+static inline
3721+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
3722+{
3723+ return au_sbr(sb, bindex)->br_id;
3724+}
3725+
3726+static inline
3727+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
3728+{
86dc4139 3729+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 3730+}
3731+
3732+static inline
3733+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
3734+{
86dc4139 3735+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 3736+}
3737+
3738+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
3739+{
e49829fe 3740+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 3741+}
3742+
3743+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
3744+{
3745+ return au_sbr(sb, bindex)->br_perm;
3746+}
3747+
3748+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
3749+{
3750+ return au_br_whable(au_sbr_perm(sb, bindex));
3751+}
3752+
3753+/* ---------------------------------------------------------------------- */
3754+
3755+/*
3756+ * wbr_wh_read_lock, wbr_wh_write_lock
3757+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
3758+ */
3759+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
3760+
dece6358
AM
3761+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
3762+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
3763+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
3764+
1facf9fc 3765+#endif /* __KERNEL__ */
3766+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
3767diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
3768--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
fb47a38f 3769+++ linux/fs/aufs/conf.mk 2014-04-24 22:11:10.848602379 +0200
523b37e3 3770@@ -0,0 +1,37 @@
4a4d8108
AM
3771+
3772+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
3773+
3774+define AuConf
3775+ifdef ${1}
3776+AuConfStr += ${1}=${${1}}
3777+endif
3778+endef
3779+
b752ccd1 3780+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 3781+ SBILIST \
7f207e10 3782+ HNOTIFY HFSNOTIFY \
4a4d8108
AM
3783+ EXPORT INO_T_64 \
3784+ RDU \
3785+ SP_IATTR \
3786+ SHWH \
3787+ BR_RAMFS \
3788+ BR_FUSE POLL \
3789+ BR_HFSPLUS \
3790+ BDEV_LOOP \
b752ccd1
AM
3791+ DEBUG MAGIC_SYSRQ
3792+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
3793+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
3794+
3795+AuConfName = ${obj}/conf.str
3796+${AuConfName}.tmp: FORCE
3797+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
3798+${AuConfName}: ${AuConfName}.tmp
3799+ @diff -q $< $@ > /dev/null 2>&1 || { \
3800+ echo ' GEN ' $@; \
3801+ cp -p $< $@; \
3802+ }
3803+FORCE:
3804+clean-files += ${AuConfName} ${AuConfName}.tmp
3805+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
3806+
3807+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
3808diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
3809--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 3810+++ linux/fs/aufs/cpup.c 2014-04-24 22:11:10.848602379 +0200
523b37e3 3811@@ -0,0 +1,1277 @@
1facf9fc 3812+/*
523b37e3 3813+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 3814+ *
3815+ * This program, aufs is free software; you can redistribute it and/or modify
3816+ * it under the terms of the GNU General Public License as published by
3817+ * the Free Software Foundation; either version 2 of the License, or
3818+ * (at your option) any later version.
dece6358
AM
3819+ *
3820+ * This program is distributed in the hope that it will be useful,
3821+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3822+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3823+ * GNU General Public License for more details.
3824+ *
3825+ * You should have received a copy of the GNU General Public License
523b37e3 3826+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 3827+ */
3828+
3829+/*
3830+ * copy-up functions, see wbr_policy.c for copy-down
3831+ */
3832+
3833+#include <linux/fs_stack.h>
dece6358 3834+#include <linux/mm.h>
1facf9fc 3835+#include "aufs.h"
3836+
86dc4139 3837+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 3838+{
3839+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 3840+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 3841+
86dc4139
AM
3842+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
3843+
3844+ dst->i_flags |= iflags & ~mask;
1facf9fc 3845+ if (au_test_fs_notime(dst->i_sb))
3846+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
3847+}
3848+
3849+void au_cpup_attr_timesizes(struct inode *inode)
3850+{
3851+ struct inode *h_inode;
3852+
3853+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3854+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 3855+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 3856+}
3857+
3858+void au_cpup_attr_nlink(struct inode *inode, int force)
3859+{
3860+ struct inode *h_inode;
3861+ struct super_block *sb;
3862+ aufs_bindex_t bindex, bend;
3863+
3864+ sb = inode->i_sb;
3865+ bindex = au_ibstart(inode);
3866+ h_inode = au_h_iptr(inode, bindex);
3867+ if (!force
3868+ && !S_ISDIR(h_inode->i_mode)
3869+ && au_opt_test(au_mntflags(sb), PLINK)
3870+ && au_plink_test(inode))
3871+ return;
3872+
7eafdf33
AM
3873+ /*
3874+ * 0 can happen in revalidating.
3875+ * h_inode->i_mutex is not held, but it is harmless since once i_nlink
3876+ * reaches 0, it will never become positive.
3877+ */
92d182d2 3878+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 3879+
3880+ /*
3881+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
3882+ * it may includes whplink directory.
3883+ */
3884+ if (S_ISDIR(h_inode->i_mode)) {
3885+ bend = au_ibend(inode);
3886+ for (bindex++; bindex <= bend; bindex++) {
3887+ h_inode = au_h_iptr(inode, bindex);
3888+ if (h_inode)
3889+ au_add_nlink(inode, h_inode);
3890+ }
3891+ }
3892+}
3893+
3894+void au_cpup_attr_changeable(struct inode *inode)
3895+{
3896+ struct inode *h_inode;
3897+
3898+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3899+ inode->i_mode = h_inode->i_mode;
3900+ inode->i_uid = h_inode->i_uid;
3901+ inode->i_gid = h_inode->i_gid;
3902+ au_cpup_attr_timesizes(inode);
86dc4139 3903+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 3904+}
3905+
3906+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
3907+{
3908+ struct au_iinfo *iinfo = au_ii(inode);
3909+
1308ab2a 3910+ IiMustWriteLock(inode);
3911+
1facf9fc 3912+ iinfo->ii_higen = h_inode->i_generation;
3913+ iinfo->ii_hsb1 = h_inode->i_sb;
3914+}
3915+
3916+void au_cpup_attr_all(struct inode *inode, int force)
3917+{
3918+ struct inode *h_inode;
3919+
3920+ h_inode = au_h_iptr(inode, au_ibstart(inode));
3921+ au_cpup_attr_changeable(inode);
3922+ if (inode->i_nlink > 0)
3923+ au_cpup_attr_nlink(inode, force);
3924+ inode->i_rdev = h_inode->i_rdev;
3925+ inode->i_blkbits = h_inode->i_blkbits;
3926+ au_cpup_igen(inode, h_inode);
3927+}
3928+
3929+/* ---------------------------------------------------------------------- */
3930+
3931+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
3932+
3933+/* keep the timestamps of the parent dir when cpup */
3934+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
3935+ struct path *h_path)
3936+{
3937+ struct inode *h_inode;
3938+
3939+ dt->dt_dentry = dentry;
3940+ dt->dt_h_path = *h_path;
3941+ h_inode = h_path->dentry->d_inode;
3942+ dt->dt_atime = h_inode->i_atime;
3943+ dt->dt_mtime = h_inode->i_mtime;
3944+ /* smp_mb(); */
3945+}
3946+
3947+void au_dtime_revert(struct au_dtime *dt)
3948+{
3949+ struct iattr attr;
3950+ int err;
3951+
3952+ attr.ia_atime = dt->dt_atime;
3953+ attr.ia_mtime = dt->dt_mtime;
3954+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
3955+ | ATTR_ATIME | ATTR_ATIME_SET;
3956+
523b37e3
AM
3957+ /* no delegation since this is a directory */
3958+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 3959+ if (unlikely(err))
0c3ec466 3960+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 3961+}
3962+
3963+/* ---------------------------------------------------------------------- */
3964+
86dc4139
AM
3965+/* internal use only */
3966+struct au_cpup_reg_attr {
3967+ int valid;
3968+ struct kstat st;
3969+ unsigned int iflags; /* inode->i_flags */
3970+};
3971+
1facf9fc 3972+static noinline_for_stack
86dc4139
AM
3973+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
3974+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 3975+{
3976+ int err, sbits;
3977+ struct iattr ia;
3978+ struct path h_path;
1308ab2a 3979+ struct inode *h_isrc, *h_idst;
86dc4139 3980+ struct kstat *h_st;
1facf9fc 3981+
3982+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 3983+ h_idst = h_path.dentry->d_inode;
1facf9fc 3984+ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
3985+ h_isrc = h_src->d_inode;
1308ab2a 3986+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 3987+ | ATTR_ATIME | ATTR_MTIME
3988+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
3989+ if (h_src_attr && h_src_attr->valid) {
3990+ h_st = &h_src_attr->st;
3991+ ia.ia_uid = h_st->uid;
3992+ ia.ia_gid = h_st->gid;
3993+ ia.ia_atime = h_st->atime;
3994+ ia.ia_mtime = h_st->mtime;
3995+ if (h_idst->i_mode != h_st->mode
3996+ && !S_ISLNK(h_idst->i_mode)) {
3997+ ia.ia_valid |= ATTR_MODE;
3998+ ia.ia_mode = h_st->mode;
3999+ }
4000+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
4001+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
4002+ } else {
4003+ ia.ia_uid = h_isrc->i_uid;
4004+ ia.ia_gid = h_isrc->i_gid;
4005+ ia.ia_atime = h_isrc->i_atime;
4006+ ia.ia_mtime = h_isrc->i_mtime;
4007+ if (h_idst->i_mode != h_isrc->i_mode
4008+ && !S_ISLNK(h_idst->i_mode)) {
4009+ ia.ia_valid |= ATTR_MODE;
4010+ ia.ia_mode = h_isrc->i_mode;
4011+ }
4012+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
4013+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 4014+ }
523b37e3
AM
4015+ /* no delegation since it is just created */
4016+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4017+
4018+ /* is this nfs only? */
4019+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
4020+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
4021+ ia.ia_mode = h_isrc->i_mode;
523b37e3 4022+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4023+ }
4024+
4025+ return err;
4026+}
4027+
4028+/* ---------------------------------------------------------------------- */
4029+
4030+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
4031+ char *buf, unsigned long blksize)
4032+{
4033+ int err;
4034+ size_t sz, rbytes, wbytes;
4035+ unsigned char all_zero;
4036+ char *p, *zp;
4037+ struct mutex *h_mtx;
4038+ /* reduce stack usage */
4039+ struct iattr *ia;
4040+
4041+ zp = page_address(ZERO_PAGE(0));
4042+ if (unlikely(!zp))
4043+ return -ENOMEM; /* possible? */
4044+
4045+ err = 0;
4046+ all_zero = 0;
4047+ while (len) {
4048+ AuDbg("len %lld\n", len);
4049+ sz = blksize;
4050+ if (len < blksize)
4051+ sz = len;
4052+
4053+ rbytes = 0;
4054+ /* todo: signal_pending? */
4055+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
4056+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
4057+ err = rbytes;
4058+ }
4059+ if (unlikely(err < 0))
4060+ break;
4061+
4062+ all_zero = 0;
4063+ if (len >= rbytes && rbytes == blksize)
4064+ all_zero = !memcmp(buf, zp, rbytes);
4065+ if (!all_zero) {
4066+ wbytes = rbytes;
4067+ p = buf;
4068+ while (wbytes) {
4069+ size_t b;
4070+
4071+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
4072+ err = b;
4073+ /* todo: signal_pending? */
4074+ if (unlikely(err == -EAGAIN || err == -EINTR))
4075+ continue;
4076+ if (unlikely(err < 0))
4077+ break;
4078+ wbytes -= b;
4079+ p += b;
4080+ }
392086de
AM
4081+ if (unlikely(err < 0))
4082+ break;
1facf9fc 4083+ } else {
4084+ loff_t res;
4085+
4086+ AuLabel(hole);
4087+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
4088+ err = res;
4089+ if (unlikely(res < 0))
4090+ break;
4091+ }
4092+ len -= rbytes;
4093+ err = 0;
4094+ }
4095+
4096+ /* the last block may be a hole */
4097+ if (!err && all_zero) {
4098+ AuLabel(last hole);
4099+
4100+ err = 1;
4101+ if (au_test_nfs(dst->f_dentry->d_sb)) {
4102+ /* nfs requires this step to make last hole */
4103+ /* is this only nfs? */
4104+ do {
4105+ /* todo: signal_pending? */
4106+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
4107+ } while (err == -EAGAIN || err == -EINTR);
4108+ if (err == 1)
4109+ dst->f_pos--;
4110+ }
4111+
4112+ if (err == 1) {
4113+ ia = (void *)buf;
4114+ ia->ia_size = dst->f_pos;
4115+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
4116+ ia->ia_file = dst;
c06a8ce3 4117+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 4118+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
523b37e3
AM
4119+ /* no delegation since it is just created */
4120+ err = vfsub_notify_change(&dst->f_path, ia,
4121+ /*delegated*/NULL);
1facf9fc 4122+ mutex_unlock(h_mtx);
4123+ }
4124+ }
4125+
4126+ return err;
4127+}
4128+
4129+int au_copy_file(struct file *dst, struct file *src, loff_t len)
4130+{
4131+ int err;
4132+ unsigned long blksize;
4133+ unsigned char do_kfree;
4134+ char *buf;
4135+
4136+ err = -ENOMEM;
4137+ blksize = dst->f_dentry->d_sb->s_blocksize;
4138+ if (!blksize || PAGE_SIZE < blksize)
4139+ blksize = PAGE_SIZE;
4140+ AuDbg("blksize %lu\n", blksize);
4141+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
4142+ if (do_kfree)
4143+ buf = kmalloc(blksize, GFP_NOFS);
4144+ else
4145+ buf = (void *)__get_free_page(GFP_NOFS);
4146+ if (unlikely(!buf))
4147+ goto out;
4148+
4149+ if (len > (1 << 22))
4150+ AuDbg("copying a large file %lld\n", (long long)len);
4151+
4152+ src->f_pos = 0;
4153+ dst->f_pos = 0;
4154+ err = au_do_copy_file(dst, src, len, buf, blksize);
4155+ if (do_kfree)
4156+ kfree(buf);
4157+ else
4158+ free_page((unsigned long)buf);
4159+
4f0767ce 4160+out:
1facf9fc 4161+ return err;
4162+}
4163+
4164+/*
4165+ * to support a sparse file which is opened with O_APPEND,
4166+ * we need to close the file.
4167+ */
c2b27bf2 4168+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 4169+{
4170+ int err, i;
4171+ enum { SRC, DST };
4172+ struct {
4173+ aufs_bindex_t bindex;
4174+ unsigned int flags;
4175+ struct dentry *dentry;
392086de 4176+ int force_wr;
1facf9fc 4177+ struct file *file;
523b37e3 4178+ void *label;
1facf9fc 4179+ } *f, file[] = {
4180+ {
c2b27bf2 4181+ .bindex = cpg->bsrc,
1facf9fc 4182+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 4183+ .label = &&out
1facf9fc 4184+ },
4185+ {
c2b27bf2 4186+ .bindex = cpg->bdst,
1facf9fc 4187+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 4188+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 4189+ .label = &&out_src
1facf9fc 4190+ }
4191+ };
4192+ struct super_block *sb;
4193+
4194+ /* bsrc branch can be ro/rw. */
c2b27bf2 4195+ sb = cpg->dentry->d_sb;
1facf9fc 4196+ f = file;
4197+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
4198+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
4199+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 4200+ /*file*/NULL, f->force_wr);
1facf9fc 4201+ err = PTR_ERR(f->file);
4202+ if (IS_ERR(f->file))
4203+ goto *f->label;
1facf9fc 4204+ }
4205+
4206+ /* try stopping to update while we copyup */
4207+ IMustLock(file[SRC].dentry->d_inode);
c2b27bf2 4208+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 4209+
1facf9fc 4210+ fput(file[DST].file);
4211+ au_sbr_put(sb, file[DST].bindex);
523b37e3 4212+
4f0767ce 4213+out_src:
1facf9fc 4214+ fput(file[SRC].file);
4215+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 4216+out:
1facf9fc 4217+ return err;
4218+}
4219+
c2b27bf2 4220+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 4221+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4222+{
4223+ int err, rerr;
4224+ loff_t l;
86dc4139
AM
4225+ struct path h_path;
4226+ struct inode *h_src_inode;
1facf9fc 4227+
4228+ err = 0;
c2b27bf2 4229+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
86dc4139 4230+ l = i_size_read(h_src_inode);
c2b27bf2
AM
4231+ if (cpg->len == -1 || l < cpg->len)
4232+ cpg->len = l;
4233+ if (cpg->len) {
86dc4139
AM
4234+ /* try stopping to update while we are referencing */
4235+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2 4236+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 4237+
c2b27bf2
AM
4238+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
4239+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139
AM
4240+ h_src_attr->iflags = h_src_inode->i_flags;
4241+ err = vfs_getattr(&h_path, &h_src_attr->st);
4242+ if (unlikely(err)) {
4243+ mutex_unlock(&h_src_inode->i_mutex);
4244+ goto out;
4245+ }
4246+ h_src_attr->valid = 1;
c2b27bf2 4247+ err = au_cp_regular(cpg);
86dc4139 4248+ mutex_unlock(&h_src_inode->i_mutex);
c2b27bf2 4249+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
4250+ if (!err && rerr)
4251+ err = rerr;
1facf9fc 4252+ }
4253+
4f0767ce 4254+out:
1facf9fc 4255+ return err;
4256+}
4257+
4258+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
4259+ struct inode *h_dir)
4260+{
4261+ int err, symlen;
4262+ mm_segment_t old_fs;
b752ccd1
AM
4263+ union {
4264+ char *k;
4265+ char __user *u;
4266+ } sym;
1facf9fc 4267+
4268+ err = -ENOSYS;
4269+ if (unlikely(!h_src->d_inode->i_op->readlink))
4270+ goto out;
4271+
4272+ err = -ENOMEM;
537831f9 4273+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 4274+ if (unlikely(!sym.k))
1facf9fc 4275+ goto out;
4276+
9dbd164d 4277+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 4278+ old_fs = get_fs();
4279+ set_fs(KERNEL_DS);
b752ccd1 4280+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 4281+ err = symlen;
4282+ set_fs(old_fs);
4283+
4284+ if (symlen > 0) {
b752ccd1
AM
4285+ sym.k[symlen] = 0;
4286+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 4287+ }
537831f9 4288+ free_page((unsigned long)sym.k);
1facf9fc 4289+
4f0767ce 4290+out:
1facf9fc 4291+ return err;
4292+}
4293+
1facf9fc 4294+static noinline_for_stack
c2b27bf2 4295+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 4296+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4297+{
4298+ int err;
4299+ umode_t mode;
4300+ unsigned int mnt_flags;
4301+ unsigned char isdir;
c2b27bf2 4302+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4303+ struct au_dtime dt;
4304+ struct path h_path;
4305+ struct dentry *h_src, *h_dst, *h_parent;
4306+ struct inode *h_inode, *h_dir;
4307+ struct super_block *sb;
4308+
4309+ /* bsrc branch can be ro/rw. */
c2b27bf2 4310+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
1facf9fc 4311+ h_inode = h_src->d_inode;
c2b27bf2 4312+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
1facf9fc 4313+
4314+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
4315+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
4316+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
4317+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
4318+ AUFS_WH_PFX_LEN));
1facf9fc 4319+ h_parent = h_dst->d_parent; /* dir inode is locked */
4320+ h_dir = h_parent->d_inode;
4321+ IMustLock(h_dir);
4322+ AuDebugOn(h_parent != h_dst->d_parent);
4323+
c2b27bf2
AM
4324+ sb = cpg->dentry->d_sb;
4325+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 4326+ if (do_dt) {
4327+ h_path.dentry = h_parent;
4328+ au_dtime_store(&dt, dst_parent, &h_path);
4329+ }
4330+ h_path.dentry = h_dst;
4331+
4332+ isdir = 0;
4333+ mode = h_inode->i_mode;
4334+ switch (mode & S_IFMT) {
4335+ case S_IFREG:
b4510431
AM
4336+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
4337+ /*want_excl*/true);
1facf9fc 4338+ if (!err)
c2b27bf2 4339+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 4340+ break;
4341+ case S_IFDIR:
4342+ isdir = 1;
4343+ err = vfsub_mkdir(h_dir, &h_path, mode);
4344+ if (!err) {
4345+ /*
4346+ * strange behaviour from the users view,
4347+ * particularry setattr case
4348+ */
c2b27bf2 4349+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
1facf9fc 4350+ au_cpup_attr_nlink(dst_parent->d_inode,
4351+ /*force*/1);
c2b27bf2 4352+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
1facf9fc 4353+ }
4354+ break;
4355+ case S_IFLNK:
4356+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
4357+ break;
4358+ case S_IFCHR:
4359+ case S_IFBLK:
4360+ AuDebugOn(!capable(CAP_MKNOD));
4361+ /*FALLTHROUGH*/
4362+ case S_IFIFO:
4363+ case S_IFSOCK:
4364+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
4365+ break;
4366+ default:
4367+ AuIOErr("Unknown inode type 0%o\n", mode);
4368+ err = -EIO;
4369+ }
4370+
4371+ mnt_flags = au_mntflags(sb);
4372+ if (!au_opt_test(mnt_flags, UDBA_NONE)
4373+ && !isdir
4374+ && au_opt_test(mnt_flags, XINO)
4375+ && h_inode->i_nlink == 1
4376+ /* todo: unnecessary? */
c2b27bf2
AM
4377+ /* && cpg->dentry->d_inode->i_nlink == 1 */
4378+ && cpg->bdst < cpg->bsrc
4379+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
4380+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 4381+ /* ignore this error */
4382+
4383+ if (do_dt)
4384+ au_dtime_revert(&dt);
4385+ return err;
4386+}
4387+
392086de 4388+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
4389+{
4390+ int err;
392086de 4391+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 4392+ struct inode *h_dir;
392086de 4393+ aufs_bindex_t bdst;
86dc4139 4394+
392086de
AM
4395+ dentry = cpg->dentry;
4396+ bdst = cpg->bdst;
4397+ h_dentry = au_h_dptr(dentry, bdst);
4398+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
4399+ dget(h_dentry);
4400+ au_set_h_dptr(dentry, bdst, NULL);
4401+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
4402+ if (!err)
4403+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 4404+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
4405+ } else {
4406+ err = 0;
4407+ parent = dget_parent(dentry);
4408+ h_parent = au_h_dptr(parent, bdst);
4409+ dput(parent);
4410+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
4411+ if (IS_ERR(h_path->dentry))
4412+ err = PTR_ERR(h_path->dentry);
86dc4139 4413+ }
392086de
AM
4414+ if (unlikely(err))
4415+ goto out;
86dc4139 4416+
86dc4139
AM
4417+ h_parent = h_dentry->d_parent; /* dir inode is locked */
4418+ h_dir = h_parent->d_inode;
4419+ IMustLock(h_dir);
523b37e3
AM
4420+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
4421+ /* no delegation since it is just created */
4422+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL);
86dc4139
AM
4423+ dput(h_path->dentry);
4424+
4425+out:
4426+ return err;
4427+}
4428+
1facf9fc 4429+/*
4430+ * copyup the @dentry from @bsrc to @bdst.
4431+ * the caller must set the both of lower dentries.
4432+ * @len is for truncating when it is -1 copyup the entire file.
4433+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 4434+ * basic->bsrc can be larger than basic->bdst.
1facf9fc 4435+ */
c2b27bf2 4436+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 4437+{
4438+ int err, rerr;
4439+ aufs_bindex_t old_ibstart;
4440+ unsigned char isdir, plink;
1facf9fc 4441+ struct dentry *h_src, *h_dst, *h_parent;
523b37e3 4442+ struct inode *dst_inode, *h_dir, *inode, *delegated;
1facf9fc 4443+ struct super_block *sb;
86dc4139 4444+ struct au_branch *br;
c2b27bf2
AM
4445+ /* to reuduce stack size */
4446+ struct {
4447+ struct au_dtime dt;
4448+ struct path h_path;
4449+ struct au_cpup_reg_attr h_src_attr;
4450+ } *a;
1facf9fc 4451+
c2b27bf2
AM
4452+ err = -ENOMEM;
4453+ a = kmalloc(sizeof(*a), GFP_NOFS);
4454+ if (unlikely(!a))
4455+ goto out;
4456+ a->h_src_attr.valid = 0;
1facf9fc 4457+
c2b27bf2
AM
4458+ sb = cpg->dentry->d_sb;
4459+ br = au_sbr(sb, cpg->bdst);
4460+ a->h_path.mnt = au_br_mnt(br);
4461+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 4462+ h_parent = h_dst->d_parent; /* dir inode is locked */
4463+ h_dir = h_parent->d_inode;
4464+ IMustLock(h_dir);
4465+
c2b27bf2
AM
4466+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
4467+ inode = cpg->dentry->d_inode;
1facf9fc 4468+
4469+ if (!dst_parent)
c2b27bf2 4470+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 4471+ else
4472+ dget(dst_parent);
4473+
4474+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 4475+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 4476+ if (dst_inode) {
4477+ if (unlikely(!plink)) {
4478+ err = -EIO;
027c5e7a
AM
4479+ AuIOErr("hi%lu(i%lu) exists on b%d "
4480+ "but plink is disabled\n",
c2b27bf2
AM
4481+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
4482+ goto out_parent;
1facf9fc 4483+ }
4484+
4485+ if (dst_inode->i_nlink) {
c2b27bf2 4486+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4487+
c2b27bf2 4488+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 4489+ err = PTR_ERR(h_src);
4490+ if (IS_ERR(h_src))
c2b27bf2 4491+ goto out_parent;
1facf9fc 4492+ if (unlikely(!h_src->d_inode)) {
4493+ err = -EIO;
4494+ AuIOErr("i%lu exists on a upper branch "
027c5e7a
AM
4495+ "but not pseudo-linked\n",
4496+ inode->i_ino);
1facf9fc 4497+ dput(h_src);
c2b27bf2 4498+ goto out_parent;
1facf9fc 4499+ }
4500+
4501+ if (do_dt) {
c2b27bf2
AM
4502+ a->h_path.dentry = h_parent;
4503+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 4504+ }
86dc4139 4505+
c2b27bf2 4506+ a->h_path.dentry = h_dst;
523b37e3
AM
4507+ delegated = NULL;
4508+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 4509+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 4510+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 4511+ if (do_dt)
c2b27bf2 4512+ au_dtime_revert(&a->dt);
523b37e3
AM
4513+ if (unlikely(err == -EWOULDBLOCK)) {
4514+ pr_warn("cannot retry for NFSv4 delegation"
4515+ " for an internal link\n");
4516+ iput(delegated);
4517+ }
1facf9fc 4518+ dput(h_src);
c2b27bf2 4519+ goto out_parent;
1facf9fc 4520+ } else
4521+ /* todo: cpup_wh_file? */
4522+ /* udba work */
4a4d8108 4523+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 4524+ }
4525+
86dc4139 4526+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 4527+ old_ibstart = au_ibstart(inode);
c2b27bf2 4528+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 4529+ if (unlikely(err))
86dc4139 4530+ goto out_rev;
1facf9fc 4531+ dst_inode = h_dst->d_inode;
4532+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139 4533+ /* todo: necessary? */
c2b27bf2 4534+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 4535+
c2b27bf2 4536+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
4537+ if (unlikely(err)) {
4538+ /* todo: necessary? */
c2b27bf2 4539+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
86dc4139
AM
4540+ mutex_unlock(&dst_inode->i_mutex);
4541+ goto out_rev;
4542+ }
4543+
c2b27bf2 4544+ if (cpg->bdst < old_ibstart) {
86dc4139 4545+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 4546+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 4547+ if (unlikely(err)) {
c2b27bf2
AM
4548+ /* ignore an error */
4549+ /* au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
4550+ mutex_unlock(&dst_inode->i_mutex);
4551+ goto out_rev;
4a4d8108 4552+ }
4a4d8108 4553+ }
c2b27bf2
AM
4554+ au_set_ibstart(inode, cpg->bdst);
4555+ } else
4556+ au_set_ibend(inode, cpg->bdst);
4557+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
4558+ au_hi_flags(inode, isdir));
4559+
4560+ /* todo: necessary? */
c2b27bf2 4561+ /* err = au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
4562+ mutex_unlock(&dst_inode->i_mutex);
4563+ if (unlikely(err))
4564+ goto out_rev;
4565+
4566+ if (!isdir
4567+ && h_src->d_inode->i_nlink > 1
4568+ && plink)
c2b27bf2 4569+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 4570+
c2b27bf2
AM
4571+ if (au_ftest_cpup(cpg->flags, RENAME)) {
4572+ a->h_path.dentry = h_dst;
392086de 4573+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
4574+ }
4575+ if (!err)
c2b27bf2 4576+ goto out_parent; /* success */
1facf9fc 4577+
4578+ /* revert */
4a4d8108 4579+out_rev:
c2b27bf2
AM
4580+ a->h_path.dentry = h_parent;
4581+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
4582+ a->h_path.dentry = h_dst;
86dc4139
AM
4583+ rerr = 0;
4584+ if (h_dst->d_inode) {
523b37e3
AM
4585+ if (!isdir) {
4586+ /* no delegation since it is just created */
4587+ rerr = vfsub_unlink(h_dir, &a->h_path,
4588+ /*delegated*/NULL, /*force*/0);
4589+ } else
c2b27bf2 4590+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 4591+ }
c2b27bf2 4592+ au_dtime_revert(&a->dt);
1facf9fc 4593+ if (rerr) {
4594+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
4595+ err = -EIO;
4596+ }
c2b27bf2 4597+out_parent:
1facf9fc 4598+ dput(dst_parent);
c2b27bf2
AM
4599+ kfree(a);
4600+out:
1facf9fc 4601+ return err;
4602+}
4603+
c2b27bf2 4604+#if 0 /* unused */
1facf9fc 4605+struct au_cpup_single_args {
4606+ int *errp;
c2b27bf2 4607+ struct au_cp_generic *cpg;
1facf9fc 4608+ struct dentry *dst_parent;
4609+};
4610+
4611+static void au_call_cpup_single(void *args)
4612+{
4613+ struct au_cpup_single_args *a = args;
86dc4139 4614+
c2b27bf2
AM
4615+ au_pin_hdir_acquire_nest(a->cpg->pin);
4616+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
4617+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4618+}
c2b27bf2 4619+#endif
1facf9fc 4620+
53392da6
AM
4621+/*
4622+ * prevent SIGXFSZ in copy-up.
4623+ * testing CAP_MKNOD is for generic fs,
4624+ * but CAP_FSETID is for xfs only, currently.
4625+ */
86dc4139 4626+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
4627+{
4628+ int do_sio;
86dc4139
AM
4629+ struct super_block *sb;
4630+ struct inode *h_dir;
53392da6
AM
4631+
4632+ do_sio = 0;
86dc4139 4633+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
4634+ if (!au_wkq_test()
4635+ && (!au_sbi(sb)->si_plink_maint_pid
4636+ || au_plink_maint(sb, AuLock_NOPLM))) {
4637+ switch (mode & S_IFMT) {
4638+ case S_IFREG:
4639+ /* no condition about RLIMIT_FSIZE and the file size */
4640+ do_sio = 1;
4641+ break;
4642+ case S_IFCHR:
4643+ case S_IFBLK:
4644+ do_sio = !capable(CAP_MKNOD);
4645+ break;
4646+ }
4647+ if (!do_sio)
4648+ do_sio = ((mode & (S_ISUID | S_ISGID))
4649+ && !capable(CAP_FSETID));
86dc4139
AM
4650+ /* this workaround may be removed in the future */
4651+ if (!do_sio) {
4652+ h_dir = au_pinned_h_dir(pin);
4653+ do_sio = h_dir->i_mode & S_ISVTX;
4654+ }
53392da6
AM
4655+ }
4656+
4657+ return do_sio;
4658+}
4659+
c2b27bf2
AM
4660+#if 0 /* unused */
4661+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 4662+{
4663+ int err, wkq_err;
1facf9fc 4664+ struct dentry *h_dentry;
4665+
c2b27bf2 4666+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
86dc4139 4667+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
c2b27bf2 4668+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 4669+ else {
4670+ struct au_cpup_single_args args = {
4671+ .errp = &err,
c2b27bf2
AM
4672+ .cpg = cpg,
4673+ .dst_parent = dst_parent
1facf9fc 4674+ };
4675+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
4676+ if (unlikely(wkq_err))
4677+ err = wkq_err;
4678+ }
4679+
4680+ return err;
4681+}
c2b27bf2 4682+#endif
1facf9fc 4683+
4684+/*
4685+ * copyup the @dentry from the first active lower branch to @bdst,
4686+ * using au_cpup_single().
4687+ */
c2b27bf2 4688+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 4689+{
4690+ int err;
c2b27bf2
AM
4691+ unsigned int flags_orig;
4692+ struct dentry *dentry;
4693+
4694+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 4695+
c2b27bf2 4696+ dentry = cpg->dentry;
86dc4139 4697+ DiMustWriteLock(dentry);
1facf9fc 4698+
c2b27bf2 4699+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 4700+ if (!err) {
c2b27bf2
AM
4701+ flags_orig = cpg->flags;
4702+ au_fset_cpup(cpg->flags, RENAME);
4703+ err = au_cpup_single(cpg, NULL);
4704+ cpg->flags = flags_orig;
1facf9fc 4705+ if (!err)
4706+ return 0; /* success */
4707+
4708+ /* revert */
c2b27bf2
AM
4709+ au_set_h_dptr(dentry, cpg->bdst, NULL);
4710+ au_set_dbstart(dentry, cpg->bsrc);
1facf9fc 4711+ }
4712+
4713+ return err;
4714+}
4715+
4716+struct au_cpup_simple_args {
4717+ int *errp;
c2b27bf2 4718+ struct au_cp_generic *cpg;
1facf9fc 4719+};
4720+
4721+static void au_call_cpup_simple(void *args)
4722+{
4723+ struct au_cpup_simple_args *a = args;
86dc4139 4724+
c2b27bf2
AM
4725+ au_pin_hdir_acquire_nest(a->cpg->pin);
4726+ *a->errp = au_cpup_simple(a->cpg);
4727+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4728+}
4729+
c2b27bf2 4730+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 4731+{
4732+ int err, wkq_err;
c2b27bf2
AM
4733+ struct dentry *dentry, *parent;
4734+ struct file *h_file;
1facf9fc 4735+ struct inode *h_dir;
4736+
c2b27bf2
AM
4737+ dentry = cpg->dentry;
4738+ h_file = NULL;
4739+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
4740+ AuDebugOn(cpg->bsrc < 0);
392086de 4741+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
4742+ err = PTR_ERR(h_file);
4743+ if (IS_ERR(h_file))
4744+ goto out;
4745+ }
4746+
1facf9fc 4747+ parent = dget_parent(dentry);
c2b27bf2 4748+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
53392da6 4749+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
4750+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
4751+ err = au_cpup_simple(cpg);
1facf9fc 4752+ else {
4753+ struct au_cpup_simple_args args = {
4754+ .errp = &err,
c2b27bf2 4755+ .cpg = cpg
1facf9fc 4756+ };
4757+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
4758+ if (unlikely(wkq_err))
4759+ err = wkq_err;
4760+ }
4761+
4762+ dput(parent);
c2b27bf2
AM
4763+ if (h_file)
4764+ au_h_open_post(dentry, cpg->bsrc, h_file);
4765+
4766+out:
1facf9fc 4767+ return err;
4768+}
4769+
c2b27bf2 4770+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 4771+{
c2b27bf2
AM
4772+ aufs_bindex_t bsrc, bend;
4773+ struct dentry *dentry, *h_dentry;
367653fa 4774+
c2b27bf2
AM
4775+ if (cpg->bsrc < 0) {
4776+ dentry = cpg->dentry;
4777+ bend = au_dbend(dentry);
4778+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
4779+ h_dentry = au_h_dptr(dentry, bsrc);
4780+ if (h_dentry) {
4781+ AuDebugOn(!h_dentry->d_inode);
4782+ break;
4783+ }
4784+ }
4785+ AuDebugOn(bsrc > bend);
4786+ cpg->bsrc = bsrc;
367653fa 4787+ }
c2b27bf2
AM
4788+ AuDebugOn(cpg->bsrc <= cpg->bdst);
4789+ return au_do_sio_cpup_simple(cpg);
4790+}
367653fa 4791+
c2b27bf2
AM
4792+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
4793+{
4794+ AuDebugOn(cpg->bdst <= cpg->bsrc);
4795+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
4796+}
4797+
1facf9fc 4798+/* ---------------------------------------------------------------------- */
4799+
4800+/*
4801+ * copyup the deleted file for writing.
4802+ */
c2b27bf2
AM
4803+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
4804+ struct file *file)
1facf9fc 4805+{
4806+ int err;
c2b27bf2
AM
4807+ unsigned int flags_orig;
4808+ aufs_bindex_t bsrc_orig;
1facf9fc 4809+ struct dentry *h_d_dst, *h_d_start;
c2b27bf2 4810+ struct au_dinfo *dinfo;
4a4d8108 4811+ struct au_hdentry *hdp;
1facf9fc 4812+
c2b27bf2 4813+ dinfo = au_di(cpg->dentry);
1308ab2a 4814+ AuRwMustWriteLock(&dinfo->di_rwsem);
4815+
c2b27bf2
AM
4816+ bsrc_orig = cpg->bsrc;
4817+ cpg->bsrc = dinfo->di_bstart;
4a4d8108 4818+ hdp = dinfo->di_hdentry;
c2b27bf2
AM
4819+ h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
4820+ dinfo->di_bstart = cpg->bdst;
4821+ hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
86dc4139 4822+ h_d_start = NULL;
027c5e7a 4823+ if (file) {
c2b27bf2
AM
4824+ h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
4825+ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_dentry;
027c5e7a 4826+ }
c2b27bf2
AM
4827+ flags_orig = cpg->flags;
4828+ cpg->flags = !AuCpup_DTIME;
4829+ err = au_cpup_single(cpg, /*h_parent*/NULL);
4830+ cpg->flags = flags_orig;
027c5e7a
AM
4831+ if (file) {
4832+ if (!err)
4833+ err = au_reopen_nondir(file);
c2b27bf2 4834+ hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
1facf9fc 4835+ }
c2b27bf2
AM
4836+ hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
4837+ dinfo->di_bstart = cpg->bsrc;
4838+ cpg->bsrc = bsrc_orig;
1facf9fc 4839+
4840+ return err;
4841+}
4842+
c2b27bf2 4843+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 4844+{
4845+ int err;
c2b27bf2 4846+ aufs_bindex_t bdst;
1facf9fc 4847+ struct au_dtime dt;
c2b27bf2 4848+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 4849+ struct au_branch *br;
4850+ struct path h_path;
4851+
c2b27bf2
AM
4852+ dentry = cpg->dentry;
4853+ bdst = cpg->bdst;
1facf9fc 4854+ br = au_sbr(dentry->d_sb, bdst);
4855+ parent = dget_parent(dentry);
4856+ h_parent = au_h_dptr(parent, bdst);
4857+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
4858+ err = PTR_ERR(wh_dentry);
4859+ if (IS_ERR(wh_dentry))
4860+ goto out;
4861+
4862+ h_path.dentry = h_parent;
86dc4139 4863+ h_path.mnt = au_br_mnt(br);
1facf9fc 4864+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 4865+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 4866+ if (unlikely(err))
4867+ goto out_wh;
4868+
4869+ dget(wh_dentry);
4870+ h_path.dentry = wh_dentry;
523b37e3
AM
4871+ if (!S_ISDIR(wh_dentry->d_inode->i_mode)) {
4872+ /* no delegation since it is just created */
4873+ err = vfsub_unlink(h_parent->d_inode, &h_path,
4874+ /*delegated*/NULL, /*force*/0);
4875+ } else
4a4d8108 4876+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
1facf9fc 4877+ if (unlikely(err)) {
523b37e3
AM
4878+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
4879+ wh_dentry, err);
1facf9fc 4880+ err = -EIO;
4881+ }
4882+ au_dtime_revert(&dt);
4883+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
4884+
4f0767ce 4885+out_wh:
1facf9fc 4886+ dput(wh_dentry);
4f0767ce 4887+out:
1facf9fc 4888+ dput(parent);
4889+ return err;
4890+}
4891+
4892+struct au_cpup_wh_args {
4893+ int *errp;
c2b27bf2 4894+ struct au_cp_generic *cpg;
1facf9fc 4895+ struct file *file;
4896+};
4897+
4898+static void au_call_cpup_wh(void *args)
4899+{
4900+ struct au_cpup_wh_args *a = args;
86dc4139 4901+
c2b27bf2
AM
4902+ au_pin_hdir_acquire_nest(a->cpg->pin);
4903+ *a->errp = au_cpup_wh(a->cpg, a->file);
4904+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 4905+}
4906+
c2b27bf2 4907+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 4908+{
4909+ int err, wkq_err;
c2b27bf2
AM
4910+ aufs_bindex_t bdst;
4911+ struct dentry *dentry, *parent, *h_orph, *h_parent, *h_dentry;
86dc4139 4912+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 4913+ struct au_wbr *wbr;
c2b27bf2 4914+ struct au_pin wh_pin, *pin_orig;
1facf9fc 4915+
c2b27bf2
AM
4916+ dentry = cpg->dentry;
4917+ bdst = cpg->bdst;
1facf9fc 4918+ parent = dget_parent(dentry);
4919+ dir = parent->d_inode;
4920+ h_orph = NULL;
4921+ h_parent = NULL;
4922+ h_dir = au_igrab(au_h_iptr(dir, bdst));
4923+ h_tmpdir = h_dir;
c2b27bf2 4924+ pin_orig = NULL;
1facf9fc 4925+ if (!h_dir->i_nlink) {
4926+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
4927+ h_orph = wbr->wbr_orph;
4928+
4929+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 4930+ au_set_h_dptr(parent, bdst, dget(h_orph));
4931+ h_tmpdir = h_orph->d_inode;
1facf9fc 4932+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
4933+
1facf9fc 4934+ if (file)
4a4d8108 4935+ h_dentry = au_hf_top(file)->f_dentry;
1facf9fc 4936+ else
4937+ h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
dece6358 4938+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 4939+ /* todo: au_h_open_pre()? */
86dc4139 4940+
c2b27bf2 4941+ pin_orig = cpg->pin;
86dc4139 4942+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
4943+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
4944+ cpg->pin = &wh_pin;
1facf9fc 4945+ }
4946+
53392da6 4947+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
4948+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
4949+ err = au_cpup_wh(cpg, file);
1facf9fc 4950+ else {
4951+ struct au_cpup_wh_args args = {
4952+ .errp = &err,
c2b27bf2
AM
4953+ .cpg = cpg,
4954+ .file = file
1facf9fc 4955+ };
4956+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
4957+ if (unlikely(wkq_err))
4958+ err = wkq_err;
4959+ }
4960+
4961+ if (h_orph) {
4962+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 4963+ /* todo: au_h_open_post()? */
1facf9fc 4964+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 4965+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
4966+ AuDebugOn(!pin_orig);
4967+ cpg->pin = pin_orig;
1facf9fc 4968+ }
4969+ iput(h_dir);
4970+ dput(parent);
4971+
4972+ return err;
4973+}
4974+
4975+/* ---------------------------------------------------------------------- */
4976+
4977+/*
4978+ * generic routine for both of copy-up and copy-down.
4979+ */
4980+/* cf. revalidate function in file.c */
4981+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
4982+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 4983+ struct au_pin *pin,
1facf9fc 4984+ struct dentry *h_parent, void *arg),
4985+ void *arg)
4986+{
4987+ int err;
4988+ struct au_pin pin;
4989+ struct dentry *d, *parent, *h_parent, *real_parent;
4990+
4991+ err = 0;
4992+ parent = dget_parent(dentry);
4993+ if (IS_ROOT(parent))
4994+ goto out;
4995+
4996+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
4997+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
4998+
4999+ /* do not use au_dpage */
5000+ real_parent = parent;
5001+ while (1) {
5002+ dput(parent);
5003+ parent = dget_parent(dentry);
5004+ h_parent = au_h_dptr(parent, bdst);
5005+ if (h_parent)
5006+ goto out; /* success */
5007+
5008+ /* find top dir which is necessary to cpup */
5009+ do {
5010+ d = parent;
5011+ dput(parent);
5012+ parent = dget_parent(d);
5013+ di_read_lock_parent3(parent, !AuLock_IR);
5014+ h_parent = au_h_dptr(parent, bdst);
5015+ di_read_unlock(parent, !AuLock_IR);
5016+ } while (!h_parent);
5017+
5018+ if (d != real_parent)
5019+ di_write_lock_child3(d);
5020+
5021+ /* somebody else might create while we were sleeping */
5022+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
5023+ if (au_h_dptr(d, bdst))
5024+ au_update_dbstart(d);
5025+
5026+ au_pin_set_dentry(&pin, d);
5027+ err = au_do_pin(&pin);
5028+ if (!err) {
86dc4139 5029+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 5030+ au_unpin(&pin);
5031+ }
5032+ }
5033+
5034+ if (d != real_parent)
5035+ di_write_unlock(d);
5036+ if (unlikely(err))
5037+ break;
5038+ }
5039+
4f0767ce 5040+out:
1facf9fc 5041+ dput(parent);
5042+ return err;
5043+}
5044+
5045+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5046+ struct au_pin *pin,
1facf9fc 5047+ struct dentry *h_parent __maybe_unused ,
5048+ void *arg __maybe_unused)
5049+{
c2b27bf2
AM
5050+ struct au_cp_generic cpg = {
5051+ .dentry = dentry,
5052+ .bdst = bdst,
5053+ .bsrc = -1,
5054+ .len = 0,
5055+ .pin = pin,
5056+ .flags = AuCpup_DTIME
5057+ };
5058+ return au_sio_cpup_simple(&cpg);
1facf9fc 5059+}
5060+
5061+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5062+{
5063+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
5064+}
5065+
5066+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5067+{
5068+ int err;
5069+ struct dentry *parent;
5070+ struct inode *dir;
5071+
5072+ parent = dget_parent(dentry);
5073+ dir = parent->d_inode;
5074+ err = 0;
5075+ if (au_h_iptr(dir, bdst))
5076+ goto out;
5077+
5078+ di_read_unlock(parent, AuLock_IR);
5079+ di_write_lock_parent(parent);
5080+ /* someone else might change our inode while we were sleeping */
5081+ if (!au_h_iptr(dir, bdst))
5082+ err = au_cpup_dirs(dentry, bdst);
5083+ di_downgrade_lock(parent, AuLock_IR);
5084+
4f0767ce 5085+out:
1facf9fc 5086+ dput(parent);
5087+ return err;
5088+}
7f207e10
AM
5089diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
5090--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 5091+++ linux/fs/aufs/cpup.h 2014-04-24 22:11:10.848602379 +0200
523b37e3 5092@@ -0,0 +1,94 @@
1facf9fc 5093+/*
523b37e3 5094+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5095+ *
5096+ * This program, aufs is free software; you can redistribute it and/or modify
5097+ * it under the terms of the GNU General Public License as published by
5098+ * the Free Software Foundation; either version 2 of the License, or
5099+ * (at your option) any later version.
dece6358
AM
5100+ *
5101+ * This program is distributed in the hope that it will be useful,
5102+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5103+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5104+ * GNU General Public License for more details.
5105+ *
5106+ * You should have received a copy of the GNU General Public License
523b37e3 5107+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5108+ */
5109+
5110+/*
5111+ * copy-up/down functions
5112+ */
5113+
5114+#ifndef __AUFS_CPUP_H__
5115+#define __AUFS_CPUP_H__
5116+
5117+#ifdef __KERNEL__
5118+
dece6358 5119+#include <linux/path.h>
1facf9fc 5120+
dece6358
AM
5121+struct inode;
5122+struct file;
86dc4139 5123+struct au_pin;
dece6358 5124+
86dc4139 5125+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 5126+void au_cpup_attr_timesizes(struct inode *inode);
5127+void au_cpup_attr_nlink(struct inode *inode, int force);
5128+void au_cpup_attr_changeable(struct inode *inode);
5129+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
5130+void au_cpup_attr_all(struct inode *inode, int force);
5131+
5132+/* ---------------------------------------------------------------------- */
5133+
c2b27bf2
AM
5134+struct au_cp_generic {
5135+ struct dentry *dentry;
5136+ aufs_bindex_t bdst, bsrc;
5137+ loff_t len;
5138+ struct au_pin *pin;
5139+ unsigned int flags;
5140+};
5141+
1facf9fc 5142+/* cpup flags */
392086de
AM
5143+#define AuCpup_DTIME 1 /* do dtime_store/revert */
5144+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
5145+ for link(2) */
5146+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
5147+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
5148+ cpup */
5149+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
5150+ existing entry */
5151+#define AuCpup_RWDST (1 << 5) /* force write target even if
5152+ the branch is marked as RO */
c2b27bf2 5153+
1facf9fc 5154+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
5155+#define au_fset_cpup(flags, name) \
5156+ do { (flags) |= AuCpup_##name; } while (0)
5157+#define au_fclr_cpup(flags, name) \
5158+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 5159+
5160+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
5161+int au_sio_cpup_simple(struct au_cp_generic *cpg);
5162+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
5163+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 5164+
5165+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5166+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5167+ struct au_pin *pin,
1facf9fc 5168+ struct dentry *h_parent, void *arg),
5169+ void *arg);
5170+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5171+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5172+
5173+/* ---------------------------------------------------------------------- */
5174+
5175+/* keep timestamps when copyup */
5176+struct au_dtime {
5177+ struct dentry *dt_dentry;
5178+ struct path dt_h_path;
5179+ struct timespec dt_atime, dt_mtime;
5180+};
5181+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5182+ struct path *h_path);
5183+void au_dtime_revert(struct au_dtime *dt);
5184+
5185+#endif /* __KERNEL__ */
5186+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
5187diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
5188--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 5189+++ linux/fs/aufs/dbgaufs.c 2014-04-24 22:11:10.848602379 +0200
523b37e3 5190@@ -0,0 +1,432 @@
1facf9fc 5191+/*
523b37e3 5192+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5193+ *
5194+ * This program, aufs is free software; you can redistribute it and/or modify
5195+ * it under the terms of the GNU General Public License as published by
5196+ * the Free Software Foundation; either version 2 of the License, or
5197+ * (at your option) any later version.
dece6358
AM
5198+ *
5199+ * This program is distributed in the hope that it will be useful,
5200+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5201+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5202+ * GNU General Public License for more details.
5203+ *
5204+ * You should have received a copy of the GNU General Public License
523b37e3 5205+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5206+ */
5207+
5208+/*
5209+ * debugfs interface
5210+ */
5211+
5212+#include <linux/debugfs.h>
5213+#include "aufs.h"
5214+
5215+#ifndef CONFIG_SYSFS
5216+#error DEBUG_FS depends upon SYSFS
5217+#endif
5218+
5219+static struct dentry *dbgaufs;
5220+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
5221+
5222+/* 20 is max digits length of ulong 64 */
5223+struct dbgaufs_arg {
5224+ int n;
5225+ char a[20 * 4];
5226+};
5227+
5228+/*
5229+ * common function for all XINO files
5230+ */
5231+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
5232+ struct file *file)
5233+{
5234+ kfree(file->private_data);
5235+ return 0;
5236+}
5237+
5238+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
5239+{
5240+ int err;
5241+ struct kstat st;
5242+ struct dbgaufs_arg *p;
5243+
5244+ err = -ENOMEM;
5245+ p = kmalloc(sizeof(*p), GFP_NOFS);
5246+ if (unlikely(!p))
5247+ goto out;
5248+
5249+ err = 0;
5250+ p->n = 0;
5251+ file->private_data = p;
5252+ if (!xf)
5253+ goto out;
5254+
c06a8ce3 5255+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 5256+ if (!err) {
5257+ if (do_fcnt)
5258+ p->n = snprintf
5259+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
5260+ (long)file_count(xf), st.blocks, st.blksize,
5261+ (long long)st.size);
5262+ else
5263+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
5264+ st.blocks, st.blksize,
5265+ (long long)st.size);
5266+ AuDebugOn(p->n >= sizeof(p->a));
5267+ } else {
5268+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
5269+ err = 0;
5270+ }
5271+
4f0767ce 5272+out:
1facf9fc 5273+ return err;
5274+
5275+}
5276+
5277+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
5278+ size_t count, loff_t *ppos)
5279+{
5280+ struct dbgaufs_arg *p;
5281+
5282+ p = file->private_data;
5283+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5284+}
5285+
5286+/* ---------------------------------------------------------------------- */
5287+
86dc4139
AM
5288+struct dbgaufs_plink_arg {
5289+ int n;
5290+ char a[];
5291+};
5292+
5293+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
5294+ struct file *file)
5295+{
5296+ free_page((unsigned long)file->private_data);
5297+ return 0;
5298+}
5299+
5300+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
5301+{
5302+ int err, i, limit;
5303+ unsigned long n, sum;
5304+ struct dbgaufs_plink_arg *p;
5305+ struct au_sbinfo *sbinfo;
5306+ struct super_block *sb;
5307+ struct au_sphlhead *sphl;
5308+
5309+ err = -ENOMEM;
5310+ p = (void *)get_zeroed_page(GFP_NOFS);
5311+ if (unlikely(!p))
5312+ goto out;
5313+
5314+ err = -EFBIG;
5315+ sbinfo = inode->i_private;
5316+ sb = sbinfo->si_sb;
5317+ si_noflush_read_lock(sb);
5318+ if (au_opt_test(au_mntflags(sb), PLINK)) {
5319+ limit = PAGE_SIZE - sizeof(p->n);
5320+
5321+ /* the number of buckets */
5322+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
5323+ p->n += n;
5324+ limit -= n;
5325+
5326+ sum = 0;
5327+ for (i = 0, sphl = sbinfo->si_plink;
5328+ i < AuPlink_NHASH;
5329+ i++, sphl++) {
5330+ n = au_sphl_count(sphl);
5331+ sum += n;
5332+
5333+ n = snprintf(p->a + p->n, limit, "%lu ", n);
5334+ p->n += n;
5335+ limit -= n;
5336+ if (unlikely(limit <= 0))
5337+ goto out_free;
5338+ }
5339+ p->a[p->n - 1] = '\n';
5340+
5341+ /* the sum of plinks */
5342+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
5343+ p->n += n;
5344+ limit -= n;
5345+ if (unlikely(limit <= 0))
5346+ goto out_free;
5347+ } else {
5348+#define str "1\n0\n0\n"
5349+ p->n = sizeof(str) - 1;
5350+ strcpy(p->a, str);
5351+#undef str
5352+ }
5353+ si_read_unlock(sb);
5354+
5355+ err = 0;
5356+ file->private_data = p;
5357+ goto out; /* success */
5358+
5359+out_free:
5360+ free_page((unsigned long)p);
5361+out:
5362+ return err;
5363+}
5364+
5365+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
5366+ size_t count, loff_t *ppos)
5367+{
5368+ struct dbgaufs_plink_arg *p;
5369+
5370+ p = file->private_data;
5371+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5372+}
5373+
5374+static const struct file_operations dbgaufs_plink_fop = {
5375+ .owner = THIS_MODULE,
5376+ .open = dbgaufs_plink_open,
5377+ .release = dbgaufs_plink_release,
5378+ .read = dbgaufs_plink_read
5379+};
5380+
5381+/* ---------------------------------------------------------------------- */
5382+
1facf9fc 5383+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
5384+{
5385+ int err;
5386+ struct au_sbinfo *sbinfo;
5387+ struct super_block *sb;
5388+
5389+ sbinfo = inode->i_private;
5390+ sb = sbinfo->si_sb;
5391+ si_noflush_read_lock(sb);
5392+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
5393+ si_read_unlock(sb);
5394+ return err;
5395+}
5396+
5397+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 5398+ .owner = THIS_MODULE,
1facf9fc 5399+ .open = dbgaufs_xib_open,
5400+ .release = dbgaufs_xi_release,
5401+ .read = dbgaufs_xi_read
5402+};
5403+
5404+/* ---------------------------------------------------------------------- */
5405+
5406+#define DbgaufsXi_PREFIX "xi"
5407+
5408+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
5409+{
5410+ int err;
5411+ long l;
5412+ struct au_sbinfo *sbinfo;
5413+ struct super_block *sb;
5414+ struct file *xf;
5415+ struct qstr *name;
5416+
5417+ err = -ENOENT;
5418+ xf = NULL;
5419+ name = &file->f_dentry->d_name;
5420+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
5421+ || memcmp(name->name, DbgaufsXi_PREFIX,
5422+ sizeof(DbgaufsXi_PREFIX) - 1)))
5423+ goto out;
9dbd164d 5424+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 5425+ if (unlikely(err))
5426+ goto out;
5427+
5428+ sbinfo = inode->i_private;
5429+ sb = sbinfo->si_sb;
5430+ si_noflush_read_lock(sb);
5431+ if (l <= au_sbend(sb)) {
5432+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
5433+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
5434+ } else
5435+ err = -ENOENT;
5436+ si_read_unlock(sb);
5437+
4f0767ce 5438+out:
1facf9fc 5439+ return err;
5440+}
5441+
5442+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 5443+ .owner = THIS_MODULE,
1facf9fc 5444+ .open = dbgaufs_xino_open,
5445+ .release = dbgaufs_xi_release,
5446+ .read = dbgaufs_xi_read
5447+};
5448+
5449+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
5450+{
5451+ aufs_bindex_t bend;
5452+ struct au_branch *br;
5453+ struct au_xino_file *xi;
5454+
5455+ if (!au_sbi(sb)->si_dbgaufs)
5456+ return;
5457+
5458+ bend = au_sbend(sb);
5459+ for (; bindex <= bend; bindex++) {
5460+ br = au_sbr(sb, bindex);
5461+ xi = &br->br_xino;
c06a8ce3
AM
5462+ debugfs_remove(xi->xi_dbgaufs);
5463+ xi->xi_dbgaufs = NULL;
1facf9fc 5464+ }
5465+}
5466+
5467+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
5468+{
5469+ struct au_sbinfo *sbinfo;
5470+ struct dentry *parent;
5471+ struct au_branch *br;
5472+ struct au_xino_file *xi;
5473+ aufs_bindex_t bend;
5474+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
5475+
5476+ sbinfo = au_sbi(sb);
5477+ parent = sbinfo->si_dbgaufs;
5478+ if (!parent)
5479+ return;
5480+
5481+ bend = au_sbend(sb);
5482+ for (; bindex <= bend; bindex++) {
5483+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
5484+ br = au_sbr(sb, bindex);
5485+ xi = &br->br_xino;
5486+ AuDebugOn(xi->xi_dbgaufs);
5487+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
5488+ sbinfo, &dbgaufs_xino_fop);
5489+ /* ignore an error */
5490+ if (unlikely(!xi->xi_dbgaufs))
5491+ AuWarn1("failed %s under debugfs\n", name);
5492+ }
5493+}
5494+
5495+/* ---------------------------------------------------------------------- */
5496+
5497+#ifdef CONFIG_AUFS_EXPORT
5498+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
5499+{
5500+ int err;
5501+ struct au_sbinfo *sbinfo;
5502+ struct super_block *sb;
5503+
5504+ sbinfo = inode->i_private;
5505+ sb = sbinfo->si_sb;
5506+ si_noflush_read_lock(sb);
5507+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
5508+ si_read_unlock(sb);
5509+ return err;
5510+}
5511+
5512+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 5513+ .owner = THIS_MODULE,
1facf9fc 5514+ .open = dbgaufs_xigen_open,
5515+ .release = dbgaufs_xi_release,
5516+ .read = dbgaufs_xi_read
5517+};
5518+
5519+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5520+{
5521+ int err;
5522+
dece6358
AM
5523+ /*
5524+ * This function is a dynamic '__init' fucntion actually,
5525+ * so the tiny check for si_rwsem is unnecessary.
5526+ */
5527+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5528+
1facf9fc 5529+ err = -EIO;
5530+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
5531+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5532+ &dbgaufs_xigen_fop);
5533+ if (sbinfo->si_dbgaufs_xigen)
5534+ err = 0;
5535+
5536+ return err;
5537+}
5538+#else
5539+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5540+{
5541+ return 0;
5542+}
5543+#endif /* CONFIG_AUFS_EXPORT */
5544+
5545+/* ---------------------------------------------------------------------- */
5546+
5547+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
5548+{
dece6358
AM
5549+ /*
5550+ * This function is a dynamic '__init' fucntion actually,
5551+ * so the tiny check for si_rwsem is unnecessary.
5552+ */
5553+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5554+
1facf9fc 5555+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
5556+ sbinfo->si_dbgaufs = NULL;
5557+ kobject_put(&sbinfo->si_kobj);
5558+}
5559+
5560+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
5561+{
5562+ int err;
5563+ char name[SysaufsSiNameLen];
5564+
dece6358
AM
5565+ /*
5566+ * This function is a dynamic '__init' fucntion actually,
5567+ * so the tiny check for si_rwsem is unnecessary.
5568+ */
5569+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5570+
1facf9fc 5571+ err = -ENOENT;
5572+ if (!dbgaufs) {
5573+ AuErr1("/debug/aufs is uninitialized\n");
5574+ goto out;
5575+ }
5576+
5577+ err = -EIO;
5578+ sysaufs_name(sbinfo, name);
5579+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
5580+ if (unlikely(!sbinfo->si_dbgaufs))
5581+ goto out;
5582+ kobject_get(&sbinfo->si_kobj);
5583+
5584+ sbinfo->si_dbgaufs_xib = debugfs_create_file
5585+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5586+ &dbgaufs_xib_fop);
5587+ if (unlikely(!sbinfo->si_dbgaufs_xib))
5588+ goto out_dir;
5589+
86dc4139
AM
5590+ sbinfo->si_dbgaufs_plink = debugfs_create_file
5591+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
5592+ &dbgaufs_plink_fop);
5593+ if (unlikely(!sbinfo->si_dbgaufs_plink))
5594+ goto out_dir;
5595+
1facf9fc 5596+ err = dbgaufs_xigen_init(sbinfo);
5597+ if (!err)
5598+ goto out; /* success */
5599+
4f0767ce 5600+out_dir:
1facf9fc 5601+ dbgaufs_si_fin(sbinfo);
4f0767ce 5602+out:
1facf9fc 5603+ return err;
5604+}
5605+
5606+/* ---------------------------------------------------------------------- */
5607+
5608+void dbgaufs_fin(void)
5609+{
5610+ debugfs_remove(dbgaufs);
5611+}
5612+
5613+int __init dbgaufs_init(void)
5614+{
5615+ int err;
5616+
5617+ err = -EIO;
5618+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
5619+ if (dbgaufs)
5620+ err = 0;
5621+ return err;
5622+}
7f207e10
AM
5623diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
5624--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 5625+++ linux/fs/aufs/dbgaufs.h 2014-04-24 22:11:10.848602379 +0200
523b37e3 5626@@ -0,0 +1,48 @@
1facf9fc 5627+/*
523b37e3 5628+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5629+ *
5630+ * This program, aufs is free software; you can redistribute it and/or modify
5631+ * it under the terms of the GNU General Public License as published by
5632+ * the Free Software Foundation; either version 2 of the License, or
5633+ * (at your option) any later version.
dece6358
AM
5634+ *
5635+ * This program is distributed in the hope that it will be useful,
5636+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5637+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5638+ * GNU General Public License for more details.
5639+ *
5640+ * You should have received a copy of the GNU General Public License
523b37e3 5641+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5642+ */
5643+
5644+/*
5645+ * debugfs interface
5646+ */
5647+
5648+#ifndef __DBGAUFS_H__
5649+#define __DBGAUFS_H__
5650+
5651+#ifdef __KERNEL__
5652+
dece6358 5653+struct super_block;
1facf9fc 5654+struct au_sbinfo;
dece6358 5655+
1facf9fc 5656+#ifdef CONFIG_DEBUG_FS
5657+/* dbgaufs.c */
5658+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
5659+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
5660+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
5661+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
5662+void dbgaufs_fin(void);
5663+int __init dbgaufs_init(void);
1facf9fc 5664+#else
4a4d8108
AM
5665+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
5666+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
5667+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
5668+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
5669+AuStubVoid(dbgaufs_fin, void)
5670+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 5671+#endif /* CONFIG_DEBUG_FS */
5672+
5673+#endif /* __KERNEL__ */
5674+#endif /* __DBGAUFS_H__ */
7f207e10
AM
5675diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
5676--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 5677+++ linux/fs/aufs/dcsub.c 2014-04-24 22:11:10.848602379 +0200
027c5e7a 5678@@ -0,0 +1,243 @@
1facf9fc 5679+/*
523b37e3 5680+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5681+ *
5682+ * This program, aufs is free software; you can redistribute it and/or modify
5683+ * it under the terms of the GNU General Public License as published by
5684+ * the Free Software Foundation; either version 2 of the License, or
5685+ * (at your option) any later version.
dece6358
AM
5686+ *
5687+ * This program is distributed in the hope that it will be useful,
5688+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5689+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5690+ * GNU General Public License for more details.
5691+ *
5692+ * You should have received a copy of the GNU General Public License
523b37e3 5693+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5694+ */
5695+
5696+/*
5697+ * sub-routines for dentry cache
5698+ */
5699+
5700+#include "aufs.h"
5701+
5702+static void au_dpage_free(struct au_dpage *dpage)
5703+{
5704+ int i;
5705+ struct dentry **p;
5706+
5707+ p = dpage->dentries;
5708+ for (i = 0; i < dpage->ndentry; i++)
5709+ dput(*p++);
5710+ free_page((unsigned long)dpage->dentries);
5711+}
5712+
5713+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
5714+{
5715+ int err;
5716+ void *p;
5717+
5718+ err = -ENOMEM;
5719+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
5720+ if (unlikely(!dpages->dpages))
5721+ goto out;
5722+
5723+ p = (void *)__get_free_page(gfp);
5724+ if (unlikely(!p))
5725+ goto out_dpages;
5726+
5727+ dpages->dpages[0].ndentry = 0;
5728+ dpages->dpages[0].dentries = p;
5729+ dpages->ndpage = 1;
5730+ return 0; /* success */
5731+
4f0767ce 5732+out_dpages:
1facf9fc 5733+ kfree(dpages->dpages);
4f0767ce 5734+out:
1facf9fc 5735+ return err;
5736+}
5737+
5738+void au_dpages_free(struct au_dcsub_pages *dpages)
5739+{
5740+ int i;
5741+ struct au_dpage *p;
5742+
5743+ p = dpages->dpages;
5744+ for (i = 0; i < dpages->ndpage; i++)
5745+ au_dpage_free(p++);
5746+ kfree(dpages->dpages);
5747+}
5748+
5749+static int au_dpages_append(struct au_dcsub_pages *dpages,
5750+ struct dentry *dentry, gfp_t gfp)
5751+{
5752+ int err, sz;
5753+ struct au_dpage *dpage;
5754+ void *p;
5755+
5756+ dpage = dpages->dpages + dpages->ndpage - 1;
5757+ sz = PAGE_SIZE / sizeof(dentry);
5758+ if (unlikely(dpage->ndentry >= sz)) {
5759+ AuLabel(new dpage);
5760+ err = -ENOMEM;
5761+ sz = dpages->ndpage * sizeof(*dpages->dpages);
5762+ p = au_kzrealloc(dpages->dpages, sz,
5763+ sz + sizeof(*dpages->dpages), gfp);
5764+ if (unlikely(!p))
5765+ goto out;
5766+
5767+ dpages->dpages = p;
5768+ dpage = dpages->dpages + dpages->ndpage;
5769+ p = (void *)__get_free_page(gfp);
5770+ if (unlikely(!p))
5771+ goto out;
5772+
5773+ dpage->ndentry = 0;
5774+ dpage->dentries = p;
5775+ dpages->ndpage++;
5776+ }
5777+
392086de 5778+ AuDebugOn(!d_count(dentry));
027c5e7a 5779+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 5780+ return 0; /* success */
5781+
4f0767ce 5782+out:
1facf9fc 5783+ return err;
5784+}
5785+
523b37e3 5786+/* try d_walk() in linux/fs/dcache.c */
1facf9fc 5787+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5788+ au_dpages_test test, void *arg)
5789+{
5790+ int err;
027c5e7a 5791+ struct dentry *this_parent;
1facf9fc 5792+ struct list_head *next;
5793+ struct super_block *sb = root->d_sb;
5794+
5795+ err = 0;
027c5e7a
AM
5796+ write_seqlock(&rename_lock);
5797+ this_parent = root;
5798+ spin_lock(&this_parent->d_lock);
4f0767ce 5799+repeat:
1facf9fc 5800+ next = this_parent->d_subdirs.next;
4f0767ce 5801+resume:
1facf9fc 5802+ if (this_parent->d_sb == sb
5803+ && !IS_ROOT(this_parent)
027c5e7a 5804+ && au_di(this_parent)
392086de 5805+ && d_count(this_parent)
1facf9fc 5806+ && (!test || test(this_parent, arg))) {
5807+ err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
5808+ if (unlikely(err))
5809+ goto out;
5810+ }
5811+
5812+ while (next != &this_parent->d_subdirs) {
5813+ struct list_head *tmp = next;
5814+ struct dentry *dentry = list_entry(tmp, struct dentry,
5815+ d_u.d_child);
027c5e7a 5816+
1facf9fc 5817+ next = tmp->next;
027c5e7a 5818+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
392086de 5819+ if (d_count(dentry)) {
027c5e7a
AM
5820+ if (!list_empty(&dentry->d_subdirs)) {
5821+ spin_unlock(&this_parent->d_lock);
5822+ spin_release(&dentry->d_lock.dep_map, 1,
5823+ _RET_IP_);
5824+ this_parent = dentry;
5825+ spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
5826+ _RET_IP_);
5827+ goto repeat;
5828+ }
5829+ if (dentry->d_sb == sb
5830+ && au_di(dentry)
5831+ && (!test || test(dentry, arg)))
5832+ err = au_dpages_append(dpages, dentry,
5833+ GFP_ATOMIC);
1facf9fc 5834+ }
027c5e7a
AM
5835+ spin_unlock(&dentry->d_lock);
5836+ if (unlikely(err))
5837+ goto out;
1facf9fc 5838+ }
5839+
5840+ if (this_parent != root) {
027c5e7a
AM
5841+ struct dentry *tmp;
5842+ struct dentry *child;
5843+
5844+ tmp = this_parent->d_parent;
5845+ rcu_read_lock();
5846+ spin_unlock(&this_parent->d_lock);
5847+ child = this_parent;
5848+ this_parent = tmp;
5849+ spin_lock(&this_parent->d_lock);
5850+ rcu_read_unlock();
5851+ next = child->d_u.d_child.next;
1facf9fc 5852+ goto resume;
5853+ }
027c5e7a 5854+
4f0767ce 5855+out:
027c5e7a
AM
5856+ spin_unlock(&this_parent->d_lock);
5857+ write_sequnlock(&rename_lock);
1facf9fc 5858+ return err;
5859+}
5860+
5861+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5862+ int do_include, au_dpages_test test, void *arg)
5863+{
5864+ int err;
5865+
5866+ err = 0;
027c5e7a
AM
5867+ write_seqlock(&rename_lock);
5868+ spin_lock(&dentry->d_lock);
5869+ if (do_include
392086de 5870+ && d_count(dentry)
027c5e7a 5871+ && (!test || test(dentry, arg)))
1facf9fc 5872+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5873+ spin_unlock(&dentry->d_lock);
5874+ if (unlikely(err))
5875+ goto out;
5876+
5877+ /*
523b37e3 5878+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
5879+ * mount
5880+ */
1facf9fc 5881+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
5882+ dentry = dentry->d_parent; /* rename_lock is locked */
5883+ spin_lock(&dentry->d_lock);
392086de 5884+ if (d_count(dentry)
027c5e7a 5885+ && (!test || test(dentry, arg)))
1facf9fc 5886+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
5887+ spin_unlock(&dentry->d_lock);
5888+ if (unlikely(err))
5889+ break;
1facf9fc 5890+ }
5891+
4f0767ce 5892+out:
027c5e7a 5893+ write_sequnlock(&rename_lock);
1facf9fc 5894+ return err;
5895+}
5896+
027c5e7a
AM
5897+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
5898+{
5899+ return au_di(dentry) && dentry->d_sb == arg;
5900+}
5901+
5902+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5903+ struct dentry *dentry, int do_include)
5904+{
5905+ return au_dcsub_pages_rev(dpages, dentry, do_include,
5906+ au_dcsub_dpages_aufs, dentry->d_sb);
5907+}
5908+
4a4d8108 5909+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 5910+{
4a4d8108
AM
5911+ struct path path[2] = {
5912+ {
5913+ .dentry = d1
5914+ },
5915+ {
5916+ .dentry = d2
5917+ }
5918+ };
1facf9fc 5919+
4a4d8108 5920+ return path_is_under(path + 0, path + 1);
1facf9fc 5921+}
7f207e10
AM
5922diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
5923--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 5924+++ linux/fs/aufs/dcsub.h 2014-04-24 22:11:10.848602379 +0200
523b37e3 5925@@ -0,0 +1,98 @@
1facf9fc 5926+/*
523b37e3 5927+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5928+ *
5929+ * This program, aufs is free software; you can redistribute it and/or modify
5930+ * it under the terms of the GNU General Public License as published by
5931+ * the Free Software Foundation; either version 2 of the License, or
5932+ * (at your option) any later version.
dece6358
AM
5933+ *
5934+ * This program is distributed in the hope that it will be useful,
5935+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5936+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5937+ * GNU General Public License for more details.
5938+ *
5939+ * You should have received a copy of the GNU General Public License
523b37e3 5940+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5941+ */
5942+
5943+/*
5944+ * sub-routines for dentry cache
5945+ */
5946+
5947+#ifndef __AUFS_DCSUB_H__
5948+#define __AUFS_DCSUB_H__
5949+
5950+#ifdef __KERNEL__
5951+
7f207e10 5952+#include <linux/dcache.h>
027c5e7a 5953+#include <linux/fs.h>
dece6358
AM
5954+
5955+struct dentry;
1facf9fc 5956+
5957+struct au_dpage {
5958+ int ndentry;
5959+ struct dentry **dentries;
5960+};
5961+
5962+struct au_dcsub_pages {
5963+ int ndpage;
5964+ struct au_dpage *dpages;
5965+};
5966+
5967+/* ---------------------------------------------------------------------- */
5968+
7f207e10 5969+/* dcsub.c */
1facf9fc 5970+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
5971+void au_dpages_free(struct au_dcsub_pages *dpages);
5972+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
5973+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
5974+ au_dpages_test test, void *arg);
5975+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
5976+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
5977+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
5978+ struct dentry *dentry, int do_include);
4a4d8108 5979+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 5980+
7f207e10
AM
5981+/* ---------------------------------------------------------------------- */
5982+
523b37e3
AM
5983+/*
5984+ * todo: in linux-3.13, several similar (but faster) helpers are added to
5985+ * include/linux/dcache.h. Try them (in the future).
5986+ */
5987+
027c5e7a
AM
5988+static inline int au_d_hashed_positive(struct dentry *d)
5989+{
5990+ int err;
5991+ struct inode *inode = d->d_inode;
5992+ err = 0;
5993+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
5994+ err = -ENOENT;
5995+ return err;
5996+}
5997+
5998+static inline int au_d_alive(struct dentry *d)
5999+{
6000+ int err;
6001+ struct inode *inode;
6002+ err = 0;
6003+ if (!IS_ROOT(d))
6004+ err = au_d_hashed_positive(d);
6005+ else {
6006+ inode = d->d_inode;
6007+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
6008+ err = -ENOENT;
6009+ }
6010+ return err;
6011+}
6012+
6013+static inline int au_alive_dir(struct dentry *d)
7f207e10 6014+{
027c5e7a
AM
6015+ int err;
6016+ err = au_d_alive(d);
6017+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
6018+ err = -ENOENT;
6019+ return err;
7f207e10
AM
6020+}
6021+
1facf9fc 6022+#endif /* __KERNEL__ */
6023+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
6024diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
6025--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 6026+++ linux/fs/aufs/debug.c 2014-04-24 22:11:10.848602379 +0200
523b37e3 6027@@ -0,0 +1,517 @@
1facf9fc 6028+/*
523b37e3 6029+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6030+ *
6031+ * This program, aufs is free software; you can redistribute it and/or modify
6032+ * it under the terms of the GNU General Public License as published by
6033+ * the Free Software Foundation; either version 2 of the License, or
6034+ * (at your option) any later version.
dece6358
AM
6035+ *
6036+ * This program is distributed in the hope that it will be useful,
6037+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6038+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6039+ * GNU General Public License for more details.
6040+ *
6041+ * You should have received a copy of the GNU General Public License
523b37e3 6042+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6043+ */
6044+
6045+/*
6046+ * debug print functions
6047+ */
6048+
7f207e10 6049+#include <linux/vt_kern.h>
1facf9fc 6050+#include "aufs.h"
6051+
392086de
AM
6052+/* Returns 0, or -errno. arg is in kp->arg. */
6053+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
6054+{
6055+ int err, n;
6056+
6057+ err = kstrtoint(val, 0, &n);
6058+ if (!err) {
6059+ if (n > 0)
6060+ au_debug_on();
6061+ else
6062+ au_debug_off();
6063+ }
6064+ return err;
6065+}
6066+
6067+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
6068+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
6069+{
6070+ atomic_t *a;
6071+
6072+ a = kp->arg;
6073+ return sprintf(buffer, "%d", atomic_read(a));
6074+}
6075+
6076+static struct kernel_param_ops param_ops_atomic_t = {
6077+ .set = param_atomic_t_set,
6078+ .get = param_atomic_t_get
6079+ /* void (*free)(void *arg) */
6080+};
6081+
6082+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 6083+MODULE_PARM_DESC(debug, "debug print");
392086de 6084+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 6085+
6086+char *au_plevel = KERN_DEBUG;
e49829fe
JR
6087+#define dpri(fmt, ...) do { \
6088+ if ((au_plevel \
6089+ && strcmp(au_plevel, KERN_DEBUG)) \
6090+ || au_debug_test()) \
6091+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 6092+} while (0)
6093+
6094+/* ---------------------------------------------------------------------- */
6095+
6096+void au_dpri_whlist(struct au_nhash *whlist)
6097+{
6098+ unsigned long ul, n;
6099+ struct hlist_head *head;
c06a8ce3 6100+ struct au_vdir_wh *pos;
1facf9fc 6101+
6102+ n = whlist->nh_num;
6103+ head = whlist->nh_head;
6104+ for (ul = 0; ul < n; ul++) {
c06a8ce3 6105+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 6106+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
6107+ pos->wh_bindex,
6108+ pos->wh_str.len, pos->wh_str.name,
6109+ pos->wh_str.len);
1facf9fc 6110+ head++;
6111+ }
6112+}
6113+
6114+void au_dpri_vdir(struct au_vdir *vdir)
6115+{
6116+ unsigned long ul;
6117+ union au_vdir_deblk_p p;
6118+ unsigned char *o;
6119+
6120+ if (!vdir || IS_ERR(vdir)) {
6121+ dpri("err %ld\n", PTR_ERR(vdir));
6122+ return;
6123+ }
6124+
6125+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
6126+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
6127+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
6128+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
6129+ p.deblk = vdir->vd_deblk[ul];
6130+ o = p.deblk;
6131+ dpri("[%lu]: %p\n", ul, o);
6132+ }
6133+}
6134+
53392da6 6135+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 6136+ struct dentry *wh)
6137+{
6138+ char *n = NULL;
6139+ int l = 0;
6140+
6141+ if (!inode || IS_ERR(inode)) {
6142+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
6143+ return -1;
6144+ }
6145+
c2b27bf2 6146+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 6147+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
6148+ && sizeof(inode->i_blocks) != sizeof(u64));
6149+ if (wh) {
6150+ n = (void *)wh->d_name.name;
6151+ l = wh->d_name.len;
6152+ }
6153+
53392da6
AM
6154+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
6155+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
6156+ bindex, inode,
1facf9fc 6157+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
6158+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
6159+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 6160+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 6161+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
6162+ inode->i_state, inode->i_flags, inode->i_version,
6163+ inode->i_generation,
1facf9fc 6164+ l ? ", wh " : "", l, n);
6165+ return 0;
6166+}
6167+
6168+void au_dpri_inode(struct inode *inode)
6169+{
6170+ struct au_iinfo *iinfo;
6171+ aufs_bindex_t bindex;
53392da6 6172+ int err, hn;
1facf9fc 6173+
53392da6 6174+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 6175+ if (err || !au_test_aufs(inode->i_sb))
6176+ return;
6177+
6178+ iinfo = au_ii(inode);
6179+ if (!iinfo)
6180+ return;
6181+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 6182+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 6183+ if (iinfo->ii_bstart < 0)
6184+ return;
53392da6
AM
6185+ hn = 0;
6186+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
6187+ hn = !!au_hn(iinfo->ii_hinode + bindex);
6188+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 6189+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 6190+ }
1facf9fc 6191+}
6192+
2cbb1c4b
JR
6193+void au_dpri_dalias(struct inode *inode)
6194+{
6195+ struct dentry *d;
6196+
6197+ spin_lock(&inode->i_lock);
c06a8ce3 6198+ hlist_for_each_entry(d, &inode->i_dentry, d_alias)
2cbb1c4b
JR
6199+ au_dpri_dentry(d);
6200+ spin_unlock(&inode->i_lock);
6201+}
6202+
1facf9fc 6203+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
6204+{
6205+ struct dentry *wh = NULL;
53392da6 6206+ int hn;
1facf9fc 6207+
6208+ if (!dentry || IS_ERR(dentry)) {
6209+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
6210+ return -1;
6211+ }
6212+ /* do not call dget_parent() here */
027c5e7a 6213+ /* note: access d_xxx without d_lock */
523b37e3
AM
6214+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
6215+ bindex, dentry, dentry,
1facf9fc 6216+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
523b37e3
AM
6217+ d_count(dentry), dentry->d_flags,
6218+ d_unhashed(dentry) ? "un" : "");
53392da6 6219+ hn = -1;
1facf9fc 6220+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
6221+ struct au_iinfo *iinfo = au_ii(dentry->d_inode);
53392da6
AM
6222+ if (iinfo) {
6223+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 6224+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 6225+ }
1facf9fc 6226+ }
53392da6 6227+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 6228+ return 0;
6229+}
6230+
6231+void au_dpri_dentry(struct dentry *dentry)
6232+{
6233+ struct au_dinfo *dinfo;
6234+ aufs_bindex_t bindex;
6235+ int err;
4a4d8108 6236+ struct au_hdentry *hdp;
1facf9fc 6237+
6238+ err = do_pri_dentry(-1, dentry);
6239+ if (err || !au_test_aufs(dentry->d_sb))
6240+ return;
6241+
6242+ dinfo = au_di(dentry);
6243+ if (!dinfo)
6244+ return;
6245+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n",
6246+ dinfo->di_bstart, dinfo->di_bend,
6247+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry));
6248+ if (dinfo->di_bstart < 0)
6249+ return;
4a4d8108 6250+ hdp = dinfo->di_hdentry;
1facf9fc 6251+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 6252+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 6253+}
6254+
6255+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
6256+{
6257+ char a[32];
6258+
6259+ if (!file || IS_ERR(file)) {
6260+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
6261+ return -1;
6262+ }
6263+ a[0] = 0;
6264+ if (bindex < 0
6265+ && file->f_dentry
6266+ && au_test_aufs(file->f_dentry->d_sb)
6267+ && au_fi(file))
e49829fe 6268+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 6269+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 6270+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 6271+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 6272+ file->f_version, file->f_pos, a);
1facf9fc 6273+ if (file->f_dentry)
6274+ do_pri_dentry(bindex, file->f_dentry);
6275+ return 0;
6276+}
6277+
6278+void au_dpri_file(struct file *file)
6279+{
6280+ struct au_finfo *finfo;
4a4d8108
AM
6281+ struct au_fidir *fidir;
6282+ struct au_hfile *hfile;
1facf9fc 6283+ aufs_bindex_t bindex;
6284+ int err;
6285+
6286+ err = do_pri_file(-1, file);
6287+ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
6288+ return;
6289+
6290+ finfo = au_fi(file);
6291+ if (!finfo)
6292+ return;
4a4d8108 6293+ if (finfo->fi_btop < 0)
1facf9fc 6294+ return;
4a4d8108
AM
6295+ fidir = finfo->fi_hdir;
6296+ if (!fidir)
6297+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
6298+ else
e49829fe
JR
6299+ for (bindex = finfo->fi_btop;
6300+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
6301+ bindex++) {
6302+ hfile = fidir->fd_hfile + bindex;
6303+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
6304+ }
1facf9fc 6305+}
6306+
6307+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
6308+{
6309+ struct vfsmount *mnt;
6310+ struct super_block *sb;
6311+
6312+ if (!br || IS_ERR(br))
6313+ goto out;
86dc4139 6314+ mnt = au_br_mnt(br);
1facf9fc 6315+ if (!mnt || IS_ERR(mnt))
6316+ goto out;
6317+ sb = mnt->mnt_sb;
6318+ if (!sb || IS_ERR(sb))
6319+ goto out;
6320+
1e00d052 6321+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 6322+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 6323+ "xino %d\n",
1e00d052
AM
6324+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
6325+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 6326+ sb->s_flags, sb->s_count,
1facf9fc 6327+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
6328+ return 0;
6329+
4f0767ce 6330+out:
1facf9fc 6331+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
6332+ return -1;
6333+}
6334+
6335+void au_dpri_sb(struct super_block *sb)
6336+{
6337+ struct au_sbinfo *sbinfo;
6338+ aufs_bindex_t bindex;
6339+ int err;
6340+ /* to reuduce stack size */
6341+ struct {
6342+ struct vfsmount mnt;
6343+ struct au_branch fake;
6344+ } *a;
6345+
6346+ /* this function can be called from magic sysrq */
6347+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
6348+ if (unlikely(!a)) {
6349+ dpri("no memory\n");
6350+ return;
6351+ }
6352+
6353+ a->mnt.mnt_sb = sb;
6354+ a->fake.br_perm = 0;
86dc4139 6355+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 6356+ a->fake.br_xino.xi_file = NULL;
6357+ atomic_set(&a->fake.br_count, 0);
6358+ smp_mb(); /* atomic_set */
6359+ err = do_pri_br(-1, &a->fake);
6360+ kfree(a);
6361+ dpri("dev 0x%x\n", sb->s_dev);
6362+ if (err || !au_test_aufs(sb))
6363+ return;
6364+
6365+ sbinfo = au_sbi(sb);
6366+ if (!sbinfo)
6367+ return;
6368+ dpri("nw %d, gen %u, kobj %d\n",
6369+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
6370+ atomic_read(&sbinfo->si_kobj.kref.refcount));
6371+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
6372+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
6373+}
6374+
6375+/* ---------------------------------------------------------------------- */
6376+
6377+void au_dbg_sleep_jiffy(int jiffy)
6378+{
6379+ while (jiffy)
6380+ jiffy = schedule_timeout_uninterruptible(jiffy);
6381+}
6382+
6383+void au_dbg_iattr(struct iattr *ia)
6384+{
c06a8ce3
AM
6385+#define AuBit(name) \
6386+ do { \
6387+ if (ia->ia_valid & ATTR_ ## name) \
6388+ dpri(#name "\n"); \
6389+ } while (0)
1facf9fc 6390+ AuBit(MODE);
6391+ AuBit(UID);
6392+ AuBit(GID);
6393+ AuBit(SIZE);
6394+ AuBit(ATIME);
6395+ AuBit(MTIME);
6396+ AuBit(CTIME);
6397+ AuBit(ATIME_SET);
6398+ AuBit(MTIME_SET);
6399+ AuBit(FORCE);
6400+ AuBit(ATTR_FLAG);
6401+ AuBit(KILL_SUID);
6402+ AuBit(KILL_SGID);
6403+ AuBit(FILE);
6404+ AuBit(KILL_PRIV);
6405+ AuBit(OPEN);
6406+ AuBit(TIMES_SET);
6407+#undef AuBit
6408+ dpri("ia_file %p\n", ia->ia_file);
6409+}
6410+
6411+/* ---------------------------------------------------------------------- */
6412+
027c5e7a
AM
6413+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
6414+{
6415+ struct inode *h_inode, *inode = dentry->d_inode;
6416+ struct dentry *h_dentry;
6417+ aufs_bindex_t bindex, bend, bi;
6418+
6419+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
6420+ return;
6421+
6422+ bend = au_dbend(dentry);
6423+ bi = au_ibend(inode);
6424+ if (bi < bend)
6425+ bend = bi;
6426+ bindex = au_dbstart(dentry);
6427+ bi = au_ibstart(inode);
6428+ if (bi > bindex)
6429+ bindex = bi;
6430+
6431+ for (; bindex <= bend; bindex++) {
6432+ h_dentry = au_h_dptr(dentry, bindex);
6433+ if (!h_dentry)
6434+ continue;
6435+ h_inode = au_h_iptr(inode, bindex);
6436+ if (unlikely(h_inode != h_dentry->d_inode)) {
392086de 6437+ au_debug_on();
027c5e7a
AM
6438+ AuDbg("b%d, %s:%d\n", bindex, func, line);
6439+ AuDbgDentry(dentry);
6440+ AuDbgInode(inode);
392086de 6441+ au_debug_off();
027c5e7a
AM
6442+ BUG();
6443+ }
6444+ }
6445+}
6446+
1facf9fc 6447+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
6448+{
6449+ struct dentry *parent;
6450+
6451+ parent = dget_parent(dentry);
027c5e7a
AM
6452+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
6453+ AuDebugOn(IS_ROOT(dentry));
6454+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6455+ dput(parent);
6456+}
6457+
6458+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
6459+{
6460+ struct dentry *parent;
027c5e7a 6461+ struct inode *inode;
1facf9fc 6462+
6463+ parent = dget_parent(dentry);
027c5e7a
AM
6464+ inode = dentry->d_inode;
6465+ AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
6466+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6467+ dput(parent);
6468+}
6469+
6470+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
6471+{
6472+ int err, i, j;
6473+ struct au_dcsub_pages dpages;
6474+ struct au_dpage *dpage;
6475+ struct dentry **dentries;
6476+
6477+ err = au_dpages_init(&dpages, GFP_NOFS);
6478+ AuDebugOn(err);
027c5e7a 6479+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 6480+ AuDebugOn(err);
6481+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
6482+ dpage = dpages.dpages + i;
6483+ dentries = dpage->dentries;
6484+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 6485+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 6486+ }
6487+ au_dpages_free(&dpages);
6488+}
6489+
1facf9fc 6490+void au_dbg_verify_kthread(void)
6491+{
53392da6 6492+ if (au_wkq_test()) {
1facf9fc 6493+ au_dbg_blocked();
1e00d052
AM
6494+ /*
6495+ * It may be recursive, but udba=notify between two aufs mounts,
6496+ * where a single ro branch is shared, is not a problem.
6497+ */
6498+ /* WARN_ON(1); */
1facf9fc 6499+ }
6500+}
6501+
6502+/* ---------------------------------------------------------------------- */
6503+
6504+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
6505+{
6506+#ifdef AuForceNoPlink
6507+ au_opt_clr(sbinfo->si_mntflags, PLINK);
6508+#endif
6509+#ifdef AuForceNoXino
6510+ au_opt_clr(sbinfo->si_mntflags, XINO);
6511+#endif
6512+#ifdef AuForceNoRefrof
6513+ au_opt_clr(sbinfo->si_mntflags, REFROF);
6514+#endif
4a4d8108
AM
6515+#ifdef AuForceHnotify
6516+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
1facf9fc 6517+#endif
1308ab2a 6518+#ifdef AuForceRd0
6519+ sbinfo->si_rdblk = 0;
6520+ sbinfo->si_rdhash = 0;
6521+#endif
1facf9fc 6522+}
6523+
6524+int __init au_debug_init(void)
6525+{
6526+ aufs_bindex_t bindex;
6527+ struct au_vdir_destr destr;
6528+
6529+ bindex = -1;
6530+ AuDebugOn(bindex >= 0);
6531+
6532+ destr.len = -1;
6533+ AuDebugOn(destr.len < NAME_MAX);
6534+
6535+#ifdef CONFIG_4KSTACKS
0c3ec466 6536+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 6537+#endif
6538+
6539+#ifdef AuForceNoBrs
6540+ sysaufs_brs = 0;
6541+#endif
6542+
6543+ return 0;
6544+}
7f207e10
AM
6545diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
6546--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 6547+++ linux/fs/aufs/debug.h 2014-04-24 22:11:10.848602379 +0200
523b37e3 6548@@ -0,0 +1,247 @@
1facf9fc 6549+/*
523b37e3 6550+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6551+ *
6552+ * This program, aufs is free software; you can redistribute it and/or modify
6553+ * it under the terms of the GNU General Public License as published by
6554+ * the Free Software Foundation; either version 2 of the License, or
6555+ * (at your option) any later version.
dece6358
AM
6556+ *
6557+ * This program is distributed in the hope that it will be useful,
6558+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6559+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6560+ * GNU General Public License for more details.
6561+ *
6562+ * You should have received a copy of the GNU General Public License
523b37e3 6563+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6564+ */
6565+
6566+/*
6567+ * debug print functions
6568+ */
6569+
6570+#ifndef __AUFS_DEBUG_H__
6571+#define __AUFS_DEBUG_H__
6572+
6573+#ifdef __KERNEL__
6574+
392086de 6575+#include <linux/atomic.h>
4a4d8108
AM
6576+#include <linux/module.h>
6577+#include <linux/kallsyms.h>
1facf9fc 6578+#include <linux/sysrq.h>
4a4d8108 6579+
1facf9fc 6580+#ifdef CONFIG_AUFS_DEBUG
6581+#define AuDebugOn(a) BUG_ON(a)
6582+
6583+/* module parameter */
392086de
AM
6584+extern atomic_t aufs_debug;
6585+static inline void au_debug_on(void)
1facf9fc 6586+{
392086de
AM
6587+ atomic_inc(&aufs_debug);
6588+}
6589+static inline void au_debug_off(void)
6590+{
6591+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 6592+}
6593+
6594+static inline int au_debug_test(void)
6595+{
392086de 6596+ return atomic_read(&aufs_debug) > 0;
1facf9fc 6597+}
6598+#else
6599+#define AuDebugOn(a) do {} while (0)
392086de
AM
6600+AuStubVoid(au_debug_on, void)
6601+AuStubVoid(au_debug_off, void)
4a4d8108 6602+AuStubInt0(au_debug_test, void)
1facf9fc 6603+#endif /* CONFIG_AUFS_DEBUG */
6604+
392086de
AM
6605+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
6606+
1facf9fc 6607+/* ---------------------------------------------------------------------- */
6608+
6609+/* debug print */
6610+
4a4d8108 6611+#define AuDbg(fmt, ...) do { \
1facf9fc 6612+ if (au_debug_test()) \
4a4d8108 6613+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 6614+} while (0)
4a4d8108
AM
6615+#define AuLabel(l) AuDbg(#l "\n")
6616+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
6617+#define AuWarn1(fmt, ...) do { \
1facf9fc 6618+ static unsigned char _c; \
6619+ if (!_c++) \
0c3ec466 6620+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 6621+} while (0)
6622+
4a4d8108 6623+#define AuErr1(fmt, ...) do { \
1facf9fc 6624+ static unsigned char _c; \
6625+ if (!_c++) \
4a4d8108 6626+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 6627+} while (0)
6628+
4a4d8108 6629+#define AuIOErr1(fmt, ...) do { \
1facf9fc 6630+ static unsigned char _c; \
6631+ if (!_c++) \
4a4d8108 6632+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 6633+} while (0)
6634+
6635+#define AuUnsupportMsg "This operation is not supported." \
6636+ " Please report this application to aufs-users ML."
4a4d8108
AM
6637+#define AuUnsupport(fmt, ...) do { \
6638+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 6639+ dump_stack(); \
6640+} while (0)
6641+
6642+#define AuTraceErr(e) do { \
6643+ if (unlikely((e) < 0)) \
6644+ AuDbg("err %d\n", (int)(e)); \
6645+} while (0)
6646+
6647+#define AuTraceErrPtr(p) do { \
6648+ if (IS_ERR(p)) \
6649+ AuDbg("err %ld\n", PTR_ERR(p)); \
6650+} while (0)
6651+
6652+/* dirty macros for debug print, use with "%.*s" and caution */
6653+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 6654+
6655+/* ---------------------------------------------------------------------- */
6656+
6657+struct au_sbinfo;
6658+struct au_finfo;
dece6358 6659+struct dentry;
1facf9fc 6660+#ifdef CONFIG_AUFS_DEBUG
6661+extern char *au_plevel;
6662+struct au_nhash;
6663+void au_dpri_whlist(struct au_nhash *whlist);
6664+struct au_vdir;
6665+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 6666+struct inode;
1facf9fc 6667+void au_dpri_inode(struct inode *inode);
2cbb1c4b 6668+void au_dpri_dalias(struct inode *inode);
1facf9fc 6669+void au_dpri_dentry(struct dentry *dentry);
dece6358 6670+struct file;
1facf9fc 6671+void au_dpri_file(struct file *filp);
dece6358 6672+struct super_block;
1facf9fc 6673+void au_dpri_sb(struct super_block *sb);
6674+
6675+void au_dbg_sleep_jiffy(int jiffy);
dece6358 6676+struct iattr;
1facf9fc 6677+void au_dbg_iattr(struct iattr *ia);
6678+
027c5e7a
AM
6679+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
6680+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 6681+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
6682+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
6683+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 6684+void au_dbg_verify_kthread(void);
6685+
6686+int __init au_debug_init(void);
6687+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
6688+#define AuDbgWhlist(w) do { \
6689+ AuDbg(#w "\n"); \
6690+ au_dpri_whlist(w); \
6691+} while (0)
6692+
6693+#define AuDbgVdir(v) do { \
6694+ AuDbg(#v "\n"); \
6695+ au_dpri_vdir(v); \
6696+} while (0)
6697+
6698+#define AuDbgInode(i) do { \
6699+ AuDbg(#i "\n"); \
6700+ au_dpri_inode(i); \
6701+} while (0)
6702+
2cbb1c4b
JR
6703+#define AuDbgDAlias(i) do { \
6704+ AuDbg(#i "\n"); \
6705+ au_dpri_dalias(i); \
6706+} while (0)
6707+
1facf9fc 6708+#define AuDbgDentry(d) do { \
6709+ AuDbg(#d "\n"); \
6710+ au_dpri_dentry(d); \
6711+} while (0)
6712+
6713+#define AuDbgFile(f) do { \
6714+ AuDbg(#f "\n"); \
6715+ au_dpri_file(f); \
6716+} while (0)
6717+
6718+#define AuDbgSb(sb) do { \
6719+ AuDbg(#sb "\n"); \
6720+ au_dpri_sb(sb); \
6721+} while (0)
6722+
6723+#define AuDbgSleep(sec) do { \
6724+ AuDbg("sleep %d sec\n", sec); \
6725+ ssleep(sec); \
6726+} while (0)
6727+
6728+#define AuDbgSleepJiffy(jiffy) do { \
6729+ AuDbg("sleep %d jiffies\n", jiffy); \
6730+ au_dbg_sleep_jiffy(jiffy); \
6731+} while (0)
6732+
6733+#define AuDbgIAttr(ia) do { \
6734+ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
6735+ au_dbg_iattr(ia); \
6736+} while (0)
4a4d8108
AM
6737+
6738+#define AuDbgSym(addr) do { \
6739+ char sym[KSYM_SYMBOL_LEN]; \
6740+ sprint_symbol(sym, (unsigned long)addr); \
6741+ AuDbg("%s\n", sym); \
6742+} while (0)
6743+
6744+#define AuInfoSym(addr) do { \
6745+ char sym[KSYM_SYMBOL_LEN]; \
6746+ sprint_symbol(sym, (unsigned long)addr); \
6747+ AuInfo("%s\n", sym); \
6748+} while (0)
1facf9fc 6749+#else
027c5e7a 6750+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
6751+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
6752+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
6753+ unsigned int sigen)
6754+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
6755+AuStubVoid(au_dbg_verify_kthread, void)
6756+AuStubInt0(__init au_debug_init, void)
6757+AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
1facf9fc 6758+
1facf9fc 6759+#define AuDbgWhlist(w) do {} while (0)
6760+#define AuDbgVdir(v) do {} while (0)
6761+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 6762+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 6763+#define AuDbgDentry(d) do {} while (0)
6764+#define AuDbgFile(f) do {} while (0)
6765+#define AuDbgSb(sb) do {} while (0)
6766+#define AuDbgSleep(sec) do {} while (0)
6767+#define AuDbgSleepJiffy(jiffy) do {} while (0)
6768+#define AuDbgIAttr(ia) do {} while (0)
4a4d8108
AM
6769+#define AuDbgSym(addr) do {} while (0)
6770+#define AuInfoSym(addr) do {} while (0)
1facf9fc 6771+#endif /* CONFIG_AUFS_DEBUG */
6772+
6773+/* ---------------------------------------------------------------------- */
6774+
6775+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
6776+int __init au_sysrq_init(void);
6777+void au_sysrq_fin(void);
6778+
6779+#ifdef CONFIG_HW_CONSOLE
6780+#define au_dbg_blocked() do { \
6781+ WARN_ON(1); \
0c5527e5 6782+ handle_sysrq('w'); \
1facf9fc 6783+} while (0)
6784+#else
4a4d8108 6785+AuStubVoid(au_dbg_blocked, void)
1facf9fc 6786+#endif
6787+
6788+#else
4a4d8108
AM
6789+AuStubInt0(__init au_sysrq_init, void)
6790+AuStubVoid(au_sysrq_fin, void)
6791+AuStubVoid(au_dbg_blocked, void)
1facf9fc 6792+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
6793+
6794+#endif /* __KERNEL__ */
6795+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
6796diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
6797--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 6798+++ linux/fs/aufs/dentry.c 2014-04-24 22:11:10.848602379 +0200
523b37e3 6799@@ -0,0 +1,1081 @@
1facf9fc 6800+/*
523b37e3 6801+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6802+ *
6803+ * This program, aufs is free software; you can redistribute it and/or modify
6804+ * it under the terms of the GNU General Public License as published by
6805+ * the Free Software Foundation; either version 2 of the License, or
6806+ * (at your option) any later version.
dece6358
AM
6807+ *
6808+ * This program is distributed in the hope that it will be useful,
6809+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6810+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6811+ * GNU General Public License for more details.
6812+ *
6813+ * You should have received a copy of the GNU General Public License
523b37e3 6814+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6815+ */
6816+
6817+/*
6818+ * lookup and dentry operations
6819+ */
6820+
dece6358 6821+#include <linux/namei.h>
1facf9fc 6822+#include "aufs.h"
6823+
1facf9fc 6824+#define AuLkup_ALLOW_NEG 1
6825+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
6826+#define au_fset_lkup(flags, name) \
6827+ do { (flags) |= AuLkup_##name; } while (0)
6828+#define au_fclr_lkup(flags, name) \
6829+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 6830+
6831+struct au_do_lookup_args {
6832+ unsigned int flags;
6833+ mode_t type;
1facf9fc 6834+};
6835+
6836+/*
6837+ * returns positive/negative dentry, NULL or an error.
6838+ * NULL means whiteout-ed or not-found.
6839+ */
6840+static struct dentry*
6841+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
6842+ aufs_bindex_t bindex, struct qstr *wh_name,
6843+ struct au_do_lookup_args *args)
6844+{
6845+ struct dentry *h_dentry;
6846+ struct inode *h_inode, *inode;
1facf9fc 6847+ struct au_branch *br;
6848+ int wh_found, opq;
6849+ unsigned char wh_able;
6850+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
6851+
1facf9fc 6852+ wh_found = 0;
6853+ br = au_sbr(dentry->d_sb, bindex);
6854+ wh_able = !!au_br_whable(br->br_perm);
6855+ if (wh_able)
6856+ wh_found = au_wh_test(h_parent, wh_name, br, /*try_sio*/0);
6857+ h_dentry = ERR_PTR(wh_found);
6858+ if (!wh_found)
6859+ goto real_lookup;
6860+ if (unlikely(wh_found < 0))
6861+ goto out;
6862+
6863+ /* We found a whiteout */
6864+ /* au_set_dbend(dentry, bindex); */
6865+ au_set_dbwh(dentry, bindex);
6866+ if (!allow_neg)
6867+ return NULL; /* success */
6868+
4f0767ce 6869+real_lookup:
b4510431 6870+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
1facf9fc 6871+ if (IS_ERR(h_dentry))
6872+ goto out;
6873+
6874+ h_inode = h_dentry->d_inode;
6875+ if (!h_inode) {
6876+ if (!allow_neg)
6877+ goto out_neg;
6878+ } else if (wh_found
6879+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
6880+ goto out_neg;
6881+
6882+ if (au_dbend(dentry) <= bindex)
6883+ au_set_dbend(dentry, bindex);
6884+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
6885+ au_set_dbstart(dentry, bindex);
6886+ au_set_h_dptr(dentry, bindex, h_dentry);
6887+
6888+ inode = dentry->d_inode;
6889+ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
6890+ || (inode && !S_ISDIR(inode->i_mode)))
6891+ goto out; /* success */
6892+
6893+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
6894+ opq = au_diropq_test(h_dentry, br);
6895+ mutex_unlock(&h_inode->i_mutex);
6896+ if (opq > 0)
6897+ au_set_dbdiropq(dentry, bindex);
6898+ else if (unlikely(opq < 0)) {
6899+ au_set_h_dptr(dentry, bindex, NULL);
6900+ h_dentry = ERR_PTR(opq);
6901+ }
6902+ goto out;
6903+
4f0767ce 6904+out_neg:
1facf9fc 6905+ dput(h_dentry);
6906+ h_dentry = NULL;
4f0767ce 6907+out:
1facf9fc 6908+ return h_dentry;
6909+}
6910+
dece6358
AM
6911+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
6912+{
6913+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
6914+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
6915+ return -EPERM;
6916+ return 0;
6917+}
6918+
1facf9fc 6919+/*
6920+ * returns the number of lower positive dentries,
6921+ * otherwise an error.
6922+ * can be called at unlinking with @type is zero.
6923+ */
537831f9 6924+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 6925+{
6926+ int npositive, err;
6927+ aufs_bindex_t bindex, btail, bdiropq;
6928+ unsigned char isdir;
6929+ struct qstr whname;
6930+ struct au_do_lookup_args args = {
b4510431 6931+ .flags = 0,
537831f9 6932+ .type = type
1facf9fc 6933+ };
6934+ const struct qstr *name = &dentry->d_name;
6935+ struct dentry *parent;
6936+ struct inode *inode;
6937+
dece6358
AM
6938+ err = au_test_shwh(dentry->d_sb, name);
6939+ if (unlikely(err))
1facf9fc 6940+ goto out;
6941+
6942+ err = au_wh_name_alloc(&whname, name);
6943+ if (unlikely(err))
6944+ goto out;
6945+
6946+ inode = dentry->d_inode;
6947+ isdir = !!(inode && S_ISDIR(inode->i_mode));
6948+ if (!type)
6949+ au_fset_lkup(args.flags, ALLOW_NEG);
6950+
6951+ npositive = 0;
4a4d8108 6952+ parent = dget_parent(dentry);
1facf9fc 6953+ btail = au_dbtaildir(parent);
6954+ for (bindex = bstart; bindex <= btail; bindex++) {
6955+ struct dentry *h_parent, *h_dentry;
6956+ struct inode *h_inode, *h_dir;
6957+
6958+ h_dentry = au_h_dptr(dentry, bindex);
6959+ if (h_dentry) {
6960+ if (h_dentry->d_inode)
6961+ npositive++;
6962+ if (type != S_IFDIR)
6963+ break;
6964+ continue;
6965+ }
6966+ h_parent = au_h_dptr(parent, bindex);
6967+ if (!h_parent)
6968+ continue;
6969+ h_dir = h_parent->d_inode;
6970+ if (!h_dir || !S_ISDIR(h_dir->i_mode))
6971+ continue;
6972+
6973+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
6974+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
6975+ &args);
6976+ mutex_unlock(&h_dir->i_mutex);
6977+ err = PTR_ERR(h_dentry);
6978+ if (IS_ERR(h_dentry))
4a4d8108 6979+ goto out_parent;
1facf9fc 6980+ au_fclr_lkup(args.flags, ALLOW_NEG);
6981+
6982+ if (au_dbwh(dentry) >= 0)
6983+ break;
6984+ if (!h_dentry)
6985+ continue;
6986+ h_inode = h_dentry->d_inode;
6987+ if (!h_inode)
6988+ continue;
6989+ npositive++;
6990+ if (!args.type)
6991+ args.type = h_inode->i_mode & S_IFMT;
6992+ if (args.type != S_IFDIR)
6993+ break;
6994+ else if (isdir) {
6995+ /* the type of lower may be different */
6996+ bdiropq = au_dbdiropq(dentry);
6997+ if (bdiropq >= 0 && bdiropq <= bindex)
6998+ break;
6999+ }
7000+ }
7001+
7002+ if (npositive) {
7003+ AuLabel(positive);
7004+ au_update_dbstart(dentry);
7005+ }
7006+ err = npositive;
7007+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
027c5e7a 7008+ && au_dbstart(dentry) < 0)) {
1facf9fc 7009+ err = -EIO;
523b37e3
AM
7010+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
7011+ dentry, err);
027c5e7a 7012+ }
1facf9fc 7013+
4f0767ce 7014+out_parent:
4a4d8108 7015+ dput(parent);
1facf9fc 7016+ kfree(whname.name);
4f0767ce 7017+out:
1facf9fc 7018+ return err;
7019+}
7020+
7021+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
7022+ struct au_branch *br)
7023+{
7024+ struct dentry *dentry;
7025+ int wkq_err;
7026+
7027+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
b4510431 7028+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 7029+ else {
b4510431
AM
7030+ struct vfsub_lkup_one_args args = {
7031+ .errp = &dentry,
7032+ .name = name,
7033+ .parent = parent
1facf9fc 7034+ };
7035+
b4510431 7036+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 7037+ if (unlikely(wkq_err))
7038+ dentry = ERR_PTR(wkq_err);
7039+ }
7040+
7041+ return dentry;
7042+}
7043+
7044+/*
7045+ * lookup @dentry on @bindex which should be negative.
7046+ */
86dc4139 7047+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 7048+{
7049+ int err;
7050+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 7051+ struct au_branch *br;
1facf9fc 7052+
1facf9fc 7053+ parent = dget_parent(dentry);
7054+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
7055+ br = au_sbr(dentry->d_sb, bindex);
7056+ if (wh)
7057+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
7058+ else
7059+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent, br);
1facf9fc 7060+ err = PTR_ERR(h_dentry);
7061+ if (IS_ERR(h_dentry))
7062+ goto out;
7063+ if (unlikely(h_dentry->d_inode)) {
7064+ err = -EIO;
523b37e3 7065+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 7066+ dput(h_dentry);
7067+ goto out;
7068+ }
7069+
4a4d8108 7070+ err = 0;
1facf9fc 7071+ if (bindex < au_dbstart(dentry))
7072+ au_set_dbstart(dentry, bindex);
7073+ if (au_dbend(dentry) < bindex)
7074+ au_set_dbend(dentry, bindex);
7075+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 7076+
4f0767ce 7077+out:
1facf9fc 7078+ dput(parent);
7079+ return err;
7080+}
7081+
7082+/* ---------------------------------------------------------------------- */
7083+
7084+/* subset of struct inode */
7085+struct au_iattr {
7086+ unsigned long i_ino;
7087+ /* unsigned int i_nlink; */
0c3ec466
AM
7088+ kuid_t i_uid;
7089+ kgid_t i_gid;
1facf9fc 7090+ u64 i_version;
7091+/*
7092+ loff_t i_size;
7093+ blkcnt_t i_blocks;
7094+*/
7095+ umode_t i_mode;
7096+};
7097+
7098+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
7099+{
7100+ ia->i_ino = h_inode->i_ino;
7101+ /* ia->i_nlink = h_inode->i_nlink; */
7102+ ia->i_uid = h_inode->i_uid;
7103+ ia->i_gid = h_inode->i_gid;
7104+ ia->i_version = h_inode->i_version;
7105+/*
7106+ ia->i_size = h_inode->i_size;
7107+ ia->i_blocks = h_inode->i_blocks;
7108+*/
7109+ ia->i_mode = (h_inode->i_mode & S_IFMT);
7110+}
7111+
7112+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
7113+{
7114+ return ia->i_ino != h_inode->i_ino
7115+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 7116+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 7117+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 7118+ || ia->i_version != h_inode->i_version
7119+/*
7120+ || ia->i_size != h_inode->i_size
7121+ || ia->i_blocks != h_inode->i_blocks
7122+*/
7123+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
7124+}
7125+
7126+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
7127+ struct au_branch *br)
7128+{
7129+ int err;
7130+ struct au_iattr ia;
7131+ struct inode *h_inode;
7132+ struct dentry *h_d;
7133+ struct super_block *h_sb;
7134+
7135+ err = 0;
7136+ memset(&ia, -1, sizeof(ia));
7137+ h_sb = h_dentry->d_sb;
7138+ h_inode = h_dentry->d_inode;
7139+ if (h_inode)
7140+ au_iattr_save(&ia, h_inode);
7141+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
7142+ /* nfs d_revalidate may return 0 for negative dentry */
7143+ /* fuse d_revalidate always return 0 for negative dentry */
7144+ goto out;
7145+
7146+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 7147+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 7148+ err = PTR_ERR(h_d);
7149+ if (IS_ERR(h_d))
7150+ goto out;
7151+
7152+ err = 0;
7153+ if (unlikely(h_d != h_dentry
7154+ || h_d->d_inode != h_inode
7155+ || (h_inode && au_iattr_test(&ia, h_inode))))
7156+ err = au_busy_or_stale();
7157+ dput(h_d);
7158+
4f0767ce 7159+out:
1facf9fc 7160+ AuTraceErr(err);
7161+ return err;
7162+}
7163+
7164+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7165+ struct dentry *h_parent, struct au_branch *br)
7166+{
7167+ int err;
7168+
7169+ err = 0;
027c5e7a
AM
7170+ if (udba == AuOpt_UDBA_REVAL
7171+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 7172+ IMustLock(h_dir);
7173+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 7174+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 7175+ err = au_h_verify_dentry(h_dentry, h_parent, br);
7176+
7177+ return err;
7178+}
7179+
7180+/* ---------------------------------------------------------------------- */
7181+
027c5e7a 7182+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 7183+{
027c5e7a 7184+ int err;
1facf9fc 7185+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
7186+ struct au_hdentry tmp, *p, *q;
7187+ struct au_dinfo *dinfo;
7188+ struct super_block *sb;
1facf9fc 7189+
027c5e7a 7190+ DiMustWriteLock(dentry);
1308ab2a 7191+
027c5e7a
AM
7192+ sb = dentry->d_sb;
7193+ dinfo = au_di(dentry);
1facf9fc 7194+ bend = dinfo->di_bend;
7195+ bwh = dinfo->di_bwh;
7196+ bdiropq = dinfo->di_bdiropq;
027c5e7a 7197+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 7198+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 7199+ if (!p->hd_dentry)
1facf9fc 7200+ continue;
7201+
027c5e7a
AM
7202+ new_bindex = au_br_index(sb, p->hd_id);
7203+ if (new_bindex == bindex)
1facf9fc 7204+ continue;
1facf9fc 7205+
1facf9fc 7206+ if (dinfo->di_bwh == bindex)
7207+ bwh = new_bindex;
7208+ if (dinfo->di_bdiropq == bindex)
7209+ bdiropq = new_bindex;
7210+ if (new_bindex < 0) {
7211+ au_hdput(p);
7212+ p->hd_dentry = NULL;
7213+ continue;
7214+ }
7215+
7216+ /* swap two lower dentries, and loop again */
7217+ q = dinfo->di_hdentry + new_bindex;
7218+ tmp = *q;
7219+ *q = *p;
7220+ *p = tmp;
7221+ if (tmp.hd_dentry) {
7222+ bindex--;
7223+ p--;
7224+ }
7225+ }
7226+
1facf9fc 7227+ dinfo->di_bwh = -1;
7228+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
7229+ dinfo->di_bwh = bwh;
7230+
7231+ dinfo->di_bdiropq = -1;
7232+ if (bdiropq >= 0
7233+ && bdiropq <= au_sbend(sb)
7234+ && au_sbr_whable(sb, bdiropq))
7235+ dinfo->di_bdiropq = bdiropq;
7236+
027c5e7a
AM
7237+ err = -EIO;
7238+ dinfo->di_bstart = -1;
7239+ dinfo->di_bend = -1;
1facf9fc 7240+ bend = au_dbend(parent);
7241+ p = dinfo->di_hdentry;
7242+ for (bindex = 0; bindex <= bend; bindex++, p++)
7243+ if (p->hd_dentry) {
7244+ dinfo->di_bstart = bindex;
7245+ break;
7246+ }
7247+
027c5e7a
AM
7248+ if (dinfo->di_bstart >= 0) {
7249+ p = dinfo->di_hdentry + bend;
7250+ for (bindex = bend; bindex >= 0; bindex--, p--)
7251+ if (p->hd_dentry) {
7252+ dinfo->di_bend = bindex;
7253+ err = 0;
7254+ break;
7255+ }
7256+ }
7257+
7258+ return err;
1facf9fc 7259+}
7260+
027c5e7a 7261+static void au_do_hide(struct dentry *dentry)
1facf9fc 7262+{
027c5e7a 7263+ struct inode *inode;
1facf9fc 7264+
027c5e7a
AM
7265+ inode = dentry->d_inode;
7266+ if (inode) {
7267+ if (!S_ISDIR(inode->i_mode)) {
7268+ if (inode->i_nlink && !d_unhashed(dentry))
7269+ drop_nlink(inode);
7270+ } else {
7271+ clear_nlink(inode);
7272+ /* stop next lookup */
7273+ inode->i_flags |= S_DEAD;
7274+ }
7275+ smp_mb(); /* necessary? */
7276+ }
7277+ d_drop(dentry);
7278+}
1308ab2a 7279+
027c5e7a
AM
7280+static int au_hide_children(struct dentry *parent)
7281+{
7282+ int err, i, j, ndentry;
7283+ struct au_dcsub_pages dpages;
7284+ struct au_dpage *dpage;
7285+ struct dentry *dentry;
1facf9fc 7286+
027c5e7a 7287+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 7288+ if (unlikely(err))
7289+ goto out;
027c5e7a
AM
7290+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
7291+ if (unlikely(err))
7292+ goto out_dpages;
1facf9fc 7293+
027c5e7a
AM
7294+ /* in reverse order */
7295+ for (i = dpages.ndpage - 1; i >= 0; i--) {
7296+ dpage = dpages.dpages + i;
7297+ ndentry = dpage->ndentry;
7298+ for (j = ndentry - 1; j >= 0; j--) {
7299+ dentry = dpage->dentries[j];
7300+ if (dentry != parent)
7301+ au_do_hide(dentry);
7302+ }
7303+ }
1facf9fc 7304+
027c5e7a
AM
7305+out_dpages:
7306+ au_dpages_free(&dpages);
4f0767ce 7307+out:
027c5e7a 7308+ return err;
1facf9fc 7309+}
7310+
027c5e7a 7311+static void au_hide(struct dentry *dentry)
1facf9fc 7312+{
027c5e7a
AM
7313+ int err;
7314+ struct inode *inode;
1facf9fc 7315+
027c5e7a
AM
7316+ AuDbgDentry(dentry);
7317+ inode = dentry->d_inode;
7318+ if (inode && S_ISDIR(inode->i_mode)) {
7319+ /* shrink_dcache_parent(dentry); */
7320+ err = au_hide_children(dentry);
7321+ if (unlikely(err))
523b37e3
AM
7322+ AuIOErr("%pd, failed hiding children, ignored %d\n",
7323+ dentry, err);
027c5e7a
AM
7324+ }
7325+ au_do_hide(dentry);
7326+}
1facf9fc 7327+
027c5e7a
AM
7328+/*
7329+ * By adding a dirty branch, a cached dentry may be affected in various ways.
7330+ *
7331+ * a dirty branch is added
7332+ * - on the top of layers
7333+ * - in the middle of layers
7334+ * - to the bottom of layers
7335+ *
7336+ * on the added branch there exists
7337+ * - a whiteout
7338+ * - a diropq
7339+ * - a same named entry
7340+ * + exist
7341+ * * negative --> positive
7342+ * * positive --> positive
7343+ * - type is unchanged
7344+ * - type is changed
7345+ * + doesn't exist
7346+ * * negative --> negative
7347+ * * positive --> negative (rejected by au_br_del() for non-dir case)
7348+ * - none
7349+ */
7350+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
7351+ struct au_dinfo *tmp)
7352+{
7353+ int err;
7354+ aufs_bindex_t bindex, bend;
7355+ struct {
7356+ struct dentry *dentry;
7357+ struct inode *inode;
7358+ mode_t mode;
7359+ } orig_h, tmp_h;
7360+ struct au_hdentry *hd;
7361+ struct inode *inode, *h_inode;
7362+ struct dentry *h_dentry;
7363+
7364+ err = 0;
7365+ AuDebugOn(dinfo->di_bstart < 0);
7366+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
7367+ orig_h.inode = orig_h.dentry->d_inode;
7368+ orig_h.mode = 0;
7369+ if (orig_h.inode)
7370+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
7371+ memset(&tmp_h, 0, sizeof(tmp_h));
7372+ if (tmp->di_bstart >= 0) {
7373+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
7374+ tmp_h.inode = tmp_h.dentry->d_inode;
7375+ if (tmp_h.inode)
7376+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
7377+ }
7378+
7379+ inode = dentry->d_inode;
7380+ if (!orig_h.inode) {
7381+ AuDbg("nagative originally\n");
7382+ if (inode) {
7383+ au_hide(dentry);
7384+ goto out;
7385+ }
7386+ AuDebugOn(inode);
7387+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7388+ AuDebugOn(dinfo->di_bdiropq != -1);
7389+
7390+ if (!tmp_h.inode) {
7391+ AuDbg("negative --> negative\n");
7392+ /* should have only one negative lower */
7393+ if (tmp->di_bstart >= 0
7394+ && tmp->di_bstart < dinfo->di_bstart) {
7395+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
7396+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7397+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
7398+ au_di_cp(dinfo, tmp);
7399+ hd = tmp->di_hdentry + tmp->di_bstart;
7400+ au_set_h_dptr(dentry, tmp->di_bstart,
7401+ dget(hd->hd_dentry));
7402+ }
7403+ au_dbg_verify_dinode(dentry);
7404+ } else {
7405+ AuDbg("negative --> positive\n");
7406+ /*
7407+ * similar to the behaviour of creating with bypassing
7408+ * aufs.
7409+ * unhash it in order to force an error in the
7410+ * succeeding create operation.
7411+ * we should not set S_DEAD here.
7412+ */
7413+ d_drop(dentry);
7414+ /* au_di_swap(tmp, dinfo); */
7415+ au_dbg_verify_dinode(dentry);
7416+ }
7417+ } else {
7418+ AuDbg("positive originally\n");
7419+ /* inode may be NULL */
7420+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
7421+ if (!tmp_h.inode) {
7422+ AuDbg("positive --> negative\n");
7423+ /* or bypassing aufs */
7424+ au_hide(dentry);
7425+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
7426+ dinfo->di_bwh = tmp->di_bwh;
7427+ if (inode)
7428+ err = au_refresh_hinode_self(inode);
7429+ au_dbg_verify_dinode(dentry);
7430+ } else if (orig_h.mode == tmp_h.mode) {
7431+ AuDbg("positive --> positive, same type\n");
7432+ if (!S_ISDIR(orig_h.mode)
7433+ && dinfo->di_bstart > tmp->di_bstart) {
7434+ /*
7435+ * similar to the behaviour of removing and
7436+ * creating.
7437+ */
7438+ au_hide(dentry);
7439+ if (inode)
7440+ err = au_refresh_hinode_self(inode);
7441+ au_dbg_verify_dinode(dentry);
7442+ } else {
7443+ /* fill empty slots */
7444+ if (dinfo->di_bstart > tmp->di_bstart)
7445+ dinfo->di_bstart = tmp->di_bstart;
7446+ if (dinfo->di_bend < tmp->di_bend)
7447+ dinfo->di_bend = tmp->di_bend;
7448+ dinfo->di_bwh = tmp->di_bwh;
7449+ dinfo->di_bdiropq = tmp->di_bdiropq;
7450+ hd = tmp->di_hdentry;
7451+ bend = dinfo->di_bend;
7452+ for (bindex = tmp->di_bstart; bindex <= bend;
7453+ bindex++) {
7454+ if (au_h_dptr(dentry, bindex))
7455+ continue;
7456+ h_dentry = hd[bindex].hd_dentry;
7457+ if (!h_dentry)
7458+ continue;
7459+ h_inode = h_dentry->d_inode;
7460+ AuDebugOn(!h_inode);
7461+ AuDebugOn(orig_h.mode
7462+ != (h_inode->i_mode
7463+ & S_IFMT));
7464+ au_set_h_dptr(dentry, bindex,
7465+ dget(h_dentry));
7466+ }
7467+ err = au_refresh_hinode(inode, dentry);
7468+ au_dbg_verify_dinode(dentry);
7469+ }
7470+ } else {
7471+ AuDbg("positive --> positive, different type\n");
7472+ /* similar to the behaviour of removing and creating */
7473+ au_hide(dentry);
7474+ if (inode)
7475+ err = au_refresh_hinode_self(inode);
7476+ au_dbg_verify_dinode(dentry);
7477+ }
7478+ }
7479+
7480+out:
7481+ return err;
7482+}
7483+
7484+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
7485+{
7486+ int err, ebrange;
7487+ unsigned int sigen;
7488+ struct au_dinfo *dinfo, *tmp;
7489+ struct super_block *sb;
7490+ struct inode *inode;
7491+
7492+ DiMustWriteLock(dentry);
7493+ AuDebugOn(IS_ROOT(dentry));
7494+ AuDebugOn(!parent->d_inode);
7495+
7496+ sb = dentry->d_sb;
7497+ inode = dentry->d_inode;
7498+ sigen = au_sigen(sb);
7499+ err = au_digen_test(parent, sigen);
7500+ if (unlikely(err))
7501+ goto out;
7502+
7503+ dinfo = au_di(dentry);
7504+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
7505+ if (unlikely(err))
7506+ goto out;
7507+ ebrange = au_dbrange_test(dentry);
7508+ if (!ebrange)
7509+ ebrange = au_do_refresh_hdentry(dentry, parent);
7510+
7511+ if (d_unhashed(dentry) || ebrange) {
7512+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
7513+ if (inode)
7514+ err = au_refresh_hinode_self(inode);
7515+ au_dbg_verify_dinode(dentry);
7516+ if (!err)
7517+ goto out_dgen; /* success */
7518+ goto out;
7519+ }
7520+
7521+ /* temporary dinfo */
7522+ AuDbgDentry(dentry);
7523+ err = -ENOMEM;
7524+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
7525+ if (unlikely(!tmp))
7526+ goto out;
7527+ au_di_swap(tmp, dinfo);
7528+ /* returns the number of positive dentries */
7529+ /*
7530+ * if current working dir is removed, it returns an error.
7531+ * but the dentry is legal.
7532+ */
537831f9 7533+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
7534+ AuDbgDentry(dentry);
7535+ au_di_swap(tmp, dinfo);
7536+ if (err == -ENOENT)
7537+ err = 0;
7538+ if (err >= 0) {
7539+ /* compare/refresh by dinfo */
7540+ AuDbgDentry(dentry);
7541+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
7542+ au_dbg_verify_dinode(dentry);
7543+ AuTraceErr(err);
7544+ }
7545+ au_rw_write_unlock(&tmp->di_rwsem);
7546+ au_di_free(tmp);
7547+ if (unlikely(err))
7548+ goto out;
7549+
7550+out_dgen:
7551+ au_update_digen(dentry);
7552+out:
7553+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 7554+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
7555+ AuDbgDentry(dentry);
7556+ }
7557+ AuTraceErr(err);
7558+ return err;
7559+}
7560+
b4510431
AM
7561+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
7562+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
7563+{
7564+ int err, valid;
027c5e7a
AM
7565+
7566+ err = 0;
7567+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
7568+ goto out;
027c5e7a
AM
7569+
7570+ AuDbg("b%d\n", bindex);
b4510431
AM
7571+ /*
7572+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
7573+ * due to whiteout and branch permission.
7574+ */
7575+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
7576+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
7577+ /* it may return tri-state */
7578+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 7579+
7580+ if (unlikely(valid < 0))
7581+ err = valid;
7582+ else if (!valid)
7583+ err = -EINVAL;
7584+
4f0767ce 7585+out:
1facf9fc 7586+ AuTraceErr(err);
7587+ return err;
7588+}
7589+
7590+/* todo: remove this */
7591+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 7592+ unsigned int flags, int do_udba)
1facf9fc 7593+{
7594+ int err;
7595+ umode_t mode, h_mode;
7596+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
523b37e3 7597+ unsigned char plus, unhashed, is_root, h_plus, h_nfs;
4a4d8108 7598+ struct inode *h_inode, *h_cached_inode;
1facf9fc 7599+ struct dentry *h_dentry;
7600+ struct qstr *name, *h_name;
7601+
7602+ err = 0;
7603+ plus = 0;
7604+ mode = 0;
1facf9fc 7605+ ibs = -1;
7606+ ibe = -1;
7607+ unhashed = !!d_unhashed(dentry);
7608+ is_root = !!IS_ROOT(dentry);
7609+ name = &dentry->d_name;
7610+
7611+ /*
7f207e10
AM
7612+ * Theoretically, REVAL test should be unnecessary in case of
7613+ * {FS,I}NOTIFY.
7614+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 7615+ * IN_ATTRIB for atime/nlink/pageio
7616+ * IN_DELETE for NFS dentry
7617+ * Let's do REVAL test too.
7618+ */
7619+ if (do_udba && inode) {
7620+ mode = (inode->i_mode & S_IFMT);
7621+ plus = (inode->i_nlink > 0);
1facf9fc 7622+ ibs = au_ibstart(inode);
7623+ ibe = au_ibend(inode);
7624+ }
7625+
7626+ bstart = au_dbstart(dentry);
7627+ btail = bstart;
7628+ if (inode && S_ISDIR(inode->i_mode))
7629+ btail = au_dbtaildir(dentry);
7630+ for (bindex = bstart; bindex <= btail; bindex++) {
7631+ h_dentry = au_h_dptr(dentry, bindex);
7632+ if (!h_dentry)
7633+ continue;
7634+
523b37e3
AM
7635+ AuDbg("b%d, %pd\n", bindex, h_dentry);
7636+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 7637+ spin_lock(&h_dentry->d_lock);
1facf9fc 7638+ h_name = &h_dentry->d_name;
7639+ if (unlikely(do_udba
7640+ && !is_root
523b37e3
AM
7641+ && ((!h_nfs
7642+ && (unhashed != !!d_unhashed(h_dentry)
7643+ || name->len != h_name->len
7644+ || memcmp(name->name, h_name->name,
7645+ name->len)))
7646+ || (h_nfs
7647+ && !(flags & LOOKUP_OPEN)
7648+ && (h_dentry->d_flags
7649+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 7650+ )) {
523b37e3
AM
7651+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
7652+ unhashed, d_unhashed(h_dentry),
7653+ dentry, h_dentry);
027c5e7a 7654+ spin_unlock(&h_dentry->d_lock);
1facf9fc 7655+ goto err;
7656+ }
027c5e7a 7657+ spin_unlock(&h_dentry->d_lock);
1facf9fc 7658+
b4510431 7659+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 7660+ if (unlikely(err))
7661+ /* do not goto err, to keep the errno */
7662+ break;
7663+
7664+ /* todo: plink too? */
7665+ if (!do_udba)
7666+ continue;
7667+
7668+ /* UDBA tests */
7669+ h_inode = h_dentry->d_inode;
7670+ if (unlikely(!!inode != !!h_inode))
7671+ goto err;
7672+
7673+ h_plus = plus;
7674+ h_mode = mode;
7675+ h_cached_inode = h_inode;
7676+ if (h_inode) {
7677+ h_mode = (h_inode->i_mode & S_IFMT);
7678+ h_plus = (h_inode->i_nlink > 0);
7679+ }
7680+ if (inode && ibs <= bindex && bindex <= ibe)
7681+ h_cached_inode = au_h_iptr(inode, bindex);
7682+
523b37e3
AM
7683+ if (!h_nfs) {
7684+ if (unlikely(plus != h_plus))
7685+ goto err;
7686+ } else {
7687+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
7688+ && !is_root
7689+ && !IS_ROOT(h_dentry)
7690+ && unhashed != d_unhashed(h_dentry)))
7691+ goto err;
7692+ }
7693+ if (unlikely(mode != h_mode
1facf9fc 7694+ || h_cached_inode != h_inode))
7695+ goto err;
7696+ continue;
7697+
f6b6e03d 7698+err:
1facf9fc 7699+ err = -EINVAL;
7700+ break;
7701+ }
7702+
523b37e3 7703+ AuTraceErr(err);
1facf9fc 7704+ return err;
7705+}
7706+
027c5e7a 7707+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 7708+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
7709+{
7710+ int err;
7711+ struct dentry *parent;
1facf9fc 7712+
027c5e7a 7713+ if (!au_digen_test(dentry, sigen))
1facf9fc 7714+ return 0;
7715+
7716+ parent = dget_parent(dentry);
7717+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 7718+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 7719+ au_dbg_verify_gen(parent, sigen);
027c5e7a 7720+ err = au_refresh_dentry(dentry, parent);
1facf9fc 7721+ di_read_unlock(parent, AuLock_IR);
7722+ dput(parent);
027c5e7a 7723+ AuTraceErr(err);
1facf9fc 7724+ return err;
7725+}
7726+
7727+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
7728+{
7729+ int err;
7730+ struct dentry *d, *parent;
7731+ struct inode *inode;
7732+
027c5e7a 7733+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 7734+ return simple_reval_dpath(dentry, sigen);
7735+
7736+ /* slow loop, keep it simple and stupid */
7737+ /* cf: au_cpup_dirs() */
7738+ err = 0;
7739+ parent = NULL;
027c5e7a 7740+ while (au_digen_test(dentry, sigen)) {
1facf9fc 7741+ d = dentry;
7742+ while (1) {
7743+ dput(parent);
7744+ parent = dget_parent(d);
027c5e7a 7745+ if (!au_digen_test(parent, sigen))
1facf9fc 7746+ break;
7747+ d = parent;
7748+ }
7749+
7750+ inode = d->d_inode;
7751+ if (d != dentry)
027c5e7a 7752+ di_write_lock_child2(d);
1facf9fc 7753+
7754+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
7755+ if (au_digen_test(d, sigen)) {
7756+ /*
7757+ * todo: consolidate with simple_reval_dpath(),
7758+ * do_refresh() and au_reval_for_attr().
7759+ */
1facf9fc 7760+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 7761+ err = au_refresh_dentry(d, parent);
1facf9fc 7762+ di_read_unlock(parent, AuLock_IR);
7763+ }
7764+
7765+ if (d != dentry)
7766+ di_write_unlock(d);
7767+ dput(parent);
7768+ if (unlikely(err))
7769+ break;
7770+ }
7771+
7772+ return err;
7773+}
7774+
7775+/*
7776+ * if valid returns 1, otherwise 0.
7777+ */
b4510431 7778+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 7779+{
7780+ int valid, err;
7781+ unsigned int sigen;
7782+ unsigned char do_udba;
7783+ struct super_block *sb;
7784+ struct inode *inode;
7785+
027c5e7a 7786+ /* todo: support rcu-walk? */
b4510431 7787+ if (flags & LOOKUP_RCU)
027c5e7a
AM
7788+ return -ECHILD;
7789+
7790+ valid = 0;
7791+ if (unlikely(!au_di(dentry)))
7792+ goto out;
7793+
7794+ inode = dentry->d_inode;
7795+ if (inode && is_bad_inode(inode))
7796+ goto out;
7797+
e49829fe 7798+ valid = 1;
1facf9fc 7799+ sb = dentry->d_sb;
e49829fe
JR
7800+ /*
7801+ * todo: very ugly
7802+ * i_mutex of parent dir may be held,
7803+ * but we should not return 'invalid' due to busy.
7804+ */
7805+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
7806+ if (unlikely(err)) {
7807+ valid = err;
027c5e7a 7808+ AuTraceErr(err);
e49829fe
JR
7809+ goto out;
7810+ }
027c5e7a
AM
7811+ if (unlikely(au_dbrange_test(dentry))) {
7812+ err = -EINVAL;
7813+ AuTraceErr(err);
7814+ goto out_dgrade;
1facf9fc 7815+ }
027c5e7a
AM
7816+
7817+ sigen = au_sigen(sb);
7818+ if (au_digen_test(dentry, sigen)) {
1facf9fc 7819+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
7820+ err = au_reval_dpath(dentry, sigen);
7821+ if (unlikely(err)) {
7822+ AuTraceErr(err);
1facf9fc 7823+ goto out_dgrade;
027c5e7a 7824+ }
1facf9fc 7825+ }
7826+ di_downgrade_lock(dentry, AuLock_IR);
7827+
1facf9fc 7828+ err = -EINVAL;
523b37e3
AM
7829+ if (!(flags & LOOKUP_OPEN)
7830+ && inode
7831+ && (IS_DEADDIR(inode) || !inode->i_nlink))
027c5e7a
AM
7832+ goto out_inval;
7833+
1facf9fc 7834+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
7835+ if (do_udba && inode) {
7836+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 7837+ struct inode *h_inode;
1facf9fc 7838+
027c5e7a
AM
7839+ if (bstart >= 0) {
7840+ h_inode = au_h_iptr(inode, bstart);
7841+ if (h_inode && au_test_higen(inode, h_inode))
7842+ goto out_inval;
7843+ }
1facf9fc 7844+ }
7845+
b4510431 7846+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 7847+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 7848+ err = -EIO;
523b37e3
AM
7849+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
7850+ dentry, err);
027c5e7a 7851+ }
e49829fe 7852+ goto out_inval;
1facf9fc 7853+
4f0767ce 7854+out_dgrade:
1facf9fc 7855+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 7856+out_inval:
1facf9fc 7857+ aufs_read_unlock(dentry, AuLock_IR);
7858+ AuTraceErr(err);
7859+ valid = !err;
e49829fe 7860+out:
027c5e7a 7861+ if (!valid) {
523b37e3 7862+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
7863+ d_drop(dentry);
7864+ }
1facf9fc 7865+ return valid;
7866+}
7867+
7868+static void aufs_d_release(struct dentry *dentry)
7869+{
027c5e7a 7870+ if (au_di(dentry)) {
4a4d8108
AM
7871+ au_di_fin(dentry);
7872+ au_hn_di_reinit(dentry);
1facf9fc 7873+ }
1facf9fc 7874+}
7875+
4a4d8108 7876+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
7877+ .d_revalidate = aufs_d_revalidate,
7878+ .d_weak_revalidate = aufs_d_revalidate,
7879+ .d_release = aufs_d_release
1facf9fc 7880+};
7f207e10
AM
7881diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
7882--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 7883+++ linux/fs/aufs/dentry.h 2014-04-24 22:11:10.848602379 +0200
523b37e3 7884@@ -0,0 +1,233 @@
1facf9fc 7885+/*
523b37e3 7886+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 7887+ *
7888+ * This program, aufs is free software; you can redistribute it and/or modify
7889+ * it under the terms of the GNU General Public License as published by
7890+ * the Free Software Foundation; either version 2 of the License, or
7891+ * (at your option) any later version.
dece6358
AM
7892+ *
7893+ * This program is distributed in the hope that it will be useful,
7894+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7895+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7896+ * GNU General Public License for more details.
7897+ *
7898+ * You should have received a copy of the GNU General Public License
523b37e3 7899+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7900+ */
7901+
7902+/*
7903+ * lookup and dentry operations
7904+ */
7905+
7906+#ifndef __AUFS_DENTRY_H__
7907+#define __AUFS_DENTRY_H__
7908+
7909+#ifdef __KERNEL__
7910+
dece6358 7911+#include <linux/dcache.h>
1facf9fc 7912+#include "rwsem.h"
7913+
1facf9fc 7914+struct au_hdentry {
7915+ struct dentry *hd_dentry;
027c5e7a 7916+ aufs_bindex_t hd_id;
1facf9fc 7917+};
7918+
7919+struct au_dinfo {
7920+ atomic_t di_generation;
7921+
dece6358 7922+ struct au_rwsem di_rwsem;
1facf9fc 7923+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
7924+ struct au_hdentry *di_hdentry;
4a4d8108 7925+} ____cacheline_aligned_in_smp;
1facf9fc 7926+
7927+/* ---------------------------------------------------------------------- */
7928+
7929+/* dentry.c */
4a4d8108 7930+extern const struct dentry_operations aufs_dop;
1facf9fc 7931+struct au_branch;
1facf9fc 7932+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent,
7933+ struct au_branch *br);
7934+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7935+ struct dentry *h_parent, struct au_branch *br);
7936+
537831f9 7937+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 7938+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 7939+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 7940+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
7941+
7942+/* dinfo.c */
4a4d8108 7943+void au_di_init_once(void *_di);
027c5e7a
AM
7944+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
7945+void au_di_free(struct au_dinfo *dinfo);
7946+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
7947+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
7948+int au_di_init(struct dentry *dentry);
7949+void au_di_fin(struct dentry *dentry);
1facf9fc 7950+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
7951+
7952+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
7953+void di_read_unlock(struct dentry *d, int flags);
7954+void di_downgrade_lock(struct dentry *d, int flags);
7955+void di_write_lock(struct dentry *d, unsigned int lsc);
7956+void di_write_unlock(struct dentry *d);
7957+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
7958+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
7959+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
7960+
7961+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 7962+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 7963+aufs_bindex_t au_dbtail(struct dentry *dentry);
7964+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
7965+
7966+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
7967+ struct dentry *h_dentry);
027c5e7a
AM
7968+int au_digen_test(struct dentry *dentry, unsigned int sigen);
7969+int au_dbrange_test(struct dentry *dentry);
1facf9fc 7970+void au_update_digen(struct dentry *dentry);
7971+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
7972+void au_update_dbstart(struct dentry *dentry);
7973+void au_update_dbend(struct dentry *dentry);
7974+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
7975+
7976+/* ---------------------------------------------------------------------- */
7977+
7978+static inline struct au_dinfo *au_di(struct dentry *dentry)
7979+{
7980+ return dentry->d_fsdata;
7981+}
7982+
7983+/* ---------------------------------------------------------------------- */
7984+
7985+/* lock subclass for dinfo */
7986+enum {
7987+ AuLsc_DI_CHILD, /* child first */
4a4d8108 7988+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 7989+ AuLsc_DI_CHILD3, /* copyup dirs */
7990+ AuLsc_DI_PARENT,
7991+ AuLsc_DI_PARENT2,
027c5e7a
AM
7992+ AuLsc_DI_PARENT3,
7993+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 7994+};
7995+
7996+/*
7997+ * di_read_lock_child, di_write_lock_child,
7998+ * di_read_lock_child2, di_write_lock_child2,
7999+ * di_read_lock_child3, di_write_lock_child3,
8000+ * di_read_lock_parent, di_write_lock_parent,
8001+ * di_read_lock_parent2, di_write_lock_parent2,
8002+ * di_read_lock_parent3, di_write_lock_parent3,
8003+ */
8004+#define AuReadLockFunc(name, lsc) \
8005+static inline void di_read_lock_##name(struct dentry *d, int flags) \
8006+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
8007+
8008+#define AuWriteLockFunc(name, lsc) \
8009+static inline void di_write_lock_##name(struct dentry *d) \
8010+{ di_write_lock(d, AuLsc_DI_##lsc); }
8011+
8012+#define AuRWLockFuncs(name, lsc) \
8013+ AuReadLockFunc(name, lsc) \
8014+ AuWriteLockFunc(name, lsc)
8015+
8016+AuRWLockFuncs(child, CHILD);
8017+AuRWLockFuncs(child2, CHILD2);
8018+AuRWLockFuncs(child3, CHILD3);
8019+AuRWLockFuncs(parent, PARENT);
8020+AuRWLockFuncs(parent2, PARENT2);
8021+AuRWLockFuncs(parent3, PARENT3);
8022+
8023+#undef AuReadLockFunc
8024+#undef AuWriteLockFunc
8025+#undef AuRWLockFuncs
8026+
8027+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
8028+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
8029+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 8030+
8031+/* ---------------------------------------------------------------------- */
8032+
8033+/* todo: memory barrier? */
8034+static inline unsigned int au_digen(struct dentry *d)
8035+{
8036+ return atomic_read(&au_di(d)->di_generation);
8037+}
8038+
8039+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
8040+{
8041+ hdentry->hd_dentry = NULL;
8042+}
8043+
8044+static inline void au_hdput(struct au_hdentry *hd)
8045+{
4a4d8108
AM
8046+ if (hd)
8047+ dput(hd->hd_dentry);
1facf9fc 8048+}
8049+
8050+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
8051+{
1308ab2a 8052+ DiMustAnyLock(dentry);
1facf9fc 8053+ return au_di(dentry)->di_bstart;
8054+}
8055+
8056+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
8057+{
1308ab2a 8058+ DiMustAnyLock(dentry);
1facf9fc 8059+ return au_di(dentry)->di_bend;
8060+}
8061+
8062+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
8063+{
1308ab2a 8064+ DiMustAnyLock(dentry);
1facf9fc 8065+ return au_di(dentry)->di_bwh;
8066+}
8067+
8068+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
8069+{
1308ab2a 8070+ DiMustAnyLock(dentry);
1facf9fc 8071+ return au_di(dentry)->di_bdiropq;
8072+}
8073+
8074+/* todo: hard/soft set? */
8075+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
8076+{
1308ab2a 8077+ DiMustWriteLock(dentry);
1facf9fc 8078+ au_di(dentry)->di_bstart = bindex;
8079+}
8080+
8081+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
8082+{
1308ab2a 8083+ DiMustWriteLock(dentry);
1facf9fc 8084+ au_di(dentry)->di_bend = bindex;
8085+}
8086+
8087+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
8088+{
1308ab2a 8089+ DiMustWriteLock(dentry);
1facf9fc 8090+ /* dbwh can be outside of bstart - bend range */
8091+ au_di(dentry)->di_bwh = bindex;
8092+}
8093+
8094+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
8095+{
1308ab2a 8096+ DiMustWriteLock(dentry);
1facf9fc 8097+ au_di(dentry)->di_bdiropq = bindex;
8098+}
8099+
8100+/* ---------------------------------------------------------------------- */
8101+
4a4d8108 8102+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 8103+static inline void au_digen_dec(struct dentry *d)
8104+{
e49829fe 8105+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 8106+}
8107+
4a4d8108 8108+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 8109+{
8110+ dentry->d_fsdata = NULL;
8111+}
8112+#else
4a4d8108
AM
8113+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
8114+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 8115+
8116+#endif /* __KERNEL__ */
8117+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
8118diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
8119--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 8120+++ linux/fs/aufs/dinfo.c 2014-04-24 22:11:10.848602379 +0200
523b37e3 8121@@ -0,0 +1,542 @@
1facf9fc 8122+/*
523b37e3 8123+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 8124+ *
8125+ * This program, aufs is free software; you can redistribute it and/or modify
8126+ * it under the terms of the GNU General Public License as published by
8127+ * the Free Software Foundation; either version 2 of the License, or
8128+ * (at your option) any later version.
dece6358
AM
8129+ *
8130+ * This program is distributed in the hope that it will be useful,
8131+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8132+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8133+ * GNU General Public License for more details.
8134+ *
8135+ * You should have received a copy of the GNU General Public License
523b37e3 8136+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8137+ */
8138+
8139+/*
8140+ * dentry private data
8141+ */
8142+
8143+#include "aufs.h"
8144+
e49829fe 8145+void au_di_init_once(void *_dinfo)
4a4d8108 8146+{
e49829fe
JR
8147+ struct au_dinfo *dinfo = _dinfo;
8148+ static struct lock_class_key aufs_di;
4a4d8108 8149+
e49829fe
JR
8150+ au_rw_init(&dinfo->di_rwsem);
8151+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
8152+}
8153+
027c5e7a 8154+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 8155+{
8156+ struct au_dinfo *dinfo;
027c5e7a 8157+ int nbr, i;
1facf9fc 8158+
8159+ dinfo = au_cache_alloc_dinfo();
8160+ if (unlikely(!dinfo))
8161+ goto out;
8162+
1facf9fc 8163+ nbr = au_sbend(sb) + 1;
8164+ if (nbr <= 0)
8165+ nbr = 1;
8166+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
8167+ if (dinfo->di_hdentry) {
8168+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
8169+ dinfo->di_bstart = -1;
8170+ dinfo->di_bend = -1;
8171+ dinfo->di_bwh = -1;
8172+ dinfo->di_bdiropq = -1;
8173+ for (i = 0; i < nbr; i++)
8174+ dinfo->di_hdentry[i].hd_id = -1;
8175+ goto out;
8176+ }
1facf9fc 8177+
1facf9fc 8178+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
8179+ dinfo = NULL;
8180+
4f0767ce 8181+out:
027c5e7a 8182+ return dinfo;
1facf9fc 8183+}
8184+
027c5e7a 8185+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 8186+{
4a4d8108
AM
8187+ struct au_hdentry *p;
8188+ aufs_bindex_t bend, bindex;
8189+
8190+ /* dentry may not be revalidated */
027c5e7a 8191+ bindex = dinfo->di_bstart;
4a4d8108 8192+ if (bindex >= 0) {
027c5e7a
AM
8193+ bend = dinfo->di_bend;
8194+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
8195+ while (bindex++ <= bend)
8196+ au_hdput(p++);
8197+ }
027c5e7a
AM
8198+ kfree(dinfo->di_hdentry);
8199+ au_cache_free_dinfo(dinfo);
8200+}
8201+
8202+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
8203+{
8204+ struct au_hdentry *p;
8205+ aufs_bindex_t bi;
8206+
8207+ AuRwMustWriteLock(&a->di_rwsem);
8208+ AuRwMustWriteLock(&b->di_rwsem);
8209+
8210+#define DiSwap(v, name) \
8211+ do { \
8212+ v = a->di_##name; \
8213+ a->di_##name = b->di_##name; \
8214+ b->di_##name = v; \
8215+ } while (0)
8216+
8217+ DiSwap(p, hdentry);
8218+ DiSwap(bi, bstart);
8219+ DiSwap(bi, bend);
8220+ DiSwap(bi, bwh);
8221+ DiSwap(bi, bdiropq);
8222+ /* smp_mb(); */
8223+
8224+#undef DiSwap
8225+}
8226+
8227+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
8228+{
8229+ AuRwMustWriteLock(&dst->di_rwsem);
8230+ AuRwMustWriteLock(&src->di_rwsem);
8231+
8232+ dst->di_bstart = src->di_bstart;
8233+ dst->di_bend = src->di_bend;
8234+ dst->di_bwh = src->di_bwh;
8235+ dst->di_bdiropq = src->di_bdiropq;
8236+ /* smp_mb(); */
8237+}
8238+
8239+int au_di_init(struct dentry *dentry)
8240+{
8241+ int err;
8242+ struct super_block *sb;
8243+ struct au_dinfo *dinfo;
8244+
8245+ err = 0;
8246+ sb = dentry->d_sb;
8247+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
8248+ if (dinfo) {
8249+ atomic_set(&dinfo->di_generation, au_sigen(sb));
8250+ /* smp_mb(); */ /* atomic_set */
8251+ dentry->d_fsdata = dinfo;
8252+ } else
8253+ err = -ENOMEM;
8254+
8255+ return err;
8256+}
8257+
8258+void au_di_fin(struct dentry *dentry)
8259+{
8260+ struct au_dinfo *dinfo;
8261+
8262+ dinfo = au_di(dentry);
8263+ AuRwDestroy(&dinfo->di_rwsem);
8264+ au_di_free(dinfo);
4a4d8108
AM
8265+}
8266+
1facf9fc 8267+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
8268+{
8269+ int err, sz;
8270+ struct au_hdentry *hdp;
8271+
1308ab2a 8272+ AuRwMustWriteLock(&dinfo->di_rwsem);
8273+
1facf9fc 8274+ err = -ENOMEM;
8275+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
8276+ if (!sz)
8277+ sz = sizeof(*hdp);
8278+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
8279+ if (hdp) {
8280+ dinfo->di_hdentry = hdp;
8281+ err = 0;
8282+ }
8283+
8284+ return err;
8285+}
8286+
8287+/* ---------------------------------------------------------------------- */
8288+
8289+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
8290+{
8291+ switch (lsc) {
8292+ case AuLsc_DI_CHILD:
8293+ ii_write_lock_child(inode);
8294+ break;
8295+ case AuLsc_DI_CHILD2:
8296+ ii_write_lock_child2(inode);
8297+ break;
8298+ case AuLsc_DI_CHILD3:
8299+ ii_write_lock_child3(inode);
8300+ break;
8301+ case AuLsc_DI_PARENT:
8302+ ii_write_lock_parent(inode);
8303+ break;
8304+ case AuLsc_DI_PARENT2:
8305+ ii_write_lock_parent2(inode);
8306+ break;
8307+ case AuLsc_DI_PARENT3:
8308+ ii_write_lock_parent3(inode);
8309+ break;
8310+ default:
8311+ BUG();
8312+ }
8313+}
8314+
8315+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
8316+{
8317+ switch (lsc) {
8318+ case AuLsc_DI_CHILD:
8319+ ii_read_lock_child(inode);
8320+ break;
8321+ case AuLsc_DI_CHILD2:
8322+ ii_read_lock_child2(inode);
8323+ break;
8324+ case AuLsc_DI_CHILD3:
8325+ ii_read_lock_child3(inode);
8326+ break;
8327+ case AuLsc_DI_PARENT:
8328+ ii_read_lock_parent(inode);
8329+ break;
8330+ case AuLsc_DI_PARENT2:
8331+ ii_read_lock_parent2(inode);
8332+ break;
8333+ case AuLsc_DI_PARENT3:
8334+ ii_read_lock_parent3(inode);
8335+ break;
8336+ default:
8337+ BUG();
8338+ }
8339+}
8340+
8341+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
8342+{
dece6358 8343+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8344+ if (d->d_inode) {
8345+ if (au_ftest_lock(flags, IW))
8346+ do_ii_write_lock(d->d_inode, lsc);
8347+ else if (au_ftest_lock(flags, IR))
8348+ do_ii_read_lock(d->d_inode, lsc);
8349+ }
8350+}
8351+
8352+void di_read_unlock(struct dentry *d, int flags)
8353+{
8354+ if (d->d_inode) {
027c5e7a
AM
8355+ if (au_ftest_lock(flags, IW)) {
8356+ au_dbg_verify_dinode(d);
1facf9fc 8357+ ii_write_unlock(d->d_inode);
027c5e7a
AM
8358+ } else if (au_ftest_lock(flags, IR)) {
8359+ au_dbg_verify_dinode(d);
1facf9fc 8360+ ii_read_unlock(d->d_inode);
027c5e7a 8361+ }
1facf9fc 8362+ }
dece6358 8363+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 8364+}
8365+
8366+void di_downgrade_lock(struct dentry *d, int flags)
8367+{
1facf9fc 8368+ if (d->d_inode && au_ftest_lock(flags, IR))
8369+ ii_downgrade_lock(d->d_inode);
dece6358 8370+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 8371+}
8372+
8373+void di_write_lock(struct dentry *d, unsigned int lsc)
8374+{
dece6358 8375+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8376+ if (d->d_inode)
8377+ do_ii_write_lock(d->d_inode, lsc);
8378+}
8379+
8380+void di_write_unlock(struct dentry *d)
8381+{
027c5e7a 8382+ au_dbg_verify_dinode(d);
1facf9fc 8383+ if (d->d_inode)
8384+ ii_write_unlock(d->d_inode);
dece6358 8385+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 8386+}
8387+
8388+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
8389+{
8390+ AuDebugOn(d1 == d2
8391+ || d1->d_inode == d2->d_inode
8392+ || d1->d_sb != d2->d_sb);
8393+
8394+ if (isdir && au_test_subdir(d1, d2)) {
8395+ di_write_lock_child(d1);
8396+ di_write_lock_child2(d2);
8397+ } else {
8398+ /* there should be no races */
8399+ di_write_lock_child(d2);
8400+ di_write_lock_child2(d1);
8401+ }
8402+}
8403+
8404+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
8405+{
8406+ AuDebugOn(d1 == d2
8407+ || d1->d_inode == d2->d_inode
8408+ || d1->d_sb != d2->d_sb);
8409+
8410+ if (isdir && au_test_subdir(d1, d2)) {
8411+ di_write_lock_parent(d1);
8412+ di_write_lock_parent2(d2);
8413+ } else {
8414+ /* there should be no races */
8415+ di_write_lock_parent(d2);
8416+ di_write_lock_parent2(d1);
8417+ }
8418+}
8419+
8420+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
8421+{
8422+ di_write_unlock(d1);
8423+ if (d1->d_inode == d2->d_inode)
dece6358 8424+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 8425+ else
8426+ di_write_unlock(d2);
8427+}
8428+
8429+/* ---------------------------------------------------------------------- */
8430+
8431+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
8432+{
8433+ struct dentry *d;
8434+
1308ab2a 8435+ DiMustAnyLock(dentry);
8436+
1facf9fc 8437+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
8438+ return NULL;
8439+ AuDebugOn(bindex < 0);
8440+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
392086de 8441+ AuDebugOn(d && d_count(d) <= 0);
1facf9fc 8442+ return d;
8443+}
8444+
2cbb1c4b
JR
8445+/*
8446+ * extended version of au_h_dptr().
8447+ * returns a hashed and positive h_dentry in bindex, NULL, or error.
8448+ */
8449+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
8450+{
8451+ struct dentry *h_dentry;
8452+ struct inode *inode, *h_inode;
8453+
8454+ inode = dentry->d_inode;
8455+ AuDebugOn(!inode);
8456+
8457+ h_dentry = NULL;
8458+ if (au_dbstart(dentry) <= bindex
8459+ && bindex <= au_dbend(dentry))
8460+ h_dentry = au_h_dptr(dentry, bindex);
8461+ if (h_dentry && !au_d_hashed_positive(h_dentry)) {
8462+ dget(h_dentry);
8463+ goto out; /* success */
8464+ }
8465+
8466+ AuDebugOn(bindex < au_ibstart(inode));
8467+ AuDebugOn(au_ibend(inode) < bindex);
8468+ h_inode = au_h_iptr(inode, bindex);
8469+ h_dentry = d_find_alias(h_inode);
8470+ if (h_dentry) {
8471+ if (!IS_ERR(h_dentry)) {
8472+ if (!au_d_hashed_positive(h_dentry))
8473+ goto out; /* success */
8474+ dput(h_dentry);
8475+ } else
8476+ goto out;
8477+ }
8478+
8479+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
8480+ h_dentry = au_plink_lkup(inode, bindex);
8481+ AuDebugOn(!h_dentry);
8482+ if (!IS_ERR(h_dentry)) {
8483+ if (!au_d_hashed_positive(h_dentry))
8484+ goto out; /* success */
8485+ dput(h_dentry);
8486+ h_dentry = NULL;
8487+ }
8488+ }
8489+
8490+out:
8491+ AuDbgDentry(h_dentry);
8492+ return h_dentry;
8493+}
8494+
1facf9fc 8495+aufs_bindex_t au_dbtail(struct dentry *dentry)
8496+{
8497+ aufs_bindex_t bend, bwh;
8498+
8499+ bend = au_dbend(dentry);
8500+ if (0 <= bend) {
8501+ bwh = au_dbwh(dentry);
8502+ if (!bwh)
8503+ return bwh;
8504+ if (0 < bwh && bwh < bend)
8505+ return bwh - 1;
8506+ }
8507+ return bend;
8508+}
8509+
8510+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
8511+{
8512+ aufs_bindex_t bend, bopq;
8513+
8514+ bend = au_dbtail(dentry);
8515+ if (0 <= bend) {
8516+ bopq = au_dbdiropq(dentry);
8517+ if (0 <= bopq && bopq < bend)
8518+ bend = bopq;
8519+ }
8520+ return bend;
8521+}
8522+
8523+/* ---------------------------------------------------------------------- */
8524+
8525+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8526+ struct dentry *h_dentry)
8527+{
8528+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 8529+ struct au_branch *br;
1facf9fc 8530+
1308ab2a 8531+ DiMustWriteLock(dentry);
8532+
4a4d8108 8533+ au_hdput(hd);
1facf9fc 8534+ hd->hd_dentry = h_dentry;
027c5e7a
AM
8535+ if (h_dentry) {
8536+ br = au_sbr(dentry->d_sb, bindex);
8537+ hd->hd_id = br->br_id;
8538+ }
8539+}
8540+
8541+int au_dbrange_test(struct dentry *dentry)
8542+{
8543+ int err;
8544+ aufs_bindex_t bstart, bend;
8545+
8546+ err = 0;
8547+ bstart = au_dbstart(dentry);
8548+ bend = au_dbend(dentry);
8549+ if (bstart >= 0)
8550+ AuDebugOn(bend < 0 && bstart > bend);
8551+ else {
8552+ err = -EIO;
8553+ AuDebugOn(bend >= 0);
8554+ }
8555+
8556+ return err;
8557+}
8558+
8559+int au_digen_test(struct dentry *dentry, unsigned int sigen)
8560+{
8561+ int err;
8562+
8563+ err = 0;
8564+ if (unlikely(au_digen(dentry) != sigen
8565+ || au_iigen_test(dentry->d_inode, sigen)))
8566+ err = -EIO;
8567+
8568+ return err;
1facf9fc 8569+}
8570+
8571+void au_update_digen(struct dentry *dentry)
8572+{
8573+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
8574+ /* smp_mb(); */ /* atomic_set */
8575+}
8576+
8577+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
8578+{
8579+ struct au_dinfo *dinfo;
8580+ struct dentry *h_d;
4a4d8108 8581+ struct au_hdentry *hdp;
1facf9fc 8582+
1308ab2a 8583+ DiMustWriteLock(dentry);
8584+
1facf9fc 8585+ dinfo = au_di(dentry);
8586+ if (!dinfo || dinfo->di_bstart < 0)
8587+ return;
8588+
4a4d8108 8589+ hdp = dinfo->di_hdentry;
1facf9fc 8590+ if (do_put_zero) {
8591+ aufs_bindex_t bindex, bend;
8592+
8593+ bend = dinfo->di_bend;
8594+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 8595+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 8596+ if (h_d && !h_d->d_inode)
8597+ au_set_h_dptr(dentry, bindex, NULL);
8598+ }
8599+ }
8600+
8601+ dinfo->di_bstart = -1;
8602+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 8603+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 8604+ break;
8605+ if (dinfo->di_bstart > dinfo->di_bend) {
8606+ dinfo->di_bstart = -1;
8607+ dinfo->di_bend = -1;
8608+ return;
8609+ }
8610+
8611+ dinfo->di_bend++;
8612+ while (0 <= --dinfo->di_bend)
4a4d8108 8613+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 8614+ break;
8615+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
8616+}
8617+
8618+void au_update_dbstart(struct dentry *dentry)
8619+{
8620+ aufs_bindex_t bindex, bend;
8621+ struct dentry *h_dentry;
8622+
8623+ bend = au_dbend(dentry);
8624+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
8625+ h_dentry = au_h_dptr(dentry, bindex);
8626+ if (!h_dentry)
8627+ continue;
8628+ if (h_dentry->d_inode) {
8629+ au_set_dbstart(dentry, bindex);
8630+ return;
8631+ }
8632+ au_set_h_dptr(dentry, bindex, NULL);
8633+ }
8634+}
8635+
8636+void au_update_dbend(struct dentry *dentry)
8637+{
8638+ aufs_bindex_t bindex, bstart;
8639+ struct dentry *h_dentry;
8640+
8641+ bstart = au_dbstart(dentry);
7f207e10 8642+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 8643+ h_dentry = au_h_dptr(dentry, bindex);
8644+ if (!h_dentry)
8645+ continue;
8646+ if (h_dentry->d_inode) {
8647+ au_set_dbend(dentry, bindex);
8648+ return;
8649+ }
8650+ au_set_h_dptr(dentry, bindex, NULL);
8651+ }
8652+}
8653+
8654+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
8655+{
8656+ aufs_bindex_t bindex, bend;
8657+
8658+ bend = au_dbend(dentry);
8659+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
8660+ if (au_h_dptr(dentry, bindex) == h_dentry)
8661+ return bindex;
8662+ return -1;
8663+}
7f207e10
AM
8664diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
8665--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 8666+++ linux/fs/aufs/dir.c 2014-04-24 22:11:10.848602379 +0200
523b37e3 8667@@ -0,0 +1,639 @@
1facf9fc 8668+/*
523b37e3 8669+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 8670+ *
8671+ * This program, aufs is free software; you can redistribute it and/or modify
8672+ * it under the terms of the GNU General Public License as published by
8673+ * the Free Software Foundation; either version 2 of the License, or
8674+ * (at your option) any later version.
dece6358
AM
8675+ *
8676+ * This program is distributed in the hope that it will be useful,
8677+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8678+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8679+ * GNU General Public License for more details.
8680+ *
8681+ * You should have received a copy of the GNU General Public License
523b37e3 8682+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8683+ */
8684+
8685+/*
8686+ * directory operations
8687+ */
8688+
8689+#include <linux/fs_stack.h>
8690+#include "aufs.h"
8691+
8692+void au_add_nlink(struct inode *dir, struct inode *h_dir)
8693+{
9dbd164d
AM
8694+ unsigned int nlink;
8695+
1facf9fc 8696+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8697+
9dbd164d
AM
8698+ nlink = dir->i_nlink;
8699+ nlink += h_dir->i_nlink - 2;
1facf9fc 8700+ if (h_dir->i_nlink < 2)
9dbd164d 8701+ nlink += 2;
f6b6e03d 8702+ smp_mb(); /* for i_nlink */
7eafdf33 8703+ /* 0 can happen in revaliding */
92d182d2 8704+ set_nlink(dir, nlink);
1facf9fc 8705+}
8706+
8707+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
8708+{
9dbd164d
AM
8709+ unsigned int nlink;
8710+
1facf9fc 8711+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
8712+
9dbd164d
AM
8713+ nlink = dir->i_nlink;
8714+ nlink -= h_dir->i_nlink - 2;
1facf9fc 8715+ if (h_dir->i_nlink < 2)
9dbd164d 8716+ nlink -= 2;
f6b6e03d 8717+ smp_mb(); /* for i_nlink */
92d182d2 8718+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 8719+ set_nlink(dir, nlink);
1facf9fc 8720+}
8721+
1308ab2a 8722+loff_t au_dir_size(struct file *file, struct dentry *dentry)
8723+{
8724+ loff_t sz;
8725+ aufs_bindex_t bindex, bend;
8726+ struct file *h_file;
8727+ struct dentry *h_dentry;
8728+
8729+ sz = 0;
8730+ if (file) {
c06a8ce3
AM
8731+ AuDebugOn(!file_inode(file));
8732+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
1308ab2a 8733+
4a4d8108 8734+ bend = au_fbend_dir(file);
1308ab2a 8735+ for (bindex = au_fbstart(file);
8736+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
8737+ bindex++) {
4a4d8108 8738+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
8739+ if (h_file && file_inode(h_file))
8740+ sz += vfsub_f_size_read(h_file);
1308ab2a 8741+ }
8742+ } else {
8743+ AuDebugOn(!dentry);
8744+ AuDebugOn(!dentry->d_inode);
8745+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
8746+
8747+ bend = au_dbtaildir(dentry);
8748+ for (bindex = au_dbstart(dentry);
8749+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
8750+ bindex++) {
8751+ h_dentry = au_h_dptr(dentry, bindex);
8752+ if (h_dentry && h_dentry->d_inode)
8753+ sz += i_size_read(h_dentry->d_inode);
8754+ }
8755+ }
8756+ if (sz < KMALLOC_MAX_SIZE)
8757+ sz = roundup_pow_of_two(sz);
8758+ if (sz > KMALLOC_MAX_SIZE)
8759+ sz = KMALLOC_MAX_SIZE;
8760+ else if (sz < NAME_MAX) {
8761+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
8762+ sz = AUFS_RDBLK_DEF;
8763+ }
8764+ return sz;
8765+}
8766+
1facf9fc 8767+/* ---------------------------------------------------------------------- */
8768+
8769+static int reopen_dir(struct file *file)
8770+{
8771+ int err;
8772+ unsigned int flags;
8773+ aufs_bindex_t bindex, btail, bstart;
8774+ struct dentry *dentry, *h_dentry;
8775+ struct file *h_file;
8776+
8777+ /* open all lower dirs */
8778+ dentry = file->f_dentry;
8779+ bstart = au_dbstart(dentry);
8780+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
8781+ au_set_h_fptr(file, bindex, NULL);
8782+ au_set_fbstart(file, bstart);
8783+
8784+ btail = au_dbtaildir(dentry);
4a4d8108 8785+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 8786+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 8787+ au_set_fbend_dir(file, btail);
1facf9fc 8788+
4a4d8108 8789+ flags = vfsub_file_flags(file);
1facf9fc 8790+ for (bindex = bstart; bindex <= btail; bindex++) {
8791+ h_dentry = au_h_dptr(dentry, bindex);
8792+ if (!h_dentry)
8793+ continue;
4a4d8108 8794+ h_file = au_hf_dir(file, bindex);
1facf9fc 8795+ if (h_file)
8796+ continue;
8797+
392086de 8798+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 8799+ err = PTR_ERR(h_file);
8800+ if (IS_ERR(h_file))
8801+ goto out; /* close all? */
8802+ au_set_h_fptr(file, bindex, h_file);
8803+ }
8804+ au_update_figen(file);
8805+ /* todo: necessary? */
8806+ /* file->f_ra = h_file->f_ra; */
8807+ err = 0;
8808+
4f0767ce 8809+out:
1facf9fc 8810+ return err;
8811+}
8812+
8813+static int do_open_dir(struct file *file, int flags)
8814+{
8815+ int err;
8816+ aufs_bindex_t bindex, btail;
8817+ struct dentry *dentry, *h_dentry;
8818+ struct file *h_file;
8819+
1308ab2a 8820+ FiMustWriteLock(file);
8821+
523b37e3 8822+ err = 0;
1facf9fc 8823+ dentry = file->f_dentry;
1facf9fc 8824+ file->f_version = dentry->d_inode->i_version;
8825+ bindex = au_dbstart(dentry);
8826+ au_set_fbstart(file, bindex);
8827+ btail = au_dbtaildir(dentry);
4a4d8108 8828+ au_set_fbend_dir(file, btail);
1facf9fc 8829+ for (; !err && bindex <= btail; bindex++) {
8830+ h_dentry = au_h_dptr(dentry, bindex);
8831+ if (!h_dentry)
8832+ continue;
8833+
392086de 8834+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 8835+ if (IS_ERR(h_file)) {
8836+ err = PTR_ERR(h_file);
8837+ break;
8838+ }
8839+ au_set_h_fptr(file, bindex, h_file);
8840+ }
8841+ au_update_figen(file);
8842+ /* todo: necessary? */
8843+ /* file->f_ra = h_file->f_ra; */
8844+ if (!err)
8845+ return 0; /* success */
8846+
8847+ /* close all */
8848+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
8849+ au_set_h_fptr(file, bindex, NULL);
8850+ au_set_fbstart(file, -1);
4a4d8108
AM
8851+ au_set_fbend_dir(file, -1);
8852+
1facf9fc 8853+ return err;
8854+}
8855+
8856+static int aufs_open_dir(struct inode *inode __maybe_unused,
8857+ struct file *file)
8858+{
4a4d8108
AM
8859+ int err;
8860+ struct super_block *sb;
8861+ struct au_fidir *fidir;
8862+
8863+ err = -ENOMEM;
8864+ sb = file->f_dentry->d_sb;
8865+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 8866+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
8867+ if (fidir) {
8868+ err = au_do_open(file, do_open_dir, fidir);
8869+ if (unlikely(err))
8870+ kfree(fidir);
8871+ }
8872+ si_read_unlock(sb);
8873+ return err;
1facf9fc 8874+}
8875+
8876+static int aufs_release_dir(struct inode *inode __maybe_unused,
8877+ struct file *file)
8878+{
8879+ struct au_vdir *vdir_cache;
4a4d8108
AM
8880+ struct au_finfo *finfo;
8881+ struct au_fidir *fidir;
8882+ aufs_bindex_t bindex, bend;
1facf9fc 8883+
4a4d8108
AM
8884+ finfo = au_fi(file);
8885+ fidir = finfo->fi_hdir;
8886+ if (fidir) {
8887+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
8888+ if (vdir_cache)
8889+ au_vdir_free(vdir_cache);
8890+
8891+ bindex = finfo->fi_btop;
8892+ if (bindex >= 0) {
8893+ /*
8894+ * calls fput() instead of filp_close(),
8895+ * since no dnotify or lock for the lower file.
8896+ */
8897+ bend = fidir->fd_bbot;
8898+ for (; bindex <= bend; bindex++)
8899+ au_set_h_fptr(file, bindex, NULL);
8900+ }
8901+ kfree(fidir);
8902+ finfo->fi_hdir = NULL;
1facf9fc 8903+ }
1facf9fc 8904+ au_finfo_fin(file);
1facf9fc 8905+ return 0;
8906+}
8907+
8908+/* ---------------------------------------------------------------------- */
8909+
4a4d8108
AM
8910+static int au_do_flush_dir(struct file *file, fl_owner_t id)
8911+{
8912+ int err;
8913+ aufs_bindex_t bindex, bend;
8914+ struct file *h_file;
8915+
8916+ err = 0;
8917+ bend = au_fbend_dir(file);
8918+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
8919+ h_file = au_hf_dir(file, bindex);
8920+ if (h_file)
8921+ err = vfsub_flush(h_file, id);
8922+ }
8923+ return err;
8924+}
8925+
8926+static int aufs_flush_dir(struct file *file, fl_owner_t id)
8927+{
8928+ return au_do_flush(file, id, au_do_flush_dir);
8929+}
8930+
8931+/* ---------------------------------------------------------------------- */
8932+
1facf9fc 8933+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
8934+{
8935+ int err;
8936+ aufs_bindex_t bend, bindex;
8937+ struct inode *inode;
8938+ struct super_block *sb;
8939+
8940+ err = 0;
8941+ sb = dentry->d_sb;
8942+ inode = dentry->d_inode;
8943+ IMustLock(inode);
8944+ bend = au_dbend(dentry);
8945+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
8946+ struct path h_path;
1facf9fc 8947+
8948+ if (au_test_ro(sb, bindex, inode))
8949+ continue;
8950+ h_path.dentry = au_h_dptr(dentry, bindex);
8951+ if (!h_path.dentry)
8952+ continue;
1facf9fc 8953+
1facf9fc 8954+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 8955+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 8956+ }
8957+
8958+ return err;
8959+}
8960+
8961+static int au_do_fsync_dir(struct file *file, int datasync)
8962+{
8963+ int err;
8964+ aufs_bindex_t bend, bindex;
8965+ struct file *h_file;
8966+ struct super_block *sb;
8967+ struct inode *inode;
1facf9fc 8968+
8969+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
8970+ if (unlikely(err))
8971+ goto out;
8972+
8973+ sb = file->f_dentry->d_sb;
c06a8ce3 8974+ inode = file_inode(file);
4a4d8108 8975+ bend = au_fbend_dir(file);
1facf9fc 8976+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 8977+ h_file = au_hf_dir(file, bindex);
1facf9fc 8978+ if (!h_file || au_test_ro(sb, bindex, inode))
8979+ continue;
8980+
53392da6 8981+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 8982+ }
8983+
4f0767ce 8984+out:
1facf9fc 8985+ return err;
8986+}
8987+
8988+/*
8989+ * @file may be NULL
8990+ */
1e00d052
AM
8991+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
8992+ int datasync)
1facf9fc 8993+{
8994+ int err;
b752ccd1 8995+ struct dentry *dentry;
1facf9fc 8996+ struct super_block *sb;
1e00d052 8997+ struct mutex *mtx;
1facf9fc 8998+
8999+ err = 0;
1e00d052
AM
9000+ dentry = file->f_dentry;
9001+ mtx = &dentry->d_inode->i_mutex;
9002+ mutex_lock(mtx);
1facf9fc 9003+ sb = dentry->d_sb;
9004+ si_noflush_read_lock(sb);
9005+ if (file)
9006+ err = au_do_fsync_dir(file, datasync);
9007+ else {
9008+ di_write_lock_child(dentry);
9009+ err = au_do_fsync_dir_no_file(dentry, datasync);
9010+ }
9011+ au_cpup_attr_timesizes(dentry->d_inode);
9012+ di_write_unlock(dentry);
9013+ if (file)
9014+ fi_write_unlock(file);
9015+
9016+ si_read_unlock(sb);
1e00d052 9017+ mutex_unlock(mtx);
1facf9fc 9018+ return err;
9019+}
9020+
9021+/* ---------------------------------------------------------------------- */
9022+
392086de 9023+static int aufs_iterate(struct file *file, struct dir_context *ctx)
1facf9fc 9024+{
9025+ int err;
9026+ struct dentry *dentry;
9dbd164d 9027+ struct inode *inode, *h_inode;
1facf9fc 9028+ struct super_block *sb;
9029+
523b37e3 9030+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 9031+
1facf9fc 9032+ dentry = file->f_dentry;
9033+ inode = dentry->d_inode;
9034+ IMustLock(inode);
9035+
9036+ sb = dentry->d_sb;
9037+ si_read_lock(sb, AuLock_FLUSH);
9038+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9039+ if (unlikely(err))
9040+ goto out;
027c5e7a
AM
9041+ err = au_alive_dir(dentry);
9042+ if (!err)
9043+ err = au_vdir_init(file);
1facf9fc 9044+ di_downgrade_lock(dentry, AuLock_IR);
9045+ if (unlikely(err))
9046+ goto out_unlock;
9047+
9dbd164d 9048+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 9049+ if (!au_test_nfsd()) {
392086de 9050+ err = au_vdir_fill_de(file, ctx);
9dbd164d 9051+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 9052+ } else {
9053+ /*
9054+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
9055+ * encode_fh() and others.
9056+ */
9dbd164d 9057+ atomic_inc(&h_inode->i_count);
1facf9fc 9058+ di_read_unlock(dentry, AuLock_IR);
9059+ si_read_unlock(sb);
392086de 9060+ err = au_vdir_fill_de(file, ctx);
1facf9fc 9061+ fsstack_copy_attr_atime(inode, h_inode);
9062+ fi_write_unlock(file);
9dbd164d 9063+ iput(h_inode);
1facf9fc 9064+
9065+ AuTraceErr(err);
9066+ return err;
9067+ }
9068+
4f0767ce 9069+out_unlock:
1facf9fc 9070+ di_read_unlock(dentry, AuLock_IR);
9071+ fi_write_unlock(file);
4f0767ce 9072+out:
1facf9fc 9073+ si_read_unlock(sb);
9074+ return err;
9075+}
9076+
9077+/* ---------------------------------------------------------------------- */
9078+
9079+#define AuTestEmpty_WHONLY 1
dece6358
AM
9080+#define AuTestEmpty_CALLED (1 << 1)
9081+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 9082+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
9083+#define au_fset_testempty(flags, name) \
9084+ do { (flags) |= AuTestEmpty_##name; } while (0)
9085+#define au_fclr_testempty(flags, name) \
9086+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 9087+
dece6358
AM
9088+#ifndef CONFIG_AUFS_SHWH
9089+#undef AuTestEmpty_SHWH
9090+#define AuTestEmpty_SHWH 0
9091+#endif
9092+
1facf9fc 9093+struct test_empty_arg {
392086de 9094+ struct dir_context ctx;
1308ab2a 9095+ struct au_nhash *whlist;
1facf9fc 9096+ unsigned int flags;
9097+ int err;
9098+ aufs_bindex_t bindex;
9099+};
9100+
392086de
AM
9101+static int test_empty_cb(struct dir_context *ctx, const char *__name,
9102+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 9103+ unsigned int d_type)
1facf9fc 9104+{
392086de
AM
9105+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
9106+ ctx);
1facf9fc 9107+ char *name = (void *)__name;
9108+
9109+ arg->err = 0;
9110+ au_fset_testempty(arg->flags, CALLED);
9111+ /* smp_mb(); */
9112+ if (name[0] == '.'
9113+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
9114+ goto out; /* success */
9115+
9116+ if (namelen <= AUFS_WH_PFX_LEN
9117+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
9118+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 9119+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9120+ arg->err = -ENOTEMPTY;
9121+ goto out;
9122+ }
9123+
9124+ name += AUFS_WH_PFX_LEN;
9125+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 9126+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9127+ arg->err = au_nhash_append_wh
1308ab2a 9128+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 9129+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 9130+
4f0767ce 9131+out:
1facf9fc 9132+ /* smp_mb(); */
9133+ AuTraceErr(arg->err);
9134+ return arg->err;
9135+}
9136+
9137+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9138+{
9139+ int err;
9140+ struct file *h_file;
9141+
9142+ h_file = au_h_open(dentry, arg->bindex,
9143+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 9144+ /*file*/NULL, /*force_wr*/0);
1facf9fc 9145+ err = PTR_ERR(h_file);
9146+ if (IS_ERR(h_file))
9147+ goto out;
9148+
9149+ err = 0;
9150+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 9151+ && !file_inode(h_file)->i_nlink)
1facf9fc 9152+ goto out_put;
9153+
9154+ do {
9155+ arg->err = 0;
9156+ au_fclr_testempty(arg->flags, CALLED);
9157+ /* smp_mb(); */
392086de 9158+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 9159+ if (err >= 0)
9160+ err = arg->err;
9161+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
9162+
4f0767ce 9163+out_put:
1facf9fc 9164+ fput(h_file);
9165+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 9166+out:
1facf9fc 9167+ return err;
9168+}
9169+
9170+struct do_test_empty_args {
9171+ int *errp;
9172+ struct dentry *dentry;
9173+ struct test_empty_arg *arg;
9174+};
9175+
9176+static void call_do_test_empty(void *args)
9177+{
9178+ struct do_test_empty_args *a = args;
9179+ *a->errp = do_test_empty(a->dentry, a->arg);
9180+}
9181+
9182+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9183+{
9184+ int err, wkq_err;
9185+ struct dentry *h_dentry;
9186+ struct inode *h_inode;
9187+
9188+ h_dentry = au_h_dptr(dentry, arg->bindex);
9189+ h_inode = h_dentry->d_inode;
53392da6 9190+ /* todo: i_mode changes anytime? */
1facf9fc 9191+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
9192+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
9193+ mutex_unlock(&h_inode->i_mutex);
9194+ if (!err)
9195+ err = do_test_empty(dentry, arg);
9196+ else {
9197+ struct do_test_empty_args args = {
9198+ .errp = &err,
9199+ .dentry = dentry,
9200+ .arg = arg
9201+ };
9202+ unsigned int flags = arg->flags;
9203+
9204+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
9205+ if (unlikely(wkq_err))
9206+ err = wkq_err;
9207+ arg->flags = flags;
9208+ }
9209+
9210+ return err;
9211+}
9212+
9213+int au_test_empty_lower(struct dentry *dentry)
9214+{
9215+ int err;
1308ab2a 9216+ unsigned int rdhash;
1facf9fc 9217+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 9218+ struct au_nhash whlist;
392086de
AM
9219+ struct test_empty_arg arg = {
9220+ .ctx = {
9221+ .actor = au_diractor(test_empty_cb)
9222+ }
9223+ };
1facf9fc 9224+
dece6358
AM
9225+ SiMustAnyLock(dentry->d_sb);
9226+
1308ab2a 9227+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
9228+ if (!rdhash)
9229+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
9230+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 9231+ if (unlikely(err))
1facf9fc 9232+ goto out;
9233+
1facf9fc 9234+ arg.flags = 0;
1308ab2a 9235+ arg.whlist = &whlist;
9236+ bstart = au_dbstart(dentry);
dece6358
AM
9237+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9238+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 9239+ arg.bindex = bstart;
9240+ err = do_test_empty(dentry, &arg);
9241+ if (unlikely(err))
9242+ goto out_whlist;
9243+
9244+ au_fset_testempty(arg.flags, WHONLY);
9245+ btail = au_dbtaildir(dentry);
9246+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
9247+ struct dentry *h_dentry;
9248+
9249+ h_dentry = au_h_dptr(dentry, bindex);
9250+ if (h_dentry && h_dentry->d_inode) {
9251+ arg.bindex = bindex;
9252+ err = do_test_empty(dentry, &arg);
9253+ }
9254+ }
9255+
4f0767ce 9256+out_whlist:
1308ab2a 9257+ au_nhash_wh_free(&whlist);
4f0767ce 9258+out:
1facf9fc 9259+ return err;
9260+}
9261+
9262+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
9263+{
9264+ int err;
392086de
AM
9265+ struct test_empty_arg arg = {
9266+ .ctx = {
9267+ .actor = au_diractor(test_empty_cb)
9268+ }
9269+ };
1facf9fc 9270+ aufs_bindex_t bindex, btail;
9271+
9272+ err = 0;
1308ab2a 9273+ arg.whlist = whlist;
1facf9fc 9274+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
9275+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9276+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 9277+ btail = au_dbtaildir(dentry);
9278+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
9279+ struct dentry *h_dentry;
9280+
9281+ h_dentry = au_h_dptr(dentry, bindex);
9282+ if (h_dentry && h_dentry->d_inode) {
9283+ arg.bindex = bindex;
9284+ err = sio_test_empty(dentry, &arg);
9285+ }
9286+ }
9287+
9288+ return err;
9289+}
9290+
9291+/* ---------------------------------------------------------------------- */
9292+
9293+const struct file_operations aufs_dir_fop = {
4a4d8108 9294+ .owner = THIS_MODULE,
027c5e7a 9295+ .llseek = default_llseek,
1facf9fc 9296+ .read = generic_read_dir,
392086de 9297+ .iterate = aufs_iterate,
1facf9fc 9298+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
9299+#ifdef CONFIG_COMPAT
9300+ .compat_ioctl = aufs_compat_ioctl_dir,
9301+#endif
1facf9fc 9302+ .open = aufs_open_dir,
9303+ .release = aufs_release_dir,
4a4d8108 9304+ .flush = aufs_flush_dir,
1facf9fc 9305+ .fsync = aufs_fsync_dir
9306+};
7f207e10
AM
9307diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
9308--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 9309+++ linux/fs/aufs/dir.h 2014-04-24 22:11:10.851935747 +0200
523b37e3 9310@@ -0,0 +1,136 @@
1facf9fc 9311+/*
523b37e3 9312+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 9313+ *
9314+ * This program, aufs is free software; you can redistribute it and/or modify
9315+ * it under the terms of the GNU General Public License as published by
9316+ * the Free Software Foundation; either version 2 of the License, or
9317+ * (at your option) any later version.
dece6358
AM
9318+ *
9319+ * This program is distributed in the hope that it will be useful,
9320+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9321+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9322+ * GNU General Public License for more details.
9323+ *
9324+ * You should have received a copy of the GNU General Public License
523b37e3 9325+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9326+ */
9327+
9328+/*
9329+ * directory operations
9330+ */
9331+
9332+#ifndef __AUFS_DIR_H__
9333+#define __AUFS_DIR_H__
9334+
9335+#ifdef __KERNEL__
9336+
9337+#include <linux/fs.h>
1facf9fc 9338+
9339+/* ---------------------------------------------------------------------- */
9340+
9341+/* need to be faster and smaller */
9342+
9343+struct au_nhash {
dece6358
AM
9344+ unsigned int nh_num;
9345+ struct hlist_head *nh_head;
1facf9fc 9346+};
9347+
9348+struct au_vdir_destr {
9349+ unsigned char len;
9350+ unsigned char name[0];
9351+} __packed;
9352+
9353+struct au_vdir_dehstr {
9354+ struct hlist_node hash;
9355+ struct au_vdir_destr *str;
4a4d8108 9356+} ____cacheline_aligned_in_smp;
1facf9fc 9357+
9358+struct au_vdir_de {
9359+ ino_t de_ino;
9360+ unsigned char de_type;
9361+ /* caution: packed */
9362+ struct au_vdir_destr de_str;
9363+} __packed;
9364+
9365+struct au_vdir_wh {
9366+ struct hlist_node wh_hash;
dece6358
AM
9367+#ifdef CONFIG_AUFS_SHWH
9368+ ino_t wh_ino;
1facf9fc 9369+ aufs_bindex_t wh_bindex;
dece6358
AM
9370+ unsigned char wh_type;
9371+#else
9372+ aufs_bindex_t wh_bindex;
9373+#endif
9374+ /* caution: packed */
1facf9fc 9375+ struct au_vdir_destr wh_str;
9376+} __packed;
9377+
9378+union au_vdir_deblk_p {
9379+ unsigned char *deblk;
9380+ struct au_vdir_de *de;
9381+};
9382+
9383+struct au_vdir {
9384+ unsigned char **vd_deblk;
9385+ unsigned long vd_nblk;
1facf9fc 9386+ struct {
9387+ unsigned long ul;
9388+ union au_vdir_deblk_p p;
9389+ } vd_last;
9390+
9391+ unsigned long vd_version;
dece6358 9392+ unsigned int vd_deblk_sz;
1facf9fc 9393+ unsigned long vd_jiffy;
4a4d8108 9394+} ____cacheline_aligned_in_smp;
1facf9fc 9395+
9396+/* ---------------------------------------------------------------------- */
9397+
9398+/* dir.c */
9399+extern const struct file_operations aufs_dir_fop;
9400+void au_add_nlink(struct inode *dir, struct inode *h_dir);
9401+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 9402+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 9403+int au_test_empty_lower(struct dentry *dentry);
9404+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
9405+
9406+/* vdir.c */
1308ab2a 9407+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
9408+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
9409+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 9410+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
9411+ int limit);
dece6358
AM
9412+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
9413+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
9414+ unsigned int d_type, aufs_bindex_t bindex,
9415+ unsigned char shwh);
1facf9fc 9416+void au_vdir_free(struct au_vdir *vdir);
9417+int au_vdir_init(struct file *file);
392086de 9418+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 9419+
9420+/* ioctl.c */
9421+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
9422+
1308ab2a 9423+#ifdef CONFIG_AUFS_RDU
9424+/* rdu.c */
9425+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
9426+#ifdef CONFIG_COMPAT
9427+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9428+ unsigned long arg);
9429+#endif
1308ab2a 9430+#else
9431+static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
9432+ unsigned long arg)
9433+{
9434+ return -EINVAL;
9435+}
b752ccd1
AM
9436+#ifdef CONFIG_COMPAT
9437+static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9438+ unsigned long arg)
9439+{
9440+ return -EINVAL;
9441+}
9442+#endif
1308ab2a 9443+#endif
9444+
1facf9fc 9445+#endif /* __KERNEL__ */
9446+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
9447diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
9448--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 9449+++ linux/fs/aufs/dynop.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 9450@@ -0,0 +1,379 @@
1facf9fc 9451+/*
523b37e3 9452+ * Copyright (C) 2010-2014 Junjiro R. Okajima
1facf9fc 9453+ *
9454+ * This program, aufs is free software; you can redistribute it and/or modify
9455+ * it under the terms of the GNU General Public License as published by
9456+ * the Free Software Foundation; either version 2 of the License, or
9457+ * (at your option) any later version.
dece6358
AM
9458+ *
9459+ * This program is distributed in the hope that it will be useful,
9460+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9461+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9462+ * GNU General Public License for more details.
9463+ *
9464+ * You should have received a copy of the GNU General Public License
523b37e3 9465+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9466+ */
9467+
9468+/*
4a4d8108 9469+ * dynamically customizable operations for regular files
1facf9fc 9470+ */
9471+
1facf9fc 9472+#include "aufs.h"
9473+
4a4d8108 9474+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 9475+
4a4d8108
AM
9476+/*
9477+ * How large will these lists be?
9478+ * Usually just a few elements, 20-30 at most for each, I guess.
9479+ */
9480+static struct au_splhead dynop[AuDyLast];
9481+
9482+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 9483+{
4a4d8108
AM
9484+ struct au_dykey *key, *tmp;
9485+ struct list_head *head;
1facf9fc 9486+
4a4d8108
AM
9487+ key = NULL;
9488+ head = &spl->head;
9489+ rcu_read_lock();
9490+ list_for_each_entry_rcu(tmp, head, dk_list)
9491+ if (tmp->dk_op.dy_hop == h_op) {
9492+ key = tmp;
9493+ kref_get(&key->dk_kref);
9494+ break;
9495+ }
9496+ rcu_read_unlock();
9497+
9498+ return key;
1facf9fc 9499+}
9500+
4a4d8108 9501+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 9502+{
4a4d8108
AM
9503+ struct au_dykey **k, *found;
9504+ const void *h_op = key->dk_op.dy_hop;
9505+ int i;
1facf9fc 9506+
4a4d8108
AM
9507+ found = NULL;
9508+ k = br->br_dykey;
9509+ for (i = 0; i < AuBrDynOp; i++)
9510+ if (k[i]) {
9511+ if (k[i]->dk_op.dy_hop == h_op) {
9512+ found = k[i];
9513+ break;
9514+ }
9515+ } else
9516+ break;
9517+ if (!found) {
9518+ spin_lock(&br->br_dykey_lock);
9519+ for (; i < AuBrDynOp; i++)
9520+ if (k[i]) {
9521+ if (k[i]->dk_op.dy_hop == h_op) {
9522+ found = k[i];
9523+ break;
9524+ }
9525+ } else {
9526+ k[i] = key;
9527+ break;
9528+ }
9529+ spin_unlock(&br->br_dykey_lock);
9530+ BUG_ON(i == AuBrDynOp); /* expand the array */
9531+ }
9532+
9533+ return found;
1facf9fc 9534+}
9535+
4a4d8108
AM
9536+/* kref_get() if @key is already added */
9537+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
9538+{
9539+ struct au_dykey *tmp, *found;
9540+ struct list_head *head;
9541+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 9542+
4a4d8108
AM
9543+ found = NULL;
9544+ head = &spl->head;
9545+ spin_lock(&spl->spin);
9546+ list_for_each_entry(tmp, head, dk_list)
9547+ if (tmp->dk_op.dy_hop == h_op) {
9548+ kref_get(&tmp->dk_kref);
9549+ found = tmp;
9550+ break;
9551+ }
9552+ if (!found)
9553+ list_add_rcu(&key->dk_list, head);
9554+ spin_unlock(&spl->spin);
1facf9fc 9555+
4a4d8108
AM
9556+ if (!found)
9557+ DyPrSym(key);
9558+ return found;
9559+}
9560+
9561+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 9562+{
4a4d8108
AM
9563+ struct au_dykey *key;
9564+
9565+ key = container_of(rcu, struct au_dykey, dk_rcu);
9566+ DyPrSym(key);
9567+ kfree(key);
1facf9fc 9568+}
9569+
4a4d8108
AM
9570+static void dy_free(struct kref *kref)
9571+{
9572+ struct au_dykey *key;
9573+ struct au_splhead *spl;
1facf9fc 9574+
4a4d8108
AM
9575+ key = container_of(kref, struct au_dykey, dk_kref);
9576+ spl = dynop + key->dk_op.dy_type;
9577+ au_spl_del_rcu(&key->dk_list, spl);
9578+ call_rcu(&key->dk_rcu, dy_free_rcu);
9579+}
9580+
9581+void au_dy_put(struct au_dykey *key)
1facf9fc 9582+{
4a4d8108
AM
9583+ kref_put(&key->dk_kref, dy_free);
9584+}
1facf9fc 9585+
4a4d8108
AM
9586+/* ---------------------------------------------------------------------- */
9587+
9588+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
9589+
9590+#ifdef CONFIG_AUFS_DEBUG
9591+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 9592+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
9593+#else
9594+#define DyDbgDeclare(cnt) do {} while (0)
9595+#define DyDbgInc(cnt) do {} while (0)
9596+#endif
9597+
9598+#define DySet(func, dst, src, h_op, h_sb) do { \
9599+ DyDbgInc(cnt); \
9600+ if (h_op->func) { \
9601+ if (src.func) \
9602+ dst.func = src.func; \
9603+ else \
9604+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
9605+ } \
9606+} while (0)
9607+
9608+#define DySetForce(func, dst, src) do { \
9609+ AuDebugOn(!src.func); \
9610+ DyDbgInc(cnt); \
9611+ dst.func = src.func; \
9612+} while (0)
9613+
9614+#define DySetAop(func) \
9615+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
9616+#define DySetAopForce(func) \
9617+ DySetForce(func, dyaop->da_op, aufs_aop)
9618+
9619+static void dy_aop(struct au_dykey *key, const void *h_op,
9620+ struct super_block *h_sb __maybe_unused)
9621+{
9622+ struct au_dyaop *dyaop = (void *)key;
9623+ const struct address_space_operations *h_aop = h_op;
9624+ DyDbgDeclare(cnt);
9625+
9626+ AuDbg("%s\n", au_sbtype(h_sb));
9627+
9628+ DySetAop(writepage);
9629+ DySetAopForce(readpage); /* force */
4a4d8108
AM
9630+ DySetAop(writepages);
9631+ DySetAop(set_page_dirty);
9632+ DySetAop(readpages);
9633+ DySetAop(write_begin);
9634+ DySetAop(write_end);
9635+ DySetAop(bmap);
9636+ DySetAop(invalidatepage);
9637+ DySetAop(releasepage);
027c5e7a 9638+ DySetAop(freepage);
4a4d8108
AM
9639+ /* these two will be changed according to an aufs mount option */
9640+ DySetAop(direct_IO);
9641+ DySetAop(get_xip_mem);
9642+ DySetAop(migratepage);
9643+ DySetAop(launder_page);
9644+ DySetAop(is_partially_uptodate);
392086de 9645+ DySetAop(is_dirty_writeback);
4a4d8108 9646+ DySetAop(error_remove_page);
b4510431
AM
9647+ DySetAop(swap_activate);
9648+ DySetAop(swap_deactivate);
4a4d8108
AM
9649+
9650+ DyDbgSize(cnt, *h_aop);
9651+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
9652+}
9653+
4a4d8108
AM
9654+/* ---------------------------------------------------------------------- */
9655+
9656+static void dy_bug(struct kref *kref)
9657+{
9658+ BUG();
9659+}
9660+
9661+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
9662+{
9663+ struct au_dykey *key, *old;
9664+ struct au_splhead *spl;
b752ccd1 9665+ struct op {
4a4d8108 9666+ unsigned int sz;
b752ccd1
AM
9667+ void (*set)(struct au_dykey *key, const void *h_op,
9668+ struct super_block *h_sb __maybe_unused);
9669+ };
9670+ static const struct op a[] = {
4a4d8108
AM
9671+ [AuDy_AOP] = {
9672+ .sz = sizeof(struct au_dyaop),
b752ccd1 9673+ .set = dy_aop
4a4d8108 9674+ }
b752ccd1
AM
9675+ };
9676+ const struct op *p;
4a4d8108
AM
9677+
9678+ spl = dynop + op->dy_type;
9679+ key = dy_gfind_get(spl, op->dy_hop);
9680+ if (key)
9681+ goto out_add; /* success */
9682+
9683+ p = a + op->dy_type;
9684+ key = kzalloc(p->sz, GFP_NOFS);
9685+ if (unlikely(!key)) {
9686+ key = ERR_PTR(-ENOMEM);
9687+ goto out;
9688+ }
9689+
9690+ key->dk_op.dy_hop = op->dy_hop;
9691+ kref_init(&key->dk_kref);
86dc4139 9692+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
9693+ old = dy_gadd(spl, key);
9694+ if (old) {
9695+ kfree(key);
9696+ key = old;
9697+ }
9698+
9699+out_add:
9700+ old = dy_bradd(br, key);
9701+ if (old)
9702+ /* its ref-count should never be zero here */
9703+ kref_put(&key->dk_kref, dy_bug);
9704+out:
9705+ return key;
9706+}
9707+
9708+/* ---------------------------------------------------------------------- */
9709+/*
9710+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
9711+ * This behaviour is neccessary to return an error from open(O_DIRECT) instead
9712+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
9713+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
9714+ * See the aufs manual in detail.
9715+ *
9716+ * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
9717+ * performance of fadvise() and madvise() may be affected.
9718+ */
9719+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
9720+{
9721+ if (!do_dx) {
9722+ dyaop->da_op.direct_IO = NULL;
9723+ dyaop->da_op.get_xip_mem = NULL;
9724+ } else {
9725+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
9726+ dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
9727+ if (!dyaop->da_get_xip_mem)
9728+ dyaop->da_op.get_xip_mem = NULL;
9729+ }
9730+}
9731+
9732+static struct au_dyaop *dy_aget(struct au_branch *br,
9733+ const struct address_space_operations *h_aop,
9734+ int do_dx)
9735+{
9736+ struct au_dyaop *dyaop;
9737+ struct au_dynop op;
9738+
9739+ op.dy_type = AuDy_AOP;
9740+ op.dy_haop = h_aop;
9741+ dyaop = (void *)dy_get(&op, br);
9742+ if (IS_ERR(dyaop))
9743+ goto out;
9744+ dy_adx(dyaop, do_dx);
9745+
9746+out:
9747+ return dyaop;
9748+}
9749+
9750+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9751+ struct inode *h_inode)
9752+{
9753+ int err, do_dx;
9754+ struct super_block *sb;
9755+ struct au_branch *br;
9756+ struct au_dyaop *dyaop;
9757+
9758+ AuDebugOn(!S_ISREG(h_inode->i_mode));
9759+ IiMustWriteLock(inode);
9760+
9761+ sb = inode->i_sb;
9762+ br = au_sbr(sb, bindex);
9763+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
9764+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
9765+ err = PTR_ERR(dyaop);
9766+ if (IS_ERR(dyaop))
9767+ /* unnecessary to call dy_fput() */
9768+ goto out;
9769+
9770+ err = 0;
9771+ inode->i_mapping->a_ops = &dyaop->da_op;
9772+
9773+out:
9774+ return err;
9775+}
9776+
b752ccd1
AM
9777+/*
9778+ * Is it safe to replace a_ops during the inode/file is in operation?
9779+ * Yes, I hope so.
9780+ */
9781+int au_dy_irefresh(struct inode *inode)
9782+{
9783+ int err;
9784+ aufs_bindex_t bstart;
9785+ struct inode *h_inode;
9786+
9787+ err = 0;
9788+ if (S_ISREG(inode->i_mode)) {
9789+ bstart = au_ibstart(inode);
9790+ h_inode = au_h_iptr(inode, bstart);
9791+ err = au_dy_iaop(inode, bstart, h_inode);
9792+ }
9793+ return err;
9794+}
9795+
4a4d8108
AM
9796+void au_dy_arefresh(int do_dx)
9797+{
9798+ struct au_splhead *spl;
9799+ struct list_head *head;
9800+ struct au_dykey *key;
9801+
9802+ spl = dynop + AuDy_AOP;
9803+ head = &spl->head;
9804+ spin_lock(&spl->spin);
9805+ list_for_each_entry(key, head, dk_list)
9806+ dy_adx((void *)key, do_dx);
9807+ spin_unlock(&spl->spin);
9808+}
9809+
4a4d8108
AM
9810+/* ---------------------------------------------------------------------- */
9811+
9812+void __init au_dy_init(void)
9813+{
9814+ int i;
9815+
9816+ /* make sure that 'struct au_dykey *' can be any type */
9817+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
9818+
9819+ for (i = 0; i < AuDyLast; i++)
9820+ au_spl_init(dynop + i);
9821+}
9822+
9823+void au_dy_fin(void)
9824+{
9825+ int i;
9826+
9827+ for (i = 0; i < AuDyLast; i++)
9828+ WARN_ON(!list_empty(&dynop[i].head));
9829+}
7f207e10
AM
9830diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
9831--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 9832+++ linux/fs/aufs/dynop.h 2014-04-24 22:11:10.851935747 +0200
523b37e3 9833@@ -0,0 +1,75 @@
4a4d8108 9834+/*
523b37e3 9835+ * Copyright (C) 2010-2014 Junjiro R. Okajima
4a4d8108
AM
9836+ *
9837+ * This program, aufs is free software; you can redistribute it and/or modify
9838+ * it under the terms of the GNU General Public License as published by
9839+ * the Free Software Foundation; either version 2 of the License, or
9840+ * (at your option) any later version.
9841+ *
9842+ * This program is distributed in the hope that it will be useful,
9843+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9844+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9845+ * GNU General Public License for more details.
9846+ *
9847+ * You should have received a copy of the GNU General Public License
523b37e3 9848+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
9849+ */
9850+
9851+/*
9852+ * dynamically customizable operations (for regular files only)
9853+ */
9854+
9855+#ifndef __AUFS_DYNOP_H__
9856+#define __AUFS_DYNOP_H__
9857+
9858+#ifdef __KERNEL__
9859+
4a4d8108
AM
9860+#include "inode.h"
9861+
2cbb1c4b 9862+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
9863+
9864+struct au_dynop {
9865+ int dy_type;
9866+ union {
9867+ const void *dy_hop;
9868+ const struct address_space_operations *dy_haop;
4a4d8108
AM
9869+ };
9870+};
9871+
9872+struct au_dykey {
9873+ union {
9874+ struct list_head dk_list;
9875+ struct rcu_head dk_rcu;
9876+ };
9877+ struct au_dynop dk_op;
9878+
9879+ /*
9880+ * during I am in the branch local array, kref is gotten. when the
9881+ * branch is removed, kref is put.
9882+ */
9883+ struct kref dk_kref;
9884+};
9885+
9886+/* stop unioning since their sizes are very different from each other */
9887+struct au_dyaop {
9888+ struct au_dykey da_key;
9889+ struct address_space_operations da_op; /* not const */
9890+ int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
9891+ void **, unsigned long *);
9892+};
9893+
4a4d8108
AM
9894+/* ---------------------------------------------------------------------- */
9895+
9896+/* dynop.c */
9897+struct au_branch;
9898+void au_dy_put(struct au_dykey *key);
9899+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
9900+ struct inode *h_inode);
b752ccd1 9901+int au_dy_irefresh(struct inode *inode);
4a4d8108 9902+void au_dy_arefresh(int do_dio);
4a4d8108
AM
9903+
9904+void __init au_dy_init(void);
9905+void au_dy_fin(void);
9906+
4a4d8108
AM
9907+#endif /* __KERNEL__ */
9908+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
9909diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
9910--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 9911+++ linux/fs/aufs/export.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 9912@@ -0,0 +1,831 @@
4a4d8108 9913+/*
523b37e3 9914+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
9915+ *
9916+ * This program, aufs is free software; you can redistribute it and/or modify
9917+ * it under the terms of the GNU General Public License as published by
9918+ * the Free Software Foundation; either version 2 of the License, or
9919+ * (at your option) any later version.
9920+ *
9921+ * This program is distributed in the hope that it will be useful,
9922+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9923+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9924+ * GNU General Public License for more details.
9925+ *
9926+ * You should have received a copy of the GNU General Public License
523b37e3 9927+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
9928+ */
9929+
9930+/*
9931+ * export via nfs
9932+ */
9933+
9934+#include <linux/exportfs.h>
7eafdf33 9935+#include <linux/fs_struct.h>
4a4d8108
AM
9936+#include <linux/namei.h>
9937+#include <linux/nsproxy.h>
9938+#include <linux/random.h>
9939+#include <linux/writeback.h>
7eafdf33 9940+#include "../fs/mount.h"
4a4d8108
AM
9941+#include "aufs.h"
9942+
9943+union conv {
9944+#ifdef CONFIG_AUFS_INO_T_64
9945+ __u32 a[2];
9946+#else
9947+ __u32 a[1];
9948+#endif
9949+ ino_t ino;
9950+};
9951+
9952+static ino_t decode_ino(__u32 *a)
9953+{
9954+ union conv u;
9955+
9956+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
9957+ u.a[0] = a[0];
9958+#ifdef CONFIG_AUFS_INO_T_64
9959+ u.a[1] = a[1];
9960+#endif
9961+ return u.ino;
9962+}
9963+
9964+static void encode_ino(__u32 *a, ino_t ino)
9965+{
9966+ union conv u;
9967+
9968+ u.ino = ino;
9969+ a[0] = u.a[0];
9970+#ifdef CONFIG_AUFS_INO_T_64
9971+ a[1] = u.a[1];
9972+#endif
9973+}
9974+
9975+/* NFS file handle */
9976+enum {
9977+ Fh_br_id,
9978+ Fh_sigen,
9979+#ifdef CONFIG_AUFS_INO_T_64
9980+ /* support 64bit inode number */
9981+ Fh_ino1,
9982+ Fh_ino2,
9983+ Fh_dir_ino1,
9984+ Fh_dir_ino2,
9985+#else
9986+ Fh_ino1,
9987+ Fh_dir_ino1,
9988+#endif
9989+ Fh_igen,
9990+ Fh_h_type,
9991+ Fh_tail,
9992+
9993+ Fh_ino = Fh_ino1,
9994+ Fh_dir_ino = Fh_dir_ino1
9995+};
9996+
9997+static int au_test_anon(struct dentry *dentry)
9998+{
027c5e7a 9999+ /* note: read d_flags without d_lock */
4a4d8108
AM
10000+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
10001+}
10002+
a2a7ad62
AM
10003+int au_test_nfsd(void)
10004+{
10005+ int ret;
10006+ struct task_struct *tsk = current;
10007+ char comm[sizeof(tsk->comm)];
10008+
10009+ ret = 0;
10010+ if (tsk->flags & PF_KTHREAD) {
10011+ get_task_comm(comm, tsk);
10012+ ret = !strcmp(comm, "nfsd");
10013+ }
10014+
10015+ return ret;
10016+}
10017+
4a4d8108
AM
10018+/* ---------------------------------------------------------------------- */
10019+/* inode generation external table */
10020+
b752ccd1 10021+void au_xigen_inc(struct inode *inode)
4a4d8108 10022+{
4a4d8108
AM
10023+ loff_t pos;
10024+ ssize_t sz;
10025+ __u32 igen;
10026+ struct super_block *sb;
10027+ struct au_sbinfo *sbinfo;
10028+
4a4d8108 10029+ sb = inode->i_sb;
b752ccd1 10030+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 10031+
b752ccd1 10032+ sbinfo = au_sbi(sb);
1facf9fc 10033+ pos = inode->i_ino;
10034+ pos *= sizeof(igen);
10035+ igen = inode->i_generation + 1;
1facf9fc 10036+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
10037+ sizeof(igen), &pos);
10038+ if (sz == sizeof(igen))
b752ccd1 10039+ return; /* success */
1facf9fc 10040+
b752ccd1 10041+ if (unlikely(sz >= 0))
1facf9fc 10042+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 10043+}
10044+
10045+int au_xigen_new(struct inode *inode)
10046+{
10047+ int err;
10048+ loff_t pos;
10049+ ssize_t sz;
10050+ struct super_block *sb;
10051+ struct au_sbinfo *sbinfo;
10052+ struct file *file;
10053+
10054+ err = 0;
10055+ /* todo: dirty, at mount time */
10056+ if (inode->i_ino == AUFS_ROOT_INO)
10057+ goto out;
10058+ sb = inode->i_sb;
dece6358 10059+ SiMustAnyLock(sb);
1facf9fc 10060+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10061+ goto out;
10062+
10063+ err = -EFBIG;
10064+ pos = inode->i_ino;
10065+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
10066+ AuIOErr1("too large i%lld\n", pos);
10067+ goto out;
10068+ }
10069+ pos *= sizeof(inode->i_generation);
10070+
10071+ err = 0;
10072+ sbinfo = au_sbi(sb);
10073+ file = sbinfo->si_xigen;
10074+ BUG_ON(!file);
10075+
c06a8ce3 10076+ if (vfsub_f_size_read(file)
1facf9fc 10077+ < pos + sizeof(inode->i_generation)) {
10078+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
10079+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
10080+ sizeof(inode->i_generation), &pos);
10081+ } else
10082+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
10083+ sizeof(inode->i_generation), &pos);
10084+ if (sz == sizeof(inode->i_generation))
10085+ goto out; /* success */
10086+
10087+ err = sz;
10088+ if (unlikely(sz >= 0)) {
10089+ err = -EIO;
10090+ AuIOErr("xigen error (%zd)\n", sz);
10091+ }
10092+
4f0767ce 10093+out:
1facf9fc 10094+ return err;
10095+}
10096+
10097+int au_xigen_set(struct super_block *sb, struct file *base)
10098+{
10099+ int err;
10100+ struct au_sbinfo *sbinfo;
10101+ struct file *file;
10102+
dece6358
AM
10103+ SiMustWriteLock(sb);
10104+
1facf9fc 10105+ sbinfo = au_sbi(sb);
10106+ file = au_xino_create2(base, sbinfo->si_xigen);
10107+ err = PTR_ERR(file);
10108+ if (IS_ERR(file))
10109+ goto out;
10110+ err = 0;
10111+ if (sbinfo->si_xigen)
10112+ fput(sbinfo->si_xigen);
10113+ sbinfo->si_xigen = file;
10114+
4f0767ce 10115+out:
1facf9fc 10116+ return err;
10117+}
10118+
10119+void au_xigen_clr(struct super_block *sb)
10120+{
10121+ struct au_sbinfo *sbinfo;
10122+
dece6358
AM
10123+ SiMustWriteLock(sb);
10124+
1facf9fc 10125+ sbinfo = au_sbi(sb);
10126+ if (sbinfo->si_xigen) {
10127+ fput(sbinfo->si_xigen);
10128+ sbinfo->si_xigen = NULL;
10129+ }
10130+}
10131+
10132+/* ---------------------------------------------------------------------- */
10133+
10134+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
10135+ ino_t dir_ino)
10136+{
10137+ struct dentry *dentry, *d;
10138+ struct inode *inode;
10139+ unsigned int sigen;
10140+
10141+ dentry = NULL;
10142+ inode = ilookup(sb, ino);
10143+ if (!inode)
10144+ goto out;
10145+
10146+ dentry = ERR_PTR(-ESTALE);
10147+ sigen = au_sigen(sb);
10148+ if (unlikely(is_bad_inode(inode)
10149+ || IS_DEADDIR(inode)
537831f9 10150+ || sigen != au_iigen(inode, NULL)))
1facf9fc 10151+ goto out_iput;
10152+
10153+ dentry = NULL;
10154+ if (!dir_ino || S_ISDIR(inode->i_mode))
10155+ dentry = d_find_alias(inode);
10156+ else {
027c5e7a 10157+ spin_lock(&inode->i_lock);
c06a8ce3 10158+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 10159+ spin_lock(&d->d_lock);
1facf9fc 10160+ if (!au_test_anon(d)
10161+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
10162+ dentry = dget_dlock(d);
10163+ spin_unlock(&d->d_lock);
1facf9fc 10164+ break;
10165+ }
027c5e7a
AM
10166+ spin_unlock(&d->d_lock);
10167+ }
10168+ spin_unlock(&inode->i_lock);
1facf9fc 10169+ }
027c5e7a 10170+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 10171+ /* need to refresh */
1facf9fc 10172+ dput(dentry);
2cbb1c4b 10173+ dentry = NULL;
1facf9fc 10174+ }
10175+
4f0767ce 10176+out_iput:
1facf9fc 10177+ iput(inode);
4f0767ce 10178+out:
2cbb1c4b 10179+ AuTraceErrPtr(dentry);
1facf9fc 10180+ return dentry;
10181+}
10182+
10183+/* ---------------------------------------------------------------------- */
10184+
10185+/* todo: dirty? */
10186+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
10187+
10188+struct au_compare_mnt_args {
10189+ /* input */
10190+ struct super_block *sb;
10191+
10192+ /* output */
10193+ struct vfsmount *mnt;
10194+};
10195+
10196+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
10197+{
10198+ struct au_compare_mnt_args *a = arg;
10199+
10200+ if (mnt->mnt_sb != a->sb)
10201+ return 0;
10202+ a->mnt = mntget(mnt);
10203+ return 1;
10204+}
10205+
1facf9fc 10206+static struct vfsmount *au_mnt_get(struct super_block *sb)
10207+{
4a4d8108 10208+ int err;
7eafdf33 10209+ struct path root;
4a4d8108
AM
10210+ struct au_compare_mnt_args args = {
10211+ .sb = sb
10212+ };
1facf9fc 10213+
7eafdf33 10214+ get_fs_root(current->fs, &root);
523b37e3 10215+ rcu_read_lock();
7eafdf33 10216+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 10217+ rcu_read_unlock();
7eafdf33 10218+ path_put(&root);
4a4d8108
AM
10219+ AuDebugOn(!err);
10220+ AuDebugOn(!args.mnt);
10221+ return args.mnt;
1facf9fc 10222+}
10223+
10224+struct au_nfsd_si_lock {
4a4d8108 10225+ unsigned int sigen;
027c5e7a 10226+ aufs_bindex_t bindex, br_id;
1facf9fc 10227+ unsigned char force_lock;
10228+};
10229+
027c5e7a
AM
10230+static int si_nfsd_read_lock(struct super_block *sb,
10231+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10232+{
027c5e7a 10233+ int err;
1facf9fc 10234+ aufs_bindex_t bindex;
10235+
10236+ si_read_lock(sb, AuLock_FLUSH);
10237+
10238+ /* branch id may be wrapped around */
027c5e7a 10239+ err = 0;
1facf9fc 10240+ bindex = au_br_index(sb, nsi_lock->br_id);
10241+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
10242+ goto out; /* success */
10243+
027c5e7a
AM
10244+ err = -ESTALE;
10245+ bindex = -1;
1facf9fc 10246+ if (!nsi_lock->force_lock)
10247+ si_read_unlock(sb);
1facf9fc 10248+
4f0767ce 10249+out:
027c5e7a
AM
10250+ nsi_lock->bindex = bindex;
10251+ return err;
1facf9fc 10252+}
10253+
10254+struct find_name_by_ino {
392086de 10255+ struct dir_context ctx;
1facf9fc 10256+ int called, found;
10257+ ino_t ino;
10258+ char *name;
10259+ int namelen;
10260+};
10261+
10262+static int
392086de
AM
10263+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
10264+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 10265+{
392086de
AM
10266+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
10267+ ctx);
1facf9fc 10268+
10269+ a->called++;
10270+ if (a->ino != ino)
10271+ return 0;
10272+
10273+ memcpy(a->name, name, namelen);
10274+ a->namelen = namelen;
10275+ a->found = 1;
10276+ return 1;
10277+}
10278+
10279+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
10280+ struct au_nfsd_si_lock *nsi_lock)
10281+{
10282+ struct dentry *dentry, *parent;
10283+ struct file *file;
10284+ struct inode *dir;
392086de
AM
10285+ struct find_name_by_ino arg = {
10286+ .ctx = {
10287+ .actor = au_diractor(find_name_by_ino)
10288+ }
10289+ };
1facf9fc 10290+ int err;
10291+
10292+ parent = path->dentry;
10293+ if (nsi_lock)
10294+ si_read_unlock(parent->d_sb);
4a4d8108 10295+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 10296+ dentry = (void *)file;
10297+ if (IS_ERR(file))
10298+ goto out;
10299+
10300+ dentry = ERR_PTR(-ENOMEM);
537831f9 10301+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 10302+ if (unlikely(!arg.name))
10303+ goto out_file;
10304+ arg.ino = ino;
10305+ arg.found = 0;
10306+ do {
10307+ arg.called = 0;
10308+ /* smp_mb(); */
392086de 10309+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 10310+ } while (!err && !arg.found && arg.called);
10311+ dentry = ERR_PTR(err);
10312+ if (unlikely(err))
10313+ goto out_name;
1716fcea
AM
10314+ /* instead of ENOENT */
10315+ dentry = ERR_PTR(-ESTALE);
1facf9fc 10316+ if (!arg.found)
10317+ goto out_name;
10318+
b4510431 10319+ /* do not call vfsub_lkup_one() */
1facf9fc 10320+ dir = parent->d_inode;
10321+ mutex_lock(&dir->i_mutex);
10322+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
10323+ mutex_unlock(&dir->i_mutex);
10324+ AuTraceErrPtr(dentry);
10325+ if (IS_ERR(dentry))
10326+ goto out_name;
10327+ AuDebugOn(au_test_anon(dentry));
10328+ if (unlikely(!dentry->d_inode)) {
10329+ dput(dentry);
10330+ dentry = ERR_PTR(-ENOENT);
10331+ }
10332+
4f0767ce 10333+out_name:
537831f9 10334+ free_page((unsigned long)arg.name);
4f0767ce 10335+out_file:
1facf9fc 10336+ fput(file);
4f0767ce 10337+out:
1facf9fc 10338+ if (unlikely(nsi_lock
10339+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
10340+ if (!IS_ERR(dentry)) {
10341+ dput(dentry);
10342+ dentry = ERR_PTR(-ESTALE);
10343+ }
10344+ AuTraceErrPtr(dentry);
10345+ return dentry;
10346+}
10347+
10348+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
10349+ ino_t dir_ino,
10350+ struct au_nfsd_si_lock *nsi_lock)
10351+{
10352+ struct dentry *dentry;
10353+ struct path path;
10354+
10355+ if (dir_ino != AUFS_ROOT_INO) {
10356+ path.dentry = decode_by_ino(sb, dir_ino, 0);
10357+ dentry = path.dentry;
10358+ if (!path.dentry || IS_ERR(path.dentry))
10359+ goto out;
10360+ AuDebugOn(au_test_anon(path.dentry));
10361+ } else
10362+ path.dentry = dget(sb->s_root);
10363+
10364+ path.mnt = au_mnt_get(sb);
10365+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
10366+ path_put(&path);
10367+
4f0767ce 10368+out:
1facf9fc 10369+ AuTraceErrPtr(dentry);
10370+ return dentry;
10371+}
10372+
10373+/* ---------------------------------------------------------------------- */
10374+
10375+static int h_acceptable(void *expv, struct dentry *dentry)
10376+{
10377+ return 1;
10378+}
10379+
10380+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
10381+ char *buf, int len, struct super_block *sb)
10382+{
10383+ char *p;
10384+ int n;
10385+ struct path path;
10386+
10387+ p = d_path(h_rootpath, buf, len);
10388+ if (IS_ERR(p))
10389+ goto out;
10390+ n = strlen(p);
10391+
10392+ path.mnt = h_rootpath->mnt;
10393+ path.dentry = h_parent;
10394+ p = d_path(&path, buf, len);
10395+ if (IS_ERR(p))
10396+ goto out;
10397+ if (n != 1)
10398+ p += n;
10399+
10400+ path.mnt = au_mnt_get(sb);
10401+ path.dentry = sb->s_root;
10402+ p = d_path(&path, buf, len - strlen(p));
10403+ mntput(path.mnt);
10404+ if (IS_ERR(p))
10405+ goto out;
10406+ if (n != 1)
10407+ p[strlen(p)] = '/';
10408+
4f0767ce 10409+out:
1facf9fc 10410+ AuTraceErrPtr(p);
10411+ return p;
10412+}
10413+
10414+static
027c5e7a
AM
10415+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
10416+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10417+{
10418+ struct dentry *dentry, *h_parent, *root;
10419+ struct super_block *h_sb;
10420+ char *pathname, *p;
10421+ struct vfsmount *h_mnt;
10422+ struct au_branch *br;
10423+ int err;
10424+ struct path path;
10425+
027c5e7a 10426+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 10427+ h_mnt = au_br_mnt(br);
1facf9fc 10428+ h_sb = h_mnt->mnt_sb;
10429+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
10430+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
10431+ fh_len - Fh_tail, fh[Fh_h_type],
10432+ h_acceptable, /*context*/NULL);
10433+ dentry = h_parent;
10434+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
10435+ AuWarn1("%s decode_fh failed, %ld\n",
10436+ au_sbtype(h_sb), PTR_ERR(h_parent));
10437+ goto out;
10438+ }
10439+ dentry = NULL;
10440+ if (unlikely(au_test_anon(h_parent))) {
10441+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
10442+ au_sbtype(h_sb));
10443+ goto out_h_parent;
10444+ }
10445+
10446+ dentry = ERR_PTR(-ENOMEM);
10447+ pathname = (void *)__get_free_page(GFP_NOFS);
10448+ if (unlikely(!pathname))
10449+ goto out_h_parent;
10450+
10451+ root = sb->s_root;
10452+ path.mnt = h_mnt;
10453+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 10454+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 10455+ di_read_unlock(root, !AuLock_IR);
10456+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
10457+ dentry = (void *)p;
10458+ if (IS_ERR(p))
10459+ goto out_pathname;
10460+
10461+ si_read_unlock(sb);
10462+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
10463+ dentry = ERR_PTR(err);
10464+ if (unlikely(err))
10465+ goto out_relock;
10466+
10467+ dentry = ERR_PTR(-ENOENT);
10468+ AuDebugOn(au_test_anon(path.dentry));
10469+ if (unlikely(!path.dentry->d_inode))
10470+ goto out_path;
10471+
10472+ if (ino != path.dentry->d_inode->i_ino)
10473+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
10474+ else
10475+ dentry = dget(path.dentry);
10476+
4f0767ce 10477+out_path:
1facf9fc 10478+ path_put(&path);
4f0767ce 10479+out_relock:
1facf9fc 10480+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
10481+ if (!IS_ERR(dentry)) {
10482+ dput(dentry);
10483+ dentry = ERR_PTR(-ESTALE);
10484+ }
4f0767ce 10485+out_pathname:
1facf9fc 10486+ free_page((unsigned long)pathname);
4f0767ce 10487+out_h_parent:
1facf9fc 10488+ dput(h_parent);
4f0767ce 10489+out:
1facf9fc 10490+ AuTraceErrPtr(dentry);
10491+ return dentry;
10492+}
10493+
10494+/* ---------------------------------------------------------------------- */
10495+
10496+static struct dentry *
10497+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
10498+ int fh_type)
10499+{
10500+ struct dentry *dentry;
10501+ __u32 *fh = fid->raw;
027c5e7a 10502+ struct au_branch *br;
1facf9fc 10503+ ino_t ino, dir_ino;
1facf9fc 10504+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 10505+ .force_lock = 0
10506+ };
10507+
1facf9fc 10508+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
10509+ /* it should never happen, but the file handle is unreliable */
10510+ if (unlikely(fh_len < Fh_tail))
10511+ goto out;
10512+ nsi_lock.sigen = fh[Fh_sigen];
10513+ nsi_lock.br_id = fh[Fh_br_id];
10514+
1facf9fc 10515+ /* branch id may be wrapped around */
027c5e7a
AM
10516+ br = NULL;
10517+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 10518+ goto out;
10519+ nsi_lock.force_lock = 1;
10520+
10521+ /* is this inode still cached? */
10522+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
10523+ /* it should never happen */
10524+ if (unlikely(ino == AUFS_ROOT_INO))
10525+ goto out;
10526+
1facf9fc 10527+ dir_ino = decode_ino(fh + Fh_dir_ino);
10528+ dentry = decode_by_ino(sb, ino, dir_ino);
10529+ if (IS_ERR(dentry))
10530+ goto out_unlock;
10531+ if (dentry)
10532+ goto accept;
10533+
10534+ /* is the parent dir cached? */
027c5e7a
AM
10535+ br = au_sbr(sb, nsi_lock.bindex);
10536+ atomic_inc(&br->br_count);
1facf9fc 10537+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
10538+ if (IS_ERR(dentry))
10539+ goto out_unlock;
10540+ if (dentry)
10541+ goto accept;
10542+
10543+ /* lookup path */
027c5e7a 10544+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 10545+ if (IS_ERR(dentry))
10546+ goto out_unlock;
10547+ if (unlikely(!dentry))
10548+ /* todo?: make it ESTALE */
10549+ goto out_unlock;
10550+
4f0767ce 10551+accept:
027c5e7a
AM
10552+ if (!au_digen_test(dentry, au_sigen(sb))
10553+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 10554+ goto out_unlock; /* success */
10555+
10556+ dput(dentry);
10557+ dentry = ERR_PTR(-ESTALE);
4f0767ce 10558+out_unlock:
027c5e7a
AM
10559+ if (br)
10560+ atomic_dec(&br->br_count);
1facf9fc 10561+ si_read_unlock(sb);
4f0767ce 10562+out:
1facf9fc 10563+ AuTraceErrPtr(dentry);
10564+ return dentry;
10565+}
10566+
10567+#if 0 /* reserved for future use */
10568+/* support subtreecheck option */
10569+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
10570+ int fh_len, int fh_type)
10571+{
10572+ struct dentry *parent;
10573+ __u32 *fh = fid->raw;
10574+ ino_t dir_ino;
10575+
10576+ dir_ino = decode_ino(fh + Fh_dir_ino);
10577+ parent = decode_by_ino(sb, dir_ino, 0);
10578+ if (IS_ERR(parent))
10579+ goto out;
10580+ if (!parent)
10581+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
10582+ dir_ino, fh, fh_len);
10583+
4f0767ce 10584+out:
1facf9fc 10585+ AuTraceErrPtr(parent);
10586+ return parent;
10587+}
10588+#endif
10589+
10590+/* ---------------------------------------------------------------------- */
10591+
0c3ec466
AM
10592+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
10593+ struct inode *dir)
1facf9fc 10594+{
10595+ int err;
0c3ec466 10596+ aufs_bindex_t bindex;
1facf9fc 10597+ struct super_block *sb, *h_sb;
0c3ec466
AM
10598+ struct dentry *dentry, *parent, *h_parent;
10599+ struct inode *h_dir;
1facf9fc 10600+ struct au_branch *br;
10601+
1facf9fc 10602+ err = -ENOSPC;
10603+ if (unlikely(*max_len <= Fh_tail)) {
10604+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
10605+ goto out;
10606+ }
10607+
10608+ err = FILEID_ROOT;
0c3ec466
AM
10609+ if (inode->i_ino == AUFS_ROOT_INO) {
10610+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 10611+ goto out;
10612+ }
10613+
1facf9fc 10614+ h_parent = NULL;
0c3ec466
AM
10615+ sb = inode->i_sb;
10616+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
10617+ if (unlikely(err))
10618+ goto out;
10619+
1facf9fc 10620+#ifdef CONFIG_AUFS_DEBUG
10621+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10622+ AuWarn1("NFS-exporting requires xino\n");
10623+#endif
027c5e7a 10624+ err = -EIO;
0c3ec466
AM
10625+ parent = NULL;
10626+ ii_read_lock_child(inode);
10627+ bindex = au_ibstart(inode);
10628+ if (!dir) {
10629+ dentry = d_find_alias(inode);
10630+ if (unlikely(!dentry))
10631+ goto out_unlock;
10632+ AuDebugOn(au_test_anon(dentry));
10633+ parent = dget_parent(dentry);
10634+ dput(dentry);
10635+ if (unlikely(!parent))
10636+ goto out_unlock;
10637+ dir = parent->d_inode;
1facf9fc 10638+ }
0c3ec466
AM
10639+
10640+ ii_read_lock_parent(dir);
10641+ h_dir = au_h_iptr(dir, bindex);
10642+ ii_read_unlock(dir);
10643+ if (unlikely(!h_dir))
10644+ goto out_parent;
10645+ h_parent = d_find_alias(h_dir);
1facf9fc 10646+ if (unlikely(!h_parent))
0c3ec466 10647+ goto out_hparent;
1facf9fc 10648+
10649+ err = -EPERM;
10650+ br = au_sbr(sb, bindex);
86dc4139 10651+ h_sb = au_br_sb(br);
1facf9fc 10652+ if (unlikely(!h_sb->s_export_op)) {
10653+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 10654+ goto out_hparent;
1facf9fc 10655+ }
10656+
10657+ fh[Fh_br_id] = br->br_id;
10658+ fh[Fh_sigen] = au_sigen(sb);
10659+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 10660+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 10661+ fh[Fh_igen] = inode->i_generation;
10662+
10663+ *max_len -= Fh_tail;
10664+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
10665+ max_len,
10666+ /*connectable or subtreecheck*/0);
10667+ err = fh[Fh_h_type];
10668+ *max_len += Fh_tail;
10669+ /* todo: macros? */
1716fcea 10670+ if (err != FILEID_INVALID)
1facf9fc 10671+ err = 99;
10672+ else
10673+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
10674+
0c3ec466 10675+out_hparent:
1facf9fc 10676+ dput(h_parent);
0c3ec466 10677+out_parent:
1facf9fc 10678+ dput(parent);
0c3ec466
AM
10679+out_unlock:
10680+ ii_read_unlock(inode);
10681+ si_read_unlock(sb);
4f0767ce 10682+out:
1facf9fc 10683+ if (unlikely(err < 0))
1716fcea 10684+ err = FILEID_INVALID;
1facf9fc 10685+ return err;
10686+}
10687+
10688+/* ---------------------------------------------------------------------- */
10689+
4a4d8108
AM
10690+static int aufs_commit_metadata(struct inode *inode)
10691+{
10692+ int err;
10693+ aufs_bindex_t bindex;
10694+ struct super_block *sb;
10695+ struct inode *h_inode;
10696+ int (*f)(struct inode *inode);
10697+
10698+ sb = inode->i_sb;
e49829fe 10699+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
10700+ ii_write_lock_child(inode);
10701+ bindex = au_ibstart(inode);
10702+ AuDebugOn(bindex < 0);
10703+ h_inode = au_h_iptr(inode, bindex);
10704+
10705+ f = h_inode->i_sb->s_export_op->commit_metadata;
10706+ if (f)
10707+ err = f(h_inode);
10708+ else {
10709+ struct writeback_control wbc = {
10710+ .sync_mode = WB_SYNC_ALL,
10711+ .nr_to_write = 0 /* metadata only */
10712+ };
10713+
10714+ err = sync_inode(h_inode, &wbc);
10715+ }
10716+
10717+ au_cpup_attr_timesizes(inode);
10718+ ii_write_unlock(inode);
10719+ si_read_unlock(sb);
10720+ return err;
10721+}
10722+
10723+/* ---------------------------------------------------------------------- */
10724+
1facf9fc 10725+static struct export_operations aufs_export_op = {
4a4d8108 10726+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 10727+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
10728+ .encode_fh = aufs_encode_fh,
10729+ .commit_metadata = aufs_commit_metadata
1facf9fc 10730+};
10731+
10732+void au_export_init(struct super_block *sb)
10733+{
10734+ struct au_sbinfo *sbinfo;
10735+ __u32 u;
10736+
10737+ sb->s_export_op = &aufs_export_op;
10738+ sbinfo = au_sbi(sb);
10739+ sbinfo->si_xigen = NULL;
10740+ get_random_bytes(&u, sizeof(u));
10741+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
10742+ atomic_set(&sbinfo->si_xigen_next, u);
10743+}
7f207e10
AM
10744diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
10745--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 10746+++ linux/fs/aufs/file.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 10747@@ -0,0 +1,724 @@
1facf9fc 10748+/*
523b37e3 10749+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 10750+ *
10751+ * This program, aufs is free software; you can redistribute it and/or modify
10752+ * it under the terms of the GNU General Public License as published by
10753+ * the Free Software Foundation; either version 2 of the License, or
10754+ * (at your option) any later version.
dece6358
AM
10755+ *
10756+ * This program is distributed in the hope that it will be useful,
10757+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10758+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10759+ * GNU General Public License for more details.
10760+ *
10761+ * You should have received a copy of the GNU General Public License
523b37e3 10762+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10763+ */
10764+
10765+/*
4a4d8108 10766+ * handling file/dir, and address_space operation
1facf9fc 10767+ */
10768+
7eafdf33
AM
10769+#ifdef CONFIG_AUFS_DEBUG
10770+#include <linux/migrate.h>
10771+#endif
4a4d8108 10772+#include <linux/pagemap.h>
1facf9fc 10773+#include "aufs.h"
10774+
4a4d8108
AM
10775+/* drop flags for writing */
10776+unsigned int au_file_roflags(unsigned int flags)
10777+{
10778+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
10779+ flags |= O_RDONLY | O_NOATIME;
10780+ return flags;
10781+}
10782+
10783+/* common functions to regular file and dir */
10784+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 10785+ struct file *file, int force_wr)
1facf9fc 10786+{
1308ab2a 10787+ struct file *h_file;
4a4d8108
AM
10788+ struct dentry *h_dentry;
10789+ struct inode *h_inode;
10790+ struct super_block *sb;
10791+ struct au_branch *br;
10792+ struct path h_path;
10793+ int err, exec_flag;
1facf9fc 10794+
4a4d8108
AM
10795+ /* a race condition can happen between open and unlink/rmdir */
10796+ h_file = ERR_PTR(-ENOENT);
10797+ h_dentry = au_h_dptr(dentry, bindex);
b752ccd1 10798+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
10799+ goto out;
10800+ h_inode = h_dentry->d_inode;
b752ccd1 10801+ if (au_test_nfsd() && !h_inode)
4a4d8108 10802+ goto out;
027c5e7a
AM
10803+ spin_lock(&h_dentry->d_lock);
10804+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
10805+ || !h_inode
10806+ /* || !dentry->d_inode->i_nlink */
10807+ ;
10808+ spin_unlock(&h_dentry->d_lock);
10809+ if (unlikely(err))
4a4d8108 10810+ goto out;
1facf9fc 10811+
4a4d8108
AM
10812+ sb = dentry->d_sb;
10813+ br = au_sbr(sb, bindex);
10814+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 10815+ exec_flag = flags & __FMODE_EXEC;
86dc4139 10816+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
027c5e7a 10817+ goto out;
1facf9fc 10818+
4a4d8108 10819+ /* drop flags for writing */
392086de
AM
10820+ if (au_test_ro(sb, bindex, dentry->d_inode)) {
10821+ if (force_wr && !(flags & O_WRONLY))
10822+ force_wr = 0;
4a4d8108 10823+ flags = au_file_roflags(flags);
392086de
AM
10824+ if (force_wr) {
10825+ h_file = ERR_PTR(-EROFS);
10826+ flags = au_file_roflags(flags);
10827+ if (unlikely(vfsub_native_ro(h_inode)
10828+ || IS_APPEND(h_inode)))
10829+ goto out;
10830+ flags &= ~O_ACCMODE;
10831+ flags |= O_WRONLY;
10832+ }
10833+ }
4a4d8108
AM
10834+ flags &= ~O_CREAT;
10835+ atomic_inc(&br->br_count);
10836+ h_path.dentry = h_dentry;
86dc4139 10837+ h_path.mnt = au_br_mnt(br);
4a4d8108
AM
10838+ if (!au_special_file(h_inode->i_mode))
10839+ h_file = vfsub_dentry_open(&h_path, flags);
10840+ else {
10841+ /* this block depends upon the configuration */
10842+ di_read_unlock(dentry, AuLock_IR);
10843+ fi_write_unlock(file);
10844+ si_read_unlock(sb);
10845+ h_file = vfsub_dentry_open(&h_path, flags);
10846+ si_noflush_read_lock(sb);
10847+ fi_write_lock(file);
10848+ di_read_lock_child(dentry, AuLock_IR);
dece6358 10849+ }
4a4d8108
AM
10850+ if (IS_ERR(h_file))
10851+ goto out_br;
dece6358 10852+
4a4d8108
AM
10853+ if (exec_flag) {
10854+ err = deny_write_access(h_file);
10855+ if (unlikely(err)) {
10856+ fput(h_file);
10857+ h_file = ERR_PTR(err);
10858+ goto out_br;
10859+ }
10860+ }
953406b4 10861+ fsnotify_open(h_file);
4a4d8108 10862+ goto out; /* success */
1facf9fc 10863+
4f0767ce 10864+out_br:
4a4d8108 10865+ atomic_dec(&br->br_count);
4f0767ce 10866+out:
4a4d8108
AM
10867+ return h_file;
10868+}
1308ab2a 10869+
4a4d8108
AM
10870+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
10871+ struct au_fidir *fidir)
1facf9fc 10872+{
dece6358 10873+ int err;
1facf9fc 10874+ struct dentry *dentry;
1308ab2a 10875+
4a4d8108
AM
10876+ err = au_finfo_init(file, fidir);
10877+ if (unlikely(err))
10878+ goto out;
1facf9fc 10879+
10880+ dentry = file->f_dentry;
4a4d8108
AM
10881+ di_read_lock_child(dentry, AuLock_IR);
10882+ err = open(file, vfsub_file_flags(file));
10883+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 10884+
4a4d8108
AM
10885+ fi_write_unlock(file);
10886+ if (unlikely(err)) {
10887+ au_fi(file)->fi_hdir = NULL;
10888+ au_finfo_fin(file);
1308ab2a 10889+ }
4a4d8108 10890+
4f0767ce 10891+out:
1308ab2a 10892+ return err;
10893+}
dece6358 10894+
4a4d8108 10895+int au_reopen_nondir(struct file *file)
1308ab2a 10896+{
4a4d8108
AM
10897+ int err;
10898+ aufs_bindex_t bstart;
10899+ struct dentry *dentry;
10900+ struct file *h_file, *h_file_tmp;
1308ab2a 10901+
4a4d8108
AM
10902+ dentry = file->f_dentry;
10903+ AuDebugOn(au_special_file(dentry->d_inode->i_mode));
10904+ bstart = au_dbstart(dentry);
10905+ h_file_tmp = NULL;
10906+ if (au_fbstart(file) == bstart) {
10907+ h_file = au_hf_top(file);
10908+ if (file->f_mode == h_file->f_mode)
10909+ return 0; /* success */
10910+ h_file_tmp = h_file;
10911+ get_file(h_file_tmp);
10912+ au_set_h_fptr(file, bstart, NULL);
10913+ }
10914+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
10915+ /*
10916+ * it can happen
10917+ * file exists on both of rw and ro
10918+ * open --> dbstart and fbstart are both 0
10919+ * prepend a branch as rw, "rw" become ro
10920+ * remove rw/file
10921+ * delete the top branch, "rw" becomes rw again
10922+ * --> dbstart is 1, fbstart is still 0
10923+ * write --> fbstart is 0 but dbstart is 1
10924+ */
10925+ /* AuDebugOn(au_fbstart(file) < bstart); */
1308ab2a 10926+
4a4d8108 10927+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
392086de 10928+ file, /*force_wr*/0);
4a4d8108 10929+ err = PTR_ERR(h_file);
86dc4139
AM
10930+ if (IS_ERR(h_file)) {
10931+ if (h_file_tmp) {
10932+ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
10933+ au_set_h_fptr(file, bstart, h_file_tmp);
10934+ h_file_tmp = NULL;
10935+ }
4a4d8108 10936+ goto out; /* todo: close all? */
86dc4139 10937+ }
4a4d8108
AM
10938+
10939+ err = 0;
10940+ au_set_fbstart(file, bstart);
10941+ au_set_h_fptr(file, bstart, h_file);
10942+ au_update_figen(file);
10943+ /* todo: necessary? */
10944+ /* file->f_ra = h_file->f_ra; */
10945+
4f0767ce 10946+out:
4a4d8108
AM
10947+ if (h_file_tmp)
10948+ fput(h_file_tmp);
10949+ return err;
1facf9fc 10950+}
10951+
1308ab2a 10952+/* ---------------------------------------------------------------------- */
10953+
4a4d8108
AM
10954+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
10955+ struct dentry *hi_wh)
1facf9fc 10956+{
4a4d8108
AM
10957+ int err;
10958+ aufs_bindex_t bstart;
10959+ struct au_dinfo *dinfo;
10960+ struct dentry *h_dentry;
10961+ struct au_hdentry *hdp;
1facf9fc 10962+
4a4d8108
AM
10963+ dinfo = au_di(file->f_dentry);
10964+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 10965+
4a4d8108
AM
10966+ bstart = dinfo->di_bstart;
10967+ dinfo->di_bstart = btgt;
10968+ hdp = dinfo->di_hdentry;
10969+ h_dentry = hdp[0 + btgt].hd_dentry;
10970+ hdp[0 + btgt].hd_dentry = hi_wh;
10971+ err = au_reopen_nondir(file);
10972+ hdp[0 + btgt].hd_dentry = h_dentry;
10973+ dinfo->di_bstart = bstart;
1facf9fc 10974+
1facf9fc 10975+ return err;
10976+}
10977+
4a4d8108 10978+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 10979+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 10980+{
4a4d8108 10981+ int err;
027c5e7a 10982+ struct inode *inode, *h_inode;
c2b27bf2
AM
10983+ struct dentry *h_dentry, *hi_wh;
10984+ struct au_cp_generic cpg = {
10985+ .dentry = file->f_dentry,
10986+ .bdst = bcpup,
10987+ .bsrc = -1,
10988+ .len = len,
10989+ .pin = pin
10990+ };
1facf9fc 10991+
c2b27bf2
AM
10992+ au_update_dbstart(cpg.dentry);
10993+ inode = cpg.dentry->d_inode;
027c5e7a 10994+ h_inode = NULL;
c2b27bf2
AM
10995+ if (au_dbstart(cpg.dentry) <= bcpup
10996+ && au_dbend(cpg.dentry) >= bcpup) {
10997+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
027c5e7a
AM
10998+ if (h_dentry)
10999+ h_inode = h_dentry->d_inode;
11000+ }
4a4d8108 11001+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 11002+ if (!hi_wh && !h_inode)
c2b27bf2 11003+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
11004+ else
11005+ /* already copied-up after unlink */
11006+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 11007+
4a4d8108
AM
11008+ if (!err
11009+ && inode->i_nlink > 1
c2b27bf2
AM
11010+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
11011+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 11012+
dece6358 11013+ return err;
1facf9fc 11014+}
11015+
4a4d8108
AM
11016+/*
11017+ * prepare the @file for writing.
11018+ */
11019+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 11020+{
4a4d8108 11021+ int err;
c2b27bf2
AM
11022+ aufs_bindex_t dbstart;
11023+ struct dentry *parent, *h_dentry;
86dc4139 11024+ struct inode *inode;
1facf9fc 11025+ struct super_block *sb;
4a4d8108 11026+ struct file *h_file;
c2b27bf2
AM
11027+ struct au_cp_generic cpg = {
11028+ .dentry = file->f_dentry,
11029+ .bdst = -1,
11030+ .bsrc = -1,
11031+ .len = len,
11032+ .pin = pin,
11033+ .flags = AuCpup_DTIME
11034+ };
1facf9fc 11035+
c2b27bf2
AM
11036+ sb = cpg.dentry->d_sb;
11037+ inode = cpg.dentry->d_inode;
4a4d8108 11038+ AuDebugOn(au_special_file(inode->i_mode));
c2b27bf2
AM
11039+ cpg.bsrc = au_fbstart(file);
11040+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 11041+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
11042+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
11043+ /*flags*/0);
1facf9fc 11044+ goto out;
4a4d8108 11045+ }
1facf9fc 11046+
027c5e7a 11047+ /* need to cpup or reopen */
c2b27bf2 11048+ parent = dget_parent(cpg.dentry);
4a4d8108 11049+ di_write_lock_parent(parent);
c2b27bf2
AM
11050+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
11051+ cpg.bdst = err;
4a4d8108
AM
11052+ if (unlikely(err < 0))
11053+ goto out_dgrade;
11054+ err = 0;
11055+
c2b27bf2
AM
11056+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
11057+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 11058+ if (unlikely(err))
4a4d8108
AM
11059+ goto out_dgrade;
11060+ }
11061+
c2b27bf2 11062+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
11063+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
11064+ if (unlikely(err))
11065+ goto out_dgrade;
11066+
11067+ h_dentry = au_hf_top(file)->f_dentry;
c2b27bf2
AM
11068+ dbstart = au_dbstart(cpg.dentry);
11069+ if (dbstart <= cpg.bdst) {
11070+ h_dentry = au_h_dptr(cpg.dentry, cpg.bdst);
027c5e7a 11071+ AuDebugOn(!h_dentry);
c2b27bf2 11072+ cpg.bsrc = cpg.bdst;
027c5e7a
AM
11073+ }
11074+
c2b27bf2
AM
11075+ if (dbstart <= cpg.bdst /* just reopen */
11076+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 11077+ ) {
392086de 11078+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 11079+ if (IS_ERR(h_file))
027c5e7a 11080+ err = PTR_ERR(h_file);
86dc4139 11081+ else {
027c5e7a 11082+ di_downgrade_lock(parent, AuLock_IR);
c2b27bf2
AM
11083+ if (dbstart > cpg.bdst)
11084+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
11085+ if (!err)
11086+ err = au_reopen_nondir(file);
c2b27bf2 11087+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 11088+ }
027c5e7a
AM
11089+ } else { /* copyup as wh and reopen */
11090+ /*
11091+ * since writable hfsplus branch is not supported,
11092+ * h_open_pre/post() are unnecessary.
11093+ */
c2b27bf2 11094+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 11095+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 11096+ }
4a4d8108
AM
11097+
11098+ if (!err) {
11099+ au_pin_set_parent_lflag(pin, /*lflag*/0);
11100+ goto out_dput; /* success */
11101+ }
11102+ au_unpin(pin);
11103+ goto out_unlock;
1facf9fc 11104+
4f0767ce 11105+out_dgrade:
4a4d8108 11106+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 11107+out_unlock:
4a4d8108 11108+ di_read_unlock(parent, AuLock_IR);
4f0767ce 11109+out_dput:
4a4d8108 11110+ dput(parent);
4f0767ce 11111+out:
1facf9fc 11112+ return err;
11113+}
11114+
4a4d8108
AM
11115+/* ---------------------------------------------------------------------- */
11116+
11117+int au_do_flush(struct file *file, fl_owner_t id,
11118+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 11119+{
4a4d8108 11120+ int err;
1facf9fc 11121+ struct super_block *sb;
4a4d8108 11122+ struct inode *inode;
1facf9fc 11123+
c06a8ce3
AM
11124+ inode = file_inode(file);
11125+ sb = inode->i_sb;
4a4d8108
AM
11126+ si_noflush_read_lock(sb);
11127+ fi_read_lock(file);
b752ccd1 11128+ ii_read_lock_child(inode);
1facf9fc 11129+
4a4d8108
AM
11130+ err = flush(file, id);
11131+ au_cpup_attr_timesizes(inode);
1facf9fc 11132+
b752ccd1 11133+ ii_read_unlock(inode);
4a4d8108 11134+ fi_read_unlock(file);
1308ab2a 11135+ si_read_unlock(sb);
dece6358 11136+ return err;
1facf9fc 11137+}
11138+
4a4d8108
AM
11139+/* ---------------------------------------------------------------------- */
11140+
11141+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 11142+{
4a4d8108 11143+ int err;
4a4d8108
AM
11144+ struct au_pin pin;
11145+ struct au_finfo *finfo;
c2b27bf2 11146+ struct dentry *parent, *hi_wh;
4a4d8108 11147+ struct inode *inode;
1facf9fc 11148+ struct super_block *sb;
c2b27bf2
AM
11149+ struct au_cp_generic cpg = {
11150+ .dentry = file->f_dentry,
11151+ .bdst = -1,
11152+ .bsrc = -1,
11153+ .len = -1,
11154+ .pin = &pin,
11155+ .flags = AuCpup_DTIME
11156+ };
1facf9fc 11157+
4a4d8108
AM
11158+ FiMustWriteLock(file);
11159+
11160+ err = 0;
11161+ finfo = au_fi(file);
c2b27bf2
AM
11162+ sb = cpg.dentry->d_sb;
11163+ inode = cpg.dentry->d_inode;
11164+ cpg.bdst = au_ibstart(inode);
11165+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 11166+ goto out;
dece6358 11167+
c2b27bf2
AM
11168+ parent = dget_parent(cpg.dentry);
11169+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 11170+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
11171+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
11172+ cpg.bdst = err;
4a4d8108
AM
11173+ di_read_unlock(parent, !AuLock_IR);
11174+ if (unlikely(err < 0))
11175+ goto out_parent;
11176+ err = 0;
1facf9fc 11177+ }
1facf9fc 11178+
4a4d8108 11179+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 11180+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
11181+ if (!S_ISDIR(inode->i_mode)
11182+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 11183+ && au_plink_test(inode)
c2b27bf2
AM
11184+ && !d_unhashed(cpg.dentry)
11185+ && cpg.bdst < au_dbstart(cpg.dentry)) {
11186+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
11187+ if (unlikely(err))
11188+ goto out_unlock;
11189+
11190+ /* always superio. */
c2b27bf2 11191+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 11192+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 11193+ if (!err) {
c2b27bf2 11194+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
11195+ au_unpin(&pin);
11196+ }
4a4d8108
AM
11197+ } else if (hi_wh) {
11198+ /* already copied-up after unlink */
c2b27bf2 11199+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
11200+ *need_reopen = 0;
11201+ }
1facf9fc 11202+
4f0767ce 11203+out_unlock:
4a4d8108 11204+ di_read_unlock(parent, AuLock_IR);
4f0767ce 11205+out_parent:
4a4d8108 11206+ dput(parent);
4f0767ce 11207+out:
1308ab2a 11208+ return err;
dece6358 11209+}
1facf9fc 11210+
4a4d8108 11211+static void au_do_refresh_dir(struct file *file)
dece6358 11212+{
4a4d8108
AM
11213+ aufs_bindex_t bindex, bend, new_bindex, brid;
11214+ struct au_hfile *p, tmp, *q;
11215+ struct au_finfo *finfo;
1308ab2a 11216+ struct super_block *sb;
4a4d8108 11217+ struct au_fidir *fidir;
1facf9fc 11218+
4a4d8108 11219+ FiMustWriteLock(file);
1facf9fc 11220+
4a4d8108
AM
11221+ sb = file->f_dentry->d_sb;
11222+ finfo = au_fi(file);
11223+ fidir = finfo->fi_hdir;
11224+ AuDebugOn(!fidir);
11225+ p = fidir->fd_hfile + finfo->fi_btop;
11226+ brid = p->hf_br->br_id;
11227+ bend = fidir->fd_bbot;
11228+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
11229+ if (!p->hf_file)
11230+ continue;
1308ab2a 11231+
4a4d8108
AM
11232+ new_bindex = au_br_index(sb, p->hf_br->br_id);
11233+ if (new_bindex == bindex)
11234+ continue;
11235+ if (new_bindex < 0) {
11236+ au_set_h_fptr(file, bindex, NULL);
11237+ continue;
11238+ }
1308ab2a 11239+
4a4d8108
AM
11240+ /* swap two lower inode, and loop again */
11241+ q = fidir->fd_hfile + new_bindex;
11242+ tmp = *q;
11243+ *q = *p;
11244+ *p = tmp;
11245+ if (tmp.hf_file) {
11246+ bindex--;
11247+ p--;
11248+ }
11249+ }
1308ab2a 11250+
4a4d8108 11251+ p = fidir->fd_hfile;
027c5e7a 11252+ if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
4a4d8108
AM
11253+ bend = au_sbend(sb);
11254+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
11255+ finfo->fi_btop++, p++)
11256+ if (p->hf_file) {
c06a8ce3 11257+ if (file_inode(p->hf_file))
4a4d8108
AM
11258+ break;
11259+ else
11260+ au_hfput(p, file);
11261+ }
11262+ } else {
11263+ bend = au_br_index(sb, brid);
11264+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
11265+ finfo->fi_btop++, p++)
11266+ if (p->hf_file)
11267+ au_hfput(p, file);
11268+ bend = au_sbend(sb);
11269+ }
1308ab2a 11270+
4a4d8108
AM
11271+ p = fidir->fd_hfile + bend;
11272+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
11273+ fidir->fd_bbot--, p--)
11274+ if (p->hf_file) {
c06a8ce3 11275+ if (file_inode(p->hf_file))
4a4d8108
AM
11276+ break;
11277+ else
11278+ au_hfput(p, file);
11279+ }
11280+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 11281+}
11282+
4a4d8108
AM
11283+/*
11284+ * after branch manipulating, refresh the file.
11285+ */
11286+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 11287+{
4a4d8108
AM
11288+ int err, need_reopen;
11289+ aufs_bindex_t bend, bindex;
11290+ struct dentry *dentry;
1308ab2a 11291+ struct au_finfo *finfo;
4a4d8108 11292+ struct au_hfile *hfile;
1facf9fc 11293+
4a4d8108 11294+ dentry = file->f_dentry;
1308ab2a 11295+ finfo = au_fi(file);
4a4d8108
AM
11296+ if (!finfo->fi_hdir) {
11297+ hfile = &finfo->fi_htop;
11298+ AuDebugOn(!hfile->hf_file);
11299+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
11300+ AuDebugOn(bindex < 0);
11301+ if (bindex != finfo->fi_btop)
11302+ au_set_fbstart(file, bindex);
11303+ } else {
11304+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
11305+ if (unlikely(err))
11306+ goto out;
11307+ au_do_refresh_dir(file);
11308+ }
1facf9fc 11309+
4a4d8108
AM
11310+ err = 0;
11311+ need_reopen = 1;
11312+ if (!au_test_mmapped(file))
11313+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 11314+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
11315+ err = reopen(file);
11316+ if (!err) {
11317+ au_update_figen(file);
11318+ goto out; /* success */
11319+ }
11320+
11321+ /* error, close all lower files */
11322+ if (finfo->fi_hdir) {
11323+ bend = au_fbend_dir(file);
11324+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
11325+ au_set_h_fptr(file, bindex, NULL);
11326+ }
1facf9fc 11327+
4f0767ce 11328+out:
1facf9fc 11329+ return err;
11330+}
11331+
4a4d8108
AM
11332+/* common function to regular file and dir */
11333+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
11334+ int wlock)
dece6358 11335+{
1308ab2a 11336+ int err;
4a4d8108
AM
11337+ unsigned int sigen, figen;
11338+ aufs_bindex_t bstart;
11339+ unsigned char pseudo_link;
11340+ struct dentry *dentry;
11341+ struct inode *inode;
1facf9fc 11342+
4a4d8108
AM
11343+ err = 0;
11344+ dentry = file->f_dentry;
11345+ inode = dentry->d_inode;
11346+ AuDebugOn(au_special_file(inode->i_mode));
11347+ sigen = au_sigen(dentry->d_sb);
11348+ fi_write_lock(file);
11349+ figen = au_figen(file);
11350+ di_write_lock_child(dentry);
11351+ bstart = au_dbstart(dentry);
11352+ pseudo_link = (bstart != au_ibstart(inode));
11353+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
11354+ if (!wlock) {
11355+ di_downgrade_lock(dentry, AuLock_IR);
11356+ fi_downgrade_lock(file);
11357+ }
11358+ goto out; /* success */
11359+ }
dece6358 11360+
4a4d8108 11361+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 11362+ if (au_digen_test(dentry, sigen)) {
4a4d8108 11363+ err = au_reval_dpath(dentry, sigen);
027c5e7a 11364+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 11365+ }
dece6358 11366+
027c5e7a
AM
11367+ if (!err)
11368+ err = refresh_file(file, reopen);
4a4d8108
AM
11369+ if (!err) {
11370+ if (!wlock) {
11371+ di_downgrade_lock(dentry, AuLock_IR);
11372+ fi_downgrade_lock(file);
11373+ }
11374+ } else {
11375+ di_write_unlock(dentry);
11376+ fi_write_unlock(file);
11377+ }
1facf9fc 11378+
4f0767ce 11379+out:
1308ab2a 11380+ return err;
11381+}
1facf9fc 11382+
4a4d8108
AM
11383+/* ---------------------------------------------------------------------- */
11384+
11385+/* cf. aufs_nopage() */
11386+/* for madvise(2) */
11387+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 11388+{
4a4d8108
AM
11389+ unlock_page(page);
11390+ return 0;
11391+}
1facf9fc 11392+
4a4d8108
AM
11393+/* it will never be called, but necessary to support O_DIRECT */
11394+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
11395+ const struct iovec *iov, loff_t offset,
11396+ unsigned long nr_segs)
11397+{ BUG(); return 0; }
1facf9fc 11398+
4a4d8108
AM
11399+/*
11400+ * it will never be called, but madvise and fadvise behaves differently
11401+ * when get_xip_mem is defined
11402+ */
11403+static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
11404+ int create, void **kmem, unsigned long *pfn)
11405+{ BUG(); return 0; }
1facf9fc 11406+
4a4d8108
AM
11407+/* they will never be called. */
11408+#ifdef CONFIG_AUFS_DEBUG
11409+static int aufs_write_begin(struct file *file, struct address_space *mapping,
11410+ loff_t pos, unsigned len, unsigned flags,
11411+ struct page **pagep, void **fsdata)
11412+{ AuUnsupport(); return 0; }
11413+static int aufs_write_end(struct file *file, struct address_space *mapping,
11414+ loff_t pos, unsigned len, unsigned copied,
11415+ struct page *page, void *fsdata)
11416+{ AuUnsupport(); return 0; }
11417+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
11418+{ AuUnsupport(); return 0; }
1308ab2a 11419+
4a4d8108
AM
11420+static int aufs_set_page_dirty(struct page *page)
11421+{ AuUnsupport(); return 0; }
392086de
AM
11422+static void aufs_invalidatepage(struct page *page, unsigned int offset,
11423+ unsigned int length)
4a4d8108
AM
11424+{ AuUnsupport(); }
11425+static int aufs_releasepage(struct page *page, gfp_t gfp)
11426+{ AuUnsupport(); return 0; }
11427+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 11428+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
11429+{ AuUnsupport(); return 0; }
11430+static int aufs_launder_page(struct page *page)
11431+{ AuUnsupport(); return 0; }
11432+static int aufs_is_partially_uptodate(struct page *page,
11433+ read_descriptor_t *desc,
11434+ unsigned long from)
11435+{ AuUnsupport(); return 0; }
392086de
AM
11436+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
11437+ bool *writeback)
11438+{ AuUnsupport(); }
4a4d8108
AM
11439+static int aufs_error_remove_page(struct address_space *mapping,
11440+ struct page *page)
11441+{ AuUnsupport(); return 0; }
b4510431
AM
11442+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
11443+ sector_t *span)
11444+{ AuUnsupport(); return 0; }
11445+static void aufs_swap_deactivate(struct file *file)
11446+{ AuUnsupport(); }
4a4d8108
AM
11447+#endif /* CONFIG_AUFS_DEBUG */
11448+
11449+const struct address_space_operations aufs_aop = {
11450+ .readpage = aufs_readpage,
11451+ .direct_IO = aufs_direct_IO,
11452+ .get_xip_mem = aufs_get_xip_mem,
11453+#ifdef CONFIG_AUFS_DEBUG
11454+ .writepage = aufs_writepage,
4a4d8108
AM
11455+ /* no writepages, because of writepage */
11456+ .set_page_dirty = aufs_set_page_dirty,
11457+ /* no readpages, because of readpage */
11458+ .write_begin = aufs_write_begin,
11459+ .write_end = aufs_write_end,
11460+ /* no bmap, no block device */
11461+ .invalidatepage = aufs_invalidatepage,
11462+ .releasepage = aufs_releasepage,
11463+ .migratepage = aufs_migratepage,
11464+ .launder_page = aufs_launder_page,
11465+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 11466+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
11467+ .error_remove_page = aufs_error_remove_page,
11468+ .swap_activate = aufs_swap_activate,
11469+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 11470+#endif /* CONFIG_AUFS_DEBUG */
dece6358 11471+};
7f207e10
AM
11472diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
11473--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 11474+++ linux/fs/aufs/file.h 2014-04-24 22:11:10.851935747 +0200
392086de 11475@@ -0,0 +1,312 @@
4a4d8108 11476+/*
523b37e3 11477+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
11478+ *
11479+ * This program, aufs is free software; you can redistribute it and/or modify
11480+ * it under the terms of the GNU General Public License as published by
11481+ * the Free Software Foundation; either version 2 of the License, or
11482+ * (at your option) any later version.
11483+ *
11484+ * This program is distributed in the hope that it will be useful,
11485+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11486+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11487+ * GNU General Public License for more details.
11488+ *
11489+ * You should have received a copy of the GNU General Public License
523b37e3 11490+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 11491+ */
1facf9fc 11492+
4a4d8108
AM
11493+/*
11494+ * file operations
11495+ */
1facf9fc 11496+
4a4d8108
AM
11497+#ifndef __AUFS_FILE_H__
11498+#define __AUFS_FILE_H__
1facf9fc 11499+
4a4d8108 11500+#ifdef __KERNEL__
1facf9fc 11501+
2cbb1c4b 11502+#include <linux/file.h>
4a4d8108
AM
11503+#include <linux/fs.h>
11504+#include <linux/poll.h>
4a4d8108 11505+#include "rwsem.h"
1facf9fc 11506+
4a4d8108
AM
11507+struct au_branch;
11508+struct au_hfile {
11509+ struct file *hf_file;
11510+ struct au_branch *hf_br;
11511+};
1facf9fc 11512+
4a4d8108
AM
11513+struct au_vdir;
11514+struct au_fidir {
11515+ aufs_bindex_t fd_bbot;
11516+ aufs_bindex_t fd_nent;
11517+ struct au_vdir *fd_vdir_cache;
11518+ struct au_hfile fd_hfile[];
11519+};
1facf9fc 11520+
4a4d8108 11521+static inline int au_fidir_sz(int nent)
dece6358 11522+{
4f0767ce
JR
11523+ AuDebugOn(nent < 0);
11524+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 11525+}
1facf9fc 11526+
4a4d8108
AM
11527+struct au_finfo {
11528+ atomic_t fi_generation;
dece6358 11529+
4a4d8108
AM
11530+ struct au_rwsem fi_rwsem;
11531+ aufs_bindex_t fi_btop;
11532+
11533+ /* do not union them */
11534+ struct { /* for non-dir */
11535+ struct au_hfile fi_htop;
2cbb1c4b 11536+ atomic_t fi_mmapped;
4a4d8108
AM
11537+ };
11538+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3
AM
11539+
11540+ struct hlist_node fi_hlist;
11541+ struct file *fi_file; /* very ugly */
4a4d8108 11542+} ____cacheline_aligned_in_smp;
1facf9fc 11543+
4a4d8108 11544+/* ---------------------------------------------------------------------- */
1facf9fc 11545+
4a4d8108
AM
11546+/* file.c */
11547+extern const struct address_space_operations aufs_aop;
11548+unsigned int au_file_roflags(unsigned int flags);
11549+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 11550+ struct file *file, int force_wr);
4a4d8108
AM
11551+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
11552+ struct au_fidir *fidir);
11553+int au_reopen_nondir(struct file *file);
11554+struct au_pin;
11555+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
11556+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
11557+ int wlock);
11558+int au_do_flush(struct file *file, fl_owner_t id,
11559+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 11560+
4a4d8108
AM
11561+/* poll.c */
11562+#ifdef CONFIG_AUFS_POLL
11563+unsigned int aufs_poll(struct file *file, poll_table *wait);
11564+#endif
1facf9fc 11565+
4a4d8108
AM
11566+#ifdef CONFIG_AUFS_BR_HFSPLUS
11567+/* hfsplus.c */
392086de
AM
11568+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
11569+ int force_wr);
4a4d8108
AM
11570+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
11571+ struct file *h_file);
11572+#else
11573+static inline
392086de
AM
11574+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
11575+ int force_wr)
dece6358 11576+{
4a4d8108
AM
11577+ return NULL;
11578+}
1facf9fc 11579+
4a4d8108
AM
11580+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
11581+ struct file *h_file);
11582+#endif
1facf9fc 11583+
4a4d8108
AM
11584+/* f_op.c */
11585+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
11586+int au_do_open_nondir(struct file *file, int flags);
11587+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
11588+
11589+#ifdef CONFIG_AUFS_SP_IATTR
11590+/* f_op_sp.c */
86dc4139 11591+struct au_finfo *au_fi_sp(struct file *file);
4a4d8108
AM
11592+int au_special_file(umode_t mode);
11593+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev);
11594+#else
86dc4139
AM
11595+static inline struct au_finfo *au_fi_sp(struct file *file)
11596+{
11597+ return NULL;
11598+}
4a4d8108
AM
11599+AuStubInt0(au_special_file, umode_t mode)
11600+static inline void au_init_special_fop(struct inode *inode, umode_t mode,
11601+ dev_t rdev)
11602+{
11603+ init_special_inode(inode, mode, rdev);
11604+}
11605+#endif
1facf9fc 11606+
4a4d8108
AM
11607+/* finfo.c */
11608+void au_hfput(struct au_hfile *hf, struct file *file);
11609+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
11610+ struct file *h_file);
1facf9fc 11611+
4a4d8108 11612+void au_update_figen(struct file *file);
4a4d8108
AM
11613+struct au_fidir *au_fidir_alloc(struct super_block *sb);
11614+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 11615+
4a4d8108
AM
11616+void au_fi_init_once(void *_fi);
11617+void au_finfo_fin(struct file *file);
11618+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 11619+
4a4d8108
AM
11620+/* ioctl.c */
11621+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
11622+#ifdef CONFIG_COMPAT
11623+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
11624+ unsigned long arg);
c2b27bf2
AM
11625+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
11626+ unsigned long arg);
b752ccd1 11627+#endif
1facf9fc 11628+
4a4d8108 11629+/* ---------------------------------------------------------------------- */
1facf9fc 11630+
4a4d8108
AM
11631+static inline struct au_finfo *au_fi(struct file *file)
11632+{
86dc4139
AM
11633+ struct au_finfo *finfo;
11634+
11635+ finfo = au_fi_sp(file);
11636+ if (!finfo)
11637+ finfo = file->private_data;
11638+ return finfo;
4a4d8108 11639+}
1facf9fc 11640+
4a4d8108 11641+/* ---------------------------------------------------------------------- */
1facf9fc 11642+
4a4d8108
AM
11643+/*
11644+ * fi_read_lock, fi_write_lock,
11645+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
11646+ */
11647+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 11648+
4a4d8108
AM
11649+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
11650+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
11651+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 11652+
1308ab2a 11653+/* ---------------------------------------------------------------------- */
11654+
4a4d8108
AM
11655+/* todo: hard/soft set? */
11656+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 11657+{
4a4d8108
AM
11658+ FiMustAnyLock(file);
11659+ return au_fi(file)->fi_btop;
11660+}
dece6358 11661+
4a4d8108
AM
11662+static inline aufs_bindex_t au_fbend_dir(struct file *file)
11663+{
11664+ FiMustAnyLock(file);
11665+ AuDebugOn(!au_fi(file)->fi_hdir);
11666+ return au_fi(file)->fi_hdir->fd_bbot;
11667+}
1facf9fc 11668+
4a4d8108
AM
11669+static inline struct au_vdir *au_fvdir_cache(struct file *file)
11670+{
11671+ FiMustAnyLock(file);
11672+ AuDebugOn(!au_fi(file)->fi_hdir);
11673+ return au_fi(file)->fi_hdir->fd_vdir_cache;
11674+}
1facf9fc 11675+
4a4d8108
AM
11676+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
11677+{
11678+ FiMustWriteLock(file);
11679+ au_fi(file)->fi_btop = bindex;
11680+}
1facf9fc 11681+
4a4d8108
AM
11682+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
11683+{
11684+ FiMustWriteLock(file);
11685+ AuDebugOn(!au_fi(file)->fi_hdir);
11686+ au_fi(file)->fi_hdir->fd_bbot = bindex;
11687+}
1308ab2a 11688+
4a4d8108
AM
11689+static inline void au_set_fvdir_cache(struct file *file,
11690+ struct au_vdir *vdir_cache)
11691+{
11692+ FiMustWriteLock(file);
11693+ AuDebugOn(!au_fi(file)->fi_hdir);
11694+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
11695+}
dece6358 11696+
4a4d8108
AM
11697+static inline struct file *au_hf_top(struct file *file)
11698+{
11699+ FiMustAnyLock(file);
11700+ AuDebugOn(au_fi(file)->fi_hdir);
11701+ return au_fi(file)->fi_htop.hf_file;
11702+}
1facf9fc 11703+
4a4d8108
AM
11704+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
11705+{
11706+ FiMustAnyLock(file);
11707+ AuDebugOn(!au_fi(file)->fi_hdir);
11708+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
11709+}
11710+
4a4d8108
AM
11711+/* todo: memory barrier? */
11712+static inline unsigned int au_figen(struct file *f)
dece6358 11713+{
4a4d8108
AM
11714+ return atomic_read(&au_fi(f)->fi_generation);
11715+}
dece6358 11716+
2cbb1c4b
JR
11717+static inline void au_set_mmapped(struct file *f)
11718+{
11719+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
11720+ return;
0c3ec466 11721+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
11722+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
11723+ ;
11724+}
11725+
11726+static inline void au_unset_mmapped(struct file *f)
11727+{
11728+ atomic_dec(&au_fi(f)->fi_mmapped);
11729+}
11730+
4a4d8108
AM
11731+static inline int au_test_mmapped(struct file *f)
11732+{
2cbb1c4b
JR
11733+ return atomic_read(&au_fi(f)->fi_mmapped);
11734+}
11735+
11736+/* customize vma->vm_file */
11737+
11738+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
11739+ struct file *file)
11740+{
53392da6
AM
11741+ struct file *f;
11742+
11743+ f = vma->vm_file;
2cbb1c4b
JR
11744+ get_file(file);
11745+ vma->vm_file = file;
53392da6 11746+ fput(f);
2cbb1c4b
JR
11747+}
11748+
11749+#ifdef CONFIG_MMU
11750+#define AuDbgVmRegion(file, vma) do {} while (0)
11751+
11752+static inline void au_vm_file_reset(struct vm_area_struct *vma,
11753+ struct file *file)
11754+{
11755+ au_do_vm_file_reset(vma, file);
11756+}
11757+#else
11758+#define AuDbgVmRegion(file, vma) \
11759+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
11760+
11761+static inline void au_vm_file_reset(struct vm_area_struct *vma,
11762+ struct file *file)
11763+{
53392da6
AM
11764+ struct file *f;
11765+
2cbb1c4b 11766+ au_do_vm_file_reset(vma, file);
53392da6 11767+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
11768+ get_file(file);
11769+ vma->vm_region->vm_file = file;
53392da6 11770+ fput(f);
2cbb1c4b
JR
11771+}
11772+#endif /* CONFIG_MMU */
11773+
11774+/* handle vma->vm_prfile */
fb47a38f 11775+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
11776+ struct file *file)
11777+{
2cbb1c4b
JR
11778+ get_file(file);
11779+ vma->vm_prfile = file;
11780+#ifndef CONFIG_MMU
11781+ get_file(file);
11782+ vma->vm_region->vm_prfile = file;
11783+#endif
fb47a38f 11784+}
1308ab2a 11785+
4a4d8108
AM
11786+#endif /* __KERNEL__ */
11787+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
11788diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
11789--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 11790+++ linux/fs/aufs/finfo.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 11791@@ -0,0 +1,156 @@
4a4d8108 11792+/*
523b37e3 11793+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
11794+ *
11795+ * This program, aufs is free software; you can redistribute it and/or modify
11796+ * it under the terms of the GNU General Public License as published by
11797+ * the Free Software Foundation; either version 2 of the License, or
11798+ * (at your option) any later version.
11799+ *
11800+ * This program is distributed in the hope that it will be useful,
11801+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11802+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11803+ * GNU General Public License for more details.
11804+ *
11805+ * You should have received a copy of the GNU General Public License
523b37e3 11806+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 11807+ */
1308ab2a 11808+
4a4d8108
AM
11809+/*
11810+ * file private data
11811+ */
1facf9fc 11812+
4a4d8108 11813+#include "aufs.h"
1facf9fc 11814+
4a4d8108
AM
11815+void au_hfput(struct au_hfile *hf, struct file *file)
11816+{
11817+ /* todo: direct access f_flags */
2cbb1c4b 11818+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
11819+ allow_write_access(hf->hf_file);
11820+ fput(hf->hf_file);
11821+ hf->hf_file = NULL;
e49829fe 11822+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
11823+ hf->hf_br = NULL;
11824+}
1facf9fc 11825+
4a4d8108
AM
11826+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
11827+{
11828+ struct au_finfo *finfo = au_fi(file);
11829+ struct au_hfile *hf;
11830+ struct au_fidir *fidir;
11831+
11832+ fidir = finfo->fi_hdir;
11833+ if (!fidir) {
11834+ AuDebugOn(finfo->fi_btop != bindex);
11835+ hf = &finfo->fi_htop;
11836+ } else
11837+ hf = fidir->fd_hfile + bindex;
11838+
11839+ if (hf && hf->hf_file)
11840+ au_hfput(hf, file);
11841+ if (val) {
11842+ FiMustWriteLock(file);
11843+ hf->hf_file = val;
11844+ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
1308ab2a 11845+ }
4a4d8108 11846+}
1facf9fc 11847+
4a4d8108
AM
11848+void au_update_figen(struct file *file)
11849+{
11850+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
11851+ /* smp_mb(); */ /* atomic_set */
1facf9fc 11852+}
11853+
4a4d8108
AM
11854+/* ---------------------------------------------------------------------- */
11855+
4a4d8108
AM
11856+struct au_fidir *au_fidir_alloc(struct super_block *sb)
11857+{
11858+ struct au_fidir *fidir;
11859+ int nbr;
11860+
11861+ nbr = au_sbend(sb) + 1;
11862+ if (nbr < 2)
11863+ nbr = 2; /* initial allocate for 2 branches */
11864+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
11865+ if (fidir) {
11866+ fidir->fd_bbot = -1;
11867+ fidir->fd_nent = nbr;
11868+ fidir->fd_vdir_cache = NULL;
11869+ }
11870+
11871+ return fidir;
11872+}
11873+
11874+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
11875+{
11876+ int err;
11877+ struct au_fidir *fidir, *p;
11878+
11879+ AuRwMustWriteLock(&finfo->fi_rwsem);
11880+ fidir = finfo->fi_hdir;
11881+ AuDebugOn(!fidir);
11882+
11883+ err = -ENOMEM;
11884+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
11885+ GFP_NOFS);
11886+ if (p) {
11887+ p->fd_nent = nbr;
11888+ finfo->fi_hdir = p;
11889+ err = 0;
11890+ }
1facf9fc 11891+
dece6358 11892+ return err;
1facf9fc 11893+}
1308ab2a 11894+
11895+/* ---------------------------------------------------------------------- */
11896+
4a4d8108 11897+void au_finfo_fin(struct file *file)
1308ab2a 11898+{
4a4d8108
AM
11899+ struct au_finfo *finfo;
11900+
7f207e10
AM
11901+ au_nfiles_dec(file->f_dentry->d_sb);
11902+
4a4d8108
AM
11903+ finfo = au_fi(file);
11904+ AuDebugOn(finfo->fi_hdir);
11905+ AuRwDestroy(&finfo->fi_rwsem);
11906+ au_cache_free_finfo(finfo);
1308ab2a 11907+}
1308ab2a 11908+
e49829fe 11909+void au_fi_init_once(void *_finfo)
4a4d8108 11910+{
e49829fe 11911+ struct au_finfo *finfo = _finfo;
2cbb1c4b 11912+ static struct lock_class_key aufs_fi;
1308ab2a 11913+
e49829fe
JR
11914+ au_rw_init(&finfo->fi_rwsem);
11915+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 11916+}
1308ab2a 11917+
4a4d8108
AM
11918+int au_finfo_init(struct file *file, struct au_fidir *fidir)
11919+{
1716fcea 11920+ int err;
4a4d8108
AM
11921+ struct au_finfo *finfo;
11922+ struct dentry *dentry;
11923+
11924+ err = -ENOMEM;
11925+ dentry = file->f_dentry;
11926+ finfo = au_cache_alloc_finfo();
11927+ if (unlikely(!finfo))
11928+ goto out;
11929+
11930+ err = 0;
7f207e10 11931+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
11932+ /* verbose coding for lock class name */
11933+ if (!fidir)
11934+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
11935+ else
11936+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
11937+ au_rw_write_lock(&finfo->fi_rwsem);
11938+ finfo->fi_btop = -1;
11939+ finfo->fi_hdir = fidir;
11940+ atomic_set(&finfo->fi_generation, au_digen(dentry));
11941+ /* smp_mb(); */ /* atomic_set */
11942+
11943+ file->private_data = finfo;
11944+
11945+out:
11946+ return err;
11947+}
7f207e10
AM
11948diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
11949--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 11950+++ linux/fs/aufs/f_op.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 11951@@ -0,0 +1,718 @@
dece6358 11952+/*
523b37e3 11953+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
11954+ *
11955+ * This program, aufs is free software; you can redistribute it and/or modify
11956+ * it under the terms of the GNU General Public License as published by
11957+ * the Free Software Foundation; either version 2 of the License, or
11958+ * (at your option) any later version.
11959+ *
11960+ * This program is distributed in the hope that it will be useful,
11961+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11962+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11963+ * GNU General Public License for more details.
11964+ *
11965+ * You should have received a copy of the GNU General Public License
523b37e3 11966+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 11967+ */
1facf9fc 11968+
11969+/*
4a4d8108 11970+ * file and vm operations
1facf9fc 11971+ */
dece6358 11972+
86dc4139 11973+#include <linux/aio.h>
4a4d8108
AM
11974+#include <linux/fs_stack.h>
11975+#include <linux/mman.h>
4a4d8108 11976+#include <linux/security.h>
dece6358
AM
11977+#include "aufs.h"
11978+
4a4d8108 11979+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 11980+{
4a4d8108
AM
11981+ int err;
11982+ aufs_bindex_t bindex;
11983+ struct file *h_file;
11984+ struct dentry *dentry;
11985+ struct au_finfo *finfo;
11986+
11987+ FiMustWriteLock(file);
11988+
523b37e3 11989+ err = 0;
4a4d8108
AM
11990+ dentry = file->f_dentry;
11991+ finfo = au_fi(file);
11992+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 11993+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108 11994+ bindex = au_dbstart(dentry);
392086de 11995+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
4a4d8108
AM
11996+ if (IS_ERR(h_file))
11997+ err = PTR_ERR(h_file);
11998+ else {
11999+ au_set_fbstart(file, bindex);
12000+ au_set_h_fptr(file, bindex, h_file);
12001+ au_update_figen(file);
523b37e3
AM
12002+ finfo->fi_file = file;
12003+ au_sphl_add(&finfo->fi_hlist, &au_sbi(dentry->d_sb)->si_files);
4a4d8108
AM
12004+ /* todo: necessary? */
12005+ /* file->f_ra = h_file->f_ra; */
12006+ }
027c5e7a 12007+
4a4d8108 12008+ return err;
1facf9fc 12009+}
12010+
4a4d8108
AM
12011+static int aufs_open_nondir(struct inode *inode __maybe_unused,
12012+ struct file *file)
1facf9fc 12013+{
4a4d8108 12014+ int err;
1308ab2a 12015+ struct super_block *sb;
1facf9fc 12016+
523b37e3
AM
12017+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
12018+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 12019+
4a4d8108
AM
12020+ sb = file->f_dentry->d_sb;
12021+ si_read_lock(sb, AuLock_FLUSH);
12022+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
12023+ si_read_unlock(sb);
12024+ return err;
12025+}
1facf9fc 12026+
4a4d8108
AM
12027+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
12028+{
12029+ struct au_finfo *finfo;
12030+ aufs_bindex_t bindex;
1facf9fc 12031+
4a4d8108 12032+ finfo = au_fi(file);
523b37e3 12033+ au_sphl_del(&finfo->fi_hlist, &au_sbi(file->f_dentry->d_sb)->si_files);
4a4d8108 12034+ bindex = finfo->fi_btop;
b4510431 12035+ if (bindex >= 0)
4a4d8108 12036+ au_set_h_fptr(file, bindex, NULL);
7f207e10 12037+
4a4d8108
AM
12038+ au_finfo_fin(file);
12039+ return 0;
1facf9fc 12040+}
12041+
4a4d8108
AM
12042+/* ---------------------------------------------------------------------- */
12043+
12044+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 12045+{
1308ab2a 12046+ int err;
4a4d8108
AM
12047+ struct file *h_file;
12048+
12049+ err = 0;
12050+ h_file = au_hf_top(file);
12051+ if (h_file)
12052+ err = vfsub_flush(h_file, id);
12053+ return err;
12054+}
12055+
12056+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
12057+{
12058+ return au_do_flush(file, id, au_do_flush_nondir);
12059+}
12060+
12061+/* ---------------------------------------------------------------------- */
9dbd164d
AM
12062+/*
12063+ * read and write functions acquire [fdi]_rwsem once, but release before
12064+ * mmap_sem. This is because to stop a race condition between mmap(2).
12065+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
12066+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
12067+ * read functions after [fdi]_rwsem are released, but it should be harmless.
12068+ */
4a4d8108
AM
12069+
12070+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
12071+ loff_t *ppos)
12072+{
12073+ ssize_t err;
dece6358 12074+ struct dentry *dentry;
4a4d8108 12075+ struct file *h_file;
dece6358 12076+ struct super_block *sb;
1facf9fc 12077+
dece6358
AM
12078+ dentry = file->f_dentry;
12079+ sb = dentry->d_sb;
e49829fe 12080+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 12081+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
12082+ if (unlikely(err))
12083+ goto out;
1facf9fc 12084+
4a4d8108 12085+ h_file = au_hf_top(file);
9dbd164d
AM
12086+ get_file(h_file);
12087+ di_read_unlock(dentry, AuLock_IR);
12088+ fi_read_unlock(file);
12089+
12090+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
12091+ err = vfsub_read_u(h_file, buf, count, ppos);
12092+ /* todo: necessary? */
12093+ /* file->f_ra = h_file->f_ra; */
9dbd164d 12094+ /* update without lock, I don't think it a problem */
c06a8ce3 12095+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 12096+ fput(h_file);
1308ab2a 12097+
4f0767ce 12098+out:
dece6358
AM
12099+ si_read_unlock(sb);
12100+ return err;
12101+}
1facf9fc 12102+
e49829fe
JR
12103+/*
12104+ * todo: very ugly
12105+ * it locks both of i_mutex and si_rwsem for read in safe.
12106+ * if the plink maintenance mode continues forever (that is the problem),
12107+ * may loop forever.
12108+ */
12109+static void au_mtx_and_read_lock(struct inode *inode)
12110+{
12111+ int err;
12112+ struct super_block *sb = inode->i_sb;
12113+
12114+ while (1) {
12115+ mutex_lock(&inode->i_mutex);
12116+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
12117+ if (!err)
12118+ break;
12119+ mutex_unlock(&inode->i_mutex);
12120+ si_read_lock(sb, AuLock_NOPLMW);
12121+ si_read_unlock(sb);
12122+ }
12123+}
12124+
4a4d8108
AM
12125+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
12126+ size_t count, loff_t *ppos)
dece6358 12127+{
4a4d8108
AM
12128+ ssize_t err;
12129+ struct au_pin pin;
dece6358 12130+ struct dentry *dentry;
9dbd164d 12131+ struct super_block *sb;
4a4d8108 12132+ struct inode *inode;
4a4d8108
AM
12133+ struct file *h_file;
12134+ char __user *buf = (char __user *)ubuf;
1facf9fc 12135+
dece6358 12136+ dentry = file->f_dentry;
9dbd164d 12137+ sb = dentry->d_sb;
4a4d8108 12138+ inode = dentry->d_inode;
e49829fe 12139+ au_mtx_and_read_lock(inode);
1facf9fc 12140+
4a4d8108
AM
12141+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12142+ if (unlikely(err))
12143+ goto out;
1facf9fc 12144+
4a4d8108
AM
12145+ err = au_ready_to_write(file, -1, &pin);
12146+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
12147+ if (unlikely(err)) {
12148+ di_read_unlock(dentry, AuLock_IR);
12149+ fi_write_unlock(file);
12150+ goto out;
12151+ }
1facf9fc 12152+
4a4d8108 12153+ h_file = au_hf_top(file);
9dbd164d 12154+ get_file(h_file);
4a4d8108 12155+ au_unpin(&pin);
9dbd164d
AM
12156+ di_read_unlock(dentry, AuLock_IR);
12157+ fi_write_unlock(file);
12158+
4a4d8108 12159+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 12160+ ii_write_lock_child(inode);
4a4d8108 12161+ au_cpup_attr_timesizes(inode);
c06a8ce3 12162+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
12163+ ii_write_unlock(inode);
12164+ fput(h_file);
1facf9fc 12165+
4f0767ce 12166+out:
9dbd164d 12167+ si_read_unlock(sb);
4a4d8108 12168+ mutex_unlock(&inode->i_mutex);
dece6358
AM
12169+ return err;
12170+}
1facf9fc 12171+
4a4d8108
AM
12172+static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
12173+ const struct iovec *iov, unsigned long nv, loff_t pos)
dece6358 12174+{
4a4d8108
AM
12175+ ssize_t err;
12176+ struct file *file;
12177+ ssize_t (*func)(struct kiocb *, const struct iovec *, unsigned long,
12178+ loff_t);
1facf9fc 12179+
4a4d8108
AM
12180+ err = security_file_permission(h_file, rw);
12181+ if (unlikely(err))
12182+ goto out;
1facf9fc 12183+
4a4d8108
AM
12184+ err = -ENOSYS;
12185+ func = NULL;
12186+ if (rw == MAY_READ)
12187+ func = h_file->f_op->aio_read;
12188+ else if (rw == MAY_WRITE)
12189+ func = h_file->f_op->aio_write;
12190+ if (func) {
12191+ file = kio->ki_filp;
12192+ kio->ki_filp = h_file;
2cbb1c4b 12193+ lockdep_off();
4a4d8108 12194+ err = func(kio, iov, nv, pos);
2cbb1c4b 12195+ lockdep_on();
4a4d8108
AM
12196+ kio->ki_filp = file;
12197+ } else
12198+ /* currently there is no such fs */
12199+ WARN_ON_ONCE(1);
1facf9fc 12200+
4f0767ce 12201+out:
dece6358
AM
12202+ return err;
12203+}
1facf9fc 12204+
4a4d8108
AM
12205+static ssize_t aufs_aio_read(struct kiocb *kio, const struct iovec *iov,
12206+ unsigned long nv, loff_t pos)
1facf9fc 12207+{
4a4d8108
AM
12208+ ssize_t err;
12209+ struct file *file, *h_file;
12210+ struct dentry *dentry;
dece6358 12211+ struct super_block *sb;
1facf9fc 12212+
4a4d8108 12213+ file = kio->ki_filp;
dece6358 12214+ dentry = file->f_dentry;
1308ab2a 12215+ sb = dentry->d_sb;
e49829fe 12216+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
12217+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
12218+ if (unlikely(err))
12219+ goto out;
12220+
12221+ h_file = au_hf_top(file);
9dbd164d
AM
12222+ get_file(h_file);
12223+ di_read_unlock(dentry, AuLock_IR);
12224+ fi_read_unlock(file);
12225+
4a4d8108
AM
12226+ err = au_do_aio(h_file, MAY_READ, kio, iov, nv, pos);
12227+ /* todo: necessary? */
12228+ /* file->f_ra = h_file->f_ra; */
9dbd164d 12229+ /* update without lock, I don't think it a problem */
c06a8ce3 12230+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 12231+ fput(h_file);
1facf9fc 12232+
4f0767ce 12233+out:
4a4d8108 12234+ si_read_unlock(sb);
1308ab2a 12235+ return err;
12236+}
1facf9fc 12237+
4a4d8108
AM
12238+static ssize_t aufs_aio_write(struct kiocb *kio, const struct iovec *iov,
12239+ unsigned long nv, loff_t pos)
1308ab2a 12240+{
4a4d8108
AM
12241+ ssize_t err;
12242+ struct au_pin pin;
12243+ struct dentry *dentry;
12244+ struct inode *inode;
4a4d8108 12245+ struct file *file, *h_file;
9dbd164d 12246+ struct super_block *sb;
1308ab2a 12247+
4a4d8108 12248+ file = kio->ki_filp;
1308ab2a 12249+ dentry = file->f_dentry;
9dbd164d 12250+ sb = dentry->d_sb;
1308ab2a 12251+ inode = dentry->d_inode;
e49829fe
JR
12252+ au_mtx_and_read_lock(inode);
12253+
4a4d8108
AM
12254+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12255+ if (unlikely(err))
1308ab2a 12256+ goto out;
1facf9fc 12257+
4a4d8108
AM
12258+ err = au_ready_to_write(file, -1, &pin);
12259+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
12260+ if (unlikely(err)) {
12261+ di_read_unlock(dentry, AuLock_IR);
12262+ fi_write_unlock(file);
12263+ goto out;
12264+ }
1facf9fc 12265+
4a4d8108 12266+ h_file = au_hf_top(file);
9dbd164d
AM
12267+ get_file(h_file);
12268+ au_unpin(&pin);
12269+ di_read_unlock(dentry, AuLock_IR);
12270+ fi_write_unlock(file);
12271+
4a4d8108 12272+ err = au_do_aio(h_file, MAY_WRITE, kio, iov, nv, pos);
9dbd164d 12273+ ii_write_lock_child(inode);
4a4d8108 12274+ au_cpup_attr_timesizes(inode);
c06a8ce3 12275+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
12276+ ii_write_unlock(inode);
12277+ fput(h_file);
1facf9fc 12278+
4f0767ce 12279+out:
9dbd164d 12280+ si_read_unlock(sb);
4a4d8108 12281+ mutex_unlock(&inode->i_mutex);
dece6358 12282+ return err;
1facf9fc 12283+}
12284+
4a4d8108
AM
12285+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
12286+ struct pipe_inode_info *pipe, size_t len,
12287+ unsigned int flags)
1facf9fc 12288+{
4a4d8108
AM
12289+ ssize_t err;
12290+ struct file *h_file;
12291+ struct dentry *dentry;
dece6358 12292+ struct super_block *sb;
1facf9fc 12293+
dece6358 12294+ dentry = file->f_dentry;
dece6358 12295+ sb = dentry->d_sb;
e49829fe 12296+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
12297+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
12298+ if (unlikely(err))
dece6358 12299+ goto out;
1facf9fc 12300+
4a4d8108
AM
12301+ err = -EINVAL;
12302+ h_file = au_hf_top(file);
9dbd164d 12303+ get_file(h_file);
4a4d8108 12304+ if (au_test_loopback_kthread()) {
87a755f4
AM
12305+ au_warn_loopback(h_file->f_dentry->d_sb);
12306+ if (file->f_mapping != h_file->f_mapping) {
12307+ file->f_mapping = h_file->f_mapping;
12308+ smp_mb(); /* unnecessary? */
12309+ }
1308ab2a 12310+ }
9dbd164d
AM
12311+ di_read_unlock(dentry, AuLock_IR);
12312+ fi_read_unlock(file);
12313+
4a4d8108
AM
12314+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
12315+ /* todo: necessasry? */
12316+ /* file->f_ra = h_file->f_ra; */
9dbd164d 12317+ /* update without lock, I don't think it a problem */
c06a8ce3 12318+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 12319+ fput(h_file);
1facf9fc 12320+
4f0767ce 12321+out:
4a4d8108 12322+ si_read_unlock(sb);
dece6358 12323+ return err;
1facf9fc 12324+}
12325+
4a4d8108
AM
12326+static ssize_t
12327+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
12328+ size_t len, unsigned int flags)
1facf9fc 12329+{
4a4d8108
AM
12330+ ssize_t err;
12331+ struct au_pin pin;
12332+ struct dentry *dentry;
12333+ struct inode *inode;
4a4d8108 12334+ struct file *h_file;
9dbd164d 12335+ struct super_block *sb;
1facf9fc 12336+
4a4d8108 12337+ dentry = file->f_dentry;
9dbd164d 12338+ sb = dentry->d_sb;
4a4d8108 12339+ inode = dentry->d_inode;
e49829fe 12340+ au_mtx_and_read_lock(inode);
9dbd164d 12341+
4a4d8108
AM
12342+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12343+ if (unlikely(err))
12344+ goto out;
1facf9fc 12345+
4a4d8108
AM
12346+ err = au_ready_to_write(file, -1, &pin);
12347+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
12348+ if (unlikely(err)) {
12349+ di_read_unlock(dentry, AuLock_IR);
12350+ fi_write_unlock(file);
12351+ goto out;
12352+ }
1facf9fc 12353+
4a4d8108 12354+ h_file = au_hf_top(file);
9dbd164d 12355+ get_file(h_file);
4a4d8108 12356+ au_unpin(&pin);
9dbd164d
AM
12357+ di_read_unlock(dentry, AuLock_IR);
12358+ fi_write_unlock(file);
12359+
4a4d8108 12360+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 12361+ ii_write_lock_child(inode);
4a4d8108 12362+ au_cpup_attr_timesizes(inode);
c06a8ce3 12363+ inode->i_mode = file_inode(h_file)->i_mode;
9dbd164d
AM
12364+ ii_write_unlock(inode);
12365+ fput(h_file);
1facf9fc 12366+
4f0767ce 12367+out:
9dbd164d 12368+ si_read_unlock(sb);
4a4d8108
AM
12369+ mutex_unlock(&inode->i_mutex);
12370+ return err;
12371+}
1facf9fc 12372+
4a4d8108
AM
12373+/* ---------------------------------------------------------------------- */
12374+
9dbd164d
AM
12375+/*
12376+ * The locking order around current->mmap_sem.
12377+ * - in most and regular cases
12378+ * file I/O syscall -- aufs_read() or something
12379+ * -- si_rwsem for read -- mmap_sem
12380+ * (Note that [fdi]i_rwsem are released before mmap_sem).
12381+ * - in mmap case
12382+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
12383+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
12384+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
12385+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
12386+ * It means that when aufs acquires si_rwsem for write, the process should never
12387+ * acquire mmap_sem.
12388+ *
392086de 12389+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
12390+ * problem either since any directory is not able to be mmap-ed.
12391+ * The similar scenario is applied to aufs_readlink() too.
12392+ */
12393+
2dfbb274
AM
12394+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
12395+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
12396+
12397+static unsigned long au_arch_prot_conv(unsigned long flags)
12398+{
12399+ /* currently ppc64 only */
12400+#ifdef CONFIG_PPC64
12401+ /* cf. linux/arch/powerpc/include/asm/mman.h */
12402+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
12403+ return AuConv_VM_PROT(flags, SAO);
12404+#else
12405+ AuDebugOn(arch_calc_vm_prot_bits(-1));
12406+ return 0;
12407+#endif
12408+}
12409+
12410+static unsigned long au_prot_conv(unsigned long flags)
12411+{
12412+ return AuConv_VM_PROT(flags, READ)
12413+ | AuConv_VM_PROT(flags, WRITE)
12414+ | AuConv_VM_PROT(flags, EXEC)
12415+ | au_arch_prot_conv(flags);
12416+}
12417+
12418+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
12419+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
12420+
12421+static unsigned long au_flag_conv(unsigned long flags)
12422+{
12423+ return AuConv_VM_MAP(flags, GROWSDOWN)
12424+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
12425+ | AuConv_VM_MAP(flags, LOCKED);
12426+}
12427+
9dbd164d 12428+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 12429+{
4a4d8108
AM
12430+ int err;
12431+ aufs_bindex_t bstart;
12432+ const unsigned char wlock
9dbd164d 12433+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
12434+ struct dentry *dentry;
12435+ struct super_block *sb;
9dbd164d
AM
12436+ struct file *h_file;
12437+ struct au_branch *br;
12438+ struct au_pin pin;
12439+
12440+ AuDbgVmRegion(file, vma);
1308ab2a 12441+
4a4d8108
AM
12442+ dentry = file->f_dentry;
12443+ sb = dentry->d_sb;
9dbd164d 12444+ lockdep_off();
e49829fe 12445+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
12446+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12447+ if (unlikely(err))
12448+ goto out;
12449+
4a4d8108 12450+ if (wlock) {
4a4d8108
AM
12451+ err = au_ready_to_write(file, -1, &pin);
12452+ di_write_unlock(dentry);
9dbd164d
AM
12453+ if (unlikely(err)) {
12454+ fi_write_unlock(file);
12455+ goto out;
12456+ }
4a4d8108
AM
12457+ au_unpin(&pin);
12458+ } else
12459+ di_write_unlock(dentry);
9dbd164d 12460+
4a4d8108 12461+ bstart = au_fbstart(file);
9dbd164d
AM
12462+ br = au_sbr(sb, bstart);
12463+ h_file = au_hf_top(file);
12464+ get_file(h_file);
2cbb1c4b 12465+ au_set_mmapped(file);
4a4d8108 12466+ fi_write_unlock(file);
9dbd164d 12467+ lockdep_on();
1308ab2a 12468+
9dbd164d 12469+ au_vm_file_reset(vma, h_file);
2dfbb274
AM
12470+ err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
12471+ au_flag_conv(vma->vm_flags));
9dbd164d
AM
12472+ if (!err)
12473+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
12474+ if (unlikely(err))
12475+ goto out_reset;
4a4d8108 12476+
fb47a38f 12477+ au_vm_prfile_set(vma, file);
4a4d8108 12478+ /* update without lock, I don't think it a problem */
c06a8ce3 12479+ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
2cbb1c4b 12480+ goto out_fput; /* success */
4a4d8108 12481+
2cbb1c4b
JR
12482+out_reset:
12483+ au_unset_mmapped(file);
12484+ au_vm_file_reset(vma, file);
12485+out_fput:
9dbd164d
AM
12486+ fput(h_file);
12487+ lockdep_off();
4f0767ce 12488+out:
9dbd164d
AM
12489+ si_read_unlock(sb);
12490+ lockdep_on();
12491+ AuTraceErr(err);
4a4d8108
AM
12492+ return err;
12493+}
12494+
12495+/* ---------------------------------------------------------------------- */
12496+
1e00d052
AM
12497+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
12498+ int datasync)
4a4d8108
AM
12499+{
12500+ int err;
12501+ struct au_pin pin;
b752ccd1 12502+ struct dentry *dentry;
4a4d8108
AM
12503+ struct inode *inode;
12504+ struct file *h_file;
12505+ struct super_block *sb;
12506+
b752ccd1 12507+ dentry = file->f_dentry;
4a4d8108 12508+ inode = dentry->d_inode;
4a4d8108 12509+ sb = dentry->d_sb;
1e00d052 12510+ mutex_lock(&inode->i_mutex);
e49829fe
JR
12511+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
12512+ if (unlikely(err))
12513+ goto out;
4a4d8108
AM
12514+
12515+ err = 0; /* -EBADF; */ /* posix? */
12516+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 12517+ goto out_si;
4a4d8108
AM
12518+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12519+ if (unlikely(err))
e49829fe 12520+ goto out_si;
4a4d8108
AM
12521+
12522+ err = au_ready_to_write(file, -1, &pin);
12523+ di_downgrade_lock(dentry, AuLock_IR);
12524+ if (unlikely(err))
12525+ goto out_unlock;
12526+ au_unpin(&pin);
12527+
12528+ err = -EINVAL;
12529+ h_file = au_hf_top(file);
53392da6
AM
12530+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
12531+ au_cpup_attr_timesizes(inode);
4a4d8108 12532+
4f0767ce 12533+out_unlock:
4a4d8108 12534+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 12535+ fi_write_unlock(file);
e49829fe 12536+out_si:
953406b4 12537+ si_read_unlock(sb);
e49829fe 12538+out:
1e00d052 12539+ mutex_unlock(&inode->i_mutex);
4a4d8108 12540+ return err;
dece6358
AM
12541+}
12542+
4a4d8108
AM
12543+/* no one supports this operation, currently */
12544+#if 0
12545+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 12546+{
4a4d8108
AM
12547+ int err;
12548+ struct au_pin pin;
1308ab2a 12549+ struct dentry *dentry;
4a4d8108
AM
12550+ struct inode *inode;
12551+ struct file *file, *h_file;
1308ab2a 12552+
4a4d8108 12553+ file = kio->ki_filp;
1308ab2a 12554+ dentry = file->f_dentry;
4a4d8108 12555+ inode = dentry->d_inode;
e49829fe 12556+ au_mtx_and_read_lock(inode);
4a4d8108
AM
12557+
12558+ err = 0; /* -EBADF; */ /* posix? */
12559+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
12560+ goto out;
12561+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
12562+ if (unlikely(err))
1308ab2a 12563+ goto out;
12564+
4a4d8108
AM
12565+ err = au_ready_to_write(file, -1, &pin);
12566+ di_downgrade_lock(dentry, AuLock_IR);
12567+ if (unlikely(err))
12568+ goto out_unlock;
12569+ au_unpin(&pin);
1308ab2a 12570+
4a4d8108
AM
12571+ err = -ENOSYS;
12572+ h_file = au_hf_top(file);
523b37e3 12573+ if (h_file->f_op->aio_fsync) {
4a4d8108 12574+ struct mutex *h_mtx;
1308ab2a 12575+
c06a8ce3 12576+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
12577+ if (!is_sync_kiocb(kio)) {
12578+ get_file(h_file);
12579+ fput(file);
12580+ }
12581+ kio->ki_filp = h_file;
12582+ err = h_file->f_op->aio_fsync(kio, datasync);
12583+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
12584+ if (!err)
12585+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
12586+ /*ignore*/
12587+ au_cpup_attr_timesizes(inode);
12588+ mutex_unlock(h_mtx);
12589+ }
1308ab2a 12590+
4f0767ce 12591+out_unlock:
4a4d8108
AM
12592+ di_read_unlock(dentry, AuLock_IR);
12593+ fi_write_unlock(file);
4f0767ce 12594+out:
e49829fe 12595+ si_read_unlock(inode->sb);
4a4d8108
AM
12596+ mutex_unlock(&inode->i_mutex);
12597+ return err;
dece6358 12598+}
4a4d8108 12599+#endif
dece6358 12600+
4a4d8108 12601+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 12602+{
4a4d8108
AM
12603+ int err;
12604+ struct file *h_file;
12605+ struct dentry *dentry;
12606+ struct super_block *sb;
1308ab2a 12607+
4a4d8108
AM
12608+ dentry = file->f_dentry;
12609+ sb = dentry->d_sb;
e49829fe 12610+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
12611+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
12612+ if (unlikely(err))
12613+ goto out;
12614+
12615+ h_file = au_hf_top(file);
523b37e3 12616+ if (h_file->f_op->fasync)
4a4d8108
AM
12617+ err = h_file->f_op->fasync(fd, h_file, flag);
12618+
12619+ di_read_unlock(dentry, AuLock_IR);
12620+ fi_read_unlock(file);
1308ab2a 12621+
4f0767ce 12622+out:
4a4d8108 12623+ si_read_unlock(sb);
1308ab2a 12624+ return err;
dece6358 12625+}
4a4d8108
AM
12626+
12627+/* ---------------------------------------------------------------------- */
12628+
12629+/* no one supports this operation, currently */
12630+#if 0
12631+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
12632+ size_t len, loff_t *pos , int more)
12633+{
12634+}
12635+#endif
12636+
12637+/* ---------------------------------------------------------------------- */
12638+
12639+const struct file_operations aufs_file_fop = {
12640+ .owner = THIS_MODULE,
2cbb1c4b 12641+
027c5e7a 12642+ .llseek = default_llseek,
4a4d8108
AM
12643+
12644+ .read = aufs_read,
12645+ .write = aufs_write,
12646+ .aio_read = aufs_aio_read,
12647+ .aio_write = aufs_aio_write,
12648+#ifdef CONFIG_AUFS_POLL
12649+ .poll = aufs_poll,
12650+#endif
12651+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 12652+#ifdef CONFIG_COMPAT
c2b27bf2 12653+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 12654+#endif
4a4d8108
AM
12655+ .mmap = aufs_mmap,
12656+ .open = aufs_open_nondir,
12657+ .flush = aufs_flush_nondir,
12658+ .release = aufs_release_nondir,
12659+ .fsync = aufs_fsync_nondir,
12660+ /* .aio_fsync = aufs_aio_fsync_nondir, */
12661+ .fasync = aufs_fasync,
12662+ /* .sendpage = aufs_sendpage, */
12663+ .splice_write = aufs_splice_write,
12664+ .splice_read = aufs_splice_read,
12665+#if 0
12666+ .aio_splice_write = aufs_aio_splice_write,
12667+ .aio_splice_read = aufs_aio_splice_read
12668+#endif
12669+};
7f207e10
AM
12670diff -urN /usr/share/empty/fs/aufs/f_op_sp.c linux/fs/aufs/f_op_sp.c
12671--- /usr/share/empty/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 12672+++ linux/fs/aufs/f_op_sp.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 12673@@ -0,0 +1,382 @@
1308ab2a 12674+/*
523b37e3 12675+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1308ab2a 12676+ *
12677+ * This program, aufs is free software; you can redistribute it and/or modify
12678+ * it under the terms of the GNU General Public License as published by
12679+ * the Free Software Foundation; either version 2 of the License, or
12680+ * (at your option) any later version.
12681+ *
12682+ * This program is distributed in the hope that it will be useful,
12683+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12684+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12685+ * GNU General Public License for more details.
12686+ *
12687+ * You should have received a copy of the GNU General Public License
523b37e3 12688+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 12689+ */
dece6358 12690+
1308ab2a 12691+/*
4a4d8108
AM
12692+ * file operations for special files.
12693+ * while they exist in aufs virtually,
12694+ * their file I/O is handled out of aufs.
1308ab2a 12695+ */
12696+
86dc4139 12697+#include <linux/aio.h>
4a4d8108 12698+#include "aufs.h"
1308ab2a 12699+
86dc4139
AM
12700+/*
12701+ * I don't think the size of this list grows much.
12702+ * so here is a very simple list implemented in order to find finfo matching a
12703+ * given file.
12704+ */
12705+static struct au_sphlhead au_finfo_sp = {
12706+ .spin = __SPIN_LOCK_INITIALIZER(au_finfo_sp.spin),
12707+ .head = HLIST_HEAD_INIT
12708+};
12709+
12710+struct au_finfo_sp {
12711+ struct hlist_node hlist;
c2b27bf2 12712+ struct file *file;
86dc4139
AM
12713+ struct au_finfo *finfo;
12714+};
12715+
12716+struct au_finfo *au_fi_sp(struct file *file)
12717+{
12718+ struct au_finfo *finfo;
12719+ struct au_finfo_sp *sp;
12720+
12721+ finfo = NULL;
12722+ spin_lock(&au_finfo_sp.spin);
12723+ hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12724+ if (sp->file != file)
12725+ continue;
12726+ finfo = sp->finfo;
12727+ break;
12728+ }
12729+ spin_unlock(&au_finfo_sp.spin);
12730+
12731+ return finfo;
12732+}
12733+
12734+static int au_fi_sp_add(struct file *file)
12735+{
12736+ int err;
12737+ struct au_finfo_sp *sp;
12738+
12739+ err = -ENOMEM;
12740+ sp = kmalloc(sizeof(*sp), GFP_NOFS);
12741+ if (sp) {
12742+ err = 0;
12743+ sp->file = file;
12744+ sp->finfo = file->private_data;
12745+ spin_lock(&au_finfo_sp.spin);
12746+ hlist_add_head(&sp->hlist, &au_finfo_sp.head);
12747+ spin_unlock(&au_finfo_sp.spin);
12748+ }
12749+ return err;
12750+}
12751+
12752+static void au_fi_sp_del(struct file *file)
12753+{
12754+ struct au_finfo_sp *sp, *do_free;
12755+
12756+ do_free = NULL;
12757+ spin_lock(&au_finfo_sp.spin);
12758+ hlist_for_each_entry(sp, &au_finfo_sp.head, hlist) {
12759+ if (sp->file != file)
12760+ continue;
12761+ hlist_del(&sp->hlist);
12762+ do_free = sp;
12763+ break;
12764+ }
12765+ spin_unlock(&au_finfo_sp.spin);
12766+ kfree(do_free);
12767+}
12768+
12769+/* ---------------------------------------------------------------------- */
12770+
4a4d8108
AM
12771+static ssize_t aufs_aio_read_sp(struct kiocb *kio, const struct iovec *iov,
12772+ unsigned long nv, loff_t pos)
dece6358 12773+{
4a4d8108
AM
12774+ ssize_t err;
12775+ aufs_bindex_t bstart;
12776+ unsigned char wbr;
12777+ struct file *file, *h_file;
12778+ struct super_block *sb;
1308ab2a 12779+
4a4d8108
AM
12780+ file = kio->ki_filp;
12781+ sb = file->f_dentry->d_sb;
12782+ si_read_lock(sb, AuLock_FLUSH);
12783+ fi_read_lock(file);
12784+ bstart = au_fbstart(file);
12785+ h_file = au_hf_top(file);
12786+ fi_read_unlock(file);
12787+ wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12788+ si_read_unlock(sb);
12789+
12790+ /* do not change the file in kio */
12791+ AuDebugOn(!h_file->f_op || !h_file->f_op->aio_read);
12792+ err = h_file->f_op->aio_read(kio, iov, nv, pos);
12793+ if (err > 0 && wbr)
12794+ file_accessed(h_file);
12795+
12796+ return err;
12797+}
12798+
12799+static ssize_t aufs_aio_write_sp(struct kiocb *kio, const struct iovec *iov,
12800+ unsigned long nv, loff_t pos)
12801+{
12802+ ssize_t err;
12803+ aufs_bindex_t bstart;
12804+ unsigned char wbr;
12805+ struct super_block *sb;
12806+ struct file *file, *h_file;
12807+
12808+ file = kio->ki_filp;
12809+ sb = file->f_dentry->d_sb;
12810+ si_read_lock(sb, AuLock_FLUSH);
12811+ fi_read_lock(file);
12812+ bstart = au_fbstart(file);
12813+ h_file = au_hf_top(file);
12814+ fi_read_unlock(file);
12815+ wbr = !!au_br_writable(au_sbr(sb, bstart)->br_perm);
12816+ si_read_unlock(sb);
12817+
12818+ /* do not change the file in kio */
12819+ AuDebugOn(!h_file->f_op || !h_file->f_op->aio_write);
12820+ err = h_file->f_op->aio_write(kio, iov, nv, pos);
4a4d8108
AM
12821+ return err;
12822+}
12823+
12824+/* ---------------------------------------------------------------------- */
12825+
12826+static int aufs_release_sp(struct inode *inode, struct file *file)
12827+{
12828+ int err;
12829+ struct file *h_file;
12830+
12831+ fi_read_lock(file);
12832+ h_file = au_hf_top(file);
12833+ fi_read_unlock(file);
12834+ /* close this fifo in aufs */
12835+ err = h_file->f_op->release(inode, file); /* ignore */
12836+ aufs_release_nondir(inode, file); /* ignore */
86dc4139 12837+ au_fi_sp_del(file);
4a4d8108
AM
12838+ return err;
12839+}
12840+
12841+/* ---------------------------------------------------------------------- */
12842+
12843+/* currently, support only FIFO */
4f0767ce
JR
12844+enum {
12845+ AuSp_FIFO, AuSp_FIFO_R, AuSp_FIFO_W, AuSp_FIFO_RW,
12846+ /* AuSp_SOCK, AuSp_CHR, AuSp_BLK, */
12847+ AuSp_Last
12848+};
4a4d8108
AM
12849+static int aufs_open_sp(struct inode *inode, struct file *file);
12850+static struct au_sp_fop {
12851+ int done;
12852+ struct file_operations fop; /* not 'const' */
12853+ spinlock_t spin;
12854+} au_sp_fop[AuSp_Last] = {
12855+ [AuSp_FIFO] = {
12856+ .fop = {
12857+ .owner = THIS_MODULE,
12858+ .open = aufs_open_sp
12859+ }
12860+ }
12861+};
12862+
12863+static void au_init_fop_sp(struct file *file)
12864+{
12865+ struct au_sp_fop *p;
12866+ int i;
12867+ struct file *h_file;
12868+
12869+ p = au_sp_fop;
12870+ if (unlikely(!p->done)) {
12871+ /* initialize first time only */
12872+ static DEFINE_SPINLOCK(spin);
12873+
12874+ spin_lock(&spin);
12875+ if (!p->done) {
12876+ BUILD_BUG_ON(sizeof(au_sp_fop)/sizeof(*au_sp_fop)
12877+ != AuSp_Last);
12878+ for (i = 0; i < AuSp_Last; i++)
12879+ spin_lock_init(&p[i].spin);
12880+ p->done = 1;
12881+ }
12882+ spin_unlock(&spin);
12883+ }
12884+
12885+ switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
12886+ case FMODE_READ:
12887+ i = AuSp_FIFO_R;
12888+ break;
12889+ case FMODE_WRITE:
12890+ i = AuSp_FIFO_W;
12891+ break;
12892+ case FMODE_READ | FMODE_WRITE:
12893+ i = AuSp_FIFO_RW;
12894+ break;
12895+ default:
12896+ BUG();
12897+ }
12898+
12899+ p += i;
12900+ if (unlikely(!p->done)) {
12901+ /* initialize first time only */
12902+ h_file = au_hf_top(file);
12903+ spin_lock(&p->spin);
12904+ if (!p->done) {
12905+ p->fop = *h_file->f_op;
12906+ p->fop.owner = THIS_MODULE;
12907+ if (p->fop.aio_read)
12908+ p->fop.aio_read = aufs_aio_read_sp;
12909+ if (p->fop.aio_write)
12910+ p->fop.aio_write = aufs_aio_write_sp;
12911+ p->fop.release = aufs_release_sp;
12912+ p->done = 1;
12913+ }
12914+ spin_unlock(&p->spin);
12915+ }
12916+ file->f_op = &p->fop;
12917+}
12918+
12919+static int au_cpup_sp(struct dentry *dentry)
12920+{
12921+ int err;
4a4d8108
AM
12922+ struct au_pin pin;
12923+ struct au_wr_dir_args wr_dir_args = {
12924+ .force_btgt = -1,
12925+ .flags = 0
12926+ };
c2b27bf2
AM
12927+ struct au_cp_generic cpg = {
12928+ .dentry = dentry,
12929+ .bdst = -1,
12930+ .bsrc = -1,
12931+ .len = -1,
12932+ .pin = &pin,
12933+ .flags = AuCpup_DTIME
12934+ };
4a4d8108 12935+
523b37e3 12936+ AuDbg("%pd\n", dentry);
4a4d8108
AM
12937+
12938+ di_read_unlock(dentry, AuLock_IR);
12939+ di_write_lock_child(dentry);
12940+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
12941+ if (unlikely(err < 0))
12942+ goto out;
c2b27bf2 12943+ cpg.bdst = err;
4a4d8108 12944+ err = 0;
c2b27bf2 12945+ if (cpg.bdst == au_dbstart(dentry))
4a4d8108
AM
12946+ goto out; /* success */
12947+
c2b27bf2 12948+ err = au_pin(&pin, dentry, cpg.bdst, au_opt_udba(dentry->d_sb),
4a4d8108
AM
12949+ AuPin_MNT_WRITE);
12950+ if (!err) {
c2b27bf2 12951+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
12952+ au_unpin(&pin);
12953+ }
12954+
4f0767ce 12955+out:
4a4d8108
AM
12956+ di_downgrade_lock(dentry, AuLock_IR);
12957+ return err;
12958+}
12959+
12960+static int au_do_open_sp(struct file *file, int flags)
12961+{
12962+ int err;
12963+ struct dentry *dentry;
12964+ struct super_block *sb;
12965+ struct file *h_file;
12966+ struct inode *h_inode;
12967+
86dc4139
AM
12968+ err = au_fi_sp_add(file);
12969+ if (unlikely(err))
12970+ goto out;
12971+
4a4d8108 12972+ dentry = file->f_dentry;
523b37e3 12973+ AuDbg("%pd\n", dentry);
4a4d8108
AM
12974+
12975+ /*
12976+ * try copying-up.
12977+ * operate on the ro branch is not an error.
12978+ */
12979+ au_cpup_sp(dentry); /* ignore */
12980+
12981+ /* prepare h_file */
12982+ err = au_do_open_nondir(file, vfsub_file_flags(file));
12983+ if (unlikely(err))
86dc4139 12984+ goto out_del;
4a4d8108
AM
12985+
12986+ sb = dentry->d_sb;
12987+ h_file = au_hf_top(file);
c06a8ce3 12988+ h_inode = file_inode(h_file);
4a4d8108
AM
12989+ di_read_unlock(dentry, AuLock_IR);
12990+ fi_write_unlock(file);
12991+ si_read_unlock(sb);
12992+ /* open this fifo in aufs */
c06a8ce3 12993+ err = h_inode->i_fop->open(file_inode(file), file);
4a4d8108
AM
12994+ si_noflush_read_lock(sb);
12995+ fi_write_lock(file);
12996+ di_read_lock_child(dentry, AuLock_IR);
86dc4139 12997+ if (!err) {
4a4d8108 12998+ au_init_fop_sp(file);
86dc4139
AM
12999+ goto out; /* success */
13000+ }
4a4d8108 13001+
86dc4139
AM
13002+out_del:
13003+ au_fi_sp_del(file);
4f0767ce 13004+out:
4a4d8108
AM
13005+ return err;
13006+}
13007+
13008+static int aufs_open_sp(struct inode *inode, struct file *file)
13009+{
13010+ int err;
13011+ struct super_block *sb;
13012+
13013+ sb = file->f_dentry->d_sb;
13014+ si_read_lock(sb, AuLock_FLUSH);
13015+ err = au_do_open(file, au_do_open_sp, /*fidir*/NULL);
13016+ si_read_unlock(sb);
13017+ return err;
13018+}
13019+
13020+/* ---------------------------------------------------------------------- */
13021+
13022+void au_init_special_fop(struct inode *inode, umode_t mode, dev_t rdev)
13023+{
13024+ init_special_inode(inode, mode, rdev);
13025+
13026+ switch (mode & S_IFMT) {
13027+ case S_IFIFO:
13028+ inode->i_fop = &au_sp_fop[AuSp_FIFO].fop;
13029+ /*FALLTHROUGH*/
13030+ case S_IFCHR:
13031+ case S_IFBLK:
13032+ case S_IFSOCK:
13033+ break;
13034+ default:
13035+ AuDebugOn(1);
13036+ }
13037+}
13038+
13039+int au_special_file(umode_t mode)
13040+{
13041+ int ret;
13042+
13043+ ret = 0;
13044+ switch (mode & S_IFMT) {
13045+ case S_IFIFO:
13046+#if 0
13047+ case S_IFCHR:
13048+ case S_IFBLK:
13049+ case S_IFSOCK:
13050+#endif
13051+ ret = 1;
13052+ }
13053+
13054+ return ret;
13055+}
7f207e10
AM
13056diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
13057--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 13058+++ linux/fs/aufs/fstype.h 2014-04-24 22:11:10.851935747 +0200
523b37e3 13059@@ -0,0 +1,469 @@
4a4d8108 13060+/*
523b37e3 13061+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
13062+ *
13063+ * This program, aufs is free software; you can redistribute it and/or modify
13064+ * it under the terms of the GNU General Public License as published by
13065+ * the Free Software Foundation; either version 2 of the License, or
13066+ * (at your option) any later version.
13067+ *
13068+ * This program is distributed in the hope that it will be useful,
13069+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13070+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13071+ * GNU General Public License for more details.
13072+ *
13073+ * You should have received a copy of the GNU General Public License
523b37e3 13074+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
13075+ */
13076+
13077+/*
13078+ * judging filesystem type
13079+ */
13080+
13081+#ifndef __AUFS_FSTYPE_H__
13082+#define __AUFS_FSTYPE_H__
13083+
13084+#ifdef __KERNEL__
13085+
13086+#include <linux/fs.h>
13087+#include <linux/magic.h>
13088+#include <linux/romfs_fs.h>
4a4d8108
AM
13089+
13090+static inline int au_test_aufs(struct super_block *sb)
13091+{
13092+ return sb->s_magic == AUFS_SUPER_MAGIC;
13093+}
13094+
13095+static inline const char *au_sbtype(struct super_block *sb)
13096+{
13097+ return sb->s_type->name;
13098+}
1308ab2a 13099+
13100+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
13101+{
13102+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
13103+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
13104+#else
13105+ return 0;
13106+#endif
13107+}
13108+
1308ab2a 13109+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 13110+{
1308ab2a 13111+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
13112+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
13113+#else
13114+ return 0;
13115+#endif
13116+}
13117+
1308ab2a 13118+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 13119+{
1308ab2a 13120+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
13121+ return sb->s_magic == CRAMFS_MAGIC;
13122+#endif
13123+ return 0;
13124+}
13125+
13126+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
13127+{
13128+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
13129+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
13130+#else
13131+ return 0;
13132+#endif
13133+}
13134+
1308ab2a 13135+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 13136+{
1308ab2a 13137+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
13138+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
13139+#else
13140+ return 0;
13141+#endif
13142+}
13143+
1308ab2a 13144+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 13145+{
1308ab2a 13146+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
13147+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
13148+#else
13149+ return 0;
13150+#endif
13151+}
13152+
1308ab2a 13153+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 13154+{
1308ab2a 13155+#ifdef CONFIG_TMPFS
13156+ return sb->s_magic == TMPFS_MAGIC;
13157+#else
13158+ return 0;
dece6358 13159+#endif
dece6358
AM
13160+}
13161+
1308ab2a 13162+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 13163+{
1308ab2a 13164+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
13165+ return !strcmp(au_sbtype(sb), "ecryptfs");
13166+#else
13167+ return 0;
13168+#endif
1facf9fc 13169+}
13170+
1308ab2a 13171+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
1facf9fc 13172+{
1308ab2a 13173+#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
13174+ return sb->s_magic == OCFS2_SUPER_MAGIC;
13175+#else
13176+ return 0;
13177+#endif
1facf9fc 13178+}
13179+
1308ab2a 13180+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
1facf9fc 13181+{
1308ab2a 13182+#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
13183+ return sb->s_magic == DLMFS_MAGIC;
13184+#else
13185+ return 0;
13186+#endif
1facf9fc 13187+}
13188+
1308ab2a 13189+static inline int au_test_coda(struct super_block *sb __maybe_unused)
1facf9fc 13190+{
1308ab2a 13191+#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
13192+ return sb->s_magic == CODA_SUPER_MAGIC;
13193+#else
13194+ return 0;
13195+#endif
13196+}
13197+
13198+static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
13199+{
13200+#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
13201+ return sb->s_magic == V9FS_MAGIC;
13202+#else
13203+ return 0;
13204+#endif
13205+}
13206+
13207+static inline int au_test_ext4(struct super_block *sb __maybe_unused)
13208+{
c2b27bf2 13209+#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE)
1308ab2a 13210+ return sb->s_magic == EXT4_SUPER_MAGIC;
13211+#else
13212+ return 0;
13213+#endif
13214+}
13215+
13216+static inline int au_test_sysv(struct super_block *sb __maybe_unused)
13217+{
13218+#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
13219+ return !strcmp(au_sbtype(sb), "sysv");
13220+#else
13221+ return 0;
13222+#endif
13223+}
13224+
13225+static inline int au_test_ramfs(struct super_block *sb)
13226+{
13227+ return sb->s_magic == RAMFS_MAGIC;
13228+}
13229+
13230+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
13231+{
13232+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
13233+ return sb->s_magic == UBIFS_SUPER_MAGIC;
13234+#else
13235+ return 0;
13236+#endif
13237+}
13238+
13239+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
13240+{
13241+#ifdef CONFIG_PROC_FS
13242+ return sb->s_magic == PROC_SUPER_MAGIC;
13243+#else
13244+ return 0;
13245+#endif
13246+}
13247+
13248+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
13249+{
13250+#ifdef CONFIG_SYSFS
13251+ return sb->s_magic == SYSFS_MAGIC;
13252+#else
13253+ return 0;
13254+#endif
13255+}
13256+
13257+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
13258+{
13259+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
13260+ return sb->s_magic == CONFIGFS_MAGIC;
13261+#else
13262+ return 0;
13263+#endif
13264+}
13265+
13266+static inline int au_test_minix(struct super_block *sb __maybe_unused)
13267+{
13268+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
13269+ return sb->s_magic == MINIX3_SUPER_MAGIC
13270+ || sb->s_magic == MINIX2_SUPER_MAGIC
13271+ || sb->s_magic == MINIX2_SUPER_MAGIC2
13272+ || sb->s_magic == MINIX_SUPER_MAGIC
13273+ || sb->s_magic == MINIX_SUPER_MAGIC2;
13274+#else
13275+ return 0;
13276+#endif
13277+}
13278+
13279+static inline int au_test_cifs(struct super_block *sb __maybe_unused)
13280+{
13281+#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
13282+ return sb->s_magic == CIFS_MAGIC_NUMBER;
13283+#else
13284+ return 0;
13285+#endif
13286+}
13287+
13288+static inline int au_test_fat(struct super_block *sb __maybe_unused)
13289+{
13290+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
13291+ return sb->s_magic == MSDOS_SUPER_MAGIC;
13292+#else
13293+ return 0;
13294+#endif
13295+}
13296+
13297+static inline int au_test_msdos(struct super_block *sb)
13298+{
13299+ return au_test_fat(sb);
13300+}
13301+
13302+static inline int au_test_vfat(struct super_block *sb)
13303+{
13304+ return au_test_fat(sb);
13305+}
13306+
13307+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
13308+{
13309+#ifdef CONFIG_SECURITYFS
13310+ return sb->s_magic == SECURITYFS_MAGIC;
13311+#else
13312+ return 0;
13313+#endif
13314+}
13315+
13316+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
13317+{
13318+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
13319+ return sb->s_magic == SQUASHFS_MAGIC;
13320+#else
13321+ return 0;
13322+#endif
13323+}
13324+
13325+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
13326+{
13327+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
13328+ return sb->s_magic == BTRFS_SUPER_MAGIC;
13329+#else
13330+ return 0;
13331+#endif
13332+}
13333+
13334+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
13335+{
13336+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
13337+ return sb->s_magic == XENFS_SUPER_MAGIC;
13338+#else
13339+ return 0;
13340+#endif
13341+}
13342+
13343+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
13344+{
13345+#ifdef CONFIG_DEBUG_FS
13346+ return sb->s_magic == DEBUGFS_MAGIC;
13347+#else
13348+ return 0;
13349+#endif
13350+}
13351+
13352+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
13353+{
13354+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
13355+ return sb->s_magic == NILFS_SUPER_MAGIC;
13356+#else
13357+ return 0;
13358+#endif
13359+}
13360+
4a4d8108
AM
13361+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
13362+{
13363+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
13364+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
13365+#else
13366+ return 0;
13367+#endif
13368+}
13369+
1308ab2a 13370+/* ---------------------------------------------------------------------- */
13371+/*
13372+ * they can't be an aufs branch.
13373+ */
13374+static inline int au_test_fs_unsuppoted(struct super_block *sb)
13375+{
13376+ return
13377+#ifndef CONFIG_AUFS_BR_RAMFS
13378+ au_test_ramfs(sb) ||
13379+#endif
13380+ au_test_procfs(sb)
13381+ || au_test_sysfs(sb)
13382+ || au_test_configfs(sb)
13383+ || au_test_debugfs(sb)
13384+ || au_test_securityfs(sb)
13385+ || au_test_xenfs(sb)
13386+ || au_test_ecryptfs(sb)
13387+ /* || !strcmp(au_sbtype(sb), "unionfs") */
13388+ || au_test_aufs(sb); /* will be supported in next version */
13389+}
13390+
1308ab2a 13391+static inline int au_test_fs_remote(struct super_block *sb)
13392+{
13393+ return !au_test_tmpfs(sb)
13394+#ifdef CONFIG_AUFS_BR_RAMFS
13395+ && !au_test_ramfs(sb)
13396+#endif
13397+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
13398+}
13399+
13400+/* ---------------------------------------------------------------------- */
13401+
13402+/*
13403+ * Note: these functions (below) are created after reading ->getattr() in all
13404+ * filesystems under linux/fs. it means we have to do so in every update...
13405+ */
13406+
13407+/*
13408+ * some filesystems require getattr to refresh the inode attributes before
13409+ * referencing.
13410+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
13411+ * and leave the work for d_revalidate()
13412+ */
13413+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
13414+{
13415+ return au_test_nfs(sb)
13416+ || au_test_fuse(sb)
1308ab2a 13417+ /* || au_test_ocfs2(sb) */ /* untested */
13418+ /* || au_test_btrfs(sb) */ /* untested */
13419+ /* || au_test_coda(sb) */ /* untested */
13420+ /* || au_test_v9fs(sb) */ /* untested */
13421+ ;
13422+}
13423+
13424+/*
13425+ * filesystems which don't maintain i_size or i_blocks.
13426+ */
13427+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
13428+{
13429+ return au_test_xfs(sb)
4a4d8108
AM
13430+ || au_test_btrfs(sb)
13431+ || au_test_ubifs(sb)
13432+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 13433+ /* || au_test_ext4(sb) */ /* untested */
13434+ /* || au_test_ocfs2(sb) */ /* untested */
13435+ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
13436+ /* || au_test_sysv(sb) */ /* untested */
1308ab2a 13437+ /* || au_test_minix(sb) */ /* untested */
13438+ ;
13439+}
13440+
13441+/*
13442+ * filesystems which don't store the correct value in some of their inode
13443+ * attributes.
13444+ */
13445+static inline int au_test_fs_bad_iattr(struct super_block *sb)
13446+{
13447+ return au_test_fs_bad_iattr_size(sb)
13448+ /* || au_test_cifs(sb) */ /* untested */
13449+ || au_test_fat(sb)
13450+ || au_test_msdos(sb)
13451+ || au_test_vfat(sb);
1facf9fc 13452+}
13453+
13454+/* they don't check i_nlink in link(2) */
13455+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
13456+{
13457+ return au_test_tmpfs(sb)
13458+#ifdef CONFIG_AUFS_BR_RAMFS
13459+ || au_test_ramfs(sb)
13460+#endif
4a4d8108 13461+ || au_test_ubifs(sb)
4a4d8108 13462+ || au_test_hfsplus(sb);
1facf9fc 13463+}
13464+
13465+/*
13466+ * filesystems which sets S_NOATIME and S_NOCMTIME.
13467+ */
13468+static inline int au_test_fs_notime(struct super_block *sb)
13469+{
13470+ return au_test_nfs(sb)
13471+ || au_test_fuse(sb)
dece6358 13472+ || au_test_ubifs(sb)
1facf9fc 13473+ /* || au_test_cifs(sb) */ /* untested */
1facf9fc 13474+ ;
13475+}
13476+
13477+/*
13478+ * filesystems which requires replacing i_mapping.
13479+ */
13480+static inline int au_test_fs_bad_mapping(struct super_block *sb)
13481+{
dece6358
AM
13482+ return au_test_fuse(sb)
13483+ || au_test_ubifs(sb);
1facf9fc 13484+}
13485+
13486+/* temporary support for i#1 in cramfs */
13487+static inline int au_test_fs_unique_ino(struct inode *inode)
13488+{
13489+ if (au_test_cramfs(inode->i_sb))
13490+ return inode->i_ino != 1;
13491+ return 1;
13492+}
13493+
13494+/* ---------------------------------------------------------------------- */
13495+
13496+/*
13497+ * the filesystem where the xino files placed must support i/o after unlink and
13498+ * maintain i_size and i_blocks.
13499+ */
13500+static inline int au_test_fs_bad_xino(struct super_block *sb)
13501+{
13502+ return au_test_fs_remote(sb)
13503+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 13504+ /* don't want unnecessary work for xino */
13505+ || au_test_aufs(sb)
1308ab2a 13506+ || au_test_ecryptfs(sb)
13507+ || au_test_nilfs(sb);
1facf9fc 13508+}
13509+
13510+static inline int au_test_fs_trunc_xino(struct super_block *sb)
13511+{
13512+ return au_test_tmpfs(sb)
13513+ || au_test_ramfs(sb);
13514+}
13515+
13516+/*
13517+ * test if the @sb is real-readonly.
13518+ */
13519+static inline int au_test_fs_rr(struct super_block *sb)
13520+{
13521+ return au_test_squashfs(sb)
13522+ || au_test_iso9660(sb)
13523+ || au_test_cramfs(sb)
13524+ || au_test_romfs(sb);
13525+}
13526+
13527+#endif /* __KERNEL__ */
13528+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
13529diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
13530--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f
JR
13531+++ linux/fs/aufs/hfsnotify.c 2014-04-24 22:11:10.851935747 +0200
13532@@ -0,0 +1,281 @@
1facf9fc 13533+/*
523b37e3 13534+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 13535+ *
13536+ * This program, aufs is free software; you can redistribute it and/or modify
13537+ * it under the terms of the GNU General Public License as published by
13538+ * the Free Software Foundation; either version 2 of the License, or
13539+ * (at your option) any later version.
dece6358
AM
13540+ *
13541+ * This program is distributed in the hope that it will be useful,
13542+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13543+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13544+ * GNU General Public License for more details.
13545+ *
13546+ * You should have received a copy of the GNU General Public License
523b37e3 13547+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 13548+ */
13549+
13550+/*
4a4d8108 13551+ * fsnotify for the lower directories
1facf9fc 13552+ */
13553+
13554+#include "aufs.h"
13555+
4a4d8108
AM
13556+/* FS_IN_IGNORED is unnecessary */
13557+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
13558+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 13559+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 13560+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 13561+
0c5527e5 13562+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 13563+{
0c5527e5
AM
13564+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
13565+ hn_mark);
4a4d8108 13566+ AuDbg("here\n");
7eafdf33
AM
13567+ au_cache_free_hnotify(hn);
13568+ smp_mb__before_atomic_dec();
1716fcea
AM
13569+ if (atomic64_dec_and_test(&au_hfsn_ifree))
13570+ wake_up(&au_hfsn_wq);
4a4d8108 13571+}
1facf9fc 13572+
027c5e7a 13573+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 13574+{
1716fcea 13575+ int err;
027c5e7a
AM
13576+ struct au_hnotify *hn;
13577+ struct super_block *sb;
13578+ struct au_branch *br;
0c5527e5 13579+ struct fsnotify_mark *mark;
027c5e7a 13580+ aufs_bindex_t bindex;
1facf9fc 13581+
027c5e7a
AM
13582+ hn = hinode->hi_notify;
13583+ sb = hn->hn_aufs_inode->i_sb;
13584+ bindex = au_br_index(sb, hinode->hi_id);
13585+ br = au_sbr(sb, bindex);
1716fcea
AM
13586+ AuDebugOn(!br->br_hfsn);
13587+
0c5527e5
AM
13588+ mark = &hn->hn_mark;
13589+ fsnotify_init_mark(mark, au_hfsn_free_mark);
13590+ mark->mask = AuHfsnMask;
7f207e10
AM
13591+ /*
13592+ * by udba rename or rmdir, aufs assign a new inode to the known
13593+ * h_inode, so specify 1 to allow dups.
13594+ */
1716fcea 13595+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 13596+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
13597+ /* even if err */
13598+ fsnotify_put_mark(mark);
13599+
13600+ return err;
1facf9fc 13601+}
13602+
7eafdf33 13603+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 13604+{
0c5527e5 13605+ struct fsnotify_mark *mark;
7eafdf33 13606+ unsigned long long ull;
1716fcea 13607+ struct fsnotify_group *group;
7eafdf33
AM
13608+
13609+ ull = atomic64_inc_return(&au_hfsn_ifree);
13610+ BUG_ON(!ull);
953406b4 13611+
0c5527e5 13612+ mark = &hn->hn_mark;
1716fcea
AM
13613+ spin_lock(&mark->lock);
13614+ group = mark->group;
13615+ fsnotify_get_group(group);
13616+ spin_unlock(&mark->lock);
13617+ fsnotify_destroy_mark(mark, group);
13618+ fsnotify_put_group(group);
7f207e10 13619+
7eafdf33
AM
13620+ /* free hn by myself */
13621+ return 0;
1facf9fc 13622+}
13623+
13624+/* ---------------------------------------------------------------------- */
13625+
4a4d8108 13626+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 13627+{
0c5527e5 13628+ struct fsnotify_mark *mark;
1facf9fc 13629+
0c5527e5
AM
13630+ mark = &hinode->hi_notify->hn_mark;
13631+ spin_lock(&mark->lock);
1facf9fc 13632+ if (do_set) {
0c5527e5
AM
13633+ AuDebugOn(mark->mask & AuHfsnMask);
13634+ mark->mask |= AuHfsnMask;
1facf9fc 13635+ } else {
0c5527e5
AM
13636+ AuDebugOn(!(mark->mask & AuHfsnMask));
13637+ mark->mask &= ~AuHfsnMask;
1facf9fc 13638+ }
0c5527e5 13639+ spin_unlock(&mark->lock);
4a4d8108 13640+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 13641+}
13642+
4a4d8108 13643+/* ---------------------------------------------------------------------- */
1facf9fc 13644+
4a4d8108
AM
13645+/* #define AuDbgHnotify */
13646+#ifdef AuDbgHnotify
13647+static char *au_hfsn_name(u32 mask)
13648+{
13649+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
13650+#define test_ret(flag) \
13651+ do { \
13652+ if (mask & flag) \
13653+ return #flag; \
13654+ } while (0)
4a4d8108
AM
13655+ test_ret(FS_ACCESS);
13656+ test_ret(FS_MODIFY);
13657+ test_ret(FS_ATTRIB);
13658+ test_ret(FS_CLOSE_WRITE);
13659+ test_ret(FS_CLOSE_NOWRITE);
13660+ test_ret(FS_OPEN);
13661+ test_ret(FS_MOVED_FROM);
13662+ test_ret(FS_MOVED_TO);
13663+ test_ret(FS_CREATE);
13664+ test_ret(FS_DELETE);
13665+ test_ret(FS_DELETE_SELF);
13666+ test_ret(FS_MOVE_SELF);
13667+ test_ret(FS_UNMOUNT);
13668+ test_ret(FS_Q_OVERFLOW);
13669+ test_ret(FS_IN_IGNORED);
13670+ test_ret(FS_IN_ISDIR);
13671+ test_ret(FS_IN_ONESHOT);
13672+ test_ret(FS_EVENT_ON_CHILD);
13673+ return "";
13674+#undef test_ret
13675+#else
13676+ return "??";
13677+#endif
1facf9fc 13678+}
4a4d8108 13679+#endif
1facf9fc 13680+
13681+/* ---------------------------------------------------------------------- */
13682+
1716fcea
AM
13683+static void au_hfsn_free_group(struct fsnotify_group *group)
13684+{
13685+ struct au_br_hfsnotify *hfsn = group->private;
13686+
13687+ AuDbg("here\n");
13688+ kfree(hfsn);
13689+}
13690+
4a4d8108 13691+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 13692+ struct inode *inode,
0c5527e5
AM
13693+ struct fsnotify_mark *inode_mark,
13694+ struct fsnotify_mark *vfsmount_mark,
fb47a38f
JR
13695+ u32 mask, void *data, int data_type,
13696+ const unsigned char *file_name, u32 cookie)
1facf9fc 13697+{
13698+ int err;
4a4d8108
AM
13699+ struct au_hnotify *hnotify;
13700+ struct inode *h_dir, *h_inode;
fb47a38f 13701+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
4a4d8108 13702+
fb47a38f 13703+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 13704+
13705+ err = 0;
0c5527e5 13706+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 13707+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 13708+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 13709+ goto out;
1facf9fc 13710+
fb47a38f
JR
13711+ h_dir = inode;
13712+ h_inode = NULL;
4a4d8108 13713+#ifdef AuDbgHnotify
392086de 13714+ au_debug_on();
4a4d8108
AM
13715+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
13716+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
13717+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
13718+ h_dir->i_ino, mask, au_hfsn_name(mask),
13719+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
13720+ /* WARN_ON(1); */
1facf9fc 13721+ }
392086de 13722+ au_debug_off();
1facf9fc 13723+#endif
4a4d8108 13724+
0c5527e5
AM
13725+ AuDebugOn(!inode_mark);
13726+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
13727+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 13728+
4a4d8108
AM
13729+out:
13730+ return err;
13731+}
1facf9fc 13732+
4a4d8108 13733+static struct fsnotify_ops au_hfsn_ops = {
1716fcea
AM
13734+ .handle_event = au_hfsn_handle_event,
13735+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
13736+};
13737+
13738+/* ---------------------------------------------------------------------- */
13739+
027c5e7a
AM
13740+static void au_hfsn_fin_br(struct au_branch *br)
13741+{
1716fcea 13742+ struct au_br_hfsnotify *hfsn;
027c5e7a 13743+
1716fcea
AM
13744+ hfsn = br->br_hfsn;
13745+ if (hfsn)
13746+ fsnotify_put_group(hfsn->hfsn_group);
027c5e7a
AM
13747+}
13748+
1716fcea 13749+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
13750+{
13751+ int err;
1716fcea
AM
13752+ struct fsnotify_group *group;
13753+ struct au_br_hfsnotify *hfsn;
1facf9fc 13754+
4a4d8108 13755+ err = 0;
1716fcea
AM
13756+ br->br_hfsn = NULL;
13757+ if (!au_br_hnotifyable(perm))
027c5e7a 13758+ goto out;
027c5e7a 13759+
1716fcea
AM
13760+ err = -ENOMEM;
13761+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
13762+ if (unlikely(!hfsn))
027c5e7a
AM
13763+ goto out;
13764+
1716fcea
AM
13765+ err = 0;
13766+ group = fsnotify_alloc_group(&au_hfsn_ops);
13767+ if (IS_ERR(group)) {
13768+ err = PTR_ERR(group);
0c5527e5 13769+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 13770+ goto out_hfsn;
4a4d8108 13771+ }
1facf9fc 13772+
1716fcea
AM
13773+ group->private = hfsn;
13774+ hfsn->hfsn_group = group;
13775+ br->br_hfsn = hfsn;
13776+ goto out; /* success */
13777+
13778+out_hfsn:
13779+ kfree(hfsn);
027c5e7a 13780+out:
1716fcea
AM
13781+ return err;
13782+}
13783+
13784+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
13785+{
13786+ int err;
13787+
13788+ err = 0;
13789+ if (!br->br_hfsn)
13790+ err = au_hfsn_init_br(br, perm);
13791+
1facf9fc 13792+ return err;
13793+}
13794+
7eafdf33
AM
13795+/* ---------------------------------------------------------------------- */
13796+
13797+static void au_hfsn_fin(void)
13798+{
13799+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
13800+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
13801+}
13802+
4a4d8108
AM
13803+const struct au_hnotify_op au_hnotify_op = {
13804+ .ctl = au_hfsn_ctl,
13805+ .alloc = au_hfsn_alloc,
13806+ .free = au_hfsn_free,
1facf9fc 13807+
7eafdf33
AM
13808+ .fin = au_hfsn_fin,
13809+
027c5e7a
AM
13810+ .reset_br = au_hfsn_reset_br,
13811+ .fin_br = au_hfsn_fin_br,
13812+ .init_br = au_hfsn_init_br
4a4d8108 13813+};
7f207e10
AM
13814diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
13815--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 13816+++ linux/fs/aufs/hfsplus.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 13817@@ -0,0 +1,56 @@
4a4d8108 13818+/*
523b37e3 13819+ * Copyright (C) 2010-2014 Junjiro R. Okajima
4a4d8108
AM
13820+ *
13821+ * This program, aufs is free software; you can redistribute it and/or modify
13822+ * it under the terms of the GNU General Public License as published by
13823+ * the Free Software Foundation; either version 2 of the License, or
13824+ * (at your option) any later version.
13825+ *
13826+ * This program is distributed in the hope that it will be useful,
13827+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13828+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13829+ * GNU General Public License for more details.
13830+ *
13831+ * You should have received a copy of the GNU General Public License
523b37e3 13832+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 13833+ */
1facf9fc 13834+
4a4d8108
AM
13835+/*
13836+ * special support for filesystems which aqucires an inode mutex
13837+ * at final closing a file, eg, hfsplus.
13838+ *
13839+ * This trick is very simple and stupid, just to open the file before really
13840+ * neceeary open to tell hfsplus that this is not the final closing.
13841+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
13842+ * and au_h_open_post() after releasing it.
13843+ */
1facf9fc 13844+
4a4d8108 13845+#include "aufs.h"
1facf9fc 13846+
392086de
AM
13847+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
13848+ int force_wr)
4a4d8108
AM
13849+{
13850+ struct file *h_file;
13851+ struct dentry *h_dentry;
1facf9fc 13852+
4a4d8108
AM
13853+ h_dentry = au_h_dptr(dentry, bindex);
13854+ AuDebugOn(!h_dentry);
13855+ AuDebugOn(!h_dentry->d_inode);
4a4d8108
AM
13856+
13857+ h_file = NULL;
13858+ if (au_test_hfsplus(h_dentry->d_sb)
13859+ && S_ISREG(h_dentry->d_inode->i_mode))
13860+ h_file = au_h_open(dentry, bindex,
13861+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 13862+ /*file*/NULL, force_wr);
4a4d8108 13863+ return h_file;
1facf9fc 13864+}
13865+
4a4d8108
AM
13866+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
13867+ struct file *h_file)
13868+{
13869+ if (h_file) {
13870+ fput(h_file);
13871+ au_sbr_put(dentry->d_sb, bindex);
13872+ }
13873+}
7f207e10
AM
13874diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
13875--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 13876+++ linux/fs/aufs/hnotify.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 13877@@ -0,0 +1,710 @@
e49829fe 13878+/*
523b37e3 13879+ * Copyright (C) 2005-2014 Junjiro R. Okajima
e49829fe
JR
13880+ *
13881+ * This program, aufs is free software; you can redistribute it and/or modify
13882+ * it under the terms of the GNU General Public License as published by
13883+ * the Free Software Foundation; either version 2 of the License, or
13884+ * (at your option) any later version.
13885+ *
13886+ * This program is distributed in the hope that it will be useful,
13887+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13888+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13889+ * GNU General Public License for more details.
13890+ *
13891+ * You should have received a copy of the GNU General Public License
523b37e3 13892+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
13893+ */
13894+
13895+/*
7f207e10 13896+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
13897+ */
13898+
13899+#include "aufs.h"
13900+
027c5e7a 13901+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
13902+{
13903+ int err;
7f207e10 13904+ struct au_hnotify *hn;
1facf9fc 13905+
4a4d8108
AM
13906+ err = -ENOMEM;
13907+ hn = au_cache_alloc_hnotify();
13908+ if (hn) {
13909+ hn->hn_aufs_inode = inode;
027c5e7a
AM
13910+ hinode->hi_notify = hn;
13911+ err = au_hnotify_op.alloc(hinode);
13912+ AuTraceErr(err);
13913+ if (unlikely(err)) {
13914+ hinode->hi_notify = NULL;
4a4d8108
AM
13915+ au_cache_free_hnotify(hn);
13916+ /*
13917+ * The upper dir was removed by udba, but the same named
13918+ * dir left. In this case, aufs assignes a new inode
13919+ * number and set the monitor again.
13920+ * For the lower dir, the old monitnor is still left.
13921+ */
13922+ if (err == -EEXIST)
13923+ err = 0;
13924+ }
1308ab2a 13925+ }
1308ab2a 13926+
027c5e7a 13927+ AuTraceErr(err);
1308ab2a 13928+ return err;
dece6358 13929+}
1facf9fc 13930+
4a4d8108 13931+void au_hn_free(struct au_hinode *hinode)
dece6358 13932+{
4a4d8108 13933+ struct au_hnotify *hn;
1facf9fc 13934+
4a4d8108
AM
13935+ hn = hinode->hi_notify;
13936+ if (hn) {
4a4d8108 13937+ hinode->hi_notify = NULL;
7eafdf33
AM
13938+ if (au_hnotify_op.free(hinode, hn))
13939+ au_cache_free_hnotify(hn);
4a4d8108
AM
13940+ }
13941+}
dece6358 13942+
4a4d8108 13943+/* ---------------------------------------------------------------------- */
dece6358 13944+
4a4d8108
AM
13945+void au_hn_ctl(struct au_hinode *hinode, int do_set)
13946+{
13947+ if (hinode->hi_notify)
13948+ au_hnotify_op.ctl(hinode, do_set);
13949+}
13950+
13951+void au_hn_reset(struct inode *inode, unsigned int flags)
13952+{
13953+ aufs_bindex_t bindex, bend;
13954+ struct inode *hi;
13955+ struct dentry *iwhdentry;
1facf9fc 13956+
1308ab2a 13957+ bend = au_ibend(inode);
4a4d8108
AM
13958+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
13959+ hi = au_h_iptr(inode, bindex);
13960+ if (!hi)
13961+ continue;
1308ab2a 13962+
4a4d8108
AM
13963+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
13964+ iwhdentry = au_hi_wh(inode, bindex);
13965+ if (iwhdentry)
13966+ dget(iwhdentry);
13967+ au_igrab(hi);
13968+ au_set_h_iptr(inode, bindex, NULL, 0);
13969+ au_set_h_iptr(inode, bindex, au_igrab(hi),
13970+ flags & ~AuHi_XINO);
13971+ iput(hi);
13972+ dput(iwhdentry);
13973+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 13974+ }
1facf9fc 13975+}
13976+
1308ab2a 13977+/* ---------------------------------------------------------------------- */
1facf9fc 13978+
4a4d8108 13979+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 13980+{
4a4d8108
AM
13981+ int err;
13982+ aufs_bindex_t bindex, bend, bfound, bstart;
13983+ struct inode *h_i;
1facf9fc 13984+
4a4d8108
AM
13985+ err = 0;
13986+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 13987+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
13988+ goto out;
13989+ }
1facf9fc 13990+
4a4d8108
AM
13991+ bfound = -1;
13992+ bend = au_ibend(inode);
13993+ bstart = au_ibstart(inode);
13994+#if 0 /* reserved for future use */
13995+ if (bindex == bend) {
13996+ /* keep this ino in rename case */
13997+ goto out;
13998+ }
13999+#endif
14000+ for (bindex = bstart; bindex <= bend; bindex++)
14001+ if (au_h_iptr(inode, bindex) == h_inode) {
14002+ bfound = bindex;
14003+ break;
14004+ }
14005+ if (bfound < 0)
1308ab2a 14006+ goto out;
1facf9fc 14007+
4a4d8108
AM
14008+ for (bindex = bstart; bindex <= bend; bindex++) {
14009+ h_i = au_h_iptr(inode, bindex);
14010+ if (!h_i)
14011+ continue;
1facf9fc 14012+
4a4d8108
AM
14013+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
14014+ /* ignore this error */
14015+ /* bad action? */
1facf9fc 14016+ }
1facf9fc 14017+
4a4d8108 14018+ /* children inode number will be broken */
1facf9fc 14019+
4f0767ce 14020+out:
4a4d8108
AM
14021+ AuTraceErr(err);
14022+ return err;
1facf9fc 14023+}
14024+
4a4d8108 14025+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 14026+{
4a4d8108
AM
14027+ int err, i, j, ndentry;
14028+ struct au_dcsub_pages dpages;
14029+ struct au_dpage *dpage;
14030+ struct dentry **dentries;
1facf9fc 14031+
4a4d8108
AM
14032+ err = au_dpages_init(&dpages, GFP_NOFS);
14033+ if (unlikely(err))
14034+ goto out;
14035+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
14036+ if (unlikely(err))
14037+ goto out_dpages;
1facf9fc 14038+
4a4d8108
AM
14039+ for (i = 0; i < dpages.ndpage; i++) {
14040+ dpage = dpages.dpages + i;
14041+ dentries = dpage->dentries;
14042+ ndentry = dpage->ndentry;
14043+ for (j = 0; j < ndentry; j++) {
14044+ struct dentry *d;
14045+
14046+ d = dentries[j];
14047+ if (IS_ROOT(d))
14048+ continue;
14049+
4a4d8108
AM
14050+ au_digen_dec(d);
14051+ if (d->d_inode)
14052+ /* todo: reset children xino?
14053+ cached children only? */
14054+ au_iigen_dec(d->d_inode);
1308ab2a 14055+ }
dece6358 14056+ }
1facf9fc 14057+
4f0767ce 14058+out_dpages:
4a4d8108 14059+ au_dpages_free(&dpages);
dece6358 14060+
027c5e7a 14061+#if 0
4a4d8108
AM
14062+ /* discard children */
14063+ dentry_unhash(dentry);
14064+ dput(dentry);
027c5e7a 14065+#endif
4f0767ce 14066+out:
dece6358
AM
14067+ return err;
14068+}
14069+
1308ab2a 14070+/*
4a4d8108 14071+ * return 0 if processed.
1308ab2a 14072+ */
4a4d8108
AM
14073+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
14074+ const unsigned int isdir)
dece6358 14075+{
1308ab2a 14076+ int err;
4a4d8108
AM
14077+ struct dentry *d;
14078+ struct qstr *dname;
1facf9fc 14079+
4a4d8108
AM
14080+ err = 1;
14081+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14082+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14083+ err = 0;
14084+ goto out;
14085+ }
dece6358 14086+
4a4d8108
AM
14087+ if (!isdir) {
14088+ AuDebugOn(!name);
14089+ au_iigen_dec(inode);
027c5e7a 14090+ spin_lock(&inode->i_lock);
c06a8ce3 14091+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 14092+ spin_lock(&d->d_lock);
4a4d8108
AM
14093+ dname = &d->d_name;
14094+ if (dname->len != nlen
027c5e7a
AM
14095+ && memcmp(dname->name, name, nlen)) {
14096+ spin_unlock(&d->d_lock);
4a4d8108 14097+ continue;
027c5e7a 14098+ }
4a4d8108 14099+ err = 0;
4a4d8108
AM
14100+ au_digen_dec(d);
14101+ spin_unlock(&d->d_lock);
14102+ break;
1facf9fc 14103+ }
027c5e7a 14104+ spin_unlock(&inode->i_lock);
1308ab2a 14105+ } else {
027c5e7a 14106+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
14107+ d = d_find_alias(inode);
14108+ if (!d) {
14109+ au_iigen_dec(inode);
14110+ goto out;
14111+ }
1facf9fc 14112+
027c5e7a 14113+ spin_lock(&d->d_lock);
4a4d8108 14114+ dname = &d->d_name;
027c5e7a
AM
14115+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
14116+ spin_unlock(&d->d_lock);
4a4d8108 14117+ err = hn_gen_tree(d);
027c5e7a
AM
14118+ spin_lock(&d->d_lock);
14119+ }
14120+ spin_unlock(&d->d_lock);
4a4d8108
AM
14121+ dput(d);
14122+ }
1facf9fc 14123+
4f0767ce 14124+out:
4a4d8108 14125+ AuTraceErr(err);
1308ab2a 14126+ return err;
14127+}
dece6358 14128+
4a4d8108 14129+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 14130+{
4a4d8108
AM
14131+ int err;
14132+ struct inode *inode;
1facf9fc 14133+
4a4d8108
AM
14134+ inode = dentry->d_inode;
14135+ if (IS_ROOT(dentry)
14136+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
14137+ ) {
0c3ec466 14138+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14139+ return 0;
14140+ }
1308ab2a 14141+
4a4d8108
AM
14142+ err = 0;
14143+ if (!isdir) {
4a4d8108
AM
14144+ au_digen_dec(dentry);
14145+ if (inode)
14146+ au_iigen_dec(inode);
14147+ } else {
027c5e7a 14148+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
14149+ if (inode)
14150+ err = hn_gen_tree(dentry);
14151+ }
14152+
14153+ AuTraceErr(err);
14154+ return err;
1facf9fc 14155+}
14156+
4a4d8108 14157+/* ---------------------------------------------------------------------- */
1facf9fc 14158+
4a4d8108
AM
14159+/* hnotify job flags */
14160+#define AuHnJob_XINO0 1
14161+#define AuHnJob_GEN (1 << 1)
14162+#define AuHnJob_DIRENT (1 << 2)
14163+#define AuHnJob_ISDIR (1 << 3)
14164+#define AuHnJob_TRYXINO0 (1 << 4)
14165+#define AuHnJob_MNTPNT (1 << 5)
14166+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
14167+#define au_fset_hnjob(flags, name) \
14168+ do { (flags) |= AuHnJob_##name; } while (0)
14169+#define au_fclr_hnjob(flags, name) \
14170+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 14171+
4a4d8108
AM
14172+enum {
14173+ AuHn_CHILD,
14174+ AuHn_PARENT,
14175+ AuHnLast
14176+};
1facf9fc 14177+
4a4d8108
AM
14178+struct au_hnotify_args {
14179+ struct inode *h_dir, *dir, *h_child_inode;
14180+ u32 mask;
14181+ unsigned int flags[AuHnLast];
14182+ unsigned int h_child_nlen;
14183+ char h_child_name[];
14184+};
1facf9fc 14185+
4a4d8108
AM
14186+struct hn_job_args {
14187+ unsigned int flags;
14188+ struct inode *inode, *h_inode, *dir, *h_dir;
14189+ struct dentry *dentry;
14190+ char *h_name;
14191+ int h_nlen;
14192+};
1308ab2a 14193+
4a4d8108
AM
14194+static int hn_job(struct hn_job_args *a)
14195+{
14196+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
1308ab2a 14197+
4a4d8108
AM
14198+ /* reset xino */
14199+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
14200+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 14201+
4a4d8108
AM
14202+ if (au_ftest_hnjob(a->flags, TRYXINO0)
14203+ && a->inode
14204+ && a->h_inode) {
14205+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
14206+ if (!a->h_inode->i_nlink)
14207+ hn_xino(a->inode, a->h_inode); /* ignore this error */
14208+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 14209+ }
1facf9fc 14210+
4a4d8108
AM
14211+ /* make the generation obsolete */
14212+ if (au_ftest_hnjob(a->flags, GEN)) {
14213+ int err = -1;
14214+ if (a->inode)
14215+ err = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
14216+ isdir);
14217+ if (err && a->dentry)
14218+ hn_gen_by_name(a->dentry, isdir);
14219+ /* ignore this error */
1facf9fc 14220+ }
1facf9fc 14221+
4a4d8108
AM
14222+ /* make dir entries obsolete */
14223+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
14224+ struct au_vdir *vdir;
1facf9fc 14225+
4a4d8108
AM
14226+ vdir = au_ivdir(a->inode);
14227+ if (vdir)
14228+ vdir->vd_jiffy = 0;
14229+ /* IMustLock(a->inode); */
14230+ /* a->inode->i_version++; */
14231+ }
1facf9fc 14232+
4a4d8108
AM
14233+ /* can do nothing but warn */
14234+ if (au_ftest_hnjob(a->flags, MNTPNT)
14235+ && a->dentry
14236+ && d_mountpoint(a->dentry))
523b37e3 14237+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 14238+
4a4d8108 14239+ return 0;
1308ab2a 14240+}
1facf9fc 14241+
1308ab2a 14242+/* ---------------------------------------------------------------------- */
1facf9fc 14243+
4a4d8108
AM
14244+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
14245+ struct inode *dir)
1308ab2a 14246+{
4a4d8108
AM
14247+ struct dentry *dentry, *d, *parent;
14248+ struct qstr *dname;
1308ab2a 14249+
4a4d8108
AM
14250+ parent = d_find_alias(dir);
14251+ if (!parent)
14252+ return NULL;
1308ab2a 14253+
4a4d8108 14254+ dentry = NULL;
027c5e7a 14255+ spin_lock(&parent->d_lock);
4a4d8108 14256+ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
523b37e3 14257+ /* AuDbg("%pd\n", d); */
027c5e7a 14258+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
14259+ dname = &d->d_name;
14260+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
14261+ goto cont_unlock;
14262+ if (au_di(d))
14263+ au_digen_dec(d);
14264+ else
14265+ goto cont_unlock;
392086de 14266+ if (d_count(d)) {
027c5e7a 14267+ dentry = dget_dlock(d);
4a4d8108 14268+ spin_unlock(&d->d_lock);
027c5e7a 14269+ break;
dece6358 14270+ }
1facf9fc 14271+
f6b6e03d 14272+cont_unlock:
027c5e7a 14273+ spin_unlock(&d->d_lock);
1308ab2a 14274+ }
027c5e7a 14275+ spin_unlock(&parent->d_lock);
4a4d8108 14276+ dput(parent);
1facf9fc 14277+
4a4d8108
AM
14278+ if (dentry)
14279+ di_write_lock_child(dentry);
1308ab2a 14280+
4a4d8108
AM
14281+ return dentry;
14282+}
dece6358 14283+
4a4d8108
AM
14284+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
14285+ aufs_bindex_t bindex, ino_t h_ino)
14286+{
14287+ struct inode *inode;
14288+ ino_t ino;
14289+ int err;
14290+
14291+ inode = NULL;
14292+ err = au_xino_read(sb, bindex, h_ino, &ino);
14293+ if (!err && ino)
14294+ inode = ilookup(sb, ino);
14295+ if (!inode)
14296+ goto out;
14297+
14298+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14299+ pr_warn("wrong root branch\n");
4a4d8108
AM
14300+ iput(inode);
14301+ inode = NULL;
14302+ goto out;
1308ab2a 14303+ }
14304+
4a4d8108 14305+ ii_write_lock_child(inode);
1308ab2a 14306+
4f0767ce 14307+out:
4a4d8108 14308+ return inode;
dece6358
AM
14309+}
14310+
4a4d8108 14311+static void au_hn_bh(void *_args)
1facf9fc 14312+{
4a4d8108
AM
14313+ struct au_hnotify_args *a = _args;
14314+ struct super_block *sb;
14315+ aufs_bindex_t bindex, bend, bfound;
14316+ unsigned char xino, try_iput;
1facf9fc 14317+ int err;
1308ab2a 14318+ struct inode *inode;
4a4d8108
AM
14319+ ino_t h_ino;
14320+ struct hn_job_args args;
14321+ struct dentry *dentry;
14322+ struct au_sbinfo *sbinfo;
1facf9fc 14323+
4a4d8108
AM
14324+ AuDebugOn(!_args);
14325+ AuDebugOn(!a->h_dir);
14326+ AuDebugOn(!a->dir);
14327+ AuDebugOn(!a->mask);
14328+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
14329+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
14330+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 14331+
4a4d8108
AM
14332+ inode = NULL;
14333+ dentry = NULL;
14334+ /*
14335+ * do not lock a->dir->i_mutex here
14336+ * because of d_revalidate() may cause a deadlock.
14337+ */
14338+ sb = a->dir->i_sb;
14339+ AuDebugOn(!sb);
14340+ sbinfo = au_sbi(sb);
14341+ AuDebugOn(!sbinfo);
7f207e10 14342+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 14343+
4a4d8108
AM
14344+ ii_read_lock_parent(a->dir);
14345+ bfound = -1;
14346+ bend = au_ibend(a->dir);
14347+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
14348+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
14349+ bfound = bindex;
14350+ break;
14351+ }
14352+ ii_read_unlock(a->dir);
14353+ if (unlikely(bfound < 0))
14354+ goto out;
1facf9fc 14355+
4a4d8108
AM
14356+ xino = !!au_opt_test(au_mntflags(sb), XINO);
14357+ h_ino = 0;
14358+ if (a->h_child_inode)
14359+ h_ino = a->h_child_inode->i_ino;
1facf9fc 14360+
4a4d8108
AM
14361+ if (a->h_child_nlen
14362+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
14363+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
14364+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
14365+ a->dir);
14366+ try_iput = 0;
14367+ if (dentry)
14368+ inode = dentry->d_inode;
14369+ if (xino && !inode && h_ino
14370+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
14371+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
14372+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
14373+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
14374+ try_iput = 1;
14375+ }
1facf9fc 14376+
4a4d8108
AM
14377+ args.flags = a->flags[AuHn_CHILD];
14378+ args.dentry = dentry;
14379+ args.inode = inode;
14380+ args.h_inode = a->h_child_inode;
14381+ args.dir = a->dir;
14382+ args.h_dir = a->h_dir;
14383+ args.h_name = a->h_child_name;
14384+ args.h_nlen = a->h_child_nlen;
14385+ err = hn_job(&args);
14386+ if (dentry) {
027c5e7a 14387+ if (au_di(dentry))
4a4d8108
AM
14388+ di_write_unlock(dentry);
14389+ dput(dentry);
14390+ }
14391+ if (inode && try_iput) {
14392+ ii_write_unlock(inode);
14393+ iput(inode);
14394+ }
1facf9fc 14395+
4a4d8108
AM
14396+ ii_write_lock_parent(a->dir);
14397+ args.flags = a->flags[AuHn_PARENT];
14398+ args.dentry = NULL;
14399+ args.inode = a->dir;
14400+ args.h_inode = a->h_dir;
14401+ args.dir = NULL;
14402+ args.h_dir = NULL;
14403+ args.h_name = NULL;
14404+ args.h_nlen = 0;
14405+ err = hn_job(&args);
14406+ ii_write_unlock(a->dir);
1facf9fc 14407+
4f0767ce 14408+out:
4a4d8108
AM
14409+ iput(a->h_child_inode);
14410+ iput(a->h_dir);
14411+ iput(a->dir);
027c5e7a
AM
14412+ si_write_unlock(sb);
14413+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 14414+ kfree(a);
dece6358 14415+}
1facf9fc 14416+
4a4d8108
AM
14417+/* ---------------------------------------------------------------------- */
14418+
14419+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
14420+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 14421+{
4a4d8108 14422+ int err, len;
53392da6 14423+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
14424+ unsigned char isdir, isroot, wh;
14425+ struct inode *dir;
14426+ struct au_hnotify_args *args;
14427+ char *p, *h_child_name;
dece6358 14428+
1308ab2a 14429+ err = 0;
4a4d8108
AM
14430+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
14431+ dir = igrab(hnotify->hn_aufs_inode);
14432+ if (!dir)
14433+ goto out;
1facf9fc 14434+
4a4d8108
AM
14435+ isroot = (dir->i_ino == AUFS_ROOT_INO);
14436+ wh = 0;
14437+ h_child_name = (void *)h_child_qstr->name;
14438+ len = h_child_qstr->len;
14439+ if (h_child_name) {
14440+ if (len > AUFS_WH_PFX_LEN
14441+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
14442+ h_child_name += AUFS_WH_PFX_LEN;
14443+ len -= AUFS_WH_PFX_LEN;
14444+ wh = 1;
14445+ }
1facf9fc 14446+ }
dece6358 14447+
4a4d8108
AM
14448+ isdir = 0;
14449+ if (h_child_inode)
14450+ isdir = !!S_ISDIR(h_child_inode->i_mode);
14451+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
14452+ flags[AuHn_CHILD] = 0;
14453+ if (isdir)
14454+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
14455+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
14456+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
14457+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
14458+ case FS_MOVED_FROM:
14459+ case FS_MOVED_TO:
14460+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
14461+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
14462+ /*FALLTHROUGH*/
14463+ case FS_CREATE:
fb47a38f 14464+ AuDebugOn(!h_child_name);
4a4d8108 14465+ break;
1facf9fc 14466+
4a4d8108
AM
14467+ case FS_DELETE:
14468+ /*
14469+ * aufs never be able to get this child inode.
14470+ * revalidation should be in d_revalidate()
14471+ * by checking i_nlink, i_generation or d_unhashed().
14472+ */
14473+ AuDebugOn(!h_child_name);
14474+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
14475+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
14476+ break;
dece6358 14477+
4a4d8108
AM
14478+ default:
14479+ AuDebugOn(1);
14480+ }
1308ab2a 14481+
4a4d8108
AM
14482+ if (wh)
14483+ h_child_inode = NULL;
1308ab2a 14484+
4a4d8108
AM
14485+ err = -ENOMEM;
14486+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 14487+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
14488+ if (unlikely(!args)) {
14489+ AuErr1("no memory\n");
14490+ iput(dir);
14491+ goto out;
14492+ }
14493+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
14494+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
14495+ args->mask = mask;
14496+ args->dir = dir;
14497+ args->h_dir = igrab(h_dir);
14498+ if (h_child_inode)
14499+ h_child_inode = igrab(h_child_inode); /* can be NULL */
14500+ args->h_child_inode = h_child_inode;
14501+ args->h_child_nlen = len;
14502+ if (len) {
14503+ p = (void *)args;
14504+ p += sizeof(*args);
14505+ memcpy(p, h_child_name, len);
14506+ p[len] = 0;
1308ab2a 14507+ }
1308ab2a 14508+
53392da6
AM
14509+ f = 0;
14510+ if (!dir->i_nlink)
14511+ f = AuWkq_NEST;
14512+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
14513+ if (unlikely(err)) {
14514+ pr_err("wkq %d\n", err);
14515+ iput(args->h_child_inode);
14516+ iput(args->h_dir);
14517+ iput(args->dir);
14518+ kfree(args);
1facf9fc 14519+ }
1facf9fc 14520+
4a4d8108 14521+out:
1facf9fc 14522+ return err;
14523+}
14524+
027c5e7a
AM
14525+/* ---------------------------------------------------------------------- */
14526+
14527+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
14528+{
14529+ int err;
14530+
14531+ AuDebugOn(!(udba & AuOptMask_UDBA));
14532+
14533+ err = 0;
14534+ if (au_hnotify_op.reset_br)
14535+ err = au_hnotify_op.reset_br(udba, br, perm);
14536+
14537+ return err;
14538+}
14539+
14540+int au_hnotify_init_br(struct au_branch *br, int perm)
14541+{
14542+ int err;
14543+
14544+ err = 0;
14545+ if (au_hnotify_op.init_br)
14546+ err = au_hnotify_op.init_br(br, perm);
14547+
14548+ return err;
14549+}
14550+
14551+void au_hnotify_fin_br(struct au_branch *br)
14552+{
14553+ if (au_hnotify_op.fin_br)
14554+ au_hnotify_op.fin_br(br);
14555+}
14556+
4a4d8108
AM
14557+static void au_hn_destroy_cache(void)
14558+{
14559+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
14560+ au_cachep[AuCache_HNOTIFY] = NULL;
14561+}
1308ab2a 14562+
4a4d8108 14563+int __init au_hnotify_init(void)
1facf9fc 14564+{
1308ab2a 14565+ int err;
1308ab2a 14566+
4a4d8108
AM
14567+ err = -ENOMEM;
14568+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
14569+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
14570+ err = 0;
14571+ if (au_hnotify_op.init)
14572+ err = au_hnotify_op.init();
4a4d8108
AM
14573+ if (unlikely(err))
14574+ au_hn_destroy_cache();
1308ab2a 14575+ }
1308ab2a 14576+ AuTraceErr(err);
4a4d8108 14577+ return err;
1308ab2a 14578+}
14579+
4a4d8108 14580+void au_hnotify_fin(void)
1308ab2a 14581+{
027c5e7a
AM
14582+ if (au_hnotify_op.fin)
14583+ au_hnotify_op.fin();
4a4d8108
AM
14584+ /* cf. au_cache_fin() */
14585+ if (au_cachep[AuCache_HNOTIFY])
14586+ au_hn_destroy_cache();
dece6358 14587+}
7f207e10
AM
14588diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
14589--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 14590+++ linux/fs/aufs/iinfo.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 14591@@ -0,0 +1,275 @@
dece6358 14592+/*
523b37e3 14593+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
14594+ *
14595+ * This program, aufs is free software; you can redistribute it and/or modify
14596+ * it under the terms of the GNU General Public License as published by
14597+ * the Free Software Foundation; either version 2 of the License, or
14598+ * (at your option) any later version.
14599+ *
14600+ * This program is distributed in the hope that it will be useful,
14601+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14602+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14603+ * GNU General Public License for more details.
14604+ *
14605+ * You should have received a copy of the GNU General Public License
523b37e3 14606+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 14607+ */
1facf9fc 14608+
dece6358 14609+/*
4a4d8108 14610+ * inode private data
dece6358 14611+ */
1facf9fc 14612+
1308ab2a 14613+#include "aufs.h"
1facf9fc 14614+
4a4d8108 14615+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 14616+{
4a4d8108 14617+ struct inode *h_inode;
1facf9fc 14618+
4a4d8108 14619+ IiMustAnyLock(inode);
1facf9fc 14620+
4a4d8108
AM
14621+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
14622+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14623+ return h_inode;
14624+}
1facf9fc 14625+
4a4d8108
AM
14626+/* todo: hard/soft set? */
14627+void au_hiput(struct au_hinode *hinode)
14628+{
14629+ au_hn_free(hinode);
14630+ dput(hinode->hi_whdentry);
14631+ iput(hinode->hi_inode);
14632+}
1facf9fc 14633+
4a4d8108
AM
14634+unsigned int au_hi_flags(struct inode *inode, int isdir)
14635+{
14636+ unsigned int flags;
14637+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 14638+
4a4d8108
AM
14639+ flags = 0;
14640+ if (au_opt_test(mnt_flags, XINO))
14641+ au_fset_hi(flags, XINO);
14642+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
14643+ au_fset_hi(flags, HNOTIFY);
14644+ return flags;
1facf9fc 14645+}
14646+
4a4d8108
AM
14647+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
14648+ struct inode *h_inode, unsigned int flags)
1308ab2a 14649+{
4a4d8108
AM
14650+ struct au_hinode *hinode;
14651+ struct inode *hi;
14652+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 14653+
4a4d8108 14654+ IiMustWriteLock(inode);
dece6358 14655+
4a4d8108
AM
14656+ hinode = iinfo->ii_hinode + bindex;
14657+ hi = hinode->hi_inode;
14658+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
14659+
14660+ if (hi)
14661+ au_hiput(hinode);
14662+ hinode->hi_inode = h_inode;
14663+ if (h_inode) {
14664+ int err;
14665+ struct super_block *sb = inode->i_sb;
14666+ struct au_branch *br;
14667+
027c5e7a
AM
14668+ AuDebugOn(inode->i_mode
14669+ && (h_inode->i_mode & S_IFMT)
14670+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
14671+ if (bindex == iinfo->ii_bstart)
14672+ au_cpup_igen(inode, h_inode);
14673+ br = au_sbr(sb, bindex);
14674+ hinode->hi_id = br->br_id;
14675+ if (au_ftest_hi(flags, XINO)) {
14676+ err = au_xino_write(sb, bindex, h_inode->i_ino,
14677+ inode->i_ino);
14678+ if (unlikely(err))
14679+ AuIOErr1("failed au_xino_write() %d\n", err);
14680+ }
14681+
14682+ if (au_ftest_hi(flags, HNOTIFY)
14683+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 14684+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
14685+ if (unlikely(err))
14686+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 14687+ }
14688+ }
4a4d8108 14689+}
dece6358 14690+
4a4d8108
AM
14691+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
14692+ struct dentry *h_wh)
14693+{
14694+ struct au_hinode *hinode;
dece6358 14695+
4a4d8108
AM
14696+ IiMustWriteLock(inode);
14697+
14698+ hinode = au_ii(inode)->ii_hinode + bindex;
14699+ AuDebugOn(hinode->hi_whdentry);
14700+ hinode->hi_whdentry = h_wh;
1facf9fc 14701+}
14702+
537831f9 14703+void au_update_iigen(struct inode *inode, int half)
1308ab2a 14704+{
537831f9
AM
14705+ struct au_iinfo *iinfo;
14706+ struct au_iigen *iigen;
14707+ unsigned int sigen;
14708+
14709+ sigen = au_sigen(inode->i_sb);
14710+ iinfo = au_ii(inode);
14711+ iigen = &iinfo->ii_generation;
14712+ spin_lock(&iinfo->ii_genspin);
14713+ iigen->ig_generation = sigen;
14714+ if (half)
14715+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
14716+ else
14717+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
14718+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 14719+}
1facf9fc 14720+
4a4d8108
AM
14721+/* it may be called at remount time, too */
14722+void au_update_ibrange(struct inode *inode, int do_put_zero)
14723+{
14724+ struct au_iinfo *iinfo;
027c5e7a 14725+ aufs_bindex_t bindex, bend;
1facf9fc 14726+
4a4d8108 14727+ iinfo = au_ii(inode);
027c5e7a 14728+ if (!iinfo)
4a4d8108 14729+ return;
1facf9fc 14730+
4a4d8108 14731+ IiMustWriteLock(inode);
1facf9fc 14732+
027c5e7a 14733+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
14734+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14735+ bindex++) {
14736+ struct inode *h_i;
1facf9fc 14737+
4a4d8108 14738+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
027c5e7a
AM
14739+ if (h_i && !h_i->i_nlink)
14740+ au_set_h_iptr(inode, bindex, NULL, 0);
14741+ }
4a4d8108
AM
14742+ }
14743+
027c5e7a
AM
14744+ iinfo->ii_bstart = -1;
14745+ iinfo->ii_bend = -1;
14746+ bend = au_sbend(inode->i_sb);
14747+ for (bindex = 0; bindex <= bend; bindex++)
14748+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14749+ iinfo->ii_bstart = bindex;
4a4d8108 14750+ break;
027c5e7a
AM
14751+ }
14752+ if (iinfo->ii_bstart >= 0)
14753+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
14754+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
14755+ iinfo->ii_bend = bindex;
14756+ break;
14757+ }
14758+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 14759+}
1facf9fc 14760+
dece6358 14761+/* ---------------------------------------------------------------------- */
1facf9fc 14762+
4a4d8108 14763+void au_icntnr_init_once(void *_c)
dece6358 14764+{
4a4d8108
AM
14765+ struct au_icntnr *c = _c;
14766+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 14767+ static struct lock_class_key aufs_ii;
1facf9fc 14768+
537831f9 14769+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 14770+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 14771+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
14772+ inode_init_once(&c->vfs_inode);
14773+}
1facf9fc 14774+
4a4d8108
AM
14775+int au_iinfo_init(struct inode *inode)
14776+{
14777+ struct au_iinfo *iinfo;
14778+ struct super_block *sb;
14779+ int nbr, i;
1facf9fc 14780+
4a4d8108
AM
14781+ sb = inode->i_sb;
14782+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
14783+ nbr = au_sbend(sb) + 1;
14784+ if (unlikely(nbr <= 0))
14785+ nbr = 1;
14786+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
14787+ if (iinfo->ii_hinode) {
7f207e10 14788+ au_ninodes_inc(sb);
4a4d8108
AM
14789+ for (i = 0; i < nbr; i++)
14790+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 14791+
537831f9 14792+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
14793+ iinfo->ii_bstart = -1;
14794+ iinfo->ii_bend = -1;
14795+ iinfo->ii_vdir = NULL;
14796+ return 0;
1308ab2a 14797+ }
4a4d8108
AM
14798+ return -ENOMEM;
14799+}
1facf9fc 14800+
4a4d8108
AM
14801+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
14802+{
14803+ int err, sz;
14804+ struct au_hinode *hip;
1facf9fc 14805+
4a4d8108
AM
14806+ AuRwMustWriteLock(&iinfo->ii_rwsem);
14807+
14808+ err = -ENOMEM;
14809+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
14810+ if (!sz)
14811+ sz = sizeof(*hip);
14812+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
14813+ if (hip) {
14814+ iinfo->ii_hinode = hip;
14815+ err = 0;
1308ab2a 14816+ }
4a4d8108 14817+
1308ab2a 14818+ return err;
1facf9fc 14819+}
14820+
4a4d8108 14821+void au_iinfo_fin(struct inode *inode)
1facf9fc 14822+{
4a4d8108
AM
14823+ struct au_iinfo *iinfo;
14824+ struct au_hinode *hi;
14825+ struct super_block *sb;
b752ccd1
AM
14826+ aufs_bindex_t bindex, bend;
14827+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 14828+
4a4d8108
AM
14829+ iinfo = au_ii(inode);
14830+ /* bad_inode case */
14831+ if (!iinfo)
14832+ return;
1308ab2a 14833+
b752ccd1 14834+ sb = inode->i_sb;
7f207e10 14835+ au_ninodes_dec(sb);
b752ccd1
AM
14836+ if (si_pid_test(sb))
14837+ au_xino_delete_inode(inode, unlinked);
14838+ else {
14839+ /*
14840+ * it is safe to hide the dependency between sbinfo and
14841+ * sb->s_umount.
14842+ */
14843+ lockdep_off();
14844+ si_noflush_read_lock(sb);
14845+ au_xino_delete_inode(inode, unlinked);
14846+ si_read_unlock(sb);
14847+ lockdep_on();
14848+ }
14849+
4a4d8108
AM
14850+ if (iinfo->ii_vdir)
14851+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 14852+
b752ccd1
AM
14853+ bindex = iinfo->ii_bstart;
14854+ if (bindex >= 0) {
14855+ hi = iinfo->ii_hinode + bindex;
4a4d8108 14856+ bend = iinfo->ii_bend;
b752ccd1
AM
14857+ while (bindex++ <= bend) {
14858+ if (hi->hi_inode)
4a4d8108 14859+ au_hiput(hi);
4a4d8108
AM
14860+ hi++;
14861+ }
14862+ }
4a4d8108 14863+ kfree(iinfo->ii_hinode);
027c5e7a 14864+ iinfo->ii_hinode = NULL;
4a4d8108 14865+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 14866+}
7f207e10
AM
14867diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
14868--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 14869+++ linux/fs/aufs/inode.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 14870@@ -0,0 +1,491 @@
4a4d8108 14871+/*
523b37e3 14872+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
14873+ *
14874+ * This program, aufs is free software; you can redistribute it and/or modify
14875+ * it under the terms of the GNU General Public License as published by
14876+ * the Free Software Foundation; either version 2 of the License, or
14877+ * (at your option) any later version.
14878+ *
14879+ * This program is distributed in the hope that it will be useful,
14880+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14881+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14882+ * GNU General Public License for more details.
14883+ *
14884+ * You should have received a copy of the GNU General Public License
523b37e3 14885+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 14886+ */
1facf9fc 14887+
4a4d8108
AM
14888+/*
14889+ * inode functions
14890+ */
1facf9fc 14891+
4a4d8108 14892+#include "aufs.h"
1308ab2a 14893+
4a4d8108
AM
14894+struct inode *au_igrab(struct inode *inode)
14895+{
14896+ if (inode) {
14897+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 14898+ ihold(inode);
1facf9fc 14899+ }
4a4d8108
AM
14900+ return inode;
14901+}
1facf9fc 14902+
4a4d8108
AM
14903+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
14904+{
14905+ au_cpup_attr_all(inode, /*force*/0);
537831f9 14906+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
14907+ if (do_version)
14908+ inode->i_version++;
dece6358 14909+}
1facf9fc 14910+
027c5e7a 14911+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 14912+{
4a4d8108 14913+ int err, e;
027c5e7a 14914+ umode_t type;
4a4d8108 14915+ aufs_bindex_t bindex, new_bindex;
1308ab2a 14916+ struct super_block *sb;
4a4d8108 14917+ struct au_iinfo *iinfo;
027c5e7a 14918+ struct au_hinode *p, *q, tmp;
1facf9fc 14919+
4a4d8108 14920+ IiMustWriteLock(inode);
1facf9fc 14921+
027c5e7a 14922+ *update = 0;
4a4d8108 14923+ sb = inode->i_sb;
027c5e7a 14924+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
14925+ iinfo = au_ii(inode);
14926+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
14927+ if (unlikely(err))
1308ab2a 14928+ goto out;
1facf9fc 14929+
027c5e7a 14930+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 14931+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
14932+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
14933+ bindex++, p++) {
14934+ if (!p->hi_inode)
14935+ continue;
1facf9fc 14936+
027c5e7a 14937+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
14938+ new_bindex = au_br_index(sb, p->hi_id);
14939+ if (new_bindex == bindex)
14940+ continue;
1facf9fc 14941+
4a4d8108 14942+ if (new_bindex < 0) {
027c5e7a 14943+ *update = 1;
4a4d8108
AM
14944+ au_hiput(p);
14945+ p->hi_inode = NULL;
14946+ continue;
1308ab2a 14947+ }
4a4d8108
AM
14948+
14949+ if (new_bindex < iinfo->ii_bstart)
14950+ iinfo->ii_bstart = new_bindex;
14951+ if (iinfo->ii_bend < new_bindex)
14952+ iinfo->ii_bend = new_bindex;
14953+ /* swap two lower inode, and loop again */
14954+ q = iinfo->ii_hinode + new_bindex;
14955+ tmp = *q;
14956+ *q = *p;
14957+ *p = tmp;
14958+ if (tmp.hi_inode) {
14959+ bindex--;
14960+ p--;
1308ab2a 14961+ }
14962+ }
4a4d8108
AM
14963+ au_update_ibrange(inode, /*do_put_zero*/0);
14964+ e = au_dy_irefresh(inode);
14965+ if (unlikely(e && !err))
14966+ err = e;
1facf9fc 14967+
4f0767ce 14968+out:
027c5e7a
AM
14969+ AuTraceErr(err);
14970+ return err;
14971+}
14972+
14973+int au_refresh_hinode_self(struct inode *inode)
14974+{
14975+ int err, update;
14976+
14977+ err = au_ii_refresh(inode, &update);
14978+ if (!err)
14979+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
14980+
14981+ AuTraceErr(err);
4a4d8108
AM
14982+ return err;
14983+}
1facf9fc 14984+
4a4d8108
AM
14985+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
14986+{
027c5e7a 14987+ int err, e, update;
4a4d8108 14988+ unsigned int flags;
027c5e7a 14989+ umode_t mode;
4a4d8108 14990+ aufs_bindex_t bindex, bend;
027c5e7a 14991+ unsigned char isdir;
4a4d8108
AM
14992+ struct au_hinode *p;
14993+ struct au_iinfo *iinfo;
1facf9fc 14994+
027c5e7a 14995+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
14996+ if (unlikely(err))
14997+ goto out;
14998+
14999+ update = 0;
15000+ iinfo = au_ii(inode);
15001+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
15002+ mode = (inode->i_mode & S_IFMT);
15003+ isdir = S_ISDIR(mode);
4a4d8108
AM
15004+ flags = au_hi_flags(inode, isdir);
15005+ bend = au_dbend(dentry);
15006+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
15007+ struct inode *h_i;
15008+ struct dentry *h_d;
15009+
15010+ h_d = au_h_dptr(dentry, bindex);
15011+ if (!h_d || !h_d->d_inode)
15012+ continue;
15013+
027c5e7a 15014+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
15015+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
15016+ h_i = au_h_iptr(inode, bindex);
15017+ if (h_i) {
15018+ if (h_i == h_d->d_inode)
15019+ continue;
15020+ err = -EIO;
15021+ break;
15022+ }
15023+ }
15024+ if (bindex < iinfo->ii_bstart)
15025+ iinfo->ii_bstart = bindex;
15026+ if (iinfo->ii_bend < bindex)
15027+ iinfo->ii_bend = bindex;
15028+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
15029+ update = 1;
1308ab2a 15030+ }
4a4d8108
AM
15031+ au_update_ibrange(inode, /*do_put_zero*/0);
15032+ e = au_dy_irefresh(inode);
15033+ if (unlikely(e && !err))
15034+ err = e;
027c5e7a
AM
15035+ if (!err)
15036+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 15037+
4f0767ce 15038+out:
4a4d8108 15039+ AuTraceErr(err);
1308ab2a 15040+ return err;
dece6358
AM
15041+}
15042+
4a4d8108 15043+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 15044+{
4a4d8108
AM
15045+ int err;
15046+ unsigned int flags;
15047+ umode_t mode;
15048+ aufs_bindex_t bindex, bstart, btail;
15049+ unsigned char isdir;
15050+ struct dentry *h_dentry;
15051+ struct inode *h_inode;
15052+ struct au_iinfo *iinfo;
dece6358 15053+
4a4d8108 15054+ IiMustWriteLock(inode);
dece6358 15055+
4a4d8108
AM
15056+ err = 0;
15057+ isdir = 0;
15058+ bstart = au_dbstart(dentry);
15059+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
15060+ mode = h_inode->i_mode;
15061+ switch (mode & S_IFMT) {
15062+ case S_IFREG:
15063+ btail = au_dbtail(dentry);
15064+ inode->i_op = &aufs_iop;
15065+ inode->i_fop = &aufs_file_fop;
15066+ err = au_dy_iaop(inode, bstart, h_inode);
15067+ if (unlikely(err))
15068+ goto out;
15069+ break;
15070+ case S_IFDIR:
15071+ isdir = 1;
15072+ btail = au_dbtaildir(dentry);
15073+ inode->i_op = &aufs_dir_iop;
15074+ inode->i_fop = &aufs_dir_fop;
15075+ break;
15076+ case S_IFLNK:
15077+ btail = au_dbtail(dentry);
15078+ inode->i_op = &aufs_symlink_iop;
15079+ break;
15080+ case S_IFBLK:
15081+ case S_IFCHR:
15082+ case S_IFIFO:
15083+ case S_IFSOCK:
15084+ btail = au_dbtail(dentry);
15085+ inode->i_op = &aufs_iop;
15086+ au_init_special_fop(inode, mode, h_inode->i_rdev);
15087+ break;
15088+ default:
15089+ AuIOErr("Unknown file type 0%o\n", mode);
15090+ err = -EIO;
1308ab2a 15091+ goto out;
4a4d8108 15092+ }
dece6358 15093+
4a4d8108
AM
15094+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
15095+ flags = au_hi_flags(inode, isdir);
15096+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
15097+ && au_ftest_hi(flags, HNOTIFY)
15098+ && dentry->d_name.len > AUFS_WH_PFX_LEN
15099+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
15100+ au_fclr_hi(flags, HNOTIFY);
15101+ iinfo = au_ii(inode);
15102+ iinfo->ii_bstart = bstart;
15103+ iinfo->ii_bend = btail;
15104+ for (bindex = bstart; bindex <= btail; bindex++) {
15105+ h_dentry = au_h_dptr(dentry, bindex);
15106+ if (h_dentry)
15107+ au_set_h_iptr(inode, bindex,
15108+ au_igrab(h_dentry->d_inode), flags);
15109+ }
15110+ au_cpup_attr_all(inode, /*force*/1);
dece6358 15111+
4f0767ce 15112+out:
4a4d8108
AM
15113+ return err;
15114+}
dece6358 15115+
027c5e7a
AM
15116+/*
15117+ * successful returns with iinfo write_locked
15118+ * minus: errno
15119+ * zero: success, matched
15120+ * plus: no error, but unmatched
15121+ */
15122+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
15123+{
15124+ int err;
537831f9
AM
15125+ unsigned int gen;
15126+ struct au_iigen iigen;
4a4d8108
AM
15127+ aufs_bindex_t bindex, bend;
15128+ struct inode *h_inode, *h_dinode;
dece6358 15129+
4a4d8108
AM
15130+ /*
15131+ * before this function, if aufs got any iinfo lock, it must be only
15132+ * one, the parent dir.
15133+ * it can happen by UDBA and the obsoleted inode number.
15134+ */
15135+ err = -EIO;
15136+ if (unlikely(inode->i_ino == parent_ino(dentry)))
15137+ goto out;
15138+
027c5e7a 15139+ err = 1;
4a4d8108
AM
15140+ ii_write_lock_new_child(inode);
15141+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
15142+ bend = au_ibend(inode);
15143+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
15144+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
15145+ if (!h_inode || h_inode != h_dinode)
15146+ continue;
15147+
15148+ err = 0;
15149+ gen = au_iigen(inode, &iigen);
15150+ if (gen == au_digen(dentry)
15151+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 15152+ break;
537831f9
AM
15153+
15154+ /* fully refresh inode using dentry */
15155+ err = au_refresh_hinode(inode, dentry);
15156+ if (!err)
15157+ au_update_iigen(inode, /*half*/0);
15158+ break;
1facf9fc 15159+ }
dece6358 15160+
4a4d8108
AM
15161+ if (unlikely(err))
15162+ ii_write_unlock(inode);
4f0767ce 15163+out:
1facf9fc 15164+ return err;
15165+}
1facf9fc 15166+
4a4d8108
AM
15167+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
15168+ unsigned int d_type, ino_t *ino)
1facf9fc 15169+{
4a4d8108
AM
15170+ int err;
15171+ struct mutex *mtx;
1facf9fc 15172+
b752ccd1 15173+ /* prevent hardlinked inode number from race condition */
4a4d8108 15174+ mtx = NULL;
b752ccd1 15175+ if (d_type != DT_DIR) {
4a4d8108
AM
15176+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
15177+ mutex_lock(mtx);
15178+ }
15179+ err = au_xino_read(sb, bindex, h_ino, ino);
15180+ if (unlikely(err))
15181+ goto out;
1308ab2a 15182+
4a4d8108
AM
15183+ if (!*ino) {
15184+ err = -EIO;
15185+ *ino = au_xino_new_ino(sb);
15186+ if (unlikely(!*ino))
1facf9fc 15187+ goto out;
4a4d8108
AM
15188+ err = au_xino_write(sb, bindex, h_ino, *ino);
15189+ if (unlikely(err))
1308ab2a 15190+ goto out;
1308ab2a 15191+ }
1facf9fc 15192+
4f0767ce 15193+out:
b752ccd1 15194+ if (mtx)
4a4d8108 15195+ mutex_unlock(mtx);
1facf9fc 15196+ return err;
15197+}
15198+
4a4d8108
AM
15199+/* successful returns with iinfo write_locked */
15200+/* todo: return with unlocked? */
15201+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 15202+{
b752ccd1 15203+ struct inode *inode, *h_inode;
4a4d8108
AM
15204+ struct dentry *h_dentry;
15205+ struct super_block *sb;
b752ccd1 15206+ struct mutex *mtx;
4a4d8108 15207+ ino_t h_ino, ino;
1716fcea 15208+ int err;
4a4d8108 15209+ aufs_bindex_t bstart;
1facf9fc 15210+
4a4d8108
AM
15211+ sb = dentry->d_sb;
15212+ bstart = au_dbstart(dentry);
15213+ h_dentry = au_h_dptr(dentry, bstart);
b752ccd1
AM
15214+ h_inode = h_dentry->d_inode;
15215+ h_ino = h_inode->i_ino;
15216+
15217+ /*
15218+ * stop 'race'-ing between hardlinks under different
15219+ * parents.
15220+ */
15221+ mtx = NULL;
15222+ if (!S_ISDIR(h_inode->i_mode))
15223+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
15224+
4f0767ce 15225+new_ino:
b752ccd1
AM
15226+ if (mtx)
15227+ mutex_lock(mtx);
4a4d8108
AM
15228+ err = au_xino_read(sb, bstart, h_ino, &ino);
15229+ inode = ERR_PTR(err);
15230+ if (unlikely(err))
15231+ goto out;
b752ccd1 15232+
4a4d8108
AM
15233+ if (!ino) {
15234+ ino = au_xino_new_ino(sb);
15235+ if (unlikely(!ino)) {
15236+ inode = ERR_PTR(-EIO);
dece6358
AM
15237+ goto out;
15238+ }
15239+ }
1facf9fc 15240+
4a4d8108
AM
15241+ AuDbg("i%lu\n", (unsigned long)ino);
15242+ inode = au_iget_locked(sb, ino);
15243+ err = PTR_ERR(inode);
15244+ if (IS_ERR(inode))
1facf9fc 15245+ goto out;
1facf9fc 15246+
4a4d8108
AM
15247+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
15248+ if (inode->i_state & I_NEW) {
1716fcea
AM
15249+ /* verbose coding for lock class name */
15250+ if (unlikely(S_ISLNK(h_inode->i_mode)))
15251+ au_rw_class(&au_ii(inode)->ii_rwsem,
15252+ au_lc_key + AuLcSymlink_IIINFO);
15253+ else if (unlikely(S_ISDIR(h_inode->i_mode)))
15254+ au_rw_class(&au_ii(inode)->ii_rwsem,
15255+ au_lc_key + AuLcDir_IIINFO);
15256+ else /* likely */
15257+ au_rw_class(&au_ii(inode)->ii_rwsem,
15258+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 15259+
4a4d8108
AM
15260+ ii_write_lock_new_child(inode);
15261+ err = set_inode(inode, dentry);
15262+ if (!err) {
15263+ unlock_new_inode(inode);
15264+ goto out; /* success */
15265+ }
1308ab2a 15266+
027c5e7a
AM
15267+ /*
15268+ * iget_failed() calls iput(), but we need to call
15269+ * ii_write_unlock() after iget_failed(). so dirty hack for
15270+ * i_count.
15271+ */
15272+ atomic_inc(&inode->i_count);
4a4d8108 15273+ iget_failed(inode);
027c5e7a
AM
15274+ ii_write_unlock(inode);
15275+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
15276+ /* ignore this error */
15277+ goto out_iput;
15278+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
15279+ /*
15280+ * horrible race condition between lookup, readdir and copyup
15281+ * (or something).
15282+ */
15283+ if (mtx)
15284+ mutex_unlock(mtx);
027c5e7a
AM
15285+ err = reval_inode(inode, dentry);
15286+ if (unlikely(err < 0)) {
15287+ mtx = NULL;
15288+ goto out_iput;
15289+ }
15290+
b752ccd1
AM
15291+ if (!err) {
15292+ mtx = NULL;
4a4d8108 15293+ goto out; /* success */
b752ccd1
AM
15294+ } else if (mtx)
15295+ mutex_lock(mtx);
4a4d8108
AM
15296+ }
15297+
15298+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
15299+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3
AM
15300+ " b%d, %s, %pd, hi%lu, i%lu.\n",
15301+ bstart, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
15302+ (unsigned long)h_ino, (unsigned long)ino);
15303+ ino = 0;
15304+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
15305+ if (!err) {
15306+ iput(inode);
b752ccd1
AM
15307+ if (mtx)
15308+ mutex_unlock(mtx);
4a4d8108
AM
15309+ goto new_ino;
15310+ }
1308ab2a 15311+
4f0767ce 15312+out_iput:
4a4d8108 15313+ iput(inode);
4a4d8108 15314+ inode = ERR_PTR(err);
4f0767ce 15315+out:
b752ccd1
AM
15316+ if (mtx)
15317+ mutex_unlock(mtx);
4a4d8108 15318+ return inode;
1facf9fc 15319+}
15320+
4a4d8108 15321+/* ---------------------------------------------------------------------- */
1facf9fc 15322+
4a4d8108
AM
15323+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
15324+ struct inode *inode)
15325+{
15326+ int err;
1facf9fc 15327+
4a4d8108 15328+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 15329+
4a4d8108
AM
15330+ /* pseudo-link after flushed may happen out of bounds */
15331+ if (!err
15332+ && inode
15333+ && au_ibstart(inode) <= bindex
15334+ && bindex <= au_ibend(inode)) {
15335+ /*
15336+ * permission check is unnecessary since vfsub routine
15337+ * will be called later
15338+ */
15339+ struct inode *hi = au_h_iptr(inode, bindex);
15340+ if (hi)
15341+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 15342+ }
15343+
4a4d8108
AM
15344+ return err;
15345+}
dece6358 15346+
4a4d8108
AM
15347+int au_test_h_perm(struct inode *h_inode, int mask)
15348+{
2dfbb274 15349+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
15350+ return 0;
15351+ return inode_permission(h_inode, mask);
15352+}
1facf9fc 15353+
4a4d8108
AM
15354+int au_test_h_perm_sio(struct inode *h_inode, int mask)
15355+{
15356+ if (au_test_nfs(h_inode->i_sb)
15357+ && (mask & MAY_WRITE)
15358+ && S_ISDIR(h_inode->i_mode))
15359+ mask |= MAY_READ; /* force permission check */
15360+ return au_test_h_perm(h_inode, mask);
1facf9fc 15361+}
7f207e10
AM
15362diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
15363--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 15364+++ linux/fs/aufs/inode.h 2014-04-24 22:11:10.855269116 +0200
523b37e3 15365@@ -0,0 +1,599 @@
4a4d8108 15366+/*
523b37e3 15367+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
15368+ *
15369+ * This program, aufs is free software; you can redistribute it and/or modify
15370+ * it under the terms of the GNU General Public License as published by
15371+ * the Free Software Foundation; either version 2 of the License, or
15372+ * (at your option) any later version.
15373+ *
15374+ * This program is distributed in the hope that it will be useful,
15375+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15376+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15377+ * GNU General Public License for more details.
15378+ *
15379+ * You should have received a copy of the GNU General Public License
523b37e3 15380+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15381+ */
1facf9fc 15382+
1308ab2a 15383+/*
4a4d8108 15384+ * inode operations
1308ab2a 15385+ */
dece6358 15386+
4a4d8108
AM
15387+#ifndef __AUFS_INODE_H__
15388+#define __AUFS_INODE_H__
dece6358 15389+
4a4d8108 15390+#ifdef __KERNEL__
1308ab2a 15391+
4a4d8108 15392+#include <linux/fsnotify.h>
4a4d8108 15393+#include "rwsem.h"
1308ab2a 15394+
4a4d8108 15395+struct vfsmount;
1facf9fc 15396+
4a4d8108
AM
15397+struct au_hnotify {
15398+#ifdef CONFIG_AUFS_HNOTIFY
15399+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 15400+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 15401+ struct fsnotify_mark hn_mark;
4a4d8108 15402+#endif
7f207e10 15403+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
15404+#endif
15405+} ____cacheline_aligned_in_smp;
1facf9fc 15406+
4a4d8108
AM
15407+struct au_hinode {
15408+ struct inode *hi_inode;
15409+ aufs_bindex_t hi_id;
15410+#ifdef CONFIG_AUFS_HNOTIFY
15411+ struct au_hnotify *hi_notify;
15412+#endif
dece6358 15413+
4a4d8108
AM
15414+ /* reference to the copied-up whiteout with get/put */
15415+ struct dentry *hi_whdentry;
15416+};
dece6358 15417+
537831f9
AM
15418+/* ig_flags */
15419+#define AuIG_HALF_REFRESHED 1
15420+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
15421+#define au_ig_fset(flags, name) \
15422+ do { (flags) |= AuIG_##name; } while (0)
15423+#define au_ig_fclr(flags, name) \
15424+ do { (flags) &= ~AuIG_##name; } while (0)
15425+
15426+struct au_iigen {
15427+ __u32 ig_generation, ig_flags;
15428+};
15429+
4a4d8108
AM
15430+struct au_vdir;
15431+struct au_iinfo {
537831f9 15432+ spinlock_t ii_genspin;
7a9e40b8 15433+ struct au_iigen ii_generation;
4a4d8108 15434+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 15435+
4a4d8108
AM
15436+ struct au_rwsem ii_rwsem;
15437+ aufs_bindex_t ii_bstart, ii_bend;
15438+ __u32 ii_higen;
15439+ struct au_hinode *ii_hinode;
15440+ struct au_vdir *ii_vdir;
15441+};
1facf9fc 15442+
4a4d8108
AM
15443+struct au_icntnr {
15444+ struct au_iinfo iinfo;
15445+ struct inode vfs_inode;
15446+} ____cacheline_aligned_in_smp;
1308ab2a 15447+
4a4d8108
AM
15448+/* au_pin flags */
15449+#define AuPin_DI_LOCKED 1
15450+#define AuPin_MNT_WRITE (1 << 1)
15451+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
15452+#define au_fset_pin(flags, name) \
15453+ do { (flags) |= AuPin_##name; } while (0)
15454+#define au_fclr_pin(flags, name) \
15455+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
15456+
15457+struct au_pin {
15458+ /* input */
15459+ struct dentry *dentry;
15460+ unsigned int udba;
15461+ unsigned char lsc_di, lsc_hi, flags;
15462+ aufs_bindex_t bindex;
15463+
15464+ /* output */
15465+ struct dentry *parent;
15466+ struct au_hinode *hdir;
15467+ struct vfsmount *h_mnt;
86dc4139
AM
15468+
15469+ /* temporary unlock/relock for copyup */
15470+ struct dentry *h_dentry, *h_parent;
15471+ struct au_branch *br;
15472+ struct task_struct *task;
4a4d8108 15473+};
1facf9fc 15474+
86dc4139
AM
15475+void au_pin_hdir_unlock(struct au_pin *p);
15476+int au_pin_hdir_relock(struct au_pin *p);
15477+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
15478+void au_pin_hdir_acquire_nest(struct au_pin *p);
15479+void au_pin_hdir_release(struct au_pin *p);
15480+
1308ab2a 15481+/* ---------------------------------------------------------------------- */
15482+
4a4d8108 15483+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 15484+{
4a4d8108 15485+ struct au_iinfo *iinfo;
1facf9fc 15486+
4a4d8108
AM
15487+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
15488+ if (iinfo->ii_hinode)
15489+ return iinfo;
15490+ return NULL; /* debugging bad_inode case */
15491+}
1facf9fc 15492+
4a4d8108 15493+/* ---------------------------------------------------------------------- */
1facf9fc 15494+
4a4d8108
AM
15495+/* inode.c */
15496+struct inode *au_igrab(struct inode *inode);
027c5e7a 15497+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
15498+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
15499+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
15500+ unsigned int d_type, ino_t *ino);
15501+struct inode *au_new_inode(struct dentry *dentry, int must_new);
15502+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
15503+ struct inode *inode);
15504+int au_test_h_perm(struct inode *h_inode, int mask);
15505+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 15506+
4a4d8108
AM
15507+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
15508+ ino_t h_ino, unsigned int d_type, ino_t *ino)
15509+{
15510+#ifdef CONFIG_AUFS_SHWH
15511+ return au_ino(sb, bindex, h_ino, d_type, ino);
15512+#else
15513+ return 0;
15514+#endif
15515+}
1facf9fc 15516+
4a4d8108
AM
15517+/* i_op.c */
15518+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 15519+
4a4d8108
AM
15520+/* au_wr_dir flags */
15521+#define AuWrDir_ADD_ENTRY 1
86dc4139
AM
15522+#define AuWrDir_TMP_WHENTRY (1 << 1)
15523+#define AuWrDir_ISDIR (1 << 2)
4a4d8108 15524+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
15525+#define au_fset_wrdir(flags, name) \
15526+ do { (flags) |= AuWrDir_##name; } while (0)
15527+#define au_fclr_wrdir(flags, name) \
15528+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 15529+
4a4d8108
AM
15530+struct au_wr_dir_args {
15531+ aufs_bindex_t force_btgt;
15532+ unsigned char flags;
15533+};
15534+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
15535+ struct au_wr_dir_args *args);
dece6358 15536+
4a4d8108
AM
15537+struct dentry *au_pinned_h_parent(struct au_pin *pin);
15538+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
15539+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
15540+ unsigned int udba, unsigned char flags);
15541+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
15542+ unsigned int udba, unsigned char flags) __must_check;
15543+int au_do_pin(struct au_pin *pin) __must_check;
15544+void au_unpin(struct au_pin *pin);
1facf9fc 15545+
4a4d8108
AM
15546+/* i_op_add.c */
15547+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
15548+ struct dentry *h_parent, int isdir);
7eafdf33
AM
15549+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
15550+ dev_t dev);
4a4d8108 15551+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 15552+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 15553+ bool want_excl);
4a4d8108
AM
15554+int aufs_link(struct dentry *src_dentry, struct inode *dir,
15555+ struct dentry *dentry);
7eafdf33 15556+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 15557+
4a4d8108
AM
15558+/* i_op_del.c */
15559+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
15560+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
15561+ struct dentry *h_parent, int isdir);
15562+int aufs_unlink(struct inode *dir, struct dentry *dentry);
15563+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 15564+
4a4d8108
AM
15565+/* i_op_ren.c */
15566+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
15567+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
15568+ struct inode *dir, struct dentry *dentry);
1facf9fc 15569+
4a4d8108
AM
15570+/* iinfo.c */
15571+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
15572+void au_hiput(struct au_hinode *hinode);
15573+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15574+ struct dentry *h_wh);
15575+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 15576+
4a4d8108
AM
15577+/* hinode flags */
15578+#define AuHi_XINO 1
15579+#define AuHi_HNOTIFY (1 << 1)
15580+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
15581+#define au_fset_hi(flags, name) \
15582+ do { (flags) |= AuHi_##name; } while (0)
15583+#define au_fclr_hi(flags, name) \
15584+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 15585+
4a4d8108
AM
15586+#ifndef CONFIG_AUFS_HNOTIFY
15587+#undef AuHi_HNOTIFY
15588+#define AuHi_HNOTIFY 0
15589+#endif
1facf9fc 15590+
4a4d8108
AM
15591+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15592+ struct inode *h_inode, unsigned int flags);
1facf9fc 15593+
537831f9 15594+void au_update_iigen(struct inode *inode, int half);
4a4d8108 15595+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 15596+
4a4d8108
AM
15597+void au_icntnr_init_once(void *_c);
15598+int au_iinfo_init(struct inode *inode);
15599+void au_iinfo_fin(struct inode *inode);
15600+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 15601+
e49829fe 15602+#ifdef CONFIG_PROC_FS
4a4d8108 15603+/* plink.c */
e49829fe
JR
15604+int au_plink_maint(struct super_block *sb, int flags);
15605+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
15606+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
15607+#ifdef CONFIG_AUFS_DEBUG
15608+void au_plink_list(struct super_block *sb);
15609+#else
15610+AuStubVoid(au_plink_list, struct super_block *sb)
15611+#endif
15612+int au_plink_test(struct inode *inode);
15613+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
15614+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
15615+ struct dentry *h_dentry);
e49829fe
JR
15616+void au_plink_put(struct super_block *sb, int verbose);
15617+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 15618+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
15619+#else
15620+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
15621+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
15622+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
15623+AuStubVoid(au_plink_list, struct super_block *sb);
15624+AuStubInt0(au_plink_test, struct inode *inode);
15625+AuStub(struct dentry *, au_plink_lkup, return NULL,
15626+ struct inode *inode, aufs_bindex_t bindex);
15627+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
15628+ struct dentry *h_dentry);
15629+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
15630+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
15631+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
15632+#endif /* CONFIG_PROC_FS */
1facf9fc 15633+
4a4d8108 15634+/* ---------------------------------------------------------------------- */
1308ab2a 15635+
4a4d8108
AM
15636+/* lock subclass for iinfo */
15637+enum {
15638+ AuLsc_II_CHILD, /* child first */
15639+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
15640+ AuLsc_II_CHILD3, /* copyup dirs */
15641+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
15642+ AuLsc_II_PARENT2,
15643+ AuLsc_II_PARENT3, /* copyup dirs */
15644+ AuLsc_II_NEW_CHILD
15645+};
1308ab2a 15646+
1facf9fc 15647+/*
4a4d8108
AM
15648+ * ii_read_lock_child, ii_write_lock_child,
15649+ * ii_read_lock_child2, ii_write_lock_child2,
15650+ * ii_read_lock_child3, ii_write_lock_child3,
15651+ * ii_read_lock_parent, ii_write_lock_parent,
15652+ * ii_read_lock_parent2, ii_write_lock_parent2,
15653+ * ii_read_lock_parent3, ii_write_lock_parent3,
15654+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 15655+ */
4a4d8108
AM
15656+#define AuReadLockFunc(name, lsc) \
15657+static inline void ii_read_lock_##name(struct inode *i) \
15658+{ \
15659+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15660+}
15661+
15662+#define AuWriteLockFunc(name, lsc) \
15663+static inline void ii_write_lock_##name(struct inode *i) \
15664+{ \
15665+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
15666+}
15667+
15668+#define AuRWLockFuncs(name, lsc) \
15669+ AuReadLockFunc(name, lsc) \
15670+ AuWriteLockFunc(name, lsc)
15671+
15672+AuRWLockFuncs(child, CHILD);
15673+AuRWLockFuncs(child2, CHILD2);
15674+AuRWLockFuncs(child3, CHILD3);
15675+AuRWLockFuncs(parent, PARENT);
15676+AuRWLockFuncs(parent2, PARENT2);
15677+AuRWLockFuncs(parent3, PARENT3);
15678+AuRWLockFuncs(new_child, NEW_CHILD);
15679+
15680+#undef AuReadLockFunc
15681+#undef AuWriteLockFunc
15682+#undef AuRWLockFuncs
1facf9fc 15683+
15684+/*
4a4d8108 15685+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 15686+ */
4a4d8108 15687+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 15688+
4a4d8108
AM
15689+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
15690+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
15691+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 15692+
4a4d8108 15693+/* ---------------------------------------------------------------------- */
1308ab2a 15694+
027c5e7a
AM
15695+static inline void au_icntnr_init(struct au_icntnr *c)
15696+{
15697+#ifdef CONFIG_AUFS_DEBUG
15698+ c->vfs_inode.i_mode = 0;
15699+#endif
15700+}
15701+
537831f9 15702+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 15703+{
537831f9
AM
15704+ unsigned int gen;
15705+ struct au_iinfo *iinfo;
15706+
15707+ iinfo = au_ii(inode);
15708+ spin_lock(&iinfo->ii_genspin);
15709+ if (iigen)
15710+ *iigen = iinfo->ii_generation;
15711+ gen = iinfo->ii_generation.ig_generation;
15712+ spin_unlock(&iinfo->ii_genspin);
15713+
15714+ return gen;
4a4d8108 15715+}
1308ab2a 15716+
4a4d8108
AM
15717+/* tiny test for inode number */
15718+/* tmpfs generation is too rough */
15719+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
15720+{
15721+ struct au_iinfo *iinfo;
1308ab2a 15722+
4a4d8108
AM
15723+ iinfo = au_ii(inode);
15724+ AuRwMustAnyLock(&iinfo->ii_rwsem);
15725+ return !(iinfo->ii_hsb1 == h_inode->i_sb
15726+ && iinfo->ii_higen == h_inode->i_generation);
15727+}
1308ab2a 15728+
4a4d8108
AM
15729+static inline void au_iigen_dec(struct inode *inode)
15730+{
537831f9
AM
15731+ struct au_iinfo *iinfo;
15732+
15733+ iinfo = au_ii(inode);
15734+ spin_lock(&iinfo->ii_genspin);
15735+ iinfo->ii_generation.ig_generation--;
15736+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
15737+}
15738+
15739+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
15740+{
15741+ int err;
15742+
15743+ err = 0;
537831f9 15744+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
15745+ err = -EIO;
15746+
15747+ return err;
4a4d8108 15748+}
1308ab2a 15749+
4a4d8108 15750+/* ---------------------------------------------------------------------- */
1308ab2a 15751+
4a4d8108
AM
15752+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
15753+ aufs_bindex_t bindex)
15754+{
15755+ IiMustAnyLock(inode);
15756+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
15757+}
1308ab2a 15758+
4a4d8108
AM
15759+static inline aufs_bindex_t au_ibstart(struct inode *inode)
15760+{
15761+ IiMustAnyLock(inode);
15762+ return au_ii(inode)->ii_bstart;
15763+}
1308ab2a 15764+
4a4d8108
AM
15765+static inline aufs_bindex_t au_ibend(struct inode *inode)
15766+{
15767+ IiMustAnyLock(inode);
15768+ return au_ii(inode)->ii_bend;
15769+}
1308ab2a 15770+
4a4d8108
AM
15771+static inline struct au_vdir *au_ivdir(struct inode *inode)
15772+{
15773+ IiMustAnyLock(inode);
15774+ return au_ii(inode)->ii_vdir;
15775+}
1308ab2a 15776+
4a4d8108
AM
15777+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
15778+{
15779+ IiMustAnyLock(inode);
15780+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
15781+}
1308ab2a 15782+
4a4d8108 15783+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15784+{
4a4d8108
AM
15785+ IiMustWriteLock(inode);
15786+ au_ii(inode)->ii_bstart = bindex;
15787+}
1308ab2a 15788+
4a4d8108
AM
15789+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
15790+{
15791+ IiMustWriteLock(inode);
15792+ au_ii(inode)->ii_bend = bindex;
1308ab2a 15793+}
15794+
4a4d8108
AM
15795+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
15796+{
15797+ IiMustWriteLock(inode);
15798+ au_ii(inode)->ii_vdir = vdir;
15799+}
1facf9fc 15800+
4a4d8108 15801+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15802+{
4a4d8108
AM
15803+ IiMustAnyLock(inode);
15804+ return au_ii(inode)->ii_hinode + bindex;
15805+}
dece6358 15806+
4a4d8108 15807+/* ---------------------------------------------------------------------- */
1facf9fc 15808+
4a4d8108
AM
15809+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
15810+{
15811+ if (pin)
15812+ return pin->parent;
15813+ return NULL;
1facf9fc 15814+}
15815+
4a4d8108 15816+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 15817+{
4a4d8108
AM
15818+ if (pin && pin->hdir)
15819+ return pin->hdir->hi_inode;
15820+ return NULL;
1308ab2a 15821+}
1facf9fc 15822+
4a4d8108
AM
15823+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
15824+{
15825+ if (pin)
15826+ return pin->hdir;
15827+ return NULL;
15828+}
1facf9fc 15829+
4a4d8108 15830+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 15831+{
4a4d8108
AM
15832+ if (pin)
15833+ pin->dentry = dentry;
15834+}
1308ab2a 15835+
4a4d8108
AM
15836+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
15837+ unsigned char lflag)
15838+{
15839+ if (pin) {
7f207e10 15840+ if (lflag)
4a4d8108 15841+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 15842+ else
4a4d8108 15843+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 15844+ }
4a4d8108
AM
15845+}
15846+
15847+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
15848+{
15849+ if (pin) {
15850+ dput(pin->parent);
15851+ pin->parent = dget(parent);
1facf9fc 15852+ }
4a4d8108 15853+}
1facf9fc 15854+
4a4d8108
AM
15855+/* ---------------------------------------------------------------------- */
15856+
027c5e7a 15857+struct au_branch;
4a4d8108
AM
15858+#ifdef CONFIG_AUFS_HNOTIFY
15859+struct au_hnotify_op {
15860+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 15861+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
15862+
15863+ /*
15864+ * if it returns true, the the caller should free hinode->hi_notify,
15865+ * otherwise ->free() frees it.
15866+ */
15867+ int (*free)(struct au_hinode *hinode,
15868+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
15869+
15870+ void (*fin)(void);
15871+ int (*init)(void);
027c5e7a
AM
15872+
15873+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
15874+ void (*fin_br)(struct au_branch *br);
15875+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
15876+};
15877+
15878+/* hnotify.c */
027c5e7a 15879+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
15880+void au_hn_free(struct au_hinode *hinode);
15881+void au_hn_ctl(struct au_hinode *hinode, int do_set);
15882+void au_hn_reset(struct inode *inode, unsigned int flags);
15883+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15884+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
15885+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
15886+int au_hnotify_init_br(struct au_branch *br, int perm);
15887+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
15888+int __init au_hnotify_init(void);
15889+void au_hnotify_fin(void);
15890+
7f207e10 15891+/* hfsnotify.c */
4a4d8108
AM
15892+extern const struct au_hnotify_op au_hnotify_op;
15893+
15894+static inline
15895+void au_hn_init(struct au_hinode *hinode)
15896+{
15897+ hinode->hi_notify = NULL;
1308ab2a 15898+}
15899+
53392da6
AM
15900+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15901+{
15902+ return hinode->hi_notify;
15903+}
15904+
4a4d8108
AM
15905+#else
15906+static inline
15907+int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
027c5e7a 15908+ struct inode *inode __maybe_unused)
1308ab2a 15909+{
4a4d8108
AM
15910+ return -EOPNOTSUPP;
15911+}
1308ab2a 15912+
53392da6
AM
15913+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
15914+{
15915+ return NULL;
15916+}
15917+
4a4d8108
AM
15918+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
15919+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
15920+ int do_set __maybe_unused)
15921+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
15922+ unsigned int flags __maybe_unused)
027c5e7a
AM
15923+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
15924+ struct au_branch *br __maybe_unused,
15925+ int perm __maybe_unused)
15926+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
15927+ int perm __maybe_unused)
15928+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
15929+AuStubInt0(__init au_hnotify_init, void)
15930+AuStubVoid(au_hnotify_fin, void)
15931+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
15932+#endif /* CONFIG_AUFS_HNOTIFY */
15933+
15934+static inline void au_hn_suspend(struct au_hinode *hdir)
15935+{
15936+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 15937+}
15938+
4a4d8108 15939+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 15940+{
4a4d8108
AM
15941+ au_hn_ctl(hdir, /*do_set*/1);
15942+}
1308ab2a 15943+
4a4d8108
AM
15944+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
15945+{
15946+ mutex_lock(&hdir->hi_inode->i_mutex);
15947+ au_hn_suspend(hdir);
15948+}
dece6358 15949+
4a4d8108
AM
15950+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
15951+ unsigned int sc __maybe_unused)
15952+{
15953+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
15954+ au_hn_suspend(hdir);
1facf9fc 15955+}
1facf9fc 15956+
4a4d8108
AM
15957+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
15958+{
15959+ au_hn_resume(hdir);
15960+ mutex_unlock(&hdir->hi_inode->i_mutex);
15961+}
15962+
15963+#endif /* __KERNEL__ */
15964+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
15965diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
15966--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 15967+++ linux/fs/aufs/ioctl.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 15968@@ -0,0 +1,201 @@
4a4d8108 15969+/*
523b37e3 15970+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
15971+ *
15972+ * This program, aufs is free software; you can redistribute it and/or modify
15973+ * it under the terms of the GNU General Public License as published by
15974+ * the Free Software Foundation; either version 2 of the License, or
15975+ * (at your option) any later version.
15976+ *
15977+ * This program is distributed in the hope that it will be useful,
15978+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15979+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15980+ * GNU General Public License for more details.
15981+ *
15982+ * You should have received a copy of the GNU General Public License
523b37e3 15983+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
15984+ */
15985+
15986+/*
15987+ * ioctl
15988+ * plink-management and readdir in userspace.
15989+ * assist the pathconf(3) wrapper library.
c2b27bf2 15990+ * move-down
4a4d8108
AM
15991+ */
15992+
c2b27bf2
AM
15993+#include <linux/compat.h>
15994+#include <linux/file.h>
4a4d8108
AM
15995+#include "aufs.h"
15996+
1e00d052 15997+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
15998+{
15999+ int err, fd;
16000+ aufs_bindex_t wbi, bindex, bend;
16001+ struct file *h_file;
16002+ struct super_block *sb;
16003+ struct dentry *root;
1e00d052
AM
16004+ struct au_branch *br;
16005+ struct aufs_wbr_fd wbrfd = {
16006+ .oflags = au_dir_roflags,
16007+ .brid = -1
16008+ };
16009+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
16010+ | O_NOATIME | O_CLOEXEC;
4a4d8108 16011+
1e00d052
AM
16012+ AuDebugOn(wbrfd.oflags & ~valid);
16013+
16014+ if (arg) {
16015+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
16016+ if (unlikely(err)) {
16017+ err = -EFAULT;
16018+ goto out;
16019+ }
16020+
16021+ err = -EINVAL;
16022+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
16023+ wbrfd.oflags |= au_dir_roflags;
16024+ AuDbg("0%o\n", wbrfd.oflags);
16025+ if (unlikely(wbrfd.oflags & ~valid))
16026+ goto out;
16027+ }
16028+
16029+ fd = get_unused_fd();
16030+ err = fd;
16031+ if (unlikely(fd < 0))
4a4d8108 16032+ goto out;
4a4d8108 16033+
1e00d052 16034+ h_file = ERR_PTR(-EINVAL);
4a4d8108 16035+ wbi = 0;
1e00d052 16036+ br = NULL;
4a4d8108
AM
16037+ sb = path->dentry->d_sb;
16038+ root = sb->s_root;
16039+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
16040+ bend = au_sbend(sb);
16041+ if (wbrfd.brid >= 0) {
16042+ wbi = au_br_index(sb, wbrfd.brid);
16043+ if (unlikely(wbi < 0 || wbi > bend))
16044+ goto out_unlock;
16045+ }
16046+
16047+ h_file = ERR_PTR(-ENOENT);
16048+ br = au_sbr(sb, wbi);
16049+ if (!au_br_writable(br->br_perm)) {
16050+ if (arg)
16051+ goto out_unlock;
16052+
16053+ bindex = wbi + 1;
16054+ wbi = -1;
16055+ for (; bindex <= bend; bindex++) {
16056+ br = au_sbr(sb, bindex);
16057+ if (au_br_writable(br->br_perm)) {
4a4d8108 16058+ wbi = bindex;
1e00d052 16059+ br = au_sbr(sb, wbi);
4a4d8108
AM
16060+ break;
16061+ }
16062+ }
4a4d8108
AM
16063+ }
16064+ AuDbg("wbi %d\n", wbi);
1e00d052 16065+ if (wbi >= 0)
392086de
AM
16066+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
16067+ /*force_wr*/0);
1e00d052
AM
16068+
16069+out_unlock:
4a4d8108
AM
16070+ aufs_read_unlock(root, AuLock_IR);
16071+ err = PTR_ERR(h_file);
16072+ if (IS_ERR(h_file))
16073+ goto out_fd;
16074+
1e00d052 16075+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
16076+ fd_install(fd, h_file);
16077+ err = fd;
16078+ goto out; /* success */
16079+
4f0767ce 16080+out_fd:
4a4d8108 16081+ put_unused_fd(fd);
4f0767ce 16082+out:
1e00d052 16083+ AuTraceErr(err);
4a4d8108
AM
16084+ return err;
16085+}
16086+
16087+/* ---------------------------------------------------------------------- */
16088+
16089+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
16090+{
16091+ long err;
16092+
16093+ switch (cmd) {
4a4d8108
AM
16094+ case AUFS_CTL_RDU:
16095+ case AUFS_CTL_RDU_INO:
16096+ err = au_rdu_ioctl(file, cmd, arg);
16097+ break;
16098+
16099+ case AUFS_CTL_WBR_FD:
1e00d052 16100+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
16101+ break;
16102+
027c5e7a
AM
16103+ case AUFS_CTL_IBUSY:
16104+ err = au_ibusy_ioctl(file, arg);
16105+ break;
16106+
4a4d8108
AM
16107+ default:
16108+ /* do not call the lower */
16109+ AuDbg("0x%x\n", cmd);
16110+ err = -ENOTTY;
16111+ }
16112+
16113+ AuTraceErr(err);
16114+ return err;
16115+}
16116+
16117+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
16118+{
16119+ long err;
16120+
16121+ switch (cmd) {
c2b27bf2 16122+ case AUFS_CTL_MVDOWN:
c2b27bf2
AM
16123+ err = au_mvdown(file->f_dentry, (void __user *)arg);
16124+ break;
16125+
4a4d8108 16126+ case AUFS_CTL_WBR_FD:
1e00d052 16127+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
16128+ break;
16129+
16130+ default:
16131+ /* do not call the lower */
16132+ AuDbg("0x%x\n", cmd);
16133+ err = -ENOTTY;
16134+ }
16135+
16136+ AuTraceErr(err);
16137+ return err;
16138+}
b752ccd1
AM
16139+
16140+#ifdef CONFIG_COMPAT
16141+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
16142+ unsigned long arg)
16143+{
16144+ long err;
16145+
16146+ switch (cmd) {
16147+ case AUFS_CTL_RDU:
16148+ case AUFS_CTL_RDU_INO:
16149+ err = au_rdu_compat_ioctl(file, cmd, arg);
16150+ break;
16151+
027c5e7a
AM
16152+ case AUFS_CTL_IBUSY:
16153+ err = au_ibusy_compat_ioctl(file, arg);
16154+ break;
16155+
b752ccd1
AM
16156+ default:
16157+ err = aufs_ioctl_dir(file, cmd, arg);
16158+ }
16159+
16160+ AuTraceErr(err);
16161+ return err;
16162+}
16163+
b752ccd1
AM
16164+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
16165+ unsigned long arg)
16166+{
16167+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
16168+}
16169+#endif
7f207e10
AM
16170diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
16171--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 16172+++ linux/fs/aufs/i_op_add.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 16173@@ -0,0 +1,762 @@
4a4d8108 16174+/*
523b37e3 16175+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
16176+ *
16177+ * This program, aufs is free software; you can redistribute it and/or modify
16178+ * it under the terms of the GNU General Public License as published by
16179+ * the Free Software Foundation; either version 2 of the License, or
16180+ * (at your option) any later version.
16181+ *
16182+ * This program is distributed in the hope that it will be useful,
16183+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16184+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16185+ * GNU General Public License for more details.
16186+ *
16187+ * You should have received a copy of the GNU General Public License
523b37e3 16188+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16189+ */
16190+
16191+/*
16192+ * inode operations (add entry)
16193+ */
16194+
16195+#include "aufs.h"
16196+
16197+/*
16198+ * final procedure of adding a new entry, except link(2).
16199+ * remove whiteout, instantiate, copyup the parent dir's times and size
16200+ * and update version.
16201+ * if it failed, re-create the removed whiteout.
16202+ */
16203+static int epilog(struct inode *dir, aufs_bindex_t bindex,
16204+ struct dentry *wh_dentry, struct dentry *dentry)
16205+{
16206+ int err, rerr;
16207+ aufs_bindex_t bwh;
16208+ struct path h_path;
16209+ struct inode *inode, *h_dir;
16210+ struct dentry *wh;
16211+
16212+ bwh = -1;
16213+ if (wh_dentry) {
16214+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
16215+ IMustLock(h_dir);
16216+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
16217+ bwh = au_dbwh(dentry);
16218+ h_path.dentry = wh_dentry;
16219+ h_path.mnt = au_sbr_mnt(dir->i_sb, bindex);
16220+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
16221+ dentry);
16222+ if (unlikely(err))
16223+ goto out;
16224+ }
16225+
16226+ inode = au_new_inode(dentry, /*must_new*/1);
16227+ if (!IS_ERR(inode)) {
16228+ d_instantiate(dentry, inode);
16229+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
16230+ IMustLock(dir);
16231+ if (au_ibstart(dir) == au_dbstart(dentry))
16232+ au_cpup_attr_timesizes(dir);
16233+ dir->i_version++;
16234+ return 0; /* success */
16235+ }
16236+
16237+ err = PTR_ERR(inode);
16238+ if (!wh_dentry)
16239+ goto out;
16240+
16241+ /* revert */
16242+ /* dir inode is locked */
16243+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
16244+ rerr = PTR_ERR(wh);
16245+ if (IS_ERR(wh)) {
523b37e3
AM
16246+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
16247+ dentry, err, rerr);
4a4d8108
AM
16248+ err = -EIO;
16249+ } else
16250+ dput(wh);
16251+
4f0767ce 16252+out:
4a4d8108
AM
16253+ return err;
16254+}
16255+
027c5e7a
AM
16256+static int au_d_may_add(struct dentry *dentry)
16257+{
16258+ int err;
16259+
16260+ err = 0;
16261+ if (unlikely(d_unhashed(dentry)))
16262+ err = -ENOENT;
16263+ if (unlikely(dentry->d_inode))
16264+ err = -EEXIST;
16265+ return err;
16266+}
16267+
4a4d8108
AM
16268+/*
16269+ * simple tests for the adding inode operations.
16270+ * following the checks in vfs, plus the parent-child relationship.
16271+ */
16272+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
16273+ struct dentry *h_parent, int isdir)
16274+{
16275+ int err;
16276+ umode_t h_mode;
16277+ struct dentry *h_dentry;
16278+ struct inode *h_inode;
16279+
16280+ err = -ENAMETOOLONG;
16281+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
16282+ goto out;
16283+
16284+ h_dentry = au_h_dptr(dentry, bindex);
16285+ h_inode = h_dentry->d_inode;
16286+ if (!dentry->d_inode) {
16287+ err = -EEXIST;
16288+ if (unlikely(h_inode))
16289+ goto out;
16290+ } else {
16291+ /* rename(2) case */
16292+ err = -EIO;
16293+ if (unlikely(!h_inode || !h_inode->i_nlink))
16294+ goto out;
16295+
16296+ h_mode = h_inode->i_mode;
16297+ if (!isdir) {
16298+ err = -EISDIR;
16299+ if (unlikely(S_ISDIR(h_mode)))
16300+ goto out;
16301+ } else if (unlikely(!S_ISDIR(h_mode))) {
16302+ err = -ENOTDIR;
16303+ goto out;
16304+ }
16305+ }
16306+
16307+ err = 0;
16308+ /* expected parent dir is locked */
16309+ if (unlikely(h_parent != h_dentry->d_parent))
16310+ err = -EIO;
16311+
4f0767ce 16312+out:
4a4d8108
AM
16313+ AuTraceErr(err);
16314+ return err;
16315+}
16316+
16317+/*
16318+ * initial procedure of adding a new entry.
16319+ * prepare writable branch and the parent dir, lock it,
16320+ * and lookup whiteout for the new entry.
16321+ */
16322+static struct dentry*
16323+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
16324+ struct dentry *src_dentry, struct au_pin *pin,
16325+ struct au_wr_dir_args *wr_dir_args)
16326+{
16327+ struct dentry *wh_dentry, *h_parent;
16328+ struct super_block *sb;
16329+ struct au_branch *br;
16330+ int err;
16331+ unsigned int udba;
16332+ aufs_bindex_t bcpup;
16333+
523b37e3 16334+ AuDbg("%pd\n", dentry);
4a4d8108
AM
16335+
16336+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
16337+ bcpup = err;
16338+ wh_dentry = ERR_PTR(err);
16339+ if (unlikely(err < 0))
16340+ goto out;
16341+
16342+ sb = dentry->d_sb;
16343+ udba = au_opt_udba(sb);
16344+ err = au_pin(pin, dentry, bcpup, udba,
16345+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16346+ wh_dentry = ERR_PTR(err);
16347+ if (unlikely(err))
16348+ goto out;
16349+
16350+ h_parent = au_pinned_h_parent(pin);
16351+ if (udba != AuOpt_UDBA_NONE
16352+ && au_dbstart(dentry) == bcpup)
16353+ err = au_may_add(dentry, bcpup, h_parent,
16354+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
16355+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
16356+ err = -ENAMETOOLONG;
16357+ wh_dentry = ERR_PTR(err);
16358+ if (unlikely(err))
16359+ goto out_unpin;
16360+
16361+ br = au_sbr(sb, bcpup);
16362+ if (dt) {
16363+ struct path tmp = {
16364+ .dentry = h_parent,
86dc4139 16365+ .mnt = au_br_mnt(br)
4a4d8108
AM
16366+ };
16367+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
16368+ }
16369+
16370+ wh_dentry = NULL;
16371+ if (bcpup != au_dbwh(dentry))
16372+ goto out; /* success */
16373+
16374+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
16375+
4f0767ce 16376+out_unpin:
4a4d8108
AM
16377+ if (IS_ERR(wh_dentry))
16378+ au_unpin(pin);
4f0767ce 16379+out:
4a4d8108
AM
16380+ return wh_dentry;
16381+}
16382+
16383+/* ---------------------------------------------------------------------- */
16384+
16385+enum { Mknod, Symlink, Creat };
16386+struct simple_arg {
16387+ int type;
16388+ union {
16389+ struct {
7eafdf33 16390+ umode_t mode;
b4510431 16391+ bool want_excl;
4a4d8108
AM
16392+ } c;
16393+ struct {
16394+ const char *symname;
16395+ } s;
16396+ struct {
7eafdf33 16397+ umode_t mode;
4a4d8108
AM
16398+ dev_t dev;
16399+ } m;
16400+ } u;
16401+};
16402+
16403+static int add_simple(struct inode *dir, struct dentry *dentry,
16404+ struct simple_arg *arg)
16405+{
16406+ int err;
16407+ aufs_bindex_t bstart;
16408+ unsigned char created;
4a4d8108
AM
16409+ struct dentry *wh_dentry, *parent;
16410+ struct inode *h_dir;
c2b27bf2
AM
16411+ /* to reuduce stack size */
16412+ struct {
16413+ struct au_dtime dt;
16414+ struct au_pin pin;
16415+ struct path h_path;
16416+ struct au_wr_dir_args wr_dir_args;
16417+ } *a;
4a4d8108 16418+
523b37e3 16419+ AuDbg("%pd\n", dentry);
4a4d8108
AM
16420+ IMustLock(dir);
16421+
c2b27bf2
AM
16422+ err = -ENOMEM;
16423+ a = kmalloc(sizeof(*a), GFP_NOFS);
16424+ if (unlikely(!a))
16425+ goto out;
16426+ a->wr_dir_args.force_btgt = -1;
16427+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
16428+
4a4d8108 16429+ parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
16430+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
16431+ if (unlikely(err))
c2b27bf2 16432+ goto out_free;
027c5e7a
AM
16433+ err = au_d_may_add(dentry);
16434+ if (unlikely(err))
16435+ goto out_unlock;
4a4d8108 16436+ di_write_lock_parent(parent);
c2b27bf2
AM
16437+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
16438+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
16439+ err = PTR_ERR(wh_dentry);
16440+ if (IS_ERR(wh_dentry))
027c5e7a 16441+ goto out_parent;
4a4d8108
AM
16442+
16443+ bstart = au_dbstart(dentry);
c2b27bf2
AM
16444+ a->h_path.dentry = au_h_dptr(dentry, bstart);
16445+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
16446+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
16447+ switch (arg->type) {
16448+ case Creat:
c2b27bf2 16449+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
537831f9 16450+ arg->u.c.want_excl);
4a4d8108
AM
16451+ break;
16452+ case Symlink:
c2b27bf2 16453+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
16454+ break;
16455+ case Mknod:
c2b27bf2
AM
16456+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
16457+ arg->u.m.dev);
4a4d8108
AM
16458+ break;
16459+ default:
16460+ BUG();
16461+ }
16462+ created = !err;
16463+ if (!err)
16464+ err = epilog(dir, bstart, wh_dentry, dentry);
16465+
16466+ /* revert */
c2b27bf2 16467+ if (unlikely(created && err && a->h_path.dentry->d_inode)) {
4a4d8108 16468+ int rerr;
523b37e3
AM
16469+ /* no delegation since it is just created */
16470+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
16471+ /*force*/0);
4a4d8108 16472+ if (rerr) {
523b37e3
AM
16473+ AuIOErr("%pd revert failure(%d, %d)\n",
16474+ dentry, err, rerr);
4a4d8108
AM
16475+ err = -EIO;
16476+ }
c2b27bf2 16477+ au_dtime_revert(&a->dt);
4a4d8108
AM
16478+ }
16479+
c2b27bf2 16480+ au_unpin(&a->pin);
4a4d8108
AM
16481+ dput(wh_dentry);
16482+
027c5e7a
AM
16483+out_parent:
16484+ di_write_unlock(parent);
16485+out_unlock:
4a4d8108
AM
16486+ if (unlikely(err)) {
16487+ au_update_dbstart(dentry);
16488+ d_drop(dentry);
16489+ }
4a4d8108 16490+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
16491+out_free:
16492+ kfree(a);
027c5e7a 16493+out:
4a4d8108
AM
16494+ return err;
16495+}
16496+
7eafdf33
AM
16497+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
16498+ dev_t dev)
4a4d8108
AM
16499+{
16500+ struct simple_arg arg = {
16501+ .type = Mknod,
16502+ .u.m = {
16503+ .mode = mode,
16504+ .dev = dev
16505+ }
16506+ };
16507+ return add_simple(dir, dentry, &arg);
16508+}
16509+
16510+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
16511+{
16512+ struct simple_arg arg = {
16513+ .type = Symlink,
16514+ .u.s.symname = symname
16515+ };
16516+ return add_simple(dir, dentry, &arg);
16517+}
16518+
7eafdf33 16519+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 16520+ bool want_excl)
4a4d8108
AM
16521+{
16522+ struct simple_arg arg = {
16523+ .type = Creat,
16524+ .u.c = {
b4510431
AM
16525+ .mode = mode,
16526+ .want_excl = want_excl
4a4d8108
AM
16527+ }
16528+ };
16529+ return add_simple(dir, dentry, &arg);
16530+}
16531+
16532+/* ---------------------------------------------------------------------- */
16533+
16534+struct au_link_args {
16535+ aufs_bindex_t bdst, bsrc;
16536+ struct au_pin pin;
16537+ struct path h_path;
16538+ struct dentry *src_parent, *parent;
16539+};
16540+
16541+static int au_cpup_before_link(struct dentry *src_dentry,
16542+ struct au_link_args *a)
16543+{
16544+ int err;
16545+ struct dentry *h_src_dentry;
c2b27bf2
AM
16546+ struct au_cp_generic cpg = {
16547+ .dentry = src_dentry,
16548+ .bdst = a->bdst,
16549+ .bsrc = a->bsrc,
16550+ .len = -1,
16551+ .pin = &a->pin,
16552+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
16553+ };
4a4d8108
AM
16554+
16555+ di_read_lock_parent(a->src_parent, AuLock_IR);
16556+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
16557+ if (unlikely(err))
16558+ goto out;
16559+
16560+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
16561+ err = au_pin(&a->pin, src_dentry, a->bdst,
16562+ au_opt_udba(src_dentry->d_sb),
16563+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16564+ if (unlikely(err))
16565+ goto out;
367653fa 16566+
c2b27bf2 16567+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
16568+ au_unpin(&a->pin);
16569+
4f0767ce 16570+out:
4a4d8108
AM
16571+ di_read_unlock(a->src_parent, AuLock_IR);
16572+ return err;
16573+}
16574+
86dc4139
AM
16575+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
16576+ struct au_link_args *a)
4a4d8108
AM
16577+{
16578+ int err;
16579+ unsigned char plink;
86dc4139 16580+ aufs_bindex_t bend;
4a4d8108 16581+ struct dentry *h_src_dentry;
523b37e3 16582+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
16583+ struct super_block *sb;
16584+ struct file *h_file;
16585+
16586+ plink = 0;
16587+ h_inode = NULL;
16588+ sb = src_dentry->d_sb;
16589+ inode = src_dentry->d_inode;
16590+ if (au_ibstart(inode) <= a->bdst)
16591+ h_inode = au_h_iptr(inode, a->bdst);
16592+ if (!h_inode || !h_inode->i_nlink) {
16593+ /* copyup src_dentry as the name of dentry. */
86dc4139
AM
16594+ bend = au_dbend(dentry);
16595+ if (bend < a->bsrc)
16596+ au_set_dbend(dentry, a->bsrc);
16597+ au_set_h_dptr(dentry, a->bsrc,
16598+ dget(au_h_dptr(src_dentry, a->bsrc)));
16599+ dget(a->h_path.dentry);
16600+ au_set_h_dptr(dentry, a->bdst, NULL);
16601+ dentry->d_inode = src_dentry->d_inode; /* tmp */
392086de 16602+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 16603+ if (IS_ERR(h_file))
4a4d8108 16604+ err = PTR_ERR(h_file);
86dc4139 16605+ else {
c2b27bf2
AM
16606+ struct au_cp_generic cpg = {
16607+ .dentry = dentry,
16608+ .bdst = a->bdst,
16609+ .bsrc = -1,
16610+ .len = -1,
16611+ .pin = &a->pin,
16612+ .flags = AuCpup_KEEPLINO
16613+ };
16614+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
16615+ au_h_open_post(dentry, a->bsrc, h_file);
16616+ if (!err) {
16617+ dput(a->h_path.dentry);
16618+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16619+ } else
16620+ au_set_h_dptr(dentry, a->bdst,
16621+ a->h_path.dentry);
16622+ }
16623+ dentry->d_inode = NULL; /* restore */
16624+ au_set_h_dptr(dentry, a->bsrc, NULL);
16625+ au_set_dbend(dentry, bend);
4a4d8108
AM
16626+ } else {
16627+ /* the inode of src_dentry already exists on a.bdst branch */
16628+ h_src_dentry = d_find_alias(h_inode);
16629+ if (!h_src_dentry && au_plink_test(inode)) {
16630+ plink = 1;
16631+ h_src_dentry = au_plink_lkup(inode, a->bdst);
16632+ err = PTR_ERR(h_src_dentry);
16633+ if (IS_ERR(h_src_dentry))
16634+ goto out;
16635+
16636+ if (unlikely(!h_src_dentry->d_inode)) {
16637+ dput(h_src_dentry);
16638+ h_src_dentry = NULL;
16639+ }
16640+
16641+ }
16642+ if (h_src_dentry) {
523b37e3 16643+ delegated = NULL;
4a4d8108 16644+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
16645+ &a->h_path, &delegated);
16646+ if (unlikely(err == -EWOULDBLOCK)) {
16647+ pr_warn("cannot retry for NFSv4 delegation"
16648+ " for an internal link\n");
16649+ iput(delegated);
16650+ }
4a4d8108
AM
16651+ dput(h_src_dentry);
16652+ } else {
16653+ AuIOErr("no dentry found for hi%lu on b%d\n",
16654+ h_inode->i_ino, a->bdst);
16655+ err = -EIO;
16656+ }
16657+ }
16658+
16659+ if (!err && !plink)
16660+ au_plink_append(inode, a->bdst, a->h_path.dentry);
16661+
16662+out:
2cbb1c4b 16663+ AuTraceErr(err);
4a4d8108
AM
16664+ return err;
16665+}
16666+
16667+int aufs_link(struct dentry *src_dentry, struct inode *dir,
16668+ struct dentry *dentry)
16669+{
16670+ int err, rerr;
16671+ struct au_dtime dt;
16672+ struct au_link_args *a;
16673+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 16674+ struct inode *inode, *delegated;
4a4d8108
AM
16675+ struct super_block *sb;
16676+ struct au_wr_dir_args wr_dir_args = {
16677+ /* .force_btgt = -1, */
16678+ .flags = AuWrDir_ADD_ENTRY
16679+ };
16680+
16681+ IMustLock(dir);
16682+ inode = src_dentry->d_inode;
16683+ IMustLock(inode);
16684+
4a4d8108
AM
16685+ err = -ENOMEM;
16686+ a = kzalloc(sizeof(*a), GFP_NOFS);
16687+ if (unlikely(!a))
16688+ goto out;
16689+
16690+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
16691+ err = aufs_read_and_write_lock2(dentry, src_dentry,
16692+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
16693+ if (unlikely(err))
16694+ goto out_kfree;
027c5e7a
AM
16695+ err = au_d_hashed_positive(src_dentry);
16696+ if (unlikely(err))
16697+ goto out_unlock;
16698+ err = au_d_may_add(dentry);
16699+ if (unlikely(err))
16700+ goto out_unlock;
e49829fe 16701+
4a4d8108 16702+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 16703+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
16704+
16705+ di_write_lock_parent(a->parent);
16706+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
16707+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
16708+ &wr_dir_args);
16709+ err = PTR_ERR(wh_dentry);
16710+ if (IS_ERR(wh_dentry))
027c5e7a 16711+ goto out_parent;
4a4d8108
AM
16712+
16713+ err = 0;
16714+ sb = dentry->d_sb;
16715+ a->bdst = au_dbstart(dentry);
16716+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
16717+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
16718+ a->bsrc = au_ibstart(inode);
16719+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16720+ if (!h_src_dentry) {
16721+ a->bsrc = au_dbstart(src_dentry);
16722+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
16723+ AuDebugOn(!h_src_dentry);
16724+ } else if (IS_ERR(h_src_dentry))
16725+ goto out_parent;
16726+
4a4d8108
AM
16727+ if (au_opt_test(au_mntflags(sb), PLINK)) {
16728+ if (a->bdst < a->bsrc
16729+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 16730+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
16731+ else {
16732+ delegated = NULL;
4a4d8108 16733+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
16734+ &a->h_path, &delegated);
16735+ if (unlikely(err == -EWOULDBLOCK)) {
16736+ pr_warn("cannot retry for NFSv4 delegation"
16737+ " for an internal link\n");
16738+ iput(delegated);
16739+ }
16740+ }
2cbb1c4b 16741+ dput(h_src_dentry);
4a4d8108
AM
16742+ } else {
16743+ /*
16744+ * copyup src_dentry to the branch we process,
16745+ * and then link(2) to it.
16746+ */
2cbb1c4b 16747+ dput(h_src_dentry);
4a4d8108
AM
16748+ if (a->bdst < a->bsrc
16749+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
16750+ au_unpin(&a->pin);
16751+ di_write_unlock(a->parent);
16752+ err = au_cpup_before_link(src_dentry, a);
16753+ di_write_lock_parent(a->parent);
16754+ if (!err)
16755+ err = au_pin(&a->pin, dentry, a->bdst,
16756+ au_opt_udba(sb),
16757+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
16758+ if (unlikely(err))
16759+ goto out_wh;
16760+ }
16761+ if (!err) {
16762+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
16763+ err = -ENOENT;
523b37e3
AM
16764+ if (h_src_dentry && h_src_dentry->d_inode) {
16765+ delegated = NULL;
4a4d8108
AM
16766+ err = vfsub_link(h_src_dentry,
16767+ au_pinned_h_dir(&a->pin),
523b37e3
AM
16768+ &a->h_path, &delegated);
16769+ if (unlikely(err == -EWOULDBLOCK)) {
16770+ pr_warn("cannot retry"
16771+ " for NFSv4 delegation"
16772+ " for an internal link\n");
16773+ iput(delegated);
16774+ }
16775+ }
4a4d8108
AM
16776+ }
16777+ }
16778+ if (unlikely(err))
16779+ goto out_unpin;
16780+
16781+ if (wh_dentry) {
16782+ a->h_path.dentry = wh_dentry;
16783+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
16784+ dentry);
16785+ if (unlikely(err))
16786+ goto out_revert;
16787+ }
16788+
16789+ dir->i_version++;
16790+ if (au_ibstart(dir) == au_dbstart(dentry))
16791+ au_cpup_attr_timesizes(dir);
16792+ inc_nlink(inode);
16793+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
16794+ d_instantiate(dentry, au_igrab(inode));
16795+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
16796+ /* some filesystem calls d_drop() */
16797+ d_drop(dentry);
16798+ goto out_unpin; /* success */
16799+
4f0767ce 16800+out_revert:
523b37e3
AM
16801+ /* no delegation since it is just created */
16802+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
16803+ /*delegated*/NULL, /*force*/0);
027c5e7a 16804+ if (unlikely(rerr)) {
523b37e3 16805+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
16806+ err = -EIO;
16807+ }
4a4d8108 16808+ au_dtime_revert(&dt);
4f0767ce 16809+out_unpin:
4a4d8108 16810+ au_unpin(&a->pin);
4f0767ce 16811+out_wh:
4a4d8108 16812+ dput(wh_dentry);
027c5e7a
AM
16813+out_parent:
16814+ di_write_unlock(a->parent);
16815+ dput(a->src_parent);
4f0767ce 16816+out_unlock:
4a4d8108
AM
16817+ if (unlikely(err)) {
16818+ au_update_dbstart(dentry);
16819+ d_drop(dentry);
16820+ }
4a4d8108 16821+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 16822+out_kfree:
4a4d8108 16823+ kfree(a);
4f0767ce 16824+out:
86dc4139 16825+ AuTraceErr(err);
4a4d8108
AM
16826+ return err;
16827+}
16828+
7eafdf33 16829+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
16830+{
16831+ int err, rerr;
16832+ aufs_bindex_t bindex;
16833+ unsigned char diropq;
16834+ struct path h_path;
16835+ struct dentry *wh_dentry, *parent, *opq_dentry;
16836+ struct mutex *h_mtx;
16837+ struct super_block *sb;
16838+ struct {
16839+ struct au_pin pin;
16840+ struct au_dtime dt;
16841+ } *a; /* reduce the stack usage */
16842+ struct au_wr_dir_args wr_dir_args = {
16843+ .force_btgt = -1,
16844+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
16845+ };
16846+
16847+ IMustLock(dir);
16848+
16849+ err = -ENOMEM;
16850+ a = kmalloc(sizeof(*a), GFP_NOFS);
16851+ if (unlikely(!a))
16852+ goto out;
16853+
027c5e7a
AM
16854+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
16855+ if (unlikely(err))
16856+ goto out_free;
16857+ err = au_d_may_add(dentry);
16858+ if (unlikely(err))
16859+ goto out_unlock;
16860+
4a4d8108
AM
16861+ parent = dentry->d_parent; /* dir inode is locked */
16862+ di_write_lock_parent(parent);
16863+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
16864+ &a->pin, &wr_dir_args);
16865+ err = PTR_ERR(wh_dentry);
16866+ if (IS_ERR(wh_dentry))
027c5e7a 16867+ goto out_parent;
4a4d8108
AM
16868+
16869+ sb = dentry->d_sb;
16870+ bindex = au_dbstart(dentry);
16871+ h_path.dentry = au_h_dptr(dentry, bindex);
16872+ h_path.mnt = au_sbr_mnt(sb, bindex);
16873+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
16874+ if (unlikely(err))
027c5e7a 16875+ goto out_unpin;
4a4d8108
AM
16876+
16877+ /* make the dir opaque */
16878+ diropq = 0;
16879+ h_mtx = &h_path.dentry->d_inode->i_mutex;
16880+ if (wh_dentry
16881+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
16882+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16883+ opq_dentry = au_diropq_create(dentry, bindex);
16884+ mutex_unlock(h_mtx);
16885+ err = PTR_ERR(opq_dentry);
16886+ if (IS_ERR(opq_dentry))
16887+ goto out_dir;
16888+ dput(opq_dentry);
16889+ diropq = 1;
16890+ }
16891+
16892+ err = epilog(dir, bindex, wh_dentry, dentry);
16893+ if (!err) {
16894+ inc_nlink(dir);
027c5e7a 16895+ goto out_unpin; /* success */
4a4d8108
AM
16896+ }
16897+
16898+ /* revert */
16899+ if (diropq) {
16900+ AuLabel(revert opq);
16901+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
16902+ rerr = au_diropq_remove(dentry, bindex);
16903+ mutex_unlock(h_mtx);
16904+ if (rerr) {
523b37e3
AM
16905+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
16906+ dentry, err, rerr);
4a4d8108
AM
16907+ err = -EIO;
16908+ }
16909+ }
16910+
4f0767ce 16911+out_dir:
4a4d8108
AM
16912+ AuLabel(revert dir);
16913+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
16914+ if (rerr) {
523b37e3
AM
16915+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
16916+ dentry, err, rerr);
4a4d8108
AM
16917+ err = -EIO;
16918+ }
4a4d8108 16919+ au_dtime_revert(&a->dt);
027c5e7a 16920+out_unpin:
4a4d8108
AM
16921+ au_unpin(&a->pin);
16922+ dput(wh_dentry);
027c5e7a
AM
16923+out_parent:
16924+ di_write_unlock(parent);
16925+out_unlock:
4a4d8108
AM
16926+ if (unlikely(err)) {
16927+ au_update_dbstart(dentry);
16928+ d_drop(dentry);
16929+ }
4a4d8108 16930+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 16931+out_free:
4a4d8108 16932+ kfree(a);
4f0767ce 16933+out:
4a4d8108
AM
16934+ return err;
16935+}
7f207e10
AM
16936diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
16937--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 16938+++ linux/fs/aufs/i_op.c 2014-04-24 22:11:10.851935747 +0200
523b37e3 16939@@ -0,0 +1,1127 @@
4a4d8108 16940+/*
523b37e3 16941+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
16942+ *
16943+ * This program, aufs is free software; you can redistribute it and/or modify
16944+ * it under the terms of the GNU General Public License as published by
16945+ * the Free Software Foundation; either version 2 of the License, or
16946+ * (at your option) any later version.
16947+ *
16948+ * This program is distributed in the hope that it will be useful,
16949+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16950+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16951+ * GNU General Public License for more details.
16952+ *
16953+ * You should have received a copy of the GNU General Public License
523b37e3 16954+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16955+ */
1facf9fc 16956+
1308ab2a 16957+/*
4a4d8108 16958+ * inode operations (except add/del/rename)
1308ab2a 16959+ */
4a4d8108
AM
16960+
16961+#include <linux/device_cgroup.h>
16962+#include <linux/fs_stack.h>
92d182d2 16963+#include <linux/mm.h>
4a4d8108
AM
16964+#include <linux/namei.h>
16965+#include <linux/security.h>
4a4d8108
AM
16966+#include "aufs.h"
16967+
1e00d052 16968+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 16969+ struct vfsmount *h_mnt, int brperm)
1facf9fc 16970+{
1308ab2a 16971+ int err;
4a4d8108 16972+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 16973+
4a4d8108
AM
16974+ err = -EACCES;
16975+ if ((write_mask && IS_IMMUTABLE(h_inode))
16976+ || ((mask & MAY_EXEC)
16977+ && S_ISREG(h_inode->i_mode)
16978+ && ((h_mnt->mnt_flags & MNT_NOEXEC)
16979+ || !(h_inode->i_mode & S_IXUGO))))
16980+ goto out;
16981+
16982+ /*
16983+ * - skip the lower fs test in the case of write to ro branch.
16984+ * - nfs dir permission write check is optimized, but a policy for
16985+ * link/rename requires a real check.
16986+ */
16987+ if ((write_mask && !au_br_writable(brperm))
16988+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
16989+ && write_mask && !(mask & MAY_READ))
16990+ || !h_inode->i_op->permission) {
16991+ /* AuLabel(generic_permission); */
1e00d052 16992+ err = generic_permission(h_inode, mask);
1308ab2a 16993+ } else {
4a4d8108 16994+ /* AuLabel(h_inode->permission); */
1e00d052 16995+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
16996+ AuTraceErr(err);
16997+ }
1facf9fc 16998+
4a4d8108
AM
16999+ if (!err)
17000+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 17001+ if (!err)
4a4d8108 17002+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
17003+
17004+#if 0
17005+ if (!err) {
17006+ /* todo: do we need to call ima_path_check()? */
17007+ struct path h_path = {
17008+ .dentry =
17009+ .mnt = h_mnt
17010+ };
17011+ err = ima_path_check(&h_path,
17012+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
17013+ IMA_COUNT_LEAVE);
1308ab2a 17014+ }
4a4d8108 17015+#endif
dece6358 17016+
4f0767ce 17017+out:
1308ab2a 17018+ return err;
17019+}
dece6358 17020+
1e00d052 17021+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 17022+{
17023+ int err;
4a4d8108
AM
17024+ aufs_bindex_t bindex, bend;
17025+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
17026+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
17027+ struct inode *h_inode;
17028+ struct super_block *sb;
17029+ struct au_branch *br;
1facf9fc 17030+
027c5e7a 17031+ /* todo: support rcu-walk? */
1e00d052 17032+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
17033+ return -ECHILD;
17034+
4a4d8108
AM
17035+ sb = inode->i_sb;
17036+ si_read_lock(sb, AuLock_FLUSH);
17037+ ii_read_lock_child(inode);
027c5e7a
AM
17038+#if 0
17039+ err = au_iigen_test(inode, au_sigen(sb));
17040+ if (unlikely(err))
17041+ goto out;
17042+#endif
dece6358 17043+
4a4d8108
AM
17044+ if (!isdir || write_mask) {
17045+ err = au_busy_or_stale();
17046+ h_inode = au_h_iptr(inode, au_ibstart(inode));
17047+ if (unlikely(!h_inode
17048+ || (h_inode->i_mode & S_IFMT)
17049+ != (inode->i_mode & S_IFMT)))
17050+ goto out;
1facf9fc 17051+
4a4d8108
AM
17052+ err = 0;
17053+ bindex = au_ibstart(inode);
17054+ br = au_sbr(sb, bindex);
86dc4139 17055+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
4a4d8108
AM
17056+ if (write_mask
17057+ && !err
17058+ && !special_file(h_inode->i_mode)) {
17059+ /* test whether the upper writable branch exists */
17060+ err = -EROFS;
17061+ for (; bindex >= 0; bindex--)
17062+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
17063+ err = 0;
17064+ break;
17065+ }
17066+ }
17067+ goto out;
17068+ }
dece6358 17069+
4a4d8108 17070+ /* non-write to dir */
1308ab2a 17071+ err = 0;
4a4d8108
AM
17072+ bend = au_ibend(inode);
17073+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
17074+ h_inode = au_h_iptr(inode, bindex);
17075+ if (h_inode) {
17076+ err = au_busy_or_stale();
17077+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
17078+ break;
17079+
17080+ br = au_sbr(sb, bindex);
86dc4139 17081+ err = h_permission(h_inode, mask, au_br_mnt(br),
4a4d8108
AM
17082+ br->br_perm);
17083+ }
17084+ }
1308ab2a 17085+
4f0767ce 17086+out:
4a4d8108
AM
17087+ ii_read_unlock(inode);
17088+ si_read_unlock(sb);
1308ab2a 17089+ return err;
17090+}
17091+
4a4d8108 17092+/* ---------------------------------------------------------------------- */
1facf9fc 17093+
4a4d8108 17094+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 17095+ unsigned int flags)
4a4d8108
AM
17096+{
17097+ struct dentry *ret, *parent;
b752ccd1 17098+ struct inode *inode;
4a4d8108 17099+ struct super_block *sb;
1716fcea 17100+ int err, npositive;
dece6358 17101+
4a4d8108 17102+ IMustLock(dir);
1308ab2a 17103+
537831f9
AM
17104+ /* todo: support rcu-walk? */
17105+ ret = ERR_PTR(-ECHILD);
17106+ if (flags & LOOKUP_RCU)
17107+ goto out;
17108+
17109+ ret = ERR_PTR(-ENAMETOOLONG);
17110+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17111+ goto out;
17112+
4a4d8108 17113+ sb = dir->i_sb;
7f207e10
AM
17114+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17115+ ret = ERR_PTR(err);
17116+ if (unlikely(err))
17117+ goto out;
17118+
4a4d8108
AM
17119+ err = au_di_init(dentry);
17120+ ret = ERR_PTR(err);
17121+ if (unlikely(err))
7f207e10 17122+ goto out_si;
1308ab2a 17123+
9dbd164d 17124+ inode = NULL;
027c5e7a 17125+ npositive = 0; /* suppress a warning */
4a4d8108
AM
17126+ parent = dentry->d_parent; /* dir inode is locked */
17127+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
17128+ err = au_alive_dir(parent);
17129+ if (!err)
17130+ err = au_digen_test(parent, au_sigen(sb));
17131+ if (!err) {
17132+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 17133+ /*type*/0);
027c5e7a
AM
17134+ err = npositive;
17135+ }
4a4d8108 17136+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
17137+ ret = ERR_PTR(err);
17138+ if (unlikely(err < 0))
17139+ goto out_unlock;
1308ab2a 17140+
4a4d8108 17141+ if (npositive) {
b752ccd1 17142+ inode = au_new_inode(dentry, /*must_new*/0);
4a4d8108 17143+ ret = (void *)inode;
1facf9fc 17144+ }
9dbd164d
AM
17145+ if (IS_ERR(inode)) {
17146+ inode = NULL;
4a4d8108 17147+ goto out_unlock;
9dbd164d 17148+ }
4a4d8108
AM
17149+
17150+ ret = d_splice_alias(inode, dentry);
537831f9
AM
17151+#if 0
17152+ if (unlikely(d_need_lookup(dentry))) {
17153+ spin_lock(&dentry->d_lock);
17154+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
17155+ spin_unlock(&dentry->d_lock);
17156+ } else
17157+#endif
7f207e10 17158+ if (unlikely(IS_ERR(ret) && inode)) {
4a4d8108 17159+ ii_write_unlock(inode);
7f207e10 17160+ iput(inode);
2dfbb274 17161+ inode = NULL;
7f207e10 17162+ }
1facf9fc 17163+
4f0767ce 17164+out_unlock:
4a4d8108 17165+ di_write_unlock(dentry);
2dfbb274 17166+ if (inode) {
1716fcea
AM
17167+ /* verbose coding for lock class name */
17168+ if (unlikely(S_ISLNK(inode->i_mode)))
17169+ au_rw_class(&au_di(dentry)->di_rwsem,
17170+ au_lc_key + AuLcSymlink_DIINFO);
17171+ else if (unlikely(S_ISDIR(inode->i_mode)))
17172+ au_rw_class(&au_di(dentry)->di_rwsem,
17173+ au_lc_key + AuLcDir_DIINFO);
17174+ else /* likely */
17175+ au_rw_class(&au_di(dentry)->di_rwsem,
17176+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 17177+ }
7f207e10 17178+out_si:
4a4d8108 17179+ si_read_unlock(sb);
7f207e10 17180+out:
4a4d8108
AM
17181+ return ret;
17182+}
1facf9fc 17183+
4a4d8108 17184+/* ---------------------------------------------------------------------- */
1facf9fc 17185+
4a4d8108
AM
17186+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
17187+ const unsigned char add_entry, aufs_bindex_t bcpup,
17188+ aufs_bindex_t bstart)
17189+{
17190+ int err;
17191+ struct dentry *h_parent;
17192+ struct inode *h_dir;
1facf9fc 17193+
027c5e7a 17194+ if (add_entry)
4a4d8108 17195+ IMustLock(parent->d_inode);
027c5e7a 17196+ else
4a4d8108
AM
17197+ di_write_lock_parent(parent);
17198+
17199+ err = 0;
17200+ if (!au_h_dptr(parent, bcpup)) {
c2b27bf2
AM
17201+ if (bstart > bcpup)
17202+ err = au_cpup_dirs(dentry, bcpup);
17203+ else if (bstart < bcpup)
4a4d8108
AM
17204+ err = au_cpdown_dirs(dentry, bcpup);
17205+ else
c2b27bf2 17206+ BUG();
4a4d8108
AM
17207+ }
17208+ if (!err && add_entry) {
17209+ h_parent = au_h_dptr(parent, bcpup);
17210+ h_dir = h_parent->d_inode;
17211+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
86dc4139
AM
17212+ err = au_lkup_neg(dentry, bcpup,
17213+ au_ftest_wrdir(add_entry, TMP_WHENTRY));
4a4d8108
AM
17214+ /* todo: no unlock here */
17215+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
17216+
17217+ AuDbg("bcpup %d\n", bcpup);
17218+ if (!err) {
17219+ if (!dentry->d_inode)
17220+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
17221+ au_update_dbrange(dentry, /*do_put_zero*/0);
17222+ }
1308ab2a 17223+ }
1facf9fc 17224+
4a4d8108
AM
17225+ if (!add_entry)
17226+ di_write_unlock(parent);
17227+ if (!err)
17228+ err = bcpup; /* success */
1308ab2a 17229+
027c5e7a 17230+ AuTraceErr(err);
4a4d8108
AM
17231+ return err;
17232+}
1facf9fc 17233+
4a4d8108
AM
17234+/*
17235+ * decide the branch and the parent dir where we will create a new entry.
17236+ * returns new bindex or an error.
17237+ * copyup the parent dir if needed.
17238+ */
17239+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
17240+ struct au_wr_dir_args *args)
17241+{
17242+ int err;
392086de 17243+ unsigned int flags;
4a4d8108 17244+ aufs_bindex_t bcpup, bstart, src_bstart;
86dc4139
AM
17245+ const unsigned char add_entry
17246+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
17247+ | au_ftest_wrdir(args->flags, TMP_WHENTRY);
4a4d8108
AM
17248+ struct super_block *sb;
17249+ struct dentry *parent;
17250+ struct au_sbinfo *sbinfo;
1facf9fc 17251+
4a4d8108
AM
17252+ sb = dentry->d_sb;
17253+ sbinfo = au_sbi(sb);
17254+ parent = dget_parent(dentry);
17255+ bstart = au_dbstart(dentry);
17256+ bcpup = bstart;
17257+ if (args->force_btgt < 0) {
17258+ if (src_dentry) {
17259+ src_bstart = au_dbstart(src_dentry);
17260+ if (src_bstart < bstart)
17261+ bcpup = src_bstart;
17262+ } else if (add_entry) {
392086de
AM
17263+ flags = 0;
17264+ if (au_ftest_wrdir(args->flags, ISDIR))
17265+ au_fset_wbr(flags, DIR);
17266+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
17267+ bcpup = err;
17268+ }
1facf9fc 17269+
4a4d8108
AM
17270+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
17271+ if (add_entry)
17272+ err = AuWbrCopyup(sbinfo, dentry);
17273+ else {
17274+ if (!IS_ROOT(dentry)) {
17275+ di_read_lock_parent(parent, !AuLock_IR);
17276+ err = AuWbrCopyup(sbinfo, dentry);
17277+ di_read_unlock(parent, !AuLock_IR);
17278+ } else
17279+ err = AuWbrCopyup(sbinfo, dentry);
17280+ }
17281+ bcpup = err;
17282+ if (unlikely(err < 0))
17283+ goto out;
17284+ }
17285+ } else {
17286+ bcpup = args->force_btgt;
17287+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
1308ab2a 17288+ }
027c5e7a 17289+
4a4d8108
AM
17290+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
17291+ err = bcpup;
17292+ if (bcpup == bstart)
17293+ goto out; /* success */
4a4d8108
AM
17294+
17295+ /* copyup the new parent into the branch we process */
17296+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
17297+ if (err >= 0) {
17298+ if (!dentry->d_inode) {
17299+ au_set_h_dptr(dentry, bstart, NULL);
17300+ au_set_dbstart(dentry, bcpup);
17301+ au_set_dbend(dentry, bcpup);
17302+ }
17303+ AuDebugOn(add_entry && !au_h_dptr(dentry, bcpup));
17304+ }
86dc4139
AM
17305+
17306+out:
17307+ dput(parent);
17308+ return err;
17309+}
17310+
17311+/* ---------------------------------------------------------------------- */
17312+
17313+void au_pin_hdir_unlock(struct au_pin *p)
17314+{
17315+ if (p->hdir)
17316+ au_hn_imtx_unlock(p->hdir);
17317+}
17318+
17319+static int au_pin_hdir_lock(struct au_pin *p)
17320+{
17321+ int err;
17322+
17323+ err = 0;
17324+ if (!p->hdir)
17325+ goto out;
17326+
17327+ /* even if an error happens later, keep this lock */
17328+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
17329+
17330+ err = -EBUSY;
17331+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
17332+ goto out;
17333+
17334+ err = 0;
17335+ if (p->h_dentry)
17336+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
17337+ p->h_parent, p->br);
17338+
17339+out:
17340+ return err;
17341+}
17342+
17343+int au_pin_hdir_relock(struct au_pin *p)
17344+{
17345+ int err, i;
17346+ struct inode *h_i;
17347+ struct dentry *h_d[] = {
17348+ p->h_dentry,
17349+ p->h_parent
17350+ };
17351+
17352+ err = au_pin_hdir_lock(p);
17353+ if (unlikely(err))
17354+ goto out;
17355+
17356+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
17357+ if (!h_d[i])
17358+ continue;
17359+ h_i = h_d[i]->d_inode;
17360+ if (h_i)
17361+ err = !h_i->i_nlink;
17362+ }
17363+
17364+out:
17365+ return err;
17366+}
17367+
17368+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
17369+{
17370+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
17371+ p->hdir->hi_inode->i_mutex.owner = task;
17372+#endif
17373+}
17374+
17375+void au_pin_hdir_acquire_nest(struct au_pin *p)
17376+{
17377+ if (p->hdir) {
17378+ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
17379+ p->lsc_hi, 0, NULL, _RET_IP_);
17380+ au_pin_hdir_set_owner(p, current);
17381+ }
dece6358 17382+}
1facf9fc 17383+
86dc4139
AM
17384+void au_pin_hdir_release(struct au_pin *p)
17385+{
17386+ if (p->hdir) {
17387+ au_pin_hdir_set_owner(p, p->task);
17388+ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
17389+ }
17390+}
1308ab2a 17391+
4a4d8108 17392+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 17393+{
4a4d8108
AM
17394+ if (pin && pin->parent)
17395+ return au_h_dptr(pin->parent, pin->bindex);
17396+ return NULL;
dece6358 17397+}
1facf9fc 17398+
4a4d8108 17399+void au_unpin(struct au_pin *p)
dece6358 17400+{
86dc4139
AM
17401+ if (p->hdir)
17402+ au_pin_hdir_unlock(p);
e49829fe 17403+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 17404+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
17405+ if (!p->hdir)
17406+ return;
1facf9fc 17407+
4a4d8108
AM
17408+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17409+ di_read_unlock(p->parent, AuLock_IR);
17410+ iput(p->hdir->hi_inode);
17411+ dput(p->parent);
17412+ p->parent = NULL;
17413+ p->hdir = NULL;
17414+ p->h_mnt = NULL;
86dc4139 17415+ /* do not clear p->task */
4a4d8108 17416+}
1308ab2a 17417+
4a4d8108
AM
17418+int au_do_pin(struct au_pin *p)
17419+{
17420+ int err;
17421+ struct super_block *sb;
4a4d8108
AM
17422+ struct inode *h_dir;
17423+
17424+ err = 0;
17425+ sb = p->dentry->d_sb;
86dc4139 17426+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
17427+ if (IS_ROOT(p->dentry)) {
17428+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 17429+ p->h_mnt = au_br_mnt(p->br);
b4510431 17430+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
17431+ if (unlikely(err)) {
17432+ au_fclr_pin(p->flags, MNT_WRITE);
17433+ goto out_err;
17434+ }
17435+ }
dece6358 17436+ goto out;
1facf9fc 17437+ }
17438+
86dc4139 17439+ p->h_dentry = NULL;
4a4d8108 17440+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 17441+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 17442+
4a4d8108
AM
17443+ p->parent = dget_parent(p->dentry);
17444+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17445+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 17446+
4a4d8108 17447+ h_dir = NULL;
86dc4139 17448+ p->h_parent = au_h_dptr(p->parent, p->bindex);
4a4d8108
AM
17449+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
17450+ if (p->hdir)
17451+ h_dir = p->hdir->hi_inode;
dece6358 17452+
b752ccd1
AM
17453+ /*
17454+ * udba case, or
17455+ * if DI_LOCKED is not set, then p->parent may be different
17456+ * and h_parent can be NULL.
17457+ */
86dc4139 17458+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 17459+ err = -EBUSY;
4a4d8108
AM
17460+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17461+ di_read_unlock(p->parent, AuLock_IR);
17462+ dput(p->parent);
17463+ p->parent = NULL;
17464+ goto out_err;
17465+ }
1308ab2a 17466+
4a4d8108 17467+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 17468+ p->h_mnt = au_br_mnt(p->br);
b4510431 17469+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 17470+ if (unlikely(err)) {
4a4d8108 17471+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
17472+ if (!au_ftest_pin(p->flags, DI_LOCKED))
17473+ di_read_unlock(p->parent, AuLock_IR);
17474+ dput(p->parent);
17475+ p->parent = NULL;
17476+ goto out_err;
dece6358
AM
17477+ }
17478+ }
4a4d8108 17479+
86dc4139
AM
17480+ au_igrab(h_dir);
17481+ err = au_pin_hdir_lock(p);
17482+ if (!err)
17483+ goto out; /* success */
17484+
4f0767ce 17485+out_err:
4a4d8108
AM
17486+ pr_err("err %d\n", err);
17487+ err = au_busy_or_stale();
4f0767ce 17488+out:
1facf9fc 17489+ return err;
17490+}
17491+
4a4d8108
AM
17492+void au_pin_init(struct au_pin *p, struct dentry *dentry,
17493+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
17494+ unsigned int udba, unsigned char flags)
17495+{
17496+ p->dentry = dentry;
17497+ p->udba = udba;
17498+ p->lsc_di = lsc_di;
17499+ p->lsc_hi = lsc_hi;
17500+ p->flags = flags;
17501+ p->bindex = bindex;
17502+
17503+ p->parent = NULL;
17504+ p->hdir = NULL;
17505+ p->h_mnt = NULL;
86dc4139
AM
17506+
17507+ p->h_dentry = NULL;
17508+ p->h_parent = NULL;
17509+ p->br = NULL;
17510+ p->task = current;
4a4d8108
AM
17511+}
17512+
17513+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
17514+ unsigned int udba, unsigned char flags)
17515+{
17516+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
17517+ udba, flags);
17518+ return au_do_pin(pin);
17519+}
17520+
dece6358
AM
17521+/* ---------------------------------------------------------------------- */
17522+
1308ab2a 17523+/*
4a4d8108
AM
17524+ * ->setattr() and ->getattr() are called in various cases.
17525+ * chmod, stat: dentry is revalidated.
17526+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
17527+ * unhashed.
17528+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 17529+ */
027c5e7a 17530+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
4a4d8108 17531+static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 17532+{
4a4d8108
AM
17533+ int err;
17534+ struct inode *inode;
17535+ struct dentry *parent;
1facf9fc 17536+
1308ab2a 17537+ err = 0;
4a4d8108 17538+ inode = dentry->d_inode;
027c5e7a 17539+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
17540+ parent = dget_parent(dentry);
17541+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 17542+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
17543+ di_read_unlock(parent, AuLock_IR);
17544+ dput(parent);
dece6358 17545+ }
1facf9fc 17546+
4a4d8108 17547+ AuTraceErr(err);
1308ab2a 17548+ return err;
17549+}
dece6358 17550+
4a4d8108
AM
17551+#define AuIcpup_DID_CPUP 1
17552+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
7f207e10
AM
17553+#define au_fset_icpup(flags, name) \
17554+ do { (flags) |= AuIcpup_##name; } while (0)
17555+#define au_fclr_icpup(flags, name) \
17556+ do { (flags) &= ~AuIcpup_##name; } while (0)
1308ab2a 17557+
4a4d8108
AM
17558+struct au_icpup_args {
17559+ unsigned char flags;
17560+ unsigned char pin_flags;
17561+ aufs_bindex_t btgt;
17562+ unsigned int udba;
17563+ struct au_pin pin;
17564+ struct path h_path;
17565+ struct inode *h_inode;
17566+};
1308ab2a 17567+
4a4d8108
AM
17568+static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
17569+ struct au_icpup_args *a)
1308ab2a 17570+{
17571+ int err;
4a4d8108 17572+ loff_t sz;
e49829fe 17573+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
17574+ struct dentry *hi_wh, *parent;
17575+ struct inode *inode;
4a4d8108
AM
17576+ struct au_wr_dir_args wr_dir_args = {
17577+ .force_btgt = -1,
17578+ .flags = 0
17579+ };
17580+
17581+ bstart = au_dbstart(dentry);
17582+ inode = dentry->d_inode;
17583+ if (S_ISDIR(inode->i_mode))
17584+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
17585+ /* plink or hi_wh() case */
e49829fe 17586+ ibstart = au_ibstart(inode);
027c5e7a 17587+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 17588+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
17589+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17590+ if (unlikely(err < 0))
17591+ goto out;
17592+ a->btgt = err;
17593+ if (err != bstart)
17594+ au_fset_icpup(a->flags, DID_CPUP);
17595+
17596+ err = 0;
17597+ a->pin_flags = AuPin_MNT_WRITE;
17598+ parent = NULL;
17599+ if (!IS_ROOT(dentry)) {
17600+ au_fset_pin(a->pin_flags, DI_LOCKED);
17601+ parent = dget_parent(dentry);
17602+ di_write_lock_parent(parent);
17603+ }
17604+
17605+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
17606+ if (unlikely(err))
17607+ goto out_parent;
17608+
17609+ a->h_path.dentry = au_h_dptr(dentry, bstart);
17610+ a->h_inode = a->h_path.dentry->d_inode;
17611+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
17612+ sz = -1;
17613+ if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
17614+ sz = ia->ia_size;
86dc4139 17615+ mutex_unlock(&a->h_inode->i_mutex);
4a4d8108 17616+
4a4d8108 17617+ hi_wh = NULL;
027c5e7a 17618+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
17619+ hi_wh = au_hi_wh(inode, a->btgt);
17620+ if (!hi_wh) {
c2b27bf2
AM
17621+ struct au_cp_generic cpg = {
17622+ .dentry = dentry,
17623+ .bdst = a->btgt,
17624+ .bsrc = -1,
17625+ .len = sz,
17626+ .pin = &a->pin
17627+ };
17628+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
17629+ if (unlikely(err))
17630+ goto out_unlock;
17631+ hi_wh = au_hi_wh(inode, a->btgt);
17632+ /* todo: revalidate hi_wh? */
17633+ }
17634+ }
17635+
17636+ if (parent) {
17637+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
17638+ di_downgrade_lock(parent, AuLock_IR);
17639+ dput(parent);
17640+ parent = NULL;
17641+ }
17642+ if (!au_ftest_icpup(a->flags, DID_CPUP))
17643+ goto out; /* success */
17644+
17645+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
17646+ struct au_cp_generic cpg = {
17647+ .dentry = dentry,
17648+ .bdst = a->btgt,
17649+ .bsrc = bstart,
17650+ .len = sz,
17651+ .pin = &a->pin,
17652+ .flags = AuCpup_DTIME | AuCpup_HOPEN
17653+ };
17654+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
17655+ if (!err)
17656+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17657+ } else if (!hi_wh)
17658+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
17659+ else
17660+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 17661+
4f0767ce 17662+out_unlock:
4a4d8108 17663+ a->h_inode = a->h_path.dentry->d_inode;
86dc4139 17664+ if (!err)
dece6358 17665+ goto out; /* success */
4a4d8108 17666+ au_unpin(&a->pin);
4f0767ce 17667+out_parent:
4a4d8108
AM
17668+ if (parent) {
17669+ di_write_unlock(parent);
17670+ dput(parent);
17671+ }
4f0767ce 17672+out:
86dc4139
AM
17673+ if (!err)
17674+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 17675+ return err;
17676+}
17677+
4a4d8108 17678+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 17679+{
4a4d8108 17680+ int err;
523b37e3 17681+ struct inode *inode, *delegated;
4a4d8108
AM
17682+ struct super_block *sb;
17683+ struct file *file;
17684+ struct au_icpup_args *a;
1facf9fc 17685+
4a4d8108
AM
17686+ inode = dentry->d_inode;
17687+ IMustLock(inode);
dece6358 17688+
4a4d8108
AM
17689+ err = -ENOMEM;
17690+ a = kzalloc(sizeof(*a), GFP_NOFS);
17691+ if (unlikely(!a))
17692+ goto out;
1facf9fc 17693+
4a4d8108
AM
17694+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
17695+ ia->ia_valid &= ~ATTR_MODE;
dece6358 17696+
4a4d8108
AM
17697+ file = NULL;
17698+ sb = dentry->d_sb;
e49829fe
JR
17699+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17700+ if (unlikely(err))
17701+ goto out_kfree;
17702+
4a4d8108
AM
17703+ if (ia->ia_valid & ATTR_FILE) {
17704+ /* currently ftruncate(2) only */
17705+ AuDebugOn(!S_ISREG(inode->i_mode));
17706+ file = ia->ia_file;
17707+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
17708+ if (unlikely(err))
17709+ goto out_si;
17710+ ia->ia_file = au_hf_top(file);
17711+ a->udba = AuOpt_UDBA_NONE;
17712+ } else {
17713+ /* fchmod() doesn't pass ia_file */
17714+ a->udba = au_opt_udba(sb);
027c5e7a
AM
17715+ di_write_lock_child(dentry);
17716+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
17717+ if (d_unhashed(dentry))
17718+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
17719+ if (a->udba != AuOpt_UDBA_NONE) {
17720+ AuDebugOn(IS_ROOT(dentry));
17721+ err = au_reval_for_attr(dentry, au_sigen(sb));
17722+ if (unlikely(err))
17723+ goto out_dentry;
17724+ }
dece6358 17725+ }
dece6358 17726+
4a4d8108
AM
17727+ err = au_pin_and_icpup(dentry, ia, a);
17728+ if (unlikely(err < 0))
17729+ goto out_dentry;
17730+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
17731+ ia->ia_file = NULL;
17732+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 17733+ }
dece6358 17734+
4a4d8108
AM
17735+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
17736+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
17737+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 17738+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
17739+ if (unlikely(err))
17740+ goto out_unlock;
17741+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
17742+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 17743+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
17744+ if (unlikely(err))
17745+ goto out_unlock;
17746+ }
dece6358 17747+
4a4d8108
AM
17748+ if (ia->ia_valid & ATTR_SIZE) {
17749+ struct file *f;
1308ab2a 17750+
953406b4 17751+ if (ia->ia_size < i_size_read(inode))
4a4d8108 17752+ /* unmap only */
953406b4 17753+ truncate_setsize(inode, ia->ia_size);
1308ab2a 17754+
4a4d8108
AM
17755+ f = NULL;
17756+ if (ia->ia_valid & ATTR_FILE)
17757+ f = ia->ia_file;
17758+ mutex_unlock(&a->h_inode->i_mutex);
17759+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
17760+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
523b37e3
AM
17761+ } else {
17762+ delegated = NULL;
17763+ while (1) {
17764+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
17765+ if (delegated) {
17766+ err = break_deleg_wait(&delegated);
17767+ if (!err)
17768+ continue;
17769+ }
17770+ break;
17771+ }
17772+ }
4a4d8108
AM
17773+ if (!err)
17774+ au_cpup_attr_changeable(inode);
1308ab2a 17775+
4f0767ce 17776+out_unlock:
4a4d8108
AM
17777+ mutex_unlock(&a->h_inode->i_mutex);
17778+ au_unpin(&a->pin);
027c5e7a
AM
17779+ if (unlikely(err))
17780+ au_update_dbstart(dentry);
4f0767ce 17781+out_dentry:
4a4d8108
AM
17782+ di_write_unlock(dentry);
17783+ if (file) {
17784+ fi_write_unlock(file);
17785+ ia->ia_file = file;
17786+ ia->ia_valid |= ATTR_FILE;
17787+ }
4f0767ce 17788+out_si:
4a4d8108 17789+ si_read_unlock(sb);
e49829fe 17790+out_kfree:
4a4d8108 17791+ kfree(a);
4f0767ce 17792+out:
4a4d8108
AM
17793+ AuTraceErr(err);
17794+ return err;
1facf9fc 17795+}
17796+
4a4d8108
AM
17797+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
17798+ unsigned int nlink)
1facf9fc 17799+{
9dbd164d
AM
17800+ unsigned int n;
17801+
4a4d8108 17802+ inode->i_mode = st->mode;
86dc4139
AM
17803+ /* don't i_[ug]id_write() here */
17804+ inode->i_uid = st->uid;
17805+ inode->i_gid = st->gid;
4a4d8108
AM
17806+ inode->i_atime = st->atime;
17807+ inode->i_mtime = st->mtime;
17808+ inode->i_ctime = st->ctime;
1facf9fc 17809+
4a4d8108
AM
17810+ au_cpup_attr_nlink(inode, /*force*/0);
17811+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
17812+ n = inode->i_nlink;
17813+ n -= nlink;
17814+ n += st->nlink;
f6b6e03d 17815+ smp_mb(); /* for i_nlink */
7eafdf33 17816+ /* 0 can happen */
92d182d2 17817+ set_nlink(inode, n);
4a4d8108 17818+ }
1facf9fc 17819+
4a4d8108
AM
17820+ spin_lock(&inode->i_lock);
17821+ inode->i_blocks = st->blocks;
17822+ i_size_write(inode, st->size);
17823+ spin_unlock(&inode->i_lock);
1facf9fc 17824+}
17825+
4a4d8108
AM
17826+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
17827+ struct dentry *dentry, struct kstat *st)
1facf9fc 17828+{
4a4d8108
AM
17829+ int err;
17830+ unsigned int mnt_flags;
17831+ aufs_bindex_t bindex;
17832+ unsigned char udba_none, positive;
17833+ struct super_block *sb, *h_sb;
17834+ struct inode *inode;
c06a8ce3 17835+ struct path h_path;
1facf9fc 17836+
4a4d8108
AM
17837+ sb = dentry->d_sb;
17838+ inode = dentry->d_inode;
7f207e10
AM
17839+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17840+ if (unlikely(err))
17841+ goto out;
4a4d8108
AM
17842+ mnt_flags = au_mntflags(sb);
17843+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 17844+
4a4d8108 17845+ /* support fstat(2) */
027c5e7a 17846+ if (!d_unlinked(dentry) && !udba_none) {
4a4d8108 17847+ unsigned int sigen = au_sigen(sb);
027c5e7a
AM
17848+ err = au_digen_test(dentry, sigen);
17849+ if (!err) {
4a4d8108 17850+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a
AM
17851+ err = au_dbrange_test(dentry);
17852+ if (unlikely(err))
17853+ goto out_unlock;
17854+ } else {
4a4d8108
AM
17855+ AuDebugOn(IS_ROOT(dentry));
17856+ di_write_lock_child(dentry);
027c5e7a
AM
17857+ err = au_dbrange_test(dentry);
17858+ if (!err)
17859+ err = au_reval_for_attr(dentry, sigen);
4a4d8108
AM
17860+ di_downgrade_lock(dentry, AuLock_IR);
17861+ if (unlikely(err))
7f207e10 17862+ goto out_unlock;
4a4d8108
AM
17863+ }
17864+ } else
17865+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 17866+
4a4d8108 17867+ bindex = au_ibstart(inode);
c06a8ce3
AM
17868+ h_path.mnt = au_sbr_mnt(sb, bindex);
17869+ h_sb = h_path.mnt->mnt_sb;
4a4d8108
AM
17870+ if (!au_test_fs_bad_iattr(h_sb) && udba_none)
17871+ goto out_fill; /* success */
1facf9fc 17872+
c06a8ce3 17873+ h_path.dentry = NULL;
4a4d8108 17874+ if (au_dbstart(dentry) == bindex)
c06a8ce3 17875+ h_path.dentry = dget(au_h_dptr(dentry, bindex));
4a4d8108 17876+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c06a8ce3
AM
17877+ h_path.dentry = au_plink_lkup(inode, bindex);
17878+ if (IS_ERR(h_path.dentry))
4a4d8108
AM
17879+ goto out_fill; /* pretending success */
17880+ }
17881+ /* illegally overlapped or something */
c06a8ce3 17882+ if (unlikely(!h_path.dentry))
4a4d8108
AM
17883+ goto out_fill; /* pretending success */
17884+
c06a8ce3 17885+ positive = !!h_path.dentry->d_inode;
4a4d8108 17886+ if (positive)
c06a8ce3
AM
17887+ err = vfs_getattr(&h_path, st);
17888+ dput(h_path.dentry);
4a4d8108
AM
17889+ if (!err) {
17890+ if (positive)
c06a8ce3
AM
17891+ au_refresh_iattr(inode, st,
17892+ h_path.dentry->d_inode->i_nlink);
4a4d8108 17893+ goto out_fill; /* success */
1facf9fc 17894+ }
7f207e10
AM
17895+ AuTraceErr(err);
17896+ goto out_unlock;
4a4d8108 17897+
4f0767ce 17898+out_fill:
4a4d8108 17899+ generic_fillattr(inode, st);
7f207e10 17900+out_unlock:
4a4d8108
AM
17901+ di_read_unlock(dentry, AuLock_IR);
17902+ si_read_unlock(sb);
7f207e10
AM
17903+out:
17904+ AuTraceErr(err);
4a4d8108 17905+ return err;
1facf9fc 17906+}
17907+
17908+/* ---------------------------------------------------------------------- */
17909+
4a4d8108
AM
17910+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
17911+ int bufsiz)
1facf9fc 17912+{
17913+ int err;
4a4d8108
AM
17914+ struct super_block *sb;
17915+ struct dentry *h_dentry;
1facf9fc 17916+
4a4d8108
AM
17917+ err = -EINVAL;
17918+ h_dentry = au_h_dptr(dentry, bindex);
17919+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
17920+ goto out;
1facf9fc 17921+
4a4d8108
AM
17922+ err = security_inode_readlink(h_dentry);
17923+ if (unlikely(err))
dece6358 17924+ goto out;
1facf9fc 17925+
4a4d8108
AM
17926+ sb = dentry->d_sb;
17927+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
17928+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
17929+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
1facf9fc 17930+ }
4a4d8108 17931+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 17932+
4f0767ce 17933+out:
4a4d8108
AM
17934+ return err;
17935+}
1facf9fc 17936+
4a4d8108
AM
17937+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
17938+{
17939+ int err;
1facf9fc 17940+
027c5e7a
AM
17941+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17942+ if (unlikely(err))
17943+ goto out;
17944+ err = au_d_hashed_positive(dentry);
17945+ if (!err)
17946+ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
4a4d8108 17947+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 17948+
027c5e7a 17949+out:
4a4d8108
AM
17950+ return err;
17951+}
1facf9fc 17952+
4a4d8108
AM
17953+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
17954+{
17955+ int err;
4a4d8108 17956+ mm_segment_t old_fs;
b752ccd1
AM
17957+ union {
17958+ char *k;
17959+ char __user *u;
17960+ } buf;
1facf9fc 17961+
4a4d8108 17962+ err = -ENOMEM;
537831f9 17963+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 17964+ if (unlikely(!buf.k))
4a4d8108 17965+ goto out;
1facf9fc 17966+
027c5e7a
AM
17967+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
17968+ if (unlikely(err))
17969+ goto out_name;
17970+
17971+ err = au_d_hashed_positive(dentry);
17972+ if (!err) {
17973+ old_fs = get_fs();
17974+ set_fs(KERNEL_DS);
17975+ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
17976+ set_fs(old_fs);
17977+ }
4a4d8108 17978+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 17979+
4a4d8108 17980+ if (err >= 0) {
b752ccd1 17981+ buf.k[err] = 0;
4a4d8108 17982+ /* will be freed by put_link */
b752ccd1 17983+ nd_set_link(nd, buf.k);
4a4d8108 17984+ return NULL; /* success */
1308ab2a 17985+ }
1facf9fc 17986+
027c5e7a 17987+out_name:
537831f9 17988+ free_page((unsigned long)buf.k);
4f0767ce 17989+out:
4a4d8108
AM
17990+ AuTraceErr(err);
17991+ return ERR_PTR(err);
17992+}
1facf9fc 17993+
4a4d8108
AM
17994+static void aufs_put_link(struct dentry *dentry __maybe_unused,
17995+ struct nameidata *nd, void *cookie __maybe_unused)
17996+{
537831f9
AM
17997+ char *p;
17998+
17999+ p = nd_get_link(nd);
18000+ if (!IS_ERR_OR_NULL(p))
18001+ free_page((unsigned long)p);
4a4d8108 18002+}
1facf9fc 18003+
4a4d8108 18004+/* ---------------------------------------------------------------------- */
1facf9fc 18005+
0c3ec466 18006+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 18007+{
0c3ec466
AM
18008+ int err;
18009+ struct super_block *sb;
18010+ struct inode *h_inode;
18011+
18012+ sb = inode->i_sb;
18013+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
18014+ lockdep_off();
18015+ si_read_lock(sb, AuLock_FLUSH);
18016+ ii_write_lock_child(inode);
18017+ lockdep_on();
18018+ h_inode = au_h_iptr(inode, au_ibstart(inode));
18019+ err = vfsub_update_time(h_inode, ts, flags);
18020+ lockdep_off();
18021+ ii_write_unlock(inode);
18022+ si_read_unlock(sb);
18023+ lockdep_on();
18024+ return err;
4a4d8108 18025+}
1facf9fc 18026+
4a4d8108 18027+/* ---------------------------------------------------------------------- */
1308ab2a 18028+
4a4d8108
AM
18029+struct inode_operations aufs_symlink_iop = {
18030+ .permission = aufs_permission,
18031+ .setattr = aufs_setattr,
18032+ .getattr = aufs_getattr,
0c3ec466 18033+
4a4d8108
AM
18034+ .readlink = aufs_readlink,
18035+ .follow_link = aufs_follow_link,
0c3ec466
AM
18036+ .put_link = aufs_put_link,
18037+
18038+ /* .update_time = aufs_update_time */
4a4d8108
AM
18039+};
18040+
18041+struct inode_operations aufs_dir_iop = {
18042+ .create = aufs_create,
18043+ .lookup = aufs_lookup,
18044+ .link = aufs_link,
18045+ .unlink = aufs_unlink,
18046+ .symlink = aufs_symlink,
18047+ .mkdir = aufs_mkdir,
18048+ .rmdir = aufs_rmdir,
18049+ .mknod = aufs_mknod,
18050+ .rename = aufs_rename,
18051+
18052+ .permission = aufs_permission,
18053+ .setattr = aufs_setattr,
0c3ec466
AM
18054+ .getattr = aufs_getattr,
18055+
18056+ .update_time = aufs_update_time
b4510431 18057+ /* no support for atomic_open() */
4a4d8108
AM
18058+};
18059+
18060+struct inode_operations aufs_iop = {
18061+ .permission = aufs_permission,
18062+ .setattr = aufs_setattr,
18063+ .getattr = aufs_getattr,
0c3ec466
AM
18064+
18065+ .update_time = aufs_update_time
4a4d8108 18066+};
7f207e10
AM
18067diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
18068--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 18069+++ linux/fs/aufs/i_op_del.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 18070@@ -0,0 +1,506 @@
1facf9fc 18071+/*
523b37e3 18072+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 18073+ *
18074+ * This program, aufs is free software; you can redistribute it and/or modify
18075+ * it under the terms of the GNU General Public License as published by
18076+ * the Free Software Foundation; either version 2 of the License, or
18077+ * (at your option) any later version.
dece6358
AM
18078+ *
18079+ * This program is distributed in the hope that it will be useful,
18080+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18081+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18082+ * GNU General Public License for more details.
18083+ *
18084+ * You should have received a copy of the GNU General Public License
523b37e3 18085+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 18086+ */
18087+
18088+/*
4a4d8108 18089+ * inode operations (del entry)
1308ab2a 18090+ */
dece6358 18091+
1308ab2a 18092+#include "aufs.h"
dece6358 18093+
4a4d8108
AM
18094+/*
18095+ * decide if a new whiteout for @dentry is necessary or not.
18096+ * when it is necessary, prepare the parent dir for the upper branch whose
18097+ * branch index is @bcpup for creation. the actual creation of the whiteout will
18098+ * be done by caller.
18099+ * return value:
18100+ * 0: wh is unnecessary
18101+ * plus: wh is necessary
18102+ * minus: error
18103+ */
18104+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 18105+{
4a4d8108
AM
18106+ int need_wh, err;
18107+ aufs_bindex_t bstart;
18108+ struct super_block *sb;
dece6358 18109+
4a4d8108
AM
18110+ sb = dentry->d_sb;
18111+ bstart = au_dbstart(dentry);
18112+ if (*bcpup < 0) {
18113+ *bcpup = bstart;
18114+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
18115+ err = AuWbrCopyup(au_sbi(sb), dentry);
18116+ *bcpup = err;
18117+ if (unlikely(err < 0))
18118+ goto out;
18119+ }
18120+ } else
18121+ AuDebugOn(bstart < *bcpup
18122+ || au_test_ro(sb, *bcpup, dentry->d_inode));
18123+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 18124+
4a4d8108
AM
18125+ if (*bcpup != bstart) {
18126+ err = au_cpup_dirs(dentry, *bcpup);
18127+ if (unlikely(err))
18128+ goto out;
18129+ need_wh = 1;
18130+ } else {
027c5e7a 18131+ struct au_dinfo *dinfo, *tmp;
4a4d8108 18132+
027c5e7a
AM
18133+ need_wh = -ENOMEM;
18134+ dinfo = au_di(dentry);
18135+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
18136+ if (tmp) {
18137+ au_di_cp(tmp, dinfo);
18138+ au_di_swap(tmp, dinfo);
18139+ /* returns the number of positive dentries */
537831f9 18140+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
18141+ au_di_swap(tmp, dinfo);
18142+ au_rw_write_unlock(&tmp->di_rwsem);
18143+ au_di_free(tmp);
4a4d8108
AM
18144+ }
18145+ }
18146+ AuDbg("need_wh %d\n", need_wh);
18147+ err = need_wh;
18148+
4f0767ce 18149+out:
4a4d8108 18150+ return err;
1facf9fc 18151+}
18152+
4a4d8108
AM
18153+/*
18154+ * simple tests for the del-entry operations.
18155+ * following the checks in vfs, plus the parent-child relationship.
18156+ */
18157+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
18158+ struct dentry *h_parent, int isdir)
1facf9fc 18159+{
4a4d8108
AM
18160+ int err;
18161+ umode_t h_mode;
18162+ struct dentry *h_dentry, *h_latest;
1308ab2a 18163+ struct inode *h_inode;
1facf9fc 18164+
4a4d8108
AM
18165+ h_dentry = au_h_dptr(dentry, bindex);
18166+ h_inode = h_dentry->d_inode;
18167+ if (dentry->d_inode) {
18168+ err = -ENOENT;
18169+ if (unlikely(!h_inode || !h_inode->i_nlink))
18170+ goto out;
1facf9fc 18171+
4a4d8108
AM
18172+ h_mode = h_inode->i_mode;
18173+ if (!isdir) {
18174+ err = -EISDIR;
18175+ if (unlikely(S_ISDIR(h_mode)))
18176+ goto out;
18177+ } else if (unlikely(!S_ISDIR(h_mode))) {
18178+ err = -ENOTDIR;
18179+ goto out;
18180+ }
18181+ } else {
18182+ /* rename(2) case */
18183+ err = -EIO;
18184+ if (unlikely(h_inode))
18185+ goto out;
18186+ }
1facf9fc 18187+
4a4d8108
AM
18188+ err = -ENOENT;
18189+ /* expected parent dir is locked */
18190+ if (unlikely(h_parent != h_dentry->d_parent))
18191+ goto out;
18192+ err = 0;
18193+
18194+ /*
18195+ * rmdir a dir may break the consistency on some filesystem.
18196+ * let's try heavy test.
18197+ */
18198+ err = -EACCES;
18199+ if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
18200+ goto out;
18201+
18202+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
18203+ au_sbr(dentry->d_sb, bindex));
18204+ err = -EIO;
18205+ if (IS_ERR(h_latest))
18206+ goto out;
18207+ if (h_latest == h_dentry)
18208+ err = 0;
18209+ dput(h_latest);
18210+
4f0767ce 18211+out:
4a4d8108 18212+ return err;
1308ab2a 18213+}
1facf9fc 18214+
4a4d8108
AM
18215+/*
18216+ * decide the branch where we operate for @dentry. the branch index will be set
18217+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
18218+ * dir for reverting.
18219+ * when a new whiteout is necessary, create it.
18220+ */
18221+static struct dentry*
18222+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
18223+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 18224+{
4a4d8108
AM
18225+ struct dentry *wh_dentry;
18226+ struct super_block *sb;
18227+ struct path h_path;
18228+ int err, need_wh;
18229+ unsigned int udba;
18230+ aufs_bindex_t bcpup;
dece6358 18231+
4a4d8108
AM
18232+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
18233+ wh_dentry = ERR_PTR(need_wh);
18234+ if (unlikely(need_wh < 0))
18235+ goto out;
18236+
18237+ sb = dentry->d_sb;
18238+ udba = au_opt_udba(sb);
18239+ bcpup = *rbcpup;
18240+ err = au_pin(pin, dentry, bcpup, udba,
18241+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
18242+ wh_dentry = ERR_PTR(err);
18243+ if (unlikely(err))
18244+ goto out;
18245+
18246+ h_path.dentry = au_pinned_h_parent(pin);
18247+ if (udba != AuOpt_UDBA_NONE
18248+ && au_dbstart(dentry) == bcpup) {
18249+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
18250+ wh_dentry = ERR_PTR(err);
18251+ if (unlikely(err))
18252+ goto out_unpin;
18253+ }
18254+
18255+ h_path.mnt = au_sbr_mnt(sb, bcpup);
18256+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
18257+ wh_dentry = NULL;
18258+ if (!need_wh)
18259+ goto out; /* success, no need to create whiteout */
18260+
18261+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
18262+ if (IS_ERR(wh_dentry))
18263+ goto out_unpin;
18264+
18265+ /* returns with the parent is locked and wh_dentry is dget-ed */
18266+ goto out; /* success */
18267+
4f0767ce 18268+out_unpin:
4a4d8108 18269+ au_unpin(pin);
4f0767ce 18270+out:
4a4d8108 18271+ return wh_dentry;
1facf9fc 18272+}
18273+
4a4d8108
AM
18274+/*
18275+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
18276+ * in order to be revertible and save time for removing many child whiteouts
18277+ * under the dir.
18278+ * returns 1 when there are too many child whiteout and caller should remove
18279+ * them asynchronously. returns 0 when the number of children is enough small to
18280+ * remove now or the branch fs is a remote fs.
18281+ * otherwise return an error.
18282+ */
18283+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
18284+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 18285+{
4a4d8108
AM
18286+ int rmdir_later, err, dirwh;
18287+ struct dentry *h_dentry;
18288+ struct super_block *sb;
18289+
18290+ sb = dentry->d_sb;
18291+ SiMustAnyLock(sb);
18292+ h_dentry = au_h_dptr(dentry, bindex);
18293+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
18294+ if (unlikely(err))
18295+ goto out;
18296+
18297+ /* stop monitoring */
18298+ au_hn_free(au_hi(dentry->d_inode, bindex));
18299+
18300+ if (!au_test_fs_remote(h_dentry->d_sb)) {
18301+ dirwh = au_sbi(sb)->si_dirwh;
18302+ rmdir_later = (dirwh <= 1);
18303+ if (!rmdir_later)
18304+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
18305+ dirwh);
18306+ if (rmdir_later)
18307+ return rmdir_later;
18308+ }
1facf9fc 18309+
4a4d8108
AM
18310+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
18311+ if (unlikely(err)) {
523b37e3
AM
18312+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
18313+ h_dentry, bindex, err);
4a4d8108
AM
18314+ err = 0;
18315+ }
dece6358 18316+
4f0767ce 18317+out:
4a4d8108
AM
18318+ AuTraceErr(err);
18319+ return err;
18320+}
1308ab2a 18321+
4a4d8108
AM
18322+/*
18323+ * final procedure for deleting a entry.
18324+ * maintain dentry and iattr.
18325+ */
18326+static void epilog(struct inode *dir, struct dentry *dentry,
18327+ aufs_bindex_t bindex)
18328+{
18329+ struct inode *inode;
1308ab2a 18330+
4a4d8108
AM
18331+ inode = dentry->d_inode;
18332+ d_drop(dentry);
18333+ inode->i_ctime = dir->i_ctime;
1308ab2a 18334+
4a4d8108
AM
18335+ if (au_ibstart(dir) == bindex)
18336+ au_cpup_attr_timesizes(dir);
18337+ dir->i_version++;
1facf9fc 18338+}
18339+
4a4d8108
AM
18340+/*
18341+ * when an error happened, remove the created whiteout and revert everything.
18342+ */
7f207e10
AM
18343+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
18344+ aufs_bindex_t bwh, struct dentry *wh_dentry,
18345+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 18346+{
4a4d8108
AM
18347+ int rerr;
18348+ struct path h_path = {
18349+ .dentry = wh_dentry,
7f207e10 18350+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 18351+ };
dece6358 18352+
7f207e10 18353+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
18354+ if (!rerr) {
18355+ au_set_dbwh(dentry, bwh);
18356+ au_dtime_revert(dt);
18357+ return 0;
18358+ }
dece6358 18359+
523b37e3 18360+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 18361+ return -EIO;
1facf9fc 18362+}
18363+
4a4d8108 18364+/* ---------------------------------------------------------------------- */
1facf9fc 18365+
4a4d8108 18366+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 18367+{
4a4d8108
AM
18368+ int err;
18369+ aufs_bindex_t bwh, bindex, bstart;
523b37e3 18370+ struct inode *inode, *h_dir, *delegated;
4a4d8108 18371+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
18372+ /* to reuduce stack size */
18373+ struct {
18374+ struct au_dtime dt;
18375+ struct au_pin pin;
18376+ struct path h_path;
18377+ } *a;
1facf9fc 18378+
4a4d8108 18379+ IMustLock(dir);
027c5e7a 18380+
c2b27bf2
AM
18381+ err = -ENOMEM;
18382+ a = kmalloc(sizeof(*a), GFP_NOFS);
18383+ if (unlikely(!a))
18384+ goto out;
18385+
027c5e7a
AM
18386+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
18387+ if (unlikely(err))
c2b27bf2 18388+ goto out_free;
027c5e7a
AM
18389+ err = au_d_hashed_positive(dentry);
18390+ if (unlikely(err))
18391+ goto out_unlock;
4a4d8108 18392+ inode = dentry->d_inode;
4a4d8108 18393+ IMustLock(inode);
027c5e7a
AM
18394+ err = -EISDIR;
18395+ if (unlikely(S_ISDIR(inode->i_mode)))
18396+ goto out_unlock; /* possible? */
1facf9fc 18397+
4a4d8108
AM
18398+ bstart = au_dbstart(dentry);
18399+ bwh = au_dbwh(dentry);
18400+ bindex = -1;
027c5e7a
AM
18401+ parent = dentry->d_parent; /* dir inode is locked */
18402+ di_write_lock_parent(parent);
c2b27bf2
AM
18403+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
18404+ &a->pin);
4a4d8108
AM
18405+ err = PTR_ERR(wh_dentry);
18406+ if (IS_ERR(wh_dentry))
027c5e7a 18407+ goto out_parent;
1facf9fc 18408+
c2b27bf2
AM
18409+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
18410+ a->h_path.dentry = au_h_dptr(dentry, bstart);
18411+ dget(a->h_path.dentry);
4a4d8108 18412+ if (bindex == bstart) {
c2b27bf2 18413+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
18414+ delegated = NULL;
18415+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
18416+ if (unlikely(err == -EWOULDBLOCK)) {
18417+ pr_warn("cannot retry for NFSv4 delegation"
18418+ " for an internal unlink\n");
18419+ iput(delegated);
18420+ }
4a4d8108
AM
18421+ } else {
18422+ /* dir inode is locked */
18423+ h_dir = wh_dentry->d_parent->d_inode;
18424+ IMustLock(h_dir);
18425+ err = 0;
18426+ }
dece6358 18427+
4a4d8108 18428+ if (!err) {
7f207e10 18429+ vfsub_drop_nlink(inode);
4a4d8108
AM
18430+ epilog(dir, dentry, bindex);
18431+
18432+ /* update target timestamps */
18433+ if (bindex == bstart) {
c2b27bf2
AM
18434+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
18435+ /*ignore*/
18436+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
4a4d8108
AM
18437+ } else
18438+ /* todo: this timestamp may be reverted later */
18439+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 18440+ goto out_unpin; /* success */
1facf9fc 18441+ }
18442+
4a4d8108
AM
18443+ /* revert */
18444+ if (wh_dentry) {
18445+ int rerr;
18446+
c2b27bf2
AM
18447+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
18448+ &a->dt);
4a4d8108
AM
18449+ if (rerr)
18450+ err = rerr;
dece6358 18451+ }
1facf9fc 18452+
027c5e7a 18453+out_unpin:
c2b27bf2 18454+ au_unpin(&a->pin);
4a4d8108 18455+ dput(wh_dentry);
c2b27bf2 18456+ dput(a->h_path.dentry);
027c5e7a 18457+out_parent:
4a4d8108 18458+ di_write_unlock(parent);
027c5e7a 18459+out_unlock:
4a4d8108 18460+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
18461+out_free:
18462+ kfree(a);
027c5e7a 18463+out:
4a4d8108 18464+ return err;
dece6358
AM
18465+}
18466+
4a4d8108 18467+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 18468+{
4a4d8108
AM
18469+ int err, rmdir_later;
18470+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
18471+ struct inode *inode;
18472+ struct dentry *parent, *wh_dentry, *h_dentry;
18473+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
18474+ /* to reuduce stack size */
18475+ struct {
18476+ struct au_dtime dt;
18477+ struct au_pin pin;
18478+ } *a;
1facf9fc 18479+
4a4d8108 18480+ IMustLock(dir);
027c5e7a 18481+
c2b27bf2
AM
18482+ err = -ENOMEM;
18483+ a = kmalloc(sizeof(*a), GFP_NOFS);
18484+ if (unlikely(!a))
18485+ goto out;
18486+
027c5e7a
AM
18487+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
18488+ if (unlikely(err))
c2b27bf2 18489+ goto out_free;
53392da6
AM
18490+ err = au_alive_dir(dentry);
18491+ if (unlikely(err))
027c5e7a 18492+ goto out_unlock;
53392da6 18493+ inode = dentry->d_inode;
4a4d8108 18494+ IMustLock(inode);
027c5e7a
AM
18495+ err = -ENOTDIR;
18496+ if (unlikely(!S_ISDIR(inode->i_mode)))
18497+ goto out_unlock; /* possible? */
dece6358 18498+
4a4d8108
AM
18499+ err = -ENOMEM;
18500+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
18501+ if (unlikely(!args))
18502+ goto out_unlock;
dece6358 18503+
4a4d8108
AM
18504+ parent = dentry->d_parent; /* dir inode is locked */
18505+ di_write_lock_parent(parent);
18506+ err = au_test_empty(dentry, &args->whlist);
18507+ if (unlikely(err))
027c5e7a 18508+ goto out_parent;
1facf9fc 18509+
4a4d8108
AM
18510+ bstart = au_dbstart(dentry);
18511+ bwh = au_dbwh(dentry);
18512+ bindex = -1;
c2b27bf2
AM
18513+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
18514+ &a->pin);
4a4d8108
AM
18515+ err = PTR_ERR(wh_dentry);
18516+ if (IS_ERR(wh_dentry))
027c5e7a 18517+ goto out_parent;
1facf9fc 18518+
4a4d8108
AM
18519+ h_dentry = au_h_dptr(dentry, bstart);
18520+ dget(h_dentry);
18521+ rmdir_later = 0;
18522+ if (bindex == bstart) {
18523+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
18524+ if (err > 0) {
18525+ rmdir_later = err;
18526+ err = 0;
18527+ }
18528+ } else {
18529+ /* stop monitoring */
18530+ au_hn_free(au_hi(inode, bstart));
18531+
18532+ /* dir inode is locked */
18533+ IMustLock(wh_dentry->d_parent->d_inode);
1facf9fc 18534+ err = 0;
18535+ }
18536+
4a4d8108 18537+ if (!err) {
027c5e7a 18538+ vfsub_dead_dir(inode);
4a4d8108
AM
18539+ au_set_dbdiropq(dentry, -1);
18540+ epilog(dir, dentry, bindex);
1308ab2a 18541+
4a4d8108
AM
18542+ if (rmdir_later) {
18543+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
18544+ args = NULL;
18545+ }
1308ab2a 18546+
4a4d8108 18547+ goto out_unpin; /* success */
1facf9fc 18548+ }
18549+
4a4d8108
AM
18550+ /* revert */
18551+ AuLabel(revert);
18552+ if (wh_dentry) {
18553+ int rerr;
1308ab2a 18554+
c2b27bf2
AM
18555+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
18556+ &a->dt);
4a4d8108
AM
18557+ if (rerr)
18558+ err = rerr;
1facf9fc 18559+ }
18560+
4f0767ce 18561+out_unpin:
c2b27bf2 18562+ au_unpin(&a->pin);
4a4d8108
AM
18563+ dput(wh_dentry);
18564+ dput(h_dentry);
027c5e7a 18565+out_parent:
4a4d8108
AM
18566+ di_write_unlock(parent);
18567+ if (args)
18568+ au_whtmp_rmdir_free(args);
4f0767ce 18569+out_unlock:
4a4d8108 18570+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
18571+out_free:
18572+ kfree(a);
4f0767ce 18573+out:
4a4d8108
AM
18574+ AuTraceErr(err);
18575+ return err;
dece6358 18576+}
7f207e10
AM
18577diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
18578--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 18579+++ linux/fs/aufs/i_op_ren.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 18580@@ -0,0 +1,1032 @@
1facf9fc 18581+/*
523b37e3 18582+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 18583+ *
18584+ * This program, aufs is free software; you can redistribute it and/or modify
18585+ * it under the terms of the GNU General Public License as published by
18586+ * the Free Software Foundation; either version 2 of the License, or
18587+ * (at your option) any later version.
dece6358
AM
18588+ *
18589+ * This program is distributed in the hope that it will be useful,
18590+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18591+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18592+ * GNU General Public License for more details.
18593+ *
18594+ * You should have received a copy of the GNU General Public License
523b37e3 18595+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 18596+ */
18597+
18598+/*
4a4d8108
AM
18599+ * inode operation (rename entry)
18600+ * todo: this is crazy monster
1facf9fc 18601+ */
18602+
18603+#include "aufs.h"
18604+
4a4d8108
AM
18605+enum { AuSRC, AuDST, AuSrcDst };
18606+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 18607+
4a4d8108
AM
18608+#define AuRen_ISDIR 1
18609+#define AuRen_ISSAMEDIR (1 << 1)
18610+#define AuRen_WHSRC (1 << 2)
18611+#define AuRen_WHDST (1 << 3)
18612+#define AuRen_MNT_WRITE (1 << 4)
18613+#define AuRen_DT_DSTDIR (1 << 5)
18614+#define AuRen_DIROPQ (1 << 6)
18615+#define AuRen_CPUP (1 << 7)
18616+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
18617+#define au_fset_ren(flags, name) \
18618+ do { (flags) |= AuRen_##name; } while (0)
18619+#define au_fclr_ren(flags, name) \
18620+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 18621+
4a4d8108
AM
18622+struct au_ren_args {
18623+ struct {
18624+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
18625+ *wh_dentry;
18626+ struct inode *dir, *inode;
18627+ struct au_hinode *hdir;
18628+ struct au_dtime dt[AuParentChild];
18629+ aufs_bindex_t bstart;
18630+ } sd[AuSrcDst];
1facf9fc 18631+
4a4d8108
AM
18632+#define src_dentry sd[AuSRC].dentry
18633+#define src_dir sd[AuSRC].dir
18634+#define src_inode sd[AuSRC].inode
18635+#define src_h_dentry sd[AuSRC].h_dentry
18636+#define src_parent sd[AuSRC].parent
18637+#define src_h_parent sd[AuSRC].h_parent
18638+#define src_wh_dentry sd[AuSRC].wh_dentry
18639+#define src_hdir sd[AuSRC].hdir
18640+#define src_h_dir sd[AuSRC].hdir->hi_inode
18641+#define src_dt sd[AuSRC].dt
18642+#define src_bstart sd[AuSRC].bstart
1facf9fc 18643+
4a4d8108
AM
18644+#define dst_dentry sd[AuDST].dentry
18645+#define dst_dir sd[AuDST].dir
18646+#define dst_inode sd[AuDST].inode
18647+#define dst_h_dentry sd[AuDST].h_dentry
18648+#define dst_parent sd[AuDST].parent
18649+#define dst_h_parent sd[AuDST].h_parent
18650+#define dst_wh_dentry sd[AuDST].wh_dentry
18651+#define dst_hdir sd[AuDST].hdir
18652+#define dst_h_dir sd[AuDST].hdir->hi_inode
18653+#define dst_dt sd[AuDST].dt
18654+#define dst_bstart sd[AuDST].bstart
18655+
18656+ struct dentry *h_trap;
18657+ struct au_branch *br;
18658+ struct au_hinode *src_hinode;
18659+ struct path h_path;
18660+ struct au_nhash whlist;
027c5e7a 18661+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 18662+
1308ab2a 18663+ unsigned int flags;
1facf9fc 18664+
4a4d8108
AM
18665+ struct au_whtmp_rmdir *thargs;
18666+ struct dentry *h_dst;
18667+};
1308ab2a 18668+
4a4d8108 18669+/* ---------------------------------------------------------------------- */
1308ab2a 18670+
4a4d8108
AM
18671+/*
18672+ * functions for reverting.
18673+ * when an error happened in a single rename systemcall, we should revert
18674+ * everything as if nothing happend.
18675+ * we don't need to revert the copied-up/down the parent dir since they are
18676+ * harmless.
18677+ */
1facf9fc 18678+
4a4d8108
AM
18679+#define RevertFailure(fmt, ...) do { \
18680+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
18681+ ##__VA_ARGS__, err, rerr); \
18682+ err = -EIO; \
18683+} while (0)
1facf9fc 18684+
4a4d8108 18685+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 18686+{
4a4d8108 18687+ int rerr;
1facf9fc 18688+
4a4d8108
AM
18689+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18690+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
18691+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 18692+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108 18693+ if (rerr)
523b37e3 18694+ RevertFailure("remove diropq %pd", a->src_dentry);
4a4d8108 18695+}
1facf9fc 18696+
4a4d8108
AM
18697+static void au_ren_rev_rename(int err, struct au_ren_args *a)
18698+{
18699+ int rerr;
523b37e3 18700+ struct inode *delegated;
1facf9fc 18701+
b4510431
AM
18702+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
18703+ a->src_h_parent);
4a4d8108
AM
18704+ rerr = PTR_ERR(a->h_path.dentry);
18705+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 18706+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 18707+ return;
1facf9fc 18708+ }
18709+
523b37e3 18710+ delegated = NULL;
4a4d8108
AM
18711+ rerr = vfsub_rename(a->dst_h_dir,
18712+ au_h_dptr(a->src_dentry, a->btgt),
523b37e3
AM
18713+ a->src_h_dir, &a->h_path, &delegated);
18714+ if (unlikely(rerr == -EWOULDBLOCK)) {
18715+ pr_warn("cannot retry for NFSv4 delegation"
18716+ " for an internal rename\n");
18717+ iput(delegated);
18718+ }
4a4d8108
AM
18719+ d_drop(a->h_path.dentry);
18720+ dput(a->h_path.dentry);
18721+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
18722+ if (rerr)
523b37e3 18723+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 18724+}
18725+
4a4d8108 18726+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
1facf9fc 18727+{
4a4d8108 18728+ int rerr;
1facf9fc 18729+
4a4d8108 18730+ a->h_path.dentry = a->dst_h_dentry;
523b37e3
AM
18731+ /* no delegation since it is just created */
18732+ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*delegated*/NULL,
18733+ /*force*/0);
4a4d8108
AM
18734+ au_set_h_dptr(a->src_dentry, a->btgt, NULL);
18735+ au_set_dbstart(a->src_dentry, a->src_bstart);
18736+ if (rerr)
523b37e3 18737+ RevertFailure("unlink %pd", a->dst_h_dentry);
1facf9fc 18738+}
18739+
4a4d8108 18740+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 18741+{
4a4d8108 18742+ int rerr;
523b37e3 18743+ struct inode *delegated;
dece6358 18744+
b4510431
AM
18745+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
18746+ a->dst_h_parent);
4a4d8108
AM
18747+ rerr = PTR_ERR(a->h_path.dentry);
18748+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 18749+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
18750+ return;
18751+ }
18752+ if (a->h_path.dentry->d_inode) {
18753+ d_drop(a->h_path.dentry);
18754+ dput(a->h_path.dentry);
18755+ return;
dece6358
AM
18756+ }
18757+
523b37e3
AM
18758+ delegated = NULL;
18759+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
18760+ &delegated);
18761+ if (unlikely(rerr == -EWOULDBLOCK)) {
18762+ pr_warn("cannot retry for NFSv4 delegation"
18763+ " for an internal rename\n");
18764+ iput(delegated);
18765+ }
4a4d8108
AM
18766+ d_drop(a->h_path.dentry);
18767+ dput(a->h_path.dentry);
18768+ if (!rerr)
18769+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
18770+ else
523b37e3 18771+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 18772+}
1308ab2a 18773+
4a4d8108
AM
18774+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
18775+{
18776+ int rerr;
1308ab2a 18777+
4a4d8108
AM
18778+ a->h_path.dentry = a->src_wh_dentry;
18779+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 18780+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 18781+ if (rerr)
523b37e3 18782+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 18783+}
4a4d8108 18784+#undef RevertFailure
1facf9fc 18785+
1308ab2a 18786+/* ---------------------------------------------------------------------- */
18787+
4a4d8108
AM
18788+/*
18789+ * when we have to copyup the renaming entry, do it with the rename-target name
18790+ * in order to minimize the cost (the later actual rename is unnecessary).
18791+ * otherwise rename it on the target branch.
18792+ */
18793+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 18794+{
dece6358 18795+ int err;
4a4d8108 18796+ struct dentry *d;
523b37e3 18797+ struct inode *delegated;
1facf9fc 18798+
4a4d8108
AM
18799+ d = a->src_dentry;
18800+ if (au_dbstart(d) == a->btgt) {
18801+ a->h_path.dentry = a->dst_h_dentry;
18802+ if (au_ftest_ren(a->flags, DIROPQ)
18803+ && au_dbdiropq(d) == a->btgt)
18804+ au_fclr_ren(a->flags, DIROPQ);
18805+ AuDebugOn(au_dbstart(d) != a->btgt);
523b37e3 18806+ delegated = NULL;
4a4d8108 18807+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
523b37e3
AM
18808+ a->dst_h_dir, &a->h_path, &delegated);
18809+ if (unlikely(err == -EWOULDBLOCK)) {
18810+ pr_warn("cannot retry for NFSv4 delegation"
18811+ " for an internal rename\n");
18812+ iput(delegated);
18813+ }
c2b27bf2 18814+ } else
86dc4139 18815+ BUG();
1308ab2a 18816+
027c5e7a
AM
18817+ if (!err && a->h_dst)
18818+ /* it will be set to dinfo later */
18819+ dget(a->h_dst);
1facf9fc 18820+
dece6358
AM
18821+ return err;
18822+}
1facf9fc 18823+
4a4d8108
AM
18824+/* cf. aufs_rmdir() */
18825+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 18826+{
4a4d8108
AM
18827+ int err;
18828+ struct inode *dir;
1facf9fc 18829+
4a4d8108
AM
18830+ dir = a->dst_dir;
18831+ SiMustAnyLock(dir->i_sb);
18832+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
18833+ au_sbi(dir->i_sb)->si_dirwh)
18834+ || au_test_fs_remote(a->h_dst->d_sb)) {
18835+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
18836+ if (unlikely(err))
523b37e3
AM
18837+ pr_warn("failed removing whtmp dir %pd (%d), "
18838+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
18839+ } else {
18840+ au_nhash_wh_free(&a->thargs->whlist);
18841+ a->thargs->whlist = a->whlist;
18842+ a->whlist.nh_num = 0;
18843+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
18844+ dput(a->h_dst);
18845+ a->thargs = NULL;
18846+ }
18847+
18848+ return 0;
1308ab2a 18849+}
1facf9fc 18850+
4a4d8108
AM
18851+/* make it 'opaque' dir. */
18852+static int au_ren_diropq(struct au_ren_args *a)
18853+{
18854+ int err;
18855+ struct dentry *diropq;
1facf9fc 18856+
4a4d8108 18857+ err = 0;
027c5e7a 18858+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
18859+ a->src_hinode = au_hi(a->src_inode, a->btgt);
18860+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
18861+ diropq = au_diropq_create(a->src_dentry, a->btgt);
18862+ au_hn_imtx_unlock(a->src_hinode);
18863+ if (IS_ERR(diropq))
18864+ err = PTR_ERR(diropq);
18865+ dput(diropq);
1facf9fc 18866+
4a4d8108
AM
18867+ return err;
18868+}
1facf9fc 18869+
4a4d8108
AM
18870+static int do_rename(struct au_ren_args *a)
18871+{
18872+ int err;
18873+ struct dentry *d, *h_d;
1facf9fc 18874+
4a4d8108
AM
18875+ /* prepare workqueue args for asynchronous rmdir */
18876+ h_d = a->dst_h_dentry;
18877+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
18878+ err = -ENOMEM;
18879+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
18880+ if (unlikely(!a->thargs))
18881+ goto out;
18882+ a->h_dst = dget(h_d);
18883+ }
1facf9fc 18884+
4a4d8108
AM
18885+ /* create whiteout for src_dentry */
18886+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
18887+ a->src_bwh = au_dbwh(a->src_dentry);
18888+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
18889+ a->src_wh_dentry
18890+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
18891+ err = PTR_ERR(a->src_wh_dentry);
18892+ if (IS_ERR(a->src_wh_dentry))
18893+ goto out_thargs;
18894+ }
1facf9fc 18895+
4a4d8108
AM
18896+ /* lookup whiteout for dentry */
18897+ if (au_ftest_ren(a->flags, WHDST)) {
18898+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
18899+ a->br);
18900+ err = PTR_ERR(h_d);
18901+ if (IS_ERR(h_d))
18902+ goto out_whsrc;
18903+ if (!h_d->d_inode)
18904+ dput(h_d);
18905+ else
18906+ a->dst_wh_dentry = h_d;
18907+ }
1facf9fc 18908+
4a4d8108
AM
18909+ /* rename dentry to tmpwh */
18910+ if (a->thargs) {
18911+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
18912+ if (unlikely(err))
18913+ goto out_whdst;
dece6358 18914+
4a4d8108
AM
18915+ d = a->dst_dentry;
18916+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 18917+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
18918+ if (unlikely(err))
18919+ goto out_whtmp;
18920+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
18921+ }
1facf9fc 18922+
c2b27bf2 18923+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
1facf9fc 18924+
4a4d8108
AM
18925+ /* rename by vfs_rename or cpup */
18926+ d = a->dst_dentry;
18927+ if (au_ftest_ren(a->flags, ISDIR)
18928+ && (a->dst_wh_dentry
18929+ || au_dbdiropq(d) == a->btgt
18930+ /* hide the lower to keep xino */
18931+ || a->btgt < au_dbend(d)
18932+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
18933+ au_fset_ren(a->flags, DIROPQ);
18934+ err = au_ren_or_cpup(a);
18935+ if (unlikely(err))
18936+ /* leave the copied-up one */
18937+ goto out_whtmp;
1308ab2a 18938+
4a4d8108
AM
18939+ /* make dir opaque */
18940+ if (au_ftest_ren(a->flags, DIROPQ)) {
18941+ err = au_ren_diropq(a);
18942+ if (unlikely(err))
18943+ goto out_rename;
18944+ }
1308ab2a 18945+
4a4d8108
AM
18946+ /* update target timestamps */
18947+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
18948+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
18949+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
18950+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
1facf9fc 18951+
4a4d8108
AM
18952+ /* remove whiteout for dentry */
18953+ if (a->dst_wh_dentry) {
18954+ a->h_path.dentry = a->dst_wh_dentry;
18955+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
18956+ a->dst_dentry);
18957+ if (unlikely(err))
18958+ goto out_diropq;
18959+ }
1facf9fc 18960+
4a4d8108
AM
18961+ /* remove whtmp */
18962+ if (a->thargs)
18963+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 18964+
4a4d8108
AM
18965+ err = 0;
18966+ goto out_success;
18967+
4f0767ce 18968+out_diropq:
4a4d8108
AM
18969+ if (au_ftest_ren(a->flags, DIROPQ))
18970+ au_ren_rev_diropq(err, a);
4f0767ce 18971+out_rename:
4a4d8108
AM
18972+ if (!au_ftest_ren(a->flags, CPUP))
18973+ au_ren_rev_rename(err, a);
18974+ else
18975+ au_ren_rev_cpup(err, a);
027c5e7a 18976+ dput(a->h_dst);
4f0767ce 18977+out_whtmp:
4a4d8108
AM
18978+ if (a->thargs)
18979+ au_ren_rev_whtmp(err, a);
4f0767ce 18980+out_whdst:
4a4d8108
AM
18981+ dput(a->dst_wh_dentry);
18982+ a->dst_wh_dentry = NULL;
4f0767ce 18983+out_whsrc:
4a4d8108
AM
18984+ if (a->src_wh_dentry)
18985+ au_ren_rev_whsrc(err, a);
4f0767ce 18986+out_success:
4a4d8108
AM
18987+ dput(a->src_wh_dentry);
18988+ dput(a->dst_wh_dentry);
4f0767ce 18989+out_thargs:
4a4d8108
AM
18990+ if (a->thargs) {
18991+ dput(a->h_dst);
18992+ au_whtmp_rmdir_free(a->thargs);
18993+ a->thargs = NULL;
18994+ }
4f0767ce 18995+out:
4a4d8108 18996+ return err;
dece6358 18997+}
1facf9fc 18998+
1308ab2a 18999+/* ---------------------------------------------------------------------- */
1facf9fc 19000+
4a4d8108
AM
19001+/*
19002+ * test if @dentry dir can be rename destination or not.
19003+ * success means, it is a logically empty dir.
19004+ */
19005+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 19006+{
4a4d8108 19007+ return au_test_empty(dentry, whlist);
1308ab2a 19008+}
1facf9fc 19009+
4a4d8108
AM
19010+/*
19011+ * test if @dentry dir can be rename source or not.
19012+ * if it can, return 0 and @children is filled.
19013+ * success means,
19014+ * - it is a logically empty dir.
19015+ * - or, it exists on writable branch and has no children including whiteouts
19016+ * on the lower branch.
19017+ */
19018+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
19019+{
19020+ int err;
19021+ unsigned int rdhash;
19022+ aufs_bindex_t bstart;
1facf9fc 19023+
4a4d8108
AM
19024+ bstart = au_dbstart(dentry);
19025+ if (bstart != btgt) {
19026+ struct au_nhash whlist;
dece6358 19027+
4a4d8108
AM
19028+ SiMustAnyLock(dentry->d_sb);
19029+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
19030+ if (!rdhash)
19031+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
19032+ dentry));
19033+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
19034+ if (unlikely(err))
19035+ goto out;
19036+ err = au_test_empty(dentry, &whlist);
19037+ au_nhash_wh_free(&whlist);
19038+ goto out;
19039+ }
dece6358 19040+
4a4d8108
AM
19041+ if (bstart == au_dbtaildir(dentry))
19042+ return 0; /* success */
dece6358 19043+
4a4d8108 19044+ err = au_test_empty_lower(dentry);
1facf9fc 19045+
4f0767ce 19046+out:
4a4d8108
AM
19047+ if (err == -ENOTEMPTY) {
19048+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
19049+ " is not supported\n");
19050+ err = -EXDEV;
19051+ }
19052+ return err;
19053+}
1308ab2a 19054+
4a4d8108
AM
19055+/* side effect: sets whlist and h_dentry */
19056+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 19057+{
4a4d8108
AM
19058+ int err;
19059+ unsigned int rdhash;
19060+ struct dentry *d;
1facf9fc 19061+
4a4d8108
AM
19062+ d = a->dst_dentry;
19063+ SiMustAnyLock(d->d_sb);
1facf9fc 19064+
4a4d8108
AM
19065+ err = 0;
19066+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
19067+ rdhash = au_sbi(d->d_sb)->si_rdhash;
19068+ if (!rdhash)
19069+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
19070+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
19071+ if (unlikely(err))
19072+ goto out;
1308ab2a 19073+
4a4d8108
AM
19074+ au_set_dbstart(d, a->dst_bstart);
19075+ err = may_rename_dstdir(d, &a->whlist);
19076+ au_set_dbstart(d, a->btgt);
19077+ }
19078+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
19079+ if (unlikely(err))
19080+ goto out;
19081+
19082+ d = a->src_dentry;
19083+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
19084+ if (au_ftest_ren(a->flags, ISDIR)) {
19085+ err = may_rename_srcdir(d, a->btgt);
19086+ if (unlikely(err)) {
19087+ au_nhash_wh_free(&a->whlist);
19088+ a->whlist.nh_num = 0;
19089+ }
19090+ }
4f0767ce 19091+out:
4a4d8108 19092+ return err;
1facf9fc 19093+}
19094+
4a4d8108 19095+/* ---------------------------------------------------------------------- */
1facf9fc 19096+
4a4d8108
AM
19097+/*
19098+ * simple tests for rename.
19099+ * following the checks in vfs, plus the parent-child relationship.
19100+ */
19101+static int au_may_ren(struct au_ren_args *a)
19102+{
19103+ int err, isdir;
19104+ struct inode *h_inode;
1facf9fc 19105+
4a4d8108
AM
19106+ if (a->src_bstart == a->btgt) {
19107+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
19108+ au_ftest_ren(a->flags, ISDIR));
19109+ if (unlikely(err))
19110+ goto out;
19111+ err = -EINVAL;
19112+ if (unlikely(a->src_h_dentry == a->h_trap))
19113+ goto out;
19114+ }
1facf9fc 19115+
4a4d8108
AM
19116+ err = 0;
19117+ if (a->dst_bstart != a->btgt)
19118+ goto out;
1facf9fc 19119+
027c5e7a
AM
19120+ err = -ENOTEMPTY;
19121+ if (unlikely(a->dst_h_dentry == a->h_trap))
19122+ goto out;
19123+
4a4d8108
AM
19124+ err = -EIO;
19125+ h_inode = a->dst_h_dentry->d_inode;
19126+ isdir = !!au_ftest_ren(a->flags, ISDIR);
19127+ if (!a->dst_dentry->d_inode) {
19128+ if (unlikely(h_inode))
19129+ goto out;
19130+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
19131+ isdir);
19132+ } else {
19133+ if (unlikely(!h_inode || !h_inode->i_nlink))
19134+ goto out;
19135+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
19136+ isdir);
19137+ if (unlikely(err))
19138+ goto out;
4a4d8108 19139+ }
1facf9fc 19140+
4f0767ce 19141+out:
4a4d8108
AM
19142+ if (unlikely(err == -ENOENT || err == -EEXIST))
19143+ err = -EIO;
19144+ AuTraceErr(err);
19145+ return err;
19146+}
1facf9fc 19147+
1308ab2a 19148+/* ---------------------------------------------------------------------- */
1facf9fc 19149+
4a4d8108
AM
19150+/*
19151+ * locking order
19152+ * (VFS)
19153+ * - src_dir and dir by lock_rename()
19154+ * - inode if exitsts
19155+ * (aufs)
19156+ * - lock all
19157+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
19158+ * + si_read_lock
19159+ * + di_write_lock2_child()
19160+ * + di_write_lock_child()
19161+ * + ii_write_lock_child()
19162+ * + di_write_lock_child2()
19163+ * + ii_write_lock_child2()
19164+ * + src_parent and parent
19165+ * + di_write_lock_parent()
19166+ * + ii_write_lock_parent()
19167+ * + di_write_lock_parent2()
19168+ * + ii_write_lock_parent2()
19169+ * + lower src_dir and dir by vfsub_lock_rename()
19170+ * + verify the every relationships between child and parent. if any
19171+ * of them failed, unlock all and return -EBUSY.
19172+ */
19173+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 19174+{
4a4d8108
AM
19175+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
19176+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
19177+ if (au_ftest_ren(a->flags, MNT_WRITE))
19178+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 19179+}
19180+
4a4d8108 19181+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 19182+{
4a4d8108
AM
19183+ int err;
19184+ unsigned int udba;
1308ab2a 19185+
4a4d8108
AM
19186+ err = 0;
19187+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
19188+ a->src_hdir = au_hi(a->src_dir, a->btgt);
19189+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
19190+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
19191+
19192+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
19193+ if (unlikely(err))
19194+ goto out;
19195+ au_fset_ren(a->flags, MNT_WRITE);
4a4d8108
AM
19196+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
19197+ a->dst_h_parent, a->dst_hdir);
19198+ udba = au_opt_udba(a->src_dentry->d_sb);
19199+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
19200+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
19201+ err = au_busy_or_stale();
19202+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
19203+ err = au_h_verify(a->src_h_dentry, udba,
19204+ a->src_h_parent->d_inode, a->src_h_parent,
19205+ a->br);
19206+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
19207+ err = au_h_verify(a->dst_h_dentry, udba,
19208+ a->dst_h_parent->d_inode, a->dst_h_parent,
19209+ a->br);
86dc4139 19210+ if (!err)
4a4d8108 19211+ goto out; /* success */
4a4d8108
AM
19212+
19213+ err = au_busy_or_stale();
4a4d8108 19214+ au_ren_unlock(a);
86dc4139 19215+
4f0767ce 19216+out:
4a4d8108 19217+ return err;
1facf9fc 19218+}
19219+
19220+/* ---------------------------------------------------------------------- */
19221+
4a4d8108 19222+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 19223+{
4a4d8108 19224+ struct inode *dir;
dece6358 19225+
4a4d8108
AM
19226+ dir = a->dst_dir;
19227+ dir->i_version++;
19228+ if (au_ftest_ren(a->flags, ISDIR)) {
19229+ /* is this updating defined in POSIX? */
19230+ au_cpup_attr_timesizes(a->src_inode);
19231+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 19232+ }
027c5e7a 19233+
4a4d8108
AM
19234+ if (au_ibstart(dir) == a->btgt)
19235+ au_cpup_attr_timesizes(dir);
dece6358 19236+
4a4d8108
AM
19237+ if (au_ftest_ren(a->flags, ISSAMEDIR))
19238+ return;
dece6358 19239+
4a4d8108
AM
19240+ dir = a->src_dir;
19241+ dir->i_version++;
19242+ if (au_ftest_ren(a->flags, ISDIR))
19243+ au_cpup_attr_nlink(dir, /*force*/1);
19244+ if (au_ibstart(dir) == a->btgt)
19245+ au_cpup_attr_timesizes(dir);
1facf9fc 19246+}
19247+
4a4d8108 19248+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 19249+{
4a4d8108
AM
19250+ aufs_bindex_t bend, bindex;
19251+ struct dentry *d, *h_d;
19252+ struct inode *i, *h_i;
19253+ struct super_block *sb;
dece6358 19254+
027c5e7a
AM
19255+ d = a->dst_dentry;
19256+ d_drop(d);
19257+ if (a->h_dst)
19258+ /* already dget-ed by au_ren_or_cpup() */
19259+ au_set_h_dptr(d, a->btgt, a->h_dst);
19260+
19261+ i = a->dst_inode;
19262+ if (i) {
19263+ if (!au_ftest_ren(a->flags, ISDIR))
19264+ vfsub_drop_nlink(i);
19265+ else {
19266+ vfsub_dead_dir(i);
19267+ au_cpup_attr_timesizes(i);
19268+ }
19269+ au_update_dbrange(d, /*do_put_zero*/1);
19270+ } else {
19271+ bend = a->btgt;
19272+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
19273+ au_set_h_dptr(d, bindex, NULL);
19274+ bend = au_dbend(d);
19275+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
19276+ au_set_h_dptr(d, bindex, NULL);
19277+ au_update_dbrange(d, /*do_put_zero*/0);
19278+ }
19279+
4a4d8108
AM
19280+ d = a->src_dentry;
19281+ au_set_dbwh(d, -1);
19282+ bend = au_dbend(d);
19283+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
19284+ h_d = au_h_dptr(d, bindex);
19285+ if (h_d)
19286+ au_set_h_dptr(d, bindex, NULL);
19287+ }
19288+ au_set_dbend(d, a->btgt);
19289+
19290+ sb = d->d_sb;
19291+ i = a->src_inode;
19292+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
19293+ return; /* success */
19294+
19295+ bend = au_ibend(i);
19296+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
19297+ h_i = au_h_iptr(i, bindex);
19298+ if (h_i) {
19299+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
19300+ /* ignore this error */
19301+ au_set_h_iptr(i, bindex, NULL, 0);
19302+ }
19303+ }
19304+ au_set_ibend(i, a->btgt);
1308ab2a 19305+}
dece6358 19306+
4a4d8108
AM
19307+/* ---------------------------------------------------------------------- */
19308+
19309+/* mainly for link(2) and rename(2) */
19310+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 19311+{
4a4d8108
AM
19312+ aufs_bindex_t bdiropq, bwh;
19313+ struct dentry *parent;
19314+ struct au_branch *br;
19315+
19316+ parent = dentry->d_parent;
19317+ IMustLock(parent->d_inode); /* dir is locked */
19318+
19319+ bdiropq = au_dbdiropq(parent);
19320+ bwh = au_dbwh(dentry);
19321+ br = au_sbr(dentry->d_sb, btgt);
19322+ if (au_br_rdonly(br)
19323+ || (0 <= bdiropq && bdiropq < btgt)
19324+ || (0 <= bwh && bwh < btgt))
19325+ btgt = -1;
19326+
19327+ AuDbg("btgt %d\n", btgt);
19328+ return btgt;
1facf9fc 19329+}
19330+
4a4d8108
AM
19331+/* sets src_bstart, dst_bstart and btgt */
19332+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 19333+{
4a4d8108
AM
19334+ int err;
19335+ struct au_wr_dir_args wr_dir_args = {
19336+ /* .force_btgt = -1, */
19337+ .flags = AuWrDir_ADD_ENTRY
19338+ };
dece6358 19339+
4a4d8108
AM
19340+ a->src_bstart = au_dbstart(a->src_dentry);
19341+ a->dst_bstart = au_dbstart(a->dst_dentry);
19342+ if (au_ftest_ren(a->flags, ISDIR))
19343+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
19344+ wr_dir_args.force_btgt = a->src_bstart;
19345+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
19346+ wr_dir_args.force_btgt = a->dst_bstart;
19347+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
19348+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
19349+ a->btgt = err;
dece6358 19350+
4a4d8108 19351+ return err;
1facf9fc 19352+}
19353+
4a4d8108 19354+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 19355+{
4a4d8108
AM
19356+ a->h_path.dentry = a->src_h_parent;
19357+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
19358+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
19359+ a->h_path.dentry = a->dst_h_parent;
19360+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
19361+ }
1facf9fc 19362+
4a4d8108
AM
19363+ au_fclr_ren(a->flags, DT_DSTDIR);
19364+ if (!au_ftest_ren(a->flags, ISDIR))
19365+ return;
dece6358 19366+
4a4d8108
AM
19367+ a->h_path.dentry = a->src_h_dentry;
19368+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
19369+ if (a->dst_h_dentry->d_inode) {
19370+ au_fset_ren(a->flags, DT_DSTDIR);
19371+ a->h_path.dentry = a->dst_h_dentry;
19372+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
19373+ }
1308ab2a 19374+}
dece6358 19375+
4a4d8108 19376+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 19377+{
4a4d8108
AM
19378+ struct dentry *h_d;
19379+ struct mutex *h_mtx;
19380+
19381+ au_dtime_revert(a->src_dt + AuPARENT);
19382+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
19383+ au_dtime_revert(a->dst_dt + AuPARENT);
19384+
19385+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
19386+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
19387+ h_mtx = &h_d->d_inode->i_mutex;
19388+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
19389+ au_dtime_revert(a->src_dt + AuCHILD);
19390+ mutex_unlock(h_mtx);
19391+
19392+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
19393+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
19394+ h_mtx = &h_d->d_inode->i_mutex;
19395+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
19396+ au_dtime_revert(a->dst_dt + AuCHILD);
19397+ mutex_unlock(h_mtx);
1facf9fc 19398+ }
19399+ }
19400+}
19401+
4a4d8108
AM
19402+/* ---------------------------------------------------------------------- */
19403+
19404+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
19405+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 19406+{
e49829fe 19407+ int err, flags;
4a4d8108
AM
19408+ /* reduce stack space */
19409+ struct au_ren_args *a;
19410+
523b37e3 19411+ AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry);
4a4d8108
AM
19412+ IMustLock(_src_dir);
19413+ IMustLock(_dst_dir);
19414+
19415+ err = -ENOMEM;
19416+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
19417+ a = kzalloc(sizeof(*a), GFP_NOFS);
19418+ if (unlikely(!a))
19419+ goto out;
19420+
19421+ a->src_dir = _src_dir;
19422+ a->src_dentry = _src_dentry;
19423+ a->src_inode = a->src_dentry->d_inode;
19424+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
19425+ a->dst_dir = _dst_dir;
19426+ a->dst_dentry = _dst_dentry;
19427+ a->dst_inode = a->dst_dentry->d_inode;
19428+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
19429+ if (a->dst_inode) {
19430+ IMustLock(a->dst_inode);
19431+ au_igrab(a->dst_inode);
1facf9fc 19432+ }
1facf9fc 19433+
4a4d8108 19434+ err = -ENOTDIR;
027c5e7a 19435+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
4a4d8108
AM
19436+ if (S_ISDIR(a->src_inode->i_mode)) {
19437+ au_fset_ren(a->flags, ISDIR);
19438+ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
19439+ goto out_free;
e49829fe
JR
19440+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
19441+ AuLock_DIR | flags);
4a4d8108 19442+ } else
e49829fe
JR
19443+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
19444+ flags);
19445+ if (unlikely(err))
19446+ goto out_free;
1facf9fc 19447+
027c5e7a
AM
19448+ err = au_d_hashed_positive(a->src_dentry);
19449+ if (unlikely(err))
19450+ goto out_unlock;
19451+ err = -ENOENT;
19452+ if (a->dst_inode) {
19453+ /*
19454+ * If it is a dir, VFS unhash dst_dentry before this
19455+ * function. It means we cannot rely upon d_unhashed().
19456+ */
19457+ if (unlikely(!a->dst_inode->i_nlink))
19458+ goto out_unlock;
19459+ if (!S_ISDIR(a->dst_inode->i_mode)) {
19460+ err = au_d_hashed_positive(a->dst_dentry);
19461+ if (unlikely(err))
19462+ goto out_unlock;
19463+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
19464+ goto out_unlock;
19465+ } else if (unlikely(d_unhashed(a->dst_dentry)))
19466+ goto out_unlock;
19467+
7eafdf33
AM
19468+ /*
19469+ * is it possible?
19470+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
19471+ * there may exist a problem somewhere else.
19472+ */
19473+ err = -EINVAL;
19474+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
19475+ goto out_unlock;
19476+
4a4d8108
AM
19477+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
19478+ di_write_lock_parent(a->dst_parent);
1facf9fc 19479+
4a4d8108
AM
19480+ /* which branch we process */
19481+ err = au_ren_wbr(a);
19482+ if (unlikely(err < 0))
027c5e7a 19483+ goto out_parent;
4a4d8108 19484+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 19485+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 19486+
4a4d8108
AM
19487+ /* are they available to be renamed */
19488+ err = au_ren_may_dir(a);
19489+ if (unlikely(err))
19490+ goto out_children;
1facf9fc 19491+
4a4d8108
AM
19492+ /* prepare the writable parent dir on the same branch */
19493+ if (a->dst_bstart == a->btgt) {
19494+ au_fset_ren(a->flags, WHDST);
19495+ } else {
19496+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
19497+ if (unlikely(err))
19498+ goto out_children;
19499+ }
1facf9fc 19500+
4a4d8108
AM
19501+ if (a->src_dir != a->dst_dir) {
19502+ /*
19503+ * this temporary unlock is safe,
19504+ * because both dir->i_mutex are locked.
19505+ */
19506+ di_write_unlock(a->dst_parent);
19507+ di_write_lock_parent(a->src_parent);
19508+ err = au_wr_dir_need_wh(a->src_dentry,
19509+ au_ftest_ren(a->flags, ISDIR),
19510+ &a->btgt);
19511+ di_write_unlock(a->src_parent);
19512+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
19513+ au_fclr_ren(a->flags, ISSAMEDIR);
19514+ } else
19515+ err = au_wr_dir_need_wh(a->src_dentry,
19516+ au_ftest_ren(a->flags, ISDIR),
19517+ &a->btgt);
19518+ if (unlikely(err < 0))
19519+ goto out_children;
19520+ if (err)
19521+ au_fset_ren(a->flags, WHSRC);
1facf9fc 19522+
86dc4139
AM
19523+ /* cpup src */
19524+ if (a->src_bstart != a->btgt) {
86dc4139
AM
19525+ struct au_pin pin;
19526+
19527+ err = au_pin(&pin, a->src_dentry, a->btgt,
19528+ au_opt_udba(a->src_dentry->d_sb),
19529+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 19530+ if (!err) {
c2b27bf2
AM
19531+ struct au_cp_generic cpg = {
19532+ .dentry = a->src_dentry,
19533+ .bdst = a->btgt,
19534+ .bsrc = a->src_bstart,
19535+ .len = -1,
19536+ .pin = &pin,
19537+ .flags = AuCpup_DTIME | AuCpup_HOPEN
19538+ };
367653fa 19539+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
c2b27bf2 19540+ err = au_sio_cpup_simple(&cpg);
367653fa 19541+ au_unpin(&pin);
86dc4139 19542+ }
86dc4139
AM
19543+ if (unlikely(err))
19544+ goto out_children;
19545+ a->src_bstart = a->btgt;
19546+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
19547+ au_fset_ren(a->flags, WHSRC);
19548+ }
19549+
4a4d8108
AM
19550+ /* lock them all */
19551+ err = au_ren_lock(a);
19552+ if (unlikely(err))
86dc4139 19553+ /* leave the copied-up one */
4a4d8108 19554+ goto out_children;
1facf9fc 19555+
4a4d8108
AM
19556+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
19557+ err = au_may_ren(a);
19558+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
19559+ err = -ENAMETOOLONG;
19560+ if (unlikely(err))
19561+ goto out_hdir;
1facf9fc 19562+
4a4d8108
AM
19563+ /* store timestamps to be revertible */
19564+ au_ren_dt(a);
1facf9fc 19565+
4a4d8108
AM
19566+ /* here we go */
19567+ err = do_rename(a);
19568+ if (unlikely(err))
19569+ goto out_dt;
19570+
19571+ /* update dir attributes */
19572+ au_ren_refresh_dir(a);
19573+
19574+ /* dput/iput all lower dentries */
19575+ au_ren_refresh(a);
19576+
19577+ goto out_hdir; /* success */
19578+
4f0767ce 19579+out_dt:
4a4d8108 19580+ au_ren_rev_dt(err, a);
4f0767ce 19581+out_hdir:
4a4d8108 19582+ au_ren_unlock(a);
4f0767ce 19583+out_children:
4a4d8108 19584+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
19585+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
19586+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
19587+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
19588+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 19589+ }
027c5e7a 19590+out_parent:
4a4d8108
AM
19591+ if (!err)
19592+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
19593+ else {
19594+ au_update_dbstart(a->dst_dentry);
19595+ if (!a->dst_inode)
19596+ d_drop(a->dst_dentry);
19597+ }
4a4d8108
AM
19598+ if (au_ftest_ren(a->flags, ISSAMEDIR))
19599+ di_write_unlock(a->dst_parent);
19600+ else
19601+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 19602+out_unlock:
4a4d8108 19603+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 19604+out_free:
4a4d8108
AM
19605+ iput(a->dst_inode);
19606+ if (a->thargs)
19607+ au_whtmp_rmdir_free(a->thargs);
19608+ kfree(a);
4f0767ce 19609+out:
4a4d8108
AM
19610+ AuTraceErr(err);
19611+ return err;
1308ab2a 19612+}
7f207e10
AM
19613diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
19614--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
fb47a38f 19615+++ linux/fs/aufs/Kconfig 2014-04-24 22:11:10.835268907 +0200
523b37e3 19616@@ -0,0 +1,179 @@
4a4d8108
AM
19617+config AUFS_FS
19618+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
19619+ help
19620+ Aufs is a stackable unification filesystem such as Unionfs,
19621+ which unifies several directories and provides a merged single
19622+ directory.
19623+ In the early days, aufs was entirely re-designed and
19624+ re-implemented Unionfs Version 1.x series. Introducing many
19625+ original ideas, approaches and improvements, it becomes totally
19626+ different from Unionfs while keeping the basic features.
1facf9fc 19627+
4a4d8108
AM
19628+if AUFS_FS
19629+choice
19630+ prompt "Maximum number of branches"
19631+ default AUFS_BRANCH_MAX_127
19632+ help
19633+ Specifies the maximum number of branches (or member directories)
19634+ in a single aufs. The larger value consumes more system
19635+ resources and has a minor impact to performance.
19636+config AUFS_BRANCH_MAX_127
19637+ bool "127"
19638+ help
19639+ Specifies the maximum number of branches (or member directories)
19640+ in a single aufs. The larger value consumes more system
19641+ resources and has a minor impact to performance.
19642+config AUFS_BRANCH_MAX_511
19643+ bool "511"
19644+ help
19645+ Specifies the maximum number of branches (or member directories)
19646+ in a single aufs. The larger value consumes more system
19647+ resources and has a minor impact to performance.
19648+config AUFS_BRANCH_MAX_1023
19649+ bool "1023"
19650+ help
19651+ Specifies the maximum number of branches (or member directories)
19652+ in a single aufs. The larger value consumes more system
19653+ resources and has a minor impact to performance.
19654+config AUFS_BRANCH_MAX_32767
19655+ bool "32767"
19656+ help
19657+ Specifies the maximum number of branches (or member directories)
19658+ in a single aufs. The larger value consumes more system
19659+ resources and has a minor impact to performance.
19660+endchoice
1facf9fc 19661+
e49829fe
JR
19662+config AUFS_SBILIST
19663+ bool
19664+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
19665+ default y
19666+ help
19667+ Automatic configuration for internal use.
19668+ When aufs supports Magic SysRq or /proc, enabled automatically.
19669+
4a4d8108
AM
19670+config AUFS_HNOTIFY
19671+ bool "Detect direct branch access (bypassing aufs)"
19672+ help
19673+ If you want to modify files on branches directly, eg. bypassing aufs,
19674+ and want aufs to detect the changes of them fully, then enable this
19675+ option and use 'udba=notify' mount option.
7f207e10 19676+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
19677+ It will have a negative impact to the performance.
19678+ See detail in aufs.5.
dece6358 19679+
4a4d8108
AM
19680+choice
19681+ prompt "method" if AUFS_HNOTIFY
19682+ default AUFS_HFSNOTIFY
19683+config AUFS_HFSNOTIFY
19684+ bool "fsnotify"
19685+ select FSNOTIFY
4a4d8108 19686+endchoice
1facf9fc 19687+
4a4d8108
AM
19688+config AUFS_EXPORT
19689+ bool "NFS-exportable aufs"
2cbb1c4b 19690+ depends on EXPORTFS
4a4d8108
AM
19691+ help
19692+ If you want to export your mounted aufs via NFS, then enable this
19693+ option. There are several requirements for this configuration.
19694+ See detail in aufs.5.
1facf9fc 19695+
4a4d8108
AM
19696+config AUFS_INO_T_64
19697+ bool
19698+ depends on AUFS_EXPORT
19699+ depends on 64BIT && !(ALPHA || S390)
19700+ default y
19701+ help
19702+ Automatic configuration for internal use.
19703+ /* typedef unsigned long/int __kernel_ino_t */
19704+ /* alpha and s390x are int */
1facf9fc 19705+
4a4d8108
AM
19706+config AUFS_RDU
19707+ bool "Readdir in userspace"
19708+ help
19709+ Aufs has two methods to provide a merged view for a directory,
19710+ by a user-space library and by kernel-space natively. The latter
19711+ is always enabled but sometimes large and slow.
19712+ If you enable this option, install the library in aufs2-util
19713+ package, and set some environment variables for your readdir(3),
19714+ then the work will be handled in user-space which generally
19715+ shows better performance in most cases.
19716+ See detail in aufs.5.
1facf9fc 19717+
4a4d8108
AM
19718+config AUFS_SP_IATTR
19719+ bool "Respect the attributes (mtime/ctime mainly) of special files"
19720+ help
19721+ When you write something to a special file, some attributes of it
19722+ (mtime/ctime mainly) may be updated. Generally such updates are
19723+ less important (actually some device drivers and NFS ignore
19724+ it). But some applications (such like test program) requires
19725+ such updates. If you need these updates, then enable this
19726+ configuration which introduces some overhead.
19727+ Currently this configuration handles FIFO only.
1facf9fc 19728+
4a4d8108
AM
19729+config AUFS_SHWH
19730+ bool "Show whiteouts"
19731+ help
19732+ If you want to make the whiteouts in aufs visible, then enable
19733+ this option and specify 'shwh' mount option. Although it may
19734+ sounds like philosophy or something, but in technically it
19735+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 19736+
4a4d8108
AM
19737+config AUFS_BR_RAMFS
19738+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
19739+ help
19740+ If you want to use ramfs as an aufs branch fs, then enable this
19741+ option. Generally tmpfs is recommended.
19742+ Aufs prohibited them to be a branch fs by default, because
19743+ initramfs becomes unusable after switch_root or something
19744+ generally. If you sets initramfs as an aufs branch and boot your
19745+ system by switch_root, you will meet a problem easily since the
19746+ files in initramfs may be inaccessible.
19747+ Unless you are going to use ramfs as an aufs branch fs without
19748+ switch_root or something, leave it N.
1facf9fc 19749+
4a4d8108
AM
19750+config AUFS_BR_FUSE
19751+ bool "Fuse fs as an aufs branch"
19752+ depends on FUSE_FS
19753+ select AUFS_POLL
19754+ help
19755+ If you want to use fuse-based userspace filesystem as an aufs
19756+ branch fs, then enable this option.
19757+ It implements the internal poll(2) operation which is
19758+ implemented by fuse only (curretnly).
1facf9fc 19759+
4a4d8108
AM
19760+config AUFS_POLL
19761+ bool
19762+ help
19763+ Automatic configuration for internal use.
1facf9fc 19764+
4a4d8108
AM
19765+config AUFS_BR_HFSPLUS
19766+ bool "Hfsplus as an aufs branch"
19767+ depends on HFSPLUS_FS
19768+ default y
19769+ help
19770+ If you want to use hfsplus fs as an aufs branch fs, then enable
19771+ this option. This option introduces a small overhead at
19772+ copying-up a file on hfsplus.
1facf9fc 19773+
4a4d8108
AM
19774+config AUFS_BDEV_LOOP
19775+ bool
19776+ depends on BLK_DEV_LOOP
19777+ default y
19778+ help
19779+ Automatic configuration for internal use.
19780+ Convert =[ym] into =y.
1308ab2a 19781+
4a4d8108
AM
19782+config AUFS_DEBUG
19783+ bool "Debug aufs"
19784+ help
19785+ Enable this to compile aufs internal debug code.
19786+ It will have a negative impact to the performance.
19787+
19788+config AUFS_MAGIC_SYSRQ
19789+ bool
19790+ depends on AUFS_DEBUG && MAGIC_SYSRQ
19791+ default y
19792+ help
19793+ Automatic configuration for internal use.
19794+ When aufs supports Magic SysRq, enabled automatically.
19795+endif
7f207e10
AM
19796diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
19797--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 19798+++ linux/fs/aufs/loop.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 19799@@ -0,0 +1,145 @@
1facf9fc 19800+/*
523b37e3 19801+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19802+ *
19803+ * This program, aufs is free software; you can redistribute it and/or modify
19804+ * it under the terms of the GNU General Public License as published by
19805+ * the Free Software Foundation; either version 2 of the License, or
19806+ * (at your option) any later version.
dece6358
AM
19807+ *
19808+ * This program is distributed in the hope that it will be useful,
19809+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19810+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19811+ * GNU General Public License for more details.
19812+ *
19813+ * You should have received a copy of the GNU General Public License
523b37e3 19814+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19815+ */
19816+
19817+/*
19818+ * support for loopback block device as a branch
19819+ */
19820+
1facf9fc 19821+#include "aufs.h"
19822+
392086de
AM
19823+/* added into drivers/block/loop.c */
19824+static struct file *(*backing_file_func)(struct super_block *sb);
19825+
1facf9fc 19826+/*
19827+ * test if two lower dentries have overlapping branches.
19828+ */
b752ccd1 19829+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 19830+{
b752ccd1 19831+ struct super_block *h_sb;
392086de
AM
19832+ struct file *backing_file;
19833+
19834+ if (unlikely(!backing_file_func)) {
19835+ /* don't load "loop" module here */
19836+ backing_file_func = symbol_get(loop_backing_file);
19837+ if (unlikely(!backing_file_func))
19838+ /* "loop" module is not loaded */
19839+ return 0;
19840+ }
1facf9fc 19841+
b752ccd1 19842+ h_sb = h_adding->d_sb;
392086de
AM
19843+ backing_file = backing_file_func(h_sb);
19844+ if (!backing_file)
1facf9fc 19845+ return 0;
19846+
392086de 19847+ h_adding = backing_file->f_dentry;
b752ccd1
AM
19848+ /*
19849+ * h_adding can be local NFS.
19850+ * in this case aufs cannot detect the loop.
19851+ */
19852+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 19853+ return 1;
b752ccd1 19854+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 19855+}
19856+
19857+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
19858+int au_test_loopback_kthread(void)
19859+{
b752ccd1
AM
19860+ int ret;
19861+ struct task_struct *tsk = current;
a2a7ad62 19862+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
19863+
19864+ ret = 0;
19865+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
19866+ get_task_comm(comm, tsk);
19867+ c = comm[4];
b752ccd1 19868+ ret = ('0' <= c && c <= '9'
a2a7ad62 19869+ && !strncmp(comm, "loop", 4));
b752ccd1 19870+ }
1facf9fc 19871+
b752ccd1 19872+ return ret;
1facf9fc 19873+}
87a755f4
AM
19874+
19875+/* ---------------------------------------------------------------------- */
19876+
19877+#define au_warn_loopback_step 16
19878+static int au_warn_loopback_nelem = au_warn_loopback_step;
19879+static unsigned long *au_warn_loopback_array;
19880+
19881+void au_warn_loopback(struct super_block *h_sb)
19882+{
19883+ int i, new_nelem;
19884+ unsigned long *a, magic;
19885+ static DEFINE_SPINLOCK(spin);
19886+
19887+ magic = h_sb->s_magic;
19888+ spin_lock(&spin);
19889+ a = au_warn_loopback_array;
19890+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
19891+ if (a[i] == magic) {
19892+ spin_unlock(&spin);
19893+ return;
19894+ }
19895+
19896+ /* h_sb is new to us, print it */
19897+ if (i < au_warn_loopback_nelem) {
19898+ a[i] = magic;
19899+ goto pr;
19900+ }
19901+
19902+ /* expand the array */
19903+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
19904+ a = au_kzrealloc(au_warn_loopback_array,
19905+ au_warn_loopback_nelem * sizeof(unsigned long),
19906+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
19907+ if (a) {
19908+ au_warn_loopback_nelem = new_nelem;
19909+ au_warn_loopback_array = a;
19910+ a[i] = magic;
19911+ goto pr;
19912+ }
19913+
19914+ spin_unlock(&spin);
19915+ AuWarn1("realloc failed, ignored\n");
19916+ return;
19917+
19918+pr:
19919+ spin_unlock(&spin);
0c3ec466
AM
19920+ pr_warn("you may want to try another patch for loopback file "
19921+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
19922+}
19923+
19924+int au_loopback_init(void)
19925+{
19926+ int err;
19927+ struct super_block *sb __maybe_unused;
19928+
19929+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
19930+
19931+ err = 0;
19932+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
19933+ sizeof(unsigned long), GFP_NOFS);
19934+ if (unlikely(!au_warn_loopback_array))
19935+ err = -ENOMEM;
19936+
19937+ return err;
19938+}
19939+
19940+void au_loopback_fin(void)
19941+{
392086de 19942+ symbol_put(loop_backing_file);
87a755f4
AM
19943+ kfree(au_warn_loopback_array);
19944+}
7f207e10
AM
19945diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
19946--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 19947+++ linux/fs/aufs/loop.h 2014-04-24 22:11:10.855269116 +0200
523b37e3 19948@@ -0,0 +1,52 @@
1facf9fc 19949+/*
523b37e3 19950+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19951+ *
19952+ * This program, aufs is free software; you can redistribute it and/or modify
19953+ * it under the terms of the GNU General Public License as published by
19954+ * the Free Software Foundation; either version 2 of the License, or
19955+ * (at your option) any later version.
dece6358
AM
19956+ *
19957+ * This program is distributed in the hope that it will be useful,
19958+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19959+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19960+ * GNU General Public License for more details.
19961+ *
19962+ * You should have received a copy of the GNU General Public License
523b37e3 19963+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19964+ */
19965+
19966+/*
19967+ * support for loopback mount as a branch
19968+ */
19969+
19970+#ifndef __AUFS_LOOP_H__
19971+#define __AUFS_LOOP_H__
19972+
19973+#ifdef __KERNEL__
19974+
dece6358
AM
19975+struct dentry;
19976+struct super_block;
1facf9fc 19977+
19978+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
19979+/* drivers/block/loop.c */
19980+struct file *loop_backing_file(struct super_block *sb);
19981+
1facf9fc 19982+/* loop.c */
b752ccd1 19983+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 19984+int au_test_loopback_kthread(void);
87a755f4
AM
19985+void au_warn_loopback(struct super_block *h_sb);
19986+
19987+int au_loopback_init(void);
19988+void au_loopback_fin(void);
1facf9fc 19989+#else
4a4d8108 19990+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 19991+ struct dentry *h_adding)
4a4d8108 19992+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
19993+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
19994+
19995+AuStubInt0(au_loopback_init, void)
19996+AuStubVoid(au_loopback_fin, void)
1facf9fc 19997+#endif /* BLK_DEV_LOOP */
19998+
19999+#endif /* __KERNEL__ */
20000+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
20001diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
20002--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
fb47a38f 20003+++ linux/fs/aufs/magic.mk 2012-10-05 20:40:23.980965955 +0200
4a4d8108 20004@@ -0,0 +1,54 @@
1facf9fc 20005+
20006+# defined in ${srctree}/fs/fuse/inode.c
20007+# tristate
20008+ifdef CONFIG_FUSE_FS
20009+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
20010+endif
20011+
20012+# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
20013+# tristate
20014+ifdef CONFIG_OCFS2_FS
20015+ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
20016+endif
20017+
20018+# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
20019+# tristate
20020+ifdef CONFIG_OCFS2_FS_O2CB
20021+ccflags-y += -DDLMFS_MAGIC=0x76a9f425
20022+endif
20023+
1facf9fc 20024+# defined in ${srctree}/fs/cifs/cifsfs.c
20025+# tristate
20026+ifdef CONFIG_CIFS_FS
20027+ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
20028+endif
20029+
20030+# defined in ${srctree}/fs/xfs/xfs_sb.h
20031+# tristate
20032+ifdef CONFIG_XFS_FS
20033+ccflags-y += -DXFS_SB_MAGIC=0x58465342
20034+endif
20035+
20036+# defined in ${srctree}/fs/configfs/mount.c
20037+# tristate
20038+ifdef CONFIG_CONFIGFS_FS
20039+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
20040+endif
20041+
20042+# defined in ${srctree}/fs/9p/v9fs.h
20043+# tristate
20044+ifdef CONFIG_9P_FS
20045+ccflags-y += -DV9FS_MAGIC=0x01021997
20046+endif
20047+
20048+# defined in ${srctree}/fs/ubifs/ubifs.h
20049+# tristate
20050+ifdef CONFIG_UBIFS_FS
20051+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
20052+endif
4a4d8108
AM
20053+
20054+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
20055+# tristate
20056+ifdef CONFIG_HFSPLUS_FS
20057+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
20058+endif
7f207e10
AM
20059diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
20060--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
fb47a38f 20061+++ linux/fs/aufs/Makefile 2014-04-24 22:11:10.845269011 +0200
2dfbb274 20062@@ -0,0 +1,42 @@
4a4d8108
AM
20063+
20064+include ${src}/magic.mk
20065+ifeq (${CONFIG_AUFS_FS},m)
20066+include ${src}/conf.mk
20067+endif
20068+-include ${src}/priv_def.mk
20069+
20070+# cf. include/linux/kernel.h
20071+# enable pr_debug
20072+ccflags-y += -DDEBUG
f6c5ef8b
AM
20073+# sparse requires the full pathname
20074+ifdef M
523b37e3 20075+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 20076+else
523b37e3 20077+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 20078+endif
4a4d8108
AM
20079+
20080+obj-$(CONFIG_AUFS_FS) += aufs.o
20081+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
20082+ wkq.o vfsub.o dcsub.o \
e49829fe 20083+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
20084+ dinfo.o dentry.o \
20085+ dynop.o \
20086+ finfo.o file.o f_op.o \
20087+ dir.o vdir.o \
20088+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 20089+ mvdown.o ioctl.o
4a4d8108
AM
20090+
20091+# all are boolean
e49829fe 20092+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
20093+aufs-$(CONFIG_SYSFS) += sysfs.o
20094+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
20095+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
20096+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
20097+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108
AM
20098+aufs-$(CONFIG_AUFS_EXPORT) += export.o
20099+aufs-$(CONFIG_AUFS_POLL) += poll.o
20100+aufs-$(CONFIG_AUFS_RDU) += rdu.o
20101+aufs-$(CONFIG_AUFS_SP_IATTR) += f_op_sp.o
20102+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
20103+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
20104+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
20105diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
20106--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 20107+++ linux/fs/aufs/module.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 20108@@ -0,0 +1,202 @@
1facf9fc 20109+/*
523b37e3 20110+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 20111+ *
20112+ * This program, aufs is free software; you can redistribute it and/or modify
20113+ * it under the terms of the GNU General Public License as published by
20114+ * the Free Software Foundation; either version 2 of the License, or
20115+ * (at your option) any later version.
dece6358
AM
20116+ *
20117+ * This program is distributed in the hope that it will be useful,
20118+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20119+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20120+ * GNU General Public License for more details.
20121+ *
20122+ * You should have received a copy of the GNU General Public License
523b37e3 20123+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20124+ */
20125+
20126+/*
20127+ * module global variables and operations
20128+ */
20129+
20130+#include <linux/module.h>
20131+#include <linux/seq_file.h>
20132+#include "aufs.h"
20133+
20134+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
20135+{
20136+ if (new_sz <= nused)
20137+ return p;
20138+
20139+ p = krealloc(p, new_sz, gfp);
20140+ if (p)
20141+ memset(p + nused, 0, new_sz - nused);
20142+ return p;
20143+}
20144+
20145+/* ---------------------------------------------------------------------- */
20146+
20147+/*
20148+ * aufs caches
20149+ */
20150+struct kmem_cache *au_cachep[AuCache_Last];
20151+static int __init au_cache_init(void)
20152+{
4a4d8108 20153+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 20154+ if (au_cachep[AuCache_DINFO])
027c5e7a 20155+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
20156+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
20157+ au_icntnr_init_once);
1facf9fc 20158+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
20159+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
20160+ au_fi_init_once);
1facf9fc 20161+ if (au_cachep[AuCache_FINFO])
20162+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
20163+ if (au_cachep[AuCache_VDIR])
20164+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
20165+ if (au_cachep[AuCache_DEHSTR])
20166+ return 0;
20167+
20168+ return -ENOMEM;
20169+}
20170+
20171+static void au_cache_fin(void)
20172+{
20173+ int i;
4a4d8108 20174+
537831f9
AM
20175+ /*
20176+ * Make sure all delayed rcu free inodes are flushed before we
20177+ * destroy cache.
20178+ */
20179+ rcu_barrier();
20180+
7eafdf33
AM
20181+ /* excluding AuCache_HNOTIFY */
20182+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
20183+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 20184+ if (au_cachep[i]) {
20185+ kmem_cache_destroy(au_cachep[i]);
20186+ au_cachep[i] = NULL;
20187+ }
20188+}
20189+
20190+/* ---------------------------------------------------------------------- */
20191+
20192+int au_dir_roflags;
20193+
e49829fe 20194+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
20195+/*
20196+ * iterate_supers_type() doesn't protect us from
20197+ * remounting (branch management)
20198+ */
e49829fe
JR
20199+struct au_splhead au_sbilist;
20200+#endif
20201+
9dbd164d
AM
20202+struct lock_class_key au_lc_key[AuLcKey_Last];
20203+
1facf9fc 20204+/*
20205+ * functions for module interface.
20206+ */
20207+MODULE_LICENSE("GPL");
20208+/* MODULE_LICENSE("GPL v2"); */
dece6358 20209+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 20210+MODULE_DESCRIPTION(AUFS_NAME
20211+ " -- Advanced multi layered unification filesystem");
20212+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 20213+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 20214+
1facf9fc 20215+/* this module parameter has no meaning when SYSFS is disabled */
20216+int sysaufs_brs = 1;
20217+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
20218+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
20219+
20220+/* ---------------------------------------------------------------------- */
20221+
20222+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
20223+
20224+int au_seq_path(struct seq_file *seq, struct path *path)
20225+{
20226+ return seq_path(seq, path, au_esc_chars);
20227+}
20228+
20229+/* ---------------------------------------------------------------------- */
20230+
20231+static int __init aufs_init(void)
20232+{
20233+ int err, i;
20234+ char *p;
20235+
20236+ p = au_esc_chars;
20237+ for (i = 1; i <= ' '; i++)
20238+ *p++ = i;
20239+ *p++ = '\\';
20240+ *p++ = '\x7f';
20241+ *p = 0;
20242+
20243+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
20244+
e49829fe 20245+ au_sbilist_init();
1facf9fc 20246+ sysaufs_brs_init();
20247+ au_debug_init();
4a4d8108 20248+ au_dy_init();
1facf9fc 20249+ err = sysaufs_init();
20250+ if (unlikely(err))
20251+ goto out;
e49829fe 20252+ err = au_procfs_init();
4f0767ce 20253+ if (unlikely(err))
953406b4 20254+ goto out_sysaufs;
e49829fe
JR
20255+ err = au_wkq_init();
20256+ if (unlikely(err))
20257+ goto out_procfs;
87a755f4 20258+ err = au_loopback_init();
1facf9fc 20259+ if (unlikely(err))
20260+ goto out_wkq;
87a755f4
AM
20261+ err = au_hnotify_init();
20262+ if (unlikely(err))
20263+ goto out_loopback;
1facf9fc 20264+ err = au_sysrq_init();
20265+ if (unlikely(err))
20266+ goto out_hin;
20267+ err = au_cache_init();
20268+ if (unlikely(err))
20269+ goto out_sysrq;
20270+ err = register_filesystem(&aufs_fs_type);
20271+ if (unlikely(err))
20272+ goto out_cache;
4a4d8108
AM
20273+ /* since we define pr_fmt, call printk directly */
20274+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 20275+ goto out; /* success */
20276+
4f0767ce 20277+out_cache:
1facf9fc 20278+ au_cache_fin();
4f0767ce 20279+out_sysrq:
1facf9fc 20280+ au_sysrq_fin();
4f0767ce 20281+out_hin:
4a4d8108 20282+ au_hnotify_fin();
87a755f4
AM
20283+out_loopback:
20284+ au_loopback_fin();
4f0767ce 20285+out_wkq:
1facf9fc 20286+ au_wkq_fin();
e49829fe
JR
20287+out_procfs:
20288+ au_procfs_fin();
4f0767ce 20289+out_sysaufs:
1facf9fc 20290+ sysaufs_fin();
4a4d8108 20291+ au_dy_fin();
4f0767ce 20292+out:
1facf9fc 20293+ return err;
20294+}
20295+
20296+static void __exit aufs_exit(void)
20297+{
20298+ unregister_filesystem(&aufs_fs_type);
20299+ au_cache_fin();
20300+ au_sysrq_fin();
4a4d8108 20301+ au_hnotify_fin();
87a755f4 20302+ au_loopback_fin();
1facf9fc 20303+ au_wkq_fin();
e49829fe 20304+ au_procfs_fin();
1facf9fc 20305+ sysaufs_fin();
4a4d8108 20306+ au_dy_fin();
1facf9fc 20307+}
20308+
20309+module_init(aufs_init);
20310+module_exit(aufs_exit);
7f207e10
AM
20311diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
20312--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 20313+++ linux/fs/aufs/module.h 2014-04-24 22:11:10.855269116 +0200
523b37e3 20314@@ -0,0 +1,104 @@
1facf9fc 20315+/*
523b37e3 20316+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 20317+ *
20318+ * This program, aufs is free software; you can redistribute it and/or modify
20319+ * it under the terms of the GNU General Public License as published by
20320+ * the Free Software Foundation; either version 2 of the License, or
20321+ * (at your option) any later version.
dece6358
AM
20322+ *
20323+ * This program is distributed in the hope that it will be useful,
20324+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20325+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20326+ * GNU General Public License for more details.
20327+ *
20328+ * You should have received a copy of the GNU General Public License
523b37e3 20329+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20330+ */
20331+
20332+/*
20333+ * module initialization and module-global
20334+ */
20335+
20336+#ifndef __AUFS_MODULE_H__
20337+#define __AUFS_MODULE_H__
20338+
20339+#ifdef __KERNEL__
20340+
20341+#include <linux/slab.h>
20342+
dece6358
AM
20343+struct path;
20344+struct seq_file;
20345+
1facf9fc 20346+/* module parameters */
1facf9fc 20347+extern int sysaufs_brs;
20348+
20349+/* ---------------------------------------------------------------------- */
20350+
20351+extern int au_dir_roflags;
20352+
9dbd164d
AM
20353+enum {
20354+ AuLcNonDir_FIINFO,
20355+ AuLcNonDir_DIINFO,
20356+ AuLcNonDir_IIINFO,
20357+
20358+ AuLcDir_FIINFO,
20359+ AuLcDir_DIINFO,
20360+ AuLcDir_IIINFO,
20361+
20362+ AuLcSymlink_DIINFO,
20363+ AuLcSymlink_IIINFO,
20364+
20365+ AuLcKey_Last
20366+};
20367+extern struct lock_class_key au_lc_key[AuLcKey_Last];
20368+
1facf9fc 20369+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
20370+int au_seq_path(struct seq_file *seq, struct path *path);
20371+
e49829fe
JR
20372+#ifdef CONFIG_PROC_FS
20373+/* procfs.c */
20374+int __init au_procfs_init(void);
20375+void au_procfs_fin(void);
20376+#else
20377+AuStubInt0(au_procfs_init, void);
20378+AuStubVoid(au_procfs_fin, void);
20379+#endif
20380+
4f0767ce
JR
20381+/* ---------------------------------------------------------------------- */
20382+
20383+/* kmem cache */
1facf9fc 20384+enum {
20385+ AuCache_DINFO,
20386+ AuCache_ICNTNR,
20387+ AuCache_FINFO,
20388+ AuCache_VDIR,
20389+ AuCache_DEHSTR,
7eafdf33 20390+ AuCache_HNOTIFY, /* must be last */
1facf9fc 20391+ AuCache_Last
20392+};
20393+
4a4d8108
AM
20394+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
20395+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
20396+#define AuCacheCtor(type, ctor) \
20397+ kmem_cache_create(#type, sizeof(struct type), \
20398+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 20399+
20400+extern struct kmem_cache *au_cachep[];
20401+
20402+#define AuCacheFuncs(name, index) \
4a4d8108 20403+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 20404+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 20405+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 20406+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
20407+
20408+AuCacheFuncs(dinfo, DINFO);
20409+AuCacheFuncs(icntnr, ICNTNR);
20410+AuCacheFuncs(finfo, FINFO);
20411+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
20412+AuCacheFuncs(vdir_dehstr, DEHSTR);
20413+#ifdef CONFIG_AUFS_HNOTIFY
20414+AuCacheFuncs(hnotify, HNOTIFY);
20415+#endif
1facf9fc 20416+
4a4d8108
AM
20417+#endif /* __KERNEL__ */
20418+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
20419diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
20420--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 20421+++ linux/fs/aufs/mvdown.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 20422@@ -0,0 +1,627 @@
c2b27bf2 20423+/*
523b37e3 20424+ * Copyright (C) 2011-2014 Junjiro R. Okajima
c2b27bf2
AM
20425+ *
20426+ * This program, aufs is free software; you can redistribute it and/or modify
20427+ * it under the terms of the GNU General Public License as published by
20428+ * the Free Software Foundation; either version 2 of the License, or
20429+ * (at your option) any later version.
20430+ *
20431+ * This program is distributed in the hope that it will be useful,
20432+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20433+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20434+ * GNU General Public License for more details.
20435+ *
20436+ * You should have received a copy of the GNU General Public License
523b37e3
AM
20437+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20438+ */
20439+
20440+/*
20441+ * move-down, opposite of copy-up
c2b27bf2
AM
20442+ */
20443+
20444+#include "aufs.h"
20445+
c2b27bf2
AM
20446+struct au_mvd_args {
20447+ struct {
c2b27bf2
AM
20448+ struct super_block *h_sb;
20449+ struct dentry *h_parent;
20450+ struct au_hinode *hdir;
392086de 20451+ struct inode *h_dir, *h_inode;
c2b27bf2
AM
20452+ } info[AUFS_MVDOWN_NARRAY];
20453+
20454+ struct aufs_mvdown mvdown;
20455+ struct dentry *dentry, *parent;
20456+ struct inode *inode, *dir;
20457+ struct super_block *sb;
20458+ aufs_bindex_t bopq, bwh, bfound;
20459+ unsigned char rename_lock;
20460+ struct au_pin pin;
20461+};
20462+
392086de
AM
20463+#define mvd_errno mvdown.au_errno
20464+#define mvd_bsrc mvdown.a[AUFS_MVDOWN_UPPER].bindex
20465+#define mvd_src_brid mvdown.a[AUFS_MVDOWN_UPPER].brid
20466+#define mvd_bdst mvdown.a[AUFS_MVDOWN_LOWER].bindex
20467+#define mvd_dst_brid mvdown.a[AUFS_MVDOWN_LOWER].brid
c2b27bf2 20468+
392086de
AM
20469+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
20470+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
20471+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
20472+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
20473+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
20474+
20475+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
20476+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
20477+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
20478+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
20479+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c2b27bf2
AM
20480+
20481+#define AU_MVD_PR(flag, ...) do { \
20482+ if (flag) \
20483+ pr_err(__VA_ARGS__); \
20484+ } while (0)
20485+
20486+/* make the parent dir on bdst */
392086de 20487+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20488+{
20489+ int err;
20490+
20491+ err = 0;
20492+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
20493+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
20494+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
20495+ a->mvd_h_dst_parent = NULL;
20496+ if (au_dbend(a->parent) >= a->mvd_bdst)
20497+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
20498+ if (!a->mvd_h_dst_parent) {
20499+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
20500+ if (unlikely(err)) {
392086de 20501+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
20502+ goto out;
20503+ }
20504+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
20505+ }
20506+
20507+out:
20508+ AuTraceErr(err);
20509+ return err;
20510+}
20511+
20512+/* lock them all */
392086de 20513+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20514+{
20515+ int err;
20516+ struct dentry *h_trap;
20517+
20518+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
20519+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
20520+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
20521+ a->rename_lock = 0;
392086de
AM
20522+ err = au_pin(&a->pin, a->dentry, a->mvd_bdst,
20523+ au_opt_udba(a->sb),
c2b27bf2
AM
20524+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
20525+ if (!err) {
20526+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
20527+ mutex_lock_nested(&a->mvd_h_src_dir->i_mutex,
20528+ AuLsc_I_PARENT3);
20529+ } else
392086de 20530+ AU_MVD_PR(dmsg, "pin failed\n");
c2b27bf2
AM
20531+ goto out;
20532+ }
20533+
20534+ err = 0;
20535+ a->rename_lock = 1;
20536+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
20537+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
20538+ if (h_trap) {
20539+ err = (h_trap != a->mvd_h_src_parent);
20540+ if (err)
20541+ err = (h_trap != a->mvd_h_dst_parent);
20542+ }
20543+ BUG_ON(err); /* it should never happen */
20544+
20545+out:
20546+ AuTraceErr(err);
20547+ return err;
20548+}
20549+
392086de 20550+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20551+{
20552+ if (!a->rename_lock) {
20553+ mutex_unlock(&a->mvd_h_src_dir->i_mutex);
20554+ au_unpin(&a->pin);
20555+ } else
20556+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
20557+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
20558+}
20559+
20560+/* copy-down the file */
392086de 20561+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20562+{
20563+ int err;
20564+ struct au_cp_generic cpg = {
20565+ .dentry = a->dentry,
20566+ .bdst = a->mvd_bdst,
20567+ .bsrc = a->mvd_bsrc,
20568+ .len = -1,
20569+ .pin = &a->pin,
20570+ .flags = AuCpup_DTIME | AuCpup_HOPEN
20571+ };
20572+
20573+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
20574+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
20575+ au_fset_cpup(cpg.flags, OVERWRITE);
20576+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
20577+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
20578+ err = au_sio_cpdown_simple(&cpg);
20579+ if (unlikely(err))
392086de 20580+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
20581+
20582+ AuTraceErr(err);
20583+ return err;
20584+}
20585+
20586+/*
20587+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
20588+ * were sleeping
20589+ */
392086de 20590+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20591+{
20592+ int err;
20593+ struct path h_path;
20594+ struct au_branch *br;
523b37e3 20595+ struct inode *delegated;
c2b27bf2
AM
20596+
20597+ br = au_sbr(a->sb, a->mvd_bdst);
20598+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
20599+ err = PTR_ERR(h_path.dentry);
20600+ if (IS_ERR(h_path.dentry)) {
392086de 20601+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
20602+ goto out;
20603+ }
20604+
20605+ err = 0;
20606+ if (h_path.dentry->d_inode) {
20607+ h_path.mnt = au_br_mnt(br);
523b37e3 20608+ delegated = NULL;
c2b27bf2 20609+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
523b37e3
AM
20610+ &delegated, /*force*/0);
20611+ if (unlikely(err == -EWOULDBLOCK)) {
20612+ pr_warn("cannot retry for NFSv4 delegation"
20613+ " for an internal unlink\n");
20614+ iput(delegated);
20615+ }
c2b27bf2 20616+ if (unlikely(err))
392086de 20617+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
20618+ }
20619+ dput(h_path.dentry);
20620+
20621+out:
20622+ AuTraceErr(err);
20623+ return err;
20624+}
20625+
20626+/*
20627+ * unlink the topmost h_dentry
20628+ * Note: the target file MAY be modified by UDBA between this mutex_unlock() and
20629+ * mutex_lock() in vfs_unlink(). in this case, such changes may be lost.
20630+ */
392086de 20631+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20632+{
20633+ int err;
20634+ struct path h_path;
523b37e3 20635+ struct inode *delegated;
c2b27bf2
AM
20636+
20637+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
20638+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
20639+ delegated = NULL;
20640+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
20641+ if (unlikely(err == -EWOULDBLOCK)) {
20642+ pr_warn("cannot retry for NFSv4 delegation"
20643+ " for an internal unlink\n");
20644+ iput(delegated);
20645+ }
c2b27bf2 20646+ if (unlikely(err))
392086de 20647+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
20648+
20649+ AuTraceErr(err);
20650+ return err;
20651+}
20652+
20653+/*
20654+ * copy-down the file and unlink the bsrc file.
20655+ * - unlink the bdst whout if exist
20656+ * - copy-down the file (with whtmp name and rename)
20657+ * - unlink the bsrc file
20658+ */
392086de 20659+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20660+{
20661+ int err;
20662+
392086de 20663+ err = au_do_mkdir(dmsg, a);
c2b27bf2 20664+ if (!err)
392086de 20665+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
20666+ if (unlikely(err))
20667+ goto out;
20668+
20669+ /*
20670+ * do not revert the activities we made on bdst since they should be
20671+ * harmless in aufs.
20672+ */
20673+
392086de 20674+ err = au_do_cpdown(dmsg, a);
c2b27bf2 20675+ if (!err)
392086de
AM
20676+ err = au_do_unlink_wh(dmsg, a);
20677+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
20678+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
20679+ if (unlikely(err))
20680+ goto out_unlock;
20681+
20682+ /* maintain internal array */
392086de
AM
20683+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
20684+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
20685+ au_set_dbstart(a->dentry, a->mvd_bdst);
20686+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
20687+ au_set_ibstart(a->inode, a->mvd_bdst);
20688+ }
c2b27bf2
AM
20689+ if (au_dbend(a->dentry) < a->mvd_bdst)
20690+ au_set_dbend(a->dentry, a->mvd_bdst);
c2b27bf2
AM
20691+ if (au_ibend(a->inode) < a->mvd_bdst)
20692+ au_set_ibend(a->inode, a->mvd_bdst);
20693+
20694+out_unlock:
392086de 20695+ au_do_unlock(dmsg, a);
c2b27bf2
AM
20696+out:
20697+ AuTraceErr(err);
20698+ return err;
20699+}
20700+
20701+/* ---------------------------------------------------------------------- */
20702+
392086de 20703+static int find_lower_writable(struct au_mvd_args *a)
c2b27bf2 20704+{
392086de
AM
20705+ struct super_block *sb;
20706+ aufs_bindex_t bindex, bend;
c2b27bf2
AM
20707+ struct au_branch *br;
20708+
392086de
AM
20709+ sb = a->sb;
20710+ bindex = a->mvd_bsrc;
c2b27bf2 20711+ bend = au_sbend(sb);
392086de
AM
20712+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER)) {
20713+ for (bindex++; bindex <= bend; bindex++) {
20714+ br = au_sbr(sb, bindex);
20715+ if (!au_br_rdonly(br))
20716+ return bindex;
20717+ }
20718+ } else {
20719+ for (bindex++; bindex <= bend; bindex++) {
20720+ br = au_sbr(sb, bindex);
20721+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
20722+ if (au_br_rdonly(br))
20723+ a->mvdown.flags
20724+ |= AUFS_MVDOWN_ROLOWER_R;
20725+ return bindex;
20726+ }
20727+ }
c2b27bf2
AM
20728+ }
20729+
20730+ return -1;
20731+}
20732+
20733+/* make sure the file is idle */
392086de 20734+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20735+{
20736+ int err, plinked;
c2b27bf2
AM
20737+
20738+ err = 0;
c2b27bf2
AM
20739+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
20740+ if (au_dbstart(a->dentry) == a->mvd_bsrc
392086de 20741+ && d_count(a->dentry) == 1
c2b27bf2 20742+ && atomic_read(&a->inode->i_count) == 1
392086de 20743+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
20744+ && (!plinked || !au_plink_test(a->inode))
20745+ && a->inode->i_nlink == 1)
20746+ goto out;
20747+
20748+ err = -EBUSY;
392086de 20749+ AU_MVD_PR(dmsg,
c2b27bf2 20750+ "b%d, d{b%d, c%u?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
392086de 20751+ a->mvd_bsrc, au_dbstart(a->dentry), d_count(a->dentry),
c2b27bf2 20752+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 20753+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
20754+ plinked, plinked ? au_plink_test(a->inode) : 0);
20755+
20756+out:
20757+ AuTraceErr(err);
20758+ return err;
20759+}
20760+
20761+/* make sure the parent dir is fine */
392086de 20762+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
20763+ struct au_mvd_args *a)
20764+{
20765+ int err;
20766+ aufs_bindex_t bindex;
20767+
20768+ err = 0;
20769+ if (unlikely(au_alive_dir(a->parent))) {
20770+ err = -ENOENT;
392086de 20771+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
20772+ goto out;
20773+ }
20774+
20775+ a->bopq = au_dbdiropq(a->parent);
20776+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
20777+ AuDbg("b%d\n", bindex);
20778+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
20779+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
20780+ err = -EINVAL;
392086de
AM
20781+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
20782+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
20783+ a->bopq, a->mvd_bdst);
20784+ }
20785+
20786+out:
20787+ AuTraceErr(err);
20788+ return err;
20789+}
20790+
392086de 20791+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
20792+ struct au_mvd_args *a)
20793+{
20794+ int err;
20795+ struct au_dinfo *dinfo, *tmp;
20796+
20797+ /* lookup the next lower positive entry */
20798+ err = -ENOMEM;
20799+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
20800+ if (unlikely(!tmp))
20801+ goto out;
20802+
20803+ a->bfound = -1;
20804+ a->bwh = -1;
20805+ dinfo = au_di(a->dentry);
20806+ au_di_cp(tmp, dinfo);
20807+ au_di_swap(tmp, dinfo);
20808+
20809+ /* returns the number of positive dentries */
20810+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
20811+ if (!err)
20812+ a->bwh = au_dbwh(a->dentry);
20813+ else if (err > 0)
20814+ a->bfound = au_dbstart(a->dentry);
20815+
20816+ au_di_swap(tmp, dinfo);
20817+ au_rw_write_unlock(&tmp->di_rwsem);
20818+ au_di_free(tmp);
20819+ if (unlikely(err < 0))
392086de 20820+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
20821+
20822+ /*
20823+ * here, we have these cases.
20824+ * bfound == -1
20825+ * no positive dentry under bsrc. there are more sub-cases.
20826+ * bwh < 0
20827+ * there no whiteout, we can safely move-down.
20828+ * bwh <= bsrc
20829+ * impossible
20830+ * bsrc < bwh && bwh < bdst
20831+ * there is a whiteout on RO branch. cannot proceed.
20832+ * bwh == bdst
20833+ * there is a whiteout on the RW target branch. it should
20834+ * be removed.
20835+ * bdst < bwh
20836+ * there is a whiteout somewhere unrelated branch.
20837+ * -1 < bfound && bfound <= bsrc
20838+ * impossible.
20839+ * bfound < bdst
20840+ * found, but it is on RO branch between bsrc and bdst. cannot
20841+ * proceed.
20842+ * bfound == bdst
20843+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
20844+ * error.
20845+ * bdst < bfound
20846+ * found, after we create the file on bdst, it will be hidden.
20847+ */
20848+
20849+ AuDebugOn(a->bfound == -1
20850+ && a->bwh != -1
20851+ && a->bwh <= a->mvd_bsrc);
20852+ AuDebugOn(-1 < a->bfound
20853+ && a->bfound <= a->mvd_bsrc);
20854+
20855+ err = -EINVAL;
20856+ if (a->bfound == -1
20857+ && a->mvd_bsrc < a->bwh
20858+ && a->bwh != -1
20859+ && a->bwh < a->mvd_bdst) {
392086de
AM
20860+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
20861+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
20862+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
20863+ goto out;
20864+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
20865+ a->mvd_errno = EAU_MVDOWN_UPPER;
20866+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
20867+ a->mvd_bdst, a->bfound);
20868+ goto out;
20869+ }
20870+
20871+ err = 0; /* success */
20872+
20873+out:
20874+ AuTraceErr(err);
20875+ return err;
20876+}
20877+
392086de 20878+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20879+{
20880+ int err;
20881+
392086de
AM
20882+ err = 0;
20883+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
20884+ && a->bfound == a->mvd_bdst)
20885+ err = -EEXIST;
c2b27bf2
AM
20886+ AuTraceErr(err);
20887+ return err;
20888+}
20889+
392086de 20890+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
20891+{
20892+ int err;
20893+ struct au_branch *br;
20894+
20895+ err = -EISDIR;
20896+ if (unlikely(S_ISDIR(a->inode->i_mode)))
20897+ goto out;
20898+
20899+ err = -EINVAL;
392086de
AM
20900+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
20901+ a->mvd_bsrc = au_ibstart(a->inode);
20902+ else {
20903+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
20904+ if (unlikely(a->mvd_bsrc < 0
20905+ || (a->mvd_bsrc < au_dbstart(a->dentry)
20906+ || au_dbend(a->dentry) < a->mvd_bsrc
20907+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
20908+ || (a->mvd_bsrc < au_ibstart(a->inode)
20909+ || au_ibend(a->inode) < a->mvd_bsrc
20910+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
20911+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
20912+ AU_MVD_PR(dmsg, "no upper\n");
20913+ goto out;
20914+ }
20915+ }
c2b27bf2 20916+ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
392086de
AM
20917+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
20918+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
20919+ goto out;
20920+ }
392086de 20921+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
20922+ br = au_sbr(a->sb, a->mvd_bsrc);
20923+ err = au_br_rdonly(br);
392086de
AM
20924+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
20925+ if (unlikely(err))
20926+ goto out;
20927+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
20928+ || IS_APPEND(a->mvd_h_src_inode))) {
20929+ if (err)
20930+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
20931+ /* go on */
20932+ } else
c2b27bf2
AM
20933+ goto out;
20934+
20935+ err = -EINVAL;
392086de
AM
20936+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
20937+ a->mvd_bdst = find_lower_writable(a);
20938+ if (unlikely(a->mvd_bdst < 0)) {
20939+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
20940+ AU_MVD_PR(dmsg, "no writable lower branch\n");
20941+ goto out;
20942+ }
20943+ } else {
20944+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
20945+ if (unlikely(a->mvd_bdst < 0
20946+ || au_sbend(a->sb) < a->mvd_bdst)) {
20947+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
20948+ AU_MVD_PR(dmsg, "no lower brid\n");
20949+ goto out;
20950+ }
c2b27bf2
AM
20951+ }
20952+
392086de 20953+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 20954+ if (!err)
392086de 20955+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 20956+ if (!err)
392086de 20957+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 20958+ if (!err)
392086de 20959+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
20960+ if (!err)
20961+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
20962+
20963+out:
20964+ AuTraceErr(err);
20965+ return err;
20966+}
20967+
20968+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
20969+{
392086de
AM
20970+ int err, e;
20971+ unsigned char dmsg;
20972+ struct au_mvd_args *args;
c2b27bf2
AM
20973+
20974+ err = -EPERM;
20975+ if (unlikely(!capable(CAP_SYS_ADMIN)))
20976+ goto out;
20977+
392086de
AM
20978+ WARN_ONCE(1, "move-down is still testing...\n");
20979+
20980+ err = -ENOMEM;
20981+ args = kmalloc(sizeof(*args), GFP_NOFS);
20982+ if (unlikely(!args))
20983+ goto out;
20984+
20985+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
20986+ if (!err)
20987+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
20988+ if (unlikely(err)) {
20989+ err = -EFAULT;
392086de
AM
20990+ AuTraceErr(err);
20991+ goto out_free;
c2b27bf2 20992+ }
392086de
AM
20993+ AuDbg("flags 0x%x\n", args->mvdown.flags);
20994+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
20995+ args->mvdown.au_errno = 0;
20996+ args->dentry = dentry;
20997+ args->inode = dentry->d_inode;
20998+ args->sb = dentry->d_sb;
c2b27bf2 20999+
392086de
AM
21000+ err = -ENOENT;
21001+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
21002+ args->parent = dget_parent(dentry);
21003+ args->dir = args->parent->d_inode;
21004+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
21005+ dput(args->parent);
21006+ if (unlikely(args->parent != dentry->d_parent)) {
21007+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
21008+ goto out_dir;
21009+ }
21010+
392086de 21011+ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
c2b27bf2
AM
21012+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
21013+ if (unlikely(err))
21014+ goto out_inode;
21015+
392086de
AM
21016+ di_write_lock_parent(args->parent);
21017+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
21018+ if (unlikely(err))
21019+ goto out_parent;
21020+
21021+ AuDbgDentry(dentry);
392086de
AM
21022+ AuDbgInode(args->inode);
21023+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
21024+ if (unlikely(err))
21025+ goto out_parent;
21026+ AuDbgDentry(dentry);
392086de 21027+ AuDbgInode(args->inode);
c2b27bf2 21028+
392086de
AM
21029+ au_cpup_attr_timesizes(args->dir);
21030+ au_cpup_attr_timesizes(args->inode);
21031+ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
c2b27bf2
AM
21032+ /* au_digen_dec(dentry); */
21033+
21034+out_parent:
392086de 21035+ di_write_unlock(args->parent);
c2b27bf2
AM
21036+ aufs_read_unlock(dentry, AuLock_DW);
21037+out_inode:
392086de 21038+ mutex_unlock(&args->inode->i_mutex);
c2b27bf2 21039+out_dir:
392086de
AM
21040+ mutex_unlock(&args->dir->i_mutex);
21041+out_free:
21042+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
21043+ if (unlikely(e))
21044+ err = -EFAULT;
21045+ kfree(args);
c2b27bf2
AM
21046+out:
21047+ AuTraceErr(err);
21048+ return err;
21049+}
21050diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
21051--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 21052+++ linux/fs/aufs/opts.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 21053@@ -0,0 +1,1701 @@
1facf9fc 21054+/*
523b37e3 21055+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 21056+ *
21057+ * This program, aufs is free software; you can redistribute it and/or modify
21058+ * it under the terms of the GNU General Public License as published by
21059+ * the Free Software Foundation; either version 2 of the License, or
21060+ * (at your option) any later version.
dece6358
AM
21061+ *
21062+ * This program is distributed in the hope that it will be useful,
21063+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21064+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21065+ * GNU General Public License for more details.
21066+ *
21067+ * You should have received a copy of the GNU General Public License
523b37e3 21068+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21069+ */
21070+
21071+/*
21072+ * mount options/flags
21073+ */
21074+
dece6358 21075+#include <linux/namei.h>
1facf9fc 21076+#include <linux/types.h> /* a distribution requires */
21077+#include <linux/parser.h>
21078+#include "aufs.h"
21079+
21080+/* ---------------------------------------------------------------------- */
21081+
21082+enum {
21083+ Opt_br,
21084+ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
21085+ Opt_idel, Opt_imod, Opt_ireorder,
21086+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
dece6358 21087+ Opt_rdblk_def, Opt_rdhash_def,
1facf9fc 21088+ Opt_xino, Opt_zxino, Opt_noxino,
21089+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
21090+ Opt_trunc_xino_path, Opt_itrunc_xino,
21091+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 21092+ Opt_shwh, Opt_noshwh,
1facf9fc 21093+ Opt_plink, Opt_noplink, Opt_list_plink,
21094+ Opt_udba,
4a4d8108 21095+ Opt_dio, Opt_nodio,
1facf9fc 21096+ /* Opt_lock, Opt_unlock, */
21097+ Opt_cmd, Opt_cmd_args,
21098+ Opt_diropq_a, Opt_diropq_w,
21099+ Opt_warn_perm, Opt_nowarn_perm,
21100+ Opt_wbr_copyup, Opt_wbr_create,
21101+ Opt_refrof, Opt_norefrof,
21102+ Opt_verbose, Opt_noverbose,
21103+ Opt_sum, Opt_nosum, Opt_wsum,
21104+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
21105+};
21106+
21107+static match_table_t options = {
21108+ {Opt_br, "br=%s"},
21109+ {Opt_br, "br:%s"},
21110+
21111+ {Opt_add, "add=%d:%s"},
21112+ {Opt_add, "add:%d:%s"},
21113+ {Opt_add, "ins=%d:%s"},
21114+ {Opt_add, "ins:%d:%s"},
21115+ {Opt_append, "append=%s"},
21116+ {Opt_append, "append:%s"},
21117+ {Opt_prepend, "prepend=%s"},
21118+ {Opt_prepend, "prepend:%s"},
21119+
21120+ {Opt_del, "del=%s"},
21121+ {Opt_del, "del:%s"},
21122+ /* {Opt_idel, "idel:%d"}, */
21123+ {Opt_mod, "mod=%s"},
21124+ {Opt_mod, "mod:%s"},
21125+ /* {Opt_imod, "imod:%d:%s"}, */
21126+
21127+ {Opt_dirwh, "dirwh=%d"},
21128+
21129+ {Opt_xino, "xino=%s"},
21130+ {Opt_noxino, "noxino"},
21131+ {Opt_trunc_xino, "trunc_xino"},
21132+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
21133+ {Opt_notrunc_xino, "notrunc_xino"},
21134+ {Opt_trunc_xino_path, "trunc_xino=%s"},
21135+ {Opt_itrunc_xino, "itrunc_xino=%d"},
21136+ /* {Opt_zxino, "zxino=%s"}, */
21137+ {Opt_trunc_xib, "trunc_xib"},
21138+ {Opt_notrunc_xib, "notrunc_xib"},
21139+
e49829fe 21140+#ifdef CONFIG_PROC_FS
1facf9fc 21141+ {Opt_plink, "plink"},
e49829fe
JR
21142+#else
21143+ {Opt_ignore_silent, "plink"},
21144+#endif
21145+
1facf9fc 21146+ {Opt_noplink, "noplink"},
e49829fe 21147+
1facf9fc 21148+#ifdef CONFIG_AUFS_DEBUG
21149+ {Opt_list_plink, "list_plink"},
21150+#endif
21151+
21152+ {Opt_udba, "udba=%s"},
21153+
4a4d8108
AM
21154+ {Opt_dio, "dio"},
21155+ {Opt_nodio, "nodio"},
21156+
1facf9fc 21157+ {Opt_diropq_a, "diropq=always"},
21158+ {Opt_diropq_a, "diropq=a"},
21159+ {Opt_diropq_w, "diropq=whiteouted"},
21160+ {Opt_diropq_w, "diropq=w"},
21161+
21162+ {Opt_warn_perm, "warn_perm"},
21163+ {Opt_nowarn_perm, "nowarn_perm"},
21164+
21165+ /* keep them temporary */
21166+ {Opt_ignore_silent, "coo=%s"},
21167+ {Opt_ignore_silent, "nodlgt"},
21168+ {Opt_ignore_silent, "nodirperm1"},
1facf9fc 21169+ {Opt_ignore_silent, "clean_plink"},
21170+
dece6358
AM
21171+#ifdef CONFIG_AUFS_SHWH
21172+ {Opt_shwh, "shwh"},
21173+#endif
21174+ {Opt_noshwh, "noshwh"},
21175+
1facf9fc 21176+ {Opt_rendir, "rendir=%d"},
21177+
21178+ {Opt_refrof, "refrof"},
21179+ {Opt_norefrof, "norefrof"},
21180+
21181+ {Opt_verbose, "verbose"},
21182+ {Opt_verbose, "v"},
21183+ {Opt_noverbose, "noverbose"},
21184+ {Opt_noverbose, "quiet"},
21185+ {Opt_noverbose, "q"},
21186+ {Opt_noverbose, "silent"},
21187+
21188+ {Opt_sum, "sum"},
21189+ {Opt_nosum, "nosum"},
21190+ {Opt_wsum, "wsum"},
21191+
21192+ {Opt_rdcache, "rdcache=%d"},
21193+ {Opt_rdblk, "rdblk=%d"},
dece6358 21194+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 21195+ {Opt_rdhash, "rdhash=%d"},
dece6358 21196+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 21197+
21198+ {Opt_wbr_create, "create=%s"},
21199+ {Opt_wbr_create, "create_policy=%s"},
21200+ {Opt_wbr_copyup, "cpup=%s"},
21201+ {Opt_wbr_copyup, "copyup=%s"},
21202+ {Opt_wbr_copyup, "copyup_policy=%s"},
21203+
21204+ /* internal use for the scripts */
21205+ {Opt_ignore_silent, "si=%s"},
21206+
21207+ {Opt_br, "dirs=%s"},
21208+ {Opt_ignore, "debug=%d"},
21209+ {Opt_ignore, "delete=whiteout"},
21210+ {Opt_ignore, "delete=all"},
21211+ {Opt_ignore, "imap=%s"},
21212+
1308ab2a 21213+ /* temporary workaround, due to old mount(8)? */
21214+ {Opt_ignore_silent, "relatime"},
21215+
1facf9fc 21216+ {Opt_err, NULL}
21217+};
21218+
21219+/* ---------------------------------------------------------------------- */
21220+
21221+static const char *au_parser_pattern(int val, struct match_token *token)
21222+{
21223+ while (token->pattern) {
21224+ if (token->token == val)
21225+ return token->pattern;
21226+ token++;
21227+ }
21228+ BUG();
21229+ return "??";
21230+}
21231+
21232+/* ---------------------------------------------------------------------- */
21233+
1e00d052 21234+static match_table_t brperm = {
1facf9fc 21235+ {AuBrPerm_RO, AUFS_BRPERM_RO},
21236+ {AuBrPerm_RR, AUFS_BRPERM_RR},
21237+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
21238+ {0, NULL}
21239+};
1facf9fc 21240+
86dc4139
AM
21241+static match_table_t brattr = {
21242+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
1e00d052 21243+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
1e00d052
AM
21244+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
21245+ {0, NULL}
1facf9fc 21246+};
21247+
86dc4139
AM
21248+#define AuBrStr_LONGEST AUFS_BRPERM_RW \
21249+ "+" AUFS_BRATTR_UNPIN \
21250+ "+" AUFS_BRWATTR_NLWH
1e00d052
AM
21251+
21252+static int br_attr_val(char *str, match_table_t table, substring_t args[])
21253+{
21254+ int attr, v;
21255+ char *p;
21256+
21257+ attr = 0;
21258+ do {
21259+ p = strchr(str, '+');
21260+ if (p)
21261+ *p = 0;
21262+ v = match_token(str, table, args);
21263+ if (v)
21264+ attr |= v;
21265+ else {
21266+ if (p)
21267+ *p = '+';
0c3ec466 21268+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
21269+ break;
21270+ }
21271+ if (p)
21272+ str = p + 1;
21273+ } while (p);
21274+
21275+ return attr;
21276+}
21277+
4a4d8108 21278+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 21279+{
21280+ int val;
86dc4139 21281+ char *p, *q;
1facf9fc 21282+ substring_t args[MAX_OPT_ARGS];
21283+
1e00d052
AM
21284+ p = strchr(perm, '+');
21285+ if (p)
21286+ *p = 0;
21287+ val = match_token(perm, brperm, args);
21288+ if (!val) {
21289+ if (p)
21290+ *p = '+';
0c3ec466 21291+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
21292+ val = AuBrPerm_RO;
21293+ goto out;
21294+ }
21295+ if (!p)
21296+ goto out;
21297+
86dc4139
AM
21298+ p++;
21299+ while (1) {
21300+ q = strchr(p, '+');
21301+ if (q)
21302+ *q = 0;
21303+ val |= br_attr_val(p, brattr, args);
21304+ if (q) {
21305+ *q = '+';
21306+ p = q + 1;
21307+ } else
21308+ break;
21309+ }
21310+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
21311+ case AuBrPerm_RO:
21312+ case AuBrPerm_RR:
86dc4139
AM
21313+ if (unlikely(val & AuBrWAttr_NoLinkWH)) {
21314+ pr_warn("ignored branch attribute %s\n",
21315+ AUFS_BRWATTR_NLWH);
21316+ val &= ~AuBrWAttr_NoLinkWH;
21317+ }
1e00d052
AM
21318+ break;
21319+ case AuBrPerm_RW:
86dc4139
AM
21320+ if (unlikely(val & AuBrRAttr_WH)) {
21321+ pr_warn("ignored branch attribute %s\n",
21322+ AUFS_BRRATTR_WH);
21323+ val &= ~AuBrRAttr_WH;
21324+ }
1e00d052
AM
21325+ break;
21326+ }
21327+
21328+out:
1facf9fc 21329+ return val;
21330+}
21331+
1e00d052
AM
21332+/* Caller should free the return value */
21333+char *au_optstr_br_perm(int brperm)
1facf9fc 21334+{
1e00d052
AM
21335+ char *p, a[sizeof(AuBrStr_LONGEST)];
21336+ int sz;
21337+
21338+#define SetPerm(str) do { \
21339+ sz = sizeof(str); \
21340+ memcpy(a, str, sz); \
21341+ p = a + sz - 1; \
21342+ } while (0)
21343+
21344+#define AppendAttr(flag, str) do { \
21345+ if (brperm & flag) { \
21346+ sz = sizeof(str); \
21347+ *p++ = '+'; \
21348+ memcpy(p, str, sz); \
21349+ p += sz - 1; \
21350+ } \
21351+ } while (0)
21352+
21353+ switch (brperm & AuBrPerm_Mask) {
21354+ case AuBrPerm_RO:
21355+ SetPerm(AUFS_BRPERM_RO);
21356+ break;
21357+ case AuBrPerm_RR:
21358+ SetPerm(AUFS_BRPERM_RR);
21359+ break;
21360+ case AuBrPerm_RW:
21361+ SetPerm(AUFS_BRPERM_RW);
21362+ break;
21363+ default:
21364+ AuDebugOn(1);
21365+ }
21366+
86dc4139 21367+ AppendAttr(AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN);
1e00d052
AM
21368+ AppendAttr(AuBrRAttr_WH, AUFS_BRRATTR_WH);
21369+ AppendAttr(AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH);
21370+
21371+ AuDebugOn(strlen(a) >= sizeof(a));
21372+ return kstrdup(a, GFP_NOFS);
21373+#undef SetPerm
21374+#undef AppendAttr
1facf9fc 21375+}
21376+
21377+/* ---------------------------------------------------------------------- */
21378+
21379+static match_table_t udbalevel = {
21380+ {AuOpt_UDBA_REVAL, "reval"},
21381+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
21382+#ifdef CONFIG_AUFS_HNOTIFY
21383+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
21384+#ifdef CONFIG_AUFS_HFSNOTIFY
21385+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 21386+#endif
1facf9fc 21387+#endif
21388+ {-1, NULL}
21389+};
21390+
4a4d8108 21391+static int noinline_for_stack udba_val(char *str)
1facf9fc 21392+{
21393+ substring_t args[MAX_OPT_ARGS];
21394+
7f207e10 21395+ return match_token(str, udbalevel, args);
1facf9fc 21396+}
21397+
21398+const char *au_optstr_udba(int udba)
21399+{
21400+ return au_parser_pattern(udba, (void *)udbalevel);
21401+}
21402+
21403+/* ---------------------------------------------------------------------- */
21404+
21405+static match_table_t au_wbr_create_policy = {
21406+ {AuWbrCreate_TDP, "tdp"},
21407+ {AuWbrCreate_TDP, "top-down-parent"},
21408+ {AuWbrCreate_RR, "rr"},
21409+ {AuWbrCreate_RR, "round-robin"},
21410+ {AuWbrCreate_MFS, "mfs"},
21411+ {AuWbrCreate_MFS, "most-free-space"},
21412+ {AuWbrCreate_MFSV, "mfs:%d"},
21413+ {AuWbrCreate_MFSV, "most-free-space:%d"},
21414+
21415+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
21416+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
21417+ {AuWbrCreate_PMFS, "pmfs"},
21418+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
21419+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
21420+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 21421+
21422+ {-1, NULL}
21423+};
21424+
dece6358
AM
21425+/*
21426+ * cf. linux/lib/parser.c and cmdline.c
21427+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 21428+ * kstrto...().
dece6358 21429+ */
4a4d8108
AM
21430+static int noinline_for_stack
21431+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 21432+{
21433+ int err;
21434+ unsigned int len;
21435+ char a[32];
21436+
21437+ err = -ERANGE;
21438+ len = s->to - s->from;
21439+ if (len + 1 <= sizeof(a)) {
21440+ memcpy(a, s->from, len);
21441+ a[len] = '\0';
9dbd164d 21442+ err = kstrtoull(a, 0, result);
1facf9fc 21443+ }
21444+ return err;
21445+}
21446+
21447+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
21448+ struct au_opt_wbr_create *create)
21449+{
21450+ int err;
21451+ unsigned long long ull;
21452+
21453+ err = 0;
21454+ if (!au_match_ull(arg, &ull))
21455+ create->mfsrr_watermark = ull;
21456+ else {
4a4d8108 21457+ pr_err("bad integer in %s\n", str);
1facf9fc 21458+ err = -EINVAL;
21459+ }
21460+
21461+ return err;
21462+}
21463+
21464+static int au_wbr_mfs_sec(substring_t *arg, char *str,
21465+ struct au_opt_wbr_create *create)
21466+{
21467+ int n, err;
21468+
21469+ err = 0;
027c5e7a 21470+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 21471+ create->mfs_second = n;
21472+ else {
4a4d8108 21473+ pr_err("bad integer in %s\n", str);
1facf9fc 21474+ err = -EINVAL;
21475+ }
21476+
21477+ return err;
21478+}
21479+
4a4d8108
AM
21480+static int noinline_for_stack
21481+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 21482+{
21483+ int err, e;
21484+ substring_t args[MAX_OPT_ARGS];
21485+
21486+ err = match_token(str, au_wbr_create_policy, args);
21487+ create->wbr_create = err;
21488+ switch (err) {
21489+ case AuWbrCreate_MFSRRV:
392086de 21490+ case AuWbrCreate_PMFSRRV:
1facf9fc 21491+ e = au_wbr_mfs_wmark(&args[0], str, create);
21492+ if (!e)
21493+ e = au_wbr_mfs_sec(&args[1], str, create);
21494+ if (unlikely(e))
21495+ err = e;
21496+ break;
21497+ case AuWbrCreate_MFSRR:
392086de 21498+ case AuWbrCreate_PMFSRR:
1facf9fc 21499+ e = au_wbr_mfs_wmark(&args[0], str, create);
21500+ if (unlikely(e)) {
21501+ err = e;
21502+ break;
21503+ }
21504+ /*FALLTHROUGH*/
21505+ case AuWbrCreate_MFS:
21506+ case AuWbrCreate_PMFS:
027c5e7a 21507+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 21508+ break;
21509+ case AuWbrCreate_MFSV:
21510+ case AuWbrCreate_PMFSV:
21511+ e = au_wbr_mfs_sec(&args[0], str, create);
21512+ if (unlikely(e))
21513+ err = e;
21514+ break;
21515+ }
21516+
21517+ return err;
21518+}
21519+
21520+const char *au_optstr_wbr_create(int wbr_create)
21521+{
21522+ return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy);
21523+}
21524+
21525+static match_table_t au_wbr_copyup_policy = {
21526+ {AuWbrCopyup_TDP, "tdp"},
21527+ {AuWbrCopyup_TDP, "top-down-parent"},
21528+ {AuWbrCopyup_BUP, "bup"},
21529+ {AuWbrCopyup_BUP, "bottom-up-parent"},
21530+ {AuWbrCopyup_BU, "bu"},
21531+ {AuWbrCopyup_BU, "bottom-up"},
21532+ {-1, NULL}
21533+};
21534+
4a4d8108 21535+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 21536+{
21537+ substring_t args[MAX_OPT_ARGS];
21538+
21539+ return match_token(str, au_wbr_copyup_policy, args);
21540+}
21541+
21542+const char *au_optstr_wbr_copyup(int wbr_copyup)
21543+{
21544+ return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy);
21545+}
21546+
21547+/* ---------------------------------------------------------------------- */
21548+
21549+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
21550+
21551+static void dump_opts(struct au_opts *opts)
21552+{
21553+#ifdef CONFIG_AUFS_DEBUG
21554+ /* reduce stack space */
21555+ union {
21556+ struct au_opt_add *add;
21557+ struct au_opt_del *del;
21558+ struct au_opt_mod *mod;
21559+ struct au_opt_xino *xino;
21560+ struct au_opt_xino_itrunc *xino_itrunc;
21561+ struct au_opt_wbr_create *create;
21562+ } u;
21563+ struct au_opt *opt;
21564+
21565+ opt = opts->opt;
21566+ while (opt->type != Opt_tail) {
21567+ switch (opt->type) {
21568+ case Opt_add:
21569+ u.add = &opt->add;
21570+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
21571+ u.add->bindex, u.add->pathname, u.add->perm,
21572+ u.add->path.dentry);
21573+ break;
21574+ case Opt_del:
21575+ case Opt_idel:
21576+ u.del = &opt->del;
21577+ AuDbg("del {%s, %p}\n",
21578+ u.del->pathname, u.del->h_path.dentry);
21579+ break;
21580+ case Opt_mod:
21581+ case Opt_imod:
21582+ u.mod = &opt->mod;
21583+ AuDbg("mod {%s, 0x%x, %p}\n",
21584+ u.mod->path, u.mod->perm, u.mod->h_root);
21585+ break;
21586+ case Opt_append:
21587+ u.add = &opt->add;
21588+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
21589+ u.add->bindex, u.add->pathname, u.add->perm,
21590+ u.add->path.dentry);
21591+ break;
21592+ case Opt_prepend:
21593+ u.add = &opt->add;
21594+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
21595+ u.add->bindex, u.add->pathname, u.add->perm,
21596+ u.add->path.dentry);
21597+ break;
21598+ case Opt_dirwh:
21599+ AuDbg("dirwh %d\n", opt->dirwh);
21600+ break;
21601+ case Opt_rdcache:
21602+ AuDbg("rdcache %d\n", opt->rdcache);
21603+ break;
21604+ case Opt_rdblk:
21605+ AuDbg("rdblk %u\n", opt->rdblk);
21606+ break;
dece6358
AM
21607+ case Opt_rdblk_def:
21608+ AuDbg("rdblk_def\n");
21609+ break;
1facf9fc 21610+ case Opt_rdhash:
21611+ AuDbg("rdhash %u\n", opt->rdhash);
21612+ break;
dece6358
AM
21613+ case Opt_rdhash_def:
21614+ AuDbg("rdhash_def\n");
21615+ break;
1facf9fc 21616+ case Opt_xino:
21617+ u.xino = &opt->xino;
523b37e3 21618+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 21619+ break;
21620+ case Opt_trunc_xino:
21621+ AuLabel(trunc_xino);
21622+ break;
21623+ case Opt_notrunc_xino:
21624+ AuLabel(notrunc_xino);
21625+ break;
21626+ case Opt_trunc_xino_path:
21627+ case Opt_itrunc_xino:
21628+ u.xino_itrunc = &opt->xino_itrunc;
21629+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
21630+ break;
21631+
21632+ case Opt_noxino:
21633+ AuLabel(noxino);
21634+ break;
21635+ case Opt_trunc_xib:
21636+ AuLabel(trunc_xib);
21637+ break;
21638+ case Opt_notrunc_xib:
21639+ AuLabel(notrunc_xib);
21640+ break;
dece6358
AM
21641+ case Opt_shwh:
21642+ AuLabel(shwh);
21643+ break;
21644+ case Opt_noshwh:
21645+ AuLabel(noshwh);
21646+ break;
1facf9fc 21647+ case Opt_plink:
21648+ AuLabel(plink);
21649+ break;
21650+ case Opt_noplink:
21651+ AuLabel(noplink);
21652+ break;
21653+ case Opt_list_plink:
21654+ AuLabel(list_plink);
21655+ break;
21656+ case Opt_udba:
21657+ AuDbg("udba %d, %s\n",
21658+ opt->udba, au_optstr_udba(opt->udba));
21659+ break;
4a4d8108
AM
21660+ case Opt_dio:
21661+ AuLabel(dio);
21662+ break;
21663+ case Opt_nodio:
21664+ AuLabel(nodio);
21665+ break;
1facf9fc 21666+ case Opt_diropq_a:
21667+ AuLabel(diropq_a);
21668+ break;
21669+ case Opt_diropq_w:
21670+ AuLabel(diropq_w);
21671+ break;
21672+ case Opt_warn_perm:
21673+ AuLabel(warn_perm);
21674+ break;
21675+ case Opt_nowarn_perm:
21676+ AuLabel(nowarn_perm);
21677+ break;
21678+ case Opt_refrof:
21679+ AuLabel(refrof);
21680+ break;
21681+ case Opt_norefrof:
21682+ AuLabel(norefrof);
21683+ break;
21684+ case Opt_verbose:
21685+ AuLabel(verbose);
21686+ break;
21687+ case Opt_noverbose:
21688+ AuLabel(noverbose);
21689+ break;
21690+ case Opt_sum:
21691+ AuLabel(sum);
21692+ break;
21693+ case Opt_nosum:
21694+ AuLabel(nosum);
21695+ break;
21696+ case Opt_wsum:
21697+ AuLabel(wsum);
21698+ break;
21699+ case Opt_wbr_create:
21700+ u.create = &opt->wbr_create;
21701+ AuDbg("create %d, %s\n", u.create->wbr_create,
21702+ au_optstr_wbr_create(u.create->wbr_create));
21703+ switch (u.create->wbr_create) {
21704+ case AuWbrCreate_MFSV:
21705+ case AuWbrCreate_PMFSV:
21706+ AuDbg("%d sec\n", u.create->mfs_second);
21707+ break;
21708+ case AuWbrCreate_MFSRR:
21709+ AuDbg("%llu watermark\n",
21710+ u.create->mfsrr_watermark);
21711+ break;
21712+ case AuWbrCreate_MFSRRV:
392086de 21713+ case AuWbrCreate_PMFSRRV:
1facf9fc 21714+ AuDbg("%llu watermark, %d sec\n",
21715+ u.create->mfsrr_watermark,
21716+ u.create->mfs_second);
21717+ break;
21718+ }
21719+ break;
21720+ case Opt_wbr_copyup:
21721+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
21722+ au_optstr_wbr_copyup(opt->wbr_copyup));
21723+ break;
21724+ default:
21725+ BUG();
21726+ }
21727+ opt++;
21728+ }
21729+#endif
21730+}
21731+
21732+void au_opts_free(struct au_opts *opts)
21733+{
21734+ struct au_opt *opt;
21735+
21736+ opt = opts->opt;
21737+ while (opt->type != Opt_tail) {
21738+ switch (opt->type) {
21739+ case Opt_add:
21740+ case Opt_append:
21741+ case Opt_prepend:
21742+ path_put(&opt->add.path);
21743+ break;
21744+ case Opt_del:
21745+ case Opt_idel:
21746+ path_put(&opt->del.h_path);
21747+ break;
21748+ case Opt_mod:
21749+ case Opt_imod:
21750+ dput(opt->mod.h_root);
21751+ break;
21752+ case Opt_xino:
21753+ fput(opt->xino.file);
21754+ break;
21755+ }
21756+ opt++;
21757+ }
21758+}
21759+
21760+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
21761+ aufs_bindex_t bindex)
21762+{
21763+ int err;
21764+ struct au_opt_add *add = &opt->add;
21765+ char *p;
21766+
21767+ add->bindex = bindex;
1e00d052 21768+ add->perm = AuBrPerm_RO;
1facf9fc 21769+ add->pathname = opt_str;
21770+ p = strchr(opt_str, '=');
21771+ if (p) {
21772+ *p++ = 0;
21773+ if (*p)
21774+ add->perm = br_perm_val(p);
21775+ }
21776+
21777+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
21778+ if (!err) {
21779+ if (!p) {
21780+ add->perm = AuBrPerm_RO;
21781+ if (au_test_fs_rr(add->path.dentry->d_sb))
21782+ add->perm = AuBrPerm_RR;
21783+ else if (!bindex && !(sb_flags & MS_RDONLY))
21784+ add->perm = AuBrPerm_RW;
21785+ }
21786+ opt->type = Opt_add;
21787+ goto out;
21788+ }
4a4d8108 21789+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 21790+ err = -EINVAL;
21791+
4f0767ce 21792+out:
1facf9fc 21793+ return err;
21794+}
21795+
21796+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
21797+{
21798+ int err;
21799+
21800+ del->pathname = args[0].from;
21801+ AuDbg("del path %s\n", del->pathname);
21802+
21803+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
21804+ if (unlikely(err))
4a4d8108 21805+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 21806+
21807+ return err;
21808+}
21809+
21810+#if 0 /* reserved for future use */
21811+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
21812+ struct au_opt_del *del, substring_t args[])
21813+{
21814+ int err;
21815+ struct dentry *root;
21816+
21817+ err = -EINVAL;
21818+ root = sb->s_root;
21819+ aufs_read_lock(root, AuLock_FLUSH);
21820+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 21821+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 21822+ goto out;
21823+ }
21824+
21825+ err = 0;
21826+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
21827+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
21828+
4f0767ce 21829+out:
1facf9fc 21830+ aufs_read_unlock(root, !AuLock_IR);
21831+ return err;
21832+}
21833+#endif
21834+
4a4d8108
AM
21835+static int noinline_for_stack
21836+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 21837+{
21838+ int err;
21839+ struct path path;
21840+ char *p;
21841+
21842+ err = -EINVAL;
21843+ mod->path = args[0].from;
21844+ p = strchr(mod->path, '=');
21845+ if (unlikely(!p)) {
4a4d8108 21846+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 21847+ goto out;
21848+ }
21849+
21850+ *p++ = 0;
21851+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
21852+ if (unlikely(err)) {
4a4d8108 21853+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 21854+ goto out;
21855+ }
21856+
21857+ mod->perm = br_perm_val(p);
21858+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
21859+ mod->h_root = dget(path.dentry);
21860+ path_put(&path);
21861+
4f0767ce 21862+out:
1facf9fc 21863+ return err;
21864+}
21865+
21866+#if 0 /* reserved for future use */
21867+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
21868+ struct au_opt_mod *mod, substring_t args[])
21869+{
21870+ int err;
21871+ struct dentry *root;
21872+
21873+ err = -EINVAL;
21874+ root = sb->s_root;
21875+ aufs_read_lock(root, AuLock_FLUSH);
21876+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 21877+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 21878+ goto out;
21879+ }
21880+
21881+ err = 0;
21882+ mod->perm = br_perm_val(args[1].from);
21883+ AuDbg("mod path %s, perm 0x%x, %s\n",
21884+ mod->path, mod->perm, args[1].from);
21885+ mod->h_root = dget(au_h_dptr(root, bindex));
21886+
4f0767ce 21887+out:
1facf9fc 21888+ aufs_read_unlock(root, !AuLock_IR);
21889+ return err;
21890+}
21891+#endif
21892+
21893+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
21894+ substring_t args[])
21895+{
21896+ int err;
21897+ struct file *file;
21898+
21899+ file = au_xino_create(sb, args[0].from, /*silent*/0);
21900+ err = PTR_ERR(file);
21901+ if (IS_ERR(file))
21902+ goto out;
21903+
21904+ err = -EINVAL;
21905+ if (unlikely(file->f_dentry->d_sb == sb)) {
21906+ fput(file);
4a4d8108 21907+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 21908+ goto out;
21909+ }
21910+
21911+ err = 0;
21912+ xino->file = file;
21913+ xino->path = args[0].from;
21914+
4f0767ce 21915+out:
1facf9fc 21916+ return err;
21917+}
21918+
4a4d8108
AM
21919+static int noinline_for_stack
21920+au_opts_parse_xino_itrunc_path(struct super_block *sb,
21921+ struct au_opt_xino_itrunc *xino_itrunc,
21922+ substring_t args[])
1facf9fc 21923+{
21924+ int err;
21925+ aufs_bindex_t bend, bindex;
21926+ struct path path;
21927+ struct dentry *root;
21928+
21929+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
21930+ if (unlikely(err)) {
4a4d8108 21931+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 21932+ goto out;
21933+ }
21934+
21935+ xino_itrunc->bindex = -1;
21936+ root = sb->s_root;
21937+ aufs_read_lock(root, AuLock_FLUSH);
21938+ bend = au_sbend(sb);
21939+ for (bindex = 0; bindex <= bend; bindex++) {
21940+ if (au_h_dptr(root, bindex) == path.dentry) {
21941+ xino_itrunc->bindex = bindex;
21942+ break;
21943+ }
21944+ }
21945+ aufs_read_unlock(root, !AuLock_IR);
21946+ path_put(&path);
21947+
21948+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 21949+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 21950+ err = -EINVAL;
21951+ }
21952+
4f0767ce 21953+out:
1facf9fc 21954+ return err;
21955+}
21956+
21957+/* called without aufs lock */
21958+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
21959+{
21960+ int err, n, token;
21961+ aufs_bindex_t bindex;
21962+ unsigned char skipped;
21963+ struct dentry *root;
21964+ struct au_opt *opt, *opt_tail;
21965+ char *opt_str;
21966+ /* reduce the stack space */
21967+ union {
21968+ struct au_opt_xino_itrunc *xino_itrunc;
21969+ struct au_opt_wbr_create *create;
21970+ } u;
21971+ struct {
21972+ substring_t args[MAX_OPT_ARGS];
21973+ } *a;
21974+
21975+ err = -ENOMEM;
21976+ a = kmalloc(sizeof(*a), GFP_NOFS);
21977+ if (unlikely(!a))
21978+ goto out;
21979+
21980+ root = sb->s_root;
21981+ err = 0;
21982+ bindex = 0;
21983+ opt = opts->opt;
21984+ opt_tail = opt + opts->max_opt - 1;
21985+ opt->type = Opt_tail;
21986+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
21987+ err = -EINVAL;
21988+ skipped = 0;
21989+ token = match_token(opt_str, options, a->args);
21990+ switch (token) {
21991+ case Opt_br:
21992+ err = 0;
21993+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
21994+ && *opt_str) {
21995+ err = opt_add(opt, opt_str, opts->sb_flags,
21996+ bindex++);
21997+ if (unlikely(!err && ++opt > opt_tail)) {
21998+ err = -E2BIG;
21999+ break;
22000+ }
22001+ opt->type = Opt_tail;
22002+ skipped = 1;
22003+ }
22004+ break;
22005+ case Opt_add:
22006+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 22007+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 22008+ break;
22009+ }
22010+ bindex = n;
22011+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
22012+ bindex);
22013+ if (!err)
22014+ opt->type = token;
22015+ break;
22016+ case Opt_append:
22017+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
22018+ /*dummy bindex*/1);
22019+ if (!err)
22020+ opt->type = token;
22021+ break;
22022+ case Opt_prepend:
22023+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
22024+ /*bindex*/0);
22025+ if (!err)
22026+ opt->type = token;
22027+ break;
22028+ case Opt_del:
22029+ err = au_opts_parse_del(&opt->del, a->args);
22030+ if (!err)
22031+ opt->type = token;
22032+ break;
22033+#if 0 /* reserved for future use */
22034+ case Opt_idel:
22035+ del->pathname = "(indexed)";
22036+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 22037+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 22038+ break;
22039+ }
22040+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
22041+ if (!err)
22042+ opt->type = token;
22043+ break;
22044+#endif
22045+ case Opt_mod:
22046+ err = au_opts_parse_mod(&opt->mod, a->args);
22047+ if (!err)
22048+ opt->type = token;
22049+ break;
22050+#ifdef IMOD /* reserved for future use */
22051+ case Opt_imod:
22052+ u.mod->path = "(indexed)";
22053+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 22054+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 22055+ break;
22056+ }
22057+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
22058+ if (!err)
22059+ opt->type = token;
22060+ break;
22061+#endif
22062+ case Opt_xino:
22063+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
22064+ if (!err)
22065+ opt->type = token;
22066+ break;
22067+
22068+ case Opt_trunc_xino_path:
22069+ err = au_opts_parse_xino_itrunc_path
22070+ (sb, &opt->xino_itrunc, a->args);
22071+ if (!err)
22072+ opt->type = token;
22073+ break;
22074+
22075+ case Opt_itrunc_xino:
22076+ u.xino_itrunc = &opt->xino_itrunc;
22077+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 22078+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 22079+ break;
22080+ }
22081+ u.xino_itrunc->bindex = n;
22082+ aufs_read_lock(root, AuLock_FLUSH);
22083+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 22084+ pr_err("out of bounds, %d\n", n);
1facf9fc 22085+ aufs_read_unlock(root, !AuLock_IR);
22086+ break;
22087+ }
22088+ aufs_read_unlock(root, !AuLock_IR);
22089+ err = 0;
22090+ opt->type = token;
22091+ break;
22092+
22093+ case Opt_dirwh:
22094+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
22095+ break;
22096+ err = 0;
22097+ opt->type = token;
22098+ break;
22099+
22100+ case Opt_rdcache:
027c5e7a
AM
22101+ if (unlikely(match_int(&a->args[0], &n))) {
22102+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 22103+ break;
027c5e7a
AM
22104+ }
22105+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
22106+ pr_err("rdcache must be smaller than %d\n",
22107+ AUFS_RDCACHE_MAX);
22108+ break;
22109+ }
22110+ opt->rdcache = n;
1facf9fc 22111+ err = 0;
22112+ opt->type = token;
22113+ break;
22114+ case Opt_rdblk:
22115+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 22116+ || n < 0
1facf9fc 22117+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 22118+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 22119+ break;
22120+ }
1308ab2a 22121+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
22122+ pr_err("rdblk must be larger than %d\n",
22123+ NAME_MAX);
1facf9fc 22124+ break;
22125+ }
22126+ opt->rdblk = n;
22127+ err = 0;
22128+ opt->type = token;
22129+ break;
22130+ case Opt_rdhash:
22131+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 22132+ || n < 0
1facf9fc 22133+ || n * sizeof(struct hlist_head)
22134+ > KMALLOC_MAX_SIZE)) {
4a4d8108 22135+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 22136+ break;
22137+ }
22138+ opt->rdhash = n;
22139+ err = 0;
22140+ opt->type = token;
22141+ break;
22142+
22143+ case Opt_trunc_xino:
22144+ case Opt_notrunc_xino:
22145+ case Opt_noxino:
22146+ case Opt_trunc_xib:
22147+ case Opt_notrunc_xib:
dece6358
AM
22148+ case Opt_shwh:
22149+ case Opt_noshwh:
1facf9fc 22150+ case Opt_plink:
22151+ case Opt_noplink:
22152+ case Opt_list_plink:
4a4d8108
AM
22153+ case Opt_dio:
22154+ case Opt_nodio:
1facf9fc 22155+ case Opt_diropq_a:
22156+ case Opt_diropq_w:
22157+ case Opt_warn_perm:
22158+ case Opt_nowarn_perm:
22159+ case Opt_refrof:
22160+ case Opt_norefrof:
22161+ case Opt_verbose:
22162+ case Opt_noverbose:
22163+ case Opt_sum:
22164+ case Opt_nosum:
22165+ case Opt_wsum:
dece6358
AM
22166+ case Opt_rdblk_def:
22167+ case Opt_rdhash_def:
1facf9fc 22168+ err = 0;
22169+ opt->type = token;
22170+ break;
22171+
22172+ case Opt_udba:
22173+ opt->udba = udba_val(a->args[0].from);
22174+ if (opt->udba >= 0) {
22175+ err = 0;
22176+ opt->type = token;
22177+ } else
4a4d8108 22178+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 22179+ break;
22180+
22181+ case Opt_wbr_create:
22182+ u.create = &opt->wbr_create;
22183+ u.create->wbr_create
22184+ = au_wbr_create_val(a->args[0].from, u.create);
22185+ if (u.create->wbr_create >= 0) {
22186+ err = 0;
22187+ opt->type = token;
22188+ } else
4a4d8108 22189+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 22190+ break;
22191+ case Opt_wbr_copyup:
22192+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
22193+ if (opt->wbr_copyup >= 0) {
22194+ err = 0;
22195+ opt->type = token;
22196+ } else
4a4d8108 22197+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 22198+ break;
22199+
22200+ case Opt_ignore:
0c3ec466 22201+ pr_warn("ignored %s\n", opt_str);
1facf9fc 22202+ /*FALLTHROUGH*/
22203+ case Opt_ignore_silent:
22204+ skipped = 1;
22205+ err = 0;
22206+ break;
22207+ case Opt_err:
4a4d8108 22208+ pr_err("unknown option %s\n", opt_str);
1facf9fc 22209+ break;
22210+ }
22211+
22212+ if (!err && !skipped) {
22213+ if (unlikely(++opt > opt_tail)) {
22214+ err = -E2BIG;
22215+ opt--;
22216+ opt->type = Opt_tail;
22217+ break;
22218+ }
22219+ opt->type = Opt_tail;
22220+ }
22221+ }
22222+
22223+ kfree(a);
22224+ dump_opts(opts);
22225+ if (unlikely(err))
22226+ au_opts_free(opts);
22227+
4f0767ce 22228+out:
1facf9fc 22229+ return err;
22230+}
22231+
22232+static int au_opt_wbr_create(struct super_block *sb,
22233+ struct au_opt_wbr_create *create)
22234+{
22235+ int err;
22236+ struct au_sbinfo *sbinfo;
22237+
dece6358
AM
22238+ SiMustWriteLock(sb);
22239+
1facf9fc 22240+ err = 1; /* handled */
22241+ sbinfo = au_sbi(sb);
22242+ if (sbinfo->si_wbr_create_ops->fin) {
22243+ err = sbinfo->si_wbr_create_ops->fin(sb);
22244+ if (!err)
22245+ err = 1;
22246+ }
22247+
22248+ sbinfo->si_wbr_create = create->wbr_create;
22249+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
22250+ switch (create->wbr_create) {
22251+ case AuWbrCreate_MFSRRV:
22252+ case AuWbrCreate_MFSRR:
392086de
AM
22253+ case AuWbrCreate_PMFSRR:
22254+ case AuWbrCreate_PMFSRRV:
1facf9fc 22255+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
22256+ /*FALLTHROUGH*/
22257+ case AuWbrCreate_MFS:
22258+ case AuWbrCreate_MFSV:
22259+ case AuWbrCreate_PMFS:
22260+ case AuWbrCreate_PMFSV:
e49829fe
JR
22261+ sbinfo->si_wbr_mfs.mfs_expire
22262+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 22263+ break;
22264+ }
22265+
22266+ if (sbinfo->si_wbr_create_ops->init)
22267+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
22268+
22269+ return err;
22270+}
22271+
22272+/*
22273+ * returns,
22274+ * plus: processed without an error
22275+ * zero: unprocessed
22276+ */
22277+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
22278+ struct au_opts *opts)
22279+{
22280+ int err;
22281+ struct au_sbinfo *sbinfo;
22282+
dece6358
AM
22283+ SiMustWriteLock(sb);
22284+
1facf9fc 22285+ err = 1; /* handled */
22286+ sbinfo = au_sbi(sb);
22287+ switch (opt->type) {
22288+ case Opt_udba:
22289+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
22290+ sbinfo->si_mntflags |= opt->udba;
22291+ opts->given_udba |= opt->udba;
22292+ break;
22293+
22294+ case Opt_plink:
22295+ au_opt_set(sbinfo->si_mntflags, PLINK);
22296+ break;
22297+ case Opt_noplink:
22298+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 22299+ au_plink_put(sb, /*verbose*/1);
1facf9fc 22300+ au_opt_clr(sbinfo->si_mntflags, PLINK);
22301+ break;
22302+ case Opt_list_plink:
22303+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
22304+ au_plink_list(sb);
22305+ break;
22306+
4a4d8108
AM
22307+ case Opt_dio:
22308+ au_opt_set(sbinfo->si_mntflags, DIO);
22309+ au_fset_opts(opts->flags, REFRESH_DYAOP);
22310+ break;
22311+ case Opt_nodio:
22312+ au_opt_clr(sbinfo->si_mntflags, DIO);
22313+ au_fset_opts(opts->flags, REFRESH_DYAOP);
22314+ break;
22315+
1facf9fc 22316+ case Opt_diropq_a:
22317+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
22318+ break;
22319+ case Opt_diropq_w:
22320+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
22321+ break;
22322+
22323+ case Opt_warn_perm:
22324+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
22325+ break;
22326+ case Opt_nowarn_perm:
22327+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
22328+ break;
22329+
22330+ case Opt_refrof:
22331+ au_opt_set(sbinfo->si_mntflags, REFROF);
22332+ break;
22333+ case Opt_norefrof:
22334+ au_opt_clr(sbinfo->si_mntflags, REFROF);
22335+ break;
22336+
22337+ case Opt_verbose:
22338+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
22339+ break;
22340+ case Opt_noverbose:
22341+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
22342+ break;
22343+
22344+ case Opt_sum:
22345+ au_opt_set(sbinfo->si_mntflags, SUM);
22346+ break;
22347+ case Opt_wsum:
22348+ au_opt_clr(sbinfo->si_mntflags, SUM);
22349+ au_opt_set(sbinfo->si_mntflags, SUM_W);
22350+ case Opt_nosum:
22351+ au_opt_clr(sbinfo->si_mntflags, SUM);
22352+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
22353+ break;
22354+
22355+ case Opt_wbr_create:
22356+ err = au_opt_wbr_create(sb, &opt->wbr_create);
22357+ break;
22358+ case Opt_wbr_copyup:
22359+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
22360+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
22361+ break;
22362+
22363+ case Opt_dirwh:
22364+ sbinfo->si_dirwh = opt->dirwh;
22365+ break;
22366+
22367+ case Opt_rdcache:
e49829fe
JR
22368+ sbinfo->si_rdcache
22369+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 22370+ break;
22371+ case Opt_rdblk:
22372+ sbinfo->si_rdblk = opt->rdblk;
22373+ break;
dece6358
AM
22374+ case Opt_rdblk_def:
22375+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
22376+ break;
1facf9fc 22377+ case Opt_rdhash:
22378+ sbinfo->si_rdhash = opt->rdhash;
22379+ break;
dece6358
AM
22380+ case Opt_rdhash_def:
22381+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
22382+ break;
22383+
22384+ case Opt_shwh:
22385+ au_opt_set(sbinfo->si_mntflags, SHWH);
22386+ break;
22387+ case Opt_noshwh:
22388+ au_opt_clr(sbinfo->si_mntflags, SHWH);
22389+ break;
1facf9fc 22390+
22391+ case Opt_trunc_xino:
22392+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
22393+ break;
22394+ case Opt_notrunc_xino:
22395+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
22396+ break;
22397+
22398+ case Opt_trunc_xino_path:
22399+ case Opt_itrunc_xino:
22400+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
22401+ if (!err)
22402+ err = 1;
22403+ break;
22404+
22405+ case Opt_trunc_xib:
22406+ au_fset_opts(opts->flags, TRUNC_XIB);
22407+ break;
22408+ case Opt_notrunc_xib:
22409+ au_fclr_opts(opts->flags, TRUNC_XIB);
22410+ break;
22411+
22412+ default:
22413+ err = 0;
22414+ break;
22415+ }
22416+
22417+ return err;
22418+}
22419+
22420+/*
22421+ * returns tri-state.
22422+ * plus: processed without an error
22423+ * zero: unprocessed
22424+ * minus: error
22425+ */
22426+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
22427+ struct au_opts *opts)
22428+{
22429+ int err, do_refresh;
22430+
22431+ err = 0;
22432+ switch (opt->type) {
22433+ case Opt_append:
22434+ opt->add.bindex = au_sbend(sb) + 1;
22435+ if (opt->add.bindex < 0)
22436+ opt->add.bindex = 0;
22437+ goto add;
22438+ case Opt_prepend:
22439+ opt->add.bindex = 0;
f6b6e03d 22440+ add: /* indented label */
1facf9fc 22441+ case Opt_add:
22442+ err = au_br_add(sb, &opt->add,
22443+ au_ftest_opts(opts->flags, REMOUNT));
22444+ if (!err) {
22445+ err = 1;
027c5e7a 22446+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22447+ }
22448+ break;
22449+
22450+ case Opt_del:
22451+ case Opt_idel:
22452+ err = au_br_del(sb, &opt->del,
22453+ au_ftest_opts(opts->flags, REMOUNT));
22454+ if (!err) {
22455+ err = 1;
22456+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 22457+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22458+ }
22459+ break;
22460+
22461+ case Opt_mod:
22462+ case Opt_imod:
22463+ err = au_br_mod(sb, &opt->mod,
22464+ au_ftest_opts(opts->flags, REMOUNT),
22465+ &do_refresh);
22466+ if (!err) {
22467+ err = 1;
027c5e7a
AM
22468+ if (do_refresh)
22469+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22470+ }
22471+ break;
22472+ }
22473+
22474+ return err;
22475+}
22476+
22477+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
22478+ struct au_opt_xino **opt_xino,
22479+ struct au_opts *opts)
22480+{
22481+ int err;
22482+ aufs_bindex_t bend, bindex;
22483+ struct dentry *root, *parent, *h_root;
22484+
22485+ err = 0;
22486+ switch (opt->type) {
22487+ case Opt_xino:
22488+ err = au_xino_set(sb, &opt->xino,
22489+ !!au_ftest_opts(opts->flags, REMOUNT));
22490+ if (unlikely(err))
22491+ break;
22492+
22493+ *opt_xino = &opt->xino;
22494+ au_xino_brid_set(sb, -1);
22495+
22496+ /* safe d_parent access */
22497+ parent = opt->xino.file->f_dentry->d_parent;
22498+ root = sb->s_root;
22499+ bend = au_sbend(sb);
22500+ for (bindex = 0; bindex <= bend; bindex++) {
22501+ h_root = au_h_dptr(root, bindex);
22502+ if (h_root == parent) {
22503+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
22504+ break;
22505+ }
22506+ }
22507+ break;
22508+
22509+ case Opt_noxino:
22510+ au_xino_clr(sb);
22511+ au_xino_brid_set(sb, -1);
22512+ *opt_xino = (void *)-1;
22513+ break;
22514+ }
22515+
22516+ return err;
22517+}
22518+
22519+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
22520+ unsigned int pending)
22521+{
22522+ int err;
22523+ aufs_bindex_t bindex, bend;
22524+ unsigned char do_plink, skip, do_free;
22525+ struct au_branch *br;
22526+ struct au_wbr *wbr;
22527+ struct dentry *root;
22528+ struct inode *dir, *h_dir;
22529+ struct au_sbinfo *sbinfo;
22530+ struct au_hinode *hdir;
22531+
dece6358
AM
22532+ SiMustAnyLock(sb);
22533+
1facf9fc 22534+ sbinfo = au_sbi(sb);
22535+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
22536+
dece6358
AM
22537+ if (!(sb_flags & MS_RDONLY)) {
22538+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 22539+ pr_warn("first branch should be rw\n");
dece6358 22540+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 22541+ pr_warn("shwh should be used with ro\n");
dece6358 22542+ }
1facf9fc 22543+
4a4d8108 22544+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 22545+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 22546+ pr_warn("udba=*notify requires xino\n");
1facf9fc 22547+
22548+ err = 0;
22549+ root = sb->s_root;
4a4d8108 22550+ dir = root->d_inode;
1facf9fc 22551+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
22552+ bend = au_sbend(sb);
22553+ for (bindex = 0; !err && bindex <= bend; bindex++) {
22554+ skip = 0;
22555+ h_dir = au_h_iptr(dir, bindex);
22556+ br = au_sbr(sb, bindex);
22557+ do_free = 0;
22558+
22559+ wbr = br->br_wbr;
22560+ if (wbr)
22561+ wbr_wh_read_lock(wbr);
22562+
1e00d052 22563+ if (!au_br_writable(br->br_perm)) {
1facf9fc 22564+ do_free = !!wbr;
22565+ skip = (!wbr
22566+ || (!wbr->wbr_whbase
22567+ && !wbr->wbr_plink
22568+ && !wbr->wbr_orph));
1e00d052 22569+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 22570+ /* skip = (!br->br_whbase && !br->br_orph); */
22571+ skip = (!wbr || !wbr->wbr_whbase);
22572+ if (skip && wbr) {
22573+ if (do_plink)
22574+ skip = !!wbr->wbr_plink;
22575+ else
22576+ skip = !wbr->wbr_plink;
22577+ }
1e00d052 22578+ } else {
1facf9fc 22579+ /* skip = (br->br_whbase && br->br_ohph); */
22580+ skip = (wbr && wbr->wbr_whbase);
22581+ if (skip) {
22582+ if (do_plink)
22583+ skip = !!wbr->wbr_plink;
22584+ else
22585+ skip = !wbr->wbr_plink;
22586+ }
1facf9fc 22587+ }
22588+ if (wbr)
22589+ wbr_wh_read_unlock(wbr);
22590+
22591+ if (skip)
22592+ continue;
22593+
22594+ hdir = au_hi(dir, bindex);
4a4d8108 22595+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 22596+ if (wbr)
22597+ wbr_wh_write_lock(wbr);
86dc4139 22598+ err = au_wh_init(br, sb);
1facf9fc 22599+ if (wbr)
22600+ wbr_wh_write_unlock(wbr);
4a4d8108 22601+ au_hn_imtx_unlock(hdir);
1facf9fc 22602+
22603+ if (!err && do_free) {
22604+ kfree(wbr);
22605+ br->br_wbr = NULL;
22606+ }
22607+ }
22608+
22609+ return err;
22610+}
22611+
22612+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
22613+{
22614+ int err;
22615+ unsigned int tmp;
027c5e7a 22616+ aufs_bindex_t bindex, bend;
1facf9fc 22617+ struct au_opt *opt;
22618+ struct au_opt_xino *opt_xino, xino;
22619+ struct au_sbinfo *sbinfo;
027c5e7a 22620+ struct au_branch *br;
1facf9fc 22621+
dece6358
AM
22622+ SiMustWriteLock(sb);
22623+
1facf9fc 22624+ err = 0;
22625+ opt_xino = NULL;
22626+ opt = opts->opt;
22627+ while (err >= 0 && opt->type != Opt_tail)
22628+ err = au_opt_simple(sb, opt++, opts);
22629+ if (err > 0)
22630+ err = 0;
22631+ else if (unlikely(err < 0))
22632+ goto out;
22633+
22634+ /* disable xino and udba temporary */
22635+ sbinfo = au_sbi(sb);
22636+ tmp = sbinfo->si_mntflags;
22637+ au_opt_clr(sbinfo->si_mntflags, XINO);
22638+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
22639+
22640+ opt = opts->opt;
22641+ while (err >= 0 && opt->type != Opt_tail)
22642+ err = au_opt_br(sb, opt++, opts);
22643+ if (err > 0)
22644+ err = 0;
22645+ else if (unlikely(err < 0))
22646+ goto out;
22647+
22648+ bend = au_sbend(sb);
22649+ if (unlikely(bend < 0)) {
22650+ err = -EINVAL;
4a4d8108 22651+ pr_err("no branches\n");
1facf9fc 22652+ goto out;
22653+ }
22654+
22655+ if (au_opt_test(tmp, XINO))
22656+ au_opt_set(sbinfo->si_mntflags, XINO);
22657+ opt = opts->opt;
22658+ while (!err && opt->type != Opt_tail)
22659+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
22660+ if (unlikely(err))
22661+ goto out;
22662+
22663+ err = au_opts_verify(sb, sb->s_flags, tmp);
22664+ if (unlikely(err))
22665+ goto out;
22666+
22667+ /* restore xino */
22668+ if (au_opt_test(tmp, XINO) && !opt_xino) {
22669+ xino.file = au_xino_def(sb);
22670+ err = PTR_ERR(xino.file);
22671+ if (IS_ERR(xino.file))
22672+ goto out;
22673+
22674+ err = au_xino_set(sb, &xino, /*remount*/0);
22675+ fput(xino.file);
22676+ if (unlikely(err))
22677+ goto out;
22678+ }
22679+
22680+ /* restore udba */
027c5e7a 22681+ tmp &= AuOptMask_UDBA;
1facf9fc 22682+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
22683+ sbinfo->si_mntflags |= tmp;
22684+ bend = au_sbend(sb);
22685+ for (bindex = 0; bindex <= bend; bindex++) {
22686+ br = au_sbr(sb, bindex);
22687+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
22688+ if (unlikely(err))
22689+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
22690+ bindex, err);
22691+ /* go on even if err */
22692+ }
4a4d8108 22693+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
1facf9fc 22694+ struct inode *dir = sb->s_root->d_inode;
4a4d8108 22695+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 22696+ }
22697+
4f0767ce 22698+out:
1facf9fc 22699+ return err;
22700+}
22701+
22702+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
22703+{
22704+ int err, rerr;
22705+ struct inode *dir;
22706+ struct au_opt_xino *opt_xino;
22707+ struct au_opt *opt;
22708+ struct au_sbinfo *sbinfo;
22709+
dece6358
AM
22710+ SiMustWriteLock(sb);
22711+
1facf9fc 22712+ dir = sb->s_root->d_inode;
22713+ sbinfo = au_sbi(sb);
22714+ err = 0;
22715+ opt_xino = NULL;
22716+ opt = opts->opt;
22717+ while (err >= 0 && opt->type != Opt_tail) {
22718+ err = au_opt_simple(sb, opt, opts);
22719+ if (!err)
22720+ err = au_opt_br(sb, opt, opts);
22721+ if (!err)
22722+ err = au_opt_xino(sb, opt, &opt_xino, opts);
22723+ opt++;
22724+ }
22725+ if (err > 0)
22726+ err = 0;
22727+ AuTraceErr(err);
22728+ /* go on even err */
22729+
22730+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
22731+ if (unlikely(rerr && !err))
22732+ err = rerr;
22733+
22734+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
22735+ rerr = au_xib_trunc(sb);
22736+ if (unlikely(rerr && !err))
22737+ err = rerr;
22738+ }
22739+
22740+ /* will be handled by the caller */
027c5e7a 22741+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 22742+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 22743+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 22744+
22745+ AuDbg("status 0x%x\n", opts->flags);
22746+ return err;
22747+}
22748+
22749+/* ---------------------------------------------------------------------- */
22750+
22751+unsigned int au_opt_udba(struct super_block *sb)
22752+{
22753+ return au_mntflags(sb) & AuOptMask_UDBA;
22754+}
7f207e10
AM
22755diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
22756--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 22757+++ linux/fs/aufs/opts.h 2014-04-24 22:11:10.855269116 +0200
523b37e3 22758@@ -0,0 +1,210 @@
1facf9fc 22759+/*
523b37e3 22760+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 22761+ *
22762+ * This program, aufs is free software; you can redistribute it and/or modify
22763+ * it under the terms of the GNU General Public License as published by
22764+ * the Free Software Foundation; either version 2 of the License, or
22765+ * (at your option) any later version.
dece6358
AM
22766+ *
22767+ * This program is distributed in the hope that it will be useful,
22768+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22769+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22770+ * GNU General Public License for more details.
22771+ *
22772+ * You should have received a copy of the GNU General Public License
523b37e3 22773+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22774+ */
22775+
22776+/*
22777+ * mount options/flags
22778+ */
22779+
22780+#ifndef __AUFS_OPTS_H__
22781+#define __AUFS_OPTS_H__
22782+
22783+#ifdef __KERNEL__
22784+
dece6358 22785+#include <linux/path.h>
1facf9fc 22786+
dece6358
AM
22787+struct file;
22788+struct super_block;
22789+
1facf9fc 22790+/* ---------------------------------------------------------------------- */
22791+
22792+/* mount flags */
22793+#define AuOpt_XINO 1 /* external inode number bitmap
22794+ and translation table */
22795+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
22796+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
22797+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 22798+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
22799+#define AuOpt_SHWH (1 << 5) /* show whiteout */
22800+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
22801+#define AuOpt_DIRPERM1 (1 << 7) /* unimplemented */
22802+#define AuOpt_REFROF (1 << 8) /* unimplemented */
22803+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
22804+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
22805+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
22806+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
22807+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 22808+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 22809+
4a4d8108
AM
22810+#ifndef CONFIG_AUFS_HNOTIFY
22811+#undef AuOpt_UDBA_HNOTIFY
22812+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 22813+#endif
dece6358
AM
22814+#ifndef CONFIG_AUFS_SHWH
22815+#undef AuOpt_SHWH
22816+#define AuOpt_SHWH 0
22817+#endif
1facf9fc 22818+
22819+#define AuOpt_Def (AuOpt_XINO \
22820+ | AuOpt_UDBA_REVAL \
22821+ | AuOpt_PLINK \
22822+ /* | AuOpt_DIRPERM1 */ \
22823+ | AuOpt_WARN_PERM)
22824+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
22825+ | AuOpt_UDBA_REVAL \
4a4d8108 22826+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 22827+
22828+#define au_opt_test(flags, name) (flags & AuOpt_##name)
22829+#define au_opt_set(flags, name) do { \
22830+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
22831+ ((flags) |= AuOpt_##name); \
22832+} while (0)
22833+#define au_opt_set_udba(flags, name) do { \
22834+ (flags) &= ~AuOptMask_UDBA; \
22835+ ((flags) |= AuOpt_##name); \
22836+} while (0)
7f207e10
AM
22837+#define au_opt_clr(flags, name) do { \
22838+ ((flags) &= ~AuOpt_##name); \
22839+} while (0)
1facf9fc 22840+
e49829fe
JR
22841+static inline unsigned int au_opts_plink(unsigned int mntflags)
22842+{
22843+#ifdef CONFIG_PROC_FS
22844+ return mntflags;
22845+#else
22846+ return mntflags & ~AuOpt_PLINK;
22847+#endif
22848+}
22849+
1facf9fc 22850+/* ---------------------------------------------------------------------- */
22851+
22852+/* policies to select one among multiple writable branches */
22853+enum {
22854+ AuWbrCreate_TDP, /* top down parent */
22855+ AuWbrCreate_RR, /* round robin */
22856+ AuWbrCreate_MFS, /* most free space */
22857+ AuWbrCreate_MFSV, /* mfs with seconds */
22858+ AuWbrCreate_MFSRR, /* mfs then rr */
22859+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
22860+ AuWbrCreate_PMFS, /* parent and mfs */
22861+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
22862+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
22863+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 22864+
22865+ AuWbrCreate_Def = AuWbrCreate_TDP
22866+};
22867+
22868+enum {
22869+ AuWbrCopyup_TDP, /* top down parent */
22870+ AuWbrCopyup_BUP, /* bottom up parent */
22871+ AuWbrCopyup_BU, /* bottom up */
22872+
22873+ AuWbrCopyup_Def = AuWbrCopyup_TDP
22874+};
22875+
22876+/* ---------------------------------------------------------------------- */
22877+
22878+struct au_opt_add {
22879+ aufs_bindex_t bindex;
22880+ char *pathname;
22881+ int perm;
22882+ struct path path;
22883+};
22884+
22885+struct au_opt_del {
22886+ char *pathname;
22887+ struct path h_path;
22888+};
22889+
22890+struct au_opt_mod {
22891+ char *path;
22892+ int perm;
22893+ struct dentry *h_root;
22894+};
22895+
22896+struct au_opt_xino {
22897+ char *path;
22898+ struct file *file;
22899+};
22900+
22901+struct au_opt_xino_itrunc {
22902+ aufs_bindex_t bindex;
22903+};
22904+
22905+struct au_opt_wbr_create {
22906+ int wbr_create;
22907+ int mfs_second;
22908+ unsigned long long mfsrr_watermark;
22909+};
22910+
22911+struct au_opt {
22912+ int type;
22913+ union {
22914+ struct au_opt_xino xino;
22915+ struct au_opt_xino_itrunc xino_itrunc;
22916+ struct au_opt_add add;
22917+ struct au_opt_del del;
22918+ struct au_opt_mod mod;
22919+ int dirwh;
22920+ int rdcache;
22921+ unsigned int rdblk;
22922+ unsigned int rdhash;
22923+ int udba;
22924+ struct au_opt_wbr_create wbr_create;
22925+ int wbr_copyup;
22926+ };
22927+};
22928+
22929+/* opts flags */
22930+#define AuOpts_REMOUNT 1
027c5e7a
AM
22931+#define AuOpts_REFRESH (1 << 1)
22932+#define AuOpts_TRUNC_XIB (1 << 2)
22933+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 22934+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
22935+#define au_fset_opts(flags, name) \
22936+ do { (flags) |= AuOpts_##name; } while (0)
22937+#define au_fclr_opts(flags, name) \
22938+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 22939+
22940+struct au_opts {
22941+ struct au_opt *opt;
22942+ int max_opt;
22943+
22944+ unsigned int given_udba;
22945+ unsigned int flags;
22946+ unsigned long sb_flags;
22947+};
22948+
22949+/* ---------------------------------------------------------------------- */
22950+
1e00d052 22951+char *au_optstr_br_perm(int brperm);
1facf9fc 22952+const char *au_optstr_udba(int udba);
22953+const char *au_optstr_wbr_copyup(int wbr_copyup);
22954+const char *au_optstr_wbr_create(int wbr_create);
22955+
22956+void au_opts_free(struct au_opts *opts);
22957+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
22958+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
22959+ unsigned int pending);
22960+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
22961+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
22962+
22963+unsigned int au_opt_udba(struct super_block *sb);
22964+
22965+/* ---------------------------------------------------------------------- */
22966+
22967+#endif /* __KERNEL__ */
22968+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
22969diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
22970--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 22971+++ linux/fs/aufs/plink.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 22972@@ -0,0 +1,532 @@
1facf9fc 22973+/*
523b37e3 22974+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 22975+ *
22976+ * This program, aufs is free software; you can redistribute it and/or modify
22977+ * it under the terms of the GNU General Public License as published by
22978+ * the Free Software Foundation; either version 2 of the License, or
22979+ * (at your option) any later version.
dece6358
AM
22980+ *
22981+ * This program is distributed in the hope that it will be useful,
22982+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22983+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22984+ * GNU General Public License for more details.
22985+ *
22986+ * You should have received a copy of the GNU General Public License
523b37e3 22987+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22988+ */
22989+
22990+/*
22991+ * pseudo-link
22992+ */
22993+
22994+#include "aufs.h"
22995+
22996+/*
e49829fe 22997+ * the pseudo-link maintenance mode.
1facf9fc 22998+ * during a user process maintains the pseudo-links,
22999+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
23000+ *
23001+ * Flags
23002+ * NOPLM:
23003+ * For entry functions which will handle plink, and i_mutex is already held
23004+ * in VFS.
23005+ * They cannot wait and should return an error at once.
23006+ * Callers has to check the error.
23007+ * NOPLMW:
23008+ * For entry functions which will handle plink, but i_mutex is not held
23009+ * in VFS.
23010+ * They can wait the plink maintenance mode to finish.
23011+ *
23012+ * They behave like F_SETLK and F_SETLKW.
23013+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 23014+ */
e49829fe
JR
23015+
23016+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 23017+{
e49829fe
JR
23018+ int err;
23019+ pid_t pid, ppid;
23020+ struct au_sbinfo *sbi;
dece6358
AM
23021+
23022+ SiMustAnyLock(sb);
23023+
e49829fe
JR
23024+ err = 0;
23025+ if (!au_opt_test(au_mntflags(sb), PLINK))
23026+ goto out;
23027+
23028+ sbi = au_sbi(sb);
23029+ pid = sbi->si_plink_maint_pid;
23030+ if (!pid || pid == current->pid)
23031+ goto out;
23032+
23033+ /* todo: it highly depends upon /sbin/mount.aufs */
23034+ rcu_read_lock();
23035+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
23036+ rcu_read_unlock();
23037+ if (pid == ppid)
23038+ goto out;
23039+
23040+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
23041+ /* if there is no i_mutex lock in VFS, we don't need to wait */
23042+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
23043+ while (sbi->si_plink_maint_pid) {
23044+ si_read_unlock(sb);
23045+ /* gave up wake_up_bit() */
23046+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
23047+
23048+ if (au_ftest_lock(flags, FLUSH))
23049+ au_nwt_flush(&sbi->si_nowait);
23050+ si_noflush_read_lock(sb);
23051+ }
23052+ } else if (au_ftest_lock(flags, NOPLM)) {
23053+ AuDbg("ppid %d, pid %d\n", ppid, pid);
23054+ err = -EAGAIN;
23055+ }
23056+
23057+out:
23058+ return err;
4a4d8108
AM
23059+}
23060+
e49829fe 23061+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 23062+{
4a4d8108 23063+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 23064+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 23065+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 23066+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
23067+}
23068+
e49829fe 23069+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
23070+{
23071+ int err;
4a4d8108
AM
23072+ struct au_sbinfo *sbinfo;
23073+
23074+ err = 0;
4a4d8108
AM
23075+ sbinfo = au_sbi(sb);
23076+ /* make sure i am the only one in this fs */
e49829fe
JR
23077+ si_write_lock(sb, AuLock_FLUSH);
23078+ if (au_opt_test(au_mntflags(sb), PLINK)) {
23079+ spin_lock(&sbinfo->si_plink_maint_lock);
23080+ if (!sbinfo->si_plink_maint_pid)
23081+ sbinfo->si_plink_maint_pid = current->pid;
23082+ else
23083+ err = -EBUSY;
23084+ spin_unlock(&sbinfo->si_plink_maint_lock);
23085+ }
4a4d8108
AM
23086+ si_write_unlock(sb);
23087+
23088+ return err;
1facf9fc 23089+}
23090+
23091+/* ---------------------------------------------------------------------- */
23092+
1facf9fc 23093+#ifdef CONFIG_AUFS_DEBUG
23094+void au_plink_list(struct super_block *sb)
23095+{
86dc4139 23096+ int i;
1facf9fc 23097+ struct au_sbinfo *sbinfo;
86dc4139 23098+ struct hlist_head *plink_hlist;
1facf9fc 23099+ struct pseudo_link *plink;
23100+
dece6358
AM
23101+ SiMustAnyLock(sb);
23102+
1facf9fc 23103+ sbinfo = au_sbi(sb);
23104+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23105+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23106+
86dc4139
AM
23107+ for (i = 0; i < AuPlink_NHASH; i++) {
23108+ plink_hlist = &sbinfo->si_plink[i].head;
23109+ rcu_read_lock();
23110+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
23111+ AuDbg("%lu\n", plink->inode->i_ino);
23112+ rcu_read_unlock();
23113+ }
1facf9fc 23114+}
23115+#endif
23116+
23117+/* is the inode pseudo-linked? */
23118+int au_plink_test(struct inode *inode)
23119+{
86dc4139 23120+ int found, i;
1facf9fc 23121+ struct au_sbinfo *sbinfo;
86dc4139 23122+ struct hlist_head *plink_hlist;
1facf9fc 23123+ struct pseudo_link *plink;
23124+
23125+ sbinfo = au_sbi(inode->i_sb);
dece6358 23126+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 23127+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 23128+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 23129+
23130+ found = 0;
86dc4139
AM
23131+ i = au_plink_hash(inode->i_ino);
23132+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 23133+ rcu_read_lock();
86dc4139 23134+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 23135+ if (plink->inode == inode) {
23136+ found = 1;
23137+ break;
23138+ }
4a4d8108 23139+ rcu_read_unlock();
1facf9fc 23140+ return found;
23141+}
23142+
23143+/* ---------------------------------------------------------------------- */
23144+
23145+/*
23146+ * generate a name for plink.
23147+ * the file will be stored under AUFS_WH_PLINKDIR.
23148+ */
23149+/* 20 is max digits length of ulong 64 */
23150+#define PLINK_NAME_LEN ((20 + 1) * 2)
23151+
23152+static int plink_name(char *name, int len, struct inode *inode,
23153+ aufs_bindex_t bindex)
23154+{
23155+ int rlen;
23156+ struct inode *h_inode;
23157+
23158+ h_inode = au_h_iptr(inode, bindex);
23159+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
23160+ return rlen;
23161+}
23162+
7f207e10
AM
23163+struct au_do_plink_lkup_args {
23164+ struct dentry **errp;
23165+ struct qstr *tgtname;
23166+ struct dentry *h_parent;
23167+ struct au_branch *br;
23168+};
23169+
23170+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
23171+ struct dentry *h_parent,
23172+ struct au_branch *br)
23173+{
23174+ struct dentry *h_dentry;
23175+ struct mutex *h_mtx;
23176+
23177+ h_mtx = &h_parent->d_inode->i_mutex;
23178+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 23179+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
23180+ mutex_unlock(h_mtx);
23181+ return h_dentry;
23182+}
23183+
23184+static void au_call_do_plink_lkup(void *args)
23185+{
23186+ struct au_do_plink_lkup_args *a = args;
23187+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
23188+}
23189+
1facf9fc 23190+/* lookup the plink-ed @inode under the branch at @bindex */
23191+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
23192+{
23193+ struct dentry *h_dentry, *h_parent;
23194+ struct au_branch *br;
23195+ struct inode *h_dir;
7f207e10 23196+ int wkq_err;
1facf9fc 23197+ char a[PLINK_NAME_LEN];
0c3ec466 23198+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 23199+
e49829fe
JR
23200+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
23201+
1facf9fc 23202+ br = au_sbr(inode->i_sb, bindex);
23203+ h_parent = br->br_wbr->wbr_plink;
23204+ h_dir = h_parent->d_inode;
23205+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
23206+
2dfbb274 23207+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
23208+ struct au_do_plink_lkup_args args = {
23209+ .errp = &h_dentry,
23210+ .tgtname = &tgtname,
23211+ .h_parent = h_parent,
23212+ .br = br
23213+ };
23214+
23215+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
23216+ if (unlikely(wkq_err))
23217+ h_dentry = ERR_PTR(wkq_err);
23218+ } else
23219+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
23220+
1facf9fc 23221+ return h_dentry;
23222+}
23223+
23224+/* create a pseudo-link */
23225+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
23226+ struct dentry *h_dentry, struct au_branch *br)
23227+{
23228+ int err;
23229+ struct path h_path = {
86dc4139 23230+ .mnt = au_br_mnt(br)
1facf9fc 23231+ };
523b37e3 23232+ struct inode *h_dir, *delegated;
1facf9fc 23233+
23234+ h_dir = h_parent->d_inode;
7f207e10 23235+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 23236+again:
b4510431 23237+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 23238+ err = PTR_ERR(h_path.dentry);
23239+ if (IS_ERR(h_path.dentry))
23240+ goto out;
23241+
23242+ err = 0;
23243+ /* wh.plink dir is not monitored */
7f207e10 23244+ /* todo: is it really safe? */
1facf9fc 23245+ if (h_path.dentry->d_inode
23246+ && h_path.dentry->d_inode != h_dentry->d_inode) {
523b37e3
AM
23247+ delegated = NULL;
23248+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
23249+ if (unlikely(err == -EWOULDBLOCK)) {
23250+ pr_warn("cannot retry for NFSv4 delegation"
23251+ " for an internal unlink\n");
23252+ iput(delegated);
23253+ }
1facf9fc 23254+ dput(h_path.dentry);
23255+ h_path.dentry = NULL;
23256+ if (!err)
23257+ goto again;
23258+ }
523b37e3
AM
23259+ if (!err && !h_path.dentry->d_inode) {
23260+ delegated = NULL;
23261+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
23262+ if (unlikely(err == -EWOULDBLOCK)) {
23263+ pr_warn("cannot retry for NFSv4 delegation"
23264+ " for an internal link\n");
23265+ iput(delegated);
23266+ }
23267+ }
1facf9fc 23268+ dput(h_path.dentry);
23269+
4f0767ce 23270+out:
7f207e10 23271+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 23272+ return err;
23273+}
23274+
23275+struct do_whplink_args {
23276+ int *errp;
23277+ struct qstr *tgt;
23278+ struct dentry *h_parent;
23279+ struct dentry *h_dentry;
23280+ struct au_branch *br;
23281+};
23282+
23283+static void call_do_whplink(void *args)
23284+{
23285+ struct do_whplink_args *a = args;
23286+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
23287+}
23288+
23289+static int whplink(struct dentry *h_dentry, struct inode *inode,
23290+ aufs_bindex_t bindex, struct au_branch *br)
23291+{
23292+ int err, wkq_err;
23293+ struct au_wbr *wbr;
23294+ struct dentry *h_parent;
23295+ struct inode *h_dir;
23296+ char a[PLINK_NAME_LEN];
0c3ec466 23297+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 23298+
23299+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
23300+ h_parent = wbr->wbr_plink;
23301+ h_dir = h_parent->d_inode;
23302+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
23303+
23304+ /* always superio. */
2dfbb274 23305+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 23306+ struct do_whplink_args args = {
23307+ .errp = &err,
23308+ .tgt = &tgtname,
23309+ .h_parent = h_parent,
23310+ .h_dentry = h_dentry,
23311+ .br = br
23312+ };
23313+ wkq_err = au_wkq_wait(call_do_whplink, &args);
23314+ if (unlikely(wkq_err))
23315+ err = wkq_err;
23316+ } else
23317+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 23318+
23319+ return err;
23320+}
23321+
23322+/* free a single plink */
23323+static void do_put_plink(struct pseudo_link *plink, int do_del)
23324+{
1facf9fc 23325+ if (do_del)
86dc4139 23326+ hlist_del(&plink->hlist);
4a4d8108
AM
23327+ iput(plink->inode);
23328+ kfree(plink);
23329+}
23330+
23331+static void do_put_plink_rcu(struct rcu_head *rcu)
23332+{
23333+ struct pseudo_link *plink;
23334+
23335+ plink = container_of(rcu, struct pseudo_link, rcu);
23336+ iput(plink->inode);
1facf9fc 23337+ kfree(plink);
23338+}
23339+
23340+/*
23341+ * create a new pseudo-link for @h_dentry on @bindex.
23342+ * the linked inode is held in aufs @inode.
23343+ */
23344+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
23345+ struct dentry *h_dentry)
23346+{
23347+ struct super_block *sb;
23348+ struct au_sbinfo *sbinfo;
86dc4139 23349+ struct hlist_head *plink_hlist;
4a4d8108 23350+ struct pseudo_link *plink, *tmp;
86dc4139
AM
23351+ struct au_sphlhead *sphl;
23352+ int found, err, cnt, i;
1facf9fc 23353+
23354+ sb = inode->i_sb;
23355+ sbinfo = au_sbi(sb);
23356+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23357+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23358+
86dc4139 23359+ found = au_plink_test(inode);
4a4d8108 23360+ if (found)
1facf9fc 23361+ return;
4a4d8108 23362+
86dc4139
AM
23363+ i = au_plink_hash(inode->i_ino);
23364+ sphl = sbinfo->si_plink + i;
23365+ plink_hlist = &sphl->head;
4a4d8108
AM
23366+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
23367+ if (tmp)
23368+ tmp->inode = au_igrab(inode);
23369+ else {
23370+ err = -ENOMEM;
23371+ goto out;
1facf9fc 23372+ }
23373+
86dc4139
AM
23374+ spin_lock(&sphl->spin);
23375+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
23376+ if (plink->inode == inode) {
23377+ found = 1;
23378+ break;
23379+ }
1facf9fc 23380+ }
4a4d8108 23381+ if (!found)
86dc4139
AM
23382+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
23383+ spin_unlock(&sphl->spin);
4a4d8108 23384+ if (!found) {
86dc4139
AM
23385+ cnt = au_sphl_count(sphl);
23386+#define msg "unexpectedly unblanced or too many pseudo-links"
23387+ if (cnt > AUFS_PLINK_WARN)
23388+ AuWarn1(msg ", %d\n", cnt);
23389+#undef msg
1facf9fc 23390+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
23391+ } else {
23392+ do_put_plink(tmp, 0);
23393+ return;
1facf9fc 23394+ }
23395+
4a4d8108 23396+out:
1facf9fc 23397+ if (unlikely(err)) {
0c3ec466 23398+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 23399+ if (tmp) {
86dc4139 23400+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
23401+ call_rcu(&tmp->rcu, do_put_plink_rcu);
23402+ }
1facf9fc 23403+ }
23404+}
23405+
23406+/* free all plinks */
e49829fe 23407+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 23408+{
86dc4139 23409+ int i, warned;
1facf9fc 23410+ struct au_sbinfo *sbinfo;
86dc4139
AM
23411+ struct hlist_head *plink_hlist;
23412+ struct hlist_node *tmp;
23413+ struct pseudo_link *plink;
1facf9fc 23414+
dece6358
AM
23415+ SiMustWriteLock(sb);
23416+
1facf9fc 23417+ sbinfo = au_sbi(sb);
23418+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23419+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23420+
1facf9fc 23421+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
23422+ warned = 0;
23423+ for (i = 0; i < AuPlink_NHASH; i++) {
23424+ plink_hlist = &sbinfo->si_plink[i].head;
23425+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
23426+ pr_warn("pseudo-link is not flushed");
23427+ warned = 1;
23428+ }
23429+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
23430+ do_put_plink(plink, 0);
23431+ INIT_HLIST_HEAD(plink_hlist);
23432+ }
1facf9fc 23433+}
23434+
e49829fe
JR
23435+void au_plink_clean(struct super_block *sb, int verbose)
23436+{
23437+ struct dentry *root;
23438+
23439+ root = sb->s_root;
23440+ aufs_write_lock(root);
23441+ if (au_opt_test(au_mntflags(sb), PLINK))
23442+ au_plink_put(sb, verbose);
23443+ aufs_write_unlock(root);
23444+}
23445+
86dc4139
AM
23446+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
23447+{
23448+ int do_put;
23449+ aufs_bindex_t bstart, bend, bindex;
23450+
23451+ do_put = 0;
23452+ bstart = au_ibstart(inode);
23453+ bend = au_ibend(inode);
23454+ if (bstart >= 0) {
23455+ for (bindex = bstart; bindex <= bend; bindex++) {
23456+ if (!au_h_iptr(inode, bindex)
23457+ || au_ii_br_id(inode, bindex) != br_id)
23458+ continue;
23459+ au_set_h_iptr(inode, bindex, NULL, 0);
23460+ do_put = 1;
23461+ break;
23462+ }
23463+ if (do_put)
23464+ for (bindex = bstart; bindex <= bend; bindex++)
23465+ if (au_h_iptr(inode, bindex)) {
23466+ do_put = 0;
23467+ break;
23468+ }
23469+ } else
23470+ do_put = 1;
23471+
23472+ return do_put;
23473+}
23474+
1facf9fc 23475+/* free the plinks on a branch specified by @br_id */
23476+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
23477+{
23478+ struct au_sbinfo *sbinfo;
86dc4139
AM
23479+ struct hlist_head *plink_hlist;
23480+ struct hlist_node *tmp;
23481+ struct pseudo_link *plink;
1facf9fc 23482+ struct inode *inode;
86dc4139 23483+ int i, do_put;
1facf9fc 23484+
dece6358
AM
23485+ SiMustWriteLock(sb);
23486+
1facf9fc 23487+ sbinfo = au_sbi(sb);
23488+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 23489+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 23490+
1facf9fc 23491+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
23492+ for (i = 0; i < AuPlink_NHASH; i++) {
23493+ plink_hlist = &sbinfo->si_plink[i].head;
23494+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
23495+ inode = au_igrab(plink->inode);
23496+ ii_write_lock_child(inode);
23497+ do_put = au_plink_do_half_refresh(inode, br_id);
dece6358
AM
23498+ if (do_put)
23499+ do_put_plink(plink, 1);
86dc4139
AM
23500+ ii_write_unlock(inode);
23501+ iput(inode);
dece6358 23502+ }
dece6358
AM
23503+ }
23504+}
7f207e10
AM
23505diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
23506--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 23507+++ linux/fs/aufs/poll.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 23508@@ -0,0 +1,55 @@
dece6358 23509+/*
523b37e3 23510+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
23511+ *
23512+ * This program, aufs is free software; you can redistribute it and/or modify
23513+ * it under the terms of the GNU General Public License as published by
23514+ * the Free Software Foundation; either version 2 of the License, or
23515+ * (at your option) any later version.
23516+ *
23517+ * This program is distributed in the hope that it will be useful,
23518+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23519+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23520+ * GNU General Public License for more details.
23521+ *
23522+ * You should have received a copy of the GNU General Public License
523b37e3 23523+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
23524+ */
23525+
1308ab2a 23526+/*
23527+ * poll operation
23528+ * There is only one filesystem which implements ->poll operation, currently.
23529+ */
23530+
23531+#include "aufs.h"
23532+
23533+unsigned int aufs_poll(struct file *file, poll_table *wait)
23534+{
23535+ unsigned int mask;
23536+ int err;
23537+ struct file *h_file;
23538+ struct dentry *dentry;
23539+ struct super_block *sb;
23540+
23541+ /* We should pretend an error happened. */
23542+ mask = POLLERR /* | POLLIN | POLLOUT */;
23543+ dentry = file->f_dentry;
23544+ sb = dentry->d_sb;
e49829fe 23545+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 23546+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
23547+ if (unlikely(err))
23548+ goto out;
23549+
23550+ /* it is not an error if h_file has no operation */
23551+ mask = DEFAULT_POLLMASK;
4a4d8108 23552+ h_file = au_hf_top(file);
523b37e3 23553+ if (h_file->f_op->poll)
1308ab2a 23554+ mask = h_file->f_op->poll(h_file, wait);
23555+
23556+ di_read_unlock(dentry, AuLock_IR);
23557+ fi_read_unlock(file);
23558+
4f0767ce 23559+out:
1308ab2a 23560+ si_read_unlock(sb);
23561+ AuTraceErr((int)mask);
23562+ return mask;
23563+}
7f207e10
AM
23564diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
23565--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 23566+++ linux/fs/aufs/procfs.c 2014-04-24 22:11:10.855269116 +0200
523b37e3 23567@@ -0,0 +1,169 @@
e49829fe 23568+/*
523b37e3 23569+ * Copyright (C) 2010-2014 Junjiro R. Okajima
e49829fe
JR
23570+ *
23571+ * This program, aufs is free software; you can redistribute it and/or modify
23572+ * it under the terms of the GNU General Public License as published by
23573+ * the Free Software Foundation; either version 2 of the License, or
23574+ * (at your option) any later version.
23575+ *
23576+ * This program is distributed in the hope that it will be useful,
23577+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23578+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23579+ * GNU General Public License for more details.
23580+ *
23581+ * You should have received a copy of the GNU General Public License
523b37e3 23582+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
23583+ */
23584+
23585+/*
23586+ * procfs interfaces
23587+ */
23588+
23589+#include <linux/proc_fs.h>
23590+#include "aufs.h"
23591+
23592+static int au_procfs_plm_release(struct inode *inode, struct file *file)
23593+{
23594+ struct au_sbinfo *sbinfo;
23595+
23596+ sbinfo = file->private_data;
23597+ if (sbinfo) {
23598+ au_plink_maint_leave(sbinfo);
23599+ kobject_put(&sbinfo->si_kobj);
23600+ }
23601+
23602+ return 0;
23603+}
23604+
23605+static void au_procfs_plm_write_clean(struct file *file)
23606+{
23607+ struct au_sbinfo *sbinfo;
23608+
23609+ sbinfo = file->private_data;
23610+ if (sbinfo)
23611+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
23612+}
23613+
23614+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
23615+{
23616+ int err;
23617+ struct super_block *sb;
23618+ struct au_sbinfo *sbinfo;
23619+
23620+ err = -EBUSY;
23621+ if (unlikely(file->private_data))
23622+ goto out;
23623+
23624+ sb = NULL;
53392da6 23625+ /* don't use au_sbilist_lock() here */
e49829fe
JR
23626+ spin_lock(&au_sbilist.spin);
23627+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
23628+ if (id == sysaufs_si_id(sbinfo)) {
23629+ kobject_get(&sbinfo->si_kobj);
23630+ sb = sbinfo->si_sb;
23631+ break;
23632+ }
23633+ spin_unlock(&au_sbilist.spin);
23634+
23635+ err = -EINVAL;
23636+ if (unlikely(!sb))
23637+ goto out;
23638+
23639+ err = au_plink_maint_enter(sb);
23640+ if (!err)
23641+ /* keep kobject_get() */
23642+ file->private_data = sbinfo;
23643+ else
23644+ kobject_put(&sbinfo->si_kobj);
23645+out:
23646+ return err;
23647+}
23648+
23649+/*
23650+ * Accept a valid "si=xxxx" only.
23651+ * Once it is accepted successfully, accept "clean" too.
23652+ */
23653+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
23654+ size_t count, loff_t *ppos)
23655+{
23656+ ssize_t err;
23657+ unsigned long id;
23658+ /* last newline is allowed */
23659+ char buf[3 + sizeof(unsigned long) * 2 + 1];
23660+
23661+ err = -EACCES;
23662+ if (unlikely(!capable(CAP_SYS_ADMIN)))
23663+ goto out;
23664+
23665+ err = -EINVAL;
23666+ if (unlikely(count > sizeof(buf)))
23667+ goto out;
23668+
23669+ err = copy_from_user(buf, ubuf, count);
23670+ if (unlikely(err)) {
23671+ err = -EFAULT;
23672+ goto out;
23673+ }
23674+ buf[count] = 0;
23675+
23676+ err = -EINVAL;
23677+ if (!strcmp("clean", buf)) {
23678+ au_procfs_plm_write_clean(file);
23679+ goto out_success;
23680+ } else if (unlikely(strncmp("si=", buf, 3)))
23681+ goto out;
23682+
9dbd164d 23683+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
23684+ if (unlikely(err))
23685+ goto out;
23686+
23687+ err = au_procfs_plm_write_si(file, id);
23688+ if (unlikely(err))
23689+ goto out;
23690+
23691+out_success:
23692+ err = count; /* success */
23693+out:
23694+ return err;
23695+}
23696+
23697+static const struct file_operations au_procfs_plm_fop = {
23698+ .write = au_procfs_plm_write,
23699+ .release = au_procfs_plm_release,
23700+ .owner = THIS_MODULE
23701+};
23702+
23703+/* ---------------------------------------------------------------------- */
23704+
23705+static struct proc_dir_entry *au_procfs_dir;
23706+
23707+void au_procfs_fin(void)
23708+{
23709+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
23710+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
23711+}
23712+
23713+int __init au_procfs_init(void)
23714+{
23715+ int err;
23716+ struct proc_dir_entry *entry;
23717+
23718+ err = -ENOMEM;
23719+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
23720+ if (unlikely(!au_procfs_dir))
23721+ goto out;
23722+
23723+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
23724+ au_procfs_dir, &au_procfs_plm_fop);
23725+ if (unlikely(!entry))
23726+ goto out_dir;
23727+
23728+ err = 0;
23729+ goto out; /* success */
23730+
23731+
23732+out_dir:
23733+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
23734+out:
23735+ return err;
23736+}
7f207e10
AM
23737diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
23738--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 23739+++ linux/fs/aufs/rdu.c 2014-04-24 22:11:10.858602483 +0200
523b37e3 23740@@ -0,0 +1,388 @@
1308ab2a 23741+/*
523b37e3 23742+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1308ab2a 23743+ *
23744+ * This program, aufs is free software; you can redistribute it and/or modify
23745+ * it under the terms of the GNU General Public License as published by
23746+ * the Free Software Foundation; either version 2 of the License, or
23747+ * (at your option) any later version.
23748+ *
23749+ * This program is distributed in the hope that it will be useful,
23750+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23751+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23752+ * GNU General Public License for more details.
23753+ *
23754+ * You should have received a copy of the GNU General Public License
523b37e3 23755+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 23756+ */
23757+
23758+/*
23759+ * readdir in userspace.
23760+ */
23761+
b752ccd1 23762+#include <linux/compat.h>
4a4d8108 23763+#include <linux/fs_stack.h>
1308ab2a 23764+#include <linux/security.h>
1308ab2a 23765+#include "aufs.h"
23766+
23767+/* bits for struct aufs_rdu.flags */
23768+#define AuRdu_CALLED 1
23769+#define AuRdu_CONT (1 << 1)
23770+#define AuRdu_FULL (1 << 2)
23771+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
23772+#define au_fset_rdu(flags, name) \
23773+ do { (flags) |= AuRdu_##name; } while (0)
23774+#define au_fclr_rdu(flags, name) \
23775+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 23776+
23777+struct au_rdu_arg {
392086de 23778+ struct dir_context ctx;
1308ab2a 23779+ struct aufs_rdu *rdu;
23780+ union au_rdu_ent_ul ent;
23781+ unsigned long end;
23782+
23783+ struct super_block *sb;
23784+ int err;
23785+};
23786+
392086de 23787+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 23788+ loff_t offset, u64 h_ino, unsigned int d_type)
23789+{
23790+ int err, len;
392086de 23791+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 23792+ struct aufs_rdu *rdu = arg->rdu;
23793+ struct au_rdu_ent ent;
23794+
23795+ err = 0;
23796+ arg->err = 0;
23797+ au_fset_rdu(rdu->cookie.flags, CALLED);
23798+ len = au_rdu_len(nlen);
23799+ if (arg->ent.ul + len < arg->end) {
23800+ ent.ino = h_ino;
23801+ ent.bindex = rdu->cookie.bindex;
23802+ ent.type = d_type;
23803+ ent.nlen = nlen;
4a4d8108
AM
23804+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
23805+ ent.type = DT_UNKNOWN;
1308ab2a 23806+
9dbd164d 23807+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 23808+ err = -EFAULT;
23809+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
23810+ goto out;
23811+ if (copy_to_user(arg->ent.e->name, name, nlen))
23812+ goto out;
23813+ /* the terminating NULL */
23814+ if (__put_user(0, arg->ent.e->name + nlen))
23815+ goto out;
23816+ err = 0;
23817+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
23818+ arg->ent.ul += len;
23819+ rdu->rent++;
23820+ } else {
23821+ err = -EFAULT;
23822+ au_fset_rdu(rdu->cookie.flags, FULL);
23823+ rdu->full = 1;
23824+ rdu->tail = arg->ent;
23825+ }
23826+
4f0767ce 23827+out:
1308ab2a 23828+ /* AuTraceErr(err); */
23829+ return err;
23830+}
23831+
23832+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
23833+{
23834+ int err;
23835+ loff_t offset;
23836+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
23837+
92d182d2 23838+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 23839+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
23840+ err = offset;
23841+ if (unlikely(offset != cookie->h_pos))
23842+ goto out;
23843+
23844+ err = 0;
23845+ do {
23846+ arg->err = 0;
23847+ au_fclr_rdu(cookie->flags, CALLED);
23848+ /* smp_mb(); */
392086de 23849+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 23850+ if (err >= 0)
23851+ err = arg->err;
23852+ } while (!err
23853+ && au_ftest_rdu(cookie->flags, CALLED)
23854+ && !au_ftest_rdu(cookie->flags, FULL));
23855+ cookie->h_pos = h_file->f_pos;
23856+
4f0767ce 23857+out:
1308ab2a 23858+ AuTraceErr(err);
23859+ return err;
23860+}
23861+
23862+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
23863+{
23864+ int err;
23865+ aufs_bindex_t bend;
392086de
AM
23866+ struct au_rdu_arg arg = {
23867+ .ctx = {
23868+ .actor = au_diractor(au_rdu_fill)
23869+ }
23870+ };
1308ab2a 23871+ struct dentry *dentry;
23872+ struct inode *inode;
23873+ struct file *h_file;
23874+ struct au_rdu_cookie *cookie = &rdu->cookie;
23875+
23876+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
23877+ if (unlikely(err)) {
23878+ err = -EFAULT;
23879+ AuTraceErr(err);
23880+ goto out;
23881+ }
23882+ rdu->rent = 0;
23883+ rdu->tail = rdu->ent;
23884+ rdu->full = 0;
23885+ arg.rdu = rdu;
23886+ arg.ent = rdu->ent;
23887+ arg.end = arg.ent.ul;
23888+ arg.end += rdu->sz;
23889+
23890+ err = -ENOTDIR;
523b37e3 23891+ if (unlikely(!file->f_op->iterate))
1308ab2a 23892+ goto out;
23893+
23894+ err = security_file_permission(file, MAY_READ);
23895+ AuTraceErr(err);
23896+ if (unlikely(err))
23897+ goto out;
23898+
23899+ dentry = file->f_dentry;
23900+ inode = dentry->d_inode;
23901+#if 1
23902+ mutex_lock(&inode->i_mutex);
23903+#else
23904+ err = mutex_lock_killable(&inode->i_mutex);
23905+ AuTraceErr(err);
23906+ if (unlikely(err))
23907+ goto out;
23908+#endif
1308ab2a 23909+
23910+ arg.sb = inode->i_sb;
e49829fe
JR
23911+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
23912+ if (unlikely(err))
23913+ goto out_mtx;
027c5e7a
AM
23914+ err = au_alive_dir(dentry);
23915+ if (unlikely(err))
23916+ goto out_si;
e49829fe 23917+ /* todo: reval? */
1308ab2a 23918+ fi_read_lock(file);
23919+
23920+ err = -EAGAIN;
23921+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
23922+ && cookie->generation != au_figen(file)))
23923+ goto out_unlock;
23924+
23925+ err = 0;
23926+ if (!rdu->blk) {
23927+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
23928+ if (!rdu->blk)
23929+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
23930+ }
23931+ bend = au_fbstart(file);
23932+ if (cookie->bindex < bend)
23933+ cookie->bindex = bend;
4a4d8108 23934+ bend = au_fbend_dir(file);
1308ab2a 23935+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
23936+ for (; !err && cookie->bindex <= bend;
23937+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 23938+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 23939+ if (!h_file)
23940+ continue;
23941+
23942+ au_fclr_rdu(cookie->flags, FULL);
23943+ err = au_rdu_do(h_file, &arg);
23944+ AuTraceErr(err);
23945+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
23946+ break;
23947+ }
23948+ AuDbg("rent %llu\n", rdu->rent);
23949+
23950+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
23951+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
23952+ au_fset_rdu(cookie->flags, CONT);
23953+ cookie->generation = au_figen(file);
23954+ }
23955+
23956+ ii_read_lock_child(inode);
23957+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
23958+ ii_read_unlock(inode);
23959+
4f0767ce 23960+out_unlock:
1308ab2a 23961+ fi_read_unlock(file);
027c5e7a 23962+out_si:
1308ab2a 23963+ si_read_unlock(arg.sb);
4f0767ce 23964+out_mtx:
1308ab2a 23965+ mutex_unlock(&inode->i_mutex);
4f0767ce 23966+out:
1308ab2a 23967+ AuTraceErr(err);
23968+ return err;
23969+}
23970+
23971+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
23972+{
23973+ int err;
23974+ ino_t ino;
23975+ unsigned long long nent;
23976+ union au_rdu_ent_ul *u;
23977+ struct au_rdu_ent ent;
23978+ struct super_block *sb;
23979+
23980+ err = 0;
23981+ nent = rdu->nent;
23982+ u = &rdu->ent;
23983+ sb = file->f_dentry->d_sb;
23984+ si_read_lock(sb, AuLock_FLUSH);
23985+ while (nent-- > 0) {
9dbd164d 23986+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 23987+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
23988+ if (!err)
23989+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 23990+ if (unlikely(err)) {
23991+ err = -EFAULT;
23992+ AuTraceErr(err);
23993+ break;
23994+ }
23995+
23996+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
23997+ if (!ent.wh)
23998+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
23999+ else
24000+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
24001+ &ino);
24002+ if (unlikely(err)) {
24003+ AuTraceErr(err);
24004+ break;
24005+ }
24006+
24007+ err = __put_user(ino, &u->e->ino);
24008+ if (unlikely(err)) {
24009+ err = -EFAULT;
24010+ AuTraceErr(err);
24011+ break;
24012+ }
24013+ u->ul += au_rdu_len(ent.nlen);
24014+ }
24015+ si_read_unlock(sb);
24016+
24017+ return err;
24018+}
24019+
24020+/* ---------------------------------------------------------------------- */
24021+
24022+static int au_rdu_verify(struct aufs_rdu *rdu)
24023+{
b752ccd1 24024+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 24025+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 24026+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 24027+ rdu->blk,
24028+ rdu->rent, rdu->shwh, rdu->full,
24029+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
24030+ rdu->cookie.generation);
dece6358 24031+
b752ccd1 24032+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 24033+ return 0;
dece6358 24034+
b752ccd1
AM
24035+ AuDbg("%u:%u\n",
24036+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 24037+ return -EINVAL;
24038+}
24039+
24040+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 24041+{
1308ab2a 24042+ long err, e;
24043+ struct aufs_rdu rdu;
24044+ void __user *p = (void __user *)arg;
dece6358 24045+
1308ab2a 24046+ err = copy_from_user(&rdu, p, sizeof(rdu));
24047+ if (unlikely(err)) {
24048+ err = -EFAULT;
24049+ AuTraceErr(err);
24050+ goto out;
24051+ }
24052+ err = au_rdu_verify(&rdu);
dece6358
AM
24053+ if (unlikely(err))
24054+ goto out;
24055+
1308ab2a 24056+ switch (cmd) {
24057+ case AUFS_CTL_RDU:
24058+ err = au_rdu(file, &rdu);
24059+ if (unlikely(err))
24060+ break;
dece6358 24061+
1308ab2a 24062+ e = copy_to_user(p, &rdu, sizeof(rdu));
24063+ if (unlikely(e)) {
24064+ err = -EFAULT;
24065+ AuTraceErr(err);
24066+ }
24067+ break;
24068+ case AUFS_CTL_RDU_INO:
24069+ err = au_rdu_ino(file, &rdu);
24070+ break;
24071+
24072+ default:
4a4d8108 24073+ /* err = -ENOTTY; */
1308ab2a 24074+ err = -EINVAL;
24075+ }
dece6358 24076+
4f0767ce 24077+out:
1308ab2a 24078+ AuTraceErr(err);
24079+ return err;
1facf9fc 24080+}
b752ccd1
AM
24081+
24082+#ifdef CONFIG_COMPAT
24083+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
24084+{
24085+ long err, e;
24086+ struct aufs_rdu rdu;
24087+ void __user *p = compat_ptr(arg);
24088+
24089+ /* todo: get_user()? */
24090+ err = copy_from_user(&rdu, p, sizeof(rdu));
24091+ if (unlikely(err)) {
24092+ err = -EFAULT;
24093+ AuTraceErr(err);
24094+ goto out;
24095+ }
24096+ rdu.ent.e = compat_ptr(rdu.ent.ul);
24097+ err = au_rdu_verify(&rdu);
24098+ if (unlikely(err))
24099+ goto out;
24100+
24101+ switch (cmd) {
24102+ case AUFS_CTL_RDU:
24103+ err = au_rdu(file, &rdu);
24104+ if (unlikely(err))
24105+ break;
24106+
24107+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
24108+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
24109+ e = copy_to_user(p, &rdu, sizeof(rdu));
24110+ if (unlikely(e)) {
24111+ err = -EFAULT;
24112+ AuTraceErr(err);
24113+ }
24114+ break;
24115+ case AUFS_CTL_RDU_INO:
24116+ err = au_rdu_ino(file, &rdu);
24117+ break;
24118+
24119+ default:
24120+ /* err = -ENOTTY; */
24121+ err = -EINVAL;
24122+ }
24123+
4f0767ce 24124+out:
b752ccd1
AM
24125+ AuTraceErr(err);
24126+ return err;
24127+}
24128+#endif
7f207e10
AM
24129diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
24130--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 24131+++ linux/fs/aufs/rwsem.h 2014-04-24 22:11:10.858602483 +0200
523b37e3 24132@@ -0,0 +1,187 @@
1facf9fc 24133+/*
523b37e3 24134+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 24135+ *
24136+ * This program, aufs is free software; you can redistribute it and/or modify
24137+ * it under the terms of the GNU General Public License as published by
24138+ * the Free Software Foundation; either version 2 of the License, or
24139+ * (at your option) any later version.
dece6358
AM
24140+ *
24141+ * This program is distributed in the hope that it will be useful,
24142+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24143+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24144+ * GNU General Public License for more details.
24145+ *
24146+ * You should have received a copy of the GNU General Public License
523b37e3 24147+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24148+ */
24149+
24150+/*
24151+ * simple read-write semaphore wrappers
24152+ */
24153+
24154+#ifndef __AUFS_RWSEM_H__
24155+#define __AUFS_RWSEM_H__
24156+
24157+#ifdef __KERNEL__
24158+
4a4d8108 24159+#include "debug.h"
dece6358
AM
24160+
24161+struct au_rwsem {
24162+ struct rw_semaphore rwsem;
24163+#ifdef CONFIG_AUFS_DEBUG
24164+ /* just for debugging, not almighty counter */
24165+ atomic_t rcnt, wcnt;
24166+#endif
24167+};
24168+
24169+#ifdef CONFIG_AUFS_DEBUG
24170+#define AuDbgCntInit(rw) do { \
24171+ atomic_set(&(rw)->rcnt, 0); \
24172+ atomic_set(&(rw)->wcnt, 0); \
24173+ smp_mb(); /* atomic set */ \
24174+} while (0)
24175+
e49829fe 24176+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 24177+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 24178+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
24179+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
24180+#else
24181+#define AuDbgCntInit(rw) do {} while (0)
24182+#define AuDbgRcntInc(rw) do {} while (0)
24183+#define AuDbgRcntDec(rw) do {} while (0)
24184+#define AuDbgWcntInc(rw) do {} while (0)
24185+#define AuDbgWcntDec(rw) do {} while (0)
24186+#endif /* CONFIG_AUFS_DEBUG */
24187+
24188+/* to debug easier, do not make them inlined functions */
24189+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
24190+/* rwsem_is_locked() is unusable */
24191+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
24192+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
24193+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
24194+ && atomic_read(&(rw)->wcnt) <= 0)
24195+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
24196+ || atomic_read(&(rw)->wcnt))
24197+
e49829fe
JR
24198+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
24199+
dece6358
AM
24200+static inline void au_rw_init(struct au_rwsem *rw)
24201+{
24202+ AuDbgCntInit(rw);
24203+ init_rwsem(&rw->rwsem);
24204+}
24205+
24206+static inline void au_rw_init_wlock(struct au_rwsem *rw)
24207+{
24208+ au_rw_init(rw);
24209+ down_write(&rw->rwsem);
24210+ AuDbgWcntInc(rw);
24211+}
24212+
24213+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
24214+ unsigned int lsc)
24215+{
24216+ au_rw_init(rw);
24217+ down_write_nested(&rw->rwsem, lsc);
24218+ AuDbgWcntInc(rw);
24219+}
24220+
24221+static inline void au_rw_read_lock(struct au_rwsem *rw)
24222+{
24223+ down_read(&rw->rwsem);
24224+ AuDbgRcntInc(rw);
24225+}
24226+
24227+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
24228+{
24229+ down_read_nested(&rw->rwsem, lsc);
24230+ AuDbgRcntInc(rw);
24231+}
24232+
24233+static inline void au_rw_read_unlock(struct au_rwsem *rw)
24234+{
24235+ AuRwMustReadLock(rw);
24236+ AuDbgRcntDec(rw);
24237+ up_read(&rw->rwsem);
24238+}
24239+
24240+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
24241+{
24242+ AuRwMustWriteLock(rw);
24243+ AuDbgRcntInc(rw);
24244+ AuDbgWcntDec(rw);
24245+ downgrade_write(&rw->rwsem);
24246+}
24247+
24248+static inline void au_rw_write_lock(struct au_rwsem *rw)
24249+{
24250+ down_write(&rw->rwsem);
24251+ AuDbgWcntInc(rw);
24252+}
24253+
24254+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
24255+ unsigned int lsc)
24256+{
24257+ down_write_nested(&rw->rwsem, lsc);
24258+ AuDbgWcntInc(rw);
24259+}
1facf9fc 24260+
dece6358
AM
24261+static inline void au_rw_write_unlock(struct au_rwsem *rw)
24262+{
24263+ AuRwMustWriteLock(rw);
24264+ AuDbgWcntDec(rw);
24265+ up_write(&rw->rwsem);
24266+}
24267+
24268+/* why is not _nested version defined */
24269+static inline int au_rw_read_trylock(struct au_rwsem *rw)
24270+{
24271+ int ret = down_read_trylock(&rw->rwsem);
24272+ if (ret)
24273+ AuDbgRcntInc(rw);
24274+ return ret;
24275+}
24276+
24277+static inline int au_rw_write_trylock(struct au_rwsem *rw)
24278+{
24279+ int ret = down_write_trylock(&rw->rwsem);
24280+ if (ret)
24281+ AuDbgWcntInc(rw);
24282+ return ret;
24283+}
24284+
24285+#undef AuDbgCntInit
24286+#undef AuDbgRcntInc
24287+#undef AuDbgRcntDec
24288+#undef AuDbgWcntInc
24289+#undef AuDbgWcntDec
1facf9fc 24290+
24291+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
24292+static inline void prefix##_read_lock(param) \
dece6358 24293+{ au_rw_read_lock(rwsem); } \
1facf9fc 24294+static inline void prefix##_write_lock(param) \
dece6358 24295+{ au_rw_write_lock(rwsem); } \
1facf9fc 24296+static inline int prefix##_read_trylock(param) \
dece6358 24297+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 24298+static inline int prefix##_write_trylock(param) \
dece6358 24299+{ return au_rw_write_trylock(rwsem); }
1facf9fc 24300+/* why is not _nested version defined */
24301+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 24302+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 24303+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 24304+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 24305+
24306+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
24307+static inline void prefix##_read_unlock(param) \
dece6358 24308+{ au_rw_read_unlock(rwsem); } \
1facf9fc 24309+static inline void prefix##_write_unlock(param) \
dece6358 24310+{ au_rw_write_unlock(rwsem); } \
1facf9fc 24311+static inline void prefix##_downgrade_lock(param) \
dece6358 24312+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 24313+
24314+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
24315+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
24316+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
24317+
24318+#endif /* __KERNEL__ */
24319+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
24320diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
24321--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 24322+++ linux/fs/aufs/sbinfo.c 2014-04-24 22:11:10.858602483 +0200
523b37e3 24323@@ -0,0 +1,351 @@
1facf9fc 24324+/*
523b37e3 24325+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 24326+ *
24327+ * This program, aufs is free software; you can redistribute it and/or modify
24328+ * it under the terms of the GNU General Public License as published by
24329+ * the Free Software Foundation; either version 2 of the License, or
24330+ * (at your option) any later version.
dece6358
AM
24331+ *
24332+ * This program is distributed in the hope that it will be useful,
24333+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24334+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24335+ * GNU General Public License for more details.
24336+ *
24337+ * You should have received a copy of the GNU General Public License
523b37e3 24338+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24339+ */
24340+
24341+/*
24342+ * superblock private data
24343+ */
24344+
24345+#include "aufs.h"
24346+
24347+/*
24348+ * they are necessary regardless sysfs is disabled.
24349+ */
24350+void au_si_free(struct kobject *kobj)
24351+{
86dc4139 24352+ int i;
1facf9fc 24353+ struct au_sbinfo *sbinfo;
b752ccd1 24354+ char *locked __maybe_unused; /* debug only */
1facf9fc 24355+
24356+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
24357+ for (i = 0; i < AuPlink_NHASH; i++)
24358+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 24359+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 24360+
e49829fe 24361+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 24362+ au_br_free(sbinfo);
e49829fe 24363+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
24364+
24365+ AuDebugOn(radix_tree_gang_lookup
24366+ (&sbinfo->au_si_pid.tree, (void **)&locked,
24367+ /*first_index*/PID_MAX_DEFAULT - 1,
24368+ /*max_items*/sizeof(locked)/sizeof(*locked)));
24369+
1facf9fc 24370+ kfree(sbinfo->si_branch);
b752ccd1 24371+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 24372+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 24373+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 24374+
24375+ kfree(sbinfo);
24376+}
24377+
24378+int au_si_alloc(struct super_block *sb)
24379+{
86dc4139 24380+ int err, i;
1facf9fc 24381+ struct au_sbinfo *sbinfo;
e49829fe 24382+ static struct lock_class_key aufs_si;
1facf9fc 24383+
24384+ err = -ENOMEM;
4a4d8108 24385+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 24386+ if (unlikely(!sbinfo))
24387+ goto out;
24388+
b752ccd1
AM
24389+ BUILD_BUG_ON(sizeof(unsigned long) !=
24390+ sizeof(*sbinfo->au_si_pid.bitmap));
24391+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
24392+ sizeof(*sbinfo->au_si_pid.bitmap),
24393+ GFP_NOFS);
24394+ if (unlikely(!sbinfo->au_si_pid.bitmap))
24395+ goto out_sbinfo;
24396+
1facf9fc 24397+ /* will be reallocated separately */
24398+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
24399+ if (unlikely(!sbinfo->si_branch))
b752ccd1 24400+ goto out_pidmap;
1facf9fc 24401+
1facf9fc 24402+ err = sysaufs_si_init(sbinfo);
24403+ if (unlikely(err))
24404+ goto out_br;
24405+
24406+ au_nwt_init(&sbinfo->si_nowait);
dece6358 24407+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 24408+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
24409+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
24410+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
24411+
7f207e10 24412+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
24413+ atomic_long_set(&sbinfo->si_nfiles, 0);
24414+
1facf9fc 24415+ sbinfo->si_bend = -1;
392086de 24416+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 24417+
24418+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
24419+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
24420+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
24421+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 24422+
e49829fe 24423+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 24424+
392086de
AM
24425+ sbinfo->si_xino_jiffy = jiffies;
24426+ sbinfo->si_xino_expire
24427+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 24428+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 24429+ sbinfo->si_xino_brid = -1;
24430+ /* leave si_xib_last_pindex and si_xib_next_bit */
24431+
e49829fe 24432+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 24433+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
24434+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
24435+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
24436+
86dc4139
AM
24437+ for (i = 0; i < AuPlink_NHASH; i++)
24438+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 24439+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 24440+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 24441+
523b37e3
AM
24442+ au_sphl_init(&sbinfo->si_files);
24443+
1facf9fc 24444+ /* leave other members for sysaufs and si_mnt. */
24445+ sbinfo->si_sb = sb;
24446+ sb->s_fs_info = sbinfo;
b752ccd1 24447+ si_pid_set(sb);
1facf9fc 24448+ au_debug_sbinfo_init(sbinfo);
24449+ return 0; /* success */
24450+
4f0767ce 24451+out_br:
1facf9fc 24452+ kfree(sbinfo->si_branch);
4f0767ce 24453+out_pidmap:
b752ccd1 24454+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 24455+out_sbinfo:
1facf9fc 24456+ kfree(sbinfo);
4f0767ce 24457+out:
1facf9fc 24458+ return err;
24459+}
24460+
24461+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
24462+{
24463+ int err, sz;
24464+ struct au_branch **brp;
24465+
dece6358
AM
24466+ AuRwMustWriteLock(&sbinfo->si_rwsem);
24467+
1facf9fc 24468+ err = -ENOMEM;
24469+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
24470+ if (unlikely(!sz))
24471+ sz = sizeof(*brp);
24472+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
24473+ if (brp) {
24474+ sbinfo->si_branch = brp;
24475+ err = 0;
24476+ }
24477+
24478+ return err;
24479+}
24480+
24481+/* ---------------------------------------------------------------------- */
24482+
24483+unsigned int au_sigen_inc(struct super_block *sb)
24484+{
24485+ unsigned int gen;
24486+
dece6358
AM
24487+ SiMustWriteLock(sb);
24488+
1facf9fc 24489+ gen = ++au_sbi(sb)->si_generation;
24490+ au_update_digen(sb->s_root);
537831f9 24491+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 24492+ sb->s_root->d_inode->i_version++;
24493+ return gen;
24494+}
24495+
24496+aufs_bindex_t au_new_br_id(struct super_block *sb)
24497+{
24498+ aufs_bindex_t br_id;
24499+ int i;
24500+ struct au_sbinfo *sbinfo;
24501+
dece6358
AM
24502+ SiMustWriteLock(sb);
24503+
1facf9fc 24504+ sbinfo = au_sbi(sb);
24505+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
24506+ br_id = ++sbinfo->si_last_br_id;
7f207e10 24507+ AuDebugOn(br_id < 0);
1facf9fc 24508+ if (br_id && au_br_index(sb, br_id) < 0)
24509+ return br_id;
24510+ }
24511+
24512+ return -1;
24513+}
24514+
24515+/* ---------------------------------------------------------------------- */
24516+
e49829fe
JR
24517+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
24518+int si_read_lock(struct super_block *sb, int flags)
24519+{
24520+ int err;
24521+
24522+ err = 0;
24523+ if (au_ftest_lock(flags, FLUSH))
24524+ au_nwt_flush(&au_sbi(sb)->si_nowait);
24525+
24526+ si_noflush_read_lock(sb);
24527+ err = au_plink_maint(sb, flags);
24528+ if (unlikely(err))
24529+ si_read_unlock(sb);
24530+
24531+ return err;
24532+}
24533+
24534+int si_write_lock(struct super_block *sb, int flags)
24535+{
24536+ int err;
24537+
24538+ if (au_ftest_lock(flags, FLUSH))
24539+ au_nwt_flush(&au_sbi(sb)->si_nowait);
24540+
24541+ si_noflush_write_lock(sb);
24542+ err = au_plink_maint(sb, flags);
24543+ if (unlikely(err))
24544+ si_write_unlock(sb);
24545+
24546+ return err;
24547+}
24548+
1facf9fc 24549+/* dentry and super_block lock. call at entry point */
e49829fe 24550+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 24551+{
e49829fe 24552+ int err;
027c5e7a 24553+ struct super_block *sb;
e49829fe 24554+
027c5e7a
AM
24555+ sb = dentry->d_sb;
24556+ err = si_read_lock(sb, flags);
24557+ if (unlikely(err))
24558+ goto out;
24559+
24560+ if (au_ftest_lock(flags, DW))
24561+ di_write_lock_child(dentry);
24562+ else
24563+ di_read_lock_child(dentry, flags);
24564+
24565+ if (au_ftest_lock(flags, GEN)) {
24566+ err = au_digen_test(dentry, au_sigen(sb));
24567+ AuDebugOn(!err && au_dbrange_test(dentry));
24568+ if (unlikely(err))
24569+ aufs_read_unlock(dentry, flags);
e49829fe
JR
24570+ }
24571+
027c5e7a 24572+out:
e49829fe 24573+ return err;
1facf9fc 24574+}
24575+
24576+void aufs_read_unlock(struct dentry *dentry, int flags)
24577+{
24578+ if (au_ftest_lock(flags, DW))
24579+ di_write_unlock(dentry);
24580+ else
24581+ di_read_unlock(dentry, flags);
24582+ si_read_unlock(dentry->d_sb);
24583+}
24584+
24585+void aufs_write_lock(struct dentry *dentry)
24586+{
e49829fe 24587+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 24588+ di_write_lock_child(dentry);
24589+}
24590+
24591+void aufs_write_unlock(struct dentry *dentry)
24592+{
24593+ di_write_unlock(dentry);
24594+ si_write_unlock(dentry->d_sb);
24595+}
24596+
e49829fe 24597+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 24598+{
e49829fe 24599+ int err;
027c5e7a
AM
24600+ unsigned int sigen;
24601+ struct super_block *sb;
e49829fe 24602+
027c5e7a
AM
24603+ sb = d1->d_sb;
24604+ err = si_read_lock(sb, flags);
24605+ if (unlikely(err))
24606+ goto out;
24607+
24608+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
24609+
24610+ if (au_ftest_lock(flags, GEN)) {
24611+ sigen = au_sigen(sb);
24612+ err = au_digen_test(d1, sigen);
24613+ AuDebugOn(!err && au_dbrange_test(d1));
24614+ if (!err) {
24615+ err = au_digen_test(d2, sigen);
24616+ AuDebugOn(!err && au_dbrange_test(d2));
24617+ }
24618+ if (unlikely(err))
24619+ aufs_read_and_write_unlock2(d1, d2);
24620+ }
24621+
24622+out:
e49829fe 24623+ return err;
1facf9fc 24624+}
24625+
24626+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
24627+{
24628+ di_write_unlock2(d1, d2);
24629+ si_read_unlock(d1->d_sb);
24630+}
b752ccd1
AM
24631+
24632+/* ---------------------------------------------------------------------- */
24633+
24634+int si_pid_test_slow(struct super_block *sb)
24635+{
24636+ void *p;
24637+
24638+ rcu_read_lock();
24639+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
24640+ rcu_read_unlock();
24641+
027c5e7a 24642+ return (long)!!p;
b752ccd1
AM
24643+}
24644+
24645+void si_pid_set_slow(struct super_block *sb)
24646+{
24647+ int err;
24648+ struct au_sbinfo *sbinfo;
24649+
24650+ AuDebugOn(si_pid_test_slow(sb));
24651+
24652+ sbinfo = au_sbi(sb);
24653+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
24654+ AuDebugOn(err);
24655+ spin_lock(&sbinfo->au_si_pid.tree_lock);
24656+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 24657+ /*any valid ptr*/sb);
b752ccd1
AM
24658+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
24659+ AuDebugOn(err);
24660+ radix_tree_preload_end();
24661+}
24662+
24663+void si_pid_clr_slow(struct super_block *sb)
24664+{
24665+ void *p;
24666+ struct au_sbinfo *sbinfo;
24667+
24668+ AuDebugOn(!si_pid_test_slow(sb));
24669+
24670+ sbinfo = au_sbi(sb);
24671+ spin_lock(&sbinfo->au_si_pid.tree_lock);
24672+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
24673+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 24674+}
7f207e10
AM
24675diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
24676--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 24677+++ linux/fs/aufs/spl.h 2014-04-24 22:11:10.858602483 +0200
523b37e3 24678@@ -0,0 +1,111 @@
1facf9fc 24679+/*
523b37e3 24680+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 24681+ *
24682+ * This program, aufs is free software; you can redistribute it and/or modify
24683+ * it under the terms of the GNU General Public License as published by
24684+ * the Free Software Foundation; either version 2 of the License, or
24685+ * (at your option) any later version.
dece6358
AM
24686+ *
24687+ * This program is distributed in the hope that it will be useful,
24688+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24689+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24690+ * GNU General Public License for more details.
24691+ *
24692+ * You should have received a copy of the GNU General Public License
523b37e3 24693+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24694+ */
24695+
24696+/*
24697+ * simple list protected by a spinlock
24698+ */
24699+
24700+#ifndef __AUFS_SPL_H__
24701+#define __AUFS_SPL_H__
24702+
24703+#ifdef __KERNEL__
24704+
1facf9fc 24705+struct au_splhead {
24706+ spinlock_t spin;
24707+ struct list_head head;
24708+};
24709+
24710+static inline void au_spl_init(struct au_splhead *spl)
24711+{
24712+ spin_lock_init(&spl->spin);
24713+ INIT_LIST_HEAD(&spl->head);
24714+}
24715+
24716+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
24717+{
24718+ spin_lock(&spl->spin);
24719+ list_add(list, &spl->head);
24720+ spin_unlock(&spl->spin);
24721+}
24722+
24723+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
24724+{
24725+ spin_lock(&spl->spin);
24726+ list_del(list);
24727+ spin_unlock(&spl->spin);
24728+}
24729+
4a4d8108
AM
24730+static inline void au_spl_del_rcu(struct list_head *list,
24731+ struct au_splhead *spl)
24732+{
24733+ spin_lock(&spl->spin);
24734+ list_del_rcu(list);
24735+ spin_unlock(&spl->spin);
24736+}
24737+
86dc4139
AM
24738+/* ---------------------------------------------------------------------- */
24739+
24740+struct au_sphlhead {
24741+ spinlock_t spin;
24742+ struct hlist_head head;
24743+};
24744+
24745+static inline void au_sphl_init(struct au_sphlhead *sphl)
24746+{
24747+ spin_lock_init(&sphl->spin);
24748+ INIT_HLIST_HEAD(&sphl->head);
24749+}
24750+
24751+static inline void au_sphl_add(struct hlist_node *hlist,
24752+ struct au_sphlhead *sphl)
24753+{
24754+ spin_lock(&sphl->spin);
24755+ hlist_add_head(hlist, &sphl->head);
24756+ spin_unlock(&sphl->spin);
24757+}
24758+
24759+static inline void au_sphl_del(struct hlist_node *hlist,
24760+ struct au_sphlhead *sphl)
24761+{
24762+ spin_lock(&sphl->spin);
24763+ hlist_del(hlist);
24764+ spin_unlock(&sphl->spin);
24765+}
24766+
24767+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
24768+ struct au_sphlhead *sphl)
24769+{
24770+ spin_lock(&sphl->spin);
24771+ hlist_del_rcu(hlist);
24772+ spin_unlock(&sphl->spin);
24773+}
24774+
24775+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
24776+{
24777+ unsigned long cnt;
24778+ struct hlist_node *pos;
24779+
24780+ cnt = 0;
24781+ spin_lock(&sphl->spin);
24782+ hlist_for_each(pos, &sphl->head)
24783+ cnt++;
24784+ spin_unlock(&sphl->spin);
24785+ return cnt;
24786+}
24787+
1facf9fc 24788+#endif /* __KERNEL__ */
24789+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
24790diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
24791--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 24792+++ linux/fs/aufs/super.c 2014-04-24 22:11:10.858602483 +0200
523b37e3 24793@@ -0,0 +1,1001 @@
1facf9fc 24794+/*
523b37e3 24795+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 24796+ *
24797+ * This program, aufs is free software; you can redistribute it and/or modify
24798+ * it under the terms of the GNU General Public License as published by
24799+ * the Free Software Foundation; either version 2 of the License, or
24800+ * (at your option) any later version.
dece6358
AM
24801+ *
24802+ * This program is distributed in the hope that it will be useful,
24803+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24804+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24805+ * GNU General Public License for more details.
24806+ *
24807+ * You should have received a copy of the GNU General Public License
523b37e3 24808+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24809+ */
24810+
24811+/*
24812+ * mount and super_block operations
24813+ */
24814+
f6c5ef8b 24815+#include <linux/mm.h>
dece6358 24816+#include <linux/module.h>
1facf9fc 24817+#include <linux/seq_file.h>
24818+#include <linux/statfs.h>
7f207e10
AM
24819+#include <linux/vmalloc.h>
24820+#include <linux/writeback.h>
1facf9fc 24821+#include "aufs.h"
24822+
24823+/*
24824+ * super_operations
24825+ */
24826+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
24827+{
24828+ struct au_icntnr *c;
24829+
24830+ c = au_cache_alloc_icntnr();
24831+ if (c) {
027c5e7a 24832+ au_icntnr_init(c);
1facf9fc 24833+ c->vfs_inode.i_version = 1; /* sigen(sb); */
24834+ c->iinfo.ii_hinode = NULL;
24835+ return &c->vfs_inode;
24836+ }
24837+ return NULL;
24838+}
24839+
027c5e7a
AM
24840+static void aufs_destroy_inode_cb(struct rcu_head *head)
24841+{
24842+ struct inode *inode = container_of(head, struct inode, i_rcu);
24843+
b4510431 24844+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
24845+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
24846+}
24847+
1facf9fc 24848+static void aufs_destroy_inode(struct inode *inode)
24849+{
24850+ au_iinfo_fin(inode);
027c5e7a 24851+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 24852+}
24853+
24854+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
24855+{
24856+ struct inode *inode;
24857+ int err;
24858+
24859+ inode = iget_locked(sb, ino);
24860+ if (unlikely(!inode)) {
24861+ inode = ERR_PTR(-ENOMEM);
24862+ goto out;
24863+ }
24864+ if (!(inode->i_state & I_NEW))
24865+ goto out;
24866+
24867+ err = au_xigen_new(inode);
24868+ if (!err)
24869+ err = au_iinfo_init(inode);
24870+ if (!err)
24871+ inode->i_version++;
24872+ else {
24873+ iget_failed(inode);
24874+ inode = ERR_PTR(err);
24875+ }
24876+
4f0767ce 24877+out:
1facf9fc 24878+ /* never return NULL */
24879+ AuDebugOn(!inode);
24880+ AuTraceErrPtr(inode);
24881+ return inode;
24882+}
24883+
24884+/* lock free root dinfo */
24885+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
24886+{
24887+ int err;
24888+ aufs_bindex_t bindex, bend;
24889+ struct path path;
4a4d8108 24890+ struct au_hdentry *hdp;
1facf9fc 24891+ struct au_branch *br;
1e00d052 24892+ char *perm;
1facf9fc 24893+
24894+ err = 0;
24895+ bend = au_sbend(sb);
4a4d8108 24896+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 24897+ for (bindex = 0; !err && bindex <= bend; bindex++) {
24898+ br = au_sbr(sb, bindex);
86dc4139 24899+ path.mnt = au_br_mnt(br);
4a4d8108 24900+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 24901+ err = au_seq_path(seq, &path);
1e00d052
AM
24902+ if (err > 0) {
24903+ perm = au_optstr_br_perm(br->br_perm);
24904+ if (perm) {
24905+ err = seq_printf(seq, "=%s", perm);
24906+ kfree(perm);
24907+ if (err == -1)
24908+ err = -E2BIG;
24909+ } else
24910+ err = -ENOMEM;
24911+ }
1facf9fc 24912+ if (!err && bindex != bend)
24913+ err = seq_putc(seq, ':');
24914+ }
24915+
24916+ return err;
24917+}
24918+
24919+static void au_show_wbr_create(struct seq_file *m, int v,
24920+ struct au_sbinfo *sbinfo)
24921+{
24922+ const char *pat;
24923+
dece6358
AM
24924+ AuRwMustAnyLock(&sbinfo->si_rwsem);
24925+
c2b27bf2 24926+ seq_puts(m, ",create=");
1facf9fc 24927+ pat = au_optstr_wbr_create(v);
24928+ switch (v) {
24929+ case AuWbrCreate_TDP:
24930+ case AuWbrCreate_RR:
24931+ case AuWbrCreate_MFS:
24932+ case AuWbrCreate_PMFS:
c2b27bf2 24933+ seq_puts(m, pat);
1facf9fc 24934+ break;
24935+ case AuWbrCreate_MFSV:
24936+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
24937+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24938+ / MSEC_PER_SEC);
1facf9fc 24939+ break;
24940+ case AuWbrCreate_PMFSV:
24941+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
24942+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24943+ / MSEC_PER_SEC);
1facf9fc 24944+ break;
24945+ case AuWbrCreate_MFSRR:
24946+ seq_printf(m, /*pat*/"mfsrr:%llu",
24947+ sbinfo->si_wbr_mfs.mfsrr_watermark);
24948+ break;
24949+ case AuWbrCreate_MFSRRV:
24950+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
24951+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
24952+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24953+ / MSEC_PER_SEC);
1facf9fc 24954+ break;
392086de
AM
24955+ case AuWbrCreate_PMFSRR:
24956+ seq_printf(m, /*pat*/"pmfsrr:%llu",
24957+ sbinfo->si_wbr_mfs.mfsrr_watermark);
24958+ break;
24959+ case AuWbrCreate_PMFSRRV:
24960+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
24961+ sbinfo->si_wbr_mfs.mfsrr_watermark,
24962+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
24963+ / MSEC_PER_SEC);
24964+ break;
1facf9fc 24965+ }
24966+}
24967+
7eafdf33 24968+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 24969+{
24970+#ifdef CONFIG_SYSFS
24971+ return 0;
24972+#else
24973+ int err;
24974+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
24975+ aufs_bindex_t bindex, brid;
1facf9fc 24976+ struct qstr *name;
24977+ struct file *f;
24978+ struct dentry *d, *h_root;
4a4d8108 24979+ struct au_hdentry *hdp;
1facf9fc 24980+
dece6358
AM
24981+ AuRwMustAnyLock(&sbinfo->si_rwsem);
24982+
1facf9fc 24983+ err = 0;
1facf9fc 24984+ f = au_sbi(sb)->si_xib;
24985+ if (!f)
24986+ goto out;
24987+
24988+ /* stop printing the default xino path on the first writable branch */
24989+ h_root = NULL;
24990+ brid = au_xino_brid(sb);
24991+ if (brid >= 0) {
24992+ bindex = au_br_index(sb, brid);
4a4d8108
AM
24993+ hdp = au_di(sb->s_root)->di_hdentry;
24994+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 24995+ }
24996+ d = f->f_dentry;
24997+ name = &d->d_name;
24998+ /* safe ->d_parent because the file is unlinked */
24999+ if (d->d_parent == h_root
25000+ && name->len == len
25001+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
25002+ goto out;
25003+
25004+ seq_puts(seq, ",xino=");
25005+ err = au_xino_path(seq, f);
25006+
4f0767ce 25007+out:
1facf9fc 25008+ return err;
25009+#endif
25010+}
25011+
25012+/* seq_file will re-call me in case of too long string */
7eafdf33 25013+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 25014+{
027c5e7a 25015+ int err;
1facf9fc 25016+ unsigned int mnt_flags, v;
25017+ struct super_block *sb;
25018+ struct au_sbinfo *sbinfo;
25019+
25020+#define AuBool(name, str) do { \
25021+ v = au_opt_test(mnt_flags, name); \
25022+ if (v != au_opt_test(AuOpt_Def, name)) \
25023+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
25024+} while (0)
25025+
25026+#define AuStr(name, str) do { \
25027+ v = mnt_flags & AuOptMask_##name; \
25028+ if (v != (AuOpt_Def & AuOptMask_##name)) \
25029+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
25030+} while (0)
25031+
25032+#define AuUInt(name, str, val) do { \
25033+ if (val != AUFS_##name##_DEF) \
25034+ seq_printf(m, "," #str "=%u", val); \
25035+} while (0)
25036+
25037+ /* lock free root dinfo */
7eafdf33 25038+ sb = dentry->d_sb;
1facf9fc 25039+ si_noflush_read_lock(sb);
25040+ sbinfo = au_sbi(sb);
25041+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
25042+
25043+ mnt_flags = au_mntflags(sb);
25044+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 25045+ err = au_show_xino(m, sb);
1facf9fc 25046+ if (unlikely(err))
25047+ goto out;
25048+ } else
25049+ seq_puts(m, ",noxino");
25050+
25051+ AuBool(TRUNC_XINO, trunc_xino);
25052+ AuStr(UDBA, udba);
dece6358 25053+ AuBool(SHWH, shwh);
1facf9fc 25054+ AuBool(PLINK, plink);
4a4d8108 25055+ AuBool(DIO, dio);
1facf9fc 25056+ /* AuBool(DIRPERM1, dirperm1); */
25057+ /* AuBool(REFROF, refrof); */
25058+
25059+ v = sbinfo->si_wbr_create;
25060+ if (v != AuWbrCreate_Def)
25061+ au_show_wbr_create(m, v, sbinfo);
25062+
25063+ v = sbinfo->si_wbr_copyup;
25064+ if (v != AuWbrCopyup_Def)
25065+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
25066+
25067+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
25068+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
25069+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
25070+
25071+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
25072+
027c5e7a
AM
25073+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
25074+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 25075+
25076+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
25077+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
25078+
25079+ AuBool(SUM, sum);
25080+ /* AuBool(SUM_W, wsum); */
25081+ AuBool(WARN_PERM, warn_perm);
25082+ AuBool(VERBOSE, verbose);
25083+
4f0767ce 25084+out:
1facf9fc 25085+ /* be sure to print "br:" last */
25086+ if (!sysaufs_brs) {
25087+ seq_puts(m, ",br:");
25088+ au_show_brs(m, sb);
25089+ }
25090+ si_read_unlock(sb);
25091+ return 0;
25092+
1facf9fc 25093+#undef AuBool
25094+#undef AuStr
4a4d8108 25095+#undef AuUInt
1facf9fc 25096+}
25097+
25098+/* ---------------------------------------------------------------------- */
25099+
25100+/* sum mode which returns the summation for statfs(2) */
25101+
25102+static u64 au_add_till_max(u64 a, u64 b)
25103+{
25104+ u64 old;
25105+
25106+ old = a;
25107+ a += b;
92d182d2
AM
25108+ if (old <= a)
25109+ return a;
25110+ return ULLONG_MAX;
25111+}
25112+
25113+static u64 au_mul_till_max(u64 a, long mul)
25114+{
25115+ u64 old;
25116+
25117+ old = a;
25118+ a *= mul;
25119+ if (old <= a)
1facf9fc 25120+ return a;
25121+ return ULLONG_MAX;
25122+}
25123+
25124+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
25125+{
25126+ int err;
92d182d2 25127+ long bsize, factor;
1facf9fc 25128+ u64 blocks, bfree, bavail, files, ffree;
25129+ aufs_bindex_t bend, bindex, i;
25130+ unsigned char shared;
7f207e10 25131+ struct path h_path;
1facf9fc 25132+ struct super_block *h_sb;
25133+
92d182d2
AM
25134+ err = 0;
25135+ bsize = LONG_MAX;
25136+ files = 0;
25137+ ffree = 0;
1facf9fc 25138+ blocks = 0;
25139+ bfree = 0;
25140+ bavail = 0;
1facf9fc 25141+ bend = au_sbend(sb);
92d182d2 25142+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
25143+ h_path.mnt = au_sbr_mnt(sb, bindex);
25144+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 25145+ shared = 0;
92d182d2 25146+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 25147+ shared = (au_sbr_sb(sb, i) == h_sb);
25148+ if (shared)
25149+ continue;
25150+
25151+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
25152+ h_path.dentry = h_path.mnt->mnt_root;
25153+ err = vfs_statfs(&h_path, buf);
1facf9fc 25154+ if (unlikely(err))
25155+ goto out;
25156+
92d182d2
AM
25157+ if (bsize > buf->f_bsize) {
25158+ /*
25159+ * we will reduce bsize, so we have to expand blocks
25160+ * etc. to match them again
25161+ */
25162+ factor = (bsize / buf->f_bsize);
25163+ blocks = au_mul_till_max(blocks, factor);
25164+ bfree = au_mul_till_max(bfree, factor);
25165+ bavail = au_mul_till_max(bavail, factor);
25166+ bsize = buf->f_bsize;
25167+ }
25168+
25169+ factor = (buf->f_bsize / bsize);
25170+ blocks = au_add_till_max(blocks,
25171+ au_mul_till_max(buf->f_blocks, factor));
25172+ bfree = au_add_till_max(bfree,
25173+ au_mul_till_max(buf->f_bfree, factor));
25174+ bavail = au_add_till_max(bavail,
25175+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 25176+ files = au_add_till_max(files, buf->f_files);
25177+ ffree = au_add_till_max(ffree, buf->f_ffree);
25178+ }
25179+
92d182d2 25180+ buf->f_bsize = bsize;
1facf9fc 25181+ buf->f_blocks = blocks;
25182+ buf->f_bfree = bfree;
25183+ buf->f_bavail = bavail;
25184+ buf->f_files = files;
25185+ buf->f_ffree = ffree;
92d182d2 25186+ buf->f_frsize = 0;
1facf9fc 25187+
4f0767ce 25188+out:
1facf9fc 25189+ return err;
25190+}
25191+
25192+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
25193+{
25194+ int err;
7f207e10 25195+ struct path h_path;
1facf9fc 25196+ struct super_block *sb;
25197+
25198+ /* lock free root dinfo */
25199+ sb = dentry->d_sb;
25200+ si_noflush_read_lock(sb);
7f207e10 25201+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 25202+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
25203+ h_path.mnt = au_sbr_mnt(sb, 0);
25204+ h_path.dentry = h_path.mnt->mnt_root;
25205+ err = vfs_statfs(&h_path, buf);
25206+ } else
1facf9fc 25207+ err = au_statfs_sum(sb, buf);
25208+ si_read_unlock(sb);
25209+
25210+ if (!err) {
25211+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 25212+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 25213+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
25214+ }
25215+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
25216+
25217+ return err;
25218+}
25219+
25220+/* ---------------------------------------------------------------------- */
25221+
537831f9
AM
25222+static int aufs_sync_fs(struct super_block *sb, int wait)
25223+{
25224+ int err, e;
25225+ aufs_bindex_t bend, bindex;
25226+ struct au_branch *br;
25227+ struct super_block *h_sb;
25228+
25229+ err = 0;
25230+ si_noflush_read_lock(sb);
25231+ bend = au_sbend(sb);
25232+ for (bindex = 0; bindex <= bend; bindex++) {
25233+ br = au_sbr(sb, bindex);
25234+ if (!au_br_writable(br->br_perm))
25235+ continue;
25236+
25237+ h_sb = au_sbr_sb(sb, bindex);
25238+ if (h_sb->s_op->sync_fs) {
25239+ e = h_sb->s_op->sync_fs(h_sb, wait);
25240+ if (unlikely(e && !err))
25241+ err = e;
25242+ /* go on even if an error happens */
25243+ }
25244+ }
25245+ si_read_unlock(sb);
25246+
25247+ return err;
25248+}
25249+
25250+/* ---------------------------------------------------------------------- */
25251+
1facf9fc 25252+/* final actions when unmounting a file system */
25253+static void aufs_put_super(struct super_block *sb)
25254+{
25255+ struct au_sbinfo *sbinfo;
25256+
25257+ sbinfo = au_sbi(sb);
25258+ if (!sbinfo)
25259+ return;
25260+
1facf9fc 25261+ dbgaufs_si_fin(sbinfo);
25262+ kobject_put(&sbinfo->si_kobj);
25263+}
25264+
25265+/* ---------------------------------------------------------------------- */
25266+
7f207e10
AM
25267+void au_array_free(void *array)
25268+{
25269+ if (array) {
25270+ if (!is_vmalloc_addr(array))
25271+ kfree(array);
25272+ else
25273+ vfree(array);
25274+ }
25275+}
25276+
25277+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
25278+{
25279+ void *array;
25280+ unsigned long long n;
25281+
25282+ array = NULL;
25283+ n = 0;
25284+ if (!*hint)
25285+ goto out;
25286+
25287+ if (*hint > ULLONG_MAX / sizeof(array)) {
25288+ array = ERR_PTR(-EMFILE);
25289+ pr_err("hint %llu\n", *hint);
25290+ goto out;
25291+ }
25292+
25293+ array = kmalloc(sizeof(array) * *hint, GFP_NOFS);
25294+ if (unlikely(!array))
25295+ array = vmalloc(sizeof(array) * *hint);
25296+ if (unlikely(!array)) {
25297+ array = ERR_PTR(-ENOMEM);
25298+ goto out;
25299+ }
25300+
25301+ n = cb(array, *hint, arg);
25302+ AuDebugOn(n > *hint);
25303+
25304+out:
25305+ *hint = n;
25306+ return array;
25307+}
25308+
25309+static unsigned long long au_iarray_cb(void *a,
25310+ unsigned long long max __maybe_unused,
25311+ void *arg)
25312+{
25313+ unsigned long long n;
25314+ struct inode **p, *inode;
25315+ struct list_head *head;
25316+
25317+ n = 0;
25318+ p = a;
25319+ head = arg;
2cbb1c4b 25320+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
25321+ list_for_each_entry(inode, head, i_sb_list) {
25322+ if (!is_bad_inode(inode)
25323+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
25324+ spin_lock(&inode->i_lock);
25325+ if (atomic_read(&inode->i_count)) {
25326+ au_igrab(inode);
25327+ *p++ = inode;
25328+ n++;
25329+ AuDebugOn(n > max);
25330+ }
25331+ spin_unlock(&inode->i_lock);
7f207e10
AM
25332+ }
25333+ }
2cbb1c4b 25334+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
25335+
25336+ return n;
25337+}
25338+
25339+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
25340+{
25341+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
25342+ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
25343+}
25344+
25345+void au_iarray_free(struct inode **a, unsigned long long max)
25346+{
25347+ unsigned long long ull;
25348+
25349+ for (ull = 0; ull < max; ull++)
25350+ iput(a[ull]);
25351+ au_array_free(a);
25352+}
25353+
25354+/* ---------------------------------------------------------------------- */
25355+
1facf9fc 25356+/*
25357+ * refresh dentry and inode at remount time.
25358+ */
027c5e7a
AM
25359+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
25360+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
25361+ struct dentry *parent)
1facf9fc 25362+{
25363+ int err;
1facf9fc 25364+
25365+ di_write_lock_child(dentry);
1facf9fc 25366+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
25367+ err = au_refresh_dentry(dentry, parent);
25368+ if (!err && dir_flags)
25369+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 25370+ di_read_unlock(parent, AuLock_IR);
1facf9fc 25371+ di_write_unlock(dentry);
25372+
25373+ return err;
25374+}
25375+
027c5e7a
AM
25376+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
25377+ struct au_sbinfo *sbinfo,
25378+ const unsigned int dir_flags)
1facf9fc 25379+{
027c5e7a
AM
25380+ int err;
25381+ struct dentry *parent;
25382+ struct inode *inode;
25383+
25384+ err = 0;
25385+ parent = dget_parent(dentry);
25386+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
25387+ inode = dentry->d_inode;
25388+ if (inode) {
25389+ if (!S_ISDIR(inode->i_mode))
25390+ err = au_do_refresh(dentry, /*dir_flags*/0,
25391+ parent);
25392+ else {
25393+ err = au_do_refresh(dentry, dir_flags, parent);
25394+ if (unlikely(err))
25395+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
25396+ }
25397+ } else
25398+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
25399+ AuDbgDentry(dentry);
25400+ }
25401+ dput(parent);
25402+
25403+ AuTraceErr(err);
25404+ return err;
1facf9fc 25405+}
25406+
027c5e7a 25407+static int au_refresh_d(struct super_block *sb)
1facf9fc 25408+{
25409+ int err, i, j, ndentry, e;
027c5e7a 25410+ unsigned int sigen;
1facf9fc 25411+ struct au_dcsub_pages dpages;
25412+ struct au_dpage *dpage;
027c5e7a
AM
25413+ struct dentry **dentries, *d;
25414+ struct au_sbinfo *sbinfo;
25415+ struct dentry *root = sb->s_root;
25416+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
1facf9fc 25417+
027c5e7a
AM
25418+ err = au_dpages_init(&dpages, GFP_NOFS);
25419+ if (unlikely(err))
1facf9fc 25420+ goto out;
027c5e7a
AM
25421+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
25422+ if (unlikely(err))
1facf9fc 25423+ goto out_dpages;
1facf9fc 25424+
027c5e7a
AM
25425+ sigen = au_sigen(sb);
25426+ sbinfo = au_sbi(sb);
25427+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 25428+ dpage = dpages.dpages + i;
25429+ dentries = dpage->dentries;
25430+ ndentry = dpage->ndentry;
027c5e7a 25431+ for (j = 0; j < ndentry; j++) {
1facf9fc 25432+ d = dentries[j];
027c5e7a
AM
25433+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
25434+ if (unlikely(e && !err))
25435+ err = e;
25436+ /* go on even err */
1facf9fc 25437+ }
25438+ }
25439+
4f0767ce 25440+out_dpages:
1facf9fc 25441+ au_dpages_free(&dpages);
4f0767ce 25442+out:
1facf9fc 25443+ return err;
25444+}
25445+
027c5e7a 25446+static int au_refresh_i(struct super_block *sb)
1facf9fc 25447+{
027c5e7a
AM
25448+ int err, e;
25449+ unsigned int sigen;
25450+ unsigned long long max, ull;
25451+ struct inode *inode, **array;
1facf9fc 25452+
027c5e7a
AM
25453+ array = au_iarray_alloc(sb, &max);
25454+ err = PTR_ERR(array);
25455+ if (IS_ERR(array))
25456+ goto out;
1facf9fc 25457+
25458+ err = 0;
027c5e7a
AM
25459+ sigen = au_sigen(sb);
25460+ for (ull = 0; ull < max; ull++) {
25461+ inode = array[ull];
537831f9 25462+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 25463+ ii_write_lock_child(inode);
027c5e7a 25464+ e = au_refresh_hinode_self(inode);
1facf9fc 25465+ ii_write_unlock(inode);
25466+ if (unlikely(e)) {
027c5e7a 25467+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 25468+ if (!err)
25469+ err = e;
25470+ /* go on even if err */
25471+ }
25472+ }
1facf9fc 25473+ }
25474+
027c5e7a 25475+ au_iarray_free(array, max);
1facf9fc 25476+
4f0767ce 25477+out:
1facf9fc 25478+ return err;
25479+}
25480+
027c5e7a 25481+static void au_remount_refresh(struct super_block *sb)
1facf9fc 25482+{
027c5e7a
AM
25483+ int err, e;
25484+ unsigned int udba;
25485+ aufs_bindex_t bindex, bend;
1facf9fc 25486+ struct dentry *root;
25487+ struct inode *inode;
027c5e7a 25488+ struct au_branch *br;
1facf9fc 25489+
25490+ au_sigen_inc(sb);
027c5e7a 25491+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 25492+
25493+ root = sb->s_root;
25494+ DiMustNoWaiters(root);
25495+ inode = root->d_inode;
25496+ IiMustNoWaiters(inode);
1facf9fc 25497+
027c5e7a
AM
25498+ udba = au_opt_udba(sb);
25499+ bend = au_sbend(sb);
25500+ for (bindex = 0; bindex <= bend; bindex++) {
25501+ br = au_sbr(sb, bindex);
25502+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 25503+ if (unlikely(err))
027c5e7a
AM
25504+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
25505+ bindex, err);
25506+ /* go on even if err */
1facf9fc 25507+ }
027c5e7a 25508+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 25509+
027c5e7a
AM
25510+ di_write_unlock(root);
25511+ err = au_refresh_d(sb);
25512+ e = au_refresh_i(sb);
25513+ if (unlikely(e && !err))
25514+ err = e;
1facf9fc 25515+ /* aufs_write_lock() calls ..._child() */
25516+ di_write_lock_child(root);
027c5e7a
AM
25517+
25518+ au_cpup_attr_all(inode, /*force*/1);
25519+
25520+ if (unlikely(err))
25521+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 25522+}
25523+
25524+/* stop extra interpretation of errno in mount(8), and strange error messages */
25525+static int cvt_err(int err)
25526+{
25527+ AuTraceErr(err);
25528+
25529+ switch (err) {
25530+ case -ENOENT:
25531+ case -ENOTDIR:
25532+ case -EEXIST:
25533+ case -EIO:
25534+ err = -EINVAL;
25535+ }
25536+ return err;
25537+}
25538+
25539+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
25540+{
4a4d8108
AM
25541+ int err, do_dx;
25542+ unsigned int mntflags;
1facf9fc 25543+ struct au_opts opts;
25544+ struct dentry *root;
25545+ struct inode *inode;
25546+ struct au_sbinfo *sbinfo;
25547+
25548+ err = 0;
25549+ root = sb->s_root;
25550+ if (!data || !*data) {
e49829fe
JR
25551+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
25552+ if (!err) {
25553+ di_write_lock_child(root);
25554+ err = au_opts_verify(sb, *flags, /*pending*/0);
25555+ aufs_write_unlock(root);
25556+ }
1facf9fc 25557+ goto out;
25558+ }
25559+
25560+ err = -ENOMEM;
25561+ memset(&opts, 0, sizeof(opts));
25562+ opts.opt = (void *)__get_free_page(GFP_NOFS);
25563+ if (unlikely(!opts.opt))
25564+ goto out;
25565+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
25566+ opts.flags = AuOpts_REMOUNT;
25567+ opts.sb_flags = *flags;
25568+
25569+ /* parse it before aufs lock */
25570+ err = au_opts_parse(sb, data, &opts);
25571+ if (unlikely(err))
25572+ goto out_opts;
25573+
25574+ sbinfo = au_sbi(sb);
25575+ inode = root->d_inode;
25576+ mutex_lock(&inode->i_mutex);
e49829fe
JR
25577+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
25578+ if (unlikely(err))
25579+ goto out_mtx;
25580+ di_write_lock_child(root);
1facf9fc 25581+
25582+ /* au_opts_remount() may return an error */
25583+ err = au_opts_remount(sb, &opts);
25584+ au_opts_free(&opts);
25585+
027c5e7a
AM
25586+ if (au_ftest_opts(opts.flags, REFRESH))
25587+ au_remount_refresh(sb);
1facf9fc 25588+
4a4d8108
AM
25589+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
25590+ mntflags = au_mntflags(sb);
25591+ do_dx = !!au_opt_test(mntflags, DIO);
25592+ au_dy_arefresh(do_dx);
25593+ }
25594+
1facf9fc 25595+ aufs_write_unlock(root);
953406b4 25596+
e49829fe
JR
25597+out_mtx:
25598+ mutex_unlock(&inode->i_mutex);
4f0767ce 25599+out_opts:
1facf9fc 25600+ free_page((unsigned long)opts.opt);
4f0767ce 25601+out:
1facf9fc 25602+ err = cvt_err(err);
25603+ AuTraceErr(err);
25604+ return err;
25605+}
25606+
4a4d8108 25607+static const struct super_operations aufs_sop = {
1facf9fc 25608+ .alloc_inode = aufs_alloc_inode,
25609+ .destroy_inode = aufs_destroy_inode,
b752ccd1 25610+ /* always deleting, no clearing */
1facf9fc 25611+ .drop_inode = generic_delete_inode,
25612+ .show_options = aufs_show_options,
25613+ .statfs = aufs_statfs,
25614+ .put_super = aufs_put_super,
537831f9 25615+ .sync_fs = aufs_sync_fs,
1facf9fc 25616+ .remount_fs = aufs_remount_fs
25617+};
25618+
25619+/* ---------------------------------------------------------------------- */
25620+
25621+static int alloc_root(struct super_block *sb)
25622+{
25623+ int err;
25624+ struct inode *inode;
25625+ struct dentry *root;
25626+
25627+ err = -ENOMEM;
25628+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
25629+ err = PTR_ERR(inode);
25630+ if (IS_ERR(inode))
25631+ goto out;
25632+
25633+ inode->i_op = &aufs_dir_iop;
25634+ inode->i_fop = &aufs_dir_fop;
25635+ inode->i_mode = S_IFDIR;
9dbd164d 25636+ set_nlink(inode, 2);
1facf9fc 25637+ unlock_new_inode(inode);
25638+
92d182d2 25639+ root = d_make_root(inode);
1facf9fc 25640+ if (unlikely(!root))
92d182d2 25641+ goto out;
1facf9fc 25642+ err = PTR_ERR(root);
25643+ if (IS_ERR(root))
92d182d2 25644+ goto out;
1facf9fc 25645+
4a4d8108 25646+ err = au_di_init(root);
1facf9fc 25647+ if (!err) {
25648+ sb->s_root = root;
25649+ return 0; /* success */
25650+ }
25651+ dput(root);
1facf9fc 25652+
4f0767ce 25653+out:
1facf9fc 25654+ return err;
1facf9fc 25655+}
25656+
25657+static int aufs_fill_super(struct super_block *sb, void *raw_data,
25658+ int silent __maybe_unused)
25659+{
25660+ int err;
25661+ struct au_opts opts;
25662+ struct dentry *root;
25663+ struct inode *inode;
25664+ char *arg = raw_data;
25665+
25666+ if (unlikely(!arg || !*arg)) {
25667+ err = -EINVAL;
4a4d8108 25668+ pr_err("no arg\n");
1facf9fc 25669+ goto out;
25670+ }
25671+
25672+ err = -ENOMEM;
25673+ memset(&opts, 0, sizeof(opts));
25674+ opts.opt = (void *)__get_free_page(GFP_NOFS);
25675+ if (unlikely(!opts.opt))
25676+ goto out;
25677+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
25678+ opts.sb_flags = sb->s_flags;
25679+
25680+ err = au_si_alloc(sb);
25681+ if (unlikely(err))
25682+ goto out_opts;
25683+
25684+ /* all timestamps always follow the ones on the branch */
25685+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
25686+ sb->s_op = &aufs_sop;
027c5e7a 25687+ sb->s_d_op = &aufs_dop;
1facf9fc 25688+ sb->s_magic = AUFS_SUPER_MAGIC;
25689+ sb->s_maxbytes = 0;
25690+ au_export_init(sb);
25691+
25692+ err = alloc_root(sb);
25693+ if (unlikely(err)) {
25694+ si_write_unlock(sb);
25695+ goto out_info;
25696+ }
25697+ root = sb->s_root;
25698+ inode = root->d_inode;
25699+
25700+ /*
25701+ * actually we can parse options regardless aufs lock here.
25702+ * but at remount time, parsing must be done before aufs lock.
25703+ * so we follow the same rule.
25704+ */
25705+ ii_write_lock_parent(inode);
25706+ aufs_write_unlock(root);
25707+ err = au_opts_parse(sb, arg, &opts);
25708+ if (unlikely(err))
25709+ goto out_root;
25710+
25711+ /* lock vfs_inode first, then aufs. */
25712+ mutex_lock(&inode->i_mutex);
1facf9fc 25713+ aufs_write_lock(root);
25714+ err = au_opts_mount(sb, &opts);
25715+ au_opts_free(&opts);
1facf9fc 25716+ aufs_write_unlock(root);
25717+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
25718+ if (!err)
25719+ goto out_opts; /* success */
1facf9fc 25720+
4f0767ce 25721+out_root:
1facf9fc 25722+ dput(root);
25723+ sb->s_root = NULL;
4f0767ce 25724+out_info:
2cbb1c4b 25725+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 25726+ kobject_put(&au_sbi(sb)->si_kobj);
25727+ sb->s_fs_info = NULL;
4f0767ce 25728+out_opts:
1facf9fc 25729+ free_page((unsigned long)opts.opt);
4f0767ce 25730+out:
1facf9fc 25731+ AuTraceErr(err);
25732+ err = cvt_err(err);
25733+ AuTraceErr(err);
25734+ return err;
25735+}
25736+
25737+/* ---------------------------------------------------------------------- */
25738+
027c5e7a
AM
25739+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
25740+ const char *dev_name __maybe_unused,
25741+ void *raw_data)
1facf9fc 25742+{
027c5e7a 25743+ struct dentry *root;
1facf9fc 25744+ struct super_block *sb;
25745+
25746+ /* all timestamps always follow the ones on the branch */
25747+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
25748+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
25749+ if (IS_ERR(root))
25750+ goto out;
25751+
25752+ sb = root->d_sb;
25753+ si_write_lock(sb, !AuLock_FLUSH);
25754+ sysaufs_brs_add(sb, 0);
25755+ si_write_unlock(sb);
25756+ au_sbilist_add(sb);
25757+
25758+out:
25759+ return root;
1facf9fc 25760+}
25761+
e49829fe
JR
25762+static void aufs_kill_sb(struct super_block *sb)
25763+{
25764+ struct au_sbinfo *sbinfo;
25765+
25766+ sbinfo = au_sbi(sb);
25767+ if (sbinfo) {
25768+ au_sbilist_del(sb);
25769+ aufs_write_lock(sb->s_root);
25770+ if (sbinfo->si_wbr_create_ops->fin)
25771+ sbinfo->si_wbr_create_ops->fin(sb);
25772+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
25773+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
027c5e7a 25774+ au_remount_refresh(sb);
e49829fe
JR
25775+ }
25776+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
25777+ au_plink_put(sb, /*verbose*/1);
25778+ au_xino_clr(sb);
1e00d052 25779+ sbinfo->si_sb = NULL;
e49829fe 25780+ aufs_write_unlock(sb->s_root);
e49829fe
JR
25781+ au_nwt_flush(&sbinfo->si_nowait);
25782+ }
98d9a5b1 25783+ kill_anon_super(sb);
e49829fe
JR
25784+}
25785+
1facf9fc 25786+struct file_system_type aufs_fs_type = {
25787+ .name = AUFS_FSTYPE,
c06a8ce3
AM
25788+ /* a race between rename and others */
25789+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 25790+ .mount = aufs_mount,
e49829fe 25791+ .kill_sb = aufs_kill_sb,
1facf9fc 25792+ /* no need to __module_get() and module_put(). */
25793+ .owner = THIS_MODULE,
25794+};
7f207e10
AM
25795diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
25796--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 25797+++ linux/fs/aufs/super.h 2014-04-24 22:11:10.858602483 +0200
523b37e3 25798@@ -0,0 +1,571 @@
1facf9fc 25799+/*
523b37e3 25800+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25801+ *
25802+ * This program, aufs is free software; you can redistribute it and/or modify
25803+ * it under the terms of the GNU General Public License as published by
25804+ * the Free Software Foundation; either version 2 of the License, or
25805+ * (at your option) any later version.
dece6358
AM
25806+ *
25807+ * This program is distributed in the hope that it will be useful,
25808+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25809+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25810+ * GNU General Public License for more details.
25811+ *
25812+ * You should have received a copy of the GNU General Public License
523b37e3 25813+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25814+ */
25815+
25816+/*
25817+ * super_block operations
25818+ */
25819+
25820+#ifndef __AUFS_SUPER_H__
25821+#define __AUFS_SUPER_H__
25822+
25823+#ifdef __KERNEL__
25824+
25825+#include <linux/fs.h>
1facf9fc 25826+#include "rwsem.h"
25827+#include "spl.h"
25828+#include "wkq.h"
25829+
25830+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
25831+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
25832+ loff_t *);
25833+
25834+/* policies to select one among multiple writable branches */
25835+struct au_wbr_copyup_operations {
25836+ int (*copyup)(struct dentry *dentry);
25837+};
25838+
392086de
AM
25839+#define AuWbr_DIR 1 /* target is a dir */
25840+#define AuWbr_PARENT (1 << 1) /* always require a parent */
25841+
25842+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
25843+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
25844+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
25845+
1facf9fc 25846+struct au_wbr_create_operations {
392086de 25847+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 25848+ int (*init)(struct super_block *sb);
25849+ int (*fin)(struct super_block *sb);
25850+};
25851+
25852+struct au_wbr_mfs {
25853+ struct mutex mfs_lock; /* protect this structure */
25854+ unsigned long mfs_jiffy;
25855+ unsigned long mfs_expire;
25856+ aufs_bindex_t mfs_bindex;
25857+
25858+ unsigned long long mfsrr_bytes;
25859+ unsigned long long mfsrr_watermark;
25860+};
25861+
86dc4139
AM
25862+struct pseudo_link {
25863+ union {
25864+ struct hlist_node hlist;
25865+ struct rcu_head rcu;
25866+ };
25867+ struct inode *inode;
25868+};
25869+
25870+#define AuPlink_NHASH 100
25871+static inline int au_plink_hash(ino_t ino)
25872+{
25873+ return ino % AuPlink_NHASH;
25874+}
25875+
1facf9fc 25876+struct au_branch;
25877+struct au_sbinfo {
25878+ /* nowait tasks in the system-wide workqueue */
25879+ struct au_nowait_tasks si_nowait;
25880+
b752ccd1
AM
25881+ /*
25882+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
25883+ * rwsem for au_sbinfo is necessary.
25884+ */
dece6358 25885+ struct au_rwsem si_rwsem;
1facf9fc 25886+
b752ccd1
AM
25887+ /* prevent recursive locking in deleting inode */
25888+ struct {
25889+ unsigned long *bitmap;
25890+ spinlock_t tree_lock;
25891+ struct radix_tree_root tree;
25892+ } au_si_pid;
25893+
7f207e10 25894+ /*
523b37e3
AM
25895+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
25896+ * remount.
7f207e10
AM
25897+ */
25898+ atomic_long_t si_ninodes, si_nfiles;
25899+
1facf9fc 25900+ /* branch management */
25901+ unsigned int si_generation;
25902+
25903+ /* see above flags */
25904+ unsigned char au_si_status;
25905+
25906+ aufs_bindex_t si_bend;
7f207e10
AM
25907+
25908+ /* dirty trick to keep br_id plus */
25909+ unsigned int si_last_br_id :
25910+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 25911+ struct au_branch **si_branch;
25912+
25913+ /* policy to select a writable branch */
25914+ unsigned char si_wbr_copyup;
25915+ unsigned char si_wbr_create;
25916+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
25917+ struct au_wbr_create_operations *si_wbr_create_ops;
25918+
25919+ /* round robin */
25920+ atomic_t si_wbr_rr_next;
25921+
25922+ /* most free space */
25923+ struct au_wbr_mfs si_wbr_mfs;
25924+
25925+ /* mount flags */
25926+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
25927+ unsigned int si_mntflags;
25928+
25929+ /* external inode number (bitmap and translation table) */
25930+ au_readf_t si_xread;
25931+ au_writef_t si_xwrite;
25932+ struct file *si_xib;
25933+ struct mutex si_xib_mtx; /* protect xib members */
25934+ unsigned long *si_xib_buf;
25935+ unsigned long si_xib_last_pindex;
25936+ int si_xib_next_bit;
25937+ aufs_bindex_t si_xino_brid;
392086de
AM
25938+ unsigned long si_xino_jiffy;
25939+ unsigned long si_xino_expire;
1facf9fc 25940+ /* reserved for future use */
25941+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
25942+
25943+#ifdef CONFIG_AUFS_EXPORT
25944+ /* i_generation */
25945+ struct file *si_xigen;
25946+ atomic_t si_xigen_next;
25947+#endif
25948+
25949+ /* vdir parameters */
e49829fe 25950+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 25951+ unsigned int si_rdblk; /* deblk size */
25952+ unsigned int si_rdhash; /* hash size */
25953+
25954+ /*
25955+ * If the number of whiteouts are larger than si_dirwh, leave all of
25956+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
25957+ * future fsck.aufs or kernel thread will remove them later.
25958+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
25959+ */
25960+ unsigned int si_dirwh;
25961+
25962+ /*
25963+ * rename(2) a directory with all children.
25964+ */
25965+ /* reserved for future use */
25966+ /* int si_rendir; */
25967+
25968+ /* pseudo_link list */
86dc4139 25969+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 25970+ wait_queue_head_t si_plink_wq;
4a4d8108 25971+ spinlock_t si_plink_maint_lock;
e49829fe 25972+ pid_t si_plink_maint_pid;
1facf9fc 25973+
523b37e3
AM
25974+ /* file list */
25975+ struct au_sphlhead si_files;
25976+
1facf9fc 25977+ /*
25978+ * sysfs and lifetime management.
25979+ * this is not a small structure and it may be a waste of memory in case
25980+ * of sysfs is disabled, particulary when many aufs-es are mounted.
25981+ * but using sysfs is majority.
25982+ */
25983+ struct kobject si_kobj;
25984+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
25985+ struct dentry *si_dbgaufs;
25986+ struct dentry *si_dbgaufs_plink;
25987+ struct dentry *si_dbgaufs_xib;
1facf9fc 25988+#ifdef CONFIG_AUFS_EXPORT
25989+ struct dentry *si_dbgaufs_xigen;
25990+#endif
25991+#endif
25992+
e49829fe
JR
25993+#ifdef CONFIG_AUFS_SBILIST
25994+ struct list_head si_list;
25995+#endif
25996+
1facf9fc 25997+ /* dirty, necessary for unmounting, sysfs and sysrq */
25998+ struct super_block *si_sb;
25999+};
26000+
dece6358
AM
26001+/* sbinfo status flags */
26002+/*
26003+ * set true when refresh_dirs() failed at remount time.
26004+ * then try refreshing dirs at access time again.
26005+ * if it is false, refreshing dirs at access time is unnecesary
26006+ */
027c5e7a 26007+#define AuSi_FAILED_REFRESH_DIR 1
dece6358
AM
26008+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
26009+ unsigned int flag)
26010+{
26011+ AuRwMustAnyLock(&sbi->si_rwsem);
26012+ return sbi->au_si_status & flag;
26013+}
26014+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
26015+#define au_fset_si(sbinfo, name) do { \
26016+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
26017+ (sbinfo)->au_si_status |= AuSi_##name; \
26018+} while (0)
26019+#define au_fclr_si(sbinfo, name) do { \
26020+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
26021+ (sbinfo)->au_si_status &= ~AuSi_##name; \
26022+} while (0)
26023+
1facf9fc 26024+/* ---------------------------------------------------------------------- */
26025+
26026+/* policy to select one among writable branches */
4a4d8108
AM
26027+#define AuWbrCopyup(sbinfo, ...) \
26028+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
26029+#define AuWbrCreate(sbinfo, ...) \
26030+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 26031+
26032+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
26033+#define AuLock_DW 1 /* write-lock dentry */
26034+#define AuLock_IR (1 << 1) /* read-lock inode */
26035+#define AuLock_IW (1 << 2) /* write-lock inode */
26036+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
26037+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
26038+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
26039+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 26040+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 26041+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
26042+#define au_fset_lock(flags, name) \
26043+ do { (flags) |= AuLock_##name; } while (0)
26044+#define au_fclr_lock(flags, name) \
26045+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 26046+
26047+/* ---------------------------------------------------------------------- */
26048+
26049+/* super.c */
26050+extern struct file_system_type aufs_fs_type;
26051+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
7f207e10
AM
26052+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
26053+ void *arg);
26054+void au_array_free(void *array);
26055+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
26056+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
26057+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 26058+
26059+/* sbinfo.c */
26060+void au_si_free(struct kobject *kobj);
26061+int au_si_alloc(struct super_block *sb);
26062+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
26063+
26064+unsigned int au_sigen_inc(struct super_block *sb);
26065+aufs_bindex_t au_new_br_id(struct super_block *sb);
26066+
e49829fe
JR
26067+int si_read_lock(struct super_block *sb, int flags);
26068+int si_write_lock(struct super_block *sb, int flags);
26069+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 26070+void aufs_read_unlock(struct dentry *dentry, int flags);
26071+void aufs_write_lock(struct dentry *dentry);
26072+void aufs_write_unlock(struct dentry *dentry);
e49829fe 26073+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 26074+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
26075+
b752ccd1
AM
26076+int si_pid_test_slow(struct super_block *sb);
26077+void si_pid_set_slow(struct super_block *sb);
26078+void si_pid_clr_slow(struct super_block *sb);
26079+
1facf9fc 26080+/* wbr_policy.c */
26081+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
26082+extern struct au_wbr_create_operations au_wbr_create_ops[];
26083+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2
AM
26084+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
26085+
26086+/* mvdown.c */
26087+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 26088+
26089+/* ---------------------------------------------------------------------- */
26090+
26091+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
26092+{
26093+ return sb->s_fs_info;
26094+}
26095+
26096+/* ---------------------------------------------------------------------- */
26097+
26098+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 26099+int au_test_nfsd(void);
1facf9fc 26100+void au_export_init(struct super_block *sb);
b752ccd1 26101+void au_xigen_inc(struct inode *inode);
1facf9fc 26102+int au_xigen_new(struct inode *inode);
26103+int au_xigen_set(struct super_block *sb, struct file *base);
26104+void au_xigen_clr(struct super_block *sb);
26105+
26106+static inline int au_busy_or_stale(void)
26107+{
b752ccd1 26108+ if (!au_test_nfsd())
1facf9fc 26109+ return -EBUSY;
26110+ return -ESTALE;
26111+}
26112+#else
b752ccd1 26113+AuStubInt0(au_test_nfsd, void)
a2a7ad62 26114+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 26115+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
26116+AuStubInt0(au_xigen_new, struct inode *inode)
26117+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
26118+AuStubVoid(au_xigen_clr, struct super_block *sb)
1facf9fc 26119+static inline int au_busy_or_stale(void)
26120+{
26121+ return -EBUSY;
26122+}
26123+#endif /* CONFIG_AUFS_EXPORT */
26124+
26125+/* ---------------------------------------------------------------------- */
26126+
e49829fe
JR
26127+#ifdef CONFIG_AUFS_SBILIST
26128+/* module.c */
26129+extern struct au_splhead au_sbilist;
26130+
26131+static inline void au_sbilist_init(void)
26132+{
26133+ au_spl_init(&au_sbilist);
26134+}
26135+
26136+static inline void au_sbilist_add(struct super_block *sb)
26137+{
26138+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
26139+}
26140+
26141+static inline void au_sbilist_del(struct super_block *sb)
26142+{
26143+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
26144+}
53392da6
AM
26145+
26146+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
26147+static inline void au_sbilist_lock(void)
26148+{
26149+ spin_lock(&au_sbilist.spin);
26150+}
26151+
26152+static inline void au_sbilist_unlock(void)
26153+{
26154+ spin_unlock(&au_sbilist.spin);
26155+}
26156+#define AuGFP_SBILIST GFP_ATOMIC
26157+#else
26158+AuStubVoid(au_sbilist_lock, void)
26159+AuStubVoid(au_sbilist_unlock, void)
26160+#define AuGFP_SBILIST GFP_NOFS
26161+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
26162+#else
26163+AuStubVoid(au_sbilist_init, void)
26164+AuStubVoid(au_sbilist_add, struct super_block*)
26165+AuStubVoid(au_sbilist_del, struct super_block*)
53392da6
AM
26166+AuStubVoid(au_sbilist_lock, void)
26167+AuStubVoid(au_sbilist_unlock, void)
26168+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
26169+#endif
26170+
26171+/* ---------------------------------------------------------------------- */
26172+
1facf9fc 26173+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
26174+{
dece6358
AM
26175+ /*
26176+ * This function is a dynamic '__init' fucntion actually,
26177+ * so the tiny check for si_rwsem is unnecessary.
26178+ */
26179+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 26180+#ifdef CONFIG_DEBUG_FS
26181+ sbinfo->si_dbgaufs = NULL;
86dc4139 26182+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 26183+ sbinfo->si_dbgaufs_xib = NULL;
26184+#ifdef CONFIG_AUFS_EXPORT
26185+ sbinfo->si_dbgaufs_xigen = NULL;
26186+#endif
26187+#endif
26188+}
26189+
26190+/* ---------------------------------------------------------------------- */
26191+
b752ccd1
AM
26192+static inline pid_t si_pid_bit(void)
26193+{
26194+ /* the origin of pid is 1, but the bitmap's is 0 */
26195+ return current->pid - 1;
26196+}
26197+
26198+static inline int si_pid_test(struct super_block *sb)
26199+{
26200+ pid_t bit = si_pid_bit();
26201+ if (bit < PID_MAX_DEFAULT)
26202+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
26203+ else
26204+ return si_pid_test_slow(sb);
26205+}
26206+
26207+static inline void si_pid_set(struct super_block *sb)
26208+{
26209+ pid_t bit = si_pid_bit();
26210+ if (bit < PID_MAX_DEFAULT) {
26211+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
26212+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
26213+ /* smp_mb(); */
26214+ } else
26215+ si_pid_set_slow(sb);
26216+}
26217+
26218+static inline void si_pid_clr(struct super_block *sb)
26219+{
26220+ pid_t bit = si_pid_bit();
26221+ if (bit < PID_MAX_DEFAULT) {
26222+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
26223+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
26224+ /* smp_mb(); */
26225+ } else
26226+ si_pid_clr_slow(sb);
26227+}
26228+
26229+/* ---------------------------------------------------------------------- */
26230+
1facf9fc 26231+/* lock superblock. mainly for entry point functions */
26232+/*
b752ccd1
AM
26233+ * __si_read_lock, __si_write_lock,
26234+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 26235+ */
b752ccd1 26236+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 26237+
dece6358
AM
26238+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
26239+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
26240+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
26241+
b752ccd1
AM
26242+static inline void si_noflush_read_lock(struct super_block *sb)
26243+{
26244+ __si_read_lock(sb);
26245+ si_pid_set(sb);
26246+}
26247+
26248+static inline int si_noflush_read_trylock(struct super_block *sb)
26249+{
26250+ int locked = __si_read_trylock(sb);
26251+ if (locked)
26252+ si_pid_set(sb);
26253+ return locked;
26254+}
26255+
26256+static inline void si_noflush_write_lock(struct super_block *sb)
26257+{
26258+ __si_write_lock(sb);
26259+ si_pid_set(sb);
26260+}
26261+
26262+static inline int si_noflush_write_trylock(struct super_block *sb)
26263+{
26264+ int locked = __si_write_trylock(sb);
26265+ if (locked)
26266+ si_pid_set(sb);
26267+ return locked;
26268+}
26269+
e49829fe 26270+#if 0 /* unused */
1facf9fc 26271+static inline int si_read_trylock(struct super_block *sb, int flags)
26272+{
26273+ if (au_ftest_lock(flags, FLUSH))
26274+ au_nwt_flush(&au_sbi(sb)->si_nowait);
26275+ return si_noflush_read_trylock(sb);
26276+}
e49829fe 26277+#endif
1facf9fc 26278+
b752ccd1
AM
26279+static inline void si_read_unlock(struct super_block *sb)
26280+{
26281+ si_pid_clr(sb);
26282+ __si_read_unlock(sb);
26283+}
26284+
b752ccd1 26285+#if 0 /* unused */
1facf9fc 26286+static inline int si_write_trylock(struct super_block *sb, int flags)
26287+{
26288+ if (au_ftest_lock(flags, FLUSH))
26289+ au_nwt_flush(&au_sbi(sb)->si_nowait);
26290+ return si_noflush_write_trylock(sb);
26291+}
b752ccd1
AM
26292+#endif
26293+
26294+static inline void si_write_unlock(struct super_block *sb)
26295+{
26296+ si_pid_clr(sb);
26297+ __si_write_unlock(sb);
26298+}
26299+
26300+#if 0 /* unused */
26301+static inline void si_downgrade_lock(struct super_block *sb)
26302+{
26303+ __si_downgrade_lock(sb);
26304+}
26305+#endif
1facf9fc 26306+
26307+/* ---------------------------------------------------------------------- */
26308+
26309+static inline aufs_bindex_t au_sbend(struct super_block *sb)
26310+{
dece6358 26311+ SiMustAnyLock(sb);
1facf9fc 26312+ return au_sbi(sb)->si_bend;
26313+}
26314+
26315+static inline unsigned int au_mntflags(struct super_block *sb)
26316+{
dece6358 26317+ SiMustAnyLock(sb);
1facf9fc 26318+ return au_sbi(sb)->si_mntflags;
26319+}
26320+
26321+static inline unsigned int au_sigen(struct super_block *sb)
26322+{
dece6358 26323+ SiMustAnyLock(sb);
1facf9fc 26324+ return au_sbi(sb)->si_generation;
26325+}
26326+
7f207e10
AM
26327+static inline void au_ninodes_inc(struct super_block *sb)
26328+{
26329+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
26330+}
26331+
26332+static inline void au_ninodes_dec(struct super_block *sb)
26333+{
26334+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
26335+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
26336+}
26337+
26338+static inline void au_nfiles_inc(struct super_block *sb)
26339+{
26340+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
26341+}
26342+
26343+static inline void au_nfiles_dec(struct super_block *sb)
26344+{
26345+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
26346+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
26347+}
26348+
1facf9fc 26349+static inline struct au_branch *au_sbr(struct super_block *sb,
26350+ aufs_bindex_t bindex)
26351+{
dece6358 26352+ SiMustAnyLock(sb);
1facf9fc 26353+ return au_sbi(sb)->si_branch[0 + bindex];
26354+}
26355+
26356+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
26357+{
dece6358 26358+ SiMustWriteLock(sb);
1facf9fc 26359+ au_sbi(sb)->si_xino_brid = brid;
26360+}
26361+
26362+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
26363+{
dece6358 26364+ SiMustAnyLock(sb);
1facf9fc 26365+ return au_sbi(sb)->si_xino_brid;
26366+}
26367+
26368+#endif /* __KERNEL__ */
26369+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
26370diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
26371--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 26372+++ linux/fs/aufs/sysaufs.c 2014-04-24 22:11:10.858602483 +0200
523b37e3 26373@@ -0,0 +1,104 @@
1facf9fc 26374+/*
523b37e3 26375+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26376+ *
26377+ * This program, aufs is free software; you can redistribute it and/or modify
26378+ * it under the terms of the GNU General Public License as published by
26379+ * the Free Software Foundation; either version 2 of the License, or
26380+ * (at your option) any later version.
dece6358
AM
26381+ *
26382+ * This program is distributed in the hope that it will be useful,
26383+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26384+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26385+ * GNU General Public License for more details.
26386+ *
26387+ * You should have received a copy of the GNU General Public License
523b37e3 26388+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26389+ */
26390+
26391+/*
26392+ * sysfs interface and lifetime management
26393+ * they are necessary regardless sysfs is disabled.
26394+ */
26395+
1facf9fc 26396+#include <linux/random.h>
1facf9fc 26397+#include "aufs.h"
26398+
26399+unsigned long sysaufs_si_mask;
e49829fe 26400+struct kset *sysaufs_kset;
1facf9fc 26401+
26402+#define AuSiAttr(_name) { \
26403+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
26404+ .show = sysaufs_si_##_name, \
26405+}
26406+
26407+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
26408+struct attribute *sysaufs_si_attrs[] = {
26409+ &sysaufs_si_attr_xi_path.attr,
26410+ NULL,
26411+};
26412+
4a4d8108 26413+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 26414+ .show = sysaufs_si_show
26415+};
26416+
26417+static struct kobj_type au_sbi_ktype = {
26418+ .release = au_si_free,
26419+ .sysfs_ops = &au_sbi_ops,
26420+ .default_attrs = sysaufs_si_attrs
26421+};
26422+
26423+/* ---------------------------------------------------------------------- */
26424+
26425+int sysaufs_si_init(struct au_sbinfo *sbinfo)
26426+{
26427+ int err;
26428+
e49829fe 26429+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 26430+ /* cf. sysaufs_name() */
26431+ err = kobject_init_and_add
e49829fe 26432+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 26433+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
26434+
26435+ dbgaufs_si_null(sbinfo);
26436+ if (!err) {
26437+ err = dbgaufs_si_init(sbinfo);
26438+ if (unlikely(err))
26439+ kobject_put(&sbinfo->si_kobj);
26440+ }
26441+ return err;
26442+}
26443+
26444+void sysaufs_fin(void)
26445+{
26446+ dbgaufs_fin();
e49829fe
JR
26447+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
26448+ kset_unregister(sysaufs_kset);
1facf9fc 26449+}
26450+
26451+int __init sysaufs_init(void)
26452+{
26453+ int err;
26454+
26455+ do {
26456+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
26457+ } while (!sysaufs_si_mask);
26458+
4a4d8108 26459+ err = -EINVAL;
e49829fe
JR
26460+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
26461+ if (unlikely(!sysaufs_kset))
4a4d8108 26462+ goto out;
e49829fe
JR
26463+ err = PTR_ERR(sysaufs_kset);
26464+ if (IS_ERR(sysaufs_kset))
1facf9fc 26465+ goto out;
e49829fe 26466+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 26467+ if (unlikely(err)) {
e49829fe 26468+ kset_unregister(sysaufs_kset);
1facf9fc 26469+ goto out;
26470+ }
26471+
26472+ err = dbgaufs_init();
26473+ if (unlikely(err))
26474+ sysaufs_fin();
4f0767ce 26475+out:
1facf9fc 26476+ return err;
26477+}
7f207e10
AM
26478diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
26479--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 26480+++ linux/fs/aufs/sysaufs.h 2014-04-24 22:11:10.858602483 +0200
523b37e3 26481@@ -0,0 +1,103 @@
1facf9fc 26482+/*
523b37e3 26483+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26484+ *
26485+ * This program, aufs is free software; you can redistribute it and/or modify
26486+ * it under the terms of the GNU General Public License as published by
26487+ * the Free Software Foundation; either version 2 of the License, or
26488+ * (at your option) any later version.
dece6358
AM
26489+ *
26490+ * This program is distributed in the hope that it will be useful,
26491+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26492+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26493+ * GNU General Public License for more details.
26494+ *
26495+ * You should have received a copy of the GNU General Public License
523b37e3 26496+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26497+ */
26498+
26499+/*
26500+ * sysfs interface and mount lifetime management
26501+ */
26502+
26503+#ifndef __SYSAUFS_H__
26504+#define __SYSAUFS_H__
26505+
26506+#ifdef __KERNEL__
26507+
1facf9fc 26508+#include <linux/sysfs.h>
1facf9fc 26509+#include "module.h"
26510+
dece6358
AM
26511+struct super_block;
26512+struct au_sbinfo;
26513+
1facf9fc 26514+struct sysaufs_si_attr {
26515+ struct attribute attr;
26516+ int (*show)(struct seq_file *seq, struct super_block *sb);
26517+};
26518+
26519+/* ---------------------------------------------------------------------- */
26520+
26521+/* sysaufs.c */
26522+extern unsigned long sysaufs_si_mask;
e49829fe 26523+extern struct kset *sysaufs_kset;
1facf9fc 26524+extern struct attribute *sysaufs_si_attrs[];
26525+int sysaufs_si_init(struct au_sbinfo *sbinfo);
26526+int __init sysaufs_init(void);
26527+void sysaufs_fin(void);
26528+
26529+/* ---------------------------------------------------------------------- */
26530+
26531+/* some people doesn't like to show a pointer in kernel */
26532+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
26533+{
26534+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
26535+}
26536+
26537+#define SysaufsSiNamePrefix "si_"
26538+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
26539+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
26540+{
26541+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
26542+ sysaufs_si_id(sbinfo));
26543+}
26544+
26545+struct au_branch;
26546+#ifdef CONFIG_SYSFS
26547+/* sysfs.c */
26548+extern struct attribute_group *sysaufs_attr_group;
26549+
26550+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
26551+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
26552+ char *buf);
26553+
26554+void sysaufs_br_init(struct au_branch *br);
26555+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
26556+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
26557+
26558+#define sysaufs_brs_init() do {} while (0)
26559+
26560+#else
26561+#define sysaufs_attr_group NULL
26562+
4a4d8108 26563+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
1facf9fc 26564+
26565+static inline
26566+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
26567+ char *buf)
26568+{
26569+ return 0;
26570+}
26571+
4a4d8108
AM
26572+AuStubVoid(sysaufs_br_init, struct au_branch *br)
26573+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
26574+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 26575+
26576+static inline void sysaufs_brs_init(void)
26577+{
26578+ sysaufs_brs = 0;
26579+}
26580+
26581+#endif /* CONFIG_SYSFS */
26582+
26583+#endif /* __KERNEL__ */
26584+#endif /* __SYSAUFS_H__ */
7f207e10
AM
26585diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
26586--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 26587+++ linux/fs/aufs/sysfs.c 2014-04-24 22:11:10.858602483 +0200
523b37e3 26588@@ -0,0 +1,296 @@
1facf9fc 26589+/*
523b37e3 26590+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26591+ *
26592+ * This program, aufs is free software; you can redistribute it and/or modify
26593+ * it under the terms of the GNU General Public License as published by
26594+ * the Free Software Foundation; either version 2 of the License, or
26595+ * (at your option) any later version.
dece6358
AM
26596+ *
26597+ * This program is distributed in the hope that it will be useful,
26598+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26599+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26600+ * GNU General Public License for more details.
26601+ *
26602+ * You should have received a copy of the GNU General Public License
523b37e3 26603+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26604+ */
26605+
26606+/*
26607+ * sysfs interface
26608+ */
26609+
1facf9fc 26610+#include <linux/seq_file.h>
1facf9fc 26611+#include "aufs.h"
26612+
4a4d8108
AM
26613+#ifdef CONFIG_AUFS_FS_MODULE
26614+/* this entry violates the "one line per file" policy of sysfs */
26615+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
26616+ char *buf)
26617+{
26618+ ssize_t err;
26619+ static char *conf =
26620+/* this file is generated at compiling */
26621+#include "conf.str"
26622+ ;
26623+
26624+ err = snprintf(buf, PAGE_SIZE, conf);
26625+ if (unlikely(err >= PAGE_SIZE))
26626+ err = -EFBIG;
26627+ return err;
26628+}
26629+
26630+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
26631+#endif
26632+
1facf9fc 26633+static struct attribute *au_attr[] = {
4a4d8108
AM
26634+#ifdef CONFIG_AUFS_FS_MODULE
26635+ &au_config_attr.attr,
26636+#endif
1facf9fc 26637+ NULL, /* need to NULL terminate the list of attributes */
26638+};
26639+
26640+static struct attribute_group sysaufs_attr_group_body = {
26641+ .attrs = au_attr
26642+};
26643+
26644+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
26645+
26646+/* ---------------------------------------------------------------------- */
26647+
26648+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
26649+{
26650+ int err;
26651+
dece6358
AM
26652+ SiMustAnyLock(sb);
26653+
1facf9fc 26654+ err = 0;
26655+ if (au_opt_test(au_mntflags(sb), XINO)) {
26656+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
26657+ seq_putc(seq, '\n');
26658+ }
26659+ return err;
26660+}
26661+
26662+/*
26663+ * the lifetime of branch is independent from the entry under sysfs.
26664+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
26665+ * unlinked.
26666+ */
26667+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 26668+ aufs_bindex_t bindex, int idx)
1facf9fc 26669+{
1e00d052 26670+ int err;
1facf9fc 26671+ struct path path;
26672+ struct dentry *root;
26673+ struct au_branch *br;
1e00d052 26674+ char *perm;
1facf9fc 26675+
26676+ AuDbg("b%d\n", bindex);
26677+
1e00d052 26678+ err = 0;
1facf9fc 26679+ root = sb->s_root;
26680+ di_read_lock_parent(root, !AuLock_IR);
26681+ br = au_sbr(sb, bindex);
392086de
AM
26682+
26683+ switch (idx) {
26684+ case AuBrSysfs_BR:
26685+ path.mnt = au_br_mnt(br);
26686+ path.dentry = au_h_dptr(root, bindex);
26687+ au_seq_path(seq, &path);
26688+ di_read_unlock(root, !AuLock_IR);
26689+ perm = au_optstr_br_perm(br->br_perm);
26690+ if (perm) {
26691+ err = seq_printf(seq, "=%s\n", perm);
26692+ kfree(perm);
26693+ if (err == -1)
26694+ err = -E2BIG;
26695+ } else
26696+ err = -ENOMEM;
26697+ break;
26698+ case AuBrSysfs_BRID:
26699+ err = seq_printf(seq, "%d\n", br->br_id);
26700+ di_read_unlock(root, !AuLock_IR);
1e00d052
AM
26701+ if (err == -1)
26702+ err = -E2BIG;
392086de
AM
26703+ break;
26704+ }
26705+
1e00d052 26706+ return err;
1facf9fc 26707+}
26708+
26709+/* ---------------------------------------------------------------------- */
26710+
26711+static struct seq_file *au_seq(char *p, ssize_t len)
26712+{
26713+ struct seq_file *seq;
26714+
26715+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
26716+ if (seq) {
26717+ /* mutex_init(&seq.lock); */
26718+ seq->buf = p;
26719+ seq->size = len;
26720+ return seq; /* success */
26721+ }
26722+
26723+ seq = ERR_PTR(-ENOMEM);
26724+ return seq;
26725+}
26726+
392086de
AM
26727+#define SysaufsBr_PREFIX "br"
26728+#define SysaufsBrid_PREFIX "brid"
1facf9fc 26729+
26730+/* todo: file size may exceed PAGE_SIZE */
26731+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 26732+ char *buf)
1facf9fc 26733+{
26734+ ssize_t err;
392086de 26735+ int idx;
1facf9fc 26736+ long l;
26737+ aufs_bindex_t bend;
26738+ struct au_sbinfo *sbinfo;
26739+ struct super_block *sb;
26740+ struct seq_file *seq;
26741+ char *name;
26742+ struct attribute **cattr;
26743+
26744+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
26745+ sb = sbinfo->si_sb;
1308ab2a 26746+
26747+ /*
26748+ * prevent a race condition between sysfs and aufs.
26749+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
26750+ * prohibits maintaining the sysfs entries.
26751+ * hew we acquire read lock after sysfs_get_active_two().
26752+ * on the other hand, the remount process may maintain the sysfs/aufs
26753+ * entries after acquiring write lock.
26754+ * it can cause a deadlock.
26755+ * simply we gave up processing read here.
26756+ */
26757+ err = -EBUSY;
26758+ if (unlikely(!si_noflush_read_trylock(sb)))
26759+ goto out;
1facf9fc 26760+
26761+ seq = au_seq(buf, PAGE_SIZE);
26762+ err = PTR_ERR(seq);
26763+ if (IS_ERR(seq))
1308ab2a 26764+ goto out_unlock;
1facf9fc 26765+
26766+ name = (void *)attr->name;
26767+ cattr = sysaufs_si_attrs;
26768+ while (*cattr) {
26769+ if (!strcmp(name, (*cattr)->name)) {
26770+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
26771+ ->show(seq, sb);
26772+ goto out_seq;
26773+ }
26774+ cattr++;
26775+ }
26776+
392086de
AM
26777+ if (!strncmp(name, SysaufsBrid_PREFIX,
26778+ sizeof(SysaufsBrid_PREFIX) - 1)) {
26779+ idx = AuBrSysfs_BRID;
26780+ name += sizeof(SysaufsBrid_PREFIX) - 1;
26781+ } else if (!strncmp(name, SysaufsBr_PREFIX,
26782+ sizeof(SysaufsBr_PREFIX) - 1)) {
26783+ idx = AuBrSysfs_BR;
1facf9fc 26784+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
26785+ } else
26786+ BUG();
26787+
26788+ err = kstrtol(name, 10, &l);
26789+ if (!err) {
26790+ bend = au_sbend(sb);
26791+ if (l <= bend)
26792+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
26793+ else
26794+ err = -ENOENT;
1facf9fc 26795+ }
1facf9fc 26796+
4f0767ce 26797+out_seq:
1facf9fc 26798+ if (!err) {
26799+ err = seq->count;
26800+ /* sysfs limit */
26801+ if (unlikely(err == PAGE_SIZE))
26802+ err = -EFBIG;
26803+ }
26804+ kfree(seq);
4f0767ce 26805+out_unlock:
1facf9fc 26806+ si_read_unlock(sb);
4f0767ce 26807+out:
1facf9fc 26808+ return err;
26809+}
26810+
26811+/* ---------------------------------------------------------------------- */
26812+
26813+void sysaufs_br_init(struct au_branch *br)
26814+{
392086de
AM
26815+ int i;
26816+ struct au_brsysfs *br_sysfs;
26817+ struct attribute *attr;
4a4d8108 26818+
392086de
AM
26819+ br_sysfs = br->br_sysfs;
26820+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26821+ attr = &br_sysfs->attr;
26822+ sysfs_attr_init(attr);
26823+ attr->name = br_sysfs->name;
26824+ attr->mode = S_IRUGO;
26825+ br_sysfs++;
26826+ }
1facf9fc 26827+}
26828+
26829+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
26830+{
26831+ struct au_branch *br;
26832+ struct kobject *kobj;
392086de
AM
26833+ struct au_brsysfs *br_sysfs;
26834+ int i;
1facf9fc 26835+ aufs_bindex_t bend;
26836+
26837+ dbgaufs_brs_del(sb, bindex);
26838+
26839+ if (!sysaufs_brs)
26840+ return;
26841+
26842+ kobj = &au_sbi(sb)->si_kobj;
26843+ bend = au_sbend(sb);
26844+ for (; bindex <= bend; bindex++) {
26845+ br = au_sbr(sb, bindex);
392086de
AM
26846+ br_sysfs = br->br_sysfs;
26847+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26848+ sysfs_remove_file(kobj, &br_sysfs->attr);
26849+ br_sysfs++;
26850+ }
1facf9fc 26851+ }
26852+}
26853+
26854+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
26855+{
392086de 26856+ int err, i;
1facf9fc 26857+ aufs_bindex_t bend;
26858+ struct kobject *kobj;
26859+ struct au_branch *br;
392086de 26860+ struct au_brsysfs *br_sysfs;
1facf9fc 26861+
26862+ dbgaufs_brs_add(sb, bindex);
26863+
26864+ if (!sysaufs_brs)
26865+ return;
26866+
26867+ kobj = &au_sbi(sb)->si_kobj;
26868+ bend = au_sbend(sb);
26869+ for (; bindex <= bend; bindex++) {
26870+ br = au_sbr(sb, bindex);
392086de
AM
26871+ br_sysfs = br->br_sysfs;
26872+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
26873+ SysaufsBr_PREFIX "%d", bindex);
26874+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
26875+ SysaufsBrid_PREFIX "%d", bindex);
26876+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
26877+ err = sysfs_create_file(kobj, &br_sysfs->attr);
26878+ if (unlikely(err))
26879+ pr_warn("failed %s under sysfs(%d)\n",
26880+ br_sysfs->name, err);
26881+ br_sysfs++;
26882+ }
1facf9fc 26883+ }
26884+}
7f207e10
AM
26885diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
26886--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 26887+++ linux/fs/aufs/sysrq.c 2014-04-24 22:11:10.858602483 +0200
523b37e3 26888@@ -0,0 +1,154 @@
1facf9fc 26889+/*
523b37e3 26890+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26891+ *
26892+ * This program, aufs is free software; you can redistribute it and/or modify
26893+ * it under the terms of the GNU General Public License as published by
26894+ * the Free Software Foundation; either version 2 of the License, or
26895+ * (at your option) any later version.
dece6358
AM
26896+ *
26897+ * This program is distributed in the hope that it will be useful,
26898+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26899+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26900+ * GNU General Public License for more details.
26901+ *
26902+ * You should have received a copy of the GNU General Public License
523b37e3 26903+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26904+ */
26905+
26906+/*
26907+ * magic sysrq hanlder
26908+ */
26909+
1facf9fc 26910+/* #include <linux/sysrq.h> */
027c5e7a 26911+#include <linux/writeback.h>
1facf9fc 26912+#include "aufs.h"
26913+
26914+/* ---------------------------------------------------------------------- */
26915+
26916+static void sysrq_sb(struct super_block *sb)
26917+{
26918+ char *plevel;
26919+ struct au_sbinfo *sbinfo;
26920+ struct file *file;
523b37e3
AM
26921+ struct au_sphlhead *files;
26922+ struct au_finfo *finfo;
1facf9fc 26923+
26924+ plevel = au_plevel;
26925+ au_plevel = KERN_WARNING;
1facf9fc 26926+
4a4d8108 26927+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
26928+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
26929+
26930+ sbinfo = au_sbi(sb);
4a4d8108 26931+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 26932+ pr("superblock\n");
1facf9fc 26933+ au_dpri_sb(sb);
027c5e7a
AM
26934+
26935+#if 0
c06a8ce3 26936+ pr("root dentry\n");
1facf9fc 26937+ au_dpri_dentry(sb->s_root);
c06a8ce3 26938+ pr("root inode\n");
1facf9fc 26939+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
26940+#endif
26941+
1facf9fc 26942+#if 0
027c5e7a
AM
26943+ do {
26944+ int err, i, j, ndentry;
26945+ struct au_dcsub_pages dpages;
26946+ struct au_dpage *dpage;
26947+
26948+ err = au_dpages_init(&dpages, GFP_ATOMIC);
26949+ if (unlikely(err))
26950+ break;
26951+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
26952+ if (!err)
26953+ for (i = 0; i < dpages.ndpage; i++) {
26954+ dpage = dpages.dpages + i;
26955+ ndentry = dpage->ndentry;
26956+ for (j = 0; j < ndentry; j++)
26957+ au_dpri_dentry(dpage->dentries[j]);
26958+ }
26959+ au_dpages_free(&dpages);
26960+ } while (0);
26961+#endif
26962+
26963+#if 1
26964+ {
26965+ struct inode *i;
c06a8ce3 26966+ pr("isolated inode\n");
2cbb1c4b
JR
26967+ spin_lock(&inode_sb_list_lock);
26968+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
26969+ spin_lock(&i->i_lock);
b4510431 26970+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 26971+ au_dpri_inode(i);
2cbb1c4b
JR
26972+ spin_unlock(&i->i_lock);
26973+ }
26974+ spin_unlock(&inode_sb_list_lock);
027c5e7a 26975+ }
1facf9fc 26976+#endif
c06a8ce3 26977+ pr("files\n");
523b37e3
AM
26978+ files = &au_sbi(sb)->si_files;
26979+ spin_lock(&files->spin);
26980+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
4a4d8108 26981+ umode_t mode;
523b37e3 26982+ file = finfo->fi_file;
c06a8ce3 26983+ mode = file_inode(file)->i_mode;
4a4d8108 26984+ if (!special_file(mode) || au_special_file(mode))
1facf9fc 26985+ au_dpri_file(file);
523b37e3
AM
26986+ }
26987+ spin_unlock(&files->spin);
c06a8ce3 26988+ pr("done\n");
1facf9fc 26989+
c06a8ce3 26990+#undef pr
1facf9fc 26991+ au_plevel = plevel;
1facf9fc 26992+}
26993+
26994+/* ---------------------------------------------------------------------- */
26995+
26996+/* module parameter */
26997+static char *aufs_sysrq_key = "a";
26998+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
26999+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
27000+
0c5527e5 27001+static void au_sysrq(int key __maybe_unused)
1facf9fc 27002+{
1facf9fc 27003+ struct au_sbinfo *sbinfo;
27004+
027c5e7a 27005+ lockdep_off();
53392da6 27006+ au_sbilist_lock();
e49829fe 27007+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 27008+ sysrq_sb(sbinfo->si_sb);
53392da6 27009+ au_sbilist_unlock();
027c5e7a 27010+ lockdep_on();
1facf9fc 27011+}
27012+
27013+static struct sysrq_key_op au_sysrq_op = {
27014+ .handler = au_sysrq,
27015+ .help_msg = "Aufs",
27016+ .action_msg = "Aufs",
27017+ .enable_mask = SYSRQ_ENABLE_DUMP
27018+};
27019+
27020+/* ---------------------------------------------------------------------- */
27021+
27022+int __init au_sysrq_init(void)
27023+{
27024+ int err;
27025+ char key;
27026+
27027+ err = -1;
27028+ key = *aufs_sysrq_key;
27029+ if ('a' <= key && key <= 'z')
27030+ err = register_sysrq_key(key, &au_sysrq_op);
27031+ if (unlikely(err))
4a4d8108 27032+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 27033+ return err;
27034+}
27035+
27036+void au_sysrq_fin(void)
27037+{
27038+ int err;
27039+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
27040+ if (unlikely(err))
4a4d8108 27041+ pr_err("err %d (ignored)\n", err);
1facf9fc 27042+}
7f207e10
AM
27043diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
27044--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 27045+++ linux/fs/aufs/vdir.c 2014-04-24 22:11:10.858602483 +0200
523b37e3 27046@@ -0,0 +1,887 @@
1facf9fc 27047+/*
523b37e3 27048+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 27049+ *
27050+ * This program, aufs is free software; you can redistribute it and/or modify
27051+ * it under the terms of the GNU General Public License as published by
27052+ * the Free Software Foundation; either version 2 of the License, or
27053+ * (at your option) any later version.
dece6358
AM
27054+ *
27055+ * This program is distributed in the hope that it will be useful,
27056+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27057+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27058+ * GNU General Public License for more details.
27059+ *
27060+ * You should have received a copy of the GNU General Public License
523b37e3 27061+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27062+ */
27063+
27064+/*
27065+ * virtual or vertical directory
27066+ */
27067+
27068+#include "aufs.h"
27069+
dece6358 27070+static unsigned int calc_size(int nlen)
1facf9fc 27071+{
dece6358 27072+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 27073+}
27074+
27075+static int set_deblk_end(union au_vdir_deblk_p *p,
27076+ union au_vdir_deblk_p *deblk_end)
27077+{
27078+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
27079+ p->de->de_str.len = 0;
27080+ /* smp_mb(); */
27081+ return 0;
27082+ }
27083+ return -1; /* error */
27084+}
27085+
27086+/* returns true or false */
27087+static int is_deblk_end(union au_vdir_deblk_p *p,
27088+ union au_vdir_deblk_p *deblk_end)
27089+{
27090+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
27091+ return !p->de->de_str.len;
27092+ return 1;
27093+}
27094+
27095+static unsigned char *last_deblk(struct au_vdir *vdir)
27096+{
27097+ return vdir->vd_deblk[vdir->vd_nblk - 1];
27098+}
27099+
27100+/* ---------------------------------------------------------------------- */
27101+
1308ab2a 27102+/* estimate the apropriate size for name hash table */
27103+unsigned int au_rdhash_est(loff_t sz)
27104+{
27105+ unsigned int n;
27106+
27107+ n = UINT_MAX;
27108+ sz >>= 10;
27109+ if (sz < n)
27110+ n = sz;
27111+ if (sz < AUFS_RDHASH_DEF)
27112+ n = AUFS_RDHASH_DEF;
4a4d8108 27113+ /* pr_info("n %u\n", n); */
1308ab2a 27114+ return n;
27115+}
27116+
1facf9fc 27117+/*
27118+ * the allocated memory has to be freed by
dece6358 27119+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 27120+ */
dece6358 27121+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 27122+{
1facf9fc 27123+ struct hlist_head *head;
dece6358 27124+ unsigned int u;
1facf9fc 27125+
dece6358
AM
27126+ head = kmalloc(sizeof(*nhash->nh_head) * num_hash, gfp);
27127+ if (head) {
27128+ nhash->nh_num = num_hash;
27129+ nhash->nh_head = head;
27130+ for (u = 0; u < num_hash; u++)
1facf9fc 27131+ INIT_HLIST_HEAD(head++);
dece6358 27132+ return 0; /* success */
1facf9fc 27133+ }
1facf9fc 27134+
dece6358 27135+ return -ENOMEM;
1facf9fc 27136+}
27137+
dece6358
AM
27138+static void nhash_count(struct hlist_head *head)
27139+{
27140+#if 0
27141+ unsigned long n;
27142+ struct hlist_node *pos;
27143+
27144+ n = 0;
27145+ hlist_for_each(pos, head)
27146+ n++;
4a4d8108 27147+ pr_info("%lu\n", n);
dece6358
AM
27148+#endif
27149+}
27150+
27151+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 27152+{
c06a8ce3
AM
27153+ struct au_vdir_wh *pos;
27154+ struct hlist_node *node;
1facf9fc 27155+
c06a8ce3
AM
27156+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
27157+ kfree(pos);
1facf9fc 27158+}
27159+
dece6358 27160+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 27161+{
c06a8ce3
AM
27162+ struct au_vdir_dehstr *pos;
27163+ struct hlist_node *node;
1facf9fc 27164+
c06a8ce3
AM
27165+ hlist_for_each_entry_safe(pos, node, head, hash)
27166+ au_cache_free_vdir_dehstr(pos);
1facf9fc 27167+}
27168+
dece6358
AM
27169+static void au_nhash_do_free(struct au_nhash *nhash,
27170+ void (*free)(struct hlist_head *head))
1facf9fc 27171+{
1308ab2a 27172+ unsigned int n;
1facf9fc 27173+ struct hlist_head *head;
1facf9fc 27174+
dece6358 27175+ n = nhash->nh_num;
1308ab2a 27176+ if (!n)
27177+ return;
27178+
dece6358 27179+ head = nhash->nh_head;
1308ab2a 27180+ while (n-- > 0) {
dece6358
AM
27181+ nhash_count(head);
27182+ free(head++);
1facf9fc 27183+ }
dece6358 27184+ kfree(nhash->nh_head);
1facf9fc 27185+}
27186+
dece6358 27187+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 27188+{
dece6358
AM
27189+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
27190+}
1facf9fc 27191+
dece6358
AM
27192+static void au_nhash_de_free(struct au_nhash *delist)
27193+{
27194+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 27195+}
27196+
27197+/* ---------------------------------------------------------------------- */
27198+
27199+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
27200+ int limit)
27201+{
27202+ int num;
27203+ unsigned int u, n;
27204+ struct hlist_head *head;
c06a8ce3 27205+ struct au_vdir_wh *pos;
1facf9fc 27206+
27207+ num = 0;
27208+ n = whlist->nh_num;
27209+ head = whlist->nh_head;
1308ab2a 27210+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
27211+ hlist_for_each_entry(pos, head, wh_hash)
27212+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 27213+ return 1;
1facf9fc 27214+ return 0;
27215+}
27216+
27217+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 27218+ unsigned char *name,
1facf9fc 27219+ unsigned int len)
27220+{
dece6358
AM
27221+ unsigned int v;
27222+ /* const unsigned int magic_bit = 12; */
27223+
1308ab2a 27224+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
27225+
dece6358
AM
27226+ v = 0;
27227+ while (len--)
27228+ v += *name++;
27229+ /* v = hash_long(v, magic_bit); */
27230+ v %= nhash->nh_num;
27231+ return nhash->nh_head + v;
27232+}
27233+
27234+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
27235+ int nlen)
27236+{
27237+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 27238+}
27239+
27240+/* returns found or not */
dece6358 27241+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 27242+{
27243+ struct hlist_head *head;
c06a8ce3 27244+ struct au_vdir_wh *pos;
1facf9fc 27245+ struct au_vdir_destr *str;
27246+
dece6358 27247+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
27248+ hlist_for_each_entry(pos, head, wh_hash) {
27249+ str = &pos->wh_str;
1facf9fc 27250+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
27251+ if (au_nhash_test_name(str, name, nlen))
27252+ return 1;
27253+ }
27254+ return 0;
27255+}
27256+
27257+/* returns found(true) or not */
27258+static int test_known(struct au_nhash *delist, char *name, int nlen)
27259+{
27260+ struct hlist_head *head;
c06a8ce3 27261+ struct au_vdir_dehstr *pos;
dece6358
AM
27262+ struct au_vdir_destr *str;
27263+
27264+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
27265+ hlist_for_each_entry(pos, head, hash) {
27266+ str = pos->str;
dece6358
AM
27267+ AuDbg("%.*s\n", str->len, str->name);
27268+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 27269+ return 1;
27270+ }
27271+ return 0;
27272+}
27273+
dece6358
AM
27274+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
27275+ unsigned char d_type)
27276+{
27277+#ifdef CONFIG_AUFS_SHWH
27278+ wh->wh_ino = ino;
27279+ wh->wh_type = d_type;
27280+#endif
27281+}
27282+
27283+/* ---------------------------------------------------------------------- */
27284+
27285+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
27286+ unsigned int d_type, aufs_bindex_t bindex,
27287+ unsigned char shwh)
1facf9fc 27288+{
27289+ int err;
27290+ struct au_vdir_destr *str;
27291+ struct au_vdir_wh *wh;
27292+
dece6358 27293+ AuDbg("%.*s\n", nlen, name);
1308ab2a 27294+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
27295+
1facf9fc 27296+ err = -ENOMEM;
dece6358 27297+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 27298+ if (unlikely(!wh))
27299+ goto out;
27300+
27301+ err = 0;
27302+ wh->wh_bindex = bindex;
dece6358
AM
27303+ if (shwh)
27304+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 27305+ str = &wh->wh_str;
dece6358
AM
27306+ str->len = nlen;
27307+ memcpy(str->name, name, nlen);
27308+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 27309+ /* smp_mb(); */
27310+
4f0767ce 27311+out:
1facf9fc 27312+ return err;
27313+}
27314+
1facf9fc 27315+static int append_deblk(struct au_vdir *vdir)
27316+{
27317+ int err;
dece6358 27318+ unsigned long ul;
1facf9fc 27319+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
27320+ union au_vdir_deblk_p p, deblk_end;
27321+ unsigned char **o;
27322+
27323+ err = -ENOMEM;
dece6358
AM
27324+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
27325+ GFP_NOFS);
1facf9fc 27326+ if (unlikely(!o))
27327+ goto out;
27328+
27329+ vdir->vd_deblk = o;
27330+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
27331+ if (p.deblk) {
27332+ ul = vdir->vd_nblk++;
27333+ vdir->vd_deblk[ul] = p.deblk;
27334+ vdir->vd_last.ul = ul;
27335+ vdir->vd_last.p.deblk = p.deblk;
27336+ deblk_end.deblk = p.deblk + deblk_sz;
27337+ err = set_deblk_end(&p, &deblk_end);
27338+ }
27339+
4f0767ce 27340+out:
1facf9fc 27341+ return err;
27342+}
27343+
dece6358
AM
27344+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
27345+ unsigned int d_type, struct au_nhash *delist)
27346+{
27347+ int err;
27348+ unsigned int sz;
27349+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
27350+ union au_vdir_deblk_p p, *room, deblk_end;
27351+ struct au_vdir_dehstr *dehstr;
27352+
27353+ p.deblk = last_deblk(vdir);
27354+ deblk_end.deblk = p.deblk + deblk_sz;
27355+ room = &vdir->vd_last.p;
27356+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
27357+ || !is_deblk_end(room, &deblk_end));
27358+
27359+ sz = calc_size(nlen);
27360+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
27361+ err = append_deblk(vdir);
27362+ if (unlikely(err))
27363+ goto out;
27364+
27365+ p.deblk = last_deblk(vdir);
27366+ deblk_end.deblk = p.deblk + deblk_sz;
27367+ /* smp_mb(); */
27368+ AuDebugOn(room->deblk != p.deblk);
27369+ }
27370+
27371+ err = -ENOMEM;
4a4d8108 27372+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
27373+ if (unlikely(!dehstr))
27374+ goto out;
27375+
27376+ dehstr->str = &room->de->de_str;
27377+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
27378+ room->de->de_ino = ino;
27379+ room->de->de_type = d_type;
27380+ room->de->de_str.len = nlen;
27381+ memcpy(room->de->de_str.name, name, nlen);
27382+
27383+ err = 0;
27384+ room->deblk += sz;
27385+ if (unlikely(set_deblk_end(room, &deblk_end)))
27386+ err = append_deblk(vdir);
27387+ /* smp_mb(); */
27388+
4f0767ce 27389+out:
dece6358
AM
27390+ return err;
27391+}
27392+
27393+/* ---------------------------------------------------------------------- */
27394+
27395+void au_vdir_free(struct au_vdir *vdir)
27396+{
27397+ unsigned char **deblk;
27398+
27399+ deblk = vdir->vd_deblk;
27400+ while (vdir->vd_nblk--)
27401+ kfree(*deblk++);
27402+ kfree(vdir->vd_deblk);
27403+ au_cache_free_vdir(vdir);
27404+}
27405+
1308ab2a 27406+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 27407+{
27408+ struct au_vdir *vdir;
1308ab2a 27409+ struct super_block *sb;
1facf9fc 27410+ int err;
27411+
1308ab2a 27412+ sb = file->f_dentry->d_sb;
dece6358
AM
27413+ SiMustAnyLock(sb);
27414+
1facf9fc 27415+ err = -ENOMEM;
27416+ vdir = au_cache_alloc_vdir();
27417+ if (unlikely(!vdir))
27418+ goto out;
27419+
27420+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
27421+ if (unlikely(!vdir->vd_deblk))
27422+ goto out_free;
27423+
27424+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 27425+ if (!vdir->vd_deblk_sz) {
27426+ /* estimate the apropriate size for deblk */
27427+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 27428+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 27429+ }
1facf9fc 27430+ vdir->vd_nblk = 0;
27431+ vdir->vd_version = 0;
27432+ vdir->vd_jiffy = 0;
27433+ err = append_deblk(vdir);
27434+ if (!err)
27435+ return vdir; /* success */
27436+
27437+ kfree(vdir->vd_deblk);
27438+
4f0767ce 27439+out_free:
1facf9fc 27440+ au_cache_free_vdir(vdir);
4f0767ce 27441+out:
1facf9fc 27442+ vdir = ERR_PTR(err);
27443+ return vdir;
27444+}
27445+
27446+static int reinit_vdir(struct au_vdir *vdir)
27447+{
27448+ int err;
27449+ union au_vdir_deblk_p p, deblk_end;
27450+
27451+ while (vdir->vd_nblk > 1) {
27452+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
27453+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
27454+ vdir->vd_nblk--;
27455+ }
27456+ p.deblk = vdir->vd_deblk[0];
27457+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
27458+ err = set_deblk_end(&p, &deblk_end);
27459+ /* keep vd_dblk_sz */
27460+ vdir->vd_last.ul = 0;
27461+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
27462+ vdir->vd_version = 0;
27463+ vdir->vd_jiffy = 0;
27464+ /* smp_mb(); */
27465+ return err;
27466+}
27467+
27468+/* ---------------------------------------------------------------------- */
27469+
1facf9fc 27470+#define AuFillVdir_CALLED 1
27471+#define AuFillVdir_WHABLE (1 << 1)
dece6358 27472+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 27473+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
27474+#define au_fset_fillvdir(flags, name) \
27475+ do { (flags) |= AuFillVdir_##name; } while (0)
27476+#define au_fclr_fillvdir(flags, name) \
27477+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 27478+
dece6358
AM
27479+#ifndef CONFIG_AUFS_SHWH
27480+#undef AuFillVdir_SHWH
27481+#define AuFillVdir_SHWH 0
27482+#endif
27483+
1facf9fc 27484+struct fillvdir_arg {
392086de 27485+ struct dir_context ctx;
1facf9fc 27486+ struct file *file;
27487+ struct au_vdir *vdir;
dece6358
AM
27488+ struct au_nhash delist;
27489+ struct au_nhash whlist;
1facf9fc 27490+ aufs_bindex_t bindex;
27491+ unsigned int flags;
27492+ int err;
27493+};
27494+
392086de 27495+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 27496+ loff_t offset __maybe_unused, u64 h_ino,
27497+ unsigned int d_type)
27498+{
392086de 27499+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 27500+ char *name = (void *)__name;
27501+ struct super_block *sb;
1facf9fc 27502+ ino_t ino;
dece6358 27503+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 27504+
1facf9fc 27505+ arg->err = 0;
dece6358 27506+ sb = arg->file->f_dentry->d_sb;
1facf9fc 27507+ au_fset_fillvdir(arg->flags, CALLED);
27508+ /* smp_mb(); */
dece6358 27509+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 27510+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
27511+ if (test_known(&arg->delist, name, nlen)
27512+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
27513+ goto out; /* already exists or whiteouted */
1facf9fc 27514+
27515+ sb = arg->file->f_dentry->d_sb;
dece6358 27516+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
27517+ if (!arg->err) {
27518+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
27519+ d_type = DT_UNKNOWN;
dece6358
AM
27520+ arg->err = append_de(arg->vdir, name, nlen, ino,
27521+ d_type, &arg->delist);
4a4d8108 27522+ }
1facf9fc 27523+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
27524+ name += AUFS_WH_PFX_LEN;
dece6358
AM
27525+ nlen -= AUFS_WH_PFX_LEN;
27526+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
27527+ goto out; /* already whiteouted */
1facf9fc 27528+
dece6358
AM
27529+ if (shwh)
27530+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
27531+ &ino);
4a4d8108
AM
27532+ if (!arg->err) {
27533+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
27534+ d_type = DT_UNKNOWN;
1facf9fc 27535+ arg->err = au_nhash_append_wh
dece6358
AM
27536+ (&arg->whlist, name, nlen, ino, d_type,
27537+ arg->bindex, shwh);
4a4d8108 27538+ }
1facf9fc 27539+ }
27540+
4f0767ce 27541+out:
1facf9fc 27542+ if (!arg->err)
27543+ arg->vdir->vd_jiffy = jiffies;
27544+ /* smp_mb(); */
27545+ AuTraceErr(arg->err);
27546+ return arg->err;
27547+}
27548+
dece6358
AM
27549+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
27550+ struct au_nhash *whlist, struct au_nhash *delist)
27551+{
27552+#ifdef CONFIG_AUFS_SHWH
27553+ int err;
27554+ unsigned int nh, u;
27555+ struct hlist_head *head;
c06a8ce3
AM
27556+ struct au_vdir_wh *pos;
27557+ struct hlist_node *n;
dece6358
AM
27558+ char *p, *o;
27559+ struct au_vdir_destr *destr;
27560+
27561+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
27562+
27563+ err = -ENOMEM;
537831f9 27564+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
27565+ if (unlikely(!p))
27566+ goto out;
27567+
27568+ err = 0;
27569+ nh = whlist->nh_num;
27570+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
27571+ p += AUFS_WH_PFX_LEN;
27572+ for (u = 0; u < nh; u++) {
27573+ head = whlist->nh_head + u;
c06a8ce3
AM
27574+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
27575+ destr = &pos->wh_str;
dece6358
AM
27576+ memcpy(p, destr->name, destr->len);
27577+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 27578+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
27579+ if (unlikely(err))
27580+ break;
27581+ }
27582+ }
27583+
537831f9 27584+ free_page((unsigned long)o);
dece6358 27585+
4f0767ce 27586+out:
dece6358
AM
27587+ AuTraceErr(err);
27588+ return err;
27589+#else
27590+ return 0;
27591+#endif
27592+}
27593+
1facf9fc 27594+static int au_do_read_vdir(struct fillvdir_arg *arg)
27595+{
27596+ int err;
dece6358 27597+ unsigned int rdhash;
1facf9fc 27598+ loff_t offset;
dece6358
AM
27599+ aufs_bindex_t bend, bindex, bstart;
27600+ unsigned char shwh;
1facf9fc 27601+ struct file *hf, *file;
27602+ struct super_block *sb;
27603+
1facf9fc 27604+ file = arg->file;
27605+ sb = file->f_dentry->d_sb;
dece6358
AM
27606+ SiMustAnyLock(sb);
27607+
27608+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 27609+ if (!rdhash)
27610+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
27611+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
27612+ if (unlikely(err))
1facf9fc 27613+ goto out;
dece6358
AM
27614+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
27615+ if (unlikely(err))
1facf9fc 27616+ goto out_delist;
27617+
27618+ err = 0;
27619+ arg->flags = 0;
dece6358
AM
27620+ shwh = 0;
27621+ if (au_opt_test(au_mntflags(sb), SHWH)) {
27622+ shwh = 1;
27623+ au_fset_fillvdir(arg->flags, SHWH);
27624+ }
27625+ bstart = au_fbstart(file);
4a4d8108 27626+ bend = au_fbend_dir(file);
dece6358 27627+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 27628+ hf = au_hf_dir(file, bindex);
1facf9fc 27629+ if (!hf)
27630+ continue;
27631+
27632+ offset = vfsub_llseek(hf, 0, SEEK_SET);
27633+ err = offset;
27634+ if (unlikely(offset))
27635+ break;
27636+
27637+ arg->bindex = bindex;
27638+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
27639+ if (shwh
27640+ || (bindex != bend
27641+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 27642+ au_fset_fillvdir(arg->flags, WHABLE);
27643+ do {
27644+ arg->err = 0;
27645+ au_fclr_fillvdir(arg->flags, CALLED);
27646+ /* smp_mb(); */
392086de 27647+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 27648+ if (err >= 0)
27649+ err = arg->err;
27650+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
27651+
27652+ /*
27653+ * dir_relax() may be good for concurrency, but aufs should not
27654+ * use it since it will cause a lockdep problem.
27655+ */
1facf9fc 27656+ }
dece6358
AM
27657+
27658+ if (!err && shwh)
27659+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
27660+
27661+ au_nhash_wh_free(&arg->whlist);
1facf9fc 27662+
4f0767ce 27663+out_delist:
dece6358 27664+ au_nhash_de_free(&arg->delist);
4f0767ce 27665+out:
1facf9fc 27666+ return err;
27667+}
27668+
27669+static int read_vdir(struct file *file, int may_read)
27670+{
27671+ int err;
27672+ unsigned long expire;
27673+ unsigned char do_read;
392086de
AM
27674+ struct fillvdir_arg arg = {
27675+ .ctx = {
27676+ .actor = au_diractor(fillvdir)
27677+ }
27678+ };
1facf9fc 27679+ struct inode *inode;
27680+ struct au_vdir *vdir, *allocated;
27681+
27682+ err = 0;
c06a8ce3 27683+ inode = file_inode(file);
1facf9fc 27684+ IMustLock(inode);
dece6358
AM
27685+ SiMustAnyLock(inode->i_sb);
27686+
1facf9fc 27687+ allocated = NULL;
27688+ do_read = 0;
27689+ expire = au_sbi(inode->i_sb)->si_rdcache;
27690+ vdir = au_ivdir(inode);
27691+ if (!vdir) {
27692+ do_read = 1;
1308ab2a 27693+ vdir = alloc_vdir(file);
1facf9fc 27694+ err = PTR_ERR(vdir);
27695+ if (IS_ERR(vdir))
27696+ goto out;
27697+ err = 0;
27698+ allocated = vdir;
27699+ } else if (may_read
27700+ && (inode->i_version != vdir->vd_version
27701+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
27702+ do_read = 1;
27703+ err = reinit_vdir(vdir);
27704+ if (unlikely(err))
27705+ goto out;
27706+ }
27707+
27708+ if (!do_read)
27709+ return 0; /* success */
27710+
27711+ arg.file = file;
27712+ arg.vdir = vdir;
27713+ err = au_do_read_vdir(&arg);
27714+ if (!err) {
392086de 27715+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 27716+ vdir->vd_version = inode->i_version;
27717+ vdir->vd_last.ul = 0;
27718+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
27719+ if (allocated)
27720+ au_set_ivdir(inode, allocated);
27721+ } else if (allocated)
27722+ au_vdir_free(allocated);
27723+
4f0767ce 27724+out:
1facf9fc 27725+ return err;
27726+}
27727+
27728+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
27729+{
27730+ int err, rerr;
27731+ unsigned long ul, n;
27732+ const unsigned int deblk_sz = src->vd_deblk_sz;
27733+
27734+ AuDebugOn(tgt->vd_nblk != 1);
27735+
27736+ err = -ENOMEM;
27737+ if (tgt->vd_nblk < src->vd_nblk) {
27738+ unsigned char **p;
27739+
dece6358
AM
27740+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
27741+ GFP_NOFS);
1facf9fc 27742+ if (unlikely(!p))
27743+ goto out;
27744+ tgt->vd_deblk = p;
27745+ }
27746+
1308ab2a 27747+ if (tgt->vd_deblk_sz != deblk_sz) {
27748+ unsigned char *p;
27749+
27750+ tgt->vd_deblk_sz = deblk_sz;
27751+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
27752+ if (unlikely(!p))
27753+ goto out;
27754+ tgt->vd_deblk[0] = p;
27755+ }
1facf9fc 27756+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 27757+ tgt->vd_version = src->vd_version;
27758+ tgt->vd_jiffy = src->vd_jiffy;
27759+
27760+ n = src->vd_nblk;
27761+ for (ul = 1; ul < n; ul++) {
dece6358
AM
27762+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
27763+ GFP_NOFS);
27764+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 27765+ goto out;
1308ab2a 27766+ tgt->vd_nblk++;
1facf9fc 27767+ }
1308ab2a 27768+ tgt->vd_nblk = n;
27769+ tgt->vd_last.ul = tgt->vd_last.ul;
27770+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
27771+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
27772+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 27773+ /* smp_mb(); */
27774+ return 0; /* success */
27775+
4f0767ce 27776+out:
1facf9fc 27777+ rerr = reinit_vdir(tgt);
27778+ BUG_ON(rerr);
27779+ return err;
27780+}
27781+
27782+int au_vdir_init(struct file *file)
27783+{
27784+ int err;
27785+ struct inode *inode;
27786+ struct au_vdir *vdir_cache, *allocated;
27787+
392086de 27788+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 27789+ err = read_vdir(file, !file->f_pos);
27790+ if (unlikely(err))
27791+ goto out;
27792+
27793+ allocated = NULL;
27794+ vdir_cache = au_fvdir_cache(file);
27795+ if (!vdir_cache) {
1308ab2a 27796+ vdir_cache = alloc_vdir(file);
1facf9fc 27797+ err = PTR_ERR(vdir_cache);
27798+ if (IS_ERR(vdir_cache))
27799+ goto out;
27800+ allocated = vdir_cache;
27801+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 27802+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 27803+ err = reinit_vdir(vdir_cache);
27804+ if (unlikely(err))
27805+ goto out;
27806+ } else
27807+ return 0; /* success */
27808+
c06a8ce3 27809+ inode = file_inode(file);
1facf9fc 27810+ err = copy_vdir(vdir_cache, au_ivdir(inode));
27811+ if (!err) {
27812+ file->f_version = inode->i_version;
27813+ if (allocated)
27814+ au_set_fvdir_cache(file, allocated);
27815+ } else if (allocated)
27816+ au_vdir_free(allocated);
27817+
4f0767ce 27818+out:
1facf9fc 27819+ return err;
27820+}
27821+
27822+static loff_t calc_offset(struct au_vdir *vdir)
27823+{
27824+ loff_t offset;
27825+ union au_vdir_deblk_p p;
27826+
27827+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
27828+ offset = vdir->vd_last.p.deblk - p.deblk;
27829+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
27830+ return offset;
27831+}
27832+
27833+/* returns true or false */
392086de 27834+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 27835+{
27836+ int valid;
27837+ unsigned int deblk_sz;
27838+ unsigned long ul, n;
27839+ loff_t offset;
27840+ union au_vdir_deblk_p p, deblk_end;
27841+ struct au_vdir *vdir_cache;
27842+
27843+ valid = 1;
27844+ vdir_cache = au_fvdir_cache(file);
27845+ offset = calc_offset(vdir_cache);
27846+ AuDbg("offset %lld\n", offset);
392086de 27847+ if (ctx->pos == offset)
1facf9fc 27848+ goto out;
27849+
27850+ vdir_cache->vd_last.ul = 0;
27851+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 27852+ if (!ctx->pos)
1facf9fc 27853+ goto out;
27854+
27855+ valid = 0;
27856+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 27857+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 27858+ AuDbg("ul %lu\n", ul);
27859+ if (ul >= vdir_cache->vd_nblk)
27860+ goto out;
27861+
27862+ n = vdir_cache->vd_nblk;
27863+ for (; ul < n; ul++) {
27864+ p.deblk = vdir_cache->vd_deblk[ul];
27865+ deblk_end.deblk = p.deblk + deblk_sz;
27866+ offset = ul;
27867+ offset *= deblk_sz;
392086de 27868+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 27869+ unsigned int l;
27870+
27871+ l = calc_size(p.de->de_str.len);
27872+ offset += l;
27873+ p.deblk += l;
27874+ }
27875+ if (!is_deblk_end(&p, &deblk_end)) {
27876+ valid = 1;
27877+ vdir_cache->vd_last.ul = ul;
27878+ vdir_cache->vd_last.p = p;
27879+ break;
27880+ }
27881+ }
27882+
4f0767ce 27883+out:
1facf9fc 27884+ /* smp_mb(); */
27885+ AuTraceErr(!valid);
27886+ return valid;
27887+}
27888+
392086de 27889+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 27890+{
1facf9fc 27891+ unsigned int l, deblk_sz;
27892+ union au_vdir_deblk_p deblk_end;
27893+ struct au_vdir *vdir_cache;
27894+ struct au_vdir_de *de;
27895+
27896+ vdir_cache = au_fvdir_cache(file);
392086de 27897+ if (!seek_vdir(file, ctx))
1facf9fc 27898+ return 0;
27899+
27900+ deblk_sz = vdir_cache->vd_deblk_sz;
27901+ while (1) {
27902+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
27903+ deblk_end.deblk += deblk_sz;
27904+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
27905+ de = vdir_cache->vd_last.p.de;
27906+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 27907+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 27908+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
27909+ if (unlikely(!dir_emit(ctx, de->de_str.name,
27910+ de->de_str.len, de->de_ino,
27911+ de->de_type))) {
1facf9fc 27912+ /* todo: ignore the error caused by udba? */
27913+ /* return err; */
27914+ return 0;
27915+ }
27916+
27917+ l = calc_size(de->de_str.len);
27918+ vdir_cache->vd_last.p.deblk += l;
392086de 27919+ ctx->pos += l;
1facf9fc 27920+ }
27921+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
27922+ vdir_cache->vd_last.ul++;
27923+ vdir_cache->vd_last.p.deblk
27924+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 27925+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 27926+ continue;
27927+ }
27928+ break;
27929+ }
27930+
27931+ /* smp_mb(); */
27932+ return 0;
27933+}
7f207e10
AM
27934diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
27935--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 27936+++ linux/fs/aufs/vfsub.c 2014-04-24 22:11:10.861935852 +0200
523b37e3 27937@@ -0,0 +1,782 @@
1facf9fc 27938+/*
523b37e3 27939+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 27940+ *
27941+ * This program, aufs is free software; you can redistribute it and/or modify
27942+ * it under the terms of the GNU General Public License as published by
27943+ * the Free Software Foundation; either version 2 of the License, or
27944+ * (at your option) any later version.
dece6358
AM
27945+ *
27946+ * This program is distributed in the hope that it will be useful,
27947+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27948+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27949+ * GNU General Public License for more details.
27950+ *
27951+ * You should have received a copy of the GNU General Public License
523b37e3 27952+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27953+ */
27954+
27955+/*
27956+ * sub-routines for VFS
27957+ */
27958+
1308ab2a 27959+#include <linux/ima.h>
dece6358
AM
27960+#include <linux/namei.h>
27961+#include <linux/security.h>
27962+#include <linux/splice.h>
1facf9fc 27963+#include "aufs.h"
27964+
27965+int vfsub_update_h_iattr(struct path *h_path, int *did)
27966+{
27967+ int err;
27968+ struct kstat st;
27969+ struct super_block *h_sb;
27970+
27971+ /* for remote fs, leave work for its getattr or d_revalidate */
27972+ /* for bad i_attr fs, handle them in aufs_getattr() */
27973+ /* still some fs may acquire i_mutex. we need to skip them */
27974+ err = 0;
27975+ if (!did)
27976+ did = &err;
27977+ h_sb = h_path->dentry->d_sb;
27978+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
27979+ if (*did)
c06a8ce3 27980+ err = vfs_getattr(h_path, &st);
1facf9fc 27981+
27982+ return err;
27983+}
27984+
27985+/* ---------------------------------------------------------------------- */
27986+
4a4d8108 27987+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 27988+{
27989+ struct file *file;
27990+
b4510431 27991+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 27992+ current_cred());
2cbb1c4b
JR
27993+ if (!IS_ERR_OR_NULL(file)
27994+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
27995+ i_readcount_inc(path->dentry->d_inode);
4a4d8108 27996+
1308ab2a 27997+ return file;
27998+}
27999+
1facf9fc 28000+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
28001+{
28002+ struct file *file;
28003+
2cbb1c4b 28004+ lockdep_off();
7f207e10 28005+ file = filp_open(path,
2cbb1c4b 28006+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 28007+ mode);
2cbb1c4b 28008+ lockdep_on();
1facf9fc 28009+ if (IS_ERR(file))
28010+ goto out;
28011+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
28012+
4f0767ce 28013+out:
1facf9fc 28014+ return file;
28015+}
28016+
28017+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
28018+{
28019+ int err;
28020+
1facf9fc 28021+ err = kern_path(name, flags, path);
1facf9fc 28022+ if (!err && path->dentry->d_inode)
28023+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
28024+ return err;
28025+}
28026+
28027+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
28028+ int len)
28029+{
28030+ struct path path = {
28031+ .mnt = NULL
28032+ };
28033+
1308ab2a 28034+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 28035+ IMustLock(parent->d_inode);
28036+
28037+ path.dentry = lookup_one_len(name, parent, len);
28038+ if (IS_ERR(path.dentry))
28039+ goto out;
28040+ if (path.dentry->d_inode)
28041+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
28042+
4f0767ce 28043+out:
4a4d8108 28044+ AuTraceErrPtr(path.dentry);
1facf9fc 28045+ return path.dentry;
28046+}
28047+
b4510431 28048+void vfsub_call_lkup_one(void *args)
2cbb1c4b 28049+{
b4510431
AM
28050+ struct vfsub_lkup_one_args *a = args;
28051+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
28052+}
28053+
1facf9fc 28054+/* ---------------------------------------------------------------------- */
28055+
28056+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
28057+ struct dentry *d2, struct au_hinode *hdir2)
28058+{
28059+ struct dentry *d;
28060+
2cbb1c4b 28061+ lockdep_off();
1facf9fc 28062+ d = lock_rename(d1, d2);
2cbb1c4b 28063+ lockdep_on();
4a4d8108 28064+ au_hn_suspend(hdir1);
1facf9fc 28065+ if (hdir1 != hdir2)
4a4d8108 28066+ au_hn_suspend(hdir2);
1facf9fc 28067+
28068+ return d;
28069+}
28070+
28071+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
28072+ struct dentry *d2, struct au_hinode *hdir2)
28073+{
4a4d8108 28074+ au_hn_resume(hdir1);
1facf9fc 28075+ if (hdir1 != hdir2)
4a4d8108 28076+ au_hn_resume(hdir2);
2cbb1c4b 28077+ lockdep_off();
1facf9fc 28078+ unlock_rename(d1, d2);
2cbb1c4b 28079+ lockdep_on();
1facf9fc 28080+}
28081+
28082+/* ---------------------------------------------------------------------- */
28083+
b4510431 28084+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 28085+{
28086+ int err;
28087+ struct dentry *d;
28088+
28089+ IMustLock(dir);
28090+
28091+ d = path->dentry;
28092+ path->dentry = d->d_parent;
b752ccd1 28093+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 28094+ path->dentry = d;
28095+ if (unlikely(err))
28096+ goto out;
28097+
b4510431 28098+ err = vfs_create(dir, path->dentry, mode, want_excl);
1facf9fc 28099+ if (!err) {
28100+ struct path tmp = *path;
28101+ int did;
28102+
28103+ vfsub_update_h_iattr(&tmp, &did);
28104+ if (did) {
28105+ tmp.dentry = path->dentry->d_parent;
28106+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
28107+ }
28108+ /*ignore*/
28109+ }
28110+
4f0767ce 28111+out:
1facf9fc 28112+ return err;
28113+}
28114+
28115+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
28116+{
28117+ int err;
28118+ struct dentry *d;
28119+
28120+ IMustLock(dir);
28121+
28122+ d = path->dentry;
28123+ path->dentry = d->d_parent;
b752ccd1 28124+ err = security_path_symlink(path, d, symname);
1facf9fc 28125+ path->dentry = d;
28126+ if (unlikely(err))
28127+ goto out;
28128+
28129+ err = vfs_symlink(dir, path->dentry, symname);
28130+ if (!err) {
28131+ struct path tmp = *path;
28132+ int did;
28133+
28134+ vfsub_update_h_iattr(&tmp, &did);
28135+ if (did) {
28136+ tmp.dentry = path->dentry->d_parent;
28137+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
28138+ }
28139+ /*ignore*/
28140+ }
28141+
4f0767ce 28142+out:
1facf9fc 28143+ return err;
28144+}
28145+
28146+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
28147+{
28148+ int err;
28149+ struct dentry *d;
28150+
28151+ IMustLock(dir);
28152+
28153+ d = path->dentry;
28154+ path->dentry = d->d_parent;
027c5e7a 28155+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 28156+ path->dentry = d;
28157+ if (unlikely(err))
28158+ goto out;
28159+
28160+ err = vfs_mknod(dir, path->dentry, mode, dev);
28161+ if (!err) {
28162+ struct path tmp = *path;
28163+ int did;
28164+
28165+ vfsub_update_h_iattr(&tmp, &did);
28166+ if (did) {
28167+ tmp.dentry = path->dentry->d_parent;
28168+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
28169+ }
28170+ /*ignore*/
28171+ }
28172+
4f0767ce 28173+out:
1facf9fc 28174+ return err;
28175+}
28176+
28177+static int au_test_nlink(struct inode *inode)
28178+{
28179+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
28180+
28181+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
28182+ || inode->i_nlink < link_max)
28183+ return 0;
28184+ return -EMLINK;
28185+}
28186+
523b37e3
AM
28187+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
28188+ struct inode **delegated_inode)
1facf9fc 28189+{
28190+ int err;
28191+ struct dentry *d;
28192+
28193+ IMustLock(dir);
28194+
28195+ err = au_test_nlink(src_dentry->d_inode);
28196+ if (unlikely(err))
28197+ return err;
28198+
b4510431 28199+ /* we don't call may_linkat() */
1facf9fc 28200+ d = path->dentry;
28201+ path->dentry = d->d_parent;
b752ccd1 28202+ err = security_path_link(src_dentry, path, d);
1facf9fc 28203+ path->dentry = d;
28204+ if (unlikely(err))
28205+ goto out;
28206+
2cbb1c4b 28207+ lockdep_off();
523b37e3 28208+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 28209+ lockdep_on();
1facf9fc 28210+ if (!err) {
28211+ struct path tmp = *path;
28212+ int did;
28213+
28214+ /* fuse has different memory inode for the same inumber */
28215+ vfsub_update_h_iattr(&tmp, &did);
28216+ if (did) {
28217+ tmp.dentry = path->dentry->d_parent;
28218+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
28219+ tmp.dentry = src_dentry;
28220+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
28221+ }
28222+ /*ignore*/
28223+ }
28224+
4f0767ce 28225+out:
1facf9fc 28226+ return err;
28227+}
28228+
28229+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3
AM
28230+ struct inode *dir, struct path *path,
28231+ struct inode **delegated_inode)
1facf9fc 28232+{
28233+ int err;
28234+ struct path tmp = {
28235+ .mnt = path->mnt
28236+ };
28237+ struct dentry *d;
28238+
28239+ IMustLock(dir);
28240+ IMustLock(src_dir);
28241+
28242+ d = path->dentry;
28243+ path->dentry = d->d_parent;
28244+ tmp.dentry = src_dentry->d_parent;
b752ccd1 28245+ err = security_path_rename(&tmp, src_dentry, path, d);
1facf9fc 28246+ path->dentry = d;
28247+ if (unlikely(err))
28248+ goto out;
28249+
2cbb1c4b 28250+ lockdep_off();
523b37e3
AM
28251+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
28252+ delegated_inode);
2cbb1c4b 28253+ lockdep_on();
1facf9fc 28254+ if (!err) {
28255+ int did;
28256+
28257+ tmp.dentry = d->d_parent;
28258+ vfsub_update_h_iattr(&tmp, &did);
28259+ if (did) {
28260+ tmp.dentry = src_dentry;
28261+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
28262+ tmp.dentry = src_dentry->d_parent;
28263+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
28264+ }
28265+ /*ignore*/
28266+ }
28267+
4f0767ce 28268+out:
1facf9fc 28269+ return err;
28270+}
28271+
28272+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
28273+{
28274+ int err;
28275+ struct dentry *d;
28276+
28277+ IMustLock(dir);
28278+
28279+ d = path->dentry;
28280+ path->dentry = d->d_parent;
b752ccd1 28281+ err = security_path_mkdir(path, d, mode);
1facf9fc 28282+ path->dentry = d;
28283+ if (unlikely(err))
28284+ goto out;
28285+
28286+ err = vfs_mkdir(dir, path->dentry, mode);
28287+ if (!err) {
28288+ struct path tmp = *path;
28289+ int did;
28290+
28291+ vfsub_update_h_iattr(&tmp, &did);
28292+ if (did) {
28293+ tmp.dentry = path->dentry->d_parent;
28294+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
28295+ }
28296+ /*ignore*/
28297+ }
28298+
4f0767ce 28299+out:
1facf9fc 28300+ return err;
28301+}
28302+
28303+int vfsub_rmdir(struct inode *dir, struct path *path)
28304+{
28305+ int err;
28306+ struct dentry *d;
28307+
28308+ IMustLock(dir);
28309+
28310+ d = path->dentry;
28311+ path->dentry = d->d_parent;
b752ccd1 28312+ err = security_path_rmdir(path, d);
1facf9fc 28313+ path->dentry = d;
28314+ if (unlikely(err))
28315+ goto out;
28316+
2cbb1c4b 28317+ lockdep_off();
1facf9fc 28318+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 28319+ lockdep_on();
1facf9fc 28320+ if (!err) {
28321+ struct path tmp = {
28322+ .dentry = path->dentry->d_parent,
28323+ .mnt = path->mnt
28324+ };
28325+
28326+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
28327+ }
28328+
4f0767ce 28329+out:
1facf9fc 28330+ return err;
28331+}
28332+
28333+/* ---------------------------------------------------------------------- */
28334+
9dbd164d 28335+/* todo: support mmap_sem? */
1facf9fc 28336+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
28337+ loff_t *ppos)
28338+{
28339+ ssize_t err;
28340+
2cbb1c4b 28341+ lockdep_off();
1facf9fc 28342+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 28343+ lockdep_on();
1facf9fc 28344+ if (err >= 0)
28345+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
28346+ return err;
28347+}
28348+
28349+/* todo: kernel_read()? */
28350+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
28351+ loff_t *ppos)
28352+{
28353+ ssize_t err;
28354+ mm_segment_t oldfs;
b752ccd1
AM
28355+ union {
28356+ void *k;
28357+ char __user *u;
28358+ } buf;
1facf9fc 28359+
b752ccd1 28360+ buf.k = kbuf;
1facf9fc 28361+ oldfs = get_fs();
28362+ set_fs(KERNEL_DS);
b752ccd1 28363+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 28364+ set_fs(oldfs);
28365+ return err;
28366+}
28367+
28368+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
28369+ loff_t *ppos)
28370+{
28371+ ssize_t err;
28372+
2cbb1c4b 28373+ lockdep_off();
1facf9fc 28374+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 28375+ lockdep_on();
1facf9fc 28376+ if (err >= 0)
28377+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
28378+ return err;
28379+}
28380+
28381+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
28382+{
28383+ ssize_t err;
28384+ mm_segment_t oldfs;
b752ccd1
AM
28385+ union {
28386+ void *k;
28387+ const char __user *u;
28388+ } buf;
1facf9fc 28389+
b752ccd1 28390+ buf.k = kbuf;
1facf9fc 28391+ oldfs = get_fs();
28392+ set_fs(KERNEL_DS);
b752ccd1 28393+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 28394+ set_fs(oldfs);
28395+ return err;
28396+}
28397+
4a4d8108
AM
28398+int vfsub_flush(struct file *file, fl_owner_t id)
28399+{
28400+ int err;
28401+
28402+ err = 0;
523b37e3 28403+ if (file->f_op->flush) {
2cbb1c4b
JR
28404+ if (!au_test_nfs(file->f_dentry->d_sb))
28405+ err = file->f_op->flush(file, id);
28406+ else {
28407+ lockdep_off();
28408+ err = file->f_op->flush(file, id);
28409+ lockdep_on();
28410+ }
4a4d8108
AM
28411+ if (!err)
28412+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
28413+ /*ignore*/
28414+ }
28415+ return err;
28416+}
28417+
392086de 28418+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 28419+{
28420+ int err;
28421+
523b37e3 28422+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 28423+
2cbb1c4b 28424+ lockdep_off();
392086de 28425+ err = iterate_dir(file, ctx);
2cbb1c4b 28426+ lockdep_on();
1facf9fc 28427+ if (err >= 0)
28428+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
28429+ return err;
28430+}
28431+
28432+long vfsub_splice_to(struct file *in, loff_t *ppos,
28433+ struct pipe_inode_info *pipe, size_t len,
28434+ unsigned int flags)
28435+{
28436+ long err;
28437+
2cbb1c4b 28438+ lockdep_off();
0fc653ad 28439+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 28440+ lockdep_on();
4a4d8108 28441+ file_accessed(in);
1facf9fc 28442+ if (err >= 0)
28443+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
28444+ return err;
28445+}
28446+
28447+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
28448+ loff_t *ppos, size_t len, unsigned int flags)
28449+{
28450+ long err;
28451+
2cbb1c4b 28452+ lockdep_off();
0fc653ad 28453+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 28454+ lockdep_on();
1facf9fc 28455+ if (err >= 0)
28456+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
28457+ return err;
28458+}
28459+
53392da6
AM
28460+int vfsub_fsync(struct file *file, struct path *path, int datasync)
28461+{
28462+ int err;
28463+
28464+ /* file can be NULL */
28465+ lockdep_off();
28466+ err = vfs_fsync(file, datasync);
28467+ lockdep_on();
28468+ if (!err) {
28469+ if (!path) {
28470+ AuDebugOn(!file);
28471+ path = &file->f_path;
28472+ }
28473+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
28474+ }
28475+ return err;
28476+}
28477+
1facf9fc 28478+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
28479+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
28480+ struct file *h_file)
28481+{
28482+ int err;
28483+ struct inode *h_inode;
c06a8ce3 28484+ struct super_block *h_sb;
1facf9fc 28485+
1facf9fc 28486+ if (!h_file) {
c06a8ce3
AM
28487+ err = vfsub_truncate(h_path, length);
28488+ goto out;
1facf9fc 28489+ }
28490+
c06a8ce3
AM
28491+ h_inode = h_path->dentry->d_inode;
28492+ h_sb = h_inode->i_sb;
28493+ lockdep_off();
28494+ sb_start_write(h_sb);
28495+ lockdep_on();
1facf9fc 28496+ err = locks_verify_truncate(h_inode, h_file, length);
28497+ if (!err)
953406b4 28498+ err = security_path_truncate(h_path);
2cbb1c4b
JR
28499+ if (!err) {
28500+ lockdep_off();
1facf9fc 28501+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
28502+ lockdep_on();
28503+ }
c06a8ce3
AM
28504+ lockdep_off();
28505+ sb_end_write(h_sb);
28506+ lockdep_on();
1facf9fc 28507+
4f0767ce 28508+out:
1facf9fc 28509+ return err;
28510+}
28511+
28512+/* ---------------------------------------------------------------------- */
28513+
28514+struct au_vfsub_mkdir_args {
28515+ int *errp;
28516+ struct inode *dir;
28517+ struct path *path;
28518+ int mode;
28519+};
28520+
28521+static void au_call_vfsub_mkdir(void *args)
28522+{
28523+ struct au_vfsub_mkdir_args *a = args;
28524+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
28525+}
28526+
28527+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
28528+{
28529+ int err, do_sio, wkq_err;
28530+
28531+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
28532+ if (!do_sio)
28533+ err = vfsub_mkdir(dir, path, mode);
28534+ else {
28535+ struct au_vfsub_mkdir_args args = {
28536+ .errp = &err,
28537+ .dir = dir,
28538+ .path = path,
28539+ .mode = mode
28540+ };
28541+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
28542+ if (unlikely(wkq_err))
28543+ err = wkq_err;
28544+ }
28545+
28546+ return err;
28547+}
28548+
28549+struct au_vfsub_rmdir_args {
28550+ int *errp;
28551+ struct inode *dir;
28552+ struct path *path;
28553+};
28554+
28555+static void au_call_vfsub_rmdir(void *args)
28556+{
28557+ struct au_vfsub_rmdir_args *a = args;
28558+ *a->errp = vfsub_rmdir(a->dir, a->path);
28559+}
28560+
28561+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
28562+{
28563+ int err, do_sio, wkq_err;
28564+
28565+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
28566+ if (!do_sio)
28567+ err = vfsub_rmdir(dir, path);
28568+ else {
28569+ struct au_vfsub_rmdir_args args = {
28570+ .errp = &err,
28571+ .dir = dir,
28572+ .path = path
28573+ };
28574+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
28575+ if (unlikely(wkq_err))
28576+ err = wkq_err;
28577+ }
28578+
28579+ return err;
28580+}
28581+
28582+/* ---------------------------------------------------------------------- */
28583+
28584+struct notify_change_args {
28585+ int *errp;
28586+ struct path *path;
28587+ struct iattr *ia;
523b37e3 28588+ struct inode **delegated_inode;
1facf9fc 28589+};
28590+
28591+static void call_notify_change(void *args)
28592+{
28593+ struct notify_change_args *a = args;
28594+ struct inode *h_inode;
28595+
28596+ h_inode = a->path->dentry->d_inode;
28597+ IMustLock(h_inode);
28598+
28599+ *a->errp = -EPERM;
28600+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
523b37e3
AM
28601+ *a->errp = notify_change(a->path->dentry, a->ia,
28602+ a->delegated_inode);
1facf9fc 28603+ if (!*a->errp)
28604+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
28605+ }
28606+ AuTraceErr(*a->errp);
28607+}
28608+
523b37e3
AM
28609+int vfsub_notify_change(struct path *path, struct iattr *ia,
28610+ struct inode **delegated_inode)
1facf9fc 28611+{
28612+ int err;
28613+ struct notify_change_args args = {
523b37e3
AM
28614+ .errp = &err,
28615+ .path = path,
28616+ .ia = ia,
28617+ .delegated_inode = delegated_inode
1facf9fc 28618+ };
28619+
28620+ call_notify_change(&args);
28621+
28622+ return err;
28623+}
28624+
523b37e3
AM
28625+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
28626+ struct inode **delegated_inode)
1facf9fc 28627+{
28628+ int err, wkq_err;
28629+ struct notify_change_args args = {
523b37e3
AM
28630+ .errp = &err,
28631+ .path = path,
28632+ .ia = ia,
28633+ .delegated_inode = delegated_inode
1facf9fc 28634+ };
28635+
28636+ wkq_err = au_wkq_wait(call_notify_change, &args);
28637+ if (unlikely(wkq_err))
28638+ err = wkq_err;
28639+
28640+ return err;
28641+}
28642+
28643+/* ---------------------------------------------------------------------- */
28644+
28645+struct unlink_args {
28646+ int *errp;
28647+ struct inode *dir;
28648+ struct path *path;
523b37e3 28649+ struct inode **delegated_inode;
1facf9fc 28650+};
28651+
28652+static void call_unlink(void *args)
28653+{
28654+ struct unlink_args *a = args;
28655+ struct dentry *d = a->path->dentry;
28656+ struct inode *h_inode;
28657+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
392086de 28658+ && d_count(d) == 1);
1facf9fc 28659+
28660+ IMustLock(a->dir);
28661+
28662+ a->path->dentry = d->d_parent;
28663+ *a->errp = security_path_unlink(a->path, d);
28664+ a->path->dentry = d;
28665+ if (unlikely(*a->errp))
28666+ return;
28667+
28668+ if (!stop_sillyrename)
28669+ dget(d);
28670+ h_inode = d->d_inode;
28671+ if (h_inode)
027c5e7a 28672+ ihold(h_inode);
1facf9fc 28673+
2cbb1c4b 28674+ lockdep_off();
523b37e3 28675+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 28676+ lockdep_on();
1facf9fc 28677+ if (!*a->errp) {
28678+ struct path tmp = {
28679+ .dentry = d->d_parent,
28680+ .mnt = a->path->mnt
28681+ };
28682+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
28683+ }
28684+
28685+ if (!stop_sillyrename)
28686+ dput(d);
28687+ if (h_inode)
28688+ iput(h_inode);
28689+
28690+ AuTraceErr(*a->errp);
28691+}
28692+
28693+/*
28694+ * @dir: must be locked.
28695+ * @dentry: target dentry.
28696+ */
523b37e3
AM
28697+int vfsub_unlink(struct inode *dir, struct path *path,
28698+ struct inode **delegated_inode, int force)
1facf9fc 28699+{
28700+ int err;
28701+ struct unlink_args args = {
523b37e3
AM
28702+ .errp = &err,
28703+ .dir = dir,
28704+ .path = path,
28705+ .delegated_inode = delegated_inode
1facf9fc 28706+ };
28707+
28708+ if (!force)
28709+ call_unlink(&args);
28710+ else {
28711+ int wkq_err;
28712+
28713+ wkq_err = au_wkq_wait(call_unlink, &args);
28714+ if (unlikely(wkq_err))
28715+ err = wkq_err;
28716+ }
28717+
28718+ return err;
28719+}
7f207e10
AM
28720diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
28721--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 28722+++ linux/fs/aufs/vfsub.h 2014-04-24 22:11:10.861935852 +0200
523b37e3 28723@@ -0,0 +1,282 @@
1facf9fc 28724+/*
523b37e3 28725+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28726+ *
28727+ * This program, aufs is free software; you can redistribute it and/or modify
28728+ * it under the terms of the GNU General Public License as published by
28729+ * the Free Software Foundation; either version 2 of the License, or
28730+ * (at your option) any later version.
dece6358
AM
28731+ *
28732+ * This program is distributed in the hope that it will be useful,
28733+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28734+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28735+ * GNU General Public License for more details.
28736+ *
28737+ * You should have received a copy of the GNU General Public License
523b37e3 28738+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28739+ */
28740+
28741+/*
28742+ * sub-routines for VFS
28743+ */
28744+
28745+#ifndef __AUFS_VFSUB_H__
28746+#define __AUFS_VFSUB_H__
28747+
28748+#ifdef __KERNEL__
28749+
28750+#include <linux/fs.h>
0c5527e5 28751+#include <linux/lglock.h>
b4510431 28752+#include <linux/mount.h>
7f207e10 28753+#include "debug.h"
1facf9fc 28754+
7f207e10 28755+/* copied from linux/fs/internal.h */
2cbb1c4b 28756+/* todo: BAD approach!! */
c06a8ce3 28757+extern void __mnt_drop_write(struct vfsmount *);
2cbb1c4b 28758+extern spinlock_t inode_sb_list_lock;
7f207e10
AM
28759+
28760+/* ---------------------------------------------------------------------- */
1facf9fc 28761+
28762+/* lock subclass for lower inode */
28763+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
28764+/* reduce? gave up. */
28765+enum {
523b37e3 28766+ AuLsc_I_Begin = I_MUTEX_NONDIR2, /* 4 */
1facf9fc 28767+ AuLsc_I_PARENT, /* lower inode, parent first */
28768+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 28769+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 28770+ AuLsc_I_CHILD,
28771+ AuLsc_I_CHILD2,
28772+ AuLsc_I_End
28773+};
28774+
28775+/* to debug easier, do not make them inlined functions */
28776+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
28777+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
28778+
28779+/* ---------------------------------------------------------------------- */
28780+
7f207e10
AM
28781+static inline void vfsub_drop_nlink(struct inode *inode)
28782+{
28783+ AuDebugOn(!inode->i_nlink);
28784+ drop_nlink(inode);
28785+}
28786+
027c5e7a
AM
28787+static inline void vfsub_dead_dir(struct inode *inode)
28788+{
28789+ AuDebugOn(!S_ISDIR(inode->i_mode));
28790+ inode->i_flags |= S_DEAD;
28791+ clear_nlink(inode);
28792+}
28793+
392086de
AM
28794+static inline int vfsub_native_ro(struct inode *inode)
28795+{
28796+ return (inode->i_sb->s_flags & MS_RDONLY)
28797+ || IS_RDONLY(inode)
28798+ /* || IS_APPEND(inode) */
28799+ || IS_IMMUTABLE(inode);
28800+}
28801+
7f207e10
AM
28802+/* ---------------------------------------------------------------------- */
28803+
28804+int vfsub_update_h_iattr(struct path *h_path, int *did);
28805+struct file *vfsub_dentry_open(struct path *path, int flags);
28806+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
1facf9fc 28807+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 28808+
1facf9fc 28809+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
28810+ int len);
b4510431
AM
28811+
28812+struct vfsub_lkup_one_args {
28813+ struct dentry **errp;
28814+ struct qstr *name;
28815+ struct dentry *parent;
28816+};
28817+
28818+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
28819+ struct dentry *parent)
28820+{
28821+ return vfsub_lookup_one_len(name->name, parent, name->len);
28822+}
28823+
28824+void vfsub_call_lkup_one(void *args);
28825+
28826+/* ---------------------------------------------------------------------- */
28827+
28828+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
28829+{
28830+ int err;
28831+ lockdep_off();
28832+ err = mnt_want_write(mnt);
28833+ lockdep_on();
28834+ return err;
28835+}
28836+
28837+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
28838+{
28839+ lockdep_off();
28840+ mnt_drop_write(mnt);
28841+ lockdep_on();
28842+}
1facf9fc 28843+
c06a8ce3
AM
28844+static inline void vfsub_mnt_drop_write_file(struct file *file)
28845+{
28846+ lockdep_off();
28847+ mnt_drop_write_file(file);
28848+ lockdep_on();
28849+}
28850+
1facf9fc 28851+/* ---------------------------------------------------------------------- */
28852+
28853+struct au_hinode;
28854+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
28855+ struct dentry *d2, struct au_hinode *hdir2);
28856+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
28857+ struct dentry *d2, struct au_hinode *hdir2);
28858+
537831f9
AM
28859+int vfsub_create(struct inode *dir, struct path *path, int mode,
28860+ bool want_excl);
1facf9fc 28861+int vfsub_symlink(struct inode *dir, struct path *path,
28862+ const char *symname);
28863+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
28864+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 28865+ struct path *path, struct inode **delegated_inode);
1facf9fc 28866+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3
AM
28867+ struct inode *hdir, struct path *path,
28868+ struct inode **delegated_inode);
1facf9fc 28869+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
28870+int vfsub_rmdir(struct inode *dir, struct path *path);
28871+
28872+/* ---------------------------------------------------------------------- */
28873+
28874+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
28875+ loff_t *ppos);
28876+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
28877+ loff_t *ppos);
28878+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
28879+ loff_t *ppos);
28880+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
28881+ loff_t *ppos);
4a4d8108 28882+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
28883+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
28884+
28885+/* just for type-check */
28886+static inline filldir_t au_diractor(int (*func)(struct dir_context *,
28887+ const char *, int, loff_t, u64,
28888+ unsigned))
28889+{
28890+ return (filldir_t)func;
28891+}
28892+
1facf9fc 28893+
c06a8ce3
AM
28894+static inline loff_t vfsub_f_size_read(struct file *file)
28895+{
28896+ return i_size_read(file_inode(file));
28897+}
28898+
4a4d8108
AM
28899+static inline unsigned int vfsub_file_flags(struct file *file)
28900+{
28901+ unsigned int flags;
28902+
28903+ spin_lock(&file->f_lock);
28904+ flags = file->f_flags;
28905+ spin_unlock(&file->f_lock);
28906+
28907+ return flags;
28908+}
1308ab2a 28909+
1facf9fc 28910+static inline void vfsub_file_accessed(struct file *h_file)
28911+{
28912+ file_accessed(h_file);
28913+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
28914+}
28915+
28916+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
28917+ struct dentry *h_dentry)
28918+{
28919+ struct path h_path = {
28920+ .dentry = h_dentry,
28921+ .mnt = h_mnt
28922+ };
92d182d2 28923+ touch_atime(&h_path);
1facf9fc 28924+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
28925+}
28926+
0c3ec466
AM
28927+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
28928+ int flags)
28929+{
28930+ return update_time(h_inode, ts, flags);
28931+ /* no vfsub_update_h_iattr() since we don't have struct path */
28932+}
28933+
4a4d8108
AM
28934+long vfsub_splice_to(struct file *in, loff_t *ppos,
28935+ struct pipe_inode_info *pipe, size_t len,
28936+ unsigned int flags);
28937+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
28938+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
28939+
28940+static inline long vfsub_truncate(struct path *path, loff_t length)
28941+{
28942+ long err;
28943+ lockdep_off();
28944+ err = vfs_truncate(path, length);
28945+ lockdep_on();
28946+ return err;
28947+}
28948+
4a4d8108
AM
28949+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
28950+ struct file *h_file);
53392da6 28951+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 28952+
1facf9fc 28953+/* ---------------------------------------------------------------------- */
28954+
28955+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
28956+{
28957+ loff_t err;
28958+
2cbb1c4b 28959+ lockdep_off();
1facf9fc 28960+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 28961+ lockdep_on();
1facf9fc 28962+ return err;
28963+}
28964+
28965+/* ---------------------------------------------------------------------- */
28966+
28967+/* dirty workaround for strict type of fmode_t */
28968+union vfsub_fmu {
28969+ fmode_t fm;
28970+ unsigned int ui;
28971+};
28972+
28973+static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
28974+{
28975+ union vfsub_fmu u = {
28976+ .fm = fm
28977+ };
28978+
28979+ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
28980+
28981+ return u.ui;
28982+}
28983+
28984+static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
28985+{
28986+ union vfsub_fmu u = {
28987+ .ui = ui
28988+ };
28989+
28990+ return u.fm;
28991+}
28992+
4a4d8108
AM
28993+/* ---------------------------------------------------------------------- */
28994+
28995+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
28996+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
28997+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
28998+ struct inode **delegated_inode);
28999+int vfsub_notify_change(struct path *path, struct iattr *ia,
29000+ struct inode **delegated_inode);
29001+int vfsub_unlink(struct inode *dir, struct path *path,
29002+ struct inode **delegated_inode, int force);
4a4d8108 29003+
1facf9fc 29004+#endif /* __KERNEL__ */
29005+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
29006diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
29007--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 29008+++ linux/fs/aufs/wbr_policy.c 2014-04-24 22:11:10.861935852 +0200
392086de 29009@@ -0,0 +1,756 @@
1facf9fc 29010+/*
523b37e3 29011+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 29012+ *
29013+ * This program, aufs is free software; you can redistribute it and/or modify
29014+ * it under the terms of the GNU General Public License as published by
29015+ * the Free Software Foundation; either version 2 of the License, or
29016+ * (at your option) any later version.
dece6358
AM
29017+ *
29018+ * This program is distributed in the hope that it will be useful,
29019+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29020+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29021+ * GNU General Public License for more details.
29022+ *
29023+ * You should have received a copy of the GNU General Public License
523b37e3 29024+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29025+ */
29026+
29027+/*
29028+ * policies for selecting one among multiple writable branches
29029+ */
29030+
29031+#include <linux/statfs.h>
29032+#include "aufs.h"
29033+
29034+/* subset of cpup_attr() */
29035+static noinline_for_stack
29036+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
29037+{
29038+ int err, sbits;
29039+ struct iattr ia;
29040+ struct inode *h_isrc;
29041+
29042+ h_isrc = h_src->d_inode;
29043+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
29044+ ia.ia_mode = h_isrc->i_mode;
29045+ ia.ia_uid = h_isrc->i_uid;
29046+ ia.ia_gid = h_isrc->i_gid;
29047+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
86dc4139 29048+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
523b37e3
AM
29049+ /* no delegation since it is just created */
29050+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 29051+
29052+ /* is this nfs only? */
29053+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
29054+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
29055+ ia.ia_mode = h_isrc->i_mode;
523b37e3 29056+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 29057+ }
29058+
29059+ return err;
29060+}
29061+
29062+#define AuCpdown_PARENT_OPQ 1
29063+#define AuCpdown_WHED (1 << 1)
29064+#define AuCpdown_MADE_DIR (1 << 2)
29065+#define AuCpdown_DIROPQ (1 << 3)
29066+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
29067+#define au_fset_cpdown(flags, name) \
29068+ do { (flags) |= AuCpdown_##name; } while (0)
29069+#define au_fclr_cpdown(flags, name) \
29070+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 29071+
1facf9fc 29072+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 29073+ unsigned int *flags)
1facf9fc 29074+{
29075+ int err;
29076+ struct dentry *opq_dentry;
29077+
29078+ opq_dentry = au_diropq_create(dentry, bdst);
29079+ err = PTR_ERR(opq_dentry);
29080+ if (IS_ERR(opq_dentry))
29081+ goto out;
29082+ dput(opq_dentry);
c2b27bf2 29083+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 29084+
4f0767ce 29085+out:
1facf9fc 29086+ return err;
29087+}
29088+
29089+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
29090+ struct inode *dir, aufs_bindex_t bdst)
29091+{
29092+ int err;
29093+ struct path h_path;
29094+ struct au_branch *br;
29095+
29096+ br = au_sbr(dentry->d_sb, bdst);
29097+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
29098+ err = PTR_ERR(h_path.dentry);
29099+ if (IS_ERR(h_path.dentry))
29100+ goto out;
29101+
29102+ err = 0;
29103+ if (h_path.dentry->d_inode) {
86dc4139 29104+ h_path.mnt = au_br_mnt(br);
1facf9fc 29105+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
29106+ dentry);
29107+ }
29108+ dput(h_path.dentry);
29109+
4f0767ce 29110+out:
1facf9fc 29111+ return err;
29112+}
29113+
29114+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 29115+ struct au_pin *pin,
1facf9fc 29116+ struct dentry *h_parent, void *arg)
29117+{
29118+ int err, rerr;
4a4d8108 29119+ aufs_bindex_t bopq, bstart;
1facf9fc 29120+ struct path h_path;
29121+ struct dentry *parent;
29122+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 29123+ unsigned int *flags = arg;
1facf9fc 29124+
29125+ bstart = au_dbstart(dentry);
29126+ /* dentry is di-locked */
29127+ parent = dget_parent(dentry);
29128+ dir = parent->d_inode;
29129+ h_dir = h_parent->d_inode;
29130+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
29131+ IMustLock(h_dir);
29132+
86dc4139 29133+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 29134+ if (unlikely(err < 0))
29135+ goto out;
29136+ h_path.dentry = au_h_dptr(dentry, bdst);
29137+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
29138+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
29139+ S_IRWXU | S_IRUGO | S_IXUGO);
29140+ if (unlikely(err))
29141+ goto out_put;
c2b27bf2 29142+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 29143+
1facf9fc 29144+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
29145+ au_fclr_cpdown(*flags, WHED);
29146+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 29147+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
29148+ au_fset_cpdown(*flags, WHED);
29149+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
29150+ au_fset_cpdown(*flags, PARENT_OPQ);
1facf9fc 29151+ h_inode = h_path.dentry->d_inode;
29152+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2
AM
29153+ if (au_ftest_cpdown(*flags, WHED)) {
29154+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 29155+ if (unlikely(err)) {
29156+ mutex_unlock(&h_inode->i_mutex);
29157+ goto out_dir;
29158+ }
29159+ }
29160+
29161+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
29162+ mutex_unlock(&h_inode->i_mutex);
29163+ if (unlikely(err))
29164+ goto out_opq;
29165+
c2b27bf2 29166+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 29167+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
29168+ if (unlikely(err))
29169+ goto out_opq;
29170+ }
29171+
29172+ inode = dentry->d_inode;
29173+ if (au_ibend(inode) < bdst)
29174+ au_set_ibend(inode, bdst);
29175+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
29176+ au_hi_flags(inode, /*isdir*/1));
29177+ goto out; /* success */
29178+
29179+ /* revert */
4f0767ce 29180+out_opq:
c2b27bf2 29181+ if (au_ftest_cpdown(*flags, DIROPQ)) {
1facf9fc 29182+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
29183+ rerr = au_diropq_remove(dentry, bdst);
29184+ mutex_unlock(&h_inode->i_mutex);
29185+ if (unlikely(rerr)) {
523b37e3
AM
29186+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
29187+ dentry, bdst, rerr);
1facf9fc 29188+ err = -EIO;
29189+ goto out;
29190+ }
29191+ }
4f0767ce 29192+out_dir:
c2b27bf2 29193+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 29194+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
29195+ if (unlikely(rerr)) {
523b37e3
AM
29196+ AuIOErr("failed removing %pd b%d (%d)\n",
29197+ dentry, bdst, rerr);
1facf9fc 29198+ err = -EIO;
29199+ }
29200+ }
4f0767ce 29201+out_put:
1facf9fc 29202+ au_set_h_dptr(dentry, bdst, NULL);
29203+ if (au_dbend(dentry) == bdst)
29204+ au_update_dbend(dentry);
4f0767ce 29205+out:
1facf9fc 29206+ dput(parent);
29207+ return err;
29208+}
29209+
29210+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
29211+{
29212+ int err;
c2b27bf2 29213+ unsigned int flags;
1facf9fc 29214+
c2b27bf2
AM
29215+ flags = 0;
29216+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 29217+
29218+ return err;
29219+}
29220+
29221+/* ---------------------------------------------------------------------- */
29222+
29223+/* policies for create */
29224+
c2b27bf2 29225+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
29226+{
29227+ int err, i, j, ndentry;
29228+ aufs_bindex_t bopq;
29229+ struct au_dcsub_pages dpages;
29230+ struct au_dpage *dpage;
29231+ struct dentry **dentries, *parent, *d;
29232+
29233+ err = au_dpages_init(&dpages, GFP_NOFS);
29234+ if (unlikely(err))
29235+ goto out;
29236+ parent = dget_parent(dentry);
027c5e7a 29237+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
29238+ if (unlikely(err))
29239+ goto out_free;
29240+
29241+ err = bindex;
29242+ for (i = 0; i < dpages.ndpage; i++) {
29243+ dpage = dpages.dpages + i;
29244+ dentries = dpage->dentries;
29245+ ndentry = dpage->ndentry;
29246+ for (j = 0; j < ndentry; j++) {
29247+ d = dentries[j];
29248+ di_read_lock_parent2(d, !AuLock_IR);
29249+ bopq = au_dbdiropq(d);
29250+ di_read_unlock(d, !AuLock_IR);
29251+ if (bopq >= 0 && bopq < err)
29252+ err = bopq;
29253+ }
29254+ }
29255+
29256+out_free:
29257+ dput(parent);
29258+ au_dpages_free(&dpages);
29259+out:
29260+ return err;
29261+}
29262+
1facf9fc 29263+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
29264+{
29265+ for (; bindex >= 0; bindex--)
29266+ if (!au_br_rdonly(au_sbr(sb, bindex)))
29267+ return bindex;
29268+ return -EROFS;
29269+}
29270+
29271+/* top down parent */
392086de
AM
29272+static int au_wbr_create_tdp(struct dentry *dentry,
29273+ unsigned int flags __maybe_unused)
1facf9fc 29274+{
29275+ int err;
29276+ aufs_bindex_t bstart, bindex;
29277+ struct super_block *sb;
29278+ struct dentry *parent, *h_parent;
29279+
29280+ sb = dentry->d_sb;
29281+ bstart = au_dbstart(dentry);
29282+ err = bstart;
29283+ if (!au_br_rdonly(au_sbr(sb, bstart)))
29284+ goto out;
29285+
29286+ err = -EROFS;
29287+ parent = dget_parent(dentry);
29288+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
29289+ h_parent = au_h_dptr(parent, bindex);
29290+ if (!h_parent || !h_parent->d_inode)
29291+ continue;
29292+
29293+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
29294+ err = bindex;
29295+ break;
29296+ }
29297+ }
29298+ dput(parent);
29299+
29300+ /* bottom up here */
4a4d8108 29301+ if (unlikely(err < 0)) {
1facf9fc 29302+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
29303+ if (err >= 0)
29304+ err = au_wbr_nonopq(dentry, err);
29305+ }
1facf9fc 29306+
4f0767ce 29307+out:
1facf9fc 29308+ AuDbg("b%d\n", err);
29309+ return err;
29310+}
29311+
29312+/* ---------------------------------------------------------------------- */
29313+
29314+/* an exception for the policy other than tdp */
29315+static int au_wbr_create_exp(struct dentry *dentry)
29316+{
29317+ int err;
29318+ aufs_bindex_t bwh, bdiropq;
29319+ struct dentry *parent;
29320+
29321+ err = -1;
29322+ bwh = au_dbwh(dentry);
29323+ parent = dget_parent(dentry);
29324+ bdiropq = au_dbdiropq(parent);
29325+ if (bwh >= 0) {
29326+ if (bdiropq >= 0)
29327+ err = min(bdiropq, bwh);
29328+ else
29329+ err = bwh;
29330+ AuDbg("%d\n", err);
29331+ } else if (bdiropq >= 0) {
29332+ err = bdiropq;
29333+ AuDbg("%d\n", err);
29334+ }
29335+ dput(parent);
29336+
4a4d8108
AM
29337+ if (err >= 0)
29338+ err = au_wbr_nonopq(dentry, err);
29339+
1facf9fc 29340+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
29341+ err = -1;
29342+
29343+ AuDbg("%d\n", err);
29344+ return err;
29345+}
29346+
29347+/* ---------------------------------------------------------------------- */
29348+
29349+/* round robin */
29350+static int au_wbr_create_init_rr(struct super_block *sb)
29351+{
29352+ int err;
29353+
29354+ err = au_wbr_bu(sb, au_sbend(sb));
29355+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 29356+ /* smp_mb(); */
1facf9fc 29357+
29358+ AuDbg("b%d\n", err);
29359+ return err;
29360+}
29361+
392086de 29362+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 29363+{
29364+ int err, nbr;
29365+ unsigned int u;
29366+ aufs_bindex_t bindex, bend;
29367+ struct super_block *sb;
29368+ atomic_t *next;
29369+
29370+ err = au_wbr_create_exp(dentry);
29371+ if (err >= 0)
29372+ goto out;
29373+
29374+ sb = dentry->d_sb;
29375+ next = &au_sbi(sb)->si_wbr_rr_next;
29376+ bend = au_sbend(sb);
29377+ nbr = bend + 1;
29378+ for (bindex = 0; bindex <= bend; bindex++) {
392086de 29379+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 29380+ err = atomic_dec_return(next) + 1;
29381+ /* modulo for 0 is meaningless */
29382+ if (unlikely(!err))
29383+ err = atomic_dec_return(next) + 1;
29384+ } else
29385+ err = atomic_read(next);
29386+ AuDbg("%d\n", err);
29387+ u = err;
29388+ err = u % nbr;
29389+ AuDbg("%d\n", err);
29390+ if (!au_br_rdonly(au_sbr(sb, err)))
29391+ break;
29392+ err = -EROFS;
29393+ }
29394+
4a4d8108
AM
29395+ if (err >= 0)
29396+ err = au_wbr_nonopq(dentry, err);
29397+
4f0767ce 29398+out:
1facf9fc 29399+ AuDbg("%d\n", err);
29400+ return err;
29401+}
29402+
29403+/* ---------------------------------------------------------------------- */
29404+
29405+/* most free space */
392086de 29406+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 29407+{
29408+ struct super_block *sb;
29409+ struct au_branch *br;
29410+ struct au_wbr_mfs *mfs;
392086de 29411+ struct dentry *h_parent;
1facf9fc 29412+ aufs_bindex_t bindex, bend;
29413+ int err;
29414+ unsigned long long b, bavail;
7f207e10 29415+ struct path h_path;
1facf9fc 29416+ /* reduce the stack usage */
29417+ struct kstatfs *st;
29418+
29419+ st = kmalloc(sizeof(*st), GFP_NOFS);
29420+ if (unlikely(!st)) {
29421+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
29422+ return;
29423+ }
29424+
29425+ bavail = 0;
29426+ sb = dentry->d_sb;
29427+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 29428+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 29429+ mfs->mfs_bindex = -EROFS;
29430+ mfs->mfsrr_bytes = 0;
392086de
AM
29431+ if (!parent) {
29432+ bindex = 0;
29433+ bend = au_sbend(sb);
29434+ } else {
29435+ bindex = au_dbstart(parent);
29436+ bend = au_dbtaildir(parent);
29437+ }
29438+
29439+ for (; bindex <= bend; bindex++) {
29440+ if (parent) {
29441+ h_parent = au_h_dptr(parent, bindex);
29442+ if (!h_parent || !h_parent->d_inode)
29443+ continue;
29444+ }
1facf9fc 29445+ br = au_sbr(sb, bindex);
29446+ if (au_br_rdonly(br))
29447+ continue;
29448+
29449+ /* sb->s_root for NFS is unreliable */
86dc4139 29450+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
29451+ h_path.dentry = h_path.mnt->mnt_root;
29452+ err = vfs_statfs(&h_path, st);
1facf9fc 29453+ if (unlikely(err)) {
29454+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
29455+ continue;
29456+ }
29457+
29458+ /* when the available size is equal, select the lower one */
29459+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
29460+ || sizeof(b) < sizeof(st->f_bsize));
29461+ b = st->f_bavail * st->f_bsize;
29462+ br->br_wbr->wbr_bytes = b;
29463+ if (b >= bavail) {
29464+ bavail = b;
29465+ mfs->mfs_bindex = bindex;
29466+ mfs->mfs_jiffy = jiffies;
29467+ }
29468+ }
29469+
29470+ mfs->mfsrr_bytes = bavail;
29471+ AuDbg("b%d\n", mfs->mfs_bindex);
29472+ kfree(st);
29473+}
29474+
392086de 29475+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 29476+{
29477+ int err;
392086de 29478+ struct dentry *parent;
1facf9fc 29479+ struct super_block *sb;
29480+ struct au_wbr_mfs *mfs;
29481+
29482+ err = au_wbr_create_exp(dentry);
29483+ if (err >= 0)
29484+ goto out;
29485+
29486+ sb = dentry->d_sb;
392086de
AM
29487+ parent = NULL;
29488+ if (au_ftest_wbr(flags, PARENT))
29489+ parent = dget_parent(dentry);
1facf9fc 29490+ mfs = &au_sbi(sb)->si_wbr_mfs;
29491+ mutex_lock(&mfs->mfs_lock);
29492+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
29493+ || mfs->mfs_bindex < 0
29494+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 29495+ au_mfs(dentry, parent);
1facf9fc 29496+ mutex_unlock(&mfs->mfs_lock);
29497+ err = mfs->mfs_bindex;
392086de 29498+ dput(parent);
1facf9fc 29499+
4a4d8108
AM
29500+ if (err >= 0)
29501+ err = au_wbr_nonopq(dentry, err);
29502+
4f0767ce 29503+out:
1facf9fc 29504+ AuDbg("b%d\n", err);
29505+ return err;
29506+}
29507+
29508+static int au_wbr_create_init_mfs(struct super_block *sb)
29509+{
29510+ struct au_wbr_mfs *mfs;
29511+
29512+ mfs = &au_sbi(sb)->si_wbr_mfs;
29513+ mutex_init(&mfs->mfs_lock);
29514+ mfs->mfs_jiffy = 0;
29515+ mfs->mfs_bindex = -EROFS;
29516+
29517+ return 0;
29518+}
29519+
29520+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
29521+{
29522+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
29523+ return 0;
29524+}
29525+
29526+/* ---------------------------------------------------------------------- */
29527+
29528+/* most free space and then round robin */
392086de 29529+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 29530+{
29531+ int err;
29532+ struct au_wbr_mfs *mfs;
29533+
392086de 29534+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 29535+ if (err >= 0) {
29536+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 29537+ mutex_lock(&mfs->mfs_lock);
1facf9fc 29538+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 29539+ err = au_wbr_create_rr(dentry, flags);
dece6358 29540+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 29541+ }
29542+
29543+ AuDbg("b%d\n", err);
29544+ return err;
29545+}
29546+
29547+static int au_wbr_create_init_mfsrr(struct super_block *sb)
29548+{
29549+ int err;
29550+
29551+ au_wbr_create_init_mfs(sb); /* ignore */
29552+ err = au_wbr_create_init_rr(sb);
29553+
29554+ return err;
29555+}
29556+
29557+/* ---------------------------------------------------------------------- */
29558+
29559+/* top down parent and most free space */
392086de 29560+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 29561+{
29562+ int err, e2;
29563+ unsigned long long b;
29564+ aufs_bindex_t bindex, bstart, bend;
29565+ struct super_block *sb;
29566+ struct dentry *parent, *h_parent;
29567+ struct au_branch *br;
29568+
392086de 29569+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 29570+ if (unlikely(err < 0))
29571+ goto out;
29572+ parent = dget_parent(dentry);
29573+ bstart = au_dbstart(parent);
29574+ bend = au_dbtaildir(parent);
29575+ if (bstart == bend)
29576+ goto out_parent; /* success */
29577+
392086de 29578+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 29579+ if (e2 < 0)
29580+ goto out_parent; /* success */
29581+
29582+ /* when the available size is equal, select upper one */
29583+ sb = dentry->d_sb;
29584+ br = au_sbr(sb, err);
29585+ b = br->br_wbr->wbr_bytes;
29586+ AuDbg("b%d, %llu\n", err, b);
29587+
29588+ for (bindex = bstart; bindex <= bend; bindex++) {
29589+ h_parent = au_h_dptr(parent, bindex);
29590+ if (!h_parent || !h_parent->d_inode)
29591+ continue;
29592+
29593+ br = au_sbr(sb, bindex);
29594+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
29595+ b = br->br_wbr->wbr_bytes;
29596+ err = bindex;
29597+ AuDbg("b%d, %llu\n", err, b);
29598+ }
29599+ }
29600+
4a4d8108
AM
29601+ if (err >= 0)
29602+ err = au_wbr_nonopq(dentry, err);
29603+
4f0767ce 29604+out_parent:
1facf9fc 29605+ dput(parent);
4f0767ce 29606+out:
1facf9fc 29607+ AuDbg("b%d\n", err);
29608+ return err;
29609+}
29610+
29611+/* ---------------------------------------------------------------------- */
29612+
392086de
AM
29613+/*
29614+ * - top down parent
29615+ * - most free space with parent
29616+ * - most free space round-robin regardless parent
29617+ */
29618+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
29619+{
29620+ int err;
29621+ unsigned long long watermark;
29622+ struct super_block *sb;
29623+ struct au_branch *br;
29624+ struct au_wbr_mfs *mfs;
29625+
29626+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
29627+ if (unlikely(err < 0))
29628+ goto out;
29629+
29630+ sb = dentry->d_sb;
29631+ br = au_sbr(sb, err);
29632+ mfs = &au_sbi(sb)->si_wbr_mfs;
29633+ mutex_lock(&mfs->mfs_lock);
29634+ watermark = mfs->mfsrr_watermark;
29635+ mutex_unlock(&mfs->mfs_lock);
29636+ if (br->br_wbr->wbr_bytes < watermark)
29637+ /* regardless the parent dir */
29638+ err = au_wbr_create_mfsrr(dentry, flags);
29639+
29640+out:
29641+ AuDbg("b%d\n", err);
29642+ return err;
29643+}
29644+
29645+/* ---------------------------------------------------------------------- */
29646+
1facf9fc 29647+/* policies for copyup */
29648+
29649+/* top down parent */
29650+static int au_wbr_copyup_tdp(struct dentry *dentry)
29651+{
392086de 29652+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 29653+}
29654+
29655+/* bottom up parent */
29656+static int au_wbr_copyup_bup(struct dentry *dentry)
29657+{
29658+ int err;
29659+ aufs_bindex_t bindex, bstart;
29660+ struct dentry *parent, *h_parent;
29661+ struct super_block *sb;
29662+
29663+ err = -EROFS;
29664+ sb = dentry->d_sb;
29665+ parent = dget_parent(dentry);
29666+ bstart = au_dbstart(parent);
29667+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
29668+ h_parent = au_h_dptr(parent, bindex);
29669+ if (!h_parent || !h_parent->d_inode)
29670+ continue;
29671+
29672+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
29673+ err = bindex;
29674+ break;
29675+ }
29676+ }
29677+ dput(parent);
29678+
29679+ /* bottom up here */
29680+ if (unlikely(err < 0))
29681+ err = au_wbr_bu(sb, bstart - 1);
29682+
29683+ AuDbg("b%d\n", err);
29684+ return err;
29685+}
29686+
29687+/* bottom up */
29688+static int au_wbr_copyup_bu(struct dentry *dentry)
29689+{
29690+ int err;
4a4d8108 29691+ aufs_bindex_t bstart;
1facf9fc 29692+
4a4d8108
AM
29693+ bstart = au_dbstart(dentry);
29694+ err = au_wbr_bu(dentry->d_sb, bstart);
29695+ AuDbg("b%d\n", err);
29696+ if (err > bstart)
29697+ err = au_wbr_nonopq(dentry, err);
1facf9fc 29698+
29699+ AuDbg("b%d\n", err);
29700+ return err;
29701+}
29702+
29703+/* ---------------------------------------------------------------------- */
29704+
29705+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
29706+ [AuWbrCopyup_TDP] = {
29707+ .copyup = au_wbr_copyup_tdp
29708+ },
29709+ [AuWbrCopyup_BUP] = {
29710+ .copyup = au_wbr_copyup_bup
29711+ },
29712+ [AuWbrCopyup_BU] = {
29713+ .copyup = au_wbr_copyup_bu
29714+ }
29715+};
29716+
29717+struct au_wbr_create_operations au_wbr_create_ops[] = {
29718+ [AuWbrCreate_TDP] = {
29719+ .create = au_wbr_create_tdp
29720+ },
29721+ [AuWbrCreate_RR] = {
29722+ .create = au_wbr_create_rr,
29723+ .init = au_wbr_create_init_rr
29724+ },
29725+ [AuWbrCreate_MFS] = {
29726+ .create = au_wbr_create_mfs,
29727+ .init = au_wbr_create_init_mfs,
29728+ .fin = au_wbr_create_fin_mfs
29729+ },
29730+ [AuWbrCreate_MFSV] = {
29731+ .create = au_wbr_create_mfs,
29732+ .init = au_wbr_create_init_mfs,
29733+ .fin = au_wbr_create_fin_mfs
29734+ },
29735+ [AuWbrCreate_MFSRR] = {
29736+ .create = au_wbr_create_mfsrr,
29737+ .init = au_wbr_create_init_mfsrr,
29738+ .fin = au_wbr_create_fin_mfs
29739+ },
29740+ [AuWbrCreate_MFSRRV] = {
29741+ .create = au_wbr_create_mfsrr,
29742+ .init = au_wbr_create_init_mfsrr,
29743+ .fin = au_wbr_create_fin_mfs
29744+ },
29745+ [AuWbrCreate_PMFS] = {
29746+ .create = au_wbr_create_pmfs,
29747+ .init = au_wbr_create_init_mfs,
29748+ .fin = au_wbr_create_fin_mfs
29749+ },
29750+ [AuWbrCreate_PMFSV] = {
29751+ .create = au_wbr_create_pmfs,
29752+ .init = au_wbr_create_init_mfs,
29753+ .fin = au_wbr_create_fin_mfs
392086de
AM
29754+ },
29755+ [AuWbrCreate_PMFSRR] = {
29756+ .create = au_wbr_create_pmfsrr,
29757+ .init = au_wbr_create_init_mfsrr,
29758+ .fin = au_wbr_create_fin_mfs
29759+ },
29760+ [AuWbrCreate_PMFSRRV] = {
29761+ .create = au_wbr_create_pmfsrr,
29762+ .init = au_wbr_create_init_mfsrr,
29763+ .fin = au_wbr_create_fin_mfs
1facf9fc 29764+ }
29765+};
7f207e10
AM
29766diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
29767--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 29768+++ linux/fs/aufs/whout.c 2014-04-24 22:11:10.861935852 +0200
523b37e3 29769@@ -0,0 +1,1052 @@
1facf9fc 29770+/*
523b37e3 29771+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 29772+ *
29773+ * This program, aufs is free software; you can redistribute it and/or modify
29774+ * it under the terms of the GNU General Public License as published by
29775+ * the Free Software Foundation; either version 2 of the License, or
29776+ * (at your option) any later version.
dece6358
AM
29777+ *
29778+ * This program is distributed in the hope that it will be useful,
29779+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29780+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29781+ * GNU General Public License for more details.
29782+ *
29783+ * You should have received a copy of the GNU General Public License
523b37e3 29784+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29785+ */
29786+
29787+/*
29788+ * whiteout for logical deletion and opaque directory
29789+ */
29790+
1facf9fc 29791+#include "aufs.h"
29792+
29793+#define WH_MASK S_IRUGO
29794+
29795+/*
29796+ * If a directory contains this file, then it is opaque. We start with the
29797+ * .wh. flag so that it is blocked by lookup.
29798+ */
0c3ec466
AM
29799+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
29800+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 29801+
29802+/*
29803+ * generate whiteout name, which is NOT terminated by NULL.
29804+ * @name: original d_name.name
29805+ * @len: original d_name.len
29806+ * @wh: whiteout qstr
29807+ * returns zero when succeeds, otherwise error.
29808+ * succeeded value as wh->name should be freed by kfree().
29809+ */
29810+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
29811+{
29812+ char *p;
29813+
29814+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
29815+ return -ENAMETOOLONG;
29816+
29817+ wh->len = name->len + AUFS_WH_PFX_LEN;
29818+ p = kmalloc(wh->len, GFP_NOFS);
29819+ wh->name = p;
29820+ if (p) {
29821+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29822+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
29823+ /* smp_mb(); */
29824+ return 0;
29825+ }
29826+ return -ENOMEM;
29827+}
29828+
29829+/* ---------------------------------------------------------------------- */
29830+
29831+/*
29832+ * test if the @wh_name exists under @h_parent.
29833+ * @try_sio specifies the necessary of super-io.
29834+ */
29835+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
29836+ struct au_branch *br, int try_sio)
29837+{
29838+ int err;
29839+ struct dentry *wh_dentry;
1facf9fc 29840+
1facf9fc 29841+ if (!try_sio)
b4510431 29842+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 29843+ else
29844+ wh_dentry = au_sio_lkup_one(wh_name, h_parent, br);
29845+ err = PTR_ERR(wh_dentry);
29846+ if (IS_ERR(wh_dentry))
29847+ goto out;
29848+
29849+ err = 0;
29850+ if (!wh_dentry->d_inode)
29851+ goto out_wh; /* success */
29852+
29853+ err = 1;
29854+ if (S_ISREG(wh_dentry->d_inode->i_mode))
29855+ goto out_wh; /* success */
29856+
29857+ err = -EIO;
523b37e3
AM
29858+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
29859+ wh_dentry, wh_dentry->d_inode->i_mode);
1facf9fc 29860+
4f0767ce 29861+out_wh:
1facf9fc 29862+ dput(wh_dentry);
4f0767ce 29863+out:
1facf9fc 29864+ return err;
29865+}
29866+
29867+/*
29868+ * test if the @h_dentry sets opaque or not.
29869+ */
29870+int au_diropq_test(struct dentry *h_dentry, struct au_branch *br)
29871+{
29872+ int err;
29873+ struct inode *h_dir;
29874+
29875+ h_dir = h_dentry->d_inode;
29876+ err = au_wh_test(h_dentry, &diropq_name, br,
29877+ au_test_h_perm_sio(h_dir, MAY_EXEC));
29878+ return err;
29879+}
29880+
29881+/*
29882+ * returns a negative dentry whose name is unique and temporary.
29883+ */
29884+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
29885+ struct qstr *prefix)
29886+{
1facf9fc 29887+ struct dentry *dentry;
29888+ int i;
027c5e7a 29889+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 29890+ *name, *p;
027c5e7a 29891+ /* strict atomic_t is unnecessary here */
1facf9fc 29892+ static unsigned short cnt;
29893+ struct qstr qs;
29894+
4a4d8108
AM
29895+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
29896+
1facf9fc 29897+ name = defname;
027c5e7a
AM
29898+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
29899+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 29900+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 29901+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 29902+ goto out;
29903+ dentry = ERR_PTR(-ENOMEM);
29904+ name = kmalloc(qs.len + 1, GFP_NOFS);
29905+ if (unlikely(!name))
29906+ goto out;
29907+ }
29908+
29909+ /* doubly whiteout-ed */
29910+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
29911+ p = name + AUFS_WH_PFX_LEN * 2;
29912+ memcpy(p, prefix->name, prefix->len);
29913+ p += prefix->len;
29914+ *p++ = '.';
4a4d8108 29915+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 29916+
29917+ qs.name = name;
29918+ for (i = 0; i < 3; i++) {
b752ccd1 29919+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
1facf9fc 29920+ dentry = au_sio_lkup_one(&qs, h_parent, br);
29921+ if (IS_ERR(dentry) || !dentry->d_inode)
29922+ goto out_name;
29923+ dput(dentry);
29924+ }
0c3ec466 29925+ /* pr_warn("could not get random name\n"); */
1facf9fc 29926+ dentry = ERR_PTR(-EEXIST);
29927+ AuDbg("%.*s\n", AuLNPair(&qs));
29928+ BUG();
29929+
4f0767ce 29930+out_name:
1facf9fc 29931+ if (name != defname)
29932+ kfree(name);
4f0767ce 29933+out:
4a4d8108 29934+ AuTraceErrPtr(dentry);
1facf9fc 29935+ return dentry;
1facf9fc 29936+}
29937+
29938+/*
29939+ * rename the @h_dentry on @br to the whiteouted temporary name.
29940+ */
29941+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
29942+{
29943+ int err;
29944+ struct path h_path = {
86dc4139 29945+ .mnt = au_br_mnt(br)
1facf9fc 29946+ };
523b37e3 29947+ struct inode *h_dir, *delegated;
1facf9fc 29948+ struct dentry *h_parent;
29949+
29950+ h_parent = h_dentry->d_parent; /* dir inode is locked */
29951+ h_dir = h_parent->d_inode;
29952+ IMustLock(h_dir);
29953+
29954+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
29955+ err = PTR_ERR(h_path.dentry);
29956+ if (IS_ERR(h_path.dentry))
29957+ goto out;
29958+
29959+ /* under the same dir, no need to lock_rename() */
523b37e3
AM
29960+ delegated = NULL;
29961+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated);
1facf9fc 29962+ AuTraceErr(err);
523b37e3
AM
29963+ if (unlikely(err == -EWOULDBLOCK)) {
29964+ pr_warn("cannot retry for NFSv4 delegation"
29965+ " for an internal rename\n");
29966+ iput(delegated);
29967+ }
1facf9fc 29968+ dput(h_path.dentry);
29969+
4f0767ce 29970+out:
4a4d8108 29971+ AuTraceErr(err);
1facf9fc 29972+ return err;
29973+}
29974+
29975+/* ---------------------------------------------------------------------- */
29976+/*
29977+ * functions for removing a whiteout
29978+ */
29979+
29980+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
29981+{
523b37e3
AM
29982+ int err, force;
29983+ struct inode *delegated;
1facf9fc 29984+
29985+ /*
29986+ * forces superio when the dir has a sticky bit.
29987+ * this may be a violation of unix fs semantics.
29988+ */
29989+ force = (h_dir->i_mode & S_ISVTX)
0c3ec466 29990+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
523b37e3
AM
29991+ delegated = NULL;
29992+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
29993+ if (unlikely(err == -EWOULDBLOCK)) {
29994+ pr_warn("cannot retry for NFSv4 delegation"
29995+ " for an internal unlink\n");
29996+ iput(delegated);
29997+ }
29998+ return err;
1facf9fc 29999+}
30000+
30001+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
30002+ struct dentry *dentry)
30003+{
30004+ int err;
30005+
30006+ err = do_unlink_wh(h_dir, h_path);
30007+ if (!err && dentry)
30008+ au_set_dbwh(dentry, -1);
30009+
30010+ return err;
30011+}
30012+
30013+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
30014+ struct au_branch *br)
30015+{
30016+ int err;
30017+ struct path h_path = {
86dc4139 30018+ .mnt = au_br_mnt(br)
1facf9fc 30019+ };
30020+
30021+ err = 0;
b4510431 30022+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 30023+ if (IS_ERR(h_path.dentry))
30024+ err = PTR_ERR(h_path.dentry);
30025+ else {
30026+ if (h_path.dentry->d_inode
30027+ && S_ISREG(h_path.dentry->d_inode->i_mode))
30028+ err = do_unlink_wh(h_parent->d_inode, &h_path);
30029+ dput(h_path.dentry);
30030+ }
30031+
30032+ return err;
30033+}
30034+
30035+/* ---------------------------------------------------------------------- */
30036+/*
30037+ * initialize/clean whiteout for a branch
30038+ */
30039+
30040+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
30041+ const int isdir)
30042+{
30043+ int err;
523b37e3 30044+ struct inode *delegated;
1facf9fc 30045+
30046+ if (!whpath->dentry->d_inode)
30047+ return;
30048+
86dc4139
AM
30049+ if (isdir)
30050+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
30051+ else {
30052+ delegated = NULL;
30053+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
30054+ if (unlikely(err == -EWOULDBLOCK)) {
30055+ pr_warn("cannot retry for NFSv4 delegation"
30056+ " for an internal unlink\n");
30057+ iput(delegated);
30058+ }
30059+ }
1facf9fc 30060+ if (unlikely(err))
523b37e3
AM
30061+ pr_warn("failed removing %pd (%d), ignored.\n",
30062+ whpath->dentry, err);
1facf9fc 30063+}
30064+
30065+static int test_linkable(struct dentry *h_root)
30066+{
30067+ struct inode *h_dir = h_root->d_inode;
30068+
30069+ if (h_dir->i_op->link)
30070+ return 0;
30071+
523b37e3
AM
30072+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
30073+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 30074+ return -ENOSYS;
30075+}
30076+
30077+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
30078+static int au_whdir(struct inode *h_dir, struct path *path)
30079+{
30080+ int err;
30081+
30082+ err = -EEXIST;
30083+ if (!path->dentry->d_inode) {
30084+ int mode = S_IRWXU;
30085+
30086+ if (au_test_nfs(path->dentry->d_sb))
30087+ mode |= S_IXUGO;
86dc4139 30088+ err = vfsub_mkdir(h_dir, path, mode);
1facf9fc 30089+ } else if (S_ISDIR(path->dentry->d_inode->i_mode))
30090+ err = 0;
30091+ else
523b37e3 30092+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 30093+
30094+ return err;
30095+}
30096+
30097+struct au_wh_base {
30098+ const struct qstr *name;
30099+ struct dentry *dentry;
30100+};
30101+
30102+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
30103+ struct path *h_path)
30104+{
30105+ h_path->dentry = base[AuBrWh_BASE].dentry;
30106+ au_wh_clean(h_dir, h_path, /*isdir*/0);
30107+ h_path->dentry = base[AuBrWh_PLINK].dentry;
30108+ au_wh_clean(h_dir, h_path, /*isdir*/1);
30109+ h_path->dentry = base[AuBrWh_ORPH].dentry;
30110+ au_wh_clean(h_dir, h_path, /*isdir*/1);
30111+}
30112+
30113+/*
30114+ * returns tri-state,
30115+ * minus: error, caller should print the mesage
30116+ * zero: succuess
30117+ * plus: error, caller should NOT print the mesage
30118+ */
30119+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
30120+ int do_plink, struct au_wh_base base[],
30121+ struct path *h_path)
30122+{
30123+ int err;
30124+ struct inode *h_dir;
30125+
30126+ h_dir = h_root->d_inode;
30127+ h_path->dentry = base[AuBrWh_BASE].dentry;
30128+ au_wh_clean(h_dir, h_path, /*isdir*/0);
30129+ h_path->dentry = base[AuBrWh_PLINK].dentry;
30130+ if (do_plink) {
30131+ err = test_linkable(h_root);
30132+ if (unlikely(err)) {
30133+ err = 1;
30134+ goto out;
30135+ }
30136+
30137+ err = au_whdir(h_dir, h_path);
30138+ if (unlikely(err))
30139+ goto out;
30140+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
30141+ } else
30142+ au_wh_clean(h_dir, h_path, /*isdir*/1);
30143+ h_path->dentry = base[AuBrWh_ORPH].dentry;
30144+ err = au_whdir(h_dir, h_path);
30145+ if (unlikely(err))
30146+ goto out;
30147+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
30148+
4f0767ce 30149+out:
1facf9fc 30150+ return err;
30151+}
30152+
30153+/*
30154+ * for the moment, aufs supports the branch filesystem which does not support
30155+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
30156+ * copyup failed. finally, such filesystem will not be used as the writable
30157+ * branch.
30158+ *
30159+ * returns tri-state, see above.
30160+ */
30161+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
30162+ int do_plink, struct au_wh_base base[],
30163+ struct path *h_path)
30164+{
30165+ int err;
30166+ struct inode *h_dir;
30167+
1308ab2a 30168+ WbrWhMustWriteLock(wbr);
30169+
1facf9fc 30170+ err = test_linkable(h_root);
30171+ if (unlikely(err)) {
30172+ err = 1;
30173+ goto out;
30174+ }
30175+
30176+ /*
30177+ * todo: should this create be done in /sbin/mount.aufs helper?
30178+ */
30179+ err = -EEXIST;
30180+ h_dir = h_root->d_inode;
30181+ if (!base[AuBrWh_BASE].dentry->d_inode) {
86dc4139
AM
30182+ h_path->dentry = base[AuBrWh_BASE].dentry;
30183+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
1facf9fc 30184+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
30185+ err = 0;
30186+ else
523b37e3 30187+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 30188+ if (unlikely(err))
30189+ goto out;
30190+
30191+ h_path->dentry = base[AuBrWh_PLINK].dentry;
30192+ if (do_plink) {
30193+ err = au_whdir(h_dir, h_path);
30194+ if (unlikely(err))
30195+ goto out;
30196+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
30197+ } else
30198+ au_wh_clean(h_dir, h_path, /*isdir*/1);
30199+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
30200+
30201+ h_path->dentry = base[AuBrWh_ORPH].dentry;
30202+ err = au_whdir(h_dir, h_path);
30203+ if (unlikely(err))
30204+ goto out;
30205+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
30206+
4f0767ce 30207+out:
1facf9fc 30208+ return err;
30209+}
30210+
30211+/*
30212+ * initialize the whiteout base file/dir for @br.
30213+ */
86dc4139 30214+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 30215+{
30216+ int err, i;
30217+ const unsigned char do_plink
30218+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 30219+ struct inode *h_dir;
86dc4139
AM
30220+ struct path path = br->br_path;
30221+ struct dentry *h_root = path.dentry;
1facf9fc 30222+ struct au_wbr *wbr = br->br_wbr;
30223+ static const struct qstr base_name[] = {
0c3ec466
AM
30224+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
30225+ sizeof(AUFS_BASE_NAME) - 1),
30226+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
30227+ sizeof(AUFS_PLINKDIR_NAME) - 1),
30228+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
30229+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 30230+ };
30231+ struct au_wh_base base[] = {
30232+ [AuBrWh_BASE] = {
30233+ .name = base_name + AuBrWh_BASE,
30234+ .dentry = NULL
30235+ },
30236+ [AuBrWh_PLINK] = {
30237+ .name = base_name + AuBrWh_PLINK,
30238+ .dentry = NULL
30239+ },
30240+ [AuBrWh_ORPH] = {
30241+ .name = base_name + AuBrWh_ORPH,
30242+ .dentry = NULL
30243+ }
30244+ };
30245+
1308ab2a 30246+ if (wbr)
30247+ WbrWhMustWriteLock(wbr);
1facf9fc 30248+
1facf9fc 30249+ for (i = 0; i < AuBrWh_Last; i++) {
30250+ /* doubly whiteouted */
30251+ struct dentry *d;
30252+
30253+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
30254+ err = PTR_ERR(d);
30255+ if (IS_ERR(d))
30256+ goto out;
30257+
30258+ base[i].dentry = d;
30259+ AuDebugOn(wbr
30260+ && wbr->wbr_wh[i]
30261+ && wbr->wbr_wh[i] != base[i].dentry);
30262+ }
30263+
30264+ if (wbr)
30265+ for (i = 0; i < AuBrWh_Last; i++) {
30266+ dput(wbr->wbr_wh[i]);
30267+ wbr->wbr_wh[i] = NULL;
30268+ }
30269+
30270+ err = 0;
1e00d052 30271+ if (!au_br_writable(br->br_perm)) {
4a4d8108 30272+ h_dir = h_root->d_inode;
1facf9fc 30273+ au_wh_init_ro(h_dir, base, &path);
1e00d052 30274+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 30275+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
30276+ if (err > 0)
30277+ goto out;
30278+ else if (err)
30279+ goto out_err;
1e00d052 30280+ } else {
1facf9fc 30281+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
30282+ if (err > 0)
30283+ goto out;
30284+ else if (err)
30285+ goto out_err;
1facf9fc 30286+ }
30287+ goto out; /* success */
30288+
4f0767ce 30289+out_err:
523b37e3
AM
30290+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
30291+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 30292+out:
1facf9fc 30293+ for (i = 0; i < AuBrWh_Last; i++)
30294+ dput(base[i].dentry);
30295+ return err;
30296+}
30297+
30298+/* ---------------------------------------------------------------------- */
30299+/*
30300+ * whiteouts are all hard-linked usually.
30301+ * when its link count reaches a ceiling, we create a new whiteout base
30302+ * asynchronously.
30303+ */
30304+
30305+struct reinit_br_wh {
30306+ struct super_block *sb;
30307+ struct au_branch *br;
30308+};
30309+
30310+static void reinit_br_wh(void *arg)
30311+{
30312+ int err;
30313+ aufs_bindex_t bindex;
30314+ struct path h_path;
30315+ struct reinit_br_wh *a = arg;
30316+ struct au_wbr *wbr;
523b37e3 30317+ struct inode *dir, *delegated;
1facf9fc 30318+ struct dentry *h_root;
30319+ struct au_hinode *hdir;
30320+
30321+ err = 0;
30322+ wbr = a->br->br_wbr;
30323+ /* big aufs lock */
30324+ si_noflush_write_lock(a->sb);
30325+ if (!au_br_writable(a->br->br_perm))
30326+ goto out;
30327+ bindex = au_br_index(a->sb, a->br->br_id);
30328+ if (unlikely(bindex < 0))
30329+ goto out;
30330+
1308ab2a 30331+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 30332+ dir = a->sb->s_root->d_inode;
1facf9fc 30333+ hdir = au_hi(dir, bindex);
30334+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 30335+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 30336+
4a4d8108 30337+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 30338+ wbr_wh_write_lock(wbr);
30339+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
30340+ h_root, a->br);
30341+ if (!err) {
86dc4139
AM
30342+ h_path.dentry = wbr->wbr_whbase;
30343+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
30344+ delegated = NULL;
30345+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
30346+ /*force*/0);
30347+ if (unlikely(err == -EWOULDBLOCK)) {
30348+ pr_warn("cannot retry for NFSv4 delegation"
30349+ " for an internal unlink\n");
30350+ iput(delegated);
30351+ }
1facf9fc 30352+ } else {
523b37e3 30353+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 30354+ err = 0;
30355+ }
30356+ dput(wbr->wbr_whbase);
30357+ wbr->wbr_whbase = NULL;
30358+ if (!err)
86dc4139 30359+ err = au_wh_init(a->br, a->sb);
1facf9fc 30360+ wbr_wh_write_unlock(wbr);
4a4d8108 30361+ au_hn_imtx_unlock(hdir);
1308ab2a 30362+ di_read_unlock(a->sb->s_root, AuLock_IR);
1facf9fc 30363+
4f0767ce 30364+out:
1facf9fc 30365+ if (wbr)
30366+ atomic_dec(&wbr->wbr_wh_running);
30367+ atomic_dec(&a->br->br_count);
1facf9fc 30368+ si_write_unlock(a->sb);
027c5e7a 30369+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 30370+ kfree(arg);
30371+ if (unlikely(err))
30372+ AuIOErr("err %d\n", err);
30373+}
30374+
30375+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
30376+{
30377+ int do_dec, wkq_err;
30378+ struct reinit_br_wh *arg;
30379+
30380+ do_dec = 1;
30381+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
30382+ goto out;
30383+
30384+ /* ignore ENOMEM */
30385+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
30386+ if (arg) {
30387+ /*
30388+ * dec(wh_running), kfree(arg) and dec(br_count)
30389+ * in reinit function
30390+ */
30391+ arg->sb = sb;
30392+ arg->br = br;
30393+ atomic_inc(&br->br_count);
53392da6 30394+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 30395+ if (unlikely(wkq_err)) {
30396+ atomic_dec(&br->br_wbr->wbr_wh_running);
30397+ atomic_dec(&br->br_count);
30398+ kfree(arg);
30399+ }
30400+ do_dec = 0;
30401+ }
30402+
4f0767ce 30403+out:
1facf9fc 30404+ if (do_dec)
30405+ atomic_dec(&br->br_wbr->wbr_wh_running);
30406+}
30407+
30408+/* ---------------------------------------------------------------------- */
30409+
30410+/*
30411+ * create the whiteout @wh.
30412+ */
30413+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
30414+ struct dentry *wh)
30415+{
30416+ int err;
30417+ struct path h_path = {
30418+ .dentry = wh
30419+ };
30420+ struct au_branch *br;
30421+ struct au_wbr *wbr;
30422+ struct dentry *h_parent;
523b37e3 30423+ struct inode *h_dir, *delegated;
1facf9fc 30424+
30425+ h_parent = wh->d_parent; /* dir inode is locked */
30426+ h_dir = h_parent->d_inode;
30427+ IMustLock(h_dir);
30428+
30429+ br = au_sbr(sb, bindex);
86dc4139 30430+ h_path.mnt = au_br_mnt(br);
1facf9fc 30431+ wbr = br->br_wbr;
30432+ wbr_wh_read_lock(wbr);
30433+ if (wbr->wbr_whbase) {
523b37e3
AM
30434+ delegated = NULL;
30435+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
30436+ if (unlikely(err == -EWOULDBLOCK)) {
30437+ pr_warn("cannot retry for NFSv4 delegation"
30438+ " for an internal link\n");
30439+ iput(delegated);
30440+ }
1facf9fc 30441+ if (!err || err != -EMLINK)
30442+ goto out;
30443+
30444+ /* link count full. re-initialize br_whbase. */
30445+ kick_reinit_br_wh(sb, br);
30446+ }
30447+
30448+ /* return this error in this context */
b4510431 30449+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
1facf9fc 30450+
4f0767ce 30451+out:
1facf9fc 30452+ wbr_wh_read_unlock(wbr);
30453+ return err;
30454+}
30455+
30456+/* ---------------------------------------------------------------------- */
30457+
30458+/*
30459+ * create or remove the diropq.
30460+ */
30461+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
30462+ unsigned int flags)
30463+{
30464+ struct dentry *opq_dentry, *h_dentry;
30465+ struct super_block *sb;
30466+ struct au_branch *br;
30467+ int err;
30468+
30469+ sb = dentry->d_sb;
30470+ br = au_sbr(sb, bindex);
30471+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 30472+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 30473+ if (IS_ERR(opq_dentry))
30474+ goto out;
30475+
30476+ if (au_ftest_diropq(flags, CREATE)) {
30477+ err = link_or_create_wh(sb, bindex, opq_dentry);
30478+ if (!err) {
30479+ au_set_dbdiropq(dentry, bindex);
30480+ goto out; /* success */
30481+ }
30482+ } else {
30483+ struct path tmp = {
30484+ .dentry = opq_dentry,
86dc4139 30485+ .mnt = au_br_mnt(br)
1facf9fc 30486+ };
30487+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
30488+ if (!err)
30489+ au_set_dbdiropq(dentry, -1);
30490+ }
30491+ dput(opq_dentry);
30492+ opq_dentry = ERR_PTR(err);
30493+
4f0767ce 30494+out:
1facf9fc 30495+ return opq_dentry;
30496+}
30497+
30498+struct do_diropq_args {
30499+ struct dentry **errp;
30500+ struct dentry *dentry;
30501+ aufs_bindex_t bindex;
30502+ unsigned int flags;
30503+};
30504+
30505+static void call_do_diropq(void *args)
30506+{
30507+ struct do_diropq_args *a = args;
30508+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
30509+}
30510+
30511+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
30512+ unsigned int flags)
30513+{
30514+ struct dentry *diropq, *h_dentry;
30515+
30516+ h_dentry = au_h_dptr(dentry, bindex);
30517+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
30518+ diropq = do_diropq(dentry, bindex, flags);
30519+ else {
30520+ int wkq_err;
30521+ struct do_diropq_args args = {
30522+ .errp = &diropq,
30523+ .dentry = dentry,
30524+ .bindex = bindex,
30525+ .flags = flags
30526+ };
30527+
30528+ wkq_err = au_wkq_wait(call_do_diropq, &args);
30529+ if (unlikely(wkq_err))
30530+ diropq = ERR_PTR(wkq_err);
30531+ }
30532+
30533+ return diropq;
30534+}
30535+
30536+/* ---------------------------------------------------------------------- */
30537+
30538+/*
30539+ * lookup whiteout dentry.
30540+ * @h_parent: lower parent dentry which must exist and be locked
30541+ * @base_name: name of dentry which will be whiteouted
30542+ * returns dentry for whiteout.
30543+ */
30544+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
30545+ struct au_branch *br)
30546+{
30547+ int err;
30548+ struct qstr wh_name;
30549+ struct dentry *wh_dentry;
30550+
30551+ err = au_wh_name_alloc(&wh_name, base_name);
30552+ wh_dentry = ERR_PTR(err);
30553+ if (!err) {
b4510431 30554+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 30555+ kfree(wh_name.name);
30556+ }
30557+ return wh_dentry;
30558+}
30559+
30560+/*
30561+ * link/create a whiteout for @dentry on @bindex.
30562+ */
30563+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
30564+ struct dentry *h_parent)
30565+{
30566+ struct dentry *wh_dentry;
30567+ struct super_block *sb;
30568+ int err;
30569+
30570+ sb = dentry->d_sb;
30571+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
30572+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
30573+ err = link_or_create_wh(sb, bindex, wh_dentry);
30574+ if (!err)
30575+ au_set_dbwh(dentry, bindex);
30576+ else {
30577+ dput(wh_dentry);
30578+ wh_dentry = ERR_PTR(err);
30579+ }
30580+ }
30581+
30582+ return wh_dentry;
30583+}
30584+
30585+/* ---------------------------------------------------------------------- */
30586+
30587+/* Delete all whiteouts in this directory on branch bindex. */
30588+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
30589+ aufs_bindex_t bindex, struct au_branch *br)
30590+{
30591+ int err;
30592+ unsigned long ul, n;
30593+ struct qstr wh_name;
30594+ char *p;
30595+ struct hlist_head *head;
c06a8ce3 30596+ struct au_vdir_wh *pos;
1facf9fc 30597+ struct au_vdir_destr *str;
30598+
30599+ err = -ENOMEM;
537831f9 30600+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 30601+ wh_name.name = p;
30602+ if (unlikely(!wh_name.name))
30603+ goto out;
30604+
30605+ err = 0;
30606+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
30607+ p += AUFS_WH_PFX_LEN;
30608+ n = whlist->nh_num;
30609+ head = whlist->nh_head;
30610+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
30611+ hlist_for_each_entry(pos, head, wh_hash) {
30612+ if (pos->wh_bindex != bindex)
1facf9fc 30613+ continue;
30614+
c06a8ce3 30615+ str = &pos->wh_str;
1facf9fc 30616+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
30617+ memcpy(p, str->name, str->len);
30618+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
30619+ err = unlink_wh_name(h_dentry, &wh_name, br);
30620+ if (!err)
30621+ continue;
30622+ break;
30623+ }
30624+ AuIOErr("whiteout name too long %.*s\n",
30625+ str->len, str->name);
30626+ err = -EIO;
30627+ break;
30628+ }
30629+ }
537831f9 30630+ free_page((unsigned long)wh_name.name);
1facf9fc 30631+
4f0767ce 30632+out:
1facf9fc 30633+ return err;
30634+}
30635+
30636+struct del_wh_children_args {
30637+ int *errp;
30638+ struct dentry *h_dentry;
1308ab2a 30639+ struct au_nhash *whlist;
1facf9fc 30640+ aufs_bindex_t bindex;
30641+ struct au_branch *br;
30642+};
30643+
30644+static void call_del_wh_children(void *args)
30645+{
30646+ struct del_wh_children_args *a = args;
1308ab2a 30647+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 30648+}
30649+
30650+/* ---------------------------------------------------------------------- */
30651+
30652+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
30653+{
30654+ struct au_whtmp_rmdir *whtmp;
dece6358 30655+ int err;
1308ab2a 30656+ unsigned int rdhash;
dece6358
AM
30657+
30658+ SiMustAnyLock(sb);
1facf9fc 30659+
30660+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
30661+ if (unlikely(!whtmp)) {
30662+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 30663+ goto out;
dece6358 30664+ }
1facf9fc 30665+
30666+ whtmp->dir = NULL;
027c5e7a 30667+ whtmp->br = NULL;
1facf9fc 30668+ whtmp->wh_dentry = NULL;
1308ab2a 30669+ /* no estimation for dir size */
30670+ rdhash = au_sbi(sb)->si_rdhash;
30671+ if (!rdhash)
30672+ rdhash = AUFS_RDHASH_DEF;
30673+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
30674+ if (unlikely(err)) {
30675+ kfree(whtmp);
30676+ whtmp = ERR_PTR(err);
30677+ }
dece6358 30678+
4f0767ce 30679+out:
dece6358 30680+ return whtmp;
1facf9fc 30681+}
30682+
30683+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
30684+{
027c5e7a
AM
30685+ if (whtmp->br)
30686+ atomic_dec(&whtmp->br->br_count);
1facf9fc 30687+ dput(whtmp->wh_dentry);
30688+ iput(whtmp->dir);
dece6358 30689+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 30690+ kfree(whtmp);
30691+}
30692+
30693+/*
30694+ * rmdir the whiteouted temporary named dir @h_dentry.
30695+ * @whlist: whiteouted children.
30696+ */
30697+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
30698+ struct dentry *wh_dentry, struct au_nhash *whlist)
30699+{
30700+ int err;
30701+ struct path h_tmp;
30702+ struct inode *wh_inode, *h_dir;
30703+ struct au_branch *br;
30704+
30705+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
30706+ IMustLock(h_dir);
30707+
30708+ br = au_sbr(dir->i_sb, bindex);
30709+ wh_inode = wh_dentry->d_inode;
30710+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
30711+
30712+ /*
30713+ * someone else might change some whiteouts while we were sleeping.
30714+ * it means this whlist may have an obsoleted entry.
30715+ */
30716+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
30717+ err = del_wh_children(wh_dentry, whlist, bindex, br);
30718+ else {
30719+ int wkq_err;
30720+ struct del_wh_children_args args = {
30721+ .errp = &err,
30722+ .h_dentry = wh_dentry,
1308ab2a 30723+ .whlist = whlist,
1facf9fc 30724+ .bindex = bindex,
30725+ .br = br
30726+ };
30727+
30728+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
30729+ if (unlikely(wkq_err))
30730+ err = wkq_err;
30731+ }
30732+ mutex_unlock(&wh_inode->i_mutex);
30733+
30734+ if (!err) {
30735+ h_tmp.dentry = wh_dentry;
86dc4139 30736+ h_tmp.mnt = au_br_mnt(br);
1facf9fc 30737+ err = vfsub_rmdir(h_dir, &h_tmp);
1facf9fc 30738+ }
30739+
30740+ if (!err) {
30741+ if (au_ibstart(dir) == bindex) {
7f207e10 30742+ /* todo: dir->i_mutex is necessary */
1facf9fc 30743+ au_cpup_attr_timesizes(dir);
7f207e10 30744+ vfsub_drop_nlink(dir);
1facf9fc 30745+ }
30746+ return 0; /* success */
30747+ }
30748+
523b37e3 30749+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 30750+ return err;
30751+}
30752+
30753+static void call_rmdir_whtmp(void *args)
30754+{
30755+ int err;
e49829fe 30756+ aufs_bindex_t bindex;
1facf9fc 30757+ struct au_whtmp_rmdir *a = args;
30758+ struct super_block *sb;
30759+ struct dentry *h_parent;
30760+ struct inode *h_dir;
1facf9fc 30761+ struct au_hinode *hdir;
30762+
30763+ /* rmdir by nfsd may cause deadlock with this i_mutex */
30764+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 30765+ err = -EROFS;
1facf9fc 30766+ sb = a->dir->i_sb;
e49829fe
JR
30767+ si_read_lock(sb, !AuLock_FLUSH);
30768+ if (!au_br_writable(a->br->br_perm))
30769+ goto out;
30770+ bindex = au_br_index(sb, a->br->br_id);
30771+ if (unlikely(bindex < 0))
1facf9fc 30772+ goto out;
30773+
30774+ err = -EIO;
1facf9fc 30775+ ii_write_lock_parent(a->dir);
30776+ h_parent = dget_parent(a->wh_dentry);
30777+ h_dir = h_parent->d_inode;
e49829fe 30778+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
30779+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
30780+ if (unlikely(err))
30781+ goto out_mnt;
4a4d8108 30782+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
30783+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
30784+ a->br);
86dc4139
AM
30785+ if (!err)
30786+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 30787+ au_hn_imtx_unlock(hdir);
86dc4139
AM
30788+ vfsub_mnt_drop_write(au_br_mnt(a->br));
30789+
30790+out_mnt:
1facf9fc 30791+ dput(h_parent);
30792+ ii_write_unlock(a->dir);
4f0767ce 30793+out:
1facf9fc 30794+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 30795+ au_whtmp_rmdir_free(a);
027c5e7a
AM
30796+ si_read_unlock(sb);
30797+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 30798+ if (unlikely(err))
30799+ AuIOErr("err %d\n", err);
30800+}
30801+
30802+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
30803+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
30804+{
30805+ int wkq_err;
e49829fe 30806+ struct super_block *sb;
1facf9fc 30807+
30808+ IMustLock(dir);
30809+
30810+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 30811+ sb = dir->i_sb;
1facf9fc 30812+ args->dir = au_igrab(dir);
e49829fe
JR
30813+ args->br = au_sbr(sb, bindex);
30814+ atomic_inc(&args->br->br_count);
1facf9fc 30815+ args->wh_dentry = dget(wh_dentry);
53392da6 30816+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 30817+ if (unlikely(wkq_err)) {
523b37e3 30818+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 30819+ au_whtmp_rmdir_free(args);
30820+ }
30821+}
7f207e10
AM
30822diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
30823--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 30824+++ linux/fs/aufs/whout.h 2014-04-24 22:11:10.861935852 +0200
523b37e3 30825@@ -0,0 +1,86 @@
1facf9fc 30826+/*
523b37e3 30827+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30828+ *
30829+ * This program, aufs is free software; you can redistribute it and/or modify
30830+ * it under the terms of the GNU General Public License as published by
30831+ * the Free Software Foundation; either version 2 of the License, or
30832+ * (at your option) any later version.
dece6358
AM
30833+ *
30834+ * This program is distributed in the hope that it will be useful,
30835+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30836+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30837+ * GNU General Public License for more details.
30838+ *
30839+ * You should have received a copy of the GNU General Public License
523b37e3 30840+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30841+ */
30842+
30843+/*
30844+ * whiteout for logical deletion and opaque directory
30845+ */
30846+
30847+#ifndef __AUFS_WHOUT_H__
30848+#define __AUFS_WHOUT_H__
30849+
30850+#ifdef __KERNEL__
30851+
1facf9fc 30852+#include "dir.h"
30853+
30854+/* whout.c */
30855+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
30856+struct au_branch;
30857+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name,
30858+ struct au_branch *br, int try_sio);
30859+int au_diropq_test(struct dentry *h_dentry, struct au_branch *br);
30860+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
30861+ struct qstr *prefix);
30862+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
30863+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
30864+ struct dentry *dentry);
86dc4139 30865+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 30866+
30867+/* diropq flags */
30868+#define AuDiropq_CREATE 1
30869+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
30870+#define au_fset_diropq(flags, name) \
30871+ do { (flags) |= AuDiropq_##name; } while (0)
30872+#define au_fclr_diropq(flags, name) \
30873+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 30874+
30875+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
30876+ unsigned int flags);
30877+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
30878+ struct au_branch *br);
30879+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
30880+ struct dentry *h_parent);
30881+
30882+/* real rmdir for the whiteout-ed dir */
30883+struct au_whtmp_rmdir {
30884+ struct inode *dir;
e49829fe 30885+ struct au_branch *br;
1facf9fc 30886+ struct dentry *wh_dentry;
dece6358 30887+ struct au_nhash whlist;
1facf9fc 30888+};
30889+
30890+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
30891+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
30892+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
30893+ struct dentry *wh_dentry, struct au_nhash *whlist);
30894+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
30895+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
30896+
30897+/* ---------------------------------------------------------------------- */
30898+
30899+static inline struct dentry *au_diropq_create(struct dentry *dentry,
30900+ aufs_bindex_t bindex)
30901+{
30902+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
30903+}
30904+
30905+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
30906+{
30907+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
30908+}
30909+
30910+#endif /* __KERNEL__ */
30911+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
30912diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
30913--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 30914+++ linux/fs/aufs/wkq.c 2014-04-24 22:11:10.861935852 +0200
523b37e3 30915@@ -0,0 +1,212 @@
1facf9fc 30916+/*
523b37e3 30917+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30918+ *
30919+ * This program, aufs is free software; you can redistribute it and/or modify
30920+ * it under the terms of the GNU General Public License as published by
30921+ * the Free Software Foundation; either version 2 of the License, or
30922+ * (at your option) any later version.
dece6358
AM
30923+ *
30924+ * This program is distributed in the hope that it will be useful,
30925+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30926+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30927+ * GNU General Public License for more details.
30928+ *
30929+ * You should have received a copy of the GNU General Public License
523b37e3 30930+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30931+ */
30932+
30933+/*
30934+ * workqueue for asynchronous/super-io operations
30935+ * todo: try new dredential scheme
30936+ */
30937+
dece6358 30938+#include <linux/module.h>
1facf9fc 30939+#include "aufs.h"
30940+
9dbd164d 30941+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 30942+
9dbd164d 30943+static struct workqueue_struct *au_wkq;
1facf9fc 30944+
30945+struct au_wkinfo {
30946+ struct work_struct wk;
7f207e10 30947+ struct kobject *kobj;
1facf9fc 30948+
30949+ unsigned int flags; /* see wkq.h */
30950+
30951+ au_wkq_func_t func;
30952+ void *args;
30953+
1facf9fc 30954+ struct completion *comp;
30955+};
30956+
30957+/* ---------------------------------------------------------------------- */
30958+
1facf9fc 30959+static void wkq_func(struct work_struct *wk)
30960+{
30961+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
30962+
2dfbb274 30963+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
30964+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
30965+
1facf9fc 30966+ wkinfo->func(wkinfo->args);
1facf9fc 30967+ if (au_ftest_wkq(wkinfo->flags, WAIT))
30968+ complete(wkinfo->comp);
30969+ else {
7f207e10 30970+ kobject_put(wkinfo->kobj);
9dbd164d 30971+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 30972+ kfree(wkinfo);
30973+ }
30974+}
30975+
30976+/*
30977+ * Since struct completion is large, try allocating it dynamically.
30978+ */
c2b27bf2 30979+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 30980+#define AuWkqCompDeclare(name) struct completion *comp = NULL
30981+
30982+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
30983+{
30984+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
30985+ if (*comp) {
30986+ init_completion(*comp);
30987+ wkinfo->comp = *comp;
30988+ return 0;
30989+ }
30990+ return -ENOMEM;
30991+}
30992+
30993+static void au_wkq_comp_free(struct completion *comp)
30994+{
30995+ kfree(comp);
30996+}
30997+
30998+#else
30999+
31000+/* no braces */
31001+#define AuWkqCompDeclare(name) \
31002+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
31003+ struct completion *comp = &_ ## name
31004+
31005+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
31006+{
31007+ wkinfo->comp = *comp;
31008+ return 0;
31009+}
31010+
31011+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
31012+{
31013+ /* empty */
31014+}
31015+#endif /* 4KSTACKS */
31016+
53392da6 31017+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 31018+{
53392da6
AM
31019+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
31020+ if (au_wkq_test()) {
31021+ AuWarn1("wkq from wkq, due to a dead dir by UDBA?\n");
31022+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
31023+ }
31024+ } else
31025+ au_dbg_verify_kthread();
31026+
31027+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 31028+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 31029+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
31030+ } else {
31031+ INIT_WORK(&wkinfo->wk, wkq_func);
31032+ schedule_work(&wkinfo->wk);
31033+ }
1facf9fc 31034+}
31035+
7f207e10
AM
31036+/*
31037+ * Be careful. It is easy to make deadlock happen.
31038+ * processA: lock, wkq and wait
31039+ * processB: wkq and wait, lock in wkq
31040+ * --> deadlock
31041+ */
b752ccd1 31042+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 31043+{
31044+ int err;
31045+ AuWkqCompDeclare(comp);
31046+ struct au_wkinfo wkinfo = {
b752ccd1 31047+ .flags = flags,
1facf9fc 31048+ .func = func,
31049+ .args = args
31050+ };
31051+
31052+ err = au_wkq_comp_alloc(&wkinfo, &comp);
31053+ if (!err) {
53392da6 31054+ au_wkq_run(&wkinfo);
1facf9fc 31055+ /* no timeout, no interrupt */
31056+ wait_for_completion(wkinfo.comp);
31057+ au_wkq_comp_free(comp);
4a4d8108 31058+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 31059+ }
31060+
31061+ return err;
31062+
31063+}
31064+
027c5e7a
AM
31065+/*
31066+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
31067+ * problem in a concurrent umounting.
31068+ */
53392da6
AM
31069+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
31070+ unsigned int flags)
1facf9fc 31071+{
31072+ int err;
31073+ struct au_wkinfo *wkinfo;
31074+
31075+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
31076+
31077+ /*
31078+ * wkq_func() must free this wkinfo.
31079+ * it highly depends upon the implementation of workqueue.
31080+ */
31081+ err = 0;
31082+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
31083+ if (wkinfo) {
7f207e10 31084+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 31085+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 31086+ wkinfo->func = func;
31087+ wkinfo->args = args;
31088+ wkinfo->comp = NULL;
7f207e10 31089+ kobject_get(wkinfo->kobj);
9dbd164d 31090+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 31091+
53392da6 31092+ au_wkq_run(wkinfo);
1facf9fc 31093+ } else {
31094+ err = -ENOMEM;
e49829fe 31095+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 31096+ }
31097+
31098+ return err;
31099+}
31100+
31101+/* ---------------------------------------------------------------------- */
31102+
31103+void au_nwt_init(struct au_nowait_tasks *nwt)
31104+{
31105+ atomic_set(&nwt->nw_len, 0);
4a4d8108 31106+ /* smp_mb(); */ /* atomic_set */
1facf9fc 31107+ init_waitqueue_head(&nwt->nw_wq);
31108+}
31109+
31110+void au_wkq_fin(void)
31111+{
9dbd164d 31112+ destroy_workqueue(au_wkq);
1facf9fc 31113+}
31114+
31115+int __init au_wkq_init(void)
31116+{
9dbd164d 31117+ int err;
b752ccd1
AM
31118+
31119+ err = 0;
86dc4139 31120+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
31121+ if (IS_ERR(au_wkq))
31122+ err = PTR_ERR(au_wkq);
31123+ else if (!au_wkq)
31124+ err = -ENOMEM;
b752ccd1
AM
31125+
31126+ return err;
1facf9fc 31127+}
7f207e10
AM
31128diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
31129--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 31130+++ linux/fs/aufs/wkq.h 2014-04-24 22:11:10.861935852 +0200
523b37e3 31131@@ -0,0 +1,91 @@
1facf9fc 31132+/*
523b37e3 31133+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 31134+ *
31135+ * This program, aufs is free software; you can redistribute it and/or modify
31136+ * it under the terms of the GNU General Public License as published by
31137+ * the Free Software Foundation; either version 2 of the License, or
31138+ * (at your option) any later version.
dece6358
AM
31139+ *
31140+ * This program is distributed in the hope that it will be useful,
31141+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31142+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31143+ * GNU General Public License for more details.
31144+ *
31145+ * You should have received a copy of the GNU General Public License
523b37e3 31146+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31147+ */
31148+
31149+/*
31150+ * workqueue for asynchronous/super-io operations
31151+ * todo: try new credentials management scheme
31152+ */
31153+
31154+#ifndef __AUFS_WKQ_H__
31155+#define __AUFS_WKQ_H__
31156+
31157+#ifdef __KERNEL__
31158+
dece6358
AM
31159+struct super_block;
31160+
1facf9fc 31161+/* ---------------------------------------------------------------------- */
31162+
31163+/*
31164+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
31165+ */
31166+struct au_nowait_tasks {
31167+ atomic_t nw_len;
31168+ wait_queue_head_t nw_wq;
31169+};
31170+
31171+/* ---------------------------------------------------------------------- */
31172+
31173+typedef void (*au_wkq_func_t)(void *args);
31174+
31175+/* wkq flags */
31176+#define AuWkq_WAIT 1
9dbd164d 31177+#define AuWkq_NEST (1 << 1)
1facf9fc 31178+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
31179+#define au_fset_wkq(flags, name) \
31180+ do { (flags) |= AuWkq_##name; } while (0)
31181+#define au_fclr_wkq(flags, name) \
31182+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 31183+
9dbd164d
AM
31184+#ifndef CONFIG_AUFS_HNOTIFY
31185+#undef AuWkq_NEST
31186+#define AuWkq_NEST 0
31187+#endif
31188+
1facf9fc 31189+/* wkq.c */
b752ccd1 31190+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
31191+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
31192+ unsigned int flags);
1facf9fc 31193+void au_nwt_init(struct au_nowait_tasks *nwt);
31194+int __init au_wkq_init(void);
31195+void au_wkq_fin(void);
31196+
31197+/* ---------------------------------------------------------------------- */
31198+
53392da6
AM
31199+static inline int au_wkq_test(void)
31200+{
31201+ return current->flags & PF_WQ_WORKER;
31202+}
31203+
b752ccd1 31204+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 31205+{
b752ccd1 31206+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 31207+}
31208+
31209+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
31210+{
e49829fe 31211+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 31212+ wake_up_all(&nwt->nw_wq);
31213+}
31214+
31215+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
31216+{
31217+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
31218+ return 0;
31219+}
31220+
31221+#endif /* __KERNEL__ */
31222+#endif /* __AUFS_WKQ_H__ */
7f207e10
AM
31223diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
31224--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
fb47a38f 31225+++ linux/fs/aufs/xino.c 2014-04-24 22:11:10.861935852 +0200
523b37e3 31226@@ -0,0 +1,1314 @@
1facf9fc 31227+/*
523b37e3 31228+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 31229+ *
31230+ * This program, aufs is free software; you can redistribute it and/or modify
31231+ * it under the terms of the GNU General Public License as published by
31232+ * the Free Software Foundation; either version 2 of the License, or
31233+ * (at your option) any later version.
dece6358
AM
31234+ *
31235+ * This program is distributed in the hope that it will be useful,
31236+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31237+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31238+ * GNU General Public License for more details.
31239+ *
31240+ * You should have received a copy of the GNU General Public License
523b37e3 31241+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31242+ */
31243+
31244+/*
31245+ * external inode number translation table and bitmap
31246+ */
31247+
31248+#include <linux/seq_file.h>
392086de 31249+#include <linux/statfs.h>
1facf9fc 31250+#include "aufs.h"
31251+
9dbd164d 31252+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 31253+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 31254+ loff_t *pos)
31255+{
31256+ ssize_t err;
31257+ mm_segment_t oldfs;
b752ccd1
AM
31258+ union {
31259+ void *k;
31260+ char __user *u;
31261+ } buf;
1facf9fc 31262+
b752ccd1 31263+ buf.k = kbuf;
1facf9fc 31264+ oldfs = get_fs();
31265+ set_fs(KERNEL_DS);
31266+ do {
31267+ /* todo: signal_pending? */
b752ccd1 31268+ err = func(file, buf.u, size, pos);
1facf9fc 31269+ } while (err == -EAGAIN || err == -EINTR);
31270+ set_fs(oldfs);
31271+
31272+#if 0 /* reserved for future use */
31273+ if (err > 0)
31274+ fsnotify_access(file->f_dentry);
31275+#endif
31276+
31277+ return err;
31278+}
31279+
31280+/* ---------------------------------------------------------------------- */
31281+
b752ccd1 31282+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 31283+ size_t size, loff_t *pos)
31284+{
31285+ ssize_t err;
31286+ mm_segment_t oldfs;
b752ccd1
AM
31287+ union {
31288+ void *k;
31289+ const char __user *u;
31290+ } buf;
1facf9fc 31291+
b752ccd1 31292+ buf.k = kbuf;
1facf9fc 31293+ oldfs = get_fs();
31294+ set_fs(KERNEL_DS);
1facf9fc 31295+ do {
31296+ /* todo: signal_pending? */
b752ccd1 31297+ err = func(file, buf.u, size, pos);
1facf9fc 31298+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 31299+ set_fs(oldfs);
31300+
31301+#if 0 /* reserved for future use */
31302+ if (err > 0)
31303+ fsnotify_modify(file->f_dentry);
31304+#endif
31305+
31306+ return err;
31307+}
31308+
31309+struct do_xino_fwrite_args {
31310+ ssize_t *errp;
31311+ au_writef_t func;
31312+ struct file *file;
31313+ void *buf;
31314+ size_t size;
31315+ loff_t *pos;
31316+};
31317+
31318+static void call_do_xino_fwrite(void *args)
31319+{
31320+ struct do_xino_fwrite_args *a = args;
31321+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
31322+}
31323+
31324+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
31325+ loff_t *pos)
31326+{
31327+ ssize_t err;
31328+
31329+ /* todo: signal block and no wkq? */
b752ccd1
AM
31330+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
31331+ lockdep_off();
31332+ err = do_xino_fwrite(func, file, buf, size, pos);
31333+ lockdep_on();
31334+ } else {
31335+ /*
31336+ * it breaks RLIMIT_FSIZE and normal user's limit,
31337+ * users should care about quota and real 'filesystem full.'
31338+ */
1facf9fc 31339+ int wkq_err;
31340+ struct do_xino_fwrite_args args = {
31341+ .errp = &err,
31342+ .func = func,
31343+ .file = file,
31344+ .buf = buf,
31345+ .size = size,
31346+ .pos = pos
31347+ };
31348+
31349+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
31350+ if (unlikely(wkq_err))
31351+ err = wkq_err;
b752ccd1 31352+ }
1facf9fc 31353+
31354+ return err;
31355+}
31356+
31357+/* ---------------------------------------------------------------------- */
31358+
31359+/*
31360+ * create a new xinofile at the same place/path as @base_file.
31361+ */
31362+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
31363+{
31364+ struct file *file;
4a4d8108 31365+ struct dentry *base, *parent;
523b37e3 31366+ struct inode *dir, *delegated;
1facf9fc 31367+ struct qstr *name;
1308ab2a 31368+ struct path path;
4a4d8108 31369+ int err;
1facf9fc 31370+
31371+ base = base_file->f_dentry;
31372+ parent = base->d_parent; /* dir inode is locked */
31373+ dir = parent->d_inode;
31374+ IMustLock(dir);
31375+
31376+ file = ERR_PTR(-EINVAL);
31377+ name = &base->d_name;
4a4d8108
AM
31378+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
31379+ if (IS_ERR(path.dentry)) {
31380+ file = (void *)path.dentry;
523b37e3
AM
31381+ pr_err("%pd lookup err %ld\n",
31382+ base, PTR_ERR(path.dentry));
1facf9fc 31383+ goto out;
31384+ }
31385+
31386+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 31387+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 31388+ if (unlikely(err)) {
31389+ file = ERR_PTR(err);
523b37e3 31390+ pr_err("%pd create err %d\n", base, err);
1facf9fc 31391+ goto out_dput;
31392+ }
31393+
c06a8ce3 31394+ path.mnt = base_file->f_path.mnt;
4a4d8108 31395+ file = vfsub_dentry_open(&path,
7f207e10 31396+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 31397+ /* | __FMODE_NONOTIFY */);
1facf9fc 31398+ if (IS_ERR(file)) {
523b37e3 31399+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 31400+ goto out_dput;
31401+ }
31402+
523b37e3
AM
31403+ delegated = NULL;
31404+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
31405+ if (unlikely(err == -EWOULDBLOCK)) {
31406+ pr_warn("cannot retry for NFSv4 delegation"
31407+ " for an internal unlink\n");
31408+ iput(delegated);
31409+ }
1facf9fc 31410+ if (unlikely(err)) {
523b37e3 31411+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 31412+ goto out_fput;
31413+ }
31414+
31415+ if (copy_src) {
31416+ /* no one can touch copy_src xino */
c06a8ce3 31417+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 31418+ if (unlikely(err)) {
523b37e3 31419+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 31420+ goto out_fput;
31421+ }
31422+ }
31423+ goto out_dput; /* success */
31424+
4f0767ce 31425+out_fput:
1facf9fc 31426+ fput(file);
31427+ file = ERR_PTR(err);
4f0767ce 31428+out_dput:
4a4d8108 31429+ dput(path.dentry);
4f0767ce 31430+out:
1facf9fc 31431+ return file;
31432+}
31433+
31434+struct au_xino_lock_dir {
31435+ struct au_hinode *hdir;
31436+ struct dentry *parent;
31437+ struct mutex *mtx;
31438+};
31439+
31440+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
31441+ struct au_xino_lock_dir *ldir)
31442+{
31443+ aufs_bindex_t brid, bindex;
31444+
31445+ ldir->hdir = NULL;
31446+ bindex = -1;
31447+ brid = au_xino_brid(sb);
31448+ if (brid >= 0)
31449+ bindex = au_br_index(sb, brid);
31450+ if (bindex >= 0) {
31451+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 31452+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 31453+ } else {
31454+ ldir->parent = dget_parent(xino->f_dentry);
31455+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
31456+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
31457+ }
31458+}
31459+
31460+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
31461+{
31462+ if (ldir->hdir)
4a4d8108 31463+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 31464+ else {
31465+ mutex_unlock(ldir->mtx);
31466+ dput(ldir->parent);
31467+ }
31468+}
31469+
31470+/* ---------------------------------------------------------------------- */
31471+
31472+/* trucate xino files asynchronously */
31473+
31474+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
31475+{
31476+ int err;
392086de
AM
31477+ unsigned long jiffy;
31478+ blkcnt_t blocks;
1facf9fc 31479+ aufs_bindex_t bi, bend;
392086de 31480+ struct kstatfs *st;
1facf9fc 31481+ struct au_branch *br;
31482+ struct file *new_xino, *file;
31483+ struct super_block *h_sb;
31484+ struct au_xino_lock_dir ldir;
31485+
392086de
AM
31486+ err = -ENOMEM;
31487+ st = kzalloc(sizeof(*st), GFP_NOFS);
31488+ if (unlikely(!st))
31489+ goto out;
31490+
1facf9fc 31491+ err = -EINVAL;
31492+ bend = au_sbend(sb);
31493+ if (unlikely(bindex < 0 || bend < bindex))
392086de 31494+ goto out_st;
1facf9fc 31495+ br = au_sbr(sb, bindex);
31496+ file = br->br_xino.xi_file;
31497+ if (!file)
392086de
AM
31498+ goto out_st;
31499+
31500+ err = vfs_statfs(&file->f_path, st);
31501+ if (unlikely(err))
31502+ AuErr1("statfs err %d, ignored\n", err);
31503+ jiffy = jiffies;
31504+ blocks = file_inode(file)->i_blocks;
31505+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
31506+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 31507+
31508+ au_xino_lock_dir(sb, file, &ldir);
31509+ /* mnt_want_write() is unnecessary here */
31510+ new_xino = au_xino_create2(file, file);
31511+ au_xino_unlock_dir(&ldir);
31512+ err = PTR_ERR(new_xino);
392086de
AM
31513+ if (IS_ERR(new_xino)) {
31514+ pr_err("err %d, ignored\n", err);
31515+ goto out_st;
31516+ }
1facf9fc 31517+ err = 0;
31518+ fput(file);
31519+ br->br_xino.xi_file = new_xino;
31520+
86dc4139 31521+ h_sb = au_br_sb(br);
1facf9fc 31522+ for (bi = 0; bi <= bend; bi++) {
31523+ if (unlikely(bi == bindex))
31524+ continue;
31525+ br = au_sbr(sb, bi);
86dc4139 31526+ if (au_br_sb(br) != h_sb)
1facf9fc 31527+ continue;
31528+
31529+ fput(br->br_xino.xi_file);
31530+ br->br_xino.xi_file = new_xino;
31531+ get_file(new_xino);
31532+ }
31533+
392086de
AM
31534+ err = vfs_statfs(&new_xino->f_path, st);
31535+ if (!err) {
31536+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
31537+ bindex, (u64)file_inode(new_xino)->i_blocks,
31538+ st->f_bfree, st->f_blocks);
31539+ if (file_inode(new_xino)->i_blocks < blocks)
31540+ au_sbi(sb)->si_xino_jiffy = jiffy;
31541+ } else
31542+ AuErr1("statfs err %d, ignored\n", err);
31543+
31544+out_st:
31545+ kfree(st);
4f0767ce 31546+out:
1facf9fc 31547+ return err;
31548+}
31549+
31550+struct xino_do_trunc_args {
31551+ struct super_block *sb;
31552+ struct au_branch *br;
31553+};
31554+
31555+static void xino_do_trunc(void *_args)
31556+{
31557+ struct xino_do_trunc_args *args = _args;
31558+ struct super_block *sb;
31559+ struct au_branch *br;
31560+ struct inode *dir;
31561+ int err;
31562+ aufs_bindex_t bindex;
31563+
31564+ err = 0;
31565+ sb = args->sb;
31566+ dir = sb->s_root->d_inode;
31567+ br = args->br;
31568+
31569+ si_noflush_write_lock(sb);
31570+ ii_read_lock_parent(dir);
31571+ bindex = au_br_index(sb, br->br_id);
31572+ err = au_xino_trunc(sb, bindex);
1facf9fc 31573+ ii_read_unlock(dir);
31574+ if (unlikely(err))
392086de 31575+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 31576+ atomic_dec(&br->br_xino_running);
31577+ atomic_dec(&br->br_count);
1facf9fc 31578+ si_write_unlock(sb);
027c5e7a 31579+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 31580+ kfree(args);
31581+}
31582+
392086de
AM
31583+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
31584+{
31585+ int err;
31586+ struct kstatfs st;
31587+ struct au_sbinfo *sbinfo;
31588+
31589+ /* todo: si_xino_expire and the ratio should be customizable */
31590+ sbinfo = au_sbi(sb);
31591+ if (time_before(jiffies,
31592+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
31593+ return 0;
31594+
31595+ /* truncation border */
31596+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
31597+ if (unlikely(err)) {
31598+ AuErr1("statfs err %d, ignored\n", err);
31599+ return 0;
31600+ }
31601+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
31602+ return 0;
31603+
31604+ return 1;
31605+}
31606+
1facf9fc 31607+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
31608+{
31609+ struct xino_do_trunc_args *args;
31610+ int wkq_err;
31611+
392086de 31612+ if (!xino_trunc_test(sb, br))
1facf9fc 31613+ return;
31614+
31615+ if (atomic_inc_return(&br->br_xino_running) > 1)
31616+ goto out;
31617+
31618+ /* lock and kfree() will be called in trunc_xino() */
31619+ args = kmalloc(sizeof(*args), GFP_NOFS);
31620+ if (unlikely(!args)) {
31621+ AuErr1("no memory\n");
31622+ goto out_args;
31623+ }
31624+
e49829fe 31625+ atomic_inc(&br->br_count);
1facf9fc 31626+ args->sb = sb;
31627+ args->br = br;
53392da6 31628+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 31629+ if (!wkq_err)
31630+ return; /* success */
31631+
4a4d8108 31632+ pr_err("wkq %d\n", wkq_err);
e49829fe 31633+ atomic_dec(&br->br_count);
1facf9fc 31634+
4f0767ce 31635+out_args:
1facf9fc 31636+ kfree(args);
4f0767ce 31637+out:
e49829fe 31638+ atomic_dec(&br->br_xino_running);
1facf9fc 31639+}
31640+
31641+/* ---------------------------------------------------------------------- */
31642+
31643+static int au_xino_do_write(au_writef_t write, struct file *file,
31644+ ino_t h_ino, ino_t ino)
31645+{
31646+ loff_t pos;
31647+ ssize_t sz;
31648+
31649+ pos = h_ino;
31650+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
31651+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
31652+ return -EFBIG;
31653+ }
31654+ pos *= sizeof(ino);
31655+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
31656+ if (sz == sizeof(ino))
31657+ return 0; /* success */
31658+
31659+ AuIOErr("write failed (%zd)\n", sz);
31660+ return -EIO;
31661+}
31662+
31663+/*
31664+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
31665+ * at the position of @h_ino.
31666+ * even if @ino is zero, it is written to the xinofile and means no entry.
31667+ * if the size of the xino file on a specific filesystem exceeds the watermark,
31668+ * try truncating it.
31669+ */
31670+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
31671+ ino_t ino)
31672+{
31673+ int err;
31674+ unsigned int mnt_flags;
31675+ struct au_branch *br;
31676+
31677+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
31678+ || ((loff_t)-1) > 0);
dece6358 31679+ SiMustAnyLock(sb);
1facf9fc 31680+
31681+ mnt_flags = au_mntflags(sb);
31682+ if (!au_opt_test(mnt_flags, XINO))
31683+ return 0;
31684+
31685+ br = au_sbr(sb, bindex);
31686+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
31687+ h_ino, ino);
31688+ if (!err) {
31689+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 31690+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 31691+ xino_try_trunc(sb, br);
31692+ return 0; /* success */
31693+ }
31694+
31695+ AuIOErr("write failed (%d)\n", err);
31696+ return -EIO;
31697+}
31698+
31699+/* ---------------------------------------------------------------------- */
31700+
31701+/* aufs inode number bitmap */
31702+
31703+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
31704+static ino_t xib_calc_ino(unsigned long pindex, int bit)
31705+{
31706+ ino_t ino;
31707+
31708+ AuDebugOn(bit < 0 || page_bits <= bit);
31709+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
31710+ return ino;
31711+}
31712+
31713+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
31714+{
31715+ AuDebugOn(ino < AUFS_FIRST_INO);
31716+ ino -= AUFS_FIRST_INO;
31717+ *pindex = ino / page_bits;
31718+ *bit = ino % page_bits;
31719+}
31720+
31721+static int xib_pindex(struct super_block *sb, unsigned long pindex)
31722+{
31723+ int err;
31724+ loff_t pos;
31725+ ssize_t sz;
31726+ struct au_sbinfo *sbinfo;
31727+ struct file *xib;
31728+ unsigned long *p;
31729+
31730+ sbinfo = au_sbi(sb);
31731+ MtxMustLock(&sbinfo->si_xib_mtx);
31732+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
31733+ || !au_opt_test(sbinfo->si_mntflags, XINO));
31734+
31735+ if (pindex == sbinfo->si_xib_last_pindex)
31736+ return 0;
31737+
31738+ xib = sbinfo->si_xib;
31739+ p = sbinfo->si_xib_buf;
31740+ pos = sbinfo->si_xib_last_pindex;
31741+ pos *= PAGE_SIZE;
31742+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
31743+ if (unlikely(sz != PAGE_SIZE))
31744+ goto out;
31745+
31746+ pos = pindex;
31747+ pos *= PAGE_SIZE;
c06a8ce3 31748+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 31749+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
31750+ else {
31751+ memset(p, 0, PAGE_SIZE);
31752+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
31753+ }
31754+ if (sz == PAGE_SIZE) {
31755+ sbinfo->si_xib_last_pindex = pindex;
31756+ return 0; /* success */
31757+ }
31758+
4f0767ce 31759+out:
b752ccd1
AM
31760+ AuIOErr1("write failed (%zd)\n", sz);
31761+ err = sz;
31762+ if (sz >= 0)
31763+ err = -EIO;
31764+ return err;
31765+}
31766+
31767+/* ---------------------------------------------------------------------- */
31768+
31769+static void au_xib_clear_bit(struct inode *inode)
31770+{
31771+ int err, bit;
31772+ unsigned long pindex;
31773+ struct super_block *sb;
31774+ struct au_sbinfo *sbinfo;
31775+
31776+ AuDebugOn(inode->i_nlink);
31777+
31778+ sb = inode->i_sb;
31779+ xib_calc_bit(inode->i_ino, &pindex, &bit);
31780+ AuDebugOn(page_bits <= bit);
31781+ sbinfo = au_sbi(sb);
31782+ mutex_lock(&sbinfo->si_xib_mtx);
31783+ err = xib_pindex(sb, pindex);
31784+ if (!err) {
31785+ clear_bit(bit, sbinfo->si_xib_buf);
31786+ sbinfo->si_xib_next_bit = bit;
31787+ }
31788+ mutex_unlock(&sbinfo->si_xib_mtx);
31789+}
31790+
31791+/* for s_op->delete_inode() */
31792+void au_xino_delete_inode(struct inode *inode, const int unlinked)
31793+{
31794+ int err;
31795+ unsigned int mnt_flags;
31796+ aufs_bindex_t bindex, bend, bi;
31797+ unsigned char try_trunc;
31798+ struct au_iinfo *iinfo;
31799+ struct super_block *sb;
31800+ struct au_hinode *hi;
31801+ struct inode *h_inode;
31802+ struct au_branch *br;
31803+ au_writef_t xwrite;
31804+
31805+ sb = inode->i_sb;
31806+ mnt_flags = au_mntflags(sb);
31807+ if (!au_opt_test(mnt_flags, XINO)
31808+ || inode->i_ino == AUFS_ROOT_INO)
31809+ return;
31810+
31811+ if (unlinked) {
31812+ au_xigen_inc(inode);
31813+ au_xib_clear_bit(inode);
31814+ }
31815+
31816+ iinfo = au_ii(inode);
31817+ if (!iinfo)
31818+ return;
1facf9fc 31819+
b752ccd1
AM
31820+ bindex = iinfo->ii_bstart;
31821+ if (bindex < 0)
31822+ return;
1facf9fc 31823+
b752ccd1
AM
31824+ xwrite = au_sbi(sb)->si_xwrite;
31825+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
31826+ hi = iinfo->ii_hinode + bindex;
31827+ bend = iinfo->ii_bend;
31828+ for (; bindex <= bend; bindex++, hi++) {
31829+ h_inode = hi->hi_inode;
31830+ if (!h_inode
31831+ || (!unlinked && h_inode->i_nlink))
31832+ continue;
1facf9fc 31833+
b752ccd1
AM
31834+ /* inode may not be revalidated */
31835+ bi = au_br_index(sb, hi->hi_id);
31836+ if (bi < 0)
31837+ continue;
1facf9fc 31838+
b752ccd1
AM
31839+ br = au_sbr(sb, bi);
31840+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
31841+ h_inode->i_ino, /*ino*/0);
31842+ if (!err && try_trunc
86dc4139 31843+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 31844+ xino_try_trunc(sb, br);
1facf9fc 31845+ }
1facf9fc 31846+}
31847+
31848+/* get an unused inode number from bitmap */
31849+ino_t au_xino_new_ino(struct super_block *sb)
31850+{
31851+ ino_t ino;
31852+ unsigned long *p, pindex, ul, pend;
31853+ struct au_sbinfo *sbinfo;
31854+ struct file *file;
31855+ int free_bit, err;
31856+
31857+ if (!au_opt_test(au_mntflags(sb), XINO))
31858+ return iunique(sb, AUFS_FIRST_INO);
31859+
31860+ sbinfo = au_sbi(sb);
31861+ mutex_lock(&sbinfo->si_xib_mtx);
31862+ p = sbinfo->si_xib_buf;
31863+ free_bit = sbinfo->si_xib_next_bit;
31864+ if (free_bit < page_bits && !test_bit(free_bit, p))
31865+ goto out; /* success */
31866+ free_bit = find_first_zero_bit(p, page_bits);
31867+ if (free_bit < page_bits)
31868+ goto out; /* success */
31869+
31870+ pindex = sbinfo->si_xib_last_pindex;
31871+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
31872+ err = xib_pindex(sb, ul);
31873+ if (unlikely(err))
31874+ goto out_err;
31875+ free_bit = find_first_zero_bit(p, page_bits);
31876+ if (free_bit < page_bits)
31877+ goto out; /* success */
31878+ }
31879+
31880+ file = sbinfo->si_xib;
c06a8ce3 31881+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 31882+ for (ul = pindex + 1; ul <= pend; ul++) {
31883+ err = xib_pindex(sb, ul);
31884+ if (unlikely(err))
31885+ goto out_err;
31886+ free_bit = find_first_zero_bit(p, page_bits);
31887+ if (free_bit < page_bits)
31888+ goto out; /* success */
31889+ }
31890+ BUG();
31891+
4f0767ce 31892+out:
1facf9fc 31893+ set_bit(free_bit, p);
7f207e10 31894+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 31895+ pindex = sbinfo->si_xib_last_pindex;
31896+ mutex_unlock(&sbinfo->si_xib_mtx);
31897+ ino = xib_calc_ino(pindex, free_bit);
31898+ AuDbg("i%lu\n", (unsigned long)ino);
31899+ return ino;
4f0767ce 31900+out_err:
1facf9fc 31901+ mutex_unlock(&sbinfo->si_xib_mtx);
31902+ AuDbg("i0\n");
31903+ return 0;
31904+}
31905+
31906+/*
31907+ * read @ino from xinofile for the specified branch{@sb, @bindex}
31908+ * at the position of @h_ino.
31909+ * if @ino does not exist and @do_new is true, get new one.
31910+ */
31911+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
31912+ ino_t *ino)
31913+{
31914+ int err;
31915+ ssize_t sz;
31916+ loff_t pos;
31917+ struct file *file;
31918+ struct au_sbinfo *sbinfo;
31919+
31920+ *ino = 0;
31921+ if (!au_opt_test(au_mntflags(sb), XINO))
31922+ return 0; /* no xino */
31923+
31924+ err = 0;
31925+ sbinfo = au_sbi(sb);
31926+ pos = h_ino;
31927+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
31928+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
31929+ return -EFBIG;
31930+ }
31931+ pos *= sizeof(*ino);
31932+
31933+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 31934+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 31935+ return 0; /* no ino */
31936+
31937+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
31938+ if (sz == sizeof(*ino))
31939+ return 0; /* success */
31940+
31941+ err = sz;
31942+ if (unlikely(sz >= 0)) {
31943+ err = -EIO;
31944+ AuIOErr("xino read error (%zd)\n", sz);
31945+ }
31946+
31947+ return err;
31948+}
31949+
31950+/* ---------------------------------------------------------------------- */
31951+
31952+/* create and set a new xino file */
31953+
31954+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
31955+{
31956+ struct file *file;
31957+ struct dentry *h_parent, *d;
31958+ struct inode *h_dir;
31959+ int err;
31960+
31961+ /*
31962+ * at mount-time, and the xino file is the default path,
4a4d8108 31963+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 31964+ * when a user specified the xino, we cannot get au_hdir to be ignored.
31965+ */
7f207e10 31966+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 31967+ /* | __FMODE_NONOTIFY */,
1facf9fc 31968+ S_IRUGO | S_IWUGO);
31969+ if (IS_ERR(file)) {
31970+ if (!silent)
4a4d8108 31971+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 31972+ return file;
31973+ }
31974+
31975+ /* keep file count */
31976+ h_parent = dget_parent(file->f_dentry);
31977+ h_dir = h_parent->d_inode;
31978+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
31979+ /* mnt_want_write() is unnecessary here */
523b37e3
AM
31980+ /* no delegation since it is just created */
31981+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, /*force*/0);
1facf9fc 31982+ mutex_unlock(&h_dir->i_mutex);
31983+ dput(h_parent);
31984+ if (unlikely(err)) {
31985+ if (!silent)
4a4d8108 31986+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 31987+ goto out;
31988+ }
31989+
31990+ err = -EINVAL;
31991+ d = file->f_dentry;
31992+ if (unlikely(sb == d->d_sb)) {
31993+ if (!silent)
4a4d8108 31994+ pr_err("%s must be outside\n", fname);
1facf9fc 31995+ goto out;
31996+ }
31997+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
31998+ if (!silent)
4a4d8108
AM
31999+ pr_err("xino doesn't support %s(%s)\n",
32000+ fname, au_sbtype(d->d_sb));
1facf9fc 32001+ goto out;
32002+ }
32003+ return file; /* success */
32004+
4f0767ce 32005+out:
1facf9fc 32006+ fput(file);
32007+ file = ERR_PTR(err);
32008+ return file;
32009+}
32010+
32011+/*
32012+ * find another branch who is on the same filesystem of the specified
32013+ * branch{@btgt}. search until @bend.
32014+ */
32015+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
32016+ aufs_bindex_t bend)
32017+{
32018+ aufs_bindex_t bindex;
32019+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
32020+
32021+ for (bindex = 0; bindex < btgt; bindex++)
32022+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
32023+ return bindex;
32024+ for (bindex++; bindex <= bend; bindex++)
32025+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
32026+ return bindex;
32027+ return -1;
32028+}
32029+
32030+/* ---------------------------------------------------------------------- */
32031+
32032+/*
32033+ * initialize the xinofile for the specified branch @br
32034+ * at the place/path where @base_file indicates.
32035+ * test whether another branch is on the same filesystem or not,
32036+ * if @do_test is true.
32037+ */
32038+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
32039+ struct file *base_file, int do_test)
32040+{
32041+ int err;
32042+ ino_t ino;
32043+ aufs_bindex_t bend, bindex;
32044+ struct au_branch *shared_br, *b;
32045+ struct file *file;
32046+ struct super_block *tgt_sb;
32047+
32048+ shared_br = NULL;
32049+ bend = au_sbend(sb);
32050+ if (do_test) {
86dc4139 32051+ tgt_sb = au_br_sb(br);
1facf9fc 32052+ for (bindex = 0; bindex <= bend; bindex++) {
32053+ b = au_sbr(sb, bindex);
86dc4139 32054+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 32055+ shared_br = b;
32056+ break;
32057+ }
32058+ }
32059+ }
32060+
32061+ if (!shared_br || !shared_br->br_xino.xi_file) {
32062+ struct au_xino_lock_dir ldir;
32063+
32064+ au_xino_lock_dir(sb, base_file, &ldir);
32065+ /* mnt_want_write() is unnecessary here */
32066+ file = au_xino_create2(base_file, NULL);
32067+ au_xino_unlock_dir(&ldir);
32068+ err = PTR_ERR(file);
32069+ if (IS_ERR(file))
32070+ goto out;
32071+ br->br_xino.xi_file = file;
32072+ } else {
32073+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
32074+ get_file(br->br_xino.xi_file);
32075+ }
32076+
32077+ ino = AUFS_ROOT_INO;
32078+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
32079+ h_ino, ino);
b752ccd1
AM
32080+ if (unlikely(err)) {
32081+ fput(br->br_xino.xi_file);
32082+ br->br_xino.xi_file = NULL;
32083+ }
1facf9fc 32084+
4f0767ce 32085+out:
1facf9fc 32086+ return err;
32087+}
32088+
32089+/* ---------------------------------------------------------------------- */
32090+
32091+/* trucate a xino bitmap file */
32092+
32093+/* todo: slow */
32094+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
32095+{
32096+ int err, bit;
32097+ ssize_t sz;
32098+ unsigned long pindex;
32099+ loff_t pos, pend;
32100+ struct au_sbinfo *sbinfo;
32101+ au_readf_t func;
32102+ ino_t *ino;
32103+ unsigned long *p;
32104+
32105+ err = 0;
32106+ sbinfo = au_sbi(sb);
dece6358 32107+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 32108+ p = sbinfo->si_xib_buf;
32109+ func = sbinfo->si_xread;
c06a8ce3 32110+ pend = vfsub_f_size_read(file);
1facf9fc 32111+ pos = 0;
32112+ while (pos < pend) {
32113+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
32114+ err = sz;
32115+ if (unlikely(sz <= 0))
32116+ goto out;
32117+
32118+ err = 0;
32119+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
32120+ if (unlikely(*ino < AUFS_FIRST_INO))
32121+ continue;
32122+
32123+ xib_calc_bit(*ino, &pindex, &bit);
32124+ AuDebugOn(page_bits <= bit);
32125+ err = xib_pindex(sb, pindex);
32126+ if (!err)
32127+ set_bit(bit, p);
32128+ else
32129+ goto out;
32130+ }
32131+ }
32132+
4f0767ce 32133+out:
1facf9fc 32134+ return err;
32135+}
32136+
32137+static int xib_restore(struct super_block *sb)
32138+{
32139+ int err;
32140+ aufs_bindex_t bindex, bend;
32141+ void *page;
32142+
32143+ err = -ENOMEM;
32144+ page = (void *)__get_free_page(GFP_NOFS);
32145+ if (unlikely(!page))
32146+ goto out;
32147+
32148+ err = 0;
32149+ bend = au_sbend(sb);
32150+ for (bindex = 0; !err && bindex <= bend; bindex++)
32151+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
32152+ err = do_xib_restore
32153+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
32154+ else
32155+ AuDbg("b%d\n", bindex);
32156+ free_page((unsigned long)page);
32157+
4f0767ce 32158+out:
1facf9fc 32159+ return err;
32160+}
32161+
32162+int au_xib_trunc(struct super_block *sb)
32163+{
32164+ int err;
32165+ ssize_t sz;
32166+ loff_t pos;
32167+ struct au_xino_lock_dir ldir;
32168+ struct au_sbinfo *sbinfo;
32169+ unsigned long *p;
32170+ struct file *file;
32171+
dece6358
AM
32172+ SiMustWriteLock(sb);
32173+
1facf9fc 32174+ err = 0;
32175+ sbinfo = au_sbi(sb);
32176+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
32177+ goto out;
32178+
32179+ file = sbinfo->si_xib;
c06a8ce3 32180+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 32181+ goto out;
32182+
32183+ au_xino_lock_dir(sb, file, &ldir);
32184+ /* mnt_want_write() is unnecessary here */
32185+ file = au_xino_create2(sbinfo->si_xib, NULL);
32186+ au_xino_unlock_dir(&ldir);
32187+ err = PTR_ERR(file);
32188+ if (IS_ERR(file))
32189+ goto out;
32190+ fput(sbinfo->si_xib);
32191+ sbinfo->si_xib = file;
32192+
32193+ p = sbinfo->si_xib_buf;
32194+ memset(p, 0, PAGE_SIZE);
32195+ pos = 0;
32196+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
32197+ if (unlikely(sz != PAGE_SIZE)) {
32198+ err = sz;
32199+ AuIOErr("err %d\n", err);
32200+ if (sz >= 0)
32201+ err = -EIO;
32202+ goto out;
32203+ }
32204+
32205+ mutex_lock(&sbinfo->si_xib_mtx);
32206+ /* mnt_want_write() is unnecessary here */
32207+ err = xib_restore(sb);
32208+ mutex_unlock(&sbinfo->si_xib_mtx);
32209+
32210+out:
32211+ return err;
32212+}
32213+
32214+/* ---------------------------------------------------------------------- */
32215+
32216+/*
32217+ * xino mount option handlers
32218+ */
32219+static au_readf_t find_readf(struct file *h_file)
32220+{
32221+ const struct file_operations *fop = h_file->f_op;
32222+
523b37e3
AM
32223+ if (fop->read)
32224+ return fop->read;
32225+ if (fop->aio_read)
32226+ return do_sync_read;
1facf9fc 32227+ return ERR_PTR(-ENOSYS);
32228+}
32229+
32230+static au_writef_t find_writef(struct file *h_file)
32231+{
32232+ const struct file_operations *fop = h_file->f_op;
32233+
523b37e3
AM
32234+ if (fop->write)
32235+ return fop->write;
32236+ if (fop->aio_write)
32237+ return do_sync_write;
1facf9fc 32238+ return ERR_PTR(-ENOSYS);
32239+}
32240+
32241+/* xino bitmap */
32242+static void xino_clear_xib(struct super_block *sb)
32243+{
32244+ struct au_sbinfo *sbinfo;
32245+
dece6358
AM
32246+ SiMustWriteLock(sb);
32247+
1facf9fc 32248+ sbinfo = au_sbi(sb);
32249+ sbinfo->si_xread = NULL;
32250+ sbinfo->si_xwrite = NULL;
32251+ if (sbinfo->si_xib)
32252+ fput(sbinfo->si_xib);
32253+ sbinfo->si_xib = NULL;
32254+ free_page((unsigned long)sbinfo->si_xib_buf);
32255+ sbinfo->si_xib_buf = NULL;
32256+}
32257+
32258+static int au_xino_set_xib(struct super_block *sb, struct file *base)
32259+{
32260+ int err;
32261+ loff_t pos;
32262+ struct au_sbinfo *sbinfo;
32263+ struct file *file;
32264+
dece6358
AM
32265+ SiMustWriteLock(sb);
32266+
1facf9fc 32267+ sbinfo = au_sbi(sb);
32268+ file = au_xino_create2(base, sbinfo->si_xib);
32269+ err = PTR_ERR(file);
32270+ if (IS_ERR(file))
32271+ goto out;
32272+ if (sbinfo->si_xib)
32273+ fput(sbinfo->si_xib);
32274+ sbinfo->si_xib = file;
32275+ sbinfo->si_xread = find_readf(file);
32276+ sbinfo->si_xwrite = find_writef(file);
32277+
32278+ err = -ENOMEM;
32279+ if (!sbinfo->si_xib_buf)
32280+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
32281+ if (unlikely(!sbinfo->si_xib_buf))
32282+ goto out_unset;
32283+
32284+ sbinfo->si_xib_last_pindex = 0;
32285+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 32286+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 32287+ pos = 0;
32288+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
32289+ PAGE_SIZE, &pos);
32290+ if (unlikely(err != PAGE_SIZE))
32291+ goto out_free;
32292+ }
32293+ err = 0;
32294+ goto out; /* success */
32295+
4f0767ce 32296+out_free:
1facf9fc 32297+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
32298+ sbinfo->si_xib_buf = NULL;
32299+ if (err >= 0)
32300+ err = -EIO;
4f0767ce 32301+out_unset:
b752ccd1
AM
32302+ fput(sbinfo->si_xib);
32303+ sbinfo->si_xib = NULL;
32304+ sbinfo->si_xread = NULL;
32305+ sbinfo->si_xwrite = NULL;
4f0767ce 32306+out:
b752ccd1 32307+ return err;
1facf9fc 32308+}
32309+
b752ccd1
AM
32310+/* xino for each branch */
32311+static void xino_clear_br(struct super_block *sb)
32312+{
32313+ aufs_bindex_t bindex, bend;
32314+ struct au_branch *br;
1facf9fc 32315+
b752ccd1
AM
32316+ bend = au_sbend(sb);
32317+ for (bindex = 0; bindex <= bend; bindex++) {
32318+ br = au_sbr(sb, bindex);
32319+ if (!br || !br->br_xino.xi_file)
32320+ continue;
32321+
32322+ fput(br->br_xino.xi_file);
32323+ br->br_xino.xi_file = NULL;
32324+ }
32325+}
32326+
32327+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 32328+{
32329+ int err;
b752ccd1
AM
32330+ ino_t ino;
32331+ aufs_bindex_t bindex, bend, bshared;
32332+ struct {
32333+ struct file *old, *new;
32334+ } *fpair, *p;
32335+ struct au_branch *br;
32336+ struct inode *inode;
32337+ au_writef_t writef;
1facf9fc 32338+
b752ccd1
AM
32339+ SiMustWriteLock(sb);
32340+
32341+ err = -ENOMEM;
32342+ bend = au_sbend(sb);
32343+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
32344+ if (unlikely(!fpair))
1facf9fc 32345+ goto out;
32346+
b752ccd1
AM
32347+ inode = sb->s_root->d_inode;
32348+ ino = AUFS_ROOT_INO;
32349+ writef = au_sbi(sb)->si_xwrite;
32350+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
32351+ br = au_sbr(sb, bindex);
32352+ bshared = is_sb_shared(sb, bindex, bindex - 1);
32353+ if (bshared >= 0) {
32354+ /* shared xino */
32355+ *p = fpair[bshared];
32356+ get_file(p->new);
32357+ }
32358+
32359+ if (!p->new) {
32360+ /* new xino */
32361+ p->old = br->br_xino.xi_file;
32362+ p->new = au_xino_create2(base, br->br_xino.xi_file);
32363+ err = PTR_ERR(p->new);
32364+ if (IS_ERR(p->new)) {
32365+ p->new = NULL;
32366+ goto out_pair;
32367+ }
32368+ }
32369+
32370+ err = au_xino_do_write(writef, p->new,
32371+ au_h_iptr(inode, bindex)->i_ino, ino);
32372+ if (unlikely(err))
32373+ goto out_pair;
32374+ }
32375+
32376+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
32377+ br = au_sbr(sb, bindex);
32378+ if (br->br_xino.xi_file)
32379+ fput(br->br_xino.xi_file);
32380+ get_file(p->new);
32381+ br->br_xino.xi_file = p->new;
32382+ }
1facf9fc 32383+
4f0767ce 32384+out_pair:
b752ccd1
AM
32385+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
32386+ if (p->new)
32387+ fput(p->new);
32388+ else
32389+ break;
32390+ kfree(fpair);
4f0767ce 32391+out:
1facf9fc 32392+ return err;
32393+}
b752ccd1
AM
32394+
32395+void au_xino_clr(struct super_block *sb)
32396+{
32397+ struct au_sbinfo *sbinfo;
32398+
32399+ au_xigen_clr(sb);
32400+ xino_clear_xib(sb);
32401+ xino_clear_br(sb);
32402+ sbinfo = au_sbi(sb);
32403+ /* lvalue, do not call au_mntflags() */
32404+ au_opt_clr(sbinfo->si_mntflags, XINO);
32405+}
32406+
32407+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
32408+{
32409+ int err, skip;
32410+ struct dentry *parent, *cur_parent;
32411+ struct qstr *dname, *cur_name;
32412+ struct file *cur_xino;
32413+ struct inode *dir;
32414+ struct au_sbinfo *sbinfo;
32415+
32416+ SiMustWriteLock(sb);
32417+
32418+ err = 0;
32419+ sbinfo = au_sbi(sb);
32420+ parent = dget_parent(xino->file->f_dentry);
32421+ if (remount) {
32422+ skip = 0;
32423+ dname = &xino->file->f_dentry->d_name;
32424+ cur_xino = sbinfo->si_xib;
32425+ if (cur_xino) {
32426+ cur_parent = dget_parent(cur_xino->f_dentry);
32427+ cur_name = &cur_xino->f_dentry->d_name;
32428+ skip = (cur_parent == parent
32429+ && dname->len == cur_name->len
32430+ && !memcmp(dname->name, cur_name->name,
32431+ dname->len));
32432+ dput(cur_parent);
32433+ }
32434+ if (skip)
32435+ goto out;
32436+ }
32437+
32438+ au_opt_set(sbinfo->si_mntflags, XINO);
32439+ dir = parent->d_inode;
32440+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
32441+ /* mnt_want_write() is unnecessary here */
32442+ err = au_xino_set_xib(sb, xino->file);
32443+ if (!err)
32444+ err = au_xigen_set(sb, xino->file);
32445+ if (!err)
32446+ err = au_xino_set_br(sb, xino->file);
32447+ mutex_unlock(&dir->i_mutex);
32448+ if (!err)
32449+ goto out; /* success */
32450+
32451+ /* reset all */
32452+ AuIOErr("failed creating xino(%d).\n", err);
32453+
4f0767ce 32454+out:
b752ccd1
AM
32455+ dput(parent);
32456+ return err;
32457+}
32458+
32459+/* ---------------------------------------------------------------------- */
32460+
32461+/*
32462+ * create a xinofile at the default place/path.
32463+ */
32464+struct file *au_xino_def(struct super_block *sb)
32465+{
32466+ struct file *file;
32467+ char *page, *p;
32468+ struct au_branch *br;
32469+ struct super_block *h_sb;
32470+ struct path path;
32471+ aufs_bindex_t bend, bindex, bwr;
32472+
32473+ br = NULL;
32474+ bend = au_sbend(sb);
32475+ bwr = -1;
32476+ for (bindex = 0; bindex <= bend; bindex++) {
32477+ br = au_sbr(sb, bindex);
32478+ if (au_br_writable(br->br_perm)
86dc4139 32479+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
32480+ bwr = bindex;
32481+ break;
32482+ }
32483+ }
32484+
7f207e10
AM
32485+ if (bwr >= 0) {
32486+ file = ERR_PTR(-ENOMEM);
537831f9 32487+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
32488+ if (unlikely(!page))
32489+ goto out;
86dc4139 32490+ path.mnt = au_br_mnt(br);
7f207e10
AM
32491+ path.dentry = au_h_dptr(sb->s_root, bwr);
32492+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
32493+ file = (void *)p;
32494+ if (!IS_ERR(p)) {
32495+ strcat(p, "/" AUFS_XINO_FNAME);
32496+ AuDbg("%s\n", p);
32497+ file = au_xino_create(sb, p, /*silent*/0);
32498+ if (!IS_ERR(file))
32499+ au_xino_brid_set(sb, br->br_id);
32500+ }
537831f9 32501+ free_page((unsigned long)page);
7f207e10
AM
32502+ } else {
32503+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
32504+ if (IS_ERR(file))
32505+ goto out;
32506+ h_sb = file->f_dentry->d_sb;
32507+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
32508+ pr_err("xino doesn't support %s(%s)\n",
32509+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
32510+ fput(file);
32511+ file = ERR_PTR(-EINVAL);
32512+ }
32513+ if (!IS_ERR(file))
32514+ au_xino_brid_set(sb, -1);
32515+ }
0c5527e5 32516+
7f207e10
AM
32517+out:
32518+ return file;
32519+}
32520+
32521+/* ---------------------------------------------------------------------- */
32522+
32523+int au_xino_path(struct seq_file *seq, struct file *file)
32524+{
32525+ int err;
32526+
32527+ err = au_seq_path(seq, &file->f_path);
32528+ if (unlikely(err < 0))
32529+ goto out;
32530+
32531+ err = 0;
32532+#define Deleted "\\040(deleted)"
32533+ seq->count -= sizeof(Deleted) - 1;
32534+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
32535+ sizeof(Deleted) - 1));
32536+#undef Deleted
32537+
32538+out:
32539+ return err;
32540+}
537831f9
AM
32541diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
32542--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
fb47a38f 32543+++ linux/include/uapi/linux/aufs_type.h 2014-04-24 22:11:10.935269950 +0200
523b37e3 32544@@ -0,0 +1,281 @@
7f207e10 32545+/*
523b37e3 32546+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
32547+ *
32548+ * This program, aufs is free software; you can redistribute it and/or modify
32549+ * it under the terms of the GNU General Public License as published by
32550+ * the Free Software Foundation; either version 2 of the License, or
32551+ * (at your option) any later version.
32552+ *
32553+ * This program is distributed in the hope that it will be useful,
32554+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32555+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32556+ * GNU General Public License for more details.
32557+ *
32558+ * You should have received a copy of the GNU General Public License
523b37e3 32559+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
32560+ */
32561+
32562+#ifndef __AUFS_TYPE_H__
32563+#define __AUFS_TYPE_H__
32564+
f6c5ef8b
AM
32565+#define AUFS_NAME "aufs"
32566+
9dbd164d 32567+#ifdef __KERNEL__
f6c5ef8b
AM
32568+/*
32569+ * define it before including all other headers.
32570+ * sched.h may use pr_* macros before defining "current", so define the
32571+ * no-current version first, and re-define later.
32572+ */
32573+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
32574+#include <linux/sched.h>
32575+#undef pr_fmt
a2a7ad62
AM
32576+#define pr_fmt(fmt) \
32577+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
32578+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
32579+#else
32580+#include <stdint.h>
32581+#include <sys/types.h>
f6c5ef8b 32582+#endif /* __KERNEL__ */
7f207e10 32583+
f6c5ef8b
AM
32584+#include <linux/limits.h>
32585+
fb47a38f 32586+#define AUFS_VERSION "3.14-20140407"
7f207e10
AM
32587+
32588+/* todo? move this to linux-2.6.19/include/magic.h */
32589+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
32590+
32591+/* ---------------------------------------------------------------------- */
32592+
32593+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 32594+typedef int8_t aufs_bindex_t;
7f207e10
AM
32595+#define AUFS_BRANCH_MAX 127
32596+#else
9dbd164d 32597+typedef int16_t aufs_bindex_t;
7f207e10
AM
32598+#ifdef CONFIG_AUFS_BRANCH_MAX_511
32599+#define AUFS_BRANCH_MAX 511
32600+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
32601+#define AUFS_BRANCH_MAX 1023
32602+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
32603+#define AUFS_BRANCH_MAX 32767
32604+#endif
32605+#endif
32606+
32607+#ifdef __KERNEL__
32608+#ifndef AUFS_BRANCH_MAX
32609+#error unknown CONFIG_AUFS_BRANCH_MAX value
32610+#endif
32611+#endif /* __KERNEL__ */
32612+
32613+/* ---------------------------------------------------------------------- */
32614+
7f207e10
AM
32615+#define AUFS_FSTYPE AUFS_NAME
32616+
32617+#define AUFS_ROOT_INO 2
32618+#define AUFS_FIRST_INO 11
32619+
32620+#define AUFS_WH_PFX ".wh."
32621+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
32622+#define AUFS_WH_TMP_LEN 4
86dc4139 32623+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
32624+#define AUFS_MAX_NAMELEN (NAME_MAX \
32625+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
32626+ - 1 /* dot */\
32627+ - AUFS_WH_TMP_LEN) /* hex */
32628+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
32629+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
32630+#define AUFS_XINO_DEF_SEC 30 /* seconds */
32631+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
32632+#define AUFS_DIRWH_DEF 3
32633+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 32634+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
32635+#define AUFS_RDBLK_DEF 512 /* bytes */
32636+#define AUFS_RDHASH_DEF 32
32637+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
32638+#define AUFS_MFS_DEF_SEC 30 /* seconds */
32639+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
86dc4139 32640+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
32641+
32642+/* pseudo-link maintenace under /proc */
32643+#define AUFS_PLINK_MAINT_NAME "plink_maint"
32644+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
32645+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
32646+
32647+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
32648+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
32649+
32650+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
32651+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
32652+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
32653+
32654+/* doubly whiteouted */
32655+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
32656+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
32657+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
32658+
1e00d052 32659+/* branch permissions and attributes */
7f207e10
AM
32660+#define AUFS_BRPERM_RW "rw"
32661+#define AUFS_BRPERM_RO "ro"
32662+#define AUFS_BRPERM_RR "rr"
1e00d052
AM
32663+#define AUFS_BRRATTR_WH "wh"
32664+#define AUFS_BRWATTR_NLWH "nolwh"
86dc4139 32665+#define AUFS_BRATTR_UNPIN "unpin"
7f207e10
AM
32666+
32667+/* ---------------------------------------------------------------------- */
32668+
32669+/* ioctl */
32670+enum {
32671+ /* readdir in userspace */
32672+ AuCtl_RDU,
32673+ AuCtl_RDU_INO,
32674+
32675+ /* pathconf wrapper */
027c5e7a
AM
32676+ AuCtl_WBR_FD,
32677+
32678+ /* busy inode */
c2b27bf2
AM
32679+ AuCtl_IBUSY,
32680+
32681+ /* move-down */
32682+ AuCtl_MVDOWN
7f207e10
AM
32683+};
32684+
32685+/* borrowed from linux/include/linux/kernel.h */
32686+#ifndef ALIGN
32687+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
32688+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
32689+#endif
32690+
32691+/* borrowed from linux/include/linux/compiler-gcc3.h */
32692+#ifndef __aligned
32693+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
32694+#endif
32695+
32696+#ifdef __KERNEL__
32697+#ifndef __packed
7f207e10
AM
32698+#define __packed __attribute__((packed))
32699+#endif
53392da6 32700+#endif
7f207e10
AM
32701+
32702+struct au_rdu_cookie {
9dbd164d
AM
32703+ uint64_t h_pos;
32704+ int16_t bindex;
32705+ uint8_t flags;
32706+ uint8_t pad;
32707+ uint32_t generation;
7f207e10
AM
32708+} __aligned(8);
32709+
32710+struct au_rdu_ent {
9dbd164d
AM
32711+ uint64_t ino;
32712+ int16_t bindex;
32713+ uint8_t type;
32714+ uint8_t nlen;
32715+ uint8_t wh;
7f207e10
AM
32716+ char name[0];
32717+} __aligned(8);
32718+
32719+static inline int au_rdu_len(int nlen)
32720+{
32721+ /* include the terminating NULL */
32722+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 32723+ sizeof(uint64_t));
7f207e10
AM
32724+}
32725+
32726+union au_rdu_ent_ul {
32727+ struct au_rdu_ent __user *e;
9dbd164d 32728+ uint64_t ul;
7f207e10
AM
32729+};
32730+
32731+enum {
32732+ AufsCtlRduV_SZ,
32733+ AufsCtlRduV_End
32734+};
32735+
32736+struct aufs_rdu {
32737+ /* input */
32738+ union {
9dbd164d
AM
32739+ uint64_t sz; /* AuCtl_RDU */
32740+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
32741+ };
32742+ union au_rdu_ent_ul ent;
9dbd164d 32743+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
32744+
32745+ /* input/output */
9dbd164d 32746+ uint32_t blk;
7f207e10
AM
32747+
32748+ /* output */
32749+ union au_rdu_ent_ul tail;
32750+ /* number of entries which were added in a single call */
9dbd164d
AM
32751+ uint64_t rent;
32752+ uint8_t full;
32753+ uint8_t shwh;
7f207e10
AM
32754+
32755+ struct au_rdu_cookie cookie;
32756+} __aligned(8);
32757+
1e00d052
AM
32758+/* ---------------------------------------------------------------------- */
32759+
32760+struct aufs_wbr_fd {
9dbd164d
AM
32761+ uint32_t oflags;
32762+ int16_t brid;
1e00d052
AM
32763+} __aligned(8);
32764+
32765+/* ---------------------------------------------------------------------- */
32766+
027c5e7a 32767+struct aufs_ibusy {
9dbd164d
AM
32768+ uint64_t ino, h_ino;
32769+ int16_t bindex;
027c5e7a
AM
32770+} __aligned(8);
32771+
1e00d052
AM
32772+/* ---------------------------------------------------------------------- */
32773+
392086de
AM
32774+/* error code for move-down */
32775+/* the actual message strings are implemented in aufs-util.git */
32776+enum {
32777+ EAU_MVDOWN_OPAQUE = 1,
32778+ EAU_MVDOWN_WHITEOUT,
32779+ EAU_MVDOWN_UPPER,
32780+ EAU_MVDOWN_BOTTOM,
32781+ EAU_MVDOWN_NOUPPER,
32782+ EAU_MVDOWN_NOLOWERBR,
32783+ EAU_Last
32784+};
32785+
c2b27bf2 32786+/* flags for move-down */
392086de
AM
32787+#define AUFS_MVDOWN_DMSG 1
32788+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
32789+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
32790+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
32791+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
32792+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
32793+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
32794+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
32795+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
c2b27bf2
AM
32796+/* will be added more */
32797+
392086de
AM
32798+enum {
32799+ AUFS_MVDOWN_UPPER,
32800+ AUFS_MVDOWN_LOWER,
32801+ AUFS_MVDOWN_NARRAY
32802+};
32803+
c2b27bf2 32804+struct aufs_mvdown {
392086de
AM
32805+ uint32_t flags;
32806+ struct {
32807+ int16_t bindex;
32808+ int16_t brid;
32809+ } a[AUFS_MVDOWN_NARRAY];
32810+ int8_t au_errno;
c2b27bf2
AM
32811+ /* will be added more */
32812+} __aligned(8);
32813+
32814+/* ---------------------------------------------------------------------- */
32815+
7f207e10
AM
32816+#define AuCtlType 'A'
32817+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
32818+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
32819+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
32820+ struct aufs_wbr_fd)
027c5e7a 32821+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
32822+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
32823+ struct aufs_mvdown)
7f207e10
AM
32824+
32825+#endif /* __AUFS_TYPE_H__ */
93a1a2a2
JR
32826aufs3.14 loopback patch
32827
32828diff --git a/drivers/block/loop.c b/drivers/block/loop.c
32829index ec278ac..1894990 100644
32830--- a/drivers/block/loop.c
32831+++ b/drivers/block/loop.c
32832@@ -514,7 +514,7 @@ out:
32833 }
32834
32835 struct switch_request {
32836- struct file *file;
32837+ struct file *file, *virt_file;
32838 struct completion wait;
32839 };
32840
32841@@ -576,7 +576,8 @@ static int loop_thread(void *data)
32842 * First it needs to flush existing IO, it does this by sending a magic
32843 * BIO down the pipe. The completion of this BIO does the actual switch.
32844 */
32845-static int loop_switch(struct loop_device *lo, struct file *file)
32846+static int loop_switch(struct loop_device *lo, struct file *file,
32847+ struct file *virt_file)
32848 {
32849 struct switch_request w;
32850 struct bio *bio = bio_alloc(GFP_KERNEL, 0);
32851@@ -584,6 +585,7 @@ static int loop_switch(struct loop_device *lo, struct file *file)
32852 return -ENOMEM;
32853 init_completion(&w.wait);
32854 w.file = file;
32855+ w.virt_file = virt_file;
32856 bio->bi_private = &w;
32857 bio->bi_bdev = NULL;
32858 loop_make_request(lo->lo_queue, bio);
32859@@ -600,7 +602,7 @@ static int loop_flush(struct loop_device *lo)
32860 if (!lo->lo_thread)
32861 return 0;
32862
32863- return loop_switch(lo, NULL);
32864+ return loop_switch(lo, NULL, NULL);
32865 }
32866
32867 /*
32868@@ -619,6 +621,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
32869 mapping = file->f_mapping;
32870 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
32871 lo->lo_backing_file = file;
32872+ lo->lo_backing_virt_file = p->virt_file;
32873 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
32874 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
32875 lo->old_gfp_mask = mapping_gfp_mask(mapping);
32876@@ -627,6 +630,13 @@ out:
32877 complete(&p->wait);
32878 }
32879
32880+static struct file *loop_real_file(struct file *file)
32881+{
32882+ struct file *f = NULL;
32883+ if (file->f_dentry->d_sb->s_op->real_loop)
32884+ f = file->f_dentry->d_sb->s_op->real_loop(file);
32885+ return f;
32886+}
32887
32888 /*
32889 * loop_change_fd switched the backing store of a loopback device to
32890@@ -640,6 +650,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
32891 unsigned int arg)
32892 {
32893 struct file *file, *old_file;
32894+ struct file *f, *virt_file = NULL, *old_virt_file;
32895 struct inode *inode;
32896 int error;
32897
32898@@ -656,9 +667,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
32899 file = fget(arg);
32900 if (!file)
32901 goto out;
32902+ f = loop_real_file(file);
32903+ if (f) {
32904+ virt_file = file;
32905+ file = f;
32906+ get_file(file);
32907+ }
32908
32909 inode = file->f_mapping->host;
32910 old_file = lo->lo_backing_file;
32911+ old_virt_file = lo->lo_backing_virt_file;
32912
32913 error = -EINVAL;
32914
32915@@ -670,17 +688,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
32916 goto out_putf;
32917
32918 /* and ... switch */
32919- error = loop_switch(lo, file);
32920+ error = loop_switch(lo, file, virt_file);
32921 if (error)
32922 goto out_putf;
32923
32924 fput(old_file);
32925+ if (old_virt_file)
32926+ fput(old_virt_file);
32927 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
32928 ioctl_by_bdev(bdev, BLKRRPART, 0);
32929 return 0;
32930
32931 out_putf:
32932 fput(file);
32933+ if (virt_file)
32934+ fput(virt_file);
32935 out:
32936 return error;
32937 }
32938@@ -841,7 +863,7 @@ static void loop_config_discard(struct loop_device *lo)
32939 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
32940 struct block_device *bdev, unsigned int arg)
32941 {
32942- struct file *file, *f;
32943+ struct file *file, *f, *virt_file = NULL;
32944 struct inode *inode;
32945 struct address_space *mapping;
32946 unsigned lo_blocksize;
32947@@ -856,6 +878,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
32948 file = fget(arg);
32949 if (!file)
32950 goto out;
32951+ f = loop_real_file(file);
32952+ if (f) {
32953+ virt_file = file;
32954+ file = f;
32955+ get_file(file);
32956+ }
32957
32958 error = -EBUSY;
32959 if (lo->lo_state != Lo_unbound)
32960@@ -904,6 +932,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
32961 lo->lo_device = bdev;
32962 lo->lo_flags = lo_flags;
32963 lo->lo_backing_file = file;
32964+ lo->lo_backing_virt_file = virt_file;
32965 lo->transfer = transfer_none;
32966 lo->ioctl = NULL;
32967 lo->lo_sizelimit = 0;
32968@@ -948,6 +977,7 @@ out_clr:
32969 lo->lo_thread = NULL;
32970 lo->lo_device = NULL;
32971 lo->lo_backing_file = NULL;
32972+ lo->lo_backing_virt_file = NULL;
32973 lo->lo_flags = 0;
32974 set_capacity(lo->lo_disk, 0);
32975 invalidate_bdev(bdev);
32976@@ -957,6 +987,8 @@ out_clr:
32977 lo->lo_state = Lo_unbound;
32978 out_putf:
32979 fput(file);
32980+ if (virt_file)
32981+ fput(virt_file);
32982 out:
32983 /* This is safe: open() is still holding a reference. */
32984 module_put(THIS_MODULE);
32985@@ -1003,6 +1035,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
32986 static int loop_clr_fd(struct loop_device *lo)
32987 {
32988 struct file *filp = lo->lo_backing_file;
32989+ struct file *virt_filp = lo->lo_backing_virt_file;
32990 gfp_t gfp = lo->old_gfp_mask;
32991 struct block_device *bdev = lo->lo_device;
32992
32993@@ -1036,6 +1069,7 @@ static int loop_clr_fd(struct loop_device *lo)
32994
32995 spin_lock_irq(&lo->lo_lock);
32996 lo->lo_backing_file = NULL;
32997+ lo->lo_backing_virt_file = NULL;
32998 spin_unlock_irq(&lo->lo_lock);
32999
33000 loop_release_xfer(lo);
33001@@ -1078,6 +1112,8 @@ static int loop_clr_fd(struct loop_device *lo)
33002 * bd_mutex which is usually taken before lo_ctl_mutex.
33003 */
33004 fput(filp);
33005+ if (virt_filp)
33006+ fput(virt_filp);
33007 return 0;
33008 }
33009
33010diff --git a/drivers/block/loop.h b/drivers/block/loop.h
33011index 90df5d6..cb91822 100644
33012--- a/drivers/block/loop.h
33013+++ b/drivers/block/loop.h
33014@@ -44,7 +44,7 @@ struct loop_device {
33015 int (*ioctl)(struct loop_device *, int cmd,
33016 unsigned long arg);
33017
33018- struct file * lo_backing_file;
33019+ struct file * lo_backing_file, *lo_backing_virt_file;
33020 struct block_device *lo_device;
33021 unsigned lo_blocksize;
33022 void *key_data;
33023diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
33024index 2e0302d..b35af58 100644
33025--- a/fs/aufs/f_op.c
33026+++ b/fs/aufs/f_op.c
33027@@ -337,7 +337,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
33028 err = -EINVAL;
33029 h_file = au_hf_top(file);
33030 get_file(h_file);
33031- if (au_test_loopback_kthread()) {
33032+ if (0 && au_test_loopback_kthread()) {
33033 au_warn_loopback(h_file->f_dentry->d_sb);
33034 if (file->f_mapping != h_file->f_mapping) {
33035 file->f_mapping = h_file->f_mapping;
33036diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
33037index 3b03b52..4ab749d 100644
33038--- a/fs/aufs/loop.c
33039+++ b/fs/aufs/loop.c
33040@@ -130,3 +130,19 @@ void au_loopback_fin(void)
33041 symbol_put(loop_backing_file);
33042 kfree(au_warn_loopback_array);
33043 }
33044+
33045+/* ---------------------------------------------------------------------- */
33046+
33047+/* support the loopback block device insude aufs */
33048+
33049+struct file *aufs_real_loop(struct file *file)
33050+{
33051+ struct file *f;
33052+
33053+ BUG_ON(!au_test_aufs(file->f_dentry->d_sb));
33054+ fi_read_lock(file);
33055+ f = au_hf_top(file);
33056+ fi_read_unlock(file);
33057+ AuDebugOn(!f);
33058+ return f;
33059+}
33060diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
33061index da8b756..28cb7ea 100644
33062--- a/fs/aufs/loop.h
33063+++ b/fs/aufs/loop.h
33064@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
33065
33066 int au_loopback_init(void);
33067 void au_loopback_fin(void);
33068+
33069+struct file *aufs_real_loop(struct file *file);
33070 #else
33071+AuStub(struct file *, loop_backing_file, return NULL)
33072+
33073 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
33074 struct dentry *h_adding)
33075 AuStubInt0(au_test_loopback_kthread, void)
33076@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
33077
33078 AuStubInt0(au_loopback_init, void)
33079 AuStubVoid(au_loopback_fin, void)
33080+
33081+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
33082 #endif /* BLK_DEV_LOOP */
33083
33084 #endif /* __KERNEL__ */
33085diff --git a/fs/aufs/super.c b/fs/aufs/super.c
33086index b609e5a..e3909ed 100644
33087--- a/fs/aufs/super.c
33088+++ b/fs/aufs/super.c
33089@@ -807,7 +807,10 @@ static const struct super_operations aufs_sop = {
33090 .statfs = aufs_statfs,
33091 .put_super = aufs_put_super,
33092 .sync_fs = aufs_sync_fs,
33093- .remount_fs = aufs_remount_fs
33094+ .remount_fs = aufs_remount_fs,
33095+#ifdef CONFIG_AUFS_BDEV_LOOP
33096+ .real_loop = aufs_real_loop
33097+#endif
33098 };
33099
33100 /* ---------------------------------------------------------------------- */
33101diff --git a/include/linux/fs.h b/include/linux/fs.h
33102index f3f635c..c4308ca 100644
33103--- a/include/linux/fs.h
33104+++ b/include/linux/fs.h
33105@@ -1626,6 +1626,10 @@ struct super_operations {
33106 int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
33107 long (*nr_cached_objects)(struct super_block *, int);
33108 long (*free_cached_objects)(struct super_block *, long, int);
33109+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
33110+ /* and aufs */
33111+ struct file *(*real_loop)(struct file *);
33112+#endif
33113 };
33114
33115 /*
This page took 6.881742 seconds and 4 git commands to generate.