]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- add patch for btrfs
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
2000de60 1aufs3.19 kbuild patch
7f207e10
AM
2
3diff --git a/fs/Kconfig b/fs/Kconfig
c1595e42 4index 664991a..1481093 100644
7f207e10
AM
5--- a/fs/Kconfig
6+++ b/fs/Kconfig
c1595e42 7@@ -210,6 +210,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
2000de60 16index bedff48..9e7c0b7 100644
7f207e10
AM
17--- a/fs/Makefile
18+++ b/fs/Makefile
c1595e42 19@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules
7f207e10 20 obj-$(CONFIG_CEPH_FS) += ceph/
bf0370f2 21 obj-$(CONFIG_PSTORE) += pstore/
c06a8ce3 22 obj-$(CONFIG_EFIVAR_FS) += efivarfs/
86dc4139 23+obj-$(CONFIG_AUFS_FS) += aufs/
c06a8ce3 24diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
2000de60 25index 00b10002..f4a389c 100644
c06a8ce3
AM
26--- a/include/uapi/linux/Kbuild
27+++ b/include/uapi/linux/Kbuild
2000de60 28@@ -57,6 +57,7 @@ header-y += atmsvc.h
03673fb0
JR
29 header-y += atm_tcp.h
30 header-y += atm_zatm.h
c06a8ce3
AM
31 header-y += audit.h
32+header-y += aufs_type.h
c06a8ce3 33 header-y += auto_fs4.h
03673fb0 34 header-y += auto_fs.h
c06a8ce3 35 header-y += auxvec.h
2000de60 36aufs3.19 base patch
7f207e10 37
c1595e42 38diff --git a/MAINTAINERS b/MAINTAINERS
2000de60 39index d66a97d..1c113a4 100644
c1595e42
JR
40--- a/MAINTAINERS
41+++ b/MAINTAINERS
2000de60 42@@ -1833,6 +1833,20 @@ F: include/linux/audit.h
c1595e42
JR
43 F: include/uapi/linux/audit.h
44 F: kernel/audit*
45
46+AUFS (advanced multi layered unification filesystem) FILESYSTEM
47+M: "J. R. Okajima" <hooanon05g@gmail.com>
48+L: linux-unionfs@vger.kernel.org
49+L: aufs-users@lists.sourceforge.net (members only)
50+W: http://aufs.sourceforge.net
51+T: git://git.code.sf.net/p/aufs/aufs3-linux
52+T: git://github.com/sfjro/aufs3-linux.git
53+S: Supported
54+F: Documentation/filesystems/aufs/
55+F: Documentation/ABI/testing/debugfs-aufs
56+F: Documentation/ABI/testing/sysfs-aufs
57+F: fs/aufs/
58+F: include/uapi/linux/aufs_type.h
59+
60 AUXILIARY DISPLAY DRIVERS
61 M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
62 W: http://miguelojeda.es/auxdisplay.htm
392086de 63diff --git a/drivers/block/loop.c b/drivers/block/loop.c
076b876e 64index 6cb1beb..30efd68 100644
392086de
AM
65--- a/drivers/block/loop.c
66+++ b/drivers/block/loop.c
fb47a38f 67@@ -692,6 +692,24 @@ static inline int is_loop_device(struct file *file)
392086de
AM
68 return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
69 }
70
71+/*
72+ * for AUFS
73+ * no get/put for file.
74+ */
75+struct file *loop_backing_file(struct super_block *sb)
76+{
77+ struct file *ret;
78+ struct loop_device *l;
79+
80+ ret = NULL;
81+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
82+ l = sb->s_bdev->bd_disk->private_data;
83+ ret = l->lo_backing_file;
84+ }
85+ return ret;
86+}
87+EXPORT_SYMBOL(loop_backing_file);
88+
89 /* loop sysfs attributes */
90
91 static ssize_t loop_attr_show(struct device *dev, char *page,
c1595e42 92diff --git a/fs/dcache.c b/fs/dcache.c
2000de60 93index e368d4f..eaed72c 100644
c1595e42
JR
94--- a/fs/dcache.c
95+++ b/fs/dcache.c
96@@ -1019,7 +1019,7 @@ enum d_walk_ret {
97 *
98 * The @enter() and @finish() callbacks are called with d_lock held.
99 */
100-static void d_walk(struct dentry *parent, void *data,
101+void d_walk(struct dentry *parent, void *data,
102 enum d_walk_ret (*enter)(void *, struct dentry *),
103 void (*finish)(void *))
104 {
0c3ec466 105diff --git a/fs/inode.c b/fs/inode.c
2000de60 106index aa149e7..98d87de 100644
0c3ec466
AM
107--- a/fs/inode.c
108+++ b/fs/inode.c
2000de60 109@@ -1499,7 +1499,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
0c3ec466
AM
110 * This does the actual work of updating an inodes time or version. Must have
111 * had called mnt_want_write() before calling this.
112 */
113-static int update_time(struct inode *inode, struct timespec *time, int flags)
114+int update_time(struct inode *inode, struct timespec *time, int flags)
115 {
116 if (inode->i_op->update_time)
117 return inode->i_op->update_time(inode, time, flags);
7f207e10 118diff --git a/fs/splice.c b/fs/splice.c
c1595e42 119index 75c6058..619359a 100644
7f207e10
AM
120--- a/fs/splice.c
121+++ b/fs/splice.c
076b876e 122@@ -1114,8 +1114,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
7f207e10
AM
123 /*
124 * Attempt to initiate a splice from pipe to file.
125 */
126-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
127- loff_t *ppos, size_t len, unsigned int flags)
128+long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
129+ loff_t *ppos, size_t len, unsigned int flags)
130 {
131 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
132 loff_t *, size_t, unsigned int);
076b876e 133@@ -1131,9 +1131,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7f207e10
AM
134 /*
135 * Attempt to initiate a splice from a file to a pipe.
136 */
137-static long do_splice_to(struct file *in, loff_t *ppos,
138- struct pipe_inode_info *pipe, size_t len,
139- unsigned int flags)
140+long do_splice_to(struct file *in, loff_t *ppos,
141+ struct pipe_inode_info *pipe, size_t len,
142+ unsigned int flags)
143 {
144 ssize_t (*splice_read)(struct file *, loff_t *,
145 struct pipe_inode_info *, size_t, unsigned int);
0c3ec466 146diff --git a/include/linux/fs.h b/include/linux/fs.h
2000de60 147index 42efe13..f634198 100644
0c3ec466
AM
148--- a/include/linux/fs.h
149+++ b/include/linux/fs.h
2000de60 150@@ -2690,6 +2690,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *);
0c3ec466
AM
151 extern int inode_newsize_ok(const struct inode *, loff_t offset);
152 extern void setattr_copy(struct inode *inode, const struct iattr *attr);
153
154+extern int update_time(struct inode *, struct timespec *, int);
155 extern int file_update_time(struct file *file);
156
157 extern int generic_show_options(struct seq_file *m, struct dentry *root);
1e00d052 158diff --git a/include/linux/splice.h b/include/linux/splice.h
076b876e 159index da2751d..2e0fca6 100644
1e00d052
AM
160--- a/include/linux/splice.h
161+++ b/include/linux/splice.h
076b876e 162@@ -83,4 +83,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
4b3da204
AM
163 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
164
165 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
1e00d052
AM
166+
167+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
168+ loff_t *ppos, size_t len, unsigned int flags);
169+extern long do_splice_to(struct file *in, loff_t *ppos,
170+ struct pipe_inode_info *pipe, size_t len,
171+ unsigned int flags);
172 #endif
2000de60 173aufs3.19 mmap patch
fb47a38f
JR
174
175diff --git a/fs/buffer.c b/fs/buffer.c
c1595e42 176index 20805db..363569f 100644
fb47a38f
JR
177--- a/fs/buffer.c
178+++ b/fs/buffer.c
c1595e42 179@@ -2450,7 +2450,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
fb47a38f
JR
180 * Update file times before taking page lock. We may end up failing the
181 * fault so this update may be superfluous but who really cares...
182 */
183- file_update_time(vma->vm_file);
184+ vma_file_update_time(vma);
185
186 ret = __block_page_mkwrite(vma, vmf, get_block);
187 sb_end_pagefault(sb);
c1595e42 188diff --git a/fs/proc/base.c b/fs/proc/base.c
2000de60 189index 3f3d7ae..426bcc7 100644
c1595e42
JR
190--- a/fs/proc/base.c
191+++ b/fs/proc/base.c
192@@ -1735,7 +1735,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
193 down_read(&mm->mmap_sem);
194 vma = find_exact_vma(mm, vm_start, vm_end);
195 if (vma && vma->vm_file) {
196- *path = vma->vm_file->f_path;
197+ *path = vma_pr_or_file(vma)->f_path;
198 path_get(path);
199 rc = 0;
200 }
fb47a38f 201diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
076b876e 202index d4a3574..1397181 100644
fb47a38f
JR
203--- a/fs/proc/nommu.c
204+++ b/fs/proc/nommu.c
076b876e 205@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
fb47a38f
JR
206 file = region->vm_file;
207
208 if (file) {
209- struct inode *inode = file_inode(region->vm_file);
210+ struct inode *inode;
076b876e 211+
fb47a38f
JR
212+ file = vmr_pr_or_file(region);
213+ inode = file_inode(file);
214 dev = inode->i_sb->s_dev;
215 ino = inode->i_ino;
216 }
217diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
2000de60 218index 246eae8..dfd0875 100644
fb47a38f
JR
219--- a/fs/proc/task_mmu.c
220+++ b/fs/proc/task_mmu.c
c1595e42 221@@ -276,7 +276,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
fb47a38f
JR
222 const char *name = NULL;
223
224 if (file) {
225- struct inode *inode = file_inode(vma->vm_file);
226+ struct inode *inode;
076b876e 227+
fb47a38f
JR
228+ file = vma_pr_or_file(vma);
229+ inode = file_inode(file);
230 dev = inode->i_sb->s_dev;
231 ino = inode->i_ino;
232 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
2000de60 233@@ -1475,7 +1478,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
076b876e
AM
234 struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
235 struct vm_area_struct *vma = v;
236 struct numa_maps *md = &numa_priv->md;
237- struct file *file = vma->vm_file;
238+ struct file *file = vma_pr_or_file(vma);
076b876e
AM
239 struct mm_struct *mm = vma->vm_mm;
240 struct mm_walk walk = {};
e26ee53e 241 struct mempolicy *pol;
fb47a38f 242diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
c1595e42 243index 599ec2e..de6cd6e 100644
fb47a38f
JR
244--- a/fs/proc/task_nommu.c
245+++ b/fs/proc/task_nommu.c
c1595e42 246@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
fb47a38f
JR
247 file = vma->vm_file;
248
249 if (file) {
250- struct inode *inode = file_inode(vma->vm_file);
251+ struct inode *inode;
076b876e 252+
fb47a38f
JR
253+ file = vma_pr_or_file(file);
254+ inode = file_inode(file);
255 dev = inode->i_sb->s_dev;
256 ino = inode->i_ino;
257 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
258diff --git a/include/linux/mm.h b/include/linux/mm.h
2000de60 259index dd5ea30..445d798 100644
fb47a38f
JR
260--- a/include/linux/mm.h
261+++ b/include/linux/mm.h
2000de60 262@@ -1224,6 +1224,28 @@ static inline int fixup_user_fault(struct task_struct *tsk,
fb47a38f
JR
263 }
264 #endif
265
076b876e
AM
266+#ifdef CONFIG_MMU
267+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
268+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
269+ int);
270+extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
271+extern void vma_do_fput(struct vm_area_struct *, const char[], int);
fb47a38f 272+
fb47a38f
JR
273+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
274+ __LINE__)
275+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
276+ __LINE__)
277+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
278+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
076b876e
AM
279+#else
280+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
281+extern void vmr_do_fput(struct vm_region *, const char[], int);
282+
283+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
284+ __LINE__)
285+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
286+#endif /* CONFIG_MMU */
fb47a38f
JR
287+
288 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
289 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
290 void *buf, int len, int write);
291diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
2000de60 292index 6d34aa2..f13dd51 100644
fb47a38f
JR
293--- a/include/linux/mm_types.h
294+++ b/include/linux/mm_types.h
2000de60 295@@ -233,6 +233,7 @@ struct vm_region {
fb47a38f
JR
296 unsigned long vm_top; /* region allocated to here */
297 unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
298 struct file *vm_file; /* the backing file or NULL */
299+ struct file *vm_prfile; /* the virtual backing file or NULL */
300
301 int vm_usage; /* region usage count (access under nommu_region_sem) */
302 bool vm_icache_flushed : 1; /* true if the icache has been flushed for
2000de60 303@@ -301,6 +302,7 @@ struct vm_area_struct {
fb47a38f
JR
304 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
305 units, *not* PAGE_CACHE_SIZE */
306 struct file * vm_file; /* File we map to (can be NULL). */
307+ struct file *vm_prfile; /* shadow of vm_file */
308 void * vm_private_data; /* was vm_pte (shared mem) */
309
310 #ifndef CONFIG_MMU
311diff --git a/kernel/fork.c b/kernel/fork.c
2000de60 312index 4dc2dda..5984c61 100644
fb47a38f
JR
313--- a/kernel/fork.c
314+++ b/kernel/fork.c
c1595e42 315@@ -430,7 +430,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
fb47a38f
JR
316 struct inode *inode = file_inode(file);
317 struct address_space *mapping = file->f_mapping;
318
319- get_file(file);
320+ vma_get_file(tmp);
321 if (tmp->vm_flags & VM_DENYWRITE)
322 atomic_dec(&inode->i_writecount);
2000de60 323 i_mmap_lock_write(mapping);
076b876e 324diff --git a/mm/Makefile b/mm/Makefile
2000de60 325index 4bf586e..59bd276 100644
076b876e
AM
326--- a/mm/Makefile
327+++ b/mm/Makefile
c1595e42 328@@ -18,7 +18,7 @@ obj-y := filemap.o mempool.o oom_kill.o \
076b876e 329 mm_init.o mmu_context.o percpu.o slab_common.o \
c1595e42 330 compaction.o vmacache.o \
076b876e 331 interval_tree.o list_lru.o workingset.o \
e26ee53e 332- iov_iter.o debug.o $(mmu-y)
c1595e42 333+ iov_iter.o prfile.o debug.o $(mmu-y)
076b876e
AM
334
335 obj-y += init-mm.o
336
fb47a38f 337diff --git a/mm/filemap.c b/mm/filemap.c
2000de60 338index 673e458..a623932 100644
fb47a38f
JR
339--- a/mm/filemap.c
340+++ b/mm/filemap.c
2000de60 341@@ -2063,7 +2063,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
fb47a38f
JR
342 int ret = VM_FAULT_LOCKED;
343
344 sb_start_pagefault(inode->i_sb);
345- file_update_time(vma->vm_file);
346+ vma_file_update_time(vma);
347 lock_page(page);
348 if (page->mapping != inode->i_mapping) {
349 unlock_page(page);
350diff --git a/mm/fremap.c b/mm/fremap.c
2000de60 351index 2805d71..1b011b0 100644
fb47a38f
JR
352--- a/mm/fremap.c
353+++ b/mm/fremap.c
076b876e 354@@ -224,16 +224,28 @@ get_write_lock:
38d290e6
JR
355 */
356 if (mapping_cap_account_dirty(mapping)) {
357 unsigned long addr;
358- struct file *file = get_file(vma->vm_file);
359+ struct file *file = vma->vm_file,
360+ *prfile = vma->vm_prfile;
361+
fb47a38f
JR
362 /* mmap_region may free vma; grab the info now */
363 vm_flags = vma->vm_flags;
364
365+ vma_get_file(vma);
366 addr = mmap_region(file, start, size, vm_flags, pgoff);
38d290e6 367- fput(file);
fb47a38f 368+ vma_fput(vma);
fb47a38f
JR
369 if (IS_ERR_VALUE(addr)) {
370 err = addr;
38d290e6
JR
371 } else {
372 BUG_ON(addr != start);
373+ if (prfile) {
374+ struct vm_area_struct *new_vma;
076b876e 375+
38d290e6
JR
376+ new_vma = find_vma(mm, addr);
377+ if (!new_vma->vm_prfile)
378+ new_vma->vm_prfile = prfile;
379+ if (new_vma != vma)
380+ get_file(prfile);
381+ }
382 err = 0;
383 }
384 goto out_freed;
fb47a38f 385diff --git a/mm/madvise.c b/mm/madvise.c
2000de60 386index a271adc..29a932f 100644
fb47a38f
JR
387--- a/mm/madvise.c
388+++ b/mm/madvise.c
c1595e42 389@@ -324,12 +324,12 @@ static long madvise_remove(struct vm_area_struct *vma,
fb47a38f
JR
390 * vma's reference to the file) can go away as soon as we drop
391 * mmap_sem.
392 */
393- get_file(f);
394+ vma_get_file(vma);
395 up_read(&current->mm->mmap_sem);
03673fb0 396 error = vfs_fallocate(f,
fb47a38f
JR
397 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
398 offset, end - start);
399- fput(f);
400+ vma_fput(vma);
401 down_read(&current->mm->mmap_sem);
402 return error;
403 }
404diff --git a/mm/memory.c b/mm/memory.c
2000de60 405index 2c3536c..444bb1d 100644
fb47a38f
JR
406--- a/mm/memory.c
407+++ b/mm/memory.c
2000de60
JR
408@@ -2157,7 +2157,7 @@ reuse:
409
fb47a38f
JR
410 /* file_update_time outside page_lock */
411 if (vma->vm_file)
412- file_update_time(vma->vm_file);
413+ vma_file_update_time(vma);
414 }
415 put_page(dirty_page);
416 if (page_mkwrite) {
fb47a38f 417diff --git a/mm/mmap.c b/mm/mmap.c
2000de60 418index 7f684d5..ffa1b91 100644
fb47a38f
JR
419--- a/mm/mmap.c
420+++ b/mm/mmap.c
c1595e42 421@@ -277,7 +277,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
fb47a38f
JR
422 if (vma->vm_ops && vma->vm_ops->close)
423 vma->vm_ops->close(vma);
424 if (vma->vm_file)
425- fput(vma->vm_file);
426+ vma_fput(vma);
427 mpol_put(vma_policy(vma));
428 kmem_cache_free(vm_area_cachep, vma);
429 return next;
2000de60 430@@ -897,7 +897,7 @@ again: remove_next = 1 + (end > next->vm_end);
fb47a38f
JR
431 if (remove_next) {
432 if (file) {
433 uprobe_munmap(next, next->vm_start, next->vm_end);
434- fput(file);
435+ vma_fput(vma);
436 }
437 if (next->anon_vma)
438 anon_vma_merge(vma, next);
2000de60 439@@ -1682,8 +1682,8 @@ out:
35939ee7
JR
440 return addr;
441
fb47a38f 442 unmap_and_free_vma:
fb47a38f
JR
443+ vma_fput(vma);
444 vma->vm_file = NULL;
445- fput(file);
446
447 /* Undo any partial mapping done by a device driver. */
448 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
2000de60 449@@ -2484,7 +2484,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
450 goto out_free_mpol;
451
452 if (new->vm_file)
453- get_file(new->vm_file);
454+ vma_get_file(new);
455
456 if (new->vm_ops && new->vm_ops->open)
457 new->vm_ops->open(new);
2000de60 458@@ -2503,7 +2503,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
fb47a38f
JR
459 if (new->vm_ops && new->vm_ops->close)
460 new->vm_ops->close(new);
461 if (new->vm_file)
462- fput(new->vm_file);
463+ vma_fput(new);
464 unlink_anon_vmas(new);
465 out_free_mpol:
466 mpol_put(vma_policy(new));
2000de60 467@@ -2895,7 +2895,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
fb47a38f
JR
468 if (anon_vma_clone(new_vma, vma))
469 goto out_free_mempol;
470 if (new_vma->vm_file)
471- get_file(new_vma->vm_file);
472+ vma_get_file(new_vma);
473 if (new_vma->vm_ops && new_vma->vm_ops->open)
474 new_vma->vm_ops->open(new_vma);
475 vma_link(mm, new_vma, prev, rb_link, rb_parent);
476diff --git a/mm/msync.c b/mm/msync.c
076b876e 477index 992a167..ce1915b 100644
fb47a38f
JR
478--- a/mm/msync.c
479+++ b/mm/msync.c
076b876e 480@@ -84,13 +84,13 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
fb47a38f
JR
481 start = vma->vm_end;
482 if ((flags & MS_SYNC) && file &&
483 (vma->vm_flags & VM_SHARED)) {
484- get_file(file);
485+ vma_get_file(vma);
486 up_read(&mm->mmap_sem);
076b876e
AM
487 if (vma->vm_flags & VM_NONLINEAR)
488 error = vfs_fsync(file, 1);
489 else
490 error = vfs_fsync_range(file, fstart, fend, 1);
fb47a38f
JR
491- fput(file);
492+ vma_fput(vma);
493 if (error || start >= end)
494 goto out;
495 down_read(&mm->mmap_sem);
496diff --git a/mm/nommu.c b/mm/nommu.c
2000de60 497index 28bd8c4..3c0ace2 100644
fb47a38f
JR
498--- a/mm/nommu.c
499+++ b/mm/nommu.c
2000de60 500@@ -659,7 +659,7 @@ static void __put_nommu_region(struct vm_region *region)
fb47a38f
JR
501 up_write(&nommu_region_sem);
502
503 if (region->vm_file)
504- fput(region->vm_file);
505+ vmr_fput(region);
506
507 /* IO memory and memory shared directly out of the pagecache
508 * from ramfs/tmpfs mustn't be released here */
2000de60 509@@ -824,7 +824,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
fb47a38f
JR
510 if (vma->vm_ops && vma->vm_ops->close)
511 vma->vm_ops->close(vma);
512 if (vma->vm_file)
513- fput(vma->vm_file);
514+ vma_fput(vma);
515 put_nommu_region(vma->vm_region);
516 kmem_cache_free(vm_area_cachep, vma);
517 }
2000de60 518@@ -1375,7 +1375,7 @@ unsigned long do_mmap_pgoff(struct file *file,
fb47a38f
JR
519 goto error_just_free;
520 }
521 }
522- fput(region->vm_file);
523+ vmr_fput(region);
524 kmem_cache_free(vm_region_jar, region);
525 region = pregion;
526 result = start;
2000de60 527@@ -1451,10 +1451,10 @@ error_just_free:
fb47a38f
JR
528 up_write(&nommu_region_sem);
529 error:
530 if (region->vm_file)
531- fput(region->vm_file);
532+ vmr_fput(region);
533 kmem_cache_free(vm_region_jar, region);
534 if (vma->vm_file)
535- fput(vma->vm_file);
536+ vma_fput(vma);
537 kmem_cache_free(vm_area_cachep, vma);
538 kleave(" = %d", ret);
539 return ret;
076b876e
AM
540diff --git a/mm/prfile.c b/mm/prfile.c
541new file mode 100644
542index 0000000..fc708d2
543--- /dev/null
544+++ b/mm/prfile.c
545@@ -0,0 +1,86 @@
546+/*
547+ * Mainly for aufs which mmap(2) diffrent file and wants to print different path
548+ * in /proc/PID/maps.
549+ * Call these functions via macros defined in linux/mm.h.
550+ *
551+ * See Documentation/filesystems/aufs/design/06mmap.txt
552+ *
553+ * Copyright (c) 2014 Junjro R. Okajima
554+ * Copyright (c) 2014 Ian Campbell
555+ */
556+
557+#include <linux/mm.h>
558+#include <linux/file.h>
559+#include <linux/fs.h>
560+
561+/* #define PRFILE_TRACE */
562+static inline void prfile_trace(struct file *f, struct file *pr,
563+ const char func[], int line, const char func2[])
564+{
565+#ifdef PRFILE_TRACE
566+ if (pr)
567+ pr_info("%s:%d: %s, %p\n", func, line, func2,
568+ f ? (char *)f->f_dentry->d_name.name : "(null)");
569+#endif
570+}
571+
572+#ifdef CONFIG_MMU
573+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
574+ int line)
575+{
576+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
577+
578+ prfile_trace(f, pr, func, line, __func__);
579+ file_update_time(f);
580+ if (f && pr)
581+ file_update_time(pr);
582+}
583+
584+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
585+ int line)
586+{
587+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
588+
589+ prfile_trace(f, pr, func, line, __func__);
590+ return (f && pr) ? pr : f;
591+}
592+
593+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
594+{
595+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
596+
597+ prfile_trace(f, pr, func, line, __func__);
598+ get_file(f);
599+ if (f && pr)
600+ get_file(pr);
601+}
602+
603+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
604+{
605+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
606+
607+ prfile_trace(f, pr, func, line, __func__);
608+ fput(f);
609+ if (f && pr)
610+ fput(pr);
611+}
612+#else
613+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
614+ int line)
615+{
616+ struct file *f = region->vm_file, *pr = region->vm_prfile;
617+
618+ prfile_trace(f, pr, func, line, __func__);
619+ return (f && pr) ? pr : f;
620+}
621+
622+void vmr_do_fput(struct vm_region *region, const char func[], int line)
623+{
624+ struct file *f = region->vm_file, *pr = region->vm_prfile;
625+
626+ prfile_trace(f, pr, func, line, __func__);
627+ fput(f);
628+ if (f && pr)
629+ fput(pr);
630+}
631+#endif /* CONFIG_MMU */
2000de60 632aufs3.19 standalone patch
7f207e10 633
c1595e42 634diff --git a/fs/dcache.c b/fs/dcache.c
2000de60 635index eaed72c..3b4386e 100644
c1595e42
JR
636--- a/fs/dcache.c
637+++ b/fs/dcache.c
638@@ -1124,6 +1124,7 @@ rename_retry:
639 seq = 1;
640 goto again;
641 }
642+EXPORT_SYMBOL(d_walk);
643
644 /*
645 * Search for at least 1 mount point in the dentry's subdirs.
1e00d052 646diff --git a/fs/inode.c b/fs/inode.c
2000de60 647index 98d87de..084d84f 100644
1e00d052
AM
648--- a/fs/inode.c
649+++ b/fs/inode.c
392086de 650@@ -57,6 +57,7 @@ static struct hlist_head *inode_hashtable __read_mostly;
4b3da204 651 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
2cbb1c4b
JR
652
653 __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
2cbb1c4b 654+EXPORT_SYMBOL(inode_sb_list_lock);
7f207e10
AM
655
656 /*
4b3da204 657 * Empty aops. Can be used for the cases where the user does not
2000de60 658@@ -1515,6 +1516,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags)
0c3ec466
AM
659 mark_inode_dirty_sync(inode);
660 return 0;
661 }
662+EXPORT_SYMBOL(update_time);
663
664 /**
665 * touch_atime - update the access time
7f207e10 666diff --git a/fs/namespace.c b/fs/namespace.c
2000de60 667index cd1e968..a99a3a7 100644
7f207e10
AM
668--- a/fs/namespace.c
669+++ b/fs/namespace.c
c1595e42 670@@ -454,6 +454,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
c06a8ce3
AM
671 mnt_dec_writers(real_mount(mnt));
672 preempt_enable();
673 }
674+EXPORT_SYMBOL_GPL(__mnt_drop_write);
675
676 /**
677 * mnt_drop_write - give up write access to a mount
2000de60 678@@ -1728,6 +1729,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
7f207e10
AM
679 }
680 return 0;
681 }
682+EXPORT_SYMBOL(iterate_mounts);
683
7eafdf33 684 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
7f207e10
AM
685 {
686diff --git a/fs/notify/group.c b/fs/notify/group.c
c1595e42 687index d16b62c..06ca6bc 100644
7f207e10
AM
688--- a/fs/notify/group.c
689+++ b/fs/notify/group.c
690@@ -22,6 +22,7 @@
691 #include <linux/srcu.h>
692 #include <linux/rculist.h>
693 #include <linux/wait.h>
694+#include <linux/module.h>
695
696 #include <linux/fsnotify_backend.h>
697 #include "fsnotify.h"
fb47a38f 698@@ -72,6 +73,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
1716fcea
AM
699 {
700 atomic_inc(&group->refcnt);
701 }
702+EXPORT_SYMBOL(fsnotify_get_group);
703
704 /*
705 * Drop a reference to a group. Free it if it's through.
fb47a38f 706@@ -81,6 +83,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
7f207e10 707 if (atomic_dec_and_test(&group->refcnt))
1716fcea 708 fsnotify_final_destroy_group(group);
7f207e10
AM
709 }
710+EXPORT_SYMBOL(fsnotify_put_group);
711
712 /*
713 * Create a new fsnotify_group and hold a reference for the group returned.
fb47a38f 714@@ -109,6 +112,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
7f207e10
AM
715
716 return group;
717 }
718+EXPORT_SYMBOL(fsnotify_alloc_group);
1716fcea
AM
719
720 int fsnotify_fasync(int fd, struct file *file, int on)
721 {
7f207e10 722diff --git a/fs/notify/mark.c b/fs/notify/mark.c
2000de60 723index 92e48c7..d2c4b68 100644
7f207e10
AM
724--- a/fs/notify/mark.c
725+++ b/fs/notify/mark.c
392086de 726@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
7f207e10 727 mark->free_mark(mark);
1716fcea 728 }
7f207e10
AM
729 }
730+EXPORT_SYMBOL(fsnotify_put_mark);
731
2000de60
JR
732 /* Calculate mask of events for a list of marks */
733 u32 fsnotify_recalc_mask(struct hlist_head *head)
734@@ -202,6 +203,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
1716fcea
AM
735 fsnotify_destroy_mark_locked(mark, group);
736 mutex_unlock(&group->mark_mutex);
7f207e10
AM
737 }
738+EXPORT_SYMBOL(fsnotify_destroy_mark);
739
2000de60
JR
740 /*
741 * Destroy all marks in the given list. The marks must be already detached from
742@@ -376,6 +378,7 @@ err:
7f207e10
AM
743
744 return ret;
745 }
746+EXPORT_SYMBOL(fsnotify_add_mark);
747
1716fcea
AM
748 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
749 struct inode *inode, struct vfsmount *mnt, int allow_dups)
2000de60 750@@ -455,6 +458,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
7f207e10
AM
751 atomic_set(&mark->refcnt, 1);
752 mark->free_mark = free_mark;
753 }
754+EXPORT_SYMBOL(fsnotify_init_mark);
755
756 static int fsnotify_mark_destroy(void *ignored)
757 {
758diff --git a/fs/open.c b/fs/open.c
2000de60 759index 813be03..328f0d6 100644
7f207e10
AM
760--- a/fs/open.c
761+++ b/fs/open.c
523b37e3 762@@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
7f207e10
AM
763 mutex_unlock(&dentry->d_inode->i_mutex);
764 return ret;
765 }
766+EXPORT_SYMBOL(do_truncate);
767
1716fcea 768 long vfs_truncate(struct path *path, loff_t length)
7f207e10
AM
769 {
770diff --git a/fs/splice.c b/fs/splice.c
c1595e42 771index 619359a..c14f60e 100644
7f207e10
AM
772--- a/fs/splice.c
773+++ b/fs/splice.c
076b876e 774@@ -1127,6 +1127,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
775
776 return splice_write(pipe, out, ppos, len, flags);
7f207e10
AM
777 }
778+EXPORT_SYMBOL(do_splice_from);
779
780 /*
781 * Attempt to initiate a splice from a file to a pipe.
076b876e 782@@ -1153,6 +1154,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
783
784 return splice_read(in, ppos, pipe, len, flags);
785 }
786+EXPORT_SYMBOL(do_splice_to);
787
788 /**
789 * splice_direct_to_actor - splices data directly between two non-pipes
c1595e42 790diff --git a/fs/xattr.c b/fs/xattr.c
2000de60 791index 4ef6985..6bb6303 100644
c1595e42
JR
792--- a/fs/xattr.c
793+++ b/fs/xattr.c
794@@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
795 *xattr_value = value;
796 return error;
797 }
798+EXPORT_SYMBOL(vfs_getxattr_alloc);
799
800 /* Compare an extended attribute value with the given value */
801 int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
7f207e10 802diff --git a/security/commoncap.c b/security/commoncap.c
2000de60 803index 2915d85..58382dd 100644
7f207e10
AM
804--- a/security/commoncap.c
805+++ b/security/commoncap.c
c1595e42 806@@ -979,9 +979,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 807 }
7f207e10
AM
808 return ret;
809 }
0c3ec466
AM
810+EXPORT_SYMBOL(cap_mmap_addr);
811
812 int cap_mmap_file(struct file *file, unsigned long reqprot,
813 unsigned long prot, unsigned long flags)
814 {
815 return 0;
816 }
817+EXPORT_SYMBOL(cap_mmap_file);
7f207e10 818diff --git a/security/device_cgroup.c b/security/device_cgroup.c
c1595e42 819index 188c1d2..426d9af 100644
7f207e10
AM
820--- a/security/device_cgroup.c
821+++ b/security/device_cgroup.c
f6c5ef8b
AM
822@@ -7,6 +7,7 @@
823 #include <linux/device_cgroup.h>
824 #include <linux/cgroup.h>
825 #include <linux/ctype.h>
826+#include <linux/export.h>
827 #include <linux/list.h>
828 #include <linux/uaccess.h>
829 #include <linux/seq_file.h>
076b876e 830@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
831 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
832 access);
7f207e10 833 }
2cbb1c4b 834+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
835
836 int devcgroup_inode_mknod(int mode, dev_t dev)
837 {
838diff --git a/security/security.c b/security/security.c
c1595e42 839index 18b35c6..12c67af 100644
7f207e10
AM
840--- a/security/security.c
841+++ b/security/security.c
392086de 842@@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
843 return 0;
844 return security_ops->path_rmdir(dir, dentry);
845 }
846+EXPORT_SYMBOL(security_path_rmdir);
847
848 int security_path_unlink(struct path *dir, struct dentry *dentry)
849 {
392086de 850@@ -423,6 +424,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
851 return 0;
852 return security_ops->path_symlink(dir, dentry, old_name);
853 }
854+EXPORT_SYMBOL(security_path_symlink);
855
856 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
857 struct dentry *new_dentry)
392086de 858@@ -431,6 +433,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
859 return 0;
860 return security_ops->path_link(old_dentry, new_dir, new_dentry);
861 }
862+EXPORT_SYMBOL(security_path_link);
863
864 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
38d290e6
JR
865 struct path *new_dir, struct dentry *new_dentry,
866@@ -458,6 +461,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
867 return 0;
868 return security_ops->path_truncate(path);
869 }
870+EXPORT_SYMBOL(security_path_truncate);
871
7eafdf33
AM
872 int security_path_chmod(struct path *path, umode_t mode)
873 {
38d290e6 874@@ -465,6 +469,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 875 return 0;
7eafdf33 876 return security_ops->path_chmod(path, mode);
7f207e10
AM
877 }
878+EXPORT_SYMBOL(security_path_chmod);
879
537831f9 880 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 881 {
38d290e6 882@@ -472,6 +477,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
883 return 0;
884 return security_ops->path_chown(path, uid, gid);
885 }
886+EXPORT_SYMBOL(security_path_chown);
887
888 int security_path_chroot(struct path *path)
889 {
38d290e6 890@@ -557,6 +563,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
891 return 0;
892 return security_ops->inode_readlink(dentry);
893 }
894+EXPORT_SYMBOL(security_inode_readlink);
895
896 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
897 {
38d290e6 898@@ -571,6 +578,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 899 return 0;
1e00d052 900 return security_ops->inode_permission(inode, mask);
7f207e10
AM
901 }
902+EXPORT_SYMBOL(security_inode_permission);
903
1e00d052 904 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 905 {
38d290e6 906@@ -693,6 +701,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
907
908 return fsnotify_perm(file, mask);
909 }
910+EXPORT_SYMBOL(security_file_permission);
911
912 int security_file_alloc(struct file *file)
913 {
38d290e6 914@@ -753,6 +762,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
915 return ret;
916 return ima_file_mmap(file, prot);
917 }
0c3ec466 918+EXPORT_SYMBOL(security_mmap_file);
7f207e10 919
0c3ec466
AM
920 int security_mmap_addr(unsigned long addr)
921 {
7f207e10
AM
922diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
923--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
2000de60 924+++ linux/Documentation/ABI/testing/debugfs-aufs 2015-03-27 21:56:35.453461667 +0100
86dc4139 925@@ -0,0 +1,50 @@
7f207e10
AM
926+What: /debug/aufs/si_<id>/
927+Date: March 2009
f6b6e03d 928+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
929+Description:
930+ Under /debug/aufs, a directory named si_<id> is created
931+ per aufs mount, where <id> is a unique id generated
932+ internally.
1facf9fc 933+
86dc4139
AM
934+What: /debug/aufs/si_<id>/plink
935+Date: Apr 2013
f6b6e03d 936+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
937+Description:
938+ It has three lines and shows the information about the
939+ pseudo-link. The first line is a single number
940+ representing a number of buckets. The second line is a
941+ number of pseudo-links per buckets (separated by a
942+ blank). The last line is a single number representing a
943+ total number of psedo-links.
944+ When the aufs mount option 'noplink' is specified, it
945+ will show "1\n0\n0\n".
946+
7f207e10
AM
947+What: /debug/aufs/si_<id>/xib
948+Date: March 2009
f6b6e03d 949+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
950+Description:
951+ It shows the consumed blocks by xib (External Inode Number
952+ Bitmap), its block size and file size.
953+ When the aufs mount option 'noxino' is specified, it
954+ will be empty. About XINO files, see the aufs manual.
955+
956+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
957+Date: March 2009
f6b6e03d 958+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
959+Description:
960+ It shows the consumed blocks by xino (External Inode Number
961+ Translation Table), its link count, block size and file
962+ size.
963+ When the aufs mount option 'noxino' is specified, it
964+ will be empty. About XINO files, see the aufs manual.
965+
966+What: /debug/aufs/si_<id>/xigen
967+Date: March 2009
f6b6e03d 968+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
969+Description:
970+ It shows the consumed blocks by xigen (External Inode
971+ Generation Table), its block size and file size.
972+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
973+ be created.
974+ When the aufs mount option 'noxino' is specified, it
975+ will be empty. About XINO files, see the aufs manual.
976diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
977--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
2000de60 978+++ linux/Documentation/ABI/testing/sysfs-aufs 2015-03-27 21:56:35.456795001 +0100
392086de 979@@ -0,0 +1,31 @@
7f207e10
AM
980+What: /sys/fs/aufs/si_<id>/
981+Date: March 2009
f6b6e03d 982+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
983+Description:
984+ Under /sys/fs/aufs, a directory named si_<id> is created
985+ per aufs mount, where <id> is a unique id generated
986+ internally.
987+
988+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
989+Date: March 2009
f6b6e03d 990+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
991+Description:
992+ It shows the abolute path of a member directory (which
993+ is called branch) in aufs, and its permission.
994+
392086de
AM
995+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
996+Date: July 2013
f6b6e03d 997+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
998+Description:
999+ It shows the id of a member directory (which is called
1000+ branch) in aufs.
1001+
7f207e10
AM
1002+What: /sys/fs/aufs/si_<id>/xi_path
1003+Date: March 2009
f6b6e03d 1004+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1005+Description:
1006+ It shows the abolute path of XINO (External Inode Number
1007+ Bitmap, Translation Table and Generation Table) file
1008+ even if it is the default path.
1009+ When the aufs mount option 'noxino' is specified, it
1010+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
1011diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
1012--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1013+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2015-03-27 21:56:35.456795001 +0100
523b37e3 1014@@ -0,0 +1,161 @@
53392da6 1015+
2000de60 1016+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1017+#
1018+# This program is free software; you can redistribute it and/or modify
1019+# it under the terms of the GNU General Public License as published by
1020+# the Free Software Foundation; either version 2 of the License, or
1021+# (at your option) any later version.
1022+#
1023+# This program is distributed in the hope that it will be useful,
1024+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1025+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1026+# GNU General Public License for more details.
1027+#
1028+# You should have received a copy of the GNU General Public License
523b37e3 1029+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1030+
1031+Introduction
1032+----------------------------------------
1033+
1034+aufs [ei ju: ef es] | [a u f s]
1035+1. abbrev. for "advanced multi-layered unification filesystem".
1036+2. abbrev. for "another unionfs".
1037+3. abbrev. for "auf das" in German which means "on the" in English.
1038+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
1039+ But "Filesystem aufs Filesystem" is hard to understand.
1040+
1041+AUFS is a filesystem with features:
1042+- multi layered stackable unification filesystem, the member directory
1043+ is called as a branch.
1044+- branch permission and attribute, 'readonly', 'real-readonly',
1045+ 'readwrite', 'whiteout-able', 'link-able whiteout' and their
1046+ combination.
1047+- internal "file copy-on-write".
1048+- logical deletion, whiteout.
1049+- dynamic branch manipulation, adding, deleting and changing permission.
1050+- allow bypassing aufs, user's direct branch access.
1051+- external inode number translation table and bitmap which maintains the
1052+ persistent aufs inode number.
1053+- seekable directory, including NFS readdir.
1054+- file mapping, mmap and sharing pages.
1055+- pseudo-link, hardlink over branches.
1056+- loopback mounted filesystem as a branch.
1057+- several policies to select one among multiple writable branches.
1058+- revert a single systemcall when an error occurs in aufs.
1059+- and more...
1060+
1061+
1062+Multi Layered Stackable Unification Filesystem
1063+----------------------------------------------------------------------
1064+Most people already knows what it is.
1065+It is a filesystem which unifies several directories and provides a
1066+merged single directory. When users access a file, the access will be
1067+passed/re-directed/converted (sorry, I am not sure which English word is
1068+correct) to the real file on the member filesystem. The member
1069+filesystem is called 'lower filesystem' or 'branch' and has a mode
1070+'readonly' and 'readwrite.' And the deletion for a file on the lower
1071+readonly branch is handled by creating 'whiteout' on the upper writable
1072+branch.
1073+
1074+On LKML, there have been discussions about UnionMount (Jan Blunck,
1075+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1076+different approaches to implement the merged-view.
1077+The former tries putting it into VFS, and the latter implements as a
1078+separate filesystem.
1079+(If I misunderstand about these implementations, please let me know and
1080+I shall correct it. Because it is a long time ago when I read their
1081+source files last time).
1082+
1083+UnionMount's approach will be able to small, but may be hard to share
1084+branches between several UnionMount since the whiteout in it is
1085+implemented in the inode on branch filesystem and always
1086+shared. According to Bharata's post, readdir does not seems to be
1087+finished yet.
1088+There are several missing features known in this implementations such as
1089+- for users, the inode number may change silently. eg. copy-up.
1090+- link(2) may break by copy-up.
1091+- read(2) may get an obsoleted filedata (fstat(2) too).
1092+- fcntl(F_SETLK) may be broken by copy-up.
1093+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1094+ open(O_RDWR).
1095+
1096+Unionfs has a longer history. When I started implementing a stacking filesystem
1097+(Aug 2005), it already existed. It has virtual super_block, inode,
1098+dentry and file objects and they have an array pointing lower same kind
1099+objects. After contributing many patches for Unionfs, I re-started my
1100+project AUFS (Jun 2006).
1101+
1102+In AUFS, the structure of filesystem resembles to Unionfs, but I
1103+implemented my own ideas, approaches and enhancements and it became
1104+totally different one.
1105+
1106+Comparing DM snapshot and fs based implementation
1107+- the number of bytes to be copied between devices is much smaller.
1108+- the type of filesystem must be one and only.
1109+- the fs must be writable, no readonly fs, even for the lower original
1110+ device. so the compression fs will not be usable. but if we use
1111+ loopback mount, we may address this issue.
1112+ for instance,
1113+ mount /cdrom/squashfs.img /sq
1114+ losetup /sq/ext2.img
1115+ losetup /somewhere/cow
1116+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1117+- it will be difficult (or needs more operations) to extract the
1118+ difference between the original device and COW.
1119+- DM snapshot-merge may help a lot when users try merging. in the
1120+ fs-layer union, users will use rsync(1).
1121+
1122+
1123+Several characters/aspects of aufs
1124+----------------------------------------------------------------------
1125+
1126+Aufs has several characters or aspects.
1127+1. a filesystem, callee of VFS helper
1128+2. sub-VFS, caller of VFS helper for branches
1129+3. a virtual filesystem which maintains persistent inode number
1130+4. reader/writer of files on branches such like an application
1131+
1132+1. Callee of VFS Helper
1133+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1134+unlink(2) from an application reaches sys_unlink() kernel function and
1135+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1136+calls filesystem specific unlink operation. Actually aufs implements the
1137+unlink operation but it behaves like a redirector.
1138+
1139+2. Caller of VFS Helper for Branches
1140+aufs_unlink() passes the unlink request to the branch filesystem as if
1141+it were called from VFS. So the called unlink operation of the branch
1142+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1143+every necessary pre/post operation for the branch filesystem.
1144+- acquire the lock for the parent dir on a branch
1145+- lookup in a branch
1146+- revalidate dentry on a branch
1147+- mnt_want_write() for a branch
1148+- vfs_unlink() for a branch
1149+- mnt_drop_write() for a branch
1150+- release the lock on a branch
1151+
1152+3. Persistent Inode Number
1153+One of the most important issue for a filesystem is to maintain inode
1154+numbers. This is particularly important to support exporting a
1155+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1156+backend block device for its own. But some storage is necessary to
1157+maintain inode number. It may be a large space and may not suit to keep
1158+in memory. Aufs rents some space from its first writable branch
1159+filesystem (by default) and creates file(s) on it. These files are
1160+created by aufs internally and removed soon (currently) keeping opened.
1161+Note: Because these files are removed, they are totally gone after
1162+ unmounting aufs. It means the inode numbers are not persistent
1163+ across unmount or reboot. I have a plan to make them really
1164+ persistent which will be important for aufs on NFS server.
1165+
1166+4. Read/Write Files Internally (copy-on-write)
1167+Because a branch can be readonly, when you write a file on it, aufs will
1168+"copy-up" it to the upper writable branch internally. And then write the
1169+originally requested thing to the file. Generally kernel doesn't
1170+open/read/write file actively. In aufs, even a single write may cause a
1171+internal "file copy". This behaviour is very similar to cp(1) command.
1172+
1173+Some people may think it is better to pass such work to user space
1174+helper, instead of doing in kernel space. Actually I am still thinking
1175+about it. But currently I have implemented it in kernel space.
1176diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1177--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1178+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2015-03-27 21:56:35.456795001 +0100
076b876e 1179@@ -0,0 +1,251 @@
53392da6 1180+
2000de60 1181+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1182+#
1183+# This program is free software; you can redistribute it and/or modify
1184+# it under the terms of the GNU General Public License as published by
1185+# the Free Software Foundation; either version 2 of the License, or
1186+# (at your option) any later version.
1187+#
1188+# This program is distributed in the hope that it will be useful,
1189+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1190+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1191+# GNU General Public License for more details.
1192+#
1193+# You should have received a copy of the GNU General Public License
523b37e3 1194+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1195+
1196+Basic Aufs Internal Structure
1197+
1198+Superblock/Inode/Dentry/File Objects
1199+----------------------------------------------------------------------
1200+As like an ordinary filesystem, aufs has its own
1201+superblock/inode/dentry/file objects. All these objects have a
1202+dynamically allocated array and store the same kind of pointers to the
1203+lower filesystem, branch.
1204+For example, when you build a union with one readwrite branch and one
1205+readonly, mounted /au, /rw and /ro respectively.
1206+- /au = /rw + /ro
1207+- /ro/fileA exists but /rw/fileA
1208+
1209+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1210+pointers are stored in a aufs dentry. The array in aufs dentry will be,
1211+- [0] = NULL
1212+- [1] = /ro/fileA
1213+
1214+This style of an array is essentially same to the aufs
1215+superblock/inode/dentry/file objects.
1216+
1217+Because aufs supports manipulating branches, ie. add/delete/change
1218+dynamically, these objects has its own generation. When branches are
1219+changed, the generation in aufs superblock is incremented. And a
1220+generation in other object are compared when it is accessed.
1221+When a generation in other objects are obsoleted, aufs refreshes the
1222+internal array.
1223+
1224+
1225+Superblock
1226+----------------------------------------------------------------------
1227+Additionally aufs superblock has some data for policies to select one
1228+among multiple writable branches, XIB files, pseudo-links and kobject.
1229+See below in detail.
1230+About the policies which supports copy-down a directory, see policy.txt
1231+too.
1232+
1233+
1234+Branch and XINO(External Inode Number Translation Table)
1235+----------------------------------------------------------------------
1236+Every branch has its own xino (external inode number translation table)
1237+file. The xino file is created and unlinked by aufs internally. When two
1238+members of a union exist on the same filesystem, they share the single
1239+xino file.
1240+The struct of a xino file is simple, just a sequence of aufs inode
1241+numbers which is indexed by the lower inode number.
1242+In the above sample, assume the inode number of /ro/fileA is i111 and
1243+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1244+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1245+
1246+When the inode numbers are not contiguous, the xino file will be sparse
1247+which has a hole in it and doesn't consume as much disk space as it
1248+might appear. If your branch filesystem consumes disk space for such
1249+holes, then you should specify 'xino=' option at mounting aufs.
1250+
1251+Also a writable branch has three kinds of "whiteout bases". All these
1252+are existed when the branch is joined to aufs and the names are
1253+whiteout-ed doubly, so that users will never see their names in aufs
1254+hierarchy.
1255+1. a regular file which will be linked to all whiteouts.
1256+2. a directory to store a pseudo-link.
1257+3. a directory to store an "orphan-ed" file temporary.
1258+
1259+1. Whiteout Base
1260+ When you remove a file on a readonly branch, aufs handles it as a
1261+ logical deletion and creates a whiteout on the upper writable branch
1262+ as a hardlink of this file in order not to consume inode on the
1263+ writable branch.
1264+2. Pseudo-link Dir
1265+ See below, Pseudo-link.
1266+3. Step-Parent Dir
1267+ When "fileC" exists on the lower readonly branch only and it is
1268+ opened and removed with its parent dir, and then user writes
1269+ something into it, then aufs copies-up fileC to this
1270+ directory. Because there is no other dir to store fileC. After
1271+ creating a file under this dir, the file is unlinked.
1272+
1273+Because aufs supports manipulating branches, ie. add/delete/change
1274+dynamically, a branch has its own id. When the branch order changes, aufs
1275+finds the new index by searching the branch id.
1276+
1277+
1278+Pseudo-link
1279+----------------------------------------------------------------------
1280+Assume "fileA" exists on the lower readonly branch only and it is
1281+hardlinked to "fileB" on the branch. When you write something to fileA,
1282+aufs copies-up it to the upper writable branch. Additionally aufs
1283+creates a hardlink under the Pseudo-link Directory of the writable
1284+branch. The inode of a pseudo-link is kept in aufs super_block as a
1285+simple list. If fileB is read after unlinking fileA, aufs returns
1286+filedata from the pseudo-link instead of the lower readonly
1287+branch. Because the pseudo-link is based upon the inode, to keep the
1288+inode number by xino (see above) is important.
1289+
1290+All the hardlinks under the Pseudo-link Directory of the writable branch
1291+should be restored in a proper location later. Aufs provides a utility
1292+to do this. The userspace helpers executed at remounting and unmounting
1293+aufs by default.
1294+During this utility is running, it puts aufs into the pseudo-link
1295+maintenance mode. In this mode, only the process which began the
1296+maintenance mode (and its child processes) is allowed to operate in
1297+aufs. Some other processes which are not related to the pseudo-link will
1298+be allowed to run too, but the rest have to return an error or wait
1299+until the maintenance mode ends. If a process already acquires an inode
1300+mutex (in VFS), it has to return an error.
1301+
1302+
1303+XIB(external inode number bitmap)
1304+----------------------------------------------------------------------
1305+Addition to the xino file per a branch, aufs has an external inode number
1306+bitmap in a superblock object. It is also a file such like a xino file.
1307+It is a simple bitmap to mark whether the aufs inode number is in-use or
1308+not.
1309+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1310+
1311+Aufs implements a feature to truncate/refresh both of xino and xib to
1312+reduce the number of consumed disk blocks for these files.
1313+
1314+
1315+Virtual or Vertical Dir, and Readdir in Userspace
1316+----------------------------------------------------------------------
1317+In order to support multiple layers (branches), aufs readdir operation
1318+constructs a virtual dir block on memory. For readdir, aufs calls
1319+vfs_readdir() internally for each dir on branches, merges their entries
1320+with eliminating the whiteout-ed ones, and sets it to file (dir)
1321+object. So the file object has its entry list until it is closed. The
1322+entry list will be updated when the file position is zero and becomes
1323+old. This decision is made in aufs automatically.
1324+
1325+The dynamically allocated memory block for the name of entries has a
1326+unit of 512 bytes (by default) and stores the names contiguously (no
1327+padding). Another block for each entry is handled by kmem_cache too.
1328+During building dir blocks, aufs creates hash list and judging whether
1329+the entry is whiteouted by its upper branch or already listed.
1330+The merged result is cached in the corresponding inode object and
1331+maintained by a customizable life-time option.
1332+
1333+Some people may call it can be a security hole or invite DoS attack
1334+since the opened and once readdir-ed dir (file object) holds its entry
1335+list and becomes a pressure for system memory. But I'd say it is similar
1336+to files under /proc or /sys. The virtual files in them also holds a
1337+memory page (generally) while they are opened. When an idea to reduce
1338+memory for them is introduced, it will be applied to aufs too.
1339+For those who really hate this situation, I've developed readdir(3)
1340+library which operates this merging in userspace. You just need to set
1341+LD_PRELOAD environment variable, and aufs will not consume no memory in
1342+kernel space for readdir(3).
1343+
1344+
1345+Workqueue
1346+----------------------------------------------------------------------
1347+Aufs sometimes requires privilege access to a branch. For instance,
1348+in copy-up/down operation. When a user process is going to make changes
1349+to a file which exists in the lower readonly branch only, and the mode
1350+of one of ancestor directories may not be writable by a user
1351+process. Here aufs copy-up the file with its ancestors and they may
1352+require privilege to set its owner/group/mode/etc.
1353+This is a typical case of a application character of aufs (see
1354+Introduction).
1355+
1356+Aufs uses workqueue synchronously for this case. It creates its own
1357+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1358+passes the request to call mkdir or write (for example), and wait for
1359+its completion. This approach solves a problem of a signal handler
1360+simply.
1361+If aufs didn't adopt the workqueue and changed the privilege of the
1362+process, and if the mkdir/write call arises SIGXFSZ or other signal,
1363+then the user process might gain a privilege or the generated core file
1364+was owned by a superuser.
1365+
1366+Also aufs uses the system global workqueue ("events" kernel thread) too
1367+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1368+whiteout base and etc. This is unrelated to a privilege.
1369+Most of aufs operation tries acquiring a rw_semaphore for aufs
1370+superblock at the beginning, at the same time waits for the completion
1371+of all queued asynchronous tasks.
1372+
1373+
1374+Whiteout
1375+----------------------------------------------------------------------
1376+The whiteout in aufs is very similar to Unionfs's. That is represented
1377+by its filename. UnionMount takes an approach of a file mode, but I am
1378+afraid several utilities (find(1) or something) will have to support it.
1379+
1380+Basically the whiteout represents "logical deletion" which stops aufs to
1381+lookup further, but also it represents "dir is opaque" which also stop
1382+lookup.
1383+
1384+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1385+In order to make several functions in a single systemcall to be
1386+revertible, aufs adopts an approach to rename a directory to a temporary
1387+unique whiteouted name.
1388+For example, in rename(2) dir where the target dir already existed, aufs
1389+renames the target dir to a temporary unique whiteouted name before the
1390+actual rename on a branch and then handles other actions (make it opaque,
1391+update the attributes, etc). If an error happens in these actions, aufs
1392+simply renames the whiteouted name back and returns an error. If all are
1393+succeeded, aufs registers a function to remove the whiteouted unique
1394+temporary name completely and asynchronously to the system global
1395+workqueue.
1396+
1397+
1398+Copy-up
1399+----------------------------------------------------------------------
1400+It is a well-known feature or concept.
1401+When user modifies a file on a readonly branch, aufs operate "copy-up"
1402+internally and makes change to the new file on the upper writable branch.
1403+When the trigger systemcall does not update the timestamps of the parent
1404+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1405+
1406+
1407+Move-down (aufs3.9 and later)
1408+----------------------------------------------------------------------
1409+"Copy-up" is one of the essential feature in aufs. It copies a file from
1410+the lower readonly branch to the upper writable branch when a user
1411+changes something about the file.
1412+"Move-down" is an opposite action of copy-up. Basically this action is
1413+ran manually instead of automatically and internally.
076b876e
AM
1414+For desgin and implementation, aufs has to consider these issues.
1415+- whiteout for the file may exist on the lower branch.
1416+- ancestor directories may not exist on the lower branch.
1417+- diropq for the ancestor directories may exist on the upper branch.
1418+- free space on the lower branch will reduce.
1419+- another access to the file may happen during moving-down, including
1420+ UDBA.
1421+- the file should not be hard-linked nor pseudo-linked. they should be
1422+ handled by auplink utility later.
c2b27bf2
AM
1423+
1424+Sometimes users want to move-down a file from the upper writable branch
1425+to the lower readonly or writable branch. For instance,
1426+- the free space of the upper writable branch is going to run out.
1427+- create a new intermediate branch between the upper and lower branch.
1428+- etc.
1429+
1430+For this purpose, use "aumvdown" command in aufs-util.git.
53392da6
AM
1431diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1432--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1433+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2015-03-27 21:56:35.456795001 +0100
076b876e 1434@@ -0,0 +1,133 @@
53392da6 1435+
2000de60 1436+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1437+#
1438+# This program is free software; you can redistribute it and/or modify
1439+# it under the terms of the GNU General Public License as published by
1440+# the Free Software Foundation; either version 2 of the License, or
1441+# (at your option) any later version.
1442+#
1443+# This program is distributed in the hope that it will be useful,
1444+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1445+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1446+# GNU General Public License for more details.
1447+#
1448+# You should have received a copy of the GNU General Public License
523b37e3 1449+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1450+
1451+Lookup in a Branch
1452+----------------------------------------------------------------------
1453+Since aufs has a character of sub-VFS (see Introduction), it operates
1454+lookup for branches as VFS does. It may be a heavy work. Generally
1455+speaking struct nameidata is a bigger structure and includes many
1456+information. But almost all lookup operation in aufs is the simplest
1457+case, ie. lookup only an entry directly connected to its parent. Digging
1458+down the directory hierarchy is unnecessary.
1459+
1460+VFS has a function lookup_one_len() for that use, but it is not usable
1461+for a branch filesystem which requires struct nameidata. So aufs
1462+implements a simple lookup wrapper function. When a branch filesystem
1463+allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
1464+a simplest nameidata and calls lookup_hash().
1465+Here aufs applies "a principle in NFSD", ie. if the filesystem supports
1466+NFS-export, then it has to support NULL as a nameidata parameter for
1467+->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
1468+aufs tests if ->s_export_op in the branch is NULL or not.
1469+
1470+When a branch is a remote filesystem, aufs basically trusts its
1471+->d_revalidate(), also aufs forces the hardest revalidate tests for
1472+them.
1473+For d_revalidate, aufs implements three levels of revalidate tests. See
1474+"Revalidate Dentry and UDBA" in detail.
1475+
1476+
076b876e
AM
1477+Test Only the Highest One for the Directory Permission (dirperm1 option)
1478+----------------------------------------------------------------------
1479+Let's try case study.
1480+- aufs has two branches, upper readwrite and lower readonly.
1481+ /au = /rw + /ro
1482+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1483+- user invoked "chmod a+rx /au/dirA"
1484+- the internal copy-up is activated and "/rw/dirA" is created and its
1485+ permission bits are set to world readble.
1486+- then "/au/dirA" becomes world readable?
1487+
1488+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1489+or it may be a natively readonly filesystem. If aufs respects the lower
1490+branch, it should not respond readdir request from other users. But user
1491+allowed it by chmod. Should really aufs rejects showing the entries
1492+under /ro/dirA?
1493+
1494+To be honest, I don't have a best solution for this case. So aufs
1495+implements 'dirperm1' and 'nodirperm1' and leave it to users.
1496+When dirperm1 is specified, aufs checks only the highest one for the
1497+directory permission, and shows the entries. Otherwise, as usual, checks
1498+every dir existing on all branches and rejects the request.
1499+
1500+As a side effect, dirperm1 option improves the performance of aufs
1501+because the number of permission check is reduced when the number of
1502+branch is many.
1503+
1504+
53392da6
AM
1505+Loopback Mount
1506+----------------------------------------------------------------------
1507+Basically aufs supports any type of filesystem and block device for a
1508+branch (actually there are some exceptions). But it is prohibited to add
1509+a loopback mounted one whose backend file exists in a filesystem which is
1510+already added to aufs. The reason is to protect aufs from a recursive
1511+lookup. If it was allowed, the aufs lookup operation might re-enter a
1512+lookup for the loopback mounted branch in the same context, and will
1513+cause a deadlock.
1514+
1515+
1516+Revalidate Dentry and UDBA (User's Direct Branch Access)
1517+----------------------------------------------------------------------
1518+Generally VFS helpers re-validate a dentry as a part of lookup.
1519+0. digging down the directory hierarchy.
1520+1. lock the parent dir by its i_mutex.
1521+2. lookup the final (child) entry.
1522+3. revalidate it.
1523+4. call the actual operation (create, unlink, etc.)
1524+5. unlock the parent dir
1525+
1526+If the filesystem implements its ->d_revalidate() (step 3), then it is
1527+called. Actually aufs implements it and checks the dentry on a branch is
1528+still valid.
1529+But it is not enough. Because aufs has to release the lock for the
1530+parent dir on a branch at the end of ->lookup() (step 2) and
1531+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1532+held by VFS.
1533+If the file on a branch is changed directly, eg. bypassing aufs, after
1534+aufs released the lock, then the subsequent operation may cause
1535+something unpleasant result.
1536+
1537+This situation is a result of VFS architecture, ->lookup() and
1538+->d_revalidate() is separated. But I never say it is wrong. It is a good
1539+design from VFS's point of view. It is just not suitable for sub-VFS
1540+character in aufs.
1541+
1542+Aufs supports such case by three level of revalidation which is
1543+selectable by user.
1544+1. Simple Revalidate
1545+ Addition to the native flow in VFS's, confirm the child-parent
1546+ relationship on the branch just after locking the parent dir on the
1547+ branch in the "actual operation" (step 4). When this validation
1548+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1549+ checks the validation of the dentry on branches.
1550+2. Monitor Changes Internally by Inotify/Fsnotify
1551+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1552+ the dentry on the branch, and returns EBUSY if it finds different
1553+ dentry.
1554+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1555+ during it is in cache. When the event is notified, aufs registers a
1556+ function to kernel 'events' thread by schedule_work(). And the
1557+ function sets some special status to the cached aufs dentry and inode
1558+ private data. If they are not cached, then aufs has nothing to
1559+ do. When the same file is accessed through aufs (step 0-3) later,
1560+ aufs will detect the status and refresh all necessary data.
1561+ In this mode, aufs has to ignore the event which is fired by aufs
1562+ itself.
1563+3. No Extra Validation
1564+ This is the simplest test and doesn't add any additional revalidation
1565+ test, and skip therevalidatin in step 4. It is useful and improves
1566+ aufs performance when system surely hide the aufs branches from user,
1567+ by over-mounting something (or another method).
1568diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1569--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1570+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2015-03-27 21:56:35.456795001 +0100
523b37e3 1571@@ -0,0 +1,75 @@
53392da6 1572+
2000de60 1573+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1574+#
1575+# This program is free software; you can redistribute it and/or modify
1576+# it under the terms of the GNU General Public License as published by
1577+# the Free Software Foundation; either version 2 of the License, or
1578+# (at your option) any later version.
1579+#
1580+# This program is distributed in the hope that it will be useful,
1581+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1582+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1583+# GNU General Public License for more details.
1584+#
1585+# You should have received a copy of the GNU General Public License
523b37e3 1586+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1587+
1588+Branch Manipulation
1589+
1590+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1591+and changing its permission/attribute, there are a lot of works to do.
1592+
1593+
1594+Add a Branch
1595+----------------------------------------------------------------------
1596+o Confirm the adding dir exists outside of aufs, including loopback
1597+ mount.
1598+- and other various attributes...
1599+o Initialize the xino file and whiteout bases if necessary.
1600+ See struct.txt.
1601+
1602+o Check the owner/group/mode of the directory
1603+ When the owner/group/mode of the adding directory differs from the
1604+ existing branch, aufs issues a warning because it may impose a
1605+ security risk.
1606+ For example, when a upper writable branch has a world writable empty
1607+ top directory, a malicious user can create any files on the writable
1608+ branch directly, like copy-up and modify manually. If something like
1609+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1610+ writable branch, and the writable branch is world-writable, then a
1611+ malicious guy may create /etc/passwd on the writable branch directly
1612+ and the infected file will be valid in aufs.
1613+ I am afraid it can be a security issue, but nothing to do except
1614+ producing a warning.
1615+
1616+
1617+Delete a Branch
1618+----------------------------------------------------------------------
1619+o Confirm the deleting branch is not busy
1620+ To be general, there is one merit to adopt "remount" interface to
1621+ manipulate branches. It is to discard caches. At deleting a branch,
1622+ aufs checks the still cached (and connected) dentries and inodes. If
1623+ there are any, then they are all in-use. An inode without its
1624+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1625+
1626+ For the cached one, aufs checks whether the same named entry exists on
1627+ other branches.
1628+ If the cached one is a directory, because aufs provides a merged view
1629+ to users, as long as one dir is left on any branch aufs can show the
1630+ dir to users. In this case, the branch can be removed from aufs.
1631+ Otherwise aufs rejects deleting the branch.
1632+
1633+ If any file on the deleting branch is opened by aufs, then aufs
1634+ rejects deleting.
1635+
1636+
1637+Modify the Permission of a Branch
1638+----------------------------------------------------------------------
1639+o Re-initialize or remove the xino file and whiteout bases if necessary.
1640+ See struct.txt.
1641+
1642+o rw --> ro: Confirm the modifying branch is not busy
1643+ Aufs rejects the request if any of these conditions are true.
1644+ - a file on the branch is mmap-ed.
1645+ - a regular file on the branch is opened for write and there is no
1646+ same named entry on the upper branch.
1647diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1648--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1649+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2015-03-27 21:56:35.456795001 +0100
523b37e3 1650@@ -0,0 +1,64 @@
53392da6 1651+
2000de60 1652+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1653+#
1654+# This program is free software; you can redistribute it and/or modify
1655+# it under the terms of the GNU General Public License as published by
1656+# the Free Software Foundation; either version 2 of the License, or
1657+# (at your option) any later version.
1658+#
1659+# This program is distributed in the hope that it will be useful,
1660+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1661+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1662+# GNU General Public License for more details.
1663+#
1664+# You should have received a copy of the GNU General Public License
523b37e3 1665+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1666+
1667+Policies to Select One among Multiple Writable Branches
1668+----------------------------------------------------------------------
1669+When the number of writable branch is more than one, aufs has to decide
1670+the target branch for file creation or copy-up. By default, the highest
1671+writable branch which has the parent (or ancestor) dir of the target
1672+file is chosen (top-down-parent policy).
1673+By user's request, aufs implements some other policies to select the
1674+writable branch, for file creation two policies, round-robin and
1675+most-free-space policies. For copy-up three policies, top-down-parent,
1676+bottom-up-parent and bottom-up policies.
1677+
1678+As expected, the round-robin policy selects the branch in circular. When
1679+you have two writable branches and creates 10 new files, 5 files will be
1680+created for each branch. mkdir(2) systemcall is an exception. When you
1681+create 10 new directories, all will be created on the same branch.
1682+And the most-free-space policy selects the one which has most free
1683+space among the writable branches. The amount of free space will be
1684+checked by aufs internally, and users can specify its time interval.
1685+
1686+The policies for copy-up is more simple,
1687+top-down-parent is equivalent to the same named on in create policy,
1688+bottom-up-parent selects the writable branch where the parent dir
1689+exists and the nearest upper one from the copyup-source,
1690+bottom-up selects the nearest upper writable branch from the
1691+copyup-source, regardless the existence of the parent dir.
1692+
1693+There are some rules or exceptions to apply these policies.
1694+- If there is a readonly branch above the policy-selected branch and
1695+ the parent dir is marked as opaque (a variation of whiteout), or the
1696+ target (creating) file is whiteout-ed on the upper readonly branch,
1697+ then the result of the policy is ignored and the target file will be
1698+ created on the nearest upper writable branch than the readonly branch.
1699+- If there is a writable branch above the policy-selected branch and
1700+ the parent dir is marked as opaque or the target file is whiteouted
1701+ on the branch, then the result of the policy is ignored and the target
1702+ file will be created on the highest one among the upper writable
1703+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1704+ it as usual.
1705+- link(2) and rename(2) systemcalls are exceptions in every policy.
1706+ They try selecting the branch where the source exists as possible
1707+ since copyup a large file will take long time. If it can't be,
1708+ ie. the branch where the source exists is readonly, then they will
1709+ follow the copyup policy.
1710+- There is an exception for rename(2) when the target exists.
1711+ If the rename target exists, aufs compares the index of the branches
1712+ where the source and the target exists and selects the higher
1713+ one. If the selected branch is readonly, then aufs follows the
1714+ copyup policy.
076b876e
AM
1715diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
1716--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1717+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2015-03-27 21:56:35.456795001 +0100
076b876e
AM
1718@@ -0,0 +1,120 @@
1719+
2000de60 1720+# Copyright (C) 2011-2015 Junjiro R. Okajima
076b876e
AM
1721+#
1722+# This program is free software; you can redistribute it and/or modify
1723+# it under the terms of the GNU General Public License as published by
1724+# the Free Software Foundation; either version 2 of the License, or
1725+# (at your option) any later version.
1726+#
1727+# This program is distributed in the hope that it will be useful,
1728+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1729+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1730+# GNU General Public License for more details.
1731+#
1732+# You should have received a copy of the GNU General Public License
1733+# along with this program; if not, write to the Free Software
1734+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1735+
1736+
1737+File-based Hierarchical Storage Management (FHSM)
1738+----------------------------------------------------------------------
1739+Hierarchical Storage Management (or HSM) is a well-known feature in the
1740+storage world. Aufs provides this feature as file-based with multiple
1741+writable branches, based upon the principle of "Colder-Lower".
1742+Here the word "colder" means that the less used files, and "lower" means
1743+that the position in the order of the stacked branches.
1744+These multiple writable branches are prioritized, ie. the topmost one
1745+should be the fastest drive and be used heavily.
1746+
1747+o Characters in aufs FHSM story
1748+- aufs itself and a new branch attribute.
1749+- a new ioctl interface to move-down and to establish a connection with
1750+ the daemon ("move-down" is a converse of "copy-up").
1751+- userspace tool and daemon.
1752+
1753+The userspace daemon establishes a connection with aufs and waits for
1754+the notification. The notified information is very similar to struct
1755+statfs containing the number of consumed blocks and inodes.
1756+When the consumed blocks/inodes of a branch exceeds the user-specified
1757+upper watermark, the daemon activates its move-down process until the
1758+consumed blocks/inodes reaches the user-specified lower watermark.
1759+
1760+The actual move-down is done by aufs based upon the request from
1761+user-space since we need to maintain the inode number and the internal
1762+pointer arrays in aufs.
1763+
1764+Currently aufs FHSM handles the regular files only. Additionally they
1765+must not be hard-linked nor pseudo-linked.
1766+
1767+
1768+o Cowork of aufs and the user-space daemon
1769+ During the userspace daemon established the connection, aufs sends a
1770+ small notification to it whenever aufs writes something into the
1771+ writable branch. But it may cost high since aufs issues statfs(2)
1772+ internally. So user can specify a new option to cache the
1773+ info. Actually the notification is controlled by these factors.
1774+ + the specified cache time.
1775+ + classified as "force" by aufs internally.
1776+ Until the specified time expires, aufs doesn't send the info
1777+ except the forced cases. When aufs decide forcing, the info is always
1778+ notified to userspace.
1779+ For example, the number of free inodes is generally large enough and
1780+ the shortage of it happens rarely. So aufs doesn't force the
1781+ notification when creating a new file, directory and others. This is
1782+ the typical case which aufs doesn't force.
1783+ When aufs writes the actual filedata and the files consumes any of new
1784+ blocks, the aufs forces notifying.
1785+
1786+
1787+o Interfaces in aufs
1788+- New branch attribute.
1789+ + fhsm
1790+ Specifies that the branch is managed by FHSM feature. In other word,
1791+ participant in the FHSM.
1792+ When nofhsm is set to the branch, it will not be the source/target
1793+ branch of the move-down operation. This attribute is set
1794+ independently from coo and moo attributes, and if you want full
1795+ FHSM, you should specify them as well.
1796+- New mount option.
1797+ + fhsm_sec
1798+ Specifies a second to suppress many less important info to be
1799+ notified.
1800+- New ioctl.
1801+ + AUFS_CTL_FHSM_FD
1802+ create a new file descriptor which userspace can read the notification
1803+ (a subset of struct statfs) from aufs.
1804+- Module parameter 'brs'
1805+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
1806+ be set.
1807+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
1808+ When there are two or more branches with fhsm attributes,
1809+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
1810+ terminates it. As a result of remounting and branch-manipulation, the
1811+ number of branches with fhsm attribute can be one. In this case,
1812+ /sbin/mount.aufs will terminate the user-space daemon.
1813+
1814+
1815+Finally the operation is done as these steps in kernel-space.
1816+- make sure that,
1817+ + no one else is using the file.
1818+ + the file is not hard-linked.
1819+ + the file is not pseudo-linked.
1820+ + the file is a regular file.
1821+ + the parent dir is not opaqued.
1822+- find the target writable branch.
1823+- make sure the file is not whiteout-ed by the upper (than the target)
1824+ branch.
1825+- make the parent dir on the target branch.
1826+- mutex lock the inode on the branch.
1827+- unlink the whiteout on the target branch (if exists).
1828+- lookup and create the whiteout-ed temporary name on the target branch.
1829+- copy the file as the whiteout-ed temporary name on the target branch.
1830+- rename the whiteout-ed temporary name to the original name.
1831+- unlink the file on the source branch.
1832+- maintain the internal pointer array and the external inode number
1833+ table (XINO).
1834+- maintain the timestamps and other attributes of the parent dir and the
1835+ file.
1836+
1837+And of course, in every step, an error may happen. So the operation
1838+should restore the original file state after an error happens.
53392da6
AM
1839diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1840--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1841+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2015-03-27 21:56:35.460128334 +0100
523b37e3 1842@@ -0,0 +1,46 @@
53392da6 1843+
2000de60 1844+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1845+#
1846+# This program is free software; you can redistribute it and/or modify
1847+# it under the terms of the GNU General Public License as published by
1848+# the Free Software Foundation; either version 2 of the License, or
1849+# (at your option) any later version.
1850+#
1851+# This program is distributed in the hope that it will be useful,
1852+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1853+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1854+# GNU General Public License for more details.
1855+#
1856+# You should have received a copy of the GNU General Public License
523b37e3 1857+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1858+
1859+mmap(2) -- File Memory Mapping
1860+----------------------------------------------------------------------
1861+In aufs, the file-mapped pages are handled by a branch fs directly, no
1862+interaction with aufs. It means aufs_mmap() calls the branch fs's
1863+->mmap().
1864+This approach is simple and good, but there is one problem.
1865+Under /proc, several entries show the mmap-ped files by its path (with
1866+device and inode number), and the printed path will be the path on the
1867+branch fs's instead of virtual aufs's.
1868+This is not a problem in most cases, but some utilities lsof(1) (and its
1869+user) may expect the path on aufs.
1870+
1871+To address this issue, aufs adds a new member called vm_prfile in struct
1872+vm_area_struct (and struct vm_region). The original vm_file points to
1873+the file on the branch fs in order to handle everything correctly as
1874+usual. The new vm_prfile points to a virtual file in aufs, and the
1875+show-functions in procfs refers to vm_prfile if it is set.
1876+Also we need to maintain several other places where touching vm_file
1877+such like
1878+- fork()/clone() copies vma and the reference count of vm_file is
1879+ incremented.
1880+- merging vma maintains the ref count too.
1881+
1882+This is not a good approach. It just faking the printed path. But it
1883+leaves all behaviour around f_mapping unchanged. This is surely an
1884+advantage.
1885+Actually aufs had adopted another complicated approach which calls
1886+generic_file_mmap() and handles struct vm_operations_struct. In this
1887+approach, aufs met a hard problem and I could not solve it without
1888+switching the approach.
c1595e42
JR
1889diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
1890--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1891+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2015-03-27 21:56:35.460128334 +0100
c1595e42
JR
1892@@ -0,0 +1,96 @@
1893+
2000de60 1894+# Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
1895+#
1896+# This program is free software; you can redistribute it and/or modify
1897+# it under the terms of the GNU General Public License as published by
1898+# the Free Software Foundation; either version 2 of the License, or
1899+# (at your option) any later version.
1900+#
1901+# This program is distributed in the hope that it will be useful,
1902+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1903+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1904+# GNU General Public License for more details.
1905+#
1906+# You should have received a copy of the GNU General Public License
1907+# along with this program; if not, write to the Free Software
1908+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1909+
1910+
1911+Listing XATTR/EA and getting the value
1912+----------------------------------------------------------------------
1913+For the inode standard attributes (owner, group, timestamps, etc.), aufs
1914+shows the values from the topmost existing file. This behaviour is good
1915+for the non-dir entreis since the bahaviour exactly matches the shown
1916+information. But for the directories, aufs considers all the same named
1917+entries on the lower branches. Which means, if one of the lower entry
1918+rejects readdir call, then aufs returns an error even if the topmost
1919+entry allows it. This behaviour is necessary to respect the branch fs's
1920+security, but can make users confused since the user-visible standard
1921+attributes don't match the behaviour.
1922+To address this issue, aufs has a mount option called dirperm1 which
1923+checks the permission for the topmost entry only, and ignores the lower
1924+entry's permission.
1925+
1926+A similar issue can happen around XATTR.
1927+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
1928+always set. Otherwise these very unpleasant situation can happen.
1929+- listxattr(2) may return the duplicated entires.
1930+- users may not be able to remove or reset the XATTR forever,
1931+
1932+
1933+XATTR/EA support in the internal (copy,move)-(up,down)
1934+----------------------------------------------------------------------
1935+Generally the extended attributes of inode are categorazied as these.
1936+- "security" for LSM and capability.
1937+- "system" for posix ACL, 'acl' mount option is required for the branch
1938+ fs generally.
1939+- "trusted" for userspace, CAP_SYS_ADMIN is required.
1940+- "user" for userspace, 'user_xattr' mount option is required for the
1941+ branch fs generally.
1942+
1943+Moreover there are some other categories. Aufs handles these rather
1944+unpopular categories as the ordinary ones, ie. there is no special
1945+condition nor exception.
1946+
1947+In copy-up, the support for XATTR on the dst branch may differ from the
1948+src branch. In this case, the copy-up operation will get an error and
1949+the original user operation which triggered the copy-up fails. It can
1950+happen that even all copy-up will fail.
1951+When both of src and dst branches support XATTR and if an error occurs
1952+during copying XATTR, then the copy-up should fail obviously. That is a
1953+good reason and aufs should return an error to userspace. But when only
1954+the src branch support XATTR, aufs should not return an error.
1955+For example, the src branch supports ACL but the dst branch doesn't
1956+because the dst branch may natively un-support it or temporary
1957+un-support it due to "noacl" mount option. Of course, the dst branch fs
1958+may NOT return an error even if the XATTR is not supported. It is
1959+totally up to the branch fs.
1960+
1961+Anyway when the aufs internal copy-up gets an error from the dst branch
1962+fs, then aufs tries removing the just copied entry and returns the error
1963+to the userspace. The worst case of this situation will be all copy-up
1964+will fail.
1965+
1966+For the copy-up operation, there two basic approaches.
1967+- copy the specified XATTR only (by category above), and return the
1968+ error if it happens inconditionally.
1969+- copy all XATTR, and ignore the error on the specified category only.
1970+
1971+In order to support XATTR and to implement the correct behaviour, aufs
1972+chooses the latter approach and introduces some attributes for its
1973+branch, "icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
1974+They correspond to the XATTR namespaces (see above). Additionally, to be
1975+convenient, "icex" is also provided which means all "ix*" attributes are
1976+set.
1977+
1978+The meaning of these attributes is to ignore the error from setting
1979+XATTR on that branch.
1980+Note that aufs tries copying all XATTR unconditionally, and ignores the
1981+error from the dst branch according to the specified attributes.
1982+
1983+Some XATTR may have its default value. The default value may come from
1984+the parent dir or the environment. If the default value is set at the
1985+file creating-time, it will be overwritten by copy-up.
1986+Some contradiction may happen I am afraid.
1987+Do we need another attribute to stop copying XATTR? I am unsure. For
1988+now, aufs implements the branch attributes to ignore the error.
53392da6
AM
1989diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1990--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 1991+++ linux/Documentation/filesystems/aufs/design/07export.txt 2015-03-27 21:56:35.460128334 +0100
523b37e3 1992@@ -0,0 +1,58 @@
53392da6 1993+
2000de60 1994+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
1995+#
1996+# This program is free software; you can redistribute it and/or modify
1997+# it under the terms of the GNU General Public License as published by
1998+# the Free Software Foundation; either version 2 of the License, or
1999+# (at your option) any later version.
2000+#
2001+# This program is distributed in the hope that it will be useful,
2002+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2003+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2004+# GNU General Public License for more details.
2005+#
2006+# You should have received a copy of the GNU General Public License
523b37e3 2007+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2008+
2009+Export Aufs via NFS
2010+----------------------------------------------------------------------
2011+Here is an approach.
2012+- like xino/xib, add a new file 'xigen' which stores aufs inode
2013+ generation.
2014+- iget_locked(): initialize aufs inode generation for a new inode, and
2015+ store it in xigen file.
2016+- destroy_inode(): increment aufs inode generation and store it in xigen
2017+ file. it is necessary even if it is not unlinked, because any data of
2018+ inode may be changed by UDBA.
2019+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
2020+ build file handle by
2021+ + branch id (4 bytes)
2022+ + superblock generation (4 bytes)
2023+ + inode number (4 or 8 bytes)
2024+ + parent dir inode number (4 or 8 bytes)
2025+ + inode generation (4 bytes))
2026+ + return value of exportfs_encode_fh() for the parent on a branch (4
2027+ bytes)
2028+ + file handle for a branch (by exportfs_encode_fh())
2029+- fh_to_dentry():
2030+ + find the index of a branch from its id in handle, and check it is
2031+ still exist in aufs.
2032+ + 1st level: get the inode number from handle and search it in cache.
2033+ + 2nd level: if not found, get the parent inode number from handle and
2034+ search it in cache. and then open the parent dir, find the matching
2035+ inode number by vfs_readdir() and get its name, and call
2036+ lookup_one_len() for the target dentry.
2037+ + 3rd level: if the parent dir is not cached, call
2038+ exportfs_decode_fh() for a branch and get the parent on a branch,
2039+ build a pathname of it, convert it a pathname in aufs, call
2040+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
2041+ the 2nd level.
2042+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
2043+ for every branch, but not itself. to get this, (currently) aufs
2044+ searches in current->nsproxy->mnt_ns list. it may not be a good
2045+ idea, but I didn't get other approach.
2046+ + test the generation of the gotten inode.
2047+- every inode operation: they may get EBUSY due to UDBA. in this case,
2048+ convert it into ESTALE for NFSD.
2049+- readdir(): call lockdep_on/off() because filldir in NFSD calls
2050+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
2051diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
2052--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 2053+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2015-03-27 21:56:35.460128334 +0100
523b37e3 2054@@ -0,0 +1,52 @@
53392da6 2055+
2000de60 2056+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
2057+#
2058+# This program is free software; you can redistribute it and/or modify
2059+# it under the terms of the GNU General Public License as published by
2060+# the Free Software Foundation; either version 2 of the License, or
2061+# (at your option) any later version.
2062+#
2063+# This program is distributed in the hope that it will be useful,
2064+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2065+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2066+# GNU General Public License for more details.
2067+#
2068+# You should have received a copy of the GNU General Public License
523b37e3 2069+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2070+
2071+Show Whiteout Mode (shwh)
2072+----------------------------------------------------------------------
2073+Generally aufs hides the name of whiteouts. But in some cases, to show
2074+them is very useful for users. For instance, creating a new middle layer
2075+(branch) by merging existing layers.
2076+
2077+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2078+When you have three branches,
2079+- Bottom: 'system', squashfs (underlying base system), read-only
2080+- Middle: 'mods', squashfs, read-only
2081+- Top: 'overlay', ram (tmpfs), read-write
2082+
2083+The top layer is loaded at boot time and saved at shutdown, to preserve
2084+the changes made to the system during the session.
2085+When larger changes have been made, or smaller changes have accumulated,
2086+the size of the saved top layer data grows. At this point, it would be
2087+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2088+and rewrite the 'mods' squashfs, clearing the top layer and thus
2089+restoring save and load speed.
2090+
2091+This merging is simplified by the use of another aufs mount, of just the
2092+two overlay branches using the 'shwh' option.
2093+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2094+ aufs /livesys/merge_union
2095+
2096+A merged view of these two branches is then available at
2097+/livesys/merge_union, and the new feature is that the whiteouts are
2098+visible!
2099+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2100+writing to all branches. Also the default mode for all branches is 'ro'.
2101+It is now possible to save the combined contents of the two overlay
2102+branches to a new squashfs, e.g.:
2103+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2104+
2105+This new squashfs archive can be stored on the boot device and the
2106+initramfs will use it to replace the old one at the next boot.
2107diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2108--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 2109+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2015-03-27 21:56:35.460128334 +0100
523b37e3 2110@@ -0,0 +1,46 @@
53392da6 2111+
2000de60 2112+# Copyright (C) 2010-2015 Junjiro R. Okajima
53392da6
AM
2113+#
2114+# This program is free software; you can redistribute it and/or modify
2115+# it under the terms of the GNU General Public License as published by
2116+# the Free Software Foundation; either version 2 of the License, or
2117+# (at your option) any later version.
2118+#
2119+# This program is distributed in the hope that it will be useful,
2120+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2121+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2122+# GNU General Public License for more details.
2123+#
2124+# You should have received a copy of the GNU General Public License
523b37e3 2125+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2126+
2127+Dynamically customizable FS operations
2128+----------------------------------------------------------------------
2129+Generally FS operations (struct inode_operations, struct
2130+address_space_operations, struct file_operations, etc.) are defined as
2131+"static const", but it never means that FS have only one set of
2132+operation. Some FS have multiple sets of them. For instance, ext2 has
2133+three sets, one for XIP, for NOBH, and for normal.
2134+Since aufs overrides and redirects these operations, sometimes aufs has
2135+to change its behaviour according to the branch FS type. More imporantly
2136+VFS acts differently if a function (member in the struct) is set or
2137+not. It means aufs should have several sets of operations and select one
2138+among them according to the branch FS definition.
2139+
2140+In order to solve this problem and not to affect the behavour of VFS,
2141+aufs defines these operations dynamically. For instance, aufs defines
2142+aio_read function for struct file_operations, but it may not be set to
2143+the file_operations. When the branch FS doesn't have it, aufs doesn't
2144+set it to its file_operations while the function definition itself is
2145+still alive. So the behaviour of io_submit(2) will not change, and it
2146+will return an error when aio_read is not defined.
2147+
2148+The lifetime of these dynamically generated operation object is
2149+maintained by aufs branch object. When the branch is removed from aufs,
2150+the reference counter of the object is decremented. When it reaches
2151+zero, the dynamically generated operation object will be freed.
2152+
2153+This approach is designed to support AIO (io_submit), Direcit I/O and
2154+XIP mainly.
2155+Currently this approach is applied to file_operations and
2156+vm_operations_struct for regular files only.
2157diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
2158--- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
2000de60 2159+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2015-03-27 21:56:35.460128334 +0100
076b876e 2160@@ -0,0 +1,58 @@
53392da6 2161+
2000de60 2162+# Copyright (C) 2005-2015 Junjiro R. Okajima
53392da6
AM
2163+#
2164+# This program is free software; you can redistribute it and/or modify
2165+# it under the terms of the GNU General Public License as published by
2166+# the Free Software Foundation; either version 2 of the License, or
2167+# (at your option) any later version.
2168+#
2169+# This program is distributed in the hope that it will be useful,
2170+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2171+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2172+# GNU General Public License for more details.
2173+#
2174+# You should have received a copy of the GNU General Public License
523b37e3 2175+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2176+
2177+Plan
2178+
2179+Restoring some features which was implemented in aufs1.
2180+They were dropped in aufs2 in order to make source files simpler and
2181+easier to be reviewed.
2182+
2183+
53392da6
AM
2184+Being Another Aufs's Readonly Branch (robr)
2185+----------------------------------------------------------------------
2186+Aufs1 allows aufs to be another aufs's readonly branch.
2187+This feature was developed by a user's request. But it may not be used
2188+currecnly.
2189+
2190+
53392da6
AM
2191+Refresh the Opened File (refrof)
2192+----------------------------------------------------------------------
2193+This option is implemented in aufs1 but incomplete.
2194+
2195+When user reads from a file, he expects to get its latest filedata
2196+generally. If the file is removed and a new same named file is created,
2197+the content he gets is unchanged, ie. the unlinked filedata.
2198+
2199+Let's try case study again.
2200+- aufs has two branches.
2201+ /au = /rw + /ro
2202+- "fileA" exists under /ro, but /rw.
2203+- user opened "/au/fileA".
2204+- he or someone else inserts a branch (/new) between /rw and /ro.
2205+ /au = /rw + /new + /ro
2206+- the new branch has "fileA".
2207+- user reads from the opened "fileA"
2208+- which filedata should aufs return, from /ro or /new?
2209+
2210+Some people says it has to be "from /ro" and it is a semantics of Unix.
2211+The others say it should be "from /new" because the file is not removed
2212+and it is equivalent to the case of someone else modifies the file.
2213+
2214+Here again I don't have a best and final answer. I got an idea to
2215+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
2216+Opened File) is specified (by default), aufs returns the filedata from
2217+/new.
2218+Otherwise from /new.
2219diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2220--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
2221+++ linux/Documentation/filesystems/aufs/README 2015-03-27 21:56:35.456795001 +0100
2222@@ -0,0 +1,389 @@
53392da6
AM
2223+
2224+Aufs3 -- advanced multi layered unification filesystem version 3.x
2225+http://aufs.sf.net
2226+Junjiro R. Okajima
2227+
2228+
2229+0. Introduction
2230+----------------------------------------
2231+In the early days, aufs was entirely re-designed and re-implemented
2232+Unionfs Version 1.x series. After many original ideas, approaches,
2233+improvements and implementations, it becomes totally different from
2234+Unionfs while keeping the basic features.
2235+Recently, Unionfs Version 2.x series begin taking some of the same
2236+approaches to aufs1's.
2237+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2238+University and his team.
2239+
2240+Aufs3 supports linux-3.0 and later.
2241+If you want older kernel version support, try aufs2-2.6.git or
2242+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2243+
2244+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2245+ According to Christoph Hellwig, linux rejects all union-type
2246+ filesystems but UnionMount.
53392da6
AM
2247+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2248+
38d290e6
JR
2249+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2250+ UnionMount, and he pointed out an issue around a directory mutex
2251+ lock and aufs addressed it. But it is still unsure whether aufs will
2252+ be merged (or any other union solution).
076b876e 2253+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2254+
53392da6
AM
2255+
2256+1. Features
2257+----------------------------------------
2258+- unite several directories into a single virtual filesystem. The member
2259+ directory is called as a branch.
2260+- you can specify the permission flags to the branch, which are 'readonly',
2261+ 'readwrite' and 'whiteout-able.'
2262+- by upper writable branch, internal copyup and whiteout, files/dirs on
2263+ readonly branch are modifiable logically.
2264+- dynamic branch manipulation, add, del.
2265+- etc...
2266+
2267+Also there are many enhancements in aufs1, such as:
2268+- readdir(3) in userspace.
2269+- keep inode number by external inode number table
2270+- keep the timestamps of file/dir in internal copyup operation
2271+- seekable directory, supporting NFS readdir.
2272+- whiteout is hardlinked in order to reduce the consumption of inodes
2273+ on branch
2274+- do not copyup, nor create a whiteout when it is unnecessary
2275+- revert a single systemcall when an error occurs in aufs
2276+- remount interface instead of ioctl
2277+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2278+- loopback mounted filesystem as a branch
2279+- kernel thread for removing the dir who has a plenty of whiteouts
2280+- support copyup sparse file (a file which has a 'hole' in it)
2281+- default permission flags for branches
2282+- selectable permission flags for ro branch, whether whiteout can
2283+ exist or not
2284+- export via NFS.
2285+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2286+- support multiple writable branches, some policies to select one
2287+ among multiple writable branches.
2288+- a new semantics for link(2) and rename(2) to support multiple
2289+ writable branches.
2290+- no glibc changes are required.
2291+- pseudo hardlink (hardlink over branches)
2292+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2293+ including NFS or remote filesystem branch.
2294+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2295+- and more...
2296+
2297+Currently these features are dropped temporary from aufs3.
2298+See design/08plan.txt in detail.
2299+- test only the highest one for the directory permission (dirperm1)
2300+- copyup on open (coo=)
2301+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2302+ (robr)
2303+- statistics of aufs thread (/sys/fs/aufs/stat)
2304+- delegation mode (dlgt)
2305+ a delegation of the internal branch access to support task I/O
2306+ accounting, which also supports Linux Security Modules (LSM) mainly
2307+ for Suse AppArmor.
2308+- intent.open/create (file open in a single lookup)
2309+
2310+Features or just an idea in the future (see also design/*.txt),
2311+- reorder the branch index without del/re-add.
2312+- permanent xino files for NFSD
2313+- an option for refreshing the opened files after add/del branches
2314+- 'move' policy for copy-up between two writable branches, after
2315+ checking free space.
2316+- light version, without branch manipulation. (unnecessary?)
2317+- copyup in userspace
2318+- inotify in userspace
2319+- readv/writev
2320+- xattr, acl
2321+
2322+
2323+2. Download
2324+----------------------------------------
1e00d052
AM
2325+There were three GIT trees for aufs3, aufs3-linux.git,
2326+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
2327+"aufs-util.git."
2328+While the aufs-util is always necessary, you need either of aufs3-linux
2329+or aufs3-standalone.
2330+
2331+The aufs3-linux tree includes the whole linux mainline GIT tree,
2332+git://git.kernel.org/.../torvalds/linux.git.
2333+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
b4510431 2334+build aufs3 as an external kernel module.
2000de60
JR
2335+Several extra patches are not included in this tree. Only
2336+aufs3-standalong tree contains them. They are describe in the later
2337+section "Configuration and Compilation."
1e00d052
AM
2338+
2339+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6 2340+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2000de60 2341+But you need to apply all aufs patches manually.
53392da6
AM
2342+
2343+You will find GIT branches whose name is in form of "aufs3.x" where "x"
2344+represents the linux kernel version, "linux-3.x". For instance,
1e00d052
AM
2345+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
2346+"aufs3.x-rcN" branch.
2347+
2348+o aufs3-linux tree
2349+$ git clone --reference /your/linux/git/tree \
2000de60 2350+ git://git.code.sf.net/p/aufs/aufs3-linux aufs3-linux.git
1e00d052
AM
2351+- if you don't have linux GIT tree, then remove "--reference ..."
2352+$ cd aufs3-linux.git
2353+$ git checkout origin/aufs3.0
53392da6 2354+
2000de60
JR
2355+Or You may want to directly git-pull aufs into your linux GIT tree, and
2356+leave the patch-work to GIT.
2357+$ cd /your/linux/git/tree
2358+$ git remote add aufs3 https://github.com/sfjro/aufs3-linux.git
2359+- aufs3-linux.git tree also exists on github.
2360+$ git fetch aufs3
2361+$ git checkout -b my3.14 v3.14
2362+$ (add your change...)
2363+$ git pull aufs3 aufs3.14
2364+- now you have v3.14 + your_changes + aufs3.14 in you my3.14 branch.
2365+- you may need to solve some conflicts between your_changes and
2366+ aufs3.14. in this case, git-rerere is recommended so that you can
2367+ solve the similar confilicts automatically when you upgrade to 3.15 or
2368+ later in the future.
2369+
53392da6 2370+o aufs3-standalone tree
86dc4139 2371+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
53392da6
AM
2372+ aufs3-standalone.git
2373+$ cd aufs3-standalone.git
2374+$ git checkout origin/aufs3.0
2375+
2376+o aufs-util tree
86dc4139 2377+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
53392da6
AM
2378+ aufs-util.git
2379+$ cd aufs-util.git
2380+$ git checkout origin/aufs3.0
2381+
9dbd164d
AM
2382+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
2383+The minor version number, 'x' in '3.x', of aufs may not always
2384+follow the minor version number of the kernel.
2385+Because changes in the kernel that cause the use of a new
2386+minor version number do not always require changes to aufs-util.
2387+
2388+Since aufs-util has its own minor version number, you may not be
2389+able to find a GIT branch in aufs-util for your kernel's
2390+exact minor version number.
2391+In this case, you should git-checkout the branch for the
53392da6 2392+nearest lower number.
9dbd164d
AM
2393+
2394+For (an unreleased) example:
2395+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 2396+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
2397+or something numerically smaller is the branch for your kernel.
2398+
53392da6
AM
2399+Also you can view all branches by
2400+ $ git branch -a
2401+
2402+
2403+3. Configuration and Compilation
2404+----------------------------------------
2405+Make sure you have git-checkout'ed the correct branch.
2406+
1e00d052 2407+For aufs3-linux tree,
c06a8ce3 2408+- enable CONFIG_AUFS_FS.
1e00d052
AM
2409+- set other aufs configurations if necessary.
2410+
53392da6
AM
2411+For aufs3-standalone tree,
2412+There are several ways to build.
2413+
2414+1.
2415+- apply ./aufs3-kbuild.patch to your kernel source files.
2416+- apply ./aufs3-base.patch too.
523b37e3 2417+- apply ./aufs3-mmap.patch too.
53392da6
AM
2418+- apply ./aufs3-standalone.patch too, if you have a plan to set
2419+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
537831f9
AM
2420+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2421+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2422+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2423+ =m or =y.
2424+- and build your kernel as usual.
2425+- install the built kernel.
c06a8ce3
AM
2426+ Note: Since linux-3.9, every filesystem module requires an alias
2427+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2428+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2429+- install the header files too by "make headers_install" to the
2430+ directory where you specify. By default, it is $PWD/usr.
b4510431 2431+ "make help" shows a brief note for headers_install.
53392da6
AM
2432+- and reboot your system.
2433+
2434+2.
2435+- module only (CONFIG_AUFS_FS=m).
2436+- apply ./aufs3-base.patch to your kernel source files.
523b37e3 2437+- apply ./aufs3-mmap.patch too.
53392da6
AM
2438+- apply ./aufs3-standalone.patch too.
2439+- build your kernel, don't forget "make headers_install", and reboot.
2440+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2441+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2442+ every aufs configurations.
2443+- build the module by simple "make".
c06a8ce3
AM
2444+ Note: Since linux-3.9, every filesystem module requires an alias
2445+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2446+ modules.aliases file.
53392da6
AM
2447+- you can specify ${KDIR} make variable which points to your kernel
2448+ source tree.
2449+- install the files
2450+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2451+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2452+ + run "make install_headers" (instead of headers_install) to install
2453+ the modified aufs header file (you can specify DESTDIR which is
2454+ available in aufs standalone version's Makefile only), or copy
2455+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2456+ you like manually. By default, the target directory is $PWD/usr.
53392da6
AM
2457+- no need to apply aufs3-kbuild.patch, nor copying source files to your
2458+ kernel source tree.
2459+
b4510431 2460+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2461+ as well as "make headers_install" in the kernel source tree.
2462+ headers_install is subject to be forgotten, but it is essentially
2463+ necessary, not only for building aufs-util.
2464+ You may not meet problems without headers_install in some older
2465+ version though.
2466+
2467+And then,
2468+- read README in aufs-util, build and install it
9dbd164d
AM
2469+- note that your distribution may contain an obsoleted version of
2470+ aufs_type.h in /usr/include/linux or something. When you build aufs
2471+ utilities, make sure that your compiler refers the correct aufs header
2472+ file which is built by "make headers_install."
53392da6
AM
2473+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2474+ then run "make install_ulib" too. And refer to the aufs manual in
2475+ detail.
2476+
38d290e6
JR
2477+There several other patches in aufs3-standalone.git. They are all
2478+optional. When you meet some problems, they will help you.
2479+- aufs3-loopback.patch
2480+ Supports a nested loopback mount in a branch-fs. This patch is
2481+ unnecessary until aufs produces a message like "you may want to try
2482+ another patch for loopback file".
2483+- vfs-ino.patch
2484+ Modifies a system global kernel internal function get_next_ino() in
2485+ order to stop assigning 0 for an inode-number. Not directly related to
2486+ aufs, but recommended generally.
2487+- tmpfs-idr.patch
2488+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2489+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2490+ duplication of inode number, which is important for backup tools and
2491+ other utilities. When you find aufs XINO files for tmpfs branch
2492+ growing too much, try this patch.
2493+
53392da6
AM
2494+
2495+4. Usage
2496+----------------------------------------
2497+At first, make sure aufs-util are installed, and please read the aufs
2498+manual, aufs.5 in aufs-util.git tree.
2499+$ man -l aufs.5
2500+
2501+And then,
2502+$ mkdir /tmp/rw /tmp/aufs
2503+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2504+
2505+Here is another example. The result is equivalent.
2506+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2507+ Or
2508+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2509+# mount -o remount,append:${HOME} /tmp/aufs
2510+
2511+Then, you can see whole tree of your home dir through /tmp/aufs. If
2512+you modify a file under /tmp/aufs, the one on your home directory is
2513+not affected, instead the same named file will be newly created under
2514+/tmp/rw. And all of your modification to a file will be applied to
2515+the one under /tmp/rw. This is called the file based Copy on Write
2516+(COW) method.
2517+Aufs mount options are described in aufs.5.
2518+If you run chroot or something and make your aufs as a root directory,
2519+then you need to customize the shutdown script. See the aufs manual in
2520+detail.
2521+
2522+Additionally, there are some sample usages of aufs which are a
2523+diskless system with network booting, and LiveCD over NFS.
2524+See sample dir in CVS tree on SourceForge.
2525+
2526+
2527+5. Contact
2528+----------------------------------------
2529+When you have any problems or strange behaviour in aufs, please let me
2530+know with:
2531+- /proc/mounts (instead of the output of mount(8))
2532+- /sys/module/aufs/*
2533+- /sys/fs/aufs/* (if you have them)
2534+- /debug/aufs/* (if you have them)
2535+- linux kernel version
2536+ if your kernel is not plain, for example modified by distributor,
2537+ the url where i can download its source is necessary too.
2538+- aufs version which was printed at loading the module or booting the
2539+ system, instead of the date you downloaded.
2540+- configuration (define/undefine CONFIG_AUFS_xxx)
2541+- kernel configuration or /proc/config.gz (if you have it)
2542+- behaviour which you think to be incorrect
2543+- actual operation, reproducible one is better
2544+- mailto: aufs-users at lists.sourceforge.net
2545+
2546+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2547+and Feature Requests) on SourceForge. Please join and write to
2548+aufs-users ML.
2549+
2550+
2551+6. Acknowledgements
2552+----------------------------------------
2553+Thanks to everyone who have tried and are using aufs, whoever
2554+have reported a bug or any feedback.
2555+
2556+Especially donators:
2557+Tomas Matejicek(slax.org) made a donation (much more than once).
2558+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2559+ scripts) is making "doubling" donations.
2560+ Unfortunately I cannot list all of the donators, but I really
b4510431 2561+ appreciate.
53392da6
AM
2562+ It ends Aug 2010, but the ordinary donation URL is still available.
2563+ <http://sourceforge.net/donate/index.php?group_id=167503>
2564+Dai Itasaka made a donation (2007/8).
2565+Chuck Smith made a donation (2008/4, 10 and 12).
2566+Henk Schoneveld made a donation (2008/9).
2567+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2568+Francois Dupoux made a donation (2008/11).
2569+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2570+ aufs2 GIT tree (2009/2).
2571+William Grant made a donation (2009/3).
2572+Patrick Lane made a donation (2009/4).
2573+The Mail Archive (mail-archive.com) made donations (2009/5).
2574+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2575+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2576+Pavel Pronskiy made a donation (2011/2).
2577+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2578+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
2579+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2580+11).
1e00d052 2581+Sam Liddicott made a donation (2011/9).
86dc4139
AM
2582+Era Scarecrow made a donation (2013/4).
2583+Bor Ratajc made a donation (2013/4).
2584+Alessandro Gorreta made a donation (2013/4).
2585+POIRETTE Marc made a donation (2013/4).
2586+Alessandro Gorreta made a donation (2013/4).
2587+lauri kasvandik made a donation (2013/5).
392086de 2588+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
2589+The Parted Magic Project made a donation (2013/9 and 11).
2590+Pavel Barta made a donation (2013/10).
38d290e6 2591+Nikolay Pertsev made a donation (2014/5).
076b876e
AM
2592+James B made a donation (2014/7).
2593+Stefano Di Biase made a donation (2014/8).
2000de60 2594+Daniel Epellei made a donation (2015/1).
53392da6
AM
2595+
2596+Thank you very much.
2597+Donations are always, including future donations, very important and
2598+helpful for me to keep on developing aufs.
2599+
2600+
2601+7.
2602+----------------------------------------
2603+If you are an experienced user, no explanation is needed. Aufs is
2604+just a linux filesystem.
2605+
2606+
2607+Enjoy!
2608+
2609+# Local variables: ;
2610+# mode: text;
2611+# End: ;
7f207e10
AM
2612diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
2613--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
2000de60 2614+++ linux/fs/aufs/aufs.h 2015-03-27 21:56:35.460128334 +0100
523b37e3 2615@@ -0,0 +1,59 @@
7f207e10 2616+/*
2000de60 2617+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
2618+ *
2619+ * This program, aufs is free software; you can redistribute it and/or modify
2620+ * it under the terms of the GNU General Public License as published by
2621+ * the Free Software Foundation; either version 2 of the License, or
2622+ * (at your option) any later version.
2623+ *
2624+ * This program is distributed in the hope that it will be useful,
2625+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2626+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2627+ * GNU General Public License for more details.
2628+ *
2629+ * You should have received a copy of the GNU General Public License
523b37e3 2630+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2631+ */
2632+
2633+/*
2634+ * all header files
2635+ */
2636+
2637+#ifndef __AUFS_H__
2638+#define __AUFS_H__
2639+
2640+#ifdef __KERNEL__
2641+
2642+#define AuStub(type, name, body, ...) \
2643+ static inline type name(__VA_ARGS__) { body; }
2644+
2645+#define AuStubVoid(name, ...) \
2646+ AuStub(void, name, , __VA_ARGS__)
2647+#define AuStubInt0(name, ...) \
2648+ AuStub(int, name, return 0, __VA_ARGS__)
2649+
2650+#include "debug.h"
2651+
2652+#include "branch.h"
2653+#include "cpup.h"
2654+#include "dcsub.h"
2655+#include "dbgaufs.h"
2656+#include "dentry.h"
2657+#include "dir.h"
2658+#include "dynop.h"
2659+#include "file.h"
2660+#include "fstype.h"
2661+#include "inode.h"
2662+#include "loop.h"
2663+#include "module.h"
7f207e10
AM
2664+#include "opts.h"
2665+#include "rwsem.h"
2666+#include "spl.h"
2667+#include "super.h"
2668+#include "sysaufs.h"
2669+#include "vfsub.h"
2670+#include "whout.h"
2671+#include "wkq.h"
2672+
2673+#endif /* __KERNEL__ */
2674+#endif /* __AUFS_H__ */
2675diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
2676--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
2677+++ linux/fs/aufs/branch.c 2015-03-27 21:56:35.460128334 +0100
2678@@ -0,0 +1,1408 @@
7f207e10 2679+/*
2000de60 2680+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
2681+ *
2682+ * This program, aufs is free software; you can redistribute it and/or modify
2683+ * it under the terms of the GNU General Public License as published by
2684+ * the Free Software Foundation; either version 2 of the License, or
2685+ * (at your option) any later version.
2686+ *
2687+ * This program is distributed in the hope that it will be useful,
2688+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2689+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2690+ * GNU General Public License for more details.
2691+ *
2692+ * You should have received a copy of the GNU General Public License
523b37e3 2693+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2694+ */
2695+
2696+/*
2697+ * branch management
2698+ */
2699+
027c5e7a 2700+#include <linux/compat.h>
7f207e10
AM
2701+#include <linux/statfs.h>
2702+#include "aufs.h"
2703+
2704+/*
2705+ * free a single branch
1facf9fc 2706+ */
2707+static void au_br_do_free(struct au_branch *br)
2708+{
2709+ int i;
2710+ struct au_wbr *wbr;
4a4d8108 2711+ struct au_dykey **key;
1facf9fc 2712+
027c5e7a
AM
2713+ au_hnotify_fin_br(br);
2714+
1facf9fc 2715+ if (br->br_xino.xi_file)
2716+ fput(br->br_xino.xi_file);
2717+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
2718+
2719+ AuDebugOn(atomic_read(&br->br_count));
2720+
2721+ wbr = br->br_wbr;
2722+ if (wbr) {
2723+ for (i = 0; i < AuBrWh_Last; i++)
2724+ dput(wbr->wbr_wh[i]);
2725+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 2726+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 2727+ }
2728+
076b876e
AM
2729+ if (br->br_fhsm) {
2730+ au_br_fhsm_fin(br->br_fhsm);
2731+ kfree(br->br_fhsm);
2732+ }
2733+
4a4d8108
AM
2734+ key = br->br_dykey;
2735+ for (i = 0; i < AuBrDynOp; i++, key++)
2736+ if (*key)
2737+ au_dy_put(*key);
2738+ else
2739+ break;
2740+
537831f9
AM
2741+ /* recursive lock, s_umount of branch's */
2742+ lockdep_off();
86dc4139 2743+ path_put(&br->br_path);
537831f9 2744+ lockdep_on();
1facf9fc 2745+ kfree(wbr);
2746+ kfree(br);
2747+}
2748+
2749+/*
2750+ * frees all branches
2751+ */
2752+void au_br_free(struct au_sbinfo *sbinfo)
2753+{
2754+ aufs_bindex_t bmax;
2755+ struct au_branch **br;
2756+
dece6358
AM
2757+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2758+
1facf9fc 2759+ bmax = sbinfo->si_bend + 1;
2760+ br = sbinfo->si_branch;
2761+ while (bmax--)
2762+ au_br_do_free(*br++);
2763+}
2764+
2765+/*
2766+ * find the index of a branch which is specified by @br_id.
2767+ */
2768+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2769+{
2770+ aufs_bindex_t bindex, bend;
2771+
2772+ bend = au_sbend(sb);
2773+ for (bindex = 0; bindex <= bend; bindex++)
2774+ if (au_sbr_id(sb, bindex) == br_id)
2775+ return bindex;
2776+ return -1;
2777+}
2778+
2779+/* ---------------------------------------------------------------------- */
2780+
2781+/*
2782+ * add a branch
2783+ */
2784+
b752ccd1
AM
2785+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2786+ struct dentry *h_root)
1facf9fc 2787+{
b752ccd1
AM
2788+ if (unlikely(h_adding == h_root
2789+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2790+ return 1;
b752ccd1
AM
2791+ if (h_adding->d_sb != h_root->d_sb)
2792+ return 0;
2793+ return au_test_subdir(h_adding, h_root)
2794+ || au_test_subdir(h_root, h_adding);
1facf9fc 2795+}
2796+
2797+/*
2798+ * returns a newly allocated branch. @new_nbranch is a number of branches
2799+ * after adding a branch.
2800+ */
2801+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2802+ int perm)
2803+{
2804+ struct au_branch *add_branch;
2805+ struct dentry *root;
4a4d8108 2806+ int err;
1facf9fc 2807+
4a4d8108 2808+ err = -ENOMEM;
1facf9fc 2809+ root = sb->s_root;
2810+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2811+ if (unlikely(!add_branch))
2812+ goto out;
2813+
027c5e7a
AM
2814+ err = au_hnotify_init_br(add_branch, perm);
2815+ if (unlikely(err))
2816+ goto out_br;
2817+
1facf9fc 2818+ add_branch->br_wbr = NULL;
2819+ if (au_br_writable(perm)) {
2820+ /* may be freed separately at changing the branch permission */
2821+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2822+ GFP_NOFS);
2823+ if (unlikely(!add_branch->br_wbr))
027c5e7a 2824+ goto out_hnotify;
1facf9fc 2825+ }
2826+
076b876e
AM
2827+ add_branch->br_fhsm = NULL;
2828+ if (au_br_fhsm(perm)) {
2829+ err = au_fhsm_br_alloc(add_branch);
2830+ if (unlikely(err))
2831+ goto out_wbr;
2832+ }
2833+
4a4d8108
AM
2834+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2835+ if (!err)
2836+ err = au_di_realloc(au_di(root), new_nbranch);
2837+ if (!err)
2838+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2839+ if (!err)
2840+ return add_branch; /* success */
1facf9fc 2841+
076b876e 2842+out_wbr:
1facf9fc 2843+ kfree(add_branch->br_wbr);
027c5e7a
AM
2844+out_hnotify:
2845+ au_hnotify_fin_br(add_branch);
4f0767ce 2846+out_br:
1facf9fc 2847+ kfree(add_branch);
4f0767ce 2848+out:
4a4d8108 2849+ return ERR_PTR(err);
1facf9fc 2850+}
2851+
2852+/*
2853+ * test if the branch permission is legal or not.
2854+ */
2855+static int test_br(struct inode *inode, int brperm, char *path)
2856+{
2857+ int err;
2858+
4a4d8108
AM
2859+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2860+ if (!err)
2861+ goto out;
1facf9fc 2862+
4a4d8108
AM
2863+ err = -EINVAL;
2864+ pr_err("write permission for readonly mount or inode, %s\n", path);
2865+
4f0767ce 2866+out:
1facf9fc 2867+ return err;
2868+}
2869+
2870+/*
2871+ * returns:
2872+ * 0: success, the caller will add it
2873+ * plus: success, it is already unified, the caller should ignore it
2874+ * minus: error
2875+ */
2876+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2877+{
2878+ int err;
2879+ aufs_bindex_t bend, bindex;
2880+ struct dentry *root;
2881+ struct inode *inode, *h_inode;
2882+
2883+ root = sb->s_root;
2884+ bend = au_sbend(sb);
2885+ if (unlikely(bend >= 0
2886+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2887+ err = 1;
2888+ if (!remount) {
2889+ err = -EINVAL;
4a4d8108 2890+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2891+ }
2892+ goto out;
2893+ }
2894+
2895+ err = -ENOSPC; /* -E2BIG; */
2896+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2897+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2898+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2899+ goto out;
2900+ }
2901+
2902+ err = -EDOM;
2903+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2904+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2905+ goto out;
2906+ }
2907+
2908+ inode = add->path.dentry->d_inode;
2909+ err = -ENOENT;
2910+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2911+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2912+ goto out;
2913+ }
2914+
2915+ err = -EINVAL;
2916+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2917+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2918+ goto out;
2919+ }
2920+
2921+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2922+ pr_err("unsupported filesystem, %s (%s)\n",
2923+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2924+ goto out;
2925+ }
2926+
c1595e42
JR
2927+ if (unlikely(inode->i_sb->s_stack_depth)) {
2928+ pr_err("already stacked, %s (%s)\n",
2929+ add->pathname, au_sbtype(inode->i_sb));
2930+ goto out;
2931+ }
2932+
1facf9fc 2933+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2934+ if (unlikely(err))
2935+ goto out;
2936+
2937+ if (bend < 0)
2938+ return 0; /* success */
2939+
2940+ err = -EINVAL;
2941+ for (bindex = 0; bindex <= bend; bindex++)
2942+ if (unlikely(test_overlap(sb, add->path.dentry,
2943+ au_h_dptr(root, bindex)))) {
4a4d8108 2944+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 2945+ goto out;
2946+ }
2947+
2948+ err = 0;
2949+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2950+ h_inode = au_h_dptr(root, 0)->d_inode;
2951+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
2952+ || !uid_eq(h_inode->i_uid, inode->i_uid)
2953+ || !gid_eq(h_inode->i_gid, inode->i_gid))
2954+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2955+ add->pathname,
2956+ i_uid_read(inode), i_gid_read(inode),
2957+ (inode->i_mode & S_IALLUGO),
2958+ i_uid_read(h_inode), i_gid_read(h_inode),
2959+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 2960+ }
2961+
4f0767ce 2962+out:
1facf9fc 2963+ return err;
2964+}
2965+
2966+/*
2967+ * initialize or clean the whiteouts for an adding branch
2968+ */
2969+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 2970+ int new_perm)
1facf9fc 2971+{
2972+ int err, old_perm;
2973+ aufs_bindex_t bindex;
2974+ struct mutex *h_mtx;
2975+ struct au_wbr *wbr;
2976+ struct au_hinode *hdir;
2977+
86dc4139
AM
2978+ err = vfsub_mnt_want_write(au_br_mnt(br));
2979+ if (unlikely(err))
2980+ goto out;
2981+
1facf9fc 2982+ wbr = br->br_wbr;
2983+ old_perm = br->br_perm;
2984+ br->br_perm = new_perm;
2985+ hdir = NULL;
2986+ h_mtx = NULL;
2987+ bindex = au_br_index(sb, br->br_id);
2988+ if (0 <= bindex) {
2989+ hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 2990+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2991+ } else {
86dc4139 2992+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
1facf9fc 2993+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2994+ }
2995+ if (!wbr)
86dc4139 2996+ err = au_wh_init(br, sb);
1facf9fc 2997+ else {
2998+ wbr_wh_write_lock(wbr);
86dc4139 2999+ err = au_wh_init(br, sb);
1facf9fc 3000+ wbr_wh_write_unlock(wbr);
3001+ }
3002+ if (hdir)
4a4d8108 3003+ au_hn_imtx_unlock(hdir);
1facf9fc 3004+ else
3005+ mutex_unlock(h_mtx);
86dc4139 3006+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 3007+ br->br_perm = old_perm;
3008+
3009+ if (!err && wbr && !au_br_writable(new_perm)) {
3010+ kfree(wbr);
3011+ br->br_wbr = NULL;
3012+ }
3013+
86dc4139 3014+out:
1facf9fc 3015+ return err;
3016+}
3017+
3018+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 3019+ int perm)
1facf9fc 3020+{
3021+ int err;
4a4d8108 3022+ struct kstatfs kst;
1facf9fc 3023+ struct au_wbr *wbr;
3024+
3025+ wbr = br->br_wbr;
dece6358 3026+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 3027+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
3028+ atomic_set(&wbr->wbr_wh_running, 0);
3029+ wbr->wbr_bytes = 0;
3030+
4a4d8108
AM
3031+ /*
3032+ * a limit for rmdir/rename a dir
523b37e3 3033+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 3034+ */
86dc4139 3035+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
3036+ if (unlikely(err))
3037+ goto out;
3038+ err = -EINVAL;
3039+ if (kst.f_namelen >= NAME_MAX)
86dc4139 3040+ err = au_br_init_wh(sb, br, perm);
4a4d8108 3041+ else
523b37e3
AM
3042+ pr_err("%pd(%s), unsupported namelen %ld\n",
3043+ au_br_dentry(br),
86dc4139 3044+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 3045+
4f0767ce 3046+out:
1facf9fc 3047+ return err;
3048+}
3049+
c1595e42 3050+/* initialize a new branch */
1facf9fc 3051+static int au_br_init(struct au_branch *br, struct super_block *sb,
3052+ struct au_opt_add *add)
3053+{
3054+ int err;
3055+
3056+ err = 0;
3057+ memset(&br->br_xino, 0, sizeof(br->br_xino));
3058+ mutex_init(&br->br_xino.xi_nondir_mtx);
3059+ br->br_perm = add->perm;
86dc4139 3060+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108
AM
3061+ spin_lock_init(&br->br_dykey_lock);
3062+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 3063+ atomic_set(&br->br_count, 0);
1facf9fc 3064+ atomic_set(&br->br_xino_running, 0);
3065+ br->br_id = au_new_br_id(sb);
7f207e10 3066+ AuDebugOn(br->br_id < 0);
1facf9fc 3067+
3068+ if (au_br_writable(add->perm)) {
86dc4139 3069+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 3070+ if (unlikely(err))
b752ccd1 3071+ goto out_err;
1facf9fc 3072+ }
3073+
3074+ if (au_opt_test(au_mntflags(sb), XINO)) {
3075+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
3076+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
3077+ if (unlikely(err)) {
3078+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 3079+ goto out_err;
1facf9fc 3080+ }
3081+ }
3082+
3083+ sysaufs_br_init(br);
86dc4139 3084+ path_get(&br->br_path);
b752ccd1 3085+ goto out; /* success */
1facf9fc 3086+
4f0767ce 3087+out_err:
86dc4139 3088+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 3089+out:
1facf9fc 3090+ return err;
3091+}
3092+
3093+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
3094+ struct au_branch *br, aufs_bindex_t bend,
3095+ aufs_bindex_t amount)
3096+{
3097+ struct au_branch **brp;
3098+
dece6358
AM
3099+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3100+
1facf9fc 3101+ brp = sbinfo->si_branch + bindex;
3102+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3103+ *brp = br;
3104+ sbinfo->si_bend++;
3105+ if (unlikely(bend < 0))
3106+ sbinfo->si_bend = 0;
3107+}
3108+
3109+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
3110+ aufs_bindex_t bend, aufs_bindex_t amount)
3111+{
3112+ struct au_hdentry *hdp;
3113+
1308ab2a 3114+ AuRwMustWriteLock(&dinfo->di_rwsem);
3115+
1facf9fc 3116+ hdp = dinfo->di_hdentry + bindex;
3117+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3118+ au_h_dentry_init(hdp);
3119+ dinfo->di_bend++;
3120+ if (unlikely(bend < 0))
3121+ dinfo->di_bstart = 0;
3122+}
3123+
3124+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
3125+ aufs_bindex_t bend, aufs_bindex_t amount)
3126+{
3127+ struct au_hinode *hip;
3128+
1308ab2a 3129+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3130+
1facf9fc 3131+ hip = iinfo->ii_hinode + bindex;
3132+ memmove(hip + 1, hip, sizeof(*hip) * amount);
3133+ hip->hi_inode = NULL;
4a4d8108 3134+ au_hn_init(hip);
1facf9fc 3135+ iinfo->ii_bend++;
3136+ if (unlikely(bend < 0))
3137+ iinfo->ii_bstart = 0;
3138+}
3139+
86dc4139
AM
3140+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3141+ aufs_bindex_t bindex)
1facf9fc 3142+{
86dc4139 3143+ struct dentry *root, *h_dentry;
1facf9fc 3144+ struct inode *root_inode;
3145+ aufs_bindex_t bend, amount;
3146+
3147+ root = sb->s_root;
3148+ root_inode = root->d_inode;
1facf9fc 3149+ bend = au_sbend(sb);
3150+ amount = bend + 1 - bindex;
86dc4139 3151+ h_dentry = au_br_dentry(br);
53392da6 3152+ au_sbilist_lock();
1facf9fc 3153+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
3154+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
3155+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
3156+ au_set_h_dptr(root, bindex, dget(h_dentry));
3157+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
3158+ /*flags*/0);
53392da6 3159+ au_sbilist_unlock();
1facf9fc 3160+}
3161+
3162+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3163+{
3164+ int err;
1facf9fc 3165+ aufs_bindex_t bend, add_bindex;
3166+ struct dentry *root, *h_dentry;
3167+ struct inode *root_inode;
3168+ struct au_branch *add_branch;
3169+
3170+ root = sb->s_root;
3171+ root_inode = root->d_inode;
3172+ IMustLock(root_inode);
3173+ err = test_add(sb, add, remount);
3174+ if (unlikely(err < 0))
3175+ goto out;
3176+ if (err) {
3177+ err = 0;
3178+ goto out; /* success */
3179+ }
3180+
3181+ bend = au_sbend(sb);
3182+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
3183+ err = PTR_ERR(add_branch);
3184+ if (IS_ERR(add_branch))
3185+ goto out;
3186+
3187+ err = au_br_init(add_branch, sb, add);
3188+ if (unlikely(err)) {
3189+ au_br_do_free(add_branch);
3190+ goto out;
3191+ }
3192+
3193+ add_bindex = add->bindex;
1facf9fc 3194+ if (!remount)
86dc4139 3195+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3196+ else {
3197+ sysaufs_brs_del(sb, add_bindex);
86dc4139 3198+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3199+ sysaufs_brs_add(sb, add_bindex);
3200+ }
3201+
86dc4139 3202+ h_dentry = add->path.dentry;
1308ab2a 3203+ if (!add_bindex) {
1facf9fc 3204+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3205+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3206+ } else
1facf9fc 3207+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 3208+
3209+ /*
4a4d8108 3210+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 3211+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 3212+ * once detached from aufs.
3213+ */
3214+ if (au_xino_brid(sb) < 0
3215+ && au_br_writable(add_branch->br_perm)
3216+ && !au_test_fs_bad_xino(h_dentry->d_sb)
3217+ && add_branch->br_xino.xi_file
2000de60 3218+ && add_branch->br_xino.xi_file->f_path.dentry->d_parent == h_dentry)
1facf9fc 3219+ au_xino_brid_set(sb, add_branch->br_id);
3220+
4f0767ce 3221+out:
1facf9fc 3222+ return err;
3223+}
3224+
3225+/* ---------------------------------------------------------------------- */
3226+
076b876e
AM
3227+static unsigned long long au_farray_cb(void *a,
3228+ unsigned long long max __maybe_unused,
3229+ void *arg)
3230+{
3231+ unsigned long long n;
3232+ struct file **p, *f;
3233+ struct au_sphlhead *files;
3234+ struct au_finfo *finfo;
3235+ struct super_block *sb = arg;
3236+
3237+ n = 0;
3238+ p = a;
3239+ files = &au_sbi(sb)->si_files;
3240+ spin_lock(&files->spin);
3241+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
3242+ f = finfo->fi_file;
3243+ if (file_count(f)
3244+ && !special_file(file_inode(f)->i_mode)) {
3245+ get_file(f);
3246+ *p++ = f;
3247+ n++;
3248+ AuDebugOn(n > max);
3249+ }
3250+ }
3251+ spin_unlock(&files->spin);
3252+
3253+ return n;
3254+}
3255+
3256+static struct file **au_farray_alloc(struct super_block *sb,
3257+ unsigned long long *max)
3258+{
3259+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
3260+ return au_array_alloc(max, au_farray_cb, sb);
3261+}
3262+
3263+static void au_farray_free(struct file **a, unsigned long long max)
3264+{
3265+ unsigned long long ull;
3266+
3267+ for (ull = 0; ull < max; ull++)
3268+ if (a[ull])
3269+ fput(a[ull]);
3270+ au_array_free(a);
3271+}
3272+
3273+/* ---------------------------------------------------------------------- */
3274+
1facf9fc 3275+/*
3276+ * delete a branch
3277+ */
3278+
3279+/* to show the line number, do not make it inlined function */
4a4d8108 3280+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3281+ if (do_info) \
4a4d8108 3282+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3283+} while (0)
3284+
027c5e7a
AM
3285+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
3286+ aufs_bindex_t bend)
3287+{
3288+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
3289+}
3290+
3291+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
3292+ aufs_bindex_t bend)
3293+{
3294+ return au_test_ibusy(dentry->d_inode, bstart, bend);
3295+}
3296+
1facf9fc 3297+/*
3298+ * test if the branch is deletable or not.
3299+ */
3300+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3301+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3302+{
3303+ int err, i, j, ndentry;
3304+ aufs_bindex_t bstart, bend;
1facf9fc 3305+ struct au_dcsub_pages dpages;
3306+ struct au_dpage *dpage;
3307+ struct dentry *d;
1facf9fc 3308+
3309+ err = au_dpages_init(&dpages, GFP_NOFS);
3310+ if (unlikely(err))
3311+ goto out;
3312+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3313+ if (unlikely(err))
3314+ goto out_dpages;
3315+
1facf9fc 3316+ for (i = 0; !err && i < dpages.ndpage; i++) {
3317+ dpage = dpages.dpages + i;
3318+ ndentry = dpage->ndentry;
3319+ for (j = 0; !err && j < ndentry; j++) {
3320+ d = dpage->dentries[j];
c1595e42 3321+ AuDebugOn(au_dcount(d) <= 0);
027c5e7a 3322+ if (!au_digen_test(d, sigen)) {
1facf9fc 3323+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3324+ if (unlikely(au_dbrange_test(d))) {
3325+ di_read_unlock(d, AuLock_IR);
3326+ continue;
3327+ }
3328+ } else {
1facf9fc 3329+ di_write_lock_child(d);
027c5e7a
AM
3330+ if (unlikely(au_dbrange_test(d))) {
3331+ di_write_unlock(d);
3332+ continue;
3333+ }
1facf9fc 3334+ err = au_reval_dpath(d, sigen);
3335+ if (!err)
3336+ di_downgrade_lock(d, AuLock_IR);
3337+ else {
3338+ di_write_unlock(d);
3339+ break;
3340+ }
3341+ }
3342+
027c5e7a 3343+ /* AuDbgDentry(d); */
1facf9fc 3344+ bstart = au_dbstart(d);
3345+ bend = au_dbend(d);
3346+ if (bstart <= bindex
3347+ && bindex <= bend
3348+ && au_h_dptr(d, bindex)
027c5e7a 3349+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 3350+ err = -EBUSY;
523b37e3 3351+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3352+ AuDbgDentry(d);
1facf9fc 3353+ }
3354+ di_read_unlock(d, AuLock_IR);
3355+ }
3356+ }
3357+
4f0767ce 3358+out_dpages:
1facf9fc 3359+ au_dpages_free(&dpages);
4f0767ce 3360+out:
1facf9fc 3361+ return err;
3362+}
3363+
3364+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3365+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3366+{
3367+ int err;
7f207e10
AM
3368+ unsigned long long max, ull;
3369+ struct inode *i, **array;
1facf9fc 3370+ aufs_bindex_t bstart, bend;
1facf9fc 3371+
7f207e10
AM
3372+ array = au_iarray_alloc(sb, &max);
3373+ err = PTR_ERR(array);
3374+ if (IS_ERR(array))
3375+ goto out;
3376+
1facf9fc 3377+ err = 0;
7f207e10
AM
3378+ AuDbg("b%d\n", bindex);
3379+ for (ull = 0; !err && ull < max; ull++) {
3380+ i = array[ull];
076b876e
AM
3381+ if (unlikely(!i))
3382+ break;
7f207e10 3383+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3384+ continue;
3385+
7f207e10 3386+ /* AuDbgInode(i); */
537831f9 3387+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3388+ ii_read_lock_child(i);
3389+ else {
3390+ ii_write_lock_child(i);
027c5e7a
AM
3391+ err = au_refresh_hinode_self(i);
3392+ au_iigen_dec(i);
1facf9fc 3393+ if (!err)
3394+ ii_downgrade_lock(i);
3395+ else {
3396+ ii_write_unlock(i);
3397+ break;
3398+ }
3399+ }
3400+
3401+ bstart = au_ibstart(i);
3402+ bend = au_ibend(i);
3403+ if (bstart <= bindex
3404+ && bindex <= bend
3405+ && au_h_iptr(i, bindex)
027c5e7a 3406+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 3407+ err = -EBUSY;
3408+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3409+ AuDbgInode(i);
1facf9fc 3410+ }
3411+ ii_read_unlock(i);
3412+ }
7f207e10 3413+ au_iarray_free(array, max);
1facf9fc 3414+
7f207e10 3415+out:
1facf9fc 3416+ return err;
3417+}
3418+
b752ccd1
AM
3419+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3420+ const unsigned int verbose)
1facf9fc 3421+{
3422+ int err;
3423+ unsigned int sigen;
3424+
3425+ sigen = au_sigen(root->d_sb);
3426+ DiMustNoWaiters(root);
3427+ IiMustNoWaiters(root->d_inode);
3428+ di_write_unlock(root);
b752ccd1 3429+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3430+ if (!err)
b752ccd1 3431+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3432+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3433+
3434+ return err;
3435+}
3436+
076b876e
AM
3437+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3438+ struct file **to_free, int *idx)
3439+{
3440+ int err;
c1595e42 3441+ unsigned char matched, root;
076b876e
AM
3442+ aufs_bindex_t bindex, bend;
3443+ struct au_fidir *fidir;
3444+ struct au_hfile *hfile;
3445+
3446+ err = 0;
2000de60 3447+ root = IS_ROOT(file->f_path.dentry);
c1595e42
JR
3448+ if (root) {
3449+ get_file(file);
3450+ to_free[*idx] = file;
3451+ (*idx)++;
3452+ goto out;
3453+ }
3454+
076b876e 3455+ matched = 0;
076b876e
AM
3456+ fidir = au_fi(file)->fi_hdir;
3457+ AuDebugOn(!fidir);
3458+ bend = au_fbend_dir(file);
3459+ for (bindex = au_fbstart(file); bindex <= bend; bindex++) {
3460+ hfile = fidir->fd_hfile + bindex;
3461+ if (!hfile->hf_file)
3462+ continue;
3463+
c1595e42 3464+ if (hfile->hf_br->br_id == br_id) {
076b876e 3465+ matched = 1;
076b876e 3466+ break;
c1595e42 3467+ }
076b876e 3468+ }
c1595e42 3469+ if (matched)
076b876e
AM
3470+ err = -EBUSY;
3471+
3472+out:
3473+ return err;
3474+}
3475+
3476+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3477+ struct file **to_free, int opened)
3478+{
3479+ int err, idx;
3480+ unsigned long long ull, max;
3481+ aufs_bindex_t bstart;
3482+ struct file *file, **array;
076b876e
AM
3483+ struct dentry *root;
3484+ struct au_hfile *hfile;
3485+
3486+ array = au_farray_alloc(sb, &max);
3487+ err = PTR_ERR(array);
3488+ if (IS_ERR(array))
3489+ goto out;
3490+
3491+ err = 0;
3492+ idx = 0;
3493+ root = sb->s_root;
3494+ di_write_unlock(root);
3495+ for (ull = 0; ull < max; ull++) {
3496+ file = array[ull];
3497+ if (unlikely(!file))
3498+ break;
3499+
3500+ /* AuDbg("%pD\n", file); */
3501+ fi_read_lock(file);
3502+ bstart = au_fbstart(file);
2000de60 3503+ if (!d_is_dir(file->f_path.dentry)) {
076b876e
AM
3504+ hfile = &au_fi(file)->fi_htop;
3505+ if (hfile->hf_br->br_id == br_id)
3506+ err = -EBUSY;
3507+ } else
3508+ err = test_dir_busy(file, br_id, to_free, &idx);
3509+ fi_read_unlock(file);
3510+ if (unlikely(err))
3511+ break;
3512+ }
3513+ di_write_lock_child(root);
3514+ au_farray_free(array, max);
3515+ AuDebugOn(idx > opened);
3516+
3517+out:
3518+ return err;
3519+}
3520+
3521+static void br_del_file(struct file **to_free, unsigned long long opened,
3522+ aufs_bindex_t br_id)
3523+{
3524+ unsigned long long ull;
3525+ aufs_bindex_t bindex, bstart, bend, bfound;
3526+ struct file *file;
3527+ struct au_fidir *fidir;
3528+ struct au_hfile *hfile;
3529+
3530+ for (ull = 0; ull < opened; ull++) {
3531+ file = to_free[ull];
3532+ if (unlikely(!file))
3533+ break;
3534+
3535+ /* AuDbg("%pD\n", file); */
2000de60 3536+ AuDebugOn(!d_is_dir(file->f_path.dentry));
076b876e
AM
3537+ bfound = -1;
3538+ fidir = au_fi(file)->fi_hdir;
3539+ AuDebugOn(!fidir);
3540+ fi_write_lock(file);
3541+ bstart = au_fbstart(file);
3542+ bend = au_fbend_dir(file);
3543+ for (bindex = bstart; bindex <= bend; bindex++) {
3544+ hfile = fidir->fd_hfile + bindex;
3545+ if (!hfile->hf_file)
3546+ continue;
3547+
3548+ if (hfile->hf_br->br_id == br_id) {
3549+ bfound = bindex;
3550+ break;
3551+ }
3552+ }
3553+ AuDebugOn(bfound < 0);
3554+ au_set_h_fptr(file, bfound, NULL);
3555+ if (bfound == bstart) {
3556+ for (bstart++; bstart <= bend; bstart++)
3557+ if (au_hf_dir(file, bstart)) {
3558+ au_set_fbstart(file, bstart);
3559+ break;
3560+ }
3561+ }
3562+ fi_write_unlock(file);
3563+ }
3564+}
3565+
1facf9fc 3566+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
3567+ const aufs_bindex_t bindex,
3568+ const aufs_bindex_t bend)
3569+{
3570+ struct au_branch **brp, **p;
3571+
dece6358
AM
3572+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3573+
1facf9fc 3574+ brp = sbinfo->si_branch + bindex;
3575+ if (bindex < bend)
3576+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
3577+ sbinfo->si_branch[0 + bend] = NULL;
3578+ sbinfo->si_bend--;
3579+
53392da6 3580+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3581+ if (p)
3582+ sbinfo->si_branch = p;
4a4d8108 3583+ /* harmless error */
1facf9fc 3584+}
3585+
3586+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
3587+ const aufs_bindex_t bend)
3588+{
3589+ struct au_hdentry *hdp, *p;
3590+
1308ab2a 3591+ AuRwMustWriteLock(&dinfo->di_rwsem);
3592+
4a4d8108 3593+ hdp = dinfo->di_hdentry;
1facf9fc 3594+ if (bindex < bend)
4a4d8108
AM
3595+ memmove(hdp + bindex, hdp + bindex + 1,
3596+ sizeof(*hdp) * (bend - bindex));
3597+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 3598+ dinfo->di_bend--;
3599+
53392da6 3600+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3601+ if (p)
3602+ dinfo->di_hdentry = p;
4a4d8108 3603+ /* harmless error */
1facf9fc 3604+}
3605+
3606+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
3607+ const aufs_bindex_t bend)
3608+{
3609+ struct au_hinode *hip, *p;
3610+
1308ab2a 3611+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3612+
1facf9fc 3613+ hip = iinfo->ii_hinode + bindex;
3614+ if (bindex < bend)
3615+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
3616+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 3617+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 3618+ iinfo->ii_bend--;
3619+
53392da6 3620+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3621+ if (p)
3622+ iinfo->ii_hinode = p;
4a4d8108 3623+ /* harmless error */
1facf9fc 3624+}
3625+
3626+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
3627+ struct au_branch *br)
3628+{
3629+ aufs_bindex_t bend;
3630+ struct au_sbinfo *sbinfo;
53392da6
AM
3631+ struct dentry *root, *h_root;
3632+ struct inode *inode, *h_inode;
3633+ struct au_hinode *hinode;
1facf9fc 3634+
dece6358
AM
3635+ SiMustWriteLock(sb);
3636+
1facf9fc 3637+ root = sb->s_root;
3638+ inode = root->d_inode;
1facf9fc 3639+ sbinfo = au_sbi(sb);
3640+ bend = sbinfo->si_bend;
3641+
53392da6
AM
3642+ h_root = au_h_dptr(root, bindex);
3643+ hinode = au_hi(inode, bindex);
3644+ h_inode = au_igrab(hinode->hi_inode);
3645+ au_hiput(hinode);
1facf9fc 3646+
53392da6 3647+ au_sbilist_lock();
1facf9fc 3648+ au_br_do_del_brp(sbinfo, bindex, bend);
3649+ au_br_do_del_hdp(au_di(root), bindex, bend);
3650+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
3651+ au_sbilist_unlock();
3652+
3653+ dput(h_root);
3654+ iput(h_inode);
3655+ au_br_do_free(br);
1facf9fc 3656+}
3657+
076b876e
AM
3658+static unsigned long long empty_cb(void *array, unsigned long long max,
3659+ void *arg)
3660+{
3661+ return max;
3662+}
3663+
1facf9fc 3664+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
3665+{
3666+ int err, rerr, i;
076b876e 3667+ unsigned long long opened;
1facf9fc 3668+ unsigned int mnt_flags;
3669+ aufs_bindex_t bindex, bend, br_id;
3670+ unsigned char do_wh, verbose;
3671+ struct au_branch *br;
3672+ struct au_wbr *wbr;
076b876e
AM
3673+ struct dentry *root;
3674+ struct file **to_free;
1facf9fc 3675+
3676+ err = 0;
076b876e
AM
3677+ opened = 0;
3678+ to_free = NULL;
3679+ root = sb->s_root;
3680+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 3681+ if (bindex < 0) {
3682+ if (remount)
3683+ goto out; /* success */
3684+ err = -ENOENT;
4a4d8108 3685+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 3686+ goto out;
3687+ }
3688+ AuDbg("bindex b%d\n", bindex);
3689+
3690+ err = -EBUSY;
3691+ mnt_flags = au_mntflags(sb);
3692+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3693+ bend = au_sbend(sb);
3694+ if (unlikely(!bend)) {
3695+ AuVerbose(verbose, "no more branches left\n");
3696+ goto out;
3697+ }
3698+ br = au_sbr(sb, bindex);
86dc4139 3699+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
076b876e
AM
3700+
3701+ br_id = br->br_id;
3702+ opened = atomic_read(&br->br_count);
3703+ if (unlikely(opened)) {
3704+ to_free = au_array_alloc(&opened, empty_cb, NULL);
3705+ err = PTR_ERR(to_free);
3706+ if (IS_ERR(to_free))
3707+ goto out;
3708+
3709+ err = test_file_busy(sb, br_id, to_free, opened);
3710+ if (unlikely(err)) {
3711+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
3712+ goto out;
3713+ }
1facf9fc 3714+ }
3715+
3716+ wbr = br->br_wbr;
3717+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
3718+ if (do_wh) {
1308ab2a 3719+ /* instead of WbrWhMustWriteLock(wbr) */
3720+ SiMustWriteLock(sb);
1facf9fc 3721+ for (i = 0; i < AuBrWh_Last; i++) {
3722+ dput(wbr->wbr_wh[i]);
3723+ wbr->wbr_wh[i] = NULL;
3724+ }
3725+ }
3726+
076b876e 3727+ err = test_children_busy(root, bindex, verbose);
1facf9fc 3728+ if (unlikely(err)) {
3729+ if (do_wh)
3730+ goto out_wh;
3731+ goto out;
3732+ }
3733+
3734+ err = 0;
076b876e
AM
3735+ if (to_free) {
3736+ /*
3737+ * now we confirmed the branch is deletable.
3738+ * let's free the remaining opened dirs on the branch.
3739+ */
3740+ di_write_unlock(root);
3741+ br_del_file(to_free, opened, br_id);
3742+ di_write_lock_child(root);
3743+ }
3744+
1facf9fc 3745+ if (!remount)
3746+ au_br_do_del(sb, bindex, br);
3747+ else {
3748+ sysaufs_brs_del(sb, bindex);
3749+ au_br_do_del(sb, bindex, br);
3750+ sysaufs_brs_add(sb, bindex);
3751+ }
3752+
1308ab2a 3753+ if (!bindex) {
076b876e 3754+ au_cpup_attr_all(root->d_inode, /*force*/1);
1308ab2a 3755+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
3756+ } else
076b876e 3757+ au_sub_nlink(root->d_inode, del->h_path.dentry->d_inode);
1facf9fc 3758+ if (au_opt_test(mnt_flags, PLINK))
3759+ au_plink_half_refresh(sb, br_id);
3760+
b752ccd1 3761+ if (au_xino_brid(sb) == br_id)
1facf9fc 3762+ au_xino_brid_set(sb, -1);
3763+ goto out; /* success */
3764+
4f0767ce 3765+out_wh:
1facf9fc 3766+ /* revert */
86dc4139 3767+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 3768+ if (rerr)
0c3ec466
AM
3769+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
3770+ del->pathname, rerr);
4f0767ce 3771+out:
076b876e
AM
3772+ if (to_free)
3773+ au_farray_free(to_free, opened);
1facf9fc 3774+ return err;
3775+}
3776+
3777+/* ---------------------------------------------------------------------- */
3778+
027c5e7a
AM
3779+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
3780+{
3781+ int err;
3782+ aufs_bindex_t bstart, bend;
3783+ struct aufs_ibusy ibusy;
3784+ struct inode *inode, *h_inode;
3785+
3786+ err = -EPERM;
3787+ if (unlikely(!capable(CAP_SYS_ADMIN)))
3788+ goto out;
3789+
3790+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
3791+ if (!err)
3792+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
3793+ if (unlikely(err)) {
3794+ err = -EFAULT;
3795+ AuTraceErr(err);
3796+ goto out;
3797+ }
3798+
3799+ err = -EINVAL;
3800+ si_read_lock(sb, AuLock_FLUSH);
3801+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
3802+ goto out_unlock;
3803+
3804+ err = 0;
3805+ ibusy.h_ino = 0; /* invalid */
3806+ inode = ilookup(sb, ibusy.ino);
3807+ if (!inode
3808+ || inode->i_ino == AUFS_ROOT_INO
3809+ || is_bad_inode(inode))
3810+ goto out_unlock;
3811+
3812+ ii_read_lock_child(inode);
3813+ bstart = au_ibstart(inode);
3814+ bend = au_ibend(inode);
3815+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
3816+ h_inode = au_h_iptr(inode, ibusy.bindex);
3817+ if (h_inode && au_test_ibusy(inode, bstart, bend))
3818+ ibusy.h_ino = h_inode->i_ino;
3819+ }
3820+ ii_read_unlock(inode);
3821+ iput(inode);
3822+
3823+out_unlock:
3824+ si_read_unlock(sb);
3825+ if (!err) {
3826+ err = __put_user(ibusy.h_ino, &arg->h_ino);
3827+ if (unlikely(err)) {
3828+ err = -EFAULT;
3829+ AuTraceErr(err);
3830+ }
3831+ }
3832+out:
3833+ return err;
3834+}
3835+
3836+long au_ibusy_ioctl(struct file *file, unsigned long arg)
3837+{
2000de60 3838+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg);
027c5e7a
AM
3839+}
3840+
3841+#ifdef CONFIG_COMPAT
3842+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
3843+{
2000de60 3844+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg));
027c5e7a
AM
3845+}
3846+#endif
3847+
3848+/* ---------------------------------------------------------------------- */
3849+
1facf9fc 3850+/*
3851+ * change a branch permission
3852+ */
3853+
dece6358
AM
3854+static void au_warn_ima(void)
3855+{
3856+#ifdef CONFIG_IMA
1308ab2a 3857+ /* since it doesn't support mark_files_ro() */
027c5e7a 3858+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
3859+#endif
3860+}
3861+
1facf9fc 3862+static int do_need_sigen_inc(int a, int b)
3863+{
3864+ return au_br_whable(a) && !au_br_whable(b);
3865+}
3866+
3867+static int need_sigen_inc(int old, int new)
3868+{
3869+ return do_need_sigen_inc(old, new)
3870+ || do_need_sigen_inc(new, old);
3871+}
3872+
3873+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
3874+{
7f207e10 3875+ int err, do_warn;
027c5e7a 3876+ unsigned int mnt_flags;
7f207e10 3877+ unsigned long long ull, max;
e49829fe 3878+ aufs_bindex_t br_id;
38d290e6 3879+ unsigned char verbose, writer;
7f207e10 3880+ struct file *file, *hf, **array;
e49829fe
JR
3881+ struct inode *inode;
3882+ struct au_hfile *hfile;
1facf9fc 3883+
027c5e7a
AM
3884+ mnt_flags = au_mntflags(sb);
3885+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3886+
7f207e10
AM
3887+ array = au_farray_alloc(sb, &max);
3888+ err = PTR_ERR(array);
3889+ if (IS_ERR(array))
1facf9fc 3890+ goto out;
3891+
7f207e10 3892+ do_warn = 0;
e49829fe 3893+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
3894+ for (ull = 0; ull < max; ull++) {
3895+ file = array[ull];
076b876e
AM
3896+ if (unlikely(!file))
3897+ break;
1facf9fc 3898+
523b37e3 3899+ /* AuDbg("%pD\n", file); */
1facf9fc 3900+ fi_read_lock(file);
3901+ if (unlikely(au_test_mmapped(file))) {
3902+ err = -EBUSY;
523b37e3 3903+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 3904+ AuDbgFile(file);
1facf9fc 3905+ FiMustNoWaiters(file);
3906+ fi_read_unlock(file);
7f207e10 3907+ goto out_array;
1facf9fc 3908+ }
3909+
c06a8ce3 3910+ inode = file_inode(file);
e49829fe
JR
3911+ hfile = &au_fi(file)->fi_htop;
3912+ hf = hfile->hf_file;
3913+ if (!S_ISREG(inode->i_mode)
1facf9fc 3914+ || !(file->f_mode & FMODE_WRITE)
e49829fe 3915+ || hfile->hf_br->br_id != br_id
7f207e10
AM
3916+ || !(hf->f_mode & FMODE_WRITE))
3917+ array[ull] = NULL;
3918+ else {
3919+ do_warn = 1;
3920+ get_file(file);
1facf9fc 3921+ }
3922+
1facf9fc 3923+ FiMustNoWaiters(file);
3924+ fi_read_unlock(file);
7f207e10
AM
3925+ fput(file);
3926+ }
1facf9fc 3927+
3928+ err = 0;
7f207e10 3929+ if (do_warn)
dece6358 3930+ au_warn_ima();
7f207e10
AM
3931+
3932+ for (ull = 0; ull < max; ull++) {
3933+ file = array[ull];
3934+ if (!file)
3935+ continue;
3936+
1facf9fc 3937+ /* todo: already flushed? */
523b37e3
AM
3938+ /*
3939+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
3940+ * approach which resets f_mode and calls mnt_drop_write() and
3941+ * file_release_write() for each file, because the branch
3942+ * attribute in aufs world is totally different from the native
3943+ * fs rw/ro mode.
3944+ */
7f207e10
AM
3945+ /* fi_read_lock(file); */
3946+ hfile = &au_fi(file)->fi_htop;
3947+ hf = hfile->hf_file;
3948+ /* fi_read_unlock(file); */
027c5e7a 3949+ spin_lock(&hf->f_lock);
38d290e6
JR
3950+ writer = !!(hf->f_mode & FMODE_WRITER);
3951+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 3952+ spin_unlock(&hf->f_lock);
38d290e6
JR
3953+ if (writer) {
3954+ put_write_access(file_inode(hf));
c06a8ce3 3955+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 3956+ }
3957+ }
3958+
7f207e10
AM
3959+out_array:
3960+ au_farray_free(array, max);
4f0767ce 3961+out:
7f207e10 3962+ AuTraceErr(err);
1facf9fc 3963+ return err;
3964+}
3965+
3966+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3967+ int *do_refresh)
1facf9fc 3968+{
3969+ int err, rerr;
3970+ aufs_bindex_t bindex;
3971+ struct dentry *root;
3972+ struct au_branch *br;
076b876e 3973+ struct au_br_fhsm *bf;
1facf9fc 3974+
3975+ root = sb->s_root;
1facf9fc 3976+ bindex = au_find_dbindex(root, mod->h_root);
3977+ if (bindex < 0) {
3978+ if (remount)
3979+ return 0; /* success */
3980+ err = -ENOENT;
4a4d8108 3981+ pr_err("%s no such branch\n", mod->path);
1facf9fc 3982+ goto out;
3983+ }
3984+ AuDbg("bindex b%d\n", bindex);
3985+
3986+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3987+ if (unlikely(err))
3988+ goto out;
3989+
3990+ br = au_sbr(sb, bindex);
86dc4139 3991+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 3992+ if (br->br_perm == mod->perm)
3993+ return 0; /* success */
3994+
076b876e
AM
3995+ /* pre-allocate for non-fhsm --> fhsm */
3996+ bf = NULL;
3997+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
3998+ err = au_fhsm_br_alloc(br);
3999+ if (unlikely(err))
4000+ goto out;
4001+ bf = br->br_fhsm;
4002+ br->br_fhsm = NULL;
4003+ }
4004+
1facf9fc 4005+ if (au_br_writable(br->br_perm)) {
4006+ /* remove whiteout base */
86dc4139 4007+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 4008+ if (unlikely(err))
076b876e 4009+ goto out_bf;
1facf9fc 4010+
4011+ if (!au_br_writable(mod->perm)) {
4012+ /* rw --> ro, file might be mmapped */
4013+ DiMustNoWaiters(root);
4014+ IiMustNoWaiters(root->d_inode);
4015+ di_write_unlock(root);
4016+ err = au_br_mod_files_ro(sb, bindex);
4017+ /* aufs_write_lock() calls ..._child() */
4018+ di_write_lock_child(root);
4019+
4020+ if (unlikely(err)) {
4021+ rerr = -ENOMEM;
4022+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
4023+ GFP_NOFS);
86dc4139
AM
4024+ if (br->br_wbr)
4025+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 4026+ if (unlikely(rerr)) {
4027+ AuIOErr("nested error %d (%d)\n",
4028+ rerr, err);
4029+ br->br_perm = mod->perm;
4030+ }
4031+ }
4032+ }
4033+ } else if (au_br_writable(mod->perm)) {
4034+ /* ro --> rw */
4035+ err = -ENOMEM;
4036+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
4037+ if (br->br_wbr) {
86dc4139 4038+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 4039+ if (unlikely(err)) {
4040+ kfree(br->br_wbr);
4041+ br->br_wbr = NULL;
4042+ }
4043+ }
4044+ }
076b876e
AM
4045+ if (unlikely(err))
4046+ goto out_bf;
4047+
4048+ if (au_br_fhsm(br->br_perm)) {
4049+ if (!au_br_fhsm(mod->perm)) {
4050+ /* fhsm --> non-fhsm */
4051+ au_br_fhsm_fin(br->br_fhsm);
4052+ kfree(br->br_fhsm);
4053+ br->br_fhsm = NULL;
4054+ }
4055+ } else if (au_br_fhsm(mod->perm))
4056+ /* non-fhsm --> fhsm */
4057+ br->br_fhsm = bf;
4058+
076b876e
AM
4059+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
4060+ br->br_perm = mod->perm;
4061+ goto out; /* success */
1facf9fc 4062+
076b876e
AM
4063+out_bf:
4064+ kfree(bf);
4065+out:
4066+ AuTraceErr(err);
4067+ return err;
4068+}
4069+
4070+/* ---------------------------------------------------------------------- */
4071+
4072+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4073+{
4074+ int err;
4075+ struct kstatfs kstfs;
4076+
4077+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 4078+ if (!err) {
076b876e
AM
4079+ stfs->f_blocks = kstfs.f_blocks;
4080+ stfs->f_bavail = kstfs.f_bavail;
4081+ stfs->f_files = kstfs.f_files;
4082+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 4083+ }
4084+
1facf9fc 4085+ return err;
4086+}
7f207e10
AM
4087diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4088--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
2000de60 4089+++ linux/fs/aufs/branch.h 2015-03-27 21:56:35.460128334 +0100
c1595e42 4090@@ -0,0 +1,267 @@
1facf9fc 4091+/*
2000de60 4092+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 4093+ *
4094+ * This program, aufs is free software; you can redistribute it and/or modify
4095+ * it under the terms of the GNU General Public License as published by
4096+ * the Free Software Foundation; either version 2 of the License, or
4097+ * (at your option) any later version.
dece6358
AM
4098+ *
4099+ * This program is distributed in the hope that it will be useful,
4100+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4101+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4102+ * GNU General Public License for more details.
4103+ *
4104+ * You should have received a copy of the GNU General Public License
523b37e3 4105+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4106+ */
4107+
4108+/*
4109+ * branch filesystems and xino for them
4110+ */
4111+
4112+#ifndef __AUFS_BRANCH_H__
4113+#define __AUFS_BRANCH_H__
4114+
4115+#ifdef __KERNEL__
4116+
1facf9fc 4117+#include <linux/mount.h>
4a4d8108 4118+#include "dynop.h"
1facf9fc 4119+#include "rwsem.h"
4120+#include "super.h"
4121+
4122+/* ---------------------------------------------------------------------- */
4123+
4124+/* a xino file */
4125+struct au_xino_file {
4126+ struct file *xi_file;
4127+ struct mutex xi_nondir_mtx;
4128+
4129+ /* todo: make xino files an array to support huge inode number */
4130+
4131+#ifdef CONFIG_DEBUG_FS
4132+ struct dentry *xi_dbgaufs;
4133+#endif
4134+};
4135+
076b876e
AM
4136+/* File-based Hierarchical Storage Management */
4137+struct au_br_fhsm {
4138+#ifdef CONFIG_AUFS_FHSM
4139+ struct mutex bf_lock;
4140+ unsigned long bf_jiffy;
4141+ struct aufs_stfs bf_stfs;
4142+ int bf_readable;
4143+#endif
4144+};
4145+
1facf9fc 4146+/* members for writable branch only */
4147+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4148+struct au_wbr {
dece6358 4149+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4150+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4151+ atomic_t wbr_wh_running;
1facf9fc 4152+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4153+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4154+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4155+
4156+ /* mfs mode */
4157+ unsigned long long wbr_bytes;
4158+};
4159+
4a4d8108
AM
4160+/* ext2 has 3 types of operations at least, ext3 has 4 */
4161+#define AuBrDynOp (AuDyLast * 4)
4162+
1716fcea
AM
4163+#ifdef CONFIG_AUFS_HFSNOTIFY
4164+/* support for asynchronous destruction */
4165+struct au_br_hfsnotify {
4166+ struct fsnotify_group *hfsn_group;
4167+};
4168+#endif
4169+
392086de
AM
4170+/* sysfs entries */
4171+struct au_brsysfs {
4172+ char name[16];
4173+ struct attribute attr;
4174+};
4175+
4176+enum {
4177+ AuBrSysfs_BR,
4178+ AuBrSysfs_BRID,
4179+ AuBrSysfs_Last
4180+};
4181+
1facf9fc 4182+/* protected by superblock rwsem */
4183+struct au_branch {
4184+ struct au_xino_file br_xino;
4185+
4186+ aufs_bindex_t br_id;
4187+
4188+ int br_perm;
86dc4139 4189+ struct path br_path;
4a4d8108
AM
4190+ spinlock_t br_dykey_lock;
4191+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 4192+ atomic_t br_count;
4193+
4194+ struct au_wbr *br_wbr;
076b876e 4195+ struct au_br_fhsm *br_fhsm;
1facf9fc 4196+
4197+ /* xino truncation */
1facf9fc 4198+ atomic_t br_xino_running;
4199+
027c5e7a 4200+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4201+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4202+#endif
4203+
1facf9fc 4204+#ifdef CONFIG_SYSFS
392086de
AM
4205+ /* entries under sysfs per mount-point */
4206+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4207+#endif
4208+};
4209+
4210+/* ---------------------------------------------------------------------- */
4211+
86dc4139
AM
4212+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4213+{
4214+ return br->br_path.mnt;
4215+}
4216+
4217+static inline struct dentry *au_br_dentry(struct au_branch *br)
4218+{
4219+ return br->br_path.dentry;
4220+}
4221+
4222+static inline struct super_block *au_br_sb(struct au_branch *br)
4223+{
4224+ return au_br_mnt(br)->mnt_sb;
4225+}
4226+
1facf9fc 4227+static inline int au_br_rdonly(struct au_branch *br)
4228+{
86dc4139 4229+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 4230+ || !au_br_writable(br->br_perm))
4231+ ? -EROFS : 0;
4232+}
4233+
4a4d8108 4234+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4235+{
4a4d8108 4236+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4237+ return !(brperm & AuBrPerm_RR);
1facf9fc 4238+#else
4239+ return 0;
4240+#endif
4241+}
4242+
4243+/* ---------------------------------------------------------------------- */
4244+
4245+/* branch.c */
4246+struct au_sbinfo;
4247+void au_br_free(struct au_sbinfo *sinfo);
4248+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4249+struct au_opt_add;
4250+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4251+struct au_opt_del;
4252+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4253+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4254+#ifdef CONFIG_COMPAT
4255+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4256+#endif
1facf9fc 4257+struct au_opt_mod;
4258+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4259+ int *do_refresh);
076b876e
AM
4260+struct aufs_stfs;
4261+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4262+
4263+/* xino.c */
4264+static const loff_t au_loff_max = LLONG_MAX;
4265+
4266+int au_xib_trunc(struct super_block *sb);
4267+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
4268+ loff_t *pos);
4269+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
4270+ loff_t *pos);
4271+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
4272+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
4273+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 4274+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4275+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4276+ ino_t ino);
4277+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4278+ ino_t *ino);
4279+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4280+ struct file *base_file, int do_test);
4281+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
4282+
4283+struct au_opt_xino;
4284+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
4285+void au_xino_clr(struct super_block *sb);
4286+struct file *au_xino_def(struct super_block *sb);
4287+int au_xino_path(struct seq_file *seq, struct file *file);
4288+
4289+/* ---------------------------------------------------------------------- */
4290+
4291+/* Superblock to branch */
4292+static inline
4293+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4294+{
4295+ return au_sbr(sb, bindex)->br_id;
4296+}
4297+
4298+static inline
4299+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4300+{
86dc4139 4301+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4302+}
4303+
4304+static inline
4305+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4306+{
86dc4139 4307+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4308+}
4309+
4310+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
4311+{
e49829fe 4312+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 4313+}
4314+
4315+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4316+{
4317+ return au_sbr(sb, bindex)->br_perm;
4318+}
4319+
4320+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4321+{
4322+ return au_br_whable(au_sbr_perm(sb, bindex));
4323+}
4324+
4325+/* ---------------------------------------------------------------------- */
4326+
4327+/*
4328+ * wbr_wh_read_lock, wbr_wh_write_lock
4329+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
4330+ */
4331+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
4332+
dece6358
AM
4333+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
4334+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
4335+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
4336+
076b876e
AM
4337+/* ---------------------------------------------------------------------- */
4338+
4339+#ifdef CONFIG_AUFS_FHSM
4340+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4341+{
4342+ mutex_init(&brfhsm->bf_lock);
4343+ brfhsm->bf_jiffy = 0;
4344+ brfhsm->bf_readable = 0;
4345+}
4346+
4347+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4348+{
4349+ mutex_destroy(&brfhsm->bf_lock);
4350+}
4351+#else
4352+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4353+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4354+#endif
4355+
1facf9fc 4356+#endif /* __KERNEL__ */
4357+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4358diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4359--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
2000de60 4360+++ linux/fs/aufs/conf.mk 2015-03-27 21:56:35.460128334 +0100
c1595e42 4361@@ -0,0 +1,38 @@
4a4d8108
AM
4362+
4363+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4364+
4365+define AuConf
4366+ifdef ${1}
4367+AuConfStr += ${1}=${${1}}
4368+endif
4369+endef
4370+
b752ccd1 4371+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4372+ SBILIST \
7f207e10 4373+ HNOTIFY HFSNOTIFY \
4a4d8108 4374+ EXPORT INO_T_64 \
c1595e42 4375+ XATTR \
076b876e 4376+ FHSM \
4a4d8108 4377+ RDU \
4a4d8108
AM
4378+ SHWH \
4379+ BR_RAMFS \
4380+ BR_FUSE POLL \
4381+ BR_HFSPLUS \
4382+ BDEV_LOOP \
b752ccd1
AM
4383+ DEBUG MAGIC_SYSRQ
4384+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4385+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4386+
4387+AuConfName = ${obj}/conf.str
4388+${AuConfName}.tmp: FORCE
4389+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4390+${AuConfName}: ${AuConfName}.tmp
4391+ @diff -q $< $@ > /dev/null 2>&1 || { \
4392+ echo ' GEN ' $@; \
4393+ cp -p $< $@; \
4394+ }
4395+FORCE:
4396+clean-files += ${AuConfName} ${AuConfName}.tmp
4397+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4398+
4399+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4400diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4401--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
2000de60 4402+++ linux/fs/aufs/cpup.c 2015-03-27 21:56:35.460128334 +0100
c1595e42 4403@@ -0,0 +1,1303 @@
1facf9fc 4404+/*
2000de60 4405+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 4406+ *
4407+ * This program, aufs is free software; you can redistribute it and/or modify
4408+ * it under the terms of the GNU General Public License as published by
4409+ * the Free Software Foundation; either version 2 of the License, or
4410+ * (at your option) any later version.
dece6358
AM
4411+ *
4412+ * This program is distributed in the hope that it will be useful,
4413+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4415+ * GNU General Public License for more details.
4416+ *
4417+ * You should have received a copy of the GNU General Public License
523b37e3 4418+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4419+ */
4420+
4421+/*
4422+ * copy-up functions, see wbr_policy.c for copy-down
4423+ */
4424+
4425+#include <linux/fs_stack.h>
dece6358 4426+#include <linux/mm.h>
1facf9fc 4427+#include "aufs.h"
4428+
86dc4139 4429+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4430+{
4431+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4432+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4433+
86dc4139
AM
4434+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4435+
4436+ dst->i_flags |= iflags & ~mask;
1facf9fc 4437+ if (au_test_fs_notime(dst->i_sb))
4438+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4439+}
4440+
4441+void au_cpup_attr_timesizes(struct inode *inode)
4442+{
4443+ struct inode *h_inode;
4444+
4445+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4446+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 4447+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 4448+}
4449+
4450+void au_cpup_attr_nlink(struct inode *inode, int force)
4451+{
4452+ struct inode *h_inode;
4453+ struct super_block *sb;
4454+ aufs_bindex_t bindex, bend;
4455+
4456+ sb = inode->i_sb;
4457+ bindex = au_ibstart(inode);
4458+ h_inode = au_h_iptr(inode, bindex);
4459+ if (!force
4460+ && !S_ISDIR(h_inode->i_mode)
4461+ && au_opt_test(au_mntflags(sb), PLINK)
4462+ && au_plink_test(inode))
4463+ return;
4464+
7eafdf33
AM
4465+ /*
4466+ * 0 can happen in revalidating.
38d290e6
JR
4467+ * h_inode->i_mutex may not be held here, but it is harmless since once
4468+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
4469+ * case.
4470+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
4471+ * the incorrect link count.
7eafdf33 4472+ */
92d182d2 4473+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 4474+
4475+ /*
4476+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
4477+ * it may includes whplink directory.
4478+ */
4479+ if (S_ISDIR(h_inode->i_mode)) {
4480+ bend = au_ibend(inode);
4481+ for (bindex++; bindex <= bend; bindex++) {
4482+ h_inode = au_h_iptr(inode, bindex);
4483+ if (h_inode)
4484+ au_add_nlink(inode, h_inode);
4485+ }
4486+ }
4487+}
4488+
4489+void au_cpup_attr_changeable(struct inode *inode)
4490+{
4491+ struct inode *h_inode;
4492+
4493+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4494+ inode->i_mode = h_inode->i_mode;
4495+ inode->i_uid = h_inode->i_uid;
4496+ inode->i_gid = h_inode->i_gid;
4497+ au_cpup_attr_timesizes(inode);
86dc4139 4498+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 4499+}
4500+
4501+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
4502+{
4503+ struct au_iinfo *iinfo = au_ii(inode);
4504+
1308ab2a 4505+ IiMustWriteLock(inode);
4506+
1facf9fc 4507+ iinfo->ii_higen = h_inode->i_generation;
4508+ iinfo->ii_hsb1 = h_inode->i_sb;
4509+}
4510+
4511+void au_cpup_attr_all(struct inode *inode, int force)
4512+{
4513+ struct inode *h_inode;
4514+
4515+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4516+ au_cpup_attr_changeable(inode);
4517+ if (inode->i_nlink > 0)
4518+ au_cpup_attr_nlink(inode, force);
4519+ inode->i_rdev = h_inode->i_rdev;
4520+ inode->i_blkbits = h_inode->i_blkbits;
4521+ au_cpup_igen(inode, h_inode);
4522+}
4523+
4524+/* ---------------------------------------------------------------------- */
4525+
4526+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
4527+
4528+/* keep the timestamps of the parent dir when cpup */
4529+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4530+ struct path *h_path)
4531+{
4532+ struct inode *h_inode;
4533+
4534+ dt->dt_dentry = dentry;
4535+ dt->dt_h_path = *h_path;
4536+ h_inode = h_path->dentry->d_inode;
4537+ dt->dt_atime = h_inode->i_atime;
4538+ dt->dt_mtime = h_inode->i_mtime;
4539+ /* smp_mb(); */
4540+}
4541+
4542+void au_dtime_revert(struct au_dtime *dt)
4543+{
4544+ struct iattr attr;
4545+ int err;
4546+
4547+ attr.ia_atime = dt->dt_atime;
4548+ attr.ia_mtime = dt->dt_mtime;
4549+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
4550+ | ATTR_ATIME | ATTR_ATIME_SET;
4551+
523b37e3
AM
4552+ /* no delegation since this is a directory */
4553+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 4554+ if (unlikely(err))
0c3ec466 4555+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 4556+}
4557+
4558+/* ---------------------------------------------------------------------- */
4559+
86dc4139
AM
4560+/* internal use only */
4561+struct au_cpup_reg_attr {
4562+ int valid;
4563+ struct kstat st;
4564+ unsigned int iflags; /* inode->i_flags */
4565+};
4566+
1facf9fc 4567+static noinline_for_stack
86dc4139
AM
4568+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
4569+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4570+{
c1595e42 4571+ int err, sbits, icex;
1facf9fc 4572+ struct iattr ia;
4573+ struct path h_path;
1308ab2a 4574+ struct inode *h_isrc, *h_idst;
86dc4139 4575+ struct kstat *h_st;
c1595e42 4576+ struct au_branch *br;
1facf9fc 4577+
4578+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 4579+ h_idst = h_path.dentry->d_inode;
c1595e42
JR
4580+ br = au_sbr(dst->d_sb, bindex);
4581+ h_path.mnt = au_br_mnt(br);
1facf9fc 4582+ h_isrc = h_src->d_inode;
1308ab2a 4583+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 4584+ | ATTR_ATIME | ATTR_MTIME
4585+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
4586+ if (h_src_attr && h_src_attr->valid) {
4587+ h_st = &h_src_attr->st;
4588+ ia.ia_uid = h_st->uid;
4589+ ia.ia_gid = h_st->gid;
4590+ ia.ia_atime = h_st->atime;
4591+ ia.ia_mtime = h_st->mtime;
4592+ if (h_idst->i_mode != h_st->mode
4593+ && !S_ISLNK(h_idst->i_mode)) {
4594+ ia.ia_valid |= ATTR_MODE;
4595+ ia.ia_mode = h_st->mode;
4596+ }
4597+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
4598+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
4599+ } else {
4600+ ia.ia_uid = h_isrc->i_uid;
4601+ ia.ia_gid = h_isrc->i_gid;
4602+ ia.ia_atime = h_isrc->i_atime;
4603+ ia.ia_mtime = h_isrc->i_mtime;
4604+ if (h_idst->i_mode != h_isrc->i_mode
4605+ && !S_ISLNK(h_idst->i_mode)) {
4606+ ia.ia_valid |= ATTR_MODE;
4607+ ia.ia_mode = h_isrc->i_mode;
4608+ }
4609+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
4610+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 4611+ }
523b37e3
AM
4612+ /* no delegation since it is just created */
4613+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4614+
4615+ /* is this nfs only? */
4616+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
4617+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
4618+ ia.ia_mode = h_isrc->i_mode;
523b37e3 4619+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4620+ }
4621+
c1595e42
JR
4622+ icex = br->br_perm & AuBrAttr_ICEX;
4623+ if (!err)
4624+ err = au_cpup_xattr(h_path.dentry, h_src, icex);
4625+
1facf9fc 4626+ return err;
4627+}
4628+
4629+/* ---------------------------------------------------------------------- */
4630+
4631+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
4632+ char *buf, unsigned long blksize)
4633+{
4634+ int err;
4635+ size_t sz, rbytes, wbytes;
4636+ unsigned char all_zero;
4637+ char *p, *zp;
4638+ struct mutex *h_mtx;
4639+ /* reduce stack usage */
4640+ struct iattr *ia;
4641+
4642+ zp = page_address(ZERO_PAGE(0));
4643+ if (unlikely(!zp))
4644+ return -ENOMEM; /* possible? */
4645+
4646+ err = 0;
4647+ all_zero = 0;
4648+ while (len) {
4649+ AuDbg("len %lld\n", len);
4650+ sz = blksize;
4651+ if (len < blksize)
4652+ sz = len;
4653+
4654+ rbytes = 0;
4655+ /* todo: signal_pending? */
4656+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
4657+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
4658+ err = rbytes;
4659+ }
4660+ if (unlikely(err < 0))
4661+ break;
4662+
4663+ all_zero = 0;
4664+ if (len >= rbytes && rbytes == blksize)
4665+ all_zero = !memcmp(buf, zp, rbytes);
4666+ if (!all_zero) {
4667+ wbytes = rbytes;
4668+ p = buf;
4669+ while (wbytes) {
4670+ size_t b;
4671+
4672+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
4673+ err = b;
4674+ /* todo: signal_pending? */
4675+ if (unlikely(err == -EAGAIN || err == -EINTR))
4676+ continue;
4677+ if (unlikely(err < 0))
4678+ break;
4679+ wbytes -= b;
4680+ p += b;
4681+ }
392086de
AM
4682+ if (unlikely(err < 0))
4683+ break;
1facf9fc 4684+ } else {
4685+ loff_t res;
4686+
4687+ AuLabel(hole);
4688+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
4689+ err = res;
4690+ if (unlikely(res < 0))
4691+ break;
4692+ }
4693+ len -= rbytes;
4694+ err = 0;
4695+ }
4696+
4697+ /* the last block may be a hole */
4698+ if (!err && all_zero) {
4699+ AuLabel(last hole);
4700+
4701+ err = 1;
2000de60 4702+ if (au_test_nfs(dst->f_path.dentry->d_sb)) {
1facf9fc 4703+ /* nfs requires this step to make last hole */
4704+ /* is this only nfs? */
4705+ do {
4706+ /* todo: signal_pending? */
4707+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
4708+ } while (err == -EAGAIN || err == -EINTR);
4709+ if (err == 1)
4710+ dst->f_pos--;
4711+ }
4712+
4713+ if (err == 1) {
4714+ ia = (void *)buf;
4715+ ia->ia_size = dst->f_pos;
4716+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
4717+ ia->ia_file = dst;
c06a8ce3 4718+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 4719+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
523b37e3
AM
4720+ /* no delegation since it is just created */
4721+ err = vfsub_notify_change(&dst->f_path, ia,
4722+ /*delegated*/NULL);
1facf9fc 4723+ mutex_unlock(h_mtx);
4724+ }
4725+ }
4726+
4727+ return err;
4728+}
4729+
4730+int au_copy_file(struct file *dst, struct file *src, loff_t len)
4731+{
4732+ int err;
4733+ unsigned long blksize;
4734+ unsigned char do_kfree;
4735+ char *buf;
4736+
4737+ err = -ENOMEM;
2000de60 4738+ blksize = dst->f_path.dentry->d_sb->s_blocksize;
1facf9fc 4739+ if (!blksize || PAGE_SIZE < blksize)
4740+ blksize = PAGE_SIZE;
4741+ AuDbg("blksize %lu\n", blksize);
4742+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
4743+ if (do_kfree)
4744+ buf = kmalloc(blksize, GFP_NOFS);
4745+ else
4746+ buf = (void *)__get_free_page(GFP_NOFS);
4747+ if (unlikely(!buf))
4748+ goto out;
4749+
4750+ if (len > (1 << 22))
4751+ AuDbg("copying a large file %lld\n", (long long)len);
4752+
4753+ src->f_pos = 0;
4754+ dst->f_pos = 0;
4755+ err = au_do_copy_file(dst, src, len, buf, blksize);
4756+ if (do_kfree)
4757+ kfree(buf);
4758+ else
4759+ free_page((unsigned long)buf);
4760+
4f0767ce 4761+out:
1facf9fc 4762+ return err;
4763+}
4764+
4765+/*
4766+ * to support a sparse file which is opened with O_APPEND,
4767+ * we need to close the file.
4768+ */
c2b27bf2 4769+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 4770+{
4771+ int err, i;
4772+ enum { SRC, DST };
4773+ struct {
4774+ aufs_bindex_t bindex;
4775+ unsigned int flags;
4776+ struct dentry *dentry;
392086de 4777+ int force_wr;
1facf9fc 4778+ struct file *file;
523b37e3 4779+ void *label;
1facf9fc 4780+ } *f, file[] = {
4781+ {
c2b27bf2 4782+ .bindex = cpg->bsrc,
1facf9fc 4783+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 4784+ .label = &&out
1facf9fc 4785+ },
4786+ {
c2b27bf2 4787+ .bindex = cpg->bdst,
1facf9fc 4788+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 4789+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 4790+ .label = &&out_src
1facf9fc 4791+ }
4792+ };
4793+ struct super_block *sb;
4794+
4795+ /* bsrc branch can be ro/rw. */
c2b27bf2 4796+ sb = cpg->dentry->d_sb;
1facf9fc 4797+ f = file;
4798+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
4799+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
4800+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 4801+ /*file*/NULL, f->force_wr);
1facf9fc 4802+ err = PTR_ERR(f->file);
4803+ if (IS_ERR(f->file))
4804+ goto *f->label;
1facf9fc 4805+ }
4806+
4807+ /* try stopping to update while we copyup */
4808+ IMustLock(file[SRC].dentry->d_inode);
c2b27bf2 4809+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 4810+
1facf9fc 4811+ fput(file[DST].file);
4812+ au_sbr_put(sb, file[DST].bindex);
523b37e3 4813+
4f0767ce 4814+out_src:
1facf9fc 4815+ fput(file[SRC].file);
4816+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 4817+out:
1facf9fc 4818+ return err;
4819+}
4820+
c2b27bf2 4821+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 4822+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4823+{
4824+ int err, rerr;
4825+ loff_t l;
86dc4139 4826+ struct path h_path;
38d290e6 4827+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 4828+
4829+ err = 0;
c2b27bf2 4830+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
86dc4139 4831+ l = i_size_read(h_src_inode);
c2b27bf2
AM
4832+ if (cpg->len == -1 || l < cpg->len)
4833+ cpg->len = l;
4834+ if (cpg->len) {
86dc4139
AM
4835+ /* try stopping to update while we are referencing */
4836+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2 4837+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 4838+
c2b27bf2
AM
4839+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
4840+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139
AM
4841+ h_src_attr->iflags = h_src_inode->i_flags;
4842+ err = vfs_getattr(&h_path, &h_src_attr->st);
4843+ if (unlikely(err)) {
4844+ mutex_unlock(&h_src_inode->i_mutex);
4845+ goto out;
4846+ }
4847+ h_src_attr->valid = 1;
c2b27bf2 4848+ err = au_cp_regular(cpg);
86dc4139 4849+ mutex_unlock(&h_src_inode->i_mutex);
c2b27bf2 4850+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
4851+ if (!err && rerr)
4852+ err = rerr;
1facf9fc 4853+ }
38d290e6
JR
4854+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
4855+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
4856+ h_dst_inode = h_path.dentry->d_inode;
4857+ spin_lock(&h_dst_inode->i_lock);
4858+ h_dst_inode->i_state |= I_LINKABLE;
4859+ spin_unlock(&h_dst_inode->i_lock);
4860+ }
1facf9fc 4861+
4f0767ce 4862+out:
1facf9fc 4863+ return err;
4864+}
4865+
4866+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
4867+ struct inode *h_dir)
4868+{
4869+ int err, symlen;
4870+ mm_segment_t old_fs;
b752ccd1
AM
4871+ union {
4872+ char *k;
4873+ char __user *u;
4874+ } sym;
1facf9fc 4875+
4876+ err = -ENOSYS;
4877+ if (unlikely(!h_src->d_inode->i_op->readlink))
4878+ goto out;
4879+
4880+ err = -ENOMEM;
537831f9 4881+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 4882+ if (unlikely(!sym.k))
1facf9fc 4883+ goto out;
4884+
9dbd164d 4885+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 4886+ old_fs = get_fs();
4887+ set_fs(KERNEL_DS);
b752ccd1 4888+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 4889+ err = symlen;
4890+ set_fs(old_fs);
4891+
4892+ if (symlen > 0) {
b752ccd1
AM
4893+ sym.k[symlen] = 0;
4894+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 4895+ }
537831f9 4896+ free_page((unsigned long)sym.k);
1facf9fc 4897+
4f0767ce 4898+out:
1facf9fc 4899+ return err;
4900+}
4901+
1facf9fc 4902+static noinline_for_stack
c2b27bf2 4903+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 4904+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4905+{
4906+ int err;
4907+ umode_t mode;
4908+ unsigned int mnt_flags;
076b876e 4909+ unsigned char isdir, isreg, force;
c2b27bf2 4910+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4911+ struct au_dtime dt;
4912+ struct path h_path;
4913+ struct dentry *h_src, *h_dst, *h_parent;
4914+ struct inode *h_inode, *h_dir;
4915+ struct super_block *sb;
4916+
4917+ /* bsrc branch can be ro/rw. */
c2b27bf2 4918+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
1facf9fc 4919+ h_inode = h_src->d_inode;
c2b27bf2 4920+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
1facf9fc 4921+
4922+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
4923+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
4924+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
4925+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
4926+ AUFS_WH_PFX_LEN));
1facf9fc 4927+ h_parent = h_dst->d_parent; /* dir inode is locked */
4928+ h_dir = h_parent->d_inode;
4929+ IMustLock(h_dir);
4930+ AuDebugOn(h_parent != h_dst->d_parent);
4931+
c2b27bf2
AM
4932+ sb = cpg->dentry->d_sb;
4933+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 4934+ if (do_dt) {
4935+ h_path.dentry = h_parent;
4936+ au_dtime_store(&dt, dst_parent, &h_path);
4937+ }
4938+ h_path.dentry = h_dst;
4939+
076b876e 4940+ isreg = 0;
1facf9fc 4941+ isdir = 0;
4942+ mode = h_inode->i_mode;
4943+ switch (mode & S_IFMT) {
4944+ case S_IFREG:
076b876e 4945+ isreg = 1;
b4510431
AM
4946+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
4947+ /*want_excl*/true);
1facf9fc 4948+ if (!err)
c2b27bf2 4949+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 4950+ break;
4951+ case S_IFDIR:
4952+ isdir = 1;
4953+ err = vfsub_mkdir(h_dir, &h_path, mode);
4954+ if (!err) {
4955+ /*
4956+ * strange behaviour from the users view,
4957+ * particularry setattr case
4958+ */
c2b27bf2 4959+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
1facf9fc 4960+ au_cpup_attr_nlink(dst_parent->d_inode,
4961+ /*force*/1);
c2b27bf2 4962+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
1facf9fc 4963+ }
4964+ break;
4965+ case S_IFLNK:
4966+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
4967+ break;
4968+ case S_IFCHR:
4969+ case S_IFBLK:
4970+ AuDebugOn(!capable(CAP_MKNOD));
4971+ /*FALLTHROUGH*/
4972+ case S_IFIFO:
4973+ case S_IFSOCK:
4974+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
4975+ break;
4976+ default:
4977+ AuIOErr("Unknown inode type 0%o\n", mode);
4978+ err = -EIO;
4979+ }
4980+
4981+ mnt_flags = au_mntflags(sb);
4982+ if (!au_opt_test(mnt_flags, UDBA_NONE)
4983+ && !isdir
4984+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
4985+ && (h_inode->i_nlink == 1
4986+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 4987+ /* todo: unnecessary? */
c2b27bf2
AM
4988+ /* && cpg->dentry->d_inode->i_nlink == 1 */
4989+ && cpg->bdst < cpg->bsrc
4990+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
4991+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 4992+ /* ignore this error */
4993+
076b876e
AM
4994+ if (!err) {
4995+ force = 0;
4996+ if (isreg) {
4997+ force = !!cpg->len;
4998+ if (cpg->len == -1)
4999+ force = !!i_size_read(h_inode);
5000+ }
5001+ au_fhsm_wrote(sb, cpg->bdst, force);
5002+ }
5003+
1facf9fc 5004+ if (do_dt)
5005+ au_dtime_revert(&dt);
5006+ return err;
5007+}
5008+
392086de 5009+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
5010+{
5011+ int err;
392086de 5012+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 5013+ struct inode *h_dir;
392086de 5014+ aufs_bindex_t bdst;
86dc4139 5015+
392086de
AM
5016+ dentry = cpg->dentry;
5017+ bdst = cpg->bdst;
5018+ h_dentry = au_h_dptr(dentry, bdst);
5019+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
5020+ dget(h_dentry);
5021+ au_set_h_dptr(dentry, bdst, NULL);
5022+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
5023+ if (!err)
5024+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 5025+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
5026+ } else {
5027+ err = 0;
5028+ parent = dget_parent(dentry);
5029+ h_parent = au_h_dptr(parent, bdst);
5030+ dput(parent);
5031+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
5032+ if (IS_ERR(h_path->dentry))
5033+ err = PTR_ERR(h_path->dentry);
86dc4139 5034+ }
392086de
AM
5035+ if (unlikely(err))
5036+ goto out;
86dc4139 5037+
86dc4139
AM
5038+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5039+ h_dir = h_parent->d_inode;
5040+ IMustLock(h_dir);
523b37e3
AM
5041+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
5042+ /* no delegation since it is just created */
5043+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL);
86dc4139
AM
5044+ dput(h_path->dentry);
5045+
5046+out:
5047+ return err;
5048+}
5049+
1facf9fc 5050+/*
5051+ * copyup the @dentry from @bsrc to @bdst.
5052+ * the caller must set the both of lower dentries.
5053+ * @len is for truncating when it is -1 copyup the entire file.
5054+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 5055+ * basic->bsrc can be larger than basic->bdst.
1facf9fc 5056+ */
c2b27bf2 5057+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5058+{
5059+ int err, rerr;
5060+ aufs_bindex_t old_ibstart;
5061+ unsigned char isdir, plink;
1facf9fc 5062+ struct dentry *h_src, *h_dst, *h_parent;
523b37e3 5063+ struct inode *dst_inode, *h_dir, *inode, *delegated;
1facf9fc 5064+ struct super_block *sb;
86dc4139 5065+ struct au_branch *br;
c2b27bf2
AM
5066+ /* to reuduce stack size */
5067+ struct {
5068+ struct au_dtime dt;
5069+ struct path h_path;
5070+ struct au_cpup_reg_attr h_src_attr;
5071+ } *a;
1facf9fc 5072+
c2b27bf2
AM
5073+ err = -ENOMEM;
5074+ a = kmalloc(sizeof(*a), GFP_NOFS);
5075+ if (unlikely(!a))
5076+ goto out;
5077+ a->h_src_attr.valid = 0;
1facf9fc 5078+
c2b27bf2
AM
5079+ sb = cpg->dentry->d_sb;
5080+ br = au_sbr(sb, cpg->bdst);
5081+ a->h_path.mnt = au_br_mnt(br);
5082+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 5083+ h_parent = h_dst->d_parent; /* dir inode is locked */
5084+ h_dir = h_parent->d_inode;
5085+ IMustLock(h_dir);
5086+
c2b27bf2
AM
5087+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5088+ inode = cpg->dentry->d_inode;
1facf9fc 5089+
5090+ if (!dst_parent)
c2b27bf2 5091+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 5092+ else
5093+ dget(dst_parent);
5094+
5095+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 5096+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 5097+ if (dst_inode) {
5098+ if (unlikely(!plink)) {
5099+ err = -EIO;
027c5e7a
AM
5100+ AuIOErr("hi%lu(i%lu) exists on b%d "
5101+ "but plink is disabled\n",
c2b27bf2
AM
5102+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5103+ goto out_parent;
1facf9fc 5104+ }
5105+
5106+ if (dst_inode->i_nlink) {
c2b27bf2 5107+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5108+
c2b27bf2 5109+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 5110+ err = PTR_ERR(h_src);
5111+ if (IS_ERR(h_src))
c2b27bf2 5112+ goto out_parent;
1facf9fc 5113+ if (unlikely(!h_src->d_inode)) {
5114+ err = -EIO;
5115+ AuIOErr("i%lu exists on a upper branch "
027c5e7a
AM
5116+ "but not pseudo-linked\n",
5117+ inode->i_ino);
1facf9fc 5118+ dput(h_src);
c2b27bf2 5119+ goto out_parent;
1facf9fc 5120+ }
5121+
5122+ if (do_dt) {
c2b27bf2
AM
5123+ a->h_path.dentry = h_parent;
5124+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 5125+ }
86dc4139 5126+
c2b27bf2 5127+ a->h_path.dentry = h_dst;
523b37e3
AM
5128+ delegated = NULL;
5129+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 5130+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 5131+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 5132+ if (do_dt)
c2b27bf2 5133+ au_dtime_revert(&a->dt);
523b37e3
AM
5134+ if (unlikely(err == -EWOULDBLOCK)) {
5135+ pr_warn("cannot retry for NFSv4 delegation"
5136+ " for an internal link\n");
5137+ iput(delegated);
5138+ }
1facf9fc 5139+ dput(h_src);
c2b27bf2 5140+ goto out_parent;
1facf9fc 5141+ } else
5142+ /* todo: cpup_wh_file? */
5143+ /* udba work */
4a4d8108 5144+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 5145+ }
5146+
86dc4139 5147+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 5148+ old_ibstart = au_ibstart(inode);
c2b27bf2 5149+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 5150+ if (unlikely(err))
86dc4139 5151+ goto out_rev;
1facf9fc 5152+ dst_inode = h_dst->d_inode;
5153+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139 5154+ /* todo: necessary? */
c2b27bf2 5155+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5156+
c2b27bf2 5157+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5158+ if (unlikely(err)) {
5159+ /* todo: necessary? */
c2b27bf2 5160+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
86dc4139
AM
5161+ mutex_unlock(&dst_inode->i_mutex);
5162+ goto out_rev;
5163+ }
5164+
c2b27bf2 5165+ if (cpg->bdst < old_ibstart) {
86dc4139 5166+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5167+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5168+ if (unlikely(err)) {
c2b27bf2
AM
5169+ /* ignore an error */
5170+ /* au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5171+ mutex_unlock(&dst_inode->i_mutex);
5172+ goto out_rev;
4a4d8108 5173+ }
4a4d8108 5174+ }
c2b27bf2
AM
5175+ au_set_ibstart(inode, cpg->bdst);
5176+ } else
5177+ au_set_ibend(inode, cpg->bdst);
5178+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5179+ au_hi_flags(inode, isdir));
5180+
5181+ /* todo: necessary? */
c2b27bf2 5182+ /* err = au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5183+ mutex_unlock(&dst_inode->i_mutex);
5184+ if (unlikely(err))
5185+ goto out_rev;
5186+
5187+ if (!isdir
38d290e6
JR
5188+ && (h_src->d_inode->i_nlink > 1
5189+ || h_src->d_inode->i_state & I_LINKABLE)
86dc4139 5190+ && plink)
c2b27bf2 5191+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5192+
c2b27bf2
AM
5193+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5194+ a->h_path.dentry = h_dst;
392086de 5195+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5196+ }
5197+ if (!err)
c2b27bf2 5198+ goto out_parent; /* success */
1facf9fc 5199+
5200+ /* revert */
4a4d8108 5201+out_rev:
c2b27bf2
AM
5202+ a->h_path.dentry = h_parent;
5203+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5204+ a->h_path.dentry = h_dst;
86dc4139
AM
5205+ rerr = 0;
5206+ if (h_dst->d_inode) {
523b37e3
AM
5207+ if (!isdir) {
5208+ /* no delegation since it is just created */
5209+ rerr = vfsub_unlink(h_dir, &a->h_path,
5210+ /*delegated*/NULL, /*force*/0);
5211+ } else
c2b27bf2 5212+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5213+ }
c2b27bf2 5214+ au_dtime_revert(&a->dt);
1facf9fc 5215+ if (rerr) {
5216+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5217+ err = -EIO;
5218+ }
c2b27bf2 5219+out_parent:
1facf9fc 5220+ dput(dst_parent);
c2b27bf2
AM
5221+ kfree(a);
5222+out:
1facf9fc 5223+ return err;
5224+}
5225+
c2b27bf2 5226+#if 0 /* unused */
1facf9fc 5227+struct au_cpup_single_args {
5228+ int *errp;
c2b27bf2 5229+ struct au_cp_generic *cpg;
1facf9fc 5230+ struct dentry *dst_parent;
5231+};
5232+
5233+static void au_call_cpup_single(void *args)
5234+{
5235+ struct au_cpup_single_args *a = args;
86dc4139 5236+
c2b27bf2
AM
5237+ au_pin_hdir_acquire_nest(a->cpg->pin);
5238+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5239+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5240+}
c2b27bf2 5241+#endif
1facf9fc 5242+
53392da6
AM
5243+/*
5244+ * prevent SIGXFSZ in copy-up.
5245+ * testing CAP_MKNOD is for generic fs,
5246+ * but CAP_FSETID is for xfs only, currently.
5247+ */
86dc4139 5248+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5249+{
5250+ int do_sio;
86dc4139
AM
5251+ struct super_block *sb;
5252+ struct inode *h_dir;
53392da6
AM
5253+
5254+ do_sio = 0;
86dc4139 5255+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5256+ if (!au_wkq_test()
5257+ && (!au_sbi(sb)->si_plink_maint_pid
5258+ || au_plink_maint(sb, AuLock_NOPLM))) {
5259+ switch (mode & S_IFMT) {
5260+ case S_IFREG:
5261+ /* no condition about RLIMIT_FSIZE and the file size */
5262+ do_sio = 1;
5263+ break;
5264+ case S_IFCHR:
5265+ case S_IFBLK:
5266+ do_sio = !capable(CAP_MKNOD);
5267+ break;
5268+ }
5269+ if (!do_sio)
5270+ do_sio = ((mode & (S_ISUID | S_ISGID))
5271+ && !capable(CAP_FSETID));
86dc4139
AM
5272+ /* this workaround may be removed in the future */
5273+ if (!do_sio) {
5274+ h_dir = au_pinned_h_dir(pin);
5275+ do_sio = h_dir->i_mode & S_ISVTX;
5276+ }
53392da6
AM
5277+ }
5278+
5279+ return do_sio;
5280+}
5281+
c2b27bf2
AM
5282+#if 0 /* unused */
5283+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5284+{
5285+ int err, wkq_err;
1facf9fc 5286+ struct dentry *h_dentry;
5287+
c2b27bf2 5288+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
86dc4139 5289+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
c2b27bf2 5290+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 5291+ else {
5292+ struct au_cpup_single_args args = {
5293+ .errp = &err,
c2b27bf2
AM
5294+ .cpg = cpg,
5295+ .dst_parent = dst_parent
1facf9fc 5296+ };
5297+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5298+ if (unlikely(wkq_err))
5299+ err = wkq_err;
5300+ }
5301+
5302+ return err;
5303+}
c2b27bf2 5304+#endif
1facf9fc 5305+
5306+/*
5307+ * copyup the @dentry from the first active lower branch to @bdst,
5308+ * using au_cpup_single().
5309+ */
c2b27bf2 5310+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5311+{
5312+ int err;
c2b27bf2
AM
5313+ unsigned int flags_orig;
5314+ struct dentry *dentry;
5315+
5316+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 5317+
c2b27bf2 5318+ dentry = cpg->dentry;
86dc4139 5319+ DiMustWriteLock(dentry);
1facf9fc 5320+
c2b27bf2 5321+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 5322+ if (!err) {
c2b27bf2
AM
5323+ flags_orig = cpg->flags;
5324+ au_fset_cpup(cpg->flags, RENAME);
5325+ err = au_cpup_single(cpg, NULL);
5326+ cpg->flags = flags_orig;
1facf9fc 5327+ if (!err)
5328+ return 0; /* success */
5329+
5330+ /* revert */
c2b27bf2
AM
5331+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5332+ au_set_dbstart(dentry, cpg->bsrc);
1facf9fc 5333+ }
5334+
5335+ return err;
5336+}
5337+
5338+struct au_cpup_simple_args {
5339+ int *errp;
c2b27bf2 5340+ struct au_cp_generic *cpg;
1facf9fc 5341+};
5342+
5343+static void au_call_cpup_simple(void *args)
5344+{
5345+ struct au_cpup_simple_args *a = args;
86dc4139 5346+
c2b27bf2
AM
5347+ au_pin_hdir_acquire_nest(a->cpg->pin);
5348+ *a->errp = au_cpup_simple(a->cpg);
5349+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5350+}
5351+
c2b27bf2 5352+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5353+{
5354+ int err, wkq_err;
c2b27bf2
AM
5355+ struct dentry *dentry, *parent;
5356+ struct file *h_file;
1facf9fc 5357+ struct inode *h_dir;
5358+
c2b27bf2
AM
5359+ dentry = cpg->dentry;
5360+ h_file = NULL;
5361+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
5362+ AuDebugOn(cpg->bsrc < 0);
392086de 5363+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
5364+ err = PTR_ERR(h_file);
5365+ if (IS_ERR(h_file))
5366+ goto out;
5367+ }
5368+
1facf9fc 5369+ parent = dget_parent(dentry);
c2b27bf2 5370+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
53392da6 5371+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
5372+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
5373+ err = au_cpup_simple(cpg);
1facf9fc 5374+ else {
5375+ struct au_cpup_simple_args args = {
5376+ .errp = &err,
c2b27bf2 5377+ .cpg = cpg
1facf9fc 5378+ };
5379+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
5380+ if (unlikely(wkq_err))
5381+ err = wkq_err;
5382+ }
5383+
5384+ dput(parent);
c2b27bf2
AM
5385+ if (h_file)
5386+ au_h_open_post(dentry, cpg->bsrc, h_file);
5387+
5388+out:
1facf9fc 5389+ return err;
5390+}
5391+
c2b27bf2 5392+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 5393+{
c2b27bf2
AM
5394+ aufs_bindex_t bsrc, bend;
5395+ struct dentry *dentry, *h_dentry;
367653fa 5396+
c2b27bf2
AM
5397+ if (cpg->bsrc < 0) {
5398+ dentry = cpg->dentry;
5399+ bend = au_dbend(dentry);
5400+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
5401+ h_dentry = au_h_dptr(dentry, bsrc);
5402+ if (h_dentry) {
5403+ AuDebugOn(!h_dentry->d_inode);
5404+ break;
5405+ }
5406+ }
5407+ AuDebugOn(bsrc > bend);
5408+ cpg->bsrc = bsrc;
367653fa 5409+ }
c2b27bf2
AM
5410+ AuDebugOn(cpg->bsrc <= cpg->bdst);
5411+ return au_do_sio_cpup_simple(cpg);
5412+}
367653fa 5413+
c2b27bf2
AM
5414+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
5415+{
5416+ AuDebugOn(cpg->bdst <= cpg->bsrc);
5417+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
5418+}
5419+
1facf9fc 5420+/* ---------------------------------------------------------------------- */
5421+
5422+/*
5423+ * copyup the deleted file for writing.
5424+ */
c2b27bf2
AM
5425+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
5426+ struct file *file)
1facf9fc 5427+{
5428+ int err;
c2b27bf2
AM
5429+ unsigned int flags_orig;
5430+ aufs_bindex_t bsrc_orig;
1facf9fc 5431+ struct dentry *h_d_dst, *h_d_start;
c2b27bf2 5432+ struct au_dinfo *dinfo;
4a4d8108 5433+ struct au_hdentry *hdp;
1facf9fc 5434+
c2b27bf2 5435+ dinfo = au_di(cpg->dentry);
1308ab2a 5436+ AuRwMustWriteLock(&dinfo->di_rwsem);
5437+
c2b27bf2
AM
5438+ bsrc_orig = cpg->bsrc;
5439+ cpg->bsrc = dinfo->di_bstart;
4a4d8108 5440+ hdp = dinfo->di_hdentry;
c2b27bf2
AM
5441+ h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
5442+ dinfo->di_bstart = cpg->bdst;
5443+ hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
86dc4139 5444+ h_d_start = NULL;
027c5e7a 5445+ if (file) {
c2b27bf2 5446+ h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
2000de60 5447+ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_path.dentry;
027c5e7a 5448+ }
c2b27bf2
AM
5449+ flags_orig = cpg->flags;
5450+ cpg->flags = !AuCpup_DTIME;
5451+ err = au_cpup_single(cpg, /*h_parent*/NULL);
5452+ cpg->flags = flags_orig;
027c5e7a
AM
5453+ if (file) {
5454+ if (!err)
5455+ err = au_reopen_nondir(file);
c2b27bf2 5456+ hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
1facf9fc 5457+ }
c2b27bf2
AM
5458+ hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
5459+ dinfo->di_bstart = cpg->bsrc;
5460+ cpg->bsrc = bsrc_orig;
1facf9fc 5461+
5462+ return err;
5463+}
5464+
c2b27bf2 5465+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5466+{
5467+ int err;
c2b27bf2 5468+ aufs_bindex_t bdst;
1facf9fc 5469+ struct au_dtime dt;
c2b27bf2 5470+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 5471+ struct au_branch *br;
5472+ struct path h_path;
5473+
c2b27bf2
AM
5474+ dentry = cpg->dentry;
5475+ bdst = cpg->bdst;
1facf9fc 5476+ br = au_sbr(dentry->d_sb, bdst);
5477+ parent = dget_parent(dentry);
5478+ h_parent = au_h_dptr(parent, bdst);
5479+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
5480+ err = PTR_ERR(wh_dentry);
5481+ if (IS_ERR(wh_dentry))
5482+ goto out;
5483+
5484+ h_path.dentry = h_parent;
86dc4139 5485+ h_path.mnt = au_br_mnt(br);
1facf9fc 5486+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 5487+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 5488+ if (unlikely(err))
5489+ goto out_wh;
5490+
5491+ dget(wh_dentry);
5492+ h_path.dentry = wh_dentry;
2000de60 5493+ if (!d_is_dir(wh_dentry)) {
523b37e3
AM
5494+ /* no delegation since it is just created */
5495+ err = vfsub_unlink(h_parent->d_inode, &h_path,
5496+ /*delegated*/NULL, /*force*/0);
5497+ } else
4a4d8108 5498+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
1facf9fc 5499+ if (unlikely(err)) {
523b37e3
AM
5500+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
5501+ wh_dentry, err);
1facf9fc 5502+ err = -EIO;
5503+ }
5504+ au_dtime_revert(&dt);
5505+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
5506+
4f0767ce 5507+out_wh:
1facf9fc 5508+ dput(wh_dentry);
4f0767ce 5509+out:
1facf9fc 5510+ dput(parent);
5511+ return err;
5512+}
5513+
5514+struct au_cpup_wh_args {
5515+ int *errp;
c2b27bf2 5516+ struct au_cp_generic *cpg;
1facf9fc 5517+ struct file *file;
5518+};
5519+
5520+static void au_call_cpup_wh(void *args)
5521+{
5522+ struct au_cpup_wh_args *a = args;
86dc4139 5523+
c2b27bf2
AM
5524+ au_pin_hdir_acquire_nest(a->cpg->pin);
5525+ *a->errp = au_cpup_wh(a->cpg, a->file);
5526+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5527+}
5528+
c2b27bf2 5529+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5530+{
5531+ int err, wkq_err;
c2b27bf2 5532+ aufs_bindex_t bdst;
c1595e42 5533+ struct dentry *dentry, *parent, *h_orph, *h_parent;
86dc4139 5534+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 5535+ struct au_wbr *wbr;
c2b27bf2 5536+ struct au_pin wh_pin, *pin_orig;
1facf9fc 5537+
c2b27bf2
AM
5538+ dentry = cpg->dentry;
5539+ bdst = cpg->bdst;
1facf9fc 5540+ parent = dget_parent(dentry);
5541+ dir = parent->d_inode;
5542+ h_orph = NULL;
5543+ h_parent = NULL;
5544+ h_dir = au_igrab(au_h_iptr(dir, bdst));
5545+ h_tmpdir = h_dir;
c2b27bf2 5546+ pin_orig = NULL;
1facf9fc 5547+ if (!h_dir->i_nlink) {
5548+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
5549+ h_orph = wbr->wbr_orph;
5550+
5551+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 5552+ au_set_h_dptr(parent, bdst, dget(h_orph));
5553+ h_tmpdir = h_orph->d_inode;
1facf9fc 5554+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
5555+
dece6358 5556+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 5557+ /* todo: au_h_open_pre()? */
86dc4139 5558+
c2b27bf2 5559+ pin_orig = cpg->pin;
86dc4139 5560+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
5561+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
5562+ cpg->pin = &wh_pin;
1facf9fc 5563+ }
5564+
53392da6 5565+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
5566+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
5567+ err = au_cpup_wh(cpg, file);
1facf9fc 5568+ else {
5569+ struct au_cpup_wh_args args = {
5570+ .errp = &err,
c2b27bf2
AM
5571+ .cpg = cpg,
5572+ .file = file
1facf9fc 5573+ };
5574+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
5575+ if (unlikely(wkq_err))
5576+ err = wkq_err;
5577+ }
5578+
5579+ if (h_orph) {
5580+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 5581+ /* todo: au_h_open_post()? */
1facf9fc 5582+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 5583+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
5584+ AuDebugOn(!pin_orig);
5585+ cpg->pin = pin_orig;
1facf9fc 5586+ }
5587+ iput(h_dir);
5588+ dput(parent);
5589+
5590+ return err;
5591+}
5592+
5593+/* ---------------------------------------------------------------------- */
5594+
5595+/*
5596+ * generic routine for both of copy-up and copy-down.
5597+ */
5598+/* cf. revalidate function in file.c */
5599+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5600+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5601+ struct au_pin *pin,
1facf9fc 5602+ struct dentry *h_parent, void *arg),
5603+ void *arg)
5604+{
5605+ int err;
5606+ struct au_pin pin;
5607+ struct dentry *d, *parent, *h_parent, *real_parent;
5608+
5609+ err = 0;
5610+ parent = dget_parent(dentry);
5611+ if (IS_ROOT(parent))
5612+ goto out;
5613+
5614+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
5615+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
5616+
5617+ /* do not use au_dpage */
5618+ real_parent = parent;
5619+ while (1) {
5620+ dput(parent);
5621+ parent = dget_parent(dentry);
5622+ h_parent = au_h_dptr(parent, bdst);
5623+ if (h_parent)
5624+ goto out; /* success */
5625+
5626+ /* find top dir which is necessary to cpup */
5627+ do {
5628+ d = parent;
5629+ dput(parent);
5630+ parent = dget_parent(d);
5631+ di_read_lock_parent3(parent, !AuLock_IR);
5632+ h_parent = au_h_dptr(parent, bdst);
5633+ di_read_unlock(parent, !AuLock_IR);
5634+ } while (!h_parent);
5635+
5636+ if (d != real_parent)
5637+ di_write_lock_child3(d);
5638+
5639+ /* somebody else might create while we were sleeping */
5640+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
5641+ if (au_h_dptr(d, bdst))
5642+ au_update_dbstart(d);
5643+
5644+ au_pin_set_dentry(&pin, d);
5645+ err = au_do_pin(&pin);
5646+ if (!err) {
86dc4139 5647+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 5648+ au_unpin(&pin);
5649+ }
5650+ }
5651+
5652+ if (d != real_parent)
5653+ di_write_unlock(d);
5654+ if (unlikely(err))
5655+ break;
5656+ }
5657+
4f0767ce 5658+out:
1facf9fc 5659+ dput(parent);
5660+ return err;
5661+}
5662+
5663+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5664+ struct au_pin *pin,
2000de60 5665+ struct dentry *h_parent __maybe_unused,
1facf9fc 5666+ void *arg __maybe_unused)
5667+{
c2b27bf2
AM
5668+ struct au_cp_generic cpg = {
5669+ .dentry = dentry,
5670+ .bdst = bdst,
5671+ .bsrc = -1,
5672+ .len = 0,
5673+ .pin = pin,
5674+ .flags = AuCpup_DTIME
5675+ };
5676+ return au_sio_cpup_simple(&cpg);
1facf9fc 5677+}
5678+
5679+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5680+{
5681+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
5682+}
5683+
5684+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5685+{
5686+ int err;
5687+ struct dentry *parent;
5688+ struct inode *dir;
5689+
5690+ parent = dget_parent(dentry);
5691+ dir = parent->d_inode;
5692+ err = 0;
5693+ if (au_h_iptr(dir, bdst))
5694+ goto out;
5695+
5696+ di_read_unlock(parent, AuLock_IR);
5697+ di_write_lock_parent(parent);
5698+ /* someone else might change our inode while we were sleeping */
5699+ if (!au_h_iptr(dir, bdst))
5700+ err = au_cpup_dirs(dentry, bdst);
5701+ di_downgrade_lock(parent, AuLock_IR);
5702+
4f0767ce 5703+out:
1facf9fc 5704+ dput(parent);
5705+ return err;
5706+}
7f207e10
AM
5707diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
5708--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
2000de60 5709+++ linux/fs/aufs/cpup.h 2015-03-27 21:56:35.460128334 +0100
523b37e3 5710@@ -0,0 +1,94 @@
1facf9fc 5711+/*
2000de60 5712+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 5713+ *
5714+ * This program, aufs is free software; you can redistribute it and/or modify
5715+ * it under the terms of the GNU General Public License as published by
5716+ * the Free Software Foundation; either version 2 of the License, or
5717+ * (at your option) any later version.
dece6358
AM
5718+ *
5719+ * This program is distributed in the hope that it will be useful,
5720+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5721+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5722+ * GNU General Public License for more details.
5723+ *
5724+ * You should have received a copy of the GNU General Public License
523b37e3 5725+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5726+ */
5727+
5728+/*
5729+ * copy-up/down functions
5730+ */
5731+
5732+#ifndef __AUFS_CPUP_H__
5733+#define __AUFS_CPUP_H__
5734+
5735+#ifdef __KERNEL__
5736+
dece6358 5737+#include <linux/path.h>
1facf9fc 5738+
dece6358
AM
5739+struct inode;
5740+struct file;
86dc4139 5741+struct au_pin;
dece6358 5742+
86dc4139 5743+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 5744+void au_cpup_attr_timesizes(struct inode *inode);
5745+void au_cpup_attr_nlink(struct inode *inode, int force);
5746+void au_cpup_attr_changeable(struct inode *inode);
5747+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
5748+void au_cpup_attr_all(struct inode *inode, int force);
5749+
5750+/* ---------------------------------------------------------------------- */
5751+
c2b27bf2
AM
5752+struct au_cp_generic {
5753+ struct dentry *dentry;
5754+ aufs_bindex_t bdst, bsrc;
5755+ loff_t len;
5756+ struct au_pin *pin;
5757+ unsigned int flags;
5758+};
5759+
1facf9fc 5760+/* cpup flags */
392086de
AM
5761+#define AuCpup_DTIME 1 /* do dtime_store/revert */
5762+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
5763+ for link(2) */
5764+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
5765+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
5766+ cpup */
5767+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
5768+ existing entry */
5769+#define AuCpup_RWDST (1 << 5) /* force write target even if
5770+ the branch is marked as RO */
c2b27bf2 5771+
1facf9fc 5772+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
5773+#define au_fset_cpup(flags, name) \
5774+ do { (flags) |= AuCpup_##name; } while (0)
5775+#define au_fclr_cpup(flags, name) \
5776+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 5777+
5778+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
5779+int au_sio_cpup_simple(struct au_cp_generic *cpg);
5780+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
5781+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 5782+
5783+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5784+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5785+ struct au_pin *pin,
1facf9fc 5786+ struct dentry *h_parent, void *arg),
5787+ void *arg);
5788+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5789+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5790+
5791+/* ---------------------------------------------------------------------- */
5792+
5793+/* keep timestamps when copyup */
5794+struct au_dtime {
5795+ struct dentry *dt_dentry;
5796+ struct path dt_h_path;
5797+ struct timespec dt_atime, dt_mtime;
5798+};
5799+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5800+ struct path *h_path);
5801+void au_dtime_revert(struct au_dtime *dt);
5802+
5803+#endif /* __KERNEL__ */
5804+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
5805diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
5806--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
2000de60 5807+++ linux/fs/aufs/dbgaufs.c 2015-03-27 21:56:35.463461668 +0100
523b37e3 5808@@ -0,0 +1,432 @@
1facf9fc 5809+/*
2000de60 5810+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 5811+ *
5812+ * This program, aufs is free software; you can redistribute it and/or modify
5813+ * it under the terms of the GNU General Public License as published by
5814+ * the Free Software Foundation; either version 2 of the License, or
5815+ * (at your option) any later version.
dece6358
AM
5816+ *
5817+ * This program is distributed in the hope that it will be useful,
5818+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5819+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5820+ * GNU General Public License for more details.
5821+ *
5822+ * You should have received a copy of the GNU General Public License
523b37e3 5823+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5824+ */
5825+
5826+/*
5827+ * debugfs interface
5828+ */
5829+
5830+#include <linux/debugfs.h>
5831+#include "aufs.h"
5832+
5833+#ifndef CONFIG_SYSFS
5834+#error DEBUG_FS depends upon SYSFS
5835+#endif
5836+
5837+static struct dentry *dbgaufs;
5838+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
5839+
5840+/* 20 is max digits length of ulong 64 */
5841+struct dbgaufs_arg {
5842+ int n;
5843+ char a[20 * 4];
5844+};
5845+
5846+/*
5847+ * common function for all XINO files
5848+ */
5849+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
5850+ struct file *file)
5851+{
5852+ kfree(file->private_data);
5853+ return 0;
5854+}
5855+
5856+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
5857+{
5858+ int err;
5859+ struct kstat st;
5860+ struct dbgaufs_arg *p;
5861+
5862+ err = -ENOMEM;
5863+ p = kmalloc(sizeof(*p), GFP_NOFS);
5864+ if (unlikely(!p))
5865+ goto out;
5866+
5867+ err = 0;
5868+ p->n = 0;
5869+ file->private_data = p;
5870+ if (!xf)
5871+ goto out;
5872+
c06a8ce3 5873+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 5874+ if (!err) {
5875+ if (do_fcnt)
5876+ p->n = snprintf
5877+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
5878+ (long)file_count(xf), st.blocks, st.blksize,
5879+ (long long)st.size);
5880+ else
5881+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
5882+ st.blocks, st.blksize,
5883+ (long long)st.size);
5884+ AuDebugOn(p->n >= sizeof(p->a));
5885+ } else {
5886+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
5887+ err = 0;
5888+ }
5889+
4f0767ce 5890+out:
1facf9fc 5891+ return err;
5892+
5893+}
5894+
5895+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
5896+ size_t count, loff_t *ppos)
5897+{
5898+ struct dbgaufs_arg *p;
5899+
5900+ p = file->private_data;
5901+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5902+}
5903+
5904+/* ---------------------------------------------------------------------- */
5905+
86dc4139
AM
5906+struct dbgaufs_plink_arg {
5907+ int n;
5908+ char a[];
5909+};
5910+
5911+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
5912+ struct file *file)
5913+{
5914+ free_page((unsigned long)file->private_data);
5915+ return 0;
5916+}
5917+
5918+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
5919+{
5920+ int err, i, limit;
5921+ unsigned long n, sum;
5922+ struct dbgaufs_plink_arg *p;
5923+ struct au_sbinfo *sbinfo;
5924+ struct super_block *sb;
5925+ struct au_sphlhead *sphl;
5926+
5927+ err = -ENOMEM;
5928+ p = (void *)get_zeroed_page(GFP_NOFS);
5929+ if (unlikely(!p))
5930+ goto out;
5931+
5932+ err = -EFBIG;
5933+ sbinfo = inode->i_private;
5934+ sb = sbinfo->si_sb;
5935+ si_noflush_read_lock(sb);
5936+ if (au_opt_test(au_mntflags(sb), PLINK)) {
5937+ limit = PAGE_SIZE - sizeof(p->n);
5938+
5939+ /* the number of buckets */
5940+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
5941+ p->n += n;
5942+ limit -= n;
5943+
5944+ sum = 0;
5945+ for (i = 0, sphl = sbinfo->si_plink;
5946+ i < AuPlink_NHASH;
5947+ i++, sphl++) {
5948+ n = au_sphl_count(sphl);
5949+ sum += n;
5950+
5951+ n = snprintf(p->a + p->n, limit, "%lu ", n);
5952+ p->n += n;
5953+ limit -= n;
5954+ if (unlikely(limit <= 0))
5955+ goto out_free;
5956+ }
5957+ p->a[p->n - 1] = '\n';
5958+
5959+ /* the sum of plinks */
5960+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
5961+ p->n += n;
5962+ limit -= n;
5963+ if (unlikely(limit <= 0))
5964+ goto out_free;
5965+ } else {
5966+#define str "1\n0\n0\n"
5967+ p->n = sizeof(str) - 1;
5968+ strcpy(p->a, str);
5969+#undef str
5970+ }
5971+ si_read_unlock(sb);
5972+
5973+ err = 0;
5974+ file->private_data = p;
5975+ goto out; /* success */
5976+
5977+out_free:
5978+ free_page((unsigned long)p);
5979+out:
5980+ return err;
5981+}
5982+
5983+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
5984+ size_t count, loff_t *ppos)
5985+{
5986+ struct dbgaufs_plink_arg *p;
5987+
5988+ p = file->private_data;
5989+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5990+}
5991+
5992+static const struct file_operations dbgaufs_plink_fop = {
5993+ .owner = THIS_MODULE,
5994+ .open = dbgaufs_plink_open,
5995+ .release = dbgaufs_plink_release,
5996+ .read = dbgaufs_plink_read
5997+};
5998+
5999+/* ---------------------------------------------------------------------- */
6000+
1facf9fc 6001+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
6002+{
6003+ int err;
6004+ struct au_sbinfo *sbinfo;
6005+ struct super_block *sb;
6006+
6007+ sbinfo = inode->i_private;
6008+ sb = sbinfo->si_sb;
6009+ si_noflush_read_lock(sb);
6010+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
6011+ si_read_unlock(sb);
6012+ return err;
6013+}
6014+
6015+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 6016+ .owner = THIS_MODULE,
1facf9fc 6017+ .open = dbgaufs_xib_open,
6018+ .release = dbgaufs_xi_release,
6019+ .read = dbgaufs_xi_read
6020+};
6021+
6022+/* ---------------------------------------------------------------------- */
6023+
6024+#define DbgaufsXi_PREFIX "xi"
6025+
6026+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
6027+{
6028+ int err;
6029+ long l;
6030+ struct au_sbinfo *sbinfo;
6031+ struct super_block *sb;
6032+ struct file *xf;
6033+ struct qstr *name;
6034+
6035+ err = -ENOENT;
6036+ xf = NULL;
2000de60 6037+ name = &file->f_path.dentry->d_name;
1facf9fc 6038+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
6039+ || memcmp(name->name, DbgaufsXi_PREFIX,
6040+ sizeof(DbgaufsXi_PREFIX) - 1)))
6041+ goto out;
9dbd164d 6042+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 6043+ if (unlikely(err))
6044+ goto out;
6045+
6046+ sbinfo = inode->i_private;
6047+ sb = sbinfo->si_sb;
6048+ si_noflush_read_lock(sb);
6049+ if (l <= au_sbend(sb)) {
6050+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
6051+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
6052+ } else
6053+ err = -ENOENT;
6054+ si_read_unlock(sb);
6055+
4f0767ce 6056+out:
1facf9fc 6057+ return err;
6058+}
6059+
6060+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 6061+ .owner = THIS_MODULE,
1facf9fc 6062+ .open = dbgaufs_xino_open,
6063+ .release = dbgaufs_xi_release,
6064+ .read = dbgaufs_xi_read
6065+};
6066+
6067+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6068+{
6069+ aufs_bindex_t bend;
6070+ struct au_branch *br;
6071+ struct au_xino_file *xi;
6072+
6073+ if (!au_sbi(sb)->si_dbgaufs)
6074+ return;
6075+
6076+ bend = au_sbend(sb);
6077+ for (; bindex <= bend; bindex++) {
6078+ br = au_sbr(sb, bindex);
6079+ xi = &br->br_xino;
c06a8ce3
AM
6080+ debugfs_remove(xi->xi_dbgaufs);
6081+ xi->xi_dbgaufs = NULL;
1facf9fc 6082+ }
6083+}
6084+
6085+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
6086+{
6087+ struct au_sbinfo *sbinfo;
6088+ struct dentry *parent;
6089+ struct au_branch *br;
6090+ struct au_xino_file *xi;
6091+ aufs_bindex_t bend;
6092+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
6093+
6094+ sbinfo = au_sbi(sb);
6095+ parent = sbinfo->si_dbgaufs;
6096+ if (!parent)
6097+ return;
6098+
6099+ bend = au_sbend(sb);
6100+ for (; bindex <= bend; bindex++) {
6101+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6102+ br = au_sbr(sb, bindex);
6103+ xi = &br->br_xino;
6104+ AuDebugOn(xi->xi_dbgaufs);
6105+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6106+ sbinfo, &dbgaufs_xino_fop);
6107+ /* ignore an error */
6108+ if (unlikely(!xi->xi_dbgaufs))
6109+ AuWarn1("failed %s under debugfs\n", name);
6110+ }
6111+}
6112+
6113+/* ---------------------------------------------------------------------- */
6114+
6115+#ifdef CONFIG_AUFS_EXPORT
6116+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6117+{
6118+ int err;
6119+ struct au_sbinfo *sbinfo;
6120+ struct super_block *sb;
6121+
6122+ sbinfo = inode->i_private;
6123+ sb = sbinfo->si_sb;
6124+ si_noflush_read_lock(sb);
6125+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
6126+ si_read_unlock(sb);
6127+ return err;
6128+}
6129+
6130+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 6131+ .owner = THIS_MODULE,
1facf9fc 6132+ .open = dbgaufs_xigen_open,
6133+ .release = dbgaufs_xi_release,
6134+ .read = dbgaufs_xi_read
6135+};
6136+
6137+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6138+{
6139+ int err;
6140+
dece6358 6141+ /*
c1595e42 6142+ * This function is a dynamic '__init' function actually,
dece6358
AM
6143+ * so the tiny check for si_rwsem is unnecessary.
6144+ */
6145+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6146+
1facf9fc 6147+ err = -EIO;
6148+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6149+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6150+ &dbgaufs_xigen_fop);
6151+ if (sbinfo->si_dbgaufs_xigen)
6152+ err = 0;
6153+
6154+ return err;
6155+}
6156+#else
6157+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6158+{
6159+ return 0;
6160+}
6161+#endif /* CONFIG_AUFS_EXPORT */
6162+
6163+/* ---------------------------------------------------------------------- */
6164+
6165+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6166+{
dece6358 6167+ /*
c1595e42 6168+ * This function is a dynamic '__init' function actually,
dece6358
AM
6169+ * so the tiny check for si_rwsem is unnecessary.
6170+ */
6171+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6172+
1facf9fc 6173+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6174+ sbinfo->si_dbgaufs = NULL;
6175+ kobject_put(&sbinfo->si_kobj);
6176+}
6177+
6178+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6179+{
6180+ int err;
6181+ char name[SysaufsSiNameLen];
6182+
dece6358 6183+ /*
c1595e42 6184+ * This function is a dynamic '__init' function actually,
dece6358
AM
6185+ * so the tiny check for si_rwsem is unnecessary.
6186+ */
6187+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6188+
1facf9fc 6189+ err = -ENOENT;
6190+ if (!dbgaufs) {
6191+ AuErr1("/debug/aufs is uninitialized\n");
6192+ goto out;
6193+ }
6194+
6195+ err = -EIO;
6196+ sysaufs_name(sbinfo, name);
6197+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6198+ if (unlikely(!sbinfo->si_dbgaufs))
6199+ goto out;
6200+ kobject_get(&sbinfo->si_kobj);
6201+
6202+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6203+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6204+ &dbgaufs_xib_fop);
6205+ if (unlikely(!sbinfo->si_dbgaufs_xib))
6206+ goto out_dir;
6207+
86dc4139
AM
6208+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6209+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6210+ &dbgaufs_plink_fop);
6211+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6212+ goto out_dir;
6213+
1facf9fc 6214+ err = dbgaufs_xigen_init(sbinfo);
6215+ if (!err)
6216+ goto out; /* success */
6217+
4f0767ce 6218+out_dir:
1facf9fc 6219+ dbgaufs_si_fin(sbinfo);
4f0767ce 6220+out:
1facf9fc 6221+ return err;
6222+}
6223+
6224+/* ---------------------------------------------------------------------- */
6225+
6226+void dbgaufs_fin(void)
6227+{
6228+ debugfs_remove(dbgaufs);
6229+}
6230+
6231+int __init dbgaufs_init(void)
6232+{
6233+ int err;
6234+
6235+ err = -EIO;
6236+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
6237+ if (dbgaufs)
6238+ err = 0;
6239+ return err;
6240+}
7f207e10
AM
6241diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
6242--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
2000de60 6243+++ linux/fs/aufs/dbgaufs.h 2015-03-27 21:56:35.463461668 +0100
523b37e3 6244@@ -0,0 +1,48 @@
1facf9fc 6245+/*
2000de60 6246+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6247+ *
6248+ * This program, aufs is free software; you can redistribute it and/or modify
6249+ * it under the terms of the GNU General Public License as published by
6250+ * the Free Software Foundation; either version 2 of the License, or
6251+ * (at your option) any later version.
dece6358
AM
6252+ *
6253+ * This program is distributed in the hope that it will be useful,
6254+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6255+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6256+ * GNU General Public License for more details.
6257+ *
6258+ * You should have received a copy of the GNU General Public License
523b37e3 6259+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6260+ */
6261+
6262+/*
6263+ * debugfs interface
6264+ */
6265+
6266+#ifndef __DBGAUFS_H__
6267+#define __DBGAUFS_H__
6268+
6269+#ifdef __KERNEL__
6270+
dece6358 6271+struct super_block;
1facf9fc 6272+struct au_sbinfo;
dece6358 6273+
1facf9fc 6274+#ifdef CONFIG_DEBUG_FS
6275+/* dbgaufs.c */
6276+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
6277+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
6278+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
6279+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
6280+void dbgaufs_fin(void);
6281+int __init dbgaufs_init(void);
1facf9fc 6282+#else
4a4d8108
AM
6283+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
6284+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
6285+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
6286+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
6287+AuStubVoid(dbgaufs_fin, void)
6288+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 6289+#endif /* CONFIG_DEBUG_FS */
6290+
6291+#endif /* __KERNEL__ */
6292+#endif /* __DBGAUFS_H__ */
7f207e10
AM
6293diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
6294--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
2000de60 6295+++ linux/fs/aufs/dcsub.c 2015-03-27 21:56:35.463461668 +0100
c1595e42 6296@@ -0,0 +1,224 @@
1facf9fc 6297+/*
2000de60 6298+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6299+ *
6300+ * This program, aufs is free software; you can redistribute it and/or modify
6301+ * it under the terms of the GNU General Public License as published by
6302+ * the Free Software Foundation; either version 2 of the License, or
6303+ * (at your option) any later version.
dece6358
AM
6304+ *
6305+ * This program is distributed in the hope that it will be useful,
6306+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6307+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6308+ * GNU General Public License for more details.
6309+ *
6310+ * You should have received a copy of the GNU General Public License
523b37e3 6311+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6312+ */
6313+
6314+/*
6315+ * sub-routines for dentry cache
6316+ */
6317+
6318+#include "aufs.h"
6319+
6320+static void au_dpage_free(struct au_dpage *dpage)
6321+{
6322+ int i;
6323+ struct dentry **p;
6324+
6325+ p = dpage->dentries;
6326+ for (i = 0; i < dpage->ndentry; i++)
6327+ dput(*p++);
6328+ free_page((unsigned long)dpage->dentries);
6329+}
6330+
6331+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
6332+{
6333+ int err;
6334+ void *p;
6335+
6336+ err = -ENOMEM;
6337+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
6338+ if (unlikely(!dpages->dpages))
6339+ goto out;
6340+
6341+ p = (void *)__get_free_page(gfp);
6342+ if (unlikely(!p))
6343+ goto out_dpages;
6344+
6345+ dpages->dpages[0].ndentry = 0;
6346+ dpages->dpages[0].dentries = p;
6347+ dpages->ndpage = 1;
6348+ return 0; /* success */
6349+
4f0767ce 6350+out_dpages:
1facf9fc 6351+ kfree(dpages->dpages);
4f0767ce 6352+out:
1facf9fc 6353+ return err;
6354+}
6355+
6356+void au_dpages_free(struct au_dcsub_pages *dpages)
6357+{
6358+ int i;
6359+ struct au_dpage *p;
6360+
6361+ p = dpages->dpages;
6362+ for (i = 0; i < dpages->ndpage; i++)
6363+ au_dpage_free(p++);
6364+ kfree(dpages->dpages);
6365+}
6366+
6367+static int au_dpages_append(struct au_dcsub_pages *dpages,
6368+ struct dentry *dentry, gfp_t gfp)
6369+{
6370+ int err, sz;
6371+ struct au_dpage *dpage;
6372+ void *p;
6373+
6374+ dpage = dpages->dpages + dpages->ndpage - 1;
6375+ sz = PAGE_SIZE / sizeof(dentry);
6376+ if (unlikely(dpage->ndentry >= sz)) {
6377+ AuLabel(new dpage);
6378+ err = -ENOMEM;
6379+ sz = dpages->ndpage * sizeof(*dpages->dpages);
6380+ p = au_kzrealloc(dpages->dpages, sz,
6381+ sz + sizeof(*dpages->dpages), gfp);
6382+ if (unlikely(!p))
6383+ goto out;
6384+
6385+ dpages->dpages = p;
6386+ dpage = dpages->dpages + dpages->ndpage;
6387+ p = (void *)__get_free_page(gfp);
6388+ if (unlikely(!p))
6389+ goto out;
6390+
6391+ dpage->ndentry = 0;
6392+ dpage->dentries = p;
6393+ dpages->ndpage++;
6394+ }
6395+
c1595e42 6396+ AuDebugOn(au_dcount(dentry) <= 0);
027c5e7a 6397+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 6398+ return 0; /* success */
6399+
4f0767ce 6400+out:
1facf9fc 6401+ return err;
6402+}
6403+
c1595e42
JR
6404+/* todo: BAD approach */
6405+/* copied from linux/fs/dcache.c */
6406+enum d_walk_ret {
6407+ D_WALK_CONTINUE,
6408+ D_WALK_QUIT,
6409+ D_WALK_NORETRY,
6410+ D_WALK_SKIP,
6411+};
6412+
6413+extern void d_walk(struct dentry *parent, void *data,
6414+ enum d_walk_ret (*enter)(void *, struct dentry *),
6415+ void (*finish)(void *));
6416+
6417+struct ac_dpages_arg {
1facf9fc 6418+ int err;
c1595e42
JR
6419+ struct au_dcsub_pages *dpages;
6420+ struct super_block *sb;
6421+ au_dpages_test test;
6422+ void *arg;
6423+};
1facf9fc 6424+
c1595e42
JR
6425+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
6426+{
6427+ enum d_walk_ret ret;
6428+ struct ac_dpages_arg *arg = _arg;
1facf9fc 6429+
c1595e42
JR
6430+ ret = D_WALK_CONTINUE;
6431+ if (dentry->d_sb == arg->sb
6432+ && !IS_ROOT(dentry)
6433+ && au_dcount(dentry) > 0
6434+ && au_di(dentry)
6435+ && (!arg->test || arg->test(dentry, arg->arg))) {
6436+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
6437+ if (unlikely(arg->err))
6438+ ret = D_WALK_QUIT;
1facf9fc 6439+ }
6440+
c1595e42
JR
6441+ return ret;
6442+}
027c5e7a 6443+
c1595e42
JR
6444+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6445+ au_dpages_test test, void *arg)
6446+{
6447+ struct ac_dpages_arg args = {
6448+ .err = 0,
6449+ .dpages = dpages,
6450+ .sb = root->d_sb,
6451+ .test = test,
6452+ .arg = arg
6453+ };
027c5e7a 6454+
c1595e42
JR
6455+ d_walk(root, &args, au_call_dpages_append, NULL);
6456+
6457+ return args.err;
1facf9fc 6458+}
6459+
6460+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6461+ int do_include, au_dpages_test test, void *arg)
6462+{
6463+ int err;
6464+
6465+ err = 0;
027c5e7a
AM
6466+ write_seqlock(&rename_lock);
6467+ spin_lock(&dentry->d_lock);
6468+ if (do_include
c1595e42 6469+ && au_dcount(dentry) > 0
027c5e7a 6470+ && (!test || test(dentry, arg)))
1facf9fc 6471+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6472+ spin_unlock(&dentry->d_lock);
6473+ if (unlikely(err))
6474+ goto out;
6475+
6476+ /*
523b37e3 6477+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
6478+ * mount
6479+ */
1facf9fc 6480+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
6481+ dentry = dentry->d_parent; /* rename_lock is locked */
6482+ spin_lock(&dentry->d_lock);
c1595e42 6483+ if (au_dcount(dentry) > 0
027c5e7a 6484+ && (!test || test(dentry, arg)))
1facf9fc 6485+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6486+ spin_unlock(&dentry->d_lock);
6487+ if (unlikely(err))
6488+ break;
1facf9fc 6489+ }
6490+
4f0767ce 6491+out:
027c5e7a 6492+ write_sequnlock(&rename_lock);
1facf9fc 6493+ return err;
6494+}
6495+
027c5e7a
AM
6496+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
6497+{
6498+ return au_di(dentry) && dentry->d_sb == arg;
6499+}
6500+
6501+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6502+ struct dentry *dentry, int do_include)
6503+{
6504+ return au_dcsub_pages_rev(dpages, dentry, do_include,
6505+ au_dcsub_dpages_aufs, dentry->d_sb);
6506+}
6507+
4a4d8108 6508+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 6509+{
4a4d8108
AM
6510+ struct path path[2] = {
6511+ {
6512+ .dentry = d1
6513+ },
6514+ {
6515+ .dentry = d2
6516+ }
6517+ };
1facf9fc 6518+
4a4d8108 6519+ return path_is_under(path + 0, path + 1);
1facf9fc 6520+}
7f207e10
AM
6521diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
6522--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
2000de60 6523+++ linux/fs/aufs/dcsub.h 2015-03-27 21:56:35.463461668 +0100
c1595e42 6524@@ -0,0 +1,125 @@
1facf9fc 6525+/*
2000de60 6526+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6527+ *
6528+ * This program, aufs is free software; you can redistribute it and/or modify
6529+ * it under the terms of the GNU General Public License as published by
6530+ * the Free Software Foundation; either version 2 of the License, or
6531+ * (at your option) any later version.
dece6358
AM
6532+ *
6533+ * This program is distributed in the hope that it will be useful,
6534+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6535+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6536+ * GNU General Public License for more details.
6537+ *
6538+ * You should have received a copy of the GNU General Public License
523b37e3 6539+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6540+ */
6541+
6542+/*
6543+ * sub-routines for dentry cache
6544+ */
6545+
6546+#ifndef __AUFS_DCSUB_H__
6547+#define __AUFS_DCSUB_H__
6548+
6549+#ifdef __KERNEL__
6550+
7f207e10 6551+#include <linux/dcache.h>
027c5e7a 6552+#include <linux/fs.h>
dece6358
AM
6553+
6554+struct dentry;
1facf9fc 6555+
6556+struct au_dpage {
6557+ int ndentry;
6558+ struct dentry **dentries;
6559+};
6560+
6561+struct au_dcsub_pages {
6562+ int ndpage;
6563+ struct au_dpage *dpages;
6564+};
6565+
6566+/* ---------------------------------------------------------------------- */
6567+
7f207e10 6568+/* dcsub.c */
1facf9fc 6569+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
6570+void au_dpages_free(struct au_dcsub_pages *dpages);
6571+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
6572+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6573+ au_dpages_test test, void *arg);
6574+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6575+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
6576+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6577+ struct dentry *dentry, int do_include);
4a4d8108 6578+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 6579+
7f207e10
AM
6580+/* ---------------------------------------------------------------------- */
6581+
523b37e3
AM
6582+/*
6583+ * todo: in linux-3.13, several similar (but faster) helpers are added to
6584+ * include/linux/dcache.h. Try them (in the future).
6585+ */
6586+
027c5e7a
AM
6587+static inline int au_d_hashed_positive(struct dentry *d)
6588+{
6589+ int err;
6590+ struct inode *inode = d->d_inode;
076b876e 6591+
027c5e7a
AM
6592+ err = 0;
6593+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
6594+ err = -ENOENT;
6595+ return err;
6596+}
6597+
38d290e6
JR
6598+static inline int au_d_linkable(struct dentry *d)
6599+{
6600+ int err;
6601+ struct inode *inode = d->d_inode;
076b876e 6602+
38d290e6
JR
6603+ err = au_d_hashed_positive(d);
6604+ if (err
6605+ && inode
6606+ && (inode->i_state & I_LINKABLE))
6607+ err = 0;
6608+ return err;
6609+}
6610+
027c5e7a
AM
6611+static inline int au_d_alive(struct dentry *d)
6612+{
6613+ int err;
6614+ struct inode *inode;
076b876e 6615+
027c5e7a
AM
6616+ err = 0;
6617+ if (!IS_ROOT(d))
6618+ err = au_d_hashed_positive(d);
6619+ else {
6620+ inode = d->d_inode;
6621+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
6622+ err = -ENOENT;
6623+ }
6624+ return err;
6625+}
6626+
6627+static inline int au_alive_dir(struct dentry *d)
7f207e10 6628+{
027c5e7a 6629+ int err;
076b876e 6630+
027c5e7a
AM
6631+ err = au_d_alive(d);
6632+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
6633+ err = -ENOENT;
6634+ return err;
7f207e10
AM
6635+}
6636+
38d290e6
JR
6637+static inline int au_qstreq(struct qstr *a, struct qstr *b)
6638+{
6639+ return a->len == b->len
6640+ && !memcmp(a->name, b->name, a->len);
6641+}
6642+
c1595e42
JR
6643+static inline int au_dcount(struct dentry *d)
6644+{
6645+ return (int)d_count(d);
6646+}
6647+
1facf9fc 6648+#endif /* __KERNEL__ */
6649+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
6650diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
6651--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
2000de60 6652+++ linux/fs/aufs/debug.c 2015-03-27 21:56:35.463461668 +0100
c1595e42 6653@@ -0,0 +1,520 @@
1facf9fc 6654+/*
2000de60 6655+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 6656+ *
6657+ * This program, aufs is free software; you can redistribute it and/or modify
6658+ * it under the terms of the GNU General Public License as published by
6659+ * the Free Software Foundation; either version 2 of the License, or
6660+ * (at your option) any later version.
dece6358
AM
6661+ *
6662+ * This program is distributed in the hope that it will be useful,
6663+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6664+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6665+ * GNU General Public License for more details.
6666+ *
6667+ * You should have received a copy of the GNU General Public License
523b37e3 6668+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6669+ */
6670+
6671+/*
6672+ * debug print functions
6673+ */
6674+
7f207e10 6675+#include <linux/vt_kern.h>
1facf9fc 6676+#include "aufs.h"
6677+
392086de
AM
6678+/* Returns 0, or -errno. arg is in kp->arg. */
6679+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
6680+{
6681+ int err, n;
6682+
6683+ err = kstrtoint(val, 0, &n);
6684+ if (!err) {
6685+ if (n > 0)
6686+ au_debug_on();
6687+ else
6688+ au_debug_off();
6689+ }
6690+ return err;
6691+}
6692+
6693+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
6694+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
6695+{
6696+ atomic_t *a;
6697+
6698+ a = kp->arg;
6699+ return sprintf(buffer, "%d", atomic_read(a));
6700+}
6701+
6702+static struct kernel_param_ops param_ops_atomic_t = {
6703+ .set = param_atomic_t_set,
6704+ .get = param_atomic_t_get
6705+ /* void (*free)(void *arg) */
6706+};
6707+
6708+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 6709+MODULE_PARM_DESC(debug, "debug print");
392086de 6710+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 6711+
c1595e42 6712+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
1facf9fc 6713+char *au_plevel = KERN_DEBUG;
e49829fe
JR
6714+#define dpri(fmt, ...) do { \
6715+ if ((au_plevel \
6716+ && strcmp(au_plevel, KERN_DEBUG)) \
6717+ || au_debug_test()) \
6718+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 6719+} while (0)
6720+
6721+/* ---------------------------------------------------------------------- */
6722+
6723+void au_dpri_whlist(struct au_nhash *whlist)
6724+{
6725+ unsigned long ul, n;
6726+ struct hlist_head *head;
c06a8ce3 6727+ struct au_vdir_wh *pos;
1facf9fc 6728+
6729+ n = whlist->nh_num;
6730+ head = whlist->nh_head;
6731+ for (ul = 0; ul < n; ul++) {
c06a8ce3 6732+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 6733+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
6734+ pos->wh_bindex,
6735+ pos->wh_str.len, pos->wh_str.name,
6736+ pos->wh_str.len);
1facf9fc 6737+ head++;
6738+ }
6739+}
6740+
6741+void au_dpri_vdir(struct au_vdir *vdir)
6742+{
6743+ unsigned long ul;
6744+ union au_vdir_deblk_p p;
6745+ unsigned char *o;
6746+
6747+ if (!vdir || IS_ERR(vdir)) {
6748+ dpri("err %ld\n", PTR_ERR(vdir));
6749+ return;
6750+ }
6751+
6752+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
6753+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
6754+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
6755+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
6756+ p.deblk = vdir->vd_deblk[ul];
6757+ o = p.deblk;
6758+ dpri("[%lu]: %p\n", ul, o);
6759+ }
6760+}
6761+
53392da6 6762+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 6763+ struct dentry *wh)
6764+{
6765+ char *n = NULL;
6766+ int l = 0;
6767+
6768+ if (!inode || IS_ERR(inode)) {
6769+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
6770+ return -1;
6771+ }
6772+
c2b27bf2 6773+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 6774+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
6775+ && sizeof(inode->i_blocks) != sizeof(u64));
6776+ if (wh) {
6777+ n = (void *)wh->d_name.name;
6778+ l = wh->d_name.len;
6779+ }
6780+
53392da6
AM
6781+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
6782+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
6783+ bindex, inode,
1facf9fc 6784+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
6785+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
6786+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 6787+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 6788+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
6789+ inode->i_state, inode->i_flags, inode->i_version,
6790+ inode->i_generation,
1facf9fc 6791+ l ? ", wh " : "", l, n);
6792+ return 0;
6793+}
6794+
6795+void au_dpri_inode(struct inode *inode)
6796+{
6797+ struct au_iinfo *iinfo;
6798+ aufs_bindex_t bindex;
53392da6 6799+ int err, hn;
1facf9fc 6800+
53392da6 6801+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 6802+ if (err || !au_test_aufs(inode->i_sb))
6803+ return;
6804+
6805+ iinfo = au_ii(inode);
6806+ if (!iinfo)
6807+ return;
6808+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 6809+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 6810+ if (iinfo->ii_bstart < 0)
6811+ return;
53392da6
AM
6812+ hn = 0;
6813+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
6814+ hn = !!au_hn(iinfo->ii_hinode + bindex);
6815+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 6816+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 6817+ }
1facf9fc 6818+}
6819+
2cbb1c4b
JR
6820+void au_dpri_dalias(struct inode *inode)
6821+{
6822+ struct dentry *d;
6823+
6824+ spin_lock(&inode->i_lock);
c1595e42 6825+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
2cbb1c4b
JR
6826+ au_dpri_dentry(d);
6827+ spin_unlock(&inode->i_lock);
6828+}
6829+
1facf9fc 6830+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
6831+{
6832+ struct dentry *wh = NULL;
53392da6 6833+ int hn;
076b876e 6834+ struct au_iinfo *iinfo;
1facf9fc 6835+
6836+ if (!dentry || IS_ERR(dentry)) {
6837+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
6838+ return -1;
6839+ }
6840+ /* do not call dget_parent() here */
027c5e7a 6841+ /* note: access d_xxx without d_lock */
523b37e3
AM
6842+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
6843+ bindex, dentry, dentry,
1facf9fc 6844+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
c1595e42 6845+ au_dcount(dentry), dentry->d_flags,
523b37e3 6846+ d_unhashed(dentry) ? "un" : "");
53392da6 6847+ hn = -1;
1facf9fc 6848+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
076b876e 6849+ iinfo = au_ii(dentry->d_inode);
53392da6
AM
6850+ if (iinfo) {
6851+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 6852+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 6853+ }
1facf9fc 6854+ }
53392da6 6855+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 6856+ return 0;
6857+}
6858+
6859+void au_dpri_dentry(struct dentry *dentry)
6860+{
6861+ struct au_dinfo *dinfo;
6862+ aufs_bindex_t bindex;
6863+ int err;
4a4d8108 6864+ struct au_hdentry *hdp;
1facf9fc 6865+
6866+ err = do_pri_dentry(-1, dentry);
6867+ if (err || !au_test_aufs(dentry->d_sb))
6868+ return;
6869+
6870+ dinfo = au_di(dentry);
6871+ if (!dinfo)
6872+ return;
38d290e6 6873+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
1facf9fc 6874+ dinfo->di_bstart, dinfo->di_bend,
38d290e6
JR
6875+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
6876+ dinfo->di_tmpfile);
1facf9fc 6877+ if (dinfo->di_bstart < 0)
6878+ return;
4a4d8108 6879+ hdp = dinfo->di_hdentry;
1facf9fc 6880+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 6881+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 6882+}
6883+
6884+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
6885+{
6886+ char a[32];
6887+
6888+ if (!file || IS_ERR(file)) {
6889+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
6890+ return -1;
6891+ }
6892+ a[0] = 0;
6893+ if (bindex < 0
2000de60
JR
6894+ && file->f_path.dentry
6895+ && au_test_aufs(file->f_path.dentry->d_sb)
1facf9fc 6896+ && au_fi(file))
e49829fe 6897+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 6898+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 6899+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 6900+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 6901+ file->f_version, file->f_pos, a);
2000de60
JR
6902+ if (file->f_path.dentry)
6903+ do_pri_dentry(bindex, file->f_path.dentry);
1facf9fc 6904+ return 0;
6905+}
6906+
6907+void au_dpri_file(struct file *file)
6908+{
6909+ struct au_finfo *finfo;
4a4d8108
AM
6910+ struct au_fidir *fidir;
6911+ struct au_hfile *hfile;
1facf9fc 6912+ aufs_bindex_t bindex;
6913+ int err;
6914+
6915+ err = do_pri_file(-1, file);
2000de60
JR
6916+ if (err
6917+ || !file->f_path.dentry
6918+ || !au_test_aufs(file->f_path.dentry->d_sb))
1facf9fc 6919+ return;
6920+
6921+ finfo = au_fi(file);
6922+ if (!finfo)
6923+ return;
4a4d8108 6924+ if (finfo->fi_btop < 0)
1facf9fc 6925+ return;
4a4d8108
AM
6926+ fidir = finfo->fi_hdir;
6927+ if (!fidir)
6928+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
6929+ else
e49829fe
JR
6930+ for (bindex = finfo->fi_btop;
6931+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
6932+ bindex++) {
6933+ hfile = fidir->fd_hfile + bindex;
6934+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
6935+ }
1facf9fc 6936+}
6937+
6938+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
6939+{
6940+ struct vfsmount *mnt;
6941+ struct super_block *sb;
6942+
6943+ if (!br || IS_ERR(br))
6944+ goto out;
86dc4139 6945+ mnt = au_br_mnt(br);
1facf9fc 6946+ if (!mnt || IS_ERR(mnt))
6947+ goto out;
6948+ sb = mnt->mnt_sb;
6949+ if (!sb || IS_ERR(sb))
6950+ goto out;
6951+
1e00d052 6952+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 6953+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 6954+ "xino %d\n",
1e00d052
AM
6955+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
6956+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 6957+ sb->s_flags, sb->s_count,
1facf9fc 6958+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
6959+ return 0;
6960+
4f0767ce 6961+out:
1facf9fc 6962+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
6963+ return -1;
6964+}
6965+
6966+void au_dpri_sb(struct super_block *sb)
6967+{
6968+ struct au_sbinfo *sbinfo;
6969+ aufs_bindex_t bindex;
6970+ int err;
6971+ /* to reuduce stack size */
6972+ struct {
6973+ struct vfsmount mnt;
6974+ struct au_branch fake;
6975+ } *a;
6976+
6977+ /* this function can be called from magic sysrq */
6978+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
6979+ if (unlikely(!a)) {
6980+ dpri("no memory\n");
6981+ return;
6982+ }
6983+
6984+ a->mnt.mnt_sb = sb;
6985+ a->fake.br_perm = 0;
86dc4139 6986+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 6987+ a->fake.br_xino.xi_file = NULL;
6988+ atomic_set(&a->fake.br_count, 0);
6989+ smp_mb(); /* atomic_set */
6990+ err = do_pri_br(-1, &a->fake);
6991+ kfree(a);
6992+ dpri("dev 0x%x\n", sb->s_dev);
6993+ if (err || !au_test_aufs(sb))
6994+ return;
6995+
6996+ sbinfo = au_sbi(sb);
6997+ if (!sbinfo)
6998+ return;
6999+ dpri("nw %d, gen %u, kobj %d\n",
7000+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
7001+ atomic_read(&sbinfo->si_kobj.kref.refcount));
7002+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
7003+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
7004+}
7005+
7006+/* ---------------------------------------------------------------------- */
7007+
7008+void au_dbg_sleep_jiffy(int jiffy)
7009+{
7010+ while (jiffy)
7011+ jiffy = schedule_timeout_uninterruptible(jiffy);
7012+}
7013+
7014+void au_dbg_iattr(struct iattr *ia)
7015+{
c06a8ce3
AM
7016+#define AuBit(name) \
7017+ do { \
7018+ if (ia->ia_valid & ATTR_ ## name) \
7019+ dpri(#name "\n"); \
7020+ } while (0)
1facf9fc 7021+ AuBit(MODE);
7022+ AuBit(UID);
7023+ AuBit(GID);
7024+ AuBit(SIZE);
7025+ AuBit(ATIME);
7026+ AuBit(MTIME);
7027+ AuBit(CTIME);
7028+ AuBit(ATIME_SET);
7029+ AuBit(MTIME_SET);
7030+ AuBit(FORCE);
7031+ AuBit(ATTR_FLAG);
7032+ AuBit(KILL_SUID);
7033+ AuBit(KILL_SGID);
7034+ AuBit(FILE);
7035+ AuBit(KILL_PRIV);
7036+ AuBit(OPEN);
7037+ AuBit(TIMES_SET);
7038+#undef AuBit
7039+ dpri("ia_file %p\n", ia->ia_file);
7040+}
7041+
7042+/* ---------------------------------------------------------------------- */
7043+
027c5e7a
AM
7044+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
7045+{
7046+ struct inode *h_inode, *inode = dentry->d_inode;
7047+ struct dentry *h_dentry;
7048+ aufs_bindex_t bindex, bend, bi;
7049+
7050+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
7051+ return;
7052+
7053+ bend = au_dbend(dentry);
7054+ bi = au_ibend(inode);
7055+ if (bi < bend)
7056+ bend = bi;
7057+ bindex = au_dbstart(dentry);
7058+ bi = au_ibstart(inode);
7059+ if (bi > bindex)
7060+ bindex = bi;
7061+
7062+ for (; bindex <= bend; bindex++) {
7063+ h_dentry = au_h_dptr(dentry, bindex);
7064+ if (!h_dentry)
7065+ continue;
7066+ h_inode = au_h_iptr(inode, bindex);
7067+ if (unlikely(h_inode != h_dentry->d_inode)) {
392086de 7068+ au_debug_on();
027c5e7a
AM
7069+ AuDbg("b%d, %s:%d\n", bindex, func, line);
7070+ AuDbgDentry(dentry);
7071+ AuDbgInode(inode);
392086de 7072+ au_debug_off();
027c5e7a
AM
7073+ BUG();
7074+ }
7075+ }
7076+}
7077+
1facf9fc 7078+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
7079+{
7080+ struct dentry *parent;
7081+
7082+ parent = dget_parent(dentry);
2000de60 7083+ AuDebugOn(!d_is_dir(dentry));
027c5e7a
AM
7084+ AuDebugOn(IS_ROOT(dentry));
7085+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 7086+ dput(parent);
7087+}
7088+
7089+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
7090+{
7091+ struct dentry *parent;
7092+
7093+ parent = dget_parent(dentry);
2000de60 7094+ AuDebugOn(d_is_dir(dentry));
027c5e7a 7095+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 7096+ dput(parent);
7097+}
7098+
7099+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
7100+{
7101+ int err, i, j;
7102+ struct au_dcsub_pages dpages;
7103+ struct au_dpage *dpage;
7104+ struct dentry **dentries;
7105+
7106+ err = au_dpages_init(&dpages, GFP_NOFS);
7107+ AuDebugOn(err);
027c5e7a 7108+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 7109+ AuDebugOn(err);
7110+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7111+ dpage = dpages.dpages + i;
7112+ dentries = dpage->dentries;
7113+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 7114+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 7115+ }
7116+ au_dpages_free(&dpages);
7117+}
7118+
1facf9fc 7119+void au_dbg_verify_kthread(void)
7120+{
53392da6 7121+ if (au_wkq_test()) {
1facf9fc 7122+ au_dbg_blocked();
1e00d052
AM
7123+ /*
7124+ * It may be recursive, but udba=notify between two aufs mounts,
7125+ * where a single ro branch is shared, is not a problem.
7126+ */
7127+ /* WARN_ON(1); */
1facf9fc 7128+ }
7129+}
7130+
7131+/* ---------------------------------------------------------------------- */
7132+
7133+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
7134+{
7135+#ifdef AuForceNoPlink
7136+ au_opt_clr(sbinfo->si_mntflags, PLINK);
7137+#endif
7138+#ifdef AuForceNoXino
7139+ au_opt_clr(sbinfo->si_mntflags, XINO);
7140+#endif
7141+#ifdef AuForceNoRefrof
7142+ au_opt_clr(sbinfo->si_mntflags, REFROF);
7143+#endif
4a4d8108
AM
7144+#ifdef AuForceHnotify
7145+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
1facf9fc 7146+#endif
1308ab2a 7147+#ifdef AuForceRd0
7148+ sbinfo->si_rdblk = 0;
7149+ sbinfo->si_rdhash = 0;
7150+#endif
1facf9fc 7151+}
7152+
7153+int __init au_debug_init(void)
7154+{
7155+ aufs_bindex_t bindex;
7156+ struct au_vdir_destr destr;
7157+
7158+ bindex = -1;
7159+ AuDebugOn(bindex >= 0);
7160+
7161+ destr.len = -1;
7162+ AuDebugOn(destr.len < NAME_MAX);
7163+
7164+#ifdef CONFIG_4KSTACKS
0c3ec466 7165+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7166+#endif
7167+
7168+#ifdef AuForceNoBrs
7169+ sysaufs_brs = 0;
7170+#endif
7171+
7172+ return 0;
7173+}
7f207e10
AM
7174diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7175--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
2000de60 7176+++ linux/fs/aufs/debug.h 2015-03-27 21:56:35.463461668 +0100
c1595e42 7177@@ -0,0 +1,262 @@
1facf9fc 7178+/*
2000de60 7179+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 7180+ *
7181+ * This program, aufs is free software; you can redistribute it and/or modify
7182+ * it under the terms of the GNU General Public License as published by
7183+ * the Free Software Foundation; either version 2 of the License, or
7184+ * (at your option) any later version.
dece6358
AM
7185+ *
7186+ * This program is distributed in the hope that it will be useful,
7187+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7188+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7189+ * GNU General Public License for more details.
7190+ *
7191+ * You should have received a copy of the GNU General Public License
523b37e3 7192+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7193+ */
7194+
7195+/*
7196+ * debug print functions
7197+ */
7198+
7199+#ifndef __AUFS_DEBUG_H__
7200+#define __AUFS_DEBUG_H__
7201+
7202+#ifdef __KERNEL__
7203+
392086de 7204+#include <linux/atomic.h>
4a4d8108
AM
7205+#include <linux/module.h>
7206+#include <linux/kallsyms.h>
1facf9fc 7207+#include <linux/sysrq.h>
4a4d8108 7208+
1facf9fc 7209+#ifdef CONFIG_AUFS_DEBUG
7210+#define AuDebugOn(a) BUG_ON(a)
7211+
7212+/* module parameter */
392086de
AM
7213+extern atomic_t aufs_debug;
7214+static inline void au_debug_on(void)
1facf9fc 7215+{
392086de
AM
7216+ atomic_inc(&aufs_debug);
7217+}
7218+static inline void au_debug_off(void)
7219+{
7220+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7221+}
7222+
7223+static inline int au_debug_test(void)
7224+{
392086de 7225+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7226+}
7227+#else
7228+#define AuDebugOn(a) do {} while (0)
392086de
AM
7229+AuStubVoid(au_debug_on, void)
7230+AuStubVoid(au_debug_off, void)
4a4d8108 7231+AuStubInt0(au_debug_test, void)
1facf9fc 7232+#endif /* CONFIG_AUFS_DEBUG */
7233+
392086de
AM
7234+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7235+
1facf9fc 7236+/* ---------------------------------------------------------------------- */
7237+
7238+/* debug print */
7239+
4a4d8108 7240+#define AuDbg(fmt, ...) do { \
1facf9fc 7241+ if (au_debug_test()) \
4a4d8108 7242+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7243+} while (0)
4a4d8108
AM
7244+#define AuLabel(l) AuDbg(#l "\n")
7245+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7246+#define AuWarn1(fmt, ...) do { \
1facf9fc 7247+ static unsigned char _c; \
7248+ if (!_c++) \
0c3ec466 7249+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 7250+} while (0)
7251+
4a4d8108 7252+#define AuErr1(fmt, ...) do { \
1facf9fc 7253+ static unsigned char _c; \
7254+ if (!_c++) \
4a4d8108 7255+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 7256+} while (0)
7257+
4a4d8108 7258+#define AuIOErr1(fmt, ...) do { \
1facf9fc 7259+ static unsigned char _c; \
7260+ if (!_c++) \
4a4d8108 7261+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 7262+} while (0)
7263+
7264+#define AuUnsupportMsg "This operation is not supported." \
7265+ " Please report this application to aufs-users ML."
4a4d8108
AM
7266+#define AuUnsupport(fmt, ...) do { \
7267+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 7268+ dump_stack(); \
7269+} while (0)
7270+
7271+#define AuTraceErr(e) do { \
7272+ if (unlikely((e) < 0)) \
7273+ AuDbg("err %d\n", (int)(e)); \
7274+} while (0)
7275+
7276+#define AuTraceErrPtr(p) do { \
7277+ if (IS_ERR(p)) \
7278+ AuDbg("err %ld\n", PTR_ERR(p)); \
7279+} while (0)
7280+
7281+/* dirty macros for debug print, use with "%.*s" and caution */
7282+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 7283+
7284+/* ---------------------------------------------------------------------- */
7285+
7286+struct au_sbinfo;
7287+struct au_finfo;
dece6358 7288+struct dentry;
1facf9fc 7289+#ifdef CONFIG_AUFS_DEBUG
c1595e42 7290+extern struct mutex au_dbg_mtx;
1facf9fc 7291+extern char *au_plevel;
7292+struct au_nhash;
7293+void au_dpri_whlist(struct au_nhash *whlist);
7294+struct au_vdir;
7295+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 7296+struct inode;
1facf9fc 7297+void au_dpri_inode(struct inode *inode);
2cbb1c4b 7298+void au_dpri_dalias(struct inode *inode);
1facf9fc 7299+void au_dpri_dentry(struct dentry *dentry);
dece6358 7300+struct file;
1facf9fc 7301+void au_dpri_file(struct file *filp);
dece6358 7302+struct super_block;
1facf9fc 7303+void au_dpri_sb(struct super_block *sb);
7304+
7305+void au_dbg_sleep_jiffy(int jiffy);
dece6358 7306+struct iattr;
1facf9fc 7307+void au_dbg_iattr(struct iattr *ia);
7308+
027c5e7a
AM
7309+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
7310+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 7311+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
7312+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
7313+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 7314+void au_dbg_verify_kthread(void);
7315+
7316+int __init au_debug_init(void);
7317+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
7318+#define AuDbgWhlist(w) do { \
c1595e42 7319+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7320+ AuDbg(#w "\n"); \
7321+ au_dpri_whlist(w); \
c1595e42 7322+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7323+} while (0)
7324+
7325+#define AuDbgVdir(v) do { \
c1595e42 7326+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7327+ AuDbg(#v "\n"); \
7328+ au_dpri_vdir(v); \
c1595e42 7329+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7330+} while (0)
7331+
7332+#define AuDbgInode(i) do { \
c1595e42 7333+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7334+ AuDbg(#i "\n"); \
7335+ au_dpri_inode(i); \
c1595e42 7336+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7337+} while (0)
7338+
2cbb1c4b 7339+#define AuDbgDAlias(i) do { \
c1595e42 7340+ mutex_lock(&au_dbg_mtx); \
2cbb1c4b
JR
7341+ AuDbg(#i "\n"); \
7342+ au_dpri_dalias(i); \
c1595e42 7343+ mutex_unlock(&au_dbg_mtx); \
2cbb1c4b
JR
7344+} while (0)
7345+
1facf9fc 7346+#define AuDbgDentry(d) do { \
c1595e42 7347+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7348+ AuDbg(#d "\n"); \
7349+ au_dpri_dentry(d); \
c1595e42 7350+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7351+} while (0)
7352+
7353+#define AuDbgFile(f) do { \
c1595e42 7354+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7355+ AuDbg(#f "\n"); \
7356+ au_dpri_file(f); \
c1595e42 7357+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7358+} while (0)
7359+
7360+#define AuDbgSb(sb) do { \
c1595e42 7361+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7362+ AuDbg(#sb "\n"); \
7363+ au_dpri_sb(sb); \
c1595e42 7364+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7365+} while (0)
7366+
7367+#define AuDbgSleep(sec) do { \
7368+ AuDbg("sleep %d sec\n", sec); \
7369+ ssleep(sec); \
7370+} while (0)
7371+
7372+#define AuDbgSleepJiffy(jiffy) do { \
7373+ AuDbg("sleep %d jiffies\n", jiffy); \
7374+ au_dbg_sleep_jiffy(jiffy); \
7375+} while (0)
7376+
7377+#define AuDbgIAttr(ia) do { \
7378+ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
7379+ au_dbg_iattr(ia); \
7380+} while (0)
4a4d8108
AM
7381+
7382+#define AuDbgSym(addr) do { \
7383+ char sym[KSYM_SYMBOL_LEN]; \
7384+ sprint_symbol(sym, (unsigned long)addr); \
7385+ AuDbg("%s\n", sym); \
7386+} while (0)
7387+
7388+#define AuInfoSym(addr) do { \
7389+ char sym[KSYM_SYMBOL_LEN]; \
7390+ sprint_symbol(sym, (unsigned long)addr); \
7391+ AuInfo("%s\n", sym); \
7392+} while (0)
1facf9fc 7393+#else
027c5e7a 7394+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
7395+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
7396+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
7397+ unsigned int sigen)
7398+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
7399+AuStubVoid(au_dbg_verify_kthread, void)
7400+AuStubInt0(__init au_debug_init, void)
7401+AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
1facf9fc 7402+
1facf9fc 7403+#define AuDbgWhlist(w) do {} while (0)
7404+#define AuDbgVdir(v) do {} while (0)
7405+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 7406+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 7407+#define AuDbgDentry(d) do {} while (0)
7408+#define AuDbgFile(f) do {} while (0)
7409+#define AuDbgSb(sb) do {} while (0)
7410+#define AuDbgSleep(sec) do {} while (0)
7411+#define AuDbgSleepJiffy(jiffy) do {} while (0)
7412+#define AuDbgIAttr(ia) do {} while (0)
4a4d8108
AM
7413+#define AuDbgSym(addr) do {} while (0)
7414+#define AuInfoSym(addr) do {} while (0)
1facf9fc 7415+#endif /* CONFIG_AUFS_DEBUG */
7416+
7417+/* ---------------------------------------------------------------------- */
7418+
7419+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
7420+int __init au_sysrq_init(void);
7421+void au_sysrq_fin(void);
7422+
7423+#ifdef CONFIG_HW_CONSOLE
7424+#define au_dbg_blocked() do { \
7425+ WARN_ON(1); \
0c5527e5 7426+ handle_sysrq('w'); \
1facf9fc 7427+} while (0)
7428+#else
4a4d8108 7429+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7430+#endif
7431+
7432+#else
4a4d8108
AM
7433+AuStubInt0(__init au_sysrq_init, void)
7434+AuStubVoid(au_sysrq_fin, void)
7435+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7436+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
7437+
7438+#endif /* __KERNEL__ */
7439+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
7440diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
7441--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
7442+++ linux/fs/aufs/dentry.c 2015-03-27 21:56:35.463461668 +0100
7443@@ -0,0 +1,1097 @@
1facf9fc 7444+/*
2000de60 7445+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 7446+ *
7447+ * This program, aufs is free software; you can redistribute it and/or modify
7448+ * it under the terms of the GNU General Public License as published by
7449+ * the Free Software Foundation; either version 2 of the License, or
7450+ * (at your option) any later version.
dece6358
AM
7451+ *
7452+ * This program is distributed in the hope that it will be useful,
7453+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7454+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7455+ * GNU General Public License for more details.
7456+ *
7457+ * You should have received a copy of the GNU General Public License
523b37e3 7458+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7459+ */
7460+
7461+/*
7462+ * lookup and dentry operations
7463+ */
7464+
dece6358 7465+#include <linux/namei.h>
1facf9fc 7466+#include "aufs.h"
7467+
1facf9fc 7468+#define AuLkup_ALLOW_NEG 1
076b876e 7469+#define AuLkup_IGNORE_PERM (1 << 1)
1facf9fc 7470+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
7471+#define au_fset_lkup(flags, name) \
7472+ do { (flags) |= AuLkup_##name; } while (0)
7473+#define au_fclr_lkup(flags, name) \
7474+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 7475+
7476+struct au_do_lookup_args {
7477+ unsigned int flags;
7478+ mode_t type;
1facf9fc 7479+};
7480+
7481+/*
7482+ * returns positive/negative dentry, NULL or an error.
7483+ * NULL means whiteout-ed or not-found.
7484+ */
7485+static struct dentry*
7486+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
7487+ aufs_bindex_t bindex, struct qstr *wh_name,
7488+ struct au_do_lookup_args *args)
7489+{
7490+ struct dentry *h_dentry;
2000de60 7491+ struct inode *h_inode;
1facf9fc 7492+ struct au_branch *br;
7493+ int wh_found, opq;
7494+ unsigned char wh_able;
7495+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
7496+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
7497+ IGNORE_PERM);
1facf9fc 7498+
1facf9fc 7499+ wh_found = 0;
7500+ br = au_sbr(dentry->d_sb, bindex);
7501+ wh_able = !!au_br_whable(br->br_perm);
7502+ if (wh_able)
076b876e 7503+ wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0);
1facf9fc 7504+ h_dentry = ERR_PTR(wh_found);
7505+ if (!wh_found)
7506+ goto real_lookup;
7507+ if (unlikely(wh_found < 0))
7508+ goto out;
7509+
7510+ /* We found a whiteout */
7511+ /* au_set_dbend(dentry, bindex); */
7512+ au_set_dbwh(dentry, bindex);
7513+ if (!allow_neg)
7514+ return NULL; /* success */
7515+
4f0767ce 7516+real_lookup:
076b876e
AM
7517+ if (!ignore_perm)
7518+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
7519+ else
7520+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
2000de60
JR
7521+ if (IS_ERR(h_dentry)) {
7522+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG
7523+ && !allow_neg)
7524+ h_dentry = NULL;
1facf9fc 7525+ goto out;
2000de60 7526+ }
1facf9fc 7527+
7528+ h_inode = h_dentry->d_inode;
7529+ if (!h_inode) {
7530+ if (!allow_neg)
7531+ goto out_neg;
7532+ } else if (wh_found
7533+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
7534+ goto out_neg;
7535+
7536+ if (au_dbend(dentry) <= bindex)
7537+ au_set_dbend(dentry, bindex);
7538+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7539+ au_set_dbstart(dentry, bindex);
7540+ au_set_h_dptr(dentry, bindex, h_dentry);
7541+
2000de60
JR
7542+ if (!d_is_dir(h_dentry)
7543+ || !wh_able
7544+ || (d_is_positive(dentry) && !d_is_dir(dentry)))
1facf9fc 7545+ goto out; /* success */
7546+
7547+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
076b876e 7548+ opq = au_diropq_test(h_dentry);
1facf9fc 7549+ mutex_unlock(&h_inode->i_mutex);
7550+ if (opq > 0)
7551+ au_set_dbdiropq(dentry, bindex);
7552+ else if (unlikely(opq < 0)) {
7553+ au_set_h_dptr(dentry, bindex, NULL);
7554+ h_dentry = ERR_PTR(opq);
7555+ }
7556+ goto out;
7557+
4f0767ce 7558+out_neg:
1facf9fc 7559+ dput(h_dentry);
7560+ h_dentry = NULL;
4f0767ce 7561+out:
1facf9fc 7562+ return h_dentry;
7563+}
7564+
dece6358
AM
7565+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
7566+{
7567+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
7568+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
7569+ return -EPERM;
7570+ return 0;
7571+}
7572+
1facf9fc 7573+/*
7574+ * returns the number of lower positive dentries,
7575+ * otherwise an error.
7576+ * can be called at unlinking with @type is zero.
7577+ */
537831f9 7578+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 7579+{
7580+ int npositive, err;
7581+ aufs_bindex_t bindex, btail, bdiropq;
076b876e 7582+ unsigned char isdir, dirperm1;
1facf9fc 7583+ struct qstr whname;
7584+ struct au_do_lookup_args args = {
b4510431 7585+ .flags = 0,
537831f9 7586+ .type = type
1facf9fc 7587+ };
7588+ const struct qstr *name = &dentry->d_name;
7589+ struct dentry *parent;
7590+ struct inode *inode;
076b876e 7591+ struct super_block *sb;
1facf9fc 7592+
076b876e
AM
7593+ sb = dentry->d_sb;
7594+ err = au_test_shwh(sb, name);
dece6358 7595+ if (unlikely(err))
1facf9fc 7596+ goto out;
7597+
7598+ err = au_wh_name_alloc(&whname, name);
7599+ if (unlikely(err))
7600+ goto out;
7601+
7602+ inode = dentry->d_inode;
2000de60 7603+ isdir = !!d_is_dir(dentry);
1facf9fc 7604+ if (!type)
7605+ au_fset_lkup(args.flags, ALLOW_NEG);
076b876e 7606+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
1facf9fc 7607+
7608+ npositive = 0;
4a4d8108 7609+ parent = dget_parent(dentry);
1facf9fc 7610+ btail = au_dbtaildir(parent);
7611+ for (bindex = bstart; bindex <= btail; bindex++) {
7612+ struct dentry *h_parent, *h_dentry;
7613+ struct inode *h_inode, *h_dir;
7614+
7615+ h_dentry = au_h_dptr(dentry, bindex);
7616+ if (h_dentry) {
7617+ if (h_dentry->d_inode)
7618+ npositive++;
7619+ if (type != S_IFDIR)
7620+ break;
7621+ continue;
7622+ }
7623+ h_parent = au_h_dptr(parent, bindex);
2000de60 7624+ if (!h_parent || !d_is_dir(h_parent))
1facf9fc 7625+ continue;
7626+
2000de60 7627+ h_dir = h_parent->d_inode;
1facf9fc 7628+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
7629+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
7630+ &args);
7631+ mutex_unlock(&h_dir->i_mutex);
7632+ err = PTR_ERR(h_dentry);
7633+ if (IS_ERR(h_dentry))
4a4d8108 7634+ goto out_parent;
2000de60
JR
7635+ if (h_dentry)
7636+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
7637+ if (dirperm1)
7638+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 7639+
7640+ if (au_dbwh(dentry) >= 0)
7641+ break;
7642+ if (!h_dentry)
7643+ continue;
7644+ h_inode = h_dentry->d_inode;
7645+ if (!h_inode)
7646+ continue;
7647+ npositive++;
7648+ if (!args.type)
7649+ args.type = h_inode->i_mode & S_IFMT;
7650+ if (args.type != S_IFDIR)
7651+ break;
7652+ else if (isdir) {
7653+ /* the type of lower may be different */
7654+ bdiropq = au_dbdiropq(dentry);
7655+ if (bdiropq >= 0 && bdiropq <= bindex)
7656+ break;
7657+ }
7658+ }
7659+
7660+ if (npositive) {
7661+ AuLabel(positive);
7662+ au_update_dbstart(dentry);
7663+ }
7664+ err = npositive;
076b876e 7665+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
027c5e7a 7666+ && au_dbstart(dentry) < 0)) {
1facf9fc 7667+ err = -EIO;
523b37e3
AM
7668+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
7669+ dentry, err);
027c5e7a 7670+ }
1facf9fc 7671+
4f0767ce 7672+out_parent:
4a4d8108 7673+ dput(parent);
1facf9fc 7674+ kfree(whname.name);
4f0767ce 7675+out:
1facf9fc 7676+ return err;
7677+}
7678+
076b876e 7679+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 7680+{
7681+ struct dentry *dentry;
7682+ int wkq_err;
7683+
7684+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
b4510431 7685+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 7686+ else {
b4510431
AM
7687+ struct vfsub_lkup_one_args args = {
7688+ .errp = &dentry,
7689+ .name = name,
7690+ .parent = parent
1facf9fc 7691+ };
7692+
b4510431 7693+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 7694+ if (unlikely(wkq_err))
7695+ dentry = ERR_PTR(wkq_err);
7696+ }
7697+
7698+ return dentry;
7699+}
7700+
7701+/*
7702+ * lookup @dentry on @bindex which should be negative.
7703+ */
86dc4139 7704+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 7705+{
7706+ int err;
7707+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 7708+ struct au_branch *br;
1facf9fc 7709+
1facf9fc 7710+ parent = dget_parent(dentry);
7711+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
7712+ br = au_sbr(dentry->d_sb, bindex);
7713+ if (wh)
7714+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
7715+ else
076b876e 7716+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 7717+ err = PTR_ERR(h_dentry);
7718+ if (IS_ERR(h_dentry))
7719+ goto out;
7720+ if (unlikely(h_dentry->d_inode)) {
7721+ err = -EIO;
523b37e3 7722+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 7723+ dput(h_dentry);
7724+ goto out;
7725+ }
7726+
4a4d8108 7727+ err = 0;
1facf9fc 7728+ if (bindex < au_dbstart(dentry))
7729+ au_set_dbstart(dentry, bindex);
7730+ if (au_dbend(dentry) < bindex)
7731+ au_set_dbend(dentry, bindex);
7732+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 7733+
4f0767ce 7734+out:
1facf9fc 7735+ dput(parent);
7736+ return err;
7737+}
7738+
7739+/* ---------------------------------------------------------------------- */
7740+
7741+/* subset of struct inode */
7742+struct au_iattr {
7743+ unsigned long i_ino;
7744+ /* unsigned int i_nlink; */
0c3ec466
AM
7745+ kuid_t i_uid;
7746+ kgid_t i_gid;
1facf9fc 7747+ u64 i_version;
7748+/*
7749+ loff_t i_size;
7750+ blkcnt_t i_blocks;
7751+*/
7752+ umode_t i_mode;
7753+};
7754+
7755+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
7756+{
7757+ ia->i_ino = h_inode->i_ino;
7758+ /* ia->i_nlink = h_inode->i_nlink; */
7759+ ia->i_uid = h_inode->i_uid;
7760+ ia->i_gid = h_inode->i_gid;
7761+ ia->i_version = h_inode->i_version;
7762+/*
7763+ ia->i_size = h_inode->i_size;
7764+ ia->i_blocks = h_inode->i_blocks;
7765+*/
7766+ ia->i_mode = (h_inode->i_mode & S_IFMT);
7767+}
7768+
7769+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
7770+{
7771+ return ia->i_ino != h_inode->i_ino
7772+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 7773+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 7774+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 7775+ || ia->i_version != h_inode->i_version
7776+/*
7777+ || ia->i_size != h_inode->i_size
7778+ || ia->i_blocks != h_inode->i_blocks
7779+*/
7780+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
7781+}
7782+
7783+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
7784+ struct au_branch *br)
7785+{
7786+ int err;
7787+ struct au_iattr ia;
7788+ struct inode *h_inode;
7789+ struct dentry *h_d;
7790+ struct super_block *h_sb;
7791+
7792+ err = 0;
7793+ memset(&ia, -1, sizeof(ia));
7794+ h_sb = h_dentry->d_sb;
7795+ h_inode = h_dentry->d_inode;
7796+ if (h_inode)
7797+ au_iattr_save(&ia, h_inode);
7798+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
7799+ /* nfs d_revalidate may return 0 for negative dentry */
7800+ /* fuse d_revalidate always return 0 for negative dentry */
7801+ goto out;
7802+
7803+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 7804+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 7805+ err = PTR_ERR(h_d);
7806+ if (IS_ERR(h_d))
7807+ goto out;
7808+
7809+ err = 0;
7810+ if (unlikely(h_d != h_dentry
7811+ || h_d->d_inode != h_inode
7812+ || (h_inode && au_iattr_test(&ia, h_inode))))
7813+ err = au_busy_or_stale();
7814+ dput(h_d);
7815+
4f0767ce 7816+out:
1facf9fc 7817+ AuTraceErr(err);
7818+ return err;
7819+}
7820+
7821+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7822+ struct dentry *h_parent, struct au_branch *br)
7823+{
7824+ int err;
7825+
7826+ err = 0;
027c5e7a
AM
7827+ if (udba == AuOpt_UDBA_REVAL
7828+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 7829+ IMustLock(h_dir);
7830+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 7831+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 7832+ err = au_h_verify_dentry(h_dentry, h_parent, br);
7833+
7834+ return err;
7835+}
7836+
7837+/* ---------------------------------------------------------------------- */
7838+
027c5e7a 7839+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 7840+{
027c5e7a 7841+ int err;
1facf9fc 7842+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
7843+ struct au_hdentry tmp, *p, *q;
7844+ struct au_dinfo *dinfo;
7845+ struct super_block *sb;
1facf9fc 7846+
027c5e7a 7847+ DiMustWriteLock(dentry);
1308ab2a 7848+
027c5e7a
AM
7849+ sb = dentry->d_sb;
7850+ dinfo = au_di(dentry);
1facf9fc 7851+ bend = dinfo->di_bend;
7852+ bwh = dinfo->di_bwh;
7853+ bdiropq = dinfo->di_bdiropq;
027c5e7a 7854+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 7855+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 7856+ if (!p->hd_dentry)
1facf9fc 7857+ continue;
7858+
027c5e7a
AM
7859+ new_bindex = au_br_index(sb, p->hd_id);
7860+ if (new_bindex == bindex)
1facf9fc 7861+ continue;
1facf9fc 7862+
1facf9fc 7863+ if (dinfo->di_bwh == bindex)
7864+ bwh = new_bindex;
7865+ if (dinfo->di_bdiropq == bindex)
7866+ bdiropq = new_bindex;
7867+ if (new_bindex < 0) {
7868+ au_hdput(p);
7869+ p->hd_dentry = NULL;
7870+ continue;
7871+ }
7872+
7873+ /* swap two lower dentries, and loop again */
7874+ q = dinfo->di_hdentry + new_bindex;
7875+ tmp = *q;
7876+ *q = *p;
7877+ *p = tmp;
7878+ if (tmp.hd_dentry) {
7879+ bindex--;
7880+ p--;
7881+ }
7882+ }
7883+
1facf9fc 7884+ dinfo->di_bwh = -1;
7885+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
7886+ dinfo->di_bwh = bwh;
7887+
7888+ dinfo->di_bdiropq = -1;
7889+ if (bdiropq >= 0
7890+ && bdiropq <= au_sbend(sb)
7891+ && au_sbr_whable(sb, bdiropq))
7892+ dinfo->di_bdiropq = bdiropq;
7893+
027c5e7a
AM
7894+ err = -EIO;
7895+ dinfo->di_bstart = -1;
7896+ dinfo->di_bend = -1;
1facf9fc 7897+ bend = au_dbend(parent);
7898+ p = dinfo->di_hdentry;
7899+ for (bindex = 0; bindex <= bend; bindex++, p++)
7900+ if (p->hd_dentry) {
7901+ dinfo->di_bstart = bindex;
7902+ break;
7903+ }
7904+
027c5e7a
AM
7905+ if (dinfo->di_bstart >= 0) {
7906+ p = dinfo->di_hdentry + bend;
7907+ for (bindex = bend; bindex >= 0; bindex--, p--)
7908+ if (p->hd_dentry) {
7909+ dinfo->di_bend = bindex;
7910+ err = 0;
7911+ break;
7912+ }
7913+ }
7914+
7915+ return err;
1facf9fc 7916+}
7917+
027c5e7a 7918+static void au_do_hide(struct dentry *dentry)
1facf9fc 7919+{
027c5e7a 7920+ struct inode *inode;
1facf9fc 7921+
027c5e7a
AM
7922+ inode = dentry->d_inode;
7923+ if (inode) {
7924+ if (!S_ISDIR(inode->i_mode)) {
7925+ if (inode->i_nlink && !d_unhashed(dentry))
7926+ drop_nlink(inode);
7927+ } else {
7928+ clear_nlink(inode);
7929+ /* stop next lookup */
7930+ inode->i_flags |= S_DEAD;
7931+ }
7932+ smp_mb(); /* necessary? */
7933+ }
7934+ d_drop(dentry);
7935+}
1308ab2a 7936+
027c5e7a
AM
7937+static int au_hide_children(struct dentry *parent)
7938+{
7939+ int err, i, j, ndentry;
7940+ struct au_dcsub_pages dpages;
7941+ struct au_dpage *dpage;
7942+ struct dentry *dentry;
1facf9fc 7943+
027c5e7a 7944+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 7945+ if (unlikely(err))
7946+ goto out;
027c5e7a
AM
7947+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
7948+ if (unlikely(err))
7949+ goto out_dpages;
1facf9fc 7950+
027c5e7a
AM
7951+ /* in reverse order */
7952+ for (i = dpages.ndpage - 1; i >= 0; i--) {
7953+ dpage = dpages.dpages + i;
7954+ ndentry = dpage->ndentry;
7955+ for (j = ndentry - 1; j >= 0; j--) {
7956+ dentry = dpage->dentries[j];
7957+ if (dentry != parent)
7958+ au_do_hide(dentry);
7959+ }
7960+ }
1facf9fc 7961+
027c5e7a
AM
7962+out_dpages:
7963+ au_dpages_free(&dpages);
4f0767ce 7964+out:
027c5e7a 7965+ return err;
1facf9fc 7966+}
7967+
027c5e7a 7968+static void au_hide(struct dentry *dentry)
1facf9fc 7969+{
027c5e7a 7970+ int err;
1facf9fc 7971+
027c5e7a 7972+ AuDbgDentry(dentry);
2000de60 7973+ if (d_is_dir(dentry)) {
027c5e7a
AM
7974+ /* shrink_dcache_parent(dentry); */
7975+ err = au_hide_children(dentry);
7976+ if (unlikely(err))
523b37e3
AM
7977+ AuIOErr("%pd, failed hiding children, ignored %d\n",
7978+ dentry, err);
027c5e7a
AM
7979+ }
7980+ au_do_hide(dentry);
7981+}
1facf9fc 7982+
027c5e7a
AM
7983+/*
7984+ * By adding a dirty branch, a cached dentry may be affected in various ways.
7985+ *
7986+ * a dirty branch is added
7987+ * - on the top of layers
7988+ * - in the middle of layers
7989+ * - to the bottom of layers
7990+ *
7991+ * on the added branch there exists
7992+ * - a whiteout
7993+ * - a diropq
7994+ * - a same named entry
7995+ * + exist
7996+ * * negative --> positive
7997+ * * positive --> positive
7998+ * - type is unchanged
7999+ * - type is changed
8000+ * + doesn't exist
8001+ * * negative --> negative
8002+ * * positive --> negative (rejected by au_br_del() for non-dir case)
8003+ * - none
8004+ */
8005+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
8006+ struct au_dinfo *tmp)
8007+{
8008+ int err;
8009+ aufs_bindex_t bindex, bend;
8010+ struct {
8011+ struct dentry *dentry;
8012+ struct inode *inode;
8013+ mode_t mode;
8014+ } orig_h, tmp_h;
8015+ struct au_hdentry *hd;
8016+ struct inode *inode, *h_inode;
8017+ struct dentry *h_dentry;
8018+
8019+ err = 0;
8020+ AuDebugOn(dinfo->di_bstart < 0);
8021+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
8022+ orig_h.inode = orig_h.dentry->d_inode;
8023+ orig_h.mode = 0;
8024+ if (orig_h.inode)
8025+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
8026+ memset(&tmp_h, 0, sizeof(tmp_h));
8027+ if (tmp->di_bstart >= 0) {
8028+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
8029+ tmp_h.inode = tmp_h.dentry->d_inode;
8030+ if (tmp_h.inode)
8031+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
8032+ }
8033+
8034+ inode = dentry->d_inode;
8035+ if (!orig_h.inode) {
8036+ AuDbg("nagative originally\n");
8037+ if (inode) {
8038+ au_hide(dentry);
8039+ goto out;
8040+ }
8041+ AuDebugOn(inode);
8042+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
8043+ AuDebugOn(dinfo->di_bdiropq != -1);
8044+
8045+ if (!tmp_h.inode) {
8046+ AuDbg("negative --> negative\n");
8047+ /* should have only one negative lower */
8048+ if (tmp->di_bstart >= 0
8049+ && tmp->di_bstart < dinfo->di_bstart) {
8050+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
8051+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
8052+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
8053+ au_di_cp(dinfo, tmp);
8054+ hd = tmp->di_hdentry + tmp->di_bstart;
8055+ au_set_h_dptr(dentry, tmp->di_bstart,
8056+ dget(hd->hd_dentry));
8057+ }
8058+ au_dbg_verify_dinode(dentry);
8059+ } else {
8060+ AuDbg("negative --> positive\n");
8061+ /*
8062+ * similar to the behaviour of creating with bypassing
8063+ * aufs.
8064+ * unhash it in order to force an error in the
8065+ * succeeding create operation.
8066+ * we should not set S_DEAD here.
8067+ */
8068+ d_drop(dentry);
8069+ /* au_di_swap(tmp, dinfo); */
8070+ au_dbg_verify_dinode(dentry);
8071+ }
8072+ } else {
8073+ AuDbg("positive originally\n");
8074+ /* inode may be NULL */
8075+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
8076+ if (!tmp_h.inode) {
8077+ AuDbg("positive --> negative\n");
8078+ /* or bypassing aufs */
8079+ au_hide(dentry);
8080+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
8081+ dinfo->di_bwh = tmp->di_bwh;
8082+ if (inode)
8083+ err = au_refresh_hinode_self(inode);
8084+ au_dbg_verify_dinode(dentry);
8085+ } else if (orig_h.mode == tmp_h.mode) {
8086+ AuDbg("positive --> positive, same type\n");
8087+ if (!S_ISDIR(orig_h.mode)
8088+ && dinfo->di_bstart > tmp->di_bstart) {
8089+ /*
8090+ * similar to the behaviour of removing and
8091+ * creating.
8092+ */
8093+ au_hide(dentry);
8094+ if (inode)
8095+ err = au_refresh_hinode_self(inode);
8096+ au_dbg_verify_dinode(dentry);
8097+ } else {
8098+ /* fill empty slots */
8099+ if (dinfo->di_bstart > tmp->di_bstart)
8100+ dinfo->di_bstart = tmp->di_bstart;
8101+ if (dinfo->di_bend < tmp->di_bend)
8102+ dinfo->di_bend = tmp->di_bend;
8103+ dinfo->di_bwh = tmp->di_bwh;
8104+ dinfo->di_bdiropq = tmp->di_bdiropq;
8105+ hd = tmp->di_hdentry;
8106+ bend = dinfo->di_bend;
8107+ for (bindex = tmp->di_bstart; bindex <= bend;
8108+ bindex++) {
8109+ if (au_h_dptr(dentry, bindex))
8110+ continue;
8111+ h_dentry = hd[bindex].hd_dentry;
8112+ if (!h_dentry)
8113+ continue;
8114+ h_inode = h_dentry->d_inode;
8115+ AuDebugOn(!h_inode);
8116+ AuDebugOn(orig_h.mode
8117+ != (h_inode->i_mode
8118+ & S_IFMT));
8119+ au_set_h_dptr(dentry, bindex,
8120+ dget(h_dentry));
8121+ }
8122+ err = au_refresh_hinode(inode, dentry);
8123+ au_dbg_verify_dinode(dentry);
8124+ }
8125+ } else {
8126+ AuDbg("positive --> positive, different type\n");
8127+ /* similar to the behaviour of removing and creating */
8128+ au_hide(dentry);
8129+ if (inode)
8130+ err = au_refresh_hinode_self(inode);
8131+ au_dbg_verify_dinode(dentry);
8132+ }
8133+ }
8134+
8135+out:
8136+ return err;
8137+}
8138+
8139+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
8140+{
8141+ int err, ebrange;
8142+ unsigned int sigen;
8143+ struct au_dinfo *dinfo, *tmp;
8144+ struct super_block *sb;
8145+ struct inode *inode;
8146+
8147+ DiMustWriteLock(dentry);
8148+ AuDebugOn(IS_ROOT(dentry));
8149+ AuDebugOn(!parent->d_inode);
8150+
8151+ sb = dentry->d_sb;
8152+ inode = dentry->d_inode;
8153+ sigen = au_sigen(sb);
8154+ err = au_digen_test(parent, sigen);
8155+ if (unlikely(err))
8156+ goto out;
8157+
8158+ dinfo = au_di(dentry);
8159+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
8160+ if (unlikely(err))
8161+ goto out;
8162+ ebrange = au_dbrange_test(dentry);
8163+ if (!ebrange)
8164+ ebrange = au_do_refresh_hdentry(dentry, parent);
8165+
38d290e6 8166+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
027c5e7a
AM
8167+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
8168+ if (inode)
8169+ err = au_refresh_hinode_self(inode);
8170+ au_dbg_verify_dinode(dentry);
8171+ if (!err)
8172+ goto out_dgen; /* success */
8173+ goto out;
8174+ }
8175+
8176+ /* temporary dinfo */
8177+ AuDbgDentry(dentry);
8178+ err = -ENOMEM;
8179+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8180+ if (unlikely(!tmp))
8181+ goto out;
8182+ au_di_swap(tmp, dinfo);
8183+ /* returns the number of positive dentries */
8184+ /*
8185+ * if current working dir is removed, it returns an error.
8186+ * but the dentry is legal.
8187+ */
537831f9 8188+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
8189+ AuDbgDentry(dentry);
8190+ au_di_swap(tmp, dinfo);
8191+ if (err == -ENOENT)
8192+ err = 0;
8193+ if (err >= 0) {
8194+ /* compare/refresh by dinfo */
8195+ AuDbgDentry(dentry);
8196+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8197+ au_dbg_verify_dinode(dentry);
8198+ AuTraceErr(err);
8199+ }
8200+ au_rw_write_unlock(&tmp->di_rwsem);
8201+ au_di_free(tmp);
8202+ if (unlikely(err))
8203+ goto out;
8204+
8205+out_dgen:
8206+ au_update_digen(dentry);
8207+out:
8208+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8209+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8210+ AuDbgDentry(dentry);
8211+ }
8212+ AuTraceErr(err);
8213+ return err;
8214+}
8215+
b4510431
AM
8216+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8217+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8218+{
8219+ int err, valid;
027c5e7a
AM
8220+
8221+ err = 0;
8222+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8223+ goto out;
027c5e7a
AM
8224+
8225+ AuDbg("b%d\n", bindex);
b4510431
AM
8226+ /*
8227+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8228+ * due to whiteout and branch permission.
8229+ */
8230+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8231+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8232+ /* it may return tri-state */
8233+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8234+
8235+ if (unlikely(valid < 0))
8236+ err = valid;
8237+ else if (!valid)
8238+ err = -EINVAL;
8239+
4f0767ce 8240+out:
1facf9fc 8241+ AuTraceErr(err);
8242+ return err;
8243+}
8244+
8245+/* todo: remove this */
8246+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 8247+ unsigned int flags, int do_udba)
1facf9fc 8248+{
8249+ int err;
8250+ umode_t mode, h_mode;
8251+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
38d290e6 8252+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 8253+ struct inode *h_inode, *h_cached_inode;
1facf9fc 8254+ struct dentry *h_dentry;
8255+ struct qstr *name, *h_name;
8256+
8257+ err = 0;
8258+ plus = 0;
8259+ mode = 0;
1facf9fc 8260+ ibs = -1;
8261+ ibe = -1;
8262+ unhashed = !!d_unhashed(dentry);
8263+ is_root = !!IS_ROOT(dentry);
8264+ name = &dentry->d_name;
38d290e6 8265+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 8266+
8267+ /*
7f207e10
AM
8268+ * Theoretically, REVAL test should be unnecessary in case of
8269+ * {FS,I}NOTIFY.
8270+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 8271+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 8272+ * Let's do REVAL test too.
8273+ */
8274+ if (do_udba && inode) {
8275+ mode = (inode->i_mode & S_IFMT);
8276+ plus = (inode->i_nlink > 0);
1facf9fc 8277+ ibs = au_ibstart(inode);
8278+ ibe = au_ibend(inode);
8279+ }
8280+
8281+ bstart = au_dbstart(dentry);
8282+ btail = bstart;
8283+ if (inode && S_ISDIR(inode->i_mode))
8284+ btail = au_dbtaildir(dentry);
8285+ for (bindex = bstart; bindex <= btail; bindex++) {
8286+ h_dentry = au_h_dptr(dentry, bindex);
8287+ if (!h_dentry)
8288+ continue;
8289+
523b37e3
AM
8290+ AuDbg("b%d, %pd\n", bindex, h_dentry);
8291+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 8292+ spin_lock(&h_dentry->d_lock);
1facf9fc 8293+ h_name = &h_dentry->d_name;
8294+ if (unlikely(do_udba
8295+ && !is_root
523b37e3
AM
8296+ && ((!h_nfs
8297+ && (unhashed != !!d_unhashed(h_dentry)
38d290e6
JR
8298+ || (!tmpfile
8299+ && !au_qstreq(name, h_name))
8300+ ))
523b37e3
AM
8301+ || (h_nfs
8302+ && !(flags & LOOKUP_OPEN)
8303+ && (h_dentry->d_flags
8304+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 8305+ )) {
38d290e6
JR
8306+ int h_unhashed;
8307+
8308+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 8309+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
8310+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
8311+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 8312+ goto err;
8313+ }
027c5e7a 8314+ spin_unlock(&h_dentry->d_lock);
1facf9fc 8315+
b4510431 8316+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 8317+ if (unlikely(err))
8318+ /* do not goto err, to keep the errno */
8319+ break;
8320+
8321+ /* todo: plink too? */
8322+ if (!do_udba)
8323+ continue;
8324+
8325+ /* UDBA tests */
8326+ h_inode = h_dentry->d_inode;
8327+ if (unlikely(!!inode != !!h_inode))
8328+ goto err;
8329+
8330+ h_plus = plus;
8331+ h_mode = mode;
8332+ h_cached_inode = h_inode;
8333+ if (h_inode) {
8334+ h_mode = (h_inode->i_mode & S_IFMT);
8335+ h_plus = (h_inode->i_nlink > 0);
8336+ }
8337+ if (inode && ibs <= bindex && bindex <= ibe)
8338+ h_cached_inode = au_h_iptr(inode, bindex);
8339+
523b37e3 8340+ if (!h_nfs) {
38d290e6 8341+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
8342+ goto err;
8343+ } else {
8344+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
8345+ && !is_root
8346+ && !IS_ROOT(h_dentry)
8347+ && unhashed != d_unhashed(h_dentry)))
8348+ goto err;
8349+ }
8350+ if (unlikely(mode != h_mode
1facf9fc 8351+ || h_cached_inode != h_inode))
8352+ goto err;
8353+ continue;
8354+
f6b6e03d 8355+err:
1facf9fc 8356+ err = -EINVAL;
8357+ break;
8358+ }
8359+
523b37e3 8360+ AuTraceErr(err);
1facf9fc 8361+ return err;
8362+}
8363+
027c5e7a 8364+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 8365+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
8366+{
8367+ int err;
8368+ struct dentry *parent;
1facf9fc 8369+
027c5e7a 8370+ if (!au_digen_test(dentry, sigen))
1facf9fc 8371+ return 0;
8372+
8373+ parent = dget_parent(dentry);
8374+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8375+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 8376+ au_dbg_verify_gen(parent, sigen);
027c5e7a 8377+ err = au_refresh_dentry(dentry, parent);
1facf9fc 8378+ di_read_unlock(parent, AuLock_IR);
8379+ dput(parent);
027c5e7a 8380+ AuTraceErr(err);
1facf9fc 8381+ return err;
8382+}
8383+
8384+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
8385+{
8386+ int err;
8387+ struct dentry *d, *parent;
8388+ struct inode *inode;
8389+
027c5e7a 8390+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 8391+ return simple_reval_dpath(dentry, sigen);
8392+
8393+ /* slow loop, keep it simple and stupid */
8394+ /* cf: au_cpup_dirs() */
8395+ err = 0;
8396+ parent = NULL;
027c5e7a 8397+ while (au_digen_test(dentry, sigen)) {
1facf9fc 8398+ d = dentry;
8399+ while (1) {
8400+ dput(parent);
8401+ parent = dget_parent(d);
027c5e7a 8402+ if (!au_digen_test(parent, sigen))
1facf9fc 8403+ break;
8404+ d = parent;
8405+ }
8406+
8407+ inode = d->d_inode;
8408+ if (d != dentry)
027c5e7a 8409+ di_write_lock_child2(d);
1facf9fc 8410+
8411+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
8412+ if (au_digen_test(d, sigen)) {
8413+ /*
8414+ * todo: consolidate with simple_reval_dpath(),
8415+ * do_refresh() and au_reval_for_attr().
8416+ */
1facf9fc 8417+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8418+ err = au_refresh_dentry(d, parent);
1facf9fc 8419+ di_read_unlock(parent, AuLock_IR);
8420+ }
8421+
8422+ if (d != dentry)
8423+ di_write_unlock(d);
8424+ dput(parent);
8425+ if (unlikely(err))
8426+ break;
8427+ }
8428+
8429+ return err;
8430+}
8431+
8432+/*
8433+ * if valid returns 1, otherwise 0.
8434+ */
b4510431 8435+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 8436+{
8437+ int valid, err;
8438+ unsigned int sigen;
8439+ unsigned char do_udba;
8440+ struct super_block *sb;
8441+ struct inode *inode;
8442+
027c5e7a 8443+ /* todo: support rcu-walk? */
b4510431 8444+ if (flags & LOOKUP_RCU)
027c5e7a
AM
8445+ return -ECHILD;
8446+
8447+ valid = 0;
8448+ if (unlikely(!au_di(dentry)))
8449+ goto out;
8450+
e49829fe 8451+ valid = 1;
1facf9fc 8452+ sb = dentry->d_sb;
e49829fe
JR
8453+ /*
8454+ * todo: very ugly
8455+ * i_mutex of parent dir may be held,
8456+ * but we should not return 'invalid' due to busy.
8457+ */
8458+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
8459+ if (unlikely(err)) {
8460+ valid = err;
027c5e7a 8461+ AuTraceErr(err);
e49829fe
JR
8462+ goto out;
8463+ }
c1595e42
JR
8464+ inode = dentry->d_inode;
8465+ if (unlikely(inode && is_bad_inode(inode))) {
8466+ err = -EINVAL;
8467+ AuTraceErr(err);
8468+ goto out_dgrade;
8469+ }
027c5e7a
AM
8470+ if (unlikely(au_dbrange_test(dentry))) {
8471+ err = -EINVAL;
8472+ AuTraceErr(err);
8473+ goto out_dgrade;
1facf9fc 8474+ }
027c5e7a
AM
8475+
8476+ sigen = au_sigen(sb);
8477+ if (au_digen_test(dentry, sigen)) {
1facf9fc 8478+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
8479+ err = au_reval_dpath(dentry, sigen);
8480+ if (unlikely(err)) {
8481+ AuTraceErr(err);
1facf9fc 8482+ goto out_dgrade;
027c5e7a 8483+ }
1facf9fc 8484+ }
8485+ di_downgrade_lock(dentry, AuLock_IR);
8486+
1facf9fc 8487+ err = -EINVAL;
c1595e42 8488+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
523b37e3 8489+ && inode
38d290e6 8490+ && !(inode->i_state && I_LINKABLE)
523b37e3 8491+ && (IS_DEADDIR(inode) || !inode->i_nlink))
027c5e7a
AM
8492+ goto out_inval;
8493+
1facf9fc 8494+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
8495+ if (do_udba && inode) {
8496+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 8497+ struct inode *h_inode;
1facf9fc 8498+
027c5e7a
AM
8499+ if (bstart >= 0) {
8500+ h_inode = au_h_iptr(inode, bstart);
8501+ if (h_inode && au_test_higen(inode, h_inode))
8502+ goto out_inval;
8503+ }
1facf9fc 8504+ }
8505+
b4510431 8506+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 8507+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 8508+ err = -EIO;
523b37e3
AM
8509+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
8510+ dentry, err);
027c5e7a 8511+ }
e49829fe 8512+ goto out_inval;
1facf9fc 8513+
4f0767ce 8514+out_dgrade:
1facf9fc 8515+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 8516+out_inval:
1facf9fc 8517+ aufs_read_unlock(dentry, AuLock_IR);
8518+ AuTraceErr(err);
8519+ valid = !err;
e49829fe 8520+out:
027c5e7a 8521+ if (!valid) {
523b37e3 8522+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
8523+ d_drop(dentry);
8524+ }
1facf9fc 8525+ return valid;
8526+}
8527+
8528+static void aufs_d_release(struct dentry *dentry)
8529+{
027c5e7a 8530+ if (au_di(dentry)) {
4a4d8108
AM
8531+ au_di_fin(dentry);
8532+ au_hn_di_reinit(dentry);
1facf9fc 8533+ }
1facf9fc 8534+}
8535+
4a4d8108 8536+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
8537+ .d_revalidate = aufs_d_revalidate,
8538+ .d_weak_revalidate = aufs_d_revalidate,
8539+ .d_release = aufs_d_release
1facf9fc 8540+};
7f207e10
AM
8541diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
8542--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
2000de60 8543+++ linux/fs/aufs/dentry.h 2015-03-27 21:56:35.463461668 +0100
076b876e 8544@@ -0,0 +1,233 @@
1facf9fc 8545+/*
2000de60 8546+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 8547+ *
8548+ * This program, aufs is free software; you can redistribute it and/or modify
8549+ * it under the terms of the GNU General Public License as published by
8550+ * the Free Software Foundation; either version 2 of the License, or
8551+ * (at your option) any later version.
dece6358
AM
8552+ *
8553+ * This program is distributed in the hope that it will be useful,
8554+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8555+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8556+ * GNU General Public License for more details.
8557+ *
8558+ * You should have received a copy of the GNU General Public License
523b37e3 8559+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8560+ */
8561+
8562+/*
8563+ * lookup and dentry operations
8564+ */
8565+
8566+#ifndef __AUFS_DENTRY_H__
8567+#define __AUFS_DENTRY_H__
8568+
8569+#ifdef __KERNEL__
8570+
dece6358 8571+#include <linux/dcache.h>
1facf9fc 8572+#include "rwsem.h"
8573+
1facf9fc 8574+struct au_hdentry {
8575+ struct dentry *hd_dentry;
027c5e7a 8576+ aufs_bindex_t hd_id;
1facf9fc 8577+};
8578+
8579+struct au_dinfo {
8580+ atomic_t di_generation;
8581+
dece6358 8582+ struct au_rwsem di_rwsem;
1facf9fc 8583+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
38d290e6 8584+ unsigned char di_tmpfile; /* to allow the different name */
1facf9fc 8585+ struct au_hdentry *di_hdentry;
4a4d8108 8586+} ____cacheline_aligned_in_smp;
1facf9fc 8587+
8588+/* ---------------------------------------------------------------------- */
8589+
8590+/* dentry.c */
4a4d8108 8591+extern const struct dentry_operations aufs_dop;
1facf9fc 8592+struct au_branch;
076b876e 8593+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 8594+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8595+ struct dentry *h_parent, struct au_branch *br);
8596+
537831f9 8597+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 8598+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 8599+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 8600+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
8601+
8602+/* dinfo.c */
4a4d8108 8603+void au_di_init_once(void *_di);
027c5e7a
AM
8604+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
8605+void au_di_free(struct au_dinfo *dinfo);
8606+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
8607+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
8608+int au_di_init(struct dentry *dentry);
8609+void au_di_fin(struct dentry *dentry);
1facf9fc 8610+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
8611+
8612+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
8613+void di_read_unlock(struct dentry *d, int flags);
8614+void di_downgrade_lock(struct dentry *d, int flags);
8615+void di_write_lock(struct dentry *d, unsigned int lsc);
8616+void di_write_unlock(struct dentry *d);
8617+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
8618+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
8619+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
8620+
8621+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 8622+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 8623+aufs_bindex_t au_dbtail(struct dentry *dentry);
8624+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
8625+
8626+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8627+ struct dentry *h_dentry);
027c5e7a
AM
8628+int au_digen_test(struct dentry *dentry, unsigned int sigen);
8629+int au_dbrange_test(struct dentry *dentry);
1facf9fc 8630+void au_update_digen(struct dentry *dentry);
8631+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
8632+void au_update_dbstart(struct dentry *dentry);
8633+void au_update_dbend(struct dentry *dentry);
8634+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
8635+
8636+/* ---------------------------------------------------------------------- */
8637+
8638+static inline struct au_dinfo *au_di(struct dentry *dentry)
8639+{
8640+ return dentry->d_fsdata;
8641+}
8642+
8643+/* ---------------------------------------------------------------------- */
8644+
8645+/* lock subclass for dinfo */
8646+enum {
8647+ AuLsc_DI_CHILD, /* child first */
4a4d8108 8648+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 8649+ AuLsc_DI_CHILD3, /* copyup dirs */
8650+ AuLsc_DI_PARENT,
8651+ AuLsc_DI_PARENT2,
027c5e7a
AM
8652+ AuLsc_DI_PARENT3,
8653+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 8654+};
8655+
8656+/*
8657+ * di_read_lock_child, di_write_lock_child,
8658+ * di_read_lock_child2, di_write_lock_child2,
8659+ * di_read_lock_child3, di_write_lock_child3,
8660+ * di_read_lock_parent, di_write_lock_parent,
8661+ * di_read_lock_parent2, di_write_lock_parent2,
8662+ * di_read_lock_parent3, di_write_lock_parent3,
8663+ */
8664+#define AuReadLockFunc(name, lsc) \
8665+static inline void di_read_lock_##name(struct dentry *d, int flags) \
8666+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
8667+
8668+#define AuWriteLockFunc(name, lsc) \
8669+static inline void di_write_lock_##name(struct dentry *d) \
8670+{ di_write_lock(d, AuLsc_DI_##lsc); }
8671+
8672+#define AuRWLockFuncs(name, lsc) \
8673+ AuReadLockFunc(name, lsc) \
8674+ AuWriteLockFunc(name, lsc)
8675+
8676+AuRWLockFuncs(child, CHILD);
8677+AuRWLockFuncs(child2, CHILD2);
8678+AuRWLockFuncs(child3, CHILD3);
8679+AuRWLockFuncs(parent, PARENT);
8680+AuRWLockFuncs(parent2, PARENT2);
8681+AuRWLockFuncs(parent3, PARENT3);
8682+
8683+#undef AuReadLockFunc
8684+#undef AuWriteLockFunc
8685+#undef AuRWLockFuncs
8686+
8687+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
8688+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
8689+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 8690+
8691+/* ---------------------------------------------------------------------- */
8692+
8693+/* todo: memory barrier? */
8694+static inline unsigned int au_digen(struct dentry *d)
8695+{
8696+ return atomic_read(&au_di(d)->di_generation);
8697+}
8698+
8699+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
8700+{
8701+ hdentry->hd_dentry = NULL;
8702+}
8703+
8704+static inline void au_hdput(struct au_hdentry *hd)
8705+{
4a4d8108
AM
8706+ if (hd)
8707+ dput(hd->hd_dentry);
1facf9fc 8708+}
8709+
8710+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
8711+{
1308ab2a 8712+ DiMustAnyLock(dentry);
1facf9fc 8713+ return au_di(dentry)->di_bstart;
8714+}
8715+
8716+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
8717+{
1308ab2a 8718+ DiMustAnyLock(dentry);
1facf9fc 8719+ return au_di(dentry)->di_bend;
8720+}
8721+
8722+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
8723+{
1308ab2a 8724+ DiMustAnyLock(dentry);
1facf9fc 8725+ return au_di(dentry)->di_bwh;
8726+}
8727+
8728+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
8729+{
1308ab2a 8730+ DiMustAnyLock(dentry);
1facf9fc 8731+ return au_di(dentry)->di_bdiropq;
8732+}
8733+
8734+/* todo: hard/soft set? */
8735+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
8736+{
1308ab2a 8737+ DiMustWriteLock(dentry);
1facf9fc 8738+ au_di(dentry)->di_bstart = bindex;
8739+}
8740+
8741+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
8742+{
1308ab2a 8743+ DiMustWriteLock(dentry);
1facf9fc 8744+ au_di(dentry)->di_bend = bindex;
8745+}
8746+
8747+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
8748+{
1308ab2a 8749+ DiMustWriteLock(dentry);
1facf9fc 8750+ /* dbwh can be outside of bstart - bend range */
8751+ au_di(dentry)->di_bwh = bindex;
8752+}
8753+
8754+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
8755+{
1308ab2a 8756+ DiMustWriteLock(dentry);
1facf9fc 8757+ au_di(dentry)->di_bdiropq = bindex;
8758+}
8759+
8760+/* ---------------------------------------------------------------------- */
8761+
4a4d8108 8762+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 8763+static inline void au_digen_dec(struct dentry *d)
8764+{
e49829fe 8765+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 8766+}
8767+
4a4d8108 8768+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 8769+{
8770+ dentry->d_fsdata = NULL;
8771+}
8772+#else
4a4d8108
AM
8773+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
8774+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 8775+
8776+#endif /* __KERNEL__ */
8777+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
8778diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
8779--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
2000de60 8780+++ linux/fs/aufs/dinfo.c 2015-03-27 21:56:35.463461668 +0100
38d290e6 8781@@ -0,0 +1,544 @@
1facf9fc 8782+/*
2000de60 8783+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 8784+ *
8785+ * This program, aufs is free software; you can redistribute it and/or modify
8786+ * it under the terms of the GNU General Public License as published by
8787+ * the Free Software Foundation; either version 2 of the License, or
8788+ * (at your option) any later version.
dece6358
AM
8789+ *
8790+ * This program is distributed in the hope that it will be useful,
8791+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8792+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8793+ * GNU General Public License for more details.
8794+ *
8795+ * You should have received a copy of the GNU General Public License
523b37e3 8796+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8797+ */
8798+
8799+/*
8800+ * dentry private data
8801+ */
8802+
8803+#include "aufs.h"
8804+
e49829fe 8805+void au_di_init_once(void *_dinfo)
4a4d8108 8806+{
e49829fe
JR
8807+ struct au_dinfo *dinfo = _dinfo;
8808+ static struct lock_class_key aufs_di;
4a4d8108 8809+
e49829fe
JR
8810+ au_rw_init(&dinfo->di_rwsem);
8811+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
8812+}
8813+
027c5e7a 8814+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 8815+{
8816+ struct au_dinfo *dinfo;
027c5e7a 8817+ int nbr, i;
1facf9fc 8818+
8819+ dinfo = au_cache_alloc_dinfo();
8820+ if (unlikely(!dinfo))
8821+ goto out;
8822+
1facf9fc 8823+ nbr = au_sbend(sb) + 1;
8824+ if (nbr <= 0)
8825+ nbr = 1;
8826+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
8827+ if (dinfo->di_hdentry) {
8828+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
8829+ dinfo->di_bstart = -1;
8830+ dinfo->di_bend = -1;
8831+ dinfo->di_bwh = -1;
8832+ dinfo->di_bdiropq = -1;
38d290e6 8833+ dinfo->di_tmpfile = 0;
027c5e7a
AM
8834+ for (i = 0; i < nbr; i++)
8835+ dinfo->di_hdentry[i].hd_id = -1;
8836+ goto out;
8837+ }
1facf9fc 8838+
1facf9fc 8839+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
8840+ dinfo = NULL;
8841+
4f0767ce 8842+out:
027c5e7a 8843+ return dinfo;
1facf9fc 8844+}
8845+
027c5e7a 8846+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 8847+{
4a4d8108
AM
8848+ struct au_hdentry *p;
8849+ aufs_bindex_t bend, bindex;
8850+
8851+ /* dentry may not be revalidated */
027c5e7a 8852+ bindex = dinfo->di_bstart;
4a4d8108 8853+ if (bindex >= 0) {
027c5e7a
AM
8854+ bend = dinfo->di_bend;
8855+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
8856+ while (bindex++ <= bend)
8857+ au_hdput(p++);
8858+ }
027c5e7a
AM
8859+ kfree(dinfo->di_hdentry);
8860+ au_cache_free_dinfo(dinfo);
8861+}
8862+
8863+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
8864+{
8865+ struct au_hdentry *p;
8866+ aufs_bindex_t bi;
8867+
8868+ AuRwMustWriteLock(&a->di_rwsem);
8869+ AuRwMustWriteLock(&b->di_rwsem);
8870+
8871+#define DiSwap(v, name) \
8872+ do { \
8873+ v = a->di_##name; \
8874+ a->di_##name = b->di_##name; \
8875+ b->di_##name = v; \
8876+ } while (0)
8877+
8878+ DiSwap(p, hdentry);
8879+ DiSwap(bi, bstart);
8880+ DiSwap(bi, bend);
8881+ DiSwap(bi, bwh);
8882+ DiSwap(bi, bdiropq);
8883+ /* smp_mb(); */
8884+
8885+#undef DiSwap
8886+}
8887+
8888+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
8889+{
8890+ AuRwMustWriteLock(&dst->di_rwsem);
8891+ AuRwMustWriteLock(&src->di_rwsem);
8892+
8893+ dst->di_bstart = src->di_bstart;
8894+ dst->di_bend = src->di_bend;
8895+ dst->di_bwh = src->di_bwh;
8896+ dst->di_bdiropq = src->di_bdiropq;
8897+ /* smp_mb(); */
8898+}
8899+
8900+int au_di_init(struct dentry *dentry)
8901+{
8902+ int err;
8903+ struct super_block *sb;
8904+ struct au_dinfo *dinfo;
8905+
8906+ err = 0;
8907+ sb = dentry->d_sb;
8908+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
8909+ if (dinfo) {
8910+ atomic_set(&dinfo->di_generation, au_sigen(sb));
8911+ /* smp_mb(); */ /* atomic_set */
8912+ dentry->d_fsdata = dinfo;
8913+ } else
8914+ err = -ENOMEM;
8915+
8916+ return err;
8917+}
8918+
8919+void au_di_fin(struct dentry *dentry)
8920+{
8921+ struct au_dinfo *dinfo;
8922+
8923+ dinfo = au_di(dentry);
8924+ AuRwDestroy(&dinfo->di_rwsem);
8925+ au_di_free(dinfo);
4a4d8108
AM
8926+}
8927+
1facf9fc 8928+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
8929+{
8930+ int err, sz;
8931+ struct au_hdentry *hdp;
8932+
1308ab2a 8933+ AuRwMustWriteLock(&dinfo->di_rwsem);
8934+
1facf9fc 8935+ err = -ENOMEM;
8936+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
8937+ if (!sz)
8938+ sz = sizeof(*hdp);
8939+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
8940+ if (hdp) {
8941+ dinfo->di_hdentry = hdp;
8942+ err = 0;
8943+ }
8944+
8945+ return err;
8946+}
8947+
8948+/* ---------------------------------------------------------------------- */
8949+
8950+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
8951+{
8952+ switch (lsc) {
8953+ case AuLsc_DI_CHILD:
8954+ ii_write_lock_child(inode);
8955+ break;
8956+ case AuLsc_DI_CHILD2:
8957+ ii_write_lock_child2(inode);
8958+ break;
8959+ case AuLsc_DI_CHILD3:
8960+ ii_write_lock_child3(inode);
8961+ break;
8962+ case AuLsc_DI_PARENT:
8963+ ii_write_lock_parent(inode);
8964+ break;
8965+ case AuLsc_DI_PARENT2:
8966+ ii_write_lock_parent2(inode);
8967+ break;
8968+ case AuLsc_DI_PARENT3:
8969+ ii_write_lock_parent3(inode);
8970+ break;
8971+ default:
8972+ BUG();
8973+ }
8974+}
8975+
8976+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
8977+{
8978+ switch (lsc) {
8979+ case AuLsc_DI_CHILD:
8980+ ii_read_lock_child(inode);
8981+ break;
8982+ case AuLsc_DI_CHILD2:
8983+ ii_read_lock_child2(inode);
8984+ break;
8985+ case AuLsc_DI_CHILD3:
8986+ ii_read_lock_child3(inode);
8987+ break;
8988+ case AuLsc_DI_PARENT:
8989+ ii_read_lock_parent(inode);
8990+ break;
8991+ case AuLsc_DI_PARENT2:
8992+ ii_read_lock_parent2(inode);
8993+ break;
8994+ case AuLsc_DI_PARENT3:
8995+ ii_read_lock_parent3(inode);
8996+ break;
8997+ default:
8998+ BUG();
8999+ }
9000+}
9001+
9002+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
9003+{
dece6358 9004+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 9005+ if (d->d_inode) {
9006+ if (au_ftest_lock(flags, IW))
9007+ do_ii_write_lock(d->d_inode, lsc);
9008+ else if (au_ftest_lock(flags, IR))
9009+ do_ii_read_lock(d->d_inode, lsc);
9010+ }
9011+}
9012+
9013+void di_read_unlock(struct dentry *d, int flags)
9014+{
9015+ if (d->d_inode) {
027c5e7a
AM
9016+ if (au_ftest_lock(flags, IW)) {
9017+ au_dbg_verify_dinode(d);
1facf9fc 9018+ ii_write_unlock(d->d_inode);
027c5e7a
AM
9019+ } else if (au_ftest_lock(flags, IR)) {
9020+ au_dbg_verify_dinode(d);
1facf9fc 9021+ ii_read_unlock(d->d_inode);
027c5e7a 9022+ }
1facf9fc 9023+ }
dece6358 9024+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 9025+}
9026+
9027+void di_downgrade_lock(struct dentry *d, int flags)
9028+{
1facf9fc 9029+ if (d->d_inode && au_ftest_lock(flags, IR))
9030+ ii_downgrade_lock(d->d_inode);
dece6358 9031+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 9032+}
9033+
9034+void di_write_lock(struct dentry *d, unsigned int lsc)
9035+{
dece6358 9036+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 9037+ if (d->d_inode)
9038+ do_ii_write_lock(d->d_inode, lsc);
9039+}
9040+
9041+void di_write_unlock(struct dentry *d)
9042+{
027c5e7a 9043+ au_dbg_verify_dinode(d);
1facf9fc 9044+ if (d->d_inode)
9045+ ii_write_unlock(d->d_inode);
dece6358 9046+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 9047+}
9048+
9049+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
9050+{
9051+ AuDebugOn(d1 == d2
9052+ || d1->d_inode == d2->d_inode
9053+ || d1->d_sb != d2->d_sb);
9054+
9055+ if (isdir && au_test_subdir(d1, d2)) {
9056+ di_write_lock_child(d1);
9057+ di_write_lock_child2(d2);
9058+ } else {
9059+ /* there should be no races */
9060+ di_write_lock_child(d2);
9061+ di_write_lock_child2(d1);
9062+ }
9063+}
9064+
9065+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
9066+{
9067+ AuDebugOn(d1 == d2
9068+ || d1->d_inode == d2->d_inode
9069+ || d1->d_sb != d2->d_sb);
9070+
9071+ if (isdir && au_test_subdir(d1, d2)) {
9072+ di_write_lock_parent(d1);
9073+ di_write_lock_parent2(d2);
9074+ } else {
9075+ /* there should be no races */
9076+ di_write_lock_parent(d2);
9077+ di_write_lock_parent2(d1);
9078+ }
9079+}
9080+
9081+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
9082+{
9083+ di_write_unlock(d1);
9084+ if (d1->d_inode == d2->d_inode)
dece6358 9085+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 9086+ else
9087+ di_write_unlock(d2);
9088+}
9089+
9090+/* ---------------------------------------------------------------------- */
9091+
9092+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
9093+{
9094+ struct dentry *d;
9095+
1308ab2a 9096+ DiMustAnyLock(dentry);
9097+
1facf9fc 9098+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
9099+ return NULL;
9100+ AuDebugOn(bindex < 0);
9101+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
c1595e42 9102+ AuDebugOn(d && au_dcount(d) <= 0);
1facf9fc 9103+ return d;
9104+}
9105+
2cbb1c4b
JR
9106+/*
9107+ * extended version of au_h_dptr().
38d290e6
JR
9108+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
9109+ * error.
2cbb1c4b
JR
9110+ */
9111+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
9112+{
9113+ struct dentry *h_dentry;
9114+ struct inode *inode, *h_inode;
9115+
9116+ inode = dentry->d_inode;
9117+ AuDebugOn(!inode);
9118+
9119+ h_dentry = NULL;
9120+ if (au_dbstart(dentry) <= bindex
9121+ && bindex <= au_dbend(dentry))
9122+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 9123+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
9124+ dget(h_dentry);
9125+ goto out; /* success */
9126+ }
9127+
9128+ AuDebugOn(bindex < au_ibstart(inode));
9129+ AuDebugOn(au_ibend(inode) < bindex);
9130+ h_inode = au_h_iptr(inode, bindex);
9131+ h_dentry = d_find_alias(h_inode);
9132+ if (h_dentry) {
9133+ if (!IS_ERR(h_dentry)) {
38d290e6 9134+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
9135+ goto out; /* success */
9136+ dput(h_dentry);
9137+ } else
9138+ goto out;
9139+ }
9140+
9141+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
9142+ h_dentry = au_plink_lkup(inode, bindex);
9143+ AuDebugOn(!h_dentry);
9144+ if (!IS_ERR(h_dentry)) {
9145+ if (!au_d_hashed_positive(h_dentry))
9146+ goto out; /* success */
9147+ dput(h_dentry);
9148+ h_dentry = NULL;
9149+ }
9150+ }
9151+
9152+out:
9153+ AuDbgDentry(h_dentry);
9154+ return h_dentry;
9155+}
9156+
1facf9fc 9157+aufs_bindex_t au_dbtail(struct dentry *dentry)
9158+{
9159+ aufs_bindex_t bend, bwh;
9160+
9161+ bend = au_dbend(dentry);
9162+ if (0 <= bend) {
9163+ bwh = au_dbwh(dentry);
9164+ if (!bwh)
9165+ return bwh;
9166+ if (0 < bwh && bwh < bend)
9167+ return bwh - 1;
9168+ }
9169+ return bend;
9170+}
9171+
9172+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9173+{
9174+ aufs_bindex_t bend, bopq;
9175+
9176+ bend = au_dbtail(dentry);
9177+ if (0 <= bend) {
9178+ bopq = au_dbdiropq(dentry);
9179+ if (0 <= bopq && bopq < bend)
9180+ bend = bopq;
9181+ }
9182+ return bend;
9183+}
9184+
9185+/* ---------------------------------------------------------------------- */
9186+
9187+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9188+ struct dentry *h_dentry)
9189+{
9190+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 9191+ struct au_branch *br;
1facf9fc 9192+
1308ab2a 9193+ DiMustWriteLock(dentry);
9194+
4a4d8108 9195+ au_hdput(hd);
1facf9fc 9196+ hd->hd_dentry = h_dentry;
027c5e7a
AM
9197+ if (h_dentry) {
9198+ br = au_sbr(dentry->d_sb, bindex);
9199+ hd->hd_id = br->br_id;
9200+ }
9201+}
9202+
9203+int au_dbrange_test(struct dentry *dentry)
9204+{
9205+ int err;
9206+ aufs_bindex_t bstart, bend;
9207+
9208+ err = 0;
9209+ bstart = au_dbstart(dentry);
9210+ bend = au_dbend(dentry);
9211+ if (bstart >= 0)
9212+ AuDebugOn(bend < 0 && bstart > bend);
9213+ else {
9214+ err = -EIO;
9215+ AuDebugOn(bend >= 0);
9216+ }
9217+
9218+ return err;
9219+}
9220+
9221+int au_digen_test(struct dentry *dentry, unsigned int sigen)
9222+{
9223+ int err;
9224+
9225+ err = 0;
9226+ if (unlikely(au_digen(dentry) != sigen
9227+ || au_iigen_test(dentry->d_inode, sigen)))
9228+ err = -EIO;
9229+
9230+ return err;
1facf9fc 9231+}
9232+
9233+void au_update_digen(struct dentry *dentry)
9234+{
9235+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
9236+ /* smp_mb(); */ /* atomic_set */
9237+}
9238+
9239+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
9240+{
9241+ struct au_dinfo *dinfo;
9242+ struct dentry *h_d;
4a4d8108 9243+ struct au_hdentry *hdp;
1facf9fc 9244+
1308ab2a 9245+ DiMustWriteLock(dentry);
9246+
1facf9fc 9247+ dinfo = au_di(dentry);
9248+ if (!dinfo || dinfo->di_bstart < 0)
9249+ return;
9250+
4a4d8108 9251+ hdp = dinfo->di_hdentry;
1facf9fc 9252+ if (do_put_zero) {
9253+ aufs_bindex_t bindex, bend;
9254+
9255+ bend = dinfo->di_bend;
9256+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 9257+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 9258+ if (h_d && !h_d->d_inode)
9259+ au_set_h_dptr(dentry, bindex, NULL);
9260+ }
9261+ }
9262+
9263+ dinfo->di_bstart = -1;
9264+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 9265+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 9266+ break;
9267+ if (dinfo->di_bstart > dinfo->di_bend) {
9268+ dinfo->di_bstart = -1;
9269+ dinfo->di_bend = -1;
9270+ return;
9271+ }
9272+
9273+ dinfo->di_bend++;
9274+ while (0 <= --dinfo->di_bend)
4a4d8108 9275+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 9276+ break;
9277+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
9278+}
9279+
9280+void au_update_dbstart(struct dentry *dentry)
9281+{
9282+ aufs_bindex_t bindex, bend;
9283+ struct dentry *h_dentry;
9284+
9285+ bend = au_dbend(dentry);
9286+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
9287+ h_dentry = au_h_dptr(dentry, bindex);
9288+ if (!h_dentry)
9289+ continue;
9290+ if (h_dentry->d_inode) {
9291+ au_set_dbstart(dentry, bindex);
9292+ return;
9293+ }
9294+ au_set_h_dptr(dentry, bindex, NULL);
9295+ }
9296+}
9297+
9298+void au_update_dbend(struct dentry *dentry)
9299+{
9300+ aufs_bindex_t bindex, bstart;
9301+ struct dentry *h_dentry;
9302+
9303+ bstart = au_dbstart(dentry);
7f207e10 9304+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 9305+ h_dentry = au_h_dptr(dentry, bindex);
9306+ if (!h_dentry)
9307+ continue;
9308+ if (h_dentry->d_inode) {
9309+ au_set_dbend(dentry, bindex);
9310+ return;
9311+ }
9312+ au_set_h_dptr(dentry, bindex, NULL);
9313+ }
9314+}
9315+
9316+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
9317+{
9318+ aufs_bindex_t bindex, bend;
9319+
9320+ bend = au_dbend(dentry);
9321+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
9322+ if (au_h_dptr(dentry, bindex) == h_dentry)
9323+ return bindex;
9324+ return -1;
9325+}
7f207e10
AM
9326diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
9327--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
9328+++ linux/fs/aufs/dir.c 2015-03-27 21:56:35.463461668 +0100
9329@@ -0,0 +1,643 @@
1facf9fc 9330+/*
2000de60 9331+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 9332+ *
9333+ * This program, aufs is free software; you can redistribute it and/or modify
9334+ * it under the terms of the GNU General Public License as published by
9335+ * the Free Software Foundation; either version 2 of the License, or
9336+ * (at your option) any later version.
dece6358
AM
9337+ *
9338+ * This program is distributed in the hope that it will be useful,
9339+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9340+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9341+ * GNU General Public License for more details.
9342+ *
9343+ * You should have received a copy of the GNU General Public License
523b37e3 9344+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9345+ */
9346+
9347+/*
9348+ * directory operations
9349+ */
9350+
9351+#include <linux/fs_stack.h>
9352+#include "aufs.h"
9353+
9354+void au_add_nlink(struct inode *dir, struct inode *h_dir)
9355+{
9dbd164d
AM
9356+ unsigned int nlink;
9357+
1facf9fc 9358+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9359+
9dbd164d
AM
9360+ nlink = dir->i_nlink;
9361+ nlink += h_dir->i_nlink - 2;
1facf9fc 9362+ if (h_dir->i_nlink < 2)
9dbd164d 9363+ nlink += 2;
f6b6e03d 9364+ smp_mb(); /* for i_nlink */
7eafdf33 9365+ /* 0 can happen in revaliding */
92d182d2 9366+ set_nlink(dir, nlink);
1facf9fc 9367+}
9368+
9369+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
9370+{
9dbd164d
AM
9371+ unsigned int nlink;
9372+
1facf9fc 9373+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9374+
9dbd164d
AM
9375+ nlink = dir->i_nlink;
9376+ nlink -= h_dir->i_nlink - 2;
1facf9fc 9377+ if (h_dir->i_nlink < 2)
9dbd164d 9378+ nlink -= 2;
f6b6e03d 9379+ smp_mb(); /* for i_nlink */
92d182d2 9380+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 9381+ set_nlink(dir, nlink);
1facf9fc 9382+}
9383+
1308ab2a 9384+loff_t au_dir_size(struct file *file, struct dentry *dentry)
9385+{
9386+ loff_t sz;
9387+ aufs_bindex_t bindex, bend;
9388+ struct file *h_file;
9389+ struct dentry *h_dentry;
9390+
9391+ sz = 0;
9392+ if (file) {
2000de60 9393+ AuDebugOn(!d_is_dir(file->f_path.dentry));
1308ab2a 9394+
4a4d8108 9395+ bend = au_fbend_dir(file);
1308ab2a 9396+ for (bindex = au_fbstart(file);
9397+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9398+ bindex++) {
4a4d8108 9399+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
9400+ if (h_file && file_inode(h_file))
9401+ sz += vfsub_f_size_read(h_file);
1308ab2a 9402+ }
9403+ } else {
9404+ AuDebugOn(!dentry);
2000de60 9405+ AuDebugOn(!d_is_dir(dentry));
1308ab2a 9406+
9407+ bend = au_dbtaildir(dentry);
9408+ for (bindex = au_dbstart(dentry);
9409+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9410+ bindex++) {
9411+ h_dentry = au_h_dptr(dentry, bindex);
9412+ if (h_dentry && h_dentry->d_inode)
9413+ sz += i_size_read(h_dentry->d_inode);
9414+ }
9415+ }
9416+ if (sz < KMALLOC_MAX_SIZE)
9417+ sz = roundup_pow_of_two(sz);
9418+ if (sz > KMALLOC_MAX_SIZE)
9419+ sz = KMALLOC_MAX_SIZE;
9420+ else if (sz < NAME_MAX) {
9421+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
9422+ sz = AUFS_RDBLK_DEF;
9423+ }
9424+ return sz;
9425+}
9426+
1facf9fc 9427+/* ---------------------------------------------------------------------- */
9428+
9429+static int reopen_dir(struct file *file)
9430+{
9431+ int err;
9432+ unsigned int flags;
9433+ aufs_bindex_t bindex, btail, bstart;
9434+ struct dentry *dentry, *h_dentry;
9435+ struct file *h_file;
9436+
9437+ /* open all lower dirs */
2000de60 9438+ dentry = file->f_path.dentry;
1facf9fc 9439+ bstart = au_dbstart(dentry);
9440+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
9441+ au_set_h_fptr(file, bindex, NULL);
9442+ au_set_fbstart(file, bstart);
9443+
9444+ btail = au_dbtaildir(dentry);
4a4d8108 9445+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 9446+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 9447+ au_set_fbend_dir(file, btail);
1facf9fc 9448+
4a4d8108 9449+ flags = vfsub_file_flags(file);
1facf9fc 9450+ for (bindex = bstart; bindex <= btail; bindex++) {
9451+ h_dentry = au_h_dptr(dentry, bindex);
9452+ if (!h_dentry)
9453+ continue;
4a4d8108 9454+ h_file = au_hf_dir(file, bindex);
1facf9fc 9455+ if (h_file)
9456+ continue;
9457+
392086de 9458+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9459+ err = PTR_ERR(h_file);
9460+ if (IS_ERR(h_file))
9461+ goto out; /* close all? */
9462+ au_set_h_fptr(file, bindex, h_file);
9463+ }
9464+ au_update_figen(file);
9465+ /* todo: necessary? */
9466+ /* file->f_ra = h_file->f_ra; */
9467+ err = 0;
9468+
4f0767ce 9469+out:
1facf9fc 9470+ return err;
9471+}
9472+
9473+static int do_open_dir(struct file *file, int flags)
9474+{
9475+ int err;
9476+ aufs_bindex_t bindex, btail;
9477+ struct dentry *dentry, *h_dentry;
9478+ struct file *h_file;
9479+
1308ab2a 9480+ FiMustWriteLock(file);
9481+
523b37e3 9482+ err = 0;
2000de60 9483+ dentry = file->f_path.dentry;
1facf9fc 9484+ file->f_version = dentry->d_inode->i_version;
9485+ bindex = au_dbstart(dentry);
9486+ au_set_fbstart(file, bindex);
9487+ btail = au_dbtaildir(dentry);
4a4d8108 9488+ au_set_fbend_dir(file, btail);
1facf9fc 9489+ for (; !err && bindex <= btail; bindex++) {
9490+ h_dentry = au_h_dptr(dentry, bindex);
9491+ if (!h_dentry)
9492+ continue;
9493+
392086de 9494+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9495+ if (IS_ERR(h_file)) {
9496+ err = PTR_ERR(h_file);
9497+ break;
9498+ }
9499+ au_set_h_fptr(file, bindex, h_file);
9500+ }
9501+ au_update_figen(file);
9502+ /* todo: necessary? */
9503+ /* file->f_ra = h_file->f_ra; */
9504+ if (!err)
9505+ return 0; /* success */
9506+
9507+ /* close all */
9508+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
9509+ au_set_h_fptr(file, bindex, NULL);
9510+ au_set_fbstart(file, -1);
4a4d8108
AM
9511+ au_set_fbend_dir(file, -1);
9512+
1facf9fc 9513+ return err;
9514+}
9515+
9516+static int aufs_open_dir(struct inode *inode __maybe_unused,
9517+ struct file *file)
9518+{
4a4d8108
AM
9519+ int err;
9520+ struct super_block *sb;
9521+ struct au_fidir *fidir;
9522+
9523+ err = -ENOMEM;
2000de60 9524+ sb = file->f_path.dentry->d_sb;
4a4d8108 9525+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 9526+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
9527+ if (fidir) {
9528+ err = au_do_open(file, do_open_dir, fidir);
9529+ if (unlikely(err))
9530+ kfree(fidir);
9531+ }
9532+ si_read_unlock(sb);
9533+ return err;
1facf9fc 9534+}
9535+
9536+static int aufs_release_dir(struct inode *inode __maybe_unused,
9537+ struct file *file)
9538+{
9539+ struct au_vdir *vdir_cache;
4a4d8108
AM
9540+ struct au_finfo *finfo;
9541+ struct au_fidir *fidir;
9542+ aufs_bindex_t bindex, bend;
1facf9fc 9543+
4a4d8108
AM
9544+ finfo = au_fi(file);
9545+ fidir = finfo->fi_hdir;
9546+ if (fidir) {
076b876e 9547+ au_sphl_del(&finfo->fi_hlist,
2000de60 9548+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108
AM
9549+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
9550+ if (vdir_cache)
9551+ au_vdir_free(vdir_cache);
9552+
9553+ bindex = finfo->fi_btop;
9554+ if (bindex >= 0) {
9555+ /*
9556+ * calls fput() instead of filp_close(),
9557+ * since no dnotify or lock for the lower file.
9558+ */
9559+ bend = fidir->fd_bbot;
9560+ for (; bindex <= bend; bindex++)
9561+ au_set_h_fptr(file, bindex, NULL);
9562+ }
9563+ kfree(fidir);
9564+ finfo->fi_hdir = NULL;
1facf9fc 9565+ }
1facf9fc 9566+ au_finfo_fin(file);
1facf9fc 9567+ return 0;
9568+}
9569+
9570+/* ---------------------------------------------------------------------- */
9571+
4a4d8108
AM
9572+static int au_do_flush_dir(struct file *file, fl_owner_t id)
9573+{
9574+ int err;
9575+ aufs_bindex_t bindex, bend;
9576+ struct file *h_file;
9577+
9578+ err = 0;
9579+ bend = au_fbend_dir(file);
9580+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
9581+ h_file = au_hf_dir(file, bindex);
9582+ if (h_file)
9583+ err = vfsub_flush(h_file, id);
9584+ }
9585+ return err;
9586+}
9587+
9588+static int aufs_flush_dir(struct file *file, fl_owner_t id)
9589+{
9590+ return au_do_flush(file, id, au_do_flush_dir);
9591+}
9592+
9593+/* ---------------------------------------------------------------------- */
9594+
1facf9fc 9595+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
9596+{
9597+ int err;
9598+ aufs_bindex_t bend, bindex;
9599+ struct inode *inode;
9600+ struct super_block *sb;
9601+
9602+ err = 0;
9603+ sb = dentry->d_sb;
9604+ inode = dentry->d_inode;
9605+ IMustLock(inode);
9606+ bend = au_dbend(dentry);
9607+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
9608+ struct path h_path;
1facf9fc 9609+
9610+ if (au_test_ro(sb, bindex, inode))
9611+ continue;
9612+ h_path.dentry = au_h_dptr(dentry, bindex);
9613+ if (!h_path.dentry)
9614+ continue;
1facf9fc 9615+
1facf9fc 9616+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 9617+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 9618+ }
9619+
9620+ return err;
9621+}
9622+
9623+static int au_do_fsync_dir(struct file *file, int datasync)
9624+{
9625+ int err;
9626+ aufs_bindex_t bend, bindex;
9627+ struct file *h_file;
9628+ struct super_block *sb;
9629+ struct inode *inode;
1facf9fc 9630+
9631+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9632+ if (unlikely(err))
9633+ goto out;
9634+
2000de60 9635+ sb = file->f_path.dentry->d_sb;
c06a8ce3 9636+ inode = file_inode(file);
4a4d8108 9637+ bend = au_fbend_dir(file);
1facf9fc 9638+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 9639+ h_file = au_hf_dir(file, bindex);
1facf9fc 9640+ if (!h_file || au_test_ro(sb, bindex, inode))
9641+ continue;
9642+
53392da6 9643+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 9644+ }
9645+
4f0767ce 9646+out:
1facf9fc 9647+ return err;
9648+}
9649+
9650+/*
9651+ * @file may be NULL
9652+ */
1e00d052
AM
9653+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
9654+ int datasync)
1facf9fc 9655+{
9656+ int err;
b752ccd1 9657+ struct dentry *dentry;
1facf9fc 9658+ struct super_block *sb;
1e00d052 9659+ struct mutex *mtx;
1facf9fc 9660+
9661+ err = 0;
2000de60 9662+ dentry = file->f_path.dentry;
1e00d052
AM
9663+ mtx = &dentry->d_inode->i_mutex;
9664+ mutex_lock(mtx);
1facf9fc 9665+ sb = dentry->d_sb;
9666+ si_noflush_read_lock(sb);
9667+ if (file)
9668+ err = au_do_fsync_dir(file, datasync);
9669+ else {
9670+ di_write_lock_child(dentry);
9671+ err = au_do_fsync_dir_no_file(dentry, datasync);
9672+ }
9673+ au_cpup_attr_timesizes(dentry->d_inode);
9674+ di_write_unlock(dentry);
9675+ if (file)
9676+ fi_write_unlock(file);
9677+
9678+ si_read_unlock(sb);
1e00d052 9679+ mutex_unlock(mtx);
1facf9fc 9680+ return err;
9681+}
9682+
9683+/* ---------------------------------------------------------------------- */
9684+
392086de 9685+static int aufs_iterate(struct file *file, struct dir_context *ctx)
1facf9fc 9686+{
9687+ int err;
9688+ struct dentry *dentry;
9dbd164d 9689+ struct inode *inode, *h_inode;
1facf9fc 9690+ struct super_block *sb;
9691+
523b37e3 9692+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 9693+
2000de60 9694+ dentry = file->f_path.dentry;
1facf9fc 9695+ inode = dentry->d_inode;
9696+ IMustLock(inode);
9697+
9698+ sb = dentry->d_sb;
9699+ si_read_lock(sb, AuLock_FLUSH);
9700+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9701+ if (unlikely(err))
9702+ goto out;
027c5e7a
AM
9703+ err = au_alive_dir(dentry);
9704+ if (!err)
9705+ err = au_vdir_init(file);
1facf9fc 9706+ di_downgrade_lock(dentry, AuLock_IR);
9707+ if (unlikely(err))
9708+ goto out_unlock;
9709+
9dbd164d 9710+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 9711+ if (!au_test_nfsd()) {
392086de 9712+ err = au_vdir_fill_de(file, ctx);
9dbd164d 9713+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 9714+ } else {
9715+ /*
9716+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
9717+ * encode_fh() and others.
9718+ */
9dbd164d 9719+ atomic_inc(&h_inode->i_count);
1facf9fc 9720+ di_read_unlock(dentry, AuLock_IR);
9721+ si_read_unlock(sb);
392086de 9722+ err = au_vdir_fill_de(file, ctx);
1facf9fc 9723+ fsstack_copy_attr_atime(inode, h_inode);
9724+ fi_write_unlock(file);
9dbd164d 9725+ iput(h_inode);
1facf9fc 9726+
9727+ AuTraceErr(err);
9728+ return err;
9729+ }
9730+
4f0767ce 9731+out_unlock:
1facf9fc 9732+ di_read_unlock(dentry, AuLock_IR);
9733+ fi_write_unlock(file);
4f0767ce 9734+out:
1facf9fc 9735+ si_read_unlock(sb);
9736+ return err;
9737+}
9738+
9739+/* ---------------------------------------------------------------------- */
9740+
9741+#define AuTestEmpty_WHONLY 1
dece6358
AM
9742+#define AuTestEmpty_CALLED (1 << 1)
9743+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 9744+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
9745+#define au_fset_testempty(flags, name) \
9746+ do { (flags) |= AuTestEmpty_##name; } while (0)
9747+#define au_fclr_testempty(flags, name) \
9748+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 9749+
dece6358
AM
9750+#ifndef CONFIG_AUFS_SHWH
9751+#undef AuTestEmpty_SHWH
9752+#define AuTestEmpty_SHWH 0
9753+#endif
9754+
1facf9fc 9755+struct test_empty_arg {
392086de 9756+ struct dir_context ctx;
1308ab2a 9757+ struct au_nhash *whlist;
1facf9fc 9758+ unsigned int flags;
9759+ int err;
9760+ aufs_bindex_t bindex;
9761+};
9762+
392086de
AM
9763+static int test_empty_cb(struct dir_context *ctx, const char *__name,
9764+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 9765+ unsigned int d_type)
1facf9fc 9766+{
392086de
AM
9767+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
9768+ ctx);
1facf9fc 9769+ char *name = (void *)__name;
9770+
9771+ arg->err = 0;
9772+ au_fset_testempty(arg->flags, CALLED);
9773+ /* smp_mb(); */
9774+ if (name[0] == '.'
9775+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
9776+ goto out; /* success */
9777+
9778+ if (namelen <= AUFS_WH_PFX_LEN
9779+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
9780+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 9781+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9782+ arg->err = -ENOTEMPTY;
9783+ goto out;
9784+ }
9785+
9786+ name += AUFS_WH_PFX_LEN;
9787+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 9788+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9789+ arg->err = au_nhash_append_wh
1308ab2a 9790+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 9791+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 9792+
4f0767ce 9793+out:
1facf9fc 9794+ /* smp_mb(); */
9795+ AuTraceErr(arg->err);
9796+ return arg->err;
9797+}
9798+
9799+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9800+{
9801+ int err;
9802+ struct file *h_file;
9803+
9804+ h_file = au_h_open(dentry, arg->bindex,
9805+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 9806+ /*file*/NULL, /*force_wr*/0);
1facf9fc 9807+ err = PTR_ERR(h_file);
9808+ if (IS_ERR(h_file))
9809+ goto out;
9810+
9811+ err = 0;
9812+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 9813+ && !file_inode(h_file)->i_nlink)
1facf9fc 9814+ goto out_put;
9815+
9816+ do {
9817+ arg->err = 0;
9818+ au_fclr_testempty(arg->flags, CALLED);
9819+ /* smp_mb(); */
392086de 9820+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 9821+ if (err >= 0)
9822+ err = arg->err;
9823+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
9824+
4f0767ce 9825+out_put:
1facf9fc 9826+ fput(h_file);
9827+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 9828+out:
1facf9fc 9829+ return err;
9830+}
9831+
9832+struct do_test_empty_args {
9833+ int *errp;
9834+ struct dentry *dentry;
9835+ struct test_empty_arg *arg;
9836+};
9837+
9838+static void call_do_test_empty(void *args)
9839+{
9840+ struct do_test_empty_args *a = args;
9841+ *a->errp = do_test_empty(a->dentry, a->arg);
9842+}
9843+
9844+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9845+{
9846+ int err, wkq_err;
9847+ struct dentry *h_dentry;
9848+ struct inode *h_inode;
9849+
9850+ h_dentry = au_h_dptr(dentry, arg->bindex);
9851+ h_inode = h_dentry->d_inode;
53392da6 9852+ /* todo: i_mode changes anytime? */
1facf9fc 9853+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
9854+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
9855+ mutex_unlock(&h_inode->i_mutex);
9856+ if (!err)
9857+ err = do_test_empty(dentry, arg);
9858+ else {
9859+ struct do_test_empty_args args = {
9860+ .errp = &err,
9861+ .dentry = dentry,
9862+ .arg = arg
9863+ };
9864+ unsigned int flags = arg->flags;
9865+
9866+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
9867+ if (unlikely(wkq_err))
9868+ err = wkq_err;
9869+ arg->flags = flags;
9870+ }
9871+
9872+ return err;
9873+}
9874+
9875+int au_test_empty_lower(struct dentry *dentry)
9876+{
9877+ int err;
1308ab2a 9878+ unsigned int rdhash;
1facf9fc 9879+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 9880+ struct au_nhash whlist;
392086de
AM
9881+ struct test_empty_arg arg = {
9882+ .ctx = {
2000de60 9883+ .actor = test_empty_cb
392086de
AM
9884+ }
9885+ };
076b876e 9886+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 9887+
dece6358
AM
9888+ SiMustAnyLock(dentry->d_sb);
9889+
1308ab2a 9890+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
9891+ if (!rdhash)
9892+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
9893+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 9894+ if (unlikely(err))
1facf9fc 9895+ goto out;
9896+
1facf9fc 9897+ arg.flags = 0;
1308ab2a 9898+ arg.whlist = &whlist;
9899+ bstart = au_dbstart(dentry);
dece6358
AM
9900+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9901+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
9902+ test_empty = do_test_empty;
9903+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
9904+ test_empty = sio_test_empty;
1facf9fc 9905+ arg.bindex = bstart;
076b876e 9906+ err = test_empty(dentry, &arg);
1facf9fc 9907+ if (unlikely(err))
9908+ goto out_whlist;
9909+
9910+ au_fset_testempty(arg.flags, WHONLY);
9911+ btail = au_dbtaildir(dentry);
9912+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
9913+ struct dentry *h_dentry;
9914+
9915+ h_dentry = au_h_dptr(dentry, bindex);
9916+ if (h_dentry && h_dentry->d_inode) {
9917+ arg.bindex = bindex;
076b876e 9918+ err = test_empty(dentry, &arg);
1facf9fc 9919+ }
9920+ }
9921+
4f0767ce 9922+out_whlist:
1308ab2a 9923+ au_nhash_wh_free(&whlist);
4f0767ce 9924+out:
1facf9fc 9925+ return err;
9926+}
9927+
9928+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
9929+{
9930+ int err;
392086de
AM
9931+ struct test_empty_arg arg = {
9932+ .ctx = {
2000de60 9933+ .actor = test_empty_cb
392086de
AM
9934+ }
9935+ };
1facf9fc 9936+ aufs_bindex_t bindex, btail;
9937+
9938+ err = 0;
1308ab2a 9939+ arg.whlist = whlist;
1facf9fc 9940+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
9941+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9942+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 9943+ btail = au_dbtaildir(dentry);
9944+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
9945+ struct dentry *h_dentry;
9946+
9947+ h_dentry = au_h_dptr(dentry, bindex);
9948+ if (h_dentry && h_dentry->d_inode) {
9949+ arg.bindex = bindex;
9950+ err = sio_test_empty(dentry, &arg);
9951+ }
9952+ }
9953+
9954+ return err;
9955+}
9956+
9957+/* ---------------------------------------------------------------------- */
9958+
9959+const struct file_operations aufs_dir_fop = {
4a4d8108 9960+ .owner = THIS_MODULE,
027c5e7a 9961+ .llseek = default_llseek,
1facf9fc 9962+ .read = generic_read_dir,
392086de 9963+ .iterate = aufs_iterate,
1facf9fc 9964+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
9965+#ifdef CONFIG_COMPAT
9966+ .compat_ioctl = aufs_compat_ioctl_dir,
9967+#endif
1facf9fc 9968+ .open = aufs_open_dir,
9969+ .release = aufs_release_dir,
4a4d8108 9970+ .flush = aufs_flush_dir,
1facf9fc 9971+ .fsync = aufs_fsync_dir
9972+};
7f207e10
AM
9973diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
9974--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
2000de60 9975+++ linux/fs/aufs/dir.h 2015-03-27 21:56:35.463461668 +0100
c1595e42 9976@@ -0,0 +1,130 @@
1facf9fc 9977+/*
2000de60 9978+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 9979+ *
9980+ * This program, aufs is free software; you can redistribute it and/or modify
9981+ * it under the terms of the GNU General Public License as published by
9982+ * the Free Software Foundation; either version 2 of the License, or
9983+ * (at your option) any later version.
dece6358
AM
9984+ *
9985+ * This program is distributed in the hope that it will be useful,
9986+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9987+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9988+ * GNU General Public License for more details.
9989+ *
9990+ * You should have received a copy of the GNU General Public License
523b37e3 9991+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9992+ */
9993+
9994+/*
9995+ * directory operations
9996+ */
9997+
9998+#ifndef __AUFS_DIR_H__
9999+#define __AUFS_DIR_H__
10000+
10001+#ifdef __KERNEL__
10002+
10003+#include <linux/fs.h>
1facf9fc 10004+
10005+/* ---------------------------------------------------------------------- */
10006+
10007+/* need to be faster and smaller */
10008+
10009+struct au_nhash {
dece6358
AM
10010+ unsigned int nh_num;
10011+ struct hlist_head *nh_head;
1facf9fc 10012+};
10013+
10014+struct au_vdir_destr {
10015+ unsigned char len;
10016+ unsigned char name[0];
10017+} __packed;
10018+
10019+struct au_vdir_dehstr {
10020+ struct hlist_node hash;
10021+ struct au_vdir_destr *str;
4a4d8108 10022+} ____cacheline_aligned_in_smp;
1facf9fc 10023+
10024+struct au_vdir_de {
10025+ ino_t de_ino;
10026+ unsigned char de_type;
10027+ /* caution: packed */
10028+ struct au_vdir_destr de_str;
10029+} __packed;
10030+
10031+struct au_vdir_wh {
10032+ struct hlist_node wh_hash;
dece6358
AM
10033+#ifdef CONFIG_AUFS_SHWH
10034+ ino_t wh_ino;
1facf9fc 10035+ aufs_bindex_t wh_bindex;
dece6358
AM
10036+ unsigned char wh_type;
10037+#else
10038+ aufs_bindex_t wh_bindex;
10039+#endif
10040+ /* caution: packed */
1facf9fc 10041+ struct au_vdir_destr wh_str;
10042+} __packed;
10043+
10044+union au_vdir_deblk_p {
10045+ unsigned char *deblk;
10046+ struct au_vdir_de *de;
10047+};
10048+
10049+struct au_vdir {
10050+ unsigned char **vd_deblk;
10051+ unsigned long vd_nblk;
1facf9fc 10052+ struct {
10053+ unsigned long ul;
10054+ union au_vdir_deblk_p p;
10055+ } vd_last;
10056+
10057+ unsigned long vd_version;
dece6358 10058+ unsigned int vd_deblk_sz;
1facf9fc 10059+ unsigned long vd_jiffy;
4a4d8108 10060+} ____cacheline_aligned_in_smp;
1facf9fc 10061+
10062+/* ---------------------------------------------------------------------- */
10063+
10064+/* dir.c */
10065+extern const struct file_operations aufs_dir_fop;
10066+void au_add_nlink(struct inode *dir, struct inode *h_dir);
10067+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 10068+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 10069+int au_test_empty_lower(struct dentry *dentry);
10070+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
10071+
10072+/* vdir.c */
1308ab2a 10073+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
10074+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
10075+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 10076+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
10077+ int limit);
dece6358
AM
10078+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
10079+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
10080+ unsigned int d_type, aufs_bindex_t bindex,
10081+ unsigned char shwh);
1facf9fc 10082+void au_vdir_free(struct au_vdir *vdir);
10083+int au_vdir_init(struct file *file);
392086de 10084+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 10085+
10086+/* ioctl.c */
10087+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
10088+
1308ab2a 10089+#ifdef CONFIG_AUFS_RDU
10090+/* rdu.c */
10091+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
10092+#ifdef CONFIG_COMPAT
10093+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
10094+ unsigned long arg);
10095+#endif
1308ab2a 10096+#else
c1595e42
JR
10097+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
10098+ unsigned int cmd, unsigned long arg)
b752ccd1 10099+#ifdef CONFIG_COMPAT
c1595e42
JR
10100+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
10101+ unsigned int cmd, unsigned long arg)
b752ccd1 10102+#endif
1308ab2a 10103+#endif
10104+
1facf9fc 10105+#endif /* __KERNEL__ */
10106+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
10107diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
10108--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
2000de60 10109+++ linux/fs/aufs/dynop.c 2015-03-27 21:56:35.463461668 +0100
523b37e3 10110@@ -0,0 +1,379 @@
1facf9fc 10111+/*
2000de60 10112+ * Copyright (C) 2010-2015 Junjiro R. Okajima
1facf9fc 10113+ *
10114+ * This program, aufs is free software; you can redistribute it and/or modify
10115+ * it under the terms of the GNU General Public License as published by
10116+ * the Free Software Foundation; either version 2 of the License, or
10117+ * (at your option) any later version.
dece6358
AM
10118+ *
10119+ * This program is distributed in the hope that it will be useful,
10120+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10121+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10122+ * GNU General Public License for more details.
10123+ *
10124+ * You should have received a copy of the GNU General Public License
523b37e3 10125+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10126+ */
10127+
10128+/*
4a4d8108 10129+ * dynamically customizable operations for regular files
1facf9fc 10130+ */
10131+
1facf9fc 10132+#include "aufs.h"
10133+
4a4d8108 10134+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 10135+
4a4d8108
AM
10136+/*
10137+ * How large will these lists be?
10138+ * Usually just a few elements, 20-30 at most for each, I guess.
10139+ */
10140+static struct au_splhead dynop[AuDyLast];
10141+
10142+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 10143+{
4a4d8108
AM
10144+ struct au_dykey *key, *tmp;
10145+ struct list_head *head;
1facf9fc 10146+
4a4d8108
AM
10147+ key = NULL;
10148+ head = &spl->head;
10149+ rcu_read_lock();
10150+ list_for_each_entry_rcu(tmp, head, dk_list)
10151+ if (tmp->dk_op.dy_hop == h_op) {
10152+ key = tmp;
10153+ kref_get(&key->dk_kref);
10154+ break;
10155+ }
10156+ rcu_read_unlock();
10157+
10158+ return key;
1facf9fc 10159+}
10160+
4a4d8108 10161+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 10162+{
4a4d8108
AM
10163+ struct au_dykey **k, *found;
10164+ const void *h_op = key->dk_op.dy_hop;
10165+ int i;
1facf9fc 10166+
4a4d8108
AM
10167+ found = NULL;
10168+ k = br->br_dykey;
10169+ for (i = 0; i < AuBrDynOp; i++)
10170+ if (k[i]) {
10171+ if (k[i]->dk_op.dy_hop == h_op) {
10172+ found = k[i];
10173+ break;
10174+ }
10175+ } else
10176+ break;
10177+ if (!found) {
10178+ spin_lock(&br->br_dykey_lock);
10179+ for (; i < AuBrDynOp; i++)
10180+ if (k[i]) {
10181+ if (k[i]->dk_op.dy_hop == h_op) {
10182+ found = k[i];
10183+ break;
10184+ }
10185+ } else {
10186+ k[i] = key;
10187+ break;
10188+ }
10189+ spin_unlock(&br->br_dykey_lock);
10190+ BUG_ON(i == AuBrDynOp); /* expand the array */
10191+ }
10192+
10193+ return found;
1facf9fc 10194+}
10195+
4a4d8108
AM
10196+/* kref_get() if @key is already added */
10197+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
10198+{
10199+ struct au_dykey *tmp, *found;
10200+ struct list_head *head;
10201+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 10202+
4a4d8108
AM
10203+ found = NULL;
10204+ head = &spl->head;
10205+ spin_lock(&spl->spin);
10206+ list_for_each_entry(tmp, head, dk_list)
10207+ if (tmp->dk_op.dy_hop == h_op) {
10208+ kref_get(&tmp->dk_kref);
10209+ found = tmp;
10210+ break;
10211+ }
10212+ if (!found)
10213+ list_add_rcu(&key->dk_list, head);
10214+ spin_unlock(&spl->spin);
1facf9fc 10215+
4a4d8108
AM
10216+ if (!found)
10217+ DyPrSym(key);
10218+ return found;
10219+}
10220+
10221+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 10222+{
4a4d8108
AM
10223+ struct au_dykey *key;
10224+
10225+ key = container_of(rcu, struct au_dykey, dk_rcu);
10226+ DyPrSym(key);
10227+ kfree(key);
1facf9fc 10228+}
10229+
4a4d8108
AM
10230+static void dy_free(struct kref *kref)
10231+{
10232+ struct au_dykey *key;
10233+ struct au_splhead *spl;
1facf9fc 10234+
4a4d8108
AM
10235+ key = container_of(kref, struct au_dykey, dk_kref);
10236+ spl = dynop + key->dk_op.dy_type;
10237+ au_spl_del_rcu(&key->dk_list, spl);
10238+ call_rcu(&key->dk_rcu, dy_free_rcu);
10239+}
10240+
10241+void au_dy_put(struct au_dykey *key)
1facf9fc 10242+{
4a4d8108
AM
10243+ kref_put(&key->dk_kref, dy_free);
10244+}
1facf9fc 10245+
4a4d8108
AM
10246+/* ---------------------------------------------------------------------- */
10247+
10248+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
10249+
10250+#ifdef CONFIG_AUFS_DEBUG
10251+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 10252+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
10253+#else
10254+#define DyDbgDeclare(cnt) do {} while (0)
10255+#define DyDbgInc(cnt) do {} while (0)
10256+#endif
10257+
10258+#define DySet(func, dst, src, h_op, h_sb) do { \
10259+ DyDbgInc(cnt); \
10260+ if (h_op->func) { \
10261+ if (src.func) \
10262+ dst.func = src.func; \
10263+ else \
10264+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
10265+ } \
10266+} while (0)
10267+
10268+#define DySetForce(func, dst, src) do { \
10269+ AuDebugOn(!src.func); \
10270+ DyDbgInc(cnt); \
10271+ dst.func = src.func; \
10272+} while (0)
10273+
10274+#define DySetAop(func) \
10275+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
10276+#define DySetAopForce(func) \
10277+ DySetForce(func, dyaop->da_op, aufs_aop)
10278+
10279+static void dy_aop(struct au_dykey *key, const void *h_op,
10280+ struct super_block *h_sb __maybe_unused)
10281+{
10282+ struct au_dyaop *dyaop = (void *)key;
10283+ const struct address_space_operations *h_aop = h_op;
10284+ DyDbgDeclare(cnt);
10285+
10286+ AuDbg("%s\n", au_sbtype(h_sb));
10287+
10288+ DySetAop(writepage);
10289+ DySetAopForce(readpage); /* force */
4a4d8108
AM
10290+ DySetAop(writepages);
10291+ DySetAop(set_page_dirty);
10292+ DySetAop(readpages);
10293+ DySetAop(write_begin);
10294+ DySetAop(write_end);
10295+ DySetAop(bmap);
10296+ DySetAop(invalidatepage);
10297+ DySetAop(releasepage);
027c5e7a 10298+ DySetAop(freepage);
4a4d8108
AM
10299+ /* these two will be changed according to an aufs mount option */
10300+ DySetAop(direct_IO);
10301+ DySetAop(get_xip_mem);
10302+ DySetAop(migratepage);
10303+ DySetAop(launder_page);
10304+ DySetAop(is_partially_uptodate);
392086de 10305+ DySetAop(is_dirty_writeback);
4a4d8108 10306+ DySetAop(error_remove_page);
b4510431
AM
10307+ DySetAop(swap_activate);
10308+ DySetAop(swap_deactivate);
4a4d8108
AM
10309+
10310+ DyDbgSize(cnt, *h_aop);
10311+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
10312+}
10313+
4a4d8108
AM
10314+/* ---------------------------------------------------------------------- */
10315+
10316+static void dy_bug(struct kref *kref)
10317+{
10318+ BUG();
10319+}
10320+
10321+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
10322+{
10323+ struct au_dykey *key, *old;
10324+ struct au_splhead *spl;
b752ccd1 10325+ struct op {
4a4d8108 10326+ unsigned int sz;
b752ccd1
AM
10327+ void (*set)(struct au_dykey *key, const void *h_op,
10328+ struct super_block *h_sb __maybe_unused);
10329+ };
10330+ static const struct op a[] = {
4a4d8108
AM
10331+ [AuDy_AOP] = {
10332+ .sz = sizeof(struct au_dyaop),
b752ccd1 10333+ .set = dy_aop
4a4d8108 10334+ }
b752ccd1
AM
10335+ };
10336+ const struct op *p;
4a4d8108
AM
10337+
10338+ spl = dynop + op->dy_type;
10339+ key = dy_gfind_get(spl, op->dy_hop);
10340+ if (key)
10341+ goto out_add; /* success */
10342+
10343+ p = a + op->dy_type;
10344+ key = kzalloc(p->sz, GFP_NOFS);
10345+ if (unlikely(!key)) {
10346+ key = ERR_PTR(-ENOMEM);
10347+ goto out;
10348+ }
10349+
10350+ key->dk_op.dy_hop = op->dy_hop;
10351+ kref_init(&key->dk_kref);
86dc4139 10352+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
10353+ old = dy_gadd(spl, key);
10354+ if (old) {
10355+ kfree(key);
10356+ key = old;
10357+ }
10358+
10359+out_add:
10360+ old = dy_bradd(br, key);
10361+ if (old)
10362+ /* its ref-count should never be zero here */
10363+ kref_put(&key->dk_kref, dy_bug);
10364+out:
10365+ return key;
10366+}
10367+
10368+/* ---------------------------------------------------------------------- */
10369+/*
10370+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
c1595e42 10371+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
4a4d8108
AM
10372+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
10373+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
10374+ * See the aufs manual in detail.
10375+ *
10376+ * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
10377+ * performance of fadvise() and madvise() may be affected.
10378+ */
10379+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
10380+{
10381+ if (!do_dx) {
10382+ dyaop->da_op.direct_IO = NULL;
10383+ dyaop->da_op.get_xip_mem = NULL;
10384+ } else {
10385+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
10386+ dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
10387+ if (!dyaop->da_get_xip_mem)
10388+ dyaop->da_op.get_xip_mem = NULL;
10389+ }
10390+}
10391+
10392+static struct au_dyaop *dy_aget(struct au_branch *br,
10393+ const struct address_space_operations *h_aop,
10394+ int do_dx)
10395+{
10396+ struct au_dyaop *dyaop;
10397+ struct au_dynop op;
10398+
10399+ op.dy_type = AuDy_AOP;
10400+ op.dy_haop = h_aop;
10401+ dyaop = (void *)dy_get(&op, br);
10402+ if (IS_ERR(dyaop))
10403+ goto out;
10404+ dy_adx(dyaop, do_dx);
10405+
10406+out:
10407+ return dyaop;
10408+}
10409+
10410+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10411+ struct inode *h_inode)
10412+{
10413+ int err, do_dx;
10414+ struct super_block *sb;
10415+ struct au_branch *br;
10416+ struct au_dyaop *dyaop;
10417+
10418+ AuDebugOn(!S_ISREG(h_inode->i_mode));
10419+ IiMustWriteLock(inode);
10420+
10421+ sb = inode->i_sb;
10422+ br = au_sbr(sb, bindex);
10423+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
10424+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
10425+ err = PTR_ERR(dyaop);
10426+ if (IS_ERR(dyaop))
10427+ /* unnecessary to call dy_fput() */
10428+ goto out;
10429+
10430+ err = 0;
10431+ inode->i_mapping->a_ops = &dyaop->da_op;
10432+
10433+out:
10434+ return err;
10435+}
10436+
b752ccd1
AM
10437+/*
10438+ * Is it safe to replace a_ops during the inode/file is in operation?
10439+ * Yes, I hope so.
10440+ */
10441+int au_dy_irefresh(struct inode *inode)
10442+{
10443+ int err;
10444+ aufs_bindex_t bstart;
10445+ struct inode *h_inode;
10446+
10447+ err = 0;
10448+ if (S_ISREG(inode->i_mode)) {
10449+ bstart = au_ibstart(inode);
10450+ h_inode = au_h_iptr(inode, bstart);
10451+ err = au_dy_iaop(inode, bstart, h_inode);
10452+ }
10453+ return err;
10454+}
10455+
4a4d8108
AM
10456+void au_dy_arefresh(int do_dx)
10457+{
10458+ struct au_splhead *spl;
10459+ struct list_head *head;
10460+ struct au_dykey *key;
10461+
10462+ spl = dynop + AuDy_AOP;
10463+ head = &spl->head;
10464+ spin_lock(&spl->spin);
10465+ list_for_each_entry(key, head, dk_list)
10466+ dy_adx((void *)key, do_dx);
10467+ spin_unlock(&spl->spin);
10468+}
10469+
4a4d8108
AM
10470+/* ---------------------------------------------------------------------- */
10471+
10472+void __init au_dy_init(void)
10473+{
10474+ int i;
10475+
10476+ /* make sure that 'struct au_dykey *' can be any type */
10477+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
10478+
10479+ for (i = 0; i < AuDyLast; i++)
10480+ au_spl_init(dynop + i);
10481+}
10482+
10483+void au_dy_fin(void)
10484+{
10485+ int i;
10486+
10487+ for (i = 0; i < AuDyLast; i++)
10488+ WARN_ON(!list_empty(&dynop[i].head));
10489+}
7f207e10
AM
10490diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
10491--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
2000de60 10492+++ linux/fs/aufs/dynop.h 2015-03-27 21:56:35.463461668 +0100
523b37e3 10493@@ -0,0 +1,75 @@
4a4d8108 10494+/*
2000de60 10495+ * Copyright (C) 2010-2015 Junjiro R. Okajima
4a4d8108
AM
10496+ *
10497+ * This program, aufs is free software; you can redistribute it and/or modify
10498+ * it under the terms of the GNU General Public License as published by
10499+ * the Free Software Foundation; either version 2 of the License, or
10500+ * (at your option) any later version.
10501+ *
10502+ * This program is distributed in the hope that it will be useful,
10503+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10504+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10505+ * GNU General Public License for more details.
10506+ *
10507+ * You should have received a copy of the GNU General Public License
523b37e3 10508+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10509+ */
10510+
10511+/*
10512+ * dynamically customizable operations (for regular files only)
10513+ */
10514+
10515+#ifndef __AUFS_DYNOP_H__
10516+#define __AUFS_DYNOP_H__
10517+
10518+#ifdef __KERNEL__
10519+
4a4d8108
AM
10520+#include "inode.h"
10521+
2cbb1c4b 10522+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
10523+
10524+struct au_dynop {
10525+ int dy_type;
10526+ union {
10527+ const void *dy_hop;
10528+ const struct address_space_operations *dy_haop;
4a4d8108
AM
10529+ };
10530+};
10531+
10532+struct au_dykey {
10533+ union {
10534+ struct list_head dk_list;
10535+ struct rcu_head dk_rcu;
10536+ };
10537+ struct au_dynop dk_op;
10538+
10539+ /*
10540+ * during I am in the branch local array, kref is gotten. when the
10541+ * branch is removed, kref is put.
10542+ */
10543+ struct kref dk_kref;
10544+};
10545+
10546+/* stop unioning since their sizes are very different from each other */
10547+struct au_dyaop {
10548+ struct au_dykey da_key;
10549+ struct address_space_operations da_op; /* not const */
10550+ int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
10551+ void **, unsigned long *);
10552+};
10553+
4a4d8108
AM
10554+/* ---------------------------------------------------------------------- */
10555+
10556+/* dynop.c */
10557+struct au_branch;
10558+void au_dy_put(struct au_dykey *key);
10559+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10560+ struct inode *h_inode);
b752ccd1 10561+int au_dy_irefresh(struct inode *inode);
4a4d8108 10562+void au_dy_arefresh(int do_dio);
4a4d8108
AM
10563+
10564+void __init au_dy_init(void);
10565+void au_dy_fin(void);
10566+
4a4d8108
AM
10567+#endif /* __KERNEL__ */
10568+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
10569diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
10570--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
2000de60 10571+++ linux/fs/aufs/export.c 2015-03-27 21:56:35.463461668 +0100
523b37e3 10572@@ -0,0 +1,831 @@
4a4d8108 10573+/*
2000de60 10574+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
10575+ *
10576+ * This program, aufs is free software; you can redistribute it and/or modify
10577+ * it under the terms of the GNU General Public License as published by
10578+ * the Free Software Foundation; either version 2 of the License, or
10579+ * (at your option) any later version.
10580+ *
10581+ * This program is distributed in the hope that it will be useful,
10582+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10583+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10584+ * GNU General Public License for more details.
10585+ *
10586+ * You should have received a copy of the GNU General Public License
523b37e3 10587+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10588+ */
10589+
10590+/*
10591+ * export via nfs
10592+ */
10593+
10594+#include <linux/exportfs.h>
7eafdf33 10595+#include <linux/fs_struct.h>
4a4d8108
AM
10596+#include <linux/namei.h>
10597+#include <linux/nsproxy.h>
10598+#include <linux/random.h>
10599+#include <linux/writeback.h>
7eafdf33 10600+#include "../fs/mount.h"
4a4d8108
AM
10601+#include "aufs.h"
10602+
10603+union conv {
10604+#ifdef CONFIG_AUFS_INO_T_64
10605+ __u32 a[2];
10606+#else
10607+ __u32 a[1];
10608+#endif
10609+ ino_t ino;
10610+};
10611+
10612+static ino_t decode_ino(__u32 *a)
10613+{
10614+ union conv u;
10615+
10616+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
10617+ u.a[0] = a[0];
10618+#ifdef CONFIG_AUFS_INO_T_64
10619+ u.a[1] = a[1];
10620+#endif
10621+ return u.ino;
10622+}
10623+
10624+static void encode_ino(__u32 *a, ino_t ino)
10625+{
10626+ union conv u;
10627+
10628+ u.ino = ino;
10629+ a[0] = u.a[0];
10630+#ifdef CONFIG_AUFS_INO_T_64
10631+ a[1] = u.a[1];
10632+#endif
10633+}
10634+
10635+/* NFS file handle */
10636+enum {
10637+ Fh_br_id,
10638+ Fh_sigen,
10639+#ifdef CONFIG_AUFS_INO_T_64
10640+ /* support 64bit inode number */
10641+ Fh_ino1,
10642+ Fh_ino2,
10643+ Fh_dir_ino1,
10644+ Fh_dir_ino2,
10645+#else
10646+ Fh_ino1,
10647+ Fh_dir_ino1,
10648+#endif
10649+ Fh_igen,
10650+ Fh_h_type,
10651+ Fh_tail,
10652+
10653+ Fh_ino = Fh_ino1,
10654+ Fh_dir_ino = Fh_dir_ino1
10655+};
10656+
10657+static int au_test_anon(struct dentry *dentry)
10658+{
027c5e7a 10659+ /* note: read d_flags without d_lock */
4a4d8108
AM
10660+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
10661+}
10662+
a2a7ad62
AM
10663+int au_test_nfsd(void)
10664+{
10665+ int ret;
10666+ struct task_struct *tsk = current;
10667+ char comm[sizeof(tsk->comm)];
10668+
10669+ ret = 0;
10670+ if (tsk->flags & PF_KTHREAD) {
10671+ get_task_comm(comm, tsk);
10672+ ret = !strcmp(comm, "nfsd");
10673+ }
10674+
10675+ return ret;
10676+}
10677+
4a4d8108
AM
10678+/* ---------------------------------------------------------------------- */
10679+/* inode generation external table */
10680+
b752ccd1 10681+void au_xigen_inc(struct inode *inode)
4a4d8108 10682+{
4a4d8108
AM
10683+ loff_t pos;
10684+ ssize_t sz;
10685+ __u32 igen;
10686+ struct super_block *sb;
10687+ struct au_sbinfo *sbinfo;
10688+
4a4d8108 10689+ sb = inode->i_sb;
b752ccd1 10690+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 10691+
b752ccd1 10692+ sbinfo = au_sbi(sb);
1facf9fc 10693+ pos = inode->i_ino;
10694+ pos *= sizeof(igen);
10695+ igen = inode->i_generation + 1;
1facf9fc 10696+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
10697+ sizeof(igen), &pos);
10698+ if (sz == sizeof(igen))
b752ccd1 10699+ return; /* success */
1facf9fc 10700+
b752ccd1 10701+ if (unlikely(sz >= 0))
1facf9fc 10702+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 10703+}
10704+
10705+int au_xigen_new(struct inode *inode)
10706+{
10707+ int err;
10708+ loff_t pos;
10709+ ssize_t sz;
10710+ struct super_block *sb;
10711+ struct au_sbinfo *sbinfo;
10712+ struct file *file;
10713+
10714+ err = 0;
10715+ /* todo: dirty, at mount time */
10716+ if (inode->i_ino == AUFS_ROOT_INO)
10717+ goto out;
10718+ sb = inode->i_sb;
dece6358 10719+ SiMustAnyLock(sb);
1facf9fc 10720+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10721+ goto out;
10722+
10723+ err = -EFBIG;
10724+ pos = inode->i_ino;
10725+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
10726+ AuIOErr1("too large i%lld\n", pos);
10727+ goto out;
10728+ }
10729+ pos *= sizeof(inode->i_generation);
10730+
10731+ err = 0;
10732+ sbinfo = au_sbi(sb);
10733+ file = sbinfo->si_xigen;
10734+ BUG_ON(!file);
10735+
c06a8ce3 10736+ if (vfsub_f_size_read(file)
1facf9fc 10737+ < pos + sizeof(inode->i_generation)) {
10738+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
10739+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
10740+ sizeof(inode->i_generation), &pos);
10741+ } else
10742+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
10743+ sizeof(inode->i_generation), &pos);
10744+ if (sz == sizeof(inode->i_generation))
10745+ goto out; /* success */
10746+
10747+ err = sz;
10748+ if (unlikely(sz >= 0)) {
10749+ err = -EIO;
10750+ AuIOErr("xigen error (%zd)\n", sz);
10751+ }
10752+
4f0767ce 10753+out:
1facf9fc 10754+ return err;
10755+}
10756+
10757+int au_xigen_set(struct super_block *sb, struct file *base)
10758+{
10759+ int err;
10760+ struct au_sbinfo *sbinfo;
10761+ struct file *file;
10762+
dece6358
AM
10763+ SiMustWriteLock(sb);
10764+
1facf9fc 10765+ sbinfo = au_sbi(sb);
10766+ file = au_xino_create2(base, sbinfo->si_xigen);
10767+ err = PTR_ERR(file);
10768+ if (IS_ERR(file))
10769+ goto out;
10770+ err = 0;
10771+ if (sbinfo->si_xigen)
10772+ fput(sbinfo->si_xigen);
10773+ sbinfo->si_xigen = file;
10774+
4f0767ce 10775+out:
1facf9fc 10776+ return err;
10777+}
10778+
10779+void au_xigen_clr(struct super_block *sb)
10780+{
10781+ struct au_sbinfo *sbinfo;
10782+
dece6358
AM
10783+ SiMustWriteLock(sb);
10784+
1facf9fc 10785+ sbinfo = au_sbi(sb);
10786+ if (sbinfo->si_xigen) {
10787+ fput(sbinfo->si_xigen);
10788+ sbinfo->si_xigen = NULL;
10789+ }
10790+}
10791+
10792+/* ---------------------------------------------------------------------- */
10793+
10794+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
10795+ ino_t dir_ino)
10796+{
10797+ struct dentry *dentry, *d;
10798+ struct inode *inode;
10799+ unsigned int sigen;
10800+
10801+ dentry = NULL;
10802+ inode = ilookup(sb, ino);
10803+ if (!inode)
10804+ goto out;
10805+
10806+ dentry = ERR_PTR(-ESTALE);
10807+ sigen = au_sigen(sb);
10808+ if (unlikely(is_bad_inode(inode)
10809+ || IS_DEADDIR(inode)
537831f9 10810+ || sigen != au_iigen(inode, NULL)))
1facf9fc 10811+ goto out_iput;
10812+
10813+ dentry = NULL;
10814+ if (!dir_ino || S_ISDIR(inode->i_mode))
10815+ dentry = d_find_alias(inode);
10816+ else {
027c5e7a 10817+ spin_lock(&inode->i_lock);
c1595e42 10818+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 10819+ spin_lock(&d->d_lock);
1facf9fc 10820+ if (!au_test_anon(d)
10821+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
10822+ dentry = dget_dlock(d);
10823+ spin_unlock(&d->d_lock);
1facf9fc 10824+ break;
10825+ }
027c5e7a
AM
10826+ spin_unlock(&d->d_lock);
10827+ }
10828+ spin_unlock(&inode->i_lock);
1facf9fc 10829+ }
027c5e7a 10830+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 10831+ /* need to refresh */
1facf9fc 10832+ dput(dentry);
2cbb1c4b 10833+ dentry = NULL;
1facf9fc 10834+ }
10835+
4f0767ce 10836+out_iput:
1facf9fc 10837+ iput(inode);
4f0767ce 10838+out:
2cbb1c4b 10839+ AuTraceErrPtr(dentry);
1facf9fc 10840+ return dentry;
10841+}
10842+
10843+/* ---------------------------------------------------------------------- */
10844+
10845+/* todo: dirty? */
10846+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
10847+
10848+struct au_compare_mnt_args {
10849+ /* input */
10850+ struct super_block *sb;
10851+
10852+ /* output */
10853+ struct vfsmount *mnt;
10854+};
10855+
10856+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
10857+{
10858+ struct au_compare_mnt_args *a = arg;
10859+
10860+ if (mnt->mnt_sb != a->sb)
10861+ return 0;
10862+ a->mnt = mntget(mnt);
10863+ return 1;
10864+}
10865+
1facf9fc 10866+static struct vfsmount *au_mnt_get(struct super_block *sb)
10867+{
4a4d8108 10868+ int err;
7eafdf33 10869+ struct path root;
4a4d8108
AM
10870+ struct au_compare_mnt_args args = {
10871+ .sb = sb
10872+ };
1facf9fc 10873+
7eafdf33 10874+ get_fs_root(current->fs, &root);
523b37e3 10875+ rcu_read_lock();
7eafdf33 10876+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 10877+ rcu_read_unlock();
7eafdf33 10878+ path_put(&root);
4a4d8108
AM
10879+ AuDebugOn(!err);
10880+ AuDebugOn(!args.mnt);
10881+ return args.mnt;
1facf9fc 10882+}
10883+
10884+struct au_nfsd_si_lock {
4a4d8108 10885+ unsigned int sigen;
027c5e7a 10886+ aufs_bindex_t bindex, br_id;
1facf9fc 10887+ unsigned char force_lock;
10888+};
10889+
027c5e7a
AM
10890+static int si_nfsd_read_lock(struct super_block *sb,
10891+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10892+{
027c5e7a 10893+ int err;
1facf9fc 10894+ aufs_bindex_t bindex;
10895+
10896+ si_read_lock(sb, AuLock_FLUSH);
10897+
10898+ /* branch id may be wrapped around */
027c5e7a 10899+ err = 0;
1facf9fc 10900+ bindex = au_br_index(sb, nsi_lock->br_id);
10901+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
10902+ goto out; /* success */
10903+
027c5e7a
AM
10904+ err = -ESTALE;
10905+ bindex = -1;
1facf9fc 10906+ if (!nsi_lock->force_lock)
10907+ si_read_unlock(sb);
1facf9fc 10908+
4f0767ce 10909+out:
027c5e7a
AM
10910+ nsi_lock->bindex = bindex;
10911+ return err;
1facf9fc 10912+}
10913+
10914+struct find_name_by_ino {
392086de 10915+ struct dir_context ctx;
1facf9fc 10916+ int called, found;
10917+ ino_t ino;
10918+ char *name;
10919+ int namelen;
10920+};
10921+
10922+static int
392086de
AM
10923+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
10924+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 10925+{
392086de
AM
10926+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
10927+ ctx);
1facf9fc 10928+
10929+ a->called++;
10930+ if (a->ino != ino)
10931+ return 0;
10932+
10933+ memcpy(a->name, name, namelen);
10934+ a->namelen = namelen;
10935+ a->found = 1;
10936+ return 1;
10937+}
10938+
10939+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
10940+ struct au_nfsd_si_lock *nsi_lock)
10941+{
10942+ struct dentry *dentry, *parent;
10943+ struct file *file;
10944+ struct inode *dir;
392086de
AM
10945+ struct find_name_by_ino arg = {
10946+ .ctx = {
2000de60 10947+ .actor = find_name_by_ino
392086de
AM
10948+ }
10949+ };
1facf9fc 10950+ int err;
10951+
10952+ parent = path->dentry;
10953+ if (nsi_lock)
10954+ si_read_unlock(parent->d_sb);
4a4d8108 10955+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 10956+ dentry = (void *)file;
10957+ if (IS_ERR(file))
10958+ goto out;
10959+
10960+ dentry = ERR_PTR(-ENOMEM);
537831f9 10961+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 10962+ if (unlikely(!arg.name))
10963+ goto out_file;
10964+ arg.ino = ino;
10965+ arg.found = 0;
10966+ do {
10967+ arg.called = 0;
10968+ /* smp_mb(); */
392086de 10969+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 10970+ } while (!err && !arg.found && arg.called);
10971+ dentry = ERR_PTR(err);
10972+ if (unlikely(err))
10973+ goto out_name;
1716fcea
AM
10974+ /* instead of ENOENT */
10975+ dentry = ERR_PTR(-ESTALE);
1facf9fc 10976+ if (!arg.found)
10977+ goto out_name;
10978+
b4510431 10979+ /* do not call vfsub_lkup_one() */
1facf9fc 10980+ dir = parent->d_inode;
10981+ mutex_lock(&dir->i_mutex);
10982+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
10983+ mutex_unlock(&dir->i_mutex);
10984+ AuTraceErrPtr(dentry);
10985+ if (IS_ERR(dentry))
10986+ goto out_name;
10987+ AuDebugOn(au_test_anon(dentry));
10988+ if (unlikely(!dentry->d_inode)) {
10989+ dput(dentry);
10990+ dentry = ERR_PTR(-ENOENT);
10991+ }
10992+
4f0767ce 10993+out_name:
537831f9 10994+ free_page((unsigned long)arg.name);
4f0767ce 10995+out_file:
1facf9fc 10996+ fput(file);
4f0767ce 10997+out:
1facf9fc 10998+ if (unlikely(nsi_lock
10999+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
11000+ if (!IS_ERR(dentry)) {
11001+ dput(dentry);
11002+ dentry = ERR_PTR(-ESTALE);
11003+ }
11004+ AuTraceErrPtr(dentry);
11005+ return dentry;
11006+}
11007+
11008+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
11009+ ino_t dir_ino,
11010+ struct au_nfsd_si_lock *nsi_lock)
11011+{
11012+ struct dentry *dentry;
11013+ struct path path;
11014+
11015+ if (dir_ino != AUFS_ROOT_INO) {
11016+ path.dentry = decode_by_ino(sb, dir_ino, 0);
11017+ dentry = path.dentry;
11018+ if (!path.dentry || IS_ERR(path.dentry))
11019+ goto out;
11020+ AuDebugOn(au_test_anon(path.dentry));
11021+ } else
11022+ path.dentry = dget(sb->s_root);
11023+
11024+ path.mnt = au_mnt_get(sb);
11025+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
11026+ path_put(&path);
11027+
4f0767ce 11028+out:
1facf9fc 11029+ AuTraceErrPtr(dentry);
11030+ return dentry;
11031+}
11032+
11033+/* ---------------------------------------------------------------------- */
11034+
11035+static int h_acceptable(void *expv, struct dentry *dentry)
11036+{
11037+ return 1;
11038+}
11039+
11040+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
11041+ char *buf, int len, struct super_block *sb)
11042+{
11043+ char *p;
11044+ int n;
11045+ struct path path;
11046+
11047+ p = d_path(h_rootpath, buf, len);
11048+ if (IS_ERR(p))
11049+ goto out;
11050+ n = strlen(p);
11051+
11052+ path.mnt = h_rootpath->mnt;
11053+ path.dentry = h_parent;
11054+ p = d_path(&path, buf, len);
11055+ if (IS_ERR(p))
11056+ goto out;
11057+ if (n != 1)
11058+ p += n;
11059+
11060+ path.mnt = au_mnt_get(sb);
11061+ path.dentry = sb->s_root;
11062+ p = d_path(&path, buf, len - strlen(p));
11063+ mntput(path.mnt);
11064+ if (IS_ERR(p))
11065+ goto out;
11066+ if (n != 1)
11067+ p[strlen(p)] = '/';
11068+
4f0767ce 11069+out:
1facf9fc 11070+ AuTraceErrPtr(p);
11071+ return p;
11072+}
11073+
11074+static
027c5e7a
AM
11075+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
11076+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 11077+{
11078+ struct dentry *dentry, *h_parent, *root;
11079+ struct super_block *h_sb;
11080+ char *pathname, *p;
11081+ struct vfsmount *h_mnt;
11082+ struct au_branch *br;
11083+ int err;
11084+ struct path path;
11085+
027c5e7a 11086+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 11087+ h_mnt = au_br_mnt(br);
1facf9fc 11088+ h_sb = h_mnt->mnt_sb;
11089+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
11090+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
11091+ fh_len - Fh_tail, fh[Fh_h_type],
11092+ h_acceptable, /*context*/NULL);
11093+ dentry = h_parent;
11094+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
11095+ AuWarn1("%s decode_fh failed, %ld\n",
11096+ au_sbtype(h_sb), PTR_ERR(h_parent));
11097+ goto out;
11098+ }
11099+ dentry = NULL;
11100+ if (unlikely(au_test_anon(h_parent))) {
11101+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
11102+ au_sbtype(h_sb));
11103+ goto out_h_parent;
11104+ }
11105+
11106+ dentry = ERR_PTR(-ENOMEM);
11107+ pathname = (void *)__get_free_page(GFP_NOFS);
11108+ if (unlikely(!pathname))
11109+ goto out_h_parent;
11110+
11111+ root = sb->s_root;
11112+ path.mnt = h_mnt;
11113+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 11114+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 11115+ di_read_unlock(root, !AuLock_IR);
11116+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
11117+ dentry = (void *)p;
11118+ if (IS_ERR(p))
11119+ goto out_pathname;
11120+
11121+ si_read_unlock(sb);
11122+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
11123+ dentry = ERR_PTR(err);
11124+ if (unlikely(err))
11125+ goto out_relock;
11126+
11127+ dentry = ERR_PTR(-ENOENT);
11128+ AuDebugOn(au_test_anon(path.dentry));
11129+ if (unlikely(!path.dentry->d_inode))
11130+ goto out_path;
11131+
11132+ if (ino != path.dentry->d_inode->i_ino)
11133+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
11134+ else
11135+ dentry = dget(path.dentry);
11136+
4f0767ce 11137+out_path:
1facf9fc 11138+ path_put(&path);
4f0767ce 11139+out_relock:
1facf9fc 11140+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
11141+ if (!IS_ERR(dentry)) {
11142+ dput(dentry);
11143+ dentry = ERR_PTR(-ESTALE);
11144+ }
4f0767ce 11145+out_pathname:
1facf9fc 11146+ free_page((unsigned long)pathname);
4f0767ce 11147+out_h_parent:
1facf9fc 11148+ dput(h_parent);
4f0767ce 11149+out:
1facf9fc 11150+ AuTraceErrPtr(dentry);
11151+ return dentry;
11152+}
11153+
11154+/* ---------------------------------------------------------------------- */
11155+
11156+static struct dentry *
11157+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
11158+ int fh_type)
11159+{
11160+ struct dentry *dentry;
11161+ __u32 *fh = fid->raw;
027c5e7a 11162+ struct au_branch *br;
1facf9fc 11163+ ino_t ino, dir_ino;
1facf9fc 11164+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 11165+ .force_lock = 0
11166+ };
11167+
1facf9fc 11168+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
11169+ /* it should never happen, but the file handle is unreliable */
11170+ if (unlikely(fh_len < Fh_tail))
11171+ goto out;
11172+ nsi_lock.sigen = fh[Fh_sigen];
11173+ nsi_lock.br_id = fh[Fh_br_id];
11174+
1facf9fc 11175+ /* branch id may be wrapped around */
027c5e7a
AM
11176+ br = NULL;
11177+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 11178+ goto out;
11179+ nsi_lock.force_lock = 1;
11180+
11181+ /* is this inode still cached? */
11182+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
11183+ /* it should never happen */
11184+ if (unlikely(ino == AUFS_ROOT_INO))
11185+ goto out;
11186+
1facf9fc 11187+ dir_ino = decode_ino(fh + Fh_dir_ino);
11188+ dentry = decode_by_ino(sb, ino, dir_ino);
11189+ if (IS_ERR(dentry))
11190+ goto out_unlock;
11191+ if (dentry)
11192+ goto accept;
11193+
11194+ /* is the parent dir cached? */
027c5e7a
AM
11195+ br = au_sbr(sb, nsi_lock.bindex);
11196+ atomic_inc(&br->br_count);
1facf9fc 11197+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
11198+ if (IS_ERR(dentry))
11199+ goto out_unlock;
11200+ if (dentry)
11201+ goto accept;
11202+
11203+ /* lookup path */
027c5e7a 11204+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 11205+ if (IS_ERR(dentry))
11206+ goto out_unlock;
11207+ if (unlikely(!dentry))
11208+ /* todo?: make it ESTALE */
11209+ goto out_unlock;
11210+
4f0767ce 11211+accept:
027c5e7a
AM
11212+ if (!au_digen_test(dentry, au_sigen(sb))
11213+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 11214+ goto out_unlock; /* success */
11215+
11216+ dput(dentry);
11217+ dentry = ERR_PTR(-ESTALE);
4f0767ce 11218+out_unlock:
027c5e7a
AM
11219+ if (br)
11220+ atomic_dec(&br->br_count);
1facf9fc 11221+ si_read_unlock(sb);
4f0767ce 11222+out:
1facf9fc 11223+ AuTraceErrPtr(dentry);
11224+ return dentry;
11225+}
11226+
11227+#if 0 /* reserved for future use */
11228+/* support subtreecheck option */
11229+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
11230+ int fh_len, int fh_type)
11231+{
11232+ struct dentry *parent;
11233+ __u32 *fh = fid->raw;
11234+ ino_t dir_ino;
11235+
11236+ dir_ino = decode_ino(fh + Fh_dir_ino);
11237+ parent = decode_by_ino(sb, dir_ino, 0);
11238+ if (IS_ERR(parent))
11239+ goto out;
11240+ if (!parent)
11241+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
11242+ dir_ino, fh, fh_len);
11243+
4f0767ce 11244+out:
1facf9fc 11245+ AuTraceErrPtr(parent);
11246+ return parent;
11247+}
11248+#endif
11249+
11250+/* ---------------------------------------------------------------------- */
11251+
0c3ec466
AM
11252+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
11253+ struct inode *dir)
1facf9fc 11254+{
11255+ int err;
0c3ec466 11256+ aufs_bindex_t bindex;
1facf9fc 11257+ struct super_block *sb, *h_sb;
0c3ec466
AM
11258+ struct dentry *dentry, *parent, *h_parent;
11259+ struct inode *h_dir;
1facf9fc 11260+ struct au_branch *br;
11261+
1facf9fc 11262+ err = -ENOSPC;
11263+ if (unlikely(*max_len <= Fh_tail)) {
11264+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
11265+ goto out;
11266+ }
11267+
11268+ err = FILEID_ROOT;
0c3ec466
AM
11269+ if (inode->i_ino == AUFS_ROOT_INO) {
11270+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 11271+ goto out;
11272+ }
11273+
1facf9fc 11274+ h_parent = NULL;
0c3ec466
AM
11275+ sb = inode->i_sb;
11276+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
11277+ if (unlikely(err))
11278+ goto out;
11279+
1facf9fc 11280+#ifdef CONFIG_AUFS_DEBUG
11281+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
11282+ AuWarn1("NFS-exporting requires xino\n");
11283+#endif
027c5e7a 11284+ err = -EIO;
0c3ec466
AM
11285+ parent = NULL;
11286+ ii_read_lock_child(inode);
11287+ bindex = au_ibstart(inode);
11288+ if (!dir) {
c1595e42 11289+ dentry = d_find_any_alias(inode);
0c3ec466
AM
11290+ if (unlikely(!dentry))
11291+ goto out_unlock;
11292+ AuDebugOn(au_test_anon(dentry));
11293+ parent = dget_parent(dentry);
11294+ dput(dentry);
11295+ if (unlikely(!parent))
11296+ goto out_unlock;
11297+ dir = parent->d_inode;
1facf9fc 11298+ }
0c3ec466
AM
11299+
11300+ ii_read_lock_parent(dir);
11301+ h_dir = au_h_iptr(dir, bindex);
11302+ ii_read_unlock(dir);
11303+ if (unlikely(!h_dir))
11304+ goto out_parent;
c1595e42 11305+ h_parent = d_find_any_alias(h_dir);
1facf9fc 11306+ if (unlikely(!h_parent))
0c3ec466 11307+ goto out_hparent;
1facf9fc 11308+
11309+ err = -EPERM;
11310+ br = au_sbr(sb, bindex);
86dc4139 11311+ h_sb = au_br_sb(br);
1facf9fc 11312+ if (unlikely(!h_sb->s_export_op)) {
11313+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 11314+ goto out_hparent;
1facf9fc 11315+ }
11316+
11317+ fh[Fh_br_id] = br->br_id;
11318+ fh[Fh_sigen] = au_sigen(sb);
11319+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 11320+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 11321+ fh[Fh_igen] = inode->i_generation;
11322+
11323+ *max_len -= Fh_tail;
11324+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
11325+ max_len,
11326+ /*connectable or subtreecheck*/0);
11327+ err = fh[Fh_h_type];
11328+ *max_len += Fh_tail;
11329+ /* todo: macros? */
1716fcea 11330+ if (err != FILEID_INVALID)
1facf9fc 11331+ err = 99;
11332+ else
11333+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
11334+
0c3ec466 11335+out_hparent:
1facf9fc 11336+ dput(h_parent);
0c3ec466 11337+out_parent:
1facf9fc 11338+ dput(parent);
0c3ec466
AM
11339+out_unlock:
11340+ ii_read_unlock(inode);
11341+ si_read_unlock(sb);
4f0767ce 11342+out:
1facf9fc 11343+ if (unlikely(err < 0))
1716fcea 11344+ err = FILEID_INVALID;
1facf9fc 11345+ return err;
11346+}
11347+
11348+/* ---------------------------------------------------------------------- */
11349+
4a4d8108
AM
11350+static int aufs_commit_metadata(struct inode *inode)
11351+{
11352+ int err;
11353+ aufs_bindex_t bindex;
11354+ struct super_block *sb;
11355+ struct inode *h_inode;
11356+ int (*f)(struct inode *inode);
11357+
11358+ sb = inode->i_sb;
e49829fe 11359+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11360+ ii_write_lock_child(inode);
11361+ bindex = au_ibstart(inode);
11362+ AuDebugOn(bindex < 0);
11363+ h_inode = au_h_iptr(inode, bindex);
11364+
11365+ f = h_inode->i_sb->s_export_op->commit_metadata;
11366+ if (f)
11367+ err = f(h_inode);
11368+ else {
11369+ struct writeback_control wbc = {
11370+ .sync_mode = WB_SYNC_ALL,
11371+ .nr_to_write = 0 /* metadata only */
11372+ };
11373+
11374+ err = sync_inode(h_inode, &wbc);
11375+ }
11376+
11377+ au_cpup_attr_timesizes(inode);
11378+ ii_write_unlock(inode);
11379+ si_read_unlock(sb);
11380+ return err;
11381+}
11382+
11383+/* ---------------------------------------------------------------------- */
11384+
1facf9fc 11385+static struct export_operations aufs_export_op = {
4a4d8108 11386+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 11387+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
11388+ .encode_fh = aufs_encode_fh,
11389+ .commit_metadata = aufs_commit_metadata
1facf9fc 11390+};
11391+
11392+void au_export_init(struct super_block *sb)
11393+{
11394+ struct au_sbinfo *sbinfo;
11395+ __u32 u;
11396+
11397+ sb->s_export_op = &aufs_export_op;
11398+ sbinfo = au_sbi(sb);
11399+ sbinfo->si_xigen = NULL;
11400+ get_random_bytes(&u, sizeof(u));
11401+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
11402+ atomic_set(&sbinfo->si_xigen_next, u);
11403+}
076b876e
AM
11404diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
11405--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
2000de60 11406+++ linux/fs/aufs/fhsm.c 2015-03-27 21:56:35.463461668 +0100
c1595e42 11407@@ -0,0 +1,426 @@
076b876e 11408+/*
2000de60 11409+ * Copyright (C) 2011-2015 Junjiro R. Okajima
076b876e
AM
11410+ *
11411+ * This program, aufs is free software; you can redistribute it and/or modify
11412+ * it under the terms of the GNU General Public License as published by
11413+ * the Free Software Foundation; either version 2 of the License, or
11414+ * (at your option) any later version.
11415+ *
11416+ * This program is distributed in the hope that it will be useful,
11417+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11418+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11419+ * GNU General Public License for more details.
11420+ *
11421+ * You should have received a copy of the GNU General Public License
11422+ * along with this program; if not, write to the Free Software
11423+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11424+ */
11425+
11426+/*
11427+ * File-based Hierarchy Storage Management
11428+ */
11429+
11430+#include <linux/anon_inodes.h>
11431+#include <linux/poll.h>
11432+#include <linux/seq_file.h>
11433+#include <linux/statfs.h>
11434+#include "aufs.h"
11435+
c1595e42
JR
11436+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
11437+{
11438+ struct au_sbinfo *sbinfo;
11439+ struct au_fhsm *fhsm;
11440+
11441+ SiMustAnyLock(sb);
11442+
11443+ sbinfo = au_sbi(sb);
11444+ fhsm = &sbinfo->si_fhsm;
11445+ AuDebugOn(!fhsm);
11446+ return fhsm->fhsm_bottom;
11447+}
11448+
11449+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
11450+{
11451+ struct au_sbinfo *sbinfo;
11452+ struct au_fhsm *fhsm;
11453+
11454+ SiMustWriteLock(sb);
11455+
11456+ sbinfo = au_sbi(sb);
11457+ fhsm = &sbinfo->si_fhsm;
11458+ AuDebugOn(!fhsm);
11459+ fhsm->fhsm_bottom = bindex;
11460+}
11461+
11462+/* ---------------------------------------------------------------------- */
11463+
076b876e
AM
11464+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
11465+{
11466+ struct au_br_fhsm *bf;
11467+
11468+ bf = br->br_fhsm;
11469+ MtxMustLock(&bf->bf_lock);
11470+
11471+ return !bf->bf_readable
11472+ || time_after(jiffies,
11473+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
11474+}
11475+
11476+/* ---------------------------------------------------------------------- */
11477+
11478+static void au_fhsm_notify(struct super_block *sb, int val)
11479+{
11480+ struct au_sbinfo *sbinfo;
11481+ struct au_fhsm *fhsm;
11482+
11483+ SiMustAnyLock(sb);
11484+
11485+ sbinfo = au_sbi(sb);
11486+ fhsm = &sbinfo->si_fhsm;
11487+ if (au_fhsm_pid(fhsm)
11488+ && atomic_read(&fhsm->fhsm_readable) != -1) {
11489+ atomic_set(&fhsm->fhsm_readable, val);
11490+ if (val)
11491+ wake_up(&fhsm->fhsm_wqh);
11492+ }
11493+}
11494+
11495+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
11496+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
11497+{
11498+ int err;
11499+ struct au_branch *br;
11500+ struct au_br_fhsm *bf;
11501+
11502+ br = au_sbr(sb, bindex);
11503+ AuDebugOn(au_br_rdonly(br));
11504+ bf = br->br_fhsm;
11505+ AuDebugOn(!bf);
11506+
11507+ if (do_lock)
11508+ mutex_lock(&bf->bf_lock);
11509+ else
11510+ MtxMustLock(&bf->bf_lock);
11511+
11512+ /* sb->s_root for NFS is unreliable */
11513+ err = au_br_stfs(br, &bf->bf_stfs);
11514+ if (unlikely(err)) {
11515+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
11516+ goto out;
11517+ }
11518+
11519+ bf->bf_jiffy = jiffies;
11520+ bf->bf_readable = 1;
11521+ if (do_notify)
11522+ au_fhsm_notify(sb, /*val*/1);
11523+ if (rstfs)
11524+ *rstfs = bf->bf_stfs;
11525+
11526+out:
11527+ if (do_lock)
11528+ mutex_unlock(&bf->bf_lock);
11529+ au_fhsm_notify(sb, /*val*/1);
11530+
11531+ return err;
11532+}
11533+
11534+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
11535+{
11536+ int err;
076b876e
AM
11537+ struct au_sbinfo *sbinfo;
11538+ struct au_fhsm *fhsm;
11539+ struct au_branch *br;
11540+ struct au_br_fhsm *bf;
11541+
11542+ AuDbg("b%d, force %d\n", bindex, force);
11543+ SiMustAnyLock(sb);
11544+
11545+ sbinfo = au_sbi(sb);
11546+ fhsm = &sbinfo->si_fhsm;
c1595e42
JR
11547+ if (!au_ftest_si(sbinfo, FHSM)
11548+ || fhsm->fhsm_bottom == bindex)
076b876e
AM
11549+ return;
11550+
11551+ br = au_sbr(sb, bindex);
11552+ bf = br->br_fhsm;
11553+ AuDebugOn(!bf);
11554+ mutex_lock(&bf->bf_lock);
11555+ if (force
11556+ || au_fhsm_pid(fhsm)
11557+ || au_fhsm_test_jiffy(sbinfo, br))
11558+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
11559+ /*do_notify*/1);
11560+ mutex_unlock(&bf->bf_lock);
11561+}
11562+
11563+void au_fhsm_wrote_all(struct super_block *sb, int force)
11564+{
11565+ aufs_bindex_t bindex, bend;
11566+ struct au_branch *br;
11567+
11568+ /* exclude the bottom */
c1595e42 11569+ bend = au_fhsm_bottom(sb);
076b876e
AM
11570+ for (bindex = 0; bindex < bend; bindex++) {
11571+ br = au_sbr(sb, bindex);
11572+ if (au_br_fhsm(br->br_perm))
11573+ au_fhsm_wrote(sb, bindex, force);
11574+ }
11575+}
11576+
11577+/* ---------------------------------------------------------------------- */
11578+
11579+static unsigned int au_fhsm_poll(struct file *file,
11580+ struct poll_table_struct *wait)
11581+{
11582+ unsigned int mask;
11583+ struct au_sbinfo *sbinfo;
11584+ struct au_fhsm *fhsm;
11585+
11586+ mask = 0;
11587+ sbinfo = file->private_data;
11588+ fhsm = &sbinfo->si_fhsm;
11589+ poll_wait(file, &fhsm->fhsm_wqh, wait);
11590+ if (atomic_read(&fhsm->fhsm_readable))
11591+ mask = POLLIN /* | POLLRDNORM */;
11592+
11593+ AuTraceErr((int)mask);
11594+ return mask;
11595+}
11596+
11597+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
11598+ struct aufs_stfs *stfs, __s16 brid)
11599+{
11600+ int err;
11601+
11602+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
11603+ if (!err)
11604+ err = __put_user(brid, &stbr->brid);
11605+ if (unlikely(err))
11606+ err = -EFAULT;
11607+
11608+ return err;
11609+}
11610+
11611+static ssize_t au_fhsm_do_read(struct super_block *sb,
11612+ struct aufs_stbr __user *stbr, size_t count)
11613+{
11614+ ssize_t err;
11615+ int nstbr;
11616+ aufs_bindex_t bindex, bend;
11617+ struct au_branch *br;
11618+ struct au_br_fhsm *bf;
11619+
11620+ /* except the bottom branch */
11621+ err = 0;
11622+ nstbr = 0;
c1595e42 11623+ bend = au_fhsm_bottom(sb);
076b876e
AM
11624+ for (bindex = 0; !err && bindex < bend; bindex++) {
11625+ br = au_sbr(sb, bindex);
11626+ if (!au_br_fhsm(br->br_perm))
11627+ continue;
11628+
11629+ bf = br->br_fhsm;
11630+ mutex_lock(&bf->bf_lock);
11631+ if (bf->bf_readable) {
11632+ err = -EFAULT;
11633+ if (count >= sizeof(*stbr))
11634+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
11635+ br->br_id);
11636+ if (!err) {
11637+ bf->bf_readable = 0;
11638+ count -= sizeof(*stbr);
11639+ nstbr++;
11640+ }
11641+ }
11642+ mutex_unlock(&bf->bf_lock);
11643+ }
11644+ if (!err)
11645+ err = sizeof(*stbr) * nstbr;
11646+
11647+ return err;
11648+}
11649+
11650+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
11651+ loff_t *pos)
11652+{
11653+ ssize_t err;
11654+ int readable;
11655+ aufs_bindex_t nfhsm, bindex, bend;
11656+ struct au_sbinfo *sbinfo;
11657+ struct au_fhsm *fhsm;
11658+ struct au_branch *br;
11659+ struct super_block *sb;
11660+
11661+ err = 0;
11662+ sbinfo = file->private_data;
11663+ fhsm = &sbinfo->si_fhsm;
11664+need_data:
11665+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
11666+ if (!atomic_read(&fhsm->fhsm_readable)) {
11667+ if (vfsub_file_flags(file) & O_NONBLOCK)
11668+ err = -EAGAIN;
11669+ else
11670+ err = wait_event_interruptible_locked_irq
11671+ (fhsm->fhsm_wqh,
11672+ atomic_read(&fhsm->fhsm_readable));
11673+ }
11674+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
11675+ if (unlikely(err))
11676+ goto out;
11677+
11678+ /* sb may already be dead */
11679+ au_rw_read_lock(&sbinfo->si_rwsem);
11680+ readable = atomic_read(&fhsm->fhsm_readable);
11681+ if (readable > 0) {
11682+ sb = sbinfo->si_sb;
11683+ AuDebugOn(!sb);
11684+ /* exclude the bottom branch */
11685+ nfhsm = 0;
c1595e42 11686+ bend = au_fhsm_bottom(sb);
076b876e
AM
11687+ for (bindex = 0; bindex < bend; bindex++) {
11688+ br = au_sbr(sb, bindex);
11689+ if (au_br_fhsm(br->br_perm))
11690+ nfhsm++;
11691+ }
11692+ err = -EMSGSIZE;
11693+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
11694+ atomic_set(&fhsm->fhsm_readable, 0);
11695+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
11696+ count);
11697+ }
11698+ }
11699+ au_rw_read_unlock(&sbinfo->si_rwsem);
11700+ if (!readable)
11701+ goto need_data;
11702+
11703+out:
11704+ return err;
11705+}
11706+
11707+static int au_fhsm_release(struct inode *inode, struct file *file)
11708+{
11709+ struct au_sbinfo *sbinfo;
11710+ struct au_fhsm *fhsm;
11711+
11712+ /* sb may already be dead */
11713+ sbinfo = file->private_data;
11714+ fhsm = &sbinfo->si_fhsm;
11715+ spin_lock(&fhsm->fhsm_spin);
11716+ fhsm->fhsm_pid = 0;
11717+ spin_unlock(&fhsm->fhsm_spin);
11718+ kobject_put(&sbinfo->si_kobj);
11719+
11720+ return 0;
11721+}
11722+
11723+static const struct file_operations au_fhsm_fops = {
11724+ .owner = THIS_MODULE,
11725+ .llseek = noop_llseek,
11726+ .read = au_fhsm_read,
11727+ .poll = au_fhsm_poll,
11728+ .release = au_fhsm_release
11729+};
11730+
11731+int au_fhsm_fd(struct super_block *sb, int oflags)
11732+{
11733+ int err, fd;
11734+ struct au_sbinfo *sbinfo;
11735+ struct au_fhsm *fhsm;
11736+
11737+ err = -EPERM;
11738+ if (unlikely(!capable(CAP_SYS_ADMIN)))
11739+ goto out;
11740+
11741+ err = -EINVAL;
11742+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
11743+ goto out;
11744+
11745+ err = 0;
11746+ sbinfo = au_sbi(sb);
11747+ fhsm = &sbinfo->si_fhsm;
11748+ spin_lock(&fhsm->fhsm_spin);
11749+ if (!fhsm->fhsm_pid)
11750+ fhsm->fhsm_pid = current->pid;
11751+ else
11752+ err = -EBUSY;
11753+ spin_unlock(&fhsm->fhsm_spin);
11754+ if (unlikely(err))
11755+ goto out;
11756+
11757+ oflags |= O_RDONLY;
11758+ /* oflags |= FMODE_NONOTIFY; */
11759+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
11760+ err = fd;
11761+ if (unlikely(fd < 0))
11762+ goto out_pid;
11763+
11764+ /* succeed reglardless 'fhsm' status */
11765+ kobject_get(&sbinfo->si_kobj);
11766+ si_noflush_read_lock(sb);
11767+ if (au_ftest_si(sbinfo, FHSM))
11768+ au_fhsm_wrote_all(sb, /*force*/0);
11769+ si_read_unlock(sb);
11770+ goto out; /* success */
11771+
11772+out_pid:
11773+ spin_lock(&fhsm->fhsm_spin);
11774+ fhsm->fhsm_pid = 0;
11775+ spin_unlock(&fhsm->fhsm_spin);
11776+out:
11777+ AuTraceErr(err);
11778+ return err;
11779+}
11780+
11781+/* ---------------------------------------------------------------------- */
11782+
11783+int au_fhsm_br_alloc(struct au_branch *br)
11784+{
11785+ int err;
11786+
11787+ err = 0;
11788+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
11789+ if (br->br_fhsm)
11790+ au_br_fhsm_init(br->br_fhsm);
11791+ else
11792+ err = -ENOMEM;
11793+
11794+ return err;
11795+}
11796+
11797+/* ---------------------------------------------------------------------- */
11798+
11799+void au_fhsm_fin(struct super_block *sb)
11800+{
11801+ au_fhsm_notify(sb, /*val*/-1);
11802+}
11803+
11804+void au_fhsm_init(struct au_sbinfo *sbinfo)
11805+{
11806+ struct au_fhsm *fhsm;
11807+
11808+ fhsm = &sbinfo->si_fhsm;
11809+ spin_lock_init(&fhsm->fhsm_spin);
11810+ init_waitqueue_head(&fhsm->fhsm_wqh);
11811+ atomic_set(&fhsm->fhsm_readable, 0);
11812+ fhsm->fhsm_expire
11813+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
c1595e42 11814+ fhsm->fhsm_bottom = -1;
076b876e
AM
11815+}
11816+
11817+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
11818+{
11819+ sbinfo->si_fhsm.fhsm_expire
11820+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
11821+}
11822+
11823+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
11824+{
11825+ unsigned int u;
11826+
11827+ if (!au_ftest_si(sbinfo, FHSM))
11828+ return;
11829+
11830+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
11831+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
11832+ seq_printf(seq, ",fhsm_sec=%u", u);
11833+}
7f207e10
AM
11834diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
11835--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
2000de60 11836+++ linux/fs/aufs/file.c 2015-03-27 21:56:35.463461668 +0100
c1595e42 11837@@ -0,0 +1,829 @@
1facf9fc 11838+/*
2000de60 11839+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 11840+ *
11841+ * This program, aufs is free software; you can redistribute it and/or modify
11842+ * it under the terms of the GNU General Public License as published by
11843+ * the Free Software Foundation; either version 2 of the License, or
11844+ * (at your option) any later version.
dece6358
AM
11845+ *
11846+ * This program is distributed in the hope that it will be useful,
11847+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11848+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11849+ * GNU General Public License for more details.
11850+ *
11851+ * You should have received a copy of the GNU General Public License
523b37e3 11852+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 11853+ */
11854+
11855+/*
4a4d8108 11856+ * handling file/dir, and address_space operation
1facf9fc 11857+ */
11858+
7eafdf33
AM
11859+#ifdef CONFIG_AUFS_DEBUG
11860+#include <linux/migrate.h>
11861+#endif
4a4d8108 11862+#include <linux/pagemap.h>
1facf9fc 11863+#include "aufs.h"
11864+
4a4d8108
AM
11865+/* drop flags for writing */
11866+unsigned int au_file_roflags(unsigned int flags)
11867+{
11868+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
11869+ flags |= O_RDONLY | O_NOATIME;
11870+ return flags;
11871+}
11872+
11873+/* common functions to regular file and dir */
11874+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 11875+ struct file *file, int force_wr)
1facf9fc 11876+{
1308ab2a 11877+ struct file *h_file;
4a4d8108
AM
11878+ struct dentry *h_dentry;
11879+ struct inode *h_inode;
11880+ struct super_block *sb;
11881+ struct au_branch *br;
11882+ struct path h_path;
11883+ int err, exec_flag;
1facf9fc 11884+
4a4d8108
AM
11885+ /* a race condition can happen between open and unlink/rmdir */
11886+ h_file = ERR_PTR(-ENOENT);
11887+ h_dentry = au_h_dptr(dentry, bindex);
b752ccd1 11888+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
11889+ goto out;
11890+ h_inode = h_dentry->d_inode;
b752ccd1 11891+ if (au_test_nfsd() && !h_inode)
4a4d8108 11892+ goto out;
027c5e7a
AM
11893+ spin_lock(&h_dentry->d_lock);
11894+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
11895+ || !h_inode
11896+ /* || !dentry->d_inode->i_nlink */
11897+ ;
11898+ spin_unlock(&h_dentry->d_lock);
11899+ if (unlikely(err))
4a4d8108 11900+ goto out;
1facf9fc 11901+
4a4d8108
AM
11902+ sb = dentry->d_sb;
11903+ br = au_sbr(sb, bindex);
11904+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 11905+ exec_flag = flags & __FMODE_EXEC;
86dc4139 11906+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
027c5e7a 11907+ goto out;
1facf9fc 11908+
4a4d8108 11909+ /* drop flags for writing */
392086de
AM
11910+ if (au_test_ro(sb, bindex, dentry->d_inode)) {
11911+ if (force_wr && !(flags & O_WRONLY))
11912+ force_wr = 0;
4a4d8108 11913+ flags = au_file_roflags(flags);
392086de
AM
11914+ if (force_wr) {
11915+ h_file = ERR_PTR(-EROFS);
11916+ flags = au_file_roflags(flags);
11917+ if (unlikely(vfsub_native_ro(h_inode)
11918+ || IS_APPEND(h_inode)))
11919+ goto out;
11920+ flags &= ~O_ACCMODE;
11921+ flags |= O_WRONLY;
11922+ }
11923+ }
4a4d8108
AM
11924+ flags &= ~O_CREAT;
11925+ atomic_inc(&br->br_count);
11926+ h_path.dentry = h_dentry;
86dc4139 11927+ h_path.mnt = au_br_mnt(br);
38d290e6 11928+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
11929+ if (IS_ERR(h_file))
11930+ goto out_br;
dece6358 11931+
4a4d8108
AM
11932+ if (exec_flag) {
11933+ err = deny_write_access(h_file);
11934+ if (unlikely(err)) {
11935+ fput(h_file);
11936+ h_file = ERR_PTR(err);
11937+ goto out_br;
11938+ }
11939+ }
953406b4 11940+ fsnotify_open(h_file);
4a4d8108 11941+ goto out; /* success */
1facf9fc 11942+
4f0767ce 11943+out_br:
4a4d8108 11944+ atomic_dec(&br->br_count);
4f0767ce 11945+out:
4a4d8108
AM
11946+ return h_file;
11947+}
1308ab2a 11948+
076b876e
AM
11949+static int au_cmoo(struct dentry *dentry)
11950+{
11951+ int err, cmoo;
11952+ unsigned int udba;
11953+ struct path h_path;
11954+ struct au_pin pin;
11955+ struct au_cp_generic cpg = {
11956+ .dentry = dentry,
11957+ .bdst = -1,
11958+ .bsrc = -1,
11959+ .len = -1,
11960+ .pin = &pin,
11961+ .flags = AuCpup_DTIME | AuCpup_HOPEN
11962+ };
11963+ struct inode *inode, *delegated;
11964+ struct super_block *sb;
11965+ struct au_sbinfo *sbinfo;
11966+ struct au_fhsm *fhsm;
11967+ pid_t pid;
11968+ struct au_branch *br;
11969+ struct dentry *parent;
11970+ struct au_hinode *hdir;
11971+
11972+ DiMustWriteLock(dentry);
11973+ inode = dentry->d_inode;
11974+ IiMustWriteLock(inode);
11975+
11976+ err = 0;
11977+ if (IS_ROOT(dentry))
11978+ goto out;
11979+ cpg.bsrc = au_dbstart(dentry);
11980+ if (!cpg.bsrc)
11981+ goto out;
11982+
11983+ sb = dentry->d_sb;
11984+ sbinfo = au_sbi(sb);
11985+ fhsm = &sbinfo->si_fhsm;
11986+ pid = au_fhsm_pid(fhsm);
11987+ if (pid
11988+ && (current->pid == pid
11989+ || current->real_parent->pid == pid))
11990+ goto out;
11991+
11992+ br = au_sbr(sb, cpg.bsrc);
11993+ cmoo = au_br_cmoo(br->br_perm);
11994+ if (!cmoo)
11995+ goto out;
11996+ if (!S_ISREG(inode->i_mode))
11997+ cmoo &= AuBrAttr_COO_ALL;
11998+ if (!cmoo)
11999+ goto out;
12000+
12001+ parent = dget_parent(dentry);
12002+ di_write_lock_parent(parent);
12003+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
12004+ cpg.bdst = err;
12005+ if (unlikely(err < 0)) {
12006+ err = 0; /* there is no upper writable branch */
12007+ goto out_dgrade;
12008+ }
12009+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
12010+
12011+ /* do not respect the coo attrib for the target branch */
12012+ err = au_cpup_dirs(dentry, cpg.bdst);
12013+ if (unlikely(err))
12014+ goto out_dgrade;
12015+
12016+ di_downgrade_lock(parent, AuLock_IR);
12017+ udba = au_opt_udba(sb);
12018+ err = au_pin(&pin, dentry, cpg.bdst, udba,
12019+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12020+ if (unlikely(err))
12021+ goto out_parent;
12022+
12023+ err = au_sio_cpup_simple(&cpg);
12024+ au_unpin(&pin);
12025+ if (unlikely(err))
12026+ goto out_parent;
12027+ if (!(cmoo & AuBrWAttr_MOO))
12028+ goto out_parent; /* success */
12029+
12030+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
12031+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12032+ if (unlikely(err))
12033+ goto out_parent;
12034+
12035+ h_path.mnt = au_br_mnt(br);
12036+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
12037+ hdir = au_hi(parent->d_inode, cpg.bsrc);
12038+ delegated = NULL;
12039+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
12040+ au_unpin(&pin);
12041+ /* todo: keep h_dentry or not? */
12042+ if (unlikely(err == -EWOULDBLOCK)) {
12043+ pr_warn("cannot retry for NFSv4 delegation"
12044+ " for an internal unlink\n");
12045+ iput(delegated);
12046+ }
12047+ if (unlikely(err)) {
12048+ pr_err("unlink %pd after coo failed (%d), ignored\n",
12049+ dentry, err);
12050+ err = 0;
12051+ }
12052+ goto out_parent; /* success */
12053+
12054+out_dgrade:
12055+ di_downgrade_lock(parent, AuLock_IR);
12056+out_parent:
12057+ di_read_unlock(parent, AuLock_IR);
12058+ dput(parent);
12059+out:
12060+ AuTraceErr(err);
12061+ return err;
12062+}
12063+
4a4d8108
AM
12064+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
12065+ struct au_fidir *fidir)
1facf9fc 12066+{
dece6358 12067+ int err;
1facf9fc 12068+ struct dentry *dentry;
076b876e 12069+ struct au_finfo *finfo;
1308ab2a 12070+
4a4d8108
AM
12071+ err = au_finfo_init(file, fidir);
12072+ if (unlikely(err))
12073+ goto out;
1facf9fc 12074+
2000de60 12075+ dentry = file->f_path.dentry;
076b876e
AM
12076+ di_write_lock_child(dentry);
12077+ err = au_cmoo(dentry);
12078+ di_downgrade_lock(dentry, AuLock_IR);
12079+ if (!err)
12080+ err = open(file, vfsub_file_flags(file));
4a4d8108 12081+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 12082+
076b876e
AM
12083+ finfo = au_fi(file);
12084+ if (!err) {
12085+ finfo->fi_file = file;
12086+ au_sphl_add(&finfo->fi_hlist,
2000de60 12087+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
076b876e 12088+ }
4a4d8108
AM
12089+ fi_write_unlock(file);
12090+ if (unlikely(err)) {
076b876e 12091+ finfo->fi_hdir = NULL;
4a4d8108 12092+ au_finfo_fin(file);
1308ab2a 12093+ }
4a4d8108 12094+
4f0767ce 12095+out:
1308ab2a 12096+ return err;
12097+}
dece6358 12098+
4a4d8108 12099+int au_reopen_nondir(struct file *file)
1308ab2a 12100+{
4a4d8108
AM
12101+ int err;
12102+ aufs_bindex_t bstart;
12103+ struct dentry *dentry;
12104+ struct file *h_file, *h_file_tmp;
1308ab2a 12105+
2000de60 12106+ dentry = file->f_path.dentry;
4a4d8108
AM
12107+ bstart = au_dbstart(dentry);
12108+ h_file_tmp = NULL;
12109+ if (au_fbstart(file) == bstart) {
12110+ h_file = au_hf_top(file);
12111+ if (file->f_mode == h_file->f_mode)
12112+ return 0; /* success */
12113+ h_file_tmp = h_file;
12114+ get_file(h_file_tmp);
12115+ au_set_h_fptr(file, bstart, NULL);
12116+ }
12117+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
12118+ /*
12119+ * it can happen
12120+ * file exists on both of rw and ro
12121+ * open --> dbstart and fbstart are both 0
12122+ * prepend a branch as rw, "rw" become ro
12123+ * remove rw/file
12124+ * delete the top branch, "rw" becomes rw again
12125+ * --> dbstart is 1, fbstart is still 0
12126+ * write --> fbstart is 0 but dbstart is 1
12127+ */
12128+ /* AuDebugOn(au_fbstart(file) < bstart); */
1308ab2a 12129+
4a4d8108 12130+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
392086de 12131+ file, /*force_wr*/0);
4a4d8108 12132+ err = PTR_ERR(h_file);
86dc4139
AM
12133+ if (IS_ERR(h_file)) {
12134+ if (h_file_tmp) {
12135+ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
12136+ au_set_h_fptr(file, bstart, h_file_tmp);
12137+ h_file_tmp = NULL;
12138+ }
4a4d8108 12139+ goto out; /* todo: close all? */
86dc4139 12140+ }
4a4d8108
AM
12141+
12142+ err = 0;
12143+ au_set_fbstart(file, bstart);
12144+ au_set_h_fptr(file, bstart, h_file);
12145+ au_update_figen(file);
12146+ /* todo: necessary? */
12147+ /* file->f_ra = h_file->f_ra; */
12148+
4f0767ce 12149+out:
4a4d8108
AM
12150+ if (h_file_tmp)
12151+ fput(h_file_tmp);
12152+ return err;
1facf9fc 12153+}
12154+
1308ab2a 12155+/* ---------------------------------------------------------------------- */
12156+
4a4d8108
AM
12157+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
12158+ struct dentry *hi_wh)
1facf9fc 12159+{
4a4d8108
AM
12160+ int err;
12161+ aufs_bindex_t bstart;
12162+ struct au_dinfo *dinfo;
12163+ struct dentry *h_dentry;
12164+ struct au_hdentry *hdp;
1facf9fc 12165+
2000de60 12166+ dinfo = au_di(file->f_path.dentry);
4a4d8108 12167+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 12168+
4a4d8108
AM
12169+ bstart = dinfo->di_bstart;
12170+ dinfo->di_bstart = btgt;
12171+ hdp = dinfo->di_hdentry;
12172+ h_dentry = hdp[0 + btgt].hd_dentry;
12173+ hdp[0 + btgt].hd_dentry = hi_wh;
12174+ err = au_reopen_nondir(file);
12175+ hdp[0 + btgt].hd_dentry = h_dentry;
12176+ dinfo->di_bstart = bstart;
1facf9fc 12177+
1facf9fc 12178+ return err;
12179+}
12180+
4a4d8108 12181+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 12182+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 12183+{
4a4d8108 12184+ int err;
027c5e7a 12185+ struct inode *inode, *h_inode;
c2b27bf2
AM
12186+ struct dentry *h_dentry, *hi_wh;
12187+ struct au_cp_generic cpg = {
2000de60 12188+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12189+ .bdst = bcpup,
12190+ .bsrc = -1,
12191+ .len = len,
12192+ .pin = pin
12193+ };
1facf9fc 12194+
c2b27bf2
AM
12195+ au_update_dbstart(cpg.dentry);
12196+ inode = cpg.dentry->d_inode;
027c5e7a 12197+ h_inode = NULL;
c2b27bf2
AM
12198+ if (au_dbstart(cpg.dentry) <= bcpup
12199+ && au_dbend(cpg.dentry) >= bcpup) {
12200+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
027c5e7a
AM
12201+ if (h_dentry)
12202+ h_inode = h_dentry->d_inode;
12203+ }
4a4d8108 12204+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 12205+ if (!hi_wh && !h_inode)
c2b27bf2 12206+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
12207+ else
12208+ /* already copied-up after unlink */
12209+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 12210+
4a4d8108 12211+ if (!err
38d290e6
JR
12212+ && (inode->i_nlink > 1
12213+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
12214+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
12215+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 12216+
dece6358 12217+ return err;
1facf9fc 12218+}
12219+
4a4d8108
AM
12220+/*
12221+ * prepare the @file for writing.
12222+ */
12223+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 12224+{
4a4d8108 12225+ int err;
c2b27bf2 12226+ aufs_bindex_t dbstart;
c1595e42 12227+ struct dentry *parent;
86dc4139 12228+ struct inode *inode;
1facf9fc 12229+ struct super_block *sb;
4a4d8108 12230+ struct file *h_file;
c2b27bf2 12231+ struct au_cp_generic cpg = {
2000de60 12232+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12233+ .bdst = -1,
12234+ .bsrc = -1,
12235+ .len = len,
12236+ .pin = pin,
12237+ .flags = AuCpup_DTIME
12238+ };
1facf9fc 12239+
c2b27bf2
AM
12240+ sb = cpg.dentry->d_sb;
12241+ inode = cpg.dentry->d_inode;
c2b27bf2
AM
12242+ cpg.bsrc = au_fbstart(file);
12243+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 12244+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
12245+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
12246+ /*flags*/0);
1facf9fc 12247+ goto out;
4a4d8108 12248+ }
1facf9fc 12249+
027c5e7a 12250+ /* need to cpup or reopen */
c2b27bf2 12251+ parent = dget_parent(cpg.dentry);
4a4d8108 12252+ di_write_lock_parent(parent);
c2b27bf2
AM
12253+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12254+ cpg.bdst = err;
4a4d8108
AM
12255+ if (unlikely(err < 0))
12256+ goto out_dgrade;
12257+ err = 0;
12258+
c2b27bf2
AM
12259+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
12260+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 12261+ if (unlikely(err))
4a4d8108
AM
12262+ goto out_dgrade;
12263+ }
12264+
c2b27bf2 12265+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
12266+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12267+ if (unlikely(err))
12268+ goto out_dgrade;
12269+
c2b27bf2 12270+ dbstart = au_dbstart(cpg.dentry);
c1595e42 12271+ if (dbstart <= cpg.bdst)
c2b27bf2 12272+ cpg.bsrc = cpg.bdst;
027c5e7a 12273+
c2b27bf2
AM
12274+ if (dbstart <= cpg.bdst /* just reopen */
12275+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 12276+ ) {
392086de 12277+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 12278+ if (IS_ERR(h_file))
027c5e7a 12279+ err = PTR_ERR(h_file);
86dc4139 12280+ else {
027c5e7a 12281+ di_downgrade_lock(parent, AuLock_IR);
c2b27bf2
AM
12282+ if (dbstart > cpg.bdst)
12283+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
12284+ if (!err)
12285+ err = au_reopen_nondir(file);
c2b27bf2 12286+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 12287+ }
027c5e7a
AM
12288+ } else { /* copyup as wh and reopen */
12289+ /*
12290+ * since writable hfsplus branch is not supported,
12291+ * h_open_pre/post() are unnecessary.
12292+ */
c2b27bf2 12293+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 12294+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 12295+ }
4a4d8108
AM
12296+
12297+ if (!err) {
12298+ au_pin_set_parent_lflag(pin, /*lflag*/0);
12299+ goto out_dput; /* success */
12300+ }
12301+ au_unpin(pin);
12302+ goto out_unlock;
1facf9fc 12303+
4f0767ce 12304+out_dgrade:
4a4d8108 12305+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 12306+out_unlock:
4a4d8108 12307+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12308+out_dput:
4a4d8108 12309+ dput(parent);
4f0767ce 12310+out:
1facf9fc 12311+ return err;
12312+}
12313+
4a4d8108
AM
12314+/* ---------------------------------------------------------------------- */
12315+
12316+int au_do_flush(struct file *file, fl_owner_t id,
12317+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 12318+{
4a4d8108 12319+ int err;
1facf9fc 12320+ struct super_block *sb;
4a4d8108 12321+ struct inode *inode;
1facf9fc 12322+
c06a8ce3
AM
12323+ inode = file_inode(file);
12324+ sb = inode->i_sb;
4a4d8108
AM
12325+ si_noflush_read_lock(sb);
12326+ fi_read_lock(file);
b752ccd1 12327+ ii_read_lock_child(inode);
1facf9fc 12328+
4a4d8108
AM
12329+ err = flush(file, id);
12330+ au_cpup_attr_timesizes(inode);
1facf9fc 12331+
b752ccd1 12332+ ii_read_unlock(inode);
4a4d8108 12333+ fi_read_unlock(file);
1308ab2a 12334+ si_read_unlock(sb);
dece6358 12335+ return err;
1facf9fc 12336+}
12337+
4a4d8108
AM
12338+/* ---------------------------------------------------------------------- */
12339+
12340+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 12341+{
4a4d8108 12342+ int err;
4a4d8108
AM
12343+ struct au_pin pin;
12344+ struct au_finfo *finfo;
c2b27bf2 12345+ struct dentry *parent, *hi_wh;
4a4d8108 12346+ struct inode *inode;
1facf9fc 12347+ struct super_block *sb;
c2b27bf2 12348+ struct au_cp_generic cpg = {
2000de60 12349+ .dentry = file->f_path.dentry,
c2b27bf2
AM
12350+ .bdst = -1,
12351+ .bsrc = -1,
12352+ .len = -1,
12353+ .pin = &pin,
12354+ .flags = AuCpup_DTIME
12355+ };
1facf9fc 12356+
4a4d8108
AM
12357+ FiMustWriteLock(file);
12358+
12359+ err = 0;
12360+ finfo = au_fi(file);
c2b27bf2
AM
12361+ sb = cpg.dentry->d_sb;
12362+ inode = cpg.dentry->d_inode;
12363+ cpg.bdst = au_ibstart(inode);
12364+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 12365+ goto out;
dece6358 12366+
c2b27bf2
AM
12367+ parent = dget_parent(cpg.dentry);
12368+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 12369+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
12370+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12371+ cpg.bdst = err;
4a4d8108
AM
12372+ di_read_unlock(parent, !AuLock_IR);
12373+ if (unlikely(err < 0))
12374+ goto out_parent;
12375+ err = 0;
1facf9fc 12376+ }
1facf9fc 12377+
4a4d8108 12378+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 12379+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
12380+ if (!S_ISDIR(inode->i_mode)
12381+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 12382+ && au_plink_test(inode)
c2b27bf2
AM
12383+ && !d_unhashed(cpg.dentry)
12384+ && cpg.bdst < au_dbstart(cpg.dentry)) {
12385+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
12386+ if (unlikely(err))
12387+ goto out_unlock;
12388+
12389+ /* always superio. */
c2b27bf2 12390+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 12391+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 12392+ if (!err) {
c2b27bf2 12393+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
12394+ au_unpin(&pin);
12395+ }
4a4d8108
AM
12396+ } else if (hi_wh) {
12397+ /* already copied-up after unlink */
c2b27bf2 12398+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
12399+ *need_reopen = 0;
12400+ }
1facf9fc 12401+
4f0767ce 12402+out_unlock:
4a4d8108 12403+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12404+out_parent:
4a4d8108 12405+ dput(parent);
4f0767ce 12406+out:
1308ab2a 12407+ return err;
dece6358 12408+}
1facf9fc 12409+
4a4d8108 12410+static void au_do_refresh_dir(struct file *file)
dece6358 12411+{
4a4d8108
AM
12412+ aufs_bindex_t bindex, bend, new_bindex, brid;
12413+ struct au_hfile *p, tmp, *q;
12414+ struct au_finfo *finfo;
1308ab2a 12415+ struct super_block *sb;
4a4d8108 12416+ struct au_fidir *fidir;
1facf9fc 12417+
4a4d8108 12418+ FiMustWriteLock(file);
1facf9fc 12419+
2000de60 12420+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
12421+ finfo = au_fi(file);
12422+ fidir = finfo->fi_hdir;
12423+ AuDebugOn(!fidir);
12424+ p = fidir->fd_hfile + finfo->fi_btop;
12425+ brid = p->hf_br->br_id;
12426+ bend = fidir->fd_bbot;
12427+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
12428+ if (!p->hf_file)
12429+ continue;
1308ab2a 12430+
4a4d8108
AM
12431+ new_bindex = au_br_index(sb, p->hf_br->br_id);
12432+ if (new_bindex == bindex)
12433+ continue;
12434+ if (new_bindex < 0) {
12435+ au_set_h_fptr(file, bindex, NULL);
12436+ continue;
12437+ }
1308ab2a 12438+
4a4d8108
AM
12439+ /* swap two lower inode, and loop again */
12440+ q = fidir->fd_hfile + new_bindex;
12441+ tmp = *q;
12442+ *q = *p;
12443+ *p = tmp;
12444+ if (tmp.hf_file) {
12445+ bindex--;
12446+ p--;
12447+ }
12448+ }
1308ab2a 12449+
4a4d8108 12450+ p = fidir->fd_hfile;
2000de60 12451+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
4a4d8108
AM
12452+ bend = au_sbend(sb);
12453+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
12454+ finfo->fi_btop++, p++)
12455+ if (p->hf_file) {
c06a8ce3 12456+ if (file_inode(p->hf_file))
4a4d8108 12457+ break;
c1595e42 12458+ au_hfput(p, file);
4a4d8108
AM
12459+ }
12460+ } else {
12461+ bend = au_br_index(sb, brid);
12462+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
12463+ finfo->fi_btop++, p++)
12464+ if (p->hf_file)
12465+ au_hfput(p, file);
12466+ bend = au_sbend(sb);
12467+ }
1308ab2a 12468+
4a4d8108
AM
12469+ p = fidir->fd_hfile + bend;
12470+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
12471+ fidir->fd_bbot--, p--)
12472+ if (p->hf_file) {
c06a8ce3 12473+ if (file_inode(p->hf_file))
4a4d8108 12474+ break;
c1595e42 12475+ au_hfput(p, file);
4a4d8108
AM
12476+ }
12477+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 12478+}
12479+
4a4d8108
AM
12480+/*
12481+ * after branch manipulating, refresh the file.
12482+ */
12483+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 12484+{
4a4d8108
AM
12485+ int err, need_reopen;
12486+ aufs_bindex_t bend, bindex;
12487+ struct dentry *dentry;
1308ab2a 12488+ struct au_finfo *finfo;
4a4d8108 12489+ struct au_hfile *hfile;
1facf9fc 12490+
2000de60 12491+ dentry = file->f_path.dentry;
1308ab2a 12492+ finfo = au_fi(file);
4a4d8108
AM
12493+ if (!finfo->fi_hdir) {
12494+ hfile = &finfo->fi_htop;
12495+ AuDebugOn(!hfile->hf_file);
12496+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
12497+ AuDebugOn(bindex < 0);
12498+ if (bindex != finfo->fi_btop)
12499+ au_set_fbstart(file, bindex);
12500+ } else {
12501+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
12502+ if (unlikely(err))
12503+ goto out;
12504+ au_do_refresh_dir(file);
12505+ }
1facf9fc 12506+
4a4d8108
AM
12507+ err = 0;
12508+ need_reopen = 1;
12509+ if (!au_test_mmapped(file))
12510+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 12511+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
12512+ err = reopen(file);
12513+ if (!err) {
12514+ au_update_figen(file);
12515+ goto out; /* success */
12516+ }
12517+
12518+ /* error, close all lower files */
12519+ if (finfo->fi_hdir) {
12520+ bend = au_fbend_dir(file);
12521+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
12522+ au_set_h_fptr(file, bindex, NULL);
12523+ }
1facf9fc 12524+
4f0767ce 12525+out:
1facf9fc 12526+ return err;
12527+}
12528+
4a4d8108
AM
12529+/* common function to regular file and dir */
12530+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12531+ int wlock)
dece6358 12532+{
1308ab2a 12533+ int err;
4a4d8108
AM
12534+ unsigned int sigen, figen;
12535+ aufs_bindex_t bstart;
12536+ unsigned char pseudo_link;
12537+ struct dentry *dentry;
12538+ struct inode *inode;
1facf9fc 12539+
4a4d8108 12540+ err = 0;
2000de60 12541+ dentry = file->f_path.dentry;
4a4d8108 12542+ inode = dentry->d_inode;
4a4d8108
AM
12543+ sigen = au_sigen(dentry->d_sb);
12544+ fi_write_lock(file);
12545+ figen = au_figen(file);
12546+ di_write_lock_child(dentry);
12547+ bstart = au_dbstart(dentry);
12548+ pseudo_link = (bstart != au_ibstart(inode));
12549+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
12550+ if (!wlock) {
12551+ di_downgrade_lock(dentry, AuLock_IR);
12552+ fi_downgrade_lock(file);
12553+ }
12554+ goto out; /* success */
12555+ }
dece6358 12556+
4a4d8108 12557+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 12558+ if (au_digen_test(dentry, sigen)) {
4a4d8108 12559+ err = au_reval_dpath(dentry, sigen);
027c5e7a 12560+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 12561+ }
dece6358 12562+
027c5e7a
AM
12563+ if (!err)
12564+ err = refresh_file(file, reopen);
4a4d8108
AM
12565+ if (!err) {
12566+ if (!wlock) {
12567+ di_downgrade_lock(dentry, AuLock_IR);
12568+ fi_downgrade_lock(file);
12569+ }
12570+ } else {
12571+ di_write_unlock(dentry);
12572+ fi_write_unlock(file);
12573+ }
1facf9fc 12574+
4f0767ce 12575+out:
1308ab2a 12576+ return err;
12577+}
1facf9fc 12578+
4a4d8108
AM
12579+/* ---------------------------------------------------------------------- */
12580+
12581+/* cf. aufs_nopage() */
12582+/* for madvise(2) */
12583+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 12584+{
4a4d8108
AM
12585+ unlock_page(page);
12586+ return 0;
12587+}
1facf9fc 12588+
4a4d8108
AM
12589+/* it will never be called, but necessary to support O_DIRECT */
12590+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
076b876e 12591+ struct iov_iter *iter, loff_t offset)
4a4d8108 12592+{ BUG(); return 0; }
1facf9fc 12593+
4a4d8108
AM
12594+/*
12595+ * it will never be called, but madvise and fadvise behaves differently
12596+ * when get_xip_mem is defined
12597+ */
12598+static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
12599+ int create, void **kmem, unsigned long *pfn)
12600+{ BUG(); return 0; }
1facf9fc 12601+
4a4d8108
AM
12602+/* they will never be called. */
12603+#ifdef CONFIG_AUFS_DEBUG
12604+static int aufs_write_begin(struct file *file, struct address_space *mapping,
12605+ loff_t pos, unsigned len, unsigned flags,
12606+ struct page **pagep, void **fsdata)
12607+{ AuUnsupport(); return 0; }
12608+static int aufs_write_end(struct file *file, struct address_space *mapping,
12609+ loff_t pos, unsigned len, unsigned copied,
12610+ struct page *page, void *fsdata)
12611+{ AuUnsupport(); return 0; }
12612+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
12613+{ AuUnsupport(); return 0; }
1308ab2a 12614+
4a4d8108
AM
12615+static int aufs_set_page_dirty(struct page *page)
12616+{ AuUnsupport(); return 0; }
392086de
AM
12617+static void aufs_invalidatepage(struct page *page, unsigned int offset,
12618+ unsigned int length)
4a4d8108
AM
12619+{ AuUnsupport(); }
12620+static int aufs_releasepage(struct page *page, gfp_t gfp)
12621+{ AuUnsupport(); return 0; }
12622+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 12623+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
12624+{ AuUnsupport(); return 0; }
12625+static int aufs_launder_page(struct page *page)
12626+{ AuUnsupport(); return 0; }
12627+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
12628+ unsigned long from,
12629+ unsigned long count)
4a4d8108 12630+{ AuUnsupport(); return 0; }
392086de
AM
12631+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
12632+ bool *writeback)
12633+{ AuUnsupport(); }
4a4d8108
AM
12634+static int aufs_error_remove_page(struct address_space *mapping,
12635+ struct page *page)
12636+{ AuUnsupport(); return 0; }
b4510431
AM
12637+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
12638+ sector_t *span)
12639+{ AuUnsupport(); return 0; }
12640+static void aufs_swap_deactivate(struct file *file)
12641+{ AuUnsupport(); }
4a4d8108
AM
12642+#endif /* CONFIG_AUFS_DEBUG */
12643+
12644+const struct address_space_operations aufs_aop = {
12645+ .readpage = aufs_readpage,
12646+ .direct_IO = aufs_direct_IO,
12647+ .get_xip_mem = aufs_get_xip_mem,
12648+#ifdef CONFIG_AUFS_DEBUG
12649+ .writepage = aufs_writepage,
4a4d8108
AM
12650+ /* no writepages, because of writepage */
12651+ .set_page_dirty = aufs_set_page_dirty,
12652+ /* no readpages, because of readpage */
12653+ .write_begin = aufs_write_begin,
12654+ .write_end = aufs_write_end,
12655+ /* no bmap, no block device */
12656+ .invalidatepage = aufs_invalidatepage,
12657+ .releasepage = aufs_releasepage,
12658+ .migratepage = aufs_migratepage,
12659+ .launder_page = aufs_launder_page,
12660+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 12661+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
12662+ .error_remove_page = aufs_error_remove_page,
12663+ .swap_activate = aufs_swap_activate,
12664+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 12665+#endif /* CONFIG_AUFS_DEBUG */
dece6358 12666+};
7f207e10
AM
12667diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
12668--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
2000de60 12669+++ linux/fs/aufs/file.h 2015-03-27 21:56:35.463461668 +0100
c1595e42 12670@@ -0,0 +1,284 @@
4a4d8108 12671+/*
2000de60 12672+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
12673+ *
12674+ * This program, aufs is free software; you can redistribute it and/or modify
12675+ * it under the terms of the GNU General Public License as published by
12676+ * the Free Software Foundation; either version 2 of the License, or
12677+ * (at your option) any later version.
12678+ *
12679+ * This program is distributed in the hope that it will be useful,
12680+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12681+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12682+ * GNU General Public License for more details.
12683+ *
12684+ * You should have received a copy of the GNU General Public License
523b37e3 12685+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12686+ */
1facf9fc 12687+
4a4d8108
AM
12688+/*
12689+ * file operations
12690+ */
1facf9fc 12691+
4a4d8108
AM
12692+#ifndef __AUFS_FILE_H__
12693+#define __AUFS_FILE_H__
1facf9fc 12694+
4a4d8108 12695+#ifdef __KERNEL__
1facf9fc 12696+
2cbb1c4b 12697+#include <linux/file.h>
4a4d8108
AM
12698+#include <linux/fs.h>
12699+#include <linux/poll.h>
4a4d8108 12700+#include "rwsem.h"
1facf9fc 12701+
4a4d8108
AM
12702+struct au_branch;
12703+struct au_hfile {
12704+ struct file *hf_file;
12705+ struct au_branch *hf_br;
12706+};
1facf9fc 12707+
4a4d8108
AM
12708+struct au_vdir;
12709+struct au_fidir {
12710+ aufs_bindex_t fd_bbot;
12711+ aufs_bindex_t fd_nent;
12712+ struct au_vdir *fd_vdir_cache;
12713+ struct au_hfile fd_hfile[];
12714+};
1facf9fc 12715+
4a4d8108 12716+static inline int au_fidir_sz(int nent)
dece6358 12717+{
4f0767ce
JR
12718+ AuDebugOn(nent < 0);
12719+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 12720+}
1facf9fc 12721+
4a4d8108
AM
12722+struct au_finfo {
12723+ atomic_t fi_generation;
dece6358 12724+
4a4d8108
AM
12725+ struct au_rwsem fi_rwsem;
12726+ aufs_bindex_t fi_btop;
12727+
12728+ /* do not union them */
12729+ struct { /* for non-dir */
12730+ struct au_hfile fi_htop;
2cbb1c4b 12731+ atomic_t fi_mmapped;
4a4d8108
AM
12732+ };
12733+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3
AM
12734+
12735+ struct hlist_node fi_hlist;
12736+ struct file *fi_file; /* very ugly */
4a4d8108 12737+} ____cacheline_aligned_in_smp;
1facf9fc 12738+
4a4d8108 12739+/* ---------------------------------------------------------------------- */
1facf9fc 12740+
4a4d8108
AM
12741+/* file.c */
12742+extern const struct address_space_operations aufs_aop;
12743+unsigned int au_file_roflags(unsigned int flags);
12744+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 12745+ struct file *file, int force_wr);
4a4d8108
AM
12746+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
12747+ struct au_fidir *fidir);
12748+int au_reopen_nondir(struct file *file);
12749+struct au_pin;
12750+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
12751+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12752+ int wlock);
12753+int au_do_flush(struct file *file, fl_owner_t id,
12754+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 12755+
4a4d8108
AM
12756+/* poll.c */
12757+#ifdef CONFIG_AUFS_POLL
12758+unsigned int aufs_poll(struct file *file, poll_table *wait);
12759+#endif
1facf9fc 12760+
4a4d8108
AM
12761+#ifdef CONFIG_AUFS_BR_HFSPLUS
12762+/* hfsplus.c */
392086de
AM
12763+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
12764+ int force_wr);
4a4d8108
AM
12765+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
12766+ struct file *h_file);
12767+#else
c1595e42
JR
12768+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
12769+ aufs_bindex_t bindex, int force_wr)
4a4d8108
AM
12770+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
12771+ struct file *h_file);
12772+#endif
1facf9fc 12773+
4a4d8108
AM
12774+/* f_op.c */
12775+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
12776+int au_do_open_nondir(struct file *file, int flags);
12777+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
12778+
4a4d8108
AM
12779+/* finfo.c */
12780+void au_hfput(struct au_hfile *hf, struct file *file);
12781+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
12782+ struct file *h_file);
1facf9fc 12783+
4a4d8108 12784+void au_update_figen(struct file *file);
4a4d8108
AM
12785+struct au_fidir *au_fidir_alloc(struct super_block *sb);
12786+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 12787+
4a4d8108
AM
12788+void au_fi_init_once(void *_fi);
12789+void au_finfo_fin(struct file *file);
12790+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 12791+
4a4d8108
AM
12792+/* ioctl.c */
12793+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
12794+#ifdef CONFIG_COMPAT
12795+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
12796+ unsigned long arg);
c2b27bf2
AM
12797+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
12798+ unsigned long arg);
b752ccd1 12799+#endif
1facf9fc 12800+
4a4d8108 12801+/* ---------------------------------------------------------------------- */
1facf9fc 12802+
4a4d8108
AM
12803+static inline struct au_finfo *au_fi(struct file *file)
12804+{
38d290e6 12805+ return file->private_data;
4a4d8108 12806+}
1facf9fc 12807+
4a4d8108 12808+/* ---------------------------------------------------------------------- */
1facf9fc 12809+
4a4d8108
AM
12810+/*
12811+ * fi_read_lock, fi_write_lock,
12812+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
12813+ */
12814+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 12815+
4a4d8108
AM
12816+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
12817+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
12818+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 12819+
1308ab2a 12820+/* ---------------------------------------------------------------------- */
12821+
4a4d8108
AM
12822+/* todo: hard/soft set? */
12823+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 12824+{
4a4d8108
AM
12825+ FiMustAnyLock(file);
12826+ return au_fi(file)->fi_btop;
12827+}
dece6358 12828+
4a4d8108
AM
12829+static inline aufs_bindex_t au_fbend_dir(struct file *file)
12830+{
12831+ FiMustAnyLock(file);
12832+ AuDebugOn(!au_fi(file)->fi_hdir);
12833+ return au_fi(file)->fi_hdir->fd_bbot;
12834+}
1facf9fc 12835+
4a4d8108
AM
12836+static inline struct au_vdir *au_fvdir_cache(struct file *file)
12837+{
12838+ FiMustAnyLock(file);
12839+ AuDebugOn(!au_fi(file)->fi_hdir);
12840+ return au_fi(file)->fi_hdir->fd_vdir_cache;
12841+}
1facf9fc 12842+
4a4d8108
AM
12843+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
12844+{
12845+ FiMustWriteLock(file);
12846+ au_fi(file)->fi_btop = bindex;
12847+}
1facf9fc 12848+
4a4d8108
AM
12849+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
12850+{
12851+ FiMustWriteLock(file);
12852+ AuDebugOn(!au_fi(file)->fi_hdir);
12853+ au_fi(file)->fi_hdir->fd_bbot = bindex;
12854+}
1308ab2a 12855+
4a4d8108
AM
12856+static inline void au_set_fvdir_cache(struct file *file,
12857+ struct au_vdir *vdir_cache)
12858+{
12859+ FiMustWriteLock(file);
12860+ AuDebugOn(!au_fi(file)->fi_hdir);
12861+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
12862+}
dece6358 12863+
4a4d8108
AM
12864+static inline struct file *au_hf_top(struct file *file)
12865+{
12866+ FiMustAnyLock(file);
12867+ AuDebugOn(au_fi(file)->fi_hdir);
12868+ return au_fi(file)->fi_htop.hf_file;
12869+}
1facf9fc 12870+
4a4d8108
AM
12871+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
12872+{
12873+ FiMustAnyLock(file);
12874+ AuDebugOn(!au_fi(file)->fi_hdir);
12875+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
12876+}
12877+
4a4d8108
AM
12878+/* todo: memory barrier? */
12879+static inline unsigned int au_figen(struct file *f)
dece6358 12880+{
4a4d8108
AM
12881+ return atomic_read(&au_fi(f)->fi_generation);
12882+}
dece6358 12883+
2cbb1c4b
JR
12884+static inline void au_set_mmapped(struct file *f)
12885+{
12886+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
12887+ return;
0c3ec466 12888+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
12889+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
12890+ ;
12891+}
12892+
12893+static inline void au_unset_mmapped(struct file *f)
12894+{
12895+ atomic_dec(&au_fi(f)->fi_mmapped);
12896+}
12897+
4a4d8108
AM
12898+static inline int au_test_mmapped(struct file *f)
12899+{
2cbb1c4b
JR
12900+ return atomic_read(&au_fi(f)->fi_mmapped);
12901+}
12902+
12903+/* customize vma->vm_file */
12904+
12905+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
12906+ struct file *file)
12907+{
53392da6
AM
12908+ struct file *f;
12909+
12910+ f = vma->vm_file;
2cbb1c4b
JR
12911+ get_file(file);
12912+ vma->vm_file = file;
53392da6 12913+ fput(f);
2cbb1c4b
JR
12914+}
12915+
12916+#ifdef CONFIG_MMU
12917+#define AuDbgVmRegion(file, vma) do {} while (0)
12918+
12919+static inline void au_vm_file_reset(struct vm_area_struct *vma,
12920+ struct file *file)
12921+{
12922+ au_do_vm_file_reset(vma, file);
12923+}
12924+#else
12925+#define AuDbgVmRegion(file, vma) \
12926+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
12927+
12928+static inline void au_vm_file_reset(struct vm_area_struct *vma,
12929+ struct file *file)
12930+{
53392da6
AM
12931+ struct file *f;
12932+
2cbb1c4b 12933+ au_do_vm_file_reset(vma, file);
53392da6 12934+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
12935+ get_file(file);
12936+ vma->vm_region->vm_file = file;
53392da6 12937+ fput(f);
2cbb1c4b
JR
12938+}
12939+#endif /* CONFIG_MMU */
12940+
12941+/* handle vma->vm_prfile */
fb47a38f 12942+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
12943+ struct file *file)
12944+{
2cbb1c4b
JR
12945+ get_file(file);
12946+ vma->vm_prfile = file;
12947+#ifndef CONFIG_MMU
12948+ get_file(file);
12949+ vma->vm_region->vm_prfile = file;
12950+#endif
fb47a38f 12951+}
1308ab2a 12952+
4a4d8108
AM
12953+#endif /* __KERNEL__ */
12954+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
12955diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
12956--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
2000de60 12957+++ linux/fs/aufs/finfo.c 2015-03-27 21:56:35.463461668 +0100
523b37e3 12958@@ -0,0 +1,156 @@
4a4d8108 12959+/*
2000de60 12960+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
12961+ *
12962+ * This program, aufs is free software; you can redistribute it and/or modify
12963+ * it under the terms of the GNU General Public License as published by
12964+ * the Free Software Foundation; either version 2 of the License, or
12965+ * (at your option) any later version.
12966+ *
12967+ * This program is distributed in the hope that it will be useful,
12968+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12969+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12970+ * GNU General Public License for more details.
12971+ *
12972+ * You should have received a copy of the GNU General Public License
523b37e3 12973+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12974+ */
1308ab2a 12975+
4a4d8108
AM
12976+/*
12977+ * file private data
12978+ */
1facf9fc 12979+
4a4d8108 12980+#include "aufs.h"
1facf9fc 12981+
4a4d8108
AM
12982+void au_hfput(struct au_hfile *hf, struct file *file)
12983+{
12984+ /* todo: direct access f_flags */
2cbb1c4b 12985+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
12986+ allow_write_access(hf->hf_file);
12987+ fput(hf->hf_file);
12988+ hf->hf_file = NULL;
e49829fe 12989+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
12990+ hf->hf_br = NULL;
12991+}
1facf9fc 12992+
4a4d8108
AM
12993+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
12994+{
12995+ struct au_finfo *finfo = au_fi(file);
12996+ struct au_hfile *hf;
12997+ struct au_fidir *fidir;
12998+
12999+ fidir = finfo->fi_hdir;
13000+ if (!fidir) {
13001+ AuDebugOn(finfo->fi_btop != bindex);
13002+ hf = &finfo->fi_htop;
13003+ } else
13004+ hf = fidir->fd_hfile + bindex;
13005+
13006+ if (hf && hf->hf_file)
13007+ au_hfput(hf, file);
13008+ if (val) {
13009+ FiMustWriteLock(file);
13010+ hf->hf_file = val;
2000de60 13011+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex);
1308ab2a 13012+ }
4a4d8108 13013+}
1facf9fc 13014+
4a4d8108
AM
13015+void au_update_figen(struct file *file)
13016+{
2000de60 13017+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry));
4a4d8108 13018+ /* smp_mb(); */ /* atomic_set */
1facf9fc 13019+}
13020+
4a4d8108
AM
13021+/* ---------------------------------------------------------------------- */
13022+
4a4d8108
AM
13023+struct au_fidir *au_fidir_alloc(struct super_block *sb)
13024+{
13025+ struct au_fidir *fidir;
13026+ int nbr;
13027+
13028+ nbr = au_sbend(sb) + 1;
13029+ if (nbr < 2)
13030+ nbr = 2; /* initial allocate for 2 branches */
13031+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
13032+ if (fidir) {
13033+ fidir->fd_bbot = -1;
13034+ fidir->fd_nent = nbr;
13035+ fidir->fd_vdir_cache = NULL;
13036+ }
13037+
13038+ return fidir;
13039+}
13040+
13041+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
13042+{
13043+ int err;
13044+ struct au_fidir *fidir, *p;
13045+
13046+ AuRwMustWriteLock(&finfo->fi_rwsem);
13047+ fidir = finfo->fi_hdir;
13048+ AuDebugOn(!fidir);
13049+
13050+ err = -ENOMEM;
13051+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
13052+ GFP_NOFS);
13053+ if (p) {
13054+ p->fd_nent = nbr;
13055+ finfo->fi_hdir = p;
13056+ err = 0;
13057+ }
1facf9fc 13058+
dece6358 13059+ return err;
1facf9fc 13060+}
1308ab2a 13061+
13062+/* ---------------------------------------------------------------------- */
13063+
4a4d8108 13064+void au_finfo_fin(struct file *file)
1308ab2a 13065+{
4a4d8108
AM
13066+ struct au_finfo *finfo;
13067+
2000de60 13068+ au_nfiles_dec(file->f_path.dentry->d_sb);
7f207e10 13069+
4a4d8108
AM
13070+ finfo = au_fi(file);
13071+ AuDebugOn(finfo->fi_hdir);
13072+ AuRwDestroy(&finfo->fi_rwsem);
13073+ au_cache_free_finfo(finfo);
1308ab2a 13074+}
1308ab2a 13075+
e49829fe 13076+void au_fi_init_once(void *_finfo)
4a4d8108 13077+{
e49829fe 13078+ struct au_finfo *finfo = _finfo;
2cbb1c4b 13079+ static struct lock_class_key aufs_fi;
1308ab2a 13080+
e49829fe
JR
13081+ au_rw_init(&finfo->fi_rwsem);
13082+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 13083+}
1308ab2a 13084+
4a4d8108
AM
13085+int au_finfo_init(struct file *file, struct au_fidir *fidir)
13086+{
1716fcea 13087+ int err;
4a4d8108
AM
13088+ struct au_finfo *finfo;
13089+ struct dentry *dentry;
13090+
13091+ err = -ENOMEM;
2000de60 13092+ dentry = file->f_path.dentry;
4a4d8108
AM
13093+ finfo = au_cache_alloc_finfo();
13094+ if (unlikely(!finfo))
13095+ goto out;
13096+
13097+ err = 0;
7f207e10 13098+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
13099+ /* verbose coding for lock class name */
13100+ if (!fidir)
13101+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
13102+ else
13103+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
13104+ au_rw_write_lock(&finfo->fi_rwsem);
13105+ finfo->fi_btop = -1;
13106+ finfo->fi_hdir = fidir;
13107+ atomic_set(&finfo->fi_generation, au_digen(dentry));
13108+ /* smp_mb(); */ /* atomic_set */
13109+
13110+ file->private_data = finfo;
13111+
13112+out:
13113+ return err;
13114+}
7f207e10
AM
13115diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
13116--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
13117+++ linux/fs/aufs/f_op.c 2015-03-27 21:56:35.463461668 +0100
13118@@ -0,0 +1,814 @@
dece6358 13119+/*
2000de60 13120+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
13121+ *
13122+ * This program, aufs is free software; you can redistribute it and/or modify
13123+ * it under the terms of the GNU General Public License as published by
13124+ * the Free Software Foundation; either version 2 of the License, or
13125+ * (at your option) any later version.
13126+ *
13127+ * This program is distributed in the hope that it will be useful,
13128+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13129+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13130+ * GNU General Public License for more details.
13131+ *
13132+ * You should have received a copy of the GNU General Public License
523b37e3 13133+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 13134+ */
1facf9fc 13135+
13136+/*
4a4d8108 13137+ * file and vm operations
1facf9fc 13138+ */
dece6358 13139+
86dc4139 13140+#include <linux/aio.h>
4a4d8108
AM
13141+#include <linux/fs_stack.h>
13142+#include <linux/mman.h>
4a4d8108 13143+#include <linux/security.h>
dece6358
AM
13144+#include "aufs.h"
13145+
4a4d8108 13146+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 13147+{
4a4d8108
AM
13148+ int err;
13149+ aufs_bindex_t bindex;
13150+ struct file *h_file;
13151+ struct dentry *dentry;
13152+ struct au_finfo *finfo;
38d290e6 13153+ struct inode *h_inode;
4a4d8108
AM
13154+
13155+ FiMustWriteLock(file);
13156+
523b37e3 13157+ err = 0;
2000de60 13158+ dentry = file->f_path.dentry;
4a4d8108
AM
13159+ finfo = au_fi(file);
13160+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 13161+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108 13162+ bindex = au_dbstart(dentry);
392086de 13163+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
4a4d8108
AM
13164+ if (IS_ERR(h_file))
13165+ err = PTR_ERR(h_file);
13166+ else {
38d290e6
JR
13167+ if ((flags & __O_TMPFILE)
13168+ && !(flags & O_EXCL)) {
13169+ h_inode = file_inode(h_file);
13170+ spin_lock(&h_inode->i_lock);
13171+ h_inode->i_state |= I_LINKABLE;
13172+ spin_unlock(&h_inode->i_lock);
13173+ }
4a4d8108
AM
13174+ au_set_fbstart(file, bindex);
13175+ au_set_h_fptr(file, bindex, h_file);
13176+ au_update_figen(file);
13177+ /* todo: necessary? */
13178+ /* file->f_ra = h_file->f_ra; */
13179+ }
027c5e7a 13180+
4a4d8108 13181+ return err;
1facf9fc 13182+}
13183+
4a4d8108
AM
13184+static int aufs_open_nondir(struct inode *inode __maybe_unused,
13185+ struct file *file)
1facf9fc 13186+{
4a4d8108 13187+ int err;
1308ab2a 13188+ struct super_block *sb;
1facf9fc 13189+
523b37e3
AM
13190+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
13191+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 13192+
2000de60 13193+ sb = file->f_path.dentry->d_sb;
4a4d8108
AM
13194+ si_read_lock(sb, AuLock_FLUSH);
13195+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
13196+ si_read_unlock(sb);
13197+ return err;
13198+}
1facf9fc 13199+
4a4d8108
AM
13200+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
13201+{
13202+ struct au_finfo *finfo;
13203+ aufs_bindex_t bindex;
1facf9fc 13204+
4a4d8108 13205+ finfo = au_fi(file);
2000de60
JR
13206+ au_sphl_del(&finfo->fi_hlist,
13207+ &au_sbi(file->f_path.dentry->d_sb)->si_files);
4a4d8108 13208+ bindex = finfo->fi_btop;
b4510431 13209+ if (bindex >= 0)
4a4d8108 13210+ au_set_h_fptr(file, bindex, NULL);
7f207e10 13211+
4a4d8108
AM
13212+ au_finfo_fin(file);
13213+ return 0;
1facf9fc 13214+}
13215+
4a4d8108
AM
13216+/* ---------------------------------------------------------------------- */
13217+
13218+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 13219+{
1308ab2a 13220+ int err;
4a4d8108
AM
13221+ struct file *h_file;
13222+
13223+ err = 0;
13224+ h_file = au_hf_top(file);
13225+ if (h_file)
13226+ err = vfsub_flush(h_file, id);
13227+ return err;
13228+}
13229+
13230+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
13231+{
13232+ return au_do_flush(file, id, au_do_flush_nondir);
13233+}
13234+
13235+/* ---------------------------------------------------------------------- */
9dbd164d
AM
13236+/*
13237+ * read and write functions acquire [fdi]_rwsem once, but release before
13238+ * mmap_sem. This is because to stop a race condition between mmap(2).
13239+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
13240+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
13241+ * read functions after [fdi]_rwsem are released, but it should be harmless.
13242+ */
4a4d8108
AM
13243+
13244+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
13245+ loff_t *ppos)
13246+{
13247+ ssize_t err;
dece6358 13248+ struct dentry *dentry;
4a4d8108 13249+ struct file *h_file;
dece6358 13250+ struct super_block *sb;
1facf9fc 13251+
2000de60 13252+ dentry = file->f_path.dentry;
dece6358 13253+ sb = dentry->d_sb;
e49829fe 13254+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 13255+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
13256+ if (unlikely(err))
13257+ goto out;
1facf9fc 13258+
4a4d8108 13259+ h_file = au_hf_top(file);
9dbd164d
AM
13260+ get_file(h_file);
13261+ di_read_unlock(dentry, AuLock_IR);
13262+ fi_read_unlock(file);
13263+
13264+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
13265+ err = vfsub_read_u(h_file, buf, count, ppos);
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);
1308ab2a 13271+
4f0767ce 13272+out:
dece6358
AM
13273+ si_read_unlock(sb);
13274+ return err;
13275+}
1facf9fc 13276+
e49829fe
JR
13277+/*
13278+ * todo: very ugly
13279+ * it locks both of i_mutex and si_rwsem for read in safe.
13280+ * if the plink maintenance mode continues forever (that is the problem),
13281+ * may loop forever.
13282+ */
13283+static void au_mtx_and_read_lock(struct inode *inode)
13284+{
13285+ int err;
13286+ struct super_block *sb = inode->i_sb;
13287+
13288+ while (1) {
13289+ mutex_lock(&inode->i_mutex);
13290+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13291+ if (!err)
13292+ break;
13293+ mutex_unlock(&inode->i_mutex);
13294+ si_read_lock(sb, AuLock_NOPLMW);
13295+ si_read_unlock(sb);
13296+ }
13297+}
13298+
4a4d8108
AM
13299+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
13300+ size_t count, loff_t *ppos)
dece6358 13301+{
4a4d8108 13302+ ssize_t err;
076b876e
AM
13303+ blkcnt_t blks;
13304+ aufs_bindex_t bstart;
4a4d8108 13305+ struct au_pin pin;
dece6358 13306+ struct dentry *dentry;
076b876e 13307+ struct inode *inode, *h_inode;
9dbd164d 13308+ struct super_block *sb;
4a4d8108
AM
13309+ struct file *h_file;
13310+ char __user *buf = (char __user *)ubuf;
1facf9fc 13311+
2000de60 13312+ dentry = file->f_path.dentry;
9dbd164d 13313+ sb = dentry->d_sb;
4a4d8108 13314+ inode = dentry->d_inode;
e49829fe 13315+ au_mtx_and_read_lock(inode);
1facf9fc 13316+
4a4d8108
AM
13317+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13318+ if (unlikely(err))
13319+ goto out;
1facf9fc 13320+
4a4d8108
AM
13321+ err = au_ready_to_write(file, -1, &pin);
13322+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13323+ if (unlikely(err)) {
13324+ di_read_unlock(dentry, AuLock_IR);
13325+ fi_write_unlock(file);
13326+ goto out;
13327+ }
1facf9fc 13328+
076b876e 13329+ bstart = au_fbstart(file);
4a4d8108 13330+ h_file = au_hf_top(file);
9dbd164d 13331+ get_file(h_file);
c1595e42 13332+ h_inode = file_inode(h_file);
076b876e 13333+ blks = h_inode->i_blocks;
4a4d8108 13334+ au_unpin(&pin);
9dbd164d
AM
13335+ di_read_unlock(dentry, AuLock_IR);
13336+ fi_write_unlock(file);
13337+
4a4d8108 13338+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 13339+ ii_write_lock_child(inode);
4a4d8108 13340+ au_cpup_attr_timesizes(inode);
c06a8ce3 13341+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13342+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13343+ if (err > 0)
13344+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13345+ ii_write_unlock(inode);
13346+ fput(h_file);
1facf9fc 13347+
4f0767ce 13348+out:
9dbd164d 13349+ si_read_unlock(sb);
4a4d8108 13350+ mutex_unlock(&inode->i_mutex);
dece6358
AM
13351+ return err;
13352+}
1facf9fc 13353+
076b876e
AM
13354+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
13355+ struct iov_iter *iov_iter)
dece6358 13356+{
4a4d8108
AM
13357+ ssize_t err;
13358+ struct file *file;
076b876e
AM
13359+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
13360+ ssize_t (*aio)(struct kiocb *, const struct iovec *, unsigned long,
13361+ loff_t);
1facf9fc 13362+
4a4d8108
AM
13363+ err = security_file_permission(h_file, rw);
13364+ if (unlikely(err))
13365+ goto out;
1facf9fc 13366+
4a4d8108 13367+ err = -ENOSYS;
076b876e
AM
13368+ iter = NULL;
13369+ aio = NULL;
13370+ if (rw == MAY_READ) {
13371+ iter = h_file->f_op->read_iter;
13372+ aio = h_file->f_op->aio_read;
13373+ } else if (rw == MAY_WRITE) {
13374+ iter = h_file->f_op->write_iter;
13375+ aio = h_file->f_op->aio_write;
13376+ }
13377+
13378+ file = kio->ki_filp;
13379+ kio->ki_filp = h_file;
13380+ if (iter) {
2cbb1c4b 13381+ lockdep_off();
076b876e
AM
13382+ err = iter(kio, iov_iter);
13383+ lockdep_on();
13384+ } else if (aio) {
13385+ lockdep_off();
13386+ err = aio(kio, iov_iter->iov, iov_iter->nr_segs, kio->ki_pos);
2cbb1c4b 13387+ lockdep_on();
4a4d8108
AM
13388+ } else
13389+ /* currently there is no such fs */
13390+ WARN_ON_ONCE(1);
076b876e 13391+ kio->ki_filp = file;
1facf9fc 13392+
4f0767ce 13393+out:
dece6358
AM
13394+ return err;
13395+}
1facf9fc 13396+
076b876e 13397+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 13398+{
4a4d8108
AM
13399+ ssize_t err;
13400+ struct file *file, *h_file;
13401+ struct dentry *dentry;
dece6358 13402+ struct super_block *sb;
1facf9fc 13403+
4a4d8108 13404+ file = kio->ki_filp;
2000de60 13405+ dentry = file->f_path.dentry;
1308ab2a 13406+ sb = dentry->d_sb;
e49829fe 13407+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13408+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13409+ if (unlikely(err))
13410+ goto out;
13411+
13412+ h_file = au_hf_top(file);
9dbd164d
AM
13413+ get_file(h_file);
13414+ di_read_unlock(dentry, AuLock_IR);
13415+ fi_read_unlock(file);
13416+
076b876e 13417+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
13418+ /* todo: necessary? */
13419+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13420+ /* update without lock, I don't think it a problem */
c06a8ce3 13421+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13422+ fput(h_file);
1facf9fc 13423+
4f0767ce 13424+out:
4a4d8108 13425+ si_read_unlock(sb);
1308ab2a 13426+ return err;
13427+}
1facf9fc 13428+
076b876e 13429+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 13430+{
4a4d8108 13431+ ssize_t err;
076b876e
AM
13432+ blkcnt_t blks;
13433+ aufs_bindex_t bstart;
4a4d8108
AM
13434+ struct au_pin pin;
13435+ struct dentry *dentry;
076b876e 13436+ struct inode *inode, *h_inode;
4a4d8108 13437+ struct file *file, *h_file;
9dbd164d 13438+ struct super_block *sb;
1308ab2a 13439+
4a4d8108 13440+ file = kio->ki_filp;
2000de60 13441+ dentry = file->f_path.dentry;
9dbd164d 13442+ sb = dentry->d_sb;
1308ab2a 13443+ inode = dentry->d_inode;
e49829fe
JR
13444+ au_mtx_and_read_lock(inode);
13445+
4a4d8108
AM
13446+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13447+ if (unlikely(err))
1308ab2a 13448+ goto out;
1facf9fc 13449+
4a4d8108
AM
13450+ err = au_ready_to_write(file, -1, &pin);
13451+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13452+ if (unlikely(err)) {
13453+ di_read_unlock(dentry, AuLock_IR);
13454+ fi_write_unlock(file);
13455+ goto out;
13456+ }
1facf9fc 13457+
076b876e 13458+ bstart = au_fbstart(file);
4a4d8108 13459+ h_file = au_hf_top(file);
9dbd164d 13460+ get_file(h_file);
c1595e42 13461+ h_inode = file_inode(h_file);
076b876e 13462+ blks = h_inode->i_blocks;
9dbd164d
AM
13463+ au_unpin(&pin);
13464+ di_read_unlock(dentry, AuLock_IR);
13465+ fi_write_unlock(file);
13466+
076b876e 13467+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
9dbd164d 13468+ ii_write_lock_child(inode);
4a4d8108 13469+ au_cpup_attr_timesizes(inode);
c06a8ce3 13470+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13471+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13472+ if (err > 0)
13473+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13474+ ii_write_unlock(inode);
13475+ fput(h_file);
1facf9fc 13476+
4f0767ce 13477+out:
9dbd164d 13478+ si_read_unlock(sb);
4a4d8108 13479+ mutex_unlock(&inode->i_mutex);
dece6358 13480+ return err;
1facf9fc 13481+}
13482+
4a4d8108
AM
13483+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
13484+ struct pipe_inode_info *pipe, size_t len,
13485+ unsigned int flags)
1facf9fc 13486+{
4a4d8108
AM
13487+ ssize_t err;
13488+ struct file *h_file;
13489+ struct dentry *dentry;
dece6358 13490+ struct super_block *sb;
1facf9fc 13491+
2000de60 13492+ dentry = file->f_path.dentry;
dece6358 13493+ sb = dentry->d_sb;
e49829fe 13494+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13495+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13496+ if (unlikely(err))
dece6358 13497+ goto out;
1facf9fc 13498+
4a4d8108
AM
13499+ err = -EINVAL;
13500+ h_file = au_hf_top(file);
9dbd164d 13501+ get_file(h_file);
4a4d8108 13502+ if (au_test_loopback_kthread()) {
2000de60 13503+ au_warn_loopback(h_file->f_path.dentry->d_sb);
87a755f4
AM
13504+ if (file->f_mapping != h_file->f_mapping) {
13505+ file->f_mapping = h_file->f_mapping;
13506+ smp_mb(); /* unnecessary? */
13507+ }
1308ab2a 13508+ }
9dbd164d
AM
13509+ di_read_unlock(dentry, AuLock_IR);
13510+ fi_read_unlock(file);
13511+
4a4d8108
AM
13512+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
13513+ /* todo: necessasry? */
13514+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13515+ /* update without lock, I don't think it a problem */
c06a8ce3 13516+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13517+ fput(h_file);
1facf9fc 13518+
4f0767ce 13519+out:
4a4d8108 13520+ si_read_unlock(sb);
dece6358 13521+ return err;
1facf9fc 13522+}
13523+
4a4d8108
AM
13524+static ssize_t
13525+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
13526+ size_t len, unsigned int flags)
1facf9fc 13527+{
4a4d8108 13528+ ssize_t err;
076b876e
AM
13529+ blkcnt_t blks;
13530+ aufs_bindex_t bstart;
4a4d8108
AM
13531+ struct au_pin pin;
13532+ struct dentry *dentry;
076b876e 13533+ struct inode *inode, *h_inode;
9dbd164d 13534+ struct super_block *sb;
076b876e 13535+ struct file *h_file;
1facf9fc 13536+
2000de60 13537+ dentry = file->f_path.dentry;
9dbd164d 13538+ sb = dentry->d_sb;
4a4d8108 13539+ inode = dentry->d_inode;
e49829fe 13540+ au_mtx_and_read_lock(inode);
9dbd164d 13541+
4a4d8108
AM
13542+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13543+ if (unlikely(err))
13544+ goto out;
1facf9fc 13545+
4a4d8108
AM
13546+ err = au_ready_to_write(file, -1, &pin);
13547+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13548+ if (unlikely(err)) {
13549+ di_read_unlock(dentry, AuLock_IR);
13550+ fi_write_unlock(file);
13551+ goto out;
13552+ }
1facf9fc 13553+
076b876e 13554+ bstart = au_fbstart(file);
4a4d8108 13555+ h_file = au_hf_top(file);
9dbd164d 13556+ get_file(h_file);
c1595e42 13557+ h_inode = file_inode(h_file);
076b876e 13558+ blks = h_inode->i_blocks;
4a4d8108 13559+ au_unpin(&pin);
9dbd164d
AM
13560+ di_read_unlock(dentry, AuLock_IR);
13561+ fi_write_unlock(file);
13562+
4a4d8108 13563+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 13564+ ii_write_lock_child(inode);
4a4d8108 13565+ au_cpup_attr_timesizes(inode);
c06a8ce3 13566+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13567+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13568+ if (err > 0)
13569+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13570+ ii_write_unlock(inode);
13571+ fput(h_file);
1facf9fc 13572+
4f0767ce 13573+out:
9dbd164d 13574+ si_read_unlock(sb);
4a4d8108
AM
13575+ mutex_unlock(&inode->i_mutex);
13576+ return err;
13577+}
1facf9fc 13578+
38d290e6
JR
13579+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
13580+ loff_t len)
13581+{
13582+ long err;
13583+ struct au_pin pin;
13584+ struct dentry *dentry;
13585+ struct super_block *sb;
13586+ struct inode *inode;
13587+ struct file *h_file;
13588+
2000de60 13589+ dentry = file->f_path.dentry;
38d290e6
JR
13590+ sb = dentry->d_sb;
13591+ inode = dentry->d_inode;
13592+ au_mtx_and_read_lock(inode);
13593+
13594+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13595+ if (unlikely(err))
13596+ goto out;
13597+
13598+ err = au_ready_to_write(file, -1, &pin);
13599+ di_downgrade_lock(dentry, AuLock_IR);
13600+ if (unlikely(err)) {
13601+ di_read_unlock(dentry, AuLock_IR);
13602+ fi_write_unlock(file);
13603+ goto out;
13604+ }
13605+
13606+ h_file = au_hf_top(file);
13607+ get_file(h_file);
13608+ au_unpin(&pin);
13609+ di_read_unlock(dentry, AuLock_IR);
13610+ fi_write_unlock(file);
13611+
13612+ lockdep_off();
03673fb0 13613+ err = vfs_fallocate(h_file, mode, offset, len);
38d290e6
JR
13614+ lockdep_on();
13615+ ii_write_lock_child(inode);
13616+ au_cpup_attr_timesizes(inode);
13617+ inode->i_mode = file_inode(h_file)->i_mode;
13618+ ii_write_unlock(inode);
13619+ fput(h_file);
13620+
13621+out:
13622+ si_read_unlock(sb);
13623+ mutex_unlock(&inode->i_mutex);
13624+ return err;
13625+}
13626+
4a4d8108
AM
13627+/* ---------------------------------------------------------------------- */
13628+
9dbd164d
AM
13629+/*
13630+ * The locking order around current->mmap_sem.
13631+ * - in most and regular cases
13632+ * file I/O syscall -- aufs_read() or something
13633+ * -- si_rwsem for read -- mmap_sem
13634+ * (Note that [fdi]i_rwsem are released before mmap_sem).
13635+ * - in mmap case
13636+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
13637+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
13638+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
13639+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
13640+ * It means that when aufs acquires si_rwsem for write, the process should never
13641+ * acquire mmap_sem.
13642+ *
392086de 13643+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
13644+ * problem either since any directory is not able to be mmap-ed.
13645+ * The similar scenario is applied to aufs_readlink() too.
13646+ */
13647+
38d290e6 13648+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
13649+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
13650+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
13651+
13652+static unsigned long au_arch_prot_conv(unsigned long flags)
13653+{
13654+ /* currently ppc64 only */
13655+#ifdef CONFIG_PPC64
13656+ /* cf. linux/arch/powerpc/include/asm/mman.h */
13657+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
13658+ return AuConv_VM_PROT(flags, SAO);
13659+#else
13660+ AuDebugOn(arch_calc_vm_prot_bits(-1));
13661+ return 0;
13662+#endif
13663+}
13664+
13665+static unsigned long au_prot_conv(unsigned long flags)
13666+{
13667+ return AuConv_VM_PROT(flags, READ)
13668+ | AuConv_VM_PROT(flags, WRITE)
13669+ | AuConv_VM_PROT(flags, EXEC)
13670+ | au_arch_prot_conv(flags);
13671+}
13672+
13673+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
13674+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
13675+
13676+static unsigned long au_flag_conv(unsigned long flags)
13677+{
13678+ return AuConv_VM_MAP(flags, GROWSDOWN)
13679+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
13680+ | AuConv_VM_MAP(flags, LOCKED);
13681+}
38d290e6 13682+#endif
2dfbb274 13683+
9dbd164d 13684+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 13685+{
4a4d8108
AM
13686+ int err;
13687+ aufs_bindex_t bstart;
13688+ const unsigned char wlock
9dbd164d 13689+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
13690+ struct dentry *dentry;
13691+ struct super_block *sb;
9dbd164d
AM
13692+ struct file *h_file;
13693+ struct au_branch *br;
13694+ struct au_pin pin;
13695+
13696+ AuDbgVmRegion(file, vma);
1308ab2a 13697+
2000de60 13698+ dentry = file->f_path.dentry;
4a4d8108 13699+ sb = dentry->d_sb;
9dbd164d 13700+ lockdep_off();
e49829fe 13701+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
13702+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13703+ if (unlikely(err))
13704+ goto out;
13705+
4a4d8108 13706+ if (wlock) {
4a4d8108
AM
13707+ err = au_ready_to_write(file, -1, &pin);
13708+ di_write_unlock(dentry);
9dbd164d
AM
13709+ if (unlikely(err)) {
13710+ fi_write_unlock(file);
13711+ goto out;
13712+ }
4a4d8108
AM
13713+ au_unpin(&pin);
13714+ } else
13715+ di_write_unlock(dentry);
9dbd164d 13716+
4a4d8108 13717+ bstart = au_fbstart(file);
9dbd164d
AM
13718+ br = au_sbr(sb, bstart);
13719+ h_file = au_hf_top(file);
13720+ get_file(h_file);
2cbb1c4b 13721+ au_set_mmapped(file);
4a4d8108 13722+ fi_write_unlock(file);
9dbd164d 13723+ lockdep_on();
1308ab2a 13724+
9dbd164d 13725+ au_vm_file_reset(vma, h_file);
38d290e6
JR
13726+ /*
13727+ * we cannot call security_mmap_file() here since it may acquire
13728+ * mmap_sem or i_mutex.
13729+ *
13730+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
13731+ * au_flag_conv(vma->vm_flags));
13732+ */
9dbd164d
AM
13733+ if (!err)
13734+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
13735+ if (unlikely(err))
13736+ goto out_reset;
4a4d8108 13737+
fb47a38f 13738+ au_vm_prfile_set(vma, file);
4a4d8108 13739+ /* update without lock, I don't think it a problem */
c06a8ce3 13740+ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
2cbb1c4b 13741+ goto out_fput; /* success */
4a4d8108 13742+
2cbb1c4b
JR
13743+out_reset:
13744+ au_unset_mmapped(file);
13745+ au_vm_file_reset(vma, file);
13746+out_fput:
9dbd164d
AM
13747+ fput(h_file);
13748+ lockdep_off();
4f0767ce 13749+out:
9dbd164d
AM
13750+ si_read_unlock(sb);
13751+ lockdep_on();
13752+ AuTraceErr(err);
4a4d8108
AM
13753+ return err;
13754+}
13755+
13756+/* ---------------------------------------------------------------------- */
13757+
1e00d052
AM
13758+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
13759+ int datasync)
4a4d8108
AM
13760+{
13761+ int err;
13762+ struct au_pin pin;
b752ccd1 13763+ struct dentry *dentry;
4a4d8108
AM
13764+ struct inode *inode;
13765+ struct file *h_file;
13766+ struct super_block *sb;
13767+
2000de60 13768+ dentry = file->f_path.dentry;
4a4d8108 13769+ inode = dentry->d_inode;
4a4d8108 13770+ sb = dentry->d_sb;
1e00d052 13771+ mutex_lock(&inode->i_mutex);
e49829fe
JR
13772+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13773+ if (unlikely(err))
13774+ goto out;
4a4d8108
AM
13775+
13776+ err = 0; /* -EBADF; */ /* posix? */
13777+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 13778+ goto out_si;
4a4d8108
AM
13779+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13780+ if (unlikely(err))
e49829fe 13781+ goto out_si;
4a4d8108
AM
13782+
13783+ err = au_ready_to_write(file, -1, &pin);
13784+ di_downgrade_lock(dentry, AuLock_IR);
13785+ if (unlikely(err))
13786+ goto out_unlock;
13787+ au_unpin(&pin);
13788+
13789+ err = -EINVAL;
13790+ h_file = au_hf_top(file);
53392da6
AM
13791+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
13792+ au_cpup_attr_timesizes(inode);
4a4d8108 13793+
4f0767ce 13794+out_unlock:
4a4d8108 13795+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 13796+ fi_write_unlock(file);
e49829fe 13797+out_si:
953406b4 13798+ si_read_unlock(sb);
e49829fe 13799+out:
1e00d052 13800+ mutex_unlock(&inode->i_mutex);
4a4d8108 13801+ return err;
dece6358
AM
13802+}
13803+
4a4d8108
AM
13804+/* no one supports this operation, currently */
13805+#if 0
13806+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 13807+{
4a4d8108
AM
13808+ int err;
13809+ struct au_pin pin;
1308ab2a 13810+ struct dentry *dentry;
4a4d8108
AM
13811+ struct inode *inode;
13812+ struct file *file, *h_file;
1308ab2a 13813+
4a4d8108 13814+ file = kio->ki_filp;
2000de60 13815+ dentry = file->f_path.dentry;
4a4d8108 13816+ inode = dentry->d_inode;
e49829fe 13817+ au_mtx_and_read_lock(inode);
4a4d8108
AM
13818+
13819+ err = 0; /* -EBADF; */ /* posix? */
13820+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
13821+ goto out;
13822+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13823+ if (unlikely(err))
1308ab2a 13824+ goto out;
13825+
4a4d8108
AM
13826+ err = au_ready_to_write(file, -1, &pin);
13827+ di_downgrade_lock(dentry, AuLock_IR);
13828+ if (unlikely(err))
13829+ goto out_unlock;
13830+ au_unpin(&pin);
1308ab2a 13831+
4a4d8108
AM
13832+ err = -ENOSYS;
13833+ h_file = au_hf_top(file);
523b37e3 13834+ if (h_file->f_op->aio_fsync) {
4a4d8108 13835+ struct mutex *h_mtx;
1308ab2a 13836+
c06a8ce3 13837+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
13838+ if (!is_sync_kiocb(kio)) {
13839+ get_file(h_file);
13840+ fput(file);
13841+ }
13842+ kio->ki_filp = h_file;
13843+ err = h_file->f_op->aio_fsync(kio, datasync);
13844+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
13845+ if (!err)
13846+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
13847+ /*ignore*/
13848+ au_cpup_attr_timesizes(inode);
13849+ mutex_unlock(h_mtx);
13850+ }
1308ab2a 13851+
4f0767ce 13852+out_unlock:
4a4d8108
AM
13853+ di_read_unlock(dentry, AuLock_IR);
13854+ fi_write_unlock(file);
4f0767ce 13855+out:
e49829fe 13856+ si_read_unlock(inode->sb);
4a4d8108
AM
13857+ mutex_unlock(&inode->i_mutex);
13858+ return err;
dece6358 13859+}
4a4d8108 13860+#endif
dece6358 13861+
4a4d8108 13862+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 13863+{
4a4d8108
AM
13864+ int err;
13865+ struct file *h_file;
13866+ struct dentry *dentry;
13867+ struct super_block *sb;
1308ab2a 13868+
2000de60 13869+ dentry = file->f_path.dentry;
4a4d8108 13870+ sb = dentry->d_sb;
e49829fe 13871+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13872+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13873+ if (unlikely(err))
13874+ goto out;
13875+
13876+ h_file = au_hf_top(file);
523b37e3 13877+ if (h_file->f_op->fasync)
4a4d8108
AM
13878+ err = h_file->f_op->fasync(fd, h_file, flag);
13879+
13880+ di_read_unlock(dentry, AuLock_IR);
13881+ fi_read_unlock(file);
1308ab2a 13882+
4f0767ce 13883+out:
4a4d8108 13884+ si_read_unlock(sb);
1308ab2a 13885+ return err;
dece6358 13886+}
4a4d8108
AM
13887+
13888+/* ---------------------------------------------------------------------- */
13889+
13890+/* no one supports this operation, currently */
13891+#if 0
13892+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
2000de60 13893+ size_t len, loff_t *pos, int more)
4a4d8108
AM
13894+{
13895+}
13896+#endif
13897+
13898+/* ---------------------------------------------------------------------- */
13899+
13900+const struct file_operations aufs_file_fop = {
13901+ .owner = THIS_MODULE,
2cbb1c4b 13902+
027c5e7a 13903+ .llseek = default_llseek,
4a4d8108
AM
13904+
13905+ .read = aufs_read,
13906+ .write = aufs_write,
076b876e
AM
13907+ .read_iter = aufs_read_iter,
13908+ .write_iter = aufs_write_iter,
13909+
4a4d8108
AM
13910+#ifdef CONFIG_AUFS_POLL
13911+ .poll = aufs_poll,
13912+#endif
13913+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 13914+#ifdef CONFIG_COMPAT
c2b27bf2 13915+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 13916+#endif
4a4d8108
AM
13917+ .mmap = aufs_mmap,
13918+ .open = aufs_open_nondir,
13919+ .flush = aufs_flush_nondir,
13920+ .release = aufs_release_nondir,
13921+ .fsync = aufs_fsync_nondir,
13922+ /* .aio_fsync = aufs_aio_fsync_nondir, */
13923+ .fasync = aufs_fasync,
13924+ /* .sendpage = aufs_sendpage, */
13925+ .splice_write = aufs_splice_write,
13926+ .splice_read = aufs_splice_read,
13927+#if 0
13928+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 13929+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 13930+#endif
38d290e6 13931+ .fallocate = aufs_fallocate
4a4d8108 13932+};
7f207e10
AM
13933diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
13934--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
2000de60 13935+++ linux/fs/aufs/fstype.h 2015-03-27 21:56:35.463461668 +0100
523b37e3 13936@@ -0,0 +1,469 @@
4a4d8108 13937+/*
2000de60 13938+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
13939+ *
13940+ * This program, aufs is free software; you can redistribute it and/or modify
13941+ * it under the terms of the GNU General Public License as published by
13942+ * the Free Software Foundation; either version 2 of the License, or
13943+ * (at your option) any later version.
13944+ *
13945+ * This program is distributed in the hope that it will be useful,
13946+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13947+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13948+ * GNU General Public License for more details.
13949+ *
13950+ * You should have received a copy of the GNU General Public License
523b37e3 13951+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
13952+ */
13953+
13954+/*
13955+ * judging filesystem type
13956+ */
13957+
13958+#ifndef __AUFS_FSTYPE_H__
13959+#define __AUFS_FSTYPE_H__
13960+
13961+#ifdef __KERNEL__
13962+
13963+#include <linux/fs.h>
13964+#include <linux/magic.h>
13965+#include <linux/romfs_fs.h>
4a4d8108
AM
13966+
13967+static inline int au_test_aufs(struct super_block *sb)
13968+{
13969+ return sb->s_magic == AUFS_SUPER_MAGIC;
13970+}
13971+
13972+static inline const char *au_sbtype(struct super_block *sb)
13973+{
13974+ return sb->s_type->name;
13975+}
1308ab2a 13976+
13977+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
13978+{
2000de60
JR
13979+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
13980+ return sb->s_magic == ISOFS_SUPER_MAGIC;
dece6358
AM
13981+#else
13982+ return 0;
13983+#endif
13984+}
13985+
1308ab2a 13986+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 13987+{
2000de60
JR
13988+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
13989+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
13990+#else
13991+ return 0;
13992+#endif
13993+}
13994+
1308ab2a 13995+static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
dece6358 13996+{
1308ab2a 13997+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
13998+ return sb->s_magic == CRAMFS_MAGIC;
13999+#endif
14000+ return 0;
14001+}
14002+
14003+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
14004+{
14005+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
14006+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
14007+#else
14008+ return 0;
14009+#endif
14010+}
14011+
1308ab2a 14012+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 14013+{
1308ab2a 14014+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
14015+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
14016+#else
14017+ return 0;
14018+#endif
14019+}
14020+
1308ab2a 14021+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 14022+{
1308ab2a 14023+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
14024+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
14025+#else
14026+ return 0;
14027+#endif
14028+}
14029+
1308ab2a 14030+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 14031+{
1308ab2a 14032+#ifdef CONFIG_TMPFS
14033+ return sb->s_magic == TMPFS_MAGIC;
14034+#else
14035+ return 0;
dece6358 14036+#endif
dece6358
AM
14037+}
14038+
1308ab2a 14039+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 14040+{
1308ab2a 14041+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
14042+ return !strcmp(au_sbtype(sb), "ecryptfs");
14043+#else
14044+ return 0;
14045+#endif
1facf9fc 14046+}
14047+
1308ab2a 14048+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
1facf9fc 14049+{
1308ab2a 14050+#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
14051+ return sb->s_magic == OCFS2_SUPER_MAGIC;
14052+#else
14053+ return 0;
14054+#endif
1facf9fc 14055+}
14056+
1308ab2a 14057+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
1facf9fc 14058+{
1308ab2a 14059+#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
14060+ return sb->s_magic == DLMFS_MAGIC;
14061+#else
14062+ return 0;
14063+#endif
1facf9fc 14064+}
14065+
1308ab2a 14066+static inline int au_test_coda(struct super_block *sb __maybe_unused)
1facf9fc 14067+{
1308ab2a 14068+#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
14069+ return sb->s_magic == CODA_SUPER_MAGIC;
14070+#else
14071+ return 0;
14072+#endif
14073+}
14074+
14075+static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
14076+{
14077+#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
14078+ return sb->s_magic == V9FS_MAGIC;
14079+#else
14080+ return 0;
14081+#endif
14082+}
14083+
14084+static inline int au_test_ext4(struct super_block *sb __maybe_unused)
14085+{
c2b27bf2 14086+#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE)
1308ab2a 14087+ return sb->s_magic == EXT4_SUPER_MAGIC;
14088+#else
14089+ return 0;
14090+#endif
14091+}
14092+
14093+static inline int au_test_sysv(struct super_block *sb __maybe_unused)
14094+{
14095+#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
14096+ return !strcmp(au_sbtype(sb), "sysv");
14097+#else
14098+ return 0;
14099+#endif
14100+}
14101+
14102+static inline int au_test_ramfs(struct super_block *sb)
14103+{
14104+ return sb->s_magic == RAMFS_MAGIC;
14105+}
14106+
14107+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
14108+{
14109+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
14110+ return sb->s_magic == UBIFS_SUPER_MAGIC;
14111+#else
14112+ return 0;
14113+#endif
14114+}
14115+
14116+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
14117+{
14118+#ifdef CONFIG_PROC_FS
14119+ return sb->s_magic == PROC_SUPER_MAGIC;
14120+#else
14121+ return 0;
14122+#endif
14123+}
14124+
14125+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
14126+{
14127+#ifdef CONFIG_SYSFS
14128+ return sb->s_magic == SYSFS_MAGIC;
14129+#else
14130+ return 0;
14131+#endif
14132+}
14133+
14134+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
14135+{
14136+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
14137+ return sb->s_magic == CONFIGFS_MAGIC;
14138+#else
14139+ return 0;
14140+#endif
14141+}
14142+
14143+static inline int au_test_minix(struct super_block *sb __maybe_unused)
14144+{
14145+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
14146+ return sb->s_magic == MINIX3_SUPER_MAGIC
14147+ || sb->s_magic == MINIX2_SUPER_MAGIC
14148+ || sb->s_magic == MINIX2_SUPER_MAGIC2
14149+ || sb->s_magic == MINIX_SUPER_MAGIC
14150+ || sb->s_magic == MINIX_SUPER_MAGIC2;
14151+#else
14152+ return 0;
14153+#endif
14154+}
14155+
14156+static inline int au_test_cifs(struct super_block *sb __maybe_unused)
14157+{
14158+#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
14159+ return sb->s_magic == CIFS_MAGIC_NUMBER;
14160+#else
14161+ return 0;
14162+#endif
14163+}
14164+
14165+static inline int au_test_fat(struct super_block *sb __maybe_unused)
14166+{
14167+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
14168+ return sb->s_magic == MSDOS_SUPER_MAGIC;
14169+#else
14170+ return 0;
14171+#endif
14172+}
14173+
14174+static inline int au_test_msdos(struct super_block *sb)
14175+{
14176+ return au_test_fat(sb);
14177+}
14178+
14179+static inline int au_test_vfat(struct super_block *sb)
14180+{
14181+ return au_test_fat(sb);
14182+}
14183+
14184+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
14185+{
14186+#ifdef CONFIG_SECURITYFS
14187+ return sb->s_magic == SECURITYFS_MAGIC;
14188+#else
14189+ return 0;
14190+#endif
14191+}
14192+
14193+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
14194+{
14195+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
14196+ return sb->s_magic == SQUASHFS_MAGIC;
14197+#else
14198+ return 0;
14199+#endif
14200+}
14201+
14202+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
14203+{
14204+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
14205+ return sb->s_magic == BTRFS_SUPER_MAGIC;
14206+#else
14207+ return 0;
14208+#endif
14209+}
14210+
14211+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
14212+{
14213+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
14214+ return sb->s_magic == XENFS_SUPER_MAGIC;
14215+#else
14216+ return 0;
14217+#endif
14218+}
14219+
14220+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
14221+{
14222+#ifdef CONFIG_DEBUG_FS
14223+ return sb->s_magic == DEBUGFS_MAGIC;
14224+#else
14225+ return 0;
14226+#endif
14227+}
14228+
14229+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
14230+{
14231+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
14232+ return sb->s_magic == NILFS_SUPER_MAGIC;
14233+#else
14234+ return 0;
14235+#endif
14236+}
14237+
4a4d8108
AM
14238+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
14239+{
14240+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
14241+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
14242+#else
14243+ return 0;
14244+#endif
14245+}
14246+
1308ab2a 14247+/* ---------------------------------------------------------------------- */
14248+/*
14249+ * they can't be an aufs branch.
14250+ */
14251+static inline int au_test_fs_unsuppoted(struct super_block *sb)
14252+{
14253+ return
14254+#ifndef CONFIG_AUFS_BR_RAMFS
14255+ au_test_ramfs(sb) ||
14256+#endif
14257+ au_test_procfs(sb)
14258+ || au_test_sysfs(sb)
14259+ || au_test_configfs(sb)
14260+ || au_test_debugfs(sb)
14261+ || au_test_securityfs(sb)
14262+ || au_test_xenfs(sb)
14263+ || au_test_ecryptfs(sb)
14264+ /* || !strcmp(au_sbtype(sb), "unionfs") */
14265+ || au_test_aufs(sb); /* will be supported in next version */
14266+}
14267+
1308ab2a 14268+static inline int au_test_fs_remote(struct super_block *sb)
14269+{
14270+ return !au_test_tmpfs(sb)
14271+#ifdef CONFIG_AUFS_BR_RAMFS
14272+ && !au_test_ramfs(sb)
14273+#endif
14274+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
14275+}
14276+
14277+/* ---------------------------------------------------------------------- */
14278+
14279+/*
14280+ * Note: these functions (below) are created after reading ->getattr() in all
14281+ * filesystems under linux/fs. it means we have to do so in every update...
14282+ */
14283+
14284+/*
14285+ * some filesystems require getattr to refresh the inode attributes before
14286+ * referencing.
14287+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
14288+ * and leave the work for d_revalidate()
14289+ */
14290+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
14291+{
14292+ return au_test_nfs(sb)
14293+ || au_test_fuse(sb)
1308ab2a 14294+ /* || au_test_ocfs2(sb) */ /* untested */
14295+ /* || au_test_btrfs(sb) */ /* untested */
14296+ /* || au_test_coda(sb) */ /* untested */
14297+ /* || au_test_v9fs(sb) */ /* untested */
14298+ ;
14299+}
14300+
14301+/*
14302+ * filesystems which don't maintain i_size or i_blocks.
14303+ */
14304+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
14305+{
14306+ return au_test_xfs(sb)
4a4d8108
AM
14307+ || au_test_btrfs(sb)
14308+ || au_test_ubifs(sb)
14309+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 14310+ /* || au_test_ext4(sb) */ /* untested */
14311+ /* || au_test_ocfs2(sb) */ /* untested */
14312+ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
14313+ /* || au_test_sysv(sb) */ /* untested */
1308ab2a 14314+ /* || au_test_minix(sb) */ /* untested */
14315+ ;
14316+}
14317+
14318+/*
14319+ * filesystems which don't store the correct value in some of their inode
14320+ * attributes.
14321+ */
14322+static inline int au_test_fs_bad_iattr(struct super_block *sb)
14323+{
14324+ return au_test_fs_bad_iattr_size(sb)
14325+ /* || au_test_cifs(sb) */ /* untested */
14326+ || au_test_fat(sb)
14327+ || au_test_msdos(sb)
14328+ || au_test_vfat(sb);
1facf9fc 14329+}
14330+
14331+/* they don't check i_nlink in link(2) */
14332+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
14333+{
14334+ return au_test_tmpfs(sb)
14335+#ifdef CONFIG_AUFS_BR_RAMFS
14336+ || au_test_ramfs(sb)
14337+#endif
4a4d8108 14338+ || au_test_ubifs(sb)
4a4d8108 14339+ || au_test_hfsplus(sb);
1facf9fc 14340+}
14341+
14342+/*
14343+ * filesystems which sets S_NOATIME and S_NOCMTIME.
14344+ */
14345+static inline int au_test_fs_notime(struct super_block *sb)
14346+{
14347+ return au_test_nfs(sb)
14348+ || au_test_fuse(sb)
dece6358 14349+ || au_test_ubifs(sb)
1facf9fc 14350+ /* || au_test_cifs(sb) */ /* untested */
1facf9fc 14351+ ;
14352+}
14353+
14354+/*
14355+ * filesystems which requires replacing i_mapping.
14356+ */
14357+static inline int au_test_fs_bad_mapping(struct super_block *sb)
14358+{
dece6358
AM
14359+ return au_test_fuse(sb)
14360+ || au_test_ubifs(sb);
1facf9fc 14361+}
14362+
14363+/* temporary support for i#1 in cramfs */
14364+static inline int au_test_fs_unique_ino(struct inode *inode)
14365+{
14366+ if (au_test_cramfs(inode->i_sb))
14367+ return inode->i_ino != 1;
14368+ return 1;
14369+}
14370+
14371+/* ---------------------------------------------------------------------- */
14372+
14373+/*
14374+ * the filesystem where the xino files placed must support i/o after unlink and
14375+ * maintain i_size and i_blocks.
14376+ */
14377+static inline int au_test_fs_bad_xino(struct super_block *sb)
14378+{
14379+ return au_test_fs_remote(sb)
14380+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 14381+ /* don't want unnecessary work for xino */
14382+ || au_test_aufs(sb)
1308ab2a 14383+ || au_test_ecryptfs(sb)
14384+ || au_test_nilfs(sb);
1facf9fc 14385+}
14386+
14387+static inline int au_test_fs_trunc_xino(struct super_block *sb)
14388+{
14389+ return au_test_tmpfs(sb)
14390+ || au_test_ramfs(sb);
14391+}
14392+
14393+/*
14394+ * test if the @sb is real-readonly.
14395+ */
14396+static inline int au_test_fs_rr(struct super_block *sb)
14397+{
14398+ return au_test_squashfs(sb)
14399+ || au_test_iso9660(sb)
14400+ || au_test_cramfs(sb)
14401+ || au_test_romfs(sb);
14402+}
14403+
14404+#endif /* __KERNEL__ */
14405+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
14406diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
14407--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
2000de60 14408+++ linux/fs/aufs/hfsnotify.c 2015-03-27 21:56:35.463461668 +0100
c1595e42 14409@@ -0,0 +1,288 @@
1facf9fc 14410+/*
2000de60 14411+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 14412+ *
14413+ * This program, aufs is free software; you can redistribute it and/or modify
14414+ * it under the terms of the GNU General Public License as published by
14415+ * the Free Software Foundation; either version 2 of the License, or
14416+ * (at your option) any later version.
dece6358
AM
14417+ *
14418+ * This program is distributed in the hope that it will be useful,
14419+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14420+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14421+ * GNU General Public License for more details.
14422+ *
14423+ * You should have received a copy of the GNU General Public License
523b37e3 14424+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14425+ */
14426+
14427+/*
4a4d8108 14428+ * fsnotify for the lower directories
1facf9fc 14429+ */
14430+
14431+#include "aufs.h"
14432+
4a4d8108
AM
14433+/* FS_IN_IGNORED is unnecessary */
14434+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
14435+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 14436+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 14437+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 14438+
0c5527e5 14439+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 14440+{
0c5527e5
AM
14441+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
14442+ hn_mark);
4a4d8108 14443+ AuDbg("here\n");
7eafdf33 14444+ au_cache_free_hnotify(hn);
076b876e 14445+ smp_mb__before_atomic();
1716fcea
AM
14446+ if (atomic64_dec_and_test(&au_hfsn_ifree))
14447+ wake_up(&au_hfsn_wq);
4a4d8108 14448+}
1facf9fc 14449+
027c5e7a 14450+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 14451+{
1716fcea 14452+ int err;
027c5e7a
AM
14453+ struct au_hnotify *hn;
14454+ struct super_block *sb;
14455+ struct au_branch *br;
0c5527e5 14456+ struct fsnotify_mark *mark;
027c5e7a 14457+ aufs_bindex_t bindex;
1facf9fc 14458+
027c5e7a
AM
14459+ hn = hinode->hi_notify;
14460+ sb = hn->hn_aufs_inode->i_sb;
14461+ bindex = au_br_index(sb, hinode->hi_id);
14462+ br = au_sbr(sb, bindex);
1716fcea
AM
14463+ AuDebugOn(!br->br_hfsn);
14464+
0c5527e5
AM
14465+ mark = &hn->hn_mark;
14466+ fsnotify_init_mark(mark, au_hfsn_free_mark);
14467+ mark->mask = AuHfsnMask;
7f207e10
AM
14468+ /*
14469+ * by udba rename or rmdir, aufs assign a new inode to the known
14470+ * h_inode, so specify 1 to allow dups.
14471+ */
c1595e42 14472+ lockdep_off();
1716fcea 14473+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 14474+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
14475+ /* even if err */
14476+ fsnotify_put_mark(mark);
c1595e42 14477+ lockdep_on();
1716fcea
AM
14478+
14479+ return err;
1facf9fc 14480+}
14481+
7eafdf33 14482+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 14483+{
0c5527e5 14484+ struct fsnotify_mark *mark;
7eafdf33 14485+ unsigned long long ull;
1716fcea 14486+ struct fsnotify_group *group;
7eafdf33
AM
14487+
14488+ ull = atomic64_inc_return(&au_hfsn_ifree);
14489+ BUG_ON(!ull);
953406b4 14490+
0c5527e5 14491+ mark = &hn->hn_mark;
1716fcea
AM
14492+ spin_lock(&mark->lock);
14493+ group = mark->group;
14494+ fsnotify_get_group(group);
14495+ spin_unlock(&mark->lock);
c1595e42 14496+ lockdep_off();
1716fcea
AM
14497+ fsnotify_destroy_mark(mark, group);
14498+ fsnotify_put_group(group);
c1595e42 14499+ lockdep_on();
7f207e10 14500+
7eafdf33
AM
14501+ /* free hn by myself */
14502+ return 0;
1facf9fc 14503+}
14504+
14505+/* ---------------------------------------------------------------------- */
14506+
4a4d8108 14507+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 14508+{
0c5527e5 14509+ struct fsnotify_mark *mark;
1facf9fc 14510+
0c5527e5
AM
14511+ mark = &hinode->hi_notify->hn_mark;
14512+ spin_lock(&mark->lock);
1facf9fc 14513+ if (do_set) {
0c5527e5
AM
14514+ AuDebugOn(mark->mask & AuHfsnMask);
14515+ mark->mask |= AuHfsnMask;
1facf9fc 14516+ } else {
0c5527e5
AM
14517+ AuDebugOn(!(mark->mask & AuHfsnMask));
14518+ mark->mask &= ~AuHfsnMask;
1facf9fc 14519+ }
0c5527e5 14520+ spin_unlock(&mark->lock);
4a4d8108 14521+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 14522+}
14523+
4a4d8108 14524+/* ---------------------------------------------------------------------- */
1facf9fc 14525+
4a4d8108
AM
14526+/* #define AuDbgHnotify */
14527+#ifdef AuDbgHnotify
14528+static char *au_hfsn_name(u32 mask)
14529+{
14530+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
14531+#define test_ret(flag) \
14532+ do { \
14533+ if (mask & flag) \
14534+ return #flag; \
14535+ } while (0)
4a4d8108
AM
14536+ test_ret(FS_ACCESS);
14537+ test_ret(FS_MODIFY);
14538+ test_ret(FS_ATTRIB);
14539+ test_ret(FS_CLOSE_WRITE);
14540+ test_ret(FS_CLOSE_NOWRITE);
14541+ test_ret(FS_OPEN);
14542+ test_ret(FS_MOVED_FROM);
14543+ test_ret(FS_MOVED_TO);
14544+ test_ret(FS_CREATE);
14545+ test_ret(FS_DELETE);
14546+ test_ret(FS_DELETE_SELF);
14547+ test_ret(FS_MOVE_SELF);
14548+ test_ret(FS_UNMOUNT);
14549+ test_ret(FS_Q_OVERFLOW);
14550+ test_ret(FS_IN_IGNORED);
14551+ test_ret(FS_IN_ISDIR);
14552+ test_ret(FS_IN_ONESHOT);
14553+ test_ret(FS_EVENT_ON_CHILD);
14554+ return "";
14555+#undef test_ret
14556+#else
14557+ return "??";
14558+#endif
1facf9fc 14559+}
4a4d8108 14560+#endif
1facf9fc 14561+
14562+/* ---------------------------------------------------------------------- */
14563+
1716fcea
AM
14564+static void au_hfsn_free_group(struct fsnotify_group *group)
14565+{
14566+ struct au_br_hfsnotify *hfsn = group->private;
14567+
14568+ AuDbg("here\n");
14569+ kfree(hfsn);
14570+}
14571+
4a4d8108 14572+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 14573+ struct inode *inode,
0c5527e5
AM
14574+ struct fsnotify_mark *inode_mark,
14575+ struct fsnotify_mark *vfsmount_mark,
fb47a38f
JR
14576+ u32 mask, void *data, int data_type,
14577+ const unsigned char *file_name, u32 cookie)
1facf9fc 14578+{
14579+ int err;
4a4d8108
AM
14580+ struct au_hnotify *hnotify;
14581+ struct inode *h_dir, *h_inode;
fb47a38f 14582+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
4a4d8108 14583+
fb47a38f 14584+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 14585+
14586+ err = 0;
0c5527e5 14587+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 14588+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 14589+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 14590+ goto out;
1facf9fc 14591+
fb47a38f
JR
14592+ h_dir = inode;
14593+ h_inode = NULL;
4a4d8108 14594+#ifdef AuDbgHnotify
392086de 14595+ au_debug_on();
4a4d8108
AM
14596+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
14597+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
14598+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
14599+ h_dir->i_ino, mask, au_hfsn_name(mask),
14600+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
14601+ /* WARN_ON(1); */
1facf9fc 14602+ }
392086de 14603+ au_debug_off();
1facf9fc 14604+#endif
4a4d8108 14605+
0c5527e5
AM
14606+ AuDebugOn(!inode_mark);
14607+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
14608+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 14609+
4a4d8108
AM
14610+out:
14611+ return err;
14612+}
1facf9fc 14613+
4a4d8108 14614+static struct fsnotify_ops au_hfsn_ops = {
1716fcea
AM
14615+ .handle_event = au_hfsn_handle_event,
14616+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
14617+};
14618+
14619+/* ---------------------------------------------------------------------- */
14620+
027c5e7a
AM
14621+static void au_hfsn_fin_br(struct au_branch *br)
14622+{
1716fcea 14623+ struct au_br_hfsnotify *hfsn;
027c5e7a 14624+
1716fcea 14625+ hfsn = br->br_hfsn;
c1595e42
JR
14626+ if (hfsn) {
14627+ lockdep_off();
1716fcea 14628+ fsnotify_put_group(hfsn->hfsn_group);
c1595e42
JR
14629+ lockdep_on();
14630+ }
027c5e7a
AM
14631+}
14632+
1716fcea 14633+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
14634+{
14635+ int err;
1716fcea
AM
14636+ struct fsnotify_group *group;
14637+ struct au_br_hfsnotify *hfsn;
1facf9fc 14638+
4a4d8108 14639+ err = 0;
1716fcea
AM
14640+ br->br_hfsn = NULL;
14641+ if (!au_br_hnotifyable(perm))
027c5e7a 14642+ goto out;
027c5e7a 14643+
1716fcea
AM
14644+ err = -ENOMEM;
14645+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
14646+ if (unlikely(!hfsn))
027c5e7a
AM
14647+ goto out;
14648+
1716fcea
AM
14649+ err = 0;
14650+ group = fsnotify_alloc_group(&au_hfsn_ops);
14651+ if (IS_ERR(group)) {
14652+ err = PTR_ERR(group);
0c5527e5 14653+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 14654+ goto out_hfsn;
4a4d8108 14655+ }
1facf9fc 14656+
1716fcea
AM
14657+ group->private = hfsn;
14658+ hfsn->hfsn_group = group;
14659+ br->br_hfsn = hfsn;
14660+ goto out; /* success */
14661+
14662+out_hfsn:
14663+ kfree(hfsn);
027c5e7a 14664+out:
1716fcea
AM
14665+ return err;
14666+}
14667+
14668+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
14669+{
14670+ int err;
14671+
14672+ err = 0;
14673+ if (!br->br_hfsn)
14674+ err = au_hfsn_init_br(br, perm);
14675+
1facf9fc 14676+ return err;
14677+}
14678+
7eafdf33
AM
14679+/* ---------------------------------------------------------------------- */
14680+
14681+static void au_hfsn_fin(void)
14682+{
14683+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
14684+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
14685+}
14686+
4a4d8108
AM
14687+const struct au_hnotify_op au_hnotify_op = {
14688+ .ctl = au_hfsn_ctl,
14689+ .alloc = au_hfsn_alloc,
14690+ .free = au_hfsn_free,
1facf9fc 14691+
7eafdf33
AM
14692+ .fin = au_hfsn_fin,
14693+
027c5e7a
AM
14694+ .reset_br = au_hfsn_reset_br,
14695+ .fin_br = au_hfsn_fin_br,
14696+ .init_br = au_hfsn_init_br
4a4d8108 14697+};
7f207e10
AM
14698diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
14699--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
2000de60 14700+++ linux/fs/aufs/hfsplus.c 2015-03-27 21:56:35.463461668 +0100
523b37e3 14701@@ -0,0 +1,56 @@
4a4d8108 14702+/*
2000de60 14703+ * Copyright (C) 2010-2015 Junjiro R. Okajima
4a4d8108
AM
14704+ *
14705+ * This program, aufs is free software; you can redistribute it and/or modify
14706+ * it under the terms of the GNU General Public License as published by
14707+ * the Free Software Foundation; either version 2 of the License, or
14708+ * (at your option) any later version.
14709+ *
14710+ * This program is distributed in the hope that it will be useful,
14711+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14712+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14713+ * GNU General Public License for more details.
14714+ *
14715+ * You should have received a copy of the GNU General Public License
523b37e3 14716+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 14717+ */
1facf9fc 14718+
4a4d8108
AM
14719+/*
14720+ * special support for filesystems which aqucires an inode mutex
14721+ * at final closing a file, eg, hfsplus.
14722+ *
14723+ * This trick is very simple and stupid, just to open the file before really
14724+ * neceeary open to tell hfsplus that this is not the final closing.
14725+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
14726+ * and au_h_open_post() after releasing it.
14727+ */
1facf9fc 14728+
4a4d8108 14729+#include "aufs.h"
1facf9fc 14730+
392086de
AM
14731+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
14732+ int force_wr)
4a4d8108
AM
14733+{
14734+ struct file *h_file;
14735+ struct dentry *h_dentry;
1facf9fc 14736+
4a4d8108
AM
14737+ h_dentry = au_h_dptr(dentry, bindex);
14738+ AuDebugOn(!h_dentry);
14739+ AuDebugOn(!h_dentry->d_inode);
4a4d8108
AM
14740+
14741+ h_file = NULL;
14742+ if (au_test_hfsplus(h_dentry->d_sb)
14743+ && S_ISREG(h_dentry->d_inode->i_mode))
14744+ h_file = au_h_open(dentry, bindex,
14745+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 14746+ /*file*/NULL, force_wr);
4a4d8108 14747+ return h_file;
1facf9fc 14748+}
14749+
4a4d8108
AM
14750+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
14751+ struct file *h_file)
14752+{
14753+ if (h_file) {
14754+ fput(h_file);
14755+ au_sbr_put(dentry->d_sb, bindex);
14756+ }
14757+}
7f207e10
AM
14758diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
14759--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
2000de60 14760+++ linux/fs/aufs/hnotify.c 2015-03-27 21:56:35.463461668 +0100
076b876e 14761@@ -0,0 +1,714 @@
e49829fe 14762+/*
2000de60 14763+ * Copyright (C) 2005-2015 Junjiro R. Okajima
e49829fe
JR
14764+ *
14765+ * This program, aufs is free software; you can redistribute it and/or modify
14766+ * it under the terms of the GNU General Public License as published by
14767+ * the Free Software Foundation; either version 2 of the License, or
14768+ * (at your option) any later version.
14769+ *
14770+ * This program is distributed in the hope that it will be useful,
14771+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14772+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14773+ * GNU General Public License for more details.
14774+ *
14775+ * You should have received a copy of the GNU General Public License
523b37e3 14776+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
14777+ */
14778+
14779+/*
7f207e10 14780+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
14781+ */
14782+
14783+#include "aufs.h"
14784+
027c5e7a 14785+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
14786+{
14787+ int err;
7f207e10 14788+ struct au_hnotify *hn;
1facf9fc 14789+
4a4d8108
AM
14790+ err = -ENOMEM;
14791+ hn = au_cache_alloc_hnotify();
14792+ if (hn) {
14793+ hn->hn_aufs_inode = inode;
027c5e7a
AM
14794+ hinode->hi_notify = hn;
14795+ err = au_hnotify_op.alloc(hinode);
14796+ AuTraceErr(err);
14797+ if (unlikely(err)) {
14798+ hinode->hi_notify = NULL;
4a4d8108
AM
14799+ au_cache_free_hnotify(hn);
14800+ /*
14801+ * The upper dir was removed by udba, but the same named
14802+ * dir left. In this case, aufs assignes a new inode
14803+ * number and set the monitor again.
14804+ * For the lower dir, the old monitnor is still left.
14805+ */
14806+ if (err == -EEXIST)
14807+ err = 0;
14808+ }
1308ab2a 14809+ }
1308ab2a 14810+
027c5e7a 14811+ AuTraceErr(err);
1308ab2a 14812+ return err;
dece6358 14813+}
1facf9fc 14814+
4a4d8108 14815+void au_hn_free(struct au_hinode *hinode)
dece6358 14816+{
4a4d8108 14817+ struct au_hnotify *hn;
1facf9fc 14818+
4a4d8108
AM
14819+ hn = hinode->hi_notify;
14820+ if (hn) {
4a4d8108 14821+ hinode->hi_notify = NULL;
7eafdf33
AM
14822+ if (au_hnotify_op.free(hinode, hn))
14823+ au_cache_free_hnotify(hn);
4a4d8108
AM
14824+ }
14825+}
dece6358 14826+
4a4d8108 14827+/* ---------------------------------------------------------------------- */
dece6358 14828+
4a4d8108
AM
14829+void au_hn_ctl(struct au_hinode *hinode, int do_set)
14830+{
14831+ if (hinode->hi_notify)
14832+ au_hnotify_op.ctl(hinode, do_set);
14833+}
14834+
14835+void au_hn_reset(struct inode *inode, unsigned int flags)
14836+{
14837+ aufs_bindex_t bindex, bend;
14838+ struct inode *hi;
14839+ struct dentry *iwhdentry;
1facf9fc 14840+
1308ab2a 14841+ bend = au_ibend(inode);
4a4d8108
AM
14842+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14843+ hi = au_h_iptr(inode, bindex);
14844+ if (!hi)
14845+ continue;
1308ab2a 14846+
4a4d8108
AM
14847+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
14848+ iwhdentry = au_hi_wh(inode, bindex);
14849+ if (iwhdentry)
14850+ dget(iwhdentry);
14851+ au_igrab(hi);
14852+ au_set_h_iptr(inode, bindex, NULL, 0);
14853+ au_set_h_iptr(inode, bindex, au_igrab(hi),
14854+ flags & ~AuHi_XINO);
14855+ iput(hi);
14856+ dput(iwhdentry);
14857+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 14858+ }
1facf9fc 14859+}
14860+
1308ab2a 14861+/* ---------------------------------------------------------------------- */
1facf9fc 14862+
4a4d8108 14863+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 14864+{
4a4d8108
AM
14865+ int err;
14866+ aufs_bindex_t bindex, bend, bfound, bstart;
14867+ struct inode *h_i;
1facf9fc 14868+
4a4d8108
AM
14869+ err = 0;
14870+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14871+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14872+ goto out;
14873+ }
1facf9fc 14874+
4a4d8108
AM
14875+ bfound = -1;
14876+ bend = au_ibend(inode);
14877+ bstart = au_ibstart(inode);
14878+#if 0 /* reserved for future use */
14879+ if (bindex == bend) {
14880+ /* keep this ino in rename case */
14881+ goto out;
14882+ }
14883+#endif
14884+ for (bindex = bstart; bindex <= bend; bindex++)
14885+ if (au_h_iptr(inode, bindex) == h_inode) {
14886+ bfound = bindex;
14887+ break;
14888+ }
14889+ if (bfound < 0)
1308ab2a 14890+ goto out;
1facf9fc 14891+
4a4d8108
AM
14892+ for (bindex = bstart; bindex <= bend; bindex++) {
14893+ h_i = au_h_iptr(inode, bindex);
14894+ if (!h_i)
14895+ continue;
1facf9fc 14896+
4a4d8108
AM
14897+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
14898+ /* ignore this error */
14899+ /* bad action? */
1facf9fc 14900+ }
1facf9fc 14901+
4a4d8108 14902+ /* children inode number will be broken */
1facf9fc 14903+
4f0767ce 14904+out:
4a4d8108
AM
14905+ AuTraceErr(err);
14906+ return err;
1facf9fc 14907+}
14908+
4a4d8108 14909+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 14910+{
4a4d8108
AM
14911+ int err, i, j, ndentry;
14912+ struct au_dcsub_pages dpages;
14913+ struct au_dpage *dpage;
14914+ struct dentry **dentries;
1facf9fc 14915+
4a4d8108
AM
14916+ err = au_dpages_init(&dpages, GFP_NOFS);
14917+ if (unlikely(err))
14918+ goto out;
14919+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
14920+ if (unlikely(err))
14921+ goto out_dpages;
1facf9fc 14922+
4a4d8108
AM
14923+ for (i = 0; i < dpages.ndpage; i++) {
14924+ dpage = dpages.dpages + i;
14925+ dentries = dpage->dentries;
14926+ ndentry = dpage->ndentry;
14927+ for (j = 0; j < ndentry; j++) {
14928+ struct dentry *d;
14929+
14930+ d = dentries[j];
14931+ if (IS_ROOT(d))
14932+ continue;
14933+
4a4d8108
AM
14934+ au_digen_dec(d);
14935+ if (d->d_inode)
14936+ /* todo: reset children xino?
14937+ cached children only? */
14938+ au_iigen_dec(d->d_inode);
1308ab2a 14939+ }
dece6358 14940+ }
1facf9fc 14941+
4f0767ce 14942+out_dpages:
4a4d8108 14943+ au_dpages_free(&dpages);
dece6358 14944+
027c5e7a 14945+#if 0
4a4d8108
AM
14946+ /* discard children */
14947+ dentry_unhash(dentry);
14948+ dput(dentry);
027c5e7a 14949+#endif
4f0767ce 14950+out:
dece6358
AM
14951+ return err;
14952+}
14953+
1308ab2a 14954+/*
4a4d8108 14955+ * return 0 if processed.
1308ab2a 14956+ */
4a4d8108
AM
14957+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
14958+ const unsigned int isdir)
dece6358 14959+{
1308ab2a 14960+ int err;
4a4d8108
AM
14961+ struct dentry *d;
14962+ struct qstr *dname;
1facf9fc 14963+
4a4d8108
AM
14964+ err = 1;
14965+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14966+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14967+ err = 0;
14968+ goto out;
14969+ }
dece6358 14970+
4a4d8108
AM
14971+ if (!isdir) {
14972+ AuDebugOn(!name);
14973+ au_iigen_dec(inode);
027c5e7a 14974+ spin_lock(&inode->i_lock);
c1595e42 14975+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 14976+ spin_lock(&d->d_lock);
4a4d8108
AM
14977+ dname = &d->d_name;
14978+ if (dname->len != nlen
027c5e7a
AM
14979+ && memcmp(dname->name, name, nlen)) {
14980+ spin_unlock(&d->d_lock);
4a4d8108 14981+ continue;
027c5e7a 14982+ }
4a4d8108 14983+ err = 0;
4a4d8108
AM
14984+ au_digen_dec(d);
14985+ spin_unlock(&d->d_lock);
14986+ break;
1facf9fc 14987+ }
027c5e7a 14988+ spin_unlock(&inode->i_lock);
1308ab2a 14989+ } else {
027c5e7a 14990+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
c1595e42 14991+ d = d_find_any_alias(inode);
4a4d8108
AM
14992+ if (!d) {
14993+ au_iigen_dec(inode);
14994+ goto out;
14995+ }
1facf9fc 14996+
027c5e7a 14997+ spin_lock(&d->d_lock);
4a4d8108 14998+ dname = &d->d_name;
027c5e7a
AM
14999+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
15000+ spin_unlock(&d->d_lock);
4a4d8108 15001+ err = hn_gen_tree(d);
027c5e7a
AM
15002+ spin_lock(&d->d_lock);
15003+ }
15004+ spin_unlock(&d->d_lock);
4a4d8108
AM
15005+ dput(d);
15006+ }
1facf9fc 15007+
4f0767ce 15008+out:
4a4d8108 15009+ AuTraceErr(err);
1308ab2a 15010+ return err;
15011+}
dece6358 15012+
4a4d8108 15013+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 15014+{
4a4d8108
AM
15015+ int err;
15016+ struct inode *inode;
1facf9fc 15017+
4a4d8108
AM
15018+ inode = dentry->d_inode;
15019+ if (IS_ROOT(dentry)
15020+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
15021+ ) {
0c3ec466 15022+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
15023+ return 0;
15024+ }
1308ab2a 15025+
4a4d8108
AM
15026+ err = 0;
15027+ if (!isdir) {
4a4d8108
AM
15028+ au_digen_dec(dentry);
15029+ if (inode)
15030+ au_iigen_dec(inode);
15031+ } else {
027c5e7a 15032+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
15033+ if (inode)
15034+ err = hn_gen_tree(dentry);
15035+ }
15036+
15037+ AuTraceErr(err);
15038+ return err;
1facf9fc 15039+}
15040+
4a4d8108 15041+/* ---------------------------------------------------------------------- */
1facf9fc 15042+
4a4d8108
AM
15043+/* hnotify job flags */
15044+#define AuHnJob_XINO0 1
15045+#define AuHnJob_GEN (1 << 1)
15046+#define AuHnJob_DIRENT (1 << 2)
15047+#define AuHnJob_ISDIR (1 << 3)
15048+#define AuHnJob_TRYXINO0 (1 << 4)
15049+#define AuHnJob_MNTPNT (1 << 5)
15050+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
15051+#define au_fset_hnjob(flags, name) \
15052+ do { (flags) |= AuHnJob_##name; } while (0)
15053+#define au_fclr_hnjob(flags, name) \
15054+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 15055+
4a4d8108
AM
15056+enum {
15057+ AuHn_CHILD,
15058+ AuHn_PARENT,
15059+ AuHnLast
15060+};
1facf9fc 15061+
4a4d8108
AM
15062+struct au_hnotify_args {
15063+ struct inode *h_dir, *dir, *h_child_inode;
15064+ u32 mask;
15065+ unsigned int flags[AuHnLast];
15066+ unsigned int h_child_nlen;
15067+ char h_child_name[];
15068+};
1facf9fc 15069+
4a4d8108
AM
15070+struct hn_job_args {
15071+ unsigned int flags;
15072+ struct inode *inode, *h_inode, *dir, *h_dir;
15073+ struct dentry *dentry;
15074+ char *h_name;
15075+ int h_nlen;
15076+};
1308ab2a 15077+
4a4d8108
AM
15078+static int hn_job(struct hn_job_args *a)
15079+{
15080+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 15081+ int e;
1308ab2a 15082+
4a4d8108
AM
15083+ /* reset xino */
15084+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
15085+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 15086+
4a4d8108
AM
15087+ if (au_ftest_hnjob(a->flags, TRYXINO0)
15088+ && a->inode
15089+ && a->h_inode) {
15090+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
38d290e6
JR
15091+ if (!a->h_inode->i_nlink
15092+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108
AM
15093+ hn_xino(a->inode, a->h_inode); /* ignore this error */
15094+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 15095+ }
1facf9fc 15096+
4a4d8108
AM
15097+ /* make the generation obsolete */
15098+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 15099+ e = -1;
4a4d8108 15100+ if (a->inode)
076b876e 15101+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 15102+ isdir);
076b876e 15103+ if (e && a->dentry)
4a4d8108
AM
15104+ hn_gen_by_name(a->dentry, isdir);
15105+ /* ignore this error */
1facf9fc 15106+ }
1facf9fc 15107+
4a4d8108
AM
15108+ /* make dir entries obsolete */
15109+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
15110+ struct au_vdir *vdir;
1facf9fc 15111+
4a4d8108
AM
15112+ vdir = au_ivdir(a->inode);
15113+ if (vdir)
15114+ vdir->vd_jiffy = 0;
15115+ /* IMustLock(a->inode); */
15116+ /* a->inode->i_version++; */
15117+ }
1facf9fc 15118+
4a4d8108
AM
15119+ /* can do nothing but warn */
15120+ if (au_ftest_hnjob(a->flags, MNTPNT)
15121+ && a->dentry
15122+ && d_mountpoint(a->dentry))
523b37e3 15123+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 15124+
4a4d8108 15125+ return 0;
1308ab2a 15126+}
1facf9fc 15127+
1308ab2a 15128+/* ---------------------------------------------------------------------- */
1facf9fc 15129+
4a4d8108
AM
15130+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
15131+ struct inode *dir)
1308ab2a 15132+{
4a4d8108
AM
15133+ struct dentry *dentry, *d, *parent;
15134+ struct qstr *dname;
1308ab2a 15135+
c1595e42 15136+ parent = d_find_any_alias(dir);
4a4d8108
AM
15137+ if (!parent)
15138+ return NULL;
1308ab2a 15139+
4a4d8108 15140+ dentry = NULL;
027c5e7a 15141+ spin_lock(&parent->d_lock);
c1595e42 15142+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
523b37e3 15143+ /* AuDbg("%pd\n", d); */
027c5e7a 15144+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
15145+ dname = &d->d_name;
15146+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
15147+ goto cont_unlock;
15148+ if (au_di(d))
15149+ au_digen_dec(d);
15150+ else
15151+ goto cont_unlock;
c1595e42 15152+ if (au_dcount(d) > 0) {
027c5e7a 15153+ dentry = dget_dlock(d);
4a4d8108 15154+ spin_unlock(&d->d_lock);
027c5e7a 15155+ break;
dece6358 15156+ }
1facf9fc 15157+
f6b6e03d 15158+cont_unlock:
027c5e7a 15159+ spin_unlock(&d->d_lock);
1308ab2a 15160+ }
027c5e7a 15161+ spin_unlock(&parent->d_lock);
4a4d8108 15162+ dput(parent);
1facf9fc 15163+
4a4d8108
AM
15164+ if (dentry)
15165+ di_write_lock_child(dentry);
1308ab2a 15166+
4a4d8108
AM
15167+ return dentry;
15168+}
dece6358 15169+
4a4d8108
AM
15170+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
15171+ aufs_bindex_t bindex, ino_t h_ino)
15172+{
15173+ struct inode *inode;
15174+ ino_t ino;
15175+ int err;
15176+
15177+ inode = NULL;
15178+ err = au_xino_read(sb, bindex, h_ino, &ino);
15179+ if (!err && ino)
15180+ inode = ilookup(sb, ino);
15181+ if (!inode)
15182+ goto out;
15183+
15184+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 15185+ pr_warn("wrong root branch\n");
4a4d8108
AM
15186+ iput(inode);
15187+ inode = NULL;
15188+ goto out;
1308ab2a 15189+ }
15190+
4a4d8108 15191+ ii_write_lock_child(inode);
1308ab2a 15192+
4f0767ce 15193+out:
4a4d8108 15194+ return inode;
dece6358
AM
15195+}
15196+
4a4d8108 15197+static void au_hn_bh(void *_args)
1facf9fc 15198+{
4a4d8108
AM
15199+ struct au_hnotify_args *a = _args;
15200+ struct super_block *sb;
15201+ aufs_bindex_t bindex, bend, bfound;
15202+ unsigned char xino, try_iput;
1facf9fc 15203+ int err;
1308ab2a 15204+ struct inode *inode;
4a4d8108
AM
15205+ ino_t h_ino;
15206+ struct hn_job_args args;
15207+ struct dentry *dentry;
15208+ struct au_sbinfo *sbinfo;
1facf9fc 15209+
4a4d8108
AM
15210+ AuDebugOn(!_args);
15211+ AuDebugOn(!a->h_dir);
15212+ AuDebugOn(!a->dir);
15213+ AuDebugOn(!a->mask);
15214+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
15215+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
15216+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 15217+
4a4d8108
AM
15218+ inode = NULL;
15219+ dentry = NULL;
15220+ /*
15221+ * do not lock a->dir->i_mutex here
15222+ * because of d_revalidate() may cause a deadlock.
15223+ */
15224+ sb = a->dir->i_sb;
15225+ AuDebugOn(!sb);
15226+ sbinfo = au_sbi(sb);
15227+ AuDebugOn(!sbinfo);
7f207e10 15228+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 15229+
4a4d8108
AM
15230+ ii_read_lock_parent(a->dir);
15231+ bfound = -1;
15232+ bend = au_ibend(a->dir);
15233+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
15234+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
15235+ bfound = bindex;
15236+ break;
15237+ }
15238+ ii_read_unlock(a->dir);
15239+ if (unlikely(bfound < 0))
15240+ goto out;
1facf9fc 15241+
4a4d8108
AM
15242+ xino = !!au_opt_test(au_mntflags(sb), XINO);
15243+ h_ino = 0;
15244+ if (a->h_child_inode)
15245+ h_ino = a->h_child_inode->i_ino;
1facf9fc 15246+
4a4d8108
AM
15247+ if (a->h_child_nlen
15248+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
15249+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
15250+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
15251+ a->dir);
15252+ try_iput = 0;
15253+ if (dentry)
15254+ inode = dentry->d_inode;
15255+ if (xino && !inode && h_ino
15256+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
15257+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
15258+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
15259+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
15260+ try_iput = 1;
15261+ }
1facf9fc 15262+
4a4d8108
AM
15263+ args.flags = a->flags[AuHn_CHILD];
15264+ args.dentry = dentry;
15265+ args.inode = inode;
15266+ args.h_inode = a->h_child_inode;
15267+ args.dir = a->dir;
15268+ args.h_dir = a->h_dir;
15269+ args.h_name = a->h_child_name;
15270+ args.h_nlen = a->h_child_nlen;
15271+ err = hn_job(&args);
15272+ if (dentry) {
027c5e7a 15273+ if (au_di(dentry))
4a4d8108
AM
15274+ di_write_unlock(dentry);
15275+ dput(dentry);
15276+ }
15277+ if (inode && try_iput) {
15278+ ii_write_unlock(inode);
15279+ iput(inode);
15280+ }
1facf9fc 15281+
4a4d8108
AM
15282+ ii_write_lock_parent(a->dir);
15283+ args.flags = a->flags[AuHn_PARENT];
15284+ args.dentry = NULL;
15285+ args.inode = a->dir;
15286+ args.h_inode = a->h_dir;
15287+ args.dir = NULL;
15288+ args.h_dir = NULL;
15289+ args.h_name = NULL;
15290+ args.h_nlen = 0;
15291+ err = hn_job(&args);
15292+ ii_write_unlock(a->dir);
1facf9fc 15293+
4f0767ce 15294+out:
4a4d8108
AM
15295+ iput(a->h_child_inode);
15296+ iput(a->h_dir);
15297+ iput(a->dir);
027c5e7a
AM
15298+ si_write_unlock(sb);
15299+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 15300+ kfree(a);
dece6358 15301+}
1facf9fc 15302+
4a4d8108
AM
15303+/* ---------------------------------------------------------------------- */
15304+
15305+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15306+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 15307+{
4a4d8108 15308+ int err, len;
53392da6 15309+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
15310+ unsigned char isdir, isroot, wh;
15311+ struct inode *dir;
15312+ struct au_hnotify_args *args;
15313+ char *p, *h_child_name;
dece6358 15314+
1308ab2a 15315+ err = 0;
4a4d8108
AM
15316+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
15317+ dir = igrab(hnotify->hn_aufs_inode);
15318+ if (!dir)
15319+ goto out;
1facf9fc 15320+
4a4d8108
AM
15321+ isroot = (dir->i_ino == AUFS_ROOT_INO);
15322+ wh = 0;
15323+ h_child_name = (void *)h_child_qstr->name;
15324+ len = h_child_qstr->len;
15325+ if (h_child_name) {
15326+ if (len > AUFS_WH_PFX_LEN
15327+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
15328+ h_child_name += AUFS_WH_PFX_LEN;
15329+ len -= AUFS_WH_PFX_LEN;
15330+ wh = 1;
15331+ }
1facf9fc 15332+ }
dece6358 15333+
4a4d8108
AM
15334+ isdir = 0;
15335+ if (h_child_inode)
15336+ isdir = !!S_ISDIR(h_child_inode->i_mode);
15337+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
15338+ flags[AuHn_CHILD] = 0;
15339+ if (isdir)
15340+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
15341+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
15342+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
15343+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
15344+ case FS_MOVED_FROM:
15345+ case FS_MOVED_TO:
15346+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
15347+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15348+ /*FALLTHROUGH*/
15349+ case FS_CREATE:
fb47a38f 15350+ AuDebugOn(!h_child_name);
4a4d8108 15351+ break;
1facf9fc 15352+
4a4d8108
AM
15353+ case FS_DELETE:
15354+ /*
15355+ * aufs never be able to get this child inode.
15356+ * revalidation should be in d_revalidate()
15357+ * by checking i_nlink, i_generation or d_unhashed().
15358+ */
15359+ AuDebugOn(!h_child_name);
15360+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
15361+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15362+ break;
dece6358 15363+
4a4d8108
AM
15364+ default:
15365+ AuDebugOn(1);
15366+ }
1308ab2a 15367+
4a4d8108
AM
15368+ if (wh)
15369+ h_child_inode = NULL;
1308ab2a 15370+
4a4d8108
AM
15371+ err = -ENOMEM;
15372+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 15373+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
15374+ if (unlikely(!args)) {
15375+ AuErr1("no memory\n");
15376+ iput(dir);
15377+ goto out;
15378+ }
15379+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
15380+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
15381+ args->mask = mask;
15382+ args->dir = dir;
15383+ args->h_dir = igrab(h_dir);
15384+ if (h_child_inode)
15385+ h_child_inode = igrab(h_child_inode); /* can be NULL */
15386+ args->h_child_inode = h_child_inode;
15387+ args->h_child_nlen = len;
15388+ if (len) {
15389+ p = (void *)args;
15390+ p += sizeof(*args);
15391+ memcpy(p, h_child_name, len);
15392+ p[len] = 0;
1308ab2a 15393+ }
1308ab2a 15394+
38d290e6 15395+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 15396+ f = 0;
38d290e6
JR
15397+ if (!dir->i_nlink
15398+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
15399+ f = AuWkq_NEST;
15400+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
15401+ if (unlikely(err)) {
15402+ pr_err("wkq %d\n", err);
15403+ iput(args->h_child_inode);
15404+ iput(args->h_dir);
15405+ iput(args->dir);
15406+ kfree(args);
1facf9fc 15407+ }
1facf9fc 15408+
4a4d8108 15409+out:
1facf9fc 15410+ return err;
15411+}
15412+
027c5e7a
AM
15413+/* ---------------------------------------------------------------------- */
15414+
15415+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
15416+{
15417+ int err;
15418+
15419+ AuDebugOn(!(udba & AuOptMask_UDBA));
15420+
15421+ err = 0;
15422+ if (au_hnotify_op.reset_br)
15423+ err = au_hnotify_op.reset_br(udba, br, perm);
15424+
15425+ return err;
15426+}
15427+
15428+int au_hnotify_init_br(struct au_branch *br, int perm)
15429+{
15430+ int err;
15431+
15432+ err = 0;
15433+ if (au_hnotify_op.init_br)
15434+ err = au_hnotify_op.init_br(br, perm);
15435+
15436+ return err;
15437+}
15438+
15439+void au_hnotify_fin_br(struct au_branch *br)
15440+{
15441+ if (au_hnotify_op.fin_br)
15442+ au_hnotify_op.fin_br(br);
15443+}
15444+
4a4d8108
AM
15445+static void au_hn_destroy_cache(void)
15446+{
15447+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
15448+ au_cachep[AuCache_HNOTIFY] = NULL;
15449+}
1308ab2a 15450+
4a4d8108 15451+int __init au_hnotify_init(void)
1facf9fc 15452+{
1308ab2a 15453+ int err;
1308ab2a 15454+
4a4d8108
AM
15455+ err = -ENOMEM;
15456+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
15457+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
15458+ err = 0;
15459+ if (au_hnotify_op.init)
15460+ err = au_hnotify_op.init();
4a4d8108
AM
15461+ if (unlikely(err))
15462+ au_hn_destroy_cache();
1308ab2a 15463+ }
1308ab2a 15464+ AuTraceErr(err);
4a4d8108 15465+ return err;
1308ab2a 15466+}
15467+
4a4d8108 15468+void au_hnotify_fin(void)
1308ab2a 15469+{
027c5e7a
AM
15470+ if (au_hnotify_op.fin)
15471+ au_hnotify_op.fin();
4a4d8108
AM
15472+ /* cf. au_cache_fin() */
15473+ if (au_cachep[AuCache_HNOTIFY])
15474+ au_hn_destroy_cache();
dece6358 15475+}
7f207e10
AM
15476diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
15477--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
2000de60 15478+++ linux/fs/aufs/iinfo.c 2015-03-27 21:56:35.466795000 +0100
38d290e6 15479@@ -0,0 +1,277 @@
dece6358 15480+/*
2000de60 15481+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
15482+ *
15483+ * This program, aufs is free software; you can redistribute it and/or modify
15484+ * it under the terms of the GNU General Public License as published by
15485+ * the Free Software Foundation; either version 2 of the License, or
15486+ * (at your option) any later version.
15487+ *
15488+ * This program is distributed in the hope that it will be useful,
15489+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15490+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15491+ * GNU General Public License for more details.
15492+ *
15493+ * You should have received a copy of the GNU General Public License
523b37e3 15494+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15495+ */
1facf9fc 15496+
dece6358 15497+/*
4a4d8108 15498+ * inode private data
dece6358 15499+ */
1facf9fc 15500+
1308ab2a 15501+#include "aufs.h"
1facf9fc 15502+
4a4d8108 15503+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15504+{
4a4d8108 15505+ struct inode *h_inode;
1facf9fc 15506+
4a4d8108 15507+ IiMustAnyLock(inode);
1facf9fc 15508+
4a4d8108
AM
15509+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
15510+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15511+ return h_inode;
15512+}
1facf9fc 15513+
4a4d8108
AM
15514+/* todo: hard/soft set? */
15515+void au_hiput(struct au_hinode *hinode)
15516+{
15517+ au_hn_free(hinode);
15518+ dput(hinode->hi_whdentry);
15519+ iput(hinode->hi_inode);
15520+}
1facf9fc 15521+
4a4d8108
AM
15522+unsigned int au_hi_flags(struct inode *inode, int isdir)
15523+{
15524+ unsigned int flags;
15525+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 15526+
4a4d8108
AM
15527+ flags = 0;
15528+ if (au_opt_test(mnt_flags, XINO))
15529+ au_fset_hi(flags, XINO);
15530+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
15531+ au_fset_hi(flags, HNOTIFY);
15532+ return flags;
1facf9fc 15533+}
15534+
4a4d8108
AM
15535+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15536+ struct inode *h_inode, unsigned int flags)
1308ab2a 15537+{
4a4d8108
AM
15538+ struct au_hinode *hinode;
15539+ struct inode *hi;
15540+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 15541+
4a4d8108 15542+ IiMustWriteLock(inode);
dece6358 15543+
4a4d8108
AM
15544+ hinode = iinfo->ii_hinode + bindex;
15545+ hi = hinode->hi_inode;
15546+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15547+
15548+ if (hi)
15549+ au_hiput(hinode);
15550+ hinode->hi_inode = h_inode;
15551+ if (h_inode) {
15552+ int err;
15553+ struct super_block *sb = inode->i_sb;
15554+ struct au_branch *br;
15555+
027c5e7a
AM
15556+ AuDebugOn(inode->i_mode
15557+ && (h_inode->i_mode & S_IFMT)
15558+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
15559+ if (bindex == iinfo->ii_bstart)
15560+ au_cpup_igen(inode, h_inode);
15561+ br = au_sbr(sb, bindex);
15562+ hinode->hi_id = br->br_id;
15563+ if (au_ftest_hi(flags, XINO)) {
15564+ err = au_xino_write(sb, bindex, h_inode->i_ino,
15565+ inode->i_ino);
15566+ if (unlikely(err))
15567+ AuIOErr1("failed au_xino_write() %d\n", err);
15568+ }
15569+
15570+ if (au_ftest_hi(flags, HNOTIFY)
15571+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 15572+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
15573+ if (unlikely(err))
15574+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 15575+ }
15576+ }
4a4d8108 15577+}
dece6358 15578+
4a4d8108
AM
15579+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15580+ struct dentry *h_wh)
15581+{
15582+ struct au_hinode *hinode;
dece6358 15583+
4a4d8108
AM
15584+ IiMustWriteLock(inode);
15585+
15586+ hinode = au_ii(inode)->ii_hinode + bindex;
15587+ AuDebugOn(hinode->hi_whdentry);
15588+ hinode->hi_whdentry = h_wh;
1facf9fc 15589+}
15590+
537831f9 15591+void au_update_iigen(struct inode *inode, int half)
1308ab2a 15592+{
537831f9
AM
15593+ struct au_iinfo *iinfo;
15594+ struct au_iigen *iigen;
15595+ unsigned int sigen;
15596+
15597+ sigen = au_sigen(inode->i_sb);
15598+ iinfo = au_ii(inode);
15599+ iigen = &iinfo->ii_generation;
15600+ spin_lock(&iinfo->ii_genspin);
15601+ iigen->ig_generation = sigen;
15602+ if (half)
15603+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
15604+ else
15605+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
15606+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 15607+}
1facf9fc 15608+
4a4d8108
AM
15609+/* it may be called at remount time, too */
15610+void au_update_ibrange(struct inode *inode, int do_put_zero)
15611+{
15612+ struct au_iinfo *iinfo;
027c5e7a 15613+ aufs_bindex_t bindex, bend;
1facf9fc 15614+
4a4d8108 15615+ iinfo = au_ii(inode);
027c5e7a 15616+ if (!iinfo)
4a4d8108 15617+ return;
1facf9fc 15618+
4a4d8108 15619+ IiMustWriteLock(inode);
1facf9fc 15620+
027c5e7a 15621+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
15622+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15623+ bindex++) {
15624+ struct inode *h_i;
1facf9fc 15625+
4a4d8108 15626+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
38d290e6
JR
15627+ if (h_i
15628+ && !h_i->i_nlink
15629+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
15630+ au_set_h_iptr(inode, bindex, NULL, 0);
15631+ }
4a4d8108
AM
15632+ }
15633+
027c5e7a
AM
15634+ iinfo->ii_bstart = -1;
15635+ iinfo->ii_bend = -1;
15636+ bend = au_sbend(inode->i_sb);
15637+ for (bindex = 0; bindex <= bend; bindex++)
15638+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15639+ iinfo->ii_bstart = bindex;
4a4d8108 15640+ break;
027c5e7a
AM
15641+ }
15642+ if (iinfo->ii_bstart >= 0)
15643+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
15644+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15645+ iinfo->ii_bend = bindex;
15646+ break;
15647+ }
15648+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 15649+}
1facf9fc 15650+
dece6358 15651+/* ---------------------------------------------------------------------- */
1facf9fc 15652+
4a4d8108 15653+void au_icntnr_init_once(void *_c)
dece6358 15654+{
4a4d8108
AM
15655+ struct au_icntnr *c = _c;
15656+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 15657+ static struct lock_class_key aufs_ii;
1facf9fc 15658+
537831f9 15659+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 15660+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 15661+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
15662+ inode_init_once(&c->vfs_inode);
15663+}
1facf9fc 15664+
4a4d8108
AM
15665+int au_iinfo_init(struct inode *inode)
15666+{
15667+ struct au_iinfo *iinfo;
15668+ struct super_block *sb;
15669+ int nbr, i;
1facf9fc 15670+
4a4d8108
AM
15671+ sb = inode->i_sb;
15672+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
15673+ nbr = au_sbend(sb) + 1;
15674+ if (unlikely(nbr <= 0))
15675+ nbr = 1;
15676+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
15677+ if (iinfo->ii_hinode) {
7f207e10 15678+ au_ninodes_inc(sb);
4a4d8108
AM
15679+ for (i = 0; i < nbr; i++)
15680+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 15681+
537831f9 15682+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
15683+ iinfo->ii_bstart = -1;
15684+ iinfo->ii_bend = -1;
15685+ iinfo->ii_vdir = NULL;
15686+ return 0;
1308ab2a 15687+ }
4a4d8108
AM
15688+ return -ENOMEM;
15689+}
1facf9fc 15690+
4a4d8108
AM
15691+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
15692+{
15693+ int err, sz;
15694+ struct au_hinode *hip;
1facf9fc 15695+
4a4d8108
AM
15696+ AuRwMustWriteLock(&iinfo->ii_rwsem);
15697+
15698+ err = -ENOMEM;
15699+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
15700+ if (!sz)
15701+ sz = sizeof(*hip);
15702+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
15703+ if (hip) {
15704+ iinfo->ii_hinode = hip;
15705+ err = 0;
1308ab2a 15706+ }
4a4d8108 15707+
1308ab2a 15708+ return err;
1facf9fc 15709+}
15710+
4a4d8108 15711+void au_iinfo_fin(struct inode *inode)
1facf9fc 15712+{
4a4d8108
AM
15713+ struct au_iinfo *iinfo;
15714+ struct au_hinode *hi;
15715+ struct super_block *sb;
b752ccd1
AM
15716+ aufs_bindex_t bindex, bend;
15717+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 15718+
4a4d8108
AM
15719+ iinfo = au_ii(inode);
15720+ /* bad_inode case */
15721+ if (!iinfo)
15722+ return;
1308ab2a 15723+
b752ccd1 15724+ sb = inode->i_sb;
7f207e10 15725+ au_ninodes_dec(sb);
b752ccd1
AM
15726+ if (si_pid_test(sb))
15727+ au_xino_delete_inode(inode, unlinked);
15728+ else {
15729+ /*
15730+ * it is safe to hide the dependency between sbinfo and
15731+ * sb->s_umount.
15732+ */
15733+ lockdep_off();
15734+ si_noflush_read_lock(sb);
15735+ au_xino_delete_inode(inode, unlinked);
15736+ si_read_unlock(sb);
15737+ lockdep_on();
15738+ }
15739+
4a4d8108
AM
15740+ if (iinfo->ii_vdir)
15741+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 15742+
b752ccd1
AM
15743+ bindex = iinfo->ii_bstart;
15744+ if (bindex >= 0) {
15745+ hi = iinfo->ii_hinode + bindex;
4a4d8108 15746+ bend = iinfo->ii_bend;
b752ccd1
AM
15747+ while (bindex++ <= bend) {
15748+ if (hi->hi_inode)
4a4d8108 15749+ au_hiput(hi);
4a4d8108
AM
15750+ hi++;
15751+ }
15752+ }
4a4d8108 15753+ kfree(iinfo->ii_hinode);
027c5e7a 15754+ iinfo->ii_hinode = NULL;
4a4d8108 15755+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 15756+}
7f207e10
AM
15757diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
15758--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
15759+++ linux/fs/aufs/inode.c 2015-03-27 21:56:35.466795000 +0100
15760@@ -0,0 +1,495 @@
4a4d8108 15761+/*
2000de60 15762+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
15763+ *
15764+ * This program, aufs is free software; you can redistribute it and/or modify
15765+ * it under the terms of the GNU General Public License as published by
15766+ * the Free Software Foundation; either version 2 of the License, or
15767+ * (at your option) any later version.
15768+ *
15769+ * This program is distributed in the hope that it will be useful,
15770+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15771+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15772+ * GNU General Public License for more details.
15773+ *
15774+ * You should have received a copy of the GNU General Public License
523b37e3 15775+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15776+ */
1facf9fc 15777+
4a4d8108
AM
15778+/*
15779+ * inode functions
15780+ */
1facf9fc 15781+
4a4d8108 15782+#include "aufs.h"
1308ab2a 15783+
4a4d8108
AM
15784+struct inode *au_igrab(struct inode *inode)
15785+{
15786+ if (inode) {
15787+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 15788+ ihold(inode);
1facf9fc 15789+ }
4a4d8108
AM
15790+ return inode;
15791+}
1facf9fc 15792+
4a4d8108
AM
15793+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
15794+{
15795+ au_cpup_attr_all(inode, /*force*/0);
537831f9 15796+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
15797+ if (do_version)
15798+ inode->i_version++;
dece6358 15799+}
1facf9fc 15800+
027c5e7a 15801+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 15802+{
4a4d8108 15803+ int err, e;
027c5e7a 15804+ umode_t type;
4a4d8108 15805+ aufs_bindex_t bindex, new_bindex;
1308ab2a 15806+ struct super_block *sb;
4a4d8108 15807+ struct au_iinfo *iinfo;
027c5e7a 15808+ struct au_hinode *p, *q, tmp;
1facf9fc 15809+
4a4d8108 15810+ IiMustWriteLock(inode);
1facf9fc 15811+
027c5e7a 15812+ *update = 0;
4a4d8108 15813+ sb = inode->i_sb;
027c5e7a 15814+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
15815+ iinfo = au_ii(inode);
15816+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
15817+ if (unlikely(err))
1308ab2a 15818+ goto out;
1facf9fc 15819+
027c5e7a 15820+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 15821+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
15822+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15823+ bindex++, p++) {
15824+ if (!p->hi_inode)
15825+ continue;
1facf9fc 15826+
027c5e7a 15827+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
15828+ new_bindex = au_br_index(sb, p->hi_id);
15829+ if (new_bindex == bindex)
15830+ continue;
1facf9fc 15831+
4a4d8108 15832+ if (new_bindex < 0) {
027c5e7a 15833+ *update = 1;
4a4d8108
AM
15834+ au_hiput(p);
15835+ p->hi_inode = NULL;
15836+ continue;
1308ab2a 15837+ }
4a4d8108
AM
15838+
15839+ if (new_bindex < iinfo->ii_bstart)
15840+ iinfo->ii_bstart = new_bindex;
15841+ if (iinfo->ii_bend < new_bindex)
15842+ iinfo->ii_bend = new_bindex;
15843+ /* swap two lower inode, and loop again */
15844+ q = iinfo->ii_hinode + new_bindex;
15845+ tmp = *q;
15846+ *q = *p;
15847+ *p = tmp;
15848+ if (tmp.hi_inode) {
15849+ bindex--;
15850+ p--;
1308ab2a 15851+ }
15852+ }
4a4d8108
AM
15853+ au_update_ibrange(inode, /*do_put_zero*/0);
15854+ e = au_dy_irefresh(inode);
15855+ if (unlikely(e && !err))
15856+ err = e;
1facf9fc 15857+
4f0767ce 15858+out:
027c5e7a
AM
15859+ AuTraceErr(err);
15860+ return err;
15861+}
15862+
15863+int au_refresh_hinode_self(struct inode *inode)
15864+{
15865+ int err, update;
15866+
15867+ err = au_ii_refresh(inode, &update);
15868+ if (!err)
15869+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
15870+
15871+ AuTraceErr(err);
4a4d8108
AM
15872+ return err;
15873+}
1facf9fc 15874+
4a4d8108
AM
15875+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
15876+{
027c5e7a 15877+ int err, e, update;
4a4d8108 15878+ unsigned int flags;
027c5e7a 15879+ umode_t mode;
4a4d8108 15880+ aufs_bindex_t bindex, bend;
027c5e7a 15881+ unsigned char isdir;
4a4d8108
AM
15882+ struct au_hinode *p;
15883+ struct au_iinfo *iinfo;
1facf9fc 15884+
027c5e7a 15885+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
15886+ if (unlikely(err))
15887+ goto out;
15888+
15889+ update = 0;
15890+ iinfo = au_ii(inode);
15891+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
15892+ mode = (inode->i_mode & S_IFMT);
15893+ isdir = S_ISDIR(mode);
4a4d8108
AM
15894+ flags = au_hi_flags(inode, isdir);
15895+ bend = au_dbend(dentry);
15896+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
15897+ struct inode *h_i;
15898+ struct dentry *h_d;
15899+
15900+ h_d = au_h_dptr(dentry, bindex);
15901+ if (!h_d || !h_d->d_inode)
15902+ continue;
15903+
027c5e7a 15904+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
15905+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
15906+ h_i = au_h_iptr(inode, bindex);
15907+ if (h_i) {
15908+ if (h_i == h_d->d_inode)
15909+ continue;
15910+ err = -EIO;
15911+ break;
15912+ }
15913+ }
15914+ if (bindex < iinfo->ii_bstart)
15915+ iinfo->ii_bstart = bindex;
15916+ if (iinfo->ii_bend < bindex)
15917+ iinfo->ii_bend = bindex;
15918+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
15919+ update = 1;
1308ab2a 15920+ }
4a4d8108
AM
15921+ au_update_ibrange(inode, /*do_put_zero*/0);
15922+ e = au_dy_irefresh(inode);
15923+ if (unlikely(e && !err))
15924+ err = e;
027c5e7a
AM
15925+ if (!err)
15926+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 15927+
4f0767ce 15928+out:
4a4d8108 15929+ AuTraceErr(err);
1308ab2a 15930+ return err;
dece6358
AM
15931+}
15932+
4a4d8108 15933+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 15934+{
4a4d8108
AM
15935+ int err;
15936+ unsigned int flags;
15937+ umode_t mode;
15938+ aufs_bindex_t bindex, bstart, btail;
15939+ unsigned char isdir;
15940+ struct dentry *h_dentry;
15941+ struct inode *h_inode;
15942+ struct au_iinfo *iinfo;
dece6358 15943+
4a4d8108 15944+ IiMustWriteLock(inode);
dece6358 15945+
4a4d8108
AM
15946+ err = 0;
15947+ isdir = 0;
15948+ bstart = au_dbstart(dentry);
15949+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
15950+ mode = h_inode->i_mode;
15951+ switch (mode & S_IFMT) {
15952+ case S_IFREG:
15953+ btail = au_dbtail(dentry);
15954+ inode->i_op = &aufs_iop;
15955+ inode->i_fop = &aufs_file_fop;
15956+ err = au_dy_iaop(inode, bstart, h_inode);
15957+ if (unlikely(err))
15958+ goto out;
15959+ break;
15960+ case S_IFDIR:
15961+ isdir = 1;
15962+ btail = au_dbtaildir(dentry);
15963+ inode->i_op = &aufs_dir_iop;
15964+ inode->i_fop = &aufs_dir_fop;
15965+ break;
15966+ case S_IFLNK:
15967+ btail = au_dbtail(dentry);
15968+ inode->i_op = &aufs_symlink_iop;
15969+ break;
15970+ case S_IFBLK:
15971+ case S_IFCHR:
15972+ case S_IFIFO:
15973+ case S_IFSOCK:
15974+ btail = au_dbtail(dentry);
15975+ inode->i_op = &aufs_iop;
38d290e6 15976+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
15977+ break;
15978+ default:
15979+ AuIOErr("Unknown file type 0%o\n", mode);
15980+ err = -EIO;
1308ab2a 15981+ goto out;
4a4d8108 15982+ }
dece6358 15983+
4a4d8108
AM
15984+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
15985+ flags = au_hi_flags(inode, isdir);
15986+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
15987+ && au_ftest_hi(flags, HNOTIFY)
15988+ && dentry->d_name.len > AUFS_WH_PFX_LEN
15989+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
15990+ au_fclr_hi(flags, HNOTIFY);
15991+ iinfo = au_ii(inode);
15992+ iinfo->ii_bstart = bstart;
15993+ iinfo->ii_bend = btail;
15994+ for (bindex = bstart; bindex <= btail; bindex++) {
15995+ h_dentry = au_h_dptr(dentry, bindex);
15996+ if (h_dentry)
15997+ au_set_h_iptr(inode, bindex,
15998+ au_igrab(h_dentry->d_inode), flags);
15999+ }
16000+ au_cpup_attr_all(inode, /*force*/1);
c1595e42
JR
16001+ /*
16002+ * to force calling aufs_get_acl() every time,
16003+ * do not call cache_no_acl() for aufs inode.
16004+ */
dece6358 16005+
4f0767ce 16006+out:
4a4d8108
AM
16007+ return err;
16008+}
dece6358 16009+
027c5e7a
AM
16010+/*
16011+ * successful returns with iinfo write_locked
16012+ * minus: errno
16013+ * zero: success, matched
16014+ * plus: no error, but unmatched
16015+ */
16016+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
16017+{
16018+ int err;
537831f9
AM
16019+ unsigned int gen;
16020+ struct au_iigen iigen;
4a4d8108
AM
16021+ aufs_bindex_t bindex, bend;
16022+ struct inode *h_inode, *h_dinode;
dece6358 16023+
4a4d8108
AM
16024+ /*
16025+ * before this function, if aufs got any iinfo lock, it must be only
16026+ * one, the parent dir.
16027+ * it can happen by UDBA and the obsoleted inode number.
16028+ */
16029+ err = -EIO;
16030+ if (unlikely(inode->i_ino == parent_ino(dentry)))
16031+ goto out;
16032+
027c5e7a 16033+ err = 1;
4a4d8108
AM
16034+ ii_write_lock_new_child(inode);
16035+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
16036+ bend = au_ibend(inode);
16037+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
16038+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
16039+ if (!h_inode || h_inode != h_dinode)
16040+ continue;
16041+
16042+ err = 0;
16043+ gen = au_iigen(inode, &iigen);
16044+ if (gen == au_digen(dentry)
16045+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 16046+ break;
537831f9
AM
16047+
16048+ /* fully refresh inode using dentry */
16049+ err = au_refresh_hinode(inode, dentry);
16050+ if (!err)
16051+ au_update_iigen(inode, /*half*/0);
16052+ break;
1facf9fc 16053+ }
dece6358 16054+
4a4d8108
AM
16055+ if (unlikely(err))
16056+ ii_write_unlock(inode);
4f0767ce 16057+out:
1facf9fc 16058+ return err;
16059+}
1facf9fc 16060+
4a4d8108
AM
16061+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16062+ unsigned int d_type, ino_t *ino)
1facf9fc 16063+{
4a4d8108
AM
16064+ int err;
16065+ struct mutex *mtx;
1facf9fc 16066+
b752ccd1 16067+ /* prevent hardlinked inode number from race condition */
4a4d8108 16068+ mtx = NULL;
b752ccd1 16069+ if (d_type != DT_DIR) {
4a4d8108
AM
16070+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
16071+ mutex_lock(mtx);
16072+ }
16073+ err = au_xino_read(sb, bindex, h_ino, ino);
16074+ if (unlikely(err))
16075+ goto out;
1308ab2a 16076+
4a4d8108
AM
16077+ if (!*ino) {
16078+ err = -EIO;
16079+ *ino = au_xino_new_ino(sb);
16080+ if (unlikely(!*ino))
1facf9fc 16081+ goto out;
4a4d8108
AM
16082+ err = au_xino_write(sb, bindex, h_ino, *ino);
16083+ if (unlikely(err))
1308ab2a 16084+ goto out;
1308ab2a 16085+ }
1facf9fc 16086+
4f0767ce 16087+out:
b752ccd1 16088+ if (mtx)
4a4d8108 16089+ mutex_unlock(mtx);
1facf9fc 16090+ return err;
16091+}
16092+
4a4d8108
AM
16093+/* successful returns with iinfo write_locked */
16094+/* todo: return with unlocked? */
16095+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 16096+{
2000de60 16097+ struct inode *inode;
4a4d8108
AM
16098+ struct dentry *h_dentry;
16099+ struct super_block *sb;
b752ccd1 16100+ struct mutex *mtx;
4a4d8108 16101+ ino_t h_ino, ino;
1716fcea 16102+ int err;
4a4d8108 16103+ aufs_bindex_t bstart;
1facf9fc 16104+
4a4d8108
AM
16105+ sb = dentry->d_sb;
16106+ bstart = au_dbstart(dentry);
16107+ h_dentry = au_h_dptr(dentry, bstart);
2000de60 16108+ h_ino = h_dentry->d_inode->i_ino;
b752ccd1
AM
16109+
16110+ /*
16111+ * stop 'race'-ing between hardlinks under different
16112+ * parents.
16113+ */
16114+ mtx = NULL;
2000de60 16115+ if (!d_is_dir(h_dentry))
b752ccd1
AM
16116+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
16117+
4f0767ce 16118+new_ino:
b752ccd1
AM
16119+ if (mtx)
16120+ mutex_lock(mtx);
4a4d8108
AM
16121+ err = au_xino_read(sb, bstart, h_ino, &ino);
16122+ inode = ERR_PTR(err);
16123+ if (unlikely(err))
16124+ goto out;
b752ccd1 16125+
4a4d8108
AM
16126+ if (!ino) {
16127+ ino = au_xino_new_ino(sb);
16128+ if (unlikely(!ino)) {
16129+ inode = ERR_PTR(-EIO);
dece6358
AM
16130+ goto out;
16131+ }
16132+ }
1facf9fc 16133+
4a4d8108
AM
16134+ AuDbg("i%lu\n", (unsigned long)ino);
16135+ inode = au_iget_locked(sb, ino);
16136+ err = PTR_ERR(inode);
16137+ if (IS_ERR(inode))
1facf9fc 16138+ goto out;
1facf9fc 16139+
4a4d8108
AM
16140+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
16141+ if (inode->i_state & I_NEW) {
1716fcea 16142+ /* verbose coding for lock class name */
2000de60 16143+ if (unlikely(d_is_symlink(h_dentry)))
1716fcea
AM
16144+ au_rw_class(&au_ii(inode)->ii_rwsem,
16145+ au_lc_key + AuLcSymlink_IIINFO);
2000de60 16146+ else if (unlikely(d_is_dir(h_dentry)))
1716fcea
AM
16147+ au_rw_class(&au_ii(inode)->ii_rwsem,
16148+ au_lc_key + AuLcDir_IIINFO);
16149+ else /* likely */
16150+ au_rw_class(&au_ii(inode)->ii_rwsem,
16151+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 16152+
4a4d8108
AM
16153+ ii_write_lock_new_child(inode);
16154+ err = set_inode(inode, dentry);
16155+ if (!err) {
16156+ unlock_new_inode(inode);
16157+ goto out; /* success */
16158+ }
1308ab2a 16159+
027c5e7a
AM
16160+ /*
16161+ * iget_failed() calls iput(), but we need to call
16162+ * ii_write_unlock() after iget_failed(). so dirty hack for
16163+ * i_count.
16164+ */
16165+ atomic_inc(&inode->i_count);
4a4d8108 16166+ iget_failed(inode);
027c5e7a
AM
16167+ ii_write_unlock(inode);
16168+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
16169+ /* ignore this error */
16170+ goto out_iput;
16171+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
16172+ /*
16173+ * horrible race condition between lookup, readdir and copyup
16174+ * (or something).
16175+ */
16176+ if (mtx)
16177+ mutex_unlock(mtx);
027c5e7a
AM
16178+ err = reval_inode(inode, dentry);
16179+ if (unlikely(err < 0)) {
16180+ mtx = NULL;
16181+ goto out_iput;
16182+ }
16183+
b752ccd1
AM
16184+ if (!err) {
16185+ mtx = NULL;
4a4d8108 16186+ goto out; /* success */
b752ccd1
AM
16187+ } else if (mtx)
16188+ mutex_lock(mtx);
4a4d8108
AM
16189+ }
16190+
16191+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
16192+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3
AM
16193+ " b%d, %s, %pd, hi%lu, i%lu.\n",
16194+ bstart, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
16195+ (unsigned long)h_ino, (unsigned long)ino);
16196+ ino = 0;
16197+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
16198+ if (!err) {
16199+ iput(inode);
b752ccd1
AM
16200+ if (mtx)
16201+ mutex_unlock(mtx);
4a4d8108
AM
16202+ goto new_ino;
16203+ }
1308ab2a 16204+
4f0767ce 16205+out_iput:
4a4d8108 16206+ iput(inode);
4a4d8108 16207+ inode = ERR_PTR(err);
4f0767ce 16208+out:
b752ccd1
AM
16209+ if (mtx)
16210+ mutex_unlock(mtx);
4a4d8108 16211+ return inode;
1facf9fc 16212+}
16213+
4a4d8108 16214+/* ---------------------------------------------------------------------- */
1facf9fc 16215+
4a4d8108
AM
16216+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16217+ struct inode *inode)
16218+{
16219+ int err;
076b876e 16220+ struct inode *hi;
1facf9fc 16221+
4a4d8108 16222+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 16223+
4a4d8108
AM
16224+ /* pseudo-link after flushed may happen out of bounds */
16225+ if (!err
16226+ && inode
16227+ && au_ibstart(inode) <= bindex
16228+ && bindex <= au_ibend(inode)) {
16229+ /*
16230+ * permission check is unnecessary since vfsub routine
16231+ * will be called later
16232+ */
076b876e 16233+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
16234+ if (hi)
16235+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 16236+ }
16237+
4a4d8108
AM
16238+ return err;
16239+}
dece6358 16240+
4a4d8108
AM
16241+int au_test_h_perm(struct inode *h_inode, int mask)
16242+{
2dfbb274 16243+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
16244+ return 0;
16245+ return inode_permission(h_inode, mask);
16246+}
1facf9fc 16247+
4a4d8108
AM
16248+int au_test_h_perm_sio(struct inode *h_inode, int mask)
16249+{
16250+ if (au_test_nfs(h_inode->i_sb)
16251+ && (mask & MAY_WRITE)
16252+ && S_ISDIR(h_inode->i_mode))
16253+ mask |= MAY_READ; /* force permission check */
16254+ return au_test_h_perm(h_inode, mask);
1facf9fc 16255+}
7f207e10
AM
16256diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
16257--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
2000de60 16258+++ linux/fs/aufs/inode.h 2015-03-27 21:56:35.466795000 +0100
c1595e42 16259@@ -0,0 +1,667 @@
4a4d8108 16260+/*
2000de60 16261+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
16262+ *
16263+ * This program, aufs is free software; you can redistribute it and/or modify
16264+ * it under the terms of the GNU General Public License as published by
16265+ * the Free Software Foundation; either version 2 of the License, or
16266+ * (at your option) any later version.
16267+ *
16268+ * This program is distributed in the hope that it will be useful,
16269+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16270+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16271+ * GNU General Public License for more details.
16272+ *
16273+ * You should have received a copy of the GNU General Public License
523b37e3 16274+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16275+ */
1facf9fc 16276+
1308ab2a 16277+/*
4a4d8108 16278+ * inode operations
1308ab2a 16279+ */
dece6358 16280+
4a4d8108
AM
16281+#ifndef __AUFS_INODE_H__
16282+#define __AUFS_INODE_H__
dece6358 16283+
4a4d8108 16284+#ifdef __KERNEL__
1308ab2a 16285+
4a4d8108 16286+#include <linux/fsnotify.h>
4a4d8108 16287+#include "rwsem.h"
1308ab2a 16288+
4a4d8108 16289+struct vfsmount;
1facf9fc 16290+
4a4d8108
AM
16291+struct au_hnotify {
16292+#ifdef CONFIG_AUFS_HNOTIFY
16293+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 16294+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 16295+ struct fsnotify_mark hn_mark;
4a4d8108 16296+#endif
7f207e10 16297+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
16298+#endif
16299+} ____cacheline_aligned_in_smp;
1facf9fc 16300+
4a4d8108
AM
16301+struct au_hinode {
16302+ struct inode *hi_inode;
16303+ aufs_bindex_t hi_id;
16304+#ifdef CONFIG_AUFS_HNOTIFY
16305+ struct au_hnotify *hi_notify;
16306+#endif
dece6358 16307+
4a4d8108
AM
16308+ /* reference to the copied-up whiteout with get/put */
16309+ struct dentry *hi_whdentry;
16310+};
dece6358 16311+
537831f9
AM
16312+/* ig_flags */
16313+#define AuIG_HALF_REFRESHED 1
16314+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
16315+#define au_ig_fset(flags, name) \
16316+ do { (flags) |= AuIG_##name; } while (0)
16317+#define au_ig_fclr(flags, name) \
16318+ do { (flags) &= ~AuIG_##name; } while (0)
16319+
16320+struct au_iigen {
16321+ __u32 ig_generation, ig_flags;
16322+};
16323+
4a4d8108
AM
16324+struct au_vdir;
16325+struct au_iinfo {
537831f9 16326+ spinlock_t ii_genspin;
7a9e40b8 16327+ struct au_iigen ii_generation;
4a4d8108 16328+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 16329+
4a4d8108
AM
16330+ struct au_rwsem ii_rwsem;
16331+ aufs_bindex_t ii_bstart, ii_bend;
16332+ __u32 ii_higen;
16333+ struct au_hinode *ii_hinode;
16334+ struct au_vdir *ii_vdir;
16335+};
1facf9fc 16336+
4a4d8108
AM
16337+struct au_icntnr {
16338+ struct au_iinfo iinfo;
16339+ struct inode vfs_inode;
16340+} ____cacheline_aligned_in_smp;
1308ab2a 16341+
4a4d8108
AM
16342+/* au_pin flags */
16343+#define AuPin_DI_LOCKED 1
16344+#define AuPin_MNT_WRITE (1 << 1)
16345+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
16346+#define au_fset_pin(flags, name) \
16347+ do { (flags) |= AuPin_##name; } while (0)
16348+#define au_fclr_pin(flags, name) \
16349+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
16350+
16351+struct au_pin {
16352+ /* input */
16353+ struct dentry *dentry;
16354+ unsigned int udba;
16355+ unsigned char lsc_di, lsc_hi, flags;
16356+ aufs_bindex_t bindex;
16357+
16358+ /* output */
16359+ struct dentry *parent;
16360+ struct au_hinode *hdir;
16361+ struct vfsmount *h_mnt;
86dc4139
AM
16362+
16363+ /* temporary unlock/relock for copyup */
16364+ struct dentry *h_dentry, *h_parent;
16365+ struct au_branch *br;
16366+ struct task_struct *task;
4a4d8108 16367+};
1facf9fc 16368+
86dc4139 16369+void au_pin_hdir_unlock(struct au_pin *p);
c1595e42 16370+int au_pin_hdir_lock(struct au_pin *p);
86dc4139
AM
16371+int au_pin_hdir_relock(struct au_pin *p);
16372+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
16373+void au_pin_hdir_acquire_nest(struct au_pin *p);
16374+void au_pin_hdir_release(struct au_pin *p);
16375+
1308ab2a 16376+/* ---------------------------------------------------------------------- */
16377+
4a4d8108 16378+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 16379+{
4a4d8108 16380+ struct au_iinfo *iinfo;
1facf9fc 16381+
4a4d8108
AM
16382+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
16383+ if (iinfo->ii_hinode)
16384+ return iinfo;
16385+ return NULL; /* debugging bad_inode case */
16386+}
1facf9fc 16387+
4a4d8108 16388+/* ---------------------------------------------------------------------- */
1facf9fc 16389+
4a4d8108
AM
16390+/* inode.c */
16391+struct inode *au_igrab(struct inode *inode);
027c5e7a 16392+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
16393+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
16394+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16395+ unsigned int d_type, ino_t *ino);
16396+struct inode *au_new_inode(struct dentry *dentry, int must_new);
16397+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16398+ struct inode *inode);
16399+int au_test_h_perm(struct inode *h_inode, int mask);
16400+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 16401+
4a4d8108
AM
16402+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
16403+ ino_t h_ino, unsigned int d_type, ino_t *ino)
16404+{
16405+#ifdef CONFIG_AUFS_SHWH
16406+ return au_ino(sb, bindex, h_ino, d_type, ino);
16407+#else
16408+ return 0;
16409+#endif
16410+}
1facf9fc 16411+
4a4d8108
AM
16412+/* i_op.c */
16413+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 16414+
4a4d8108
AM
16415+/* au_wr_dir flags */
16416+#define AuWrDir_ADD_ENTRY 1
86dc4139
AM
16417+#define AuWrDir_TMP_WHENTRY (1 << 1)
16418+#define AuWrDir_ISDIR (1 << 2)
38d290e6 16419+#define AuWrDir_TMPFILE (1 << 3)
4a4d8108 16420+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
16421+#define au_fset_wrdir(flags, name) \
16422+ do { (flags) |= AuWrDir_##name; } while (0)
16423+#define au_fclr_wrdir(flags, name) \
16424+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 16425+
4a4d8108
AM
16426+struct au_wr_dir_args {
16427+ aufs_bindex_t force_btgt;
16428+ unsigned char flags;
16429+};
16430+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16431+ struct au_wr_dir_args *args);
dece6358 16432+
4a4d8108
AM
16433+struct dentry *au_pinned_h_parent(struct au_pin *pin);
16434+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
16435+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16436+ unsigned int udba, unsigned char flags);
16437+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16438+ unsigned int udba, unsigned char flags) __must_check;
16439+int au_do_pin(struct au_pin *pin) __must_check;
16440+void au_unpin(struct au_pin *pin);
c1595e42
JR
16441+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
16442+
16443+#define AuIcpup_DID_CPUP 1
16444+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
16445+#define au_fset_icpup(flags, name) \
16446+ do { (flags) |= AuIcpup_##name; } while (0)
16447+#define au_fclr_icpup(flags, name) \
16448+ do { (flags) &= ~AuIcpup_##name; } while (0)
16449+
16450+struct au_icpup_args {
16451+ unsigned char flags;
16452+ unsigned char pin_flags;
16453+ aufs_bindex_t btgt;
16454+ unsigned int udba;
16455+ struct au_pin pin;
16456+ struct path h_path;
16457+ struct inode *h_inode;
16458+};
16459+
16460+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
16461+ struct au_icpup_args *a);
16462+
16463+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path);
1facf9fc 16464+
4a4d8108
AM
16465+/* i_op_add.c */
16466+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
16467+ struct dentry *h_parent, int isdir);
7eafdf33
AM
16468+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
16469+ dev_t dev);
4a4d8108 16470+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 16471+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 16472+ bool want_excl);
38d290e6 16473+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
16474+int aufs_link(struct dentry *src_dentry, struct inode *dir,
16475+ struct dentry *dentry);
7eafdf33 16476+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 16477+
4a4d8108
AM
16478+/* i_op_del.c */
16479+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
16480+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
16481+ struct dentry *h_parent, int isdir);
16482+int aufs_unlink(struct inode *dir, struct dentry *dentry);
16483+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 16484+
4a4d8108
AM
16485+/* i_op_ren.c */
16486+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
16487+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
16488+ struct inode *dir, struct dentry *dentry);
1facf9fc 16489+
4a4d8108
AM
16490+/* iinfo.c */
16491+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
16492+void au_hiput(struct au_hinode *hinode);
16493+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
16494+ struct dentry *h_wh);
16495+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 16496+
4a4d8108
AM
16497+/* hinode flags */
16498+#define AuHi_XINO 1
16499+#define AuHi_HNOTIFY (1 << 1)
16500+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
16501+#define au_fset_hi(flags, name) \
16502+ do { (flags) |= AuHi_##name; } while (0)
16503+#define au_fclr_hi(flags, name) \
16504+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 16505+
4a4d8108
AM
16506+#ifndef CONFIG_AUFS_HNOTIFY
16507+#undef AuHi_HNOTIFY
16508+#define AuHi_HNOTIFY 0
16509+#endif
1facf9fc 16510+
4a4d8108
AM
16511+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
16512+ struct inode *h_inode, unsigned int flags);
1facf9fc 16513+
537831f9 16514+void au_update_iigen(struct inode *inode, int half);
4a4d8108 16515+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 16516+
4a4d8108
AM
16517+void au_icntnr_init_once(void *_c);
16518+int au_iinfo_init(struct inode *inode);
16519+void au_iinfo_fin(struct inode *inode);
16520+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 16521+
e49829fe 16522+#ifdef CONFIG_PROC_FS
4a4d8108 16523+/* plink.c */
e49829fe
JR
16524+int au_plink_maint(struct super_block *sb, int flags);
16525+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
16526+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
16527+#ifdef CONFIG_AUFS_DEBUG
16528+void au_plink_list(struct super_block *sb);
16529+#else
16530+AuStubVoid(au_plink_list, struct super_block *sb)
16531+#endif
16532+int au_plink_test(struct inode *inode);
16533+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
16534+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
16535+ struct dentry *h_dentry);
e49829fe
JR
16536+void au_plink_put(struct super_block *sb, int verbose);
16537+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 16538+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
16539+#else
16540+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
16541+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
16542+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
16543+AuStubVoid(au_plink_list, struct super_block *sb);
16544+AuStubInt0(au_plink_test, struct inode *inode);
16545+AuStub(struct dentry *, au_plink_lkup, return NULL,
16546+ struct inode *inode, aufs_bindex_t bindex);
16547+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
16548+ struct dentry *h_dentry);
16549+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
16550+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
16551+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
16552+#endif /* CONFIG_PROC_FS */
1facf9fc 16553+
c1595e42
JR
16554+#ifdef CONFIG_AUFS_XATTR
16555+/* xattr.c */
16556+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags);
16557+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
16558+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
16559+ size_t size);
16560+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
16561+ size_t size, int flags);
16562+int aufs_removexattr(struct dentry *dentry, const char *name);
16563+
16564+/* void au_xattr_init(struct super_block *sb); */
16565+#else
16566+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
16567+ int ignore_flags);
16568+/* AuStubVoid(au_xattr_init, struct super_block *sb); */
16569+#endif
16570+
16571+#ifdef CONFIG_FS_POSIX_ACL
16572+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
16573+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
16574+#endif
16575+
16576+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
16577+enum {
16578+ AU_XATTR_SET,
16579+ AU_XATTR_REMOVE,
16580+ AU_ACL_SET
16581+};
16582+
16583+struct au_srxattr {
16584+ int type;
16585+ union {
16586+ struct {
16587+ const char *name;
16588+ const void *value;
16589+ size_t size;
16590+ int flags;
16591+ } set;
16592+ struct {
16593+ const char *name;
16594+ } remove;
16595+ struct {
16596+ struct posix_acl *acl;
16597+ int type;
16598+ } acl_set;
16599+ } u;
16600+};
16601+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg);
16602+#endif
16603+
4a4d8108 16604+/* ---------------------------------------------------------------------- */
1308ab2a 16605+
4a4d8108
AM
16606+/* lock subclass for iinfo */
16607+enum {
16608+ AuLsc_II_CHILD, /* child first */
16609+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
16610+ AuLsc_II_CHILD3, /* copyup dirs */
16611+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
16612+ AuLsc_II_PARENT2,
16613+ AuLsc_II_PARENT3, /* copyup dirs */
16614+ AuLsc_II_NEW_CHILD
16615+};
1308ab2a 16616+
1facf9fc 16617+/*
4a4d8108
AM
16618+ * ii_read_lock_child, ii_write_lock_child,
16619+ * ii_read_lock_child2, ii_write_lock_child2,
16620+ * ii_read_lock_child3, ii_write_lock_child3,
16621+ * ii_read_lock_parent, ii_write_lock_parent,
16622+ * ii_read_lock_parent2, ii_write_lock_parent2,
16623+ * ii_read_lock_parent3, ii_write_lock_parent3,
16624+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 16625+ */
4a4d8108
AM
16626+#define AuReadLockFunc(name, lsc) \
16627+static inline void ii_read_lock_##name(struct inode *i) \
16628+{ \
16629+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16630+}
16631+
16632+#define AuWriteLockFunc(name, lsc) \
16633+static inline void ii_write_lock_##name(struct inode *i) \
16634+{ \
16635+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16636+}
16637+
16638+#define AuRWLockFuncs(name, lsc) \
16639+ AuReadLockFunc(name, lsc) \
16640+ AuWriteLockFunc(name, lsc)
16641+
16642+AuRWLockFuncs(child, CHILD);
16643+AuRWLockFuncs(child2, CHILD2);
16644+AuRWLockFuncs(child3, CHILD3);
16645+AuRWLockFuncs(parent, PARENT);
16646+AuRWLockFuncs(parent2, PARENT2);
16647+AuRWLockFuncs(parent3, PARENT3);
16648+AuRWLockFuncs(new_child, NEW_CHILD);
16649+
16650+#undef AuReadLockFunc
16651+#undef AuWriteLockFunc
16652+#undef AuRWLockFuncs
1facf9fc 16653+
16654+/*
4a4d8108 16655+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 16656+ */
4a4d8108 16657+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 16658+
4a4d8108
AM
16659+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
16660+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
16661+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 16662+
4a4d8108 16663+/* ---------------------------------------------------------------------- */
1308ab2a 16664+
027c5e7a
AM
16665+static inline void au_icntnr_init(struct au_icntnr *c)
16666+{
16667+#ifdef CONFIG_AUFS_DEBUG
16668+ c->vfs_inode.i_mode = 0;
16669+#endif
16670+}
16671+
537831f9 16672+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 16673+{
537831f9
AM
16674+ unsigned int gen;
16675+ struct au_iinfo *iinfo;
16676+
16677+ iinfo = au_ii(inode);
16678+ spin_lock(&iinfo->ii_genspin);
16679+ if (iigen)
16680+ *iigen = iinfo->ii_generation;
16681+ gen = iinfo->ii_generation.ig_generation;
16682+ spin_unlock(&iinfo->ii_genspin);
16683+
16684+ return gen;
4a4d8108 16685+}
1308ab2a 16686+
4a4d8108
AM
16687+/* tiny test for inode number */
16688+/* tmpfs generation is too rough */
16689+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
16690+{
16691+ struct au_iinfo *iinfo;
1308ab2a 16692+
4a4d8108
AM
16693+ iinfo = au_ii(inode);
16694+ AuRwMustAnyLock(&iinfo->ii_rwsem);
16695+ return !(iinfo->ii_hsb1 == h_inode->i_sb
16696+ && iinfo->ii_higen == h_inode->i_generation);
16697+}
1308ab2a 16698+
4a4d8108
AM
16699+static inline void au_iigen_dec(struct inode *inode)
16700+{
537831f9
AM
16701+ struct au_iinfo *iinfo;
16702+
16703+ iinfo = au_ii(inode);
16704+ spin_lock(&iinfo->ii_genspin);
16705+ iinfo->ii_generation.ig_generation--;
16706+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
16707+}
16708+
16709+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
16710+{
16711+ int err;
16712+
16713+ err = 0;
537831f9 16714+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
16715+ err = -EIO;
16716+
16717+ return err;
4a4d8108 16718+}
1308ab2a 16719+
4a4d8108 16720+/* ---------------------------------------------------------------------- */
1308ab2a 16721+
4a4d8108
AM
16722+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
16723+ aufs_bindex_t bindex)
16724+{
16725+ IiMustAnyLock(inode);
16726+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
16727+}
1308ab2a 16728+
4a4d8108
AM
16729+static inline aufs_bindex_t au_ibstart(struct inode *inode)
16730+{
16731+ IiMustAnyLock(inode);
16732+ return au_ii(inode)->ii_bstart;
16733+}
1308ab2a 16734+
4a4d8108
AM
16735+static inline aufs_bindex_t au_ibend(struct inode *inode)
16736+{
16737+ IiMustAnyLock(inode);
16738+ return au_ii(inode)->ii_bend;
16739+}
1308ab2a 16740+
4a4d8108
AM
16741+static inline struct au_vdir *au_ivdir(struct inode *inode)
16742+{
16743+ IiMustAnyLock(inode);
16744+ return au_ii(inode)->ii_vdir;
16745+}
1308ab2a 16746+
4a4d8108
AM
16747+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
16748+{
16749+ IiMustAnyLock(inode);
16750+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
16751+}
1308ab2a 16752+
4a4d8108 16753+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16754+{
4a4d8108
AM
16755+ IiMustWriteLock(inode);
16756+ au_ii(inode)->ii_bstart = bindex;
16757+}
1308ab2a 16758+
4a4d8108
AM
16759+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
16760+{
16761+ IiMustWriteLock(inode);
16762+ au_ii(inode)->ii_bend = bindex;
1308ab2a 16763+}
16764+
4a4d8108
AM
16765+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
16766+{
16767+ IiMustWriteLock(inode);
16768+ au_ii(inode)->ii_vdir = vdir;
16769+}
1facf9fc 16770+
4a4d8108 16771+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16772+{
4a4d8108
AM
16773+ IiMustAnyLock(inode);
16774+ return au_ii(inode)->ii_hinode + bindex;
16775+}
dece6358 16776+
4a4d8108 16777+/* ---------------------------------------------------------------------- */
1facf9fc 16778+
4a4d8108
AM
16779+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
16780+{
16781+ if (pin)
16782+ return pin->parent;
16783+ return NULL;
1facf9fc 16784+}
16785+
4a4d8108 16786+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 16787+{
4a4d8108
AM
16788+ if (pin && pin->hdir)
16789+ return pin->hdir->hi_inode;
16790+ return NULL;
1308ab2a 16791+}
1facf9fc 16792+
4a4d8108
AM
16793+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
16794+{
16795+ if (pin)
16796+ return pin->hdir;
16797+ return NULL;
16798+}
1facf9fc 16799+
4a4d8108 16800+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 16801+{
4a4d8108
AM
16802+ if (pin)
16803+ pin->dentry = dentry;
16804+}
1308ab2a 16805+
4a4d8108
AM
16806+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
16807+ unsigned char lflag)
16808+{
16809+ if (pin) {
7f207e10 16810+ if (lflag)
4a4d8108 16811+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 16812+ else
4a4d8108 16813+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 16814+ }
4a4d8108
AM
16815+}
16816+
16817+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
16818+{
16819+ if (pin) {
16820+ dput(pin->parent);
16821+ pin->parent = dget(parent);
1facf9fc 16822+ }
4a4d8108 16823+}
1facf9fc 16824+
4a4d8108
AM
16825+/* ---------------------------------------------------------------------- */
16826+
027c5e7a 16827+struct au_branch;
4a4d8108
AM
16828+#ifdef CONFIG_AUFS_HNOTIFY
16829+struct au_hnotify_op {
16830+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 16831+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
16832+
16833+ /*
16834+ * if it returns true, the the caller should free hinode->hi_notify,
16835+ * otherwise ->free() frees it.
16836+ */
16837+ int (*free)(struct au_hinode *hinode,
16838+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
16839+
16840+ void (*fin)(void);
16841+ int (*init)(void);
027c5e7a
AM
16842+
16843+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
16844+ void (*fin_br)(struct au_branch *br);
16845+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
16846+};
16847+
16848+/* hnotify.c */
027c5e7a 16849+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
16850+void au_hn_free(struct au_hinode *hinode);
16851+void au_hn_ctl(struct au_hinode *hinode, int do_set);
16852+void au_hn_reset(struct inode *inode, unsigned int flags);
16853+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
16854+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
16855+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
16856+int au_hnotify_init_br(struct au_branch *br, int perm);
16857+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
16858+int __init au_hnotify_init(void);
16859+void au_hnotify_fin(void);
16860+
7f207e10 16861+/* hfsnotify.c */
4a4d8108
AM
16862+extern const struct au_hnotify_op au_hnotify_op;
16863+
16864+static inline
16865+void au_hn_init(struct au_hinode *hinode)
16866+{
16867+ hinode->hi_notify = NULL;
1308ab2a 16868+}
16869+
53392da6
AM
16870+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
16871+{
16872+ return hinode->hi_notify;
16873+}
16874+
4a4d8108 16875+#else
c1595e42
JR
16876+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
16877+ struct au_hinode *hinode __maybe_unused,
16878+ struct inode *inode __maybe_unused)
16879+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
4a4d8108
AM
16880+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
16881+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
16882+ int do_set __maybe_unused)
16883+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
16884+ unsigned int flags __maybe_unused)
027c5e7a
AM
16885+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
16886+ struct au_branch *br __maybe_unused,
16887+ int perm __maybe_unused)
16888+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
16889+ int perm __maybe_unused)
16890+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
16891+AuStubInt0(__init au_hnotify_init, void)
16892+AuStubVoid(au_hnotify_fin, void)
16893+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
16894+#endif /* CONFIG_AUFS_HNOTIFY */
16895+
16896+static inline void au_hn_suspend(struct au_hinode *hdir)
16897+{
16898+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 16899+}
16900+
4a4d8108 16901+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 16902+{
4a4d8108
AM
16903+ au_hn_ctl(hdir, /*do_set*/1);
16904+}
1308ab2a 16905+
4a4d8108
AM
16906+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
16907+{
16908+ mutex_lock(&hdir->hi_inode->i_mutex);
16909+ au_hn_suspend(hdir);
16910+}
dece6358 16911+
4a4d8108
AM
16912+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
16913+ unsigned int sc __maybe_unused)
16914+{
16915+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
16916+ au_hn_suspend(hdir);
1facf9fc 16917+}
1facf9fc 16918+
4a4d8108
AM
16919+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
16920+{
16921+ au_hn_resume(hdir);
16922+ mutex_unlock(&hdir->hi_inode->i_mutex);
16923+}
16924+
16925+#endif /* __KERNEL__ */
16926+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
16927diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
16928--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
2000de60 16929+++ linux/fs/aufs/ioctl.c 2015-03-27 21:56:35.466795000 +0100
c1595e42 16930@@ -0,0 +1,219 @@
4a4d8108 16931+/*
2000de60 16932+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
16933+ *
16934+ * This program, aufs is free software; you can redistribute it and/or modify
16935+ * it under the terms of the GNU General Public License as published by
16936+ * the Free Software Foundation; either version 2 of the License, or
16937+ * (at your option) any later version.
16938+ *
16939+ * This program is distributed in the hope that it will be useful,
16940+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16941+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16942+ * GNU General Public License for more details.
16943+ *
16944+ * You should have received a copy of the GNU General Public License
523b37e3 16945+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16946+ */
16947+
16948+/*
16949+ * ioctl
16950+ * plink-management and readdir in userspace.
16951+ * assist the pathconf(3) wrapper library.
c2b27bf2 16952+ * move-down
076b876e 16953+ * File-based Hierarchical Storage Management.
4a4d8108
AM
16954+ */
16955+
c2b27bf2
AM
16956+#include <linux/compat.h>
16957+#include <linux/file.h>
4a4d8108
AM
16958+#include "aufs.h"
16959+
1e00d052 16960+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
16961+{
16962+ int err, fd;
16963+ aufs_bindex_t wbi, bindex, bend;
16964+ struct file *h_file;
16965+ struct super_block *sb;
16966+ struct dentry *root;
1e00d052
AM
16967+ struct au_branch *br;
16968+ struct aufs_wbr_fd wbrfd = {
16969+ .oflags = au_dir_roflags,
16970+ .brid = -1
16971+ };
16972+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
16973+ | O_NOATIME | O_CLOEXEC;
4a4d8108 16974+
1e00d052
AM
16975+ AuDebugOn(wbrfd.oflags & ~valid);
16976+
16977+ if (arg) {
16978+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
16979+ if (unlikely(err)) {
16980+ err = -EFAULT;
16981+ goto out;
16982+ }
16983+
16984+ err = -EINVAL;
16985+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
16986+ wbrfd.oflags |= au_dir_roflags;
16987+ AuDbg("0%o\n", wbrfd.oflags);
16988+ if (unlikely(wbrfd.oflags & ~valid))
16989+ goto out;
16990+ }
16991+
2000de60 16992+ fd = get_unused_fd_flags(0);
1e00d052
AM
16993+ err = fd;
16994+ if (unlikely(fd < 0))
4a4d8108 16995+ goto out;
4a4d8108 16996+
1e00d052 16997+ h_file = ERR_PTR(-EINVAL);
4a4d8108 16998+ wbi = 0;
1e00d052 16999+ br = NULL;
4a4d8108
AM
17000+ sb = path->dentry->d_sb;
17001+ root = sb->s_root;
17002+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
17003+ bend = au_sbend(sb);
17004+ if (wbrfd.brid >= 0) {
17005+ wbi = au_br_index(sb, wbrfd.brid);
17006+ if (unlikely(wbi < 0 || wbi > bend))
17007+ goto out_unlock;
17008+ }
17009+
17010+ h_file = ERR_PTR(-ENOENT);
17011+ br = au_sbr(sb, wbi);
17012+ if (!au_br_writable(br->br_perm)) {
17013+ if (arg)
17014+ goto out_unlock;
17015+
17016+ bindex = wbi + 1;
17017+ wbi = -1;
17018+ for (; bindex <= bend; bindex++) {
17019+ br = au_sbr(sb, bindex);
17020+ if (au_br_writable(br->br_perm)) {
4a4d8108 17021+ wbi = bindex;
1e00d052 17022+ br = au_sbr(sb, wbi);
4a4d8108
AM
17023+ break;
17024+ }
17025+ }
4a4d8108
AM
17026+ }
17027+ AuDbg("wbi %d\n", wbi);
1e00d052 17028+ if (wbi >= 0)
392086de
AM
17029+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
17030+ /*force_wr*/0);
1e00d052
AM
17031+
17032+out_unlock:
4a4d8108
AM
17033+ aufs_read_unlock(root, AuLock_IR);
17034+ err = PTR_ERR(h_file);
17035+ if (IS_ERR(h_file))
17036+ goto out_fd;
17037+
1e00d052 17038+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
17039+ fd_install(fd, h_file);
17040+ err = fd;
17041+ goto out; /* success */
17042+
4f0767ce 17043+out_fd:
4a4d8108 17044+ put_unused_fd(fd);
4f0767ce 17045+out:
1e00d052 17046+ AuTraceErr(err);
4a4d8108
AM
17047+ return err;
17048+}
17049+
17050+/* ---------------------------------------------------------------------- */
17051+
17052+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
17053+{
17054+ long err;
c1595e42 17055+ struct dentry *dentry;
4a4d8108
AM
17056+
17057+ switch (cmd) {
4a4d8108
AM
17058+ case AUFS_CTL_RDU:
17059+ case AUFS_CTL_RDU_INO:
17060+ err = au_rdu_ioctl(file, cmd, arg);
17061+ break;
17062+
17063+ case AUFS_CTL_WBR_FD:
1e00d052 17064+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
17065+ break;
17066+
027c5e7a
AM
17067+ case AUFS_CTL_IBUSY:
17068+ err = au_ibusy_ioctl(file, arg);
17069+ break;
17070+
076b876e
AM
17071+ case AUFS_CTL_BRINFO:
17072+ err = au_brinfo_ioctl(file, arg);
17073+ break;
17074+
17075+ case AUFS_CTL_FHSM_FD:
2000de60 17076+ dentry = file->f_path.dentry;
c1595e42
JR
17077+ if (IS_ROOT(dentry))
17078+ err = au_fhsm_fd(dentry->d_sb, arg);
17079+ else
17080+ err = -ENOTTY;
076b876e
AM
17081+ break;
17082+
4a4d8108
AM
17083+ default:
17084+ /* do not call the lower */
17085+ AuDbg("0x%x\n", cmd);
17086+ err = -ENOTTY;
17087+ }
17088+
17089+ AuTraceErr(err);
17090+ return err;
17091+}
17092+
17093+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
17094+{
17095+ long err;
17096+
17097+ switch (cmd) {
c2b27bf2 17098+ case AUFS_CTL_MVDOWN:
2000de60 17099+ err = au_mvdown(file->f_path.dentry, (void __user *)arg);
c2b27bf2
AM
17100+ break;
17101+
4a4d8108 17102+ case AUFS_CTL_WBR_FD:
1e00d052 17103+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
17104+ break;
17105+
17106+ default:
17107+ /* do not call the lower */
17108+ AuDbg("0x%x\n", cmd);
17109+ err = -ENOTTY;
17110+ }
17111+
17112+ AuTraceErr(err);
17113+ return err;
17114+}
b752ccd1
AM
17115+
17116+#ifdef CONFIG_COMPAT
17117+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
17118+ unsigned long arg)
17119+{
17120+ long err;
17121+
17122+ switch (cmd) {
17123+ case AUFS_CTL_RDU:
17124+ case AUFS_CTL_RDU_INO:
17125+ err = au_rdu_compat_ioctl(file, cmd, arg);
17126+ break;
17127+
027c5e7a
AM
17128+ case AUFS_CTL_IBUSY:
17129+ err = au_ibusy_compat_ioctl(file, arg);
17130+ break;
17131+
076b876e
AM
17132+ case AUFS_CTL_BRINFO:
17133+ err = au_brinfo_compat_ioctl(file, arg);
17134+ break;
17135+
b752ccd1
AM
17136+ default:
17137+ err = aufs_ioctl_dir(file, cmd, arg);
17138+ }
17139+
17140+ AuTraceErr(err);
17141+ return err;
17142+}
17143+
b752ccd1
AM
17144+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
17145+ unsigned long arg)
17146+{
17147+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
17148+}
17149+#endif
7f207e10
AM
17150diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
17151--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
17152+++ linux/fs/aufs/i_op_add.c 2015-03-27 21:56:35.463461668 +0100
17153@@ -0,0 +1,896 @@
4a4d8108 17154+/*
2000de60 17155+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
17156+ *
17157+ * This program, aufs is free software; you can redistribute it and/or modify
17158+ * it under the terms of the GNU General Public License as published by
17159+ * the Free Software Foundation; either version 2 of the License, or
17160+ * (at your option) any later version.
17161+ *
17162+ * This program is distributed in the hope that it will be useful,
17163+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17164+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17165+ * GNU General Public License for more details.
17166+ *
17167+ * You should have received a copy of the GNU General Public License
523b37e3 17168+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
17169+ */
17170+
17171+/*
17172+ * inode operations (add entry)
17173+ */
17174+
17175+#include "aufs.h"
17176+
17177+/*
17178+ * final procedure of adding a new entry, except link(2).
17179+ * remove whiteout, instantiate, copyup the parent dir's times and size
17180+ * and update version.
17181+ * if it failed, re-create the removed whiteout.
17182+ */
17183+static int epilog(struct inode *dir, aufs_bindex_t bindex,
17184+ struct dentry *wh_dentry, struct dentry *dentry)
17185+{
17186+ int err, rerr;
17187+ aufs_bindex_t bwh;
17188+ struct path h_path;
076b876e 17189+ struct super_block *sb;
4a4d8108
AM
17190+ struct inode *inode, *h_dir;
17191+ struct dentry *wh;
17192+
17193+ bwh = -1;
076b876e 17194+ sb = dir->i_sb;
4a4d8108
AM
17195+ if (wh_dentry) {
17196+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
17197+ IMustLock(h_dir);
17198+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
17199+ bwh = au_dbwh(dentry);
17200+ h_path.dentry = wh_dentry;
076b876e 17201+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
17202+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
17203+ dentry);
17204+ if (unlikely(err))
17205+ goto out;
17206+ }
17207+
17208+ inode = au_new_inode(dentry, /*must_new*/1);
17209+ if (!IS_ERR(inode)) {
17210+ d_instantiate(dentry, inode);
17211+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
17212+ IMustLock(dir);
17213+ if (au_ibstart(dir) == au_dbstart(dentry))
17214+ au_cpup_attr_timesizes(dir);
17215+ dir->i_version++;
076b876e 17216+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
17217+ return 0; /* success */
17218+ }
17219+
17220+ err = PTR_ERR(inode);
17221+ if (!wh_dentry)
17222+ goto out;
17223+
17224+ /* revert */
17225+ /* dir inode is locked */
17226+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
17227+ rerr = PTR_ERR(wh);
17228+ if (IS_ERR(wh)) {
523b37e3
AM
17229+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
17230+ dentry, err, rerr);
4a4d8108
AM
17231+ err = -EIO;
17232+ } else
17233+ dput(wh);
17234+
4f0767ce 17235+out:
4a4d8108
AM
17236+ return err;
17237+}
17238+
027c5e7a
AM
17239+static int au_d_may_add(struct dentry *dentry)
17240+{
17241+ int err;
17242+
17243+ err = 0;
17244+ if (unlikely(d_unhashed(dentry)))
17245+ err = -ENOENT;
17246+ if (unlikely(dentry->d_inode))
17247+ err = -EEXIST;
17248+ return err;
17249+}
17250+
4a4d8108
AM
17251+/*
17252+ * simple tests for the adding inode operations.
17253+ * following the checks in vfs, plus the parent-child relationship.
17254+ */
17255+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
17256+ struct dentry *h_parent, int isdir)
17257+{
17258+ int err;
17259+ umode_t h_mode;
17260+ struct dentry *h_dentry;
17261+ struct inode *h_inode;
17262+
17263+ err = -ENAMETOOLONG;
17264+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17265+ goto out;
17266+
17267+ h_dentry = au_h_dptr(dentry, bindex);
17268+ h_inode = h_dentry->d_inode;
17269+ if (!dentry->d_inode) {
17270+ err = -EEXIST;
17271+ if (unlikely(h_inode))
17272+ goto out;
17273+ } else {
17274+ /* rename(2) case */
17275+ err = -EIO;
17276+ if (unlikely(!h_inode || !h_inode->i_nlink))
17277+ goto out;
17278+
17279+ h_mode = h_inode->i_mode;
17280+ if (!isdir) {
17281+ err = -EISDIR;
17282+ if (unlikely(S_ISDIR(h_mode)))
17283+ goto out;
17284+ } else if (unlikely(!S_ISDIR(h_mode))) {
17285+ err = -ENOTDIR;
17286+ goto out;
17287+ }
17288+ }
17289+
17290+ err = 0;
17291+ /* expected parent dir is locked */
17292+ if (unlikely(h_parent != h_dentry->d_parent))
17293+ err = -EIO;
17294+
4f0767ce 17295+out:
4a4d8108
AM
17296+ AuTraceErr(err);
17297+ return err;
17298+}
17299+
17300+/*
17301+ * initial procedure of adding a new entry.
17302+ * prepare writable branch and the parent dir, lock it,
17303+ * and lookup whiteout for the new entry.
17304+ */
17305+static struct dentry*
17306+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
17307+ struct dentry *src_dentry, struct au_pin *pin,
17308+ struct au_wr_dir_args *wr_dir_args)
17309+{
17310+ struct dentry *wh_dentry, *h_parent;
17311+ struct super_block *sb;
17312+ struct au_branch *br;
17313+ int err;
17314+ unsigned int udba;
17315+ aufs_bindex_t bcpup;
17316+
523b37e3 17317+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17318+
17319+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
17320+ bcpup = err;
17321+ wh_dentry = ERR_PTR(err);
17322+ if (unlikely(err < 0))
17323+ goto out;
17324+
17325+ sb = dentry->d_sb;
17326+ udba = au_opt_udba(sb);
17327+ err = au_pin(pin, dentry, bcpup, udba,
17328+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17329+ wh_dentry = ERR_PTR(err);
17330+ if (unlikely(err))
17331+ goto out;
17332+
17333+ h_parent = au_pinned_h_parent(pin);
17334+ if (udba != AuOpt_UDBA_NONE
17335+ && au_dbstart(dentry) == bcpup)
17336+ err = au_may_add(dentry, bcpup, h_parent,
17337+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
17338+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17339+ err = -ENAMETOOLONG;
17340+ wh_dentry = ERR_PTR(err);
17341+ if (unlikely(err))
17342+ goto out_unpin;
17343+
17344+ br = au_sbr(sb, bcpup);
17345+ if (dt) {
17346+ struct path tmp = {
17347+ .dentry = h_parent,
86dc4139 17348+ .mnt = au_br_mnt(br)
4a4d8108
AM
17349+ };
17350+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
17351+ }
17352+
17353+ wh_dentry = NULL;
17354+ if (bcpup != au_dbwh(dentry))
17355+ goto out; /* success */
17356+
2000de60
JR
17357+ /*
17358+ * ENAMETOOLONG here means that if we allowed create such name, then it
17359+ * would not be able to removed in the future. So we don't allow such
17360+ * name here and we don't handle ENAMETOOLONG differently here.
17361+ */
4a4d8108
AM
17362+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
17363+
4f0767ce 17364+out_unpin:
4a4d8108
AM
17365+ if (IS_ERR(wh_dentry))
17366+ au_unpin(pin);
4f0767ce 17367+out:
4a4d8108
AM
17368+ return wh_dentry;
17369+}
17370+
17371+/* ---------------------------------------------------------------------- */
17372+
17373+enum { Mknod, Symlink, Creat };
17374+struct simple_arg {
17375+ int type;
17376+ union {
17377+ struct {
7eafdf33 17378+ umode_t mode;
b4510431 17379+ bool want_excl;
4a4d8108
AM
17380+ } c;
17381+ struct {
17382+ const char *symname;
17383+ } s;
17384+ struct {
7eafdf33 17385+ umode_t mode;
4a4d8108
AM
17386+ dev_t dev;
17387+ } m;
17388+ } u;
17389+};
17390+
17391+static int add_simple(struct inode *dir, struct dentry *dentry,
17392+ struct simple_arg *arg)
17393+{
076b876e 17394+ int err, rerr;
4a4d8108
AM
17395+ aufs_bindex_t bstart;
17396+ unsigned char created;
4a4d8108
AM
17397+ struct dentry *wh_dentry, *parent;
17398+ struct inode *h_dir;
c2b27bf2
AM
17399+ /* to reuduce stack size */
17400+ struct {
17401+ struct au_dtime dt;
17402+ struct au_pin pin;
17403+ struct path h_path;
17404+ struct au_wr_dir_args wr_dir_args;
17405+ } *a;
4a4d8108 17406+
523b37e3 17407+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17408+ IMustLock(dir);
17409+
c2b27bf2
AM
17410+ err = -ENOMEM;
17411+ a = kmalloc(sizeof(*a), GFP_NOFS);
17412+ if (unlikely(!a))
17413+ goto out;
17414+ a->wr_dir_args.force_btgt = -1;
17415+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
17416+
4a4d8108 17417+ parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17418+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17419+ if (unlikely(err))
c2b27bf2 17420+ goto out_free;
027c5e7a
AM
17421+ err = au_d_may_add(dentry);
17422+ if (unlikely(err))
17423+ goto out_unlock;
4a4d8108 17424+ di_write_lock_parent(parent);
c2b27bf2
AM
17425+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17426+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
17427+ err = PTR_ERR(wh_dentry);
17428+ if (IS_ERR(wh_dentry))
027c5e7a 17429+ goto out_parent;
4a4d8108
AM
17430+
17431+ bstart = au_dbstart(dentry);
c2b27bf2
AM
17432+ a->h_path.dentry = au_h_dptr(dentry, bstart);
17433+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
17434+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
17435+ switch (arg->type) {
17436+ case Creat:
c2b27bf2 17437+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
537831f9 17438+ arg->u.c.want_excl);
4a4d8108
AM
17439+ break;
17440+ case Symlink:
c2b27bf2 17441+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
17442+ break;
17443+ case Mknod:
c2b27bf2
AM
17444+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
17445+ arg->u.m.dev);
4a4d8108
AM
17446+ break;
17447+ default:
17448+ BUG();
17449+ }
17450+ created = !err;
17451+ if (!err)
17452+ err = epilog(dir, bstart, wh_dentry, dentry);
17453+
17454+ /* revert */
c2b27bf2 17455+ if (unlikely(created && err && a->h_path.dentry->d_inode)) {
523b37e3
AM
17456+ /* no delegation since it is just created */
17457+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
17458+ /*force*/0);
4a4d8108 17459+ if (rerr) {
523b37e3
AM
17460+ AuIOErr("%pd revert failure(%d, %d)\n",
17461+ dentry, err, rerr);
4a4d8108
AM
17462+ err = -EIO;
17463+ }
c2b27bf2 17464+ au_dtime_revert(&a->dt);
4a4d8108
AM
17465+ }
17466+
c2b27bf2 17467+ au_unpin(&a->pin);
4a4d8108
AM
17468+ dput(wh_dentry);
17469+
027c5e7a
AM
17470+out_parent:
17471+ di_write_unlock(parent);
17472+out_unlock:
4a4d8108
AM
17473+ if (unlikely(err)) {
17474+ au_update_dbstart(dentry);
17475+ d_drop(dentry);
17476+ }
4a4d8108 17477+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
17478+out_free:
17479+ kfree(a);
027c5e7a 17480+out:
4a4d8108
AM
17481+ return err;
17482+}
17483+
7eafdf33
AM
17484+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
17485+ dev_t dev)
4a4d8108
AM
17486+{
17487+ struct simple_arg arg = {
17488+ .type = Mknod,
17489+ .u.m = {
17490+ .mode = mode,
17491+ .dev = dev
17492+ }
17493+ };
17494+ return add_simple(dir, dentry, &arg);
17495+}
17496+
17497+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
17498+{
17499+ struct simple_arg arg = {
17500+ .type = Symlink,
17501+ .u.s.symname = symname
17502+ };
17503+ return add_simple(dir, dentry, &arg);
17504+}
17505+
7eafdf33 17506+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 17507+ bool want_excl)
4a4d8108
AM
17508+{
17509+ struct simple_arg arg = {
17510+ .type = Creat,
17511+ .u.c = {
b4510431
AM
17512+ .mode = mode,
17513+ .want_excl = want_excl
4a4d8108
AM
17514+ }
17515+ };
17516+ return add_simple(dir, dentry, &arg);
17517+}
17518+
38d290e6
JR
17519+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
17520+{
17521+ int err;
17522+ aufs_bindex_t bindex;
17523+ struct super_block *sb;
17524+ struct dentry *parent, *h_parent, *h_dentry;
17525+ struct inode *h_dir, *inode;
17526+ struct vfsmount *h_mnt;
17527+ struct au_wr_dir_args wr_dir_args = {
17528+ .force_btgt = -1,
17529+ .flags = AuWrDir_TMPFILE
17530+ };
17531+
17532+ /* copy-up may happen */
17533+ mutex_lock(&dir->i_mutex);
17534+
17535+ sb = dir->i_sb;
17536+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17537+ if (unlikely(err))
17538+ goto out;
17539+
17540+ err = au_di_init(dentry);
17541+ if (unlikely(err))
17542+ goto out_si;
17543+
17544+ err = -EBUSY;
17545+ parent = d_find_any_alias(dir);
17546+ AuDebugOn(!parent);
17547+ di_write_lock_parent(parent);
17548+ if (unlikely(parent->d_inode != dir))
17549+ goto out_parent;
17550+
17551+ err = au_digen_test(parent, au_sigen(sb));
17552+ if (unlikely(err))
17553+ goto out_parent;
17554+
17555+ bindex = au_dbstart(parent);
17556+ au_set_dbstart(dentry, bindex);
17557+ au_set_dbend(dentry, bindex);
17558+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17559+ bindex = err;
17560+ if (unlikely(err < 0))
17561+ goto out_parent;
17562+
17563+ err = -EOPNOTSUPP;
17564+ h_dir = au_h_iptr(dir, bindex);
17565+ if (unlikely(!h_dir->i_op->tmpfile))
17566+ goto out_parent;
17567+
17568+ h_mnt = au_sbr_mnt(sb, bindex);
17569+ err = vfsub_mnt_want_write(h_mnt);
17570+ if (unlikely(err))
17571+ goto out_parent;
17572+
17573+ h_parent = au_h_dptr(parent, bindex);
17574+ err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC);
17575+ if (unlikely(err))
17576+ goto out_mnt;
17577+
17578+ err = -ENOMEM;
17579+ h_dentry = d_alloc(h_parent, &dentry->d_name);
17580+ if (unlikely(!h_dentry))
17581+ goto out_mnt;
17582+
17583+ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode);
17584+ if (unlikely(err))
17585+ goto out_dentry;
17586+
17587+ au_set_dbstart(dentry, bindex);
17588+ au_set_dbend(dentry, bindex);
17589+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
17590+ inode = au_new_inode(dentry, /*must_new*/1);
17591+ if (IS_ERR(inode)) {
17592+ err = PTR_ERR(inode);
17593+ au_set_h_dptr(dentry, bindex, NULL);
17594+ au_set_dbstart(dentry, -1);
17595+ au_set_dbend(dentry, -1);
17596+ } else {
17597+ if (!inode->i_nlink)
17598+ set_nlink(inode, 1);
17599+ d_tmpfile(dentry, inode);
17600+ au_di(dentry)->di_tmpfile = 1;
17601+
17602+ /* update without i_mutex */
17603+ if (au_ibstart(dir) == au_dbstart(dentry))
17604+ au_cpup_attr_timesizes(dir);
17605+ }
17606+
17607+out_dentry:
17608+ dput(h_dentry);
17609+out_mnt:
17610+ vfsub_mnt_drop_write(h_mnt);
17611+out_parent:
17612+ di_write_unlock(parent);
17613+ dput(parent);
17614+ di_write_unlock(dentry);
17615+ if (!err)
17616+#if 0
17617+ /* verbose coding for lock class name */
17618+ au_rw_class(&au_di(dentry)->di_rwsem,
17619+ au_lc_key + AuLcNonDir_DIINFO);
17620+#else
17621+ ;
17622+#endif
17623+ else {
17624+ au_di_fin(dentry);
17625+ dentry->d_fsdata = NULL;
17626+ }
17627+out_si:
17628+ si_read_unlock(sb);
17629+out:
17630+ mutex_unlock(&dir->i_mutex);
17631+ return err;
17632+}
17633+
4a4d8108
AM
17634+/* ---------------------------------------------------------------------- */
17635+
17636+struct au_link_args {
17637+ aufs_bindex_t bdst, bsrc;
17638+ struct au_pin pin;
17639+ struct path h_path;
17640+ struct dentry *src_parent, *parent;
17641+};
17642+
17643+static int au_cpup_before_link(struct dentry *src_dentry,
17644+ struct au_link_args *a)
17645+{
17646+ int err;
17647+ struct dentry *h_src_dentry;
c2b27bf2
AM
17648+ struct au_cp_generic cpg = {
17649+ .dentry = src_dentry,
17650+ .bdst = a->bdst,
17651+ .bsrc = a->bsrc,
17652+ .len = -1,
17653+ .pin = &a->pin,
17654+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
17655+ };
4a4d8108
AM
17656+
17657+ di_read_lock_parent(a->src_parent, AuLock_IR);
17658+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
17659+ if (unlikely(err))
17660+ goto out;
17661+
17662+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
17663+ err = au_pin(&a->pin, src_dentry, a->bdst,
17664+ au_opt_udba(src_dentry->d_sb),
17665+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17666+ if (unlikely(err))
17667+ goto out;
367653fa 17668+
c2b27bf2 17669+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
17670+ au_unpin(&a->pin);
17671+
4f0767ce 17672+out:
4a4d8108
AM
17673+ di_read_unlock(a->src_parent, AuLock_IR);
17674+ return err;
17675+}
17676+
86dc4139
AM
17677+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
17678+ struct au_link_args *a)
4a4d8108
AM
17679+{
17680+ int err;
17681+ unsigned char plink;
86dc4139 17682+ aufs_bindex_t bend;
4a4d8108 17683+ struct dentry *h_src_dentry;
523b37e3 17684+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
17685+ struct super_block *sb;
17686+ struct file *h_file;
17687+
17688+ plink = 0;
17689+ h_inode = NULL;
17690+ sb = src_dentry->d_sb;
17691+ inode = src_dentry->d_inode;
17692+ if (au_ibstart(inode) <= a->bdst)
17693+ h_inode = au_h_iptr(inode, a->bdst);
17694+ if (!h_inode || !h_inode->i_nlink) {
17695+ /* copyup src_dentry as the name of dentry. */
86dc4139
AM
17696+ bend = au_dbend(dentry);
17697+ if (bend < a->bsrc)
17698+ au_set_dbend(dentry, a->bsrc);
17699+ au_set_h_dptr(dentry, a->bsrc,
17700+ dget(au_h_dptr(src_dentry, a->bsrc)));
17701+ dget(a->h_path.dentry);
17702+ au_set_h_dptr(dentry, a->bdst, NULL);
c1595e42
JR
17703+ AuDbg("temporary d_inode...\n");
17704+ spin_lock(&dentry->d_lock);
86dc4139 17705+ dentry->d_inode = src_dentry->d_inode; /* tmp */
c1595e42 17706+ spin_unlock(&dentry->d_lock);
392086de 17707+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 17708+ if (IS_ERR(h_file))
4a4d8108 17709+ err = PTR_ERR(h_file);
86dc4139 17710+ else {
c2b27bf2
AM
17711+ struct au_cp_generic cpg = {
17712+ .dentry = dentry,
17713+ .bdst = a->bdst,
17714+ .bsrc = -1,
17715+ .len = -1,
17716+ .pin = &a->pin,
17717+ .flags = AuCpup_KEEPLINO
17718+ };
17719+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
17720+ au_h_open_post(dentry, a->bsrc, h_file);
17721+ if (!err) {
17722+ dput(a->h_path.dentry);
17723+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17724+ } else
17725+ au_set_h_dptr(dentry, a->bdst,
17726+ a->h_path.dentry);
17727+ }
c1595e42 17728+ spin_lock(&dentry->d_lock);
86dc4139 17729+ dentry->d_inode = NULL; /* restore */
c1595e42
JR
17730+ spin_unlock(&dentry->d_lock);
17731+ AuDbg("temporary d_inode...done\n");
86dc4139
AM
17732+ au_set_h_dptr(dentry, a->bsrc, NULL);
17733+ au_set_dbend(dentry, bend);
4a4d8108
AM
17734+ } else {
17735+ /* the inode of src_dentry already exists on a.bdst branch */
17736+ h_src_dentry = d_find_alias(h_inode);
17737+ if (!h_src_dentry && au_plink_test(inode)) {
17738+ plink = 1;
17739+ h_src_dentry = au_plink_lkup(inode, a->bdst);
17740+ err = PTR_ERR(h_src_dentry);
17741+ if (IS_ERR(h_src_dentry))
17742+ goto out;
17743+
17744+ if (unlikely(!h_src_dentry->d_inode)) {
17745+ dput(h_src_dentry);
17746+ h_src_dentry = NULL;
17747+ }
17748+
17749+ }
17750+ if (h_src_dentry) {
523b37e3 17751+ delegated = NULL;
4a4d8108 17752+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17753+ &a->h_path, &delegated);
17754+ if (unlikely(err == -EWOULDBLOCK)) {
17755+ pr_warn("cannot retry for NFSv4 delegation"
17756+ " for an internal link\n");
17757+ iput(delegated);
17758+ }
4a4d8108
AM
17759+ dput(h_src_dentry);
17760+ } else {
17761+ AuIOErr("no dentry found for hi%lu on b%d\n",
17762+ h_inode->i_ino, a->bdst);
17763+ err = -EIO;
17764+ }
17765+ }
17766+
17767+ if (!err && !plink)
17768+ au_plink_append(inode, a->bdst, a->h_path.dentry);
17769+
17770+out:
2cbb1c4b 17771+ AuTraceErr(err);
4a4d8108
AM
17772+ return err;
17773+}
17774+
17775+int aufs_link(struct dentry *src_dentry, struct inode *dir,
17776+ struct dentry *dentry)
17777+{
17778+ int err, rerr;
17779+ struct au_dtime dt;
17780+ struct au_link_args *a;
17781+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 17782+ struct inode *inode, *delegated;
4a4d8108
AM
17783+ struct super_block *sb;
17784+ struct au_wr_dir_args wr_dir_args = {
17785+ /* .force_btgt = -1, */
17786+ .flags = AuWrDir_ADD_ENTRY
17787+ };
17788+
17789+ IMustLock(dir);
17790+ inode = src_dentry->d_inode;
17791+ IMustLock(inode);
17792+
4a4d8108
AM
17793+ err = -ENOMEM;
17794+ a = kzalloc(sizeof(*a), GFP_NOFS);
17795+ if (unlikely(!a))
17796+ goto out;
17797+
17798+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17799+ err = aufs_read_and_write_lock2(dentry, src_dentry,
17800+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
17801+ if (unlikely(err))
17802+ goto out_kfree;
38d290e6 17803+ err = au_d_linkable(src_dentry);
027c5e7a
AM
17804+ if (unlikely(err))
17805+ goto out_unlock;
17806+ err = au_d_may_add(dentry);
17807+ if (unlikely(err))
17808+ goto out_unlock;
e49829fe 17809+
4a4d8108 17810+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 17811+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
17812+
17813+ di_write_lock_parent(a->parent);
17814+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
17815+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
17816+ &wr_dir_args);
17817+ err = PTR_ERR(wh_dentry);
17818+ if (IS_ERR(wh_dentry))
027c5e7a 17819+ goto out_parent;
4a4d8108
AM
17820+
17821+ err = 0;
17822+ sb = dentry->d_sb;
17823+ a->bdst = au_dbstart(dentry);
17824+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17825+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
17826+ a->bsrc = au_ibstart(inode);
17827+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
17828+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
17829+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b
JR
17830+ if (!h_src_dentry) {
17831+ a->bsrc = au_dbstart(src_dentry);
17832+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
17833+ AuDebugOn(!h_src_dentry);
38d290e6
JR
17834+ } else if (IS_ERR(h_src_dentry)) {
17835+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 17836+ goto out_parent;
38d290e6 17837+ }
2cbb1c4b 17838+
4a4d8108
AM
17839+ if (au_opt_test(au_mntflags(sb), PLINK)) {
17840+ if (a->bdst < a->bsrc
17841+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 17842+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
17843+ else {
17844+ delegated = NULL;
4a4d8108 17845+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17846+ &a->h_path, &delegated);
17847+ if (unlikely(err == -EWOULDBLOCK)) {
17848+ pr_warn("cannot retry for NFSv4 delegation"
17849+ " for an internal link\n");
17850+ iput(delegated);
17851+ }
17852+ }
2cbb1c4b 17853+ dput(h_src_dentry);
4a4d8108
AM
17854+ } else {
17855+ /*
17856+ * copyup src_dentry to the branch we process,
17857+ * and then link(2) to it.
17858+ */
2cbb1c4b 17859+ dput(h_src_dentry);
4a4d8108
AM
17860+ if (a->bdst < a->bsrc
17861+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
17862+ au_unpin(&a->pin);
17863+ di_write_unlock(a->parent);
17864+ err = au_cpup_before_link(src_dentry, a);
17865+ di_write_lock_parent(a->parent);
17866+ if (!err)
17867+ err = au_pin(&a->pin, dentry, a->bdst,
17868+ au_opt_udba(sb),
17869+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17870+ if (unlikely(err))
17871+ goto out_wh;
17872+ }
17873+ if (!err) {
17874+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
17875+ err = -ENOENT;
523b37e3
AM
17876+ if (h_src_dentry && h_src_dentry->d_inode) {
17877+ delegated = NULL;
4a4d8108
AM
17878+ err = vfsub_link(h_src_dentry,
17879+ au_pinned_h_dir(&a->pin),
523b37e3
AM
17880+ &a->h_path, &delegated);
17881+ if (unlikely(err == -EWOULDBLOCK)) {
17882+ pr_warn("cannot retry"
17883+ " for NFSv4 delegation"
17884+ " for an internal link\n");
17885+ iput(delegated);
17886+ }
17887+ }
4a4d8108
AM
17888+ }
17889+ }
17890+ if (unlikely(err))
17891+ goto out_unpin;
17892+
17893+ if (wh_dentry) {
17894+ a->h_path.dentry = wh_dentry;
17895+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
17896+ dentry);
17897+ if (unlikely(err))
17898+ goto out_revert;
17899+ }
17900+
17901+ dir->i_version++;
17902+ if (au_ibstart(dir) == au_dbstart(dentry))
17903+ au_cpup_attr_timesizes(dir);
17904+ inc_nlink(inode);
17905+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
17906+ d_instantiate(dentry, au_igrab(inode));
17907+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
17908+ /* some filesystem calls d_drop() */
17909+ d_drop(dentry);
076b876e
AM
17910+ /* some filesystems consume an inode even hardlink */
17911+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
17912+ goto out_unpin; /* success */
17913+
4f0767ce 17914+out_revert:
523b37e3
AM
17915+ /* no delegation since it is just created */
17916+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
17917+ /*delegated*/NULL, /*force*/0);
027c5e7a 17918+ if (unlikely(rerr)) {
523b37e3 17919+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
17920+ err = -EIO;
17921+ }
4a4d8108 17922+ au_dtime_revert(&dt);
4f0767ce 17923+out_unpin:
4a4d8108 17924+ au_unpin(&a->pin);
4f0767ce 17925+out_wh:
4a4d8108 17926+ dput(wh_dentry);
027c5e7a
AM
17927+out_parent:
17928+ di_write_unlock(a->parent);
17929+ dput(a->src_parent);
4f0767ce 17930+out_unlock:
4a4d8108
AM
17931+ if (unlikely(err)) {
17932+ au_update_dbstart(dentry);
17933+ d_drop(dentry);
17934+ }
4a4d8108 17935+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 17936+out_kfree:
4a4d8108 17937+ kfree(a);
4f0767ce 17938+out:
86dc4139 17939+ AuTraceErr(err);
4a4d8108
AM
17940+ return err;
17941+}
17942+
7eafdf33 17943+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
17944+{
17945+ int err, rerr;
17946+ aufs_bindex_t bindex;
17947+ unsigned char diropq;
17948+ struct path h_path;
17949+ struct dentry *wh_dentry, *parent, *opq_dentry;
17950+ struct mutex *h_mtx;
17951+ struct super_block *sb;
17952+ struct {
17953+ struct au_pin pin;
17954+ struct au_dtime dt;
17955+ } *a; /* reduce the stack usage */
17956+ struct au_wr_dir_args wr_dir_args = {
17957+ .force_btgt = -1,
17958+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
17959+ };
17960+
17961+ IMustLock(dir);
17962+
17963+ err = -ENOMEM;
17964+ a = kmalloc(sizeof(*a), GFP_NOFS);
17965+ if (unlikely(!a))
17966+ goto out;
17967+
027c5e7a
AM
17968+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17969+ if (unlikely(err))
17970+ goto out_free;
17971+ err = au_d_may_add(dentry);
17972+ if (unlikely(err))
17973+ goto out_unlock;
17974+
4a4d8108
AM
17975+ parent = dentry->d_parent; /* dir inode is locked */
17976+ di_write_lock_parent(parent);
17977+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17978+ &a->pin, &wr_dir_args);
17979+ err = PTR_ERR(wh_dentry);
17980+ if (IS_ERR(wh_dentry))
027c5e7a 17981+ goto out_parent;
4a4d8108
AM
17982+
17983+ sb = dentry->d_sb;
17984+ bindex = au_dbstart(dentry);
17985+ h_path.dentry = au_h_dptr(dentry, bindex);
17986+ h_path.mnt = au_sbr_mnt(sb, bindex);
17987+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
17988+ if (unlikely(err))
027c5e7a 17989+ goto out_unpin;
4a4d8108
AM
17990+
17991+ /* make the dir opaque */
17992+ diropq = 0;
17993+ h_mtx = &h_path.dentry->d_inode->i_mutex;
17994+ if (wh_dentry
17995+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
17996+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17997+ opq_dentry = au_diropq_create(dentry, bindex);
17998+ mutex_unlock(h_mtx);
17999+ err = PTR_ERR(opq_dentry);
18000+ if (IS_ERR(opq_dentry))
18001+ goto out_dir;
18002+ dput(opq_dentry);
18003+ diropq = 1;
18004+ }
18005+
18006+ err = epilog(dir, bindex, wh_dentry, dentry);
18007+ if (!err) {
18008+ inc_nlink(dir);
027c5e7a 18009+ goto out_unpin; /* success */
4a4d8108
AM
18010+ }
18011+
18012+ /* revert */
18013+ if (diropq) {
18014+ AuLabel(revert opq);
18015+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18016+ rerr = au_diropq_remove(dentry, bindex);
18017+ mutex_unlock(h_mtx);
18018+ if (rerr) {
523b37e3
AM
18019+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
18020+ dentry, err, rerr);
4a4d8108
AM
18021+ err = -EIO;
18022+ }
18023+ }
18024+
4f0767ce 18025+out_dir:
4a4d8108
AM
18026+ AuLabel(revert dir);
18027+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
18028+ if (rerr) {
523b37e3
AM
18029+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
18030+ dentry, err, rerr);
4a4d8108
AM
18031+ err = -EIO;
18032+ }
4a4d8108 18033+ au_dtime_revert(&a->dt);
027c5e7a 18034+out_unpin:
4a4d8108
AM
18035+ au_unpin(&a->pin);
18036+ dput(wh_dentry);
027c5e7a
AM
18037+out_parent:
18038+ di_write_unlock(parent);
18039+out_unlock:
4a4d8108
AM
18040+ if (unlikely(err)) {
18041+ au_update_dbstart(dentry);
18042+ d_drop(dentry);
18043+ }
4a4d8108 18044+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 18045+out_free:
4a4d8108 18046+ kfree(a);
4f0767ce 18047+out:
4a4d8108
AM
18048+ return err;
18049+}
7f207e10
AM
18050diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
18051--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
18052+++ linux/fs/aufs/i_op.c 2015-03-27 21:56:35.463461668 +0100
18053@@ -0,0 +1,1299 @@
4a4d8108 18054+/*
2000de60 18055+ * Copyright (C) 2005-2015 Junjiro R. Okajima
4a4d8108
AM
18056+ *
18057+ * This program, aufs is free software; you can redistribute it and/or modify
18058+ * it under the terms of the GNU General Public License as published by
18059+ * the Free Software Foundation; either version 2 of the License, or
18060+ * (at your option) any later version.
18061+ *
18062+ * This program is distributed in the hope that it will be useful,
18063+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18064+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18065+ * GNU General Public License for more details.
18066+ *
18067+ * You should have received a copy of the GNU General Public License
523b37e3 18068+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18069+ */
1facf9fc 18070+
1308ab2a 18071+/*
4a4d8108 18072+ * inode operations (except add/del/rename)
1308ab2a 18073+ */
4a4d8108
AM
18074+
18075+#include <linux/device_cgroup.h>
18076+#include <linux/fs_stack.h>
92d182d2 18077+#include <linux/mm.h>
4a4d8108
AM
18078+#include <linux/namei.h>
18079+#include <linux/security.h>
4a4d8108
AM
18080+#include "aufs.h"
18081+
1e00d052 18082+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 18083+ struct vfsmount *h_mnt, int brperm)
1facf9fc 18084+{
1308ab2a 18085+ int err;
4a4d8108 18086+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 18087+
4a4d8108
AM
18088+ err = -EACCES;
18089+ if ((write_mask && IS_IMMUTABLE(h_inode))
18090+ || ((mask & MAY_EXEC)
18091+ && S_ISREG(h_inode->i_mode)
18092+ && ((h_mnt->mnt_flags & MNT_NOEXEC)
18093+ || !(h_inode->i_mode & S_IXUGO))))
18094+ goto out;
18095+
18096+ /*
18097+ * - skip the lower fs test in the case of write to ro branch.
18098+ * - nfs dir permission write check is optimized, but a policy for
18099+ * link/rename requires a real check.
18100+ */
18101+ if ((write_mask && !au_br_writable(brperm))
18102+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
18103+ && write_mask && !(mask & MAY_READ))
18104+ || !h_inode->i_op->permission) {
18105+ /* AuLabel(generic_permission); */
1e00d052 18106+ err = generic_permission(h_inode, mask);
1308ab2a 18107+ } else {
4a4d8108 18108+ /* AuLabel(h_inode->permission); */
1e00d052 18109+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
18110+ AuTraceErr(err);
18111+ }
1facf9fc 18112+
4a4d8108
AM
18113+ if (!err)
18114+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 18115+ if (!err)
4a4d8108 18116+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
18117+
18118+#if 0
18119+ if (!err) {
18120+ /* todo: do we need to call ima_path_check()? */
18121+ struct path h_path = {
18122+ .dentry =
18123+ .mnt = h_mnt
18124+ };
18125+ err = ima_path_check(&h_path,
18126+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
18127+ IMA_COUNT_LEAVE);
1308ab2a 18128+ }
4a4d8108 18129+#endif
dece6358 18130+
4f0767ce 18131+out:
1308ab2a 18132+ return err;
18133+}
dece6358 18134+
1e00d052 18135+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 18136+{
18137+ int err;
4a4d8108
AM
18138+ aufs_bindex_t bindex, bend;
18139+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
18140+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
18141+ struct inode *h_inode;
18142+ struct super_block *sb;
18143+ struct au_branch *br;
1facf9fc 18144+
027c5e7a 18145+ /* todo: support rcu-walk? */
1e00d052 18146+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
18147+ return -ECHILD;
18148+
4a4d8108
AM
18149+ sb = inode->i_sb;
18150+ si_read_lock(sb, AuLock_FLUSH);
18151+ ii_read_lock_child(inode);
027c5e7a
AM
18152+#if 0
18153+ err = au_iigen_test(inode, au_sigen(sb));
18154+ if (unlikely(err))
18155+ goto out;
18156+#endif
dece6358 18157+
076b876e
AM
18158+ if (!isdir
18159+ || write_mask
18160+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108
AM
18161+ err = au_busy_or_stale();
18162+ h_inode = au_h_iptr(inode, au_ibstart(inode));
18163+ if (unlikely(!h_inode
18164+ || (h_inode->i_mode & S_IFMT)
18165+ != (inode->i_mode & S_IFMT)))
18166+ goto out;
1facf9fc 18167+
4a4d8108
AM
18168+ err = 0;
18169+ bindex = au_ibstart(inode);
18170+ br = au_sbr(sb, bindex);
86dc4139 18171+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
4a4d8108
AM
18172+ if (write_mask
18173+ && !err
18174+ && !special_file(h_inode->i_mode)) {
18175+ /* test whether the upper writable branch exists */
18176+ err = -EROFS;
18177+ for (; bindex >= 0; bindex--)
18178+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
18179+ err = 0;
18180+ break;
18181+ }
18182+ }
18183+ goto out;
18184+ }
dece6358 18185+
4a4d8108 18186+ /* non-write to dir */
1308ab2a 18187+ err = 0;
4a4d8108
AM
18188+ bend = au_ibend(inode);
18189+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
18190+ h_inode = au_h_iptr(inode, bindex);
18191+ if (h_inode) {
18192+ err = au_busy_or_stale();
18193+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
18194+ break;
18195+
18196+ br = au_sbr(sb, bindex);
86dc4139 18197+ err = h_permission(h_inode, mask, au_br_mnt(br),
4a4d8108
AM
18198+ br->br_perm);
18199+ }
18200+ }
1308ab2a 18201+
4f0767ce 18202+out:
4a4d8108
AM
18203+ ii_read_unlock(inode);
18204+ si_read_unlock(sb);
1308ab2a 18205+ return err;
18206+}
18207+
4a4d8108 18208+/* ---------------------------------------------------------------------- */
1facf9fc 18209+
4a4d8108 18210+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 18211+ unsigned int flags)
4a4d8108
AM
18212+{
18213+ struct dentry *ret, *parent;
b752ccd1 18214+ struct inode *inode;
4a4d8108 18215+ struct super_block *sb;
1716fcea 18216+ int err, npositive;
dece6358 18217+
4a4d8108 18218+ IMustLock(dir);
1308ab2a 18219+
537831f9
AM
18220+ /* todo: support rcu-walk? */
18221+ ret = ERR_PTR(-ECHILD);
18222+ if (flags & LOOKUP_RCU)
18223+ goto out;
18224+
18225+ ret = ERR_PTR(-ENAMETOOLONG);
18226+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
18227+ goto out;
18228+
4a4d8108 18229+ sb = dir->i_sb;
7f207e10
AM
18230+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18231+ ret = ERR_PTR(err);
18232+ if (unlikely(err))
18233+ goto out;
18234+
4a4d8108
AM
18235+ err = au_di_init(dentry);
18236+ ret = ERR_PTR(err);
18237+ if (unlikely(err))
7f207e10 18238+ goto out_si;
1308ab2a 18239+
9dbd164d 18240+ inode = NULL;
027c5e7a 18241+ npositive = 0; /* suppress a warning */
4a4d8108
AM
18242+ parent = dentry->d_parent; /* dir inode is locked */
18243+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
18244+ err = au_alive_dir(parent);
18245+ if (!err)
18246+ err = au_digen_test(parent, au_sigen(sb));
18247+ if (!err) {
18248+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 18249+ /*type*/0);
027c5e7a
AM
18250+ err = npositive;
18251+ }
4a4d8108 18252+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
18253+ ret = ERR_PTR(err);
18254+ if (unlikely(err < 0))
18255+ goto out_unlock;
1308ab2a 18256+
4a4d8108 18257+ if (npositive) {
b752ccd1 18258+ inode = au_new_inode(dentry, /*must_new*/0);
c1595e42
JR
18259+ if (IS_ERR(inode)) {
18260+ ret = (void *)inode;
18261+ inode = NULL;
18262+ goto out_unlock;
18263+ }
9dbd164d 18264+ }
4a4d8108 18265+
c1595e42
JR
18266+ if (inode)
18267+ atomic_inc(&inode->i_count);
4a4d8108 18268+ ret = d_splice_alias(inode, dentry);
537831f9
AM
18269+#if 0
18270+ if (unlikely(d_need_lookup(dentry))) {
18271+ spin_lock(&dentry->d_lock);
18272+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
18273+ spin_unlock(&dentry->d_lock);
18274+ } else
18275+#endif
c1595e42 18276+ if (inode) {
2000de60 18277+ if (!IS_ERR(ret)) {
c1595e42 18278+ iput(inode);
2000de60
JR
18279+ if (ret && ret != dentry)
18280+ ii_write_unlock(inode);
18281+ } else {
c1595e42
JR
18282+ ii_write_unlock(inode);
18283+ iput(inode);
18284+ inode = NULL;
18285+ }
7f207e10 18286+ }
1facf9fc 18287+
4f0767ce 18288+out_unlock:
4a4d8108 18289+ di_write_unlock(dentry);
2dfbb274 18290+ if (inode) {
1716fcea
AM
18291+ /* verbose coding for lock class name */
18292+ if (unlikely(S_ISLNK(inode->i_mode)))
18293+ au_rw_class(&au_di(dentry)->di_rwsem,
18294+ au_lc_key + AuLcSymlink_DIINFO);
18295+ else if (unlikely(S_ISDIR(inode->i_mode)))
18296+ au_rw_class(&au_di(dentry)->di_rwsem,
18297+ au_lc_key + AuLcDir_DIINFO);
18298+ else /* likely */
18299+ au_rw_class(&au_di(dentry)->di_rwsem,
18300+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 18301+ }
7f207e10 18302+out_si:
4a4d8108 18303+ si_read_unlock(sb);
7f207e10 18304+out:
4a4d8108
AM
18305+ return ret;
18306+}
1facf9fc 18307+
4a4d8108 18308+/* ---------------------------------------------------------------------- */
1facf9fc 18309+
4a4d8108
AM
18310+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
18311+ const unsigned char add_entry, aufs_bindex_t bcpup,
18312+ aufs_bindex_t bstart)
18313+{
18314+ int err;
18315+ struct dentry *h_parent;
18316+ struct inode *h_dir;
1facf9fc 18317+
027c5e7a 18318+ if (add_entry)
4a4d8108 18319+ IMustLock(parent->d_inode);
027c5e7a 18320+ else
4a4d8108
AM
18321+ di_write_lock_parent(parent);
18322+
18323+ err = 0;
18324+ if (!au_h_dptr(parent, bcpup)) {
c2b27bf2
AM
18325+ if (bstart > bcpup)
18326+ err = au_cpup_dirs(dentry, bcpup);
18327+ else if (bstart < bcpup)
4a4d8108
AM
18328+ err = au_cpdown_dirs(dentry, bcpup);
18329+ else
c2b27bf2 18330+ BUG();
4a4d8108 18331+ }
38d290e6 18332+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108
AM
18333+ h_parent = au_h_dptr(parent, bcpup);
18334+ h_dir = h_parent->d_inode;
18335+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
86dc4139
AM
18336+ err = au_lkup_neg(dentry, bcpup,
18337+ au_ftest_wrdir(add_entry, TMP_WHENTRY));
4a4d8108
AM
18338+ /* todo: no unlock here */
18339+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
18340+
18341+ AuDbg("bcpup %d\n", bcpup);
18342+ if (!err) {
18343+ if (!dentry->d_inode)
18344+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
18345+ au_update_dbrange(dentry, /*do_put_zero*/0);
18346+ }
1308ab2a 18347+ }
1facf9fc 18348+
4a4d8108
AM
18349+ if (!add_entry)
18350+ di_write_unlock(parent);
18351+ if (!err)
18352+ err = bcpup; /* success */
1308ab2a 18353+
027c5e7a 18354+ AuTraceErr(err);
4a4d8108
AM
18355+ return err;
18356+}
1facf9fc 18357+
4a4d8108
AM
18358+/*
18359+ * decide the branch and the parent dir where we will create a new entry.
18360+ * returns new bindex or an error.
18361+ * copyup the parent dir if needed.
18362+ */
18363+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18364+ struct au_wr_dir_args *args)
18365+{
18366+ int err;
392086de 18367+ unsigned int flags;
4a4d8108 18368+ aufs_bindex_t bcpup, bstart, src_bstart;
86dc4139
AM
18369+ const unsigned char add_entry
18370+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6
JR
18371+ | au_ftest_wrdir(args->flags, TMP_WHENTRY)
18372+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
18373+ struct super_block *sb;
18374+ struct dentry *parent;
18375+ struct au_sbinfo *sbinfo;
1facf9fc 18376+
4a4d8108
AM
18377+ sb = dentry->d_sb;
18378+ sbinfo = au_sbi(sb);
18379+ parent = dget_parent(dentry);
18380+ bstart = au_dbstart(dentry);
18381+ bcpup = bstart;
18382+ if (args->force_btgt < 0) {
18383+ if (src_dentry) {
18384+ src_bstart = au_dbstart(src_dentry);
18385+ if (src_bstart < bstart)
18386+ bcpup = src_bstart;
18387+ } else if (add_entry) {
392086de
AM
18388+ flags = 0;
18389+ if (au_ftest_wrdir(args->flags, ISDIR))
18390+ au_fset_wbr(flags, DIR);
18391+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
18392+ bcpup = err;
18393+ }
1facf9fc 18394+
4a4d8108
AM
18395+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
18396+ if (add_entry)
18397+ err = AuWbrCopyup(sbinfo, dentry);
18398+ else {
18399+ if (!IS_ROOT(dentry)) {
18400+ di_read_lock_parent(parent, !AuLock_IR);
18401+ err = AuWbrCopyup(sbinfo, dentry);
18402+ di_read_unlock(parent, !AuLock_IR);
18403+ } else
18404+ err = AuWbrCopyup(sbinfo, dentry);
18405+ }
18406+ bcpup = err;
18407+ if (unlikely(err < 0))
18408+ goto out;
18409+ }
18410+ } else {
18411+ bcpup = args->force_btgt;
18412+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
1308ab2a 18413+ }
027c5e7a 18414+
4a4d8108
AM
18415+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
18416+ err = bcpup;
18417+ if (bcpup == bstart)
18418+ goto out; /* success */
4a4d8108
AM
18419+
18420+ /* copyup the new parent into the branch we process */
18421+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
18422+ if (err >= 0) {
18423+ if (!dentry->d_inode) {
18424+ au_set_h_dptr(dentry, bstart, NULL);
18425+ au_set_dbstart(dentry, bcpup);
18426+ au_set_dbend(dentry, bcpup);
18427+ }
38d290e6
JR
18428+ AuDebugOn(add_entry
18429+ && !au_ftest_wrdir(args->flags, TMPFILE)
18430+ && !au_h_dptr(dentry, bcpup));
027c5e7a 18431+ }
86dc4139
AM
18432+
18433+out:
18434+ dput(parent);
18435+ return err;
18436+}
18437+
18438+/* ---------------------------------------------------------------------- */
18439+
18440+void au_pin_hdir_unlock(struct au_pin *p)
18441+{
18442+ if (p->hdir)
18443+ au_hn_imtx_unlock(p->hdir);
18444+}
18445+
c1595e42 18446+int au_pin_hdir_lock(struct au_pin *p)
86dc4139
AM
18447+{
18448+ int err;
18449+
18450+ err = 0;
18451+ if (!p->hdir)
18452+ goto out;
18453+
18454+ /* even if an error happens later, keep this lock */
18455+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
18456+
18457+ err = -EBUSY;
18458+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
18459+ goto out;
18460+
18461+ err = 0;
18462+ if (p->h_dentry)
18463+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
18464+ p->h_parent, p->br);
18465+
18466+out:
18467+ return err;
18468+}
18469+
18470+int au_pin_hdir_relock(struct au_pin *p)
18471+{
18472+ int err, i;
18473+ struct inode *h_i;
18474+ struct dentry *h_d[] = {
18475+ p->h_dentry,
18476+ p->h_parent
18477+ };
18478+
18479+ err = au_pin_hdir_lock(p);
18480+ if (unlikely(err))
18481+ goto out;
18482+
18483+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
18484+ if (!h_d[i])
18485+ continue;
18486+ h_i = h_d[i]->d_inode;
18487+ if (h_i)
18488+ err = !h_i->i_nlink;
18489+ }
18490+
18491+out:
18492+ return err;
18493+}
18494+
18495+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
18496+{
18497+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
18498+ p->hdir->hi_inode->i_mutex.owner = task;
18499+#endif
18500+}
18501+
18502+void au_pin_hdir_acquire_nest(struct au_pin *p)
18503+{
18504+ if (p->hdir) {
18505+ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
18506+ p->lsc_hi, 0, NULL, _RET_IP_);
18507+ au_pin_hdir_set_owner(p, current);
18508+ }
dece6358 18509+}
1facf9fc 18510+
86dc4139
AM
18511+void au_pin_hdir_release(struct au_pin *p)
18512+{
18513+ if (p->hdir) {
18514+ au_pin_hdir_set_owner(p, p->task);
18515+ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
18516+ }
18517+}
1308ab2a 18518+
4a4d8108 18519+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 18520+{
4a4d8108
AM
18521+ if (pin && pin->parent)
18522+ return au_h_dptr(pin->parent, pin->bindex);
18523+ return NULL;
dece6358 18524+}
1facf9fc 18525+
4a4d8108 18526+void au_unpin(struct au_pin *p)
dece6358 18527+{
86dc4139
AM
18528+ if (p->hdir)
18529+ au_pin_hdir_unlock(p);
e49829fe 18530+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 18531+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
18532+ if (!p->hdir)
18533+ return;
1facf9fc 18534+
4a4d8108
AM
18535+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18536+ di_read_unlock(p->parent, AuLock_IR);
18537+ iput(p->hdir->hi_inode);
18538+ dput(p->parent);
18539+ p->parent = NULL;
18540+ p->hdir = NULL;
18541+ p->h_mnt = NULL;
86dc4139 18542+ /* do not clear p->task */
4a4d8108 18543+}
1308ab2a 18544+
4a4d8108
AM
18545+int au_do_pin(struct au_pin *p)
18546+{
18547+ int err;
18548+ struct super_block *sb;
4a4d8108
AM
18549+ struct inode *h_dir;
18550+
18551+ err = 0;
18552+ sb = p->dentry->d_sb;
86dc4139 18553+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
18554+ if (IS_ROOT(p->dentry)) {
18555+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18556+ p->h_mnt = au_br_mnt(p->br);
b4510431 18557+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
18558+ if (unlikely(err)) {
18559+ au_fclr_pin(p->flags, MNT_WRITE);
18560+ goto out_err;
18561+ }
18562+ }
dece6358 18563+ goto out;
1facf9fc 18564+ }
18565+
86dc4139 18566+ p->h_dentry = NULL;
4a4d8108 18567+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 18568+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 18569+
4a4d8108
AM
18570+ p->parent = dget_parent(p->dentry);
18571+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18572+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 18573+
4a4d8108 18574+ h_dir = NULL;
86dc4139 18575+ p->h_parent = au_h_dptr(p->parent, p->bindex);
4a4d8108
AM
18576+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
18577+ if (p->hdir)
18578+ h_dir = p->hdir->hi_inode;
dece6358 18579+
b752ccd1
AM
18580+ /*
18581+ * udba case, or
18582+ * if DI_LOCKED is not set, then p->parent may be different
18583+ * and h_parent can be NULL.
18584+ */
86dc4139 18585+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 18586+ err = -EBUSY;
4a4d8108
AM
18587+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18588+ di_read_unlock(p->parent, AuLock_IR);
18589+ dput(p->parent);
18590+ p->parent = NULL;
18591+ goto out_err;
18592+ }
1308ab2a 18593+
4a4d8108 18594+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18595+ p->h_mnt = au_br_mnt(p->br);
b4510431 18596+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 18597+ if (unlikely(err)) {
4a4d8108 18598+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
18599+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18600+ di_read_unlock(p->parent, AuLock_IR);
18601+ dput(p->parent);
18602+ p->parent = NULL;
18603+ goto out_err;
dece6358
AM
18604+ }
18605+ }
4a4d8108 18606+
86dc4139
AM
18607+ au_igrab(h_dir);
18608+ err = au_pin_hdir_lock(p);
18609+ if (!err)
18610+ goto out; /* success */
18611+
076b876e
AM
18612+ au_unpin(p);
18613+
4f0767ce 18614+out_err:
4a4d8108
AM
18615+ pr_err("err %d\n", err);
18616+ err = au_busy_or_stale();
4f0767ce 18617+out:
1facf9fc 18618+ return err;
18619+}
18620+
4a4d8108
AM
18621+void au_pin_init(struct au_pin *p, struct dentry *dentry,
18622+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18623+ unsigned int udba, unsigned char flags)
18624+{
18625+ p->dentry = dentry;
18626+ p->udba = udba;
18627+ p->lsc_di = lsc_di;
18628+ p->lsc_hi = lsc_hi;
18629+ p->flags = flags;
18630+ p->bindex = bindex;
18631+
18632+ p->parent = NULL;
18633+ p->hdir = NULL;
18634+ p->h_mnt = NULL;
86dc4139
AM
18635+
18636+ p->h_dentry = NULL;
18637+ p->h_parent = NULL;
18638+ p->br = NULL;
18639+ p->task = current;
4a4d8108
AM
18640+}
18641+
18642+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18643+ unsigned int udba, unsigned char flags)
18644+{
18645+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
18646+ udba, flags);
18647+ return au_do_pin(pin);
18648+}
18649+
dece6358
AM
18650+/* ---------------------------------------------------------------------- */
18651+
1308ab2a 18652+/*
4a4d8108
AM
18653+ * ->setattr() and ->getattr() are called in various cases.
18654+ * chmod, stat: dentry is revalidated.
18655+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
18656+ * unhashed.
18657+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 18658+ */
027c5e7a 18659+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
c1595e42 18660+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 18661+{
4a4d8108
AM
18662+ int err;
18663+ struct inode *inode;
18664+ struct dentry *parent;
1facf9fc 18665+
1308ab2a 18666+ err = 0;
4a4d8108 18667+ inode = dentry->d_inode;
027c5e7a 18668+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
18669+ parent = dget_parent(dentry);
18670+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 18671+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
18672+ di_read_unlock(parent, AuLock_IR);
18673+ dput(parent);
dece6358 18674+ }
1facf9fc 18675+
4a4d8108 18676+ AuTraceErr(err);
1308ab2a 18677+ return err;
18678+}
dece6358 18679+
c1595e42
JR
18680+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
18681+ struct au_icpup_args *a)
1308ab2a 18682+{
18683+ int err;
4a4d8108 18684+ loff_t sz;
e49829fe 18685+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
18686+ struct dentry *hi_wh, *parent;
18687+ struct inode *inode;
4a4d8108
AM
18688+ struct au_wr_dir_args wr_dir_args = {
18689+ .force_btgt = -1,
18690+ .flags = 0
18691+ };
18692+
2000de60 18693+ if (d_is_dir(dentry))
4a4d8108
AM
18694+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
18695+ /* plink or hi_wh() case */
2000de60
JR
18696+ bstart = au_dbstart(dentry);
18697+ inode = dentry->d_inode;
e49829fe 18698+ ibstart = au_ibstart(inode);
027c5e7a 18699+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 18700+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
18701+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
18702+ if (unlikely(err < 0))
18703+ goto out;
18704+ a->btgt = err;
18705+ if (err != bstart)
18706+ au_fset_icpup(a->flags, DID_CPUP);
18707+
18708+ err = 0;
18709+ a->pin_flags = AuPin_MNT_WRITE;
18710+ parent = NULL;
18711+ if (!IS_ROOT(dentry)) {
18712+ au_fset_pin(a->pin_flags, DI_LOCKED);
18713+ parent = dget_parent(dentry);
18714+ di_write_lock_parent(parent);
18715+ }
18716+
18717+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
18718+ if (unlikely(err))
18719+ goto out_parent;
18720+
18721+ a->h_path.dentry = au_h_dptr(dentry, bstart);
18722+ a->h_inode = a->h_path.dentry->d_inode;
4a4d8108 18723+ sz = -1;
c1595e42
JR
18724+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
18725+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
18726+ if (ia->ia_size < i_size_read(a->h_inode))
18727+ sz = ia->ia_size;
18728+ mutex_unlock(&a->h_inode->i_mutex);
18729+ }
4a4d8108 18730+
4a4d8108 18731+ hi_wh = NULL;
027c5e7a 18732+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
18733+ hi_wh = au_hi_wh(inode, a->btgt);
18734+ if (!hi_wh) {
c2b27bf2
AM
18735+ struct au_cp_generic cpg = {
18736+ .dentry = dentry,
18737+ .bdst = a->btgt,
18738+ .bsrc = -1,
18739+ .len = sz,
18740+ .pin = &a->pin
18741+ };
18742+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
18743+ if (unlikely(err))
18744+ goto out_unlock;
18745+ hi_wh = au_hi_wh(inode, a->btgt);
18746+ /* todo: revalidate hi_wh? */
18747+ }
18748+ }
18749+
18750+ if (parent) {
18751+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
18752+ di_downgrade_lock(parent, AuLock_IR);
18753+ dput(parent);
18754+ parent = NULL;
18755+ }
18756+ if (!au_ftest_icpup(a->flags, DID_CPUP))
18757+ goto out; /* success */
18758+
18759+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
18760+ struct au_cp_generic cpg = {
18761+ .dentry = dentry,
18762+ .bdst = a->btgt,
18763+ .bsrc = bstart,
18764+ .len = sz,
18765+ .pin = &a->pin,
18766+ .flags = AuCpup_DTIME | AuCpup_HOPEN
18767+ };
18768+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
18769+ if (!err)
18770+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18771+ } else if (!hi_wh)
18772+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18773+ else
18774+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 18775+
4f0767ce 18776+out_unlock:
4a4d8108 18777+ a->h_inode = a->h_path.dentry->d_inode;
86dc4139 18778+ if (!err)
dece6358 18779+ goto out; /* success */
4a4d8108 18780+ au_unpin(&a->pin);
4f0767ce 18781+out_parent:
4a4d8108
AM
18782+ if (parent) {
18783+ di_write_unlock(parent);
18784+ dput(parent);
18785+ }
4f0767ce 18786+out:
86dc4139
AM
18787+ if (!err)
18788+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 18789+ return err;
18790+}
18791+
4a4d8108 18792+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 18793+{
4a4d8108 18794+ int err;
523b37e3 18795+ struct inode *inode, *delegated;
4a4d8108
AM
18796+ struct super_block *sb;
18797+ struct file *file;
18798+ struct au_icpup_args *a;
1facf9fc 18799+
4a4d8108
AM
18800+ inode = dentry->d_inode;
18801+ IMustLock(inode);
dece6358 18802+
4a4d8108
AM
18803+ err = -ENOMEM;
18804+ a = kzalloc(sizeof(*a), GFP_NOFS);
18805+ if (unlikely(!a))
18806+ goto out;
1facf9fc 18807+
4a4d8108
AM
18808+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
18809+ ia->ia_valid &= ~ATTR_MODE;
dece6358 18810+
4a4d8108
AM
18811+ file = NULL;
18812+ sb = dentry->d_sb;
e49829fe
JR
18813+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18814+ if (unlikely(err))
18815+ goto out_kfree;
18816+
4a4d8108
AM
18817+ if (ia->ia_valid & ATTR_FILE) {
18818+ /* currently ftruncate(2) only */
18819+ AuDebugOn(!S_ISREG(inode->i_mode));
18820+ file = ia->ia_file;
18821+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
18822+ if (unlikely(err))
18823+ goto out_si;
18824+ ia->ia_file = au_hf_top(file);
18825+ a->udba = AuOpt_UDBA_NONE;
18826+ } else {
18827+ /* fchmod() doesn't pass ia_file */
18828+ a->udba = au_opt_udba(sb);
027c5e7a
AM
18829+ di_write_lock_child(dentry);
18830+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
18831+ if (d_unhashed(dentry))
18832+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
18833+ if (a->udba != AuOpt_UDBA_NONE) {
18834+ AuDebugOn(IS_ROOT(dentry));
18835+ err = au_reval_for_attr(dentry, au_sigen(sb));
18836+ if (unlikely(err))
18837+ goto out_dentry;
18838+ }
dece6358 18839+ }
dece6358 18840+
4a4d8108
AM
18841+ err = au_pin_and_icpup(dentry, ia, a);
18842+ if (unlikely(err < 0))
18843+ goto out_dentry;
18844+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
18845+ ia->ia_file = NULL;
18846+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 18847+ }
dece6358 18848+
4a4d8108
AM
18849+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
18850+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
18851+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 18852+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
18853+ if (unlikely(err))
18854+ goto out_unlock;
18855+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
18856+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 18857+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
18858+ if (unlikely(err))
18859+ goto out_unlock;
18860+ }
dece6358 18861+
4a4d8108
AM
18862+ if (ia->ia_valid & ATTR_SIZE) {
18863+ struct file *f;
1308ab2a 18864+
953406b4 18865+ if (ia->ia_size < i_size_read(inode))
4a4d8108 18866+ /* unmap only */
953406b4 18867+ truncate_setsize(inode, ia->ia_size);
1308ab2a 18868+
4a4d8108
AM
18869+ f = NULL;
18870+ if (ia->ia_valid & ATTR_FILE)
18871+ f = ia->ia_file;
18872+ mutex_unlock(&a->h_inode->i_mutex);
18873+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
18874+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
523b37e3
AM
18875+ } else {
18876+ delegated = NULL;
18877+ while (1) {
18878+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
18879+ if (delegated) {
18880+ err = break_deleg_wait(&delegated);
18881+ if (!err)
18882+ continue;
18883+ }
18884+ break;
18885+ }
18886+ }
4a4d8108
AM
18887+ if (!err)
18888+ au_cpup_attr_changeable(inode);
1308ab2a 18889+
4f0767ce 18890+out_unlock:
4a4d8108
AM
18891+ mutex_unlock(&a->h_inode->i_mutex);
18892+ au_unpin(&a->pin);
027c5e7a
AM
18893+ if (unlikely(err))
18894+ au_update_dbstart(dentry);
4f0767ce 18895+out_dentry:
4a4d8108
AM
18896+ di_write_unlock(dentry);
18897+ if (file) {
18898+ fi_write_unlock(file);
18899+ ia->ia_file = file;
18900+ ia->ia_valid |= ATTR_FILE;
18901+ }
4f0767ce 18902+out_si:
4a4d8108 18903+ si_read_unlock(sb);
e49829fe 18904+out_kfree:
4a4d8108 18905+ kfree(a);
4f0767ce 18906+out:
4a4d8108
AM
18907+ AuTraceErr(err);
18908+ return err;
1facf9fc 18909+}
18910+
c1595e42
JR
18911+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
18912+static int au_h_path_to_set_attr(struct dentry *dentry,
18913+ struct au_icpup_args *a, struct path *h_path)
18914+{
18915+ int err;
18916+ struct super_block *sb;
18917+
18918+ sb = dentry->d_sb;
18919+ a->udba = au_opt_udba(sb);
18920+ /* no d_unlinked(), to set UDBA_NONE for root */
18921+ if (d_unhashed(dentry))
18922+ a->udba = AuOpt_UDBA_NONE;
18923+ if (a->udba != AuOpt_UDBA_NONE) {
18924+ AuDebugOn(IS_ROOT(dentry));
18925+ err = au_reval_for_attr(dentry, au_sigen(sb));
18926+ if (unlikely(err))
18927+ goto out;
18928+ }
18929+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
18930+ if (unlikely(err < 0))
18931+ goto out;
18932+
18933+ h_path->dentry = a->h_path.dentry;
18934+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
18935+
18936+out:
18937+ return err;
18938+}
18939+
18940+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg)
18941+{
18942+ int err;
18943+ struct path h_path;
18944+ struct super_block *sb;
18945+ struct au_icpup_args *a;
18946+ struct inode *inode, *h_inode;
18947+
18948+ inode = dentry->d_inode;
18949+ IMustLock(inode);
18950+
18951+ err = -ENOMEM;
18952+ a = kzalloc(sizeof(*a), GFP_NOFS);
18953+ if (unlikely(!a))
18954+ goto out;
18955+
18956+ sb = dentry->d_sb;
18957+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18958+ if (unlikely(err))
18959+ goto out_kfree;
18960+
18961+ h_path.dentry = NULL; /* silence gcc */
18962+ di_write_lock_child(dentry);
18963+ err = au_h_path_to_set_attr(dentry, a, &h_path);
18964+ if (unlikely(err))
18965+ goto out_di;
18966+
18967+ mutex_unlock(&a->h_inode->i_mutex);
18968+ switch (arg->type) {
18969+ case AU_XATTR_SET:
18970+ err = vfsub_setxattr(h_path.dentry,
18971+ arg->u.set.name, arg->u.set.value,
18972+ arg->u.set.size, arg->u.set.flags);
18973+ break;
18974+ case AU_XATTR_REMOVE:
18975+ err = vfsub_removexattr(h_path.dentry, arg->u.remove.name);
18976+ break;
18977+ case AU_ACL_SET:
18978+ err = -EOPNOTSUPP;
18979+ h_inode = h_path.dentry->d_inode;
18980+ if (h_inode->i_op->set_acl)
18981+ err = h_inode->i_op->set_acl(h_inode,
18982+ arg->u.acl_set.acl,
18983+ arg->u.acl_set.type);
18984+ break;
18985+ }
18986+ if (!err)
18987+ au_cpup_attr_timesizes(inode);
18988+
18989+ au_unpin(&a->pin);
18990+ if (unlikely(err))
18991+ au_update_dbstart(dentry);
18992+
18993+out_di:
18994+ di_write_unlock(dentry);
18995+ si_read_unlock(sb);
18996+out_kfree:
18997+ kfree(a);
18998+out:
18999+ AuTraceErr(err);
19000+ return err;
19001+}
19002+#endif
19003+
4a4d8108
AM
19004+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
19005+ unsigned int nlink)
1facf9fc 19006+{
9dbd164d
AM
19007+ unsigned int n;
19008+
4a4d8108 19009+ inode->i_mode = st->mode;
86dc4139
AM
19010+ /* don't i_[ug]id_write() here */
19011+ inode->i_uid = st->uid;
19012+ inode->i_gid = st->gid;
4a4d8108
AM
19013+ inode->i_atime = st->atime;
19014+ inode->i_mtime = st->mtime;
19015+ inode->i_ctime = st->ctime;
1facf9fc 19016+
4a4d8108
AM
19017+ au_cpup_attr_nlink(inode, /*force*/0);
19018+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
19019+ n = inode->i_nlink;
19020+ n -= nlink;
19021+ n += st->nlink;
f6b6e03d 19022+ smp_mb(); /* for i_nlink */
7eafdf33 19023+ /* 0 can happen */
92d182d2 19024+ set_nlink(inode, n);
4a4d8108 19025+ }
1facf9fc 19026+
4a4d8108
AM
19027+ spin_lock(&inode->i_lock);
19028+ inode->i_blocks = st->blocks;
19029+ i_size_write(inode, st->size);
19030+ spin_unlock(&inode->i_lock);
1facf9fc 19031+}
19032+
c1595e42
JR
19033+/*
19034+ * common routine for aufs_getattr() and aufs_getxattr().
19035+ * returns zero or negative (an error).
19036+ * @dentry will be read-locked in success.
19037+ */
19038+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path)
1facf9fc 19039+{
4a4d8108 19040+ int err;
076b876e 19041+ unsigned int mnt_flags, sigen;
c1595e42 19042+ unsigned char udba_none;
4a4d8108 19043+ aufs_bindex_t bindex;
4a4d8108
AM
19044+ struct super_block *sb, *h_sb;
19045+ struct inode *inode;
1facf9fc 19046+
c1595e42
JR
19047+ h_path->mnt = NULL;
19048+ h_path->dentry = NULL;
19049+
19050+ err = 0;
4a4d8108 19051+ sb = dentry->d_sb;
4a4d8108
AM
19052+ mnt_flags = au_mntflags(sb);
19053+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 19054+
4a4d8108 19055+ /* support fstat(2) */
027c5e7a 19056+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 19057+ sigen = au_sigen(sb);
027c5e7a
AM
19058+ err = au_digen_test(dentry, sigen);
19059+ if (!err) {
4a4d8108 19060+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a 19061+ err = au_dbrange_test(dentry);
c1595e42
JR
19062+ if (unlikely(err)) {
19063+ di_read_unlock(dentry, AuLock_IR);
19064+ goto out;
19065+ }
027c5e7a 19066+ } else {
4a4d8108
AM
19067+ AuDebugOn(IS_ROOT(dentry));
19068+ di_write_lock_child(dentry);
027c5e7a
AM
19069+ err = au_dbrange_test(dentry);
19070+ if (!err)
19071+ err = au_reval_for_attr(dentry, sigen);
c1595e42
JR
19072+ if (!err)
19073+ di_downgrade_lock(dentry, AuLock_IR);
19074+ else {
19075+ di_write_unlock(dentry);
19076+ goto out;
19077+ }
4a4d8108
AM
19078+ }
19079+ } else
19080+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 19081+
c1595e42 19082+ inode = dentry->d_inode;
4a4d8108 19083+ bindex = au_ibstart(inode);
c1595e42
JR
19084+ h_path->mnt = au_sbr_mnt(sb, bindex);
19085+ h_sb = h_path->mnt->mnt_sb;
19086+ if (!force
19087+ && !au_test_fs_bad_iattr(h_sb)
19088+ && udba_none)
19089+ goto out; /* success */
1facf9fc 19090+
4a4d8108 19091+ if (au_dbstart(dentry) == bindex)
c1595e42 19092+ h_path->dentry = au_h_dptr(dentry, bindex);
4a4d8108 19093+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c1595e42
JR
19094+ h_path->dentry = au_plink_lkup(inode, bindex);
19095+ if (IS_ERR(h_path->dentry))
19096+ /* pretending success */
19097+ h_path->dentry = NULL;
19098+ else
19099+ dput(h_path->dentry);
4a4d8108 19100+ }
c1595e42
JR
19101+
19102+out:
19103+ return err;
19104+}
19105+
19106+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
19107+ struct dentry *dentry, struct kstat *st)
19108+{
19109+ int err;
19110+ unsigned char positive;
19111+ struct path h_path;
19112+ struct inode *inode;
19113+ struct super_block *sb;
19114+
19115+ inode = dentry->d_inode;
19116+ sb = dentry->d_sb;
19117+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19118+ if (unlikely(err))
19119+ goto out;
19120+ err = au_h_path_getattr(dentry, /*force*/0, &h_path);
19121+ if (unlikely(err))
19122+ goto out_si;
c06a8ce3 19123+ if (unlikely(!h_path.dentry))
c1595e42 19124+ /* illegally overlapped or something */
4a4d8108
AM
19125+ goto out_fill; /* pretending success */
19126+
c06a8ce3 19127+ positive = !!h_path.dentry->d_inode;
4a4d8108 19128+ if (positive)
c06a8ce3 19129+ err = vfs_getattr(&h_path, st);
4a4d8108
AM
19130+ if (!err) {
19131+ if (positive)
c06a8ce3
AM
19132+ au_refresh_iattr(inode, st,
19133+ h_path.dentry->d_inode->i_nlink);
4a4d8108 19134+ goto out_fill; /* success */
1facf9fc 19135+ }
7f207e10 19136+ AuTraceErr(err);
c1595e42 19137+ goto out_di;
4a4d8108 19138+
4f0767ce 19139+out_fill:
4a4d8108 19140+ generic_fillattr(inode, st);
c1595e42 19141+out_di:
4a4d8108 19142+ di_read_unlock(dentry, AuLock_IR);
c1595e42 19143+out_si:
4a4d8108 19144+ si_read_unlock(sb);
7f207e10
AM
19145+out:
19146+ AuTraceErr(err);
4a4d8108 19147+ return err;
1facf9fc 19148+}
19149+
19150+/* ---------------------------------------------------------------------- */
19151+
4a4d8108
AM
19152+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
19153+ int bufsiz)
1facf9fc 19154+{
19155+ int err;
4a4d8108
AM
19156+ struct super_block *sb;
19157+ struct dentry *h_dentry;
1facf9fc 19158+
4a4d8108
AM
19159+ err = -EINVAL;
19160+ h_dentry = au_h_dptr(dentry, bindex);
19161+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
19162+ goto out;
1facf9fc 19163+
4a4d8108
AM
19164+ err = security_inode_readlink(h_dentry);
19165+ if (unlikely(err))
dece6358 19166+ goto out;
1facf9fc 19167+
4a4d8108
AM
19168+ sb = dentry->d_sb;
19169+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
19170+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
19171+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
1facf9fc 19172+ }
4a4d8108 19173+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 19174+
4f0767ce 19175+out:
4a4d8108
AM
19176+ return err;
19177+}
1facf9fc 19178+
4a4d8108
AM
19179+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
19180+{
19181+ int err;
1facf9fc 19182+
027c5e7a
AM
19183+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
19184+ if (unlikely(err))
19185+ goto out;
19186+ err = au_d_hashed_positive(dentry);
19187+ if (!err)
19188+ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
4a4d8108 19189+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 19190+
027c5e7a 19191+out:
4a4d8108
AM
19192+ return err;
19193+}
1facf9fc 19194+
4a4d8108
AM
19195+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
19196+{
19197+ int err;
4a4d8108 19198+ mm_segment_t old_fs;
b752ccd1
AM
19199+ union {
19200+ char *k;
19201+ char __user *u;
19202+ } buf;
1facf9fc 19203+
4a4d8108 19204+ err = -ENOMEM;
537831f9 19205+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 19206+ if (unlikely(!buf.k))
4a4d8108 19207+ goto out;
1facf9fc 19208+
027c5e7a
AM
19209+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
19210+ if (unlikely(err))
19211+ goto out_name;
19212+
19213+ err = au_d_hashed_positive(dentry);
19214+ if (!err) {
19215+ old_fs = get_fs();
19216+ set_fs(KERNEL_DS);
19217+ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
19218+ set_fs(old_fs);
19219+ }
4a4d8108 19220+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 19221+
4a4d8108 19222+ if (err >= 0) {
b752ccd1 19223+ buf.k[err] = 0;
4a4d8108 19224+ /* will be freed by put_link */
b752ccd1 19225+ nd_set_link(nd, buf.k);
4a4d8108 19226+ return NULL; /* success */
1308ab2a 19227+ }
1facf9fc 19228+
027c5e7a 19229+out_name:
537831f9 19230+ free_page((unsigned long)buf.k);
4f0767ce 19231+out:
4a4d8108
AM
19232+ AuTraceErr(err);
19233+ return ERR_PTR(err);
19234+}
1facf9fc 19235+
4a4d8108
AM
19236+static void aufs_put_link(struct dentry *dentry __maybe_unused,
19237+ struct nameidata *nd, void *cookie __maybe_unused)
19238+{
537831f9
AM
19239+ char *p;
19240+
19241+ p = nd_get_link(nd);
19242+ if (!IS_ERR_OR_NULL(p))
19243+ free_page((unsigned long)p);
4a4d8108 19244+}
1facf9fc 19245+
4a4d8108 19246+/* ---------------------------------------------------------------------- */
1facf9fc 19247+
0c3ec466 19248+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 19249+{
0c3ec466
AM
19250+ int err;
19251+ struct super_block *sb;
19252+ struct inode *h_inode;
19253+
19254+ sb = inode->i_sb;
19255+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
19256+ lockdep_off();
19257+ si_read_lock(sb, AuLock_FLUSH);
19258+ ii_write_lock_child(inode);
19259+ lockdep_on();
19260+ h_inode = au_h_iptr(inode, au_ibstart(inode));
19261+ err = vfsub_update_time(h_inode, ts, flags);
19262+ lockdep_off();
38d290e6
JR
19263+ if (!err)
19264+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
19265+ ii_write_unlock(inode);
19266+ si_read_unlock(sb);
19267+ lockdep_on();
38d290e6
JR
19268+
19269+ if (!err && (flags & S_VERSION))
19270+ inode_inc_iversion(inode);
19271+
0c3ec466 19272+ return err;
4a4d8108 19273+}
1facf9fc 19274+
4a4d8108 19275+/* ---------------------------------------------------------------------- */
1308ab2a 19276+
4a4d8108
AM
19277+struct inode_operations aufs_symlink_iop = {
19278+ .permission = aufs_permission,
c1595e42
JR
19279+#ifdef CONFIG_FS_POSIX_ACL
19280+ .get_acl = aufs_get_acl,
19281+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
19282+#endif
19283+
4a4d8108
AM
19284+ .setattr = aufs_setattr,
19285+ .getattr = aufs_getattr,
0c3ec466 19286+
c1595e42
JR
19287+#ifdef CONFIG_AUFS_XATTR
19288+ .setxattr = aufs_setxattr,
19289+ .getxattr = aufs_getxattr,
19290+ .listxattr = aufs_listxattr,
19291+ .removexattr = aufs_removexattr,
19292+#endif
19293+
4a4d8108
AM
19294+ .readlink = aufs_readlink,
19295+ .follow_link = aufs_follow_link,
0c3ec466
AM
19296+ .put_link = aufs_put_link,
19297+
19298+ /* .update_time = aufs_update_time */
4a4d8108
AM
19299+};
19300+
19301+struct inode_operations aufs_dir_iop = {
19302+ .create = aufs_create,
19303+ .lookup = aufs_lookup,
19304+ .link = aufs_link,
19305+ .unlink = aufs_unlink,
19306+ .symlink = aufs_symlink,
19307+ .mkdir = aufs_mkdir,
19308+ .rmdir = aufs_rmdir,
19309+ .mknod = aufs_mknod,
19310+ .rename = aufs_rename,
19311+
19312+ .permission = aufs_permission,
c1595e42
JR
19313+#ifdef CONFIG_FS_POSIX_ACL
19314+ .get_acl = aufs_get_acl,
19315+ .set_acl = aufs_set_acl,
19316+#endif
19317+
4a4d8108 19318+ .setattr = aufs_setattr,
0c3ec466
AM
19319+ .getattr = aufs_getattr,
19320+
c1595e42
JR
19321+#ifdef CONFIG_AUFS_XATTR
19322+ .setxattr = aufs_setxattr,
19323+ .getxattr = aufs_getxattr,
19324+ .listxattr = aufs_listxattr,
19325+ .removexattr = aufs_removexattr,
19326+#endif
19327+
38d290e6 19328+ .update_time = aufs_update_time,
b4510431 19329+ /* no support for atomic_open() */
38d290e6
JR
19330+
19331+ .tmpfile = aufs_tmpfile
4a4d8108
AM
19332+};
19333+
19334+struct inode_operations aufs_iop = {
19335+ .permission = aufs_permission,
c1595e42
JR
19336+#ifdef CONFIG_FS_POSIX_ACL
19337+ .get_acl = aufs_get_acl,
19338+ .set_acl = aufs_set_acl,
19339+#endif
19340+
4a4d8108
AM
19341+ .setattr = aufs_setattr,
19342+ .getattr = aufs_getattr,
0c3ec466 19343+
c1595e42
JR
19344+#ifdef CONFIG_AUFS_XATTR
19345+ .setxattr = aufs_setxattr,
19346+ .getxattr = aufs_getxattr,
19347+ .listxattr = aufs_listxattr,
19348+ .removexattr = aufs_removexattr,
19349+#endif
19350+
0c3ec466 19351+ .update_time = aufs_update_time
4a4d8108 19352+};
7f207e10
AM
19353diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
19354--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
2000de60 19355+++ linux/fs/aufs/i_op_del.c 2015-03-27 21:56:35.466795000 +0100
076b876e 19356@@ -0,0 +1,507 @@
1facf9fc 19357+/*
2000de60 19358+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 19359+ *
19360+ * This program, aufs is free software; you can redistribute it and/or modify
19361+ * it under the terms of the GNU General Public License as published by
19362+ * the Free Software Foundation; either version 2 of the License, or
19363+ * (at your option) any later version.
dece6358
AM
19364+ *
19365+ * This program is distributed in the hope that it will be useful,
19366+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19367+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19368+ * GNU General Public License for more details.
19369+ *
19370+ * You should have received a copy of the GNU General Public License
523b37e3 19371+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19372+ */
19373+
19374+/*
4a4d8108 19375+ * inode operations (del entry)
1308ab2a 19376+ */
dece6358 19377+
1308ab2a 19378+#include "aufs.h"
dece6358 19379+
4a4d8108
AM
19380+/*
19381+ * decide if a new whiteout for @dentry is necessary or not.
19382+ * when it is necessary, prepare the parent dir for the upper branch whose
19383+ * branch index is @bcpup for creation. the actual creation of the whiteout will
19384+ * be done by caller.
19385+ * return value:
19386+ * 0: wh is unnecessary
19387+ * plus: wh is necessary
19388+ * minus: error
19389+ */
19390+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 19391+{
4a4d8108
AM
19392+ int need_wh, err;
19393+ aufs_bindex_t bstart;
19394+ struct super_block *sb;
dece6358 19395+
4a4d8108
AM
19396+ sb = dentry->d_sb;
19397+ bstart = au_dbstart(dentry);
19398+ if (*bcpup < 0) {
19399+ *bcpup = bstart;
19400+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
19401+ err = AuWbrCopyup(au_sbi(sb), dentry);
19402+ *bcpup = err;
19403+ if (unlikely(err < 0))
19404+ goto out;
19405+ }
19406+ } else
19407+ AuDebugOn(bstart < *bcpup
19408+ || au_test_ro(sb, *bcpup, dentry->d_inode));
19409+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 19410+
4a4d8108
AM
19411+ if (*bcpup != bstart) {
19412+ err = au_cpup_dirs(dentry, *bcpup);
19413+ if (unlikely(err))
19414+ goto out;
19415+ need_wh = 1;
19416+ } else {
027c5e7a 19417+ struct au_dinfo *dinfo, *tmp;
4a4d8108 19418+
027c5e7a
AM
19419+ need_wh = -ENOMEM;
19420+ dinfo = au_di(dentry);
19421+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
19422+ if (tmp) {
19423+ au_di_cp(tmp, dinfo);
19424+ au_di_swap(tmp, dinfo);
19425+ /* returns the number of positive dentries */
537831f9 19426+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
19427+ au_di_swap(tmp, dinfo);
19428+ au_rw_write_unlock(&tmp->di_rwsem);
19429+ au_di_free(tmp);
4a4d8108
AM
19430+ }
19431+ }
19432+ AuDbg("need_wh %d\n", need_wh);
19433+ err = need_wh;
19434+
4f0767ce 19435+out:
4a4d8108 19436+ return err;
1facf9fc 19437+}
19438+
4a4d8108
AM
19439+/*
19440+ * simple tests for the del-entry operations.
19441+ * following the checks in vfs, plus the parent-child relationship.
19442+ */
19443+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
19444+ struct dentry *h_parent, int isdir)
1facf9fc 19445+{
4a4d8108
AM
19446+ int err;
19447+ umode_t h_mode;
19448+ struct dentry *h_dentry, *h_latest;
1308ab2a 19449+ struct inode *h_inode;
1facf9fc 19450+
4a4d8108
AM
19451+ h_dentry = au_h_dptr(dentry, bindex);
19452+ h_inode = h_dentry->d_inode;
19453+ if (dentry->d_inode) {
19454+ err = -ENOENT;
19455+ if (unlikely(!h_inode || !h_inode->i_nlink))
19456+ goto out;
1facf9fc 19457+
4a4d8108
AM
19458+ h_mode = h_inode->i_mode;
19459+ if (!isdir) {
19460+ err = -EISDIR;
19461+ if (unlikely(S_ISDIR(h_mode)))
19462+ goto out;
19463+ } else if (unlikely(!S_ISDIR(h_mode))) {
19464+ err = -ENOTDIR;
19465+ goto out;
19466+ }
19467+ } else {
19468+ /* rename(2) case */
19469+ err = -EIO;
19470+ if (unlikely(h_inode))
19471+ goto out;
19472+ }
1facf9fc 19473+
4a4d8108
AM
19474+ err = -ENOENT;
19475+ /* expected parent dir is locked */
19476+ if (unlikely(h_parent != h_dentry->d_parent))
19477+ goto out;
19478+ err = 0;
19479+
19480+ /*
19481+ * rmdir a dir may break the consistency on some filesystem.
19482+ * let's try heavy test.
19483+ */
19484+ err = -EACCES;
076b876e
AM
19485+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
19486+ && au_test_h_perm(h_parent->d_inode,
19487+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
19488+ goto out;
19489+
076b876e 19490+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
19491+ err = -EIO;
19492+ if (IS_ERR(h_latest))
19493+ goto out;
19494+ if (h_latest == h_dentry)
19495+ err = 0;
19496+ dput(h_latest);
19497+
4f0767ce 19498+out:
4a4d8108 19499+ return err;
1308ab2a 19500+}
1facf9fc 19501+
4a4d8108
AM
19502+/*
19503+ * decide the branch where we operate for @dentry. the branch index will be set
19504+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
19505+ * dir for reverting.
19506+ * when a new whiteout is necessary, create it.
19507+ */
19508+static struct dentry*
19509+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
19510+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 19511+{
4a4d8108
AM
19512+ struct dentry *wh_dentry;
19513+ struct super_block *sb;
19514+ struct path h_path;
19515+ int err, need_wh;
19516+ unsigned int udba;
19517+ aufs_bindex_t bcpup;
dece6358 19518+
4a4d8108
AM
19519+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
19520+ wh_dentry = ERR_PTR(need_wh);
19521+ if (unlikely(need_wh < 0))
19522+ goto out;
19523+
19524+ sb = dentry->d_sb;
19525+ udba = au_opt_udba(sb);
19526+ bcpup = *rbcpup;
19527+ err = au_pin(pin, dentry, bcpup, udba,
19528+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19529+ wh_dentry = ERR_PTR(err);
19530+ if (unlikely(err))
19531+ goto out;
19532+
19533+ h_path.dentry = au_pinned_h_parent(pin);
19534+ if (udba != AuOpt_UDBA_NONE
19535+ && au_dbstart(dentry) == bcpup) {
19536+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
19537+ wh_dentry = ERR_PTR(err);
19538+ if (unlikely(err))
19539+ goto out_unpin;
19540+ }
19541+
19542+ h_path.mnt = au_sbr_mnt(sb, bcpup);
19543+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
19544+ wh_dentry = NULL;
19545+ if (!need_wh)
19546+ goto out; /* success, no need to create whiteout */
19547+
19548+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
19549+ if (IS_ERR(wh_dentry))
19550+ goto out_unpin;
19551+
19552+ /* returns with the parent is locked and wh_dentry is dget-ed */
19553+ goto out; /* success */
19554+
4f0767ce 19555+out_unpin:
4a4d8108 19556+ au_unpin(pin);
4f0767ce 19557+out:
4a4d8108 19558+ return wh_dentry;
1facf9fc 19559+}
19560+
4a4d8108
AM
19561+/*
19562+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
19563+ * in order to be revertible and save time for removing many child whiteouts
19564+ * under the dir.
19565+ * returns 1 when there are too many child whiteout and caller should remove
19566+ * them asynchronously. returns 0 when the number of children is enough small to
19567+ * remove now or the branch fs is a remote fs.
19568+ * otherwise return an error.
19569+ */
19570+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
19571+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 19572+{
4a4d8108
AM
19573+ int rmdir_later, err, dirwh;
19574+ struct dentry *h_dentry;
19575+ struct super_block *sb;
19576+
19577+ sb = dentry->d_sb;
19578+ SiMustAnyLock(sb);
19579+ h_dentry = au_h_dptr(dentry, bindex);
19580+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
19581+ if (unlikely(err))
19582+ goto out;
19583+
19584+ /* stop monitoring */
19585+ au_hn_free(au_hi(dentry->d_inode, bindex));
19586+
19587+ if (!au_test_fs_remote(h_dentry->d_sb)) {
19588+ dirwh = au_sbi(sb)->si_dirwh;
19589+ rmdir_later = (dirwh <= 1);
19590+ if (!rmdir_later)
19591+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
19592+ dirwh);
19593+ if (rmdir_later)
19594+ return rmdir_later;
19595+ }
1facf9fc 19596+
4a4d8108
AM
19597+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
19598+ if (unlikely(err)) {
523b37e3
AM
19599+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
19600+ h_dentry, bindex, err);
4a4d8108
AM
19601+ err = 0;
19602+ }
dece6358 19603+
4f0767ce 19604+out:
4a4d8108
AM
19605+ AuTraceErr(err);
19606+ return err;
19607+}
1308ab2a 19608+
4a4d8108
AM
19609+/*
19610+ * final procedure for deleting a entry.
19611+ * maintain dentry and iattr.
19612+ */
19613+static void epilog(struct inode *dir, struct dentry *dentry,
19614+ aufs_bindex_t bindex)
19615+{
19616+ struct inode *inode;
1308ab2a 19617+
4a4d8108
AM
19618+ inode = dentry->d_inode;
19619+ d_drop(dentry);
19620+ inode->i_ctime = dir->i_ctime;
1308ab2a 19621+
4a4d8108
AM
19622+ if (au_ibstart(dir) == bindex)
19623+ au_cpup_attr_timesizes(dir);
19624+ dir->i_version++;
1facf9fc 19625+}
19626+
4a4d8108
AM
19627+/*
19628+ * when an error happened, remove the created whiteout and revert everything.
19629+ */
7f207e10
AM
19630+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
19631+ aufs_bindex_t bwh, struct dentry *wh_dentry,
19632+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 19633+{
4a4d8108
AM
19634+ int rerr;
19635+ struct path h_path = {
19636+ .dentry = wh_dentry,
7f207e10 19637+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 19638+ };
dece6358 19639+
7f207e10 19640+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
19641+ if (!rerr) {
19642+ au_set_dbwh(dentry, bwh);
19643+ au_dtime_revert(dt);
19644+ return 0;
19645+ }
dece6358 19646+
523b37e3 19647+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 19648+ return -EIO;
1facf9fc 19649+}
19650+
4a4d8108 19651+/* ---------------------------------------------------------------------- */
1facf9fc 19652+
4a4d8108 19653+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 19654+{
4a4d8108
AM
19655+ int err;
19656+ aufs_bindex_t bwh, bindex, bstart;
523b37e3 19657+ struct inode *inode, *h_dir, *delegated;
4a4d8108 19658+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
19659+ /* to reuduce stack size */
19660+ struct {
19661+ struct au_dtime dt;
19662+ struct au_pin pin;
19663+ struct path h_path;
19664+ } *a;
1facf9fc 19665+
4a4d8108 19666+ IMustLock(dir);
027c5e7a 19667+
c2b27bf2
AM
19668+ err = -ENOMEM;
19669+ a = kmalloc(sizeof(*a), GFP_NOFS);
19670+ if (unlikely(!a))
19671+ goto out;
19672+
027c5e7a
AM
19673+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
19674+ if (unlikely(err))
c2b27bf2 19675+ goto out_free;
027c5e7a
AM
19676+ err = au_d_hashed_positive(dentry);
19677+ if (unlikely(err))
19678+ goto out_unlock;
4a4d8108 19679+ inode = dentry->d_inode;
4a4d8108 19680+ IMustLock(inode);
027c5e7a 19681+ err = -EISDIR;
2000de60 19682+ if (unlikely(d_is_dir(dentry)))
027c5e7a 19683+ goto out_unlock; /* possible? */
1facf9fc 19684+
4a4d8108
AM
19685+ bstart = au_dbstart(dentry);
19686+ bwh = au_dbwh(dentry);
19687+ bindex = -1;
027c5e7a
AM
19688+ parent = dentry->d_parent; /* dir inode is locked */
19689+ di_write_lock_parent(parent);
c2b27bf2
AM
19690+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
19691+ &a->pin);
4a4d8108
AM
19692+ err = PTR_ERR(wh_dentry);
19693+ if (IS_ERR(wh_dentry))
027c5e7a 19694+ goto out_parent;
1facf9fc 19695+
c2b27bf2
AM
19696+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
19697+ a->h_path.dentry = au_h_dptr(dentry, bstart);
19698+ dget(a->h_path.dentry);
4a4d8108 19699+ if (bindex == bstart) {
c2b27bf2 19700+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
19701+ delegated = NULL;
19702+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
19703+ if (unlikely(err == -EWOULDBLOCK)) {
19704+ pr_warn("cannot retry for NFSv4 delegation"
19705+ " for an internal unlink\n");
19706+ iput(delegated);
19707+ }
4a4d8108
AM
19708+ } else {
19709+ /* dir inode is locked */
19710+ h_dir = wh_dentry->d_parent->d_inode;
19711+ IMustLock(h_dir);
19712+ err = 0;
19713+ }
dece6358 19714+
4a4d8108 19715+ if (!err) {
7f207e10 19716+ vfsub_drop_nlink(inode);
4a4d8108
AM
19717+ epilog(dir, dentry, bindex);
19718+
19719+ /* update target timestamps */
19720+ if (bindex == bstart) {
c2b27bf2
AM
19721+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
19722+ /*ignore*/
19723+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
4a4d8108
AM
19724+ } else
19725+ /* todo: this timestamp may be reverted later */
19726+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 19727+ goto out_unpin; /* success */
1facf9fc 19728+ }
19729+
4a4d8108
AM
19730+ /* revert */
19731+ if (wh_dentry) {
19732+ int rerr;
19733+
c2b27bf2
AM
19734+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19735+ &a->dt);
4a4d8108
AM
19736+ if (rerr)
19737+ err = rerr;
dece6358 19738+ }
1facf9fc 19739+
027c5e7a 19740+out_unpin:
c2b27bf2 19741+ au_unpin(&a->pin);
4a4d8108 19742+ dput(wh_dentry);
c2b27bf2 19743+ dput(a->h_path.dentry);
027c5e7a 19744+out_parent:
4a4d8108 19745+ di_write_unlock(parent);
027c5e7a 19746+out_unlock:
4a4d8108 19747+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19748+out_free:
19749+ kfree(a);
027c5e7a 19750+out:
4a4d8108 19751+ return err;
dece6358
AM
19752+}
19753+
4a4d8108 19754+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 19755+{
4a4d8108
AM
19756+ int err, rmdir_later;
19757+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
19758+ struct inode *inode;
19759+ struct dentry *parent, *wh_dentry, *h_dentry;
19760+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
19761+ /* to reuduce stack size */
19762+ struct {
19763+ struct au_dtime dt;
19764+ struct au_pin pin;
19765+ } *a;
1facf9fc 19766+
4a4d8108 19767+ IMustLock(dir);
027c5e7a 19768+
c2b27bf2
AM
19769+ err = -ENOMEM;
19770+ a = kmalloc(sizeof(*a), GFP_NOFS);
19771+ if (unlikely(!a))
19772+ goto out;
19773+
027c5e7a
AM
19774+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
19775+ if (unlikely(err))
c2b27bf2 19776+ goto out_free;
53392da6
AM
19777+ err = au_alive_dir(dentry);
19778+ if (unlikely(err))
027c5e7a 19779+ goto out_unlock;
53392da6 19780+ inode = dentry->d_inode;
4a4d8108 19781+ IMustLock(inode);
027c5e7a 19782+ err = -ENOTDIR;
2000de60 19783+ if (unlikely(!d_is_dir(dentry)))
027c5e7a 19784+ goto out_unlock; /* possible? */
dece6358 19785+
4a4d8108
AM
19786+ err = -ENOMEM;
19787+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
19788+ if (unlikely(!args))
19789+ goto out_unlock;
dece6358 19790+
4a4d8108
AM
19791+ parent = dentry->d_parent; /* dir inode is locked */
19792+ di_write_lock_parent(parent);
19793+ err = au_test_empty(dentry, &args->whlist);
19794+ if (unlikely(err))
027c5e7a 19795+ goto out_parent;
1facf9fc 19796+
4a4d8108
AM
19797+ bstart = au_dbstart(dentry);
19798+ bwh = au_dbwh(dentry);
19799+ bindex = -1;
c2b27bf2
AM
19800+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
19801+ &a->pin);
4a4d8108
AM
19802+ err = PTR_ERR(wh_dentry);
19803+ if (IS_ERR(wh_dentry))
027c5e7a 19804+ goto out_parent;
1facf9fc 19805+
4a4d8108
AM
19806+ h_dentry = au_h_dptr(dentry, bstart);
19807+ dget(h_dentry);
19808+ rmdir_later = 0;
19809+ if (bindex == bstart) {
19810+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
19811+ if (err > 0) {
19812+ rmdir_later = err;
19813+ err = 0;
19814+ }
19815+ } else {
19816+ /* stop monitoring */
19817+ au_hn_free(au_hi(inode, bstart));
19818+
19819+ /* dir inode is locked */
19820+ IMustLock(wh_dentry->d_parent->d_inode);
1facf9fc 19821+ err = 0;
19822+ }
19823+
4a4d8108 19824+ if (!err) {
027c5e7a 19825+ vfsub_dead_dir(inode);
4a4d8108
AM
19826+ au_set_dbdiropq(dentry, -1);
19827+ epilog(dir, dentry, bindex);
1308ab2a 19828+
4a4d8108
AM
19829+ if (rmdir_later) {
19830+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
19831+ args = NULL;
19832+ }
1308ab2a 19833+
4a4d8108 19834+ goto out_unpin; /* success */
1facf9fc 19835+ }
19836+
4a4d8108
AM
19837+ /* revert */
19838+ AuLabel(revert);
19839+ if (wh_dentry) {
19840+ int rerr;
1308ab2a 19841+
c2b27bf2
AM
19842+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19843+ &a->dt);
4a4d8108
AM
19844+ if (rerr)
19845+ err = rerr;
1facf9fc 19846+ }
19847+
4f0767ce 19848+out_unpin:
c2b27bf2 19849+ au_unpin(&a->pin);
4a4d8108
AM
19850+ dput(wh_dentry);
19851+ dput(h_dentry);
027c5e7a 19852+out_parent:
4a4d8108
AM
19853+ di_write_unlock(parent);
19854+ if (args)
19855+ au_whtmp_rmdir_free(args);
4f0767ce 19856+out_unlock:
4a4d8108 19857+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19858+out_free:
19859+ kfree(a);
4f0767ce 19860+out:
4a4d8108
AM
19861+ AuTraceErr(err);
19862+ return err;
dece6358 19863+}
7f207e10
AM
19864diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
19865--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
19866+++ linux/fs/aufs/i_op_ren.c 2015-03-27 21:56:35.466795000 +0100
19867@@ -0,0 +1,1035 @@
1facf9fc 19868+/*
2000de60 19869+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 19870+ *
19871+ * This program, aufs is free software; you can redistribute it and/or modify
19872+ * it under the terms of the GNU General Public License as published by
19873+ * the Free Software Foundation; either version 2 of the License, or
19874+ * (at your option) any later version.
dece6358
AM
19875+ *
19876+ * This program is distributed in the hope that it will be useful,
19877+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19878+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19879+ * GNU General Public License for more details.
19880+ *
19881+ * You should have received a copy of the GNU General Public License
523b37e3 19882+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19883+ */
19884+
19885+/*
4a4d8108
AM
19886+ * inode operation (rename entry)
19887+ * todo: this is crazy monster
1facf9fc 19888+ */
19889+
19890+#include "aufs.h"
19891+
4a4d8108
AM
19892+enum { AuSRC, AuDST, AuSrcDst };
19893+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 19894+
4a4d8108
AM
19895+#define AuRen_ISDIR 1
19896+#define AuRen_ISSAMEDIR (1 << 1)
19897+#define AuRen_WHSRC (1 << 2)
19898+#define AuRen_WHDST (1 << 3)
19899+#define AuRen_MNT_WRITE (1 << 4)
19900+#define AuRen_DT_DSTDIR (1 << 5)
19901+#define AuRen_DIROPQ (1 << 6)
19902+#define AuRen_CPUP (1 << 7)
19903+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
19904+#define au_fset_ren(flags, name) \
19905+ do { (flags) |= AuRen_##name; } while (0)
19906+#define au_fclr_ren(flags, name) \
19907+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 19908+
4a4d8108
AM
19909+struct au_ren_args {
19910+ struct {
19911+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
19912+ *wh_dentry;
19913+ struct inode *dir, *inode;
19914+ struct au_hinode *hdir;
19915+ struct au_dtime dt[AuParentChild];
19916+ aufs_bindex_t bstart;
19917+ } sd[AuSrcDst];
1facf9fc 19918+
4a4d8108
AM
19919+#define src_dentry sd[AuSRC].dentry
19920+#define src_dir sd[AuSRC].dir
19921+#define src_inode sd[AuSRC].inode
19922+#define src_h_dentry sd[AuSRC].h_dentry
19923+#define src_parent sd[AuSRC].parent
19924+#define src_h_parent sd[AuSRC].h_parent
19925+#define src_wh_dentry sd[AuSRC].wh_dentry
19926+#define src_hdir sd[AuSRC].hdir
19927+#define src_h_dir sd[AuSRC].hdir->hi_inode
19928+#define src_dt sd[AuSRC].dt
19929+#define src_bstart sd[AuSRC].bstart
1facf9fc 19930+
4a4d8108
AM
19931+#define dst_dentry sd[AuDST].dentry
19932+#define dst_dir sd[AuDST].dir
19933+#define dst_inode sd[AuDST].inode
19934+#define dst_h_dentry sd[AuDST].h_dentry
19935+#define dst_parent sd[AuDST].parent
19936+#define dst_h_parent sd[AuDST].h_parent
19937+#define dst_wh_dentry sd[AuDST].wh_dentry
19938+#define dst_hdir sd[AuDST].hdir
19939+#define dst_h_dir sd[AuDST].hdir->hi_inode
19940+#define dst_dt sd[AuDST].dt
19941+#define dst_bstart sd[AuDST].bstart
19942+
19943+ struct dentry *h_trap;
19944+ struct au_branch *br;
19945+ struct au_hinode *src_hinode;
19946+ struct path h_path;
19947+ struct au_nhash whlist;
027c5e7a 19948+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 19949+
1308ab2a 19950+ unsigned int flags;
1facf9fc 19951+
4a4d8108
AM
19952+ struct au_whtmp_rmdir *thargs;
19953+ struct dentry *h_dst;
19954+};
1308ab2a 19955+
4a4d8108 19956+/* ---------------------------------------------------------------------- */
1308ab2a 19957+
4a4d8108
AM
19958+/*
19959+ * functions for reverting.
19960+ * when an error happened in a single rename systemcall, we should revert
19961+ * everything as if nothing happend.
19962+ * we don't need to revert the copied-up/down the parent dir since they are
19963+ * harmless.
19964+ */
1facf9fc 19965+
4a4d8108
AM
19966+#define RevertFailure(fmt, ...) do { \
19967+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
19968+ ##__VA_ARGS__, err, rerr); \
19969+ err = -EIO; \
19970+} while (0)
1facf9fc 19971+
4a4d8108 19972+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 19973+{
4a4d8108 19974+ int rerr;
1facf9fc 19975+
4a4d8108
AM
19976+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
19977+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
19978+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 19979+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108 19980+ if (rerr)
523b37e3 19981+ RevertFailure("remove diropq %pd", a->src_dentry);
4a4d8108 19982+}
1facf9fc 19983+
4a4d8108
AM
19984+static void au_ren_rev_rename(int err, struct au_ren_args *a)
19985+{
19986+ int rerr;
523b37e3 19987+ struct inode *delegated;
1facf9fc 19988+
b4510431
AM
19989+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
19990+ a->src_h_parent);
4a4d8108
AM
19991+ rerr = PTR_ERR(a->h_path.dentry);
19992+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 19993+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 19994+ return;
1facf9fc 19995+ }
19996+
523b37e3 19997+ delegated = NULL;
4a4d8108
AM
19998+ rerr = vfsub_rename(a->dst_h_dir,
19999+ au_h_dptr(a->src_dentry, a->btgt),
523b37e3
AM
20000+ a->src_h_dir, &a->h_path, &delegated);
20001+ if (unlikely(rerr == -EWOULDBLOCK)) {
20002+ pr_warn("cannot retry for NFSv4 delegation"
20003+ " for an internal rename\n");
20004+ iput(delegated);
20005+ }
4a4d8108
AM
20006+ d_drop(a->h_path.dentry);
20007+ dput(a->h_path.dentry);
20008+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
20009+ if (rerr)
523b37e3 20010+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 20011+}
20012+
4a4d8108 20013+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
1facf9fc 20014+{
4a4d8108 20015+ int rerr;
1facf9fc 20016+
4a4d8108 20017+ a->h_path.dentry = a->dst_h_dentry;
523b37e3
AM
20018+ /* no delegation since it is just created */
20019+ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*delegated*/NULL,
20020+ /*force*/0);
4a4d8108
AM
20021+ au_set_h_dptr(a->src_dentry, a->btgt, NULL);
20022+ au_set_dbstart(a->src_dentry, a->src_bstart);
20023+ if (rerr)
523b37e3 20024+ RevertFailure("unlink %pd", a->dst_h_dentry);
1facf9fc 20025+}
20026+
4a4d8108 20027+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 20028+{
4a4d8108 20029+ int rerr;
523b37e3 20030+ struct inode *delegated;
dece6358 20031+
b4510431
AM
20032+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
20033+ a->dst_h_parent);
4a4d8108
AM
20034+ rerr = PTR_ERR(a->h_path.dentry);
20035+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 20036+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
20037+ return;
20038+ }
20039+ if (a->h_path.dentry->d_inode) {
20040+ d_drop(a->h_path.dentry);
20041+ dput(a->h_path.dentry);
20042+ return;
dece6358
AM
20043+ }
20044+
523b37e3
AM
20045+ delegated = NULL;
20046+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
20047+ &delegated);
20048+ if (unlikely(rerr == -EWOULDBLOCK)) {
20049+ pr_warn("cannot retry for NFSv4 delegation"
20050+ " for an internal rename\n");
20051+ iput(delegated);
20052+ }
4a4d8108
AM
20053+ d_drop(a->h_path.dentry);
20054+ dput(a->h_path.dentry);
20055+ if (!rerr)
20056+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
20057+ else
523b37e3 20058+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 20059+}
1308ab2a 20060+
4a4d8108
AM
20061+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
20062+{
20063+ int rerr;
1308ab2a 20064+
4a4d8108
AM
20065+ a->h_path.dentry = a->src_wh_dentry;
20066+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 20067+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 20068+ if (rerr)
523b37e3 20069+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 20070+}
4a4d8108 20071+#undef RevertFailure
1facf9fc 20072+
1308ab2a 20073+/* ---------------------------------------------------------------------- */
20074+
4a4d8108
AM
20075+/*
20076+ * when we have to copyup the renaming entry, do it with the rename-target name
20077+ * in order to minimize the cost (the later actual rename is unnecessary).
20078+ * otherwise rename it on the target branch.
20079+ */
20080+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 20081+{
dece6358 20082+ int err;
4a4d8108 20083+ struct dentry *d;
523b37e3 20084+ struct inode *delegated;
1facf9fc 20085+
4a4d8108
AM
20086+ d = a->src_dentry;
20087+ if (au_dbstart(d) == a->btgt) {
20088+ a->h_path.dentry = a->dst_h_dentry;
20089+ if (au_ftest_ren(a->flags, DIROPQ)
20090+ && au_dbdiropq(d) == a->btgt)
20091+ au_fclr_ren(a->flags, DIROPQ);
20092+ AuDebugOn(au_dbstart(d) != a->btgt);
523b37e3 20093+ delegated = NULL;
4a4d8108 20094+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
523b37e3
AM
20095+ a->dst_h_dir, &a->h_path, &delegated);
20096+ if (unlikely(err == -EWOULDBLOCK)) {
20097+ pr_warn("cannot retry for NFSv4 delegation"
20098+ " for an internal rename\n");
20099+ iput(delegated);
20100+ }
c2b27bf2 20101+ } else
86dc4139 20102+ BUG();
1308ab2a 20103+
027c5e7a
AM
20104+ if (!err && a->h_dst)
20105+ /* it will be set to dinfo later */
20106+ dget(a->h_dst);
1facf9fc 20107+
dece6358
AM
20108+ return err;
20109+}
1facf9fc 20110+
4a4d8108
AM
20111+/* cf. aufs_rmdir() */
20112+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 20113+{
4a4d8108
AM
20114+ int err;
20115+ struct inode *dir;
1facf9fc 20116+
4a4d8108
AM
20117+ dir = a->dst_dir;
20118+ SiMustAnyLock(dir->i_sb);
20119+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
20120+ au_sbi(dir->i_sb)->si_dirwh)
20121+ || au_test_fs_remote(a->h_dst->d_sb)) {
20122+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
20123+ if (unlikely(err))
523b37e3
AM
20124+ pr_warn("failed removing whtmp dir %pd (%d), "
20125+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
20126+ } else {
20127+ au_nhash_wh_free(&a->thargs->whlist);
20128+ a->thargs->whlist = a->whlist;
20129+ a->whlist.nh_num = 0;
20130+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
20131+ dput(a->h_dst);
20132+ a->thargs = NULL;
20133+ }
20134+
20135+ return 0;
1308ab2a 20136+}
1facf9fc 20137+
4a4d8108
AM
20138+/* make it 'opaque' dir. */
20139+static int au_ren_diropq(struct au_ren_args *a)
20140+{
20141+ int err;
20142+ struct dentry *diropq;
1facf9fc 20143+
4a4d8108 20144+ err = 0;
027c5e7a 20145+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
20146+ a->src_hinode = au_hi(a->src_inode, a->btgt);
20147+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
20148+ diropq = au_diropq_create(a->src_dentry, a->btgt);
20149+ au_hn_imtx_unlock(a->src_hinode);
20150+ if (IS_ERR(diropq))
20151+ err = PTR_ERR(diropq);
076b876e
AM
20152+ else
20153+ dput(diropq);
1facf9fc 20154+
4a4d8108
AM
20155+ return err;
20156+}
1facf9fc 20157+
4a4d8108
AM
20158+static int do_rename(struct au_ren_args *a)
20159+{
20160+ int err;
20161+ struct dentry *d, *h_d;
1facf9fc 20162+
4a4d8108
AM
20163+ /* prepare workqueue args for asynchronous rmdir */
20164+ h_d = a->dst_h_dentry;
20165+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
20166+ err = -ENOMEM;
20167+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
20168+ if (unlikely(!a->thargs))
20169+ goto out;
20170+ a->h_dst = dget(h_d);
20171+ }
1facf9fc 20172+
4a4d8108
AM
20173+ /* create whiteout for src_dentry */
20174+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
20175+ a->src_bwh = au_dbwh(a->src_dentry);
20176+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
20177+ a->src_wh_dentry
20178+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
20179+ err = PTR_ERR(a->src_wh_dentry);
20180+ if (IS_ERR(a->src_wh_dentry))
20181+ goto out_thargs;
20182+ }
1facf9fc 20183+
4a4d8108
AM
20184+ /* lookup whiteout for dentry */
20185+ if (au_ftest_ren(a->flags, WHDST)) {
20186+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
20187+ a->br);
20188+ err = PTR_ERR(h_d);
20189+ if (IS_ERR(h_d))
20190+ goto out_whsrc;
20191+ if (!h_d->d_inode)
20192+ dput(h_d);
20193+ else
20194+ a->dst_wh_dentry = h_d;
20195+ }
1facf9fc 20196+
4a4d8108
AM
20197+ /* rename dentry to tmpwh */
20198+ if (a->thargs) {
20199+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
20200+ if (unlikely(err))
20201+ goto out_whdst;
dece6358 20202+
4a4d8108
AM
20203+ d = a->dst_dentry;
20204+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 20205+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
20206+ if (unlikely(err))
20207+ goto out_whtmp;
20208+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
20209+ }
1facf9fc 20210+
c2b27bf2 20211+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
1facf9fc 20212+
4a4d8108
AM
20213+ /* rename by vfs_rename or cpup */
20214+ d = a->dst_dentry;
20215+ if (au_ftest_ren(a->flags, ISDIR)
20216+ && (a->dst_wh_dentry
20217+ || au_dbdiropq(d) == a->btgt
20218+ /* hide the lower to keep xino */
20219+ || a->btgt < au_dbend(d)
20220+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
20221+ au_fset_ren(a->flags, DIROPQ);
20222+ err = au_ren_or_cpup(a);
20223+ if (unlikely(err))
20224+ /* leave the copied-up one */
20225+ goto out_whtmp;
1308ab2a 20226+
4a4d8108
AM
20227+ /* make dir opaque */
20228+ if (au_ftest_ren(a->flags, DIROPQ)) {
20229+ err = au_ren_diropq(a);
20230+ if (unlikely(err))
20231+ goto out_rename;
20232+ }
1308ab2a 20233+
4a4d8108
AM
20234+ /* update target timestamps */
20235+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
20236+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
20237+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
20238+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
1facf9fc 20239+
4a4d8108
AM
20240+ /* remove whiteout for dentry */
20241+ if (a->dst_wh_dentry) {
20242+ a->h_path.dentry = a->dst_wh_dentry;
20243+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
20244+ a->dst_dentry);
20245+ if (unlikely(err))
20246+ goto out_diropq;
20247+ }
1facf9fc 20248+
4a4d8108
AM
20249+ /* remove whtmp */
20250+ if (a->thargs)
20251+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 20252+
076b876e 20253+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
4a4d8108
AM
20254+ err = 0;
20255+ goto out_success;
20256+
4f0767ce 20257+out_diropq:
4a4d8108
AM
20258+ if (au_ftest_ren(a->flags, DIROPQ))
20259+ au_ren_rev_diropq(err, a);
4f0767ce 20260+out_rename:
4a4d8108
AM
20261+ if (!au_ftest_ren(a->flags, CPUP))
20262+ au_ren_rev_rename(err, a);
20263+ else
20264+ au_ren_rev_cpup(err, a);
027c5e7a 20265+ dput(a->h_dst);
4f0767ce 20266+out_whtmp:
4a4d8108
AM
20267+ if (a->thargs)
20268+ au_ren_rev_whtmp(err, a);
4f0767ce 20269+out_whdst:
4a4d8108
AM
20270+ dput(a->dst_wh_dentry);
20271+ a->dst_wh_dentry = NULL;
4f0767ce 20272+out_whsrc:
4a4d8108
AM
20273+ if (a->src_wh_dentry)
20274+ au_ren_rev_whsrc(err, a);
4f0767ce 20275+out_success:
4a4d8108
AM
20276+ dput(a->src_wh_dentry);
20277+ dput(a->dst_wh_dentry);
4f0767ce 20278+out_thargs:
4a4d8108
AM
20279+ if (a->thargs) {
20280+ dput(a->h_dst);
20281+ au_whtmp_rmdir_free(a->thargs);
20282+ a->thargs = NULL;
20283+ }
4f0767ce 20284+out:
4a4d8108 20285+ return err;
dece6358 20286+}
1facf9fc 20287+
1308ab2a 20288+/* ---------------------------------------------------------------------- */
1facf9fc 20289+
4a4d8108
AM
20290+/*
20291+ * test if @dentry dir can be rename destination or not.
20292+ * success means, it is a logically empty dir.
20293+ */
20294+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 20295+{
4a4d8108 20296+ return au_test_empty(dentry, whlist);
1308ab2a 20297+}
1facf9fc 20298+
4a4d8108
AM
20299+/*
20300+ * test if @dentry dir can be rename source or not.
20301+ * if it can, return 0 and @children is filled.
20302+ * success means,
20303+ * - it is a logically empty dir.
20304+ * - or, it exists on writable branch and has no children including whiteouts
20305+ * on the lower branch.
20306+ */
20307+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
20308+{
20309+ int err;
20310+ unsigned int rdhash;
20311+ aufs_bindex_t bstart;
1facf9fc 20312+
4a4d8108
AM
20313+ bstart = au_dbstart(dentry);
20314+ if (bstart != btgt) {
20315+ struct au_nhash whlist;
dece6358 20316+
4a4d8108
AM
20317+ SiMustAnyLock(dentry->d_sb);
20318+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
20319+ if (!rdhash)
20320+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
20321+ dentry));
20322+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
20323+ if (unlikely(err))
20324+ goto out;
20325+ err = au_test_empty(dentry, &whlist);
20326+ au_nhash_wh_free(&whlist);
20327+ goto out;
20328+ }
dece6358 20329+
4a4d8108
AM
20330+ if (bstart == au_dbtaildir(dentry))
20331+ return 0; /* success */
dece6358 20332+
4a4d8108 20333+ err = au_test_empty_lower(dentry);
1facf9fc 20334+
4f0767ce 20335+out:
4a4d8108
AM
20336+ if (err == -ENOTEMPTY) {
20337+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
20338+ " is not supported\n");
20339+ err = -EXDEV;
20340+ }
20341+ return err;
20342+}
1308ab2a 20343+
4a4d8108
AM
20344+/* side effect: sets whlist and h_dentry */
20345+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 20346+{
4a4d8108
AM
20347+ int err;
20348+ unsigned int rdhash;
20349+ struct dentry *d;
1facf9fc 20350+
4a4d8108
AM
20351+ d = a->dst_dentry;
20352+ SiMustAnyLock(d->d_sb);
1facf9fc 20353+
4a4d8108
AM
20354+ err = 0;
20355+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
20356+ rdhash = au_sbi(d->d_sb)->si_rdhash;
20357+ if (!rdhash)
20358+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
20359+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
20360+ if (unlikely(err))
20361+ goto out;
1308ab2a 20362+
4a4d8108
AM
20363+ au_set_dbstart(d, a->dst_bstart);
20364+ err = may_rename_dstdir(d, &a->whlist);
20365+ au_set_dbstart(d, a->btgt);
20366+ }
20367+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
20368+ if (unlikely(err))
20369+ goto out;
20370+
20371+ d = a->src_dentry;
20372+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
20373+ if (au_ftest_ren(a->flags, ISDIR)) {
20374+ err = may_rename_srcdir(d, a->btgt);
20375+ if (unlikely(err)) {
20376+ au_nhash_wh_free(&a->whlist);
20377+ a->whlist.nh_num = 0;
20378+ }
20379+ }
4f0767ce 20380+out:
4a4d8108 20381+ return err;
1facf9fc 20382+}
20383+
4a4d8108 20384+/* ---------------------------------------------------------------------- */
1facf9fc 20385+
4a4d8108
AM
20386+/*
20387+ * simple tests for rename.
20388+ * following the checks in vfs, plus the parent-child relationship.
20389+ */
20390+static int au_may_ren(struct au_ren_args *a)
20391+{
20392+ int err, isdir;
20393+ struct inode *h_inode;
1facf9fc 20394+
4a4d8108
AM
20395+ if (a->src_bstart == a->btgt) {
20396+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
20397+ au_ftest_ren(a->flags, ISDIR));
20398+ if (unlikely(err))
20399+ goto out;
20400+ err = -EINVAL;
20401+ if (unlikely(a->src_h_dentry == a->h_trap))
20402+ goto out;
20403+ }
1facf9fc 20404+
4a4d8108
AM
20405+ err = 0;
20406+ if (a->dst_bstart != a->btgt)
20407+ goto out;
1facf9fc 20408+
027c5e7a
AM
20409+ err = -ENOTEMPTY;
20410+ if (unlikely(a->dst_h_dentry == a->h_trap))
20411+ goto out;
20412+
4a4d8108
AM
20413+ err = -EIO;
20414+ h_inode = a->dst_h_dentry->d_inode;
20415+ isdir = !!au_ftest_ren(a->flags, ISDIR);
20416+ if (!a->dst_dentry->d_inode) {
20417+ if (unlikely(h_inode))
20418+ goto out;
20419+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
20420+ isdir);
20421+ } else {
20422+ if (unlikely(!h_inode || !h_inode->i_nlink))
20423+ goto out;
20424+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
20425+ isdir);
20426+ if (unlikely(err))
20427+ goto out;
4a4d8108 20428+ }
1facf9fc 20429+
4f0767ce 20430+out:
4a4d8108
AM
20431+ if (unlikely(err == -ENOENT || err == -EEXIST))
20432+ err = -EIO;
20433+ AuTraceErr(err);
20434+ return err;
20435+}
1facf9fc 20436+
1308ab2a 20437+/* ---------------------------------------------------------------------- */
1facf9fc 20438+
4a4d8108
AM
20439+/*
20440+ * locking order
20441+ * (VFS)
20442+ * - src_dir and dir by lock_rename()
20443+ * - inode if exitsts
20444+ * (aufs)
20445+ * - lock all
20446+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
20447+ * + si_read_lock
20448+ * + di_write_lock2_child()
20449+ * + di_write_lock_child()
20450+ * + ii_write_lock_child()
20451+ * + di_write_lock_child2()
20452+ * + ii_write_lock_child2()
20453+ * + src_parent and parent
20454+ * + di_write_lock_parent()
20455+ * + ii_write_lock_parent()
20456+ * + di_write_lock_parent2()
20457+ * + ii_write_lock_parent2()
20458+ * + lower src_dir and dir by vfsub_lock_rename()
20459+ * + verify the every relationships between child and parent. if any
20460+ * of them failed, unlock all and return -EBUSY.
20461+ */
20462+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 20463+{
4a4d8108
AM
20464+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
20465+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
20466+ if (au_ftest_ren(a->flags, MNT_WRITE))
20467+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 20468+}
20469+
4a4d8108 20470+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 20471+{
4a4d8108
AM
20472+ int err;
20473+ unsigned int udba;
1308ab2a 20474+
4a4d8108
AM
20475+ err = 0;
20476+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
20477+ a->src_hdir = au_hi(a->src_dir, a->btgt);
20478+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
20479+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
20480+
20481+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
20482+ if (unlikely(err))
20483+ goto out;
20484+ au_fset_ren(a->flags, MNT_WRITE);
4a4d8108
AM
20485+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
20486+ a->dst_h_parent, a->dst_hdir);
20487+ udba = au_opt_udba(a->src_dentry->d_sb);
20488+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
20489+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
20490+ err = au_busy_or_stale();
20491+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
20492+ err = au_h_verify(a->src_h_dentry, udba,
20493+ a->src_h_parent->d_inode, a->src_h_parent,
20494+ a->br);
20495+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
20496+ err = au_h_verify(a->dst_h_dentry, udba,
20497+ a->dst_h_parent->d_inode, a->dst_h_parent,
20498+ a->br);
86dc4139 20499+ if (!err)
4a4d8108 20500+ goto out; /* success */
4a4d8108
AM
20501+
20502+ err = au_busy_or_stale();
4a4d8108 20503+ au_ren_unlock(a);
86dc4139 20504+
4f0767ce 20505+out:
4a4d8108 20506+ return err;
1facf9fc 20507+}
20508+
20509+/* ---------------------------------------------------------------------- */
20510+
4a4d8108 20511+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 20512+{
4a4d8108 20513+ struct inode *dir;
dece6358 20514+
4a4d8108
AM
20515+ dir = a->dst_dir;
20516+ dir->i_version++;
20517+ if (au_ftest_ren(a->flags, ISDIR)) {
20518+ /* is this updating defined in POSIX? */
20519+ au_cpup_attr_timesizes(a->src_inode);
20520+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 20521+ }
027c5e7a 20522+
4a4d8108
AM
20523+ if (au_ibstart(dir) == a->btgt)
20524+ au_cpup_attr_timesizes(dir);
dece6358 20525+
4a4d8108
AM
20526+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20527+ return;
dece6358 20528+
4a4d8108
AM
20529+ dir = a->src_dir;
20530+ dir->i_version++;
20531+ if (au_ftest_ren(a->flags, ISDIR))
20532+ au_cpup_attr_nlink(dir, /*force*/1);
20533+ if (au_ibstart(dir) == a->btgt)
20534+ au_cpup_attr_timesizes(dir);
1facf9fc 20535+}
20536+
4a4d8108 20537+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 20538+{
4a4d8108
AM
20539+ aufs_bindex_t bend, bindex;
20540+ struct dentry *d, *h_d;
20541+ struct inode *i, *h_i;
20542+ struct super_block *sb;
dece6358 20543+
027c5e7a
AM
20544+ d = a->dst_dentry;
20545+ d_drop(d);
20546+ if (a->h_dst)
20547+ /* already dget-ed by au_ren_or_cpup() */
20548+ au_set_h_dptr(d, a->btgt, a->h_dst);
20549+
20550+ i = a->dst_inode;
20551+ if (i) {
20552+ if (!au_ftest_ren(a->flags, ISDIR))
20553+ vfsub_drop_nlink(i);
20554+ else {
20555+ vfsub_dead_dir(i);
20556+ au_cpup_attr_timesizes(i);
20557+ }
20558+ au_update_dbrange(d, /*do_put_zero*/1);
20559+ } else {
20560+ bend = a->btgt;
20561+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
20562+ au_set_h_dptr(d, bindex, NULL);
20563+ bend = au_dbend(d);
20564+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
20565+ au_set_h_dptr(d, bindex, NULL);
20566+ au_update_dbrange(d, /*do_put_zero*/0);
20567+ }
20568+
4a4d8108
AM
20569+ d = a->src_dentry;
20570+ au_set_dbwh(d, -1);
20571+ bend = au_dbend(d);
20572+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20573+ h_d = au_h_dptr(d, bindex);
20574+ if (h_d)
20575+ au_set_h_dptr(d, bindex, NULL);
20576+ }
20577+ au_set_dbend(d, a->btgt);
20578+
20579+ sb = d->d_sb;
20580+ i = a->src_inode;
20581+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
20582+ return; /* success */
20583+
20584+ bend = au_ibend(i);
20585+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20586+ h_i = au_h_iptr(i, bindex);
20587+ if (h_i) {
20588+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
20589+ /* ignore this error */
20590+ au_set_h_iptr(i, bindex, NULL, 0);
20591+ }
20592+ }
20593+ au_set_ibend(i, a->btgt);
1308ab2a 20594+}
dece6358 20595+
4a4d8108
AM
20596+/* ---------------------------------------------------------------------- */
20597+
20598+/* mainly for link(2) and rename(2) */
20599+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 20600+{
4a4d8108
AM
20601+ aufs_bindex_t bdiropq, bwh;
20602+ struct dentry *parent;
20603+ struct au_branch *br;
20604+
20605+ parent = dentry->d_parent;
20606+ IMustLock(parent->d_inode); /* dir is locked */
20607+
20608+ bdiropq = au_dbdiropq(parent);
20609+ bwh = au_dbwh(dentry);
20610+ br = au_sbr(dentry->d_sb, btgt);
20611+ if (au_br_rdonly(br)
20612+ || (0 <= bdiropq && bdiropq < btgt)
20613+ || (0 <= bwh && bwh < btgt))
20614+ btgt = -1;
20615+
20616+ AuDbg("btgt %d\n", btgt);
20617+ return btgt;
1facf9fc 20618+}
20619+
4a4d8108
AM
20620+/* sets src_bstart, dst_bstart and btgt */
20621+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 20622+{
4a4d8108
AM
20623+ int err;
20624+ struct au_wr_dir_args wr_dir_args = {
20625+ /* .force_btgt = -1, */
20626+ .flags = AuWrDir_ADD_ENTRY
20627+ };
dece6358 20628+
4a4d8108
AM
20629+ a->src_bstart = au_dbstart(a->src_dentry);
20630+ a->dst_bstart = au_dbstart(a->dst_dentry);
20631+ if (au_ftest_ren(a->flags, ISDIR))
20632+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
20633+ wr_dir_args.force_btgt = a->src_bstart;
20634+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
20635+ wr_dir_args.force_btgt = a->dst_bstart;
20636+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
20637+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
20638+ a->btgt = err;
dece6358 20639+
4a4d8108 20640+ return err;
1facf9fc 20641+}
20642+
4a4d8108 20643+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 20644+{
4a4d8108
AM
20645+ a->h_path.dentry = a->src_h_parent;
20646+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
20647+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
20648+ a->h_path.dentry = a->dst_h_parent;
20649+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
20650+ }
1facf9fc 20651+
4a4d8108
AM
20652+ au_fclr_ren(a->flags, DT_DSTDIR);
20653+ if (!au_ftest_ren(a->flags, ISDIR))
20654+ return;
dece6358 20655+
4a4d8108
AM
20656+ a->h_path.dentry = a->src_h_dentry;
20657+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
20658+ if (a->dst_h_dentry->d_inode) {
20659+ au_fset_ren(a->flags, DT_DSTDIR);
20660+ a->h_path.dentry = a->dst_h_dentry;
20661+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
20662+ }
1308ab2a 20663+}
dece6358 20664+
4a4d8108 20665+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 20666+{
4a4d8108
AM
20667+ struct dentry *h_d;
20668+ struct mutex *h_mtx;
20669+
20670+ au_dtime_revert(a->src_dt + AuPARENT);
20671+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
20672+ au_dtime_revert(a->dst_dt + AuPARENT);
20673+
20674+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
20675+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
20676+ h_mtx = &h_d->d_inode->i_mutex;
20677+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20678+ au_dtime_revert(a->src_dt + AuCHILD);
20679+ mutex_unlock(h_mtx);
20680+
20681+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
20682+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
20683+ h_mtx = &h_d->d_inode->i_mutex;
20684+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20685+ au_dtime_revert(a->dst_dt + AuCHILD);
20686+ mutex_unlock(h_mtx);
1facf9fc 20687+ }
20688+ }
20689+}
20690+
4a4d8108
AM
20691+/* ---------------------------------------------------------------------- */
20692+
20693+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
20694+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 20695+{
e49829fe 20696+ int err, flags;
4a4d8108
AM
20697+ /* reduce stack space */
20698+ struct au_ren_args *a;
20699+
523b37e3 20700+ AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry);
4a4d8108
AM
20701+ IMustLock(_src_dir);
20702+ IMustLock(_dst_dir);
20703+
20704+ err = -ENOMEM;
20705+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
20706+ a = kzalloc(sizeof(*a), GFP_NOFS);
20707+ if (unlikely(!a))
20708+ goto out;
20709+
20710+ a->src_dir = _src_dir;
20711+ a->src_dentry = _src_dentry;
20712+ a->src_inode = a->src_dentry->d_inode;
20713+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
20714+ a->dst_dir = _dst_dir;
20715+ a->dst_dentry = _dst_dentry;
20716+ a->dst_inode = a->dst_dentry->d_inode;
20717+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
20718+ if (a->dst_inode) {
20719+ IMustLock(a->dst_inode);
20720+ au_igrab(a->dst_inode);
1facf9fc 20721+ }
1facf9fc 20722+
4a4d8108 20723+ err = -ENOTDIR;
027c5e7a 20724+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
2000de60 20725+ if (d_is_dir(a->src_dentry)) {
4a4d8108 20726+ au_fset_ren(a->flags, ISDIR);
2000de60
JR
20727+ if (unlikely(d_is_positive(a->dst_dentry)
20728+ && !d_is_dir(a->dst_dentry)))
4a4d8108 20729+ goto out_free;
e49829fe
JR
20730+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20731+ AuLock_DIR | flags);
4a4d8108 20732+ } else
e49829fe
JR
20733+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20734+ flags);
20735+ if (unlikely(err))
20736+ goto out_free;
1facf9fc 20737+
027c5e7a
AM
20738+ err = au_d_hashed_positive(a->src_dentry);
20739+ if (unlikely(err))
20740+ goto out_unlock;
20741+ err = -ENOENT;
20742+ if (a->dst_inode) {
20743+ /*
20744+ * If it is a dir, VFS unhash dst_dentry before this
20745+ * function. It means we cannot rely upon d_unhashed().
20746+ */
20747+ if (unlikely(!a->dst_inode->i_nlink))
20748+ goto out_unlock;
20749+ if (!S_ISDIR(a->dst_inode->i_mode)) {
20750+ err = au_d_hashed_positive(a->dst_dentry);
20751+ if (unlikely(err))
20752+ goto out_unlock;
20753+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
20754+ goto out_unlock;
20755+ } else if (unlikely(d_unhashed(a->dst_dentry)))
20756+ goto out_unlock;
20757+
7eafdf33
AM
20758+ /*
20759+ * is it possible?
20760+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
20761+ * there may exist a problem somewhere else.
20762+ */
20763+ err = -EINVAL;
20764+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
20765+ goto out_unlock;
20766+
4a4d8108
AM
20767+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
20768+ di_write_lock_parent(a->dst_parent);
1facf9fc 20769+
4a4d8108
AM
20770+ /* which branch we process */
20771+ err = au_ren_wbr(a);
20772+ if (unlikely(err < 0))
027c5e7a 20773+ goto out_parent;
4a4d8108 20774+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 20775+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 20776+
4a4d8108
AM
20777+ /* are they available to be renamed */
20778+ err = au_ren_may_dir(a);
20779+ if (unlikely(err))
20780+ goto out_children;
1facf9fc 20781+
4a4d8108
AM
20782+ /* prepare the writable parent dir on the same branch */
20783+ if (a->dst_bstart == a->btgt) {
20784+ au_fset_ren(a->flags, WHDST);
20785+ } else {
20786+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
20787+ if (unlikely(err))
20788+ goto out_children;
20789+ }
1facf9fc 20790+
4a4d8108
AM
20791+ if (a->src_dir != a->dst_dir) {
20792+ /*
20793+ * this temporary unlock is safe,
20794+ * because both dir->i_mutex are locked.
20795+ */
20796+ di_write_unlock(a->dst_parent);
20797+ di_write_lock_parent(a->src_parent);
20798+ err = au_wr_dir_need_wh(a->src_dentry,
20799+ au_ftest_ren(a->flags, ISDIR),
20800+ &a->btgt);
20801+ di_write_unlock(a->src_parent);
20802+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
20803+ au_fclr_ren(a->flags, ISSAMEDIR);
20804+ } else
20805+ err = au_wr_dir_need_wh(a->src_dentry,
20806+ au_ftest_ren(a->flags, ISDIR),
20807+ &a->btgt);
20808+ if (unlikely(err < 0))
20809+ goto out_children;
20810+ if (err)
20811+ au_fset_ren(a->flags, WHSRC);
1facf9fc 20812+
86dc4139
AM
20813+ /* cpup src */
20814+ if (a->src_bstart != a->btgt) {
86dc4139
AM
20815+ struct au_pin pin;
20816+
20817+ err = au_pin(&pin, a->src_dentry, a->btgt,
20818+ au_opt_udba(a->src_dentry->d_sb),
20819+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 20820+ if (!err) {
c2b27bf2
AM
20821+ struct au_cp_generic cpg = {
20822+ .dentry = a->src_dentry,
20823+ .bdst = a->btgt,
20824+ .bsrc = a->src_bstart,
20825+ .len = -1,
20826+ .pin = &pin,
20827+ .flags = AuCpup_DTIME | AuCpup_HOPEN
20828+ };
367653fa 20829+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
c2b27bf2 20830+ err = au_sio_cpup_simple(&cpg);
367653fa 20831+ au_unpin(&pin);
86dc4139 20832+ }
86dc4139
AM
20833+ if (unlikely(err))
20834+ goto out_children;
20835+ a->src_bstart = a->btgt;
20836+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
20837+ au_fset_ren(a->flags, WHSRC);
20838+ }
20839+
4a4d8108
AM
20840+ /* lock them all */
20841+ err = au_ren_lock(a);
20842+ if (unlikely(err))
86dc4139 20843+ /* leave the copied-up one */
4a4d8108 20844+ goto out_children;
1facf9fc 20845+
4a4d8108
AM
20846+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
20847+ err = au_may_ren(a);
20848+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
20849+ err = -ENAMETOOLONG;
20850+ if (unlikely(err))
20851+ goto out_hdir;
1facf9fc 20852+
4a4d8108
AM
20853+ /* store timestamps to be revertible */
20854+ au_ren_dt(a);
1facf9fc 20855+
4a4d8108
AM
20856+ /* here we go */
20857+ err = do_rename(a);
20858+ if (unlikely(err))
20859+ goto out_dt;
20860+
20861+ /* update dir attributes */
20862+ au_ren_refresh_dir(a);
20863+
20864+ /* dput/iput all lower dentries */
20865+ au_ren_refresh(a);
20866+
20867+ goto out_hdir; /* success */
20868+
4f0767ce 20869+out_dt:
4a4d8108 20870+ au_ren_rev_dt(err, a);
4f0767ce 20871+out_hdir:
4a4d8108 20872+ au_ren_unlock(a);
4f0767ce 20873+out_children:
4a4d8108 20874+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
20875+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
20876+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
20877+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
20878+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 20879+ }
027c5e7a 20880+out_parent:
4a4d8108
AM
20881+ if (!err)
20882+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
20883+ else {
20884+ au_update_dbstart(a->dst_dentry);
20885+ if (!a->dst_inode)
20886+ d_drop(a->dst_dentry);
20887+ }
4a4d8108
AM
20888+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20889+ di_write_unlock(a->dst_parent);
20890+ else
20891+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 20892+out_unlock:
4a4d8108 20893+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 20894+out_free:
4a4d8108
AM
20895+ iput(a->dst_inode);
20896+ if (a->thargs)
20897+ au_whtmp_rmdir_free(a->thargs);
20898+ kfree(a);
4f0767ce 20899+out:
4a4d8108
AM
20900+ AuTraceErr(err);
20901+ return err;
1308ab2a 20902+}
7f207e10
AM
20903diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
20904--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
2000de60 20905+++ linux/fs/aufs/Kconfig 2015-03-27 21:56:35.460128334 +0100
c1595e42 20906@@ -0,0 +1,185 @@
4a4d8108
AM
20907+config AUFS_FS
20908+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
20909+ help
20910+ Aufs is a stackable unification filesystem such as Unionfs,
20911+ which unifies several directories and provides a merged single
20912+ directory.
20913+ In the early days, aufs was entirely re-designed and
20914+ re-implemented Unionfs Version 1.x series. Introducing many
20915+ original ideas, approaches and improvements, it becomes totally
20916+ different from Unionfs while keeping the basic features.
1facf9fc 20917+
4a4d8108
AM
20918+if AUFS_FS
20919+choice
20920+ prompt "Maximum number of branches"
20921+ default AUFS_BRANCH_MAX_127
20922+ help
20923+ Specifies the maximum number of branches (or member directories)
20924+ in a single aufs. The larger value consumes more system
20925+ resources and has a minor impact to performance.
20926+config AUFS_BRANCH_MAX_127
20927+ bool "127"
20928+ help
20929+ Specifies the maximum number of branches (or member directories)
20930+ in a single aufs. The larger value consumes more system
20931+ resources and has a minor impact to performance.
20932+config AUFS_BRANCH_MAX_511
20933+ bool "511"
20934+ help
20935+ Specifies the maximum number of branches (or member directories)
20936+ in a single aufs. The larger value consumes more system
20937+ resources and has a minor impact to performance.
20938+config AUFS_BRANCH_MAX_1023
20939+ bool "1023"
20940+ help
20941+ Specifies the maximum number of branches (or member directories)
20942+ in a single aufs. The larger value consumes more system
20943+ resources and has a minor impact to performance.
20944+config AUFS_BRANCH_MAX_32767
20945+ bool "32767"
20946+ help
20947+ Specifies the maximum number of branches (or member directories)
20948+ in a single aufs. The larger value consumes more system
20949+ resources and has a minor impact to performance.
20950+endchoice
1facf9fc 20951+
e49829fe
JR
20952+config AUFS_SBILIST
20953+ bool
20954+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
20955+ default y
20956+ help
20957+ Automatic configuration for internal use.
20958+ When aufs supports Magic SysRq or /proc, enabled automatically.
20959+
4a4d8108
AM
20960+config AUFS_HNOTIFY
20961+ bool "Detect direct branch access (bypassing aufs)"
20962+ help
20963+ If you want to modify files on branches directly, eg. bypassing aufs,
20964+ and want aufs to detect the changes of them fully, then enable this
20965+ option and use 'udba=notify' mount option.
7f207e10 20966+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
20967+ It will have a negative impact to the performance.
20968+ See detail in aufs.5.
dece6358 20969+
4a4d8108
AM
20970+choice
20971+ prompt "method" if AUFS_HNOTIFY
20972+ default AUFS_HFSNOTIFY
20973+config AUFS_HFSNOTIFY
20974+ bool "fsnotify"
20975+ select FSNOTIFY
4a4d8108 20976+endchoice
1facf9fc 20977+
4a4d8108
AM
20978+config AUFS_EXPORT
20979+ bool "NFS-exportable aufs"
2cbb1c4b 20980+ depends on EXPORTFS
4a4d8108
AM
20981+ help
20982+ If you want to export your mounted aufs via NFS, then enable this
20983+ option. There are several requirements for this configuration.
20984+ See detail in aufs.5.
1facf9fc 20985+
4a4d8108
AM
20986+config AUFS_INO_T_64
20987+ bool
20988+ depends on AUFS_EXPORT
20989+ depends on 64BIT && !(ALPHA || S390)
20990+ default y
20991+ help
20992+ Automatic configuration for internal use.
20993+ /* typedef unsigned long/int __kernel_ino_t */
20994+ /* alpha and s390x are int */
1facf9fc 20995+
c1595e42
JR
20996+config AUFS_XATTR
20997+ bool "support for XATTR/EA (including Security Labels)"
20998+ help
20999+ If your branch fs supports XATTR/EA and you want to make them
21000+ available in aufs too, then enable this opsion and specify the
21001+ branch attributes for EA.
21002+ See detail in aufs.5.
21003+
076b876e
AM
21004+config AUFS_FHSM
21005+ bool "File-based Hierarchical Storage Management"
21006+ help
21007+ Hierarchical Storage Management (or HSM) is a well-known feature
21008+ in the storage world. Aufs provides this feature as file-based.
21009+ with multiple branches.
21010+ These multiple branches are prioritized, ie. the topmost one
21011+ should be the fastest drive and be used heavily.
21012+
4a4d8108
AM
21013+config AUFS_RDU
21014+ bool "Readdir in userspace"
21015+ help
21016+ Aufs has two methods to provide a merged view for a directory,
21017+ by a user-space library and by kernel-space natively. The latter
21018+ is always enabled but sometimes large and slow.
21019+ If you enable this option, install the library in aufs2-util
21020+ package, and set some environment variables for your readdir(3),
21021+ then the work will be handled in user-space which generally
21022+ shows better performance in most cases.
21023+ See detail in aufs.5.
1facf9fc 21024+
4a4d8108
AM
21025+config AUFS_SHWH
21026+ bool "Show whiteouts"
21027+ help
21028+ If you want to make the whiteouts in aufs visible, then enable
21029+ this option and specify 'shwh' mount option. Although it may
21030+ sounds like philosophy or something, but in technically it
21031+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 21032+
4a4d8108
AM
21033+config AUFS_BR_RAMFS
21034+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
21035+ help
21036+ If you want to use ramfs as an aufs branch fs, then enable this
21037+ option. Generally tmpfs is recommended.
21038+ Aufs prohibited them to be a branch fs by default, because
21039+ initramfs becomes unusable after switch_root or something
21040+ generally. If you sets initramfs as an aufs branch and boot your
21041+ system by switch_root, you will meet a problem easily since the
21042+ files in initramfs may be inaccessible.
21043+ Unless you are going to use ramfs as an aufs branch fs without
21044+ switch_root or something, leave it N.
1facf9fc 21045+
4a4d8108
AM
21046+config AUFS_BR_FUSE
21047+ bool "Fuse fs as an aufs branch"
21048+ depends on FUSE_FS
21049+ select AUFS_POLL
21050+ help
21051+ If you want to use fuse-based userspace filesystem as an aufs
21052+ branch fs, then enable this option.
21053+ It implements the internal poll(2) operation which is
21054+ implemented by fuse only (curretnly).
1facf9fc 21055+
4a4d8108
AM
21056+config AUFS_POLL
21057+ bool
21058+ help
21059+ Automatic configuration for internal use.
1facf9fc 21060+
4a4d8108
AM
21061+config AUFS_BR_HFSPLUS
21062+ bool "Hfsplus as an aufs branch"
21063+ depends on HFSPLUS_FS
21064+ default y
21065+ help
21066+ If you want to use hfsplus fs as an aufs branch fs, then enable
21067+ this option. This option introduces a small overhead at
21068+ copying-up a file on hfsplus.
1facf9fc 21069+
4a4d8108
AM
21070+config AUFS_BDEV_LOOP
21071+ bool
21072+ depends on BLK_DEV_LOOP
21073+ default y
21074+ help
21075+ Automatic configuration for internal use.
21076+ Convert =[ym] into =y.
1308ab2a 21077+
4a4d8108
AM
21078+config AUFS_DEBUG
21079+ bool "Debug aufs"
21080+ help
21081+ Enable this to compile aufs internal debug code.
21082+ It will have a negative impact to the performance.
21083+
21084+config AUFS_MAGIC_SYSRQ
21085+ bool
21086+ depends on AUFS_DEBUG && MAGIC_SYSRQ
21087+ default y
21088+ help
21089+ Automatic configuration for internal use.
21090+ When aufs supports Magic SysRq, enabled automatically.
21091+endif
7f207e10
AM
21092diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
21093--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
2000de60 21094+++ linux/fs/aufs/loop.c 2015-03-27 21:56:35.466795000 +0100
523b37e3 21095@@ -0,0 +1,145 @@
1facf9fc 21096+/*
2000de60 21097+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21098+ *
21099+ * This program, aufs is free software; you can redistribute it and/or modify
21100+ * it under the terms of the GNU General Public License as published by
21101+ * the Free Software Foundation; either version 2 of the License, or
21102+ * (at your option) any later version.
dece6358
AM
21103+ *
21104+ * This program is distributed in the hope that it will be useful,
21105+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21106+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21107+ * GNU General Public License for more details.
21108+ *
21109+ * You should have received a copy of the GNU General Public License
523b37e3 21110+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21111+ */
21112+
21113+/*
21114+ * support for loopback block device as a branch
21115+ */
21116+
1facf9fc 21117+#include "aufs.h"
21118+
392086de
AM
21119+/* added into drivers/block/loop.c */
21120+static struct file *(*backing_file_func)(struct super_block *sb);
21121+
1facf9fc 21122+/*
21123+ * test if two lower dentries have overlapping branches.
21124+ */
b752ccd1 21125+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 21126+{
b752ccd1 21127+ struct super_block *h_sb;
392086de
AM
21128+ struct file *backing_file;
21129+
21130+ if (unlikely(!backing_file_func)) {
21131+ /* don't load "loop" module here */
21132+ backing_file_func = symbol_get(loop_backing_file);
21133+ if (unlikely(!backing_file_func))
21134+ /* "loop" module is not loaded */
21135+ return 0;
21136+ }
1facf9fc 21137+
b752ccd1 21138+ h_sb = h_adding->d_sb;
392086de
AM
21139+ backing_file = backing_file_func(h_sb);
21140+ if (!backing_file)
1facf9fc 21141+ return 0;
21142+
2000de60 21143+ h_adding = backing_file->f_path.dentry;
b752ccd1
AM
21144+ /*
21145+ * h_adding can be local NFS.
21146+ * in this case aufs cannot detect the loop.
21147+ */
21148+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 21149+ return 1;
b752ccd1 21150+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 21151+}
21152+
21153+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
21154+int au_test_loopback_kthread(void)
21155+{
b752ccd1
AM
21156+ int ret;
21157+ struct task_struct *tsk = current;
a2a7ad62 21158+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
21159+
21160+ ret = 0;
21161+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
21162+ get_task_comm(comm, tsk);
21163+ c = comm[4];
b752ccd1 21164+ ret = ('0' <= c && c <= '9'
a2a7ad62 21165+ && !strncmp(comm, "loop", 4));
b752ccd1 21166+ }
1facf9fc 21167+
b752ccd1 21168+ return ret;
1facf9fc 21169+}
87a755f4
AM
21170+
21171+/* ---------------------------------------------------------------------- */
21172+
21173+#define au_warn_loopback_step 16
21174+static int au_warn_loopback_nelem = au_warn_loopback_step;
21175+static unsigned long *au_warn_loopback_array;
21176+
21177+void au_warn_loopback(struct super_block *h_sb)
21178+{
21179+ int i, new_nelem;
21180+ unsigned long *a, magic;
21181+ static DEFINE_SPINLOCK(spin);
21182+
21183+ magic = h_sb->s_magic;
21184+ spin_lock(&spin);
21185+ a = au_warn_loopback_array;
21186+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
21187+ if (a[i] == magic) {
21188+ spin_unlock(&spin);
21189+ return;
21190+ }
21191+
21192+ /* h_sb is new to us, print it */
21193+ if (i < au_warn_loopback_nelem) {
21194+ a[i] = magic;
21195+ goto pr;
21196+ }
21197+
21198+ /* expand the array */
21199+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
21200+ a = au_kzrealloc(au_warn_loopback_array,
21201+ au_warn_loopback_nelem * sizeof(unsigned long),
21202+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
21203+ if (a) {
21204+ au_warn_loopback_nelem = new_nelem;
21205+ au_warn_loopback_array = a;
21206+ a[i] = magic;
21207+ goto pr;
21208+ }
21209+
21210+ spin_unlock(&spin);
21211+ AuWarn1("realloc failed, ignored\n");
21212+ return;
21213+
21214+pr:
21215+ spin_unlock(&spin);
0c3ec466
AM
21216+ pr_warn("you may want to try another patch for loopback file "
21217+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
21218+}
21219+
21220+int au_loopback_init(void)
21221+{
21222+ int err;
21223+ struct super_block *sb __maybe_unused;
21224+
21225+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
21226+
21227+ err = 0;
21228+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
21229+ sizeof(unsigned long), GFP_NOFS);
21230+ if (unlikely(!au_warn_loopback_array))
21231+ err = -ENOMEM;
21232+
21233+ return err;
21234+}
21235+
21236+void au_loopback_fin(void)
21237+{
392086de 21238+ symbol_put(loop_backing_file);
87a755f4
AM
21239+ kfree(au_warn_loopback_array);
21240+}
7f207e10
AM
21241diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
21242--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
2000de60 21243+++ linux/fs/aufs/loop.h 2015-03-27 21:56:35.466795000 +0100
523b37e3 21244@@ -0,0 +1,52 @@
1facf9fc 21245+/*
2000de60 21246+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21247+ *
21248+ * This program, aufs is free software; you can redistribute it and/or modify
21249+ * it under the terms of the GNU General Public License as published by
21250+ * the Free Software Foundation; either version 2 of the License, or
21251+ * (at your option) any later version.
dece6358
AM
21252+ *
21253+ * This program is distributed in the hope that it will be useful,
21254+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21255+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21256+ * GNU General Public License for more details.
21257+ *
21258+ * You should have received a copy of the GNU General Public License
523b37e3 21259+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21260+ */
21261+
21262+/*
21263+ * support for loopback mount as a branch
21264+ */
21265+
21266+#ifndef __AUFS_LOOP_H__
21267+#define __AUFS_LOOP_H__
21268+
21269+#ifdef __KERNEL__
21270+
dece6358
AM
21271+struct dentry;
21272+struct super_block;
1facf9fc 21273+
21274+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
21275+/* drivers/block/loop.c */
21276+struct file *loop_backing_file(struct super_block *sb);
21277+
1facf9fc 21278+/* loop.c */
b752ccd1 21279+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 21280+int au_test_loopback_kthread(void);
87a755f4
AM
21281+void au_warn_loopback(struct super_block *h_sb);
21282+
21283+int au_loopback_init(void);
21284+void au_loopback_fin(void);
1facf9fc 21285+#else
4a4d8108 21286+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 21287+ struct dentry *h_adding)
4a4d8108 21288+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
21289+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
21290+
21291+AuStubInt0(au_loopback_init, void)
21292+AuStubVoid(au_loopback_fin, void)
1facf9fc 21293+#endif /* BLK_DEV_LOOP */
21294+
21295+#endif /* __KERNEL__ */
21296+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
21297diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
21298--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
2000de60 21299+++ linux/fs/aufs/magic.mk 2015-03-27 21:56:35.466795000 +0100
4a4d8108 21300@@ -0,0 +1,54 @@
1facf9fc 21301+
21302+# defined in ${srctree}/fs/fuse/inode.c
21303+# tristate
21304+ifdef CONFIG_FUSE_FS
21305+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
21306+endif
21307+
21308+# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
21309+# tristate
21310+ifdef CONFIG_OCFS2_FS
21311+ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
21312+endif
21313+
21314+# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
21315+# tristate
21316+ifdef CONFIG_OCFS2_FS_O2CB
21317+ccflags-y += -DDLMFS_MAGIC=0x76a9f425
21318+endif
21319+
1facf9fc 21320+# defined in ${srctree}/fs/cifs/cifsfs.c
21321+# tristate
21322+ifdef CONFIG_CIFS_FS
21323+ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
21324+endif
21325+
21326+# defined in ${srctree}/fs/xfs/xfs_sb.h
21327+# tristate
21328+ifdef CONFIG_XFS_FS
21329+ccflags-y += -DXFS_SB_MAGIC=0x58465342
21330+endif
21331+
21332+# defined in ${srctree}/fs/configfs/mount.c
21333+# tristate
21334+ifdef CONFIG_CONFIGFS_FS
21335+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
21336+endif
21337+
21338+# defined in ${srctree}/fs/9p/v9fs.h
21339+# tristate
21340+ifdef CONFIG_9P_FS
21341+ccflags-y += -DV9FS_MAGIC=0x01021997
21342+endif
21343+
21344+# defined in ${srctree}/fs/ubifs/ubifs.h
21345+# tristate
21346+ifdef CONFIG_UBIFS_FS
21347+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
21348+endif
4a4d8108
AM
21349+
21350+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
21351+# tristate
21352+ifdef CONFIG_HFSPLUS_FS
21353+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
21354+endif
7f207e10
AM
21355diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
21356--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
2000de60 21357+++ linux/fs/aufs/Makefile 2015-03-27 21:56:35.460128334 +0100
c1595e42 21358@@ -0,0 +1,44 @@
4a4d8108
AM
21359+
21360+include ${src}/magic.mk
21361+ifeq (${CONFIG_AUFS_FS},m)
21362+include ${src}/conf.mk
21363+endif
21364+-include ${src}/priv_def.mk
21365+
21366+# cf. include/linux/kernel.h
21367+# enable pr_debug
21368+ccflags-y += -DDEBUG
f6c5ef8b
AM
21369+# sparse requires the full pathname
21370+ifdef M
523b37e3 21371+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 21372+else
523b37e3 21373+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 21374+endif
4a4d8108
AM
21375+
21376+obj-$(CONFIG_AUFS_FS) += aufs.o
21377+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
21378+ wkq.o vfsub.o dcsub.o \
e49829fe 21379+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
21380+ dinfo.o dentry.o \
21381+ dynop.o \
21382+ finfo.o file.o f_op.o \
21383+ dir.o vdir.o \
21384+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 21385+ mvdown.o ioctl.o
4a4d8108
AM
21386+
21387+# all are boolean
e49829fe 21388+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
21389+aufs-$(CONFIG_SYSFS) += sysfs.o
21390+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
21391+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
21392+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
21393+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 21394+aufs-$(CONFIG_AUFS_EXPORT) += export.o
c1595e42
JR
21395+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
21396+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
076b876e 21397+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
21398+aufs-$(CONFIG_AUFS_POLL) += poll.o
21399+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
21400+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
21401+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
21402+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
21403diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
21404--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
2000de60 21405+++ linux/fs/aufs/module.c 2015-03-27 21:56:35.466795000 +0100
076b876e 21406@@ -0,0 +1,210 @@
1facf9fc 21407+/*
2000de60 21408+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21409+ *
21410+ * This program, aufs is free software; you can redistribute it and/or modify
21411+ * it under the terms of the GNU General Public License as published by
21412+ * the Free Software Foundation; either version 2 of the License, or
21413+ * (at your option) any later version.
dece6358
AM
21414+ *
21415+ * This program is distributed in the hope that it will be useful,
21416+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21417+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21418+ * GNU General Public License for more details.
21419+ *
21420+ * You should have received a copy of the GNU General Public License
523b37e3 21421+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21422+ */
21423+
21424+/*
21425+ * module global variables and operations
21426+ */
21427+
21428+#include <linux/module.h>
21429+#include <linux/seq_file.h>
21430+#include "aufs.h"
21431+
21432+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
21433+{
21434+ if (new_sz <= nused)
21435+ return p;
21436+
21437+ p = krealloc(p, new_sz, gfp);
21438+ if (p)
21439+ memset(p + nused, 0, new_sz - nused);
21440+ return p;
21441+}
21442+
21443+/* ---------------------------------------------------------------------- */
21444+
21445+/*
21446+ * aufs caches
21447+ */
21448+struct kmem_cache *au_cachep[AuCache_Last];
21449+static int __init au_cache_init(void)
21450+{
4a4d8108 21451+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 21452+ if (au_cachep[AuCache_DINFO])
027c5e7a 21453+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
21454+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
21455+ au_icntnr_init_once);
1facf9fc 21456+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
21457+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
21458+ au_fi_init_once);
1facf9fc 21459+ if (au_cachep[AuCache_FINFO])
21460+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
21461+ if (au_cachep[AuCache_VDIR])
21462+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
21463+ if (au_cachep[AuCache_DEHSTR])
21464+ return 0;
21465+
21466+ return -ENOMEM;
21467+}
21468+
21469+static void au_cache_fin(void)
21470+{
21471+ int i;
4a4d8108 21472+
537831f9
AM
21473+ /*
21474+ * Make sure all delayed rcu free inodes are flushed before we
21475+ * destroy cache.
21476+ */
21477+ rcu_barrier();
21478+
7eafdf33
AM
21479+ /* excluding AuCache_HNOTIFY */
21480+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
21481+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 21482+ if (au_cachep[i]) {
21483+ kmem_cache_destroy(au_cachep[i]);
21484+ au_cachep[i] = NULL;
21485+ }
21486+}
21487+
21488+/* ---------------------------------------------------------------------- */
21489+
21490+int au_dir_roflags;
21491+
e49829fe 21492+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
21493+/*
21494+ * iterate_supers_type() doesn't protect us from
21495+ * remounting (branch management)
21496+ */
e49829fe
JR
21497+struct au_splhead au_sbilist;
21498+#endif
21499+
9dbd164d
AM
21500+struct lock_class_key au_lc_key[AuLcKey_Last];
21501+
1facf9fc 21502+/*
21503+ * functions for module interface.
21504+ */
21505+MODULE_LICENSE("GPL");
21506+/* MODULE_LICENSE("GPL v2"); */
dece6358 21507+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 21508+MODULE_DESCRIPTION(AUFS_NAME
21509+ " -- Advanced multi layered unification filesystem");
21510+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 21511+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 21512+
1facf9fc 21513+/* this module parameter has no meaning when SYSFS is disabled */
21514+int sysaufs_brs = 1;
21515+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
21516+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
21517+
076b876e
AM
21518+/* this module parameter has no meaning when USER_NS is disabled */
21519+static bool au_userns;
21520+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
21521+module_param_named(allow_userns, au_userns, bool, S_IRUGO);
21522+
1facf9fc 21523+/* ---------------------------------------------------------------------- */
21524+
21525+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
21526+
21527+int au_seq_path(struct seq_file *seq, struct path *path)
21528+{
21529+ return seq_path(seq, path, au_esc_chars);
21530+}
21531+
21532+/* ---------------------------------------------------------------------- */
21533+
21534+static int __init aufs_init(void)
21535+{
21536+ int err, i;
21537+ char *p;
21538+
21539+ p = au_esc_chars;
21540+ for (i = 1; i <= ' '; i++)
21541+ *p++ = i;
21542+ *p++ = '\\';
21543+ *p++ = '\x7f';
21544+ *p = 0;
21545+
21546+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
21547+
e49829fe 21548+ au_sbilist_init();
1facf9fc 21549+ sysaufs_brs_init();
21550+ au_debug_init();
4a4d8108 21551+ au_dy_init();
1facf9fc 21552+ err = sysaufs_init();
21553+ if (unlikely(err))
21554+ goto out;
e49829fe 21555+ err = au_procfs_init();
4f0767ce 21556+ if (unlikely(err))
953406b4 21557+ goto out_sysaufs;
e49829fe
JR
21558+ err = au_wkq_init();
21559+ if (unlikely(err))
21560+ goto out_procfs;
87a755f4 21561+ err = au_loopback_init();
1facf9fc 21562+ if (unlikely(err))
21563+ goto out_wkq;
87a755f4
AM
21564+ err = au_hnotify_init();
21565+ if (unlikely(err))
21566+ goto out_loopback;
1facf9fc 21567+ err = au_sysrq_init();
21568+ if (unlikely(err))
21569+ goto out_hin;
21570+ err = au_cache_init();
21571+ if (unlikely(err))
21572+ goto out_sysrq;
076b876e
AM
21573+
21574+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 21575+ err = register_filesystem(&aufs_fs_type);
21576+ if (unlikely(err))
21577+ goto out_cache;
076b876e 21578+
4a4d8108
AM
21579+ /* since we define pr_fmt, call printk directly */
21580+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 21581+ goto out; /* success */
21582+
4f0767ce 21583+out_cache:
1facf9fc 21584+ au_cache_fin();
4f0767ce 21585+out_sysrq:
1facf9fc 21586+ au_sysrq_fin();
4f0767ce 21587+out_hin:
4a4d8108 21588+ au_hnotify_fin();
87a755f4
AM
21589+out_loopback:
21590+ au_loopback_fin();
4f0767ce 21591+out_wkq:
1facf9fc 21592+ au_wkq_fin();
e49829fe
JR
21593+out_procfs:
21594+ au_procfs_fin();
4f0767ce 21595+out_sysaufs:
1facf9fc 21596+ sysaufs_fin();
4a4d8108 21597+ au_dy_fin();
4f0767ce 21598+out:
1facf9fc 21599+ return err;
21600+}
21601+
21602+static void __exit aufs_exit(void)
21603+{
21604+ unregister_filesystem(&aufs_fs_type);
21605+ au_cache_fin();
21606+ au_sysrq_fin();
4a4d8108 21607+ au_hnotify_fin();
87a755f4 21608+ au_loopback_fin();
1facf9fc 21609+ au_wkq_fin();
e49829fe 21610+ au_procfs_fin();
1facf9fc 21611+ sysaufs_fin();
4a4d8108 21612+ au_dy_fin();
1facf9fc 21613+}
21614+
21615+module_init(aufs_init);
21616+module_exit(aufs_exit);
7f207e10
AM
21617diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
21618--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
2000de60 21619+++ linux/fs/aufs/module.h 2015-03-27 21:56:35.466795000 +0100
523b37e3 21620@@ -0,0 +1,104 @@
1facf9fc 21621+/*
2000de60 21622+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 21623+ *
21624+ * This program, aufs is free software; you can redistribute it and/or modify
21625+ * it under the terms of the GNU General Public License as published by
21626+ * the Free Software Foundation; either version 2 of the License, or
21627+ * (at your option) any later version.
dece6358
AM
21628+ *
21629+ * This program is distributed in the hope that it will be useful,
21630+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21631+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21632+ * GNU General Public License for more details.
21633+ *
21634+ * You should have received a copy of the GNU General Public License
523b37e3 21635+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21636+ */
21637+
21638+/*
21639+ * module initialization and module-global
21640+ */
21641+
21642+#ifndef __AUFS_MODULE_H__
21643+#define __AUFS_MODULE_H__
21644+
21645+#ifdef __KERNEL__
21646+
21647+#include <linux/slab.h>
21648+
dece6358
AM
21649+struct path;
21650+struct seq_file;
21651+
1facf9fc 21652+/* module parameters */
1facf9fc 21653+extern int sysaufs_brs;
21654+
21655+/* ---------------------------------------------------------------------- */
21656+
21657+extern int au_dir_roflags;
21658+
9dbd164d
AM
21659+enum {
21660+ AuLcNonDir_FIINFO,
21661+ AuLcNonDir_DIINFO,
21662+ AuLcNonDir_IIINFO,
21663+
21664+ AuLcDir_FIINFO,
21665+ AuLcDir_DIINFO,
21666+ AuLcDir_IIINFO,
21667+
21668+ AuLcSymlink_DIINFO,
21669+ AuLcSymlink_IIINFO,
21670+
21671+ AuLcKey_Last
21672+};
21673+extern struct lock_class_key au_lc_key[AuLcKey_Last];
21674+
1facf9fc 21675+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
21676+int au_seq_path(struct seq_file *seq, struct path *path);
21677+
e49829fe
JR
21678+#ifdef CONFIG_PROC_FS
21679+/* procfs.c */
21680+int __init au_procfs_init(void);
21681+void au_procfs_fin(void);
21682+#else
21683+AuStubInt0(au_procfs_init, void);
21684+AuStubVoid(au_procfs_fin, void);
21685+#endif
21686+
4f0767ce
JR
21687+/* ---------------------------------------------------------------------- */
21688+
21689+/* kmem cache */
1facf9fc 21690+enum {
21691+ AuCache_DINFO,
21692+ AuCache_ICNTNR,
21693+ AuCache_FINFO,
21694+ AuCache_VDIR,
21695+ AuCache_DEHSTR,
7eafdf33 21696+ AuCache_HNOTIFY, /* must be last */
1facf9fc 21697+ AuCache_Last
21698+};
21699+
4a4d8108
AM
21700+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
21701+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
21702+#define AuCacheCtor(type, ctor) \
21703+ kmem_cache_create(#type, sizeof(struct type), \
21704+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 21705+
21706+extern struct kmem_cache *au_cachep[];
21707+
21708+#define AuCacheFuncs(name, index) \
4a4d8108 21709+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 21710+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 21711+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 21712+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
21713+
21714+AuCacheFuncs(dinfo, DINFO);
21715+AuCacheFuncs(icntnr, ICNTNR);
21716+AuCacheFuncs(finfo, FINFO);
21717+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
21718+AuCacheFuncs(vdir_dehstr, DEHSTR);
21719+#ifdef CONFIG_AUFS_HNOTIFY
21720+AuCacheFuncs(hnotify, HNOTIFY);
21721+#endif
1facf9fc 21722+
4a4d8108
AM
21723+#endif /* __KERNEL__ */
21724+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
21725diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
21726--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
2000de60 21727+++ linux/fs/aufs/mvdown.c 2015-03-27 21:56:35.466795000 +0100
c1595e42 21728@@ -0,0 +1,694 @@
c2b27bf2 21729+/*
2000de60 21730+ * Copyright (C) 2011-2015 Junjiro R. Okajima
c2b27bf2
AM
21731+ *
21732+ * This program, aufs is free software; you can redistribute it and/or modify
21733+ * it under the terms of the GNU General Public License as published by
21734+ * the Free Software Foundation; either version 2 of the License, or
21735+ * (at your option) any later version.
21736+ *
21737+ * This program is distributed in the hope that it will be useful,
21738+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21739+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21740+ * GNU General Public License for more details.
21741+ *
21742+ * You should have received a copy of the GNU General Public License
523b37e3
AM
21743+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21744+ */
21745+
21746+/*
21747+ * move-down, opposite of copy-up
c2b27bf2
AM
21748+ */
21749+
21750+#include "aufs.h"
21751+
c2b27bf2
AM
21752+struct au_mvd_args {
21753+ struct {
c2b27bf2
AM
21754+ struct super_block *h_sb;
21755+ struct dentry *h_parent;
21756+ struct au_hinode *hdir;
392086de 21757+ struct inode *h_dir, *h_inode;
c1595e42 21758+ struct au_pin pin;
c2b27bf2
AM
21759+ } info[AUFS_MVDOWN_NARRAY];
21760+
21761+ struct aufs_mvdown mvdown;
21762+ struct dentry *dentry, *parent;
21763+ struct inode *inode, *dir;
21764+ struct super_block *sb;
21765+ aufs_bindex_t bopq, bwh, bfound;
21766+ unsigned char rename_lock;
c2b27bf2
AM
21767+};
21768+
392086de 21769+#define mvd_errno mvdown.au_errno
076b876e
AM
21770+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
21771+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
21772+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
21773+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 21774+
392086de
AM
21775+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
21776+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
21777+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
21778+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
21779+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
c1595e42 21780+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
392086de
AM
21781+
21782+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
21783+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
21784+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
21785+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
21786+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c1595e42 21787+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
c2b27bf2
AM
21788+
21789+#define AU_MVD_PR(flag, ...) do { \
21790+ if (flag) \
21791+ pr_err(__VA_ARGS__); \
21792+ } while (0)
21793+
076b876e
AM
21794+static int find_lower_writable(struct au_mvd_args *a)
21795+{
21796+ struct super_block *sb;
21797+ aufs_bindex_t bindex, bend;
21798+ struct au_branch *br;
21799+
21800+ sb = a->sb;
21801+ bindex = a->mvd_bsrc;
21802+ bend = au_sbend(sb);
21803+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
21804+ for (bindex++; bindex <= bend; bindex++) {
21805+ br = au_sbr(sb, bindex);
21806+ if (au_br_fhsm(br->br_perm)
21807+ && (!(au_br_sb(br)->s_flags & MS_RDONLY)))
21808+ return bindex;
21809+ }
21810+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
21811+ for (bindex++; bindex <= bend; bindex++) {
21812+ br = au_sbr(sb, bindex);
21813+ if (!au_br_rdonly(br))
21814+ return bindex;
21815+ }
21816+ else
21817+ for (bindex++; bindex <= bend; bindex++) {
21818+ br = au_sbr(sb, bindex);
21819+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
21820+ if (au_br_rdonly(br))
21821+ a->mvdown.flags
21822+ |= AUFS_MVDOWN_ROLOWER_R;
21823+ return bindex;
21824+ }
21825+ }
21826+
21827+ return -1;
21828+}
21829+
c2b27bf2 21830+/* make the parent dir on bdst */
392086de 21831+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21832+{
21833+ int err;
21834+
21835+ err = 0;
21836+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
21837+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
21838+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
21839+ a->mvd_h_dst_parent = NULL;
21840+ if (au_dbend(a->parent) >= a->mvd_bdst)
21841+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
21842+ if (!a->mvd_h_dst_parent) {
21843+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
21844+ if (unlikely(err)) {
392086de 21845+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
21846+ goto out;
21847+ }
21848+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
21849+ }
21850+
21851+out:
21852+ AuTraceErr(err);
21853+ return err;
21854+}
21855+
21856+/* lock them all */
392086de 21857+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21858+{
21859+ int err;
21860+ struct dentry *h_trap;
21861+
21862+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
21863+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
c1595e42
JR
21864+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
21865+ au_opt_udba(a->sb),
21866+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21867+ AuTraceErr(err);
21868+ if (unlikely(err)) {
21869+ AU_MVD_PR(dmsg, "pin_dst failed\n");
21870+ goto out;
21871+ }
21872+
c2b27bf2
AM
21873+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
21874+ a->rename_lock = 0;
c1595e42
JR
21875+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
21876+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
21877+ au_opt_udba(a->sb),
21878+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21879+ err = au_do_pin(&a->mvd_pin_src);
21880+ AuTraceErr(err);
21881+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
21882+ if (unlikely(err)) {
21883+ AU_MVD_PR(dmsg, "pin_src failed\n");
21884+ goto out_dst;
21885+ }
21886+ goto out; /* success */
c2b27bf2
AM
21887+ }
21888+
c2b27bf2 21889+ a->rename_lock = 1;
c1595e42
JR
21890+ au_pin_hdir_unlock(&a->mvd_pin_dst);
21891+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
21892+ au_opt_udba(a->sb),
21893+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21894+ AuTraceErr(err);
21895+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
21896+ if (unlikely(err)) {
21897+ AU_MVD_PR(dmsg, "pin_src failed\n");
21898+ au_pin_hdir_lock(&a->mvd_pin_dst);
21899+ goto out_dst;
21900+ }
21901+ au_pin_hdir_unlock(&a->mvd_pin_src);
c2b27bf2
AM
21902+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21903+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
21904+ if (h_trap) {
21905+ err = (h_trap != a->mvd_h_src_parent);
21906+ if (err)
21907+ err = (h_trap != a->mvd_h_dst_parent);
21908+ }
21909+ BUG_ON(err); /* it should never happen */
c1595e42
JR
21910+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
21911+ err = -EBUSY;
21912+ AuTraceErr(err);
21913+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21914+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
21915+ au_pin_hdir_lock(&a->mvd_pin_src);
21916+ au_unpin(&a->mvd_pin_src);
21917+ au_pin_hdir_lock(&a->mvd_pin_dst);
21918+ goto out_dst;
21919+ }
21920+ goto out; /* success */
c2b27bf2 21921+
c1595e42
JR
21922+out_dst:
21923+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
21924+out:
21925+ AuTraceErr(err);
21926+ return err;
21927+}
21928+
392086de 21929+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2 21930+{
c1595e42
JR
21931+ if (!a->rename_lock)
21932+ au_unpin(&a->mvd_pin_src);
21933+ else {
c2b27bf2
AM
21934+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21935+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
c1595e42
JR
21936+ au_pin_hdir_lock(&a->mvd_pin_src);
21937+ au_unpin(&a->mvd_pin_src);
21938+ au_pin_hdir_lock(&a->mvd_pin_dst);
21939+ }
21940+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
21941+}
21942+
21943+/* copy-down the file */
392086de 21944+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21945+{
21946+ int err;
21947+ struct au_cp_generic cpg = {
21948+ .dentry = a->dentry,
21949+ .bdst = a->mvd_bdst,
21950+ .bsrc = a->mvd_bsrc,
21951+ .len = -1,
c1595e42 21952+ .pin = &a->mvd_pin_dst,
c2b27bf2
AM
21953+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21954+ };
21955+
21956+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
21957+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
21958+ au_fset_cpup(cpg.flags, OVERWRITE);
21959+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
21960+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
21961+ err = au_sio_cpdown_simple(&cpg);
21962+ if (unlikely(err))
392086de 21963+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
21964+
21965+ AuTraceErr(err);
21966+ return err;
21967+}
21968+
21969+/*
21970+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
21971+ * were sleeping
21972+ */
392086de 21973+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21974+{
21975+ int err;
21976+ struct path h_path;
21977+ struct au_branch *br;
523b37e3 21978+ struct inode *delegated;
c2b27bf2
AM
21979+
21980+ br = au_sbr(a->sb, a->mvd_bdst);
21981+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
21982+ err = PTR_ERR(h_path.dentry);
21983+ if (IS_ERR(h_path.dentry)) {
392086de 21984+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
21985+ goto out;
21986+ }
21987+
21988+ err = 0;
21989+ if (h_path.dentry->d_inode) {
21990+ h_path.mnt = au_br_mnt(br);
523b37e3 21991+ delegated = NULL;
c2b27bf2 21992+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
523b37e3
AM
21993+ &delegated, /*force*/0);
21994+ if (unlikely(err == -EWOULDBLOCK)) {
21995+ pr_warn("cannot retry for NFSv4 delegation"
21996+ " for an internal unlink\n");
21997+ iput(delegated);
21998+ }
c2b27bf2 21999+ if (unlikely(err))
392086de 22000+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
22001+ }
22002+ dput(h_path.dentry);
22003+
22004+out:
22005+ AuTraceErr(err);
22006+ return err;
22007+}
22008+
22009+/*
22010+ * unlink the topmost h_dentry
c2b27bf2 22011+ */
392086de 22012+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22013+{
22014+ int err;
22015+ struct path h_path;
523b37e3 22016+ struct inode *delegated;
c2b27bf2
AM
22017+
22018+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
22019+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
22020+ delegated = NULL;
22021+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
22022+ if (unlikely(err == -EWOULDBLOCK)) {
22023+ pr_warn("cannot retry for NFSv4 delegation"
22024+ " for an internal unlink\n");
22025+ iput(delegated);
22026+ }
c2b27bf2 22027+ if (unlikely(err))
392086de 22028+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
22029+
22030+ AuTraceErr(err);
22031+ return err;
22032+}
22033+
076b876e
AM
22034+/* Since mvdown succeeded, we ignore an error of this function */
22035+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
22036+{
22037+ int err;
22038+ struct au_branch *br;
22039+
22040+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
22041+ br = au_sbr(a->sb, a->mvd_bsrc);
22042+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
22043+ if (!err) {
22044+ br = au_sbr(a->sb, a->mvd_bdst);
22045+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
22046+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
22047+ }
22048+ if (!err)
22049+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
22050+ else
22051+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
22052+}
22053+
c2b27bf2
AM
22054+/*
22055+ * copy-down the file and unlink the bsrc file.
22056+ * - unlink the bdst whout if exist
22057+ * - copy-down the file (with whtmp name and rename)
22058+ * - unlink the bsrc file
22059+ */
392086de 22060+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22061+{
22062+ int err;
22063+
392086de 22064+ err = au_do_mkdir(dmsg, a);
c2b27bf2 22065+ if (!err)
392086de 22066+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
22067+ if (unlikely(err))
22068+ goto out;
22069+
22070+ /*
22071+ * do not revert the activities we made on bdst since they should be
22072+ * harmless in aufs.
22073+ */
22074+
392086de 22075+ err = au_do_cpdown(dmsg, a);
c2b27bf2 22076+ if (!err)
392086de
AM
22077+ err = au_do_unlink_wh(dmsg, a);
22078+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
22079+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
22080+ if (unlikely(err))
22081+ goto out_unlock;
22082+
c1595e42
JR
22083+ AuDbg("%pd2, 0x%x, %d --> %d\n",
22084+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
076b876e
AM
22085+ if (find_lower_writable(a) < 0)
22086+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
22087+
22088+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
22089+ au_do_stfs(dmsg, a);
22090+
c2b27bf2 22091+ /* maintain internal array */
392086de
AM
22092+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
22093+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
22094+ au_set_dbstart(a->dentry, a->mvd_bdst);
22095+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
22096+ au_set_ibstart(a->inode, a->mvd_bdst);
22097+ }
c2b27bf2
AM
22098+ if (au_dbend(a->dentry) < a->mvd_bdst)
22099+ au_set_dbend(a->dentry, a->mvd_bdst);
c2b27bf2
AM
22100+ if (au_ibend(a->inode) < a->mvd_bdst)
22101+ au_set_ibend(a->inode, a->mvd_bdst);
22102+
22103+out_unlock:
392086de 22104+ au_do_unlock(dmsg, a);
c2b27bf2
AM
22105+out:
22106+ AuTraceErr(err);
22107+ return err;
22108+}
22109+
22110+/* ---------------------------------------------------------------------- */
22111+
c2b27bf2 22112+/* make sure the file is idle */
392086de 22113+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22114+{
22115+ int err, plinked;
c2b27bf2
AM
22116+
22117+ err = 0;
c2b27bf2
AM
22118+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
22119+ if (au_dbstart(a->dentry) == a->mvd_bsrc
c1595e42 22120+ && au_dcount(a->dentry) == 1
c2b27bf2 22121+ && atomic_read(&a->inode->i_count) == 1
392086de 22122+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
22123+ && (!plinked || !au_plink_test(a->inode))
22124+ && a->inode->i_nlink == 1)
22125+ goto out;
22126+
22127+ err = -EBUSY;
392086de 22128+ AU_MVD_PR(dmsg,
c1595e42
JR
22129+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
22130+ a->mvd_bsrc, au_dbstart(a->dentry), au_dcount(a->dentry),
c2b27bf2 22131+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 22132+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
22133+ plinked, plinked ? au_plink_test(a->inode) : 0);
22134+
22135+out:
22136+ AuTraceErr(err);
22137+ return err;
22138+}
22139+
22140+/* make sure the parent dir is fine */
392086de 22141+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
22142+ struct au_mvd_args *a)
22143+{
22144+ int err;
22145+ aufs_bindex_t bindex;
22146+
22147+ err = 0;
22148+ if (unlikely(au_alive_dir(a->parent))) {
22149+ err = -ENOENT;
392086de 22150+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
22151+ goto out;
22152+ }
22153+
22154+ a->bopq = au_dbdiropq(a->parent);
22155+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
22156+ AuDbg("b%d\n", bindex);
22157+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
22158+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
22159+ err = -EINVAL;
392086de
AM
22160+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
22161+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
22162+ a->bopq, a->mvd_bdst);
22163+ }
22164+
22165+out:
22166+ AuTraceErr(err);
22167+ return err;
22168+}
22169+
392086de 22170+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
22171+ struct au_mvd_args *a)
22172+{
22173+ int err;
22174+ struct au_dinfo *dinfo, *tmp;
22175+
22176+ /* lookup the next lower positive entry */
22177+ err = -ENOMEM;
22178+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
22179+ if (unlikely(!tmp))
22180+ goto out;
22181+
22182+ a->bfound = -1;
22183+ a->bwh = -1;
22184+ dinfo = au_di(a->dentry);
22185+ au_di_cp(tmp, dinfo);
22186+ au_di_swap(tmp, dinfo);
22187+
22188+ /* returns the number of positive dentries */
22189+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
22190+ if (!err)
22191+ a->bwh = au_dbwh(a->dentry);
22192+ else if (err > 0)
22193+ a->bfound = au_dbstart(a->dentry);
22194+
22195+ au_di_swap(tmp, dinfo);
22196+ au_rw_write_unlock(&tmp->di_rwsem);
22197+ au_di_free(tmp);
22198+ if (unlikely(err < 0))
392086de 22199+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
22200+
22201+ /*
22202+ * here, we have these cases.
22203+ * bfound == -1
22204+ * no positive dentry under bsrc. there are more sub-cases.
22205+ * bwh < 0
22206+ * there no whiteout, we can safely move-down.
22207+ * bwh <= bsrc
22208+ * impossible
22209+ * bsrc < bwh && bwh < bdst
22210+ * there is a whiteout on RO branch. cannot proceed.
22211+ * bwh == bdst
22212+ * there is a whiteout on the RW target branch. it should
22213+ * be removed.
22214+ * bdst < bwh
22215+ * there is a whiteout somewhere unrelated branch.
22216+ * -1 < bfound && bfound <= bsrc
22217+ * impossible.
22218+ * bfound < bdst
22219+ * found, but it is on RO branch between bsrc and bdst. cannot
22220+ * proceed.
22221+ * bfound == bdst
22222+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
22223+ * error.
22224+ * bdst < bfound
22225+ * found, after we create the file on bdst, it will be hidden.
22226+ */
22227+
22228+ AuDebugOn(a->bfound == -1
22229+ && a->bwh != -1
22230+ && a->bwh <= a->mvd_bsrc);
22231+ AuDebugOn(-1 < a->bfound
22232+ && a->bfound <= a->mvd_bsrc);
22233+
22234+ err = -EINVAL;
22235+ if (a->bfound == -1
22236+ && a->mvd_bsrc < a->bwh
22237+ && a->bwh != -1
22238+ && a->bwh < a->mvd_bdst) {
392086de
AM
22239+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
22240+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
22241+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
22242+ goto out;
22243+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
22244+ a->mvd_errno = EAU_MVDOWN_UPPER;
22245+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
22246+ a->mvd_bdst, a->bfound);
22247+ goto out;
22248+ }
22249+
22250+ err = 0; /* success */
22251+
22252+out:
22253+ AuTraceErr(err);
22254+ return err;
22255+}
22256+
392086de 22257+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22258+{
22259+ int err;
22260+
392086de
AM
22261+ err = 0;
22262+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
22263+ && a->bfound == a->mvd_bdst)
22264+ err = -EEXIST;
c2b27bf2
AM
22265+ AuTraceErr(err);
22266+ return err;
22267+}
22268+
392086de 22269+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22270+{
22271+ int err;
22272+ struct au_branch *br;
22273+
22274+ err = -EISDIR;
22275+ if (unlikely(S_ISDIR(a->inode->i_mode)))
22276+ goto out;
22277+
22278+ err = -EINVAL;
392086de
AM
22279+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
22280+ a->mvd_bsrc = au_ibstart(a->inode);
22281+ else {
22282+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
22283+ if (unlikely(a->mvd_bsrc < 0
22284+ || (a->mvd_bsrc < au_dbstart(a->dentry)
22285+ || au_dbend(a->dentry) < a->mvd_bsrc
22286+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
22287+ || (a->mvd_bsrc < au_ibstart(a->inode)
22288+ || au_ibend(a->inode) < a->mvd_bsrc
22289+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
22290+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
22291+ AU_MVD_PR(dmsg, "no upper\n");
22292+ goto out;
22293+ }
22294+ }
c2b27bf2 22295+ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
392086de
AM
22296+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
22297+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
22298+ goto out;
22299+ }
392086de 22300+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
22301+ br = au_sbr(a->sb, a->mvd_bsrc);
22302+ err = au_br_rdonly(br);
392086de
AM
22303+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
22304+ if (unlikely(err))
22305+ goto out;
22306+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
22307+ || IS_APPEND(a->mvd_h_src_inode))) {
22308+ if (err)
22309+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
22310+ /* go on */
22311+ } else
c2b27bf2
AM
22312+ goto out;
22313+
22314+ err = -EINVAL;
392086de
AM
22315+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
22316+ a->mvd_bdst = find_lower_writable(a);
22317+ if (unlikely(a->mvd_bdst < 0)) {
22318+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
22319+ AU_MVD_PR(dmsg, "no writable lower branch\n");
22320+ goto out;
22321+ }
22322+ } else {
22323+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
22324+ if (unlikely(a->mvd_bdst < 0
22325+ || au_sbend(a->sb) < a->mvd_bdst)) {
22326+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
22327+ AU_MVD_PR(dmsg, "no lower brid\n");
22328+ goto out;
22329+ }
c2b27bf2
AM
22330+ }
22331+
392086de 22332+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 22333+ if (!err)
392086de 22334+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 22335+ if (!err)
392086de 22336+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 22337+ if (!err)
392086de 22338+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
22339+ if (!err)
22340+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
22341+
22342+out:
22343+ AuTraceErr(err);
22344+ return err;
22345+}
22346+
22347+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
22348+{
392086de
AM
22349+ int err, e;
22350+ unsigned char dmsg;
22351+ struct au_mvd_args *args;
c2b27bf2
AM
22352+
22353+ err = -EPERM;
22354+ if (unlikely(!capable(CAP_SYS_ADMIN)))
22355+ goto out;
22356+
392086de
AM
22357+ err = -ENOMEM;
22358+ args = kmalloc(sizeof(*args), GFP_NOFS);
22359+ if (unlikely(!args))
22360+ goto out;
22361+
22362+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
22363+ if (!err)
22364+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
22365+ if (unlikely(err)) {
22366+ err = -EFAULT;
392086de
AM
22367+ AuTraceErr(err);
22368+ goto out_free;
c2b27bf2 22369+ }
392086de
AM
22370+ AuDbg("flags 0x%x\n", args->mvdown.flags);
22371+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
22372+ args->mvdown.au_errno = 0;
22373+ args->dentry = dentry;
22374+ args->inode = dentry->d_inode;
22375+ args->sb = dentry->d_sb;
c2b27bf2 22376+
392086de
AM
22377+ err = -ENOENT;
22378+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
22379+ args->parent = dget_parent(dentry);
22380+ args->dir = args->parent->d_inode;
22381+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
22382+ dput(args->parent);
22383+ if (unlikely(args->parent != dentry->d_parent)) {
22384+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
22385+ goto out_dir;
22386+ }
22387+
392086de 22388+ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
c2b27bf2
AM
22389+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
22390+ if (unlikely(err))
22391+ goto out_inode;
22392+
392086de
AM
22393+ di_write_lock_parent(args->parent);
22394+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
22395+ if (unlikely(err))
22396+ goto out_parent;
22397+
392086de 22398+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
22399+ if (unlikely(err))
22400+ goto out_parent;
c2b27bf2 22401+
392086de
AM
22402+ au_cpup_attr_timesizes(args->dir);
22403+ au_cpup_attr_timesizes(args->inode);
22404+ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
c2b27bf2
AM
22405+ /* au_digen_dec(dentry); */
22406+
22407+out_parent:
392086de 22408+ di_write_unlock(args->parent);
c2b27bf2
AM
22409+ aufs_read_unlock(dentry, AuLock_DW);
22410+out_inode:
392086de 22411+ mutex_unlock(&args->inode->i_mutex);
c2b27bf2 22412+out_dir:
392086de
AM
22413+ mutex_unlock(&args->dir->i_mutex);
22414+out_free:
22415+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
22416+ if (unlikely(e))
22417+ err = -EFAULT;
22418+ kfree(args);
c2b27bf2
AM
22419+out:
22420+ AuTraceErr(err);
22421+ return err;
22422+}
22423diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
22424--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
22425+++ linux/fs/aufs/opts.c 2015-03-27 21:56:35.466795000 +0100
22426@@ -0,0 +1,1859 @@
1facf9fc 22427+/*
2000de60 22428+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 22429+ *
22430+ * This program, aufs is free software; you can redistribute it and/or modify
22431+ * it under the terms of the GNU General Public License as published by
22432+ * the Free Software Foundation; either version 2 of the License, or
22433+ * (at your option) any later version.
dece6358
AM
22434+ *
22435+ * This program is distributed in the hope that it will be useful,
22436+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22437+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22438+ * GNU General Public License for more details.
22439+ *
22440+ * You should have received a copy of the GNU General Public License
523b37e3 22441+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22442+ */
22443+
22444+/*
22445+ * mount options/flags
22446+ */
22447+
dece6358 22448+#include <linux/namei.h>
1facf9fc 22449+#include <linux/types.h> /* a distribution requires */
22450+#include <linux/parser.h>
22451+#include "aufs.h"
22452+
22453+/* ---------------------------------------------------------------------- */
22454+
22455+enum {
22456+ Opt_br,
22457+ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
22458+ Opt_idel, Opt_imod, Opt_ireorder,
22459+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
dece6358 22460+ Opt_rdblk_def, Opt_rdhash_def,
1facf9fc 22461+ Opt_xino, Opt_zxino, Opt_noxino,
22462+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
22463+ Opt_trunc_xino_path, Opt_itrunc_xino,
22464+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 22465+ Opt_shwh, Opt_noshwh,
1facf9fc 22466+ Opt_plink, Opt_noplink, Opt_list_plink,
22467+ Opt_udba,
4a4d8108 22468+ Opt_dio, Opt_nodio,
1facf9fc 22469+ /* Opt_lock, Opt_unlock, */
22470+ Opt_cmd, Opt_cmd_args,
22471+ Opt_diropq_a, Opt_diropq_w,
22472+ Opt_warn_perm, Opt_nowarn_perm,
22473+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 22474+ Opt_fhsm_sec,
1facf9fc 22475+ Opt_refrof, Opt_norefrof,
22476+ Opt_verbose, Opt_noverbose,
22477+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 22478+ Opt_dirperm1, Opt_nodirperm1,
c1595e42 22479+ Opt_acl, Opt_noacl,
1facf9fc 22480+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
22481+};
22482+
22483+static match_table_t options = {
22484+ {Opt_br, "br=%s"},
22485+ {Opt_br, "br:%s"},
22486+
22487+ {Opt_add, "add=%d:%s"},
22488+ {Opt_add, "add:%d:%s"},
22489+ {Opt_add, "ins=%d:%s"},
22490+ {Opt_add, "ins:%d:%s"},
22491+ {Opt_append, "append=%s"},
22492+ {Opt_append, "append:%s"},
22493+ {Opt_prepend, "prepend=%s"},
22494+ {Opt_prepend, "prepend:%s"},
22495+
22496+ {Opt_del, "del=%s"},
22497+ {Opt_del, "del:%s"},
22498+ /* {Opt_idel, "idel:%d"}, */
22499+ {Opt_mod, "mod=%s"},
22500+ {Opt_mod, "mod:%s"},
22501+ /* {Opt_imod, "imod:%d:%s"}, */
22502+
22503+ {Opt_dirwh, "dirwh=%d"},
22504+
22505+ {Opt_xino, "xino=%s"},
22506+ {Opt_noxino, "noxino"},
22507+ {Opt_trunc_xino, "trunc_xino"},
22508+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
22509+ {Opt_notrunc_xino, "notrunc_xino"},
22510+ {Opt_trunc_xino_path, "trunc_xino=%s"},
22511+ {Opt_itrunc_xino, "itrunc_xino=%d"},
22512+ /* {Opt_zxino, "zxino=%s"}, */
22513+ {Opt_trunc_xib, "trunc_xib"},
22514+ {Opt_notrunc_xib, "notrunc_xib"},
22515+
e49829fe 22516+#ifdef CONFIG_PROC_FS
1facf9fc 22517+ {Opt_plink, "plink"},
e49829fe
JR
22518+#else
22519+ {Opt_ignore_silent, "plink"},
22520+#endif
22521+
1facf9fc 22522+ {Opt_noplink, "noplink"},
e49829fe 22523+
1facf9fc 22524+#ifdef CONFIG_AUFS_DEBUG
22525+ {Opt_list_plink, "list_plink"},
22526+#endif
22527+
22528+ {Opt_udba, "udba=%s"},
22529+
4a4d8108
AM
22530+ {Opt_dio, "dio"},
22531+ {Opt_nodio, "nodio"},
22532+
076b876e
AM
22533+#ifdef CONFIG_AUFS_FHSM
22534+ {Opt_fhsm_sec, "fhsm_sec=%d"},
22535+#else
22536+ {Opt_ignore_silent, "fhsm_sec=%d"},
22537+#endif
22538+
1facf9fc 22539+ {Opt_diropq_a, "diropq=always"},
22540+ {Opt_diropq_a, "diropq=a"},
22541+ {Opt_diropq_w, "diropq=whiteouted"},
22542+ {Opt_diropq_w, "diropq=w"},
22543+
22544+ {Opt_warn_perm, "warn_perm"},
22545+ {Opt_nowarn_perm, "nowarn_perm"},
22546+
22547+ /* keep them temporary */
1facf9fc 22548+ {Opt_ignore_silent, "nodlgt"},
1facf9fc 22549+ {Opt_ignore_silent, "clean_plink"},
22550+
dece6358
AM
22551+#ifdef CONFIG_AUFS_SHWH
22552+ {Opt_shwh, "shwh"},
22553+#endif
22554+ {Opt_noshwh, "noshwh"},
22555+
076b876e
AM
22556+ {Opt_dirperm1, "dirperm1"},
22557+ {Opt_nodirperm1, "nodirperm1"},
22558+
1facf9fc 22559+ {Opt_rendir, "rendir=%d"},
22560+
22561+ {Opt_refrof, "refrof"},
22562+ {Opt_norefrof, "norefrof"},
22563+
22564+ {Opt_verbose, "verbose"},
22565+ {Opt_verbose, "v"},
22566+ {Opt_noverbose, "noverbose"},
22567+ {Opt_noverbose, "quiet"},
22568+ {Opt_noverbose, "q"},
22569+ {Opt_noverbose, "silent"},
22570+
22571+ {Opt_sum, "sum"},
22572+ {Opt_nosum, "nosum"},
22573+ {Opt_wsum, "wsum"},
22574+
22575+ {Opt_rdcache, "rdcache=%d"},
22576+ {Opt_rdblk, "rdblk=%d"},
dece6358 22577+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 22578+ {Opt_rdhash, "rdhash=%d"},
dece6358 22579+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 22580+
22581+ {Opt_wbr_create, "create=%s"},
22582+ {Opt_wbr_create, "create_policy=%s"},
22583+ {Opt_wbr_copyup, "cpup=%s"},
22584+ {Opt_wbr_copyup, "copyup=%s"},
22585+ {Opt_wbr_copyup, "copyup_policy=%s"},
22586+
c1595e42
JR
22587+ /* generic VFS flag */
22588+#ifdef CONFIG_FS_POSIX_ACL
22589+ {Opt_acl, "acl"},
22590+ {Opt_noacl, "noacl"},
22591+#else
22592+ {Opt_ignore_silent, "acl"},
22593+ {Opt_ignore_silent, "noacl"},
22594+#endif
22595+
1facf9fc 22596+ /* internal use for the scripts */
22597+ {Opt_ignore_silent, "si=%s"},
22598+
22599+ {Opt_br, "dirs=%s"},
22600+ {Opt_ignore, "debug=%d"},
22601+ {Opt_ignore, "delete=whiteout"},
22602+ {Opt_ignore, "delete=all"},
22603+ {Opt_ignore, "imap=%s"},
22604+
1308ab2a 22605+ /* temporary workaround, due to old mount(8)? */
22606+ {Opt_ignore_silent, "relatime"},
22607+
1facf9fc 22608+ {Opt_err, NULL}
22609+};
22610+
22611+/* ---------------------------------------------------------------------- */
22612+
076b876e 22613+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 22614+{
076b876e
AM
22615+ struct match_token *p;
22616+
22617+ p = tbl;
22618+ while (p->pattern) {
22619+ if (p->token == val)
22620+ return p->pattern;
22621+ p++;
1facf9fc 22622+ }
22623+ BUG();
22624+ return "??";
22625+}
22626+
076b876e
AM
22627+static const char *au_optstr(int *val, match_table_t tbl)
22628+{
22629+ struct match_token *p;
22630+ int v;
22631+
22632+ v = *val;
2000de60
JR
22633+ if (!v)
22634+ goto out;
076b876e 22635+ p = tbl;
2000de60
JR
22636+ while (p->pattern) {
22637+ if (p->token
22638+ && (v & p->token) == p->token) {
076b876e
AM
22639+ *val &= ~p->token;
22640+ return p->pattern;
22641+ }
22642+ p++;
22643+ }
2000de60
JR
22644+
22645+out:
076b876e
AM
22646+ return NULL;
22647+}
22648+
1facf9fc 22649+/* ---------------------------------------------------------------------- */
22650+
1e00d052 22651+static match_table_t brperm = {
1facf9fc 22652+ {AuBrPerm_RO, AUFS_BRPERM_RO},
22653+ {AuBrPerm_RR, AUFS_BRPERM_RR},
22654+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
22655+ {0, NULL}
22656+};
1facf9fc 22657+
86dc4139 22658+static match_table_t brattr = {
076b876e
AM
22659+ /* general */
22660+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
22661+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
c1595e42 22662+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
86dc4139 22663+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
2000de60 22664+#ifdef CONFIG_AUFS_FHSM
076b876e 22665+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
2000de60
JR
22666+#endif
22667+#ifdef CONFIG_AUFS_XATTR
c1595e42
JR
22668+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
22669+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
22670+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
22671+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
22672+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
22673+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
2000de60 22674+#endif
076b876e
AM
22675+
22676+ /* ro/rr branch */
1e00d052 22677+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
22678+
22679+ /* rw branch */
22680+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 22681+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 22682+
1e00d052 22683+ {0, NULL}
1facf9fc 22684+};
22685+
1e00d052
AM
22686+static int br_attr_val(char *str, match_table_t table, substring_t args[])
22687+{
22688+ int attr, v;
22689+ char *p;
22690+
22691+ attr = 0;
22692+ do {
22693+ p = strchr(str, '+');
22694+ if (p)
22695+ *p = 0;
22696+ v = match_token(str, table, args);
076b876e
AM
22697+ if (v) {
22698+ if (v & AuBrAttr_CMOO_Mask)
22699+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 22700+ attr |= v;
076b876e 22701+ } else {
1e00d052
AM
22702+ if (p)
22703+ *p = '+';
0c3ec466 22704+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
22705+ break;
22706+ }
22707+ if (p)
22708+ str = p + 1;
22709+ } while (p);
22710+
22711+ return attr;
22712+}
22713+
076b876e
AM
22714+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
22715+{
22716+ int sz;
22717+ const char *p;
22718+ char *q;
22719+
076b876e
AM
22720+ q = str->a;
22721+ *q = 0;
22722+ p = au_optstr(&perm, brattr);
22723+ if (p) {
22724+ sz = strlen(p);
22725+ memcpy(q, p, sz + 1);
22726+ q += sz;
22727+ } else
22728+ goto out;
22729+
22730+ do {
22731+ p = au_optstr(&perm, brattr);
22732+ if (p) {
22733+ *q++ = '+';
22734+ sz = strlen(p);
22735+ memcpy(q, p, sz + 1);
22736+ q += sz;
22737+ }
22738+ } while (p);
22739+
22740+out:
c1595e42 22741+ return q - str->a;
076b876e
AM
22742+}
22743+
4a4d8108 22744+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 22745+{
076b876e
AM
22746+ int val, bad, sz;
22747+ char *p;
1facf9fc 22748+ substring_t args[MAX_OPT_ARGS];
076b876e 22749+ au_br_perm_str_t attr;
1facf9fc 22750+
1e00d052
AM
22751+ p = strchr(perm, '+');
22752+ if (p)
22753+ *p = 0;
22754+ val = match_token(perm, brperm, args);
22755+ if (!val) {
22756+ if (p)
22757+ *p = '+';
0c3ec466 22758+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
22759+ val = AuBrPerm_RO;
22760+ goto out;
22761+ }
22762+ if (!p)
22763+ goto out;
22764+
076b876e
AM
22765+ val |= br_attr_val(p + 1, brattr, args);
22766+
22767+ bad = 0;
86dc4139 22768+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
22769+ case AuBrPerm_RO:
22770+ case AuBrPerm_RR:
076b876e
AM
22771+ bad = val & AuBrWAttr_Mask;
22772+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
22773+ break;
22774+ case AuBrPerm_RW:
076b876e
AM
22775+ bad = val & AuBrRAttr_Mask;
22776+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
22777+ break;
22778+ }
c1595e42
JR
22779+
22780+ /*
22781+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
22782+ * does not treat it as an error, just warning.
22783+ * this is a tiny guard for the user operation.
22784+ */
22785+ if (val & AuBrAttr_UNPIN) {
22786+ bad |= AuBrAttr_UNPIN;
22787+ val &= ~AuBrAttr_UNPIN;
22788+ }
22789+
076b876e
AM
22790+ if (unlikely(bad)) {
22791+ sz = au_do_optstr_br_attr(&attr, bad);
22792+ AuDebugOn(!sz);
22793+ pr_warn("ignored branch attribute %s\n", attr.a);
22794+ }
1e00d052
AM
22795+
22796+out:
1facf9fc 22797+ return val;
22798+}
22799+
076b876e 22800+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 22801+{
076b876e
AM
22802+ au_br_perm_str_t attr;
22803+ const char *p;
22804+ char *q;
1e00d052
AM
22805+ int sz;
22806+
076b876e
AM
22807+ q = str->a;
22808+ p = au_optstr(&perm, brperm);
22809+ AuDebugOn(!p || !*p);
22810+ sz = strlen(p);
22811+ memcpy(q, p, sz + 1);
22812+ q += sz;
1e00d052 22813+
076b876e
AM
22814+ sz = au_do_optstr_br_attr(&attr, perm);
22815+ if (sz) {
22816+ *q++ = '+';
22817+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
22818+ }
22819+
076b876e 22820+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 22821+}
22822+
22823+/* ---------------------------------------------------------------------- */
22824+
22825+static match_table_t udbalevel = {
22826+ {AuOpt_UDBA_REVAL, "reval"},
22827+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
22828+#ifdef CONFIG_AUFS_HNOTIFY
22829+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
22830+#ifdef CONFIG_AUFS_HFSNOTIFY
22831+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 22832+#endif
1facf9fc 22833+#endif
22834+ {-1, NULL}
22835+};
22836+
4a4d8108 22837+static int noinline_for_stack udba_val(char *str)
1facf9fc 22838+{
22839+ substring_t args[MAX_OPT_ARGS];
22840+
7f207e10 22841+ return match_token(str, udbalevel, args);
1facf9fc 22842+}
22843+
22844+const char *au_optstr_udba(int udba)
22845+{
076b876e 22846+ return au_parser_pattern(udba, udbalevel);
1facf9fc 22847+}
22848+
22849+/* ---------------------------------------------------------------------- */
22850+
22851+static match_table_t au_wbr_create_policy = {
22852+ {AuWbrCreate_TDP, "tdp"},
22853+ {AuWbrCreate_TDP, "top-down-parent"},
22854+ {AuWbrCreate_RR, "rr"},
22855+ {AuWbrCreate_RR, "round-robin"},
22856+ {AuWbrCreate_MFS, "mfs"},
22857+ {AuWbrCreate_MFS, "most-free-space"},
22858+ {AuWbrCreate_MFSV, "mfs:%d"},
22859+ {AuWbrCreate_MFSV, "most-free-space:%d"},
22860+
22861+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
22862+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
22863+ {AuWbrCreate_PMFS, "pmfs"},
22864+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
22865+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
22866+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 22867+
22868+ {-1, NULL}
22869+};
22870+
dece6358
AM
22871+/*
22872+ * cf. linux/lib/parser.c and cmdline.c
22873+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 22874+ * kstrto...().
dece6358 22875+ */
4a4d8108
AM
22876+static int noinline_for_stack
22877+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 22878+{
22879+ int err;
22880+ unsigned int len;
22881+ char a[32];
22882+
22883+ err = -ERANGE;
22884+ len = s->to - s->from;
22885+ if (len + 1 <= sizeof(a)) {
22886+ memcpy(a, s->from, len);
22887+ a[len] = '\0';
9dbd164d 22888+ err = kstrtoull(a, 0, result);
1facf9fc 22889+ }
22890+ return err;
22891+}
22892+
22893+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
22894+ struct au_opt_wbr_create *create)
22895+{
22896+ int err;
22897+ unsigned long long ull;
22898+
22899+ err = 0;
22900+ if (!au_match_ull(arg, &ull))
22901+ create->mfsrr_watermark = ull;
22902+ else {
4a4d8108 22903+ pr_err("bad integer in %s\n", str);
1facf9fc 22904+ err = -EINVAL;
22905+ }
22906+
22907+ return err;
22908+}
22909+
22910+static int au_wbr_mfs_sec(substring_t *arg, char *str,
22911+ struct au_opt_wbr_create *create)
22912+{
22913+ int n, err;
22914+
22915+ err = 0;
027c5e7a 22916+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 22917+ create->mfs_second = n;
22918+ else {
4a4d8108 22919+ pr_err("bad integer in %s\n", str);
1facf9fc 22920+ err = -EINVAL;
22921+ }
22922+
22923+ return err;
22924+}
22925+
4a4d8108
AM
22926+static int noinline_for_stack
22927+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 22928+{
22929+ int err, e;
22930+ substring_t args[MAX_OPT_ARGS];
22931+
22932+ err = match_token(str, au_wbr_create_policy, args);
22933+ create->wbr_create = err;
22934+ switch (err) {
22935+ case AuWbrCreate_MFSRRV:
392086de 22936+ case AuWbrCreate_PMFSRRV:
1facf9fc 22937+ e = au_wbr_mfs_wmark(&args[0], str, create);
22938+ if (!e)
22939+ e = au_wbr_mfs_sec(&args[1], str, create);
22940+ if (unlikely(e))
22941+ err = e;
22942+ break;
22943+ case AuWbrCreate_MFSRR:
392086de 22944+ case AuWbrCreate_PMFSRR:
1facf9fc 22945+ e = au_wbr_mfs_wmark(&args[0], str, create);
22946+ if (unlikely(e)) {
22947+ err = e;
22948+ break;
22949+ }
22950+ /*FALLTHROUGH*/
22951+ case AuWbrCreate_MFS:
22952+ case AuWbrCreate_PMFS:
027c5e7a 22953+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 22954+ break;
22955+ case AuWbrCreate_MFSV:
22956+ case AuWbrCreate_PMFSV:
22957+ e = au_wbr_mfs_sec(&args[0], str, create);
22958+ if (unlikely(e))
22959+ err = e;
22960+ break;
22961+ }
22962+
22963+ return err;
22964+}
22965+
22966+const char *au_optstr_wbr_create(int wbr_create)
22967+{
076b876e 22968+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 22969+}
22970+
22971+static match_table_t au_wbr_copyup_policy = {
22972+ {AuWbrCopyup_TDP, "tdp"},
22973+ {AuWbrCopyup_TDP, "top-down-parent"},
22974+ {AuWbrCopyup_BUP, "bup"},
22975+ {AuWbrCopyup_BUP, "bottom-up-parent"},
22976+ {AuWbrCopyup_BU, "bu"},
22977+ {AuWbrCopyup_BU, "bottom-up"},
22978+ {-1, NULL}
22979+};
22980+
4a4d8108 22981+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 22982+{
22983+ substring_t args[MAX_OPT_ARGS];
22984+
22985+ return match_token(str, au_wbr_copyup_policy, args);
22986+}
22987+
22988+const char *au_optstr_wbr_copyup(int wbr_copyup)
22989+{
076b876e 22990+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 22991+}
22992+
22993+/* ---------------------------------------------------------------------- */
22994+
22995+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
22996+
22997+static void dump_opts(struct au_opts *opts)
22998+{
22999+#ifdef CONFIG_AUFS_DEBUG
23000+ /* reduce stack space */
23001+ union {
23002+ struct au_opt_add *add;
23003+ struct au_opt_del *del;
23004+ struct au_opt_mod *mod;
23005+ struct au_opt_xino *xino;
23006+ struct au_opt_xino_itrunc *xino_itrunc;
23007+ struct au_opt_wbr_create *create;
23008+ } u;
23009+ struct au_opt *opt;
23010+
23011+ opt = opts->opt;
23012+ while (opt->type != Opt_tail) {
23013+ switch (opt->type) {
23014+ case Opt_add:
23015+ u.add = &opt->add;
23016+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
23017+ u.add->bindex, u.add->pathname, u.add->perm,
23018+ u.add->path.dentry);
23019+ break;
23020+ case Opt_del:
23021+ case Opt_idel:
23022+ u.del = &opt->del;
23023+ AuDbg("del {%s, %p}\n",
23024+ u.del->pathname, u.del->h_path.dentry);
23025+ break;
23026+ case Opt_mod:
23027+ case Opt_imod:
23028+ u.mod = &opt->mod;
23029+ AuDbg("mod {%s, 0x%x, %p}\n",
23030+ u.mod->path, u.mod->perm, u.mod->h_root);
23031+ break;
23032+ case Opt_append:
23033+ u.add = &opt->add;
23034+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
23035+ u.add->bindex, u.add->pathname, u.add->perm,
23036+ u.add->path.dentry);
23037+ break;
23038+ case Opt_prepend:
23039+ u.add = &opt->add;
23040+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
23041+ u.add->bindex, u.add->pathname, u.add->perm,
23042+ u.add->path.dentry);
23043+ break;
23044+ case Opt_dirwh:
23045+ AuDbg("dirwh %d\n", opt->dirwh);
23046+ break;
23047+ case Opt_rdcache:
23048+ AuDbg("rdcache %d\n", opt->rdcache);
23049+ break;
23050+ case Opt_rdblk:
23051+ AuDbg("rdblk %u\n", opt->rdblk);
23052+ break;
dece6358
AM
23053+ case Opt_rdblk_def:
23054+ AuDbg("rdblk_def\n");
23055+ break;
1facf9fc 23056+ case Opt_rdhash:
23057+ AuDbg("rdhash %u\n", opt->rdhash);
23058+ break;
dece6358
AM
23059+ case Opt_rdhash_def:
23060+ AuDbg("rdhash_def\n");
23061+ break;
1facf9fc 23062+ case Opt_xino:
23063+ u.xino = &opt->xino;
523b37e3 23064+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 23065+ break;
23066+ case Opt_trunc_xino:
23067+ AuLabel(trunc_xino);
23068+ break;
23069+ case Opt_notrunc_xino:
23070+ AuLabel(notrunc_xino);
23071+ break;
23072+ case Opt_trunc_xino_path:
23073+ case Opt_itrunc_xino:
23074+ u.xino_itrunc = &opt->xino_itrunc;
23075+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
23076+ break;
23077+
23078+ case Opt_noxino:
23079+ AuLabel(noxino);
23080+ break;
23081+ case Opt_trunc_xib:
23082+ AuLabel(trunc_xib);
23083+ break;
23084+ case Opt_notrunc_xib:
23085+ AuLabel(notrunc_xib);
23086+ break;
dece6358
AM
23087+ case Opt_shwh:
23088+ AuLabel(shwh);
23089+ break;
23090+ case Opt_noshwh:
23091+ AuLabel(noshwh);
23092+ break;
076b876e
AM
23093+ case Opt_dirperm1:
23094+ AuLabel(dirperm1);
23095+ break;
23096+ case Opt_nodirperm1:
23097+ AuLabel(nodirperm1);
23098+ break;
1facf9fc 23099+ case Opt_plink:
23100+ AuLabel(plink);
23101+ break;
23102+ case Opt_noplink:
23103+ AuLabel(noplink);
23104+ break;
23105+ case Opt_list_plink:
23106+ AuLabel(list_plink);
23107+ break;
23108+ case Opt_udba:
23109+ AuDbg("udba %d, %s\n",
23110+ opt->udba, au_optstr_udba(opt->udba));
23111+ break;
4a4d8108
AM
23112+ case Opt_dio:
23113+ AuLabel(dio);
23114+ break;
23115+ case Opt_nodio:
23116+ AuLabel(nodio);
23117+ break;
1facf9fc 23118+ case Opt_diropq_a:
23119+ AuLabel(diropq_a);
23120+ break;
23121+ case Opt_diropq_w:
23122+ AuLabel(diropq_w);
23123+ break;
23124+ case Opt_warn_perm:
23125+ AuLabel(warn_perm);
23126+ break;
23127+ case Opt_nowarn_perm:
23128+ AuLabel(nowarn_perm);
23129+ break;
23130+ case Opt_refrof:
23131+ AuLabel(refrof);
23132+ break;
23133+ case Opt_norefrof:
23134+ AuLabel(norefrof);
23135+ break;
23136+ case Opt_verbose:
23137+ AuLabel(verbose);
23138+ break;
23139+ case Opt_noverbose:
23140+ AuLabel(noverbose);
23141+ break;
23142+ case Opt_sum:
23143+ AuLabel(sum);
23144+ break;
23145+ case Opt_nosum:
23146+ AuLabel(nosum);
23147+ break;
23148+ case Opt_wsum:
23149+ AuLabel(wsum);
23150+ break;
23151+ case Opt_wbr_create:
23152+ u.create = &opt->wbr_create;
23153+ AuDbg("create %d, %s\n", u.create->wbr_create,
23154+ au_optstr_wbr_create(u.create->wbr_create));
23155+ switch (u.create->wbr_create) {
23156+ case AuWbrCreate_MFSV:
23157+ case AuWbrCreate_PMFSV:
23158+ AuDbg("%d sec\n", u.create->mfs_second);
23159+ break;
23160+ case AuWbrCreate_MFSRR:
23161+ AuDbg("%llu watermark\n",
23162+ u.create->mfsrr_watermark);
23163+ break;
23164+ case AuWbrCreate_MFSRRV:
392086de 23165+ case AuWbrCreate_PMFSRRV:
1facf9fc 23166+ AuDbg("%llu watermark, %d sec\n",
23167+ u.create->mfsrr_watermark,
23168+ u.create->mfs_second);
23169+ break;
23170+ }
23171+ break;
23172+ case Opt_wbr_copyup:
23173+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
23174+ au_optstr_wbr_copyup(opt->wbr_copyup));
23175+ break;
076b876e
AM
23176+ case Opt_fhsm_sec:
23177+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
23178+ break;
c1595e42
JR
23179+ case Opt_acl:
23180+ AuLabel(acl);
23181+ break;
23182+ case Opt_noacl:
23183+ AuLabel(noacl);
23184+ break;
1facf9fc 23185+ default:
23186+ BUG();
23187+ }
23188+ opt++;
23189+ }
23190+#endif
23191+}
23192+
23193+void au_opts_free(struct au_opts *opts)
23194+{
23195+ struct au_opt *opt;
23196+
23197+ opt = opts->opt;
23198+ while (opt->type != Opt_tail) {
23199+ switch (opt->type) {
23200+ case Opt_add:
23201+ case Opt_append:
23202+ case Opt_prepend:
23203+ path_put(&opt->add.path);
23204+ break;
23205+ case Opt_del:
23206+ case Opt_idel:
23207+ path_put(&opt->del.h_path);
23208+ break;
23209+ case Opt_mod:
23210+ case Opt_imod:
23211+ dput(opt->mod.h_root);
23212+ break;
23213+ case Opt_xino:
23214+ fput(opt->xino.file);
23215+ break;
23216+ }
23217+ opt++;
23218+ }
23219+}
23220+
23221+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
23222+ aufs_bindex_t bindex)
23223+{
23224+ int err;
23225+ struct au_opt_add *add = &opt->add;
23226+ char *p;
23227+
23228+ add->bindex = bindex;
1e00d052 23229+ add->perm = AuBrPerm_RO;
1facf9fc 23230+ add->pathname = opt_str;
23231+ p = strchr(opt_str, '=');
23232+ if (p) {
23233+ *p++ = 0;
23234+ if (*p)
23235+ add->perm = br_perm_val(p);
23236+ }
23237+
23238+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
23239+ if (!err) {
23240+ if (!p) {
23241+ add->perm = AuBrPerm_RO;
23242+ if (au_test_fs_rr(add->path.dentry->d_sb))
23243+ add->perm = AuBrPerm_RR;
23244+ else if (!bindex && !(sb_flags & MS_RDONLY))
23245+ add->perm = AuBrPerm_RW;
23246+ }
23247+ opt->type = Opt_add;
23248+ goto out;
23249+ }
4a4d8108 23250+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 23251+ err = -EINVAL;
23252+
4f0767ce 23253+out:
1facf9fc 23254+ return err;
23255+}
23256+
23257+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
23258+{
23259+ int err;
23260+
23261+ del->pathname = args[0].from;
23262+ AuDbg("del path %s\n", del->pathname);
23263+
23264+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
23265+ if (unlikely(err))
4a4d8108 23266+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 23267+
23268+ return err;
23269+}
23270+
23271+#if 0 /* reserved for future use */
23272+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
23273+ struct au_opt_del *del, substring_t args[])
23274+{
23275+ int err;
23276+ struct dentry *root;
23277+
23278+ err = -EINVAL;
23279+ root = sb->s_root;
23280+ aufs_read_lock(root, AuLock_FLUSH);
23281+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 23282+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 23283+ goto out;
23284+ }
23285+
23286+ err = 0;
23287+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
23288+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
23289+
4f0767ce 23290+out:
1facf9fc 23291+ aufs_read_unlock(root, !AuLock_IR);
23292+ return err;
23293+}
23294+#endif
23295+
4a4d8108
AM
23296+static int noinline_for_stack
23297+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 23298+{
23299+ int err;
23300+ struct path path;
23301+ char *p;
23302+
23303+ err = -EINVAL;
23304+ mod->path = args[0].from;
23305+ p = strchr(mod->path, '=');
23306+ if (unlikely(!p)) {
4a4d8108 23307+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 23308+ goto out;
23309+ }
23310+
23311+ *p++ = 0;
23312+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
23313+ if (unlikely(err)) {
4a4d8108 23314+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 23315+ goto out;
23316+ }
23317+
23318+ mod->perm = br_perm_val(p);
23319+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
23320+ mod->h_root = dget(path.dentry);
23321+ path_put(&path);
23322+
4f0767ce 23323+out:
1facf9fc 23324+ return err;
23325+}
23326+
23327+#if 0 /* reserved for future use */
23328+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
23329+ struct au_opt_mod *mod, substring_t args[])
23330+{
23331+ int err;
23332+ struct dentry *root;
23333+
23334+ err = -EINVAL;
23335+ root = sb->s_root;
23336+ aufs_read_lock(root, AuLock_FLUSH);
23337+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 23338+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 23339+ goto out;
23340+ }
23341+
23342+ err = 0;
23343+ mod->perm = br_perm_val(args[1].from);
23344+ AuDbg("mod path %s, perm 0x%x, %s\n",
23345+ mod->path, mod->perm, args[1].from);
23346+ mod->h_root = dget(au_h_dptr(root, bindex));
23347+
4f0767ce 23348+out:
1facf9fc 23349+ aufs_read_unlock(root, !AuLock_IR);
23350+ return err;
23351+}
23352+#endif
23353+
23354+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
23355+ substring_t args[])
23356+{
23357+ int err;
23358+ struct file *file;
23359+
23360+ file = au_xino_create(sb, args[0].from, /*silent*/0);
23361+ err = PTR_ERR(file);
23362+ if (IS_ERR(file))
23363+ goto out;
23364+
23365+ err = -EINVAL;
2000de60 23366+ if (unlikely(file->f_path.dentry->d_sb == sb)) {
1facf9fc 23367+ fput(file);
4a4d8108 23368+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 23369+ goto out;
23370+ }
23371+
23372+ err = 0;
23373+ xino->file = file;
23374+ xino->path = args[0].from;
23375+
4f0767ce 23376+out:
1facf9fc 23377+ return err;
23378+}
23379+
4a4d8108
AM
23380+static int noinline_for_stack
23381+au_opts_parse_xino_itrunc_path(struct super_block *sb,
23382+ struct au_opt_xino_itrunc *xino_itrunc,
23383+ substring_t args[])
1facf9fc 23384+{
23385+ int err;
23386+ aufs_bindex_t bend, bindex;
23387+ struct path path;
23388+ struct dentry *root;
23389+
23390+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
23391+ if (unlikely(err)) {
4a4d8108 23392+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 23393+ goto out;
23394+ }
23395+
23396+ xino_itrunc->bindex = -1;
23397+ root = sb->s_root;
23398+ aufs_read_lock(root, AuLock_FLUSH);
23399+ bend = au_sbend(sb);
23400+ for (bindex = 0; bindex <= bend; bindex++) {
23401+ if (au_h_dptr(root, bindex) == path.dentry) {
23402+ xino_itrunc->bindex = bindex;
23403+ break;
23404+ }
23405+ }
23406+ aufs_read_unlock(root, !AuLock_IR);
23407+ path_put(&path);
23408+
23409+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 23410+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 23411+ err = -EINVAL;
23412+ }
23413+
4f0767ce 23414+out:
1facf9fc 23415+ return err;
23416+}
23417+
23418+/* called without aufs lock */
23419+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
23420+{
23421+ int err, n, token;
23422+ aufs_bindex_t bindex;
23423+ unsigned char skipped;
23424+ struct dentry *root;
23425+ struct au_opt *opt, *opt_tail;
23426+ char *opt_str;
23427+ /* reduce the stack space */
23428+ union {
23429+ struct au_opt_xino_itrunc *xino_itrunc;
23430+ struct au_opt_wbr_create *create;
23431+ } u;
23432+ struct {
23433+ substring_t args[MAX_OPT_ARGS];
23434+ } *a;
23435+
23436+ err = -ENOMEM;
23437+ a = kmalloc(sizeof(*a), GFP_NOFS);
23438+ if (unlikely(!a))
23439+ goto out;
23440+
23441+ root = sb->s_root;
23442+ err = 0;
23443+ bindex = 0;
23444+ opt = opts->opt;
23445+ opt_tail = opt + opts->max_opt - 1;
23446+ opt->type = Opt_tail;
23447+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
23448+ err = -EINVAL;
23449+ skipped = 0;
23450+ token = match_token(opt_str, options, a->args);
23451+ switch (token) {
23452+ case Opt_br:
23453+ err = 0;
23454+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
23455+ && *opt_str) {
23456+ err = opt_add(opt, opt_str, opts->sb_flags,
23457+ bindex++);
23458+ if (unlikely(!err && ++opt > opt_tail)) {
23459+ err = -E2BIG;
23460+ break;
23461+ }
23462+ opt->type = Opt_tail;
23463+ skipped = 1;
23464+ }
23465+ break;
23466+ case Opt_add:
23467+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23468+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23469+ break;
23470+ }
23471+ bindex = n;
23472+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
23473+ bindex);
23474+ if (!err)
23475+ opt->type = token;
23476+ break;
23477+ case Opt_append:
23478+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
23479+ /*dummy bindex*/1);
23480+ if (!err)
23481+ opt->type = token;
23482+ break;
23483+ case Opt_prepend:
23484+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
23485+ /*bindex*/0);
23486+ if (!err)
23487+ opt->type = token;
23488+ break;
23489+ case Opt_del:
23490+ err = au_opts_parse_del(&opt->del, a->args);
23491+ if (!err)
23492+ opt->type = token;
23493+ break;
23494+#if 0 /* reserved for future use */
23495+ case Opt_idel:
23496+ del->pathname = "(indexed)";
23497+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 23498+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23499+ break;
23500+ }
23501+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
23502+ if (!err)
23503+ opt->type = token;
23504+ break;
23505+#endif
23506+ case Opt_mod:
23507+ err = au_opts_parse_mod(&opt->mod, a->args);
23508+ if (!err)
23509+ opt->type = token;
23510+ break;
23511+#ifdef IMOD /* reserved for future use */
23512+ case Opt_imod:
23513+ u.mod->path = "(indexed)";
23514+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23515+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23516+ break;
23517+ }
23518+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
23519+ if (!err)
23520+ opt->type = token;
23521+ break;
23522+#endif
23523+ case Opt_xino:
23524+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
23525+ if (!err)
23526+ opt->type = token;
23527+ break;
23528+
23529+ case Opt_trunc_xino_path:
23530+ err = au_opts_parse_xino_itrunc_path
23531+ (sb, &opt->xino_itrunc, a->args);
23532+ if (!err)
23533+ opt->type = token;
23534+ break;
23535+
23536+ case Opt_itrunc_xino:
23537+ u.xino_itrunc = &opt->xino_itrunc;
23538+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23539+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23540+ break;
23541+ }
23542+ u.xino_itrunc->bindex = n;
23543+ aufs_read_lock(root, AuLock_FLUSH);
23544+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 23545+ pr_err("out of bounds, %d\n", n);
1facf9fc 23546+ aufs_read_unlock(root, !AuLock_IR);
23547+ break;
23548+ }
23549+ aufs_read_unlock(root, !AuLock_IR);
23550+ err = 0;
23551+ opt->type = token;
23552+ break;
23553+
23554+ case Opt_dirwh:
23555+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
23556+ break;
23557+ err = 0;
23558+ opt->type = token;
23559+ break;
23560+
23561+ case Opt_rdcache:
027c5e7a
AM
23562+ if (unlikely(match_int(&a->args[0], &n))) {
23563+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23564+ break;
027c5e7a
AM
23565+ }
23566+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
23567+ pr_err("rdcache must be smaller than %d\n",
23568+ AUFS_RDCACHE_MAX);
23569+ break;
23570+ }
23571+ opt->rdcache = n;
1facf9fc 23572+ err = 0;
23573+ opt->type = token;
23574+ break;
23575+ case Opt_rdblk:
23576+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23577+ || n < 0
1facf9fc 23578+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 23579+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23580+ break;
23581+ }
1308ab2a 23582+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
23583+ pr_err("rdblk must be larger than %d\n",
23584+ NAME_MAX);
1facf9fc 23585+ break;
23586+ }
23587+ opt->rdblk = n;
23588+ err = 0;
23589+ opt->type = token;
23590+ break;
23591+ case Opt_rdhash:
23592+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23593+ || n < 0
1facf9fc 23594+ || n * sizeof(struct hlist_head)
23595+ > KMALLOC_MAX_SIZE)) {
4a4d8108 23596+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23597+ break;
23598+ }
23599+ opt->rdhash = n;
23600+ err = 0;
23601+ opt->type = token;
23602+ break;
23603+
23604+ case Opt_trunc_xino:
23605+ case Opt_notrunc_xino:
23606+ case Opt_noxino:
23607+ case Opt_trunc_xib:
23608+ case Opt_notrunc_xib:
dece6358
AM
23609+ case Opt_shwh:
23610+ case Opt_noshwh:
076b876e
AM
23611+ case Opt_dirperm1:
23612+ case Opt_nodirperm1:
1facf9fc 23613+ case Opt_plink:
23614+ case Opt_noplink:
23615+ case Opt_list_plink:
4a4d8108
AM
23616+ case Opt_dio:
23617+ case Opt_nodio:
1facf9fc 23618+ case Opt_diropq_a:
23619+ case Opt_diropq_w:
23620+ case Opt_warn_perm:
23621+ case Opt_nowarn_perm:
23622+ case Opt_refrof:
23623+ case Opt_norefrof:
23624+ case Opt_verbose:
23625+ case Opt_noverbose:
23626+ case Opt_sum:
23627+ case Opt_nosum:
23628+ case Opt_wsum:
dece6358
AM
23629+ case Opt_rdblk_def:
23630+ case Opt_rdhash_def:
c1595e42
JR
23631+ case Opt_acl:
23632+ case Opt_noacl:
1facf9fc 23633+ err = 0;
23634+ opt->type = token;
23635+ break;
23636+
23637+ case Opt_udba:
23638+ opt->udba = udba_val(a->args[0].from);
23639+ if (opt->udba >= 0) {
23640+ err = 0;
23641+ opt->type = token;
23642+ } else
4a4d8108 23643+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23644+ break;
23645+
23646+ case Opt_wbr_create:
23647+ u.create = &opt->wbr_create;
23648+ u.create->wbr_create
23649+ = au_wbr_create_val(a->args[0].from, u.create);
23650+ if (u.create->wbr_create >= 0) {
23651+ err = 0;
23652+ opt->type = token;
23653+ } else
4a4d8108 23654+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23655+ break;
23656+ case Opt_wbr_copyup:
23657+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
23658+ if (opt->wbr_copyup >= 0) {
23659+ err = 0;
23660+ opt->type = token;
23661+ } else
4a4d8108 23662+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23663+ break;
23664+
076b876e
AM
23665+ case Opt_fhsm_sec:
23666+ if (unlikely(match_int(&a->args[0], &n)
23667+ || n < 0)) {
23668+ pr_err("bad integer in %s\n", opt_str);
23669+ break;
23670+ }
23671+ if (sysaufs_brs) {
23672+ opt->fhsm_second = n;
23673+ opt->type = token;
23674+ } else
23675+ pr_warn("ignored %s\n", opt_str);
23676+ err = 0;
23677+ break;
23678+
1facf9fc 23679+ case Opt_ignore:
0c3ec466 23680+ pr_warn("ignored %s\n", opt_str);
1facf9fc 23681+ /*FALLTHROUGH*/
23682+ case Opt_ignore_silent:
23683+ skipped = 1;
23684+ err = 0;
23685+ break;
23686+ case Opt_err:
4a4d8108 23687+ pr_err("unknown option %s\n", opt_str);
1facf9fc 23688+ break;
23689+ }
23690+
23691+ if (!err && !skipped) {
23692+ if (unlikely(++opt > opt_tail)) {
23693+ err = -E2BIG;
23694+ opt--;
23695+ opt->type = Opt_tail;
23696+ break;
23697+ }
23698+ opt->type = Opt_tail;
23699+ }
23700+ }
23701+
23702+ kfree(a);
23703+ dump_opts(opts);
23704+ if (unlikely(err))
23705+ au_opts_free(opts);
23706+
4f0767ce 23707+out:
1facf9fc 23708+ return err;
23709+}
23710+
23711+static int au_opt_wbr_create(struct super_block *sb,
23712+ struct au_opt_wbr_create *create)
23713+{
23714+ int err;
23715+ struct au_sbinfo *sbinfo;
23716+
dece6358
AM
23717+ SiMustWriteLock(sb);
23718+
1facf9fc 23719+ err = 1; /* handled */
23720+ sbinfo = au_sbi(sb);
23721+ if (sbinfo->si_wbr_create_ops->fin) {
23722+ err = sbinfo->si_wbr_create_ops->fin(sb);
23723+ if (!err)
23724+ err = 1;
23725+ }
23726+
23727+ sbinfo->si_wbr_create = create->wbr_create;
23728+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
23729+ switch (create->wbr_create) {
23730+ case AuWbrCreate_MFSRRV:
23731+ case AuWbrCreate_MFSRR:
392086de
AM
23732+ case AuWbrCreate_PMFSRR:
23733+ case AuWbrCreate_PMFSRRV:
1facf9fc 23734+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
23735+ /*FALLTHROUGH*/
23736+ case AuWbrCreate_MFS:
23737+ case AuWbrCreate_MFSV:
23738+ case AuWbrCreate_PMFS:
23739+ case AuWbrCreate_PMFSV:
e49829fe
JR
23740+ sbinfo->si_wbr_mfs.mfs_expire
23741+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 23742+ break;
23743+ }
23744+
23745+ if (sbinfo->si_wbr_create_ops->init)
23746+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
23747+
23748+ return err;
23749+}
23750+
23751+/*
23752+ * returns,
23753+ * plus: processed without an error
23754+ * zero: unprocessed
23755+ */
23756+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
23757+ struct au_opts *opts)
23758+{
23759+ int err;
23760+ struct au_sbinfo *sbinfo;
23761+
dece6358
AM
23762+ SiMustWriteLock(sb);
23763+
1facf9fc 23764+ err = 1; /* handled */
23765+ sbinfo = au_sbi(sb);
23766+ switch (opt->type) {
23767+ case Opt_udba:
23768+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
23769+ sbinfo->si_mntflags |= opt->udba;
23770+ opts->given_udba |= opt->udba;
23771+ break;
23772+
23773+ case Opt_plink:
23774+ au_opt_set(sbinfo->si_mntflags, PLINK);
23775+ break;
23776+ case Opt_noplink:
23777+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 23778+ au_plink_put(sb, /*verbose*/1);
1facf9fc 23779+ au_opt_clr(sbinfo->si_mntflags, PLINK);
23780+ break;
23781+ case Opt_list_plink:
23782+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
23783+ au_plink_list(sb);
23784+ break;
23785+
4a4d8108
AM
23786+ case Opt_dio:
23787+ au_opt_set(sbinfo->si_mntflags, DIO);
23788+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23789+ break;
23790+ case Opt_nodio:
23791+ au_opt_clr(sbinfo->si_mntflags, DIO);
23792+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23793+ break;
23794+
076b876e
AM
23795+ case Opt_fhsm_sec:
23796+ au_fhsm_set(sbinfo, opt->fhsm_second);
23797+ break;
23798+
1facf9fc 23799+ case Opt_diropq_a:
23800+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
23801+ break;
23802+ case Opt_diropq_w:
23803+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
23804+ break;
23805+
23806+ case Opt_warn_perm:
23807+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
23808+ break;
23809+ case Opt_nowarn_perm:
23810+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
23811+ break;
23812+
23813+ case Opt_refrof:
23814+ au_opt_set(sbinfo->si_mntflags, REFROF);
23815+ break;
23816+ case Opt_norefrof:
23817+ au_opt_clr(sbinfo->si_mntflags, REFROF);
23818+ break;
23819+
23820+ case Opt_verbose:
23821+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
23822+ break;
23823+ case Opt_noverbose:
23824+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
23825+ break;
23826+
23827+ case Opt_sum:
23828+ au_opt_set(sbinfo->si_mntflags, SUM);
23829+ break;
23830+ case Opt_wsum:
23831+ au_opt_clr(sbinfo->si_mntflags, SUM);
23832+ au_opt_set(sbinfo->si_mntflags, SUM_W);
23833+ case Opt_nosum:
23834+ au_opt_clr(sbinfo->si_mntflags, SUM);
23835+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
23836+ break;
23837+
23838+ case Opt_wbr_create:
23839+ err = au_opt_wbr_create(sb, &opt->wbr_create);
23840+ break;
23841+ case Opt_wbr_copyup:
23842+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
23843+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
23844+ break;
23845+
23846+ case Opt_dirwh:
23847+ sbinfo->si_dirwh = opt->dirwh;
23848+ break;
23849+
23850+ case Opt_rdcache:
e49829fe
JR
23851+ sbinfo->si_rdcache
23852+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 23853+ break;
23854+ case Opt_rdblk:
23855+ sbinfo->si_rdblk = opt->rdblk;
23856+ break;
dece6358
AM
23857+ case Opt_rdblk_def:
23858+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
23859+ break;
1facf9fc 23860+ case Opt_rdhash:
23861+ sbinfo->si_rdhash = opt->rdhash;
23862+ break;
dece6358
AM
23863+ case Opt_rdhash_def:
23864+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
23865+ break;
23866+
23867+ case Opt_shwh:
23868+ au_opt_set(sbinfo->si_mntflags, SHWH);
23869+ break;
23870+ case Opt_noshwh:
23871+ au_opt_clr(sbinfo->si_mntflags, SHWH);
23872+ break;
1facf9fc 23873+
076b876e
AM
23874+ case Opt_dirperm1:
23875+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
23876+ break;
23877+ case Opt_nodirperm1:
23878+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
23879+ break;
23880+
1facf9fc 23881+ case Opt_trunc_xino:
23882+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
23883+ break;
23884+ case Opt_notrunc_xino:
23885+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
23886+ break;
23887+
23888+ case Opt_trunc_xino_path:
23889+ case Opt_itrunc_xino:
23890+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
23891+ if (!err)
23892+ err = 1;
23893+ break;
23894+
23895+ case Opt_trunc_xib:
23896+ au_fset_opts(opts->flags, TRUNC_XIB);
23897+ break;
23898+ case Opt_notrunc_xib:
23899+ au_fclr_opts(opts->flags, TRUNC_XIB);
23900+ break;
23901+
c1595e42
JR
23902+ case Opt_acl:
23903+ sb->s_flags |= MS_POSIXACL;
23904+ break;
23905+ case Opt_noacl:
23906+ sb->s_flags &= ~MS_POSIXACL;
23907+ break;
23908+
1facf9fc 23909+ default:
23910+ err = 0;
23911+ break;
23912+ }
23913+
23914+ return err;
23915+}
23916+
23917+/*
23918+ * returns tri-state.
23919+ * plus: processed without an error
23920+ * zero: unprocessed
23921+ * minus: error
23922+ */
23923+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
23924+ struct au_opts *opts)
23925+{
23926+ int err, do_refresh;
23927+
23928+ err = 0;
23929+ switch (opt->type) {
23930+ case Opt_append:
23931+ opt->add.bindex = au_sbend(sb) + 1;
23932+ if (opt->add.bindex < 0)
23933+ opt->add.bindex = 0;
23934+ goto add;
23935+ case Opt_prepend:
23936+ opt->add.bindex = 0;
f6b6e03d 23937+ add: /* indented label */
1facf9fc 23938+ case Opt_add:
23939+ err = au_br_add(sb, &opt->add,
23940+ au_ftest_opts(opts->flags, REMOUNT));
23941+ if (!err) {
23942+ err = 1;
027c5e7a 23943+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23944+ }
23945+ break;
23946+
23947+ case Opt_del:
23948+ case Opt_idel:
23949+ err = au_br_del(sb, &opt->del,
23950+ au_ftest_opts(opts->flags, REMOUNT));
23951+ if (!err) {
23952+ err = 1;
23953+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 23954+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23955+ }
23956+ break;
23957+
23958+ case Opt_mod:
23959+ case Opt_imod:
23960+ err = au_br_mod(sb, &opt->mod,
23961+ au_ftest_opts(opts->flags, REMOUNT),
23962+ &do_refresh);
23963+ if (!err) {
23964+ err = 1;
027c5e7a
AM
23965+ if (do_refresh)
23966+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23967+ }
23968+ break;
23969+ }
23970+
23971+ return err;
23972+}
23973+
23974+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
23975+ struct au_opt_xino **opt_xino,
23976+ struct au_opts *opts)
23977+{
23978+ int err;
23979+ aufs_bindex_t bend, bindex;
23980+ struct dentry *root, *parent, *h_root;
23981+
23982+ err = 0;
23983+ switch (opt->type) {
23984+ case Opt_xino:
23985+ err = au_xino_set(sb, &opt->xino,
23986+ !!au_ftest_opts(opts->flags, REMOUNT));
23987+ if (unlikely(err))
23988+ break;
23989+
23990+ *opt_xino = &opt->xino;
23991+ au_xino_brid_set(sb, -1);
23992+
23993+ /* safe d_parent access */
2000de60 23994+ parent = opt->xino.file->f_path.dentry->d_parent;
1facf9fc 23995+ root = sb->s_root;
23996+ bend = au_sbend(sb);
23997+ for (bindex = 0; bindex <= bend; bindex++) {
23998+ h_root = au_h_dptr(root, bindex);
23999+ if (h_root == parent) {
24000+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
24001+ break;
24002+ }
24003+ }
24004+ break;
24005+
24006+ case Opt_noxino:
24007+ au_xino_clr(sb);
24008+ au_xino_brid_set(sb, -1);
24009+ *opt_xino = (void *)-1;
24010+ break;
24011+ }
24012+
24013+ return err;
24014+}
24015+
24016+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
24017+ unsigned int pending)
24018+{
076b876e 24019+ int err, fhsm;
1facf9fc 24020+ aufs_bindex_t bindex, bend;
24021+ unsigned char do_plink, skip, do_free;
24022+ struct au_branch *br;
24023+ struct au_wbr *wbr;
24024+ struct dentry *root;
24025+ struct inode *dir, *h_dir;
24026+ struct au_sbinfo *sbinfo;
24027+ struct au_hinode *hdir;
24028+
dece6358
AM
24029+ SiMustAnyLock(sb);
24030+
1facf9fc 24031+ sbinfo = au_sbi(sb);
24032+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
24033+
dece6358
AM
24034+ if (!(sb_flags & MS_RDONLY)) {
24035+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 24036+ pr_warn("first branch should be rw\n");
dece6358 24037+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 24038+ pr_warn("shwh should be used with ro\n");
dece6358 24039+ }
1facf9fc 24040+
4a4d8108 24041+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 24042+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 24043+ pr_warn("udba=*notify requires xino\n");
1facf9fc 24044+
076b876e
AM
24045+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
24046+ pr_warn("dirperm1 breaks the protection"
24047+ " by the permission bits on the lower branch\n");
24048+
1facf9fc 24049+ err = 0;
076b876e 24050+ fhsm = 0;
1facf9fc 24051+ root = sb->s_root;
4a4d8108 24052+ dir = root->d_inode;
1facf9fc 24053+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
24054+ bend = au_sbend(sb);
24055+ for (bindex = 0; !err && bindex <= bend; bindex++) {
24056+ skip = 0;
24057+ h_dir = au_h_iptr(dir, bindex);
24058+ br = au_sbr(sb, bindex);
1facf9fc 24059+
c1595e42
JR
24060+ if ((br->br_perm & AuBrAttr_ICEX)
24061+ && !h_dir->i_op->listxattr)
24062+ br->br_perm &= ~AuBrAttr_ICEX;
24063+#if 0
24064+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
24065+ && (au_br_sb(br)->s_flags & MS_NOSEC))
24066+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
24067+#endif
24068+
24069+ do_free = 0;
1facf9fc 24070+ wbr = br->br_wbr;
24071+ if (wbr)
24072+ wbr_wh_read_lock(wbr);
24073+
1e00d052 24074+ if (!au_br_writable(br->br_perm)) {
1facf9fc 24075+ do_free = !!wbr;
24076+ skip = (!wbr
24077+ || (!wbr->wbr_whbase
24078+ && !wbr->wbr_plink
24079+ && !wbr->wbr_orph));
1e00d052 24080+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 24081+ /* skip = (!br->br_whbase && !br->br_orph); */
24082+ skip = (!wbr || !wbr->wbr_whbase);
24083+ if (skip && wbr) {
24084+ if (do_plink)
24085+ skip = !!wbr->wbr_plink;
24086+ else
24087+ skip = !wbr->wbr_plink;
24088+ }
1e00d052 24089+ } else {
1facf9fc 24090+ /* skip = (br->br_whbase && br->br_ohph); */
24091+ skip = (wbr && wbr->wbr_whbase);
24092+ if (skip) {
24093+ if (do_plink)
24094+ skip = !!wbr->wbr_plink;
24095+ else
24096+ skip = !wbr->wbr_plink;
24097+ }
1facf9fc 24098+ }
24099+ if (wbr)
24100+ wbr_wh_read_unlock(wbr);
24101+
076b876e
AM
24102+ if (au_br_fhsm(br->br_perm)) {
24103+ fhsm++;
24104+ AuDebugOn(!br->br_fhsm);
24105+ }
24106+
1facf9fc 24107+ if (skip)
24108+ continue;
24109+
24110+ hdir = au_hi(dir, bindex);
4a4d8108 24111+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 24112+ if (wbr)
24113+ wbr_wh_write_lock(wbr);
86dc4139 24114+ err = au_wh_init(br, sb);
1facf9fc 24115+ if (wbr)
24116+ wbr_wh_write_unlock(wbr);
4a4d8108 24117+ au_hn_imtx_unlock(hdir);
1facf9fc 24118+
24119+ if (!err && do_free) {
24120+ kfree(wbr);
24121+ br->br_wbr = NULL;
24122+ }
24123+ }
24124+
c1595e42 24125+ if (fhsm >= 2) {
076b876e 24126+ au_fset_si(sbinfo, FHSM);
c1595e42
JR
24127+ for (bindex = bend; bindex >= 0; bindex--) {
24128+ br = au_sbr(sb, bindex);
24129+ if (au_br_fhsm(br->br_perm)) {
24130+ au_fhsm_set_bottom(sb, bindex);
24131+ break;
24132+ }
24133+ }
24134+ } else {
076b876e 24135+ au_fclr_si(sbinfo, FHSM);
c1595e42
JR
24136+ au_fhsm_set_bottom(sb, -1);
24137+ }
076b876e 24138+
1facf9fc 24139+ return err;
24140+}
24141+
24142+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
24143+{
24144+ int err;
24145+ unsigned int tmp;
027c5e7a 24146+ aufs_bindex_t bindex, bend;
1facf9fc 24147+ struct au_opt *opt;
24148+ struct au_opt_xino *opt_xino, xino;
24149+ struct au_sbinfo *sbinfo;
027c5e7a 24150+ struct au_branch *br;
076b876e 24151+ struct inode *dir;
1facf9fc 24152+
dece6358
AM
24153+ SiMustWriteLock(sb);
24154+
1facf9fc 24155+ err = 0;
24156+ opt_xino = NULL;
24157+ opt = opts->opt;
24158+ while (err >= 0 && opt->type != Opt_tail)
24159+ err = au_opt_simple(sb, opt++, opts);
24160+ if (err > 0)
24161+ err = 0;
24162+ else if (unlikely(err < 0))
24163+ goto out;
24164+
24165+ /* disable xino and udba temporary */
24166+ sbinfo = au_sbi(sb);
24167+ tmp = sbinfo->si_mntflags;
24168+ au_opt_clr(sbinfo->si_mntflags, XINO);
24169+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
24170+
24171+ opt = opts->opt;
24172+ while (err >= 0 && opt->type != Opt_tail)
24173+ err = au_opt_br(sb, opt++, opts);
24174+ if (err > 0)
24175+ err = 0;
24176+ else if (unlikely(err < 0))
24177+ goto out;
24178+
24179+ bend = au_sbend(sb);
24180+ if (unlikely(bend < 0)) {
24181+ err = -EINVAL;
4a4d8108 24182+ pr_err("no branches\n");
1facf9fc 24183+ goto out;
24184+ }
24185+
24186+ if (au_opt_test(tmp, XINO))
24187+ au_opt_set(sbinfo->si_mntflags, XINO);
24188+ opt = opts->opt;
24189+ while (!err && opt->type != Opt_tail)
24190+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
24191+ if (unlikely(err))
24192+ goto out;
24193+
24194+ err = au_opts_verify(sb, sb->s_flags, tmp);
24195+ if (unlikely(err))
24196+ goto out;
24197+
24198+ /* restore xino */
24199+ if (au_opt_test(tmp, XINO) && !opt_xino) {
24200+ xino.file = au_xino_def(sb);
24201+ err = PTR_ERR(xino.file);
24202+ if (IS_ERR(xino.file))
24203+ goto out;
24204+
24205+ err = au_xino_set(sb, &xino, /*remount*/0);
24206+ fput(xino.file);
24207+ if (unlikely(err))
24208+ goto out;
24209+ }
24210+
24211+ /* restore udba */
027c5e7a 24212+ tmp &= AuOptMask_UDBA;
1facf9fc 24213+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
24214+ sbinfo->si_mntflags |= tmp;
24215+ bend = au_sbend(sb);
24216+ for (bindex = 0; bindex <= bend; bindex++) {
24217+ br = au_sbr(sb, bindex);
24218+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
24219+ if (unlikely(err))
24220+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
24221+ bindex, err);
24222+ /* go on even if err */
24223+ }
4a4d8108 24224+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
076b876e 24225+ dir = sb->s_root->d_inode;
4a4d8108 24226+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 24227+ }
24228+
4f0767ce 24229+out:
1facf9fc 24230+ return err;
24231+}
24232+
24233+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
24234+{
24235+ int err, rerr;
24236+ struct inode *dir;
24237+ struct au_opt_xino *opt_xino;
24238+ struct au_opt *opt;
24239+ struct au_sbinfo *sbinfo;
24240+
dece6358
AM
24241+ SiMustWriteLock(sb);
24242+
1facf9fc 24243+ dir = sb->s_root->d_inode;
24244+ sbinfo = au_sbi(sb);
24245+ err = 0;
24246+ opt_xino = NULL;
24247+ opt = opts->opt;
24248+ while (err >= 0 && opt->type != Opt_tail) {
24249+ err = au_opt_simple(sb, opt, opts);
24250+ if (!err)
24251+ err = au_opt_br(sb, opt, opts);
24252+ if (!err)
24253+ err = au_opt_xino(sb, opt, &opt_xino, opts);
24254+ opt++;
24255+ }
24256+ if (err > 0)
24257+ err = 0;
24258+ AuTraceErr(err);
24259+ /* go on even err */
24260+
24261+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
24262+ if (unlikely(rerr && !err))
24263+ err = rerr;
24264+
24265+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
24266+ rerr = au_xib_trunc(sb);
24267+ if (unlikely(rerr && !err))
24268+ err = rerr;
24269+ }
24270+
24271+ /* will be handled by the caller */
027c5e7a 24272+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 24273+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 24274+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24275+
24276+ AuDbg("status 0x%x\n", opts->flags);
24277+ return err;
24278+}
24279+
24280+/* ---------------------------------------------------------------------- */
24281+
24282+unsigned int au_opt_udba(struct super_block *sb)
24283+{
24284+ return au_mntflags(sb) & AuOptMask_UDBA;
24285+}
7f207e10
AM
24286diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
24287--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
2000de60 24288+++ linux/fs/aufs/opts.h 2015-03-27 21:56:35.466795000 +0100
076b876e 24289@@ -0,0 +1,213 @@
1facf9fc 24290+/*
2000de60 24291+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 24292+ *
24293+ * This program, aufs is free software; you can redistribute it and/or modify
24294+ * it under the terms of the GNU General Public License as published by
24295+ * the Free Software Foundation; either version 2 of the License, or
24296+ * (at your option) any later version.
dece6358
AM
24297+ *
24298+ * This program is distributed in the hope that it will be useful,
24299+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24300+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24301+ * GNU General Public License for more details.
24302+ *
24303+ * You should have received a copy of the GNU General Public License
523b37e3 24304+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24305+ */
24306+
24307+/*
24308+ * mount options/flags
24309+ */
24310+
24311+#ifndef __AUFS_OPTS_H__
24312+#define __AUFS_OPTS_H__
24313+
24314+#ifdef __KERNEL__
24315+
dece6358 24316+#include <linux/path.h>
076b876e 24317+#include "branch.h"
1facf9fc 24318+
dece6358
AM
24319+struct file;
24320+struct super_block;
24321+
1facf9fc 24322+/* ---------------------------------------------------------------------- */
24323+
24324+/* mount flags */
24325+#define AuOpt_XINO 1 /* external inode number bitmap
24326+ and translation table */
24327+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
24328+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
24329+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 24330+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
24331+#define AuOpt_SHWH (1 << 5) /* show whiteout */
24332+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
24333+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
24334+ bits */
dece6358
AM
24335+#define AuOpt_REFROF (1 << 8) /* unimplemented */
24336+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
24337+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
24338+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
24339+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
24340+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 24341+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 24342+
4a4d8108
AM
24343+#ifndef CONFIG_AUFS_HNOTIFY
24344+#undef AuOpt_UDBA_HNOTIFY
24345+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 24346+#endif
dece6358
AM
24347+#ifndef CONFIG_AUFS_SHWH
24348+#undef AuOpt_SHWH
24349+#define AuOpt_SHWH 0
24350+#endif
1facf9fc 24351+
24352+#define AuOpt_Def (AuOpt_XINO \
24353+ | AuOpt_UDBA_REVAL \
24354+ | AuOpt_PLINK \
24355+ /* | AuOpt_DIRPERM1 */ \
24356+ | AuOpt_WARN_PERM)
24357+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
24358+ | AuOpt_UDBA_REVAL \
4a4d8108 24359+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 24360+
24361+#define au_opt_test(flags, name) (flags & AuOpt_##name)
24362+#define au_opt_set(flags, name) do { \
24363+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
24364+ ((flags) |= AuOpt_##name); \
24365+} while (0)
24366+#define au_opt_set_udba(flags, name) do { \
24367+ (flags) &= ~AuOptMask_UDBA; \
24368+ ((flags) |= AuOpt_##name); \
24369+} while (0)
7f207e10
AM
24370+#define au_opt_clr(flags, name) do { \
24371+ ((flags) &= ~AuOpt_##name); \
24372+} while (0)
1facf9fc 24373+
e49829fe
JR
24374+static inline unsigned int au_opts_plink(unsigned int mntflags)
24375+{
24376+#ifdef CONFIG_PROC_FS
24377+ return mntflags;
24378+#else
24379+ return mntflags & ~AuOpt_PLINK;
24380+#endif
24381+}
24382+
1facf9fc 24383+/* ---------------------------------------------------------------------- */
24384+
24385+/* policies to select one among multiple writable branches */
24386+enum {
24387+ AuWbrCreate_TDP, /* top down parent */
24388+ AuWbrCreate_RR, /* round robin */
24389+ AuWbrCreate_MFS, /* most free space */
24390+ AuWbrCreate_MFSV, /* mfs with seconds */
24391+ AuWbrCreate_MFSRR, /* mfs then rr */
24392+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
24393+ AuWbrCreate_PMFS, /* parent and mfs */
24394+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
24395+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
24396+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 24397+
24398+ AuWbrCreate_Def = AuWbrCreate_TDP
24399+};
24400+
24401+enum {
24402+ AuWbrCopyup_TDP, /* top down parent */
24403+ AuWbrCopyup_BUP, /* bottom up parent */
24404+ AuWbrCopyup_BU, /* bottom up */
24405+
24406+ AuWbrCopyup_Def = AuWbrCopyup_TDP
24407+};
24408+
24409+/* ---------------------------------------------------------------------- */
24410+
24411+struct au_opt_add {
24412+ aufs_bindex_t bindex;
24413+ char *pathname;
24414+ int perm;
24415+ struct path path;
24416+};
24417+
24418+struct au_opt_del {
24419+ char *pathname;
24420+ struct path h_path;
24421+};
24422+
24423+struct au_opt_mod {
24424+ char *path;
24425+ int perm;
24426+ struct dentry *h_root;
24427+};
24428+
24429+struct au_opt_xino {
24430+ char *path;
24431+ struct file *file;
24432+};
24433+
24434+struct au_opt_xino_itrunc {
24435+ aufs_bindex_t bindex;
24436+};
24437+
24438+struct au_opt_wbr_create {
24439+ int wbr_create;
24440+ int mfs_second;
24441+ unsigned long long mfsrr_watermark;
24442+};
24443+
24444+struct au_opt {
24445+ int type;
24446+ union {
24447+ struct au_opt_xino xino;
24448+ struct au_opt_xino_itrunc xino_itrunc;
24449+ struct au_opt_add add;
24450+ struct au_opt_del del;
24451+ struct au_opt_mod mod;
24452+ int dirwh;
24453+ int rdcache;
24454+ unsigned int rdblk;
24455+ unsigned int rdhash;
24456+ int udba;
24457+ struct au_opt_wbr_create wbr_create;
24458+ int wbr_copyup;
076b876e 24459+ unsigned int fhsm_second;
1facf9fc 24460+ };
24461+};
24462+
24463+/* opts flags */
24464+#define AuOpts_REMOUNT 1
027c5e7a
AM
24465+#define AuOpts_REFRESH (1 << 1)
24466+#define AuOpts_TRUNC_XIB (1 << 2)
24467+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 24468+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
24469+#define au_fset_opts(flags, name) \
24470+ do { (flags) |= AuOpts_##name; } while (0)
24471+#define au_fclr_opts(flags, name) \
24472+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 24473+
24474+struct au_opts {
24475+ struct au_opt *opt;
24476+ int max_opt;
24477+
24478+ unsigned int given_udba;
24479+ unsigned int flags;
24480+ unsigned long sb_flags;
24481+};
24482+
24483+/* ---------------------------------------------------------------------- */
24484+
076b876e 24485+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 24486+const char *au_optstr_udba(int udba);
24487+const char *au_optstr_wbr_copyup(int wbr_copyup);
24488+const char *au_optstr_wbr_create(int wbr_create);
24489+
24490+void au_opts_free(struct au_opts *opts);
24491+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
24492+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
24493+ unsigned int pending);
24494+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
24495+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
24496+
24497+unsigned int au_opt_udba(struct super_block *sb);
24498+
24499+/* ---------------------------------------------------------------------- */
24500+
24501+#endif /* __KERNEL__ */
24502+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
24503diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
24504--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
2000de60 24505+++ linux/fs/aufs/plink.c 2015-03-27 21:56:35.466795000 +0100
523b37e3 24506@@ -0,0 +1,532 @@
1facf9fc 24507+/*
2000de60 24508+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 24509+ *
24510+ * This program, aufs is free software; you can redistribute it and/or modify
24511+ * it under the terms of the GNU General Public License as published by
24512+ * the Free Software Foundation; either version 2 of the License, or
24513+ * (at your option) any later version.
dece6358
AM
24514+ *
24515+ * This program is distributed in the hope that it will be useful,
24516+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24517+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24518+ * GNU General Public License for more details.
24519+ *
24520+ * You should have received a copy of the GNU General Public License
523b37e3 24521+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24522+ */
24523+
24524+/*
24525+ * pseudo-link
24526+ */
24527+
24528+#include "aufs.h"
24529+
24530+/*
e49829fe 24531+ * the pseudo-link maintenance mode.
1facf9fc 24532+ * during a user process maintains the pseudo-links,
24533+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
24534+ *
24535+ * Flags
24536+ * NOPLM:
24537+ * For entry functions which will handle plink, and i_mutex is already held
24538+ * in VFS.
24539+ * They cannot wait and should return an error at once.
24540+ * Callers has to check the error.
24541+ * NOPLMW:
24542+ * For entry functions which will handle plink, but i_mutex is not held
24543+ * in VFS.
24544+ * They can wait the plink maintenance mode to finish.
24545+ *
24546+ * They behave like F_SETLK and F_SETLKW.
24547+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 24548+ */
e49829fe
JR
24549+
24550+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 24551+{
e49829fe
JR
24552+ int err;
24553+ pid_t pid, ppid;
24554+ struct au_sbinfo *sbi;
dece6358
AM
24555+
24556+ SiMustAnyLock(sb);
24557+
e49829fe
JR
24558+ err = 0;
24559+ if (!au_opt_test(au_mntflags(sb), PLINK))
24560+ goto out;
24561+
24562+ sbi = au_sbi(sb);
24563+ pid = sbi->si_plink_maint_pid;
24564+ if (!pid || pid == current->pid)
24565+ goto out;
24566+
24567+ /* todo: it highly depends upon /sbin/mount.aufs */
24568+ rcu_read_lock();
24569+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
24570+ rcu_read_unlock();
24571+ if (pid == ppid)
24572+ goto out;
24573+
24574+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
24575+ /* if there is no i_mutex lock in VFS, we don't need to wait */
24576+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
24577+ while (sbi->si_plink_maint_pid) {
24578+ si_read_unlock(sb);
24579+ /* gave up wake_up_bit() */
24580+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
24581+
24582+ if (au_ftest_lock(flags, FLUSH))
24583+ au_nwt_flush(&sbi->si_nowait);
24584+ si_noflush_read_lock(sb);
24585+ }
24586+ } else if (au_ftest_lock(flags, NOPLM)) {
24587+ AuDbg("ppid %d, pid %d\n", ppid, pid);
24588+ err = -EAGAIN;
24589+ }
24590+
24591+out:
24592+ return err;
4a4d8108
AM
24593+}
24594+
e49829fe 24595+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 24596+{
4a4d8108 24597+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 24598+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 24599+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 24600+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
24601+}
24602+
e49829fe 24603+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
24604+{
24605+ int err;
4a4d8108
AM
24606+ struct au_sbinfo *sbinfo;
24607+
24608+ err = 0;
4a4d8108
AM
24609+ sbinfo = au_sbi(sb);
24610+ /* make sure i am the only one in this fs */
e49829fe
JR
24611+ si_write_lock(sb, AuLock_FLUSH);
24612+ if (au_opt_test(au_mntflags(sb), PLINK)) {
24613+ spin_lock(&sbinfo->si_plink_maint_lock);
24614+ if (!sbinfo->si_plink_maint_pid)
24615+ sbinfo->si_plink_maint_pid = current->pid;
24616+ else
24617+ err = -EBUSY;
24618+ spin_unlock(&sbinfo->si_plink_maint_lock);
24619+ }
4a4d8108
AM
24620+ si_write_unlock(sb);
24621+
24622+ return err;
1facf9fc 24623+}
24624+
24625+/* ---------------------------------------------------------------------- */
24626+
1facf9fc 24627+#ifdef CONFIG_AUFS_DEBUG
24628+void au_plink_list(struct super_block *sb)
24629+{
86dc4139 24630+ int i;
1facf9fc 24631+ struct au_sbinfo *sbinfo;
86dc4139 24632+ struct hlist_head *plink_hlist;
1facf9fc 24633+ struct pseudo_link *plink;
24634+
dece6358
AM
24635+ SiMustAnyLock(sb);
24636+
1facf9fc 24637+ sbinfo = au_sbi(sb);
24638+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24639+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24640+
86dc4139
AM
24641+ for (i = 0; i < AuPlink_NHASH; i++) {
24642+ plink_hlist = &sbinfo->si_plink[i].head;
24643+ rcu_read_lock();
24644+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
24645+ AuDbg("%lu\n", plink->inode->i_ino);
24646+ rcu_read_unlock();
24647+ }
1facf9fc 24648+}
24649+#endif
24650+
24651+/* is the inode pseudo-linked? */
24652+int au_plink_test(struct inode *inode)
24653+{
86dc4139 24654+ int found, i;
1facf9fc 24655+ struct au_sbinfo *sbinfo;
86dc4139 24656+ struct hlist_head *plink_hlist;
1facf9fc 24657+ struct pseudo_link *plink;
24658+
24659+ sbinfo = au_sbi(inode->i_sb);
dece6358 24660+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 24661+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 24662+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 24663+
24664+ found = 0;
86dc4139
AM
24665+ i = au_plink_hash(inode->i_ino);
24666+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 24667+ rcu_read_lock();
86dc4139 24668+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 24669+ if (plink->inode == inode) {
24670+ found = 1;
24671+ break;
24672+ }
4a4d8108 24673+ rcu_read_unlock();
1facf9fc 24674+ return found;
24675+}
24676+
24677+/* ---------------------------------------------------------------------- */
24678+
24679+/*
24680+ * generate a name for plink.
24681+ * the file will be stored under AUFS_WH_PLINKDIR.
24682+ */
24683+/* 20 is max digits length of ulong 64 */
24684+#define PLINK_NAME_LEN ((20 + 1) * 2)
24685+
24686+static int plink_name(char *name, int len, struct inode *inode,
24687+ aufs_bindex_t bindex)
24688+{
24689+ int rlen;
24690+ struct inode *h_inode;
24691+
24692+ h_inode = au_h_iptr(inode, bindex);
24693+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
24694+ return rlen;
24695+}
24696+
7f207e10
AM
24697+struct au_do_plink_lkup_args {
24698+ struct dentry **errp;
24699+ struct qstr *tgtname;
24700+ struct dentry *h_parent;
24701+ struct au_branch *br;
24702+};
24703+
24704+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
24705+ struct dentry *h_parent,
24706+ struct au_branch *br)
24707+{
24708+ struct dentry *h_dentry;
24709+ struct mutex *h_mtx;
24710+
24711+ h_mtx = &h_parent->d_inode->i_mutex;
24712+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 24713+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
24714+ mutex_unlock(h_mtx);
24715+ return h_dentry;
24716+}
24717+
24718+static void au_call_do_plink_lkup(void *args)
24719+{
24720+ struct au_do_plink_lkup_args *a = args;
24721+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
24722+}
24723+
1facf9fc 24724+/* lookup the plink-ed @inode under the branch at @bindex */
24725+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
24726+{
24727+ struct dentry *h_dentry, *h_parent;
24728+ struct au_branch *br;
24729+ struct inode *h_dir;
7f207e10 24730+ int wkq_err;
1facf9fc 24731+ char a[PLINK_NAME_LEN];
0c3ec466 24732+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24733+
e49829fe
JR
24734+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
24735+
1facf9fc 24736+ br = au_sbr(inode->i_sb, bindex);
24737+ h_parent = br->br_wbr->wbr_plink;
24738+ h_dir = h_parent->d_inode;
24739+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24740+
2dfbb274 24741+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
24742+ struct au_do_plink_lkup_args args = {
24743+ .errp = &h_dentry,
24744+ .tgtname = &tgtname,
24745+ .h_parent = h_parent,
24746+ .br = br
24747+ };
24748+
24749+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
24750+ if (unlikely(wkq_err))
24751+ h_dentry = ERR_PTR(wkq_err);
24752+ } else
24753+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
24754+
1facf9fc 24755+ return h_dentry;
24756+}
24757+
24758+/* create a pseudo-link */
24759+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
24760+ struct dentry *h_dentry, struct au_branch *br)
24761+{
24762+ int err;
24763+ struct path h_path = {
86dc4139 24764+ .mnt = au_br_mnt(br)
1facf9fc 24765+ };
523b37e3 24766+ struct inode *h_dir, *delegated;
1facf9fc 24767+
24768+ h_dir = h_parent->d_inode;
7f207e10 24769+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 24770+again:
b4510431 24771+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 24772+ err = PTR_ERR(h_path.dentry);
24773+ if (IS_ERR(h_path.dentry))
24774+ goto out;
24775+
24776+ err = 0;
24777+ /* wh.plink dir is not monitored */
7f207e10 24778+ /* todo: is it really safe? */
1facf9fc 24779+ if (h_path.dentry->d_inode
24780+ && h_path.dentry->d_inode != h_dentry->d_inode) {
523b37e3
AM
24781+ delegated = NULL;
24782+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
24783+ if (unlikely(err == -EWOULDBLOCK)) {
24784+ pr_warn("cannot retry for NFSv4 delegation"
24785+ " for an internal unlink\n");
24786+ iput(delegated);
24787+ }
1facf9fc 24788+ dput(h_path.dentry);
24789+ h_path.dentry = NULL;
24790+ if (!err)
24791+ goto again;
24792+ }
523b37e3
AM
24793+ if (!err && !h_path.dentry->d_inode) {
24794+ delegated = NULL;
24795+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
24796+ if (unlikely(err == -EWOULDBLOCK)) {
24797+ pr_warn("cannot retry for NFSv4 delegation"
24798+ " for an internal link\n");
24799+ iput(delegated);
24800+ }
24801+ }
1facf9fc 24802+ dput(h_path.dentry);
24803+
4f0767ce 24804+out:
7f207e10 24805+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 24806+ return err;
24807+}
24808+
24809+struct do_whplink_args {
24810+ int *errp;
24811+ struct qstr *tgt;
24812+ struct dentry *h_parent;
24813+ struct dentry *h_dentry;
24814+ struct au_branch *br;
24815+};
24816+
24817+static void call_do_whplink(void *args)
24818+{
24819+ struct do_whplink_args *a = args;
24820+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
24821+}
24822+
24823+static int whplink(struct dentry *h_dentry, struct inode *inode,
24824+ aufs_bindex_t bindex, struct au_branch *br)
24825+{
24826+ int err, wkq_err;
24827+ struct au_wbr *wbr;
24828+ struct dentry *h_parent;
24829+ struct inode *h_dir;
24830+ char a[PLINK_NAME_LEN];
0c3ec466 24831+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24832+
24833+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
24834+ h_parent = wbr->wbr_plink;
24835+ h_dir = h_parent->d_inode;
24836+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24837+
24838+ /* always superio. */
2dfbb274 24839+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 24840+ struct do_whplink_args args = {
24841+ .errp = &err,
24842+ .tgt = &tgtname,
24843+ .h_parent = h_parent,
24844+ .h_dentry = h_dentry,
24845+ .br = br
24846+ };
24847+ wkq_err = au_wkq_wait(call_do_whplink, &args);
24848+ if (unlikely(wkq_err))
24849+ err = wkq_err;
24850+ } else
24851+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 24852+
24853+ return err;
24854+}
24855+
24856+/* free a single plink */
24857+static void do_put_plink(struct pseudo_link *plink, int do_del)
24858+{
1facf9fc 24859+ if (do_del)
86dc4139 24860+ hlist_del(&plink->hlist);
4a4d8108
AM
24861+ iput(plink->inode);
24862+ kfree(plink);
24863+}
24864+
24865+static void do_put_plink_rcu(struct rcu_head *rcu)
24866+{
24867+ struct pseudo_link *plink;
24868+
24869+ plink = container_of(rcu, struct pseudo_link, rcu);
24870+ iput(plink->inode);
1facf9fc 24871+ kfree(plink);
24872+}
24873+
24874+/*
24875+ * create a new pseudo-link for @h_dentry on @bindex.
24876+ * the linked inode is held in aufs @inode.
24877+ */
24878+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
24879+ struct dentry *h_dentry)
24880+{
24881+ struct super_block *sb;
24882+ struct au_sbinfo *sbinfo;
86dc4139 24883+ struct hlist_head *plink_hlist;
4a4d8108 24884+ struct pseudo_link *plink, *tmp;
86dc4139
AM
24885+ struct au_sphlhead *sphl;
24886+ int found, err, cnt, i;
1facf9fc 24887+
24888+ sb = inode->i_sb;
24889+ sbinfo = au_sbi(sb);
24890+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24891+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24892+
86dc4139 24893+ found = au_plink_test(inode);
4a4d8108 24894+ if (found)
1facf9fc 24895+ return;
4a4d8108 24896+
86dc4139
AM
24897+ i = au_plink_hash(inode->i_ino);
24898+ sphl = sbinfo->si_plink + i;
24899+ plink_hlist = &sphl->head;
4a4d8108
AM
24900+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
24901+ if (tmp)
24902+ tmp->inode = au_igrab(inode);
24903+ else {
24904+ err = -ENOMEM;
24905+ goto out;
1facf9fc 24906+ }
24907+
86dc4139
AM
24908+ spin_lock(&sphl->spin);
24909+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
24910+ if (plink->inode == inode) {
24911+ found = 1;
24912+ break;
24913+ }
1facf9fc 24914+ }
4a4d8108 24915+ if (!found)
86dc4139
AM
24916+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
24917+ spin_unlock(&sphl->spin);
4a4d8108 24918+ if (!found) {
86dc4139
AM
24919+ cnt = au_sphl_count(sphl);
24920+#define msg "unexpectedly unblanced or too many pseudo-links"
24921+ if (cnt > AUFS_PLINK_WARN)
24922+ AuWarn1(msg ", %d\n", cnt);
24923+#undef msg
1facf9fc 24924+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
24925+ } else {
24926+ do_put_plink(tmp, 0);
24927+ return;
1facf9fc 24928+ }
24929+
4a4d8108 24930+out:
1facf9fc 24931+ if (unlikely(err)) {
0c3ec466 24932+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 24933+ if (tmp) {
86dc4139 24934+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
24935+ call_rcu(&tmp->rcu, do_put_plink_rcu);
24936+ }
1facf9fc 24937+ }
24938+}
24939+
24940+/* free all plinks */
e49829fe 24941+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 24942+{
86dc4139 24943+ int i, warned;
1facf9fc 24944+ struct au_sbinfo *sbinfo;
86dc4139
AM
24945+ struct hlist_head *plink_hlist;
24946+ struct hlist_node *tmp;
24947+ struct pseudo_link *plink;
1facf9fc 24948+
dece6358
AM
24949+ SiMustWriteLock(sb);
24950+
1facf9fc 24951+ sbinfo = au_sbi(sb);
24952+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24953+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24954+
1facf9fc 24955+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
24956+ warned = 0;
24957+ for (i = 0; i < AuPlink_NHASH; i++) {
24958+ plink_hlist = &sbinfo->si_plink[i].head;
24959+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
24960+ pr_warn("pseudo-link is not flushed");
24961+ warned = 1;
24962+ }
24963+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
24964+ do_put_plink(plink, 0);
24965+ INIT_HLIST_HEAD(plink_hlist);
24966+ }
1facf9fc 24967+}
24968+
e49829fe
JR
24969+void au_plink_clean(struct super_block *sb, int verbose)
24970+{
24971+ struct dentry *root;
24972+
24973+ root = sb->s_root;
24974+ aufs_write_lock(root);
24975+ if (au_opt_test(au_mntflags(sb), PLINK))
24976+ au_plink_put(sb, verbose);
24977+ aufs_write_unlock(root);
24978+}
24979+
86dc4139
AM
24980+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
24981+{
24982+ int do_put;
24983+ aufs_bindex_t bstart, bend, bindex;
24984+
24985+ do_put = 0;
24986+ bstart = au_ibstart(inode);
24987+ bend = au_ibend(inode);
24988+ if (bstart >= 0) {
24989+ for (bindex = bstart; bindex <= bend; bindex++) {
24990+ if (!au_h_iptr(inode, bindex)
24991+ || au_ii_br_id(inode, bindex) != br_id)
24992+ continue;
24993+ au_set_h_iptr(inode, bindex, NULL, 0);
24994+ do_put = 1;
24995+ break;
24996+ }
24997+ if (do_put)
24998+ for (bindex = bstart; bindex <= bend; bindex++)
24999+ if (au_h_iptr(inode, bindex)) {
25000+ do_put = 0;
25001+ break;
25002+ }
25003+ } else
25004+ do_put = 1;
25005+
25006+ return do_put;
25007+}
25008+
1facf9fc 25009+/* free the plinks on a branch specified by @br_id */
25010+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
25011+{
25012+ struct au_sbinfo *sbinfo;
86dc4139
AM
25013+ struct hlist_head *plink_hlist;
25014+ struct hlist_node *tmp;
25015+ struct pseudo_link *plink;
1facf9fc 25016+ struct inode *inode;
86dc4139 25017+ int i, do_put;
1facf9fc 25018+
dece6358
AM
25019+ SiMustWriteLock(sb);
25020+
1facf9fc 25021+ sbinfo = au_sbi(sb);
25022+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25023+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25024+
1facf9fc 25025+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
25026+ for (i = 0; i < AuPlink_NHASH; i++) {
25027+ plink_hlist = &sbinfo->si_plink[i].head;
25028+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
25029+ inode = au_igrab(plink->inode);
25030+ ii_write_lock_child(inode);
25031+ do_put = au_plink_do_half_refresh(inode, br_id);
dece6358
AM
25032+ if (do_put)
25033+ do_put_plink(plink, 1);
86dc4139
AM
25034+ ii_write_unlock(inode);
25035+ iput(inode);
dece6358 25036+ }
dece6358
AM
25037+ }
25038+}
7f207e10
AM
25039diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
25040--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
2000de60 25041+++ linux/fs/aufs/poll.c 2015-03-27 21:56:35.466795000 +0100
523b37e3 25042@@ -0,0 +1,55 @@
dece6358 25043+/*
2000de60 25044+ * Copyright (C) 2005-2015 Junjiro R. Okajima
dece6358
AM
25045+ *
25046+ * This program, aufs is free software; you can redistribute it and/or modify
25047+ * it under the terms of the GNU General Public License as published by
25048+ * the Free Software Foundation; either version 2 of the License, or
25049+ * (at your option) any later version.
25050+ *
25051+ * This program is distributed in the hope that it will be useful,
25052+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25053+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25054+ * GNU General Public License for more details.
25055+ *
25056+ * You should have received a copy of the GNU General Public License
523b37e3 25057+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
25058+ */
25059+
1308ab2a 25060+/*
25061+ * poll operation
25062+ * There is only one filesystem which implements ->poll operation, currently.
25063+ */
25064+
25065+#include "aufs.h"
25066+
25067+unsigned int aufs_poll(struct file *file, poll_table *wait)
25068+{
25069+ unsigned int mask;
25070+ int err;
25071+ struct file *h_file;
25072+ struct dentry *dentry;
25073+ struct super_block *sb;
25074+
25075+ /* We should pretend an error happened. */
25076+ mask = POLLERR /* | POLLIN | POLLOUT */;
2000de60 25077+ dentry = file->f_path.dentry;
1308ab2a 25078+ sb = dentry->d_sb;
e49829fe 25079+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 25080+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
25081+ if (unlikely(err))
25082+ goto out;
25083+
25084+ /* it is not an error if h_file has no operation */
25085+ mask = DEFAULT_POLLMASK;
4a4d8108 25086+ h_file = au_hf_top(file);
523b37e3 25087+ if (h_file->f_op->poll)
1308ab2a 25088+ mask = h_file->f_op->poll(h_file, wait);
25089+
25090+ di_read_unlock(dentry, AuLock_IR);
25091+ fi_read_unlock(file);
25092+
4f0767ce 25093+out:
1308ab2a 25094+ si_read_unlock(sb);
25095+ AuTraceErr((int)mask);
25096+ return mask;
25097+}
c1595e42
JR
25098diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
25099--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
2000de60 25100+++ linux/fs/aufs/posix_acl.c 2015-03-27 21:56:35.466795000 +0100
c1595e42
JR
25101@@ -0,0 +1,99 @@
25102+/*
2000de60 25103+ * Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
25104+ *
25105+ * This program, aufs is free software; you can redistribute it and/or modify
25106+ * it under the terms of the GNU General Public License as published by
25107+ * the Free Software Foundation; either version 2 of the License, or
25108+ * (at your option) any later version.
25109+ *
25110+ * This program is distributed in the hope that it will be useful,
25111+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25112+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25113+ * GNU General Public License for more details.
25114+ *
25115+ * You should have received a copy of the GNU General Public License
25116+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25117+ */
25118+
25119+/*
25120+ * posix acl operations
25121+ */
25122+
25123+#include <linux/fs.h>
25124+#include <linux/posix_acl.h>
25125+#include "aufs.h"
25126+
25127+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
25128+{
25129+ struct posix_acl *acl;
25130+ int err;
25131+ aufs_bindex_t bindex;
25132+ struct inode *h_inode;
25133+ struct super_block *sb;
25134+
25135+ acl = NULL;
25136+ sb = inode->i_sb;
25137+ si_read_lock(sb, AuLock_FLUSH);
25138+ ii_read_lock_child(inode);
25139+ if (!(sb->s_flags & MS_POSIXACL))
25140+ goto out;
25141+
25142+ bindex = au_ibstart(inode);
25143+ h_inode = au_h_iptr(inode, bindex);
25144+ if (unlikely(!h_inode
25145+ || ((h_inode->i_mode & S_IFMT)
25146+ != (inode->i_mode & S_IFMT)))) {
25147+ err = au_busy_or_stale();
25148+ acl = ERR_PTR(err);
25149+ goto out;
25150+ }
25151+
25152+ /* always topmost only */
25153+ acl = get_acl(h_inode, type);
25154+
25155+out:
25156+ ii_read_unlock(inode);
25157+ si_read_unlock(sb);
25158+
25159+ AuTraceErrPtr(acl);
25160+ return acl;
25161+}
25162+
25163+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
25164+{
25165+ int err;
25166+ ssize_t ssz;
25167+ struct dentry *dentry;
25168+ struct au_srxattr arg = {
25169+ .type = AU_ACL_SET,
25170+ .u.acl_set = {
25171+ .acl = acl,
25172+ .type = type
25173+ },
25174+ };
25175+
25176+ mutex_lock(&inode->i_mutex);
25177+ if (inode->i_ino == AUFS_ROOT_INO)
25178+ dentry = dget(inode->i_sb->s_root);
25179+ else {
25180+ dentry = d_find_alias(inode);
25181+ if (!dentry)
25182+ dentry = d_find_any_alias(inode);
25183+ if (!dentry) {
25184+ pr_warn("cannot handle this inode, "
25185+ "please report to aufs-users ML\n");
25186+ err = -ENOENT;
25187+ goto out;
25188+ }
25189+ }
25190+
25191+ ssz = au_srxattr(dentry, &arg);
25192+ dput(dentry);
25193+ err = ssz;
25194+ if (ssz >= 0)
25195+ err = 0;
25196+
25197+out:
25198+ mutex_unlock(&inode->i_mutex);
25199+ return err;
25200+}
7f207e10
AM
25201diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
25202--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
2000de60 25203+++ linux/fs/aufs/procfs.c 2015-03-27 21:56:35.466795000 +0100
523b37e3 25204@@ -0,0 +1,169 @@
e49829fe 25205+/*
2000de60 25206+ * Copyright (C) 2010-2015 Junjiro R. Okajima
e49829fe
JR
25207+ *
25208+ * This program, aufs is free software; you can redistribute it and/or modify
25209+ * it under the terms of the GNU General Public License as published by
25210+ * the Free Software Foundation; either version 2 of the License, or
25211+ * (at your option) any later version.
25212+ *
25213+ * This program is distributed in the hope that it will be useful,
25214+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25215+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25216+ * GNU General Public License for more details.
25217+ *
25218+ * You should have received a copy of the GNU General Public License
523b37e3 25219+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
25220+ */
25221+
25222+/*
25223+ * procfs interfaces
25224+ */
25225+
25226+#include <linux/proc_fs.h>
25227+#include "aufs.h"
25228+
25229+static int au_procfs_plm_release(struct inode *inode, struct file *file)
25230+{
25231+ struct au_sbinfo *sbinfo;
25232+
25233+ sbinfo = file->private_data;
25234+ if (sbinfo) {
25235+ au_plink_maint_leave(sbinfo);
25236+ kobject_put(&sbinfo->si_kobj);
25237+ }
25238+
25239+ return 0;
25240+}
25241+
25242+static void au_procfs_plm_write_clean(struct file *file)
25243+{
25244+ struct au_sbinfo *sbinfo;
25245+
25246+ sbinfo = file->private_data;
25247+ if (sbinfo)
25248+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
25249+}
25250+
25251+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
25252+{
25253+ int err;
25254+ struct super_block *sb;
25255+ struct au_sbinfo *sbinfo;
25256+
25257+ err = -EBUSY;
25258+ if (unlikely(file->private_data))
25259+ goto out;
25260+
25261+ sb = NULL;
53392da6 25262+ /* don't use au_sbilist_lock() here */
e49829fe
JR
25263+ spin_lock(&au_sbilist.spin);
25264+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
25265+ if (id == sysaufs_si_id(sbinfo)) {
25266+ kobject_get(&sbinfo->si_kobj);
25267+ sb = sbinfo->si_sb;
25268+ break;
25269+ }
25270+ spin_unlock(&au_sbilist.spin);
25271+
25272+ err = -EINVAL;
25273+ if (unlikely(!sb))
25274+ goto out;
25275+
25276+ err = au_plink_maint_enter(sb);
25277+ if (!err)
25278+ /* keep kobject_get() */
25279+ file->private_data = sbinfo;
25280+ else
25281+ kobject_put(&sbinfo->si_kobj);
25282+out:
25283+ return err;
25284+}
25285+
25286+/*
25287+ * Accept a valid "si=xxxx" only.
25288+ * Once it is accepted successfully, accept "clean" too.
25289+ */
25290+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
25291+ size_t count, loff_t *ppos)
25292+{
25293+ ssize_t err;
25294+ unsigned long id;
25295+ /* last newline is allowed */
25296+ char buf[3 + sizeof(unsigned long) * 2 + 1];
25297+
25298+ err = -EACCES;
25299+ if (unlikely(!capable(CAP_SYS_ADMIN)))
25300+ goto out;
25301+
25302+ err = -EINVAL;
25303+ if (unlikely(count > sizeof(buf)))
25304+ goto out;
25305+
25306+ err = copy_from_user(buf, ubuf, count);
25307+ if (unlikely(err)) {
25308+ err = -EFAULT;
25309+ goto out;
25310+ }
25311+ buf[count] = 0;
25312+
25313+ err = -EINVAL;
25314+ if (!strcmp("clean", buf)) {
25315+ au_procfs_plm_write_clean(file);
25316+ goto out_success;
25317+ } else if (unlikely(strncmp("si=", buf, 3)))
25318+ goto out;
25319+
9dbd164d 25320+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
25321+ if (unlikely(err))
25322+ goto out;
25323+
25324+ err = au_procfs_plm_write_si(file, id);
25325+ if (unlikely(err))
25326+ goto out;
25327+
25328+out_success:
25329+ err = count; /* success */
25330+out:
25331+ return err;
25332+}
25333+
25334+static const struct file_operations au_procfs_plm_fop = {
25335+ .write = au_procfs_plm_write,
25336+ .release = au_procfs_plm_release,
25337+ .owner = THIS_MODULE
25338+};
25339+
25340+/* ---------------------------------------------------------------------- */
25341+
25342+static struct proc_dir_entry *au_procfs_dir;
25343+
25344+void au_procfs_fin(void)
25345+{
25346+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
25347+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
25348+}
25349+
25350+int __init au_procfs_init(void)
25351+{
25352+ int err;
25353+ struct proc_dir_entry *entry;
25354+
25355+ err = -ENOMEM;
25356+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
25357+ if (unlikely(!au_procfs_dir))
25358+ goto out;
25359+
25360+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
25361+ au_procfs_dir, &au_procfs_plm_fop);
25362+ if (unlikely(!entry))
25363+ goto out_dir;
25364+
25365+ err = 0;
25366+ goto out; /* success */
25367+
25368+
25369+out_dir:
25370+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
25371+out:
25372+ return err;
25373+}
7f207e10
AM
25374diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
25375--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
2000de60 25376+++ linux/fs/aufs/rdu.c 2015-03-27 21:56:35.466795000 +0100
523b37e3 25377@@ -0,0 +1,388 @@
1308ab2a 25378+/*
2000de60 25379+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1308ab2a 25380+ *
25381+ * This program, aufs is free software; you can redistribute it and/or modify
25382+ * it under the terms of the GNU General Public License as published by
25383+ * the Free Software Foundation; either version 2 of the License, or
25384+ * (at your option) any later version.
25385+ *
25386+ * This program is distributed in the hope that it will be useful,
25387+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25388+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25389+ * GNU General Public License for more details.
25390+ *
25391+ * You should have received a copy of the GNU General Public License
523b37e3 25392+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 25393+ */
25394+
25395+/*
25396+ * readdir in userspace.
25397+ */
25398+
b752ccd1 25399+#include <linux/compat.h>
4a4d8108 25400+#include <linux/fs_stack.h>
1308ab2a 25401+#include <linux/security.h>
1308ab2a 25402+#include "aufs.h"
25403+
25404+/* bits for struct aufs_rdu.flags */
25405+#define AuRdu_CALLED 1
25406+#define AuRdu_CONT (1 << 1)
25407+#define AuRdu_FULL (1 << 2)
25408+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
25409+#define au_fset_rdu(flags, name) \
25410+ do { (flags) |= AuRdu_##name; } while (0)
25411+#define au_fclr_rdu(flags, name) \
25412+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 25413+
25414+struct au_rdu_arg {
392086de 25415+ struct dir_context ctx;
1308ab2a 25416+ struct aufs_rdu *rdu;
25417+ union au_rdu_ent_ul ent;
25418+ unsigned long end;
25419+
25420+ struct super_block *sb;
25421+ int err;
25422+};
25423+
392086de 25424+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 25425+ loff_t offset, u64 h_ino, unsigned int d_type)
25426+{
25427+ int err, len;
392086de 25428+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 25429+ struct aufs_rdu *rdu = arg->rdu;
25430+ struct au_rdu_ent ent;
25431+
25432+ err = 0;
25433+ arg->err = 0;
25434+ au_fset_rdu(rdu->cookie.flags, CALLED);
25435+ len = au_rdu_len(nlen);
25436+ if (arg->ent.ul + len < arg->end) {
25437+ ent.ino = h_ino;
25438+ ent.bindex = rdu->cookie.bindex;
25439+ ent.type = d_type;
25440+ ent.nlen = nlen;
4a4d8108
AM
25441+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
25442+ ent.type = DT_UNKNOWN;
1308ab2a 25443+
9dbd164d 25444+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25445+ err = -EFAULT;
25446+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
25447+ goto out;
25448+ if (copy_to_user(arg->ent.e->name, name, nlen))
25449+ goto out;
25450+ /* the terminating NULL */
25451+ if (__put_user(0, arg->ent.e->name + nlen))
25452+ goto out;
25453+ err = 0;
25454+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
25455+ arg->ent.ul += len;
25456+ rdu->rent++;
25457+ } else {
25458+ err = -EFAULT;
25459+ au_fset_rdu(rdu->cookie.flags, FULL);
25460+ rdu->full = 1;
25461+ rdu->tail = arg->ent;
25462+ }
25463+
4f0767ce 25464+out:
1308ab2a 25465+ /* AuTraceErr(err); */
25466+ return err;
25467+}
25468+
25469+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
25470+{
25471+ int err;
25472+ loff_t offset;
25473+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
25474+
92d182d2 25475+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 25476+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
25477+ err = offset;
25478+ if (unlikely(offset != cookie->h_pos))
25479+ goto out;
25480+
25481+ err = 0;
25482+ do {
25483+ arg->err = 0;
25484+ au_fclr_rdu(cookie->flags, CALLED);
25485+ /* smp_mb(); */
392086de 25486+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 25487+ if (err >= 0)
25488+ err = arg->err;
25489+ } while (!err
25490+ && au_ftest_rdu(cookie->flags, CALLED)
25491+ && !au_ftest_rdu(cookie->flags, FULL));
25492+ cookie->h_pos = h_file->f_pos;
25493+
4f0767ce 25494+out:
1308ab2a 25495+ AuTraceErr(err);
25496+ return err;
25497+}
25498+
25499+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
25500+{
25501+ int err;
25502+ aufs_bindex_t bend;
392086de
AM
25503+ struct au_rdu_arg arg = {
25504+ .ctx = {
2000de60 25505+ .actor = au_rdu_fill
392086de
AM
25506+ }
25507+ };
1308ab2a 25508+ struct dentry *dentry;
25509+ struct inode *inode;
25510+ struct file *h_file;
25511+ struct au_rdu_cookie *cookie = &rdu->cookie;
25512+
25513+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
25514+ if (unlikely(err)) {
25515+ err = -EFAULT;
25516+ AuTraceErr(err);
25517+ goto out;
25518+ }
25519+ rdu->rent = 0;
25520+ rdu->tail = rdu->ent;
25521+ rdu->full = 0;
25522+ arg.rdu = rdu;
25523+ arg.ent = rdu->ent;
25524+ arg.end = arg.ent.ul;
25525+ arg.end += rdu->sz;
25526+
25527+ err = -ENOTDIR;
523b37e3 25528+ if (unlikely(!file->f_op->iterate))
1308ab2a 25529+ goto out;
25530+
25531+ err = security_file_permission(file, MAY_READ);
25532+ AuTraceErr(err);
25533+ if (unlikely(err))
25534+ goto out;
25535+
2000de60 25536+ dentry = file->f_path.dentry;
1308ab2a 25537+ inode = dentry->d_inode;
25538+#if 1
25539+ mutex_lock(&inode->i_mutex);
25540+#else
25541+ err = mutex_lock_killable(&inode->i_mutex);
25542+ AuTraceErr(err);
25543+ if (unlikely(err))
25544+ goto out;
25545+#endif
1308ab2a 25546+
25547+ arg.sb = inode->i_sb;
e49829fe
JR
25548+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
25549+ if (unlikely(err))
25550+ goto out_mtx;
027c5e7a
AM
25551+ err = au_alive_dir(dentry);
25552+ if (unlikely(err))
25553+ goto out_si;
e49829fe 25554+ /* todo: reval? */
1308ab2a 25555+ fi_read_lock(file);
25556+
25557+ err = -EAGAIN;
25558+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
25559+ && cookie->generation != au_figen(file)))
25560+ goto out_unlock;
25561+
25562+ err = 0;
25563+ if (!rdu->blk) {
25564+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
25565+ if (!rdu->blk)
25566+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
25567+ }
25568+ bend = au_fbstart(file);
25569+ if (cookie->bindex < bend)
25570+ cookie->bindex = bend;
4a4d8108 25571+ bend = au_fbend_dir(file);
1308ab2a 25572+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
25573+ for (; !err && cookie->bindex <= bend;
25574+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 25575+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 25576+ if (!h_file)
25577+ continue;
25578+
25579+ au_fclr_rdu(cookie->flags, FULL);
25580+ err = au_rdu_do(h_file, &arg);
25581+ AuTraceErr(err);
25582+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
25583+ break;
25584+ }
25585+ AuDbg("rent %llu\n", rdu->rent);
25586+
25587+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
25588+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
25589+ au_fset_rdu(cookie->flags, CONT);
25590+ cookie->generation = au_figen(file);
25591+ }
25592+
25593+ ii_read_lock_child(inode);
25594+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
25595+ ii_read_unlock(inode);
25596+
4f0767ce 25597+out_unlock:
1308ab2a 25598+ fi_read_unlock(file);
027c5e7a 25599+out_si:
1308ab2a 25600+ si_read_unlock(arg.sb);
4f0767ce 25601+out_mtx:
1308ab2a 25602+ mutex_unlock(&inode->i_mutex);
4f0767ce 25603+out:
1308ab2a 25604+ AuTraceErr(err);
25605+ return err;
25606+}
25607+
25608+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
25609+{
25610+ int err;
25611+ ino_t ino;
25612+ unsigned long long nent;
25613+ union au_rdu_ent_ul *u;
25614+ struct au_rdu_ent ent;
25615+ struct super_block *sb;
25616+
25617+ err = 0;
25618+ nent = rdu->nent;
25619+ u = &rdu->ent;
2000de60 25620+ sb = file->f_path.dentry->d_sb;
1308ab2a 25621+ si_read_lock(sb, AuLock_FLUSH);
25622+ while (nent-- > 0) {
9dbd164d 25623+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25624+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
25625+ if (!err)
25626+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 25627+ if (unlikely(err)) {
25628+ err = -EFAULT;
25629+ AuTraceErr(err);
25630+ break;
25631+ }
25632+
25633+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
25634+ if (!ent.wh)
25635+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
25636+ else
25637+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
25638+ &ino);
25639+ if (unlikely(err)) {
25640+ AuTraceErr(err);
25641+ break;
25642+ }
25643+
25644+ err = __put_user(ino, &u->e->ino);
25645+ if (unlikely(err)) {
25646+ err = -EFAULT;
25647+ AuTraceErr(err);
25648+ break;
25649+ }
25650+ u->ul += au_rdu_len(ent.nlen);
25651+ }
25652+ si_read_unlock(sb);
25653+
25654+ return err;
25655+}
25656+
25657+/* ---------------------------------------------------------------------- */
25658+
25659+static int au_rdu_verify(struct aufs_rdu *rdu)
25660+{
b752ccd1 25661+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 25662+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 25663+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 25664+ rdu->blk,
25665+ rdu->rent, rdu->shwh, rdu->full,
25666+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
25667+ rdu->cookie.generation);
dece6358 25668+
b752ccd1 25669+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 25670+ return 0;
dece6358 25671+
b752ccd1
AM
25672+ AuDbg("%u:%u\n",
25673+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 25674+ return -EINVAL;
25675+}
25676+
25677+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 25678+{
1308ab2a 25679+ long err, e;
25680+ struct aufs_rdu rdu;
25681+ void __user *p = (void __user *)arg;
dece6358 25682+
1308ab2a 25683+ err = copy_from_user(&rdu, p, sizeof(rdu));
25684+ if (unlikely(err)) {
25685+ err = -EFAULT;
25686+ AuTraceErr(err);
25687+ goto out;
25688+ }
25689+ err = au_rdu_verify(&rdu);
dece6358
AM
25690+ if (unlikely(err))
25691+ goto out;
25692+
1308ab2a 25693+ switch (cmd) {
25694+ case AUFS_CTL_RDU:
25695+ err = au_rdu(file, &rdu);
25696+ if (unlikely(err))
25697+ break;
dece6358 25698+
1308ab2a 25699+ e = copy_to_user(p, &rdu, sizeof(rdu));
25700+ if (unlikely(e)) {
25701+ err = -EFAULT;
25702+ AuTraceErr(err);
25703+ }
25704+ break;
25705+ case AUFS_CTL_RDU_INO:
25706+ err = au_rdu_ino(file, &rdu);
25707+ break;
25708+
25709+ default:
4a4d8108 25710+ /* err = -ENOTTY; */
1308ab2a 25711+ err = -EINVAL;
25712+ }
dece6358 25713+
4f0767ce 25714+out:
1308ab2a 25715+ AuTraceErr(err);
25716+ return err;
1facf9fc 25717+}
b752ccd1
AM
25718+
25719+#ifdef CONFIG_COMPAT
25720+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
25721+{
25722+ long err, e;
25723+ struct aufs_rdu rdu;
25724+ void __user *p = compat_ptr(arg);
25725+
25726+ /* todo: get_user()? */
25727+ err = copy_from_user(&rdu, p, sizeof(rdu));
25728+ if (unlikely(err)) {
25729+ err = -EFAULT;
25730+ AuTraceErr(err);
25731+ goto out;
25732+ }
25733+ rdu.ent.e = compat_ptr(rdu.ent.ul);
25734+ err = au_rdu_verify(&rdu);
25735+ if (unlikely(err))
25736+ goto out;
25737+
25738+ switch (cmd) {
25739+ case AUFS_CTL_RDU:
25740+ err = au_rdu(file, &rdu);
25741+ if (unlikely(err))
25742+ break;
25743+
25744+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
25745+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
25746+ e = copy_to_user(p, &rdu, sizeof(rdu));
25747+ if (unlikely(e)) {
25748+ err = -EFAULT;
25749+ AuTraceErr(err);
25750+ }
25751+ break;
25752+ case AUFS_CTL_RDU_INO:
25753+ err = au_rdu_ino(file, &rdu);
25754+ break;
25755+
25756+ default:
25757+ /* err = -ENOTTY; */
25758+ err = -EINVAL;
25759+ }
25760+
4f0767ce 25761+out:
b752ccd1
AM
25762+ AuTraceErr(err);
25763+ return err;
25764+}
25765+#endif
7f207e10
AM
25766diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
25767--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
2000de60 25768+++ linux/fs/aufs/rwsem.h 2015-03-27 21:56:35.466795000 +0100
076b876e 25769@@ -0,0 +1,191 @@
1facf9fc 25770+/*
2000de60 25771+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 25772+ *
25773+ * This program, aufs is free software; you can redistribute it and/or modify
25774+ * it under the terms of the GNU General Public License as published by
25775+ * the Free Software Foundation; either version 2 of the License, or
25776+ * (at your option) any later version.
dece6358
AM
25777+ *
25778+ * This program is distributed in the hope that it will be useful,
25779+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25780+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25781+ * GNU General Public License for more details.
25782+ *
25783+ * You should have received a copy of the GNU General Public License
523b37e3 25784+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25785+ */
25786+
25787+/*
25788+ * simple read-write semaphore wrappers
25789+ */
25790+
25791+#ifndef __AUFS_RWSEM_H__
25792+#define __AUFS_RWSEM_H__
25793+
25794+#ifdef __KERNEL__
25795+
4a4d8108 25796+#include "debug.h"
dece6358
AM
25797+
25798+struct au_rwsem {
25799+ struct rw_semaphore rwsem;
25800+#ifdef CONFIG_AUFS_DEBUG
25801+ /* just for debugging, not almighty counter */
25802+ atomic_t rcnt, wcnt;
25803+#endif
25804+};
25805+
25806+#ifdef CONFIG_AUFS_DEBUG
25807+#define AuDbgCntInit(rw) do { \
25808+ atomic_set(&(rw)->rcnt, 0); \
25809+ atomic_set(&(rw)->wcnt, 0); \
25810+ smp_mb(); /* atomic set */ \
25811+} while (0)
25812+
e49829fe 25813+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 25814+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 25815+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
25816+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
25817+#else
25818+#define AuDbgCntInit(rw) do {} while (0)
25819+#define AuDbgRcntInc(rw) do {} while (0)
25820+#define AuDbgRcntDec(rw) do {} while (0)
25821+#define AuDbgWcntInc(rw) do {} while (0)
25822+#define AuDbgWcntDec(rw) do {} while (0)
25823+#endif /* CONFIG_AUFS_DEBUG */
25824+
25825+/* to debug easier, do not make them inlined functions */
25826+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
25827+/* rwsem_is_locked() is unusable */
25828+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
25829+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
25830+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
25831+ && atomic_read(&(rw)->wcnt) <= 0)
25832+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
25833+ || atomic_read(&(rw)->wcnt))
25834+
e49829fe
JR
25835+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
25836+
dece6358
AM
25837+static inline void au_rw_init(struct au_rwsem *rw)
25838+{
25839+ AuDbgCntInit(rw);
25840+ init_rwsem(&rw->rwsem);
25841+}
25842+
25843+static inline void au_rw_init_wlock(struct au_rwsem *rw)
25844+{
25845+ au_rw_init(rw);
25846+ down_write(&rw->rwsem);
25847+ AuDbgWcntInc(rw);
25848+}
25849+
25850+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
25851+ unsigned int lsc)
25852+{
25853+ au_rw_init(rw);
25854+ down_write_nested(&rw->rwsem, lsc);
25855+ AuDbgWcntInc(rw);
25856+}
25857+
25858+static inline void au_rw_read_lock(struct au_rwsem *rw)
25859+{
25860+ down_read(&rw->rwsem);
25861+ AuDbgRcntInc(rw);
25862+}
25863+
25864+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
25865+{
25866+ down_read_nested(&rw->rwsem, lsc);
25867+ AuDbgRcntInc(rw);
25868+}
25869+
25870+static inline void au_rw_read_unlock(struct au_rwsem *rw)
25871+{
25872+ AuRwMustReadLock(rw);
25873+ AuDbgRcntDec(rw);
25874+ up_read(&rw->rwsem);
25875+}
25876+
25877+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
25878+{
25879+ AuRwMustWriteLock(rw);
25880+ AuDbgRcntInc(rw);
25881+ AuDbgWcntDec(rw);
25882+ downgrade_write(&rw->rwsem);
25883+}
25884+
25885+static inline void au_rw_write_lock(struct au_rwsem *rw)
25886+{
25887+ down_write(&rw->rwsem);
25888+ AuDbgWcntInc(rw);
25889+}
25890+
25891+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
25892+ unsigned int lsc)
25893+{
25894+ down_write_nested(&rw->rwsem, lsc);
25895+ AuDbgWcntInc(rw);
25896+}
1facf9fc 25897+
dece6358
AM
25898+static inline void au_rw_write_unlock(struct au_rwsem *rw)
25899+{
25900+ AuRwMustWriteLock(rw);
25901+ AuDbgWcntDec(rw);
25902+ up_write(&rw->rwsem);
25903+}
25904+
25905+/* why is not _nested version defined */
25906+static inline int au_rw_read_trylock(struct au_rwsem *rw)
25907+{
076b876e
AM
25908+ int ret;
25909+
25910+ ret = down_read_trylock(&rw->rwsem);
dece6358
AM
25911+ if (ret)
25912+ AuDbgRcntInc(rw);
25913+ return ret;
25914+}
25915+
25916+static inline int au_rw_write_trylock(struct au_rwsem *rw)
25917+{
076b876e
AM
25918+ int ret;
25919+
25920+ ret = down_write_trylock(&rw->rwsem);
dece6358
AM
25921+ if (ret)
25922+ AuDbgWcntInc(rw);
25923+ return ret;
25924+}
25925+
25926+#undef AuDbgCntInit
25927+#undef AuDbgRcntInc
25928+#undef AuDbgRcntDec
25929+#undef AuDbgWcntInc
25930+#undef AuDbgWcntDec
1facf9fc 25931+
25932+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
25933+static inline void prefix##_read_lock(param) \
dece6358 25934+{ au_rw_read_lock(rwsem); } \
1facf9fc 25935+static inline void prefix##_write_lock(param) \
dece6358 25936+{ au_rw_write_lock(rwsem); } \
1facf9fc 25937+static inline int prefix##_read_trylock(param) \
dece6358 25938+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 25939+static inline int prefix##_write_trylock(param) \
dece6358 25940+{ return au_rw_write_trylock(rwsem); }
1facf9fc 25941+/* why is not _nested version defined */
25942+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 25943+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 25944+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 25945+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 25946+
25947+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
25948+static inline void prefix##_read_unlock(param) \
dece6358 25949+{ au_rw_read_unlock(rwsem); } \
1facf9fc 25950+static inline void prefix##_write_unlock(param) \
dece6358 25951+{ au_rw_write_unlock(rwsem); } \
1facf9fc 25952+static inline void prefix##_downgrade_lock(param) \
dece6358 25953+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 25954+
25955+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
25956+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
25957+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
25958+
25959+#endif /* __KERNEL__ */
25960+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
25961diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
25962--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
2000de60 25963+++ linux/fs/aufs/sbinfo.c 2015-03-27 21:56:35.466795000 +0100
076b876e 25964@@ -0,0 +1,353 @@
1facf9fc 25965+/*
2000de60 25966+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 25967+ *
25968+ * This program, aufs is free software; you can redistribute it and/or modify
25969+ * it under the terms of the GNU General Public License as published by
25970+ * the Free Software Foundation; either version 2 of the License, or
25971+ * (at your option) any later version.
dece6358
AM
25972+ *
25973+ * This program is distributed in the hope that it will be useful,
25974+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25975+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25976+ * GNU General Public License for more details.
25977+ *
25978+ * You should have received a copy of the GNU General Public License
523b37e3 25979+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25980+ */
25981+
25982+/*
25983+ * superblock private data
25984+ */
25985+
25986+#include "aufs.h"
25987+
25988+/*
25989+ * they are necessary regardless sysfs is disabled.
25990+ */
25991+void au_si_free(struct kobject *kobj)
25992+{
86dc4139 25993+ int i;
1facf9fc 25994+ struct au_sbinfo *sbinfo;
b752ccd1 25995+ char *locked __maybe_unused; /* debug only */
1facf9fc 25996+
25997+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
25998+ for (i = 0; i < AuPlink_NHASH; i++)
25999+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 26000+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 26001+
e49829fe 26002+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 26003+ au_br_free(sbinfo);
e49829fe 26004+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
26005+
26006+ AuDebugOn(radix_tree_gang_lookup
26007+ (&sbinfo->au_si_pid.tree, (void **)&locked,
26008+ /*first_index*/PID_MAX_DEFAULT - 1,
26009+ /*max_items*/sizeof(locked)/sizeof(*locked)));
26010+
1facf9fc 26011+ kfree(sbinfo->si_branch);
b752ccd1 26012+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 26013+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 26014+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 26015+
26016+ kfree(sbinfo);
26017+}
26018+
26019+int au_si_alloc(struct super_block *sb)
26020+{
86dc4139 26021+ int err, i;
1facf9fc 26022+ struct au_sbinfo *sbinfo;
e49829fe 26023+ static struct lock_class_key aufs_si;
1facf9fc 26024+
26025+ err = -ENOMEM;
4a4d8108 26026+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 26027+ if (unlikely(!sbinfo))
26028+ goto out;
26029+
b752ccd1
AM
26030+ BUILD_BUG_ON(sizeof(unsigned long) !=
26031+ sizeof(*sbinfo->au_si_pid.bitmap));
26032+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
26033+ sizeof(*sbinfo->au_si_pid.bitmap),
26034+ GFP_NOFS);
26035+ if (unlikely(!sbinfo->au_si_pid.bitmap))
26036+ goto out_sbinfo;
26037+
1facf9fc 26038+ /* will be reallocated separately */
26039+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
26040+ if (unlikely(!sbinfo->si_branch))
b752ccd1 26041+ goto out_pidmap;
1facf9fc 26042+
1facf9fc 26043+ err = sysaufs_si_init(sbinfo);
26044+ if (unlikely(err))
26045+ goto out_br;
26046+
26047+ au_nwt_init(&sbinfo->si_nowait);
dece6358 26048+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 26049+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
26050+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
26051+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
26052+
7f207e10 26053+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
26054+ atomic_long_set(&sbinfo->si_nfiles, 0);
26055+
1facf9fc 26056+ sbinfo->si_bend = -1;
392086de 26057+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 26058+
26059+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
26060+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
26061+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
26062+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 26063+
076b876e
AM
26064+ au_fhsm_init(sbinfo);
26065+
e49829fe 26066+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 26067+
392086de
AM
26068+ sbinfo->si_xino_jiffy = jiffies;
26069+ sbinfo->si_xino_expire
26070+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 26071+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 26072+ sbinfo->si_xino_brid = -1;
26073+ /* leave si_xib_last_pindex and si_xib_next_bit */
26074+
e49829fe 26075+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 26076+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
26077+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
26078+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
26079+
86dc4139
AM
26080+ for (i = 0; i < AuPlink_NHASH; i++)
26081+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 26082+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 26083+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 26084+
523b37e3
AM
26085+ au_sphl_init(&sbinfo->si_files);
26086+
1facf9fc 26087+ /* leave other members for sysaufs and si_mnt. */
26088+ sbinfo->si_sb = sb;
26089+ sb->s_fs_info = sbinfo;
b752ccd1 26090+ si_pid_set(sb);
1facf9fc 26091+ au_debug_sbinfo_init(sbinfo);
26092+ return 0; /* success */
26093+
4f0767ce 26094+out_br:
1facf9fc 26095+ kfree(sbinfo->si_branch);
4f0767ce 26096+out_pidmap:
b752ccd1 26097+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 26098+out_sbinfo:
1facf9fc 26099+ kfree(sbinfo);
4f0767ce 26100+out:
1facf9fc 26101+ return err;
26102+}
26103+
26104+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
26105+{
26106+ int err, sz;
26107+ struct au_branch **brp;
26108+
dece6358
AM
26109+ AuRwMustWriteLock(&sbinfo->si_rwsem);
26110+
1facf9fc 26111+ err = -ENOMEM;
26112+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
26113+ if (unlikely(!sz))
26114+ sz = sizeof(*brp);
26115+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
26116+ if (brp) {
26117+ sbinfo->si_branch = brp;
26118+ err = 0;
26119+ }
26120+
26121+ return err;
26122+}
26123+
26124+/* ---------------------------------------------------------------------- */
26125+
26126+unsigned int au_sigen_inc(struct super_block *sb)
26127+{
26128+ unsigned int gen;
26129+
dece6358
AM
26130+ SiMustWriteLock(sb);
26131+
1facf9fc 26132+ gen = ++au_sbi(sb)->si_generation;
26133+ au_update_digen(sb->s_root);
537831f9 26134+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 26135+ sb->s_root->d_inode->i_version++;
26136+ return gen;
26137+}
26138+
26139+aufs_bindex_t au_new_br_id(struct super_block *sb)
26140+{
26141+ aufs_bindex_t br_id;
26142+ int i;
26143+ struct au_sbinfo *sbinfo;
26144+
dece6358
AM
26145+ SiMustWriteLock(sb);
26146+
1facf9fc 26147+ sbinfo = au_sbi(sb);
26148+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
26149+ br_id = ++sbinfo->si_last_br_id;
7f207e10 26150+ AuDebugOn(br_id < 0);
1facf9fc 26151+ if (br_id && au_br_index(sb, br_id) < 0)
26152+ return br_id;
26153+ }
26154+
26155+ return -1;
26156+}
26157+
26158+/* ---------------------------------------------------------------------- */
26159+
e49829fe
JR
26160+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
26161+int si_read_lock(struct super_block *sb, int flags)
26162+{
26163+ int err;
26164+
26165+ err = 0;
26166+ if (au_ftest_lock(flags, FLUSH))
26167+ au_nwt_flush(&au_sbi(sb)->si_nowait);
26168+
26169+ si_noflush_read_lock(sb);
26170+ err = au_plink_maint(sb, flags);
26171+ if (unlikely(err))
26172+ si_read_unlock(sb);
26173+
26174+ return err;
26175+}
26176+
26177+int si_write_lock(struct super_block *sb, int flags)
26178+{
26179+ int err;
26180+
26181+ if (au_ftest_lock(flags, FLUSH))
26182+ au_nwt_flush(&au_sbi(sb)->si_nowait);
26183+
26184+ si_noflush_write_lock(sb);
26185+ err = au_plink_maint(sb, flags);
26186+ if (unlikely(err))
26187+ si_write_unlock(sb);
26188+
26189+ return err;
26190+}
26191+
1facf9fc 26192+/* dentry and super_block lock. call at entry point */
e49829fe 26193+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 26194+{
e49829fe 26195+ int err;
027c5e7a 26196+ struct super_block *sb;
e49829fe 26197+
027c5e7a
AM
26198+ sb = dentry->d_sb;
26199+ err = si_read_lock(sb, flags);
26200+ if (unlikely(err))
26201+ goto out;
26202+
26203+ if (au_ftest_lock(flags, DW))
26204+ di_write_lock_child(dentry);
26205+ else
26206+ di_read_lock_child(dentry, flags);
26207+
26208+ if (au_ftest_lock(flags, GEN)) {
26209+ err = au_digen_test(dentry, au_sigen(sb));
26210+ AuDebugOn(!err && au_dbrange_test(dentry));
26211+ if (unlikely(err))
26212+ aufs_read_unlock(dentry, flags);
e49829fe
JR
26213+ }
26214+
027c5e7a 26215+out:
e49829fe 26216+ return err;
1facf9fc 26217+}
26218+
26219+void aufs_read_unlock(struct dentry *dentry, int flags)
26220+{
26221+ if (au_ftest_lock(flags, DW))
26222+ di_write_unlock(dentry);
26223+ else
26224+ di_read_unlock(dentry, flags);
26225+ si_read_unlock(dentry->d_sb);
26226+}
26227+
26228+void aufs_write_lock(struct dentry *dentry)
26229+{
e49829fe 26230+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 26231+ di_write_lock_child(dentry);
26232+}
26233+
26234+void aufs_write_unlock(struct dentry *dentry)
26235+{
26236+ di_write_unlock(dentry);
26237+ si_write_unlock(dentry->d_sb);
26238+}
26239+
e49829fe 26240+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 26241+{
e49829fe 26242+ int err;
027c5e7a
AM
26243+ unsigned int sigen;
26244+ struct super_block *sb;
e49829fe 26245+
027c5e7a
AM
26246+ sb = d1->d_sb;
26247+ err = si_read_lock(sb, flags);
26248+ if (unlikely(err))
26249+ goto out;
26250+
26251+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
26252+
26253+ if (au_ftest_lock(flags, GEN)) {
26254+ sigen = au_sigen(sb);
26255+ err = au_digen_test(d1, sigen);
26256+ AuDebugOn(!err && au_dbrange_test(d1));
26257+ if (!err) {
26258+ err = au_digen_test(d2, sigen);
26259+ AuDebugOn(!err && au_dbrange_test(d2));
26260+ }
26261+ if (unlikely(err))
26262+ aufs_read_and_write_unlock2(d1, d2);
26263+ }
26264+
26265+out:
e49829fe 26266+ return err;
1facf9fc 26267+}
26268+
26269+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
26270+{
26271+ di_write_unlock2(d1, d2);
26272+ si_read_unlock(d1->d_sb);
26273+}
b752ccd1
AM
26274+
26275+/* ---------------------------------------------------------------------- */
26276+
26277+int si_pid_test_slow(struct super_block *sb)
26278+{
26279+ void *p;
26280+
26281+ rcu_read_lock();
26282+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
26283+ rcu_read_unlock();
26284+
027c5e7a 26285+ return (long)!!p;
b752ccd1
AM
26286+}
26287+
26288+void si_pid_set_slow(struct super_block *sb)
26289+{
26290+ int err;
26291+ struct au_sbinfo *sbinfo;
26292+
26293+ AuDebugOn(si_pid_test_slow(sb));
26294+
26295+ sbinfo = au_sbi(sb);
26296+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
26297+ AuDebugOn(err);
26298+ spin_lock(&sbinfo->au_si_pid.tree_lock);
26299+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 26300+ /*any valid ptr*/sb);
b752ccd1
AM
26301+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
26302+ AuDebugOn(err);
26303+ radix_tree_preload_end();
26304+}
26305+
26306+void si_pid_clr_slow(struct super_block *sb)
26307+{
26308+ void *p;
26309+ struct au_sbinfo *sbinfo;
26310+
26311+ AuDebugOn(!si_pid_test_slow(sb));
26312+
26313+ sbinfo = au_sbi(sb);
26314+ spin_lock(&sbinfo->au_si_pid.tree_lock);
26315+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
26316+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 26317+}
7f207e10
AM
26318diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
26319--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
2000de60 26320+++ linux/fs/aufs/spl.h 2015-03-27 21:56:35.466795000 +0100
523b37e3 26321@@ -0,0 +1,111 @@
1facf9fc 26322+/*
2000de60 26323+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 26324+ *
26325+ * This program, aufs is free software; you can redistribute it and/or modify
26326+ * it under the terms of the GNU General Public License as published by
26327+ * the Free Software Foundation; either version 2 of the License, or
26328+ * (at your option) any later version.
dece6358
AM
26329+ *
26330+ * This program is distributed in the hope that it will be useful,
26331+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26332+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26333+ * GNU General Public License for more details.
26334+ *
26335+ * You should have received a copy of the GNU General Public License
523b37e3 26336+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26337+ */
26338+
26339+/*
26340+ * simple list protected by a spinlock
26341+ */
26342+
26343+#ifndef __AUFS_SPL_H__
26344+#define __AUFS_SPL_H__
26345+
26346+#ifdef __KERNEL__
26347+
1facf9fc 26348+struct au_splhead {
26349+ spinlock_t spin;
26350+ struct list_head head;
26351+};
26352+
26353+static inline void au_spl_init(struct au_splhead *spl)
26354+{
26355+ spin_lock_init(&spl->spin);
26356+ INIT_LIST_HEAD(&spl->head);
26357+}
26358+
26359+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
26360+{
26361+ spin_lock(&spl->spin);
26362+ list_add(list, &spl->head);
26363+ spin_unlock(&spl->spin);
26364+}
26365+
26366+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
26367+{
26368+ spin_lock(&spl->spin);
26369+ list_del(list);
26370+ spin_unlock(&spl->spin);
26371+}
26372+
4a4d8108
AM
26373+static inline void au_spl_del_rcu(struct list_head *list,
26374+ struct au_splhead *spl)
26375+{
26376+ spin_lock(&spl->spin);
26377+ list_del_rcu(list);
26378+ spin_unlock(&spl->spin);
26379+}
26380+
86dc4139
AM
26381+/* ---------------------------------------------------------------------- */
26382+
26383+struct au_sphlhead {
26384+ spinlock_t spin;
26385+ struct hlist_head head;
26386+};
26387+
26388+static inline void au_sphl_init(struct au_sphlhead *sphl)
26389+{
26390+ spin_lock_init(&sphl->spin);
26391+ INIT_HLIST_HEAD(&sphl->head);
26392+}
26393+
26394+static inline void au_sphl_add(struct hlist_node *hlist,
26395+ struct au_sphlhead *sphl)
26396+{
26397+ spin_lock(&sphl->spin);
26398+ hlist_add_head(hlist, &sphl->head);
26399+ spin_unlock(&sphl->spin);
26400+}
26401+
26402+static inline void au_sphl_del(struct hlist_node *hlist,
26403+ struct au_sphlhead *sphl)
26404+{
26405+ spin_lock(&sphl->spin);
26406+ hlist_del(hlist);
26407+ spin_unlock(&sphl->spin);
26408+}
26409+
26410+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
26411+ struct au_sphlhead *sphl)
26412+{
26413+ spin_lock(&sphl->spin);
26414+ hlist_del_rcu(hlist);
26415+ spin_unlock(&sphl->spin);
26416+}
26417+
26418+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
26419+{
26420+ unsigned long cnt;
26421+ struct hlist_node *pos;
26422+
26423+ cnt = 0;
26424+ spin_lock(&sphl->spin);
26425+ hlist_for_each(pos, &sphl->head)
26426+ cnt++;
26427+ spin_unlock(&sphl->spin);
26428+ return cnt;
26429+}
26430+
1facf9fc 26431+#endif /* __KERNEL__ */
26432+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
26433diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
26434--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
2000de60 26435+++ linux/fs/aufs/super.c 2015-03-27 21:56:35.466795000 +0100
c1595e42 26436@@ -0,0 +1,1009 @@
1facf9fc 26437+/*
2000de60 26438+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 26439+ *
26440+ * This program, aufs is free software; you can redistribute it and/or modify
26441+ * it under the terms of the GNU General Public License as published by
26442+ * the Free Software Foundation; either version 2 of the License, or
26443+ * (at your option) any later version.
dece6358
AM
26444+ *
26445+ * This program is distributed in the hope that it will be useful,
26446+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26447+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26448+ * GNU General Public License for more details.
26449+ *
26450+ * You should have received a copy of the GNU General Public License
523b37e3 26451+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26452+ */
26453+
26454+/*
26455+ * mount and super_block operations
26456+ */
26457+
f6c5ef8b 26458+#include <linux/mm.h>
dece6358 26459+#include <linux/module.h>
1facf9fc 26460+#include <linux/seq_file.h>
26461+#include <linux/statfs.h>
7f207e10
AM
26462+#include <linux/vmalloc.h>
26463+#include <linux/writeback.h>
1facf9fc 26464+#include "aufs.h"
26465+
26466+/*
26467+ * super_operations
26468+ */
26469+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
26470+{
26471+ struct au_icntnr *c;
26472+
26473+ c = au_cache_alloc_icntnr();
26474+ if (c) {
027c5e7a 26475+ au_icntnr_init(c);
1facf9fc 26476+ c->vfs_inode.i_version = 1; /* sigen(sb); */
26477+ c->iinfo.ii_hinode = NULL;
26478+ return &c->vfs_inode;
26479+ }
26480+ return NULL;
26481+}
26482+
027c5e7a
AM
26483+static void aufs_destroy_inode_cb(struct rcu_head *head)
26484+{
26485+ struct inode *inode = container_of(head, struct inode, i_rcu);
26486+
b4510431 26487+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
26488+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
26489+}
26490+
1facf9fc 26491+static void aufs_destroy_inode(struct inode *inode)
26492+{
26493+ au_iinfo_fin(inode);
027c5e7a 26494+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 26495+}
26496+
26497+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
26498+{
26499+ struct inode *inode;
26500+ int err;
26501+
26502+ inode = iget_locked(sb, ino);
26503+ if (unlikely(!inode)) {
26504+ inode = ERR_PTR(-ENOMEM);
26505+ goto out;
26506+ }
26507+ if (!(inode->i_state & I_NEW))
26508+ goto out;
26509+
26510+ err = au_xigen_new(inode);
26511+ if (!err)
26512+ err = au_iinfo_init(inode);
26513+ if (!err)
26514+ inode->i_version++;
26515+ else {
26516+ iget_failed(inode);
26517+ inode = ERR_PTR(err);
26518+ }
26519+
4f0767ce 26520+out:
1facf9fc 26521+ /* never return NULL */
26522+ AuDebugOn(!inode);
26523+ AuTraceErrPtr(inode);
26524+ return inode;
26525+}
26526+
26527+/* lock free root dinfo */
26528+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
26529+{
26530+ int err;
26531+ aufs_bindex_t bindex, bend;
26532+ struct path path;
4a4d8108 26533+ struct au_hdentry *hdp;
1facf9fc 26534+ struct au_branch *br;
076b876e 26535+ au_br_perm_str_t perm;
1facf9fc 26536+
26537+ err = 0;
26538+ bend = au_sbend(sb);
4a4d8108 26539+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 26540+ for (bindex = 0; !err && bindex <= bend; bindex++) {
26541+ br = au_sbr(sb, bindex);
86dc4139 26542+ path.mnt = au_br_mnt(br);
4a4d8108 26543+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 26544+ err = au_seq_path(seq, &path);
1e00d052 26545+ if (err > 0) {
076b876e
AM
26546+ au_optstr_br_perm(&perm, br->br_perm);
26547+ err = seq_printf(seq, "=%s", perm.a);
26548+ if (err == -1)
26549+ err = -E2BIG;
1e00d052 26550+ }
1facf9fc 26551+ if (!err && bindex != bend)
26552+ err = seq_putc(seq, ':');
26553+ }
26554+
26555+ return err;
26556+}
26557+
26558+static void au_show_wbr_create(struct seq_file *m, int v,
26559+ struct au_sbinfo *sbinfo)
26560+{
26561+ const char *pat;
26562+
dece6358
AM
26563+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26564+
c2b27bf2 26565+ seq_puts(m, ",create=");
1facf9fc 26566+ pat = au_optstr_wbr_create(v);
26567+ switch (v) {
26568+ case AuWbrCreate_TDP:
26569+ case AuWbrCreate_RR:
26570+ case AuWbrCreate_MFS:
26571+ case AuWbrCreate_PMFS:
c2b27bf2 26572+ seq_puts(m, pat);
1facf9fc 26573+ break;
26574+ case AuWbrCreate_MFSV:
26575+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
26576+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26577+ / MSEC_PER_SEC);
1facf9fc 26578+ break;
26579+ case AuWbrCreate_PMFSV:
26580+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
26581+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26582+ / MSEC_PER_SEC);
1facf9fc 26583+ break;
26584+ case AuWbrCreate_MFSRR:
26585+ seq_printf(m, /*pat*/"mfsrr:%llu",
26586+ sbinfo->si_wbr_mfs.mfsrr_watermark);
26587+ break;
26588+ case AuWbrCreate_MFSRRV:
26589+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
26590+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
26591+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26592+ / MSEC_PER_SEC);
1facf9fc 26593+ break;
392086de
AM
26594+ case AuWbrCreate_PMFSRR:
26595+ seq_printf(m, /*pat*/"pmfsrr:%llu",
26596+ sbinfo->si_wbr_mfs.mfsrr_watermark);
26597+ break;
26598+ case AuWbrCreate_PMFSRRV:
26599+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
26600+ sbinfo->si_wbr_mfs.mfsrr_watermark,
26601+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26602+ / MSEC_PER_SEC);
26603+ break;
1facf9fc 26604+ }
26605+}
26606+
7eafdf33 26607+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 26608+{
26609+#ifdef CONFIG_SYSFS
26610+ return 0;
26611+#else
26612+ int err;
26613+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
26614+ aufs_bindex_t bindex, brid;
1facf9fc 26615+ struct qstr *name;
26616+ struct file *f;
26617+ struct dentry *d, *h_root;
4a4d8108 26618+ struct au_hdentry *hdp;
1facf9fc 26619+
dece6358
AM
26620+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26621+
1facf9fc 26622+ err = 0;
1facf9fc 26623+ f = au_sbi(sb)->si_xib;
26624+ if (!f)
26625+ goto out;
26626+
26627+ /* stop printing the default xino path on the first writable branch */
26628+ h_root = NULL;
26629+ brid = au_xino_brid(sb);
26630+ if (brid >= 0) {
26631+ bindex = au_br_index(sb, brid);
4a4d8108
AM
26632+ hdp = au_di(sb->s_root)->di_hdentry;
26633+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 26634+ }
2000de60 26635+ d = f->f_path.dentry;
1facf9fc 26636+ name = &d->d_name;
26637+ /* safe ->d_parent because the file is unlinked */
26638+ if (d->d_parent == h_root
26639+ && name->len == len
26640+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
26641+ goto out;
26642+
26643+ seq_puts(seq, ",xino=");
26644+ err = au_xino_path(seq, f);
26645+
4f0767ce 26646+out:
1facf9fc 26647+ return err;
26648+#endif
26649+}
26650+
26651+/* seq_file will re-call me in case of too long string */
7eafdf33 26652+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 26653+{
027c5e7a 26654+ int err;
1facf9fc 26655+ unsigned int mnt_flags, v;
26656+ struct super_block *sb;
26657+ struct au_sbinfo *sbinfo;
26658+
26659+#define AuBool(name, str) do { \
26660+ v = au_opt_test(mnt_flags, name); \
26661+ if (v != au_opt_test(AuOpt_Def, name)) \
26662+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
26663+} while (0)
26664+
26665+#define AuStr(name, str) do { \
26666+ v = mnt_flags & AuOptMask_##name; \
26667+ if (v != (AuOpt_Def & AuOptMask_##name)) \
26668+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
26669+} while (0)
26670+
26671+#define AuUInt(name, str, val) do { \
26672+ if (val != AUFS_##name##_DEF) \
26673+ seq_printf(m, "," #str "=%u", val); \
26674+} while (0)
26675+
7eafdf33 26676+ sb = dentry->d_sb;
c1595e42
JR
26677+ if (sb->s_flags & MS_POSIXACL)
26678+ seq_puts(m, ",acl");
26679+
26680+ /* lock free root dinfo */
1facf9fc 26681+ si_noflush_read_lock(sb);
26682+ sbinfo = au_sbi(sb);
26683+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
26684+
26685+ mnt_flags = au_mntflags(sb);
26686+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 26687+ err = au_show_xino(m, sb);
1facf9fc 26688+ if (unlikely(err))
26689+ goto out;
26690+ } else
26691+ seq_puts(m, ",noxino");
26692+
26693+ AuBool(TRUNC_XINO, trunc_xino);
26694+ AuStr(UDBA, udba);
dece6358 26695+ AuBool(SHWH, shwh);
1facf9fc 26696+ AuBool(PLINK, plink);
4a4d8108 26697+ AuBool(DIO, dio);
076b876e 26698+ AuBool(DIRPERM1, dirperm1);
1facf9fc 26699+ /* AuBool(REFROF, refrof); */
26700+
26701+ v = sbinfo->si_wbr_create;
26702+ if (v != AuWbrCreate_Def)
26703+ au_show_wbr_create(m, v, sbinfo);
26704+
26705+ v = sbinfo->si_wbr_copyup;
26706+ if (v != AuWbrCopyup_Def)
26707+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
26708+
26709+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
26710+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
26711+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
26712+
26713+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
26714+
027c5e7a
AM
26715+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
26716+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 26717+
26718+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
26719+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
26720+
076b876e
AM
26721+ au_fhsm_show(m, sbinfo);
26722+
1facf9fc 26723+ AuBool(SUM, sum);
26724+ /* AuBool(SUM_W, wsum); */
26725+ AuBool(WARN_PERM, warn_perm);
26726+ AuBool(VERBOSE, verbose);
26727+
4f0767ce 26728+out:
1facf9fc 26729+ /* be sure to print "br:" last */
26730+ if (!sysaufs_brs) {
26731+ seq_puts(m, ",br:");
26732+ au_show_brs(m, sb);
26733+ }
26734+ si_read_unlock(sb);
26735+ return 0;
26736+
1facf9fc 26737+#undef AuBool
26738+#undef AuStr
4a4d8108 26739+#undef AuUInt
1facf9fc 26740+}
26741+
26742+/* ---------------------------------------------------------------------- */
26743+
26744+/* sum mode which returns the summation for statfs(2) */
26745+
26746+static u64 au_add_till_max(u64 a, u64 b)
26747+{
26748+ u64 old;
26749+
26750+ old = a;
26751+ a += b;
92d182d2
AM
26752+ if (old <= a)
26753+ return a;
26754+ return ULLONG_MAX;
26755+}
26756+
26757+static u64 au_mul_till_max(u64 a, long mul)
26758+{
26759+ u64 old;
26760+
26761+ old = a;
26762+ a *= mul;
26763+ if (old <= a)
1facf9fc 26764+ return a;
26765+ return ULLONG_MAX;
26766+}
26767+
26768+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
26769+{
26770+ int err;
92d182d2 26771+ long bsize, factor;
1facf9fc 26772+ u64 blocks, bfree, bavail, files, ffree;
26773+ aufs_bindex_t bend, bindex, i;
26774+ unsigned char shared;
7f207e10 26775+ struct path h_path;
1facf9fc 26776+ struct super_block *h_sb;
26777+
92d182d2
AM
26778+ err = 0;
26779+ bsize = LONG_MAX;
26780+ files = 0;
26781+ ffree = 0;
1facf9fc 26782+ blocks = 0;
26783+ bfree = 0;
26784+ bavail = 0;
1facf9fc 26785+ bend = au_sbend(sb);
92d182d2 26786+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
26787+ h_path.mnt = au_sbr_mnt(sb, bindex);
26788+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 26789+ shared = 0;
92d182d2 26790+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 26791+ shared = (au_sbr_sb(sb, i) == h_sb);
26792+ if (shared)
26793+ continue;
26794+
26795+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
26796+ h_path.dentry = h_path.mnt->mnt_root;
26797+ err = vfs_statfs(&h_path, buf);
1facf9fc 26798+ if (unlikely(err))
26799+ goto out;
26800+
92d182d2
AM
26801+ if (bsize > buf->f_bsize) {
26802+ /*
26803+ * we will reduce bsize, so we have to expand blocks
26804+ * etc. to match them again
26805+ */
26806+ factor = (bsize / buf->f_bsize);
26807+ blocks = au_mul_till_max(blocks, factor);
26808+ bfree = au_mul_till_max(bfree, factor);
26809+ bavail = au_mul_till_max(bavail, factor);
26810+ bsize = buf->f_bsize;
26811+ }
26812+
26813+ factor = (buf->f_bsize / bsize);
26814+ blocks = au_add_till_max(blocks,
26815+ au_mul_till_max(buf->f_blocks, factor));
26816+ bfree = au_add_till_max(bfree,
26817+ au_mul_till_max(buf->f_bfree, factor));
26818+ bavail = au_add_till_max(bavail,
26819+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 26820+ files = au_add_till_max(files, buf->f_files);
26821+ ffree = au_add_till_max(ffree, buf->f_ffree);
26822+ }
26823+
92d182d2 26824+ buf->f_bsize = bsize;
1facf9fc 26825+ buf->f_blocks = blocks;
26826+ buf->f_bfree = bfree;
26827+ buf->f_bavail = bavail;
26828+ buf->f_files = files;
26829+ buf->f_ffree = ffree;
92d182d2 26830+ buf->f_frsize = 0;
1facf9fc 26831+
4f0767ce 26832+out:
1facf9fc 26833+ return err;
26834+}
26835+
26836+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
26837+{
26838+ int err;
7f207e10 26839+ struct path h_path;
1facf9fc 26840+ struct super_block *sb;
26841+
26842+ /* lock free root dinfo */
26843+ sb = dentry->d_sb;
26844+ si_noflush_read_lock(sb);
7f207e10 26845+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 26846+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
26847+ h_path.mnt = au_sbr_mnt(sb, 0);
26848+ h_path.dentry = h_path.mnt->mnt_root;
26849+ err = vfs_statfs(&h_path, buf);
26850+ } else
1facf9fc 26851+ err = au_statfs_sum(sb, buf);
26852+ si_read_unlock(sb);
26853+
26854+ if (!err) {
26855+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 26856+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 26857+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
26858+ }
26859+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
26860+
26861+ return err;
26862+}
26863+
26864+/* ---------------------------------------------------------------------- */
26865+
537831f9
AM
26866+static int aufs_sync_fs(struct super_block *sb, int wait)
26867+{
26868+ int err, e;
26869+ aufs_bindex_t bend, bindex;
26870+ struct au_branch *br;
26871+ struct super_block *h_sb;
26872+
26873+ err = 0;
26874+ si_noflush_read_lock(sb);
26875+ bend = au_sbend(sb);
26876+ for (bindex = 0; bindex <= bend; bindex++) {
26877+ br = au_sbr(sb, bindex);
26878+ if (!au_br_writable(br->br_perm))
26879+ continue;
26880+
26881+ h_sb = au_sbr_sb(sb, bindex);
26882+ if (h_sb->s_op->sync_fs) {
26883+ e = h_sb->s_op->sync_fs(h_sb, wait);
26884+ if (unlikely(e && !err))
26885+ err = e;
26886+ /* go on even if an error happens */
26887+ }
26888+ }
26889+ si_read_unlock(sb);
26890+
26891+ return err;
26892+}
26893+
26894+/* ---------------------------------------------------------------------- */
26895+
1facf9fc 26896+/* final actions when unmounting a file system */
26897+static void aufs_put_super(struct super_block *sb)
26898+{
26899+ struct au_sbinfo *sbinfo;
26900+
26901+ sbinfo = au_sbi(sb);
26902+ if (!sbinfo)
26903+ return;
26904+
1facf9fc 26905+ dbgaufs_si_fin(sbinfo);
26906+ kobject_put(&sbinfo->si_kobj);
26907+}
26908+
26909+/* ---------------------------------------------------------------------- */
26910+
7f207e10
AM
26911+void au_array_free(void *array)
26912+{
26913+ if (array) {
26914+ if (!is_vmalloc_addr(array))
26915+ kfree(array);
26916+ else
26917+ vfree(array);
26918+ }
26919+}
26920+
26921+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
26922+{
26923+ void *array;
076b876e 26924+ unsigned long long n, sz;
7f207e10
AM
26925+
26926+ array = NULL;
26927+ n = 0;
26928+ if (!*hint)
26929+ goto out;
26930+
26931+ if (*hint > ULLONG_MAX / sizeof(array)) {
26932+ array = ERR_PTR(-EMFILE);
26933+ pr_err("hint %llu\n", *hint);
26934+ goto out;
26935+ }
26936+
076b876e
AM
26937+ sz = sizeof(array) * *hint;
26938+ array = kzalloc(sz, GFP_NOFS);
7f207e10 26939+ if (unlikely(!array))
076b876e 26940+ array = vzalloc(sz);
7f207e10
AM
26941+ if (unlikely(!array)) {
26942+ array = ERR_PTR(-ENOMEM);
26943+ goto out;
26944+ }
26945+
26946+ n = cb(array, *hint, arg);
26947+ AuDebugOn(n > *hint);
26948+
26949+out:
26950+ *hint = n;
26951+ return array;
26952+}
26953+
26954+static unsigned long long au_iarray_cb(void *a,
26955+ unsigned long long max __maybe_unused,
26956+ void *arg)
26957+{
26958+ unsigned long long n;
26959+ struct inode **p, *inode;
26960+ struct list_head *head;
26961+
26962+ n = 0;
26963+ p = a;
26964+ head = arg;
2cbb1c4b 26965+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
26966+ list_for_each_entry(inode, head, i_sb_list) {
26967+ if (!is_bad_inode(inode)
26968+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
26969+ spin_lock(&inode->i_lock);
26970+ if (atomic_read(&inode->i_count)) {
26971+ au_igrab(inode);
26972+ *p++ = inode;
26973+ n++;
26974+ AuDebugOn(n > max);
26975+ }
26976+ spin_unlock(&inode->i_lock);
7f207e10
AM
26977+ }
26978+ }
2cbb1c4b 26979+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
26980+
26981+ return n;
26982+}
26983+
26984+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
26985+{
26986+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
26987+ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
26988+}
26989+
26990+void au_iarray_free(struct inode **a, unsigned long long max)
26991+{
26992+ unsigned long long ull;
26993+
26994+ for (ull = 0; ull < max; ull++)
26995+ iput(a[ull]);
26996+ au_array_free(a);
26997+}
26998+
26999+/* ---------------------------------------------------------------------- */
27000+
1facf9fc 27001+/*
27002+ * refresh dentry and inode at remount time.
27003+ */
027c5e7a
AM
27004+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
27005+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
27006+ struct dentry *parent)
1facf9fc 27007+{
27008+ int err;
1facf9fc 27009+
27010+ di_write_lock_child(dentry);
1facf9fc 27011+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
27012+ err = au_refresh_dentry(dentry, parent);
27013+ if (!err && dir_flags)
27014+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 27015+ di_read_unlock(parent, AuLock_IR);
1facf9fc 27016+ di_write_unlock(dentry);
27017+
27018+ return err;
27019+}
27020+
027c5e7a
AM
27021+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
27022+ struct au_sbinfo *sbinfo,
27023+ const unsigned int dir_flags)
1facf9fc 27024+{
027c5e7a
AM
27025+ int err;
27026+ struct dentry *parent;
27027+ struct inode *inode;
27028+
27029+ err = 0;
27030+ parent = dget_parent(dentry);
27031+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
27032+ inode = dentry->d_inode;
27033+ if (inode) {
27034+ if (!S_ISDIR(inode->i_mode))
27035+ err = au_do_refresh(dentry, /*dir_flags*/0,
27036+ parent);
27037+ else {
27038+ err = au_do_refresh(dentry, dir_flags, parent);
27039+ if (unlikely(err))
27040+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
27041+ }
27042+ } else
27043+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
27044+ AuDbgDentry(dentry);
27045+ }
27046+ dput(parent);
27047+
27048+ AuTraceErr(err);
27049+ return err;
1facf9fc 27050+}
27051+
027c5e7a 27052+static int au_refresh_d(struct super_block *sb)
1facf9fc 27053+{
27054+ int err, i, j, ndentry, e;
027c5e7a 27055+ unsigned int sigen;
1facf9fc 27056+ struct au_dcsub_pages dpages;
27057+ struct au_dpage *dpage;
027c5e7a
AM
27058+ struct dentry **dentries, *d;
27059+ struct au_sbinfo *sbinfo;
27060+ struct dentry *root = sb->s_root;
27061+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
1facf9fc 27062+
027c5e7a
AM
27063+ err = au_dpages_init(&dpages, GFP_NOFS);
27064+ if (unlikely(err))
1facf9fc 27065+ goto out;
027c5e7a
AM
27066+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
27067+ if (unlikely(err))
1facf9fc 27068+ goto out_dpages;
1facf9fc 27069+
027c5e7a
AM
27070+ sigen = au_sigen(sb);
27071+ sbinfo = au_sbi(sb);
27072+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 27073+ dpage = dpages.dpages + i;
27074+ dentries = dpage->dentries;
27075+ ndentry = dpage->ndentry;
027c5e7a 27076+ for (j = 0; j < ndentry; j++) {
1facf9fc 27077+ d = dentries[j];
027c5e7a
AM
27078+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
27079+ if (unlikely(e && !err))
27080+ err = e;
27081+ /* go on even err */
1facf9fc 27082+ }
27083+ }
27084+
4f0767ce 27085+out_dpages:
1facf9fc 27086+ au_dpages_free(&dpages);
4f0767ce 27087+out:
1facf9fc 27088+ return err;
27089+}
27090+
027c5e7a 27091+static int au_refresh_i(struct super_block *sb)
1facf9fc 27092+{
027c5e7a
AM
27093+ int err, e;
27094+ unsigned int sigen;
27095+ unsigned long long max, ull;
27096+ struct inode *inode, **array;
1facf9fc 27097+
027c5e7a
AM
27098+ array = au_iarray_alloc(sb, &max);
27099+ err = PTR_ERR(array);
27100+ if (IS_ERR(array))
27101+ goto out;
1facf9fc 27102+
27103+ err = 0;
027c5e7a
AM
27104+ sigen = au_sigen(sb);
27105+ for (ull = 0; ull < max; ull++) {
27106+ inode = array[ull];
076b876e
AM
27107+ if (unlikely(!inode))
27108+ break;
537831f9 27109+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 27110+ ii_write_lock_child(inode);
027c5e7a 27111+ e = au_refresh_hinode_self(inode);
1facf9fc 27112+ ii_write_unlock(inode);
27113+ if (unlikely(e)) {
027c5e7a 27114+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 27115+ if (!err)
27116+ err = e;
27117+ /* go on even if err */
27118+ }
27119+ }
1facf9fc 27120+ }
27121+
027c5e7a 27122+ au_iarray_free(array, max);
1facf9fc 27123+
4f0767ce 27124+out:
1facf9fc 27125+ return err;
27126+}
27127+
027c5e7a 27128+static void au_remount_refresh(struct super_block *sb)
1facf9fc 27129+{
027c5e7a
AM
27130+ int err, e;
27131+ unsigned int udba;
27132+ aufs_bindex_t bindex, bend;
1facf9fc 27133+ struct dentry *root;
27134+ struct inode *inode;
027c5e7a 27135+ struct au_branch *br;
1facf9fc 27136+
27137+ au_sigen_inc(sb);
027c5e7a 27138+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 27139+
27140+ root = sb->s_root;
27141+ DiMustNoWaiters(root);
27142+ inode = root->d_inode;
27143+ IiMustNoWaiters(inode);
1facf9fc 27144+
027c5e7a
AM
27145+ udba = au_opt_udba(sb);
27146+ bend = au_sbend(sb);
27147+ for (bindex = 0; bindex <= bend; bindex++) {
27148+ br = au_sbr(sb, bindex);
27149+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 27150+ if (unlikely(err))
027c5e7a
AM
27151+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
27152+ bindex, err);
27153+ /* go on even if err */
1facf9fc 27154+ }
027c5e7a 27155+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 27156+
027c5e7a
AM
27157+ di_write_unlock(root);
27158+ err = au_refresh_d(sb);
27159+ e = au_refresh_i(sb);
27160+ if (unlikely(e && !err))
27161+ err = e;
1facf9fc 27162+ /* aufs_write_lock() calls ..._child() */
27163+ di_write_lock_child(root);
027c5e7a
AM
27164+
27165+ au_cpup_attr_all(inode, /*force*/1);
27166+
27167+ if (unlikely(err))
27168+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 27169+}
27170+
27171+/* stop extra interpretation of errno in mount(8), and strange error messages */
27172+static int cvt_err(int err)
27173+{
27174+ AuTraceErr(err);
27175+
27176+ switch (err) {
27177+ case -ENOENT:
27178+ case -ENOTDIR:
27179+ case -EEXIST:
27180+ case -EIO:
27181+ err = -EINVAL;
27182+ }
27183+ return err;
27184+}
27185+
27186+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
27187+{
4a4d8108
AM
27188+ int err, do_dx;
27189+ unsigned int mntflags;
1facf9fc 27190+ struct au_opts opts;
27191+ struct dentry *root;
27192+ struct inode *inode;
27193+ struct au_sbinfo *sbinfo;
27194+
27195+ err = 0;
27196+ root = sb->s_root;
27197+ if (!data || !*data) {
e49829fe
JR
27198+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
27199+ if (!err) {
27200+ di_write_lock_child(root);
27201+ err = au_opts_verify(sb, *flags, /*pending*/0);
27202+ aufs_write_unlock(root);
27203+ }
1facf9fc 27204+ goto out;
27205+ }
27206+
27207+ err = -ENOMEM;
27208+ memset(&opts, 0, sizeof(opts));
27209+ opts.opt = (void *)__get_free_page(GFP_NOFS);
27210+ if (unlikely(!opts.opt))
27211+ goto out;
27212+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
27213+ opts.flags = AuOpts_REMOUNT;
27214+ opts.sb_flags = *flags;
27215+
27216+ /* parse it before aufs lock */
27217+ err = au_opts_parse(sb, data, &opts);
27218+ if (unlikely(err))
27219+ goto out_opts;
27220+
27221+ sbinfo = au_sbi(sb);
27222+ inode = root->d_inode;
27223+ mutex_lock(&inode->i_mutex);
e49829fe
JR
27224+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
27225+ if (unlikely(err))
27226+ goto out_mtx;
27227+ di_write_lock_child(root);
1facf9fc 27228+
27229+ /* au_opts_remount() may return an error */
27230+ err = au_opts_remount(sb, &opts);
27231+ au_opts_free(&opts);
27232+
027c5e7a
AM
27233+ if (au_ftest_opts(opts.flags, REFRESH))
27234+ au_remount_refresh(sb);
1facf9fc 27235+
4a4d8108
AM
27236+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
27237+ mntflags = au_mntflags(sb);
27238+ do_dx = !!au_opt_test(mntflags, DIO);
27239+ au_dy_arefresh(do_dx);
27240+ }
27241+
076b876e 27242+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 27243+ aufs_write_unlock(root);
953406b4 27244+
e49829fe
JR
27245+out_mtx:
27246+ mutex_unlock(&inode->i_mutex);
4f0767ce 27247+out_opts:
1facf9fc 27248+ free_page((unsigned long)opts.opt);
4f0767ce 27249+out:
1facf9fc 27250+ err = cvt_err(err);
27251+ AuTraceErr(err);
27252+ return err;
27253+}
27254+
4a4d8108 27255+static const struct super_operations aufs_sop = {
1facf9fc 27256+ .alloc_inode = aufs_alloc_inode,
27257+ .destroy_inode = aufs_destroy_inode,
b752ccd1 27258+ /* always deleting, no clearing */
1facf9fc 27259+ .drop_inode = generic_delete_inode,
27260+ .show_options = aufs_show_options,
27261+ .statfs = aufs_statfs,
27262+ .put_super = aufs_put_super,
537831f9 27263+ .sync_fs = aufs_sync_fs,
1facf9fc 27264+ .remount_fs = aufs_remount_fs
27265+};
27266+
27267+/* ---------------------------------------------------------------------- */
27268+
27269+static int alloc_root(struct super_block *sb)
27270+{
27271+ int err;
27272+ struct inode *inode;
27273+ struct dentry *root;
27274+
27275+ err = -ENOMEM;
27276+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
27277+ err = PTR_ERR(inode);
27278+ if (IS_ERR(inode))
27279+ goto out;
27280+
27281+ inode->i_op = &aufs_dir_iop;
27282+ inode->i_fop = &aufs_dir_fop;
27283+ inode->i_mode = S_IFDIR;
9dbd164d 27284+ set_nlink(inode, 2);
1facf9fc 27285+ unlock_new_inode(inode);
27286+
92d182d2 27287+ root = d_make_root(inode);
1facf9fc 27288+ if (unlikely(!root))
92d182d2 27289+ goto out;
1facf9fc 27290+ err = PTR_ERR(root);
27291+ if (IS_ERR(root))
92d182d2 27292+ goto out;
1facf9fc 27293+
4a4d8108 27294+ err = au_di_init(root);
1facf9fc 27295+ if (!err) {
27296+ sb->s_root = root;
27297+ return 0; /* success */
27298+ }
27299+ dput(root);
1facf9fc 27300+
4f0767ce 27301+out:
1facf9fc 27302+ return err;
1facf9fc 27303+}
27304+
27305+static int aufs_fill_super(struct super_block *sb, void *raw_data,
27306+ int silent __maybe_unused)
27307+{
27308+ int err;
27309+ struct au_opts opts;
27310+ struct dentry *root;
27311+ struct inode *inode;
27312+ char *arg = raw_data;
27313+
27314+ if (unlikely(!arg || !*arg)) {
27315+ err = -EINVAL;
4a4d8108 27316+ pr_err("no arg\n");
1facf9fc 27317+ goto out;
27318+ }
27319+
27320+ err = -ENOMEM;
27321+ memset(&opts, 0, sizeof(opts));
27322+ opts.opt = (void *)__get_free_page(GFP_NOFS);
27323+ if (unlikely(!opts.opt))
27324+ goto out;
27325+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
27326+ opts.sb_flags = sb->s_flags;
27327+
27328+ err = au_si_alloc(sb);
27329+ if (unlikely(err))
27330+ goto out_opts;
27331+
27332+ /* all timestamps always follow the ones on the branch */
27333+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
27334+ sb->s_op = &aufs_sop;
027c5e7a 27335+ sb->s_d_op = &aufs_dop;
1facf9fc 27336+ sb->s_magic = AUFS_SUPER_MAGIC;
27337+ sb->s_maxbytes = 0;
c1595e42 27338+ sb->s_stack_depth = 1;
1facf9fc 27339+ au_export_init(sb);
c1595e42 27340+ /* au_xattr_init(sb); */
1facf9fc 27341+
27342+ err = alloc_root(sb);
27343+ if (unlikely(err)) {
27344+ si_write_unlock(sb);
27345+ goto out_info;
27346+ }
27347+ root = sb->s_root;
27348+ inode = root->d_inode;
27349+
27350+ /*
27351+ * actually we can parse options regardless aufs lock here.
27352+ * but at remount time, parsing must be done before aufs lock.
27353+ * so we follow the same rule.
27354+ */
27355+ ii_write_lock_parent(inode);
27356+ aufs_write_unlock(root);
27357+ err = au_opts_parse(sb, arg, &opts);
27358+ if (unlikely(err))
27359+ goto out_root;
27360+
27361+ /* lock vfs_inode first, then aufs. */
27362+ mutex_lock(&inode->i_mutex);
1facf9fc 27363+ aufs_write_lock(root);
27364+ err = au_opts_mount(sb, &opts);
27365+ au_opts_free(&opts);
1facf9fc 27366+ aufs_write_unlock(root);
27367+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
27368+ if (!err)
27369+ goto out_opts; /* success */
1facf9fc 27370+
4f0767ce 27371+out_root:
1facf9fc 27372+ dput(root);
27373+ sb->s_root = NULL;
4f0767ce 27374+out_info:
2cbb1c4b 27375+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 27376+ kobject_put(&au_sbi(sb)->si_kobj);
27377+ sb->s_fs_info = NULL;
4f0767ce 27378+out_opts:
1facf9fc 27379+ free_page((unsigned long)opts.opt);
4f0767ce 27380+out:
1facf9fc 27381+ AuTraceErr(err);
27382+ err = cvt_err(err);
27383+ AuTraceErr(err);
27384+ return err;
27385+}
27386+
27387+/* ---------------------------------------------------------------------- */
27388+
027c5e7a
AM
27389+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
27390+ const char *dev_name __maybe_unused,
27391+ void *raw_data)
1facf9fc 27392+{
027c5e7a 27393+ struct dentry *root;
1facf9fc 27394+ struct super_block *sb;
27395+
27396+ /* all timestamps always follow the ones on the branch */
27397+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
27398+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
27399+ if (IS_ERR(root))
27400+ goto out;
27401+
27402+ sb = root->d_sb;
27403+ si_write_lock(sb, !AuLock_FLUSH);
27404+ sysaufs_brs_add(sb, 0);
27405+ si_write_unlock(sb);
27406+ au_sbilist_add(sb);
27407+
27408+out:
27409+ return root;
1facf9fc 27410+}
27411+
e49829fe
JR
27412+static void aufs_kill_sb(struct super_block *sb)
27413+{
27414+ struct au_sbinfo *sbinfo;
27415+
27416+ sbinfo = au_sbi(sb);
27417+ if (sbinfo) {
27418+ au_sbilist_del(sb);
27419+ aufs_write_lock(sb->s_root);
076b876e 27420+ au_fhsm_fin(sb);
e49829fe
JR
27421+ if (sbinfo->si_wbr_create_ops->fin)
27422+ sbinfo->si_wbr_create_ops->fin(sb);
27423+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
27424+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
027c5e7a 27425+ au_remount_refresh(sb);
e49829fe
JR
27426+ }
27427+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
27428+ au_plink_put(sb, /*verbose*/1);
27429+ au_xino_clr(sb);
1e00d052 27430+ sbinfo->si_sb = NULL;
e49829fe 27431+ aufs_write_unlock(sb->s_root);
e49829fe
JR
27432+ au_nwt_flush(&sbinfo->si_nowait);
27433+ }
98d9a5b1 27434+ kill_anon_super(sb);
e49829fe
JR
27435+}
27436+
1facf9fc 27437+struct file_system_type aufs_fs_type = {
27438+ .name = AUFS_FSTYPE,
c06a8ce3
AM
27439+ /* a race between rename and others */
27440+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 27441+ .mount = aufs_mount,
e49829fe 27442+ .kill_sb = aufs_kill_sb,
1facf9fc 27443+ /* no need to __module_get() and module_put(). */
27444+ .owner = THIS_MODULE,
27445+};
7f207e10
AM
27446diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
27447--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
2000de60 27448+++ linux/fs/aufs/super.h 2015-03-27 21:56:35.466795000 +0100
c1595e42 27449@@ -0,0 +1,641 @@
1facf9fc 27450+/*
2000de60 27451+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 27452+ *
27453+ * This program, aufs is free software; you can redistribute it and/or modify
27454+ * it under the terms of the GNU General Public License as published by
27455+ * the Free Software Foundation; either version 2 of the License, or
27456+ * (at your option) any later version.
dece6358
AM
27457+ *
27458+ * This program is distributed in the hope that it will be useful,
27459+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27460+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27461+ * GNU General Public License for more details.
27462+ *
27463+ * You should have received a copy of the GNU General Public License
523b37e3 27464+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27465+ */
27466+
27467+/*
27468+ * super_block operations
27469+ */
27470+
27471+#ifndef __AUFS_SUPER_H__
27472+#define __AUFS_SUPER_H__
27473+
27474+#ifdef __KERNEL__
27475+
27476+#include <linux/fs.h>
1facf9fc 27477+#include "rwsem.h"
27478+#include "spl.h"
27479+#include "wkq.h"
27480+
27481+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
27482+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
27483+ loff_t *);
27484+
27485+/* policies to select one among multiple writable branches */
27486+struct au_wbr_copyup_operations {
27487+ int (*copyup)(struct dentry *dentry);
27488+};
27489+
392086de
AM
27490+#define AuWbr_DIR 1 /* target is a dir */
27491+#define AuWbr_PARENT (1 << 1) /* always require a parent */
27492+
27493+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
27494+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
27495+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
27496+
1facf9fc 27497+struct au_wbr_create_operations {
392086de 27498+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 27499+ int (*init)(struct super_block *sb);
27500+ int (*fin)(struct super_block *sb);
27501+};
27502+
27503+struct au_wbr_mfs {
27504+ struct mutex mfs_lock; /* protect this structure */
27505+ unsigned long mfs_jiffy;
27506+ unsigned long mfs_expire;
27507+ aufs_bindex_t mfs_bindex;
27508+
27509+ unsigned long long mfsrr_bytes;
27510+ unsigned long long mfsrr_watermark;
27511+};
27512+
86dc4139
AM
27513+struct pseudo_link {
27514+ union {
27515+ struct hlist_node hlist;
27516+ struct rcu_head rcu;
27517+ };
27518+ struct inode *inode;
27519+};
27520+
27521+#define AuPlink_NHASH 100
27522+static inline int au_plink_hash(ino_t ino)
27523+{
27524+ return ino % AuPlink_NHASH;
27525+}
27526+
076b876e
AM
27527+/* File-based Hierarchical Storage Management */
27528+struct au_fhsm {
27529+#ifdef CONFIG_AUFS_FHSM
27530+ /* allow only one process who can receive the notification */
27531+ spinlock_t fhsm_spin;
27532+ pid_t fhsm_pid;
27533+ wait_queue_head_t fhsm_wqh;
27534+ atomic_t fhsm_readable;
27535+
c1595e42 27536+ /* these are protected by si_rwsem */
076b876e 27537+ unsigned long fhsm_expire;
c1595e42 27538+ aufs_bindex_t fhsm_bottom;
076b876e
AM
27539+#endif
27540+};
27541+
1facf9fc 27542+struct au_branch;
27543+struct au_sbinfo {
27544+ /* nowait tasks in the system-wide workqueue */
27545+ struct au_nowait_tasks si_nowait;
27546+
b752ccd1
AM
27547+ /*
27548+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
27549+ * rwsem for au_sbinfo is necessary.
27550+ */
dece6358 27551+ struct au_rwsem si_rwsem;
1facf9fc 27552+
b752ccd1
AM
27553+ /* prevent recursive locking in deleting inode */
27554+ struct {
27555+ unsigned long *bitmap;
27556+ spinlock_t tree_lock;
27557+ struct radix_tree_root tree;
27558+ } au_si_pid;
27559+
7f207e10 27560+ /*
523b37e3
AM
27561+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
27562+ * remount.
7f207e10
AM
27563+ */
27564+ atomic_long_t si_ninodes, si_nfiles;
27565+
1facf9fc 27566+ /* branch management */
27567+ unsigned int si_generation;
27568+
2000de60 27569+ /* see AuSi_ flags */
1facf9fc 27570+ unsigned char au_si_status;
27571+
27572+ aufs_bindex_t si_bend;
7f207e10
AM
27573+
27574+ /* dirty trick to keep br_id plus */
27575+ unsigned int si_last_br_id :
27576+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 27577+ struct au_branch **si_branch;
27578+
27579+ /* policy to select a writable branch */
27580+ unsigned char si_wbr_copyup;
27581+ unsigned char si_wbr_create;
27582+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
27583+ struct au_wbr_create_operations *si_wbr_create_ops;
27584+
27585+ /* round robin */
27586+ atomic_t si_wbr_rr_next;
27587+
27588+ /* most free space */
27589+ struct au_wbr_mfs si_wbr_mfs;
27590+
076b876e
AM
27591+ /* File-based Hierarchical Storage Management */
27592+ struct au_fhsm si_fhsm;
27593+
1facf9fc 27594+ /* mount flags */
27595+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
27596+ unsigned int si_mntflags;
27597+
27598+ /* external inode number (bitmap and translation table) */
27599+ au_readf_t si_xread;
27600+ au_writef_t si_xwrite;
27601+ struct file *si_xib;
27602+ struct mutex si_xib_mtx; /* protect xib members */
27603+ unsigned long *si_xib_buf;
27604+ unsigned long si_xib_last_pindex;
27605+ int si_xib_next_bit;
27606+ aufs_bindex_t si_xino_brid;
392086de
AM
27607+ unsigned long si_xino_jiffy;
27608+ unsigned long si_xino_expire;
1facf9fc 27609+ /* reserved for future use */
27610+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
27611+
27612+#ifdef CONFIG_AUFS_EXPORT
27613+ /* i_generation */
27614+ struct file *si_xigen;
27615+ atomic_t si_xigen_next;
27616+#endif
27617+
27618+ /* vdir parameters */
e49829fe 27619+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 27620+ unsigned int si_rdblk; /* deblk size */
27621+ unsigned int si_rdhash; /* hash size */
27622+
27623+ /*
27624+ * If the number of whiteouts are larger than si_dirwh, leave all of
27625+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
27626+ * future fsck.aufs or kernel thread will remove them later.
27627+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
27628+ */
27629+ unsigned int si_dirwh;
27630+
27631+ /*
27632+ * rename(2) a directory with all children.
27633+ */
27634+ /* reserved for future use */
27635+ /* int si_rendir; */
27636+
27637+ /* pseudo_link list */
86dc4139 27638+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 27639+ wait_queue_head_t si_plink_wq;
4a4d8108 27640+ spinlock_t si_plink_maint_lock;
e49829fe 27641+ pid_t si_plink_maint_pid;
1facf9fc 27642+
523b37e3
AM
27643+ /* file list */
27644+ struct au_sphlhead si_files;
27645+
1facf9fc 27646+ /*
27647+ * sysfs and lifetime management.
27648+ * this is not a small structure and it may be a waste of memory in case
27649+ * of sysfs is disabled, particulary when many aufs-es are mounted.
27650+ * but using sysfs is majority.
27651+ */
27652+ struct kobject si_kobj;
27653+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
27654+ struct dentry *si_dbgaufs;
27655+ struct dentry *si_dbgaufs_plink;
27656+ struct dentry *si_dbgaufs_xib;
1facf9fc 27657+#ifdef CONFIG_AUFS_EXPORT
27658+ struct dentry *si_dbgaufs_xigen;
27659+#endif
27660+#endif
27661+
e49829fe
JR
27662+#ifdef CONFIG_AUFS_SBILIST
27663+ struct list_head si_list;
27664+#endif
27665+
1facf9fc 27666+ /* dirty, necessary for unmounting, sysfs and sysrq */
27667+ struct super_block *si_sb;
27668+};
27669+
dece6358
AM
27670+/* sbinfo status flags */
27671+/*
27672+ * set true when refresh_dirs() failed at remount time.
27673+ * then try refreshing dirs at access time again.
27674+ * if it is false, refreshing dirs at access time is unnecesary
27675+ */
027c5e7a 27676+#define AuSi_FAILED_REFRESH_DIR 1
076b876e
AM
27677+
27678+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
27679+
27680+#ifndef CONFIG_AUFS_FHSM
27681+#undef AuSi_FHSM
27682+#define AuSi_FHSM 0
27683+#endif
27684+
dece6358
AM
27685+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
27686+ unsigned int flag)
27687+{
27688+ AuRwMustAnyLock(&sbi->si_rwsem);
27689+ return sbi->au_si_status & flag;
27690+}
27691+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
27692+#define au_fset_si(sbinfo, name) do { \
27693+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27694+ (sbinfo)->au_si_status |= AuSi_##name; \
27695+} while (0)
27696+#define au_fclr_si(sbinfo, name) do { \
27697+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27698+ (sbinfo)->au_si_status &= ~AuSi_##name; \
27699+} while (0)
27700+
1facf9fc 27701+/* ---------------------------------------------------------------------- */
27702+
27703+/* policy to select one among writable branches */
4a4d8108
AM
27704+#define AuWbrCopyup(sbinfo, ...) \
27705+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
27706+#define AuWbrCreate(sbinfo, ...) \
27707+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 27708+
27709+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
27710+#define AuLock_DW 1 /* write-lock dentry */
27711+#define AuLock_IR (1 << 1) /* read-lock inode */
27712+#define AuLock_IW (1 << 2) /* write-lock inode */
27713+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
27714+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
27715+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
27716+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 27717+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 27718+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
27719+#define au_fset_lock(flags, name) \
27720+ do { (flags) |= AuLock_##name; } while (0)
27721+#define au_fclr_lock(flags, name) \
27722+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 27723+
27724+/* ---------------------------------------------------------------------- */
27725+
27726+/* super.c */
27727+extern struct file_system_type aufs_fs_type;
27728+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
7f207e10
AM
27729+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
27730+ void *arg);
27731+void au_array_free(void *array);
27732+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
27733+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
27734+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 27735+
27736+/* sbinfo.c */
27737+void au_si_free(struct kobject *kobj);
27738+int au_si_alloc(struct super_block *sb);
27739+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
27740+
27741+unsigned int au_sigen_inc(struct super_block *sb);
27742+aufs_bindex_t au_new_br_id(struct super_block *sb);
27743+
e49829fe
JR
27744+int si_read_lock(struct super_block *sb, int flags);
27745+int si_write_lock(struct super_block *sb, int flags);
27746+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 27747+void aufs_read_unlock(struct dentry *dentry, int flags);
27748+void aufs_write_lock(struct dentry *dentry);
27749+void aufs_write_unlock(struct dentry *dentry);
e49829fe 27750+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 27751+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
27752+
b752ccd1
AM
27753+int si_pid_test_slow(struct super_block *sb);
27754+void si_pid_set_slow(struct super_block *sb);
27755+void si_pid_clr_slow(struct super_block *sb);
27756+
1facf9fc 27757+/* wbr_policy.c */
27758+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
27759+extern struct au_wbr_create_operations au_wbr_create_ops[];
27760+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 27761+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
076b876e 27762+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart);
c2b27bf2
AM
27763+
27764+/* mvdown.c */
27765+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 27766+
076b876e
AM
27767+#ifdef CONFIG_AUFS_FHSM
27768+/* fhsm.c */
27769+
27770+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
27771+{
27772+ pid_t pid;
27773+
27774+ spin_lock(&fhsm->fhsm_spin);
27775+ pid = fhsm->fhsm_pid;
27776+ spin_unlock(&fhsm->fhsm_spin);
27777+
27778+ return pid;
27779+}
27780+
27781+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
27782+void au_fhsm_wrote_all(struct super_block *sb, int force);
27783+int au_fhsm_fd(struct super_block *sb, int oflags);
27784+int au_fhsm_br_alloc(struct au_branch *br);
c1595e42 27785+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
076b876e
AM
27786+void au_fhsm_fin(struct super_block *sb);
27787+void au_fhsm_init(struct au_sbinfo *sbinfo);
27788+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
27789+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
27790+#else
27791+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
27792+ int force)
27793+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
27794+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
c1595e42
JR
27795+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
27796+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
27797+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
076b876e
AM
27798+AuStubVoid(au_fhsm_fin, struct super_block *sb)
27799+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
27800+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
27801+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
27802+#endif
27803+
1facf9fc 27804+/* ---------------------------------------------------------------------- */
27805+
27806+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
27807+{
27808+ return sb->s_fs_info;
27809+}
27810+
27811+/* ---------------------------------------------------------------------- */
27812+
27813+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 27814+int au_test_nfsd(void);
1facf9fc 27815+void au_export_init(struct super_block *sb);
b752ccd1 27816+void au_xigen_inc(struct inode *inode);
1facf9fc 27817+int au_xigen_new(struct inode *inode);
27818+int au_xigen_set(struct super_block *sb, struct file *base);
27819+void au_xigen_clr(struct super_block *sb);
27820+
27821+static inline int au_busy_or_stale(void)
27822+{
b752ccd1 27823+ if (!au_test_nfsd())
1facf9fc 27824+ return -EBUSY;
27825+ return -ESTALE;
27826+}
27827+#else
b752ccd1 27828+AuStubInt0(au_test_nfsd, void)
a2a7ad62 27829+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 27830+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
27831+AuStubInt0(au_xigen_new, struct inode *inode)
27832+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
27833+AuStubVoid(au_xigen_clr, struct super_block *sb)
c1595e42 27834+AuStub(int, au_busy_or_stale, return -EBUSY, void)
1facf9fc 27835+#endif /* CONFIG_AUFS_EXPORT */
27836+
27837+/* ---------------------------------------------------------------------- */
27838+
e49829fe
JR
27839+#ifdef CONFIG_AUFS_SBILIST
27840+/* module.c */
27841+extern struct au_splhead au_sbilist;
27842+
27843+static inline void au_sbilist_init(void)
27844+{
27845+ au_spl_init(&au_sbilist);
27846+}
27847+
27848+static inline void au_sbilist_add(struct super_block *sb)
27849+{
27850+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
27851+}
27852+
27853+static inline void au_sbilist_del(struct super_block *sb)
27854+{
27855+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
27856+}
53392da6
AM
27857+
27858+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
27859+static inline void au_sbilist_lock(void)
27860+{
27861+ spin_lock(&au_sbilist.spin);
27862+}
27863+
27864+static inline void au_sbilist_unlock(void)
27865+{
27866+ spin_unlock(&au_sbilist.spin);
27867+}
27868+#define AuGFP_SBILIST GFP_ATOMIC
27869+#else
27870+AuStubVoid(au_sbilist_lock, void)
27871+AuStubVoid(au_sbilist_unlock, void)
27872+#define AuGFP_SBILIST GFP_NOFS
27873+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
27874+#else
27875+AuStubVoid(au_sbilist_init, void)
c1595e42
JR
27876+AuStubVoid(au_sbilist_add, struct super_block *sb)
27877+AuStubVoid(au_sbilist_del, struct super_block *sb)
53392da6
AM
27878+AuStubVoid(au_sbilist_lock, void)
27879+AuStubVoid(au_sbilist_unlock, void)
27880+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
27881+#endif
27882+
27883+/* ---------------------------------------------------------------------- */
27884+
1facf9fc 27885+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
27886+{
dece6358 27887+ /*
c1595e42 27888+ * This function is a dynamic '__init' function actually,
dece6358
AM
27889+ * so the tiny check for si_rwsem is unnecessary.
27890+ */
27891+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 27892+#ifdef CONFIG_DEBUG_FS
27893+ sbinfo->si_dbgaufs = NULL;
86dc4139 27894+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 27895+ sbinfo->si_dbgaufs_xib = NULL;
27896+#ifdef CONFIG_AUFS_EXPORT
27897+ sbinfo->si_dbgaufs_xigen = NULL;
27898+#endif
27899+#endif
27900+}
27901+
27902+/* ---------------------------------------------------------------------- */
27903+
b752ccd1
AM
27904+static inline pid_t si_pid_bit(void)
27905+{
27906+ /* the origin of pid is 1, but the bitmap's is 0 */
27907+ return current->pid - 1;
27908+}
27909+
27910+static inline int si_pid_test(struct super_block *sb)
27911+{
076b876e
AM
27912+ pid_t bit;
27913+
27914+ bit = si_pid_bit();
b752ccd1
AM
27915+ if (bit < PID_MAX_DEFAULT)
27916+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
c1595e42 27917+ return si_pid_test_slow(sb);
b752ccd1
AM
27918+}
27919+
27920+static inline void si_pid_set(struct super_block *sb)
27921+{
076b876e
AM
27922+ pid_t bit;
27923+
27924+ bit = si_pid_bit();
b752ccd1
AM
27925+ if (bit < PID_MAX_DEFAULT) {
27926+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
27927+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27928+ /* smp_mb(); */
27929+ } else
27930+ si_pid_set_slow(sb);
27931+}
27932+
27933+static inline void si_pid_clr(struct super_block *sb)
27934+{
076b876e
AM
27935+ pid_t bit;
27936+
27937+ bit = si_pid_bit();
b752ccd1
AM
27938+ if (bit < PID_MAX_DEFAULT) {
27939+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
27940+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27941+ /* smp_mb(); */
27942+ } else
27943+ si_pid_clr_slow(sb);
27944+}
27945+
27946+/* ---------------------------------------------------------------------- */
27947+
1facf9fc 27948+/* lock superblock. mainly for entry point functions */
27949+/*
b752ccd1
AM
27950+ * __si_read_lock, __si_write_lock,
27951+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 27952+ */
b752ccd1 27953+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 27954+
dece6358
AM
27955+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
27956+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
27957+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
27958+
b752ccd1
AM
27959+static inline void si_noflush_read_lock(struct super_block *sb)
27960+{
27961+ __si_read_lock(sb);
27962+ si_pid_set(sb);
27963+}
27964+
27965+static inline int si_noflush_read_trylock(struct super_block *sb)
27966+{
076b876e
AM
27967+ int locked;
27968+
27969+ locked = __si_read_trylock(sb);
b752ccd1
AM
27970+ if (locked)
27971+ si_pid_set(sb);
27972+ return locked;
27973+}
27974+
27975+static inline void si_noflush_write_lock(struct super_block *sb)
27976+{
27977+ __si_write_lock(sb);
27978+ si_pid_set(sb);
27979+}
27980+
27981+static inline int si_noflush_write_trylock(struct super_block *sb)
27982+{
076b876e
AM
27983+ int locked;
27984+
27985+ locked = __si_write_trylock(sb);
b752ccd1
AM
27986+ if (locked)
27987+ si_pid_set(sb);
27988+ return locked;
27989+}
27990+
e49829fe 27991+#if 0 /* unused */
1facf9fc 27992+static inline int si_read_trylock(struct super_block *sb, int flags)
27993+{
27994+ if (au_ftest_lock(flags, FLUSH))
27995+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27996+ return si_noflush_read_trylock(sb);
27997+}
e49829fe 27998+#endif
1facf9fc 27999+
b752ccd1
AM
28000+static inline void si_read_unlock(struct super_block *sb)
28001+{
28002+ si_pid_clr(sb);
28003+ __si_read_unlock(sb);
28004+}
28005+
b752ccd1 28006+#if 0 /* unused */
1facf9fc 28007+static inline int si_write_trylock(struct super_block *sb, int flags)
28008+{
28009+ if (au_ftest_lock(flags, FLUSH))
28010+ au_nwt_flush(&au_sbi(sb)->si_nowait);
28011+ return si_noflush_write_trylock(sb);
28012+}
b752ccd1
AM
28013+#endif
28014+
28015+static inline void si_write_unlock(struct super_block *sb)
28016+{
28017+ si_pid_clr(sb);
28018+ __si_write_unlock(sb);
28019+}
28020+
28021+#if 0 /* unused */
28022+static inline void si_downgrade_lock(struct super_block *sb)
28023+{
28024+ __si_downgrade_lock(sb);
28025+}
28026+#endif
1facf9fc 28027+
28028+/* ---------------------------------------------------------------------- */
28029+
28030+static inline aufs_bindex_t au_sbend(struct super_block *sb)
28031+{
dece6358 28032+ SiMustAnyLock(sb);
1facf9fc 28033+ return au_sbi(sb)->si_bend;
28034+}
28035+
28036+static inline unsigned int au_mntflags(struct super_block *sb)
28037+{
dece6358 28038+ SiMustAnyLock(sb);
1facf9fc 28039+ return au_sbi(sb)->si_mntflags;
28040+}
28041+
28042+static inline unsigned int au_sigen(struct super_block *sb)
28043+{
dece6358 28044+ SiMustAnyLock(sb);
1facf9fc 28045+ return au_sbi(sb)->si_generation;
28046+}
28047+
7f207e10
AM
28048+static inline void au_ninodes_inc(struct super_block *sb)
28049+{
28050+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
28051+}
28052+
28053+static inline void au_ninodes_dec(struct super_block *sb)
28054+{
28055+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
28056+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
28057+}
28058+
28059+static inline void au_nfiles_inc(struct super_block *sb)
28060+{
28061+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
28062+}
28063+
28064+static inline void au_nfiles_dec(struct super_block *sb)
28065+{
28066+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
28067+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
28068+}
28069+
1facf9fc 28070+static inline struct au_branch *au_sbr(struct super_block *sb,
28071+ aufs_bindex_t bindex)
28072+{
dece6358 28073+ SiMustAnyLock(sb);
1facf9fc 28074+ return au_sbi(sb)->si_branch[0 + bindex];
28075+}
28076+
28077+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
28078+{
dece6358 28079+ SiMustWriteLock(sb);
1facf9fc 28080+ au_sbi(sb)->si_xino_brid = brid;
28081+}
28082+
28083+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
28084+{
dece6358 28085+ SiMustAnyLock(sb);
1facf9fc 28086+ return au_sbi(sb)->si_xino_brid;
28087+}
28088+
28089+#endif /* __KERNEL__ */
28090+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
28091diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
28092--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
2000de60 28093+++ linux/fs/aufs/sysaufs.c 2015-03-27 21:56:35.466795000 +0100
523b37e3 28094@@ -0,0 +1,104 @@
1facf9fc 28095+/*
2000de60 28096+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28097+ *
28098+ * This program, aufs is free software; you can redistribute it and/or modify
28099+ * it under the terms of the GNU General Public License as published by
28100+ * the Free Software Foundation; either version 2 of the License, or
28101+ * (at your option) any later version.
dece6358
AM
28102+ *
28103+ * This program is distributed in the hope that it will be useful,
28104+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28105+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28106+ * GNU General Public License for more details.
28107+ *
28108+ * You should have received a copy of the GNU General Public License
523b37e3 28109+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28110+ */
28111+
28112+/*
28113+ * sysfs interface and lifetime management
28114+ * they are necessary regardless sysfs is disabled.
28115+ */
28116+
1facf9fc 28117+#include <linux/random.h>
1facf9fc 28118+#include "aufs.h"
28119+
28120+unsigned long sysaufs_si_mask;
e49829fe 28121+struct kset *sysaufs_kset;
1facf9fc 28122+
28123+#define AuSiAttr(_name) { \
28124+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
28125+ .show = sysaufs_si_##_name, \
28126+}
28127+
28128+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
28129+struct attribute *sysaufs_si_attrs[] = {
28130+ &sysaufs_si_attr_xi_path.attr,
28131+ NULL,
28132+};
28133+
4a4d8108 28134+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 28135+ .show = sysaufs_si_show
28136+};
28137+
28138+static struct kobj_type au_sbi_ktype = {
28139+ .release = au_si_free,
28140+ .sysfs_ops = &au_sbi_ops,
28141+ .default_attrs = sysaufs_si_attrs
28142+};
28143+
28144+/* ---------------------------------------------------------------------- */
28145+
28146+int sysaufs_si_init(struct au_sbinfo *sbinfo)
28147+{
28148+ int err;
28149+
e49829fe 28150+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 28151+ /* cf. sysaufs_name() */
28152+ err = kobject_init_and_add
e49829fe 28153+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 28154+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
28155+
28156+ dbgaufs_si_null(sbinfo);
28157+ if (!err) {
28158+ err = dbgaufs_si_init(sbinfo);
28159+ if (unlikely(err))
28160+ kobject_put(&sbinfo->si_kobj);
28161+ }
28162+ return err;
28163+}
28164+
28165+void sysaufs_fin(void)
28166+{
28167+ dbgaufs_fin();
e49829fe
JR
28168+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
28169+ kset_unregister(sysaufs_kset);
1facf9fc 28170+}
28171+
28172+int __init sysaufs_init(void)
28173+{
28174+ int err;
28175+
28176+ do {
28177+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
28178+ } while (!sysaufs_si_mask);
28179+
4a4d8108 28180+ err = -EINVAL;
e49829fe
JR
28181+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
28182+ if (unlikely(!sysaufs_kset))
4a4d8108 28183+ goto out;
e49829fe
JR
28184+ err = PTR_ERR(sysaufs_kset);
28185+ if (IS_ERR(sysaufs_kset))
1facf9fc 28186+ goto out;
e49829fe 28187+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 28188+ if (unlikely(err)) {
e49829fe 28189+ kset_unregister(sysaufs_kset);
1facf9fc 28190+ goto out;
28191+ }
28192+
28193+ err = dbgaufs_init();
28194+ if (unlikely(err))
28195+ sysaufs_fin();
4f0767ce 28196+out:
1facf9fc 28197+ return err;
28198+}
7f207e10
AM
28199diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
28200--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
2000de60 28201+++ linux/fs/aufs/sysaufs.h 2015-03-27 21:56:35.466795000 +0100
c1595e42 28202@@ -0,0 +1,101 @@
1facf9fc 28203+/*
2000de60 28204+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28205+ *
28206+ * This program, aufs is free software; you can redistribute it and/or modify
28207+ * it under the terms of the GNU General Public License as published by
28208+ * the Free Software Foundation; either version 2 of the License, or
28209+ * (at your option) any later version.
dece6358
AM
28210+ *
28211+ * This program is distributed in the hope that it will be useful,
28212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28213+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28214+ * GNU General Public License for more details.
28215+ *
28216+ * You should have received a copy of the GNU General Public License
523b37e3 28217+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28218+ */
28219+
28220+/*
28221+ * sysfs interface and mount lifetime management
28222+ */
28223+
28224+#ifndef __SYSAUFS_H__
28225+#define __SYSAUFS_H__
28226+
28227+#ifdef __KERNEL__
28228+
1facf9fc 28229+#include <linux/sysfs.h>
1facf9fc 28230+#include "module.h"
28231+
dece6358
AM
28232+struct super_block;
28233+struct au_sbinfo;
28234+
1facf9fc 28235+struct sysaufs_si_attr {
28236+ struct attribute attr;
28237+ int (*show)(struct seq_file *seq, struct super_block *sb);
28238+};
28239+
28240+/* ---------------------------------------------------------------------- */
28241+
28242+/* sysaufs.c */
28243+extern unsigned long sysaufs_si_mask;
e49829fe 28244+extern struct kset *sysaufs_kset;
1facf9fc 28245+extern struct attribute *sysaufs_si_attrs[];
28246+int sysaufs_si_init(struct au_sbinfo *sbinfo);
28247+int __init sysaufs_init(void);
28248+void sysaufs_fin(void);
28249+
28250+/* ---------------------------------------------------------------------- */
28251+
28252+/* some people doesn't like to show a pointer in kernel */
28253+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
28254+{
28255+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
28256+}
28257+
28258+#define SysaufsSiNamePrefix "si_"
28259+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
28260+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
28261+{
28262+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
28263+ sysaufs_si_id(sbinfo));
28264+}
28265+
28266+struct au_branch;
28267+#ifdef CONFIG_SYSFS
28268+/* sysfs.c */
28269+extern struct attribute_group *sysaufs_attr_group;
28270+
28271+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
28272+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
28273+ char *buf);
076b876e
AM
28274+long au_brinfo_ioctl(struct file *file, unsigned long arg);
28275+#ifdef CONFIG_COMPAT
28276+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
28277+#endif
1facf9fc 28278+
28279+void sysaufs_br_init(struct au_branch *br);
28280+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
28281+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
28282+
28283+#define sysaufs_brs_init() do {} while (0)
28284+
28285+#else
28286+#define sysaufs_attr_group NULL
28287+
4a4d8108 28288+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
c1595e42
JR
28289+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
28290+ struct attribute *attr, char *buf)
4a4d8108
AM
28291+AuStubVoid(sysaufs_br_init, struct au_branch *br)
28292+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
28293+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 28294+
28295+static inline void sysaufs_brs_init(void)
28296+{
28297+ sysaufs_brs = 0;
28298+}
28299+
28300+#endif /* CONFIG_SYSFS */
28301+
28302+#endif /* __KERNEL__ */
28303+#endif /* __SYSAUFS_H__ */
7f207e10
AM
28304diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
28305--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
2000de60 28306+++ linux/fs/aufs/sysfs.c 2015-03-27 21:56:35.466795000 +0100
076b876e 28307@@ -0,0 +1,372 @@
1facf9fc 28308+/*
2000de60 28309+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28310+ *
28311+ * This program, aufs is free software; you can redistribute it and/or modify
28312+ * it under the terms of the GNU General Public License as published by
28313+ * the Free Software Foundation; either version 2 of the License, or
28314+ * (at your option) any later version.
dece6358
AM
28315+ *
28316+ * This program is distributed in the hope that it will be useful,
28317+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28318+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28319+ * GNU General Public License for more details.
28320+ *
28321+ * You should have received a copy of the GNU General Public License
523b37e3 28322+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28323+ */
28324+
28325+/*
28326+ * sysfs interface
28327+ */
28328+
076b876e 28329+#include <linux/compat.h>
1facf9fc 28330+#include <linux/seq_file.h>
1facf9fc 28331+#include "aufs.h"
28332+
4a4d8108
AM
28333+#ifdef CONFIG_AUFS_FS_MODULE
28334+/* this entry violates the "one line per file" policy of sysfs */
28335+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
28336+ char *buf)
28337+{
28338+ ssize_t err;
28339+ static char *conf =
28340+/* this file is generated at compiling */
28341+#include "conf.str"
28342+ ;
28343+
28344+ err = snprintf(buf, PAGE_SIZE, conf);
28345+ if (unlikely(err >= PAGE_SIZE))
28346+ err = -EFBIG;
28347+ return err;
28348+}
28349+
28350+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
28351+#endif
28352+
1facf9fc 28353+static struct attribute *au_attr[] = {
4a4d8108
AM
28354+#ifdef CONFIG_AUFS_FS_MODULE
28355+ &au_config_attr.attr,
28356+#endif
1facf9fc 28357+ NULL, /* need to NULL terminate the list of attributes */
28358+};
28359+
28360+static struct attribute_group sysaufs_attr_group_body = {
28361+ .attrs = au_attr
28362+};
28363+
28364+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
28365+
28366+/* ---------------------------------------------------------------------- */
28367+
28368+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
28369+{
28370+ int err;
28371+
dece6358
AM
28372+ SiMustAnyLock(sb);
28373+
1facf9fc 28374+ err = 0;
28375+ if (au_opt_test(au_mntflags(sb), XINO)) {
28376+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
28377+ seq_putc(seq, '\n');
28378+ }
28379+ return err;
28380+}
28381+
28382+/*
28383+ * the lifetime of branch is independent from the entry under sysfs.
28384+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
28385+ * unlinked.
28386+ */
28387+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 28388+ aufs_bindex_t bindex, int idx)
1facf9fc 28389+{
1e00d052 28390+ int err;
1facf9fc 28391+ struct path path;
28392+ struct dentry *root;
28393+ struct au_branch *br;
076b876e 28394+ au_br_perm_str_t perm;
1facf9fc 28395+
28396+ AuDbg("b%d\n", bindex);
28397+
1e00d052 28398+ err = 0;
1facf9fc 28399+ root = sb->s_root;
28400+ di_read_lock_parent(root, !AuLock_IR);
28401+ br = au_sbr(sb, bindex);
392086de
AM
28402+
28403+ switch (idx) {
28404+ case AuBrSysfs_BR:
28405+ path.mnt = au_br_mnt(br);
28406+ path.dentry = au_h_dptr(root, bindex);
28407+ au_seq_path(seq, &path);
076b876e
AM
28408+ au_optstr_br_perm(&perm, br->br_perm);
28409+ err = seq_printf(seq, "=%s\n", perm.a);
392086de
AM
28410+ break;
28411+ case AuBrSysfs_BRID:
28412+ err = seq_printf(seq, "%d\n", br->br_id);
392086de
AM
28413+ break;
28414+ }
076b876e
AM
28415+ di_read_unlock(root, !AuLock_IR);
28416+ if (err == -1)
28417+ err = -E2BIG;
392086de 28418+
1e00d052 28419+ return err;
1facf9fc 28420+}
28421+
28422+/* ---------------------------------------------------------------------- */
28423+
28424+static struct seq_file *au_seq(char *p, ssize_t len)
28425+{
28426+ struct seq_file *seq;
28427+
28428+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
28429+ if (seq) {
28430+ /* mutex_init(&seq.lock); */
28431+ seq->buf = p;
28432+ seq->size = len;
28433+ return seq; /* success */
28434+ }
28435+
28436+ seq = ERR_PTR(-ENOMEM);
28437+ return seq;
28438+}
28439+
392086de
AM
28440+#define SysaufsBr_PREFIX "br"
28441+#define SysaufsBrid_PREFIX "brid"
1facf9fc 28442+
28443+/* todo: file size may exceed PAGE_SIZE */
28444+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 28445+ char *buf)
1facf9fc 28446+{
28447+ ssize_t err;
392086de 28448+ int idx;
1facf9fc 28449+ long l;
28450+ aufs_bindex_t bend;
28451+ struct au_sbinfo *sbinfo;
28452+ struct super_block *sb;
28453+ struct seq_file *seq;
28454+ char *name;
28455+ struct attribute **cattr;
28456+
28457+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
28458+ sb = sbinfo->si_sb;
1308ab2a 28459+
28460+ /*
28461+ * prevent a race condition between sysfs and aufs.
28462+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
28463+ * prohibits maintaining the sysfs entries.
28464+ * hew we acquire read lock after sysfs_get_active_two().
28465+ * on the other hand, the remount process may maintain the sysfs/aufs
28466+ * entries after acquiring write lock.
28467+ * it can cause a deadlock.
28468+ * simply we gave up processing read here.
28469+ */
28470+ err = -EBUSY;
28471+ if (unlikely(!si_noflush_read_trylock(sb)))
28472+ goto out;
1facf9fc 28473+
28474+ seq = au_seq(buf, PAGE_SIZE);
28475+ err = PTR_ERR(seq);
28476+ if (IS_ERR(seq))
1308ab2a 28477+ goto out_unlock;
1facf9fc 28478+
28479+ name = (void *)attr->name;
28480+ cattr = sysaufs_si_attrs;
28481+ while (*cattr) {
28482+ if (!strcmp(name, (*cattr)->name)) {
28483+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
28484+ ->show(seq, sb);
28485+ goto out_seq;
28486+ }
28487+ cattr++;
28488+ }
28489+
392086de
AM
28490+ if (!strncmp(name, SysaufsBrid_PREFIX,
28491+ sizeof(SysaufsBrid_PREFIX) - 1)) {
28492+ idx = AuBrSysfs_BRID;
28493+ name += sizeof(SysaufsBrid_PREFIX) - 1;
28494+ } else if (!strncmp(name, SysaufsBr_PREFIX,
28495+ sizeof(SysaufsBr_PREFIX) - 1)) {
28496+ idx = AuBrSysfs_BR;
1facf9fc 28497+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
28498+ } else
28499+ BUG();
28500+
28501+ err = kstrtol(name, 10, &l);
28502+ if (!err) {
28503+ bend = au_sbend(sb);
28504+ if (l <= bend)
28505+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
28506+ else
28507+ err = -ENOENT;
1facf9fc 28508+ }
1facf9fc 28509+
4f0767ce 28510+out_seq:
1facf9fc 28511+ if (!err) {
28512+ err = seq->count;
28513+ /* sysfs limit */
28514+ if (unlikely(err == PAGE_SIZE))
28515+ err = -EFBIG;
28516+ }
28517+ kfree(seq);
4f0767ce 28518+out_unlock:
1facf9fc 28519+ si_read_unlock(sb);
4f0767ce 28520+out:
1facf9fc 28521+ return err;
28522+}
28523+
28524+/* ---------------------------------------------------------------------- */
28525+
076b876e
AM
28526+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
28527+{
28528+ int err;
28529+ int16_t brid;
28530+ aufs_bindex_t bindex, bend;
28531+ size_t sz;
28532+ char *buf;
28533+ struct seq_file *seq;
28534+ struct au_branch *br;
28535+
28536+ si_read_lock(sb, AuLock_FLUSH);
28537+ bend = au_sbend(sb);
28538+ err = bend + 1;
28539+ if (!arg)
28540+ goto out;
28541+
28542+ err = -ENOMEM;
28543+ buf = (void *)__get_free_page(GFP_NOFS);
28544+ if (unlikely(!buf))
28545+ goto out;
28546+
28547+ seq = au_seq(buf, PAGE_SIZE);
28548+ err = PTR_ERR(seq);
28549+ if (IS_ERR(seq))
28550+ goto out_buf;
28551+
28552+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
28553+ for (bindex = 0; bindex <= bend; bindex++, arg++) {
28554+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
28555+ if (unlikely(err))
28556+ break;
28557+
28558+ br = au_sbr(sb, bindex);
28559+ brid = br->br_id;
28560+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
28561+ err = __put_user(brid, &arg->id);
28562+ if (unlikely(err))
28563+ break;
28564+
28565+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
28566+ err = __put_user(br->br_perm, &arg->perm);
28567+ if (unlikely(err))
28568+ break;
28569+
28570+ au_seq_path(seq, &br->br_path);
28571+ err = seq_putc(seq, '\0');
28572+ if (!err && seq->count <= sz) {
28573+ err = copy_to_user(arg->path, seq->buf, seq->count);
28574+ seq->count = 0;
28575+ if (unlikely(err))
28576+ break;
28577+ } else {
28578+ err = -E2BIG;
28579+ goto out_seq;
28580+ }
28581+ }
28582+ if (unlikely(err))
28583+ err = -EFAULT;
28584+
28585+out_seq:
28586+ kfree(seq);
28587+out_buf:
28588+ free_page((unsigned long)buf);
28589+out:
28590+ si_read_unlock(sb);
28591+ return err;
28592+}
28593+
28594+long au_brinfo_ioctl(struct file *file, unsigned long arg)
28595+{
2000de60 28596+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg);
076b876e
AM
28597+}
28598+
28599+#ifdef CONFIG_COMPAT
28600+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
28601+{
2000de60 28602+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg));
076b876e
AM
28603+}
28604+#endif
28605+
28606+/* ---------------------------------------------------------------------- */
28607+
1facf9fc 28608+void sysaufs_br_init(struct au_branch *br)
28609+{
392086de
AM
28610+ int i;
28611+ struct au_brsysfs *br_sysfs;
28612+ struct attribute *attr;
4a4d8108 28613+
392086de
AM
28614+ br_sysfs = br->br_sysfs;
28615+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28616+ attr = &br_sysfs->attr;
28617+ sysfs_attr_init(attr);
28618+ attr->name = br_sysfs->name;
28619+ attr->mode = S_IRUGO;
28620+ br_sysfs++;
28621+ }
1facf9fc 28622+}
28623+
28624+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
28625+{
28626+ struct au_branch *br;
28627+ struct kobject *kobj;
392086de
AM
28628+ struct au_brsysfs *br_sysfs;
28629+ int i;
1facf9fc 28630+ aufs_bindex_t bend;
28631+
28632+ dbgaufs_brs_del(sb, bindex);
28633+
28634+ if (!sysaufs_brs)
28635+ return;
28636+
28637+ kobj = &au_sbi(sb)->si_kobj;
28638+ bend = au_sbend(sb);
28639+ for (; bindex <= bend; bindex++) {
28640+ br = au_sbr(sb, bindex);
392086de
AM
28641+ br_sysfs = br->br_sysfs;
28642+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28643+ sysfs_remove_file(kobj, &br_sysfs->attr);
28644+ br_sysfs++;
28645+ }
1facf9fc 28646+ }
28647+}
28648+
28649+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
28650+{
392086de 28651+ int err, i;
1facf9fc 28652+ aufs_bindex_t bend;
28653+ struct kobject *kobj;
28654+ struct au_branch *br;
392086de 28655+ struct au_brsysfs *br_sysfs;
1facf9fc 28656+
28657+ dbgaufs_brs_add(sb, bindex);
28658+
28659+ if (!sysaufs_brs)
28660+ return;
28661+
28662+ kobj = &au_sbi(sb)->si_kobj;
28663+ bend = au_sbend(sb);
28664+ for (; bindex <= bend; bindex++) {
28665+ br = au_sbr(sb, bindex);
392086de
AM
28666+ br_sysfs = br->br_sysfs;
28667+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
28668+ SysaufsBr_PREFIX "%d", bindex);
28669+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
28670+ SysaufsBrid_PREFIX "%d", bindex);
28671+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28672+ err = sysfs_create_file(kobj, &br_sysfs->attr);
28673+ if (unlikely(err))
28674+ pr_warn("failed %s under sysfs(%d)\n",
28675+ br_sysfs->name, err);
28676+ br_sysfs++;
28677+ }
1facf9fc 28678+ }
28679+}
7f207e10
AM
28680diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
28681--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
2000de60 28682+++ linux/fs/aufs/sysrq.c 2015-03-27 21:56:35.466795000 +0100
076b876e 28683@@ -0,0 +1,157 @@
1facf9fc 28684+/*
2000de60 28685+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28686+ *
28687+ * This program, aufs is free software; you can redistribute it and/or modify
28688+ * it under the terms of the GNU General Public License as published by
28689+ * the Free Software Foundation; either version 2 of the License, or
28690+ * (at your option) any later version.
dece6358
AM
28691+ *
28692+ * This program is distributed in the hope that it will be useful,
28693+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28694+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28695+ * GNU General Public License for more details.
28696+ *
28697+ * You should have received a copy of the GNU General Public License
523b37e3 28698+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28699+ */
28700+
28701+/*
28702+ * magic sysrq hanlder
28703+ */
28704+
1facf9fc 28705+/* #include <linux/sysrq.h> */
027c5e7a 28706+#include <linux/writeback.h>
1facf9fc 28707+#include "aufs.h"
28708+
28709+/* ---------------------------------------------------------------------- */
28710+
28711+static void sysrq_sb(struct super_block *sb)
28712+{
28713+ char *plevel;
28714+ struct au_sbinfo *sbinfo;
28715+ struct file *file;
523b37e3
AM
28716+ struct au_sphlhead *files;
28717+ struct au_finfo *finfo;
1facf9fc 28718+
28719+ plevel = au_plevel;
28720+ au_plevel = KERN_WARNING;
1facf9fc 28721+
4a4d8108 28722+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
28723+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
28724+
28725+ sbinfo = au_sbi(sb);
4a4d8108 28726+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 28727+ pr("superblock\n");
1facf9fc 28728+ au_dpri_sb(sb);
027c5e7a
AM
28729+
28730+#if 0
c06a8ce3 28731+ pr("root dentry\n");
1facf9fc 28732+ au_dpri_dentry(sb->s_root);
c06a8ce3 28733+ pr("root inode\n");
1facf9fc 28734+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
28735+#endif
28736+
1facf9fc 28737+#if 0
027c5e7a
AM
28738+ do {
28739+ int err, i, j, ndentry;
28740+ struct au_dcsub_pages dpages;
28741+ struct au_dpage *dpage;
28742+
28743+ err = au_dpages_init(&dpages, GFP_ATOMIC);
28744+ if (unlikely(err))
28745+ break;
28746+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
28747+ if (!err)
28748+ for (i = 0; i < dpages.ndpage; i++) {
28749+ dpage = dpages.dpages + i;
28750+ ndentry = dpage->ndentry;
28751+ for (j = 0; j < ndentry; j++)
28752+ au_dpri_dentry(dpage->dentries[j]);
28753+ }
28754+ au_dpages_free(&dpages);
28755+ } while (0);
28756+#endif
28757+
28758+#if 1
28759+ {
28760+ struct inode *i;
076b876e 28761+
c06a8ce3 28762+ pr("isolated inode\n");
2cbb1c4b
JR
28763+ spin_lock(&inode_sb_list_lock);
28764+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
28765+ spin_lock(&i->i_lock);
b4510431 28766+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 28767+ au_dpri_inode(i);
2cbb1c4b
JR
28768+ spin_unlock(&i->i_lock);
28769+ }
28770+ spin_unlock(&inode_sb_list_lock);
027c5e7a 28771+ }
1facf9fc 28772+#endif
c06a8ce3 28773+ pr("files\n");
523b37e3
AM
28774+ files = &au_sbi(sb)->si_files;
28775+ spin_lock(&files->spin);
28776+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
4a4d8108 28777+ umode_t mode;
076b876e 28778+
523b37e3 28779+ file = finfo->fi_file;
c06a8ce3 28780+ mode = file_inode(file)->i_mode;
38d290e6 28781+ if (!special_file(mode))
1facf9fc 28782+ au_dpri_file(file);
523b37e3
AM
28783+ }
28784+ spin_unlock(&files->spin);
c06a8ce3 28785+ pr("done\n");
1facf9fc 28786+
c06a8ce3 28787+#undef pr
1facf9fc 28788+ au_plevel = plevel;
1facf9fc 28789+}
28790+
28791+/* ---------------------------------------------------------------------- */
28792+
28793+/* module parameter */
28794+static char *aufs_sysrq_key = "a";
28795+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
28796+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
28797+
0c5527e5 28798+static void au_sysrq(int key __maybe_unused)
1facf9fc 28799+{
1facf9fc 28800+ struct au_sbinfo *sbinfo;
28801+
027c5e7a 28802+ lockdep_off();
53392da6 28803+ au_sbilist_lock();
e49829fe 28804+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 28805+ sysrq_sb(sbinfo->si_sb);
53392da6 28806+ au_sbilist_unlock();
027c5e7a 28807+ lockdep_on();
1facf9fc 28808+}
28809+
28810+static struct sysrq_key_op au_sysrq_op = {
28811+ .handler = au_sysrq,
28812+ .help_msg = "Aufs",
28813+ .action_msg = "Aufs",
28814+ .enable_mask = SYSRQ_ENABLE_DUMP
28815+};
28816+
28817+/* ---------------------------------------------------------------------- */
28818+
28819+int __init au_sysrq_init(void)
28820+{
28821+ int err;
28822+ char key;
28823+
28824+ err = -1;
28825+ key = *aufs_sysrq_key;
28826+ if ('a' <= key && key <= 'z')
28827+ err = register_sysrq_key(key, &au_sysrq_op);
28828+ if (unlikely(err))
4a4d8108 28829+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 28830+ return err;
28831+}
28832+
28833+void au_sysrq_fin(void)
28834+{
28835+ int err;
076b876e 28836+
1facf9fc 28837+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
28838+ if (unlikely(err))
4a4d8108 28839+ pr_err("err %d (ignored)\n", err);
1facf9fc 28840+}
7f207e10
AM
28841diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
28842--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
2000de60 28843+++ linux/fs/aufs/vdir.c 2015-03-27 21:56:35.466795000 +0100
076b876e 28844@@ -0,0 +1,889 @@
1facf9fc 28845+/*
2000de60 28846+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 28847+ *
28848+ * This program, aufs is free software; you can redistribute it and/or modify
28849+ * it under the terms of the GNU General Public License as published by
28850+ * the Free Software Foundation; either version 2 of the License, or
28851+ * (at your option) any later version.
dece6358
AM
28852+ *
28853+ * This program is distributed in the hope that it will be useful,
28854+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28855+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28856+ * GNU General Public License for more details.
28857+ *
28858+ * You should have received a copy of the GNU General Public License
523b37e3 28859+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28860+ */
28861+
28862+/*
28863+ * virtual or vertical directory
28864+ */
28865+
28866+#include "aufs.h"
28867+
dece6358 28868+static unsigned int calc_size(int nlen)
1facf9fc 28869+{
dece6358 28870+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 28871+}
28872+
28873+static int set_deblk_end(union au_vdir_deblk_p *p,
28874+ union au_vdir_deblk_p *deblk_end)
28875+{
28876+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
28877+ p->de->de_str.len = 0;
28878+ /* smp_mb(); */
28879+ return 0;
28880+ }
28881+ return -1; /* error */
28882+}
28883+
28884+/* returns true or false */
28885+static int is_deblk_end(union au_vdir_deblk_p *p,
28886+ union au_vdir_deblk_p *deblk_end)
28887+{
28888+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
28889+ return !p->de->de_str.len;
28890+ return 1;
28891+}
28892+
28893+static unsigned char *last_deblk(struct au_vdir *vdir)
28894+{
28895+ return vdir->vd_deblk[vdir->vd_nblk - 1];
28896+}
28897+
28898+/* ---------------------------------------------------------------------- */
28899+
1308ab2a 28900+/* estimate the apropriate size for name hash table */
28901+unsigned int au_rdhash_est(loff_t sz)
28902+{
28903+ unsigned int n;
28904+
28905+ n = UINT_MAX;
28906+ sz >>= 10;
28907+ if (sz < n)
28908+ n = sz;
28909+ if (sz < AUFS_RDHASH_DEF)
28910+ n = AUFS_RDHASH_DEF;
4a4d8108 28911+ /* pr_info("n %u\n", n); */
1308ab2a 28912+ return n;
28913+}
28914+
1facf9fc 28915+/*
28916+ * the allocated memory has to be freed by
dece6358 28917+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 28918+ */
dece6358 28919+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 28920+{
1facf9fc 28921+ struct hlist_head *head;
dece6358 28922+ unsigned int u;
076b876e 28923+ size_t sz;
1facf9fc 28924+
076b876e
AM
28925+ sz = sizeof(*nhash->nh_head) * num_hash;
28926+ head = kmalloc(sz, gfp);
dece6358
AM
28927+ if (head) {
28928+ nhash->nh_num = num_hash;
28929+ nhash->nh_head = head;
28930+ for (u = 0; u < num_hash; u++)
1facf9fc 28931+ INIT_HLIST_HEAD(head++);
dece6358 28932+ return 0; /* success */
1facf9fc 28933+ }
1facf9fc 28934+
dece6358 28935+ return -ENOMEM;
1facf9fc 28936+}
28937+
dece6358
AM
28938+static void nhash_count(struct hlist_head *head)
28939+{
28940+#if 0
28941+ unsigned long n;
28942+ struct hlist_node *pos;
28943+
28944+ n = 0;
28945+ hlist_for_each(pos, head)
28946+ n++;
4a4d8108 28947+ pr_info("%lu\n", n);
dece6358
AM
28948+#endif
28949+}
28950+
28951+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 28952+{
c06a8ce3
AM
28953+ struct au_vdir_wh *pos;
28954+ struct hlist_node *node;
1facf9fc 28955+
c06a8ce3
AM
28956+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
28957+ kfree(pos);
1facf9fc 28958+}
28959+
dece6358 28960+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 28961+{
c06a8ce3
AM
28962+ struct au_vdir_dehstr *pos;
28963+ struct hlist_node *node;
1facf9fc 28964+
c06a8ce3
AM
28965+ hlist_for_each_entry_safe(pos, node, head, hash)
28966+ au_cache_free_vdir_dehstr(pos);
1facf9fc 28967+}
28968+
dece6358
AM
28969+static void au_nhash_do_free(struct au_nhash *nhash,
28970+ void (*free)(struct hlist_head *head))
1facf9fc 28971+{
1308ab2a 28972+ unsigned int n;
1facf9fc 28973+ struct hlist_head *head;
1facf9fc 28974+
dece6358 28975+ n = nhash->nh_num;
1308ab2a 28976+ if (!n)
28977+ return;
28978+
dece6358 28979+ head = nhash->nh_head;
1308ab2a 28980+ while (n-- > 0) {
dece6358
AM
28981+ nhash_count(head);
28982+ free(head++);
1facf9fc 28983+ }
dece6358 28984+ kfree(nhash->nh_head);
1facf9fc 28985+}
28986+
dece6358 28987+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 28988+{
dece6358
AM
28989+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
28990+}
1facf9fc 28991+
dece6358
AM
28992+static void au_nhash_de_free(struct au_nhash *delist)
28993+{
28994+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 28995+}
28996+
28997+/* ---------------------------------------------------------------------- */
28998+
28999+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
29000+ int limit)
29001+{
29002+ int num;
29003+ unsigned int u, n;
29004+ struct hlist_head *head;
c06a8ce3 29005+ struct au_vdir_wh *pos;
1facf9fc 29006+
29007+ num = 0;
29008+ n = whlist->nh_num;
29009+ head = whlist->nh_head;
1308ab2a 29010+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
29011+ hlist_for_each_entry(pos, head, wh_hash)
29012+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 29013+ return 1;
1facf9fc 29014+ return 0;
29015+}
29016+
29017+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 29018+ unsigned char *name,
1facf9fc 29019+ unsigned int len)
29020+{
dece6358
AM
29021+ unsigned int v;
29022+ /* const unsigned int magic_bit = 12; */
29023+
1308ab2a 29024+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
29025+
dece6358
AM
29026+ v = 0;
29027+ while (len--)
29028+ v += *name++;
29029+ /* v = hash_long(v, magic_bit); */
29030+ v %= nhash->nh_num;
29031+ return nhash->nh_head + v;
29032+}
29033+
29034+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
29035+ int nlen)
29036+{
29037+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 29038+}
29039+
29040+/* returns found or not */
dece6358 29041+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 29042+{
29043+ struct hlist_head *head;
c06a8ce3 29044+ struct au_vdir_wh *pos;
1facf9fc 29045+ struct au_vdir_destr *str;
29046+
dece6358 29047+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
29048+ hlist_for_each_entry(pos, head, wh_hash) {
29049+ str = &pos->wh_str;
1facf9fc 29050+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
29051+ if (au_nhash_test_name(str, name, nlen))
29052+ return 1;
29053+ }
29054+ return 0;
29055+}
29056+
29057+/* returns found(true) or not */
29058+static int test_known(struct au_nhash *delist, char *name, int nlen)
29059+{
29060+ struct hlist_head *head;
c06a8ce3 29061+ struct au_vdir_dehstr *pos;
dece6358
AM
29062+ struct au_vdir_destr *str;
29063+
29064+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
29065+ hlist_for_each_entry(pos, head, hash) {
29066+ str = pos->str;
dece6358
AM
29067+ AuDbg("%.*s\n", str->len, str->name);
29068+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 29069+ return 1;
29070+ }
29071+ return 0;
29072+}
29073+
dece6358
AM
29074+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
29075+ unsigned char d_type)
29076+{
29077+#ifdef CONFIG_AUFS_SHWH
29078+ wh->wh_ino = ino;
29079+ wh->wh_type = d_type;
29080+#endif
29081+}
29082+
29083+/* ---------------------------------------------------------------------- */
29084+
29085+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
29086+ unsigned int d_type, aufs_bindex_t bindex,
29087+ unsigned char shwh)
1facf9fc 29088+{
29089+ int err;
29090+ struct au_vdir_destr *str;
29091+ struct au_vdir_wh *wh;
29092+
dece6358 29093+ AuDbg("%.*s\n", nlen, name);
1308ab2a 29094+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
29095+
1facf9fc 29096+ err = -ENOMEM;
dece6358 29097+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 29098+ if (unlikely(!wh))
29099+ goto out;
29100+
29101+ err = 0;
29102+ wh->wh_bindex = bindex;
dece6358
AM
29103+ if (shwh)
29104+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 29105+ str = &wh->wh_str;
dece6358
AM
29106+ str->len = nlen;
29107+ memcpy(str->name, name, nlen);
29108+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 29109+ /* smp_mb(); */
29110+
4f0767ce 29111+out:
1facf9fc 29112+ return err;
29113+}
29114+
1facf9fc 29115+static int append_deblk(struct au_vdir *vdir)
29116+{
29117+ int err;
dece6358 29118+ unsigned long ul;
1facf9fc 29119+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
29120+ union au_vdir_deblk_p p, deblk_end;
29121+ unsigned char **o;
29122+
29123+ err = -ENOMEM;
dece6358
AM
29124+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
29125+ GFP_NOFS);
1facf9fc 29126+ if (unlikely(!o))
29127+ goto out;
29128+
29129+ vdir->vd_deblk = o;
29130+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
29131+ if (p.deblk) {
29132+ ul = vdir->vd_nblk++;
29133+ vdir->vd_deblk[ul] = p.deblk;
29134+ vdir->vd_last.ul = ul;
29135+ vdir->vd_last.p.deblk = p.deblk;
29136+ deblk_end.deblk = p.deblk + deblk_sz;
29137+ err = set_deblk_end(&p, &deblk_end);
29138+ }
29139+
4f0767ce 29140+out:
1facf9fc 29141+ return err;
29142+}
29143+
dece6358
AM
29144+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
29145+ unsigned int d_type, struct au_nhash *delist)
29146+{
29147+ int err;
29148+ unsigned int sz;
29149+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
29150+ union au_vdir_deblk_p p, *room, deblk_end;
29151+ struct au_vdir_dehstr *dehstr;
29152+
29153+ p.deblk = last_deblk(vdir);
29154+ deblk_end.deblk = p.deblk + deblk_sz;
29155+ room = &vdir->vd_last.p;
29156+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
29157+ || !is_deblk_end(room, &deblk_end));
29158+
29159+ sz = calc_size(nlen);
29160+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
29161+ err = append_deblk(vdir);
29162+ if (unlikely(err))
29163+ goto out;
29164+
29165+ p.deblk = last_deblk(vdir);
29166+ deblk_end.deblk = p.deblk + deblk_sz;
29167+ /* smp_mb(); */
29168+ AuDebugOn(room->deblk != p.deblk);
29169+ }
29170+
29171+ err = -ENOMEM;
4a4d8108 29172+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
29173+ if (unlikely(!dehstr))
29174+ goto out;
29175+
29176+ dehstr->str = &room->de->de_str;
29177+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
29178+ room->de->de_ino = ino;
29179+ room->de->de_type = d_type;
29180+ room->de->de_str.len = nlen;
29181+ memcpy(room->de->de_str.name, name, nlen);
29182+
29183+ err = 0;
29184+ room->deblk += sz;
29185+ if (unlikely(set_deblk_end(room, &deblk_end)))
29186+ err = append_deblk(vdir);
29187+ /* smp_mb(); */
29188+
4f0767ce 29189+out:
dece6358
AM
29190+ return err;
29191+}
29192+
29193+/* ---------------------------------------------------------------------- */
29194+
29195+void au_vdir_free(struct au_vdir *vdir)
29196+{
29197+ unsigned char **deblk;
29198+
29199+ deblk = vdir->vd_deblk;
29200+ while (vdir->vd_nblk--)
29201+ kfree(*deblk++);
29202+ kfree(vdir->vd_deblk);
29203+ au_cache_free_vdir(vdir);
29204+}
29205+
1308ab2a 29206+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 29207+{
29208+ struct au_vdir *vdir;
1308ab2a 29209+ struct super_block *sb;
1facf9fc 29210+ int err;
29211+
2000de60 29212+ sb = file->f_path.dentry->d_sb;
dece6358
AM
29213+ SiMustAnyLock(sb);
29214+
1facf9fc 29215+ err = -ENOMEM;
29216+ vdir = au_cache_alloc_vdir();
29217+ if (unlikely(!vdir))
29218+ goto out;
29219+
29220+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
29221+ if (unlikely(!vdir->vd_deblk))
29222+ goto out_free;
29223+
29224+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 29225+ if (!vdir->vd_deblk_sz) {
29226+ /* estimate the apropriate size for deblk */
29227+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 29228+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 29229+ }
1facf9fc 29230+ vdir->vd_nblk = 0;
29231+ vdir->vd_version = 0;
29232+ vdir->vd_jiffy = 0;
29233+ err = append_deblk(vdir);
29234+ if (!err)
29235+ return vdir; /* success */
29236+
29237+ kfree(vdir->vd_deblk);
29238+
4f0767ce 29239+out_free:
1facf9fc 29240+ au_cache_free_vdir(vdir);
4f0767ce 29241+out:
1facf9fc 29242+ vdir = ERR_PTR(err);
29243+ return vdir;
29244+}
29245+
29246+static int reinit_vdir(struct au_vdir *vdir)
29247+{
29248+ int err;
29249+ union au_vdir_deblk_p p, deblk_end;
29250+
29251+ while (vdir->vd_nblk > 1) {
29252+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
29253+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
29254+ vdir->vd_nblk--;
29255+ }
29256+ p.deblk = vdir->vd_deblk[0];
29257+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
29258+ err = set_deblk_end(&p, &deblk_end);
29259+ /* keep vd_dblk_sz */
29260+ vdir->vd_last.ul = 0;
29261+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
29262+ vdir->vd_version = 0;
29263+ vdir->vd_jiffy = 0;
29264+ /* smp_mb(); */
29265+ return err;
29266+}
29267+
29268+/* ---------------------------------------------------------------------- */
29269+
1facf9fc 29270+#define AuFillVdir_CALLED 1
29271+#define AuFillVdir_WHABLE (1 << 1)
dece6358 29272+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 29273+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
29274+#define au_fset_fillvdir(flags, name) \
29275+ do { (flags) |= AuFillVdir_##name; } while (0)
29276+#define au_fclr_fillvdir(flags, name) \
29277+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 29278+
dece6358
AM
29279+#ifndef CONFIG_AUFS_SHWH
29280+#undef AuFillVdir_SHWH
29281+#define AuFillVdir_SHWH 0
29282+#endif
29283+
1facf9fc 29284+struct fillvdir_arg {
392086de 29285+ struct dir_context ctx;
1facf9fc 29286+ struct file *file;
29287+ struct au_vdir *vdir;
dece6358
AM
29288+ struct au_nhash delist;
29289+ struct au_nhash whlist;
1facf9fc 29290+ aufs_bindex_t bindex;
29291+ unsigned int flags;
29292+ int err;
29293+};
29294+
392086de 29295+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 29296+ loff_t offset __maybe_unused, u64 h_ino,
29297+ unsigned int d_type)
29298+{
392086de 29299+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 29300+ char *name = (void *)__name;
29301+ struct super_block *sb;
1facf9fc 29302+ ino_t ino;
dece6358 29303+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 29304+
1facf9fc 29305+ arg->err = 0;
2000de60 29306+ sb = arg->file->f_path.dentry->d_sb;
1facf9fc 29307+ au_fset_fillvdir(arg->flags, CALLED);
29308+ /* smp_mb(); */
dece6358 29309+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 29310+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
29311+ if (test_known(&arg->delist, name, nlen)
29312+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
29313+ goto out; /* already exists or whiteouted */
1facf9fc 29314+
2000de60 29315+ sb = arg->file->f_path.dentry->d_sb;
dece6358 29316+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
29317+ if (!arg->err) {
29318+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
29319+ d_type = DT_UNKNOWN;
dece6358
AM
29320+ arg->err = append_de(arg->vdir, name, nlen, ino,
29321+ d_type, &arg->delist);
4a4d8108 29322+ }
1facf9fc 29323+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
29324+ name += AUFS_WH_PFX_LEN;
dece6358
AM
29325+ nlen -= AUFS_WH_PFX_LEN;
29326+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
29327+ goto out; /* already whiteouted */
1facf9fc 29328+
dece6358
AM
29329+ if (shwh)
29330+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
29331+ &ino);
4a4d8108
AM
29332+ if (!arg->err) {
29333+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
29334+ d_type = DT_UNKNOWN;
1facf9fc 29335+ arg->err = au_nhash_append_wh
dece6358
AM
29336+ (&arg->whlist, name, nlen, ino, d_type,
29337+ arg->bindex, shwh);
4a4d8108 29338+ }
1facf9fc 29339+ }
29340+
4f0767ce 29341+out:
1facf9fc 29342+ if (!arg->err)
29343+ arg->vdir->vd_jiffy = jiffies;
29344+ /* smp_mb(); */
29345+ AuTraceErr(arg->err);
29346+ return arg->err;
29347+}
29348+
dece6358
AM
29349+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
29350+ struct au_nhash *whlist, struct au_nhash *delist)
29351+{
29352+#ifdef CONFIG_AUFS_SHWH
29353+ int err;
29354+ unsigned int nh, u;
29355+ struct hlist_head *head;
c06a8ce3
AM
29356+ struct au_vdir_wh *pos;
29357+ struct hlist_node *n;
dece6358
AM
29358+ char *p, *o;
29359+ struct au_vdir_destr *destr;
29360+
29361+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
29362+
29363+ err = -ENOMEM;
537831f9 29364+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
29365+ if (unlikely(!p))
29366+ goto out;
29367+
29368+ err = 0;
29369+ nh = whlist->nh_num;
29370+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29371+ p += AUFS_WH_PFX_LEN;
29372+ for (u = 0; u < nh; u++) {
29373+ head = whlist->nh_head + u;
c06a8ce3
AM
29374+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
29375+ destr = &pos->wh_str;
dece6358
AM
29376+ memcpy(p, destr->name, destr->len);
29377+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 29378+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
29379+ if (unlikely(err))
29380+ break;
29381+ }
29382+ }
29383+
537831f9 29384+ free_page((unsigned long)o);
dece6358 29385+
4f0767ce 29386+out:
dece6358
AM
29387+ AuTraceErr(err);
29388+ return err;
29389+#else
29390+ return 0;
29391+#endif
29392+}
29393+
1facf9fc 29394+static int au_do_read_vdir(struct fillvdir_arg *arg)
29395+{
29396+ int err;
dece6358 29397+ unsigned int rdhash;
1facf9fc 29398+ loff_t offset;
dece6358
AM
29399+ aufs_bindex_t bend, bindex, bstart;
29400+ unsigned char shwh;
1facf9fc 29401+ struct file *hf, *file;
29402+ struct super_block *sb;
29403+
1facf9fc 29404+ file = arg->file;
2000de60 29405+ sb = file->f_path.dentry->d_sb;
dece6358
AM
29406+ SiMustAnyLock(sb);
29407+
29408+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 29409+ if (!rdhash)
29410+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
29411+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
29412+ if (unlikely(err))
1facf9fc 29413+ goto out;
dece6358
AM
29414+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
29415+ if (unlikely(err))
1facf9fc 29416+ goto out_delist;
29417+
29418+ err = 0;
29419+ arg->flags = 0;
dece6358
AM
29420+ shwh = 0;
29421+ if (au_opt_test(au_mntflags(sb), SHWH)) {
29422+ shwh = 1;
29423+ au_fset_fillvdir(arg->flags, SHWH);
29424+ }
29425+ bstart = au_fbstart(file);
4a4d8108 29426+ bend = au_fbend_dir(file);
dece6358 29427+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 29428+ hf = au_hf_dir(file, bindex);
1facf9fc 29429+ if (!hf)
29430+ continue;
29431+
29432+ offset = vfsub_llseek(hf, 0, SEEK_SET);
29433+ err = offset;
29434+ if (unlikely(offset))
29435+ break;
29436+
29437+ arg->bindex = bindex;
29438+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
29439+ if (shwh
29440+ || (bindex != bend
29441+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 29442+ au_fset_fillvdir(arg->flags, WHABLE);
29443+ do {
29444+ arg->err = 0;
29445+ au_fclr_fillvdir(arg->flags, CALLED);
29446+ /* smp_mb(); */
392086de 29447+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 29448+ if (err >= 0)
29449+ err = arg->err;
29450+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
29451+
29452+ /*
29453+ * dir_relax() may be good for concurrency, but aufs should not
29454+ * use it since it will cause a lockdep problem.
29455+ */
1facf9fc 29456+ }
dece6358
AM
29457+
29458+ if (!err && shwh)
29459+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
29460+
29461+ au_nhash_wh_free(&arg->whlist);
1facf9fc 29462+
4f0767ce 29463+out_delist:
dece6358 29464+ au_nhash_de_free(&arg->delist);
4f0767ce 29465+out:
1facf9fc 29466+ return err;
29467+}
29468+
29469+static int read_vdir(struct file *file, int may_read)
29470+{
29471+ int err;
29472+ unsigned long expire;
29473+ unsigned char do_read;
392086de
AM
29474+ struct fillvdir_arg arg = {
29475+ .ctx = {
2000de60 29476+ .actor = fillvdir
392086de
AM
29477+ }
29478+ };
1facf9fc 29479+ struct inode *inode;
29480+ struct au_vdir *vdir, *allocated;
29481+
29482+ err = 0;
c06a8ce3 29483+ inode = file_inode(file);
1facf9fc 29484+ IMustLock(inode);
dece6358
AM
29485+ SiMustAnyLock(inode->i_sb);
29486+
1facf9fc 29487+ allocated = NULL;
29488+ do_read = 0;
29489+ expire = au_sbi(inode->i_sb)->si_rdcache;
29490+ vdir = au_ivdir(inode);
29491+ if (!vdir) {
29492+ do_read = 1;
1308ab2a 29493+ vdir = alloc_vdir(file);
1facf9fc 29494+ err = PTR_ERR(vdir);
29495+ if (IS_ERR(vdir))
29496+ goto out;
29497+ err = 0;
29498+ allocated = vdir;
29499+ } else if (may_read
29500+ && (inode->i_version != vdir->vd_version
29501+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
29502+ do_read = 1;
29503+ err = reinit_vdir(vdir);
29504+ if (unlikely(err))
29505+ goto out;
29506+ }
29507+
29508+ if (!do_read)
29509+ return 0; /* success */
29510+
29511+ arg.file = file;
29512+ arg.vdir = vdir;
29513+ err = au_do_read_vdir(&arg);
29514+ if (!err) {
392086de 29515+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 29516+ vdir->vd_version = inode->i_version;
29517+ vdir->vd_last.ul = 0;
29518+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
29519+ if (allocated)
29520+ au_set_ivdir(inode, allocated);
29521+ } else if (allocated)
29522+ au_vdir_free(allocated);
29523+
4f0767ce 29524+out:
1facf9fc 29525+ return err;
29526+}
29527+
29528+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
29529+{
29530+ int err, rerr;
29531+ unsigned long ul, n;
29532+ const unsigned int deblk_sz = src->vd_deblk_sz;
29533+
29534+ AuDebugOn(tgt->vd_nblk != 1);
29535+
29536+ err = -ENOMEM;
29537+ if (tgt->vd_nblk < src->vd_nblk) {
29538+ unsigned char **p;
29539+
dece6358
AM
29540+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
29541+ GFP_NOFS);
1facf9fc 29542+ if (unlikely(!p))
29543+ goto out;
29544+ tgt->vd_deblk = p;
29545+ }
29546+
1308ab2a 29547+ if (tgt->vd_deblk_sz != deblk_sz) {
29548+ unsigned char *p;
29549+
29550+ tgt->vd_deblk_sz = deblk_sz;
29551+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
29552+ if (unlikely(!p))
29553+ goto out;
29554+ tgt->vd_deblk[0] = p;
29555+ }
1facf9fc 29556+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 29557+ tgt->vd_version = src->vd_version;
29558+ tgt->vd_jiffy = src->vd_jiffy;
29559+
29560+ n = src->vd_nblk;
29561+ for (ul = 1; ul < n; ul++) {
dece6358
AM
29562+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
29563+ GFP_NOFS);
29564+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 29565+ goto out;
1308ab2a 29566+ tgt->vd_nblk++;
1facf9fc 29567+ }
1308ab2a 29568+ tgt->vd_nblk = n;
29569+ tgt->vd_last.ul = tgt->vd_last.ul;
29570+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
29571+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
29572+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 29573+ /* smp_mb(); */
29574+ return 0; /* success */
29575+
4f0767ce 29576+out:
1facf9fc 29577+ rerr = reinit_vdir(tgt);
29578+ BUG_ON(rerr);
29579+ return err;
29580+}
29581+
29582+int au_vdir_init(struct file *file)
29583+{
29584+ int err;
29585+ struct inode *inode;
29586+ struct au_vdir *vdir_cache, *allocated;
29587+
392086de 29588+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 29589+ err = read_vdir(file, !file->f_pos);
29590+ if (unlikely(err))
29591+ goto out;
29592+
29593+ allocated = NULL;
29594+ vdir_cache = au_fvdir_cache(file);
29595+ if (!vdir_cache) {
1308ab2a 29596+ vdir_cache = alloc_vdir(file);
1facf9fc 29597+ err = PTR_ERR(vdir_cache);
29598+ if (IS_ERR(vdir_cache))
29599+ goto out;
29600+ allocated = vdir_cache;
29601+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 29602+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 29603+ err = reinit_vdir(vdir_cache);
29604+ if (unlikely(err))
29605+ goto out;
29606+ } else
29607+ return 0; /* success */
29608+
c06a8ce3 29609+ inode = file_inode(file);
1facf9fc 29610+ err = copy_vdir(vdir_cache, au_ivdir(inode));
29611+ if (!err) {
29612+ file->f_version = inode->i_version;
29613+ if (allocated)
29614+ au_set_fvdir_cache(file, allocated);
29615+ } else if (allocated)
29616+ au_vdir_free(allocated);
29617+
4f0767ce 29618+out:
1facf9fc 29619+ return err;
29620+}
29621+
29622+static loff_t calc_offset(struct au_vdir *vdir)
29623+{
29624+ loff_t offset;
29625+ union au_vdir_deblk_p p;
29626+
29627+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
29628+ offset = vdir->vd_last.p.deblk - p.deblk;
29629+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
29630+ return offset;
29631+}
29632+
29633+/* returns true or false */
392086de 29634+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 29635+{
29636+ int valid;
29637+ unsigned int deblk_sz;
29638+ unsigned long ul, n;
29639+ loff_t offset;
29640+ union au_vdir_deblk_p p, deblk_end;
29641+ struct au_vdir *vdir_cache;
29642+
29643+ valid = 1;
29644+ vdir_cache = au_fvdir_cache(file);
29645+ offset = calc_offset(vdir_cache);
29646+ AuDbg("offset %lld\n", offset);
392086de 29647+ if (ctx->pos == offset)
1facf9fc 29648+ goto out;
29649+
29650+ vdir_cache->vd_last.ul = 0;
29651+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 29652+ if (!ctx->pos)
1facf9fc 29653+ goto out;
29654+
29655+ valid = 0;
29656+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 29657+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 29658+ AuDbg("ul %lu\n", ul);
29659+ if (ul >= vdir_cache->vd_nblk)
29660+ goto out;
29661+
29662+ n = vdir_cache->vd_nblk;
29663+ for (; ul < n; ul++) {
29664+ p.deblk = vdir_cache->vd_deblk[ul];
29665+ deblk_end.deblk = p.deblk + deblk_sz;
29666+ offset = ul;
29667+ offset *= deblk_sz;
392086de 29668+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 29669+ unsigned int l;
29670+
29671+ l = calc_size(p.de->de_str.len);
29672+ offset += l;
29673+ p.deblk += l;
29674+ }
29675+ if (!is_deblk_end(&p, &deblk_end)) {
29676+ valid = 1;
29677+ vdir_cache->vd_last.ul = ul;
29678+ vdir_cache->vd_last.p = p;
29679+ break;
29680+ }
29681+ }
29682+
4f0767ce 29683+out:
1facf9fc 29684+ /* smp_mb(); */
29685+ AuTraceErr(!valid);
29686+ return valid;
29687+}
29688+
392086de 29689+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 29690+{
1facf9fc 29691+ unsigned int l, deblk_sz;
29692+ union au_vdir_deblk_p deblk_end;
29693+ struct au_vdir *vdir_cache;
29694+ struct au_vdir_de *de;
29695+
29696+ vdir_cache = au_fvdir_cache(file);
392086de 29697+ if (!seek_vdir(file, ctx))
1facf9fc 29698+ return 0;
29699+
29700+ deblk_sz = vdir_cache->vd_deblk_sz;
29701+ while (1) {
29702+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
29703+ deblk_end.deblk += deblk_sz;
29704+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
29705+ de = vdir_cache->vd_last.p.de;
29706+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 29707+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 29708+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
29709+ if (unlikely(!dir_emit(ctx, de->de_str.name,
29710+ de->de_str.len, de->de_ino,
29711+ de->de_type))) {
1facf9fc 29712+ /* todo: ignore the error caused by udba? */
29713+ /* return err; */
29714+ return 0;
29715+ }
29716+
29717+ l = calc_size(de->de_str.len);
29718+ vdir_cache->vd_last.p.deblk += l;
392086de 29719+ ctx->pos += l;
1facf9fc 29720+ }
29721+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
29722+ vdir_cache->vd_last.ul++;
29723+ vdir_cache->vd_last.p.deblk
29724+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 29725+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 29726+ continue;
29727+ }
29728+ break;
29729+ }
29730+
29731+ /* smp_mb(); */
29732+ return 0;
29733+}
7f207e10
AM
29734diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
29735--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
2000de60 29736+++ linux/fs/aufs/vfsub.c 2015-03-27 21:56:35.470128334 +0100
c1595e42 29737@@ -0,0 +1,796 @@
1facf9fc 29738+/*
2000de60 29739+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 29740+ *
29741+ * This program, aufs is free software; you can redistribute it and/or modify
29742+ * it under the terms of the GNU General Public License as published by
29743+ * the Free Software Foundation; either version 2 of the License, or
29744+ * (at your option) any later version.
dece6358
AM
29745+ *
29746+ * This program is distributed in the hope that it will be useful,
29747+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29748+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29749+ * GNU General Public License for more details.
29750+ *
29751+ * You should have received a copy of the GNU General Public License
523b37e3 29752+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29753+ */
29754+
29755+/*
29756+ * sub-routines for VFS
29757+ */
29758+
1308ab2a 29759+#include <linux/ima.h>
dece6358
AM
29760+#include <linux/namei.h>
29761+#include <linux/security.h>
29762+#include <linux/splice.h>
1facf9fc 29763+#include "aufs.h"
29764+
29765+int vfsub_update_h_iattr(struct path *h_path, int *did)
29766+{
29767+ int err;
29768+ struct kstat st;
29769+ struct super_block *h_sb;
29770+
29771+ /* for remote fs, leave work for its getattr or d_revalidate */
29772+ /* for bad i_attr fs, handle them in aufs_getattr() */
29773+ /* still some fs may acquire i_mutex. we need to skip them */
29774+ err = 0;
29775+ if (!did)
29776+ did = &err;
29777+ h_sb = h_path->dentry->d_sb;
29778+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
29779+ if (*did)
c06a8ce3 29780+ err = vfs_getattr(h_path, &st);
1facf9fc 29781+
29782+ return err;
29783+}
29784+
29785+/* ---------------------------------------------------------------------- */
29786+
4a4d8108 29787+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 29788+{
29789+ struct file *file;
29790+
b4510431 29791+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 29792+ current_cred());
2cbb1c4b
JR
29793+ if (!IS_ERR_OR_NULL(file)
29794+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
29795+ i_readcount_inc(path->dentry->d_inode);
4a4d8108 29796+
1308ab2a 29797+ return file;
29798+}
29799+
1facf9fc 29800+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
29801+{
29802+ struct file *file;
29803+
2cbb1c4b 29804+ lockdep_off();
7f207e10 29805+ file = filp_open(path,
2cbb1c4b 29806+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 29807+ mode);
2cbb1c4b 29808+ lockdep_on();
1facf9fc 29809+ if (IS_ERR(file))
29810+ goto out;
29811+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29812+
4f0767ce 29813+out:
1facf9fc 29814+ return file;
29815+}
29816+
29817+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
29818+{
29819+ int err;
29820+
1facf9fc 29821+ err = kern_path(name, flags, path);
1facf9fc 29822+ if (!err && path->dentry->d_inode)
29823+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
29824+ return err;
29825+}
29826+
29827+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
29828+ int len)
29829+{
29830+ struct path path = {
29831+ .mnt = NULL
29832+ };
29833+
1308ab2a 29834+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 29835+ IMustLock(parent->d_inode);
29836+
29837+ path.dentry = lookup_one_len(name, parent, len);
29838+ if (IS_ERR(path.dentry))
29839+ goto out;
29840+ if (path.dentry->d_inode)
29841+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
29842+
4f0767ce 29843+out:
4a4d8108 29844+ AuTraceErrPtr(path.dentry);
1facf9fc 29845+ return path.dentry;
29846+}
29847+
b4510431 29848+void vfsub_call_lkup_one(void *args)
2cbb1c4b 29849+{
b4510431
AM
29850+ struct vfsub_lkup_one_args *a = args;
29851+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
29852+}
29853+
1facf9fc 29854+/* ---------------------------------------------------------------------- */
29855+
29856+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
29857+ struct dentry *d2, struct au_hinode *hdir2)
29858+{
29859+ struct dentry *d;
29860+
2cbb1c4b 29861+ lockdep_off();
1facf9fc 29862+ d = lock_rename(d1, d2);
2cbb1c4b 29863+ lockdep_on();
4a4d8108 29864+ au_hn_suspend(hdir1);
1facf9fc 29865+ if (hdir1 != hdir2)
4a4d8108 29866+ au_hn_suspend(hdir2);
1facf9fc 29867+
29868+ return d;
29869+}
29870+
29871+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
29872+ struct dentry *d2, struct au_hinode *hdir2)
29873+{
4a4d8108 29874+ au_hn_resume(hdir1);
1facf9fc 29875+ if (hdir1 != hdir2)
4a4d8108 29876+ au_hn_resume(hdir2);
2cbb1c4b 29877+ lockdep_off();
1facf9fc 29878+ unlock_rename(d1, d2);
2cbb1c4b 29879+ lockdep_on();
1facf9fc 29880+}
29881+
29882+/* ---------------------------------------------------------------------- */
29883+
b4510431 29884+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 29885+{
29886+ int err;
29887+ struct dentry *d;
29888+
29889+ IMustLock(dir);
29890+
29891+ d = path->dentry;
29892+ path->dentry = d->d_parent;
b752ccd1 29893+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 29894+ path->dentry = d;
29895+ if (unlikely(err))
29896+ goto out;
29897+
c1595e42 29898+ lockdep_off();
b4510431 29899+ err = vfs_create(dir, path->dentry, mode, want_excl);
c1595e42 29900+ lockdep_on();
1facf9fc 29901+ if (!err) {
29902+ struct path tmp = *path;
29903+ int did;
29904+
29905+ vfsub_update_h_iattr(&tmp, &did);
29906+ if (did) {
29907+ tmp.dentry = path->dentry->d_parent;
29908+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29909+ }
29910+ /*ignore*/
29911+ }
29912+
4f0767ce 29913+out:
1facf9fc 29914+ return err;
29915+}
29916+
29917+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
29918+{
29919+ int err;
29920+ struct dentry *d;
29921+
29922+ IMustLock(dir);
29923+
29924+ d = path->dentry;
29925+ path->dentry = d->d_parent;
b752ccd1 29926+ err = security_path_symlink(path, d, symname);
1facf9fc 29927+ path->dentry = d;
29928+ if (unlikely(err))
29929+ goto out;
29930+
c1595e42 29931+ lockdep_off();
1facf9fc 29932+ err = vfs_symlink(dir, path->dentry, symname);
c1595e42 29933+ lockdep_on();
1facf9fc 29934+ if (!err) {
29935+ struct path tmp = *path;
29936+ int did;
29937+
29938+ vfsub_update_h_iattr(&tmp, &did);
29939+ if (did) {
29940+ tmp.dentry = path->dentry->d_parent;
29941+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29942+ }
29943+ /*ignore*/
29944+ }
29945+
4f0767ce 29946+out:
1facf9fc 29947+ return err;
29948+}
29949+
29950+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
29951+{
29952+ int err;
29953+ struct dentry *d;
29954+
29955+ IMustLock(dir);
29956+
29957+ d = path->dentry;
29958+ path->dentry = d->d_parent;
027c5e7a 29959+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 29960+ path->dentry = d;
29961+ if (unlikely(err))
29962+ goto out;
29963+
c1595e42 29964+ lockdep_off();
1facf9fc 29965+ err = vfs_mknod(dir, path->dentry, mode, dev);
c1595e42 29966+ lockdep_on();
1facf9fc 29967+ if (!err) {
29968+ struct path tmp = *path;
29969+ int did;
29970+
29971+ vfsub_update_h_iattr(&tmp, &did);
29972+ if (did) {
29973+ tmp.dentry = path->dentry->d_parent;
29974+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29975+ }
29976+ /*ignore*/
29977+ }
29978+
4f0767ce 29979+out:
1facf9fc 29980+ return err;
29981+}
29982+
29983+static int au_test_nlink(struct inode *inode)
29984+{
29985+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
29986+
29987+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
29988+ || inode->i_nlink < link_max)
29989+ return 0;
29990+ return -EMLINK;
29991+}
29992+
523b37e3
AM
29993+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
29994+ struct inode **delegated_inode)
1facf9fc 29995+{
29996+ int err;
29997+ struct dentry *d;
29998+
29999+ IMustLock(dir);
30000+
30001+ err = au_test_nlink(src_dentry->d_inode);
30002+ if (unlikely(err))
30003+ return err;
30004+
b4510431 30005+ /* we don't call may_linkat() */
1facf9fc 30006+ d = path->dentry;
30007+ path->dentry = d->d_parent;
b752ccd1 30008+ err = security_path_link(src_dentry, path, d);
1facf9fc 30009+ path->dentry = d;
30010+ if (unlikely(err))
30011+ goto out;
30012+
2cbb1c4b 30013+ lockdep_off();
523b37e3 30014+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 30015+ lockdep_on();
1facf9fc 30016+ if (!err) {
30017+ struct path tmp = *path;
30018+ int did;
30019+
30020+ /* fuse has different memory inode for the same inumber */
30021+ vfsub_update_h_iattr(&tmp, &did);
30022+ if (did) {
30023+ tmp.dentry = path->dentry->d_parent;
30024+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30025+ tmp.dentry = src_dentry;
30026+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30027+ }
30028+ /*ignore*/
30029+ }
30030+
4f0767ce 30031+out:
1facf9fc 30032+ return err;
30033+}
30034+
30035+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3
AM
30036+ struct inode *dir, struct path *path,
30037+ struct inode **delegated_inode)
1facf9fc 30038+{
30039+ int err;
30040+ struct path tmp = {
30041+ .mnt = path->mnt
30042+ };
30043+ struct dentry *d;
30044+
30045+ IMustLock(dir);
30046+ IMustLock(src_dir);
30047+
30048+ d = path->dentry;
30049+ path->dentry = d->d_parent;
30050+ tmp.dentry = src_dentry->d_parent;
38d290e6 30051+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 30052+ path->dentry = d;
30053+ if (unlikely(err))
30054+ goto out;
30055+
2cbb1c4b 30056+ lockdep_off();
523b37e3 30057+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
38d290e6 30058+ delegated_inode, /*flags*/0);
2cbb1c4b 30059+ lockdep_on();
1facf9fc 30060+ if (!err) {
30061+ int did;
30062+
30063+ tmp.dentry = d->d_parent;
30064+ vfsub_update_h_iattr(&tmp, &did);
30065+ if (did) {
30066+ tmp.dentry = src_dentry;
30067+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30068+ tmp.dentry = src_dentry->d_parent;
30069+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30070+ }
30071+ /*ignore*/
30072+ }
30073+
4f0767ce 30074+out:
1facf9fc 30075+ return err;
30076+}
30077+
30078+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
30079+{
30080+ int err;
30081+ struct dentry *d;
30082+
30083+ IMustLock(dir);
30084+
30085+ d = path->dentry;
30086+ path->dentry = d->d_parent;
b752ccd1 30087+ err = security_path_mkdir(path, d, mode);
1facf9fc 30088+ path->dentry = d;
30089+ if (unlikely(err))
30090+ goto out;
30091+
c1595e42 30092+ lockdep_off();
1facf9fc 30093+ err = vfs_mkdir(dir, path->dentry, mode);
c1595e42 30094+ lockdep_on();
1facf9fc 30095+ if (!err) {
30096+ struct path tmp = *path;
30097+ int did;
30098+
30099+ vfsub_update_h_iattr(&tmp, &did);
30100+ if (did) {
30101+ tmp.dentry = path->dentry->d_parent;
30102+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30103+ }
30104+ /*ignore*/
30105+ }
30106+
4f0767ce 30107+out:
1facf9fc 30108+ return err;
30109+}
30110+
30111+int vfsub_rmdir(struct inode *dir, struct path *path)
30112+{
30113+ int err;
30114+ struct dentry *d;
30115+
30116+ IMustLock(dir);
30117+
30118+ d = path->dentry;
30119+ path->dentry = d->d_parent;
b752ccd1 30120+ err = security_path_rmdir(path, d);
1facf9fc 30121+ path->dentry = d;
30122+ if (unlikely(err))
30123+ goto out;
30124+
2cbb1c4b 30125+ lockdep_off();
1facf9fc 30126+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 30127+ lockdep_on();
1facf9fc 30128+ if (!err) {
30129+ struct path tmp = {
30130+ .dentry = path->dentry->d_parent,
30131+ .mnt = path->mnt
30132+ };
30133+
30134+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
30135+ }
30136+
4f0767ce 30137+out:
1facf9fc 30138+ return err;
30139+}
30140+
30141+/* ---------------------------------------------------------------------- */
30142+
9dbd164d 30143+/* todo: support mmap_sem? */
1facf9fc 30144+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
30145+ loff_t *ppos)
30146+{
30147+ ssize_t err;
30148+
2cbb1c4b 30149+ lockdep_off();
1facf9fc 30150+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 30151+ lockdep_on();
1facf9fc 30152+ if (err >= 0)
30153+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30154+ return err;
30155+}
30156+
30157+/* todo: kernel_read()? */
30158+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
30159+ loff_t *ppos)
30160+{
30161+ ssize_t err;
30162+ mm_segment_t oldfs;
b752ccd1
AM
30163+ union {
30164+ void *k;
30165+ char __user *u;
30166+ } buf;
1facf9fc 30167+
b752ccd1 30168+ buf.k = kbuf;
1facf9fc 30169+ oldfs = get_fs();
30170+ set_fs(KERNEL_DS);
b752ccd1 30171+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 30172+ set_fs(oldfs);
30173+ return err;
30174+}
30175+
30176+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
30177+ loff_t *ppos)
30178+{
30179+ ssize_t err;
30180+
2cbb1c4b 30181+ lockdep_off();
1facf9fc 30182+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 30183+ lockdep_on();
1facf9fc 30184+ if (err >= 0)
30185+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30186+ return err;
30187+}
30188+
30189+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
30190+{
30191+ ssize_t err;
30192+ mm_segment_t oldfs;
b752ccd1
AM
30193+ union {
30194+ void *k;
30195+ const char __user *u;
30196+ } buf;
1facf9fc 30197+
b752ccd1 30198+ buf.k = kbuf;
1facf9fc 30199+ oldfs = get_fs();
30200+ set_fs(KERNEL_DS);
b752ccd1 30201+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 30202+ set_fs(oldfs);
30203+ return err;
30204+}
30205+
4a4d8108
AM
30206+int vfsub_flush(struct file *file, fl_owner_t id)
30207+{
30208+ int err;
30209+
30210+ err = 0;
523b37e3 30211+ if (file->f_op->flush) {
2000de60 30212+ if (!au_test_nfs(file->f_path.dentry->d_sb))
2cbb1c4b
JR
30213+ err = file->f_op->flush(file, id);
30214+ else {
30215+ lockdep_off();
30216+ err = file->f_op->flush(file, id);
30217+ lockdep_on();
30218+ }
4a4d8108
AM
30219+ if (!err)
30220+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
30221+ /*ignore*/
30222+ }
30223+ return err;
30224+}
30225+
392086de 30226+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 30227+{
30228+ int err;
30229+
523b37e3 30230+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 30231+
2cbb1c4b 30232+ lockdep_off();
392086de 30233+ err = iterate_dir(file, ctx);
2cbb1c4b 30234+ lockdep_on();
1facf9fc 30235+ if (err >= 0)
30236+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30237+ return err;
30238+}
30239+
30240+long vfsub_splice_to(struct file *in, loff_t *ppos,
30241+ struct pipe_inode_info *pipe, size_t len,
30242+ unsigned int flags)
30243+{
30244+ long err;
30245+
2cbb1c4b 30246+ lockdep_off();
0fc653ad 30247+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 30248+ lockdep_on();
4a4d8108 30249+ file_accessed(in);
1facf9fc 30250+ if (err >= 0)
30251+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
30252+ return err;
30253+}
30254+
30255+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
30256+ loff_t *ppos, size_t len, unsigned int flags)
30257+{
30258+ long err;
30259+
2cbb1c4b 30260+ lockdep_off();
0fc653ad 30261+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 30262+ lockdep_on();
1facf9fc 30263+ if (err >= 0)
30264+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
30265+ return err;
30266+}
30267+
53392da6
AM
30268+int vfsub_fsync(struct file *file, struct path *path, int datasync)
30269+{
30270+ int err;
30271+
30272+ /* file can be NULL */
30273+ lockdep_off();
30274+ err = vfs_fsync(file, datasync);
30275+ lockdep_on();
30276+ if (!err) {
30277+ if (!path) {
30278+ AuDebugOn(!file);
30279+ path = &file->f_path;
30280+ }
30281+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
30282+ }
30283+ return err;
30284+}
30285+
1facf9fc 30286+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
30287+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
30288+ struct file *h_file)
30289+{
30290+ int err;
30291+ struct inode *h_inode;
c06a8ce3 30292+ struct super_block *h_sb;
1facf9fc 30293+
1facf9fc 30294+ if (!h_file) {
c06a8ce3
AM
30295+ err = vfsub_truncate(h_path, length);
30296+ goto out;
1facf9fc 30297+ }
30298+
c06a8ce3
AM
30299+ h_inode = h_path->dentry->d_inode;
30300+ h_sb = h_inode->i_sb;
30301+ lockdep_off();
30302+ sb_start_write(h_sb);
30303+ lockdep_on();
1facf9fc 30304+ err = locks_verify_truncate(h_inode, h_file, length);
30305+ if (!err)
953406b4 30306+ err = security_path_truncate(h_path);
2cbb1c4b
JR
30307+ if (!err) {
30308+ lockdep_off();
1facf9fc 30309+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
30310+ lockdep_on();
30311+ }
c06a8ce3
AM
30312+ lockdep_off();
30313+ sb_end_write(h_sb);
30314+ lockdep_on();
1facf9fc 30315+
4f0767ce 30316+out:
1facf9fc 30317+ return err;
30318+}
30319+
30320+/* ---------------------------------------------------------------------- */
30321+
30322+struct au_vfsub_mkdir_args {
30323+ int *errp;
30324+ struct inode *dir;
30325+ struct path *path;
30326+ int mode;
30327+};
30328+
30329+static void au_call_vfsub_mkdir(void *args)
30330+{
30331+ struct au_vfsub_mkdir_args *a = args;
30332+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
30333+}
30334+
30335+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
30336+{
30337+ int err, do_sio, wkq_err;
30338+
30339+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
30340+ if (!do_sio) {
30341+ lockdep_off();
1facf9fc 30342+ err = vfsub_mkdir(dir, path, mode);
c1595e42
JR
30343+ lockdep_on();
30344+ } else {
1facf9fc 30345+ struct au_vfsub_mkdir_args args = {
30346+ .errp = &err,
30347+ .dir = dir,
30348+ .path = path,
30349+ .mode = mode
30350+ };
30351+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
30352+ if (unlikely(wkq_err))
30353+ err = wkq_err;
30354+ }
30355+
30356+ return err;
30357+}
30358+
30359+struct au_vfsub_rmdir_args {
30360+ int *errp;
30361+ struct inode *dir;
30362+ struct path *path;
30363+};
30364+
30365+static void au_call_vfsub_rmdir(void *args)
30366+{
30367+ struct au_vfsub_rmdir_args *a = args;
30368+ *a->errp = vfsub_rmdir(a->dir, a->path);
30369+}
30370+
30371+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
30372+{
30373+ int err, do_sio, wkq_err;
30374+
30375+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
30376+ if (!do_sio) {
30377+ lockdep_off();
1facf9fc 30378+ err = vfsub_rmdir(dir, path);
c1595e42
JR
30379+ lockdep_on();
30380+ } else {
1facf9fc 30381+ struct au_vfsub_rmdir_args args = {
30382+ .errp = &err,
30383+ .dir = dir,
30384+ .path = path
30385+ };
30386+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
30387+ if (unlikely(wkq_err))
30388+ err = wkq_err;
30389+ }
30390+
30391+ return err;
30392+}
30393+
30394+/* ---------------------------------------------------------------------- */
30395+
30396+struct notify_change_args {
30397+ int *errp;
30398+ struct path *path;
30399+ struct iattr *ia;
523b37e3 30400+ struct inode **delegated_inode;
1facf9fc 30401+};
30402+
30403+static void call_notify_change(void *args)
30404+{
30405+ struct notify_change_args *a = args;
30406+ struct inode *h_inode;
30407+
30408+ h_inode = a->path->dentry->d_inode;
30409+ IMustLock(h_inode);
30410+
30411+ *a->errp = -EPERM;
30412+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
c1595e42 30413+ lockdep_off();
523b37e3
AM
30414+ *a->errp = notify_change(a->path->dentry, a->ia,
30415+ a->delegated_inode);
c1595e42 30416+ lockdep_on();
1facf9fc 30417+ if (!*a->errp)
30418+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
30419+ }
30420+ AuTraceErr(*a->errp);
30421+}
30422+
523b37e3
AM
30423+int vfsub_notify_change(struct path *path, struct iattr *ia,
30424+ struct inode **delegated_inode)
1facf9fc 30425+{
30426+ int err;
30427+ struct notify_change_args args = {
523b37e3
AM
30428+ .errp = &err,
30429+ .path = path,
30430+ .ia = ia,
30431+ .delegated_inode = delegated_inode
1facf9fc 30432+ };
30433+
30434+ call_notify_change(&args);
30435+
30436+ return err;
30437+}
30438+
523b37e3
AM
30439+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
30440+ struct inode **delegated_inode)
1facf9fc 30441+{
30442+ int err, wkq_err;
30443+ struct notify_change_args args = {
523b37e3
AM
30444+ .errp = &err,
30445+ .path = path,
30446+ .ia = ia,
30447+ .delegated_inode = delegated_inode
1facf9fc 30448+ };
30449+
30450+ wkq_err = au_wkq_wait(call_notify_change, &args);
30451+ if (unlikely(wkq_err))
30452+ err = wkq_err;
30453+
30454+ return err;
30455+}
30456+
30457+/* ---------------------------------------------------------------------- */
30458+
30459+struct unlink_args {
30460+ int *errp;
30461+ struct inode *dir;
30462+ struct path *path;
523b37e3 30463+ struct inode **delegated_inode;
1facf9fc 30464+};
30465+
30466+static void call_unlink(void *args)
30467+{
30468+ struct unlink_args *a = args;
30469+ struct dentry *d = a->path->dentry;
30470+ struct inode *h_inode;
30471+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
c1595e42 30472+ && au_dcount(d) == 1);
1facf9fc 30473+
30474+ IMustLock(a->dir);
30475+
30476+ a->path->dentry = d->d_parent;
30477+ *a->errp = security_path_unlink(a->path, d);
30478+ a->path->dentry = d;
30479+ if (unlikely(*a->errp))
30480+ return;
30481+
30482+ if (!stop_sillyrename)
30483+ dget(d);
30484+ h_inode = d->d_inode;
30485+ if (h_inode)
027c5e7a 30486+ ihold(h_inode);
1facf9fc 30487+
2cbb1c4b 30488+ lockdep_off();
523b37e3 30489+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 30490+ lockdep_on();
1facf9fc 30491+ if (!*a->errp) {
30492+ struct path tmp = {
30493+ .dentry = d->d_parent,
30494+ .mnt = a->path->mnt
30495+ };
30496+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
30497+ }
30498+
30499+ if (!stop_sillyrename)
30500+ dput(d);
30501+ if (h_inode)
30502+ iput(h_inode);
30503+
30504+ AuTraceErr(*a->errp);
30505+}
30506+
30507+/*
30508+ * @dir: must be locked.
30509+ * @dentry: target dentry.
30510+ */
523b37e3
AM
30511+int vfsub_unlink(struct inode *dir, struct path *path,
30512+ struct inode **delegated_inode, int force)
1facf9fc 30513+{
30514+ int err;
30515+ struct unlink_args args = {
523b37e3
AM
30516+ .errp = &err,
30517+ .dir = dir,
30518+ .path = path,
30519+ .delegated_inode = delegated_inode
1facf9fc 30520+ };
30521+
30522+ if (!force)
30523+ call_unlink(&args);
30524+ else {
30525+ int wkq_err;
30526+
30527+ wkq_err = au_wkq_wait(call_unlink, &args);
30528+ if (unlikely(wkq_err))
30529+ err = wkq_err;
30530+ }
30531+
30532+ return err;
30533+}
7f207e10
AM
30534diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
30535--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
30536+++ linux/fs/aufs/vfsub.h 2015-03-27 21:56:35.470128334 +0100
30537@@ -0,0 +1,301 @@
1facf9fc 30538+/*
2000de60 30539+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 30540+ *
30541+ * This program, aufs is free software; you can redistribute it and/or modify
30542+ * it under the terms of the GNU General Public License as published by
30543+ * the Free Software Foundation; either version 2 of the License, or
30544+ * (at your option) any later version.
dece6358
AM
30545+ *
30546+ * This program is distributed in the hope that it will be useful,
30547+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30548+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30549+ * GNU General Public License for more details.
30550+ *
30551+ * You should have received a copy of the GNU General Public License
523b37e3 30552+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30553+ */
30554+
30555+/*
30556+ * sub-routines for VFS
30557+ */
30558+
30559+#ifndef __AUFS_VFSUB_H__
30560+#define __AUFS_VFSUB_H__
30561+
30562+#ifdef __KERNEL__
30563+
30564+#include <linux/fs.h>
0c5527e5 30565+#include <linux/lglock.h>
b4510431 30566+#include <linux/mount.h>
c1595e42 30567+#include <linux/xattr.h>
7f207e10 30568+#include "debug.h"
1facf9fc 30569+
7f207e10 30570+/* copied from linux/fs/internal.h */
2cbb1c4b 30571+/* todo: BAD approach!! */
c06a8ce3 30572+extern void __mnt_drop_write(struct vfsmount *);
2cbb1c4b 30573+extern spinlock_t inode_sb_list_lock;
7f207e10
AM
30574+
30575+/* ---------------------------------------------------------------------- */
1facf9fc 30576+
30577+/* lock subclass for lower inode */
30578+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
30579+/* reduce? gave up. */
30580+enum {
c1595e42 30581+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
1facf9fc 30582+ AuLsc_I_PARENT, /* lower inode, parent first */
30583+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 30584+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 30585+ AuLsc_I_CHILD,
30586+ AuLsc_I_CHILD2,
30587+ AuLsc_I_End
30588+};
30589+
30590+/* to debug easier, do not make them inlined functions */
30591+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
30592+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
30593+
30594+/* ---------------------------------------------------------------------- */
30595+
7f207e10
AM
30596+static inline void vfsub_drop_nlink(struct inode *inode)
30597+{
30598+ AuDebugOn(!inode->i_nlink);
30599+ drop_nlink(inode);
30600+}
30601+
027c5e7a
AM
30602+static inline void vfsub_dead_dir(struct inode *inode)
30603+{
30604+ AuDebugOn(!S_ISDIR(inode->i_mode));
30605+ inode->i_flags |= S_DEAD;
30606+ clear_nlink(inode);
30607+}
30608+
392086de
AM
30609+static inline int vfsub_native_ro(struct inode *inode)
30610+{
30611+ return (inode->i_sb->s_flags & MS_RDONLY)
30612+ || IS_RDONLY(inode)
30613+ /* || IS_APPEND(inode) */
30614+ || IS_IMMUTABLE(inode);
30615+}
30616+
7f207e10
AM
30617+/* ---------------------------------------------------------------------- */
30618+
30619+int vfsub_update_h_iattr(struct path *h_path, int *did);
30620+struct file *vfsub_dentry_open(struct path *path, int flags);
30621+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
1facf9fc 30622+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 30623+
1facf9fc 30624+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
30625+ int len);
b4510431
AM
30626+
30627+struct vfsub_lkup_one_args {
30628+ struct dentry **errp;
30629+ struct qstr *name;
30630+ struct dentry *parent;
30631+};
30632+
30633+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
30634+ struct dentry *parent)
30635+{
30636+ return vfsub_lookup_one_len(name->name, parent, name->len);
30637+}
30638+
30639+void vfsub_call_lkup_one(void *args);
30640+
30641+/* ---------------------------------------------------------------------- */
30642+
30643+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
30644+{
30645+ int err;
076b876e 30646+
b4510431
AM
30647+ lockdep_off();
30648+ err = mnt_want_write(mnt);
30649+ lockdep_on();
30650+ return err;
30651+}
30652+
30653+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
30654+{
30655+ lockdep_off();
30656+ mnt_drop_write(mnt);
30657+ lockdep_on();
30658+}
1facf9fc 30659+
c06a8ce3
AM
30660+static inline void vfsub_mnt_drop_write_file(struct file *file)
30661+{
30662+ lockdep_off();
30663+ mnt_drop_write_file(file);
30664+ lockdep_on();
30665+}
30666+
1facf9fc 30667+/* ---------------------------------------------------------------------- */
30668+
30669+struct au_hinode;
30670+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
30671+ struct dentry *d2, struct au_hinode *hdir2);
30672+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
30673+ struct dentry *d2, struct au_hinode *hdir2);
30674+
537831f9
AM
30675+int vfsub_create(struct inode *dir, struct path *path, int mode,
30676+ bool want_excl);
1facf9fc 30677+int vfsub_symlink(struct inode *dir, struct path *path,
30678+ const char *symname);
30679+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
30680+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 30681+ struct path *path, struct inode **delegated_inode);
1facf9fc 30682+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3
AM
30683+ struct inode *hdir, struct path *path,
30684+ struct inode **delegated_inode);
1facf9fc 30685+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
30686+int vfsub_rmdir(struct inode *dir, struct path *path);
30687+
30688+/* ---------------------------------------------------------------------- */
30689+
30690+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
30691+ loff_t *ppos);
30692+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
30693+ loff_t *ppos);
30694+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
30695+ loff_t *ppos);
30696+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
30697+ loff_t *ppos);
4a4d8108 30698+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
30699+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
30700+
c06a8ce3
AM
30701+static inline loff_t vfsub_f_size_read(struct file *file)
30702+{
30703+ return i_size_read(file_inode(file));
30704+}
30705+
4a4d8108
AM
30706+static inline unsigned int vfsub_file_flags(struct file *file)
30707+{
30708+ unsigned int flags;
30709+
30710+ spin_lock(&file->f_lock);
30711+ flags = file->f_flags;
30712+ spin_unlock(&file->f_lock);
30713+
30714+ return flags;
30715+}
1308ab2a 30716+
1facf9fc 30717+static inline void vfsub_file_accessed(struct file *h_file)
30718+{
30719+ file_accessed(h_file);
30720+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
30721+}
30722+
30723+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
30724+ struct dentry *h_dentry)
30725+{
30726+ struct path h_path = {
30727+ .dentry = h_dentry,
30728+ .mnt = h_mnt
30729+ };
92d182d2 30730+ touch_atime(&h_path);
1facf9fc 30731+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
30732+}
30733+
0c3ec466
AM
30734+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
30735+ int flags)
30736+{
30737+ return update_time(h_inode, ts, flags);
30738+ /* no vfsub_update_h_iattr() since we don't have struct path */
30739+}
30740+
4a4d8108
AM
30741+long vfsub_splice_to(struct file *in, loff_t *ppos,
30742+ struct pipe_inode_info *pipe, size_t len,
30743+ unsigned int flags);
30744+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
30745+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
30746+
30747+static inline long vfsub_truncate(struct path *path, loff_t length)
30748+{
30749+ long err;
076b876e 30750+
c06a8ce3
AM
30751+ lockdep_off();
30752+ err = vfs_truncate(path, length);
30753+ lockdep_on();
30754+ return err;
30755+}
30756+
4a4d8108
AM
30757+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
30758+ struct file *h_file);
53392da6 30759+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 30760+
1facf9fc 30761+/* ---------------------------------------------------------------------- */
30762+
30763+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
30764+{
30765+ loff_t err;
30766+
2cbb1c4b 30767+ lockdep_off();
1facf9fc 30768+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 30769+ lockdep_on();
1facf9fc 30770+ return err;
30771+}
30772+
30773+/* ---------------------------------------------------------------------- */
30774+
30775+/* dirty workaround for strict type of fmode_t */
30776+union vfsub_fmu {
30777+ fmode_t fm;
30778+ unsigned int ui;
30779+};
30780+
30781+static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
30782+{
30783+ union vfsub_fmu u = {
30784+ .fm = fm
30785+ };
30786+
30787+ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
30788+
30789+ return u.ui;
30790+}
30791+
30792+static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
30793+{
30794+ union vfsub_fmu u = {
30795+ .ui = ui
30796+ };
30797+
30798+ return u.fm;
30799+}
30800+
4a4d8108
AM
30801+/* ---------------------------------------------------------------------- */
30802+
30803+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
30804+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
30805+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
30806+ struct inode **delegated_inode);
30807+int vfsub_notify_change(struct path *path, struct iattr *ia,
30808+ struct inode **delegated_inode);
30809+int vfsub_unlink(struct inode *dir, struct path *path,
30810+ struct inode **delegated_inode, int force);
4a4d8108 30811+
c1595e42
JR
30812+/* ---------------------------------------------------------------------- */
30813+
30814+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
30815+ const void *value, size_t size, int flags)
30816+{
30817+ int err;
30818+
30819+ lockdep_off();
30820+ err = vfs_setxattr(dentry, name, value, size, flags);
30821+ lockdep_on();
30822+
30823+ return err;
30824+}
30825+
30826+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
30827+{
30828+ int err;
30829+
30830+ lockdep_off();
30831+ err = vfs_removexattr(dentry, name);
30832+ lockdep_on();
30833+
30834+ return err;
30835+}
30836+
1facf9fc 30837+#endif /* __KERNEL__ */
30838+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
30839diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
30840--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
2000de60 30841+++ linux/fs/aufs/wbr_policy.c 2015-03-27 21:56:35.470128334 +0100
076b876e 30842@@ -0,0 +1,765 @@
1facf9fc 30843+/*
2000de60 30844+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 30845+ *
30846+ * This program, aufs is free software; you can redistribute it and/or modify
30847+ * it under the terms of the GNU General Public License as published by
30848+ * the Free Software Foundation; either version 2 of the License, or
30849+ * (at your option) any later version.
dece6358
AM
30850+ *
30851+ * This program is distributed in the hope that it will be useful,
30852+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30853+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30854+ * GNU General Public License for more details.
30855+ *
30856+ * You should have received a copy of the GNU General Public License
523b37e3 30857+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30858+ */
30859+
30860+/*
30861+ * policies for selecting one among multiple writable branches
30862+ */
30863+
30864+#include <linux/statfs.h>
30865+#include "aufs.h"
30866+
30867+/* subset of cpup_attr() */
30868+static noinline_for_stack
30869+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
30870+{
30871+ int err, sbits;
30872+ struct iattr ia;
30873+ struct inode *h_isrc;
30874+
30875+ h_isrc = h_src->d_inode;
30876+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
30877+ ia.ia_mode = h_isrc->i_mode;
30878+ ia.ia_uid = h_isrc->i_uid;
30879+ ia.ia_gid = h_isrc->i_gid;
30880+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
86dc4139 30881+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
523b37e3
AM
30882+ /* no delegation since it is just created */
30883+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 30884+
30885+ /* is this nfs only? */
30886+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
30887+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
30888+ ia.ia_mode = h_isrc->i_mode;
523b37e3 30889+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 30890+ }
30891+
30892+ return err;
30893+}
30894+
30895+#define AuCpdown_PARENT_OPQ 1
30896+#define AuCpdown_WHED (1 << 1)
30897+#define AuCpdown_MADE_DIR (1 << 2)
30898+#define AuCpdown_DIROPQ (1 << 3)
30899+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
30900+#define au_fset_cpdown(flags, name) \
30901+ do { (flags) |= AuCpdown_##name; } while (0)
30902+#define au_fclr_cpdown(flags, name) \
30903+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 30904+
1facf9fc 30905+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 30906+ unsigned int *flags)
1facf9fc 30907+{
30908+ int err;
30909+ struct dentry *opq_dentry;
30910+
30911+ opq_dentry = au_diropq_create(dentry, bdst);
30912+ err = PTR_ERR(opq_dentry);
30913+ if (IS_ERR(opq_dentry))
30914+ goto out;
30915+ dput(opq_dentry);
c2b27bf2 30916+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 30917+
4f0767ce 30918+out:
1facf9fc 30919+ return err;
30920+}
30921+
30922+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
30923+ struct inode *dir, aufs_bindex_t bdst)
30924+{
30925+ int err;
30926+ struct path h_path;
30927+ struct au_branch *br;
30928+
30929+ br = au_sbr(dentry->d_sb, bdst);
30930+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
30931+ err = PTR_ERR(h_path.dentry);
30932+ if (IS_ERR(h_path.dentry))
30933+ goto out;
30934+
30935+ err = 0;
30936+ if (h_path.dentry->d_inode) {
86dc4139 30937+ h_path.mnt = au_br_mnt(br);
1facf9fc 30938+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
30939+ dentry);
30940+ }
30941+ dput(h_path.dentry);
30942+
4f0767ce 30943+out:
1facf9fc 30944+ return err;
30945+}
30946+
30947+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 30948+ struct au_pin *pin,
1facf9fc 30949+ struct dentry *h_parent, void *arg)
30950+{
30951+ int err, rerr;
4a4d8108 30952+ aufs_bindex_t bopq, bstart;
1facf9fc 30953+ struct path h_path;
30954+ struct dentry *parent;
30955+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 30956+ unsigned int *flags = arg;
1facf9fc 30957+
30958+ bstart = au_dbstart(dentry);
30959+ /* dentry is di-locked */
30960+ parent = dget_parent(dentry);
30961+ dir = parent->d_inode;
30962+ h_dir = h_parent->d_inode;
30963+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
30964+ IMustLock(h_dir);
30965+
86dc4139 30966+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 30967+ if (unlikely(err < 0))
30968+ goto out;
30969+ h_path.dentry = au_h_dptr(dentry, bdst);
30970+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
30971+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
30972+ S_IRWXU | S_IRUGO | S_IXUGO);
30973+ if (unlikely(err))
30974+ goto out_put;
c2b27bf2 30975+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 30976+
1facf9fc 30977+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
30978+ au_fclr_cpdown(*flags, WHED);
30979+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 30980+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
30981+ au_fset_cpdown(*flags, WHED);
30982+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
30983+ au_fset_cpdown(*flags, PARENT_OPQ);
1facf9fc 30984+ h_inode = h_path.dentry->d_inode;
30985+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2
AM
30986+ if (au_ftest_cpdown(*flags, WHED)) {
30987+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 30988+ if (unlikely(err)) {
30989+ mutex_unlock(&h_inode->i_mutex);
30990+ goto out_dir;
30991+ }
30992+ }
30993+
30994+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
30995+ mutex_unlock(&h_inode->i_mutex);
30996+ if (unlikely(err))
30997+ goto out_opq;
30998+
c2b27bf2 30999+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 31000+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
31001+ if (unlikely(err))
31002+ goto out_opq;
31003+ }
31004+
31005+ inode = dentry->d_inode;
31006+ if (au_ibend(inode) < bdst)
31007+ au_set_ibend(inode, bdst);
31008+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
31009+ au_hi_flags(inode, /*isdir*/1));
076b876e 31010+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 31011+ goto out; /* success */
31012+
31013+ /* revert */
4f0767ce 31014+out_opq:
c2b27bf2 31015+ if (au_ftest_cpdown(*flags, DIROPQ)) {
1facf9fc 31016+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
31017+ rerr = au_diropq_remove(dentry, bdst);
31018+ mutex_unlock(&h_inode->i_mutex);
31019+ if (unlikely(rerr)) {
523b37e3
AM
31020+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
31021+ dentry, bdst, rerr);
1facf9fc 31022+ err = -EIO;
31023+ goto out;
31024+ }
31025+ }
4f0767ce 31026+out_dir:
c2b27bf2 31027+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 31028+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
31029+ if (unlikely(rerr)) {
523b37e3
AM
31030+ AuIOErr("failed removing %pd b%d (%d)\n",
31031+ dentry, bdst, rerr);
1facf9fc 31032+ err = -EIO;
31033+ }
31034+ }
4f0767ce 31035+out_put:
1facf9fc 31036+ au_set_h_dptr(dentry, bdst, NULL);
31037+ if (au_dbend(dentry) == bdst)
31038+ au_update_dbend(dentry);
4f0767ce 31039+out:
1facf9fc 31040+ dput(parent);
31041+ return err;
31042+}
31043+
31044+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
31045+{
31046+ int err;
c2b27bf2 31047+ unsigned int flags;
1facf9fc 31048+
c2b27bf2
AM
31049+ flags = 0;
31050+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 31051+
31052+ return err;
31053+}
31054+
31055+/* ---------------------------------------------------------------------- */
31056+
31057+/* policies for create */
31058+
c2b27bf2 31059+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
31060+{
31061+ int err, i, j, ndentry;
31062+ aufs_bindex_t bopq;
31063+ struct au_dcsub_pages dpages;
31064+ struct au_dpage *dpage;
31065+ struct dentry **dentries, *parent, *d;
31066+
31067+ err = au_dpages_init(&dpages, GFP_NOFS);
31068+ if (unlikely(err))
31069+ goto out;
31070+ parent = dget_parent(dentry);
027c5e7a 31071+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
31072+ if (unlikely(err))
31073+ goto out_free;
31074+
31075+ err = bindex;
31076+ for (i = 0; i < dpages.ndpage; i++) {
31077+ dpage = dpages.dpages + i;
31078+ dentries = dpage->dentries;
31079+ ndentry = dpage->ndentry;
31080+ for (j = 0; j < ndentry; j++) {
31081+ d = dentries[j];
31082+ di_read_lock_parent2(d, !AuLock_IR);
31083+ bopq = au_dbdiropq(d);
31084+ di_read_unlock(d, !AuLock_IR);
31085+ if (bopq >= 0 && bopq < err)
31086+ err = bopq;
31087+ }
31088+ }
31089+
31090+out_free:
31091+ dput(parent);
31092+ au_dpages_free(&dpages);
31093+out:
31094+ return err;
31095+}
31096+
1facf9fc 31097+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
31098+{
31099+ for (; bindex >= 0; bindex--)
31100+ if (!au_br_rdonly(au_sbr(sb, bindex)))
31101+ return bindex;
31102+ return -EROFS;
31103+}
31104+
31105+/* top down parent */
392086de
AM
31106+static int au_wbr_create_tdp(struct dentry *dentry,
31107+ unsigned int flags __maybe_unused)
1facf9fc 31108+{
31109+ int err;
31110+ aufs_bindex_t bstart, bindex;
31111+ struct super_block *sb;
31112+ struct dentry *parent, *h_parent;
31113+
31114+ sb = dentry->d_sb;
31115+ bstart = au_dbstart(dentry);
31116+ err = bstart;
31117+ if (!au_br_rdonly(au_sbr(sb, bstart)))
31118+ goto out;
31119+
31120+ err = -EROFS;
31121+ parent = dget_parent(dentry);
31122+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
31123+ h_parent = au_h_dptr(parent, bindex);
31124+ if (!h_parent || !h_parent->d_inode)
31125+ continue;
31126+
31127+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
31128+ err = bindex;
31129+ break;
31130+ }
31131+ }
31132+ dput(parent);
31133+
31134+ /* bottom up here */
4a4d8108 31135+ if (unlikely(err < 0)) {
1facf9fc 31136+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
31137+ if (err >= 0)
31138+ err = au_wbr_nonopq(dentry, err);
31139+ }
1facf9fc 31140+
4f0767ce 31141+out:
1facf9fc 31142+ AuDbg("b%d\n", err);
31143+ return err;
31144+}
31145+
31146+/* ---------------------------------------------------------------------- */
31147+
31148+/* an exception for the policy other than tdp */
31149+static int au_wbr_create_exp(struct dentry *dentry)
31150+{
31151+ int err;
31152+ aufs_bindex_t bwh, bdiropq;
31153+ struct dentry *parent;
31154+
31155+ err = -1;
31156+ bwh = au_dbwh(dentry);
31157+ parent = dget_parent(dentry);
31158+ bdiropq = au_dbdiropq(parent);
31159+ if (bwh >= 0) {
31160+ if (bdiropq >= 0)
31161+ err = min(bdiropq, bwh);
31162+ else
31163+ err = bwh;
31164+ AuDbg("%d\n", err);
31165+ } else if (bdiropq >= 0) {
31166+ err = bdiropq;
31167+ AuDbg("%d\n", err);
31168+ }
31169+ dput(parent);
31170+
4a4d8108
AM
31171+ if (err >= 0)
31172+ err = au_wbr_nonopq(dentry, err);
31173+
1facf9fc 31174+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
31175+ err = -1;
31176+
31177+ AuDbg("%d\n", err);
31178+ return err;
31179+}
31180+
31181+/* ---------------------------------------------------------------------- */
31182+
31183+/* round robin */
31184+static int au_wbr_create_init_rr(struct super_block *sb)
31185+{
31186+ int err;
31187+
31188+ err = au_wbr_bu(sb, au_sbend(sb));
31189+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 31190+ /* smp_mb(); */
1facf9fc 31191+
31192+ AuDbg("b%d\n", err);
31193+ return err;
31194+}
31195+
392086de 31196+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 31197+{
31198+ int err, nbr;
31199+ unsigned int u;
31200+ aufs_bindex_t bindex, bend;
31201+ struct super_block *sb;
31202+ atomic_t *next;
31203+
31204+ err = au_wbr_create_exp(dentry);
31205+ if (err >= 0)
31206+ goto out;
31207+
31208+ sb = dentry->d_sb;
31209+ next = &au_sbi(sb)->si_wbr_rr_next;
31210+ bend = au_sbend(sb);
31211+ nbr = bend + 1;
31212+ for (bindex = 0; bindex <= bend; bindex++) {
392086de 31213+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 31214+ err = atomic_dec_return(next) + 1;
31215+ /* modulo for 0 is meaningless */
31216+ if (unlikely(!err))
31217+ err = atomic_dec_return(next) + 1;
31218+ } else
31219+ err = atomic_read(next);
31220+ AuDbg("%d\n", err);
31221+ u = err;
31222+ err = u % nbr;
31223+ AuDbg("%d\n", err);
31224+ if (!au_br_rdonly(au_sbr(sb, err)))
31225+ break;
31226+ err = -EROFS;
31227+ }
31228+
4a4d8108
AM
31229+ if (err >= 0)
31230+ err = au_wbr_nonopq(dentry, err);
31231+
4f0767ce 31232+out:
1facf9fc 31233+ AuDbg("%d\n", err);
31234+ return err;
31235+}
31236+
31237+/* ---------------------------------------------------------------------- */
31238+
31239+/* most free space */
392086de 31240+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 31241+{
31242+ struct super_block *sb;
31243+ struct au_branch *br;
31244+ struct au_wbr_mfs *mfs;
392086de 31245+ struct dentry *h_parent;
1facf9fc 31246+ aufs_bindex_t bindex, bend;
31247+ int err;
31248+ unsigned long long b, bavail;
7f207e10 31249+ struct path h_path;
1facf9fc 31250+ /* reduce the stack usage */
31251+ struct kstatfs *st;
31252+
31253+ st = kmalloc(sizeof(*st), GFP_NOFS);
31254+ if (unlikely(!st)) {
31255+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
31256+ return;
31257+ }
31258+
31259+ bavail = 0;
31260+ sb = dentry->d_sb;
31261+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 31262+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 31263+ mfs->mfs_bindex = -EROFS;
31264+ mfs->mfsrr_bytes = 0;
392086de
AM
31265+ if (!parent) {
31266+ bindex = 0;
31267+ bend = au_sbend(sb);
31268+ } else {
31269+ bindex = au_dbstart(parent);
31270+ bend = au_dbtaildir(parent);
31271+ }
31272+
31273+ for (; bindex <= bend; bindex++) {
31274+ if (parent) {
31275+ h_parent = au_h_dptr(parent, bindex);
31276+ if (!h_parent || !h_parent->d_inode)
31277+ continue;
31278+ }
1facf9fc 31279+ br = au_sbr(sb, bindex);
31280+ if (au_br_rdonly(br))
31281+ continue;
31282+
31283+ /* sb->s_root for NFS is unreliable */
86dc4139 31284+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
31285+ h_path.dentry = h_path.mnt->mnt_root;
31286+ err = vfs_statfs(&h_path, st);
1facf9fc 31287+ if (unlikely(err)) {
31288+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
31289+ continue;
31290+ }
31291+
31292+ /* when the available size is equal, select the lower one */
31293+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
31294+ || sizeof(b) < sizeof(st->f_bsize));
31295+ b = st->f_bavail * st->f_bsize;
31296+ br->br_wbr->wbr_bytes = b;
31297+ if (b >= bavail) {
31298+ bavail = b;
31299+ mfs->mfs_bindex = bindex;
31300+ mfs->mfs_jiffy = jiffies;
31301+ }
31302+ }
31303+
31304+ mfs->mfsrr_bytes = bavail;
31305+ AuDbg("b%d\n", mfs->mfs_bindex);
31306+ kfree(st);
31307+}
31308+
392086de 31309+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 31310+{
31311+ int err;
392086de 31312+ struct dentry *parent;
1facf9fc 31313+ struct super_block *sb;
31314+ struct au_wbr_mfs *mfs;
31315+
31316+ err = au_wbr_create_exp(dentry);
31317+ if (err >= 0)
31318+ goto out;
31319+
31320+ sb = dentry->d_sb;
392086de
AM
31321+ parent = NULL;
31322+ if (au_ftest_wbr(flags, PARENT))
31323+ parent = dget_parent(dentry);
1facf9fc 31324+ mfs = &au_sbi(sb)->si_wbr_mfs;
31325+ mutex_lock(&mfs->mfs_lock);
31326+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
31327+ || mfs->mfs_bindex < 0
31328+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 31329+ au_mfs(dentry, parent);
1facf9fc 31330+ mutex_unlock(&mfs->mfs_lock);
31331+ err = mfs->mfs_bindex;
392086de 31332+ dput(parent);
1facf9fc 31333+
4a4d8108
AM
31334+ if (err >= 0)
31335+ err = au_wbr_nonopq(dentry, err);
31336+
4f0767ce 31337+out:
1facf9fc 31338+ AuDbg("b%d\n", err);
31339+ return err;
31340+}
31341+
31342+static int au_wbr_create_init_mfs(struct super_block *sb)
31343+{
31344+ struct au_wbr_mfs *mfs;
31345+
31346+ mfs = &au_sbi(sb)->si_wbr_mfs;
31347+ mutex_init(&mfs->mfs_lock);
31348+ mfs->mfs_jiffy = 0;
31349+ mfs->mfs_bindex = -EROFS;
31350+
31351+ return 0;
31352+}
31353+
31354+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
31355+{
31356+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
31357+ return 0;
31358+}
31359+
31360+/* ---------------------------------------------------------------------- */
31361+
31362+/* most free space and then round robin */
392086de 31363+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 31364+{
31365+ int err;
31366+ struct au_wbr_mfs *mfs;
31367+
392086de 31368+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 31369+ if (err >= 0) {
31370+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 31371+ mutex_lock(&mfs->mfs_lock);
1facf9fc 31372+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 31373+ err = au_wbr_create_rr(dentry, flags);
dece6358 31374+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 31375+ }
31376+
31377+ AuDbg("b%d\n", err);
31378+ return err;
31379+}
31380+
31381+static int au_wbr_create_init_mfsrr(struct super_block *sb)
31382+{
31383+ int err;
31384+
31385+ au_wbr_create_init_mfs(sb); /* ignore */
31386+ err = au_wbr_create_init_rr(sb);
31387+
31388+ return err;
31389+}
31390+
31391+/* ---------------------------------------------------------------------- */
31392+
31393+/* top down parent and most free space */
392086de 31394+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 31395+{
31396+ int err, e2;
31397+ unsigned long long b;
31398+ aufs_bindex_t bindex, bstart, bend;
31399+ struct super_block *sb;
31400+ struct dentry *parent, *h_parent;
31401+ struct au_branch *br;
31402+
392086de 31403+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 31404+ if (unlikely(err < 0))
31405+ goto out;
31406+ parent = dget_parent(dentry);
31407+ bstart = au_dbstart(parent);
31408+ bend = au_dbtaildir(parent);
31409+ if (bstart == bend)
31410+ goto out_parent; /* success */
31411+
392086de 31412+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 31413+ if (e2 < 0)
31414+ goto out_parent; /* success */
31415+
31416+ /* when the available size is equal, select upper one */
31417+ sb = dentry->d_sb;
31418+ br = au_sbr(sb, err);
31419+ b = br->br_wbr->wbr_bytes;
31420+ AuDbg("b%d, %llu\n", err, b);
31421+
31422+ for (bindex = bstart; bindex <= bend; bindex++) {
31423+ h_parent = au_h_dptr(parent, bindex);
31424+ if (!h_parent || !h_parent->d_inode)
31425+ continue;
31426+
31427+ br = au_sbr(sb, bindex);
31428+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
31429+ b = br->br_wbr->wbr_bytes;
31430+ err = bindex;
31431+ AuDbg("b%d, %llu\n", err, b);
31432+ }
31433+ }
31434+
4a4d8108
AM
31435+ if (err >= 0)
31436+ err = au_wbr_nonopq(dentry, err);
31437+
4f0767ce 31438+out_parent:
1facf9fc 31439+ dput(parent);
4f0767ce 31440+out:
1facf9fc 31441+ AuDbg("b%d\n", err);
31442+ return err;
31443+}
31444+
31445+/* ---------------------------------------------------------------------- */
31446+
392086de
AM
31447+/*
31448+ * - top down parent
31449+ * - most free space with parent
31450+ * - most free space round-robin regardless parent
31451+ */
31452+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
31453+{
31454+ int err;
31455+ unsigned long long watermark;
31456+ struct super_block *sb;
31457+ struct au_branch *br;
31458+ struct au_wbr_mfs *mfs;
31459+
31460+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
31461+ if (unlikely(err < 0))
31462+ goto out;
31463+
31464+ sb = dentry->d_sb;
31465+ br = au_sbr(sb, err);
31466+ mfs = &au_sbi(sb)->si_wbr_mfs;
31467+ mutex_lock(&mfs->mfs_lock);
31468+ watermark = mfs->mfsrr_watermark;
31469+ mutex_unlock(&mfs->mfs_lock);
31470+ if (br->br_wbr->wbr_bytes < watermark)
31471+ /* regardless the parent dir */
31472+ err = au_wbr_create_mfsrr(dentry, flags);
31473+
31474+out:
31475+ AuDbg("b%d\n", err);
31476+ return err;
31477+}
31478+
31479+/* ---------------------------------------------------------------------- */
31480+
1facf9fc 31481+/* policies for copyup */
31482+
31483+/* top down parent */
31484+static int au_wbr_copyup_tdp(struct dentry *dentry)
31485+{
392086de 31486+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 31487+}
31488+
31489+/* bottom up parent */
31490+static int au_wbr_copyup_bup(struct dentry *dentry)
31491+{
31492+ int err;
31493+ aufs_bindex_t bindex, bstart;
31494+ struct dentry *parent, *h_parent;
31495+ struct super_block *sb;
31496+
31497+ err = -EROFS;
31498+ sb = dentry->d_sb;
31499+ parent = dget_parent(dentry);
31500+ bstart = au_dbstart(parent);
31501+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
31502+ h_parent = au_h_dptr(parent, bindex);
31503+ if (!h_parent || !h_parent->d_inode)
31504+ continue;
31505+
31506+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
31507+ err = bindex;
31508+ break;
31509+ }
31510+ }
31511+ dput(parent);
31512+
31513+ /* bottom up here */
31514+ if (unlikely(err < 0))
31515+ err = au_wbr_bu(sb, bstart - 1);
31516+
31517+ AuDbg("b%d\n", err);
31518+ return err;
31519+}
31520+
31521+/* bottom up */
076b876e 31522+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart)
1facf9fc 31523+{
31524+ int err;
31525+
4a4d8108
AM
31526+ err = au_wbr_bu(dentry->d_sb, bstart);
31527+ AuDbg("b%d\n", err);
31528+ if (err > bstart)
31529+ err = au_wbr_nonopq(dentry, err);
1facf9fc 31530+
31531+ AuDbg("b%d\n", err);
31532+ return err;
31533+}
31534+
076b876e
AM
31535+static int au_wbr_copyup_bu(struct dentry *dentry)
31536+{
31537+ int err;
31538+ aufs_bindex_t bstart;
31539+
31540+ bstart = au_dbstart(dentry);
31541+ err = au_wbr_do_copyup_bu(dentry, bstart);
31542+ return err;
31543+}
31544+
1facf9fc 31545+/* ---------------------------------------------------------------------- */
31546+
31547+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
31548+ [AuWbrCopyup_TDP] = {
31549+ .copyup = au_wbr_copyup_tdp
31550+ },
31551+ [AuWbrCopyup_BUP] = {
31552+ .copyup = au_wbr_copyup_bup
31553+ },
31554+ [AuWbrCopyup_BU] = {
31555+ .copyup = au_wbr_copyup_bu
31556+ }
31557+};
31558+
31559+struct au_wbr_create_operations au_wbr_create_ops[] = {
31560+ [AuWbrCreate_TDP] = {
31561+ .create = au_wbr_create_tdp
31562+ },
31563+ [AuWbrCreate_RR] = {
31564+ .create = au_wbr_create_rr,
31565+ .init = au_wbr_create_init_rr
31566+ },
31567+ [AuWbrCreate_MFS] = {
31568+ .create = au_wbr_create_mfs,
31569+ .init = au_wbr_create_init_mfs,
31570+ .fin = au_wbr_create_fin_mfs
31571+ },
31572+ [AuWbrCreate_MFSV] = {
31573+ .create = au_wbr_create_mfs,
31574+ .init = au_wbr_create_init_mfs,
31575+ .fin = au_wbr_create_fin_mfs
31576+ },
31577+ [AuWbrCreate_MFSRR] = {
31578+ .create = au_wbr_create_mfsrr,
31579+ .init = au_wbr_create_init_mfsrr,
31580+ .fin = au_wbr_create_fin_mfs
31581+ },
31582+ [AuWbrCreate_MFSRRV] = {
31583+ .create = au_wbr_create_mfsrr,
31584+ .init = au_wbr_create_init_mfsrr,
31585+ .fin = au_wbr_create_fin_mfs
31586+ },
31587+ [AuWbrCreate_PMFS] = {
31588+ .create = au_wbr_create_pmfs,
31589+ .init = au_wbr_create_init_mfs,
31590+ .fin = au_wbr_create_fin_mfs
31591+ },
31592+ [AuWbrCreate_PMFSV] = {
31593+ .create = au_wbr_create_pmfs,
31594+ .init = au_wbr_create_init_mfs,
31595+ .fin = au_wbr_create_fin_mfs
392086de
AM
31596+ },
31597+ [AuWbrCreate_PMFSRR] = {
31598+ .create = au_wbr_create_pmfsrr,
31599+ .init = au_wbr_create_init_mfsrr,
31600+ .fin = au_wbr_create_fin_mfs
31601+ },
31602+ [AuWbrCreate_PMFSRRV] = {
31603+ .create = au_wbr_create_pmfsrr,
31604+ .init = au_wbr_create_init_mfsrr,
31605+ .fin = au_wbr_create_fin_mfs
1facf9fc 31606+ }
31607+};
7f207e10
AM
31608diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
31609--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
2000de60
JR
31610+++ linux/fs/aufs/whout.c 2015-03-27 21:56:35.470128334 +0100
31611@@ -0,0 +1,1064 @@
1facf9fc 31612+/*
2000de60 31613+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 31614+ *
31615+ * This program, aufs is free software; you can redistribute it and/or modify
31616+ * it under the terms of the GNU General Public License as published by
31617+ * the Free Software Foundation; either version 2 of the License, or
31618+ * (at your option) any later version.
dece6358
AM
31619+ *
31620+ * This program is distributed in the hope that it will be useful,
31621+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31622+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31623+ * GNU General Public License for more details.
31624+ *
31625+ * You should have received a copy of the GNU General Public License
523b37e3 31626+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31627+ */
31628+
31629+/*
31630+ * whiteout for logical deletion and opaque directory
31631+ */
31632+
1facf9fc 31633+#include "aufs.h"
31634+
31635+#define WH_MASK S_IRUGO
31636+
31637+/*
31638+ * If a directory contains this file, then it is opaque. We start with the
31639+ * .wh. flag so that it is blocked by lookup.
31640+ */
0c3ec466
AM
31641+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
31642+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 31643+
31644+/*
31645+ * generate whiteout name, which is NOT terminated by NULL.
31646+ * @name: original d_name.name
31647+ * @len: original d_name.len
31648+ * @wh: whiteout qstr
31649+ * returns zero when succeeds, otherwise error.
31650+ * succeeded value as wh->name should be freed by kfree().
31651+ */
31652+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
31653+{
31654+ char *p;
31655+
31656+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
31657+ return -ENAMETOOLONG;
31658+
31659+ wh->len = name->len + AUFS_WH_PFX_LEN;
31660+ p = kmalloc(wh->len, GFP_NOFS);
31661+ wh->name = p;
31662+ if (p) {
31663+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
31664+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
31665+ /* smp_mb(); */
31666+ return 0;
31667+ }
31668+ return -ENOMEM;
31669+}
31670+
31671+/* ---------------------------------------------------------------------- */
31672+
31673+/*
31674+ * test if the @wh_name exists under @h_parent.
31675+ * @try_sio specifies the necessary of super-io.
31676+ */
076b876e 31677+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 31678+{
31679+ int err;
31680+ struct dentry *wh_dentry;
1facf9fc 31681+
1facf9fc 31682+ if (!try_sio)
b4510431 31683+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 31684+ else
076b876e 31685+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 31686+ err = PTR_ERR(wh_dentry);
2000de60
JR
31687+ if (IS_ERR(wh_dentry)) {
31688+ if (err == -ENAMETOOLONG)
31689+ err = 0;
1facf9fc 31690+ goto out;
2000de60 31691+ }
1facf9fc 31692+
31693+ err = 0;
31694+ if (!wh_dentry->d_inode)
31695+ goto out_wh; /* success */
31696+
31697+ err = 1;
31698+ if (S_ISREG(wh_dentry->d_inode->i_mode))
31699+ goto out_wh; /* success */
31700+
31701+ err = -EIO;
523b37e3
AM
31702+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
31703+ wh_dentry, wh_dentry->d_inode->i_mode);
1facf9fc 31704+
4f0767ce 31705+out_wh:
1facf9fc 31706+ dput(wh_dentry);
4f0767ce 31707+out:
1facf9fc 31708+ return err;
31709+}
31710+
31711+/*
31712+ * test if the @h_dentry sets opaque or not.
31713+ */
076b876e 31714+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 31715+{
31716+ int err;
31717+ struct inode *h_dir;
31718+
31719+ h_dir = h_dentry->d_inode;
076b876e 31720+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 31721+ au_test_h_perm_sio(h_dir, MAY_EXEC));
31722+ return err;
31723+}
31724+
31725+/*
31726+ * returns a negative dentry whose name is unique and temporary.
31727+ */
31728+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
31729+ struct qstr *prefix)
31730+{
1facf9fc 31731+ struct dentry *dentry;
31732+ int i;
027c5e7a 31733+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 31734+ *name, *p;
027c5e7a 31735+ /* strict atomic_t is unnecessary here */
1facf9fc 31736+ static unsigned short cnt;
31737+ struct qstr qs;
31738+
4a4d8108
AM
31739+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
31740+
1facf9fc 31741+ name = defname;
027c5e7a
AM
31742+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
31743+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 31744+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 31745+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 31746+ goto out;
31747+ dentry = ERR_PTR(-ENOMEM);
31748+ name = kmalloc(qs.len + 1, GFP_NOFS);
31749+ if (unlikely(!name))
31750+ goto out;
31751+ }
31752+
31753+ /* doubly whiteout-ed */
31754+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
31755+ p = name + AUFS_WH_PFX_LEN * 2;
31756+ memcpy(p, prefix->name, prefix->len);
31757+ p += prefix->len;
31758+ *p++ = '.';
4a4d8108 31759+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 31760+
31761+ qs.name = name;
31762+ for (i = 0; i < 3; i++) {
b752ccd1 31763+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 31764+ dentry = au_sio_lkup_one(&qs, h_parent);
1facf9fc 31765+ if (IS_ERR(dentry) || !dentry->d_inode)
31766+ goto out_name;
31767+ dput(dentry);
31768+ }
0c3ec466 31769+ /* pr_warn("could not get random name\n"); */
1facf9fc 31770+ dentry = ERR_PTR(-EEXIST);
31771+ AuDbg("%.*s\n", AuLNPair(&qs));
31772+ BUG();
31773+
4f0767ce 31774+out_name:
1facf9fc 31775+ if (name != defname)
31776+ kfree(name);
4f0767ce 31777+out:
4a4d8108 31778+ AuTraceErrPtr(dentry);
1facf9fc 31779+ return dentry;
1facf9fc 31780+}
31781+
31782+/*
31783+ * rename the @h_dentry on @br to the whiteouted temporary name.
31784+ */
31785+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
31786+{
31787+ int err;
31788+ struct path h_path = {
86dc4139 31789+ .mnt = au_br_mnt(br)
1facf9fc 31790+ };
523b37e3 31791+ struct inode *h_dir, *delegated;
1facf9fc 31792+ struct dentry *h_parent;
31793+
31794+ h_parent = h_dentry->d_parent; /* dir inode is locked */
31795+ h_dir = h_parent->d_inode;
31796+ IMustLock(h_dir);
31797+
31798+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
31799+ err = PTR_ERR(h_path.dentry);
31800+ if (IS_ERR(h_path.dentry))
31801+ goto out;
31802+
31803+ /* under the same dir, no need to lock_rename() */
523b37e3
AM
31804+ delegated = NULL;
31805+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated);
1facf9fc 31806+ AuTraceErr(err);
523b37e3
AM
31807+ if (unlikely(err == -EWOULDBLOCK)) {
31808+ pr_warn("cannot retry for NFSv4 delegation"
31809+ " for an internal rename\n");
31810+ iput(delegated);
31811+ }
1facf9fc 31812+ dput(h_path.dentry);
31813+
4f0767ce 31814+out:
4a4d8108 31815+ AuTraceErr(err);
1facf9fc 31816+ return err;
31817+}
31818+
31819+/* ---------------------------------------------------------------------- */
31820+/*
31821+ * functions for removing a whiteout
31822+ */
31823+
31824+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
31825+{
523b37e3
AM
31826+ int err, force;
31827+ struct inode *delegated;
1facf9fc 31828+
31829+ /*
31830+ * forces superio when the dir has a sticky bit.
31831+ * this may be a violation of unix fs semantics.
31832+ */
31833+ force = (h_dir->i_mode & S_ISVTX)
0c3ec466 31834+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
523b37e3
AM
31835+ delegated = NULL;
31836+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
31837+ if (unlikely(err == -EWOULDBLOCK)) {
31838+ pr_warn("cannot retry for NFSv4 delegation"
31839+ " for an internal unlink\n");
31840+ iput(delegated);
31841+ }
31842+ return err;
1facf9fc 31843+}
31844+
31845+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
31846+ struct dentry *dentry)
31847+{
31848+ int err;
31849+
31850+ err = do_unlink_wh(h_dir, h_path);
31851+ if (!err && dentry)
31852+ au_set_dbwh(dentry, -1);
31853+
31854+ return err;
31855+}
31856+
31857+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
31858+ struct au_branch *br)
31859+{
31860+ int err;
31861+ struct path h_path = {
86dc4139 31862+ .mnt = au_br_mnt(br)
1facf9fc 31863+ };
31864+
31865+ err = 0;
b4510431 31866+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 31867+ if (IS_ERR(h_path.dentry))
31868+ err = PTR_ERR(h_path.dentry);
31869+ else {
31870+ if (h_path.dentry->d_inode
31871+ && S_ISREG(h_path.dentry->d_inode->i_mode))
31872+ err = do_unlink_wh(h_parent->d_inode, &h_path);
31873+ dput(h_path.dentry);
31874+ }
31875+
31876+ return err;
31877+}
31878+
31879+/* ---------------------------------------------------------------------- */
31880+/*
31881+ * initialize/clean whiteout for a branch
31882+ */
31883+
31884+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
31885+ const int isdir)
31886+{
31887+ int err;
523b37e3 31888+ struct inode *delegated;
1facf9fc 31889+
31890+ if (!whpath->dentry->d_inode)
31891+ return;
31892+
86dc4139
AM
31893+ if (isdir)
31894+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
31895+ else {
31896+ delegated = NULL;
31897+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
31898+ if (unlikely(err == -EWOULDBLOCK)) {
31899+ pr_warn("cannot retry for NFSv4 delegation"
31900+ " for an internal unlink\n");
31901+ iput(delegated);
31902+ }
31903+ }
1facf9fc 31904+ if (unlikely(err))
523b37e3
AM
31905+ pr_warn("failed removing %pd (%d), ignored.\n",
31906+ whpath->dentry, err);
1facf9fc 31907+}
31908+
31909+static int test_linkable(struct dentry *h_root)
31910+{
31911+ struct inode *h_dir = h_root->d_inode;
31912+
31913+ if (h_dir->i_op->link)
31914+ return 0;
31915+
523b37e3
AM
31916+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
31917+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 31918+ return -ENOSYS;
31919+}
31920+
31921+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
31922+static int au_whdir(struct inode *h_dir, struct path *path)
31923+{
31924+ int err;
31925+
31926+ err = -EEXIST;
31927+ if (!path->dentry->d_inode) {
31928+ int mode = S_IRWXU;
31929+
31930+ if (au_test_nfs(path->dentry->d_sb))
31931+ mode |= S_IXUGO;
86dc4139 31932+ err = vfsub_mkdir(h_dir, path, mode);
2000de60 31933+ } else if (d_is_dir(path->dentry))
1facf9fc 31934+ err = 0;
31935+ else
523b37e3 31936+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 31937+
31938+ return err;
31939+}
31940+
31941+struct au_wh_base {
31942+ const struct qstr *name;
31943+ struct dentry *dentry;
31944+};
31945+
31946+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
31947+ struct path *h_path)
31948+{
31949+ h_path->dentry = base[AuBrWh_BASE].dentry;
31950+ au_wh_clean(h_dir, h_path, /*isdir*/0);
31951+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31952+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31953+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31954+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31955+}
31956+
31957+/*
31958+ * returns tri-state,
c1595e42 31959+ * minus: error, caller should print the message
1facf9fc 31960+ * zero: succuess
c1595e42 31961+ * plus: error, caller should NOT print the message
1facf9fc 31962+ */
31963+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
31964+ int do_plink, struct au_wh_base base[],
31965+ struct path *h_path)
31966+{
31967+ int err;
31968+ struct inode *h_dir;
31969+
31970+ h_dir = h_root->d_inode;
31971+ h_path->dentry = base[AuBrWh_BASE].dentry;
31972+ au_wh_clean(h_dir, h_path, /*isdir*/0);
31973+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31974+ if (do_plink) {
31975+ err = test_linkable(h_root);
31976+ if (unlikely(err)) {
31977+ err = 1;
31978+ goto out;
31979+ }
31980+
31981+ err = au_whdir(h_dir, h_path);
31982+ if (unlikely(err))
31983+ goto out;
31984+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
31985+ } else
31986+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31987+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31988+ err = au_whdir(h_dir, h_path);
31989+ if (unlikely(err))
31990+ goto out;
31991+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
31992+
4f0767ce 31993+out:
1facf9fc 31994+ return err;
31995+}
31996+
31997+/*
31998+ * for the moment, aufs supports the branch filesystem which does not support
31999+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
32000+ * copyup failed. finally, such filesystem will not be used as the writable
32001+ * branch.
32002+ *
32003+ * returns tri-state, see above.
32004+ */
32005+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
32006+ int do_plink, struct au_wh_base base[],
32007+ struct path *h_path)
32008+{
32009+ int err;
32010+ struct inode *h_dir;
32011+
1308ab2a 32012+ WbrWhMustWriteLock(wbr);
32013+
1facf9fc 32014+ err = test_linkable(h_root);
32015+ if (unlikely(err)) {
32016+ err = 1;
32017+ goto out;
32018+ }
32019+
32020+ /*
32021+ * todo: should this create be done in /sbin/mount.aufs helper?
32022+ */
32023+ err = -EEXIST;
32024+ h_dir = h_root->d_inode;
32025+ if (!base[AuBrWh_BASE].dentry->d_inode) {
86dc4139
AM
32026+ h_path->dentry = base[AuBrWh_BASE].dentry;
32027+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
1facf9fc 32028+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
32029+ err = 0;
32030+ else
523b37e3 32031+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 32032+ if (unlikely(err))
32033+ goto out;
32034+
32035+ h_path->dentry = base[AuBrWh_PLINK].dentry;
32036+ if (do_plink) {
32037+ err = au_whdir(h_dir, h_path);
32038+ if (unlikely(err))
32039+ goto out;
32040+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
32041+ } else
32042+ au_wh_clean(h_dir, h_path, /*isdir*/1);
32043+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
32044+
32045+ h_path->dentry = base[AuBrWh_ORPH].dentry;
32046+ err = au_whdir(h_dir, h_path);
32047+ if (unlikely(err))
32048+ goto out;
32049+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
32050+
4f0767ce 32051+out:
1facf9fc 32052+ return err;
32053+}
32054+
32055+/*
32056+ * initialize the whiteout base file/dir for @br.
32057+ */
86dc4139 32058+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 32059+{
32060+ int err, i;
32061+ const unsigned char do_plink
32062+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 32063+ struct inode *h_dir;
86dc4139
AM
32064+ struct path path = br->br_path;
32065+ struct dentry *h_root = path.dentry;
1facf9fc 32066+ struct au_wbr *wbr = br->br_wbr;
32067+ static const struct qstr base_name[] = {
0c3ec466
AM
32068+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
32069+ sizeof(AUFS_BASE_NAME) - 1),
32070+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
32071+ sizeof(AUFS_PLINKDIR_NAME) - 1),
32072+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
32073+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 32074+ };
32075+ struct au_wh_base base[] = {
32076+ [AuBrWh_BASE] = {
32077+ .name = base_name + AuBrWh_BASE,
32078+ .dentry = NULL
32079+ },
32080+ [AuBrWh_PLINK] = {
32081+ .name = base_name + AuBrWh_PLINK,
32082+ .dentry = NULL
32083+ },
32084+ [AuBrWh_ORPH] = {
32085+ .name = base_name + AuBrWh_ORPH,
32086+ .dentry = NULL
32087+ }
32088+ };
32089+
1308ab2a 32090+ if (wbr)
32091+ WbrWhMustWriteLock(wbr);
1facf9fc 32092+
1facf9fc 32093+ for (i = 0; i < AuBrWh_Last; i++) {
32094+ /* doubly whiteouted */
32095+ struct dentry *d;
32096+
32097+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
32098+ err = PTR_ERR(d);
32099+ if (IS_ERR(d))
32100+ goto out;
32101+
32102+ base[i].dentry = d;
32103+ AuDebugOn(wbr
32104+ && wbr->wbr_wh[i]
32105+ && wbr->wbr_wh[i] != base[i].dentry);
32106+ }
32107+
32108+ if (wbr)
32109+ for (i = 0; i < AuBrWh_Last; i++) {
32110+ dput(wbr->wbr_wh[i]);
32111+ wbr->wbr_wh[i] = NULL;
32112+ }
32113+
32114+ err = 0;
1e00d052 32115+ if (!au_br_writable(br->br_perm)) {
4a4d8108 32116+ h_dir = h_root->d_inode;
1facf9fc 32117+ au_wh_init_ro(h_dir, base, &path);
1e00d052 32118+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 32119+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
32120+ if (err > 0)
32121+ goto out;
32122+ else if (err)
32123+ goto out_err;
1e00d052 32124+ } else {
1facf9fc 32125+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
32126+ if (err > 0)
32127+ goto out;
32128+ else if (err)
32129+ goto out_err;
1facf9fc 32130+ }
32131+ goto out; /* success */
32132+
4f0767ce 32133+out_err:
523b37e3
AM
32134+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
32135+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 32136+out:
1facf9fc 32137+ for (i = 0; i < AuBrWh_Last; i++)
32138+ dput(base[i].dentry);
32139+ return err;
32140+}
32141+
32142+/* ---------------------------------------------------------------------- */
32143+/*
32144+ * whiteouts are all hard-linked usually.
32145+ * when its link count reaches a ceiling, we create a new whiteout base
32146+ * asynchronously.
32147+ */
32148+
32149+struct reinit_br_wh {
32150+ struct super_block *sb;
32151+ struct au_branch *br;
32152+};
32153+
32154+static void reinit_br_wh(void *arg)
32155+{
32156+ int err;
32157+ aufs_bindex_t bindex;
32158+ struct path h_path;
32159+ struct reinit_br_wh *a = arg;
32160+ struct au_wbr *wbr;
523b37e3 32161+ struct inode *dir, *delegated;
1facf9fc 32162+ struct dentry *h_root;
32163+ struct au_hinode *hdir;
32164+
32165+ err = 0;
32166+ wbr = a->br->br_wbr;
32167+ /* big aufs lock */
32168+ si_noflush_write_lock(a->sb);
32169+ if (!au_br_writable(a->br->br_perm))
32170+ goto out;
32171+ bindex = au_br_index(a->sb, a->br->br_id);
32172+ if (unlikely(bindex < 0))
32173+ goto out;
32174+
1308ab2a 32175+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 32176+ dir = a->sb->s_root->d_inode;
1facf9fc 32177+ hdir = au_hi(dir, bindex);
32178+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 32179+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 32180+
4a4d8108 32181+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 32182+ wbr_wh_write_lock(wbr);
32183+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
32184+ h_root, a->br);
32185+ if (!err) {
86dc4139
AM
32186+ h_path.dentry = wbr->wbr_whbase;
32187+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
32188+ delegated = NULL;
32189+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
32190+ /*force*/0);
32191+ if (unlikely(err == -EWOULDBLOCK)) {
32192+ pr_warn("cannot retry for NFSv4 delegation"
32193+ " for an internal unlink\n");
32194+ iput(delegated);
32195+ }
1facf9fc 32196+ } else {
523b37e3 32197+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 32198+ err = 0;
32199+ }
32200+ dput(wbr->wbr_whbase);
32201+ wbr->wbr_whbase = NULL;
32202+ if (!err)
86dc4139 32203+ err = au_wh_init(a->br, a->sb);
1facf9fc 32204+ wbr_wh_write_unlock(wbr);
4a4d8108 32205+ au_hn_imtx_unlock(hdir);
1308ab2a 32206+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
32207+ if (!err)
32208+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 32209+
4f0767ce 32210+out:
1facf9fc 32211+ if (wbr)
32212+ atomic_dec(&wbr->wbr_wh_running);
32213+ atomic_dec(&a->br->br_count);
1facf9fc 32214+ si_write_unlock(a->sb);
027c5e7a 32215+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 32216+ kfree(arg);
32217+ if (unlikely(err))
32218+ AuIOErr("err %d\n", err);
32219+}
32220+
32221+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
32222+{
32223+ int do_dec, wkq_err;
32224+ struct reinit_br_wh *arg;
32225+
32226+ do_dec = 1;
32227+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
32228+ goto out;
32229+
32230+ /* ignore ENOMEM */
32231+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
32232+ if (arg) {
32233+ /*
32234+ * dec(wh_running), kfree(arg) and dec(br_count)
32235+ * in reinit function
32236+ */
32237+ arg->sb = sb;
32238+ arg->br = br;
32239+ atomic_inc(&br->br_count);
53392da6 32240+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 32241+ if (unlikely(wkq_err)) {
32242+ atomic_dec(&br->br_wbr->wbr_wh_running);
32243+ atomic_dec(&br->br_count);
32244+ kfree(arg);
32245+ }
32246+ do_dec = 0;
32247+ }
32248+
4f0767ce 32249+out:
1facf9fc 32250+ if (do_dec)
32251+ atomic_dec(&br->br_wbr->wbr_wh_running);
32252+}
32253+
32254+/* ---------------------------------------------------------------------- */
32255+
32256+/*
32257+ * create the whiteout @wh.
32258+ */
32259+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
32260+ struct dentry *wh)
32261+{
32262+ int err;
32263+ struct path h_path = {
32264+ .dentry = wh
32265+ };
32266+ struct au_branch *br;
32267+ struct au_wbr *wbr;
32268+ struct dentry *h_parent;
523b37e3 32269+ struct inode *h_dir, *delegated;
1facf9fc 32270+
32271+ h_parent = wh->d_parent; /* dir inode is locked */
32272+ h_dir = h_parent->d_inode;
32273+ IMustLock(h_dir);
32274+
32275+ br = au_sbr(sb, bindex);
86dc4139 32276+ h_path.mnt = au_br_mnt(br);
1facf9fc 32277+ wbr = br->br_wbr;
32278+ wbr_wh_read_lock(wbr);
32279+ if (wbr->wbr_whbase) {
523b37e3
AM
32280+ delegated = NULL;
32281+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
32282+ if (unlikely(err == -EWOULDBLOCK)) {
32283+ pr_warn("cannot retry for NFSv4 delegation"
32284+ " for an internal link\n");
32285+ iput(delegated);
32286+ }
1facf9fc 32287+ if (!err || err != -EMLINK)
32288+ goto out;
32289+
32290+ /* link count full. re-initialize br_whbase. */
32291+ kick_reinit_br_wh(sb, br);
32292+ }
32293+
32294+ /* return this error in this context */
b4510431 32295+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
32296+ if (!err)
32297+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 32298+
4f0767ce 32299+out:
1facf9fc 32300+ wbr_wh_read_unlock(wbr);
32301+ return err;
32302+}
32303+
32304+/* ---------------------------------------------------------------------- */
32305+
32306+/*
32307+ * create or remove the diropq.
32308+ */
32309+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
32310+ unsigned int flags)
32311+{
32312+ struct dentry *opq_dentry, *h_dentry;
32313+ struct super_block *sb;
32314+ struct au_branch *br;
32315+ int err;
32316+
32317+ sb = dentry->d_sb;
32318+ br = au_sbr(sb, bindex);
32319+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 32320+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 32321+ if (IS_ERR(opq_dentry))
32322+ goto out;
32323+
32324+ if (au_ftest_diropq(flags, CREATE)) {
32325+ err = link_or_create_wh(sb, bindex, opq_dentry);
32326+ if (!err) {
32327+ au_set_dbdiropq(dentry, bindex);
32328+ goto out; /* success */
32329+ }
32330+ } else {
32331+ struct path tmp = {
32332+ .dentry = opq_dentry,
86dc4139 32333+ .mnt = au_br_mnt(br)
1facf9fc 32334+ };
32335+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
32336+ if (!err)
32337+ au_set_dbdiropq(dentry, -1);
32338+ }
32339+ dput(opq_dentry);
32340+ opq_dentry = ERR_PTR(err);
32341+
4f0767ce 32342+out:
1facf9fc 32343+ return opq_dentry;
32344+}
32345+
32346+struct do_diropq_args {
32347+ struct dentry **errp;
32348+ struct dentry *dentry;
32349+ aufs_bindex_t bindex;
32350+ unsigned int flags;
32351+};
32352+
32353+static void call_do_diropq(void *args)
32354+{
32355+ struct do_diropq_args *a = args;
32356+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
32357+}
32358+
32359+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
32360+ unsigned int flags)
32361+{
32362+ struct dentry *diropq, *h_dentry;
32363+
32364+ h_dentry = au_h_dptr(dentry, bindex);
32365+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
32366+ diropq = do_diropq(dentry, bindex, flags);
32367+ else {
32368+ int wkq_err;
32369+ struct do_diropq_args args = {
32370+ .errp = &diropq,
32371+ .dentry = dentry,
32372+ .bindex = bindex,
32373+ .flags = flags
32374+ };
32375+
32376+ wkq_err = au_wkq_wait(call_do_diropq, &args);
32377+ if (unlikely(wkq_err))
32378+ diropq = ERR_PTR(wkq_err);
32379+ }
32380+
32381+ return diropq;
32382+}
32383+
32384+/* ---------------------------------------------------------------------- */
32385+
32386+/*
32387+ * lookup whiteout dentry.
32388+ * @h_parent: lower parent dentry which must exist and be locked
32389+ * @base_name: name of dentry which will be whiteouted
32390+ * returns dentry for whiteout.
32391+ */
32392+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
32393+ struct au_branch *br)
32394+{
32395+ int err;
32396+ struct qstr wh_name;
32397+ struct dentry *wh_dentry;
32398+
32399+ err = au_wh_name_alloc(&wh_name, base_name);
32400+ wh_dentry = ERR_PTR(err);
32401+ if (!err) {
b4510431 32402+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 32403+ kfree(wh_name.name);
32404+ }
32405+ return wh_dentry;
32406+}
32407+
32408+/*
32409+ * link/create a whiteout for @dentry on @bindex.
32410+ */
32411+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
32412+ struct dentry *h_parent)
32413+{
32414+ struct dentry *wh_dentry;
32415+ struct super_block *sb;
32416+ int err;
32417+
32418+ sb = dentry->d_sb;
32419+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
32420+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
32421+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 32422+ if (!err) {
1facf9fc 32423+ au_set_dbwh(dentry, bindex);
076b876e
AM
32424+ au_fhsm_wrote(sb, bindex, /*force*/0);
32425+ } else {
1facf9fc 32426+ dput(wh_dentry);
32427+ wh_dentry = ERR_PTR(err);
32428+ }
32429+ }
32430+
32431+ return wh_dentry;
32432+}
32433+
32434+/* ---------------------------------------------------------------------- */
32435+
32436+/* Delete all whiteouts in this directory on branch bindex. */
32437+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
32438+ aufs_bindex_t bindex, struct au_branch *br)
32439+{
32440+ int err;
32441+ unsigned long ul, n;
32442+ struct qstr wh_name;
32443+ char *p;
32444+ struct hlist_head *head;
c06a8ce3 32445+ struct au_vdir_wh *pos;
1facf9fc 32446+ struct au_vdir_destr *str;
32447+
32448+ err = -ENOMEM;
537831f9 32449+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 32450+ wh_name.name = p;
32451+ if (unlikely(!wh_name.name))
32452+ goto out;
32453+
32454+ err = 0;
32455+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32456+ p += AUFS_WH_PFX_LEN;
32457+ n = whlist->nh_num;
32458+ head = whlist->nh_head;
32459+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
32460+ hlist_for_each_entry(pos, head, wh_hash) {
32461+ if (pos->wh_bindex != bindex)
1facf9fc 32462+ continue;
32463+
c06a8ce3 32464+ str = &pos->wh_str;
1facf9fc 32465+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
32466+ memcpy(p, str->name, str->len);
32467+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
32468+ err = unlink_wh_name(h_dentry, &wh_name, br);
32469+ if (!err)
32470+ continue;
32471+ break;
32472+ }
32473+ AuIOErr("whiteout name too long %.*s\n",
32474+ str->len, str->name);
32475+ err = -EIO;
32476+ break;
32477+ }
32478+ }
537831f9 32479+ free_page((unsigned long)wh_name.name);
1facf9fc 32480+
4f0767ce 32481+out:
1facf9fc 32482+ return err;
32483+}
32484+
32485+struct del_wh_children_args {
32486+ int *errp;
32487+ struct dentry *h_dentry;
1308ab2a 32488+ struct au_nhash *whlist;
1facf9fc 32489+ aufs_bindex_t bindex;
32490+ struct au_branch *br;
32491+};
32492+
32493+static void call_del_wh_children(void *args)
32494+{
32495+ struct del_wh_children_args *a = args;
1308ab2a 32496+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 32497+}
32498+
32499+/* ---------------------------------------------------------------------- */
32500+
32501+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
32502+{
32503+ struct au_whtmp_rmdir *whtmp;
dece6358 32504+ int err;
1308ab2a 32505+ unsigned int rdhash;
dece6358
AM
32506+
32507+ SiMustAnyLock(sb);
1facf9fc 32508+
32509+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
32510+ if (unlikely(!whtmp)) {
32511+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 32512+ goto out;
dece6358 32513+ }
1facf9fc 32514+
32515+ whtmp->dir = NULL;
027c5e7a 32516+ whtmp->br = NULL;
1facf9fc 32517+ whtmp->wh_dentry = NULL;
1308ab2a 32518+ /* no estimation for dir size */
32519+ rdhash = au_sbi(sb)->si_rdhash;
32520+ if (!rdhash)
32521+ rdhash = AUFS_RDHASH_DEF;
32522+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
32523+ if (unlikely(err)) {
32524+ kfree(whtmp);
32525+ whtmp = ERR_PTR(err);
32526+ }
dece6358 32527+
4f0767ce 32528+out:
dece6358 32529+ return whtmp;
1facf9fc 32530+}
32531+
32532+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
32533+{
027c5e7a
AM
32534+ if (whtmp->br)
32535+ atomic_dec(&whtmp->br->br_count);
1facf9fc 32536+ dput(whtmp->wh_dentry);
32537+ iput(whtmp->dir);
dece6358 32538+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 32539+ kfree(whtmp);
32540+}
32541+
32542+/*
32543+ * rmdir the whiteouted temporary named dir @h_dentry.
32544+ * @whlist: whiteouted children.
32545+ */
32546+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
32547+ struct dentry *wh_dentry, struct au_nhash *whlist)
32548+{
32549+ int err;
2000de60 32550+ unsigned int h_nlink;
1facf9fc 32551+ struct path h_tmp;
32552+ struct inode *wh_inode, *h_dir;
32553+ struct au_branch *br;
32554+
32555+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
32556+ IMustLock(h_dir);
32557+
32558+ br = au_sbr(dir->i_sb, bindex);
32559+ wh_inode = wh_dentry->d_inode;
32560+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
32561+
32562+ /*
32563+ * someone else might change some whiteouts while we were sleeping.
32564+ * it means this whlist may have an obsoleted entry.
32565+ */
32566+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
32567+ err = del_wh_children(wh_dentry, whlist, bindex, br);
32568+ else {
32569+ int wkq_err;
32570+ struct del_wh_children_args args = {
32571+ .errp = &err,
32572+ .h_dentry = wh_dentry,
1308ab2a 32573+ .whlist = whlist,
1facf9fc 32574+ .bindex = bindex,
32575+ .br = br
32576+ };
32577+
32578+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
32579+ if (unlikely(wkq_err))
32580+ err = wkq_err;
32581+ }
32582+ mutex_unlock(&wh_inode->i_mutex);
32583+
32584+ if (!err) {
32585+ h_tmp.dentry = wh_dentry;
86dc4139 32586+ h_tmp.mnt = au_br_mnt(br);
2000de60 32587+ h_nlink = h_dir->i_nlink;
1facf9fc 32588+ err = vfsub_rmdir(h_dir, &h_tmp);
2000de60
JR
32589+ /* some fs doesn't change the parent nlink in some cases */
32590+ h_nlink -= h_dir->i_nlink;
1facf9fc 32591+ }
32592+
32593+ if (!err) {
32594+ if (au_ibstart(dir) == bindex) {
7f207e10 32595+ /* todo: dir->i_mutex is necessary */
1facf9fc 32596+ au_cpup_attr_timesizes(dir);
2000de60
JR
32597+ if (h_nlink)
32598+ vfsub_drop_nlink(dir);
1facf9fc 32599+ }
32600+ return 0; /* success */
32601+ }
32602+
523b37e3 32603+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 32604+ return err;
32605+}
32606+
32607+static void call_rmdir_whtmp(void *args)
32608+{
32609+ int err;
e49829fe 32610+ aufs_bindex_t bindex;
1facf9fc 32611+ struct au_whtmp_rmdir *a = args;
32612+ struct super_block *sb;
32613+ struct dentry *h_parent;
32614+ struct inode *h_dir;
1facf9fc 32615+ struct au_hinode *hdir;
32616+
32617+ /* rmdir by nfsd may cause deadlock with this i_mutex */
32618+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 32619+ err = -EROFS;
1facf9fc 32620+ sb = a->dir->i_sb;
e49829fe
JR
32621+ si_read_lock(sb, !AuLock_FLUSH);
32622+ if (!au_br_writable(a->br->br_perm))
32623+ goto out;
32624+ bindex = au_br_index(sb, a->br->br_id);
32625+ if (unlikely(bindex < 0))
1facf9fc 32626+ goto out;
32627+
32628+ err = -EIO;
1facf9fc 32629+ ii_write_lock_parent(a->dir);
32630+ h_parent = dget_parent(a->wh_dentry);
32631+ h_dir = h_parent->d_inode;
e49829fe 32632+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
32633+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
32634+ if (unlikely(err))
32635+ goto out_mnt;
4a4d8108 32636+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
32637+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
32638+ a->br);
86dc4139
AM
32639+ if (!err)
32640+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 32641+ au_hn_imtx_unlock(hdir);
86dc4139
AM
32642+ vfsub_mnt_drop_write(au_br_mnt(a->br));
32643+
32644+out_mnt:
1facf9fc 32645+ dput(h_parent);
32646+ ii_write_unlock(a->dir);
4f0767ce 32647+out:
1facf9fc 32648+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 32649+ au_whtmp_rmdir_free(a);
027c5e7a
AM
32650+ si_read_unlock(sb);
32651+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32652+ if (unlikely(err))
32653+ AuIOErr("err %d\n", err);
32654+}
32655+
32656+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
32657+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
32658+{
32659+ int wkq_err;
e49829fe 32660+ struct super_block *sb;
1facf9fc 32661+
32662+ IMustLock(dir);
32663+
32664+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 32665+ sb = dir->i_sb;
1facf9fc 32666+ args->dir = au_igrab(dir);
e49829fe
JR
32667+ args->br = au_sbr(sb, bindex);
32668+ atomic_inc(&args->br->br_count);
1facf9fc 32669+ args->wh_dentry = dget(wh_dentry);
53392da6 32670+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 32671+ if (unlikely(wkq_err)) {
523b37e3 32672+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 32673+ au_whtmp_rmdir_free(args);
32674+ }
32675+}
7f207e10
AM
32676diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
32677--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
2000de60 32678+++ linux/fs/aufs/whout.h 2015-03-27 21:56:35.470128334 +0100
076b876e 32679@@ -0,0 +1,85 @@
1facf9fc 32680+/*
2000de60 32681+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 32682+ *
32683+ * This program, aufs is free software; you can redistribute it and/or modify
32684+ * it under the terms of the GNU General Public License as published by
32685+ * the Free Software Foundation; either version 2 of the License, or
32686+ * (at your option) any later version.
dece6358
AM
32687+ *
32688+ * This program is distributed in the hope that it will be useful,
32689+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32690+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32691+ * GNU General Public License for more details.
32692+ *
32693+ * You should have received a copy of the GNU General Public License
523b37e3 32694+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32695+ */
32696+
32697+/*
32698+ * whiteout for logical deletion and opaque directory
32699+ */
32700+
32701+#ifndef __AUFS_WHOUT_H__
32702+#define __AUFS_WHOUT_H__
32703+
32704+#ifdef __KERNEL__
32705+
1facf9fc 32706+#include "dir.h"
32707+
32708+/* whout.c */
32709+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
32710+struct au_branch;
076b876e
AM
32711+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
32712+int au_diropq_test(struct dentry *h_dentry);
1facf9fc 32713+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
32714+ struct qstr *prefix);
32715+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
32716+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
32717+ struct dentry *dentry);
86dc4139 32718+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 32719+
32720+/* diropq flags */
32721+#define AuDiropq_CREATE 1
32722+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
32723+#define au_fset_diropq(flags, name) \
32724+ do { (flags) |= AuDiropq_##name; } while (0)
32725+#define au_fclr_diropq(flags, name) \
32726+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 32727+
32728+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
32729+ unsigned int flags);
32730+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
32731+ struct au_branch *br);
32732+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
32733+ struct dentry *h_parent);
32734+
32735+/* real rmdir for the whiteout-ed dir */
32736+struct au_whtmp_rmdir {
32737+ struct inode *dir;
e49829fe 32738+ struct au_branch *br;
1facf9fc 32739+ struct dentry *wh_dentry;
dece6358 32740+ struct au_nhash whlist;
1facf9fc 32741+};
32742+
32743+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
32744+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
32745+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
32746+ struct dentry *wh_dentry, struct au_nhash *whlist);
32747+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
32748+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
32749+
32750+/* ---------------------------------------------------------------------- */
32751+
32752+static inline struct dentry *au_diropq_create(struct dentry *dentry,
32753+ aufs_bindex_t bindex)
32754+{
32755+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
32756+}
32757+
32758+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
32759+{
32760+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
32761+}
32762+
32763+#endif /* __KERNEL__ */
32764+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
32765diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
32766--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
2000de60 32767+++ linux/fs/aufs/wkq.c 2015-03-27 21:56:35.470128334 +0100
38d290e6 32768@@ -0,0 +1,213 @@
1facf9fc 32769+/*
2000de60 32770+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 32771+ *
32772+ * This program, aufs is free software; you can redistribute it and/or modify
32773+ * it under the terms of the GNU General Public License as published by
32774+ * the Free Software Foundation; either version 2 of the License, or
32775+ * (at your option) any later version.
dece6358
AM
32776+ *
32777+ * This program is distributed in the hope that it will be useful,
32778+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32779+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32780+ * GNU General Public License for more details.
32781+ *
32782+ * You should have received a copy of the GNU General Public License
523b37e3 32783+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32784+ */
32785+
32786+/*
32787+ * workqueue for asynchronous/super-io operations
32788+ * todo: try new dredential scheme
32789+ */
32790+
dece6358 32791+#include <linux/module.h>
1facf9fc 32792+#include "aufs.h"
32793+
9dbd164d 32794+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 32795+
9dbd164d 32796+static struct workqueue_struct *au_wkq;
1facf9fc 32797+
32798+struct au_wkinfo {
32799+ struct work_struct wk;
7f207e10 32800+ struct kobject *kobj;
1facf9fc 32801+
32802+ unsigned int flags; /* see wkq.h */
32803+
32804+ au_wkq_func_t func;
32805+ void *args;
32806+
1facf9fc 32807+ struct completion *comp;
32808+};
32809+
32810+/* ---------------------------------------------------------------------- */
32811+
1facf9fc 32812+static void wkq_func(struct work_struct *wk)
32813+{
32814+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
32815+
2dfbb274 32816+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
32817+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
32818+
1facf9fc 32819+ wkinfo->func(wkinfo->args);
1facf9fc 32820+ if (au_ftest_wkq(wkinfo->flags, WAIT))
32821+ complete(wkinfo->comp);
32822+ else {
7f207e10 32823+ kobject_put(wkinfo->kobj);
9dbd164d 32824+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 32825+ kfree(wkinfo);
32826+ }
32827+}
32828+
32829+/*
32830+ * Since struct completion is large, try allocating it dynamically.
32831+ */
c2b27bf2 32832+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 32833+#define AuWkqCompDeclare(name) struct completion *comp = NULL
32834+
32835+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
32836+{
32837+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
32838+ if (*comp) {
32839+ init_completion(*comp);
32840+ wkinfo->comp = *comp;
32841+ return 0;
32842+ }
32843+ return -ENOMEM;
32844+}
32845+
32846+static void au_wkq_comp_free(struct completion *comp)
32847+{
32848+ kfree(comp);
32849+}
32850+
32851+#else
32852+
32853+/* no braces */
32854+#define AuWkqCompDeclare(name) \
32855+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
32856+ struct completion *comp = &_ ## name
32857+
32858+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
32859+{
32860+ wkinfo->comp = *comp;
32861+ return 0;
32862+}
32863+
32864+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
32865+{
32866+ /* empty */
32867+}
32868+#endif /* 4KSTACKS */
32869+
53392da6 32870+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 32871+{
53392da6
AM
32872+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
32873+ if (au_wkq_test()) {
38d290e6
JR
32874+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
32875+ " due to a dead dir by UDBA?\n");
53392da6
AM
32876+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
32877+ }
32878+ } else
32879+ au_dbg_verify_kthread();
32880+
32881+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 32882+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 32883+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
32884+ } else {
32885+ INIT_WORK(&wkinfo->wk, wkq_func);
32886+ schedule_work(&wkinfo->wk);
32887+ }
1facf9fc 32888+}
32889+
7f207e10
AM
32890+/*
32891+ * Be careful. It is easy to make deadlock happen.
32892+ * processA: lock, wkq and wait
32893+ * processB: wkq and wait, lock in wkq
32894+ * --> deadlock
32895+ */
b752ccd1 32896+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 32897+{
32898+ int err;
32899+ AuWkqCompDeclare(comp);
32900+ struct au_wkinfo wkinfo = {
b752ccd1 32901+ .flags = flags,
1facf9fc 32902+ .func = func,
32903+ .args = args
32904+ };
32905+
32906+ err = au_wkq_comp_alloc(&wkinfo, &comp);
32907+ if (!err) {
53392da6 32908+ au_wkq_run(&wkinfo);
1facf9fc 32909+ /* no timeout, no interrupt */
32910+ wait_for_completion(wkinfo.comp);
32911+ au_wkq_comp_free(comp);
4a4d8108 32912+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 32913+ }
32914+
32915+ return err;
32916+
32917+}
32918+
027c5e7a
AM
32919+/*
32920+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
32921+ * problem in a concurrent umounting.
32922+ */
53392da6
AM
32923+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
32924+ unsigned int flags)
1facf9fc 32925+{
32926+ int err;
32927+ struct au_wkinfo *wkinfo;
32928+
32929+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
32930+
32931+ /*
32932+ * wkq_func() must free this wkinfo.
32933+ * it highly depends upon the implementation of workqueue.
32934+ */
32935+ err = 0;
32936+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
32937+ if (wkinfo) {
7f207e10 32938+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 32939+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 32940+ wkinfo->func = func;
32941+ wkinfo->args = args;
32942+ wkinfo->comp = NULL;
7f207e10 32943+ kobject_get(wkinfo->kobj);
9dbd164d 32944+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 32945+
53392da6 32946+ au_wkq_run(wkinfo);
1facf9fc 32947+ } else {
32948+ err = -ENOMEM;
e49829fe 32949+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32950+ }
32951+
32952+ return err;
32953+}
32954+
32955+/* ---------------------------------------------------------------------- */
32956+
32957+void au_nwt_init(struct au_nowait_tasks *nwt)
32958+{
32959+ atomic_set(&nwt->nw_len, 0);
4a4d8108 32960+ /* smp_mb(); */ /* atomic_set */
1facf9fc 32961+ init_waitqueue_head(&nwt->nw_wq);
32962+}
32963+
32964+void au_wkq_fin(void)
32965+{
9dbd164d 32966+ destroy_workqueue(au_wkq);
1facf9fc 32967+}
32968+
32969+int __init au_wkq_init(void)
32970+{
9dbd164d 32971+ int err;
b752ccd1
AM
32972+
32973+ err = 0;
86dc4139 32974+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
32975+ if (IS_ERR(au_wkq))
32976+ err = PTR_ERR(au_wkq);
32977+ else if (!au_wkq)
32978+ err = -ENOMEM;
b752ccd1
AM
32979+
32980+ return err;
1facf9fc 32981+}
7f207e10
AM
32982diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
32983--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
2000de60 32984+++ linux/fs/aufs/wkq.h 2015-03-27 21:56:35.470128334 +0100
523b37e3 32985@@ -0,0 +1,91 @@
1facf9fc 32986+/*
2000de60 32987+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 32988+ *
32989+ * This program, aufs is free software; you can redistribute it and/or modify
32990+ * it under the terms of the GNU General Public License as published by
32991+ * the Free Software Foundation; either version 2 of the License, or
32992+ * (at your option) any later version.
dece6358
AM
32993+ *
32994+ * This program is distributed in the hope that it will be useful,
32995+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32996+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32997+ * GNU General Public License for more details.
32998+ *
32999+ * You should have received a copy of the GNU General Public License
523b37e3 33000+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33001+ */
33002+
33003+/*
33004+ * workqueue for asynchronous/super-io operations
33005+ * todo: try new credentials management scheme
33006+ */
33007+
33008+#ifndef __AUFS_WKQ_H__
33009+#define __AUFS_WKQ_H__
33010+
33011+#ifdef __KERNEL__
33012+
dece6358
AM
33013+struct super_block;
33014+
1facf9fc 33015+/* ---------------------------------------------------------------------- */
33016+
33017+/*
33018+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
33019+ */
33020+struct au_nowait_tasks {
33021+ atomic_t nw_len;
33022+ wait_queue_head_t nw_wq;
33023+};
33024+
33025+/* ---------------------------------------------------------------------- */
33026+
33027+typedef void (*au_wkq_func_t)(void *args);
33028+
33029+/* wkq flags */
33030+#define AuWkq_WAIT 1
9dbd164d 33031+#define AuWkq_NEST (1 << 1)
1facf9fc 33032+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
33033+#define au_fset_wkq(flags, name) \
33034+ do { (flags) |= AuWkq_##name; } while (0)
33035+#define au_fclr_wkq(flags, name) \
33036+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 33037+
9dbd164d
AM
33038+#ifndef CONFIG_AUFS_HNOTIFY
33039+#undef AuWkq_NEST
33040+#define AuWkq_NEST 0
33041+#endif
33042+
1facf9fc 33043+/* wkq.c */
b752ccd1 33044+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
33045+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
33046+ unsigned int flags);
1facf9fc 33047+void au_nwt_init(struct au_nowait_tasks *nwt);
33048+int __init au_wkq_init(void);
33049+void au_wkq_fin(void);
33050+
33051+/* ---------------------------------------------------------------------- */
33052+
53392da6
AM
33053+static inline int au_wkq_test(void)
33054+{
33055+ return current->flags & PF_WQ_WORKER;
33056+}
33057+
b752ccd1 33058+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 33059+{
b752ccd1 33060+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 33061+}
33062+
33063+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
33064+{
e49829fe 33065+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 33066+ wake_up_all(&nwt->nw_wq);
33067+}
33068+
33069+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
33070+{
33071+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
33072+ return 0;
33073+}
33074+
33075+#endif /* __KERNEL__ */
33076+#endif /* __AUFS_WKQ_H__ */
c1595e42
JR
33077diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
33078--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
2000de60 33079+++ linux/fs/aufs/xattr.c 2015-03-27 21:56:35.470128334 +0100
c1595e42
JR
33080@@ -0,0 +1,334 @@
33081+/*
2000de60 33082+ * Copyright (C) 2014-2015 Junjiro R. Okajima
c1595e42
JR
33083+ *
33084+ * This program, aufs is free software; you can redistribute it and/or modify
33085+ * it under the terms of the GNU General Public License as published by
33086+ * the Free Software Foundation; either version 2 of the License, or
33087+ * (at your option) any later version.
33088+ *
33089+ * This program is distributed in the hope that it will be useful,
33090+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33091+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33092+ * GNU General Public License for more details.
33093+ *
33094+ * You should have received a copy of the GNU General Public License
33095+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
33096+ */
33097+
33098+/*
33099+ * handling xattr functions
33100+ */
33101+
33102+#include <linux/xattr.h>
33103+#include "aufs.h"
33104+
33105+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
33106+{
33107+ if (!ignore_flags)
33108+ goto out;
33109+ switch (err) {
33110+ case -ENOMEM:
33111+ case -EDQUOT:
33112+ goto out;
33113+ }
33114+
33115+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
33116+ err = 0;
33117+ goto out;
33118+ }
33119+
33120+#define cmp(brattr, prefix) do { \
33121+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
33122+ XATTR_##prefix##_PREFIX_LEN)) { \
33123+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
33124+ err = 0; \
33125+ goto out; \
33126+ } \
33127+ } while (0)
33128+
33129+ cmp(SEC, SECURITY);
33130+ cmp(SYS, SYSTEM);
33131+ cmp(TR, TRUSTED);
33132+ cmp(USR, USER);
33133+#undef cmp
33134+
33135+ if (ignore_flags & AuBrAttr_ICEX_OTH)
33136+ err = 0;
33137+
33138+out:
33139+ return err;
33140+}
33141+
33142+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
33143+
33144+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
33145+ char *name, char **buf, unsigned int ignore_flags)
33146+{
33147+ int err;
33148+ ssize_t ssz;
33149+ struct inode *h_idst;
33150+
33151+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
33152+ err = ssz;
33153+ if (unlikely(err <= 0)) {
33154+ AuTraceErr(err);
33155+ if (err == -ENODATA
33156+ || (err == -EOPNOTSUPP
33157+ && (ignore_flags & au_xattr_out_of_list)))
33158+ err = 0;
33159+ goto out;
33160+ }
33161+
33162+ /* unlock it temporary */
33163+ h_idst = h_dst->d_inode;
33164+ mutex_unlock(&h_idst->i_mutex);
33165+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
33166+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
33167+ if (unlikely(err)) {
33168+ AuDbg("%s, err %d\n", name, err);
33169+ err = au_xattr_ignore(err, name, ignore_flags);
33170+ }
33171+
33172+out:
33173+ return err;
33174+}
33175+
33176+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags)
33177+{
33178+ int err, unlocked, acl_access, acl_default;
33179+ ssize_t ssz;
33180+ struct inode *h_isrc, *h_idst;
33181+ char *value, *p, *o, *e;
33182+
33183+ /* try stopping to update the source inode while we are referencing */
33184+ /* there should not be the parent-child relation ship between them */
33185+ h_isrc = h_src->d_inode;
33186+ h_idst = h_dst->d_inode;
33187+ mutex_unlock(&h_idst->i_mutex);
33188+ mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
33189+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
33190+ unlocked = 0;
33191+
33192+ /* some filesystems don't list POSIX ACL, for example tmpfs */
33193+ ssz = vfs_listxattr(h_src, NULL, 0);
33194+ err = ssz;
33195+ if (unlikely(err < 0)) {
33196+ AuTraceErr(err);
33197+ if (err == -ENODATA
33198+ || err == -EOPNOTSUPP)
33199+ err = 0; /* ignore */
33200+ goto out;
33201+ }
33202+
33203+ err = 0;
33204+ p = NULL;
33205+ o = NULL;
33206+ if (ssz) {
33207+ err = -ENOMEM;
33208+ p = kmalloc(ssz, GFP_NOFS);
33209+ o = p;
33210+ if (unlikely(!p))
33211+ goto out;
33212+ err = vfs_listxattr(h_src, p, ssz);
33213+ }
33214+ mutex_unlock(&h_isrc->i_mutex);
33215+ unlocked = 1;
33216+ AuDbg("err %d, ssz %zd\n", err, ssz);
33217+ if (unlikely(err < 0))
33218+ goto out_free;
33219+
33220+ err = 0;
33221+ e = p + ssz;
33222+ value = NULL;
33223+ acl_access = 0;
33224+ acl_default = 0;
33225+ while (!err && p < e) {
33226+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
33227+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
33228+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
33229+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
33230+ - 1);
33231+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags);
33232+ p += strlen(p) + 1;
33233+ }
33234+ AuTraceErr(err);
33235+ ignore_flags |= au_xattr_out_of_list;
33236+ if (!err && !acl_access) {
33237+ err = au_do_cpup_xattr(h_dst, h_src,
33238+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
33239+ ignore_flags);
33240+ AuTraceErr(err);
33241+ }
33242+ if (!err && !acl_default) {
33243+ err = au_do_cpup_xattr(h_dst, h_src,
33244+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
33245+ ignore_flags);
33246+ AuTraceErr(err);
33247+ }
33248+
33249+ kfree(value);
33250+
33251+out_free:
33252+ kfree(o);
33253+out:
33254+ if (!unlocked)
33255+ mutex_unlock(&h_isrc->i_mutex);
33256+ AuTraceErr(err);
33257+ return err;
33258+}
33259+
33260+/* ---------------------------------------------------------------------- */
33261+
33262+enum {
33263+ AU_XATTR_LIST,
33264+ AU_XATTR_GET
33265+};
33266+
33267+struct au_lgxattr {
33268+ int type;
33269+ union {
33270+ struct {
33271+ char *list;
33272+ size_t size;
33273+ } list;
33274+ struct {
33275+ const char *name;
33276+ void *value;
33277+ size_t size;
33278+ } get;
33279+ } u;
33280+};
33281+
33282+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
33283+{
33284+ ssize_t err;
33285+ struct path h_path;
33286+ struct super_block *sb;
33287+
33288+ sb = dentry->d_sb;
33289+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
33290+ if (unlikely(err))
33291+ goto out;
33292+ err = au_h_path_getattr(dentry, /*force*/1, &h_path);
33293+ if (unlikely(err))
33294+ goto out_si;
33295+ if (unlikely(!h_path.dentry))
33296+ /* illegally overlapped or something */
33297+ goto out_di; /* pretending success */
33298+
33299+ /* always topmost entry only */
33300+ switch (arg->type) {
33301+ case AU_XATTR_LIST:
33302+ err = vfs_listxattr(h_path.dentry,
33303+ arg->u.list.list, arg->u.list.size);
33304+ break;
33305+ case AU_XATTR_GET:
33306+ err = vfs_getxattr(h_path.dentry,
33307+ arg->u.get.name, arg->u.get.value,
33308+ arg->u.get.size);
33309+ break;
33310+ }
33311+
33312+out_di:
33313+ di_read_unlock(dentry, AuLock_IR);
33314+out_si:
33315+ si_read_unlock(sb);
33316+out:
33317+ AuTraceErr(err);
33318+ return err;
33319+}
33320+
33321+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
33322+{
33323+ struct au_lgxattr arg = {
33324+ .type = AU_XATTR_LIST,
33325+ .u.list = {
33326+ .list = list,
33327+ .size = size
33328+ },
33329+ };
33330+
33331+ return au_lgxattr(dentry, &arg);
33332+}
33333+
33334+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
33335+ size_t size)
33336+{
33337+ struct au_lgxattr arg = {
33338+ .type = AU_XATTR_GET,
33339+ .u.get = {
33340+ .name = name,
33341+ .value = value,
33342+ .size = size
33343+ },
33344+ };
33345+
33346+ return au_lgxattr(dentry, &arg);
33347+}
33348+
33349+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
33350+ size_t size, int flags)
33351+{
33352+ struct au_srxattr arg = {
33353+ .type = AU_XATTR_SET,
33354+ .u.set = {
33355+ .name = name,
33356+ .value = value,
33357+ .size = size,
33358+ .flags = flags
33359+ },
33360+ };
33361+
33362+ return au_srxattr(dentry, &arg);
33363+}
33364+
33365+int aufs_removexattr(struct dentry *dentry, const char *name)
33366+{
33367+ struct au_srxattr arg = {
33368+ .type = AU_XATTR_REMOVE,
33369+ .u.remove = {
33370+ .name = name
33371+ },
33372+ };
33373+
33374+ return au_srxattr(dentry, &arg);
33375+}
33376+
33377+/* ---------------------------------------------------------------------- */
33378+
33379+#if 0
33380+static size_t au_xattr_list(struct dentry *dentry, char *list, size_t list_size,
33381+ const char *name, size_t name_len, int type)
33382+{
33383+ return aufs_listxattr(dentry, list, list_size);
33384+}
33385+
33386+static int au_xattr_get(struct dentry *dentry, const char *name, void *buffer,
33387+ size_t size, int type)
33388+{
33389+ return aufs_getxattr(dentry, name, buffer, size);
33390+}
33391+
33392+static int au_xattr_set(struct dentry *dentry, const char *name,
33393+ const void *value, size_t size, int flags, int type)
33394+{
33395+ return aufs_setxattr(dentry, name, value, size, flags);
33396+}
33397+
33398+static const struct xattr_handler au_xattr_handler = {
33399+ /* no prefix, no flags */
33400+ .list = au_xattr_list,
33401+ .get = au_xattr_get,
33402+ .set = au_xattr_set
33403+ /* why no remove? */
33404+};
33405+
33406+static const struct xattr_handler *au_xattr_handlers[] = {
33407+ &au_xattr_handler
33408+};
33409+
33410+void au_xattr_init(struct super_block *sb)
33411+{
33412+ /* sb->s_xattr = au_xattr_handlers; */
33413+}
33414+#endif
7f207e10
AM
33415diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
33416--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
2000de60 33417+++ linux/fs/aufs/xino.c 2015-03-27 21:56:35.470128334 +0100
c1595e42 33418@@ -0,0 +1,1318 @@
1facf9fc 33419+/*
2000de60 33420+ * Copyright (C) 2005-2015 Junjiro R. Okajima
1facf9fc 33421+ *
33422+ * This program, aufs is free software; you can redistribute it and/or modify
33423+ * it under the terms of the GNU General Public License as published by
33424+ * the Free Software Foundation; either version 2 of the License, or
33425+ * (at your option) any later version.
dece6358
AM
33426+ *
33427+ * This program is distributed in the hope that it will be useful,
33428+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33429+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33430+ * GNU General Public License for more details.
33431+ *
33432+ * You should have received a copy of the GNU General Public License
523b37e3 33433+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33434+ */
33435+
33436+/*
33437+ * external inode number translation table and bitmap
33438+ */
33439+
33440+#include <linux/seq_file.h>
392086de 33441+#include <linux/statfs.h>
1facf9fc 33442+#include "aufs.h"
33443+
9dbd164d 33444+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 33445+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 33446+ loff_t *pos)
33447+{
33448+ ssize_t err;
33449+ mm_segment_t oldfs;
b752ccd1
AM
33450+ union {
33451+ void *k;
33452+ char __user *u;
33453+ } buf;
1facf9fc 33454+
b752ccd1 33455+ buf.k = kbuf;
1facf9fc 33456+ oldfs = get_fs();
33457+ set_fs(KERNEL_DS);
33458+ do {
33459+ /* todo: signal_pending? */
b752ccd1 33460+ err = func(file, buf.u, size, pos);
1facf9fc 33461+ } while (err == -EAGAIN || err == -EINTR);
33462+ set_fs(oldfs);
33463+
33464+#if 0 /* reserved for future use */
33465+ if (err > 0)
2000de60 33466+ fsnotify_access(file->f_path.dentry);
1facf9fc 33467+#endif
33468+
33469+ return err;
33470+}
33471+
33472+/* ---------------------------------------------------------------------- */
33473+
b752ccd1 33474+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 33475+ size_t size, loff_t *pos)
33476+{
33477+ ssize_t err;
33478+ mm_segment_t oldfs;
b752ccd1
AM
33479+ union {
33480+ void *k;
33481+ const char __user *u;
33482+ } buf;
1facf9fc 33483+
b752ccd1 33484+ buf.k = kbuf;
1facf9fc 33485+ oldfs = get_fs();
33486+ set_fs(KERNEL_DS);
1facf9fc 33487+ do {
33488+ /* todo: signal_pending? */
b752ccd1 33489+ err = func(file, buf.u, size, pos);
1facf9fc 33490+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 33491+ set_fs(oldfs);
33492+
33493+#if 0 /* reserved for future use */
33494+ if (err > 0)
2000de60 33495+ fsnotify_modify(file->f_path.dentry);
1facf9fc 33496+#endif
33497+
33498+ return err;
33499+}
33500+
33501+struct do_xino_fwrite_args {
33502+ ssize_t *errp;
33503+ au_writef_t func;
33504+ struct file *file;
33505+ void *buf;
33506+ size_t size;
33507+ loff_t *pos;
33508+};
33509+
33510+static void call_do_xino_fwrite(void *args)
33511+{
33512+ struct do_xino_fwrite_args *a = args;
33513+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
33514+}
33515+
33516+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
33517+ loff_t *pos)
33518+{
33519+ ssize_t err;
33520+
33521+ /* todo: signal block and no wkq? */
b752ccd1
AM
33522+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
33523+ lockdep_off();
33524+ err = do_xino_fwrite(func, file, buf, size, pos);
33525+ lockdep_on();
33526+ } else {
33527+ /*
33528+ * it breaks RLIMIT_FSIZE and normal user's limit,
33529+ * users should care about quota and real 'filesystem full.'
33530+ */
1facf9fc 33531+ int wkq_err;
33532+ struct do_xino_fwrite_args args = {
33533+ .errp = &err,
33534+ .func = func,
33535+ .file = file,
33536+ .buf = buf,
33537+ .size = size,
33538+ .pos = pos
33539+ };
33540+
33541+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
33542+ if (unlikely(wkq_err))
33543+ err = wkq_err;
b752ccd1 33544+ }
1facf9fc 33545+
33546+ return err;
33547+}
33548+
33549+/* ---------------------------------------------------------------------- */
33550+
33551+/*
33552+ * create a new xinofile at the same place/path as @base_file.
33553+ */
33554+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
33555+{
33556+ struct file *file;
4a4d8108 33557+ struct dentry *base, *parent;
523b37e3 33558+ struct inode *dir, *delegated;
1facf9fc 33559+ struct qstr *name;
1308ab2a 33560+ struct path path;
4a4d8108 33561+ int err;
1facf9fc 33562+
2000de60 33563+ base = base_file->f_path.dentry;
1facf9fc 33564+ parent = base->d_parent; /* dir inode is locked */
33565+ dir = parent->d_inode;
33566+ IMustLock(dir);
33567+
33568+ file = ERR_PTR(-EINVAL);
33569+ name = &base->d_name;
4a4d8108
AM
33570+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
33571+ if (IS_ERR(path.dentry)) {
33572+ file = (void *)path.dentry;
523b37e3
AM
33573+ pr_err("%pd lookup err %ld\n",
33574+ base, PTR_ERR(path.dentry));
1facf9fc 33575+ goto out;
33576+ }
33577+
33578+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 33579+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 33580+ if (unlikely(err)) {
33581+ file = ERR_PTR(err);
523b37e3 33582+ pr_err("%pd create err %d\n", base, err);
1facf9fc 33583+ goto out_dput;
33584+ }
33585+
c06a8ce3 33586+ path.mnt = base_file->f_path.mnt;
4a4d8108 33587+ file = vfsub_dentry_open(&path,
7f207e10 33588+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 33589+ /* | __FMODE_NONOTIFY */);
1facf9fc 33590+ if (IS_ERR(file)) {
523b37e3 33591+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 33592+ goto out_dput;
33593+ }
33594+
523b37e3
AM
33595+ delegated = NULL;
33596+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
33597+ if (unlikely(err == -EWOULDBLOCK)) {
33598+ pr_warn("cannot retry for NFSv4 delegation"
33599+ " for an internal unlink\n");
33600+ iput(delegated);
33601+ }
1facf9fc 33602+ if (unlikely(err)) {
523b37e3 33603+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 33604+ goto out_fput;
33605+ }
33606+
33607+ if (copy_src) {
33608+ /* no one can touch copy_src xino */
c06a8ce3 33609+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 33610+ if (unlikely(err)) {
523b37e3 33611+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 33612+ goto out_fput;
33613+ }
33614+ }
33615+ goto out_dput; /* success */
33616+
4f0767ce 33617+out_fput:
1facf9fc 33618+ fput(file);
33619+ file = ERR_PTR(err);
4f0767ce 33620+out_dput:
4a4d8108 33621+ dput(path.dentry);
4f0767ce 33622+out:
1facf9fc 33623+ return file;
33624+}
33625+
33626+struct au_xino_lock_dir {
33627+ struct au_hinode *hdir;
33628+ struct dentry *parent;
33629+ struct mutex *mtx;
33630+};
33631+
33632+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
33633+ struct au_xino_lock_dir *ldir)
33634+{
33635+ aufs_bindex_t brid, bindex;
33636+
33637+ ldir->hdir = NULL;
33638+ bindex = -1;
33639+ brid = au_xino_brid(sb);
33640+ if (brid >= 0)
33641+ bindex = au_br_index(sb, brid);
33642+ if (bindex >= 0) {
33643+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 33644+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 33645+ } else {
2000de60 33646+ ldir->parent = dget_parent(xino->f_path.dentry);
1facf9fc 33647+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
33648+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
33649+ }
33650+}
33651+
33652+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
33653+{
33654+ if (ldir->hdir)
4a4d8108 33655+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 33656+ else {
33657+ mutex_unlock(ldir->mtx);
33658+ dput(ldir->parent);
33659+ }
33660+}
33661+
33662+/* ---------------------------------------------------------------------- */
33663+
33664+/* trucate xino files asynchronously */
33665+
33666+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
33667+{
33668+ int err;
392086de
AM
33669+ unsigned long jiffy;
33670+ blkcnt_t blocks;
1facf9fc 33671+ aufs_bindex_t bi, bend;
392086de 33672+ struct kstatfs *st;
1facf9fc 33673+ struct au_branch *br;
33674+ struct file *new_xino, *file;
33675+ struct super_block *h_sb;
33676+ struct au_xino_lock_dir ldir;
33677+
392086de
AM
33678+ err = -ENOMEM;
33679+ st = kzalloc(sizeof(*st), GFP_NOFS);
33680+ if (unlikely(!st))
33681+ goto out;
33682+
1facf9fc 33683+ err = -EINVAL;
33684+ bend = au_sbend(sb);
33685+ if (unlikely(bindex < 0 || bend < bindex))
392086de 33686+ goto out_st;
1facf9fc 33687+ br = au_sbr(sb, bindex);
33688+ file = br->br_xino.xi_file;
33689+ if (!file)
392086de
AM
33690+ goto out_st;
33691+
33692+ err = vfs_statfs(&file->f_path, st);
33693+ if (unlikely(err))
33694+ AuErr1("statfs err %d, ignored\n", err);
33695+ jiffy = jiffies;
33696+ blocks = file_inode(file)->i_blocks;
33697+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
33698+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 33699+
33700+ au_xino_lock_dir(sb, file, &ldir);
33701+ /* mnt_want_write() is unnecessary here */
33702+ new_xino = au_xino_create2(file, file);
33703+ au_xino_unlock_dir(&ldir);
33704+ err = PTR_ERR(new_xino);
392086de
AM
33705+ if (IS_ERR(new_xino)) {
33706+ pr_err("err %d, ignored\n", err);
33707+ goto out_st;
33708+ }
1facf9fc 33709+ err = 0;
33710+ fput(file);
33711+ br->br_xino.xi_file = new_xino;
33712+
86dc4139 33713+ h_sb = au_br_sb(br);
1facf9fc 33714+ for (bi = 0; bi <= bend; bi++) {
33715+ if (unlikely(bi == bindex))
33716+ continue;
33717+ br = au_sbr(sb, bi);
86dc4139 33718+ if (au_br_sb(br) != h_sb)
1facf9fc 33719+ continue;
33720+
33721+ fput(br->br_xino.xi_file);
33722+ br->br_xino.xi_file = new_xino;
33723+ get_file(new_xino);
33724+ }
33725+
392086de
AM
33726+ err = vfs_statfs(&new_xino->f_path, st);
33727+ if (!err) {
33728+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
33729+ bindex, (u64)file_inode(new_xino)->i_blocks,
33730+ st->f_bfree, st->f_blocks);
33731+ if (file_inode(new_xino)->i_blocks < blocks)
33732+ au_sbi(sb)->si_xino_jiffy = jiffy;
33733+ } else
33734+ AuErr1("statfs err %d, ignored\n", err);
33735+
33736+out_st:
33737+ kfree(st);
4f0767ce 33738+out:
1facf9fc 33739+ return err;
33740+}
33741+
33742+struct xino_do_trunc_args {
33743+ struct super_block *sb;
33744+ struct au_branch *br;
33745+};
33746+
33747+static void xino_do_trunc(void *_args)
33748+{
33749+ struct xino_do_trunc_args *args = _args;
33750+ struct super_block *sb;
33751+ struct au_branch *br;
33752+ struct inode *dir;
33753+ int err;
33754+ aufs_bindex_t bindex;
33755+
33756+ err = 0;
33757+ sb = args->sb;
33758+ dir = sb->s_root->d_inode;
33759+ br = args->br;
33760+
33761+ si_noflush_write_lock(sb);
33762+ ii_read_lock_parent(dir);
33763+ bindex = au_br_index(sb, br->br_id);
33764+ err = au_xino_trunc(sb, bindex);
1facf9fc 33765+ ii_read_unlock(dir);
33766+ if (unlikely(err))
392086de 33767+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 33768+ atomic_dec(&br->br_xino_running);
33769+ atomic_dec(&br->br_count);
1facf9fc 33770+ si_write_unlock(sb);
027c5e7a 33771+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 33772+ kfree(args);
33773+}
33774+
392086de
AM
33775+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
33776+{
33777+ int err;
33778+ struct kstatfs st;
33779+ struct au_sbinfo *sbinfo;
33780+
33781+ /* todo: si_xino_expire and the ratio should be customizable */
33782+ sbinfo = au_sbi(sb);
33783+ if (time_before(jiffies,
33784+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
33785+ return 0;
33786+
33787+ /* truncation border */
33788+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
33789+ if (unlikely(err)) {
33790+ AuErr1("statfs err %d, ignored\n", err);
33791+ return 0;
33792+ }
33793+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
33794+ return 0;
33795+
33796+ return 1;
33797+}
33798+
1facf9fc 33799+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
33800+{
33801+ struct xino_do_trunc_args *args;
33802+ int wkq_err;
33803+
392086de 33804+ if (!xino_trunc_test(sb, br))
1facf9fc 33805+ return;
33806+
33807+ if (atomic_inc_return(&br->br_xino_running) > 1)
33808+ goto out;
33809+
33810+ /* lock and kfree() will be called in trunc_xino() */
33811+ args = kmalloc(sizeof(*args), GFP_NOFS);
33812+ if (unlikely(!args)) {
33813+ AuErr1("no memory\n");
33814+ goto out_args;
33815+ }
33816+
e49829fe 33817+ atomic_inc(&br->br_count);
1facf9fc 33818+ args->sb = sb;
33819+ args->br = br;
53392da6 33820+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 33821+ if (!wkq_err)
33822+ return; /* success */
33823+
4a4d8108 33824+ pr_err("wkq %d\n", wkq_err);
e49829fe 33825+ atomic_dec(&br->br_count);
1facf9fc 33826+
4f0767ce 33827+out_args:
1facf9fc 33828+ kfree(args);
4f0767ce 33829+out:
e49829fe 33830+ atomic_dec(&br->br_xino_running);
1facf9fc 33831+}
33832+
33833+/* ---------------------------------------------------------------------- */
33834+
33835+static int au_xino_do_write(au_writef_t write, struct file *file,
33836+ ino_t h_ino, ino_t ino)
33837+{
33838+ loff_t pos;
33839+ ssize_t sz;
33840+
33841+ pos = h_ino;
33842+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
33843+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
33844+ return -EFBIG;
33845+ }
33846+ pos *= sizeof(ino);
33847+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
33848+ if (sz == sizeof(ino))
33849+ return 0; /* success */
33850+
33851+ AuIOErr("write failed (%zd)\n", sz);
33852+ return -EIO;
33853+}
33854+
33855+/*
33856+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
33857+ * at the position of @h_ino.
33858+ * even if @ino is zero, it is written to the xinofile and means no entry.
33859+ * if the size of the xino file on a specific filesystem exceeds the watermark,
33860+ * try truncating it.
33861+ */
33862+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
33863+ ino_t ino)
33864+{
33865+ int err;
33866+ unsigned int mnt_flags;
33867+ struct au_branch *br;
33868+
33869+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
33870+ || ((loff_t)-1) > 0);
dece6358 33871+ SiMustAnyLock(sb);
1facf9fc 33872+
33873+ mnt_flags = au_mntflags(sb);
33874+ if (!au_opt_test(mnt_flags, XINO))
33875+ return 0;
33876+
33877+ br = au_sbr(sb, bindex);
33878+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
33879+ h_ino, ino);
33880+ if (!err) {
33881+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 33882+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 33883+ xino_try_trunc(sb, br);
33884+ return 0; /* success */
33885+ }
33886+
33887+ AuIOErr("write failed (%d)\n", err);
33888+ return -EIO;
33889+}
33890+
33891+/* ---------------------------------------------------------------------- */
33892+
33893+/* aufs inode number bitmap */
33894+
33895+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
33896+static ino_t xib_calc_ino(unsigned long pindex, int bit)
33897+{
33898+ ino_t ino;
33899+
33900+ AuDebugOn(bit < 0 || page_bits <= bit);
33901+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
33902+ return ino;
33903+}
33904+
33905+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
33906+{
33907+ AuDebugOn(ino < AUFS_FIRST_INO);
33908+ ino -= AUFS_FIRST_INO;
33909+ *pindex = ino / page_bits;
33910+ *bit = ino % page_bits;
33911+}
33912+
33913+static int xib_pindex(struct super_block *sb, unsigned long pindex)
33914+{
33915+ int err;
33916+ loff_t pos;
33917+ ssize_t sz;
33918+ struct au_sbinfo *sbinfo;
33919+ struct file *xib;
33920+ unsigned long *p;
33921+
33922+ sbinfo = au_sbi(sb);
33923+ MtxMustLock(&sbinfo->si_xib_mtx);
33924+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
33925+ || !au_opt_test(sbinfo->si_mntflags, XINO));
33926+
33927+ if (pindex == sbinfo->si_xib_last_pindex)
33928+ return 0;
33929+
33930+ xib = sbinfo->si_xib;
33931+ p = sbinfo->si_xib_buf;
33932+ pos = sbinfo->si_xib_last_pindex;
33933+ pos *= PAGE_SIZE;
33934+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
33935+ if (unlikely(sz != PAGE_SIZE))
33936+ goto out;
33937+
33938+ pos = pindex;
33939+ pos *= PAGE_SIZE;
c06a8ce3 33940+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 33941+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
33942+ else {
33943+ memset(p, 0, PAGE_SIZE);
33944+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
33945+ }
33946+ if (sz == PAGE_SIZE) {
33947+ sbinfo->si_xib_last_pindex = pindex;
33948+ return 0; /* success */
33949+ }
33950+
4f0767ce 33951+out:
b752ccd1
AM
33952+ AuIOErr1("write failed (%zd)\n", sz);
33953+ err = sz;
33954+ if (sz >= 0)
33955+ err = -EIO;
33956+ return err;
33957+}
33958+
33959+/* ---------------------------------------------------------------------- */
33960+
33961+static void au_xib_clear_bit(struct inode *inode)
33962+{
33963+ int err, bit;
33964+ unsigned long pindex;
33965+ struct super_block *sb;
33966+ struct au_sbinfo *sbinfo;
33967+
33968+ AuDebugOn(inode->i_nlink);
33969+
33970+ sb = inode->i_sb;
33971+ xib_calc_bit(inode->i_ino, &pindex, &bit);
33972+ AuDebugOn(page_bits <= bit);
33973+ sbinfo = au_sbi(sb);
33974+ mutex_lock(&sbinfo->si_xib_mtx);
33975+ err = xib_pindex(sb, pindex);
33976+ if (!err) {
33977+ clear_bit(bit, sbinfo->si_xib_buf);
33978+ sbinfo->si_xib_next_bit = bit;
33979+ }
33980+ mutex_unlock(&sbinfo->si_xib_mtx);
33981+}
33982+
33983+/* for s_op->delete_inode() */
33984+void au_xino_delete_inode(struct inode *inode, const int unlinked)
33985+{
33986+ int err;
33987+ unsigned int mnt_flags;
33988+ aufs_bindex_t bindex, bend, bi;
33989+ unsigned char try_trunc;
33990+ struct au_iinfo *iinfo;
33991+ struct super_block *sb;
33992+ struct au_hinode *hi;
33993+ struct inode *h_inode;
33994+ struct au_branch *br;
33995+ au_writef_t xwrite;
33996+
33997+ sb = inode->i_sb;
33998+ mnt_flags = au_mntflags(sb);
33999+ if (!au_opt_test(mnt_flags, XINO)
34000+ || inode->i_ino == AUFS_ROOT_INO)
34001+ return;
34002+
34003+ if (unlinked) {
34004+ au_xigen_inc(inode);
34005+ au_xib_clear_bit(inode);
34006+ }
34007+
34008+ iinfo = au_ii(inode);
34009+ if (!iinfo)
34010+ return;
1facf9fc 34011+
b752ccd1
AM
34012+ bindex = iinfo->ii_bstart;
34013+ if (bindex < 0)
34014+ return;
1facf9fc 34015+
b752ccd1
AM
34016+ xwrite = au_sbi(sb)->si_xwrite;
34017+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
34018+ hi = iinfo->ii_hinode + bindex;
34019+ bend = iinfo->ii_bend;
34020+ for (; bindex <= bend; bindex++, hi++) {
34021+ h_inode = hi->hi_inode;
34022+ if (!h_inode
34023+ || (!unlinked && h_inode->i_nlink))
34024+ continue;
1facf9fc 34025+
b752ccd1
AM
34026+ /* inode may not be revalidated */
34027+ bi = au_br_index(sb, hi->hi_id);
34028+ if (bi < 0)
34029+ continue;
1facf9fc 34030+
b752ccd1
AM
34031+ br = au_sbr(sb, bi);
34032+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
34033+ h_inode->i_ino, /*ino*/0);
34034+ if (!err && try_trunc
86dc4139 34035+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 34036+ xino_try_trunc(sb, br);
1facf9fc 34037+ }
1facf9fc 34038+}
34039+
34040+/* get an unused inode number from bitmap */
34041+ino_t au_xino_new_ino(struct super_block *sb)
34042+{
34043+ ino_t ino;
34044+ unsigned long *p, pindex, ul, pend;
34045+ struct au_sbinfo *sbinfo;
34046+ struct file *file;
34047+ int free_bit, err;
34048+
34049+ if (!au_opt_test(au_mntflags(sb), XINO))
34050+ return iunique(sb, AUFS_FIRST_INO);
34051+
34052+ sbinfo = au_sbi(sb);
34053+ mutex_lock(&sbinfo->si_xib_mtx);
34054+ p = sbinfo->si_xib_buf;
34055+ free_bit = sbinfo->si_xib_next_bit;
34056+ if (free_bit < page_bits && !test_bit(free_bit, p))
34057+ goto out; /* success */
34058+ free_bit = find_first_zero_bit(p, page_bits);
34059+ if (free_bit < page_bits)
34060+ goto out; /* success */
34061+
34062+ pindex = sbinfo->si_xib_last_pindex;
34063+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
34064+ err = xib_pindex(sb, ul);
34065+ if (unlikely(err))
34066+ goto out_err;
34067+ free_bit = find_first_zero_bit(p, page_bits);
34068+ if (free_bit < page_bits)
34069+ goto out; /* success */
34070+ }
34071+
34072+ file = sbinfo->si_xib;
c06a8ce3 34073+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 34074+ for (ul = pindex + 1; ul <= pend; ul++) {
34075+ err = xib_pindex(sb, ul);
34076+ if (unlikely(err))
34077+ goto out_err;
34078+ free_bit = find_first_zero_bit(p, page_bits);
34079+ if (free_bit < page_bits)
34080+ goto out; /* success */
34081+ }
34082+ BUG();
34083+
4f0767ce 34084+out:
1facf9fc 34085+ set_bit(free_bit, p);
7f207e10 34086+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 34087+ pindex = sbinfo->si_xib_last_pindex;
34088+ mutex_unlock(&sbinfo->si_xib_mtx);
34089+ ino = xib_calc_ino(pindex, free_bit);
34090+ AuDbg("i%lu\n", (unsigned long)ino);
34091+ return ino;
4f0767ce 34092+out_err:
1facf9fc 34093+ mutex_unlock(&sbinfo->si_xib_mtx);
34094+ AuDbg("i0\n");
34095+ return 0;
34096+}
34097+
34098+/*
34099+ * read @ino from xinofile for the specified branch{@sb, @bindex}
34100+ * at the position of @h_ino.
34101+ * if @ino does not exist and @do_new is true, get new one.
34102+ */
34103+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
34104+ ino_t *ino)
34105+{
34106+ int err;
34107+ ssize_t sz;
34108+ loff_t pos;
34109+ struct file *file;
34110+ struct au_sbinfo *sbinfo;
34111+
34112+ *ino = 0;
34113+ if (!au_opt_test(au_mntflags(sb), XINO))
34114+ return 0; /* no xino */
34115+
34116+ err = 0;
34117+ sbinfo = au_sbi(sb);
34118+ pos = h_ino;
34119+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
34120+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
34121+ return -EFBIG;
34122+ }
34123+ pos *= sizeof(*ino);
34124+
34125+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 34126+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 34127+ return 0; /* no ino */
34128+
34129+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
34130+ if (sz == sizeof(*ino))
34131+ return 0; /* success */
34132+
34133+ err = sz;
34134+ if (unlikely(sz >= 0)) {
34135+ err = -EIO;
34136+ AuIOErr("xino read error (%zd)\n", sz);
34137+ }
34138+
34139+ return err;
34140+}
34141+
34142+/* ---------------------------------------------------------------------- */
34143+
34144+/* create and set a new xino file */
34145+
34146+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
34147+{
34148+ struct file *file;
34149+ struct dentry *h_parent, *d;
34150+ struct inode *h_dir;
34151+ int err;
34152+
34153+ /*
34154+ * at mount-time, and the xino file is the default path,
4a4d8108 34155+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 34156+ * when a user specified the xino, we cannot get au_hdir to be ignored.
34157+ */
7f207e10 34158+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 34159+ /* | __FMODE_NONOTIFY */,
1facf9fc 34160+ S_IRUGO | S_IWUGO);
34161+ if (IS_ERR(file)) {
34162+ if (!silent)
4a4d8108 34163+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 34164+ return file;
34165+ }
34166+
34167+ /* keep file count */
2000de60 34168+ h_parent = dget_parent(file->f_path.dentry);
1facf9fc 34169+ h_dir = h_parent->d_inode;
34170+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
34171+ /* mnt_want_write() is unnecessary here */
523b37e3
AM
34172+ /* no delegation since it is just created */
34173+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, /*force*/0);
1facf9fc 34174+ mutex_unlock(&h_dir->i_mutex);
34175+ dput(h_parent);
34176+ if (unlikely(err)) {
34177+ if (!silent)
4a4d8108 34178+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 34179+ goto out;
34180+ }
34181+
34182+ err = -EINVAL;
2000de60 34183+ d = file->f_path.dentry;
1facf9fc 34184+ if (unlikely(sb == d->d_sb)) {
34185+ if (!silent)
4a4d8108 34186+ pr_err("%s must be outside\n", fname);
1facf9fc 34187+ goto out;
34188+ }
34189+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
34190+ if (!silent)
4a4d8108
AM
34191+ pr_err("xino doesn't support %s(%s)\n",
34192+ fname, au_sbtype(d->d_sb));
1facf9fc 34193+ goto out;
34194+ }
34195+ return file; /* success */
34196+
4f0767ce 34197+out:
1facf9fc 34198+ fput(file);
34199+ file = ERR_PTR(err);
34200+ return file;
34201+}
34202+
34203+/*
34204+ * find another branch who is on the same filesystem of the specified
34205+ * branch{@btgt}. search until @bend.
34206+ */
34207+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
34208+ aufs_bindex_t bend)
34209+{
34210+ aufs_bindex_t bindex;
34211+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
34212+
34213+ for (bindex = 0; bindex < btgt; bindex++)
34214+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
34215+ return bindex;
34216+ for (bindex++; bindex <= bend; bindex++)
34217+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
34218+ return bindex;
34219+ return -1;
34220+}
34221+
34222+/* ---------------------------------------------------------------------- */
34223+
34224+/*
34225+ * initialize the xinofile for the specified branch @br
34226+ * at the place/path where @base_file indicates.
34227+ * test whether another branch is on the same filesystem or not,
34228+ * if @do_test is true.
34229+ */
34230+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
34231+ struct file *base_file, int do_test)
34232+{
34233+ int err;
34234+ ino_t ino;
34235+ aufs_bindex_t bend, bindex;
34236+ struct au_branch *shared_br, *b;
34237+ struct file *file;
34238+ struct super_block *tgt_sb;
34239+
34240+ shared_br = NULL;
34241+ bend = au_sbend(sb);
34242+ if (do_test) {
86dc4139 34243+ tgt_sb = au_br_sb(br);
1facf9fc 34244+ for (bindex = 0; bindex <= bend; bindex++) {
34245+ b = au_sbr(sb, bindex);
86dc4139 34246+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 34247+ shared_br = b;
34248+ break;
34249+ }
34250+ }
34251+ }
34252+
34253+ if (!shared_br || !shared_br->br_xino.xi_file) {
34254+ struct au_xino_lock_dir ldir;
34255+
34256+ au_xino_lock_dir(sb, base_file, &ldir);
34257+ /* mnt_want_write() is unnecessary here */
34258+ file = au_xino_create2(base_file, NULL);
34259+ au_xino_unlock_dir(&ldir);
34260+ err = PTR_ERR(file);
34261+ if (IS_ERR(file))
34262+ goto out;
34263+ br->br_xino.xi_file = file;
34264+ } else {
34265+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
34266+ get_file(br->br_xino.xi_file);
34267+ }
34268+
34269+ ino = AUFS_ROOT_INO;
34270+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
34271+ h_ino, ino);
b752ccd1
AM
34272+ if (unlikely(err)) {
34273+ fput(br->br_xino.xi_file);
34274+ br->br_xino.xi_file = NULL;
34275+ }
1facf9fc 34276+
4f0767ce 34277+out:
1facf9fc 34278+ return err;
34279+}
34280+
34281+/* ---------------------------------------------------------------------- */
34282+
34283+/* trucate a xino bitmap file */
34284+
34285+/* todo: slow */
34286+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
34287+{
34288+ int err, bit;
34289+ ssize_t sz;
34290+ unsigned long pindex;
34291+ loff_t pos, pend;
34292+ struct au_sbinfo *sbinfo;
34293+ au_readf_t func;
34294+ ino_t *ino;
34295+ unsigned long *p;
34296+
34297+ err = 0;
34298+ sbinfo = au_sbi(sb);
dece6358 34299+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 34300+ p = sbinfo->si_xib_buf;
34301+ func = sbinfo->si_xread;
c06a8ce3 34302+ pend = vfsub_f_size_read(file);
1facf9fc 34303+ pos = 0;
34304+ while (pos < pend) {
34305+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
34306+ err = sz;
34307+ if (unlikely(sz <= 0))
34308+ goto out;
34309+
34310+ err = 0;
34311+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
34312+ if (unlikely(*ino < AUFS_FIRST_INO))
34313+ continue;
34314+
34315+ xib_calc_bit(*ino, &pindex, &bit);
34316+ AuDebugOn(page_bits <= bit);
34317+ err = xib_pindex(sb, pindex);
34318+ if (!err)
34319+ set_bit(bit, p);
34320+ else
34321+ goto out;
34322+ }
34323+ }
34324+
4f0767ce 34325+out:
1facf9fc 34326+ return err;
34327+}
34328+
34329+static int xib_restore(struct super_block *sb)
34330+{
34331+ int err;
34332+ aufs_bindex_t bindex, bend;
34333+ void *page;
34334+
34335+ err = -ENOMEM;
34336+ page = (void *)__get_free_page(GFP_NOFS);
34337+ if (unlikely(!page))
34338+ goto out;
34339+
34340+ err = 0;
34341+ bend = au_sbend(sb);
34342+ for (bindex = 0; !err && bindex <= bend; bindex++)
34343+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
34344+ err = do_xib_restore
34345+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
34346+ else
34347+ AuDbg("b%d\n", bindex);
34348+ free_page((unsigned long)page);
34349+
4f0767ce 34350+out:
1facf9fc 34351+ return err;
34352+}
34353+
34354+int au_xib_trunc(struct super_block *sb)
34355+{
34356+ int err;
34357+ ssize_t sz;
34358+ loff_t pos;
34359+ struct au_xino_lock_dir ldir;
34360+ struct au_sbinfo *sbinfo;
34361+ unsigned long *p;
34362+ struct file *file;
34363+
dece6358
AM
34364+ SiMustWriteLock(sb);
34365+
1facf9fc 34366+ err = 0;
34367+ sbinfo = au_sbi(sb);
34368+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
34369+ goto out;
34370+
34371+ file = sbinfo->si_xib;
c06a8ce3 34372+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 34373+ goto out;
34374+
34375+ au_xino_lock_dir(sb, file, &ldir);
34376+ /* mnt_want_write() is unnecessary here */
34377+ file = au_xino_create2(sbinfo->si_xib, NULL);
34378+ au_xino_unlock_dir(&ldir);
34379+ err = PTR_ERR(file);
34380+ if (IS_ERR(file))
34381+ goto out;
34382+ fput(sbinfo->si_xib);
34383+ sbinfo->si_xib = file;
34384+
34385+ p = sbinfo->si_xib_buf;
34386+ memset(p, 0, PAGE_SIZE);
34387+ pos = 0;
34388+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
34389+ if (unlikely(sz != PAGE_SIZE)) {
34390+ err = sz;
34391+ AuIOErr("err %d\n", err);
34392+ if (sz >= 0)
34393+ err = -EIO;
34394+ goto out;
34395+ }
34396+
34397+ mutex_lock(&sbinfo->si_xib_mtx);
34398+ /* mnt_want_write() is unnecessary here */
34399+ err = xib_restore(sb);
34400+ mutex_unlock(&sbinfo->si_xib_mtx);
34401+
34402+out:
34403+ return err;
34404+}
34405+
34406+/* ---------------------------------------------------------------------- */
34407+
34408+/*
34409+ * xino mount option handlers
34410+ */
34411+static au_readf_t find_readf(struct file *h_file)
34412+{
34413+ const struct file_operations *fop = h_file->f_op;
34414+
523b37e3
AM
34415+ if (fop->read)
34416+ return fop->read;
34417+ if (fop->aio_read)
34418+ return do_sync_read;
076b876e
AM
34419+ if (fop->read_iter)
34420+ return new_sync_read;
1facf9fc 34421+ return ERR_PTR(-ENOSYS);
34422+}
34423+
34424+static au_writef_t find_writef(struct file *h_file)
34425+{
34426+ const struct file_operations *fop = h_file->f_op;
34427+
523b37e3
AM
34428+ if (fop->write)
34429+ return fop->write;
34430+ if (fop->aio_write)
34431+ return do_sync_write;
076b876e
AM
34432+ if (fop->write_iter)
34433+ return new_sync_write;
1facf9fc 34434+ return ERR_PTR(-ENOSYS);
34435+}
34436+
34437+/* xino bitmap */
34438+static void xino_clear_xib(struct super_block *sb)
34439+{
34440+ struct au_sbinfo *sbinfo;
34441+
dece6358
AM
34442+ SiMustWriteLock(sb);
34443+
1facf9fc 34444+ sbinfo = au_sbi(sb);
34445+ sbinfo->si_xread = NULL;
34446+ sbinfo->si_xwrite = NULL;
34447+ if (sbinfo->si_xib)
34448+ fput(sbinfo->si_xib);
34449+ sbinfo->si_xib = NULL;
34450+ free_page((unsigned long)sbinfo->si_xib_buf);
34451+ sbinfo->si_xib_buf = NULL;
34452+}
34453+
34454+static int au_xino_set_xib(struct super_block *sb, struct file *base)
34455+{
34456+ int err;
34457+ loff_t pos;
34458+ struct au_sbinfo *sbinfo;
34459+ struct file *file;
34460+
dece6358
AM
34461+ SiMustWriteLock(sb);
34462+
1facf9fc 34463+ sbinfo = au_sbi(sb);
34464+ file = au_xino_create2(base, sbinfo->si_xib);
34465+ err = PTR_ERR(file);
34466+ if (IS_ERR(file))
34467+ goto out;
34468+ if (sbinfo->si_xib)
34469+ fput(sbinfo->si_xib);
34470+ sbinfo->si_xib = file;
34471+ sbinfo->si_xread = find_readf(file);
34472+ sbinfo->si_xwrite = find_writef(file);
34473+
34474+ err = -ENOMEM;
34475+ if (!sbinfo->si_xib_buf)
34476+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
34477+ if (unlikely(!sbinfo->si_xib_buf))
34478+ goto out_unset;
34479+
34480+ sbinfo->si_xib_last_pindex = 0;
34481+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 34482+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 34483+ pos = 0;
34484+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
34485+ PAGE_SIZE, &pos);
34486+ if (unlikely(err != PAGE_SIZE))
34487+ goto out_free;
34488+ }
34489+ err = 0;
34490+ goto out; /* success */
34491+
4f0767ce 34492+out_free:
1facf9fc 34493+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
34494+ sbinfo->si_xib_buf = NULL;
34495+ if (err >= 0)
34496+ err = -EIO;
4f0767ce 34497+out_unset:
b752ccd1
AM
34498+ fput(sbinfo->si_xib);
34499+ sbinfo->si_xib = NULL;
34500+ sbinfo->si_xread = NULL;
34501+ sbinfo->si_xwrite = NULL;
4f0767ce 34502+out:
b752ccd1 34503+ return err;
1facf9fc 34504+}
34505+
b752ccd1
AM
34506+/* xino for each branch */
34507+static void xino_clear_br(struct super_block *sb)
34508+{
34509+ aufs_bindex_t bindex, bend;
34510+ struct au_branch *br;
1facf9fc 34511+
b752ccd1
AM
34512+ bend = au_sbend(sb);
34513+ for (bindex = 0; bindex <= bend; bindex++) {
34514+ br = au_sbr(sb, bindex);
34515+ if (!br || !br->br_xino.xi_file)
34516+ continue;
34517+
34518+ fput(br->br_xino.xi_file);
34519+ br->br_xino.xi_file = NULL;
34520+ }
34521+}
34522+
34523+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 34524+{
34525+ int err;
b752ccd1
AM
34526+ ino_t ino;
34527+ aufs_bindex_t bindex, bend, bshared;
34528+ struct {
34529+ struct file *old, *new;
34530+ } *fpair, *p;
34531+ struct au_branch *br;
34532+ struct inode *inode;
34533+ au_writef_t writef;
1facf9fc 34534+
b752ccd1
AM
34535+ SiMustWriteLock(sb);
34536+
34537+ err = -ENOMEM;
34538+ bend = au_sbend(sb);
34539+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
34540+ if (unlikely(!fpair))
1facf9fc 34541+ goto out;
34542+
b752ccd1
AM
34543+ inode = sb->s_root->d_inode;
34544+ ino = AUFS_ROOT_INO;
34545+ writef = au_sbi(sb)->si_xwrite;
34546+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
34547+ br = au_sbr(sb, bindex);
34548+ bshared = is_sb_shared(sb, bindex, bindex - 1);
34549+ if (bshared >= 0) {
34550+ /* shared xino */
34551+ *p = fpair[bshared];
34552+ get_file(p->new);
34553+ }
34554+
34555+ if (!p->new) {
34556+ /* new xino */
34557+ p->old = br->br_xino.xi_file;
34558+ p->new = au_xino_create2(base, br->br_xino.xi_file);
34559+ err = PTR_ERR(p->new);
34560+ if (IS_ERR(p->new)) {
34561+ p->new = NULL;
34562+ goto out_pair;
34563+ }
34564+ }
34565+
34566+ err = au_xino_do_write(writef, p->new,
34567+ au_h_iptr(inode, bindex)->i_ino, ino);
34568+ if (unlikely(err))
34569+ goto out_pair;
34570+ }
34571+
34572+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
34573+ br = au_sbr(sb, bindex);
34574+ if (br->br_xino.xi_file)
34575+ fput(br->br_xino.xi_file);
34576+ get_file(p->new);
34577+ br->br_xino.xi_file = p->new;
34578+ }
1facf9fc 34579+
4f0767ce 34580+out_pair:
b752ccd1
AM
34581+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
34582+ if (p->new)
34583+ fput(p->new);
34584+ else
34585+ break;
34586+ kfree(fpair);
4f0767ce 34587+out:
1facf9fc 34588+ return err;
34589+}
b752ccd1
AM
34590+
34591+void au_xino_clr(struct super_block *sb)
34592+{
34593+ struct au_sbinfo *sbinfo;
34594+
34595+ au_xigen_clr(sb);
34596+ xino_clear_xib(sb);
34597+ xino_clear_br(sb);
34598+ sbinfo = au_sbi(sb);
34599+ /* lvalue, do not call au_mntflags() */
34600+ au_opt_clr(sbinfo->si_mntflags, XINO);
34601+}
34602+
34603+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
34604+{
34605+ int err, skip;
34606+ struct dentry *parent, *cur_parent;
34607+ struct qstr *dname, *cur_name;
34608+ struct file *cur_xino;
34609+ struct inode *dir;
34610+ struct au_sbinfo *sbinfo;
34611+
34612+ SiMustWriteLock(sb);
34613+
34614+ err = 0;
34615+ sbinfo = au_sbi(sb);
2000de60 34616+ parent = dget_parent(xino->file->f_path.dentry);
b752ccd1
AM
34617+ if (remount) {
34618+ skip = 0;
2000de60 34619+ dname = &xino->file->f_path.dentry->d_name;
b752ccd1
AM
34620+ cur_xino = sbinfo->si_xib;
34621+ if (cur_xino) {
2000de60
JR
34622+ cur_parent = dget_parent(cur_xino->f_path.dentry);
34623+ cur_name = &cur_xino->f_path.dentry->d_name;
b752ccd1 34624+ skip = (cur_parent == parent
38d290e6 34625+ && au_qstreq(dname, cur_name));
b752ccd1
AM
34626+ dput(cur_parent);
34627+ }
34628+ if (skip)
34629+ goto out;
34630+ }
34631+
34632+ au_opt_set(sbinfo->si_mntflags, XINO);
34633+ dir = parent->d_inode;
34634+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
34635+ /* mnt_want_write() is unnecessary here */
34636+ err = au_xino_set_xib(sb, xino->file);
34637+ if (!err)
34638+ err = au_xigen_set(sb, xino->file);
34639+ if (!err)
34640+ err = au_xino_set_br(sb, xino->file);
34641+ mutex_unlock(&dir->i_mutex);
34642+ if (!err)
34643+ goto out; /* success */
34644+
34645+ /* reset all */
34646+ AuIOErr("failed creating xino(%d).\n", err);
c1595e42
JR
34647+ au_xigen_clr(sb);
34648+ xino_clear_xib(sb);
b752ccd1 34649+
4f0767ce 34650+out:
b752ccd1
AM
34651+ dput(parent);
34652+ return err;
34653+}
34654+
34655+/* ---------------------------------------------------------------------- */
34656+
34657+/*
34658+ * create a xinofile at the default place/path.
34659+ */
34660+struct file *au_xino_def(struct super_block *sb)
34661+{
34662+ struct file *file;
34663+ char *page, *p;
34664+ struct au_branch *br;
34665+ struct super_block *h_sb;
34666+ struct path path;
34667+ aufs_bindex_t bend, bindex, bwr;
34668+
34669+ br = NULL;
34670+ bend = au_sbend(sb);
34671+ bwr = -1;
34672+ for (bindex = 0; bindex <= bend; bindex++) {
34673+ br = au_sbr(sb, bindex);
34674+ if (au_br_writable(br->br_perm)
86dc4139 34675+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
34676+ bwr = bindex;
34677+ break;
34678+ }
34679+ }
34680+
7f207e10
AM
34681+ if (bwr >= 0) {
34682+ file = ERR_PTR(-ENOMEM);
537831f9 34683+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
34684+ if (unlikely(!page))
34685+ goto out;
86dc4139 34686+ path.mnt = au_br_mnt(br);
7f207e10
AM
34687+ path.dentry = au_h_dptr(sb->s_root, bwr);
34688+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
34689+ file = (void *)p;
34690+ if (!IS_ERR(p)) {
34691+ strcat(p, "/" AUFS_XINO_FNAME);
34692+ AuDbg("%s\n", p);
34693+ file = au_xino_create(sb, p, /*silent*/0);
34694+ if (!IS_ERR(file))
34695+ au_xino_brid_set(sb, br->br_id);
34696+ }
537831f9 34697+ free_page((unsigned long)page);
7f207e10
AM
34698+ } else {
34699+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
34700+ if (IS_ERR(file))
34701+ goto out;
2000de60 34702+ h_sb = file->f_path.dentry->d_sb;
7f207e10
AM
34703+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
34704+ pr_err("xino doesn't support %s(%s)\n",
34705+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
34706+ fput(file);
34707+ file = ERR_PTR(-EINVAL);
34708+ }
34709+ if (!IS_ERR(file))
34710+ au_xino_brid_set(sb, -1);
34711+ }
0c5527e5 34712+
7f207e10
AM
34713+out:
34714+ return file;
34715+}
34716+
34717+/* ---------------------------------------------------------------------- */
34718+
34719+int au_xino_path(struct seq_file *seq, struct file *file)
34720+{
34721+ int err;
34722+
34723+ err = au_seq_path(seq, &file->f_path);
34724+ if (unlikely(err < 0))
34725+ goto out;
34726+
34727+ err = 0;
34728+#define Deleted "\\040(deleted)"
34729+ seq->count -= sizeof(Deleted) - 1;
34730+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
34731+ sizeof(Deleted) - 1));
34732+#undef Deleted
34733+
34734+out:
34735+ return err;
34736+}
537831f9
AM
34737diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
34738--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
2000de60 34739+++ linux/include/uapi/linux/aufs_type.h 2015-03-27 21:56:35.470128334 +0100
c1595e42 34740@@ -0,0 +1,419 @@
7f207e10 34741+/*
2000de60 34742+ * Copyright (C) 2005-2015 Junjiro R. Okajima
7f207e10
AM
34743+ *
34744+ * This program, aufs is free software; you can redistribute it and/or modify
34745+ * it under the terms of the GNU General Public License as published by
34746+ * the Free Software Foundation; either version 2 of the License, or
34747+ * (at your option) any later version.
34748+ *
34749+ * This program is distributed in the hope that it will be useful,
34750+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34751+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34752+ * GNU General Public License for more details.
34753+ *
34754+ * You should have received a copy of the GNU General Public License
523b37e3 34755+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
34756+ */
34757+
34758+#ifndef __AUFS_TYPE_H__
34759+#define __AUFS_TYPE_H__
34760+
f6c5ef8b
AM
34761+#define AUFS_NAME "aufs"
34762+
9dbd164d 34763+#ifdef __KERNEL__
f6c5ef8b
AM
34764+/*
34765+ * define it before including all other headers.
34766+ * sched.h may use pr_* macros before defining "current", so define the
34767+ * no-current version first, and re-define later.
34768+ */
34769+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
34770+#include <linux/sched.h>
34771+#undef pr_fmt
a2a7ad62
AM
34772+#define pr_fmt(fmt) \
34773+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
34774+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
34775+#else
34776+#include <stdint.h>
34777+#include <sys/types.h>
f6c5ef8b 34778+#endif /* __KERNEL__ */
7f207e10 34779+
f6c5ef8b
AM
34780+#include <linux/limits.h>
34781+
2000de60 34782+#define AUFS_VERSION "3.19-20150323"
7f207e10
AM
34783+
34784+/* todo? move this to linux-2.6.19/include/magic.h */
34785+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
34786+
34787+/* ---------------------------------------------------------------------- */
34788+
34789+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 34790+typedef int8_t aufs_bindex_t;
7f207e10
AM
34791+#define AUFS_BRANCH_MAX 127
34792+#else
9dbd164d 34793+typedef int16_t aufs_bindex_t;
7f207e10
AM
34794+#ifdef CONFIG_AUFS_BRANCH_MAX_511
34795+#define AUFS_BRANCH_MAX 511
34796+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
34797+#define AUFS_BRANCH_MAX 1023
34798+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
34799+#define AUFS_BRANCH_MAX 32767
34800+#endif
34801+#endif
34802+
34803+#ifdef __KERNEL__
34804+#ifndef AUFS_BRANCH_MAX
34805+#error unknown CONFIG_AUFS_BRANCH_MAX value
34806+#endif
34807+#endif /* __KERNEL__ */
34808+
34809+/* ---------------------------------------------------------------------- */
34810+
7f207e10
AM
34811+#define AUFS_FSTYPE AUFS_NAME
34812+
34813+#define AUFS_ROOT_INO 2
34814+#define AUFS_FIRST_INO 11
34815+
34816+#define AUFS_WH_PFX ".wh."
34817+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
34818+#define AUFS_WH_TMP_LEN 4
86dc4139 34819+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
34820+#define AUFS_MAX_NAMELEN (NAME_MAX \
34821+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
34822+ - 1 /* dot */\
34823+ - AUFS_WH_TMP_LEN) /* hex */
34824+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
34825+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
34826+#define AUFS_XINO_DEF_SEC 30 /* seconds */
34827+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
34828+#define AUFS_DIRWH_DEF 3
34829+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 34830+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
34831+#define AUFS_RDBLK_DEF 512 /* bytes */
34832+#define AUFS_RDHASH_DEF 32
34833+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
34834+#define AUFS_MFS_DEF_SEC 30 /* seconds */
34835+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 34836+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 34837+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
34838+
34839+/* pseudo-link maintenace under /proc */
34840+#define AUFS_PLINK_MAINT_NAME "plink_maint"
34841+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
34842+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
34843+
34844+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
34845+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
34846+
34847+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
34848+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
34849+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
34850+
34851+/* doubly whiteouted */
34852+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
34853+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
34854+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
34855+
1e00d052 34856+/* branch permissions and attributes */
7f207e10
AM
34857+#define AUFS_BRPERM_RW "rw"
34858+#define AUFS_BRPERM_RO "ro"
34859+#define AUFS_BRPERM_RR "rr"
076b876e
AM
34860+#define AUFS_BRATTR_COO_REG "coo_reg"
34861+#define AUFS_BRATTR_COO_ALL "coo_all"
34862+#define AUFS_BRATTR_FHSM "fhsm"
34863+#define AUFS_BRATTR_UNPIN "unpin"
c1595e42
JR
34864+#define AUFS_BRATTR_ICEX "icex"
34865+#define AUFS_BRATTR_ICEX_SEC "icexsec"
34866+#define AUFS_BRATTR_ICEX_SYS "icexsys"
34867+#define AUFS_BRATTR_ICEX_TR "icextr"
34868+#define AUFS_BRATTR_ICEX_USR "icexusr"
34869+#define AUFS_BRATTR_ICEX_OTH "icexoth"
1e00d052
AM
34870+#define AUFS_BRRATTR_WH "wh"
34871+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
34872+#define AUFS_BRWATTR_MOO "moo"
34873+
34874+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
34875+#define AuBrPerm_RO (1 << 1) /* readonly */
34876+#define AuBrPerm_RR (1 << 2) /* natively readonly */
34877+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
34878+
34879+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
34880+#define AuBrAttr_COO_ALL (1 << 4)
34881+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
34882+
34883+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
34884+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
c1595e42
JR
34885+ branch. meaningless since
34886+ linux-3.18-rc1 */
34887+
34888+/* ignore error in copying XATTR */
34889+#define AuBrAttr_ICEX_SEC (1 << 7)
34890+#define AuBrAttr_ICEX_SYS (1 << 8)
34891+#define AuBrAttr_ICEX_TR (1 << 9)
34892+#define AuBrAttr_ICEX_USR (1 << 10)
34893+#define AuBrAttr_ICEX_OTH (1 << 11)
34894+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
34895+ | AuBrAttr_ICEX_SYS \
34896+ | AuBrAttr_ICEX_TR \
34897+ | AuBrAttr_ICEX_USR \
34898+ | AuBrAttr_ICEX_OTH)
34899+
34900+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
076b876e
AM
34901+#define AuBrRAttr_Mask AuBrRAttr_WH
34902+
c1595e42
JR
34903+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
34904+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
076b876e
AM
34905+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
34906+
34907+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
34908+
c1595e42 34909+/* #warning test userspace */
076b876e
AM
34910+#ifdef __KERNEL__
34911+#ifndef CONFIG_AUFS_FHSM
34912+#undef AuBrAttr_FHSM
34913+#define AuBrAttr_FHSM 0
34914+#endif
c1595e42
JR
34915+#ifndef CONFIG_AUFS_XATTR
34916+#undef AuBrAttr_ICEX
34917+#define AuBrAttr_ICEX 0
34918+#undef AuBrAttr_ICEX_SEC
34919+#define AuBrAttr_ICEX_SEC 0
34920+#undef AuBrAttr_ICEX_SYS
34921+#define AuBrAttr_ICEX_SYS 0
34922+#undef AuBrAttr_ICEX_TR
34923+#define AuBrAttr_ICEX_TR 0
34924+#undef AuBrAttr_ICEX_USR
34925+#define AuBrAttr_ICEX_USR 0
34926+#undef AuBrAttr_ICEX_OTH
34927+#define AuBrAttr_ICEX_OTH 0
34928+#endif
076b876e
AM
34929+#endif
34930+
34931+/* the longest combination */
c1595e42
JR
34932+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
34933+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
34934+ "+" AUFS_BRATTR_COO_REG \
34935+ "+" AUFS_BRATTR_FHSM \
34936+ "+" AUFS_BRATTR_UNPIN \
34937+ "+" AUFS_BRATTR_ICEX_SEC \
34938+ "+" AUFS_BRATTR_ICEX_SYS \
34939+ "+" AUFS_BRATTR_ICEX_USR \
34940+ "+" AUFS_BRATTR_ICEX_OTH \
076b876e
AM
34941+ "+" AUFS_BRWATTR_NLWH)
34942+
34943+typedef struct {
34944+ char a[AuBrPermStrSz];
34945+} au_br_perm_str_t;
34946+
34947+static inline int au_br_writable(int brperm)
34948+{
34949+ return brperm & AuBrPerm_RW;
34950+}
34951+
34952+static inline int au_br_whable(int brperm)
34953+{
34954+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
34955+}
34956+
34957+static inline int au_br_wh_linkable(int brperm)
34958+{
34959+ return !(brperm & AuBrWAttr_NoLinkWH);
34960+}
34961+
34962+static inline int au_br_cmoo(int brperm)
34963+{
34964+ return brperm & AuBrAttr_CMOO_Mask;
34965+}
34966+
34967+static inline int au_br_fhsm(int brperm)
34968+{
34969+ return brperm & AuBrAttr_FHSM;
34970+}
7f207e10
AM
34971+
34972+/* ---------------------------------------------------------------------- */
34973+
34974+/* ioctl */
34975+enum {
34976+ /* readdir in userspace */
34977+ AuCtl_RDU,
34978+ AuCtl_RDU_INO,
34979+
076b876e
AM
34980+ AuCtl_WBR_FD, /* pathconf wrapper */
34981+ AuCtl_IBUSY, /* busy inode */
34982+ AuCtl_MVDOWN, /* move-down */
34983+ AuCtl_BR, /* info about branches */
34984+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
34985+};
34986+
34987+/* borrowed from linux/include/linux/kernel.h */
34988+#ifndef ALIGN
34989+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
34990+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
34991+#endif
34992+
34993+/* borrowed from linux/include/linux/compiler-gcc3.h */
34994+#ifndef __aligned
34995+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
34996+#endif
34997+
34998+#ifdef __KERNEL__
34999+#ifndef __packed
7f207e10
AM
35000+#define __packed __attribute__((packed))
35001+#endif
53392da6 35002+#endif
7f207e10
AM
35003+
35004+struct au_rdu_cookie {
9dbd164d
AM
35005+ uint64_t h_pos;
35006+ int16_t bindex;
35007+ uint8_t flags;
35008+ uint8_t pad;
35009+ uint32_t generation;
7f207e10
AM
35010+} __aligned(8);
35011+
35012+struct au_rdu_ent {
9dbd164d
AM
35013+ uint64_t ino;
35014+ int16_t bindex;
35015+ uint8_t type;
35016+ uint8_t nlen;
35017+ uint8_t wh;
7f207e10
AM
35018+ char name[0];
35019+} __aligned(8);
35020+
35021+static inline int au_rdu_len(int nlen)
35022+{
35023+ /* include the terminating NULL */
35024+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 35025+ sizeof(uint64_t));
7f207e10
AM
35026+}
35027+
35028+union au_rdu_ent_ul {
35029+ struct au_rdu_ent __user *e;
9dbd164d 35030+ uint64_t ul;
7f207e10
AM
35031+};
35032+
35033+enum {
35034+ AufsCtlRduV_SZ,
35035+ AufsCtlRduV_End
35036+};
35037+
35038+struct aufs_rdu {
35039+ /* input */
35040+ union {
9dbd164d
AM
35041+ uint64_t sz; /* AuCtl_RDU */
35042+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
35043+ };
35044+ union au_rdu_ent_ul ent;
9dbd164d 35045+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
35046+
35047+ /* input/output */
9dbd164d 35048+ uint32_t blk;
7f207e10
AM
35049+
35050+ /* output */
35051+ union au_rdu_ent_ul tail;
35052+ /* number of entries which were added in a single call */
9dbd164d
AM
35053+ uint64_t rent;
35054+ uint8_t full;
35055+ uint8_t shwh;
7f207e10
AM
35056+
35057+ struct au_rdu_cookie cookie;
35058+} __aligned(8);
35059+
1e00d052
AM
35060+/* ---------------------------------------------------------------------- */
35061+
35062+struct aufs_wbr_fd {
9dbd164d
AM
35063+ uint32_t oflags;
35064+ int16_t brid;
1e00d052
AM
35065+} __aligned(8);
35066+
35067+/* ---------------------------------------------------------------------- */
35068+
027c5e7a 35069+struct aufs_ibusy {
9dbd164d
AM
35070+ uint64_t ino, h_ino;
35071+ int16_t bindex;
027c5e7a
AM
35072+} __aligned(8);
35073+
1e00d052
AM
35074+/* ---------------------------------------------------------------------- */
35075+
392086de
AM
35076+/* error code for move-down */
35077+/* the actual message strings are implemented in aufs-util.git */
35078+enum {
35079+ EAU_MVDOWN_OPAQUE = 1,
35080+ EAU_MVDOWN_WHITEOUT,
35081+ EAU_MVDOWN_UPPER,
35082+ EAU_MVDOWN_BOTTOM,
35083+ EAU_MVDOWN_NOUPPER,
35084+ EAU_MVDOWN_NOLOWERBR,
35085+ EAU_Last
35086+};
35087+
c2b27bf2 35088+/* flags for move-down */
392086de
AM
35089+#define AUFS_MVDOWN_DMSG 1
35090+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
35091+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
35092+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
35093+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
35094+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
35095+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
35096+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
35097+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
35098+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
35099+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
35100+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
35101+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 35102+
076b876e 35103+/* index for move-down */
392086de
AM
35104+enum {
35105+ AUFS_MVDOWN_UPPER,
35106+ AUFS_MVDOWN_LOWER,
35107+ AUFS_MVDOWN_NARRAY
35108+};
35109+
076b876e
AM
35110+/*
35111+ * additional info of move-down
35112+ * number of free blocks and inodes.
35113+ * subset of struct kstatfs, but smaller and always 64bit.
35114+ */
35115+struct aufs_stfs {
35116+ uint64_t f_blocks;
35117+ uint64_t f_bavail;
35118+ uint64_t f_files;
35119+ uint64_t f_ffree;
35120+};
35121+
35122+struct aufs_stbr {
35123+ int16_t brid; /* optional input */
35124+ int16_t bindex; /* output */
35125+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
35126+} __aligned(8);
35127+
c2b27bf2 35128+struct aufs_mvdown {
076b876e
AM
35129+ uint32_t flags; /* input/output */
35130+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
35131+ int8_t au_errno; /* output */
35132+} __aligned(8);
35133+
35134+/* ---------------------------------------------------------------------- */
35135+
35136+union aufs_brinfo {
35137+ /* PATH_MAX may differ between kernel-space and user-space */
35138+ char _spacer[4096];
392086de 35139+ struct {
076b876e
AM
35140+ int16_t id;
35141+ int perm;
35142+ char path[0];
35143+ };
c2b27bf2
AM
35144+} __aligned(8);
35145+
35146+/* ---------------------------------------------------------------------- */
35147+
7f207e10
AM
35148+#define AuCtlType 'A'
35149+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
35150+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
35151+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
35152+ struct aufs_wbr_fd)
027c5e7a 35153+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
35154+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
35155+ struct aufs_mvdown)
076b876e
AM
35156+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
35157+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
35158+
35159+#endif /* __AUFS_TYPE_H__ */
2000de60 35160aufs3.19 loopback patch
93a1a2a2
JR
35161
35162diff --git a/drivers/block/loop.c b/drivers/block/loop.c
2000de60 35163index 30efd68..2a9b789 100644
93a1a2a2
JR
35164--- a/drivers/block/loop.c
35165+++ b/drivers/block/loop.c
35166@@ -514,7 +514,7 @@ out:
35167 }
35168
35169 struct switch_request {
35170- struct file *file;
35171+ struct file *file, *virt_file;
35172 struct completion wait;
35173 };
35174
35175@@ -576,7 +576,8 @@ static int loop_thread(void *data)
35176 * First it needs to flush existing IO, it does this by sending a magic
35177 * BIO down the pipe. The completion of this BIO does the actual switch.
35178 */
35179-static int loop_switch(struct loop_device *lo, struct file *file)
35180+static int loop_switch(struct loop_device *lo, struct file *file,
35181+ struct file *virt_file)
35182 {
35183 struct switch_request w;
35184 struct bio *bio = bio_alloc(GFP_KERNEL, 0);
35185@@ -584,6 +585,7 @@ static int loop_switch(struct loop_device *lo, struct file *file)
35186 return -ENOMEM;
35187 init_completion(&w.wait);
35188 w.file = file;
35189+ w.virt_file = virt_file;
35190 bio->bi_private = &w;
35191 bio->bi_bdev = NULL;
35192 loop_make_request(lo->lo_queue, bio);
35193@@ -600,7 +602,7 @@ static int loop_flush(struct loop_device *lo)
35194 if (!lo->lo_thread)
35195 return 0;
35196
35197- return loop_switch(lo, NULL);
35198+ return loop_switch(lo, NULL, NULL);
35199 }
35200
35201 /*
35202@@ -619,6 +621,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
35203 mapping = file->f_mapping;
35204 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
35205 lo->lo_backing_file = file;
35206+ lo->lo_backing_virt_file = p->virt_file;
35207 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
35208 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
35209 lo->old_gfp_mask = mapping_gfp_mask(mapping);
35210@@ -627,6 +630,13 @@ out:
35211 complete(&p->wait);
35212 }
35213
35214+static struct file *loop_real_file(struct file *file)
35215+{
35216+ struct file *f = NULL;
2000de60
JR
35217+ if (file->f_path.dentry->d_sb->s_op->real_loop)
35218+ f = file->f_path.dentry->d_sb->s_op->real_loop(file);
93a1a2a2
JR
35219+ return f;
35220+}
35221
35222 /*
35223 * loop_change_fd switched the backing store of a loopback device to
35224@@ -640,6 +650,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
35225 unsigned int arg)
35226 {
35227 struct file *file, *old_file;
35228+ struct file *f, *virt_file = NULL, *old_virt_file;
35229 struct inode *inode;
35230 int error;
35231
35232@@ -656,9 +667,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
35233 file = fget(arg);
35234 if (!file)
35235 goto out;
35236+ f = loop_real_file(file);
35237+ if (f) {
35238+ virt_file = file;
35239+ file = f;
35240+ get_file(file);
35241+ }
35242
35243 inode = file->f_mapping->host;
35244 old_file = lo->lo_backing_file;
35245+ old_virt_file = lo->lo_backing_virt_file;
35246
35247 error = -EINVAL;
35248
35249@@ -670,17 +688,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
35250 goto out_putf;
35251
35252 /* and ... switch */
35253- error = loop_switch(lo, file);
35254+ error = loop_switch(lo, file, virt_file);
35255 if (error)
35256 goto out_putf;
35257
35258 fput(old_file);
35259+ if (old_virt_file)
35260+ fput(old_virt_file);
35261 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
35262 ioctl_by_bdev(bdev, BLKRRPART, 0);
35263 return 0;
35264
35265 out_putf:
35266 fput(file);
35267+ if (virt_file)
35268+ fput(virt_file);
35269 out:
35270 return error;
35271 }
35272@@ -841,7 +863,7 @@ static void loop_config_discard(struct loop_device *lo)
35273 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
35274 struct block_device *bdev, unsigned int arg)
35275 {
35276- struct file *file, *f;
35277+ struct file *file, *f, *virt_file = NULL;
35278 struct inode *inode;
35279 struct address_space *mapping;
35280 unsigned lo_blocksize;
35281@@ -856,6 +878,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
35282 file = fget(arg);
35283 if (!file)
35284 goto out;
35285+ f = loop_real_file(file);
35286+ if (f) {
35287+ virt_file = file;
35288+ file = f;
35289+ get_file(file);
35290+ }
35291
35292 error = -EBUSY;
35293 if (lo->lo_state != Lo_unbound)
35294@@ -904,6 +932,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
35295 lo->lo_device = bdev;
35296 lo->lo_flags = lo_flags;
35297 lo->lo_backing_file = file;
35298+ lo->lo_backing_virt_file = virt_file;
35299 lo->transfer = transfer_none;
35300 lo->ioctl = NULL;
35301 lo->lo_sizelimit = 0;
35302@@ -948,6 +977,7 @@ out_clr:
35303 lo->lo_thread = NULL;
35304 lo->lo_device = NULL;
35305 lo->lo_backing_file = NULL;
35306+ lo->lo_backing_virt_file = NULL;
35307 lo->lo_flags = 0;
35308 set_capacity(lo->lo_disk, 0);
35309 invalidate_bdev(bdev);
35310@@ -957,6 +987,8 @@ out_clr:
35311 lo->lo_state = Lo_unbound;
35312 out_putf:
35313 fput(file);
35314+ if (virt_file)
35315+ fput(virt_file);
35316 out:
35317 /* This is safe: open() is still holding a reference. */
35318 module_put(THIS_MODULE);
35319@@ -1003,6 +1035,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
35320 static int loop_clr_fd(struct loop_device *lo)
35321 {
35322 struct file *filp = lo->lo_backing_file;
35323+ struct file *virt_filp = lo->lo_backing_virt_file;
35324 gfp_t gfp = lo->old_gfp_mask;
35325 struct block_device *bdev = lo->lo_device;
35326
35327@@ -1036,6 +1069,7 @@ static int loop_clr_fd(struct loop_device *lo)
35328
35329 spin_lock_irq(&lo->lo_lock);
35330 lo->lo_backing_file = NULL;
35331+ lo->lo_backing_virt_file = NULL;
35332 spin_unlock_irq(&lo->lo_lock);
35333
35334 loop_release_xfer(lo);
35335@@ -1078,6 +1112,8 @@ static int loop_clr_fd(struct loop_device *lo)
35336 * bd_mutex which is usually taken before lo_ctl_mutex.
35337 */
35338 fput(filp);
35339+ if (virt_filp)
35340+ fput(virt_filp);
35341 return 0;
35342 }
35343
35344diff --git a/drivers/block/loop.h b/drivers/block/loop.h
35345index 90df5d6..cb91822 100644
35346--- a/drivers/block/loop.h
35347+++ b/drivers/block/loop.h
35348@@ -44,7 +44,7 @@ struct loop_device {
35349 int (*ioctl)(struct loop_device *, int cmd,
35350 unsigned long arg);
35351
35352- struct file * lo_backing_file;
35353+ struct file * lo_backing_file, *lo_backing_virt_file;
35354 struct block_device *lo_device;
35355 unsigned lo_blocksize;
35356 void *key_data;
35357diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
2000de60 35358index 41c4c4a..6a68365 100644
93a1a2a2
JR
35359--- a/fs/aufs/f_op.c
35360+++ b/fs/aufs/f_op.c
2000de60 35361@@ -368,7 +368,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
93a1a2a2
JR
35362 err = -EINVAL;
35363 h_file = au_hf_top(file);
35364 get_file(h_file);
35365- if (au_test_loopback_kthread()) {
35366+ if (0 && au_test_loopback_kthread()) {
2000de60 35367 au_warn_loopback(h_file->f_path.dentry->d_sb);
93a1a2a2
JR
35368 if (file->f_mapping != h_file->f_mapping) {
35369 file->f_mapping = h_file->f_mapping;
35370diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
2000de60 35371index 69f7e96..7941063 100644
93a1a2a2
JR
35372--- a/fs/aufs/loop.c
35373+++ b/fs/aufs/loop.c
35374@@ -130,3 +130,19 @@ void au_loopback_fin(void)
35375 symbol_put(loop_backing_file);
35376 kfree(au_warn_loopback_array);
35377 }
35378+
35379+/* ---------------------------------------------------------------------- */
35380+
35381+/* support the loopback block device insude aufs */
35382+
35383+struct file *aufs_real_loop(struct file *file)
35384+{
35385+ struct file *f;
35386+
2000de60 35387+ BUG_ON(!au_test_aufs(file->f_path.dentry->d_sb));
93a1a2a2
JR
35388+ fi_read_lock(file);
35389+ f = au_hf_top(file);
35390+ fi_read_unlock(file);
35391+ AuDebugOn(!f);
35392+ return f;
35393+}
35394diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
2000de60 35395index 6d9864d..3322557 100644
93a1a2a2
JR
35396--- a/fs/aufs/loop.h
35397+++ b/fs/aufs/loop.h
35398@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
35399
35400 int au_loopback_init(void);
35401 void au_loopback_fin(void);
35402+
35403+struct file *aufs_real_loop(struct file *file);
35404 #else
35405+AuStub(struct file *, loop_backing_file, return NULL)
35406+
35407 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
35408 struct dentry *h_adding)
35409 AuStubInt0(au_test_loopback_kthread, void)
35410@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
35411
35412 AuStubInt0(au_loopback_init, void)
35413 AuStubVoid(au_loopback_fin, void)
35414+
35415+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
35416 #endif /* BLK_DEV_LOOP */
35417
35418 #endif /* __KERNEL__ */
35419diff --git a/fs/aufs/super.c b/fs/aufs/super.c
2000de60 35420index 9acda0e..bb80e3b 100644
93a1a2a2
JR
35421--- a/fs/aufs/super.c
35422+++ b/fs/aufs/super.c
c1595e42 35423@@ -812,7 +812,10 @@ static const struct super_operations aufs_sop = {
93a1a2a2
JR
35424 .statfs = aufs_statfs,
35425 .put_super = aufs_put_super,
35426 .sync_fs = aufs_sync_fs,
35427- .remount_fs = aufs_remount_fs
35428+ .remount_fs = aufs_remount_fs,
35429+#ifdef CONFIG_AUFS_BDEV_LOOP
35430+ .real_loop = aufs_real_loop
35431+#endif
35432 };
35433
35434 /* ---------------------------------------------------------------------- */
35435diff --git a/include/linux/fs.h b/include/linux/fs.h
2000de60 35436index f634198..bfecf84 100644
93a1a2a2
JR
35437--- a/include/linux/fs.h
35438+++ b/include/linux/fs.h
2000de60 35439@@ -1620,6 +1620,10 @@ struct super_operations {
93a1a2a2
JR
35440 int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
35441 long (*nr_cached_objects)(struct super_block *, int);
35442 long (*free_cached_objects)(struct super_block *, long, int);
35443+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
35444+ /* and aufs */
35445+ struct file *(*real_loop)(struct file *);
35446+#endif
35447 };
35448
35449 /*
This page took 5.706243 seconds and 4 git commands to generate.