]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- started update to 3.17
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
076b876e 1aufs3.16 kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
38d290e6 4index 312393f..78632ed 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
38d290e6 7@@ -209,6 +209,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
076b876e 16index 4030cbf..5bd169a 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
076b876e 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
076b876e 25index 24e9033..fe9a8d4 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
076b876e 36aufs3.16 base patch
7f207e10 37
392086de 38diff --git a/drivers/block/loop.c b/drivers/block/loop.c
076b876e 39index 6cb1beb..30efd68 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
076b876e 68index 6eecb7f..b225c0f 100644
0c3ec466
AM
69--- a/fs/inode.c
70+++ b/fs/inode.c
38d290e6 71@@ -1496,7 +1496,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
076b876e 81index f5cb9ba..9ba380c 100644
7f207e10
AM
82--- a/fs/splice.c
83+++ b/fs/splice.c
076b876e 84@@ -1114,8 +1114,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);
076b876e 95@@ -1131,9 +1131,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
076b876e 109index e11d60c..2f32b35 100644
0c3ec466
AM
110--- a/include/linux/fs.h
111+++ b/include/linux/fs.h
076b876e 112@@ -2618,6 +2618,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
076b876e 121index da2751d..2e0fca6 100644
1e00d052
AM
122--- a/include/linux/splice.h
123+++ b/include/linux/splice.h
076b876e 124@@ -83,4 +83,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
076b876e 135aufs3.16 mmap patch
fb47a38f
JR
136
137diff --git a/fs/buffer.c b/fs/buffer.c
076b876e 138index eba6e4f..31f0b2d 100644
fb47a38f
JR
139--- a/fs/buffer.c
140+++ b/fs/buffer.c
076b876e 141@@ -2460,7 +2460,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
fb47a38f
JR
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
076b876e 151index d4a3574..1397181 100644
fb47a38f
JR
152--- a/fs/proc/nommu.c
153+++ b/fs/proc/nommu.c
076b876e 154@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
fb47a38f
JR
155 file = region->vm_file;
156
157 if (file) {
158- struct inode *inode = file_inode(region->vm_file);
159+ struct inode *inode;
076b876e 160+
fb47a38f
JR
161+ file = vmr_pr_or_file(region);
162+ inode = file_inode(file);
163 dev = inode->i_sb->s_dev;
164 ino = inode->i_ino;
165 }
166diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
076b876e 167index cfa63ee..bf4919e 100644
fb47a38f
JR
168--- a/fs/proc/task_mmu.c
169+++ b/fs/proc/task_mmu.c
076b876e 170@@ -265,7 +265,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
fb47a38f
JR
171 const char *name = NULL;
172
173 if (file) {
174- struct inode *inode = file_inode(vma->vm_file);
175+ struct inode *inode;
076b876e 176+
fb47a38f
JR
177+ file = vma_pr_or_file(vma);
178+ inode = file_inode(file);
179 dev = inode->i_sb->s_dev;
180 ino = inode->i_ino;
181 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
076b876e
AM
182@@ -1390,7 +1393,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
183 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
184 struct vm_area_struct *vma = v;
185 struct numa_maps *md = &numa_priv->md;
186- struct file *file = vma->vm_file;
187+ struct file *file = vma_pr_or_file(vma);
188 struct task_struct *task = proc_priv->task;
189 struct mm_struct *mm = vma->vm_mm;
190 struct mm_walk walk = {};
fb47a38f 191diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
076b876e 192index 678455d..0ef7ef4 100644
fb47a38f
JR
193--- a/fs/proc/task_nommu.c
194+++ b/fs/proc/task_nommu.c
076b876e 195@@ -141,7 +141,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
fb47a38f
JR
196 file = vma->vm_file;
197
198 if (file) {
199- struct inode *inode = file_inode(vma->vm_file);
200+ struct inode *inode;
076b876e 201+
fb47a38f
JR
202+ file = vma_pr_or_file(file);
203+ inode = file_inode(file);
204 dev = inode->i_sb->s_dev;
205 ino = inode->i_ino;
206 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
207diff --git a/include/linux/mm.h b/include/linux/mm.h
076b876e 208index e03dd29..dd32624 100644
fb47a38f
JR
209--- a/include/linux/mm.h
210+++ b/include/linux/mm.h
076b876e 211@@ -1184,6 +1184,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
fb47a38f
JR
212 }
213 #endif
214
076b876e
AM
215+#ifdef CONFIG_MMU
216+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
217+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
218+ int);
219+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
220+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
fb47a38f 221+
fb47a38f
JR
222+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
223+ __LINE__)
224+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
225+ __LINE__)
226+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
227+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
076b876e
AM
228+#else
229+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
230+extern void vmr_do_fput(struct vm_region *, const char[], int);
231+
232+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
233+ __LINE__)
234+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
235+#endif /* CONFIG_MMU */
fb47a38f
JR
236+
237 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
238 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
239 void *buf, int len, int write);
240diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
076b876e 241index 96c5750..a087ecd 100644
fb47a38f
JR
242--- a/include/linux/mm_types.h
243+++ b/include/linux/mm_types.h
38d290e6 244@@ -232,6 +232,7 @@ struct vm_region {
fb47a38f
JR
245 unsigned long vm_top; /* region allocated to here */
246 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
247 struct file *vm_file; /* the backing file or NULL */
248+ struct file *vm_prfile; /* the virtual backing file or NULL */
249
250 int vm_usage; /* region usage count (access under nommu_region_sem) */
251 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
38d290e6 252@@ -300,6 +301,7 @@ struct vm_area_struct {
fb47a38f
JR
253 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
254 units, *not* PAGE_CACHE_SIZE */
255 struct file * vm_file; /* File we map to (can be NULL). */
256+ struct file *vm_prfile; /* shadow of vm_file */
257 void * vm_private_data; /* was vm_pte (shared mem) */
258
259 #ifndef CONFIG_MMU
260diff --git a/kernel/fork.c b/kernel/fork.c
076b876e 261index 6a13c46..714302c 100644
fb47a38f
JR
262--- a/kernel/fork.c
263+++ b/kernel/fork.c
38d290e6 264@@ -416,7 +416,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
fb47a38f
JR
265 struct inode *inode = file_inode(file);
266 struct address_space *mapping = file->f_mapping;
267
268- get_file(file);
269+ vma_get_file(tmp);
270 if (tmp->vm_flags & VM_DENYWRITE)
271 atomic_dec(&inode->i_writecount);
272 mutex_lock(&mapping->i_mmap_mutex);
076b876e
AM
273diff --git a/mm/Makefile b/mm/Makefile
274index 4064f3e..0003fdf 100644
275--- a/mm/Makefile
276+++ b/mm/Makefile
277@@ -18,7 +18,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \
278 mm_init.o mmu_context.o percpu.o slab_common.o \
279 compaction.o balloon_compaction.o vmacache.o \
280 interval_tree.o list_lru.o workingset.o \
281- iov_iter.o $(mmu-y)
282+ iov_iter.o prfile.o $(mmu-y)
283
284 obj-y += init-mm.o
285
fb47a38f 286diff --git a/mm/filemap.c b/mm/filemap.c
076b876e 287index 900edfa..f4dda0c 100644
fb47a38f
JR
288--- a/mm/filemap.c
289+++ b/mm/filemap.c
076b876e 290@@ -2040,7 +2040,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
fb47a38f
JR
291 int ret = VM_FAULT_LOCKED;
292
293 sb_start_pagefault(inode->i_sb);
294- file_update_time(vma->vm_file);
295+ vma_file_update_time(vma);
296 lock_page(page);
297 if (page->mapping != inode->i_mapping) {
298 unlock_page(page);
299diff --git a/mm/fremap.c b/mm/fremap.c
076b876e 300index 72b8fa3..a00bbf0 100644
fb47a38f
JR
301--- a/mm/fremap.c
302+++ b/mm/fremap.c
076b876e 303@@ -224,16 +224,28 @@ get_write_lock:
38d290e6
JR
304 */
305 if (mapping_cap_account_dirty(mapping)) {
306 unsigned long addr;
307- struct file *file = get_file(vma->vm_file);
308+ struct file *file = vma->vm_file,
309+ *prfile = vma->vm_prfile;
310+
fb47a38f
JR
311 /* mmap_region may free vma; grab the info now */
312 vm_flags = vma->vm_flags;
313
314+ vma_get_file(vma);
315 addr = mmap_region(file, start, size, vm_flags, pgoff);
38d290e6 316- fput(file);
fb47a38f 317+ vma_fput(vma);
fb47a38f
JR
318 if (IS_ERR_VALUE(addr)) {
319 err = addr;
38d290e6
JR
320 } else {
321 BUG_ON(addr != start);
322+ if (prfile) {
323+ struct vm_area_struct *new_vma;
076b876e 324+
38d290e6
JR
325+ new_vma = find_vma(mm, addr);
326+ if (!new_vma->vm_prfile)
327+ new_vma->vm_prfile = prfile;
328+ if (new_vma != vma)
329+ get_file(prfile);
330+ }
331 err = 0;
332 }
333 goto out_freed;
fb47a38f 334diff --git a/mm/madvise.c b/mm/madvise.c
38d290e6 335index a402f8f..134e15d 100644
fb47a38f
JR
336--- a/mm/madvise.c
337+++ b/mm/madvise.c
338@@ -327,12 +327,12 @@ static long madvise_remove(struct vm_area_struct *vma,
339 * vma's reference to the file) can go away as soon as we drop
340 * mmap_sem.
341 */
342- get_file(f);
343+ vma_get_file(vma);
344 up_read(&current->mm->mmap_sem);
345 error = do_fallocate(f,
346 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
347 offset, end - start);
348- fput(f);
349+ vma_fput(vma);
350 down_read(&current->mm->mmap_sem);
351 return error;
352 }
353diff --git a/mm/memory.c b/mm/memory.c
076b876e 354index 8b44f76..69a72bf 100644
fb47a38f
JR
355--- a/mm/memory.c
356+++ b/mm/memory.c
076b876e 357@@ -2161,7 +2161,7 @@ reuse:
38d290e6 358 set_page_dirty_balance(dirty_page);
fb47a38f
JR
359 /* file_update_time outside page_lock */
360 if (vma->vm_file)
361- file_update_time(vma->vm_file);
362+ vma_file_update_time(vma);
363 }
364 put_page(dirty_page);
365 if (page_mkwrite) {
fb47a38f 366diff --git a/mm/mmap.c b/mm/mmap.c
076b876e 367index 129b847..869d1d7 100644
fb47a38f
JR
368--- a/mm/mmap.c
369+++ b/mm/mmap.c
076b876e 370@@ -253,7 +253,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
fb47a38f
JR
371 if (vma->vm_ops && vma->vm_ops->close)
372 vma->vm_ops->close(vma);
373 if (vma->vm_file)
374- fput(vma->vm_file);
375+ vma_fput(vma);
376 mpol_put(vma_policy(vma));
377 kmem_cache_free(vm_area_cachep, vma);
378 return next;
076b876e 379@@ -863,7 +863,7 @@ again: remove_next = 1 + (end > next->vm_end);
fb47a38f
JR
380 if (remove_next) {
381 if (file) {
382 uprobe_munmap(next, next->vm_start, next->vm_end);
383- fput(file);
384+ vma_fput(vma);
385 }
386 if (next->anon_vma)
387 anon_vma_merge(vma, next);
076b876e 388@@ -1643,8 +1643,8 @@ out:
35939ee7
JR
389 return addr;
390
fb47a38f 391 unmap_and_free_vma:
fb47a38f
JR
392+ vma_fput(vma);
393 vma->vm_file = NULL;
394- fput(file);
395
396 /* Undo any partial mapping done by a device driver. */
397 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
076b876e 398@@ -2434,7 +2434,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
fb47a38f
JR
399 goto out_free_mpol;
400
401 if (new->vm_file)
402- get_file(new->vm_file);
403+ vma_get_file(new);
404
405 if (new->vm_ops && new->vm_ops->open)
406 new->vm_ops->open(new);
076b876e 407@@ -2453,7 +2453,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
fb47a38f
JR
408 if (new->vm_ops && new->vm_ops->close)
409 new->vm_ops->close(new);
410 if (new->vm_file)
411- fput(new->vm_file);
412+ vma_fput(new);
413 unlink_anon_vmas(new);
414 out_free_mpol:
415 mpol_put(vma_policy(new));
076b876e 416@@ -2842,7 +2842,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
fb47a38f
JR
417 if (anon_vma_clone(new_vma, vma))
418 goto out_free_mempol;
419 if (new_vma->vm_file)
420- get_file(new_vma->vm_file);
421+ vma_get_file(new_vma);
422 if (new_vma->vm_ops && new_vma->vm_ops->open)
423 new_vma->vm_ops->open(new_vma);
424 vma_link(mm, new_vma, prev, rb_link, rb_parent);
425diff --git a/mm/msync.c b/mm/msync.c
076b876e 426index 992a167..ce1915b 100644
fb47a38f
JR
427--- a/mm/msync.c
428+++ b/mm/msync.c
076b876e 429@@ -84,13 +84,13 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
fb47a38f
JR
430 start = vma->vm_end;
431 if ((flags & MS_SYNC) && file &&
432 (vma->vm_flags & VM_SHARED)) {
433- get_file(file);
434+ vma_get_file(vma);
435 up_read(&mm->mmap_sem);
076b876e
AM
436 if (vma->vm_flags & VM_NONLINEAR)
437 error = vfs_fsync(file, 1);
438 else
439 error = vfs_fsync_range(file, fstart, fend, 1);
fb47a38f
JR
440- fput(file);
441+ vma_fput(vma);
442 if (error || start >= end)
443 goto out;
444 down_read(&mm->mmap_sem);
445diff --git a/mm/nommu.c b/mm/nommu.c
076b876e 446index 4a852f6..b369644 100644
fb47a38f
JR
447--- a/mm/nommu.c
448+++ b/mm/nommu.c
076b876e 449@@ -658,7 +658,7 @@ static void __put_nommu_region(struct vm_region *region)
fb47a38f
JR
450 up_write(&nommu_region_sem);
451
452 if (region->vm_file)
453- fput(region->vm_file);
454+ vmr_fput(region);
455
456 /* IO memory and memory shared directly out of the pagecache
457 * from ramfs/tmpfs mustn't be released here */
076b876e 458@@ -823,7 +823,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
fb47a38f
JR
459 if (vma->vm_ops && vma->vm_ops->close)
460 vma->vm_ops->close(vma);
461 if (vma->vm_file)
462- fput(vma->vm_file);
463+ vma_fput(vma);
464 put_nommu_region(vma->vm_region);
465 kmem_cache_free(vm_area_cachep, vma);
466 }
076b876e 467@@ -1385,7 +1385,7 @@ unsigned long do_mmap_pgoff(struct file *file,
fb47a38f
JR
468 goto error_just_free;
469 }
470 }
471- fput(region->vm_file);
472+ vmr_fput(region);
473 kmem_cache_free(vm_region_jar, region);
474 region = pregion;
475 result = start;
076b876e 476@@ -1461,10 +1461,10 @@ error_just_free:
fb47a38f
JR
477 up_write(&nommu_region_sem);
478 error:
479 if (region->vm_file)
480- fput(region->vm_file);
481+ vmr_fput(region);
482 kmem_cache_free(vm_region_jar, region);
483 if (vma->vm_file)
484- fput(vma->vm_file);
485+ vma_fput(vma);
486 kmem_cache_free(vm_area_cachep, vma);
487 kleave(" = %d", ret);
488 return ret;
076b876e
AM
489diff --git a/mm/prfile.c b/mm/prfile.c
490new file mode 100644
491index 0000000..fc708d2
492--- /dev/null
493+++ b/mm/prfile.c
494@@ -0,0 +1,86 @@
495+/*
496+ * Mainly for aufs which mmap(2) diffrent file and wants to print different path
497+ * in /proc/PID/maps.
498+ * Call these functions via macros defined in linux/mm.h.
499+ *
500+ * See Documentation/filesystems/aufs/design/06mmap.txt
501+ *
502+ * Copyright (c) 2014 Junjro R. Okajima
503+ * Copyright (c) 2014 Ian Campbell
504+ */
505+
506+#include <linux/mm.h>
507+#include <linux/file.h>
508+#include <linux/fs.h>
509+
510+/* #define PRFILE_TRACE */
511+static inline void prfile_trace(struct file *f, struct file *pr,
512+ const char func[], int line, const char func2[])
513+{
514+#ifdef PRFILE_TRACE
515+ if (pr)
516+ pr_info("%s:%d: %s, %p\n", func, line, func2,
517+ f ? (char *)f->f_dentry->d_name.name : "(null)");
518+#endif
519+}
520+
521+#ifdef CONFIG_MMU
522+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
523+ int line)
524+{
525+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
526+
527+ prfile_trace(f, pr, func, line, __func__);
528+ file_update_time(f);
529+ if (f && pr)
530+ file_update_time(pr);
531+}
532+
533+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
534+ int line)
535+{
536+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
537+
538+ prfile_trace(f, pr, func, line, __func__);
539+ return (f && pr) ? pr : f;
540+}
541+
542+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
543+{
544+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
545+
546+ prfile_trace(f, pr, func, line, __func__);
547+ get_file(f);
548+ if (f && pr)
549+ get_file(pr);
550+}
551+
552+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
553+{
554+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
555+
556+ prfile_trace(f, pr, func, line, __func__);
557+ fput(f);
558+ if (f && pr)
559+ fput(pr);
560+}
561+#else
562+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
563+ int line)
564+{
565+ struct file *f = region->vm_file, *pr = region->vm_prfile;
566+
567+ prfile_trace(f, pr, func, line, __func__);
568+ return (f && pr) ? pr : f;
569+}
570+
571+void vmr_do_fput(struct vm_region *region, const char func[], int line)
572+{
573+ struct file *f = region->vm_file, *pr = region->vm_prfile;
574+
575+ prfile_trace(f, pr, func, line, __func__);
576+ fput(f);
577+ if (f && pr)
578+ fput(pr);
579+}
580+#endif /* CONFIG_MMU */
581aufs3.16 standalone patch
7f207e10 582
1e00d052 583diff --git a/fs/inode.c b/fs/inode.c
076b876e 584index b225c0f..73259c8 100644
1e00d052
AM
585--- a/fs/inode.c
586+++ b/fs/inode.c
392086de 587@@ -57,6 +57,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
4b3da204 588 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
2cbb1c4b
JR
589
590 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
2cbb1c4b 591+EXPORT_SYMBOL(inode_sb_list_lock);
7f207e10
AM
592
593 /*
4b3da204 594 * Empty aops. Can be used for the cases where the user does not
38d290e6 595@@ -1512,6 +1513,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
0c3ec466
AM
596 mark_inode_dirty_sync(inode);
597 return 0;
598 }
599+EXPORT_SYMBOL(update_time);
600
601 /**
602 * touch_atime - update the access time
7f207e10 603diff --git a/fs/namespace.c b/fs/namespace.c
38d290e6 604index 182bc41..c88e101 100644
7f207e10
AM
605--- a/fs/namespace.c
606+++ b/fs/namespace.c
38d290e6 607@@ -453,6 +453,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
608 mnt_dec_writers(real_mount(mnt));
609 preempt_enable();
610 }
611+EXPORT_SYMBOL_GPL(__mnt_drop_write);
612
613 /**
614 * mnt_drop_write - give up write access to a mount
38d290e6 615@@ -1564,6 +1565,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
616 }
617 return 0;
618 }
619+EXPORT_SYMBOL(iterate_mounts);
620
7eafdf33 621 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
622 {
623diff --git a/fs/notify/group.c b/fs/notify/group.c
fb47a38f 624index ad19959..adf290d 100644
7f207e10
AM
625--- a/fs/notify/group.c
626+++ b/fs/notify/group.c
627@@ -22,6 +22,7 @@
628 #include <linux/srcu.h>
629 #include <linux/rculist.h>
630 #include <linux/wait.h>
631+#include <linux/module.h>
632
633 #include <linux/fsnotify_backend.h>
634 #include "fsnotify.h"
fb47a38f 635@@ -72,6 +73,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea
AM
636 {
637 atomic_inc(&group->refcnt);
638 }
639+EXPORT_SYMBOL(fsnotify_get_group);
640
641 /*
642 * Drop a reference to a group. Free it if it's through.
fb47a38f 643@@ -81,6 +83,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 644 if (atomic_dec_and_test(&group->refcnt))
1716fcea 645 fsnotify_final_destroy_group(group);
7f207e10
AM
646 }
647+EXPORT_SYMBOL(fsnotify_put_group);
648
649 /*
650 * Create a new fsnotify_group and hold a reference for the group returned.
fb47a38f 651@@ -109,6 +112,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
652
653 return group;
654 }
655+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
656
657 int fsnotify_fasync(int fd, struct file *file, int on)
658 {
7f207e10 659diff --git a/fs/notify/mark.c b/fs/notify/mark.c
076b876e 660index d90deaa..60b4239 100644
7f207e10
AM
661--- a/fs/notify/mark.c
662+++ b/fs/notify/mark.c
392086de 663@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 664 mark->free_mark(mark);
1716fcea 665 }
7f207e10
AM
666 }
667+EXPORT_SYMBOL(fsnotify_put_mark);
668
669 /*
670 * Any time a mark is getting freed we end up here.
392086de 671@@ -191,6 +192,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea
AM
672 fsnotify_destroy_mark_locked(mark, group);
673 mutex_unlock(&group->mark_mutex);
7f207e10
AM
674 }
675+EXPORT_SYMBOL(fsnotify_destroy_mark);
676
677 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
678 {
392086de 679@@ -275,6 +277,7 @@ err:
7f207e10
AM
680
681 return ret;
682 }
683+EXPORT_SYMBOL(fsnotify_add_mark);
684
1716fcea
AM
685 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
686 struct inode *inode, struct vfsmount *mnt, int allow_dups)
392086de 687@@ -336,6 +339,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
688 atomic_set(&mark->refcnt, 1);
689 mark->free_mark = free_mark;
690 }
691+EXPORT_SYMBOL(fsnotify_init_mark);
692
693 static int fsnotify_mark_destroy(void *ignored)
694 {
695diff --git a/fs/open.c b/fs/open.c
076b876e 696index d6fd3ac..5e99d8b 100644
7f207e10
AM
697--- a/fs/open.c
698+++ b/fs/open.c
523b37e3 699@@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
7f207e10
AM
700 mutex_unlock(&dentry->d_inode->i_mutex);
701 return ret;
702 }
703+EXPORT_SYMBOL(do_truncate);
704
1716fcea 705 long vfs_truncate(struct path *path, loff_t length)
7f207e10 706 {
076b876e 707@@ -298,6 +299,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
38d290e6
JR
708 sb_end_write(inode->i_sb);
709 return ret;
710 }
711+EXPORT_SYMBOL(do_fallocate);
712
713 SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
714 {
7f207e10 715diff --git a/fs/splice.c b/fs/splice.c
076b876e 716index 9ba380c..3419932 100644
7f207e10
AM
717--- a/fs/splice.c
718+++ b/fs/splice.c
076b876e 719@@ -1127,6 +1127,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
720
721 return splice_write(pipe, out, ppos, len, flags);
7f207e10
AM
722 }
723+EXPORT_SYMBOL(do_splice_from);
724
725 /*
726 * Attempt to initiate a splice from a file to a pipe.
076b876e 727@@ -1153,6 +1154,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
728
729 return splice_read(in, ppos, pipe, len, flags);
730 }
731+EXPORT_SYMBOL(do_splice_to);
732
733 /**
734 * splice_direct_to_actor - splices data directly between two non-pipes
735diff --git a/security/commoncap.c b/security/commoncap.c
392086de 736index b9d613e..ba3b618 100644
7f207e10
AM
737--- a/security/commoncap.c
738+++ b/security/commoncap.c
1716fcea 739@@ -988,9 +988,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 740 }
7f207e10
AM
741 return ret;
742 }
0c3ec466
AM
743+EXPORT_SYMBOL(cap_mmap_addr);
744
745 int cap_mmap_file(struct file *file, unsigned long reqprot,
746 unsigned long prot, unsigned long flags)
747 {
748 return 0;
749 }
750+EXPORT_SYMBOL(cap_mmap_file);
7f207e10 751diff --git a/security/device_cgroup.c b/security/device_cgroup.c
076b876e 752index d9d69e6..3f6f471 100644
7f207e10
AM
753--- a/security/device_cgroup.c
754+++ b/security/device_cgroup.c
f6c5ef8b
AM
755@@ -7,6 +7,7 @@
756 #include <linux/device_cgroup.h>
757 #include <linux/cgroup.h>
758 #include <linux/ctype.h>
759+#include <linux/export.h>
760 #include <linux/list.h>
761 #include <linux/uaccess.h>
762 #include <linux/seq_file.h>
076b876e 763@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
764 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
765 access);
7f207e10 766 }
2cbb1c4b 767+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
768
769 int devcgroup_inode_mknod(int mode, dev_t dev)
770 {
771diff --git a/security/security.c b/security/security.c
076b876e 772index 31614e9..b223a66 100644
7f207e10
AM
773--- a/security/security.c
774+++ b/security/security.c
392086de 775@@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
776 return 0;
777 return security_ops->path_rmdir(dir, dentry);
778 }
779+EXPORT_SYMBOL(security_path_rmdir);
780
781 int security_path_unlink(struct path *dir, struct dentry *dentry)
782 {
392086de 783@@ -423,6 +424,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
784 return 0;
785 return security_ops->path_symlink(dir, dentry, old_name);
786 }
787+EXPORT_SYMBOL(security_path_symlink);
788
789 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
790 struct dentry *new_dentry)
392086de 791@@ -431,6 +433,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
792 return 0;
793 return security_ops->path_link(old_dentry, new_dir, new_dentry);
794 }
795+EXPORT_SYMBOL(security_path_link);
796
797 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
38d290e6
JR
798 struct path *new_dir, struct dentry *new_dentry,
799@@ -458,6 +461,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
800 return 0;
801 return security_ops->path_truncate(path);
802 }
803+EXPORT_SYMBOL(security_path_truncate);
804
7eafdf33
AM
805 int security_path_chmod(struct path *path, umode_t mode)
806 {
38d290e6 807@@ -465,6 +469,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 808 return 0;
7eafdf33 809 return security_ops->path_chmod(path, mode);
7f207e10
AM
810 }
811+EXPORT_SYMBOL(security_path_chmod);
812
537831f9 813 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 814 {
38d290e6 815@@ -472,6 +477,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
816 return 0;
817 return security_ops->path_chown(path, uid, gid);
818 }
819+EXPORT_SYMBOL(security_path_chown);
820
821 int security_path_chroot(struct path *path)
822 {
38d290e6 823@@ -557,6 +563,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
824 return 0;
825 return security_ops->inode_readlink(dentry);
826 }
827+EXPORT_SYMBOL(security_inode_readlink);
828
829 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
830 {
38d290e6 831@@ -571,6 +578,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 832 return 0;
1e00d052 833 return security_ops->inode_permission(inode, mask);
7f207e10
AM
834 }
835+EXPORT_SYMBOL(security_inode_permission);
836
1e00d052 837 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 838 {
38d290e6 839@@ -693,6 +701,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
840
841 return fsnotify_perm(file, mask);
842 }
843+EXPORT_SYMBOL(security_file_permission);
844
845 int security_file_alloc(struct file *file)
846 {
38d290e6 847@@ -753,6 +762,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
848 return ret;
849 return ima_file_mmap(file, prot);
850 }
0c3ec466 851+EXPORT_SYMBOL(security_mmap_file);
7f207e10 852
0c3ec466
AM
853 int security_mmap_addr(unsigned long addr)
854 {
7f207e10
AM
855diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
856--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
076b876e 857+++ linux/Documentation/ABI/testing/debugfs-aufs 2014-01-30 21:10:02.794146538 +0100
86dc4139 858@@ -0,0 +1,50 @@
7f207e10
AM
859+What: /debug/aufs/si_<id>/
860+Date: March 2009
f6b6e03d 861+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
862+Description:
863+ Under /debug/aufs, a directory named si_<id> is created
864+ per aufs mount, where <id> is a unique id generated
865+ internally.
1facf9fc 866+
86dc4139
AM
867+What: /debug/aufs/si_<id>/plink
868+Date: Apr 2013
f6b6e03d 869+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
870+Description:
871+ It has three lines and shows the information about the
872+ pseudo-link. The first line is a single number
873+ representing a number of buckets. The second line is a
874+ number of pseudo-links per buckets (separated by a
875+ blank). The last line is a single number representing a
876+ total number of psedo-links.
877+ When the aufs mount option 'noplink' is specified, it
878+ will show "1\n0\n0\n".
879+
7f207e10
AM
880+What: /debug/aufs/si_<id>/xib
881+Date: March 2009
f6b6e03d 882+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
883+Description:
884+ It shows the consumed blocks by xib (External Inode Number
885+ Bitmap), its block size and file size.
886+ When the aufs mount option 'noxino' is specified, it
887+ will be empty. About XINO files, see the aufs manual.
888+
889+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
890+Date: March 2009
f6b6e03d 891+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
892+Description:
893+ It shows the consumed blocks by xino (External Inode Number
894+ Translation Table), its link count, block size and file
895+ size.
896+ When the aufs mount option 'noxino' is specified, it
897+ will be empty. About XINO files, see the aufs manual.
898+
899+What: /debug/aufs/si_<id>/xigen
900+Date: March 2009
f6b6e03d 901+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
902+Description:
903+ It shows the consumed blocks by xigen (External Inode
904+ Generation Table), its block size and file size.
905+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
906+ be created.
907+ When the aufs mount option 'noxino' is specified, it
908+ will be empty. About XINO files, see the aufs manual.
909diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
910--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
076b876e 911+++ linux/Documentation/ABI/testing/sysfs-aufs 2014-01-30 21:10:02.794146538 +0100
392086de 912@@ -0,0 +1,31 @@
7f207e10
AM
913+What: /sys/fs/aufs/si_<id>/
914+Date: March 2009
f6b6e03d 915+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
916+Description:
917+ Under /sys/fs/aufs, a directory named si_<id> is created
918+ per aufs mount, where <id> is a unique id generated
919+ internally.
920+
921+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
922+Date: March 2009
f6b6e03d 923+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
924+Description:
925+ It shows the abolute path of a member directory (which
926+ is called branch) in aufs, and its permission.
927+
392086de
AM
928+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
929+Date: July 2013
f6b6e03d 930+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
931+Description:
932+ It shows the id of a member directory (which is called
933+ branch) in aufs.
934+
7f207e10
AM
935+What: /sys/fs/aufs/si_<id>/xi_path
936+Date: March 2009
f6b6e03d 937+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
938+Description:
939+ It shows the abolute path of XINO (External Inode Number
940+ Bitmap, Translation Table and Generation Table) file
941+ even if it is the default path.
942+ When the aufs mount option 'noxino' is specified, it
943+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
944diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
945--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
076b876e 946+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2014-01-30 21:10:02.807480310 +0100
523b37e3 947@@ -0,0 +1,161 @@
53392da6 948+
523b37e3 949+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
950+#
951+# This program is free software; you can redistribute it and/or modify
952+# it under the terms of the GNU General Public License as published by
953+# the Free Software Foundation; either version 2 of the License, or
954+# (at your option) any later version.
955+#
956+# This program is distributed in the hope that it will be useful,
957+# but WITHOUT ANY WARRANTY; without even the implied warranty of
958+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
959+# GNU General Public License for more details.
960+#
961+# You should have received a copy of the GNU General Public License
523b37e3 962+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
963+
964+Introduction
965+----------------------------------------
966+
967+aufs [ei ju: ef es] | [a u f s]
968+1. abbrev. for "advanced multi-layered unification filesystem".
969+2. abbrev. for "another unionfs".
970+3. abbrev. for "auf das" in German which means "on the" in English.
971+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
972+ But "Filesystem aufs Filesystem" is hard to understand.
973+
974+AUFS is a filesystem with features:
975+- multi layered stackable unification filesystem, the member directory
976+ is called as a branch.
977+- branch permission and attribute, 'readonly', 'real-readonly',
978+ 'readwrite', 'whiteout-able', 'link-able whiteout' and their
979+ combination.
980+- internal "file copy-on-write".
981+- logical deletion, whiteout.
982+- dynamic branch manipulation, adding, deleting and changing permission.
983+- allow bypassing aufs, user's direct branch access.
984+- external inode number translation table and bitmap which maintains the
985+ persistent aufs inode number.
986+- seekable directory, including NFS readdir.
987+- file mapping, mmap and sharing pages.
988+- pseudo-link, hardlink over branches.
989+- loopback mounted filesystem as a branch.
990+- several policies to select one among multiple writable branches.
991+- revert a single systemcall when an error occurs in aufs.
992+- and more...
993+
994+
995+Multi Layered Stackable Unification Filesystem
996+----------------------------------------------------------------------
997+Most people already knows what it is.
998+It is a filesystem which unifies several directories and provides a
999+merged single directory. When users access a file, the access will be
1000+passed/re-directed/converted (sorry, I am not sure which English word is
1001+correct) to the real file on the member filesystem. The member
1002+filesystem is called 'lower filesystem' or 'branch' and has a mode
1003+'readonly' and 'readwrite.' And the deletion for a file on the lower
1004+readonly branch is handled by creating 'whiteout' on the upper writable
1005+branch.
1006+
1007+On LKML, there have been discussions about UnionMount (Jan Blunck,
1008+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1009+different approaches to implement the merged-view.
1010+The former tries putting it into VFS, and the latter implements as a
1011+separate filesystem.
1012+(If I misunderstand about these implementations, please let me know and
1013+I shall correct it. Because it is a long time ago when I read their
1014+source files last time).
1015+
1016+UnionMount's approach will be able to small, but may be hard to share
1017+branches between several UnionMount since the whiteout in it is
1018+implemented in the inode on branch filesystem and always
1019+shared. According to Bharata's post, readdir does not seems to be
1020+finished yet.
1021+There are several missing features known in this implementations such as
1022+- for users, the inode number may change silently. eg. copy-up.
1023+- link(2) may break by copy-up.
1024+- read(2) may get an obsoleted filedata (fstat(2) too).
1025+- fcntl(F_SETLK) may be broken by copy-up.
1026+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1027+ open(O_RDWR).
1028+
1029+Unionfs has a longer history. When I started implementing a stacking filesystem
1030+(Aug 2005), it already existed. It has virtual super_block, inode,
1031+dentry and file objects and they have an array pointing lower same kind
1032+objects. After contributing many patches for Unionfs, I re-started my
1033+project AUFS (Jun 2006).
1034+
1035+In AUFS, the structure of filesystem resembles to Unionfs, but I
1036+implemented my own ideas, approaches and enhancements and it became
1037+totally different one.
1038+
1039+Comparing DM snapshot and fs based implementation
1040+- the number of bytes to be copied between devices is much smaller.
1041+- the type of filesystem must be one and only.
1042+- the fs must be writable, no readonly fs, even for the lower original
1043+ device. so the compression fs will not be usable. but if we use
1044+ loopback mount, we may address this issue.
1045+ for instance,
1046+ mount /cdrom/squashfs.img /sq
1047+ losetup /sq/ext2.img
1048+ losetup /somewhere/cow
1049+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1050+- it will be difficult (or needs more operations) to extract the
1051+ difference between the original device and COW.
1052+- DM snapshot-merge may help a lot when users try merging. in the
1053+ fs-layer union, users will use rsync(1).
1054+
1055+
1056+Several characters/aspects of aufs
1057+----------------------------------------------------------------------
1058+
1059+Aufs has several characters or aspects.
1060+1. a filesystem, callee of VFS helper
1061+2. sub-VFS, caller of VFS helper for branches
1062+3. a virtual filesystem which maintains persistent inode number
1063+4. reader/writer of files on branches such like an application
1064+
1065+1. Callee of VFS Helper
1066+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1067+unlink(2) from an application reaches sys_unlink() kernel function and
1068+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1069+calls filesystem specific unlink operation. Actually aufs implements the
1070+unlink operation but it behaves like a redirector.
1071+
1072+2. Caller of VFS Helper for Branches
1073+aufs_unlink() passes the unlink request to the branch filesystem as if
1074+it were called from VFS. So the called unlink operation of the branch
1075+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1076+every necessary pre/post operation for the branch filesystem.
1077+- acquire the lock for the parent dir on a branch
1078+- lookup in a branch
1079+- revalidate dentry on a branch
1080+- mnt_want_write() for a branch
1081+- vfs_unlink() for a branch
1082+- mnt_drop_write() for a branch
1083+- release the lock on a branch
1084+
1085+3. Persistent Inode Number
1086+One of the most important issue for a filesystem is to maintain inode
1087+numbers. This is particularly important to support exporting a
1088+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1089+backend block device for its own. But some storage is necessary to
1090+maintain inode number. It may be a large space and may not suit to keep
1091+in memory. Aufs rents some space from its first writable branch
1092+filesystem (by default) and creates file(s) on it. These files are
1093+created by aufs internally and removed soon (currently) keeping opened.
1094+Note: Because these files are removed, they are totally gone after
1095+ unmounting aufs. It means the inode numbers are not persistent
1096+ across unmount or reboot. I have a plan to make them really
1097+ persistent which will be important for aufs on NFS server.
1098+
1099+4. Read/Write Files Internally (copy-on-write)
1100+Because a branch can be readonly, when you write a file on it, aufs will
1101+"copy-up" it to the upper writable branch internally. And then write the
1102+originally requested thing to the file. Generally kernel doesn't
1103+open/read/write file actively. In aufs, even a single write may cause a
1104+internal "file copy". This behaviour is very similar to cp(1) command.
1105+
1106+Some people may think it is better to pass such work to user space
1107+helper, instead of doing in kernel space. Actually I am still thinking
1108+about it. But currently I have implemented it in kernel space.
1109diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1110--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
1111+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2014-08-14 10:15:45.115275734 +0200
1112@@ -0,0 +1,251 @@
53392da6 1113+
523b37e3 1114+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1115+#
1116+# This program is free software; you can redistribute it and/or modify
1117+# it under the terms of the GNU General Public License as published by
1118+# the Free Software Foundation; either version 2 of the License, or
1119+# (at your option) any later version.
1120+#
1121+# This program is distributed in the hope that it will be useful,
1122+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1123+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1124+# GNU General Public License for more details.
1125+#
1126+# You should have received a copy of the GNU General Public License
523b37e3 1127+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1128+
1129+Basic Aufs Internal Structure
1130+
1131+Superblock/Inode/Dentry/File Objects
1132+----------------------------------------------------------------------
1133+As like an ordinary filesystem, aufs has its own
1134+superblock/inode/dentry/file objects. All these objects have a
1135+dynamically allocated array and store the same kind of pointers to the
1136+lower filesystem, branch.
1137+For example, when you build a union with one readwrite branch and one
1138+readonly, mounted /au, /rw and /ro respectively.
1139+- /au = /rw + /ro
1140+- /ro/fileA exists but /rw/fileA
1141+
1142+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1143+pointers are stored in a aufs dentry. The array in aufs dentry will be,
1144+- [0] = NULL
1145+- [1] = /ro/fileA
1146+
1147+This style of an array is essentially same to the aufs
1148+superblock/inode/dentry/file objects.
1149+
1150+Because aufs supports manipulating branches, ie. add/delete/change
1151+dynamically, these objects has its own generation. When branches are
1152+changed, the generation in aufs superblock is incremented. And a
1153+generation in other object are compared when it is accessed.
1154+When a generation in other objects are obsoleted, aufs refreshes the
1155+internal array.
1156+
1157+
1158+Superblock
1159+----------------------------------------------------------------------
1160+Additionally aufs superblock has some data for policies to select one
1161+among multiple writable branches, XIB files, pseudo-links and kobject.
1162+See below in detail.
1163+About the policies which supports copy-down a directory, see policy.txt
1164+too.
1165+
1166+
1167+Branch and XINO(External Inode Number Translation Table)
1168+----------------------------------------------------------------------
1169+Every branch has its own xino (external inode number translation table)
1170+file. The xino file is created and unlinked by aufs internally. When two
1171+members of a union exist on the same filesystem, they share the single
1172+xino file.
1173+The struct of a xino file is simple, just a sequence of aufs inode
1174+numbers which is indexed by the lower inode number.
1175+In the above sample, assume the inode number of /ro/fileA is i111 and
1176+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1177+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1178+
1179+When the inode numbers are not contiguous, the xino file will be sparse
1180+which has a hole in it and doesn't consume as much disk space as it
1181+might appear. If your branch filesystem consumes disk space for such
1182+holes, then you should specify 'xino=' option at mounting aufs.
1183+
1184+Also a writable branch has three kinds of "whiteout bases". All these
1185+are existed when the branch is joined to aufs and the names are
1186+whiteout-ed doubly, so that users will never see their names in aufs
1187+hierarchy.
1188+1. a regular file which will be linked to all whiteouts.
1189+2. a directory to store a pseudo-link.
1190+3. a directory to store an "orphan-ed" file temporary.
1191+
1192+1. Whiteout Base
1193+ When you remove a file on a readonly branch, aufs handles it as a
1194+ logical deletion and creates a whiteout on the upper writable branch
1195+ as a hardlink of this file in order not to consume inode on the
1196+ writable branch.
1197+2. Pseudo-link Dir
1198+ See below, Pseudo-link.
1199+3. Step-Parent Dir
1200+ When "fileC" exists on the lower readonly branch only and it is
1201+ opened and removed with its parent dir, and then user writes
1202+ something into it, then aufs copies-up fileC to this
1203+ directory. Because there is no other dir to store fileC. After
1204+ creating a file under this dir, the file is unlinked.
1205+
1206+Because aufs supports manipulating branches, ie. add/delete/change
1207+dynamically, a branch has its own id. When the branch order changes, aufs
1208+finds the new index by searching the branch id.
1209+
1210+
1211+Pseudo-link
1212+----------------------------------------------------------------------
1213+Assume "fileA" exists on the lower readonly branch only and it is
1214+hardlinked to "fileB" on the branch. When you write something to fileA,
1215+aufs copies-up it to the upper writable branch. Additionally aufs
1216+creates a hardlink under the Pseudo-link Directory of the writable
1217+branch. The inode of a pseudo-link is kept in aufs super_block as a
1218+simple list. If fileB is read after unlinking fileA, aufs returns
1219+filedata from the pseudo-link instead of the lower readonly
1220+branch. Because the pseudo-link is based upon the inode, to keep the
1221+inode number by xino (see above) is important.
1222+
1223+All the hardlinks under the Pseudo-link Directory of the writable branch
1224+should be restored in a proper location later. Aufs provides a utility
1225+to do this. The userspace helpers executed at remounting and unmounting
1226+aufs by default.
1227+During this utility is running, it puts aufs into the pseudo-link
1228+maintenance mode. In this mode, only the process which began the
1229+maintenance mode (and its child processes) is allowed to operate in
1230+aufs. Some other processes which are not related to the pseudo-link will
1231+be allowed to run too, but the rest have to return an error or wait
1232+until the maintenance mode ends. If a process already acquires an inode
1233+mutex (in VFS), it has to return an error.
1234+
1235+
1236+XIB(external inode number bitmap)
1237+----------------------------------------------------------------------
1238+Addition to the xino file per a branch, aufs has an external inode number
1239+bitmap in a superblock object. It is also a file such like a xino file.
1240+It is a simple bitmap to mark whether the aufs inode number is in-use or
1241+not.
1242+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1243+
1244+Aufs implements a feature to truncate/refresh both of xino and xib to
1245+reduce the number of consumed disk blocks for these files.
1246+
1247+
1248+Virtual or Vertical Dir, and Readdir in Userspace
1249+----------------------------------------------------------------------
1250+In order to support multiple layers (branches), aufs readdir operation
1251+constructs a virtual dir block on memory. For readdir, aufs calls
1252+vfs_readdir() internally for each dir on branches, merges their entries
1253+with eliminating the whiteout-ed ones, and sets it to file (dir)
1254+object. So the file object has its entry list until it is closed. The
1255+entry list will be updated when the file position is zero and becomes
1256+old. This decision is made in aufs automatically.
1257+
1258+The dynamically allocated memory block for the name of entries has a
1259+unit of 512 bytes (by default) and stores the names contiguously (no
1260+padding). Another block for each entry is handled by kmem_cache too.
1261+During building dir blocks, aufs creates hash list and judging whether
1262+the entry is whiteouted by its upper branch or already listed.
1263+The merged result is cached in the corresponding inode object and
1264+maintained by a customizable life-time option.
1265+
1266+Some people may call it can be a security hole or invite DoS attack
1267+since the opened and once readdir-ed dir (file object) holds its entry
1268+list and becomes a pressure for system memory. But I'd say it is similar
1269+to files under /proc or /sys. The virtual files in them also holds a
1270+memory page (generally) while they are opened. When an idea to reduce
1271+memory for them is introduced, it will be applied to aufs too.
1272+For those who really hate this situation, I've developed readdir(3)
1273+library which operates this merging in userspace. You just need to set
1274+LD_PRELOAD environment variable, and aufs will not consume no memory in
1275+kernel space for readdir(3).
1276+
1277+
1278+Workqueue
1279+----------------------------------------------------------------------
1280+Aufs sometimes requires privilege access to a branch. For instance,
1281+in copy-up/down operation. When a user process is going to make changes
1282+to a file which exists in the lower readonly branch only, and the mode
1283+of one of ancestor directories may not be writable by a user
1284+process. Here aufs copy-up the file with its ancestors and they may
1285+require privilege to set its owner/group/mode/etc.
1286+This is a typical case of a application character of aufs (see
1287+Introduction).
1288+
1289+Aufs uses workqueue synchronously for this case. It creates its own
1290+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1291+passes the request to call mkdir or write (for example), and wait for
1292+its completion. This approach solves a problem of a signal handler
1293+simply.
1294+If aufs didn't adopt the workqueue and changed the privilege of the
1295+process, and if the mkdir/write call arises SIGXFSZ or other signal,
1296+then the user process might gain a privilege or the generated core file
1297+was owned by a superuser.
1298+
1299+Also aufs uses the system global workqueue ("events" kernel thread) too
1300+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1301+whiteout base and etc. This is unrelated to a privilege.
1302+Most of aufs operation tries acquiring a rw_semaphore for aufs
1303+superblock at the beginning, at the same time waits for the completion
1304+of all queued asynchronous tasks.
1305+
1306+
1307+Whiteout
1308+----------------------------------------------------------------------
1309+The whiteout in aufs is very similar to Unionfs's. That is represented
1310+by its filename. UnionMount takes an approach of a file mode, but I am
1311+afraid several utilities (find(1) or something) will have to support it.
1312+
1313+Basically the whiteout represents "logical deletion" which stops aufs to
1314+lookup further, but also it represents "dir is opaque" which also stop
1315+lookup.
1316+
1317+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1318+In order to make several functions in a single systemcall to be
1319+revertible, aufs adopts an approach to rename a directory to a temporary
1320+unique whiteouted name.
1321+For example, in rename(2) dir where the target dir already existed, aufs
1322+renames the target dir to a temporary unique whiteouted name before the
1323+actual rename on a branch and then handles other actions (make it opaque,
1324+update the attributes, etc). If an error happens in these actions, aufs
1325+simply renames the whiteouted name back and returns an error. If all are
1326+succeeded, aufs registers a function to remove the whiteouted unique
1327+temporary name completely and asynchronously to the system global
1328+workqueue.
1329+
1330+
1331+Copy-up
1332+----------------------------------------------------------------------
1333+It is a well-known feature or concept.
1334+When user modifies a file on a readonly branch, aufs operate "copy-up"
1335+internally and makes change to the new file on the upper writable branch.
1336+When the trigger systemcall does not update the timestamps of the parent
1337+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1338+
1339+
1340+Move-down (aufs3.9 and later)
1341+----------------------------------------------------------------------
1342+"Copy-up" is one of the essential feature in aufs. It copies a file from
1343+the lower readonly branch to the upper writable branch when a user
1344+changes something about the file.
1345+"Move-down" is an opposite action of copy-up. Basically this action is
1346+ran manually instead of automatically and internally.
076b876e
AM
1347+For desgin and implementation, aufs has to consider these issues.
1348+- whiteout for the file may exist on the lower branch.
1349+- ancestor directories may not exist on the lower branch.
1350+- diropq for the ancestor directories may exist on the upper branch.
1351+- free space on the lower branch will reduce.
1352+- another access to the file may happen during moving-down, including
1353+ UDBA.
1354+- the file should not be hard-linked nor pseudo-linked. they should be
1355+ handled by auplink utility later.
c2b27bf2
AM
1356+
1357+Sometimes users want to move-down a file from the upper writable branch
1358+to the lower readonly or writable branch. For instance,
1359+- the free space of the upper writable branch is going to run out.
1360+- create a new intermediate branch between the upper and lower branch.
1361+- etc.
1362+
1363+For this purpose, use "aumvdown" command in aufs-util.git.
53392da6
AM
1364diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1365--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
1366+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2014-08-14 10:15:45.118609182 +0200
1367@@ -0,0 +1,133 @@
53392da6 1368+
523b37e3 1369+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1370+#
1371+# This program is free software; you can redistribute it and/or modify
1372+# it under the terms of the GNU General Public License as published by
1373+# the Free Software Foundation; either version 2 of the License, or
1374+# (at your option) any later version.
1375+#
1376+# This program is distributed in the hope that it will be useful,
1377+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1378+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1379+# GNU General Public License for more details.
1380+#
1381+# You should have received a copy of the GNU General Public License
523b37e3 1382+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1383+
1384+Lookup in a Branch
1385+----------------------------------------------------------------------
1386+Since aufs has a character of sub-VFS (see Introduction), it operates
1387+lookup for branches as VFS does. It may be a heavy work. Generally
1388+speaking struct nameidata is a bigger structure and includes many
1389+information. But almost all lookup operation in aufs is the simplest
1390+case, ie. lookup only an entry directly connected to its parent. Digging
1391+down the directory hierarchy is unnecessary.
1392+
1393+VFS has a function lookup_one_len() for that use, but it is not usable
1394+for a branch filesystem which requires struct nameidata. So aufs
1395+implements a simple lookup wrapper function. When a branch filesystem
1396+allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
1397+a simplest nameidata and calls lookup_hash().
1398+Here aufs applies "a principle in NFSD", ie. if the filesystem supports
1399+NFS-export, then it has to support NULL as a nameidata parameter for
1400+->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
1401+aufs tests if ->s_export_op in the branch is NULL or not.
1402+
1403+When a branch is a remote filesystem, aufs basically trusts its
1404+->d_revalidate(), also aufs forces the hardest revalidate tests for
1405+them.
1406+For d_revalidate, aufs implements three levels of revalidate tests. See
1407+"Revalidate Dentry and UDBA" in detail.
1408+
1409+
076b876e
AM
1410+Test Only the Highest One for the Directory Permission (dirperm1 option)
1411+----------------------------------------------------------------------
1412+Let's try case study.
1413+- aufs has two branches, upper readwrite and lower readonly.
1414+ /au = /rw + /ro
1415+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1416+- user invoked "chmod a+rx /au/dirA"
1417+- the internal copy-up is activated and "/rw/dirA" is created and its
1418+ permission bits are set to world readble.
1419+- then "/au/dirA" becomes world readable?
1420+
1421+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1422+or it may be a natively readonly filesystem. If aufs respects the lower
1423+branch, it should not respond readdir request from other users. But user
1424+allowed it by chmod. Should really aufs rejects showing the entries
1425+under /ro/dirA?
1426+
1427+To be honest, I don't have a best solution for this case. So aufs
1428+implements 'dirperm1' and 'nodirperm1' and leave it to users.
1429+When dirperm1 is specified, aufs checks only the highest one for the
1430+directory permission, and shows the entries. Otherwise, as usual, checks
1431+every dir existing on all branches and rejects the request.
1432+
1433+As a side effect, dirperm1 option improves the performance of aufs
1434+because the number of permission check is reduced when the number of
1435+branch is many.
1436+
1437+
53392da6
AM
1438+Loopback Mount
1439+----------------------------------------------------------------------
1440+Basically aufs supports any type of filesystem and block device for a
1441+branch (actually there are some exceptions). But it is prohibited to add
1442+a loopback mounted one whose backend file exists in a filesystem which is
1443+already added to aufs. The reason is to protect aufs from a recursive
1444+lookup. If it was allowed, the aufs lookup operation might re-enter a
1445+lookup for the loopback mounted branch in the same context, and will
1446+cause a deadlock.
1447+
1448+
1449+Revalidate Dentry and UDBA (User's Direct Branch Access)
1450+----------------------------------------------------------------------
1451+Generally VFS helpers re-validate a dentry as a part of lookup.
1452+0. digging down the directory hierarchy.
1453+1. lock the parent dir by its i_mutex.
1454+2. lookup the final (child) entry.
1455+3. revalidate it.
1456+4. call the actual operation (create, unlink, etc.)
1457+5. unlock the parent dir
1458+
1459+If the filesystem implements its ->d_revalidate() (step 3), then it is
1460+called. Actually aufs implements it and checks the dentry on a branch is
1461+still valid.
1462+But it is not enough. Because aufs has to release the lock for the
1463+parent dir on a branch at the end of ->lookup() (step 2) and
1464+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1465+held by VFS.
1466+If the file on a branch is changed directly, eg. bypassing aufs, after
1467+aufs released the lock, then the subsequent operation may cause
1468+something unpleasant result.
1469+
1470+This situation is a result of VFS architecture, ->lookup() and
1471+->d_revalidate() is separated. But I never say it is wrong. It is a good
1472+design from VFS's point of view. It is just not suitable for sub-VFS
1473+character in aufs.
1474+
1475+Aufs supports such case by three level of revalidation which is
1476+selectable by user.
1477+1. Simple Revalidate
1478+ Addition to the native flow in VFS's, confirm the child-parent
1479+ relationship on the branch just after locking the parent dir on the
1480+ branch in the "actual operation" (step 4). When this validation
1481+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1482+ checks the validation of the dentry on branches.
1483+2. Monitor Changes Internally by Inotify/Fsnotify
1484+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1485+ the dentry on the branch, and returns EBUSY if it finds different
1486+ dentry.
1487+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1488+ during it is in cache. When the event is notified, aufs registers a
1489+ function to kernel 'events' thread by schedule_work(). And the
1490+ function sets some special status to the cached aufs dentry and inode
1491+ private data. If they are not cached, then aufs has nothing to
1492+ do. When the same file is accessed through aufs (step 0-3) later,
1493+ aufs will detect the status and refresh all necessary data.
1494+ In this mode, aufs has to ignore the event which is fired by aufs
1495+ itself.
1496+3. No Extra Validation
1497+ This is the simplest test and doesn't add any additional revalidation
1498+ test, and skip therevalidatin in step 4. It is useful and improves
1499+ aufs performance when system surely hide the aufs branches from user,
1500+ by over-mounting something (or another method).
1501diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1502--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
076b876e 1503+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2014-01-30 21:10:02.807480310 +0100
523b37e3 1504@@ -0,0 +1,75 @@
53392da6 1505+
523b37e3 1506+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1507+#
1508+# This program is free software; you can redistribute it and/or modify
1509+# it under the terms of the GNU General Public License as published by
1510+# the Free Software Foundation; either version 2 of the License, or
1511+# (at your option) any later version.
1512+#
1513+# This program is distributed in the hope that it will be useful,
1514+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1515+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1516+# GNU General Public License for more details.
1517+#
1518+# You should have received a copy of the GNU General Public License
523b37e3 1519+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1520+
1521+Branch Manipulation
1522+
1523+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1524+and changing its permission/attribute, there are a lot of works to do.
1525+
1526+
1527+Add a Branch
1528+----------------------------------------------------------------------
1529+o Confirm the adding dir exists outside of aufs, including loopback
1530+ mount.
1531+- and other various attributes...
1532+o Initialize the xino file and whiteout bases if necessary.
1533+ See struct.txt.
1534+
1535+o Check the owner/group/mode of the directory
1536+ When the owner/group/mode of the adding directory differs from the
1537+ existing branch, aufs issues a warning because it may impose a
1538+ security risk.
1539+ For example, when a upper writable branch has a world writable empty
1540+ top directory, a malicious user can create any files on the writable
1541+ branch directly, like copy-up and modify manually. If something like
1542+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1543+ writable branch, and the writable branch is world-writable, then a
1544+ malicious guy may create /etc/passwd on the writable branch directly
1545+ and the infected file will be valid in aufs.
1546+ I am afraid it can be a security issue, but nothing to do except
1547+ producing a warning.
1548+
1549+
1550+Delete a Branch
1551+----------------------------------------------------------------------
1552+o Confirm the deleting branch is not busy
1553+ To be general, there is one merit to adopt "remount" interface to
1554+ manipulate branches. It is to discard caches. At deleting a branch,
1555+ aufs checks the still cached (and connected) dentries and inodes. If
1556+ there are any, then they are all in-use. An inode without its
1557+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1558+
1559+ For the cached one, aufs checks whether the same named entry exists on
1560+ other branches.
1561+ If the cached one is a directory, because aufs provides a merged view
1562+ to users, as long as one dir is left on any branch aufs can show the
1563+ dir to users. In this case, the branch can be removed from aufs.
1564+ Otherwise aufs rejects deleting the branch.
1565+
1566+ If any file on the deleting branch is opened by aufs, then aufs
1567+ rejects deleting.
1568+
1569+
1570+Modify the Permission of a Branch
1571+----------------------------------------------------------------------
1572+o Re-initialize or remove the xino file and whiteout bases if necessary.
1573+ See struct.txt.
1574+
1575+o rw --> ro: Confirm the modifying branch is not busy
1576+ Aufs rejects the request if any of these conditions are true.
1577+ - a file on the branch is mmap-ed.
1578+ - a regular file on the branch is opened for write and there is no
1579+ same named entry on the upper branch.
1580diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1581--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
076b876e 1582+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2014-01-30 21:10:02.807480310 +0100
523b37e3 1583@@ -0,0 +1,64 @@
53392da6 1584+
523b37e3 1585+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1586+#
1587+# This program is free software; you can redistribute it and/or modify
1588+# it under the terms of the GNU General Public License as published by
1589+# the Free Software Foundation; either version 2 of the License, or
1590+# (at your option) any later version.
1591+#
1592+# This program is distributed in the hope that it will be useful,
1593+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1594+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1595+# GNU General Public License for more details.
1596+#
1597+# You should have received a copy of the GNU General Public License
523b37e3 1598+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1599+
1600+Policies to Select One among Multiple Writable Branches
1601+----------------------------------------------------------------------
1602+When the number of writable branch is more than one, aufs has to decide
1603+the target branch for file creation or copy-up. By default, the highest
1604+writable branch which has the parent (or ancestor) dir of the target
1605+file is chosen (top-down-parent policy).
1606+By user's request, aufs implements some other policies to select the
1607+writable branch, for file creation two policies, round-robin and
1608+most-free-space policies. For copy-up three policies, top-down-parent,
1609+bottom-up-parent and bottom-up policies.
1610+
1611+As expected, the round-robin policy selects the branch in circular. When
1612+you have two writable branches and creates 10 new files, 5 files will be
1613+created for each branch. mkdir(2) systemcall is an exception. When you
1614+create 10 new directories, all will be created on the same branch.
1615+And the most-free-space policy selects the one which has most free
1616+space among the writable branches. The amount of free space will be
1617+checked by aufs internally, and users can specify its time interval.
1618+
1619+The policies for copy-up is more simple,
1620+top-down-parent is equivalent to the same named on in create policy,
1621+bottom-up-parent selects the writable branch where the parent dir
1622+exists and the nearest upper one from the copyup-source,
1623+bottom-up selects the nearest upper writable branch from the
1624+copyup-source, regardless the existence of the parent dir.
1625+
1626+There are some rules or exceptions to apply these policies.
1627+- If there is a readonly branch above the policy-selected branch and
1628+ the parent dir is marked as opaque (a variation of whiteout), or the
1629+ target (creating) file is whiteout-ed on the upper readonly branch,
1630+ then the result of the policy is ignored and the target file will be
1631+ created on the nearest upper writable branch than the readonly branch.
1632+- If there is a writable branch above the policy-selected branch and
1633+ the parent dir is marked as opaque or the target file is whiteouted
1634+ on the branch, then the result of the policy is ignored and the target
1635+ file will be created on the highest one among the upper writable
1636+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1637+ it as usual.
1638+- link(2) and rename(2) systemcalls are exceptions in every policy.
1639+ They try selecting the branch where the source exists as possible
1640+ since copyup a large file will take long time. If it can't be,
1641+ ie. the branch where the source exists is readonly, then they will
1642+ follow the copyup policy.
1643+- There is an exception for rename(2) when the target exists.
1644+ If the rename target exists, aufs compares the index of the branches
1645+ where the source and the target exists and selects the higher
1646+ one. If the selected branch is readonly, then aufs follows the
1647+ copyup policy.
076b876e
AM
1648diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
1649--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
1650+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2014-08-14 10:15:45.118609182 +0200
1651@@ -0,0 +1,120 @@
1652+
1653+# Copyright (C) 2011-2014 Junjiro R. Okajima
1654+#
1655+# This program is free software; you can redistribute it and/or modify
1656+# it under the terms of the GNU General Public License as published by
1657+# the Free Software Foundation; either version 2 of the License, or
1658+# (at your option) any later version.
1659+#
1660+# This program is distributed in the hope that it will be useful,
1661+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1662+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1663+# GNU General Public License for more details.
1664+#
1665+# You should have received a copy of the GNU General Public License
1666+# along with this program; if not, write to the Free Software
1667+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1668+
1669+
1670+File-based Hierarchical Storage Management (FHSM)
1671+----------------------------------------------------------------------
1672+Hierarchical Storage Management (or HSM) is a well-known feature in the
1673+storage world. Aufs provides this feature as file-based with multiple
1674+writable branches, based upon the principle of "Colder-Lower".
1675+Here the word "colder" means that the less used files, and "lower" means
1676+that the position in the order of the stacked branches.
1677+These multiple writable branches are prioritized, ie. the topmost one
1678+should be the fastest drive and be used heavily.
1679+
1680+o Characters in aufs FHSM story
1681+- aufs itself and a new branch attribute.
1682+- a new ioctl interface to move-down and to establish a connection with
1683+ the daemon ("move-down" is a converse of "copy-up").
1684+- userspace tool and daemon.
1685+
1686+The userspace daemon establishes a connection with aufs and waits for
1687+the notification. The notified information is very similar to struct
1688+statfs containing the number of consumed blocks and inodes.
1689+When the consumed blocks/inodes of a branch exceeds the user-specified
1690+upper watermark, the daemon activates its move-down process until the
1691+consumed blocks/inodes reaches the user-specified lower watermark.
1692+
1693+The actual move-down is done by aufs based upon the request from
1694+user-space since we need to maintain the inode number and the internal
1695+pointer arrays in aufs.
1696+
1697+Currently aufs FHSM handles the regular files only. Additionally they
1698+must not be hard-linked nor pseudo-linked.
1699+
1700+
1701+o Cowork of aufs and the user-space daemon
1702+ During the userspace daemon established the connection, aufs sends a
1703+ small notification to it whenever aufs writes something into the
1704+ writable branch. But it may cost high since aufs issues statfs(2)
1705+ internally. So user can specify a new option to cache the
1706+ info. Actually the notification is controlled by these factors.
1707+ + the specified cache time.
1708+ + classified as "force" by aufs internally.
1709+ Until the specified time expires, aufs doesn't send the info
1710+ except the forced cases. When aufs decide forcing, the info is always
1711+ notified to userspace.
1712+ For example, the number of free inodes is generally large enough and
1713+ the shortage of it happens rarely. So aufs doesn't force the
1714+ notification when creating a new file, directory and others. This is
1715+ the typical case which aufs doesn't force.
1716+ When aufs writes the actual filedata and the files consumes any of new
1717+ blocks, the aufs forces notifying.
1718+
1719+
1720+o Interfaces in aufs
1721+- New branch attribute.
1722+ + fhsm
1723+ Specifies that the branch is managed by FHSM feature. In other word,
1724+ participant in the FHSM.
1725+ When nofhsm is set to the branch, it will not be the source/target
1726+ branch of the move-down operation. This attribute is set
1727+ independently from coo and moo attributes, and if you want full
1728+ FHSM, you should specify them as well.
1729+- New mount option.
1730+ + fhsm_sec
1731+ Specifies a second to suppress many less important info to be
1732+ notified.
1733+- New ioctl.
1734+ + AUFS_CTL_FHSM_FD
1735+ create a new file descriptor which userspace can read the notification
1736+ (a subset of struct statfs) from aufs.
1737+- Module parameter 'brs'
1738+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
1739+ be set.
1740+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
1741+ When there are two or more branches with fhsm attributes,
1742+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
1743+ terminates it. As a result of remounting and branch-manipulation, the
1744+ number of branches with fhsm attribute can be one. In this case,
1745+ /sbin/mount.aufs will terminate the user-space daemon.
1746+
1747+
1748+Finally the operation is done as these steps in kernel-space.
1749+- make sure that,
1750+ + no one else is using the file.
1751+ + the file is not hard-linked.
1752+ + the file is not pseudo-linked.
1753+ + the file is a regular file.
1754+ + the parent dir is not opaqued.
1755+- find the target writable branch.
1756+- make sure the file is not whiteout-ed by the upper (than the target)
1757+ branch.
1758+- make the parent dir on the target branch.
1759+- mutex lock the inode on the branch.
1760+- unlink the whiteout on the target branch (if exists).
1761+- lookup and create the whiteout-ed temporary name on the target branch.
1762+- copy the file as the whiteout-ed temporary name on the target branch.
1763+- rename the whiteout-ed temporary name to the original name.
1764+- unlink the file on the source branch.
1765+- maintain the internal pointer array and the external inode number
1766+ table (XINO).
1767+- maintain the timestamps and other attributes of the parent dir and the
1768+ file.
1769+
1770+And of course, in every step, an error may happen. So the operation
1771+should restore the original file state after an error happens.
53392da6
AM
1772diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1773--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
076b876e 1774+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2014-01-30 21:10:02.807480310 +0100
523b37e3 1775@@ -0,0 +1,46 @@
53392da6 1776+
523b37e3 1777+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1778+#
1779+# This program is free software; you can redistribute it and/or modify
1780+# it under the terms of the GNU General Public License as published by
1781+# the Free Software Foundation; either version 2 of the License, or
1782+# (at your option) any later version.
1783+#
1784+# This program is distributed in the hope that it will be useful,
1785+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1786+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1787+# GNU General Public License for more details.
1788+#
1789+# You should have received a copy of the GNU General Public License
523b37e3 1790+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1791+
1792+mmap(2) -- File Memory Mapping
1793+----------------------------------------------------------------------
1794+In aufs, the file-mapped pages are handled by a branch fs directly, no
1795+interaction with aufs. It means aufs_mmap() calls the branch fs's
1796+->mmap().
1797+This approach is simple and good, but there is one problem.
1798+Under /proc, several entries show the mmap-ped files by its path (with
1799+device and inode number), and the printed path will be the path on the
1800+branch fs's instead of virtual aufs's.
1801+This is not a problem in most cases, but some utilities lsof(1) (and its
1802+user) may expect the path on aufs.
1803+
1804+To address this issue, aufs adds a new member called vm_prfile in struct
1805+vm_area_struct (and struct vm_region). The original vm_file points to
1806+the file on the branch fs in order to handle everything correctly as
1807+usual. The new vm_prfile points to a virtual file in aufs, and the
1808+show-functions in procfs refers to vm_prfile if it is set.
1809+Also we need to maintain several other places where touching vm_file
1810+such like
1811+- fork()/clone() copies vma and the reference count of vm_file is
1812+ incremented.
1813+- merging vma maintains the ref count too.
1814+
1815+This is not a good approach. It just faking the printed path. But it
1816+leaves all behaviour around f_mapping unchanged. This is surely an
1817+advantage.
1818+Actually aufs had adopted another complicated approach which calls
1819+generic_file_mmap() and handles struct vm_operations_struct. In this
1820+approach, aufs met a hard problem and I could not solve it without
1821+switching the approach.
1822diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1823--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
076b876e 1824+++ linux/Documentation/filesystems/aufs/design/07export.txt 2014-01-30 21:10:02.807480310 +0100
523b37e3 1825@@ -0,0 +1,58 @@
53392da6 1826+
523b37e3 1827+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1828+#
1829+# This program is free software; you can redistribute it and/or modify
1830+# it under the terms of the GNU General Public License as published by
1831+# the Free Software Foundation; either version 2 of the License, or
1832+# (at your option) any later version.
1833+#
1834+# This program is distributed in the hope that it will be useful,
1835+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1836+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1837+# GNU General Public License for more details.
1838+#
1839+# You should have received a copy of the GNU General Public License
523b37e3 1840+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1841+
1842+Export Aufs via NFS
1843+----------------------------------------------------------------------
1844+Here is an approach.
1845+- like xino/xib, add a new file 'xigen' which stores aufs inode
1846+ generation.
1847+- iget_locked(): initialize aufs inode generation for a new inode, and
1848+ store it in xigen file.
1849+- destroy_inode(): increment aufs inode generation and store it in xigen
1850+ file. it is necessary even if it is not unlinked, because any data of
1851+ inode may be changed by UDBA.
1852+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
1853+ build file handle by
1854+ + branch id (4 bytes)
1855+ + superblock generation (4 bytes)
1856+ + inode number (4 or 8 bytes)
1857+ + parent dir inode number (4 or 8 bytes)
1858+ + inode generation (4 bytes))
1859+ + return value of exportfs_encode_fh() for the parent on a branch (4
1860+ bytes)
1861+ + file handle for a branch (by exportfs_encode_fh())
1862+- fh_to_dentry():
1863+ + find the index of a branch from its id in handle, and check it is
1864+ still exist in aufs.
1865+ + 1st level: get the inode number from handle and search it in cache.
1866+ + 2nd level: if not found, get the parent inode number from handle and
1867+ search it in cache. and then open the parent dir, find the matching
1868+ inode number by vfs_readdir() and get its name, and call
1869+ lookup_one_len() for the target dentry.
1870+ + 3rd level: if the parent dir is not cached, call
1871+ exportfs_decode_fh() for a branch and get the parent on a branch,
1872+ build a pathname of it, convert it a pathname in aufs, call
1873+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
1874+ the 2nd level.
1875+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
1876+ for every branch, but not itself. to get this, (currently) aufs
1877+ searches in current->nsproxy->mnt_ns list. it may not be a good
1878+ idea, but I didn't get other approach.
1879+ + test the generation of the gotten inode.
1880+- every inode operation: they may get EBUSY due to UDBA. in this case,
1881+ convert it into ESTALE for NFSD.
1882+- readdir(): call lockdep_on/off() because filldir in NFSD calls
1883+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
1884diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
1885--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
076b876e 1886+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2014-01-30 21:10:02.807480310 +0100
523b37e3 1887@@ -0,0 +1,52 @@
53392da6 1888+
523b37e3 1889+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1890+#
1891+# This program is free software; you can redistribute it and/or modify
1892+# it under the terms of the GNU General Public License as published by
1893+# the Free Software Foundation; either version 2 of the License, or
1894+# (at your option) any later version.
1895+#
1896+# This program is distributed in the hope that it will be useful,
1897+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1898+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1899+# GNU General Public License for more details.
1900+#
1901+# You should have received a copy of the GNU General Public License
523b37e3 1902+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1903+
1904+Show Whiteout Mode (shwh)
1905+----------------------------------------------------------------------
1906+Generally aufs hides the name of whiteouts. But in some cases, to show
1907+them is very useful for users. For instance, creating a new middle layer
1908+(branch) by merging existing layers.
1909+
1910+(borrowing aufs1 HOW-TO from a user, Michael Towers)
1911+When you have three branches,
1912+- Bottom: 'system', squashfs (underlying base system), read-only
1913+- Middle: 'mods', squashfs, read-only
1914+- Top: 'overlay', ram (tmpfs), read-write
1915+
1916+The top layer is loaded at boot time and saved at shutdown, to preserve
1917+the changes made to the system during the session.
1918+When larger changes have been made, or smaller changes have accumulated,
1919+the size of the saved top layer data grows. At this point, it would be
1920+nice to be able to merge the two overlay branches ('mods' and 'overlay')
1921+and rewrite the 'mods' squashfs, clearing the top layer and thus
1922+restoring save and load speed.
1923+
1924+This merging is simplified by the use of another aufs mount, of just the
1925+two overlay branches using the 'shwh' option.
1926+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
1927+ aufs /livesys/merge_union
1928+
1929+A merged view of these two branches is then available at
1930+/livesys/merge_union, and the new feature is that the whiteouts are
1931+visible!
1932+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
1933+writing to all branches. Also the default mode for all branches is 'ro'.
1934+It is now possible to save the combined contents of the two overlay
1935+branches to a new squashfs, e.g.:
1936+# mksquashfs /livesys/merge_union /path/to/newmods.squash
1937+
1938+This new squashfs archive can be stored on the boot device and the
1939+initramfs will use it to replace the old one at the next boot.
1940diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
1941--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
076b876e 1942+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2014-01-30 21:10:02.807480310 +0100
523b37e3 1943@@ -0,0 +1,46 @@
53392da6 1944+
523b37e3 1945+# Copyright (C) 2010-2014 Junjiro R. Okajima
53392da6
AM
1946+#
1947+# This program is free software; you can redistribute it and/or modify
1948+# it under the terms of the GNU General Public License as published by
1949+# the Free Software Foundation; either version 2 of the License, or
1950+# (at your option) any later version.
1951+#
1952+# This program is distributed in the hope that it will be useful,
1953+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1954+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1955+# GNU General Public License for more details.
1956+#
1957+# You should have received a copy of the GNU General Public License
523b37e3 1958+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1959+
1960+Dynamically customizable FS operations
1961+----------------------------------------------------------------------
1962+Generally FS operations (struct inode_operations, struct
1963+address_space_operations, struct file_operations, etc.) are defined as
1964+"static const", but it never means that FS have only one set of
1965+operation. Some FS have multiple sets of them. For instance, ext2 has
1966+three sets, one for XIP, for NOBH, and for normal.
1967+Since aufs overrides and redirects these operations, sometimes aufs has
1968+to change its behaviour according to the branch FS type. More imporantly
1969+VFS acts differently if a function (member in the struct) is set or
1970+not. It means aufs should have several sets of operations and select one
1971+among them according to the branch FS definition.
1972+
1973+In order to solve this problem and not to affect the behavour of VFS,
1974+aufs defines these operations dynamically. For instance, aufs defines
1975+aio_read function for struct file_operations, but it may not be set to
1976+the file_operations. When the branch FS doesn't have it, aufs doesn't
1977+set it to its file_operations while the function definition itself is
1978+still alive. So the behaviour of io_submit(2) will not change, and it
1979+will return an error when aio_read is not defined.
1980+
1981+The lifetime of these dynamically generated operation object is
1982+maintained by aufs branch object. When the branch is removed from aufs,
1983+the reference counter of the object is decremented. When it reaches
1984+zero, the dynamically generated operation object will be freed.
1985+
1986+This approach is designed to support AIO (io_submit), Direcit I/O and
1987+XIP mainly.
1988+Currently this approach is applied to file_operations and
1989+vm_operations_struct for regular files only.
1990diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
1991--- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
1992+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2014-08-14 10:15:45.118609182 +0200
1993@@ -0,0 +1,58 @@
53392da6 1994+
523b37e3 1995+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1996+#
1997+# This program is free software; you can redistribute it and/or modify
1998+# it under the terms of the GNU General Public License as published by
1999+# the Free Software Foundation; either version 2 of the License, or
2000+# (at your option) any later version.
2001+#
2002+# This program is distributed in the hope that it will be useful,
2003+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2004+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2005+# GNU General Public License for more details.
2006+#
2007+# You should have received a copy of the GNU General Public License
523b37e3 2008+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2009+
2010+Plan
2011+
2012+Restoring some features which was implemented in aufs1.
2013+They were dropped in aufs2 in order to make source files simpler and
2014+easier to be reviewed.
2015+
2016+
53392da6
AM
2017+Being Another Aufs's Readonly Branch (robr)
2018+----------------------------------------------------------------------
2019+Aufs1 allows aufs to be another aufs's readonly branch.
2020+This feature was developed by a user's request. But it may not be used
2021+currecnly.
2022+
2023+
53392da6
AM
2024+Refresh the Opened File (refrof)
2025+----------------------------------------------------------------------
2026+This option is implemented in aufs1 but incomplete.
2027+
2028+When user reads from a file, he expects to get its latest filedata
2029+generally. If the file is removed and a new same named file is created,
2030+the content he gets is unchanged, ie. the unlinked filedata.
2031+
2032+Let's try case study again.
2033+- aufs has two branches.
2034+ /au = /rw + /ro
2035+- "fileA" exists under /ro, but /rw.
2036+- user opened "/au/fileA".
2037+- he or someone else inserts a branch (/new) between /rw and /ro.
2038+ /au = /rw + /new + /ro
2039+- the new branch has "fileA".
2040+- user reads from the opened "fileA"
2041+- which filedata should aufs return, from /ro or /new?
2042+
2043+Some people says it has to be "from /ro" and it is a semantics of Unix.
2044+The others say it should be "from /new" because the file is not removed
2045+and it is equivalent to the case of someone else modifies the file.
2046+
2047+Here again I don't have a best and final answer. I got an idea to
2048+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
2049+Opened File) is specified (by default), aufs returns the filedata from
2050+/new.
2051+Otherwise from /new.
2052diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2053--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
2054+++ linux/Documentation/filesystems/aufs/README 2014-08-14 10:15:45.115275734 +0200
2055@@ -0,0 +1,370 @@
53392da6
AM
2056+
2057+Aufs3 -- advanced multi layered unification filesystem version 3.x
2058+http://aufs.sf.net
2059+Junjiro R. Okajima
2060+
2061+
2062+0. Introduction
2063+----------------------------------------
2064+In the early days, aufs was entirely re-designed and re-implemented
2065+Unionfs Version 1.x series. After many original ideas, approaches,
2066+improvements and implementations, it becomes totally different from
2067+Unionfs while keeping the basic features.
2068+Recently, Unionfs Version 2.x series begin taking some of the same
2069+approaches to aufs1's.
2070+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2071+University and his team.
2072+
2073+Aufs3 supports linux-3.0 and later.
2074+If you want older kernel version support, try aufs2-2.6.git or
2075+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2076+
2077+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2078+ According to Christoph Hellwig, linux rejects all union-type
2079+ filesystems but UnionMount.
53392da6
AM
2080+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2081+
38d290e6
JR
2082+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2083+ UnionMount, and he pointed out an issue around a directory mutex
2084+ lock and aufs addressed it. But it is still unsure whether aufs will
2085+ be merged (or any other union solution).
076b876e 2086+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2087+
53392da6
AM
2088+
2089+1. Features
2090+----------------------------------------
2091+- unite several directories into a single virtual filesystem. The member
2092+ directory is called as a branch.
2093+- you can specify the permission flags to the branch, which are 'readonly',
2094+ 'readwrite' and 'whiteout-able.'
2095+- by upper writable branch, internal copyup and whiteout, files/dirs on
2096+ readonly branch are modifiable logically.
2097+- dynamic branch manipulation, add, del.
2098+- etc...
2099+
2100+Also there are many enhancements in aufs1, such as:
2101+- readdir(3) in userspace.
2102+- keep inode number by external inode number table
2103+- keep the timestamps of file/dir in internal copyup operation
2104+- seekable directory, supporting NFS readdir.
2105+- whiteout is hardlinked in order to reduce the consumption of inodes
2106+ on branch
2107+- do not copyup, nor create a whiteout when it is unnecessary
2108+- revert a single systemcall when an error occurs in aufs
2109+- remount interface instead of ioctl
2110+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2111+- loopback mounted filesystem as a branch
2112+- kernel thread for removing the dir who has a plenty of whiteouts
2113+- support copyup sparse file (a file which has a 'hole' in it)
2114+- default permission flags for branches
2115+- selectable permission flags for ro branch, whether whiteout can
2116+ exist or not
2117+- export via NFS.
2118+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2119+- support multiple writable branches, some policies to select one
2120+ among multiple writable branches.
2121+- a new semantics for link(2) and rename(2) to support multiple
2122+ writable branches.
2123+- no glibc changes are required.
2124+- pseudo hardlink (hardlink over branches)
2125+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2126+ including NFS or remote filesystem branch.
2127+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2128+- and more...
2129+
2130+Currently these features are dropped temporary from aufs3.
2131+See design/08plan.txt in detail.
2132+- test only the highest one for the directory permission (dirperm1)
2133+- copyup on open (coo=)
2134+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2135+ (robr)
2136+- statistics of aufs thread (/sys/fs/aufs/stat)
2137+- delegation mode (dlgt)
2138+ a delegation of the internal branch access to support task I/O
2139+ accounting, which also supports Linux Security Modules (LSM) mainly
2140+ for Suse AppArmor.
2141+- intent.open/create (file open in a single lookup)
2142+
2143+Features or just an idea in the future (see also design/*.txt),
2144+- reorder the branch index without del/re-add.
2145+- permanent xino files for NFSD
2146+- an option for refreshing the opened files after add/del branches
2147+- 'move' policy for copy-up between two writable branches, after
2148+ checking free space.
2149+- light version, without branch manipulation. (unnecessary?)
2150+- copyup in userspace
2151+- inotify in userspace
2152+- readv/writev
2153+- xattr, acl
2154+
2155+
2156+2. Download
2157+----------------------------------------
1e00d052
AM
2158+There were three GIT trees for aufs3, aufs3-linux.git,
2159+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
2160+"aufs-util.git."
2161+While the aufs-util is always necessary, you need either of aufs3-linux
2162+or aufs3-standalone.
2163+
2164+The aufs3-linux tree includes the whole linux mainline GIT tree,
2165+git://git.kernel.org/.../torvalds/linux.git.
2166+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
b4510431 2167+build aufs3 as an external kernel module.
1e00d052
AM
2168+
2169+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6
AM
2170+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2171+
2172+You will find GIT branches whose name is in form of "aufs3.x" where "x"
2173+represents the linux kernel version, "linux-3.x". For instance,
1e00d052
AM
2174+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
2175+"aufs3.x-rcN" branch.
2176+
2177+o aufs3-linux tree
2178+$ git clone --reference /your/linux/git/tree \
86dc4139 2179+ git://git.code.sf.net/p/aufs/aufs3-linux aufs-aufs3-linux \
1e00d052
AM
2180+ aufs3-linux.git
2181+- if you don't have linux GIT tree, then remove "--reference ..."
2182+$ cd aufs3-linux.git
2183+$ git checkout origin/aufs3.0
53392da6
AM
2184+
2185+o aufs3-standalone tree
86dc4139 2186+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
53392da6
AM
2187+ aufs3-standalone.git
2188+$ cd aufs3-standalone.git
2189+$ git checkout origin/aufs3.0
2190+
2191+o aufs-util tree
86dc4139 2192+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
53392da6
AM
2193+ aufs-util.git
2194+$ cd aufs-util.git
2195+$ git checkout origin/aufs3.0
2196+
9dbd164d
AM
2197+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
2198+The minor version number, 'x' in '3.x', of aufs may not always
2199+follow the minor version number of the kernel.
2200+Because changes in the kernel that cause the use of a new
2201+minor version number do not always require changes to aufs-util.
2202+
2203+Since aufs-util has its own minor version number, you may not be
2204+able to find a GIT branch in aufs-util for your kernel's
2205+exact minor version number.
2206+In this case, you should git-checkout the branch for the
53392da6 2207+nearest lower number.
9dbd164d
AM
2208+
2209+For (an unreleased) example:
2210+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 2211+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
2212+or something numerically smaller is the branch for your kernel.
2213+
53392da6
AM
2214+Also you can view all branches by
2215+ $ git branch -a
2216+
2217+
2218+3. Configuration and Compilation
2219+----------------------------------------
2220+Make sure you have git-checkout'ed the correct branch.
2221+
1e00d052 2222+For aufs3-linux tree,
c06a8ce3 2223+- enable CONFIG_AUFS_FS.
1e00d052
AM
2224+- set other aufs configurations if necessary.
2225+
53392da6
AM
2226+For aufs3-standalone tree,
2227+There are several ways to build.
2228+
2229+1.
2230+- apply ./aufs3-kbuild.patch to your kernel source files.
2231+- apply ./aufs3-base.patch too.
523b37e3 2232+- apply ./aufs3-mmap.patch too.
53392da6
AM
2233+- apply ./aufs3-standalone.patch too, if you have a plan to set
2234+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
537831f9
AM
2235+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2236+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2237+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2238+ =m or =y.
2239+- and build your kernel as usual.
2240+- install the built kernel.
c06a8ce3
AM
2241+ Note: Since linux-3.9, every filesystem module requires an alias
2242+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2243+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2244+- install the header files too by "make headers_install" to the
2245+ directory where you specify. By default, it is $PWD/usr.
b4510431 2246+ "make help" shows a brief note for headers_install.
53392da6
AM
2247+- and reboot your system.
2248+
2249+2.
2250+- module only (CONFIG_AUFS_FS=m).
2251+- apply ./aufs3-base.patch to your kernel source files.
523b37e3 2252+- apply ./aufs3-mmap.patch too.
53392da6
AM
2253+- apply ./aufs3-standalone.patch too.
2254+- build your kernel, don't forget "make headers_install", and reboot.
2255+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2256+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2257+ every aufs configurations.
2258+- build the module by simple "make".
c06a8ce3
AM
2259+ Note: Since linux-3.9, every filesystem module requires an alias
2260+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2261+ modules.aliases file.
53392da6
AM
2262+- you can specify ${KDIR} make variable which points to your kernel
2263+ source tree.
2264+- install the files
2265+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2266+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2267+ + run "make install_headers" (instead of headers_install) to install
2268+ the modified aufs header file (you can specify DESTDIR which is
2269+ available in aufs standalone version's Makefile only), or copy
2270+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2271+ you like manually. By default, the target directory is $PWD/usr.
53392da6
AM
2272+- no need to apply aufs3-kbuild.patch, nor copying source files to your
2273+ kernel source tree.
2274+
b4510431 2275+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2276+ as well as "make headers_install" in the kernel source tree.
2277+ headers_install is subject to be forgotten, but it is essentially
2278+ necessary, not only for building aufs-util.
2279+ You may not meet problems without headers_install in some older
2280+ version though.
2281+
2282+And then,
2283+- read README in aufs-util, build and install it
9dbd164d
AM
2284+- note that your distribution may contain an obsoleted version of
2285+ aufs_type.h in /usr/include/linux or something. When you build aufs
2286+ utilities, make sure that your compiler refers the correct aufs header
2287+ file which is built by "make headers_install."
53392da6
AM
2288+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2289+ then run "make install_ulib" too. And refer to the aufs manual in
2290+ detail.
2291+
38d290e6
JR
2292+There several other patches in aufs3-standalone.git. They are all
2293+optional. When you meet some problems, they will help you.
2294+- aufs3-loopback.patch
2295+ Supports a nested loopback mount in a branch-fs. This patch is
2296+ unnecessary until aufs produces a message like "you may want to try
2297+ another patch for loopback file".
2298+- vfs-ino.patch
2299+ Modifies a system global kernel internal function get_next_ino() in
2300+ order to stop assigning 0 for an inode-number. Not directly related to
2301+ aufs, but recommended generally.
2302+- tmpfs-idr.patch
2303+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2304+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2305+ duplication of inode number, which is important for backup tools and
2306+ other utilities. When you find aufs XINO files for tmpfs branch
2307+ growing too much, try this patch.
2308+
53392da6
AM
2309+
2310+4. Usage
2311+----------------------------------------
2312+At first, make sure aufs-util are installed, and please read the aufs
2313+manual, aufs.5 in aufs-util.git tree.
2314+$ man -l aufs.5
2315+
2316+And then,
2317+$ mkdir /tmp/rw /tmp/aufs
2318+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2319+
2320+Here is another example. The result is equivalent.
2321+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2322+ Or
2323+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2324+# mount -o remount,append:${HOME} /tmp/aufs
2325+
2326+Then, you can see whole tree of your home dir through /tmp/aufs. If
2327+you modify a file under /tmp/aufs, the one on your home directory is
2328+not affected, instead the same named file will be newly created under
2329+/tmp/rw. And all of your modification to a file will be applied to
2330+the one under /tmp/rw. This is called the file based Copy on Write
2331+(COW) method.
2332+Aufs mount options are described in aufs.5.
2333+If you run chroot or something and make your aufs as a root directory,
2334+then you need to customize the shutdown script. See the aufs manual in
2335+detail.
2336+
2337+Additionally, there are some sample usages of aufs which are a
2338+diskless system with network booting, and LiveCD over NFS.
2339+See sample dir in CVS tree on SourceForge.
2340+
2341+
2342+5. Contact
2343+----------------------------------------
2344+When you have any problems or strange behaviour in aufs, please let me
2345+know with:
2346+- /proc/mounts (instead of the output of mount(8))
2347+- /sys/module/aufs/*
2348+- /sys/fs/aufs/* (if you have them)
2349+- /debug/aufs/* (if you have them)
2350+- linux kernel version
2351+ if your kernel is not plain, for example modified by distributor,
2352+ the url where i can download its source is necessary too.
2353+- aufs version which was printed at loading the module or booting the
2354+ system, instead of the date you downloaded.
2355+- configuration (define/undefine CONFIG_AUFS_xxx)
2356+- kernel configuration or /proc/config.gz (if you have it)
2357+- behaviour which you think to be incorrect
2358+- actual operation, reproducible one is better
2359+- mailto: aufs-users at lists.sourceforge.net
2360+
2361+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2362+and Feature Requests) on SourceForge. Please join and write to
2363+aufs-users ML.
2364+
2365+
2366+6. Acknowledgements
2367+----------------------------------------
2368+Thanks to everyone who have tried and are using aufs, whoever
2369+have reported a bug or any feedback.
2370+
2371+Especially donators:
2372+Tomas Matejicek(slax.org) made a donation (much more than once).
2373+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2374+ scripts) is making "doubling" donations.
2375+ Unfortunately I cannot list all of the donators, but I really
b4510431 2376+ appreciate.
53392da6
AM
2377+ It ends Aug 2010, but the ordinary donation URL is still available.
2378+ <http://sourceforge.net/donate/index.php?group_id=167503>
2379+Dai Itasaka made a donation (2007/8).
2380+Chuck Smith made a donation (2008/4, 10 and 12).
2381+Henk Schoneveld made a donation (2008/9).
2382+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2383+Francois Dupoux made a donation (2008/11).
2384+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2385+ aufs2 GIT tree (2009/2).
2386+William Grant made a donation (2009/3).
2387+Patrick Lane made a donation (2009/4).
2388+The Mail Archive (mail-archive.com) made donations (2009/5).
2389+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2390+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2391+Pavel Pronskiy made a donation (2011/2).
2392+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2393+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
2394+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2395+11).
1e00d052 2396+Sam Liddicott made a donation (2011/9).
86dc4139
AM
2397+Era Scarecrow made a donation (2013/4).
2398+Bor Ratajc made a donation (2013/4).
2399+Alessandro Gorreta made a donation (2013/4).
2400+POIRETTE Marc made a donation (2013/4).
2401+Alessandro Gorreta made a donation (2013/4).
2402+lauri kasvandik made a donation (2013/5).
392086de 2403+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
2404+The Parted Magic Project made a donation (2013/9 and 11).
2405+Pavel Barta made a donation (2013/10).
38d290e6 2406+Nikolay Pertsev made a donation (2014/5).
076b876e
AM
2407+James B made a donation (2014/7).
2408+Stefano Di Biase made a donation (2014/8).
53392da6
AM
2409+
2410+Thank you very much.
2411+Donations are always, including future donations, very important and
2412+helpful for me to keep on developing aufs.
2413+
2414+
2415+7.
2416+----------------------------------------
2417+If you are an experienced user, no explanation is needed. Aufs is
2418+just a linux filesystem.
2419+
2420+
2421+Enjoy!
2422+
2423+# Local variables: ;
2424+# mode: text;
2425+# End: ;
7f207e10
AM
2426diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
2427--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
076b876e 2428+++ linux/fs/aufs/aufs.h 2014-01-30 21:10:02.827480967 +0100
523b37e3 2429@@ -0,0 +1,59 @@
7f207e10 2430+/*
523b37e3 2431+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
2432+ *
2433+ * This program, aufs is free software; you can redistribute it and/or modify
2434+ * it under the terms of the GNU General Public License as published by
2435+ * the Free Software Foundation; either version 2 of the License, or
2436+ * (at your option) any later version.
2437+ *
2438+ * This program is distributed in the hope that it will be useful,
2439+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2440+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2441+ * GNU General Public License for more details.
2442+ *
2443+ * You should have received a copy of the GNU General Public License
523b37e3 2444+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2445+ */
2446+
2447+/*
2448+ * all header files
2449+ */
2450+
2451+#ifndef __AUFS_H__
2452+#define __AUFS_H__
2453+
2454+#ifdef __KERNEL__
2455+
2456+#define AuStub(type, name, body, ...) \
2457+ static inline type name(__VA_ARGS__) { body; }
2458+
2459+#define AuStubVoid(name, ...) \
2460+ AuStub(void, name, , __VA_ARGS__)
2461+#define AuStubInt0(name, ...) \
2462+ AuStub(int, name, return 0, __VA_ARGS__)
2463+
2464+#include "debug.h"
2465+
2466+#include "branch.h"
2467+#include "cpup.h"
2468+#include "dcsub.h"
2469+#include "dbgaufs.h"
2470+#include "dentry.h"
2471+#include "dir.h"
2472+#include "dynop.h"
2473+#include "file.h"
2474+#include "fstype.h"
2475+#include "inode.h"
2476+#include "loop.h"
2477+#include "module.h"
7f207e10
AM
2478+#include "opts.h"
2479+#include "rwsem.h"
2480+#include "spl.h"
2481+#include "super.h"
2482+#include "sysaufs.h"
2483+#include "vfsub.h"
2484+#include "whout.h"
2485+#include "wkq.h"
2486+
2487+#endif /* __KERNEL__ */
2488+#endif /* __AUFS_H__ */
2489diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
2490--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
2491+++ linux/fs/aufs/branch.c 2014-08-14 10:16:04.512608923 +0200
2492@@ -0,0 +1,1447 @@
7f207e10 2493+/*
523b37e3 2494+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
2495+ *
2496+ * This program, aufs is free software; you can redistribute it and/or modify
2497+ * it under the terms of the GNU General Public License as published by
2498+ * the Free Software Foundation; either version 2 of the License, or
2499+ * (at your option) any later version.
2500+ *
2501+ * This program is distributed in the hope that it will be useful,
2502+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2503+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2504+ * GNU General Public License for more details.
2505+ *
2506+ * You should have received a copy of the GNU General Public License
523b37e3 2507+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2508+ */
2509+
2510+/*
2511+ * branch management
2512+ */
2513+
027c5e7a 2514+#include <linux/compat.h>
7f207e10
AM
2515+#include <linux/statfs.h>
2516+#include "aufs.h"
2517+
2518+/*
2519+ * free a single branch
1facf9fc 2520+ */
86dc4139
AM
2521+
2522+/* prohibit rmdir to the root of the branch */
2523+/* todo: another new flag? */
2524+static void au_br_dflags_force(struct au_branch *br)
2525+{
2526+ struct dentry *h_dentry;
2527+
2528+ h_dentry = au_br_dentry(br);
2529+ spin_lock(&h_dentry->d_lock);
2530+ br->br_dflags = h_dentry->d_flags & DCACHE_MOUNTED;
2531+ h_dentry->d_flags |= DCACHE_MOUNTED;
2532+ spin_unlock(&h_dentry->d_lock);
2533+}
2534+
2535+/* restore its d_flags */
2536+static void au_br_dflags_restore(struct au_branch *br)
2537+{
2538+ struct dentry *h_dentry;
2539+
2540+ if (br->br_dflags)
2541+ return;
2542+
2543+ h_dentry = au_br_dentry(br);
2544+ spin_lock(&h_dentry->d_lock);
2545+ h_dentry->d_flags &= ~DCACHE_MOUNTED;
2546+ spin_unlock(&h_dentry->d_lock);
2547+}
2548+
1facf9fc 2549+static void au_br_do_free(struct au_branch *br)
2550+{
2551+ int i;
2552+ struct au_wbr *wbr;
4a4d8108 2553+ struct au_dykey **key;
1facf9fc 2554+
027c5e7a
AM
2555+ au_hnotify_fin_br(br);
2556+
1facf9fc 2557+ if (br->br_xino.xi_file)
2558+ fput(br->br_xino.xi_file);
2559+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
2560+
2561+ AuDebugOn(atomic_read(&br->br_count));
2562+
2563+ wbr = br->br_wbr;
2564+ if (wbr) {
2565+ for (i = 0; i < AuBrWh_Last; i++)
2566+ dput(wbr->wbr_wh[i]);
2567+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 2568+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 2569+ }
2570+
076b876e
AM
2571+ if (br->br_fhsm) {
2572+ au_br_fhsm_fin(br->br_fhsm);
2573+ kfree(br->br_fhsm);
2574+ }
2575+
4a4d8108
AM
2576+ key = br->br_dykey;
2577+ for (i = 0; i < AuBrDynOp; i++, key++)
2578+ if (*key)
2579+ au_dy_put(*key);
2580+ else
2581+ break;
2582+
86dc4139
AM
2583+ au_br_dflags_restore(br);
2584+
537831f9
AM
2585+ /* recursive lock, s_umount of branch's */
2586+ lockdep_off();
86dc4139 2587+ path_put(&br->br_path);
537831f9 2588+ lockdep_on();
1facf9fc 2589+ kfree(wbr);
2590+ kfree(br);
2591+}
2592+
2593+/*
2594+ * frees all branches
2595+ */
2596+void au_br_free(struct au_sbinfo *sbinfo)
2597+{
2598+ aufs_bindex_t bmax;
2599+ struct au_branch **br;
2600+
dece6358
AM
2601+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2602+
1facf9fc 2603+ bmax = sbinfo->si_bend + 1;
2604+ br = sbinfo->si_branch;
2605+ while (bmax--)
2606+ au_br_do_free(*br++);
2607+}
2608+
2609+/*
2610+ * find the index of a branch which is specified by @br_id.
2611+ */
2612+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2613+{
2614+ aufs_bindex_t bindex, bend;
2615+
2616+ bend = au_sbend(sb);
2617+ for (bindex = 0; bindex <= bend; bindex++)
2618+ if (au_sbr_id(sb, bindex) == br_id)
2619+ return bindex;
2620+ return -1;
2621+}
2622+
2623+/* ---------------------------------------------------------------------- */
2624+
2625+/*
2626+ * add a branch
2627+ */
2628+
b752ccd1
AM
2629+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2630+ struct dentry *h_root)
1facf9fc 2631+{
b752ccd1
AM
2632+ if (unlikely(h_adding == h_root
2633+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2634+ return 1;
b752ccd1
AM
2635+ if (h_adding->d_sb != h_root->d_sb)
2636+ return 0;
2637+ return au_test_subdir(h_adding, h_root)
2638+ || au_test_subdir(h_root, h_adding);
1facf9fc 2639+}
2640+
2641+/*
2642+ * returns a newly allocated branch. @new_nbranch is a number of branches
2643+ * after adding a branch.
2644+ */
2645+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2646+ int perm)
2647+{
2648+ struct au_branch *add_branch;
2649+ struct dentry *root;
4a4d8108 2650+ int err;
1facf9fc 2651+
4a4d8108 2652+ err = -ENOMEM;
1facf9fc 2653+ root = sb->s_root;
2654+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2655+ if (unlikely(!add_branch))
2656+ goto out;
2657+
027c5e7a
AM
2658+ err = au_hnotify_init_br(add_branch, perm);
2659+ if (unlikely(err))
2660+ goto out_br;
2661+
1facf9fc 2662+ add_branch->br_wbr = NULL;
2663+ if (au_br_writable(perm)) {
2664+ /* may be freed separately at changing the branch permission */
2665+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2666+ GFP_NOFS);
2667+ if (unlikely(!add_branch->br_wbr))
027c5e7a 2668+ goto out_hnotify;
1facf9fc 2669+ }
2670+
076b876e
AM
2671+ add_branch->br_fhsm = NULL;
2672+ if (au_br_fhsm(perm)) {
2673+ err = au_fhsm_br_alloc(add_branch);
2674+ if (unlikely(err))
2675+ goto out_wbr;
2676+ }
2677+
4a4d8108
AM
2678+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2679+ if (!err)
2680+ err = au_di_realloc(au_di(root), new_nbranch);
2681+ if (!err)
2682+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2683+ if (!err)
2684+ return add_branch; /* success */
1facf9fc 2685+
076b876e 2686+out_wbr:
1facf9fc 2687+ kfree(add_branch->br_wbr);
027c5e7a
AM
2688+out_hnotify:
2689+ au_hnotify_fin_br(add_branch);
4f0767ce 2690+out_br:
1facf9fc 2691+ kfree(add_branch);
4f0767ce 2692+out:
4a4d8108 2693+ return ERR_PTR(err);
1facf9fc 2694+}
2695+
2696+/*
2697+ * test if the branch permission is legal or not.
2698+ */
2699+static int test_br(struct inode *inode, int brperm, char *path)
2700+{
2701+ int err;
2702+
4a4d8108
AM
2703+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2704+ if (!err)
2705+ goto out;
1facf9fc 2706+
4a4d8108
AM
2707+ err = -EINVAL;
2708+ pr_err("write permission for readonly mount or inode, %s\n", path);
2709+
4f0767ce 2710+out:
1facf9fc 2711+ return err;
2712+}
2713+
2714+/*
2715+ * returns:
2716+ * 0: success, the caller will add it
2717+ * plus: success, it is already unified, the caller should ignore it
2718+ * minus: error
2719+ */
2720+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2721+{
2722+ int err;
2723+ aufs_bindex_t bend, bindex;
2724+ struct dentry *root;
2725+ struct inode *inode, *h_inode;
2726+
2727+ root = sb->s_root;
2728+ bend = au_sbend(sb);
2729+ if (unlikely(bend >= 0
2730+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2731+ err = 1;
2732+ if (!remount) {
2733+ err = -EINVAL;
4a4d8108 2734+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2735+ }
2736+ goto out;
2737+ }
2738+
2739+ err = -ENOSPC; /* -E2BIG; */
2740+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2741+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2742+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2743+ goto out;
2744+ }
2745+
2746+ err = -EDOM;
2747+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2748+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2749+ goto out;
2750+ }
2751+
2752+ inode = add->path.dentry->d_inode;
2753+ err = -ENOENT;
2754+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2755+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2756+ goto out;
2757+ }
2758+
2759+ err = -EINVAL;
2760+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2761+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2762+ goto out;
2763+ }
2764+
2765+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2766+ pr_err("unsupported filesystem, %s (%s)\n",
2767+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2768+ goto out;
2769+ }
2770+
2771+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2772+ if (unlikely(err))
2773+ goto out;
2774+
2775+ if (bend < 0)
2776+ return 0; /* success */
2777+
2778+ err = -EINVAL;
2779+ for (bindex = 0; bindex <= bend; bindex++)
2780+ if (unlikely(test_overlap(sb, add->path.dentry,
2781+ au_h_dptr(root, bindex)))) {
4a4d8108 2782+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 2783+ goto out;
2784+ }
2785+
2786+ err = 0;
2787+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2788+ h_inode = au_h_dptr(root, 0)->d_inode;
2789+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
2790+ || !uid_eq(h_inode->i_uid, inode->i_uid)
2791+ || !gid_eq(h_inode->i_gid, inode->i_gid))
2792+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2793+ add->pathname,
2794+ i_uid_read(inode), i_gid_read(inode),
2795+ (inode->i_mode & S_IALLUGO),
2796+ i_uid_read(h_inode), i_gid_read(h_inode),
2797+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 2798+ }
2799+
4f0767ce 2800+out:
1facf9fc 2801+ return err;
2802+}
2803+
2804+/*
2805+ * initialize or clean the whiteouts for an adding branch
2806+ */
2807+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 2808+ int new_perm)
1facf9fc 2809+{
2810+ int err, old_perm;
2811+ aufs_bindex_t bindex;
2812+ struct mutex *h_mtx;
2813+ struct au_wbr *wbr;
2814+ struct au_hinode *hdir;
2815+
86dc4139
AM
2816+ err = vfsub_mnt_want_write(au_br_mnt(br));
2817+ if (unlikely(err))
2818+ goto out;
2819+
1facf9fc 2820+ wbr = br->br_wbr;
2821+ old_perm = br->br_perm;
2822+ br->br_perm = new_perm;
2823+ hdir = NULL;
2824+ h_mtx = NULL;
2825+ bindex = au_br_index(sb, br->br_id);
2826+ if (0 <= bindex) {
2827+ hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 2828+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2829+ } else {
86dc4139 2830+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
1facf9fc 2831+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2832+ }
2833+ if (!wbr)
86dc4139 2834+ err = au_wh_init(br, sb);
1facf9fc 2835+ else {
2836+ wbr_wh_write_lock(wbr);
86dc4139 2837+ err = au_wh_init(br, sb);
1facf9fc 2838+ wbr_wh_write_unlock(wbr);
2839+ }
2840+ if (hdir)
4a4d8108 2841+ au_hn_imtx_unlock(hdir);
1facf9fc 2842+ else
2843+ mutex_unlock(h_mtx);
86dc4139 2844+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 2845+ br->br_perm = old_perm;
2846+
2847+ if (!err && wbr && !au_br_writable(new_perm)) {
2848+ kfree(wbr);
2849+ br->br_wbr = NULL;
2850+ }
2851+
86dc4139 2852+out:
1facf9fc 2853+ return err;
2854+}
2855+
2856+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 2857+ int perm)
1facf9fc 2858+{
2859+ int err;
4a4d8108 2860+ struct kstatfs kst;
1facf9fc 2861+ struct au_wbr *wbr;
2862+
2863+ wbr = br->br_wbr;
dece6358 2864+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 2865+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
2866+ atomic_set(&wbr->wbr_wh_running, 0);
2867+ wbr->wbr_bytes = 0;
2868+
4a4d8108
AM
2869+ /*
2870+ * a limit for rmdir/rename a dir
523b37e3 2871+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 2872+ */
86dc4139 2873+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
2874+ if (unlikely(err))
2875+ goto out;
2876+ err = -EINVAL;
2877+ if (kst.f_namelen >= NAME_MAX)
86dc4139 2878+ err = au_br_init_wh(sb, br, perm);
4a4d8108 2879+ else
523b37e3
AM
2880+ pr_err("%pd(%s), unsupported namelen %ld\n",
2881+ au_br_dentry(br),
86dc4139 2882+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 2883+
4f0767ce 2884+out:
1facf9fc 2885+ return err;
2886+}
2887+
2888+/* intialize a new branch */
2889+static int au_br_init(struct au_branch *br, struct super_block *sb,
2890+ struct au_opt_add *add)
2891+{
2892+ int err;
2893+
2894+ err = 0;
2895+ memset(&br->br_xino, 0, sizeof(br->br_xino));
2896+ mutex_init(&br->br_xino.xi_nondir_mtx);
2897+ br->br_perm = add->perm;
86dc4139
AM
2898+ BUILD_BUG_ON(sizeof(br->br_dflags)
2899+ != sizeof(br->br_path.dentry->d_flags));
2900+ br->br_dflags = DCACHE_MOUNTED;
2901+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108
AM
2902+ spin_lock_init(&br->br_dykey_lock);
2903+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 2904+ atomic_set(&br->br_count, 0);
1facf9fc 2905+ atomic_set(&br->br_xino_running, 0);
2906+ br->br_id = au_new_br_id(sb);
7f207e10 2907+ AuDebugOn(br->br_id < 0);
1facf9fc 2908+
2909+ if (au_br_writable(add->perm)) {
86dc4139 2910+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 2911+ if (unlikely(err))
b752ccd1 2912+ goto out_err;
1facf9fc 2913+ }
2914+
2915+ if (au_opt_test(au_mntflags(sb), XINO)) {
2916+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
2917+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
2918+ if (unlikely(err)) {
2919+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 2920+ goto out_err;
1facf9fc 2921+ }
2922+ }
2923+
2924+ sysaufs_br_init(br);
86dc4139 2925+ path_get(&br->br_path);
b752ccd1 2926+ goto out; /* success */
1facf9fc 2927+
4f0767ce 2928+out_err:
86dc4139 2929+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 2930+out:
1facf9fc 2931+ return err;
2932+}
2933+
2934+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
2935+ struct au_branch *br, aufs_bindex_t bend,
2936+ aufs_bindex_t amount)
2937+{
2938+ struct au_branch **brp;
2939+
dece6358
AM
2940+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2941+
1facf9fc 2942+ brp = sbinfo->si_branch + bindex;
2943+ memmove(brp + 1, brp, sizeof(*brp) * amount);
2944+ *brp = br;
2945+ sbinfo->si_bend++;
2946+ if (unlikely(bend < 0))
2947+ sbinfo->si_bend = 0;
2948+}
2949+
2950+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
2951+ aufs_bindex_t bend, aufs_bindex_t amount)
2952+{
2953+ struct au_hdentry *hdp;
2954+
1308ab2a 2955+ AuRwMustWriteLock(&dinfo->di_rwsem);
2956+
1facf9fc 2957+ hdp = dinfo->di_hdentry + bindex;
2958+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
2959+ au_h_dentry_init(hdp);
2960+ dinfo->di_bend++;
2961+ if (unlikely(bend < 0))
2962+ dinfo->di_bstart = 0;
2963+}
2964+
2965+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
2966+ aufs_bindex_t bend, aufs_bindex_t amount)
2967+{
2968+ struct au_hinode *hip;
2969+
1308ab2a 2970+ AuRwMustWriteLock(&iinfo->ii_rwsem);
2971+
1facf9fc 2972+ hip = iinfo->ii_hinode + bindex;
2973+ memmove(hip + 1, hip, sizeof(*hip) * amount);
2974+ hip->hi_inode = NULL;
4a4d8108 2975+ au_hn_init(hip);
1facf9fc 2976+ iinfo->ii_bend++;
2977+ if (unlikely(bend < 0))
2978+ iinfo->ii_bstart = 0;
2979+}
2980+
86dc4139
AM
2981+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
2982+ aufs_bindex_t bindex)
1facf9fc 2983+{
86dc4139 2984+ struct dentry *root, *h_dentry;
1facf9fc 2985+ struct inode *root_inode;
2986+ aufs_bindex_t bend, amount;
2987+
86dc4139
AM
2988+ au_br_dflags_force(br);
2989+
1facf9fc 2990+ root = sb->s_root;
2991+ root_inode = root->d_inode;
1facf9fc 2992+ bend = au_sbend(sb);
2993+ amount = bend + 1 - bindex;
86dc4139 2994+ h_dentry = au_br_dentry(br);
53392da6 2995+ au_sbilist_lock();
1facf9fc 2996+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
2997+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
2998+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
2999+ au_set_h_dptr(root, bindex, dget(h_dentry));
3000+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
3001+ /*flags*/0);
53392da6 3002+ au_sbilist_unlock();
1facf9fc 3003+}
3004+
3005+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3006+{
3007+ int err;
1facf9fc 3008+ aufs_bindex_t bend, add_bindex;
3009+ struct dentry *root, *h_dentry;
3010+ struct inode *root_inode;
3011+ struct au_branch *add_branch;
3012+
3013+ root = sb->s_root;
3014+ root_inode = root->d_inode;
3015+ IMustLock(root_inode);
3016+ err = test_add(sb, add, remount);
3017+ if (unlikely(err < 0))
3018+ goto out;
3019+ if (err) {
3020+ err = 0;
3021+ goto out; /* success */
3022+ }
3023+
3024+ bend = au_sbend(sb);
3025+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
3026+ err = PTR_ERR(add_branch);
3027+ if (IS_ERR(add_branch))
3028+ goto out;
3029+
3030+ err = au_br_init(add_branch, sb, add);
3031+ if (unlikely(err)) {
3032+ au_br_do_free(add_branch);
3033+ goto out;
3034+ }
3035+
3036+ add_bindex = add->bindex;
1facf9fc 3037+ if (!remount)
86dc4139 3038+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3039+ else {
3040+ sysaufs_brs_del(sb, add_bindex);
86dc4139 3041+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3042+ sysaufs_brs_add(sb, add_bindex);
3043+ }
3044+
86dc4139 3045+ h_dentry = add->path.dentry;
1308ab2a 3046+ if (!add_bindex) {
1facf9fc 3047+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3048+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3049+ } else
1facf9fc 3050+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 3051+
3052+ /*
4a4d8108 3053+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 3054+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 3055+ * once detached from aufs.
3056+ */
3057+ if (au_xino_brid(sb) < 0
3058+ && au_br_writable(add_branch->br_perm)
3059+ && !au_test_fs_bad_xino(h_dentry->d_sb)
3060+ && add_branch->br_xino.xi_file
3061+ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
3062+ au_xino_brid_set(sb, add_branch->br_id);
3063+
4f0767ce 3064+out:
1facf9fc 3065+ return err;
3066+}
3067+
3068+/* ---------------------------------------------------------------------- */
3069+
076b876e
AM
3070+static unsigned long long au_farray_cb(void *a,
3071+ unsigned long long max __maybe_unused,
3072+ void *arg)
3073+{
3074+ unsigned long long n;
3075+ struct file **p, *f;
3076+ struct au_sphlhead *files;
3077+ struct au_finfo *finfo;
3078+ struct super_block *sb = arg;
3079+
3080+ n = 0;
3081+ p = a;
3082+ files = &au_sbi(sb)->si_files;
3083+ spin_lock(&files->spin);
3084+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
3085+ f = finfo->fi_file;
3086+ if (file_count(f)
3087+ && !special_file(file_inode(f)->i_mode)) {
3088+ get_file(f);
3089+ *p++ = f;
3090+ n++;
3091+ AuDebugOn(n > max);
3092+ }
3093+ }
3094+ spin_unlock(&files->spin);
3095+
3096+ return n;
3097+}
3098+
3099+static struct file **au_farray_alloc(struct super_block *sb,
3100+ unsigned long long *max)
3101+{
3102+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
3103+ return au_array_alloc(max, au_farray_cb, sb);
3104+}
3105+
3106+static void au_farray_free(struct file **a, unsigned long long max)
3107+{
3108+ unsigned long long ull;
3109+
3110+ for (ull = 0; ull < max; ull++)
3111+ if (a[ull])
3112+ fput(a[ull]);
3113+ au_array_free(a);
3114+}
3115+
3116+/* ---------------------------------------------------------------------- */
3117+
1facf9fc 3118+/*
3119+ * delete a branch
3120+ */
3121+
3122+/* to show the line number, do not make it inlined function */
4a4d8108 3123+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3124+ if (do_info) \
4a4d8108 3125+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3126+} while (0)
3127+
027c5e7a
AM
3128+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
3129+ aufs_bindex_t bend)
3130+{
3131+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
3132+}
3133+
3134+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
3135+ aufs_bindex_t bend)
3136+{
3137+ return au_test_ibusy(dentry->d_inode, bstart, bend);
3138+}
3139+
1facf9fc 3140+/*
3141+ * test if the branch is deletable or not.
3142+ */
3143+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3144+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3145+{
3146+ int err, i, j, ndentry;
3147+ aufs_bindex_t bstart, bend;
1facf9fc 3148+ struct au_dcsub_pages dpages;
3149+ struct au_dpage *dpage;
3150+ struct dentry *d;
1facf9fc 3151+
3152+ err = au_dpages_init(&dpages, GFP_NOFS);
3153+ if (unlikely(err))
3154+ goto out;
3155+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3156+ if (unlikely(err))
3157+ goto out_dpages;
3158+
1facf9fc 3159+ for (i = 0; !err && i < dpages.ndpage; i++) {
3160+ dpage = dpages.dpages + i;
3161+ ndentry = dpage->ndentry;
3162+ for (j = 0; !err && j < ndentry; j++) {
3163+ d = dpage->dentries[j];
392086de 3164+ AuDebugOn(!d_count(d));
027c5e7a 3165+ if (!au_digen_test(d, sigen)) {
1facf9fc 3166+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3167+ if (unlikely(au_dbrange_test(d))) {
3168+ di_read_unlock(d, AuLock_IR);
3169+ continue;
3170+ }
3171+ } else {
1facf9fc 3172+ di_write_lock_child(d);
027c5e7a
AM
3173+ if (unlikely(au_dbrange_test(d))) {
3174+ di_write_unlock(d);
3175+ continue;
3176+ }
1facf9fc 3177+ err = au_reval_dpath(d, sigen);
3178+ if (!err)
3179+ di_downgrade_lock(d, AuLock_IR);
3180+ else {
3181+ di_write_unlock(d);
3182+ break;
3183+ }
3184+ }
3185+
027c5e7a 3186+ /* AuDbgDentry(d); */
1facf9fc 3187+ bstart = au_dbstart(d);
3188+ bend = au_dbend(d);
3189+ if (bstart <= bindex
3190+ && bindex <= bend
3191+ && au_h_dptr(d, bindex)
027c5e7a 3192+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 3193+ err = -EBUSY;
523b37e3 3194+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3195+ AuDbgDentry(d);
1facf9fc 3196+ }
3197+ di_read_unlock(d, AuLock_IR);
3198+ }
3199+ }
3200+
4f0767ce 3201+out_dpages:
1facf9fc 3202+ au_dpages_free(&dpages);
4f0767ce 3203+out:
1facf9fc 3204+ return err;
3205+}
3206+
3207+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3208+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3209+{
3210+ int err;
7f207e10
AM
3211+ unsigned long long max, ull;
3212+ struct inode *i, **array;
1facf9fc 3213+ aufs_bindex_t bstart, bend;
1facf9fc 3214+
7f207e10
AM
3215+ array = au_iarray_alloc(sb, &max);
3216+ err = PTR_ERR(array);
3217+ if (IS_ERR(array))
3218+ goto out;
3219+
1facf9fc 3220+ err = 0;
7f207e10
AM
3221+ AuDbg("b%d\n", bindex);
3222+ for (ull = 0; !err && ull < max; ull++) {
3223+ i = array[ull];
076b876e
AM
3224+ if (unlikely(!i))
3225+ break;
7f207e10 3226+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3227+ continue;
3228+
7f207e10 3229+ /* AuDbgInode(i); */
537831f9 3230+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3231+ ii_read_lock_child(i);
3232+ else {
3233+ ii_write_lock_child(i);
027c5e7a
AM
3234+ err = au_refresh_hinode_self(i);
3235+ au_iigen_dec(i);
1facf9fc 3236+ if (!err)
3237+ ii_downgrade_lock(i);
3238+ else {
3239+ ii_write_unlock(i);
3240+ break;
3241+ }
3242+ }
3243+
3244+ bstart = au_ibstart(i);
3245+ bend = au_ibend(i);
3246+ if (bstart <= bindex
3247+ && bindex <= bend
3248+ && au_h_iptr(i, bindex)
027c5e7a 3249+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 3250+ err = -EBUSY;
3251+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3252+ AuDbgInode(i);
1facf9fc 3253+ }
3254+ ii_read_unlock(i);
3255+ }
7f207e10 3256+ au_iarray_free(array, max);
1facf9fc 3257+
7f207e10 3258+out:
1facf9fc 3259+ return err;
3260+}
3261+
b752ccd1
AM
3262+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3263+ const unsigned int verbose)
1facf9fc 3264+{
3265+ int err;
3266+ unsigned int sigen;
3267+
3268+ sigen = au_sigen(root->d_sb);
3269+ DiMustNoWaiters(root);
3270+ IiMustNoWaiters(root->d_inode);
3271+ di_write_unlock(root);
b752ccd1 3272+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3273+ if (!err)
b752ccd1 3274+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3275+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3276+
3277+ return err;
3278+}
3279+
076b876e
AM
3280+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3281+ struct file **to_free, int *idx)
3282+{
3283+ int err;
3284+ unsigned char matched, unmatched;
3285+ aufs_bindex_t bindex, bend;
3286+ struct au_fidir *fidir;
3287+ struct au_hfile *hfile;
3288+
3289+ err = 0;
3290+ matched = 0;
3291+ unmatched = 0;
3292+ fidir = au_fi(file)->fi_hdir;
3293+ AuDebugOn(!fidir);
3294+ bend = au_fbend_dir(file);
3295+ for (bindex = au_fbstart(file); bindex <= bend; bindex++) {
3296+ hfile = fidir->fd_hfile + bindex;
3297+ if (!hfile->hf_file)
3298+ continue;
3299+
3300+ if (hfile->hf_br->br_id == br_id)
3301+ matched = 1;
3302+ else
3303+ unmatched = 1;
3304+ if (matched && unmatched)
3305+ break;
3306+ }
3307+ if (!matched)
3308+ goto out; /* success */
3309+
3310+ if (unmatched) {
3311+ get_file(file);
3312+ to_free[*idx] = file;
3313+ (*idx)++;
3314+ } else
3315+ err = -EBUSY;
3316+
3317+out:
3318+ return err;
3319+}
3320+
3321+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3322+ struct file **to_free, int opened)
3323+{
3324+ int err, idx;
3325+ unsigned long long ull, max;
3326+ aufs_bindex_t bstart;
3327+ struct file *file, **array;
3328+ struct inode *inode;
3329+ struct dentry *root;
3330+ struct au_hfile *hfile;
3331+
3332+ array = au_farray_alloc(sb, &max);
3333+ err = PTR_ERR(array);
3334+ if (IS_ERR(array))
3335+ goto out;
3336+
3337+ err = 0;
3338+ idx = 0;
3339+ root = sb->s_root;
3340+ di_write_unlock(root);
3341+ for (ull = 0; ull < max; ull++) {
3342+ file = array[ull];
3343+ if (unlikely(!file))
3344+ break;
3345+
3346+ /* AuDbg("%pD\n", file); */
3347+ fi_read_lock(file);
3348+ bstart = au_fbstart(file);
3349+ inode = file_inode(file);
3350+ if (!S_ISDIR(inode->i_mode)) {
3351+ hfile = &au_fi(file)->fi_htop;
3352+ if (hfile->hf_br->br_id == br_id)
3353+ err = -EBUSY;
3354+ } else
3355+ err = test_dir_busy(file, br_id, to_free, &idx);
3356+ fi_read_unlock(file);
3357+ if (unlikely(err))
3358+ break;
3359+ }
3360+ di_write_lock_child(root);
3361+ au_farray_free(array, max);
3362+ AuDebugOn(idx > opened);
3363+
3364+out:
3365+ return err;
3366+}
3367+
3368+static void br_del_file(struct file **to_free, unsigned long long opened,
3369+ aufs_bindex_t br_id)
3370+{
3371+ unsigned long long ull;
3372+ aufs_bindex_t bindex, bstart, bend, bfound;
3373+ struct file *file;
3374+ struct au_fidir *fidir;
3375+ struct au_hfile *hfile;
3376+
3377+ for (ull = 0; ull < opened; ull++) {
3378+ file = to_free[ull];
3379+ if (unlikely(!file))
3380+ break;
3381+
3382+ /* AuDbg("%pD\n", file); */
3383+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
3384+ bfound = -1;
3385+ fidir = au_fi(file)->fi_hdir;
3386+ AuDebugOn(!fidir);
3387+ fi_write_lock(file);
3388+ bstart = au_fbstart(file);
3389+ bend = au_fbend_dir(file);
3390+ for (bindex = bstart; bindex <= bend; bindex++) {
3391+ hfile = fidir->fd_hfile + bindex;
3392+ if (!hfile->hf_file)
3393+ continue;
3394+
3395+ if (hfile->hf_br->br_id == br_id) {
3396+ bfound = bindex;
3397+ break;
3398+ }
3399+ }
3400+ AuDebugOn(bfound < 0);
3401+ au_set_h_fptr(file, bfound, NULL);
3402+ if (bfound == bstart) {
3403+ for (bstart++; bstart <= bend; bstart++)
3404+ if (au_hf_dir(file, bstart)) {
3405+ au_set_fbstart(file, bstart);
3406+ break;
3407+ }
3408+ }
3409+ fi_write_unlock(file);
3410+ }
3411+}
3412+
1facf9fc 3413+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
3414+ const aufs_bindex_t bindex,
3415+ const aufs_bindex_t bend)
3416+{
3417+ struct au_branch **brp, **p;
3418+
dece6358
AM
3419+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3420+
1facf9fc 3421+ brp = sbinfo->si_branch + bindex;
3422+ if (bindex < bend)
3423+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
3424+ sbinfo->si_branch[0 + bend] = NULL;
3425+ sbinfo->si_bend--;
3426+
53392da6 3427+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3428+ if (p)
3429+ sbinfo->si_branch = p;
4a4d8108 3430+ /* harmless error */
1facf9fc 3431+}
3432+
3433+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
3434+ const aufs_bindex_t bend)
3435+{
3436+ struct au_hdentry *hdp, *p;
3437+
1308ab2a 3438+ AuRwMustWriteLock(&dinfo->di_rwsem);
3439+
4a4d8108 3440+ hdp = dinfo->di_hdentry;
1facf9fc 3441+ if (bindex < bend)
4a4d8108
AM
3442+ memmove(hdp + bindex, hdp + bindex + 1,
3443+ sizeof(*hdp) * (bend - bindex));
3444+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 3445+ dinfo->di_bend--;
3446+
53392da6 3447+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3448+ if (p)
3449+ dinfo->di_hdentry = p;
4a4d8108 3450+ /* harmless error */
1facf9fc 3451+}
3452+
3453+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
3454+ const aufs_bindex_t bend)
3455+{
3456+ struct au_hinode *hip, *p;
3457+
1308ab2a 3458+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3459+
1facf9fc 3460+ hip = iinfo->ii_hinode + bindex;
3461+ if (bindex < bend)
3462+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
3463+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 3464+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 3465+ iinfo->ii_bend--;
3466+
53392da6 3467+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3468+ if (p)
3469+ iinfo->ii_hinode = p;
4a4d8108 3470+ /* harmless error */
1facf9fc 3471+}
3472+
3473+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
3474+ struct au_branch *br)
3475+{
3476+ aufs_bindex_t bend;
3477+ struct au_sbinfo *sbinfo;
53392da6
AM
3478+ struct dentry *root, *h_root;
3479+ struct inode *inode, *h_inode;
3480+ struct au_hinode *hinode;
1facf9fc 3481+
dece6358
AM
3482+ SiMustWriteLock(sb);
3483+
1facf9fc 3484+ root = sb->s_root;
3485+ inode = root->d_inode;
1facf9fc 3486+ sbinfo = au_sbi(sb);
3487+ bend = sbinfo->si_bend;
3488+
53392da6
AM
3489+ h_root = au_h_dptr(root, bindex);
3490+ hinode = au_hi(inode, bindex);
3491+ h_inode = au_igrab(hinode->hi_inode);
3492+ au_hiput(hinode);
1facf9fc 3493+
53392da6 3494+ au_sbilist_lock();
1facf9fc 3495+ au_br_do_del_brp(sbinfo, bindex, bend);
3496+ au_br_do_del_hdp(au_di(root), bindex, bend);
3497+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
3498+ au_sbilist_unlock();
3499+
3500+ dput(h_root);
3501+ iput(h_inode);
3502+ au_br_do_free(br);
1facf9fc 3503+}
3504+
076b876e
AM
3505+static unsigned long long empty_cb(void *array, unsigned long long max,
3506+ void *arg)
3507+{
3508+ return max;
3509+}
3510+
1facf9fc 3511+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
3512+{
3513+ int err, rerr, i;
076b876e 3514+ unsigned long long opened;
1facf9fc 3515+ unsigned int mnt_flags;
3516+ aufs_bindex_t bindex, bend, br_id;
3517+ unsigned char do_wh, verbose;
3518+ struct au_branch *br;
3519+ struct au_wbr *wbr;
076b876e
AM
3520+ struct dentry *root;
3521+ struct file **to_free;
1facf9fc 3522+
3523+ err = 0;
076b876e
AM
3524+ opened = 0;
3525+ to_free = NULL;
3526+ root = sb->s_root;
3527+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 3528+ if (bindex < 0) {
3529+ if (remount)
3530+ goto out; /* success */
3531+ err = -ENOENT;
4a4d8108 3532+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 3533+ goto out;
3534+ }
3535+ AuDbg("bindex b%d\n", bindex);
3536+
3537+ err = -EBUSY;
3538+ mnt_flags = au_mntflags(sb);
3539+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3540+ bend = au_sbend(sb);
3541+ if (unlikely(!bend)) {
3542+ AuVerbose(verbose, "no more branches left\n");
3543+ goto out;
3544+ }
3545+ br = au_sbr(sb, bindex);
86dc4139 3546+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
076b876e
AM
3547+
3548+ br_id = br->br_id;
3549+ opened = atomic_read(&br->br_count);
3550+ if (unlikely(opened)) {
3551+ to_free = au_array_alloc(&opened, empty_cb, NULL);
3552+ err = PTR_ERR(to_free);
3553+ if (IS_ERR(to_free))
3554+ goto out;
3555+
3556+ err = test_file_busy(sb, br_id, to_free, opened);
3557+ if (unlikely(err)) {
3558+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
3559+ goto out;
3560+ }
1facf9fc 3561+ }
3562+
3563+ wbr = br->br_wbr;
3564+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
3565+ if (do_wh) {
1308ab2a 3566+ /* instead of WbrWhMustWriteLock(wbr) */
3567+ SiMustWriteLock(sb);
1facf9fc 3568+ for (i = 0; i < AuBrWh_Last; i++) {
3569+ dput(wbr->wbr_wh[i]);
3570+ wbr->wbr_wh[i] = NULL;
3571+ }
3572+ }
3573+
076b876e 3574+ err = test_children_busy(root, bindex, verbose);
1facf9fc 3575+ if (unlikely(err)) {
3576+ if (do_wh)
3577+ goto out_wh;
3578+ goto out;
3579+ }
3580+
3581+ err = 0;
076b876e
AM
3582+ if (to_free) {
3583+ /*
3584+ * now we confirmed the branch is deletable.
3585+ * let's free the remaining opened dirs on the branch.
3586+ */
3587+ di_write_unlock(root);
3588+ br_del_file(to_free, opened, br_id);
3589+ di_write_lock_child(root);
3590+ }
3591+
1facf9fc 3592+ if (!remount)
3593+ au_br_do_del(sb, bindex, br);
3594+ else {
3595+ sysaufs_brs_del(sb, bindex);
3596+ au_br_do_del(sb, bindex, br);
3597+ sysaufs_brs_add(sb, bindex);
3598+ }
3599+
1308ab2a 3600+ if (!bindex) {
076b876e 3601+ au_cpup_attr_all(root->d_inode, /*force*/1);
1308ab2a 3602+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
3603+ } else
076b876e 3604+ au_sub_nlink(root->d_inode, del->h_path.dentry->d_inode);
1facf9fc 3605+ if (au_opt_test(mnt_flags, PLINK))
3606+ au_plink_half_refresh(sb, br_id);
3607+
b752ccd1 3608+ if (au_xino_brid(sb) == br_id)
1facf9fc 3609+ au_xino_brid_set(sb, -1);
3610+ goto out; /* success */
3611+
4f0767ce 3612+out_wh:
1facf9fc 3613+ /* revert */
86dc4139 3614+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 3615+ if (rerr)
0c3ec466
AM
3616+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
3617+ del->pathname, rerr);
4f0767ce 3618+out:
076b876e
AM
3619+ if (to_free)
3620+ au_farray_free(to_free, opened);
1facf9fc 3621+ return err;
3622+}
3623+
3624+/* ---------------------------------------------------------------------- */
3625+
027c5e7a
AM
3626+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
3627+{
3628+ int err;
3629+ aufs_bindex_t bstart, bend;
3630+ struct aufs_ibusy ibusy;
3631+ struct inode *inode, *h_inode;
3632+
3633+ err = -EPERM;
3634+ if (unlikely(!capable(CAP_SYS_ADMIN)))
3635+ goto out;
3636+
3637+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
3638+ if (!err)
3639+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
3640+ if (unlikely(err)) {
3641+ err = -EFAULT;
3642+ AuTraceErr(err);
3643+ goto out;
3644+ }
3645+
3646+ err = -EINVAL;
3647+ si_read_lock(sb, AuLock_FLUSH);
3648+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
3649+ goto out_unlock;
3650+
3651+ err = 0;
3652+ ibusy.h_ino = 0; /* invalid */
3653+ inode = ilookup(sb, ibusy.ino);
3654+ if (!inode
3655+ || inode->i_ino == AUFS_ROOT_INO
3656+ || is_bad_inode(inode))
3657+ goto out_unlock;
3658+
3659+ ii_read_lock_child(inode);
3660+ bstart = au_ibstart(inode);
3661+ bend = au_ibend(inode);
3662+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
3663+ h_inode = au_h_iptr(inode, ibusy.bindex);
3664+ if (h_inode && au_test_ibusy(inode, bstart, bend))
3665+ ibusy.h_ino = h_inode->i_ino;
3666+ }
3667+ ii_read_unlock(inode);
3668+ iput(inode);
3669+
3670+out_unlock:
3671+ si_read_unlock(sb);
3672+ if (!err) {
3673+ err = __put_user(ibusy.h_ino, &arg->h_ino);
3674+ if (unlikely(err)) {
3675+ err = -EFAULT;
3676+ AuTraceErr(err);
3677+ }
3678+ }
3679+out:
3680+ return err;
3681+}
3682+
3683+long au_ibusy_ioctl(struct file *file, unsigned long arg)
3684+{
3685+ return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
3686+}
3687+
3688+#ifdef CONFIG_COMPAT
3689+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
3690+{
3691+ return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
3692+}
3693+#endif
3694+
3695+/* ---------------------------------------------------------------------- */
3696+
1facf9fc 3697+/*
3698+ * change a branch permission
3699+ */
3700+
dece6358
AM
3701+static void au_warn_ima(void)
3702+{
3703+#ifdef CONFIG_IMA
1308ab2a 3704+ /* since it doesn't support mark_files_ro() */
027c5e7a 3705+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
3706+#endif
3707+}
3708+
1facf9fc 3709+static int do_need_sigen_inc(int a, int b)
3710+{
3711+ return au_br_whable(a) && !au_br_whable(b);
3712+}
3713+
3714+static int need_sigen_inc(int old, int new)
3715+{
3716+ return do_need_sigen_inc(old, new)
3717+ || do_need_sigen_inc(new, old);
3718+}
3719+
3720+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
3721+{
7f207e10 3722+ int err, do_warn;
027c5e7a 3723+ unsigned int mnt_flags;
7f207e10 3724+ unsigned long long ull, max;
e49829fe 3725+ aufs_bindex_t br_id;
38d290e6 3726+ unsigned char verbose, writer;
7f207e10 3727+ struct file *file, *hf, **array;
e49829fe
JR
3728+ struct inode *inode;
3729+ struct au_hfile *hfile;
1facf9fc 3730+
027c5e7a
AM
3731+ mnt_flags = au_mntflags(sb);
3732+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3733+
7f207e10
AM
3734+ array = au_farray_alloc(sb, &max);
3735+ err = PTR_ERR(array);
3736+ if (IS_ERR(array))
1facf9fc 3737+ goto out;
3738+
7f207e10 3739+ do_warn = 0;
e49829fe 3740+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
3741+ for (ull = 0; ull < max; ull++) {
3742+ file = array[ull];
076b876e
AM
3743+ if (unlikely(!file))
3744+ break;
1facf9fc 3745+
523b37e3 3746+ /* AuDbg("%pD\n", file); */
1facf9fc 3747+ fi_read_lock(file);
3748+ if (unlikely(au_test_mmapped(file))) {
3749+ err = -EBUSY;
523b37e3 3750+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 3751+ AuDbgFile(file);
1facf9fc 3752+ FiMustNoWaiters(file);
3753+ fi_read_unlock(file);
7f207e10 3754+ goto out_array;
1facf9fc 3755+ }
3756+
c06a8ce3 3757+ inode = file_inode(file);
e49829fe
JR
3758+ hfile = &au_fi(file)->fi_htop;
3759+ hf = hfile->hf_file;
3760+ if (!S_ISREG(inode->i_mode)
1facf9fc 3761+ || !(file->f_mode & FMODE_WRITE)
e49829fe 3762+ || hfile->hf_br->br_id != br_id
7f207e10
AM
3763+ || !(hf->f_mode & FMODE_WRITE))
3764+ array[ull] = NULL;
3765+ else {
3766+ do_warn = 1;
3767+ get_file(file);
1facf9fc 3768+ }
3769+
1facf9fc 3770+ FiMustNoWaiters(file);
3771+ fi_read_unlock(file);
7f207e10
AM
3772+ fput(file);
3773+ }
1facf9fc 3774+
3775+ err = 0;
7f207e10 3776+ if (do_warn)
dece6358 3777+ au_warn_ima();
7f207e10
AM
3778+
3779+ for (ull = 0; ull < max; ull++) {
3780+ file = array[ull];
3781+ if (!file)
3782+ continue;
3783+
1facf9fc 3784+ /* todo: already flushed? */
523b37e3
AM
3785+ /*
3786+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
3787+ * approach which resets f_mode and calls mnt_drop_write() and
3788+ * file_release_write() for each file, because the branch
3789+ * attribute in aufs world is totally different from the native
3790+ * fs rw/ro mode.
3791+ */
7f207e10
AM
3792+ /* fi_read_lock(file); */
3793+ hfile = &au_fi(file)->fi_htop;
3794+ hf = hfile->hf_file;
3795+ /* fi_read_unlock(file); */
027c5e7a 3796+ spin_lock(&hf->f_lock);
38d290e6
JR
3797+ writer = !!(hf->f_mode & FMODE_WRITER);
3798+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 3799+ spin_unlock(&hf->f_lock);
38d290e6
JR
3800+ if (writer) {
3801+ put_write_access(file_inode(hf));
c06a8ce3 3802+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 3803+ }
3804+ }
3805+
7f207e10
AM
3806+out_array:
3807+ au_farray_free(array, max);
4f0767ce 3808+out:
7f207e10 3809+ AuTraceErr(err);
1facf9fc 3810+ return err;
3811+}
3812+
3813+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3814+ int *do_refresh)
1facf9fc 3815+{
3816+ int err, rerr;
3817+ aufs_bindex_t bindex;
3818+ struct dentry *root;
3819+ struct au_branch *br;
076b876e 3820+ struct au_br_fhsm *bf;
1facf9fc 3821+
3822+ root = sb->s_root;
1facf9fc 3823+ bindex = au_find_dbindex(root, mod->h_root);
3824+ if (bindex < 0) {
3825+ if (remount)
3826+ return 0; /* success */
3827+ err = -ENOENT;
4a4d8108 3828+ pr_err("%s no such branch\n", mod->path);
1facf9fc 3829+ goto out;
3830+ }
3831+ AuDbg("bindex b%d\n", bindex);
3832+
3833+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3834+ if (unlikely(err))
3835+ goto out;
3836+
3837+ br = au_sbr(sb, bindex);
86dc4139 3838+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 3839+ if (br->br_perm == mod->perm)
3840+ return 0; /* success */
3841+
076b876e
AM
3842+ /* pre-allocate for non-fhsm --> fhsm */
3843+ bf = NULL;
3844+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
3845+ err = au_fhsm_br_alloc(br);
3846+ if (unlikely(err))
3847+ goto out;
3848+ bf = br->br_fhsm;
3849+ br->br_fhsm = NULL;
3850+ }
3851+
1facf9fc 3852+ if (au_br_writable(br->br_perm)) {
3853+ /* remove whiteout base */
86dc4139 3854+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 3855+ if (unlikely(err))
076b876e 3856+ goto out_bf;
1facf9fc 3857+
3858+ if (!au_br_writable(mod->perm)) {
3859+ /* rw --> ro, file might be mmapped */
3860+ DiMustNoWaiters(root);
3861+ IiMustNoWaiters(root->d_inode);
3862+ di_write_unlock(root);
3863+ err = au_br_mod_files_ro(sb, bindex);
3864+ /* aufs_write_lock() calls ..._child() */
3865+ di_write_lock_child(root);
3866+
3867+ if (unlikely(err)) {
3868+ rerr = -ENOMEM;
3869+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
3870+ GFP_NOFS);
86dc4139
AM
3871+ if (br->br_wbr)
3872+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 3873+ if (unlikely(rerr)) {
3874+ AuIOErr("nested error %d (%d)\n",
3875+ rerr, err);
3876+ br->br_perm = mod->perm;
3877+ }
3878+ }
3879+ }
3880+ } else if (au_br_writable(mod->perm)) {
3881+ /* ro --> rw */
3882+ err = -ENOMEM;
3883+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
3884+ if (br->br_wbr) {
86dc4139 3885+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 3886+ if (unlikely(err)) {
3887+ kfree(br->br_wbr);
3888+ br->br_wbr = NULL;
3889+ }
3890+ }
3891+ }
076b876e
AM
3892+ if (unlikely(err))
3893+ goto out_bf;
3894+
3895+ if (au_br_fhsm(br->br_perm)) {
3896+ if (!au_br_fhsm(mod->perm)) {
3897+ /* fhsm --> non-fhsm */
3898+ au_br_fhsm_fin(br->br_fhsm);
3899+ kfree(br->br_fhsm);
3900+ br->br_fhsm = NULL;
3901+ }
3902+ } else if (au_br_fhsm(mod->perm))
3903+ /* non-fhsm --> fhsm */
3904+ br->br_fhsm = bf;
3905+
3906+ if ((br->br_perm & AuBrAttr_UNPIN)
3907+ && !(mod->perm & AuBrAttr_UNPIN))
3908+ au_br_dflags_force(br);
3909+ else if (!(br->br_perm & AuBrAttr_UNPIN)
3910+ && (mod->perm & AuBrAttr_UNPIN))
3911+ au_br_dflags_restore(br);
3912+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
3913+ br->br_perm = mod->perm;
3914+ goto out; /* success */
1facf9fc 3915+
076b876e
AM
3916+out_bf:
3917+ kfree(bf);
3918+out:
3919+ AuTraceErr(err);
3920+ return err;
3921+}
3922+
3923+/* ---------------------------------------------------------------------- */
3924+
3925+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
3926+{
3927+ int err;
3928+ struct kstatfs kstfs;
3929+
3930+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 3931+ if (!err) {
076b876e
AM
3932+ stfs->f_blocks = kstfs.f_blocks;
3933+ stfs->f_bavail = kstfs.f_bavail;
3934+ stfs->f_files = kstfs.f_files;
3935+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 3936+ }
3937+
1facf9fc 3938+ return err;
3939+}
7f207e10
AM
3940diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
3941--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
3942+++ linux/fs/aufs/branch.h 2014-08-14 10:15:45.118609182 +0200
3943@@ -0,0 +1,268 @@
1facf9fc 3944+/*
523b37e3 3945+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 3946+ *
3947+ * This program, aufs is free software; you can redistribute it and/or modify
3948+ * it under the terms of the GNU General Public License as published by
3949+ * the Free Software Foundation; either version 2 of the License, or
3950+ * (at your option) any later version.
dece6358
AM
3951+ *
3952+ * This program is distributed in the hope that it will be useful,
3953+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3954+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3955+ * GNU General Public License for more details.
3956+ *
3957+ * You should have received a copy of the GNU General Public License
523b37e3 3958+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 3959+ */
3960+
3961+/*
3962+ * branch filesystems and xino for them
3963+ */
3964+
3965+#ifndef __AUFS_BRANCH_H__
3966+#define __AUFS_BRANCH_H__
3967+
3968+#ifdef __KERNEL__
3969+
1facf9fc 3970+#include <linux/mount.h>
4a4d8108 3971+#include "dynop.h"
1facf9fc 3972+#include "rwsem.h"
3973+#include "super.h"
3974+
3975+/* ---------------------------------------------------------------------- */
3976+
3977+/* a xino file */
3978+struct au_xino_file {
3979+ struct file *xi_file;
3980+ struct mutex xi_nondir_mtx;
3981+
3982+ /* todo: make xino files an array to support huge inode number */
3983+
3984+#ifdef CONFIG_DEBUG_FS
3985+ struct dentry *xi_dbgaufs;
3986+#endif
3987+};
3988+
076b876e
AM
3989+/* File-based Hierarchical Storage Management */
3990+struct au_br_fhsm {
3991+#ifdef CONFIG_AUFS_FHSM
3992+ struct mutex bf_lock;
3993+ unsigned long bf_jiffy;
3994+ struct aufs_stfs bf_stfs;
3995+ int bf_readable;
3996+#endif
3997+};
3998+
1facf9fc 3999+/* members for writable branch only */
4000+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4001+struct au_wbr {
dece6358 4002+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4003+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4004+ atomic_t wbr_wh_running;
1facf9fc 4005+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4006+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4007+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4008+
4009+ /* mfs mode */
4010+ unsigned long long wbr_bytes;
4011+};
4012+
4a4d8108
AM
4013+/* ext2 has 3 types of operations at least, ext3 has 4 */
4014+#define AuBrDynOp (AuDyLast * 4)
4015+
1716fcea
AM
4016+#ifdef CONFIG_AUFS_HFSNOTIFY
4017+/* support for asynchronous destruction */
4018+struct au_br_hfsnotify {
4019+ struct fsnotify_group *hfsn_group;
4020+};
4021+#endif
4022+
392086de
AM
4023+/* sysfs entries */
4024+struct au_brsysfs {
4025+ char name[16];
4026+ struct attribute attr;
4027+};
4028+
4029+enum {
4030+ AuBrSysfs_BR,
4031+ AuBrSysfs_BRID,
4032+ AuBrSysfs_Last
4033+};
4034+
1facf9fc 4035+/* protected by superblock rwsem */
4036+struct au_branch {
4037+ struct au_xino_file br_xino;
4038+
4039+ aufs_bindex_t br_id;
4040+
4041+ int br_perm;
86dc4139
AM
4042+ unsigned int br_dflags;
4043+ struct path br_path;
4a4d8108
AM
4044+ spinlock_t br_dykey_lock;
4045+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 4046+ atomic_t br_count;
4047+
4048+ struct au_wbr *br_wbr;
076b876e 4049+ struct au_br_fhsm *br_fhsm;
1facf9fc 4050+
4051+ /* xino truncation */
1facf9fc 4052+ atomic_t br_xino_running;
4053+
027c5e7a 4054+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4055+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4056+#endif
4057+
1facf9fc 4058+#ifdef CONFIG_SYSFS
392086de
AM
4059+ /* entries under sysfs per mount-point */
4060+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4061+#endif
4062+};
4063+
4064+/* ---------------------------------------------------------------------- */
4065+
86dc4139
AM
4066+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4067+{
4068+ return br->br_path.mnt;
4069+}
4070+
4071+static inline struct dentry *au_br_dentry(struct au_branch *br)
4072+{
4073+ return br->br_path.dentry;
4074+}
4075+
4076+static inline struct super_block *au_br_sb(struct au_branch *br)
4077+{
4078+ return au_br_mnt(br)->mnt_sb;
4079+}
4080+
1facf9fc 4081+static inline int au_br_rdonly(struct au_branch *br)
4082+{
86dc4139 4083+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 4084+ || !au_br_writable(br->br_perm))
4085+ ? -EROFS : 0;
4086+}
4087+
4a4d8108 4088+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4089+{
4a4d8108 4090+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4091+ return !(brperm & AuBrPerm_RR);
1facf9fc 4092+#else
4093+ return 0;
4094+#endif
4095+}
4096+
4097+/* ---------------------------------------------------------------------- */
4098+
4099+/* branch.c */
4100+struct au_sbinfo;
4101+void au_br_free(struct au_sbinfo *sinfo);
4102+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4103+struct au_opt_add;
4104+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4105+struct au_opt_del;
4106+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4107+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4108+#ifdef CONFIG_COMPAT
4109+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4110+#endif
1facf9fc 4111+struct au_opt_mod;
4112+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4113+ int *do_refresh);
076b876e
AM
4114+struct aufs_stfs;
4115+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4116+
4117+/* xino.c */
4118+static const loff_t au_loff_max = LLONG_MAX;
4119+
4120+int au_xib_trunc(struct super_block *sb);
4121+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
4122+ loff_t *pos);
4123+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
4124+ loff_t *pos);
4125+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
4126+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
4127+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 4128+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4129+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4130+ ino_t ino);
4131+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4132+ ino_t *ino);
4133+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4134+ struct file *base_file, int do_test);
4135+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
4136+
4137+struct au_opt_xino;
4138+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
4139+void au_xino_clr(struct super_block *sb);
4140+struct file *au_xino_def(struct super_block *sb);
4141+int au_xino_path(struct seq_file *seq, struct file *file);
4142+
4143+/* ---------------------------------------------------------------------- */
4144+
4145+/* Superblock to branch */
4146+static inline
4147+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4148+{
4149+ return au_sbr(sb, bindex)->br_id;
4150+}
4151+
4152+static inline
4153+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4154+{
86dc4139 4155+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4156+}
4157+
4158+static inline
4159+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4160+{
86dc4139 4161+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4162+}
4163+
4164+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
4165+{
e49829fe 4166+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 4167+}
4168+
4169+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4170+{
4171+ return au_sbr(sb, bindex)->br_perm;
4172+}
4173+
4174+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4175+{
4176+ return au_br_whable(au_sbr_perm(sb, bindex));
4177+}
4178+
4179+/* ---------------------------------------------------------------------- */
4180+
4181+/*
4182+ * wbr_wh_read_lock, wbr_wh_write_lock
4183+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
4184+ */
4185+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
4186+
dece6358
AM
4187+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
4188+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
4189+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
4190+
076b876e
AM
4191+/* ---------------------------------------------------------------------- */
4192+
4193+#ifdef CONFIG_AUFS_FHSM
4194+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4195+{
4196+ mutex_init(&brfhsm->bf_lock);
4197+ brfhsm->bf_jiffy = 0;
4198+ brfhsm->bf_readable = 0;
4199+}
4200+
4201+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4202+{
4203+ mutex_destroy(&brfhsm->bf_lock);
4204+}
4205+#else
4206+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4207+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4208+#endif
4209+
1facf9fc 4210+#endif /* __KERNEL__ */
4211+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4212diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4213--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
4214+++ linux/fs/aufs/conf.mk 2014-08-14 10:15:45.118609182 +0200
4215@@ -0,0 +1,37 @@
4a4d8108
AM
4216+
4217+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4218+
4219+define AuConf
4220+ifdef ${1}
4221+AuConfStr += ${1}=${${1}}
4222+endif
4223+endef
4224+
b752ccd1 4225+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4226+ SBILIST \
7f207e10 4227+ HNOTIFY HFSNOTIFY \
4a4d8108 4228+ EXPORT INO_T_64 \
076b876e 4229+ FHSM \
4a4d8108 4230+ RDU \
4a4d8108
AM
4231+ SHWH \
4232+ BR_RAMFS \
4233+ BR_FUSE POLL \
4234+ BR_HFSPLUS \
4235+ BDEV_LOOP \
b752ccd1
AM
4236+ DEBUG MAGIC_SYSRQ
4237+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4238+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4239+
4240+AuConfName = ${obj}/conf.str
4241+${AuConfName}.tmp: FORCE
4242+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4243+${AuConfName}: ${AuConfName}.tmp
4244+ @diff -q $< $@ > /dev/null 2>&1 || { \
4245+ echo ' GEN ' $@; \
4246+ cp -p $< $@; \
4247+ }
4248+FORCE:
4249+clean-files += ${AuConfName} ${AuConfName}.tmp
4250+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4251+
4252+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4253diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4254--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
4255+++ linux/fs/aufs/cpup.c 2014-08-14 10:15:45.118609182 +0200
4256@@ -0,0 +1,1301 @@
1facf9fc 4257+/*
523b37e3 4258+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 4259+ *
4260+ * This program, aufs is free software; you can redistribute it and/or modify
4261+ * it under the terms of the GNU General Public License as published by
4262+ * the Free Software Foundation; either version 2 of the License, or
4263+ * (at your option) any later version.
dece6358
AM
4264+ *
4265+ * This program is distributed in the hope that it will be useful,
4266+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4267+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4268+ * GNU General Public License for more details.
4269+ *
4270+ * You should have received a copy of the GNU General Public License
523b37e3 4271+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4272+ */
4273+
4274+/*
4275+ * copy-up functions, see wbr_policy.c for copy-down
4276+ */
4277+
4278+#include <linux/fs_stack.h>
dece6358 4279+#include <linux/mm.h>
1facf9fc 4280+#include "aufs.h"
4281+
86dc4139 4282+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4283+{
4284+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4285+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4286+
86dc4139
AM
4287+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4288+
4289+ dst->i_flags |= iflags & ~mask;
1facf9fc 4290+ if (au_test_fs_notime(dst->i_sb))
4291+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4292+}
4293+
4294+void au_cpup_attr_timesizes(struct inode *inode)
4295+{
4296+ struct inode *h_inode;
4297+
4298+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4299+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 4300+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 4301+}
4302+
4303+void au_cpup_attr_nlink(struct inode *inode, int force)
4304+{
4305+ struct inode *h_inode;
4306+ struct super_block *sb;
4307+ aufs_bindex_t bindex, bend;
4308+
4309+ sb = inode->i_sb;
4310+ bindex = au_ibstart(inode);
4311+ h_inode = au_h_iptr(inode, bindex);
4312+ if (!force
4313+ && !S_ISDIR(h_inode->i_mode)
4314+ && au_opt_test(au_mntflags(sb), PLINK)
4315+ && au_plink_test(inode))
4316+ return;
4317+
7eafdf33
AM
4318+ /*
4319+ * 0 can happen in revalidating.
38d290e6
JR
4320+ * h_inode->i_mutex may not be held here, but it is harmless since once
4321+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
4322+ * case.
4323+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
4324+ * the incorrect link count.
7eafdf33 4325+ */
92d182d2 4326+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 4327+
4328+ /*
4329+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
4330+ * it may includes whplink directory.
4331+ */
4332+ if (S_ISDIR(h_inode->i_mode)) {
4333+ bend = au_ibend(inode);
4334+ for (bindex++; bindex <= bend; bindex++) {
4335+ h_inode = au_h_iptr(inode, bindex);
4336+ if (h_inode)
4337+ au_add_nlink(inode, h_inode);
4338+ }
4339+ }
4340+}
4341+
4342+void au_cpup_attr_changeable(struct inode *inode)
4343+{
4344+ struct inode *h_inode;
4345+
4346+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4347+ inode->i_mode = h_inode->i_mode;
4348+ inode->i_uid = h_inode->i_uid;
4349+ inode->i_gid = h_inode->i_gid;
4350+ au_cpup_attr_timesizes(inode);
86dc4139 4351+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 4352+}
4353+
4354+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
4355+{
4356+ struct au_iinfo *iinfo = au_ii(inode);
4357+
1308ab2a 4358+ IiMustWriteLock(inode);
4359+
1facf9fc 4360+ iinfo->ii_higen = h_inode->i_generation;
4361+ iinfo->ii_hsb1 = h_inode->i_sb;
4362+}
4363+
4364+void au_cpup_attr_all(struct inode *inode, int force)
4365+{
4366+ struct inode *h_inode;
4367+
4368+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4369+ au_cpup_attr_changeable(inode);
4370+ if (inode->i_nlink > 0)
4371+ au_cpup_attr_nlink(inode, force);
4372+ inode->i_rdev = h_inode->i_rdev;
4373+ inode->i_blkbits = h_inode->i_blkbits;
4374+ au_cpup_igen(inode, h_inode);
4375+}
4376+
4377+/* ---------------------------------------------------------------------- */
4378+
4379+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
4380+
4381+/* keep the timestamps of the parent dir when cpup */
4382+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4383+ struct path *h_path)
4384+{
4385+ struct inode *h_inode;
4386+
4387+ dt->dt_dentry = dentry;
4388+ dt->dt_h_path = *h_path;
4389+ h_inode = h_path->dentry->d_inode;
4390+ dt->dt_atime = h_inode->i_atime;
4391+ dt->dt_mtime = h_inode->i_mtime;
4392+ /* smp_mb(); */
4393+}
4394+
4395+void au_dtime_revert(struct au_dtime *dt)
4396+{
4397+ struct iattr attr;
4398+ int err;
4399+
4400+ attr.ia_atime = dt->dt_atime;
4401+ attr.ia_mtime = dt->dt_mtime;
4402+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
4403+ | ATTR_ATIME | ATTR_ATIME_SET;
4404+
523b37e3
AM
4405+ /* no delegation since this is a directory */
4406+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 4407+ if (unlikely(err))
0c3ec466 4408+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 4409+}
4410+
4411+/* ---------------------------------------------------------------------- */
4412+
86dc4139
AM
4413+/* internal use only */
4414+struct au_cpup_reg_attr {
4415+ int valid;
4416+ struct kstat st;
4417+ unsigned int iflags; /* inode->i_flags */
4418+};
4419+
1facf9fc 4420+static noinline_for_stack
86dc4139
AM
4421+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
4422+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4423+{
4424+ int err, sbits;
4425+ struct iattr ia;
4426+ struct path h_path;
1308ab2a 4427+ struct inode *h_isrc, *h_idst;
86dc4139 4428+ struct kstat *h_st;
1facf9fc 4429+
4430+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 4431+ h_idst = h_path.dentry->d_inode;
1facf9fc 4432+ h_path.mnt = au_sbr_mnt(dst->d_sb, bindex);
4433+ h_isrc = h_src->d_inode;
1308ab2a 4434+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 4435+ | ATTR_ATIME | ATTR_MTIME
4436+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
4437+ if (h_src_attr && h_src_attr->valid) {
4438+ h_st = &h_src_attr->st;
4439+ ia.ia_uid = h_st->uid;
4440+ ia.ia_gid = h_st->gid;
4441+ ia.ia_atime = h_st->atime;
4442+ ia.ia_mtime = h_st->mtime;
4443+ if (h_idst->i_mode != h_st->mode
4444+ && !S_ISLNK(h_idst->i_mode)) {
4445+ ia.ia_valid |= ATTR_MODE;
4446+ ia.ia_mode = h_st->mode;
4447+ }
4448+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
4449+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
4450+ } else {
4451+ ia.ia_uid = h_isrc->i_uid;
4452+ ia.ia_gid = h_isrc->i_gid;
4453+ ia.ia_atime = h_isrc->i_atime;
4454+ ia.ia_mtime = h_isrc->i_mtime;
4455+ if (h_idst->i_mode != h_isrc->i_mode
4456+ && !S_ISLNK(h_idst->i_mode)) {
4457+ ia.ia_valid |= ATTR_MODE;
4458+ ia.ia_mode = h_isrc->i_mode;
4459+ }
4460+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
4461+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 4462+ }
523b37e3
AM
4463+ /* no delegation since it is just created */
4464+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4465+
4466+ /* is this nfs only? */
4467+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
4468+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
4469+ ia.ia_mode = h_isrc->i_mode;
523b37e3 4470+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4471+ }
4472+
4473+ return err;
4474+}
4475+
4476+/* ---------------------------------------------------------------------- */
4477+
4478+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
4479+ char *buf, unsigned long blksize)
4480+{
4481+ int err;
4482+ size_t sz, rbytes, wbytes;
4483+ unsigned char all_zero;
4484+ char *p, *zp;
4485+ struct mutex *h_mtx;
4486+ /* reduce stack usage */
4487+ struct iattr *ia;
4488+
4489+ zp = page_address(ZERO_PAGE(0));
4490+ if (unlikely(!zp))
4491+ return -ENOMEM; /* possible? */
4492+
4493+ err = 0;
4494+ all_zero = 0;
4495+ while (len) {
4496+ AuDbg("len %lld\n", len);
4497+ sz = blksize;
4498+ if (len < blksize)
4499+ sz = len;
4500+
4501+ rbytes = 0;
4502+ /* todo: signal_pending? */
4503+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
4504+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
4505+ err = rbytes;
4506+ }
4507+ if (unlikely(err < 0))
4508+ break;
4509+
4510+ all_zero = 0;
4511+ if (len >= rbytes && rbytes == blksize)
4512+ all_zero = !memcmp(buf, zp, rbytes);
4513+ if (!all_zero) {
4514+ wbytes = rbytes;
4515+ p = buf;
4516+ while (wbytes) {
4517+ size_t b;
4518+
4519+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
4520+ err = b;
4521+ /* todo: signal_pending? */
4522+ if (unlikely(err == -EAGAIN || err == -EINTR))
4523+ continue;
4524+ if (unlikely(err < 0))
4525+ break;
4526+ wbytes -= b;
4527+ p += b;
4528+ }
392086de
AM
4529+ if (unlikely(err < 0))
4530+ break;
1facf9fc 4531+ } else {
4532+ loff_t res;
4533+
4534+ AuLabel(hole);
4535+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
4536+ err = res;
4537+ if (unlikely(res < 0))
4538+ break;
4539+ }
4540+ len -= rbytes;
4541+ err = 0;
4542+ }
4543+
4544+ /* the last block may be a hole */
4545+ if (!err && all_zero) {
4546+ AuLabel(last hole);
4547+
4548+ err = 1;
4549+ if (au_test_nfs(dst->f_dentry->d_sb)) {
4550+ /* nfs requires this step to make last hole */
4551+ /* is this only nfs? */
4552+ do {
4553+ /* todo: signal_pending? */
4554+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
4555+ } while (err == -EAGAIN || err == -EINTR);
4556+ if (err == 1)
4557+ dst->f_pos--;
4558+ }
4559+
4560+ if (err == 1) {
4561+ ia = (void *)buf;
4562+ ia->ia_size = dst->f_pos;
4563+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
4564+ ia->ia_file = dst;
c06a8ce3 4565+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 4566+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
523b37e3
AM
4567+ /* no delegation since it is just created */
4568+ err = vfsub_notify_change(&dst->f_path, ia,
4569+ /*delegated*/NULL);
1facf9fc 4570+ mutex_unlock(h_mtx);
4571+ }
4572+ }
4573+
4574+ return err;
4575+}
4576+
4577+int au_copy_file(struct file *dst, struct file *src, loff_t len)
4578+{
4579+ int err;
4580+ unsigned long blksize;
4581+ unsigned char do_kfree;
4582+ char *buf;
4583+
4584+ err = -ENOMEM;
4585+ blksize = dst->f_dentry->d_sb->s_blocksize;
4586+ if (!blksize || PAGE_SIZE < blksize)
4587+ blksize = PAGE_SIZE;
4588+ AuDbg("blksize %lu\n", blksize);
4589+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
4590+ if (do_kfree)
4591+ buf = kmalloc(blksize, GFP_NOFS);
4592+ else
4593+ buf = (void *)__get_free_page(GFP_NOFS);
4594+ if (unlikely(!buf))
4595+ goto out;
4596+
4597+ if (len > (1 << 22))
4598+ AuDbg("copying a large file %lld\n", (long long)len);
4599+
4600+ src->f_pos = 0;
4601+ dst->f_pos = 0;
4602+ err = au_do_copy_file(dst, src, len, buf, blksize);
4603+ if (do_kfree)
4604+ kfree(buf);
4605+ else
4606+ free_page((unsigned long)buf);
4607+
4f0767ce 4608+out:
1facf9fc 4609+ return err;
4610+}
4611+
4612+/*
4613+ * to support a sparse file which is opened with O_APPEND,
4614+ * we need to close the file.
4615+ */
c2b27bf2 4616+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 4617+{
4618+ int err, i;
4619+ enum { SRC, DST };
4620+ struct {
4621+ aufs_bindex_t bindex;
4622+ unsigned int flags;
4623+ struct dentry *dentry;
392086de 4624+ int force_wr;
1facf9fc 4625+ struct file *file;
523b37e3 4626+ void *label;
1facf9fc 4627+ } *f, file[] = {
4628+ {
c2b27bf2 4629+ .bindex = cpg->bsrc,
1facf9fc 4630+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 4631+ .label = &&out
1facf9fc 4632+ },
4633+ {
c2b27bf2 4634+ .bindex = cpg->bdst,
1facf9fc 4635+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 4636+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 4637+ .label = &&out_src
1facf9fc 4638+ }
4639+ };
4640+ struct super_block *sb;
4641+
4642+ /* bsrc branch can be ro/rw. */
c2b27bf2 4643+ sb = cpg->dentry->d_sb;
1facf9fc 4644+ f = file;
4645+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
4646+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
4647+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 4648+ /*file*/NULL, f->force_wr);
1facf9fc 4649+ err = PTR_ERR(f->file);
4650+ if (IS_ERR(f->file))
4651+ goto *f->label;
1facf9fc 4652+ }
4653+
4654+ /* try stopping to update while we copyup */
4655+ IMustLock(file[SRC].dentry->d_inode);
c2b27bf2 4656+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 4657+
1facf9fc 4658+ fput(file[DST].file);
4659+ au_sbr_put(sb, file[DST].bindex);
523b37e3 4660+
4f0767ce 4661+out_src:
1facf9fc 4662+ fput(file[SRC].file);
4663+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 4664+out:
1facf9fc 4665+ return err;
4666+}
4667+
c2b27bf2 4668+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 4669+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4670+{
4671+ int err, rerr;
4672+ loff_t l;
86dc4139 4673+ struct path h_path;
38d290e6 4674+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 4675+
4676+ err = 0;
c2b27bf2 4677+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
86dc4139 4678+ l = i_size_read(h_src_inode);
c2b27bf2
AM
4679+ if (cpg->len == -1 || l < cpg->len)
4680+ cpg->len = l;
4681+ if (cpg->len) {
86dc4139
AM
4682+ /* try stopping to update while we are referencing */
4683+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2 4684+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 4685+
c2b27bf2
AM
4686+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
4687+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139
AM
4688+ h_src_attr->iflags = h_src_inode->i_flags;
4689+ err = vfs_getattr(&h_path, &h_src_attr->st);
4690+ if (unlikely(err)) {
4691+ mutex_unlock(&h_src_inode->i_mutex);
4692+ goto out;
4693+ }
4694+ h_src_attr->valid = 1;
c2b27bf2 4695+ err = au_cp_regular(cpg);
86dc4139 4696+ mutex_unlock(&h_src_inode->i_mutex);
c2b27bf2 4697+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
4698+ if (!err && rerr)
4699+ err = rerr;
1facf9fc 4700+ }
38d290e6
JR
4701+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
4702+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
4703+ h_dst_inode = h_path.dentry->d_inode;
4704+ spin_lock(&h_dst_inode->i_lock);
4705+ h_dst_inode->i_state |= I_LINKABLE;
4706+ spin_unlock(&h_dst_inode->i_lock);
4707+ }
1facf9fc 4708+
4f0767ce 4709+out:
1facf9fc 4710+ return err;
4711+}
4712+
4713+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
4714+ struct inode *h_dir)
4715+{
4716+ int err, symlen;
4717+ mm_segment_t old_fs;
b752ccd1
AM
4718+ union {
4719+ char *k;
4720+ char __user *u;
4721+ } sym;
1facf9fc 4722+
4723+ err = -ENOSYS;
4724+ if (unlikely(!h_src->d_inode->i_op->readlink))
4725+ goto out;
4726+
4727+ err = -ENOMEM;
537831f9 4728+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 4729+ if (unlikely(!sym.k))
1facf9fc 4730+ goto out;
4731+
9dbd164d 4732+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 4733+ old_fs = get_fs();
4734+ set_fs(KERNEL_DS);
b752ccd1 4735+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 4736+ err = symlen;
4737+ set_fs(old_fs);
4738+
4739+ if (symlen > 0) {
b752ccd1
AM
4740+ sym.k[symlen] = 0;
4741+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 4742+ }
537831f9 4743+ free_page((unsigned long)sym.k);
1facf9fc 4744+
4f0767ce 4745+out:
1facf9fc 4746+ return err;
4747+}
4748+
1facf9fc 4749+static noinline_for_stack
c2b27bf2 4750+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 4751+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4752+{
4753+ int err;
4754+ umode_t mode;
4755+ unsigned int mnt_flags;
076b876e 4756+ unsigned char isdir, isreg, force;
c2b27bf2 4757+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4758+ struct au_dtime dt;
4759+ struct path h_path;
4760+ struct dentry *h_src, *h_dst, *h_parent;
4761+ struct inode *h_inode, *h_dir;
4762+ struct super_block *sb;
4763+
4764+ /* bsrc branch can be ro/rw. */
c2b27bf2 4765+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
1facf9fc 4766+ h_inode = h_src->d_inode;
c2b27bf2 4767+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
1facf9fc 4768+
4769+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
4770+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
4771+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
4772+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
4773+ AUFS_WH_PFX_LEN));
1facf9fc 4774+ h_parent = h_dst->d_parent; /* dir inode is locked */
4775+ h_dir = h_parent->d_inode;
4776+ IMustLock(h_dir);
4777+ AuDebugOn(h_parent != h_dst->d_parent);
4778+
c2b27bf2
AM
4779+ sb = cpg->dentry->d_sb;
4780+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 4781+ if (do_dt) {
4782+ h_path.dentry = h_parent;
4783+ au_dtime_store(&dt, dst_parent, &h_path);
4784+ }
4785+ h_path.dentry = h_dst;
4786+
076b876e 4787+ isreg = 0;
1facf9fc 4788+ isdir = 0;
4789+ mode = h_inode->i_mode;
4790+ switch (mode & S_IFMT) {
4791+ case S_IFREG:
076b876e 4792+ isreg = 1;
b4510431
AM
4793+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
4794+ /*want_excl*/true);
1facf9fc 4795+ if (!err)
c2b27bf2 4796+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 4797+ break;
4798+ case S_IFDIR:
4799+ isdir = 1;
4800+ err = vfsub_mkdir(h_dir, &h_path, mode);
4801+ if (!err) {
4802+ /*
4803+ * strange behaviour from the users view,
4804+ * particularry setattr case
4805+ */
c2b27bf2 4806+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
1facf9fc 4807+ au_cpup_attr_nlink(dst_parent->d_inode,
4808+ /*force*/1);
c2b27bf2 4809+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
1facf9fc 4810+ }
4811+ break;
4812+ case S_IFLNK:
4813+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
4814+ break;
4815+ case S_IFCHR:
4816+ case S_IFBLK:
4817+ AuDebugOn(!capable(CAP_MKNOD));
4818+ /*FALLTHROUGH*/
4819+ case S_IFIFO:
4820+ case S_IFSOCK:
4821+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
4822+ break;
4823+ default:
4824+ AuIOErr("Unknown inode type 0%o\n", mode);
4825+ err = -EIO;
4826+ }
4827+
4828+ mnt_flags = au_mntflags(sb);
4829+ if (!au_opt_test(mnt_flags, UDBA_NONE)
4830+ && !isdir
4831+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
4832+ && (h_inode->i_nlink == 1
4833+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 4834+ /* todo: unnecessary? */
c2b27bf2
AM
4835+ /* && cpg->dentry->d_inode->i_nlink == 1 */
4836+ && cpg->bdst < cpg->bsrc
4837+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
4838+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 4839+ /* ignore this error */
4840+
076b876e
AM
4841+ if (!err) {
4842+ force = 0;
4843+ if (isreg) {
4844+ force = !!cpg->len;
4845+ if (cpg->len == -1)
4846+ force = !!i_size_read(h_inode);
4847+ }
4848+ au_fhsm_wrote(sb, cpg->bdst, force);
4849+ }
4850+
1facf9fc 4851+ if (do_dt)
4852+ au_dtime_revert(&dt);
4853+ return err;
4854+}
4855+
392086de 4856+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
4857+{
4858+ int err;
392086de 4859+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 4860+ struct inode *h_dir;
392086de 4861+ aufs_bindex_t bdst;
86dc4139 4862+
392086de
AM
4863+ dentry = cpg->dentry;
4864+ bdst = cpg->bdst;
4865+ h_dentry = au_h_dptr(dentry, bdst);
4866+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
4867+ dget(h_dentry);
4868+ au_set_h_dptr(dentry, bdst, NULL);
4869+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
4870+ if (!err)
4871+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 4872+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
4873+ } else {
4874+ err = 0;
4875+ parent = dget_parent(dentry);
4876+ h_parent = au_h_dptr(parent, bdst);
4877+ dput(parent);
4878+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
4879+ if (IS_ERR(h_path->dentry))
4880+ err = PTR_ERR(h_path->dentry);
86dc4139 4881+ }
392086de
AM
4882+ if (unlikely(err))
4883+ goto out;
86dc4139 4884+
86dc4139
AM
4885+ h_parent = h_dentry->d_parent; /* dir inode is locked */
4886+ h_dir = h_parent->d_inode;
4887+ IMustLock(h_dir);
523b37e3
AM
4888+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
4889+ /* no delegation since it is just created */
4890+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL);
86dc4139
AM
4891+ dput(h_path->dentry);
4892+
4893+out:
4894+ return err;
4895+}
4896+
1facf9fc 4897+/*
4898+ * copyup the @dentry from @bsrc to @bdst.
4899+ * the caller must set the both of lower dentries.
4900+ * @len is for truncating when it is -1 copyup the entire file.
4901+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 4902+ * basic->bsrc can be larger than basic->bdst.
1facf9fc 4903+ */
c2b27bf2 4904+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 4905+{
4906+ int err, rerr;
4907+ aufs_bindex_t old_ibstart;
4908+ unsigned char isdir, plink;
1facf9fc 4909+ struct dentry *h_src, *h_dst, *h_parent;
523b37e3 4910+ struct inode *dst_inode, *h_dir, *inode, *delegated;
1facf9fc 4911+ struct super_block *sb;
86dc4139 4912+ struct au_branch *br;
c2b27bf2
AM
4913+ /* to reuduce stack size */
4914+ struct {
4915+ struct au_dtime dt;
4916+ struct path h_path;
4917+ struct au_cpup_reg_attr h_src_attr;
4918+ } *a;
1facf9fc 4919+
c2b27bf2
AM
4920+ err = -ENOMEM;
4921+ a = kmalloc(sizeof(*a), GFP_NOFS);
4922+ if (unlikely(!a))
4923+ goto out;
4924+ a->h_src_attr.valid = 0;
1facf9fc 4925+
c2b27bf2
AM
4926+ sb = cpg->dentry->d_sb;
4927+ br = au_sbr(sb, cpg->bdst);
4928+ a->h_path.mnt = au_br_mnt(br);
4929+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 4930+ h_parent = h_dst->d_parent; /* dir inode is locked */
4931+ h_dir = h_parent->d_inode;
4932+ IMustLock(h_dir);
4933+
c2b27bf2
AM
4934+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
4935+ inode = cpg->dentry->d_inode;
1facf9fc 4936+
4937+ if (!dst_parent)
c2b27bf2 4938+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 4939+ else
4940+ dget(dst_parent);
4941+
4942+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 4943+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 4944+ if (dst_inode) {
4945+ if (unlikely(!plink)) {
4946+ err = -EIO;
027c5e7a
AM
4947+ AuIOErr("hi%lu(i%lu) exists on b%d "
4948+ "but plink is disabled\n",
c2b27bf2
AM
4949+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
4950+ goto out_parent;
1facf9fc 4951+ }
4952+
4953+ if (dst_inode->i_nlink) {
c2b27bf2 4954+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4955+
c2b27bf2 4956+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 4957+ err = PTR_ERR(h_src);
4958+ if (IS_ERR(h_src))
c2b27bf2 4959+ goto out_parent;
1facf9fc 4960+ if (unlikely(!h_src->d_inode)) {
4961+ err = -EIO;
4962+ AuIOErr("i%lu exists on a upper branch "
027c5e7a
AM
4963+ "but not pseudo-linked\n",
4964+ inode->i_ino);
1facf9fc 4965+ dput(h_src);
c2b27bf2 4966+ goto out_parent;
1facf9fc 4967+ }
4968+
4969+ if (do_dt) {
c2b27bf2
AM
4970+ a->h_path.dentry = h_parent;
4971+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 4972+ }
86dc4139 4973+
c2b27bf2 4974+ a->h_path.dentry = h_dst;
523b37e3
AM
4975+ delegated = NULL;
4976+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 4977+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 4978+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 4979+ if (do_dt)
c2b27bf2 4980+ au_dtime_revert(&a->dt);
523b37e3
AM
4981+ if (unlikely(err == -EWOULDBLOCK)) {
4982+ pr_warn("cannot retry for NFSv4 delegation"
4983+ " for an internal link\n");
4984+ iput(delegated);
4985+ }
1facf9fc 4986+ dput(h_src);
c2b27bf2 4987+ goto out_parent;
1facf9fc 4988+ } else
4989+ /* todo: cpup_wh_file? */
4990+ /* udba work */
4a4d8108 4991+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 4992+ }
4993+
86dc4139 4994+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 4995+ old_ibstart = au_ibstart(inode);
c2b27bf2 4996+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 4997+ if (unlikely(err))
86dc4139 4998+ goto out_rev;
1facf9fc 4999+ dst_inode = h_dst->d_inode;
5000+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139 5001+ /* todo: necessary? */
c2b27bf2 5002+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5003+
c2b27bf2 5004+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5005+ if (unlikely(err)) {
5006+ /* todo: necessary? */
c2b27bf2 5007+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
86dc4139
AM
5008+ mutex_unlock(&dst_inode->i_mutex);
5009+ goto out_rev;
5010+ }
5011+
c2b27bf2 5012+ if (cpg->bdst < old_ibstart) {
86dc4139 5013+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5014+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5015+ if (unlikely(err)) {
c2b27bf2
AM
5016+ /* ignore an error */
5017+ /* au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5018+ mutex_unlock(&dst_inode->i_mutex);
5019+ goto out_rev;
4a4d8108 5020+ }
4a4d8108 5021+ }
c2b27bf2
AM
5022+ au_set_ibstart(inode, cpg->bdst);
5023+ } else
5024+ au_set_ibend(inode, cpg->bdst);
5025+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5026+ au_hi_flags(inode, isdir));
5027+
5028+ /* todo: necessary? */
c2b27bf2 5029+ /* err = au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5030+ mutex_unlock(&dst_inode->i_mutex);
5031+ if (unlikely(err))
5032+ goto out_rev;
5033+
5034+ if (!isdir
38d290e6
JR
5035+ && (h_src->d_inode->i_nlink > 1
5036+ || h_src->d_inode->i_state & I_LINKABLE)
86dc4139 5037+ && plink)
c2b27bf2 5038+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5039+
c2b27bf2
AM
5040+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5041+ a->h_path.dentry = h_dst;
392086de 5042+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5043+ }
5044+ if (!err)
c2b27bf2 5045+ goto out_parent; /* success */
1facf9fc 5046+
5047+ /* revert */
4a4d8108 5048+out_rev:
c2b27bf2
AM
5049+ a->h_path.dentry = h_parent;
5050+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5051+ a->h_path.dentry = h_dst;
86dc4139
AM
5052+ rerr = 0;
5053+ if (h_dst->d_inode) {
523b37e3
AM
5054+ if (!isdir) {
5055+ /* no delegation since it is just created */
5056+ rerr = vfsub_unlink(h_dir, &a->h_path,
5057+ /*delegated*/NULL, /*force*/0);
5058+ } else
c2b27bf2 5059+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5060+ }
c2b27bf2 5061+ au_dtime_revert(&a->dt);
1facf9fc 5062+ if (rerr) {
5063+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5064+ err = -EIO;
5065+ }
c2b27bf2 5066+out_parent:
1facf9fc 5067+ dput(dst_parent);
c2b27bf2
AM
5068+ kfree(a);
5069+out:
1facf9fc 5070+ return err;
5071+}
5072+
c2b27bf2 5073+#if 0 /* unused */
1facf9fc 5074+struct au_cpup_single_args {
5075+ int *errp;
c2b27bf2 5076+ struct au_cp_generic *cpg;
1facf9fc 5077+ struct dentry *dst_parent;
5078+};
5079+
5080+static void au_call_cpup_single(void *args)
5081+{
5082+ struct au_cpup_single_args *a = args;
86dc4139 5083+
c2b27bf2
AM
5084+ au_pin_hdir_acquire_nest(a->cpg->pin);
5085+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5086+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5087+}
c2b27bf2 5088+#endif
1facf9fc 5089+
53392da6
AM
5090+/*
5091+ * prevent SIGXFSZ in copy-up.
5092+ * testing CAP_MKNOD is for generic fs,
5093+ * but CAP_FSETID is for xfs only, currently.
5094+ */
86dc4139 5095+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5096+{
5097+ int do_sio;
86dc4139
AM
5098+ struct super_block *sb;
5099+ struct inode *h_dir;
53392da6
AM
5100+
5101+ do_sio = 0;
86dc4139 5102+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5103+ if (!au_wkq_test()
5104+ && (!au_sbi(sb)->si_plink_maint_pid
5105+ || au_plink_maint(sb, AuLock_NOPLM))) {
5106+ switch (mode & S_IFMT) {
5107+ case S_IFREG:
5108+ /* no condition about RLIMIT_FSIZE and the file size */
5109+ do_sio = 1;
5110+ break;
5111+ case S_IFCHR:
5112+ case S_IFBLK:
5113+ do_sio = !capable(CAP_MKNOD);
5114+ break;
5115+ }
5116+ if (!do_sio)
5117+ do_sio = ((mode & (S_ISUID | S_ISGID))
5118+ && !capable(CAP_FSETID));
86dc4139
AM
5119+ /* this workaround may be removed in the future */
5120+ if (!do_sio) {
5121+ h_dir = au_pinned_h_dir(pin);
5122+ do_sio = h_dir->i_mode & S_ISVTX;
5123+ }
53392da6
AM
5124+ }
5125+
5126+ return do_sio;
5127+}
5128+
c2b27bf2
AM
5129+#if 0 /* unused */
5130+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5131+{
5132+ int err, wkq_err;
1facf9fc 5133+ struct dentry *h_dentry;
5134+
c2b27bf2 5135+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
86dc4139 5136+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
c2b27bf2 5137+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 5138+ else {
5139+ struct au_cpup_single_args args = {
5140+ .errp = &err,
c2b27bf2
AM
5141+ .cpg = cpg,
5142+ .dst_parent = dst_parent
1facf9fc 5143+ };
5144+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5145+ if (unlikely(wkq_err))
5146+ err = wkq_err;
5147+ }
5148+
5149+ return err;
5150+}
c2b27bf2 5151+#endif
1facf9fc 5152+
5153+/*
5154+ * copyup the @dentry from the first active lower branch to @bdst,
5155+ * using au_cpup_single().
5156+ */
c2b27bf2 5157+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5158+{
5159+ int err;
c2b27bf2
AM
5160+ unsigned int flags_orig;
5161+ struct dentry *dentry;
5162+
5163+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 5164+
c2b27bf2 5165+ dentry = cpg->dentry;
86dc4139 5166+ DiMustWriteLock(dentry);
1facf9fc 5167+
c2b27bf2 5168+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 5169+ if (!err) {
c2b27bf2
AM
5170+ flags_orig = cpg->flags;
5171+ au_fset_cpup(cpg->flags, RENAME);
5172+ err = au_cpup_single(cpg, NULL);
5173+ cpg->flags = flags_orig;
1facf9fc 5174+ if (!err)
5175+ return 0; /* success */
5176+
5177+ /* revert */
c2b27bf2
AM
5178+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5179+ au_set_dbstart(dentry, cpg->bsrc);
1facf9fc 5180+ }
5181+
5182+ return err;
5183+}
5184+
5185+struct au_cpup_simple_args {
5186+ int *errp;
c2b27bf2 5187+ struct au_cp_generic *cpg;
1facf9fc 5188+};
5189+
5190+static void au_call_cpup_simple(void *args)
5191+{
5192+ struct au_cpup_simple_args *a = args;
86dc4139 5193+
c2b27bf2
AM
5194+ au_pin_hdir_acquire_nest(a->cpg->pin);
5195+ *a->errp = au_cpup_simple(a->cpg);
5196+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5197+}
5198+
c2b27bf2 5199+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5200+{
5201+ int err, wkq_err;
c2b27bf2
AM
5202+ struct dentry *dentry, *parent;
5203+ struct file *h_file;
1facf9fc 5204+ struct inode *h_dir;
5205+
c2b27bf2
AM
5206+ dentry = cpg->dentry;
5207+ h_file = NULL;
5208+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
5209+ AuDebugOn(cpg->bsrc < 0);
392086de 5210+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
5211+ err = PTR_ERR(h_file);
5212+ if (IS_ERR(h_file))
5213+ goto out;
5214+ }
5215+
1facf9fc 5216+ parent = dget_parent(dentry);
c2b27bf2 5217+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
53392da6 5218+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
5219+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
5220+ err = au_cpup_simple(cpg);
1facf9fc 5221+ else {
5222+ struct au_cpup_simple_args args = {
5223+ .errp = &err,
c2b27bf2 5224+ .cpg = cpg
1facf9fc 5225+ };
5226+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
5227+ if (unlikely(wkq_err))
5228+ err = wkq_err;
5229+ }
5230+
5231+ dput(parent);
c2b27bf2
AM
5232+ if (h_file)
5233+ au_h_open_post(dentry, cpg->bsrc, h_file);
5234+
5235+out:
1facf9fc 5236+ return err;
5237+}
5238+
c2b27bf2 5239+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 5240+{
c2b27bf2
AM
5241+ aufs_bindex_t bsrc, bend;
5242+ struct dentry *dentry, *h_dentry;
367653fa 5243+
c2b27bf2
AM
5244+ if (cpg->bsrc < 0) {
5245+ dentry = cpg->dentry;
5246+ bend = au_dbend(dentry);
5247+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
5248+ h_dentry = au_h_dptr(dentry, bsrc);
5249+ if (h_dentry) {
5250+ AuDebugOn(!h_dentry->d_inode);
5251+ break;
5252+ }
5253+ }
5254+ AuDebugOn(bsrc > bend);
5255+ cpg->bsrc = bsrc;
367653fa 5256+ }
c2b27bf2
AM
5257+ AuDebugOn(cpg->bsrc <= cpg->bdst);
5258+ return au_do_sio_cpup_simple(cpg);
5259+}
367653fa 5260+
c2b27bf2
AM
5261+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
5262+{
5263+ AuDebugOn(cpg->bdst <= cpg->bsrc);
5264+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
5265+}
5266+
1facf9fc 5267+/* ---------------------------------------------------------------------- */
5268+
5269+/*
5270+ * copyup the deleted file for writing.
5271+ */
c2b27bf2
AM
5272+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
5273+ struct file *file)
1facf9fc 5274+{
5275+ int err;
c2b27bf2
AM
5276+ unsigned int flags_orig;
5277+ aufs_bindex_t bsrc_orig;
1facf9fc 5278+ struct dentry *h_d_dst, *h_d_start;
c2b27bf2 5279+ struct au_dinfo *dinfo;
4a4d8108 5280+ struct au_hdentry *hdp;
1facf9fc 5281+
c2b27bf2 5282+ dinfo = au_di(cpg->dentry);
1308ab2a 5283+ AuRwMustWriteLock(&dinfo->di_rwsem);
5284+
c2b27bf2
AM
5285+ bsrc_orig = cpg->bsrc;
5286+ cpg->bsrc = dinfo->di_bstart;
4a4d8108 5287+ hdp = dinfo->di_hdentry;
c2b27bf2
AM
5288+ h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
5289+ dinfo->di_bstart = cpg->bdst;
5290+ hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
86dc4139 5291+ h_d_start = NULL;
027c5e7a 5292+ if (file) {
c2b27bf2
AM
5293+ h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
5294+ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_dentry;
027c5e7a 5295+ }
c2b27bf2
AM
5296+ flags_orig = cpg->flags;
5297+ cpg->flags = !AuCpup_DTIME;
5298+ err = au_cpup_single(cpg, /*h_parent*/NULL);
5299+ cpg->flags = flags_orig;
027c5e7a
AM
5300+ if (file) {
5301+ if (!err)
5302+ err = au_reopen_nondir(file);
c2b27bf2 5303+ hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
1facf9fc 5304+ }
c2b27bf2
AM
5305+ hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
5306+ dinfo->di_bstart = cpg->bsrc;
5307+ cpg->bsrc = bsrc_orig;
1facf9fc 5308+
5309+ return err;
5310+}
5311+
c2b27bf2 5312+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5313+{
5314+ int err;
c2b27bf2 5315+ aufs_bindex_t bdst;
1facf9fc 5316+ struct au_dtime dt;
c2b27bf2 5317+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 5318+ struct au_branch *br;
5319+ struct path h_path;
5320+
c2b27bf2
AM
5321+ dentry = cpg->dentry;
5322+ bdst = cpg->bdst;
1facf9fc 5323+ br = au_sbr(dentry->d_sb, bdst);
5324+ parent = dget_parent(dentry);
5325+ h_parent = au_h_dptr(parent, bdst);
5326+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
5327+ err = PTR_ERR(wh_dentry);
5328+ if (IS_ERR(wh_dentry))
5329+ goto out;
5330+
5331+ h_path.dentry = h_parent;
86dc4139 5332+ h_path.mnt = au_br_mnt(br);
1facf9fc 5333+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 5334+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 5335+ if (unlikely(err))
5336+ goto out_wh;
5337+
5338+ dget(wh_dentry);
5339+ h_path.dentry = wh_dentry;
523b37e3
AM
5340+ if (!S_ISDIR(wh_dentry->d_inode->i_mode)) {
5341+ /* no delegation since it is just created */
5342+ err = vfsub_unlink(h_parent->d_inode, &h_path,
5343+ /*delegated*/NULL, /*force*/0);
5344+ } else
4a4d8108 5345+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
1facf9fc 5346+ if (unlikely(err)) {
523b37e3
AM
5347+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
5348+ wh_dentry, err);
1facf9fc 5349+ err = -EIO;
5350+ }
5351+ au_dtime_revert(&dt);
5352+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
5353+
4f0767ce 5354+out_wh:
1facf9fc 5355+ dput(wh_dentry);
4f0767ce 5356+out:
1facf9fc 5357+ dput(parent);
5358+ return err;
5359+}
5360+
5361+struct au_cpup_wh_args {
5362+ int *errp;
c2b27bf2 5363+ struct au_cp_generic *cpg;
1facf9fc 5364+ struct file *file;
5365+};
5366+
5367+static void au_call_cpup_wh(void *args)
5368+{
5369+ struct au_cpup_wh_args *a = args;
86dc4139 5370+
c2b27bf2
AM
5371+ au_pin_hdir_acquire_nest(a->cpg->pin);
5372+ *a->errp = au_cpup_wh(a->cpg, a->file);
5373+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5374+}
5375+
c2b27bf2 5376+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5377+{
5378+ int err, wkq_err;
c2b27bf2
AM
5379+ aufs_bindex_t bdst;
5380+ struct dentry *dentry, *parent, *h_orph, *h_parent, *h_dentry;
86dc4139 5381+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 5382+ struct au_wbr *wbr;
c2b27bf2 5383+ struct au_pin wh_pin, *pin_orig;
1facf9fc 5384+
c2b27bf2
AM
5385+ dentry = cpg->dentry;
5386+ bdst = cpg->bdst;
1facf9fc 5387+ parent = dget_parent(dentry);
5388+ dir = parent->d_inode;
5389+ h_orph = NULL;
5390+ h_parent = NULL;
5391+ h_dir = au_igrab(au_h_iptr(dir, bdst));
5392+ h_tmpdir = h_dir;
c2b27bf2 5393+ pin_orig = NULL;
1facf9fc 5394+ if (!h_dir->i_nlink) {
5395+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
5396+ h_orph = wbr->wbr_orph;
5397+
5398+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 5399+ au_set_h_dptr(parent, bdst, dget(h_orph));
5400+ h_tmpdir = h_orph->d_inode;
1facf9fc 5401+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
5402+
1facf9fc 5403+ if (file)
4a4d8108 5404+ h_dentry = au_hf_top(file)->f_dentry;
1facf9fc 5405+ else
5406+ h_dentry = au_h_dptr(dentry, au_dbstart(dentry));
dece6358 5407+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 5408+ /* todo: au_h_open_pre()? */
86dc4139 5409+
c2b27bf2 5410+ pin_orig = cpg->pin;
86dc4139 5411+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
5412+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
5413+ cpg->pin = &wh_pin;
1facf9fc 5414+ }
5415+
53392da6 5416+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
5417+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
5418+ err = au_cpup_wh(cpg, file);
1facf9fc 5419+ else {
5420+ struct au_cpup_wh_args args = {
5421+ .errp = &err,
c2b27bf2
AM
5422+ .cpg = cpg,
5423+ .file = file
1facf9fc 5424+ };
5425+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
5426+ if (unlikely(wkq_err))
5427+ err = wkq_err;
5428+ }
5429+
5430+ if (h_orph) {
5431+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 5432+ /* todo: au_h_open_post()? */
1facf9fc 5433+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 5434+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
5435+ AuDebugOn(!pin_orig);
5436+ cpg->pin = pin_orig;
1facf9fc 5437+ }
5438+ iput(h_dir);
5439+ dput(parent);
5440+
5441+ return err;
5442+}
5443+
5444+/* ---------------------------------------------------------------------- */
5445+
5446+/*
5447+ * generic routine for both of copy-up and copy-down.
5448+ */
5449+/* cf. revalidate function in file.c */
5450+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5451+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5452+ struct au_pin *pin,
1facf9fc 5453+ struct dentry *h_parent, void *arg),
5454+ void *arg)
5455+{
5456+ int err;
5457+ struct au_pin pin;
5458+ struct dentry *d, *parent, *h_parent, *real_parent;
5459+
5460+ err = 0;
5461+ parent = dget_parent(dentry);
5462+ if (IS_ROOT(parent))
5463+ goto out;
5464+
5465+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
5466+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
5467+
5468+ /* do not use au_dpage */
5469+ real_parent = parent;
5470+ while (1) {
5471+ dput(parent);
5472+ parent = dget_parent(dentry);
5473+ h_parent = au_h_dptr(parent, bdst);
5474+ if (h_parent)
5475+ goto out; /* success */
5476+
5477+ /* find top dir which is necessary to cpup */
5478+ do {
5479+ d = parent;
5480+ dput(parent);
5481+ parent = dget_parent(d);
5482+ di_read_lock_parent3(parent, !AuLock_IR);
5483+ h_parent = au_h_dptr(parent, bdst);
5484+ di_read_unlock(parent, !AuLock_IR);
5485+ } while (!h_parent);
5486+
5487+ if (d != real_parent)
5488+ di_write_lock_child3(d);
5489+
5490+ /* somebody else might create while we were sleeping */
5491+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
5492+ if (au_h_dptr(d, bdst))
5493+ au_update_dbstart(d);
5494+
5495+ au_pin_set_dentry(&pin, d);
5496+ err = au_do_pin(&pin);
5497+ if (!err) {
86dc4139 5498+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 5499+ au_unpin(&pin);
5500+ }
5501+ }
5502+
5503+ if (d != real_parent)
5504+ di_write_unlock(d);
5505+ if (unlikely(err))
5506+ break;
5507+ }
5508+
4f0767ce 5509+out:
1facf9fc 5510+ dput(parent);
5511+ return err;
5512+}
5513+
5514+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5515+ struct au_pin *pin,
1facf9fc 5516+ struct dentry *h_parent __maybe_unused ,
5517+ void *arg __maybe_unused)
5518+{
c2b27bf2
AM
5519+ struct au_cp_generic cpg = {
5520+ .dentry = dentry,
5521+ .bdst = bdst,
5522+ .bsrc = -1,
5523+ .len = 0,
5524+ .pin = pin,
5525+ .flags = AuCpup_DTIME
5526+ };
5527+ return au_sio_cpup_simple(&cpg);
1facf9fc 5528+}
5529+
5530+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5531+{
5532+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
5533+}
5534+
5535+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5536+{
5537+ int err;
5538+ struct dentry *parent;
5539+ struct inode *dir;
5540+
5541+ parent = dget_parent(dentry);
5542+ dir = parent->d_inode;
5543+ err = 0;
5544+ if (au_h_iptr(dir, bdst))
5545+ goto out;
5546+
5547+ di_read_unlock(parent, AuLock_IR);
5548+ di_write_lock_parent(parent);
5549+ /* someone else might change our inode while we were sleeping */
5550+ if (!au_h_iptr(dir, bdst))
5551+ err = au_cpup_dirs(dentry, bdst);
5552+ di_downgrade_lock(parent, AuLock_IR);
5553+
4f0767ce 5554+out:
1facf9fc 5555+ dput(parent);
5556+ return err;
5557+}
7f207e10
AM
5558diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
5559--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
076b876e 5560+++ linux/fs/aufs/cpup.h 2014-01-30 21:10:02.827480967 +0100
523b37e3 5561@@ -0,0 +1,94 @@
1facf9fc 5562+/*
523b37e3 5563+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5564+ *
5565+ * This program, aufs is free software; you can redistribute it and/or modify
5566+ * it under the terms of the GNU General Public License as published by
5567+ * the Free Software Foundation; either version 2 of the License, or
5568+ * (at your option) any later version.
dece6358
AM
5569+ *
5570+ * This program is distributed in the hope that it will be useful,
5571+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5572+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5573+ * GNU General Public License for more details.
5574+ *
5575+ * You should have received a copy of the GNU General Public License
523b37e3 5576+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5577+ */
5578+
5579+/*
5580+ * copy-up/down functions
5581+ */
5582+
5583+#ifndef __AUFS_CPUP_H__
5584+#define __AUFS_CPUP_H__
5585+
5586+#ifdef __KERNEL__
5587+
dece6358 5588+#include <linux/path.h>
1facf9fc 5589+
dece6358
AM
5590+struct inode;
5591+struct file;
86dc4139 5592+struct au_pin;
dece6358 5593+
86dc4139 5594+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 5595+void au_cpup_attr_timesizes(struct inode *inode);
5596+void au_cpup_attr_nlink(struct inode *inode, int force);
5597+void au_cpup_attr_changeable(struct inode *inode);
5598+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
5599+void au_cpup_attr_all(struct inode *inode, int force);
5600+
5601+/* ---------------------------------------------------------------------- */
5602+
c2b27bf2
AM
5603+struct au_cp_generic {
5604+ struct dentry *dentry;
5605+ aufs_bindex_t bdst, bsrc;
5606+ loff_t len;
5607+ struct au_pin *pin;
5608+ unsigned int flags;
5609+};
5610+
1facf9fc 5611+/* cpup flags */
392086de
AM
5612+#define AuCpup_DTIME 1 /* do dtime_store/revert */
5613+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
5614+ for link(2) */
5615+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
5616+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
5617+ cpup */
5618+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
5619+ existing entry */
5620+#define AuCpup_RWDST (1 << 5) /* force write target even if
5621+ the branch is marked as RO */
c2b27bf2 5622+
1facf9fc 5623+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
5624+#define au_fset_cpup(flags, name) \
5625+ do { (flags) |= AuCpup_##name; } while (0)
5626+#define au_fclr_cpup(flags, name) \
5627+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 5628+
5629+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
5630+int au_sio_cpup_simple(struct au_cp_generic *cpg);
5631+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
5632+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 5633+
5634+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5635+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5636+ struct au_pin *pin,
1facf9fc 5637+ struct dentry *h_parent, void *arg),
5638+ void *arg);
5639+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5640+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5641+
5642+/* ---------------------------------------------------------------------- */
5643+
5644+/* keep timestamps when copyup */
5645+struct au_dtime {
5646+ struct dentry *dt_dentry;
5647+ struct path dt_h_path;
5648+ struct timespec dt_atime, dt_mtime;
5649+};
5650+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5651+ struct path *h_path);
5652+void au_dtime_revert(struct au_dtime *dt);
5653+
5654+#endif /* __KERNEL__ */
5655+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
5656diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
5657--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
076b876e 5658+++ linux/fs/aufs/dbgaufs.c 2014-01-30 21:10:02.827480967 +0100
523b37e3 5659@@ -0,0 +1,432 @@
1facf9fc 5660+/*
523b37e3 5661+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5662+ *
5663+ * This program, aufs is free software; you can redistribute it and/or modify
5664+ * it under the terms of the GNU General Public License as published by
5665+ * the Free Software Foundation; either version 2 of the License, or
5666+ * (at your option) any later version.
dece6358
AM
5667+ *
5668+ * This program is distributed in the hope that it will be useful,
5669+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5670+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5671+ * GNU General Public License for more details.
5672+ *
5673+ * You should have received a copy of the GNU General Public License
523b37e3 5674+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5675+ */
5676+
5677+/*
5678+ * debugfs interface
5679+ */
5680+
5681+#include <linux/debugfs.h>
5682+#include "aufs.h"
5683+
5684+#ifndef CONFIG_SYSFS
5685+#error DEBUG_FS depends upon SYSFS
5686+#endif
5687+
5688+static struct dentry *dbgaufs;
5689+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
5690+
5691+/* 20 is max digits length of ulong 64 */
5692+struct dbgaufs_arg {
5693+ int n;
5694+ char a[20 * 4];
5695+};
5696+
5697+/*
5698+ * common function for all XINO files
5699+ */
5700+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
5701+ struct file *file)
5702+{
5703+ kfree(file->private_data);
5704+ return 0;
5705+}
5706+
5707+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
5708+{
5709+ int err;
5710+ struct kstat st;
5711+ struct dbgaufs_arg *p;
5712+
5713+ err = -ENOMEM;
5714+ p = kmalloc(sizeof(*p), GFP_NOFS);
5715+ if (unlikely(!p))
5716+ goto out;
5717+
5718+ err = 0;
5719+ p->n = 0;
5720+ file->private_data = p;
5721+ if (!xf)
5722+ goto out;
5723+
c06a8ce3 5724+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 5725+ if (!err) {
5726+ if (do_fcnt)
5727+ p->n = snprintf
5728+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
5729+ (long)file_count(xf), st.blocks, st.blksize,
5730+ (long long)st.size);
5731+ else
5732+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
5733+ st.blocks, st.blksize,
5734+ (long long)st.size);
5735+ AuDebugOn(p->n >= sizeof(p->a));
5736+ } else {
5737+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
5738+ err = 0;
5739+ }
5740+
4f0767ce 5741+out:
1facf9fc 5742+ return err;
5743+
5744+}
5745+
5746+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
5747+ size_t count, loff_t *ppos)
5748+{
5749+ struct dbgaufs_arg *p;
5750+
5751+ p = file->private_data;
5752+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5753+}
5754+
5755+/* ---------------------------------------------------------------------- */
5756+
86dc4139
AM
5757+struct dbgaufs_plink_arg {
5758+ int n;
5759+ char a[];
5760+};
5761+
5762+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
5763+ struct file *file)
5764+{
5765+ free_page((unsigned long)file->private_data);
5766+ return 0;
5767+}
5768+
5769+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
5770+{
5771+ int err, i, limit;
5772+ unsigned long n, sum;
5773+ struct dbgaufs_plink_arg *p;
5774+ struct au_sbinfo *sbinfo;
5775+ struct super_block *sb;
5776+ struct au_sphlhead *sphl;
5777+
5778+ err = -ENOMEM;
5779+ p = (void *)get_zeroed_page(GFP_NOFS);
5780+ if (unlikely(!p))
5781+ goto out;
5782+
5783+ err = -EFBIG;
5784+ sbinfo = inode->i_private;
5785+ sb = sbinfo->si_sb;
5786+ si_noflush_read_lock(sb);
5787+ if (au_opt_test(au_mntflags(sb), PLINK)) {
5788+ limit = PAGE_SIZE - sizeof(p->n);
5789+
5790+ /* the number of buckets */
5791+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
5792+ p->n += n;
5793+ limit -= n;
5794+
5795+ sum = 0;
5796+ for (i = 0, sphl = sbinfo->si_plink;
5797+ i < AuPlink_NHASH;
5798+ i++, sphl++) {
5799+ n = au_sphl_count(sphl);
5800+ sum += n;
5801+
5802+ n = snprintf(p->a + p->n, limit, "%lu ", n);
5803+ p->n += n;
5804+ limit -= n;
5805+ if (unlikely(limit <= 0))
5806+ goto out_free;
5807+ }
5808+ p->a[p->n - 1] = '\n';
5809+
5810+ /* the sum of plinks */
5811+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
5812+ p->n += n;
5813+ limit -= n;
5814+ if (unlikely(limit <= 0))
5815+ goto out_free;
5816+ } else {
5817+#define str "1\n0\n0\n"
5818+ p->n = sizeof(str) - 1;
5819+ strcpy(p->a, str);
5820+#undef str
5821+ }
5822+ si_read_unlock(sb);
5823+
5824+ err = 0;
5825+ file->private_data = p;
5826+ goto out; /* success */
5827+
5828+out_free:
5829+ free_page((unsigned long)p);
5830+out:
5831+ return err;
5832+}
5833+
5834+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
5835+ size_t count, loff_t *ppos)
5836+{
5837+ struct dbgaufs_plink_arg *p;
5838+
5839+ p = file->private_data;
5840+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5841+}
5842+
5843+static const struct file_operations dbgaufs_plink_fop = {
5844+ .owner = THIS_MODULE,
5845+ .open = dbgaufs_plink_open,
5846+ .release = dbgaufs_plink_release,
5847+ .read = dbgaufs_plink_read
5848+};
5849+
5850+/* ---------------------------------------------------------------------- */
5851+
1facf9fc 5852+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
5853+{
5854+ int err;
5855+ struct au_sbinfo *sbinfo;
5856+ struct super_block *sb;
5857+
5858+ sbinfo = inode->i_private;
5859+ sb = sbinfo->si_sb;
5860+ si_noflush_read_lock(sb);
5861+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
5862+ si_read_unlock(sb);
5863+ return err;
5864+}
5865+
5866+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 5867+ .owner = THIS_MODULE,
1facf9fc 5868+ .open = dbgaufs_xib_open,
5869+ .release = dbgaufs_xi_release,
5870+ .read = dbgaufs_xi_read
5871+};
5872+
5873+/* ---------------------------------------------------------------------- */
5874+
5875+#define DbgaufsXi_PREFIX "xi"
5876+
5877+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
5878+{
5879+ int err;
5880+ long l;
5881+ struct au_sbinfo *sbinfo;
5882+ struct super_block *sb;
5883+ struct file *xf;
5884+ struct qstr *name;
5885+
5886+ err = -ENOENT;
5887+ xf = NULL;
5888+ name = &file->f_dentry->d_name;
5889+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
5890+ || memcmp(name->name, DbgaufsXi_PREFIX,
5891+ sizeof(DbgaufsXi_PREFIX) - 1)))
5892+ goto out;
9dbd164d 5893+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 5894+ if (unlikely(err))
5895+ goto out;
5896+
5897+ sbinfo = inode->i_private;
5898+ sb = sbinfo->si_sb;
5899+ si_noflush_read_lock(sb);
5900+ if (l <= au_sbend(sb)) {
5901+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
5902+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
5903+ } else
5904+ err = -ENOENT;
5905+ si_read_unlock(sb);
5906+
4f0767ce 5907+out:
1facf9fc 5908+ return err;
5909+}
5910+
5911+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 5912+ .owner = THIS_MODULE,
1facf9fc 5913+ .open = dbgaufs_xino_open,
5914+ .release = dbgaufs_xi_release,
5915+ .read = dbgaufs_xi_read
5916+};
5917+
5918+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
5919+{
5920+ aufs_bindex_t bend;
5921+ struct au_branch *br;
5922+ struct au_xino_file *xi;
5923+
5924+ if (!au_sbi(sb)->si_dbgaufs)
5925+ return;
5926+
5927+ bend = au_sbend(sb);
5928+ for (; bindex <= bend; bindex++) {
5929+ br = au_sbr(sb, bindex);
5930+ xi = &br->br_xino;
c06a8ce3
AM
5931+ debugfs_remove(xi->xi_dbgaufs);
5932+ xi->xi_dbgaufs = NULL;
1facf9fc 5933+ }
5934+}
5935+
5936+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
5937+{
5938+ struct au_sbinfo *sbinfo;
5939+ struct dentry *parent;
5940+ struct au_branch *br;
5941+ struct au_xino_file *xi;
5942+ aufs_bindex_t bend;
5943+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
5944+
5945+ sbinfo = au_sbi(sb);
5946+ parent = sbinfo->si_dbgaufs;
5947+ if (!parent)
5948+ return;
5949+
5950+ bend = au_sbend(sb);
5951+ for (; bindex <= bend; bindex++) {
5952+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
5953+ br = au_sbr(sb, bindex);
5954+ xi = &br->br_xino;
5955+ AuDebugOn(xi->xi_dbgaufs);
5956+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
5957+ sbinfo, &dbgaufs_xino_fop);
5958+ /* ignore an error */
5959+ if (unlikely(!xi->xi_dbgaufs))
5960+ AuWarn1("failed %s under debugfs\n", name);
5961+ }
5962+}
5963+
5964+/* ---------------------------------------------------------------------- */
5965+
5966+#ifdef CONFIG_AUFS_EXPORT
5967+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
5968+{
5969+ int err;
5970+ struct au_sbinfo *sbinfo;
5971+ struct super_block *sb;
5972+
5973+ sbinfo = inode->i_private;
5974+ sb = sbinfo->si_sb;
5975+ si_noflush_read_lock(sb);
5976+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
5977+ si_read_unlock(sb);
5978+ return err;
5979+}
5980+
5981+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 5982+ .owner = THIS_MODULE,
1facf9fc 5983+ .open = dbgaufs_xigen_open,
5984+ .release = dbgaufs_xi_release,
5985+ .read = dbgaufs_xi_read
5986+};
5987+
5988+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
5989+{
5990+ int err;
5991+
dece6358
AM
5992+ /*
5993+ * This function is a dynamic '__init' fucntion actually,
5994+ * so the tiny check for si_rwsem is unnecessary.
5995+ */
5996+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
5997+
1facf9fc 5998+ err = -EIO;
5999+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6000+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6001+ &dbgaufs_xigen_fop);
6002+ if (sbinfo->si_dbgaufs_xigen)
6003+ err = 0;
6004+
6005+ return err;
6006+}
6007+#else
6008+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6009+{
6010+ return 0;
6011+}
6012+#endif /* CONFIG_AUFS_EXPORT */
6013+
6014+/* ---------------------------------------------------------------------- */
6015+
6016+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6017+{
dece6358
AM
6018+ /*
6019+ * This function is a dynamic '__init' fucntion actually,
6020+ * so the tiny check for si_rwsem is unnecessary.
6021+ */
6022+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6023+
1facf9fc 6024+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6025+ sbinfo->si_dbgaufs = NULL;
6026+ kobject_put(&sbinfo->si_kobj);
6027+}
6028+
6029+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6030+{
6031+ int err;
6032+ char name[SysaufsSiNameLen];
6033+
dece6358
AM
6034+ /*
6035+ * This function is a dynamic '__init' fucntion actually,
6036+ * so the tiny check for si_rwsem is unnecessary.
6037+ */
6038+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6039+
1facf9fc 6040+ err = -ENOENT;
6041+ if (!dbgaufs) {
6042+ AuErr1("/debug/aufs is uninitialized\n");
6043+ goto out;
6044+ }
6045+
6046+ err = -EIO;
6047+ sysaufs_name(sbinfo, name);
6048+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6049+ if (unlikely(!sbinfo->si_dbgaufs))
6050+ goto out;
6051+ kobject_get(&sbinfo->si_kobj);
6052+
6053+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6054+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6055+ &dbgaufs_xib_fop);
6056+ if (unlikely(!sbinfo->si_dbgaufs_xib))
6057+ goto out_dir;
6058+
86dc4139
AM
6059+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6060+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6061+ &dbgaufs_plink_fop);
6062+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6063+ goto out_dir;
6064+
1facf9fc 6065+ err = dbgaufs_xigen_init(sbinfo);
6066+ if (!err)
6067+ goto out; /* success */
6068+
4f0767ce 6069+out_dir:
1facf9fc 6070+ dbgaufs_si_fin(sbinfo);
4f0767ce 6071+out:
1facf9fc 6072+ return err;
6073+}
6074+
6075+/* ---------------------------------------------------------------------- */
6076+
6077+void dbgaufs_fin(void)
6078+{
6079+ debugfs_remove(dbgaufs);
6080+}
6081+
6082+int __init dbgaufs_init(void)
6083+{
6084+ int err;
6085+
6086+ err = -EIO;
6087+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
6088+ if (dbgaufs)
6089+ err = 0;
6090+ return err;
6091+}
7f207e10
AM
6092diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
6093--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
076b876e 6094+++ linux/fs/aufs/dbgaufs.h 2014-01-30 21:10:02.827480967 +0100
523b37e3 6095@@ -0,0 +1,48 @@
1facf9fc 6096+/*
523b37e3 6097+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6098+ *
6099+ * This program, aufs is free software; you can redistribute it and/or modify
6100+ * it under the terms of the GNU General Public License as published by
6101+ * the Free Software Foundation; either version 2 of the License, or
6102+ * (at your option) any later version.
dece6358
AM
6103+ *
6104+ * This program is distributed in the hope that it will be useful,
6105+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6106+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6107+ * GNU General Public License for more details.
6108+ *
6109+ * You should have received a copy of the GNU General Public License
523b37e3 6110+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6111+ */
6112+
6113+/*
6114+ * debugfs interface
6115+ */
6116+
6117+#ifndef __DBGAUFS_H__
6118+#define __DBGAUFS_H__
6119+
6120+#ifdef __KERNEL__
6121+
dece6358 6122+struct super_block;
1facf9fc 6123+struct au_sbinfo;
dece6358 6124+
1facf9fc 6125+#ifdef CONFIG_DEBUG_FS
6126+/* dbgaufs.c */
6127+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
6128+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
6129+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
6130+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
6131+void dbgaufs_fin(void);
6132+int __init dbgaufs_init(void);
1facf9fc 6133+#else
4a4d8108
AM
6134+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
6135+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
6136+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
6137+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
6138+AuStubVoid(dbgaufs_fin, void)
6139+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 6140+#endif /* CONFIG_DEBUG_FS */
6141+
6142+#endif /* __KERNEL__ */
6143+#endif /* __DBGAUFS_H__ */
7f207e10
AM
6144diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
6145--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
076b876e 6146+++ linux/fs/aufs/dcsub.c 2014-01-30 21:10:02.827480967 +0100
027c5e7a 6147@@ -0,0 +1,243 @@
1facf9fc 6148+/*
523b37e3 6149+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6150+ *
6151+ * This program, aufs is free software; you can redistribute it and/or modify
6152+ * it under the terms of the GNU General Public License as published by
6153+ * the Free Software Foundation; either version 2 of the License, or
6154+ * (at your option) any later version.
dece6358
AM
6155+ *
6156+ * This program is distributed in the hope that it will be useful,
6157+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6158+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6159+ * GNU General Public License for more details.
6160+ *
6161+ * You should have received a copy of the GNU General Public License
523b37e3 6162+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6163+ */
6164+
6165+/*
6166+ * sub-routines for dentry cache
6167+ */
6168+
6169+#include "aufs.h"
6170+
6171+static void au_dpage_free(struct au_dpage *dpage)
6172+{
6173+ int i;
6174+ struct dentry **p;
6175+
6176+ p = dpage->dentries;
6177+ for (i = 0; i < dpage->ndentry; i++)
6178+ dput(*p++);
6179+ free_page((unsigned long)dpage->dentries);
6180+}
6181+
6182+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
6183+{
6184+ int err;
6185+ void *p;
6186+
6187+ err = -ENOMEM;
6188+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
6189+ if (unlikely(!dpages->dpages))
6190+ goto out;
6191+
6192+ p = (void *)__get_free_page(gfp);
6193+ if (unlikely(!p))
6194+ goto out_dpages;
6195+
6196+ dpages->dpages[0].ndentry = 0;
6197+ dpages->dpages[0].dentries = p;
6198+ dpages->ndpage = 1;
6199+ return 0; /* success */
6200+
4f0767ce 6201+out_dpages:
1facf9fc 6202+ kfree(dpages->dpages);
4f0767ce 6203+out:
1facf9fc 6204+ return err;
6205+}
6206+
6207+void au_dpages_free(struct au_dcsub_pages *dpages)
6208+{
6209+ int i;
6210+ struct au_dpage *p;
6211+
6212+ p = dpages->dpages;
6213+ for (i = 0; i < dpages->ndpage; i++)
6214+ au_dpage_free(p++);
6215+ kfree(dpages->dpages);
6216+}
6217+
6218+static int au_dpages_append(struct au_dcsub_pages *dpages,
6219+ struct dentry *dentry, gfp_t gfp)
6220+{
6221+ int err, sz;
6222+ struct au_dpage *dpage;
6223+ void *p;
6224+
6225+ dpage = dpages->dpages + dpages->ndpage - 1;
6226+ sz = PAGE_SIZE / sizeof(dentry);
6227+ if (unlikely(dpage->ndentry >= sz)) {
6228+ AuLabel(new dpage);
6229+ err = -ENOMEM;
6230+ sz = dpages->ndpage * sizeof(*dpages->dpages);
6231+ p = au_kzrealloc(dpages->dpages, sz,
6232+ sz + sizeof(*dpages->dpages), gfp);
6233+ if (unlikely(!p))
6234+ goto out;
6235+
6236+ dpages->dpages = p;
6237+ dpage = dpages->dpages + dpages->ndpage;
6238+ p = (void *)__get_free_page(gfp);
6239+ if (unlikely(!p))
6240+ goto out;
6241+
6242+ dpage->ndentry = 0;
6243+ dpage->dentries = p;
6244+ dpages->ndpage++;
6245+ }
6246+
392086de 6247+ AuDebugOn(!d_count(dentry));
027c5e7a 6248+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 6249+ return 0; /* success */
6250+
4f0767ce 6251+out:
1facf9fc 6252+ return err;
6253+}
6254+
523b37e3 6255+/* try d_walk() in linux/fs/dcache.c */
1facf9fc 6256+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6257+ au_dpages_test test, void *arg)
6258+{
6259+ int err;
027c5e7a 6260+ struct dentry *this_parent;
1facf9fc 6261+ struct list_head *next;
6262+ struct super_block *sb = root->d_sb;
6263+
6264+ err = 0;
027c5e7a
AM
6265+ write_seqlock(&rename_lock);
6266+ this_parent = root;
6267+ spin_lock(&this_parent->d_lock);
4f0767ce 6268+repeat:
1facf9fc 6269+ next = this_parent->d_subdirs.next;
4f0767ce 6270+resume:
1facf9fc 6271+ if (this_parent->d_sb == sb
6272+ && !IS_ROOT(this_parent)
027c5e7a 6273+ && au_di(this_parent)
392086de 6274+ && d_count(this_parent)
1facf9fc 6275+ && (!test || test(this_parent, arg))) {
6276+ err = au_dpages_append(dpages, this_parent, GFP_ATOMIC);
6277+ if (unlikely(err))
6278+ goto out;
6279+ }
6280+
6281+ while (next != &this_parent->d_subdirs) {
6282+ struct list_head *tmp = next;
6283+ struct dentry *dentry = list_entry(tmp, struct dentry,
6284+ d_u.d_child);
027c5e7a 6285+
1facf9fc 6286+ next = tmp->next;
027c5e7a 6287+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
392086de 6288+ if (d_count(dentry)) {
027c5e7a
AM
6289+ if (!list_empty(&dentry->d_subdirs)) {
6290+ spin_unlock(&this_parent->d_lock);
6291+ spin_release(&dentry->d_lock.dep_map, 1,
6292+ _RET_IP_);
6293+ this_parent = dentry;
6294+ spin_acquire(&this_parent->d_lock.dep_map, 0, 1,
6295+ _RET_IP_);
6296+ goto repeat;
6297+ }
6298+ if (dentry->d_sb == sb
6299+ && au_di(dentry)
6300+ && (!test || test(dentry, arg)))
6301+ err = au_dpages_append(dpages, dentry,
6302+ GFP_ATOMIC);
1facf9fc 6303+ }
027c5e7a
AM
6304+ spin_unlock(&dentry->d_lock);
6305+ if (unlikely(err))
6306+ goto out;
1facf9fc 6307+ }
6308+
6309+ if (this_parent != root) {
027c5e7a
AM
6310+ struct dentry *tmp;
6311+ struct dentry *child;
6312+
6313+ tmp = this_parent->d_parent;
6314+ rcu_read_lock();
6315+ spin_unlock(&this_parent->d_lock);
6316+ child = this_parent;
6317+ this_parent = tmp;
6318+ spin_lock(&this_parent->d_lock);
6319+ rcu_read_unlock();
6320+ next = child->d_u.d_child.next;
1facf9fc 6321+ goto resume;
6322+ }
027c5e7a 6323+
4f0767ce 6324+out:
027c5e7a
AM
6325+ spin_unlock(&this_parent->d_lock);
6326+ write_sequnlock(&rename_lock);
1facf9fc 6327+ return err;
6328+}
6329+
6330+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6331+ int do_include, au_dpages_test test, void *arg)
6332+{
6333+ int err;
6334+
6335+ err = 0;
027c5e7a
AM
6336+ write_seqlock(&rename_lock);
6337+ spin_lock(&dentry->d_lock);
6338+ if (do_include
392086de 6339+ && d_count(dentry)
027c5e7a 6340+ && (!test || test(dentry, arg)))
1facf9fc 6341+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6342+ spin_unlock(&dentry->d_lock);
6343+ if (unlikely(err))
6344+ goto out;
6345+
6346+ /*
523b37e3 6347+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
6348+ * mount
6349+ */
1facf9fc 6350+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
6351+ dentry = dentry->d_parent; /* rename_lock is locked */
6352+ spin_lock(&dentry->d_lock);
392086de 6353+ if (d_count(dentry)
027c5e7a 6354+ && (!test || test(dentry, arg)))
1facf9fc 6355+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6356+ spin_unlock(&dentry->d_lock);
6357+ if (unlikely(err))
6358+ break;
1facf9fc 6359+ }
6360+
4f0767ce 6361+out:
027c5e7a 6362+ write_sequnlock(&rename_lock);
1facf9fc 6363+ return err;
6364+}
6365+
027c5e7a
AM
6366+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
6367+{
6368+ return au_di(dentry) && dentry->d_sb == arg;
6369+}
6370+
6371+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6372+ struct dentry *dentry, int do_include)
6373+{
6374+ return au_dcsub_pages_rev(dpages, dentry, do_include,
6375+ au_dcsub_dpages_aufs, dentry->d_sb);
6376+}
6377+
4a4d8108 6378+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 6379+{
4a4d8108
AM
6380+ struct path path[2] = {
6381+ {
6382+ .dentry = d1
6383+ },
6384+ {
6385+ .dentry = d2
6386+ }
6387+ };
1facf9fc 6388+
4a4d8108 6389+ return path_is_under(path + 0, path + 1);
1facf9fc 6390+}
7f207e10
AM
6391diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
6392--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
6393+++ linux/fs/aufs/dcsub.h 2014-08-14 10:15:45.118609182 +0200
6394@@ -0,0 +1,120 @@
1facf9fc 6395+/*
523b37e3 6396+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6397+ *
6398+ * This program, aufs is free software; you can redistribute it and/or modify
6399+ * it under the terms of the GNU General Public License as published by
6400+ * the Free Software Foundation; either version 2 of the License, or
6401+ * (at your option) any later version.
dece6358
AM
6402+ *
6403+ * This program is distributed in the hope that it will be useful,
6404+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6405+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6406+ * GNU General Public License for more details.
6407+ *
6408+ * You should have received a copy of the GNU General Public License
523b37e3 6409+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6410+ */
6411+
6412+/*
6413+ * sub-routines for dentry cache
6414+ */
6415+
6416+#ifndef __AUFS_DCSUB_H__
6417+#define __AUFS_DCSUB_H__
6418+
6419+#ifdef __KERNEL__
6420+
7f207e10 6421+#include <linux/dcache.h>
027c5e7a 6422+#include <linux/fs.h>
dece6358
AM
6423+
6424+struct dentry;
1facf9fc 6425+
6426+struct au_dpage {
6427+ int ndentry;
6428+ struct dentry **dentries;
6429+};
6430+
6431+struct au_dcsub_pages {
6432+ int ndpage;
6433+ struct au_dpage *dpages;
6434+};
6435+
6436+/* ---------------------------------------------------------------------- */
6437+
7f207e10 6438+/* dcsub.c */
1facf9fc 6439+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
6440+void au_dpages_free(struct au_dcsub_pages *dpages);
6441+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
6442+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6443+ au_dpages_test test, void *arg);
6444+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6445+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
6446+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6447+ struct dentry *dentry, int do_include);
4a4d8108 6448+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 6449+
7f207e10
AM
6450+/* ---------------------------------------------------------------------- */
6451+
523b37e3
AM
6452+/*
6453+ * todo: in linux-3.13, several similar (but faster) helpers are added to
6454+ * include/linux/dcache.h. Try them (in the future).
6455+ */
6456+
027c5e7a
AM
6457+static inline int au_d_hashed_positive(struct dentry *d)
6458+{
6459+ int err;
6460+ struct inode *inode = d->d_inode;
076b876e 6461+
027c5e7a
AM
6462+ err = 0;
6463+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
6464+ err = -ENOENT;
6465+ return err;
6466+}
6467+
38d290e6
JR
6468+static inline int au_d_linkable(struct dentry *d)
6469+{
6470+ int err;
6471+ struct inode *inode = d->d_inode;
076b876e 6472+
38d290e6
JR
6473+ err = au_d_hashed_positive(d);
6474+ if (err
6475+ && inode
6476+ && (inode->i_state & I_LINKABLE))
6477+ err = 0;
6478+ return err;
6479+}
6480+
027c5e7a
AM
6481+static inline int au_d_alive(struct dentry *d)
6482+{
6483+ int err;
6484+ struct inode *inode;
076b876e 6485+
027c5e7a
AM
6486+ err = 0;
6487+ if (!IS_ROOT(d))
6488+ err = au_d_hashed_positive(d);
6489+ else {
6490+ inode = d->d_inode;
6491+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
6492+ err = -ENOENT;
6493+ }
6494+ return err;
6495+}
6496+
6497+static inline int au_alive_dir(struct dentry *d)
7f207e10 6498+{
027c5e7a 6499+ int err;
076b876e 6500+
027c5e7a
AM
6501+ err = au_d_alive(d);
6502+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
6503+ err = -ENOENT;
6504+ return err;
7f207e10
AM
6505+}
6506+
38d290e6
JR
6507+static inline int au_qstreq(struct qstr *a, struct qstr *b)
6508+{
6509+ return a->len == b->len
6510+ && !memcmp(a->name, b->name, a->len);
6511+}
6512+
1facf9fc 6513+#endif /* __KERNEL__ */
6514+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
6515diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
6516--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
6517+++ linux/fs/aufs/debug.c 2014-08-14 10:15:45.121942630 +0200
6518@@ -0,0 +1,519 @@
1facf9fc 6519+/*
523b37e3 6520+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6521+ *
6522+ * This program, aufs is free software; you can redistribute it and/or modify
6523+ * it under the terms of the GNU General Public License as published by
6524+ * the Free Software Foundation; either version 2 of the License, or
6525+ * (at your option) any later version.
dece6358
AM
6526+ *
6527+ * This program is distributed in the hope that it will be useful,
6528+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6529+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6530+ * GNU General Public License for more details.
6531+ *
6532+ * You should have received a copy of the GNU General Public License
523b37e3 6533+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6534+ */
6535+
6536+/*
6537+ * debug print functions
6538+ */
6539+
7f207e10 6540+#include <linux/vt_kern.h>
1facf9fc 6541+#include "aufs.h"
6542+
392086de
AM
6543+/* Returns 0, or -errno. arg is in kp->arg. */
6544+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
6545+{
6546+ int err, n;
6547+
6548+ err = kstrtoint(val, 0, &n);
6549+ if (!err) {
6550+ if (n > 0)
6551+ au_debug_on();
6552+ else
6553+ au_debug_off();
6554+ }
6555+ return err;
6556+}
6557+
6558+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
6559+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
6560+{
6561+ atomic_t *a;
6562+
6563+ a = kp->arg;
6564+ return sprintf(buffer, "%d", atomic_read(a));
6565+}
6566+
6567+static struct kernel_param_ops param_ops_atomic_t = {
6568+ .set = param_atomic_t_set,
6569+ .get = param_atomic_t_get
6570+ /* void (*free)(void *arg) */
6571+};
6572+
6573+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 6574+MODULE_PARM_DESC(debug, "debug print");
392086de 6575+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 6576+
6577+char *au_plevel = KERN_DEBUG;
e49829fe
JR
6578+#define dpri(fmt, ...) do { \
6579+ if ((au_plevel \
6580+ && strcmp(au_plevel, KERN_DEBUG)) \
6581+ || au_debug_test()) \
6582+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 6583+} while (0)
6584+
6585+/* ---------------------------------------------------------------------- */
6586+
6587+void au_dpri_whlist(struct au_nhash *whlist)
6588+{
6589+ unsigned long ul, n;
6590+ struct hlist_head *head;
c06a8ce3 6591+ struct au_vdir_wh *pos;
1facf9fc 6592+
6593+ n = whlist->nh_num;
6594+ head = whlist->nh_head;
6595+ for (ul = 0; ul < n; ul++) {
c06a8ce3 6596+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 6597+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
6598+ pos->wh_bindex,
6599+ pos->wh_str.len, pos->wh_str.name,
6600+ pos->wh_str.len);
1facf9fc 6601+ head++;
6602+ }
6603+}
6604+
6605+void au_dpri_vdir(struct au_vdir *vdir)
6606+{
6607+ unsigned long ul;
6608+ union au_vdir_deblk_p p;
6609+ unsigned char *o;
6610+
6611+ if (!vdir || IS_ERR(vdir)) {
6612+ dpri("err %ld\n", PTR_ERR(vdir));
6613+ return;
6614+ }
6615+
6616+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
6617+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
6618+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
6619+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
6620+ p.deblk = vdir->vd_deblk[ul];
6621+ o = p.deblk;
6622+ dpri("[%lu]: %p\n", ul, o);
6623+ }
6624+}
6625+
53392da6 6626+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 6627+ struct dentry *wh)
6628+{
6629+ char *n = NULL;
6630+ int l = 0;
6631+
6632+ if (!inode || IS_ERR(inode)) {
6633+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
6634+ return -1;
6635+ }
6636+
c2b27bf2 6637+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 6638+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
6639+ && sizeof(inode->i_blocks) != sizeof(u64));
6640+ if (wh) {
6641+ n = (void *)wh->d_name.name;
6642+ l = wh->d_name.len;
6643+ }
6644+
53392da6
AM
6645+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
6646+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
6647+ bindex, inode,
1facf9fc 6648+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
6649+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
6650+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 6651+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 6652+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
6653+ inode->i_state, inode->i_flags, inode->i_version,
6654+ inode->i_generation,
1facf9fc 6655+ l ? ", wh " : "", l, n);
6656+ return 0;
6657+}
6658+
6659+void au_dpri_inode(struct inode *inode)
6660+{
6661+ struct au_iinfo *iinfo;
6662+ aufs_bindex_t bindex;
53392da6 6663+ int err, hn;
1facf9fc 6664+
53392da6 6665+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 6666+ if (err || !au_test_aufs(inode->i_sb))
6667+ return;
6668+
6669+ iinfo = au_ii(inode);
6670+ if (!iinfo)
6671+ return;
6672+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 6673+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 6674+ if (iinfo->ii_bstart < 0)
6675+ return;
53392da6
AM
6676+ hn = 0;
6677+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
6678+ hn = !!au_hn(iinfo->ii_hinode + bindex);
6679+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 6680+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 6681+ }
1facf9fc 6682+}
6683+
2cbb1c4b
JR
6684+void au_dpri_dalias(struct inode *inode)
6685+{
6686+ struct dentry *d;
6687+
6688+ spin_lock(&inode->i_lock);
c06a8ce3 6689+ hlist_for_each_entry(d, &inode->i_dentry, d_alias)
2cbb1c4b
JR
6690+ au_dpri_dentry(d);
6691+ spin_unlock(&inode->i_lock);
6692+}
6693+
1facf9fc 6694+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
6695+{
6696+ struct dentry *wh = NULL;
53392da6 6697+ int hn;
076b876e 6698+ struct au_iinfo *iinfo;
1facf9fc 6699+
6700+ if (!dentry || IS_ERR(dentry)) {
6701+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
6702+ return -1;
6703+ }
6704+ /* do not call dget_parent() here */
027c5e7a 6705+ /* note: access d_xxx without d_lock */
523b37e3
AM
6706+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
6707+ bindex, dentry, dentry,
1facf9fc 6708+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
523b37e3
AM
6709+ d_count(dentry), dentry->d_flags,
6710+ d_unhashed(dentry) ? "un" : "");
53392da6 6711+ hn = -1;
1facf9fc 6712+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
076b876e 6713+ iinfo = au_ii(dentry->d_inode);
53392da6
AM
6714+ if (iinfo) {
6715+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 6716+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 6717+ }
1facf9fc 6718+ }
53392da6 6719+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 6720+ return 0;
6721+}
6722+
6723+void au_dpri_dentry(struct dentry *dentry)
6724+{
6725+ struct au_dinfo *dinfo;
6726+ aufs_bindex_t bindex;
6727+ int err;
4a4d8108 6728+ struct au_hdentry *hdp;
1facf9fc 6729+
6730+ err = do_pri_dentry(-1, dentry);
6731+ if (err || !au_test_aufs(dentry->d_sb))
6732+ return;
6733+
6734+ dinfo = au_di(dentry);
6735+ if (!dinfo)
6736+ return;
38d290e6 6737+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
1facf9fc 6738+ dinfo->di_bstart, dinfo->di_bend,
38d290e6
JR
6739+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
6740+ dinfo->di_tmpfile);
1facf9fc 6741+ if (dinfo->di_bstart < 0)
6742+ return;
4a4d8108 6743+ hdp = dinfo->di_hdentry;
1facf9fc 6744+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 6745+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 6746+}
6747+
6748+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
6749+{
6750+ char a[32];
6751+
6752+ if (!file || IS_ERR(file)) {
6753+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
6754+ return -1;
6755+ }
6756+ a[0] = 0;
6757+ if (bindex < 0
6758+ && file->f_dentry
6759+ && au_test_aufs(file->f_dentry->d_sb)
6760+ && au_fi(file))
e49829fe 6761+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 6762+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 6763+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 6764+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 6765+ file->f_version, file->f_pos, a);
1facf9fc 6766+ if (file->f_dentry)
6767+ do_pri_dentry(bindex, file->f_dentry);
6768+ return 0;
6769+}
6770+
6771+void au_dpri_file(struct file *file)
6772+{
6773+ struct au_finfo *finfo;
4a4d8108
AM
6774+ struct au_fidir *fidir;
6775+ struct au_hfile *hfile;
1facf9fc 6776+ aufs_bindex_t bindex;
6777+ int err;
6778+
6779+ err = do_pri_file(-1, file);
6780+ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
6781+ return;
6782+
6783+ finfo = au_fi(file);
6784+ if (!finfo)
6785+ return;
4a4d8108 6786+ if (finfo->fi_btop < 0)
1facf9fc 6787+ return;
4a4d8108
AM
6788+ fidir = finfo->fi_hdir;
6789+ if (!fidir)
6790+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
6791+ else
e49829fe
JR
6792+ for (bindex = finfo->fi_btop;
6793+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
6794+ bindex++) {
6795+ hfile = fidir->fd_hfile + bindex;
6796+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
6797+ }
1facf9fc 6798+}
6799+
6800+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
6801+{
6802+ struct vfsmount *mnt;
6803+ struct super_block *sb;
6804+
6805+ if (!br || IS_ERR(br))
6806+ goto out;
86dc4139 6807+ mnt = au_br_mnt(br);
1facf9fc 6808+ if (!mnt || IS_ERR(mnt))
6809+ goto out;
6810+ sb = mnt->mnt_sb;
6811+ if (!sb || IS_ERR(sb))
6812+ goto out;
6813+
1e00d052 6814+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 6815+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 6816+ "xino %d\n",
1e00d052
AM
6817+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
6818+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 6819+ sb->s_flags, sb->s_count,
1facf9fc 6820+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
6821+ return 0;
6822+
4f0767ce 6823+out:
1facf9fc 6824+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
6825+ return -1;
6826+}
6827+
6828+void au_dpri_sb(struct super_block *sb)
6829+{
6830+ struct au_sbinfo *sbinfo;
6831+ aufs_bindex_t bindex;
6832+ int err;
6833+ /* to reuduce stack size */
6834+ struct {
6835+ struct vfsmount mnt;
6836+ struct au_branch fake;
6837+ } *a;
6838+
6839+ /* this function can be called from magic sysrq */
6840+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
6841+ if (unlikely(!a)) {
6842+ dpri("no memory\n");
6843+ return;
6844+ }
6845+
6846+ a->mnt.mnt_sb = sb;
6847+ a->fake.br_perm = 0;
86dc4139 6848+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 6849+ a->fake.br_xino.xi_file = NULL;
6850+ atomic_set(&a->fake.br_count, 0);
6851+ smp_mb(); /* atomic_set */
6852+ err = do_pri_br(-1, &a->fake);
6853+ kfree(a);
6854+ dpri("dev 0x%x\n", sb->s_dev);
6855+ if (err || !au_test_aufs(sb))
6856+ return;
6857+
6858+ sbinfo = au_sbi(sb);
6859+ if (!sbinfo)
6860+ return;
6861+ dpri("nw %d, gen %u, kobj %d\n",
6862+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
6863+ atomic_read(&sbinfo->si_kobj.kref.refcount));
6864+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
6865+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
6866+}
6867+
6868+/* ---------------------------------------------------------------------- */
6869+
6870+void au_dbg_sleep_jiffy(int jiffy)
6871+{
6872+ while (jiffy)
6873+ jiffy = schedule_timeout_uninterruptible(jiffy);
6874+}
6875+
6876+void au_dbg_iattr(struct iattr *ia)
6877+{
c06a8ce3
AM
6878+#define AuBit(name) \
6879+ do { \
6880+ if (ia->ia_valid & ATTR_ ## name) \
6881+ dpri(#name "\n"); \
6882+ } while (0)
1facf9fc 6883+ AuBit(MODE);
6884+ AuBit(UID);
6885+ AuBit(GID);
6886+ AuBit(SIZE);
6887+ AuBit(ATIME);
6888+ AuBit(MTIME);
6889+ AuBit(CTIME);
6890+ AuBit(ATIME_SET);
6891+ AuBit(MTIME_SET);
6892+ AuBit(FORCE);
6893+ AuBit(ATTR_FLAG);
6894+ AuBit(KILL_SUID);
6895+ AuBit(KILL_SGID);
6896+ AuBit(FILE);
6897+ AuBit(KILL_PRIV);
6898+ AuBit(OPEN);
6899+ AuBit(TIMES_SET);
6900+#undef AuBit
6901+ dpri("ia_file %p\n", ia->ia_file);
6902+}
6903+
6904+/* ---------------------------------------------------------------------- */
6905+
027c5e7a
AM
6906+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
6907+{
6908+ struct inode *h_inode, *inode = dentry->d_inode;
6909+ struct dentry *h_dentry;
6910+ aufs_bindex_t bindex, bend, bi;
6911+
6912+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
6913+ return;
6914+
6915+ bend = au_dbend(dentry);
6916+ bi = au_ibend(inode);
6917+ if (bi < bend)
6918+ bend = bi;
6919+ bindex = au_dbstart(dentry);
6920+ bi = au_ibstart(inode);
6921+ if (bi > bindex)
6922+ bindex = bi;
6923+
6924+ for (; bindex <= bend; bindex++) {
6925+ h_dentry = au_h_dptr(dentry, bindex);
6926+ if (!h_dentry)
6927+ continue;
6928+ h_inode = au_h_iptr(inode, bindex);
6929+ if (unlikely(h_inode != h_dentry->d_inode)) {
392086de 6930+ au_debug_on();
027c5e7a
AM
6931+ AuDbg("b%d, %s:%d\n", bindex, func, line);
6932+ AuDbgDentry(dentry);
6933+ AuDbgInode(inode);
392086de 6934+ au_debug_off();
027c5e7a
AM
6935+ BUG();
6936+ }
6937+ }
6938+}
6939+
1facf9fc 6940+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
6941+{
6942+ struct dentry *parent;
6943+
6944+ parent = dget_parent(dentry);
027c5e7a
AM
6945+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
6946+ AuDebugOn(IS_ROOT(dentry));
6947+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6948+ dput(parent);
6949+}
6950+
6951+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
6952+{
6953+ struct dentry *parent;
027c5e7a 6954+ struct inode *inode;
1facf9fc 6955+
6956+ parent = dget_parent(dentry);
027c5e7a
AM
6957+ inode = dentry->d_inode;
6958+ AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
6959+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 6960+ dput(parent);
6961+}
6962+
6963+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
6964+{
6965+ int err, i, j;
6966+ struct au_dcsub_pages dpages;
6967+ struct au_dpage *dpage;
6968+ struct dentry **dentries;
6969+
6970+ err = au_dpages_init(&dpages, GFP_NOFS);
6971+ AuDebugOn(err);
027c5e7a 6972+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 6973+ AuDebugOn(err);
6974+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
6975+ dpage = dpages.dpages + i;
6976+ dentries = dpage->dentries;
6977+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 6978+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 6979+ }
6980+ au_dpages_free(&dpages);
6981+}
6982+
1facf9fc 6983+void au_dbg_verify_kthread(void)
6984+{
53392da6 6985+ if (au_wkq_test()) {
1facf9fc 6986+ au_dbg_blocked();
1e00d052
AM
6987+ /*
6988+ * It may be recursive, but udba=notify between two aufs mounts,
6989+ * where a single ro branch is shared, is not a problem.
6990+ */
6991+ /* WARN_ON(1); */
1facf9fc 6992+ }
6993+}
6994+
6995+/* ---------------------------------------------------------------------- */
6996+
6997+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
6998+{
6999+#ifdef AuForceNoPlink
7000+ au_opt_clr(sbinfo->si_mntflags, PLINK);
7001+#endif
7002+#ifdef AuForceNoXino
7003+ au_opt_clr(sbinfo->si_mntflags, XINO);
7004+#endif
7005+#ifdef AuForceNoRefrof
7006+ au_opt_clr(sbinfo->si_mntflags, REFROF);
7007+#endif
4a4d8108
AM
7008+#ifdef AuForceHnotify
7009+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
1facf9fc 7010+#endif
1308ab2a 7011+#ifdef AuForceRd0
7012+ sbinfo->si_rdblk = 0;
7013+ sbinfo->si_rdhash = 0;
7014+#endif
1facf9fc 7015+}
7016+
7017+int __init au_debug_init(void)
7018+{
7019+ aufs_bindex_t bindex;
7020+ struct au_vdir_destr destr;
7021+
7022+ bindex = -1;
7023+ AuDebugOn(bindex >= 0);
7024+
7025+ destr.len = -1;
7026+ AuDebugOn(destr.len < NAME_MAX);
7027+
7028+#ifdef CONFIG_4KSTACKS
0c3ec466 7029+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7030+#endif
7031+
7032+#ifdef AuForceNoBrs
7033+ sysaufs_brs = 0;
7034+#endif
7035+
7036+ return 0;
7037+}
7f207e10
AM
7038diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7039--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
076b876e 7040+++ linux/fs/aufs/debug.h 2014-01-30 21:10:02.827480967 +0100
523b37e3 7041@@ -0,0 +1,247 @@
1facf9fc 7042+/*
523b37e3 7043+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 7044+ *
7045+ * This program, aufs is free software; you can redistribute it and/or modify
7046+ * it under the terms of the GNU General Public License as published by
7047+ * the Free Software Foundation; either version 2 of the License, or
7048+ * (at your option) any later version.
dece6358
AM
7049+ *
7050+ * This program is distributed in the hope that it will be useful,
7051+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7052+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7053+ * GNU General Public License for more details.
7054+ *
7055+ * You should have received a copy of the GNU General Public License
523b37e3 7056+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7057+ */
7058+
7059+/*
7060+ * debug print functions
7061+ */
7062+
7063+#ifndef __AUFS_DEBUG_H__
7064+#define __AUFS_DEBUG_H__
7065+
7066+#ifdef __KERNEL__
7067+
392086de 7068+#include <linux/atomic.h>
4a4d8108
AM
7069+#include <linux/module.h>
7070+#include <linux/kallsyms.h>
1facf9fc 7071+#include <linux/sysrq.h>
4a4d8108 7072+
1facf9fc 7073+#ifdef CONFIG_AUFS_DEBUG
7074+#define AuDebugOn(a) BUG_ON(a)
7075+
7076+/* module parameter */
392086de
AM
7077+extern atomic_t aufs_debug;
7078+static inline void au_debug_on(void)
1facf9fc 7079+{
392086de
AM
7080+ atomic_inc(&aufs_debug);
7081+}
7082+static inline void au_debug_off(void)
7083+{
7084+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7085+}
7086+
7087+static inline int au_debug_test(void)
7088+{
392086de 7089+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7090+}
7091+#else
7092+#define AuDebugOn(a) do {} while (0)
392086de
AM
7093+AuStubVoid(au_debug_on, void)
7094+AuStubVoid(au_debug_off, void)
4a4d8108 7095+AuStubInt0(au_debug_test, void)
1facf9fc 7096+#endif /* CONFIG_AUFS_DEBUG */
7097+
392086de
AM
7098+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7099+
1facf9fc 7100+/* ---------------------------------------------------------------------- */
7101+
7102+/* debug print */
7103+
4a4d8108 7104+#define AuDbg(fmt, ...) do { \
1facf9fc 7105+ if (au_debug_test()) \
4a4d8108 7106+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7107+} while (0)
4a4d8108
AM
7108+#define AuLabel(l) AuDbg(#l "\n")
7109+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7110+#define AuWarn1(fmt, ...) do { \
1facf9fc 7111+ static unsigned char _c; \
7112+ if (!_c++) \
0c3ec466 7113+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 7114+} while (0)
7115+
4a4d8108 7116+#define AuErr1(fmt, ...) do { \
1facf9fc 7117+ static unsigned char _c; \
7118+ if (!_c++) \
4a4d8108 7119+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 7120+} while (0)
7121+
4a4d8108 7122+#define AuIOErr1(fmt, ...) do { \
1facf9fc 7123+ static unsigned char _c; \
7124+ if (!_c++) \
4a4d8108 7125+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 7126+} while (0)
7127+
7128+#define AuUnsupportMsg "This operation is not supported." \
7129+ " Please report this application to aufs-users ML."
4a4d8108
AM
7130+#define AuUnsupport(fmt, ...) do { \
7131+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 7132+ dump_stack(); \
7133+} while (0)
7134+
7135+#define AuTraceErr(e) do { \
7136+ if (unlikely((e) < 0)) \
7137+ AuDbg("err %d\n", (int)(e)); \
7138+} while (0)
7139+
7140+#define AuTraceErrPtr(p) do { \
7141+ if (IS_ERR(p)) \
7142+ AuDbg("err %ld\n", PTR_ERR(p)); \
7143+} while (0)
7144+
7145+/* dirty macros for debug print, use with "%.*s" and caution */
7146+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 7147+
7148+/* ---------------------------------------------------------------------- */
7149+
7150+struct au_sbinfo;
7151+struct au_finfo;
dece6358 7152+struct dentry;
1facf9fc 7153+#ifdef CONFIG_AUFS_DEBUG
7154+extern char *au_plevel;
7155+struct au_nhash;
7156+void au_dpri_whlist(struct au_nhash *whlist);
7157+struct au_vdir;
7158+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 7159+struct inode;
1facf9fc 7160+void au_dpri_inode(struct inode *inode);
2cbb1c4b 7161+void au_dpri_dalias(struct inode *inode);
1facf9fc 7162+void au_dpri_dentry(struct dentry *dentry);
dece6358 7163+struct file;
1facf9fc 7164+void au_dpri_file(struct file *filp);
dece6358 7165+struct super_block;
1facf9fc 7166+void au_dpri_sb(struct super_block *sb);
7167+
7168+void au_dbg_sleep_jiffy(int jiffy);
dece6358 7169+struct iattr;
1facf9fc 7170+void au_dbg_iattr(struct iattr *ia);
7171+
027c5e7a
AM
7172+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
7173+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 7174+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
7175+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
7176+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 7177+void au_dbg_verify_kthread(void);
7178+
7179+int __init au_debug_init(void);
7180+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
7181+#define AuDbgWhlist(w) do { \
7182+ AuDbg(#w "\n"); \
7183+ au_dpri_whlist(w); \
7184+} while (0)
7185+
7186+#define AuDbgVdir(v) do { \
7187+ AuDbg(#v "\n"); \
7188+ au_dpri_vdir(v); \
7189+} while (0)
7190+
7191+#define AuDbgInode(i) do { \
7192+ AuDbg(#i "\n"); \
7193+ au_dpri_inode(i); \
7194+} while (0)
7195+
2cbb1c4b
JR
7196+#define AuDbgDAlias(i) do { \
7197+ AuDbg(#i "\n"); \
7198+ au_dpri_dalias(i); \
7199+} while (0)
7200+
1facf9fc 7201+#define AuDbgDentry(d) do { \
7202+ AuDbg(#d "\n"); \
7203+ au_dpri_dentry(d); \
7204+} while (0)
7205+
7206+#define AuDbgFile(f) do { \
7207+ AuDbg(#f "\n"); \
7208+ au_dpri_file(f); \
7209+} while (0)
7210+
7211+#define AuDbgSb(sb) do { \
7212+ AuDbg(#sb "\n"); \
7213+ au_dpri_sb(sb); \
7214+} while (0)
7215+
7216+#define AuDbgSleep(sec) do { \
7217+ AuDbg("sleep %d sec\n", sec); \
7218+ ssleep(sec); \
7219+} while (0)
7220+
7221+#define AuDbgSleepJiffy(jiffy) do { \
7222+ AuDbg("sleep %d jiffies\n", jiffy); \
7223+ au_dbg_sleep_jiffy(jiffy); \
7224+} while (0)
7225+
7226+#define AuDbgIAttr(ia) do { \
7227+ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
7228+ au_dbg_iattr(ia); \
7229+} while (0)
4a4d8108
AM
7230+
7231+#define AuDbgSym(addr) do { \
7232+ char sym[KSYM_SYMBOL_LEN]; \
7233+ sprint_symbol(sym, (unsigned long)addr); \
7234+ AuDbg("%s\n", sym); \
7235+} while (0)
7236+
7237+#define AuInfoSym(addr) do { \
7238+ char sym[KSYM_SYMBOL_LEN]; \
7239+ sprint_symbol(sym, (unsigned long)addr); \
7240+ AuInfo("%s\n", sym); \
7241+} while (0)
1facf9fc 7242+#else
027c5e7a 7243+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
7244+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
7245+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
7246+ unsigned int sigen)
7247+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
7248+AuStubVoid(au_dbg_verify_kthread, void)
7249+AuStubInt0(__init au_debug_init, void)
7250+AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
1facf9fc 7251+
1facf9fc 7252+#define AuDbgWhlist(w) do {} while (0)
7253+#define AuDbgVdir(v) do {} while (0)
7254+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 7255+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 7256+#define AuDbgDentry(d) do {} while (0)
7257+#define AuDbgFile(f) do {} while (0)
7258+#define AuDbgSb(sb) do {} while (0)
7259+#define AuDbgSleep(sec) do {} while (0)
7260+#define AuDbgSleepJiffy(jiffy) do {} while (0)
7261+#define AuDbgIAttr(ia) do {} while (0)
4a4d8108
AM
7262+#define AuDbgSym(addr) do {} while (0)
7263+#define AuInfoSym(addr) do {} while (0)
1facf9fc 7264+#endif /* CONFIG_AUFS_DEBUG */
7265+
7266+/* ---------------------------------------------------------------------- */
7267+
7268+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
7269+int __init au_sysrq_init(void);
7270+void au_sysrq_fin(void);
7271+
7272+#ifdef CONFIG_HW_CONSOLE
7273+#define au_dbg_blocked() do { \
7274+ WARN_ON(1); \
0c5527e5 7275+ handle_sysrq('w'); \
1facf9fc 7276+} while (0)
7277+#else
4a4d8108 7278+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7279+#endif
7280+
7281+#else
4a4d8108
AM
7282+AuStubInt0(__init au_sysrq_init, void)
7283+AuStubVoid(au_sysrq_fin, void)
7284+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7285+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
7286+
7287+#endif /* __KERNEL__ */
7288+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
7289diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
7290--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
7291+++ linux/fs/aufs/dentry.c 2014-08-14 10:16:04.515942371 +0200
7292@@ -0,0 +1,1094 @@
1facf9fc 7293+/*
523b37e3 7294+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 7295+ *
7296+ * This program, aufs is free software; you can redistribute it and/or modify
7297+ * it under the terms of the GNU General Public License as published by
7298+ * the Free Software Foundation; either version 2 of the License, or
7299+ * (at your option) any later version.
dece6358
AM
7300+ *
7301+ * This program is distributed in the hope that it will be useful,
7302+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7303+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7304+ * GNU General Public License for more details.
7305+ *
7306+ * You should have received a copy of the GNU General Public License
523b37e3 7307+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7308+ */
7309+
7310+/*
7311+ * lookup and dentry operations
7312+ */
7313+
dece6358 7314+#include <linux/namei.h>
1facf9fc 7315+#include "aufs.h"
7316+
1facf9fc 7317+#define AuLkup_ALLOW_NEG 1
076b876e 7318+#define AuLkup_IGNORE_PERM (1 << 1)
1facf9fc 7319+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
7320+#define au_fset_lkup(flags, name) \
7321+ do { (flags) |= AuLkup_##name; } while (0)
7322+#define au_fclr_lkup(flags, name) \
7323+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 7324+
7325+struct au_do_lookup_args {
7326+ unsigned int flags;
7327+ mode_t type;
1facf9fc 7328+};
7329+
7330+/*
7331+ * returns positive/negative dentry, NULL or an error.
7332+ * NULL means whiteout-ed or not-found.
7333+ */
7334+static struct dentry*
7335+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
7336+ aufs_bindex_t bindex, struct qstr *wh_name,
7337+ struct au_do_lookup_args *args)
7338+{
7339+ struct dentry *h_dentry;
7340+ struct inode *h_inode, *inode;
1facf9fc 7341+ struct au_branch *br;
7342+ int wh_found, opq;
7343+ unsigned char wh_able;
7344+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
7345+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
7346+ IGNORE_PERM);
1facf9fc 7347+
1facf9fc 7348+ wh_found = 0;
7349+ br = au_sbr(dentry->d_sb, bindex);
7350+ wh_able = !!au_br_whable(br->br_perm);
7351+ if (wh_able)
076b876e 7352+ wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0);
1facf9fc 7353+ h_dentry = ERR_PTR(wh_found);
7354+ if (!wh_found)
7355+ goto real_lookup;
7356+ if (unlikely(wh_found < 0))
7357+ goto out;
7358+
7359+ /* We found a whiteout */
7360+ /* au_set_dbend(dentry, bindex); */
7361+ au_set_dbwh(dentry, bindex);
7362+ if (!allow_neg)
7363+ return NULL; /* success */
7364+
4f0767ce 7365+real_lookup:
076b876e
AM
7366+ if (!ignore_perm)
7367+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
7368+ else
7369+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 7370+ if (IS_ERR(h_dentry))
7371+ goto out;
7372+
7373+ h_inode = h_dentry->d_inode;
7374+ if (!h_inode) {
7375+ if (!allow_neg)
7376+ goto out_neg;
7377+ } else if (wh_found
7378+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
7379+ goto out_neg;
7380+
7381+ if (au_dbend(dentry) <= bindex)
7382+ au_set_dbend(dentry, bindex);
7383+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7384+ au_set_dbstart(dentry, bindex);
7385+ au_set_h_dptr(dentry, bindex, h_dentry);
7386+
7387+ inode = dentry->d_inode;
7388+ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
7389+ || (inode && !S_ISDIR(inode->i_mode)))
7390+ goto out; /* success */
7391+
7392+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
076b876e 7393+ opq = au_diropq_test(h_dentry);
1facf9fc 7394+ mutex_unlock(&h_inode->i_mutex);
7395+ if (opq > 0)
7396+ au_set_dbdiropq(dentry, bindex);
7397+ else if (unlikely(opq < 0)) {
7398+ au_set_h_dptr(dentry, bindex, NULL);
7399+ h_dentry = ERR_PTR(opq);
7400+ }
7401+ goto out;
7402+
4f0767ce 7403+out_neg:
1facf9fc 7404+ dput(h_dentry);
7405+ h_dentry = NULL;
4f0767ce 7406+out:
1facf9fc 7407+ return h_dentry;
7408+}
7409+
dece6358
AM
7410+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
7411+{
7412+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
7413+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
7414+ return -EPERM;
7415+ return 0;
7416+}
7417+
1facf9fc 7418+/*
7419+ * returns the number of lower positive dentries,
7420+ * otherwise an error.
7421+ * can be called at unlinking with @type is zero.
7422+ */
537831f9 7423+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 7424+{
7425+ int npositive, err;
7426+ aufs_bindex_t bindex, btail, bdiropq;
076b876e 7427+ unsigned char isdir, dirperm1;
1facf9fc 7428+ struct qstr whname;
7429+ struct au_do_lookup_args args = {
b4510431 7430+ .flags = 0,
537831f9 7431+ .type = type
1facf9fc 7432+ };
7433+ const struct qstr *name = &dentry->d_name;
7434+ struct dentry *parent;
7435+ struct inode *inode;
076b876e 7436+ struct super_block *sb;
1facf9fc 7437+
076b876e
AM
7438+ sb = dentry->d_sb;
7439+ err = au_test_shwh(sb, name);
dece6358 7440+ if (unlikely(err))
1facf9fc 7441+ goto out;
7442+
7443+ err = au_wh_name_alloc(&whname, name);
7444+ if (unlikely(err))
7445+ goto out;
7446+
7447+ inode = dentry->d_inode;
7448+ isdir = !!(inode && S_ISDIR(inode->i_mode));
7449+ if (!type)
7450+ au_fset_lkup(args.flags, ALLOW_NEG);
076b876e 7451+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
1facf9fc 7452+
7453+ npositive = 0;
4a4d8108 7454+ parent = dget_parent(dentry);
1facf9fc 7455+ btail = au_dbtaildir(parent);
7456+ for (bindex = bstart; bindex <= btail; bindex++) {
7457+ struct dentry *h_parent, *h_dentry;
7458+ struct inode *h_inode, *h_dir;
7459+
7460+ h_dentry = au_h_dptr(dentry, bindex);
7461+ if (h_dentry) {
7462+ if (h_dentry->d_inode)
7463+ npositive++;
7464+ if (type != S_IFDIR)
7465+ break;
7466+ continue;
7467+ }
7468+ h_parent = au_h_dptr(parent, bindex);
7469+ if (!h_parent)
7470+ continue;
7471+ h_dir = h_parent->d_inode;
7472+ if (!h_dir || !S_ISDIR(h_dir->i_mode))
7473+ continue;
7474+
7475+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
7476+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
7477+ &args);
7478+ mutex_unlock(&h_dir->i_mutex);
7479+ err = PTR_ERR(h_dentry);
7480+ if (IS_ERR(h_dentry))
4a4d8108 7481+ goto out_parent;
1facf9fc 7482+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
7483+ if (dirperm1)
7484+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 7485+
7486+ if (au_dbwh(dentry) >= 0)
7487+ break;
7488+ if (!h_dentry)
7489+ continue;
7490+ h_inode = h_dentry->d_inode;
7491+ if (!h_inode)
7492+ continue;
7493+ npositive++;
7494+ if (!args.type)
7495+ args.type = h_inode->i_mode & S_IFMT;
7496+ if (args.type != S_IFDIR)
7497+ break;
7498+ else if (isdir) {
7499+ /* the type of lower may be different */
7500+ bdiropq = au_dbdiropq(dentry);
7501+ if (bdiropq >= 0 && bdiropq <= bindex)
7502+ break;
7503+ }
7504+ }
7505+
7506+ if (npositive) {
7507+ AuLabel(positive);
7508+ au_update_dbstart(dentry);
7509+ }
7510+ err = npositive;
076b876e 7511+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
027c5e7a 7512+ && au_dbstart(dentry) < 0)) {
1facf9fc 7513+ err = -EIO;
523b37e3
AM
7514+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
7515+ dentry, err);
027c5e7a 7516+ }
1facf9fc 7517+
4f0767ce 7518+out_parent:
4a4d8108 7519+ dput(parent);
1facf9fc 7520+ kfree(whname.name);
4f0767ce 7521+out:
1facf9fc 7522+ return err;
7523+}
7524+
076b876e 7525+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 7526+{
7527+ struct dentry *dentry;
7528+ int wkq_err;
7529+
7530+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
b4510431 7531+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 7532+ else {
b4510431
AM
7533+ struct vfsub_lkup_one_args args = {
7534+ .errp = &dentry,
7535+ .name = name,
7536+ .parent = parent
1facf9fc 7537+ };
7538+
b4510431 7539+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 7540+ if (unlikely(wkq_err))
7541+ dentry = ERR_PTR(wkq_err);
7542+ }
7543+
7544+ return dentry;
7545+}
7546+
7547+/*
7548+ * lookup @dentry on @bindex which should be negative.
7549+ */
86dc4139 7550+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 7551+{
7552+ int err;
7553+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 7554+ struct au_branch *br;
1facf9fc 7555+
1facf9fc 7556+ parent = dget_parent(dentry);
7557+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
7558+ br = au_sbr(dentry->d_sb, bindex);
7559+ if (wh)
7560+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
7561+ else
076b876e 7562+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 7563+ err = PTR_ERR(h_dentry);
7564+ if (IS_ERR(h_dentry))
7565+ goto out;
7566+ if (unlikely(h_dentry->d_inode)) {
7567+ err = -EIO;
523b37e3 7568+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 7569+ dput(h_dentry);
7570+ goto out;
7571+ }
7572+
4a4d8108 7573+ err = 0;
1facf9fc 7574+ if (bindex < au_dbstart(dentry))
7575+ au_set_dbstart(dentry, bindex);
7576+ if (au_dbend(dentry) < bindex)
7577+ au_set_dbend(dentry, bindex);
7578+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 7579+
4f0767ce 7580+out:
1facf9fc 7581+ dput(parent);
7582+ return err;
7583+}
7584+
7585+/* ---------------------------------------------------------------------- */
7586+
7587+/* subset of struct inode */
7588+struct au_iattr {
7589+ unsigned long i_ino;
7590+ /* unsigned int i_nlink; */
0c3ec466
AM
7591+ kuid_t i_uid;
7592+ kgid_t i_gid;
1facf9fc 7593+ u64 i_version;
7594+/*
7595+ loff_t i_size;
7596+ blkcnt_t i_blocks;
7597+*/
7598+ umode_t i_mode;
7599+};
7600+
7601+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
7602+{
7603+ ia->i_ino = h_inode->i_ino;
7604+ /* ia->i_nlink = h_inode->i_nlink; */
7605+ ia->i_uid = h_inode->i_uid;
7606+ ia->i_gid = h_inode->i_gid;
7607+ ia->i_version = h_inode->i_version;
7608+/*
7609+ ia->i_size = h_inode->i_size;
7610+ ia->i_blocks = h_inode->i_blocks;
7611+*/
7612+ ia->i_mode = (h_inode->i_mode & S_IFMT);
7613+}
7614+
7615+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
7616+{
7617+ return ia->i_ino != h_inode->i_ino
7618+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 7619+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 7620+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 7621+ || ia->i_version != h_inode->i_version
7622+/*
7623+ || ia->i_size != h_inode->i_size
7624+ || ia->i_blocks != h_inode->i_blocks
7625+*/
7626+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
7627+}
7628+
7629+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
7630+ struct au_branch *br)
7631+{
7632+ int err;
7633+ struct au_iattr ia;
7634+ struct inode *h_inode;
7635+ struct dentry *h_d;
7636+ struct super_block *h_sb;
7637+
7638+ err = 0;
7639+ memset(&ia, -1, sizeof(ia));
7640+ h_sb = h_dentry->d_sb;
7641+ h_inode = h_dentry->d_inode;
7642+ if (h_inode)
7643+ au_iattr_save(&ia, h_inode);
7644+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
7645+ /* nfs d_revalidate may return 0 for negative dentry */
7646+ /* fuse d_revalidate always return 0 for negative dentry */
7647+ goto out;
7648+
7649+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 7650+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 7651+ err = PTR_ERR(h_d);
7652+ if (IS_ERR(h_d))
7653+ goto out;
7654+
7655+ err = 0;
7656+ if (unlikely(h_d != h_dentry
7657+ || h_d->d_inode != h_inode
7658+ || (h_inode && au_iattr_test(&ia, h_inode))))
7659+ err = au_busy_or_stale();
7660+ dput(h_d);
7661+
4f0767ce 7662+out:
1facf9fc 7663+ AuTraceErr(err);
7664+ return err;
7665+}
7666+
7667+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7668+ struct dentry *h_parent, struct au_branch *br)
7669+{
7670+ int err;
7671+
7672+ err = 0;
027c5e7a
AM
7673+ if (udba == AuOpt_UDBA_REVAL
7674+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 7675+ IMustLock(h_dir);
7676+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 7677+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 7678+ err = au_h_verify_dentry(h_dentry, h_parent, br);
7679+
7680+ return err;
7681+}
7682+
7683+/* ---------------------------------------------------------------------- */
7684+
027c5e7a 7685+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 7686+{
027c5e7a 7687+ int err;
1facf9fc 7688+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
7689+ struct au_hdentry tmp, *p, *q;
7690+ struct au_dinfo *dinfo;
7691+ struct super_block *sb;
1facf9fc 7692+
027c5e7a 7693+ DiMustWriteLock(dentry);
1308ab2a 7694+
027c5e7a
AM
7695+ sb = dentry->d_sb;
7696+ dinfo = au_di(dentry);
1facf9fc 7697+ bend = dinfo->di_bend;
7698+ bwh = dinfo->di_bwh;
7699+ bdiropq = dinfo->di_bdiropq;
027c5e7a 7700+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 7701+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 7702+ if (!p->hd_dentry)
1facf9fc 7703+ continue;
7704+
027c5e7a
AM
7705+ new_bindex = au_br_index(sb, p->hd_id);
7706+ if (new_bindex == bindex)
1facf9fc 7707+ continue;
1facf9fc 7708+
1facf9fc 7709+ if (dinfo->di_bwh == bindex)
7710+ bwh = new_bindex;
7711+ if (dinfo->di_bdiropq == bindex)
7712+ bdiropq = new_bindex;
7713+ if (new_bindex < 0) {
7714+ au_hdput(p);
7715+ p->hd_dentry = NULL;
7716+ continue;
7717+ }
7718+
7719+ /* swap two lower dentries, and loop again */
7720+ q = dinfo->di_hdentry + new_bindex;
7721+ tmp = *q;
7722+ *q = *p;
7723+ *p = tmp;
7724+ if (tmp.hd_dentry) {
7725+ bindex--;
7726+ p--;
7727+ }
7728+ }
7729+
1facf9fc 7730+ dinfo->di_bwh = -1;
7731+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
7732+ dinfo->di_bwh = bwh;
7733+
7734+ dinfo->di_bdiropq = -1;
7735+ if (bdiropq >= 0
7736+ && bdiropq <= au_sbend(sb)
7737+ && au_sbr_whable(sb, bdiropq))
7738+ dinfo->di_bdiropq = bdiropq;
7739+
027c5e7a
AM
7740+ err = -EIO;
7741+ dinfo->di_bstart = -1;
7742+ dinfo->di_bend = -1;
1facf9fc 7743+ bend = au_dbend(parent);
7744+ p = dinfo->di_hdentry;
7745+ for (bindex = 0; bindex <= bend; bindex++, p++)
7746+ if (p->hd_dentry) {
7747+ dinfo->di_bstart = bindex;
7748+ break;
7749+ }
7750+
027c5e7a
AM
7751+ if (dinfo->di_bstart >= 0) {
7752+ p = dinfo->di_hdentry + bend;
7753+ for (bindex = bend; bindex >= 0; bindex--, p--)
7754+ if (p->hd_dentry) {
7755+ dinfo->di_bend = bindex;
7756+ err = 0;
7757+ break;
7758+ }
7759+ }
7760+
7761+ return err;
1facf9fc 7762+}
7763+
027c5e7a 7764+static void au_do_hide(struct dentry *dentry)
1facf9fc 7765+{
027c5e7a 7766+ struct inode *inode;
1facf9fc 7767+
027c5e7a
AM
7768+ inode = dentry->d_inode;
7769+ if (inode) {
7770+ if (!S_ISDIR(inode->i_mode)) {
7771+ if (inode->i_nlink && !d_unhashed(dentry))
7772+ drop_nlink(inode);
7773+ } else {
7774+ clear_nlink(inode);
7775+ /* stop next lookup */
7776+ inode->i_flags |= S_DEAD;
7777+ }
7778+ smp_mb(); /* necessary? */
7779+ }
7780+ d_drop(dentry);
7781+}
1308ab2a 7782+
027c5e7a
AM
7783+static int au_hide_children(struct dentry *parent)
7784+{
7785+ int err, i, j, ndentry;
7786+ struct au_dcsub_pages dpages;
7787+ struct au_dpage *dpage;
7788+ struct dentry *dentry;
1facf9fc 7789+
027c5e7a 7790+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 7791+ if (unlikely(err))
7792+ goto out;
027c5e7a
AM
7793+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
7794+ if (unlikely(err))
7795+ goto out_dpages;
1facf9fc 7796+
027c5e7a
AM
7797+ /* in reverse order */
7798+ for (i = dpages.ndpage - 1; i >= 0; i--) {
7799+ dpage = dpages.dpages + i;
7800+ ndentry = dpage->ndentry;
7801+ for (j = ndentry - 1; j >= 0; j--) {
7802+ dentry = dpage->dentries[j];
7803+ if (dentry != parent)
7804+ au_do_hide(dentry);
7805+ }
7806+ }
1facf9fc 7807+
027c5e7a
AM
7808+out_dpages:
7809+ au_dpages_free(&dpages);
4f0767ce 7810+out:
027c5e7a 7811+ return err;
1facf9fc 7812+}
7813+
027c5e7a 7814+static void au_hide(struct dentry *dentry)
1facf9fc 7815+{
027c5e7a
AM
7816+ int err;
7817+ struct inode *inode;
1facf9fc 7818+
027c5e7a
AM
7819+ AuDbgDentry(dentry);
7820+ inode = dentry->d_inode;
7821+ if (inode && S_ISDIR(inode->i_mode)) {
7822+ /* shrink_dcache_parent(dentry); */
7823+ err = au_hide_children(dentry);
7824+ if (unlikely(err))
523b37e3
AM
7825+ AuIOErr("%pd, failed hiding children, ignored %d\n",
7826+ dentry, err);
027c5e7a
AM
7827+ }
7828+ au_do_hide(dentry);
7829+}
1facf9fc 7830+
027c5e7a
AM
7831+/*
7832+ * By adding a dirty branch, a cached dentry may be affected in various ways.
7833+ *
7834+ * a dirty branch is added
7835+ * - on the top of layers
7836+ * - in the middle of layers
7837+ * - to the bottom of layers
7838+ *
7839+ * on the added branch there exists
7840+ * - a whiteout
7841+ * - a diropq
7842+ * - a same named entry
7843+ * + exist
7844+ * * negative --> positive
7845+ * * positive --> positive
7846+ * - type is unchanged
7847+ * - type is changed
7848+ * + doesn't exist
7849+ * * negative --> negative
7850+ * * positive --> negative (rejected by au_br_del() for non-dir case)
7851+ * - none
7852+ */
7853+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
7854+ struct au_dinfo *tmp)
7855+{
7856+ int err;
7857+ aufs_bindex_t bindex, bend;
7858+ struct {
7859+ struct dentry *dentry;
7860+ struct inode *inode;
7861+ mode_t mode;
7862+ } orig_h, tmp_h;
7863+ struct au_hdentry *hd;
7864+ struct inode *inode, *h_inode;
7865+ struct dentry *h_dentry;
7866+
7867+ err = 0;
7868+ AuDebugOn(dinfo->di_bstart < 0);
7869+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
7870+ orig_h.inode = orig_h.dentry->d_inode;
7871+ orig_h.mode = 0;
7872+ if (orig_h.inode)
7873+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
7874+ memset(&tmp_h, 0, sizeof(tmp_h));
7875+ if (tmp->di_bstart >= 0) {
7876+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
7877+ tmp_h.inode = tmp_h.dentry->d_inode;
7878+ if (tmp_h.inode)
7879+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
7880+ }
7881+
7882+ inode = dentry->d_inode;
7883+ if (!orig_h.inode) {
7884+ AuDbg("nagative originally\n");
7885+ if (inode) {
7886+ au_hide(dentry);
7887+ goto out;
7888+ }
7889+ AuDebugOn(inode);
7890+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7891+ AuDebugOn(dinfo->di_bdiropq != -1);
7892+
7893+ if (!tmp_h.inode) {
7894+ AuDbg("negative --> negative\n");
7895+ /* should have only one negative lower */
7896+ if (tmp->di_bstart >= 0
7897+ && tmp->di_bstart < dinfo->di_bstart) {
7898+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
7899+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
7900+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
7901+ au_di_cp(dinfo, tmp);
7902+ hd = tmp->di_hdentry + tmp->di_bstart;
7903+ au_set_h_dptr(dentry, tmp->di_bstart,
7904+ dget(hd->hd_dentry));
7905+ }
7906+ au_dbg_verify_dinode(dentry);
7907+ } else {
7908+ AuDbg("negative --> positive\n");
7909+ /*
7910+ * similar to the behaviour of creating with bypassing
7911+ * aufs.
7912+ * unhash it in order to force an error in the
7913+ * succeeding create operation.
7914+ * we should not set S_DEAD here.
7915+ */
7916+ d_drop(dentry);
7917+ /* au_di_swap(tmp, dinfo); */
7918+ au_dbg_verify_dinode(dentry);
7919+ }
7920+ } else {
7921+ AuDbg("positive originally\n");
7922+ /* inode may be NULL */
7923+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
7924+ if (!tmp_h.inode) {
7925+ AuDbg("positive --> negative\n");
7926+ /* or bypassing aufs */
7927+ au_hide(dentry);
7928+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
7929+ dinfo->di_bwh = tmp->di_bwh;
7930+ if (inode)
7931+ err = au_refresh_hinode_self(inode);
7932+ au_dbg_verify_dinode(dentry);
7933+ } else if (orig_h.mode == tmp_h.mode) {
7934+ AuDbg("positive --> positive, same type\n");
7935+ if (!S_ISDIR(orig_h.mode)
7936+ && dinfo->di_bstart > tmp->di_bstart) {
7937+ /*
7938+ * similar to the behaviour of removing and
7939+ * creating.
7940+ */
7941+ au_hide(dentry);
7942+ if (inode)
7943+ err = au_refresh_hinode_self(inode);
7944+ au_dbg_verify_dinode(dentry);
7945+ } else {
7946+ /* fill empty slots */
7947+ if (dinfo->di_bstart > tmp->di_bstart)
7948+ dinfo->di_bstart = tmp->di_bstart;
7949+ if (dinfo->di_bend < tmp->di_bend)
7950+ dinfo->di_bend = tmp->di_bend;
7951+ dinfo->di_bwh = tmp->di_bwh;
7952+ dinfo->di_bdiropq = tmp->di_bdiropq;
7953+ hd = tmp->di_hdentry;
7954+ bend = dinfo->di_bend;
7955+ for (bindex = tmp->di_bstart; bindex <= bend;
7956+ bindex++) {
7957+ if (au_h_dptr(dentry, bindex))
7958+ continue;
7959+ h_dentry = hd[bindex].hd_dentry;
7960+ if (!h_dentry)
7961+ continue;
7962+ h_inode = h_dentry->d_inode;
7963+ AuDebugOn(!h_inode);
7964+ AuDebugOn(orig_h.mode
7965+ != (h_inode->i_mode
7966+ & S_IFMT));
7967+ au_set_h_dptr(dentry, bindex,
7968+ dget(h_dentry));
7969+ }
7970+ err = au_refresh_hinode(inode, dentry);
7971+ au_dbg_verify_dinode(dentry);
7972+ }
7973+ } else {
7974+ AuDbg("positive --> positive, different type\n");
7975+ /* similar to the behaviour of removing and creating */
7976+ au_hide(dentry);
7977+ if (inode)
7978+ err = au_refresh_hinode_self(inode);
7979+ au_dbg_verify_dinode(dentry);
7980+ }
7981+ }
7982+
7983+out:
7984+ return err;
7985+}
7986+
7987+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
7988+{
7989+ int err, ebrange;
7990+ unsigned int sigen;
7991+ struct au_dinfo *dinfo, *tmp;
7992+ struct super_block *sb;
7993+ struct inode *inode;
7994+
7995+ DiMustWriteLock(dentry);
7996+ AuDebugOn(IS_ROOT(dentry));
7997+ AuDebugOn(!parent->d_inode);
7998+
7999+ sb = dentry->d_sb;
8000+ inode = dentry->d_inode;
8001+ sigen = au_sigen(sb);
8002+ err = au_digen_test(parent, sigen);
8003+ if (unlikely(err))
8004+ goto out;
8005+
8006+ dinfo = au_di(dentry);
8007+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
8008+ if (unlikely(err))
8009+ goto out;
8010+ ebrange = au_dbrange_test(dentry);
8011+ if (!ebrange)
8012+ ebrange = au_do_refresh_hdentry(dentry, parent);
8013+
38d290e6 8014+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
027c5e7a
AM
8015+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
8016+ if (inode)
8017+ err = au_refresh_hinode_self(inode);
8018+ au_dbg_verify_dinode(dentry);
8019+ if (!err)
8020+ goto out_dgen; /* success */
8021+ goto out;
8022+ }
8023+
8024+ /* temporary dinfo */
8025+ AuDbgDentry(dentry);
8026+ err = -ENOMEM;
8027+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8028+ if (unlikely(!tmp))
8029+ goto out;
8030+ au_di_swap(tmp, dinfo);
8031+ /* returns the number of positive dentries */
8032+ /*
8033+ * if current working dir is removed, it returns an error.
8034+ * but the dentry is legal.
8035+ */
537831f9 8036+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
8037+ AuDbgDentry(dentry);
8038+ au_di_swap(tmp, dinfo);
8039+ if (err == -ENOENT)
8040+ err = 0;
8041+ if (err >= 0) {
8042+ /* compare/refresh by dinfo */
8043+ AuDbgDentry(dentry);
8044+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8045+ au_dbg_verify_dinode(dentry);
8046+ AuTraceErr(err);
8047+ }
8048+ au_rw_write_unlock(&tmp->di_rwsem);
8049+ au_di_free(tmp);
8050+ if (unlikely(err))
8051+ goto out;
8052+
8053+out_dgen:
8054+ au_update_digen(dentry);
8055+out:
8056+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8057+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8058+ AuDbgDentry(dentry);
8059+ }
8060+ AuTraceErr(err);
8061+ return err;
8062+}
8063+
b4510431
AM
8064+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8065+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8066+{
8067+ int err, valid;
027c5e7a
AM
8068+
8069+ err = 0;
8070+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8071+ goto out;
027c5e7a
AM
8072+
8073+ AuDbg("b%d\n", bindex);
b4510431
AM
8074+ /*
8075+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8076+ * due to whiteout and branch permission.
8077+ */
8078+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8079+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8080+ /* it may return tri-state */
8081+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8082+
8083+ if (unlikely(valid < 0))
8084+ err = valid;
8085+ else if (!valid)
8086+ err = -EINVAL;
8087+
4f0767ce 8088+out:
1facf9fc 8089+ AuTraceErr(err);
8090+ return err;
8091+}
8092+
8093+/* todo: remove this */
8094+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 8095+ unsigned int flags, int do_udba)
1facf9fc 8096+{
8097+ int err;
8098+ umode_t mode, h_mode;
8099+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
38d290e6 8100+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 8101+ struct inode *h_inode, *h_cached_inode;
1facf9fc 8102+ struct dentry *h_dentry;
8103+ struct qstr *name, *h_name;
8104+
8105+ err = 0;
8106+ plus = 0;
8107+ mode = 0;
1facf9fc 8108+ ibs = -1;
8109+ ibe = -1;
8110+ unhashed = !!d_unhashed(dentry);
8111+ is_root = !!IS_ROOT(dentry);
8112+ name = &dentry->d_name;
38d290e6 8113+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 8114+
8115+ /*
7f207e10
AM
8116+ * Theoretically, REVAL test should be unnecessary in case of
8117+ * {FS,I}NOTIFY.
8118+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 8119+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 8120+ * Let's do REVAL test too.
8121+ */
8122+ if (do_udba && inode) {
8123+ mode = (inode->i_mode & S_IFMT);
8124+ plus = (inode->i_nlink > 0);
1facf9fc 8125+ ibs = au_ibstart(inode);
8126+ ibe = au_ibend(inode);
8127+ }
8128+
8129+ bstart = au_dbstart(dentry);
8130+ btail = bstart;
8131+ if (inode && S_ISDIR(inode->i_mode))
8132+ btail = au_dbtaildir(dentry);
8133+ for (bindex = bstart; bindex <= btail; bindex++) {
8134+ h_dentry = au_h_dptr(dentry, bindex);
8135+ if (!h_dentry)
8136+ continue;
8137+
523b37e3
AM
8138+ AuDbg("b%d, %pd\n", bindex, h_dentry);
8139+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 8140+ spin_lock(&h_dentry->d_lock);
1facf9fc 8141+ h_name = &h_dentry->d_name;
8142+ if (unlikely(do_udba
8143+ && !is_root
523b37e3
AM
8144+ && ((!h_nfs
8145+ && (unhashed != !!d_unhashed(h_dentry)
38d290e6
JR
8146+ || (!tmpfile
8147+ && !au_qstreq(name, h_name))
8148+ ))
523b37e3
AM
8149+ || (h_nfs
8150+ && !(flags & LOOKUP_OPEN)
8151+ && (h_dentry->d_flags
8152+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 8153+ )) {
38d290e6
JR
8154+ int h_unhashed;
8155+
8156+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 8157+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
8158+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
8159+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 8160+ goto err;
8161+ }
027c5e7a 8162+ spin_unlock(&h_dentry->d_lock);
1facf9fc 8163+
b4510431 8164+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 8165+ if (unlikely(err))
8166+ /* do not goto err, to keep the errno */
8167+ break;
8168+
8169+ /* todo: plink too? */
8170+ if (!do_udba)
8171+ continue;
8172+
8173+ /* UDBA tests */
8174+ h_inode = h_dentry->d_inode;
8175+ if (unlikely(!!inode != !!h_inode))
8176+ goto err;
8177+
8178+ h_plus = plus;
8179+ h_mode = mode;
8180+ h_cached_inode = h_inode;
8181+ if (h_inode) {
8182+ h_mode = (h_inode->i_mode & S_IFMT);
8183+ h_plus = (h_inode->i_nlink > 0);
8184+ }
8185+ if (inode && ibs <= bindex && bindex <= ibe)
8186+ h_cached_inode = au_h_iptr(inode, bindex);
8187+
523b37e3 8188+ if (!h_nfs) {
38d290e6 8189+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
8190+ goto err;
8191+ } else {
8192+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
8193+ && !is_root
8194+ && !IS_ROOT(h_dentry)
8195+ && unhashed != d_unhashed(h_dentry)))
8196+ goto err;
8197+ }
8198+ if (unlikely(mode != h_mode
1facf9fc 8199+ || h_cached_inode != h_inode))
8200+ goto err;
8201+ continue;
8202+
f6b6e03d 8203+err:
1facf9fc 8204+ err = -EINVAL;
8205+ break;
8206+ }
8207+
523b37e3 8208+ AuTraceErr(err);
1facf9fc 8209+ return err;
8210+}
8211+
027c5e7a 8212+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 8213+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
8214+{
8215+ int err;
8216+ struct dentry *parent;
1facf9fc 8217+
027c5e7a 8218+ if (!au_digen_test(dentry, sigen))
1facf9fc 8219+ return 0;
8220+
8221+ parent = dget_parent(dentry);
8222+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8223+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 8224+ au_dbg_verify_gen(parent, sigen);
027c5e7a 8225+ err = au_refresh_dentry(dentry, parent);
1facf9fc 8226+ di_read_unlock(parent, AuLock_IR);
8227+ dput(parent);
027c5e7a 8228+ AuTraceErr(err);
1facf9fc 8229+ return err;
8230+}
8231+
8232+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
8233+{
8234+ int err;
8235+ struct dentry *d, *parent;
8236+ struct inode *inode;
8237+
027c5e7a 8238+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 8239+ return simple_reval_dpath(dentry, sigen);
8240+
8241+ /* slow loop, keep it simple and stupid */
8242+ /* cf: au_cpup_dirs() */
8243+ err = 0;
8244+ parent = NULL;
027c5e7a 8245+ while (au_digen_test(dentry, sigen)) {
1facf9fc 8246+ d = dentry;
8247+ while (1) {
8248+ dput(parent);
8249+ parent = dget_parent(d);
027c5e7a 8250+ if (!au_digen_test(parent, sigen))
1facf9fc 8251+ break;
8252+ d = parent;
8253+ }
8254+
8255+ inode = d->d_inode;
8256+ if (d != dentry)
027c5e7a 8257+ di_write_lock_child2(d);
1facf9fc 8258+
8259+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
8260+ if (au_digen_test(d, sigen)) {
8261+ /*
8262+ * todo: consolidate with simple_reval_dpath(),
8263+ * do_refresh() and au_reval_for_attr().
8264+ */
1facf9fc 8265+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8266+ err = au_refresh_dentry(d, parent);
1facf9fc 8267+ di_read_unlock(parent, AuLock_IR);
8268+ }
8269+
8270+ if (d != dentry)
8271+ di_write_unlock(d);
8272+ dput(parent);
8273+ if (unlikely(err))
8274+ break;
8275+ }
8276+
8277+ return err;
8278+}
8279+
8280+/*
8281+ * if valid returns 1, otherwise 0.
8282+ */
b4510431 8283+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 8284+{
8285+ int valid, err;
8286+ unsigned int sigen;
8287+ unsigned char do_udba;
8288+ struct super_block *sb;
8289+ struct inode *inode;
8290+
027c5e7a 8291+ /* todo: support rcu-walk? */
b4510431 8292+ if (flags & LOOKUP_RCU)
027c5e7a
AM
8293+ return -ECHILD;
8294+
8295+ valid = 0;
8296+ if (unlikely(!au_di(dentry)))
8297+ goto out;
8298+
8299+ inode = dentry->d_inode;
8300+ if (inode && is_bad_inode(inode))
8301+ goto out;
8302+
e49829fe 8303+ valid = 1;
1facf9fc 8304+ sb = dentry->d_sb;
e49829fe
JR
8305+ /*
8306+ * todo: very ugly
8307+ * i_mutex of parent dir may be held,
8308+ * but we should not return 'invalid' due to busy.
8309+ */
8310+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
8311+ if (unlikely(err)) {
8312+ valid = err;
027c5e7a 8313+ AuTraceErr(err);
e49829fe
JR
8314+ goto out;
8315+ }
027c5e7a
AM
8316+ if (unlikely(au_dbrange_test(dentry))) {
8317+ err = -EINVAL;
8318+ AuTraceErr(err);
8319+ goto out_dgrade;
1facf9fc 8320+ }
027c5e7a
AM
8321+
8322+ sigen = au_sigen(sb);
8323+ if (au_digen_test(dentry, sigen)) {
1facf9fc 8324+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
8325+ err = au_reval_dpath(dentry, sigen);
8326+ if (unlikely(err)) {
8327+ AuTraceErr(err);
1facf9fc 8328+ goto out_dgrade;
027c5e7a 8329+ }
1facf9fc 8330+ }
8331+ di_downgrade_lock(dentry, AuLock_IR);
8332+
1facf9fc 8333+ err = -EINVAL;
523b37e3
AM
8334+ if (!(flags & LOOKUP_OPEN)
8335+ && inode
38d290e6 8336+ && !(inode->i_state && I_LINKABLE)
523b37e3 8337+ && (IS_DEADDIR(inode) || !inode->i_nlink))
027c5e7a
AM
8338+ goto out_inval;
8339+
1facf9fc 8340+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
8341+ if (do_udba && inode) {
8342+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 8343+ struct inode *h_inode;
1facf9fc 8344+
027c5e7a
AM
8345+ if (bstart >= 0) {
8346+ h_inode = au_h_iptr(inode, bstart);
8347+ if (h_inode && au_test_higen(inode, h_inode))
8348+ goto out_inval;
8349+ }
1facf9fc 8350+ }
8351+
b4510431 8352+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 8353+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 8354+ err = -EIO;
523b37e3
AM
8355+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
8356+ dentry, err);
027c5e7a 8357+ }
e49829fe 8358+ goto out_inval;
1facf9fc 8359+
4f0767ce 8360+out_dgrade:
1facf9fc 8361+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 8362+out_inval:
1facf9fc 8363+ aufs_read_unlock(dentry, AuLock_IR);
8364+ AuTraceErr(err);
8365+ valid = !err;
e49829fe 8366+out:
027c5e7a 8367+ if (!valid) {
523b37e3 8368+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
8369+ d_drop(dentry);
8370+ }
1facf9fc 8371+ return valid;
8372+}
8373+
8374+static void aufs_d_release(struct dentry *dentry)
8375+{
027c5e7a 8376+ if (au_di(dentry)) {
4a4d8108
AM
8377+ au_di_fin(dentry);
8378+ au_hn_di_reinit(dentry);
1facf9fc 8379+ }
1facf9fc 8380+}
8381+
4a4d8108 8382+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
8383+ .d_revalidate = aufs_d_revalidate,
8384+ .d_weak_revalidate = aufs_d_revalidate,
8385+ .d_release = aufs_d_release
1facf9fc 8386+};
7f207e10
AM
8387diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
8388--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
8389+++ linux/fs/aufs/dentry.h 2014-08-14 10:15:45.121942630 +0200
8390@@ -0,0 +1,233 @@
1facf9fc 8391+/*
523b37e3 8392+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 8393+ *
8394+ * This program, aufs is free software; you can redistribute it and/or modify
8395+ * it under the terms of the GNU General Public License as published by
8396+ * the Free Software Foundation; either version 2 of the License, or
8397+ * (at your option) any later version.
dece6358
AM
8398+ *
8399+ * This program is distributed in the hope that it will be useful,
8400+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8401+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8402+ * GNU General Public License for more details.
8403+ *
8404+ * You should have received a copy of the GNU General Public License
523b37e3 8405+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8406+ */
8407+
8408+/*
8409+ * lookup and dentry operations
8410+ */
8411+
8412+#ifndef __AUFS_DENTRY_H__
8413+#define __AUFS_DENTRY_H__
8414+
8415+#ifdef __KERNEL__
8416+
dece6358 8417+#include <linux/dcache.h>
1facf9fc 8418+#include "rwsem.h"
8419+
1facf9fc 8420+struct au_hdentry {
8421+ struct dentry *hd_dentry;
027c5e7a 8422+ aufs_bindex_t hd_id;
1facf9fc 8423+};
8424+
8425+struct au_dinfo {
8426+ atomic_t di_generation;
8427+
dece6358 8428+ struct au_rwsem di_rwsem;
1facf9fc 8429+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
38d290e6 8430+ unsigned char di_tmpfile; /* to allow the different name */
1facf9fc 8431+ struct au_hdentry *di_hdentry;
4a4d8108 8432+} ____cacheline_aligned_in_smp;
1facf9fc 8433+
8434+/* ---------------------------------------------------------------------- */
8435+
8436+/* dentry.c */
4a4d8108 8437+extern const struct dentry_operations aufs_dop;
1facf9fc 8438+struct au_branch;
076b876e 8439+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 8440+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8441+ struct dentry *h_parent, struct au_branch *br);
8442+
537831f9 8443+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 8444+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 8445+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 8446+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
8447+
8448+/* dinfo.c */
4a4d8108 8449+void au_di_init_once(void *_di);
027c5e7a
AM
8450+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
8451+void au_di_free(struct au_dinfo *dinfo);
8452+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
8453+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
8454+int au_di_init(struct dentry *dentry);
8455+void au_di_fin(struct dentry *dentry);
1facf9fc 8456+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
8457+
8458+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
8459+void di_read_unlock(struct dentry *d, int flags);
8460+void di_downgrade_lock(struct dentry *d, int flags);
8461+void di_write_lock(struct dentry *d, unsigned int lsc);
8462+void di_write_unlock(struct dentry *d);
8463+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
8464+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
8465+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
8466+
8467+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 8468+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 8469+aufs_bindex_t au_dbtail(struct dentry *dentry);
8470+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
8471+
8472+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8473+ struct dentry *h_dentry);
027c5e7a
AM
8474+int au_digen_test(struct dentry *dentry, unsigned int sigen);
8475+int au_dbrange_test(struct dentry *dentry);
1facf9fc 8476+void au_update_digen(struct dentry *dentry);
8477+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
8478+void au_update_dbstart(struct dentry *dentry);
8479+void au_update_dbend(struct dentry *dentry);
8480+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
8481+
8482+/* ---------------------------------------------------------------------- */
8483+
8484+static inline struct au_dinfo *au_di(struct dentry *dentry)
8485+{
8486+ return dentry->d_fsdata;
8487+}
8488+
8489+/* ---------------------------------------------------------------------- */
8490+
8491+/* lock subclass for dinfo */
8492+enum {
8493+ AuLsc_DI_CHILD, /* child first */
4a4d8108 8494+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 8495+ AuLsc_DI_CHILD3, /* copyup dirs */
8496+ AuLsc_DI_PARENT,
8497+ AuLsc_DI_PARENT2,
027c5e7a
AM
8498+ AuLsc_DI_PARENT3,
8499+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 8500+};
8501+
8502+/*
8503+ * di_read_lock_child, di_write_lock_child,
8504+ * di_read_lock_child2, di_write_lock_child2,
8505+ * di_read_lock_child3, di_write_lock_child3,
8506+ * di_read_lock_parent, di_write_lock_parent,
8507+ * di_read_lock_parent2, di_write_lock_parent2,
8508+ * di_read_lock_parent3, di_write_lock_parent3,
8509+ */
8510+#define AuReadLockFunc(name, lsc) \
8511+static inline void di_read_lock_##name(struct dentry *d, int flags) \
8512+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
8513+
8514+#define AuWriteLockFunc(name, lsc) \
8515+static inline void di_write_lock_##name(struct dentry *d) \
8516+{ di_write_lock(d, AuLsc_DI_##lsc); }
8517+
8518+#define AuRWLockFuncs(name, lsc) \
8519+ AuReadLockFunc(name, lsc) \
8520+ AuWriteLockFunc(name, lsc)
8521+
8522+AuRWLockFuncs(child, CHILD);
8523+AuRWLockFuncs(child2, CHILD2);
8524+AuRWLockFuncs(child3, CHILD3);
8525+AuRWLockFuncs(parent, PARENT);
8526+AuRWLockFuncs(parent2, PARENT2);
8527+AuRWLockFuncs(parent3, PARENT3);
8528+
8529+#undef AuReadLockFunc
8530+#undef AuWriteLockFunc
8531+#undef AuRWLockFuncs
8532+
8533+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
8534+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
8535+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 8536+
8537+/* ---------------------------------------------------------------------- */
8538+
8539+/* todo: memory barrier? */
8540+static inline unsigned int au_digen(struct dentry *d)
8541+{
8542+ return atomic_read(&au_di(d)->di_generation);
8543+}
8544+
8545+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
8546+{
8547+ hdentry->hd_dentry = NULL;
8548+}
8549+
8550+static inline void au_hdput(struct au_hdentry *hd)
8551+{
4a4d8108
AM
8552+ if (hd)
8553+ dput(hd->hd_dentry);
1facf9fc 8554+}
8555+
8556+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
8557+{
1308ab2a 8558+ DiMustAnyLock(dentry);
1facf9fc 8559+ return au_di(dentry)->di_bstart;
8560+}
8561+
8562+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
8563+{
1308ab2a 8564+ DiMustAnyLock(dentry);
1facf9fc 8565+ return au_di(dentry)->di_bend;
8566+}
8567+
8568+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
8569+{
1308ab2a 8570+ DiMustAnyLock(dentry);
1facf9fc 8571+ return au_di(dentry)->di_bwh;
8572+}
8573+
8574+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
8575+{
1308ab2a 8576+ DiMustAnyLock(dentry);
1facf9fc 8577+ return au_di(dentry)->di_bdiropq;
8578+}
8579+
8580+/* todo: hard/soft set? */
8581+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
8582+{
1308ab2a 8583+ DiMustWriteLock(dentry);
1facf9fc 8584+ au_di(dentry)->di_bstart = bindex;
8585+}
8586+
8587+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
8588+{
1308ab2a 8589+ DiMustWriteLock(dentry);
1facf9fc 8590+ au_di(dentry)->di_bend = bindex;
8591+}
8592+
8593+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
8594+{
1308ab2a 8595+ DiMustWriteLock(dentry);
1facf9fc 8596+ /* dbwh can be outside of bstart - bend range */
8597+ au_di(dentry)->di_bwh = bindex;
8598+}
8599+
8600+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
8601+{
1308ab2a 8602+ DiMustWriteLock(dentry);
1facf9fc 8603+ au_di(dentry)->di_bdiropq = bindex;
8604+}
8605+
8606+/* ---------------------------------------------------------------------- */
8607+
4a4d8108 8608+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 8609+static inline void au_digen_dec(struct dentry *d)
8610+{
e49829fe 8611+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 8612+}
8613+
4a4d8108 8614+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 8615+{
8616+ dentry->d_fsdata = NULL;
8617+}
8618+#else
4a4d8108
AM
8619+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
8620+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 8621+
8622+#endif /* __KERNEL__ */
8623+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
8624diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
8625--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
076b876e 8626+++ linux/fs/aufs/dinfo.c 2014-08-14 10:15:45.121942630 +0200
38d290e6 8627@@ -0,0 +1,544 @@
1facf9fc 8628+/*
523b37e3 8629+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 8630+ *
8631+ * This program, aufs is free software; you can redistribute it and/or modify
8632+ * it under the terms of the GNU General Public License as published by
8633+ * the Free Software Foundation; either version 2 of the License, or
8634+ * (at your option) any later version.
dece6358
AM
8635+ *
8636+ * This program is distributed in the hope that it will be useful,
8637+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8638+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8639+ * GNU General Public License for more details.
8640+ *
8641+ * You should have received a copy of the GNU General Public License
523b37e3 8642+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8643+ */
8644+
8645+/*
8646+ * dentry private data
8647+ */
8648+
8649+#include "aufs.h"
8650+
e49829fe 8651+void au_di_init_once(void *_dinfo)
4a4d8108 8652+{
e49829fe
JR
8653+ struct au_dinfo *dinfo = _dinfo;
8654+ static struct lock_class_key aufs_di;
4a4d8108 8655+
e49829fe
JR
8656+ au_rw_init(&dinfo->di_rwsem);
8657+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
8658+}
8659+
027c5e7a 8660+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 8661+{
8662+ struct au_dinfo *dinfo;
027c5e7a 8663+ int nbr, i;
1facf9fc 8664+
8665+ dinfo = au_cache_alloc_dinfo();
8666+ if (unlikely(!dinfo))
8667+ goto out;
8668+
1facf9fc 8669+ nbr = au_sbend(sb) + 1;
8670+ if (nbr <= 0)
8671+ nbr = 1;
8672+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
8673+ if (dinfo->di_hdentry) {
8674+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
8675+ dinfo->di_bstart = -1;
8676+ dinfo->di_bend = -1;
8677+ dinfo->di_bwh = -1;
8678+ dinfo->di_bdiropq = -1;
38d290e6 8679+ dinfo->di_tmpfile = 0;
027c5e7a
AM
8680+ for (i = 0; i < nbr; i++)
8681+ dinfo->di_hdentry[i].hd_id = -1;
8682+ goto out;
8683+ }
1facf9fc 8684+
1facf9fc 8685+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
8686+ dinfo = NULL;
8687+
4f0767ce 8688+out:
027c5e7a 8689+ return dinfo;
1facf9fc 8690+}
8691+
027c5e7a 8692+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 8693+{
4a4d8108
AM
8694+ struct au_hdentry *p;
8695+ aufs_bindex_t bend, bindex;
8696+
8697+ /* dentry may not be revalidated */
027c5e7a 8698+ bindex = dinfo->di_bstart;
4a4d8108 8699+ if (bindex >= 0) {
027c5e7a
AM
8700+ bend = dinfo->di_bend;
8701+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
8702+ while (bindex++ <= bend)
8703+ au_hdput(p++);
8704+ }
027c5e7a
AM
8705+ kfree(dinfo->di_hdentry);
8706+ au_cache_free_dinfo(dinfo);
8707+}
8708+
8709+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
8710+{
8711+ struct au_hdentry *p;
8712+ aufs_bindex_t bi;
8713+
8714+ AuRwMustWriteLock(&a->di_rwsem);
8715+ AuRwMustWriteLock(&b->di_rwsem);
8716+
8717+#define DiSwap(v, name) \
8718+ do { \
8719+ v = a->di_##name; \
8720+ a->di_##name = b->di_##name; \
8721+ b->di_##name = v; \
8722+ } while (0)
8723+
8724+ DiSwap(p, hdentry);
8725+ DiSwap(bi, bstart);
8726+ DiSwap(bi, bend);
8727+ DiSwap(bi, bwh);
8728+ DiSwap(bi, bdiropq);
8729+ /* smp_mb(); */
8730+
8731+#undef DiSwap
8732+}
8733+
8734+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
8735+{
8736+ AuRwMustWriteLock(&dst->di_rwsem);
8737+ AuRwMustWriteLock(&src->di_rwsem);
8738+
8739+ dst->di_bstart = src->di_bstart;
8740+ dst->di_bend = src->di_bend;
8741+ dst->di_bwh = src->di_bwh;
8742+ dst->di_bdiropq = src->di_bdiropq;
8743+ /* smp_mb(); */
8744+}
8745+
8746+int au_di_init(struct dentry *dentry)
8747+{
8748+ int err;
8749+ struct super_block *sb;
8750+ struct au_dinfo *dinfo;
8751+
8752+ err = 0;
8753+ sb = dentry->d_sb;
8754+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
8755+ if (dinfo) {
8756+ atomic_set(&dinfo->di_generation, au_sigen(sb));
8757+ /* smp_mb(); */ /* atomic_set */
8758+ dentry->d_fsdata = dinfo;
8759+ } else
8760+ err = -ENOMEM;
8761+
8762+ return err;
8763+}
8764+
8765+void au_di_fin(struct dentry *dentry)
8766+{
8767+ struct au_dinfo *dinfo;
8768+
8769+ dinfo = au_di(dentry);
8770+ AuRwDestroy(&dinfo->di_rwsem);
8771+ au_di_free(dinfo);
4a4d8108
AM
8772+}
8773+
1facf9fc 8774+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
8775+{
8776+ int err, sz;
8777+ struct au_hdentry *hdp;
8778+
1308ab2a 8779+ AuRwMustWriteLock(&dinfo->di_rwsem);
8780+
1facf9fc 8781+ err = -ENOMEM;
8782+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
8783+ if (!sz)
8784+ sz = sizeof(*hdp);
8785+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
8786+ if (hdp) {
8787+ dinfo->di_hdentry = hdp;
8788+ err = 0;
8789+ }
8790+
8791+ return err;
8792+}
8793+
8794+/* ---------------------------------------------------------------------- */
8795+
8796+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
8797+{
8798+ switch (lsc) {
8799+ case AuLsc_DI_CHILD:
8800+ ii_write_lock_child(inode);
8801+ break;
8802+ case AuLsc_DI_CHILD2:
8803+ ii_write_lock_child2(inode);
8804+ break;
8805+ case AuLsc_DI_CHILD3:
8806+ ii_write_lock_child3(inode);
8807+ break;
8808+ case AuLsc_DI_PARENT:
8809+ ii_write_lock_parent(inode);
8810+ break;
8811+ case AuLsc_DI_PARENT2:
8812+ ii_write_lock_parent2(inode);
8813+ break;
8814+ case AuLsc_DI_PARENT3:
8815+ ii_write_lock_parent3(inode);
8816+ break;
8817+ default:
8818+ BUG();
8819+ }
8820+}
8821+
8822+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
8823+{
8824+ switch (lsc) {
8825+ case AuLsc_DI_CHILD:
8826+ ii_read_lock_child(inode);
8827+ break;
8828+ case AuLsc_DI_CHILD2:
8829+ ii_read_lock_child2(inode);
8830+ break;
8831+ case AuLsc_DI_CHILD3:
8832+ ii_read_lock_child3(inode);
8833+ break;
8834+ case AuLsc_DI_PARENT:
8835+ ii_read_lock_parent(inode);
8836+ break;
8837+ case AuLsc_DI_PARENT2:
8838+ ii_read_lock_parent2(inode);
8839+ break;
8840+ case AuLsc_DI_PARENT3:
8841+ ii_read_lock_parent3(inode);
8842+ break;
8843+ default:
8844+ BUG();
8845+ }
8846+}
8847+
8848+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
8849+{
dece6358 8850+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8851+ if (d->d_inode) {
8852+ if (au_ftest_lock(flags, IW))
8853+ do_ii_write_lock(d->d_inode, lsc);
8854+ else if (au_ftest_lock(flags, IR))
8855+ do_ii_read_lock(d->d_inode, lsc);
8856+ }
8857+}
8858+
8859+void di_read_unlock(struct dentry *d, int flags)
8860+{
8861+ if (d->d_inode) {
027c5e7a
AM
8862+ if (au_ftest_lock(flags, IW)) {
8863+ au_dbg_verify_dinode(d);
1facf9fc 8864+ ii_write_unlock(d->d_inode);
027c5e7a
AM
8865+ } else if (au_ftest_lock(flags, IR)) {
8866+ au_dbg_verify_dinode(d);
1facf9fc 8867+ ii_read_unlock(d->d_inode);
027c5e7a 8868+ }
1facf9fc 8869+ }
dece6358 8870+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 8871+}
8872+
8873+void di_downgrade_lock(struct dentry *d, int flags)
8874+{
1facf9fc 8875+ if (d->d_inode && au_ftest_lock(flags, IR))
8876+ ii_downgrade_lock(d->d_inode);
dece6358 8877+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 8878+}
8879+
8880+void di_write_lock(struct dentry *d, unsigned int lsc)
8881+{
dece6358 8882+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8883+ if (d->d_inode)
8884+ do_ii_write_lock(d->d_inode, lsc);
8885+}
8886+
8887+void di_write_unlock(struct dentry *d)
8888+{
027c5e7a 8889+ au_dbg_verify_dinode(d);
1facf9fc 8890+ if (d->d_inode)
8891+ ii_write_unlock(d->d_inode);
dece6358 8892+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 8893+}
8894+
8895+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
8896+{
8897+ AuDebugOn(d1 == d2
8898+ || d1->d_inode == d2->d_inode
8899+ || d1->d_sb != d2->d_sb);
8900+
8901+ if (isdir && au_test_subdir(d1, d2)) {
8902+ di_write_lock_child(d1);
8903+ di_write_lock_child2(d2);
8904+ } else {
8905+ /* there should be no races */
8906+ di_write_lock_child(d2);
8907+ di_write_lock_child2(d1);
8908+ }
8909+}
8910+
8911+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
8912+{
8913+ AuDebugOn(d1 == d2
8914+ || d1->d_inode == d2->d_inode
8915+ || d1->d_sb != d2->d_sb);
8916+
8917+ if (isdir && au_test_subdir(d1, d2)) {
8918+ di_write_lock_parent(d1);
8919+ di_write_lock_parent2(d2);
8920+ } else {
8921+ /* there should be no races */
8922+ di_write_lock_parent(d2);
8923+ di_write_lock_parent2(d1);
8924+ }
8925+}
8926+
8927+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
8928+{
8929+ di_write_unlock(d1);
8930+ if (d1->d_inode == d2->d_inode)
dece6358 8931+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 8932+ else
8933+ di_write_unlock(d2);
8934+}
8935+
8936+/* ---------------------------------------------------------------------- */
8937+
8938+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
8939+{
8940+ struct dentry *d;
8941+
1308ab2a 8942+ DiMustAnyLock(dentry);
8943+
1facf9fc 8944+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
8945+ return NULL;
8946+ AuDebugOn(bindex < 0);
8947+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
392086de 8948+ AuDebugOn(d && d_count(d) <= 0);
1facf9fc 8949+ return d;
8950+}
8951+
2cbb1c4b
JR
8952+/*
8953+ * extended version of au_h_dptr().
38d290e6
JR
8954+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
8955+ * error.
2cbb1c4b
JR
8956+ */
8957+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
8958+{
8959+ struct dentry *h_dentry;
8960+ struct inode *inode, *h_inode;
8961+
8962+ inode = dentry->d_inode;
8963+ AuDebugOn(!inode);
8964+
8965+ h_dentry = NULL;
8966+ if (au_dbstart(dentry) <= bindex
8967+ && bindex <= au_dbend(dentry))
8968+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 8969+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
8970+ dget(h_dentry);
8971+ goto out; /* success */
8972+ }
8973+
8974+ AuDebugOn(bindex < au_ibstart(inode));
8975+ AuDebugOn(au_ibend(inode) < bindex);
8976+ h_inode = au_h_iptr(inode, bindex);
8977+ h_dentry = d_find_alias(h_inode);
8978+ if (h_dentry) {
8979+ if (!IS_ERR(h_dentry)) {
38d290e6 8980+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
8981+ goto out; /* success */
8982+ dput(h_dentry);
8983+ } else
8984+ goto out;
8985+ }
8986+
8987+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
8988+ h_dentry = au_plink_lkup(inode, bindex);
8989+ AuDebugOn(!h_dentry);
8990+ if (!IS_ERR(h_dentry)) {
8991+ if (!au_d_hashed_positive(h_dentry))
8992+ goto out; /* success */
8993+ dput(h_dentry);
8994+ h_dentry = NULL;
8995+ }
8996+ }
8997+
8998+out:
8999+ AuDbgDentry(h_dentry);
9000+ return h_dentry;
9001+}
9002+
1facf9fc 9003+aufs_bindex_t au_dbtail(struct dentry *dentry)
9004+{
9005+ aufs_bindex_t bend, bwh;
9006+
9007+ bend = au_dbend(dentry);
9008+ if (0 <= bend) {
9009+ bwh = au_dbwh(dentry);
9010+ if (!bwh)
9011+ return bwh;
9012+ if (0 < bwh && bwh < bend)
9013+ return bwh - 1;
9014+ }
9015+ return bend;
9016+}
9017+
9018+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9019+{
9020+ aufs_bindex_t bend, bopq;
9021+
9022+ bend = au_dbtail(dentry);
9023+ if (0 <= bend) {
9024+ bopq = au_dbdiropq(dentry);
9025+ if (0 <= bopq && bopq < bend)
9026+ bend = bopq;
9027+ }
9028+ return bend;
9029+}
9030+
9031+/* ---------------------------------------------------------------------- */
9032+
9033+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9034+ struct dentry *h_dentry)
9035+{
9036+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 9037+ struct au_branch *br;
1facf9fc 9038+
1308ab2a 9039+ DiMustWriteLock(dentry);
9040+
4a4d8108 9041+ au_hdput(hd);
1facf9fc 9042+ hd->hd_dentry = h_dentry;
027c5e7a
AM
9043+ if (h_dentry) {
9044+ br = au_sbr(dentry->d_sb, bindex);
9045+ hd->hd_id = br->br_id;
9046+ }
9047+}
9048+
9049+int au_dbrange_test(struct dentry *dentry)
9050+{
9051+ int err;
9052+ aufs_bindex_t bstart, bend;
9053+
9054+ err = 0;
9055+ bstart = au_dbstart(dentry);
9056+ bend = au_dbend(dentry);
9057+ if (bstart >= 0)
9058+ AuDebugOn(bend < 0 && bstart > bend);
9059+ else {
9060+ err = -EIO;
9061+ AuDebugOn(bend >= 0);
9062+ }
9063+
9064+ return err;
9065+}
9066+
9067+int au_digen_test(struct dentry *dentry, unsigned int sigen)
9068+{
9069+ int err;
9070+
9071+ err = 0;
9072+ if (unlikely(au_digen(dentry) != sigen
9073+ || au_iigen_test(dentry->d_inode, sigen)))
9074+ err = -EIO;
9075+
9076+ return err;
1facf9fc 9077+}
9078+
9079+void au_update_digen(struct dentry *dentry)
9080+{
9081+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
9082+ /* smp_mb(); */ /* atomic_set */
9083+}
9084+
9085+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
9086+{
9087+ struct au_dinfo *dinfo;
9088+ struct dentry *h_d;
4a4d8108 9089+ struct au_hdentry *hdp;
1facf9fc 9090+
1308ab2a 9091+ DiMustWriteLock(dentry);
9092+
1facf9fc 9093+ dinfo = au_di(dentry);
9094+ if (!dinfo || dinfo->di_bstart < 0)
9095+ return;
9096+
4a4d8108 9097+ hdp = dinfo->di_hdentry;
1facf9fc 9098+ if (do_put_zero) {
9099+ aufs_bindex_t bindex, bend;
9100+
9101+ bend = dinfo->di_bend;
9102+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 9103+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 9104+ if (h_d && !h_d->d_inode)
9105+ au_set_h_dptr(dentry, bindex, NULL);
9106+ }
9107+ }
9108+
9109+ dinfo->di_bstart = -1;
9110+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 9111+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 9112+ break;
9113+ if (dinfo->di_bstart > dinfo->di_bend) {
9114+ dinfo->di_bstart = -1;
9115+ dinfo->di_bend = -1;
9116+ return;
9117+ }
9118+
9119+ dinfo->di_bend++;
9120+ while (0 <= --dinfo->di_bend)
4a4d8108 9121+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 9122+ break;
9123+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
9124+}
9125+
9126+void au_update_dbstart(struct dentry *dentry)
9127+{
9128+ aufs_bindex_t bindex, bend;
9129+ struct dentry *h_dentry;
9130+
9131+ bend = au_dbend(dentry);
9132+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
9133+ h_dentry = au_h_dptr(dentry, bindex);
9134+ if (!h_dentry)
9135+ continue;
9136+ if (h_dentry->d_inode) {
9137+ au_set_dbstart(dentry, bindex);
9138+ return;
9139+ }
9140+ au_set_h_dptr(dentry, bindex, NULL);
9141+ }
9142+}
9143+
9144+void au_update_dbend(struct dentry *dentry)
9145+{
9146+ aufs_bindex_t bindex, bstart;
9147+ struct dentry *h_dentry;
9148+
9149+ bstart = au_dbstart(dentry);
7f207e10 9150+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 9151+ h_dentry = au_h_dptr(dentry, bindex);
9152+ if (!h_dentry)
9153+ continue;
9154+ if (h_dentry->d_inode) {
9155+ au_set_dbend(dentry, bindex);
9156+ return;
9157+ }
9158+ au_set_h_dptr(dentry, bindex, NULL);
9159+ }
9160+}
9161+
9162+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
9163+{
9164+ aufs_bindex_t bindex, bend;
9165+
9166+ bend = au_dbend(dentry);
9167+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
9168+ if (au_h_dptr(dentry, bindex) == h_dentry)
9169+ return bindex;
9170+ return -1;
9171+}
7f207e10
AM
9172diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
9173--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
9174+++ linux/fs/aufs/dir.c 2014-08-14 10:15:45.121942630 +0200
9175@@ -0,0 +1,645 @@
1facf9fc 9176+/*
523b37e3 9177+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 9178+ *
9179+ * This program, aufs is free software; you can redistribute it and/or modify
9180+ * it under the terms of the GNU General Public License as published by
9181+ * the Free Software Foundation; either version 2 of the License, or
9182+ * (at your option) any later version.
dece6358
AM
9183+ *
9184+ * This program is distributed in the hope that it will be useful,
9185+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9186+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9187+ * GNU General Public License for more details.
9188+ *
9189+ * You should have received a copy of the GNU General Public License
523b37e3 9190+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9191+ */
9192+
9193+/*
9194+ * directory operations
9195+ */
9196+
9197+#include <linux/fs_stack.h>
9198+#include "aufs.h"
9199+
9200+void au_add_nlink(struct inode *dir, struct inode *h_dir)
9201+{
9dbd164d
AM
9202+ unsigned int nlink;
9203+
1facf9fc 9204+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9205+
9dbd164d
AM
9206+ nlink = dir->i_nlink;
9207+ nlink += h_dir->i_nlink - 2;
1facf9fc 9208+ if (h_dir->i_nlink < 2)
9dbd164d 9209+ nlink += 2;
f6b6e03d 9210+ smp_mb(); /* for i_nlink */
7eafdf33 9211+ /* 0 can happen in revaliding */
92d182d2 9212+ set_nlink(dir, nlink);
1facf9fc 9213+}
9214+
9215+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
9216+{
9dbd164d
AM
9217+ unsigned int nlink;
9218+
1facf9fc 9219+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9220+
9dbd164d
AM
9221+ nlink = dir->i_nlink;
9222+ nlink -= h_dir->i_nlink - 2;
1facf9fc 9223+ if (h_dir->i_nlink < 2)
9dbd164d 9224+ nlink -= 2;
f6b6e03d 9225+ smp_mb(); /* for i_nlink */
92d182d2 9226+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 9227+ set_nlink(dir, nlink);
1facf9fc 9228+}
9229+
1308ab2a 9230+loff_t au_dir_size(struct file *file, struct dentry *dentry)
9231+{
9232+ loff_t sz;
9233+ aufs_bindex_t bindex, bend;
9234+ struct file *h_file;
9235+ struct dentry *h_dentry;
9236+
9237+ sz = 0;
9238+ if (file) {
c06a8ce3
AM
9239+ AuDebugOn(!file_inode(file));
9240+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
1308ab2a 9241+
4a4d8108 9242+ bend = au_fbend_dir(file);
1308ab2a 9243+ for (bindex = au_fbstart(file);
9244+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9245+ bindex++) {
4a4d8108 9246+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
9247+ if (h_file && file_inode(h_file))
9248+ sz += vfsub_f_size_read(h_file);
1308ab2a 9249+ }
9250+ } else {
9251+ AuDebugOn(!dentry);
9252+ AuDebugOn(!dentry->d_inode);
9253+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
9254+
9255+ bend = au_dbtaildir(dentry);
9256+ for (bindex = au_dbstart(dentry);
9257+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9258+ bindex++) {
9259+ h_dentry = au_h_dptr(dentry, bindex);
9260+ if (h_dentry && h_dentry->d_inode)
9261+ sz += i_size_read(h_dentry->d_inode);
9262+ }
9263+ }
9264+ if (sz < KMALLOC_MAX_SIZE)
9265+ sz = roundup_pow_of_two(sz);
9266+ if (sz > KMALLOC_MAX_SIZE)
9267+ sz = KMALLOC_MAX_SIZE;
9268+ else if (sz < NAME_MAX) {
9269+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
9270+ sz = AUFS_RDBLK_DEF;
9271+ }
9272+ return sz;
9273+}
9274+
1facf9fc 9275+/* ---------------------------------------------------------------------- */
9276+
9277+static int reopen_dir(struct file *file)
9278+{
9279+ int err;
9280+ unsigned int flags;
9281+ aufs_bindex_t bindex, btail, bstart;
9282+ struct dentry *dentry, *h_dentry;
9283+ struct file *h_file;
9284+
9285+ /* open all lower dirs */
9286+ dentry = file->f_dentry;
9287+ bstart = au_dbstart(dentry);
9288+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
9289+ au_set_h_fptr(file, bindex, NULL);
9290+ au_set_fbstart(file, bstart);
9291+
9292+ btail = au_dbtaildir(dentry);
4a4d8108 9293+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 9294+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 9295+ au_set_fbend_dir(file, btail);
1facf9fc 9296+
4a4d8108 9297+ flags = vfsub_file_flags(file);
1facf9fc 9298+ for (bindex = bstart; bindex <= btail; bindex++) {
9299+ h_dentry = au_h_dptr(dentry, bindex);
9300+ if (!h_dentry)
9301+ continue;
4a4d8108 9302+ h_file = au_hf_dir(file, bindex);
1facf9fc 9303+ if (h_file)
9304+ continue;
9305+
392086de 9306+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9307+ err = PTR_ERR(h_file);
9308+ if (IS_ERR(h_file))
9309+ goto out; /* close all? */
9310+ au_set_h_fptr(file, bindex, h_file);
9311+ }
9312+ au_update_figen(file);
9313+ /* todo: necessary? */
9314+ /* file->f_ra = h_file->f_ra; */
9315+ err = 0;
9316+
4f0767ce 9317+out:
1facf9fc 9318+ return err;
9319+}
9320+
9321+static int do_open_dir(struct file *file, int flags)
9322+{
9323+ int err;
9324+ aufs_bindex_t bindex, btail;
9325+ struct dentry *dentry, *h_dentry;
9326+ struct file *h_file;
9327+
1308ab2a 9328+ FiMustWriteLock(file);
9329+
523b37e3 9330+ err = 0;
1facf9fc 9331+ dentry = file->f_dentry;
1facf9fc 9332+ file->f_version = dentry->d_inode->i_version;
9333+ bindex = au_dbstart(dentry);
9334+ au_set_fbstart(file, bindex);
9335+ btail = au_dbtaildir(dentry);
4a4d8108 9336+ au_set_fbend_dir(file, btail);
1facf9fc 9337+ for (; !err && bindex <= btail; bindex++) {
9338+ h_dentry = au_h_dptr(dentry, bindex);
9339+ if (!h_dentry)
9340+ continue;
9341+
392086de 9342+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9343+ if (IS_ERR(h_file)) {
9344+ err = PTR_ERR(h_file);
9345+ break;
9346+ }
9347+ au_set_h_fptr(file, bindex, h_file);
9348+ }
9349+ au_update_figen(file);
9350+ /* todo: necessary? */
9351+ /* file->f_ra = h_file->f_ra; */
9352+ if (!err)
9353+ return 0; /* success */
9354+
9355+ /* close all */
9356+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
9357+ au_set_h_fptr(file, bindex, NULL);
9358+ au_set_fbstart(file, -1);
4a4d8108
AM
9359+ au_set_fbend_dir(file, -1);
9360+
1facf9fc 9361+ return err;
9362+}
9363+
9364+static int aufs_open_dir(struct inode *inode __maybe_unused,
9365+ struct file *file)
9366+{
4a4d8108
AM
9367+ int err;
9368+ struct super_block *sb;
9369+ struct au_fidir *fidir;
9370+
9371+ err = -ENOMEM;
9372+ sb = file->f_dentry->d_sb;
9373+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 9374+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
9375+ if (fidir) {
9376+ err = au_do_open(file, do_open_dir, fidir);
9377+ if (unlikely(err))
9378+ kfree(fidir);
9379+ }
9380+ si_read_unlock(sb);
9381+ return err;
1facf9fc 9382+}
9383+
9384+static int aufs_release_dir(struct inode *inode __maybe_unused,
9385+ struct file *file)
9386+{
9387+ struct au_vdir *vdir_cache;
4a4d8108
AM
9388+ struct au_finfo *finfo;
9389+ struct au_fidir *fidir;
9390+ aufs_bindex_t bindex, bend;
1facf9fc 9391+
4a4d8108
AM
9392+ finfo = au_fi(file);
9393+ fidir = finfo->fi_hdir;
9394+ if (fidir) {
076b876e
AM
9395+ au_sphl_del(&finfo->fi_hlist,
9396+ &au_sbi(file->f_dentry->d_sb)->si_files);
4a4d8108
AM
9397+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
9398+ if (vdir_cache)
9399+ au_vdir_free(vdir_cache);
9400+
9401+ bindex = finfo->fi_btop;
9402+ if (bindex >= 0) {
9403+ /*
9404+ * calls fput() instead of filp_close(),
9405+ * since no dnotify or lock for the lower file.
9406+ */
9407+ bend = fidir->fd_bbot;
9408+ for (; bindex <= bend; bindex++)
9409+ au_set_h_fptr(file, bindex, NULL);
9410+ }
9411+ kfree(fidir);
9412+ finfo->fi_hdir = NULL;
1facf9fc 9413+ }
1facf9fc 9414+ au_finfo_fin(file);
1facf9fc 9415+ return 0;
9416+}
9417+
9418+/* ---------------------------------------------------------------------- */
9419+
4a4d8108
AM
9420+static int au_do_flush_dir(struct file *file, fl_owner_t id)
9421+{
9422+ int err;
9423+ aufs_bindex_t bindex, bend;
9424+ struct file *h_file;
9425+
9426+ err = 0;
9427+ bend = au_fbend_dir(file);
9428+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
9429+ h_file = au_hf_dir(file, bindex);
9430+ if (h_file)
9431+ err = vfsub_flush(h_file, id);
9432+ }
9433+ return err;
9434+}
9435+
9436+static int aufs_flush_dir(struct file *file, fl_owner_t id)
9437+{
9438+ return au_do_flush(file, id, au_do_flush_dir);
9439+}
9440+
9441+/* ---------------------------------------------------------------------- */
9442+
1facf9fc 9443+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
9444+{
9445+ int err;
9446+ aufs_bindex_t bend, bindex;
9447+ struct inode *inode;
9448+ struct super_block *sb;
9449+
9450+ err = 0;
9451+ sb = dentry->d_sb;
9452+ inode = dentry->d_inode;
9453+ IMustLock(inode);
9454+ bend = au_dbend(dentry);
9455+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
9456+ struct path h_path;
1facf9fc 9457+
9458+ if (au_test_ro(sb, bindex, inode))
9459+ continue;
9460+ h_path.dentry = au_h_dptr(dentry, bindex);
9461+ if (!h_path.dentry)
9462+ continue;
1facf9fc 9463+
1facf9fc 9464+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 9465+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 9466+ }
9467+
9468+ return err;
9469+}
9470+
9471+static int au_do_fsync_dir(struct file *file, int datasync)
9472+{
9473+ int err;
9474+ aufs_bindex_t bend, bindex;
9475+ struct file *h_file;
9476+ struct super_block *sb;
9477+ struct inode *inode;
1facf9fc 9478+
9479+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9480+ if (unlikely(err))
9481+ goto out;
9482+
9483+ sb = file->f_dentry->d_sb;
c06a8ce3 9484+ inode = file_inode(file);
4a4d8108 9485+ bend = au_fbend_dir(file);
1facf9fc 9486+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 9487+ h_file = au_hf_dir(file, bindex);
1facf9fc 9488+ if (!h_file || au_test_ro(sb, bindex, inode))
9489+ continue;
9490+
53392da6 9491+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 9492+ }
9493+
4f0767ce 9494+out:
1facf9fc 9495+ return err;
9496+}
9497+
9498+/*
9499+ * @file may be NULL
9500+ */
1e00d052
AM
9501+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
9502+ int datasync)
1facf9fc 9503+{
9504+ int err;
b752ccd1 9505+ struct dentry *dentry;
1facf9fc 9506+ struct super_block *sb;
1e00d052 9507+ struct mutex *mtx;
1facf9fc 9508+
9509+ err = 0;
1e00d052
AM
9510+ dentry = file->f_dentry;
9511+ mtx = &dentry->d_inode->i_mutex;
9512+ mutex_lock(mtx);
1facf9fc 9513+ sb = dentry->d_sb;
9514+ si_noflush_read_lock(sb);
9515+ if (file)
9516+ err = au_do_fsync_dir(file, datasync);
9517+ else {
9518+ di_write_lock_child(dentry);
9519+ err = au_do_fsync_dir_no_file(dentry, datasync);
9520+ }
9521+ au_cpup_attr_timesizes(dentry->d_inode);
9522+ di_write_unlock(dentry);
9523+ if (file)
9524+ fi_write_unlock(file);
9525+
9526+ si_read_unlock(sb);
1e00d052 9527+ mutex_unlock(mtx);
1facf9fc 9528+ return err;
9529+}
9530+
9531+/* ---------------------------------------------------------------------- */
9532+
392086de 9533+static int aufs_iterate(struct file *file, struct dir_context *ctx)
1facf9fc 9534+{
9535+ int err;
9536+ struct dentry *dentry;
9dbd164d 9537+ struct inode *inode, *h_inode;
1facf9fc 9538+ struct super_block *sb;
9539+
523b37e3 9540+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 9541+
1facf9fc 9542+ dentry = file->f_dentry;
9543+ inode = dentry->d_inode;
9544+ IMustLock(inode);
9545+
9546+ sb = dentry->d_sb;
9547+ si_read_lock(sb, AuLock_FLUSH);
9548+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9549+ if (unlikely(err))
9550+ goto out;
027c5e7a
AM
9551+ err = au_alive_dir(dentry);
9552+ if (!err)
9553+ err = au_vdir_init(file);
1facf9fc 9554+ di_downgrade_lock(dentry, AuLock_IR);
9555+ if (unlikely(err))
9556+ goto out_unlock;
9557+
9dbd164d 9558+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 9559+ if (!au_test_nfsd()) {
392086de 9560+ err = au_vdir_fill_de(file, ctx);
9dbd164d 9561+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 9562+ } else {
9563+ /*
9564+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
9565+ * encode_fh() and others.
9566+ */
9dbd164d 9567+ atomic_inc(&h_inode->i_count);
1facf9fc 9568+ di_read_unlock(dentry, AuLock_IR);
9569+ si_read_unlock(sb);
392086de 9570+ err = au_vdir_fill_de(file, ctx);
1facf9fc 9571+ fsstack_copy_attr_atime(inode, h_inode);
9572+ fi_write_unlock(file);
9dbd164d 9573+ iput(h_inode);
1facf9fc 9574+
9575+ AuTraceErr(err);
9576+ return err;
9577+ }
9578+
4f0767ce 9579+out_unlock:
1facf9fc 9580+ di_read_unlock(dentry, AuLock_IR);
9581+ fi_write_unlock(file);
4f0767ce 9582+out:
1facf9fc 9583+ si_read_unlock(sb);
9584+ return err;
9585+}
9586+
9587+/* ---------------------------------------------------------------------- */
9588+
9589+#define AuTestEmpty_WHONLY 1
dece6358
AM
9590+#define AuTestEmpty_CALLED (1 << 1)
9591+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 9592+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
9593+#define au_fset_testempty(flags, name) \
9594+ do { (flags) |= AuTestEmpty_##name; } while (0)
9595+#define au_fclr_testempty(flags, name) \
9596+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 9597+
dece6358
AM
9598+#ifndef CONFIG_AUFS_SHWH
9599+#undef AuTestEmpty_SHWH
9600+#define AuTestEmpty_SHWH 0
9601+#endif
9602+
1facf9fc 9603+struct test_empty_arg {
392086de 9604+ struct dir_context ctx;
1308ab2a 9605+ struct au_nhash *whlist;
1facf9fc 9606+ unsigned int flags;
9607+ int err;
9608+ aufs_bindex_t bindex;
9609+};
9610+
392086de
AM
9611+static int test_empty_cb(struct dir_context *ctx, const char *__name,
9612+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 9613+ unsigned int d_type)
1facf9fc 9614+{
392086de
AM
9615+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
9616+ ctx);
1facf9fc 9617+ char *name = (void *)__name;
9618+
9619+ arg->err = 0;
9620+ au_fset_testempty(arg->flags, CALLED);
9621+ /* smp_mb(); */
9622+ if (name[0] == '.'
9623+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
9624+ goto out; /* success */
9625+
9626+ if (namelen <= AUFS_WH_PFX_LEN
9627+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
9628+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 9629+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9630+ arg->err = -ENOTEMPTY;
9631+ goto out;
9632+ }
9633+
9634+ name += AUFS_WH_PFX_LEN;
9635+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 9636+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9637+ arg->err = au_nhash_append_wh
1308ab2a 9638+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 9639+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 9640+
4f0767ce 9641+out:
1facf9fc 9642+ /* smp_mb(); */
9643+ AuTraceErr(arg->err);
9644+ return arg->err;
9645+}
9646+
9647+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9648+{
9649+ int err;
9650+ struct file *h_file;
9651+
9652+ h_file = au_h_open(dentry, arg->bindex,
9653+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 9654+ /*file*/NULL, /*force_wr*/0);
1facf9fc 9655+ err = PTR_ERR(h_file);
9656+ if (IS_ERR(h_file))
9657+ goto out;
9658+
9659+ err = 0;
9660+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 9661+ && !file_inode(h_file)->i_nlink)
1facf9fc 9662+ goto out_put;
9663+
9664+ do {
9665+ arg->err = 0;
9666+ au_fclr_testempty(arg->flags, CALLED);
9667+ /* smp_mb(); */
392086de 9668+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 9669+ if (err >= 0)
9670+ err = arg->err;
9671+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
9672+
4f0767ce 9673+out_put:
1facf9fc 9674+ fput(h_file);
9675+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 9676+out:
1facf9fc 9677+ return err;
9678+}
9679+
9680+struct do_test_empty_args {
9681+ int *errp;
9682+ struct dentry *dentry;
9683+ struct test_empty_arg *arg;
9684+};
9685+
9686+static void call_do_test_empty(void *args)
9687+{
9688+ struct do_test_empty_args *a = args;
9689+ *a->errp = do_test_empty(a->dentry, a->arg);
9690+}
9691+
9692+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9693+{
9694+ int err, wkq_err;
9695+ struct dentry *h_dentry;
9696+ struct inode *h_inode;
9697+
9698+ h_dentry = au_h_dptr(dentry, arg->bindex);
9699+ h_inode = h_dentry->d_inode;
53392da6 9700+ /* todo: i_mode changes anytime? */
1facf9fc 9701+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
9702+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
9703+ mutex_unlock(&h_inode->i_mutex);
9704+ if (!err)
9705+ err = do_test_empty(dentry, arg);
9706+ else {
9707+ struct do_test_empty_args args = {
9708+ .errp = &err,
9709+ .dentry = dentry,
9710+ .arg = arg
9711+ };
9712+ unsigned int flags = arg->flags;
9713+
9714+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
9715+ if (unlikely(wkq_err))
9716+ err = wkq_err;
9717+ arg->flags = flags;
9718+ }
9719+
9720+ return err;
9721+}
9722+
9723+int au_test_empty_lower(struct dentry *dentry)
9724+{
9725+ int err;
1308ab2a 9726+ unsigned int rdhash;
1facf9fc 9727+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 9728+ struct au_nhash whlist;
392086de
AM
9729+ struct test_empty_arg arg = {
9730+ .ctx = {
9731+ .actor = au_diractor(test_empty_cb)
9732+ }
9733+ };
076b876e 9734+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 9735+
dece6358
AM
9736+ SiMustAnyLock(dentry->d_sb);
9737+
1308ab2a 9738+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
9739+ if (!rdhash)
9740+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
9741+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 9742+ if (unlikely(err))
1facf9fc 9743+ goto out;
9744+
1facf9fc 9745+ arg.flags = 0;
1308ab2a 9746+ arg.whlist = &whlist;
9747+ bstart = au_dbstart(dentry);
dece6358
AM
9748+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9749+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
9750+ test_empty = do_test_empty;
9751+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
9752+ test_empty = sio_test_empty;
1facf9fc 9753+ arg.bindex = bstart;
076b876e 9754+ err = test_empty(dentry, &arg);
1facf9fc 9755+ if (unlikely(err))
9756+ goto out_whlist;
9757+
9758+ au_fset_testempty(arg.flags, WHONLY);
9759+ btail = au_dbtaildir(dentry);
9760+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
9761+ struct dentry *h_dentry;
9762+
9763+ h_dentry = au_h_dptr(dentry, bindex);
9764+ if (h_dentry && h_dentry->d_inode) {
9765+ arg.bindex = bindex;
076b876e 9766+ err = test_empty(dentry, &arg);
1facf9fc 9767+ }
9768+ }
9769+
4f0767ce 9770+out_whlist:
1308ab2a 9771+ au_nhash_wh_free(&whlist);
4f0767ce 9772+out:
1facf9fc 9773+ return err;
9774+}
9775+
9776+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
9777+{
9778+ int err;
392086de
AM
9779+ struct test_empty_arg arg = {
9780+ .ctx = {
9781+ .actor = au_diractor(test_empty_cb)
9782+ }
9783+ };
1facf9fc 9784+ aufs_bindex_t bindex, btail;
9785+
9786+ err = 0;
1308ab2a 9787+ arg.whlist = whlist;
1facf9fc 9788+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
9789+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9790+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 9791+ btail = au_dbtaildir(dentry);
9792+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
9793+ struct dentry *h_dentry;
9794+
9795+ h_dentry = au_h_dptr(dentry, bindex);
9796+ if (h_dentry && h_dentry->d_inode) {
9797+ arg.bindex = bindex;
9798+ err = sio_test_empty(dentry, &arg);
9799+ }
9800+ }
9801+
9802+ return err;
9803+}
9804+
9805+/* ---------------------------------------------------------------------- */
9806+
9807+const struct file_operations aufs_dir_fop = {
4a4d8108 9808+ .owner = THIS_MODULE,
027c5e7a 9809+ .llseek = default_llseek,
1facf9fc 9810+ .read = generic_read_dir,
392086de 9811+ .iterate = aufs_iterate,
1facf9fc 9812+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
9813+#ifdef CONFIG_COMPAT
9814+ .compat_ioctl = aufs_compat_ioctl_dir,
9815+#endif
1facf9fc 9816+ .open = aufs_open_dir,
9817+ .release = aufs_release_dir,
4a4d8108 9818+ .flush = aufs_flush_dir,
1facf9fc 9819+ .fsync = aufs_fsync_dir
9820+};
7f207e10
AM
9821diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
9822--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
076b876e 9823+++ linux/fs/aufs/dir.h 2014-01-30 21:10:02.830814411 +0100
523b37e3 9824@@ -0,0 +1,136 @@
1facf9fc 9825+/*
523b37e3 9826+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 9827+ *
9828+ * This program, aufs is free software; you can redistribute it and/or modify
9829+ * it under the terms of the GNU General Public License as published by
9830+ * the Free Software Foundation; either version 2 of the License, or
9831+ * (at your option) any later version.
dece6358
AM
9832+ *
9833+ * This program is distributed in the hope that it will be useful,
9834+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9835+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9836+ * GNU General Public License for more details.
9837+ *
9838+ * You should have received a copy of the GNU General Public License
523b37e3 9839+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9840+ */
9841+
9842+/*
9843+ * directory operations
9844+ */
9845+
9846+#ifndef __AUFS_DIR_H__
9847+#define __AUFS_DIR_H__
9848+
9849+#ifdef __KERNEL__
9850+
9851+#include <linux/fs.h>
1facf9fc 9852+
9853+/* ---------------------------------------------------------------------- */
9854+
9855+/* need to be faster and smaller */
9856+
9857+struct au_nhash {
dece6358
AM
9858+ unsigned int nh_num;
9859+ struct hlist_head *nh_head;
1facf9fc 9860+};
9861+
9862+struct au_vdir_destr {
9863+ unsigned char len;
9864+ unsigned char name[0];
9865+} __packed;
9866+
9867+struct au_vdir_dehstr {
9868+ struct hlist_node hash;
9869+ struct au_vdir_destr *str;
4a4d8108 9870+} ____cacheline_aligned_in_smp;
1facf9fc 9871+
9872+struct au_vdir_de {
9873+ ino_t de_ino;
9874+ unsigned char de_type;
9875+ /* caution: packed */
9876+ struct au_vdir_destr de_str;
9877+} __packed;
9878+
9879+struct au_vdir_wh {
9880+ struct hlist_node wh_hash;
dece6358
AM
9881+#ifdef CONFIG_AUFS_SHWH
9882+ ino_t wh_ino;
1facf9fc 9883+ aufs_bindex_t wh_bindex;
dece6358
AM
9884+ unsigned char wh_type;
9885+#else
9886+ aufs_bindex_t wh_bindex;
9887+#endif
9888+ /* caution: packed */
1facf9fc 9889+ struct au_vdir_destr wh_str;
9890+} __packed;
9891+
9892+union au_vdir_deblk_p {
9893+ unsigned char *deblk;
9894+ struct au_vdir_de *de;
9895+};
9896+
9897+struct au_vdir {
9898+ unsigned char **vd_deblk;
9899+ unsigned long vd_nblk;
1facf9fc 9900+ struct {
9901+ unsigned long ul;
9902+ union au_vdir_deblk_p p;
9903+ } vd_last;
9904+
9905+ unsigned long vd_version;
dece6358 9906+ unsigned int vd_deblk_sz;
1facf9fc 9907+ unsigned long vd_jiffy;
4a4d8108 9908+} ____cacheline_aligned_in_smp;
1facf9fc 9909+
9910+/* ---------------------------------------------------------------------- */
9911+
9912+/* dir.c */
9913+extern const struct file_operations aufs_dir_fop;
9914+void au_add_nlink(struct inode *dir, struct inode *h_dir);
9915+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 9916+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 9917+int au_test_empty_lower(struct dentry *dentry);
9918+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
9919+
9920+/* vdir.c */
1308ab2a 9921+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
9922+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
9923+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 9924+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
9925+ int limit);
dece6358
AM
9926+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
9927+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
9928+ unsigned int d_type, aufs_bindex_t bindex,
9929+ unsigned char shwh);
1facf9fc 9930+void au_vdir_free(struct au_vdir *vdir);
9931+int au_vdir_init(struct file *file);
392086de 9932+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 9933+
9934+/* ioctl.c */
9935+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
9936+
1308ab2a 9937+#ifdef CONFIG_AUFS_RDU
9938+/* rdu.c */
9939+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
9940+#ifdef CONFIG_COMPAT
9941+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9942+ unsigned long arg);
9943+#endif
1308ab2a 9944+#else
9945+static inline long au_rdu_ioctl(struct file *file, unsigned int cmd,
9946+ unsigned long arg)
9947+{
9948+ return -EINVAL;
9949+}
b752ccd1
AM
9950+#ifdef CONFIG_COMPAT
9951+static inline long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
9952+ unsigned long arg)
9953+{
9954+ return -EINVAL;
9955+}
9956+#endif
1308ab2a 9957+#endif
9958+
1facf9fc 9959+#endif /* __KERNEL__ */
9960+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
9961diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
9962--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
076b876e 9963+++ linux/fs/aufs/dynop.c 2014-01-30 21:10:02.830814411 +0100
523b37e3 9964@@ -0,0 +1,379 @@
1facf9fc 9965+/*
523b37e3 9966+ * Copyright (C) 2010-2014 Junjiro R. Okajima
1facf9fc 9967+ *
9968+ * This program, aufs is free software; you can redistribute it and/or modify
9969+ * it under the terms of the GNU General Public License as published by
9970+ * the Free Software Foundation; either version 2 of the License, or
9971+ * (at your option) any later version.
dece6358
AM
9972+ *
9973+ * This program is distributed in the hope that it will be useful,
9974+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9975+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9976+ * GNU General Public License for more details.
9977+ *
9978+ * You should have received a copy of the GNU General Public License
523b37e3 9979+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9980+ */
9981+
9982+/*
4a4d8108 9983+ * dynamically customizable operations for regular files
1facf9fc 9984+ */
9985+
1facf9fc 9986+#include "aufs.h"
9987+
4a4d8108 9988+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 9989+
4a4d8108
AM
9990+/*
9991+ * How large will these lists be?
9992+ * Usually just a few elements, 20-30 at most for each, I guess.
9993+ */
9994+static struct au_splhead dynop[AuDyLast];
9995+
9996+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 9997+{
4a4d8108
AM
9998+ struct au_dykey *key, *tmp;
9999+ struct list_head *head;
1facf9fc 10000+
4a4d8108
AM
10001+ key = NULL;
10002+ head = &spl->head;
10003+ rcu_read_lock();
10004+ list_for_each_entry_rcu(tmp, head, dk_list)
10005+ if (tmp->dk_op.dy_hop == h_op) {
10006+ key = tmp;
10007+ kref_get(&key->dk_kref);
10008+ break;
10009+ }
10010+ rcu_read_unlock();
10011+
10012+ return key;
1facf9fc 10013+}
10014+
4a4d8108 10015+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 10016+{
4a4d8108
AM
10017+ struct au_dykey **k, *found;
10018+ const void *h_op = key->dk_op.dy_hop;
10019+ int i;
1facf9fc 10020+
4a4d8108
AM
10021+ found = NULL;
10022+ k = br->br_dykey;
10023+ for (i = 0; i < AuBrDynOp; i++)
10024+ if (k[i]) {
10025+ if (k[i]->dk_op.dy_hop == h_op) {
10026+ found = k[i];
10027+ break;
10028+ }
10029+ } else
10030+ break;
10031+ if (!found) {
10032+ spin_lock(&br->br_dykey_lock);
10033+ for (; i < AuBrDynOp; i++)
10034+ if (k[i]) {
10035+ if (k[i]->dk_op.dy_hop == h_op) {
10036+ found = k[i];
10037+ break;
10038+ }
10039+ } else {
10040+ k[i] = key;
10041+ break;
10042+ }
10043+ spin_unlock(&br->br_dykey_lock);
10044+ BUG_ON(i == AuBrDynOp); /* expand the array */
10045+ }
10046+
10047+ return found;
1facf9fc 10048+}
10049+
4a4d8108
AM
10050+/* kref_get() if @key is already added */
10051+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
10052+{
10053+ struct au_dykey *tmp, *found;
10054+ struct list_head *head;
10055+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 10056+
4a4d8108
AM
10057+ found = NULL;
10058+ head = &spl->head;
10059+ spin_lock(&spl->spin);
10060+ list_for_each_entry(tmp, head, dk_list)
10061+ if (tmp->dk_op.dy_hop == h_op) {
10062+ kref_get(&tmp->dk_kref);
10063+ found = tmp;
10064+ break;
10065+ }
10066+ if (!found)
10067+ list_add_rcu(&key->dk_list, head);
10068+ spin_unlock(&spl->spin);
1facf9fc 10069+
4a4d8108
AM
10070+ if (!found)
10071+ DyPrSym(key);
10072+ return found;
10073+}
10074+
10075+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 10076+{
4a4d8108
AM
10077+ struct au_dykey *key;
10078+
10079+ key = container_of(rcu, struct au_dykey, dk_rcu);
10080+ DyPrSym(key);
10081+ kfree(key);
1facf9fc 10082+}
10083+
4a4d8108
AM
10084+static void dy_free(struct kref *kref)
10085+{
10086+ struct au_dykey *key;
10087+ struct au_splhead *spl;
1facf9fc 10088+
4a4d8108
AM
10089+ key = container_of(kref, struct au_dykey, dk_kref);
10090+ spl = dynop + key->dk_op.dy_type;
10091+ au_spl_del_rcu(&key->dk_list, spl);
10092+ call_rcu(&key->dk_rcu, dy_free_rcu);
10093+}
10094+
10095+void au_dy_put(struct au_dykey *key)
1facf9fc 10096+{
4a4d8108
AM
10097+ kref_put(&key->dk_kref, dy_free);
10098+}
1facf9fc 10099+
4a4d8108
AM
10100+/* ---------------------------------------------------------------------- */
10101+
10102+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
10103+
10104+#ifdef CONFIG_AUFS_DEBUG
10105+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 10106+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
10107+#else
10108+#define DyDbgDeclare(cnt) do {} while (0)
10109+#define DyDbgInc(cnt) do {} while (0)
10110+#endif
10111+
10112+#define DySet(func, dst, src, h_op, h_sb) do { \
10113+ DyDbgInc(cnt); \
10114+ if (h_op->func) { \
10115+ if (src.func) \
10116+ dst.func = src.func; \
10117+ else \
10118+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
10119+ } \
10120+} while (0)
10121+
10122+#define DySetForce(func, dst, src) do { \
10123+ AuDebugOn(!src.func); \
10124+ DyDbgInc(cnt); \
10125+ dst.func = src.func; \
10126+} while (0)
10127+
10128+#define DySetAop(func) \
10129+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
10130+#define DySetAopForce(func) \
10131+ DySetForce(func, dyaop->da_op, aufs_aop)
10132+
10133+static void dy_aop(struct au_dykey *key, const void *h_op,
10134+ struct super_block *h_sb __maybe_unused)
10135+{
10136+ struct au_dyaop *dyaop = (void *)key;
10137+ const struct address_space_operations *h_aop = h_op;
10138+ DyDbgDeclare(cnt);
10139+
10140+ AuDbg("%s\n", au_sbtype(h_sb));
10141+
10142+ DySetAop(writepage);
10143+ DySetAopForce(readpage); /* force */
4a4d8108
AM
10144+ DySetAop(writepages);
10145+ DySetAop(set_page_dirty);
10146+ DySetAop(readpages);
10147+ DySetAop(write_begin);
10148+ DySetAop(write_end);
10149+ DySetAop(bmap);
10150+ DySetAop(invalidatepage);
10151+ DySetAop(releasepage);
027c5e7a 10152+ DySetAop(freepage);
4a4d8108
AM
10153+ /* these two will be changed according to an aufs mount option */
10154+ DySetAop(direct_IO);
10155+ DySetAop(get_xip_mem);
10156+ DySetAop(migratepage);
10157+ DySetAop(launder_page);
10158+ DySetAop(is_partially_uptodate);
392086de 10159+ DySetAop(is_dirty_writeback);
4a4d8108 10160+ DySetAop(error_remove_page);
b4510431
AM
10161+ DySetAop(swap_activate);
10162+ DySetAop(swap_deactivate);
4a4d8108
AM
10163+
10164+ DyDbgSize(cnt, *h_aop);
10165+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
10166+}
10167+
4a4d8108
AM
10168+/* ---------------------------------------------------------------------- */
10169+
10170+static void dy_bug(struct kref *kref)
10171+{
10172+ BUG();
10173+}
10174+
10175+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
10176+{
10177+ struct au_dykey *key, *old;
10178+ struct au_splhead *spl;
b752ccd1 10179+ struct op {
4a4d8108 10180+ unsigned int sz;
b752ccd1
AM
10181+ void (*set)(struct au_dykey *key, const void *h_op,
10182+ struct super_block *h_sb __maybe_unused);
10183+ };
10184+ static const struct op a[] = {
4a4d8108
AM
10185+ [AuDy_AOP] = {
10186+ .sz = sizeof(struct au_dyaop),
b752ccd1 10187+ .set = dy_aop
4a4d8108 10188+ }
b752ccd1
AM
10189+ };
10190+ const struct op *p;
4a4d8108
AM
10191+
10192+ spl = dynop + op->dy_type;
10193+ key = dy_gfind_get(spl, op->dy_hop);
10194+ if (key)
10195+ goto out_add; /* success */
10196+
10197+ p = a + op->dy_type;
10198+ key = kzalloc(p->sz, GFP_NOFS);
10199+ if (unlikely(!key)) {
10200+ key = ERR_PTR(-ENOMEM);
10201+ goto out;
10202+ }
10203+
10204+ key->dk_op.dy_hop = op->dy_hop;
10205+ kref_init(&key->dk_kref);
86dc4139 10206+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
10207+ old = dy_gadd(spl, key);
10208+ if (old) {
10209+ kfree(key);
10210+ key = old;
10211+ }
10212+
10213+out_add:
10214+ old = dy_bradd(br, key);
10215+ if (old)
10216+ /* its ref-count should never be zero here */
10217+ kref_put(&key->dk_kref, dy_bug);
10218+out:
10219+ return key;
10220+}
10221+
10222+/* ---------------------------------------------------------------------- */
10223+/*
10224+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
10225+ * This behaviour is neccessary to return an error from open(O_DIRECT) instead
10226+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
10227+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
10228+ * See the aufs manual in detail.
10229+ *
10230+ * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
10231+ * performance of fadvise() and madvise() may be affected.
10232+ */
10233+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
10234+{
10235+ if (!do_dx) {
10236+ dyaop->da_op.direct_IO = NULL;
10237+ dyaop->da_op.get_xip_mem = NULL;
10238+ } else {
10239+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
10240+ dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
10241+ if (!dyaop->da_get_xip_mem)
10242+ dyaop->da_op.get_xip_mem = NULL;
10243+ }
10244+}
10245+
10246+static struct au_dyaop *dy_aget(struct au_branch *br,
10247+ const struct address_space_operations *h_aop,
10248+ int do_dx)
10249+{
10250+ struct au_dyaop *dyaop;
10251+ struct au_dynop op;
10252+
10253+ op.dy_type = AuDy_AOP;
10254+ op.dy_haop = h_aop;
10255+ dyaop = (void *)dy_get(&op, br);
10256+ if (IS_ERR(dyaop))
10257+ goto out;
10258+ dy_adx(dyaop, do_dx);
10259+
10260+out:
10261+ return dyaop;
10262+}
10263+
10264+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10265+ struct inode *h_inode)
10266+{
10267+ int err, do_dx;
10268+ struct super_block *sb;
10269+ struct au_branch *br;
10270+ struct au_dyaop *dyaop;
10271+
10272+ AuDebugOn(!S_ISREG(h_inode->i_mode));
10273+ IiMustWriteLock(inode);
10274+
10275+ sb = inode->i_sb;
10276+ br = au_sbr(sb, bindex);
10277+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
10278+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
10279+ err = PTR_ERR(dyaop);
10280+ if (IS_ERR(dyaop))
10281+ /* unnecessary to call dy_fput() */
10282+ goto out;
10283+
10284+ err = 0;
10285+ inode->i_mapping->a_ops = &dyaop->da_op;
10286+
10287+out:
10288+ return err;
10289+}
10290+
b752ccd1
AM
10291+/*
10292+ * Is it safe to replace a_ops during the inode/file is in operation?
10293+ * Yes, I hope so.
10294+ */
10295+int au_dy_irefresh(struct inode *inode)
10296+{
10297+ int err;
10298+ aufs_bindex_t bstart;
10299+ struct inode *h_inode;
10300+
10301+ err = 0;
10302+ if (S_ISREG(inode->i_mode)) {
10303+ bstart = au_ibstart(inode);
10304+ h_inode = au_h_iptr(inode, bstart);
10305+ err = au_dy_iaop(inode, bstart, h_inode);
10306+ }
10307+ return err;
10308+}
10309+
4a4d8108
AM
10310+void au_dy_arefresh(int do_dx)
10311+{
10312+ struct au_splhead *spl;
10313+ struct list_head *head;
10314+ struct au_dykey *key;
10315+
10316+ spl = dynop + AuDy_AOP;
10317+ head = &spl->head;
10318+ spin_lock(&spl->spin);
10319+ list_for_each_entry(key, head, dk_list)
10320+ dy_adx((void *)key, do_dx);
10321+ spin_unlock(&spl->spin);
10322+}
10323+
4a4d8108
AM
10324+/* ---------------------------------------------------------------------- */
10325+
10326+void __init au_dy_init(void)
10327+{
10328+ int i;
10329+
10330+ /* make sure that 'struct au_dykey *' can be any type */
10331+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
10332+
10333+ for (i = 0; i < AuDyLast; i++)
10334+ au_spl_init(dynop + i);
10335+}
10336+
10337+void au_dy_fin(void)
10338+{
10339+ int i;
10340+
10341+ for (i = 0; i < AuDyLast; i++)
10342+ WARN_ON(!list_empty(&dynop[i].head));
10343+}
7f207e10
AM
10344diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
10345--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
076b876e 10346+++ linux/fs/aufs/dynop.h 2014-01-30 21:10:02.830814411 +0100
523b37e3 10347@@ -0,0 +1,75 @@
4a4d8108 10348+/*
523b37e3 10349+ * Copyright (C) 2010-2014 Junjiro R. Okajima
4a4d8108
AM
10350+ *
10351+ * This program, aufs is free software; you can redistribute it and/or modify
10352+ * it under the terms of the GNU General Public License as published by
10353+ * the Free Software Foundation; either version 2 of the License, or
10354+ * (at your option) any later version.
10355+ *
10356+ * This program is distributed in the hope that it will be useful,
10357+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10358+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10359+ * GNU General Public License for more details.
10360+ *
10361+ * You should have received a copy of the GNU General Public License
523b37e3 10362+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10363+ */
10364+
10365+/*
10366+ * dynamically customizable operations (for regular files only)
10367+ */
10368+
10369+#ifndef __AUFS_DYNOP_H__
10370+#define __AUFS_DYNOP_H__
10371+
10372+#ifdef __KERNEL__
10373+
4a4d8108
AM
10374+#include "inode.h"
10375+
2cbb1c4b 10376+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
10377+
10378+struct au_dynop {
10379+ int dy_type;
10380+ union {
10381+ const void *dy_hop;
10382+ const struct address_space_operations *dy_haop;
4a4d8108
AM
10383+ };
10384+};
10385+
10386+struct au_dykey {
10387+ union {
10388+ struct list_head dk_list;
10389+ struct rcu_head dk_rcu;
10390+ };
10391+ struct au_dynop dk_op;
10392+
10393+ /*
10394+ * during I am in the branch local array, kref is gotten. when the
10395+ * branch is removed, kref is put.
10396+ */
10397+ struct kref dk_kref;
10398+};
10399+
10400+/* stop unioning since their sizes are very different from each other */
10401+struct au_dyaop {
10402+ struct au_dykey da_key;
10403+ struct address_space_operations da_op; /* not const */
10404+ int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
10405+ void **, unsigned long *);
10406+};
10407+
4a4d8108
AM
10408+/* ---------------------------------------------------------------------- */
10409+
10410+/* dynop.c */
10411+struct au_branch;
10412+void au_dy_put(struct au_dykey *key);
10413+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10414+ struct inode *h_inode);
b752ccd1 10415+int au_dy_irefresh(struct inode *inode);
4a4d8108 10416+void au_dy_arefresh(int do_dio);
4a4d8108
AM
10417+
10418+void __init au_dy_init(void);
10419+void au_dy_fin(void);
10420+
4a4d8108
AM
10421+#endif /* __KERNEL__ */
10422+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
10423diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
10424--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
076b876e 10425+++ linux/fs/aufs/export.c 2014-01-30 21:10:02.830814411 +0100
523b37e3 10426@@ -0,0 +1,831 @@
4a4d8108 10427+/*
523b37e3 10428+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
10429+ *
10430+ * This program, aufs is free software; you can redistribute it and/or modify
10431+ * it under the terms of the GNU General Public License as published by
10432+ * the Free Software Foundation; either version 2 of the License, or
10433+ * (at your option) any later version.
10434+ *
10435+ * This program is distributed in the hope that it will be useful,
10436+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10437+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10438+ * GNU General Public License for more details.
10439+ *
10440+ * You should have received a copy of the GNU General Public License
523b37e3 10441+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10442+ */
10443+
10444+/*
10445+ * export via nfs
10446+ */
10447+
10448+#include <linux/exportfs.h>
7eafdf33 10449+#include <linux/fs_struct.h>
4a4d8108
AM
10450+#include <linux/namei.h>
10451+#include <linux/nsproxy.h>
10452+#include <linux/random.h>
10453+#include <linux/writeback.h>
7eafdf33 10454+#include "../fs/mount.h"
4a4d8108
AM
10455+#include "aufs.h"
10456+
10457+union conv {
10458+#ifdef CONFIG_AUFS_INO_T_64
10459+ __u32 a[2];
10460+#else
10461+ __u32 a[1];
10462+#endif
10463+ ino_t ino;
10464+};
10465+
10466+static ino_t decode_ino(__u32 *a)
10467+{
10468+ union conv u;
10469+
10470+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
10471+ u.a[0] = a[0];
10472+#ifdef CONFIG_AUFS_INO_T_64
10473+ u.a[1] = a[1];
10474+#endif
10475+ return u.ino;
10476+}
10477+
10478+static void encode_ino(__u32 *a, ino_t ino)
10479+{
10480+ union conv u;
10481+
10482+ u.ino = ino;
10483+ a[0] = u.a[0];
10484+#ifdef CONFIG_AUFS_INO_T_64
10485+ a[1] = u.a[1];
10486+#endif
10487+}
10488+
10489+/* NFS file handle */
10490+enum {
10491+ Fh_br_id,
10492+ Fh_sigen,
10493+#ifdef CONFIG_AUFS_INO_T_64
10494+ /* support 64bit inode number */
10495+ Fh_ino1,
10496+ Fh_ino2,
10497+ Fh_dir_ino1,
10498+ Fh_dir_ino2,
10499+#else
10500+ Fh_ino1,
10501+ Fh_dir_ino1,
10502+#endif
10503+ Fh_igen,
10504+ Fh_h_type,
10505+ Fh_tail,
10506+
10507+ Fh_ino = Fh_ino1,
10508+ Fh_dir_ino = Fh_dir_ino1
10509+};
10510+
10511+static int au_test_anon(struct dentry *dentry)
10512+{
027c5e7a 10513+ /* note: read d_flags without d_lock */
4a4d8108
AM
10514+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
10515+}
10516+
a2a7ad62
AM
10517+int au_test_nfsd(void)
10518+{
10519+ int ret;
10520+ struct task_struct *tsk = current;
10521+ char comm[sizeof(tsk->comm)];
10522+
10523+ ret = 0;
10524+ if (tsk->flags & PF_KTHREAD) {
10525+ get_task_comm(comm, tsk);
10526+ ret = !strcmp(comm, "nfsd");
10527+ }
10528+
10529+ return ret;
10530+}
10531+
4a4d8108
AM
10532+/* ---------------------------------------------------------------------- */
10533+/* inode generation external table */
10534+
b752ccd1 10535+void au_xigen_inc(struct inode *inode)
4a4d8108 10536+{
4a4d8108
AM
10537+ loff_t pos;
10538+ ssize_t sz;
10539+ __u32 igen;
10540+ struct super_block *sb;
10541+ struct au_sbinfo *sbinfo;
10542+
4a4d8108 10543+ sb = inode->i_sb;
b752ccd1 10544+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 10545+
b752ccd1 10546+ sbinfo = au_sbi(sb);
1facf9fc 10547+ pos = inode->i_ino;
10548+ pos *= sizeof(igen);
10549+ igen = inode->i_generation + 1;
1facf9fc 10550+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
10551+ sizeof(igen), &pos);
10552+ if (sz == sizeof(igen))
b752ccd1 10553+ return; /* success */
1facf9fc 10554+
b752ccd1 10555+ if (unlikely(sz >= 0))
1facf9fc 10556+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 10557+}
10558+
10559+int au_xigen_new(struct inode *inode)
10560+{
10561+ int err;
10562+ loff_t pos;
10563+ ssize_t sz;
10564+ struct super_block *sb;
10565+ struct au_sbinfo *sbinfo;
10566+ struct file *file;
10567+
10568+ err = 0;
10569+ /* todo: dirty, at mount time */
10570+ if (inode->i_ino == AUFS_ROOT_INO)
10571+ goto out;
10572+ sb = inode->i_sb;
dece6358 10573+ SiMustAnyLock(sb);
1facf9fc 10574+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10575+ goto out;
10576+
10577+ err = -EFBIG;
10578+ pos = inode->i_ino;
10579+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
10580+ AuIOErr1("too large i%lld\n", pos);
10581+ goto out;
10582+ }
10583+ pos *= sizeof(inode->i_generation);
10584+
10585+ err = 0;
10586+ sbinfo = au_sbi(sb);
10587+ file = sbinfo->si_xigen;
10588+ BUG_ON(!file);
10589+
c06a8ce3 10590+ if (vfsub_f_size_read(file)
1facf9fc 10591+ < pos + sizeof(inode->i_generation)) {
10592+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
10593+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
10594+ sizeof(inode->i_generation), &pos);
10595+ } else
10596+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
10597+ sizeof(inode->i_generation), &pos);
10598+ if (sz == sizeof(inode->i_generation))
10599+ goto out; /* success */
10600+
10601+ err = sz;
10602+ if (unlikely(sz >= 0)) {
10603+ err = -EIO;
10604+ AuIOErr("xigen error (%zd)\n", sz);
10605+ }
10606+
4f0767ce 10607+out:
1facf9fc 10608+ return err;
10609+}
10610+
10611+int au_xigen_set(struct super_block *sb, struct file *base)
10612+{
10613+ int err;
10614+ struct au_sbinfo *sbinfo;
10615+ struct file *file;
10616+
dece6358
AM
10617+ SiMustWriteLock(sb);
10618+
1facf9fc 10619+ sbinfo = au_sbi(sb);
10620+ file = au_xino_create2(base, sbinfo->si_xigen);
10621+ err = PTR_ERR(file);
10622+ if (IS_ERR(file))
10623+ goto out;
10624+ err = 0;
10625+ if (sbinfo->si_xigen)
10626+ fput(sbinfo->si_xigen);
10627+ sbinfo->si_xigen = file;
10628+
4f0767ce 10629+out:
1facf9fc 10630+ return err;
10631+}
10632+
10633+void au_xigen_clr(struct super_block *sb)
10634+{
10635+ struct au_sbinfo *sbinfo;
10636+
dece6358
AM
10637+ SiMustWriteLock(sb);
10638+
1facf9fc 10639+ sbinfo = au_sbi(sb);
10640+ if (sbinfo->si_xigen) {
10641+ fput(sbinfo->si_xigen);
10642+ sbinfo->si_xigen = NULL;
10643+ }
10644+}
10645+
10646+/* ---------------------------------------------------------------------- */
10647+
10648+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
10649+ ino_t dir_ino)
10650+{
10651+ struct dentry *dentry, *d;
10652+ struct inode *inode;
10653+ unsigned int sigen;
10654+
10655+ dentry = NULL;
10656+ inode = ilookup(sb, ino);
10657+ if (!inode)
10658+ goto out;
10659+
10660+ dentry = ERR_PTR(-ESTALE);
10661+ sigen = au_sigen(sb);
10662+ if (unlikely(is_bad_inode(inode)
10663+ || IS_DEADDIR(inode)
537831f9 10664+ || sigen != au_iigen(inode, NULL)))
1facf9fc 10665+ goto out_iput;
10666+
10667+ dentry = NULL;
10668+ if (!dir_ino || S_ISDIR(inode->i_mode))
10669+ dentry = d_find_alias(inode);
10670+ else {
027c5e7a 10671+ spin_lock(&inode->i_lock);
c06a8ce3 10672+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 10673+ spin_lock(&d->d_lock);
1facf9fc 10674+ if (!au_test_anon(d)
10675+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
10676+ dentry = dget_dlock(d);
10677+ spin_unlock(&d->d_lock);
1facf9fc 10678+ break;
10679+ }
027c5e7a
AM
10680+ spin_unlock(&d->d_lock);
10681+ }
10682+ spin_unlock(&inode->i_lock);
1facf9fc 10683+ }
027c5e7a 10684+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 10685+ /* need to refresh */
1facf9fc 10686+ dput(dentry);
2cbb1c4b 10687+ dentry = NULL;
1facf9fc 10688+ }
10689+
4f0767ce 10690+out_iput:
1facf9fc 10691+ iput(inode);
4f0767ce 10692+out:
2cbb1c4b 10693+ AuTraceErrPtr(dentry);
1facf9fc 10694+ return dentry;
10695+}
10696+
10697+/* ---------------------------------------------------------------------- */
10698+
10699+/* todo: dirty? */
10700+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
10701+
10702+struct au_compare_mnt_args {
10703+ /* input */
10704+ struct super_block *sb;
10705+
10706+ /* output */
10707+ struct vfsmount *mnt;
10708+};
10709+
10710+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
10711+{
10712+ struct au_compare_mnt_args *a = arg;
10713+
10714+ if (mnt->mnt_sb != a->sb)
10715+ return 0;
10716+ a->mnt = mntget(mnt);
10717+ return 1;
10718+}
10719+
1facf9fc 10720+static struct vfsmount *au_mnt_get(struct super_block *sb)
10721+{
4a4d8108 10722+ int err;
7eafdf33 10723+ struct path root;
4a4d8108
AM
10724+ struct au_compare_mnt_args args = {
10725+ .sb = sb
10726+ };
1facf9fc 10727+
7eafdf33 10728+ get_fs_root(current->fs, &root);
523b37e3 10729+ rcu_read_lock();
7eafdf33 10730+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 10731+ rcu_read_unlock();
7eafdf33 10732+ path_put(&root);
4a4d8108
AM
10733+ AuDebugOn(!err);
10734+ AuDebugOn(!args.mnt);
10735+ return args.mnt;
1facf9fc 10736+}
10737+
10738+struct au_nfsd_si_lock {
4a4d8108 10739+ unsigned int sigen;
027c5e7a 10740+ aufs_bindex_t bindex, br_id;
1facf9fc 10741+ unsigned char force_lock;
10742+};
10743+
027c5e7a
AM
10744+static int si_nfsd_read_lock(struct super_block *sb,
10745+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10746+{
027c5e7a 10747+ int err;
1facf9fc 10748+ aufs_bindex_t bindex;
10749+
10750+ si_read_lock(sb, AuLock_FLUSH);
10751+
10752+ /* branch id may be wrapped around */
027c5e7a 10753+ err = 0;
1facf9fc 10754+ bindex = au_br_index(sb, nsi_lock->br_id);
10755+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
10756+ goto out; /* success */
10757+
027c5e7a
AM
10758+ err = -ESTALE;
10759+ bindex = -1;
1facf9fc 10760+ if (!nsi_lock->force_lock)
10761+ si_read_unlock(sb);
1facf9fc 10762+
4f0767ce 10763+out:
027c5e7a
AM
10764+ nsi_lock->bindex = bindex;
10765+ return err;
1facf9fc 10766+}
10767+
10768+struct find_name_by_ino {
392086de 10769+ struct dir_context ctx;
1facf9fc 10770+ int called, found;
10771+ ino_t ino;
10772+ char *name;
10773+ int namelen;
10774+};
10775+
10776+static int
392086de
AM
10777+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
10778+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 10779+{
392086de
AM
10780+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
10781+ ctx);
1facf9fc 10782+
10783+ a->called++;
10784+ if (a->ino != ino)
10785+ return 0;
10786+
10787+ memcpy(a->name, name, namelen);
10788+ a->namelen = namelen;
10789+ a->found = 1;
10790+ return 1;
10791+}
10792+
10793+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
10794+ struct au_nfsd_si_lock *nsi_lock)
10795+{
10796+ struct dentry *dentry, *parent;
10797+ struct file *file;
10798+ struct inode *dir;
392086de
AM
10799+ struct find_name_by_ino arg = {
10800+ .ctx = {
10801+ .actor = au_diractor(find_name_by_ino)
10802+ }
10803+ };
1facf9fc 10804+ int err;
10805+
10806+ parent = path->dentry;
10807+ if (nsi_lock)
10808+ si_read_unlock(parent->d_sb);
4a4d8108 10809+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 10810+ dentry = (void *)file;
10811+ if (IS_ERR(file))
10812+ goto out;
10813+
10814+ dentry = ERR_PTR(-ENOMEM);
537831f9 10815+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 10816+ if (unlikely(!arg.name))
10817+ goto out_file;
10818+ arg.ino = ino;
10819+ arg.found = 0;
10820+ do {
10821+ arg.called = 0;
10822+ /* smp_mb(); */
392086de 10823+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 10824+ } while (!err && !arg.found && arg.called);
10825+ dentry = ERR_PTR(err);
10826+ if (unlikely(err))
10827+ goto out_name;
1716fcea
AM
10828+ /* instead of ENOENT */
10829+ dentry = ERR_PTR(-ESTALE);
1facf9fc 10830+ if (!arg.found)
10831+ goto out_name;
10832+
b4510431 10833+ /* do not call vfsub_lkup_one() */
1facf9fc 10834+ dir = parent->d_inode;
10835+ mutex_lock(&dir->i_mutex);
10836+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
10837+ mutex_unlock(&dir->i_mutex);
10838+ AuTraceErrPtr(dentry);
10839+ if (IS_ERR(dentry))
10840+ goto out_name;
10841+ AuDebugOn(au_test_anon(dentry));
10842+ if (unlikely(!dentry->d_inode)) {
10843+ dput(dentry);
10844+ dentry = ERR_PTR(-ENOENT);
10845+ }
10846+
4f0767ce 10847+out_name:
537831f9 10848+ free_page((unsigned long)arg.name);
4f0767ce 10849+out_file:
1facf9fc 10850+ fput(file);
4f0767ce 10851+out:
1facf9fc 10852+ if (unlikely(nsi_lock
10853+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
10854+ if (!IS_ERR(dentry)) {
10855+ dput(dentry);
10856+ dentry = ERR_PTR(-ESTALE);
10857+ }
10858+ AuTraceErrPtr(dentry);
10859+ return dentry;
10860+}
10861+
10862+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
10863+ ino_t dir_ino,
10864+ struct au_nfsd_si_lock *nsi_lock)
10865+{
10866+ struct dentry *dentry;
10867+ struct path path;
10868+
10869+ if (dir_ino != AUFS_ROOT_INO) {
10870+ path.dentry = decode_by_ino(sb, dir_ino, 0);
10871+ dentry = path.dentry;
10872+ if (!path.dentry || IS_ERR(path.dentry))
10873+ goto out;
10874+ AuDebugOn(au_test_anon(path.dentry));
10875+ } else
10876+ path.dentry = dget(sb->s_root);
10877+
10878+ path.mnt = au_mnt_get(sb);
10879+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
10880+ path_put(&path);
10881+
4f0767ce 10882+out:
1facf9fc 10883+ AuTraceErrPtr(dentry);
10884+ return dentry;
10885+}
10886+
10887+/* ---------------------------------------------------------------------- */
10888+
10889+static int h_acceptable(void *expv, struct dentry *dentry)
10890+{
10891+ return 1;
10892+}
10893+
10894+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
10895+ char *buf, int len, struct super_block *sb)
10896+{
10897+ char *p;
10898+ int n;
10899+ struct path path;
10900+
10901+ p = d_path(h_rootpath, buf, len);
10902+ if (IS_ERR(p))
10903+ goto out;
10904+ n = strlen(p);
10905+
10906+ path.mnt = h_rootpath->mnt;
10907+ path.dentry = h_parent;
10908+ p = d_path(&path, buf, len);
10909+ if (IS_ERR(p))
10910+ goto out;
10911+ if (n != 1)
10912+ p += n;
10913+
10914+ path.mnt = au_mnt_get(sb);
10915+ path.dentry = sb->s_root;
10916+ p = d_path(&path, buf, len - strlen(p));
10917+ mntput(path.mnt);
10918+ if (IS_ERR(p))
10919+ goto out;
10920+ if (n != 1)
10921+ p[strlen(p)] = '/';
10922+
4f0767ce 10923+out:
1facf9fc 10924+ AuTraceErrPtr(p);
10925+ return p;
10926+}
10927+
10928+static
027c5e7a
AM
10929+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
10930+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10931+{
10932+ struct dentry *dentry, *h_parent, *root;
10933+ struct super_block *h_sb;
10934+ char *pathname, *p;
10935+ struct vfsmount *h_mnt;
10936+ struct au_branch *br;
10937+ int err;
10938+ struct path path;
10939+
027c5e7a 10940+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 10941+ h_mnt = au_br_mnt(br);
1facf9fc 10942+ h_sb = h_mnt->mnt_sb;
10943+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
10944+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
10945+ fh_len - Fh_tail, fh[Fh_h_type],
10946+ h_acceptable, /*context*/NULL);
10947+ dentry = h_parent;
10948+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
10949+ AuWarn1("%s decode_fh failed, %ld\n",
10950+ au_sbtype(h_sb), PTR_ERR(h_parent));
10951+ goto out;
10952+ }
10953+ dentry = NULL;
10954+ if (unlikely(au_test_anon(h_parent))) {
10955+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
10956+ au_sbtype(h_sb));
10957+ goto out_h_parent;
10958+ }
10959+
10960+ dentry = ERR_PTR(-ENOMEM);
10961+ pathname = (void *)__get_free_page(GFP_NOFS);
10962+ if (unlikely(!pathname))
10963+ goto out_h_parent;
10964+
10965+ root = sb->s_root;
10966+ path.mnt = h_mnt;
10967+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 10968+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 10969+ di_read_unlock(root, !AuLock_IR);
10970+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
10971+ dentry = (void *)p;
10972+ if (IS_ERR(p))
10973+ goto out_pathname;
10974+
10975+ si_read_unlock(sb);
10976+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
10977+ dentry = ERR_PTR(err);
10978+ if (unlikely(err))
10979+ goto out_relock;
10980+
10981+ dentry = ERR_PTR(-ENOENT);
10982+ AuDebugOn(au_test_anon(path.dentry));
10983+ if (unlikely(!path.dentry->d_inode))
10984+ goto out_path;
10985+
10986+ if (ino != path.dentry->d_inode->i_ino)
10987+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
10988+ else
10989+ dentry = dget(path.dentry);
10990+
4f0767ce 10991+out_path:
1facf9fc 10992+ path_put(&path);
4f0767ce 10993+out_relock:
1facf9fc 10994+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
10995+ if (!IS_ERR(dentry)) {
10996+ dput(dentry);
10997+ dentry = ERR_PTR(-ESTALE);
10998+ }
4f0767ce 10999+out_pathname:
1facf9fc 11000+ free_page((unsigned long)pathname);
4f0767ce 11001+out_h_parent:
1facf9fc 11002+ dput(h_parent);
4f0767ce 11003+out:
1facf9fc 11004+ AuTraceErrPtr(dentry);
11005+ return dentry;
11006+}
11007+
11008+/* ---------------------------------------------------------------------- */
11009+
11010+static struct dentry *
11011+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
11012+ int fh_type)
11013+{
11014+ struct dentry *dentry;
11015+ __u32 *fh = fid->raw;
027c5e7a 11016+ struct au_branch *br;
1facf9fc 11017+ ino_t ino, dir_ino;
1facf9fc 11018+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 11019+ .force_lock = 0
11020+ };
11021+
1facf9fc 11022+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
11023+ /* it should never happen, but the file handle is unreliable */
11024+ if (unlikely(fh_len < Fh_tail))
11025+ goto out;
11026+ nsi_lock.sigen = fh[Fh_sigen];
11027+ nsi_lock.br_id = fh[Fh_br_id];
11028+
1facf9fc 11029+ /* branch id may be wrapped around */
027c5e7a
AM
11030+ br = NULL;
11031+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 11032+ goto out;
11033+ nsi_lock.force_lock = 1;
11034+
11035+ /* is this inode still cached? */
11036+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
11037+ /* it should never happen */
11038+ if (unlikely(ino == AUFS_ROOT_INO))
11039+ goto out;
11040+
1facf9fc 11041+ dir_ino = decode_ino(fh + Fh_dir_ino);
11042+ dentry = decode_by_ino(sb, ino, dir_ino);
11043+ if (IS_ERR(dentry))
11044+ goto out_unlock;
11045+ if (dentry)
11046+ goto accept;
11047+
11048+ /* is the parent dir cached? */
027c5e7a
AM
11049+ br = au_sbr(sb, nsi_lock.bindex);
11050+ atomic_inc(&br->br_count);
1facf9fc 11051+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
11052+ if (IS_ERR(dentry))
11053+ goto out_unlock;
11054+ if (dentry)
11055+ goto accept;
11056+
11057+ /* lookup path */
027c5e7a 11058+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 11059+ if (IS_ERR(dentry))
11060+ goto out_unlock;
11061+ if (unlikely(!dentry))
11062+ /* todo?: make it ESTALE */
11063+ goto out_unlock;
11064+
4f0767ce 11065+accept:
027c5e7a
AM
11066+ if (!au_digen_test(dentry, au_sigen(sb))
11067+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 11068+ goto out_unlock; /* success */
11069+
11070+ dput(dentry);
11071+ dentry = ERR_PTR(-ESTALE);
4f0767ce 11072+out_unlock:
027c5e7a
AM
11073+ if (br)
11074+ atomic_dec(&br->br_count);
1facf9fc 11075+ si_read_unlock(sb);
4f0767ce 11076+out:
1facf9fc 11077+ AuTraceErrPtr(dentry);
11078+ return dentry;
11079+}
11080+
11081+#if 0 /* reserved for future use */
11082+/* support subtreecheck option */
11083+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
11084+ int fh_len, int fh_type)
11085+{
11086+ struct dentry *parent;
11087+ __u32 *fh = fid->raw;
11088+ ino_t dir_ino;
11089+
11090+ dir_ino = decode_ino(fh + Fh_dir_ino);
11091+ parent = decode_by_ino(sb, dir_ino, 0);
11092+ if (IS_ERR(parent))
11093+ goto out;
11094+ if (!parent)
11095+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
11096+ dir_ino, fh, fh_len);
11097+
4f0767ce 11098+out:
1facf9fc 11099+ AuTraceErrPtr(parent);
11100+ return parent;
11101+}
11102+#endif
11103+
11104+/* ---------------------------------------------------------------------- */
11105+
0c3ec466
AM
11106+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
11107+ struct inode *dir)
1facf9fc 11108+{
11109+ int err;
0c3ec466 11110+ aufs_bindex_t bindex;
1facf9fc 11111+ struct super_block *sb, *h_sb;
0c3ec466
AM
11112+ struct dentry *dentry, *parent, *h_parent;
11113+ struct inode *h_dir;
1facf9fc 11114+ struct au_branch *br;
11115+
1facf9fc 11116+ err = -ENOSPC;
11117+ if (unlikely(*max_len <= Fh_tail)) {
11118+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
11119+ goto out;
11120+ }
11121+
11122+ err = FILEID_ROOT;
0c3ec466
AM
11123+ if (inode->i_ino == AUFS_ROOT_INO) {
11124+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 11125+ goto out;
11126+ }
11127+
1facf9fc 11128+ h_parent = NULL;
0c3ec466
AM
11129+ sb = inode->i_sb;
11130+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
11131+ if (unlikely(err))
11132+ goto out;
11133+
1facf9fc 11134+#ifdef CONFIG_AUFS_DEBUG
11135+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
11136+ AuWarn1("NFS-exporting requires xino\n");
11137+#endif
027c5e7a 11138+ err = -EIO;
0c3ec466
AM
11139+ parent = NULL;
11140+ ii_read_lock_child(inode);
11141+ bindex = au_ibstart(inode);
11142+ if (!dir) {
11143+ dentry = d_find_alias(inode);
11144+ if (unlikely(!dentry))
11145+ goto out_unlock;
11146+ AuDebugOn(au_test_anon(dentry));
11147+ parent = dget_parent(dentry);
11148+ dput(dentry);
11149+ if (unlikely(!parent))
11150+ goto out_unlock;
11151+ dir = parent->d_inode;
1facf9fc 11152+ }
0c3ec466
AM
11153+
11154+ ii_read_lock_parent(dir);
11155+ h_dir = au_h_iptr(dir, bindex);
11156+ ii_read_unlock(dir);
11157+ if (unlikely(!h_dir))
11158+ goto out_parent;
11159+ h_parent = d_find_alias(h_dir);
1facf9fc 11160+ if (unlikely(!h_parent))
0c3ec466 11161+ goto out_hparent;
1facf9fc 11162+
11163+ err = -EPERM;
11164+ br = au_sbr(sb, bindex);
86dc4139 11165+ h_sb = au_br_sb(br);
1facf9fc 11166+ if (unlikely(!h_sb->s_export_op)) {
11167+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 11168+ goto out_hparent;
1facf9fc 11169+ }
11170+
11171+ fh[Fh_br_id] = br->br_id;
11172+ fh[Fh_sigen] = au_sigen(sb);
11173+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 11174+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 11175+ fh[Fh_igen] = inode->i_generation;
11176+
11177+ *max_len -= Fh_tail;
11178+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
11179+ max_len,
11180+ /*connectable or subtreecheck*/0);
11181+ err = fh[Fh_h_type];
11182+ *max_len += Fh_tail;
11183+ /* todo: macros? */
1716fcea 11184+ if (err != FILEID_INVALID)
1facf9fc 11185+ err = 99;
11186+ else
11187+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
11188+
0c3ec466 11189+out_hparent:
1facf9fc 11190+ dput(h_parent);
0c3ec466 11191+out_parent:
1facf9fc 11192+ dput(parent);
0c3ec466
AM
11193+out_unlock:
11194+ ii_read_unlock(inode);
11195+ si_read_unlock(sb);
4f0767ce 11196+out:
1facf9fc 11197+ if (unlikely(err < 0))
1716fcea 11198+ err = FILEID_INVALID;
1facf9fc 11199+ return err;
11200+}
11201+
11202+/* ---------------------------------------------------------------------- */
11203+
4a4d8108
AM
11204+static int aufs_commit_metadata(struct inode *inode)
11205+{
11206+ int err;
11207+ aufs_bindex_t bindex;
11208+ struct super_block *sb;
11209+ struct inode *h_inode;
11210+ int (*f)(struct inode *inode);
11211+
11212+ sb = inode->i_sb;
e49829fe 11213+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11214+ ii_write_lock_child(inode);
11215+ bindex = au_ibstart(inode);
11216+ AuDebugOn(bindex < 0);
11217+ h_inode = au_h_iptr(inode, bindex);
11218+
11219+ f = h_inode->i_sb->s_export_op->commit_metadata;
11220+ if (f)
11221+ err = f(h_inode);
11222+ else {
11223+ struct writeback_control wbc = {
11224+ .sync_mode = WB_SYNC_ALL,
11225+ .nr_to_write = 0 /* metadata only */
11226+ };
11227+
11228+ err = sync_inode(h_inode, &wbc);
11229+ }
11230+
11231+ au_cpup_attr_timesizes(inode);
11232+ ii_write_unlock(inode);
11233+ si_read_unlock(sb);
11234+ return err;
11235+}
11236+
11237+/* ---------------------------------------------------------------------- */
11238+
1facf9fc 11239+static struct export_operations aufs_export_op = {
4a4d8108 11240+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 11241+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
11242+ .encode_fh = aufs_encode_fh,
11243+ .commit_metadata = aufs_commit_metadata
1facf9fc 11244+};
11245+
11246+void au_export_init(struct super_block *sb)
11247+{
11248+ struct au_sbinfo *sbinfo;
11249+ __u32 u;
11250+
11251+ sb->s_export_op = &aufs_export_op;
11252+ sbinfo = au_sbi(sb);
11253+ sbinfo->si_xigen = NULL;
11254+ get_random_bytes(&u, sizeof(u));
11255+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
11256+ atomic_set(&sbinfo->si_xigen_next, u);
11257+}
076b876e
AM
11258diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
11259--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
11260+++ linux/fs/aufs/fhsm.c 2014-08-14 10:15:45.121942630 +0200
11261@@ -0,0 +1,410 @@
11262+/*
11263+ * Copyright (C) 2011-2014 Junjiro R. Okajima
11264+ *
11265+ * This program, aufs is free software; you can redistribute it and/or modify
11266+ * it under the terms of the GNU General Public License as published by
11267+ * the Free Software Foundation; either version 2 of the License, or
11268+ * (at your option) any later version.
11269+ *
11270+ * This program is distributed in the hope that it will be useful,
11271+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11272+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11273+ * GNU General Public License for more details.
11274+ *
11275+ * You should have received a copy of the GNU General Public License
11276+ * along with this program; if not, write to the Free Software
11277+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11278+ */
11279+
11280+/*
11281+ * File-based Hierarchy Storage Management
11282+ */
11283+
11284+#include <linux/anon_inodes.h>
11285+#include <linux/poll.h>
11286+#include <linux/seq_file.h>
11287+#include <linux/statfs.h>
11288+#include "aufs.h"
11289+
11290+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
11291+{
11292+ struct au_br_fhsm *bf;
11293+
11294+ bf = br->br_fhsm;
11295+ MtxMustLock(&bf->bf_lock);
11296+
11297+ return !bf->bf_readable
11298+ || time_after(jiffies,
11299+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
11300+}
11301+
11302+/* ---------------------------------------------------------------------- */
11303+
11304+static void au_fhsm_notify(struct super_block *sb, int val)
11305+{
11306+ struct au_sbinfo *sbinfo;
11307+ struct au_fhsm *fhsm;
11308+
11309+ SiMustAnyLock(sb);
11310+
11311+ sbinfo = au_sbi(sb);
11312+ fhsm = &sbinfo->si_fhsm;
11313+ if (au_fhsm_pid(fhsm)
11314+ && atomic_read(&fhsm->fhsm_readable) != -1) {
11315+ atomic_set(&fhsm->fhsm_readable, val);
11316+ if (val)
11317+ wake_up(&fhsm->fhsm_wqh);
11318+ }
11319+}
11320+
11321+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
11322+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
11323+{
11324+ int err;
11325+ struct au_branch *br;
11326+ struct au_br_fhsm *bf;
11327+
11328+ br = au_sbr(sb, bindex);
11329+ AuDebugOn(au_br_rdonly(br));
11330+ bf = br->br_fhsm;
11331+ AuDebugOn(!bf);
11332+
11333+ if (do_lock)
11334+ mutex_lock(&bf->bf_lock);
11335+ else
11336+ MtxMustLock(&bf->bf_lock);
11337+
11338+ /* sb->s_root for NFS is unreliable */
11339+ err = au_br_stfs(br, &bf->bf_stfs);
11340+ if (unlikely(err)) {
11341+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
11342+ goto out;
11343+ }
11344+
11345+ bf->bf_jiffy = jiffies;
11346+ bf->bf_readable = 1;
11347+ if (do_notify)
11348+ au_fhsm_notify(sb, /*val*/1);
11349+ if (rstfs)
11350+ *rstfs = bf->bf_stfs;
11351+
11352+out:
11353+ if (do_lock)
11354+ mutex_unlock(&bf->bf_lock);
11355+ au_fhsm_notify(sb, /*val*/1);
11356+
11357+ return err;
11358+}
11359+
11360+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
11361+{
11362+ int err;
11363+ unsigned char do_notify;
11364+ aufs_bindex_t bend, blower;
11365+ struct au_sbinfo *sbinfo;
11366+ struct au_fhsm *fhsm;
11367+ struct au_branch *br;
11368+ struct au_br_fhsm *bf;
11369+
11370+ AuDbg("b%d, force %d\n", bindex, force);
11371+ SiMustAnyLock(sb);
11372+
11373+ sbinfo = au_sbi(sb);
11374+ fhsm = &sbinfo->si_fhsm;
11375+ if (!au_ftest_si(sbinfo, FHSM))
11376+ return;
11377+
11378+ do_notify = 0;
11379+ bend = au_sbend(sb);
11380+ for (blower = bindex + 1; blower <= bend; blower++) {
11381+ br = au_sbr(sb, blower);
11382+ if (au_br_fhsm(br->br_perm)) {
11383+ do_notify = 1;
11384+ break;
11385+ }
11386+ }
11387+ if (!do_notify)
11388+ return;
11389+
11390+ br = au_sbr(sb, bindex);
11391+ bf = br->br_fhsm;
11392+ AuDebugOn(!bf);
11393+ mutex_lock(&bf->bf_lock);
11394+ if (force
11395+ || au_fhsm_pid(fhsm)
11396+ || au_fhsm_test_jiffy(sbinfo, br))
11397+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
11398+ /*do_notify*/1);
11399+ mutex_unlock(&bf->bf_lock);
11400+}
11401+
11402+void au_fhsm_wrote_all(struct super_block *sb, int force)
11403+{
11404+ aufs_bindex_t bindex, bend;
11405+ struct au_branch *br;
11406+
11407+ /* exclude the bottom */
11408+ bend = au_sbend(sb);
11409+ for (bindex = 0; bindex < bend; bindex++) {
11410+ br = au_sbr(sb, bindex);
11411+ if (au_br_fhsm(br->br_perm))
11412+ au_fhsm_wrote(sb, bindex, force);
11413+ }
11414+}
11415+
11416+/* ---------------------------------------------------------------------- */
11417+
11418+static unsigned int au_fhsm_poll(struct file *file,
11419+ struct poll_table_struct *wait)
11420+{
11421+ unsigned int mask;
11422+ struct au_sbinfo *sbinfo;
11423+ struct au_fhsm *fhsm;
11424+
11425+ mask = 0;
11426+ sbinfo = file->private_data;
11427+ fhsm = &sbinfo->si_fhsm;
11428+ poll_wait(file, &fhsm->fhsm_wqh, wait);
11429+ if (atomic_read(&fhsm->fhsm_readable))
11430+ mask = POLLIN /* | POLLRDNORM */;
11431+
11432+ AuTraceErr((int)mask);
11433+ return mask;
11434+}
11435+
11436+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
11437+ struct aufs_stfs *stfs, __s16 brid)
11438+{
11439+ int err;
11440+
11441+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
11442+ if (!err)
11443+ err = __put_user(brid, &stbr->brid);
11444+ if (unlikely(err))
11445+ err = -EFAULT;
11446+
11447+ return err;
11448+}
11449+
11450+static ssize_t au_fhsm_do_read(struct super_block *sb,
11451+ struct aufs_stbr __user *stbr, size_t count)
11452+{
11453+ ssize_t err;
11454+ int nstbr;
11455+ aufs_bindex_t bindex, bend;
11456+ struct au_branch *br;
11457+ struct au_br_fhsm *bf;
11458+
11459+ /* except the bottom branch */
11460+ err = 0;
11461+ nstbr = 0;
11462+ bend = au_sbend(sb);
11463+ for (bindex = 0; !err && bindex < bend; bindex++) {
11464+ br = au_sbr(sb, bindex);
11465+ if (!au_br_fhsm(br->br_perm))
11466+ continue;
11467+
11468+ bf = br->br_fhsm;
11469+ mutex_lock(&bf->bf_lock);
11470+ if (bf->bf_readable) {
11471+ err = -EFAULT;
11472+ if (count >= sizeof(*stbr))
11473+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
11474+ br->br_id);
11475+ if (!err) {
11476+ bf->bf_readable = 0;
11477+ count -= sizeof(*stbr);
11478+ nstbr++;
11479+ }
11480+ }
11481+ mutex_unlock(&bf->bf_lock);
11482+ }
11483+ if (!err)
11484+ err = sizeof(*stbr) * nstbr;
11485+
11486+ return err;
11487+}
11488+
11489+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
11490+ loff_t *pos)
11491+{
11492+ ssize_t err;
11493+ int readable;
11494+ aufs_bindex_t nfhsm, bindex, bend;
11495+ struct au_sbinfo *sbinfo;
11496+ struct au_fhsm *fhsm;
11497+ struct au_branch *br;
11498+ struct super_block *sb;
11499+
11500+ err = 0;
11501+ sbinfo = file->private_data;
11502+ fhsm = &sbinfo->si_fhsm;
11503+need_data:
11504+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
11505+ if (!atomic_read(&fhsm->fhsm_readable)) {
11506+ if (vfsub_file_flags(file) & O_NONBLOCK)
11507+ err = -EAGAIN;
11508+ else
11509+ err = wait_event_interruptible_locked_irq
11510+ (fhsm->fhsm_wqh,
11511+ atomic_read(&fhsm->fhsm_readable));
11512+ }
11513+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
11514+ if (unlikely(err))
11515+ goto out;
11516+
11517+ /* sb may already be dead */
11518+ au_rw_read_lock(&sbinfo->si_rwsem);
11519+ readable = atomic_read(&fhsm->fhsm_readable);
11520+ if (readable > 0) {
11521+ sb = sbinfo->si_sb;
11522+ AuDebugOn(!sb);
11523+ /* exclude the bottom branch */
11524+ nfhsm = 0;
11525+ bend = au_sbend(sb);
11526+ for (bindex = 0; bindex < bend; bindex++) {
11527+ br = au_sbr(sb, bindex);
11528+ if (au_br_fhsm(br->br_perm))
11529+ nfhsm++;
11530+ }
11531+ err = -EMSGSIZE;
11532+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
11533+ atomic_set(&fhsm->fhsm_readable, 0);
11534+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
11535+ count);
11536+ }
11537+ }
11538+ au_rw_read_unlock(&sbinfo->si_rwsem);
11539+ if (!readable)
11540+ goto need_data;
11541+
11542+out:
11543+ return err;
11544+}
11545+
11546+static int au_fhsm_release(struct inode *inode, struct file *file)
11547+{
11548+ struct au_sbinfo *sbinfo;
11549+ struct au_fhsm *fhsm;
11550+
11551+ /* sb may already be dead */
11552+ sbinfo = file->private_data;
11553+ fhsm = &sbinfo->si_fhsm;
11554+ spin_lock(&fhsm->fhsm_spin);
11555+ fhsm->fhsm_pid = 0;
11556+ spin_unlock(&fhsm->fhsm_spin);
11557+ kobject_put(&sbinfo->si_kobj);
11558+
11559+ return 0;
11560+}
11561+
11562+static const struct file_operations au_fhsm_fops = {
11563+ .owner = THIS_MODULE,
11564+ .llseek = noop_llseek,
11565+ .read = au_fhsm_read,
11566+ .poll = au_fhsm_poll,
11567+ .release = au_fhsm_release
11568+};
11569+
11570+int au_fhsm_fd(struct super_block *sb, int oflags)
11571+{
11572+ int err, fd;
11573+ struct au_sbinfo *sbinfo;
11574+ struct au_fhsm *fhsm;
11575+
11576+ err = -EPERM;
11577+ if (unlikely(!capable(CAP_SYS_ADMIN)))
11578+ goto out;
11579+
11580+ err = -EINVAL;
11581+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
11582+ goto out;
11583+
11584+ err = 0;
11585+ sbinfo = au_sbi(sb);
11586+ fhsm = &sbinfo->si_fhsm;
11587+ spin_lock(&fhsm->fhsm_spin);
11588+ if (!fhsm->fhsm_pid)
11589+ fhsm->fhsm_pid = current->pid;
11590+ else
11591+ err = -EBUSY;
11592+ spin_unlock(&fhsm->fhsm_spin);
11593+ if (unlikely(err))
11594+ goto out;
11595+
11596+ oflags |= O_RDONLY;
11597+ /* oflags |= FMODE_NONOTIFY; */
11598+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
11599+ err = fd;
11600+ if (unlikely(fd < 0))
11601+ goto out_pid;
11602+
11603+ /* succeed reglardless 'fhsm' status */
11604+ kobject_get(&sbinfo->si_kobj);
11605+ si_noflush_read_lock(sb);
11606+ if (au_ftest_si(sbinfo, FHSM))
11607+ au_fhsm_wrote_all(sb, /*force*/0);
11608+ si_read_unlock(sb);
11609+ goto out; /* success */
11610+
11611+out_pid:
11612+ spin_lock(&fhsm->fhsm_spin);
11613+ fhsm->fhsm_pid = 0;
11614+ spin_unlock(&fhsm->fhsm_spin);
11615+out:
11616+ AuTraceErr(err);
11617+ return err;
11618+}
11619+
11620+/* ---------------------------------------------------------------------- */
11621+
11622+int au_fhsm_br_alloc(struct au_branch *br)
11623+{
11624+ int err;
11625+
11626+ err = 0;
11627+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
11628+ if (br->br_fhsm)
11629+ au_br_fhsm_init(br->br_fhsm);
11630+ else
11631+ err = -ENOMEM;
11632+
11633+ return err;
11634+}
11635+
11636+/* ---------------------------------------------------------------------- */
11637+
11638+void au_fhsm_fin(struct super_block *sb)
11639+{
11640+ au_fhsm_notify(sb, /*val*/-1);
11641+}
11642+
11643+void au_fhsm_init(struct au_sbinfo *sbinfo)
11644+{
11645+ struct au_fhsm *fhsm;
11646+
11647+ fhsm = &sbinfo->si_fhsm;
11648+ spin_lock_init(&fhsm->fhsm_spin);
11649+ init_waitqueue_head(&fhsm->fhsm_wqh);
11650+ atomic_set(&fhsm->fhsm_readable, 0);
11651+ fhsm->fhsm_expire
11652+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
11653+}
11654+
11655+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
11656+{
11657+ sbinfo->si_fhsm.fhsm_expire
11658+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
11659+}
11660+
11661+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
11662+{
11663+ unsigned int u;
11664+
11665+ if (!au_ftest_si(sbinfo, FHSM))
11666+ return;
11667+
11668+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
11669+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
11670+ seq_printf(seq, ",fhsm_sec=%u", u);
11671+}
7f207e10
AM
11672diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
11673--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
11674+++ linux/fs/aufs/file.c 2014-08-14 10:16:04.515942371 +0200
11675@@ -0,0 +1,835 @@
1facf9fc 11676+/*
523b37e3 11677+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 11678+ *
11679+ * This program, aufs is free software; you can redistribute it and/or modify
11680+ * it under the terms of the GNU General Public License as published by
11681+ * the Free Software Foundation; either version 2 of the License, or
11682+ * (at your option) any later version.
dece6358
AM
11683+ *
11684+ * This program is distributed in the hope that it will be useful,
11685+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11686+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11687+ * GNU General Public License for more details.
11688+ *
11689+ * You should have received a copy of the GNU General Public License
523b37e3 11690+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 11691+ */
11692+
11693+/*
4a4d8108 11694+ * handling file/dir, and address_space operation
1facf9fc 11695+ */
11696+
7eafdf33
AM
11697+#ifdef CONFIG_AUFS_DEBUG
11698+#include <linux/migrate.h>
11699+#endif
4a4d8108 11700+#include <linux/pagemap.h>
1facf9fc 11701+#include "aufs.h"
11702+
4a4d8108
AM
11703+/* drop flags for writing */
11704+unsigned int au_file_roflags(unsigned int flags)
11705+{
11706+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
11707+ flags |= O_RDONLY | O_NOATIME;
11708+ return flags;
11709+}
11710+
11711+/* common functions to regular file and dir */
11712+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 11713+ struct file *file, int force_wr)
1facf9fc 11714+{
1308ab2a 11715+ struct file *h_file;
4a4d8108
AM
11716+ struct dentry *h_dentry;
11717+ struct inode *h_inode;
11718+ struct super_block *sb;
11719+ struct au_branch *br;
11720+ struct path h_path;
11721+ int err, exec_flag;
1facf9fc 11722+
4a4d8108
AM
11723+ /* a race condition can happen between open and unlink/rmdir */
11724+ h_file = ERR_PTR(-ENOENT);
11725+ h_dentry = au_h_dptr(dentry, bindex);
b752ccd1 11726+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
11727+ goto out;
11728+ h_inode = h_dentry->d_inode;
b752ccd1 11729+ if (au_test_nfsd() && !h_inode)
4a4d8108 11730+ goto out;
027c5e7a
AM
11731+ spin_lock(&h_dentry->d_lock);
11732+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
11733+ || !h_inode
11734+ /* || !dentry->d_inode->i_nlink */
11735+ ;
11736+ spin_unlock(&h_dentry->d_lock);
11737+ if (unlikely(err))
4a4d8108 11738+ goto out;
1facf9fc 11739+
4a4d8108
AM
11740+ sb = dentry->d_sb;
11741+ br = au_sbr(sb, bindex);
11742+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 11743+ exec_flag = flags & __FMODE_EXEC;
86dc4139 11744+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
027c5e7a 11745+ goto out;
1facf9fc 11746+
4a4d8108 11747+ /* drop flags for writing */
392086de
AM
11748+ if (au_test_ro(sb, bindex, dentry->d_inode)) {
11749+ if (force_wr && !(flags & O_WRONLY))
11750+ force_wr = 0;
4a4d8108 11751+ flags = au_file_roflags(flags);
392086de
AM
11752+ if (force_wr) {
11753+ h_file = ERR_PTR(-EROFS);
11754+ flags = au_file_roflags(flags);
11755+ if (unlikely(vfsub_native_ro(h_inode)
11756+ || IS_APPEND(h_inode)))
11757+ goto out;
11758+ flags &= ~O_ACCMODE;
11759+ flags |= O_WRONLY;
11760+ }
11761+ }
4a4d8108
AM
11762+ flags &= ~O_CREAT;
11763+ atomic_inc(&br->br_count);
11764+ h_path.dentry = h_dentry;
86dc4139 11765+ h_path.mnt = au_br_mnt(br);
38d290e6 11766+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
11767+ if (IS_ERR(h_file))
11768+ goto out_br;
dece6358 11769+
4a4d8108
AM
11770+ if (exec_flag) {
11771+ err = deny_write_access(h_file);
11772+ if (unlikely(err)) {
11773+ fput(h_file);
11774+ h_file = ERR_PTR(err);
11775+ goto out_br;
11776+ }
11777+ }
953406b4 11778+ fsnotify_open(h_file);
4a4d8108 11779+ goto out; /* success */
1facf9fc 11780+
4f0767ce 11781+out_br:
4a4d8108 11782+ atomic_dec(&br->br_count);
4f0767ce 11783+out:
4a4d8108
AM
11784+ return h_file;
11785+}
1308ab2a 11786+
076b876e
AM
11787+static int au_cmoo(struct dentry *dentry)
11788+{
11789+ int err, cmoo;
11790+ unsigned int udba;
11791+ struct path h_path;
11792+ struct au_pin pin;
11793+ struct au_cp_generic cpg = {
11794+ .dentry = dentry,
11795+ .bdst = -1,
11796+ .bsrc = -1,
11797+ .len = -1,
11798+ .pin = &pin,
11799+ .flags = AuCpup_DTIME | AuCpup_HOPEN
11800+ };
11801+ struct inode *inode, *delegated;
11802+ struct super_block *sb;
11803+ struct au_sbinfo *sbinfo;
11804+ struct au_fhsm *fhsm;
11805+ pid_t pid;
11806+ struct au_branch *br;
11807+ struct dentry *parent;
11808+ struct au_hinode *hdir;
11809+
11810+ DiMustWriteLock(dentry);
11811+ inode = dentry->d_inode;
11812+ IiMustWriteLock(inode);
11813+
11814+ err = 0;
11815+ if (IS_ROOT(dentry))
11816+ goto out;
11817+ cpg.bsrc = au_dbstart(dentry);
11818+ if (!cpg.bsrc)
11819+ goto out;
11820+
11821+ sb = dentry->d_sb;
11822+ sbinfo = au_sbi(sb);
11823+ fhsm = &sbinfo->si_fhsm;
11824+ pid = au_fhsm_pid(fhsm);
11825+ if (pid
11826+ && (current->pid == pid
11827+ || current->real_parent->pid == pid))
11828+ goto out;
11829+
11830+ br = au_sbr(sb, cpg.bsrc);
11831+ cmoo = au_br_cmoo(br->br_perm);
11832+ if (!cmoo)
11833+ goto out;
11834+ if (!S_ISREG(inode->i_mode))
11835+ cmoo &= AuBrAttr_COO_ALL;
11836+ if (!cmoo)
11837+ goto out;
11838+
11839+ parent = dget_parent(dentry);
11840+ di_write_lock_parent(parent);
11841+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
11842+ cpg.bdst = err;
11843+ if (unlikely(err < 0)) {
11844+ err = 0; /* there is no upper writable branch */
11845+ goto out_dgrade;
11846+ }
11847+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
11848+
11849+ /* do not respect the coo attrib for the target branch */
11850+ err = au_cpup_dirs(dentry, cpg.bdst);
11851+ if (unlikely(err))
11852+ goto out_dgrade;
11853+
11854+ di_downgrade_lock(parent, AuLock_IR);
11855+ udba = au_opt_udba(sb);
11856+ err = au_pin(&pin, dentry, cpg.bdst, udba,
11857+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
11858+ if (unlikely(err))
11859+ goto out_parent;
11860+
11861+ err = au_sio_cpup_simple(&cpg);
11862+ au_unpin(&pin);
11863+ if (unlikely(err))
11864+ goto out_parent;
11865+ if (!(cmoo & AuBrWAttr_MOO))
11866+ goto out_parent; /* success */
11867+
11868+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
11869+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
11870+ if (unlikely(err))
11871+ goto out_parent;
11872+
11873+ h_path.mnt = au_br_mnt(br);
11874+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
11875+ hdir = au_hi(parent->d_inode, cpg.bsrc);
11876+ delegated = NULL;
11877+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
11878+ au_unpin(&pin);
11879+ /* todo: keep h_dentry or not? */
11880+ if (unlikely(err == -EWOULDBLOCK)) {
11881+ pr_warn("cannot retry for NFSv4 delegation"
11882+ " for an internal unlink\n");
11883+ iput(delegated);
11884+ }
11885+ if (unlikely(err)) {
11886+ pr_err("unlink %pd after coo failed (%d), ignored\n",
11887+ dentry, err);
11888+ err = 0;
11889+ }
11890+ goto out_parent; /* success */
11891+
11892+out_dgrade:
11893+ di_downgrade_lock(parent, AuLock_IR);
11894+out_parent:
11895+ di_read_unlock(parent, AuLock_IR);
11896+ dput(parent);
11897+out:
11898+ AuTraceErr(err);
11899+ return err;
11900+}
11901+
4a4d8108
AM
11902+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
11903+ struct au_fidir *fidir)
1facf9fc 11904+{
dece6358 11905+ int err;
1facf9fc 11906+ struct dentry *dentry;
076b876e 11907+ struct au_finfo *finfo;
1308ab2a 11908+
4a4d8108
AM
11909+ err = au_finfo_init(file, fidir);
11910+ if (unlikely(err))
11911+ goto out;
1facf9fc 11912+
11913+ dentry = file->f_dentry;
076b876e
AM
11914+ di_write_lock_child(dentry);
11915+ err = au_cmoo(dentry);
11916+ di_downgrade_lock(dentry, AuLock_IR);
11917+ if (!err)
11918+ err = open(file, vfsub_file_flags(file));
4a4d8108 11919+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 11920+
076b876e
AM
11921+ finfo = au_fi(file);
11922+ if (!err) {
11923+ finfo->fi_file = file;
11924+ au_sphl_add(&finfo->fi_hlist,
11925+ &au_sbi(file->f_dentry->d_sb)->si_files);
11926+ }
4a4d8108
AM
11927+ fi_write_unlock(file);
11928+ if (unlikely(err)) {
076b876e 11929+ finfo->fi_hdir = NULL;
4a4d8108 11930+ au_finfo_fin(file);
1308ab2a 11931+ }
4a4d8108 11932+
4f0767ce 11933+out:
1308ab2a 11934+ return err;
11935+}
dece6358 11936+
4a4d8108 11937+int au_reopen_nondir(struct file *file)
1308ab2a 11938+{
4a4d8108
AM
11939+ int err;
11940+ aufs_bindex_t bstart;
11941+ struct dentry *dentry;
11942+ struct file *h_file, *h_file_tmp;
1308ab2a 11943+
4a4d8108 11944+ dentry = file->f_dentry;
4a4d8108
AM
11945+ bstart = au_dbstart(dentry);
11946+ h_file_tmp = NULL;
11947+ if (au_fbstart(file) == bstart) {
11948+ h_file = au_hf_top(file);
11949+ if (file->f_mode == h_file->f_mode)
11950+ return 0; /* success */
11951+ h_file_tmp = h_file;
11952+ get_file(h_file_tmp);
11953+ au_set_h_fptr(file, bstart, NULL);
11954+ }
11955+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
11956+ /*
11957+ * it can happen
11958+ * file exists on both of rw and ro
11959+ * open --> dbstart and fbstart are both 0
11960+ * prepend a branch as rw, "rw" become ro
11961+ * remove rw/file
11962+ * delete the top branch, "rw" becomes rw again
11963+ * --> dbstart is 1, fbstart is still 0
11964+ * write --> fbstart is 0 but dbstart is 1
11965+ */
11966+ /* AuDebugOn(au_fbstart(file) < bstart); */
1308ab2a 11967+
4a4d8108 11968+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
392086de 11969+ file, /*force_wr*/0);
4a4d8108 11970+ err = PTR_ERR(h_file);
86dc4139
AM
11971+ if (IS_ERR(h_file)) {
11972+ if (h_file_tmp) {
11973+ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
11974+ au_set_h_fptr(file, bstart, h_file_tmp);
11975+ h_file_tmp = NULL;
11976+ }
4a4d8108 11977+ goto out; /* todo: close all? */
86dc4139 11978+ }
4a4d8108
AM
11979+
11980+ err = 0;
11981+ au_set_fbstart(file, bstart);
11982+ au_set_h_fptr(file, bstart, h_file);
11983+ au_update_figen(file);
11984+ /* todo: necessary? */
11985+ /* file->f_ra = h_file->f_ra; */
11986+
4f0767ce 11987+out:
4a4d8108
AM
11988+ if (h_file_tmp)
11989+ fput(h_file_tmp);
11990+ return err;
1facf9fc 11991+}
11992+
1308ab2a 11993+/* ---------------------------------------------------------------------- */
11994+
4a4d8108
AM
11995+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
11996+ struct dentry *hi_wh)
1facf9fc 11997+{
4a4d8108
AM
11998+ int err;
11999+ aufs_bindex_t bstart;
12000+ struct au_dinfo *dinfo;
12001+ struct dentry *h_dentry;
12002+ struct au_hdentry *hdp;
1facf9fc 12003+
4a4d8108
AM
12004+ dinfo = au_di(file->f_dentry);
12005+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 12006+
4a4d8108
AM
12007+ bstart = dinfo->di_bstart;
12008+ dinfo->di_bstart = btgt;
12009+ hdp = dinfo->di_hdentry;
12010+ h_dentry = hdp[0 + btgt].hd_dentry;
12011+ hdp[0 + btgt].hd_dentry = hi_wh;
12012+ err = au_reopen_nondir(file);
12013+ hdp[0 + btgt].hd_dentry = h_dentry;
12014+ dinfo->di_bstart = bstart;
1facf9fc 12015+
1facf9fc 12016+ return err;
12017+}
12018+
4a4d8108 12019+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 12020+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 12021+{
4a4d8108 12022+ int err;
027c5e7a 12023+ struct inode *inode, *h_inode;
c2b27bf2
AM
12024+ struct dentry *h_dentry, *hi_wh;
12025+ struct au_cp_generic cpg = {
12026+ .dentry = file->f_dentry,
12027+ .bdst = bcpup,
12028+ .bsrc = -1,
12029+ .len = len,
12030+ .pin = pin
12031+ };
1facf9fc 12032+
c2b27bf2
AM
12033+ au_update_dbstart(cpg.dentry);
12034+ inode = cpg.dentry->d_inode;
027c5e7a 12035+ h_inode = NULL;
c2b27bf2
AM
12036+ if (au_dbstart(cpg.dentry) <= bcpup
12037+ && au_dbend(cpg.dentry) >= bcpup) {
12038+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
027c5e7a
AM
12039+ if (h_dentry)
12040+ h_inode = h_dentry->d_inode;
12041+ }
4a4d8108 12042+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 12043+ if (!hi_wh && !h_inode)
c2b27bf2 12044+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
12045+ else
12046+ /* already copied-up after unlink */
12047+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 12048+
4a4d8108 12049+ if (!err
38d290e6
JR
12050+ && (inode->i_nlink > 1
12051+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
12052+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
12053+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 12054+
dece6358 12055+ return err;
1facf9fc 12056+}
12057+
4a4d8108
AM
12058+/*
12059+ * prepare the @file for writing.
12060+ */
12061+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 12062+{
4a4d8108 12063+ int err;
c2b27bf2
AM
12064+ aufs_bindex_t dbstart;
12065+ struct dentry *parent, *h_dentry;
86dc4139 12066+ struct inode *inode;
1facf9fc 12067+ struct super_block *sb;
4a4d8108 12068+ struct file *h_file;
c2b27bf2
AM
12069+ struct au_cp_generic cpg = {
12070+ .dentry = file->f_dentry,
12071+ .bdst = -1,
12072+ .bsrc = -1,
12073+ .len = len,
12074+ .pin = pin,
12075+ .flags = AuCpup_DTIME
12076+ };
1facf9fc 12077+
c2b27bf2
AM
12078+ sb = cpg.dentry->d_sb;
12079+ inode = cpg.dentry->d_inode;
c2b27bf2
AM
12080+ cpg.bsrc = au_fbstart(file);
12081+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 12082+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
12083+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
12084+ /*flags*/0);
1facf9fc 12085+ goto out;
4a4d8108 12086+ }
1facf9fc 12087+
027c5e7a 12088+ /* need to cpup or reopen */
c2b27bf2 12089+ parent = dget_parent(cpg.dentry);
4a4d8108 12090+ di_write_lock_parent(parent);
c2b27bf2
AM
12091+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12092+ cpg.bdst = err;
4a4d8108
AM
12093+ if (unlikely(err < 0))
12094+ goto out_dgrade;
12095+ err = 0;
12096+
c2b27bf2
AM
12097+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
12098+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 12099+ if (unlikely(err))
4a4d8108
AM
12100+ goto out_dgrade;
12101+ }
12102+
c2b27bf2 12103+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
12104+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12105+ if (unlikely(err))
12106+ goto out_dgrade;
12107+
12108+ h_dentry = au_hf_top(file)->f_dentry;
c2b27bf2
AM
12109+ dbstart = au_dbstart(cpg.dentry);
12110+ if (dbstart <= cpg.bdst) {
12111+ h_dentry = au_h_dptr(cpg.dentry, cpg.bdst);
027c5e7a 12112+ AuDebugOn(!h_dentry);
c2b27bf2 12113+ cpg.bsrc = cpg.bdst;
027c5e7a
AM
12114+ }
12115+
c2b27bf2
AM
12116+ if (dbstart <= cpg.bdst /* just reopen */
12117+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 12118+ ) {
392086de 12119+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 12120+ if (IS_ERR(h_file))
027c5e7a 12121+ err = PTR_ERR(h_file);
86dc4139 12122+ else {
027c5e7a 12123+ di_downgrade_lock(parent, AuLock_IR);
c2b27bf2
AM
12124+ if (dbstart > cpg.bdst)
12125+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
12126+ if (!err)
12127+ err = au_reopen_nondir(file);
c2b27bf2 12128+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 12129+ }
027c5e7a
AM
12130+ } else { /* copyup as wh and reopen */
12131+ /*
12132+ * since writable hfsplus branch is not supported,
12133+ * h_open_pre/post() are unnecessary.
12134+ */
c2b27bf2 12135+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 12136+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 12137+ }
4a4d8108
AM
12138+
12139+ if (!err) {
12140+ au_pin_set_parent_lflag(pin, /*lflag*/0);
12141+ goto out_dput; /* success */
12142+ }
12143+ au_unpin(pin);
12144+ goto out_unlock;
1facf9fc 12145+
4f0767ce 12146+out_dgrade:
4a4d8108 12147+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 12148+out_unlock:
4a4d8108 12149+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12150+out_dput:
4a4d8108 12151+ dput(parent);
4f0767ce 12152+out:
1facf9fc 12153+ return err;
12154+}
12155+
4a4d8108
AM
12156+/* ---------------------------------------------------------------------- */
12157+
12158+int au_do_flush(struct file *file, fl_owner_t id,
12159+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 12160+{
4a4d8108 12161+ int err;
1facf9fc 12162+ struct super_block *sb;
4a4d8108 12163+ struct inode *inode;
1facf9fc 12164+
c06a8ce3
AM
12165+ inode = file_inode(file);
12166+ sb = inode->i_sb;
4a4d8108
AM
12167+ si_noflush_read_lock(sb);
12168+ fi_read_lock(file);
b752ccd1 12169+ ii_read_lock_child(inode);
1facf9fc 12170+
4a4d8108
AM
12171+ err = flush(file, id);
12172+ au_cpup_attr_timesizes(inode);
1facf9fc 12173+
b752ccd1 12174+ ii_read_unlock(inode);
4a4d8108 12175+ fi_read_unlock(file);
1308ab2a 12176+ si_read_unlock(sb);
dece6358 12177+ return err;
1facf9fc 12178+}
12179+
4a4d8108
AM
12180+/* ---------------------------------------------------------------------- */
12181+
12182+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 12183+{
4a4d8108 12184+ int err;
4a4d8108
AM
12185+ struct au_pin pin;
12186+ struct au_finfo *finfo;
c2b27bf2 12187+ struct dentry *parent, *hi_wh;
4a4d8108 12188+ struct inode *inode;
1facf9fc 12189+ struct super_block *sb;
c2b27bf2
AM
12190+ struct au_cp_generic cpg = {
12191+ .dentry = file->f_dentry,
12192+ .bdst = -1,
12193+ .bsrc = -1,
12194+ .len = -1,
12195+ .pin = &pin,
12196+ .flags = AuCpup_DTIME
12197+ };
1facf9fc 12198+
4a4d8108
AM
12199+ FiMustWriteLock(file);
12200+
12201+ err = 0;
12202+ finfo = au_fi(file);
c2b27bf2
AM
12203+ sb = cpg.dentry->d_sb;
12204+ inode = cpg.dentry->d_inode;
12205+ cpg.bdst = au_ibstart(inode);
12206+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 12207+ goto out;
dece6358 12208+
c2b27bf2
AM
12209+ parent = dget_parent(cpg.dentry);
12210+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 12211+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
12212+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12213+ cpg.bdst = err;
4a4d8108
AM
12214+ di_read_unlock(parent, !AuLock_IR);
12215+ if (unlikely(err < 0))
12216+ goto out_parent;
12217+ err = 0;
1facf9fc 12218+ }
1facf9fc 12219+
4a4d8108 12220+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 12221+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
12222+ if (!S_ISDIR(inode->i_mode)
12223+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 12224+ && au_plink_test(inode)
c2b27bf2
AM
12225+ && !d_unhashed(cpg.dentry)
12226+ && cpg.bdst < au_dbstart(cpg.dentry)) {
12227+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
12228+ if (unlikely(err))
12229+ goto out_unlock;
12230+
12231+ /* always superio. */
c2b27bf2 12232+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 12233+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 12234+ if (!err) {
c2b27bf2 12235+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
12236+ au_unpin(&pin);
12237+ }
4a4d8108
AM
12238+ } else if (hi_wh) {
12239+ /* already copied-up after unlink */
c2b27bf2 12240+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
12241+ *need_reopen = 0;
12242+ }
1facf9fc 12243+
4f0767ce 12244+out_unlock:
4a4d8108 12245+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12246+out_parent:
4a4d8108 12247+ dput(parent);
4f0767ce 12248+out:
1308ab2a 12249+ return err;
dece6358 12250+}
1facf9fc 12251+
4a4d8108 12252+static void au_do_refresh_dir(struct file *file)
dece6358 12253+{
4a4d8108
AM
12254+ aufs_bindex_t bindex, bend, new_bindex, brid;
12255+ struct au_hfile *p, tmp, *q;
12256+ struct au_finfo *finfo;
1308ab2a 12257+ struct super_block *sb;
4a4d8108 12258+ struct au_fidir *fidir;
1facf9fc 12259+
4a4d8108 12260+ FiMustWriteLock(file);
1facf9fc 12261+
4a4d8108
AM
12262+ sb = file->f_dentry->d_sb;
12263+ finfo = au_fi(file);
12264+ fidir = finfo->fi_hdir;
12265+ AuDebugOn(!fidir);
12266+ p = fidir->fd_hfile + finfo->fi_btop;
12267+ brid = p->hf_br->br_id;
12268+ bend = fidir->fd_bbot;
12269+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
12270+ if (!p->hf_file)
12271+ continue;
1308ab2a 12272+
4a4d8108
AM
12273+ new_bindex = au_br_index(sb, p->hf_br->br_id);
12274+ if (new_bindex == bindex)
12275+ continue;
12276+ if (new_bindex < 0) {
12277+ au_set_h_fptr(file, bindex, NULL);
12278+ continue;
12279+ }
1308ab2a 12280+
4a4d8108
AM
12281+ /* swap two lower inode, and loop again */
12282+ q = fidir->fd_hfile + new_bindex;
12283+ tmp = *q;
12284+ *q = *p;
12285+ *p = tmp;
12286+ if (tmp.hf_file) {
12287+ bindex--;
12288+ p--;
12289+ }
12290+ }
1308ab2a 12291+
4a4d8108 12292+ p = fidir->fd_hfile;
027c5e7a 12293+ if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
4a4d8108
AM
12294+ bend = au_sbend(sb);
12295+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
12296+ finfo->fi_btop++, p++)
12297+ if (p->hf_file) {
c06a8ce3 12298+ if (file_inode(p->hf_file))
4a4d8108
AM
12299+ break;
12300+ else
12301+ au_hfput(p, file);
12302+ }
12303+ } else {
12304+ bend = au_br_index(sb, brid);
12305+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
12306+ finfo->fi_btop++, p++)
12307+ if (p->hf_file)
12308+ au_hfput(p, file);
12309+ bend = au_sbend(sb);
12310+ }
1308ab2a 12311+
4a4d8108
AM
12312+ p = fidir->fd_hfile + bend;
12313+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
12314+ fidir->fd_bbot--, p--)
12315+ if (p->hf_file) {
c06a8ce3 12316+ if (file_inode(p->hf_file))
4a4d8108
AM
12317+ break;
12318+ else
12319+ au_hfput(p, file);
12320+ }
12321+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 12322+}
12323+
4a4d8108
AM
12324+/*
12325+ * after branch manipulating, refresh the file.
12326+ */
12327+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 12328+{
4a4d8108
AM
12329+ int err, need_reopen;
12330+ aufs_bindex_t bend, bindex;
12331+ struct dentry *dentry;
1308ab2a 12332+ struct au_finfo *finfo;
4a4d8108 12333+ struct au_hfile *hfile;
1facf9fc 12334+
4a4d8108 12335+ dentry = file->f_dentry;
1308ab2a 12336+ finfo = au_fi(file);
4a4d8108
AM
12337+ if (!finfo->fi_hdir) {
12338+ hfile = &finfo->fi_htop;
12339+ AuDebugOn(!hfile->hf_file);
12340+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
12341+ AuDebugOn(bindex < 0);
12342+ if (bindex != finfo->fi_btop)
12343+ au_set_fbstart(file, bindex);
12344+ } else {
12345+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
12346+ if (unlikely(err))
12347+ goto out;
12348+ au_do_refresh_dir(file);
12349+ }
1facf9fc 12350+
4a4d8108
AM
12351+ err = 0;
12352+ need_reopen = 1;
12353+ if (!au_test_mmapped(file))
12354+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 12355+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
12356+ err = reopen(file);
12357+ if (!err) {
12358+ au_update_figen(file);
12359+ goto out; /* success */
12360+ }
12361+
12362+ /* error, close all lower files */
12363+ if (finfo->fi_hdir) {
12364+ bend = au_fbend_dir(file);
12365+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
12366+ au_set_h_fptr(file, bindex, NULL);
12367+ }
1facf9fc 12368+
4f0767ce 12369+out:
1facf9fc 12370+ return err;
12371+}
12372+
4a4d8108
AM
12373+/* common function to regular file and dir */
12374+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12375+ int wlock)
dece6358 12376+{
1308ab2a 12377+ int err;
4a4d8108
AM
12378+ unsigned int sigen, figen;
12379+ aufs_bindex_t bstart;
12380+ unsigned char pseudo_link;
12381+ struct dentry *dentry;
12382+ struct inode *inode;
1facf9fc 12383+
4a4d8108
AM
12384+ err = 0;
12385+ dentry = file->f_dentry;
12386+ inode = dentry->d_inode;
4a4d8108
AM
12387+ sigen = au_sigen(dentry->d_sb);
12388+ fi_write_lock(file);
12389+ figen = au_figen(file);
12390+ di_write_lock_child(dentry);
12391+ bstart = au_dbstart(dentry);
12392+ pseudo_link = (bstart != au_ibstart(inode));
12393+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
12394+ if (!wlock) {
12395+ di_downgrade_lock(dentry, AuLock_IR);
12396+ fi_downgrade_lock(file);
12397+ }
12398+ goto out; /* success */
12399+ }
dece6358 12400+
4a4d8108 12401+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 12402+ if (au_digen_test(dentry, sigen)) {
4a4d8108 12403+ err = au_reval_dpath(dentry, sigen);
027c5e7a 12404+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 12405+ }
dece6358 12406+
027c5e7a
AM
12407+ if (!err)
12408+ err = refresh_file(file, reopen);
4a4d8108
AM
12409+ if (!err) {
12410+ if (!wlock) {
12411+ di_downgrade_lock(dentry, AuLock_IR);
12412+ fi_downgrade_lock(file);
12413+ }
12414+ } else {
12415+ di_write_unlock(dentry);
12416+ fi_write_unlock(file);
12417+ }
1facf9fc 12418+
4f0767ce 12419+out:
1308ab2a 12420+ return err;
12421+}
1facf9fc 12422+
4a4d8108
AM
12423+/* ---------------------------------------------------------------------- */
12424+
12425+/* cf. aufs_nopage() */
12426+/* for madvise(2) */
12427+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 12428+{
4a4d8108
AM
12429+ unlock_page(page);
12430+ return 0;
12431+}
1facf9fc 12432+
4a4d8108
AM
12433+/* it will never be called, but necessary to support O_DIRECT */
12434+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
076b876e 12435+ struct iov_iter *iter, loff_t offset)
4a4d8108 12436+{ BUG(); return 0; }
1facf9fc 12437+
4a4d8108
AM
12438+/*
12439+ * it will never be called, but madvise and fadvise behaves differently
12440+ * when get_xip_mem is defined
12441+ */
12442+static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
12443+ int create, void **kmem, unsigned long *pfn)
12444+{ BUG(); return 0; }
1facf9fc 12445+
4a4d8108
AM
12446+/* they will never be called. */
12447+#ifdef CONFIG_AUFS_DEBUG
12448+static int aufs_write_begin(struct file *file, struct address_space *mapping,
12449+ loff_t pos, unsigned len, unsigned flags,
12450+ struct page **pagep, void **fsdata)
12451+{ AuUnsupport(); return 0; }
12452+static int aufs_write_end(struct file *file, struct address_space *mapping,
12453+ loff_t pos, unsigned len, unsigned copied,
12454+ struct page *page, void *fsdata)
12455+{ AuUnsupport(); return 0; }
12456+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
12457+{ AuUnsupport(); return 0; }
1308ab2a 12458+
4a4d8108
AM
12459+static int aufs_set_page_dirty(struct page *page)
12460+{ AuUnsupport(); return 0; }
392086de
AM
12461+static void aufs_invalidatepage(struct page *page, unsigned int offset,
12462+ unsigned int length)
4a4d8108
AM
12463+{ AuUnsupport(); }
12464+static int aufs_releasepage(struct page *page, gfp_t gfp)
12465+{ AuUnsupport(); return 0; }
12466+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 12467+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
12468+{ AuUnsupport(); return 0; }
12469+static int aufs_launder_page(struct page *page)
12470+{ AuUnsupport(); return 0; }
12471+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
12472+ unsigned long from,
12473+ unsigned long count)
4a4d8108 12474+{ AuUnsupport(); return 0; }
392086de
AM
12475+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
12476+ bool *writeback)
12477+{ AuUnsupport(); }
4a4d8108
AM
12478+static int aufs_error_remove_page(struct address_space *mapping,
12479+ struct page *page)
12480+{ AuUnsupport(); return 0; }
b4510431
AM
12481+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
12482+ sector_t *span)
12483+{ AuUnsupport(); return 0; }
12484+static void aufs_swap_deactivate(struct file *file)
12485+{ AuUnsupport(); }
4a4d8108
AM
12486+#endif /* CONFIG_AUFS_DEBUG */
12487+
12488+const struct address_space_operations aufs_aop = {
12489+ .readpage = aufs_readpage,
12490+ .direct_IO = aufs_direct_IO,
12491+ .get_xip_mem = aufs_get_xip_mem,
12492+#ifdef CONFIG_AUFS_DEBUG
12493+ .writepage = aufs_writepage,
4a4d8108
AM
12494+ /* no writepages, because of writepage */
12495+ .set_page_dirty = aufs_set_page_dirty,
12496+ /* no readpages, because of readpage */
12497+ .write_begin = aufs_write_begin,
12498+ .write_end = aufs_write_end,
12499+ /* no bmap, no block device */
12500+ .invalidatepage = aufs_invalidatepage,
12501+ .releasepage = aufs_releasepage,
12502+ .migratepage = aufs_migratepage,
12503+ .launder_page = aufs_launder_page,
12504+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 12505+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
12506+ .error_remove_page = aufs_error_remove_page,
12507+ .swap_activate = aufs_swap_activate,
12508+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 12509+#endif /* CONFIG_AUFS_DEBUG */
dece6358 12510+};
7f207e10
AM
12511diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
12512--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
076b876e 12513+++ linux/fs/aufs/file.h 2014-08-14 10:15:45.121942630 +0200
38d290e6 12514@@ -0,0 +1,289 @@
4a4d8108 12515+/*
523b37e3 12516+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
12517+ *
12518+ * This program, aufs is free software; you can redistribute it and/or modify
12519+ * it under the terms of the GNU General Public License as published by
12520+ * the Free Software Foundation; either version 2 of the License, or
12521+ * (at your option) any later version.
12522+ *
12523+ * This program is distributed in the hope that it will be useful,
12524+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12525+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12526+ * GNU General Public License for more details.
12527+ *
12528+ * You should have received a copy of the GNU General Public License
523b37e3 12529+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12530+ */
1facf9fc 12531+
4a4d8108
AM
12532+/*
12533+ * file operations
12534+ */
1facf9fc 12535+
4a4d8108
AM
12536+#ifndef __AUFS_FILE_H__
12537+#define __AUFS_FILE_H__
1facf9fc 12538+
4a4d8108 12539+#ifdef __KERNEL__
1facf9fc 12540+
2cbb1c4b 12541+#include <linux/file.h>
4a4d8108
AM
12542+#include <linux/fs.h>
12543+#include <linux/poll.h>
4a4d8108 12544+#include "rwsem.h"
1facf9fc 12545+
4a4d8108
AM
12546+struct au_branch;
12547+struct au_hfile {
12548+ struct file *hf_file;
12549+ struct au_branch *hf_br;
12550+};
1facf9fc 12551+
4a4d8108
AM
12552+struct au_vdir;
12553+struct au_fidir {
12554+ aufs_bindex_t fd_bbot;
12555+ aufs_bindex_t fd_nent;
12556+ struct au_vdir *fd_vdir_cache;
12557+ struct au_hfile fd_hfile[];
12558+};
1facf9fc 12559+
4a4d8108 12560+static inline int au_fidir_sz(int nent)
dece6358 12561+{
4f0767ce
JR
12562+ AuDebugOn(nent < 0);
12563+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 12564+}
1facf9fc 12565+
4a4d8108
AM
12566+struct au_finfo {
12567+ atomic_t fi_generation;
dece6358 12568+
4a4d8108
AM
12569+ struct au_rwsem fi_rwsem;
12570+ aufs_bindex_t fi_btop;
12571+
12572+ /* do not union them */
12573+ struct { /* for non-dir */
12574+ struct au_hfile fi_htop;
2cbb1c4b 12575+ atomic_t fi_mmapped;
4a4d8108
AM
12576+ };
12577+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3
AM
12578+
12579+ struct hlist_node fi_hlist;
12580+ struct file *fi_file; /* very ugly */
4a4d8108 12581+} ____cacheline_aligned_in_smp;
1facf9fc 12582+
4a4d8108 12583+/* ---------------------------------------------------------------------- */
1facf9fc 12584+
4a4d8108
AM
12585+/* file.c */
12586+extern const struct address_space_operations aufs_aop;
12587+unsigned int au_file_roflags(unsigned int flags);
12588+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 12589+ struct file *file, int force_wr);
4a4d8108
AM
12590+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
12591+ struct au_fidir *fidir);
12592+int au_reopen_nondir(struct file *file);
12593+struct au_pin;
12594+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
12595+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12596+ int wlock);
12597+int au_do_flush(struct file *file, fl_owner_t id,
12598+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 12599+
4a4d8108
AM
12600+/* poll.c */
12601+#ifdef CONFIG_AUFS_POLL
12602+unsigned int aufs_poll(struct file *file, poll_table *wait);
12603+#endif
1facf9fc 12604+
4a4d8108
AM
12605+#ifdef CONFIG_AUFS_BR_HFSPLUS
12606+/* hfsplus.c */
392086de
AM
12607+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
12608+ int force_wr);
4a4d8108
AM
12609+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
12610+ struct file *h_file);
12611+#else
12612+static inline
392086de
AM
12613+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
12614+ int force_wr)
dece6358 12615+{
4a4d8108
AM
12616+ return NULL;
12617+}
1facf9fc 12618+
4a4d8108
AM
12619+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
12620+ struct file *h_file);
12621+#endif
1facf9fc 12622+
4a4d8108
AM
12623+/* f_op.c */
12624+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
12625+int au_do_open_nondir(struct file *file, int flags);
12626+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
12627+
4a4d8108
AM
12628+/* finfo.c */
12629+void au_hfput(struct au_hfile *hf, struct file *file);
12630+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
12631+ struct file *h_file);
1facf9fc 12632+
4a4d8108 12633+void au_update_figen(struct file *file);
4a4d8108
AM
12634+struct au_fidir *au_fidir_alloc(struct super_block *sb);
12635+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 12636+
4a4d8108
AM
12637+void au_fi_init_once(void *_fi);
12638+void au_finfo_fin(struct file *file);
12639+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 12640+
4a4d8108
AM
12641+/* ioctl.c */
12642+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
12643+#ifdef CONFIG_COMPAT
12644+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
12645+ unsigned long arg);
c2b27bf2
AM
12646+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
12647+ unsigned long arg);
b752ccd1 12648+#endif
1facf9fc 12649+
4a4d8108 12650+/* ---------------------------------------------------------------------- */
1facf9fc 12651+
4a4d8108
AM
12652+static inline struct au_finfo *au_fi(struct file *file)
12653+{
38d290e6 12654+ return file->private_data;
4a4d8108 12655+}
1facf9fc 12656+
4a4d8108 12657+/* ---------------------------------------------------------------------- */
1facf9fc 12658+
4a4d8108
AM
12659+/*
12660+ * fi_read_lock, fi_write_lock,
12661+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
12662+ */
12663+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 12664+
4a4d8108
AM
12665+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
12666+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
12667+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 12668+
1308ab2a 12669+/* ---------------------------------------------------------------------- */
12670+
4a4d8108
AM
12671+/* todo: hard/soft set? */
12672+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 12673+{
4a4d8108
AM
12674+ FiMustAnyLock(file);
12675+ return au_fi(file)->fi_btop;
12676+}
dece6358 12677+
4a4d8108
AM
12678+static inline aufs_bindex_t au_fbend_dir(struct file *file)
12679+{
12680+ FiMustAnyLock(file);
12681+ AuDebugOn(!au_fi(file)->fi_hdir);
12682+ return au_fi(file)->fi_hdir->fd_bbot;
12683+}
1facf9fc 12684+
4a4d8108
AM
12685+static inline struct au_vdir *au_fvdir_cache(struct file *file)
12686+{
12687+ FiMustAnyLock(file);
12688+ AuDebugOn(!au_fi(file)->fi_hdir);
12689+ return au_fi(file)->fi_hdir->fd_vdir_cache;
12690+}
1facf9fc 12691+
4a4d8108
AM
12692+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
12693+{
12694+ FiMustWriteLock(file);
12695+ au_fi(file)->fi_btop = bindex;
12696+}
1facf9fc 12697+
4a4d8108
AM
12698+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
12699+{
12700+ FiMustWriteLock(file);
12701+ AuDebugOn(!au_fi(file)->fi_hdir);
12702+ au_fi(file)->fi_hdir->fd_bbot = bindex;
12703+}
1308ab2a 12704+
4a4d8108
AM
12705+static inline void au_set_fvdir_cache(struct file *file,
12706+ struct au_vdir *vdir_cache)
12707+{
12708+ FiMustWriteLock(file);
12709+ AuDebugOn(!au_fi(file)->fi_hdir);
12710+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
12711+}
dece6358 12712+
4a4d8108
AM
12713+static inline struct file *au_hf_top(struct file *file)
12714+{
12715+ FiMustAnyLock(file);
12716+ AuDebugOn(au_fi(file)->fi_hdir);
12717+ return au_fi(file)->fi_htop.hf_file;
12718+}
1facf9fc 12719+
4a4d8108
AM
12720+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
12721+{
12722+ FiMustAnyLock(file);
12723+ AuDebugOn(!au_fi(file)->fi_hdir);
12724+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
12725+}
12726+
4a4d8108
AM
12727+/* todo: memory barrier? */
12728+static inline unsigned int au_figen(struct file *f)
dece6358 12729+{
4a4d8108
AM
12730+ return atomic_read(&au_fi(f)->fi_generation);
12731+}
dece6358 12732+
2cbb1c4b
JR
12733+static inline void au_set_mmapped(struct file *f)
12734+{
12735+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
12736+ return;
0c3ec466 12737+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
12738+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
12739+ ;
12740+}
12741+
12742+static inline void au_unset_mmapped(struct file *f)
12743+{
12744+ atomic_dec(&au_fi(f)->fi_mmapped);
12745+}
12746+
4a4d8108
AM
12747+static inline int au_test_mmapped(struct file *f)
12748+{
2cbb1c4b
JR
12749+ return atomic_read(&au_fi(f)->fi_mmapped);
12750+}
12751+
12752+/* customize vma->vm_file */
12753+
12754+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
12755+ struct file *file)
12756+{
53392da6
AM
12757+ struct file *f;
12758+
12759+ f = vma->vm_file;
2cbb1c4b
JR
12760+ get_file(file);
12761+ vma->vm_file = file;
53392da6 12762+ fput(f);
2cbb1c4b
JR
12763+}
12764+
12765+#ifdef CONFIG_MMU
12766+#define AuDbgVmRegion(file, vma) do {} while (0)
12767+
12768+static inline void au_vm_file_reset(struct vm_area_struct *vma,
12769+ struct file *file)
12770+{
12771+ au_do_vm_file_reset(vma, file);
12772+}
12773+#else
12774+#define AuDbgVmRegion(file, vma) \
12775+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
12776+
12777+static inline void au_vm_file_reset(struct vm_area_struct *vma,
12778+ struct file *file)
12779+{
53392da6
AM
12780+ struct file *f;
12781+
2cbb1c4b 12782+ au_do_vm_file_reset(vma, file);
53392da6 12783+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
12784+ get_file(file);
12785+ vma->vm_region->vm_file = file;
53392da6 12786+ fput(f);
2cbb1c4b
JR
12787+}
12788+#endif /* CONFIG_MMU */
12789+
12790+/* handle vma->vm_prfile */
fb47a38f 12791+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
12792+ struct file *file)
12793+{
2cbb1c4b
JR
12794+ get_file(file);
12795+ vma->vm_prfile = file;
12796+#ifndef CONFIG_MMU
12797+ get_file(file);
12798+ vma->vm_region->vm_prfile = file;
12799+#endif
fb47a38f 12800+}
1308ab2a 12801+
4a4d8108
AM
12802+#endif /* __KERNEL__ */
12803+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
12804diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
12805--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
076b876e 12806+++ linux/fs/aufs/finfo.c 2014-01-30 21:10:02.850815069 +0100
523b37e3 12807@@ -0,0 +1,156 @@
4a4d8108 12808+/*
523b37e3 12809+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
12810+ *
12811+ * This program, aufs is free software; you can redistribute it and/or modify
12812+ * it under the terms of the GNU General Public License as published by
12813+ * the Free Software Foundation; either version 2 of the License, or
12814+ * (at your option) any later version.
12815+ *
12816+ * This program is distributed in the hope that it will be useful,
12817+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12818+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12819+ * GNU General Public License for more details.
12820+ *
12821+ * You should have received a copy of the GNU General Public License
523b37e3 12822+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12823+ */
1308ab2a 12824+
4a4d8108
AM
12825+/*
12826+ * file private data
12827+ */
1facf9fc 12828+
4a4d8108 12829+#include "aufs.h"
1facf9fc 12830+
4a4d8108
AM
12831+void au_hfput(struct au_hfile *hf, struct file *file)
12832+{
12833+ /* todo: direct access f_flags */
2cbb1c4b 12834+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
12835+ allow_write_access(hf->hf_file);
12836+ fput(hf->hf_file);
12837+ hf->hf_file = NULL;
e49829fe 12838+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
12839+ hf->hf_br = NULL;
12840+}
1facf9fc 12841+
4a4d8108
AM
12842+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
12843+{
12844+ struct au_finfo *finfo = au_fi(file);
12845+ struct au_hfile *hf;
12846+ struct au_fidir *fidir;
12847+
12848+ fidir = finfo->fi_hdir;
12849+ if (!fidir) {
12850+ AuDebugOn(finfo->fi_btop != bindex);
12851+ hf = &finfo->fi_htop;
12852+ } else
12853+ hf = fidir->fd_hfile + bindex;
12854+
12855+ if (hf && hf->hf_file)
12856+ au_hfput(hf, file);
12857+ if (val) {
12858+ FiMustWriteLock(file);
12859+ hf->hf_file = val;
12860+ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
1308ab2a 12861+ }
4a4d8108 12862+}
1facf9fc 12863+
4a4d8108
AM
12864+void au_update_figen(struct file *file)
12865+{
12866+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
12867+ /* smp_mb(); */ /* atomic_set */
1facf9fc 12868+}
12869+
4a4d8108
AM
12870+/* ---------------------------------------------------------------------- */
12871+
4a4d8108
AM
12872+struct au_fidir *au_fidir_alloc(struct super_block *sb)
12873+{
12874+ struct au_fidir *fidir;
12875+ int nbr;
12876+
12877+ nbr = au_sbend(sb) + 1;
12878+ if (nbr < 2)
12879+ nbr = 2; /* initial allocate for 2 branches */
12880+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
12881+ if (fidir) {
12882+ fidir->fd_bbot = -1;
12883+ fidir->fd_nent = nbr;
12884+ fidir->fd_vdir_cache = NULL;
12885+ }
12886+
12887+ return fidir;
12888+}
12889+
12890+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
12891+{
12892+ int err;
12893+ struct au_fidir *fidir, *p;
12894+
12895+ AuRwMustWriteLock(&finfo->fi_rwsem);
12896+ fidir = finfo->fi_hdir;
12897+ AuDebugOn(!fidir);
12898+
12899+ err = -ENOMEM;
12900+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
12901+ GFP_NOFS);
12902+ if (p) {
12903+ p->fd_nent = nbr;
12904+ finfo->fi_hdir = p;
12905+ err = 0;
12906+ }
1facf9fc 12907+
dece6358 12908+ return err;
1facf9fc 12909+}
1308ab2a 12910+
12911+/* ---------------------------------------------------------------------- */
12912+
4a4d8108 12913+void au_finfo_fin(struct file *file)
1308ab2a 12914+{
4a4d8108
AM
12915+ struct au_finfo *finfo;
12916+
7f207e10
AM
12917+ au_nfiles_dec(file->f_dentry->d_sb);
12918+
4a4d8108
AM
12919+ finfo = au_fi(file);
12920+ AuDebugOn(finfo->fi_hdir);
12921+ AuRwDestroy(&finfo->fi_rwsem);
12922+ au_cache_free_finfo(finfo);
1308ab2a 12923+}
1308ab2a 12924+
e49829fe 12925+void au_fi_init_once(void *_finfo)
4a4d8108 12926+{
e49829fe 12927+ struct au_finfo *finfo = _finfo;
2cbb1c4b 12928+ static struct lock_class_key aufs_fi;
1308ab2a 12929+
e49829fe
JR
12930+ au_rw_init(&finfo->fi_rwsem);
12931+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 12932+}
1308ab2a 12933+
4a4d8108
AM
12934+int au_finfo_init(struct file *file, struct au_fidir *fidir)
12935+{
1716fcea 12936+ int err;
4a4d8108
AM
12937+ struct au_finfo *finfo;
12938+ struct dentry *dentry;
12939+
12940+ err = -ENOMEM;
12941+ dentry = file->f_dentry;
12942+ finfo = au_cache_alloc_finfo();
12943+ if (unlikely(!finfo))
12944+ goto out;
12945+
12946+ err = 0;
7f207e10 12947+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
12948+ /* verbose coding for lock class name */
12949+ if (!fidir)
12950+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
12951+ else
12952+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
12953+ au_rw_write_lock(&finfo->fi_rwsem);
12954+ finfo->fi_btop = -1;
12955+ finfo->fi_hdir = fidir;
12956+ atomic_set(&finfo->fi_generation, au_digen(dentry));
12957+ /* smp_mb(); */ /* atomic_set */
12958+
12959+ file->private_data = finfo;
12960+
12961+out:
12962+ return err;
12963+}
7f207e10
AM
12964diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
12965--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
12966+++ linux/fs/aufs/f_op.c 2014-08-14 10:16:04.515942371 +0200
12967@@ -0,0 +1,813 @@
dece6358 12968+/*
523b37e3 12969+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
12970+ *
12971+ * This program, aufs is free software; you can redistribute it and/or modify
12972+ * it under the terms of the GNU General Public License as published by
12973+ * the Free Software Foundation; either version 2 of the License, or
12974+ * (at your option) any later version.
12975+ *
12976+ * This program is distributed in the hope that it will be useful,
12977+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12978+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12979+ * GNU General Public License for more details.
12980+ *
12981+ * You should have received a copy of the GNU General Public License
523b37e3 12982+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 12983+ */
1facf9fc 12984+
12985+/*
4a4d8108 12986+ * file and vm operations
1facf9fc 12987+ */
dece6358 12988+
86dc4139 12989+#include <linux/aio.h>
4a4d8108
AM
12990+#include <linux/fs_stack.h>
12991+#include <linux/mman.h>
4a4d8108 12992+#include <linux/security.h>
dece6358
AM
12993+#include "aufs.h"
12994+
4a4d8108 12995+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 12996+{
4a4d8108
AM
12997+ int err;
12998+ aufs_bindex_t bindex;
12999+ struct file *h_file;
13000+ struct dentry *dentry;
13001+ struct au_finfo *finfo;
38d290e6 13002+ struct inode *h_inode;
4a4d8108
AM
13003+
13004+ FiMustWriteLock(file);
13005+
523b37e3 13006+ err = 0;
4a4d8108
AM
13007+ dentry = file->f_dentry;
13008+ finfo = au_fi(file);
13009+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 13010+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108 13011+ bindex = au_dbstart(dentry);
392086de 13012+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
4a4d8108
AM
13013+ if (IS_ERR(h_file))
13014+ err = PTR_ERR(h_file);
13015+ else {
38d290e6
JR
13016+ if ((flags & __O_TMPFILE)
13017+ && !(flags & O_EXCL)) {
13018+ h_inode = file_inode(h_file);
13019+ spin_lock(&h_inode->i_lock);
13020+ h_inode->i_state |= I_LINKABLE;
13021+ spin_unlock(&h_inode->i_lock);
13022+ }
4a4d8108
AM
13023+ au_set_fbstart(file, bindex);
13024+ au_set_h_fptr(file, bindex, h_file);
13025+ au_update_figen(file);
13026+ /* todo: necessary? */
13027+ /* file->f_ra = h_file->f_ra; */
13028+ }
027c5e7a 13029+
4a4d8108 13030+ return err;
1facf9fc 13031+}
13032+
4a4d8108
AM
13033+static int aufs_open_nondir(struct inode *inode __maybe_unused,
13034+ struct file *file)
1facf9fc 13035+{
4a4d8108 13036+ int err;
1308ab2a 13037+ struct super_block *sb;
1facf9fc 13038+
523b37e3
AM
13039+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
13040+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 13041+
4a4d8108
AM
13042+ sb = file->f_dentry->d_sb;
13043+ si_read_lock(sb, AuLock_FLUSH);
13044+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
13045+ si_read_unlock(sb);
13046+ return err;
13047+}
1facf9fc 13048+
4a4d8108
AM
13049+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
13050+{
13051+ struct au_finfo *finfo;
13052+ aufs_bindex_t bindex;
1facf9fc 13053+
4a4d8108 13054+ finfo = au_fi(file);
523b37e3 13055+ au_sphl_del(&finfo->fi_hlist, &au_sbi(file->f_dentry->d_sb)->si_files);
4a4d8108 13056+ bindex = finfo->fi_btop;
b4510431 13057+ if (bindex >= 0)
4a4d8108 13058+ au_set_h_fptr(file, bindex, NULL);
7f207e10 13059+
4a4d8108
AM
13060+ au_finfo_fin(file);
13061+ return 0;
1facf9fc 13062+}
13063+
4a4d8108
AM
13064+/* ---------------------------------------------------------------------- */
13065+
13066+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 13067+{
1308ab2a 13068+ int err;
4a4d8108
AM
13069+ struct file *h_file;
13070+
13071+ err = 0;
13072+ h_file = au_hf_top(file);
13073+ if (h_file)
13074+ err = vfsub_flush(h_file, id);
13075+ return err;
13076+}
13077+
13078+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
13079+{
13080+ return au_do_flush(file, id, au_do_flush_nondir);
13081+}
13082+
13083+/* ---------------------------------------------------------------------- */
9dbd164d
AM
13084+/*
13085+ * read and write functions acquire [fdi]_rwsem once, but release before
13086+ * mmap_sem. This is because to stop a race condition between mmap(2).
13087+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
13088+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
13089+ * read functions after [fdi]_rwsem are released, but it should be harmless.
13090+ */
4a4d8108
AM
13091+
13092+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
13093+ loff_t *ppos)
13094+{
13095+ ssize_t err;
dece6358 13096+ struct dentry *dentry;
4a4d8108 13097+ struct file *h_file;
dece6358 13098+ struct super_block *sb;
1facf9fc 13099+
dece6358
AM
13100+ dentry = file->f_dentry;
13101+ sb = dentry->d_sb;
e49829fe 13102+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 13103+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
13104+ if (unlikely(err))
13105+ goto out;
1facf9fc 13106+
4a4d8108 13107+ h_file = au_hf_top(file);
9dbd164d
AM
13108+ get_file(h_file);
13109+ di_read_unlock(dentry, AuLock_IR);
13110+ fi_read_unlock(file);
13111+
13112+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
13113+ err = vfsub_read_u(h_file, buf, count, ppos);
13114+ /* todo: necessary? */
13115+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13116+ /* update without lock, I don't think it a problem */
c06a8ce3 13117+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13118+ fput(h_file);
1308ab2a 13119+
4f0767ce 13120+out:
dece6358
AM
13121+ si_read_unlock(sb);
13122+ return err;
13123+}
1facf9fc 13124+
e49829fe
JR
13125+/*
13126+ * todo: very ugly
13127+ * it locks both of i_mutex and si_rwsem for read in safe.
13128+ * if the plink maintenance mode continues forever (that is the problem),
13129+ * may loop forever.
13130+ */
13131+static void au_mtx_and_read_lock(struct inode *inode)
13132+{
13133+ int err;
13134+ struct super_block *sb = inode->i_sb;
13135+
13136+ while (1) {
13137+ mutex_lock(&inode->i_mutex);
13138+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13139+ if (!err)
13140+ break;
13141+ mutex_unlock(&inode->i_mutex);
13142+ si_read_lock(sb, AuLock_NOPLMW);
13143+ si_read_unlock(sb);
13144+ }
13145+}
13146+
4a4d8108
AM
13147+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
13148+ size_t count, loff_t *ppos)
dece6358 13149+{
4a4d8108 13150+ ssize_t err;
076b876e
AM
13151+ blkcnt_t blks;
13152+ aufs_bindex_t bstart;
4a4d8108 13153+ struct au_pin pin;
dece6358 13154+ struct dentry *dentry;
076b876e 13155+ struct inode *inode, *h_inode;
9dbd164d 13156+ struct super_block *sb;
4a4d8108
AM
13157+ struct file *h_file;
13158+ char __user *buf = (char __user *)ubuf;
1facf9fc 13159+
dece6358 13160+ dentry = file->f_dentry;
9dbd164d 13161+ sb = dentry->d_sb;
4a4d8108 13162+ inode = dentry->d_inode;
e49829fe 13163+ au_mtx_and_read_lock(inode);
1facf9fc 13164+
4a4d8108
AM
13165+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13166+ if (unlikely(err))
13167+ goto out;
1facf9fc 13168+
4a4d8108
AM
13169+ err = au_ready_to_write(file, -1, &pin);
13170+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13171+ if (unlikely(err)) {
13172+ di_read_unlock(dentry, AuLock_IR);
13173+ fi_write_unlock(file);
13174+ goto out;
13175+ }
1facf9fc 13176+
076b876e 13177+ bstart = au_fbstart(file);
4a4d8108 13178+ h_file = au_hf_top(file);
9dbd164d 13179+ get_file(h_file);
076b876e
AM
13180+ h_inode = h_file->f_dentry->d_inode;
13181+ blks = h_inode->i_blocks;
4a4d8108 13182+ au_unpin(&pin);
9dbd164d
AM
13183+ di_read_unlock(dentry, AuLock_IR);
13184+ fi_write_unlock(file);
13185+
4a4d8108 13186+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 13187+ ii_write_lock_child(inode);
4a4d8108 13188+ au_cpup_attr_timesizes(inode);
c06a8ce3 13189+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13190+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13191+ if (err > 0)
13192+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13193+ ii_write_unlock(inode);
13194+ fput(h_file);
1facf9fc 13195+
4f0767ce 13196+out:
9dbd164d 13197+ si_read_unlock(sb);
4a4d8108 13198+ mutex_unlock(&inode->i_mutex);
dece6358
AM
13199+ return err;
13200+}
1facf9fc 13201+
076b876e
AM
13202+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
13203+ struct iov_iter *iov_iter)
dece6358 13204+{
4a4d8108
AM
13205+ ssize_t err;
13206+ struct file *file;
076b876e
AM
13207+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
13208+ ssize_t (*aio)(struct kiocb *, const struct iovec *, unsigned long,
13209+ loff_t);
1facf9fc 13210+
4a4d8108
AM
13211+ err = security_file_permission(h_file, rw);
13212+ if (unlikely(err))
13213+ goto out;
1facf9fc 13214+
4a4d8108 13215+ err = -ENOSYS;
076b876e
AM
13216+ iter = NULL;
13217+ aio = NULL;
13218+ if (rw == MAY_READ) {
13219+ iter = h_file->f_op->read_iter;
13220+ aio = h_file->f_op->aio_read;
13221+ } else if (rw == MAY_WRITE) {
13222+ iter = h_file->f_op->write_iter;
13223+ aio = h_file->f_op->aio_write;
13224+ }
13225+
13226+ file = kio->ki_filp;
13227+ kio->ki_filp = h_file;
13228+ if (iter) {
2cbb1c4b 13229+ lockdep_off();
076b876e
AM
13230+ err = iter(kio, iov_iter);
13231+ lockdep_on();
13232+ } else if (aio) {
13233+ lockdep_off();
13234+ err = aio(kio, iov_iter->iov, iov_iter->nr_segs, kio->ki_pos);
2cbb1c4b 13235+ lockdep_on();
4a4d8108
AM
13236+ } else
13237+ /* currently there is no such fs */
13238+ WARN_ON_ONCE(1);
076b876e 13239+ kio->ki_filp = file;
1facf9fc 13240+
4f0767ce 13241+out:
dece6358
AM
13242+ return err;
13243+}
1facf9fc 13244+
076b876e 13245+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 13246+{
4a4d8108
AM
13247+ ssize_t err;
13248+ struct file *file, *h_file;
13249+ struct dentry *dentry;
dece6358 13250+ struct super_block *sb;
1facf9fc 13251+
4a4d8108 13252+ file = kio->ki_filp;
dece6358 13253+ dentry = file->f_dentry;
1308ab2a 13254+ sb = dentry->d_sb;
e49829fe 13255+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13256+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13257+ if (unlikely(err))
13258+ goto out;
13259+
13260+ h_file = au_hf_top(file);
9dbd164d
AM
13261+ get_file(h_file);
13262+ di_read_unlock(dentry, AuLock_IR);
13263+ fi_read_unlock(file);
13264+
076b876e 13265+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
13266+ /* todo: necessary? */
13267+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13268+ /* update without lock, I don't think it a problem */
c06a8ce3 13269+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13270+ fput(h_file);
1facf9fc 13271+
4f0767ce 13272+out:
4a4d8108 13273+ si_read_unlock(sb);
1308ab2a 13274+ return err;
13275+}
1facf9fc 13276+
076b876e 13277+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 13278+{
4a4d8108 13279+ ssize_t err;
076b876e
AM
13280+ blkcnt_t blks;
13281+ aufs_bindex_t bstart;
4a4d8108
AM
13282+ struct au_pin pin;
13283+ struct dentry *dentry;
076b876e 13284+ struct inode *inode, *h_inode;
4a4d8108 13285+ struct file *file, *h_file;
9dbd164d 13286+ struct super_block *sb;
1308ab2a 13287+
4a4d8108 13288+ file = kio->ki_filp;
1308ab2a 13289+ dentry = file->f_dentry;
9dbd164d 13290+ sb = dentry->d_sb;
1308ab2a 13291+ inode = dentry->d_inode;
e49829fe
JR
13292+ au_mtx_and_read_lock(inode);
13293+
4a4d8108
AM
13294+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13295+ if (unlikely(err))
1308ab2a 13296+ goto out;
1facf9fc 13297+
4a4d8108
AM
13298+ err = au_ready_to_write(file, -1, &pin);
13299+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13300+ if (unlikely(err)) {
13301+ di_read_unlock(dentry, AuLock_IR);
13302+ fi_write_unlock(file);
13303+ goto out;
13304+ }
1facf9fc 13305+
076b876e 13306+ bstart = au_fbstart(file);
4a4d8108 13307+ h_file = au_hf_top(file);
9dbd164d 13308+ get_file(h_file);
076b876e
AM
13309+ h_inode = h_file->f_dentry->d_inode;
13310+ blks = h_inode->i_blocks;
9dbd164d
AM
13311+ au_unpin(&pin);
13312+ di_read_unlock(dentry, AuLock_IR);
13313+ fi_write_unlock(file);
13314+
076b876e 13315+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
9dbd164d 13316+ ii_write_lock_child(inode);
4a4d8108 13317+ au_cpup_attr_timesizes(inode);
c06a8ce3 13318+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13319+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13320+ if (err > 0)
13321+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13322+ ii_write_unlock(inode);
13323+ fput(h_file);
1facf9fc 13324+
4f0767ce 13325+out:
9dbd164d 13326+ si_read_unlock(sb);
4a4d8108 13327+ mutex_unlock(&inode->i_mutex);
dece6358 13328+ return err;
1facf9fc 13329+}
13330+
4a4d8108
AM
13331+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
13332+ struct pipe_inode_info *pipe, size_t len,
13333+ unsigned int flags)
1facf9fc 13334+{
4a4d8108
AM
13335+ ssize_t err;
13336+ struct file *h_file;
13337+ struct dentry *dentry;
dece6358 13338+ struct super_block *sb;
1facf9fc 13339+
dece6358 13340+ dentry = file->f_dentry;
dece6358 13341+ sb = dentry->d_sb;
e49829fe 13342+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13343+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13344+ if (unlikely(err))
dece6358 13345+ goto out;
1facf9fc 13346+
4a4d8108
AM
13347+ err = -EINVAL;
13348+ h_file = au_hf_top(file);
9dbd164d 13349+ get_file(h_file);
4a4d8108 13350+ if (au_test_loopback_kthread()) {
87a755f4
AM
13351+ au_warn_loopback(h_file->f_dentry->d_sb);
13352+ if (file->f_mapping != h_file->f_mapping) {
13353+ file->f_mapping = h_file->f_mapping;
13354+ smp_mb(); /* unnecessary? */
13355+ }
1308ab2a 13356+ }
9dbd164d
AM
13357+ di_read_unlock(dentry, AuLock_IR);
13358+ fi_read_unlock(file);
13359+
4a4d8108
AM
13360+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
13361+ /* todo: necessasry? */
13362+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13363+ /* update without lock, I don't think it a problem */
c06a8ce3 13364+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13365+ fput(h_file);
1facf9fc 13366+
4f0767ce 13367+out:
4a4d8108 13368+ si_read_unlock(sb);
dece6358 13369+ return err;
1facf9fc 13370+}
13371+
4a4d8108
AM
13372+static ssize_t
13373+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
13374+ size_t len, unsigned int flags)
1facf9fc 13375+{
4a4d8108 13376+ ssize_t err;
076b876e
AM
13377+ blkcnt_t blks;
13378+ aufs_bindex_t bstart;
4a4d8108
AM
13379+ struct au_pin pin;
13380+ struct dentry *dentry;
076b876e 13381+ struct inode *inode, *h_inode;
9dbd164d 13382+ struct super_block *sb;
076b876e 13383+ struct file *h_file;
1facf9fc 13384+
4a4d8108 13385+ dentry = file->f_dentry;
9dbd164d 13386+ sb = dentry->d_sb;
4a4d8108 13387+ inode = dentry->d_inode;
e49829fe 13388+ au_mtx_and_read_lock(inode);
9dbd164d 13389+
4a4d8108
AM
13390+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13391+ if (unlikely(err))
13392+ goto out;
1facf9fc 13393+
4a4d8108
AM
13394+ err = au_ready_to_write(file, -1, &pin);
13395+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13396+ if (unlikely(err)) {
13397+ di_read_unlock(dentry, AuLock_IR);
13398+ fi_write_unlock(file);
13399+ goto out;
13400+ }
1facf9fc 13401+
076b876e 13402+ bstart = au_fbstart(file);
4a4d8108 13403+ h_file = au_hf_top(file);
9dbd164d 13404+ get_file(h_file);
076b876e
AM
13405+ h_inode = h_file->f_dentry->d_inode;
13406+ blks = h_inode->i_blocks;
4a4d8108 13407+ au_unpin(&pin);
9dbd164d
AM
13408+ di_read_unlock(dentry, AuLock_IR);
13409+ fi_write_unlock(file);
13410+
4a4d8108 13411+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 13412+ ii_write_lock_child(inode);
4a4d8108 13413+ au_cpup_attr_timesizes(inode);
c06a8ce3 13414+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13415+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13416+ if (err > 0)
13417+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13418+ ii_write_unlock(inode);
13419+ fput(h_file);
1facf9fc 13420+
4f0767ce 13421+out:
9dbd164d 13422+ si_read_unlock(sb);
4a4d8108
AM
13423+ mutex_unlock(&inode->i_mutex);
13424+ return err;
13425+}
1facf9fc 13426+
38d290e6
JR
13427+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
13428+ loff_t len)
13429+{
13430+ long err;
13431+ struct au_pin pin;
13432+ struct dentry *dentry;
13433+ struct super_block *sb;
13434+ struct inode *inode;
13435+ struct file *h_file;
13436+
13437+ dentry = file->f_dentry;
13438+ sb = dentry->d_sb;
13439+ inode = dentry->d_inode;
13440+ au_mtx_and_read_lock(inode);
13441+
13442+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13443+ if (unlikely(err))
13444+ goto out;
13445+
13446+ err = au_ready_to_write(file, -1, &pin);
13447+ di_downgrade_lock(dentry, AuLock_IR);
13448+ if (unlikely(err)) {
13449+ di_read_unlock(dentry, AuLock_IR);
13450+ fi_write_unlock(file);
13451+ goto out;
13452+ }
13453+
13454+ h_file = au_hf_top(file);
13455+ get_file(h_file);
13456+ au_unpin(&pin);
13457+ di_read_unlock(dentry, AuLock_IR);
13458+ fi_write_unlock(file);
13459+
13460+ lockdep_off();
13461+ err = do_fallocate(h_file, mode, offset, len);
13462+ lockdep_on();
13463+ ii_write_lock_child(inode);
13464+ au_cpup_attr_timesizes(inode);
13465+ inode->i_mode = file_inode(h_file)->i_mode;
13466+ ii_write_unlock(inode);
13467+ fput(h_file);
13468+
13469+out:
13470+ si_read_unlock(sb);
13471+ mutex_unlock(&inode->i_mutex);
13472+ return err;
13473+}
13474+
4a4d8108
AM
13475+/* ---------------------------------------------------------------------- */
13476+
9dbd164d
AM
13477+/*
13478+ * The locking order around current->mmap_sem.
13479+ * - in most and regular cases
13480+ * file I/O syscall -- aufs_read() or something
13481+ * -- si_rwsem for read -- mmap_sem
13482+ * (Note that [fdi]i_rwsem are released before mmap_sem).
13483+ * - in mmap case
13484+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
13485+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
13486+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
13487+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
13488+ * It means that when aufs acquires si_rwsem for write, the process should never
13489+ * acquire mmap_sem.
13490+ *
392086de 13491+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
13492+ * problem either since any directory is not able to be mmap-ed.
13493+ * The similar scenario is applied to aufs_readlink() too.
13494+ */
13495+
38d290e6 13496+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
13497+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
13498+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
13499+
13500+static unsigned long au_arch_prot_conv(unsigned long flags)
13501+{
13502+ /* currently ppc64 only */
13503+#ifdef CONFIG_PPC64
13504+ /* cf. linux/arch/powerpc/include/asm/mman.h */
13505+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
13506+ return AuConv_VM_PROT(flags, SAO);
13507+#else
13508+ AuDebugOn(arch_calc_vm_prot_bits(-1));
13509+ return 0;
13510+#endif
13511+}
13512+
13513+static unsigned long au_prot_conv(unsigned long flags)
13514+{
13515+ return AuConv_VM_PROT(flags, READ)
13516+ | AuConv_VM_PROT(flags, WRITE)
13517+ | AuConv_VM_PROT(flags, EXEC)
13518+ | au_arch_prot_conv(flags);
13519+}
13520+
13521+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
13522+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
13523+
13524+static unsigned long au_flag_conv(unsigned long flags)
13525+{
13526+ return AuConv_VM_MAP(flags, GROWSDOWN)
13527+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
13528+ | AuConv_VM_MAP(flags, LOCKED);
13529+}
38d290e6 13530+#endif
2dfbb274 13531+
9dbd164d 13532+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 13533+{
4a4d8108
AM
13534+ int err;
13535+ aufs_bindex_t bstart;
13536+ const unsigned char wlock
9dbd164d 13537+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
13538+ struct dentry *dentry;
13539+ struct super_block *sb;
9dbd164d
AM
13540+ struct file *h_file;
13541+ struct au_branch *br;
13542+ struct au_pin pin;
13543+
13544+ AuDbgVmRegion(file, vma);
1308ab2a 13545+
4a4d8108
AM
13546+ dentry = file->f_dentry;
13547+ sb = dentry->d_sb;
9dbd164d 13548+ lockdep_off();
e49829fe 13549+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
13550+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13551+ if (unlikely(err))
13552+ goto out;
13553+
4a4d8108 13554+ if (wlock) {
4a4d8108
AM
13555+ err = au_ready_to_write(file, -1, &pin);
13556+ di_write_unlock(dentry);
9dbd164d
AM
13557+ if (unlikely(err)) {
13558+ fi_write_unlock(file);
13559+ goto out;
13560+ }
4a4d8108
AM
13561+ au_unpin(&pin);
13562+ } else
13563+ di_write_unlock(dentry);
9dbd164d 13564+
4a4d8108 13565+ bstart = au_fbstart(file);
9dbd164d
AM
13566+ br = au_sbr(sb, bstart);
13567+ h_file = au_hf_top(file);
13568+ get_file(h_file);
2cbb1c4b 13569+ au_set_mmapped(file);
4a4d8108 13570+ fi_write_unlock(file);
9dbd164d 13571+ lockdep_on();
1308ab2a 13572+
9dbd164d 13573+ au_vm_file_reset(vma, h_file);
38d290e6
JR
13574+ /*
13575+ * we cannot call security_mmap_file() here since it may acquire
13576+ * mmap_sem or i_mutex.
13577+ *
13578+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
13579+ * au_flag_conv(vma->vm_flags));
13580+ */
9dbd164d
AM
13581+ if (!err)
13582+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
13583+ if (unlikely(err))
13584+ goto out_reset;
4a4d8108 13585+
fb47a38f 13586+ au_vm_prfile_set(vma, file);
4a4d8108 13587+ /* update without lock, I don't think it a problem */
c06a8ce3 13588+ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
2cbb1c4b 13589+ goto out_fput; /* success */
4a4d8108 13590+
2cbb1c4b
JR
13591+out_reset:
13592+ au_unset_mmapped(file);
13593+ au_vm_file_reset(vma, file);
13594+out_fput:
9dbd164d
AM
13595+ fput(h_file);
13596+ lockdep_off();
4f0767ce 13597+out:
9dbd164d
AM
13598+ si_read_unlock(sb);
13599+ lockdep_on();
13600+ AuTraceErr(err);
4a4d8108
AM
13601+ return err;
13602+}
13603+
13604+/* ---------------------------------------------------------------------- */
13605+
1e00d052
AM
13606+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
13607+ int datasync)
4a4d8108
AM
13608+{
13609+ int err;
13610+ struct au_pin pin;
b752ccd1 13611+ struct dentry *dentry;
4a4d8108
AM
13612+ struct inode *inode;
13613+ struct file *h_file;
13614+ struct super_block *sb;
13615+
b752ccd1 13616+ dentry = file->f_dentry;
4a4d8108 13617+ inode = dentry->d_inode;
4a4d8108 13618+ sb = dentry->d_sb;
1e00d052 13619+ mutex_lock(&inode->i_mutex);
e49829fe
JR
13620+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13621+ if (unlikely(err))
13622+ goto out;
4a4d8108
AM
13623+
13624+ err = 0; /* -EBADF; */ /* posix? */
13625+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 13626+ goto out_si;
4a4d8108
AM
13627+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13628+ if (unlikely(err))
e49829fe 13629+ goto out_si;
4a4d8108
AM
13630+
13631+ err = au_ready_to_write(file, -1, &pin);
13632+ di_downgrade_lock(dentry, AuLock_IR);
13633+ if (unlikely(err))
13634+ goto out_unlock;
13635+ au_unpin(&pin);
13636+
13637+ err = -EINVAL;
13638+ h_file = au_hf_top(file);
53392da6
AM
13639+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
13640+ au_cpup_attr_timesizes(inode);
4a4d8108 13641+
4f0767ce 13642+out_unlock:
4a4d8108 13643+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 13644+ fi_write_unlock(file);
e49829fe 13645+out_si:
953406b4 13646+ si_read_unlock(sb);
e49829fe 13647+out:
1e00d052 13648+ mutex_unlock(&inode->i_mutex);
4a4d8108 13649+ return err;
dece6358
AM
13650+}
13651+
4a4d8108
AM
13652+/* no one supports this operation, currently */
13653+#if 0
13654+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 13655+{
4a4d8108
AM
13656+ int err;
13657+ struct au_pin pin;
1308ab2a 13658+ struct dentry *dentry;
4a4d8108
AM
13659+ struct inode *inode;
13660+ struct file *file, *h_file;
1308ab2a 13661+
4a4d8108 13662+ file = kio->ki_filp;
1308ab2a 13663+ dentry = file->f_dentry;
4a4d8108 13664+ inode = dentry->d_inode;
e49829fe 13665+ au_mtx_and_read_lock(inode);
4a4d8108
AM
13666+
13667+ err = 0; /* -EBADF; */ /* posix? */
13668+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
13669+ goto out;
13670+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13671+ if (unlikely(err))
1308ab2a 13672+ goto out;
13673+
4a4d8108
AM
13674+ err = au_ready_to_write(file, -1, &pin);
13675+ di_downgrade_lock(dentry, AuLock_IR);
13676+ if (unlikely(err))
13677+ goto out_unlock;
13678+ au_unpin(&pin);
1308ab2a 13679+
4a4d8108
AM
13680+ err = -ENOSYS;
13681+ h_file = au_hf_top(file);
523b37e3 13682+ if (h_file->f_op->aio_fsync) {
4a4d8108 13683+ struct mutex *h_mtx;
1308ab2a 13684+
c06a8ce3 13685+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
13686+ if (!is_sync_kiocb(kio)) {
13687+ get_file(h_file);
13688+ fput(file);
13689+ }
13690+ kio->ki_filp = h_file;
13691+ err = h_file->f_op->aio_fsync(kio, datasync);
13692+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
13693+ if (!err)
13694+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
13695+ /*ignore*/
13696+ au_cpup_attr_timesizes(inode);
13697+ mutex_unlock(h_mtx);
13698+ }
1308ab2a 13699+
4f0767ce 13700+out_unlock:
4a4d8108
AM
13701+ di_read_unlock(dentry, AuLock_IR);
13702+ fi_write_unlock(file);
4f0767ce 13703+out:
e49829fe 13704+ si_read_unlock(inode->sb);
4a4d8108
AM
13705+ mutex_unlock(&inode->i_mutex);
13706+ return err;
dece6358 13707+}
4a4d8108 13708+#endif
dece6358 13709+
4a4d8108 13710+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 13711+{
4a4d8108
AM
13712+ int err;
13713+ struct file *h_file;
13714+ struct dentry *dentry;
13715+ struct super_block *sb;
1308ab2a 13716+
4a4d8108
AM
13717+ dentry = file->f_dentry;
13718+ sb = dentry->d_sb;
e49829fe 13719+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13720+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13721+ if (unlikely(err))
13722+ goto out;
13723+
13724+ h_file = au_hf_top(file);
523b37e3 13725+ if (h_file->f_op->fasync)
4a4d8108
AM
13726+ err = h_file->f_op->fasync(fd, h_file, flag);
13727+
13728+ di_read_unlock(dentry, AuLock_IR);
13729+ fi_read_unlock(file);
1308ab2a 13730+
4f0767ce 13731+out:
4a4d8108 13732+ si_read_unlock(sb);
1308ab2a 13733+ return err;
dece6358 13734+}
4a4d8108
AM
13735+
13736+/* ---------------------------------------------------------------------- */
13737+
13738+/* no one supports this operation, currently */
13739+#if 0
13740+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
13741+ size_t len, loff_t *pos , int more)
13742+{
13743+}
13744+#endif
13745+
13746+/* ---------------------------------------------------------------------- */
13747+
13748+const struct file_operations aufs_file_fop = {
13749+ .owner = THIS_MODULE,
2cbb1c4b 13750+
027c5e7a 13751+ .llseek = default_llseek,
4a4d8108
AM
13752+
13753+ .read = aufs_read,
13754+ .write = aufs_write,
076b876e
AM
13755+ .read_iter = aufs_read_iter,
13756+ .write_iter = aufs_write_iter,
13757+
4a4d8108
AM
13758+#ifdef CONFIG_AUFS_POLL
13759+ .poll = aufs_poll,
13760+#endif
13761+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 13762+#ifdef CONFIG_COMPAT
c2b27bf2 13763+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 13764+#endif
4a4d8108
AM
13765+ .mmap = aufs_mmap,
13766+ .open = aufs_open_nondir,
13767+ .flush = aufs_flush_nondir,
13768+ .release = aufs_release_nondir,
13769+ .fsync = aufs_fsync_nondir,
13770+ /* .aio_fsync = aufs_aio_fsync_nondir, */
13771+ .fasync = aufs_fasync,
13772+ /* .sendpage = aufs_sendpage, */
13773+ .splice_write = aufs_splice_write,
13774+ .splice_read = aufs_splice_read,
13775+#if 0
13776+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 13777+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 13778+#endif
38d290e6 13779+ .fallocate = aufs_fallocate
4a4d8108 13780+};
7f207e10
AM
13781diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
13782--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
076b876e 13783+++ linux/fs/aufs/fstype.h 2014-01-30 21:10:02.850815069 +0100
523b37e3 13784@@ -0,0 +1,469 @@
4a4d8108 13785+/*
523b37e3 13786+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
13787+ *
13788+ * This program, aufs is free software; you can redistribute it and/or modify
13789+ * it under the terms of the GNU General Public License as published by
13790+ * the Free Software Foundation; either version 2 of the License, or
13791+ * (at your option) any later version.
13792+ *
13793+ * This program is distributed in the hope that it will be useful,
13794+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13795+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13796+ * GNU General Public License for more details.
13797+ *
13798+ * You should have received a copy of the GNU General Public License
523b37e3 13799+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
13800+ */
13801+
13802+/*
13803+ * judging filesystem type
13804+ */
13805+
13806+#ifndef __AUFS_FSTYPE_H__
13807+#define __AUFS_FSTYPE_H__
13808+
13809+#ifdef __KERNEL__
13810+
13811+#include <linux/fs.h>
13812+#include <linux/magic.h>
13813+#include <linux/romfs_fs.h>
4a4d8108
AM
13814+
13815+static inline int au_test_aufs(struct super_block *sb)
13816+{
13817+ return sb->s_magic == AUFS_SUPER_MAGIC;
13818+}
13819+
13820+static inline const char *au_sbtype(struct super_block *sb)
13821+{
13822+ return sb->s_type->name;
13823+}
1308ab2a 13824+
13825+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
13826+{
13827+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
13828+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
13829+#else
13830+ return 0;
13831+#endif
13832+}
13833+
1308ab2a 13834+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 13835+{
1308ab2a 13836+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
13837+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
13838+#else
13839+ return 0;
13840+#endif
13841+}
13842+
1308ab2a 13843+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 13844+{
1308ab2a 13845+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
13846+ return sb->s_magic == CRAMFS_MAGIC;
13847+#endif
13848+ return 0;
13849+}
13850+
13851+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
13852+{
13853+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
13854+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
13855+#else
13856+ return 0;
13857+#endif
13858+}
13859+
1308ab2a 13860+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 13861+{
1308ab2a 13862+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
13863+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
13864+#else
13865+ return 0;
13866+#endif
13867+}
13868+
1308ab2a 13869+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 13870+{
1308ab2a 13871+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
13872+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
13873+#else
13874+ return 0;
13875+#endif
13876+}
13877+
1308ab2a 13878+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 13879+{
1308ab2a 13880+#ifdef CONFIG_TMPFS
13881+ return sb->s_magic == TMPFS_MAGIC;
13882+#else
13883+ return 0;
dece6358 13884+#endif
dece6358
AM
13885+}
13886+
1308ab2a 13887+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 13888+{
1308ab2a 13889+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
13890+ return !strcmp(au_sbtype(sb), "ecryptfs");
13891+#else
13892+ return 0;
13893+#endif
1facf9fc 13894+}
13895+
1308ab2a 13896+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
1facf9fc 13897+{
1308ab2a 13898+#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
13899+ return sb->s_magic == OCFS2_SUPER_MAGIC;
13900+#else
13901+ return 0;
13902+#endif
1facf9fc 13903+}
13904+
1308ab2a 13905+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
1facf9fc 13906+{
1308ab2a 13907+#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
13908+ return sb->s_magic == DLMFS_MAGIC;
13909+#else
13910+ return 0;
13911+#endif
1facf9fc 13912+}
13913+
1308ab2a 13914+static inline int au_test_coda(struct super_block *sb __maybe_unused)
1facf9fc 13915+{
1308ab2a 13916+#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
13917+ return sb->s_magic == CODA_SUPER_MAGIC;
13918+#else
13919+ return 0;
13920+#endif
13921+}
13922+
13923+static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
13924+{
13925+#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
13926+ return sb->s_magic == V9FS_MAGIC;
13927+#else
13928+ return 0;
13929+#endif
13930+}
13931+
13932+static inline int au_test_ext4(struct super_block *sb __maybe_unused)
13933+{
c2b27bf2 13934+#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE)
1308ab2a 13935+ return sb->s_magic == EXT4_SUPER_MAGIC;
13936+#else
13937+ return 0;
13938+#endif
13939+}
13940+
13941+static inline int au_test_sysv(struct super_block *sb __maybe_unused)
13942+{
13943+#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
13944+ return !strcmp(au_sbtype(sb), "sysv");
13945+#else
13946+ return 0;
13947+#endif
13948+}
13949+
13950+static inline int au_test_ramfs(struct super_block *sb)
13951+{
13952+ return sb->s_magic == RAMFS_MAGIC;
13953+}
13954+
13955+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
13956+{
13957+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
13958+ return sb->s_magic == UBIFS_SUPER_MAGIC;
13959+#else
13960+ return 0;
13961+#endif
13962+}
13963+
13964+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
13965+{
13966+#ifdef CONFIG_PROC_FS
13967+ return sb->s_magic == PROC_SUPER_MAGIC;
13968+#else
13969+ return 0;
13970+#endif
13971+}
13972+
13973+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
13974+{
13975+#ifdef CONFIG_SYSFS
13976+ return sb->s_magic == SYSFS_MAGIC;
13977+#else
13978+ return 0;
13979+#endif
13980+}
13981+
13982+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
13983+{
13984+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
13985+ return sb->s_magic == CONFIGFS_MAGIC;
13986+#else
13987+ return 0;
13988+#endif
13989+}
13990+
13991+static inline int au_test_minix(struct super_block *sb __maybe_unused)
13992+{
13993+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
13994+ return sb->s_magic == MINIX3_SUPER_MAGIC
13995+ || sb->s_magic == MINIX2_SUPER_MAGIC
13996+ || sb->s_magic == MINIX2_SUPER_MAGIC2
13997+ || sb->s_magic == MINIX_SUPER_MAGIC
13998+ || sb->s_magic == MINIX_SUPER_MAGIC2;
13999+#else
14000+ return 0;
14001+#endif
14002+}
14003+
14004+static inline int au_test_cifs(struct super_block *sb __maybe_unused)
14005+{
14006+#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
14007+ return sb->s_magic == CIFS_MAGIC_NUMBER;
14008+#else
14009+ return 0;
14010+#endif
14011+}
14012+
14013+static inline int au_test_fat(struct super_block *sb __maybe_unused)
14014+{
14015+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
14016+ return sb->s_magic == MSDOS_SUPER_MAGIC;
14017+#else
14018+ return 0;
14019+#endif
14020+}
14021+
14022+static inline int au_test_msdos(struct super_block *sb)
14023+{
14024+ return au_test_fat(sb);
14025+}
14026+
14027+static inline int au_test_vfat(struct super_block *sb)
14028+{
14029+ return au_test_fat(sb);
14030+}
14031+
14032+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
14033+{
14034+#ifdef CONFIG_SECURITYFS
14035+ return sb->s_magic == SECURITYFS_MAGIC;
14036+#else
14037+ return 0;
14038+#endif
14039+}
14040+
14041+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
14042+{
14043+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
14044+ return sb->s_magic == SQUASHFS_MAGIC;
14045+#else
14046+ return 0;
14047+#endif
14048+}
14049+
14050+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
14051+{
14052+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
14053+ return sb->s_magic == BTRFS_SUPER_MAGIC;
14054+#else
14055+ return 0;
14056+#endif
14057+}
14058+
14059+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
14060+{
14061+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
14062+ return sb->s_magic == XENFS_SUPER_MAGIC;
14063+#else
14064+ return 0;
14065+#endif
14066+}
14067+
14068+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
14069+{
14070+#ifdef CONFIG_DEBUG_FS
14071+ return sb->s_magic == DEBUGFS_MAGIC;
14072+#else
14073+ return 0;
14074+#endif
14075+}
14076+
14077+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
14078+{
14079+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
14080+ return sb->s_magic == NILFS_SUPER_MAGIC;
14081+#else
14082+ return 0;
14083+#endif
14084+}
14085+
4a4d8108
AM
14086+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
14087+{
14088+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
14089+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
14090+#else
14091+ return 0;
14092+#endif
14093+}
14094+
1308ab2a 14095+/* ---------------------------------------------------------------------- */
14096+/*
14097+ * they can't be an aufs branch.
14098+ */
14099+static inline int au_test_fs_unsuppoted(struct super_block *sb)
14100+{
14101+ return
14102+#ifndef CONFIG_AUFS_BR_RAMFS
14103+ au_test_ramfs(sb) ||
14104+#endif
14105+ au_test_procfs(sb)
14106+ || au_test_sysfs(sb)
14107+ || au_test_configfs(sb)
14108+ || au_test_debugfs(sb)
14109+ || au_test_securityfs(sb)
14110+ || au_test_xenfs(sb)
14111+ || au_test_ecryptfs(sb)
14112+ /* || !strcmp(au_sbtype(sb), "unionfs") */
14113+ || au_test_aufs(sb); /* will be supported in next version */
14114+}
14115+
1308ab2a 14116+static inline int au_test_fs_remote(struct super_block *sb)
14117+{
14118+ return !au_test_tmpfs(sb)
14119+#ifdef CONFIG_AUFS_BR_RAMFS
14120+ && !au_test_ramfs(sb)
14121+#endif
14122+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
14123+}
14124+
14125+/* ---------------------------------------------------------------------- */
14126+
14127+/*
14128+ * Note: these functions (below) are created after reading ->getattr() in all
14129+ * filesystems under linux/fs. it means we have to do so in every update...
14130+ */
14131+
14132+/*
14133+ * some filesystems require getattr to refresh the inode attributes before
14134+ * referencing.
14135+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
14136+ * and leave the work for d_revalidate()
14137+ */
14138+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
14139+{
14140+ return au_test_nfs(sb)
14141+ || au_test_fuse(sb)
1308ab2a 14142+ /* || au_test_ocfs2(sb) */ /* untested */
14143+ /* || au_test_btrfs(sb) */ /* untested */
14144+ /* || au_test_coda(sb) */ /* untested */
14145+ /* || au_test_v9fs(sb) */ /* untested */
14146+ ;
14147+}
14148+
14149+/*
14150+ * filesystems which don't maintain i_size or i_blocks.
14151+ */
14152+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
14153+{
14154+ return au_test_xfs(sb)
4a4d8108
AM
14155+ || au_test_btrfs(sb)
14156+ || au_test_ubifs(sb)
14157+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 14158+ /* || au_test_ext4(sb) */ /* untested */
14159+ /* || au_test_ocfs2(sb) */ /* untested */
14160+ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
14161+ /* || au_test_sysv(sb) */ /* untested */
1308ab2a 14162+ /* || au_test_minix(sb) */ /* untested */
14163+ ;
14164+}
14165+
14166+/*
14167+ * filesystems which don't store the correct value in some of their inode
14168+ * attributes.
14169+ */
14170+static inline int au_test_fs_bad_iattr(struct super_block *sb)
14171+{
14172+ return au_test_fs_bad_iattr_size(sb)
14173+ /* || au_test_cifs(sb) */ /* untested */
14174+ || au_test_fat(sb)
14175+ || au_test_msdos(sb)
14176+ || au_test_vfat(sb);
1facf9fc 14177+}
14178+
14179+/* they don't check i_nlink in link(2) */
14180+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
14181+{
14182+ return au_test_tmpfs(sb)
14183+#ifdef CONFIG_AUFS_BR_RAMFS
14184+ || au_test_ramfs(sb)
14185+#endif
4a4d8108 14186+ || au_test_ubifs(sb)
4a4d8108 14187+ || au_test_hfsplus(sb);
1facf9fc 14188+}
14189+
14190+/*
14191+ * filesystems which sets S_NOATIME and S_NOCMTIME.
14192+ */
14193+static inline int au_test_fs_notime(struct super_block *sb)
14194+{
14195+ return au_test_nfs(sb)
14196+ || au_test_fuse(sb)
dece6358 14197+ || au_test_ubifs(sb)
1facf9fc 14198+ /* || au_test_cifs(sb) */ /* untested */
1facf9fc 14199+ ;
14200+}
14201+
14202+/*
14203+ * filesystems which requires replacing i_mapping.
14204+ */
14205+static inline int au_test_fs_bad_mapping(struct super_block *sb)
14206+{
dece6358
AM
14207+ return au_test_fuse(sb)
14208+ || au_test_ubifs(sb);
1facf9fc 14209+}
14210+
14211+/* temporary support for i#1 in cramfs */
14212+static inline int au_test_fs_unique_ino(struct inode *inode)
14213+{
14214+ if (au_test_cramfs(inode->i_sb))
14215+ return inode->i_ino != 1;
14216+ return 1;
14217+}
14218+
14219+/* ---------------------------------------------------------------------- */
14220+
14221+/*
14222+ * the filesystem where the xino files placed must support i/o after unlink and
14223+ * maintain i_size and i_blocks.
14224+ */
14225+static inline int au_test_fs_bad_xino(struct super_block *sb)
14226+{
14227+ return au_test_fs_remote(sb)
14228+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 14229+ /* don't want unnecessary work for xino */
14230+ || au_test_aufs(sb)
1308ab2a 14231+ || au_test_ecryptfs(sb)
14232+ || au_test_nilfs(sb);
1facf9fc 14233+}
14234+
14235+static inline int au_test_fs_trunc_xino(struct super_block *sb)
14236+{
14237+ return au_test_tmpfs(sb)
14238+ || au_test_ramfs(sb);
14239+}
14240+
14241+/*
14242+ * test if the @sb is real-readonly.
14243+ */
14244+static inline int au_test_fs_rr(struct super_block *sb)
14245+{
14246+ return au_test_squashfs(sb)
14247+ || au_test_iso9660(sb)
14248+ || au_test_cramfs(sb)
14249+ || au_test_romfs(sb);
14250+}
14251+
14252+#endif /* __KERNEL__ */
14253+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
14254diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
14255--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
076b876e 14256+++ linux/fs/aufs/hfsnotify.c 2014-08-14 10:16:04.515942371 +0200
fb47a38f 14257@@ -0,0 +1,281 @@
1facf9fc 14258+/*
523b37e3 14259+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 14260+ *
14261+ * This program, aufs is free software; you can redistribute it and/or modify
14262+ * it under the terms of the GNU General Public License as published by
14263+ * the Free Software Foundation; either version 2 of the License, or
14264+ * (at your option) any later version.
dece6358
AM
14265+ *
14266+ * This program is distributed in the hope that it will be useful,
14267+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14268+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14269+ * GNU General Public License for more details.
14270+ *
14271+ * You should have received a copy of the GNU General Public License
523b37e3 14272+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14273+ */
14274+
14275+/*
4a4d8108 14276+ * fsnotify for the lower directories
1facf9fc 14277+ */
14278+
14279+#include "aufs.h"
14280+
4a4d8108
AM
14281+/* FS_IN_IGNORED is unnecessary */
14282+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
14283+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 14284+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 14285+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 14286+
0c5527e5 14287+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 14288+{
0c5527e5
AM
14289+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
14290+ hn_mark);
4a4d8108 14291+ AuDbg("here\n");
7eafdf33 14292+ au_cache_free_hnotify(hn);
076b876e 14293+ smp_mb__before_atomic();
1716fcea
AM
14294+ if (atomic64_dec_and_test(&au_hfsn_ifree))
14295+ wake_up(&au_hfsn_wq);
4a4d8108 14296+}
1facf9fc 14297+
027c5e7a 14298+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 14299+{
1716fcea 14300+ int err;
027c5e7a
AM
14301+ struct au_hnotify *hn;
14302+ struct super_block *sb;
14303+ struct au_branch *br;
0c5527e5 14304+ struct fsnotify_mark *mark;
027c5e7a 14305+ aufs_bindex_t bindex;
1facf9fc 14306+
027c5e7a
AM
14307+ hn = hinode->hi_notify;
14308+ sb = hn->hn_aufs_inode->i_sb;
14309+ bindex = au_br_index(sb, hinode->hi_id);
14310+ br = au_sbr(sb, bindex);
1716fcea
AM
14311+ AuDebugOn(!br->br_hfsn);
14312+
0c5527e5
AM
14313+ mark = &hn->hn_mark;
14314+ fsnotify_init_mark(mark, au_hfsn_free_mark);
14315+ mark->mask = AuHfsnMask;
7f207e10
AM
14316+ /*
14317+ * by udba rename or rmdir, aufs assign a new inode to the known
14318+ * h_inode, so specify 1 to allow dups.
14319+ */
1716fcea 14320+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 14321+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
14322+ /* even if err */
14323+ fsnotify_put_mark(mark);
14324+
14325+ return err;
1facf9fc 14326+}
14327+
7eafdf33 14328+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 14329+{
0c5527e5 14330+ struct fsnotify_mark *mark;
7eafdf33 14331+ unsigned long long ull;
1716fcea 14332+ struct fsnotify_group *group;
7eafdf33
AM
14333+
14334+ ull = atomic64_inc_return(&au_hfsn_ifree);
14335+ BUG_ON(!ull);
953406b4 14336+
0c5527e5 14337+ mark = &hn->hn_mark;
1716fcea
AM
14338+ spin_lock(&mark->lock);
14339+ group = mark->group;
14340+ fsnotify_get_group(group);
14341+ spin_unlock(&mark->lock);
14342+ fsnotify_destroy_mark(mark, group);
14343+ fsnotify_put_group(group);
7f207e10 14344+
7eafdf33
AM
14345+ /* free hn by myself */
14346+ return 0;
1facf9fc 14347+}
14348+
14349+/* ---------------------------------------------------------------------- */
14350+
4a4d8108 14351+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 14352+{
0c5527e5 14353+ struct fsnotify_mark *mark;
1facf9fc 14354+
0c5527e5
AM
14355+ mark = &hinode->hi_notify->hn_mark;
14356+ spin_lock(&mark->lock);
1facf9fc 14357+ if (do_set) {
0c5527e5
AM
14358+ AuDebugOn(mark->mask & AuHfsnMask);
14359+ mark->mask |= AuHfsnMask;
1facf9fc 14360+ } else {
0c5527e5
AM
14361+ AuDebugOn(!(mark->mask & AuHfsnMask));
14362+ mark->mask &= ~AuHfsnMask;
1facf9fc 14363+ }
0c5527e5 14364+ spin_unlock(&mark->lock);
4a4d8108 14365+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 14366+}
14367+
4a4d8108 14368+/* ---------------------------------------------------------------------- */
1facf9fc 14369+
4a4d8108
AM
14370+/* #define AuDbgHnotify */
14371+#ifdef AuDbgHnotify
14372+static char *au_hfsn_name(u32 mask)
14373+{
14374+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
14375+#define test_ret(flag) \
14376+ do { \
14377+ if (mask & flag) \
14378+ return #flag; \
14379+ } while (0)
4a4d8108
AM
14380+ test_ret(FS_ACCESS);
14381+ test_ret(FS_MODIFY);
14382+ test_ret(FS_ATTRIB);
14383+ test_ret(FS_CLOSE_WRITE);
14384+ test_ret(FS_CLOSE_NOWRITE);
14385+ test_ret(FS_OPEN);
14386+ test_ret(FS_MOVED_FROM);
14387+ test_ret(FS_MOVED_TO);
14388+ test_ret(FS_CREATE);
14389+ test_ret(FS_DELETE);
14390+ test_ret(FS_DELETE_SELF);
14391+ test_ret(FS_MOVE_SELF);
14392+ test_ret(FS_UNMOUNT);
14393+ test_ret(FS_Q_OVERFLOW);
14394+ test_ret(FS_IN_IGNORED);
14395+ test_ret(FS_IN_ISDIR);
14396+ test_ret(FS_IN_ONESHOT);
14397+ test_ret(FS_EVENT_ON_CHILD);
14398+ return "";
14399+#undef test_ret
14400+#else
14401+ return "??";
14402+#endif
1facf9fc 14403+}
4a4d8108 14404+#endif
1facf9fc 14405+
14406+/* ---------------------------------------------------------------------- */
14407+
1716fcea
AM
14408+static void au_hfsn_free_group(struct fsnotify_group *group)
14409+{
14410+ struct au_br_hfsnotify *hfsn = group->private;
14411+
14412+ AuDbg("here\n");
14413+ kfree(hfsn);
14414+}
14415+
4a4d8108 14416+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 14417+ struct inode *inode,
0c5527e5
AM
14418+ struct fsnotify_mark *inode_mark,
14419+ struct fsnotify_mark *vfsmount_mark,
fb47a38f
JR
14420+ u32 mask, void *data, int data_type,
14421+ const unsigned char *file_name, u32 cookie)
1facf9fc 14422+{
14423+ int err;
4a4d8108
AM
14424+ struct au_hnotify *hnotify;
14425+ struct inode *h_dir, *h_inode;
fb47a38f 14426+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
4a4d8108 14427+
fb47a38f 14428+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 14429+
14430+ err = 0;
0c5527e5 14431+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 14432+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 14433+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 14434+ goto out;
1facf9fc 14435+
fb47a38f
JR
14436+ h_dir = inode;
14437+ h_inode = NULL;
4a4d8108 14438+#ifdef AuDbgHnotify
392086de 14439+ au_debug_on();
4a4d8108
AM
14440+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
14441+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
14442+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
14443+ h_dir->i_ino, mask, au_hfsn_name(mask),
14444+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
14445+ /* WARN_ON(1); */
1facf9fc 14446+ }
392086de 14447+ au_debug_off();
1facf9fc 14448+#endif
4a4d8108 14449+
0c5527e5
AM
14450+ AuDebugOn(!inode_mark);
14451+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
14452+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 14453+
4a4d8108
AM
14454+out:
14455+ return err;
14456+}
1facf9fc 14457+
4a4d8108 14458+static struct fsnotify_ops au_hfsn_ops = {
1716fcea
AM
14459+ .handle_event = au_hfsn_handle_event,
14460+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
14461+};
14462+
14463+/* ---------------------------------------------------------------------- */
14464+
027c5e7a
AM
14465+static void au_hfsn_fin_br(struct au_branch *br)
14466+{
1716fcea 14467+ struct au_br_hfsnotify *hfsn;
027c5e7a 14468+
1716fcea
AM
14469+ hfsn = br->br_hfsn;
14470+ if (hfsn)
14471+ fsnotify_put_group(hfsn->hfsn_group);
027c5e7a
AM
14472+}
14473+
1716fcea 14474+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
14475+{
14476+ int err;
1716fcea
AM
14477+ struct fsnotify_group *group;
14478+ struct au_br_hfsnotify *hfsn;
1facf9fc 14479+
4a4d8108 14480+ err = 0;
1716fcea
AM
14481+ br->br_hfsn = NULL;
14482+ if (!au_br_hnotifyable(perm))
027c5e7a 14483+ goto out;
027c5e7a 14484+
1716fcea
AM
14485+ err = -ENOMEM;
14486+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
14487+ if (unlikely(!hfsn))
027c5e7a
AM
14488+ goto out;
14489+
1716fcea
AM
14490+ err = 0;
14491+ group = fsnotify_alloc_group(&au_hfsn_ops);
14492+ if (IS_ERR(group)) {
14493+ err = PTR_ERR(group);
0c5527e5 14494+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 14495+ goto out_hfsn;
4a4d8108 14496+ }
1facf9fc 14497+
1716fcea
AM
14498+ group->private = hfsn;
14499+ hfsn->hfsn_group = group;
14500+ br->br_hfsn = hfsn;
14501+ goto out; /* success */
14502+
14503+out_hfsn:
14504+ kfree(hfsn);
027c5e7a 14505+out:
1716fcea
AM
14506+ return err;
14507+}
14508+
14509+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
14510+{
14511+ int err;
14512+
14513+ err = 0;
14514+ if (!br->br_hfsn)
14515+ err = au_hfsn_init_br(br, perm);
14516+
1facf9fc 14517+ return err;
14518+}
14519+
7eafdf33
AM
14520+/* ---------------------------------------------------------------------- */
14521+
14522+static void au_hfsn_fin(void)
14523+{
14524+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
14525+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
14526+}
14527+
4a4d8108
AM
14528+const struct au_hnotify_op au_hnotify_op = {
14529+ .ctl = au_hfsn_ctl,
14530+ .alloc = au_hfsn_alloc,
14531+ .free = au_hfsn_free,
1facf9fc 14532+
7eafdf33
AM
14533+ .fin = au_hfsn_fin,
14534+
027c5e7a
AM
14535+ .reset_br = au_hfsn_reset_br,
14536+ .fin_br = au_hfsn_fin_br,
14537+ .init_br = au_hfsn_init_br
4a4d8108 14538+};
7f207e10
AM
14539diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
14540--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
076b876e 14541+++ linux/fs/aufs/hfsplus.c 2014-01-30 21:10:02.850815069 +0100
523b37e3 14542@@ -0,0 +1,56 @@
4a4d8108 14543+/*
523b37e3 14544+ * Copyright (C) 2010-2014 Junjiro R. Okajima
4a4d8108
AM
14545+ *
14546+ * This program, aufs is free software; you can redistribute it and/or modify
14547+ * it under the terms of the GNU General Public License as published by
14548+ * the Free Software Foundation; either version 2 of the License, or
14549+ * (at your option) any later version.
14550+ *
14551+ * This program is distributed in the hope that it will be useful,
14552+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14553+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14554+ * GNU General Public License for more details.
14555+ *
14556+ * You should have received a copy of the GNU General Public License
523b37e3 14557+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 14558+ */
1facf9fc 14559+
4a4d8108
AM
14560+/*
14561+ * special support for filesystems which aqucires an inode mutex
14562+ * at final closing a file, eg, hfsplus.
14563+ *
14564+ * This trick is very simple and stupid, just to open the file before really
14565+ * neceeary open to tell hfsplus that this is not the final closing.
14566+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
14567+ * and au_h_open_post() after releasing it.
14568+ */
1facf9fc 14569+
4a4d8108 14570+#include "aufs.h"
1facf9fc 14571+
392086de
AM
14572+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
14573+ int force_wr)
4a4d8108
AM
14574+{
14575+ struct file *h_file;
14576+ struct dentry *h_dentry;
1facf9fc 14577+
4a4d8108
AM
14578+ h_dentry = au_h_dptr(dentry, bindex);
14579+ AuDebugOn(!h_dentry);
14580+ AuDebugOn(!h_dentry->d_inode);
4a4d8108
AM
14581+
14582+ h_file = NULL;
14583+ if (au_test_hfsplus(h_dentry->d_sb)
14584+ && S_ISREG(h_dentry->d_inode->i_mode))
14585+ h_file = au_h_open(dentry, bindex,
14586+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 14587+ /*file*/NULL, force_wr);
4a4d8108 14588+ return h_file;
1facf9fc 14589+}
14590+
4a4d8108
AM
14591+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
14592+ struct file *h_file)
14593+{
14594+ if (h_file) {
14595+ fput(h_file);
14596+ au_sbr_put(dentry->d_sb, bindex);
14597+ }
14598+}
7f207e10
AM
14599diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
14600--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
14601+++ linux/fs/aufs/hnotify.c 2014-08-14 10:16:04.515942371 +0200
14602@@ -0,0 +1,714 @@
e49829fe 14603+/*
523b37e3 14604+ * Copyright (C) 2005-2014 Junjiro R. Okajima
e49829fe
JR
14605+ *
14606+ * This program, aufs is free software; you can redistribute it and/or modify
14607+ * it under the terms of the GNU General Public License as published by
14608+ * the Free Software Foundation; either version 2 of the License, or
14609+ * (at your option) any later version.
14610+ *
14611+ * This program is distributed in the hope that it will be useful,
14612+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14613+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14614+ * GNU General Public License for more details.
14615+ *
14616+ * You should have received a copy of the GNU General Public License
523b37e3 14617+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
14618+ */
14619+
14620+/*
7f207e10 14621+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
14622+ */
14623+
14624+#include "aufs.h"
14625+
027c5e7a 14626+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
14627+{
14628+ int err;
7f207e10 14629+ struct au_hnotify *hn;
1facf9fc 14630+
4a4d8108
AM
14631+ err = -ENOMEM;
14632+ hn = au_cache_alloc_hnotify();
14633+ if (hn) {
14634+ hn->hn_aufs_inode = inode;
027c5e7a
AM
14635+ hinode->hi_notify = hn;
14636+ err = au_hnotify_op.alloc(hinode);
14637+ AuTraceErr(err);
14638+ if (unlikely(err)) {
14639+ hinode->hi_notify = NULL;
4a4d8108
AM
14640+ au_cache_free_hnotify(hn);
14641+ /*
14642+ * The upper dir was removed by udba, but the same named
14643+ * dir left. In this case, aufs assignes a new inode
14644+ * number and set the monitor again.
14645+ * For the lower dir, the old monitnor is still left.
14646+ */
14647+ if (err == -EEXIST)
14648+ err = 0;
14649+ }
1308ab2a 14650+ }
1308ab2a 14651+
027c5e7a 14652+ AuTraceErr(err);
1308ab2a 14653+ return err;
dece6358 14654+}
1facf9fc 14655+
4a4d8108 14656+void au_hn_free(struct au_hinode *hinode)
dece6358 14657+{
4a4d8108 14658+ struct au_hnotify *hn;
1facf9fc 14659+
4a4d8108
AM
14660+ hn = hinode->hi_notify;
14661+ if (hn) {
4a4d8108 14662+ hinode->hi_notify = NULL;
7eafdf33
AM
14663+ if (au_hnotify_op.free(hinode, hn))
14664+ au_cache_free_hnotify(hn);
4a4d8108
AM
14665+ }
14666+}
dece6358 14667+
4a4d8108 14668+/* ---------------------------------------------------------------------- */
dece6358 14669+
4a4d8108
AM
14670+void au_hn_ctl(struct au_hinode *hinode, int do_set)
14671+{
14672+ if (hinode->hi_notify)
14673+ au_hnotify_op.ctl(hinode, do_set);
14674+}
14675+
14676+void au_hn_reset(struct inode *inode, unsigned int flags)
14677+{
14678+ aufs_bindex_t bindex, bend;
14679+ struct inode *hi;
14680+ struct dentry *iwhdentry;
1facf9fc 14681+
1308ab2a 14682+ bend = au_ibend(inode);
4a4d8108
AM
14683+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14684+ hi = au_h_iptr(inode, bindex);
14685+ if (!hi)
14686+ continue;
1308ab2a 14687+
4a4d8108
AM
14688+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
14689+ iwhdentry = au_hi_wh(inode, bindex);
14690+ if (iwhdentry)
14691+ dget(iwhdentry);
14692+ au_igrab(hi);
14693+ au_set_h_iptr(inode, bindex, NULL, 0);
14694+ au_set_h_iptr(inode, bindex, au_igrab(hi),
14695+ flags & ~AuHi_XINO);
14696+ iput(hi);
14697+ dput(iwhdentry);
14698+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 14699+ }
1facf9fc 14700+}
14701+
1308ab2a 14702+/* ---------------------------------------------------------------------- */
1facf9fc 14703+
4a4d8108 14704+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 14705+{
4a4d8108
AM
14706+ int err;
14707+ aufs_bindex_t bindex, bend, bfound, bstart;
14708+ struct inode *h_i;
1facf9fc 14709+
4a4d8108
AM
14710+ err = 0;
14711+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14712+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14713+ goto out;
14714+ }
1facf9fc 14715+
4a4d8108
AM
14716+ bfound = -1;
14717+ bend = au_ibend(inode);
14718+ bstart = au_ibstart(inode);
14719+#if 0 /* reserved for future use */
14720+ if (bindex == bend) {
14721+ /* keep this ino in rename case */
14722+ goto out;
14723+ }
14724+#endif
14725+ for (bindex = bstart; bindex <= bend; bindex++)
14726+ if (au_h_iptr(inode, bindex) == h_inode) {
14727+ bfound = bindex;
14728+ break;
14729+ }
14730+ if (bfound < 0)
1308ab2a 14731+ goto out;
1facf9fc 14732+
4a4d8108
AM
14733+ for (bindex = bstart; bindex <= bend; bindex++) {
14734+ h_i = au_h_iptr(inode, bindex);
14735+ if (!h_i)
14736+ continue;
1facf9fc 14737+
4a4d8108
AM
14738+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
14739+ /* ignore this error */
14740+ /* bad action? */
1facf9fc 14741+ }
1facf9fc 14742+
4a4d8108 14743+ /* children inode number will be broken */
1facf9fc 14744+
4f0767ce 14745+out:
4a4d8108
AM
14746+ AuTraceErr(err);
14747+ return err;
1facf9fc 14748+}
14749+
4a4d8108 14750+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 14751+{
4a4d8108
AM
14752+ int err, i, j, ndentry;
14753+ struct au_dcsub_pages dpages;
14754+ struct au_dpage *dpage;
14755+ struct dentry **dentries;
1facf9fc 14756+
4a4d8108
AM
14757+ err = au_dpages_init(&dpages, GFP_NOFS);
14758+ if (unlikely(err))
14759+ goto out;
14760+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
14761+ if (unlikely(err))
14762+ goto out_dpages;
1facf9fc 14763+
4a4d8108
AM
14764+ for (i = 0; i < dpages.ndpage; i++) {
14765+ dpage = dpages.dpages + i;
14766+ dentries = dpage->dentries;
14767+ ndentry = dpage->ndentry;
14768+ for (j = 0; j < ndentry; j++) {
14769+ struct dentry *d;
14770+
14771+ d = dentries[j];
14772+ if (IS_ROOT(d))
14773+ continue;
14774+
4a4d8108
AM
14775+ au_digen_dec(d);
14776+ if (d->d_inode)
14777+ /* todo: reset children xino?
14778+ cached children only? */
14779+ au_iigen_dec(d->d_inode);
1308ab2a 14780+ }
dece6358 14781+ }
1facf9fc 14782+
4f0767ce 14783+out_dpages:
4a4d8108 14784+ au_dpages_free(&dpages);
dece6358 14785+
027c5e7a 14786+#if 0
4a4d8108
AM
14787+ /* discard children */
14788+ dentry_unhash(dentry);
14789+ dput(dentry);
027c5e7a 14790+#endif
4f0767ce 14791+out:
dece6358
AM
14792+ return err;
14793+}
14794+
1308ab2a 14795+/*
4a4d8108 14796+ * return 0 if processed.
1308ab2a 14797+ */
4a4d8108
AM
14798+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
14799+ const unsigned int isdir)
dece6358 14800+{
1308ab2a 14801+ int err;
4a4d8108
AM
14802+ struct dentry *d;
14803+ struct qstr *dname;
1facf9fc 14804+
4a4d8108
AM
14805+ err = 1;
14806+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14807+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14808+ err = 0;
14809+ goto out;
14810+ }
dece6358 14811+
4a4d8108
AM
14812+ if (!isdir) {
14813+ AuDebugOn(!name);
14814+ au_iigen_dec(inode);
027c5e7a 14815+ spin_lock(&inode->i_lock);
c06a8ce3 14816+ hlist_for_each_entry(d, &inode->i_dentry, d_alias) {
027c5e7a 14817+ spin_lock(&d->d_lock);
4a4d8108
AM
14818+ dname = &d->d_name;
14819+ if (dname->len != nlen
027c5e7a
AM
14820+ && memcmp(dname->name, name, nlen)) {
14821+ spin_unlock(&d->d_lock);
4a4d8108 14822+ continue;
027c5e7a 14823+ }
4a4d8108 14824+ err = 0;
4a4d8108
AM
14825+ au_digen_dec(d);
14826+ spin_unlock(&d->d_lock);
14827+ break;
1facf9fc 14828+ }
027c5e7a 14829+ spin_unlock(&inode->i_lock);
1308ab2a 14830+ } else {
027c5e7a 14831+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
14832+ d = d_find_alias(inode);
14833+ if (!d) {
14834+ au_iigen_dec(inode);
14835+ goto out;
14836+ }
1facf9fc 14837+
027c5e7a 14838+ spin_lock(&d->d_lock);
4a4d8108 14839+ dname = &d->d_name;
027c5e7a
AM
14840+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
14841+ spin_unlock(&d->d_lock);
4a4d8108 14842+ err = hn_gen_tree(d);
027c5e7a
AM
14843+ spin_lock(&d->d_lock);
14844+ }
14845+ spin_unlock(&d->d_lock);
4a4d8108
AM
14846+ dput(d);
14847+ }
1facf9fc 14848+
4f0767ce 14849+out:
4a4d8108 14850+ AuTraceErr(err);
1308ab2a 14851+ return err;
14852+}
dece6358 14853+
4a4d8108 14854+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 14855+{
4a4d8108
AM
14856+ int err;
14857+ struct inode *inode;
1facf9fc 14858+
4a4d8108
AM
14859+ inode = dentry->d_inode;
14860+ if (IS_ROOT(dentry)
14861+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
14862+ ) {
0c3ec466 14863+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14864+ return 0;
14865+ }
1308ab2a 14866+
4a4d8108
AM
14867+ err = 0;
14868+ if (!isdir) {
4a4d8108
AM
14869+ au_digen_dec(dentry);
14870+ if (inode)
14871+ au_iigen_dec(inode);
14872+ } else {
027c5e7a 14873+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
14874+ if (inode)
14875+ err = hn_gen_tree(dentry);
14876+ }
14877+
14878+ AuTraceErr(err);
14879+ return err;
1facf9fc 14880+}
14881+
4a4d8108 14882+/* ---------------------------------------------------------------------- */
1facf9fc 14883+
4a4d8108
AM
14884+/* hnotify job flags */
14885+#define AuHnJob_XINO0 1
14886+#define AuHnJob_GEN (1 << 1)
14887+#define AuHnJob_DIRENT (1 << 2)
14888+#define AuHnJob_ISDIR (1 << 3)
14889+#define AuHnJob_TRYXINO0 (1 << 4)
14890+#define AuHnJob_MNTPNT (1 << 5)
14891+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
14892+#define au_fset_hnjob(flags, name) \
14893+ do { (flags) |= AuHnJob_##name; } while (0)
14894+#define au_fclr_hnjob(flags, name) \
14895+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 14896+
4a4d8108
AM
14897+enum {
14898+ AuHn_CHILD,
14899+ AuHn_PARENT,
14900+ AuHnLast
14901+};
1facf9fc 14902+
4a4d8108
AM
14903+struct au_hnotify_args {
14904+ struct inode *h_dir, *dir, *h_child_inode;
14905+ u32 mask;
14906+ unsigned int flags[AuHnLast];
14907+ unsigned int h_child_nlen;
14908+ char h_child_name[];
14909+};
1facf9fc 14910+
4a4d8108
AM
14911+struct hn_job_args {
14912+ unsigned int flags;
14913+ struct inode *inode, *h_inode, *dir, *h_dir;
14914+ struct dentry *dentry;
14915+ char *h_name;
14916+ int h_nlen;
14917+};
1308ab2a 14918+
4a4d8108
AM
14919+static int hn_job(struct hn_job_args *a)
14920+{
14921+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 14922+ int e;
1308ab2a 14923+
4a4d8108
AM
14924+ /* reset xino */
14925+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
14926+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 14927+
4a4d8108
AM
14928+ if (au_ftest_hnjob(a->flags, TRYXINO0)
14929+ && a->inode
14930+ && a->h_inode) {
14931+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
38d290e6
JR
14932+ if (!a->h_inode->i_nlink
14933+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108
AM
14934+ hn_xino(a->inode, a->h_inode); /* ignore this error */
14935+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 14936+ }
1facf9fc 14937+
4a4d8108
AM
14938+ /* make the generation obsolete */
14939+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 14940+ e = -1;
4a4d8108 14941+ if (a->inode)
076b876e 14942+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 14943+ isdir);
076b876e 14944+ if (e && a->dentry)
4a4d8108
AM
14945+ hn_gen_by_name(a->dentry, isdir);
14946+ /* ignore this error */
1facf9fc 14947+ }
1facf9fc 14948+
4a4d8108
AM
14949+ /* make dir entries obsolete */
14950+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
14951+ struct au_vdir *vdir;
1facf9fc 14952+
4a4d8108
AM
14953+ vdir = au_ivdir(a->inode);
14954+ if (vdir)
14955+ vdir->vd_jiffy = 0;
14956+ /* IMustLock(a->inode); */
14957+ /* a->inode->i_version++; */
14958+ }
1facf9fc 14959+
4a4d8108
AM
14960+ /* can do nothing but warn */
14961+ if (au_ftest_hnjob(a->flags, MNTPNT)
14962+ && a->dentry
14963+ && d_mountpoint(a->dentry))
523b37e3 14964+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 14965+
4a4d8108 14966+ return 0;
1308ab2a 14967+}
1facf9fc 14968+
1308ab2a 14969+/* ---------------------------------------------------------------------- */
1facf9fc 14970+
4a4d8108
AM
14971+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
14972+ struct inode *dir)
1308ab2a 14973+{
4a4d8108
AM
14974+ struct dentry *dentry, *d, *parent;
14975+ struct qstr *dname;
1308ab2a 14976+
4a4d8108
AM
14977+ parent = d_find_alias(dir);
14978+ if (!parent)
14979+ return NULL;
1308ab2a 14980+
4a4d8108 14981+ dentry = NULL;
027c5e7a 14982+ spin_lock(&parent->d_lock);
4a4d8108 14983+ list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) {
523b37e3 14984+ /* AuDbg("%pd\n", d); */
027c5e7a 14985+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
14986+ dname = &d->d_name;
14987+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
14988+ goto cont_unlock;
14989+ if (au_di(d))
14990+ au_digen_dec(d);
14991+ else
14992+ goto cont_unlock;
392086de 14993+ if (d_count(d)) {
027c5e7a 14994+ dentry = dget_dlock(d);
4a4d8108 14995+ spin_unlock(&d->d_lock);
027c5e7a 14996+ break;
dece6358 14997+ }
1facf9fc 14998+
f6b6e03d 14999+cont_unlock:
027c5e7a 15000+ spin_unlock(&d->d_lock);
1308ab2a 15001+ }
027c5e7a 15002+ spin_unlock(&parent->d_lock);
4a4d8108 15003+ dput(parent);
1facf9fc 15004+
4a4d8108
AM
15005+ if (dentry)
15006+ di_write_lock_child(dentry);
1308ab2a 15007+
4a4d8108
AM
15008+ return dentry;
15009+}
dece6358 15010+
4a4d8108
AM
15011+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
15012+ aufs_bindex_t bindex, ino_t h_ino)
15013+{
15014+ struct inode *inode;
15015+ ino_t ino;
15016+ int err;
15017+
15018+ inode = NULL;
15019+ err = au_xino_read(sb, bindex, h_ino, &ino);
15020+ if (!err && ino)
15021+ inode = ilookup(sb, ino);
15022+ if (!inode)
15023+ goto out;
15024+
15025+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 15026+ pr_warn("wrong root branch\n");
4a4d8108
AM
15027+ iput(inode);
15028+ inode = NULL;
15029+ goto out;
1308ab2a 15030+ }
15031+
4a4d8108 15032+ ii_write_lock_child(inode);
1308ab2a 15033+
4f0767ce 15034+out:
4a4d8108 15035+ return inode;
dece6358
AM
15036+}
15037+
4a4d8108 15038+static void au_hn_bh(void *_args)
1facf9fc 15039+{
4a4d8108
AM
15040+ struct au_hnotify_args *a = _args;
15041+ struct super_block *sb;
15042+ aufs_bindex_t bindex, bend, bfound;
15043+ unsigned char xino, try_iput;
1facf9fc 15044+ int err;
1308ab2a 15045+ struct inode *inode;
4a4d8108
AM
15046+ ino_t h_ino;
15047+ struct hn_job_args args;
15048+ struct dentry *dentry;
15049+ struct au_sbinfo *sbinfo;
1facf9fc 15050+
4a4d8108
AM
15051+ AuDebugOn(!_args);
15052+ AuDebugOn(!a->h_dir);
15053+ AuDebugOn(!a->dir);
15054+ AuDebugOn(!a->mask);
15055+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
15056+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
15057+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 15058+
4a4d8108
AM
15059+ inode = NULL;
15060+ dentry = NULL;
15061+ /*
15062+ * do not lock a->dir->i_mutex here
15063+ * because of d_revalidate() may cause a deadlock.
15064+ */
15065+ sb = a->dir->i_sb;
15066+ AuDebugOn(!sb);
15067+ sbinfo = au_sbi(sb);
15068+ AuDebugOn(!sbinfo);
7f207e10 15069+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 15070+
4a4d8108
AM
15071+ ii_read_lock_parent(a->dir);
15072+ bfound = -1;
15073+ bend = au_ibend(a->dir);
15074+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
15075+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
15076+ bfound = bindex;
15077+ break;
15078+ }
15079+ ii_read_unlock(a->dir);
15080+ if (unlikely(bfound < 0))
15081+ goto out;
1facf9fc 15082+
4a4d8108
AM
15083+ xino = !!au_opt_test(au_mntflags(sb), XINO);
15084+ h_ino = 0;
15085+ if (a->h_child_inode)
15086+ h_ino = a->h_child_inode->i_ino;
1facf9fc 15087+
4a4d8108
AM
15088+ if (a->h_child_nlen
15089+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
15090+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
15091+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
15092+ a->dir);
15093+ try_iput = 0;
15094+ if (dentry)
15095+ inode = dentry->d_inode;
15096+ if (xino && !inode && h_ino
15097+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
15098+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
15099+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
15100+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
15101+ try_iput = 1;
15102+ }
1facf9fc 15103+
4a4d8108
AM
15104+ args.flags = a->flags[AuHn_CHILD];
15105+ args.dentry = dentry;
15106+ args.inode = inode;
15107+ args.h_inode = a->h_child_inode;
15108+ args.dir = a->dir;
15109+ args.h_dir = a->h_dir;
15110+ args.h_name = a->h_child_name;
15111+ args.h_nlen = a->h_child_nlen;
15112+ err = hn_job(&args);
15113+ if (dentry) {
027c5e7a 15114+ if (au_di(dentry))
4a4d8108
AM
15115+ di_write_unlock(dentry);
15116+ dput(dentry);
15117+ }
15118+ if (inode && try_iput) {
15119+ ii_write_unlock(inode);
15120+ iput(inode);
15121+ }
1facf9fc 15122+
4a4d8108
AM
15123+ ii_write_lock_parent(a->dir);
15124+ args.flags = a->flags[AuHn_PARENT];
15125+ args.dentry = NULL;
15126+ args.inode = a->dir;
15127+ args.h_inode = a->h_dir;
15128+ args.dir = NULL;
15129+ args.h_dir = NULL;
15130+ args.h_name = NULL;
15131+ args.h_nlen = 0;
15132+ err = hn_job(&args);
15133+ ii_write_unlock(a->dir);
1facf9fc 15134+
4f0767ce 15135+out:
4a4d8108
AM
15136+ iput(a->h_child_inode);
15137+ iput(a->h_dir);
15138+ iput(a->dir);
027c5e7a
AM
15139+ si_write_unlock(sb);
15140+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 15141+ kfree(a);
dece6358 15142+}
1facf9fc 15143+
4a4d8108
AM
15144+/* ---------------------------------------------------------------------- */
15145+
15146+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15147+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 15148+{
4a4d8108 15149+ int err, len;
53392da6 15150+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
15151+ unsigned char isdir, isroot, wh;
15152+ struct inode *dir;
15153+ struct au_hnotify_args *args;
15154+ char *p, *h_child_name;
dece6358 15155+
1308ab2a 15156+ err = 0;
4a4d8108
AM
15157+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
15158+ dir = igrab(hnotify->hn_aufs_inode);
15159+ if (!dir)
15160+ goto out;
1facf9fc 15161+
4a4d8108
AM
15162+ isroot = (dir->i_ino == AUFS_ROOT_INO);
15163+ wh = 0;
15164+ h_child_name = (void *)h_child_qstr->name;
15165+ len = h_child_qstr->len;
15166+ if (h_child_name) {
15167+ if (len > AUFS_WH_PFX_LEN
15168+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
15169+ h_child_name += AUFS_WH_PFX_LEN;
15170+ len -= AUFS_WH_PFX_LEN;
15171+ wh = 1;
15172+ }
1facf9fc 15173+ }
dece6358 15174+
4a4d8108
AM
15175+ isdir = 0;
15176+ if (h_child_inode)
15177+ isdir = !!S_ISDIR(h_child_inode->i_mode);
15178+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
15179+ flags[AuHn_CHILD] = 0;
15180+ if (isdir)
15181+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
15182+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
15183+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
15184+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
15185+ case FS_MOVED_FROM:
15186+ case FS_MOVED_TO:
15187+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
15188+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15189+ /*FALLTHROUGH*/
15190+ case FS_CREATE:
fb47a38f 15191+ AuDebugOn(!h_child_name);
4a4d8108 15192+ break;
1facf9fc 15193+
4a4d8108
AM
15194+ case FS_DELETE:
15195+ /*
15196+ * aufs never be able to get this child inode.
15197+ * revalidation should be in d_revalidate()
15198+ * by checking i_nlink, i_generation or d_unhashed().
15199+ */
15200+ AuDebugOn(!h_child_name);
15201+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
15202+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15203+ break;
dece6358 15204+
4a4d8108
AM
15205+ default:
15206+ AuDebugOn(1);
15207+ }
1308ab2a 15208+
4a4d8108
AM
15209+ if (wh)
15210+ h_child_inode = NULL;
1308ab2a 15211+
4a4d8108
AM
15212+ err = -ENOMEM;
15213+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 15214+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
15215+ if (unlikely(!args)) {
15216+ AuErr1("no memory\n");
15217+ iput(dir);
15218+ goto out;
15219+ }
15220+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
15221+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
15222+ args->mask = mask;
15223+ args->dir = dir;
15224+ args->h_dir = igrab(h_dir);
15225+ if (h_child_inode)
15226+ h_child_inode = igrab(h_child_inode); /* can be NULL */
15227+ args->h_child_inode = h_child_inode;
15228+ args->h_child_nlen = len;
15229+ if (len) {
15230+ p = (void *)args;
15231+ p += sizeof(*args);
15232+ memcpy(p, h_child_name, len);
15233+ p[len] = 0;
1308ab2a 15234+ }
1308ab2a 15235+
38d290e6 15236+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 15237+ f = 0;
38d290e6
JR
15238+ if (!dir->i_nlink
15239+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
15240+ f = AuWkq_NEST;
15241+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
15242+ if (unlikely(err)) {
15243+ pr_err("wkq %d\n", err);
15244+ iput(args->h_child_inode);
15245+ iput(args->h_dir);
15246+ iput(args->dir);
15247+ kfree(args);
1facf9fc 15248+ }
1facf9fc 15249+
4a4d8108 15250+out:
1facf9fc 15251+ return err;
15252+}
15253+
027c5e7a
AM
15254+/* ---------------------------------------------------------------------- */
15255+
15256+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
15257+{
15258+ int err;
15259+
15260+ AuDebugOn(!(udba & AuOptMask_UDBA));
15261+
15262+ err = 0;
15263+ if (au_hnotify_op.reset_br)
15264+ err = au_hnotify_op.reset_br(udba, br, perm);
15265+
15266+ return err;
15267+}
15268+
15269+int au_hnotify_init_br(struct au_branch *br, int perm)
15270+{
15271+ int err;
15272+
15273+ err = 0;
15274+ if (au_hnotify_op.init_br)
15275+ err = au_hnotify_op.init_br(br, perm);
15276+
15277+ return err;
15278+}
15279+
15280+void au_hnotify_fin_br(struct au_branch *br)
15281+{
15282+ if (au_hnotify_op.fin_br)
15283+ au_hnotify_op.fin_br(br);
15284+}
15285+
4a4d8108
AM
15286+static void au_hn_destroy_cache(void)
15287+{
15288+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
15289+ au_cachep[AuCache_HNOTIFY] = NULL;
15290+}
1308ab2a 15291+
4a4d8108 15292+int __init au_hnotify_init(void)
1facf9fc 15293+{
1308ab2a 15294+ int err;
1308ab2a 15295+
4a4d8108
AM
15296+ err = -ENOMEM;
15297+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
15298+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
15299+ err = 0;
15300+ if (au_hnotify_op.init)
15301+ err = au_hnotify_op.init();
4a4d8108
AM
15302+ if (unlikely(err))
15303+ au_hn_destroy_cache();
1308ab2a 15304+ }
1308ab2a 15305+ AuTraceErr(err);
4a4d8108 15306+ return err;
1308ab2a 15307+}
15308+
4a4d8108 15309+void au_hnotify_fin(void)
1308ab2a 15310+{
027c5e7a
AM
15311+ if (au_hnotify_op.fin)
15312+ au_hnotify_op.fin();
4a4d8108
AM
15313+ /* cf. au_cache_fin() */
15314+ if (au_cachep[AuCache_HNOTIFY])
15315+ au_hn_destroy_cache();
dece6358 15316+}
7f207e10
AM
15317diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
15318--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
076b876e 15319+++ linux/fs/aufs/iinfo.c 2014-08-14 10:15:45.128609525 +0200
38d290e6 15320@@ -0,0 +1,277 @@
dece6358 15321+/*
523b37e3 15322+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
15323+ *
15324+ * This program, aufs is free software; you can redistribute it and/or modify
15325+ * it under the terms of the GNU General Public License as published by
15326+ * the Free Software Foundation; either version 2 of the License, or
15327+ * (at your option) any later version.
15328+ *
15329+ * This program is distributed in the hope that it will be useful,
15330+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15331+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15332+ * GNU General Public License for more details.
15333+ *
15334+ * You should have received a copy of the GNU General Public License
523b37e3 15335+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15336+ */
1facf9fc 15337+
dece6358 15338+/*
4a4d8108 15339+ * inode private data
dece6358 15340+ */
1facf9fc 15341+
1308ab2a 15342+#include "aufs.h"
1facf9fc 15343+
4a4d8108 15344+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15345+{
4a4d8108 15346+ struct inode *h_inode;
1facf9fc 15347+
4a4d8108 15348+ IiMustAnyLock(inode);
1facf9fc 15349+
4a4d8108
AM
15350+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
15351+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15352+ return h_inode;
15353+}
1facf9fc 15354+
4a4d8108
AM
15355+/* todo: hard/soft set? */
15356+void au_hiput(struct au_hinode *hinode)
15357+{
15358+ au_hn_free(hinode);
15359+ dput(hinode->hi_whdentry);
15360+ iput(hinode->hi_inode);
15361+}
1facf9fc 15362+
4a4d8108
AM
15363+unsigned int au_hi_flags(struct inode *inode, int isdir)
15364+{
15365+ unsigned int flags;
15366+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 15367+
4a4d8108
AM
15368+ flags = 0;
15369+ if (au_opt_test(mnt_flags, XINO))
15370+ au_fset_hi(flags, XINO);
15371+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
15372+ au_fset_hi(flags, HNOTIFY);
15373+ return flags;
1facf9fc 15374+}
15375+
4a4d8108
AM
15376+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15377+ struct inode *h_inode, unsigned int flags)
1308ab2a 15378+{
4a4d8108
AM
15379+ struct au_hinode *hinode;
15380+ struct inode *hi;
15381+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 15382+
4a4d8108 15383+ IiMustWriteLock(inode);
dece6358 15384+
4a4d8108
AM
15385+ hinode = iinfo->ii_hinode + bindex;
15386+ hi = hinode->hi_inode;
15387+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15388+
15389+ if (hi)
15390+ au_hiput(hinode);
15391+ hinode->hi_inode = h_inode;
15392+ if (h_inode) {
15393+ int err;
15394+ struct super_block *sb = inode->i_sb;
15395+ struct au_branch *br;
15396+
027c5e7a
AM
15397+ AuDebugOn(inode->i_mode
15398+ && (h_inode->i_mode & S_IFMT)
15399+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
15400+ if (bindex == iinfo->ii_bstart)
15401+ au_cpup_igen(inode, h_inode);
15402+ br = au_sbr(sb, bindex);
15403+ hinode->hi_id = br->br_id;
15404+ if (au_ftest_hi(flags, XINO)) {
15405+ err = au_xino_write(sb, bindex, h_inode->i_ino,
15406+ inode->i_ino);
15407+ if (unlikely(err))
15408+ AuIOErr1("failed au_xino_write() %d\n", err);
15409+ }
15410+
15411+ if (au_ftest_hi(flags, HNOTIFY)
15412+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 15413+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
15414+ if (unlikely(err))
15415+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 15416+ }
15417+ }
4a4d8108 15418+}
dece6358 15419+
4a4d8108
AM
15420+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15421+ struct dentry *h_wh)
15422+{
15423+ struct au_hinode *hinode;
dece6358 15424+
4a4d8108
AM
15425+ IiMustWriteLock(inode);
15426+
15427+ hinode = au_ii(inode)->ii_hinode + bindex;
15428+ AuDebugOn(hinode->hi_whdentry);
15429+ hinode->hi_whdentry = h_wh;
1facf9fc 15430+}
15431+
537831f9 15432+void au_update_iigen(struct inode *inode, int half)
1308ab2a 15433+{
537831f9
AM
15434+ struct au_iinfo *iinfo;
15435+ struct au_iigen *iigen;
15436+ unsigned int sigen;
15437+
15438+ sigen = au_sigen(inode->i_sb);
15439+ iinfo = au_ii(inode);
15440+ iigen = &iinfo->ii_generation;
15441+ spin_lock(&iinfo->ii_genspin);
15442+ iigen->ig_generation = sigen;
15443+ if (half)
15444+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
15445+ else
15446+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
15447+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 15448+}
1facf9fc 15449+
4a4d8108
AM
15450+/* it may be called at remount time, too */
15451+void au_update_ibrange(struct inode *inode, int do_put_zero)
15452+{
15453+ struct au_iinfo *iinfo;
027c5e7a 15454+ aufs_bindex_t bindex, bend;
1facf9fc 15455+
4a4d8108 15456+ iinfo = au_ii(inode);
027c5e7a 15457+ if (!iinfo)
4a4d8108 15458+ return;
1facf9fc 15459+
4a4d8108 15460+ IiMustWriteLock(inode);
1facf9fc 15461+
027c5e7a 15462+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
15463+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15464+ bindex++) {
15465+ struct inode *h_i;
1facf9fc 15466+
4a4d8108 15467+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
38d290e6
JR
15468+ if (h_i
15469+ && !h_i->i_nlink
15470+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
15471+ au_set_h_iptr(inode, bindex, NULL, 0);
15472+ }
4a4d8108
AM
15473+ }
15474+
027c5e7a
AM
15475+ iinfo->ii_bstart = -1;
15476+ iinfo->ii_bend = -1;
15477+ bend = au_sbend(inode->i_sb);
15478+ for (bindex = 0; bindex <= bend; bindex++)
15479+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15480+ iinfo->ii_bstart = bindex;
4a4d8108 15481+ break;
027c5e7a
AM
15482+ }
15483+ if (iinfo->ii_bstart >= 0)
15484+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
15485+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15486+ iinfo->ii_bend = bindex;
15487+ break;
15488+ }
15489+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 15490+}
1facf9fc 15491+
dece6358 15492+/* ---------------------------------------------------------------------- */
1facf9fc 15493+
4a4d8108 15494+void au_icntnr_init_once(void *_c)
dece6358 15495+{
4a4d8108
AM
15496+ struct au_icntnr *c = _c;
15497+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 15498+ static struct lock_class_key aufs_ii;
1facf9fc 15499+
537831f9 15500+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 15501+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 15502+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
15503+ inode_init_once(&c->vfs_inode);
15504+}
1facf9fc 15505+
4a4d8108
AM
15506+int au_iinfo_init(struct inode *inode)
15507+{
15508+ struct au_iinfo *iinfo;
15509+ struct super_block *sb;
15510+ int nbr, i;
1facf9fc 15511+
4a4d8108
AM
15512+ sb = inode->i_sb;
15513+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
15514+ nbr = au_sbend(sb) + 1;
15515+ if (unlikely(nbr <= 0))
15516+ nbr = 1;
15517+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
15518+ if (iinfo->ii_hinode) {
7f207e10 15519+ au_ninodes_inc(sb);
4a4d8108
AM
15520+ for (i = 0; i < nbr; i++)
15521+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 15522+
537831f9 15523+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
15524+ iinfo->ii_bstart = -1;
15525+ iinfo->ii_bend = -1;
15526+ iinfo->ii_vdir = NULL;
15527+ return 0;
1308ab2a 15528+ }
4a4d8108
AM
15529+ return -ENOMEM;
15530+}
1facf9fc 15531+
4a4d8108
AM
15532+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
15533+{
15534+ int err, sz;
15535+ struct au_hinode *hip;
1facf9fc 15536+
4a4d8108
AM
15537+ AuRwMustWriteLock(&iinfo->ii_rwsem);
15538+
15539+ err = -ENOMEM;
15540+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
15541+ if (!sz)
15542+ sz = sizeof(*hip);
15543+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
15544+ if (hip) {
15545+ iinfo->ii_hinode = hip;
15546+ err = 0;
1308ab2a 15547+ }
4a4d8108 15548+
1308ab2a 15549+ return err;
1facf9fc 15550+}
15551+
4a4d8108 15552+void au_iinfo_fin(struct inode *inode)
1facf9fc 15553+{
4a4d8108
AM
15554+ struct au_iinfo *iinfo;
15555+ struct au_hinode *hi;
15556+ struct super_block *sb;
b752ccd1
AM
15557+ aufs_bindex_t bindex, bend;
15558+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 15559+
4a4d8108
AM
15560+ iinfo = au_ii(inode);
15561+ /* bad_inode case */
15562+ if (!iinfo)
15563+ return;
1308ab2a 15564+
b752ccd1 15565+ sb = inode->i_sb;
7f207e10 15566+ au_ninodes_dec(sb);
b752ccd1
AM
15567+ if (si_pid_test(sb))
15568+ au_xino_delete_inode(inode, unlinked);
15569+ else {
15570+ /*
15571+ * it is safe to hide the dependency between sbinfo and
15572+ * sb->s_umount.
15573+ */
15574+ lockdep_off();
15575+ si_noflush_read_lock(sb);
15576+ au_xino_delete_inode(inode, unlinked);
15577+ si_read_unlock(sb);
15578+ lockdep_on();
15579+ }
15580+
4a4d8108
AM
15581+ if (iinfo->ii_vdir)
15582+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 15583+
b752ccd1
AM
15584+ bindex = iinfo->ii_bstart;
15585+ if (bindex >= 0) {
15586+ hi = iinfo->ii_hinode + bindex;
4a4d8108 15587+ bend = iinfo->ii_bend;
b752ccd1
AM
15588+ while (bindex++ <= bend) {
15589+ if (hi->hi_inode)
4a4d8108 15590+ au_hiput(hi);
4a4d8108
AM
15591+ hi++;
15592+ }
15593+ }
4a4d8108 15594+ kfree(iinfo->ii_hinode);
027c5e7a 15595+ iinfo->ii_hinode = NULL;
4a4d8108 15596+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 15597+}
7f207e10
AM
15598diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
15599--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
15600+++ linux/fs/aufs/inode.c 2014-08-14 10:15:45.128609525 +0200
15601@@ -0,0 +1,492 @@
4a4d8108 15602+/*
523b37e3 15603+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
15604+ *
15605+ * This program, aufs is free software; you can redistribute it and/or modify
15606+ * it under the terms of the GNU General Public License as published by
15607+ * the Free Software Foundation; either version 2 of the License, or
15608+ * (at your option) any later version.
15609+ *
15610+ * This program is distributed in the hope that it will be useful,
15611+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15612+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15613+ * GNU General Public License for more details.
15614+ *
15615+ * You should have received a copy of the GNU General Public License
523b37e3 15616+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15617+ */
1facf9fc 15618+
4a4d8108
AM
15619+/*
15620+ * inode functions
15621+ */
1facf9fc 15622+
4a4d8108 15623+#include "aufs.h"
1308ab2a 15624+
4a4d8108
AM
15625+struct inode *au_igrab(struct inode *inode)
15626+{
15627+ if (inode) {
15628+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 15629+ ihold(inode);
1facf9fc 15630+ }
4a4d8108
AM
15631+ return inode;
15632+}
1facf9fc 15633+
4a4d8108
AM
15634+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
15635+{
15636+ au_cpup_attr_all(inode, /*force*/0);
537831f9 15637+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
15638+ if (do_version)
15639+ inode->i_version++;
dece6358 15640+}
1facf9fc 15641+
027c5e7a 15642+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 15643+{
4a4d8108 15644+ int err, e;
027c5e7a 15645+ umode_t type;
4a4d8108 15646+ aufs_bindex_t bindex, new_bindex;
1308ab2a 15647+ struct super_block *sb;
4a4d8108 15648+ struct au_iinfo *iinfo;
027c5e7a 15649+ struct au_hinode *p, *q, tmp;
1facf9fc 15650+
4a4d8108 15651+ IiMustWriteLock(inode);
1facf9fc 15652+
027c5e7a 15653+ *update = 0;
4a4d8108 15654+ sb = inode->i_sb;
027c5e7a 15655+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
15656+ iinfo = au_ii(inode);
15657+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
15658+ if (unlikely(err))
1308ab2a 15659+ goto out;
1facf9fc 15660+
027c5e7a 15661+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 15662+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
15663+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15664+ bindex++, p++) {
15665+ if (!p->hi_inode)
15666+ continue;
1facf9fc 15667+
027c5e7a 15668+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
15669+ new_bindex = au_br_index(sb, p->hi_id);
15670+ if (new_bindex == bindex)
15671+ continue;
1facf9fc 15672+
4a4d8108 15673+ if (new_bindex < 0) {
027c5e7a 15674+ *update = 1;
4a4d8108
AM
15675+ au_hiput(p);
15676+ p->hi_inode = NULL;
15677+ continue;
1308ab2a 15678+ }
4a4d8108
AM
15679+
15680+ if (new_bindex < iinfo->ii_bstart)
15681+ iinfo->ii_bstart = new_bindex;
15682+ if (iinfo->ii_bend < new_bindex)
15683+ iinfo->ii_bend = new_bindex;
15684+ /* swap two lower inode, and loop again */
15685+ q = iinfo->ii_hinode + new_bindex;
15686+ tmp = *q;
15687+ *q = *p;
15688+ *p = tmp;
15689+ if (tmp.hi_inode) {
15690+ bindex--;
15691+ p--;
1308ab2a 15692+ }
15693+ }
4a4d8108
AM
15694+ au_update_ibrange(inode, /*do_put_zero*/0);
15695+ e = au_dy_irefresh(inode);
15696+ if (unlikely(e && !err))
15697+ err = e;
1facf9fc 15698+
4f0767ce 15699+out:
027c5e7a
AM
15700+ AuTraceErr(err);
15701+ return err;
15702+}
15703+
15704+int au_refresh_hinode_self(struct inode *inode)
15705+{
15706+ int err, update;
15707+
15708+ err = au_ii_refresh(inode, &update);
15709+ if (!err)
15710+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
15711+
15712+ AuTraceErr(err);
4a4d8108
AM
15713+ return err;
15714+}
1facf9fc 15715+
4a4d8108
AM
15716+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
15717+{
027c5e7a 15718+ int err, e, update;
4a4d8108 15719+ unsigned int flags;
027c5e7a 15720+ umode_t mode;
4a4d8108 15721+ aufs_bindex_t bindex, bend;
027c5e7a 15722+ unsigned char isdir;
4a4d8108
AM
15723+ struct au_hinode *p;
15724+ struct au_iinfo *iinfo;
1facf9fc 15725+
027c5e7a 15726+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
15727+ if (unlikely(err))
15728+ goto out;
15729+
15730+ update = 0;
15731+ iinfo = au_ii(inode);
15732+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
15733+ mode = (inode->i_mode & S_IFMT);
15734+ isdir = S_ISDIR(mode);
4a4d8108
AM
15735+ flags = au_hi_flags(inode, isdir);
15736+ bend = au_dbend(dentry);
15737+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
15738+ struct inode *h_i;
15739+ struct dentry *h_d;
15740+
15741+ h_d = au_h_dptr(dentry, bindex);
15742+ if (!h_d || !h_d->d_inode)
15743+ continue;
15744+
027c5e7a 15745+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
15746+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
15747+ h_i = au_h_iptr(inode, bindex);
15748+ if (h_i) {
15749+ if (h_i == h_d->d_inode)
15750+ continue;
15751+ err = -EIO;
15752+ break;
15753+ }
15754+ }
15755+ if (bindex < iinfo->ii_bstart)
15756+ iinfo->ii_bstart = bindex;
15757+ if (iinfo->ii_bend < bindex)
15758+ iinfo->ii_bend = bindex;
15759+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
15760+ update = 1;
1308ab2a 15761+ }
4a4d8108
AM
15762+ au_update_ibrange(inode, /*do_put_zero*/0);
15763+ e = au_dy_irefresh(inode);
15764+ if (unlikely(e && !err))
15765+ err = e;
027c5e7a
AM
15766+ if (!err)
15767+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 15768+
4f0767ce 15769+out:
4a4d8108 15770+ AuTraceErr(err);
1308ab2a 15771+ return err;
dece6358
AM
15772+}
15773+
4a4d8108 15774+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 15775+{
4a4d8108
AM
15776+ int err;
15777+ unsigned int flags;
15778+ umode_t mode;
15779+ aufs_bindex_t bindex, bstart, btail;
15780+ unsigned char isdir;
15781+ struct dentry *h_dentry;
15782+ struct inode *h_inode;
15783+ struct au_iinfo *iinfo;
dece6358 15784+
4a4d8108 15785+ IiMustWriteLock(inode);
dece6358 15786+
4a4d8108
AM
15787+ err = 0;
15788+ isdir = 0;
15789+ bstart = au_dbstart(dentry);
15790+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
15791+ mode = h_inode->i_mode;
15792+ switch (mode & S_IFMT) {
15793+ case S_IFREG:
15794+ btail = au_dbtail(dentry);
15795+ inode->i_op = &aufs_iop;
15796+ inode->i_fop = &aufs_file_fop;
15797+ err = au_dy_iaop(inode, bstart, h_inode);
15798+ if (unlikely(err))
15799+ goto out;
15800+ break;
15801+ case S_IFDIR:
15802+ isdir = 1;
15803+ btail = au_dbtaildir(dentry);
15804+ inode->i_op = &aufs_dir_iop;
15805+ inode->i_fop = &aufs_dir_fop;
15806+ break;
15807+ case S_IFLNK:
15808+ btail = au_dbtail(dentry);
15809+ inode->i_op = &aufs_symlink_iop;
15810+ break;
15811+ case S_IFBLK:
15812+ case S_IFCHR:
15813+ case S_IFIFO:
15814+ case S_IFSOCK:
15815+ btail = au_dbtail(dentry);
15816+ inode->i_op = &aufs_iop;
38d290e6 15817+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
15818+ break;
15819+ default:
15820+ AuIOErr("Unknown file type 0%o\n", mode);
15821+ err = -EIO;
1308ab2a 15822+ goto out;
4a4d8108 15823+ }
dece6358 15824+
4a4d8108
AM
15825+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
15826+ flags = au_hi_flags(inode, isdir);
15827+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
15828+ && au_ftest_hi(flags, HNOTIFY)
15829+ && dentry->d_name.len > AUFS_WH_PFX_LEN
15830+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
15831+ au_fclr_hi(flags, HNOTIFY);
15832+ iinfo = au_ii(inode);
15833+ iinfo->ii_bstart = bstart;
15834+ iinfo->ii_bend = btail;
15835+ for (bindex = bstart; bindex <= btail; bindex++) {
15836+ h_dentry = au_h_dptr(dentry, bindex);
15837+ if (h_dentry)
15838+ au_set_h_iptr(inode, bindex,
15839+ au_igrab(h_dentry->d_inode), flags);
15840+ }
15841+ au_cpup_attr_all(inode, /*force*/1);
dece6358 15842+
4f0767ce 15843+out:
4a4d8108
AM
15844+ return err;
15845+}
dece6358 15846+
027c5e7a
AM
15847+/*
15848+ * successful returns with iinfo write_locked
15849+ * minus: errno
15850+ * zero: success, matched
15851+ * plus: no error, but unmatched
15852+ */
15853+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
15854+{
15855+ int err;
537831f9
AM
15856+ unsigned int gen;
15857+ struct au_iigen iigen;
4a4d8108
AM
15858+ aufs_bindex_t bindex, bend;
15859+ struct inode *h_inode, *h_dinode;
dece6358 15860+
4a4d8108
AM
15861+ /*
15862+ * before this function, if aufs got any iinfo lock, it must be only
15863+ * one, the parent dir.
15864+ * it can happen by UDBA and the obsoleted inode number.
15865+ */
15866+ err = -EIO;
15867+ if (unlikely(inode->i_ino == parent_ino(dentry)))
15868+ goto out;
15869+
027c5e7a 15870+ err = 1;
4a4d8108
AM
15871+ ii_write_lock_new_child(inode);
15872+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
15873+ bend = au_ibend(inode);
15874+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
15875+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
15876+ if (!h_inode || h_inode != h_dinode)
15877+ continue;
15878+
15879+ err = 0;
15880+ gen = au_iigen(inode, &iigen);
15881+ if (gen == au_digen(dentry)
15882+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 15883+ break;
537831f9
AM
15884+
15885+ /* fully refresh inode using dentry */
15886+ err = au_refresh_hinode(inode, dentry);
15887+ if (!err)
15888+ au_update_iigen(inode, /*half*/0);
15889+ break;
1facf9fc 15890+ }
dece6358 15891+
4a4d8108
AM
15892+ if (unlikely(err))
15893+ ii_write_unlock(inode);
4f0767ce 15894+out:
1facf9fc 15895+ return err;
15896+}
1facf9fc 15897+
4a4d8108
AM
15898+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
15899+ unsigned int d_type, ino_t *ino)
1facf9fc 15900+{
4a4d8108
AM
15901+ int err;
15902+ struct mutex *mtx;
1facf9fc 15903+
b752ccd1 15904+ /* prevent hardlinked inode number from race condition */
4a4d8108 15905+ mtx = NULL;
b752ccd1 15906+ if (d_type != DT_DIR) {
4a4d8108
AM
15907+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
15908+ mutex_lock(mtx);
15909+ }
15910+ err = au_xino_read(sb, bindex, h_ino, ino);
15911+ if (unlikely(err))
15912+ goto out;
1308ab2a 15913+
4a4d8108
AM
15914+ if (!*ino) {
15915+ err = -EIO;
15916+ *ino = au_xino_new_ino(sb);
15917+ if (unlikely(!*ino))
1facf9fc 15918+ goto out;
4a4d8108
AM
15919+ err = au_xino_write(sb, bindex, h_ino, *ino);
15920+ if (unlikely(err))
1308ab2a 15921+ goto out;
1308ab2a 15922+ }
1facf9fc 15923+
4f0767ce 15924+out:
b752ccd1 15925+ if (mtx)
4a4d8108 15926+ mutex_unlock(mtx);
1facf9fc 15927+ return err;
15928+}
15929+
4a4d8108
AM
15930+/* successful returns with iinfo write_locked */
15931+/* todo: return with unlocked? */
15932+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 15933+{
b752ccd1 15934+ struct inode *inode, *h_inode;
4a4d8108
AM
15935+ struct dentry *h_dentry;
15936+ struct super_block *sb;
b752ccd1 15937+ struct mutex *mtx;
4a4d8108 15938+ ino_t h_ino, ino;
1716fcea 15939+ int err;
4a4d8108 15940+ aufs_bindex_t bstart;
1facf9fc 15941+
4a4d8108
AM
15942+ sb = dentry->d_sb;
15943+ bstart = au_dbstart(dentry);
15944+ h_dentry = au_h_dptr(dentry, bstart);
b752ccd1
AM
15945+ h_inode = h_dentry->d_inode;
15946+ h_ino = h_inode->i_ino;
15947+
15948+ /*
15949+ * stop 'race'-ing between hardlinks under different
15950+ * parents.
15951+ */
15952+ mtx = NULL;
15953+ if (!S_ISDIR(h_inode->i_mode))
15954+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
15955+
4f0767ce 15956+new_ino:
b752ccd1
AM
15957+ if (mtx)
15958+ mutex_lock(mtx);
4a4d8108
AM
15959+ err = au_xino_read(sb, bstart, h_ino, &ino);
15960+ inode = ERR_PTR(err);
15961+ if (unlikely(err))
15962+ goto out;
b752ccd1 15963+
4a4d8108
AM
15964+ if (!ino) {
15965+ ino = au_xino_new_ino(sb);
15966+ if (unlikely(!ino)) {
15967+ inode = ERR_PTR(-EIO);
dece6358
AM
15968+ goto out;
15969+ }
15970+ }
1facf9fc 15971+
4a4d8108
AM
15972+ AuDbg("i%lu\n", (unsigned long)ino);
15973+ inode = au_iget_locked(sb, ino);
15974+ err = PTR_ERR(inode);
15975+ if (IS_ERR(inode))
1facf9fc 15976+ goto out;
1facf9fc 15977+
4a4d8108
AM
15978+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
15979+ if (inode->i_state & I_NEW) {
1716fcea
AM
15980+ /* verbose coding for lock class name */
15981+ if (unlikely(S_ISLNK(h_inode->i_mode)))
15982+ au_rw_class(&au_ii(inode)->ii_rwsem,
15983+ au_lc_key + AuLcSymlink_IIINFO);
15984+ else if (unlikely(S_ISDIR(h_inode->i_mode)))
15985+ au_rw_class(&au_ii(inode)->ii_rwsem,
15986+ au_lc_key + AuLcDir_IIINFO);
15987+ else /* likely */
15988+ au_rw_class(&au_ii(inode)->ii_rwsem,
15989+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 15990+
4a4d8108
AM
15991+ ii_write_lock_new_child(inode);
15992+ err = set_inode(inode, dentry);
15993+ if (!err) {
15994+ unlock_new_inode(inode);
15995+ goto out; /* success */
15996+ }
1308ab2a 15997+
027c5e7a
AM
15998+ /*
15999+ * iget_failed() calls iput(), but we need to call
16000+ * ii_write_unlock() after iget_failed(). so dirty hack for
16001+ * i_count.
16002+ */
16003+ atomic_inc(&inode->i_count);
4a4d8108 16004+ iget_failed(inode);
027c5e7a
AM
16005+ ii_write_unlock(inode);
16006+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
16007+ /* ignore this error */
16008+ goto out_iput;
16009+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
16010+ /*
16011+ * horrible race condition between lookup, readdir and copyup
16012+ * (or something).
16013+ */
16014+ if (mtx)
16015+ mutex_unlock(mtx);
027c5e7a
AM
16016+ err = reval_inode(inode, dentry);
16017+ if (unlikely(err < 0)) {
16018+ mtx = NULL;
16019+ goto out_iput;
16020+ }
16021+
b752ccd1
AM
16022+ if (!err) {
16023+ mtx = NULL;
4a4d8108 16024+ goto out; /* success */
b752ccd1
AM
16025+ } else if (mtx)
16026+ mutex_lock(mtx);
4a4d8108
AM
16027+ }
16028+
16029+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
16030+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3
AM
16031+ " b%d, %s, %pd, hi%lu, i%lu.\n",
16032+ bstart, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
16033+ (unsigned long)h_ino, (unsigned long)ino);
16034+ ino = 0;
16035+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
16036+ if (!err) {
16037+ iput(inode);
b752ccd1
AM
16038+ if (mtx)
16039+ mutex_unlock(mtx);
4a4d8108
AM
16040+ goto new_ino;
16041+ }
1308ab2a 16042+
4f0767ce 16043+out_iput:
4a4d8108 16044+ iput(inode);
4a4d8108 16045+ inode = ERR_PTR(err);
4f0767ce 16046+out:
b752ccd1
AM
16047+ if (mtx)
16048+ mutex_unlock(mtx);
4a4d8108 16049+ return inode;
1facf9fc 16050+}
16051+
4a4d8108 16052+/* ---------------------------------------------------------------------- */
1facf9fc 16053+
4a4d8108
AM
16054+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16055+ struct inode *inode)
16056+{
16057+ int err;
076b876e 16058+ struct inode *hi;
1facf9fc 16059+
4a4d8108 16060+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 16061+
4a4d8108
AM
16062+ /* pseudo-link after flushed may happen out of bounds */
16063+ if (!err
16064+ && inode
16065+ && au_ibstart(inode) <= bindex
16066+ && bindex <= au_ibend(inode)) {
16067+ /*
16068+ * permission check is unnecessary since vfsub routine
16069+ * will be called later
16070+ */
076b876e 16071+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
16072+ if (hi)
16073+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 16074+ }
16075+
4a4d8108
AM
16076+ return err;
16077+}
dece6358 16078+
4a4d8108
AM
16079+int au_test_h_perm(struct inode *h_inode, int mask)
16080+{
2dfbb274 16081+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
16082+ return 0;
16083+ return inode_permission(h_inode, mask);
16084+}
1facf9fc 16085+
4a4d8108
AM
16086+int au_test_h_perm_sio(struct inode *h_inode, int mask)
16087+{
16088+ if (au_test_nfs(h_inode->i_sb)
16089+ && (mask & MAY_WRITE)
16090+ && S_ISDIR(h_inode->i_mode))
16091+ mask |= MAY_READ; /* force permission check */
16092+ return au_test_h_perm(h_inode, mask);
1facf9fc 16093+}
7f207e10
AM
16094diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
16095--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
076b876e 16096+++ linux/fs/aufs/inode.h 2014-08-14 10:15:45.128609525 +0200
38d290e6 16097@@ -0,0 +1,601 @@
4a4d8108 16098+/*
523b37e3 16099+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
16100+ *
16101+ * This program, aufs is free software; you can redistribute it and/or modify
16102+ * it under the terms of the GNU General Public License as published by
16103+ * the Free Software Foundation; either version 2 of the License, or
16104+ * (at your option) any later version.
16105+ *
16106+ * This program is distributed in the hope that it will be useful,
16107+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16108+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16109+ * GNU General Public License for more details.
16110+ *
16111+ * You should have received a copy of the GNU General Public License
523b37e3 16112+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16113+ */
1facf9fc 16114+
1308ab2a 16115+/*
4a4d8108 16116+ * inode operations
1308ab2a 16117+ */
dece6358 16118+
4a4d8108
AM
16119+#ifndef __AUFS_INODE_H__
16120+#define __AUFS_INODE_H__
dece6358 16121+
4a4d8108 16122+#ifdef __KERNEL__
1308ab2a 16123+
4a4d8108 16124+#include <linux/fsnotify.h>
4a4d8108 16125+#include "rwsem.h"
1308ab2a 16126+
4a4d8108 16127+struct vfsmount;
1facf9fc 16128+
4a4d8108
AM
16129+struct au_hnotify {
16130+#ifdef CONFIG_AUFS_HNOTIFY
16131+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 16132+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 16133+ struct fsnotify_mark hn_mark;
4a4d8108 16134+#endif
7f207e10 16135+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
16136+#endif
16137+} ____cacheline_aligned_in_smp;
1facf9fc 16138+
4a4d8108
AM
16139+struct au_hinode {
16140+ struct inode *hi_inode;
16141+ aufs_bindex_t hi_id;
16142+#ifdef CONFIG_AUFS_HNOTIFY
16143+ struct au_hnotify *hi_notify;
16144+#endif
dece6358 16145+
4a4d8108
AM
16146+ /* reference to the copied-up whiteout with get/put */
16147+ struct dentry *hi_whdentry;
16148+};
dece6358 16149+
537831f9
AM
16150+/* ig_flags */
16151+#define AuIG_HALF_REFRESHED 1
16152+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
16153+#define au_ig_fset(flags, name) \
16154+ do { (flags) |= AuIG_##name; } while (0)
16155+#define au_ig_fclr(flags, name) \
16156+ do { (flags) &= ~AuIG_##name; } while (0)
16157+
16158+struct au_iigen {
16159+ __u32 ig_generation, ig_flags;
16160+};
16161+
4a4d8108
AM
16162+struct au_vdir;
16163+struct au_iinfo {
537831f9 16164+ spinlock_t ii_genspin;
7a9e40b8 16165+ struct au_iigen ii_generation;
4a4d8108 16166+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 16167+
4a4d8108
AM
16168+ struct au_rwsem ii_rwsem;
16169+ aufs_bindex_t ii_bstart, ii_bend;
16170+ __u32 ii_higen;
16171+ struct au_hinode *ii_hinode;
16172+ struct au_vdir *ii_vdir;
16173+};
1facf9fc 16174+
4a4d8108
AM
16175+struct au_icntnr {
16176+ struct au_iinfo iinfo;
16177+ struct inode vfs_inode;
16178+} ____cacheline_aligned_in_smp;
1308ab2a 16179+
4a4d8108
AM
16180+/* au_pin flags */
16181+#define AuPin_DI_LOCKED 1
16182+#define AuPin_MNT_WRITE (1 << 1)
16183+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
16184+#define au_fset_pin(flags, name) \
16185+ do { (flags) |= AuPin_##name; } while (0)
16186+#define au_fclr_pin(flags, name) \
16187+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
16188+
16189+struct au_pin {
16190+ /* input */
16191+ struct dentry *dentry;
16192+ unsigned int udba;
16193+ unsigned char lsc_di, lsc_hi, flags;
16194+ aufs_bindex_t bindex;
16195+
16196+ /* output */
16197+ struct dentry *parent;
16198+ struct au_hinode *hdir;
16199+ struct vfsmount *h_mnt;
86dc4139
AM
16200+
16201+ /* temporary unlock/relock for copyup */
16202+ struct dentry *h_dentry, *h_parent;
16203+ struct au_branch *br;
16204+ struct task_struct *task;
4a4d8108 16205+};
1facf9fc 16206+
86dc4139
AM
16207+void au_pin_hdir_unlock(struct au_pin *p);
16208+int au_pin_hdir_relock(struct au_pin *p);
16209+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
16210+void au_pin_hdir_acquire_nest(struct au_pin *p);
16211+void au_pin_hdir_release(struct au_pin *p);
16212+
1308ab2a 16213+/* ---------------------------------------------------------------------- */
16214+
4a4d8108 16215+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 16216+{
4a4d8108 16217+ struct au_iinfo *iinfo;
1facf9fc 16218+
4a4d8108
AM
16219+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
16220+ if (iinfo->ii_hinode)
16221+ return iinfo;
16222+ return NULL; /* debugging bad_inode case */
16223+}
1facf9fc 16224+
4a4d8108 16225+/* ---------------------------------------------------------------------- */
1facf9fc 16226+
4a4d8108
AM
16227+/* inode.c */
16228+struct inode *au_igrab(struct inode *inode);
027c5e7a 16229+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
16230+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
16231+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16232+ unsigned int d_type, ino_t *ino);
16233+struct inode *au_new_inode(struct dentry *dentry, int must_new);
16234+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16235+ struct inode *inode);
16236+int au_test_h_perm(struct inode *h_inode, int mask);
16237+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 16238+
4a4d8108
AM
16239+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
16240+ ino_t h_ino, unsigned int d_type, ino_t *ino)
16241+{
16242+#ifdef CONFIG_AUFS_SHWH
16243+ return au_ino(sb, bindex, h_ino, d_type, ino);
16244+#else
16245+ return 0;
16246+#endif
16247+}
1facf9fc 16248+
4a4d8108
AM
16249+/* i_op.c */
16250+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 16251+
4a4d8108
AM
16252+/* au_wr_dir flags */
16253+#define AuWrDir_ADD_ENTRY 1
86dc4139
AM
16254+#define AuWrDir_TMP_WHENTRY (1 << 1)
16255+#define AuWrDir_ISDIR (1 << 2)
38d290e6 16256+#define AuWrDir_TMPFILE (1 << 3)
4a4d8108 16257+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
16258+#define au_fset_wrdir(flags, name) \
16259+ do { (flags) |= AuWrDir_##name; } while (0)
16260+#define au_fclr_wrdir(flags, name) \
16261+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 16262+
4a4d8108
AM
16263+struct au_wr_dir_args {
16264+ aufs_bindex_t force_btgt;
16265+ unsigned char flags;
16266+};
16267+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16268+ struct au_wr_dir_args *args);
dece6358 16269+
4a4d8108
AM
16270+struct dentry *au_pinned_h_parent(struct au_pin *pin);
16271+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
16272+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16273+ unsigned int udba, unsigned char flags);
16274+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16275+ unsigned int udba, unsigned char flags) __must_check;
16276+int au_do_pin(struct au_pin *pin) __must_check;
16277+void au_unpin(struct au_pin *pin);
1facf9fc 16278+
4a4d8108
AM
16279+/* i_op_add.c */
16280+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
16281+ struct dentry *h_parent, int isdir);
7eafdf33
AM
16282+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
16283+ dev_t dev);
4a4d8108 16284+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 16285+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 16286+ bool want_excl);
38d290e6 16287+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
16288+int aufs_link(struct dentry *src_dentry, struct inode *dir,
16289+ struct dentry *dentry);
7eafdf33 16290+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 16291+
4a4d8108
AM
16292+/* i_op_del.c */
16293+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
16294+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
16295+ struct dentry *h_parent, int isdir);
16296+int aufs_unlink(struct inode *dir, struct dentry *dentry);
16297+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 16298+
4a4d8108
AM
16299+/* i_op_ren.c */
16300+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
16301+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
16302+ struct inode *dir, struct dentry *dentry);
1facf9fc 16303+
4a4d8108
AM
16304+/* iinfo.c */
16305+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
16306+void au_hiput(struct au_hinode *hinode);
16307+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
16308+ struct dentry *h_wh);
16309+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 16310+
4a4d8108
AM
16311+/* hinode flags */
16312+#define AuHi_XINO 1
16313+#define AuHi_HNOTIFY (1 << 1)
16314+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
16315+#define au_fset_hi(flags, name) \
16316+ do { (flags) |= AuHi_##name; } while (0)
16317+#define au_fclr_hi(flags, name) \
16318+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 16319+
4a4d8108
AM
16320+#ifndef CONFIG_AUFS_HNOTIFY
16321+#undef AuHi_HNOTIFY
16322+#define AuHi_HNOTIFY 0
16323+#endif
1facf9fc 16324+
4a4d8108
AM
16325+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
16326+ struct inode *h_inode, unsigned int flags);
1facf9fc 16327+
537831f9 16328+void au_update_iigen(struct inode *inode, int half);
4a4d8108 16329+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 16330+
4a4d8108
AM
16331+void au_icntnr_init_once(void *_c);
16332+int au_iinfo_init(struct inode *inode);
16333+void au_iinfo_fin(struct inode *inode);
16334+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 16335+
e49829fe 16336+#ifdef CONFIG_PROC_FS
4a4d8108 16337+/* plink.c */
e49829fe
JR
16338+int au_plink_maint(struct super_block *sb, int flags);
16339+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
16340+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
16341+#ifdef CONFIG_AUFS_DEBUG
16342+void au_plink_list(struct super_block *sb);
16343+#else
16344+AuStubVoid(au_plink_list, struct super_block *sb)
16345+#endif
16346+int au_plink_test(struct inode *inode);
16347+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
16348+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
16349+ struct dentry *h_dentry);
e49829fe
JR
16350+void au_plink_put(struct super_block *sb, int verbose);
16351+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 16352+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
16353+#else
16354+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
16355+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
16356+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
16357+AuStubVoid(au_plink_list, struct super_block *sb);
16358+AuStubInt0(au_plink_test, struct inode *inode);
16359+AuStub(struct dentry *, au_plink_lkup, return NULL,
16360+ struct inode *inode, aufs_bindex_t bindex);
16361+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
16362+ struct dentry *h_dentry);
16363+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
16364+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
16365+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
16366+#endif /* CONFIG_PROC_FS */
1facf9fc 16367+
4a4d8108 16368+/* ---------------------------------------------------------------------- */
1308ab2a 16369+
4a4d8108
AM
16370+/* lock subclass for iinfo */
16371+enum {
16372+ AuLsc_II_CHILD, /* child first */
16373+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
16374+ AuLsc_II_CHILD3, /* copyup dirs */
16375+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
16376+ AuLsc_II_PARENT2,
16377+ AuLsc_II_PARENT3, /* copyup dirs */
16378+ AuLsc_II_NEW_CHILD
16379+};
1308ab2a 16380+
1facf9fc 16381+/*
4a4d8108
AM
16382+ * ii_read_lock_child, ii_write_lock_child,
16383+ * ii_read_lock_child2, ii_write_lock_child2,
16384+ * ii_read_lock_child3, ii_write_lock_child3,
16385+ * ii_read_lock_parent, ii_write_lock_parent,
16386+ * ii_read_lock_parent2, ii_write_lock_parent2,
16387+ * ii_read_lock_parent3, ii_write_lock_parent3,
16388+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 16389+ */
4a4d8108
AM
16390+#define AuReadLockFunc(name, lsc) \
16391+static inline void ii_read_lock_##name(struct inode *i) \
16392+{ \
16393+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16394+}
16395+
16396+#define AuWriteLockFunc(name, lsc) \
16397+static inline void ii_write_lock_##name(struct inode *i) \
16398+{ \
16399+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16400+}
16401+
16402+#define AuRWLockFuncs(name, lsc) \
16403+ AuReadLockFunc(name, lsc) \
16404+ AuWriteLockFunc(name, lsc)
16405+
16406+AuRWLockFuncs(child, CHILD);
16407+AuRWLockFuncs(child2, CHILD2);
16408+AuRWLockFuncs(child3, CHILD3);
16409+AuRWLockFuncs(parent, PARENT);
16410+AuRWLockFuncs(parent2, PARENT2);
16411+AuRWLockFuncs(parent3, PARENT3);
16412+AuRWLockFuncs(new_child, NEW_CHILD);
16413+
16414+#undef AuReadLockFunc
16415+#undef AuWriteLockFunc
16416+#undef AuRWLockFuncs
1facf9fc 16417+
16418+/*
4a4d8108 16419+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 16420+ */
4a4d8108 16421+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 16422+
4a4d8108
AM
16423+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
16424+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
16425+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 16426+
4a4d8108 16427+/* ---------------------------------------------------------------------- */
1308ab2a 16428+
027c5e7a
AM
16429+static inline void au_icntnr_init(struct au_icntnr *c)
16430+{
16431+#ifdef CONFIG_AUFS_DEBUG
16432+ c->vfs_inode.i_mode = 0;
16433+#endif
16434+}
16435+
537831f9 16436+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 16437+{
537831f9
AM
16438+ unsigned int gen;
16439+ struct au_iinfo *iinfo;
16440+
16441+ iinfo = au_ii(inode);
16442+ spin_lock(&iinfo->ii_genspin);
16443+ if (iigen)
16444+ *iigen = iinfo->ii_generation;
16445+ gen = iinfo->ii_generation.ig_generation;
16446+ spin_unlock(&iinfo->ii_genspin);
16447+
16448+ return gen;
4a4d8108 16449+}
1308ab2a 16450+
4a4d8108
AM
16451+/* tiny test for inode number */
16452+/* tmpfs generation is too rough */
16453+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
16454+{
16455+ struct au_iinfo *iinfo;
1308ab2a 16456+
4a4d8108
AM
16457+ iinfo = au_ii(inode);
16458+ AuRwMustAnyLock(&iinfo->ii_rwsem);
16459+ return !(iinfo->ii_hsb1 == h_inode->i_sb
16460+ && iinfo->ii_higen == h_inode->i_generation);
16461+}
1308ab2a 16462+
4a4d8108
AM
16463+static inline void au_iigen_dec(struct inode *inode)
16464+{
537831f9
AM
16465+ struct au_iinfo *iinfo;
16466+
16467+ iinfo = au_ii(inode);
16468+ spin_lock(&iinfo->ii_genspin);
16469+ iinfo->ii_generation.ig_generation--;
16470+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
16471+}
16472+
16473+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
16474+{
16475+ int err;
16476+
16477+ err = 0;
537831f9 16478+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
16479+ err = -EIO;
16480+
16481+ return err;
4a4d8108 16482+}
1308ab2a 16483+
4a4d8108 16484+/* ---------------------------------------------------------------------- */
1308ab2a 16485+
4a4d8108
AM
16486+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
16487+ aufs_bindex_t bindex)
16488+{
16489+ IiMustAnyLock(inode);
16490+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
16491+}
1308ab2a 16492+
4a4d8108
AM
16493+static inline aufs_bindex_t au_ibstart(struct inode *inode)
16494+{
16495+ IiMustAnyLock(inode);
16496+ return au_ii(inode)->ii_bstart;
16497+}
1308ab2a 16498+
4a4d8108
AM
16499+static inline aufs_bindex_t au_ibend(struct inode *inode)
16500+{
16501+ IiMustAnyLock(inode);
16502+ return au_ii(inode)->ii_bend;
16503+}
1308ab2a 16504+
4a4d8108
AM
16505+static inline struct au_vdir *au_ivdir(struct inode *inode)
16506+{
16507+ IiMustAnyLock(inode);
16508+ return au_ii(inode)->ii_vdir;
16509+}
1308ab2a 16510+
4a4d8108
AM
16511+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
16512+{
16513+ IiMustAnyLock(inode);
16514+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
16515+}
1308ab2a 16516+
4a4d8108 16517+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16518+{
4a4d8108
AM
16519+ IiMustWriteLock(inode);
16520+ au_ii(inode)->ii_bstart = bindex;
16521+}
1308ab2a 16522+
4a4d8108
AM
16523+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
16524+{
16525+ IiMustWriteLock(inode);
16526+ au_ii(inode)->ii_bend = bindex;
1308ab2a 16527+}
16528+
4a4d8108
AM
16529+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
16530+{
16531+ IiMustWriteLock(inode);
16532+ au_ii(inode)->ii_vdir = vdir;
16533+}
1facf9fc 16534+
4a4d8108 16535+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16536+{
4a4d8108
AM
16537+ IiMustAnyLock(inode);
16538+ return au_ii(inode)->ii_hinode + bindex;
16539+}
dece6358 16540+
4a4d8108 16541+/* ---------------------------------------------------------------------- */
1facf9fc 16542+
4a4d8108
AM
16543+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
16544+{
16545+ if (pin)
16546+ return pin->parent;
16547+ return NULL;
1facf9fc 16548+}
16549+
4a4d8108 16550+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 16551+{
4a4d8108
AM
16552+ if (pin && pin->hdir)
16553+ return pin->hdir->hi_inode;
16554+ return NULL;
1308ab2a 16555+}
1facf9fc 16556+
4a4d8108
AM
16557+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
16558+{
16559+ if (pin)
16560+ return pin->hdir;
16561+ return NULL;
16562+}
1facf9fc 16563+
4a4d8108 16564+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 16565+{
4a4d8108
AM
16566+ if (pin)
16567+ pin->dentry = dentry;
16568+}
1308ab2a 16569+
4a4d8108
AM
16570+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
16571+ unsigned char lflag)
16572+{
16573+ if (pin) {
7f207e10 16574+ if (lflag)
4a4d8108 16575+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 16576+ else
4a4d8108 16577+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 16578+ }
4a4d8108
AM
16579+}
16580+
16581+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
16582+{
16583+ if (pin) {
16584+ dput(pin->parent);
16585+ pin->parent = dget(parent);
1facf9fc 16586+ }
4a4d8108 16587+}
1facf9fc 16588+
4a4d8108
AM
16589+/* ---------------------------------------------------------------------- */
16590+
027c5e7a 16591+struct au_branch;
4a4d8108
AM
16592+#ifdef CONFIG_AUFS_HNOTIFY
16593+struct au_hnotify_op {
16594+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 16595+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
16596+
16597+ /*
16598+ * if it returns true, the the caller should free hinode->hi_notify,
16599+ * otherwise ->free() frees it.
16600+ */
16601+ int (*free)(struct au_hinode *hinode,
16602+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
16603+
16604+ void (*fin)(void);
16605+ int (*init)(void);
027c5e7a
AM
16606+
16607+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
16608+ void (*fin_br)(struct au_branch *br);
16609+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
16610+};
16611+
16612+/* hnotify.c */
027c5e7a 16613+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
16614+void au_hn_free(struct au_hinode *hinode);
16615+void au_hn_ctl(struct au_hinode *hinode, int do_set);
16616+void au_hn_reset(struct inode *inode, unsigned int flags);
16617+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
16618+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
16619+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
16620+int au_hnotify_init_br(struct au_branch *br, int perm);
16621+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
16622+int __init au_hnotify_init(void);
16623+void au_hnotify_fin(void);
16624+
7f207e10 16625+/* hfsnotify.c */
4a4d8108
AM
16626+extern const struct au_hnotify_op au_hnotify_op;
16627+
16628+static inline
16629+void au_hn_init(struct au_hinode *hinode)
16630+{
16631+ hinode->hi_notify = NULL;
1308ab2a 16632+}
16633+
53392da6
AM
16634+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
16635+{
16636+ return hinode->hi_notify;
16637+}
16638+
4a4d8108
AM
16639+#else
16640+static inline
16641+int au_hn_alloc(struct au_hinode *hinode __maybe_unused,
027c5e7a 16642+ struct inode *inode __maybe_unused)
1308ab2a 16643+{
4a4d8108
AM
16644+ return -EOPNOTSUPP;
16645+}
1308ab2a 16646+
53392da6
AM
16647+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
16648+{
16649+ return NULL;
16650+}
16651+
4a4d8108
AM
16652+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
16653+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
16654+ int do_set __maybe_unused)
16655+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
16656+ unsigned int flags __maybe_unused)
027c5e7a
AM
16657+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
16658+ struct au_branch *br __maybe_unused,
16659+ int perm __maybe_unused)
16660+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
16661+ int perm __maybe_unused)
16662+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
16663+AuStubInt0(__init au_hnotify_init, void)
16664+AuStubVoid(au_hnotify_fin, void)
16665+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
16666+#endif /* CONFIG_AUFS_HNOTIFY */
16667+
16668+static inline void au_hn_suspend(struct au_hinode *hdir)
16669+{
16670+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 16671+}
16672+
4a4d8108 16673+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 16674+{
4a4d8108
AM
16675+ au_hn_ctl(hdir, /*do_set*/1);
16676+}
1308ab2a 16677+
4a4d8108
AM
16678+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
16679+{
16680+ mutex_lock(&hdir->hi_inode->i_mutex);
16681+ au_hn_suspend(hdir);
16682+}
dece6358 16683+
4a4d8108
AM
16684+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
16685+ unsigned int sc __maybe_unused)
16686+{
16687+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
16688+ au_hn_suspend(hdir);
1facf9fc 16689+}
1facf9fc 16690+
4a4d8108
AM
16691+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
16692+{
16693+ au_hn_resume(hdir);
16694+ mutex_unlock(&hdir->hi_inode->i_mutex);
16695+}
16696+
16697+#endif /* __KERNEL__ */
16698+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
16699diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
16700--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
16701+++ linux/fs/aufs/ioctl.c 2014-08-14 10:15:45.128609525 +0200
16702@@ -0,0 +1,214 @@
4a4d8108 16703+/*
523b37e3 16704+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
16705+ *
16706+ * This program, aufs is free software; you can redistribute it and/or modify
16707+ * it under the terms of the GNU General Public License as published by
16708+ * the Free Software Foundation; either version 2 of the License, or
16709+ * (at your option) any later version.
16710+ *
16711+ * This program is distributed in the hope that it will be useful,
16712+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16713+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16714+ * GNU General Public License for more details.
16715+ *
16716+ * You should have received a copy of the GNU General Public License
523b37e3 16717+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16718+ */
16719+
16720+/*
16721+ * ioctl
16722+ * plink-management and readdir in userspace.
16723+ * assist the pathconf(3) wrapper library.
c2b27bf2 16724+ * move-down
076b876e 16725+ * File-based Hierarchical Storage Management.
4a4d8108
AM
16726+ */
16727+
c2b27bf2
AM
16728+#include <linux/compat.h>
16729+#include <linux/file.h>
4a4d8108
AM
16730+#include "aufs.h"
16731+
1e00d052 16732+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
16733+{
16734+ int err, fd;
16735+ aufs_bindex_t wbi, bindex, bend;
16736+ struct file *h_file;
16737+ struct super_block *sb;
16738+ struct dentry *root;
1e00d052
AM
16739+ struct au_branch *br;
16740+ struct aufs_wbr_fd wbrfd = {
16741+ .oflags = au_dir_roflags,
16742+ .brid = -1
16743+ };
16744+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
16745+ | O_NOATIME | O_CLOEXEC;
4a4d8108 16746+
1e00d052
AM
16747+ AuDebugOn(wbrfd.oflags & ~valid);
16748+
16749+ if (arg) {
16750+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
16751+ if (unlikely(err)) {
16752+ err = -EFAULT;
16753+ goto out;
16754+ }
16755+
16756+ err = -EINVAL;
16757+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
16758+ wbrfd.oflags |= au_dir_roflags;
16759+ AuDbg("0%o\n", wbrfd.oflags);
16760+ if (unlikely(wbrfd.oflags & ~valid))
16761+ goto out;
16762+ }
16763+
16764+ fd = get_unused_fd();
16765+ err = fd;
16766+ if (unlikely(fd < 0))
4a4d8108 16767+ goto out;
4a4d8108 16768+
1e00d052 16769+ h_file = ERR_PTR(-EINVAL);
4a4d8108 16770+ wbi = 0;
1e00d052 16771+ br = NULL;
4a4d8108
AM
16772+ sb = path->dentry->d_sb;
16773+ root = sb->s_root;
16774+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
16775+ bend = au_sbend(sb);
16776+ if (wbrfd.brid >= 0) {
16777+ wbi = au_br_index(sb, wbrfd.brid);
16778+ if (unlikely(wbi < 0 || wbi > bend))
16779+ goto out_unlock;
16780+ }
16781+
16782+ h_file = ERR_PTR(-ENOENT);
16783+ br = au_sbr(sb, wbi);
16784+ if (!au_br_writable(br->br_perm)) {
16785+ if (arg)
16786+ goto out_unlock;
16787+
16788+ bindex = wbi + 1;
16789+ wbi = -1;
16790+ for (; bindex <= bend; bindex++) {
16791+ br = au_sbr(sb, bindex);
16792+ if (au_br_writable(br->br_perm)) {
4a4d8108 16793+ wbi = bindex;
1e00d052 16794+ br = au_sbr(sb, wbi);
4a4d8108
AM
16795+ break;
16796+ }
16797+ }
4a4d8108
AM
16798+ }
16799+ AuDbg("wbi %d\n", wbi);
1e00d052 16800+ if (wbi >= 0)
392086de
AM
16801+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
16802+ /*force_wr*/0);
1e00d052
AM
16803+
16804+out_unlock:
4a4d8108
AM
16805+ aufs_read_unlock(root, AuLock_IR);
16806+ err = PTR_ERR(h_file);
16807+ if (IS_ERR(h_file))
16808+ goto out_fd;
16809+
1e00d052 16810+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
16811+ fd_install(fd, h_file);
16812+ err = fd;
16813+ goto out; /* success */
16814+
4f0767ce 16815+out_fd:
4a4d8108 16816+ put_unused_fd(fd);
4f0767ce 16817+out:
1e00d052 16818+ AuTraceErr(err);
4a4d8108
AM
16819+ return err;
16820+}
16821+
16822+/* ---------------------------------------------------------------------- */
16823+
16824+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
16825+{
16826+ long err;
16827+
16828+ switch (cmd) {
4a4d8108
AM
16829+ case AUFS_CTL_RDU:
16830+ case AUFS_CTL_RDU_INO:
16831+ err = au_rdu_ioctl(file, cmd, arg);
16832+ break;
16833+
16834+ case AUFS_CTL_WBR_FD:
1e00d052 16835+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
16836+ break;
16837+
027c5e7a
AM
16838+ case AUFS_CTL_IBUSY:
16839+ err = au_ibusy_ioctl(file, arg);
16840+ break;
16841+
076b876e
AM
16842+ case AUFS_CTL_BRINFO:
16843+ err = au_brinfo_ioctl(file, arg);
16844+ break;
16845+
16846+ case AUFS_CTL_FHSM_FD:
16847+ err = au_fhsm_fd(file->f_dentry->d_sb, arg);
16848+ break;
16849+
4a4d8108
AM
16850+ default:
16851+ /* do not call the lower */
16852+ AuDbg("0x%x\n", cmd);
16853+ err = -ENOTTY;
16854+ }
16855+
16856+ AuTraceErr(err);
16857+ return err;
16858+}
16859+
16860+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
16861+{
16862+ long err;
16863+
16864+ switch (cmd) {
c2b27bf2 16865+ case AUFS_CTL_MVDOWN:
c2b27bf2
AM
16866+ err = au_mvdown(file->f_dentry, (void __user *)arg);
16867+ break;
16868+
4a4d8108 16869+ case AUFS_CTL_WBR_FD:
1e00d052 16870+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
16871+ break;
16872+
16873+ default:
16874+ /* do not call the lower */
16875+ AuDbg("0x%x\n", cmd);
16876+ err = -ENOTTY;
16877+ }
16878+
16879+ AuTraceErr(err);
16880+ return err;
16881+}
b752ccd1
AM
16882+
16883+#ifdef CONFIG_COMPAT
16884+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
16885+ unsigned long arg)
16886+{
16887+ long err;
16888+
16889+ switch (cmd) {
16890+ case AUFS_CTL_RDU:
16891+ case AUFS_CTL_RDU_INO:
16892+ err = au_rdu_compat_ioctl(file, cmd, arg);
16893+ break;
16894+
027c5e7a
AM
16895+ case AUFS_CTL_IBUSY:
16896+ err = au_ibusy_compat_ioctl(file, arg);
16897+ break;
16898+
076b876e
AM
16899+ case AUFS_CTL_BRINFO:
16900+ err = au_brinfo_compat_ioctl(file, arg);
16901+ break;
16902+
b752ccd1
AM
16903+ default:
16904+ err = aufs_ioctl_dir(file, cmd, arg);
16905+ }
16906+
16907+ AuTraceErr(err);
16908+ return err;
16909+}
16910+
b752ccd1
AM
16911+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
16912+ unsigned long arg)
16913+{
16914+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
16915+}
16916+#endif
7f207e10
AM
16917diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
16918--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
16919+++ linux/fs/aufs/i_op_add.c 2014-08-14 10:15:45.121942630 +0200
16920@@ -0,0 +1,885 @@
4a4d8108 16921+/*
523b37e3 16922+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
16923+ *
16924+ * This program, aufs is free software; you can redistribute it and/or modify
16925+ * it under the terms of the GNU General Public License as published by
16926+ * the Free Software Foundation; either version 2 of the License, or
16927+ * (at your option) any later version.
16928+ *
16929+ * This program is distributed in the hope that it will be useful,
16930+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16931+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16932+ * GNU General Public License for more details.
16933+ *
16934+ * You should have received a copy of the GNU General Public License
523b37e3 16935+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16936+ */
16937+
16938+/*
16939+ * inode operations (add entry)
16940+ */
16941+
16942+#include "aufs.h"
16943+
16944+/*
16945+ * final procedure of adding a new entry, except link(2).
16946+ * remove whiteout, instantiate, copyup the parent dir's times and size
16947+ * and update version.
16948+ * if it failed, re-create the removed whiteout.
16949+ */
16950+static int epilog(struct inode *dir, aufs_bindex_t bindex,
16951+ struct dentry *wh_dentry, struct dentry *dentry)
16952+{
16953+ int err, rerr;
16954+ aufs_bindex_t bwh;
16955+ struct path h_path;
076b876e 16956+ struct super_block *sb;
4a4d8108
AM
16957+ struct inode *inode, *h_dir;
16958+ struct dentry *wh;
16959+
16960+ bwh = -1;
076b876e 16961+ sb = dir->i_sb;
4a4d8108
AM
16962+ if (wh_dentry) {
16963+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
16964+ IMustLock(h_dir);
16965+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
16966+ bwh = au_dbwh(dentry);
16967+ h_path.dentry = wh_dentry;
076b876e 16968+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
16969+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
16970+ dentry);
16971+ if (unlikely(err))
16972+ goto out;
16973+ }
16974+
16975+ inode = au_new_inode(dentry, /*must_new*/1);
16976+ if (!IS_ERR(inode)) {
16977+ d_instantiate(dentry, inode);
16978+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
16979+ IMustLock(dir);
16980+ if (au_ibstart(dir) == au_dbstart(dentry))
16981+ au_cpup_attr_timesizes(dir);
16982+ dir->i_version++;
076b876e 16983+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
16984+ return 0; /* success */
16985+ }
16986+
16987+ err = PTR_ERR(inode);
16988+ if (!wh_dentry)
16989+ goto out;
16990+
16991+ /* revert */
16992+ /* dir inode is locked */
16993+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
16994+ rerr = PTR_ERR(wh);
16995+ if (IS_ERR(wh)) {
523b37e3
AM
16996+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
16997+ dentry, err, rerr);
4a4d8108
AM
16998+ err = -EIO;
16999+ } else
17000+ dput(wh);
17001+
4f0767ce 17002+out:
4a4d8108
AM
17003+ return err;
17004+}
17005+
027c5e7a
AM
17006+static int au_d_may_add(struct dentry *dentry)
17007+{
17008+ int err;
17009+
17010+ err = 0;
17011+ if (unlikely(d_unhashed(dentry)))
17012+ err = -ENOENT;
17013+ if (unlikely(dentry->d_inode))
17014+ err = -EEXIST;
17015+ return err;
17016+}
17017+
4a4d8108
AM
17018+/*
17019+ * simple tests for the adding inode operations.
17020+ * following the checks in vfs, plus the parent-child relationship.
17021+ */
17022+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
17023+ struct dentry *h_parent, int isdir)
17024+{
17025+ int err;
17026+ umode_t h_mode;
17027+ struct dentry *h_dentry;
17028+ struct inode *h_inode;
17029+
17030+ err = -ENAMETOOLONG;
17031+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17032+ goto out;
17033+
17034+ h_dentry = au_h_dptr(dentry, bindex);
17035+ h_inode = h_dentry->d_inode;
17036+ if (!dentry->d_inode) {
17037+ err = -EEXIST;
17038+ if (unlikely(h_inode))
17039+ goto out;
17040+ } else {
17041+ /* rename(2) case */
17042+ err = -EIO;
17043+ if (unlikely(!h_inode || !h_inode->i_nlink))
17044+ goto out;
17045+
17046+ h_mode = h_inode->i_mode;
17047+ if (!isdir) {
17048+ err = -EISDIR;
17049+ if (unlikely(S_ISDIR(h_mode)))
17050+ goto out;
17051+ } else if (unlikely(!S_ISDIR(h_mode))) {
17052+ err = -ENOTDIR;
17053+ goto out;
17054+ }
17055+ }
17056+
17057+ err = 0;
17058+ /* expected parent dir is locked */
17059+ if (unlikely(h_parent != h_dentry->d_parent))
17060+ err = -EIO;
17061+
4f0767ce 17062+out:
4a4d8108
AM
17063+ AuTraceErr(err);
17064+ return err;
17065+}
17066+
17067+/*
17068+ * initial procedure of adding a new entry.
17069+ * prepare writable branch and the parent dir, lock it,
17070+ * and lookup whiteout for the new entry.
17071+ */
17072+static struct dentry*
17073+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
17074+ struct dentry *src_dentry, struct au_pin *pin,
17075+ struct au_wr_dir_args *wr_dir_args)
17076+{
17077+ struct dentry *wh_dentry, *h_parent;
17078+ struct super_block *sb;
17079+ struct au_branch *br;
17080+ int err;
17081+ unsigned int udba;
17082+ aufs_bindex_t bcpup;
17083+
523b37e3 17084+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17085+
17086+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
17087+ bcpup = err;
17088+ wh_dentry = ERR_PTR(err);
17089+ if (unlikely(err < 0))
17090+ goto out;
17091+
17092+ sb = dentry->d_sb;
17093+ udba = au_opt_udba(sb);
17094+ err = au_pin(pin, dentry, bcpup, udba,
17095+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17096+ wh_dentry = ERR_PTR(err);
17097+ if (unlikely(err))
17098+ goto out;
17099+
17100+ h_parent = au_pinned_h_parent(pin);
17101+ if (udba != AuOpt_UDBA_NONE
17102+ && au_dbstart(dentry) == bcpup)
17103+ err = au_may_add(dentry, bcpup, h_parent,
17104+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
17105+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17106+ err = -ENAMETOOLONG;
17107+ wh_dentry = ERR_PTR(err);
17108+ if (unlikely(err))
17109+ goto out_unpin;
17110+
17111+ br = au_sbr(sb, bcpup);
17112+ if (dt) {
17113+ struct path tmp = {
17114+ .dentry = h_parent,
86dc4139 17115+ .mnt = au_br_mnt(br)
4a4d8108
AM
17116+ };
17117+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
17118+ }
17119+
17120+ wh_dentry = NULL;
17121+ if (bcpup != au_dbwh(dentry))
17122+ goto out; /* success */
17123+
17124+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
17125+
4f0767ce 17126+out_unpin:
4a4d8108
AM
17127+ if (IS_ERR(wh_dentry))
17128+ au_unpin(pin);
4f0767ce 17129+out:
4a4d8108
AM
17130+ return wh_dentry;
17131+}
17132+
17133+/* ---------------------------------------------------------------------- */
17134+
17135+enum { Mknod, Symlink, Creat };
17136+struct simple_arg {
17137+ int type;
17138+ union {
17139+ struct {
7eafdf33 17140+ umode_t mode;
b4510431 17141+ bool want_excl;
4a4d8108
AM
17142+ } c;
17143+ struct {
17144+ const char *symname;
17145+ } s;
17146+ struct {
7eafdf33 17147+ umode_t mode;
4a4d8108
AM
17148+ dev_t dev;
17149+ } m;
17150+ } u;
17151+};
17152+
17153+static int add_simple(struct inode *dir, struct dentry *dentry,
17154+ struct simple_arg *arg)
17155+{
076b876e 17156+ int err, rerr;
4a4d8108
AM
17157+ aufs_bindex_t bstart;
17158+ unsigned char created;
4a4d8108
AM
17159+ struct dentry *wh_dentry, *parent;
17160+ struct inode *h_dir;
c2b27bf2
AM
17161+ /* to reuduce stack size */
17162+ struct {
17163+ struct au_dtime dt;
17164+ struct au_pin pin;
17165+ struct path h_path;
17166+ struct au_wr_dir_args wr_dir_args;
17167+ } *a;
4a4d8108 17168+
523b37e3 17169+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17170+ IMustLock(dir);
17171+
c2b27bf2
AM
17172+ err = -ENOMEM;
17173+ a = kmalloc(sizeof(*a), GFP_NOFS);
17174+ if (unlikely(!a))
17175+ goto out;
17176+ a->wr_dir_args.force_btgt = -1;
17177+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
17178+
4a4d8108 17179+ parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17180+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17181+ if (unlikely(err))
c2b27bf2 17182+ goto out_free;
027c5e7a
AM
17183+ err = au_d_may_add(dentry);
17184+ if (unlikely(err))
17185+ goto out_unlock;
4a4d8108 17186+ di_write_lock_parent(parent);
c2b27bf2
AM
17187+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17188+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
17189+ err = PTR_ERR(wh_dentry);
17190+ if (IS_ERR(wh_dentry))
027c5e7a 17191+ goto out_parent;
4a4d8108
AM
17192+
17193+ bstart = au_dbstart(dentry);
c2b27bf2
AM
17194+ a->h_path.dentry = au_h_dptr(dentry, bstart);
17195+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
17196+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
17197+ switch (arg->type) {
17198+ case Creat:
c2b27bf2 17199+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
537831f9 17200+ arg->u.c.want_excl);
4a4d8108
AM
17201+ break;
17202+ case Symlink:
c2b27bf2 17203+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
17204+ break;
17205+ case Mknod:
c2b27bf2
AM
17206+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
17207+ arg->u.m.dev);
4a4d8108
AM
17208+ break;
17209+ default:
17210+ BUG();
17211+ }
17212+ created = !err;
17213+ if (!err)
17214+ err = epilog(dir, bstart, wh_dentry, dentry);
17215+
17216+ /* revert */
c2b27bf2 17217+ if (unlikely(created && err && a->h_path.dentry->d_inode)) {
523b37e3
AM
17218+ /* no delegation since it is just created */
17219+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
17220+ /*force*/0);
4a4d8108 17221+ if (rerr) {
523b37e3
AM
17222+ AuIOErr("%pd revert failure(%d, %d)\n",
17223+ dentry, err, rerr);
4a4d8108
AM
17224+ err = -EIO;
17225+ }
c2b27bf2 17226+ au_dtime_revert(&a->dt);
4a4d8108
AM
17227+ }
17228+
c2b27bf2 17229+ au_unpin(&a->pin);
4a4d8108
AM
17230+ dput(wh_dentry);
17231+
027c5e7a
AM
17232+out_parent:
17233+ di_write_unlock(parent);
17234+out_unlock:
4a4d8108
AM
17235+ if (unlikely(err)) {
17236+ au_update_dbstart(dentry);
17237+ d_drop(dentry);
17238+ }
4a4d8108 17239+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
17240+out_free:
17241+ kfree(a);
027c5e7a 17242+out:
4a4d8108
AM
17243+ return err;
17244+}
17245+
7eafdf33
AM
17246+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
17247+ dev_t dev)
4a4d8108
AM
17248+{
17249+ struct simple_arg arg = {
17250+ .type = Mknod,
17251+ .u.m = {
17252+ .mode = mode,
17253+ .dev = dev
17254+ }
17255+ };
17256+ return add_simple(dir, dentry, &arg);
17257+}
17258+
17259+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
17260+{
17261+ struct simple_arg arg = {
17262+ .type = Symlink,
17263+ .u.s.symname = symname
17264+ };
17265+ return add_simple(dir, dentry, &arg);
17266+}
17267+
7eafdf33 17268+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 17269+ bool want_excl)
4a4d8108
AM
17270+{
17271+ struct simple_arg arg = {
17272+ .type = Creat,
17273+ .u.c = {
b4510431
AM
17274+ .mode = mode,
17275+ .want_excl = want_excl
4a4d8108
AM
17276+ }
17277+ };
17278+ return add_simple(dir, dentry, &arg);
17279+}
17280+
38d290e6
JR
17281+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
17282+{
17283+ int err;
17284+ aufs_bindex_t bindex;
17285+ struct super_block *sb;
17286+ struct dentry *parent, *h_parent, *h_dentry;
17287+ struct inode *h_dir, *inode;
17288+ struct vfsmount *h_mnt;
17289+ struct au_wr_dir_args wr_dir_args = {
17290+ .force_btgt = -1,
17291+ .flags = AuWrDir_TMPFILE
17292+ };
17293+
17294+ /* copy-up may happen */
17295+ mutex_lock(&dir->i_mutex);
17296+
17297+ sb = dir->i_sb;
17298+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17299+ if (unlikely(err))
17300+ goto out;
17301+
17302+ err = au_di_init(dentry);
17303+ if (unlikely(err))
17304+ goto out_si;
17305+
17306+ err = -EBUSY;
17307+ parent = d_find_any_alias(dir);
17308+ AuDebugOn(!parent);
17309+ di_write_lock_parent(parent);
17310+ if (unlikely(parent->d_inode != dir))
17311+ goto out_parent;
17312+
17313+ err = au_digen_test(parent, au_sigen(sb));
17314+ if (unlikely(err))
17315+ goto out_parent;
17316+
17317+ bindex = au_dbstart(parent);
17318+ au_set_dbstart(dentry, bindex);
17319+ au_set_dbend(dentry, bindex);
17320+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17321+ bindex = err;
17322+ if (unlikely(err < 0))
17323+ goto out_parent;
17324+
17325+ err = -EOPNOTSUPP;
17326+ h_dir = au_h_iptr(dir, bindex);
17327+ if (unlikely(!h_dir->i_op->tmpfile))
17328+ goto out_parent;
17329+
17330+ h_mnt = au_sbr_mnt(sb, bindex);
17331+ err = vfsub_mnt_want_write(h_mnt);
17332+ if (unlikely(err))
17333+ goto out_parent;
17334+
17335+ h_parent = au_h_dptr(parent, bindex);
17336+ err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC);
17337+ if (unlikely(err))
17338+ goto out_mnt;
17339+
17340+ err = -ENOMEM;
17341+ h_dentry = d_alloc(h_parent, &dentry->d_name);
17342+ if (unlikely(!h_dentry))
17343+ goto out_mnt;
17344+
17345+ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode);
17346+ if (unlikely(err))
17347+ goto out_dentry;
17348+
17349+ au_set_dbstart(dentry, bindex);
17350+ au_set_dbend(dentry, bindex);
17351+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
17352+ inode = au_new_inode(dentry, /*must_new*/1);
17353+ if (IS_ERR(inode)) {
17354+ err = PTR_ERR(inode);
17355+ au_set_h_dptr(dentry, bindex, NULL);
17356+ au_set_dbstart(dentry, -1);
17357+ au_set_dbend(dentry, -1);
17358+ } else {
17359+ if (!inode->i_nlink)
17360+ set_nlink(inode, 1);
17361+ d_tmpfile(dentry, inode);
17362+ au_di(dentry)->di_tmpfile = 1;
17363+
17364+ /* update without i_mutex */
17365+ if (au_ibstart(dir) == au_dbstart(dentry))
17366+ au_cpup_attr_timesizes(dir);
17367+ }
17368+
17369+out_dentry:
17370+ dput(h_dentry);
17371+out_mnt:
17372+ vfsub_mnt_drop_write(h_mnt);
17373+out_parent:
17374+ di_write_unlock(parent);
17375+ dput(parent);
17376+ di_write_unlock(dentry);
17377+ if (!err)
17378+#if 0
17379+ /* verbose coding for lock class name */
17380+ au_rw_class(&au_di(dentry)->di_rwsem,
17381+ au_lc_key + AuLcNonDir_DIINFO);
17382+#else
17383+ ;
17384+#endif
17385+ else {
17386+ au_di_fin(dentry);
17387+ dentry->d_fsdata = NULL;
17388+ }
17389+out_si:
17390+ si_read_unlock(sb);
17391+out:
17392+ mutex_unlock(&dir->i_mutex);
17393+ return err;
17394+}
17395+
4a4d8108
AM
17396+/* ---------------------------------------------------------------------- */
17397+
17398+struct au_link_args {
17399+ aufs_bindex_t bdst, bsrc;
17400+ struct au_pin pin;
17401+ struct path h_path;
17402+ struct dentry *src_parent, *parent;
17403+};
17404+
17405+static int au_cpup_before_link(struct dentry *src_dentry,
17406+ struct au_link_args *a)
17407+{
17408+ int err;
17409+ struct dentry *h_src_dentry;
c2b27bf2
AM
17410+ struct au_cp_generic cpg = {
17411+ .dentry = src_dentry,
17412+ .bdst = a->bdst,
17413+ .bsrc = a->bsrc,
17414+ .len = -1,
17415+ .pin = &a->pin,
17416+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
17417+ };
4a4d8108
AM
17418+
17419+ di_read_lock_parent(a->src_parent, AuLock_IR);
17420+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
17421+ if (unlikely(err))
17422+ goto out;
17423+
17424+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
17425+ err = au_pin(&a->pin, src_dentry, a->bdst,
17426+ au_opt_udba(src_dentry->d_sb),
17427+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17428+ if (unlikely(err))
17429+ goto out;
367653fa 17430+
c2b27bf2 17431+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
17432+ au_unpin(&a->pin);
17433+
4f0767ce 17434+out:
4a4d8108
AM
17435+ di_read_unlock(a->src_parent, AuLock_IR);
17436+ return err;
17437+}
17438+
86dc4139
AM
17439+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
17440+ struct au_link_args *a)
4a4d8108
AM
17441+{
17442+ int err;
17443+ unsigned char plink;
86dc4139 17444+ aufs_bindex_t bend;
4a4d8108 17445+ struct dentry *h_src_dentry;
523b37e3 17446+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
17447+ struct super_block *sb;
17448+ struct file *h_file;
17449+
17450+ plink = 0;
17451+ h_inode = NULL;
17452+ sb = src_dentry->d_sb;
17453+ inode = src_dentry->d_inode;
17454+ if (au_ibstart(inode) <= a->bdst)
17455+ h_inode = au_h_iptr(inode, a->bdst);
17456+ if (!h_inode || !h_inode->i_nlink) {
17457+ /* copyup src_dentry as the name of dentry. */
86dc4139
AM
17458+ bend = au_dbend(dentry);
17459+ if (bend < a->bsrc)
17460+ au_set_dbend(dentry, a->bsrc);
17461+ au_set_h_dptr(dentry, a->bsrc,
17462+ dget(au_h_dptr(src_dentry, a->bsrc)));
17463+ dget(a->h_path.dentry);
17464+ au_set_h_dptr(dentry, a->bdst, NULL);
17465+ dentry->d_inode = src_dentry->d_inode; /* tmp */
392086de 17466+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 17467+ if (IS_ERR(h_file))
4a4d8108 17468+ err = PTR_ERR(h_file);
86dc4139 17469+ else {
c2b27bf2
AM
17470+ struct au_cp_generic cpg = {
17471+ .dentry = dentry,
17472+ .bdst = a->bdst,
17473+ .bsrc = -1,
17474+ .len = -1,
17475+ .pin = &a->pin,
17476+ .flags = AuCpup_KEEPLINO
17477+ };
17478+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
17479+ au_h_open_post(dentry, a->bsrc, h_file);
17480+ if (!err) {
17481+ dput(a->h_path.dentry);
17482+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17483+ } else
17484+ au_set_h_dptr(dentry, a->bdst,
17485+ a->h_path.dentry);
17486+ }
17487+ dentry->d_inode = NULL; /* restore */
17488+ au_set_h_dptr(dentry, a->bsrc, NULL);
17489+ au_set_dbend(dentry, bend);
4a4d8108
AM
17490+ } else {
17491+ /* the inode of src_dentry already exists on a.bdst branch */
17492+ h_src_dentry = d_find_alias(h_inode);
17493+ if (!h_src_dentry && au_plink_test(inode)) {
17494+ plink = 1;
17495+ h_src_dentry = au_plink_lkup(inode, a->bdst);
17496+ err = PTR_ERR(h_src_dentry);
17497+ if (IS_ERR(h_src_dentry))
17498+ goto out;
17499+
17500+ if (unlikely(!h_src_dentry->d_inode)) {
17501+ dput(h_src_dentry);
17502+ h_src_dentry = NULL;
17503+ }
17504+
17505+ }
17506+ if (h_src_dentry) {
523b37e3 17507+ delegated = NULL;
4a4d8108 17508+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17509+ &a->h_path, &delegated);
17510+ if (unlikely(err == -EWOULDBLOCK)) {
17511+ pr_warn("cannot retry for NFSv4 delegation"
17512+ " for an internal link\n");
17513+ iput(delegated);
17514+ }
4a4d8108
AM
17515+ dput(h_src_dentry);
17516+ } else {
17517+ AuIOErr("no dentry found for hi%lu on b%d\n",
17518+ h_inode->i_ino, a->bdst);
17519+ err = -EIO;
17520+ }
17521+ }
17522+
17523+ if (!err && !plink)
17524+ au_plink_append(inode, a->bdst, a->h_path.dentry);
17525+
17526+out:
2cbb1c4b 17527+ AuTraceErr(err);
4a4d8108
AM
17528+ return err;
17529+}
17530+
17531+int aufs_link(struct dentry *src_dentry, struct inode *dir,
17532+ struct dentry *dentry)
17533+{
17534+ int err, rerr;
17535+ struct au_dtime dt;
17536+ struct au_link_args *a;
17537+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 17538+ struct inode *inode, *delegated;
4a4d8108
AM
17539+ struct super_block *sb;
17540+ struct au_wr_dir_args wr_dir_args = {
17541+ /* .force_btgt = -1, */
17542+ .flags = AuWrDir_ADD_ENTRY
17543+ };
17544+
17545+ IMustLock(dir);
17546+ inode = src_dentry->d_inode;
17547+ IMustLock(inode);
17548+
4a4d8108
AM
17549+ err = -ENOMEM;
17550+ a = kzalloc(sizeof(*a), GFP_NOFS);
17551+ if (unlikely(!a))
17552+ goto out;
17553+
17554+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17555+ err = aufs_read_and_write_lock2(dentry, src_dentry,
17556+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
17557+ if (unlikely(err))
17558+ goto out_kfree;
38d290e6 17559+ err = au_d_linkable(src_dentry);
027c5e7a
AM
17560+ if (unlikely(err))
17561+ goto out_unlock;
17562+ err = au_d_may_add(dentry);
17563+ if (unlikely(err))
17564+ goto out_unlock;
e49829fe 17565+
4a4d8108 17566+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 17567+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
17568+
17569+ di_write_lock_parent(a->parent);
17570+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
17571+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
17572+ &wr_dir_args);
17573+ err = PTR_ERR(wh_dentry);
17574+ if (IS_ERR(wh_dentry))
027c5e7a 17575+ goto out_parent;
4a4d8108
AM
17576+
17577+ err = 0;
17578+ sb = dentry->d_sb;
17579+ a->bdst = au_dbstart(dentry);
17580+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17581+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
17582+ a->bsrc = au_ibstart(inode);
17583+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
17584+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
17585+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b
JR
17586+ if (!h_src_dentry) {
17587+ a->bsrc = au_dbstart(src_dentry);
17588+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
17589+ AuDebugOn(!h_src_dentry);
38d290e6
JR
17590+ } else if (IS_ERR(h_src_dentry)) {
17591+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 17592+ goto out_parent;
38d290e6 17593+ }
2cbb1c4b 17594+
4a4d8108
AM
17595+ if (au_opt_test(au_mntflags(sb), PLINK)) {
17596+ if (a->bdst < a->bsrc
17597+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 17598+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
17599+ else {
17600+ delegated = NULL;
4a4d8108 17601+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17602+ &a->h_path, &delegated);
17603+ if (unlikely(err == -EWOULDBLOCK)) {
17604+ pr_warn("cannot retry for NFSv4 delegation"
17605+ " for an internal link\n");
17606+ iput(delegated);
17607+ }
17608+ }
2cbb1c4b 17609+ dput(h_src_dentry);
4a4d8108
AM
17610+ } else {
17611+ /*
17612+ * copyup src_dentry to the branch we process,
17613+ * and then link(2) to it.
17614+ */
2cbb1c4b 17615+ dput(h_src_dentry);
4a4d8108
AM
17616+ if (a->bdst < a->bsrc
17617+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
17618+ au_unpin(&a->pin);
17619+ di_write_unlock(a->parent);
17620+ err = au_cpup_before_link(src_dentry, a);
17621+ di_write_lock_parent(a->parent);
17622+ if (!err)
17623+ err = au_pin(&a->pin, dentry, a->bdst,
17624+ au_opt_udba(sb),
17625+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17626+ if (unlikely(err))
17627+ goto out_wh;
17628+ }
17629+ if (!err) {
17630+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
17631+ err = -ENOENT;
523b37e3
AM
17632+ if (h_src_dentry && h_src_dentry->d_inode) {
17633+ delegated = NULL;
4a4d8108
AM
17634+ err = vfsub_link(h_src_dentry,
17635+ au_pinned_h_dir(&a->pin),
523b37e3
AM
17636+ &a->h_path, &delegated);
17637+ if (unlikely(err == -EWOULDBLOCK)) {
17638+ pr_warn("cannot retry"
17639+ " for NFSv4 delegation"
17640+ " for an internal link\n");
17641+ iput(delegated);
17642+ }
17643+ }
4a4d8108
AM
17644+ }
17645+ }
17646+ if (unlikely(err))
17647+ goto out_unpin;
17648+
17649+ if (wh_dentry) {
17650+ a->h_path.dentry = wh_dentry;
17651+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
17652+ dentry);
17653+ if (unlikely(err))
17654+ goto out_revert;
17655+ }
17656+
17657+ dir->i_version++;
17658+ if (au_ibstart(dir) == au_dbstart(dentry))
17659+ au_cpup_attr_timesizes(dir);
17660+ inc_nlink(inode);
17661+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
17662+ d_instantiate(dentry, au_igrab(inode));
17663+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
17664+ /* some filesystem calls d_drop() */
17665+ d_drop(dentry);
076b876e
AM
17666+ /* some filesystems consume an inode even hardlink */
17667+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
17668+ goto out_unpin; /* success */
17669+
4f0767ce 17670+out_revert:
523b37e3
AM
17671+ /* no delegation since it is just created */
17672+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
17673+ /*delegated*/NULL, /*force*/0);
027c5e7a 17674+ if (unlikely(rerr)) {
523b37e3 17675+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
17676+ err = -EIO;
17677+ }
4a4d8108 17678+ au_dtime_revert(&dt);
4f0767ce 17679+out_unpin:
4a4d8108 17680+ au_unpin(&a->pin);
4f0767ce 17681+out_wh:
4a4d8108 17682+ dput(wh_dentry);
027c5e7a
AM
17683+out_parent:
17684+ di_write_unlock(a->parent);
17685+ dput(a->src_parent);
4f0767ce 17686+out_unlock:
4a4d8108
AM
17687+ if (unlikely(err)) {
17688+ au_update_dbstart(dentry);
17689+ d_drop(dentry);
17690+ }
4a4d8108 17691+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 17692+out_kfree:
4a4d8108 17693+ kfree(a);
4f0767ce 17694+out:
86dc4139 17695+ AuTraceErr(err);
4a4d8108
AM
17696+ return err;
17697+}
17698+
7eafdf33 17699+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
17700+{
17701+ int err, rerr;
17702+ aufs_bindex_t bindex;
17703+ unsigned char diropq;
17704+ struct path h_path;
17705+ struct dentry *wh_dentry, *parent, *opq_dentry;
17706+ struct mutex *h_mtx;
17707+ struct super_block *sb;
17708+ struct {
17709+ struct au_pin pin;
17710+ struct au_dtime dt;
17711+ } *a; /* reduce the stack usage */
17712+ struct au_wr_dir_args wr_dir_args = {
17713+ .force_btgt = -1,
17714+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
17715+ };
17716+
17717+ IMustLock(dir);
17718+
17719+ err = -ENOMEM;
17720+ a = kmalloc(sizeof(*a), GFP_NOFS);
17721+ if (unlikely(!a))
17722+ goto out;
17723+
027c5e7a
AM
17724+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17725+ if (unlikely(err))
17726+ goto out_free;
17727+ err = au_d_may_add(dentry);
17728+ if (unlikely(err))
17729+ goto out_unlock;
17730+
4a4d8108
AM
17731+ parent = dentry->d_parent; /* dir inode is locked */
17732+ di_write_lock_parent(parent);
17733+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17734+ &a->pin, &wr_dir_args);
17735+ err = PTR_ERR(wh_dentry);
17736+ if (IS_ERR(wh_dentry))
027c5e7a 17737+ goto out_parent;
4a4d8108
AM
17738+
17739+ sb = dentry->d_sb;
17740+ bindex = au_dbstart(dentry);
17741+ h_path.dentry = au_h_dptr(dentry, bindex);
17742+ h_path.mnt = au_sbr_mnt(sb, bindex);
17743+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
17744+ if (unlikely(err))
027c5e7a 17745+ goto out_unpin;
4a4d8108
AM
17746+
17747+ /* make the dir opaque */
17748+ diropq = 0;
17749+ h_mtx = &h_path.dentry->d_inode->i_mutex;
17750+ if (wh_dentry
17751+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
17752+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17753+ opq_dentry = au_diropq_create(dentry, bindex);
17754+ mutex_unlock(h_mtx);
17755+ err = PTR_ERR(opq_dentry);
17756+ if (IS_ERR(opq_dentry))
17757+ goto out_dir;
17758+ dput(opq_dentry);
17759+ diropq = 1;
17760+ }
17761+
17762+ err = epilog(dir, bindex, wh_dentry, dentry);
17763+ if (!err) {
17764+ inc_nlink(dir);
027c5e7a 17765+ goto out_unpin; /* success */
4a4d8108
AM
17766+ }
17767+
17768+ /* revert */
17769+ if (diropq) {
17770+ AuLabel(revert opq);
17771+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17772+ rerr = au_diropq_remove(dentry, bindex);
17773+ mutex_unlock(h_mtx);
17774+ if (rerr) {
523b37e3
AM
17775+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
17776+ dentry, err, rerr);
4a4d8108
AM
17777+ err = -EIO;
17778+ }
17779+ }
17780+
4f0767ce 17781+out_dir:
4a4d8108
AM
17782+ AuLabel(revert dir);
17783+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
17784+ if (rerr) {
523b37e3
AM
17785+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
17786+ dentry, err, rerr);
4a4d8108
AM
17787+ err = -EIO;
17788+ }
4a4d8108 17789+ au_dtime_revert(&a->dt);
027c5e7a 17790+out_unpin:
4a4d8108
AM
17791+ au_unpin(&a->pin);
17792+ dput(wh_dentry);
027c5e7a
AM
17793+out_parent:
17794+ di_write_unlock(parent);
17795+out_unlock:
4a4d8108
AM
17796+ if (unlikely(err)) {
17797+ au_update_dbstart(dentry);
17798+ d_drop(dentry);
17799+ }
4a4d8108 17800+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 17801+out_free:
4a4d8108 17802+ kfree(a);
4f0767ce 17803+out:
4a4d8108
AM
17804+ return err;
17805+}
7f207e10
AM
17806diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
17807--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
17808+++ linux/fs/aufs/i_op.c 2014-08-14 10:15:45.121942630 +0200
17809@@ -0,0 +1,1142 @@
4a4d8108 17810+/*
523b37e3 17811+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
17812+ *
17813+ * This program, aufs is free software; you can redistribute it and/or modify
17814+ * it under the terms of the GNU General Public License as published by
17815+ * the Free Software Foundation; either version 2 of the License, or
17816+ * (at your option) any later version.
17817+ *
17818+ * This program is distributed in the hope that it will be useful,
17819+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17820+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17821+ * GNU General Public License for more details.
17822+ *
17823+ * You should have received a copy of the GNU General Public License
523b37e3 17824+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 17825+ */
1facf9fc 17826+
1308ab2a 17827+/*
4a4d8108 17828+ * inode operations (except add/del/rename)
1308ab2a 17829+ */
4a4d8108
AM
17830+
17831+#include <linux/device_cgroup.h>
17832+#include <linux/fs_stack.h>
92d182d2 17833+#include <linux/mm.h>
4a4d8108
AM
17834+#include <linux/namei.h>
17835+#include <linux/security.h>
4a4d8108
AM
17836+#include "aufs.h"
17837+
1e00d052 17838+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 17839+ struct vfsmount *h_mnt, int brperm)
1facf9fc 17840+{
1308ab2a 17841+ int err;
4a4d8108 17842+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 17843+
4a4d8108
AM
17844+ err = -EACCES;
17845+ if ((write_mask && IS_IMMUTABLE(h_inode))
17846+ || ((mask & MAY_EXEC)
17847+ && S_ISREG(h_inode->i_mode)
17848+ && ((h_mnt->mnt_flags & MNT_NOEXEC)
17849+ || !(h_inode->i_mode & S_IXUGO))))
17850+ goto out;
17851+
17852+ /*
17853+ * - skip the lower fs test in the case of write to ro branch.
17854+ * - nfs dir permission write check is optimized, but a policy for
17855+ * link/rename requires a real check.
17856+ */
17857+ if ((write_mask && !au_br_writable(brperm))
17858+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
17859+ && write_mask && !(mask & MAY_READ))
17860+ || !h_inode->i_op->permission) {
17861+ /* AuLabel(generic_permission); */
1e00d052 17862+ err = generic_permission(h_inode, mask);
1308ab2a 17863+ } else {
4a4d8108 17864+ /* AuLabel(h_inode->permission); */
1e00d052 17865+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
17866+ AuTraceErr(err);
17867+ }
1facf9fc 17868+
4a4d8108
AM
17869+ if (!err)
17870+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 17871+ if (!err)
4a4d8108 17872+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
17873+
17874+#if 0
17875+ if (!err) {
17876+ /* todo: do we need to call ima_path_check()? */
17877+ struct path h_path = {
17878+ .dentry =
17879+ .mnt = h_mnt
17880+ };
17881+ err = ima_path_check(&h_path,
17882+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
17883+ IMA_COUNT_LEAVE);
1308ab2a 17884+ }
4a4d8108 17885+#endif
dece6358 17886+
4f0767ce 17887+out:
1308ab2a 17888+ return err;
17889+}
dece6358 17890+
1e00d052 17891+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 17892+{
17893+ int err;
4a4d8108
AM
17894+ aufs_bindex_t bindex, bend;
17895+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
17896+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
17897+ struct inode *h_inode;
17898+ struct super_block *sb;
17899+ struct au_branch *br;
1facf9fc 17900+
027c5e7a 17901+ /* todo: support rcu-walk? */
1e00d052 17902+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
17903+ return -ECHILD;
17904+
4a4d8108
AM
17905+ sb = inode->i_sb;
17906+ si_read_lock(sb, AuLock_FLUSH);
17907+ ii_read_lock_child(inode);
027c5e7a
AM
17908+#if 0
17909+ err = au_iigen_test(inode, au_sigen(sb));
17910+ if (unlikely(err))
17911+ goto out;
17912+#endif
dece6358 17913+
076b876e
AM
17914+ if (!isdir
17915+ || write_mask
17916+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108
AM
17917+ err = au_busy_or_stale();
17918+ h_inode = au_h_iptr(inode, au_ibstart(inode));
17919+ if (unlikely(!h_inode
17920+ || (h_inode->i_mode & S_IFMT)
17921+ != (inode->i_mode & S_IFMT)))
17922+ goto out;
1facf9fc 17923+
4a4d8108
AM
17924+ err = 0;
17925+ bindex = au_ibstart(inode);
17926+ br = au_sbr(sb, bindex);
86dc4139 17927+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
4a4d8108
AM
17928+ if (write_mask
17929+ && !err
17930+ && !special_file(h_inode->i_mode)) {
17931+ /* test whether the upper writable branch exists */
17932+ err = -EROFS;
17933+ for (; bindex >= 0; bindex--)
17934+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
17935+ err = 0;
17936+ break;
17937+ }
17938+ }
17939+ goto out;
17940+ }
dece6358 17941+
4a4d8108 17942+ /* non-write to dir */
1308ab2a 17943+ err = 0;
4a4d8108
AM
17944+ bend = au_ibend(inode);
17945+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
17946+ h_inode = au_h_iptr(inode, bindex);
17947+ if (h_inode) {
17948+ err = au_busy_or_stale();
17949+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
17950+ break;
17951+
17952+ br = au_sbr(sb, bindex);
86dc4139 17953+ err = h_permission(h_inode, mask, au_br_mnt(br),
4a4d8108
AM
17954+ br->br_perm);
17955+ }
17956+ }
1308ab2a 17957+
4f0767ce 17958+out:
4a4d8108
AM
17959+ ii_read_unlock(inode);
17960+ si_read_unlock(sb);
1308ab2a 17961+ return err;
17962+}
17963+
4a4d8108 17964+/* ---------------------------------------------------------------------- */
1facf9fc 17965+
4a4d8108 17966+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 17967+ unsigned int flags)
4a4d8108
AM
17968+{
17969+ struct dentry *ret, *parent;
b752ccd1 17970+ struct inode *inode;
4a4d8108 17971+ struct super_block *sb;
1716fcea 17972+ int err, npositive;
dece6358 17973+
4a4d8108 17974+ IMustLock(dir);
1308ab2a 17975+
537831f9
AM
17976+ /* todo: support rcu-walk? */
17977+ ret = ERR_PTR(-ECHILD);
17978+ if (flags & LOOKUP_RCU)
17979+ goto out;
17980+
17981+ ret = ERR_PTR(-ENAMETOOLONG);
17982+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17983+ goto out;
17984+
4a4d8108 17985+ sb = dir->i_sb;
7f207e10
AM
17986+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17987+ ret = ERR_PTR(err);
17988+ if (unlikely(err))
17989+ goto out;
17990+
4a4d8108
AM
17991+ err = au_di_init(dentry);
17992+ ret = ERR_PTR(err);
17993+ if (unlikely(err))
7f207e10 17994+ goto out_si;
1308ab2a 17995+
9dbd164d 17996+ inode = NULL;
027c5e7a 17997+ npositive = 0; /* suppress a warning */
4a4d8108
AM
17998+ parent = dentry->d_parent; /* dir inode is locked */
17999+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
18000+ err = au_alive_dir(parent);
18001+ if (!err)
18002+ err = au_digen_test(parent, au_sigen(sb));
18003+ if (!err) {
18004+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 18005+ /*type*/0);
027c5e7a
AM
18006+ err = npositive;
18007+ }
4a4d8108 18008+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
18009+ ret = ERR_PTR(err);
18010+ if (unlikely(err < 0))
18011+ goto out_unlock;
1308ab2a 18012+
4a4d8108 18013+ if (npositive) {
b752ccd1 18014+ inode = au_new_inode(dentry, /*must_new*/0);
4a4d8108 18015+ ret = (void *)inode;
1facf9fc 18016+ }
9dbd164d
AM
18017+ if (IS_ERR(inode)) {
18018+ inode = NULL;
4a4d8108 18019+ goto out_unlock;
9dbd164d 18020+ }
4a4d8108
AM
18021+
18022+ ret = d_splice_alias(inode, dentry);
537831f9
AM
18023+#if 0
18024+ if (unlikely(d_need_lookup(dentry))) {
18025+ spin_lock(&dentry->d_lock);
18026+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
18027+ spin_unlock(&dentry->d_lock);
18028+ } else
18029+#endif
7f207e10 18030+ if (unlikely(IS_ERR(ret) && inode)) {
4a4d8108 18031+ ii_write_unlock(inode);
7f207e10 18032+ iput(inode);
2dfbb274 18033+ inode = NULL;
7f207e10 18034+ }
1facf9fc 18035+
4f0767ce 18036+out_unlock:
4a4d8108 18037+ di_write_unlock(dentry);
2dfbb274 18038+ if (inode) {
1716fcea
AM
18039+ /* verbose coding for lock class name */
18040+ if (unlikely(S_ISLNK(inode->i_mode)))
18041+ au_rw_class(&au_di(dentry)->di_rwsem,
18042+ au_lc_key + AuLcSymlink_DIINFO);
18043+ else if (unlikely(S_ISDIR(inode->i_mode)))
18044+ au_rw_class(&au_di(dentry)->di_rwsem,
18045+ au_lc_key + AuLcDir_DIINFO);
18046+ else /* likely */
18047+ au_rw_class(&au_di(dentry)->di_rwsem,
18048+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 18049+ }
7f207e10 18050+out_si:
4a4d8108 18051+ si_read_unlock(sb);
7f207e10 18052+out:
4a4d8108
AM
18053+ return ret;
18054+}
1facf9fc 18055+
4a4d8108 18056+/* ---------------------------------------------------------------------- */
1facf9fc 18057+
4a4d8108
AM
18058+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
18059+ const unsigned char add_entry, aufs_bindex_t bcpup,
18060+ aufs_bindex_t bstart)
18061+{
18062+ int err;
18063+ struct dentry *h_parent;
18064+ struct inode *h_dir;
1facf9fc 18065+
027c5e7a 18066+ if (add_entry)
4a4d8108 18067+ IMustLock(parent->d_inode);
027c5e7a 18068+ else
4a4d8108
AM
18069+ di_write_lock_parent(parent);
18070+
18071+ err = 0;
18072+ if (!au_h_dptr(parent, bcpup)) {
c2b27bf2
AM
18073+ if (bstart > bcpup)
18074+ err = au_cpup_dirs(dentry, bcpup);
18075+ else if (bstart < bcpup)
4a4d8108
AM
18076+ err = au_cpdown_dirs(dentry, bcpup);
18077+ else
c2b27bf2 18078+ BUG();
4a4d8108 18079+ }
38d290e6 18080+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108
AM
18081+ h_parent = au_h_dptr(parent, bcpup);
18082+ h_dir = h_parent->d_inode;
18083+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
86dc4139
AM
18084+ err = au_lkup_neg(dentry, bcpup,
18085+ au_ftest_wrdir(add_entry, TMP_WHENTRY));
4a4d8108
AM
18086+ /* todo: no unlock here */
18087+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
18088+
18089+ AuDbg("bcpup %d\n", bcpup);
18090+ if (!err) {
18091+ if (!dentry->d_inode)
18092+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
18093+ au_update_dbrange(dentry, /*do_put_zero*/0);
18094+ }
1308ab2a 18095+ }
1facf9fc 18096+
4a4d8108
AM
18097+ if (!add_entry)
18098+ di_write_unlock(parent);
18099+ if (!err)
18100+ err = bcpup; /* success */
1308ab2a 18101+
027c5e7a 18102+ AuTraceErr(err);
4a4d8108
AM
18103+ return err;
18104+}
1facf9fc 18105+
4a4d8108
AM
18106+/*
18107+ * decide the branch and the parent dir where we will create a new entry.
18108+ * returns new bindex or an error.
18109+ * copyup the parent dir if needed.
18110+ */
18111+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18112+ struct au_wr_dir_args *args)
18113+{
18114+ int err;
392086de 18115+ unsigned int flags;
4a4d8108 18116+ aufs_bindex_t bcpup, bstart, src_bstart;
86dc4139
AM
18117+ const unsigned char add_entry
18118+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6
JR
18119+ | au_ftest_wrdir(args->flags, TMP_WHENTRY)
18120+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
18121+ struct super_block *sb;
18122+ struct dentry *parent;
18123+ struct au_sbinfo *sbinfo;
1facf9fc 18124+
4a4d8108
AM
18125+ sb = dentry->d_sb;
18126+ sbinfo = au_sbi(sb);
18127+ parent = dget_parent(dentry);
18128+ bstart = au_dbstart(dentry);
18129+ bcpup = bstart;
18130+ if (args->force_btgt < 0) {
18131+ if (src_dentry) {
18132+ src_bstart = au_dbstart(src_dentry);
18133+ if (src_bstart < bstart)
18134+ bcpup = src_bstart;
18135+ } else if (add_entry) {
392086de
AM
18136+ flags = 0;
18137+ if (au_ftest_wrdir(args->flags, ISDIR))
18138+ au_fset_wbr(flags, DIR);
18139+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
18140+ bcpup = err;
18141+ }
1facf9fc 18142+
4a4d8108
AM
18143+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
18144+ if (add_entry)
18145+ err = AuWbrCopyup(sbinfo, dentry);
18146+ else {
18147+ if (!IS_ROOT(dentry)) {
18148+ di_read_lock_parent(parent, !AuLock_IR);
18149+ err = AuWbrCopyup(sbinfo, dentry);
18150+ di_read_unlock(parent, !AuLock_IR);
18151+ } else
18152+ err = AuWbrCopyup(sbinfo, dentry);
18153+ }
18154+ bcpup = err;
18155+ if (unlikely(err < 0))
18156+ goto out;
18157+ }
18158+ } else {
18159+ bcpup = args->force_btgt;
18160+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
1308ab2a 18161+ }
027c5e7a 18162+
4a4d8108
AM
18163+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
18164+ err = bcpup;
18165+ if (bcpup == bstart)
18166+ goto out; /* success */
4a4d8108
AM
18167+
18168+ /* copyup the new parent into the branch we process */
18169+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
18170+ if (err >= 0) {
18171+ if (!dentry->d_inode) {
18172+ au_set_h_dptr(dentry, bstart, NULL);
18173+ au_set_dbstart(dentry, bcpup);
18174+ au_set_dbend(dentry, bcpup);
18175+ }
38d290e6
JR
18176+ AuDebugOn(add_entry
18177+ && !au_ftest_wrdir(args->flags, TMPFILE)
18178+ && !au_h_dptr(dentry, bcpup));
027c5e7a 18179+ }
86dc4139
AM
18180+
18181+out:
18182+ dput(parent);
18183+ return err;
18184+}
18185+
18186+/* ---------------------------------------------------------------------- */
18187+
18188+void au_pin_hdir_unlock(struct au_pin *p)
18189+{
18190+ if (p->hdir)
18191+ au_hn_imtx_unlock(p->hdir);
18192+}
18193+
18194+static int au_pin_hdir_lock(struct au_pin *p)
18195+{
18196+ int err;
18197+
18198+ err = 0;
18199+ if (!p->hdir)
18200+ goto out;
18201+
18202+ /* even if an error happens later, keep this lock */
18203+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
18204+
18205+ err = -EBUSY;
18206+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
18207+ goto out;
18208+
18209+ err = 0;
18210+ if (p->h_dentry)
18211+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
18212+ p->h_parent, p->br);
18213+
18214+out:
18215+ return err;
18216+}
18217+
18218+int au_pin_hdir_relock(struct au_pin *p)
18219+{
18220+ int err, i;
18221+ struct inode *h_i;
18222+ struct dentry *h_d[] = {
18223+ p->h_dentry,
18224+ p->h_parent
18225+ };
18226+
18227+ err = au_pin_hdir_lock(p);
18228+ if (unlikely(err))
18229+ goto out;
18230+
18231+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
18232+ if (!h_d[i])
18233+ continue;
18234+ h_i = h_d[i]->d_inode;
18235+ if (h_i)
18236+ err = !h_i->i_nlink;
18237+ }
18238+
18239+out:
18240+ return err;
18241+}
18242+
18243+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
18244+{
18245+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
18246+ p->hdir->hi_inode->i_mutex.owner = task;
18247+#endif
18248+}
18249+
18250+void au_pin_hdir_acquire_nest(struct au_pin *p)
18251+{
18252+ if (p->hdir) {
18253+ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
18254+ p->lsc_hi, 0, NULL, _RET_IP_);
18255+ au_pin_hdir_set_owner(p, current);
18256+ }
dece6358 18257+}
1facf9fc 18258+
86dc4139
AM
18259+void au_pin_hdir_release(struct au_pin *p)
18260+{
18261+ if (p->hdir) {
18262+ au_pin_hdir_set_owner(p, p->task);
18263+ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
18264+ }
18265+}
1308ab2a 18266+
4a4d8108 18267+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 18268+{
4a4d8108
AM
18269+ if (pin && pin->parent)
18270+ return au_h_dptr(pin->parent, pin->bindex);
18271+ return NULL;
dece6358 18272+}
1facf9fc 18273+
4a4d8108 18274+void au_unpin(struct au_pin *p)
dece6358 18275+{
86dc4139
AM
18276+ if (p->hdir)
18277+ au_pin_hdir_unlock(p);
e49829fe 18278+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 18279+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
18280+ if (!p->hdir)
18281+ return;
1facf9fc 18282+
4a4d8108
AM
18283+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18284+ di_read_unlock(p->parent, AuLock_IR);
18285+ iput(p->hdir->hi_inode);
18286+ dput(p->parent);
18287+ p->parent = NULL;
18288+ p->hdir = NULL;
18289+ p->h_mnt = NULL;
86dc4139 18290+ /* do not clear p->task */
4a4d8108 18291+}
1308ab2a 18292+
4a4d8108
AM
18293+int au_do_pin(struct au_pin *p)
18294+{
18295+ int err;
18296+ struct super_block *sb;
4a4d8108
AM
18297+ struct inode *h_dir;
18298+
18299+ err = 0;
18300+ sb = p->dentry->d_sb;
86dc4139 18301+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
18302+ if (IS_ROOT(p->dentry)) {
18303+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18304+ p->h_mnt = au_br_mnt(p->br);
b4510431 18305+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
18306+ if (unlikely(err)) {
18307+ au_fclr_pin(p->flags, MNT_WRITE);
18308+ goto out_err;
18309+ }
18310+ }
dece6358 18311+ goto out;
1facf9fc 18312+ }
18313+
86dc4139 18314+ p->h_dentry = NULL;
4a4d8108 18315+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 18316+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 18317+
4a4d8108
AM
18318+ p->parent = dget_parent(p->dentry);
18319+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18320+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 18321+
4a4d8108 18322+ h_dir = NULL;
86dc4139 18323+ p->h_parent = au_h_dptr(p->parent, p->bindex);
4a4d8108
AM
18324+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
18325+ if (p->hdir)
18326+ h_dir = p->hdir->hi_inode;
dece6358 18327+
b752ccd1
AM
18328+ /*
18329+ * udba case, or
18330+ * if DI_LOCKED is not set, then p->parent may be different
18331+ * and h_parent can be NULL.
18332+ */
86dc4139 18333+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 18334+ err = -EBUSY;
4a4d8108
AM
18335+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18336+ di_read_unlock(p->parent, AuLock_IR);
18337+ dput(p->parent);
18338+ p->parent = NULL;
18339+ goto out_err;
18340+ }
1308ab2a 18341+
4a4d8108 18342+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18343+ p->h_mnt = au_br_mnt(p->br);
b4510431 18344+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 18345+ if (unlikely(err)) {
4a4d8108 18346+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
18347+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18348+ di_read_unlock(p->parent, AuLock_IR);
18349+ dput(p->parent);
18350+ p->parent = NULL;
18351+ goto out_err;
dece6358
AM
18352+ }
18353+ }
4a4d8108 18354+
86dc4139
AM
18355+ au_igrab(h_dir);
18356+ err = au_pin_hdir_lock(p);
18357+ if (!err)
18358+ goto out; /* success */
18359+
076b876e
AM
18360+ au_unpin(p);
18361+
4f0767ce 18362+out_err:
4a4d8108
AM
18363+ pr_err("err %d\n", err);
18364+ err = au_busy_or_stale();
4f0767ce 18365+out:
1facf9fc 18366+ return err;
18367+}
18368+
4a4d8108
AM
18369+void au_pin_init(struct au_pin *p, struct dentry *dentry,
18370+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18371+ unsigned int udba, unsigned char flags)
18372+{
18373+ p->dentry = dentry;
18374+ p->udba = udba;
18375+ p->lsc_di = lsc_di;
18376+ p->lsc_hi = lsc_hi;
18377+ p->flags = flags;
18378+ p->bindex = bindex;
18379+
18380+ p->parent = NULL;
18381+ p->hdir = NULL;
18382+ p->h_mnt = NULL;
86dc4139
AM
18383+
18384+ p->h_dentry = NULL;
18385+ p->h_parent = NULL;
18386+ p->br = NULL;
18387+ p->task = current;
4a4d8108
AM
18388+}
18389+
18390+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18391+ unsigned int udba, unsigned char flags)
18392+{
18393+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
18394+ udba, flags);
18395+ return au_do_pin(pin);
18396+}
18397+
dece6358
AM
18398+/* ---------------------------------------------------------------------- */
18399+
1308ab2a 18400+/*
4a4d8108
AM
18401+ * ->setattr() and ->getattr() are called in various cases.
18402+ * chmod, stat: dentry is revalidated.
18403+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
18404+ * unhashed.
18405+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 18406+ */
027c5e7a 18407+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
4a4d8108 18408+static int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 18409+{
4a4d8108
AM
18410+ int err;
18411+ struct inode *inode;
18412+ struct dentry *parent;
1facf9fc 18413+
1308ab2a 18414+ err = 0;
4a4d8108 18415+ inode = dentry->d_inode;
027c5e7a 18416+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
18417+ parent = dget_parent(dentry);
18418+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 18419+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
18420+ di_read_unlock(parent, AuLock_IR);
18421+ dput(parent);
dece6358 18422+ }
1facf9fc 18423+
4a4d8108 18424+ AuTraceErr(err);
1308ab2a 18425+ return err;
18426+}
dece6358 18427+
4a4d8108
AM
18428+#define AuIcpup_DID_CPUP 1
18429+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
7f207e10
AM
18430+#define au_fset_icpup(flags, name) \
18431+ do { (flags) |= AuIcpup_##name; } while (0)
18432+#define au_fclr_icpup(flags, name) \
18433+ do { (flags) &= ~AuIcpup_##name; } while (0)
1308ab2a 18434+
4a4d8108
AM
18435+struct au_icpup_args {
18436+ unsigned char flags;
18437+ unsigned char pin_flags;
18438+ aufs_bindex_t btgt;
18439+ unsigned int udba;
18440+ struct au_pin pin;
18441+ struct path h_path;
18442+ struct inode *h_inode;
18443+};
1308ab2a 18444+
4a4d8108
AM
18445+static int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
18446+ struct au_icpup_args *a)
1308ab2a 18447+{
18448+ int err;
4a4d8108 18449+ loff_t sz;
e49829fe 18450+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
18451+ struct dentry *hi_wh, *parent;
18452+ struct inode *inode;
4a4d8108
AM
18453+ struct au_wr_dir_args wr_dir_args = {
18454+ .force_btgt = -1,
18455+ .flags = 0
18456+ };
18457+
18458+ bstart = au_dbstart(dentry);
18459+ inode = dentry->d_inode;
18460+ if (S_ISDIR(inode->i_mode))
18461+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
18462+ /* plink or hi_wh() case */
e49829fe 18463+ ibstart = au_ibstart(inode);
027c5e7a 18464+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 18465+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
18466+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
18467+ if (unlikely(err < 0))
18468+ goto out;
18469+ a->btgt = err;
18470+ if (err != bstart)
18471+ au_fset_icpup(a->flags, DID_CPUP);
18472+
18473+ err = 0;
18474+ a->pin_flags = AuPin_MNT_WRITE;
18475+ parent = NULL;
18476+ if (!IS_ROOT(dentry)) {
18477+ au_fset_pin(a->pin_flags, DI_LOCKED);
18478+ parent = dget_parent(dentry);
18479+ di_write_lock_parent(parent);
18480+ }
18481+
18482+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
18483+ if (unlikely(err))
18484+ goto out_parent;
18485+
18486+ a->h_path.dentry = au_h_dptr(dentry, bstart);
18487+ a->h_inode = a->h_path.dentry->d_inode;
18488+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
18489+ sz = -1;
18490+ if ((ia->ia_valid & ATTR_SIZE) && ia->ia_size < i_size_read(a->h_inode))
18491+ sz = ia->ia_size;
86dc4139 18492+ mutex_unlock(&a->h_inode->i_mutex);
4a4d8108 18493+
4a4d8108 18494+ hi_wh = NULL;
027c5e7a 18495+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
18496+ hi_wh = au_hi_wh(inode, a->btgt);
18497+ if (!hi_wh) {
c2b27bf2
AM
18498+ struct au_cp_generic cpg = {
18499+ .dentry = dentry,
18500+ .bdst = a->btgt,
18501+ .bsrc = -1,
18502+ .len = sz,
18503+ .pin = &a->pin
18504+ };
18505+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
18506+ if (unlikely(err))
18507+ goto out_unlock;
18508+ hi_wh = au_hi_wh(inode, a->btgt);
18509+ /* todo: revalidate hi_wh? */
18510+ }
18511+ }
18512+
18513+ if (parent) {
18514+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
18515+ di_downgrade_lock(parent, AuLock_IR);
18516+ dput(parent);
18517+ parent = NULL;
18518+ }
18519+ if (!au_ftest_icpup(a->flags, DID_CPUP))
18520+ goto out; /* success */
18521+
18522+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
18523+ struct au_cp_generic cpg = {
18524+ .dentry = dentry,
18525+ .bdst = a->btgt,
18526+ .bsrc = bstart,
18527+ .len = sz,
18528+ .pin = &a->pin,
18529+ .flags = AuCpup_DTIME | AuCpup_HOPEN
18530+ };
18531+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
18532+ if (!err)
18533+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18534+ } else if (!hi_wh)
18535+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18536+ else
18537+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 18538+
4f0767ce 18539+out_unlock:
4a4d8108 18540+ a->h_inode = a->h_path.dentry->d_inode;
86dc4139 18541+ if (!err)
dece6358 18542+ goto out; /* success */
4a4d8108 18543+ au_unpin(&a->pin);
4f0767ce 18544+out_parent:
4a4d8108
AM
18545+ if (parent) {
18546+ di_write_unlock(parent);
18547+ dput(parent);
18548+ }
4f0767ce 18549+out:
86dc4139
AM
18550+ if (!err)
18551+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 18552+ return err;
18553+}
18554+
4a4d8108 18555+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 18556+{
4a4d8108 18557+ int err;
523b37e3 18558+ struct inode *inode, *delegated;
4a4d8108
AM
18559+ struct super_block *sb;
18560+ struct file *file;
18561+ struct au_icpup_args *a;
1facf9fc 18562+
4a4d8108
AM
18563+ inode = dentry->d_inode;
18564+ IMustLock(inode);
dece6358 18565+
4a4d8108
AM
18566+ err = -ENOMEM;
18567+ a = kzalloc(sizeof(*a), GFP_NOFS);
18568+ if (unlikely(!a))
18569+ goto out;
1facf9fc 18570+
4a4d8108
AM
18571+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
18572+ ia->ia_valid &= ~ATTR_MODE;
dece6358 18573+
4a4d8108
AM
18574+ file = NULL;
18575+ sb = dentry->d_sb;
e49829fe
JR
18576+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18577+ if (unlikely(err))
18578+ goto out_kfree;
18579+
4a4d8108
AM
18580+ if (ia->ia_valid & ATTR_FILE) {
18581+ /* currently ftruncate(2) only */
18582+ AuDebugOn(!S_ISREG(inode->i_mode));
18583+ file = ia->ia_file;
18584+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
18585+ if (unlikely(err))
18586+ goto out_si;
18587+ ia->ia_file = au_hf_top(file);
18588+ a->udba = AuOpt_UDBA_NONE;
18589+ } else {
18590+ /* fchmod() doesn't pass ia_file */
18591+ a->udba = au_opt_udba(sb);
027c5e7a
AM
18592+ di_write_lock_child(dentry);
18593+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
18594+ if (d_unhashed(dentry))
18595+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
18596+ if (a->udba != AuOpt_UDBA_NONE) {
18597+ AuDebugOn(IS_ROOT(dentry));
18598+ err = au_reval_for_attr(dentry, au_sigen(sb));
18599+ if (unlikely(err))
18600+ goto out_dentry;
18601+ }
dece6358 18602+ }
dece6358 18603+
4a4d8108
AM
18604+ err = au_pin_and_icpup(dentry, ia, a);
18605+ if (unlikely(err < 0))
18606+ goto out_dentry;
18607+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
18608+ ia->ia_file = NULL;
18609+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 18610+ }
dece6358 18611+
4a4d8108
AM
18612+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
18613+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
18614+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 18615+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
18616+ if (unlikely(err))
18617+ goto out_unlock;
18618+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
18619+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 18620+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
18621+ if (unlikely(err))
18622+ goto out_unlock;
18623+ }
dece6358 18624+
4a4d8108
AM
18625+ if (ia->ia_valid & ATTR_SIZE) {
18626+ struct file *f;
1308ab2a 18627+
953406b4 18628+ if (ia->ia_size < i_size_read(inode))
4a4d8108 18629+ /* unmap only */
953406b4 18630+ truncate_setsize(inode, ia->ia_size);
1308ab2a 18631+
4a4d8108
AM
18632+ f = NULL;
18633+ if (ia->ia_valid & ATTR_FILE)
18634+ f = ia->ia_file;
18635+ mutex_unlock(&a->h_inode->i_mutex);
18636+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
18637+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
523b37e3
AM
18638+ } else {
18639+ delegated = NULL;
18640+ while (1) {
18641+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
18642+ if (delegated) {
18643+ err = break_deleg_wait(&delegated);
18644+ if (!err)
18645+ continue;
18646+ }
18647+ break;
18648+ }
18649+ }
4a4d8108
AM
18650+ if (!err)
18651+ au_cpup_attr_changeable(inode);
1308ab2a 18652+
4f0767ce 18653+out_unlock:
4a4d8108
AM
18654+ mutex_unlock(&a->h_inode->i_mutex);
18655+ au_unpin(&a->pin);
027c5e7a
AM
18656+ if (unlikely(err))
18657+ au_update_dbstart(dentry);
4f0767ce 18658+out_dentry:
4a4d8108
AM
18659+ di_write_unlock(dentry);
18660+ if (file) {
18661+ fi_write_unlock(file);
18662+ ia->ia_file = file;
18663+ ia->ia_valid |= ATTR_FILE;
18664+ }
4f0767ce 18665+out_si:
4a4d8108 18666+ si_read_unlock(sb);
e49829fe 18667+out_kfree:
4a4d8108 18668+ kfree(a);
4f0767ce 18669+out:
4a4d8108
AM
18670+ AuTraceErr(err);
18671+ return err;
1facf9fc 18672+}
18673+
4a4d8108
AM
18674+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
18675+ unsigned int nlink)
1facf9fc 18676+{
9dbd164d
AM
18677+ unsigned int n;
18678+
4a4d8108 18679+ inode->i_mode = st->mode;
86dc4139
AM
18680+ /* don't i_[ug]id_write() here */
18681+ inode->i_uid = st->uid;
18682+ inode->i_gid = st->gid;
4a4d8108
AM
18683+ inode->i_atime = st->atime;
18684+ inode->i_mtime = st->mtime;
18685+ inode->i_ctime = st->ctime;
1facf9fc 18686+
4a4d8108
AM
18687+ au_cpup_attr_nlink(inode, /*force*/0);
18688+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
18689+ n = inode->i_nlink;
18690+ n -= nlink;
18691+ n += st->nlink;
f6b6e03d 18692+ smp_mb(); /* for i_nlink */
7eafdf33 18693+ /* 0 can happen */
92d182d2 18694+ set_nlink(inode, n);
4a4d8108 18695+ }
1facf9fc 18696+
4a4d8108
AM
18697+ spin_lock(&inode->i_lock);
18698+ inode->i_blocks = st->blocks;
18699+ i_size_write(inode, st->size);
18700+ spin_unlock(&inode->i_lock);
1facf9fc 18701+}
18702+
4a4d8108
AM
18703+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
18704+ struct dentry *dentry, struct kstat *st)
1facf9fc 18705+{
4a4d8108 18706+ int err;
076b876e 18707+ unsigned int mnt_flags, sigen;
4a4d8108
AM
18708+ aufs_bindex_t bindex;
18709+ unsigned char udba_none, positive;
18710+ struct super_block *sb, *h_sb;
18711+ struct inode *inode;
c06a8ce3 18712+ struct path h_path;
1facf9fc 18713+
4a4d8108
AM
18714+ sb = dentry->d_sb;
18715+ inode = dentry->d_inode;
7f207e10
AM
18716+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18717+ if (unlikely(err))
18718+ goto out;
4a4d8108
AM
18719+ mnt_flags = au_mntflags(sb);
18720+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 18721+
4a4d8108 18722+ /* support fstat(2) */
027c5e7a 18723+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 18724+ sigen = au_sigen(sb);
027c5e7a
AM
18725+ err = au_digen_test(dentry, sigen);
18726+ if (!err) {
4a4d8108 18727+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a
AM
18728+ err = au_dbrange_test(dentry);
18729+ if (unlikely(err))
18730+ goto out_unlock;
18731+ } else {
4a4d8108
AM
18732+ AuDebugOn(IS_ROOT(dentry));
18733+ di_write_lock_child(dentry);
027c5e7a
AM
18734+ err = au_dbrange_test(dentry);
18735+ if (!err)
18736+ err = au_reval_for_attr(dentry, sigen);
4a4d8108
AM
18737+ di_downgrade_lock(dentry, AuLock_IR);
18738+ if (unlikely(err))
7f207e10 18739+ goto out_unlock;
4a4d8108
AM
18740+ }
18741+ } else
18742+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 18743+
4a4d8108 18744+ bindex = au_ibstart(inode);
c06a8ce3
AM
18745+ h_path.mnt = au_sbr_mnt(sb, bindex);
18746+ h_sb = h_path.mnt->mnt_sb;
4a4d8108
AM
18747+ if (!au_test_fs_bad_iattr(h_sb) && udba_none)
18748+ goto out_fill; /* success */
1facf9fc 18749+
c06a8ce3 18750+ h_path.dentry = NULL;
4a4d8108 18751+ if (au_dbstart(dentry) == bindex)
c06a8ce3 18752+ h_path.dentry = dget(au_h_dptr(dentry, bindex));
4a4d8108 18753+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c06a8ce3
AM
18754+ h_path.dentry = au_plink_lkup(inode, bindex);
18755+ if (IS_ERR(h_path.dentry))
4a4d8108
AM
18756+ goto out_fill; /* pretending success */
18757+ }
18758+ /* illegally overlapped or something */
c06a8ce3 18759+ if (unlikely(!h_path.dentry))
4a4d8108
AM
18760+ goto out_fill; /* pretending success */
18761+
c06a8ce3 18762+ positive = !!h_path.dentry->d_inode;
4a4d8108 18763+ if (positive)
c06a8ce3
AM
18764+ err = vfs_getattr(&h_path, st);
18765+ dput(h_path.dentry);
4a4d8108
AM
18766+ if (!err) {
18767+ if (positive)
c06a8ce3
AM
18768+ au_refresh_iattr(inode, st,
18769+ h_path.dentry->d_inode->i_nlink);
4a4d8108 18770+ goto out_fill; /* success */
1facf9fc 18771+ }
7f207e10
AM
18772+ AuTraceErr(err);
18773+ goto out_unlock;
4a4d8108 18774+
4f0767ce 18775+out_fill:
4a4d8108 18776+ generic_fillattr(inode, st);
7f207e10 18777+out_unlock:
4a4d8108
AM
18778+ di_read_unlock(dentry, AuLock_IR);
18779+ si_read_unlock(sb);
7f207e10
AM
18780+out:
18781+ AuTraceErr(err);
4a4d8108 18782+ return err;
1facf9fc 18783+}
18784+
18785+/* ---------------------------------------------------------------------- */
18786+
4a4d8108
AM
18787+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
18788+ int bufsiz)
1facf9fc 18789+{
18790+ int err;
4a4d8108
AM
18791+ struct super_block *sb;
18792+ struct dentry *h_dentry;
1facf9fc 18793+
4a4d8108
AM
18794+ err = -EINVAL;
18795+ h_dentry = au_h_dptr(dentry, bindex);
18796+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
18797+ goto out;
1facf9fc 18798+
4a4d8108
AM
18799+ err = security_inode_readlink(h_dentry);
18800+ if (unlikely(err))
dece6358 18801+ goto out;
1facf9fc 18802+
4a4d8108
AM
18803+ sb = dentry->d_sb;
18804+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
18805+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
18806+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
1facf9fc 18807+ }
4a4d8108 18808+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 18809+
4f0767ce 18810+out:
4a4d8108
AM
18811+ return err;
18812+}
1facf9fc 18813+
4a4d8108
AM
18814+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
18815+{
18816+ int err;
1facf9fc 18817+
027c5e7a
AM
18818+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
18819+ if (unlikely(err))
18820+ goto out;
18821+ err = au_d_hashed_positive(dentry);
18822+ if (!err)
18823+ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
4a4d8108 18824+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 18825+
027c5e7a 18826+out:
4a4d8108
AM
18827+ return err;
18828+}
1facf9fc 18829+
4a4d8108
AM
18830+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
18831+{
18832+ int err;
4a4d8108 18833+ mm_segment_t old_fs;
b752ccd1
AM
18834+ union {
18835+ char *k;
18836+ char __user *u;
18837+ } buf;
1facf9fc 18838+
4a4d8108 18839+ err = -ENOMEM;
537831f9 18840+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 18841+ if (unlikely(!buf.k))
4a4d8108 18842+ goto out;
1facf9fc 18843+
027c5e7a
AM
18844+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
18845+ if (unlikely(err))
18846+ goto out_name;
18847+
18848+ err = au_d_hashed_positive(dentry);
18849+ if (!err) {
18850+ old_fs = get_fs();
18851+ set_fs(KERNEL_DS);
18852+ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
18853+ set_fs(old_fs);
18854+ }
4a4d8108 18855+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 18856+
4a4d8108 18857+ if (err >= 0) {
b752ccd1 18858+ buf.k[err] = 0;
4a4d8108 18859+ /* will be freed by put_link */
b752ccd1 18860+ nd_set_link(nd, buf.k);
4a4d8108 18861+ return NULL; /* success */
1308ab2a 18862+ }
1facf9fc 18863+
027c5e7a 18864+out_name:
537831f9 18865+ free_page((unsigned long)buf.k);
4f0767ce 18866+out:
4a4d8108
AM
18867+ AuTraceErr(err);
18868+ return ERR_PTR(err);
18869+}
1facf9fc 18870+
4a4d8108
AM
18871+static void aufs_put_link(struct dentry *dentry __maybe_unused,
18872+ struct nameidata *nd, void *cookie __maybe_unused)
18873+{
537831f9
AM
18874+ char *p;
18875+
18876+ p = nd_get_link(nd);
18877+ if (!IS_ERR_OR_NULL(p))
18878+ free_page((unsigned long)p);
4a4d8108 18879+}
1facf9fc 18880+
4a4d8108 18881+/* ---------------------------------------------------------------------- */
1facf9fc 18882+
0c3ec466 18883+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 18884+{
0c3ec466
AM
18885+ int err;
18886+ struct super_block *sb;
18887+ struct inode *h_inode;
18888+
18889+ sb = inode->i_sb;
18890+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
18891+ lockdep_off();
18892+ si_read_lock(sb, AuLock_FLUSH);
18893+ ii_write_lock_child(inode);
18894+ lockdep_on();
18895+ h_inode = au_h_iptr(inode, au_ibstart(inode));
18896+ err = vfsub_update_time(h_inode, ts, flags);
18897+ lockdep_off();
38d290e6
JR
18898+ if (!err)
18899+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
18900+ ii_write_unlock(inode);
18901+ si_read_unlock(sb);
18902+ lockdep_on();
38d290e6
JR
18903+
18904+ if (!err && (flags & S_VERSION))
18905+ inode_inc_iversion(inode);
18906+
0c3ec466 18907+ return err;
4a4d8108 18908+}
1facf9fc 18909+
4a4d8108 18910+/* ---------------------------------------------------------------------- */
1308ab2a 18911+
4a4d8108
AM
18912+struct inode_operations aufs_symlink_iop = {
18913+ .permission = aufs_permission,
18914+ .setattr = aufs_setattr,
18915+ .getattr = aufs_getattr,
0c3ec466 18916+
4a4d8108
AM
18917+ .readlink = aufs_readlink,
18918+ .follow_link = aufs_follow_link,
0c3ec466
AM
18919+ .put_link = aufs_put_link,
18920+
18921+ /* .update_time = aufs_update_time */
4a4d8108
AM
18922+};
18923+
18924+struct inode_operations aufs_dir_iop = {
18925+ .create = aufs_create,
18926+ .lookup = aufs_lookup,
18927+ .link = aufs_link,
18928+ .unlink = aufs_unlink,
18929+ .symlink = aufs_symlink,
18930+ .mkdir = aufs_mkdir,
18931+ .rmdir = aufs_rmdir,
18932+ .mknod = aufs_mknod,
18933+ .rename = aufs_rename,
18934+
18935+ .permission = aufs_permission,
18936+ .setattr = aufs_setattr,
0c3ec466
AM
18937+ .getattr = aufs_getattr,
18938+
38d290e6 18939+ .update_time = aufs_update_time,
b4510431 18940+ /* no support for atomic_open() */
38d290e6
JR
18941+
18942+ .tmpfile = aufs_tmpfile
4a4d8108
AM
18943+};
18944+
18945+struct inode_operations aufs_iop = {
18946+ .permission = aufs_permission,
18947+ .setattr = aufs_setattr,
18948+ .getattr = aufs_getattr,
0c3ec466
AM
18949+
18950+ .update_time = aufs_update_time
4a4d8108 18951+};
7f207e10
AM
18952diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
18953--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
18954+++ linux/fs/aufs/i_op_del.c 2014-08-14 10:15:45.121942630 +0200
18955@@ -0,0 +1,507 @@
1facf9fc 18956+/*
523b37e3 18957+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 18958+ *
18959+ * This program, aufs is free software; you can redistribute it and/or modify
18960+ * it under the terms of the GNU General Public License as published by
18961+ * the Free Software Foundation; either version 2 of the License, or
18962+ * (at your option) any later version.
dece6358
AM
18963+ *
18964+ * This program is distributed in the hope that it will be useful,
18965+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18966+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18967+ * GNU General Public License for more details.
18968+ *
18969+ * You should have received a copy of the GNU General Public License
523b37e3 18970+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 18971+ */
18972+
18973+/*
4a4d8108 18974+ * inode operations (del entry)
1308ab2a 18975+ */
dece6358 18976+
1308ab2a 18977+#include "aufs.h"
dece6358 18978+
4a4d8108
AM
18979+/*
18980+ * decide if a new whiteout for @dentry is necessary or not.
18981+ * when it is necessary, prepare the parent dir for the upper branch whose
18982+ * branch index is @bcpup for creation. the actual creation of the whiteout will
18983+ * be done by caller.
18984+ * return value:
18985+ * 0: wh is unnecessary
18986+ * plus: wh is necessary
18987+ * minus: error
18988+ */
18989+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 18990+{
4a4d8108
AM
18991+ int need_wh, err;
18992+ aufs_bindex_t bstart;
18993+ struct super_block *sb;
dece6358 18994+
4a4d8108
AM
18995+ sb = dentry->d_sb;
18996+ bstart = au_dbstart(dentry);
18997+ if (*bcpup < 0) {
18998+ *bcpup = bstart;
18999+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
19000+ err = AuWbrCopyup(au_sbi(sb), dentry);
19001+ *bcpup = err;
19002+ if (unlikely(err < 0))
19003+ goto out;
19004+ }
19005+ } else
19006+ AuDebugOn(bstart < *bcpup
19007+ || au_test_ro(sb, *bcpup, dentry->d_inode));
19008+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 19009+
4a4d8108
AM
19010+ if (*bcpup != bstart) {
19011+ err = au_cpup_dirs(dentry, *bcpup);
19012+ if (unlikely(err))
19013+ goto out;
19014+ need_wh = 1;
19015+ } else {
027c5e7a 19016+ struct au_dinfo *dinfo, *tmp;
4a4d8108 19017+
027c5e7a
AM
19018+ need_wh = -ENOMEM;
19019+ dinfo = au_di(dentry);
19020+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
19021+ if (tmp) {
19022+ au_di_cp(tmp, dinfo);
19023+ au_di_swap(tmp, dinfo);
19024+ /* returns the number of positive dentries */
537831f9 19025+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
19026+ au_di_swap(tmp, dinfo);
19027+ au_rw_write_unlock(&tmp->di_rwsem);
19028+ au_di_free(tmp);
4a4d8108
AM
19029+ }
19030+ }
19031+ AuDbg("need_wh %d\n", need_wh);
19032+ err = need_wh;
19033+
4f0767ce 19034+out:
4a4d8108 19035+ return err;
1facf9fc 19036+}
19037+
4a4d8108
AM
19038+/*
19039+ * simple tests for the del-entry operations.
19040+ * following the checks in vfs, plus the parent-child relationship.
19041+ */
19042+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
19043+ struct dentry *h_parent, int isdir)
1facf9fc 19044+{
4a4d8108
AM
19045+ int err;
19046+ umode_t h_mode;
19047+ struct dentry *h_dentry, *h_latest;
1308ab2a 19048+ struct inode *h_inode;
1facf9fc 19049+
4a4d8108
AM
19050+ h_dentry = au_h_dptr(dentry, bindex);
19051+ h_inode = h_dentry->d_inode;
19052+ if (dentry->d_inode) {
19053+ err = -ENOENT;
19054+ if (unlikely(!h_inode || !h_inode->i_nlink))
19055+ goto out;
1facf9fc 19056+
4a4d8108
AM
19057+ h_mode = h_inode->i_mode;
19058+ if (!isdir) {
19059+ err = -EISDIR;
19060+ if (unlikely(S_ISDIR(h_mode)))
19061+ goto out;
19062+ } else if (unlikely(!S_ISDIR(h_mode))) {
19063+ err = -ENOTDIR;
19064+ goto out;
19065+ }
19066+ } else {
19067+ /* rename(2) case */
19068+ err = -EIO;
19069+ if (unlikely(h_inode))
19070+ goto out;
19071+ }
1facf9fc 19072+
4a4d8108
AM
19073+ err = -ENOENT;
19074+ /* expected parent dir is locked */
19075+ if (unlikely(h_parent != h_dentry->d_parent))
19076+ goto out;
19077+ err = 0;
19078+
19079+ /*
19080+ * rmdir a dir may break the consistency on some filesystem.
19081+ * let's try heavy test.
19082+ */
19083+ err = -EACCES;
076b876e
AM
19084+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
19085+ && au_test_h_perm(h_parent->d_inode,
19086+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
19087+ goto out;
19088+
076b876e 19089+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
19090+ err = -EIO;
19091+ if (IS_ERR(h_latest))
19092+ goto out;
19093+ if (h_latest == h_dentry)
19094+ err = 0;
19095+ dput(h_latest);
19096+
4f0767ce 19097+out:
4a4d8108 19098+ return err;
1308ab2a 19099+}
1facf9fc 19100+
4a4d8108
AM
19101+/*
19102+ * decide the branch where we operate for @dentry. the branch index will be set
19103+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
19104+ * dir for reverting.
19105+ * when a new whiteout is necessary, create it.
19106+ */
19107+static struct dentry*
19108+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
19109+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 19110+{
4a4d8108
AM
19111+ struct dentry *wh_dentry;
19112+ struct super_block *sb;
19113+ struct path h_path;
19114+ int err, need_wh;
19115+ unsigned int udba;
19116+ aufs_bindex_t bcpup;
dece6358 19117+
4a4d8108
AM
19118+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
19119+ wh_dentry = ERR_PTR(need_wh);
19120+ if (unlikely(need_wh < 0))
19121+ goto out;
19122+
19123+ sb = dentry->d_sb;
19124+ udba = au_opt_udba(sb);
19125+ bcpup = *rbcpup;
19126+ err = au_pin(pin, dentry, bcpup, udba,
19127+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19128+ wh_dentry = ERR_PTR(err);
19129+ if (unlikely(err))
19130+ goto out;
19131+
19132+ h_path.dentry = au_pinned_h_parent(pin);
19133+ if (udba != AuOpt_UDBA_NONE
19134+ && au_dbstart(dentry) == bcpup) {
19135+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
19136+ wh_dentry = ERR_PTR(err);
19137+ if (unlikely(err))
19138+ goto out_unpin;
19139+ }
19140+
19141+ h_path.mnt = au_sbr_mnt(sb, bcpup);
19142+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
19143+ wh_dentry = NULL;
19144+ if (!need_wh)
19145+ goto out; /* success, no need to create whiteout */
19146+
19147+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
19148+ if (IS_ERR(wh_dentry))
19149+ goto out_unpin;
19150+
19151+ /* returns with the parent is locked and wh_dentry is dget-ed */
19152+ goto out; /* success */
19153+
4f0767ce 19154+out_unpin:
4a4d8108 19155+ au_unpin(pin);
4f0767ce 19156+out:
4a4d8108 19157+ return wh_dentry;
1facf9fc 19158+}
19159+
4a4d8108
AM
19160+/*
19161+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
19162+ * in order to be revertible and save time for removing many child whiteouts
19163+ * under the dir.
19164+ * returns 1 when there are too many child whiteout and caller should remove
19165+ * them asynchronously. returns 0 when the number of children is enough small to
19166+ * remove now or the branch fs is a remote fs.
19167+ * otherwise return an error.
19168+ */
19169+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
19170+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 19171+{
4a4d8108
AM
19172+ int rmdir_later, err, dirwh;
19173+ struct dentry *h_dentry;
19174+ struct super_block *sb;
19175+
19176+ sb = dentry->d_sb;
19177+ SiMustAnyLock(sb);
19178+ h_dentry = au_h_dptr(dentry, bindex);
19179+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
19180+ if (unlikely(err))
19181+ goto out;
19182+
19183+ /* stop monitoring */
19184+ au_hn_free(au_hi(dentry->d_inode, bindex));
19185+
19186+ if (!au_test_fs_remote(h_dentry->d_sb)) {
19187+ dirwh = au_sbi(sb)->si_dirwh;
19188+ rmdir_later = (dirwh <= 1);
19189+ if (!rmdir_later)
19190+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
19191+ dirwh);
19192+ if (rmdir_later)
19193+ return rmdir_later;
19194+ }
1facf9fc 19195+
4a4d8108
AM
19196+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
19197+ if (unlikely(err)) {
523b37e3
AM
19198+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
19199+ h_dentry, bindex, err);
4a4d8108
AM
19200+ err = 0;
19201+ }
dece6358 19202+
4f0767ce 19203+out:
4a4d8108
AM
19204+ AuTraceErr(err);
19205+ return err;
19206+}
1308ab2a 19207+
4a4d8108
AM
19208+/*
19209+ * final procedure for deleting a entry.
19210+ * maintain dentry and iattr.
19211+ */
19212+static void epilog(struct inode *dir, struct dentry *dentry,
19213+ aufs_bindex_t bindex)
19214+{
19215+ struct inode *inode;
1308ab2a 19216+
4a4d8108
AM
19217+ inode = dentry->d_inode;
19218+ d_drop(dentry);
19219+ inode->i_ctime = dir->i_ctime;
1308ab2a 19220+
4a4d8108
AM
19221+ if (au_ibstart(dir) == bindex)
19222+ au_cpup_attr_timesizes(dir);
19223+ dir->i_version++;
1facf9fc 19224+}
19225+
4a4d8108
AM
19226+/*
19227+ * when an error happened, remove the created whiteout and revert everything.
19228+ */
7f207e10
AM
19229+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
19230+ aufs_bindex_t bwh, struct dentry *wh_dentry,
19231+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 19232+{
4a4d8108
AM
19233+ int rerr;
19234+ struct path h_path = {
19235+ .dentry = wh_dentry,
7f207e10 19236+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 19237+ };
dece6358 19238+
7f207e10 19239+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
19240+ if (!rerr) {
19241+ au_set_dbwh(dentry, bwh);
19242+ au_dtime_revert(dt);
19243+ return 0;
19244+ }
dece6358 19245+
523b37e3 19246+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 19247+ return -EIO;
1facf9fc 19248+}
19249+
4a4d8108 19250+/* ---------------------------------------------------------------------- */
1facf9fc 19251+
4a4d8108 19252+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 19253+{
4a4d8108
AM
19254+ int err;
19255+ aufs_bindex_t bwh, bindex, bstart;
523b37e3 19256+ struct inode *inode, *h_dir, *delegated;
4a4d8108 19257+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
19258+ /* to reuduce stack size */
19259+ struct {
19260+ struct au_dtime dt;
19261+ struct au_pin pin;
19262+ struct path h_path;
19263+ } *a;
1facf9fc 19264+
4a4d8108 19265+ IMustLock(dir);
027c5e7a 19266+
c2b27bf2
AM
19267+ err = -ENOMEM;
19268+ a = kmalloc(sizeof(*a), GFP_NOFS);
19269+ if (unlikely(!a))
19270+ goto out;
19271+
027c5e7a
AM
19272+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
19273+ if (unlikely(err))
c2b27bf2 19274+ goto out_free;
027c5e7a
AM
19275+ err = au_d_hashed_positive(dentry);
19276+ if (unlikely(err))
19277+ goto out_unlock;
4a4d8108 19278+ inode = dentry->d_inode;
4a4d8108 19279+ IMustLock(inode);
027c5e7a
AM
19280+ err = -EISDIR;
19281+ if (unlikely(S_ISDIR(inode->i_mode)))
19282+ goto out_unlock; /* possible? */
1facf9fc 19283+
4a4d8108
AM
19284+ bstart = au_dbstart(dentry);
19285+ bwh = au_dbwh(dentry);
19286+ bindex = -1;
027c5e7a
AM
19287+ parent = dentry->d_parent; /* dir inode is locked */
19288+ di_write_lock_parent(parent);
c2b27bf2
AM
19289+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
19290+ &a->pin);
4a4d8108
AM
19291+ err = PTR_ERR(wh_dentry);
19292+ if (IS_ERR(wh_dentry))
027c5e7a 19293+ goto out_parent;
1facf9fc 19294+
c2b27bf2
AM
19295+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
19296+ a->h_path.dentry = au_h_dptr(dentry, bstart);
19297+ dget(a->h_path.dentry);
4a4d8108 19298+ if (bindex == bstart) {
c2b27bf2 19299+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
19300+ delegated = NULL;
19301+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
19302+ if (unlikely(err == -EWOULDBLOCK)) {
19303+ pr_warn("cannot retry for NFSv4 delegation"
19304+ " for an internal unlink\n");
19305+ iput(delegated);
19306+ }
4a4d8108
AM
19307+ } else {
19308+ /* dir inode is locked */
19309+ h_dir = wh_dentry->d_parent->d_inode;
19310+ IMustLock(h_dir);
19311+ err = 0;
19312+ }
dece6358 19313+
4a4d8108 19314+ if (!err) {
7f207e10 19315+ vfsub_drop_nlink(inode);
4a4d8108
AM
19316+ epilog(dir, dentry, bindex);
19317+
19318+ /* update target timestamps */
19319+ if (bindex == bstart) {
c2b27bf2
AM
19320+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
19321+ /*ignore*/
19322+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
4a4d8108
AM
19323+ } else
19324+ /* todo: this timestamp may be reverted later */
19325+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 19326+ goto out_unpin; /* success */
1facf9fc 19327+ }
19328+
4a4d8108
AM
19329+ /* revert */
19330+ if (wh_dentry) {
19331+ int rerr;
19332+
c2b27bf2
AM
19333+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19334+ &a->dt);
4a4d8108
AM
19335+ if (rerr)
19336+ err = rerr;
dece6358 19337+ }
1facf9fc 19338+
027c5e7a 19339+out_unpin:
c2b27bf2 19340+ au_unpin(&a->pin);
4a4d8108 19341+ dput(wh_dentry);
c2b27bf2 19342+ dput(a->h_path.dentry);
027c5e7a 19343+out_parent:
4a4d8108 19344+ di_write_unlock(parent);
027c5e7a 19345+out_unlock:
4a4d8108 19346+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19347+out_free:
19348+ kfree(a);
027c5e7a 19349+out:
4a4d8108 19350+ return err;
dece6358
AM
19351+}
19352+
4a4d8108 19353+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 19354+{
4a4d8108
AM
19355+ int err, rmdir_later;
19356+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
19357+ struct inode *inode;
19358+ struct dentry *parent, *wh_dentry, *h_dentry;
19359+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
19360+ /* to reuduce stack size */
19361+ struct {
19362+ struct au_dtime dt;
19363+ struct au_pin pin;
19364+ } *a;
1facf9fc 19365+
4a4d8108 19366+ IMustLock(dir);
027c5e7a 19367+
c2b27bf2
AM
19368+ err = -ENOMEM;
19369+ a = kmalloc(sizeof(*a), GFP_NOFS);
19370+ if (unlikely(!a))
19371+ goto out;
19372+
027c5e7a
AM
19373+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
19374+ if (unlikely(err))
c2b27bf2 19375+ goto out_free;
53392da6
AM
19376+ err = au_alive_dir(dentry);
19377+ if (unlikely(err))
027c5e7a 19378+ goto out_unlock;
53392da6 19379+ inode = dentry->d_inode;
4a4d8108 19380+ IMustLock(inode);
027c5e7a
AM
19381+ err = -ENOTDIR;
19382+ if (unlikely(!S_ISDIR(inode->i_mode)))
19383+ goto out_unlock; /* possible? */
dece6358 19384+
4a4d8108
AM
19385+ err = -ENOMEM;
19386+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
19387+ if (unlikely(!args))
19388+ goto out_unlock;
dece6358 19389+
4a4d8108
AM
19390+ parent = dentry->d_parent; /* dir inode is locked */
19391+ di_write_lock_parent(parent);
19392+ err = au_test_empty(dentry, &args->whlist);
19393+ if (unlikely(err))
027c5e7a 19394+ goto out_parent;
1facf9fc 19395+
4a4d8108
AM
19396+ bstart = au_dbstart(dentry);
19397+ bwh = au_dbwh(dentry);
19398+ bindex = -1;
c2b27bf2
AM
19399+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
19400+ &a->pin);
4a4d8108
AM
19401+ err = PTR_ERR(wh_dentry);
19402+ if (IS_ERR(wh_dentry))
027c5e7a 19403+ goto out_parent;
1facf9fc 19404+
4a4d8108
AM
19405+ h_dentry = au_h_dptr(dentry, bstart);
19406+ dget(h_dentry);
19407+ rmdir_later = 0;
19408+ if (bindex == bstart) {
19409+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
19410+ if (err > 0) {
19411+ rmdir_later = err;
19412+ err = 0;
19413+ }
19414+ } else {
19415+ /* stop monitoring */
19416+ au_hn_free(au_hi(inode, bstart));
19417+
19418+ /* dir inode is locked */
19419+ IMustLock(wh_dentry->d_parent->d_inode);
1facf9fc 19420+ err = 0;
19421+ }
19422+
4a4d8108 19423+ if (!err) {
027c5e7a 19424+ vfsub_dead_dir(inode);
4a4d8108
AM
19425+ au_set_dbdiropq(dentry, -1);
19426+ epilog(dir, dentry, bindex);
1308ab2a 19427+
4a4d8108
AM
19428+ if (rmdir_later) {
19429+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
19430+ args = NULL;
19431+ }
1308ab2a 19432+
4a4d8108 19433+ goto out_unpin; /* success */
1facf9fc 19434+ }
19435+
4a4d8108
AM
19436+ /* revert */
19437+ AuLabel(revert);
19438+ if (wh_dentry) {
19439+ int rerr;
1308ab2a 19440+
c2b27bf2
AM
19441+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19442+ &a->dt);
4a4d8108
AM
19443+ if (rerr)
19444+ err = rerr;
1facf9fc 19445+ }
19446+
4f0767ce 19447+out_unpin:
c2b27bf2 19448+ au_unpin(&a->pin);
4a4d8108
AM
19449+ dput(wh_dentry);
19450+ dput(h_dentry);
027c5e7a 19451+out_parent:
4a4d8108
AM
19452+ di_write_unlock(parent);
19453+ if (args)
19454+ au_whtmp_rmdir_free(args);
4f0767ce 19455+out_unlock:
4a4d8108 19456+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19457+out_free:
19458+ kfree(a);
4f0767ce 19459+out:
4a4d8108
AM
19460+ AuTraceErr(err);
19461+ return err;
dece6358 19462+}
7f207e10
AM
19463diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
19464--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
19465+++ linux/fs/aufs/i_op_ren.c 2014-08-14 10:15:45.128609525 +0200
19466@@ -0,0 +1,1034 @@
1facf9fc 19467+/*
523b37e3 19468+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19469+ *
19470+ * This program, aufs is free software; you can redistribute it and/or modify
19471+ * it under the terms of the GNU General Public License as published by
19472+ * the Free Software Foundation; either version 2 of the License, or
19473+ * (at your option) any later version.
dece6358
AM
19474+ *
19475+ * This program is distributed in the hope that it will be useful,
19476+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19477+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19478+ * GNU General Public License for more details.
19479+ *
19480+ * You should have received a copy of the GNU General Public License
523b37e3 19481+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19482+ */
19483+
19484+/*
4a4d8108
AM
19485+ * inode operation (rename entry)
19486+ * todo: this is crazy monster
1facf9fc 19487+ */
19488+
19489+#include "aufs.h"
19490+
4a4d8108
AM
19491+enum { AuSRC, AuDST, AuSrcDst };
19492+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 19493+
4a4d8108
AM
19494+#define AuRen_ISDIR 1
19495+#define AuRen_ISSAMEDIR (1 << 1)
19496+#define AuRen_WHSRC (1 << 2)
19497+#define AuRen_WHDST (1 << 3)
19498+#define AuRen_MNT_WRITE (1 << 4)
19499+#define AuRen_DT_DSTDIR (1 << 5)
19500+#define AuRen_DIROPQ (1 << 6)
19501+#define AuRen_CPUP (1 << 7)
19502+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
19503+#define au_fset_ren(flags, name) \
19504+ do { (flags) |= AuRen_##name; } while (0)
19505+#define au_fclr_ren(flags, name) \
19506+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 19507+
4a4d8108
AM
19508+struct au_ren_args {
19509+ struct {
19510+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
19511+ *wh_dentry;
19512+ struct inode *dir, *inode;
19513+ struct au_hinode *hdir;
19514+ struct au_dtime dt[AuParentChild];
19515+ aufs_bindex_t bstart;
19516+ } sd[AuSrcDst];
1facf9fc 19517+
4a4d8108
AM
19518+#define src_dentry sd[AuSRC].dentry
19519+#define src_dir sd[AuSRC].dir
19520+#define src_inode sd[AuSRC].inode
19521+#define src_h_dentry sd[AuSRC].h_dentry
19522+#define src_parent sd[AuSRC].parent
19523+#define src_h_parent sd[AuSRC].h_parent
19524+#define src_wh_dentry sd[AuSRC].wh_dentry
19525+#define src_hdir sd[AuSRC].hdir
19526+#define src_h_dir sd[AuSRC].hdir->hi_inode
19527+#define src_dt sd[AuSRC].dt
19528+#define src_bstart sd[AuSRC].bstart
1facf9fc 19529+
4a4d8108
AM
19530+#define dst_dentry sd[AuDST].dentry
19531+#define dst_dir sd[AuDST].dir
19532+#define dst_inode sd[AuDST].inode
19533+#define dst_h_dentry sd[AuDST].h_dentry
19534+#define dst_parent sd[AuDST].parent
19535+#define dst_h_parent sd[AuDST].h_parent
19536+#define dst_wh_dentry sd[AuDST].wh_dentry
19537+#define dst_hdir sd[AuDST].hdir
19538+#define dst_h_dir sd[AuDST].hdir->hi_inode
19539+#define dst_dt sd[AuDST].dt
19540+#define dst_bstart sd[AuDST].bstart
19541+
19542+ struct dentry *h_trap;
19543+ struct au_branch *br;
19544+ struct au_hinode *src_hinode;
19545+ struct path h_path;
19546+ struct au_nhash whlist;
027c5e7a 19547+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 19548+
1308ab2a 19549+ unsigned int flags;
1facf9fc 19550+
4a4d8108
AM
19551+ struct au_whtmp_rmdir *thargs;
19552+ struct dentry *h_dst;
19553+};
1308ab2a 19554+
4a4d8108 19555+/* ---------------------------------------------------------------------- */
1308ab2a 19556+
4a4d8108
AM
19557+/*
19558+ * functions for reverting.
19559+ * when an error happened in a single rename systemcall, we should revert
19560+ * everything as if nothing happend.
19561+ * we don't need to revert the copied-up/down the parent dir since they are
19562+ * harmless.
19563+ */
1facf9fc 19564+
4a4d8108
AM
19565+#define RevertFailure(fmt, ...) do { \
19566+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
19567+ ##__VA_ARGS__, err, rerr); \
19568+ err = -EIO; \
19569+} while (0)
1facf9fc 19570+
4a4d8108 19571+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 19572+{
4a4d8108 19573+ int rerr;
1facf9fc 19574+
4a4d8108
AM
19575+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
19576+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
19577+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 19578+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108 19579+ if (rerr)
523b37e3 19580+ RevertFailure("remove diropq %pd", a->src_dentry);
4a4d8108 19581+}
1facf9fc 19582+
4a4d8108
AM
19583+static void au_ren_rev_rename(int err, struct au_ren_args *a)
19584+{
19585+ int rerr;
523b37e3 19586+ struct inode *delegated;
1facf9fc 19587+
b4510431
AM
19588+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
19589+ a->src_h_parent);
4a4d8108
AM
19590+ rerr = PTR_ERR(a->h_path.dentry);
19591+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 19592+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 19593+ return;
1facf9fc 19594+ }
19595+
523b37e3 19596+ delegated = NULL;
4a4d8108
AM
19597+ rerr = vfsub_rename(a->dst_h_dir,
19598+ au_h_dptr(a->src_dentry, a->btgt),
523b37e3
AM
19599+ a->src_h_dir, &a->h_path, &delegated);
19600+ if (unlikely(rerr == -EWOULDBLOCK)) {
19601+ pr_warn("cannot retry for NFSv4 delegation"
19602+ " for an internal rename\n");
19603+ iput(delegated);
19604+ }
4a4d8108
AM
19605+ d_drop(a->h_path.dentry);
19606+ dput(a->h_path.dentry);
19607+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
19608+ if (rerr)
523b37e3 19609+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 19610+}
19611+
4a4d8108 19612+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
1facf9fc 19613+{
4a4d8108 19614+ int rerr;
1facf9fc 19615+
4a4d8108 19616+ a->h_path.dentry = a->dst_h_dentry;
523b37e3
AM
19617+ /* no delegation since it is just created */
19618+ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*delegated*/NULL,
19619+ /*force*/0);
4a4d8108
AM
19620+ au_set_h_dptr(a->src_dentry, a->btgt, NULL);
19621+ au_set_dbstart(a->src_dentry, a->src_bstart);
19622+ if (rerr)
523b37e3 19623+ RevertFailure("unlink %pd", a->dst_h_dentry);
1facf9fc 19624+}
19625+
4a4d8108 19626+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 19627+{
4a4d8108 19628+ int rerr;
523b37e3 19629+ struct inode *delegated;
dece6358 19630+
b4510431
AM
19631+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
19632+ a->dst_h_parent);
4a4d8108
AM
19633+ rerr = PTR_ERR(a->h_path.dentry);
19634+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 19635+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
19636+ return;
19637+ }
19638+ if (a->h_path.dentry->d_inode) {
19639+ d_drop(a->h_path.dentry);
19640+ dput(a->h_path.dentry);
19641+ return;
dece6358
AM
19642+ }
19643+
523b37e3
AM
19644+ delegated = NULL;
19645+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
19646+ &delegated);
19647+ if (unlikely(rerr == -EWOULDBLOCK)) {
19648+ pr_warn("cannot retry for NFSv4 delegation"
19649+ " for an internal rename\n");
19650+ iput(delegated);
19651+ }
4a4d8108
AM
19652+ d_drop(a->h_path.dentry);
19653+ dput(a->h_path.dentry);
19654+ if (!rerr)
19655+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
19656+ else
523b37e3 19657+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 19658+}
1308ab2a 19659+
4a4d8108
AM
19660+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
19661+{
19662+ int rerr;
1308ab2a 19663+
4a4d8108
AM
19664+ a->h_path.dentry = a->src_wh_dentry;
19665+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 19666+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 19667+ if (rerr)
523b37e3 19668+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 19669+}
4a4d8108 19670+#undef RevertFailure
1facf9fc 19671+
1308ab2a 19672+/* ---------------------------------------------------------------------- */
19673+
4a4d8108
AM
19674+/*
19675+ * when we have to copyup the renaming entry, do it with the rename-target name
19676+ * in order to minimize the cost (the later actual rename is unnecessary).
19677+ * otherwise rename it on the target branch.
19678+ */
19679+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 19680+{
dece6358 19681+ int err;
4a4d8108 19682+ struct dentry *d;
523b37e3 19683+ struct inode *delegated;
1facf9fc 19684+
4a4d8108
AM
19685+ d = a->src_dentry;
19686+ if (au_dbstart(d) == a->btgt) {
19687+ a->h_path.dentry = a->dst_h_dentry;
19688+ if (au_ftest_ren(a->flags, DIROPQ)
19689+ && au_dbdiropq(d) == a->btgt)
19690+ au_fclr_ren(a->flags, DIROPQ);
19691+ AuDebugOn(au_dbstart(d) != a->btgt);
523b37e3 19692+ delegated = NULL;
4a4d8108 19693+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
523b37e3
AM
19694+ a->dst_h_dir, &a->h_path, &delegated);
19695+ if (unlikely(err == -EWOULDBLOCK)) {
19696+ pr_warn("cannot retry for NFSv4 delegation"
19697+ " for an internal rename\n");
19698+ iput(delegated);
19699+ }
c2b27bf2 19700+ } else
86dc4139 19701+ BUG();
1308ab2a 19702+
027c5e7a
AM
19703+ if (!err && a->h_dst)
19704+ /* it will be set to dinfo later */
19705+ dget(a->h_dst);
1facf9fc 19706+
dece6358
AM
19707+ return err;
19708+}
1facf9fc 19709+
4a4d8108
AM
19710+/* cf. aufs_rmdir() */
19711+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 19712+{
4a4d8108
AM
19713+ int err;
19714+ struct inode *dir;
1facf9fc 19715+
4a4d8108
AM
19716+ dir = a->dst_dir;
19717+ SiMustAnyLock(dir->i_sb);
19718+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
19719+ au_sbi(dir->i_sb)->si_dirwh)
19720+ || au_test_fs_remote(a->h_dst->d_sb)) {
19721+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
19722+ if (unlikely(err))
523b37e3
AM
19723+ pr_warn("failed removing whtmp dir %pd (%d), "
19724+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
19725+ } else {
19726+ au_nhash_wh_free(&a->thargs->whlist);
19727+ a->thargs->whlist = a->whlist;
19728+ a->whlist.nh_num = 0;
19729+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
19730+ dput(a->h_dst);
19731+ a->thargs = NULL;
19732+ }
19733+
19734+ return 0;
1308ab2a 19735+}
1facf9fc 19736+
4a4d8108
AM
19737+/* make it 'opaque' dir. */
19738+static int au_ren_diropq(struct au_ren_args *a)
19739+{
19740+ int err;
19741+ struct dentry *diropq;
1facf9fc 19742+
4a4d8108 19743+ err = 0;
027c5e7a 19744+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
19745+ a->src_hinode = au_hi(a->src_inode, a->btgt);
19746+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
19747+ diropq = au_diropq_create(a->src_dentry, a->btgt);
19748+ au_hn_imtx_unlock(a->src_hinode);
19749+ if (IS_ERR(diropq))
19750+ err = PTR_ERR(diropq);
076b876e
AM
19751+ else
19752+ dput(diropq);
1facf9fc 19753+
4a4d8108
AM
19754+ return err;
19755+}
1facf9fc 19756+
4a4d8108
AM
19757+static int do_rename(struct au_ren_args *a)
19758+{
19759+ int err;
19760+ struct dentry *d, *h_d;
1facf9fc 19761+
4a4d8108
AM
19762+ /* prepare workqueue args for asynchronous rmdir */
19763+ h_d = a->dst_h_dentry;
19764+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
19765+ err = -ENOMEM;
19766+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
19767+ if (unlikely(!a->thargs))
19768+ goto out;
19769+ a->h_dst = dget(h_d);
19770+ }
1facf9fc 19771+
4a4d8108
AM
19772+ /* create whiteout for src_dentry */
19773+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
19774+ a->src_bwh = au_dbwh(a->src_dentry);
19775+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
19776+ a->src_wh_dentry
19777+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
19778+ err = PTR_ERR(a->src_wh_dentry);
19779+ if (IS_ERR(a->src_wh_dentry))
19780+ goto out_thargs;
19781+ }
1facf9fc 19782+
4a4d8108
AM
19783+ /* lookup whiteout for dentry */
19784+ if (au_ftest_ren(a->flags, WHDST)) {
19785+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
19786+ a->br);
19787+ err = PTR_ERR(h_d);
19788+ if (IS_ERR(h_d))
19789+ goto out_whsrc;
19790+ if (!h_d->d_inode)
19791+ dput(h_d);
19792+ else
19793+ a->dst_wh_dentry = h_d;
19794+ }
1facf9fc 19795+
4a4d8108
AM
19796+ /* rename dentry to tmpwh */
19797+ if (a->thargs) {
19798+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
19799+ if (unlikely(err))
19800+ goto out_whdst;
dece6358 19801+
4a4d8108
AM
19802+ d = a->dst_dentry;
19803+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 19804+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
19805+ if (unlikely(err))
19806+ goto out_whtmp;
19807+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
19808+ }
1facf9fc 19809+
c2b27bf2 19810+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
1facf9fc 19811+
4a4d8108
AM
19812+ /* rename by vfs_rename or cpup */
19813+ d = a->dst_dentry;
19814+ if (au_ftest_ren(a->flags, ISDIR)
19815+ && (a->dst_wh_dentry
19816+ || au_dbdiropq(d) == a->btgt
19817+ /* hide the lower to keep xino */
19818+ || a->btgt < au_dbend(d)
19819+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
19820+ au_fset_ren(a->flags, DIROPQ);
19821+ err = au_ren_or_cpup(a);
19822+ if (unlikely(err))
19823+ /* leave the copied-up one */
19824+ goto out_whtmp;
1308ab2a 19825+
4a4d8108
AM
19826+ /* make dir opaque */
19827+ if (au_ftest_ren(a->flags, DIROPQ)) {
19828+ err = au_ren_diropq(a);
19829+ if (unlikely(err))
19830+ goto out_rename;
19831+ }
1308ab2a 19832+
4a4d8108
AM
19833+ /* update target timestamps */
19834+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
19835+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
19836+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
19837+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
1facf9fc 19838+
4a4d8108
AM
19839+ /* remove whiteout for dentry */
19840+ if (a->dst_wh_dentry) {
19841+ a->h_path.dentry = a->dst_wh_dentry;
19842+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
19843+ a->dst_dentry);
19844+ if (unlikely(err))
19845+ goto out_diropq;
19846+ }
1facf9fc 19847+
4a4d8108
AM
19848+ /* remove whtmp */
19849+ if (a->thargs)
19850+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 19851+
076b876e 19852+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
4a4d8108
AM
19853+ err = 0;
19854+ goto out_success;
19855+
4f0767ce 19856+out_diropq:
4a4d8108
AM
19857+ if (au_ftest_ren(a->flags, DIROPQ))
19858+ au_ren_rev_diropq(err, a);
4f0767ce 19859+out_rename:
4a4d8108
AM
19860+ if (!au_ftest_ren(a->flags, CPUP))
19861+ au_ren_rev_rename(err, a);
19862+ else
19863+ au_ren_rev_cpup(err, a);
027c5e7a 19864+ dput(a->h_dst);
4f0767ce 19865+out_whtmp:
4a4d8108
AM
19866+ if (a->thargs)
19867+ au_ren_rev_whtmp(err, a);
4f0767ce 19868+out_whdst:
4a4d8108
AM
19869+ dput(a->dst_wh_dentry);
19870+ a->dst_wh_dentry = NULL;
4f0767ce 19871+out_whsrc:
4a4d8108
AM
19872+ if (a->src_wh_dentry)
19873+ au_ren_rev_whsrc(err, a);
4f0767ce 19874+out_success:
4a4d8108
AM
19875+ dput(a->src_wh_dentry);
19876+ dput(a->dst_wh_dentry);
4f0767ce 19877+out_thargs:
4a4d8108
AM
19878+ if (a->thargs) {
19879+ dput(a->h_dst);
19880+ au_whtmp_rmdir_free(a->thargs);
19881+ a->thargs = NULL;
19882+ }
4f0767ce 19883+out:
4a4d8108 19884+ return err;
dece6358 19885+}
1facf9fc 19886+
1308ab2a 19887+/* ---------------------------------------------------------------------- */
1facf9fc 19888+
4a4d8108
AM
19889+/*
19890+ * test if @dentry dir can be rename destination or not.
19891+ * success means, it is a logically empty dir.
19892+ */
19893+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 19894+{
4a4d8108 19895+ return au_test_empty(dentry, whlist);
1308ab2a 19896+}
1facf9fc 19897+
4a4d8108
AM
19898+/*
19899+ * test if @dentry dir can be rename source or not.
19900+ * if it can, return 0 and @children is filled.
19901+ * success means,
19902+ * - it is a logically empty dir.
19903+ * - or, it exists on writable branch and has no children including whiteouts
19904+ * on the lower branch.
19905+ */
19906+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
19907+{
19908+ int err;
19909+ unsigned int rdhash;
19910+ aufs_bindex_t bstart;
1facf9fc 19911+
4a4d8108
AM
19912+ bstart = au_dbstart(dentry);
19913+ if (bstart != btgt) {
19914+ struct au_nhash whlist;
dece6358 19915+
4a4d8108
AM
19916+ SiMustAnyLock(dentry->d_sb);
19917+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
19918+ if (!rdhash)
19919+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
19920+ dentry));
19921+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
19922+ if (unlikely(err))
19923+ goto out;
19924+ err = au_test_empty(dentry, &whlist);
19925+ au_nhash_wh_free(&whlist);
19926+ goto out;
19927+ }
dece6358 19928+
4a4d8108
AM
19929+ if (bstart == au_dbtaildir(dentry))
19930+ return 0; /* success */
dece6358 19931+
4a4d8108 19932+ err = au_test_empty_lower(dentry);
1facf9fc 19933+
4f0767ce 19934+out:
4a4d8108
AM
19935+ if (err == -ENOTEMPTY) {
19936+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
19937+ " is not supported\n");
19938+ err = -EXDEV;
19939+ }
19940+ return err;
19941+}
1308ab2a 19942+
4a4d8108
AM
19943+/* side effect: sets whlist and h_dentry */
19944+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 19945+{
4a4d8108
AM
19946+ int err;
19947+ unsigned int rdhash;
19948+ struct dentry *d;
1facf9fc 19949+
4a4d8108
AM
19950+ d = a->dst_dentry;
19951+ SiMustAnyLock(d->d_sb);
1facf9fc 19952+
4a4d8108
AM
19953+ err = 0;
19954+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
19955+ rdhash = au_sbi(d->d_sb)->si_rdhash;
19956+ if (!rdhash)
19957+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
19958+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
19959+ if (unlikely(err))
19960+ goto out;
1308ab2a 19961+
4a4d8108
AM
19962+ au_set_dbstart(d, a->dst_bstart);
19963+ err = may_rename_dstdir(d, &a->whlist);
19964+ au_set_dbstart(d, a->btgt);
19965+ }
19966+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
19967+ if (unlikely(err))
19968+ goto out;
19969+
19970+ d = a->src_dentry;
19971+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
19972+ if (au_ftest_ren(a->flags, ISDIR)) {
19973+ err = may_rename_srcdir(d, a->btgt);
19974+ if (unlikely(err)) {
19975+ au_nhash_wh_free(&a->whlist);
19976+ a->whlist.nh_num = 0;
19977+ }
19978+ }
4f0767ce 19979+out:
4a4d8108 19980+ return err;
1facf9fc 19981+}
19982+
4a4d8108 19983+/* ---------------------------------------------------------------------- */
1facf9fc 19984+
4a4d8108
AM
19985+/*
19986+ * simple tests for rename.
19987+ * following the checks in vfs, plus the parent-child relationship.
19988+ */
19989+static int au_may_ren(struct au_ren_args *a)
19990+{
19991+ int err, isdir;
19992+ struct inode *h_inode;
1facf9fc 19993+
4a4d8108
AM
19994+ if (a->src_bstart == a->btgt) {
19995+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
19996+ au_ftest_ren(a->flags, ISDIR));
19997+ if (unlikely(err))
19998+ goto out;
19999+ err = -EINVAL;
20000+ if (unlikely(a->src_h_dentry == a->h_trap))
20001+ goto out;
20002+ }
1facf9fc 20003+
4a4d8108
AM
20004+ err = 0;
20005+ if (a->dst_bstart != a->btgt)
20006+ goto out;
1facf9fc 20007+
027c5e7a
AM
20008+ err = -ENOTEMPTY;
20009+ if (unlikely(a->dst_h_dentry == a->h_trap))
20010+ goto out;
20011+
4a4d8108
AM
20012+ err = -EIO;
20013+ h_inode = a->dst_h_dentry->d_inode;
20014+ isdir = !!au_ftest_ren(a->flags, ISDIR);
20015+ if (!a->dst_dentry->d_inode) {
20016+ if (unlikely(h_inode))
20017+ goto out;
20018+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
20019+ isdir);
20020+ } else {
20021+ if (unlikely(!h_inode || !h_inode->i_nlink))
20022+ goto out;
20023+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
20024+ isdir);
20025+ if (unlikely(err))
20026+ goto out;
4a4d8108 20027+ }
1facf9fc 20028+
4f0767ce 20029+out:
4a4d8108
AM
20030+ if (unlikely(err == -ENOENT || err == -EEXIST))
20031+ err = -EIO;
20032+ AuTraceErr(err);
20033+ return err;
20034+}
1facf9fc 20035+
1308ab2a 20036+/* ---------------------------------------------------------------------- */
1facf9fc 20037+
4a4d8108
AM
20038+/*
20039+ * locking order
20040+ * (VFS)
20041+ * - src_dir and dir by lock_rename()
20042+ * - inode if exitsts
20043+ * (aufs)
20044+ * - lock all
20045+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
20046+ * + si_read_lock
20047+ * + di_write_lock2_child()
20048+ * + di_write_lock_child()
20049+ * + ii_write_lock_child()
20050+ * + di_write_lock_child2()
20051+ * + ii_write_lock_child2()
20052+ * + src_parent and parent
20053+ * + di_write_lock_parent()
20054+ * + ii_write_lock_parent()
20055+ * + di_write_lock_parent2()
20056+ * + ii_write_lock_parent2()
20057+ * + lower src_dir and dir by vfsub_lock_rename()
20058+ * + verify the every relationships between child and parent. if any
20059+ * of them failed, unlock all and return -EBUSY.
20060+ */
20061+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 20062+{
4a4d8108
AM
20063+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
20064+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
20065+ if (au_ftest_ren(a->flags, MNT_WRITE))
20066+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 20067+}
20068+
4a4d8108 20069+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 20070+{
4a4d8108
AM
20071+ int err;
20072+ unsigned int udba;
1308ab2a 20073+
4a4d8108
AM
20074+ err = 0;
20075+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
20076+ a->src_hdir = au_hi(a->src_dir, a->btgt);
20077+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
20078+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
20079+
20080+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
20081+ if (unlikely(err))
20082+ goto out;
20083+ au_fset_ren(a->flags, MNT_WRITE);
4a4d8108
AM
20084+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
20085+ a->dst_h_parent, a->dst_hdir);
20086+ udba = au_opt_udba(a->src_dentry->d_sb);
20087+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
20088+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
20089+ err = au_busy_or_stale();
20090+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
20091+ err = au_h_verify(a->src_h_dentry, udba,
20092+ a->src_h_parent->d_inode, a->src_h_parent,
20093+ a->br);
20094+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
20095+ err = au_h_verify(a->dst_h_dentry, udba,
20096+ a->dst_h_parent->d_inode, a->dst_h_parent,
20097+ a->br);
86dc4139 20098+ if (!err)
4a4d8108 20099+ goto out; /* success */
4a4d8108
AM
20100+
20101+ err = au_busy_or_stale();
4a4d8108 20102+ au_ren_unlock(a);
86dc4139 20103+
4f0767ce 20104+out:
4a4d8108 20105+ return err;
1facf9fc 20106+}
20107+
20108+/* ---------------------------------------------------------------------- */
20109+
4a4d8108 20110+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 20111+{
4a4d8108 20112+ struct inode *dir;
dece6358 20113+
4a4d8108
AM
20114+ dir = a->dst_dir;
20115+ dir->i_version++;
20116+ if (au_ftest_ren(a->flags, ISDIR)) {
20117+ /* is this updating defined in POSIX? */
20118+ au_cpup_attr_timesizes(a->src_inode);
20119+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 20120+ }
027c5e7a 20121+
4a4d8108
AM
20122+ if (au_ibstart(dir) == a->btgt)
20123+ au_cpup_attr_timesizes(dir);
dece6358 20124+
4a4d8108
AM
20125+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20126+ return;
dece6358 20127+
4a4d8108
AM
20128+ dir = a->src_dir;
20129+ dir->i_version++;
20130+ if (au_ftest_ren(a->flags, ISDIR))
20131+ au_cpup_attr_nlink(dir, /*force*/1);
20132+ if (au_ibstart(dir) == a->btgt)
20133+ au_cpup_attr_timesizes(dir);
1facf9fc 20134+}
20135+
4a4d8108 20136+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 20137+{
4a4d8108
AM
20138+ aufs_bindex_t bend, bindex;
20139+ struct dentry *d, *h_d;
20140+ struct inode *i, *h_i;
20141+ struct super_block *sb;
dece6358 20142+
027c5e7a
AM
20143+ d = a->dst_dentry;
20144+ d_drop(d);
20145+ if (a->h_dst)
20146+ /* already dget-ed by au_ren_or_cpup() */
20147+ au_set_h_dptr(d, a->btgt, a->h_dst);
20148+
20149+ i = a->dst_inode;
20150+ if (i) {
20151+ if (!au_ftest_ren(a->flags, ISDIR))
20152+ vfsub_drop_nlink(i);
20153+ else {
20154+ vfsub_dead_dir(i);
20155+ au_cpup_attr_timesizes(i);
20156+ }
20157+ au_update_dbrange(d, /*do_put_zero*/1);
20158+ } else {
20159+ bend = a->btgt;
20160+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
20161+ au_set_h_dptr(d, bindex, NULL);
20162+ bend = au_dbend(d);
20163+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
20164+ au_set_h_dptr(d, bindex, NULL);
20165+ au_update_dbrange(d, /*do_put_zero*/0);
20166+ }
20167+
4a4d8108
AM
20168+ d = a->src_dentry;
20169+ au_set_dbwh(d, -1);
20170+ bend = au_dbend(d);
20171+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20172+ h_d = au_h_dptr(d, bindex);
20173+ if (h_d)
20174+ au_set_h_dptr(d, bindex, NULL);
20175+ }
20176+ au_set_dbend(d, a->btgt);
20177+
20178+ sb = d->d_sb;
20179+ i = a->src_inode;
20180+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
20181+ return; /* success */
20182+
20183+ bend = au_ibend(i);
20184+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20185+ h_i = au_h_iptr(i, bindex);
20186+ if (h_i) {
20187+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
20188+ /* ignore this error */
20189+ au_set_h_iptr(i, bindex, NULL, 0);
20190+ }
20191+ }
20192+ au_set_ibend(i, a->btgt);
1308ab2a 20193+}
dece6358 20194+
4a4d8108
AM
20195+/* ---------------------------------------------------------------------- */
20196+
20197+/* mainly for link(2) and rename(2) */
20198+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 20199+{
4a4d8108
AM
20200+ aufs_bindex_t bdiropq, bwh;
20201+ struct dentry *parent;
20202+ struct au_branch *br;
20203+
20204+ parent = dentry->d_parent;
20205+ IMustLock(parent->d_inode); /* dir is locked */
20206+
20207+ bdiropq = au_dbdiropq(parent);
20208+ bwh = au_dbwh(dentry);
20209+ br = au_sbr(dentry->d_sb, btgt);
20210+ if (au_br_rdonly(br)
20211+ || (0 <= bdiropq && bdiropq < btgt)
20212+ || (0 <= bwh && bwh < btgt))
20213+ btgt = -1;
20214+
20215+ AuDbg("btgt %d\n", btgt);
20216+ return btgt;
1facf9fc 20217+}
20218+
4a4d8108
AM
20219+/* sets src_bstart, dst_bstart and btgt */
20220+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 20221+{
4a4d8108
AM
20222+ int err;
20223+ struct au_wr_dir_args wr_dir_args = {
20224+ /* .force_btgt = -1, */
20225+ .flags = AuWrDir_ADD_ENTRY
20226+ };
dece6358 20227+
4a4d8108
AM
20228+ a->src_bstart = au_dbstart(a->src_dentry);
20229+ a->dst_bstart = au_dbstart(a->dst_dentry);
20230+ if (au_ftest_ren(a->flags, ISDIR))
20231+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
20232+ wr_dir_args.force_btgt = a->src_bstart;
20233+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
20234+ wr_dir_args.force_btgt = a->dst_bstart;
20235+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
20236+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
20237+ a->btgt = err;
dece6358 20238+
4a4d8108 20239+ return err;
1facf9fc 20240+}
20241+
4a4d8108 20242+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 20243+{
4a4d8108
AM
20244+ a->h_path.dentry = a->src_h_parent;
20245+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
20246+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
20247+ a->h_path.dentry = a->dst_h_parent;
20248+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
20249+ }
1facf9fc 20250+
4a4d8108
AM
20251+ au_fclr_ren(a->flags, DT_DSTDIR);
20252+ if (!au_ftest_ren(a->flags, ISDIR))
20253+ return;
dece6358 20254+
4a4d8108
AM
20255+ a->h_path.dentry = a->src_h_dentry;
20256+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
20257+ if (a->dst_h_dentry->d_inode) {
20258+ au_fset_ren(a->flags, DT_DSTDIR);
20259+ a->h_path.dentry = a->dst_h_dentry;
20260+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
20261+ }
1308ab2a 20262+}
dece6358 20263+
4a4d8108 20264+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 20265+{
4a4d8108
AM
20266+ struct dentry *h_d;
20267+ struct mutex *h_mtx;
20268+
20269+ au_dtime_revert(a->src_dt + AuPARENT);
20270+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
20271+ au_dtime_revert(a->dst_dt + AuPARENT);
20272+
20273+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
20274+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
20275+ h_mtx = &h_d->d_inode->i_mutex;
20276+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20277+ au_dtime_revert(a->src_dt + AuCHILD);
20278+ mutex_unlock(h_mtx);
20279+
20280+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
20281+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
20282+ h_mtx = &h_d->d_inode->i_mutex;
20283+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20284+ au_dtime_revert(a->dst_dt + AuCHILD);
20285+ mutex_unlock(h_mtx);
1facf9fc 20286+ }
20287+ }
20288+}
20289+
4a4d8108
AM
20290+/* ---------------------------------------------------------------------- */
20291+
20292+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
20293+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 20294+{
e49829fe 20295+ int err, flags;
4a4d8108
AM
20296+ /* reduce stack space */
20297+ struct au_ren_args *a;
20298+
523b37e3 20299+ AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry);
4a4d8108
AM
20300+ IMustLock(_src_dir);
20301+ IMustLock(_dst_dir);
20302+
20303+ err = -ENOMEM;
20304+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
20305+ a = kzalloc(sizeof(*a), GFP_NOFS);
20306+ if (unlikely(!a))
20307+ goto out;
20308+
20309+ a->src_dir = _src_dir;
20310+ a->src_dentry = _src_dentry;
20311+ a->src_inode = a->src_dentry->d_inode;
20312+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
20313+ a->dst_dir = _dst_dir;
20314+ a->dst_dentry = _dst_dentry;
20315+ a->dst_inode = a->dst_dentry->d_inode;
20316+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
20317+ if (a->dst_inode) {
20318+ IMustLock(a->dst_inode);
20319+ au_igrab(a->dst_inode);
1facf9fc 20320+ }
1facf9fc 20321+
4a4d8108 20322+ err = -ENOTDIR;
027c5e7a 20323+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
4a4d8108
AM
20324+ if (S_ISDIR(a->src_inode->i_mode)) {
20325+ au_fset_ren(a->flags, ISDIR);
20326+ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
20327+ goto out_free;
e49829fe
JR
20328+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20329+ AuLock_DIR | flags);
4a4d8108 20330+ } else
e49829fe
JR
20331+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20332+ flags);
20333+ if (unlikely(err))
20334+ goto out_free;
1facf9fc 20335+
027c5e7a
AM
20336+ err = au_d_hashed_positive(a->src_dentry);
20337+ if (unlikely(err))
20338+ goto out_unlock;
20339+ err = -ENOENT;
20340+ if (a->dst_inode) {
20341+ /*
20342+ * If it is a dir, VFS unhash dst_dentry before this
20343+ * function. It means we cannot rely upon d_unhashed().
20344+ */
20345+ if (unlikely(!a->dst_inode->i_nlink))
20346+ goto out_unlock;
20347+ if (!S_ISDIR(a->dst_inode->i_mode)) {
20348+ err = au_d_hashed_positive(a->dst_dentry);
20349+ if (unlikely(err))
20350+ goto out_unlock;
20351+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
20352+ goto out_unlock;
20353+ } else if (unlikely(d_unhashed(a->dst_dentry)))
20354+ goto out_unlock;
20355+
7eafdf33
AM
20356+ /*
20357+ * is it possible?
20358+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
20359+ * there may exist a problem somewhere else.
20360+ */
20361+ err = -EINVAL;
20362+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
20363+ goto out_unlock;
20364+
4a4d8108
AM
20365+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
20366+ di_write_lock_parent(a->dst_parent);
1facf9fc 20367+
4a4d8108
AM
20368+ /* which branch we process */
20369+ err = au_ren_wbr(a);
20370+ if (unlikely(err < 0))
027c5e7a 20371+ goto out_parent;
4a4d8108 20372+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 20373+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 20374+
4a4d8108
AM
20375+ /* are they available to be renamed */
20376+ err = au_ren_may_dir(a);
20377+ if (unlikely(err))
20378+ goto out_children;
1facf9fc 20379+
4a4d8108
AM
20380+ /* prepare the writable parent dir on the same branch */
20381+ if (a->dst_bstart == a->btgt) {
20382+ au_fset_ren(a->flags, WHDST);
20383+ } else {
20384+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
20385+ if (unlikely(err))
20386+ goto out_children;
20387+ }
1facf9fc 20388+
4a4d8108
AM
20389+ if (a->src_dir != a->dst_dir) {
20390+ /*
20391+ * this temporary unlock is safe,
20392+ * because both dir->i_mutex are locked.
20393+ */
20394+ di_write_unlock(a->dst_parent);
20395+ di_write_lock_parent(a->src_parent);
20396+ err = au_wr_dir_need_wh(a->src_dentry,
20397+ au_ftest_ren(a->flags, ISDIR),
20398+ &a->btgt);
20399+ di_write_unlock(a->src_parent);
20400+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
20401+ au_fclr_ren(a->flags, ISSAMEDIR);
20402+ } else
20403+ err = au_wr_dir_need_wh(a->src_dentry,
20404+ au_ftest_ren(a->flags, ISDIR),
20405+ &a->btgt);
20406+ if (unlikely(err < 0))
20407+ goto out_children;
20408+ if (err)
20409+ au_fset_ren(a->flags, WHSRC);
1facf9fc 20410+
86dc4139
AM
20411+ /* cpup src */
20412+ if (a->src_bstart != a->btgt) {
86dc4139
AM
20413+ struct au_pin pin;
20414+
20415+ err = au_pin(&pin, a->src_dentry, a->btgt,
20416+ au_opt_udba(a->src_dentry->d_sb),
20417+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 20418+ if (!err) {
c2b27bf2
AM
20419+ struct au_cp_generic cpg = {
20420+ .dentry = a->src_dentry,
20421+ .bdst = a->btgt,
20422+ .bsrc = a->src_bstart,
20423+ .len = -1,
20424+ .pin = &pin,
20425+ .flags = AuCpup_DTIME | AuCpup_HOPEN
20426+ };
367653fa 20427+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
c2b27bf2 20428+ err = au_sio_cpup_simple(&cpg);
367653fa 20429+ au_unpin(&pin);
86dc4139 20430+ }
86dc4139
AM
20431+ if (unlikely(err))
20432+ goto out_children;
20433+ a->src_bstart = a->btgt;
20434+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
20435+ au_fset_ren(a->flags, WHSRC);
20436+ }
20437+
4a4d8108
AM
20438+ /* lock them all */
20439+ err = au_ren_lock(a);
20440+ if (unlikely(err))
86dc4139 20441+ /* leave the copied-up one */
4a4d8108 20442+ goto out_children;
1facf9fc 20443+
4a4d8108
AM
20444+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
20445+ err = au_may_ren(a);
20446+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
20447+ err = -ENAMETOOLONG;
20448+ if (unlikely(err))
20449+ goto out_hdir;
1facf9fc 20450+
4a4d8108
AM
20451+ /* store timestamps to be revertible */
20452+ au_ren_dt(a);
1facf9fc 20453+
4a4d8108
AM
20454+ /* here we go */
20455+ err = do_rename(a);
20456+ if (unlikely(err))
20457+ goto out_dt;
20458+
20459+ /* update dir attributes */
20460+ au_ren_refresh_dir(a);
20461+
20462+ /* dput/iput all lower dentries */
20463+ au_ren_refresh(a);
20464+
20465+ goto out_hdir; /* success */
20466+
4f0767ce 20467+out_dt:
4a4d8108 20468+ au_ren_rev_dt(err, a);
4f0767ce 20469+out_hdir:
4a4d8108 20470+ au_ren_unlock(a);
4f0767ce 20471+out_children:
4a4d8108 20472+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
20473+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
20474+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
20475+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
20476+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 20477+ }
027c5e7a 20478+out_parent:
4a4d8108
AM
20479+ if (!err)
20480+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
20481+ else {
20482+ au_update_dbstart(a->dst_dentry);
20483+ if (!a->dst_inode)
20484+ d_drop(a->dst_dentry);
20485+ }
4a4d8108
AM
20486+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20487+ di_write_unlock(a->dst_parent);
20488+ else
20489+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 20490+out_unlock:
4a4d8108 20491+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 20492+out_free:
4a4d8108
AM
20493+ iput(a->dst_inode);
20494+ if (a->thargs)
20495+ au_whtmp_rmdir_free(a->thargs);
20496+ kfree(a);
4f0767ce 20497+out:
4a4d8108
AM
20498+ AuTraceErr(err);
20499+ return err;
1308ab2a 20500+}
7f207e10
AM
20501diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
20502--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
20503+++ linux/fs/aufs/Kconfig 2014-08-14 10:15:45.118609182 +0200
20504@@ -0,0 +1,177 @@
4a4d8108
AM
20505+config AUFS_FS
20506+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
20507+ help
20508+ Aufs is a stackable unification filesystem such as Unionfs,
20509+ which unifies several directories and provides a merged single
20510+ directory.
20511+ In the early days, aufs was entirely re-designed and
20512+ re-implemented Unionfs Version 1.x series. Introducing many
20513+ original ideas, approaches and improvements, it becomes totally
20514+ different from Unionfs while keeping the basic features.
1facf9fc 20515+
4a4d8108
AM
20516+if AUFS_FS
20517+choice
20518+ prompt "Maximum number of branches"
20519+ default AUFS_BRANCH_MAX_127
20520+ help
20521+ Specifies the maximum number of branches (or member directories)
20522+ in a single aufs. The larger value consumes more system
20523+ resources and has a minor impact to performance.
20524+config AUFS_BRANCH_MAX_127
20525+ bool "127"
20526+ help
20527+ Specifies the maximum number of branches (or member directories)
20528+ in a single aufs. The larger value consumes more system
20529+ resources and has a minor impact to performance.
20530+config AUFS_BRANCH_MAX_511
20531+ bool "511"
20532+ help
20533+ Specifies the maximum number of branches (or member directories)
20534+ in a single aufs. The larger value consumes more system
20535+ resources and has a minor impact to performance.
20536+config AUFS_BRANCH_MAX_1023
20537+ bool "1023"
20538+ help
20539+ Specifies the maximum number of branches (or member directories)
20540+ in a single aufs. The larger value consumes more system
20541+ resources and has a minor impact to performance.
20542+config AUFS_BRANCH_MAX_32767
20543+ bool "32767"
20544+ help
20545+ Specifies the maximum number of branches (or member directories)
20546+ in a single aufs. The larger value consumes more system
20547+ resources and has a minor impact to performance.
20548+endchoice
1facf9fc 20549+
e49829fe
JR
20550+config AUFS_SBILIST
20551+ bool
20552+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
20553+ default y
20554+ help
20555+ Automatic configuration for internal use.
20556+ When aufs supports Magic SysRq or /proc, enabled automatically.
20557+
4a4d8108
AM
20558+config AUFS_HNOTIFY
20559+ bool "Detect direct branch access (bypassing aufs)"
20560+ help
20561+ If you want to modify files on branches directly, eg. bypassing aufs,
20562+ and want aufs to detect the changes of them fully, then enable this
20563+ option and use 'udba=notify' mount option.
7f207e10 20564+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
20565+ It will have a negative impact to the performance.
20566+ See detail in aufs.5.
dece6358 20567+
4a4d8108
AM
20568+choice
20569+ prompt "method" if AUFS_HNOTIFY
20570+ default AUFS_HFSNOTIFY
20571+config AUFS_HFSNOTIFY
20572+ bool "fsnotify"
20573+ select FSNOTIFY
4a4d8108 20574+endchoice
1facf9fc 20575+
4a4d8108
AM
20576+config AUFS_EXPORT
20577+ bool "NFS-exportable aufs"
2cbb1c4b 20578+ depends on EXPORTFS
4a4d8108
AM
20579+ help
20580+ If you want to export your mounted aufs via NFS, then enable this
20581+ option. There are several requirements for this configuration.
20582+ See detail in aufs.5.
1facf9fc 20583+
4a4d8108
AM
20584+config AUFS_INO_T_64
20585+ bool
20586+ depends on AUFS_EXPORT
20587+ depends on 64BIT && !(ALPHA || S390)
20588+ default y
20589+ help
20590+ Automatic configuration for internal use.
20591+ /* typedef unsigned long/int __kernel_ino_t */
20592+ /* alpha and s390x are int */
1facf9fc 20593+
076b876e
AM
20594+config AUFS_FHSM
20595+ bool "File-based Hierarchical Storage Management"
20596+ help
20597+ Hierarchical Storage Management (or HSM) is a well-known feature
20598+ in the storage world. Aufs provides this feature as file-based.
20599+ with multiple branches.
20600+ These multiple branches are prioritized, ie. the topmost one
20601+ should be the fastest drive and be used heavily.
20602+
4a4d8108
AM
20603+config AUFS_RDU
20604+ bool "Readdir in userspace"
20605+ help
20606+ Aufs has two methods to provide a merged view for a directory,
20607+ by a user-space library and by kernel-space natively. The latter
20608+ is always enabled but sometimes large and slow.
20609+ If you enable this option, install the library in aufs2-util
20610+ package, and set some environment variables for your readdir(3),
20611+ then the work will be handled in user-space which generally
20612+ shows better performance in most cases.
20613+ See detail in aufs.5.
1facf9fc 20614+
4a4d8108
AM
20615+config AUFS_SHWH
20616+ bool "Show whiteouts"
20617+ help
20618+ If you want to make the whiteouts in aufs visible, then enable
20619+ this option and specify 'shwh' mount option. Although it may
20620+ sounds like philosophy or something, but in technically it
20621+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 20622+
4a4d8108
AM
20623+config AUFS_BR_RAMFS
20624+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
20625+ help
20626+ If you want to use ramfs as an aufs branch fs, then enable this
20627+ option. Generally tmpfs is recommended.
20628+ Aufs prohibited them to be a branch fs by default, because
20629+ initramfs becomes unusable after switch_root or something
20630+ generally. If you sets initramfs as an aufs branch and boot your
20631+ system by switch_root, you will meet a problem easily since the
20632+ files in initramfs may be inaccessible.
20633+ Unless you are going to use ramfs as an aufs branch fs without
20634+ switch_root or something, leave it N.
1facf9fc 20635+
4a4d8108
AM
20636+config AUFS_BR_FUSE
20637+ bool "Fuse fs as an aufs branch"
20638+ depends on FUSE_FS
20639+ select AUFS_POLL
20640+ help
20641+ If you want to use fuse-based userspace filesystem as an aufs
20642+ branch fs, then enable this option.
20643+ It implements the internal poll(2) operation which is
20644+ implemented by fuse only (curretnly).
1facf9fc 20645+
4a4d8108
AM
20646+config AUFS_POLL
20647+ bool
20648+ help
20649+ Automatic configuration for internal use.
1facf9fc 20650+
4a4d8108
AM
20651+config AUFS_BR_HFSPLUS
20652+ bool "Hfsplus as an aufs branch"
20653+ depends on HFSPLUS_FS
20654+ default y
20655+ help
20656+ If you want to use hfsplus fs as an aufs branch fs, then enable
20657+ this option. This option introduces a small overhead at
20658+ copying-up a file on hfsplus.
1facf9fc 20659+
4a4d8108
AM
20660+config AUFS_BDEV_LOOP
20661+ bool
20662+ depends on BLK_DEV_LOOP
20663+ default y
20664+ help
20665+ Automatic configuration for internal use.
20666+ Convert =[ym] into =y.
1308ab2a 20667+
4a4d8108
AM
20668+config AUFS_DEBUG
20669+ bool "Debug aufs"
20670+ help
20671+ Enable this to compile aufs internal debug code.
20672+ It will have a negative impact to the performance.
20673+
20674+config AUFS_MAGIC_SYSRQ
20675+ bool
20676+ depends on AUFS_DEBUG && MAGIC_SYSRQ
20677+ default y
20678+ help
20679+ Automatic configuration for internal use.
20680+ When aufs supports Magic SysRq, enabled automatically.
20681+endif
7f207e10
AM
20682diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
20683--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
076b876e 20684+++ linux/fs/aufs/loop.c 2014-01-30 21:10:02.850815069 +0100
523b37e3 20685@@ -0,0 +1,145 @@
1facf9fc 20686+/*
523b37e3 20687+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 20688+ *
20689+ * This program, aufs is free software; you can redistribute it and/or modify
20690+ * it under the terms of the GNU General Public License as published by
20691+ * the Free Software Foundation; either version 2 of the License, or
20692+ * (at your option) any later version.
dece6358
AM
20693+ *
20694+ * This program is distributed in the hope that it will be useful,
20695+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20696+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20697+ * GNU General Public License for more details.
20698+ *
20699+ * You should have received a copy of the GNU General Public License
523b37e3 20700+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20701+ */
20702+
20703+/*
20704+ * support for loopback block device as a branch
20705+ */
20706+
1facf9fc 20707+#include "aufs.h"
20708+
392086de
AM
20709+/* added into drivers/block/loop.c */
20710+static struct file *(*backing_file_func)(struct super_block *sb);
20711+
1facf9fc 20712+/*
20713+ * test if two lower dentries have overlapping branches.
20714+ */
b752ccd1 20715+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 20716+{
b752ccd1 20717+ struct super_block *h_sb;
392086de
AM
20718+ struct file *backing_file;
20719+
20720+ if (unlikely(!backing_file_func)) {
20721+ /* don't load "loop" module here */
20722+ backing_file_func = symbol_get(loop_backing_file);
20723+ if (unlikely(!backing_file_func))
20724+ /* "loop" module is not loaded */
20725+ return 0;
20726+ }
1facf9fc 20727+
b752ccd1 20728+ h_sb = h_adding->d_sb;
392086de
AM
20729+ backing_file = backing_file_func(h_sb);
20730+ if (!backing_file)
1facf9fc 20731+ return 0;
20732+
392086de 20733+ h_adding = backing_file->f_dentry;
b752ccd1
AM
20734+ /*
20735+ * h_adding can be local NFS.
20736+ * in this case aufs cannot detect the loop.
20737+ */
20738+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 20739+ return 1;
b752ccd1 20740+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 20741+}
20742+
20743+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
20744+int au_test_loopback_kthread(void)
20745+{
b752ccd1
AM
20746+ int ret;
20747+ struct task_struct *tsk = current;
a2a7ad62 20748+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
20749+
20750+ ret = 0;
20751+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
20752+ get_task_comm(comm, tsk);
20753+ c = comm[4];
b752ccd1 20754+ ret = ('0' <= c && c <= '9'
a2a7ad62 20755+ && !strncmp(comm, "loop", 4));
b752ccd1 20756+ }
1facf9fc 20757+
b752ccd1 20758+ return ret;
1facf9fc 20759+}
87a755f4
AM
20760+
20761+/* ---------------------------------------------------------------------- */
20762+
20763+#define au_warn_loopback_step 16
20764+static int au_warn_loopback_nelem = au_warn_loopback_step;
20765+static unsigned long *au_warn_loopback_array;
20766+
20767+void au_warn_loopback(struct super_block *h_sb)
20768+{
20769+ int i, new_nelem;
20770+ unsigned long *a, magic;
20771+ static DEFINE_SPINLOCK(spin);
20772+
20773+ magic = h_sb->s_magic;
20774+ spin_lock(&spin);
20775+ a = au_warn_loopback_array;
20776+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
20777+ if (a[i] == magic) {
20778+ spin_unlock(&spin);
20779+ return;
20780+ }
20781+
20782+ /* h_sb is new to us, print it */
20783+ if (i < au_warn_loopback_nelem) {
20784+ a[i] = magic;
20785+ goto pr;
20786+ }
20787+
20788+ /* expand the array */
20789+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
20790+ a = au_kzrealloc(au_warn_loopback_array,
20791+ au_warn_loopback_nelem * sizeof(unsigned long),
20792+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
20793+ if (a) {
20794+ au_warn_loopback_nelem = new_nelem;
20795+ au_warn_loopback_array = a;
20796+ a[i] = magic;
20797+ goto pr;
20798+ }
20799+
20800+ spin_unlock(&spin);
20801+ AuWarn1("realloc failed, ignored\n");
20802+ return;
20803+
20804+pr:
20805+ spin_unlock(&spin);
0c3ec466
AM
20806+ pr_warn("you may want to try another patch for loopback file "
20807+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
20808+}
20809+
20810+int au_loopback_init(void)
20811+{
20812+ int err;
20813+ struct super_block *sb __maybe_unused;
20814+
20815+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
20816+
20817+ err = 0;
20818+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
20819+ sizeof(unsigned long), GFP_NOFS);
20820+ if (unlikely(!au_warn_loopback_array))
20821+ err = -ENOMEM;
20822+
20823+ return err;
20824+}
20825+
20826+void au_loopback_fin(void)
20827+{
392086de 20828+ symbol_put(loop_backing_file);
87a755f4
AM
20829+ kfree(au_warn_loopback_array);
20830+}
7f207e10
AM
20831diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
20832--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
076b876e 20833+++ linux/fs/aufs/loop.h 2014-01-30 21:10:02.850815069 +0100
523b37e3 20834@@ -0,0 +1,52 @@
1facf9fc 20835+/*
523b37e3 20836+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 20837+ *
20838+ * This program, aufs is free software; you can redistribute it and/or modify
20839+ * it under the terms of the GNU General Public License as published by
20840+ * the Free Software Foundation; either version 2 of the License, or
20841+ * (at your option) any later version.
dece6358
AM
20842+ *
20843+ * This program is distributed in the hope that it will be useful,
20844+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20845+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20846+ * GNU General Public License for more details.
20847+ *
20848+ * You should have received a copy of the GNU General Public License
523b37e3 20849+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 20850+ */
20851+
20852+/*
20853+ * support for loopback mount as a branch
20854+ */
20855+
20856+#ifndef __AUFS_LOOP_H__
20857+#define __AUFS_LOOP_H__
20858+
20859+#ifdef __KERNEL__
20860+
dece6358
AM
20861+struct dentry;
20862+struct super_block;
1facf9fc 20863+
20864+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
20865+/* drivers/block/loop.c */
20866+struct file *loop_backing_file(struct super_block *sb);
20867+
1facf9fc 20868+/* loop.c */
b752ccd1 20869+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 20870+int au_test_loopback_kthread(void);
87a755f4
AM
20871+void au_warn_loopback(struct super_block *h_sb);
20872+
20873+int au_loopback_init(void);
20874+void au_loopback_fin(void);
1facf9fc 20875+#else
4a4d8108 20876+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 20877+ struct dentry *h_adding)
4a4d8108 20878+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
20879+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
20880+
20881+AuStubInt0(au_loopback_init, void)
20882+AuStubVoid(au_loopback_fin, void)
1facf9fc 20883+#endif /* BLK_DEV_LOOP */
20884+
20885+#endif /* __KERNEL__ */
20886+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
20887diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
20888--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
076b876e 20889+++ linux/fs/aufs/magic.mk 2014-01-30 21:10:02.850815069 +0100
4a4d8108 20890@@ -0,0 +1,54 @@
1facf9fc 20891+
20892+# defined in ${srctree}/fs/fuse/inode.c
20893+# tristate
20894+ifdef CONFIG_FUSE_FS
20895+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
20896+endif
20897+
20898+# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
20899+# tristate
20900+ifdef CONFIG_OCFS2_FS
20901+ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
20902+endif
20903+
20904+# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
20905+# tristate
20906+ifdef CONFIG_OCFS2_FS_O2CB
20907+ccflags-y += -DDLMFS_MAGIC=0x76a9f425
20908+endif
20909+
1facf9fc 20910+# defined in ${srctree}/fs/cifs/cifsfs.c
20911+# tristate
20912+ifdef CONFIG_CIFS_FS
20913+ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
20914+endif
20915+
20916+# defined in ${srctree}/fs/xfs/xfs_sb.h
20917+# tristate
20918+ifdef CONFIG_XFS_FS
20919+ccflags-y += -DXFS_SB_MAGIC=0x58465342
20920+endif
20921+
20922+# defined in ${srctree}/fs/configfs/mount.c
20923+# tristate
20924+ifdef CONFIG_CONFIGFS_FS
20925+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
20926+endif
20927+
20928+# defined in ${srctree}/fs/9p/v9fs.h
20929+# tristate
20930+ifdef CONFIG_9P_FS
20931+ccflags-y += -DV9FS_MAGIC=0x01021997
20932+endif
20933+
20934+# defined in ${srctree}/fs/ubifs/ubifs.h
20935+# tristate
20936+ifdef CONFIG_UBIFS_FS
20937+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
20938+endif
4a4d8108
AM
20939+
20940+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
20941+# tristate
20942+ifdef CONFIG_HFSPLUS_FS
20943+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
20944+endif
7f207e10
AM
20945diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
20946--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
20947+++ linux/fs/aufs/Makefile 2014-08-14 10:15:45.118609182 +0200
20948@@ -0,0 +1,42 @@
4a4d8108
AM
20949+
20950+include ${src}/magic.mk
20951+ifeq (${CONFIG_AUFS_FS},m)
20952+include ${src}/conf.mk
20953+endif
20954+-include ${src}/priv_def.mk
20955+
20956+# cf. include/linux/kernel.h
20957+# enable pr_debug
20958+ccflags-y += -DDEBUG
f6c5ef8b
AM
20959+# sparse requires the full pathname
20960+ifdef M
523b37e3 20961+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 20962+else
523b37e3 20963+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 20964+endif
4a4d8108
AM
20965+
20966+obj-$(CONFIG_AUFS_FS) += aufs.o
20967+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
20968+ wkq.o vfsub.o dcsub.o \
e49829fe 20969+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
20970+ dinfo.o dentry.o \
20971+ dynop.o \
20972+ finfo.o file.o f_op.o \
20973+ dir.o vdir.o \
20974+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 20975+ mvdown.o ioctl.o
4a4d8108
AM
20976+
20977+# all are boolean
e49829fe 20978+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
20979+aufs-$(CONFIG_SYSFS) += sysfs.o
20980+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
20981+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
20982+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
20983+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 20984+aufs-$(CONFIG_AUFS_EXPORT) += export.o
076b876e 20985+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
20986+aufs-$(CONFIG_AUFS_POLL) += poll.o
20987+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
20988+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
20989+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
20990+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
20991diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
20992--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
20993+++ linux/fs/aufs/module.c 2014-08-14 10:15:45.128609525 +0200
20994@@ -0,0 +1,210 @@
1facf9fc 20995+/*
523b37e3 20996+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 20997+ *
20998+ * This program, aufs is free software; you can redistribute it and/or modify
20999+ * it under the terms of the GNU General Public License as published by
21000+ * the Free Software Foundation; either version 2 of the License, or
21001+ * (at your option) any later version.
dece6358
AM
21002+ *
21003+ * This program is distributed in the hope that it will be useful,
21004+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21005+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21006+ * GNU General Public License for more details.
21007+ *
21008+ * You should have received a copy of the GNU General Public License
523b37e3 21009+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21010+ */
21011+
21012+/*
21013+ * module global variables and operations
21014+ */
21015+
21016+#include <linux/module.h>
21017+#include <linux/seq_file.h>
21018+#include "aufs.h"
21019+
21020+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
21021+{
21022+ if (new_sz <= nused)
21023+ return p;
21024+
21025+ p = krealloc(p, new_sz, gfp);
21026+ if (p)
21027+ memset(p + nused, 0, new_sz - nused);
21028+ return p;
21029+}
21030+
21031+/* ---------------------------------------------------------------------- */
21032+
21033+/*
21034+ * aufs caches
21035+ */
21036+struct kmem_cache *au_cachep[AuCache_Last];
21037+static int __init au_cache_init(void)
21038+{
4a4d8108 21039+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 21040+ if (au_cachep[AuCache_DINFO])
027c5e7a 21041+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
21042+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
21043+ au_icntnr_init_once);
1facf9fc 21044+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
21045+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
21046+ au_fi_init_once);
1facf9fc 21047+ if (au_cachep[AuCache_FINFO])
21048+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
21049+ if (au_cachep[AuCache_VDIR])
21050+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
21051+ if (au_cachep[AuCache_DEHSTR])
21052+ return 0;
21053+
21054+ return -ENOMEM;
21055+}
21056+
21057+static void au_cache_fin(void)
21058+{
21059+ int i;
4a4d8108 21060+
537831f9
AM
21061+ /*
21062+ * Make sure all delayed rcu free inodes are flushed before we
21063+ * destroy cache.
21064+ */
21065+ rcu_barrier();
21066+
7eafdf33
AM
21067+ /* excluding AuCache_HNOTIFY */
21068+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
21069+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 21070+ if (au_cachep[i]) {
21071+ kmem_cache_destroy(au_cachep[i]);
21072+ au_cachep[i] = NULL;
21073+ }
21074+}
21075+
21076+/* ---------------------------------------------------------------------- */
21077+
21078+int au_dir_roflags;
21079+
e49829fe 21080+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
21081+/*
21082+ * iterate_supers_type() doesn't protect us from
21083+ * remounting (branch management)
21084+ */
e49829fe
JR
21085+struct au_splhead au_sbilist;
21086+#endif
21087+
9dbd164d
AM
21088+struct lock_class_key au_lc_key[AuLcKey_Last];
21089+
1facf9fc 21090+/*
21091+ * functions for module interface.
21092+ */
21093+MODULE_LICENSE("GPL");
21094+/* MODULE_LICENSE("GPL v2"); */
dece6358 21095+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 21096+MODULE_DESCRIPTION(AUFS_NAME
21097+ " -- Advanced multi layered unification filesystem");
21098+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 21099+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 21100+
1facf9fc 21101+/* this module parameter has no meaning when SYSFS is disabled */
21102+int sysaufs_brs = 1;
21103+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
21104+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
21105+
076b876e
AM
21106+/* this module parameter has no meaning when USER_NS is disabled */
21107+static bool au_userns;
21108+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
21109+module_param_named(allow_userns, au_userns, bool, S_IRUGO);
21110+
1facf9fc 21111+/* ---------------------------------------------------------------------- */
21112+
21113+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
21114+
21115+int au_seq_path(struct seq_file *seq, struct path *path)
21116+{
21117+ return seq_path(seq, path, au_esc_chars);
21118+}
21119+
21120+/* ---------------------------------------------------------------------- */
21121+
21122+static int __init aufs_init(void)
21123+{
21124+ int err, i;
21125+ char *p;
21126+
21127+ p = au_esc_chars;
21128+ for (i = 1; i <= ' '; i++)
21129+ *p++ = i;
21130+ *p++ = '\\';
21131+ *p++ = '\x7f';
21132+ *p = 0;
21133+
21134+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
21135+
e49829fe 21136+ au_sbilist_init();
1facf9fc 21137+ sysaufs_brs_init();
21138+ au_debug_init();
4a4d8108 21139+ au_dy_init();
1facf9fc 21140+ err = sysaufs_init();
21141+ if (unlikely(err))
21142+ goto out;
e49829fe 21143+ err = au_procfs_init();
4f0767ce 21144+ if (unlikely(err))
953406b4 21145+ goto out_sysaufs;
e49829fe
JR
21146+ err = au_wkq_init();
21147+ if (unlikely(err))
21148+ goto out_procfs;
87a755f4 21149+ err = au_loopback_init();
1facf9fc 21150+ if (unlikely(err))
21151+ goto out_wkq;
87a755f4
AM
21152+ err = au_hnotify_init();
21153+ if (unlikely(err))
21154+ goto out_loopback;
1facf9fc 21155+ err = au_sysrq_init();
21156+ if (unlikely(err))
21157+ goto out_hin;
21158+ err = au_cache_init();
21159+ if (unlikely(err))
21160+ goto out_sysrq;
076b876e
AM
21161+
21162+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 21163+ err = register_filesystem(&aufs_fs_type);
21164+ if (unlikely(err))
21165+ goto out_cache;
076b876e 21166+
4a4d8108
AM
21167+ /* since we define pr_fmt, call printk directly */
21168+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 21169+ goto out; /* success */
21170+
4f0767ce 21171+out_cache:
1facf9fc 21172+ au_cache_fin();
4f0767ce 21173+out_sysrq:
1facf9fc 21174+ au_sysrq_fin();
4f0767ce 21175+out_hin:
4a4d8108 21176+ au_hnotify_fin();
87a755f4
AM
21177+out_loopback:
21178+ au_loopback_fin();
4f0767ce 21179+out_wkq:
1facf9fc 21180+ au_wkq_fin();
e49829fe
JR
21181+out_procfs:
21182+ au_procfs_fin();
4f0767ce 21183+out_sysaufs:
1facf9fc 21184+ sysaufs_fin();
4a4d8108 21185+ au_dy_fin();
4f0767ce 21186+out:
1facf9fc 21187+ return err;
21188+}
21189+
21190+static void __exit aufs_exit(void)
21191+{
21192+ unregister_filesystem(&aufs_fs_type);
21193+ au_cache_fin();
21194+ au_sysrq_fin();
4a4d8108 21195+ au_hnotify_fin();
87a755f4 21196+ au_loopback_fin();
1facf9fc 21197+ au_wkq_fin();
e49829fe 21198+ au_procfs_fin();
1facf9fc 21199+ sysaufs_fin();
4a4d8108 21200+ au_dy_fin();
1facf9fc 21201+}
21202+
21203+module_init(aufs_init);
21204+module_exit(aufs_exit);
7f207e10
AM
21205diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
21206--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
076b876e 21207+++ linux/fs/aufs/module.h 2014-01-30 21:10:02.850815069 +0100
523b37e3 21208@@ -0,0 +1,104 @@
1facf9fc 21209+/*
523b37e3 21210+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 21211+ *
21212+ * This program, aufs is free software; you can redistribute it and/or modify
21213+ * it under the terms of the GNU General Public License as published by
21214+ * the Free Software Foundation; either version 2 of the License, or
21215+ * (at your option) any later version.
dece6358
AM
21216+ *
21217+ * This program is distributed in the hope that it will be useful,
21218+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21219+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21220+ * GNU General Public License for more details.
21221+ *
21222+ * You should have received a copy of the GNU General Public License
523b37e3 21223+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21224+ */
21225+
21226+/*
21227+ * module initialization and module-global
21228+ */
21229+
21230+#ifndef __AUFS_MODULE_H__
21231+#define __AUFS_MODULE_H__
21232+
21233+#ifdef __KERNEL__
21234+
21235+#include <linux/slab.h>
21236+
dece6358
AM
21237+struct path;
21238+struct seq_file;
21239+
1facf9fc 21240+/* module parameters */
1facf9fc 21241+extern int sysaufs_brs;
21242+
21243+/* ---------------------------------------------------------------------- */
21244+
21245+extern int au_dir_roflags;
21246+
9dbd164d
AM
21247+enum {
21248+ AuLcNonDir_FIINFO,
21249+ AuLcNonDir_DIINFO,
21250+ AuLcNonDir_IIINFO,
21251+
21252+ AuLcDir_FIINFO,
21253+ AuLcDir_DIINFO,
21254+ AuLcDir_IIINFO,
21255+
21256+ AuLcSymlink_DIINFO,
21257+ AuLcSymlink_IIINFO,
21258+
21259+ AuLcKey_Last
21260+};
21261+extern struct lock_class_key au_lc_key[AuLcKey_Last];
21262+
1facf9fc 21263+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
21264+int au_seq_path(struct seq_file *seq, struct path *path);
21265+
e49829fe
JR
21266+#ifdef CONFIG_PROC_FS
21267+/* procfs.c */
21268+int __init au_procfs_init(void);
21269+void au_procfs_fin(void);
21270+#else
21271+AuStubInt0(au_procfs_init, void);
21272+AuStubVoid(au_procfs_fin, void);
21273+#endif
21274+
4f0767ce
JR
21275+/* ---------------------------------------------------------------------- */
21276+
21277+/* kmem cache */
1facf9fc 21278+enum {
21279+ AuCache_DINFO,
21280+ AuCache_ICNTNR,
21281+ AuCache_FINFO,
21282+ AuCache_VDIR,
21283+ AuCache_DEHSTR,
7eafdf33 21284+ AuCache_HNOTIFY, /* must be last */
1facf9fc 21285+ AuCache_Last
21286+};
21287+
4a4d8108
AM
21288+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
21289+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
21290+#define AuCacheCtor(type, ctor) \
21291+ kmem_cache_create(#type, sizeof(struct type), \
21292+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 21293+
21294+extern struct kmem_cache *au_cachep[];
21295+
21296+#define AuCacheFuncs(name, index) \
4a4d8108 21297+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 21298+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 21299+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 21300+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
21301+
21302+AuCacheFuncs(dinfo, DINFO);
21303+AuCacheFuncs(icntnr, ICNTNR);
21304+AuCacheFuncs(finfo, FINFO);
21305+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
21306+AuCacheFuncs(vdir_dehstr, DEHSTR);
21307+#ifdef CONFIG_AUFS_HNOTIFY
21308+AuCacheFuncs(hnotify, HNOTIFY);
21309+#endif
1facf9fc 21310+
4a4d8108
AM
21311+#endif /* __KERNEL__ */
21312+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
21313diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
21314--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
21315+++ linux/fs/aufs/mvdown.c 2014-08-14 10:15:45.128609525 +0200
21316@@ -0,0 +1,657 @@
c2b27bf2 21317+/*
523b37e3 21318+ * Copyright (C) 2011-2014 Junjiro R. Okajima
c2b27bf2
AM
21319+ *
21320+ * This program, aufs is free software; you can redistribute it and/or modify
21321+ * it under the terms of the GNU General Public License as published by
21322+ * the Free Software Foundation; either version 2 of the License, or
21323+ * (at your option) any later version.
21324+ *
21325+ * This program is distributed in the hope that it will be useful,
21326+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21327+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21328+ * GNU General Public License for more details.
21329+ *
21330+ * You should have received a copy of the GNU General Public License
523b37e3
AM
21331+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21332+ */
21333+
21334+/*
21335+ * move-down, opposite of copy-up
c2b27bf2
AM
21336+ */
21337+
21338+#include "aufs.h"
21339+
c2b27bf2
AM
21340+struct au_mvd_args {
21341+ struct {
c2b27bf2
AM
21342+ struct super_block *h_sb;
21343+ struct dentry *h_parent;
21344+ struct au_hinode *hdir;
392086de 21345+ struct inode *h_dir, *h_inode;
c2b27bf2
AM
21346+ } info[AUFS_MVDOWN_NARRAY];
21347+
21348+ struct aufs_mvdown mvdown;
21349+ struct dentry *dentry, *parent;
21350+ struct inode *inode, *dir;
21351+ struct super_block *sb;
21352+ aufs_bindex_t bopq, bwh, bfound;
21353+ unsigned char rename_lock;
21354+ struct au_pin pin;
21355+};
21356+
392086de 21357+#define mvd_errno mvdown.au_errno
076b876e
AM
21358+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
21359+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
21360+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
21361+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 21362+
392086de
AM
21363+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
21364+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
21365+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
21366+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
21367+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
21368+
21369+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
21370+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
21371+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
21372+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
21373+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c2b27bf2
AM
21374+
21375+#define AU_MVD_PR(flag, ...) do { \
21376+ if (flag) \
21377+ pr_err(__VA_ARGS__); \
21378+ } while (0)
21379+
076b876e
AM
21380+static int find_lower_writable(struct au_mvd_args *a)
21381+{
21382+ struct super_block *sb;
21383+ aufs_bindex_t bindex, bend;
21384+ struct au_branch *br;
21385+
21386+ sb = a->sb;
21387+ bindex = a->mvd_bsrc;
21388+ bend = au_sbend(sb);
21389+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
21390+ for (bindex++; bindex <= bend; bindex++) {
21391+ br = au_sbr(sb, bindex);
21392+ if (au_br_fhsm(br->br_perm)
21393+ && (!(au_br_sb(br)->s_flags & MS_RDONLY)))
21394+ return bindex;
21395+ }
21396+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
21397+ for (bindex++; bindex <= bend; bindex++) {
21398+ br = au_sbr(sb, bindex);
21399+ if (!au_br_rdonly(br))
21400+ return bindex;
21401+ }
21402+ else
21403+ for (bindex++; bindex <= bend; bindex++) {
21404+ br = au_sbr(sb, bindex);
21405+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
21406+ if (au_br_rdonly(br))
21407+ a->mvdown.flags
21408+ |= AUFS_MVDOWN_ROLOWER_R;
21409+ return bindex;
21410+ }
21411+ }
21412+
21413+ return -1;
21414+}
21415+
c2b27bf2 21416+/* make the parent dir on bdst */
392086de 21417+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21418+{
21419+ int err;
21420+
21421+ err = 0;
21422+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
21423+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
21424+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
21425+ a->mvd_h_dst_parent = NULL;
21426+ if (au_dbend(a->parent) >= a->mvd_bdst)
21427+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
21428+ if (!a->mvd_h_dst_parent) {
21429+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
21430+ if (unlikely(err)) {
392086de 21431+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
21432+ goto out;
21433+ }
21434+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
21435+ }
21436+
21437+out:
21438+ AuTraceErr(err);
21439+ return err;
21440+}
21441+
21442+/* lock them all */
392086de 21443+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21444+{
21445+ int err;
21446+ struct dentry *h_trap;
21447+
21448+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
21449+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
21450+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
21451+ a->rename_lock = 0;
392086de
AM
21452+ err = au_pin(&a->pin, a->dentry, a->mvd_bdst,
21453+ au_opt_udba(a->sb),
c2b27bf2
AM
21454+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21455+ if (!err) {
21456+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
21457+ mutex_lock_nested(&a->mvd_h_src_dir->i_mutex,
21458+ AuLsc_I_PARENT3);
21459+ } else
392086de 21460+ AU_MVD_PR(dmsg, "pin failed\n");
c2b27bf2
AM
21461+ goto out;
21462+ }
21463+
21464+ err = 0;
21465+ a->rename_lock = 1;
21466+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21467+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
21468+ if (h_trap) {
21469+ err = (h_trap != a->mvd_h_src_parent);
21470+ if (err)
21471+ err = (h_trap != a->mvd_h_dst_parent);
21472+ }
21473+ BUG_ON(err); /* it should never happen */
21474+
21475+out:
21476+ AuTraceErr(err);
21477+ return err;
21478+}
21479+
392086de 21480+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21481+{
21482+ if (!a->rename_lock) {
21483+ mutex_unlock(&a->mvd_h_src_dir->i_mutex);
21484+ au_unpin(&a->pin);
21485+ } else
21486+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21487+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
21488+}
21489+
21490+/* copy-down the file */
392086de 21491+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21492+{
21493+ int err;
21494+ struct au_cp_generic cpg = {
21495+ .dentry = a->dentry,
21496+ .bdst = a->mvd_bdst,
21497+ .bsrc = a->mvd_bsrc,
21498+ .len = -1,
21499+ .pin = &a->pin,
21500+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21501+ };
21502+
21503+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
21504+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
21505+ au_fset_cpup(cpg.flags, OVERWRITE);
21506+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
21507+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
21508+ err = au_sio_cpdown_simple(&cpg);
21509+ if (unlikely(err))
392086de 21510+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
21511+
21512+ AuTraceErr(err);
21513+ return err;
21514+}
21515+
21516+/*
21517+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
21518+ * were sleeping
21519+ */
392086de 21520+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21521+{
21522+ int err;
21523+ struct path h_path;
21524+ struct au_branch *br;
523b37e3 21525+ struct inode *delegated;
c2b27bf2
AM
21526+
21527+ br = au_sbr(a->sb, a->mvd_bdst);
21528+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
21529+ err = PTR_ERR(h_path.dentry);
21530+ if (IS_ERR(h_path.dentry)) {
392086de 21531+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
21532+ goto out;
21533+ }
21534+
21535+ err = 0;
21536+ if (h_path.dentry->d_inode) {
21537+ h_path.mnt = au_br_mnt(br);
523b37e3 21538+ delegated = NULL;
c2b27bf2 21539+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
523b37e3
AM
21540+ &delegated, /*force*/0);
21541+ if (unlikely(err == -EWOULDBLOCK)) {
21542+ pr_warn("cannot retry for NFSv4 delegation"
21543+ " for an internal unlink\n");
21544+ iput(delegated);
21545+ }
c2b27bf2 21546+ if (unlikely(err))
392086de 21547+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
21548+ }
21549+ dput(h_path.dentry);
21550+
21551+out:
21552+ AuTraceErr(err);
21553+ return err;
21554+}
21555+
21556+/*
21557+ * unlink the topmost h_dentry
21558+ * Note: the target file MAY be modified by UDBA between this mutex_unlock() and
21559+ * mutex_lock() in vfs_unlink(). in this case, such changes may be lost.
21560+ */
392086de 21561+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21562+{
21563+ int err;
21564+ struct path h_path;
523b37e3 21565+ struct inode *delegated;
c2b27bf2
AM
21566+
21567+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
21568+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
21569+ delegated = NULL;
21570+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
21571+ if (unlikely(err == -EWOULDBLOCK)) {
21572+ pr_warn("cannot retry for NFSv4 delegation"
21573+ " for an internal unlink\n");
21574+ iput(delegated);
21575+ }
c2b27bf2 21576+ if (unlikely(err))
392086de 21577+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
21578+
21579+ AuTraceErr(err);
21580+ return err;
21581+}
21582+
076b876e
AM
21583+/* Since mvdown succeeded, we ignore an error of this function */
21584+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
21585+{
21586+ int err;
21587+ struct au_branch *br;
21588+
21589+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
21590+ br = au_sbr(a->sb, a->mvd_bsrc);
21591+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
21592+ if (!err) {
21593+ br = au_sbr(a->sb, a->mvd_bdst);
21594+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
21595+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
21596+ }
21597+ if (!err)
21598+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
21599+ else
21600+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
21601+}
21602+
c2b27bf2
AM
21603+/*
21604+ * copy-down the file and unlink the bsrc file.
21605+ * - unlink the bdst whout if exist
21606+ * - copy-down the file (with whtmp name and rename)
21607+ * - unlink the bsrc file
21608+ */
392086de 21609+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21610+{
21611+ int err;
21612+
392086de 21613+ err = au_do_mkdir(dmsg, a);
c2b27bf2 21614+ if (!err)
392086de 21615+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
21616+ if (unlikely(err))
21617+ goto out;
21618+
21619+ /*
21620+ * do not revert the activities we made on bdst since they should be
21621+ * harmless in aufs.
21622+ */
21623+
392086de 21624+ err = au_do_cpdown(dmsg, a);
c2b27bf2 21625+ if (!err)
392086de
AM
21626+ err = au_do_unlink_wh(dmsg, a);
21627+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
21628+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
21629+ if (unlikely(err))
21630+ goto out_unlock;
21631+
076b876e
AM
21632+ if (find_lower_writable(a) < 0)
21633+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
21634+
21635+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
21636+ au_do_stfs(dmsg, a);
21637+
c2b27bf2 21638+ /* maintain internal array */
392086de
AM
21639+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
21640+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
21641+ au_set_dbstart(a->dentry, a->mvd_bdst);
21642+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
21643+ au_set_ibstart(a->inode, a->mvd_bdst);
21644+ }
c2b27bf2
AM
21645+ if (au_dbend(a->dentry) < a->mvd_bdst)
21646+ au_set_dbend(a->dentry, a->mvd_bdst);
c2b27bf2
AM
21647+ if (au_ibend(a->inode) < a->mvd_bdst)
21648+ au_set_ibend(a->inode, a->mvd_bdst);
21649+
21650+out_unlock:
392086de 21651+ au_do_unlock(dmsg, a);
c2b27bf2
AM
21652+out:
21653+ AuTraceErr(err);
21654+ return err;
21655+}
21656+
21657+/* ---------------------------------------------------------------------- */
21658+
c2b27bf2 21659+/* make sure the file is idle */
392086de 21660+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21661+{
21662+ int err, plinked;
c2b27bf2
AM
21663+
21664+ err = 0;
c2b27bf2
AM
21665+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
21666+ if (au_dbstart(a->dentry) == a->mvd_bsrc
392086de 21667+ && d_count(a->dentry) == 1
c2b27bf2 21668+ && atomic_read(&a->inode->i_count) == 1
392086de 21669+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
21670+ && (!plinked || !au_plink_test(a->inode))
21671+ && a->inode->i_nlink == 1)
21672+ goto out;
21673+
21674+ err = -EBUSY;
392086de 21675+ AU_MVD_PR(dmsg,
c2b27bf2 21676+ "b%d, d{b%d, c%u?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
392086de 21677+ a->mvd_bsrc, au_dbstart(a->dentry), d_count(a->dentry),
c2b27bf2 21678+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 21679+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
21680+ plinked, plinked ? au_plink_test(a->inode) : 0);
21681+
21682+out:
21683+ AuTraceErr(err);
21684+ return err;
21685+}
21686+
21687+/* make sure the parent dir is fine */
392086de 21688+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
21689+ struct au_mvd_args *a)
21690+{
21691+ int err;
21692+ aufs_bindex_t bindex;
21693+
21694+ err = 0;
21695+ if (unlikely(au_alive_dir(a->parent))) {
21696+ err = -ENOENT;
392086de 21697+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
21698+ goto out;
21699+ }
21700+
21701+ a->bopq = au_dbdiropq(a->parent);
21702+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
21703+ AuDbg("b%d\n", bindex);
21704+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
21705+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
21706+ err = -EINVAL;
392086de
AM
21707+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
21708+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
21709+ a->bopq, a->mvd_bdst);
21710+ }
21711+
21712+out:
21713+ AuTraceErr(err);
21714+ return err;
21715+}
21716+
392086de 21717+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
21718+ struct au_mvd_args *a)
21719+{
21720+ int err;
21721+ struct au_dinfo *dinfo, *tmp;
21722+
21723+ /* lookup the next lower positive entry */
21724+ err = -ENOMEM;
21725+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
21726+ if (unlikely(!tmp))
21727+ goto out;
21728+
21729+ a->bfound = -1;
21730+ a->bwh = -1;
21731+ dinfo = au_di(a->dentry);
21732+ au_di_cp(tmp, dinfo);
21733+ au_di_swap(tmp, dinfo);
21734+
21735+ /* returns the number of positive dentries */
21736+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
21737+ if (!err)
21738+ a->bwh = au_dbwh(a->dentry);
21739+ else if (err > 0)
21740+ a->bfound = au_dbstart(a->dentry);
21741+
21742+ au_di_swap(tmp, dinfo);
21743+ au_rw_write_unlock(&tmp->di_rwsem);
21744+ au_di_free(tmp);
21745+ if (unlikely(err < 0))
392086de 21746+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
21747+
21748+ /*
21749+ * here, we have these cases.
21750+ * bfound == -1
21751+ * no positive dentry under bsrc. there are more sub-cases.
21752+ * bwh < 0
21753+ * there no whiteout, we can safely move-down.
21754+ * bwh <= bsrc
21755+ * impossible
21756+ * bsrc < bwh && bwh < bdst
21757+ * there is a whiteout on RO branch. cannot proceed.
21758+ * bwh == bdst
21759+ * there is a whiteout on the RW target branch. it should
21760+ * be removed.
21761+ * bdst < bwh
21762+ * there is a whiteout somewhere unrelated branch.
21763+ * -1 < bfound && bfound <= bsrc
21764+ * impossible.
21765+ * bfound < bdst
21766+ * found, but it is on RO branch between bsrc and bdst. cannot
21767+ * proceed.
21768+ * bfound == bdst
21769+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
21770+ * error.
21771+ * bdst < bfound
21772+ * found, after we create the file on bdst, it will be hidden.
21773+ */
21774+
21775+ AuDebugOn(a->bfound == -1
21776+ && a->bwh != -1
21777+ && a->bwh <= a->mvd_bsrc);
21778+ AuDebugOn(-1 < a->bfound
21779+ && a->bfound <= a->mvd_bsrc);
21780+
21781+ err = -EINVAL;
21782+ if (a->bfound == -1
21783+ && a->mvd_bsrc < a->bwh
21784+ && a->bwh != -1
21785+ && a->bwh < a->mvd_bdst) {
392086de
AM
21786+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
21787+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
21788+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
21789+ goto out;
21790+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
21791+ a->mvd_errno = EAU_MVDOWN_UPPER;
21792+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
21793+ a->mvd_bdst, a->bfound);
21794+ goto out;
21795+ }
21796+
21797+ err = 0; /* success */
21798+
21799+out:
21800+ AuTraceErr(err);
21801+ return err;
21802+}
21803+
392086de 21804+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21805+{
21806+ int err;
21807+
392086de
AM
21808+ err = 0;
21809+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
21810+ && a->bfound == a->mvd_bdst)
21811+ err = -EEXIST;
c2b27bf2
AM
21812+ AuTraceErr(err);
21813+ return err;
21814+}
21815+
392086de 21816+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21817+{
21818+ int err;
21819+ struct au_branch *br;
21820+
21821+ err = -EISDIR;
21822+ if (unlikely(S_ISDIR(a->inode->i_mode)))
21823+ goto out;
21824+
21825+ err = -EINVAL;
392086de
AM
21826+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
21827+ a->mvd_bsrc = au_ibstart(a->inode);
21828+ else {
21829+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
21830+ if (unlikely(a->mvd_bsrc < 0
21831+ || (a->mvd_bsrc < au_dbstart(a->dentry)
21832+ || au_dbend(a->dentry) < a->mvd_bsrc
21833+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
21834+ || (a->mvd_bsrc < au_ibstart(a->inode)
21835+ || au_ibend(a->inode) < a->mvd_bsrc
21836+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
21837+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
21838+ AU_MVD_PR(dmsg, "no upper\n");
21839+ goto out;
21840+ }
21841+ }
c2b27bf2 21842+ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
392086de
AM
21843+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
21844+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
21845+ goto out;
21846+ }
392086de 21847+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
21848+ br = au_sbr(a->sb, a->mvd_bsrc);
21849+ err = au_br_rdonly(br);
392086de
AM
21850+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
21851+ if (unlikely(err))
21852+ goto out;
21853+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
21854+ || IS_APPEND(a->mvd_h_src_inode))) {
21855+ if (err)
21856+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
21857+ /* go on */
21858+ } else
c2b27bf2
AM
21859+ goto out;
21860+
21861+ err = -EINVAL;
392086de
AM
21862+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
21863+ a->mvd_bdst = find_lower_writable(a);
21864+ if (unlikely(a->mvd_bdst < 0)) {
21865+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
21866+ AU_MVD_PR(dmsg, "no writable lower branch\n");
21867+ goto out;
21868+ }
21869+ } else {
21870+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
21871+ if (unlikely(a->mvd_bdst < 0
21872+ || au_sbend(a->sb) < a->mvd_bdst)) {
21873+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
21874+ AU_MVD_PR(dmsg, "no lower brid\n");
21875+ goto out;
21876+ }
c2b27bf2
AM
21877+ }
21878+
392086de 21879+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 21880+ if (!err)
392086de 21881+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 21882+ if (!err)
392086de 21883+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 21884+ if (!err)
392086de 21885+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
21886+ if (!err)
21887+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
21888+
21889+out:
21890+ AuTraceErr(err);
21891+ return err;
21892+}
21893+
21894+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
21895+{
392086de
AM
21896+ int err, e;
21897+ unsigned char dmsg;
21898+ struct au_mvd_args *args;
c2b27bf2
AM
21899+
21900+ err = -EPERM;
21901+ if (unlikely(!capable(CAP_SYS_ADMIN)))
21902+ goto out;
21903+
392086de
AM
21904+ err = -ENOMEM;
21905+ args = kmalloc(sizeof(*args), GFP_NOFS);
21906+ if (unlikely(!args))
21907+ goto out;
21908+
21909+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
21910+ if (!err)
21911+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
21912+ if (unlikely(err)) {
21913+ err = -EFAULT;
392086de
AM
21914+ AuTraceErr(err);
21915+ goto out_free;
c2b27bf2 21916+ }
392086de
AM
21917+ AuDbg("flags 0x%x\n", args->mvdown.flags);
21918+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
21919+ args->mvdown.au_errno = 0;
21920+ args->dentry = dentry;
21921+ args->inode = dentry->d_inode;
21922+ args->sb = dentry->d_sb;
c2b27bf2 21923+
392086de
AM
21924+ err = -ENOENT;
21925+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
21926+ args->parent = dget_parent(dentry);
21927+ args->dir = args->parent->d_inode;
21928+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
21929+ dput(args->parent);
21930+ if (unlikely(args->parent != dentry->d_parent)) {
21931+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
21932+ goto out_dir;
21933+ }
21934+
392086de 21935+ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
c2b27bf2
AM
21936+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
21937+ if (unlikely(err))
21938+ goto out_inode;
21939+
392086de
AM
21940+ di_write_lock_parent(args->parent);
21941+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
21942+ if (unlikely(err))
21943+ goto out_parent;
21944+
21945+ AuDbgDentry(dentry);
392086de
AM
21946+ AuDbgInode(args->inode);
21947+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
21948+ if (unlikely(err))
21949+ goto out_parent;
21950+ AuDbgDentry(dentry);
392086de 21951+ AuDbgInode(args->inode);
c2b27bf2 21952+
392086de
AM
21953+ au_cpup_attr_timesizes(args->dir);
21954+ au_cpup_attr_timesizes(args->inode);
21955+ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
c2b27bf2
AM
21956+ /* au_digen_dec(dentry); */
21957+
21958+out_parent:
392086de 21959+ di_write_unlock(args->parent);
c2b27bf2
AM
21960+ aufs_read_unlock(dentry, AuLock_DW);
21961+out_inode:
392086de 21962+ mutex_unlock(&args->inode->i_mutex);
c2b27bf2 21963+out_dir:
392086de
AM
21964+ mutex_unlock(&args->dir->i_mutex);
21965+out_free:
21966+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
21967+ if (unlikely(e))
21968+ err = -EFAULT;
21969+ kfree(args);
c2b27bf2
AM
21970+out:
21971+ AuTraceErr(err);
21972+ return err;
21973+}
21974diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
21975--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
21976+++ linux/fs/aufs/opts.c 2014-08-14 10:15:45.128609525 +0200
21977@@ -0,0 +1,1790 @@
1facf9fc 21978+/*
523b37e3 21979+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 21980+ *
21981+ * This program, aufs is free software; you can redistribute it and/or modify
21982+ * it under the terms of the GNU General Public License as published by
21983+ * the Free Software Foundation; either version 2 of the License, or
21984+ * (at your option) any later version.
dece6358
AM
21985+ *
21986+ * This program is distributed in the hope that it will be useful,
21987+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21988+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21989+ * GNU General Public License for more details.
21990+ *
21991+ * You should have received a copy of the GNU General Public License
523b37e3 21992+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21993+ */
21994+
21995+/*
21996+ * mount options/flags
21997+ */
21998+
dece6358 21999+#include <linux/namei.h>
1facf9fc 22000+#include <linux/types.h> /* a distribution requires */
22001+#include <linux/parser.h>
22002+#include "aufs.h"
22003+
22004+/* ---------------------------------------------------------------------- */
22005+
22006+enum {
22007+ Opt_br,
22008+ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
22009+ Opt_idel, Opt_imod, Opt_ireorder,
22010+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
dece6358 22011+ Opt_rdblk_def, Opt_rdhash_def,
1facf9fc 22012+ Opt_xino, Opt_zxino, Opt_noxino,
22013+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
22014+ Opt_trunc_xino_path, Opt_itrunc_xino,
22015+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 22016+ Opt_shwh, Opt_noshwh,
1facf9fc 22017+ Opt_plink, Opt_noplink, Opt_list_plink,
22018+ Opt_udba,
4a4d8108 22019+ Opt_dio, Opt_nodio,
1facf9fc 22020+ /* Opt_lock, Opt_unlock, */
22021+ Opt_cmd, Opt_cmd_args,
22022+ Opt_diropq_a, Opt_diropq_w,
22023+ Opt_warn_perm, Opt_nowarn_perm,
22024+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 22025+ Opt_fhsm_sec,
1facf9fc 22026+ Opt_refrof, Opt_norefrof,
22027+ Opt_verbose, Opt_noverbose,
22028+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 22029+ Opt_dirperm1, Opt_nodirperm1,
1facf9fc 22030+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
22031+};
22032+
22033+static match_table_t options = {
22034+ {Opt_br, "br=%s"},
22035+ {Opt_br, "br:%s"},
22036+
22037+ {Opt_add, "add=%d:%s"},
22038+ {Opt_add, "add:%d:%s"},
22039+ {Opt_add, "ins=%d:%s"},
22040+ {Opt_add, "ins:%d:%s"},
22041+ {Opt_append, "append=%s"},
22042+ {Opt_append, "append:%s"},
22043+ {Opt_prepend, "prepend=%s"},
22044+ {Opt_prepend, "prepend:%s"},
22045+
22046+ {Opt_del, "del=%s"},
22047+ {Opt_del, "del:%s"},
22048+ /* {Opt_idel, "idel:%d"}, */
22049+ {Opt_mod, "mod=%s"},
22050+ {Opt_mod, "mod:%s"},
22051+ /* {Opt_imod, "imod:%d:%s"}, */
22052+
22053+ {Opt_dirwh, "dirwh=%d"},
22054+
22055+ {Opt_xino, "xino=%s"},
22056+ {Opt_noxino, "noxino"},
22057+ {Opt_trunc_xino, "trunc_xino"},
22058+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
22059+ {Opt_notrunc_xino, "notrunc_xino"},
22060+ {Opt_trunc_xino_path, "trunc_xino=%s"},
22061+ {Opt_itrunc_xino, "itrunc_xino=%d"},
22062+ /* {Opt_zxino, "zxino=%s"}, */
22063+ {Opt_trunc_xib, "trunc_xib"},
22064+ {Opt_notrunc_xib, "notrunc_xib"},
22065+
e49829fe 22066+#ifdef CONFIG_PROC_FS
1facf9fc 22067+ {Opt_plink, "plink"},
e49829fe
JR
22068+#else
22069+ {Opt_ignore_silent, "plink"},
22070+#endif
22071+
1facf9fc 22072+ {Opt_noplink, "noplink"},
e49829fe 22073+
1facf9fc 22074+#ifdef CONFIG_AUFS_DEBUG
22075+ {Opt_list_plink, "list_plink"},
22076+#endif
22077+
22078+ {Opt_udba, "udba=%s"},
22079+
4a4d8108
AM
22080+ {Opt_dio, "dio"},
22081+ {Opt_nodio, "nodio"},
22082+
076b876e
AM
22083+#ifdef CONFIG_AUFS_FHSM
22084+ {Opt_fhsm_sec, "fhsm_sec=%d"},
22085+#else
22086+ {Opt_ignore_silent, "fhsm_sec=%d"},
22087+#endif
22088+
1facf9fc 22089+ {Opt_diropq_a, "diropq=always"},
22090+ {Opt_diropq_a, "diropq=a"},
22091+ {Opt_diropq_w, "diropq=whiteouted"},
22092+ {Opt_diropq_w, "diropq=w"},
22093+
22094+ {Opt_warn_perm, "warn_perm"},
22095+ {Opt_nowarn_perm, "nowarn_perm"},
22096+
22097+ /* keep them temporary */
1facf9fc 22098+ {Opt_ignore_silent, "nodlgt"},
1facf9fc 22099+ {Opt_ignore_silent, "clean_plink"},
22100+
dece6358
AM
22101+#ifdef CONFIG_AUFS_SHWH
22102+ {Opt_shwh, "shwh"},
22103+#endif
22104+ {Opt_noshwh, "noshwh"},
22105+
076b876e
AM
22106+ {Opt_dirperm1, "dirperm1"},
22107+ {Opt_nodirperm1, "nodirperm1"},
22108+
1facf9fc 22109+ {Opt_rendir, "rendir=%d"},
22110+
22111+ {Opt_refrof, "refrof"},
22112+ {Opt_norefrof, "norefrof"},
22113+
22114+ {Opt_verbose, "verbose"},
22115+ {Opt_verbose, "v"},
22116+ {Opt_noverbose, "noverbose"},
22117+ {Opt_noverbose, "quiet"},
22118+ {Opt_noverbose, "q"},
22119+ {Opt_noverbose, "silent"},
22120+
22121+ {Opt_sum, "sum"},
22122+ {Opt_nosum, "nosum"},
22123+ {Opt_wsum, "wsum"},
22124+
22125+ {Opt_rdcache, "rdcache=%d"},
22126+ {Opt_rdblk, "rdblk=%d"},
dece6358 22127+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 22128+ {Opt_rdhash, "rdhash=%d"},
dece6358 22129+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 22130+
22131+ {Opt_wbr_create, "create=%s"},
22132+ {Opt_wbr_create, "create_policy=%s"},
22133+ {Opt_wbr_copyup, "cpup=%s"},
22134+ {Opt_wbr_copyup, "copyup=%s"},
22135+ {Opt_wbr_copyup, "copyup_policy=%s"},
22136+
22137+ /* internal use for the scripts */
22138+ {Opt_ignore_silent, "si=%s"},
22139+
22140+ {Opt_br, "dirs=%s"},
22141+ {Opt_ignore, "debug=%d"},
22142+ {Opt_ignore, "delete=whiteout"},
22143+ {Opt_ignore, "delete=all"},
22144+ {Opt_ignore, "imap=%s"},
22145+
1308ab2a 22146+ /* temporary workaround, due to old mount(8)? */
22147+ {Opt_ignore_silent, "relatime"},
22148+
1facf9fc 22149+ {Opt_err, NULL}
22150+};
22151+
22152+/* ---------------------------------------------------------------------- */
22153+
076b876e 22154+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 22155+{
076b876e
AM
22156+ struct match_token *p;
22157+
22158+ p = tbl;
22159+ while (p->pattern) {
22160+ if (p->token == val)
22161+ return p->pattern;
22162+ p++;
1facf9fc 22163+ }
22164+ BUG();
22165+ return "??";
22166+}
22167+
076b876e
AM
22168+static const char *au_optstr(int *val, match_table_t tbl)
22169+{
22170+ struct match_token *p;
22171+ int v;
22172+
22173+ v = *val;
22174+ p = tbl;
22175+ while (p->token) {
22176+ if ((v & p->token) == p->token) {
22177+ *val &= ~p->token;
22178+ return p->pattern;
22179+ }
22180+ p++;
22181+ }
22182+ return NULL;
22183+}
22184+
1facf9fc 22185+/* ---------------------------------------------------------------------- */
22186+
1e00d052 22187+static match_table_t brperm = {
1facf9fc 22188+ {AuBrPerm_RO, AUFS_BRPERM_RO},
22189+ {AuBrPerm_RR, AUFS_BRPERM_RR},
22190+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
22191+ {0, NULL}
22192+};
1facf9fc 22193+
86dc4139 22194+static match_table_t brattr = {
076b876e
AM
22195+ /* general */
22196+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
22197+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
86dc4139 22198+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
076b876e
AM
22199+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
22200+
22201+ /* ro/rr branch */
1e00d052 22202+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
22203+
22204+ /* rw branch */
22205+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 22206+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 22207+
1e00d052 22208+ {0, NULL}
1facf9fc 22209+};
22210+
1e00d052
AM
22211+static int br_attr_val(char *str, match_table_t table, substring_t args[])
22212+{
22213+ int attr, v;
22214+ char *p;
22215+
22216+ attr = 0;
22217+ do {
22218+ p = strchr(str, '+');
22219+ if (p)
22220+ *p = 0;
22221+ v = match_token(str, table, args);
076b876e
AM
22222+ if (v) {
22223+ if (v & AuBrAttr_CMOO_Mask)
22224+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 22225+ attr |= v;
076b876e 22226+ } else {
1e00d052
AM
22227+ if (p)
22228+ *p = '+';
0c3ec466 22229+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
22230+ break;
22231+ }
22232+ if (p)
22233+ str = p + 1;
22234+ } while (p);
22235+
22236+ return attr;
22237+}
22238+
076b876e
AM
22239+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
22240+{
22241+ int sz;
22242+ const char *p;
22243+ char *q;
22244+
22245+ sz = 0;
22246+ q = str->a;
22247+ *q = 0;
22248+ p = au_optstr(&perm, brattr);
22249+ if (p) {
22250+ sz = strlen(p);
22251+ memcpy(q, p, sz + 1);
22252+ q += sz;
22253+ } else
22254+ goto out;
22255+
22256+ do {
22257+ p = au_optstr(&perm, brattr);
22258+ if (p) {
22259+ *q++ = '+';
22260+ sz = strlen(p);
22261+ memcpy(q, p, sz + 1);
22262+ q += sz;
22263+ }
22264+ } while (p);
22265+
22266+out:
22267+ return sz;
22268+}
22269+
4a4d8108 22270+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 22271+{
076b876e
AM
22272+ int val, bad, sz;
22273+ char *p;
1facf9fc 22274+ substring_t args[MAX_OPT_ARGS];
076b876e 22275+ au_br_perm_str_t attr;
1facf9fc 22276+
1e00d052
AM
22277+ p = strchr(perm, '+');
22278+ if (p)
22279+ *p = 0;
22280+ val = match_token(perm, brperm, args);
22281+ if (!val) {
22282+ if (p)
22283+ *p = '+';
0c3ec466 22284+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
22285+ val = AuBrPerm_RO;
22286+ goto out;
22287+ }
22288+ if (!p)
22289+ goto out;
22290+
076b876e
AM
22291+ val |= br_attr_val(p + 1, brattr, args);
22292+
22293+ bad = 0;
86dc4139 22294+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
22295+ case AuBrPerm_RO:
22296+ case AuBrPerm_RR:
076b876e
AM
22297+ bad = val & AuBrWAttr_Mask;
22298+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
22299+ break;
22300+ case AuBrPerm_RW:
076b876e
AM
22301+ bad = val & AuBrRAttr_Mask;
22302+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
22303+ break;
22304+ }
076b876e
AM
22305+ if (unlikely(bad)) {
22306+ sz = au_do_optstr_br_attr(&attr, bad);
22307+ AuDebugOn(!sz);
22308+ pr_warn("ignored branch attribute %s\n", attr.a);
22309+ }
1e00d052
AM
22310+
22311+out:
1facf9fc 22312+ return val;
22313+}
22314+
076b876e 22315+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 22316+{
076b876e
AM
22317+ au_br_perm_str_t attr;
22318+ const char *p;
22319+ char *q;
1e00d052
AM
22320+ int sz;
22321+
076b876e
AM
22322+ q = str->a;
22323+ p = au_optstr(&perm, brperm);
22324+ AuDebugOn(!p || !*p);
22325+ sz = strlen(p);
22326+ memcpy(q, p, sz + 1);
22327+ q += sz;
1e00d052 22328+
076b876e
AM
22329+ sz = au_do_optstr_br_attr(&attr, perm);
22330+ if (sz) {
22331+ *q++ = '+';
22332+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
22333+ }
22334+
076b876e 22335+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 22336+}
22337+
22338+/* ---------------------------------------------------------------------- */
22339+
22340+static match_table_t udbalevel = {
22341+ {AuOpt_UDBA_REVAL, "reval"},
22342+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
22343+#ifdef CONFIG_AUFS_HNOTIFY
22344+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
22345+#ifdef CONFIG_AUFS_HFSNOTIFY
22346+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 22347+#endif
1facf9fc 22348+#endif
22349+ {-1, NULL}
22350+};
22351+
4a4d8108 22352+static int noinline_for_stack udba_val(char *str)
1facf9fc 22353+{
22354+ substring_t args[MAX_OPT_ARGS];
22355+
7f207e10 22356+ return match_token(str, udbalevel, args);
1facf9fc 22357+}
22358+
22359+const char *au_optstr_udba(int udba)
22360+{
076b876e 22361+ return au_parser_pattern(udba, udbalevel);
1facf9fc 22362+}
22363+
22364+/* ---------------------------------------------------------------------- */
22365+
22366+static match_table_t au_wbr_create_policy = {
22367+ {AuWbrCreate_TDP, "tdp"},
22368+ {AuWbrCreate_TDP, "top-down-parent"},
22369+ {AuWbrCreate_RR, "rr"},
22370+ {AuWbrCreate_RR, "round-robin"},
22371+ {AuWbrCreate_MFS, "mfs"},
22372+ {AuWbrCreate_MFS, "most-free-space"},
22373+ {AuWbrCreate_MFSV, "mfs:%d"},
22374+ {AuWbrCreate_MFSV, "most-free-space:%d"},
22375+
22376+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
22377+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
22378+ {AuWbrCreate_PMFS, "pmfs"},
22379+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
22380+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
22381+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 22382+
22383+ {-1, NULL}
22384+};
22385+
dece6358
AM
22386+/*
22387+ * cf. linux/lib/parser.c and cmdline.c
22388+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 22389+ * kstrto...().
dece6358 22390+ */
4a4d8108
AM
22391+static int noinline_for_stack
22392+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 22393+{
22394+ int err;
22395+ unsigned int len;
22396+ char a[32];
22397+
22398+ err = -ERANGE;
22399+ len = s->to - s->from;
22400+ if (len + 1 <= sizeof(a)) {
22401+ memcpy(a, s->from, len);
22402+ a[len] = '\0';
9dbd164d 22403+ err = kstrtoull(a, 0, result);
1facf9fc 22404+ }
22405+ return err;
22406+}
22407+
22408+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
22409+ struct au_opt_wbr_create *create)
22410+{
22411+ int err;
22412+ unsigned long long ull;
22413+
22414+ err = 0;
22415+ if (!au_match_ull(arg, &ull))
22416+ create->mfsrr_watermark = ull;
22417+ else {
4a4d8108 22418+ pr_err("bad integer in %s\n", str);
1facf9fc 22419+ err = -EINVAL;
22420+ }
22421+
22422+ return err;
22423+}
22424+
22425+static int au_wbr_mfs_sec(substring_t *arg, char *str,
22426+ struct au_opt_wbr_create *create)
22427+{
22428+ int n, err;
22429+
22430+ err = 0;
027c5e7a 22431+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 22432+ create->mfs_second = n;
22433+ else {
4a4d8108 22434+ pr_err("bad integer in %s\n", str);
1facf9fc 22435+ err = -EINVAL;
22436+ }
22437+
22438+ return err;
22439+}
22440+
4a4d8108
AM
22441+static int noinline_for_stack
22442+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 22443+{
22444+ int err, e;
22445+ substring_t args[MAX_OPT_ARGS];
22446+
22447+ err = match_token(str, au_wbr_create_policy, args);
22448+ create->wbr_create = err;
22449+ switch (err) {
22450+ case AuWbrCreate_MFSRRV:
392086de 22451+ case AuWbrCreate_PMFSRRV:
1facf9fc 22452+ e = au_wbr_mfs_wmark(&args[0], str, create);
22453+ if (!e)
22454+ e = au_wbr_mfs_sec(&args[1], str, create);
22455+ if (unlikely(e))
22456+ err = e;
22457+ break;
22458+ case AuWbrCreate_MFSRR:
392086de 22459+ case AuWbrCreate_PMFSRR:
1facf9fc 22460+ e = au_wbr_mfs_wmark(&args[0], str, create);
22461+ if (unlikely(e)) {
22462+ err = e;
22463+ break;
22464+ }
22465+ /*FALLTHROUGH*/
22466+ case AuWbrCreate_MFS:
22467+ case AuWbrCreate_PMFS:
027c5e7a 22468+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 22469+ break;
22470+ case AuWbrCreate_MFSV:
22471+ case AuWbrCreate_PMFSV:
22472+ e = au_wbr_mfs_sec(&args[0], str, create);
22473+ if (unlikely(e))
22474+ err = e;
22475+ break;
22476+ }
22477+
22478+ return err;
22479+}
22480+
22481+const char *au_optstr_wbr_create(int wbr_create)
22482+{
076b876e 22483+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 22484+}
22485+
22486+static match_table_t au_wbr_copyup_policy = {
22487+ {AuWbrCopyup_TDP, "tdp"},
22488+ {AuWbrCopyup_TDP, "top-down-parent"},
22489+ {AuWbrCopyup_BUP, "bup"},
22490+ {AuWbrCopyup_BUP, "bottom-up-parent"},
22491+ {AuWbrCopyup_BU, "bu"},
22492+ {AuWbrCopyup_BU, "bottom-up"},
22493+ {-1, NULL}
22494+};
22495+
4a4d8108 22496+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 22497+{
22498+ substring_t args[MAX_OPT_ARGS];
22499+
22500+ return match_token(str, au_wbr_copyup_policy, args);
22501+}
22502+
22503+const char *au_optstr_wbr_copyup(int wbr_copyup)
22504+{
076b876e 22505+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 22506+}
22507+
22508+/* ---------------------------------------------------------------------- */
22509+
22510+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
22511+
22512+static void dump_opts(struct au_opts *opts)
22513+{
22514+#ifdef CONFIG_AUFS_DEBUG
22515+ /* reduce stack space */
22516+ union {
22517+ struct au_opt_add *add;
22518+ struct au_opt_del *del;
22519+ struct au_opt_mod *mod;
22520+ struct au_opt_xino *xino;
22521+ struct au_opt_xino_itrunc *xino_itrunc;
22522+ struct au_opt_wbr_create *create;
22523+ } u;
22524+ struct au_opt *opt;
22525+
22526+ opt = opts->opt;
22527+ while (opt->type != Opt_tail) {
22528+ switch (opt->type) {
22529+ case Opt_add:
22530+ u.add = &opt->add;
22531+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
22532+ u.add->bindex, u.add->pathname, u.add->perm,
22533+ u.add->path.dentry);
22534+ break;
22535+ case Opt_del:
22536+ case Opt_idel:
22537+ u.del = &opt->del;
22538+ AuDbg("del {%s, %p}\n",
22539+ u.del->pathname, u.del->h_path.dentry);
22540+ break;
22541+ case Opt_mod:
22542+ case Opt_imod:
22543+ u.mod = &opt->mod;
22544+ AuDbg("mod {%s, 0x%x, %p}\n",
22545+ u.mod->path, u.mod->perm, u.mod->h_root);
22546+ break;
22547+ case Opt_append:
22548+ u.add = &opt->add;
22549+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
22550+ u.add->bindex, u.add->pathname, u.add->perm,
22551+ u.add->path.dentry);
22552+ break;
22553+ case Opt_prepend:
22554+ u.add = &opt->add;
22555+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
22556+ u.add->bindex, u.add->pathname, u.add->perm,
22557+ u.add->path.dentry);
22558+ break;
22559+ case Opt_dirwh:
22560+ AuDbg("dirwh %d\n", opt->dirwh);
22561+ break;
22562+ case Opt_rdcache:
22563+ AuDbg("rdcache %d\n", opt->rdcache);
22564+ break;
22565+ case Opt_rdblk:
22566+ AuDbg("rdblk %u\n", opt->rdblk);
22567+ break;
dece6358
AM
22568+ case Opt_rdblk_def:
22569+ AuDbg("rdblk_def\n");
22570+ break;
1facf9fc 22571+ case Opt_rdhash:
22572+ AuDbg("rdhash %u\n", opt->rdhash);
22573+ break;
dece6358
AM
22574+ case Opt_rdhash_def:
22575+ AuDbg("rdhash_def\n");
22576+ break;
1facf9fc 22577+ case Opt_xino:
22578+ u.xino = &opt->xino;
523b37e3 22579+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 22580+ break;
22581+ case Opt_trunc_xino:
22582+ AuLabel(trunc_xino);
22583+ break;
22584+ case Opt_notrunc_xino:
22585+ AuLabel(notrunc_xino);
22586+ break;
22587+ case Opt_trunc_xino_path:
22588+ case Opt_itrunc_xino:
22589+ u.xino_itrunc = &opt->xino_itrunc;
22590+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
22591+ break;
22592+
22593+ case Opt_noxino:
22594+ AuLabel(noxino);
22595+ break;
22596+ case Opt_trunc_xib:
22597+ AuLabel(trunc_xib);
22598+ break;
22599+ case Opt_notrunc_xib:
22600+ AuLabel(notrunc_xib);
22601+ break;
dece6358
AM
22602+ case Opt_shwh:
22603+ AuLabel(shwh);
22604+ break;
22605+ case Opt_noshwh:
22606+ AuLabel(noshwh);
22607+ break;
076b876e
AM
22608+ case Opt_dirperm1:
22609+ AuLabel(dirperm1);
22610+ break;
22611+ case Opt_nodirperm1:
22612+ AuLabel(nodirperm1);
22613+ break;
1facf9fc 22614+ case Opt_plink:
22615+ AuLabel(plink);
22616+ break;
22617+ case Opt_noplink:
22618+ AuLabel(noplink);
22619+ break;
22620+ case Opt_list_plink:
22621+ AuLabel(list_plink);
22622+ break;
22623+ case Opt_udba:
22624+ AuDbg("udba %d, %s\n",
22625+ opt->udba, au_optstr_udba(opt->udba));
22626+ break;
4a4d8108
AM
22627+ case Opt_dio:
22628+ AuLabel(dio);
22629+ break;
22630+ case Opt_nodio:
22631+ AuLabel(nodio);
22632+ break;
1facf9fc 22633+ case Opt_diropq_a:
22634+ AuLabel(diropq_a);
22635+ break;
22636+ case Opt_diropq_w:
22637+ AuLabel(diropq_w);
22638+ break;
22639+ case Opt_warn_perm:
22640+ AuLabel(warn_perm);
22641+ break;
22642+ case Opt_nowarn_perm:
22643+ AuLabel(nowarn_perm);
22644+ break;
22645+ case Opt_refrof:
22646+ AuLabel(refrof);
22647+ break;
22648+ case Opt_norefrof:
22649+ AuLabel(norefrof);
22650+ break;
22651+ case Opt_verbose:
22652+ AuLabel(verbose);
22653+ break;
22654+ case Opt_noverbose:
22655+ AuLabel(noverbose);
22656+ break;
22657+ case Opt_sum:
22658+ AuLabel(sum);
22659+ break;
22660+ case Opt_nosum:
22661+ AuLabel(nosum);
22662+ break;
22663+ case Opt_wsum:
22664+ AuLabel(wsum);
22665+ break;
22666+ case Opt_wbr_create:
22667+ u.create = &opt->wbr_create;
22668+ AuDbg("create %d, %s\n", u.create->wbr_create,
22669+ au_optstr_wbr_create(u.create->wbr_create));
22670+ switch (u.create->wbr_create) {
22671+ case AuWbrCreate_MFSV:
22672+ case AuWbrCreate_PMFSV:
22673+ AuDbg("%d sec\n", u.create->mfs_second);
22674+ break;
22675+ case AuWbrCreate_MFSRR:
22676+ AuDbg("%llu watermark\n",
22677+ u.create->mfsrr_watermark);
22678+ break;
22679+ case AuWbrCreate_MFSRRV:
392086de 22680+ case AuWbrCreate_PMFSRRV:
1facf9fc 22681+ AuDbg("%llu watermark, %d sec\n",
22682+ u.create->mfsrr_watermark,
22683+ u.create->mfs_second);
22684+ break;
22685+ }
22686+ break;
22687+ case Opt_wbr_copyup:
22688+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
22689+ au_optstr_wbr_copyup(opt->wbr_copyup));
22690+ break;
076b876e
AM
22691+ case Opt_fhsm_sec:
22692+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
22693+ break;
1facf9fc 22694+ default:
22695+ BUG();
22696+ }
22697+ opt++;
22698+ }
22699+#endif
22700+}
22701+
22702+void au_opts_free(struct au_opts *opts)
22703+{
22704+ struct au_opt *opt;
22705+
22706+ opt = opts->opt;
22707+ while (opt->type != Opt_tail) {
22708+ switch (opt->type) {
22709+ case Opt_add:
22710+ case Opt_append:
22711+ case Opt_prepend:
22712+ path_put(&opt->add.path);
22713+ break;
22714+ case Opt_del:
22715+ case Opt_idel:
22716+ path_put(&opt->del.h_path);
22717+ break;
22718+ case Opt_mod:
22719+ case Opt_imod:
22720+ dput(opt->mod.h_root);
22721+ break;
22722+ case Opt_xino:
22723+ fput(opt->xino.file);
22724+ break;
22725+ }
22726+ opt++;
22727+ }
22728+}
22729+
22730+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
22731+ aufs_bindex_t bindex)
22732+{
22733+ int err;
22734+ struct au_opt_add *add = &opt->add;
22735+ char *p;
22736+
22737+ add->bindex = bindex;
1e00d052 22738+ add->perm = AuBrPerm_RO;
1facf9fc 22739+ add->pathname = opt_str;
22740+ p = strchr(opt_str, '=');
22741+ if (p) {
22742+ *p++ = 0;
22743+ if (*p)
22744+ add->perm = br_perm_val(p);
22745+ }
22746+
22747+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
22748+ if (!err) {
22749+ if (!p) {
22750+ add->perm = AuBrPerm_RO;
22751+ if (au_test_fs_rr(add->path.dentry->d_sb))
22752+ add->perm = AuBrPerm_RR;
22753+ else if (!bindex && !(sb_flags & MS_RDONLY))
22754+ add->perm = AuBrPerm_RW;
22755+ }
22756+ opt->type = Opt_add;
22757+ goto out;
22758+ }
4a4d8108 22759+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 22760+ err = -EINVAL;
22761+
4f0767ce 22762+out:
1facf9fc 22763+ return err;
22764+}
22765+
22766+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
22767+{
22768+ int err;
22769+
22770+ del->pathname = args[0].from;
22771+ AuDbg("del path %s\n", del->pathname);
22772+
22773+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
22774+ if (unlikely(err))
4a4d8108 22775+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 22776+
22777+ return err;
22778+}
22779+
22780+#if 0 /* reserved for future use */
22781+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
22782+ struct au_opt_del *del, substring_t args[])
22783+{
22784+ int err;
22785+ struct dentry *root;
22786+
22787+ err = -EINVAL;
22788+ root = sb->s_root;
22789+ aufs_read_lock(root, AuLock_FLUSH);
22790+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 22791+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 22792+ goto out;
22793+ }
22794+
22795+ err = 0;
22796+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
22797+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
22798+
4f0767ce 22799+out:
1facf9fc 22800+ aufs_read_unlock(root, !AuLock_IR);
22801+ return err;
22802+}
22803+#endif
22804+
4a4d8108
AM
22805+static int noinline_for_stack
22806+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 22807+{
22808+ int err;
22809+ struct path path;
22810+ char *p;
22811+
22812+ err = -EINVAL;
22813+ mod->path = args[0].from;
22814+ p = strchr(mod->path, '=');
22815+ if (unlikely(!p)) {
4a4d8108 22816+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 22817+ goto out;
22818+ }
22819+
22820+ *p++ = 0;
22821+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
22822+ if (unlikely(err)) {
4a4d8108 22823+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 22824+ goto out;
22825+ }
22826+
22827+ mod->perm = br_perm_val(p);
22828+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
22829+ mod->h_root = dget(path.dentry);
22830+ path_put(&path);
22831+
4f0767ce 22832+out:
1facf9fc 22833+ return err;
22834+}
22835+
22836+#if 0 /* reserved for future use */
22837+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
22838+ struct au_opt_mod *mod, substring_t args[])
22839+{
22840+ int err;
22841+ struct dentry *root;
22842+
22843+ err = -EINVAL;
22844+ root = sb->s_root;
22845+ aufs_read_lock(root, AuLock_FLUSH);
22846+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 22847+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 22848+ goto out;
22849+ }
22850+
22851+ err = 0;
22852+ mod->perm = br_perm_val(args[1].from);
22853+ AuDbg("mod path %s, perm 0x%x, %s\n",
22854+ mod->path, mod->perm, args[1].from);
22855+ mod->h_root = dget(au_h_dptr(root, bindex));
22856+
4f0767ce 22857+out:
1facf9fc 22858+ aufs_read_unlock(root, !AuLock_IR);
22859+ return err;
22860+}
22861+#endif
22862+
22863+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
22864+ substring_t args[])
22865+{
22866+ int err;
22867+ struct file *file;
22868+
22869+ file = au_xino_create(sb, args[0].from, /*silent*/0);
22870+ err = PTR_ERR(file);
22871+ if (IS_ERR(file))
22872+ goto out;
22873+
22874+ err = -EINVAL;
22875+ if (unlikely(file->f_dentry->d_sb == sb)) {
22876+ fput(file);
4a4d8108 22877+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 22878+ goto out;
22879+ }
22880+
22881+ err = 0;
22882+ xino->file = file;
22883+ xino->path = args[0].from;
22884+
4f0767ce 22885+out:
1facf9fc 22886+ return err;
22887+}
22888+
4a4d8108
AM
22889+static int noinline_for_stack
22890+au_opts_parse_xino_itrunc_path(struct super_block *sb,
22891+ struct au_opt_xino_itrunc *xino_itrunc,
22892+ substring_t args[])
1facf9fc 22893+{
22894+ int err;
22895+ aufs_bindex_t bend, bindex;
22896+ struct path path;
22897+ struct dentry *root;
22898+
22899+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
22900+ if (unlikely(err)) {
4a4d8108 22901+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 22902+ goto out;
22903+ }
22904+
22905+ xino_itrunc->bindex = -1;
22906+ root = sb->s_root;
22907+ aufs_read_lock(root, AuLock_FLUSH);
22908+ bend = au_sbend(sb);
22909+ for (bindex = 0; bindex <= bend; bindex++) {
22910+ if (au_h_dptr(root, bindex) == path.dentry) {
22911+ xino_itrunc->bindex = bindex;
22912+ break;
22913+ }
22914+ }
22915+ aufs_read_unlock(root, !AuLock_IR);
22916+ path_put(&path);
22917+
22918+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 22919+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 22920+ err = -EINVAL;
22921+ }
22922+
4f0767ce 22923+out:
1facf9fc 22924+ return err;
22925+}
22926+
22927+/* called without aufs lock */
22928+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
22929+{
22930+ int err, n, token;
22931+ aufs_bindex_t bindex;
22932+ unsigned char skipped;
22933+ struct dentry *root;
22934+ struct au_opt *opt, *opt_tail;
22935+ char *opt_str;
22936+ /* reduce the stack space */
22937+ union {
22938+ struct au_opt_xino_itrunc *xino_itrunc;
22939+ struct au_opt_wbr_create *create;
22940+ } u;
22941+ struct {
22942+ substring_t args[MAX_OPT_ARGS];
22943+ } *a;
22944+
22945+ err = -ENOMEM;
22946+ a = kmalloc(sizeof(*a), GFP_NOFS);
22947+ if (unlikely(!a))
22948+ goto out;
22949+
22950+ root = sb->s_root;
22951+ err = 0;
22952+ bindex = 0;
22953+ opt = opts->opt;
22954+ opt_tail = opt + opts->max_opt - 1;
22955+ opt->type = Opt_tail;
22956+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
22957+ err = -EINVAL;
22958+ skipped = 0;
22959+ token = match_token(opt_str, options, a->args);
22960+ switch (token) {
22961+ case Opt_br:
22962+ err = 0;
22963+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
22964+ && *opt_str) {
22965+ err = opt_add(opt, opt_str, opts->sb_flags,
22966+ bindex++);
22967+ if (unlikely(!err && ++opt > opt_tail)) {
22968+ err = -E2BIG;
22969+ break;
22970+ }
22971+ opt->type = Opt_tail;
22972+ skipped = 1;
22973+ }
22974+ break;
22975+ case Opt_add:
22976+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 22977+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 22978+ break;
22979+ }
22980+ bindex = n;
22981+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
22982+ bindex);
22983+ if (!err)
22984+ opt->type = token;
22985+ break;
22986+ case Opt_append:
22987+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
22988+ /*dummy bindex*/1);
22989+ if (!err)
22990+ opt->type = token;
22991+ break;
22992+ case Opt_prepend:
22993+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
22994+ /*bindex*/0);
22995+ if (!err)
22996+ opt->type = token;
22997+ break;
22998+ case Opt_del:
22999+ err = au_opts_parse_del(&opt->del, a->args);
23000+ if (!err)
23001+ opt->type = token;
23002+ break;
23003+#if 0 /* reserved for future use */
23004+ case Opt_idel:
23005+ del->pathname = "(indexed)";
23006+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 23007+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23008+ break;
23009+ }
23010+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
23011+ if (!err)
23012+ opt->type = token;
23013+ break;
23014+#endif
23015+ case Opt_mod:
23016+ err = au_opts_parse_mod(&opt->mod, a->args);
23017+ if (!err)
23018+ opt->type = token;
23019+ break;
23020+#ifdef IMOD /* reserved for future use */
23021+ case Opt_imod:
23022+ u.mod->path = "(indexed)";
23023+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23024+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23025+ break;
23026+ }
23027+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
23028+ if (!err)
23029+ opt->type = token;
23030+ break;
23031+#endif
23032+ case Opt_xino:
23033+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
23034+ if (!err)
23035+ opt->type = token;
23036+ break;
23037+
23038+ case Opt_trunc_xino_path:
23039+ err = au_opts_parse_xino_itrunc_path
23040+ (sb, &opt->xino_itrunc, a->args);
23041+ if (!err)
23042+ opt->type = token;
23043+ break;
23044+
23045+ case Opt_itrunc_xino:
23046+ u.xino_itrunc = &opt->xino_itrunc;
23047+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23048+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23049+ break;
23050+ }
23051+ u.xino_itrunc->bindex = n;
23052+ aufs_read_lock(root, AuLock_FLUSH);
23053+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 23054+ pr_err("out of bounds, %d\n", n);
1facf9fc 23055+ aufs_read_unlock(root, !AuLock_IR);
23056+ break;
23057+ }
23058+ aufs_read_unlock(root, !AuLock_IR);
23059+ err = 0;
23060+ opt->type = token;
23061+ break;
23062+
23063+ case Opt_dirwh:
23064+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
23065+ break;
23066+ err = 0;
23067+ opt->type = token;
23068+ break;
23069+
23070+ case Opt_rdcache:
027c5e7a
AM
23071+ if (unlikely(match_int(&a->args[0], &n))) {
23072+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23073+ break;
027c5e7a
AM
23074+ }
23075+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
23076+ pr_err("rdcache must be smaller than %d\n",
23077+ AUFS_RDCACHE_MAX);
23078+ break;
23079+ }
23080+ opt->rdcache = n;
1facf9fc 23081+ err = 0;
23082+ opt->type = token;
23083+ break;
23084+ case Opt_rdblk:
23085+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23086+ || n < 0
1facf9fc 23087+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 23088+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23089+ break;
23090+ }
1308ab2a 23091+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
23092+ pr_err("rdblk must be larger than %d\n",
23093+ NAME_MAX);
1facf9fc 23094+ break;
23095+ }
23096+ opt->rdblk = n;
23097+ err = 0;
23098+ opt->type = token;
23099+ break;
23100+ case Opt_rdhash:
23101+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23102+ || n < 0
1facf9fc 23103+ || n * sizeof(struct hlist_head)
23104+ > KMALLOC_MAX_SIZE)) {
4a4d8108 23105+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23106+ break;
23107+ }
23108+ opt->rdhash = n;
23109+ err = 0;
23110+ opt->type = token;
23111+ break;
23112+
23113+ case Opt_trunc_xino:
23114+ case Opt_notrunc_xino:
23115+ case Opt_noxino:
23116+ case Opt_trunc_xib:
23117+ case Opt_notrunc_xib:
dece6358
AM
23118+ case Opt_shwh:
23119+ case Opt_noshwh:
076b876e
AM
23120+ case Opt_dirperm1:
23121+ case Opt_nodirperm1:
1facf9fc 23122+ case Opt_plink:
23123+ case Opt_noplink:
23124+ case Opt_list_plink:
4a4d8108
AM
23125+ case Opt_dio:
23126+ case Opt_nodio:
1facf9fc 23127+ case Opt_diropq_a:
23128+ case Opt_diropq_w:
23129+ case Opt_warn_perm:
23130+ case Opt_nowarn_perm:
23131+ case Opt_refrof:
23132+ case Opt_norefrof:
23133+ case Opt_verbose:
23134+ case Opt_noverbose:
23135+ case Opt_sum:
23136+ case Opt_nosum:
23137+ case Opt_wsum:
dece6358
AM
23138+ case Opt_rdblk_def:
23139+ case Opt_rdhash_def:
1facf9fc 23140+ err = 0;
23141+ opt->type = token;
23142+ break;
23143+
23144+ case Opt_udba:
23145+ opt->udba = udba_val(a->args[0].from);
23146+ if (opt->udba >= 0) {
23147+ err = 0;
23148+ opt->type = token;
23149+ } else
4a4d8108 23150+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23151+ break;
23152+
23153+ case Opt_wbr_create:
23154+ u.create = &opt->wbr_create;
23155+ u.create->wbr_create
23156+ = au_wbr_create_val(a->args[0].from, u.create);
23157+ if (u.create->wbr_create >= 0) {
23158+ err = 0;
23159+ opt->type = token;
23160+ } else
4a4d8108 23161+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23162+ break;
23163+ case Opt_wbr_copyup:
23164+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
23165+ if (opt->wbr_copyup >= 0) {
23166+ err = 0;
23167+ opt->type = token;
23168+ } else
4a4d8108 23169+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23170+ break;
23171+
076b876e
AM
23172+ case Opt_fhsm_sec:
23173+ if (unlikely(match_int(&a->args[0], &n)
23174+ || n < 0)) {
23175+ pr_err("bad integer in %s\n", opt_str);
23176+ break;
23177+ }
23178+ if (sysaufs_brs) {
23179+ opt->fhsm_second = n;
23180+ opt->type = token;
23181+ } else
23182+ pr_warn("ignored %s\n", opt_str);
23183+ err = 0;
23184+ break;
23185+
1facf9fc 23186+ case Opt_ignore:
0c3ec466 23187+ pr_warn("ignored %s\n", opt_str);
1facf9fc 23188+ /*FALLTHROUGH*/
23189+ case Opt_ignore_silent:
23190+ skipped = 1;
23191+ err = 0;
23192+ break;
23193+ case Opt_err:
4a4d8108 23194+ pr_err("unknown option %s\n", opt_str);
1facf9fc 23195+ break;
23196+ }
23197+
23198+ if (!err && !skipped) {
23199+ if (unlikely(++opt > opt_tail)) {
23200+ err = -E2BIG;
23201+ opt--;
23202+ opt->type = Opt_tail;
23203+ break;
23204+ }
23205+ opt->type = Opt_tail;
23206+ }
23207+ }
23208+
23209+ kfree(a);
23210+ dump_opts(opts);
23211+ if (unlikely(err))
23212+ au_opts_free(opts);
23213+
4f0767ce 23214+out:
1facf9fc 23215+ return err;
23216+}
23217+
23218+static int au_opt_wbr_create(struct super_block *sb,
23219+ struct au_opt_wbr_create *create)
23220+{
23221+ int err;
23222+ struct au_sbinfo *sbinfo;
23223+
dece6358
AM
23224+ SiMustWriteLock(sb);
23225+
1facf9fc 23226+ err = 1; /* handled */
23227+ sbinfo = au_sbi(sb);
23228+ if (sbinfo->si_wbr_create_ops->fin) {
23229+ err = sbinfo->si_wbr_create_ops->fin(sb);
23230+ if (!err)
23231+ err = 1;
23232+ }
23233+
23234+ sbinfo->si_wbr_create = create->wbr_create;
23235+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
23236+ switch (create->wbr_create) {
23237+ case AuWbrCreate_MFSRRV:
23238+ case AuWbrCreate_MFSRR:
392086de
AM
23239+ case AuWbrCreate_PMFSRR:
23240+ case AuWbrCreate_PMFSRRV:
1facf9fc 23241+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
23242+ /*FALLTHROUGH*/
23243+ case AuWbrCreate_MFS:
23244+ case AuWbrCreate_MFSV:
23245+ case AuWbrCreate_PMFS:
23246+ case AuWbrCreate_PMFSV:
e49829fe
JR
23247+ sbinfo->si_wbr_mfs.mfs_expire
23248+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 23249+ break;
23250+ }
23251+
23252+ if (sbinfo->si_wbr_create_ops->init)
23253+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
23254+
23255+ return err;
23256+}
23257+
23258+/*
23259+ * returns,
23260+ * plus: processed without an error
23261+ * zero: unprocessed
23262+ */
23263+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
23264+ struct au_opts *opts)
23265+{
23266+ int err;
23267+ struct au_sbinfo *sbinfo;
23268+
dece6358
AM
23269+ SiMustWriteLock(sb);
23270+
1facf9fc 23271+ err = 1; /* handled */
23272+ sbinfo = au_sbi(sb);
23273+ switch (opt->type) {
23274+ case Opt_udba:
23275+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
23276+ sbinfo->si_mntflags |= opt->udba;
23277+ opts->given_udba |= opt->udba;
23278+ break;
23279+
23280+ case Opt_plink:
23281+ au_opt_set(sbinfo->si_mntflags, PLINK);
23282+ break;
23283+ case Opt_noplink:
23284+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 23285+ au_plink_put(sb, /*verbose*/1);
1facf9fc 23286+ au_opt_clr(sbinfo->si_mntflags, PLINK);
23287+ break;
23288+ case Opt_list_plink:
23289+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
23290+ au_plink_list(sb);
23291+ break;
23292+
4a4d8108
AM
23293+ case Opt_dio:
23294+ au_opt_set(sbinfo->si_mntflags, DIO);
23295+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23296+ break;
23297+ case Opt_nodio:
23298+ au_opt_clr(sbinfo->si_mntflags, DIO);
23299+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23300+ break;
23301+
076b876e
AM
23302+ case Opt_fhsm_sec:
23303+ au_fhsm_set(sbinfo, opt->fhsm_second);
23304+ break;
23305+
1facf9fc 23306+ case Opt_diropq_a:
23307+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
23308+ break;
23309+ case Opt_diropq_w:
23310+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
23311+ break;
23312+
23313+ case Opt_warn_perm:
23314+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
23315+ break;
23316+ case Opt_nowarn_perm:
23317+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
23318+ break;
23319+
23320+ case Opt_refrof:
23321+ au_opt_set(sbinfo->si_mntflags, REFROF);
23322+ break;
23323+ case Opt_norefrof:
23324+ au_opt_clr(sbinfo->si_mntflags, REFROF);
23325+ break;
23326+
23327+ case Opt_verbose:
23328+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
23329+ break;
23330+ case Opt_noverbose:
23331+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
23332+ break;
23333+
23334+ case Opt_sum:
23335+ au_opt_set(sbinfo->si_mntflags, SUM);
23336+ break;
23337+ case Opt_wsum:
23338+ au_opt_clr(sbinfo->si_mntflags, SUM);
23339+ au_opt_set(sbinfo->si_mntflags, SUM_W);
23340+ case Opt_nosum:
23341+ au_opt_clr(sbinfo->si_mntflags, SUM);
23342+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
23343+ break;
23344+
23345+ case Opt_wbr_create:
23346+ err = au_opt_wbr_create(sb, &opt->wbr_create);
23347+ break;
23348+ case Opt_wbr_copyup:
23349+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
23350+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
23351+ break;
23352+
23353+ case Opt_dirwh:
23354+ sbinfo->si_dirwh = opt->dirwh;
23355+ break;
23356+
23357+ case Opt_rdcache:
e49829fe
JR
23358+ sbinfo->si_rdcache
23359+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 23360+ break;
23361+ case Opt_rdblk:
23362+ sbinfo->si_rdblk = opt->rdblk;
23363+ break;
dece6358
AM
23364+ case Opt_rdblk_def:
23365+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
23366+ break;
1facf9fc 23367+ case Opt_rdhash:
23368+ sbinfo->si_rdhash = opt->rdhash;
23369+ break;
dece6358
AM
23370+ case Opt_rdhash_def:
23371+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
23372+ break;
23373+
23374+ case Opt_shwh:
23375+ au_opt_set(sbinfo->si_mntflags, SHWH);
23376+ break;
23377+ case Opt_noshwh:
23378+ au_opt_clr(sbinfo->si_mntflags, SHWH);
23379+ break;
1facf9fc 23380+
076b876e
AM
23381+ case Opt_dirperm1:
23382+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
23383+ break;
23384+ case Opt_nodirperm1:
23385+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
23386+ break;
23387+
1facf9fc 23388+ case Opt_trunc_xino:
23389+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
23390+ break;
23391+ case Opt_notrunc_xino:
23392+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
23393+ break;
23394+
23395+ case Opt_trunc_xino_path:
23396+ case Opt_itrunc_xino:
23397+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
23398+ if (!err)
23399+ err = 1;
23400+ break;
23401+
23402+ case Opt_trunc_xib:
23403+ au_fset_opts(opts->flags, TRUNC_XIB);
23404+ break;
23405+ case Opt_notrunc_xib:
23406+ au_fclr_opts(opts->flags, TRUNC_XIB);
23407+ break;
23408+
23409+ default:
23410+ err = 0;
23411+ break;
23412+ }
23413+
23414+ return err;
23415+}
23416+
23417+/*
23418+ * returns tri-state.
23419+ * plus: processed without an error
23420+ * zero: unprocessed
23421+ * minus: error
23422+ */
23423+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
23424+ struct au_opts *opts)
23425+{
23426+ int err, do_refresh;
23427+
23428+ err = 0;
23429+ switch (opt->type) {
23430+ case Opt_append:
23431+ opt->add.bindex = au_sbend(sb) + 1;
23432+ if (opt->add.bindex < 0)
23433+ opt->add.bindex = 0;
23434+ goto add;
23435+ case Opt_prepend:
23436+ opt->add.bindex = 0;
f6b6e03d 23437+ add: /* indented label */
1facf9fc 23438+ case Opt_add:
23439+ err = au_br_add(sb, &opt->add,
23440+ au_ftest_opts(opts->flags, REMOUNT));
23441+ if (!err) {
23442+ err = 1;
027c5e7a 23443+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23444+ }
23445+ break;
23446+
23447+ case Opt_del:
23448+ case Opt_idel:
23449+ err = au_br_del(sb, &opt->del,
23450+ au_ftest_opts(opts->flags, REMOUNT));
23451+ if (!err) {
23452+ err = 1;
23453+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 23454+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23455+ }
23456+ break;
23457+
23458+ case Opt_mod:
23459+ case Opt_imod:
23460+ err = au_br_mod(sb, &opt->mod,
23461+ au_ftest_opts(opts->flags, REMOUNT),
23462+ &do_refresh);
23463+ if (!err) {
23464+ err = 1;
027c5e7a
AM
23465+ if (do_refresh)
23466+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23467+ }
23468+ break;
23469+ }
23470+
23471+ return err;
23472+}
23473+
23474+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
23475+ struct au_opt_xino **opt_xino,
23476+ struct au_opts *opts)
23477+{
23478+ int err;
23479+ aufs_bindex_t bend, bindex;
23480+ struct dentry *root, *parent, *h_root;
23481+
23482+ err = 0;
23483+ switch (opt->type) {
23484+ case Opt_xino:
23485+ err = au_xino_set(sb, &opt->xino,
23486+ !!au_ftest_opts(opts->flags, REMOUNT));
23487+ if (unlikely(err))
23488+ break;
23489+
23490+ *opt_xino = &opt->xino;
23491+ au_xino_brid_set(sb, -1);
23492+
23493+ /* safe d_parent access */
23494+ parent = opt->xino.file->f_dentry->d_parent;
23495+ root = sb->s_root;
23496+ bend = au_sbend(sb);
23497+ for (bindex = 0; bindex <= bend; bindex++) {
23498+ h_root = au_h_dptr(root, bindex);
23499+ if (h_root == parent) {
23500+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
23501+ break;
23502+ }
23503+ }
23504+ break;
23505+
23506+ case Opt_noxino:
23507+ au_xino_clr(sb);
23508+ au_xino_brid_set(sb, -1);
23509+ *opt_xino = (void *)-1;
23510+ break;
23511+ }
23512+
23513+ return err;
23514+}
23515+
23516+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
23517+ unsigned int pending)
23518+{
076b876e 23519+ int err, fhsm;
1facf9fc 23520+ aufs_bindex_t bindex, bend;
23521+ unsigned char do_plink, skip, do_free;
23522+ struct au_branch *br;
23523+ struct au_wbr *wbr;
23524+ struct dentry *root;
23525+ struct inode *dir, *h_dir;
23526+ struct au_sbinfo *sbinfo;
23527+ struct au_hinode *hdir;
23528+
dece6358
AM
23529+ SiMustAnyLock(sb);
23530+
1facf9fc 23531+ sbinfo = au_sbi(sb);
23532+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
23533+
dece6358
AM
23534+ if (!(sb_flags & MS_RDONLY)) {
23535+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 23536+ pr_warn("first branch should be rw\n");
dece6358 23537+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 23538+ pr_warn("shwh should be used with ro\n");
dece6358 23539+ }
1facf9fc 23540+
4a4d8108 23541+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 23542+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 23543+ pr_warn("udba=*notify requires xino\n");
1facf9fc 23544+
076b876e
AM
23545+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
23546+ pr_warn("dirperm1 breaks the protection"
23547+ " by the permission bits on the lower branch\n");
23548+
1facf9fc 23549+ err = 0;
076b876e 23550+ fhsm = 0;
1facf9fc 23551+ root = sb->s_root;
4a4d8108 23552+ dir = root->d_inode;
1facf9fc 23553+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
23554+ bend = au_sbend(sb);
23555+ for (bindex = 0; !err && bindex <= bend; bindex++) {
23556+ skip = 0;
23557+ h_dir = au_h_iptr(dir, bindex);
23558+ br = au_sbr(sb, bindex);
23559+ do_free = 0;
23560+
23561+ wbr = br->br_wbr;
23562+ if (wbr)
23563+ wbr_wh_read_lock(wbr);
23564+
1e00d052 23565+ if (!au_br_writable(br->br_perm)) {
1facf9fc 23566+ do_free = !!wbr;
23567+ skip = (!wbr
23568+ || (!wbr->wbr_whbase
23569+ && !wbr->wbr_plink
23570+ && !wbr->wbr_orph));
1e00d052 23571+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 23572+ /* skip = (!br->br_whbase && !br->br_orph); */
23573+ skip = (!wbr || !wbr->wbr_whbase);
23574+ if (skip && wbr) {
23575+ if (do_plink)
23576+ skip = !!wbr->wbr_plink;
23577+ else
23578+ skip = !wbr->wbr_plink;
23579+ }
1e00d052 23580+ } else {
1facf9fc 23581+ /* skip = (br->br_whbase && br->br_ohph); */
23582+ skip = (wbr && wbr->wbr_whbase);
23583+ if (skip) {
23584+ if (do_plink)
23585+ skip = !!wbr->wbr_plink;
23586+ else
23587+ skip = !wbr->wbr_plink;
23588+ }
1facf9fc 23589+ }
23590+ if (wbr)
23591+ wbr_wh_read_unlock(wbr);
23592+
076b876e
AM
23593+ if (au_br_fhsm(br->br_perm)) {
23594+ fhsm++;
23595+ AuDebugOn(!br->br_fhsm);
23596+ }
23597+
1facf9fc 23598+ if (skip)
23599+ continue;
23600+
23601+ hdir = au_hi(dir, bindex);
4a4d8108 23602+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 23603+ if (wbr)
23604+ wbr_wh_write_lock(wbr);
86dc4139 23605+ err = au_wh_init(br, sb);
1facf9fc 23606+ if (wbr)
23607+ wbr_wh_write_unlock(wbr);
4a4d8108 23608+ au_hn_imtx_unlock(hdir);
1facf9fc 23609+
23610+ if (!err && do_free) {
23611+ kfree(wbr);
23612+ br->br_wbr = NULL;
23613+ }
23614+ }
23615+
076b876e
AM
23616+ if (fhsm >= 2)
23617+ au_fset_si(sbinfo, FHSM);
23618+ else
23619+ au_fclr_si(sbinfo, FHSM);
23620+
1facf9fc 23621+ return err;
23622+}
23623+
23624+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
23625+{
23626+ int err;
23627+ unsigned int tmp;
027c5e7a 23628+ aufs_bindex_t bindex, bend;
1facf9fc 23629+ struct au_opt *opt;
23630+ struct au_opt_xino *opt_xino, xino;
23631+ struct au_sbinfo *sbinfo;
027c5e7a 23632+ struct au_branch *br;
076b876e 23633+ struct inode *dir;
1facf9fc 23634+
dece6358
AM
23635+ SiMustWriteLock(sb);
23636+
1facf9fc 23637+ err = 0;
23638+ opt_xino = NULL;
23639+ opt = opts->opt;
23640+ while (err >= 0 && opt->type != Opt_tail)
23641+ err = au_opt_simple(sb, opt++, opts);
23642+ if (err > 0)
23643+ err = 0;
23644+ else if (unlikely(err < 0))
23645+ goto out;
23646+
23647+ /* disable xino and udba temporary */
23648+ sbinfo = au_sbi(sb);
23649+ tmp = sbinfo->si_mntflags;
23650+ au_opt_clr(sbinfo->si_mntflags, XINO);
23651+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
23652+
23653+ opt = opts->opt;
23654+ while (err >= 0 && opt->type != Opt_tail)
23655+ err = au_opt_br(sb, opt++, opts);
23656+ if (err > 0)
23657+ err = 0;
23658+ else if (unlikely(err < 0))
23659+ goto out;
23660+
23661+ bend = au_sbend(sb);
23662+ if (unlikely(bend < 0)) {
23663+ err = -EINVAL;
4a4d8108 23664+ pr_err("no branches\n");
1facf9fc 23665+ goto out;
23666+ }
23667+
23668+ if (au_opt_test(tmp, XINO))
23669+ au_opt_set(sbinfo->si_mntflags, XINO);
23670+ opt = opts->opt;
23671+ while (!err && opt->type != Opt_tail)
23672+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
23673+ if (unlikely(err))
23674+ goto out;
23675+
23676+ err = au_opts_verify(sb, sb->s_flags, tmp);
23677+ if (unlikely(err))
23678+ goto out;
23679+
23680+ /* restore xino */
23681+ if (au_opt_test(tmp, XINO) && !opt_xino) {
23682+ xino.file = au_xino_def(sb);
23683+ err = PTR_ERR(xino.file);
23684+ if (IS_ERR(xino.file))
23685+ goto out;
23686+
23687+ err = au_xino_set(sb, &xino, /*remount*/0);
23688+ fput(xino.file);
23689+ if (unlikely(err))
23690+ goto out;
23691+ }
23692+
23693+ /* restore udba */
027c5e7a 23694+ tmp &= AuOptMask_UDBA;
1facf9fc 23695+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
23696+ sbinfo->si_mntflags |= tmp;
23697+ bend = au_sbend(sb);
23698+ for (bindex = 0; bindex <= bend; bindex++) {
23699+ br = au_sbr(sb, bindex);
23700+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
23701+ if (unlikely(err))
23702+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
23703+ bindex, err);
23704+ /* go on even if err */
23705+ }
4a4d8108 23706+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
076b876e 23707+ dir = sb->s_root->d_inode;
4a4d8108 23708+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 23709+ }
23710+
4f0767ce 23711+out:
1facf9fc 23712+ return err;
23713+}
23714+
23715+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
23716+{
23717+ int err, rerr;
23718+ struct inode *dir;
23719+ struct au_opt_xino *opt_xino;
23720+ struct au_opt *opt;
23721+ struct au_sbinfo *sbinfo;
23722+
dece6358
AM
23723+ SiMustWriteLock(sb);
23724+
1facf9fc 23725+ dir = sb->s_root->d_inode;
23726+ sbinfo = au_sbi(sb);
23727+ err = 0;
23728+ opt_xino = NULL;
23729+ opt = opts->opt;
23730+ while (err >= 0 && opt->type != Opt_tail) {
23731+ err = au_opt_simple(sb, opt, opts);
23732+ if (!err)
23733+ err = au_opt_br(sb, opt, opts);
23734+ if (!err)
23735+ err = au_opt_xino(sb, opt, &opt_xino, opts);
23736+ opt++;
23737+ }
23738+ if (err > 0)
23739+ err = 0;
23740+ AuTraceErr(err);
23741+ /* go on even err */
23742+
23743+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
23744+ if (unlikely(rerr && !err))
23745+ err = rerr;
23746+
23747+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
23748+ rerr = au_xib_trunc(sb);
23749+ if (unlikely(rerr && !err))
23750+ err = rerr;
23751+ }
23752+
23753+ /* will be handled by the caller */
027c5e7a 23754+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 23755+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 23756+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23757+
23758+ AuDbg("status 0x%x\n", opts->flags);
23759+ return err;
23760+}
23761+
23762+/* ---------------------------------------------------------------------- */
23763+
23764+unsigned int au_opt_udba(struct super_block *sb)
23765+{
23766+ return au_mntflags(sb) & AuOptMask_UDBA;
23767+}
7f207e10
AM
23768diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
23769--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
23770+++ linux/fs/aufs/opts.h 2014-08-14 10:15:45.128609525 +0200
23771@@ -0,0 +1,213 @@
1facf9fc 23772+/*
523b37e3 23773+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 23774+ *
23775+ * This program, aufs is free software; you can redistribute it and/or modify
23776+ * it under the terms of the GNU General Public License as published by
23777+ * the Free Software Foundation; either version 2 of the License, or
23778+ * (at your option) any later version.
dece6358
AM
23779+ *
23780+ * This program is distributed in the hope that it will be useful,
23781+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23782+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23783+ * GNU General Public License for more details.
23784+ *
23785+ * You should have received a copy of the GNU General Public License
523b37e3 23786+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 23787+ */
23788+
23789+/*
23790+ * mount options/flags
23791+ */
23792+
23793+#ifndef __AUFS_OPTS_H__
23794+#define __AUFS_OPTS_H__
23795+
23796+#ifdef __KERNEL__
23797+
dece6358 23798+#include <linux/path.h>
076b876e 23799+#include "branch.h"
1facf9fc 23800+
dece6358
AM
23801+struct file;
23802+struct super_block;
23803+
1facf9fc 23804+/* ---------------------------------------------------------------------- */
23805+
23806+/* mount flags */
23807+#define AuOpt_XINO 1 /* external inode number bitmap
23808+ and translation table */
23809+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
23810+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
23811+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 23812+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
23813+#define AuOpt_SHWH (1 << 5) /* show whiteout */
23814+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
23815+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
23816+ bits */
dece6358
AM
23817+#define AuOpt_REFROF (1 << 8) /* unimplemented */
23818+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
23819+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
23820+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
23821+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
23822+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 23823+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 23824+
4a4d8108
AM
23825+#ifndef CONFIG_AUFS_HNOTIFY
23826+#undef AuOpt_UDBA_HNOTIFY
23827+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 23828+#endif
dece6358
AM
23829+#ifndef CONFIG_AUFS_SHWH
23830+#undef AuOpt_SHWH
23831+#define AuOpt_SHWH 0
23832+#endif
1facf9fc 23833+
23834+#define AuOpt_Def (AuOpt_XINO \
23835+ | AuOpt_UDBA_REVAL \
23836+ | AuOpt_PLINK \
23837+ /* | AuOpt_DIRPERM1 */ \
23838+ | AuOpt_WARN_PERM)
23839+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
23840+ | AuOpt_UDBA_REVAL \
4a4d8108 23841+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 23842+
23843+#define au_opt_test(flags, name) (flags & AuOpt_##name)
23844+#define au_opt_set(flags, name) do { \
23845+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
23846+ ((flags) |= AuOpt_##name); \
23847+} while (0)
23848+#define au_opt_set_udba(flags, name) do { \
23849+ (flags) &= ~AuOptMask_UDBA; \
23850+ ((flags) |= AuOpt_##name); \
23851+} while (0)
7f207e10
AM
23852+#define au_opt_clr(flags, name) do { \
23853+ ((flags) &= ~AuOpt_##name); \
23854+} while (0)
1facf9fc 23855+
e49829fe
JR
23856+static inline unsigned int au_opts_plink(unsigned int mntflags)
23857+{
23858+#ifdef CONFIG_PROC_FS
23859+ return mntflags;
23860+#else
23861+ return mntflags & ~AuOpt_PLINK;
23862+#endif
23863+}
23864+
1facf9fc 23865+/* ---------------------------------------------------------------------- */
23866+
23867+/* policies to select one among multiple writable branches */
23868+enum {
23869+ AuWbrCreate_TDP, /* top down parent */
23870+ AuWbrCreate_RR, /* round robin */
23871+ AuWbrCreate_MFS, /* most free space */
23872+ AuWbrCreate_MFSV, /* mfs with seconds */
23873+ AuWbrCreate_MFSRR, /* mfs then rr */
23874+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
23875+ AuWbrCreate_PMFS, /* parent and mfs */
23876+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
23877+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
23878+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 23879+
23880+ AuWbrCreate_Def = AuWbrCreate_TDP
23881+};
23882+
23883+enum {
23884+ AuWbrCopyup_TDP, /* top down parent */
23885+ AuWbrCopyup_BUP, /* bottom up parent */
23886+ AuWbrCopyup_BU, /* bottom up */
23887+
23888+ AuWbrCopyup_Def = AuWbrCopyup_TDP
23889+};
23890+
23891+/* ---------------------------------------------------------------------- */
23892+
23893+struct au_opt_add {
23894+ aufs_bindex_t bindex;
23895+ char *pathname;
23896+ int perm;
23897+ struct path path;
23898+};
23899+
23900+struct au_opt_del {
23901+ char *pathname;
23902+ struct path h_path;
23903+};
23904+
23905+struct au_opt_mod {
23906+ char *path;
23907+ int perm;
23908+ struct dentry *h_root;
23909+};
23910+
23911+struct au_opt_xino {
23912+ char *path;
23913+ struct file *file;
23914+};
23915+
23916+struct au_opt_xino_itrunc {
23917+ aufs_bindex_t bindex;
23918+};
23919+
23920+struct au_opt_wbr_create {
23921+ int wbr_create;
23922+ int mfs_second;
23923+ unsigned long long mfsrr_watermark;
23924+};
23925+
23926+struct au_opt {
23927+ int type;
23928+ union {
23929+ struct au_opt_xino xino;
23930+ struct au_opt_xino_itrunc xino_itrunc;
23931+ struct au_opt_add add;
23932+ struct au_opt_del del;
23933+ struct au_opt_mod mod;
23934+ int dirwh;
23935+ int rdcache;
23936+ unsigned int rdblk;
23937+ unsigned int rdhash;
23938+ int udba;
23939+ struct au_opt_wbr_create wbr_create;
23940+ int wbr_copyup;
076b876e 23941+ unsigned int fhsm_second;
1facf9fc 23942+ };
23943+};
23944+
23945+/* opts flags */
23946+#define AuOpts_REMOUNT 1
027c5e7a
AM
23947+#define AuOpts_REFRESH (1 << 1)
23948+#define AuOpts_TRUNC_XIB (1 << 2)
23949+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 23950+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
23951+#define au_fset_opts(flags, name) \
23952+ do { (flags) |= AuOpts_##name; } while (0)
23953+#define au_fclr_opts(flags, name) \
23954+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 23955+
23956+struct au_opts {
23957+ struct au_opt *opt;
23958+ int max_opt;
23959+
23960+ unsigned int given_udba;
23961+ unsigned int flags;
23962+ unsigned long sb_flags;
23963+};
23964+
23965+/* ---------------------------------------------------------------------- */
23966+
076b876e 23967+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 23968+const char *au_optstr_udba(int udba);
23969+const char *au_optstr_wbr_copyup(int wbr_copyup);
23970+const char *au_optstr_wbr_create(int wbr_create);
23971+
23972+void au_opts_free(struct au_opts *opts);
23973+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
23974+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
23975+ unsigned int pending);
23976+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
23977+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
23978+
23979+unsigned int au_opt_udba(struct super_block *sb);
23980+
23981+/* ---------------------------------------------------------------------- */
23982+
23983+#endif /* __KERNEL__ */
23984+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
23985diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
23986--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
076b876e 23987+++ linux/fs/aufs/plink.c 2014-01-30 21:10:02.857481956 +0100
523b37e3 23988@@ -0,0 +1,532 @@
1facf9fc 23989+/*
523b37e3 23990+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 23991+ *
23992+ * This program, aufs is free software; you can redistribute it and/or modify
23993+ * it under the terms of the GNU General Public License as published by
23994+ * the Free Software Foundation; either version 2 of the License, or
23995+ * (at your option) any later version.
dece6358
AM
23996+ *
23997+ * This program is distributed in the hope that it will be useful,
23998+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23999+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24000+ * GNU General Public License for more details.
24001+ *
24002+ * You should have received a copy of the GNU General Public License
523b37e3 24003+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24004+ */
24005+
24006+/*
24007+ * pseudo-link
24008+ */
24009+
24010+#include "aufs.h"
24011+
24012+/*
e49829fe 24013+ * the pseudo-link maintenance mode.
1facf9fc 24014+ * during a user process maintains the pseudo-links,
24015+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
24016+ *
24017+ * Flags
24018+ * NOPLM:
24019+ * For entry functions which will handle plink, and i_mutex is already held
24020+ * in VFS.
24021+ * They cannot wait and should return an error at once.
24022+ * Callers has to check the error.
24023+ * NOPLMW:
24024+ * For entry functions which will handle plink, but i_mutex is not held
24025+ * in VFS.
24026+ * They can wait the plink maintenance mode to finish.
24027+ *
24028+ * They behave like F_SETLK and F_SETLKW.
24029+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 24030+ */
e49829fe
JR
24031+
24032+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 24033+{
e49829fe
JR
24034+ int err;
24035+ pid_t pid, ppid;
24036+ struct au_sbinfo *sbi;
dece6358
AM
24037+
24038+ SiMustAnyLock(sb);
24039+
e49829fe
JR
24040+ err = 0;
24041+ if (!au_opt_test(au_mntflags(sb), PLINK))
24042+ goto out;
24043+
24044+ sbi = au_sbi(sb);
24045+ pid = sbi->si_plink_maint_pid;
24046+ if (!pid || pid == current->pid)
24047+ goto out;
24048+
24049+ /* todo: it highly depends upon /sbin/mount.aufs */
24050+ rcu_read_lock();
24051+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
24052+ rcu_read_unlock();
24053+ if (pid == ppid)
24054+ goto out;
24055+
24056+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
24057+ /* if there is no i_mutex lock in VFS, we don't need to wait */
24058+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
24059+ while (sbi->si_plink_maint_pid) {
24060+ si_read_unlock(sb);
24061+ /* gave up wake_up_bit() */
24062+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
24063+
24064+ if (au_ftest_lock(flags, FLUSH))
24065+ au_nwt_flush(&sbi->si_nowait);
24066+ si_noflush_read_lock(sb);
24067+ }
24068+ } else if (au_ftest_lock(flags, NOPLM)) {
24069+ AuDbg("ppid %d, pid %d\n", ppid, pid);
24070+ err = -EAGAIN;
24071+ }
24072+
24073+out:
24074+ return err;
4a4d8108
AM
24075+}
24076+
e49829fe 24077+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 24078+{
4a4d8108 24079+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 24080+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 24081+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 24082+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
24083+}
24084+
e49829fe 24085+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
24086+{
24087+ int err;
4a4d8108
AM
24088+ struct au_sbinfo *sbinfo;
24089+
24090+ err = 0;
4a4d8108
AM
24091+ sbinfo = au_sbi(sb);
24092+ /* make sure i am the only one in this fs */
e49829fe
JR
24093+ si_write_lock(sb, AuLock_FLUSH);
24094+ if (au_opt_test(au_mntflags(sb), PLINK)) {
24095+ spin_lock(&sbinfo->si_plink_maint_lock);
24096+ if (!sbinfo->si_plink_maint_pid)
24097+ sbinfo->si_plink_maint_pid = current->pid;
24098+ else
24099+ err = -EBUSY;
24100+ spin_unlock(&sbinfo->si_plink_maint_lock);
24101+ }
4a4d8108
AM
24102+ si_write_unlock(sb);
24103+
24104+ return err;
1facf9fc 24105+}
24106+
24107+/* ---------------------------------------------------------------------- */
24108+
1facf9fc 24109+#ifdef CONFIG_AUFS_DEBUG
24110+void au_plink_list(struct super_block *sb)
24111+{
86dc4139 24112+ int i;
1facf9fc 24113+ struct au_sbinfo *sbinfo;
86dc4139 24114+ struct hlist_head *plink_hlist;
1facf9fc 24115+ struct pseudo_link *plink;
24116+
dece6358
AM
24117+ SiMustAnyLock(sb);
24118+
1facf9fc 24119+ sbinfo = au_sbi(sb);
24120+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24121+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24122+
86dc4139
AM
24123+ for (i = 0; i < AuPlink_NHASH; i++) {
24124+ plink_hlist = &sbinfo->si_plink[i].head;
24125+ rcu_read_lock();
24126+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
24127+ AuDbg("%lu\n", plink->inode->i_ino);
24128+ rcu_read_unlock();
24129+ }
1facf9fc 24130+}
24131+#endif
24132+
24133+/* is the inode pseudo-linked? */
24134+int au_plink_test(struct inode *inode)
24135+{
86dc4139 24136+ int found, i;
1facf9fc 24137+ struct au_sbinfo *sbinfo;
86dc4139 24138+ struct hlist_head *plink_hlist;
1facf9fc 24139+ struct pseudo_link *plink;
24140+
24141+ sbinfo = au_sbi(inode->i_sb);
dece6358 24142+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 24143+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 24144+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 24145+
24146+ found = 0;
86dc4139
AM
24147+ i = au_plink_hash(inode->i_ino);
24148+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 24149+ rcu_read_lock();
86dc4139 24150+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 24151+ if (plink->inode == inode) {
24152+ found = 1;
24153+ break;
24154+ }
4a4d8108 24155+ rcu_read_unlock();
1facf9fc 24156+ return found;
24157+}
24158+
24159+/* ---------------------------------------------------------------------- */
24160+
24161+/*
24162+ * generate a name for plink.
24163+ * the file will be stored under AUFS_WH_PLINKDIR.
24164+ */
24165+/* 20 is max digits length of ulong 64 */
24166+#define PLINK_NAME_LEN ((20 + 1) * 2)
24167+
24168+static int plink_name(char *name, int len, struct inode *inode,
24169+ aufs_bindex_t bindex)
24170+{
24171+ int rlen;
24172+ struct inode *h_inode;
24173+
24174+ h_inode = au_h_iptr(inode, bindex);
24175+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
24176+ return rlen;
24177+}
24178+
7f207e10
AM
24179+struct au_do_plink_lkup_args {
24180+ struct dentry **errp;
24181+ struct qstr *tgtname;
24182+ struct dentry *h_parent;
24183+ struct au_branch *br;
24184+};
24185+
24186+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
24187+ struct dentry *h_parent,
24188+ struct au_branch *br)
24189+{
24190+ struct dentry *h_dentry;
24191+ struct mutex *h_mtx;
24192+
24193+ h_mtx = &h_parent->d_inode->i_mutex;
24194+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 24195+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
24196+ mutex_unlock(h_mtx);
24197+ return h_dentry;
24198+}
24199+
24200+static void au_call_do_plink_lkup(void *args)
24201+{
24202+ struct au_do_plink_lkup_args *a = args;
24203+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
24204+}
24205+
1facf9fc 24206+/* lookup the plink-ed @inode under the branch at @bindex */
24207+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
24208+{
24209+ struct dentry *h_dentry, *h_parent;
24210+ struct au_branch *br;
24211+ struct inode *h_dir;
7f207e10 24212+ int wkq_err;
1facf9fc 24213+ char a[PLINK_NAME_LEN];
0c3ec466 24214+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24215+
e49829fe
JR
24216+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
24217+
1facf9fc 24218+ br = au_sbr(inode->i_sb, bindex);
24219+ h_parent = br->br_wbr->wbr_plink;
24220+ h_dir = h_parent->d_inode;
24221+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24222+
2dfbb274 24223+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
24224+ struct au_do_plink_lkup_args args = {
24225+ .errp = &h_dentry,
24226+ .tgtname = &tgtname,
24227+ .h_parent = h_parent,
24228+ .br = br
24229+ };
24230+
24231+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
24232+ if (unlikely(wkq_err))
24233+ h_dentry = ERR_PTR(wkq_err);
24234+ } else
24235+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
24236+
1facf9fc 24237+ return h_dentry;
24238+}
24239+
24240+/* create a pseudo-link */
24241+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
24242+ struct dentry *h_dentry, struct au_branch *br)
24243+{
24244+ int err;
24245+ struct path h_path = {
86dc4139 24246+ .mnt = au_br_mnt(br)
1facf9fc 24247+ };
523b37e3 24248+ struct inode *h_dir, *delegated;
1facf9fc 24249+
24250+ h_dir = h_parent->d_inode;
7f207e10 24251+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 24252+again:
b4510431 24253+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 24254+ err = PTR_ERR(h_path.dentry);
24255+ if (IS_ERR(h_path.dentry))
24256+ goto out;
24257+
24258+ err = 0;
24259+ /* wh.plink dir is not monitored */
7f207e10 24260+ /* todo: is it really safe? */
1facf9fc 24261+ if (h_path.dentry->d_inode
24262+ && h_path.dentry->d_inode != h_dentry->d_inode) {
523b37e3
AM
24263+ delegated = NULL;
24264+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
24265+ if (unlikely(err == -EWOULDBLOCK)) {
24266+ pr_warn("cannot retry for NFSv4 delegation"
24267+ " for an internal unlink\n");
24268+ iput(delegated);
24269+ }
1facf9fc 24270+ dput(h_path.dentry);
24271+ h_path.dentry = NULL;
24272+ if (!err)
24273+ goto again;
24274+ }
523b37e3
AM
24275+ if (!err && !h_path.dentry->d_inode) {
24276+ delegated = NULL;
24277+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
24278+ if (unlikely(err == -EWOULDBLOCK)) {
24279+ pr_warn("cannot retry for NFSv4 delegation"
24280+ " for an internal link\n");
24281+ iput(delegated);
24282+ }
24283+ }
1facf9fc 24284+ dput(h_path.dentry);
24285+
4f0767ce 24286+out:
7f207e10 24287+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 24288+ return err;
24289+}
24290+
24291+struct do_whplink_args {
24292+ int *errp;
24293+ struct qstr *tgt;
24294+ struct dentry *h_parent;
24295+ struct dentry *h_dentry;
24296+ struct au_branch *br;
24297+};
24298+
24299+static void call_do_whplink(void *args)
24300+{
24301+ struct do_whplink_args *a = args;
24302+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
24303+}
24304+
24305+static int whplink(struct dentry *h_dentry, struct inode *inode,
24306+ aufs_bindex_t bindex, struct au_branch *br)
24307+{
24308+ int err, wkq_err;
24309+ struct au_wbr *wbr;
24310+ struct dentry *h_parent;
24311+ struct inode *h_dir;
24312+ char a[PLINK_NAME_LEN];
0c3ec466 24313+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24314+
24315+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
24316+ h_parent = wbr->wbr_plink;
24317+ h_dir = h_parent->d_inode;
24318+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24319+
24320+ /* always superio. */
2dfbb274 24321+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 24322+ struct do_whplink_args args = {
24323+ .errp = &err,
24324+ .tgt = &tgtname,
24325+ .h_parent = h_parent,
24326+ .h_dentry = h_dentry,
24327+ .br = br
24328+ };
24329+ wkq_err = au_wkq_wait(call_do_whplink, &args);
24330+ if (unlikely(wkq_err))
24331+ err = wkq_err;
24332+ } else
24333+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 24334+
24335+ return err;
24336+}
24337+
24338+/* free a single plink */
24339+static void do_put_plink(struct pseudo_link *plink, int do_del)
24340+{
1facf9fc 24341+ if (do_del)
86dc4139 24342+ hlist_del(&plink->hlist);
4a4d8108
AM
24343+ iput(plink->inode);
24344+ kfree(plink);
24345+}
24346+
24347+static void do_put_plink_rcu(struct rcu_head *rcu)
24348+{
24349+ struct pseudo_link *plink;
24350+
24351+ plink = container_of(rcu, struct pseudo_link, rcu);
24352+ iput(plink->inode);
1facf9fc 24353+ kfree(plink);
24354+}
24355+
24356+/*
24357+ * create a new pseudo-link for @h_dentry on @bindex.
24358+ * the linked inode is held in aufs @inode.
24359+ */
24360+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
24361+ struct dentry *h_dentry)
24362+{
24363+ struct super_block *sb;
24364+ struct au_sbinfo *sbinfo;
86dc4139 24365+ struct hlist_head *plink_hlist;
4a4d8108 24366+ struct pseudo_link *plink, *tmp;
86dc4139
AM
24367+ struct au_sphlhead *sphl;
24368+ int found, err, cnt, i;
1facf9fc 24369+
24370+ sb = inode->i_sb;
24371+ sbinfo = au_sbi(sb);
24372+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24373+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24374+
86dc4139 24375+ found = au_plink_test(inode);
4a4d8108 24376+ if (found)
1facf9fc 24377+ return;
4a4d8108 24378+
86dc4139
AM
24379+ i = au_plink_hash(inode->i_ino);
24380+ sphl = sbinfo->si_plink + i;
24381+ plink_hlist = &sphl->head;
4a4d8108
AM
24382+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
24383+ if (tmp)
24384+ tmp->inode = au_igrab(inode);
24385+ else {
24386+ err = -ENOMEM;
24387+ goto out;
1facf9fc 24388+ }
24389+
86dc4139
AM
24390+ spin_lock(&sphl->spin);
24391+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
24392+ if (plink->inode == inode) {
24393+ found = 1;
24394+ break;
24395+ }
1facf9fc 24396+ }
4a4d8108 24397+ if (!found)
86dc4139
AM
24398+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
24399+ spin_unlock(&sphl->spin);
4a4d8108 24400+ if (!found) {
86dc4139
AM
24401+ cnt = au_sphl_count(sphl);
24402+#define msg "unexpectedly unblanced or too many pseudo-links"
24403+ if (cnt > AUFS_PLINK_WARN)
24404+ AuWarn1(msg ", %d\n", cnt);
24405+#undef msg
1facf9fc 24406+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
24407+ } else {
24408+ do_put_plink(tmp, 0);
24409+ return;
1facf9fc 24410+ }
24411+
4a4d8108 24412+out:
1facf9fc 24413+ if (unlikely(err)) {
0c3ec466 24414+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 24415+ if (tmp) {
86dc4139 24416+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
24417+ call_rcu(&tmp->rcu, do_put_plink_rcu);
24418+ }
1facf9fc 24419+ }
24420+}
24421+
24422+/* free all plinks */
e49829fe 24423+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 24424+{
86dc4139 24425+ int i, warned;
1facf9fc 24426+ struct au_sbinfo *sbinfo;
86dc4139
AM
24427+ struct hlist_head *plink_hlist;
24428+ struct hlist_node *tmp;
24429+ struct pseudo_link *plink;
1facf9fc 24430+
dece6358
AM
24431+ SiMustWriteLock(sb);
24432+
1facf9fc 24433+ sbinfo = au_sbi(sb);
24434+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24435+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24436+
1facf9fc 24437+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
24438+ warned = 0;
24439+ for (i = 0; i < AuPlink_NHASH; i++) {
24440+ plink_hlist = &sbinfo->si_plink[i].head;
24441+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
24442+ pr_warn("pseudo-link is not flushed");
24443+ warned = 1;
24444+ }
24445+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
24446+ do_put_plink(plink, 0);
24447+ INIT_HLIST_HEAD(plink_hlist);
24448+ }
1facf9fc 24449+}
24450+
e49829fe
JR
24451+void au_plink_clean(struct super_block *sb, int verbose)
24452+{
24453+ struct dentry *root;
24454+
24455+ root = sb->s_root;
24456+ aufs_write_lock(root);
24457+ if (au_opt_test(au_mntflags(sb), PLINK))
24458+ au_plink_put(sb, verbose);
24459+ aufs_write_unlock(root);
24460+}
24461+
86dc4139
AM
24462+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
24463+{
24464+ int do_put;
24465+ aufs_bindex_t bstart, bend, bindex;
24466+
24467+ do_put = 0;
24468+ bstart = au_ibstart(inode);
24469+ bend = au_ibend(inode);
24470+ if (bstart >= 0) {
24471+ for (bindex = bstart; bindex <= bend; bindex++) {
24472+ if (!au_h_iptr(inode, bindex)
24473+ || au_ii_br_id(inode, bindex) != br_id)
24474+ continue;
24475+ au_set_h_iptr(inode, bindex, NULL, 0);
24476+ do_put = 1;
24477+ break;
24478+ }
24479+ if (do_put)
24480+ for (bindex = bstart; bindex <= bend; bindex++)
24481+ if (au_h_iptr(inode, bindex)) {
24482+ do_put = 0;
24483+ break;
24484+ }
24485+ } else
24486+ do_put = 1;
24487+
24488+ return do_put;
24489+}
24490+
1facf9fc 24491+/* free the plinks on a branch specified by @br_id */
24492+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
24493+{
24494+ struct au_sbinfo *sbinfo;
86dc4139
AM
24495+ struct hlist_head *plink_hlist;
24496+ struct hlist_node *tmp;
24497+ struct pseudo_link *plink;
1facf9fc 24498+ struct inode *inode;
86dc4139 24499+ int i, do_put;
1facf9fc 24500+
dece6358
AM
24501+ SiMustWriteLock(sb);
24502+
1facf9fc 24503+ sbinfo = au_sbi(sb);
24504+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24505+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24506+
1facf9fc 24507+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
24508+ for (i = 0; i < AuPlink_NHASH; i++) {
24509+ plink_hlist = &sbinfo->si_plink[i].head;
24510+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
24511+ inode = au_igrab(plink->inode);
24512+ ii_write_lock_child(inode);
24513+ do_put = au_plink_do_half_refresh(inode, br_id);
dece6358
AM
24514+ if (do_put)
24515+ do_put_plink(plink, 1);
86dc4139
AM
24516+ ii_write_unlock(inode);
24517+ iput(inode);
dece6358 24518+ }
dece6358
AM
24519+ }
24520+}
7f207e10
AM
24521diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
24522--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
076b876e 24523+++ linux/fs/aufs/poll.c 2014-01-30 21:10:02.857481956 +0100
523b37e3 24524@@ -0,0 +1,55 @@
dece6358 24525+/*
523b37e3 24526+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
24527+ *
24528+ * This program, aufs is free software; you can redistribute it and/or modify
24529+ * it under the terms of the GNU General Public License as published by
24530+ * the Free Software Foundation; either version 2 of the License, or
24531+ * (at your option) any later version.
24532+ *
24533+ * This program is distributed in the hope that it will be useful,
24534+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24535+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24536+ * GNU General Public License for more details.
24537+ *
24538+ * You should have received a copy of the GNU General Public License
523b37e3 24539+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
24540+ */
24541+
1308ab2a 24542+/*
24543+ * poll operation
24544+ * There is only one filesystem which implements ->poll operation, currently.
24545+ */
24546+
24547+#include "aufs.h"
24548+
24549+unsigned int aufs_poll(struct file *file, poll_table *wait)
24550+{
24551+ unsigned int mask;
24552+ int err;
24553+ struct file *h_file;
24554+ struct dentry *dentry;
24555+ struct super_block *sb;
24556+
24557+ /* We should pretend an error happened. */
24558+ mask = POLLERR /* | POLLIN | POLLOUT */;
24559+ dentry = file->f_dentry;
24560+ sb = dentry->d_sb;
e49829fe 24561+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 24562+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
24563+ if (unlikely(err))
24564+ goto out;
24565+
24566+ /* it is not an error if h_file has no operation */
24567+ mask = DEFAULT_POLLMASK;
4a4d8108 24568+ h_file = au_hf_top(file);
523b37e3 24569+ if (h_file->f_op->poll)
1308ab2a 24570+ mask = h_file->f_op->poll(h_file, wait);
24571+
24572+ di_read_unlock(dentry, AuLock_IR);
24573+ fi_read_unlock(file);
24574+
4f0767ce 24575+out:
1308ab2a 24576+ si_read_unlock(sb);
24577+ AuTraceErr((int)mask);
24578+ return mask;
24579+}
7f207e10
AM
24580diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
24581--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
076b876e 24582+++ linux/fs/aufs/procfs.c 2014-01-30 21:10:02.857481956 +0100
523b37e3 24583@@ -0,0 +1,169 @@
e49829fe 24584+/*
523b37e3 24585+ * Copyright (C) 2010-2014 Junjiro R. Okajima
e49829fe
JR
24586+ *
24587+ * This program, aufs is free software; you can redistribute it and/or modify
24588+ * it under the terms of the GNU General Public License as published by
24589+ * the Free Software Foundation; either version 2 of the License, or
24590+ * (at your option) any later version.
24591+ *
24592+ * This program is distributed in the hope that it will be useful,
24593+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24594+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24595+ * GNU General Public License for more details.
24596+ *
24597+ * You should have received a copy of the GNU General Public License
523b37e3 24598+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
24599+ */
24600+
24601+/*
24602+ * procfs interfaces
24603+ */
24604+
24605+#include <linux/proc_fs.h>
24606+#include "aufs.h"
24607+
24608+static int au_procfs_plm_release(struct inode *inode, struct file *file)
24609+{
24610+ struct au_sbinfo *sbinfo;
24611+
24612+ sbinfo = file->private_data;
24613+ if (sbinfo) {
24614+ au_plink_maint_leave(sbinfo);
24615+ kobject_put(&sbinfo->si_kobj);
24616+ }
24617+
24618+ return 0;
24619+}
24620+
24621+static void au_procfs_plm_write_clean(struct file *file)
24622+{
24623+ struct au_sbinfo *sbinfo;
24624+
24625+ sbinfo = file->private_data;
24626+ if (sbinfo)
24627+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
24628+}
24629+
24630+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
24631+{
24632+ int err;
24633+ struct super_block *sb;
24634+ struct au_sbinfo *sbinfo;
24635+
24636+ err = -EBUSY;
24637+ if (unlikely(file->private_data))
24638+ goto out;
24639+
24640+ sb = NULL;
53392da6 24641+ /* don't use au_sbilist_lock() here */
e49829fe
JR
24642+ spin_lock(&au_sbilist.spin);
24643+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
24644+ if (id == sysaufs_si_id(sbinfo)) {
24645+ kobject_get(&sbinfo->si_kobj);
24646+ sb = sbinfo->si_sb;
24647+ break;
24648+ }
24649+ spin_unlock(&au_sbilist.spin);
24650+
24651+ err = -EINVAL;
24652+ if (unlikely(!sb))
24653+ goto out;
24654+
24655+ err = au_plink_maint_enter(sb);
24656+ if (!err)
24657+ /* keep kobject_get() */
24658+ file->private_data = sbinfo;
24659+ else
24660+ kobject_put(&sbinfo->si_kobj);
24661+out:
24662+ return err;
24663+}
24664+
24665+/*
24666+ * Accept a valid "si=xxxx" only.
24667+ * Once it is accepted successfully, accept "clean" too.
24668+ */
24669+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
24670+ size_t count, loff_t *ppos)
24671+{
24672+ ssize_t err;
24673+ unsigned long id;
24674+ /* last newline is allowed */
24675+ char buf[3 + sizeof(unsigned long) * 2 + 1];
24676+
24677+ err = -EACCES;
24678+ if (unlikely(!capable(CAP_SYS_ADMIN)))
24679+ goto out;
24680+
24681+ err = -EINVAL;
24682+ if (unlikely(count > sizeof(buf)))
24683+ goto out;
24684+
24685+ err = copy_from_user(buf, ubuf, count);
24686+ if (unlikely(err)) {
24687+ err = -EFAULT;
24688+ goto out;
24689+ }
24690+ buf[count] = 0;
24691+
24692+ err = -EINVAL;
24693+ if (!strcmp("clean", buf)) {
24694+ au_procfs_plm_write_clean(file);
24695+ goto out_success;
24696+ } else if (unlikely(strncmp("si=", buf, 3)))
24697+ goto out;
24698+
9dbd164d 24699+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
24700+ if (unlikely(err))
24701+ goto out;
24702+
24703+ err = au_procfs_plm_write_si(file, id);
24704+ if (unlikely(err))
24705+ goto out;
24706+
24707+out_success:
24708+ err = count; /* success */
24709+out:
24710+ return err;
24711+}
24712+
24713+static const struct file_operations au_procfs_plm_fop = {
24714+ .write = au_procfs_plm_write,
24715+ .release = au_procfs_plm_release,
24716+ .owner = THIS_MODULE
24717+};
24718+
24719+/* ---------------------------------------------------------------------- */
24720+
24721+static struct proc_dir_entry *au_procfs_dir;
24722+
24723+void au_procfs_fin(void)
24724+{
24725+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
24726+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
24727+}
24728+
24729+int __init au_procfs_init(void)
24730+{
24731+ int err;
24732+ struct proc_dir_entry *entry;
24733+
24734+ err = -ENOMEM;
24735+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
24736+ if (unlikely(!au_procfs_dir))
24737+ goto out;
24738+
24739+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
24740+ au_procfs_dir, &au_procfs_plm_fop);
24741+ if (unlikely(!entry))
24742+ goto out_dir;
24743+
24744+ err = 0;
24745+ goto out; /* success */
24746+
24747+
24748+out_dir:
24749+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
24750+out:
24751+ return err;
24752+}
7f207e10
AM
24753diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
24754--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
076b876e 24755+++ linux/fs/aufs/rdu.c 2014-01-30 21:10:02.857481956 +0100
523b37e3 24756@@ -0,0 +1,388 @@
1308ab2a 24757+/*
523b37e3 24758+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1308ab2a 24759+ *
24760+ * This program, aufs is free software; you can redistribute it and/or modify
24761+ * it under the terms of the GNU General Public License as published by
24762+ * the Free Software Foundation; either version 2 of the License, or
24763+ * (at your option) any later version.
24764+ *
24765+ * This program is distributed in the hope that it will be useful,
24766+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24767+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24768+ * GNU General Public License for more details.
24769+ *
24770+ * You should have received a copy of the GNU General Public License
523b37e3 24771+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 24772+ */
24773+
24774+/*
24775+ * readdir in userspace.
24776+ */
24777+
b752ccd1 24778+#include <linux/compat.h>
4a4d8108 24779+#include <linux/fs_stack.h>
1308ab2a 24780+#include <linux/security.h>
1308ab2a 24781+#include "aufs.h"
24782+
24783+/* bits for struct aufs_rdu.flags */
24784+#define AuRdu_CALLED 1
24785+#define AuRdu_CONT (1 << 1)
24786+#define AuRdu_FULL (1 << 2)
24787+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
24788+#define au_fset_rdu(flags, name) \
24789+ do { (flags) |= AuRdu_##name; } while (0)
24790+#define au_fclr_rdu(flags, name) \
24791+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 24792+
24793+struct au_rdu_arg {
392086de 24794+ struct dir_context ctx;
1308ab2a 24795+ struct aufs_rdu *rdu;
24796+ union au_rdu_ent_ul ent;
24797+ unsigned long end;
24798+
24799+ struct super_block *sb;
24800+ int err;
24801+};
24802+
392086de 24803+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 24804+ loff_t offset, u64 h_ino, unsigned int d_type)
24805+{
24806+ int err, len;
392086de 24807+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 24808+ struct aufs_rdu *rdu = arg->rdu;
24809+ struct au_rdu_ent ent;
24810+
24811+ err = 0;
24812+ arg->err = 0;
24813+ au_fset_rdu(rdu->cookie.flags, CALLED);
24814+ len = au_rdu_len(nlen);
24815+ if (arg->ent.ul + len < arg->end) {
24816+ ent.ino = h_ino;
24817+ ent.bindex = rdu->cookie.bindex;
24818+ ent.type = d_type;
24819+ ent.nlen = nlen;
4a4d8108
AM
24820+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
24821+ ent.type = DT_UNKNOWN;
1308ab2a 24822+
9dbd164d 24823+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 24824+ err = -EFAULT;
24825+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
24826+ goto out;
24827+ if (copy_to_user(arg->ent.e->name, name, nlen))
24828+ goto out;
24829+ /* the terminating NULL */
24830+ if (__put_user(0, arg->ent.e->name + nlen))
24831+ goto out;
24832+ err = 0;
24833+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
24834+ arg->ent.ul += len;
24835+ rdu->rent++;
24836+ } else {
24837+ err = -EFAULT;
24838+ au_fset_rdu(rdu->cookie.flags, FULL);
24839+ rdu->full = 1;
24840+ rdu->tail = arg->ent;
24841+ }
24842+
4f0767ce 24843+out:
1308ab2a 24844+ /* AuTraceErr(err); */
24845+ return err;
24846+}
24847+
24848+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
24849+{
24850+ int err;
24851+ loff_t offset;
24852+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
24853+
92d182d2 24854+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 24855+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
24856+ err = offset;
24857+ if (unlikely(offset != cookie->h_pos))
24858+ goto out;
24859+
24860+ err = 0;
24861+ do {
24862+ arg->err = 0;
24863+ au_fclr_rdu(cookie->flags, CALLED);
24864+ /* smp_mb(); */
392086de 24865+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 24866+ if (err >= 0)
24867+ err = arg->err;
24868+ } while (!err
24869+ && au_ftest_rdu(cookie->flags, CALLED)
24870+ && !au_ftest_rdu(cookie->flags, FULL));
24871+ cookie->h_pos = h_file->f_pos;
24872+
4f0767ce 24873+out:
1308ab2a 24874+ AuTraceErr(err);
24875+ return err;
24876+}
24877+
24878+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
24879+{
24880+ int err;
24881+ aufs_bindex_t bend;
392086de
AM
24882+ struct au_rdu_arg arg = {
24883+ .ctx = {
24884+ .actor = au_diractor(au_rdu_fill)
24885+ }
24886+ };
1308ab2a 24887+ struct dentry *dentry;
24888+ struct inode *inode;
24889+ struct file *h_file;
24890+ struct au_rdu_cookie *cookie = &rdu->cookie;
24891+
24892+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
24893+ if (unlikely(err)) {
24894+ err = -EFAULT;
24895+ AuTraceErr(err);
24896+ goto out;
24897+ }
24898+ rdu->rent = 0;
24899+ rdu->tail = rdu->ent;
24900+ rdu->full = 0;
24901+ arg.rdu = rdu;
24902+ arg.ent = rdu->ent;
24903+ arg.end = arg.ent.ul;
24904+ arg.end += rdu->sz;
24905+
24906+ err = -ENOTDIR;
523b37e3 24907+ if (unlikely(!file->f_op->iterate))
1308ab2a 24908+ goto out;
24909+
24910+ err = security_file_permission(file, MAY_READ);
24911+ AuTraceErr(err);
24912+ if (unlikely(err))
24913+ goto out;
24914+
24915+ dentry = file->f_dentry;
24916+ inode = dentry->d_inode;
24917+#if 1
24918+ mutex_lock(&inode->i_mutex);
24919+#else
24920+ err = mutex_lock_killable(&inode->i_mutex);
24921+ AuTraceErr(err);
24922+ if (unlikely(err))
24923+ goto out;
24924+#endif
1308ab2a 24925+
24926+ arg.sb = inode->i_sb;
e49829fe
JR
24927+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
24928+ if (unlikely(err))
24929+ goto out_mtx;
027c5e7a
AM
24930+ err = au_alive_dir(dentry);
24931+ if (unlikely(err))
24932+ goto out_si;
e49829fe 24933+ /* todo: reval? */
1308ab2a 24934+ fi_read_lock(file);
24935+
24936+ err = -EAGAIN;
24937+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
24938+ && cookie->generation != au_figen(file)))
24939+ goto out_unlock;
24940+
24941+ err = 0;
24942+ if (!rdu->blk) {
24943+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
24944+ if (!rdu->blk)
24945+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
24946+ }
24947+ bend = au_fbstart(file);
24948+ if (cookie->bindex < bend)
24949+ cookie->bindex = bend;
4a4d8108 24950+ bend = au_fbend_dir(file);
1308ab2a 24951+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
24952+ for (; !err && cookie->bindex <= bend;
24953+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 24954+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 24955+ if (!h_file)
24956+ continue;
24957+
24958+ au_fclr_rdu(cookie->flags, FULL);
24959+ err = au_rdu_do(h_file, &arg);
24960+ AuTraceErr(err);
24961+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
24962+ break;
24963+ }
24964+ AuDbg("rent %llu\n", rdu->rent);
24965+
24966+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
24967+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
24968+ au_fset_rdu(cookie->flags, CONT);
24969+ cookie->generation = au_figen(file);
24970+ }
24971+
24972+ ii_read_lock_child(inode);
24973+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
24974+ ii_read_unlock(inode);
24975+
4f0767ce 24976+out_unlock:
1308ab2a 24977+ fi_read_unlock(file);
027c5e7a 24978+out_si:
1308ab2a 24979+ si_read_unlock(arg.sb);
4f0767ce 24980+out_mtx:
1308ab2a 24981+ mutex_unlock(&inode->i_mutex);
4f0767ce 24982+out:
1308ab2a 24983+ AuTraceErr(err);
24984+ return err;
24985+}
24986+
24987+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
24988+{
24989+ int err;
24990+ ino_t ino;
24991+ unsigned long long nent;
24992+ union au_rdu_ent_ul *u;
24993+ struct au_rdu_ent ent;
24994+ struct super_block *sb;
24995+
24996+ err = 0;
24997+ nent = rdu->nent;
24998+ u = &rdu->ent;
24999+ sb = file->f_dentry->d_sb;
25000+ si_read_lock(sb, AuLock_FLUSH);
25001+ while (nent-- > 0) {
9dbd164d 25002+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25003+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
25004+ if (!err)
25005+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 25006+ if (unlikely(err)) {
25007+ err = -EFAULT;
25008+ AuTraceErr(err);
25009+ break;
25010+ }
25011+
25012+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
25013+ if (!ent.wh)
25014+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
25015+ else
25016+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
25017+ &ino);
25018+ if (unlikely(err)) {
25019+ AuTraceErr(err);
25020+ break;
25021+ }
25022+
25023+ err = __put_user(ino, &u->e->ino);
25024+ if (unlikely(err)) {
25025+ err = -EFAULT;
25026+ AuTraceErr(err);
25027+ break;
25028+ }
25029+ u->ul += au_rdu_len(ent.nlen);
25030+ }
25031+ si_read_unlock(sb);
25032+
25033+ return err;
25034+}
25035+
25036+/* ---------------------------------------------------------------------- */
25037+
25038+static int au_rdu_verify(struct aufs_rdu *rdu)
25039+{
b752ccd1 25040+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 25041+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 25042+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 25043+ rdu->blk,
25044+ rdu->rent, rdu->shwh, rdu->full,
25045+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
25046+ rdu->cookie.generation);
dece6358 25047+
b752ccd1 25048+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 25049+ return 0;
dece6358 25050+
b752ccd1
AM
25051+ AuDbg("%u:%u\n",
25052+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 25053+ return -EINVAL;
25054+}
25055+
25056+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 25057+{
1308ab2a 25058+ long err, e;
25059+ struct aufs_rdu rdu;
25060+ void __user *p = (void __user *)arg;
dece6358 25061+
1308ab2a 25062+ err = copy_from_user(&rdu, p, sizeof(rdu));
25063+ if (unlikely(err)) {
25064+ err = -EFAULT;
25065+ AuTraceErr(err);
25066+ goto out;
25067+ }
25068+ err = au_rdu_verify(&rdu);
dece6358
AM
25069+ if (unlikely(err))
25070+ goto out;
25071+
1308ab2a 25072+ switch (cmd) {
25073+ case AUFS_CTL_RDU:
25074+ err = au_rdu(file, &rdu);
25075+ if (unlikely(err))
25076+ break;
dece6358 25077+
1308ab2a 25078+ e = copy_to_user(p, &rdu, sizeof(rdu));
25079+ if (unlikely(e)) {
25080+ err = -EFAULT;
25081+ AuTraceErr(err);
25082+ }
25083+ break;
25084+ case AUFS_CTL_RDU_INO:
25085+ err = au_rdu_ino(file, &rdu);
25086+ break;
25087+
25088+ default:
4a4d8108 25089+ /* err = -ENOTTY; */
1308ab2a 25090+ err = -EINVAL;
25091+ }
dece6358 25092+
4f0767ce 25093+out:
1308ab2a 25094+ AuTraceErr(err);
25095+ return err;
1facf9fc 25096+}
b752ccd1
AM
25097+
25098+#ifdef CONFIG_COMPAT
25099+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
25100+{
25101+ long err, e;
25102+ struct aufs_rdu rdu;
25103+ void __user *p = compat_ptr(arg);
25104+
25105+ /* todo: get_user()? */
25106+ err = copy_from_user(&rdu, p, sizeof(rdu));
25107+ if (unlikely(err)) {
25108+ err = -EFAULT;
25109+ AuTraceErr(err);
25110+ goto out;
25111+ }
25112+ rdu.ent.e = compat_ptr(rdu.ent.ul);
25113+ err = au_rdu_verify(&rdu);
25114+ if (unlikely(err))
25115+ goto out;
25116+
25117+ switch (cmd) {
25118+ case AUFS_CTL_RDU:
25119+ err = au_rdu(file, &rdu);
25120+ if (unlikely(err))
25121+ break;
25122+
25123+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
25124+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
25125+ e = copy_to_user(p, &rdu, sizeof(rdu));
25126+ if (unlikely(e)) {
25127+ err = -EFAULT;
25128+ AuTraceErr(err);
25129+ }
25130+ break;
25131+ case AUFS_CTL_RDU_INO:
25132+ err = au_rdu_ino(file, &rdu);
25133+ break;
25134+
25135+ default:
25136+ /* err = -ENOTTY; */
25137+ err = -EINVAL;
25138+ }
25139+
4f0767ce 25140+out:
b752ccd1
AM
25141+ AuTraceErr(err);
25142+ return err;
25143+}
25144+#endif
7f207e10
AM
25145diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
25146--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
25147+++ linux/fs/aufs/rwsem.h 2014-08-14 10:15:45.128609525 +0200
25148@@ -0,0 +1,191 @@
1facf9fc 25149+/*
523b37e3 25150+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25151+ *
25152+ * This program, aufs is free software; you can redistribute it and/or modify
25153+ * it under the terms of the GNU General Public License as published by
25154+ * the Free Software Foundation; either version 2 of the License, or
25155+ * (at your option) any later version.
dece6358
AM
25156+ *
25157+ * This program is distributed in the hope that it will be useful,
25158+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25159+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25160+ * GNU General Public License for more details.
25161+ *
25162+ * You should have received a copy of the GNU General Public License
523b37e3 25163+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25164+ */
25165+
25166+/*
25167+ * simple read-write semaphore wrappers
25168+ */
25169+
25170+#ifndef __AUFS_RWSEM_H__
25171+#define __AUFS_RWSEM_H__
25172+
25173+#ifdef __KERNEL__
25174+
4a4d8108 25175+#include "debug.h"
dece6358
AM
25176+
25177+struct au_rwsem {
25178+ struct rw_semaphore rwsem;
25179+#ifdef CONFIG_AUFS_DEBUG
25180+ /* just for debugging, not almighty counter */
25181+ atomic_t rcnt, wcnt;
25182+#endif
25183+};
25184+
25185+#ifdef CONFIG_AUFS_DEBUG
25186+#define AuDbgCntInit(rw) do { \
25187+ atomic_set(&(rw)->rcnt, 0); \
25188+ atomic_set(&(rw)->wcnt, 0); \
25189+ smp_mb(); /* atomic set */ \
25190+} while (0)
25191+
e49829fe 25192+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 25193+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 25194+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
25195+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
25196+#else
25197+#define AuDbgCntInit(rw) do {} while (0)
25198+#define AuDbgRcntInc(rw) do {} while (0)
25199+#define AuDbgRcntDec(rw) do {} while (0)
25200+#define AuDbgWcntInc(rw) do {} while (0)
25201+#define AuDbgWcntDec(rw) do {} while (0)
25202+#endif /* CONFIG_AUFS_DEBUG */
25203+
25204+/* to debug easier, do not make them inlined functions */
25205+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
25206+/* rwsem_is_locked() is unusable */
25207+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
25208+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
25209+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
25210+ && atomic_read(&(rw)->wcnt) <= 0)
25211+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
25212+ || atomic_read(&(rw)->wcnt))
25213+
e49829fe
JR
25214+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
25215+
dece6358
AM
25216+static inline void au_rw_init(struct au_rwsem *rw)
25217+{
25218+ AuDbgCntInit(rw);
25219+ init_rwsem(&rw->rwsem);
25220+}
25221+
25222+static inline void au_rw_init_wlock(struct au_rwsem *rw)
25223+{
25224+ au_rw_init(rw);
25225+ down_write(&rw->rwsem);
25226+ AuDbgWcntInc(rw);
25227+}
25228+
25229+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
25230+ unsigned int lsc)
25231+{
25232+ au_rw_init(rw);
25233+ down_write_nested(&rw->rwsem, lsc);
25234+ AuDbgWcntInc(rw);
25235+}
25236+
25237+static inline void au_rw_read_lock(struct au_rwsem *rw)
25238+{
25239+ down_read(&rw->rwsem);
25240+ AuDbgRcntInc(rw);
25241+}
25242+
25243+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
25244+{
25245+ down_read_nested(&rw->rwsem, lsc);
25246+ AuDbgRcntInc(rw);
25247+}
25248+
25249+static inline void au_rw_read_unlock(struct au_rwsem *rw)
25250+{
25251+ AuRwMustReadLock(rw);
25252+ AuDbgRcntDec(rw);
25253+ up_read(&rw->rwsem);
25254+}
25255+
25256+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
25257+{
25258+ AuRwMustWriteLock(rw);
25259+ AuDbgRcntInc(rw);
25260+ AuDbgWcntDec(rw);
25261+ downgrade_write(&rw->rwsem);
25262+}
25263+
25264+static inline void au_rw_write_lock(struct au_rwsem *rw)
25265+{
25266+ down_write(&rw->rwsem);
25267+ AuDbgWcntInc(rw);
25268+}
25269+
25270+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
25271+ unsigned int lsc)
25272+{
25273+ down_write_nested(&rw->rwsem, lsc);
25274+ AuDbgWcntInc(rw);
25275+}
1facf9fc 25276+
dece6358
AM
25277+static inline void au_rw_write_unlock(struct au_rwsem *rw)
25278+{
25279+ AuRwMustWriteLock(rw);
25280+ AuDbgWcntDec(rw);
25281+ up_write(&rw->rwsem);
25282+}
25283+
25284+/* why is not _nested version defined */
25285+static inline int au_rw_read_trylock(struct au_rwsem *rw)
25286+{
076b876e
AM
25287+ int ret;
25288+
25289+ ret = down_read_trylock(&rw->rwsem);
dece6358
AM
25290+ if (ret)
25291+ AuDbgRcntInc(rw);
25292+ return ret;
25293+}
25294+
25295+static inline int au_rw_write_trylock(struct au_rwsem *rw)
25296+{
076b876e
AM
25297+ int ret;
25298+
25299+ ret = down_write_trylock(&rw->rwsem);
dece6358
AM
25300+ if (ret)
25301+ AuDbgWcntInc(rw);
25302+ return ret;
25303+}
25304+
25305+#undef AuDbgCntInit
25306+#undef AuDbgRcntInc
25307+#undef AuDbgRcntDec
25308+#undef AuDbgWcntInc
25309+#undef AuDbgWcntDec
1facf9fc 25310+
25311+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
25312+static inline void prefix##_read_lock(param) \
dece6358 25313+{ au_rw_read_lock(rwsem); } \
1facf9fc 25314+static inline void prefix##_write_lock(param) \
dece6358 25315+{ au_rw_write_lock(rwsem); } \
1facf9fc 25316+static inline int prefix##_read_trylock(param) \
dece6358 25317+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 25318+static inline int prefix##_write_trylock(param) \
dece6358 25319+{ return au_rw_write_trylock(rwsem); }
1facf9fc 25320+/* why is not _nested version defined */
25321+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 25322+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 25323+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 25324+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 25325+
25326+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
25327+static inline void prefix##_read_unlock(param) \
dece6358 25328+{ au_rw_read_unlock(rwsem); } \
1facf9fc 25329+static inline void prefix##_write_unlock(param) \
dece6358 25330+{ au_rw_write_unlock(rwsem); } \
1facf9fc 25331+static inline void prefix##_downgrade_lock(param) \
dece6358 25332+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 25333+
25334+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
25335+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
25336+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
25337+
25338+#endif /* __KERNEL__ */
25339+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
25340diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
25341--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
25342+++ linux/fs/aufs/sbinfo.c 2014-08-14 10:15:45.128609525 +0200
25343@@ -0,0 +1,353 @@
1facf9fc 25344+/*
523b37e3 25345+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25346+ *
25347+ * This program, aufs is free software; you can redistribute it and/or modify
25348+ * it under the terms of the GNU General Public License as published by
25349+ * the Free Software Foundation; either version 2 of the License, or
25350+ * (at your option) any later version.
dece6358
AM
25351+ *
25352+ * This program is distributed in the hope that it will be useful,
25353+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25354+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25355+ * GNU General Public License for more details.
25356+ *
25357+ * You should have received a copy of the GNU General Public License
523b37e3 25358+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25359+ */
25360+
25361+/*
25362+ * superblock private data
25363+ */
25364+
25365+#include "aufs.h"
25366+
25367+/*
25368+ * they are necessary regardless sysfs is disabled.
25369+ */
25370+void au_si_free(struct kobject *kobj)
25371+{
86dc4139 25372+ int i;
1facf9fc 25373+ struct au_sbinfo *sbinfo;
b752ccd1 25374+ char *locked __maybe_unused; /* debug only */
1facf9fc 25375+
25376+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
25377+ for (i = 0; i < AuPlink_NHASH; i++)
25378+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 25379+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 25380+
e49829fe 25381+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 25382+ au_br_free(sbinfo);
e49829fe 25383+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
25384+
25385+ AuDebugOn(radix_tree_gang_lookup
25386+ (&sbinfo->au_si_pid.tree, (void **)&locked,
25387+ /*first_index*/PID_MAX_DEFAULT - 1,
25388+ /*max_items*/sizeof(locked)/sizeof(*locked)));
25389+
1facf9fc 25390+ kfree(sbinfo->si_branch);
b752ccd1 25391+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 25392+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 25393+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 25394+
25395+ kfree(sbinfo);
25396+}
25397+
25398+int au_si_alloc(struct super_block *sb)
25399+{
86dc4139 25400+ int err, i;
1facf9fc 25401+ struct au_sbinfo *sbinfo;
e49829fe 25402+ static struct lock_class_key aufs_si;
1facf9fc 25403+
25404+ err = -ENOMEM;
4a4d8108 25405+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 25406+ if (unlikely(!sbinfo))
25407+ goto out;
25408+
b752ccd1
AM
25409+ BUILD_BUG_ON(sizeof(unsigned long) !=
25410+ sizeof(*sbinfo->au_si_pid.bitmap));
25411+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
25412+ sizeof(*sbinfo->au_si_pid.bitmap),
25413+ GFP_NOFS);
25414+ if (unlikely(!sbinfo->au_si_pid.bitmap))
25415+ goto out_sbinfo;
25416+
1facf9fc 25417+ /* will be reallocated separately */
25418+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
25419+ if (unlikely(!sbinfo->si_branch))
b752ccd1 25420+ goto out_pidmap;
1facf9fc 25421+
1facf9fc 25422+ err = sysaufs_si_init(sbinfo);
25423+ if (unlikely(err))
25424+ goto out_br;
25425+
25426+ au_nwt_init(&sbinfo->si_nowait);
dece6358 25427+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 25428+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
25429+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
25430+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
25431+
7f207e10 25432+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
25433+ atomic_long_set(&sbinfo->si_nfiles, 0);
25434+
1facf9fc 25435+ sbinfo->si_bend = -1;
392086de 25436+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 25437+
25438+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
25439+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
25440+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
25441+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 25442+
076b876e
AM
25443+ au_fhsm_init(sbinfo);
25444+
e49829fe 25445+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 25446+
392086de
AM
25447+ sbinfo->si_xino_jiffy = jiffies;
25448+ sbinfo->si_xino_expire
25449+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 25450+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 25451+ sbinfo->si_xino_brid = -1;
25452+ /* leave si_xib_last_pindex and si_xib_next_bit */
25453+
e49829fe 25454+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 25455+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
25456+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
25457+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
25458+
86dc4139
AM
25459+ for (i = 0; i < AuPlink_NHASH; i++)
25460+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 25461+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 25462+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 25463+
523b37e3
AM
25464+ au_sphl_init(&sbinfo->si_files);
25465+
1facf9fc 25466+ /* leave other members for sysaufs and si_mnt. */
25467+ sbinfo->si_sb = sb;
25468+ sb->s_fs_info = sbinfo;
b752ccd1 25469+ si_pid_set(sb);
1facf9fc 25470+ au_debug_sbinfo_init(sbinfo);
25471+ return 0; /* success */
25472+
4f0767ce 25473+out_br:
1facf9fc 25474+ kfree(sbinfo->si_branch);
4f0767ce 25475+out_pidmap:
b752ccd1 25476+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 25477+out_sbinfo:
1facf9fc 25478+ kfree(sbinfo);
4f0767ce 25479+out:
1facf9fc 25480+ return err;
25481+}
25482+
25483+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
25484+{
25485+ int err, sz;
25486+ struct au_branch **brp;
25487+
dece6358
AM
25488+ AuRwMustWriteLock(&sbinfo->si_rwsem);
25489+
1facf9fc 25490+ err = -ENOMEM;
25491+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
25492+ if (unlikely(!sz))
25493+ sz = sizeof(*brp);
25494+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
25495+ if (brp) {
25496+ sbinfo->si_branch = brp;
25497+ err = 0;
25498+ }
25499+
25500+ return err;
25501+}
25502+
25503+/* ---------------------------------------------------------------------- */
25504+
25505+unsigned int au_sigen_inc(struct super_block *sb)
25506+{
25507+ unsigned int gen;
25508+
dece6358
AM
25509+ SiMustWriteLock(sb);
25510+
1facf9fc 25511+ gen = ++au_sbi(sb)->si_generation;
25512+ au_update_digen(sb->s_root);
537831f9 25513+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 25514+ sb->s_root->d_inode->i_version++;
25515+ return gen;
25516+}
25517+
25518+aufs_bindex_t au_new_br_id(struct super_block *sb)
25519+{
25520+ aufs_bindex_t br_id;
25521+ int i;
25522+ struct au_sbinfo *sbinfo;
25523+
dece6358
AM
25524+ SiMustWriteLock(sb);
25525+
1facf9fc 25526+ sbinfo = au_sbi(sb);
25527+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
25528+ br_id = ++sbinfo->si_last_br_id;
7f207e10 25529+ AuDebugOn(br_id < 0);
1facf9fc 25530+ if (br_id && au_br_index(sb, br_id) < 0)
25531+ return br_id;
25532+ }
25533+
25534+ return -1;
25535+}
25536+
25537+/* ---------------------------------------------------------------------- */
25538+
e49829fe
JR
25539+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
25540+int si_read_lock(struct super_block *sb, int flags)
25541+{
25542+ int err;
25543+
25544+ err = 0;
25545+ if (au_ftest_lock(flags, FLUSH))
25546+ au_nwt_flush(&au_sbi(sb)->si_nowait);
25547+
25548+ si_noflush_read_lock(sb);
25549+ err = au_plink_maint(sb, flags);
25550+ if (unlikely(err))
25551+ si_read_unlock(sb);
25552+
25553+ return err;
25554+}
25555+
25556+int si_write_lock(struct super_block *sb, int flags)
25557+{
25558+ int err;
25559+
25560+ if (au_ftest_lock(flags, FLUSH))
25561+ au_nwt_flush(&au_sbi(sb)->si_nowait);
25562+
25563+ si_noflush_write_lock(sb);
25564+ err = au_plink_maint(sb, flags);
25565+ if (unlikely(err))
25566+ si_write_unlock(sb);
25567+
25568+ return err;
25569+}
25570+
1facf9fc 25571+/* dentry and super_block lock. call at entry point */
e49829fe 25572+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 25573+{
e49829fe 25574+ int err;
027c5e7a 25575+ struct super_block *sb;
e49829fe 25576+
027c5e7a
AM
25577+ sb = dentry->d_sb;
25578+ err = si_read_lock(sb, flags);
25579+ if (unlikely(err))
25580+ goto out;
25581+
25582+ if (au_ftest_lock(flags, DW))
25583+ di_write_lock_child(dentry);
25584+ else
25585+ di_read_lock_child(dentry, flags);
25586+
25587+ if (au_ftest_lock(flags, GEN)) {
25588+ err = au_digen_test(dentry, au_sigen(sb));
25589+ AuDebugOn(!err && au_dbrange_test(dentry));
25590+ if (unlikely(err))
25591+ aufs_read_unlock(dentry, flags);
e49829fe
JR
25592+ }
25593+
027c5e7a 25594+out:
e49829fe 25595+ return err;
1facf9fc 25596+}
25597+
25598+void aufs_read_unlock(struct dentry *dentry, int flags)
25599+{
25600+ if (au_ftest_lock(flags, DW))
25601+ di_write_unlock(dentry);
25602+ else
25603+ di_read_unlock(dentry, flags);
25604+ si_read_unlock(dentry->d_sb);
25605+}
25606+
25607+void aufs_write_lock(struct dentry *dentry)
25608+{
e49829fe 25609+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 25610+ di_write_lock_child(dentry);
25611+}
25612+
25613+void aufs_write_unlock(struct dentry *dentry)
25614+{
25615+ di_write_unlock(dentry);
25616+ si_write_unlock(dentry->d_sb);
25617+}
25618+
e49829fe 25619+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 25620+{
e49829fe 25621+ int err;
027c5e7a
AM
25622+ unsigned int sigen;
25623+ struct super_block *sb;
e49829fe 25624+
027c5e7a
AM
25625+ sb = d1->d_sb;
25626+ err = si_read_lock(sb, flags);
25627+ if (unlikely(err))
25628+ goto out;
25629+
25630+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
25631+
25632+ if (au_ftest_lock(flags, GEN)) {
25633+ sigen = au_sigen(sb);
25634+ err = au_digen_test(d1, sigen);
25635+ AuDebugOn(!err && au_dbrange_test(d1));
25636+ if (!err) {
25637+ err = au_digen_test(d2, sigen);
25638+ AuDebugOn(!err && au_dbrange_test(d2));
25639+ }
25640+ if (unlikely(err))
25641+ aufs_read_and_write_unlock2(d1, d2);
25642+ }
25643+
25644+out:
e49829fe 25645+ return err;
1facf9fc 25646+}
25647+
25648+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
25649+{
25650+ di_write_unlock2(d1, d2);
25651+ si_read_unlock(d1->d_sb);
25652+}
b752ccd1
AM
25653+
25654+/* ---------------------------------------------------------------------- */
25655+
25656+int si_pid_test_slow(struct super_block *sb)
25657+{
25658+ void *p;
25659+
25660+ rcu_read_lock();
25661+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
25662+ rcu_read_unlock();
25663+
027c5e7a 25664+ return (long)!!p;
b752ccd1
AM
25665+}
25666+
25667+void si_pid_set_slow(struct super_block *sb)
25668+{
25669+ int err;
25670+ struct au_sbinfo *sbinfo;
25671+
25672+ AuDebugOn(si_pid_test_slow(sb));
25673+
25674+ sbinfo = au_sbi(sb);
25675+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
25676+ AuDebugOn(err);
25677+ spin_lock(&sbinfo->au_si_pid.tree_lock);
25678+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 25679+ /*any valid ptr*/sb);
b752ccd1
AM
25680+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
25681+ AuDebugOn(err);
25682+ radix_tree_preload_end();
25683+}
25684+
25685+void si_pid_clr_slow(struct super_block *sb)
25686+{
25687+ void *p;
25688+ struct au_sbinfo *sbinfo;
25689+
25690+ AuDebugOn(!si_pid_test_slow(sb));
25691+
25692+ sbinfo = au_sbi(sb);
25693+ spin_lock(&sbinfo->au_si_pid.tree_lock);
25694+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
25695+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 25696+}
7f207e10
AM
25697diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
25698--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
076b876e 25699+++ linux/fs/aufs/spl.h 2014-01-30 21:10:02.857481956 +0100
523b37e3 25700@@ -0,0 +1,111 @@
1facf9fc 25701+/*
523b37e3 25702+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25703+ *
25704+ * This program, aufs is free software; you can redistribute it and/or modify
25705+ * it under the terms of the GNU General Public License as published by
25706+ * the Free Software Foundation; either version 2 of the License, or
25707+ * (at your option) any later version.
dece6358
AM
25708+ *
25709+ * This program is distributed in the hope that it will be useful,
25710+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25711+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25712+ * GNU General Public License for more details.
25713+ *
25714+ * You should have received a copy of the GNU General Public License
523b37e3 25715+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25716+ */
25717+
25718+/*
25719+ * simple list protected by a spinlock
25720+ */
25721+
25722+#ifndef __AUFS_SPL_H__
25723+#define __AUFS_SPL_H__
25724+
25725+#ifdef __KERNEL__
25726+
1facf9fc 25727+struct au_splhead {
25728+ spinlock_t spin;
25729+ struct list_head head;
25730+};
25731+
25732+static inline void au_spl_init(struct au_splhead *spl)
25733+{
25734+ spin_lock_init(&spl->spin);
25735+ INIT_LIST_HEAD(&spl->head);
25736+}
25737+
25738+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
25739+{
25740+ spin_lock(&spl->spin);
25741+ list_add(list, &spl->head);
25742+ spin_unlock(&spl->spin);
25743+}
25744+
25745+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
25746+{
25747+ spin_lock(&spl->spin);
25748+ list_del(list);
25749+ spin_unlock(&spl->spin);
25750+}
25751+
4a4d8108
AM
25752+static inline void au_spl_del_rcu(struct list_head *list,
25753+ struct au_splhead *spl)
25754+{
25755+ spin_lock(&spl->spin);
25756+ list_del_rcu(list);
25757+ spin_unlock(&spl->spin);
25758+}
25759+
86dc4139
AM
25760+/* ---------------------------------------------------------------------- */
25761+
25762+struct au_sphlhead {
25763+ spinlock_t spin;
25764+ struct hlist_head head;
25765+};
25766+
25767+static inline void au_sphl_init(struct au_sphlhead *sphl)
25768+{
25769+ spin_lock_init(&sphl->spin);
25770+ INIT_HLIST_HEAD(&sphl->head);
25771+}
25772+
25773+static inline void au_sphl_add(struct hlist_node *hlist,
25774+ struct au_sphlhead *sphl)
25775+{
25776+ spin_lock(&sphl->spin);
25777+ hlist_add_head(hlist, &sphl->head);
25778+ spin_unlock(&sphl->spin);
25779+}
25780+
25781+static inline void au_sphl_del(struct hlist_node *hlist,
25782+ struct au_sphlhead *sphl)
25783+{
25784+ spin_lock(&sphl->spin);
25785+ hlist_del(hlist);
25786+ spin_unlock(&sphl->spin);
25787+}
25788+
25789+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
25790+ struct au_sphlhead *sphl)
25791+{
25792+ spin_lock(&sphl->spin);
25793+ hlist_del_rcu(hlist);
25794+ spin_unlock(&sphl->spin);
25795+}
25796+
25797+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
25798+{
25799+ unsigned long cnt;
25800+ struct hlist_node *pos;
25801+
25802+ cnt = 0;
25803+ spin_lock(&sphl->spin);
25804+ hlist_for_each(pos, &sphl->head)
25805+ cnt++;
25806+ spin_unlock(&sphl->spin);
25807+ return cnt;
25808+}
25809+
1facf9fc 25810+#endif /* __KERNEL__ */
25811+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
25812diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
25813--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
25814+++ linux/fs/aufs/super.c 2014-08-14 10:15:45.131942973 +0200
25815@@ -0,0 +1,1004 @@
1facf9fc 25816+/*
523b37e3 25817+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25818+ *
25819+ * This program, aufs is free software; you can redistribute it and/or modify
25820+ * it under the terms of the GNU General Public License as published by
25821+ * the Free Software Foundation; either version 2 of the License, or
25822+ * (at your option) any later version.
dece6358
AM
25823+ *
25824+ * This program is distributed in the hope that it will be useful,
25825+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25826+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25827+ * GNU General Public License for more details.
25828+ *
25829+ * You should have received a copy of the GNU General Public License
523b37e3 25830+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25831+ */
25832+
25833+/*
25834+ * mount and super_block operations
25835+ */
25836+
f6c5ef8b 25837+#include <linux/mm.h>
dece6358 25838+#include <linux/module.h>
1facf9fc 25839+#include <linux/seq_file.h>
25840+#include <linux/statfs.h>
7f207e10
AM
25841+#include <linux/vmalloc.h>
25842+#include <linux/writeback.h>
1facf9fc 25843+#include "aufs.h"
25844+
25845+/*
25846+ * super_operations
25847+ */
25848+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
25849+{
25850+ struct au_icntnr *c;
25851+
25852+ c = au_cache_alloc_icntnr();
25853+ if (c) {
027c5e7a 25854+ au_icntnr_init(c);
1facf9fc 25855+ c->vfs_inode.i_version = 1; /* sigen(sb); */
25856+ c->iinfo.ii_hinode = NULL;
25857+ return &c->vfs_inode;
25858+ }
25859+ return NULL;
25860+}
25861+
027c5e7a
AM
25862+static void aufs_destroy_inode_cb(struct rcu_head *head)
25863+{
25864+ struct inode *inode = container_of(head, struct inode, i_rcu);
25865+
b4510431 25866+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
25867+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
25868+}
25869+
1facf9fc 25870+static void aufs_destroy_inode(struct inode *inode)
25871+{
25872+ au_iinfo_fin(inode);
027c5e7a 25873+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 25874+}
25875+
25876+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
25877+{
25878+ struct inode *inode;
25879+ int err;
25880+
25881+ inode = iget_locked(sb, ino);
25882+ if (unlikely(!inode)) {
25883+ inode = ERR_PTR(-ENOMEM);
25884+ goto out;
25885+ }
25886+ if (!(inode->i_state & I_NEW))
25887+ goto out;
25888+
25889+ err = au_xigen_new(inode);
25890+ if (!err)
25891+ err = au_iinfo_init(inode);
25892+ if (!err)
25893+ inode->i_version++;
25894+ else {
25895+ iget_failed(inode);
25896+ inode = ERR_PTR(err);
25897+ }
25898+
4f0767ce 25899+out:
1facf9fc 25900+ /* never return NULL */
25901+ AuDebugOn(!inode);
25902+ AuTraceErrPtr(inode);
25903+ return inode;
25904+}
25905+
25906+/* lock free root dinfo */
25907+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
25908+{
25909+ int err;
25910+ aufs_bindex_t bindex, bend;
25911+ struct path path;
4a4d8108 25912+ struct au_hdentry *hdp;
1facf9fc 25913+ struct au_branch *br;
076b876e 25914+ au_br_perm_str_t perm;
1facf9fc 25915+
25916+ err = 0;
25917+ bend = au_sbend(sb);
4a4d8108 25918+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 25919+ for (bindex = 0; !err && bindex <= bend; bindex++) {
25920+ br = au_sbr(sb, bindex);
86dc4139 25921+ path.mnt = au_br_mnt(br);
4a4d8108 25922+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 25923+ err = au_seq_path(seq, &path);
1e00d052 25924+ if (err > 0) {
076b876e
AM
25925+ au_optstr_br_perm(&perm, br->br_perm);
25926+ err = seq_printf(seq, "=%s", perm.a);
25927+ if (err == -1)
25928+ err = -E2BIG;
1e00d052 25929+ }
1facf9fc 25930+ if (!err && bindex != bend)
25931+ err = seq_putc(seq, ':');
25932+ }
25933+
25934+ return err;
25935+}
25936+
25937+static void au_show_wbr_create(struct seq_file *m, int v,
25938+ struct au_sbinfo *sbinfo)
25939+{
25940+ const char *pat;
25941+
dece6358
AM
25942+ AuRwMustAnyLock(&sbinfo->si_rwsem);
25943+
c2b27bf2 25944+ seq_puts(m, ",create=");
1facf9fc 25945+ pat = au_optstr_wbr_create(v);
25946+ switch (v) {
25947+ case AuWbrCreate_TDP:
25948+ case AuWbrCreate_RR:
25949+ case AuWbrCreate_MFS:
25950+ case AuWbrCreate_PMFS:
c2b27bf2 25951+ seq_puts(m, pat);
1facf9fc 25952+ break;
25953+ case AuWbrCreate_MFSV:
25954+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
25955+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
25956+ / MSEC_PER_SEC);
1facf9fc 25957+ break;
25958+ case AuWbrCreate_PMFSV:
25959+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
25960+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
25961+ / MSEC_PER_SEC);
1facf9fc 25962+ break;
25963+ case AuWbrCreate_MFSRR:
25964+ seq_printf(m, /*pat*/"mfsrr:%llu",
25965+ sbinfo->si_wbr_mfs.mfsrr_watermark);
25966+ break;
25967+ case AuWbrCreate_MFSRRV:
25968+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
25969+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
25970+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
25971+ / MSEC_PER_SEC);
1facf9fc 25972+ break;
392086de
AM
25973+ case AuWbrCreate_PMFSRR:
25974+ seq_printf(m, /*pat*/"pmfsrr:%llu",
25975+ sbinfo->si_wbr_mfs.mfsrr_watermark);
25976+ break;
25977+ case AuWbrCreate_PMFSRRV:
25978+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
25979+ sbinfo->si_wbr_mfs.mfsrr_watermark,
25980+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
25981+ / MSEC_PER_SEC);
25982+ break;
1facf9fc 25983+ }
25984+}
25985+
7eafdf33 25986+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 25987+{
25988+#ifdef CONFIG_SYSFS
25989+ return 0;
25990+#else
25991+ int err;
25992+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
25993+ aufs_bindex_t bindex, brid;
1facf9fc 25994+ struct qstr *name;
25995+ struct file *f;
25996+ struct dentry *d, *h_root;
4a4d8108 25997+ struct au_hdentry *hdp;
1facf9fc 25998+
dece6358
AM
25999+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26000+
1facf9fc 26001+ err = 0;
1facf9fc 26002+ f = au_sbi(sb)->si_xib;
26003+ if (!f)
26004+ goto out;
26005+
26006+ /* stop printing the default xino path on the first writable branch */
26007+ h_root = NULL;
26008+ brid = au_xino_brid(sb);
26009+ if (brid >= 0) {
26010+ bindex = au_br_index(sb, brid);
4a4d8108
AM
26011+ hdp = au_di(sb->s_root)->di_hdentry;
26012+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 26013+ }
26014+ d = f->f_dentry;
26015+ name = &d->d_name;
26016+ /* safe ->d_parent because the file is unlinked */
26017+ if (d->d_parent == h_root
26018+ && name->len == len
26019+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
26020+ goto out;
26021+
26022+ seq_puts(seq, ",xino=");
26023+ err = au_xino_path(seq, f);
26024+
4f0767ce 26025+out:
1facf9fc 26026+ return err;
26027+#endif
26028+}
26029+
26030+/* seq_file will re-call me in case of too long string */
7eafdf33 26031+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 26032+{
027c5e7a 26033+ int err;
1facf9fc 26034+ unsigned int mnt_flags, v;
26035+ struct super_block *sb;
26036+ struct au_sbinfo *sbinfo;
26037+
26038+#define AuBool(name, str) do { \
26039+ v = au_opt_test(mnt_flags, name); \
26040+ if (v != au_opt_test(AuOpt_Def, name)) \
26041+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
26042+} while (0)
26043+
26044+#define AuStr(name, str) do { \
26045+ v = mnt_flags & AuOptMask_##name; \
26046+ if (v != (AuOpt_Def & AuOptMask_##name)) \
26047+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
26048+} while (0)
26049+
26050+#define AuUInt(name, str, val) do { \
26051+ if (val != AUFS_##name##_DEF) \
26052+ seq_printf(m, "," #str "=%u", val); \
26053+} while (0)
26054+
26055+ /* lock free root dinfo */
7eafdf33 26056+ sb = dentry->d_sb;
1facf9fc 26057+ si_noflush_read_lock(sb);
26058+ sbinfo = au_sbi(sb);
26059+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
26060+
26061+ mnt_flags = au_mntflags(sb);
26062+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 26063+ err = au_show_xino(m, sb);
1facf9fc 26064+ if (unlikely(err))
26065+ goto out;
26066+ } else
26067+ seq_puts(m, ",noxino");
26068+
26069+ AuBool(TRUNC_XINO, trunc_xino);
26070+ AuStr(UDBA, udba);
dece6358 26071+ AuBool(SHWH, shwh);
1facf9fc 26072+ AuBool(PLINK, plink);
4a4d8108 26073+ AuBool(DIO, dio);
076b876e 26074+ AuBool(DIRPERM1, dirperm1);
1facf9fc 26075+ /* AuBool(REFROF, refrof); */
26076+
26077+ v = sbinfo->si_wbr_create;
26078+ if (v != AuWbrCreate_Def)
26079+ au_show_wbr_create(m, v, sbinfo);
26080+
26081+ v = sbinfo->si_wbr_copyup;
26082+ if (v != AuWbrCopyup_Def)
26083+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
26084+
26085+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
26086+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
26087+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
26088+
26089+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
26090+
027c5e7a
AM
26091+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
26092+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 26093+
26094+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
26095+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
26096+
076b876e
AM
26097+ au_fhsm_show(m, sbinfo);
26098+
1facf9fc 26099+ AuBool(SUM, sum);
26100+ /* AuBool(SUM_W, wsum); */
26101+ AuBool(WARN_PERM, warn_perm);
26102+ AuBool(VERBOSE, verbose);
26103+
4f0767ce 26104+out:
1facf9fc 26105+ /* be sure to print "br:" last */
26106+ if (!sysaufs_brs) {
26107+ seq_puts(m, ",br:");
26108+ au_show_brs(m, sb);
26109+ }
26110+ si_read_unlock(sb);
26111+ return 0;
26112+
1facf9fc 26113+#undef AuBool
26114+#undef AuStr
4a4d8108 26115+#undef AuUInt
1facf9fc 26116+}
26117+
26118+/* ---------------------------------------------------------------------- */
26119+
26120+/* sum mode which returns the summation for statfs(2) */
26121+
26122+static u64 au_add_till_max(u64 a, u64 b)
26123+{
26124+ u64 old;
26125+
26126+ old = a;
26127+ a += b;
92d182d2
AM
26128+ if (old <= a)
26129+ return a;
26130+ return ULLONG_MAX;
26131+}
26132+
26133+static u64 au_mul_till_max(u64 a, long mul)
26134+{
26135+ u64 old;
26136+
26137+ old = a;
26138+ a *= mul;
26139+ if (old <= a)
1facf9fc 26140+ return a;
26141+ return ULLONG_MAX;
26142+}
26143+
26144+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
26145+{
26146+ int err;
92d182d2 26147+ long bsize, factor;
1facf9fc 26148+ u64 blocks, bfree, bavail, files, ffree;
26149+ aufs_bindex_t bend, bindex, i;
26150+ unsigned char shared;
7f207e10 26151+ struct path h_path;
1facf9fc 26152+ struct super_block *h_sb;
26153+
92d182d2
AM
26154+ err = 0;
26155+ bsize = LONG_MAX;
26156+ files = 0;
26157+ ffree = 0;
1facf9fc 26158+ blocks = 0;
26159+ bfree = 0;
26160+ bavail = 0;
1facf9fc 26161+ bend = au_sbend(sb);
92d182d2 26162+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
26163+ h_path.mnt = au_sbr_mnt(sb, bindex);
26164+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 26165+ shared = 0;
92d182d2 26166+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 26167+ shared = (au_sbr_sb(sb, i) == h_sb);
26168+ if (shared)
26169+ continue;
26170+
26171+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
26172+ h_path.dentry = h_path.mnt->mnt_root;
26173+ err = vfs_statfs(&h_path, buf);
1facf9fc 26174+ if (unlikely(err))
26175+ goto out;
26176+
92d182d2
AM
26177+ if (bsize > buf->f_bsize) {
26178+ /*
26179+ * we will reduce bsize, so we have to expand blocks
26180+ * etc. to match them again
26181+ */
26182+ factor = (bsize / buf->f_bsize);
26183+ blocks = au_mul_till_max(blocks, factor);
26184+ bfree = au_mul_till_max(bfree, factor);
26185+ bavail = au_mul_till_max(bavail, factor);
26186+ bsize = buf->f_bsize;
26187+ }
26188+
26189+ factor = (buf->f_bsize / bsize);
26190+ blocks = au_add_till_max(blocks,
26191+ au_mul_till_max(buf->f_blocks, factor));
26192+ bfree = au_add_till_max(bfree,
26193+ au_mul_till_max(buf->f_bfree, factor));
26194+ bavail = au_add_till_max(bavail,
26195+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 26196+ files = au_add_till_max(files, buf->f_files);
26197+ ffree = au_add_till_max(ffree, buf->f_ffree);
26198+ }
26199+
92d182d2 26200+ buf->f_bsize = bsize;
1facf9fc 26201+ buf->f_blocks = blocks;
26202+ buf->f_bfree = bfree;
26203+ buf->f_bavail = bavail;
26204+ buf->f_files = files;
26205+ buf->f_ffree = ffree;
92d182d2 26206+ buf->f_frsize = 0;
1facf9fc 26207+
4f0767ce 26208+out:
1facf9fc 26209+ return err;
26210+}
26211+
26212+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
26213+{
26214+ int err;
7f207e10 26215+ struct path h_path;
1facf9fc 26216+ struct super_block *sb;
26217+
26218+ /* lock free root dinfo */
26219+ sb = dentry->d_sb;
26220+ si_noflush_read_lock(sb);
7f207e10 26221+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 26222+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
26223+ h_path.mnt = au_sbr_mnt(sb, 0);
26224+ h_path.dentry = h_path.mnt->mnt_root;
26225+ err = vfs_statfs(&h_path, buf);
26226+ } else
1facf9fc 26227+ err = au_statfs_sum(sb, buf);
26228+ si_read_unlock(sb);
26229+
26230+ if (!err) {
26231+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 26232+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 26233+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
26234+ }
26235+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
26236+
26237+ return err;
26238+}
26239+
26240+/* ---------------------------------------------------------------------- */
26241+
537831f9
AM
26242+static int aufs_sync_fs(struct super_block *sb, int wait)
26243+{
26244+ int err, e;
26245+ aufs_bindex_t bend, bindex;
26246+ struct au_branch *br;
26247+ struct super_block *h_sb;
26248+
26249+ err = 0;
26250+ si_noflush_read_lock(sb);
26251+ bend = au_sbend(sb);
26252+ for (bindex = 0; bindex <= bend; bindex++) {
26253+ br = au_sbr(sb, bindex);
26254+ if (!au_br_writable(br->br_perm))
26255+ continue;
26256+
26257+ h_sb = au_sbr_sb(sb, bindex);
26258+ if (h_sb->s_op->sync_fs) {
26259+ e = h_sb->s_op->sync_fs(h_sb, wait);
26260+ if (unlikely(e && !err))
26261+ err = e;
26262+ /* go on even if an error happens */
26263+ }
26264+ }
26265+ si_read_unlock(sb);
26266+
26267+ return err;
26268+}
26269+
26270+/* ---------------------------------------------------------------------- */
26271+
1facf9fc 26272+/* final actions when unmounting a file system */
26273+static void aufs_put_super(struct super_block *sb)
26274+{
26275+ struct au_sbinfo *sbinfo;
26276+
26277+ sbinfo = au_sbi(sb);
26278+ if (!sbinfo)
26279+ return;
26280+
1facf9fc 26281+ dbgaufs_si_fin(sbinfo);
26282+ kobject_put(&sbinfo->si_kobj);
26283+}
26284+
26285+/* ---------------------------------------------------------------------- */
26286+
7f207e10
AM
26287+void au_array_free(void *array)
26288+{
26289+ if (array) {
26290+ if (!is_vmalloc_addr(array))
26291+ kfree(array);
26292+ else
26293+ vfree(array);
26294+ }
26295+}
26296+
26297+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
26298+{
26299+ void *array;
076b876e 26300+ unsigned long long n, sz;
7f207e10
AM
26301+
26302+ array = NULL;
26303+ n = 0;
26304+ if (!*hint)
26305+ goto out;
26306+
26307+ if (*hint > ULLONG_MAX / sizeof(array)) {
26308+ array = ERR_PTR(-EMFILE);
26309+ pr_err("hint %llu\n", *hint);
26310+ goto out;
26311+ }
26312+
076b876e
AM
26313+ sz = sizeof(array) * *hint;
26314+ array = kzalloc(sz, GFP_NOFS);
7f207e10 26315+ if (unlikely(!array))
076b876e 26316+ array = vzalloc(sz);
7f207e10
AM
26317+ if (unlikely(!array)) {
26318+ array = ERR_PTR(-ENOMEM);
26319+ goto out;
26320+ }
26321+
26322+ n = cb(array, *hint, arg);
26323+ AuDebugOn(n > *hint);
26324+
26325+out:
26326+ *hint = n;
26327+ return array;
26328+}
26329+
26330+static unsigned long long au_iarray_cb(void *a,
26331+ unsigned long long max __maybe_unused,
26332+ void *arg)
26333+{
26334+ unsigned long long n;
26335+ struct inode **p, *inode;
26336+ struct list_head *head;
26337+
26338+ n = 0;
26339+ p = a;
26340+ head = arg;
2cbb1c4b 26341+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
26342+ list_for_each_entry(inode, head, i_sb_list) {
26343+ if (!is_bad_inode(inode)
26344+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
26345+ spin_lock(&inode->i_lock);
26346+ if (atomic_read(&inode->i_count)) {
26347+ au_igrab(inode);
26348+ *p++ = inode;
26349+ n++;
26350+ AuDebugOn(n > max);
26351+ }
26352+ spin_unlock(&inode->i_lock);
7f207e10
AM
26353+ }
26354+ }
2cbb1c4b 26355+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
26356+
26357+ return n;
26358+}
26359+
26360+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
26361+{
26362+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
26363+ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
26364+}
26365+
26366+void au_iarray_free(struct inode **a, unsigned long long max)
26367+{
26368+ unsigned long long ull;
26369+
26370+ for (ull = 0; ull < max; ull++)
26371+ iput(a[ull]);
26372+ au_array_free(a);
26373+}
26374+
26375+/* ---------------------------------------------------------------------- */
26376+
1facf9fc 26377+/*
26378+ * refresh dentry and inode at remount time.
26379+ */
027c5e7a
AM
26380+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
26381+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
26382+ struct dentry *parent)
1facf9fc 26383+{
26384+ int err;
1facf9fc 26385+
26386+ di_write_lock_child(dentry);
1facf9fc 26387+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
26388+ err = au_refresh_dentry(dentry, parent);
26389+ if (!err && dir_flags)
26390+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 26391+ di_read_unlock(parent, AuLock_IR);
1facf9fc 26392+ di_write_unlock(dentry);
26393+
26394+ return err;
26395+}
26396+
027c5e7a
AM
26397+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
26398+ struct au_sbinfo *sbinfo,
26399+ const unsigned int dir_flags)
1facf9fc 26400+{
027c5e7a
AM
26401+ int err;
26402+ struct dentry *parent;
26403+ struct inode *inode;
26404+
26405+ err = 0;
26406+ parent = dget_parent(dentry);
26407+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
26408+ inode = dentry->d_inode;
26409+ if (inode) {
26410+ if (!S_ISDIR(inode->i_mode))
26411+ err = au_do_refresh(dentry, /*dir_flags*/0,
26412+ parent);
26413+ else {
26414+ err = au_do_refresh(dentry, dir_flags, parent);
26415+ if (unlikely(err))
26416+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
26417+ }
26418+ } else
26419+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
26420+ AuDbgDentry(dentry);
26421+ }
26422+ dput(parent);
26423+
26424+ AuTraceErr(err);
26425+ return err;
1facf9fc 26426+}
26427+
027c5e7a 26428+static int au_refresh_d(struct super_block *sb)
1facf9fc 26429+{
26430+ int err, i, j, ndentry, e;
027c5e7a 26431+ unsigned int sigen;
1facf9fc 26432+ struct au_dcsub_pages dpages;
26433+ struct au_dpage *dpage;
027c5e7a
AM
26434+ struct dentry **dentries, *d;
26435+ struct au_sbinfo *sbinfo;
26436+ struct dentry *root = sb->s_root;
26437+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
1facf9fc 26438+
027c5e7a
AM
26439+ err = au_dpages_init(&dpages, GFP_NOFS);
26440+ if (unlikely(err))
1facf9fc 26441+ goto out;
027c5e7a
AM
26442+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
26443+ if (unlikely(err))
1facf9fc 26444+ goto out_dpages;
1facf9fc 26445+
027c5e7a
AM
26446+ sigen = au_sigen(sb);
26447+ sbinfo = au_sbi(sb);
26448+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 26449+ dpage = dpages.dpages + i;
26450+ dentries = dpage->dentries;
26451+ ndentry = dpage->ndentry;
027c5e7a 26452+ for (j = 0; j < ndentry; j++) {
1facf9fc 26453+ d = dentries[j];
027c5e7a
AM
26454+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
26455+ if (unlikely(e && !err))
26456+ err = e;
26457+ /* go on even err */
1facf9fc 26458+ }
26459+ }
26460+
4f0767ce 26461+out_dpages:
1facf9fc 26462+ au_dpages_free(&dpages);
4f0767ce 26463+out:
1facf9fc 26464+ return err;
26465+}
26466+
027c5e7a 26467+static int au_refresh_i(struct super_block *sb)
1facf9fc 26468+{
027c5e7a
AM
26469+ int err, e;
26470+ unsigned int sigen;
26471+ unsigned long long max, ull;
26472+ struct inode *inode, **array;
1facf9fc 26473+
027c5e7a
AM
26474+ array = au_iarray_alloc(sb, &max);
26475+ err = PTR_ERR(array);
26476+ if (IS_ERR(array))
26477+ goto out;
1facf9fc 26478+
26479+ err = 0;
027c5e7a
AM
26480+ sigen = au_sigen(sb);
26481+ for (ull = 0; ull < max; ull++) {
26482+ inode = array[ull];
076b876e
AM
26483+ if (unlikely(!inode))
26484+ break;
537831f9 26485+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 26486+ ii_write_lock_child(inode);
027c5e7a 26487+ e = au_refresh_hinode_self(inode);
1facf9fc 26488+ ii_write_unlock(inode);
26489+ if (unlikely(e)) {
027c5e7a 26490+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 26491+ if (!err)
26492+ err = e;
26493+ /* go on even if err */
26494+ }
26495+ }
1facf9fc 26496+ }
26497+
027c5e7a 26498+ au_iarray_free(array, max);
1facf9fc 26499+
4f0767ce 26500+out:
1facf9fc 26501+ return err;
26502+}
26503+
027c5e7a 26504+static void au_remount_refresh(struct super_block *sb)
1facf9fc 26505+{
027c5e7a
AM
26506+ int err, e;
26507+ unsigned int udba;
26508+ aufs_bindex_t bindex, bend;
1facf9fc 26509+ struct dentry *root;
26510+ struct inode *inode;
027c5e7a 26511+ struct au_branch *br;
1facf9fc 26512+
26513+ au_sigen_inc(sb);
027c5e7a 26514+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 26515+
26516+ root = sb->s_root;
26517+ DiMustNoWaiters(root);
26518+ inode = root->d_inode;
26519+ IiMustNoWaiters(inode);
1facf9fc 26520+
027c5e7a
AM
26521+ udba = au_opt_udba(sb);
26522+ bend = au_sbend(sb);
26523+ for (bindex = 0; bindex <= bend; bindex++) {
26524+ br = au_sbr(sb, bindex);
26525+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 26526+ if (unlikely(err))
027c5e7a
AM
26527+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
26528+ bindex, err);
26529+ /* go on even if err */
1facf9fc 26530+ }
027c5e7a 26531+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 26532+
027c5e7a
AM
26533+ di_write_unlock(root);
26534+ err = au_refresh_d(sb);
26535+ e = au_refresh_i(sb);
26536+ if (unlikely(e && !err))
26537+ err = e;
1facf9fc 26538+ /* aufs_write_lock() calls ..._child() */
26539+ di_write_lock_child(root);
027c5e7a
AM
26540+
26541+ au_cpup_attr_all(inode, /*force*/1);
26542+
26543+ if (unlikely(err))
26544+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 26545+}
26546+
26547+/* stop extra interpretation of errno in mount(8), and strange error messages */
26548+static int cvt_err(int err)
26549+{
26550+ AuTraceErr(err);
26551+
26552+ switch (err) {
26553+ case -ENOENT:
26554+ case -ENOTDIR:
26555+ case -EEXIST:
26556+ case -EIO:
26557+ err = -EINVAL;
26558+ }
26559+ return err;
26560+}
26561+
26562+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
26563+{
4a4d8108
AM
26564+ int err, do_dx;
26565+ unsigned int mntflags;
1facf9fc 26566+ struct au_opts opts;
26567+ struct dentry *root;
26568+ struct inode *inode;
26569+ struct au_sbinfo *sbinfo;
26570+
26571+ err = 0;
26572+ root = sb->s_root;
26573+ if (!data || !*data) {
e49829fe
JR
26574+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
26575+ if (!err) {
26576+ di_write_lock_child(root);
26577+ err = au_opts_verify(sb, *flags, /*pending*/0);
26578+ aufs_write_unlock(root);
26579+ }
1facf9fc 26580+ goto out;
26581+ }
26582+
26583+ err = -ENOMEM;
26584+ memset(&opts, 0, sizeof(opts));
26585+ opts.opt = (void *)__get_free_page(GFP_NOFS);
26586+ if (unlikely(!opts.opt))
26587+ goto out;
26588+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
26589+ opts.flags = AuOpts_REMOUNT;
26590+ opts.sb_flags = *flags;
26591+
26592+ /* parse it before aufs lock */
26593+ err = au_opts_parse(sb, data, &opts);
26594+ if (unlikely(err))
26595+ goto out_opts;
26596+
26597+ sbinfo = au_sbi(sb);
26598+ inode = root->d_inode;
26599+ mutex_lock(&inode->i_mutex);
e49829fe
JR
26600+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
26601+ if (unlikely(err))
26602+ goto out_mtx;
26603+ di_write_lock_child(root);
1facf9fc 26604+
26605+ /* au_opts_remount() may return an error */
26606+ err = au_opts_remount(sb, &opts);
26607+ au_opts_free(&opts);
26608+
027c5e7a
AM
26609+ if (au_ftest_opts(opts.flags, REFRESH))
26610+ au_remount_refresh(sb);
1facf9fc 26611+
4a4d8108
AM
26612+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
26613+ mntflags = au_mntflags(sb);
26614+ do_dx = !!au_opt_test(mntflags, DIO);
26615+ au_dy_arefresh(do_dx);
26616+ }
26617+
076b876e 26618+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 26619+ aufs_write_unlock(root);
953406b4 26620+
e49829fe
JR
26621+out_mtx:
26622+ mutex_unlock(&inode->i_mutex);
4f0767ce 26623+out_opts:
1facf9fc 26624+ free_page((unsigned long)opts.opt);
4f0767ce 26625+out:
1facf9fc 26626+ err = cvt_err(err);
26627+ AuTraceErr(err);
26628+ return err;
26629+}
26630+
4a4d8108 26631+static const struct super_operations aufs_sop = {
1facf9fc 26632+ .alloc_inode = aufs_alloc_inode,
26633+ .destroy_inode = aufs_destroy_inode,
b752ccd1 26634+ /* always deleting, no clearing */
1facf9fc 26635+ .drop_inode = generic_delete_inode,
26636+ .show_options = aufs_show_options,
26637+ .statfs = aufs_statfs,
26638+ .put_super = aufs_put_super,
537831f9 26639+ .sync_fs = aufs_sync_fs,
1facf9fc 26640+ .remount_fs = aufs_remount_fs
26641+};
26642+
26643+/* ---------------------------------------------------------------------- */
26644+
26645+static int alloc_root(struct super_block *sb)
26646+{
26647+ int err;
26648+ struct inode *inode;
26649+ struct dentry *root;
26650+
26651+ err = -ENOMEM;
26652+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
26653+ err = PTR_ERR(inode);
26654+ if (IS_ERR(inode))
26655+ goto out;
26656+
26657+ inode->i_op = &aufs_dir_iop;
26658+ inode->i_fop = &aufs_dir_fop;
26659+ inode->i_mode = S_IFDIR;
9dbd164d 26660+ set_nlink(inode, 2);
1facf9fc 26661+ unlock_new_inode(inode);
26662+
92d182d2 26663+ root = d_make_root(inode);
1facf9fc 26664+ if (unlikely(!root))
92d182d2 26665+ goto out;
1facf9fc 26666+ err = PTR_ERR(root);
26667+ if (IS_ERR(root))
92d182d2 26668+ goto out;
1facf9fc 26669+
4a4d8108 26670+ err = au_di_init(root);
1facf9fc 26671+ if (!err) {
26672+ sb->s_root = root;
26673+ return 0; /* success */
26674+ }
26675+ dput(root);
1facf9fc 26676+
4f0767ce 26677+out:
1facf9fc 26678+ return err;
1facf9fc 26679+}
26680+
26681+static int aufs_fill_super(struct super_block *sb, void *raw_data,
26682+ int silent __maybe_unused)
26683+{
26684+ int err;
26685+ struct au_opts opts;
26686+ struct dentry *root;
26687+ struct inode *inode;
26688+ char *arg = raw_data;
26689+
26690+ if (unlikely(!arg || !*arg)) {
26691+ err = -EINVAL;
4a4d8108 26692+ pr_err("no arg\n");
1facf9fc 26693+ goto out;
26694+ }
26695+
26696+ err = -ENOMEM;
26697+ memset(&opts, 0, sizeof(opts));
26698+ opts.opt = (void *)__get_free_page(GFP_NOFS);
26699+ if (unlikely(!opts.opt))
26700+ goto out;
26701+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
26702+ opts.sb_flags = sb->s_flags;
26703+
26704+ err = au_si_alloc(sb);
26705+ if (unlikely(err))
26706+ goto out_opts;
26707+
26708+ /* all timestamps always follow the ones on the branch */
26709+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
26710+ sb->s_op = &aufs_sop;
027c5e7a 26711+ sb->s_d_op = &aufs_dop;
1facf9fc 26712+ sb->s_magic = AUFS_SUPER_MAGIC;
26713+ sb->s_maxbytes = 0;
26714+ au_export_init(sb);
26715+
26716+ err = alloc_root(sb);
26717+ if (unlikely(err)) {
26718+ si_write_unlock(sb);
26719+ goto out_info;
26720+ }
26721+ root = sb->s_root;
26722+ inode = root->d_inode;
26723+
26724+ /*
26725+ * actually we can parse options regardless aufs lock here.
26726+ * but at remount time, parsing must be done before aufs lock.
26727+ * so we follow the same rule.
26728+ */
26729+ ii_write_lock_parent(inode);
26730+ aufs_write_unlock(root);
26731+ err = au_opts_parse(sb, arg, &opts);
26732+ if (unlikely(err))
26733+ goto out_root;
26734+
26735+ /* lock vfs_inode first, then aufs. */
26736+ mutex_lock(&inode->i_mutex);
1facf9fc 26737+ aufs_write_lock(root);
26738+ err = au_opts_mount(sb, &opts);
26739+ au_opts_free(&opts);
1facf9fc 26740+ aufs_write_unlock(root);
26741+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
26742+ if (!err)
26743+ goto out_opts; /* success */
1facf9fc 26744+
4f0767ce 26745+out_root:
1facf9fc 26746+ dput(root);
26747+ sb->s_root = NULL;
4f0767ce 26748+out_info:
2cbb1c4b 26749+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 26750+ kobject_put(&au_sbi(sb)->si_kobj);
26751+ sb->s_fs_info = NULL;
4f0767ce 26752+out_opts:
1facf9fc 26753+ free_page((unsigned long)opts.opt);
4f0767ce 26754+out:
1facf9fc 26755+ AuTraceErr(err);
26756+ err = cvt_err(err);
26757+ AuTraceErr(err);
26758+ return err;
26759+}
26760+
26761+/* ---------------------------------------------------------------------- */
26762+
027c5e7a
AM
26763+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
26764+ const char *dev_name __maybe_unused,
26765+ void *raw_data)
1facf9fc 26766+{
027c5e7a 26767+ struct dentry *root;
1facf9fc 26768+ struct super_block *sb;
26769+
26770+ /* all timestamps always follow the ones on the branch */
26771+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
26772+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
26773+ if (IS_ERR(root))
26774+ goto out;
26775+
26776+ sb = root->d_sb;
26777+ si_write_lock(sb, !AuLock_FLUSH);
26778+ sysaufs_brs_add(sb, 0);
26779+ si_write_unlock(sb);
26780+ au_sbilist_add(sb);
26781+
26782+out:
26783+ return root;
1facf9fc 26784+}
26785+
e49829fe
JR
26786+static void aufs_kill_sb(struct super_block *sb)
26787+{
26788+ struct au_sbinfo *sbinfo;
26789+
26790+ sbinfo = au_sbi(sb);
26791+ if (sbinfo) {
26792+ au_sbilist_del(sb);
26793+ aufs_write_lock(sb->s_root);
076b876e 26794+ au_fhsm_fin(sb);
e49829fe
JR
26795+ if (sbinfo->si_wbr_create_ops->fin)
26796+ sbinfo->si_wbr_create_ops->fin(sb);
26797+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
26798+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
027c5e7a 26799+ au_remount_refresh(sb);
e49829fe
JR
26800+ }
26801+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
26802+ au_plink_put(sb, /*verbose*/1);
26803+ au_xino_clr(sb);
1e00d052 26804+ sbinfo->si_sb = NULL;
e49829fe 26805+ aufs_write_unlock(sb->s_root);
e49829fe
JR
26806+ au_nwt_flush(&sbinfo->si_nowait);
26807+ }
98d9a5b1 26808+ kill_anon_super(sb);
e49829fe
JR
26809+}
26810+
1facf9fc 26811+struct file_system_type aufs_fs_type = {
26812+ .name = AUFS_FSTYPE,
c06a8ce3
AM
26813+ /* a race between rename and others */
26814+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 26815+ .mount = aufs_mount,
e49829fe 26816+ .kill_sb = aufs_kill_sb,
1facf9fc 26817+ /* no need to __module_get() and module_put(). */
26818+ .owner = THIS_MODULE,
26819+};
7f207e10
AM
26820diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
26821--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
26822+++ linux/fs/aufs/super.h 2014-08-14 10:15:45.131942973 +0200
26823@@ -0,0 +1,642 @@
1facf9fc 26824+/*
523b37e3 26825+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26826+ *
26827+ * This program, aufs is free software; you can redistribute it and/or modify
26828+ * it under the terms of the GNU General Public License as published by
26829+ * the Free Software Foundation; either version 2 of the License, or
26830+ * (at your option) any later version.
dece6358
AM
26831+ *
26832+ * This program is distributed in the hope that it will be useful,
26833+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26834+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26835+ * GNU General Public License for more details.
26836+ *
26837+ * You should have received a copy of the GNU General Public License
523b37e3 26838+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26839+ */
26840+
26841+/*
26842+ * super_block operations
26843+ */
26844+
26845+#ifndef __AUFS_SUPER_H__
26846+#define __AUFS_SUPER_H__
26847+
26848+#ifdef __KERNEL__
26849+
26850+#include <linux/fs.h>
1facf9fc 26851+#include "rwsem.h"
26852+#include "spl.h"
26853+#include "wkq.h"
26854+
26855+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
26856+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
26857+ loff_t *);
26858+
26859+/* policies to select one among multiple writable branches */
26860+struct au_wbr_copyup_operations {
26861+ int (*copyup)(struct dentry *dentry);
26862+};
26863+
392086de
AM
26864+#define AuWbr_DIR 1 /* target is a dir */
26865+#define AuWbr_PARENT (1 << 1) /* always require a parent */
26866+
26867+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
26868+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
26869+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
26870+
1facf9fc 26871+struct au_wbr_create_operations {
392086de 26872+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 26873+ int (*init)(struct super_block *sb);
26874+ int (*fin)(struct super_block *sb);
26875+};
26876+
26877+struct au_wbr_mfs {
26878+ struct mutex mfs_lock; /* protect this structure */
26879+ unsigned long mfs_jiffy;
26880+ unsigned long mfs_expire;
26881+ aufs_bindex_t mfs_bindex;
26882+
26883+ unsigned long long mfsrr_bytes;
26884+ unsigned long long mfsrr_watermark;
26885+};
26886+
86dc4139
AM
26887+struct pseudo_link {
26888+ union {
26889+ struct hlist_node hlist;
26890+ struct rcu_head rcu;
26891+ };
26892+ struct inode *inode;
26893+};
26894+
26895+#define AuPlink_NHASH 100
26896+static inline int au_plink_hash(ino_t ino)
26897+{
26898+ return ino % AuPlink_NHASH;
26899+}
26900+
076b876e
AM
26901+/* File-based Hierarchical Storage Management */
26902+struct au_fhsm {
26903+#ifdef CONFIG_AUFS_FHSM
26904+ /* allow only one process who can receive the notification */
26905+ spinlock_t fhsm_spin;
26906+ pid_t fhsm_pid;
26907+ wait_queue_head_t fhsm_wqh;
26908+ atomic_t fhsm_readable;
26909+
26910+ /* only this is protected by si_rwsem */
26911+ unsigned long fhsm_expire;
26912+#endif
26913+};
26914+
1facf9fc 26915+struct au_branch;
26916+struct au_sbinfo {
26917+ /* nowait tasks in the system-wide workqueue */
26918+ struct au_nowait_tasks si_nowait;
26919+
b752ccd1
AM
26920+ /*
26921+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
26922+ * rwsem for au_sbinfo is necessary.
26923+ */
dece6358 26924+ struct au_rwsem si_rwsem;
1facf9fc 26925+
b752ccd1
AM
26926+ /* prevent recursive locking in deleting inode */
26927+ struct {
26928+ unsigned long *bitmap;
26929+ spinlock_t tree_lock;
26930+ struct radix_tree_root tree;
26931+ } au_si_pid;
26932+
7f207e10 26933+ /*
523b37e3
AM
26934+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
26935+ * remount.
7f207e10
AM
26936+ */
26937+ atomic_long_t si_ninodes, si_nfiles;
26938+
1facf9fc 26939+ /* branch management */
26940+ unsigned int si_generation;
26941+
26942+ /* see above flags */
26943+ unsigned char au_si_status;
26944+
26945+ aufs_bindex_t si_bend;
7f207e10
AM
26946+
26947+ /* dirty trick to keep br_id plus */
26948+ unsigned int si_last_br_id :
26949+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 26950+ struct au_branch **si_branch;
26951+
26952+ /* policy to select a writable branch */
26953+ unsigned char si_wbr_copyup;
26954+ unsigned char si_wbr_create;
26955+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
26956+ struct au_wbr_create_operations *si_wbr_create_ops;
26957+
26958+ /* round robin */
26959+ atomic_t si_wbr_rr_next;
26960+
26961+ /* most free space */
26962+ struct au_wbr_mfs si_wbr_mfs;
26963+
076b876e
AM
26964+ /* File-based Hierarchical Storage Management */
26965+ struct au_fhsm si_fhsm;
26966+
1facf9fc 26967+ /* mount flags */
26968+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
26969+ unsigned int si_mntflags;
26970+
26971+ /* external inode number (bitmap and translation table) */
26972+ au_readf_t si_xread;
26973+ au_writef_t si_xwrite;
26974+ struct file *si_xib;
26975+ struct mutex si_xib_mtx; /* protect xib members */
26976+ unsigned long *si_xib_buf;
26977+ unsigned long si_xib_last_pindex;
26978+ int si_xib_next_bit;
26979+ aufs_bindex_t si_xino_brid;
392086de
AM
26980+ unsigned long si_xino_jiffy;
26981+ unsigned long si_xino_expire;
1facf9fc 26982+ /* reserved for future use */
26983+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
26984+
26985+#ifdef CONFIG_AUFS_EXPORT
26986+ /* i_generation */
26987+ struct file *si_xigen;
26988+ atomic_t si_xigen_next;
26989+#endif
26990+
26991+ /* vdir parameters */
e49829fe 26992+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 26993+ unsigned int si_rdblk; /* deblk size */
26994+ unsigned int si_rdhash; /* hash size */
26995+
26996+ /*
26997+ * If the number of whiteouts are larger than si_dirwh, leave all of
26998+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
26999+ * future fsck.aufs or kernel thread will remove them later.
27000+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
27001+ */
27002+ unsigned int si_dirwh;
27003+
27004+ /*
27005+ * rename(2) a directory with all children.
27006+ */
27007+ /* reserved for future use */
27008+ /* int si_rendir; */
27009+
27010+ /* pseudo_link list */
86dc4139 27011+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 27012+ wait_queue_head_t si_plink_wq;
4a4d8108 27013+ spinlock_t si_plink_maint_lock;
e49829fe 27014+ pid_t si_plink_maint_pid;
1facf9fc 27015+
523b37e3
AM
27016+ /* file list */
27017+ struct au_sphlhead si_files;
27018+
1facf9fc 27019+ /*
27020+ * sysfs and lifetime management.
27021+ * this is not a small structure and it may be a waste of memory in case
27022+ * of sysfs is disabled, particulary when many aufs-es are mounted.
27023+ * but using sysfs is majority.
27024+ */
27025+ struct kobject si_kobj;
27026+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
27027+ struct dentry *si_dbgaufs;
27028+ struct dentry *si_dbgaufs_plink;
27029+ struct dentry *si_dbgaufs_xib;
1facf9fc 27030+#ifdef CONFIG_AUFS_EXPORT
27031+ struct dentry *si_dbgaufs_xigen;
27032+#endif
27033+#endif
27034+
e49829fe
JR
27035+#ifdef CONFIG_AUFS_SBILIST
27036+ struct list_head si_list;
27037+#endif
27038+
1facf9fc 27039+ /* dirty, necessary for unmounting, sysfs and sysrq */
27040+ struct super_block *si_sb;
27041+};
27042+
dece6358
AM
27043+/* sbinfo status flags */
27044+/*
27045+ * set true when refresh_dirs() failed at remount time.
27046+ * then try refreshing dirs at access time again.
27047+ * if it is false, refreshing dirs at access time is unnecesary
27048+ */
027c5e7a 27049+#define AuSi_FAILED_REFRESH_DIR 1
076b876e
AM
27050+
27051+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
27052+
27053+#ifndef CONFIG_AUFS_FHSM
27054+#undef AuSi_FHSM
27055+#define AuSi_FHSM 0
27056+#endif
27057+
dece6358
AM
27058+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
27059+ unsigned int flag)
27060+{
27061+ AuRwMustAnyLock(&sbi->si_rwsem);
27062+ return sbi->au_si_status & flag;
27063+}
27064+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
27065+#define au_fset_si(sbinfo, name) do { \
27066+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27067+ (sbinfo)->au_si_status |= AuSi_##name; \
27068+} while (0)
27069+#define au_fclr_si(sbinfo, name) do { \
27070+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27071+ (sbinfo)->au_si_status &= ~AuSi_##name; \
27072+} while (0)
27073+
1facf9fc 27074+/* ---------------------------------------------------------------------- */
27075+
27076+/* policy to select one among writable branches */
4a4d8108
AM
27077+#define AuWbrCopyup(sbinfo, ...) \
27078+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
27079+#define AuWbrCreate(sbinfo, ...) \
27080+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 27081+
27082+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
27083+#define AuLock_DW 1 /* write-lock dentry */
27084+#define AuLock_IR (1 << 1) /* read-lock inode */
27085+#define AuLock_IW (1 << 2) /* write-lock inode */
27086+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
27087+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
27088+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
27089+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 27090+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 27091+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
27092+#define au_fset_lock(flags, name) \
27093+ do { (flags) |= AuLock_##name; } while (0)
27094+#define au_fclr_lock(flags, name) \
27095+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 27096+
27097+/* ---------------------------------------------------------------------- */
27098+
27099+/* super.c */
27100+extern struct file_system_type aufs_fs_type;
27101+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
7f207e10
AM
27102+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
27103+ void *arg);
27104+void au_array_free(void *array);
27105+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
27106+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
27107+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 27108+
27109+/* sbinfo.c */
27110+void au_si_free(struct kobject *kobj);
27111+int au_si_alloc(struct super_block *sb);
27112+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
27113+
27114+unsigned int au_sigen_inc(struct super_block *sb);
27115+aufs_bindex_t au_new_br_id(struct super_block *sb);
27116+
e49829fe
JR
27117+int si_read_lock(struct super_block *sb, int flags);
27118+int si_write_lock(struct super_block *sb, int flags);
27119+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 27120+void aufs_read_unlock(struct dentry *dentry, int flags);
27121+void aufs_write_lock(struct dentry *dentry);
27122+void aufs_write_unlock(struct dentry *dentry);
e49829fe 27123+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 27124+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
27125+
b752ccd1
AM
27126+int si_pid_test_slow(struct super_block *sb);
27127+void si_pid_set_slow(struct super_block *sb);
27128+void si_pid_clr_slow(struct super_block *sb);
27129+
1facf9fc 27130+/* wbr_policy.c */
27131+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
27132+extern struct au_wbr_create_operations au_wbr_create_ops[];
27133+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 27134+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
076b876e 27135+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart);
c2b27bf2
AM
27136+
27137+/* mvdown.c */
27138+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 27139+
076b876e
AM
27140+#ifdef CONFIG_AUFS_FHSM
27141+/* fhsm.c */
27142+
27143+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
27144+{
27145+ pid_t pid;
27146+
27147+ spin_lock(&fhsm->fhsm_spin);
27148+ pid = fhsm->fhsm_pid;
27149+ spin_unlock(&fhsm->fhsm_spin);
27150+
27151+ return pid;
27152+}
27153+
27154+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
27155+void au_fhsm_wrote_all(struct super_block *sb, int force);
27156+int au_fhsm_fd(struct super_block *sb, int oflags);
27157+int au_fhsm_br_alloc(struct au_branch *br);
27158+void au_fhsm_fin(struct super_block *sb);
27159+void au_fhsm_init(struct au_sbinfo *sbinfo);
27160+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
27161+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
27162+#else
27163+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
27164+ int force)
27165+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
27166+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
27167+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm);
27168+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br);
27169+AuStubVoid(au_fhsm_fin, struct super_block *sb)
27170+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
27171+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
27172+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
27173+#endif
27174+
1facf9fc 27175+/* ---------------------------------------------------------------------- */
27176+
27177+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
27178+{
27179+ return sb->s_fs_info;
27180+}
27181+
27182+/* ---------------------------------------------------------------------- */
27183+
27184+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 27185+int au_test_nfsd(void);
1facf9fc 27186+void au_export_init(struct super_block *sb);
b752ccd1 27187+void au_xigen_inc(struct inode *inode);
1facf9fc 27188+int au_xigen_new(struct inode *inode);
27189+int au_xigen_set(struct super_block *sb, struct file *base);
27190+void au_xigen_clr(struct super_block *sb);
27191+
27192+static inline int au_busy_or_stale(void)
27193+{
b752ccd1 27194+ if (!au_test_nfsd())
1facf9fc 27195+ return -EBUSY;
27196+ return -ESTALE;
27197+}
27198+#else
b752ccd1 27199+AuStubInt0(au_test_nfsd, void)
a2a7ad62 27200+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 27201+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
27202+AuStubInt0(au_xigen_new, struct inode *inode)
27203+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
27204+AuStubVoid(au_xigen_clr, struct super_block *sb)
1facf9fc 27205+static inline int au_busy_or_stale(void)
27206+{
27207+ return -EBUSY;
27208+}
27209+#endif /* CONFIG_AUFS_EXPORT */
27210+
27211+/* ---------------------------------------------------------------------- */
27212+
e49829fe
JR
27213+#ifdef CONFIG_AUFS_SBILIST
27214+/* module.c */
27215+extern struct au_splhead au_sbilist;
27216+
27217+static inline void au_sbilist_init(void)
27218+{
27219+ au_spl_init(&au_sbilist);
27220+}
27221+
27222+static inline void au_sbilist_add(struct super_block *sb)
27223+{
27224+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
27225+}
27226+
27227+static inline void au_sbilist_del(struct super_block *sb)
27228+{
27229+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
27230+}
53392da6
AM
27231+
27232+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
27233+static inline void au_sbilist_lock(void)
27234+{
27235+ spin_lock(&au_sbilist.spin);
27236+}
27237+
27238+static inline void au_sbilist_unlock(void)
27239+{
27240+ spin_unlock(&au_sbilist.spin);
27241+}
27242+#define AuGFP_SBILIST GFP_ATOMIC
27243+#else
27244+AuStubVoid(au_sbilist_lock, void)
27245+AuStubVoid(au_sbilist_unlock, void)
27246+#define AuGFP_SBILIST GFP_NOFS
27247+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
27248+#else
27249+AuStubVoid(au_sbilist_init, void)
27250+AuStubVoid(au_sbilist_add, struct super_block*)
27251+AuStubVoid(au_sbilist_del, struct super_block*)
53392da6
AM
27252+AuStubVoid(au_sbilist_lock, void)
27253+AuStubVoid(au_sbilist_unlock, void)
27254+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
27255+#endif
27256+
27257+/* ---------------------------------------------------------------------- */
27258+
1facf9fc 27259+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
27260+{
dece6358
AM
27261+ /*
27262+ * This function is a dynamic '__init' fucntion actually,
27263+ * so the tiny check for si_rwsem is unnecessary.
27264+ */
27265+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 27266+#ifdef CONFIG_DEBUG_FS
27267+ sbinfo->si_dbgaufs = NULL;
86dc4139 27268+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 27269+ sbinfo->si_dbgaufs_xib = NULL;
27270+#ifdef CONFIG_AUFS_EXPORT
27271+ sbinfo->si_dbgaufs_xigen = NULL;
27272+#endif
27273+#endif
27274+}
27275+
27276+/* ---------------------------------------------------------------------- */
27277+
b752ccd1
AM
27278+static inline pid_t si_pid_bit(void)
27279+{
27280+ /* the origin of pid is 1, but the bitmap's is 0 */
27281+ return current->pid - 1;
27282+}
27283+
27284+static inline int si_pid_test(struct super_block *sb)
27285+{
076b876e
AM
27286+ pid_t bit;
27287+
27288+ bit = si_pid_bit();
b752ccd1
AM
27289+ if (bit < PID_MAX_DEFAULT)
27290+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27291+ else
27292+ return si_pid_test_slow(sb);
27293+}
27294+
27295+static inline void si_pid_set(struct super_block *sb)
27296+{
076b876e
AM
27297+ pid_t bit;
27298+
27299+ bit = si_pid_bit();
b752ccd1
AM
27300+ if (bit < PID_MAX_DEFAULT) {
27301+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
27302+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27303+ /* smp_mb(); */
27304+ } else
27305+ si_pid_set_slow(sb);
27306+}
27307+
27308+static inline void si_pid_clr(struct super_block *sb)
27309+{
076b876e
AM
27310+ pid_t bit;
27311+
27312+ bit = si_pid_bit();
b752ccd1
AM
27313+ if (bit < PID_MAX_DEFAULT) {
27314+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
27315+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27316+ /* smp_mb(); */
27317+ } else
27318+ si_pid_clr_slow(sb);
27319+}
27320+
27321+/* ---------------------------------------------------------------------- */
27322+
1facf9fc 27323+/* lock superblock. mainly for entry point functions */
27324+/*
b752ccd1
AM
27325+ * __si_read_lock, __si_write_lock,
27326+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 27327+ */
b752ccd1 27328+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 27329+
dece6358
AM
27330+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
27331+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
27332+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
27333+
b752ccd1
AM
27334+static inline void si_noflush_read_lock(struct super_block *sb)
27335+{
27336+ __si_read_lock(sb);
27337+ si_pid_set(sb);
27338+}
27339+
27340+static inline int si_noflush_read_trylock(struct super_block *sb)
27341+{
076b876e
AM
27342+ int locked;
27343+
27344+ locked = __si_read_trylock(sb);
b752ccd1
AM
27345+ if (locked)
27346+ si_pid_set(sb);
27347+ return locked;
27348+}
27349+
27350+static inline void si_noflush_write_lock(struct super_block *sb)
27351+{
27352+ __si_write_lock(sb);
27353+ si_pid_set(sb);
27354+}
27355+
27356+static inline int si_noflush_write_trylock(struct super_block *sb)
27357+{
076b876e
AM
27358+ int locked;
27359+
27360+ locked = __si_write_trylock(sb);
b752ccd1
AM
27361+ if (locked)
27362+ si_pid_set(sb);
27363+ return locked;
27364+}
27365+
e49829fe 27366+#if 0 /* unused */
1facf9fc 27367+static inline int si_read_trylock(struct super_block *sb, int flags)
27368+{
27369+ if (au_ftest_lock(flags, FLUSH))
27370+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27371+ return si_noflush_read_trylock(sb);
27372+}
e49829fe 27373+#endif
1facf9fc 27374+
b752ccd1
AM
27375+static inline void si_read_unlock(struct super_block *sb)
27376+{
27377+ si_pid_clr(sb);
27378+ __si_read_unlock(sb);
27379+}
27380+
b752ccd1 27381+#if 0 /* unused */
1facf9fc 27382+static inline int si_write_trylock(struct super_block *sb, int flags)
27383+{
27384+ if (au_ftest_lock(flags, FLUSH))
27385+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27386+ return si_noflush_write_trylock(sb);
27387+}
b752ccd1
AM
27388+#endif
27389+
27390+static inline void si_write_unlock(struct super_block *sb)
27391+{
27392+ si_pid_clr(sb);
27393+ __si_write_unlock(sb);
27394+}
27395+
27396+#if 0 /* unused */
27397+static inline void si_downgrade_lock(struct super_block *sb)
27398+{
27399+ __si_downgrade_lock(sb);
27400+}
27401+#endif
1facf9fc 27402+
27403+/* ---------------------------------------------------------------------- */
27404+
27405+static inline aufs_bindex_t au_sbend(struct super_block *sb)
27406+{
dece6358 27407+ SiMustAnyLock(sb);
1facf9fc 27408+ return au_sbi(sb)->si_bend;
27409+}
27410+
27411+static inline unsigned int au_mntflags(struct super_block *sb)
27412+{
dece6358 27413+ SiMustAnyLock(sb);
1facf9fc 27414+ return au_sbi(sb)->si_mntflags;
27415+}
27416+
27417+static inline unsigned int au_sigen(struct super_block *sb)
27418+{
dece6358 27419+ SiMustAnyLock(sb);
1facf9fc 27420+ return au_sbi(sb)->si_generation;
27421+}
27422+
7f207e10
AM
27423+static inline void au_ninodes_inc(struct super_block *sb)
27424+{
27425+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
27426+}
27427+
27428+static inline void au_ninodes_dec(struct super_block *sb)
27429+{
27430+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
27431+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
27432+}
27433+
27434+static inline void au_nfiles_inc(struct super_block *sb)
27435+{
27436+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
27437+}
27438+
27439+static inline void au_nfiles_dec(struct super_block *sb)
27440+{
27441+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
27442+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
27443+}
27444+
1facf9fc 27445+static inline struct au_branch *au_sbr(struct super_block *sb,
27446+ aufs_bindex_t bindex)
27447+{
dece6358 27448+ SiMustAnyLock(sb);
1facf9fc 27449+ return au_sbi(sb)->si_branch[0 + bindex];
27450+}
27451+
27452+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
27453+{
dece6358 27454+ SiMustWriteLock(sb);
1facf9fc 27455+ au_sbi(sb)->si_xino_brid = brid;
27456+}
27457+
27458+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
27459+{
dece6358 27460+ SiMustAnyLock(sb);
1facf9fc 27461+ return au_sbi(sb)->si_xino_brid;
27462+}
27463+
27464+#endif /* __KERNEL__ */
27465+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
27466diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
27467--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
076b876e 27468+++ linux/fs/aufs/sysaufs.c 2014-01-30 21:10:02.857481956 +0100
523b37e3 27469@@ -0,0 +1,104 @@
1facf9fc 27470+/*
523b37e3 27471+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 27472+ *
27473+ * This program, aufs is free software; you can redistribute it and/or modify
27474+ * it under the terms of the GNU General Public License as published by
27475+ * the Free Software Foundation; either version 2 of the License, or
27476+ * (at your option) any later version.
dece6358
AM
27477+ *
27478+ * This program is distributed in the hope that it will be useful,
27479+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27480+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27481+ * GNU General Public License for more details.
27482+ *
27483+ * You should have received a copy of the GNU General Public License
523b37e3 27484+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27485+ */
27486+
27487+/*
27488+ * sysfs interface and lifetime management
27489+ * they are necessary regardless sysfs is disabled.
27490+ */
27491+
1facf9fc 27492+#include <linux/random.h>
1facf9fc 27493+#include "aufs.h"
27494+
27495+unsigned long sysaufs_si_mask;
e49829fe 27496+struct kset *sysaufs_kset;
1facf9fc 27497+
27498+#define AuSiAttr(_name) { \
27499+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
27500+ .show = sysaufs_si_##_name, \
27501+}
27502+
27503+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
27504+struct attribute *sysaufs_si_attrs[] = {
27505+ &sysaufs_si_attr_xi_path.attr,
27506+ NULL,
27507+};
27508+
4a4d8108 27509+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 27510+ .show = sysaufs_si_show
27511+};
27512+
27513+static struct kobj_type au_sbi_ktype = {
27514+ .release = au_si_free,
27515+ .sysfs_ops = &au_sbi_ops,
27516+ .default_attrs = sysaufs_si_attrs
27517+};
27518+
27519+/* ---------------------------------------------------------------------- */
27520+
27521+int sysaufs_si_init(struct au_sbinfo *sbinfo)
27522+{
27523+ int err;
27524+
e49829fe 27525+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 27526+ /* cf. sysaufs_name() */
27527+ err = kobject_init_and_add
e49829fe 27528+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 27529+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
27530+
27531+ dbgaufs_si_null(sbinfo);
27532+ if (!err) {
27533+ err = dbgaufs_si_init(sbinfo);
27534+ if (unlikely(err))
27535+ kobject_put(&sbinfo->si_kobj);
27536+ }
27537+ return err;
27538+}
27539+
27540+void sysaufs_fin(void)
27541+{
27542+ dbgaufs_fin();
e49829fe
JR
27543+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
27544+ kset_unregister(sysaufs_kset);
1facf9fc 27545+}
27546+
27547+int __init sysaufs_init(void)
27548+{
27549+ int err;
27550+
27551+ do {
27552+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
27553+ } while (!sysaufs_si_mask);
27554+
4a4d8108 27555+ err = -EINVAL;
e49829fe
JR
27556+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
27557+ if (unlikely(!sysaufs_kset))
4a4d8108 27558+ goto out;
e49829fe
JR
27559+ err = PTR_ERR(sysaufs_kset);
27560+ if (IS_ERR(sysaufs_kset))
1facf9fc 27561+ goto out;
e49829fe 27562+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 27563+ if (unlikely(err)) {
e49829fe 27564+ kset_unregister(sysaufs_kset);
1facf9fc 27565+ goto out;
27566+ }
27567+
27568+ err = dbgaufs_init();
27569+ if (unlikely(err))
27570+ sysaufs_fin();
4f0767ce 27571+out:
1facf9fc 27572+ return err;
27573+}
7f207e10
AM
27574diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
27575--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
27576+++ linux/fs/aufs/sysaufs.h 2014-08-14 10:15:45.131942973 +0200
27577@@ -0,0 +1,107 @@
1facf9fc 27578+/*
523b37e3 27579+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 27580+ *
27581+ * This program, aufs is free software; you can redistribute it and/or modify
27582+ * it under the terms of the GNU General Public License as published by
27583+ * the Free Software Foundation; either version 2 of the License, or
27584+ * (at your option) any later version.
dece6358
AM
27585+ *
27586+ * This program is distributed in the hope that it will be useful,
27587+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27588+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27589+ * GNU General Public License for more details.
27590+ *
27591+ * You should have received a copy of the GNU General Public License
523b37e3 27592+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27593+ */
27594+
27595+/*
27596+ * sysfs interface and mount lifetime management
27597+ */
27598+
27599+#ifndef __SYSAUFS_H__
27600+#define __SYSAUFS_H__
27601+
27602+#ifdef __KERNEL__
27603+
1facf9fc 27604+#include <linux/sysfs.h>
1facf9fc 27605+#include "module.h"
27606+
dece6358
AM
27607+struct super_block;
27608+struct au_sbinfo;
27609+
1facf9fc 27610+struct sysaufs_si_attr {
27611+ struct attribute attr;
27612+ int (*show)(struct seq_file *seq, struct super_block *sb);
27613+};
27614+
27615+/* ---------------------------------------------------------------------- */
27616+
27617+/* sysaufs.c */
27618+extern unsigned long sysaufs_si_mask;
e49829fe 27619+extern struct kset *sysaufs_kset;
1facf9fc 27620+extern struct attribute *sysaufs_si_attrs[];
27621+int sysaufs_si_init(struct au_sbinfo *sbinfo);
27622+int __init sysaufs_init(void);
27623+void sysaufs_fin(void);
27624+
27625+/* ---------------------------------------------------------------------- */
27626+
27627+/* some people doesn't like to show a pointer in kernel */
27628+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
27629+{
27630+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
27631+}
27632+
27633+#define SysaufsSiNamePrefix "si_"
27634+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
27635+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
27636+{
27637+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
27638+ sysaufs_si_id(sbinfo));
27639+}
27640+
27641+struct au_branch;
27642+#ifdef CONFIG_SYSFS
27643+/* sysfs.c */
27644+extern struct attribute_group *sysaufs_attr_group;
27645+
27646+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
27647+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
27648+ char *buf);
076b876e
AM
27649+long au_brinfo_ioctl(struct file *file, unsigned long arg);
27650+#ifdef CONFIG_COMPAT
27651+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
27652+#endif
1facf9fc 27653+
27654+void sysaufs_br_init(struct au_branch *br);
27655+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
27656+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
27657+
27658+#define sysaufs_brs_init() do {} while (0)
27659+
27660+#else
27661+#define sysaufs_attr_group NULL
27662+
4a4d8108 27663+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
1facf9fc 27664+
27665+static inline
27666+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
27667+ char *buf)
27668+{
27669+ return 0;
27670+}
27671+
4a4d8108
AM
27672+AuStubVoid(sysaufs_br_init, struct au_branch *br)
27673+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
27674+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 27675+
27676+static inline void sysaufs_brs_init(void)
27677+{
27678+ sysaufs_brs = 0;
27679+}
27680+
27681+#endif /* CONFIG_SYSFS */
27682+
27683+#endif /* __KERNEL__ */
27684+#endif /* __SYSAUFS_H__ */
7f207e10
AM
27685diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
27686--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
27687+++ linux/fs/aufs/sysfs.c 2014-08-14 10:15:45.131942973 +0200
27688@@ -0,0 +1,372 @@
1facf9fc 27689+/*
523b37e3 27690+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 27691+ *
27692+ * This program, aufs is free software; you can redistribute it and/or modify
27693+ * it under the terms of the GNU General Public License as published by
27694+ * the Free Software Foundation; either version 2 of the License, or
27695+ * (at your option) any later version.
dece6358
AM
27696+ *
27697+ * This program is distributed in the hope that it will be useful,
27698+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27699+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27700+ * GNU General Public License for more details.
27701+ *
27702+ * You should have received a copy of the GNU General Public License
523b37e3 27703+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27704+ */
27705+
27706+/*
27707+ * sysfs interface
27708+ */
27709+
076b876e 27710+#include <linux/compat.h>
1facf9fc 27711+#include <linux/seq_file.h>
1facf9fc 27712+#include "aufs.h"
27713+
4a4d8108
AM
27714+#ifdef CONFIG_AUFS_FS_MODULE
27715+/* this entry violates the "one line per file" policy of sysfs */
27716+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
27717+ char *buf)
27718+{
27719+ ssize_t err;
27720+ static char *conf =
27721+/* this file is generated at compiling */
27722+#include "conf.str"
27723+ ;
27724+
27725+ err = snprintf(buf, PAGE_SIZE, conf);
27726+ if (unlikely(err >= PAGE_SIZE))
27727+ err = -EFBIG;
27728+ return err;
27729+}
27730+
27731+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
27732+#endif
27733+
1facf9fc 27734+static struct attribute *au_attr[] = {
4a4d8108
AM
27735+#ifdef CONFIG_AUFS_FS_MODULE
27736+ &au_config_attr.attr,
27737+#endif
1facf9fc 27738+ NULL, /* need to NULL terminate the list of attributes */
27739+};
27740+
27741+static struct attribute_group sysaufs_attr_group_body = {
27742+ .attrs = au_attr
27743+};
27744+
27745+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
27746+
27747+/* ---------------------------------------------------------------------- */
27748+
27749+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
27750+{
27751+ int err;
27752+
dece6358
AM
27753+ SiMustAnyLock(sb);
27754+
1facf9fc 27755+ err = 0;
27756+ if (au_opt_test(au_mntflags(sb), XINO)) {
27757+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
27758+ seq_putc(seq, '\n');
27759+ }
27760+ return err;
27761+}
27762+
27763+/*
27764+ * the lifetime of branch is independent from the entry under sysfs.
27765+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
27766+ * unlinked.
27767+ */
27768+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 27769+ aufs_bindex_t bindex, int idx)
1facf9fc 27770+{
1e00d052 27771+ int err;
1facf9fc 27772+ struct path path;
27773+ struct dentry *root;
27774+ struct au_branch *br;
076b876e 27775+ au_br_perm_str_t perm;
1facf9fc 27776+
27777+ AuDbg("b%d\n", bindex);
27778+
1e00d052 27779+ err = 0;
1facf9fc 27780+ root = sb->s_root;
27781+ di_read_lock_parent(root, !AuLock_IR);
27782+ br = au_sbr(sb, bindex);
392086de
AM
27783+
27784+ switch (idx) {
27785+ case AuBrSysfs_BR:
27786+ path.mnt = au_br_mnt(br);
27787+ path.dentry = au_h_dptr(root, bindex);
27788+ au_seq_path(seq, &path);
076b876e
AM
27789+ au_optstr_br_perm(&perm, br->br_perm);
27790+ err = seq_printf(seq, "=%s\n", perm.a);
392086de
AM
27791+ break;
27792+ case AuBrSysfs_BRID:
27793+ err = seq_printf(seq, "%d\n", br->br_id);
392086de
AM
27794+ break;
27795+ }
076b876e
AM
27796+ di_read_unlock(root, !AuLock_IR);
27797+ if (err == -1)
27798+ err = -E2BIG;
392086de 27799+
1e00d052 27800+ return err;
1facf9fc 27801+}
27802+
27803+/* ---------------------------------------------------------------------- */
27804+
27805+static struct seq_file *au_seq(char *p, ssize_t len)
27806+{
27807+ struct seq_file *seq;
27808+
27809+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
27810+ if (seq) {
27811+ /* mutex_init(&seq.lock); */
27812+ seq->buf = p;
27813+ seq->size = len;
27814+ return seq; /* success */
27815+ }
27816+
27817+ seq = ERR_PTR(-ENOMEM);
27818+ return seq;
27819+}
27820+
392086de
AM
27821+#define SysaufsBr_PREFIX "br"
27822+#define SysaufsBrid_PREFIX "brid"
1facf9fc 27823+
27824+/* todo: file size may exceed PAGE_SIZE */
27825+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 27826+ char *buf)
1facf9fc 27827+{
27828+ ssize_t err;
392086de 27829+ int idx;
1facf9fc 27830+ long l;
27831+ aufs_bindex_t bend;
27832+ struct au_sbinfo *sbinfo;
27833+ struct super_block *sb;
27834+ struct seq_file *seq;
27835+ char *name;
27836+ struct attribute **cattr;
27837+
27838+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
27839+ sb = sbinfo->si_sb;
1308ab2a 27840+
27841+ /*
27842+ * prevent a race condition between sysfs and aufs.
27843+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
27844+ * prohibits maintaining the sysfs entries.
27845+ * hew we acquire read lock after sysfs_get_active_two().
27846+ * on the other hand, the remount process may maintain the sysfs/aufs
27847+ * entries after acquiring write lock.
27848+ * it can cause a deadlock.
27849+ * simply we gave up processing read here.
27850+ */
27851+ err = -EBUSY;
27852+ if (unlikely(!si_noflush_read_trylock(sb)))
27853+ goto out;
1facf9fc 27854+
27855+ seq = au_seq(buf, PAGE_SIZE);
27856+ err = PTR_ERR(seq);
27857+ if (IS_ERR(seq))
1308ab2a 27858+ goto out_unlock;
1facf9fc 27859+
27860+ name = (void *)attr->name;
27861+ cattr = sysaufs_si_attrs;
27862+ while (*cattr) {
27863+ if (!strcmp(name, (*cattr)->name)) {
27864+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
27865+ ->show(seq, sb);
27866+ goto out_seq;
27867+ }
27868+ cattr++;
27869+ }
27870+
392086de
AM
27871+ if (!strncmp(name, SysaufsBrid_PREFIX,
27872+ sizeof(SysaufsBrid_PREFIX) - 1)) {
27873+ idx = AuBrSysfs_BRID;
27874+ name += sizeof(SysaufsBrid_PREFIX) - 1;
27875+ } else if (!strncmp(name, SysaufsBr_PREFIX,
27876+ sizeof(SysaufsBr_PREFIX) - 1)) {
27877+ idx = AuBrSysfs_BR;
1facf9fc 27878+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
27879+ } else
27880+ BUG();
27881+
27882+ err = kstrtol(name, 10, &l);
27883+ if (!err) {
27884+ bend = au_sbend(sb);
27885+ if (l <= bend)
27886+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
27887+ else
27888+ err = -ENOENT;
1facf9fc 27889+ }
1facf9fc 27890+
4f0767ce 27891+out_seq:
1facf9fc 27892+ if (!err) {
27893+ err = seq->count;
27894+ /* sysfs limit */
27895+ if (unlikely(err == PAGE_SIZE))
27896+ err = -EFBIG;
27897+ }
27898+ kfree(seq);
4f0767ce 27899+out_unlock:
1facf9fc 27900+ si_read_unlock(sb);
4f0767ce 27901+out:
1facf9fc 27902+ return err;
27903+}
27904+
27905+/* ---------------------------------------------------------------------- */
27906+
076b876e
AM
27907+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
27908+{
27909+ int err;
27910+ int16_t brid;
27911+ aufs_bindex_t bindex, bend;
27912+ size_t sz;
27913+ char *buf;
27914+ struct seq_file *seq;
27915+ struct au_branch *br;
27916+
27917+ si_read_lock(sb, AuLock_FLUSH);
27918+ bend = au_sbend(sb);
27919+ err = bend + 1;
27920+ if (!arg)
27921+ goto out;
27922+
27923+ err = -ENOMEM;
27924+ buf = (void *)__get_free_page(GFP_NOFS);
27925+ if (unlikely(!buf))
27926+ goto out;
27927+
27928+ seq = au_seq(buf, PAGE_SIZE);
27929+ err = PTR_ERR(seq);
27930+ if (IS_ERR(seq))
27931+ goto out_buf;
27932+
27933+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
27934+ for (bindex = 0; bindex <= bend; bindex++, arg++) {
27935+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
27936+ if (unlikely(err))
27937+ break;
27938+
27939+ br = au_sbr(sb, bindex);
27940+ brid = br->br_id;
27941+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
27942+ err = __put_user(brid, &arg->id);
27943+ if (unlikely(err))
27944+ break;
27945+
27946+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
27947+ err = __put_user(br->br_perm, &arg->perm);
27948+ if (unlikely(err))
27949+ break;
27950+
27951+ au_seq_path(seq, &br->br_path);
27952+ err = seq_putc(seq, '\0');
27953+ if (!err && seq->count <= sz) {
27954+ err = copy_to_user(arg->path, seq->buf, seq->count);
27955+ seq->count = 0;
27956+ if (unlikely(err))
27957+ break;
27958+ } else {
27959+ err = -E2BIG;
27960+ goto out_seq;
27961+ }
27962+ }
27963+ if (unlikely(err))
27964+ err = -EFAULT;
27965+
27966+out_seq:
27967+ kfree(seq);
27968+out_buf:
27969+ free_page((unsigned long)buf);
27970+out:
27971+ si_read_unlock(sb);
27972+ return err;
27973+}
27974+
27975+long au_brinfo_ioctl(struct file *file, unsigned long arg)
27976+{
27977+ return au_brinfo(file->f_dentry->d_sb, (void __user *)arg);
27978+}
27979+
27980+#ifdef CONFIG_COMPAT
27981+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
27982+{
27983+ return au_brinfo(file->f_dentry->d_sb, compat_ptr(arg));
27984+}
27985+#endif
27986+
27987+/* ---------------------------------------------------------------------- */
27988+
1facf9fc 27989+void sysaufs_br_init(struct au_branch *br)
27990+{
392086de
AM
27991+ int i;
27992+ struct au_brsysfs *br_sysfs;
27993+ struct attribute *attr;
4a4d8108 27994+
392086de
AM
27995+ br_sysfs = br->br_sysfs;
27996+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
27997+ attr = &br_sysfs->attr;
27998+ sysfs_attr_init(attr);
27999+ attr->name = br_sysfs->name;
28000+ attr->mode = S_IRUGO;
28001+ br_sysfs++;
28002+ }
1facf9fc 28003+}
28004+
28005+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
28006+{
28007+ struct au_branch *br;
28008+ struct kobject *kobj;
392086de
AM
28009+ struct au_brsysfs *br_sysfs;
28010+ int i;
1facf9fc 28011+ aufs_bindex_t bend;
28012+
28013+ dbgaufs_brs_del(sb, bindex);
28014+
28015+ if (!sysaufs_brs)
28016+ return;
28017+
28018+ kobj = &au_sbi(sb)->si_kobj;
28019+ bend = au_sbend(sb);
28020+ for (; bindex <= bend; bindex++) {
28021+ br = au_sbr(sb, bindex);
392086de
AM
28022+ br_sysfs = br->br_sysfs;
28023+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28024+ sysfs_remove_file(kobj, &br_sysfs->attr);
28025+ br_sysfs++;
28026+ }
1facf9fc 28027+ }
28028+}
28029+
28030+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
28031+{
392086de 28032+ int err, i;
1facf9fc 28033+ aufs_bindex_t bend;
28034+ struct kobject *kobj;
28035+ struct au_branch *br;
392086de 28036+ struct au_brsysfs *br_sysfs;
1facf9fc 28037+
28038+ dbgaufs_brs_add(sb, bindex);
28039+
28040+ if (!sysaufs_brs)
28041+ return;
28042+
28043+ kobj = &au_sbi(sb)->si_kobj;
28044+ bend = au_sbend(sb);
28045+ for (; bindex <= bend; bindex++) {
28046+ br = au_sbr(sb, bindex);
392086de
AM
28047+ br_sysfs = br->br_sysfs;
28048+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
28049+ SysaufsBr_PREFIX "%d", bindex);
28050+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
28051+ SysaufsBrid_PREFIX "%d", bindex);
28052+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28053+ err = sysfs_create_file(kobj, &br_sysfs->attr);
28054+ if (unlikely(err))
28055+ pr_warn("failed %s under sysfs(%d)\n",
28056+ br_sysfs->name, err);
28057+ br_sysfs++;
28058+ }
1facf9fc 28059+ }
28060+}
7f207e10
AM
28061diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
28062--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
28063+++ linux/fs/aufs/sysrq.c 2014-08-14 10:15:45.131942973 +0200
28064@@ -0,0 +1,157 @@
1facf9fc 28065+/*
523b37e3 28066+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28067+ *
28068+ * This program, aufs is free software; you can redistribute it and/or modify
28069+ * it under the terms of the GNU General Public License as published by
28070+ * the Free Software Foundation; either version 2 of the License, or
28071+ * (at your option) any later version.
dece6358
AM
28072+ *
28073+ * This program is distributed in the hope that it will be useful,
28074+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28075+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28076+ * GNU General Public License for more details.
28077+ *
28078+ * You should have received a copy of the GNU General Public License
523b37e3 28079+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28080+ */
28081+
28082+/*
28083+ * magic sysrq hanlder
28084+ */
28085+
1facf9fc 28086+/* #include <linux/sysrq.h> */
027c5e7a 28087+#include <linux/writeback.h>
1facf9fc 28088+#include "aufs.h"
28089+
28090+/* ---------------------------------------------------------------------- */
28091+
28092+static void sysrq_sb(struct super_block *sb)
28093+{
28094+ char *plevel;
28095+ struct au_sbinfo *sbinfo;
28096+ struct file *file;
523b37e3
AM
28097+ struct au_sphlhead *files;
28098+ struct au_finfo *finfo;
1facf9fc 28099+
28100+ plevel = au_plevel;
28101+ au_plevel = KERN_WARNING;
1facf9fc 28102+
4a4d8108 28103+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
28104+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
28105+
28106+ sbinfo = au_sbi(sb);
4a4d8108 28107+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 28108+ pr("superblock\n");
1facf9fc 28109+ au_dpri_sb(sb);
027c5e7a
AM
28110+
28111+#if 0
c06a8ce3 28112+ pr("root dentry\n");
1facf9fc 28113+ au_dpri_dentry(sb->s_root);
c06a8ce3 28114+ pr("root inode\n");
1facf9fc 28115+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
28116+#endif
28117+
1facf9fc 28118+#if 0
027c5e7a
AM
28119+ do {
28120+ int err, i, j, ndentry;
28121+ struct au_dcsub_pages dpages;
28122+ struct au_dpage *dpage;
28123+
28124+ err = au_dpages_init(&dpages, GFP_ATOMIC);
28125+ if (unlikely(err))
28126+ break;
28127+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
28128+ if (!err)
28129+ for (i = 0; i < dpages.ndpage; i++) {
28130+ dpage = dpages.dpages + i;
28131+ ndentry = dpage->ndentry;
28132+ for (j = 0; j < ndentry; j++)
28133+ au_dpri_dentry(dpage->dentries[j]);
28134+ }
28135+ au_dpages_free(&dpages);
28136+ } while (0);
28137+#endif
28138+
28139+#if 1
28140+ {
28141+ struct inode *i;
076b876e 28142+
c06a8ce3 28143+ pr("isolated inode\n");
2cbb1c4b
JR
28144+ spin_lock(&inode_sb_list_lock);
28145+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
28146+ spin_lock(&i->i_lock);
b4510431 28147+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 28148+ au_dpri_inode(i);
2cbb1c4b
JR
28149+ spin_unlock(&i->i_lock);
28150+ }
28151+ spin_unlock(&inode_sb_list_lock);
027c5e7a 28152+ }
1facf9fc 28153+#endif
c06a8ce3 28154+ pr("files\n");
523b37e3
AM
28155+ files = &au_sbi(sb)->si_files;
28156+ spin_lock(&files->spin);
28157+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
4a4d8108 28158+ umode_t mode;
076b876e 28159+
523b37e3 28160+ file = finfo->fi_file;
c06a8ce3 28161+ mode = file_inode(file)->i_mode;
38d290e6 28162+ if (!special_file(mode))
1facf9fc 28163+ au_dpri_file(file);
523b37e3
AM
28164+ }
28165+ spin_unlock(&files->spin);
c06a8ce3 28166+ pr("done\n");
1facf9fc 28167+
c06a8ce3 28168+#undef pr
1facf9fc 28169+ au_plevel = plevel;
1facf9fc 28170+}
28171+
28172+/* ---------------------------------------------------------------------- */
28173+
28174+/* module parameter */
28175+static char *aufs_sysrq_key = "a";
28176+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
28177+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
28178+
0c5527e5 28179+static void au_sysrq(int key __maybe_unused)
1facf9fc 28180+{
1facf9fc 28181+ struct au_sbinfo *sbinfo;
28182+
027c5e7a 28183+ lockdep_off();
53392da6 28184+ au_sbilist_lock();
e49829fe 28185+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 28186+ sysrq_sb(sbinfo->si_sb);
53392da6 28187+ au_sbilist_unlock();
027c5e7a 28188+ lockdep_on();
1facf9fc 28189+}
28190+
28191+static struct sysrq_key_op au_sysrq_op = {
28192+ .handler = au_sysrq,
28193+ .help_msg = "Aufs",
28194+ .action_msg = "Aufs",
28195+ .enable_mask = SYSRQ_ENABLE_DUMP
28196+};
28197+
28198+/* ---------------------------------------------------------------------- */
28199+
28200+int __init au_sysrq_init(void)
28201+{
28202+ int err;
28203+ char key;
28204+
28205+ err = -1;
28206+ key = *aufs_sysrq_key;
28207+ if ('a' <= key && key <= 'z')
28208+ err = register_sysrq_key(key, &au_sysrq_op);
28209+ if (unlikely(err))
4a4d8108 28210+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 28211+ return err;
28212+}
28213+
28214+void au_sysrq_fin(void)
28215+{
28216+ int err;
076b876e 28217+
1facf9fc 28218+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
28219+ if (unlikely(err))
4a4d8108 28220+ pr_err("err %d (ignored)\n", err);
1facf9fc 28221+}
7f207e10
AM
28222diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
28223--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
28224+++ linux/fs/aufs/vdir.c 2014-08-14 10:15:45.131942973 +0200
28225@@ -0,0 +1,889 @@
1facf9fc 28226+/*
523b37e3 28227+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28228+ *
28229+ * This program, aufs is free software; you can redistribute it and/or modify
28230+ * it under the terms of the GNU General Public License as published by
28231+ * the Free Software Foundation; either version 2 of the License, or
28232+ * (at your option) any later version.
dece6358
AM
28233+ *
28234+ * This program is distributed in the hope that it will be useful,
28235+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28236+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28237+ * GNU General Public License for more details.
28238+ *
28239+ * You should have received a copy of the GNU General Public License
523b37e3 28240+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28241+ */
28242+
28243+/*
28244+ * virtual or vertical directory
28245+ */
28246+
28247+#include "aufs.h"
28248+
dece6358 28249+static unsigned int calc_size(int nlen)
1facf9fc 28250+{
dece6358 28251+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 28252+}
28253+
28254+static int set_deblk_end(union au_vdir_deblk_p *p,
28255+ union au_vdir_deblk_p *deblk_end)
28256+{
28257+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
28258+ p->de->de_str.len = 0;
28259+ /* smp_mb(); */
28260+ return 0;
28261+ }
28262+ return -1; /* error */
28263+}
28264+
28265+/* returns true or false */
28266+static int is_deblk_end(union au_vdir_deblk_p *p,
28267+ union au_vdir_deblk_p *deblk_end)
28268+{
28269+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
28270+ return !p->de->de_str.len;
28271+ return 1;
28272+}
28273+
28274+static unsigned char *last_deblk(struct au_vdir *vdir)
28275+{
28276+ return vdir->vd_deblk[vdir->vd_nblk - 1];
28277+}
28278+
28279+/* ---------------------------------------------------------------------- */
28280+
1308ab2a 28281+/* estimate the apropriate size for name hash table */
28282+unsigned int au_rdhash_est(loff_t sz)
28283+{
28284+ unsigned int n;
28285+
28286+ n = UINT_MAX;
28287+ sz >>= 10;
28288+ if (sz < n)
28289+ n = sz;
28290+ if (sz < AUFS_RDHASH_DEF)
28291+ n = AUFS_RDHASH_DEF;
4a4d8108 28292+ /* pr_info("n %u\n", n); */
1308ab2a 28293+ return n;
28294+}
28295+
1facf9fc 28296+/*
28297+ * the allocated memory has to be freed by
dece6358 28298+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 28299+ */
dece6358 28300+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 28301+{
1facf9fc 28302+ struct hlist_head *head;
dece6358 28303+ unsigned int u;
076b876e 28304+ size_t sz;
1facf9fc 28305+
076b876e
AM
28306+ sz = sizeof(*nhash->nh_head) * num_hash;
28307+ head = kmalloc(sz, gfp);
dece6358
AM
28308+ if (head) {
28309+ nhash->nh_num = num_hash;
28310+ nhash->nh_head = head;
28311+ for (u = 0; u < num_hash; u++)
1facf9fc 28312+ INIT_HLIST_HEAD(head++);
dece6358 28313+ return 0; /* success */
1facf9fc 28314+ }
1facf9fc 28315+
dece6358 28316+ return -ENOMEM;
1facf9fc 28317+}
28318+
dece6358
AM
28319+static void nhash_count(struct hlist_head *head)
28320+{
28321+#if 0
28322+ unsigned long n;
28323+ struct hlist_node *pos;
28324+
28325+ n = 0;
28326+ hlist_for_each(pos, head)
28327+ n++;
4a4d8108 28328+ pr_info("%lu\n", n);
dece6358
AM
28329+#endif
28330+}
28331+
28332+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 28333+{
c06a8ce3
AM
28334+ struct au_vdir_wh *pos;
28335+ struct hlist_node *node;
1facf9fc 28336+
c06a8ce3
AM
28337+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
28338+ kfree(pos);
1facf9fc 28339+}
28340+
dece6358 28341+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 28342+{
c06a8ce3
AM
28343+ struct au_vdir_dehstr *pos;
28344+ struct hlist_node *node;
1facf9fc 28345+
c06a8ce3
AM
28346+ hlist_for_each_entry_safe(pos, node, head, hash)
28347+ au_cache_free_vdir_dehstr(pos);
1facf9fc 28348+}
28349+
dece6358
AM
28350+static void au_nhash_do_free(struct au_nhash *nhash,
28351+ void (*free)(struct hlist_head *head))
1facf9fc 28352+{
1308ab2a 28353+ unsigned int n;
1facf9fc 28354+ struct hlist_head *head;
1facf9fc 28355+
dece6358 28356+ n = nhash->nh_num;
1308ab2a 28357+ if (!n)
28358+ return;
28359+
dece6358 28360+ head = nhash->nh_head;
1308ab2a 28361+ while (n-- > 0) {
dece6358
AM
28362+ nhash_count(head);
28363+ free(head++);
1facf9fc 28364+ }
dece6358 28365+ kfree(nhash->nh_head);
1facf9fc 28366+}
28367+
dece6358 28368+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 28369+{
dece6358
AM
28370+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
28371+}
1facf9fc 28372+
dece6358
AM
28373+static void au_nhash_de_free(struct au_nhash *delist)
28374+{
28375+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 28376+}
28377+
28378+/* ---------------------------------------------------------------------- */
28379+
28380+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
28381+ int limit)
28382+{
28383+ int num;
28384+ unsigned int u, n;
28385+ struct hlist_head *head;
c06a8ce3 28386+ struct au_vdir_wh *pos;
1facf9fc 28387+
28388+ num = 0;
28389+ n = whlist->nh_num;
28390+ head = whlist->nh_head;
1308ab2a 28391+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
28392+ hlist_for_each_entry(pos, head, wh_hash)
28393+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 28394+ return 1;
1facf9fc 28395+ return 0;
28396+}
28397+
28398+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 28399+ unsigned char *name,
1facf9fc 28400+ unsigned int len)
28401+{
dece6358
AM
28402+ unsigned int v;
28403+ /* const unsigned int magic_bit = 12; */
28404+
1308ab2a 28405+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
28406+
dece6358
AM
28407+ v = 0;
28408+ while (len--)
28409+ v += *name++;
28410+ /* v = hash_long(v, magic_bit); */
28411+ v %= nhash->nh_num;
28412+ return nhash->nh_head + v;
28413+}
28414+
28415+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
28416+ int nlen)
28417+{
28418+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 28419+}
28420+
28421+/* returns found or not */
dece6358 28422+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 28423+{
28424+ struct hlist_head *head;
c06a8ce3 28425+ struct au_vdir_wh *pos;
1facf9fc 28426+ struct au_vdir_destr *str;
28427+
dece6358 28428+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
28429+ hlist_for_each_entry(pos, head, wh_hash) {
28430+ str = &pos->wh_str;
1facf9fc 28431+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
28432+ if (au_nhash_test_name(str, name, nlen))
28433+ return 1;
28434+ }
28435+ return 0;
28436+}
28437+
28438+/* returns found(true) or not */
28439+static int test_known(struct au_nhash *delist, char *name, int nlen)
28440+{
28441+ struct hlist_head *head;
c06a8ce3 28442+ struct au_vdir_dehstr *pos;
dece6358
AM
28443+ struct au_vdir_destr *str;
28444+
28445+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
28446+ hlist_for_each_entry(pos, head, hash) {
28447+ str = pos->str;
dece6358
AM
28448+ AuDbg("%.*s\n", str->len, str->name);
28449+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 28450+ return 1;
28451+ }
28452+ return 0;
28453+}
28454+
dece6358
AM
28455+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
28456+ unsigned char d_type)
28457+{
28458+#ifdef CONFIG_AUFS_SHWH
28459+ wh->wh_ino = ino;
28460+ wh->wh_type = d_type;
28461+#endif
28462+}
28463+
28464+/* ---------------------------------------------------------------------- */
28465+
28466+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
28467+ unsigned int d_type, aufs_bindex_t bindex,
28468+ unsigned char shwh)
1facf9fc 28469+{
28470+ int err;
28471+ struct au_vdir_destr *str;
28472+ struct au_vdir_wh *wh;
28473+
dece6358 28474+ AuDbg("%.*s\n", nlen, name);
1308ab2a 28475+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
28476+
1facf9fc 28477+ err = -ENOMEM;
dece6358 28478+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 28479+ if (unlikely(!wh))
28480+ goto out;
28481+
28482+ err = 0;
28483+ wh->wh_bindex = bindex;
dece6358
AM
28484+ if (shwh)
28485+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 28486+ str = &wh->wh_str;
dece6358
AM
28487+ str->len = nlen;
28488+ memcpy(str->name, name, nlen);
28489+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 28490+ /* smp_mb(); */
28491+
4f0767ce 28492+out:
1facf9fc 28493+ return err;
28494+}
28495+
1facf9fc 28496+static int append_deblk(struct au_vdir *vdir)
28497+{
28498+ int err;
dece6358 28499+ unsigned long ul;
1facf9fc 28500+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
28501+ union au_vdir_deblk_p p, deblk_end;
28502+ unsigned char **o;
28503+
28504+ err = -ENOMEM;
dece6358
AM
28505+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
28506+ GFP_NOFS);
1facf9fc 28507+ if (unlikely(!o))
28508+ goto out;
28509+
28510+ vdir->vd_deblk = o;
28511+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
28512+ if (p.deblk) {
28513+ ul = vdir->vd_nblk++;
28514+ vdir->vd_deblk[ul] = p.deblk;
28515+ vdir->vd_last.ul = ul;
28516+ vdir->vd_last.p.deblk = p.deblk;
28517+ deblk_end.deblk = p.deblk + deblk_sz;
28518+ err = set_deblk_end(&p, &deblk_end);
28519+ }
28520+
4f0767ce 28521+out:
1facf9fc 28522+ return err;
28523+}
28524+
dece6358
AM
28525+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
28526+ unsigned int d_type, struct au_nhash *delist)
28527+{
28528+ int err;
28529+ unsigned int sz;
28530+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
28531+ union au_vdir_deblk_p p, *room, deblk_end;
28532+ struct au_vdir_dehstr *dehstr;
28533+
28534+ p.deblk = last_deblk(vdir);
28535+ deblk_end.deblk = p.deblk + deblk_sz;
28536+ room = &vdir->vd_last.p;
28537+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
28538+ || !is_deblk_end(room, &deblk_end));
28539+
28540+ sz = calc_size(nlen);
28541+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
28542+ err = append_deblk(vdir);
28543+ if (unlikely(err))
28544+ goto out;
28545+
28546+ p.deblk = last_deblk(vdir);
28547+ deblk_end.deblk = p.deblk + deblk_sz;
28548+ /* smp_mb(); */
28549+ AuDebugOn(room->deblk != p.deblk);
28550+ }
28551+
28552+ err = -ENOMEM;
4a4d8108 28553+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
28554+ if (unlikely(!dehstr))
28555+ goto out;
28556+
28557+ dehstr->str = &room->de->de_str;
28558+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
28559+ room->de->de_ino = ino;
28560+ room->de->de_type = d_type;
28561+ room->de->de_str.len = nlen;
28562+ memcpy(room->de->de_str.name, name, nlen);
28563+
28564+ err = 0;
28565+ room->deblk += sz;
28566+ if (unlikely(set_deblk_end(room, &deblk_end)))
28567+ err = append_deblk(vdir);
28568+ /* smp_mb(); */
28569+
4f0767ce 28570+out:
dece6358
AM
28571+ return err;
28572+}
28573+
28574+/* ---------------------------------------------------------------------- */
28575+
28576+void au_vdir_free(struct au_vdir *vdir)
28577+{
28578+ unsigned char **deblk;
28579+
28580+ deblk = vdir->vd_deblk;
28581+ while (vdir->vd_nblk--)
28582+ kfree(*deblk++);
28583+ kfree(vdir->vd_deblk);
28584+ au_cache_free_vdir(vdir);
28585+}
28586+
1308ab2a 28587+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 28588+{
28589+ struct au_vdir *vdir;
1308ab2a 28590+ struct super_block *sb;
1facf9fc 28591+ int err;
28592+
1308ab2a 28593+ sb = file->f_dentry->d_sb;
dece6358
AM
28594+ SiMustAnyLock(sb);
28595+
1facf9fc 28596+ err = -ENOMEM;
28597+ vdir = au_cache_alloc_vdir();
28598+ if (unlikely(!vdir))
28599+ goto out;
28600+
28601+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
28602+ if (unlikely(!vdir->vd_deblk))
28603+ goto out_free;
28604+
28605+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 28606+ if (!vdir->vd_deblk_sz) {
28607+ /* estimate the apropriate size for deblk */
28608+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 28609+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 28610+ }
1facf9fc 28611+ vdir->vd_nblk = 0;
28612+ vdir->vd_version = 0;
28613+ vdir->vd_jiffy = 0;
28614+ err = append_deblk(vdir);
28615+ if (!err)
28616+ return vdir; /* success */
28617+
28618+ kfree(vdir->vd_deblk);
28619+
4f0767ce 28620+out_free:
1facf9fc 28621+ au_cache_free_vdir(vdir);
4f0767ce 28622+out:
1facf9fc 28623+ vdir = ERR_PTR(err);
28624+ return vdir;
28625+}
28626+
28627+static int reinit_vdir(struct au_vdir *vdir)
28628+{
28629+ int err;
28630+ union au_vdir_deblk_p p, deblk_end;
28631+
28632+ while (vdir->vd_nblk > 1) {
28633+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
28634+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
28635+ vdir->vd_nblk--;
28636+ }
28637+ p.deblk = vdir->vd_deblk[0];
28638+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
28639+ err = set_deblk_end(&p, &deblk_end);
28640+ /* keep vd_dblk_sz */
28641+ vdir->vd_last.ul = 0;
28642+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
28643+ vdir->vd_version = 0;
28644+ vdir->vd_jiffy = 0;
28645+ /* smp_mb(); */
28646+ return err;
28647+}
28648+
28649+/* ---------------------------------------------------------------------- */
28650+
1facf9fc 28651+#define AuFillVdir_CALLED 1
28652+#define AuFillVdir_WHABLE (1 << 1)
dece6358 28653+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 28654+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
28655+#define au_fset_fillvdir(flags, name) \
28656+ do { (flags) |= AuFillVdir_##name; } while (0)
28657+#define au_fclr_fillvdir(flags, name) \
28658+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 28659+
dece6358
AM
28660+#ifndef CONFIG_AUFS_SHWH
28661+#undef AuFillVdir_SHWH
28662+#define AuFillVdir_SHWH 0
28663+#endif
28664+
1facf9fc 28665+struct fillvdir_arg {
392086de 28666+ struct dir_context ctx;
1facf9fc 28667+ struct file *file;
28668+ struct au_vdir *vdir;
dece6358
AM
28669+ struct au_nhash delist;
28670+ struct au_nhash whlist;
1facf9fc 28671+ aufs_bindex_t bindex;
28672+ unsigned int flags;
28673+ int err;
28674+};
28675+
392086de 28676+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 28677+ loff_t offset __maybe_unused, u64 h_ino,
28678+ unsigned int d_type)
28679+{
392086de 28680+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 28681+ char *name = (void *)__name;
28682+ struct super_block *sb;
1facf9fc 28683+ ino_t ino;
dece6358 28684+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 28685+
1facf9fc 28686+ arg->err = 0;
dece6358 28687+ sb = arg->file->f_dentry->d_sb;
1facf9fc 28688+ au_fset_fillvdir(arg->flags, CALLED);
28689+ /* smp_mb(); */
dece6358 28690+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 28691+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
28692+ if (test_known(&arg->delist, name, nlen)
28693+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
28694+ goto out; /* already exists or whiteouted */
1facf9fc 28695+
28696+ sb = arg->file->f_dentry->d_sb;
dece6358 28697+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
28698+ if (!arg->err) {
28699+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
28700+ d_type = DT_UNKNOWN;
dece6358
AM
28701+ arg->err = append_de(arg->vdir, name, nlen, ino,
28702+ d_type, &arg->delist);
4a4d8108 28703+ }
1facf9fc 28704+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
28705+ name += AUFS_WH_PFX_LEN;
dece6358
AM
28706+ nlen -= AUFS_WH_PFX_LEN;
28707+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
28708+ goto out; /* already whiteouted */
1facf9fc 28709+
dece6358
AM
28710+ if (shwh)
28711+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
28712+ &ino);
4a4d8108
AM
28713+ if (!arg->err) {
28714+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
28715+ d_type = DT_UNKNOWN;
1facf9fc 28716+ arg->err = au_nhash_append_wh
dece6358
AM
28717+ (&arg->whlist, name, nlen, ino, d_type,
28718+ arg->bindex, shwh);
4a4d8108 28719+ }
1facf9fc 28720+ }
28721+
4f0767ce 28722+out:
1facf9fc 28723+ if (!arg->err)
28724+ arg->vdir->vd_jiffy = jiffies;
28725+ /* smp_mb(); */
28726+ AuTraceErr(arg->err);
28727+ return arg->err;
28728+}
28729+
dece6358
AM
28730+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
28731+ struct au_nhash *whlist, struct au_nhash *delist)
28732+{
28733+#ifdef CONFIG_AUFS_SHWH
28734+ int err;
28735+ unsigned int nh, u;
28736+ struct hlist_head *head;
c06a8ce3
AM
28737+ struct au_vdir_wh *pos;
28738+ struct hlist_node *n;
dece6358
AM
28739+ char *p, *o;
28740+ struct au_vdir_destr *destr;
28741+
28742+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
28743+
28744+ err = -ENOMEM;
537831f9 28745+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
28746+ if (unlikely(!p))
28747+ goto out;
28748+
28749+ err = 0;
28750+ nh = whlist->nh_num;
28751+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
28752+ p += AUFS_WH_PFX_LEN;
28753+ for (u = 0; u < nh; u++) {
28754+ head = whlist->nh_head + u;
c06a8ce3
AM
28755+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
28756+ destr = &pos->wh_str;
dece6358
AM
28757+ memcpy(p, destr->name, destr->len);
28758+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 28759+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
28760+ if (unlikely(err))
28761+ break;
28762+ }
28763+ }
28764+
537831f9 28765+ free_page((unsigned long)o);
dece6358 28766+
4f0767ce 28767+out:
dece6358
AM
28768+ AuTraceErr(err);
28769+ return err;
28770+#else
28771+ return 0;
28772+#endif
28773+}
28774+
1facf9fc 28775+static int au_do_read_vdir(struct fillvdir_arg *arg)
28776+{
28777+ int err;
dece6358 28778+ unsigned int rdhash;
1facf9fc 28779+ loff_t offset;
dece6358
AM
28780+ aufs_bindex_t bend, bindex, bstart;
28781+ unsigned char shwh;
1facf9fc 28782+ struct file *hf, *file;
28783+ struct super_block *sb;
28784+
1facf9fc 28785+ file = arg->file;
28786+ sb = file->f_dentry->d_sb;
dece6358
AM
28787+ SiMustAnyLock(sb);
28788+
28789+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 28790+ if (!rdhash)
28791+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
28792+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
28793+ if (unlikely(err))
1facf9fc 28794+ goto out;
dece6358
AM
28795+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
28796+ if (unlikely(err))
1facf9fc 28797+ goto out_delist;
28798+
28799+ err = 0;
28800+ arg->flags = 0;
dece6358
AM
28801+ shwh = 0;
28802+ if (au_opt_test(au_mntflags(sb), SHWH)) {
28803+ shwh = 1;
28804+ au_fset_fillvdir(arg->flags, SHWH);
28805+ }
28806+ bstart = au_fbstart(file);
4a4d8108 28807+ bend = au_fbend_dir(file);
dece6358 28808+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 28809+ hf = au_hf_dir(file, bindex);
1facf9fc 28810+ if (!hf)
28811+ continue;
28812+
28813+ offset = vfsub_llseek(hf, 0, SEEK_SET);
28814+ err = offset;
28815+ if (unlikely(offset))
28816+ break;
28817+
28818+ arg->bindex = bindex;
28819+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
28820+ if (shwh
28821+ || (bindex != bend
28822+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 28823+ au_fset_fillvdir(arg->flags, WHABLE);
28824+ do {
28825+ arg->err = 0;
28826+ au_fclr_fillvdir(arg->flags, CALLED);
28827+ /* smp_mb(); */
392086de 28828+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 28829+ if (err >= 0)
28830+ err = arg->err;
28831+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
28832+
28833+ /*
28834+ * dir_relax() may be good for concurrency, but aufs should not
28835+ * use it since it will cause a lockdep problem.
28836+ */
1facf9fc 28837+ }
dece6358
AM
28838+
28839+ if (!err && shwh)
28840+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
28841+
28842+ au_nhash_wh_free(&arg->whlist);
1facf9fc 28843+
4f0767ce 28844+out_delist:
dece6358 28845+ au_nhash_de_free(&arg->delist);
4f0767ce 28846+out:
1facf9fc 28847+ return err;
28848+}
28849+
28850+static int read_vdir(struct file *file, int may_read)
28851+{
28852+ int err;
28853+ unsigned long expire;
28854+ unsigned char do_read;
392086de
AM
28855+ struct fillvdir_arg arg = {
28856+ .ctx = {
28857+ .actor = au_diractor(fillvdir)
28858+ }
28859+ };
1facf9fc 28860+ struct inode *inode;
28861+ struct au_vdir *vdir, *allocated;
28862+
28863+ err = 0;
c06a8ce3 28864+ inode = file_inode(file);
1facf9fc 28865+ IMustLock(inode);
dece6358
AM
28866+ SiMustAnyLock(inode->i_sb);
28867+
1facf9fc 28868+ allocated = NULL;
28869+ do_read = 0;
28870+ expire = au_sbi(inode->i_sb)->si_rdcache;
28871+ vdir = au_ivdir(inode);
28872+ if (!vdir) {
28873+ do_read = 1;
1308ab2a 28874+ vdir = alloc_vdir(file);
1facf9fc 28875+ err = PTR_ERR(vdir);
28876+ if (IS_ERR(vdir))
28877+ goto out;
28878+ err = 0;
28879+ allocated = vdir;
28880+ } else if (may_read
28881+ && (inode->i_version != vdir->vd_version
28882+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
28883+ do_read = 1;
28884+ err = reinit_vdir(vdir);
28885+ if (unlikely(err))
28886+ goto out;
28887+ }
28888+
28889+ if (!do_read)
28890+ return 0; /* success */
28891+
28892+ arg.file = file;
28893+ arg.vdir = vdir;
28894+ err = au_do_read_vdir(&arg);
28895+ if (!err) {
392086de 28896+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 28897+ vdir->vd_version = inode->i_version;
28898+ vdir->vd_last.ul = 0;
28899+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
28900+ if (allocated)
28901+ au_set_ivdir(inode, allocated);
28902+ } else if (allocated)
28903+ au_vdir_free(allocated);
28904+
4f0767ce 28905+out:
1facf9fc 28906+ return err;
28907+}
28908+
28909+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
28910+{
28911+ int err, rerr;
28912+ unsigned long ul, n;
28913+ const unsigned int deblk_sz = src->vd_deblk_sz;
28914+
28915+ AuDebugOn(tgt->vd_nblk != 1);
28916+
28917+ err = -ENOMEM;
28918+ if (tgt->vd_nblk < src->vd_nblk) {
28919+ unsigned char **p;
28920+
dece6358
AM
28921+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
28922+ GFP_NOFS);
1facf9fc 28923+ if (unlikely(!p))
28924+ goto out;
28925+ tgt->vd_deblk = p;
28926+ }
28927+
1308ab2a 28928+ if (tgt->vd_deblk_sz != deblk_sz) {
28929+ unsigned char *p;
28930+
28931+ tgt->vd_deblk_sz = deblk_sz;
28932+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
28933+ if (unlikely(!p))
28934+ goto out;
28935+ tgt->vd_deblk[0] = p;
28936+ }
1facf9fc 28937+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 28938+ tgt->vd_version = src->vd_version;
28939+ tgt->vd_jiffy = src->vd_jiffy;
28940+
28941+ n = src->vd_nblk;
28942+ for (ul = 1; ul < n; ul++) {
dece6358
AM
28943+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
28944+ GFP_NOFS);
28945+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 28946+ goto out;
1308ab2a 28947+ tgt->vd_nblk++;
1facf9fc 28948+ }
1308ab2a 28949+ tgt->vd_nblk = n;
28950+ tgt->vd_last.ul = tgt->vd_last.ul;
28951+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
28952+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
28953+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 28954+ /* smp_mb(); */
28955+ return 0; /* success */
28956+
4f0767ce 28957+out:
1facf9fc 28958+ rerr = reinit_vdir(tgt);
28959+ BUG_ON(rerr);
28960+ return err;
28961+}
28962+
28963+int au_vdir_init(struct file *file)
28964+{
28965+ int err;
28966+ struct inode *inode;
28967+ struct au_vdir *vdir_cache, *allocated;
28968+
392086de 28969+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 28970+ err = read_vdir(file, !file->f_pos);
28971+ if (unlikely(err))
28972+ goto out;
28973+
28974+ allocated = NULL;
28975+ vdir_cache = au_fvdir_cache(file);
28976+ if (!vdir_cache) {
1308ab2a 28977+ vdir_cache = alloc_vdir(file);
1facf9fc 28978+ err = PTR_ERR(vdir_cache);
28979+ if (IS_ERR(vdir_cache))
28980+ goto out;
28981+ allocated = vdir_cache;
28982+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 28983+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 28984+ err = reinit_vdir(vdir_cache);
28985+ if (unlikely(err))
28986+ goto out;
28987+ } else
28988+ return 0; /* success */
28989+
c06a8ce3 28990+ inode = file_inode(file);
1facf9fc 28991+ err = copy_vdir(vdir_cache, au_ivdir(inode));
28992+ if (!err) {
28993+ file->f_version = inode->i_version;
28994+ if (allocated)
28995+ au_set_fvdir_cache(file, allocated);
28996+ } else if (allocated)
28997+ au_vdir_free(allocated);
28998+
4f0767ce 28999+out:
1facf9fc 29000+ return err;
29001+}
29002+
29003+static loff_t calc_offset(struct au_vdir *vdir)
29004+{
29005+ loff_t offset;
29006+ union au_vdir_deblk_p p;
29007+
29008+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
29009+ offset = vdir->vd_last.p.deblk - p.deblk;
29010+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
29011+ return offset;
29012+}
29013+
29014+/* returns true or false */
392086de 29015+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 29016+{
29017+ int valid;
29018+ unsigned int deblk_sz;
29019+ unsigned long ul, n;
29020+ loff_t offset;
29021+ union au_vdir_deblk_p p, deblk_end;
29022+ struct au_vdir *vdir_cache;
29023+
29024+ valid = 1;
29025+ vdir_cache = au_fvdir_cache(file);
29026+ offset = calc_offset(vdir_cache);
29027+ AuDbg("offset %lld\n", offset);
392086de 29028+ if (ctx->pos == offset)
1facf9fc 29029+ goto out;
29030+
29031+ vdir_cache->vd_last.ul = 0;
29032+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 29033+ if (!ctx->pos)
1facf9fc 29034+ goto out;
29035+
29036+ valid = 0;
29037+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 29038+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 29039+ AuDbg("ul %lu\n", ul);
29040+ if (ul >= vdir_cache->vd_nblk)
29041+ goto out;
29042+
29043+ n = vdir_cache->vd_nblk;
29044+ for (; ul < n; ul++) {
29045+ p.deblk = vdir_cache->vd_deblk[ul];
29046+ deblk_end.deblk = p.deblk + deblk_sz;
29047+ offset = ul;
29048+ offset *= deblk_sz;
392086de 29049+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 29050+ unsigned int l;
29051+
29052+ l = calc_size(p.de->de_str.len);
29053+ offset += l;
29054+ p.deblk += l;
29055+ }
29056+ if (!is_deblk_end(&p, &deblk_end)) {
29057+ valid = 1;
29058+ vdir_cache->vd_last.ul = ul;
29059+ vdir_cache->vd_last.p = p;
29060+ break;
29061+ }
29062+ }
29063+
4f0767ce 29064+out:
1facf9fc 29065+ /* smp_mb(); */
29066+ AuTraceErr(!valid);
29067+ return valid;
29068+}
29069+
392086de 29070+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 29071+{
1facf9fc 29072+ unsigned int l, deblk_sz;
29073+ union au_vdir_deblk_p deblk_end;
29074+ struct au_vdir *vdir_cache;
29075+ struct au_vdir_de *de;
29076+
29077+ vdir_cache = au_fvdir_cache(file);
392086de 29078+ if (!seek_vdir(file, ctx))
1facf9fc 29079+ return 0;
29080+
29081+ deblk_sz = vdir_cache->vd_deblk_sz;
29082+ while (1) {
29083+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
29084+ deblk_end.deblk += deblk_sz;
29085+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
29086+ de = vdir_cache->vd_last.p.de;
29087+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 29088+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 29089+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
29090+ if (unlikely(!dir_emit(ctx, de->de_str.name,
29091+ de->de_str.len, de->de_ino,
29092+ de->de_type))) {
1facf9fc 29093+ /* todo: ignore the error caused by udba? */
29094+ /* return err; */
29095+ return 0;
29096+ }
29097+
29098+ l = calc_size(de->de_str.len);
29099+ vdir_cache->vd_last.p.deblk += l;
392086de 29100+ ctx->pos += l;
1facf9fc 29101+ }
29102+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
29103+ vdir_cache->vd_last.ul++;
29104+ vdir_cache->vd_last.p.deblk
29105+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 29106+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 29107+ continue;
29108+ }
29109+ break;
29110+ }
29111+
29112+ /* smp_mb(); */
29113+ return 0;
29114+}
7f207e10
AM
29115diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
29116--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
076b876e 29117+++ linux/fs/aufs/vfsub.c 2014-08-14 10:16:04.515942371 +0200
523b37e3 29118@@ -0,0 +1,782 @@
1facf9fc 29119+/*
523b37e3 29120+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 29121+ *
29122+ * This program, aufs is free software; you can redistribute it and/or modify
29123+ * it under the terms of the GNU General Public License as published by
29124+ * the Free Software Foundation; either version 2 of the License, or
29125+ * (at your option) any later version.
dece6358
AM
29126+ *
29127+ * This program is distributed in the hope that it will be useful,
29128+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29129+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29130+ * GNU General Public License for more details.
29131+ *
29132+ * You should have received a copy of the GNU General Public License
523b37e3 29133+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29134+ */
29135+
29136+/*
29137+ * sub-routines for VFS
29138+ */
29139+
1308ab2a 29140+#include <linux/ima.h>
dece6358
AM
29141+#include <linux/namei.h>
29142+#include <linux/security.h>
29143+#include <linux/splice.h>
1facf9fc 29144+#include "aufs.h"
29145+
29146+int vfsub_update_h_iattr(struct path *h_path, int *did)
29147+{
29148+ int err;
29149+ struct kstat st;
29150+ struct super_block *h_sb;
29151+
29152+ /* for remote fs, leave work for its getattr or d_revalidate */
29153+ /* for bad i_attr fs, handle them in aufs_getattr() */
29154+ /* still some fs may acquire i_mutex. we need to skip them */
29155+ err = 0;
29156+ if (!did)
29157+ did = &err;
29158+ h_sb = h_path->dentry->d_sb;
29159+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
29160+ if (*did)
c06a8ce3 29161+ err = vfs_getattr(h_path, &st);
1facf9fc 29162+
29163+ return err;
29164+}
29165+
29166+/* ---------------------------------------------------------------------- */
29167+
4a4d8108 29168+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 29169+{
29170+ struct file *file;
29171+
b4510431 29172+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 29173+ current_cred());
2cbb1c4b
JR
29174+ if (!IS_ERR_OR_NULL(file)
29175+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
29176+ i_readcount_inc(path->dentry->d_inode);
4a4d8108 29177+
1308ab2a 29178+ return file;
29179+}
29180+
1facf9fc 29181+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
29182+{
29183+ struct file *file;
29184+
2cbb1c4b 29185+ lockdep_off();
7f207e10 29186+ file = filp_open(path,
2cbb1c4b 29187+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 29188+ mode);
2cbb1c4b 29189+ lockdep_on();
1facf9fc 29190+ if (IS_ERR(file))
29191+ goto out;
29192+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29193+
4f0767ce 29194+out:
1facf9fc 29195+ return file;
29196+}
29197+
29198+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
29199+{
29200+ int err;
29201+
1facf9fc 29202+ err = kern_path(name, flags, path);
1facf9fc 29203+ if (!err && path->dentry->d_inode)
29204+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
29205+ return err;
29206+}
29207+
29208+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
29209+ int len)
29210+{
29211+ struct path path = {
29212+ .mnt = NULL
29213+ };
29214+
1308ab2a 29215+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 29216+ IMustLock(parent->d_inode);
29217+
29218+ path.dentry = lookup_one_len(name, parent, len);
29219+ if (IS_ERR(path.dentry))
29220+ goto out;
29221+ if (path.dentry->d_inode)
29222+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
29223+
4f0767ce 29224+out:
4a4d8108 29225+ AuTraceErrPtr(path.dentry);
1facf9fc 29226+ return path.dentry;
29227+}
29228+
b4510431 29229+void vfsub_call_lkup_one(void *args)
2cbb1c4b 29230+{
b4510431
AM
29231+ struct vfsub_lkup_one_args *a = args;
29232+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
29233+}
29234+
1facf9fc 29235+/* ---------------------------------------------------------------------- */
29236+
29237+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
29238+ struct dentry *d2, struct au_hinode *hdir2)
29239+{
29240+ struct dentry *d;
29241+
2cbb1c4b 29242+ lockdep_off();
1facf9fc 29243+ d = lock_rename(d1, d2);
2cbb1c4b 29244+ lockdep_on();
4a4d8108 29245+ au_hn_suspend(hdir1);
1facf9fc 29246+ if (hdir1 != hdir2)
4a4d8108 29247+ au_hn_suspend(hdir2);
1facf9fc 29248+
29249+ return d;
29250+}
29251+
29252+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
29253+ struct dentry *d2, struct au_hinode *hdir2)
29254+{
4a4d8108 29255+ au_hn_resume(hdir1);
1facf9fc 29256+ if (hdir1 != hdir2)
4a4d8108 29257+ au_hn_resume(hdir2);
2cbb1c4b 29258+ lockdep_off();
1facf9fc 29259+ unlock_rename(d1, d2);
2cbb1c4b 29260+ lockdep_on();
1facf9fc 29261+}
29262+
29263+/* ---------------------------------------------------------------------- */
29264+
b4510431 29265+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 29266+{
29267+ int err;
29268+ struct dentry *d;
29269+
29270+ IMustLock(dir);
29271+
29272+ d = path->dentry;
29273+ path->dentry = d->d_parent;
b752ccd1 29274+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 29275+ path->dentry = d;
29276+ if (unlikely(err))
29277+ goto out;
29278+
b4510431 29279+ err = vfs_create(dir, path->dentry, mode, want_excl);
1facf9fc 29280+ if (!err) {
29281+ struct path tmp = *path;
29282+ int did;
29283+
29284+ vfsub_update_h_iattr(&tmp, &did);
29285+ if (did) {
29286+ tmp.dentry = path->dentry->d_parent;
29287+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29288+ }
29289+ /*ignore*/
29290+ }
29291+
4f0767ce 29292+out:
1facf9fc 29293+ return err;
29294+}
29295+
29296+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
29297+{
29298+ int err;
29299+ struct dentry *d;
29300+
29301+ IMustLock(dir);
29302+
29303+ d = path->dentry;
29304+ path->dentry = d->d_parent;
b752ccd1 29305+ err = security_path_symlink(path, d, symname);
1facf9fc 29306+ path->dentry = d;
29307+ if (unlikely(err))
29308+ goto out;
29309+
29310+ err = vfs_symlink(dir, path->dentry, symname);
29311+ if (!err) {
29312+ struct path tmp = *path;
29313+ int did;
29314+
29315+ vfsub_update_h_iattr(&tmp, &did);
29316+ if (did) {
29317+ tmp.dentry = path->dentry->d_parent;
29318+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29319+ }
29320+ /*ignore*/
29321+ }
29322+
4f0767ce 29323+out:
1facf9fc 29324+ return err;
29325+}
29326+
29327+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
29328+{
29329+ int err;
29330+ struct dentry *d;
29331+
29332+ IMustLock(dir);
29333+
29334+ d = path->dentry;
29335+ path->dentry = d->d_parent;
027c5e7a 29336+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 29337+ path->dentry = d;
29338+ if (unlikely(err))
29339+ goto out;
29340+
29341+ err = vfs_mknod(dir, path->dentry, mode, dev);
29342+ if (!err) {
29343+ struct path tmp = *path;
29344+ int did;
29345+
29346+ vfsub_update_h_iattr(&tmp, &did);
29347+ if (did) {
29348+ tmp.dentry = path->dentry->d_parent;
29349+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29350+ }
29351+ /*ignore*/
29352+ }
29353+
4f0767ce 29354+out:
1facf9fc 29355+ return err;
29356+}
29357+
29358+static int au_test_nlink(struct inode *inode)
29359+{
29360+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
29361+
29362+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
29363+ || inode->i_nlink < link_max)
29364+ return 0;
29365+ return -EMLINK;
29366+}
29367+
523b37e3
AM
29368+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
29369+ struct inode **delegated_inode)
1facf9fc 29370+{
29371+ int err;
29372+ struct dentry *d;
29373+
29374+ IMustLock(dir);
29375+
29376+ err = au_test_nlink(src_dentry->d_inode);
29377+ if (unlikely(err))
29378+ return err;
29379+
b4510431 29380+ /* we don't call may_linkat() */
1facf9fc 29381+ d = path->dentry;
29382+ path->dentry = d->d_parent;
b752ccd1 29383+ err = security_path_link(src_dentry, path, d);
1facf9fc 29384+ path->dentry = d;
29385+ if (unlikely(err))
29386+ goto out;
29387+
2cbb1c4b 29388+ lockdep_off();
523b37e3 29389+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 29390+ lockdep_on();
1facf9fc 29391+ if (!err) {
29392+ struct path tmp = *path;
29393+ int did;
29394+
29395+ /* fuse has different memory inode for the same inumber */
29396+ vfsub_update_h_iattr(&tmp, &did);
29397+ if (did) {
29398+ tmp.dentry = path->dentry->d_parent;
29399+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29400+ tmp.dentry = src_dentry;
29401+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29402+ }
29403+ /*ignore*/
29404+ }
29405+
4f0767ce 29406+out:
1facf9fc 29407+ return err;
29408+}
29409+
29410+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3
AM
29411+ struct inode *dir, struct path *path,
29412+ struct inode **delegated_inode)
1facf9fc 29413+{
29414+ int err;
29415+ struct path tmp = {
29416+ .mnt = path->mnt
29417+ };
29418+ struct dentry *d;
29419+
29420+ IMustLock(dir);
29421+ IMustLock(src_dir);
29422+
29423+ d = path->dentry;
29424+ path->dentry = d->d_parent;
29425+ tmp.dentry = src_dentry->d_parent;
38d290e6 29426+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 29427+ path->dentry = d;
29428+ if (unlikely(err))
29429+ goto out;
29430+
2cbb1c4b 29431+ lockdep_off();
523b37e3 29432+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
38d290e6 29433+ delegated_inode, /*flags*/0);
2cbb1c4b 29434+ lockdep_on();
1facf9fc 29435+ if (!err) {
29436+ int did;
29437+
29438+ tmp.dentry = d->d_parent;
29439+ vfsub_update_h_iattr(&tmp, &did);
29440+ if (did) {
29441+ tmp.dentry = src_dentry;
29442+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29443+ tmp.dentry = src_dentry->d_parent;
29444+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29445+ }
29446+ /*ignore*/
29447+ }
29448+
4f0767ce 29449+out:
1facf9fc 29450+ return err;
29451+}
29452+
29453+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
29454+{
29455+ int err;
29456+ struct dentry *d;
29457+
29458+ IMustLock(dir);
29459+
29460+ d = path->dentry;
29461+ path->dentry = d->d_parent;
b752ccd1 29462+ err = security_path_mkdir(path, d, mode);
1facf9fc 29463+ path->dentry = d;
29464+ if (unlikely(err))
29465+ goto out;
29466+
29467+ err = vfs_mkdir(dir, path->dentry, mode);
29468+ if (!err) {
29469+ struct path tmp = *path;
29470+ int did;
29471+
29472+ vfsub_update_h_iattr(&tmp, &did);
29473+ if (did) {
29474+ tmp.dentry = path->dentry->d_parent;
29475+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29476+ }
29477+ /*ignore*/
29478+ }
29479+
4f0767ce 29480+out:
1facf9fc 29481+ return err;
29482+}
29483+
29484+int vfsub_rmdir(struct inode *dir, struct path *path)
29485+{
29486+ int err;
29487+ struct dentry *d;
29488+
29489+ IMustLock(dir);
29490+
29491+ d = path->dentry;
29492+ path->dentry = d->d_parent;
b752ccd1 29493+ err = security_path_rmdir(path, d);
1facf9fc 29494+ path->dentry = d;
29495+ if (unlikely(err))
29496+ goto out;
29497+
2cbb1c4b 29498+ lockdep_off();
1facf9fc 29499+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 29500+ lockdep_on();
1facf9fc 29501+ if (!err) {
29502+ struct path tmp = {
29503+ .dentry = path->dentry->d_parent,
29504+ .mnt = path->mnt
29505+ };
29506+
29507+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
29508+ }
29509+
4f0767ce 29510+out:
1facf9fc 29511+ return err;
29512+}
29513+
29514+/* ---------------------------------------------------------------------- */
29515+
9dbd164d 29516+/* todo: support mmap_sem? */
1facf9fc 29517+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
29518+ loff_t *ppos)
29519+{
29520+ ssize_t err;
29521+
2cbb1c4b 29522+ lockdep_off();
1facf9fc 29523+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 29524+ lockdep_on();
1facf9fc 29525+ if (err >= 0)
29526+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29527+ return err;
29528+}
29529+
29530+/* todo: kernel_read()? */
29531+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
29532+ loff_t *ppos)
29533+{
29534+ ssize_t err;
29535+ mm_segment_t oldfs;
b752ccd1
AM
29536+ union {
29537+ void *k;
29538+ char __user *u;
29539+ } buf;
1facf9fc 29540+
b752ccd1 29541+ buf.k = kbuf;
1facf9fc 29542+ oldfs = get_fs();
29543+ set_fs(KERNEL_DS);
b752ccd1 29544+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 29545+ set_fs(oldfs);
29546+ return err;
29547+}
29548+
29549+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
29550+ loff_t *ppos)
29551+{
29552+ ssize_t err;
29553+
2cbb1c4b 29554+ lockdep_off();
1facf9fc 29555+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 29556+ lockdep_on();
1facf9fc 29557+ if (err >= 0)
29558+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29559+ return err;
29560+}
29561+
29562+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
29563+{
29564+ ssize_t err;
29565+ mm_segment_t oldfs;
b752ccd1
AM
29566+ union {
29567+ void *k;
29568+ const char __user *u;
29569+ } buf;
1facf9fc 29570+
b752ccd1 29571+ buf.k = kbuf;
1facf9fc 29572+ oldfs = get_fs();
29573+ set_fs(KERNEL_DS);
b752ccd1 29574+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 29575+ set_fs(oldfs);
29576+ return err;
29577+}
29578+
4a4d8108
AM
29579+int vfsub_flush(struct file *file, fl_owner_t id)
29580+{
29581+ int err;
29582+
29583+ err = 0;
523b37e3 29584+ if (file->f_op->flush) {
2cbb1c4b
JR
29585+ if (!au_test_nfs(file->f_dentry->d_sb))
29586+ err = file->f_op->flush(file, id);
29587+ else {
29588+ lockdep_off();
29589+ err = file->f_op->flush(file, id);
29590+ lockdep_on();
29591+ }
4a4d8108
AM
29592+ if (!err)
29593+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
29594+ /*ignore*/
29595+ }
29596+ return err;
29597+}
29598+
392086de 29599+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 29600+{
29601+ int err;
29602+
523b37e3 29603+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 29604+
2cbb1c4b 29605+ lockdep_off();
392086de 29606+ err = iterate_dir(file, ctx);
2cbb1c4b 29607+ lockdep_on();
1facf9fc 29608+ if (err >= 0)
29609+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29610+ return err;
29611+}
29612+
29613+long vfsub_splice_to(struct file *in, loff_t *ppos,
29614+ struct pipe_inode_info *pipe, size_t len,
29615+ unsigned int flags)
29616+{
29617+ long err;
29618+
2cbb1c4b 29619+ lockdep_off();
0fc653ad 29620+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 29621+ lockdep_on();
4a4d8108 29622+ file_accessed(in);
1facf9fc 29623+ if (err >= 0)
29624+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
29625+ return err;
29626+}
29627+
29628+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
29629+ loff_t *ppos, size_t len, unsigned int flags)
29630+{
29631+ long err;
29632+
2cbb1c4b 29633+ lockdep_off();
0fc653ad 29634+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 29635+ lockdep_on();
1facf9fc 29636+ if (err >= 0)
29637+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
29638+ return err;
29639+}
29640+
53392da6
AM
29641+int vfsub_fsync(struct file *file, struct path *path, int datasync)
29642+{
29643+ int err;
29644+
29645+ /* file can be NULL */
29646+ lockdep_off();
29647+ err = vfs_fsync(file, datasync);
29648+ lockdep_on();
29649+ if (!err) {
29650+ if (!path) {
29651+ AuDebugOn(!file);
29652+ path = &file->f_path;
29653+ }
29654+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
29655+ }
29656+ return err;
29657+}
29658+
1facf9fc 29659+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
29660+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
29661+ struct file *h_file)
29662+{
29663+ int err;
29664+ struct inode *h_inode;
c06a8ce3 29665+ struct super_block *h_sb;
1facf9fc 29666+
1facf9fc 29667+ if (!h_file) {
c06a8ce3
AM
29668+ err = vfsub_truncate(h_path, length);
29669+ goto out;
1facf9fc 29670+ }
29671+
c06a8ce3
AM
29672+ h_inode = h_path->dentry->d_inode;
29673+ h_sb = h_inode->i_sb;
29674+ lockdep_off();
29675+ sb_start_write(h_sb);
29676+ lockdep_on();
1facf9fc 29677+ err = locks_verify_truncate(h_inode, h_file, length);
29678+ if (!err)
953406b4 29679+ err = security_path_truncate(h_path);
2cbb1c4b
JR
29680+ if (!err) {
29681+ lockdep_off();
1facf9fc 29682+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
29683+ lockdep_on();
29684+ }
c06a8ce3
AM
29685+ lockdep_off();
29686+ sb_end_write(h_sb);
29687+ lockdep_on();
1facf9fc 29688+
4f0767ce 29689+out:
1facf9fc 29690+ return err;
29691+}
29692+
29693+/* ---------------------------------------------------------------------- */
29694+
29695+struct au_vfsub_mkdir_args {
29696+ int *errp;
29697+ struct inode *dir;
29698+ struct path *path;
29699+ int mode;
29700+};
29701+
29702+static void au_call_vfsub_mkdir(void *args)
29703+{
29704+ struct au_vfsub_mkdir_args *a = args;
29705+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
29706+}
29707+
29708+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
29709+{
29710+ int err, do_sio, wkq_err;
29711+
29712+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
29713+ if (!do_sio)
29714+ err = vfsub_mkdir(dir, path, mode);
29715+ else {
29716+ struct au_vfsub_mkdir_args args = {
29717+ .errp = &err,
29718+ .dir = dir,
29719+ .path = path,
29720+ .mode = mode
29721+ };
29722+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
29723+ if (unlikely(wkq_err))
29724+ err = wkq_err;
29725+ }
29726+
29727+ return err;
29728+}
29729+
29730+struct au_vfsub_rmdir_args {
29731+ int *errp;
29732+ struct inode *dir;
29733+ struct path *path;
29734+};
29735+
29736+static void au_call_vfsub_rmdir(void *args)
29737+{
29738+ struct au_vfsub_rmdir_args *a = args;
29739+ *a->errp = vfsub_rmdir(a->dir, a->path);
29740+}
29741+
29742+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
29743+{
29744+ int err, do_sio, wkq_err;
29745+
29746+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
29747+ if (!do_sio)
29748+ err = vfsub_rmdir(dir, path);
29749+ else {
29750+ struct au_vfsub_rmdir_args args = {
29751+ .errp = &err,
29752+ .dir = dir,
29753+ .path = path
29754+ };
29755+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
29756+ if (unlikely(wkq_err))
29757+ err = wkq_err;
29758+ }
29759+
29760+ return err;
29761+}
29762+
29763+/* ---------------------------------------------------------------------- */
29764+
29765+struct notify_change_args {
29766+ int *errp;
29767+ struct path *path;
29768+ struct iattr *ia;
523b37e3 29769+ struct inode **delegated_inode;
1facf9fc 29770+};
29771+
29772+static void call_notify_change(void *args)
29773+{
29774+ struct notify_change_args *a = args;
29775+ struct inode *h_inode;
29776+
29777+ h_inode = a->path->dentry->d_inode;
29778+ IMustLock(h_inode);
29779+
29780+ *a->errp = -EPERM;
29781+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
523b37e3
AM
29782+ *a->errp = notify_change(a->path->dentry, a->ia,
29783+ a->delegated_inode);
1facf9fc 29784+ if (!*a->errp)
29785+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
29786+ }
29787+ AuTraceErr(*a->errp);
29788+}
29789+
523b37e3
AM
29790+int vfsub_notify_change(struct path *path, struct iattr *ia,
29791+ struct inode **delegated_inode)
1facf9fc 29792+{
29793+ int err;
29794+ struct notify_change_args args = {
523b37e3
AM
29795+ .errp = &err,
29796+ .path = path,
29797+ .ia = ia,
29798+ .delegated_inode = delegated_inode
1facf9fc 29799+ };
29800+
29801+ call_notify_change(&args);
29802+
29803+ return err;
29804+}
29805+
523b37e3
AM
29806+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
29807+ struct inode **delegated_inode)
1facf9fc 29808+{
29809+ int err, wkq_err;
29810+ struct notify_change_args args = {
523b37e3
AM
29811+ .errp = &err,
29812+ .path = path,
29813+ .ia = ia,
29814+ .delegated_inode = delegated_inode
1facf9fc 29815+ };
29816+
29817+ wkq_err = au_wkq_wait(call_notify_change, &args);
29818+ if (unlikely(wkq_err))
29819+ err = wkq_err;
29820+
29821+ return err;
29822+}
29823+
29824+/* ---------------------------------------------------------------------- */
29825+
29826+struct unlink_args {
29827+ int *errp;
29828+ struct inode *dir;
29829+ struct path *path;
523b37e3 29830+ struct inode **delegated_inode;
1facf9fc 29831+};
29832+
29833+static void call_unlink(void *args)
29834+{
29835+ struct unlink_args *a = args;
29836+ struct dentry *d = a->path->dentry;
29837+ struct inode *h_inode;
29838+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
392086de 29839+ && d_count(d) == 1);
1facf9fc 29840+
29841+ IMustLock(a->dir);
29842+
29843+ a->path->dentry = d->d_parent;
29844+ *a->errp = security_path_unlink(a->path, d);
29845+ a->path->dentry = d;
29846+ if (unlikely(*a->errp))
29847+ return;
29848+
29849+ if (!stop_sillyrename)
29850+ dget(d);
29851+ h_inode = d->d_inode;
29852+ if (h_inode)
027c5e7a 29853+ ihold(h_inode);
1facf9fc 29854+
2cbb1c4b 29855+ lockdep_off();
523b37e3 29856+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 29857+ lockdep_on();
1facf9fc 29858+ if (!*a->errp) {
29859+ struct path tmp = {
29860+ .dentry = d->d_parent,
29861+ .mnt = a->path->mnt
29862+ };
29863+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
29864+ }
29865+
29866+ if (!stop_sillyrename)
29867+ dput(d);
29868+ if (h_inode)
29869+ iput(h_inode);
29870+
29871+ AuTraceErr(*a->errp);
29872+}
29873+
29874+/*
29875+ * @dir: must be locked.
29876+ * @dentry: target dentry.
29877+ */
523b37e3
AM
29878+int vfsub_unlink(struct inode *dir, struct path *path,
29879+ struct inode **delegated_inode, int force)
1facf9fc 29880+{
29881+ int err;
29882+ struct unlink_args args = {
523b37e3
AM
29883+ .errp = &err,
29884+ .dir = dir,
29885+ .path = path,
29886+ .delegated_inode = delegated_inode
1facf9fc 29887+ };
29888+
29889+ if (!force)
29890+ call_unlink(&args);
29891+ else {
29892+ int wkq_err;
29893+
29894+ wkq_err = au_wkq_wait(call_unlink, &args);
29895+ if (unlikely(wkq_err))
29896+ err = wkq_err;
29897+ }
29898+
29899+ return err;
29900+}
7f207e10
AM
29901diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
29902--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
29903+++ linux/fs/aufs/vfsub.h 2014-08-14 10:15:45.131942973 +0200
29904@@ -0,0 +1,284 @@
1facf9fc 29905+/*
523b37e3 29906+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 29907+ *
29908+ * This program, aufs is free software; you can redistribute it and/or modify
29909+ * it under the terms of the GNU General Public License as published by
29910+ * the Free Software Foundation; either version 2 of the License, or
29911+ * (at your option) any later version.
dece6358
AM
29912+ *
29913+ * This program is distributed in the hope that it will be useful,
29914+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29915+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29916+ * GNU General Public License for more details.
29917+ *
29918+ * You should have received a copy of the GNU General Public License
523b37e3 29919+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29920+ */
29921+
29922+/*
29923+ * sub-routines for VFS
29924+ */
29925+
29926+#ifndef __AUFS_VFSUB_H__
29927+#define __AUFS_VFSUB_H__
29928+
29929+#ifdef __KERNEL__
29930+
29931+#include <linux/fs.h>
0c5527e5 29932+#include <linux/lglock.h>
b4510431 29933+#include <linux/mount.h>
7f207e10 29934+#include "debug.h"
1facf9fc 29935+
7f207e10 29936+/* copied from linux/fs/internal.h */
2cbb1c4b 29937+/* todo: BAD approach!! */
c06a8ce3 29938+extern void __mnt_drop_write(struct vfsmount *);
2cbb1c4b 29939+extern spinlock_t inode_sb_list_lock;
7f207e10
AM
29940+
29941+/* ---------------------------------------------------------------------- */
1facf9fc 29942+
29943+/* lock subclass for lower inode */
29944+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
29945+/* reduce? gave up. */
29946+enum {
523b37e3 29947+ AuLsc_I_Begin = I_MUTEX_NONDIR2, /* 4 */
1facf9fc 29948+ AuLsc_I_PARENT, /* lower inode, parent first */
29949+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 29950+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 29951+ AuLsc_I_CHILD,
29952+ AuLsc_I_CHILD2,
29953+ AuLsc_I_End
29954+};
29955+
29956+/* to debug easier, do not make them inlined functions */
29957+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
29958+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
29959+
29960+/* ---------------------------------------------------------------------- */
29961+
7f207e10
AM
29962+static inline void vfsub_drop_nlink(struct inode *inode)
29963+{
29964+ AuDebugOn(!inode->i_nlink);
29965+ drop_nlink(inode);
29966+}
29967+
027c5e7a
AM
29968+static inline void vfsub_dead_dir(struct inode *inode)
29969+{
29970+ AuDebugOn(!S_ISDIR(inode->i_mode));
29971+ inode->i_flags |= S_DEAD;
29972+ clear_nlink(inode);
29973+}
29974+
392086de
AM
29975+static inline int vfsub_native_ro(struct inode *inode)
29976+{
29977+ return (inode->i_sb->s_flags & MS_RDONLY)
29978+ || IS_RDONLY(inode)
29979+ /* || IS_APPEND(inode) */
29980+ || IS_IMMUTABLE(inode);
29981+}
29982+
7f207e10
AM
29983+/* ---------------------------------------------------------------------- */
29984+
29985+int vfsub_update_h_iattr(struct path *h_path, int *did);
29986+struct file *vfsub_dentry_open(struct path *path, int flags);
29987+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
1facf9fc 29988+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 29989+
1facf9fc 29990+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
29991+ int len);
b4510431
AM
29992+
29993+struct vfsub_lkup_one_args {
29994+ struct dentry **errp;
29995+ struct qstr *name;
29996+ struct dentry *parent;
29997+};
29998+
29999+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
30000+ struct dentry *parent)
30001+{
30002+ return vfsub_lookup_one_len(name->name, parent, name->len);
30003+}
30004+
30005+void vfsub_call_lkup_one(void *args);
30006+
30007+/* ---------------------------------------------------------------------- */
30008+
30009+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
30010+{
30011+ int err;
076b876e 30012+
b4510431
AM
30013+ lockdep_off();
30014+ err = mnt_want_write(mnt);
30015+ lockdep_on();
30016+ return err;
30017+}
30018+
30019+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
30020+{
30021+ lockdep_off();
30022+ mnt_drop_write(mnt);
30023+ lockdep_on();
30024+}
1facf9fc 30025+
c06a8ce3
AM
30026+static inline void vfsub_mnt_drop_write_file(struct file *file)
30027+{
30028+ lockdep_off();
30029+ mnt_drop_write_file(file);
30030+ lockdep_on();
30031+}
30032+
1facf9fc 30033+/* ---------------------------------------------------------------------- */
30034+
30035+struct au_hinode;
30036+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
30037+ struct dentry *d2, struct au_hinode *hdir2);
30038+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
30039+ struct dentry *d2, struct au_hinode *hdir2);
30040+
537831f9
AM
30041+int vfsub_create(struct inode *dir, struct path *path, int mode,
30042+ bool want_excl);
1facf9fc 30043+int vfsub_symlink(struct inode *dir, struct path *path,
30044+ const char *symname);
30045+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
30046+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 30047+ struct path *path, struct inode **delegated_inode);
1facf9fc 30048+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3
AM
30049+ struct inode *hdir, struct path *path,
30050+ struct inode **delegated_inode);
1facf9fc 30051+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
30052+int vfsub_rmdir(struct inode *dir, struct path *path);
30053+
30054+/* ---------------------------------------------------------------------- */
30055+
30056+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
30057+ loff_t *ppos);
30058+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
30059+ loff_t *ppos);
30060+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
30061+ loff_t *ppos);
30062+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
30063+ loff_t *ppos);
4a4d8108 30064+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
30065+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
30066+
30067+/* just for type-check */
30068+static inline filldir_t au_diractor(int (*func)(struct dir_context *,
30069+ const char *, int, loff_t, u64,
30070+ unsigned))
30071+{
30072+ return (filldir_t)func;
30073+}
30074+
1facf9fc 30075+
c06a8ce3
AM
30076+static inline loff_t vfsub_f_size_read(struct file *file)
30077+{
30078+ return i_size_read(file_inode(file));
30079+}
30080+
4a4d8108
AM
30081+static inline unsigned int vfsub_file_flags(struct file *file)
30082+{
30083+ unsigned int flags;
30084+
30085+ spin_lock(&file->f_lock);
30086+ flags = file->f_flags;
30087+ spin_unlock(&file->f_lock);
30088+
30089+ return flags;
30090+}
1308ab2a 30091+
1facf9fc 30092+static inline void vfsub_file_accessed(struct file *h_file)
30093+{
30094+ file_accessed(h_file);
30095+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
30096+}
30097+
30098+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
30099+ struct dentry *h_dentry)
30100+{
30101+ struct path h_path = {
30102+ .dentry = h_dentry,
30103+ .mnt = h_mnt
30104+ };
92d182d2 30105+ touch_atime(&h_path);
1facf9fc 30106+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
30107+}
30108+
0c3ec466
AM
30109+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
30110+ int flags)
30111+{
30112+ return update_time(h_inode, ts, flags);
30113+ /* no vfsub_update_h_iattr() since we don't have struct path */
30114+}
30115+
4a4d8108
AM
30116+long vfsub_splice_to(struct file *in, loff_t *ppos,
30117+ struct pipe_inode_info *pipe, size_t len,
30118+ unsigned int flags);
30119+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
30120+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
30121+
30122+static inline long vfsub_truncate(struct path *path, loff_t length)
30123+{
30124+ long err;
076b876e 30125+
c06a8ce3
AM
30126+ lockdep_off();
30127+ err = vfs_truncate(path, length);
30128+ lockdep_on();
30129+ return err;
30130+}
30131+
4a4d8108
AM
30132+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
30133+ struct file *h_file);
53392da6 30134+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 30135+
1facf9fc 30136+/* ---------------------------------------------------------------------- */
30137+
30138+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
30139+{
30140+ loff_t err;
30141+
2cbb1c4b 30142+ lockdep_off();
1facf9fc 30143+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 30144+ lockdep_on();
1facf9fc 30145+ return err;
30146+}
30147+
30148+/* ---------------------------------------------------------------------- */
30149+
30150+/* dirty workaround for strict type of fmode_t */
30151+union vfsub_fmu {
30152+ fmode_t fm;
30153+ unsigned int ui;
30154+};
30155+
30156+static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
30157+{
30158+ union vfsub_fmu u = {
30159+ .fm = fm
30160+ };
30161+
30162+ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
30163+
30164+ return u.ui;
30165+}
30166+
30167+static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
30168+{
30169+ union vfsub_fmu u = {
30170+ .ui = ui
30171+ };
30172+
30173+ return u.fm;
30174+}
30175+
4a4d8108
AM
30176+/* ---------------------------------------------------------------------- */
30177+
30178+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
30179+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
30180+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
30181+ struct inode **delegated_inode);
30182+int vfsub_notify_change(struct path *path, struct iattr *ia,
30183+ struct inode **delegated_inode);
30184+int vfsub_unlink(struct inode *dir, struct path *path,
30185+ struct inode **delegated_inode, int force);
4a4d8108 30186+
1facf9fc 30187+#endif /* __KERNEL__ */
30188+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
30189diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
30190--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
30191+++ linux/fs/aufs/wbr_policy.c 2014-08-14 10:15:45.131942973 +0200
30192@@ -0,0 +1,765 @@
1facf9fc 30193+/*
523b37e3 30194+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30195+ *
30196+ * This program, aufs is free software; you can redistribute it and/or modify
30197+ * it under the terms of the GNU General Public License as published by
30198+ * the Free Software Foundation; either version 2 of the License, or
30199+ * (at your option) any later version.
dece6358
AM
30200+ *
30201+ * This program is distributed in the hope that it will be useful,
30202+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30203+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30204+ * GNU General Public License for more details.
30205+ *
30206+ * You should have received a copy of the GNU General Public License
523b37e3 30207+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30208+ */
30209+
30210+/*
30211+ * policies for selecting one among multiple writable branches
30212+ */
30213+
30214+#include <linux/statfs.h>
30215+#include "aufs.h"
30216+
30217+/* subset of cpup_attr() */
30218+static noinline_for_stack
30219+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
30220+{
30221+ int err, sbits;
30222+ struct iattr ia;
30223+ struct inode *h_isrc;
30224+
30225+ h_isrc = h_src->d_inode;
30226+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
30227+ ia.ia_mode = h_isrc->i_mode;
30228+ ia.ia_uid = h_isrc->i_uid;
30229+ ia.ia_gid = h_isrc->i_gid;
30230+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
86dc4139 30231+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
523b37e3
AM
30232+ /* no delegation since it is just created */
30233+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 30234+
30235+ /* is this nfs only? */
30236+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
30237+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
30238+ ia.ia_mode = h_isrc->i_mode;
523b37e3 30239+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 30240+ }
30241+
30242+ return err;
30243+}
30244+
30245+#define AuCpdown_PARENT_OPQ 1
30246+#define AuCpdown_WHED (1 << 1)
30247+#define AuCpdown_MADE_DIR (1 << 2)
30248+#define AuCpdown_DIROPQ (1 << 3)
30249+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
30250+#define au_fset_cpdown(flags, name) \
30251+ do { (flags) |= AuCpdown_##name; } while (0)
30252+#define au_fclr_cpdown(flags, name) \
30253+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 30254+
1facf9fc 30255+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 30256+ unsigned int *flags)
1facf9fc 30257+{
30258+ int err;
30259+ struct dentry *opq_dentry;
30260+
30261+ opq_dentry = au_diropq_create(dentry, bdst);
30262+ err = PTR_ERR(opq_dentry);
30263+ if (IS_ERR(opq_dentry))
30264+ goto out;
30265+ dput(opq_dentry);
c2b27bf2 30266+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 30267+
4f0767ce 30268+out:
1facf9fc 30269+ return err;
30270+}
30271+
30272+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
30273+ struct inode *dir, aufs_bindex_t bdst)
30274+{
30275+ int err;
30276+ struct path h_path;
30277+ struct au_branch *br;
30278+
30279+ br = au_sbr(dentry->d_sb, bdst);
30280+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
30281+ err = PTR_ERR(h_path.dentry);
30282+ if (IS_ERR(h_path.dentry))
30283+ goto out;
30284+
30285+ err = 0;
30286+ if (h_path.dentry->d_inode) {
86dc4139 30287+ h_path.mnt = au_br_mnt(br);
1facf9fc 30288+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
30289+ dentry);
30290+ }
30291+ dput(h_path.dentry);
30292+
4f0767ce 30293+out:
1facf9fc 30294+ return err;
30295+}
30296+
30297+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 30298+ struct au_pin *pin,
1facf9fc 30299+ struct dentry *h_parent, void *arg)
30300+{
30301+ int err, rerr;
4a4d8108 30302+ aufs_bindex_t bopq, bstart;
1facf9fc 30303+ struct path h_path;
30304+ struct dentry *parent;
30305+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 30306+ unsigned int *flags = arg;
1facf9fc 30307+
30308+ bstart = au_dbstart(dentry);
30309+ /* dentry is di-locked */
30310+ parent = dget_parent(dentry);
30311+ dir = parent->d_inode;
30312+ h_dir = h_parent->d_inode;
30313+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
30314+ IMustLock(h_dir);
30315+
86dc4139 30316+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 30317+ if (unlikely(err < 0))
30318+ goto out;
30319+ h_path.dentry = au_h_dptr(dentry, bdst);
30320+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
30321+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
30322+ S_IRWXU | S_IRUGO | S_IXUGO);
30323+ if (unlikely(err))
30324+ goto out_put;
c2b27bf2 30325+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 30326+
1facf9fc 30327+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
30328+ au_fclr_cpdown(*flags, WHED);
30329+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 30330+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
30331+ au_fset_cpdown(*flags, WHED);
30332+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
30333+ au_fset_cpdown(*flags, PARENT_OPQ);
1facf9fc 30334+ h_inode = h_path.dentry->d_inode;
30335+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2
AM
30336+ if (au_ftest_cpdown(*flags, WHED)) {
30337+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 30338+ if (unlikely(err)) {
30339+ mutex_unlock(&h_inode->i_mutex);
30340+ goto out_dir;
30341+ }
30342+ }
30343+
30344+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
30345+ mutex_unlock(&h_inode->i_mutex);
30346+ if (unlikely(err))
30347+ goto out_opq;
30348+
c2b27bf2 30349+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 30350+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
30351+ if (unlikely(err))
30352+ goto out_opq;
30353+ }
30354+
30355+ inode = dentry->d_inode;
30356+ if (au_ibend(inode) < bdst)
30357+ au_set_ibend(inode, bdst);
30358+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
30359+ au_hi_flags(inode, /*isdir*/1));
076b876e 30360+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 30361+ goto out; /* success */
30362+
30363+ /* revert */
4f0767ce 30364+out_opq:
c2b27bf2 30365+ if (au_ftest_cpdown(*flags, DIROPQ)) {
1facf9fc 30366+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
30367+ rerr = au_diropq_remove(dentry, bdst);
30368+ mutex_unlock(&h_inode->i_mutex);
30369+ if (unlikely(rerr)) {
523b37e3
AM
30370+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
30371+ dentry, bdst, rerr);
1facf9fc 30372+ err = -EIO;
30373+ goto out;
30374+ }
30375+ }
4f0767ce 30376+out_dir:
c2b27bf2 30377+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 30378+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
30379+ if (unlikely(rerr)) {
523b37e3
AM
30380+ AuIOErr("failed removing %pd b%d (%d)\n",
30381+ dentry, bdst, rerr);
1facf9fc 30382+ err = -EIO;
30383+ }
30384+ }
4f0767ce 30385+out_put:
1facf9fc 30386+ au_set_h_dptr(dentry, bdst, NULL);
30387+ if (au_dbend(dentry) == bdst)
30388+ au_update_dbend(dentry);
4f0767ce 30389+out:
1facf9fc 30390+ dput(parent);
30391+ return err;
30392+}
30393+
30394+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
30395+{
30396+ int err;
c2b27bf2 30397+ unsigned int flags;
1facf9fc 30398+
c2b27bf2
AM
30399+ flags = 0;
30400+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 30401+
30402+ return err;
30403+}
30404+
30405+/* ---------------------------------------------------------------------- */
30406+
30407+/* policies for create */
30408+
c2b27bf2 30409+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
30410+{
30411+ int err, i, j, ndentry;
30412+ aufs_bindex_t bopq;
30413+ struct au_dcsub_pages dpages;
30414+ struct au_dpage *dpage;
30415+ struct dentry **dentries, *parent, *d;
30416+
30417+ err = au_dpages_init(&dpages, GFP_NOFS);
30418+ if (unlikely(err))
30419+ goto out;
30420+ parent = dget_parent(dentry);
027c5e7a 30421+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
30422+ if (unlikely(err))
30423+ goto out_free;
30424+
30425+ err = bindex;
30426+ for (i = 0; i < dpages.ndpage; i++) {
30427+ dpage = dpages.dpages + i;
30428+ dentries = dpage->dentries;
30429+ ndentry = dpage->ndentry;
30430+ for (j = 0; j < ndentry; j++) {
30431+ d = dentries[j];
30432+ di_read_lock_parent2(d, !AuLock_IR);
30433+ bopq = au_dbdiropq(d);
30434+ di_read_unlock(d, !AuLock_IR);
30435+ if (bopq >= 0 && bopq < err)
30436+ err = bopq;
30437+ }
30438+ }
30439+
30440+out_free:
30441+ dput(parent);
30442+ au_dpages_free(&dpages);
30443+out:
30444+ return err;
30445+}
30446+
1facf9fc 30447+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
30448+{
30449+ for (; bindex >= 0; bindex--)
30450+ if (!au_br_rdonly(au_sbr(sb, bindex)))
30451+ return bindex;
30452+ return -EROFS;
30453+}
30454+
30455+/* top down parent */
392086de
AM
30456+static int au_wbr_create_tdp(struct dentry *dentry,
30457+ unsigned int flags __maybe_unused)
1facf9fc 30458+{
30459+ int err;
30460+ aufs_bindex_t bstart, bindex;
30461+ struct super_block *sb;
30462+ struct dentry *parent, *h_parent;
30463+
30464+ sb = dentry->d_sb;
30465+ bstart = au_dbstart(dentry);
30466+ err = bstart;
30467+ if (!au_br_rdonly(au_sbr(sb, bstart)))
30468+ goto out;
30469+
30470+ err = -EROFS;
30471+ parent = dget_parent(dentry);
30472+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
30473+ h_parent = au_h_dptr(parent, bindex);
30474+ if (!h_parent || !h_parent->d_inode)
30475+ continue;
30476+
30477+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
30478+ err = bindex;
30479+ break;
30480+ }
30481+ }
30482+ dput(parent);
30483+
30484+ /* bottom up here */
4a4d8108 30485+ if (unlikely(err < 0)) {
1facf9fc 30486+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
30487+ if (err >= 0)
30488+ err = au_wbr_nonopq(dentry, err);
30489+ }
1facf9fc 30490+
4f0767ce 30491+out:
1facf9fc 30492+ AuDbg("b%d\n", err);
30493+ return err;
30494+}
30495+
30496+/* ---------------------------------------------------------------------- */
30497+
30498+/* an exception for the policy other than tdp */
30499+static int au_wbr_create_exp(struct dentry *dentry)
30500+{
30501+ int err;
30502+ aufs_bindex_t bwh, bdiropq;
30503+ struct dentry *parent;
30504+
30505+ err = -1;
30506+ bwh = au_dbwh(dentry);
30507+ parent = dget_parent(dentry);
30508+ bdiropq = au_dbdiropq(parent);
30509+ if (bwh >= 0) {
30510+ if (bdiropq >= 0)
30511+ err = min(bdiropq, bwh);
30512+ else
30513+ err = bwh;
30514+ AuDbg("%d\n", err);
30515+ } else if (bdiropq >= 0) {
30516+ err = bdiropq;
30517+ AuDbg("%d\n", err);
30518+ }
30519+ dput(parent);
30520+
4a4d8108
AM
30521+ if (err >= 0)
30522+ err = au_wbr_nonopq(dentry, err);
30523+
1facf9fc 30524+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
30525+ err = -1;
30526+
30527+ AuDbg("%d\n", err);
30528+ return err;
30529+}
30530+
30531+/* ---------------------------------------------------------------------- */
30532+
30533+/* round robin */
30534+static int au_wbr_create_init_rr(struct super_block *sb)
30535+{
30536+ int err;
30537+
30538+ err = au_wbr_bu(sb, au_sbend(sb));
30539+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 30540+ /* smp_mb(); */
1facf9fc 30541+
30542+ AuDbg("b%d\n", err);
30543+ return err;
30544+}
30545+
392086de 30546+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 30547+{
30548+ int err, nbr;
30549+ unsigned int u;
30550+ aufs_bindex_t bindex, bend;
30551+ struct super_block *sb;
30552+ atomic_t *next;
30553+
30554+ err = au_wbr_create_exp(dentry);
30555+ if (err >= 0)
30556+ goto out;
30557+
30558+ sb = dentry->d_sb;
30559+ next = &au_sbi(sb)->si_wbr_rr_next;
30560+ bend = au_sbend(sb);
30561+ nbr = bend + 1;
30562+ for (bindex = 0; bindex <= bend; bindex++) {
392086de 30563+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 30564+ err = atomic_dec_return(next) + 1;
30565+ /* modulo for 0 is meaningless */
30566+ if (unlikely(!err))
30567+ err = atomic_dec_return(next) + 1;
30568+ } else
30569+ err = atomic_read(next);
30570+ AuDbg("%d\n", err);
30571+ u = err;
30572+ err = u % nbr;
30573+ AuDbg("%d\n", err);
30574+ if (!au_br_rdonly(au_sbr(sb, err)))
30575+ break;
30576+ err = -EROFS;
30577+ }
30578+
4a4d8108
AM
30579+ if (err >= 0)
30580+ err = au_wbr_nonopq(dentry, err);
30581+
4f0767ce 30582+out:
1facf9fc 30583+ AuDbg("%d\n", err);
30584+ return err;
30585+}
30586+
30587+/* ---------------------------------------------------------------------- */
30588+
30589+/* most free space */
392086de 30590+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 30591+{
30592+ struct super_block *sb;
30593+ struct au_branch *br;
30594+ struct au_wbr_mfs *mfs;
392086de 30595+ struct dentry *h_parent;
1facf9fc 30596+ aufs_bindex_t bindex, bend;
30597+ int err;
30598+ unsigned long long b, bavail;
7f207e10 30599+ struct path h_path;
1facf9fc 30600+ /* reduce the stack usage */
30601+ struct kstatfs *st;
30602+
30603+ st = kmalloc(sizeof(*st), GFP_NOFS);
30604+ if (unlikely(!st)) {
30605+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
30606+ return;
30607+ }
30608+
30609+ bavail = 0;
30610+ sb = dentry->d_sb;
30611+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 30612+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 30613+ mfs->mfs_bindex = -EROFS;
30614+ mfs->mfsrr_bytes = 0;
392086de
AM
30615+ if (!parent) {
30616+ bindex = 0;
30617+ bend = au_sbend(sb);
30618+ } else {
30619+ bindex = au_dbstart(parent);
30620+ bend = au_dbtaildir(parent);
30621+ }
30622+
30623+ for (; bindex <= bend; bindex++) {
30624+ if (parent) {
30625+ h_parent = au_h_dptr(parent, bindex);
30626+ if (!h_parent || !h_parent->d_inode)
30627+ continue;
30628+ }
1facf9fc 30629+ br = au_sbr(sb, bindex);
30630+ if (au_br_rdonly(br))
30631+ continue;
30632+
30633+ /* sb->s_root for NFS is unreliable */
86dc4139 30634+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
30635+ h_path.dentry = h_path.mnt->mnt_root;
30636+ err = vfs_statfs(&h_path, st);
1facf9fc 30637+ if (unlikely(err)) {
30638+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
30639+ continue;
30640+ }
30641+
30642+ /* when the available size is equal, select the lower one */
30643+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
30644+ || sizeof(b) < sizeof(st->f_bsize));
30645+ b = st->f_bavail * st->f_bsize;
30646+ br->br_wbr->wbr_bytes = b;
30647+ if (b >= bavail) {
30648+ bavail = b;
30649+ mfs->mfs_bindex = bindex;
30650+ mfs->mfs_jiffy = jiffies;
30651+ }
30652+ }
30653+
30654+ mfs->mfsrr_bytes = bavail;
30655+ AuDbg("b%d\n", mfs->mfs_bindex);
30656+ kfree(st);
30657+}
30658+
392086de 30659+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 30660+{
30661+ int err;
392086de 30662+ struct dentry *parent;
1facf9fc 30663+ struct super_block *sb;
30664+ struct au_wbr_mfs *mfs;
30665+
30666+ err = au_wbr_create_exp(dentry);
30667+ if (err >= 0)
30668+ goto out;
30669+
30670+ sb = dentry->d_sb;
392086de
AM
30671+ parent = NULL;
30672+ if (au_ftest_wbr(flags, PARENT))
30673+ parent = dget_parent(dentry);
1facf9fc 30674+ mfs = &au_sbi(sb)->si_wbr_mfs;
30675+ mutex_lock(&mfs->mfs_lock);
30676+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
30677+ || mfs->mfs_bindex < 0
30678+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 30679+ au_mfs(dentry, parent);
1facf9fc 30680+ mutex_unlock(&mfs->mfs_lock);
30681+ err = mfs->mfs_bindex;
392086de 30682+ dput(parent);
1facf9fc 30683+
4a4d8108
AM
30684+ if (err >= 0)
30685+ err = au_wbr_nonopq(dentry, err);
30686+
4f0767ce 30687+out:
1facf9fc 30688+ AuDbg("b%d\n", err);
30689+ return err;
30690+}
30691+
30692+static int au_wbr_create_init_mfs(struct super_block *sb)
30693+{
30694+ struct au_wbr_mfs *mfs;
30695+
30696+ mfs = &au_sbi(sb)->si_wbr_mfs;
30697+ mutex_init(&mfs->mfs_lock);
30698+ mfs->mfs_jiffy = 0;
30699+ mfs->mfs_bindex = -EROFS;
30700+
30701+ return 0;
30702+}
30703+
30704+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
30705+{
30706+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
30707+ return 0;
30708+}
30709+
30710+/* ---------------------------------------------------------------------- */
30711+
30712+/* most free space and then round robin */
392086de 30713+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 30714+{
30715+ int err;
30716+ struct au_wbr_mfs *mfs;
30717+
392086de 30718+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 30719+ if (err >= 0) {
30720+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 30721+ mutex_lock(&mfs->mfs_lock);
1facf9fc 30722+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 30723+ err = au_wbr_create_rr(dentry, flags);
dece6358 30724+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 30725+ }
30726+
30727+ AuDbg("b%d\n", err);
30728+ return err;
30729+}
30730+
30731+static int au_wbr_create_init_mfsrr(struct super_block *sb)
30732+{
30733+ int err;
30734+
30735+ au_wbr_create_init_mfs(sb); /* ignore */
30736+ err = au_wbr_create_init_rr(sb);
30737+
30738+ return err;
30739+}
30740+
30741+/* ---------------------------------------------------------------------- */
30742+
30743+/* top down parent and most free space */
392086de 30744+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 30745+{
30746+ int err, e2;
30747+ unsigned long long b;
30748+ aufs_bindex_t bindex, bstart, bend;
30749+ struct super_block *sb;
30750+ struct dentry *parent, *h_parent;
30751+ struct au_branch *br;
30752+
392086de 30753+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 30754+ if (unlikely(err < 0))
30755+ goto out;
30756+ parent = dget_parent(dentry);
30757+ bstart = au_dbstart(parent);
30758+ bend = au_dbtaildir(parent);
30759+ if (bstart == bend)
30760+ goto out_parent; /* success */
30761+
392086de 30762+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 30763+ if (e2 < 0)
30764+ goto out_parent; /* success */
30765+
30766+ /* when the available size is equal, select upper one */
30767+ sb = dentry->d_sb;
30768+ br = au_sbr(sb, err);
30769+ b = br->br_wbr->wbr_bytes;
30770+ AuDbg("b%d, %llu\n", err, b);
30771+
30772+ for (bindex = bstart; bindex <= bend; bindex++) {
30773+ h_parent = au_h_dptr(parent, bindex);
30774+ if (!h_parent || !h_parent->d_inode)
30775+ continue;
30776+
30777+ br = au_sbr(sb, bindex);
30778+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
30779+ b = br->br_wbr->wbr_bytes;
30780+ err = bindex;
30781+ AuDbg("b%d, %llu\n", err, b);
30782+ }
30783+ }
30784+
4a4d8108
AM
30785+ if (err >= 0)
30786+ err = au_wbr_nonopq(dentry, err);
30787+
4f0767ce 30788+out_parent:
1facf9fc 30789+ dput(parent);
4f0767ce 30790+out:
1facf9fc 30791+ AuDbg("b%d\n", err);
30792+ return err;
30793+}
30794+
30795+/* ---------------------------------------------------------------------- */
30796+
392086de
AM
30797+/*
30798+ * - top down parent
30799+ * - most free space with parent
30800+ * - most free space round-robin regardless parent
30801+ */
30802+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
30803+{
30804+ int err;
30805+ unsigned long long watermark;
30806+ struct super_block *sb;
30807+ struct au_branch *br;
30808+ struct au_wbr_mfs *mfs;
30809+
30810+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
30811+ if (unlikely(err < 0))
30812+ goto out;
30813+
30814+ sb = dentry->d_sb;
30815+ br = au_sbr(sb, err);
30816+ mfs = &au_sbi(sb)->si_wbr_mfs;
30817+ mutex_lock(&mfs->mfs_lock);
30818+ watermark = mfs->mfsrr_watermark;
30819+ mutex_unlock(&mfs->mfs_lock);
30820+ if (br->br_wbr->wbr_bytes < watermark)
30821+ /* regardless the parent dir */
30822+ err = au_wbr_create_mfsrr(dentry, flags);
30823+
30824+out:
30825+ AuDbg("b%d\n", err);
30826+ return err;
30827+}
30828+
30829+/* ---------------------------------------------------------------------- */
30830+
1facf9fc 30831+/* policies for copyup */
30832+
30833+/* top down parent */
30834+static int au_wbr_copyup_tdp(struct dentry *dentry)
30835+{
392086de 30836+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 30837+}
30838+
30839+/* bottom up parent */
30840+static int au_wbr_copyup_bup(struct dentry *dentry)
30841+{
30842+ int err;
30843+ aufs_bindex_t bindex, bstart;
30844+ struct dentry *parent, *h_parent;
30845+ struct super_block *sb;
30846+
30847+ err = -EROFS;
30848+ sb = dentry->d_sb;
30849+ parent = dget_parent(dentry);
30850+ bstart = au_dbstart(parent);
30851+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
30852+ h_parent = au_h_dptr(parent, bindex);
30853+ if (!h_parent || !h_parent->d_inode)
30854+ continue;
30855+
30856+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
30857+ err = bindex;
30858+ break;
30859+ }
30860+ }
30861+ dput(parent);
30862+
30863+ /* bottom up here */
30864+ if (unlikely(err < 0))
30865+ err = au_wbr_bu(sb, bstart - 1);
30866+
30867+ AuDbg("b%d\n", err);
30868+ return err;
30869+}
30870+
30871+/* bottom up */
076b876e 30872+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart)
1facf9fc 30873+{
30874+ int err;
30875+
4a4d8108
AM
30876+ err = au_wbr_bu(dentry->d_sb, bstart);
30877+ AuDbg("b%d\n", err);
30878+ if (err > bstart)
30879+ err = au_wbr_nonopq(dentry, err);
1facf9fc 30880+
30881+ AuDbg("b%d\n", err);
30882+ return err;
30883+}
30884+
076b876e
AM
30885+static int au_wbr_copyup_bu(struct dentry *dentry)
30886+{
30887+ int err;
30888+ aufs_bindex_t bstart;
30889+
30890+ bstart = au_dbstart(dentry);
30891+ err = au_wbr_do_copyup_bu(dentry, bstart);
30892+ return err;
30893+}
30894+
1facf9fc 30895+/* ---------------------------------------------------------------------- */
30896+
30897+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
30898+ [AuWbrCopyup_TDP] = {
30899+ .copyup = au_wbr_copyup_tdp
30900+ },
30901+ [AuWbrCopyup_BUP] = {
30902+ .copyup = au_wbr_copyup_bup
30903+ },
30904+ [AuWbrCopyup_BU] = {
30905+ .copyup = au_wbr_copyup_bu
30906+ }
30907+};
30908+
30909+struct au_wbr_create_operations au_wbr_create_ops[] = {
30910+ [AuWbrCreate_TDP] = {
30911+ .create = au_wbr_create_tdp
30912+ },
30913+ [AuWbrCreate_RR] = {
30914+ .create = au_wbr_create_rr,
30915+ .init = au_wbr_create_init_rr
30916+ },
30917+ [AuWbrCreate_MFS] = {
30918+ .create = au_wbr_create_mfs,
30919+ .init = au_wbr_create_init_mfs,
30920+ .fin = au_wbr_create_fin_mfs
30921+ },
30922+ [AuWbrCreate_MFSV] = {
30923+ .create = au_wbr_create_mfs,
30924+ .init = au_wbr_create_init_mfs,
30925+ .fin = au_wbr_create_fin_mfs
30926+ },
30927+ [AuWbrCreate_MFSRR] = {
30928+ .create = au_wbr_create_mfsrr,
30929+ .init = au_wbr_create_init_mfsrr,
30930+ .fin = au_wbr_create_fin_mfs
30931+ },
30932+ [AuWbrCreate_MFSRRV] = {
30933+ .create = au_wbr_create_mfsrr,
30934+ .init = au_wbr_create_init_mfsrr,
30935+ .fin = au_wbr_create_fin_mfs
30936+ },
30937+ [AuWbrCreate_PMFS] = {
30938+ .create = au_wbr_create_pmfs,
30939+ .init = au_wbr_create_init_mfs,
30940+ .fin = au_wbr_create_fin_mfs
30941+ },
30942+ [AuWbrCreate_PMFSV] = {
30943+ .create = au_wbr_create_pmfs,
30944+ .init = au_wbr_create_init_mfs,
30945+ .fin = au_wbr_create_fin_mfs
392086de
AM
30946+ },
30947+ [AuWbrCreate_PMFSRR] = {
30948+ .create = au_wbr_create_pmfsrr,
30949+ .init = au_wbr_create_init_mfsrr,
30950+ .fin = au_wbr_create_fin_mfs
30951+ },
30952+ [AuWbrCreate_PMFSRRV] = {
30953+ .create = au_wbr_create_pmfsrr,
30954+ .init = au_wbr_create_init_mfsrr,
30955+ .fin = au_wbr_create_fin_mfs
1facf9fc 30956+ }
30957+};
7f207e10
AM
30958diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
30959--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
30960+++ linux/fs/aufs/whout.c 2014-08-14 10:15:45.131942973 +0200
30961@@ -0,0 +1,1056 @@
1facf9fc 30962+/*
523b37e3 30963+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30964+ *
30965+ * This program, aufs is free software; you can redistribute it and/or modify
30966+ * it under the terms of the GNU General Public License as published by
30967+ * the Free Software Foundation; either version 2 of the License, or
30968+ * (at your option) any later version.
dece6358
AM
30969+ *
30970+ * This program is distributed in the hope that it will be useful,
30971+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30972+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30973+ * GNU General Public License for more details.
30974+ *
30975+ * You should have received a copy of the GNU General Public License
523b37e3 30976+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30977+ */
30978+
30979+/*
30980+ * whiteout for logical deletion and opaque directory
30981+ */
30982+
1facf9fc 30983+#include "aufs.h"
30984+
30985+#define WH_MASK S_IRUGO
30986+
30987+/*
30988+ * If a directory contains this file, then it is opaque. We start with the
30989+ * .wh. flag so that it is blocked by lookup.
30990+ */
0c3ec466
AM
30991+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
30992+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 30993+
30994+/*
30995+ * generate whiteout name, which is NOT terminated by NULL.
30996+ * @name: original d_name.name
30997+ * @len: original d_name.len
30998+ * @wh: whiteout qstr
30999+ * returns zero when succeeds, otherwise error.
31000+ * succeeded value as wh->name should be freed by kfree().
31001+ */
31002+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
31003+{
31004+ char *p;
31005+
31006+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
31007+ return -ENAMETOOLONG;
31008+
31009+ wh->len = name->len + AUFS_WH_PFX_LEN;
31010+ p = kmalloc(wh->len, GFP_NOFS);
31011+ wh->name = p;
31012+ if (p) {
31013+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
31014+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
31015+ /* smp_mb(); */
31016+ return 0;
31017+ }
31018+ return -ENOMEM;
31019+}
31020+
31021+/* ---------------------------------------------------------------------- */
31022+
31023+/*
31024+ * test if the @wh_name exists under @h_parent.
31025+ * @try_sio specifies the necessary of super-io.
31026+ */
076b876e 31027+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 31028+{
31029+ int err;
31030+ struct dentry *wh_dentry;
1facf9fc 31031+
1facf9fc 31032+ if (!try_sio)
b4510431 31033+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 31034+ else
076b876e 31035+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 31036+ err = PTR_ERR(wh_dentry);
31037+ if (IS_ERR(wh_dentry))
31038+ goto out;
31039+
31040+ err = 0;
31041+ if (!wh_dentry->d_inode)
31042+ goto out_wh; /* success */
31043+
31044+ err = 1;
31045+ if (S_ISREG(wh_dentry->d_inode->i_mode))
31046+ goto out_wh; /* success */
31047+
31048+ err = -EIO;
523b37e3
AM
31049+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
31050+ wh_dentry, wh_dentry->d_inode->i_mode);
1facf9fc 31051+
4f0767ce 31052+out_wh:
1facf9fc 31053+ dput(wh_dentry);
4f0767ce 31054+out:
1facf9fc 31055+ return err;
31056+}
31057+
31058+/*
31059+ * test if the @h_dentry sets opaque or not.
31060+ */
076b876e 31061+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 31062+{
31063+ int err;
31064+ struct inode *h_dir;
31065+
31066+ h_dir = h_dentry->d_inode;
076b876e 31067+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 31068+ au_test_h_perm_sio(h_dir, MAY_EXEC));
31069+ return err;
31070+}
31071+
31072+/*
31073+ * returns a negative dentry whose name is unique and temporary.
31074+ */
31075+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
31076+ struct qstr *prefix)
31077+{
1facf9fc 31078+ struct dentry *dentry;
31079+ int i;
027c5e7a 31080+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 31081+ *name, *p;
027c5e7a 31082+ /* strict atomic_t is unnecessary here */
1facf9fc 31083+ static unsigned short cnt;
31084+ struct qstr qs;
31085+
4a4d8108
AM
31086+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
31087+
1facf9fc 31088+ name = defname;
027c5e7a
AM
31089+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
31090+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 31091+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 31092+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 31093+ goto out;
31094+ dentry = ERR_PTR(-ENOMEM);
31095+ name = kmalloc(qs.len + 1, GFP_NOFS);
31096+ if (unlikely(!name))
31097+ goto out;
31098+ }
31099+
31100+ /* doubly whiteout-ed */
31101+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
31102+ p = name + AUFS_WH_PFX_LEN * 2;
31103+ memcpy(p, prefix->name, prefix->len);
31104+ p += prefix->len;
31105+ *p++ = '.';
4a4d8108 31106+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 31107+
31108+ qs.name = name;
31109+ for (i = 0; i < 3; i++) {
b752ccd1 31110+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 31111+ dentry = au_sio_lkup_one(&qs, h_parent);
1facf9fc 31112+ if (IS_ERR(dentry) || !dentry->d_inode)
31113+ goto out_name;
31114+ dput(dentry);
31115+ }
0c3ec466 31116+ /* pr_warn("could not get random name\n"); */
1facf9fc 31117+ dentry = ERR_PTR(-EEXIST);
31118+ AuDbg("%.*s\n", AuLNPair(&qs));
31119+ BUG();
31120+
4f0767ce 31121+out_name:
1facf9fc 31122+ if (name != defname)
31123+ kfree(name);
4f0767ce 31124+out:
4a4d8108 31125+ AuTraceErrPtr(dentry);
1facf9fc 31126+ return dentry;
1facf9fc 31127+}
31128+
31129+/*
31130+ * rename the @h_dentry on @br to the whiteouted temporary name.
31131+ */
31132+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
31133+{
31134+ int err;
31135+ struct path h_path = {
86dc4139 31136+ .mnt = au_br_mnt(br)
1facf9fc 31137+ };
523b37e3 31138+ struct inode *h_dir, *delegated;
1facf9fc 31139+ struct dentry *h_parent;
31140+
31141+ h_parent = h_dentry->d_parent; /* dir inode is locked */
31142+ h_dir = h_parent->d_inode;
31143+ IMustLock(h_dir);
31144+
31145+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
31146+ err = PTR_ERR(h_path.dentry);
31147+ if (IS_ERR(h_path.dentry))
31148+ goto out;
31149+
31150+ /* under the same dir, no need to lock_rename() */
523b37e3
AM
31151+ delegated = NULL;
31152+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated);
1facf9fc 31153+ AuTraceErr(err);
523b37e3
AM
31154+ if (unlikely(err == -EWOULDBLOCK)) {
31155+ pr_warn("cannot retry for NFSv4 delegation"
31156+ " for an internal rename\n");
31157+ iput(delegated);
31158+ }
1facf9fc 31159+ dput(h_path.dentry);
31160+
4f0767ce 31161+out:
4a4d8108 31162+ AuTraceErr(err);
1facf9fc 31163+ return err;
31164+}
31165+
31166+/* ---------------------------------------------------------------------- */
31167+/*
31168+ * functions for removing a whiteout
31169+ */
31170+
31171+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
31172+{
523b37e3
AM
31173+ int err, force;
31174+ struct inode *delegated;
1facf9fc 31175+
31176+ /*
31177+ * forces superio when the dir has a sticky bit.
31178+ * this may be a violation of unix fs semantics.
31179+ */
31180+ force = (h_dir->i_mode & S_ISVTX)
0c3ec466 31181+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
523b37e3
AM
31182+ delegated = NULL;
31183+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
31184+ if (unlikely(err == -EWOULDBLOCK)) {
31185+ pr_warn("cannot retry for NFSv4 delegation"
31186+ " for an internal unlink\n");
31187+ iput(delegated);
31188+ }
31189+ return err;
1facf9fc 31190+}
31191+
31192+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
31193+ struct dentry *dentry)
31194+{
31195+ int err;
31196+
31197+ err = do_unlink_wh(h_dir, h_path);
31198+ if (!err && dentry)
31199+ au_set_dbwh(dentry, -1);
31200+
31201+ return err;
31202+}
31203+
31204+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
31205+ struct au_branch *br)
31206+{
31207+ int err;
31208+ struct path h_path = {
86dc4139 31209+ .mnt = au_br_mnt(br)
1facf9fc 31210+ };
31211+
31212+ err = 0;
b4510431 31213+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 31214+ if (IS_ERR(h_path.dentry))
31215+ err = PTR_ERR(h_path.dentry);
31216+ else {
31217+ if (h_path.dentry->d_inode
31218+ && S_ISREG(h_path.dentry->d_inode->i_mode))
31219+ err = do_unlink_wh(h_parent->d_inode, &h_path);
31220+ dput(h_path.dentry);
31221+ }
31222+
31223+ return err;
31224+}
31225+
31226+/* ---------------------------------------------------------------------- */
31227+/*
31228+ * initialize/clean whiteout for a branch
31229+ */
31230+
31231+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
31232+ const int isdir)
31233+{
31234+ int err;
523b37e3 31235+ struct inode *delegated;
1facf9fc 31236+
31237+ if (!whpath->dentry->d_inode)
31238+ return;
31239+
86dc4139
AM
31240+ if (isdir)
31241+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
31242+ else {
31243+ delegated = NULL;
31244+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
31245+ if (unlikely(err == -EWOULDBLOCK)) {
31246+ pr_warn("cannot retry for NFSv4 delegation"
31247+ " for an internal unlink\n");
31248+ iput(delegated);
31249+ }
31250+ }
1facf9fc 31251+ if (unlikely(err))
523b37e3
AM
31252+ pr_warn("failed removing %pd (%d), ignored.\n",
31253+ whpath->dentry, err);
1facf9fc 31254+}
31255+
31256+static int test_linkable(struct dentry *h_root)
31257+{
31258+ struct inode *h_dir = h_root->d_inode;
31259+
31260+ if (h_dir->i_op->link)
31261+ return 0;
31262+
523b37e3
AM
31263+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
31264+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 31265+ return -ENOSYS;
31266+}
31267+
31268+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
31269+static int au_whdir(struct inode *h_dir, struct path *path)
31270+{
31271+ int err;
31272+
31273+ err = -EEXIST;
31274+ if (!path->dentry->d_inode) {
31275+ int mode = S_IRWXU;
31276+
31277+ if (au_test_nfs(path->dentry->d_sb))
31278+ mode |= S_IXUGO;
86dc4139 31279+ err = vfsub_mkdir(h_dir, path, mode);
1facf9fc 31280+ } else if (S_ISDIR(path->dentry->d_inode->i_mode))
31281+ err = 0;
31282+ else
523b37e3 31283+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 31284+
31285+ return err;
31286+}
31287+
31288+struct au_wh_base {
31289+ const struct qstr *name;
31290+ struct dentry *dentry;
31291+};
31292+
31293+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
31294+ struct path *h_path)
31295+{
31296+ h_path->dentry = base[AuBrWh_BASE].dentry;
31297+ au_wh_clean(h_dir, h_path, /*isdir*/0);
31298+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31299+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31300+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31301+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31302+}
31303+
31304+/*
31305+ * returns tri-state,
31306+ * minus: error, caller should print the mesage
31307+ * zero: succuess
31308+ * plus: error, caller should NOT print the mesage
31309+ */
31310+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
31311+ int do_plink, struct au_wh_base base[],
31312+ struct path *h_path)
31313+{
31314+ int err;
31315+ struct inode *h_dir;
31316+
31317+ h_dir = h_root->d_inode;
31318+ h_path->dentry = base[AuBrWh_BASE].dentry;
31319+ au_wh_clean(h_dir, h_path, /*isdir*/0);
31320+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31321+ if (do_plink) {
31322+ err = test_linkable(h_root);
31323+ if (unlikely(err)) {
31324+ err = 1;
31325+ goto out;
31326+ }
31327+
31328+ err = au_whdir(h_dir, h_path);
31329+ if (unlikely(err))
31330+ goto out;
31331+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
31332+ } else
31333+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31334+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31335+ err = au_whdir(h_dir, h_path);
31336+ if (unlikely(err))
31337+ goto out;
31338+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
31339+
4f0767ce 31340+out:
1facf9fc 31341+ return err;
31342+}
31343+
31344+/*
31345+ * for the moment, aufs supports the branch filesystem which does not support
31346+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
31347+ * copyup failed. finally, such filesystem will not be used as the writable
31348+ * branch.
31349+ *
31350+ * returns tri-state, see above.
31351+ */
31352+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
31353+ int do_plink, struct au_wh_base base[],
31354+ struct path *h_path)
31355+{
31356+ int err;
31357+ struct inode *h_dir;
31358+
1308ab2a 31359+ WbrWhMustWriteLock(wbr);
31360+
1facf9fc 31361+ err = test_linkable(h_root);
31362+ if (unlikely(err)) {
31363+ err = 1;
31364+ goto out;
31365+ }
31366+
31367+ /*
31368+ * todo: should this create be done in /sbin/mount.aufs helper?
31369+ */
31370+ err = -EEXIST;
31371+ h_dir = h_root->d_inode;
31372+ if (!base[AuBrWh_BASE].dentry->d_inode) {
86dc4139
AM
31373+ h_path->dentry = base[AuBrWh_BASE].dentry;
31374+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
1facf9fc 31375+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
31376+ err = 0;
31377+ else
523b37e3 31378+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 31379+ if (unlikely(err))
31380+ goto out;
31381+
31382+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31383+ if (do_plink) {
31384+ err = au_whdir(h_dir, h_path);
31385+ if (unlikely(err))
31386+ goto out;
31387+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
31388+ } else
31389+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31390+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
31391+
31392+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31393+ err = au_whdir(h_dir, h_path);
31394+ if (unlikely(err))
31395+ goto out;
31396+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
31397+
4f0767ce 31398+out:
1facf9fc 31399+ return err;
31400+}
31401+
31402+/*
31403+ * initialize the whiteout base file/dir for @br.
31404+ */
86dc4139 31405+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 31406+{
31407+ int err, i;
31408+ const unsigned char do_plink
31409+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 31410+ struct inode *h_dir;
86dc4139
AM
31411+ struct path path = br->br_path;
31412+ struct dentry *h_root = path.dentry;
1facf9fc 31413+ struct au_wbr *wbr = br->br_wbr;
31414+ static const struct qstr base_name[] = {
0c3ec466
AM
31415+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
31416+ sizeof(AUFS_BASE_NAME) - 1),
31417+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
31418+ sizeof(AUFS_PLINKDIR_NAME) - 1),
31419+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
31420+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 31421+ };
31422+ struct au_wh_base base[] = {
31423+ [AuBrWh_BASE] = {
31424+ .name = base_name + AuBrWh_BASE,
31425+ .dentry = NULL
31426+ },
31427+ [AuBrWh_PLINK] = {
31428+ .name = base_name + AuBrWh_PLINK,
31429+ .dentry = NULL
31430+ },
31431+ [AuBrWh_ORPH] = {
31432+ .name = base_name + AuBrWh_ORPH,
31433+ .dentry = NULL
31434+ }
31435+ };
31436+
1308ab2a 31437+ if (wbr)
31438+ WbrWhMustWriteLock(wbr);
1facf9fc 31439+
1facf9fc 31440+ for (i = 0; i < AuBrWh_Last; i++) {
31441+ /* doubly whiteouted */
31442+ struct dentry *d;
31443+
31444+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
31445+ err = PTR_ERR(d);
31446+ if (IS_ERR(d))
31447+ goto out;
31448+
31449+ base[i].dentry = d;
31450+ AuDebugOn(wbr
31451+ && wbr->wbr_wh[i]
31452+ && wbr->wbr_wh[i] != base[i].dentry);
31453+ }
31454+
31455+ if (wbr)
31456+ for (i = 0; i < AuBrWh_Last; i++) {
31457+ dput(wbr->wbr_wh[i]);
31458+ wbr->wbr_wh[i] = NULL;
31459+ }
31460+
31461+ err = 0;
1e00d052 31462+ if (!au_br_writable(br->br_perm)) {
4a4d8108 31463+ h_dir = h_root->d_inode;
1facf9fc 31464+ au_wh_init_ro(h_dir, base, &path);
1e00d052 31465+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 31466+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
31467+ if (err > 0)
31468+ goto out;
31469+ else if (err)
31470+ goto out_err;
1e00d052 31471+ } else {
1facf9fc 31472+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
31473+ if (err > 0)
31474+ goto out;
31475+ else if (err)
31476+ goto out_err;
1facf9fc 31477+ }
31478+ goto out; /* success */
31479+
4f0767ce 31480+out_err:
523b37e3
AM
31481+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
31482+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 31483+out:
1facf9fc 31484+ for (i = 0; i < AuBrWh_Last; i++)
31485+ dput(base[i].dentry);
31486+ return err;
31487+}
31488+
31489+/* ---------------------------------------------------------------------- */
31490+/*
31491+ * whiteouts are all hard-linked usually.
31492+ * when its link count reaches a ceiling, we create a new whiteout base
31493+ * asynchronously.
31494+ */
31495+
31496+struct reinit_br_wh {
31497+ struct super_block *sb;
31498+ struct au_branch *br;
31499+};
31500+
31501+static void reinit_br_wh(void *arg)
31502+{
31503+ int err;
31504+ aufs_bindex_t bindex;
31505+ struct path h_path;
31506+ struct reinit_br_wh *a = arg;
31507+ struct au_wbr *wbr;
523b37e3 31508+ struct inode *dir, *delegated;
1facf9fc 31509+ struct dentry *h_root;
31510+ struct au_hinode *hdir;
31511+
31512+ err = 0;
31513+ wbr = a->br->br_wbr;
31514+ /* big aufs lock */
31515+ si_noflush_write_lock(a->sb);
31516+ if (!au_br_writable(a->br->br_perm))
31517+ goto out;
31518+ bindex = au_br_index(a->sb, a->br->br_id);
31519+ if (unlikely(bindex < 0))
31520+ goto out;
31521+
1308ab2a 31522+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 31523+ dir = a->sb->s_root->d_inode;
1facf9fc 31524+ hdir = au_hi(dir, bindex);
31525+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 31526+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 31527+
4a4d8108 31528+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 31529+ wbr_wh_write_lock(wbr);
31530+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
31531+ h_root, a->br);
31532+ if (!err) {
86dc4139
AM
31533+ h_path.dentry = wbr->wbr_whbase;
31534+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
31535+ delegated = NULL;
31536+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
31537+ /*force*/0);
31538+ if (unlikely(err == -EWOULDBLOCK)) {
31539+ pr_warn("cannot retry for NFSv4 delegation"
31540+ " for an internal unlink\n");
31541+ iput(delegated);
31542+ }
1facf9fc 31543+ } else {
523b37e3 31544+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 31545+ err = 0;
31546+ }
31547+ dput(wbr->wbr_whbase);
31548+ wbr->wbr_whbase = NULL;
31549+ if (!err)
86dc4139 31550+ err = au_wh_init(a->br, a->sb);
1facf9fc 31551+ wbr_wh_write_unlock(wbr);
4a4d8108 31552+ au_hn_imtx_unlock(hdir);
1308ab2a 31553+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
31554+ if (!err)
31555+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 31556+
4f0767ce 31557+out:
1facf9fc 31558+ if (wbr)
31559+ atomic_dec(&wbr->wbr_wh_running);
31560+ atomic_dec(&a->br->br_count);
1facf9fc 31561+ si_write_unlock(a->sb);
027c5e7a 31562+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 31563+ kfree(arg);
31564+ if (unlikely(err))
31565+ AuIOErr("err %d\n", err);
31566+}
31567+
31568+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
31569+{
31570+ int do_dec, wkq_err;
31571+ struct reinit_br_wh *arg;
31572+
31573+ do_dec = 1;
31574+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
31575+ goto out;
31576+
31577+ /* ignore ENOMEM */
31578+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
31579+ if (arg) {
31580+ /*
31581+ * dec(wh_running), kfree(arg) and dec(br_count)
31582+ * in reinit function
31583+ */
31584+ arg->sb = sb;
31585+ arg->br = br;
31586+ atomic_inc(&br->br_count);
53392da6 31587+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 31588+ if (unlikely(wkq_err)) {
31589+ atomic_dec(&br->br_wbr->wbr_wh_running);
31590+ atomic_dec(&br->br_count);
31591+ kfree(arg);
31592+ }
31593+ do_dec = 0;
31594+ }
31595+
4f0767ce 31596+out:
1facf9fc 31597+ if (do_dec)
31598+ atomic_dec(&br->br_wbr->wbr_wh_running);
31599+}
31600+
31601+/* ---------------------------------------------------------------------- */
31602+
31603+/*
31604+ * create the whiteout @wh.
31605+ */
31606+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
31607+ struct dentry *wh)
31608+{
31609+ int err;
31610+ struct path h_path = {
31611+ .dentry = wh
31612+ };
31613+ struct au_branch *br;
31614+ struct au_wbr *wbr;
31615+ struct dentry *h_parent;
523b37e3 31616+ struct inode *h_dir, *delegated;
1facf9fc 31617+
31618+ h_parent = wh->d_parent; /* dir inode is locked */
31619+ h_dir = h_parent->d_inode;
31620+ IMustLock(h_dir);
31621+
31622+ br = au_sbr(sb, bindex);
86dc4139 31623+ h_path.mnt = au_br_mnt(br);
1facf9fc 31624+ wbr = br->br_wbr;
31625+ wbr_wh_read_lock(wbr);
31626+ if (wbr->wbr_whbase) {
523b37e3
AM
31627+ delegated = NULL;
31628+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
31629+ if (unlikely(err == -EWOULDBLOCK)) {
31630+ pr_warn("cannot retry for NFSv4 delegation"
31631+ " for an internal link\n");
31632+ iput(delegated);
31633+ }
1facf9fc 31634+ if (!err || err != -EMLINK)
31635+ goto out;
31636+
31637+ /* link count full. re-initialize br_whbase. */
31638+ kick_reinit_br_wh(sb, br);
31639+ }
31640+
31641+ /* return this error in this context */
b4510431 31642+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
31643+ if (!err)
31644+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 31645+
4f0767ce 31646+out:
1facf9fc 31647+ wbr_wh_read_unlock(wbr);
31648+ return err;
31649+}
31650+
31651+/* ---------------------------------------------------------------------- */
31652+
31653+/*
31654+ * create or remove the diropq.
31655+ */
31656+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
31657+ unsigned int flags)
31658+{
31659+ struct dentry *opq_dentry, *h_dentry;
31660+ struct super_block *sb;
31661+ struct au_branch *br;
31662+ int err;
31663+
31664+ sb = dentry->d_sb;
31665+ br = au_sbr(sb, bindex);
31666+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 31667+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 31668+ if (IS_ERR(opq_dentry))
31669+ goto out;
31670+
31671+ if (au_ftest_diropq(flags, CREATE)) {
31672+ err = link_or_create_wh(sb, bindex, opq_dentry);
31673+ if (!err) {
31674+ au_set_dbdiropq(dentry, bindex);
31675+ goto out; /* success */
31676+ }
31677+ } else {
31678+ struct path tmp = {
31679+ .dentry = opq_dentry,
86dc4139 31680+ .mnt = au_br_mnt(br)
1facf9fc 31681+ };
31682+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
31683+ if (!err)
31684+ au_set_dbdiropq(dentry, -1);
31685+ }
31686+ dput(opq_dentry);
31687+ opq_dentry = ERR_PTR(err);
31688+
4f0767ce 31689+out:
1facf9fc 31690+ return opq_dentry;
31691+}
31692+
31693+struct do_diropq_args {
31694+ struct dentry **errp;
31695+ struct dentry *dentry;
31696+ aufs_bindex_t bindex;
31697+ unsigned int flags;
31698+};
31699+
31700+static void call_do_diropq(void *args)
31701+{
31702+ struct do_diropq_args *a = args;
31703+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
31704+}
31705+
31706+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
31707+ unsigned int flags)
31708+{
31709+ struct dentry *diropq, *h_dentry;
31710+
31711+ h_dentry = au_h_dptr(dentry, bindex);
31712+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
31713+ diropq = do_diropq(dentry, bindex, flags);
31714+ else {
31715+ int wkq_err;
31716+ struct do_diropq_args args = {
31717+ .errp = &diropq,
31718+ .dentry = dentry,
31719+ .bindex = bindex,
31720+ .flags = flags
31721+ };
31722+
31723+ wkq_err = au_wkq_wait(call_do_diropq, &args);
31724+ if (unlikely(wkq_err))
31725+ diropq = ERR_PTR(wkq_err);
31726+ }
31727+
31728+ return diropq;
31729+}
31730+
31731+/* ---------------------------------------------------------------------- */
31732+
31733+/*
31734+ * lookup whiteout dentry.
31735+ * @h_parent: lower parent dentry which must exist and be locked
31736+ * @base_name: name of dentry which will be whiteouted
31737+ * returns dentry for whiteout.
31738+ */
31739+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
31740+ struct au_branch *br)
31741+{
31742+ int err;
31743+ struct qstr wh_name;
31744+ struct dentry *wh_dentry;
31745+
31746+ err = au_wh_name_alloc(&wh_name, base_name);
31747+ wh_dentry = ERR_PTR(err);
31748+ if (!err) {
b4510431 31749+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 31750+ kfree(wh_name.name);
31751+ }
31752+ return wh_dentry;
31753+}
31754+
31755+/*
31756+ * link/create a whiteout for @dentry on @bindex.
31757+ */
31758+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
31759+ struct dentry *h_parent)
31760+{
31761+ struct dentry *wh_dentry;
31762+ struct super_block *sb;
31763+ int err;
31764+
31765+ sb = dentry->d_sb;
31766+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
31767+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
31768+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 31769+ if (!err) {
1facf9fc 31770+ au_set_dbwh(dentry, bindex);
076b876e
AM
31771+ au_fhsm_wrote(sb, bindex, /*force*/0);
31772+ } else {
1facf9fc 31773+ dput(wh_dentry);
31774+ wh_dentry = ERR_PTR(err);
31775+ }
31776+ }
31777+
31778+ return wh_dentry;
31779+}
31780+
31781+/* ---------------------------------------------------------------------- */
31782+
31783+/* Delete all whiteouts in this directory on branch bindex. */
31784+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
31785+ aufs_bindex_t bindex, struct au_branch *br)
31786+{
31787+ int err;
31788+ unsigned long ul, n;
31789+ struct qstr wh_name;
31790+ char *p;
31791+ struct hlist_head *head;
c06a8ce3 31792+ struct au_vdir_wh *pos;
1facf9fc 31793+ struct au_vdir_destr *str;
31794+
31795+ err = -ENOMEM;
537831f9 31796+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 31797+ wh_name.name = p;
31798+ if (unlikely(!wh_name.name))
31799+ goto out;
31800+
31801+ err = 0;
31802+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
31803+ p += AUFS_WH_PFX_LEN;
31804+ n = whlist->nh_num;
31805+ head = whlist->nh_head;
31806+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
31807+ hlist_for_each_entry(pos, head, wh_hash) {
31808+ if (pos->wh_bindex != bindex)
1facf9fc 31809+ continue;
31810+
c06a8ce3 31811+ str = &pos->wh_str;
1facf9fc 31812+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
31813+ memcpy(p, str->name, str->len);
31814+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
31815+ err = unlink_wh_name(h_dentry, &wh_name, br);
31816+ if (!err)
31817+ continue;
31818+ break;
31819+ }
31820+ AuIOErr("whiteout name too long %.*s\n",
31821+ str->len, str->name);
31822+ err = -EIO;
31823+ break;
31824+ }
31825+ }
537831f9 31826+ free_page((unsigned long)wh_name.name);
1facf9fc 31827+
4f0767ce 31828+out:
1facf9fc 31829+ return err;
31830+}
31831+
31832+struct del_wh_children_args {
31833+ int *errp;
31834+ struct dentry *h_dentry;
1308ab2a 31835+ struct au_nhash *whlist;
1facf9fc 31836+ aufs_bindex_t bindex;
31837+ struct au_branch *br;
31838+};
31839+
31840+static void call_del_wh_children(void *args)
31841+{
31842+ struct del_wh_children_args *a = args;
1308ab2a 31843+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 31844+}
31845+
31846+/* ---------------------------------------------------------------------- */
31847+
31848+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
31849+{
31850+ struct au_whtmp_rmdir *whtmp;
dece6358 31851+ int err;
1308ab2a 31852+ unsigned int rdhash;
dece6358
AM
31853+
31854+ SiMustAnyLock(sb);
1facf9fc 31855+
31856+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
31857+ if (unlikely(!whtmp)) {
31858+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 31859+ goto out;
dece6358 31860+ }
1facf9fc 31861+
31862+ whtmp->dir = NULL;
027c5e7a 31863+ whtmp->br = NULL;
1facf9fc 31864+ whtmp->wh_dentry = NULL;
1308ab2a 31865+ /* no estimation for dir size */
31866+ rdhash = au_sbi(sb)->si_rdhash;
31867+ if (!rdhash)
31868+ rdhash = AUFS_RDHASH_DEF;
31869+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
31870+ if (unlikely(err)) {
31871+ kfree(whtmp);
31872+ whtmp = ERR_PTR(err);
31873+ }
dece6358 31874+
4f0767ce 31875+out:
dece6358 31876+ return whtmp;
1facf9fc 31877+}
31878+
31879+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
31880+{
027c5e7a
AM
31881+ if (whtmp->br)
31882+ atomic_dec(&whtmp->br->br_count);
1facf9fc 31883+ dput(whtmp->wh_dentry);
31884+ iput(whtmp->dir);
dece6358 31885+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 31886+ kfree(whtmp);
31887+}
31888+
31889+/*
31890+ * rmdir the whiteouted temporary named dir @h_dentry.
31891+ * @whlist: whiteouted children.
31892+ */
31893+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
31894+ struct dentry *wh_dentry, struct au_nhash *whlist)
31895+{
31896+ int err;
31897+ struct path h_tmp;
31898+ struct inode *wh_inode, *h_dir;
31899+ struct au_branch *br;
31900+
31901+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
31902+ IMustLock(h_dir);
31903+
31904+ br = au_sbr(dir->i_sb, bindex);
31905+ wh_inode = wh_dentry->d_inode;
31906+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
31907+
31908+ /*
31909+ * someone else might change some whiteouts while we were sleeping.
31910+ * it means this whlist may have an obsoleted entry.
31911+ */
31912+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
31913+ err = del_wh_children(wh_dentry, whlist, bindex, br);
31914+ else {
31915+ int wkq_err;
31916+ struct del_wh_children_args args = {
31917+ .errp = &err,
31918+ .h_dentry = wh_dentry,
1308ab2a 31919+ .whlist = whlist,
1facf9fc 31920+ .bindex = bindex,
31921+ .br = br
31922+ };
31923+
31924+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
31925+ if (unlikely(wkq_err))
31926+ err = wkq_err;
31927+ }
31928+ mutex_unlock(&wh_inode->i_mutex);
31929+
31930+ if (!err) {
31931+ h_tmp.dentry = wh_dentry;
86dc4139 31932+ h_tmp.mnt = au_br_mnt(br);
1facf9fc 31933+ err = vfsub_rmdir(h_dir, &h_tmp);
1facf9fc 31934+ }
31935+
31936+ if (!err) {
31937+ if (au_ibstart(dir) == bindex) {
7f207e10 31938+ /* todo: dir->i_mutex is necessary */
1facf9fc 31939+ au_cpup_attr_timesizes(dir);
7f207e10 31940+ vfsub_drop_nlink(dir);
1facf9fc 31941+ }
31942+ return 0; /* success */
31943+ }
31944+
523b37e3 31945+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 31946+ return err;
31947+}
31948+
31949+static void call_rmdir_whtmp(void *args)
31950+{
31951+ int err;
e49829fe 31952+ aufs_bindex_t bindex;
1facf9fc 31953+ struct au_whtmp_rmdir *a = args;
31954+ struct super_block *sb;
31955+ struct dentry *h_parent;
31956+ struct inode *h_dir;
1facf9fc 31957+ struct au_hinode *hdir;
31958+
31959+ /* rmdir by nfsd may cause deadlock with this i_mutex */
31960+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 31961+ err = -EROFS;
1facf9fc 31962+ sb = a->dir->i_sb;
e49829fe
JR
31963+ si_read_lock(sb, !AuLock_FLUSH);
31964+ if (!au_br_writable(a->br->br_perm))
31965+ goto out;
31966+ bindex = au_br_index(sb, a->br->br_id);
31967+ if (unlikely(bindex < 0))
1facf9fc 31968+ goto out;
31969+
31970+ err = -EIO;
1facf9fc 31971+ ii_write_lock_parent(a->dir);
31972+ h_parent = dget_parent(a->wh_dentry);
31973+ h_dir = h_parent->d_inode;
e49829fe 31974+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
31975+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
31976+ if (unlikely(err))
31977+ goto out_mnt;
4a4d8108 31978+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
31979+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
31980+ a->br);
86dc4139
AM
31981+ if (!err)
31982+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 31983+ au_hn_imtx_unlock(hdir);
86dc4139
AM
31984+ vfsub_mnt_drop_write(au_br_mnt(a->br));
31985+
31986+out_mnt:
1facf9fc 31987+ dput(h_parent);
31988+ ii_write_unlock(a->dir);
4f0767ce 31989+out:
1facf9fc 31990+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 31991+ au_whtmp_rmdir_free(a);
027c5e7a
AM
31992+ si_read_unlock(sb);
31993+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 31994+ if (unlikely(err))
31995+ AuIOErr("err %d\n", err);
31996+}
31997+
31998+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
31999+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
32000+{
32001+ int wkq_err;
e49829fe 32002+ struct super_block *sb;
1facf9fc 32003+
32004+ IMustLock(dir);
32005+
32006+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 32007+ sb = dir->i_sb;
1facf9fc 32008+ args->dir = au_igrab(dir);
e49829fe
JR
32009+ args->br = au_sbr(sb, bindex);
32010+ atomic_inc(&args->br->br_count);
1facf9fc 32011+ args->wh_dentry = dget(wh_dentry);
53392da6 32012+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 32013+ if (unlikely(wkq_err)) {
523b37e3 32014+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 32015+ au_whtmp_rmdir_free(args);
32016+ }
32017+}
7f207e10
AM
32018diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
32019--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
32020+++ linux/fs/aufs/whout.h 2014-08-14 10:15:45.131942973 +0200
32021@@ -0,0 +1,85 @@
1facf9fc 32022+/*
523b37e3 32023+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 32024+ *
32025+ * This program, aufs is free software; you can redistribute it and/or modify
32026+ * it under the terms of the GNU General Public License as published by
32027+ * the Free Software Foundation; either version 2 of the License, or
32028+ * (at your option) any later version.
dece6358
AM
32029+ *
32030+ * This program is distributed in the hope that it will be useful,
32031+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32032+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32033+ * GNU General Public License for more details.
32034+ *
32035+ * You should have received a copy of the GNU General Public License
523b37e3 32036+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32037+ */
32038+
32039+/*
32040+ * whiteout for logical deletion and opaque directory
32041+ */
32042+
32043+#ifndef __AUFS_WHOUT_H__
32044+#define __AUFS_WHOUT_H__
32045+
32046+#ifdef __KERNEL__
32047+
1facf9fc 32048+#include "dir.h"
32049+
32050+/* whout.c */
32051+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
32052+struct au_branch;
076b876e
AM
32053+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
32054+int au_diropq_test(struct dentry *h_dentry);
1facf9fc 32055+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
32056+ struct qstr *prefix);
32057+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
32058+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
32059+ struct dentry *dentry);
86dc4139 32060+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 32061+
32062+/* diropq flags */
32063+#define AuDiropq_CREATE 1
32064+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
32065+#define au_fset_diropq(flags, name) \
32066+ do { (flags) |= AuDiropq_##name; } while (0)
32067+#define au_fclr_diropq(flags, name) \
32068+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 32069+
32070+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
32071+ unsigned int flags);
32072+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
32073+ struct au_branch *br);
32074+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
32075+ struct dentry *h_parent);
32076+
32077+/* real rmdir for the whiteout-ed dir */
32078+struct au_whtmp_rmdir {
32079+ struct inode *dir;
e49829fe 32080+ struct au_branch *br;
1facf9fc 32081+ struct dentry *wh_dentry;
dece6358 32082+ struct au_nhash whlist;
1facf9fc 32083+};
32084+
32085+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
32086+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
32087+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
32088+ struct dentry *wh_dentry, struct au_nhash *whlist);
32089+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
32090+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
32091+
32092+/* ---------------------------------------------------------------------- */
32093+
32094+static inline struct dentry *au_diropq_create(struct dentry *dentry,
32095+ aufs_bindex_t bindex)
32096+{
32097+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
32098+}
32099+
32100+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
32101+{
32102+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
32103+}
32104+
32105+#endif /* __KERNEL__ */
32106+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
32107diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
32108--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
076b876e 32109+++ linux/fs/aufs/wkq.c 2014-08-14 10:16:04.515942371 +0200
38d290e6 32110@@ -0,0 +1,213 @@
1facf9fc 32111+/*
523b37e3 32112+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 32113+ *
32114+ * This program, aufs is free software; you can redistribute it and/or modify
32115+ * it under the terms of the GNU General Public License as published by
32116+ * the Free Software Foundation; either version 2 of the License, or
32117+ * (at your option) any later version.
dece6358
AM
32118+ *
32119+ * This program is distributed in the hope that it will be useful,
32120+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32121+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32122+ * GNU General Public License for more details.
32123+ *
32124+ * You should have received a copy of the GNU General Public License
523b37e3 32125+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32126+ */
32127+
32128+/*
32129+ * workqueue for asynchronous/super-io operations
32130+ * todo: try new dredential scheme
32131+ */
32132+
dece6358 32133+#include <linux/module.h>
1facf9fc 32134+#include "aufs.h"
32135+
9dbd164d 32136+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 32137+
9dbd164d 32138+static struct workqueue_struct *au_wkq;
1facf9fc 32139+
32140+struct au_wkinfo {
32141+ struct work_struct wk;
7f207e10 32142+ struct kobject *kobj;
1facf9fc 32143+
32144+ unsigned int flags; /* see wkq.h */
32145+
32146+ au_wkq_func_t func;
32147+ void *args;
32148+
1facf9fc 32149+ struct completion *comp;
32150+};
32151+
32152+/* ---------------------------------------------------------------------- */
32153+
1facf9fc 32154+static void wkq_func(struct work_struct *wk)
32155+{
32156+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
32157+
2dfbb274 32158+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
32159+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
32160+
1facf9fc 32161+ wkinfo->func(wkinfo->args);
1facf9fc 32162+ if (au_ftest_wkq(wkinfo->flags, WAIT))
32163+ complete(wkinfo->comp);
32164+ else {
7f207e10 32165+ kobject_put(wkinfo->kobj);
9dbd164d 32166+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 32167+ kfree(wkinfo);
32168+ }
32169+}
32170+
32171+/*
32172+ * Since struct completion is large, try allocating it dynamically.
32173+ */
c2b27bf2 32174+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 32175+#define AuWkqCompDeclare(name) struct completion *comp = NULL
32176+
32177+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
32178+{
32179+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
32180+ if (*comp) {
32181+ init_completion(*comp);
32182+ wkinfo->comp = *comp;
32183+ return 0;
32184+ }
32185+ return -ENOMEM;
32186+}
32187+
32188+static void au_wkq_comp_free(struct completion *comp)
32189+{
32190+ kfree(comp);
32191+}
32192+
32193+#else
32194+
32195+/* no braces */
32196+#define AuWkqCompDeclare(name) \
32197+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
32198+ struct completion *comp = &_ ## name
32199+
32200+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
32201+{
32202+ wkinfo->comp = *comp;
32203+ return 0;
32204+}
32205+
32206+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
32207+{
32208+ /* empty */
32209+}
32210+#endif /* 4KSTACKS */
32211+
53392da6 32212+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 32213+{
53392da6
AM
32214+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
32215+ if (au_wkq_test()) {
38d290e6
JR
32216+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
32217+ " due to a dead dir by UDBA?\n");
53392da6
AM
32218+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
32219+ }
32220+ } else
32221+ au_dbg_verify_kthread();
32222+
32223+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 32224+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 32225+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
32226+ } else {
32227+ INIT_WORK(&wkinfo->wk, wkq_func);
32228+ schedule_work(&wkinfo->wk);
32229+ }
1facf9fc 32230+}
32231+
7f207e10
AM
32232+/*
32233+ * Be careful. It is easy to make deadlock happen.
32234+ * processA: lock, wkq and wait
32235+ * processB: wkq and wait, lock in wkq
32236+ * --> deadlock
32237+ */
b752ccd1 32238+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 32239+{
32240+ int err;
32241+ AuWkqCompDeclare(comp);
32242+ struct au_wkinfo wkinfo = {
b752ccd1 32243+ .flags = flags,
1facf9fc 32244+ .func = func,
32245+ .args = args
32246+ };
32247+
32248+ err = au_wkq_comp_alloc(&wkinfo, &comp);
32249+ if (!err) {
53392da6 32250+ au_wkq_run(&wkinfo);
1facf9fc 32251+ /* no timeout, no interrupt */
32252+ wait_for_completion(wkinfo.comp);
32253+ au_wkq_comp_free(comp);
4a4d8108 32254+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 32255+ }
32256+
32257+ return err;
32258+
32259+}
32260+
027c5e7a
AM
32261+/*
32262+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
32263+ * problem in a concurrent umounting.
32264+ */
53392da6
AM
32265+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
32266+ unsigned int flags)
1facf9fc 32267+{
32268+ int err;
32269+ struct au_wkinfo *wkinfo;
32270+
32271+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
32272+
32273+ /*
32274+ * wkq_func() must free this wkinfo.
32275+ * it highly depends upon the implementation of workqueue.
32276+ */
32277+ err = 0;
32278+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
32279+ if (wkinfo) {
7f207e10 32280+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 32281+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 32282+ wkinfo->func = func;
32283+ wkinfo->args = args;
32284+ wkinfo->comp = NULL;
7f207e10 32285+ kobject_get(wkinfo->kobj);
9dbd164d 32286+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 32287+
53392da6 32288+ au_wkq_run(wkinfo);
1facf9fc 32289+ } else {
32290+ err = -ENOMEM;
e49829fe 32291+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32292+ }
32293+
32294+ return err;
32295+}
32296+
32297+/* ---------------------------------------------------------------------- */
32298+
32299+void au_nwt_init(struct au_nowait_tasks *nwt)
32300+{
32301+ atomic_set(&nwt->nw_len, 0);
4a4d8108 32302+ /* smp_mb(); */ /* atomic_set */
1facf9fc 32303+ init_waitqueue_head(&nwt->nw_wq);
32304+}
32305+
32306+void au_wkq_fin(void)
32307+{
9dbd164d 32308+ destroy_workqueue(au_wkq);
1facf9fc 32309+}
32310+
32311+int __init au_wkq_init(void)
32312+{
9dbd164d 32313+ int err;
b752ccd1
AM
32314+
32315+ err = 0;
86dc4139 32316+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
32317+ if (IS_ERR(au_wkq))
32318+ err = PTR_ERR(au_wkq);
32319+ else if (!au_wkq)
32320+ err = -ENOMEM;
b752ccd1
AM
32321+
32322+ return err;
1facf9fc 32323+}
7f207e10
AM
32324diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
32325--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
076b876e 32326+++ linux/fs/aufs/wkq.h 2014-01-30 21:10:02.860815399 +0100
523b37e3 32327@@ -0,0 +1,91 @@
1facf9fc 32328+/*
523b37e3 32329+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 32330+ *
32331+ * This program, aufs is free software; you can redistribute it and/or modify
32332+ * it under the terms of the GNU General Public License as published by
32333+ * the Free Software Foundation; either version 2 of the License, or
32334+ * (at your option) any later version.
dece6358
AM
32335+ *
32336+ * This program is distributed in the hope that it will be useful,
32337+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32338+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32339+ * GNU General Public License for more details.
32340+ *
32341+ * You should have received a copy of the GNU General Public License
523b37e3 32342+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32343+ */
32344+
32345+/*
32346+ * workqueue for asynchronous/super-io operations
32347+ * todo: try new credentials management scheme
32348+ */
32349+
32350+#ifndef __AUFS_WKQ_H__
32351+#define __AUFS_WKQ_H__
32352+
32353+#ifdef __KERNEL__
32354+
dece6358
AM
32355+struct super_block;
32356+
1facf9fc 32357+/* ---------------------------------------------------------------------- */
32358+
32359+/*
32360+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
32361+ */
32362+struct au_nowait_tasks {
32363+ atomic_t nw_len;
32364+ wait_queue_head_t nw_wq;
32365+};
32366+
32367+/* ---------------------------------------------------------------------- */
32368+
32369+typedef void (*au_wkq_func_t)(void *args);
32370+
32371+/* wkq flags */
32372+#define AuWkq_WAIT 1
9dbd164d 32373+#define AuWkq_NEST (1 << 1)
1facf9fc 32374+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
32375+#define au_fset_wkq(flags, name) \
32376+ do { (flags) |= AuWkq_##name; } while (0)
32377+#define au_fclr_wkq(flags, name) \
32378+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 32379+
9dbd164d
AM
32380+#ifndef CONFIG_AUFS_HNOTIFY
32381+#undef AuWkq_NEST
32382+#define AuWkq_NEST 0
32383+#endif
32384+
1facf9fc 32385+/* wkq.c */
b752ccd1 32386+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
32387+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
32388+ unsigned int flags);
1facf9fc 32389+void au_nwt_init(struct au_nowait_tasks *nwt);
32390+int __init au_wkq_init(void);
32391+void au_wkq_fin(void);
32392+
32393+/* ---------------------------------------------------------------------- */
32394+
53392da6
AM
32395+static inline int au_wkq_test(void)
32396+{
32397+ return current->flags & PF_WQ_WORKER;
32398+}
32399+
b752ccd1 32400+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 32401+{
b752ccd1 32402+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 32403+}
32404+
32405+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
32406+{
e49829fe 32407+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 32408+ wake_up_all(&nwt->nw_wq);
32409+}
32410+
32411+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
32412+{
32413+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
32414+ return 0;
32415+}
32416+
32417+#endif /* __KERNEL__ */
32418+#endif /* __AUFS_WKQ_H__ */
7f207e10
AM
32419diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
32420--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
32421+++ linux/fs/aufs/xino.c 2014-08-14 10:16:04.515942371 +0200
32422@@ -0,0 +1,1316 @@
1facf9fc 32423+/*
523b37e3 32424+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 32425+ *
32426+ * This program, aufs is free software; you can redistribute it and/or modify
32427+ * it under the terms of the GNU General Public License as published by
32428+ * the Free Software Foundation; either version 2 of the License, or
32429+ * (at your option) any later version.
dece6358
AM
32430+ *
32431+ * This program is distributed in the hope that it will be useful,
32432+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32433+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32434+ * GNU General Public License for more details.
32435+ *
32436+ * You should have received a copy of the GNU General Public License
523b37e3 32437+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32438+ */
32439+
32440+/*
32441+ * external inode number translation table and bitmap
32442+ */
32443+
32444+#include <linux/seq_file.h>
392086de 32445+#include <linux/statfs.h>
1facf9fc 32446+#include "aufs.h"
32447+
9dbd164d 32448+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 32449+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 32450+ loff_t *pos)
32451+{
32452+ ssize_t err;
32453+ mm_segment_t oldfs;
b752ccd1
AM
32454+ union {
32455+ void *k;
32456+ char __user *u;
32457+ } buf;
1facf9fc 32458+
b752ccd1 32459+ buf.k = kbuf;
1facf9fc 32460+ oldfs = get_fs();
32461+ set_fs(KERNEL_DS);
32462+ do {
32463+ /* todo: signal_pending? */
b752ccd1 32464+ err = func(file, buf.u, size, pos);
1facf9fc 32465+ } while (err == -EAGAIN || err == -EINTR);
32466+ set_fs(oldfs);
32467+
32468+#if 0 /* reserved for future use */
32469+ if (err > 0)
32470+ fsnotify_access(file->f_dentry);
32471+#endif
32472+
32473+ return err;
32474+}
32475+
32476+/* ---------------------------------------------------------------------- */
32477+
b752ccd1 32478+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 32479+ size_t size, loff_t *pos)
32480+{
32481+ ssize_t err;
32482+ mm_segment_t oldfs;
b752ccd1
AM
32483+ union {
32484+ void *k;
32485+ const char __user *u;
32486+ } buf;
1facf9fc 32487+
b752ccd1 32488+ buf.k = kbuf;
1facf9fc 32489+ oldfs = get_fs();
32490+ set_fs(KERNEL_DS);
1facf9fc 32491+ do {
32492+ /* todo: signal_pending? */
b752ccd1 32493+ err = func(file, buf.u, size, pos);
1facf9fc 32494+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 32495+ set_fs(oldfs);
32496+
32497+#if 0 /* reserved for future use */
32498+ if (err > 0)
32499+ fsnotify_modify(file->f_dentry);
32500+#endif
32501+
32502+ return err;
32503+}
32504+
32505+struct do_xino_fwrite_args {
32506+ ssize_t *errp;
32507+ au_writef_t func;
32508+ struct file *file;
32509+ void *buf;
32510+ size_t size;
32511+ loff_t *pos;
32512+};
32513+
32514+static void call_do_xino_fwrite(void *args)
32515+{
32516+ struct do_xino_fwrite_args *a = args;
32517+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
32518+}
32519+
32520+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
32521+ loff_t *pos)
32522+{
32523+ ssize_t err;
32524+
32525+ /* todo: signal block and no wkq? */
b752ccd1
AM
32526+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
32527+ lockdep_off();
32528+ err = do_xino_fwrite(func, file, buf, size, pos);
32529+ lockdep_on();
32530+ } else {
32531+ /*
32532+ * it breaks RLIMIT_FSIZE and normal user's limit,
32533+ * users should care about quota and real 'filesystem full.'
32534+ */
1facf9fc 32535+ int wkq_err;
32536+ struct do_xino_fwrite_args args = {
32537+ .errp = &err,
32538+ .func = func,
32539+ .file = file,
32540+ .buf = buf,
32541+ .size = size,
32542+ .pos = pos
32543+ };
32544+
32545+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
32546+ if (unlikely(wkq_err))
32547+ err = wkq_err;
b752ccd1 32548+ }
1facf9fc 32549+
32550+ return err;
32551+}
32552+
32553+/* ---------------------------------------------------------------------- */
32554+
32555+/*
32556+ * create a new xinofile at the same place/path as @base_file.
32557+ */
32558+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
32559+{
32560+ struct file *file;
4a4d8108 32561+ struct dentry *base, *parent;
523b37e3 32562+ struct inode *dir, *delegated;
1facf9fc 32563+ struct qstr *name;
1308ab2a 32564+ struct path path;
4a4d8108 32565+ int err;
1facf9fc 32566+
32567+ base = base_file->f_dentry;
32568+ parent = base->d_parent; /* dir inode is locked */
32569+ dir = parent->d_inode;
32570+ IMustLock(dir);
32571+
32572+ file = ERR_PTR(-EINVAL);
32573+ name = &base->d_name;
4a4d8108
AM
32574+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
32575+ if (IS_ERR(path.dentry)) {
32576+ file = (void *)path.dentry;
523b37e3
AM
32577+ pr_err("%pd lookup err %ld\n",
32578+ base, PTR_ERR(path.dentry));
1facf9fc 32579+ goto out;
32580+ }
32581+
32582+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 32583+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 32584+ if (unlikely(err)) {
32585+ file = ERR_PTR(err);
523b37e3 32586+ pr_err("%pd create err %d\n", base, err);
1facf9fc 32587+ goto out_dput;
32588+ }
32589+
c06a8ce3 32590+ path.mnt = base_file->f_path.mnt;
4a4d8108 32591+ file = vfsub_dentry_open(&path,
7f207e10 32592+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 32593+ /* | __FMODE_NONOTIFY */);
1facf9fc 32594+ if (IS_ERR(file)) {
523b37e3 32595+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 32596+ goto out_dput;
32597+ }
32598+
523b37e3
AM
32599+ delegated = NULL;
32600+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
32601+ if (unlikely(err == -EWOULDBLOCK)) {
32602+ pr_warn("cannot retry for NFSv4 delegation"
32603+ " for an internal unlink\n");
32604+ iput(delegated);
32605+ }
1facf9fc 32606+ if (unlikely(err)) {
523b37e3 32607+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 32608+ goto out_fput;
32609+ }
32610+
32611+ if (copy_src) {
32612+ /* no one can touch copy_src xino */
c06a8ce3 32613+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 32614+ if (unlikely(err)) {
523b37e3 32615+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 32616+ goto out_fput;
32617+ }
32618+ }
32619+ goto out_dput; /* success */
32620+
4f0767ce 32621+out_fput:
1facf9fc 32622+ fput(file);
32623+ file = ERR_PTR(err);
4f0767ce 32624+out_dput:
4a4d8108 32625+ dput(path.dentry);
4f0767ce 32626+out:
1facf9fc 32627+ return file;
32628+}
32629+
32630+struct au_xino_lock_dir {
32631+ struct au_hinode *hdir;
32632+ struct dentry *parent;
32633+ struct mutex *mtx;
32634+};
32635+
32636+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
32637+ struct au_xino_lock_dir *ldir)
32638+{
32639+ aufs_bindex_t brid, bindex;
32640+
32641+ ldir->hdir = NULL;
32642+ bindex = -1;
32643+ brid = au_xino_brid(sb);
32644+ if (brid >= 0)
32645+ bindex = au_br_index(sb, brid);
32646+ if (bindex >= 0) {
32647+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 32648+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 32649+ } else {
32650+ ldir->parent = dget_parent(xino->f_dentry);
32651+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
32652+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
32653+ }
32654+}
32655+
32656+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
32657+{
32658+ if (ldir->hdir)
4a4d8108 32659+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 32660+ else {
32661+ mutex_unlock(ldir->mtx);
32662+ dput(ldir->parent);
32663+ }
32664+}
32665+
32666+/* ---------------------------------------------------------------------- */
32667+
32668+/* trucate xino files asynchronously */
32669+
32670+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
32671+{
32672+ int err;
392086de
AM
32673+ unsigned long jiffy;
32674+ blkcnt_t blocks;
1facf9fc 32675+ aufs_bindex_t bi, bend;
392086de 32676+ struct kstatfs *st;
1facf9fc 32677+ struct au_branch *br;
32678+ struct file *new_xino, *file;
32679+ struct super_block *h_sb;
32680+ struct au_xino_lock_dir ldir;
32681+
392086de
AM
32682+ err = -ENOMEM;
32683+ st = kzalloc(sizeof(*st), GFP_NOFS);
32684+ if (unlikely(!st))
32685+ goto out;
32686+
1facf9fc 32687+ err = -EINVAL;
32688+ bend = au_sbend(sb);
32689+ if (unlikely(bindex < 0 || bend < bindex))
392086de 32690+ goto out_st;
1facf9fc 32691+ br = au_sbr(sb, bindex);
32692+ file = br->br_xino.xi_file;
32693+ if (!file)
392086de
AM
32694+ goto out_st;
32695+
32696+ err = vfs_statfs(&file->f_path, st);
32697+ if (unlikely(err))
32698+ AuErr1("statfs err %d, ignored\n", err);
32699+ jiffy = jiffies;
32700+ blocks = file_inode(file)->i_blocks;
32701+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
32702+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 32703+
32704+ au_xino_lock_dir(sb, file, &ldir);
32705+ /* mnt_want_write() is unnecessary here */
32706+ new_xino = au_xino_create2(file, file);
32707+ au_xino_unlock_dir(&ldir);
32708+ err = PTR_ERR(new_xino);
392086de
AM
32709+ if (IS_ERR(new_xino)) {
32710+ pr_err("err %d, ignored\n", err);
32711+ goto out_st;
32712+ }
1facf9fc 32713+ err = 0;
32714+ fput(file);
32715+ br->br_xino.xi_file = new_xino;
32716+
86dc4139 32717+ h_sb = au_br_sb(br);
1facf9fc 32718+ for (bi = 0; bi <= bend; bi++) {
32719+ if (unlikely(bi == bindex))
32720+ continue;
32721+ br = au_sbr(sb, bi);
86dc4139 32722+ if (au_br_sb(br) != h_sb)
1facf9fc 32723+ continue;
32724+
32725+ fput(br->br_xino.xi_file);
32726+ br->br_xino.xi_file = new_xino;
32727+ get_file(new_xino);
32728+ }
32729+
392086de
AM
32730+ err = vfs_statfs(&new_xino->f_path, st);
32731+ if (!err) {
32732+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
32733+ bindex, (u64)file_inode(new_xino)->i_blocks,
32734+ st->f_bfree, st->f_blocks);
32735+ if (file_inode(new_xino)->i_blocks < blocks)
32736+ au_sbi(sb)->si_xino_jiffy = jiffy;
32737+ } else
32738+ AuErr1("statfs err %d, ignored\n", err);
32739+
32740+out_st:
32741+ kfree(st);
4f0767ce 32742+out:
1facf9fc 32743+ return err;
32744+}
32745+
32746+struct xino_do_trunc_args {
32747+ struct super_block *sb;
32748+ struct au_branch *br;
32749+};
32750+
32751+static void xino_do_trunc(void *_args)
32752+{
32753+ struct xino_do_trunc_args *args = _args;
32754+ struct super_block *sb;
32755+ struct au_branch *br;
32756+ struct inode *dir;
32757+ int err;
32758+ aufs_bindex_t bindex;
32759+
32760+ err = 0;
32761+ sb = args->sb;
32762+ dir = sb->s_root->d_inode;
32763+ br = args->br;
32764+
32765+ si_noflush_write_lock(sb);
32766+ ii_read_lock_parent(dir);
32767+ bindex = au_br_index(sb, br->br_id);
32768+ err = au_xino_trunc(sb, bindex);
1facf9fc 32769+ ii_read_unlock(dir);
32770+ if (unlikely(err))
392086de 32771+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 32772+ atomic_dec(&br->br_xino_running);
32773+ atomic_dec(&br->br_count);
1facf9fc 32774+ si_write_unlock(sb);
027c5e7a 32775+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32776+ kfree(args);
32777+}
32778+
392086de
AM
32779+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
32780+{
32781+ int err;
32782+ struct kstatfs st;
32783+ struct au_sbinfo *sbinfo;
32784+
32785+ /* todo: si_xino_expire and the ratio should be customizable */
32786+ sbinfo = au_sbi(sb);
32787+ if (time_before(jiffies,
32788+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
32789+ return 0;
32790+
32791+ /* truncation border */
32792+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
32793+ if (unlikely(err)) {
32794+ AuErr1("statfs err %d, ignored\n", err);
32795+ return 0;
32796+ }
32797+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
32798+ return 0;
32799+
32800+ return 1;
32801+}
32802+
1facf9fc 32803+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
32804+{
32805+ struct xino_do_trunc_args *args;
32806+ int wkq_err;
32807+
392086de 32808+ if (!xino_trunc_test(sb, br))
1facf9fc 32809+ return;
32810+
32811+ if (atomic_inc_return(&br->br_xino_running) > 1)
32812+ goto out;
32813+
32814+ /* lock and kfree() will be called in trunc_xino() */
32815+ args = kmalloc(sizeof(*args), GFP_NOFS);
32816+ if (unlikely(!args)) {
32817+ AuErr1("no memory\n");
32818+ goto out_args;
32819+ }
32820+
e49829fe 32821+ atomic_inc(&br->br_count);
1facf9fc 32822+ args->sb = sb;
32823+ args->br = br;
53392da6 32824+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 32825+ if (!wkq_err)
32826+ return; /* success */
32827+
4a4d8108 32828+ pr_err("wkq %d\n", wkq_err);
e49829fe 32829+ atomic_dec(&br->br_count);
1facf9fc 32830+
4f0767ce 32831+out_args:
1facf9fc 32832+ kfree(args);
4f0767ce 32833+out:
e49829fe 32834+ atomic_dec(&br->br_xino_running);
1facf9fc 32835+}
32836+
32837+/* ---------------------------------------------------------------------- */
32838+
32839+static int au_xino_do_write(au_writef_t write, struct file *file,
32840+ ino_t h_ino, ino_t ino)
32841+{
32842+ loff_t pos;
32843+ ssize_t sz;
32844+
32845+ pos = h_ino;
32846+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
32847+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
32848+ return -EFBIG;
32849+ }
32850+ pos *= sizeof(ino);
32851+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
32852+ if (sz == sizeof(ino))
32853+ return 0; /* success */
32854+
32855+ AuIOErr("write failed (%zd)\n", sz);
32856+ return -EIO;
32857+}
32858+
32859+/*
32860+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
32861+ * at the position of @h_ino.
32862+ * even if @ino is zero, it is written to the xinofile and means no entry.
32863+ * if the size of the xino file on a specific filesystem exceeds the watermark,
32864+ * try truncating it.
32865+ */
32866+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
32867+ ino_t ino)
32868+{
32869+ int err;
32870+ unsigned int mnt_flags;
32871+ struct au_branch *br;
32872+
32873+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
32874+ || ((loff_t)-1) > 0);
dece6358 32875+ SiMustAnyLock(sb);
1facf9fc 32876+
32877+ mnt_flags = au_mntflags(sb);
32878+ if (!au_opt_test(mnt_flags, XINO))
32879+ return 0;
32880+
32881+ br = au_sbr(sb, bindex);
32882+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
32883+ h_ino, ino);
32884+ if (!err) {
32885+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 32886+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 32887+ xino_try_trunc(sb, br);
32888+ return 0; /* success */
32889+ }
32890+
32891+ AuIOErr("write failed (%d)\n", err);
32892+ return -EIO;
32893+}
32894+
32895+/* ---------------------------------------------------------------------- */
32896+
32897+/* aufs inode number bitmap */
32898+
32899+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
32900+static ino_t xib_calc_ino(unsigned long pindex, int bit)
32901+{
32902+ ino_t ino;
32903+
32904+ AuDebugOn(bit < 0 || page_bits <= bit);
32905+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
32906+ return ino;
32907+}
32908+
32909+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
32910+{
32911+ AuDebugOn(ino < AUFS_FIRST_INO);
32912+ ino -= AUFS_FIRST_INO;
32913+ *pindex = ino / page_bits;
32914+ *bit = ino % page_bits;
32915+}
32916+
32917+static int xib_pindex(struct super_block *sb, unsigned long pindex)
32918+{
32919+ int err;
32920+ loff_t pos;
32921+ ssize_t sz;
32922+ struct au_sbinfo *sbinfo;
32923+ struct file *xib;
32924+ unsigned long *p;
32925+
32926+ sbinfo = au_sbi(sb);
32927+ MtxMustLock(&sbinfo->si_xib_mtx);
32928+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
32929+ || !au_opt_test(sbinfo->si_mntflags, XINO));
32930+
32931+ if (pindex == sbinfo->si_xib_last_pindex)
32932+ return 0;
32933+
32934+ xib = sbinfo->si_xib;
32935+ p = sbinfo->si_xib_buf;
32936+ pos = sbinfo->si_xib_last_pindex;
32937+ pos *= PAGE_SIZE;
32938+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
32939+ if (unlikely(sz != PAGE_SIZE))
32940+ goto out;
32941+
32942+ pos = pindex;
32943+ pos *= PAGE_SIZE;
c06a8ce3 32944+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 32945+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
32946+ else {
32947+ memset(p, 0, PAGE_SIZE);
32948+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
32949+ }
32950+ if (sz == PAGE_SIZE) {
32951+ sbinfo->si_xib_last_pindex = pindex;
32952+ return 0; /* success */
32953+ }
32954+
4f0767ce 32955+out:
b752ccd1
AM
32956+ AuIOErr1("write failed (%zd)\n", sz);
32957+ err = sz;
32958+ if (sz >= 0)
32959+ err = -EIO;
32960+ return err;
32961+}
32962+
32963+/* ---------------------------------------------------------------------- */
32964+
32965+static void au_xib_clear_bit(struct inode *inode)
32966+{
32967+ int err, bit;
32968+ unsigned long pindex;
32969+ struct super_block *sb;
32970+ struct au_sbinfo *sbinfo;
32971+
32972+ AuDebugOn(inode->i_nlink);
32973+
32974+ sb = inode->i_sb;
32975+ xib_calc_bit(inode->i_ino, &pindex, &bit);
32976+ AuDebugOn(page_bits <= bit);
32977+ sbinfo = au_sbi(sb);
32978+ mutex_lock(&sbinfo->si_xib_mtx);
32979+ err = xib_pindex(sb, pindex);
32980+ if (!err) {
32981+ clear_bit(bit, sbinfo->si_xib_buf);
32982+ sbinfo->si_xib_next_bit = bit;
32983+ }
32984+ mutex_unlock(&sbinfo->si_xib_mtx);
32985+}
32986+
32987+/* for s_op->delete_inode() */
32988+void au_xino_delete_inode(struct inode *inode, const int unlinked)
32989+{
32990+ int err;
32991+ unsigned int mnt_flags;
32992+ aufs_bindex_t bindex, bend, bi;
32993+ unsigned char try_trunc;
32994+ struct au_iinfo *iinfo;
32995+ struct super_block *sb;
32996+ struct au_hinode *hi;
32997+ struct inode *h_inode;
32998+ struct au_branch *br;
32999+ au_writef_t xwrite;
33000+
33001+ sb = inode->i_sb;
33002+ mnt_flags = au_mntflags(sb);
33003+ if (!au_opt_test(mnt_flags, XINO)
33004+ || inode->i_ino == AUFS_ROOT_INO)
33005+ return;
33006+
33007+ if (unlinked) {
33008+ au_xigen_inc(inode);
33009+ au_xib_clear_bit(inode);
33010+ }
33011+
33012+ iinfo = au_ii(inode);
33013+ if (!iinfo)
33014+ return;
1facf9fc 33015+
b752ccd1
AM
33016+ bindex = iinfo->ii_bstart;
33017+ if (bindex < 0)
33018+ return;
1facf9fc 33019+
b752ccd1
AM
33020+ xwrite = au_sbi(sb)->si_xwrite;
33021+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
33022+ hi = iinfo->ii_hinode + bindex;
33023+ bend = iinfo->ii_bend;
33024+ for (; bindex <= bend; bindex++, hi++) {
33025+ h_inode = hi->hi_inode;
33026+ if (!h_inode
33027+ || (!unlinked && h_inode->i_nlink))
33028+ continue;
1facf9fc 33029+
b752ccd1
AM
33030+ /* inode may not be revalidated */
33031+ bi = au_br_index(sb, hi->hi_id);
33032+ if (bi < 0)
33033+ continue;
1facf9fc 33034+
b752ccd1
AM
33035+ br = au_sbr(sb, bi);
33036+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
33037+ h_inode->i_ino, /*ino*/0);
33038+ if (!err && try_trunc
86dc4139 33039+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 33040+ xino_try_trunc(sb, br);
1facf9fc 33041+ }
1facf9fc 33042+}
33043+
33044+/* get an unused inode number from bitmap */
33045+ino_t au_xino_new_ino(struct super_block *sb)
33046+{
33047+ ino_t ino;
33048+ unsigned long *p, pindex, ul, pend;
33049+ struct au_sbinfo *sbinfo;
33050+ struct file *file;
33051+ int free_bit, err;
33052+
33053+ if (!au_opt_test(au_mntflags(sb), XINO))
33054+ return iunique(sb, AUFS_FIRST_INO);
33055+
33056+ sbinfo = au_sbi(sb);
33057+ mutex_lock(&sbinfo->si_xib_mtx);
33058+ p = sbinfo->si_xib_buf;
33059+ free_bit = sbinfo->si_xib_next_bit;
33060+ if (free_bit < page_bits && !test_bit(free_bit, p))
33061+ goto out; /* success */
33062+ free_bit = find_first_zero_bit(p, page_bits);
33063+ if (free_bit < page_bits)
33064+ goto out; /* success */
33065+
33066+ pindex = sbinfo->si_xib_last_pindex;
33067+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
33068+ err = xib_pindex(sb, ul);
33069+ if (unlikely(err))
33070+ goto out_err;
33071+ free_bit = find_first_zero_bit(p, page_bits);
33072+ if (free_bit < page_bits)
33073+ goto out; /* success */
33074+ }
33075+
33076+ file = sbinfo->si_xib;
c06a8ce3 33077+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 33078+ for (ul = pindex + 1; ul <= pend; ul++) {
33079+ err = xib_pindex(sb, ul);
33080+ if (unlikely(err))
33081+ goto out_err;
33082+ free_bit = find_first_zero_bit(p, page_bits);
33083+ if (free_bit < page_bits)
33084+ goto out; /* success */
33085+ }
33086+ BUG();
33087+
4f0767ce 33088+out:
1facf9fc 33089+ set_bit(free_bit, p);
7f207e10 33090+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 33091+ pindex = sbinfo->si_xib_last_pindex;
33092+ mutex_unlock(&sbinfo->si_xib_mtx);
33093+ ino = xib_calc_ino(pindex, free_bit);
33094+ AuDbg("i%lu\n", (unsigned long)ino);
33095+ return ino;
4f0767ce 33096+out_err:
1facf9fc 33097+ mutex_unlock(&sbinfo->si_xib_mtx);
33098+ AuDbg("i0\n");
33099+ return 0;
33100+}
33101+
33102+/*
33103+ * read @ino from xinofile for the specified branch{@sb, @bindex}
33104+ * at the position of @h_ino.
33105+ * if @ino does not exist and @do_new is true, get new one.
33106+ */
33107+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
33108+ ino_t *ino)
33109+{
33110+ int err;
33111+ ssize_t sz;
33112+ loff_t pos;
33113+ struct file *file;
33114+ struct au_sbinfo *sbinfo;
33115+
33116+ *ino = 0;
33117+ if (!au_opt_test(au_mntflags(sb), XINO))
33118+ return 0; /* no xino */
33119+
33120+ err = 0;
33121+ sbinfo = au_sbi(sb);
33122+ pos = h_ino;
33123+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
33124+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
33125+ return -EFBIG;
33126+ }
33127+ pos *= sizeof(*ino);
33128+
33129+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 33130+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 33131+ return 0; /* no ino */
33132+
33133+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
33134+ if (sz == sizeof(*ino))
33135+ return 0; /* success */
33136+
33137+ err = sz;
33138+ if (unlikely(sz >= 0)) {
33139+ err = -EIO;
33140+ AuIOErr("xino read error (%zd)\n", sz);
33141+ }
33142+
33143+ return err;
33144+}
33145+
33146+/* ---------------------------------------------------------------------- */
33147+
33148+/* create and set a new xino file */
33149+
33150+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
33151+{
33152+ struct file *file;
33153+ struct dentry *h_parent, *d;
33154+ struct inode *h_dir;
33155+ int err;
33156+
33157+ /*
33158+ * at mount-time, and the xino file is the default path,
4a4d8108 33159+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 33160+ * when a user specified the xino, we cannot get au_hdir to be ignored.
33161+ */
7f207e10 33162+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 33163+ /* | __FMODE_NONOTIFY */,
1facf9fc 33164+ S_IRUGO | S_IWUGO);
33165+ if (IS_ERR(file)) {
33166+ if (!silent)
4a4d8108 33167+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 33168+ return file;
33169+ }
33170+
33171+ /* keep file count */
33172+ h_parent = dget_parent(file->f_dentry);
33173+ h_dir = h_parent->d_inode;
33174+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
33175+ /* mnt_want_write() is unnecessary here */
523b37e3
AM
33176+ /* no delegation since it is just created */
33177+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, /*force*/0);
1facf9fc 33178+ mutex_unlock(&h_dir->i_mutex);
33179+ dput(h_parent);
33180+ if (unlikely(err)) {
33181+ if (!silent)
4a4d8108 33182+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 33183+ goto out;
33184+ }
33185+
33186+ err = -EINVAL;
33187+ d = file->f_dentry;
33188+ if (unlikely(sb == d->d_sb)) {
33189+ if (!silent)
4a4d8108 33190+ pr_err("%s must be outside\n", fname);
1facf9fc 33191+ goto out;
33192+ }
33193+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
33194+ if (!silent)
4a4d8108
AM
33195+ pr_err("xino doesn't support %s(%s)\n",
33196+ fname, au_sbtype(d->d_sb));
1facf9fc 33197+ goto out;
33198+ }
33199+ return file; /* success */
33200+
4f0767ce 33201+out:
1facf9fc 33202+ fput(file);
33203+ file = ERR_PTR(err);
33204+ return file;
33205+}
33206+
33207+/*
33208+ * find another branch who is on the same filesystem of the specified
33209+ * branch{@btgt}. search until @bend.
33210+ */
33211+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
33212+ aufs_bindex_t bend)
33213+{
33214+ aufs_bindex_t bindex;
33215+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
33216+
33217+ for (bindex = 0; bindex < btgt; bindex++)
33218+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
33219+ return bindex;
33220+ for (bindex++; bindex <= bend; bindex++)
33221+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
33222+ return bindex;
33223+ return -1;
33224+}
33225+
33226+/* ---------------------------------------------------------------------- */
33227+
33228+/*
33229+ * initialize the xinofile for the specified branch @br
33230+ * at the place/path where @base_file indicates.
33231+ * test whether another branch is on the same filesystem or not,
33232+ * if @do_test is true.
33233+ */
33234+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
33235+ struct file *base_file, int do_test)
33236+{
33237+ int err;
33238+ ino_t ino;
33239+ aufs_bindex_t bend, bindex;
33240+ struct au_branch *shared_br, *b;
33241+ struct file *file;
33242+ struct super_block *tgt_sb;
33243+
33244+ shared_br = NULL;
33245+ bend = au_sbend(sb);
33246+ if (do_test) {
86dc4139 33247+ tgt_sb = au_br_sb(br);
1facf9fc 33248+ for (bindex = 0; bindex <= bend; bindex++) {
33249+ b = au_sbr(sb, bindex);
86dc4139 33250+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 33251+ shared_br = b;
33252+ break;
33253+ }
33254+ }
33255+ }
33256+
33257+ if (!shared_br || !shared_br->br_xino.xi_file) {
33258+ struct au_xino_lock_dir ldir;
33259+
33260+ au_xino_lock_dir(sb, base_file, &ldir);
33261+ /* mnt_want_write() is unnecessary here */
33262+ file = au_xino_create2(base_file, NULL);
33263+ au_xino_unlock_dir(&ldir);
33264+ err = PTR_ERR(file);
33265+ if (IS_ERR(file))
33266+ goto out;
33267+ br->br_xino.xi_file = file;
33268+ } else {
33269+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
33270+ get_file(br->br_xino.xi_file);
33271+ }
33272+
33273+ ino = AUFS_ROOT_INO;
33274+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
33275+ h_ino, ino);
b752ccd1
AM
33276+ if (unlikely(err)) {
33277+ fput(br->br_xino.xi_file);
33278+ br->br_xino.xi_file = NULL;
33279+ }
1facf9fc 33280+
4f0767ce 33281+out:
1facf9fc 33282+ return err;
33283+}
33284+
33285+/* ---------------------------------------------------------------------- */
33286+
33287+/* trucate a xino bitmap file */
33288+
33289+/* todo: slow */
33290+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
33291+{
33292+ int err, bit;
33293+ ssize_t sz;
33294+ unsigned long pindex;
33295+ loff_t pos, pend;
33296+ struct au_sbinfo *sbinfo;
33297+ au_readf_t func;
33298+ ino_t *ino;
33299+ unsigned long *p;
33300+
33301+ err = 0;
33302+ sbinfo = au_sbi(sb);
dece6358 33303+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 33304+ p = sbinfo->si_xib_buf;
33305+ func = sbinfo->si_xread;
c06a8ce3 33306+ pend = vfsub_f_size_read(file);
1facf9fc 33307+ pos = 0;
33308+ while (pos < pend) {
33309+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
33310+ err = sz;
33311+ if (unlikely(sz <= 0))
33312+ goto out;
33313+
33314+ err = 0;
33315+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
33316+ if (unlikely(*ino < AUFS_FIRST_INO))
33317+ continue;
33318+
33319+ xib_calc_bit(*ino, &pindex, &bit);
33320+ AuDebugOn(page_bits <= bit);
33321+ err = xib_pindex(sb, pindex);
33322+ if (!err)
33323+ set_bit(bit, p);
33324+ else
33325+ goto out;
33326+ }
33327+ }
33328+
4f0767ce 33329+out:
1facf9fc 33330+ return err;
33331+}
33332+
33333+static int xib_restore(struct super_block *sb)
33334+{
33335+ int err;
33336+ aufs_bindex_t bindex, bend;
33337+ void *page;
33338+
33339+ err = -ENOMEM;
33340+ page = (void *)__get_free_page(GFP_NOFS);
33341+ if (unlikely(!page))
33342+ goto out;
33343+
33344+ err = 0;
33345+ bend = au_sbend(sb);
33346+ for (bindex = 0; !err && bindex <= bend; bindex++)
33347+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
33348+ err = do_xib_restore
33349+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
33350+ else
33351+ AuDbg("b%d\n", bindex);
33352+ free_page((unsigned long)page);
33353+
4f0767ce 33354+out:
1facf9fc 33355+ return err;
33356+}
33357+
33358+int au_xib_trunc(struct super_block *sb)
33359+{
33360+ int err;
33361+ ssize_t sz;
33362+ loff_t pos;
33363+ struct au_xino_lock_dir ldir;
33364+ struct au_sbinfo *sbinfo;
33365+ unsigned long *p;
33366+ struct file *file;
33367+
dece6358
AM
33368+ SiMustWriteLock(sb);
33369+
1facf9fc 33370+ err = 0;
33371+ sbinfo = au_sbi(sb);
33372+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
33373+ goto out;
33374+
33375+ file = sbinfo->si_xib;
c06a8ce3 33376+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 33377+ goto out;
33378+
33379+ au_xino_lock_dir(sb, file, &ldir);
33380+ /* mnt_want_write() is unnecessary here */
33381+ file = au_xino_create2(sbinfo->si_xib, NULL);
33382+ au_xino_unlock_dir(&ldir);
33383+ err = PTR_ERR(file);
33384+ if (IS_ERR(file))
33385+ goto out;
33386+ fput(sbinfo->si_xib);
33387+ sbinfo->si_xib = file;
33388+
33389+ p = sbinfo->si_xib_buf;
33390+ memset(p, 0, PAGE_SIZE);
33391+ pos = 0;
33392+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
33393+ if (unlikely(sz != PAGE_SIZE)) {
33394+ err = sz;
33395+ AuIOErr("err %d\n", err);
33396+ if (sz >= 0)
33397+ err = -EIO;
33398+ goto out;
33399+ }
33400+
33401+ mutex_lock(&sbinfo->si_xib_mtx);
33402+ /* mnt_want_write() is unnecessary here */
33403+ err = xib_restore(sb);
33404+ mutex_unlock(&sbinfo->si_xib_mtx);
33405+
33406+out:
33407+ return err;
33408+}
33409+
33410+/* ---------------------------------------------------------------------- */
33411+
33412+/*
33413+ * xino mount option handlers
33414+ */
33415+static au_readf_t find_readf(struct file *h_file)
33416+{
33417+ const struct file_operations *fop = h_file->f_op;
33418+
523b37e3
AM
33419+ if (fop->read)
33420+ return fop->read;
33421+ if (fop->aio_read)
33422+ return do_sync_read;
076b876e
AM
33423+ if (fop->read_iter)
33424+ return new_sync_read;
1facf9fc 33425+ return ERR_PTR(-ENOSYS);
33426+}
33427+
33428+static au_writef_t find_writef(struct file *h_file)
33429+{
33430+ const struct file_operations *fop = h_file->f_op;
33431+
523b37e3
AM
33432+ if (fop->write)
33433+ return fop->write;
33434+ if (fop->aio_write)
33435+ return do_sync_write;
076b876e
AM
33436+ if (fop->write_iter)
33437+ return new_sync_write;
1facf9fc 33438+ return ERR_PTR(-ENOSYS);
33439+}
33440+
33441+/* xino bitmap */
33442+static void xino_clear_xib(struct super_block *sb)
33443+{
33444+ struct au_sbinfo *sbinfo;
33445+
dece6358
AM
33446+ SiMustWriteLock(sb);
33447+
1facf9fc 33448+ sbinfo = au_sbi(sb);
33449+ sbinfo->si_xread = NULL;
33450+ sbinfo->si_xwrite = NULL;
33451+ if (sbinfo->si_xib)
33452+ fput(sbinfo->si_xib);
33453+ sbinfo->si_xib = NULL;
33454+ free_page((unsigned long)sbinfo->si_xib_buf);
33455+ sbinfo->si_xib_buf = NULL;
33456+}
33457+
33458+static int au_xino_set_xib(struct super_block *sb, struct file *base)
33459+{
33460+ int err;
33461+ loff_t pos;
33462+ struct au_sbinfo *sbinfo;
33463+ struct file *file;
33464+
dece6358
AM
33465+ SiMustWriteLock(sb);
33466+
1facf9fc 33467+ sbinfo = au_sbi(sb);
33468+ file = au_xino_create2(base, sbinfo->si_xib);
33469+ err = PTR_ERR(file);
33470+ if (IS_ERR(file))
33471+ goto out;
33472+ if (sbinfo->si_xib)
33473+ fput(sbinfo->si_xib);
33474+ sbinfo->si_xib = file;
33475+ sbinfo->si_xread = find_readf(file);
33476+ sbinfo->si_xwrite = find_writef(file);
33477+
33478+ err = -ENOMEM;
33479+ if (!sbinfo->si_xib_buf)
33480+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
33481+ if (unlikely(!sbinfo->si_xib_buf))
33482+ goto out_unset;
33483+
33484+ sbinfo->si_xib_last_pindex = 0;
33485+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 33486+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 33487+ pos = 0;
33488+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
33489+ PAGE_SIZE, &pos);
33490+ if (unlikely(err != PAGE_SIZE))
33491+ goto out_free;
33492+ }
33493+ err = 0;
33494+ goto out; /* success */
33495+
4f0767ce 33496+out_free:
1facf9fc 33497+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
33498+ sbinfo->si_xib_buf = NULL;
33499+ if (err >= 0)
33500+ err = -EIO;
4f0767ce 33501+out_unset:
b752ccd1
AM
33502+ fput(sbinfo->si_xib);
33503+ sbinfo->si_xib = NULL;
33504+ sbinfo->si_xread = NULL;
33505+ sbinfo->si_xwrite = NULL;
4f0767ce 33506+out:
b752ccd1 33507+ return err;
1facf9fc 33508+}
33509+
b752ccd1
AM
33510+/* xino for each branch */
33511+static void xino_clear_br(struct super_block *sb)
33512+{
33513+ aufs_bindex_t bindex, bend;
33514+ struct au_branch *br;
1facf9fc 33515+
b752ccd1
AM
33516+ bend = au_sbend(sb);
33517+ for (bindex = 0; bindex <= bend; bindex++) {
33518+ br = au_sbr(sb, bindex);
33519+ if (!br || !br->br_xino.xi_file)
33520+ continue;
33521+
33522+ fput(br->br_xino.xi_file);
33523+ br->br_xino.xi_file = NULL;
33524+ }
33525+}
33526+
33527+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 33528+{
33529+ int err;
b752ccd1
AM
33530+ ino_t ino;
33531+ aufs_bindex_t bindex, bend, bshared;
33532+ struct {
33533+ struct file *old, *new;
33534+ } *fpair, *p;
33535+ struct au_branch *br;
33536+ struct inode *inode;
33537+ au_writef_t writef;
1facf9fc 33538+
b752ccd1
AM
33539+ SiMustWriteLock(sb);
33540+
33541+ err = -ENOMEM;
33542+ bend = au_sbend(sb);
33543+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
33544+ if (unlikely(!fpair))
1facf9fc 33545+ goto out;
33546+
b752ccd1
AM
33547+ inode = sb->s_root->d_inode;
33548+ ino = AUFS_ROOT_INO;
33549+ writef = au_sbi(sb)->si_xwrite;
33550+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
33551+ br = au_sbr(sb, bindex);
33552+ bshared = is_sb_shared(sb, bindex, bindex - 1);
33553+ if (bshared >= 0) {
33554+ /* shared xino */
33555+ *p = fpair[bshared];
33556+ get_file(p->new);
33557+ }
33558+
33559+ if (!p->new) {
33560+ /* new xino */
33561+ p->old = br->br_xino.xi_file;
33562+ p->new = au_xino_create2(base, br->br_xino.xi_file);
33563+ err = PTR_ERR(p->new);
33564+ if (IS_ERR(p->new)) {
33565+ p->new = NULL;
33566+ goto out_pair;
33567+ }
33568+ }
33569+
33570+ err = au_xino_do_write(writef, p->new,
33571+ au_h_iptr(inode, bindex)->i_ino, ino);
33572+ if (unlikely(err))
33573+ goto out_pair;
33574+ }
33575+
33576+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
33577+ br = au_sbr(sb, bindex);
33578+ if (br->br_xino.xi_file)
33579+ fput(br->br_xino.xi_file);
33580+ get_file(p->new);
33581+ br->br_xino.xi_file = p->new;
33582+ }
1facf9fc 33583+
4f0767ce 33584+out_pair:
b752ccd1
AM
33585+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
33586+ if (p->new)
33587+ fput(p->new);
33588+ else
33589+ break;
33590+ kfree(fpair);
4f0767ce 33591+out:
1facf9fc 33592+ return err;
33593+}
b752ccd1
AM
33594+
33595+void au_xino_clr(struct super_block *sb)
33596+{
33597+ struct au_sbinfo *sbinfo;
33598+
33599+ au_xigen_clr(sb);
33600+ xino_clear_xib(sb);
33601+ xino_clear_br(sb);
33602+ sbinfo = au_sbi(sb);
33603+ /* lvalue, do not call au_mntflags() */
33604+ au_opt_clr(sbinfo->si_mntflags, XINO);
33605+}
33606+
33607+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
33608+{
33609+ int err, skip;
33610+ struct dentry *parent, *cur_parent;
33611+ struct qstr *dname, *cur_name;
33612+ struct file *cur_xino;
33613+ struct inode *dir;
33614+ struct au_sbinfo *sbinfo;
33615+
33616+ SiMustWriteLock(sb);
33617+
33618+ err = 0;
33619+ sbinfo = au_sbi(sb);
33620+ parent = dget_parent(xino->file->f_dentry);
33621+ if (remount) {
33622+ skip = 0;
33623+ dname = &xino->file->f_dentry->d_name;
33624+ cur_xino = sbinfo->si_xib;
33625+ if (cur_xino) {
33626+ cur_parent = dget_parent(cur_xino->f_dentry);
33627+ cur_name = &cur_xino->f_dentry->d_name;
33628+ skip = (cur_parent == parent
38d290e6 33629+ && au_qstreq(dname, cur_name));
b752ccd1
AM
33630+ dput(cur_parent);
33631+ }
33632+ if (skip)
33633+ goto out;
33634+ }
33635+
33636+ au_opt_set(sbinfo->si_mntflags, XINO);
33637+ dir = parent->d_inode;
33638+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
33639+ /* mnt_want_write() is unnecessary here */
33640+ err = au_xino_set_xib(sb, xino->file);
33641+ if (!err)
33642+ err = au_xigen_set(sb, xino->file);
33643+ if (!err)
33644+ err = au_xino_set_br(sb, xino->file);
33645+ mutex_unlock(&dir->i_mutex);
33646+ if (!err)
33647+ goto out; /* success */
33648+
33649+ /* reset all */
33650+ AuIOErr("failed creating xino(%d).\n", err);
33651+
4f0767ce 33652+out:
b752ccd1
AM
33653+ dput(parent);
33654+ return err;
33655+}
33656+
33657+/* ---------------------------------------------------------------------- */
33658+
33659+/*
33660+ * create a xinofile at the default place/path.
33661+ */
33662+struct file *au_xino_def(struct super_block *sb)
33663+{
33664+ struct file *file;
33665+ char *page, *p;
33666+ struct au_branch *br;
33667+ struct super_block *h_sb;
33668+ struct path path;
33669+ aufs_bindex_t bend, bindex, bwr;
33670+
33671+ br = NULL;
33672+ bend = au_sbend(sb);
33673+ bwr = -1;
33674+ for (bindex = 0; bindex <= bend; bindex++) {
33675+ br = au_sbr(sb, bindex);
33676+ if (au_br_writable(br->br_perm)
86dc4139 33677+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
33678+ bwr = bindex;
33679+ break;
33680+ }
33681+ }
33682+
7f207e10
AM
33683+ if (bwr >= 0) {
33684+ file = ERR_PTR(-ENOMEM);
537831f9 33685+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
33686+ if (unlikely(!page))
33687+ goto out;
86dc4139 33688+ path.mnt = au_br_mnt(br);
7f207e10
AM
33689+ path.dentry = au_h_dptr(sb->s_root, bwr);
33690+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
33691+ file = (void *)p;
33692+ if (!IS_ERR(p)) {
33693+ strcat(p, "/" AUFS_XINO_FNAME);
33694+ AuDbg("%s\n", p);
33695+ file = au_xino_create(sb, p, /*silent*/0);
33696+ if (!IS_ERR(file))
33697+ au_xino_brid_set(sb, br->br_id);
33698+ }
537831f9 33699+ free_page((unsigned long)page);
7f207e10
AM
33700+ } else {
33701+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
33702+ if (IS_ERR(file))
33703+ goto out;
33704+ h_sb = file->f_dentry->d_sb;
33705+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
33706+ pr_err("xino doesn't support %s(%s)\n",
33707+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
33708+ fput(file);
33709+ file = ERR_PTR(-EINVAL);
33710+ }
33711+ if (!IS_ERR(file))
33712+ au_xino_brid_set(sb, -1);
33713+ }
0c5527e5 33714+
7f207e10
AM
33715+out:
33716+ return file;
33717+}
33718+
33719+/* ---------------------------------------------------------------------- */
33720+
33721+int au_xino_path(struct seq_file *seq, struct file *file)
33722+{
33723+ int err;
33724+
33725+ err = au_seq_path(seq, &file->f_path);
33726+ if (unlikely(err < 0))
33727+ goto out;
33728+
33729+ err = 0;
33730+#define Deleted "\\040(deleted)"
33731+ seq->count -= sizeof(Deleted) - 1;
33732+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
33733+ sizeof(Deleted) - 1));
33734+#undef Deleted
33735+
33736+out:
33737+ return err;
33738+}
537831f9
AM
33739diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
33740--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
076b876e
AM
33741+++ linux/include/uapi/linux/aufs_type.h 2014-08-14 10:16:04.522609267 +0200
33742@@ -0,0 +1,380 @@
7f207e10 33743+/*
523b37e3 33744+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
33745+ *
33746+ * This program, aufs is free software; you can redistribute it and/or modify
33747+ * it under the terms of the GNU General Public License as published by
33748+ * the Free Software Foundation; either version 2 of the License, or
33749+ * (at your option) any later version.
33750+ *
33751+ * This program is distributed in the hope that it will be useful,
33752+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33753+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33754+ * GNU General Public License for more details.
33755+ *
33756+ * You should have received a copy of the GNU General Public License
523b37e3 33757+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
33758+ */
33759+
33760+#ifndef __AUFS_TYPE_H__
33761+#define __AUFS_TYPE_H__
33762+
f6c5ef8b
AM
33763+#define AUFS_NAME "aufs"
33764+
9dbd164d 33765+#ifdef __KERNEL__
f6c5ef8b
AM
33766+/*
33767+ * define it before including all other headers.
33768+ * sched.h may use pr_* macros before defining "current", so define the
33769+ * no-current version first, and re-define later.
33770+ */
33771+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
33772+#include <linux/sched.h>
33773+#undef pr_fmt
a2a7ad62
AM
33774+#define pr_fmt(fmt) \
33775+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
33776+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
33777+#else
33778+#include <stdint.h>
33779+#include <sys/types.h>
f6c5ef8b 33780+#endif /* __KERNEL__ */
7f207e10 33781+
f6c5ef8b
AM
33782+#include <linux/limits.h>
33783+
076b876e 33784+#define AUFS_VERSION "3.16-20140811"
7f207e10
AM
33785+
33786+/* todo? move this to linux-2.6.19/include/magic.h */
33787+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
33788+
33789+/* ---------------------------------------------------------------------- */
33790+
33791+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 33792+typedef int8_t aufs_bindex_t;
7f207e10
AM
33793+#define AUFS_BRANCH_MAX 127
33794+#else
9dbd164d 33795+typedef int16_t aufs_bindex_t;
7f207e10
AM
33796+#ifdef CONFIG_AUFS_BRANCH_MAX_511
33797+#define AUFS_BRANCH_MAX 511
33798+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
33799+#define AUFS_BRANCH_MAX 1023
33800+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
33801+#define AUFS_BRANCH_MAX 32767
33802+#endif
33803+#endif
33804+
33805+#ifdef __KERNEL__
33806+#ifndef AUFS_BRANCH_MAX
33807+#error unknown CONFIG_AUFS_BRANCH_MAX value
33808+#endif
33809+#endif /* __KERNEL__ */
33810+
33811+/* ---------------------------------------------------------------------- */
33812+
7f207e10
AM
33813+#define AUFS_FSTYPE AUFS_NAME
33814+
33815+#define AUFS_ROOT_INO 2
33816+#define AUFS_FIRST_INO 11
33817+
33818+#define AUFS_WH_PFX ".wh."
33819+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
33820+#define AUFS_WH_TMP_LEN 4
86dc4139 33821+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
33822+#define AUFS_MAX_NAMELEN (NAME_MAX \
33823+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
33824+ - 1 /* dot */\
33825+ - AUFS_WH_TMP_LEN) /* hex */
33826+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
33827+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
33828+#define AUFS_XINO_DEF_SEC 30 /* seconds */
33829+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
33830+#define AUFS_DIRWH_DEF 3
33831+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 33832+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
33833+#define AUFS_RDBLK_DEF 512 /* bytes */
33834+#define AUFS_RDHASH_DEF 32
33835+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
33836+#define AUFS_MFS_DEF_SEC 30 /* seconds */
33837+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 33838+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 33839+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
33840+
33841+/* pseudo-link maintenace under /proc */
33842+#define AUFS_PLINK_MAINT_NAME "plink_maint"
33843+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
33844+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
33845+
33846+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
33847+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
33848+
33849+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
33850+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
33851+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
33852+
33853+/* doubly whiteouted */
33854+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
33855+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
33856+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
33857+
1e00d052 33858+/* branch permissions and attributes */
7f207e10
AM
33859+#define AUFS_BRPERM_RW "rw"
33860+#define AUFS_BRPERM_RO "ro"
33861+#define AUFS_BRPERM_RR "rr"
076b876e
AM
33862+#define AUFS_BRATTR_COO_REG "coo_reg"
33863+#define AUFS_BRATTR_COO_ALL "coo_all"
33864+#define AUFS_BRATTR_FHSM "fhsm"
33865+#define AUFS_BRATTR_UNPIN "unpin"
1e00d052
AM
33866+#define AUFS_BRRATTR_WH "wh"
33867+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
33868+#define AUFS_BRWATTR_MOO "moo"
33869+
33870+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
33871+#define AuBrPerm_RO (1 << 1) /* readonly */
33872+#define AuBrPerm_RR (1 << 2) /* natively readonly */
33873+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
33874+
33875+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
33876+#define AuBrAttr_COO_ALL (1 << 4)
33877+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
33878+
33879+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
33880+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
33881+ branch */
33882+
33883+#define AuBrRAttr_WH (1 << 7) /* whiteout-able */
33884+#define AuBrRAttr_Mask AuBrRAttr_WH
33885+
33886+#define AuBrWAttr_NoLinkWH (1 << 8) /* un-hardlinkable whiteouts */
33887+#define AuBrWAttr_MOO (1 << 9) /* move-up on open */
33888+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
33889+
33890+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
33891+
33892+#ifdef __KERNEL__
33893+#ifndef CONFIG_AUFS_FHSM
33894+#undef AuBrAttr_FHSM
33895+#define AuBrAttr_FHSM 0
33896+#endif
33897+#endif
33898+
33899+/* the longest combination */
33900+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
33901+ "+" AUFS_BRATTR_COO_REG \
33902+ "+" AUFS_BRATTR_FHSM \
33903+ "+" AUFS_BRATTR_UNPIN \
33904+ "+" AUFS_BRWATTR_NLWH)
33905+
33906+typedef struct {
33907+ char a[AuBrPermStrSz];
33908+} au_br_perm_str_t;
33909+
33910+static inline int au_br_writable(int brperm)
33911+{
33912+ return brperm & AuBrPerm_RW;
33913+}
33914+
33915+static inline int au_br_whable(int brperm)
33916+{
33917+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
33918+}
33919+
33920+static inline int au_br_wh_linkable(int brperm)
33921+{
33922+ return !(brperm & AuBrWAttr_NoLinkWH);
33923+}
33924+
33925+static inline int au_br_cmoo(int brperm)
33926+{
33927+ return brperm & AuBrAttr_CMOO_Mask;
33928+}
33929+
33930+static inline int au_br_fhsm(int brperm)
33931+{
33932+ return brperm & AuBrAttr_FHSM;
33933+}
7f207e10
AM
33934+
33935+/* ---------------------------------------------------------------------- */
33936+
33937+/* ioctl */
33938+enum {
33939+ /* readdir in userspace */
33940+ AuCtl_RDU,
33941+ AuCtl_RDU_INO,
33942+
076b876e
AM
33943+ AuCtl_WBR_FD, /* pathconf wrapper */
33944+ AuCtl_IBUSY, /* busy inode */
33945+ AuCtl_MVDOWN, /* move-down */
33946+ AuCtl_BR, /* info about branches */
33947+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
33948+};
33949+
33950+/* borrowed from linux/include/linux/kernel.h */
33951+#ifndef ALIGN
33952+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
33953+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
33954+#endif
33955+
33956+/* borrowed from linux/include/linux/compiler-gcc3.h */
33957+#ifndef __aligned
33958+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
33959+#endif
33960+
33961+#ifdef __KERNEL__
33962+#ifndef __packed
7f207e10
AM
33963+#define __packed __attribute__((packed))
33964+#endif
53392da6 33965+#endif
7f207e10
AM
33966+
33967+struct au_rdu_cookie {
9dbd164d
AM
33968+ uint64_t h_pos;
33969+ int16_t bindex;
33970+ uint8_t flags;
33971+ uint8_t pad;
33972+ uint32_t generation;
7f207e10
AM
33973+} __aligned(8);
33974+
33975+struct au_rdu_ent {
9dbd164d
AM
33976+ uint64_t ino;
33977+ int16_t bindex;
33978+ uint8_t type;
33979+ uint8_t nlen;
33980+ uint8_t wh;
7f207e10
AM
33981+ char name[0];
33982+} __aligned(8);
33983+
33984+static inline int au_rdu_len(int nlen)
33985+{
33986+ /* include the terminating NULL */
33987+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 33988+ sizeof(uint64_t));
7f207e10
AM
33989+}
33990+
33991+union au_rdu_ent_ul {
33992+ struct au_rdu_ent __user *e;
9dbd164d 33993+ uint64_t ul;
7f207e10
AM
33994+};
33995+
33996+enum {
33997+ AufsCtlRduV_SZ,
33998+ AufsCtlRduV_End
33999+};
34000+
34001+struct aufs_rdu {
34002+ /* input */
34003+ union {
9dbd164d
AM
34004+ uint64_t sz; /* AuCtl_RDU */
34005+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
34006+ };
34007+ union au_rdu_ent_ul ent;
9dbd164d 34008+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
34009+
34010+ /* input/output */
9dbd164d 34011+ uint32_t blk;
7f207e10
AM
34012+
34013+ /* output */
34014+ union au_rdu_ent_ul tail;
34015+ /* number of entries which were added in a single call */
9dbd164d
AM
34016+ uint64_t rent;
34017+ uint8_t full;
34018+ uint8_t shwh;
7f207e10
AM
34019+
34020+ struct au_rdu_cookie cookie;
34021+} __aligned(8);
34022+
1e00d052
AM
34023+/* ---------------------------------------------------------------------- */
34024+
34025+struct aufs_wbr_fd {
9dbd164d
AM
34026+ uint32_t oflags;
34027+ int16_t brid;
1e00d052
AM
34028+} __aligned(8);
34029+
34030+/* ---------------------------------------------------------------------- */
34031+
027c5e7a 34032+struct aufs_ibusy {
9dbd164d
AM
34033+ uint64_t ino, h_ino;
34034+ int16_t bindex;
027c5e7a
AM
34035+} __aligned(8);
34036+
1e00d052
AM
34037+/* ---------------------------------------------------------------------- */
34038+
392086de
AM
34039+/* error code for move-down */
34040+/* the actual message strings are implemented in aufs-util.git */
34041+enum {
34042+ EAU_MVDOWN_OPAQUE = 1,
34043+ EAU_MVDOWN_WHITEOUT,
34044+ EAU_MVDOWN_UPPER,
34045+ EAU_MVDOWN_BOTTOM,
34046+ EAU_MVDOWN_NOUPPER,
34047+ EAU_MVDOWN_NOLOWERBR,
34048+ EAU_Last
34049+};
34050+
c2b27bf2 34051+/* flags for move-down */
392086de
AM
34052+#define AUFS_MVDOWN_DMSG 1
34053+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
34054+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
34055+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
34056+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
34057+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
34058+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
34059+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
34060+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
34061+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
34062+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
34063+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
34064+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 34065+
076b876e 34066+/* index for move-down */
392086de
AM
34067+enum {
34068+ AUFS_MVDOWN_UPPER,
34069+ AUFS_MVDOWN_LOWER,
34070+ AUFS_MVDOWN_NARRAY
34071+};
34072+
076b876e
AM
34073+/*
34074+ * additional info of move-down
34075+ * number of free blocks and inodes.
34076+ * subset of struct kstatfs, but smaller and always 64bit.
34077+ */
34078+struct aufs_stfs {
34079+ uint64_t f_blocks;
34080+ uint64_t f_bavail;
34081+ uint64_t f_files;
34082+ uint64_t f_ffree;
34083+};
34084+
34085+struct aufs_stbr {
34086+ int16_t brid; /* optional input */
34087+ int16_t bindex; /* output */
34088+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
34089+} __aligned(8);
34090+
c2b27bf2 34091+struct aufs_mvdown {
076b876e
AM
34092+ uint32_t flags; /* input/output */
34093+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
34094+ int8_t au_errno; /* output */
34095+} __aligned(8);
34096+
34097+/* ---------------------------------------------------------------------- */
34098+
34099+union aufs_brinfo {
34100+ /* PATH_MAX may differ between kernel-space and user-space */
34101+ char _spacer[4096];
392086de 34102+ struct {
076b876e
AM
34103+ int16_t id;
34104+ int perm;
34105+ char path[0];
34106+ };
c2b27bf2
AM
34107+} __aligned(8);
34108+
34109+/* ---------------------------------------------------------------------- */
34110+
7f207e10
AM
34111+#define AuCtlType 'A'
34112+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
34113+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
34114+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
34115+ struct aufs_wbr_fd)
027c5e7a 34116+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
34117+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
34118+ struct aufs_mvdown)
076b876e
AM
34119+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
34120+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
34121+
34122+#endif /* __AUFS_TYPE_H__ */
076b876e 34123aufs3.16 loopback patch
93a1a2a2
JR
34124
34125diff --git a/drivers/block/loop.c b/drivers/block/loop.c
076b876e 34126index 30efd68..77b31b4 100644
93a1a2a2
JR
34127--- a/drivers/block/loop.c
34128+++ b/drivers/block/loop.c
34129@@ -514,7 +514,7 @@ out:
34130 }
34131
34132 struct switch_request {
34133- struct file *file;
34134+ struct file *file, *virt_file;
34135 struct completion wait;
34136 };
34137
34138@@ -576,7 +576,8 @@ static int loop_thread(void *data)
34139 * First it needs to flush existing IO, it does this by sending a magic
34140 * BIO down the pipe. The completion of this BIO does the actual switch.
34141 */
34142-static int loop_switch(struct loop_device *lo, struct file *file)
34143+static int loop_switch(struct loop_device *lo, struct file *file,
34144+ struct file *virt_file)
34145 {
34146 struct switch_request w;
34147 struct bio *bio = bio_alloc(GFP_KERNEL, 0);
34148@@ -584,6 +585,7 @@ static int loop_switch(struct loop_device *lo, struct file *file)
34149 return -ENOMEM;
34150 init_completion(&w.wait);
34151 w.file = file;
34152+ w.virt_file = virt_file;
34153 bio->bi_private = &w;
34154 bio->bi_bdev = NULL;
34155 loop_make_request(lo->lo_queue, bio);
34156@@ -600,7 +602,7 @@ static int loop_flush(struct loop_device *lo)
34157 if (!lo->lo_thread)
34158 return 0;
34159
34160- return loop_switch(lo, NULL);
34161+ return loop_switch(lo, NULL, NULL);
34162 }
34163
34164 /*
34165@@ -619,6 +621,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
34166 mapping = file->f_mapping;
34167 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
34168 lo->lo_backing_file = file;
34169+ lo->lo_backing_virt_file = p->virt_file;
34170 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
34171 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
34172 lo->old_gfp_mask = mapping_gfp_mask(mapping);
34173@@ -627,6 +630,13 @@ out:
34174 complete(&p->wait);
34175 }
34176
34177+static struct file *loop_real_file(struct file *file)
34178+{
34179+ struct file *f = NULL;
34180+ if (file->f_dentry->d_sb->s_op->real_loop)
34181+ f = file->f_dentry->d_sb->s_op->real_loop(file);
34182+ return f;
34183+}
34184
34185 /*
34186 * loop_change_fd switched the backing store of a loopback device to
34187@@ -640,6 +650,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
34188 unsigned int arg)
34189 {
34190 struct file *file, *old_file;
34191+ struct file *f, *virt_file = NULL, *old_virt_file;
34192 struct inode *inode;
34193 int error;
34194
34195@@ -656,9 +667,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
34196 file = fget(arg);
34197 if (!file)
34198 goto out;
34199+ f = loop_real_file(file);
34200+ if (f) {
34201+ virt_file = file;
34202+ file = f;
34203+ get_file(file);
34204+ }
34205
34206 inode = file->f_mapping->host;
34207 old_file = lo->lo_backing_file;
34208+ old_virt_file = lo->lo_backing_virt_file;
34209
34210 error = -EINVAL;
34211
34212@@ -670,17 +688,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
34213 goto out_putf;
34214
34215 /* and ... switch */
34216- error = loop_switch(lo, file);
34217+ error = loop_switch(lo, file, virt_file);
34218 if (error)
34219 goto out_putf;
34220
34221 fput(old_file);
34222+ if (old_virt_file)
34223+ fput(old_virt_file);
34224 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
34225 ioctl_by_bdev(bdev, BLKRRPART, 0);
34226 return 0;
34227
34228 out_putf:
34229 fput(file);
34230+ if (virt_file)
34231+ fput(virt_file);
34232 out:
34233 return error;
34234 }
34235@@ -841,7 +863,7 @@ static void loop_config_discard(struct loop_device *lo)
34236 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
34237 struct block_device *bdev, unsigned int arg)
34238 {
34239- struct file *file, *f;
34240+ struct file *file, *f, *virt_file = NULL;
34241 struct inode *inode;
34242 struct address_space *mapping;
34243 unsigned lo_blocksize;
34244@@ -856,6 +878,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
34245 file = fget(arg);
34246 if (!file)
34247 goto out;
34248+ f = loop_real_file(file);
34249+ if (f) {
34250+ virt_file = file;
34251+ file = f;
34252+ get_file(file);
34253+ }
34254
34255 error = -EBUSY;
34256 if (lo->lo_state != Lo_unbound)
34257@@ -904,6 +932,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
34258 lo->lo_device = bdev;
34259 lo->lo_flags = lo_flags;
34260 lo->lo_backing_file = file;
34261+ lo->lo_backing_virt_file = virt_file;
34262 lo->transfer = transfer_none;
34263 lo->ioctl = NULL;
34264 lo->lo_sizelimit = 0;
34265@@ -948,6 +977,7 @@ out_clr:
34266 lo->lo_thread = NULL;
34267 lo->lo_device = NULL;
34268 lo->lo_backing_file = NULL;
34269+ lo->lo_backing_virt_file = NULL;
34270 lo->lo_flags = 0;
34271 set_capacity(lo->lo_disk, 0);
34272 invalidate_bdev(bdev);
34273@@ -957,6 +987,8 @@ out_clr:
34274 lo->lo_state = Lo_unbound;
34275 out_putf:
34276 fput(file);
34277+ if (virt_file)
34278+ fput(virt_file);
34279 out:
34280 /* This is safe: open() is still holding a reference. */
34281 module_put(THIS_MODULE);
34282@@ -1003,6 +1035,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
34283 static int loop_clr_fd(struct loop_device *lo)
34284 {
34285 struct file *filp = lo->lo_backing_file;
34286+ struct file *virt_filp = lo->lo_backing_virt_file;
34287 gfp_t gfp = lo->old_gfp_mask;
34288 struct block_device *bdev = lo->lo_device;
34289
34290@@ -1036,6 +1069,7 @@ static int loop_clr_fd(struct loop_device *lo)
34291
34292 spin_lock_irq(&lo->lo_lock);
34293 lo->lo_backing_file = NULL;
34294+ lo->lo_backing_virt_file = NULL;
34295 spin_unlock_irq(&lo->lo_lock);
34296
34297 loop_release_xfer(lo);
34298@@ -1078,6 +1112,8 @@ static int loop_clr_fd(struct loop_device *lo)
34299 * bd_mutex which is usually taken before lo_ctl_mutex.
34300 */
34301 fput(filp);
34302+ if (virt_filp)
34303+ fput(virt_filp);
34304 return 0;
34305 }
34306
34307diff --git a/drivers/block/loop.h b/drivers/block/loop.h
34308index 90df5d6..cb91822 100644
34309--- a/drivers/block/loop.h
34310+++ b/drivers/block/loop.h
34311@@ -44,7 +44,7 @@ struct loop_device {
34312 int (*ioctl)(struct loop_device *, int cmd,
34313 unsigned long arg);
34314
34315- struct file * lo_backing_file;
34316+ struct file * lo_backing_file, *lo_backing_virt_file;
34317 struct block_device *lo_device;
34318 unsigned lo_blocksize;
34319 void *key_data;
34320diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
076b876e 34321index 24ced51..69fa5cc 100644
93a1a2a2
JR
34322--- a/fs/aufs/f_op.c
34323+++ b/fs/aufs/f_op.c
076b876e 34324@@ -367,7 +367,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
93a1a2a2
JR
34325 err = -EINVAL;
34326 h_file = au_hf_top(file);
34327 get_file(h_file);
34328- if (au_test_loopback_kthread()) {
34329+ if (0 && au_test_loopback_kthread()) {
34330 au_warn_loopback(h_file->f_dentry->d_sb);
34331 if (file->f_mapping != h_file->f_mapping) {
34332 file->f_mapping = h_file->f_mapping;
34333diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
34334index 3b03b52..4ab749d 100644
34335--- a/fs/aufs/loop.c
34336+++ b/fs/aufs/loop.c
34337@@ -130,3 +130,19 @@ void au_loopback_fin(void)
34338 symbol_put(loop_backing_file);
34339 kfree(au_warn_loopback_array);
34340 }
34341+
34342+/* ---------------------------------------------------------------------- */
34343+
34344+/* support the loopback block device insude aufs */
34345+
34346+struct file *aufs_real_loop(struct file *file)
34347+{
34348+ struct file *f;
34349+
34350+ BUG_ON(!au_test_aufs(file->f_dentry->d_sb));
34351+ fi_read_lock(file);
34352+ f = au_hf_top(file);
34353+ fi_read_unlock(file);
34354+ AuDebugOn(!f);
34355+ return f;
34356+}
34357diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
34358index da8b756..28cb7ea 100644
34359--- a/fs/aufs/loop.h
34360+++ b/fs/aufs/loop.h
34361@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
34362
34363 int au_loopback_init(void);
34364 void au_loopback_fin(void);
34365+
34366+struct file *aufs_real_loop(struct file *file);
34367 #else
34368+AuStub(struct file *, loop_backing_file, return NULL)
34369+
34370 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
34371 struct dentry *h_adding)
34372 AuStubInt0(au_test_loopback_kthread, void)
34373@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
34374
34375 AuStubInt0(au_loopback_init, void)
34376 AuStubVoid(au_loopback_fin, void)
34377+
34378+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
34379 #endif /* BLK_DEV_LOOP */
34380
34381 #endif /* __KERNEL__ */
34382diff --git a/fs/aufs/super.c b/fs/aufs/super.c
076b876e 34383index 45146eb..fccd7d6 100644
93a1a2a2
JR
34384--- a/fs/aufs/super.c
34385+++ b/fs/aufs/super.c
076b876e 34386@@ -809,7 +809,10 @@ static const struct super_operations aufs_sop = {
93a1a2a2
JR
34387 .statfs = aufs_statfs,
34388 .put_super = aufs_put_super,
34389 .sync_fs = aufs_sync_fs,
34390- .remount_fs = aufs_remount_fs
34391+ .remount_fs = aufs_remount_fs,
34392+#ifdef CONFIG_AUFS_BDEV_LOOP
34393+ .real_loop = aufs_real_loop
34394+#endif
34395 };
34396
34397 /* ---------------------------------------------------------------------- */
34398diff --git a/include/linux/fs.h b/include/linux/fs.h
076b876e 34399index 2f32b35..f94f0e6 100644
93a1a2a2
JR
34400--- a/include/linux/fs.h
34401+++ b/include/linux/fs.h
076b876e 34402@@ -1561,6 +1561,10 @@ struct super_operations {
93a1a2a2
JR
34403 int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
34404 long (*nr_cached_objects)(struct super_block *, int);
34405 long (*free_cached_objects)(struct super_block *, long, int);
34406+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
34407+ /* and aufs */
34408+ struct file *(*real_loop)(struct file *);
34409+#endif
34410 };
34411
34412 /*
This page took 5.939956 seconds and 4 git commands to generate.