]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-aufs3.patch
- up to 3.18.7; vserver up to 3.18.5-vs2.3.7.3 (seems to be working but only slightly...
[packages/kernel.git] / kernel-aufs3.patch
CommitLineData
c1595e42 1aufs3.18.1+ 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
c1595e42 16index da0bbb4..c8bc724 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
c1595e42 25index 8523f9b..11f8f74 100644
c06a8ce3
AM
26--- a/include/uapi/linux/Kbuild
27+++ b/include/uapi/linux/Kbuild
28@@ -56,6 +56,7 @@ header-y += atmppp.h
29 header-y += atmsap.h
30 header-y += atmsvc.h
31 header-y += audit.h
32+header-y += aufs_type.h
33 header-y += auto_fs.h
34 header-y += auto_fs4.h
35 header-y += auxvec.h
c1595e42 36aufs3.18.1+ base patch
7f207e10 37
c1595e42
JR
38diff --git a/MAINTAINERS b/MAINTAINERS
39index c721042..83801d0 100644
40--- a/MAINTAINERS
41+++ b/MAINTAINERS
42@@ -1795,6 +1795,20 @@ F: include/linux/audit.h
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
JR
92diff --git a/fs/dcache.c b/fs/dcache.c
93index 71acf8d..da7342e 100644
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
c1595e42 106index 26753ba..df21e66 100644
0c3ec466
AM
107--- a/fs/inode.c
108+++ b/fs/inode.c
c1595e42 109@@ -1497,7 +1497,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
c1595e42 147index 9ab779e..aabcbba 100644
0c3ec466
AM
148--- a/include/linux/fs.h
149+++ b/include/linux/fs.h
c1595e42 150@@ -2664,6 +2664,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
c1595e42 173aufs3.18.1+ 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
JR
188diff --git a/fs/proc/base.c b/fs/proc/base.c
189index 772efa4..2c944de 100644
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
c1595e42 218index 4e0388c..fc429e7 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;
c1595e42 233@@ -1440,7 +1443,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
c1595e42 259index b464611..8027d51 100644
fb47a38f
JR
260--- a/include/linux/mm.h
261+++ b/include/linux/mm.h
c1595e42 262@@ -1206,6 +1206,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
c1595e42 292index 6e0b286..8f374ed 100644
fb47a38f
JR
293--- a/include/linux/mm_types.h
294+++ b/include/linux/mm_types.h
38d290e6 295@@ -232,6 +232,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
38d290e6 303@@ -300,6 +301,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
c1595e42 312index 9b7d746..9a3b8fe 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);
323 mutex_lock(&mapping->i_mmap_mutex);
076b876e 324diff --git a/mm/Makefile b/mm/Makefile
c1595e42 325index 8405eb0..e0bda2d 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
c1595e42 338index 14b4642..99bc835 100644
fb47a38f
JR
339--- a/mm/filemap.c
340+++ b/mm/filemap.c
c1595e42 341@@ -2067,7 +2067,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
076b876e 351index 72b8fa3..a00bbf0 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
c1595e42 386index 0938b30..0b66856 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);
396 error = do_fallocate(f,
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
c1595e42 405index d5f2ae9..0830a96 100644
fb47a38f
JR
406--- a/mm/memory.c
407+++ b/mm/memory.c
c1595e42 408@@ -2163,7 +2163,7 @@ reuse:
38d290e6 409 set_page_dirty_balance(dirty_page);
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
c1595e42 418index ae91989..e3bee5c 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;
c1595e42 430@@ -895,7 +895,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);
c1595e42 439@@ -1680,8 +1680,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);
c1595e42 449@@ -2477,7 +2477,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);
c1595e42 458@@ -2496,7 +2496,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));
c1595e42 467@@ -2886,7 +2886,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
c1595e42 497index bd1808e..c9ea035 100644
fb47a38f
JR
498--- a/mm/nommu.c
499+++ b/mm/nommu.c
076b876e 500@@ -658,7 +658,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 */
076b876e 509@@ -823,7 +823,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 }
076b876e 518@@ -1385,7 +1385,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;
076b876e 527@@ -1461,10 +1461,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 */
c1595e42 632aufs3.18.1+ standalone patch
7f207e10 633
c1595e42
JR
634diff --git a/fs/dcache.c b/fs/dcache.c
635index da7342e..b147b6c 100644
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
c1595e42 647index df21e66..c8df03d 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
c1595e42 658@@ -1513,6 +1514,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
c1595e42 667index 5b66b2b..68ff4e4 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
c1595e42 678@@ -1727,6 +1728,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
c1595e42 723index 34c38fa..d40cf58 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
732 /*
733 * Any time a mark is getting freed we end up here.
392086de 734@@ -191,6 +192,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
740 void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
741 {
c1595e42 742@@ -311,6 +313,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)
c1595e42 750@@ -372,6 +375,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
c1595e42 759index de92c13..65d8ab0 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 769 {
076b876e 770@@ -298,6 +299,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
38d290e6
JR
771 sb_end_write(inode->i_sb);
772 return ret;
773 }
774+EXPORT_SYMBOL(do_fallocate);
775
776 SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
777 {
7f207e10 778diff --git a/fs/splice.c b/fs/splice.c
c1595e42 779index 619359a..c14f60e 100644
7f207e10
AM
780--- a/fs/splice.c
781+++ b/fs/splice.c
076b876e 782@@ -1127,6 +1127,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
392086de
AM
783
784 return splice_write(pipe, out, ppos, len, flags);
7f207e10
AM
785 }
786+EXPORT_SYMBOL(do_splice_from);
787
788 /*
789 * Attempt to initiate a splice from a file to a pipe.
076b876e 790@@ -1153,6 +1154,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
7f207e10
AM
791
792 return splice_read(in, ppos, pipe, len, flags);
793 }
794+EXPORT_SYMBOL(do_splice_to);
795
796 /**
797 * splice_direct_to_actor - splices data directly between two non-pipes
c1595e42
JR
798diff --git a/fs/xattr.c b/fs/xattr.c
799index 64e83ef..bd71e53 100644
800--- a/fs/xattr.c
801+++ b/fs/xattr.c
802@@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
803 *xattr_value = value;
804 return error;
805 }
806+EXPORT_SYMBOL(vfs_getxattr_alloc);
807
808 /* Compare an extended attribute value with the given value */
809 int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
7f207e10 810diff --git a/security/commoncap.c b/security/commoncap.c
c1595e42 811index bab0611..3fa2f82 100644
7f207e10
AM
812--- a/security/commoncap.c
813+++ b/security/commoncap.c
c1595e42 814@@ -979,9 +979,11 @@ int cap_mmap_addr(unsigned long addr)
94337f0d 815 }
7f207e10
AM
816 return ret;
817 }
0c3ec466
AM
818+EXPORT_SYMBOL(cap_mmap_addr);
819
820 int cap_mmap_file(struct file *file, unsigned long reqprot,
821 unsigned long prot, unsigned long flags)
822 {
823 return 0;
824 }
825+EXPORT_SYMBOL(cap_mmap_file);
7f207e10 826diff --git a/security/device_cgroup.c b/security/device_cgroup.c
c1595e42 827index 188c1d2..426d9af 100644
7f207e10
AM
828--- a/security/device_cgroup.c
829+++ b/security/device_cgroup.c
f6c5ef8b
AM
830@@ -7,6 +7,7 @@
831 #include <linux/device_cgroup.h>
832 #include <linux/cgroup.h>
833 #include <linux/ctype.h>
834+#include <linux/export.h>
835 #include <linux/list.h>
836 #include <linux/uaccess.h>
837 #include <linux/seq_file.h>
076b876e 838@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct inode *inode, int mask)
537831f9
AM
839 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
840 access);
7f207e10 841 }
2cbb1c4b 842+EXPORT_SYMBOL(__devcgroup_inode_permission);
7f207e10
AM
843
844 int devcgroup_inode_mknod(int mode, dev_t dev)
845 {
846diff --git a/security/security.c b/security/security.c
c1595e42 847index 18b35c6..12c67af 100644
7f207e10
AM
848--- a/security/security.c
849+++ b/security/security.c
392086de 850@@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry)
7f207e10
AM
851 return 0;
852 return security_ops->path_rmdir(dir, dentry);
853 }
854+EXPORT_SYMBOL(security_path_rmdir);
855
856 int security_path_unlink(struct path *dir, struct dentry *dentry)
857 {
392086de 858@@ -423,6 +424,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry,
7f207e10
AM
859 return 0;
860 return security_ops->path_symlink(dir, dentry, old_name);
861 }
862+EXPORT_SYMBOL(security_path_symlink);
863
864 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
865 struct dentry *new_dentry)
392086de 866@@ -431,6 +433,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
7f207e10
AM
867 return 0;
868 return security_ops->path_link(old_dentry, new_dir, new_dentry);
869 }
870+EXPORT_SYMBOL(security_path_link);
871
872 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
38d290e6
JR
873 struct path *new_dir, struct dentry *new_dentry,
874@@ -458,6 +461,7 @@ int security_path_truncate(struct path *path)
7f207e10
AM
875 return 0;
876 return security_ops->path_truncate(path);
877 }
878+EXPORT_SYMBOL(security_path_truncate);
879
7eafdf33
AM
880 int security_path_chmod(struct path *path, umode_t mode)
881 {
38d290e6 882@@ -465,6 +469,7 @@ int security_path_chmod(struct path *path, umode_t mode)
7f207e10 883 return 0;
7eafdf33 884 return security_ops->path_chmod(path, mode);
7f207e10
AM
885 }
886+EXPORT_SYMBOL(security_path_chmod);
887
537831f9 888 int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10 889 {
38d290e6 890@@ -472,6 +477,7 @@ int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
7f207e10
AM
891 return 0;
892 return security_ops->path_chown(path, uid, gid);
893 }
894+EXPORT_SYMBOL(security_path_chown);
895
896 int security_path_chroot(struct path *path)
897 {
38d290e6 898@@ -557,6 +563,7 @@ int security_inode_readlink(struct dentry *dentry)
7f207e10
AM
899 return 0;
900 return security_ops->inode_readlink(dentry);
901 }
902+EXPORT_SYMBOL(security_inode_readlink);
903
904 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
905 {
38d290e6 906@@ -571,6 +578,7 @@ int security_inode_permission(struct inode *inode, int mask)
7f207e10 907 return 0;
1e00d052 908 return security_ops->inode_permission(inode, mask);
7f207e10
AM
909 }
910+EXPORT_SYMBOL(security_inode_permission);
911
1e00d052 912 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
7f207e10 913 {
38d290e6 914@@ -693,6 +701,7 @@ int security_file_permission(struct file *file, int mask)
7f207e10
AM
915
916 return fsnotify_perm(file, mask);
917 }
918+EXPORT_SYMBOL(security_file_permission);
919
920 int security_file_alloc(struct file *file)
921 {
38d290e6 922@@ -753,6 +762,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
7f207e10
AM
923 return ret;
924 return ima_file_mmap(file, prot);
925 }
0c3ec466 926+EXPORT_SYMBOL(security_mmap_file);
7f207e10 927
0c3ec466
AM
928 int security_mmap_addr(unsigned long addr)
929 {
7f207e10
AM
930diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs
931--- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100
c1595e42 932+++ linux/Documentation/ABI/testing/debugfs-aufs 2015-01-25 13:00:38.627713742 +0100
86dc4139 933@@ -0,0 +1,50 @@
7f207e10
AM
934+What: /debug/aufs/si_<id>/
935+Date: March 2009
f6b6e03d 936+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
937+Description:
938+ Under /debug/aufs, a directory named si_<id> is created
939+ per aufs mount, where <id> is a unique id generated
940+ internally.
1facf9fc 941+
86dc4139
AM
942+What: /debug/aufs/si_<id>/plink
943+Date: Apr 2013
f6b6e03d 944+Contact: J. R. Okajima <hooanon05g@gmail.com>
86dc4139
AM
945+Description:
946+ It has three lines and shows the information about the
947+ pseudo-link. The first line is a single number
948+ representing a number of buckets. The second line is a
949+ number of pseudo-links per buckets (separated by a
950+ blank). The last line is a single number representing a
951+ total number of psedo-links.
952+ When the aufs mount option 'noplink' is specified, it
953+ will show "1\n0\n0\n".
954+
7f207e10
AM
955+What: /debug/aufs/si_<id>/xib
956+Date: March 2009
f6b6e03d 957+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
958+Description:
959+ It shows the consumed blocks by xib (External Inode Number
960+ Bitmap), its block size and file size.
961+ When the aufs mount option 'noxino' is specified, it
962+ will be empty. About XINO files, see the aufs manual.
963+
964+What: /debug/aufs/si_<id>/xino0, xino1 ... xinoN
965+Date: March 2009
f6b6e03d 966+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
967+Description:
968+ It shows the consumed blocks by xino (External Inode Number
969+ Translation Table), its link count, block size and file
970+ size.
971+ When the aufs mount option 'noxino' is specified, it
972+ will be empty. About XINO files, see the aufs manual.
973+
974+What: /debug/aufs/si_<id>/xigen
975+Date: March 2009
f6b6e03d 976+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
977+Description:
978+ It shows the consumed blocks by xigen (External Inode
979+ Generation Table), its block size and file size.
980+ If CONFIG_AUFS_EXPORT is disabled, this entry will not
981+ be created.
982+ When the aufs mount option 'noxino' is specified, it
983+ will be empty. About XINO files, see the aufs manual.
984diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs
985--- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100
c1595e42 986+++ linux/Documentation/ABI/testing/sysfs-aufs 2015-01-25 13:00:38.627713742 +0100
392086de 987@@ -0,0 +1,31 @@
7f207e10
AM
988+What: /sys/fs/aufs/si_<id>/
989+Date: March 2009
f6b6e03d 990+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
991+Description:
992+ Under /sys/fs/aufs, a directory named si_<id> is created
993+ per aufs mount, where <id> is a unique id generated
994+ internally.
995+
996+What: /sys/fs/aufs/si_<id>/br0, br1 ... brN
997+Date: March 2009
f6b6e03d 998+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
999+Description:
1000+ It shows the abolute path of a member directory (which
1001+ is called branch) in aufs, and its permission.
1002+
392086de
AM
1003+What: /sys/fs/aufs/si_<id>/brid0, brid1 ... bridN
1004+Date: July 2013
f6b6e03d 1005+Contact: J. R. Okajima <hooanon05g@gmail.com>
392086de
AM
1006+Description:
1007+ It shows the id of a member directory (which is called
1008+ branch) in aufs.
1009+
7f207e10
AM
1010+What: /sys/fs/aufs/si_<id>/xi_path
1011+Date: March 2009
f6b6e03d 1012+Contact: J. R. Okajima <hooanon05g@gmail.com>
7f207e10
AM
1013+Description:
1014+ It shows the abolute path of XINO (External Inode Number
1015+ Bitmap, Translation Table and Generation Table) file
1016+ even if it is the default path.
1017+ When the aufs mount option 'noxino' is specified, it
1018+ will be empty. About XINO files, see the aufs manual.
53392da6
AM
1019diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt
1020--- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 1021+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2015-01-25 13:00:38.627713742 +0100
523b37e3 1022@@ -0,0 +1,161 @@
53392da6 1023+
523b37e3 1024+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1025+#
1026+# This program is free software; you can redistribute it and/or modify
1027+# it under the terms of the GNU General Public License as published by
1028+# the Free Software Foundation; either version 2 of the License, or
1029+# (at your option) any later version.
1030+#
1031+# This program is distributed in the hope that it will be useful,
1032+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1033+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1034+# GNU General Public License for more details.
1035+#
1036+# You should have received a copy of the GNU General Public License
523b37e3 1037+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1038+
1039+Introduction
1040+----------------------------------------
1041+
1042+aufs [ei ju: ef es] | [a u f s]
1043+1. abbrev. for "advanced multi-layered unification filesystem".
1044+2. abbrev. for "another unionfs".
1045+3. abbrev. for "auf das" in German which means "on the" in English.
1046+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E).
1047+ But "Filesystem aufs Filesystem" is hard to understand.
1048+
1049+AUFS is a filesystem with features:
1050+- multi layered stackable unification filesystem, the member directory
1051+ is called as a branch.
1052+- branch permission and attribute, 'readonly', 'real-readonly',
1053+ 'readwrite', 'whiteout-able', 'link-able whiteout' and their
1054+ combination.
1055+- internal "file copy-on-write".
1056+- logical deletion, whiteout.
1057+- dynamic branch manipulation, adding, deleting and changing permission.
1058+- allow bypassing aufs, user's direct branch access.
1059+- external inode number translation table and bitmap which maintains the
1060+ persistent aufs inode number.
1061+- seekable directory, including NFS readdir.
1062+- file mapping, mmap and sharing pages.
1063+- pseudo-link, hardlink over branches.
1064+- loopback mounted filesystem as a branch.
1065+- several policies to select one among multiple writable branches.
1066+- revert a single systemcall when an error occurs in aufs.
1067+- and more...
1068+
1069+
1070+Multi Layered Stackable Unification Filesystem
1071+----------------------------------------------------------------------
1072+Most people already knows what it is.
1073+It is a filesystem which unifies several directories and provides a
1074+merged single directory. When users access a file, the access will be
1075+passed/re-directed/converted (sorry, I am not sure which English word is
1076+correct) to the real file on the member filesystem. The member
1077+filesystem is called 'lower filesystem' or 'branch' and has a mode
1078+'readonly' and 'readwrite.' And the deletion for a file on the lower
1079+readonly branch is handled by creating 'whiteout' on the upper writable
1080+branch.
1081+
1082+On LKML, there have been discussions about UnionMount (Jan Blunck,
1083+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took
1084+different approaches to implement the merged-view.
1085+The former tries putting it into VFS, and the latter implements as a
1086+separate filesystem.
1087+(If I misunderstand about these implementations, please let me know and
1088+I shall correct it. Because it is a long time ago when I read their
1089+source files last time).
1090+
1091+UnionMount's approach will be able to small, but may be hard to share
1092+branches between several UnionMount since the whiteout in it is
1093+implemented in the inode on branch filesystem and always
1094+shared. According to Bharata's post, readdir does not seems to be
1095+finished yet.
1096+There are several missing features known in this implementations such as
1097+- for users, the inode number may change silently. eg. copy-up.
1098+- link(2) may break by copy-up.
1099+- read(2) may get an obsoleted filedata (fstat(2) too).
1100+- fcntl(F_SETLK) may be broken by copy-up.
1101+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after
1102+ open(O_RDWR).
1103+
1104+Unionfs has a longer history. When I started implementing a stacking filesystem
1105+(Aug 2005), it already existed. It has virtual super_block, inode,
1106+dentry and file objects and they have an array pointing lower same kind
1107+objects. After contributing many patches for Unionfs, I re-started my
1108+project AUFS (Jun 2006).
1109+
1110+In AUFS, the structure of filesystem resembles to Unionfs, but I
1111+implemented my own ideas, approaches and enhancements and it became
1112+totally different one.
1113+
1114+Comparing DM snapshot and fs based implementation
1115+- the number of bytes to be copied between devices is much smaller.
1116+- the type of filesystem must be one and only.
1117+- the fs must be writable, no readonly fs, even for the lower original
1118+ device. so the compression fs will not be usable. but if we use
1119+ loopback mount, we may address this issue.
1120+ for instance,
1121+ mount /cdrom/squashfs.img /sq
1122+ losetup /sq/ext2.img
1123+ losetup /somewhere/cow
1124+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..."
1125+- it will be difficult (or needs more operations) to extract the
1126+ difference between the original device and COW.
1127+- DM snapshot-merge may help a lot when users try merging. in the
1128+ fs-layer union, users will use rsync(1).
1129+
1130+
1131+Several characters/aspects of aufs
1132+----------------------------------------------------------------------
1133+
1134+Aufs has several characters or aspects.
1135+1. a filesystem, callee of VFS helper
1136+2. sub-VFS, caller of VFS helper for branches
1137+3. a virtual filesystem which maintains persistent inode number
1138+4. reader/writer of files on branches such like an application
1139+
1140+1. Callee of VFS Helper
1141+As an ordinary linux filesystem, aufs is a callee of VFS. For instance,
1142+unlink(2) from an application reaches sys_unlink() kernel function and
1143+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it
1144+calls filesystem specific unlink operation. Actually aufs implements the
1145+unlink operation but it behaves like a redirector.
1146+
1147+2. Caller of VFS Helper for Branches
1148+aufs_unlink() passes the unlink request to the branch filesystem as if
1149+it were called from VFS. So the called unlink operation of the branch
1150+filesystem acts as usual. As a caller of VFS helper, aufs should handle
1151+every necessary pre/post operation for the branch filesystem.
1152+- acquire the lock for the parent dir on a branch
1153+- lookup in a branch
1154+- revalidate dentry on a branch
1155+- mnt_want_write() for a branch
1156+- vfs_unlink() for a branch
1157+- mnt_drop_write() for a branch
1158+- release the lock on a branch
1159+
1160+3. Persistent Inode Number
1161+One of the most important issue for a filesystem is to maintain inode
1162+numbers. This is particularly important to support exporting a
1163+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a
1164+backend block device for its own. But some storage is necessary to
1165+maintain inode number. It may be a large space and may not suit to keep
1166+in memory. Aufs rents some space from its first writable branch
1167+filesystem (by default) and creates file(s) on it. These files are
1168+created by aufs internally and removed soon (currently) keeping opened.
1169+Note: Because these files are removed, they are totally gone after
1170+ unmounting aufs. It means the inode numbers are not persistent
1171+ across unmount or reboot. I have a plan to make them really
1172+ persistent which will be important for aufs on NFS server.
1173+
1174+4. Read/Write Files Internally (copy-on-write)
1175+Because a branch can be readonly, when you write a file on it, aufs will
1176+"copy-up" it to the upper writable branch internally. And then write the
1177+originally requested thing to the file. Generally kernel doesn't
1178+open/read/write file actively. In aufs, even a single write may cause a
1179+internal "file copy". This behaviour is very similar to cp(1) command.
1180+
1181+Some people may think it is better to pass such work to user space
1182+helper, instead of doing in kernel space. Actually I am still thinking
1183+about it. But currently I have implemented it in kernel space.
1184diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt
1185--- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 1186+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2015-01-25 13:00:38.627713742 +0100
076b876e 1187@@ -0,0 +1,251 @@
53392da6 1188+
523b37e3 1189+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1190+#
1191+# This program is free software; you can redistribute it and/or modify
1192+# it under the terms of the GNU General Public License as published by
1193+# the Free Software Foundation; either version 2 of the License, or
1194+# (at your option) any later version.
1195+#
1196+# This program is distributed in the hope that it will be useful,
1197+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1198+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1199+# GNU General Public License for more details.
1200+#
1201+# You should have received a copy of the GNU General Public License
523b37e3 1202+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1203+
1204+Basic Aufs Internal Structure
1205+
1206+Superblock/Inode/Dentry/File Objects
1207+----------------------------------------------------------------------
1208+As like an ordinary filesystem, aufs has its own
1209+superblock/inode/dentry/file objects. All these objects have a
1210+dynamically allocated array and store the same kind of pointers to the
1211+lower filesystem, branch.
1212+For example, when you build a union with one readwrite branch and one
1213+readonly, mounted /au, /rw and /ro respectively.
1214+- /au = /rw + /ro
1215+- /ro/fileA exists but /rw/fileA
1216+
1217+Aufs lookup operation finds /ro/fileA and gets dentry for that. These
1218+pointers are stored in a aufs dentry. The array in aufs dentry will be,
1219+- [0] = NULL
1220+- [1] = /ro/fileA
1221+
1222+This style of an array is essentially same to the aufs
1223+superblock/inode/dentry/file objects.
1224+
1225+Because aufs supports manipulating branches, ie. add/delete/change
1226+dynamically, these objects has its own generation. When branches are
1227+changed, the generation in aufs superblock is incremented. And a
1228+generation in other object are compared when it is accessed.
1229+When a generation in other objects are obsoleted, aufs refreshes the
1230+internal array.
1231+
1232+
1233+Superblock
1234+----------------------------------------------------------------------
1235+Additionally aufs superblock has some data for policies to select one
1236+among multiple writable branches, XIB files, pseudo-links and kobject.
1237+See below in detail.
1238+About the policies which supports copy-down a directory, see policy.txt
1239+too.
1240+
1241+
1242+Branch and XINO(External Inode Number Translation Table)
1243+----------------------------------------------------------------------
1244+Every branch has its own xino (external inode number translation table)
1245+file. The xino file is created and unlinked by aufs internally. When two
1246+members of a union exist on the same filesystem, they share the single
1247+xino file.
1248+The struct of a xino file is simple, just a sequence of aufs inode
1249+numbers which is indexed by the lower inode number.
1250+In the above sample, assume the inode number of /ro/fileA is i111 and
1251+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as
1252+4(8) bytes at 111 * 4(8) bytes offset in the xino file.
1253+
1254+When the inode numbers are not contiguous, the xino file will be sparse
1255+which has a hole in it and doesn't consume as much disk space as it
1256+might appear. If your branch filesystem consumes disk space for such
1257+holes, then you should specify 'xino=' option at mounting aufs.
1258+
1259+Also a writable branch has three kinds of "whiteout bases". All these
1260+are existed when the branch is joined to aufs and the names are
1261+whiteout-ed doubly, so that users will never see their names in aufs
1262+hierarchy.
1263+1. a regular file which will be linked to all whiteouts.
1264+2. a directory to store a pseudo-link.
1265+3. a directory to store an "orphan-ed" file temporary.
1266+
1267+1. Whiteout Base
1268+ When you remove a file on a readonly branch, aufs handles it as a
1269+ logical deletion and creates a whiteout on the upper writable branch
1270+ as a hardlink of this file in order not to consume inode on the
1271+ writable branch.
1272+2. Pseudo-link Dir
1273+ See below, Pseudo-link.
1274+3. Step-Parent Dir
1275+ When "fileC" exists on the lower readonly branch only and it is
1276+ opened and removed with its parent dir, and then user writes
1277+ something into it, then aufs copies-up fileC to this
1278+ directory. Because there is no other dir to store fileC. After
1279+ creating a file under this dir, the file is unlinked.
1280+
1281+Because aufs supports manipulating branches, ie. add/delete/change
1282+dynamically, a branch has its own id. When the branch order changes, aufs
1283+finds the new index by searching the branch id.
1284+
1285+
1286+Pseudo-link
1287+----------------------------------------------------------------------
1288+Assume "fileA" exists on the lower readonly branch only and it is
1289+hardlinked to "fileB" on the branch. When you write something to fileA,
1290+aufs copies-up it to the upper writable branch. Additionally aufs
1291+creates a hardlink under the Pseudo-link Directory of the writable
1292+branch. The inode of a pseudo-link is kept in aufs super_block as a
1293+simple list. If fileB is read after unlinking fileA, aufs returns
1294+filedata from the pseudo-link instead of the lower readonly
1295+branch. Because the pseudo-link is based upon the inode, to keep the
1296+inode number by xino (see above) is important.
1297+
1298+All the hardlinks under the Pseudo-link Directory of the writable branch
1299+should be restored in a proper location later. Aufs provides a utility
1300+to do this. The userspace helpers executed at remounting and unmounting
1301+aufs by default.
1302+During this utility is running, it puts aufs into the pseudo-link
1303+maintenance mode. In this mode, only the process which began the
1304+maintenance mode (and its child processes) is allowed to operate in
1305+aufs. Some other processes which are not related to the pseudo-link will
1306+be allowed to run too, but the rest have to return an error or wait
1307+until the maintenance mode ends. If a process already acquires an inode
1308+mutex (in VFS), it has to return an error.
1309+
1310+
1311+XIB(external inode number bitmap)
1312+----------------------------------------------------------------------
1313+Addition to the xino file per a branch, aufs has an external inode number
1314+bitmap in a superblock object. It is also a file such like a xino file.
1315+It is a simple bitmap to mark whether the aufs inode number is in-use or
1316+not.
1317+To reduce the file I/O, aufs prepares a single memory page to cache xib.
1318+
1319+Aufs implements a feature to truncate/refresh both of xino and xib to
1320+reduce the number of consumed disk blocks for these files.
1321+
1322+
1323+Virtual or Vertical Dir, and Readdir in Userspace
1324+----------------------------------------------------------------------
1325+In order to support multiple layers (branches), aufs readdir operation
1326+constructs a virtual dir block on memory. For readdir, aufs calls
1327+vfs_readdir() internally for each dir on branches, merges their entries
1328+with eliminating the whiteout-ed ones, and sets it to file (dir)
1329+object. So the file object has its entry list until it is closed. The
1330+entry list will be updated when the file position is zero and becomes
1331+old. This decision is made in aufs automatically.
1332+
1333+The dynamically allocated memory block for the name of entries has a
1334+unit of 512 bytes (by default) and stores the names contiguously (no
1335+padding). Another block for each entry is handled by kmem_cache too.
1336+During building dir blocks, aufs creates hash list and judging whether
1337+the entry is whiteouted by its upper branch or already listed.
1338+The merged result is cached in the corresponding inode object and
1339+maintained by a customizable life-time option.
1340+
1341+Some people may call it can be a security hole or invite DoS attack
1342+since the opened and once readdir-ed dir (file object) holds its entry
1343+list and becomes a pressure for system memory. But I'd say it is similar
1344+to files under /proc or /sys. The virtual files in them also holds a
1345+memory page (generally) while they are opened. When an idea to reduce
1346+memory for them is introduced, it will be applied to aufs too.
1347+For those who really hate this situation, I've developed readdir(3)
1348+library which operates this merging in userspace. You just need to set
1349+LD_PRELOAD environment variable, and aufs will not consume no memory in
1350+kernel space for readdir(3).
1351+
1352+
1353+Workqueue
1354+----------------------------------------------------------------------
1355+Aufs sometimes requires privilege access to a branch. For instance,
1356+in copy-up/down operation. When a user process is going to make changes
1357+to a file which exists in the lower readonly branch only, and the mode
1358+of one of ancestor directories may not be writable by a user
1359+process. Here aufs copy-up the file with its ancestors and they may
1360+require privilege to set its owner/group/mode/etc.
1361+This is a typical case of a application character of aufs (see
1362+Introduction).
1363+
1364+Aufs uses workqueue synchronously for this case. It creates its own
1365+workqueue. The workqueue is a kernel thread and has privilege. Aufs
1366+passes the request to call mkdir or write (for example), and wait for
1367+its completion. This approach solves a problem of a signal handler
1368+simply.
1369+If aufs didn't adopt the workqueue and changed the privilege of the
1370+process, and if the mkdir/write call arises SIGXFSZ or other signal,
1371+then the user process might gain a privilege or the generated core file
1372+was owned by a superuser.
1373+
1374+Also aufs uses the system global workqueue ("events" kernel thread) too
1375+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a
1376+whiteout base and etc. This is unrelated to a privilege.
1377+Most of aufs operation tries acquiring a rw_semaphore for aufs
1378+superblock at the beginning, at the same time waits for the completion
1379+of all queued asynchronous tasks.
1380+
1381+
1382+Whiteout
1383+----------------------------------------------------------------------
1384+The whiteout in aufs is very similar to Unionfs's. That is represented
1385+by its filename. UnionMount takes an approach of a file mode, but I am
1386+afraid several utilities (find(1) or something) will have to support it.
1387+
1388+Basically the whiteout represents "logical deletion" which stops aufs to
1389+lookup further, but also it represents "dir is opaque" which also stop
1390+lookup.
1391+
1392+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively.
1393+In order to make several functions in a single systemcall to be
1394+revertible, aufs adopts an approach to rename a directory to a temporary
1395+unique whiteouted name.
1396+For example, in rename(2) dir where the target dir already existed, aufs
1397+renames the target dir to a temporary unique whiteouted name before the
1398+actual rename on a branch and then handles other actions (make it opaque,
1399+update the attributes, etc). If an error happens in these actions, aufs
1400+simply renames the whiteouted name back and returns an error. If all are
1401+succeeded, aufs registers a function to remove the whiteouted unique
1402+temporary name completely and asynchronously to the system global
1403+workqueue.
1404+
1405+
1406+Copy-up
1407+----------------------------------------------------------------------
1408+It is a well-known feature or concept.
1409+When user modifies a file on a readonly branch, aufs operate "copy-up"
1410+internally and makes change to the new file on the upper writable branch.
1411+When the trigger systemcall does not update the timestamps of the parent
1412+dir, aufs reverts it after copy-up.
c2b27bf2
AM
1413+
1414+
1415+Move-down (aufs3.9 and later)
1416+----------------------------------------------------------------------
1417+"Copy-up" is one of the essential feature in aufs. It copies a file from
1418+the lower readonly branch to the upper writable branch when a user
1419+changes something about the file.
1420+"Move-down" is an opposite action of copy-up. Basically this action is
1421+ran manually instead of automatically and internally.
076b876e
AM
1422+For desgin and implementation, aufs has to consider these issues.
1423+- whiteout for the file may exist on the lower branch.
1424+- ancestor directories may not exist on the lower branch.
1425+- diropq for the ancestor directories may exist on the upper branch.
1426+- free space on the lower branch will reduce.
1427+- another access to the file may happen during moving-down, including
1428+ UDBA.
1429+- the file should not be hard-linked nor pseudo-linked. they should be
1430+ handled by auplink utility later.
c2b27bf2
AM
1431+
1432+Sometimes users want to move-down a file from the upper writable branch
1433+to the lower readonly or writable branch. For instance,
1434+- the free space of the upper writable branch is going to run out.
1435+- create a new intermediate branch between the upper and lower branch.
1436+- etc.
1437+
1438+For this purpose, use "aumvdown" command in aufs-util.git.
53392da6
AM
1439diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt
1440--- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 1441+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2015-01-25 13:00:38.627713742 +0100
076b876e 1442@@ -0,0 +1,133 @@
53392da6 1443+
523b37e3 1444+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1445+#
1446+# This program is free software; you can redistribute it and/or modify
1447+# it under the terms of the GNU General Public License as published by
1448+# the Free Software Foundation; either version 2 of the License, or
1449+# (at your option) any later version.
1450+#
1451+# This program is distributed in the hope that it will be useful,
1452+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1453+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1454+# GNU General Public License for more details.
1455+#
1456+# You should have received a copy of the GNU General Public License
523b37e3 1457+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1458+
1459+Lookup in a Branch
1460+----------------------------------------------------------------------
1461+Since aufs has a character of sub-VFS (see Introduction), it operates
1462+lookup for branches as VFS does. It may be a heavy work. Generally
1463+speaking struct nameidata is a bigger structure and includes many
1464+information. But almost all lookup operation in aufs is the simplest
1465+case, ie. lookup only an entry directly connected to its parent. Digging
1466+down the directory hierarchy is unnecessary.
1467+
1468+VFS has a function lookup_one_len() for that use, but it is not usable
1469+for a branch filesystem which requires struct nameidata. So aufs
1470+implements a simple lookup wrapper function. When a branch filesystem
1471+allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds
1472+a simplest nameidata and calls lookup_hash().
1473+Here aufs applies "a principle in NFSD", ie. if the filesystem supports
1474+NFS-export, then it has to support NULL as a nameidata parameter for
1475+->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in
1476+aufs tests if ->s_export_op in the branch is NULL or not.
1477+
1478+When a branch is a remote filesystem, aufs basically trusts its
1479+->d_revalidate(), also aufs forces the hardest revalidate tests for
1480+them.
1481+For d_revalidate, aufs implements three levels of revalidate tests. See
1482+"Revalidate Dentry and UDBA" in detail.
1483+
1484+
076b876e
AM
1485+Test Only the Highest One for the Directory Permission (dirperm1 option)
1486+----------------------------------------------------------------------
1487+Let's try case study.
1488+- aufs has two branches, upper readwrite and lower readonly.
1489+ /au = /rw + /ro
1490+- "dirA" exists under /ro, but /rw. and its mode is 0700.
1491+- user invoked "chmod a+rx /au/dirA"
1492+- the internal copy-up is activated and "/rw/dirA" is created and its
1493+ permission bits are set to world readble.
1494+- then "/au/dirA" becomes world readable?
1495+
1496+In this case, /ro/dirA is still 0700 since it exists in readonly branch,
1497+or it may be a natively readonly filesystem. If aufs respects the lower
1498+branch, it should not respond readdir request from other users. But user
1499+allowed it by chmod. Should really aufs rejects showing the entries
1500+under /ro/dirA?
1501+
1502+To be honest, I don't have a best solution for this case. So aufs
1503+implements 'dirperm1' and 'nodirperm1' and leave it to users.
1504+When dirperm1 is specified, aufs checks only the highest one for the
1505+directory permission, and shows the entries. Otherwise, as usual, checks
1506+every dir existing on all branches and rejects the request.
1507+
1508+As a side effect, dirperm1 option improves the performance of aufs
1509+because the number of permission check is reduced when the number of
1510+branch is many.
1511+
1512+
53392da6
AM
1513+Loopback Mount
1514+----------------------------------------------------------------------
1515+Basically aufs supports any type of filesystem and block device for a
1516+branch (actually there are some exceptions). But it is prohibited to add
1517+a loopback mounted one whose backend file exists in a filesystem which is
1518+already added to aufs. The reason is to protect aufs from a recursive
1519+lookup. If it was allowed, the aufs lookup operation might re-enter a
1520+lookup for the loopback mounted branch in the same context, and will
1521+cause a deadlock.
1522+
1523+
1524+Revalidate Dentry and UDBA (User's Direct Branch Access)
1525+----------------------------------------------------------------------
1526+Generally VFS helpers re-validate a dentry as a part of lookup.
1527+0. digging down the directory hierarchy.
1528+1. lock the parent dir by its i_mutex.
1529+2. lookup the final (child) entry.
1530+3. revalidate it.
1531+4. call the actual operation (create, unlink, etc.)
1532+5. unlock the parent dir
1533+
1534+If the filesystem implements its ->d_revalidate() (step 3), then it is
1535+called. Actually aufs implements it and checks the dentry on a branch is
1536+still valid.
1537+But it is not enough. Because aufs has to release the lock for the
1538+parent dir on a branch at the end of ->lookup() (step 2) and
1539+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still
1540+held by VFS.
1541+If the file on a branch is changed directly, eg. bypassing aufs, after
1542+aufs released the lock, then the subsequent operation may cause
1543+something unpleasant result.
1544+
1545+This situation is a result of VFS architecture, ->lookup() and
1546+->d_revalidate() is separated. But I never say it is wrong. It is a good
1547+design from VFS's point of view. It is just not suitable for sub-VFS
1548+character in aufs.
1549+
1550+Aufs supports such case by three level of revalidation which is
1551+selectable by user.
1552+1. Simple Revalidate
1553+ Addition to the native flow in VFS's, confirm the child-parent
1554+ relationship on the branch just after locking the parent dir on the
1555+ branch in the "actual operation" (step 4). When this validation
1556+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still
1557+ checks the validation of the dentry on branches.
1558+2. Monitor Changes Internally by Inotify/Fsnotify
1559+ Addition to above, in the "actual operation" (step 4) aufs re-lookup
1560+ the dentry on the branch, and returns EBUSY if it finds different
1561+ dentry.
1562+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches
1563+ during it is in cache. When the event is notified, aufs registers a
1564+ function to kernel 'events' thread by schedule_work(). And the
1565+ function sets some special status to the cached aufs dentry and inode
1566+ private data. If they are not cached, then aufs has nothing to
1567+ do. When the same file is accessed through aufs (step 0-3) later,
1568+ aufs will detect the status and refresh all necessary data.
1569+ In this mode, aufs has to ignore the event which is fired by aufs
1570+ itself.
1571+3. No Extra Validation
1572+ This is the simplest test and doesn't add any additional revalidation
1573+ test, and skip therevalidatin in step 4. It is useful and improves
1574+ aufs performance when system surely hide the aufs branches from user,
1575+ by over-mounting something (or another method).
1576diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt
1577--- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 1578+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2015-01-25 13:00:38.627713742 +0100
523b37e3 1579@@ -0,0 +1,75 @@
53392da6 1580+
523b37e3 1581+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1582+#
1583+# This program is free software; you can redistribute it and/or modify
1584+# it under the terms of the GNU General Public License as published by
1585+# the Free Software Foundation; either version 2 of the License, or
1586+# (at your option) any later version.
1587+#
1588+# This program is distributed in the hope that it will be useful,
1589+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1590+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1591+# GNU General Public License for more details.
1592+#
1593+# You should have received a copy of the GNU General Public License
523b37e3 1594+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1595+
1596+Branch Manipulation
1597+
1598+Since aufs supports dynamic branch manipulation, ie. add/remove a branch
1599+and changing its permission/attribute, there are a lot of works to do.
1600+
1601+
1602+Add a Branch
1603+----------------------------------------------------------------------
1604+o Confirm the adding dir exists outside of aufs, including loopback
1605+ mount.
1606+- and other various attributes...
1607+o Initialize the xino file and whiteout bases if necessary.
1608+ See struct.txt.
1609+
1610+o Check the owner/group/mode of the directory
1611+ When the owner/group/mode of the adding directory differs from the
1612+ existing branch, aufs issues a warning because it may impose a
1613+ security risk.
1614+ For example, when a upper writable branch has a world writable empty
1615+ top directory, a malicious user can create any files on the writable
1616+ branch directly, like copy-up and modify manually. If something like
1617+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper
1618+ writable branch, and the writable branch is world-writable, then a
1619+ malicious guy may create /etc/passwd on the writable branch directly
1620+ and the infected file will be valid in aufs.
1621+ I am afraid it can be a security issue, but nothing to do except
1622+ producing a warning.
1623+
1624+
1625+Delete a Branch
1626+----------------------------------------------------------------------
1627+o Confirm the deleting branch is not busy
1628+ To be general, there is one merit to adopt "remount" interface to
1629+ manipulate branches. It is to discard caches. At deleting a branch,
1630+ aufs checks the still cached (and connected) dentries and inodes. If
1631+ there are any, then they are all in-use. An inode without its
1632+ corresponding dentry can be alive alone (for example, inotify/fsnotify case).
1633+
1634+ For the cached one, aufs checks whether the same named entry exists on
1635+ other branches.
1636+ If the cached one is a directory, because aufs provides a merged view
1637+ to users, as long as one dir is left on any branch aufs can show the
1638+ dir to users. In this case, the branch can be removed from aufs.
1639+ Otherwise aufs rejects deleting the branch.
1640+
1641+ If any file on the deleting branch is opened by aufs, then aufs
1642+ rejects deleting.
1643+
1644+
1645+Modify the Permission of a Branch
1646+----------------------------------------------------------------------
1647+o Re-initialize or remove the xino file and whiteout bases if necessary.
1648+ See struct.txt.
1649+
1650+o rw --> ro: Confirm the modifying branch is not busy
1651+ Aufs rejects the request if any of these conditions are true.
1652+ - a file on the branch is mmap-ed.
1653+ - a regular file on the branch is opened for write and there is no
1654+ same named entry on the upper branch.
1655diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt
1656--- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 1657+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2015-01-25 13:00:38.627713742 +0100
523b37e3 1658@@ -0,0 +1,64 @@
53392da6 1659+
523b37e3 1660+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1661+#
1662+# This program is free software; you can redistribute it and/or modify
1663+# it under the terms of the GNU General Public License as published by
1664+# the Free Software Foundation; either version 2 of the License, or
1665+# (at your option) any later version.
1666+#
1667+# This program is distributed in the hope that it will be useful,
1668+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1669+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1670+# GNU General Public License for more details.
1671+#
1672+# You should have received a copy of the GNU General Public License
523b37e3 1673+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1674+
1675+Policies to Select One among Multiple Writable Branches
1676+----------------------------------------------------------------------
1677+When the number of writable branch is more than one, aufs has to decide
1678+the target branch for file creation or copy-up. By default, the highest
1679+writable branch which has the parent (or ancestor) dir of the target
1680+file is chosen (top-down-parent policy).
1681+By user's request, aufs implements some other policies to select the
1682+writable branch, for file creation two policies, round-robin and
1683+most-free-space policies. For copy-up three policies, top-down-parent,
1684+bottom-up-parent and bottom-up policies.
1685+
1686+As expected, the round-robin policy selects the branch in circular. When
1687+you have two writable branches and creates 10 new files, 5 files will be
1688+created for each branch. mkdir(2) systemcall is an exception. When you
1689+create 10 new directories, all will be created on the same branch.
1690+And the most-free-space policy selects the one which has most free
1691+space among the writable branches. The amount of free space will be
1692+checked by aufs internally, and users can specify its time interval.
1693+
1694+The policies for copy-up is more simple,
1695+top-down-parent is equivalent to the same named on in create policy,
1696+bottom-up-parent selects the writable branch where the parent dir
1697+exists and the nearest upper one from the copyup-source,
1698+bottom-up selects the nearest upper writable branch from the
1699+copyup-source, regardless the existence of the parent dir.
1700+
1701+There are some rules or exceptions to apply these policies.
1702+- If there is a readonly branch above the policy-selected branch and
1703+ the parent dir is marked as opaque (a variation of whiteout), or the
1704+ target (creating) file is whiteout-ed on the upper readonly branch,
1705+ then the result of the policy is ignored and the target file will be
1706+ created on the nearest upper writable branch than the readonly branch.
1707+- If there is a writable branch above the policy-selected branch and
1708+ the parent dir is marked as opaque or the target file is whiteouted
1709+ on the branch, then the result of the policy is ignored and the target
1710+ file will be created on the highest one among the upper writable
1711+ branches who has diropq or whiteout. In case of whiteout, aufs removes
1712+ it as usual.
1713+- link(2) and rename(2) systemcalls are exceptions in every policy.
1714+ They try selecting the branch where the source exists as possible
1715+ since copyup a large file will take long time. If it can't be,
1716+ ie. the branch where the source exists is readonly, then they will
1717+ follow the copyup policy.
1718+- There is an exception for rename(2) when the target exists.
1719+ If the rename target exists, aufs compares the index of the branches
1720+ where the source and the target exists and selects the higher
1721+ one. If the selected branch is readonly, then aufs follows the
1722+ copyup policy.
076b876e
AM
1723diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt
1724--- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 1725+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2015-01-25 13:00:38.627713742 +0100
076b876e
AM
1726@@ -0,0 +1,120 @@
1727+
1728+# Copyright (C) 2011-2014 Junjiro R. Okajima
1729+#
1730+# This program is free software; you can redistribute it and/or modify
1731+# it under the terms of the GNU General Public License as published by
1732+# the Free Software Foundation; either version 2 of the License, or
1733+# (at your option) any later version.
1734+#
1735+# This program is distributed in the hope that it will be useful,
1736+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1737+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1738+# GNU General Public License for more details.
1739+#
1740+# You should have received a copy of the GNU General Public License
1741+# along with this program; if not, write to the Free Software
1742+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1743+
1744+
1745+File-based Hierarchical Storage Management (FHSM)
1746+----------------------------------------------------------------------
1747+Hierarchical Storage Management (or HSM) is a well-known feature in the
1748+storage world. Aufs provides this feature as file-based with multiple
1749+writable branches, based upon the principle of "Colder-Lower".
1750+Here the word "colder" means that the less used files, and "lower" means
1751+that the position in the order of the stacked branches.
1752+These multiple writable branches are prioritized, ie. the topmost one
1753+should be the fastest drive and be used heavily.
1754+
1755+o Characters in aufs FHSM story
1756+- aufs itself and a new branch attribute.
1757+- a new ioctl interface to move-down and to establish a connection with
1758+ the daemon ("move-down" is a converse of "copy-up").
1759+- userspace tool and daemon.
1760+
1761+The userspace daemon establishes a connection with aufs and waits for
1762+the notification. The notified information is very similar to struct
1763+statfs containing the number of consumed blocks and inodes.
1764+When the consumed blocks/inodes of a branch exceeds the user-specified
1765+upper watermark, the daemon activates its move-down process until the
1766+consumed blocks/inodes reaches the user-specified lower watermark.
1767+
1768+The actual move-down is done by aufs based upon the request from
1769+user-space since we need to maintain the inode number and the internal
1770+pointer arrays in aufs.
1771+
1772+Currently aufs FHSM handles the regular files only. Additionally they
1773+must not be hard-linked nor pseudo-linked.
1774+
1775+
1776+o Cowork of aufs and the user-space daemon
1777+ During the userspace daemon established the connection, aufs sends a
1778+ small notification to it whenever aufs writes something into the
1779+ writable branch. But it may cost high since aufs issues statfs(2)
1780+ internally. So user can specify a new option to cache the
1781+ info. Actually the notification is controlled by these factors.
1782+ + the specified cache time.
1783+ + classified as "force" by aufs internally.
1784+ Until the specified time expires, aufs doesn't send the info
1785+ except the forced cases. When aufs decide forcing, the info is always
1786+ notified to userspace.
1787+ For example, the number of free inodes is generally large enough and
1788+ the shortage of it happens rarely. So aufs doesn't force the
1789+ notification when creating a new file, directory and others. This is
1790+ the typical case which aufs doesn't force.
1791+ When aufs writes the actual filedata and the files consumes any of new
1792+ blocks, the aufs forces notifying.
1793+
1794+
1795+o Interfaces in aufs
1796+- New branch attribute.
1797+ + fhsm
1798+ Specifies that the branch is managed by FHSM feature. In other word,
1799+ participant in the FHSM.
1800+ When nofhsm is set to the branch, it will not be the source/target
1801+ branch of the move-down operation. This attribute is set
1802+ independently from coo and moo attributes, and if you want full
1803+ FHSM, you should specify them as well.
1804+- New mount option.
1805+ + fhsm_sec
1806+ Specifies a second to suppress many less important info to be
1807+ notified.
1808+- New ioctl.
1809+ + AUFS_CTL_FHSM_FD
1810+ create a new file descriptor which userspace can read the notification
1811+ (a subset of struct statfs) from aufs.
1812+- Module parameter 'brs'
1813+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not
1814+ be set.
1815+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs
1816+ When there are two or more branches with fhsm attributes,
1817+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs
1818+ terminates it. As a result of remounting and branch-manipulation, the
1819+ number of branches with fhsm attribute can be one. In this case,
1820+ /sbin/mount.aufs will terminate the user-space daemon.
1821+
1822+
1823+Finally the operation is done as these steps in kernel-space.
1824+- make sure that,
1825+ + no one else is using the file.
1826+ + the file is not hard-linked.
1827+ + the file is not pseudo-linked.
1828+ + the file is a regular file.
1829+ + the parent dir is not opaqued.
1830+- find the target writable branch.
1831+- make sure the file is not whiteout-ed by the upper (than the target)
1832+ branch.
1833+- make the parent dir on the target branch.
1834+- mutex lock the inode on the branch.
1835+- unlink the whiteout on the target branch (if exists).
1836+- lookup and create the whiteout-ed temporary name on the target branch.
1837+- copy the file as the whiteout-ed temporary name on the target branch.
1838+- rename the whiteout-ed temporary name to the original name.
1839+- unlink the file on the source branch.
1840+- maintain the internal pointer array and the external inode number
1841+ table (XINO).
1842+- maintain the timestamps and other attributes of the parent dir and the
1843+ file.
1844+
1845+And of course, in every step, an error may happen. So the operation
1846+should restore the original file state after an error happens.
53392da6
AM
1847diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt
1848--- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 1849+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2015-01-25 13:00:38.627713742 +0100
523b37e3 1850@@ -0,0 +1,46 @@
53392da6 1851+
523b37e3 1852+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
1853+#
1854+# This program is free software; you can redistribute it and/or modify
1855+# it under the terms of the GNU General Public License as published by
1856+# the Free Software Foundation; either version 2 of the License, or
1857+# (at your option) any later version.
1858+#
1859+# This program is distributed in the hope that it will be useful,
1860+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1861+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1862+# GNU General Public License for more details.
1863+#
1864+# You should have received a copy of the GNU General Public License
523b37e3 1865+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
1866+
1867+mmap(2) -- File Memory Mapping
1868+----------------------------------------------------------------------
1869+In aufs, the file-mapped pages are handled by a branch fs directly, no
1870+interaction with aufs. It means aufs_mmap() calls the branch fs's
1871+->mmap().
1872+This approach is simple and good, but there is one problem.
1873+Under /proc, several entries show the mmap-ped files by its path (with
1874+device and inode number), and the printed path will be the path on the
1875+branch fs's instead of virtual aufs's.
1876+This is not a problem in most cases, but some utilities lsof(1) (and its
1877+user) may expect the path on aufs.
1878+
1879+To address this issue, aufs adds a new member called vm_prfile in struct
1880+vm_area_struct (and struct vm_region). The original vm_file points to
1881+the file on the branch fs in order to handle everything correctly as
1882+usual. The new vm_prfile points to a virtual file in aufs, and the
1883+show-functions in procfs refers to vm_prfile if it is set.
1884+Also we need to maintain several other places where touching vm_file
1885+such like
1886+- fork()/clone() copies vma and the reference count of vm_file is
1887+ incremented.
1888+- merging vma maintains the ref count too.
1889+
1890+This is not a good approach. It just faking the printed path. But it
1891+leaves all behaviour around f_mapping unchanged. This is surely an
1892+advantage.
1893+Actually aufs had adopted another complicated approach which calls
1894+generic_file_mmap() and handles struct vm_operations_struct. In this
1895+approach, aufs met a hard problem and I could not solve it without
1896+switching the approach.
c1595e42
JR
1897diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt
1898--- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100
1899+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2015-01-25 13:00:38.627713742 +0100
1900@@ -0,0 +1,96 @@
1901+
1902+# Copyright (C) 2014 Junjiro R. Okajima
1903+#
1904+# This program is free software; you can redistribute it and/or modify
1905+# it under the terms of the GNU General Public License as published by
1906+# the Free Software Foundation; either version 2 of the License, or
1907+# (at your option) any later version.
1908+#
1909+# This program is distributed in the hope that it will be useful,
1910+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1911+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1912+# GNU General Public License for more details.
1913+#
1914+# You should have received a copy of the GNU General Public License
1915+# along with this program; if not, write to the Free Software
1916+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1917+
1918+
1919+Listing XATTR/EA and getting the value
1920+----------------------------------------------------------------------
1921+For the inode standard attributes (owner, group, timestamps, etc.), aufs
1922+shows the values from the topmost existing file. This behaviour is good
1923+for the non-dir entreis since the bahaviour exactly matches the shown
1924+information. But for the directories, aufs considers all the same named
1925+entries on the lower branches. Which means, if one of the lower entry
1926+rejects readdir call, then aufs returns an error even if the topmost
1927+entry allows it. This behaviour is necessary to respect the branch fs's
1928+security, but can make users confused since the user-visible standard
1929+attributes don't match the behaviour.
1930+To address this issue, aufs has a mount option called dirperm1 which
1931+checks the permission for the topmost entry only, and ignores the lower
1932+entry's permission.
1933+
1934+A similar issue can happen around XATTR.
1935+getxattr(2) and listxattr(2) families behave as if dirperm1 option is
1936+always set. Otherwise these very unpleasant situation can happen.
1937+- listxattr(2) may return the duplicated entires.
1938+- users may not be able to remove or reset the XATTR forever,
1939+
1940+
1941+XATTR/EA support in the internal (copy,move)-(up,down)
1942+----------------------------------------------------------------------
1943+Generally the extended attributes of inode are categorazied as these.
1944+- "security" for LSM and capability.
1945+- "system" for posix ACL, 'acl' mount option is required for the branch
1946+ fs generally.
1947+- "trusted" for userspace, CAP_SYS_ADMIN is required.
1948+- "user" for userspace, 'user_xattr' mount option is required for the
1949+ branch fs generally.
1950+
1951+Moreover there are some other categories. Aufs handles these rather
1952+unpopular categories as the ordinary ones, ie. there is no special
1953+condition nor exception.
1954+
1955+In copy-up, the support for XATTR on the dst branch may differ from the
1956+src branch. In this case, the copy-up operation will get an error and
1957+the original user operation which triggered the copy-up fails. It can
1958+happen that even all copy-up will fail.
1959+When both of src and dst branches support XATTR and if an error occurs
1960+during copying XATTR, then the copy-up should fail obviously. That is a
1961+good reason and aufs should return an error to userspace. But when only
1962+the src branch support XATTR, aufs should not return an error.
1963+For example, the src branch supports ACL but the dst branch doesn't
1964+because the dst branch may natively un-support it or temporary
1965+un-support it due to "noacl" mount option. Of course, the dst branch fs
1966+may NOT return an error even if the XATTR is not supported. It is
1967+totally up to the branch fs.
1968+
1969+Anyway when the aufs internal copy-up gets an error from the dst branch
1970+fs, then aufs tries removing the just copied entry and returns the error
1971+to the userspace. The worst case of this situation will be all copy-up
1972+will fail.
1973+
1974+For the copy-up operation, there two basic approaches.
1975+- copy the specified XATTR only (by category above), and return the
1976+ error if it happens inconditionally.
1977+- copy all XATTR, and ignore the error on the specified category only.
1978+
1979+In order to support XATTR and to implement the correct behaviour, aufs
1980+chooses the latter approach and introduces some attributes for its
1981+branch, "icexsec", "icexsys", "icextr", "icexusr", and "icexoth".
1982+They correspond to the XATTR namespaces (see above). Additionally, to be
1983+convenient, "icex" is also provided which means all "ix*" attributes are
1984+set.
1985+
1986+The meaning of these attributes is to ignore the error from setting
1987+XATTR on that branch.
1988+Note that aufs tries copying all XATTR unconditionally, and ignores the
1989+error from the dst branch according to the specified attributes.
1990+
1991+Some XATTR may have its default value. The default value may come from
1992+the parent dir or the environment. If the default value is set at the
1993+file creating-time, it will be overwritten by copy-up.
1994+Some contradiction may happen I am afraid.
1995+Do we need another attribute to stop copying XATTR? I am unsure. For
1996+now, aufs implements the branch attributes to ignore the error.
53392da6
AM
1997diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt
1998--- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 1999+++ linux/Documentation/filesystems/aufs/design/07export.txt 2015-01-25 13:00:38.627713742 +0100
523b37e3 2000@@ -0,0 +1,58 @@
53392da6 2001+
523b37e3 2002+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
2003+#
2004+# This program is free software; you can redistribute it and/or modify
2005+# it under the terms of the GNU General Public License as published by
2006+# the Free Software Foundation; either version 2 of the License, or
2007+# (at your option) any later version.
2008+#
2009+# This program is distributed in the hope that it will be useful,
2010+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2011+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2012+# GNU General Public License for more details.
2013+#
2014+# You should have received a copy of the GNU General Public License
523b37e3 2015+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2016+
2017+Export Aufs via NFS
2018+----------------------------------------------------------------------
2019+Here is an approach.
2020+- like xino/xib, add a new file 'xigen' which stores aufs inode
2021+ generation.
2022+- iget_locked(): initialize aufs inode generation for a new inode, and
2023+ store it in xigen file.
2024+- destroy_inode(): increment aufs inode generation and store it in xigen
2025+ file. it is necessary even if it is not unlinked, because any data of
2026+ inode may be changed by UDBA.
2027+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise
2028+ build file handle by
2029+ + branch id (4 bytes)
2030+ + superblock generation (4 bytes)
2031+ + inode number (4 or 8 bytes)
2032+ + parent dir inode number (4 or 8 bytes)
2033+ + inode generation (4 bytes))
2034+ + return value of exportfs_encode_fh() for the parent on a branch (4
2035+ bytes)
2036+ + file handle for a branch (by exportfs_encode_fh())
2037+- fh_to_dentry():
2038+ + find the index of a branch from its id in handle, and check it is
2039+ still exist in aufs.
2040+ + 1st level: get the inode number from handle and search it in cache.
2041+ + 2nd level: if not found, get the parent inode number from handle and
2042+ search it in cache. and then open the parent dir, find the matching
2043+ inode number by vfs_readdir() and get its name, and call
2044+ lookup_one_len() for the target dentry.
2045+ + 3rd level: if the parent dir is not cached, call
2046+ exportfs_decode_fh() for a branch and get the parent on a branch,
2047+ build a pathname of it, convert it a pathname in aufs, call
2048+ path_lookup(). now aufs gets a parent dir dentry, then handle it as
2049+ the 2nd level.
2050+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount
2051+ for every branch, but not itself. to get this, (currently) aufs
2052+ searches in current->nsproxy->mnt_ns list. it may not be a good
2053+ idea, but I didn't get other approach.
2054+ + test the generation of the gotten inode.
2055+- every inode operation: they may get EBUSY due to UDBA. in this case,
2056+ convert it into ESTALE for NFSD.
2057+- readdir(): call lockdep_on/off() because filldir in NFSD calls
2058+ lookup_one_len(), vfs_getattr(), encode_fh() and others.
2059diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt
2060--- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 2061+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2015-01-25 13:00:38.627713742 +0100
523b37e3 2062@@ -0,0 +1,52 @@
53392da6 2063+
523b37e3 2064+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
2065+#
2066+# This program is free software; you can redistribute it and/or modify
2067+# it under the terms of the GNU General Public License as published by
2068+# the Free Software Foundation; either version 2 of the License, or
2069+# (at your option) any later version.
2070+#
2071+# This program is distributed in the hope that it will be useful,
2072+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2073+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2074+# GNU General Public License for more details.
2075+#
2076+# You should have received a copy of the GNU General Public License
523b37e3 2077+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2078+
2079+Show Whiteout Mode (shwh)
2080+----------------------------------------------------------------------
2081+Generally aufs hides the name of whiteouts. But in some cases, to show
2082+them is very useful for users. For instance, creating a new middle layer
2083+(branch) by merging existing layers.
2084+
2085+(borrowing aufs1 HOW-TO from a user, Michael Towers)
2086+When you have three branches,
2087+- Bottom: 'system', squashfs (underlying base system), read-only
2088+- Middle: 'mods', squashfs, read-only
2089+- Top: 'overlay', ram (tmpfs), read-write
2090+
2091+The top layer is loaded at boot time and saved at shutdown, to preserve
2092+the changes made to the system during the session.
2093+When larger changes have been made, or smaller changes have accumulated,
2094+the size of the saved top layer data grows. At this point, it would be
2095+nice to be able to merge the two overlay branches ('mods' and 'overlay')
2096+and rewrite the 'mods' squashfs, clearing the top layer and thus
2097+restoring save and load speed.
2098+
2099+This merging is simplified by the use of another aufs mount, of just the
2100+two overlay branches using the 'shwh' option.
2101+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \
2102+ aufs /livesys/merge_union
2103+
2104+A merged view of these two branches is then available at
2105+/livesys/merge_union, and the new feature is that the whiteouts are
2106+visible!
2107+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable
2108+writing to all branches. Also the default mode for all branches is 'ro'.
2109+It is now possible to save the combined contents of the two overlay
2110+branches to a new squashfs, e.g.:
2111+# mksquashfs /livesys/merge_union /path/to/newmods.squash
2112+
2113+This new squashfs archive can be stored on the boot device and the
2114+initramfs will use it to replace the old one at the next boot.
2115diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt
2116--- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 2117+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2015-01-25 13:00:38.627713742 +0100
523b37e3 2118@@ -0,0 +1,46 @@
53392da6 2119+
523b37e3 2120+# Copyright (C) 2010-2014 Junjiro R. Okajima
53392da6
AM
2121+#
2122+# This program is free software; you can redistribute it and/or modify
2123+# it under the terms of the GNU General Public License as published by
2124+# the Free Software Foundation; either version 2 of the License, or
2125+# (at your option) any later version.
2126+#
2127+# This program is distributed in the hope that it will be useful,
2128+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2129+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2130+# GNU General Public License for more details.
2131+#
2132+# You should have received a copy of the GNU General Public License
523b37e3 2133+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2134+
2135+Dynamically customizable FS operations
2136+----------------------------------------------------------------------
2137+Generally FS operations (struct inode_operations, struct
2138+address_space_operations, struct file_operations, etc.) are defined as
2139+"static const", but it never means that FS have only one set of
2140+operation. Some FS have multiple sets of them. For instance, ext2 has
2141+three sets, one for XIP, for NOBH, and for normal.
2142+Since aufs overrides and redirects these operations, sometimes aufs has
2143+to change its behaviour according to the branch FS type. More imporantly
2144+VFS acts differently if a function (member in the struct) is set or
2145+not. It means aufs should have several sets of operations and select one
2146+among them according to the branch FS definition.
2147+
2148+In order to solve this problem and not to affect the behavour of VFS,
2149+aufs defines these operations dynamically. For instance, aufs defines
2150+aio_read function for struct file_operations, but it may not be set to
2151+the file_operations. When the branch FS doesn't have it, aufs doesn't
2152+set it to its file_operations while the function definition itself is
2153+still alive. So the behaviour of io_submit(2) will not change, and it
2154+will return an error when aio_read is not defined.
2155+
2156+The lifetime of these dynamically generated operation object is
2157+maintained by aufs branch object. When the branch is removed from aufs,
2158+the reference counter of the object is decremented. When it reaches
2159+zero, the dynamically generated operation object will be freed.
2160+
2161+This approach is designed to support AIO (io_submit), Direcit I/O and
2162+XIP mainly.
2163+Currently this approach is applied to file_operations and
2164+vm_operations_struct for regular files only.
2165diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt linux/Documentation/filesystems/aufs/design/99plan.txt
2166--- /usr/share/empty/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100
c1595e42 2167+++ linux/Documentation/filesystems/aufs/design/99plan.txt 2015-01-25 13:00:38.627713742 +0100
076b876e 2168@@ -0,0 +1,58 @@
53392da6 2169+
523b37e3 2170+# Copyright (C) 2005-2014 Junjiro R. Okajima
53392da6
AM
2171+#
2172+# This program is free software; you can redistribute it and/or modify
2173+# it under the terms of the GNU General Public License as published by
2174+# the Free Software Foundation; either version 2 of the License, or
2175+# (at your option) any later version.
2176+#
2177+# This program is distributed in the hope that it will be useful,
2178+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2179+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2180+# GNU General Public License for more details.
2181+#
2182+# You should have received a copy of the GNU General Public License
523b37e3 2183+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53392da6
AM
2184+
2185+Plan
2186+
2187+Restoring some features which was implemented in aufs1.
2188+They were dropped in aufs2 in order to make source files simpler and
2189+easier to be reviewed.
2190+
2191+
53392da6
AM
2192+Being Another Aufs's Readonly Branch (robr)
2193+----------------------------------------------------------------------
2194+Aufs1 allows aufs to be another aufs's readonly branch.
2195+This feature was developed by a user's request. But it may not be used
2196+currecnly.
2197+
2198+
53392da6
AM
2199+Refresh the Opened File (refrof)
2200+----------------------------------------------------------------------
2201+This option is implemented in aufs1 but incomplete.
2202+
2203+When user reads from a file, he expects to get its latest filedata
2204+generally. If the file is removed and a new same named file is created,
2205+the content he gets is unchanged, ie. the unlinked filedata.
2206+
2207+Let's try case study again.
2208+- aufs has two branches.
2209+ /au = /rw + /ro
2210+- "fileA" exists under /ro, but /rw.
2211+- user opened "/au/fileA".
2212+- he or someone else inserts a branch (/new) between /rw and /ro.
2213+ /au = /rw + /new + /ro
2214+- the new branch has "fileA".
2215+- user reads from the opened "fileA"
2216+- which filedata should aufs return, from /ro or /new?
2217+
2218+Some people says it has to be "from /ro" and it is a semantics of Unix.
2219+The others say it should be "from /new" because the file is not removed
2220+and it is equivalent to the case of someone else modifies the file.
2221+
2222+Here again I don't have a best and final answer. I got an idea to
2223+implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the
2224+Opened File) is specified (by default), aufs returns the filedata from
2225+/new.
2226+Otherwise from /new.
2227diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README
2228--- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100
c1595e42 2229+++ linux/Documentation/filesystems/aufs/README 2015-01-25 13:00:38.627713742 +0100
076b876e 2230@@ -0,0 +1,370 @@
53392da6
AM
2231+
2232+Aufs3 -- advanced multi layered unification filesystem version 3.x
2233+http://aufs.sf.net
2234+Junjiro R. Okajima
2235+
2236+
2237+0. Introduction
2238+----------------------------------------
2239+In the early days, aufs was entirely re-designed and re-implemented
2240+Unionfs Version 1.x series. After many original ideas, approaches,
2241+improvements and implementations, it becomes totally different from
2242+Unionfs while keeping the basic features.
2243+Recently, Unionfs Version 2.x series begin taking some of the same
2244+approaches to aufs1's.
2245+Unionfs is being developed by Professor Erez Zadok at Stony Brook
2246+University and his team.
2247+
2248+Aufs3 supports linux-3.0 and later.
2249+If you want older kernel version support, try aufs2-2.6.git or
2250+aufs2-standalone.git repository, aufs1 from CVS on SourceForge.
2251+
2252+Note: it becomes clear that "Aufs was rejected. Let's give it up."
38d290e6
JR
2253+ According to Christoph Hellwig, linux rejects all union-type
2254+ filesystems but UnionMount.
53392da6
AM
2255+<http://marc.info/?l=linux-kernel&m=123938533724484&w=2>
2256+
38d290e6
JR
2257+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and
2258+ UnionMount, and he pointed out an issue around a directory mutex
2259+ lock and aufs addressed it. But it is still unsure whether aufs will
2260+ be merged (or any other union solution).
076b876e 2261+<http://marc.info/?l=linux-kernel&m=136312705029295&w=1>
38d290e6 2262+
53392da6
AM
2263+
2264+1. Features
2265+----------------------------------------
2266+- unite several directories into a single virtual filesystem. The member
2267+ directory is called as a branch.
2268+- you can specify the permission flags to the branch, which are 'readonly',
2269+ 'readwrite' and 'whiteout-able.'
2270+- by upper writable branch, internal copyup and whiteout, files/dirs on
2271+ readonly branch are modifiable logically.
2272+- dynamic branch manipulation, add, del.
2273+- etc...
2274+
2275+Also there are many enhancements in aufs1, such as:
2276+- readdir(3) in userspace.
2277+- keep inode number by external inode number table
2278+- keep the timestamps of file/dir in internal copyup operation
2279+- seekable directory, supporting NFS readdir.
2280+- whiteout is hardlinked in order to reduce the consumption of inodes
2281+ on branch
2282+- do not copyup, nor create a whiteout when it is unnecessary
2283+- revert a single systemcall when an error occurs in aufs
2284+- remount interface instead of ioctl
2285+- maintain /etc/mtab by an external command, /sbin/mount.aufs.
2286+- loopback mounted filesystem as a branch
2287+- kernel thread for removing the dir who has a plenty of whiteouts
2288+- support copyup sparse file (a file which has a 'hole' in it)
2289+- default permission flags for branches
2290+- selectable permission flags for ro branch, whether whiteout can
2291+ exist or not
2292+- export via NFS.
2293+- support <sysfs>/fs/aufs and <debugfs>/aufs.
2294+- support multiple writable branches, some policies to select one
2295+ among multiple writable branches.
2296+- a new semantics for link(2) and rename(2) to support multiple
2297+ writable branches.
2298+- no glibc changes are required.
2299+- pseudo hardlink (hardlink over branches)
2300+- allow a direct access manually to a file on branch, e.g. bypassing aufs.
2301+ including NFS or remote filesystem branch.
2302+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX.
2303+- and more...
2304+
2305+Currently these features are dropped temporary from aufs3.
2306+See design/08plan.txt in detail.
2307+- test only the highest one for the directory permission (dirperm1)
2308+- copyup on open (coo=)
2309+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs
2310+ (robr)
2311+- statistics of aufs thread (/sys/fs/aufs/stat)
2312+- delegation mode (dlgt)
2313+ a delegation of the internal branch access to support task I/O
2314+ accounting, which also supports Linux Security Modules (LSM) mainly
2315+ for Suse AppArmor.
2316+- intent.open/create (file open in a single lookup)
2317+
2318+Features or just an idea in the future (see also design/*.txt),
2319+- reorder the branch index without del/re-add.
2320+- permanent xino files for NFSD
2321+- an option for refreshing the opened files after add/del branches
2322+- 'move' policy for copy-up between two writable branches, after
2323+ checking free space.
2324+- light version, without branch manipulation. (unnecessary?)
2325+- copyup in userspace
2326+- inotify in userspace
2327+- readv/writev
2328+- xattr, acl
2329+
2330+
2331+2. Download
2332+----------------------------------------
1e00d052
AM
2333+There were three GIT trees for aufs3, aufs3-linux.git,
2334+aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in
2335+"aufs-util.git."
2336+While the aufs-util is always necessary, you need either of aufs3-linux
2337+or aufs3-standalone.
2338+
2339+The aufs3-linux tree includes the whole linux mainline GIT tree,
2340+git://git.kernel.org/.../torvalds/linux.git.
2341+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot
b4510431 2342+build aufs3 as an external kernel module.
1e00d052
AM
2343+
2344+On the other hand, the aufs3-standalone tree has only aufs source files
53392da6
AM
2345+and necessary patches, and you can select CONFIG_AUFS_FS=m.
2346+
2347+You will find GIT branches whose name is in form of "aufs3.x" where "x"
2348+represents the linux kernel version, "linux-3.x". For instance,
1e00d052
AM
2349+"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use
2350+"aufs3.x-rcN" branch.
2351+
2352+o aufs3-linux tree
2353+$ git clone --reference /your/linux/git/tree \
86dc4139 2354+ git://git.code.sf.net/p/aufs/aufs3-linux aufs-aufs3-linux \
1e00d052
AM
2355+ aufs3-linux.git
2356+- if you don't have linux GIT tree, then remove "--reference ..."
2357+$ cd aufs3-linux.git
2358+$ git checkout origin/aufs3.0
53392da6
AM
2359+
2360+o aufs3-standalone tree
86dc4139 2361+$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \
53392da6
AM
2362+ aufs3-standalone.git
2363+$ cd aufs3-standalone.git
2364+$ git checkout origin/aufs3.0
2365+
2366+o aufs-util tree
86dc4139 2367+$ git clone git://git.code.sf.net/p/aufs/aufs-util \
53392da6
AM
2368+ aufs-util.git
2369+$ cd aufs-util.git
2370+$ git checkout origin/aufs3.0
2371+
9dbd164d
AM
2372+Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY.
2373+The minor version number, 'x' in '3.x', of aufs may not always
2374+follow the minor version number of the kernel.
2375+Because changes in the kernel that cause the use of a new
2376+minor version number do not always require changes to aufs-util.
2377+
2378+Since aufs-util has its own minor version number, you may not be
2379+able to find a GIT branch in aufs-util for your kernel's
2380+exact minor version number.
2381+In this case, you should git-checkout the branch for the
53392da6 2382+nearest lower number.
9dbd164d
AM
2383+
2384+For (an unreleased) example:
2385+If you are using "linux-3.10" and the "aufs3.10" branch
7eafdf33 2386+does not exist in aufs-util repository, then "aufs3.9", "aufs3.8"
9dbd164d
AM
2387+or something numerically smaller is the branch for your kernel.
2388+
53392da6
AM
2389+Also you can view all branches by
2390+ $ git branch -a
2391+
2392+
2393+3. Configuration and Compilation
2394+----------------------------------------
2395+Make sure you have git-checkout'ed the correct branch.
2396+
1e00d052 2397+For aufs3-linux tree,
c06a8ce3 2398+- enable CONFIG_AUFS_FS.
1e00d052
AM
2399+- set other aufs configurations if necessary.
2400+
53392da6
AM
2401+For aufs3-standalone tree,
2402+There are several ways to build.
2403+
2404+1.
2405+- apply ./aufs3-kbuild.patch to your kernel source files.
2406+- apply ./aufs3-base.patch too.
523b37e3 2407+- apply ./aufs3-mmap.patch too.
53392da6
AM
2408+- apply ./aufs3-standalone.patch too, if you have a plan to set
2409+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch.
537831f9
AM
2410+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your
2411+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild.
c06a8ce3 2412+- enable CONFIG_AUFS_FS, you can select either
53392da6
AM
2413+ =m or =y.
2414+- and build your kernel as usual.
2415+- install the built kernel.
c06a8ce3
AM
2416+ Note: Since linux-3.9, every filesystem module requires an alias
2417+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2418+ modules.aliases file if you set CONFIG_AUFS_FS=m.
7eafdf33
AM
2419+- install the header files too by "make headers_install" to the
2420+ directory where you specify. By default, it is $PWD/usr.
b4510431 2421+ "make help" shows a brief note for headers_install.
53392da6
AM
2422+- and reboot your system.
2423+
2424+2.
2425+- module only (CONFIG_AUFS_FS=m).
2426+- apply ./aufs3-base.patch to your kernel source files.
523b37e3 2427+- apply ./aufs3-mmap.patch too.
53392da6
AM
2428+- apply ./aufs3-standalone.patch too.
2429+- build your kernel, don't forget "make headers_install", and reboot.
2430+- edit ./config.mk and set other aufs configurations if necessary.
b4510431 2431+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes
53392da6
AM
2432+ every aufs configurations.
2433+- build the module by simple "make".
c06a8ce3
AM
2434+ Note: Since linux-3.9, every filesystem module requires an alias
2435+ "fs-<fsname>". You should make sure that "fs-aufs" is listed in your
2436+ modules.aliases file.
53392da6
AM
2437+- you can specify ${KDIR} make variable which points to your kernel
2438+ source tree.
2439+- install the files
2440+ + run "make install" to install the aufs module, or copy the built
b4510431
AM
2441+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply).
2442+ + run "make install_headers" (instead of headers_install) to install
2443+ the modified aufs header file (you can specify DESTDIR which is
2444+ available in aufs standalone version's Makefile only), or copy
2445+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever
2446+ you like manually. By default, the target directory is $PWD/usr.
53392da6
AM
2447+- no need to apply aufs3-kbuild.patch, nor copying source files to your
2448+ kernel source tree.
2449+
b4510431 2450+Note: The header file aufs_type.h is necessary to build aufs-util
53392da6
AM
2451+ as well as "make headers_install" in the kernel source tree.
2452+ headers_install is subject to be forgotten, but it is essentially
2453+ necessary, not only for building aufs-util.
2454+ You may not meet problems without headers_install in some older
2455+ version though.
2456+
2457+And then,
2458+- read README in aufs-util, build and install it
9dbd164d
AM
2459+- note that your distribution may contain an obsoleted version of
2460+ aufs_type.h in /usr/include/linux or something. When you build aufs
2461+ utilities, make sure that your compiler refers the correct aufs header
2462+ file which is built by "make headers_install."
53392da6
AM
2463+- if you want to use readdir(3) in userspace or pathconf(3) wrapper,
2464+ then run "make install_ulib" too. And refer to the aufs manual in
2465+ detail.
2466+
38d290e6
JR
2467+There several other patches in aufs3-standalone.git. They are all
2468+optional. When you meet some problems, they will help you.
2469+- aufs3-loopback.patch
2470+ Supports a nested loopback mount in a branch-fs. This patch is
2471+ unnecessary until aufs produces a message like "you may want to try
2472+ another patch for loopback file".
2473+- vfs-ino.patch
2474+ Modifies a system global kernel internal function get_next_ino() in
2475+ order to stop assigning 0 for an inode-number. Not directly related to
2476+ aufs, but recommended generally.
2477+- tmpfs-idr.patch
2478+ Keeps the tmpfs inode number as the lowest value. Effective to reduce
2479+ the size of aufs XINO files for tmpfs branch. Also it prevents the
2480+ duplication of inode number, which is important for backup tools and
2481+ other utilities. When you find aufs XINO files for tmpfs branch
2482+ growing too much, try this patch.
2483+
53392da6
AM
2484+
2485+4. Usage
2486+----------------------------------------
2487+At first, make sure aufs-util are installed, and please read the aufs
2488+manual, aufs.5 in aufs-util.git tree.
2489+$ man -l aufs.5
2490+
2491+And then,
2492+$ mkdir /tmp/rw /tmp/aufs
2493+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs
2494+
2495+Here is another example. The result is equivalent.
2496+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs
2497+ Or
2498+# mount -t aufs -o br:/tmp/rw none /tmp/aufs
2499+# mount -o remount,append:${HOME} /tmp/aufs
2500+
2501+Then, you can see whole tree of your home dir through /tmp/aufs. If
2502+you modify a file under /tmp/aufs, the one on your home directory is
2503+not affected, instead the same named file will be newly created under
2504+/tmp/rw. And all of your modification to a file will be applied to
2505+the one under /tmp/rw. This is called the file based Copy on Write
2506+(COW) method.
2507+Aufs mount options are described in aufs.5.
2508+If you run chroot or something and make your aufs as a root directory,
2509+then you need to customize the shutdown script. See the aufs manual in
2510+detail.
2511+
2512+Additionally, there are some sample usages of aufs which are a
2513+diskless system with network booting, and LiveCD over NFS.
2514+See sample dir in CVS tree on SourceForge.
2515+
2516+
2517+5. Contact
2518+----------------------------------------
2519+When you have any problems or strange behaviour in aufs, please let me
2520+know with:
2521+- /proc/mounts (instead of the output of mount(8))
2522+- /sys/module/aufs/*
2523+- /sys/fs/aufs/* (if you have them)
2524+- /debug/aufs/* (if you have them)
2525+- linux kernel version
2526+ if your kernel is not plain, for example modified by distributor,
2527+ the url where i can download its source is necessary too.
2528+- aufs version which was printed at loading the module or booting the
2529+ system, instead of the date you downloaded.
2530+- configuration (define/undefine CONFIG_AUFS_xxx)
2531+- kernel configuration or /proc/config.gz (if you have it)
2532+- behaviour which you think to be incorrect
2533+- actual operation, reproducible one is better
2534+- mailto: aufs-users at lists.sourceforge.net
2535+
2536+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches,
2537+and Feature Requests) on SourceForge. Please join and write to
2538+aufs-users ML.
2539+
2540+
2541+6. Acknowledgements
2542+----------------------------------------
2543+Thanks to everyone who have tried and are using aufs, whoever
2544+have reported a bug or any feedback.
2545+
2546+Especially donators:
2547+Tomas Matejicek(slax.org) made a donation (much more than once).
2548+ Since Apr 2010, Tomas M (the author of Slax and Linux Live
2549+ scripts) is making "doubling" donations.
2550+ Unfortunately I cannot list all of the donators, but I really
b4510431 2551+ appreciate.
53392da6
AM
2552+ It ends Aug 2010, but the ordinary donation URL is still available.
2553+ <http://sourceforge.net/donate/index.php?group_id=167503>
2554+Dai Itasaka made a donation (2007/8).
2555+Chuck Smith made a donation (2008/4, 10 and 12).
2556+Henk Schoneveld made a donation (2008/9).
2557+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10).
2558+Francois Dupoux made a donation (2008/11).
2559+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public
2560+ aufs2 GIT tree (2009/2).
2561+William Grant made a donation (2009/3).
2562+Patrick Lane made a donation (2009/4).
2563+The Mail Archive (mail-archive.com) made donations (2009/5).
2564+Nippy Networks (Ed Wildgoose) made a donation (2009/7).
2565+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11).
2566+Pavel Pronskiy made a donation (2011/2).
2567+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy
2568+ Networks (Ed Wildgoose) made a donation for hardware (2011/3).
537831f9
AM
2569+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and
2570+11).
1e00d052 2571+Sam Liddicott made a donation (2011/9).
86dc4139
AM
2572+Era Scarecrow made a donation (2013/4).
2573+Bor Ratajc made a donation (2013/4).
2574+Alessandro Gorreta made a donation (2013/4).
2575+POIRETTE Marc made a donation (2013/4).
2576+Alessandro Gorreta made a donation (2013/4).
2577+lauri kasvandik made a donation (2013/5).
392086de 2578+"pemasu from Finland" made a donation (2013/7).
523b37e3
AM
2579+The Parted Magic Project made a donation (2013/9 and 11).
2580+Pavel Barta made a donation (2013/10).
38d290e6 2581+Nikolay Pertsev made a donation (2014/5).
076b876e
AM
2582+James B made a donation (2014/7).
2583+Stefano Di Biase made a donation (2014/8).
53392da6
AM
2584+
2585+Thank you very much.
2586+Donations are always, including future donations, very important and
2587+helpful for me to keep on developing aufs.
2588+
2589+
2590+7.
2591+----------------------------------------
2592+If you are an experienced user, no explanation is needed. Aufs is
2593+just a linux filesystem.
2594+
2595+
2596+Enjoy!
2597+
2598+# Local variables: ;
2599+# mode: text;
2600+# End: ;
7f207e10
AM
2601diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h
2602--- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 2603+++ linux/fs/aufs/aufs.h 2015-01-25 13:00:38.627713742 +0100
523b37e3 2604@@ -0,0 +1,59 @@
7f207e10 2605+/*
523b37e3 2606+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
2607+ *
2608+ * This program, aufs is free software; you can redistribute it and/or modify
2609+ * it under the terms of the GNU General Public License as published by
2610+ * the Free Software Foundation; either version 2 of the License, or
2611+ * (at your option) any later version.
2612+ *
2613+ * This program is distributed in the hope that it will be useful,
2614+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2615+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2616+ * GNU General Public License for more details.
2617+ *
2618+ * You should have received a copy of the GNU General Public License
523b37e3 2619+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2620+ */
2621+
2622+/*
2623+ * all header files
2624+ */
2625+
2626+#ifndef __AUFS_H__
2627+#define __AUFS_H__
2628+
2629+#ifdef __KERNEL__
2630+
2631+#define AuStub(type, name, body, ...) \
2632+ static inline type name(__VA_ARGS__) { body; }
2633+
2634+#define AuStubVoid(name, ...) \
2635+ AuStub(void, name, , __VA_ARGS__)
2636+#define AuStubInt0(name, ...) \
2637+ AuStub(int, name, return 0, __VA_ARGS__)
2638+
2639+#include "debug.h"
2640+
2641+#include "branch.h"
2642+#include "cpup.h"
2643+#include "dcsub.h"
2644+#include "dbgaufs.h"
2645+#include "dentry.h"
2646+#include "dir.h"
2647+#include "dynop.h"
2648+#include "file.h"
2649+#include "fstype.h"
2650+#include "inode.h"
2651+#include "loop.h"
2652+#include "module.h"
7f207e10
AM
2653+#include "opts.h"
2654+#include "rwsem.h"
2655+#include "spl.h"
2656+#include "super.h"
2657+#include "sysaufs.h"
2658+#include "vfsub.h"
2659+#include "whout.h"
2660+#include "wkq.h"
2661+
2662+#endif /* __KERNEL__ */
2663+#endif /* __AUFS_H__ */
2664diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
2665--- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
2666+++ linux/fs/aufs/branch.c 2015-01-25 13:00:38.627713742 +0100
2667@@ -0,0 +1,1410 @@
7f207e10 2668+/*
523b37e3 2669+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
2670+ *
2671+ * This program, aufs is free software; you can redistribute it and/or modify
2672+ * it under the terms of the GNU General Public License as published by
2673+ * the Free Software Foundation; either version 2 of the License, or
2674+ * (at your option) any later version.
2675+ *
2676+ * This program is distributed in the hope that it will be useful,
2677+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2678+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2679+ * GNU General Public License for more details.
2680+ *
2681+ * You should have received a copy of the GNU General Public License
523b37e3 2682+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
2683+ */
2684+
2685+/*
2686+ * branch management
2687+ */
2688+
027c5e7a 2689+#include <linux/compat.h>
7f207e10
AM
2690+#include <linux/statfs.h>
2691+#include "aufs.h"
2692+
2693+/*
2694+ * free a single branch
1facf9fc 2695+ */
2696+static void au_br_do_free(struct au_branch *br)
2697+{
2698+ int i;
2699+ struct au_wbr *wbr;
4a4d8108 2700+ struct au_dykey **key;
1facf9fc 2701+
027c5e7a
AM
2702+ au_hnotify_fin_br(br);
2703+
1facf9fc 2704+ if (br->br_xino.xi_file)
2705+ fput(br->br_xino.xi_file);
2706+ mutex_destroy(&br->br_xino.xi_nondir_mtx);
2707+
2708+ AuDebugOn(atomic_read(&br->br_count));
2709+
2710+ wbr = br->br_wbr;
2711+ if (wbr) {
2712+ for (i = 0; i < AuBrWh_Last; i++)
2713+ dput(wbr->wbr_wh[i]);
2714+ AuDebugOn(atomic_read(&wbr->wbr_wh_running));
dece6358 2715+ AuRwDestroy(&wbr->wbr_wh_rwsem);
1facf9fc 2716+ }
2717+
076b876e
AM
2718+ if (br->br_fhsm) {
2719+ au_br_fhsm_fin(br->br_fhsm);
2720+ kfree(br->br_fhsm);
2721+ }
2722+
4a4d8108
AM
2723+ key = br->br_dykey;
2724+ for (i = 0; i < AuBrDynOp; i++, key++)
2725+ if (*key)
2726+ au_dy_put(*key);
2727+ else
2728+ break;
2729+
537831f9
AM
2730+ /* recursive lock, s_umount of branch's */
2731+ lockdep_off();
86dc4139 2732+ path_put(&br->br_path);
537831f9 2733+ lockdep_on();
1facf9fc 2734+ kfree(wbr);
2735+ kfree(br);
2736+}
2737+
2738+/*
2739+ * frees all branches
2740+ */
2741+void au_br_free(struct au_sbinfo *sbinfo)
2742+{
2743+ aufs_bindex_t bmax;
2744+ struct au_branch **br;
2745+
dece6358
AM
2746+ AuRwMustWriteLock(&sbinfo->si_rwsem);
2747+
1facf9fc 2748+ bmax = sbinfo->si_bend + 1;
2749+ br = sbinfo->si_branch;
2750+ while (bmax--)
2751+ au_br_do_free(*br++);
2752+}
2753+
2754+/*
2755+ * find the index of a branch which is specified by @br_id.
2756+ */
2757+int au_br_index(struct super_block *sb, aufs_bindex_t br_id)
2758+{
2759+ aufs_bindex_t bindex, bend;
2760+
2761+ bend = au_sbend(sb);
2762+ for (bindex = 0; bindex <= bend; bindex++)
2763+ if (au_sbr_id(sb, bindex) == br_id)
2764+ return bindex;
2765+ return -1;
2766+}
2767+
2768+/* ---------------------------------------------------------------------- */
2769+
2770+/*
2771+ * add a branch
2772+ */
2773+
b752ccd1
AM
2774+static int test_overlap(struct super_block *sb, struct dentry *h_adding,
2775+ struct dentry *h_root)
1facf9fc 2776+{
b752ccd1
AM
2777+ if (unlikely(h_adding == h_root
2778+ || au_test_loopback_overlap(sb, h_adding)))
1facf9fc 2779+ return 1;
b752ccd1
AM
2780+ if (h_adding->d_sb != h_root->d_sb)
2781+ return 0;
2782+ return au_test_subdir(h_adding, h_root)
2783+ || au_test_subdir(h_root, h_adding);
1facf9fc 2784+}
2785+
2786+/*
2787+ * returns a newly allocated branch. @new_nbranch is a number of branches
2788+ * after adding a branch.
2789+ */
2790+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch,
2791+ int perm)
2792+{
2793+ struct au_branch *add_branch;
2794+ struct dentry *root;
4a4d8108 2795+ int err;
1facf9fc 2796+
4a4d8108 2797+ err = -ENOMEM;
1facf9fc 2798+ root = sb->s_root;
2799+ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS);
2800+ if (unlikely(!add_branch))
2801+ goto out;
2802+
027c5e7a
AM
2803+ err = au_hnotify_init_br(add_branch, perm);
2804+ if (unlikely(err))
2805+ goto out_br;
2806+
1facf9fc 2807+ add_branch->br_wbr = NULL;
2808+ if (au_br_writable(perm)) {
2809+ /* may be freed separately at changing the branch permission */
2810+ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr),
2811+ GFP_NOFS);
2812+ if (unlikely(!add_branch->br_wbr))
027c5e7a 2813+ goto out_hnotify;
1facf9fc 2814+ }
2815+
076b876e
AM
2816+ add_branch->br_fhsm = NULL;
2817+ if (au_br_fhsm(perm)) {
2818+ err = au_fhsm_br_alloc(add_branch);
2819+ if (unlikely(err))
2820+ goto out_wbr;
2821+ }
2822+
4a4d8108
AM
2823+ err = au_sbr_realloc(au_sbi(sb), new_nbranch);
2824+ if (!err)
2825+ err = au_di_realloc(au_di(root), new_nbranch);
2826+ if (!err)
2827+ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch);
2828+ if (!err)
2829+ return add_branch; /* success */
1facf9fc 2830+
076b876e 2831+out_wbr:
1facf9fc 2832+ kfree(add_branch->br_wbr);
027c5e7a
AM
2833+out_hnotify:
2834+ au_hnotify_fin_br(add_branch);
4f0767ce 2835+out_br:
1facf9fc 2836+ kfree(add_branch);
4f0767ce 2837+out:
4a4d8108 2838+ return ERR_PTR(err);
1facf9fc 2839+}
2840+
2841+/*
2842+ * test if the branch permission is legal or not.
2843+ */
2844+static int test_br(struct inode *inode, int brperm, char *path)
2845+{
2846+ int err;
2847+
4a4d8108
AM
2848+ err = (au_br_writable(brperm) && IS_RDONLY(inode));
2849+ if (!err)
2850+ goto out;
1facf9fc 2851+
4a4d8108
AM
2852+ err = -EINVAL;
2853+ pr_err("write permission for readonly mount or inode, %s\n", path);
2854+
4f0767ce 2855+out:
1facf9fc 2856+ return err;
2857+}
2858+
2859+/*
2860+ * returns:
2861+ * 0: success, the caller will add it
2862+ * plus: success, it is already unified, the caller should ignore it
2863+ * minus: error
2864+ */
2865+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
2866+{
2867+ int err;
2868+ aufs_bindex_t bend, bindex;
2869+ struct dentry *root;
2870+ struct inode *inode, *h_inode;
2871+
2872+ root = sb->s_root;
2873+ bend = au_sbend(sb);
2874+ if (unlikely(bend >= 0
2875+ && au_find_dbindex(root, add->path.dentry) >= 0)) {
2876+ err = 1;
2877+ if (!remount) {
2878+ err = -EINVAL;
4a4d8108 2879+ pr_err("%s duplicated\n", add->pathname);
1facf9fc 2880+ }
2881+ goto out;
2882+ }
2883+
2884+ err = -ENOSPC; /* -E2BIG; */
2885+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex
2886+ || AUFS_BRANCH_MAX - 1 <= bend)) {
4a4d8108 2887+ pr_err("number of branches exceeded %s\n", add->pathname);
1facf9fc 2888+ goto out;
2889+ }
2890+
2891+ err = -EDOM;
2892+ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) {
4a4d8108 2893+ pr_err("bad index %d\n", add->bindex);
1facf9fc 2894+ goto out;
2895+ }
2896+
2897+ inode = add->path.dentry->d_inode;
2898+ err = -ENOENT;
2899+ if (unlikely(!inode->i_nlink)) {
4a4d8108 2900+ pr_err("no existence %s\n", add->pathname);
1facf9fc 2901+ goto out;
2902+ }
2903+
2904+ err = -EINVAL;
2905+ if (unlikely(inode->i_sb == sb)) {
4a4d8108 2906+ pr_err("%s must be outside\n", add->pathname);
1facf9fc 2907+ goto out;
2908+ }
2909+
2910+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) {
4a4d8108
AM
2911+ pr_err("unsupported filesystem, %s (%s)\n",
2912+ add->pathname, au_sbtype(inode->i_sb));
1facf9fc 2913+ goto out;
2914+ }
2915+
c1595e42
JR
2916+ if (unlikely(inode->i_sb->s_stack_depth)) {
2917+ pr_err("already stacked, %s (%s)\n",
2918+ add->pathname, au_sbtype(inode->i_sb));
2919+ goto out;
2920+ }
2921+
1facf9fc 2922+ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname);
2923+ if (unlikely(err))
2924+ goto out;
2925+
2926+ if (bend < 0)
2927+ return 0; /* success */
2928+
2929+ err = -EINVAL;
2930+ for (bindex = 0; bindex <= bend; bindex++)
2931+ if (unlikely(test_overlap(sb, add->path.dentry,
2932+ au_h_dptr(root, bindex)))) {
4a4d8108 2933+ pr_err("%s is overlapped\n", add->pathname);
1facf9fc 2934+ goto out;
2935+ }
2936+
2937+ err = 0;
2938+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
2939+ h_inode = au_h_dptr(root, 0)->d_inode;
2940+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
0c3ec466
AM
2941+ || !uid_eq(h_inode->i_uid, inode->i_uid)
2942+ || !gid_eq(h_inode->i_gid, inode->i_gid))
2943+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
2944+ add->pathname,
2945+ i_uid_read(inode), i_gid_read(inode),
2946+ (inode->i_mode & S_IALLUGO),
2947+ i_uid_read(h_inode), i_gid_read(h_inode),
2948+ (h_inode->i_mode & S_IALLUGO));
1facf9fc 2949+ }
2950+
4f0767ce 2951+out:
1facf9fc 2952+ return err;
2953+}
2954+
2955+/*
2956+ * initialize or clean the whiteouts for an adding branch
2957+ */
2958+static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
86dc4139 2959+ int new_perm)
1facf9fc 2960+{
2961+ int err, old_perm;
2962+ aufs_bindex_t bindex;
2963+ struct mutex *h_mtx;
2964+ struct au_wbr *wbr;
2965+ struct au_hinode *hdir;
2966+
86dc4139
AM
2967+ err = vfsub_mnt_want_write(au_br_mnt(br));
2968+ if (unlikely(err))
2969+ goto out;
2970+
1facf9fc 2971+ wbr = br->br_wbr;
2972+ old_perm = br->br_perm;
2973+ br->br_perm = new_perm;
2974+ hdir = NULL;
2975+ h_mtx = NULL;
2976+ bindex = au_br_index(sb, br->br_id);
2977+ if (0 <= bindex) {
2978+ hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 2979+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 2980+ } else {
86dc4139 2981+ h_mtx = &au_br_dentry(br)->d_inode->i_mutex;
1facf9fc 2982+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT);
2983+ }
2984+ if (!wbr)
86dc4139 2985+ err = au_wh_init(br, sb);
1facf9fc 2986+ else {
2987+ wbr_wh_write_lock(wbr);
86dc4139 2988+ err = au_wh_init(br, sb);
1facf9fc 2989+ wbr_wh_write_unlock(wbr);
2990+ }
2991+ if (hdir)
4a4d8108 2992+ au_hn_imtx_unlock(hdir);
1facf9fc 2993+ else
2994+ mutex_unlock(h_mtx);
86dc4139 2995+ vfsub_mnt_drop_write(au_br_mnt(br));
1facf9fc 2996+ br->br_perm = old_perm;
2997+
2998+ if (!err && wbr && !au_br_writable(new_perm)) {
2999+ kfree(wbr);
3000+ br->br_wbr = NULL;
3001+ }
3002+
86dc4139 3003+out:
1facf9fc 3004+ return err;
3005+}
3006+
3007+static int au_wbr_init(struct au_branch *br, struct super_block *sb,
86dc4139 3008+ int perm)
1facf9fc 3009+{
3010+ int err;
4a4d8108 3011+ struct kstatfs kst;
1facf9fc 3012+ struct au_wbr *wbr;
3013+
3014+ wbr = br->br_wbr;
dece6358 3015+ au_rw_init(&wbr->wbr_wh_rwsem);
1facf9fc 3016+ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh));
3017+ atomic_set(&wbr->wbr_wh_running, 0);
3018+ wbr->wbr_bytes = 0;
3019+
4a4d8108
AM
3020+ /*
3021+ * a limit for rmdir/rename a dir
523b37e3 3022+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h
4a4d8108 3023+ */
86dc4139 3024+ err = vfs_statfs(&br->br_path, &kst);
4a4d8108
AM
3025+ if (unlikely(err))
3026+ goto out;
3027+ err = -EINVAL;
3028+ if (kst.f_namelen >= NAME_MAX)
86dc4139 3029+ err = au_br_init_wh(sb, br, perm);
4a4d8108 3030+ else
523b37e3
AM
3031+ pr_err("%pd(%s), unsupported namelen %ld\n",
3032+ au_br_dentry(br),
86dc4139 3033+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen);
1facf9fc 3034+
4f0767ce 3035+out:
1facf9fc 3036+ return err;
3037+}
3038+
c1595e42 3039+/* initialize a new branch */
1facf9fc 3040+static int au_br_init(struct au_branch *br, struct super_block *sb,
3041+ struct au_opt_add *add)
3042+{
3043+ int err;
3044+
3045+ err = 0;
3046+ memset(&br->br_xino, 0, sizeof(br->br_xino));
3047+ mutex_init(&br->br_xino.xi_nondir_mtx);
3048+ br->br_perm = add->perm;
86dc4139 3049+ br->br_path = add->path; /* set first, path_get() later */
4a4d8108
AM
3050+ spin_lock_init(&br->br_dykey_lock);
3051+ memset(br->br_dykey, 0, sizeof(br->br_dykey));
1facf9fc 3052+ atomic_set(&br->br_count, 0);
1facf9fc 3053+ atomic_set(&br->br_xino_running, 0);
3054+ br->br_id = au_new_br_id(sb);
7f207e10 3055+ AuDebugOn(br->br_id < 0);
1facf9fc 3056+
3057+ if (au_br_writable(add->perm)) {
86dc4139 3058+ err = au_wbr_init(br, sb, add->perm);
1facf9fc 3059+ if (unlikely(err))
b752ccd1 3060+ goto out_err;
1facf9fc 3061+ }
3062+
3063+ if (au_opt_test(au_mntflags(sb), XINO)) {
3064+ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino,
3065+ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1);
3066+ if (unlikely(err)) {
3067+ AuDebugOn(br->br_xino.xi_file);
b752ccd1 3068+ goto out_err;
1facf9fc 3069+ }
3070+ }
3071+
3072+ sysaufs_br_init(br);
86dc4139 3073+ path_get(&br->br_path);
b752ccd1 3074+ goto out; /* success */
1facf9fc 3075+
4f0767ce 3076+out_err:
86dc4139 3077+ memset(&br->br_path, 0, sizeof(br->br_path));
4f0767ce 3078+out:
1facf9fc 3079+ return err;
3080+}
3081+
3082+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex,
3083+ struct au_branch *br, aufs_bindex_t bend,
3084+ aufs_bindex_t amount)
3085+{
3086+ struct au_branch **brp;
3087+
dece6358
AM
3088+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3089+
1facf9fc 3090+ brp = sbinfo->si_branch + bindex;
3091+ memmove(brp + 1, brp, sizeof(*brp) * amount);
3092+ *brp = br;
3093+ sbinfo->si_bend++;
3094+ if (unlikely(bend < 0))
3095+ sbinfo->si_bend = 0;
3096+}
3097+
3098+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
3099+ aufs_bindex_t bend, aufs_bindex_t amount)
3100+{
3101+ struct au_hdentry *hdp;
3102+
1308ab2a 3103+ AuRwMustWriteLock(&dinfo->di_rwsem);
3104+
1facf9fc 3105+ hdp = dinfo->di_hdentry + bindex;
3106+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
3107+ au_h_dentry_init(hdp);
3108+ dinfo->di_bend++;
3109+ if (unlikely(bend < 0))
3110+ dinfo->di_bstart = 0;
3111+}
3112+
3113+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex,
3114+ aufs_bindex_t bend, aufs_bindex_t amount)
3115+{
3116+ struct au_hinode *hip;
3117+
1308ab2a 3118+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3119+
1facf9fc 3120+ hip = iinfo->ii_hinode + bindex;
3121+ memmove(hip + 1, hip, sizeof(*hip) * amount);
3122+ hip->hi_inode = NULL;
4a4d8108 3123+ au_hn_init(hip);
1facf9fc 3124+ iinfo->ii_bend++;
3125+ if (unlikely(bend < 0))
3126+ iinfo->ii_bstart = 0;
3127+}
3128+
86dc4139
AM
3129+static void au_br_do_add(struct super_block *sb, struct au_branch *br,
3130+ aufs_bindex_t bindex)
1facf9fc 3131+{
86dc4139 3132+ struct dentry *root, *h_dentry;
1facf9fc 3133+ struct inode *root_inode;
3134+ aufs_bindex_t bend, amount;
3135+
3136+ root = sb->s_root;
3137+ root_inode = root->d_inode;
1facf9fc 3138+ bend = au_sbend(sb);
3139+ amount = bend + 1 - bindex;
86dc4139 3140+ h_dentry = au_br_dentry(br);
53392da6 3141+ au_sbilist_lock();
1facf9fc 3142+ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount);
3143+ au_br_do_add_hdp(au_di(root), bindex, bend, amount);
3144+ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount);
3145+ au_set_h_dptr(root, bindex, dget(h_dentry));
3146+ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode),
3147+ /*flags*/0);
53392da6 3148+ au_sbilist_unlock();
1facf9fc 3149+}
3150+
3151+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount)
3152+{
3153+ int err;
1facf9fc 3154+ aufs_bindex_t bend, add_bindex;
3155+ struct dentry *root, *h_dentry;
3156+ struct inode *root_inode;
3157+ struct au_branch *add_branch;
3158+
3159+ root = sb->s_root;
3160+ root_inode = root->d_inode;
3161+ IMustLock(root_inode);
3162+ err = test_add(sb, add, remount);
3163+ if (unlikely(err < 0))
3164+ goto out;
3165+ if (err) {
3166+ err = 0;
3167+ goto out; /* success */
3168+ }
3169+
3170+ bend = au_sbend(sb);
3171+ add_branch = au_br_alloc(sb, bend + 2, add->perm);
3172+ err = PTR_ERR(add_branch);
3173+ if (IS_ERR(add_branch))
3174+ goto out;
3175+
3176+ err = au_br_init(add_branch, sb, add);
3177+ if (unlikely(err)) {
3178+ au_br_do_free(add_branch);
3179+ goto out;
3180+ }
3181+
3182+ add_bindex = add->bindex;
1facf9fc 3183+ if (!remount)
86dc4139 3184+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3185+ else {
3186+ sysaufs_brs_del(sb, add_bindex);
86dc4139 3187+ au_br_do_add(sb, add_branch, add_bindex);
1facf9fc 3188+ sysaufs_brs_add(sb, add_bindex);
3189+ }
3190+
86dc4139 3191+ h_dentry = add->path.dentry;
1308ab2a 3192+ if (!add_bindex) {
1facf9fc 3193+ au_cpup_attr_all(root_inode, /*force*/1);
1308ab2a 3194+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes;
3195+ } else
1facf9fc 3196+ au_add_nlink(root_inode, h_dentry->d_inode);
1facf9fc 3197+
3198+ /*
4a4d8108 3199+ * this test/set prevents aufs from handling unnecesary notify events
027c5e7a 3200+ * of xino files, in case of re-adding a writable branch which was
1facf9fc 3201+ * once detached from aufs.
3202+ */
3203+ if (au_xino_brid(sb) < 0
3204+ && au_br_writable(add_branch->br_perm)
3205+ && !au_test_fs_bad_xino(h_dentry->d_sb)
3206+ && add_branch->br_xino.xi_file
3207+ && add_branch->br_xino.xi_file->f_dentry->d_parent == h_dentry)
3208+ au_xino_brid_set(sb, add_branch->br_id);
3209+
4f0767ce 3210+out:
1facf9fc 3211+ return err;
3212+}
3213+
3214+/* ---------------------------------------------------------------------- */
3215+
076b876e
AM
3216+static unsigned long long au_farray_cb(void *a,
3217+ unsigned long long max __maybe_unused,
3218+ void *arg)
3219+{
3220+ unsigned long long n;
3221+ struct file **p, *f;
3222+ struct au_sphlhead *files;
3223+ struct au_finfo *finfo;
3224+ struct super_block *sb = arg;
3225+
3226+ n = 0;
3227+ p = a;
3228+ files = &au_sbi(sb)->si_files;
3229+ spin_lock(&files->spin);
3230+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
3231+ f = finfo->fi_file;
3232+ if (file_count(f)
3233+ && !special_file(file_inode(f)->i_mode)) {
3234+ get_file(f);
3235+ *p++ = f;
3236+ n++;
3237+ AuDebugOn(n > max);
3238+ }
3239+ }
3240+ spin_unlock(&files->spin);
3241+
3242+ return n;
3243+}
3244+
3245+static struct file **au_farray_alloc(struct super_block *sb,
3246+ unsigned long long *max)
3247+{
3248+ *max = atomic_long_read(&au_sbi(sb)->si_nfiles);
3249+ return au_array_alloc(max, au_farray_cb, sb);
3250+}
3251+
3252+static void au_farray_free(struct file **a, unsigned long long max)
3253+{
3254+ unsigned long long ull;
3255+
3256+ for (ull = 0; ull < max; ull++)
3257+ if (a[ull])
3258+ fput(a[ull]);
3259+ au_array_free(a);
3260+}
3261+
3262+/* ---------------------------------------------------------------------- */
3263+
1facf9fc 3264+/*
3265+ * delete a branch
3266+ */
3267+
3268+/* to show the line number, do not make it inlined function */
4a4d8108 3269+#define AuVerbose(do_info, fmt, ...) do { \
1facf9fc 3270+ if (do_info) \
4a4d8108 3271+ pr_info(fmt, ##__VA_ARGS__); \
1facf9fc 3272+} while (0)
3273+
027c5e7a
AM
3274+static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart,
3275+ aufs_bindex_t bend)
3276+{
3277+ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend;
3278+}
3279+
3280+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart,
3281+ aufs_bindex_t bend)
3282+{
3283+ return au_test_ibusy(dentry->d_inode, bstart, bend);
3284+}
3285+
1facf9fc 3286+/*
3287+ * test if the branch is deletable or not.
3288+ */
3289+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
b752ccd1 3290+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3291+{
3292+ int err, i, j, ndentry;
3293+ aufs_bindex_t bstart, bend;
1facf9fc 3294+ struct au_dcsub_pages dpages;
3295+ struct au_dpage *dpage;
3296+ struct dentry *d;
1facf9fc 3297+
3298+ err = au_dpages_init(&dpages, GFP_NOFS);
3299+ if (unlikely(err))
3300+ goto out;
3301+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
3302+ if (unlikely(err))
3303+ goto out_dpages;
3304+
1facf9fc 3305+ for (i = 0; !err && i < dpages.ndpage; i++) {
3306+ dpage = dpages.dpages + i;
3307+ ndentry = dpage->ndentry;
3308+ for (j = 0; !err && j < ndentry; j++) {
3309+ d = dpage->dentries[j];
c1595e42 3310+ AuDebugOn(au_dcount(d) <= 0);
027c5e7a 3311+ if (!au_digen_test(d, sigen)) {
1facf9fc 3312+ di_read_lock_child(d, AuLock_IR);
027c5e7a
AM
3313+ if (unlikely(au_dbrange_test(d))) {
3314+ di_read_unlock(d, AuLock_IR);
3315+ continue;
3316+ }
3317+ } else {
1facf9fc 3318+ di_write_lock_child(d);
027c5e7a
AM
3319+ if (unlikely(au_dbrange_test(d))) {
3320+ di_write_unlock(d);
3321+ continue;
3322+ }
1facf9fc 3323+ err = au_reval_dpath(d, sigen);
3324+ if (!err)
3325+ di_downgrade_lock(d, AuLock_IR);
3326+ else {
3327+ di_write_unlock(d);
3328+ break;
3329+ }
3330+ }
3331+
027c5e7a 3332+ /* AuDbgDentry(d); */
1facf9fc 3333+ bstart = au_dbstart(d);
3334+ bend = au_dbend(d);
3335+ if (bstart <= bindex
3336+ && bindex <= bend
3337+ && au_h_dptr(d, bindex)
027c5e7a 3338+ && au_test_dbusy(d, bstart, bend)) {
1facf9fc 3339+ err = -EBUSY;
523b37e3 3340+ AuVerbose(verbose, "busy %pd\n", d);
027c5e7a 3341+ AuDbgDentry(d);
1facf9fc 3342+ }
3343+ di_read_unlock(d, AuLock_IR);
3344+ }
3345+ }
3346+
4f0767ce 3347+out_dpages:
1facf9fc 3348+ au_dpages_free(&dpages);
4f0767ce 3349+out:
1facf9fc 3350+ return err;
3351+}
3352+
3353+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
b752ccd1 3354+ unsigned int sigen, const unsigned int verbose)
1facf9fc 3355+{
3356+ int err;
7f207e10
AM
3357+ unsigned long long max, ull;
3358+ struct inode *i, **array;
1facf9fc 3359+ aufs_bindex_t bstart, bend;
1facf9fc 3360+
7f207e10
AM
3361+ array = au_iarray_alloc(sb, &max);
3362+ err = PTR_ERR(array);
3363+ if (IS_ERR(array))
3364+ goto out;
3365+
1facf9fc 3366+ err = 0;
7f207e10
AM
3367+ AuDbg("b%d\n", bindex);
3368+ for (ull = 0; !err && ull < max; ull++) {
3369+ i = array[ull];
076b876e
AM
3370+ if (unlikely(!i))
3371+ break;
7f207e10 3372+ if (i->i_ino == AUFS_ROOT_INO)
1facf9fc 3373+ continue;
3374+
7f207e10 3375+ /* AuDbgInode(i); */
537831f9 3376+ if (au_iigen(i, NULL) == sigen)
1facf9fc 3377+ ii_read_lock_child(i);
3378+ else {
3379+ ii_write_lock_child(i);
027c5e7a
AM
3380+ err = au_refresh_hinode_self(i);
3381+ au_iigen_dec(i);
1facf9fc 3382+ if (!err)
3383+ ii_downgrade_lock(i);
3384+ else {
3385+ ii_write_unlock(i);
3386+ break;
3387+ }
3388+ }
3389+
3390+ bstart = au_ibstart(i);
3391+ bend = au_ibend(i);
3392+ if (bstart <= bindex
3393+ && bindex <= bend
3394+ && au_h_iptr(i, bindex)
027c5e7a 3395+ && au_test_ibusy(i, bstart, bend)) {
1facf9fc 3396+ err = -EBUSY;
3397+ AuVerbose(verbose, "busy i%lu\n", i->i_ino);
7f207e10 3398+ AuDbgInode(i);
1facf9fc 3399+ }
3400+ ii_read_unlock(i);
3401+ }
7f207e10 3402+ au_iarray_free(array, max);
1facf9fc 3403+
7f207e10 3404+out:
1facf9fc 3405+ return err;
3406+}
3407+
b752ccd1
AM
3408+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex,
3409+ const unsigned int verbose)
1facf9fc 3410+{
3411+ int err;
3412+ unsigned int sigen;
3413+
3414+ sigen = au_sigen(root->d_sb);
3415+ DiMustNoWaiters(root);
3416+ IiMustNoWaiters(root->d_inode);
3417+ di_write_unlock(root);
b752ccd1 3418+ err = test_dentry_busy(root, bindex, sigen, verbose);
1facf9fc 3419+ if (!err)
b752ccd1 3420+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose);
1facf9fc 3421+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */
3422+
3423+ return err;
3424+}
3425+
076b876e
AM
3426+static int test_dir_busy(struct file *file, aufs_bindex_t br_id,
3427+ struct file **to_free, int *idx)
3428+{
3429+ int err;
c1595e42 3430+ unsigned char matched, root;
076b876e
AM
3431+ aufs_bindex_t bindex, bend;
3432+ struct au_fidir *fidir;
3433+ struct au_hfile *hfile;
3434+
3435+ err = 0;
c1595e42
JR
3436+ root = IS_ROOT(file->f_dentry);
3437+ if (root) {
3438+ get_file(file);
3439+ to_free[*idx] = file;
3440+ (*idx)++;
3441+ goto out;
3442+ }
3443+
076b876e 3444+ matched = 0;
076b876e
AM
3445+ fidir = au_fi(file)->fi_hdir;
3446+ AuDebugOn(!fidir);
3447+ bend = au_fbend_dir(file);
3448+ for (bindex = au_fbstart(file); bindex <= bend; bindex++) {
3449+ hfile = fidir->fd_hfile + bindex;
3450+ if (!hfile->hf_file)
3451+ continue;
3452+
c1595e42 3453+ if (hfile->hf_br->br_id == br_id) {
076b876e 3454+ matched = 1;
076b876e 3455+ break;
c1595e42 3456+ }
076b876e 3457+ }
c1595e42 3458+ if (matched)
076b876e
AM
3459+ err = -EBUSY;
3460+
3461+out:
3462+ return err;
3463+}
3464+
3465+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id,
3466+ struct file **to_free, int opened)
3467+{
3468+ int err, idx;
3469+ unsigned long long ull, max;
3470+ aufs_bindex_t bstart;
3471+ struct file *file, **array;
3472+ struct inode *inode;
3473+ struct dentry *root;
3474+ struct au_hfile *hfile;
3475+
3476+ array = au_farray_alloc(sb, &max);
3477+ err = PTR_ERR(array);
3478+ if (IS_ERR(array))
3479+ goto out;
3480+
3481+ err = 0;
3482+ idx = 0;
3483+ root = sb->s_root;
3484+ di_write_unlock(root);
3485+ for (ull = 0; ull < max; ull++) {
3486+ file = array[ull];
3487+ if (unlikely(!file))
3488+ break;
3489+
3490+ /* AuDbg("%pD\n", file); */
3491+ fi_read_lock(file);
3492+ bstart = au_fbstart(file);
3493+ inode = file_inode(file);
3494+ if (!S_ISDIR(inode->i_mode)) {
3495+ hfile = &au_fi(file)->fi_htop;
3496+ if (hfile->hf_br->br_id == br_id)
3497+ err = -EBUSY;
3498+ } else
3499+ err = test_dir_busy(file, br_id, to_free, &idx);
3500+ fi_read_unlock(file);
3501+ if (unlikely(err))
3502+ break;
3503+ }
3504+ di_write_lock_child(root);
3505+ au_farray_free(array, max);
3506+ AuDebugOn(idx > opened);
3507+
3508+out:
3509+ return err;
3510+}
3511+
3512+static void br_del_file(struct file **to_free, unsigned long long opened,
3513+ aufs_bindex_t br_id)
3514+{
3515+ unsigned long long ull;
3516+ aufs_bindex_t bindex, bstart, bend, bfound;
3517+ struct file *file;
3518+ struct au_fidir *fidir;
3519+ struct au_hfile *hfile;
3520+
3521+ for (ull = 0; ull < opened; ull++) {
3522+ file = to_free[ull];
3523+ if (unlikely(!file))
3524+ break;
3525+
3526+ /* AuDbg("%pD\n", file); */
3527+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
3528+ bfound = -1;
3529+ fidir = au_fi(file)->fi_hdir;
3530+ AuDebugOn(!fidir);
3531+ fi_write_lock(file);
3532+ bstart = au_fbstart(file);
3533+ bend = au_fbend_dir(file);
3534+ for (bindex = bstart; bindex <= bend; bindex++) {
3535+ hfile = fidir->fd_hfile + bindex;
3536+ if (!hfile->hf_file)
3537+ continue;
3538+
3539+ if (hfile->hf_br->br_id == br_id) {
3540+ bfound = bindex;
3541+ break;
3542+ }
3543+ }
3544+ AuDebugOn(bfound < 0);
3545+ au_set_h_fptr(file, bfound, NULL);
3546+ if (bfound == bstart) {
3547+ for (bstart++; bstart <= bend; bstart++)
3548+ if (au_hf_dir(file, bstart)) {
3549+ au_set_fbstart(file, bstart);
3550+ break;
3551+ }
3552+ }
3553+ fi_write_unlock(file);
3554+ }
3555+}
3556+
1facf9fc 3557+static void au_br_do_del_brp(struct au_sbinfo *sbinfo,
3558+ const aufs_bindex_t bindex,
3559+ const aufs_bindex_t bend)
3560+{
3561+ struct au_branch **brp, **p;
3562+
dece6358
AM
3563+ AuRwMustWriteLock(&sbinfo->si_rwsem);
3564+
1facf9fc 3565+ brp = sbinfo->si_branch + bindex;
3566+ if (bindex < bend)
3567+ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex));
3568+ sbinfo->si_branch[0 + bend] = NULL;
3569+ sbinfo->si_bend--;
3570+
53392da6 3571+ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3572+ if (p)
3573+ sbinfo->si_branch = p;
4a4d8108 3574+ /* harmless error */
1facf9fc 3575+}
3576+
3577+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
3578+ const aufs_bindex_t bend)
3579+{
3580+ struct au_hdentry *hdp, *p;
3581+
1308ab2a 3582+ AuRwMustWriteLock(&dinfo->di_rwsem);
3583+
4a4d8108 3584+ hdp = dinfo->di_hdentry;
1facf9fc 3585+ if (bindex < bend)
4a4d8108
AM
3586+ memmove(hdp + bindex, hdp + bindex + 1,
3587+ sizeof(*hdp) * (bend - bindex));
3588+ hdp[0 + bend].hd_dentry = NULL;
1facf9fc 3589+ dinfo->di_bend--;
3590+
53392da6 3591+ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3592+ if (p)
3593+ dinfo->di_hdentry = p;
4a4d8108 3594+ /* harmless error */
1facf9fc 3595+}
3596+
3597+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex,
3598+ const aufs_bindex_t bend)
3599+{
3600+ struct au_hinode *hip, *p;
3601+
1308ab2a 3602+ AuRwMustWriteLock(&iinfo->ii_rwsem);
3603+
1facf9fc 3604+ hip = iinfo->ii_hinode + bindex;
3605+ if (bindex < bend)
3606+ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex));
3607+ iinfo->ii_hinode[0 + bend].hi_inode = NULL;
4a4d8108 3608+ au_hn_init(iinfo->ii_hinode + bend);
1facf9fc 3609+ iinfo->ii_bend--;
3610+
53392da6 3611+ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST);
1facf9fc 3612+ if (p)
3613+ iinfo->ii_hinode = p;
4a4d8108 3614+ /* harmless error */
1facf9fc 3615+}
3616+
3617+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex,
3618+ struct au_branch *br)
3619+{
3620+ aufs_bindex_t bend;
3621+ struct au_sbinfo *sbinfo;
53392da6
AM
3622+ struct dentry *root, *h_root;
3623+ struct inode *inode, *h_inode;
3624+ struct au_hinode *hinode;
1facf9fc 3625+
dece6358
AM
3626+ SiMustWriteLock(sb);
3627+
1facf9fc 3628+ root = sb->s_root;
3629+ inode = root->d_inode;
1facf9fc 3630+ sbinfo = au_sbi(sb);
3631+ bend = sbinfo->si_bend;
3632+
53392da6
AM
3633+ h_root = au_h_dptr(root, bindex);
3634+ hinode = au_hi(inode, bindex);
3635+ h_inode = au_igrab(hinode->hi_inode);
3636+ au_hiput(hinode);
1facf9fc 3637+
53392da6 3638+ au_sbilist_lock();
1facf9fc 3639+ au_br_do_del_brp(sbinfo, bindex, bend);
3640+ au_br_do_del_hdp(au_di(root), bindex, bend);
3641+ au_br_do_del_hip(au_ii(inode), bindex, bend);
53392da6
AM
3642+ au_sbilist_unlock();
3643+
3644+ dput(h_root);
3645+ iput(h_inode);
3646+ au_br_do_free(br);
1facf9fc 3647+}
3648+
076b876e
AM
3649+static unsigned long long empty_cb(void *array, unsigned long long max,
3650+ void *arg)
3651+{
3652+ return max;
3653+}
3654+
1facf9fc 3655+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount)
3656+{
3657+ int err, rerr, i;
076b876e 3658+ unsigned long long opened;
1facf9fc 3659+ unsigned int mnt_flags;
3660+ aufs_bindex_t bindex, bend, br_id;
3661+ unsigned char do_wh, verbose;
3662+ struct au_branch *br;
3663+ struct au_wbr *wbr;
076b876e
AM
3664+ struct dentry *root;
3665+ struct file **to_free;
1facf9fc 3666+
3667+ err = 0;
076b876e
AM
3668+ opened = 0;
3669+ to_free = NULL;
3670+ root = sb->s_root;
3671+ bindex = au_find_dbindex(root, del->h_path.dentry);
1facf9fc 3672+ if (bindex < 0) {
3673+ if (remount)
3674+ goto out; /* success */
3675+ err = -ENOENT;
4a4d8108 3676+ pr_err("%s no such branch\n", del->pathname);
1facf9fc 3677+ goto out;
3678+ }
3679+ AuDbg("bindex b%d\n", bindex);
3680+
3681+ err = -EBUSY;
3682+ mnt_flags = au_mntflags(sb);
3683+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3684+ bend = au_sbend(sb);
3685+ if (unlikely(!bend)) {
3686+ AuVerbose(verbose, "no more branches left\n");
3687+ goto out;
3688+ }
3689+ br = au_sbr(sb, bindex);
86dc4139 3690+ AuDebugOn(!path_equal(&br->br_path, &del->h_path));
076b876e
AM
3691+
3692+ br_id = br->br_id;
3693+ opened = atomic_read(&br->br_count);
3694+ if (unlikely(opened)) {
3695+ to_free = au_array_alloc(&opened, empty_cb, NULL);
3696+ err = PTR_ERR(to_free);
3697+ if (IS_ERR(to_free))
3698+ goto out;
3699+
3700+ err = test_file_busy(sb, br_id, to_free, opened);
3701+ if (unlikely(err)) {
3702+ AuVerbose(verbose, "%llu file(s) opened\n", opened);
3703+ goto out;
3704+ }
1facf9fc 3705+ }
3706+
3707+ wbr = br->br_wbr;
3708+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph);
3709+ if (do_wh) {
1308ab2a 3710+ /* instead of WbrWhMustWriteLock(wbr) */
3711+ SiMustWriteLock(sb);
1facf9fc 3712+ for (i = 0; i < AuBrWh_Last; i++) {
3713+ dput(wbr->wbr_wh[i]);
3714+ wbr->wbr_wh[i] = NULL;
3715+ }
3716+ }
3717+
076b876e 3718+ err = test_children_busy(root, bindex, verbose);
1facf9fc 3719+ if (unlikely(err)) {
3720+ if (do_wh)
3721+ goto out_wh;
3722+ goto out;
3723+ }
3724+
3725+ err = 0;
076b876e
AM
3726+ if (to_free) {
3727+ /*
3728+ * now we confirmed the branch is deletable.
3729+ * let's free the remaining opened dirs on the branch.
3730+ */
3731+ di_write_unlock(root);
3732+ br_del_file(to_free, opened, br_id);
3733+ di_write_lock_child(root);
3734+ }
3735+
1facf9fc 3736+ if (!remount)
3737+ au_br_do_del(sb, bindex, br);
3738+ else {
3739+ sysaufs_brs_del(sb, bindex);
3740+ au_br_do_del(sb, bindex, br);
3741+ sysaufs_brs_add(sb, bindex);
3742+ }
3743+
1308ab2a 3744+ if (!bindex) {
076b876e 3745+ au_cpup_attr_all(root->d_inode, /*force*/1);
1308ab2a 3746+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes;
3747+ } else
076b876e 3748+ au_sub_nlink(root->d_inode, del->h_path.dentry->d_inode);
1facf9fc 3749+ if (au_opt_test(mnt_flags, PLINK))
3750+ au_plink_half_refresh(sb, br_id);
3751+
b752ccd1 3752+ if (au_xino_brid(sb) == br_id)
1facf9fc 3753+ au_xino_brid_set(sb, -1);
3754+ goto out; /* success */
3755+
4f0767ce 3756+out_wh:
1facf9fc 3757+ /* revert */
86dc4139 3758+ rerr = au_br_init_wh(sb, br, br->br_perm);
1facf9fc 3759+ if (rerr)
0c3ec466
AM
3760+ pr_warn("failed re-creating base whiteout, %s. (%d)\n",
3761+ del->pathname, rerr);
4f0767ce 3762+out:
076b876e
AM
3763+ if (to_free)
3764+ au_farray_free(to_free, opened);
1facf9fc 3765+ return err;
3766+}
3767+
3768+/* ---------------------------------------------------------------------- */
3769+
027c5e7a
AM
3770+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
3771+{
3772+ int err;
3773+ aufs_bindex_t bstart, bend;
3774+ struct aufs_ibusy ibusy;
3775+ struct inode *inode, *h_inode;
3776+
3777+ err = -EPERM;
3778+ if (unlikely(!capable(CAP_SYS_ADMIN)))
3779+ goto out;
3780+
3781+ err = copy_from_user(&ibusy, arg, sizeof(ibusy));
3782+ if (!err)
3783+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino));
3784+ if (unlikely(err)) {
3785+ err = -EFAULT;
3786+ AuTraceErr(err);
3787+ goto out;
3788+ }
3789+
3790+ err = -EINVAL;
3791+ si_read_lock(sb, AuLock_FLUSH);
3792+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb)))
3793+ goto out_unlock;
3794+
3795+ err = 0;
3796+ ibusy.h_ino = 0; /* invalid */
3797+ inode = ilookup(sb, ibusy.ino);
3798+ if (!inode
3799+ || inode->i_ino == AUFS_ROOT_INO
3800+ || is_bad_inode(inode))
3801+ goto out_unlock;
3802+
3803+ ii_read_lock_child(inode);
3804+ bstart = au_ibstart(inode);
3805+ bend = au_ibend(inode);
3806+ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) {
3807+ h_inode = au_h_iptr(inode, ibusy.bindex);
3808+ if (h_inode && au_test_ibusy(inode, bstart, bend))
3809+ ibusy.h_ino = h_inode->i_ino;
3810+ }
3811+ ii_read_unlock(inode);
3812+ iput(inode);
3813+
3814+out_unlock:
3815+ si_read_unlock(sb);
3816+ if (!err) {
3817+ err = __put_user(ibusy.h_ino, &arg->h_ino);
3818+ if (unlikely(err)) {
3819+ err = -EFAULT;
3820+ AuTraceErr(err);
3821+ }
3822+ }
3823+out:
3824+ return err;
3825+}
3826+
3827+long au_ibusy_ioctl(struct file *file, unsigned long arg)
3828+{
3829+ return au_ibusy(file->f_dentry->d_sb, (void __user *)arg);
3830+}
3831+
3832+#ifdef CONFIG_COMPAT
3833+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg)
3834+{
3835+ return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg));
3836+}
3837+#endif
3838+
3839+/* ---------------------------------------------------------------------- */
3840+
1facf9fc 3841+/*
3842+ * change a branch permission
3843+ */
3844+
dece6358
AM
3845+static void au_warn_ima(void)
3846+{
3847+#ifdef CONFIG_IMA
1308ab2a 3848+ /* since it doesn't support mark_files_ro() */
027c5e7a 3849+ AuWarn1("RW -> RO makes IMA to produce wrong message\n");
dece6358
AM
3850+#endif
3851+}
3852+
1facf9fc 3853+static int do_need_sigen_inc(int a, int b)
3854+{
3855+ return au_br_whable(a) && !au_br_whable(b);
3856+}
3857+
3858+static int need_sigen_inc(int old, int new)
3859+{
3860+ return do_need_sigen_inc(old, new)
3861+ || do_need_sigen_inc(new, old);
3862+}
3863+
3864+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
3865+{
7f207e10 3866+ int err, do_warn;
027c5e7a 3867+ unsigned int mnt_flags;
7f207e10 3868+ unsigned long long ull, max;
e49829fe 3869+ aufs_bindex_t br_id;
38d290e6 3870+ unsigned char verbose, writer;
7f207e10 3871+ struct file *file, *hf, **array;
e49829fe
JR
3872+ struct inode *inode;
3873+ struct au_hfile *hfile;
1facf9fc 3874+
027c5e7a
AM
3875+ mnt_flags = au_mntflags(sb);
3876+ verbose = !!au_opt_test(mnt_flags, VERBOSE);
3877+
7f207e10
AM
3878+ array = au_farray_alloc(sb, &max);
3879+ err = PTR_ERR(array);
3880+ if (IS_ERR(array))
1facf9fc 3881+ goto out;
3882+
7f207e10 3883+ do_warn = 0;
e49829fe 3884+ br_id = au_sbr_id(sb, bindex);
7f207e10
AM
3885+ for (ull = 0; ull < max; ull++) {
3886+ file = array[ull];
076b876e
AM
3887+ if (unlikely(!file))
3888+ break;
1facf9fc 3889+
523b37e3 3890+ /* AuDbg("%pD\n", file); */
1facf9fc 3891+ fi_read_lock(file);
3892+ if (unlikely(au_test_mmapped(file))) {
3893+ err = -EBUSY;
523b37e3 3894+ AuVerbose(verbose, "mmapped %pD\n", file);
7f207e10 3895+ AuDbgFile(file);
1facf9fc 3896+ FiMustNoWaiters(file);
3897+ fi_read_unlock(file);
7f207e10 3898+ goto out_array;
1facf9fc 3899+ }
3900+
c06a8ce3 3901+ inode = file_inode(file);
e49829fe
JR
3902+ hfile = &au_fi(file)->fi_htop;
3903+ hf = hfile->hf_file;
3904+ if (!S_ISREG(inode->i_mode)
1facf9fc 3905+ || !(file->f_mode & FMODE_WRITE)
e49829fe 3906+ || hfile->hf_br->br_id != br_id
7f207e10
AM
3907+ || !(hf->f_mode & FMODE_WRITE))
3908+ array[ull] = NULL;
3909+ else {
3910+ do_warn = 1;
3911+ get_file(file);
1facf9fc 3912+ }
3913+
1facf9fc 3914+ FiMustNoWaiters(file);
3915+ fi_read_unlock(file);
7f207e10
AM
3916+ fput(file);
3917+ }
1facf9fc 3918+
3919+ err = 0;
7f207e10 3920+ if (do_warn)
dece6358 3921+ au_warn_ima();
7f207e10
AM
3922+
3923+ for (ull = 0; ull < max; ull++) {
3924+ file = array[ull];
3925+ if (!file)
3926+ continue;
3927+
1facf9fc 3928+ /* todo: already flushed? */
523b37e3
AM
3929+ /*
3930+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its
3931+ * approach which resets f_mode and calls mnt_drop_write() and
3932+ * file_release_write() for each file, because the branch
3933+ * attribute in aufs world is totally different from the native
3934+ * fs rw/ro mode.
3935+ */
7f207e10
AM
3936+ /* fi_read_lock(file); */
3937+ hfile = &au_fi(file)->fi_htop;
3938+ hf = hfile->hf_file;
3939+ /* fi_read_unlock(file); */
027c5e7a 3940+ spin_lock(&hf->f_lock);
38d290e6
JR
3941+ writer = !!(hf->f_mode & FMODE_WRITER);
3942+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER);
027c5e7a 3943+ spin_unlock(&hf->f_lock);
38d290e6
JR
3944+ if (writer) {
3945+ put_write_access(file_inode(hf));
c06a8ce3 3946+ __mnt_drop_write(hf->f_path.mnt);
1facf9fc 3947+ }
3948+ }
3949+
7f207e10
AM
3950+out_array:
3951+ au_farray_free(array, max);
4f0767ce 3952+out:
7f207e10 3953+ AuTraceErr(err);
1facf9fc 3954+ return err;
3955+}
3956+
3957+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 3958+ int *do_refresh)
1facf9fc 3959+{
3960+ int err, rerr;
3961+ aufs_bindex_t bindex;
3962+ struct dentry *root;
3963+ struct au_branch *br;
076b876e 3964+ struct au_br_fhsm *bf;
1facf9fc 3965+
3966+ root = sb->s_root;
1facf9fc 3967+ bindex = au_find_dbindex(root, mod->h_root);
3968+ if (bindex < 0) {
3969+ if (remount)
3970+ return 0; /* success */
3971+ err = -ENOENT;
4a4d8108 3972+ pr_err("%s no such branch\n", mod->path);
1facf9fc 3973+ goto out;
3974+ }
3975+ AuDbg("bindex b%d\n", bindex);
3976+
3977+ err = test_br(mod->h_root->d_inode, mod->perm, mod->path);
3978+ if (unlikely(err))
3979+ goto out;
3980+
3981+ br = au_sbr(sb, bindex);
86dc4139 3982+ AuDebugOn(mod->h_root != au_br_dentry(br));
1facf9fc 3983+ if (br->br_perm == mod->perm)
3984+ return 0; /* success */
3985+
076b876e
AM
3986+ /* pre-allocate for non-fhsm --> fhsm */
3987+ bf = NULL;
3988+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) {
3989+ err = au_fhsm_br_alloc(br);
3990+ if (unlikely(err))
3991+ goto out;
3992+ bf = br->br_fhsm;
3993+ br->br_fhsm = NULL;
3994+ }
3995+
1facf9fc 3996+ if (au_br_writable(br->br_perm)) {
3997+ /* remove whiteout base */
86dc4139 3998+ err = au_br_init_wh(sb, br, mod->perm);
1facf9fc 3999+ if (unlikely(err))
076b876e 4000+ goto out_bf;
1facf9fc 4001+
4002+ if (!au_br_writable(mod->perm)) {
4003+ /* rw --> ro, file might be mmapped */
4004+ DiMustNoWaiters(root);
4005+ IiMustNoWaiters(root->d_inode);
4006+ di_write_unlock(root);
4007+ err = au_br_mod_files_ro(sb, bindex);
4008+ /* aufs_write_lock() calls ..._child() */
4009+ di_write_lock_child(root);
4010+
4011+ if (unlikely(err)) {
4012+ rerr = -ENOMEM;
4013+ br->br_wbr = kmalloc(sizeof(*br->br_wbr),
4014+ GFP_NOFS);
86dc4139
AM
4015+ if (br->br_wbr)
4016+ rerr = au_wbr_init(br, sb, br->br_perm);
1facf9fc 4017+ if (unlikely(rerr)) {
4018+ AuIOErr("nested error %d (%d)\n",
4019+ rerr, err);
4020+ br->br_perm = mod->perm;
4021+ }
4022+ }
4023+ }
4024+ } else if (au_br_writable(mod->perm)) {
4025+ /* ro --> rw */
4026+ err = -ENOMEM;
4027+ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS);
4028+ if (br->br_wbr) {
86dc4139 4029+ err = au_wbr_init(br, sb, mod->perm);
1facf9fc 4030+ if (unlikely(err)) {
4031+ kfree(br->br_wbr);
4032+ br->br_wbr = NULL;
4033+ }
4034+ }
4035+ }
076b876e
AM
4036+ if (unlikely(err))
4037+ goto out_bf;
4038+
4039+ if (au_br_fhsm(br->br_perm)) {
4040+ if (!au_br_fhsm(mod->perm)) {
4041+ /* fhsm --> non-fhsm */
4042+ au_br_fhsm_fin(br->br_fhsm);
4043+ kfree(br->br_fhsm);
4044+ br->br_fhsm = NULL;
4045+ }
4046+ } else if (au_br_fhsm(mod->perm))
4047+ /* non-fhsm --> fhsm */
4048+ br->br_fhsm = bf;
4049+
076b876e
AM
4050+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm);
4051+ br->br_perm = mod->perm;
4052+ goto out; /* success */
1facf9fc 4053+
076b876e
AM
4054+out_bf:
4055+ kfree(bf);
4056+out:
4057+ AuTraceErr(err);
4058+ return err;
4059+}
4060+
4061+/* ---------------------------------------------------------------------- */
4062+
4063+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs)
4064+{
4065+ int err;
4066+ struct kstatfs kstfs;
4067+
4068+ err = vfs_statfs(&br->br_path, &kstfs);
1facf9fc 4069+ if (!err) {
076b876e
AM
4070+ stfs->f_blocks = kstfs.f_blocks;
4071+ stfs->f_bavail = kstfs.f_bavail;
4072+ stfs->f_files = kstfs.f_files;
4073+ stfs->f_ffree = kstfs.f_ffree;
1facf9fc 4074+ }
4075+
1facf9fc 4076+ return err;
4077+}
7f207e10
AM
4078diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h
4079--- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
4080+++ linux/fs/aufs/branch.h 2015-01-25 13:00:38.627713742 +0100
4081@@ -0,0 +1,267 @@
1facf9fc 4082+/*
523b37e3 4083+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 4084+ *
4085+ * This program, aufs is free software; you can redistribute it and/or modify
4086+ * it under the terms of the GNU General Public License as published by
4087+ * the Free Software Foundation; either version 2 of the License, or
4088+ * (at your option) any later version.
dece6358
AM
4089+ *
4090+ * This program is distributed in the hope that it will be useful,
4091+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4092+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4093+ * GNU General Public License for more details.
4094+ *
4095+ * You should have received a copy of the GNU General Public License
523b37e3 4096+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4097+ */
4098+
4099+/*
4100+ * branch filesystems and xino for them
4101+ */
4102+
4103+#ifndef __AUFS_BRANCH_H__
4104+#define __AUFS_BRANCH_H__
4105+
4106+#ifdef __KERNEL__
4107+
1facf9fc 4108+#include <linux/mount.h>
4a4d8108 4109+#include "dynop.h"
1facf9fc 4110+#include "rwsem.h"
4111+#include "super.h"
4112+
4113+/* ---------------------------------------------------------------------- */
4114+
4115+/* a xino file */
4116+struct au_xino_file {
4117+ struct file *xi_file;
4118+ struct mutex xi_nondir_mtx;
4119+
4120+ /* todo: make xino files an array to support huge inode number */
4121+
4122+#ifdef CONFIG_DEBUG_FS
4123+ struct dentry *xi_dbgaufs;
4124+#endif
4125+};
4126+
076b876e
AM
4127+/* File-based Hierarchical Storage Management */
4128+struct au_br_fhsm {
4129+#ifdef CONFIG_AUFS_FHSM
4130+ struct mutex bf_lock;
4131+ unsigned long bf_jiffy;
4132+ struct aufs_stfs bf_stfs;
4133+ int bf_readable;
4134+#endif
4135+};
4136+
1facf9fc 4137+/* members for writable branch only */
4138+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last};
4139+struct au_wbr {
dece6358 4140+ struct au_rwsem wbr_wh_rwsem;
1facf9fc 4141+ struct dentry *wbr_wh[AuBrWh_Last];
4a4d8108 4142+ atomic_t wbr_wh_running;
1facf9fc 4143+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */
4144+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */
4145+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */
4146+
4147+ /* mfs mode */
4148+ unsigned long long wbr_bytes;
4149+};
4150+
4a4d8108
AM
4151+/* ext2 has 3 types of operations at least, ext3 has 4 */
4152+#define AuBrDynOp (AuDyLast * 4)
4153+
1716fcea
AM
4154+#ifdef CONFIG_AUFS_HFSNOTIFY
4155+/* support for asynchronous destruction */
4156+struct au_br_hfsnotify {
4157+ struct fsnotify_group *hfsn_group;
4158+};
4159+#endif
4160+
392086de
AM
4161+/* sysfs entries */
4162+struct au_brsysfs {
4163+ char name[16];
4164+ struct attribute attr;
4165+};
4166+
4167+enum {
4168+ AuBrSysfs_BR,
4169+ AuBrSysfs_BRID,
4170+ AuBrSysfs_Last
4171+};
4172+
1facf9fc 4173+/* protected by superblock rwsem */
4174+struct au_branch {
4175+ struct au_xino_file br_xino;
4176+
4177+ aufs_bindex_t br_id;
4178+
4179+ int br_perm;
86dc4139 4180+ struct path br_path;
4a4d8108
AM
4181+ spinlock_t br_dykey_lock;
4182+ struct au_dykey *br_dykey[AuBrDynOp];
1facf9fc 4183+ atomic_t br_count;
4184+
4185+ struct au_wbr *br_wbr;
076b876e 4186+ struct au_br_fhsm *br_fhsm;
1facf9fc 4187+
4188+ /* xino truncation */
1facf9fc 4189+ atomic_t br_xino_running;
4190+
027c5e7a 4191+#ifdef CONFIG_AUFS_HFSNOTIFY
1716fcea 4192+ struct au_br_hfsnotify *br_hfsn;
027c5e7a
AM
4193+#endif
4194+
1facf9fc 4195+#ifdef CONFIG_SYSFS
392086de
AM
4196+ /* entries under sysfs per mount-point */
4197+ struct au_brsysfs br_sysfs[AuBrSysfs_Last];
1facf9fc 4198+#endif
4199+};
4200+
4201+/* ---------------------------------------------------------------------- */
4202+
86dc4139
AM
4203+static inline struct vfsmount *au_br_mnt(struct au_branch *br)
4204+{
4205+ return br->br_path.mnt;
4206+}
4207+
4208+static inline struct dentry *au_br_dentry(struct au_branch *br)
4209+{
4210+ return br->br_path.dentry;
4211+}
4212+
4213+static inline struct super_block *au_br_sb(struct au_branch *br)
4214+{
4215+ return au_br_mnt(br)->mnt_sb;
4216+}
4217+
1facf9fc 4218+static inline int au_br_rdonly(struct au_branch *br)
4219+{
86dc4139 4220+ return ((au_br_sb(br)->s_flags & MS_RDONLY)
1facf9fc 4221+ || !au_br_writable(br->br_perm))
4222+ ? -EROFS : 0;
4223+}
4224+
4a4d8108 4225+static inline int au_br_hnotifyable(int brperm __maybe_unused)
1facf9fc 4226+{
4a4d8108 4227+#ifdef CONFIG_AUFS_HNOTIFY
1e00d052 4228+ return !(brperm & AuBrPerm_RR);
1facf9fc 4229+#else
4230+ return 0;
4231+#endif
4232+}
4233+
4234+/* ---------------------------------------------------------------------- */
4235+
4236+/* branch.c */
4237+struct au_sbinfo;
4238+void au_br_free(struct au_sbinfo *sinfo);
4239+int au_br_index(struct super_block *sb, aufs_bindex_t br_id);
4240+struct au_opt_add;
4241+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount);
4242+struct au_opt_del;
4243+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount);
027c5e7a
AM
4244+long au_ibusy_ioctl(struct file *file, unsigned long arg);
4245+#ifdef CONFIG_COMPAT
4246+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg);
4247+#endif
1facf9fc 4248+struct au_opt_mod;
4249+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount,
7f207e10 4250+ int *do_refresh);
076b876e
AM
4251+struct aufs_stfs;
4252+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs);
1facf9fc 4253+
4254+/* xino.c */
4255+static const loff_t au_loff_max = LLONG_MAX;
4256+
4257+int au_xib_trunc(struct super_block *sb);
4258+ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size,
4259+ loff_t *pos);
4260+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
4261+ loff_t *pos);
4262+struct file *au_xino_create2(struct file *base_file, struct file *copy_src);
4263+struct file *au_xino_create(struct super_block *sb, char *fname, int silent);
4264+ino_t au_xino_new_ino(struct super_block *sb);
b752ccd1 4265+void au_xino_delete_inode(struct inode *inode, const int unlinked);
1facf9fc 4266+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4267+ ino_t ino);
4268+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
4269+ ino_t *ino);
4270+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino,
4271+ struct file *base_file, int do_test);
4272+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex);
4273+
4274+struct au_opt_xino;
4275+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount);
4276+void au_xino_clr(struct super_block *sb);
4277+struct file *au_xino_def(struct super_block *sb);
4278+int au_xino_path(struct seq_file *seq, struct file *file);
4279+
4280+/* ---------------------------------------------------------------------- */
4281+
4282+/* Superblock to branch */
4283+static inline
4284+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex)
4285+{
4286+ return au_sbr(sb, bindex)->br_id;
4287+}
4288+
4289+static inline
4290+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex)
4291+{
86dc4139 4292+ return au_br_mnt(au_sbr(sb, bindex));
1facf9fc 4293+}
4294+
4295+static inline
4296+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex)
4297+{
86dc4139 4298+ return au_br_sb(au_sbr(sb, bindex));
1facf9fc 4299+}
4300+
4301+static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex)
4302+{
e49829fe 4303+ atomic_dec(&au_sbr(sb, bindex)->br_count);
1facf9fc 4304+}
4305+
4306+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex)
4307+{
4308+ return au_sbr(sb, bindex)->br_perm;
4309+}
4310+
4311+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex)
4312+{
4313+ return au_br_whable(au_sbr_perm(sb, bindex));
4314+}
4315+
4316+/* ---------------------------------------------------------------------- */
4317+
4318+/*
4319+ * wbr_wh_read_lock, wbr_wh_write_lock
4320+ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock
4321+ */
4322+AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem);
4323+
dece6358
AM
4324+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem)
4325+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem)
4326+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem)
4327+
076b876e
AM
4328+/* ---------------------------------------------------------------------- */
4329+
4330+#ifdef CONFIG_AUFS_FHSM
4331+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm)
4332+{
4333+ mutex_init(&brfhsm->bf_lock);
4334+ brfhsm->bf_jiffy = 0;
4335+ brfhsm->bf_readable = 0;
4336+}
4337+
4338+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm)
4339+{
4340+ mutex_destroy(&brfhsm->bf_lock);
4341+}
4342+#else
4343+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm)
4344+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm)
4345+#endif
4346+
1facf9fc 4347+#endif /* __KERNEL__ */
4348+#endif /* __AUFS_BRANCH_H__ */
7f207e10
AM
4349diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk
4350--- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
4351+++ linux/fs/aufs/conf.mk 2015-01-25 13:00:38.631047076 +0100
4352@@ -0,0 +1,38 @@
4a4d8108
AM
4353+
4354+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS}
4355+
4356+define AuConf
4357+ifdef ${1}
4358+AuConfStr += ${1}=${${1}}
4359+endif
4360+endef
4361+
b752ccd1 4362+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \
e49829fe 4363+ SBILIST \
7f207e10 4364+ HNOTIFY HFSNOTIFY \
4a4d8108 4365+ EXPORT INO_T_64 \
c1595e42 4366+ XATTR \
076b876e 4367+ FHSM \
4a4d8108 4368+ RDU \
4a4d8108
AM
4369+ SHWH \
4370+ BR_RAMFS \
4371+ BR_FUSE POLL \
4372+ BR_HFSPLUS \
4373+ BDEV_LOOP \
b752ccd1
AM
4374+ DEBUG MAGIC_SYSRQ
4375+$(foreach i, ${AuConfAll}, \
4a4d8108
AM
4376+ $(eval $(call AuConf,CONFIG_AUFS_${i})))
4377+
4378+AuConfName = ${obj}/conf.str
4379+${AuConfName}.tmp: FORCE
4380+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@
4381+${AuConfName}: ${AuConfName}.tmp
4382+ @diff -q $< $@ > /dev/null 2>&1 || { \
4383+ echo ' GEN ' $@; \
4384+ cp -p $< $@; \
4385+ }
4386+FORCE:
4387+clean-files += ${AuConfName} ${AuConfName}.tmp
4388+${obj}/sysfs.o: ${AuConfName}
b752ccd1
AM
4389+
4390+-include ${srctree}/${src}/conf_priv.mk
7f207e10
AM
4391diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
4392--- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
4393+++ linux/fs/aufs/cpup.c 2015-01-25 13:00:38.631047076 +0100
4394@@ -0,0 +1,1303 @@
1facf9fc 4395+/*
523b37e3 4396+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 4397+ *
4398+ * This program, aufs is free software; you can redistribute it and/or modify
4399+ * it under the terms of the GNU General Public License as published by
4400+ * the Free Software Foundation; either version 2 of the License, or
4401+ * (at your option) any later version.
dece6358
AM
4402+ *
4403+ * This program is distributed in the hope that it will be useful,
4404+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4405+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4406+ * GNU General Public License for more details.
4407+ *
4408+ * You should have received a copy of the GNU General Public License
523b37e3 4409+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 4410+ */
4411+
4412+/*
4413+ * copy-up functions, see wbr_policy.c for copy-down
4414+ */
4415+
4416+#include <linux/fs_stack.h>
dece6358 4417+#include <linux/mm.h>
1facf9fc 4418+#include "aufs.h"
4419+
86dc4139 4420+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags)
1facf9fc 4421+{
4422+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE
367653fa 4423+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT;
1facf9fc 4424+
86dc4139
AM
4425+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags));
4426+
4427+ dst->i_flags |= iflags & ~mask;
1facf9fc 4428+ if (au_test_fs_notime(dst->i_sb))
4429+ dst->i_flags |= S_NOATIME | S_NOCMTIME;
4430+}
4431+
4432+void au_cpup_attr_timesizes(struct inode *inode)
4433+{
4434+ struct inode *h_inode;
4435+
4436+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4437+ fsstack_copy_attr_times(inode, h_inode);
4a4d8108 4438+ fsstack_copy_inode_size(inode, h_inode);
1facf9fc 4439+}
4440+
4441+void au_cpup_attr_nlink(struct inode *inode, int force)
4442+{
4443+ struct inode *h_inode;
4444+ struct super_block *sb;
4445+ aufs_bindex_t bindex, bend;
4446+
4447+ sb = inode->i_sb;
4448+ bindex = au_ibstart(inode);
4449+ h_inode = au_h_iptr(inode, bindex);
4450+ if (!force
4451+ && !S_ISDIR(h_inode->i_mode)
4452+ && au_opt_test(au_mntflags(sb), PLINK)
4453+ && au_plink_test(inode))
4454+ return;
4455+
7eafdf33
AM
4456+ /*
4457+ * 0 can happen in revalidating.
38d290e6
JR
4458+ * h_inode->i_mutex may not be held here, but it is harmless since once
4459+ * i_nlink reaches 0, it will never become positive except O_TMPFILE
4460+ * case.
4461+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause
4462+ * the incorrect link count.
7eafdf33 4463+ */
92d182d2 4464+ set_nlink(inode, h_inode->i_nlink);
1facf9fc 4465+
4466+ /*
4467+ * fewer nlink makes find(1) noisy, but larger nlink doesn't.
4468+ * it may includes whplink directory.
4469+ */
4470+ if (S_ISDIR(h_inode->i_mode)) {
4471+ bend = au_ibend(inode);
4472+ for (bindex++; bindex <= bend; bindex++) {
4473+ h_inode = au_h_iptr(inode, bindex);
4474+ if (h_inode)
4475+ au_add_nlink(inode, h_inode);
4476+ }
4477+ }
4478+}
4479+
4480+void au_cpup_attr_changeable(struct inode *inode)
4481+{
4482+ struct inode *h_inode;
4483+
4484+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4485+ inode->i_mode = h_inode->i_mode;
4486+ inode->i_uid = h_inode->i_uid;
4487+ inode->i_gid = h_inode->i_gid;
4488+ au_cpup_attr_timesizes(inode);
86dc4139 4489+ au_cpup_attr_flags(inode, h_inode->i_flags);
1facf9fc 4490+}
4491+
4492+void au_cpup_igen(struct inode *inode, struct inode *h_inode)
4493+{
4494+ struct au_iinfo *iinfo = au_ii(inode);
4495+
1308ab2a 4496+ IiMustWriteLock(inode);
4497+
1facf9fc 4498+ iinfo->ii_higen = h_inode->i_generation;
4499+ iinfo->ii_hsb1 = h_inode->i_sb;
4500+}
4501+
4502+void au_cpup_attr_all(struct inode *inode, int force)
4503+{
4504+ struct inode *h_inode;
4505+
4506+ h_inode = au_h_iptr(inode, au_ibstart(inode));
4507+ au_cpup_attr_changeable(inode);
4508+ if (inode->i_nlink > 0)
4509+ au_cpup_attr_nlink(inode, force);
4510+ inode->i_rdev = h_inode->i_rdev;
4511+ inode->i_blkbits = h_inode->i_blkbits;
4512+ au_cpup_igen(inode, h_inode);
4513+}
4514+
4515+/* ---------------------------------------------------------------------- */
4516+
4517+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */
4518+
4519+/* keep the timestamps of the parent dir when cpup */
4520+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
4521+ struct path *h_path)
4522+{
4523+ struct inode *h_inode;
4524+
4525+ dt->dt_dentry = dentry;
4526+ dt->dt_h_path = *h_path;
4527+ h_inode = h_path->dentry->d_inode;
4528+ dt->dt_atime = h_inode->i_atime;
4529+ dt->dt_mtime = h_inode->i_mtime;
4530+ /* smp_mb(); */
4531+}
4532+
4533+void au_dtime_revert(struct au_dtime *dt)
4534+{
4535+ struct iattr attr;
4536+ int err;
4537+
4538+ attr.ia_atime = dt->dt_atime;
4539+ attr.ia_mtime = dt->dt_mtime;
4540+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET
4541+ | ATTR_ATIME | ATTR_ATIME_SET;
4542+
523b37e3
AM
4543+ /* no delegation since this is a directory */
4544+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL);
1facf9fc 4545+ if (unlikely(err))
0c3ec466 4546+ pr_warn("restoring timestamps failed(%d). ignored\n", err);
1facf9fc 4547+}
4548+
4549+/* ---------------------------------------------------------------------- */
4550+
86dc4139
AM
4551+/* internal use only */
4552+struct au_cpup_reg_attr {
4553+ int valid;
4554+ struct kstat st;
4555+ unsigned int iflags; /* inode->i_flags */
4556+};
4557+
1facf9fc 4558+static noinline_for_stack
86dc4139
AM
4559+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src,
4560+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4561+{
c1595e42 4562+ int err, sbits, icex;
1facf9fc 4563+ struct iattr ia;
4564+ struct path h_path;
1308ab2a 4565+ struct inode *h_isrc, *h_idst;
86dc4139 4566+ struct kstat *h_st;
c1595e42 4567+ struct au_branch *br;
1facf9fc 4568+
4569+ h_path.dentry = au_h_dptr(dst, bindex);
1308ab2a 4570+ h_idst = h_path.dentry->d_inode;
c1595e42
JR
4571+ br = au_sbr(dst->d_sb, bindex);
4572+ h_path.mnt = au_br_mnt(br);
1facf9fc 4573+ h_isrc = h_src->d_inode;
1308ab2a 4574+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID
1facf9fc 4575+ | ATTR_ATIME | ATTR_MTIME
4576+ | ATTR_ATIME_SET | ATTR_MTIME_SET;
86dc4139
AM
4577+ if (h_src_attr && h_src_attr->valid) {
4578+ h_st = &h_src_attr->st;
4579+ ia.ia_uid = h_st->uid;
4580+ ia.ia_gid = h_st->gid;
4581+ ia.ia_atime = h_st->atime;
4582+ ia.ia_mtime = h_st->mtime;
4583+ if (h_idst->i_mode != h_st->mode
4584+ && !S_ISLNK(h_idst->i_mode)) {
4585+ ia.ia_valid |= ATTR_MODE;
4586+ ia.ia_mode = h_st->mode;
4587+ }
4588+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID));
4589+ au_cpup_attr_flags(h_idst, h_src_attr->iflags);
4590+ } else {
4591+ ia.ia_uid = h_isrc->i_uid;
4592+ ia.ia_gid = h_isrc->i_gid;
4593+ ia.ia_atime = h_isrc->i_atime;
4594+ ia.ia_mtime = h_isrc->i_mtime;
4595+ if (h_idst->i_mode != h_isrc->i_mode
4596+ && !S_ISLNK(h_idst->i_mode)) {
4597+ ia.ia_valid |= ATTR_MODE;
4598+ ia.ia_mode = h_isrc->i_mode;
4599+ }
4600+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID));
4601+ au_cpup_attr_flags(h_idst, h_isrc->i_flags);
1308ab2a 4602+ }
523b37e3
AM
4603+ /* no delegation since it is just created */
4604+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4605+
4606+ /* is this nfs only? */
4607+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) {
4608+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
4609+ ia.ia_mode = h_isrc->i_mode;
523b37e3 4610+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL);
1facf9fc 4611+ }
4612+
c1595e42
JR
4613+ icex = br->br_perm & AuBrAttr_ICEX;
4614+ if (!err)
4615+ err = au_cpup_xattr(h_path.dentry, h_src, icex);
4616+
1facf9fc 4617+ return err;
4618+}
4619+
4620+/* ---------------------------------------------------------------------- */
4621+
4622+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len,
4623+ char *buf, unsigned long blksize)
4624+{
4625+ int err;
4626+ size_t sz, rbytes, wbytes;
4627+ unsigned char all_zero;
4628+ char *p, *zp;
4629+ struct mutex *h_mtx;
4630+ /* reduce stack usage */
4631+ struct iattr *ia;
4632+
4633+ zp = page_address(ZERO_PAGE(0));
4634+ if (unlikely(!zp))
4635+ return -ENOMEM; /* possible? */
4636+
4637+ err = 0;
4638+ all_zero = 0;
4639+ while (len) {
4640+ AuDbg("len %lld\n", len);
4641+ sz = blksize;
4642+ if (len < blksize)
4643+ sz = len;
4644+
4645+ rbytes = 0;
4646+ /* todo: signal_pending? */
4647+ while (!rbytes || err == -EAGAIN || err == -EINTR) {
4648+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos);
4649+ err = rbytes;
4650+ }
4651+ if (unlikely(err < 0))
4652+ break;
4653+
4654+ all_zero = 0;
4655+ if (len >= rbytes && rbytes == blksize)
4656+ all_zero = !memcmp(buf, zp, rbytes);
4657+ if (!all_zero) {
4658+ wbytes = rbytes;
4659+ p = buf;
4660+ while (wbytes) {
4661+ size_t b;
4662+
4663+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos);
4664+ err = b;
4665+ /* todo: signal_pending? */
4666+ if (unlikely(err == -EAGAIN || err == -EINTR))
4667+ continue;
4668+ if (unlikely(err < 0))
4669+ break;
4670+ wbytes -= b;
4671+ p += b;
4672+ }
392086de
AM
4673+ if (unlikely(err < 0))
4674+ break;
1facf9fc 4675+ } else {
4676+ loff_t res;
4677+
4678+ AuLabel(hole);
4679+ res = vfsub_llseek(dst, rbytes, SEEK_CUR);
4680+ err = res;
4681+ if (unlikely(res < 0))
4682+ break;
4683+ }
4684+ len -= rbytes;
4685+ err = 0;
4686+ }
4687+
4688+ /* the last block may be a hole */
4689+ if (!err && all_zero) {
4690+ AuLabel(last hole);
4691+
4692+ err = 1;
4693+ if (au_test_nfs(dst->f_dentry->d_sb)) {
4694+ /* nfs requires this step to make last hole */
4695+ /* is this only nfs? */
4696+ do {
4697+ /* todo: signal_pending? */
4698+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos);
4699+ } while (err == -EAGAIN || err == -EINTR);
4700+ if (err == 1)
4701+ dst->f_pos--;
4702+ }
4703+
4704+ if (err == 1) {
4705+ ia = (void *)buf;
4706+ ia->ia_size = dst->f_pos;
4707+ ia->ia_valid = ATTR_SIZE | ATTR_FILE;
4708+ ia->ia_file = dst;
c06a8ce3 4709+ h_mtx = &file_inode(dst)->i_mutex;
1facf9fc 4710+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
523b37e3
AM
4711+ /* no delegation since it is just created */
4712+ err = vfsub_notify_change(&dst->f_path, ia,
4713+ /*delegated*/NULL);
1facf9fc 4714+ mutex_unlock(h_mtx);
4715+ }
4716+ }
4717+
4718+ return err;
4719+}
4720+
4721+int au_copy_file(struct file *dst, struct file *src, loff_t len)
4722+{
4723+ int err;
4724+ unsigned long blksize;
4725+ unsigned char do_kfree;
4726+ char *buf;
4727+
4728+ err = -ENOMEM;
4729+ blksize = dst->f_dentry->d_sb->s_blocksize;
4730+ if (!blksize || PAGE_SIZE < blksize)
4731+ blksize = PAGE_SIZE;
4732+ AuDbg("blksize %lu\n", blksize);
4733+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *));
4734+ if (do_kfree)
4735+ buf = kmalloc(blksize, GFP_NOFS);
4736+ else
4737+ buf = (void *)__get_free_page(GFP_NOFS);
4738+ if (unlikely(!buf))
4739+ goto out;
4740+
4741+ if (len > (1 << 22))
4742+ AuDbg("copying a large file %lld\n", (long long)len);
4743+
4744+ src->f_pos = 0;
4745+ dst->f_pos = 0;
4746+ err = au_do_copy_file(dst, src, len, buf, blksize);
4747+ if (do_kfree)
4748+ kfree(buf);
4749+ else
4750+ free_page((unsigned long)buf);
4751+
4f0767ce 4752+out:
1facf9fc 4753+ return err;
4754+}
4755+
4756+/*
4757+ * to support a sparse file which is opened with O_APPEND,
4758+ * we need to close the file.
4759+ */
c2b27bf2 4760+static int au_cp_regular(struct au_cp_generic *cpg)
1facf9fc 4761+{
4762+ int err, i;
4763+ enum { SRC, DST };
4764+ struct {
4765+ aufs_bindex_t bindex;
4766+ unsigned int flags;
4767+ struct dentry *dentry;
392086de 4768+ int force_wr;
1facf9fc 4769+ struct file *file;
523b37e3 4770+ void *label;
1facf9fc 4771+ } *f, file[] = {
4772+ {
c2b27bf2 4773+ .bindex = cpg->bsrc,
1facf9fc 4774+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE,
523b37e3 4775+ .label = &&out
1facf9fc 4776+ },
4777+ {
c2b27bf2 4778+ .bindex = cpg->bdst,
1facf9fc 4779+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
392086de 4780+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
523b37e3 4781+ .label = &&out_src
1facf9fc 4782+ }
4783+ };
4784+ struct super_block *sb;
4785+
4786+ /* bsrc branch can be ro/rw. */
c2b27bf2 4787+ sb = cpg->dentry->d_sb;
1facf9fc 4788+ f = file;
4789+ for (i = 0; i < 2; i++, f++) {
c2b27bf2
AM
4790+ f->dentry = au_h_dptr(cpg->dentry, f->bindex);
4791+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
392086de 4792+ /*file*/NULL, f->force_wr);
1facf9fc 4793+ err = PTR_ERR(f->file);
4794+ if (IS_ERR(f->file))
4795+ goto *f->label;
1facf9fc 4796+ }
4797+
4798+ /* try stopping to update while we copyup */
4799+ IMustLock(file[SRC].dentry->d_inode);
c2b27bf2 4800+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
1facf9fc 4801+
1facf9fc 4802+ fput(file[DST].file);
4803+ au_sbr_put(sb, file[DST].bindex);
523b37e3 4804+
4f0767ce 4805+out_src:
1facf9fc 4806+ fput(file[SRC].file);
4807+ au_sbr_put(sb, file[SRC].bindex);
4f0767ce 4808+out:
1facf9fc 4809+ return err;
4810+}
4811+
c2b27bf2 4812+static int au_do_cpup_regular(struct au_cp_generic *cpg,
86dc4139 4813+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4814+{
4815+ int err, rerr;
4816+ loff_t l;
86dc4139 4817+ struct path h_path;
38d290e6 4818+ struct inode *h_src_inode, *h_dst_inode;
1facf9fc 4819+
4820+ err = 0;
c2b27bf2 4821+ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc);
86dc4139 4822+ l = i_size_read(h_src_inode);
c2b27bf2
AM
4823+ if (cpg->len == -1 || l < cpg->len)
4824+ cpg->len = l;
4825+ if (cpg->len) {
86dc4139
AM
4826+ /* try stopping to update while we are referencing */
4827+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2 4828+ au_pin_hdir_unlock(cpg->pin);
1facf9fc 4829+
c2b27bf2
AM
4830+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
4831+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc);
86dc4139
AM
4832+ h_src_attr->iflags = h_src_inode->i_flags;
4833+ err = vfs_getattr(&h_path, &h_src_attr->st);
4834+ if (unlikely(err)) {
4835+ mutex_unlock(&h_src_inode->i_mutex);
4836+ goto out;
4837+ }
4838+ h_src_attr->valid = 1;
c2b27bf2 4839+ err = au_cp_regular(cpg);
86dc4139 4840+ mutex_unlock(&h_src_inode->i_mutex);
c2b27bf2 4841+ rerr = au_pin_hdir_relock(cpg->pin);
86dc4139
AM
4842+ if (!err && rerr)
4843+ err = rerr;
1facf9fc 4844+ }
38d290e6
JR
4845+ if (!err && (h_src_inode->i_state & I_LINKABLE)) {
4846+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst);
4847+ h_dst_inode = h_path.dentry->d_inode;
4848+ spin_lock(&h_dst_inode->i_lock);
4849+ h_dst_inode->i_state |= I_LINKABLE;
4850+ spin_unlock(&h_dst_inode->i_lock);
4851+ }
1facf9fc 4852+
4f0767ce 4853+out:
1facf9fc 4854+ return err;
4855+}
4856+
4857+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src,
4858+ struct inode *h_dir)
4859+{
4860+ int err, symlen;
4861+ mm_segment_t old_fs;
b752ccd1
AM
4862+ union {
4863+ char *k;
4864+ char __user *u;
4865+ } sym;
1facf9fc 4866+
4867+ err = -ENOSYS;
4868+ if (unlikely(!h_src->d_inode->i_op->readlink))
4869+ goto out;
4870+
4871+ err = -ENOMEM;
537831f9 4872+ sym.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 4873+ if (unlikely(!sym.k))
1facf9fc 4874+ goto out;
4875+
9dbd164d 4876+ /* unnecessary to support mmap_sem since symlink is not mmap-able */
1facf9fc 4877+ old_fs = get_fs();
4878+ set_fs(KERNEL_DS);
b752ccd1 4879+ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX);
1facf9fc 4880+ err = symlen;
4881+ set_fs(old_fs);
4882+
4883+ if (symlen > 0) {
b752ccd1
AM
4884+ sym.k[symlen] = 0;
4885+ err = vfsub_symlink(h_dir, h_path, sym.k);
1facf9fc 4886+ }
537831f9 4887+ free_page((unsigned long)sym.k);
1facf9fc 4888+
4f0767ce 4889+out:
1facf9fc 4890+ return err;
4891+}
4892+
1facf9fc 4893+static noinline_for_stack
c2b27bf2 4894+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
86dc4139 4895+ struct au_cpup_reg_attr *h_src_attr)
1facf9fc 4896+{
4897+ int err;
4898+ umode_t mode;
4899+ unsigned int mnt_flags;
076b876e 4900+ unsigned char isdir, isreg, force;
c2b27bf2 4901+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 4902+ struct au_dtime dt;
4903+ struct path h_path;
4904+ struct dentry *h_src, *h_dst, *h_parent;
4905+ struct inode *h_inode, *h_dir;
4906+ struct super_block *sb;
4907+
4908+ /* bsrc branch can be ro/rw. */
c2b27bf2 4909+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
1facf9fc 4910+ h_inode = h_src->d_inode;
c2b27bf2 4911+ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc));
1facf9fc 4912+
4913+ /* try stopping to be referenced while we are creating */
c2b27bf2
AM
4914+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
4915+ if (au_ftest_cpup(cpg->flags, RENAME))
86dc4139
AM
4916+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX,
4917+ AUFS_WH_PFX_LEN));
1facf9fc 4918+ h_parent = h_dst->d_parent; /* dir inode is locked */
4919+ h_dir = h_parent->d_inode;
4920+ IMustLock(h_dir);
4921+ AuDebugOn(h_parent != h_dst->d_parent);
4922+
c2b27bf2
AM
4923+ sb = cpg->dentry->d_sb;
4924+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst);
1facf9fc 4925+ if (do_dt) {
4926+ h_path.dentry = h_parent;
4927+ au_dtime_store(&dt, dst_parent, &h_path);
4928+ }
4929+ h_path.dentry = h_dst;
4930+
076b876e 4931+ isreg = 0;
1facf9fc 4932+ isdir = 0;
4933+ mode = h_inode->i_mode;
4934+ switch (mode & S_IFMT) {
4935+ case S_IFREG:
076b876e 4936+ isreg = 1;
b4510431
AM
4937+ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR,
4938+ /*want_excl*/true);
1facf9fc 4939+ if (!err)
c2b27bf2 4940+ err = au_do_cpup_regular(cpg, h_src_attr);
1facf9fc 4941+ break;
4942+ case S_IFDIR:
4943+ isdir = 1;
4944+ err = vfsub_mkdir(h_dir, &h_path, mode);
4945+ if (!err) {
4946+ /*
4947+ * strange behaviour from the users view,
4948+ * particularry setattr case
4949+ */
c2b27bf2 4950+ if (au_ibstart(dst_parent->d_inode) == cpg->bdst)
1facf9fc 4951+ au_cpup_attr_nlink(dst_parent->d_inode,
4952+ /*force*/1);
c2b27bf2 4953+ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1);
1facf9fc 4954+ }
4955+ break;
4956+ case S_IFLNK:
4957+ err = au_do_cpup_symlink(&h_path, h_src, h_dir);
4958+ break;
4959+ case S_IFCHR:
4960+ case S_IFBLK:
4961+ AuDebugOn(!capable(CAP_MKNOD));
4962+ /*FALLTHROUGH*/
4963+ case S_IFIFO:
4964+ case S_IFSOCK:
4965+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev);
4966+ break;
4967+ default:
4968+ AuIOErr("Unknown inode type 0%o\n", mode);
4969+ err = -EIO;
4970+ }
4971+
4972+ mnt_flags = au_mntflags(sb);
4973+ if (!au_opt_test(mnt_flags, UDBA_NONE)
4974+ && !isdir
4975+ && au_opt_test(mnt_flags, XINO)
38d290e6
JR
4976+ && (h_inode->i_nlink == 1
4977+ || (h_inode->i_state & I_LINKABLE))
1facf9fc 4978+ /* todo: unnecessary? */
c2b27bf2
AM
4979+ /* && cpg->dentry->d_inode->i_nlink == 1 */
4980+ && cpg->bdst < cpg->bsrc
4981+ && !au_ftest_cpup(cpg->flags, KEEPLINO))
4982+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0);
1facf9fc 4983+ /* ignore this error */
4984+
076b876e
AM
4985+ if (!err) {
4986+ force = 0;
4987+ if (isreg) {
4988+ force = !!cpg->len;
4989+ if (cpg->len == -1)
4990+ force = !!i_size_read(h_inode);
4991+ }
4992+ au_fhsm_wrote(sb, cpg->bdst, force);
4993+ }
4994+
1facf9fc 4995+ if (do_dt)
4996+ au_dtime_revert(&dt);
4997+ return err;
4998+}
4999+
392086de 5000+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
86dc4139
AM
5001+{
5002+ int err;
392086de 5003+ struct dentry *dentry, *h_dentry, *h_parent, *parent;
86dc4139 5004+ struct inode *h_dir;
392086de 5005+ aufs_bindex_t bdst;
86dc4139 5006+
392086de
AM
5007+ dentry = cpg->dentry;
5008+ bdst = cpg->bdst;
5009+ h_dentry = au_h_dptr(dentry, bdst);
5010+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
5011+ dget(h_dentry);
5012+ au_set_h_dptr(dentry, bdst, NULL);
5013+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
5014+ if (!err)
5015+ h_path->dentry = dget(au_h_dptr(dentry, bdst));
86dc4139 5016+ au_set_h_dptr(dentry, bdst, h_dentry);
392086de
AM
5017+ } else {
5018+ err = 0;
5019+ parent = dget_parent(dentry);
5020+ h_parent = au_h_dptr(parent, bdst);
5021+ dput(parent);
5022+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
5023+ if (IS_ERR(h_path->dentry))
5024+ err = PTR_ERR(h_path->dentry);
86dc4139 5025+ }
392086de
AM
5026+ if (unlikely(err))
5027+ goto out;
86dc4139 5028+
86dc4139
AM
5029+ h_parent = h_dentry->d_parent; /* dir inode is locked */
5030+ h_dir = h_parent->d_inode;
5031+ IMustLock(h_dir);
523b37e3
AM
5032+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry);
5033+ /* no delegation since it is just created */
5034+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL);
86dc4139
AM
5035+ dput(h_path->dentry);
5036+
5037+out:
5038+ return err;
5039+}
5040+
1facf9fc 5041+/*
5042+ * copyup the @dentry from @bsrc to @bdst.
5043+ * the caller must set the both of lower dentries.
5044+ * @len is for truncating when it is -1 copyup the entire file.
5045+ * in link/rename cases, @dst_parent may be different from the real one.
c2b27bf2 5046+ * basic->bsrc can be larger than basic->bdst.
1facf9fc 5047+ */
c2b27bf2 5048+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5049+{
5050+ int err, rerr;
5051+ aufs_bindex_t old_ibstart;
5052+ unsigned char isdir, plink;
1facf9fc 5053+ struct dentry *h_src, *h_dst, *h_parent;
523b37e3 5054+ struct inode *dst_inode, *h_dir, *inode, *delegated;
1facf9fc 5055+ struct super_block *sb;
86dc4139 5056+ struct au_branch *br;
c2b27bf2
AM
5057+ /* to reuduce stack size */
5058+ struct {
5059+ struct au_dtime dt;
5060+ struct path h_path;
5061+ struct au_cpup_reg_attr h_src_attr;
5062+ } *a;
1facf9fc 5063+
c2b27bf2
AM
5064+ err = -ENOMEM;
5065+ a = kmalloc(sizeof(*a), GFP_NOFS);
5066+ if (unlikely(!a))
5067+ goto out;
5068+ a->h_src_attr.valid = 0;
1facf9fc 5069+
c2b27bf2
AM
5070+ sb = cpg->dentry->d_sb;
5071+ br = au_sbr(sb, cpg->bdst);
5072+ a->h_path.mnt = au_br_mnt(br);
5073+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst);
1facf9fc 5074+ h_parent = h_dst->d_parent; /* dir inode is locked */
5075+ h_dir = h_parent->d_inode;
5076+ IMustLock(h_dir);
5077+
c2b27bf2
AM
5078+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc);
5079+ inode = cpg->dentry->d_inode;
1facf9fc 5080+
5081+ if (!dst_parent)
c2b27bf2 5082+ dst_parent = dget_parent(cpg->dentry);
1facf9fc 5083+ else
5084+ dget(dst_parent);
5085+
5086+ plink = !!au_opt_test(au_mntflags(sb), PLINK);
c2b27bf2 5087+ dst_inode = au_h_iptr(inode, cpg->bdst);
1facf9fc 5088+ if (dst_inode) {
5089+ if (unlikely(!plink)) {
5090+ err = -EIO;
027c5e7a
AM
5091+ AuIOErr("hi%lu(i%lu) exists on b%d "
5092+ "but plink is disabled\n",
c2b27bf2
AM
5093+ dst_inode->i_ino, inode->i_ino, cpg->bdst);
5094+ goto out_parent;
1facf9fc 5095+ }
5096+
5097+ if (dst_inode->i_nlink) {
c2b27bf2 5098+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME);
1facf9fc 5099+
c2b27bf2 5100+ h_src = au_plink_lkup(inode, cpg->bdst);
1facf9fc 5101+ err = PTR_ERR(h_src);
5102+ if (IS_ERR(h_src))
c2b27bf2 5103+ goto out_parent;
1facf9fc 5104+ if (unlikely(!h_src->d_inode)) {
5105+ err = -EIO;
5106+ AuIOErr("i%lu exists on a upper branch "
027c5e7a
AM
5107+ "but not pseudo-linked\n",
5108+ inode->i_ino);
1facf9fc 5109+ dput(h_src);
c2b27bf2 5110+ goto out_parent;
1facf9fc 5111+ }
5112+
5113+ if (do_dt) {
c2b27bf2
AM
5114+ a->h_path.dentry = h_parent;
5115+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
1facf9fc 5116+ }
86dc4139 5117+
c2b27bf2 5118+ a->h_path.dentry = h_dst;
523b37e3
AM
5119+ delegated = NULL;
5120+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated);
c2b27bf2 5121+ if (!err && au_ftest_cpup(cpg->flags, RENAME))
392086de 5122+ err = au_do_ren_after_cpup(cpg, &a->h_path);
1facf9fc 5123+ if (do_dt)
c2b27bf2 5124+ au_dtime_revert(&a->dt);
523b37e3
AM
5125+ if (unlikely(err == -EWOULDBLOCK)) {
5126+ pr_warn("cannot retry for NFSv4 delegation"
5127+ " for an internal link\n");
5128+ iput(delegated);
5129+ }
1facf9fc 5130+ dput(h_src);
c2b27bf2 5131+ goto out_parent;
1facf9fc 5132+ } else
5133+ /* todo: cpup_wh_file? */
5134+ /* udba work */
4a4d8108 5135+ au_update_ibrange(inode, /*do_put_zero*/1);
1facf9fc 5136+ }
5137+
86dc4139 5138+ isdir = S_ISDIR(inode->i_mode);
1facf9fc 5139+ old_ibstart = au_ibstart(inode);
c2b27bf2 5140+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr);
1facf9fc 5141+ if (unlikely(err))
86dc4139 5142+ goto out_rev;
1facf9fc 5143+ dst_inode = h_dst->d_inode;
5144+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2);
86dc4139 5145+ /* todo: necessary? */
c2b27bf2 5146+ /* au_pin_hdir_unlock(cpg->pin); */
1facf9fc 5147+
c2b27bf2 5148+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr);
86dc4139
AM
5149+ if (unlikely(err)) {
5150+ /* todo: necessary? */
c2b27bf2 5151+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */
86dc4139
AM
5152+ mutex_unlock(&dst_inode->i_mutex);
5153+ goto out_rev;
5154+ }
5155+
c2b27bf2 5156+ if (cpg->bdst < old_ibstart) {
86dc4139 5157+ if (S_ISREG(inode->i_mode)) {
c2b27bf2 5158+ err = au_dy_iaop(inode, cpg->bdst, dst_inode);
86dc4139 5159+ if (unlikely(err)) {
c2b27bf2
AM
5160+ /* ignore an error */
5161+ /* au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5162+ mutex_unlock(&dst_inode->i_mutex);
5163+ goto out_rev;
4a4d8108 5164+ }
4a4d8108 5165+ }
c2b27bf2
AM
5166+ au_set_ibstart(inode, cpg->bdst);
5167+ } else
5168+ au_set_ibend(inode, cpg->bdst);
5169+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode),
86dc4139
AM
5170+ au_hi_flags(inode, isdir));
5171+
5172+ /* todo: necessary? */
c2b27bf2 5173+ /* err = au_pin_hdir_relock(cpg->pin); */
86dc4139
AM
5174+ mutex_unlock(&dst_inode->i_mutex);
5175+ if (unlikely(err))
5176+ goto out_rev;
5177+
5178+ if (!isdir
38d290e6
JR
5179+ && (h_src->d_inode->i_nlink > 1
5180+ || h_src->d_inode->i_state & I_LINKABLE)
86dc4139 5181+ && plink)
c2b27bf2 5182+ au_plink_append(inode, cpg->bdst, h_dst);
86dc4139 5183+
c2b27bf2
AM
5184+ if (au_ftest_cpup(cpg->flags, RENAME)) {
5185+ a->h_path.dentry = h_dst;
392086de 5186+ err = au_do_ren_after_cpup(cpg, &a->h_path);
86dc4139
AM
5187+ }
5188+ if (!err)
c2b27bf2 5189+ goto out_parent; /* success */
1facf9fc 5190+
5191+ /* revert */
4a4d8108 5192+out_rev:
c2b27bf2
AM
5193+ a->h_path.dentry = h_parent;
5194+ au_dtime_store(&a->dt, dst_parent, &a->h_path);
5195+ a->h_path.dentry = h_dst;
86dc4139
AM
5196+ rerr = 0;
5197+ if (h_dst->d_inode) {
523b37e3
AM
5198+ if (!isdir) {
5199+ /* no delegation since it is just created */
5200+ rerr = vfsub_unlink(h_dir, &a->h_path,
5201+ /*delegated*/NULL, /*force*/0);
5202+ } else
c2b27bf2 5203+ rerr = vfsub_rmdir(h_dir, &a->h_path);
86dc4139 5204+ }
c2b27bf2 5205+ au_dtime_revert(&a->dt);
1facf9fc 5206+ if (rerr) {
5207+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
5208+ err = -EIO;
5209+ }
c2b27bf2 5210+out_parent:
1facf9fc 5211+ dput(dst_parent);
c2b27bf2
AM
5212+ kfree(a);
5213+out:
1facf9fc 5214+ return err;
5215+}
5216+
c2b27bf2 5217+#if 0 /* unused */
1facf9fc 5218+struct au_cpup_single_args {
5219+ int *errp;
c2b27bf2 5220+ struct au_cp_generic *cpg;
1facf9fc 5221+ struct dentry *dst_parent;
5222+};
5223+
5224+static void au_call_cpup_single(void *args)
5225+{
5226+ struct au_cpup_single_args *a = args;
86dc4139 5227+
c2b27bf2
AM
5228+ au_pin_hdir_acquire_nest(a->cpg->pin);
5229+ *a->errp = au_cpup_single(a->cpg, a->dst_parent);
5230+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5231+}
c2b27bf2 5232+#endif
1facf9fc 5233+
53392da6
AM
5234+/*
5235+ * prevent SIGXFSZ in copy-up.
5236+ * testing CAP_MKNOD is for generic fs,
5237+ * but CAP_FSETID is for xfs only, currently.
5238+ */
86dc4139 5239+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode)
53392da6
AM
5240+{
5241+ int do_sio;
86dc4139
AM
5242+ struct super_block *sb;
5243+ struct inode *h_dir;
53392da6
AM
5244+
5245+ do_sio = 0;
86dc4139 5246+ sb = au_pinned_parent(pin)->d_sb;
53392da6
AM
5247+ if (!au_wkq_test()
5248+ && (!au_sbi(sb)->si_plink_maint_pid
5249+ || au_plink_maint(sb, AuLock_NOPLM))) {
5250+ switch (mode & S_IFMT) {
5251+ case S_IFREG:
5252+ /* no condition about RLIMIT_FSIZE and the file size */
5253+ do_sio = 1;
5254+ break;
5255+ case S_IFCHR:
5256+ case S_IFBLK:
5257+ do_sio = !capable(CAP_MKNOD);
5258+ break;
5259+ }
5260+ if (!do_sio)
5261+ do_sio = ((mode & (S_ISUID | S_ISGID))
5262+ && !capable(CAP_FSETID));
86dc4139
AM
5263+ /* this workaround may be removed in the future */
5264+ if (!do_sio) {
5265+ h_dir = au_pinned_h_dir(pin);
5266+ do_sio = h_dir->i_mode & S_ISVTX;
5267+ }
53392da6
AM
5268+ }
5269+
5270+ return do_sio;
5271+}
5272+
c2b27bf2
AM
5273+#if 0 /* unused */
5274+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent)
1facf9fc 5275+{
5276+ int err, wkq_err;
1facf9fc 5277+ struct dentry *h_dentry;
5278+
c2b27bf2 5279+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc);
86dc4139 5280+ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode))
c2b27bf2 5281+ err = au_cpup_single(cpg, dst_parent);
1facf9fc 5282+ else {
5283+ struct au_cpup_single_args args = {
5284+ .errp = &err,
c2b27bf2
AM
5285+ .cpg = cpg,
5286+ .dst_parent = dst_parent
1facf9fc 5287+ };
5288+ wkq_err = au_wkq_wait(au_call_cpup_single, &args);
5289+ if (unlikely(wkq_err))
5290+ err = wkq_err;
5291+ }
5292+
5293+ return err;
5294+}
c2b27bf2 5295+#endif
1facf9fc 5296+
5297+/*
5298+ * copyup the @dentry from the first active lower branch to @bdst,
5299+ * using au_cpup_single().
5300+ */
c2b27bf2 5301+static int au_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5302+{
5303+ int err;
c2b27bf2
AM
5304+ unsigned int flags_orig;
5305+ struct dentry *dentry;
5306+
5307+ AuDebugOn(cpg->bsrc < 0);
1facf9fc 5308+
c2b27bf2 5309+ dentry = cpg->dentry;
86dc4139 5310+ DiMustWriteLock(dentry);
1facf9fc 5311+
c2b27bf2 5312+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1);
1facf9fc 5313+ if (!err) {
c2b27bf2
AM
5314+ flags_orig = cpg->flags;
5315+ au_fset_cpup(cpg->flags, RENAME);
5316+ err = au_cpup_single(cpg, NULL);
5317+ cpg->flags = flags_orig;
1facf9fc 5318+ if (!err)
5319+ return 0; /* success */
5320+
5321+ /* revert */
c2b27bf2
AM
5322+ au_set_h_dptr(dentry, cpg->bdst, NULL);
5323+ au_set_dbstart(dentry, cpg->bsrc);
1facf9fc 5324+ }
5325+
5326+ return err;
5327+}
5328+
5329+struct au_cpup_simple_args {
5330+ int *errp;
c2b27bf2 5331+ struct au_cp_generic *cpg;
1facf9fc 5332+};
5333+
5334+static void au_call_cpup_simple(void *args)
5335+{
5336+ struct au_cpup_simple_args *a = args;
86dc4139 5337+
c2b27bf2
AM
5338+ au_pin_hdir_acquire_nest(a->cpg->pin);
5339+ *a->errp = au_cpup_simple(a->cpg);
5340+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5341+}
5342+
c2b27bf2 5343+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg)
1facf9fc 5344+{
5345+ int err, wkq_err;
c2b27bf2
AM
5346+ struct dentry *dentry, *parent;
5347+ struct file *h_file;
1facf9fc 5348+ struct inode *h_dir;
5349+
c2b27bf2
AM
5350+ dentry = cpg->dentry;
5351+ h_file = NULL;
5352+ if (au_ftest_cpup(cpg->flags, HOPEN)) {
5353+ AuDebugOn(cpg->bsrc < 0);
392086de 5354+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0);
c2b27bf2
AM
5355+ err = PTR_ERR(h_file);
5356+ if (IS_ERR(h_file))
5357+ goto out;
5358+ }
5359+
1facf9fc 5360+ parent = dget_parent(dentry);
c2b27bf2 5361+ h_dir = au_h_iptr(parent->d_inode, cpg->bdst);
53392da6 5362+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
5363+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
5364+ err = au_cpup_simple(cpg);
1facf9fc 5365+ else {
5366+ struct au_cpup_simple_args args = {
5367+ .errp = &err,
c2b27bf2 5368+ .cpg = cpg
1facf9fc 5369+ };
5370+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args);
5371+ if (unlikely(wkq_err))
5372+ err = wkq_err;
5373+ }
5374+
5375+ dput(parent);
c2b27bf2
AM
5376+ if (h_file)
5377+ au_h_open_post(dentry, cpg->bsrc, h_file);
5378+
5379+out:
1facf9fc 5380+ return err;
5381+}
5382+
c2b27bf2 5383+int au_sio_cpup_simple(struct au_cp_generic *cpg)
367653fa 5384+{
c2b27bf2
AM
5385+ aufs_bindex_t bsrc, bend;
5386+ struct dentry *dentry, *h_dentry;
367653fa 5387+
c2b27bf2
AM
5388+ if (cpg->bsrc < 0) {
5389+ dentry = cpg->dentry;
5390+ bend = au_dbend(dentry);
5391+ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) {
5392+ h_dentry = au_h_dptr(dentry, bsrc);
5393+ if (h_dentry) {
5394+ AuDebugOn(!h_dentry->d_inode);
5395+ break;
5396+ }
5397+ }
5398+ AuDebugOn(bsrc > bend);
5399+ cpg->bsrc = bsrc;
367653fa 5400+ }
c2b27bf2
AM
5401+ AuDebugOn(cpg->bsrc <= cpg->bdst);
5402+ return au_do_sio_cpup_simple(cpg);
5403+}
367653fa 5404+
c2b27bf2
AM
5405+int au_sio_cpdown_simple(struct au_cp_generic *cpg)
5406+{
5407+ AuDebugOn(cpg->bdst <= cpg->bsrc);
5408+ return au_do_sio_cpup_simple(cpg);
367653fa
AM
5409+}
5410+
1facf9fc 5411+/* ---------------------------------------------------------------------- */
5412+
5413+/*
5414+ * copyup the deleted file for writing.
5415+ */
c2b27bf2
AM
5416+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
5417+ struct file *file)
1facf9fc 5418+{
5419+ int err;
c2b27bf2
AM
5420+ unsigned int flags_orig;
5421+ aufs_bindex_t bsrc_orig;
1facf9fc 5422+ struct dentry *h_d_dst, *h_d_start;
c2b27bf2 5423+ struct au_dinfo *dinfo;
4a4d8108 5424+ struct au_hdentry *hdp;
1facf9fc 5425+
c2b27bf2 5426+ dinfo = au_di(cpg->dentry);
1308ab2a 5427+ AuRwMustWriteLock(&dinfo->di_rwsem);
5428+
c2b27bf2
AM
5429+ bsrc_orig = cpg->bsrc;
5430+ cpg->bsrc = dinfo->di_bstart;
4a4d8108 5431+ hdp = dinfo->di_hdentry;
c2b27bf2
AM
5432+ h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
5433+ dinfo->di_bstart = cpg->bdst;
5434+ hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
86dc4139 5435+ h_d_start = NULL;
027c5e7a 5436+ if (file) {
c2b27bf2
AM
5437+ h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
5438+ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_dentry;
027c5e7a 5439+ }
c2b27bf2
AM
5440+ flags_orig = cpg->flags;
5441+ cpg->flags = !AuCpup_DTIME;
5442+ err = au_cpup_single(cpg, /*h_parent*/NULL);
5443+ cpg->flags = flags_orig;
027c5e7a
AM
5444+ if (file) {
5445+ if (!err)
5446+ err = au_reopen_nondir(file);
c2b27bf2 5447+ hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
1facf9fc 5448+ }
c2b27bf2
AM
5449+ hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
5450+ dinfo->di_bstart = cpg->bsrc;
5451+ cpg->bsrc = bsrc_orig;
1facf9fc 5452+
5453+ return err;
5454+}
5455+
c2b27bf2 5456+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5457+{
5458+ int err;
c2b27bf2 5459+ aufs_bindex_t bdst;
1facf9fc 5460+ struct au_dtime dt;
c2b27bf2 5461+ struct dentry *dentry, *parent, *h_parent, *wh_dentry;
1facf9fc 5462+ struct au_branch *br;
5463+ struct path h_path;
5464+
c2b27bf2
AM
5465+ dentry = cpg->dentry;
5466+ bdst = cpg->bdst;
1facf9fc 5467+ br = au_sbr(dentry->d_sb, bdst);
5468+ parent = dget_parent(dentry);
5469+ h_parent = au_h_dptr(parent, bdst);
5470+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
5471+ err = PTR_ERR(wh_dentry);
5472+ if (IS_ERR(wh_dentry))
5473+ goto out;
5474+
5475+ h_path.dentry = h_parent;
86dc4139 5476+ h_path.mnt = au_br_mnt(br);
1facf9fc 5477+ au_dtime_store(&dt, parent, &h_path);
c2b27bf2 5478+ err = au_do_cpup_wh(cpg, wh_dentry, file);
1facf9fc 5479+ if (unlikely(err))
5480+ goto out_wh;
5481+
5482+ dget(wh_dentry);
5483+ h_path.dentry = wh_dentry;
523b37e3
AM
5484+ if (!S_ISDIR(wh_dentry->d_inode->i_mode)) {
5485+ /* no delegation since it is just created */
5486+ err = vfsub_unlink(h_parent->d_inode, &h_path,
5487+ /*delegated*/NULL, /*force*/0);
5488+ } else
4a4d8108 5489+ err = vfsub_rmdir(h_parent->d_inode, &h_path);
1facf9fc 5490+ if (unlikely(err)) {
523b37e3
AM
5491+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n",
5492+ wh_dentry, err);
1facf9fc 5493+ err = -EIO;
5494+ }
5495+ au_dtime_revert(&dt);
5496+ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry);
5497+
4f0767ce 5498+out_wh:
1facf9fc 5499+ dput(wh_dentry);
4f0767ce 5500+out:
1facf9fc 5501+ dput(parent);
5502+ return err;
5503+}
5504+
5505+struct au_cpup_wh_args {
5506+ int *errp;
c2b27bf2 5507+ struct au_cp_generic *cpg;
1facf9fc 5508+ struct file *file;
5509+};
5510+
5511+static void au_call_cpup_wh(void *args)
5512+{
5513+ struct au_cpup_wh_args *a = args;
86dc4139 5514+
c2b27bf2
AM
5515+ au_pin_hdir_acquire_nest(a->cpg->pin);
5516+ *a->errp = au_cpup_wh(a->cpg, a->file);
5517+ au_pin_hdir_release(a->cpg->pin);
1facf9fc 5518+}
5519+
c2b27bf2 5520+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file)
1facf9fc 5521+{
5522+ int err, wkq_err;
c2b27bf2 5523+ aufs_bindex_t bdst;
c1595e42 5524+ struct dentry *dentry, *parent, *h_orph, *h_parent;
86dc4139 5525+ struct inode *dir, *h_dir, *h_tmpdir;
1facf9fc 5526+ struct au_wbr *wbr;
c2b27bf2 5527+ struct au_pin wh_pin, *pin_orig;
1facf9fc 5528+
c2b27bf2
AM
5529+ dentry = cpg->dentry;
5530+ bdst = cpg->bdst;
1facf9fc 5531+ parent = dget_parent(dentry);
5532+ dir = parent->d_inode;
5533+ h_orph = NULL;
5534+ h_parent = NULL;
5535+ h_dir = au_igrab(au_h_iptr(dir, bdst));
5536+ h_tmpdir = h_dir;
c2b27bf2 5537+ pin_orig = NULL;
1facf9fc 5538+ if (!h_dir->i_nlink) {
5539+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr;
5540+ h_orph = wbr->wbr_orph;
5541+
5542+ h_parent = dget(au_h_dptr(parent, bdst));
1facf9fc 5543+ au_set_h_dptr(parent, bdst, dget(h_orph));
5544+ h_tmpdir = h_orph->d_inode;
1facf9fc 5545+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0);
5546+
dece6358 5547+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3);
4a4d8108 5548+ /* todo: au_h_open_pre()? */
86dc4139 5549+
c2b27bf2 5550+ pin_orig = cpg->pin;
86dc4139 5551+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT,
c2b27bf2
AM
5552+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED);
5553+ cpg->pin = &wh_pin;
1facf9fc 5554+ }
5555+
53392da6 5556+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE)
c2b27bf2
AM
5557+ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode))
5558+ err = au_cpup_wh(cpg, file);
1facf9fc 5559+ else {
5560+ struct au_cpup_wh_args args = {
5561+ .errp = &err,
c2b27bf2
AM
5562+ .cpg = cpg,
5563+ .file = file
1facf9fc 5564+ };
5565+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args);
5566+ if (unlikely(wkq_err))
5567+ err = wkq_err;
5568+ }
5569+
5570+ if (h_orph) {
5571+ mutex_unlock(&h_tmpdir->i_mutex);
4a4d8108 5572+ /* todo: au_h_open_post()? */
1facf9fc 5573+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0);
1facf9fc 5574+ au_set_h_dptr(parent, bdst, h_parent);
c2b27bf2
AM
5575+ AuDebugOn(!pin_orig);
5576+ cpg->pin = pin_orig;
1facf9fc 5577+ }
5578+ iput(h_dir);
5579+ dput(parent);
5580+
5581+ return err;
5582+}
5583+
5584+/* ---------------------------------------------------------------------- */
5585+
5586+/*
5587+ * generic routine for both of copy-up and copy-down.
5588+ */
5589+/* cf. revalidate function in file.c */
5590+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5591+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5592+ struct au_pin *pin,
1facf9fc 5593+ struct dentry *h_parent, void *arg),
5594+ void *arg)
5595+{
5596+ int err;
5597+ struct au_pin pin;
5598+ struct dentry *d, *parent, *h_parent, *real_parent;
5599+
5600+ err = 0;
5601+ parent = dget_parent(dentry);
5602+ if (IS_ROOT(parent))
5603+ goto out;
5604+
5605+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2,
5606+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE);
5607+
5608+ /* do not use au_dpage */
5609+ real_parent = parent;
5610+ while (1) {
5611+ dput(parent);
5612+ parent = dget_parent(dentry);
5613+ h_parent = au_h_dptr(parent, bdst);
5614+ if (h_parent)
5615+ goto out; /* success */
5616+
5617+ /* find top dir which is necessary to cpup */
5618+ do {
5619+ d = parent;
5620+ dput(parent);
5621+ parent = dget_parent(d);
5622+ di_read_lock_parent3(parent, !AuLock_IR);
5623+ h_parent = au_h_dptr(parent, bdst);
5624+ di_read_unlock(parent, !AuLock_IR);
5625+ } while (!h_parent);
5626+
5627+ if (d != real_parent)
5628+ di_write_lock_child3(d);
5629+
5630+ /* somebody else might create while we were sleeping */
5631+ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) {
5632+ if (au_h_dptr(d, bdst))
5633+ au_update_dbstart(d);
5634+
5635+ au_pin_set_dentry(&pin, d);
5636+ err = au_do_pin(&pin);
5637+ if (!err) {
86dc4139 5638+ err = cp(d, bdst, &pin, h_parent, arg);
1facf9fc 5639+ au_unpin(&pin);
5640+ }
5641+ }
5642+
5643+ if (d != real_parent)
5644+ di_write_unlock(d);
5645+ if (unlikely(err))
5646+ break;
5647+ }
5648+
4f0767ce 5649+out:
1facf9fc 5650+ dput(parent);
5651+ return err;
5652+}
5653+
5654+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5655+ struct au_pin *pin,
1facf9fc 5656+ struct dentry *h_parent __maybe_unused ,
5657+ void *arg __maybe_unused)
5658+{
c2b27bf2
AM
5659+ struct au_cp_generic cpg = {
5660+ .dentry = dentry,
5661+ .bdst = bdst,
5662+ .bsrc = -1,
5663+ .len = 0,
5664+ .pin = pin,
5665+ .flags = AuCpup_DTIME
5666+ };
5667+ return au_sio_cpup_simple(&cpg);
1facf9fc 5668+}
5669+
5670+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5671+{
5672+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL);
5673+}
5674+
5675+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst)
5676+{
5677+ int err;
5678+ struct dentry *parent;
5679+ struct inode *dir;
5680+
5681+ parent = dget_parent(dentry);
5682+ dir = parent->d_inode;
5683+ err = 0;
5684+ if (au_h_iptr(dir, bdst))
5685+ goto out;
5686+
5687+ di_read_unlock(parent, AuLock_IR);
5688+ di_write_lock_parent(parent);
5689+ /* someone else might change our inode while we were sleeping */
5690+ if (!au_h_iptr(dir, bdst))
5691+ err = au_cpup_dirs(dentry, bdst);
5692+ di_downgrade_lock(parent, AuLock_IR);
5693+
4f0767ce 5694+out:
1facf9fc 5695+ dput(parent);
5696+ return err;
5697+}
7f207e10
AM
5698diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h
5699--- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 5700+++ linux/fs/aufs/cpup.h 2015-01-25 13:00:38.631047076 +0100
523b37e3 5701@@ -0,0 +1,94 @@
1facf9fc 5702+/*
523b37e3 5703+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5704+ *
5705+ * This program, aufs is free software; you can redistribute it and/or modify
5706+ * it under the terms of the GNU General Public License as published by
5707+ * the Free Software Foundation; either version 2 of the License, or
5708+ * (at your option) any later version.
dece6358
AM
5709+ *
5710+ * This program is distributed in the hope that it will be useful,
5711+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5712+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5713+ * GNU General Public License for more details.
5714+ *
5715+ * You should have received a copy of the GNU General Public License
523b37e3 5716+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5717+ */
5718+
5719+/*
5720+ * copy-up/down functions
5721+ */
5722+
5723+#ifndef __AUFS_CPUP_H__
5724+#define __AUFS_CPUP_H__
5725+
5726+#ifdef __KERNEL__
5727+
dece6358 5728+#include <linux/path.h>
1facf9fc 5729+
dece6358
AM
5730+struct inode;
5731+struct file;
86dc4139 5732+struct au_pin;
dece6358 5733+
86dc4139 5734+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags);
1facf9fc 5735+void au_cpup_attr_timesizes(struct inode *inode);
5736+void au_cpup_attr_nlink(struct inode *inode, int force);
5737+void au_cpup_attr_changeable(struct inode *inode);
5738+void au_cpup_igen(struct inode *inode, struct inode *h_inode);
5739+void au_cpup_attr_all(struct inode *inode, int force);
5740+
5741+/* ---------------------------------------------------------------------- */
5742+
c2b27bf2
AM
5743+struct au_cp_generic {
5744+ struct dentry *dentry;
5745+ aufs_bindex_t bdst, bsrc;
5746+ loff_t len;
5747+ struct au_pin *pin;
5748+ unsigned int flags;
5749+};
5750+
1facf9fc 5751+/* cpup flags */
392086de
AM
5752+#define AuCpup_DTIME 1 /* do dtime_store/revert */
5753+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino,
5754+ for link(2) */
5755+#define AuCpup_RENAME (1 << 2) /* rename after cpup */
5756+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in
5757+ cpup */
5758+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the
5759+ existing entry */
5760+#define AuCpup_RWDST (1 << 5) /* force write target even if
5761+ the branch is marked as RO */
c2b27bf2 5762+
1facf9fc 5763+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name)
7f207e10
AM
5764+#define au_fset_cpup(flags, name) \
5765+ do { (flags) |= AuCpup_##name; } while (0)
5766+#define au_fclr_cpup(flags, name) \
5767+ do { (flags) &= ~AuCpup_##name; } while (0)
1facf9fc 5768+
5769+int au_copy_file(struct file *dst, struct file *src, loff_t len);
c2b27bf2
AM
5770+int au_sio_cpup_simple(struct au_cp_generic *cpg);
5771+int au_sio_cpdown_simple(struct au_cp_generic *cpg);
5772+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file);
1facf9fc 5773+
5774+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst,
5775+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 5776+ struct au_pin *pin,
1facf9fc 5777+ struct dentry *h_parent, void *arg),
5778+ void *arg);
5779+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5780+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst);
5781+
5782+/* ---------------------------------------------------------------------- */
5783+
5784+/* keep timestamps when copyup */
5785+struct au_dtime {
5786+ struct dentry *dt_dentry;
5787+ struct path dt_h_path;
5788+ struct timespec dt_atime, dt_mtime;
5789+};
5790+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry,
5791+ struct path *h_path);
5792+void au_dtime_revert(struct au_dtime *dt);
5793+
5794+#endif /* __KERNEL__ */
5795+#endif /* __AUFS_CPUP_H__ */
7f207e10
AM
5796diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
5797--- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 5798+++ linux/fs/aufs/dbgaufs.c 2015-01-25 13:00:38.631047076 +0100
523b37e3 5799@@ -0,0 +1,432 @@
1facf9fc 5800+/*
523b37e3 5801+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 5802+ *
5803+ * This program, aufs is free software; you can redistribute it and/or modify
5804+ * it under the terms of the GNU General Public License as published by
5805+ * the Free Software Foundation; either version 2 of the License, or
5806+ * (at your option) any later version.
dece6358
AM
5807+ *
5808+ * This program is distributed in the hope that it will be useful,
5809+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5810+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5811+ * GNU General Public License for more details.
5812+ *
5813+ * You should have received a copy of the GNU General Public License
523b37e3 5814+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 5815+ */
5816+
5817+/*
5818+ * debugfs interface
5819+ */
5820+
5821+#include <linux/debugfs.h>
5822+#include "aufs.h"
5823+
5824+#ifndef CONFIG_SYSFS
5825+#error DEBUG_FS depends upon SYSFS
5826+#endif
5827+
5828+static struct dentry *dbgaufs;
5829+static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH;
5830+
5831+/* 20 is max digits length of ulong 64 */
5832+struct dbgaufs_arg {
5833+ int n;
5834+ char a[20 * 4];
5835+};
5836+
5837+/*
5838+ * common function for all XINO files
5839+ */
5840+static int dbgaufs_xi_release(struct inode *inode __maybe_unused,
5841+ struct file *file)
5842+{
5843+ kfree(file->private_data);
5844+ return 0;
5845+}
5846+
5847+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt)
5848+{
5849+ int err;
5850+ struct kstat st;
5851+ struct dbgaufs_arg *p;
5852+
5853+ err = -ENOMEM;
5854+ p = kmalloc(sizeof(*p), GFP_NOFS);
5855+ if (unlikely(!p))
5856+ goto out;
5857+
5858+ err = 0;
5859+ p->n = 0;
5860+ file->private_data = p;
5861+ if (!xf)
5862+ goto out;
5863+
c06a8ce3 5864+ err = vfs_getattr(&xf->f_path, &st);
1facf9fc 5865+ if (!err) {
5866+ if (do_fcnt)
5867+ p->n = snprintf
5868+ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n",
5869+ (long)file_count(xf), st.blocks, st.blksize,
5870+ (long long)st.size);
5871+ else
5872+ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n",
5873+ st.blocks, st.blksize,
5874+ (long long)st.size);
5875+ AuDebugOn(p->n >= sizeof(p->a));
5876+ } else {
5877+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err);
5878+ err = 0;
5879+ }
5880+
4f0767ce 5881+out:
1facf9fc 5882+ return err;
5883+
5884+}
5885+
5886+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf,
5887+ size_t count, loff_t *ppos)
5888+{
5889+ struct dbgaufs_arg *p;
5890+
5891+ p = file->private_data;
5892+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5893+}
5894+
5895+/* ---------------------------------------------------------------------- */
5896+
86dc4139
AM
5897+struct dbgaufs_plink_arg {
5898+ int n;
5899+ char a[];
5900+};
5901+
5902+static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
5903+ struct file *file)
5904+{
5905+ free_page((unsigned long)file->private_data);
5906+ return 0;
5907+}
5908+
5909+static int dbgaufs_plink_open(struct inode *inode, struct file *file)
5910+{
5911+ int err, i, limit;
5912+ unsigned long n, sum;
5913+ struct dbgaufs_plink_arg *p;
5914+ struct au_sbinfo *sbinfo;
5915+ struct super_block *sb;
5916+ struct au_sphlhead *sphl;
5917+
5918+ err = -ENOMEM;
5919+ p = (void *)get_zeroed_page(GFP_NOFS);
5920+ if (unlikely(!p))
5921+ goto out;
5922+
5923+ err = -EFBIG;
5924+ sbinfo = inode->i_private;
5925+ sb = sbinfo->si_sb;
5926+ si_noflush_read_lock(sb);
5927+ if (au_opt_test(au_mntflags(sb), PLINK)) {
5928+ limit = PAGE_SIZE - sizeof(p->n);
5929+
5930+ /* the number of buckets */
5931+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH);
5932+ p->n += n;
5933+ limit -= n;
5934+
5935+ sum = 0;
5936+ for (i = 0, sphl = sbinfo->si_plink;
5937+ i < AuPlink_NHASH;
5938+ i++, sphl++) {
5939+ n = au_sphl_count(sphl);
5940+ sum += n;
5941+
5942+ n = snprintf(p->a + p->n, limit, "%lu ", n);
5943+ p->n += n;
5944+ limit -= n;
5945+ if (unlikely(limit <= 0))
5946+ goto out_free;
5947+ }
5948+ p->a[p->n - 1] = '\n';
5949+
5950+ /* the sum of plinks */
5951+ n = snprintf(p->a + p->n, limit, "%lu\n", sum);
5952+ p->n += n;
5953+ limit -= n;
5954+ if (unlikely(limit <= 0))
5955+ goto out_free;
5956+ } else {
5957+#define str "1\n0\n0\n"
5958+ p->n = sizeof(str) - 1;
5959+ strcpy(p->a, str);
5960+#undef str
5961+ }
5962+ si_read_unlock(sb);
5963+
5964+ err = 0;
5965+ file->private_data = p;
5966+ goto out; /* success */
5967+
5968+out_free:
5969+ free_page((unsigned long)p);
5970+out:
5971+ return err;
5972+}
5973+
5974+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf,
5975+ size_t count, loff_t *ppos)
5976+{
5977+ struct dbgaufs_plink_arg *p;
5978+
5979+ p = file->private_data;
5980+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n);
5981+}
5982+
5983+static const struct file_operations dbgaufs_plink_fop = {
5984+ .owner = THIS_MODULE,
5985+ .open = dbgaufs_plink_open,
5986+ .release = dbgaufs_plink_release,
5987+ .read = dbgaufs_plink_read
5988+};
5989+
5990+/* ---------------------------------------------------------------------- */
5991+
1facf9fc 5992+static int dbgaufs_xib_open(struct inode *inode, struct file *file)
5993+{
5994+ int err;
5995+ struct au_sbinfo *sbinfo;
5996+ struct super_block *sb;
5997+
5998+ sbinfo = inode->i_private;
5999+ sb = sbinfo->si_sb;
6000+ si_noflush_read_lock(sb);
6001+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0);
6002+ si_read_unlock(sb);
6003+ return err;
6004+}
6005+
6006+static const struct file_operations dbgaufs_xib_fop = {
4a4d8108 6007+ .owner = THIS_MODULE,
1facf9fc 6008+ .open = dbgaufs_xib_open,
6009+ .release = dbgaufs_xi_release,
6010+ .read = dbgaufs_xi_read
6011+};
6012+
6013+/* ---------------------------------------------------------------------- */
6014+
6015+#define DbgaufsXi_PREFIX "xi"
6016+
6017+static int dbgaufs_xino_open(struct inode *inode, struct file *file)
6018+{
6019+ int err;
6020+ long l;
6021+ struct au_sbinfo *sbinfo;
6022+ struct super_block *sb;
6023+ struct file *xf;
6024+ struct qstr *name;
6025+
6026+ err = -ENOENT;
6027+ xf = NULL;
6028+ name = &file->f_dentry->d_name;
6029+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX)
6030+ || memcmp(name->name, DbgaufsXi_PREFIX,
6031+ sizeof(DbgaufsXi_PREFIX) - 1)))
6032+ goto out;
9dbd164d 6033+ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l);
1facf9fc 6034+ if (unlikely(err))
6035+ goto out;
6036+
6037+ sbinfo = inode->i_private;
6038+ sb = sbinfo->si_sb;
6039+ si_noflush_read_lock(sb);
6040+ if (l <= au_sbend(sb)) {
6041+ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file;
6042+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1);
6043+ } else
6044+ err = -ENOENT;
6045+ si_read_unlock(sb);
6046+
4f0767ce 6047+out:
1facf9fc 6048+ return err;
6049+}
6050+
6051+static const struct file_operations dbgaufs_xino_fop = {
4a4d8108 6052+ .owner = THIS_MODULE,
1facf9fc 6053+ .open = dbgaufs_xino_open,
6054+ .release = dbgaufs_xi_release,
6055+ .read = dbgaufs_xi_read
6056+};
6057+
6058+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
6059+{
6060+ aufs_bindex_t bend;
6061+ struct au_branch *br;
6062+ struct au_xino_file *xi;
6063+
6064+ if (!au_sbi(sb)->si_dbgaufs)
6065+ return;
6066+
6067+ bend = au_sbend(sb);
6068+ for (; bindex <= bend; bindex++) {
6069+ br = au_sbr(sb, bindex);
6070+ xi = &br->br_xino;
c06a8ce3
AM
6071+ debugfs_remove(xi->xi_dbgaufs);
6072+ xi->xi_dbgaufs = NULL;
1facf9fc 6073+ }
6074+}
6075+
6076+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
6077+{
6078+ struct au_sbinfo *sbinfo;
6079+ struct dentry *parent;
6080+ struct au_branch *br;
6081+ struct au_xino_file *xi;
6082+ aufs_bindex_t bend;
6083+ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */
6084+
6085+ sbinfo = au_sbi(sb);
6086+ parent = sbinfo->si_dbgaufs;
6087+ if (!parent)
6088+ return;
6089+
6090+ bend = au_sbend(sb);
6091+ for (; bindex <= bend; bindex++) {
6092+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex);
6093+ br = au_sbr(sb, bindex);
6094+ xi = &br->br_xino;
6095+ AuDebugOn(xi->xi_dbgaufs);
6096+ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
6097+ sbinfo, &dbgaufs_xino_fop);
6098+ /* ignore an error */
6099+ if (unlikely(!xi->xi_dbgaufs))
6100+ AuWarn1("failed %s under debugfs\n", name);
6101+ }
6102+}
6103+
6104+/* ---------------------------------------------------------------------- */
6105+
6106+#ifdef CONFIG_AUFS_EXPORT
6107+static int dbgaufs_xigen_open(struct inode *inode, struct file *file)
6108+{
6109+ int err;
6110+ struct au_sbinfo *sbinfo;
6111+ struct super_block *sb;
6112+
6113+ sbinfo = inode->i_private;
6114+ sb = sbinfo->si_sb;
6115+ si_noflush_read_lock(sb);
6116+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0);
6117+ si_read_unlock(sb);
6118+ return err;
6119+}
6120+
6121+static const struct file_operations dbgaufs_xigen_fop = {
4a4d8108 6122+ .owner = THIS_MODULE,
1facf9fc 6123+ .open = dbgaufs_xigen_open,
6124+ .release = dbgaufs_xi_release,
6125+ .read = dbgaufs_xi_read
6126+};
6127+
6128+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6129+{
6130+ int err;
6131+
dece6358 6132+ /*
c1595e42 6133+ * This function is a dynamic '__init' function actually,
dece6358
AM
6134+ * so the tiny check for si_rwsem is unnecessary.
6135+ */
6136+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6137+
1facf9fc 6138+ err = -EIO;
6139+ sbinfo->si_dbgaufs_xigen = debugfs_create_file
6140+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6141+ &dbgaufs_xigen_fop);
6142+ if (sbinfo->si_dbgaufs_xigen)
6143+ err = 0;
6144+
6145+ return err;
6146+}
6147+#else
6148+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo)
6149+{
6150+ return 0;
6151+}
6152+#endif /* CONFIG_AUFS_EXPORT */
6153+
6154+/* ---------------------------------------------------------------------- */
6155+
6156+void dbgaufs_si_fin(struct au_sbinfo *sbinfo)
6157+{
dece6358 6158+ /*
c1595e42 6159+ * This function is a dynamic '__init' function actually,
dece6358
AM
6160+ * so the tiny check for si_rwsem is unnecessary.
6161+ */
6162+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6163+
1facf9fc 6164+ debugfs_remove_recursive(sbinfo->si_dbgaufs);
6165+ sbinfo->si_dbgaufs = NULL;
6166+ kobject_put(&sbinfo->si_kobj);
6167+}
6168+
6169+int dbgaufs_si_init(struct au_sbinfo *sbinfo)
6170+{
6171+ int err;
6172+ char name[SysaufsSiNameLen];
6173+
dece6358 6174+ /*
c1595e42 6175+ * This function is a dynamic '__init' function actually,
dece6358
AM
6176+ * so the tiny check for si_rwsem is unnecessary.
6177+ */
6178+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
6179+
1facf9fc 6180+ err = -ENOENT;
6181+ if (!dbgaufs) {
6182+ AuErr1("/debug/aufs is uninitialized\n");
6183+ goto out;
6184+ }
6185+
6186+ err = -EIO;
6187+ sysaufs_name(sbinfo, name);
6188+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs);
6189+ if (unlikely(!sbinfo->si_dbgaufs))
6190+ goto out;
6191+ kobject_get(&sbinfo->si_kobj);
6192+
6193+ sbinfo->si_dbgaufs_xib = debugfs_create_file
6194+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6195+ &dbgaufs_xib_fop);
6196+ if (unlikely(!sbinfo->si_dbgaufs_xib))
6197+ goto out_dir;
6198+
86dc4139
AM
6199+ sbinfo->si_dbgaufs_plink = debugfs_create_file
6200+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo,
6201+ &dbgaufs_plink_fop);
6202+ if (unlikely(!sbinfo->si_dbgaufs_plink))
6203+ goto out_dir;
6204+
1facf9fc 6205+ err = dbgaufs_xigen_init(sbinfo);
6206+ if (!err)
6207+ goto out; /* success */
6208+
4f0767ce 6209+out_dir:
1facf9fc 6210+ dbgaufs_si_fin(sbinfo);
4f0767ce 6211+out:
1facf9fc 6212+ return err;
6213+}
6214+
6215+/* ---------------------------------------------------------------------- */
6216+
6217+void dbgaufs_fin(void)
6218+{
6219+ debugfs_remove(dbgaufs);
6220+}
6221+
6222+int __init dbgaufs_init(void)
6223+{
6224+ int err;
6225+
6226+ err = -EIO;
6227+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL);
6228+ if (dbgaufs)
6229+ err = 0;
6230+ return err;
6231+}
7f207e10
AM
6232diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h
6233--- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 6234+++ linux/fs/aufs/dbgaufs.h 2015-01-25 13:00:38.631047076 +0100
523b37e3 6235@@ -0,0 +1,48 @@
1facf9fc 6236+/*
523b37e3 6237+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6238+ *
6239+ * This program, aufs is free software; you can redistribute it and/or modify
6240+ * it under the terms of the GNU General Public License as published by
6241+ * the Free Software Foundation; either version 2 of the License, or
6242+ * (at your option) any later version.
dece6358
AM
6243+ *
6244+ * This program is distributed in the hope that it will be useful,
6245+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6246+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6247+ * GNU General Public License for more details.
6248+ *
6249+ * You should have received a copy of the GNU General Public License
523b37e3 6250+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6251+ */
6252+
6253+/*
6254+ * debugfs interface
6255+ */
6256+
6257+#ifndef __DBGAUFS_H__
6258+#define __DBGAUFS_H__
6259+
6260+#ifdef __KERNEL__
6261+
dece6358 6262+struct super_block;
1facf9fc 6263+struct au_sbinfo;
dece6358 6264+
1facf9fc 6265+#ifdef CONFIG_DEBUG_FS
6266+/* dbgaufs.c */
6267+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
6268+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
6269+void dbgaufs_si_fin(struct au_sbinfo *sbinfo);
6270+int dbgaufs_si_init(struct au_sbinfo *sbinfo);
6271+void dbgaufs_fin(void);
6272+int __init dbgaufs_init(void);
1facf9fc 6273+#else
4a4d8108
AM
6274+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
6275+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
6276+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo)
6277+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo)
6278+AuStubVoid(dbgaufs_fin, void)
6279+AuStubInt0(__init dbgaufs_init, void)
1facf9fc 6280+#endif /* CONFIG_DEBUG_FS */
6281+
6282+#endif /* __KERNEL__ */
6283+#endif /* __DBGAUFS_H__ */
7f207e10
AM
6284diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
6285--- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
6286+++ linux/fs/aufs/dcsub.c 2015-01-25 13:00:38.631047076 +0100
6287@@ -0,0 +1,224 @@
1facf9fc 6288+/*
523b37e3 6289+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6290+ *
6291+ * This program, aufs is free software; you can redistribute it and/or modify
6292+ * it under the terms of the GNU General Public License as published by
6293+ * the Free Software Foundation; either version 2 of the License, or
6294+ * (at your option) any later version.
dece6358
AM
6295+ *
6296+ * This program is distributed in the hope that it will be useful,
6297+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6298+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6299+ * GNU General Public License for more details.
6300+ *
6301+ * You should have received a copy of the GNU General Public License
523b37e3 6302+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6303+ */
6304+
6305+/*
6306+ * sub-routines for dentry cache
6307+ */
6308+
6309+#include "aufs.h"
6310+
6311+static void au_dpage_free(struct au_dpage *dpage)
6312+{
6313+ int i;
6314+ struct dentry **p;
6315+
6316+ p = dpage->dentries;
6317+ for (i = 0; i < dpage->ndentry; i++)
6318+ dput(*p++);
6319+ free_page((unsigned long)dpage->dentries);
6320+}
6321+
6322+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
6323+{
6324+ int err;
6325+ void *p;
6326+
6327+ err = -ENOMEM;
6328+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp);
6329+ if (unlikely(!dpages->dpages))
6330+ goto out;
6331+
6332+ p = (void *)__get_free_page(gfp);
6333+ if (unlikely(!p))
6334+ goto out_dpages;
6335+
6336+ dpages->dpages[0].ndentry = 0;
6337+ dpages->dpages[0].dentries = p;
6338+ dpages->ndpage = 1;
6339+ return 0; /* success */
6340+
4f0767ce 6341+out_dpages:
1facf9fc 6342+ kfree(dpages->dpages);
4f0767ce 6343+out:
1facf9fc 6344+ return err;
6345+}
6346+
6347+void au_dpages_free(struct au_dcsub_pages *dpages)
6348+{
6349+ int i;
6350+ struct au_dpage *p;
6351+
6352+ p = dpages->dpages;
6353+ for (i = 0; i < dpages->ndpage; i++)
6354+ au_dpage_free(p++);
6355+ kfree(dpages->dpages);
6356+}
6357+
6358+static int au_dpages_append(struct au_dcsub_pages *dpages,
6359+ struct dentry *dentry, gfp_t gfp)
6360+{
6361+ int err, sz;
6362+ struct au_dpage *dpage;
6363+ void *p;
6364+
6365+ dpage = dpages->dpages + dpages->ndpage - 1;
6366+ sz = PAGE_SIZE / sizeof(dentry);
6367+ if (unlikely(dpage->ndentry >= sz)) {
6368+ AuLabel(new dpage);
6369+ err = -ENOMEM;
6370+ sz = dpages->ndpage * sizeof(*dpages->dpages);
6371+ p = au_kzrealloc(dpages->dpages, sz,
6372+ sz + sizeof(*dpages->dpages), gfp);
6373+ if (unlikely(!p))
6374+ goto out;
6375+
6376+ dpages->dpages = p;
6377+ dpage = dpages->dpages + dpages->ndpage;
6378+ p = (void *)__get_free_page(gfp);
6379+ if (unlikely(!p))
6380+ goto out;
6381+
6382+ dpage->ndentry = 0;
6383+ dpage->dentries = p;
6384+ dpages->ndpage++;
6385+ }
6386+
c1595e42 6387+ AuDebugOn(au_dcount(dentry) <= 0);
027c5e7a 6388+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry);
1facf9fc 6389+ return 0; /* success */
6390+
4f0767ce 6391+out:
1facf9fc 6392+ return err;
6393+}
6394+
c1595e42
JR
6395+/* todo: BAD approach */
6396+/* copied from linux/fs/dcache.c */
6397+enum d_walk_ret {
6398+ D_WALK_CONTINUE,
6399+ D_WALK_QUIT,
6400+ D_WALK_NORETRY,
6401+ D_WALK_SKIP,
6402+};
6403+
6404+extern void d_walk(struct dentry *parent, void *data,
6405+ enum d_walk_ret (*enter)(void *, struct dentry *),
6406+ void (*finish)(void *));
6407+
6408+struct ac_dpages_arg {
1facf9fc 6409+ int err;
c1595e42
JR
6410+ struct au_dcsub_pages *dpages;
6411+ struct super_block *sb;
6412+ au_dpages_test test;
6413+ void *arg;
6414+};
1facf9fc 6415+
c1595e42
JR
6416+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry)
6417+{
6418+ enum d_walk_ret ret;
6419+ struct ac_dpages_arg *arg = _arg;
1facf9fc 6420+
c1595e42
JR
6421+ ret = D_WALK_CONTINUE;
6422+ if (dentry->d_sb == arg->sb
6423+ && !IS_ROOT(dentry)
6424+ && au_dcount(dentry) > 0
6425+ && au_di(dentry)
6426+ && (!arg->test || arg->test(dentry, arg->arg))) {
6427+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC);
6428+ if (unlikely(arg->err))
6429+ ret = D_WALK_QUIT;
1facf9fc 6430+ }
6431+
c1595e42
JR
6432+ return ret;
6433+}
027c5e7a 6434+
c1595e42
JR
6435+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6436+ au_dpages_test test, void *arg)
6437+{
6438+ struct ac_dpages_arg args = {
6439+ .err = 0,
6440+ .dpages = dpages,
6441+ .sb = root->d_sb,
6442+ .test = test,
6443+ .arg = arg
6444+ };
027c5e7a 6445+
c1595e42
JR
6446+ d_walk(root, &args, au_call_dpages_append, NULL);
6447+
6448+ return args.err;
1facf9fc 6449+}
6450+
6451+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6452+ int do_include, au_dpages_test test, void *arg)
6453+{
6454+ int err;
6455+
6456+ err = 0;
027c5e7a
AM
6457+ write_seqlock(&rename_lock);
6458+ spin_lock(&dentry->d_lock);
6459+ if (do_include
c1595e42 6460+ && au_dcount(dentry) > 0
027c5e7a 6461+ && (!test || test(dentry, arg)))
1facf9fc 6462+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6463+ spin_unlock(&dentry->d_lock);
6464+ if (unlikely(err))
6465+ goto out;
6466+
6467+ /*
523b37e3 6468+ * RCU for vfsmount is unnecessary since this is a traverse in a single
027c5e7a
AM
6469+ * mount
6470+ */
1facf9fc 6471+ while (!IS_ROOT(dentry)) {
027c5e7a
AM
6472+ dentry = dentry->d_parent; /* rename_lock is locked */
6473+ spin_lock(&dentry->d_lock);
c1595e42 6474+ if (au_dcount(dentry) > 0
027c5e7a 6475+ && (!test || test(dentry, arg)))
1facf9fc 6476+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC);
027c5e7a
AM
6477+ spin_unlock(&dentry->d_lock);
6478+ if (unlikely(err))
6479+ break;
1facf9fc 6480+ }
6481+
4f0767ce 6482+out:
027c5e7a 6483+ write_sequnlock(&rename_lock);
1facf9fc 6484+ return err;
6485+}
6486+
027c5e7a
AM
6487+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg)
6488+{
6489+ return au_di(dentry) && dentry->d_sb == arg;
6490+}
6491+
6492+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6493+ struct dentry *dentry, int do_include)
6494+{
6495+ return au_dcsub_pages_rev(dpages, dentry, do_include,
6496+ au_dcsub_dpages_aufs, dentry->d_sb);
6497+}
6498+
4a4d8108 6499+int au_test_subdir(struct dentry *d1, struct dentry *d2)
1facf9fc 6500+{
4a4d8108
AM
6501+ struct path path[2] = {
6502+ {
6503+ .dentry = d1
6504+ },
6505+ {
6506+ .dentry = d2
6507+ }
6508+ };
1facf9fc 6509+
4a4d8108 6510+ return path_is_under(path + 0, path + 1);
1facf9fc 6511+}
7f207e10
AM
6512diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h
6513--- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
6514+++ linux/fs/aufs/dcsub.h 2015-01-25 13:00:38.631047076 +0100
6515@@ -0,0 +1,125 @@
1facf9fc 6516+/*
523b37e3 6517+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6518+ *
6519+ * This program, aufs is free software; you can redistribute it and/or modify
6520+ * it under the terms of the GNU General Public License as published by
6521+ * the Free Software Foundation; either version 2 of the License, or
6522+ * (at your option) any later version.
dece6358
AM
6523+ *
6524+ * This program is distributed in the hope that it will be useful,
6525+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6526+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6527+ * GNU General Public License for more details.
6528+ *
6529+ * You should have received a copy of the GNU General Public License
523b37e3 6530+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6531+ */
6532+
6533+/*
6534+ * sub-routines for dentry cache
6535+ */
6536+
6537+#ifndef __AUFS_DCSUB_H__
6538+#define __AUFS_DCSUB_H__
6539+
6540+#ifdef __KERNEL__
6541+
7f207e10 6542+#include <linux/dcache.h>
027c5e7a 6543+#include <linux/fs.h>
dece6358
AM
6544+
6545+struct dentry;
1facf9fc 6546+
6547+struct au_dpage {
6548+ int ndentry;
6549+ struct dentry **dentries;
6550+};
6551+
6552+struct au_dcsub_pages {
6553+ int ndpage;
6554+ struct au_dpage *dpages;
6555+};
6556+
6557+/* ---------------------------------------------------------------------- */
6558+
7f207e10 6559+/* dcsub.c */
1facf9fc 6560+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp);
6561+void au_dpages_free(struct au_dcsub_pages *dpages);
6562+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg);
6563+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root,
6564+ au_dpages_test test, void *arg);
6565+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry,
6566+ int do_include, au_dpages_test test, void *arg);
027c5e7a
AM
6567+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages,
6568+ struct dentry *dentry, int do_include);
4a4d8108 6569+int au_test_subdir(struct dentry *d1, struct dentry *d2);
1facf9fc 6570+
7f207e10
AM
6571+/* ---------------------------------------------------------------------- */
6572+
523b37e3
AM
6573+/*
6574+ * todo: in linux-3.13, several similar (but faster) helpers are added to
6575+ * include/linux/dcache.h. Try them (in the future).
6576+ */
6577+
027c5e7a
AM
6578+static inline int au_d_hashed_positive(struct dentry *d)
6579+{
6580+ int err;
6581+ struct inode *inode = d->d_inode;
076b876e 6582+
027c5e7a
AM
6583+ err = 0;
6584+ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink))
6585+ err = -ENOENT;
6586+ return err;
6587+}
6588+
38d290e6
JR
6589+static inline int au_d_linkable(struct dentry *d)
6590+{
6591+ int err;
6592+ struct inode *inode = d->d_inode;
076b876e 6593+
38d290e6
JR
6594+ err = au_d_hashed_positive(d);
6595+ if (err
6596+ && inode
6597+ && (inode->i_state & I_LINKABLE))
6598+ err = 0;
6599+ return err;
6600+}
6601+
027c5e7a
AM
6602+static inline int au_d_alive(struct dentry *d)
6603+{
6604+ int err;
6605+ struct inode *inode;
076b876e 6606+
027c5e7a
AM
6607+ err = 0;
6608+ if (!IS_ROOT(d))
6609+ err = au_d_hashed_positive(d);
6610+ else {
6611+ inode = d->d_inode;
6612+ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink))
6613+ err = -ENOENT;
6614+ }
6615+ return err;
6616+}
6617+
6618+static inline int au_alive_dir(struct dentry *d)
7f207e10 6619+{
027c5e7a 6620+ int err;
076b876e 6621+
027c5e7a
AM
6622+ err = au_d_alive(d);
6623+ if (unlikely(err || IS_DEADDIR(d->d_inode)))
6624+ err = -ENOENT;
6625+ return err;
7f207e10
AM
6626+}
6627+
38d290e6
JR
6628+static inline int au_qstreq(struct qstr *a, struct qstr *b)
6629+{
6630+ return a->len == b->len
6631+ && !memcmp(a->name, b->name, a->len);
6632+}
6633+
c1595e42
JR
6634+static inline int au_dcount(struct dentry *d)
6635+{
6636+ return (int)d_count(d);
6637+}
6638+
1facf9fc 6639+#endif /* __KERNEL__ */
6640+#endif /* __AUFS_DCSUB_H__ */
7f207e10
AM
6641diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
6642--- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
6643+++ linux/fs/aufs/debug.c 2015-01-25 13:00:38.631047076 +0100
6644@@ -0,0 +1,520 @@
1facf9fc 6645+/*
523b37e3 6646+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 6647+ *
6648+ * This program, aufs is free software; you can redistribute it and/or modify
6649+ * it under the terms of the GNU General Public License as published by
6650+ * the Free Software Foundation; either version 2 of the License, or
6651+ * (at your option) any later version.
dece6358
AM
6652+ *
6653+ * This program is distributed in the hope that it will be useful,
6654+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6655+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6656+ * GNU General Public License for more details.
6657+ *
6658+ * You should have received a copy of the GNU General Public License
523b37e3 6659+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 6660+ */
6661+
6662+/*
6663+ * debug print functions
6664+ */
6665+
7f207e10 6666+#include <linux/vt_kern.h>
1facf9fc 6667+#include "aufs.h"
6668+
392086de
AM
6669+/* Returns 0, or -errno. arg is in kp->arg. */
6670+static int param_atomic_t_set(const char *val, const struct kernel_param *kp)
6671+{
6672+ int err, n;
6673+
6674+ err = kstrtoint(val, 0, &n);
6675+ if (!err) {
6676+ if (n > 0)
6677+ au_debug_on();
6678+ else
6679+ au_debug_off();
6680+ }
6681+ return err;
6682+}
6683+
6684+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
6685+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp)
6686+{
6687+ atomic_t *a;
6688+
6689+ a = kp->arg;
6690+ return sprintf(buffer, "%d", atomic_read(a));
6691+}
6692+
6693+static struct kernel_param_ops param_ops_atomic_t = {
6694+ .set = param_atomic_t_set,
6695+ .get = param_atomic_t_get
6696+ /* void (*free)(void *arg) */
6697+};
6698+
6699+atomic_t aufs_debug = ATOMIC_INIT(0);
1facf9fc 6700+MODULE_PARM_DESC(debug, "debug print");
392086de 6701+module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP);
1facf9fc 6702+
c1595e42 6703+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */
1facf9fc 6704+char *au_plevel = KERN_DEBUG;
e49829fe
JR
6705+#define dpri(fmt, ...) do { \
6706+ if ((au_plevel \
6707+ && strcmp(au_plevel, KERN_DEBUG)) \
6708+ || au_debug_test()) \
6709+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \
1facf9fc 6710+} while (0)
6711+
6712+/* ---------------------------------------------------------------------- */
6713+
6714+void au_dpri_whlist(struct au_nhash *whlist)
6715+{
6716+ unsigned long ul, n;
6717+ struct hlist_head *head;
c06a8ce3 6718+ struct au_vdir_wh *pos;
1facf9fc 6719+
6720+ n = whlist->nh_num;
6721+ head = whlist->nh_head;
6722+ for (ul = 0; ul < n; ul++) {
c06a8ce3 6723+ hlist_for_each_entry(pos, head, wh_hash)
1facf9fc 6724+ dpri("b%d, %.*s, %d\n",
c06a8ce3
AM
6725+ pos->wh_bindex,
6726+ pos->wh_str.len, pos->wh_str.name,
6727+ pos->wh_str.len);
1facf9fc 6728+ head++;
6729+ }
6730+}
6731+
6732+void au_dpri_vdir(struct au_vdir *vdir)
6733+{
6734+ unsigned long ul;
6735+ union au_vdir_deblk_p p;
6736+ unsigned char *o;
6737+
6738+ if (!vdir || IS_ERR(vdir)) {
6739+ dpri("err %ld\n", PTR_ERR(vdir));
6740+ return;
6741+ }
6742+
6743+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n",
6744+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk,
6745+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version);
6746+ for (ul = 0; ul < vdir->vd_nblk; ul++) {
6747+ p.deblk = vdir->vd_deblk[ul];
6748+ o = p.deblk;
6749+ dpri("[%lu]: %p\n", ul, o);
6750+ }
6751+}
6752+
53392da6 6753+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn,
1facf9fc 6754+ struct dentry *wh)
6755+{
6756+ char *n = NULL;
6757+ int l = 0;
6758+
6759+ if (!inode || IS_ERR(inode)) {
6760+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode));
6761+ return -1;
6762+ }
6763+
c2b27bf2 6764+ /* the type of i_blocks depends upon CONFIG_LBDAF */
1facf9fc 6765+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long)
6766+ && sizeof(inode->i_blocks) != sizeof(u64));
6767+ if (wh) {
6768+ n = (void *)wh->d_name.name;
6769+ l = wh->d_name.len;
6770+ }
6771+
53392da6
AM
6772+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu,"
6773+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n",
6774+ bindex, inode,
1facf9fc 6775+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??",
6776+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode,
6777+ i_size_read(inode), (unsigned long long)inode->i_blocks,
53392da6 6778+ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff,
1facf9fc 6779+ inode->i_mapping ? inode->i_mapping->nrpages : 0,
b752ccd1
AM
6780+ inode->i_state, inode->i_flags, inode->i_version,
6781+ inode->i_generation,
1facf9fc 6782+ l ? ", wh " : "", l, n);
6783+ return 0;
6784+}
6785+
6786+void au_dpri_inode(struct inode *inode)
6787+{
6788+ struct au_iinfo *iinfo;
6789+ aufs_bindex_t bindex;
53392da6 6790+ int err, hn;
1facf9fc 6791+
53392da6 6792+ err = do_pri_inode(-1, inode, -1, NULL);
1facf9fc 6793+ if (err || !au_test_aufs(inode->i_sb))
6794+ return;
6795+
6796+ iinfo = au_ii(inode);
6797+ if (!iinfo)
6798+ return;
6799+ dpri("i-1: bstart %d, bend %d, gen %d\n",
537831f9 6800+ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL));
1facf9fc 6801+ if (iinfo->ii_bstart < 0)
6802+ return;
53392da6
AM
6803+ hn = 0;
6804+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) {
6805+ hn = !!au_hn(iinfo->ii_hinode + bindex);
6806+ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn,
1facf9fc 6807+ iinfo->ii_hinode[0 + bindex].hi_whdentry);
53392da6 6808+ }
1facf9fc 6809+}
6810+
2cbb1c4b
JR
6811+void au_dpri_dalias(struct inode *inode)
6812+{
6813+ struct dentry *d;
6814+
6815+ spin_lock(&inode->i_lock);
c1595e42 6816+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias)
2cbb1c4b
JR
6817+ au_dpri_dentry(d);
6818+ spin_unlock(&inode->i_lock);
6819+}
6820+
1facf9fc 6821+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
6822+{
6823+ struct dentry *wh = NULL;
53392da6 6824+ int hn;
076b876e 6825+ struct au_iinfo *iinfo;
1facf9fc 6826+
6827+ if (!dentry || IS_ERR(dentry)) {
6828+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry));
6829+ return -1;
6830+ }
6831+ /* do not call dget_parent() here */
027c5e7a 6832+ /* note: access d_xxx without d_lock */
523b37e3
AM
6833+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n",
6834+ bindex, dentry, dentry,
1facf9fc 6835+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??",
c1595e42 6836+ au_dcount(dentry), dentry->d_flags,
523b37e3 6837+ d_unhashed(dentry) ? "un" : "");
53392da6 6838+ hn = -1;
1facf9fc 6839+ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) {
076b876e 6840+ iinfo = au_ii(dentry->d_inode);
53392da6
AM
6841+ if (iinfo) {
6842+ hn = !!au_hn(iinfo->ii_hinode + bindex);
1facf9fc 6843+ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry;
53392da6 6844+ }
1facf9fc 6845+ }
53392da6 6846+ do_pri_inode(bindex, dentry->d_inode, hn, wh);
1facf9fc 6847+ return 0;
6848+}
6849+
6850+void au_dpri_dentry(struct dentry *dentry)
6851+{
6852+ struct au_dinfo *dinfo;
6853+ aufs_bindex_t bindex;
6854+ int err;
4a4d8108 6855+ struct au_hdentry *hdp;
1facf9fc 6856+
6857+ err = do_pri_dentry(-1, dentry);
6858+ if (err || !au_test_aufs(dentry->d_sb))
6859+ return;
6860+
6861+ dinfo = au_di(dentry);
6862+ if (!dinfo)
6863+ return;
38d290e6 6864+ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d, tmp %d\n",
1facf9fc 6865+ dinfo->di_bstart, dinfo->di_bend,
38d290e6
JR
6866+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry),
6867+ dinfo->di_tmpfile);
1facf9fc 6868+ if (dinfo->di_bstart < 0)
6869+ return;
4a4d8108 6870+ hdp = dinfo->di_hdentry;
1facf9fc 6871+ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++)
4a4d8108 6872+ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
1facf9fc 6873+}
6874+
6875+static int do_pri_file(aufs_bindex_t bindex, struct file *file)
6876+{
6877+ char a[32];
6878+
6879+ if (!file || IS_ERR(file)) {
6880+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file));
6881+ return -1;
6882+ }
6883+ a[0] = 0;
6884+ if (bindex < 0
6885+ && file->f_dentry
6886+ && au_test_aufs(file->f_dentry->d_sb)
6887+ && au_fi(file))
e49829fe 6888+ snprintf(a, sizeof(a), ", gen %d, mmapped %d",
2cbb1c4b 6889+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped));
b752ccd1 6890+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n",
1facf9fc 6891+ bindex, file->f_mode, file->f_flags, (long)file_count(file),
b752ccd1 6892+ file->f_version, file->f_pos, a);
1facf9fc 6893+ if (file->f_dentry)
6894+ do_pri_dentry(bindex, file->f_dentry);
6895+ return 0;
6896+}
6897+
6898+void au_dpri_file(struct file *file)
6899+{
6900+ struct au_finfo *finfo;
4a4d8108
AM
6901+ struct au_fidir *fidir;
6902+ struct au_hfile *hfile;
1facf9fc 6903+ aufs_bindex_t bindex;
6904+ int err;
6905+
6906+ err = do_pri_file(-1, file);
6907+ if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb))
6908+ return;
6909+
6910+ finfo = au_fi(file);
6911+ if (!finfo)
6912+ return;
4a4d8108 6913+ if (finfo->fi_btop < 0)
1facf9fc 6914+ return;
4a4d8108
AM
6915+ fidir = finfo->fi_hdir;
6916+ if (!fidir)
6917+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file);
6918+ else
e49829fe
JR
6919+ for (bindex = finfo->fi_btop;
6920+ bindex >= 0 && bindex <= fidir->fd_bbot;
4a4d8108
AM
6921+ bindex++) {
6922+ hfile = fidir->fd_hfile + bindex;
6923+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL);
6924+ }
1facf9fc 6925+}
6926+
6927+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br)
6928+{
6929+ struct vfsmount *mnt;
6930+ struct super_block *sb;
6931+
6932+ if (!br || IS_ERR(br))
6933+ goto out;
86dc4139 6934+ mnt = au_br_mnt(br);
1facf9fc 6935+ if (!mnt || IS_ERR(mnt))
6936+ goto out;
6937+ sb = mnt->mnt_sb;
6938+ if (!sb || IS_ERR(sb))
6939+ goto out;
6940+
1e00d052 6941+ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, "
b752ccd1 6942+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, "
1facf9fc 6943+ "xino %d\n",
1e00d052
AM
6944+ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count),
6945+ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev),
b752ccd1 6946+ sb->s_flags, sb->s_count,
1facf9fc 6947+ atomic_read(&sb->s_active), !!br->br_xino.xi_file);
6948+ return 0;
6949+
4f0767ce 6950+out:
1facf9fc 6951+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br));
6952+ return -1;
6953+}
6954+
6955+void au_dpri_sb(struct super_block *sb)
6956+{
6957+ struct au_sbinfo *sbinfo;
6958+ aufs_bindex_t bindex;
6959+ int err;
6960+ /* to reuduce stack size */
6961+ struct {
6962+ struct vfsmount mnt;
6963+ struct au_branch fake;
6964+ } *a;
6965+
6966+ /* this function can be called from magic sysrq */
6967+ a = kzalloc(sizeof(*a), GFP_ATOMIC);
6968+ if (unlikely(!a)) {
6969+ dpri("no memory\n");
6970+ return;
6971+ }
6972+
6973+ a->mnt.mnt_sb = sb;
6974+ a->fake.br_perm = 0;
86dc4139 6975+ a->fake.br_path.mnt = &a->mnt;
1facf9fc 6976+ a->fake.br_xino.xi_file = NULL;
6977+ atomic_set(&a->fake.br_count, 0);
6978+ smp_mb(); /* atomic_set */
6979+ err = do_pri_br(-1, &a->fake);
6980+ kfree(a);
6981+ dpri("dev 0x%x\n", sb->s_dev);
6982+ if (err || !au_test_aufs(sb))
6983+ return;
6984+
6985+ sbinfo = au_sbi(sb);
6986+ if (!sbinfo)
6987+ return;
6988+ dpri("nw %d, gen %u, kobj %d\n",
6989+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
6990+ atomic_read(&sbinfo->si_kobj.kref.refcount));
6991+ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++)
6992+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
6993+}
6994+
6995+/* ---------------------------------------------------------------------- */
6996+
6997+void au_dbg_sleep_jiffy(int jiffy)
6998+{
6999+ while (jiffy)
7000+ jiffy = schedule_timeout_uninterruptible(jiffy);
7001+}
7002+
7003+void au_dbg_iattr(struct iattr *ia)
7004+{
c06a8ce3
AM
7005+#define AuBit(name) \
7006+ do { \
7007+ if (ia->ia_valid & ATTR_ ## name) \
7008+ dpri(#name "\n"); \
7009+ } while (0)
1facf9fc 7010+ AuBit(MODE);
7011+ AuBit(UID);
7012+ AuBit(GID);
7013+ AuBit(SIZE);
7014+ AuBit(ATIME);
7015+ AuBit(MTIME);
7016+ AuBit(CTIME);
7017+ AuBit(ATIME_SET);
7018+ AuBit(MTIME_SET);
7019+ AuBit(FORCE);
7020+ AuBit(ATTR_FLAG);
7021+ AuBit(KILL_SUID);
7022+ AuBit(KILL_SGID);
7023+ AuBit(FILE);
7024+ AuBit(KILL_PRIV);
7025+ AuBit(OPEN);
7026+ AuBit(TIMES_SET);
7027+#undef AuBit
7028+ dpri("ia_file %p\n", ia->ia_file);
7029+}
7030+
7031+/* ---------------------------------------------------------------------- */
7032+
027c5e7a
AM
7033+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line)
7034+{
7035+ struct inode *h_inode, *inode = dentry->d_inode;
7036+ struct dentry *h_dentry;
7037+ aufs_bindex_t bindex, bend, bi;
7038+
7039+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */)
7040+ return;
7041+
7042+ bend = au_dbend(dentry);
7043+ bi = au_ibend(inode);
7044+ if (bi < bend)
7045+ bend = bi;
7046+ bindex = au_dbstart(dentry);
7047+ bi = au_ibstart(inode);
7048+ if (bi > bindex)
7049+ bindex = bi;
7050+
7051+ for (; bindex <= bend; bindex++) {
7052+ h_dentry = au_h_dptr(dentry, bindex);
7053+ if (!h_dentry)
7054+ continue;
7055+ h_inode = au_h_iptr(inode, bindex);
7056+ if (unlikely(h_inode != h_dentry->d_inode)) {
392086de 7057+ au_debug_on();
027c5e7a
AM
7058+ AuDbg("b%d, %s:%d\n", bindex, func, line);
7059+ AuDbgDentry(dentry);
7060+ AuDbgInode(inode);
392086de 7061+ au_debug_off();
027c5e7a
AM
7062+ BUG();
7063+ }
7064+ }
7065+}
7066+
1facf9fc 7067+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen)
7068+{
7069+ struct dentry *parent;
7070+
7071+ parent = dget_parent(dentry);
027c5e7a
AM
7072+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
7073+ AuDebugOn(IS_ROOT(dentry));
7074+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 7075+ dput(parent);
7076+}
7077+
7078+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen)
7079+{
7080+ struct dentry *parent;
027c5e7a 7081+ struct inode *inode;
1facf9fc 7082+
7083+ parent = dget_parent(dentry);
027c5e7a
AM
7084+ inode = dentry->d_inode;
7085+ AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode));
7086+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 7087+ dput(parent);
7088+}
7089+
7090+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen)
7091+{
7092+ int err, i, j;
7093+ struct au_dcsub_pages dpages;
7094+ struct au_dpage *dpage;
7095+ struct dentry **dentries;
7096+
7097+ err = au_dpages_init(&dpages, GFP_NOFS);
7098+ AuDebugOn(err);
027c5e7a 7099+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1);
1facf9fc 7100+ AuDebugOn(err);
7101+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) {
7102+ dpage = dpages.dpages + i;
7103+ dentries = dpage->dentries;
7104+ for (j = dpage->ndentry - 1; !err && j >= 0; j--)
027c5e7a 7105+ AuDebugOn(au_digen_test(dentries[j], sigen));
1facf9fc 7106+ }
7107+ au_dpages_free(&dpages);
7108+}
7109+
1facf9fc 7110+void au_dbg_verify_kthread(void)
7111+{
53392da6 7112+ if (au_wkq_test()) {
1facf9fc 7113+ au_dbg_blocked();
1e00d052
AM
7114+ /*
7115+ * It may be recursive, but udba=notify between two aufs mounts,
7116+ * where a single ro branch is shared, is not a problem.
7117+ */
7118+ /* WARN_ON(1); */
1facf9fc 7119+ }
7120+}
7121+
7122+/* ---------------------------------------------------------------------- */
7123+
7124+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused)
7125+{
7126+#ifdef AuForceNoPlink
7127+ au_opt_clr(sbinfo->si_mntflags, PLINK);
7128+#endif
7129+#ifdef AuForceNoXino
7130+ au_opt_clr(sbinfo->si_mntflags, XINO);
7131+#endif
7132+#ifdef AuForceNoRefrof
7133+ au_opt_clr(sbinfo->si_mntflags, REFROF);
7134+#endif
4a4d8108
AM
7135+#ifdef AuForceHnotify
7136+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY);
1facf9fc 7137+#endif
1308ab2a 7138+#ifdef AuForceRd0
7139+ sbinfo->si_rdblk = 0;
7140+ sbinfo->si_rdhash = 0;
7141+#endif
1facf9fc 7142+}
7143+
7144+int __init au_debug_init(void)
7145+{
7146+ aufs_bindex_t bindex;
7147+ struct au_vdir_destr destr;
7148+
7149+ bindex = -1;
7150+ AuDebugOn(bindex >= 0);
7151+
7152+ destr.len = -1;
7153+ AuDebugOn(destr.len < NAME_MAX);
7154+
7155+#ifdef CONFIG_4KSTACKS
0c3ec466 7156+ pr_warn("CONFIG_4KSTACKS is defined.\n");
1facf9fc 7157+#endif
7158+
7159+#ifdef AuForceNoBrs
7160+ sysaufs_brs = 0;
7161+#endif
7162+
7163+ return 0;
7164+}
7f207e10
AM
7165diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h
7166--- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
7167+++ linux/fs/aufs/debug.h 2015-01-25 13:00:38.631047076 +0100
7168@@ -0,0 +1,262 @@
1facf9fc 7169+/*
523b37e3 7170+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 7171+ *
7172+ * This program, aufs is free software; you can redistribute it and/or modify
7173+ * it under the terms of the GNU General Public License as published by
7174+ * the Free Software Foundation; either version 2 of the License, or
7175+ * (at your option) any later version.
dece6358
AM
7176+ *
7177+ * This program is distributed in the hope that it will be useful,
7178+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7179+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7180+ * GNU General Public License for more details.
7181+ *
7182+ * You should have received a copy of the GNU General Public License
523b37e3 7183+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7184+ */
7185+
7186+/*
7187+ * debug print functions
7188+ */
7189+
7190+#ifndef __AUFS_DEBUG_H__
7191+#define __AUFS_DEBUG_H__
7192+
7193+#ifdef __KERNEL__
7194+
392086de 7195+#include <linux/atomic.h>
4a4d8108
AM
7196+#include <linux/module.h>
7197+#include <linux/kallsyms.h>
1facf9fc 7198+#include <linux/sysrq.h>
4a4d8108 7199+
1facf9fc 7200+#ifdef CONFIG_AUFS_DEBUG
7201+#define AuDebugOn(a) BUG_ON(a)
7202+
7203+/* module parameter */
392086de
AM
7204+extern atomic_t aufs_debug;
7205+static inline void au_debug_on(void)
1facf9fc 7206+{
392086de
AM
7207+ atomic_inc(&aufs_debug);
7208+}
7209+static inline void au_debug_off(void)
7210+{
7211+ atomic_dec_if_positive(&aufs_debug);
1facf9fc 7212+}
7213+
7214+static inline int au_debug_test(void)
7215+{
392086de 7216+ return atomic_read(&aufs_debug) > 0;
1facf9fc 7217+}
7218+#else
7219+#define AuDebugOn(a) do {} while (0)
392086de
AM
7220+AuStubVoid(au_debug_on, void)
7221+AuStubVoid(au_debug_off, void)
4a4d8108 7222+AuStubInt0(au_debug_test, void)
1facf9fc 7223+#endif /* CONFIG_AUFS_DEBUG */
7224+
392086de
AM
7225+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t)
7226+
1facf9fc 7227+/* ---------------------------------------------------------------------- */
7228+
7229+/* debug print */
7230+
4a4d8108 7231+#define AuDbg(fmt, ...) do { \
1facf9fc 7232+ if (au_debug_test()) \
4a4d8108 7233+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \
1facf9fc 7234+} while (0)
4a4d8108
AM
7235+#define AuLabel(l) AuDbg(#l "\n")
7236+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__)
7237+#define AuWarn1(fmt, ...) do { \
1facf9fc 7238+ static unsigned char _c; \
7239+ if (!_c++) \
0c3ec466 7240+ pr_warn(fmt, ##__VA_ARGS__); \
1facf9fc 7241+} while (0)
7242+
4a4d8108 7243+#define AuErr1(fmt, ...) do { \
1facf9fc 7244+ static unsigned char _c; \
7245+ if (!_c++) \
4a4d8108 7246+ pr_err(fmt, ##__VA_ARGS__); \
1facf9fc 7247+} while (0)
7248+
4a4d8108 7249+#define AuIOErr1(fmt, ...) do { \
1facf9fc 7250+ static unsigned char _c; \
7251+ if (!_c++) \
4a4d8108 7252+ AuIOErr(fmt, ##__VA_ARGS__); \
1facf9fc 7253+} while (0)
7254+
7255+#define AuUnsupportMsg "This operation is not supported." \
7256+ " Please report this application to aufs-users ML."
4a4d8108
AM
7257+#define AuUnsupport(fmt, ...) do { \
7258+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \
1facf9fc 7259+ dump_stack(); \
7260+} while (0)
7261+
7262+#define AuTraceErr(e) do { \
7263+ if (unlikely((e) < 0)) \
7264+ AuDbg("err %d\n", (int)(e)); \
7265+} while (0)
7266+
7267+#define AuTraceErrPtr(p) do { \
7268+ if (IS_ERR(p)) \
7269+ AuDbg("err %ld\n", PTR_ERR(p)); \
7270+} while (0)
7271+
7272+/* dirty macros for debug print, use with "%.*s" and caution */
7273+#define AuLNPair(qstr) (qstr)->len, (qstr)->name
1facf9fc 7274+
7275+/* ---------------------------------------------------------------------- */
7276+
7277+struct au_sbinfo;
7278+struct au_finfo;
dece6358 7279+struct dentry;
1facf9fc 7280+#ifdef CONFIG_AUFS_DEBUG
c1595e42 7281+extern struct mutex au_dbg_mtx;
1facf9fc 7282+extern char *au_plevel;
7283+struct au_nhash;
7284+void au_dpri_whlist(struct au_nhash *whlist);
7285+struct au_vdir;
7286+void au_dpri_vdir(struct au_vdir *vdir);
dece6358 7287+struct inode;
1facf9fc 7288+void au_dpri_inode(struct inode *inode);
2cbb1c4b 7289+void au_dpri_dalias(struct inode *inode);
1facf9fc 7290+void au_dpri_dentry(struct dentry *dentry);
dece6358 7291+struct file;
1facf9fc 7292+void au_dpri_file(struct file *filp);
dece6358 7293+struct super_block;
1facf9fc 7294+void au_dpri_sb(struct super_block *sb);
7295+
7296+void au_dbg_sleep_jiffy(int jiffy);
dece6358 7297+struct iattr;
1facf9fc 7298+void au_dbg_iattr(struct iattr *ia);
7299+
027c5e7a
AM
7300+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__)
7301+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line);
1facf9fc 7302+void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen);
7303+void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen);
7304+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen);
1facf9fc 7305+void au_dbg_verify_kthread(void);
7306+
7307+int __init au_debug_init(void);
7308+void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
7309+#define AuDbgWhlist(w) do { \
c1595e42 7310+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7311+ AuDbg(#w "\n"); \
7312+ au_dpri_whlist(w); \
c1595e42 7313+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7314+} while (0)
7315+
7316+#define AuDbgVdir(v) do { \
c1595e42 7317+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7318+ AuDbg(#v "\n"); \
7319+ au_dpri_vdir(v); \
c1595e42 7320+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7321+} while (0)
7322+
7323+#define AuDbgInode(i) do { \
c1595e42 7324+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7325+ AuDbg(#i "\n"); \
7326+ au_dpri_inode(i); \
c1595e42 7327+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7328+} while (0)
7329+
2cbb1c4b 7330+#define AuDbgDAlias(i) do { \
c1595e42 7331+ mutex_lock(&au_dbg_mtx); \
2cbb1c4b
JR
7332+ AuDbg(#i "\n"); \
7333+ au_dpri_dalias(i); \
c1595e42 7334+ mutex_unlock(&au_dbg_mtx); \
2cbb1c4b
JR
7335+} while (0)
7336+
1facf9fc 7337+#define AuDbgDentry(d) do { \
c1595e42 7338+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7339+ AuDbg(#d "\n"); \
7340+ au_dpri_dentry(d); \
c1595e42 7341+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7342+} while (0)
7343+
7344+#define AuDbgFile(f) do { \
c1595e42 7345+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7346+ AuDbg(#f "\n"); \
7347+ au_dpri_file(f); \
c1595e42 7348+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7349+} while (0)
7350+
7351+#define AuDbgSb(sb) do { \
c1595e42 7352+ mutex_lock(&au_dbg_mtx); \
1facf9fc 7353+ AuDbg(#sb "\n"); \
7354+ au_dpri_sb(sb); \
c1595e42 7355+ mutex_unlock(&au_dbg_mtx); \
1facf9fc 7356+} while (0)
7357+
7358+#define AuDbgSleep(sec) do { \
7359+ AuDbg("sleep %d sec\n", sec); \
7360+ ssleep(sec); \
7361+} while (0)
7362+
7363+#define AuDbgSleepJiffy(jiffy) do { \
7364+ AuDbg("sleep %d jiffies\n", jiffy); \
7365+ au_dbg_sleep_jiffy(jiffy); \
7366+} while (0)
7367+
7368+#define AuDbgIAttr(ia) do { \
7369+ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \
7370+ au_dbg_iattr(ia); \
7371+} while (0)
4a4d8108
AM
7372+
7373+#define AuDbgSym(addr) do { \
7374+ char sym[KSYM_SYMBOL_LEN]; \
7375+ sprint_symbol(sym, (unsigned long)addr); \
7376+ AuDbg("%s\n", sym); \
7377+} while (0)
7378+
7379+#define AuInfoSym(addr) do { \
7380+ char sym[KSYM_SYMBOL_LEN]; \
7381+ sprint_symbol(sym, (unsigned long)addr); \
7382+ AuInfo("%s\n", sym); \
7383+} while (0)
1facf9fc 7384+#else
027c5e7a 7385+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry)
4a4d8108
AM
7386+AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen)
7387+AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry,
7388+ unsigned int sigen)
7389+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen)
7390+AuStubVoid(au_dbg_verify_kthread, void)
7391+AuStubInt0(__init au_debug_init, void)
7392+AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
1facf9fc 7393+
1facf9fc 7394+#define AuDbgWhlist(w) do {} while (0)
7395+#define AuDbgVdir(v) do {} while (0)
7396+#define AuDbgInode(i) do {} while (0)
2cbb1c4b 7397+#define AuDbgDAlias(i) do {} while (0)
1facf9fc 7398+#define AuDbgDentry(d) do {} while (0)
7399+#define AuDbgFile(f) do {} while (0)
7400+#define AuDbgSb(sb) do {} while (0)
7401+#define AuDbgSleep(sec) do {} while (0)
7402+#define AuDbgSleepJiffy(jiffy) do {} while (0)
7403+#define AuDbgIAttr(ia) do {} while (0)
4a4d8108
AM
7404+#define AuDbgSym(addr) do {} while (0)
7405+#define AuInfoSym(addr) do {} while (0)
1facf9fc 7406+#endif /* CONFIG_AUFS_DEBUG */
7407+
7408+/* ---------------------------------------------------------------------- */
7409+
7410+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
7411+int __init au_sysrq_init(void);
7412+void au_sysrq_fin(void);
7413+
7414+#ifdef CONFIG_HW_CONSOLE
7415+#define au_dbg_blocked() do { \
7416+ WARN_ON(1); \
0c5527e5 7417+ handle_sysrq('w'); \
1facf9fc 7418+} while (0)
7419+#else
4a4d8108 7420+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7421+#endif
7422+
7423+#else
4a4d8108
AM
7424+AuStubInt0(__init au_sysrq_init, void)
7425+AuStubVoid(au_sysrq_fin, void)
7426+AuStubVoid(au_dbg_blocked, void)
1facf9fc 7427+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
7428+
7429+#endif /* __KERNEL__ */
7430+#endif /* __AUFS_DEBUG_H__ */
7f207e10
AM
7431diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
7432--- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
7433+++ linux/fs/aufs/dentry.c 2015-01-25 13:00:38.631047076 +0100
7434@@ -0,0 +1,1096 @@
1facf9fc 7435+/*
523b37e3 7436+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 7437+ *
7438+ * This program, aufs is free software; you can redistribute it and/or modify
7439+ * it under the terms of the GNU General Public License as published by
7440+ * the Free Software Foundation; either version 2 of the License, or
7441+ * (at your option) any later version.
dece6358
AM
7442+ *
7443+ * This program is distributed in the hope that it will be useful,
7444+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7445+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7446+ * GNU General Public License for more details.
7447+ *
7448+ * You should have received a copy of the GNU General Public License
523b37e3 7449+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 7450+ */
7451+
7452+/*
7453+ * lookup and dentry operations
7454+ */
7455+
dece6358 7456+#include <linux/namei.h>
1facf9fc 7457+#include "aufs.h"
7458+
1facf9fc 7459+#define AuLkup_ALLOW_NEG 1
076b876e 7460+#define AuLkup_IGNORE_PERM (1 << 1)
1facf9fc 7461+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name)
7f207e10
AM
7462+#define au_fset_lkup(flags, name) \
7463+ do { (flags) |= AuLkup_##name; } while (0)
7464+#define au_fclr_lkup(flags, name) \
7465+ do { (flags) &= ~AuLkup_##name; } while (0)
1facf9fc 7466+
7467+struct au_do_lookup_args {
7468+ unsigned int flags;
7469+ mode_t type;
1facf9fc 7470+};
7471+
7472+/*
7473+ * returns positive/negative dentry, NULL or an error.
7474+ * NULL means whiteout-ed or not-found.
7475+ */
7476+static struct dentry*
7477+au_do_lookup(struct dentry *h_parent, struct dentry *dentry,
7478+ aufs_bindex_t bindex, struct qstr *wh_name,
7479+ struct au_do_lookup_args *args)
7480+{
7481+ struct dentry *h_dentry;
7482+ struct inode *h_inode, *inode;
1facf9fc 7483+ struct au_branch *br;
7484+ int wh_found, opq;
7485+ unsigned char wh_able;
7486+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG);
076b876e
AM
7487+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags,
7488+ IGNORE_PERM);
1facf9fc 7489+
1facf9fc 7490+ wh_found = 0;
7491+ br = au_sbr(dentry->d_sb, bindex);
7492+ wh_able = !!au_br_whable(br->br_perm);
7493+ if (wh_able)
076b876e 7494+ wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0);
1facf9fc 7495+ h_dentry = ERR_PTR(wh_found);
7496+ if (!wh_found)
7497+ goto real_lookup;
7498+ if (unlikely(wh_found < 0))
7499+ goto out;
7500+
7501+ /* We found a whiteout */
7502+ /* au_set_dbend(dentry, bindex); */
7503+ au_set_dbwh(dentry, bindex);
7504+ if (!allow_neg)
7505+ return NULL; /* success */
7506+
4f0767ce 7507+real_lookup:
076b876e
AM
7508+ if (!ignore_perm)
7509+ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
7510+ else
7511+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 7512+ if (IS_ERR(h_dentry))
7513+ goto out;
7514+
7515+ h_inode = h_dentry->d_inode;
7516+ if (!h_inode) {
7517+ if (!allow_neg)
7518+ goto out_neg;
7519+ } else if (wh_found
7520+ || (args->type && args->type != (h_inode->i_mode & S_IFMT)))
7521+ goto out_neg;
7522+
7523+ if (au_dbend(dentry) <= bindex)
7524+ au_set_dbend(dentry, bindex);
7525+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
7526+ au_set_dbstart(dentry, bindex);
7527+ au_set_h_dptr(dentry, bindex, h_dentry);
7528+
7529+ inode = dentry->d_inode;
7530+ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
7531+ || (inode && !S_ISDIR(inode->i_mode)))
7532+ goto out; /* success */
7533+
7534+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
076b876e 7535+ opq = au_diropq_test(h_dentry);
1facf9fc 7536+ mutex_unlock(&h_inode->i_mutex);
7537+ if (opq > 0)
7538+ au_set_dbdiropq(dentry, bindex);
7539+ else if (unlikely(opq < 0)) {
7540+ au_set_h_dptr(dentry, bindex, NULL);
7541+ h_dentry = ERR_PTR(opq);
7542+ }
7543+ goto out;
7544+
4f0767ce 7545+out_neg:
1facf9fc 7546+ dput(h_dentry);
7547+ h_dentry = NULL;
4f0767ce 7548+out:
1facf9fc 7549+ return h_dentry;
7550+}
7551+
dece6358
AM
7552+static int au_test_shwh(struct super_block *sb, const struct qstr *name)
7553+{
7554+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH)
7555+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
7556+ return -EPERM;
7557+ return 0;
7558+}
7559+
1facf9fc 7560+/*
7561+ * returns the number of lower positive dentries,
7562+ * otherwise an error.
7563+ * can be called at unlinking with @type is zero.
7564+ */
537831f9 7565+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type)
1facf9fc 7566+{
7567+ int npositive, err;
7568+ aufs_bindex_t bindex, btail, bdiropq;
076b876e 7569+ unsigned char isdir, dirperm1;
1facf9fc 7570+ struct qstr whname;
7571+ struct au_do_lookup_args args = {
b4510431 7572+ .flags = 0,
537831f9 7573+ .type = type
1facf9fc 7574+ };
7575+ const struct qstr *name = &dentry->d_name;
7576+ struct dentry *parent;
7577+ struct inode *inode;
076b876e 7578+ struct super_block *sb;
1facf9fc 7579+
076b876e
AM
7580+ sb = dentry->d_sb;
7581+ err = au_test_shwh(sb, name);
dece6358 7582+ if (unlikely(err))
1facf9fc 7583+ goto out;
7584+
7585+ err = au_wh_name_alloc(&whname, name);
7586+ if (unlikely(err))
7587+ goto out;
7588+
7589+ inode = dentry->d_inode;
7590+ isdir = !!(inode && S_ISDIR(inode->i_mode));
7591+ if (!type)
7592+ au_fset_lkup(args.flags, ALLOW_NEG);
076b876e 7593+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1);
1facf9fc 7594+
7595+ npositive = 0;
4a4d8108 7596+ parent = dget_parent(dentry);
1facf9fc 7597+ btail = au_dbtaildir(parent);
7598+ for (bindex = bstart; bindex <= btail; bindex++) {
7599+ struct dentry *h_parent, *h_dentry;
7600+ struct inode *h_inode, *h_dir;
7601+
7602+ h_dentry = au_h_dptr(dentry, bindex);
7603+ if (h_dentry) {
7604+ if (h_dentry->d_inode)
7605+ npositive++;
7606+ if (type != S_IFDIR)
7607+ break;
7608+ continue;
7609+ }
7610+ h_parent = au_h_dptr(parent, bindex);
7611+ if (!h_parent)
7612+ continue;
7613+ h_dir = h_parent->d_inode;
7614+ if (!h_dir || !S_ISDIR(h_dir->i_mode))
7615+ continue;
7616+
7617+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
7618+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname,
7619+ &args);
7620+ mutex_unlock(&h_dir->i_mutex);
7621+ err = PTR_ERR(h_dentry);
7622+ if (IS_ERR(h_dentry))
4a4d8108 7623+ goto out_parent;
1facf9fc 7624+ au_fclr_lkup(args.flags, ALLOW_NEG);
076b876e
AM
7625+ if (dirperm1)
7626+ au_fset_lkup(args.flags, IGNORE_PERM);
1facf9fc 7627+
7628+ if (au_dbwh(dentry) >= 0)
7629+ break;
7630+ if (!h_dentry)
7631+ continue;
7632+ h_inode = h_dentry->d_inode;
7633+ if (!h_inode)
7634+ continue;
7635+ npositive++;
7636+ if (!args.type)
7637+ args.type = h_inode->i_mode & S_IFMT;
7638+ if (args.type != S_IFDIR)
7639+ break;
7640+ else if (isdir) {
7641+ /* the type of lower may be different */
7642+ bdiropq = au_dbdiropq(dentry);
7643+ if (bdiropq >= 0 && bdiropq <= bindex)
7644+ break;
7645+ }
7646+ }
7647+
7648+ if (npositive) {
7649+ AuLabel(positive);
7650+ au_update_dbstart(dentry);
7651+ }
7652+ err = npositive;
076b876e 7653+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE)
027c5e7a 7654+ && au_dbstart(dentry) < 0)) {
1facf9fc 7655+ err = -EIO;
523b37e3
AM
7656+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n",
7657+ dentry, err);
027c5e7a 7658+ }
1facf9fc 7659+
4f0767ce 7660+out_parent:
4a4d8108 7661+ dput(parent);
1facf9fc 7662+ kfree(whname.name);
4f0767ce 7663+out:
1facf9fc 7664+ return err;
7665+}
7666+
076b876e 7667+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent)
1facf9fc 7668+{
7669+ struct dentry *dentry;
7670+ int wkq_err;
7671+
7672+ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC))
b4510431 7673+ dentry = vfsub_lkup_one(name, parent);
1facf9fc 7674+ else {
b4510431
AM
7675+ struct vfsub_lkup_one_args args = {
7676+ .errp = &dentry,
7677+ .name = name,
7678+ .parent = parent
1facf9fc 7679+ };
7680+
b4510431 7681+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args);
1facf9fc 7682+ if (unlikely(wkq_err))
7683+ dentry = ERR_PTR(wkq_err);
7684+ }
7685+
7686+ return dentry;
7687+}
7688+
7689+/*
7690+ * lookup @dentry on @bindex which should be negative.
7691+ */
86dc4139 7692+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh)
1facf9fc 7693+{
7694+ int err;
7695+ struct dentry *parent, *h_parent, *h_dentry;
86dc4139 7696+ struct au_branch *br;
1facf9fc 7697+
1facf9fc 7698+ parent = dget_parent(dentry);
7699+ h_parent = au_h_dptr(parent, bindex);
86dc4139
AM
7700+ br = au_sbr(dentry->d_sb, bindex);
7701+ if (wh)
7702+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name);
7703+ else
076b876e 7704+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent);
1facf9fc 7705+ err = PTR_ERR(h_dentry);
7706+ if (IS_ERR(h_dentry))
7707+ goto out;
7708+ if (unlikely(h_dentry->d_inode)) {
7709+ err = -EIO;
523b37e3 7710+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex);
1facf9fc 7711+ dput(h_dentry);
7712+ goto out;
7713+ }
7714+
4a4d8108 7715+ err = 0;
1facf9fc 7716+ if (bindex < au_dbstart(dentry))
7717+ au_set_dbstart(dentry, bindex);
7718+ if (au_dbend(dentry) < bindex)
7719+ au_set_dbend(dentry, bindex);
7720+ au_set_h_dptr(dentry, bindex, h_dentry);
1facf9fc 7721+
4f0767ce 7722+out:
1facf9fc 7723+ dput(parent);
7724+ return err;
7725+}
7726+
7727+/* ---------------------------------------------------------------------- */
7728+
7729+/* subset of struct inode */
7730+struct au_iattr {
7731+ unsigned long i_ino;
7732+ /* unsigned int i_nlink; */
0c3ec466
AM
7733+ kuid_t i_uid;
7734+ kgid_t i_gid;
1facf9fc 7735+ u64 i_version;
7736+/*
7737+ loff_t i_size;
7738+ blkcnt_t i_blocks;
7739+*/
7740+ umode_t i_mode;
7741+};
7742+
7743+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode)
7744+{
7745+ ia->i_ino = h_inode->i_ino;
7746+ /* ia->i_nlink = h_inode->i_nlink; */
7747+ ia->i_uid = h_inode->i_uid;
7748+ ia->i_gid = h_inode->i_gid;
7749+ ia->i_version = h_inode->i_version;
7750+/*
7751+ ia->i_size = h_inode->i_size;
7752+ ia->i_blocks = h_inode->i_blocks;
7753+*/
7754+ ia->i_mode = (h_inode->i_mode & S_IFMT);
7755+}
7756+
7757+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode)
7758+{
7759+ return ia->i_ino != h_inode->i_ino
7760+ /* || ia->i_nlink != h_inode->i_nlink */
0c3ec466 7761+ || !uid_eq(ia->i_uid, h_inode->i_uid)
2dfbb274 7762+ || !gid_eq(ia->i_gid, h_inode->i_gid)
1facf9fc 7763+ || ia->i_version != h_inode->i_version
7764+/*
7765+ || ia->i_size != h_inode->i_size
7766+ || ia->i_blocks != h_inode->i_blocks
7767+*/
7768+ || ia->i_mode != (h_inode->i_mode & S_IFMT);
7769+}
7770+
7771+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent,
7772+ struct au_branch *br)
7773+{
7774+ int err;
7775+ struct au_iattr ia;
7776+ struct inode *h_inode;
7777+ struct dentry *h_d;
7778+ struct super_block *h_sb;
7779+
7780+ err = 0;
7781+ memset(&ia, -1, sizeof(ia));
7782+ h_sb = h_dentry->d_sb;
7783+ h_inode = h_dentry->d_inode;
7784+ if (h_inode)
7785+ au_iattr_save(&ia, h_inode);
7786+ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb))
7787+ /* nfs d_revalidate may return 0 for negative dentry */
7788+ /* fuse d_revalidate always return 0 for negative dentry */
7789+ goto out;
7790+
7791+ /* main purpose is namei.c:cached_lookup() and d_revalidate */
b4510431 7792+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent);
1facf9fc 7793+ err = PTR_ERR(h_d);
7794+ if (IS_ERR(h_d))
7795+ goto out;
7796+
7797+ err = 0;
7798+ if (unlikely(h_d != h_dentry
7799+ || h_d->d_inode != h_inode
7800+ || (h_inode && au_iattr_test(&ia, h_inode))))
7801+ err = au_busy_or_stale();
7802+ dput(h_d);
7803+
4f0767ce 7804+out:
1facf9fc 7805+ AuTraceErr(err);
7806+ return err;
7807+}
7808+
7809+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
7810+ struct dentry *h_parent, struct au_branch *br)
7811+{
7812+ int err;
7813+
7814+ err = 0;
027c5e7a
AM
7815+ if (udba == AuOpt_UDBA_REVAL
7816+ && !au_test_fs_remote(h_dentry->d_sb)) {
1facf9fc 7817+ IMustLock(h_dir);
7818+ err = (h_dentry->d_parent->d_inode != h_dir);
027c5e7a 7819+ } else if (udba != AuOpt_UDBA_NONE)
1facf9fc 7820+ err = au_h_verify_dentry(h_dentry, h_parent, br);
7821+
7822+ return err;
7823+}
7824+
7825+/* ---------------------------------------------------------------------- */
7826+
027c5e7a 7827+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
1facf9fc 7828+{
027c5e7a 7829+ int err;
1facf9fc 7830+ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
027c5e7a
AM
7831+ struct au_hdentry tmp, *p, *q;
7832+ struct au_dinfo *dinfo;
7833+ struct super_block *sb;
1facf9fc 7834+
027c5e7a 7835+ DiMustWriteLock(dentry);
1308ab2a 7836+
027c5e7a
AM
7837+ sb = dentry->d_sb;
7838+ dinfo = au_di(dentry);
1facf9fc 7839+ bend = dinfo->di_bend;
7840+ bwh = dinfo->di_bwh;
7841+ bdiropq = dinfo->di_bdiropq;
027c5e7a 7842+ p = dinfo->di_hdentry + dinfo->di_bstart;
1facf9fc 7843+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
027c5e7a 7844+ if (!p->hd_dentry)
1facf9fc 7845+ continue;
7846+
027c5e7a
AM
7847+ new_bindex = au_br_index(sb, p->hd_id);
7848+ if (new_bindex == bindex)
1facf9fc 7849+ continue;
1facf9fc 7850+
1facf9fc 7851+ if (dinfo->di_bwh == bindex)
7852+ bwh = new_bindex;
7853+ if (dinfo->di_bdiropq == bindex)
7854+ bdiropq = new_bindex;
7855+ if (new_bindex < 0) {
7856+ au_hdput(p);
7857+ p->hd_dentry = NULL;
7858+ continue;
7859+ }
7860+
7861+ /* swap two lower dentries, and loop again */
7862+ q = dinfo->di_hdentry + new_bindex;
7863+ tmp = *q;
7864+ *q = *p;
7865+ *p = tmp;
7866+ if (tmp.hd_dentry) {
7867+ bindex--;
7868+ p--;
7869+ }
7870+ }
7871+
1facf9fc 7872+ dinfo->di_bwh = -1;
7873+ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
7874+ dinfo->di_bwh = bwh;
7875+
7876+ dinfo->di_bdiropq = -1;
7877+ if (bdiropq >= 0
7878+ && bdiropq <= au_sbend(sb)
7879+ && au_sbr_whable(sb, bdiropq))
7880+ dinfo->di_bdiropq = bdiropq;
7881+
027c5e7a
AM
7882+ err = -EIO;
7883+ dinfo->di_bstart = -1;
7884+ dinfo->di_bend = -1;
1facf9fc 7885+ bend = au_dbend(parent);
7886+ p = dinfo->di_hdentry;
7887+ for (bindex = 0; bindex <= bend; bindex++, p++)
7888+ if (p->hd_dentry) {
7889+ dinfo->di_bstart = bindex;
7890+ break;
7891+ }
7892+
027c5e7a
AM
7893+ if (dinfo->di_bstart >= 0) {
7894+ p = dinfo->di_hdentry + bend;
7895+ for (bindex = bend; bindex >= 0; bindex--, p--)
7896+ if (p->hd_dentry) {
7897+ dinfo->di_bend = bindex;
7898+ err = 0;
7899+ break;
7900+ }
7901+ }
7902+
7903+ return err;
1facf9fc 7904+}
7905+
027c5e7a 7906+static void au_do_hide(struct dentry *dentry)
1facf9fc 7907+{
027c5e7a 7908+ struct inode *inode;
1facf9fc 7909+
027c5e7a
AM
7910+ inode = dentry->d_inode;
7911+ if (inode) {
7912+ if (!S_ISDIR(inode->i_mode)) {
7913+ if (inode->i_nlink && !d_unhashed(dentry))
7914+ drop_nlink(inode);
7915+ } else {
7916+ clear_nlink(inode);
7917+ /* stop next lookup */
7918+ inode->i_flags |= S_DEAD;
7919+ }
7920+ smp_mb(); /* necessary? */
7921+ }
7922+ d_drop(dentry);
7923+}
1308ab2a 7924+
027c5e7a
AM
7925+static int au_hide_children(struct dentry *parent)
7926+{
7927+ int err, i, j, ndentry;
7928+ struct au_dcsub_pages dpages;
7929+ struct au_dpage *dpage;
7930+ struct dentry *dentry;
1facf9fc 7931+
027c5e7a 7932+ err = au_dpages_init(&dpages, GFP_NOFS);
1facf9fc 7933+ if (unlikely(err))
7934+ goto out;
027c5e7a
AM
7935+ err = au_dcsub_pages(&dpages, parent, NULL, NULL);
7936+ if (unlikely(err))
7937+ goto out_dpages;
1facf9fc 7938+
027c5e7a
AM
7939+ /* in reverse order */
7940+ for (i = dpages.ndpage - 1; i >= 0; i--) {
7941+ dpage = dpages.dpages + i;
7942+ ndentry = dpage->ndentry;
7943+ for (j = ndentry - 1; j >= 0; j--) {
7944+ dentry = dpage->dentries[j];
7945+ if (dentry != parent)
7946+ au_do_hide(dentry);
7947+ }
7948+ }
1facf9fc 7949+
027c5e7a
AM
7950+out_dpages:
7951+ au_dpages_free(&dpages);
4f0767ce 7952+out:
027c5e7a 7953+ return err;
1facf9fc 7954+}
7955+
027c5e7a 7956+static void au_hide(struct dentry *dentry)
1facf9fc 7957+{
027c5e7a
AM
7958+ int err;
7959+ struct inode *inode;
1facf9fc 7960+
027c5e7a
AM
7961+ AuDbgDentry(dentry);
7962+ inode = dentry->d_inode;
7963+ if (inode && S_ISDIR(inode->i_mode)) {
7964+ /* shrink_dcache_parent(dentry); */
7965+ err = au_hide_children(dentry);
7966+ if (unlikely(err))
523b37e3
AM
7967+ AuIOErr("%pd, failed hiding children, ignored %d\n",
7968+ dentry, err);
027c5e7a
AM
7969+ }
7970+ au_do_hide(dentry);
7971+}
1facf9fc 7972+
027c5e7a
AM
7973+/*
7974+ * By adding a dirty branch, a cached dentry may be affected in various ways.
7975+ *
7976+ * a dirty branch is added
7977+ * - on the top of layers
7978+ * - in the middle of layers
7979+ * - to the bottom of layers
7980+ *
7981+ * on the added branch there exists
7982+ * - a whiteout
7983+ * - a diropq
7984+ * - a same named entry
7985+ * + exist
7986+ * * negative --> positive
7987+ * * positive --> positive
7988+ * - type is unchanged
7989+ * - type is changed
7990+ * + doesn't exist
7991+ * * negative --> negative
7992+ * * positive --> negative (rejected by au_br_del() for non-dir case)
7993+ * - none
7994+ */
7995+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
7996+ struct au_dinfo *tmp)
7997+{
7998+ int err;
7999+ aufs_bindex_t bindex, bend;
8000+ struct {
8001+ struct dentry *dentry;
8002+ struct inode *inode;
8003+ mode_t mode;
8004+ } orig_h, tmp_h;
8005+ struct au_hdentry *hd;
8006+ struct inode *inode, *h_inode;
8007+ struct dentry *h_dentry;
8008+
8009+ err = 0;
8010+ AuDebugOn(dinfo->di_bstart < 0);
8011+ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry;
8012+ orig_h.inode = orig_h.dentry->d_inode;
8013+ orig_h.mode = 0;
8014+ if (orig_h.inode)
8015+ orig_h.mode = orig_h.inode->i_mode & S_IFMT;
8016+ memset(&tmp_h, 0, sizeof(tmp_h));
8017+ if (tmp->di_bstart >= 0) {
8018+ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry;
8019+ tmp_h.inode = tmp_h.dentry->d_inode;
8020+ if (tmp_h.inode)
8021+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
8022+ }
8023+
8024+ inode = dentry->d_inode;
8025+ if (!orig_h.inode) {
8026+ AuDbg("nagative originally\n");
8027+ if (inode) {
8028+ au_hide(dentry);
8029+ goto out;
8030+ }
8031+ AuDebugOn(inode);
8032+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
8033+ AuDebugOn(dinfo->di_bdiropq != -1);
8034+
8035+ if (!tmp_h.inode) {
8036+ AuDbg("negative --> negative\n");
8037+ /* should have only one negative lower */
8038+ if (tmp->di_bstart >= 0
8039+ && tmp->di_bstart < dinfo->di_bstart) {
8040+ AuDebugOn(tmp->di_bstart != tmp->di_bend);
8041+ AuDebugOn(dinfo->di_bstart != dinfo->di_bend);
8042+ au_set_h_dptr(dentry, dinfo->di_bstart, NULL);
8043+ au_di_cp(dinfo, tmp);
8044+ hd = tmp->di_hdentry + tmp->di_bstart;
8045+ au_set_h_dptr(dentry, tmp->di_bstart,
8046+ dget(hd->hd_dentry));
8047+ }
8048+ au_dbg_verify_dinode(dentry);
8049+ } else {
8050+ AuDbg("negative --> positive\n");
8051+ /*
8052+ * similar to the behaviour of creating with bypassing
8053+ * aufs.
8054+ * unhash it in order to force an error in the
8055+ * succeeding create operation.
8056+ * we should not set S_DEAD here.
8057+ */
8058+ d_drop(dentry);
8059+ /* au_di_swap(tmp, dinfo); */
8060+ au_dbg_verify_dinode(dentry);
8061+ }
8062+ } else {
8063+ AuDbg("positive originally\n");
8064+ /* inode may be NULL */
8065+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode);
8066+ if (!tmp_h.inode) {
8067+ AuDbg("positive --> negative\n");
8068+ /* or bypassing aufs */
8069+ au_hide(dentry);
8070+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart)
8071+ dinfo->di_bwh = tmp->di_bwh;
8072+ if (inode)
8073+ err = au_refresh_hinode_self(inode);
8074+ au_dbg_verify_dinode(dentry);
8075+ } else if (orig_h.mode == tmp_h.mode) {
8076+ AuDbg("positive --> positive, same type\n");
8077+ if (!S_ISDIR(orig_h.mode)
8078+ && dinfo->di_bstart > tmp->di_bstart) {
8079+ /*
8080+ * similar to the behaviour of removing and
8081+ * creating.
8082+ */
8083+ au_hide(dentry);
8084+ if (inode)
8085+ err = au_refresh_hinode_self(inode);
8086+ au_dbg_verify_dinode(dentry);
8087+ } else {
8088+ /* fill empty slots */
8089+ if (dinfo->di_bstart > tmp->di_bstart)
8090+ dinfo->di_bstart = tmp->di_bstart;
8091+ if (dinfo->di_bend < tmp->di_bend)
8092+ dinfo->di_bend = tmp->di_bend;
8093+ dinfo->di_bwh = tmp->di_bwh;
8094+ dinfo->di_bdiropq = tmp->di_bdiropq;
8095+ hd = tmp->di_hdentry;
8096+ bend = dinfo->di_bend;
8097+ for (bindex = tmp->di_bstart; bindex <= bend;
8098+ bindex++) {
8099+ if (au_h_dptr(dentry, bindex))
8100+ continue;
8101+ h_dentry = hd[bindex].hd_dentry;
8102+ if (!h_dentry)
8103+ continue;
8104+ h_inode = h_dentry->d_inode;
8105+ AuDebugOn(!h_inode);
8106+ AuDebugOn(orig_h.mode
8107+ != (h_inode->i_mode
8108+ & S_IFMT));
8109+ au_set_h_dptr(dentry, bindex,
8110+ dget(h_dentry));
8111+ }
8112+ err = au_refresh_hinode(inode, dentry);
8113+ au_dbg_verify_dinode(dentry);
8114+ }
8115+ } else {
8116+ AuDbg("positive --> positive, different type\n");
8117+ /* similar to the behaviour of removing and creating */
8118+ au_hide(dentry);
8119+ if (inode)
8120+ err = au_refresh_hinode_self(inode);
8121+ au_dbg_verify_dinode(dentry);
8122+ }
8123+ }
8124+
8125+out:
8126+ return err;
8127+}
8128+
8129+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent)
8130+{
8131+ int err, ebrange;
8132+ unsigned int sigen;
8133+ struct au_dinfo *dinfo, *tmp;
8134+ struct super_block *sb;
8135+ struct inode *inode;
8136+
8137+ DiMustWriteLock(dentry);
8138+ AuDebugOn(IS_ROOT(dentry));
8139+ AuDebugOn(!parent->d_inode);
8140+
8141+ sb = dentry->d_sb;
8142+ inode = dentry->d_inode;
8143+ sigen = au_sigen(sb);
8144+ err = au_digen_test(parent, sigen);
8145+ if (unlikely(err))
8146+ goto out;
8147+
8148+ dinfo = au_di(dentry);
8149+ err = au_di_realloc(dinfo, au_sbend(sb) + 1);
8150+ if (unlikely(err))
8151+ goto out;
8152+ ebrange = au_dbrange_test(dentry);
8153+ if (!ebrange)
8154+ ebrange = au_do_refresh_hdentry(dentry, parent);
8155+
38d290e6 8156+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) {
027c5e7a
AM
8157+ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0);
8158+ if (inode)
8159+ err = au_refresh_hinode_self(inode);
8160+ au_dbg_verify_dinode(dentry);
8161+ if (!err)
8162+ goto out_dgen; /* success */
8163+ goto out;
8164+ }
8165+
8166+ /* temporary dinfo */
8167+ AuDbgDentry(dentry);
8168+ err = -ENOMEM;
8169+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
8170+ if (unlikely(!tmp))
8171+ goto out;
8172+ au_di_swap(tmp, dinfo);
8173+ /* returns the number of positive dentries */
8174+ /*
8175+ * if current working dir is removed, it returns an error.
8176+ * but the dentry is legal.
8177+ */
537831f9 8178+ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0);
027c5e7a
AM
8179+ AuDbgDentry(dentry);
8180+ au_di_swap(tmp, dinfo);
8181+ if (err == -ENOENT)
8182+ err = 0;
8183+ if (err >= 0) {
8184+ /* compare/refresh by dinfo */
8185+ AuDbgDentry(dentry);
8186+ err = au_refresh_by_dinfo(dentry, dinfo, tmp);
8187+ au_dbg_verify_dinode(dentry);
8188+ AuTraceErr(err);
8189+ }
8190+ au_rw_write_unlock(&tmp->di_rwsem);
8191+ au_di_free(tmp);
8192+ if (unlikely(err))
8193+ goto out;
8194+
8195+out_dgen:
8196+ au_update_digen(dentry);
8197+out:
8198+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) {
523b37e3 8199+ AuIOErr("failed refreshing %pd, %d\n", dentry, err);
027c5e7a
AM
8200+ AuDbgDentry(dentry);
8201+ }
8202+ AuTraceErr(err);
8203+ return err;
8204+}
8205+
b4510431
AM
8206+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags,
8207+ struct dentry *dentry, aufs_bindex_t bindex)
027c5e7a
AM
8208+{
8209+ int err, valid;
027c5e7a
AM
8210+
8211+ err = 0;
8212+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE))
8213+ goto out;
027c5e7a
AM
8214+
8215+ AuDbg("b%d\n", bindex);
b4510431
AM
8216+ /*
8217+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs,
8218+ * due to whiteout and branch permission.
8219+ */
8220+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE
8221+ | LOOKUP_FOLLOW | LOOKUP_EXCL);
8222+ /* it may return tri-state */
8223+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags);
1facf9fc 8224+
8225+ if (unlikely(valid < 0))
8226+ err = valid;
8227+ else if (!valid)
8228+ err = -EINVAL;
8229+
4f0767ce 8230+out:
1facf9fc 8231+ AuTraceErr(err);
8232+ return err;
8233+}
8234+
8235+/* todo: remove this */
8236+static int h_d_revalidate(struct dentry *dentry, struct inode *inode,
b4510431 8237+ unsigned int flags, int do_udba)
1facf9fc 8238+{
8239+ int err;
8240+ umode_t mode, h_mode;
8241+ aufs_bindex_t bindex, btail, bstart, ibs, ibe;
38d290e6 8242+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile;
4a4d8108 8243+ struct inode *h_inode, *h_cached_inode;
1facf9fc 8244+ struct dentry *h_dentry;
8245+ struct qstr *name, *h_name;
8246+
8247+ err = 0;
8248+ plus = 0;
8249+ mode = 0;
1facf9fc 8250+ ibs = -1;
8251+ ibe = -1;
8252+ unhashed = !!d_unhashed(dentry);
8253+ is_root = !!IS_ROOT(dentry);
8254+ name = &dentry->d_name;
38d290e6 8255+ tmpfile = au_di(dentry)->di_tmpfile;
1facf9fc 8256+
8257+ /*
7f207e10
AM
8258+ * Theoretically, REVAL test should be unnecessary in case of
8259+ * {FS,I}NOTIFY.
8260+ * But {fs,i}notify doesn't fire some necessary events,
1facf9fc 8261+ * IN_ATTRIB for atime/nlink/pageio
1facf9fc 8262+ * Let's do REVAL test too.
8263+ */
8264+ if (do_udba && inode) {
8265+ mode = (inode->i_mode & S_IFMT);
8266+ plus = (inode->i_nlink > 0);
1facf9fc 8267+ ibs = au_ibstart(inode);
8268+ ibe = au_ibend(inode);
8269+ }
8270+
8271+ bstart = au_dbstart(dentry);
8272+ btail = bstart;
8273+ if (inode && S_ISDIR(inode->i_mode))
8274+ btail = au_dbtaildir(dentry);
8275+ for (bindex = bstart; bindex <= btail; bindex++) {
8276+ h_dentry = au_h_dptr(dentry, bindex);
8277+ if (!h_dentry)
8278+ continue;
8279+
523b37e3
AM
8280+ AuDbg("b%d, %pd\n", bindex, h_dentry);
8281+ h_nfs = !!au_test_nfs(h_dentry->d_sb);
027c5e7a 8282+ spin_lock(&h_dentry->d_lock);
1facf9fc 8283+ h_name = &h_dentry->d_name;
8284+ if (unlikely(do_udba
8285+ && !is_root
523b37e3
AM
8286+ && ((!h_nfs
8287+ && (unhashed != !!d_unhashed(h_dentry)
38d290e6
JR
8288+ || (!tmpfile
8289+ && !au_qstreq(name, h_name))
8290+ ))
523b37e3
AM
8291+ || (h_nfs
8292+ && !(flags & LOOKUP_OPEN)
8293+ && (h_dentry->d_flags
8294+ & DCACHE_NFSFS_RENAMED)))
1facf9fc 8295+ )) {
38d290e6
JR
8296+ int h_unhashed;
8297+
8298+ h_unhashed = d_unhashed(h_dentry);
027c5e7a 8299+ spin_unlock(&h_dentry->d_lock);
38d290e6
JR
8300+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n",
8301+ unhashed, h_unhashed, dentry, h_dentry);
1facf9fc 8302+ goto err;
8303+ }
027c5e7a 8304+ spin_unlock(&h_dentry->d_lock);
1facf9fc 8305+
b4510431 8306+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex);
1facf9fc 8307+ if (unlikely(err))
8308+ /* do not goto err, to keep the errno */
8309+ break;
8310+
8311+ /* todo: plink too? */
8312+ if (!do_udba)
8313+ continue;
8314+
8315+ /* UDBA tests */
8316+ h_inode = h_dentry->d_inode;
8317+ if (unlikely(!!inode != !!h_inode))
8318+ goto err;
8319+
8320+ h_plus = plus;
8321+ h_mode = mode;
8322+ h_cached_inode = h_inode;
8323+ if (h_inode) {
8324+ h_mode = (h_inode->i_mode & S_IFMT);
8325+ h_plus = (h_inode->i_nlink > 0);
8326+ }
8327+ if (inode && ibs <= bindex && bindex <= ibe)
8328+ h_cached_inode = au_h_iptr(inode, bindex);
8329+
523b37e3 8330+ if (!h_nfs) {
38d290e6 8331+ if (unlikely(plus != h_plus && !tmpfile))
523b37e3
AM
8332+ goto err;
8333+ } else {
8334+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED)
8335+ && !is_root
8336+ && !IS_ROOT(h_dentry)
8337+ && unhashed != d_unhashed(h_dentry)))
8338+ goto err;
8339+ }
8340+ if (unlikely(mode != h_mode
1facf9fc 8341+ || h_cached_inode != h_inode))
8342+ goto err;
8343+ continue;
8344+
f6b6e03d 8345+err:
1facf9fc 8346+ err = -EINVAL;
8347+ break;
8348+ }
8349+
523b37e3 8350+ AuTraceErr(err);
1facf9fc 8351+ return err;
8352+}
8353+
027c5e7a 8354+/* todo: consolidate with do_refresh() and au_reval_for_attr() */
1facf9fc 8355+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen)
8356+{
8357+ int err;
8358+ struct dentry *parent;
1facf9fc 8359+
027c5e7a 8360+ if (!au_digen_test(dentry, sigen))
1facf9fc 8361+ return 0;
8362+
8363+ parent = dget_parent(dentry);
8364+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8365+ AuDebugOn(au_digen_test(parent, sigen));
1facf9fc 8366+ au_dbg_verify_gen(parent, sigen);
027c5e7a 8367+ err = au_refresh_dentry(dentry, parent);
1facf9fc 8368+ di_read_unlock(parent, AuLock_IR);
8369+ dput(parent);
027c5e7a 8370+ AuTraceErr(err);
1facf9fc 8371+ return err;
8372+}
8373+
8374+int au_reval_dpath(struct dentry *dentry, unsigned int sigen)
8375+{
8376+ int err;
8377+ struct dentry *d, *parent;
8378+ struct inode *inode;
8379+
027c5e7a 8380+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR))
1facf9fc 8381+ return simple_reval_dpath(dentry, sigen);
8382+
8383+ /* slow loop, keep it simple and stupid */
8384+ /* cf: au_cpup_dirs() */
8385+ err = 0;
8386+ parent = NULL;
027c5e7a 8387+ while (au_digen_test(dentry, sigen)) {
1facf9fc 8388+ d = dentry;
8389+ while (1) {
8390+ dput(parent);
8391+ parent = dget_parent(d);
027c5e7a 8392+ if (!au_digen_test(parent, sigen))
1facf9fc 8393+ break;
8394+ d = parent;
8395+ }
8396+
8397+ inode = d->d_inode;
8398+ if (d != dentry)
027c5e7a 8399+ di_write_lock_child2(d);
1facf9fc 8400+
8401+ /* someone might update our dentry while we were sleeping */
027c5e7a
AM
8402+ if (au_digen_test(d, sigen)) {
8403+ /*
8404+ * todo: consolidate with simple_reval_dpath(),
8405+ * do_refresh() and au_reval_for_attr().
8406+ */
1facf9fc 8407+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 8408+ err = au_refresh_dentry(d, parent);
1facf9fc 8409+ di_read_unlock(parent, AuLock_IR);
8410+ }
8411+
8412+ if (d != dentry)
8413+ di_write_unlock(d);
8414+ dput(parent);
8415+ if (unlikely(err))
8416+ break;
8417+ }
8418+
8419+ return err;
8420+}
8421+
8422+/*
8423+ * if valid returns 1, otherwise 0.
8424+ */
b4510431 8425+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
1facf9fc 8426+{
8427+ int valid, err;
8428+ unsigned int sigen;
8429+ unsigned char do_udba;
8430+ struct super_block *sb;
8431+ struct inode *inode;
8432+
027c5e7a 8433+ /* todo: support rcu-walk? */
b4510431 8434+ if (flags & LOOKUP_RCU)
027c5e7a
AM
8435+ return -ECHILD;
8436+
8437+ valid = 0;
8438+ if (unlikely(!au_di(dentry)))
8439+ goto out;
8440+
e49829fe 8441+ valid = 1;
1facf9fc 8442+ sb = dentry->d_sb;
e49829fe
JR
8443+ /*
8444+ * todo: very ugly
8445+ * i_mutex of parent dir may be held,
8446+ * but we should not return 'invalid' due to busy.
8447+ */
8448+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM);
8449+ if (unlikely(err)) {
8450+ valid = err;
027c5e7a 8451+ AuTraceErr(err);
e49829fe
JR
8452+ goto out;
8453+ }
c1595e42
JR
8454+ inode = dentry->d_inode;
8455+ if (unlikely(inode && is_bad_inode(inode))) {
8456+ err = -EINVAL;
8457+ AuTraceErr(err);
8458+ goto out_dgrade;
8459+ }
027c5e7a
AM
8460+ if (unlikely(au_dbrange_test(dentry))) {
8461+ err = -EINVAL;
8462+ AuTraceErr(err);
8463+ goto out_dgrade;
1facf9fc 8464+ }
027c5e7a
AM
8465+
8466+ sigen = au_sigen(sb);
8467+ if (au_digen_test(dentry, sigen)) {
1facf9fc 8468+ AuDebugOn(IS_ROOT(dentry));
027c5e7a
AM
8469+ err = au_reval_dpath(dentry, sigen);
8470+ if (unlikely(err)) {
8471+ AuTraceErr(err);
1facf9fc 8472+ goto out_dgrade;
027c5e7a 8473+ }
1facf9fc 8474+ }
8475+ di_downgrade_lock(dentry, AuLock_IR);
8476+
1facf9fc 8477+ err = -EINVAL;
c1595e42 8478+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY))
523b37e3 8479+ && inode
38d290e6 8480+ && !(inode->i_state && I_LINKABLE)
523b37e3 8481+ && (IS_DEADDIR(inode) || !inode->i_nlink))
027c5e7a
AM
8482+ goto out_inval;
8483+
1facf9fc 8484+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE);
8485+ if (do_udba && inode) {
8486+ aufs_bindex_t bstart = au_ibstart(inode);
027c5e7a 8487+ struct inode *h_inode;
1facf9fc 8488+
027c5e7a
AM
8489+ if (bstart >= 0) {
8490+ h_inode = au_h_iptr(inode, bstart);
8491+ if (h_inode && au_test_higen(inode, h_inode))
8492+ goto out_inval;
8493+ }
1facf9fc 8494+ }
8495+
b4510431 8496+ err = h_d_revalidate(dentry, inode, flags, do_udba);
027c5e7a 8497+ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) {
1facf9fc 8498+ err = -EIO;
523b37e3
AM
8499+ AuDbg("both of real entry and whiteout found, %p, err %d\n",
8500+ dentry, err);
027c5e7a 8501+ }
e49829fe 8502+ goto out_inval;
1facf9fc 8503+
4f0767ce 8504+out_dgrade:
1facf9fc 8505+ di_downgrade_lock(dentry, AuLock_IR);
e49829fe 8506+out_inval:
1facf9fc 8507+ aufs_read_unlock(dentry, AuLock_IR);
8508+ AuTraceErr(err);
8509+ valid = !err;
e49829fe 8510+out:
027c5e7a 8511+ if (!valid) {
523b37e3 8512+ AuDbg("%pd invalid, %d\n", dentry, valid);
027c5e7a
AM
8513+ d_drop(dentry);
8514+ }
1facf9fc 8515+ return valid;
8516+}
8517+
8518+static void aufs_d_release(struct dentry *dentry)
8519+{
027c5e7a 8520+ if (au_di(dentry)) {
4a4d8108
AM
8521+ au_di_fin(dentry);
8522+ au_hn_di_reinit(dentry);
1facf9fc 8523+ }
1facf9fc 8524+}
8525+
4a4d8108 8526+const struct dentry_operations aufs_dop = {
c06a8ce3
AM
8527+ .d_revalidate = aufs_d_revalidate,
8528+ .d_weak_revalidate = aufs_d_revalidate,
8529+ .d_release = aufs_d_release
1facf9fc 8530+};
7f207e10
AM
8531diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
8532--- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 8533+++ linux/fs/aufs/dentry.h 2015-01-25 13:00:38.631047076 +0100
076b876e 8534@@ -0,0 +1,233 @@
1facf9fc 8535+/*
523b37e3 8536+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 8537+ *
8538+ * This program, aufs is free software; you can redistribute it and/or modify
8539+ * it under the terms of the GNU General Public License as published by
8540+ * the Free Software Foundation; either version 2 of the License, or
8541+ * (at your option) any later version.
dece6358
AM
8542+ *
8543+ * This program is distributed in the hope that it will be useful,
8544+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8545+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8546+ * GNU General Public License for more details.
8547+ *
8548+ * You should have received a copy of the GNU General Public License
523b37e3 8549+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8550+ */
8551+
8552+/*
8553+ * lookup and dentry operations
8554+ */
8555+
8556+#ifndef __AUFS_DENTRY_H__
8557+#define __AUFS_DENTRY_H__
8558+
8559+#ifdef __KERNEL__
8560+
dece6358 8561+#include <linux/dcache.h>
1facf9fc 8562+#include "rwsem.h"
8563+
1facf9fc 8564+struct au_hdentry {
8565+ struct dentry *hd_dentry;
027c5e7a 8566+ aufs_bindex_t hd_id;
1facf9fc 8567+};
8568+
8569+struct au_dinfo {
8570+ atomic_t di_generation;
8571+
dece6358 8572+ struct au_rwsem di_rwsem;
1facf9fc 8573+ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq;
38d290e6 8574+ unsigned char di_tmpfile; /* to allow the different name */
1facf9fc 8575+ struct au_hdentry *di_hdentry;
4a4d8108 8576+} ____cacheline_aligned_in_smp;
1facf9fc 8577+
8578+/* ---------------------------------------------------------------------- */
8579+
8580+/* dentry.c */
4a4d8108 8581+extern const struct dentry_operations aufs_dop;
1facf9fc 8582+struct au_branch;
076b876e 8583+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent);
1facf9fc 8584+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir,
8585+ struct dentry *h_parent, struct au_branch *br);
8586+
537831f9 8587+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type);
86dc4139 8588+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh);
027c5e7a 8589+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent);
1facf9fc 8590+int au_reval_dpath(struct dentry *dentry, unsigned int sigen);
8591+
8592+/* dinfo.c */
4a4d8108 8593+void au_di_init_once(void *_di);
027c5e7a
AM
8594+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc);
8595+void au_di_free(struct au_dinfo *dinfo);
8596+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b);
8597+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src);
4a4d8108
AM
8598+int au_di_init(struct dentry *dentry);
8599+void au_di_fin(struct dentry *dentry);
1facf9fc 8600+int au_di_realloc(struct au_dinfo *dinfo, int nbr);
8601+
8602+void di_read_lock(struct dentry *d, int flags, unsigned int lsc);
8603+void di_read_unlock(struct dentry *d, int flags);
8604+void di_downgrade_lock(struct dentry *d, int flags);
8605+void di_write_lock(struct dentry *d, unsigned int lsc);
8606+void di_write_unlock(struct dentry *d);
8607+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir);
8608+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
8609+void di_write_unlock2(struct dentry *d1, struct dentry *d2);
8610+
8611+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
2cbb1c4b 8612+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
1facf9fc 8613+aufs_bindex_t au_dbtail(struct dentry *dentry);
8614+aufs_bindex_t au_dbtaildir(struct dentry *dentry);
8615+
8616+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
8617+ struct dentry *h_dentry);
027c5e7a
AM
8618+int au_digen_test(struct dentry *dentry, unsigned int sigen);
8619+int au_dbrange_test(struct dentry *dentry);
1facf9fc 8620+void au_update_digen(struct dentry *dentry);
8621+void au_update_dbrange(struct dentry *dentry, int do_put_zero);
8622+void au_update_dbstart(struct dentry *dentry);
8623+void au_update_dbend(struct dentry *dentry);
8624+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry);
8625+
8626+/* ---------------------------------------------------------------------- */
8627+
8628+static inline struct au_dinfo *au_di(struct dentry *dentry)
8629+{
8630+ return dentry->d_fsdata;
8631+}
8632+
8633+/* ---------------------------------------------------------------------- */
8634+
8635+/* lock subclass for dinfo */
8636+enum {
8637+ AuLsc_DI_CHILD, /* child first */
4a4d8108 8638+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */
1facf9fc 8639+ AuLsc_DI_CHILD3, /* copyup dirs */
8640+ AuLsc_DI_PARENT,
8641+ AuLsc_DI_PARENT2,
027c5e7a
AM
8642+ AuLsc_DI_PARENT3,
8643+ AuLsc_DI_TMP /* temp for replacing dinfo */
1facf9fc 8644+};
8645+
8646+/*
8647+ * di_read_lock_child, di_write_lock_child,
8648+ * di_read_lock_child2, di_write_lock_child2,
8649+ * di_read_lock_child3, di_write_lock_child3,
8650+ * di_read_lock_parent, di_write_lock_parent,
8651+ * di_read_lock_parent2, di_write_lock_parent2,
8652+ * di_read_lock_parent3, di_write_lock_parent3,
8653+ */
8654+#define AuReadLockFunc(name, lsc) \
8655+static inline void di_read_lock_##name(struct dentry *d, int flags) \
8656+{ di_read_lock(d, flags, AuLsc_DI_##lsc); }
8657+
8658+#define AuWriteLockFunc(name, lsc) \
8659+static inline void di_write_lock_##name(struct dentry *d) \
8660+{ di_write_lock(d, AuLsc_DI_##lsc); }
8661+
8662+#define AuRWLockFuncs(name, lsc) \
8663+ AuReadLockFunc(name, lsc) \
8664+ AuWriteLockFunc(name, lsc)
8665+
8666+AuRWLockFuncs(child, CHILD);
8667+AuRWLockFuncs(child2, CHILD2);
8668+AuRWLockFuncs(child3, CHILD3);
8669+AuRWLockFuncs(parent, PARENT);
8670+AuRWLockFuncs(parent2, PARENT2);
8671+AuRWLockFuncs(parent3, PARENT3);
8672+
8673+#undef AuReadLockFunc
8674+#undef AuWriteLockFunc
8675+#undef AuRWLockFuncs
8676+
8677+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem)
dece6358
AM
8678+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem)
8679+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem)
1facf9fc 8680+
8681+/* ---------------------------------------------------------------------- */
8682+
8683+/* todo: memory barrier? */
8684+static inline unsigned int au_digen(struct dentry *d)
8685+{
8686+ return atomic_read(&au_di(d)->di_generation);
8687+}
8688+
8689+static inline void au_h_dentry_init(struct au_hdentry *hdentry)
8690+{
8691+ hdentry->hd_dentry = NULL;
8692+}
8693+
8694+static inline void au_hdput(struct au_hdentry *hd)
8695+{
4a4d8108
AM
8696+ if (hd)
8697+ dput(hd->hd_dentry);
1facf9fc 8698+}
8699+
8700+static inline aufs_bindex_t au_dbstart(struct dentry *dentry)
8701+{
1308ab2a 8702+ DiMustAnyLock(dentry);
1facf9fc 8703+ return au_di(dentry)->di_bstart;
8704+}
8705+
8706+static inline aufs_bindex_t au_dbend(struct dentry *dentry)
8707+{
1308ab2a 8708+ DiMustAnyLock(dentry);
1facf9fc 8709+ return au_di(dentry)->di_bend;
8710+}
8711+
8712+static inline aufs_bindex_t au_dbwh(struct dentry *dentry)
8713+{
1308ab2a 8714+ DiMustAnyLock(dentry);
1facf9fc 8715+ return au_di(dentry)->di_bwh;
8716+}
8717+
8718+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry)
8719+{
1308ab2a 8720+ DiMustAnyLock(dentry);
1facf9fc 8721+ return au_di(dentry)->di_bdiropq;
8722+}
8723+
8724+/* todo: hard/soft set? */
8725+static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex)
8726+{
1308ab2a 8727+ DiMustWriteLock(dentry);
1facf9fc 8728+ au_di(dentry)->di_bstart = bindex;
8729+}
8730+
8731+static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex)
8732+{
1308ab2a 8733+ DiMustWriteLock(dentry);
1facf9fc 8734+ au_di(dentry)->di_bend = bindex;
8735+}
8736+
8737+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex)
8738+{
1308ab2a 8739+ DiMustWriteLock(dentry);
1facf9fc 8740+ /* dbwh can be outside of bstart - bend range */
8741+ au_di(dentry)->di_bwh = bindex;
8742+}
8743+
8744+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex)
8745+{
1308ab2a 8746+ DiMustWriteLock(dentry);
1facf9fc 8747+ au_di(dentry)->di_bdiropq = bindex;
8748+}
8749+
8750+/* ---------------------------------------------------------------------- */
8751+
4a4d8108 8752+#ifdef CONFIG_AUFS_HNOTIFY
1facf9fc 8753+static inline void au_digen_dec(struct dentry *d)
8754+{
e49829fe 8755+ atomic_dec(&au_di(d)->di_generation);
1facf9fc 8756+}
8757+
4a4d8108 8758+static inline void au_hn_di_reinit(struct dentry *dentry)
1facf9fc 8759+{
8760+ dentry->d_fsdata = NULL;
8761+}
8762+#else
4a4d8108
AM
8763+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused)
8764+#endif /* CONFIG_AUFS_HNOTIFY */
1facf9fc 8765+
8766+#endif /* __KERNEL__ */
8767+#endif /* __AUFS_DENTRY_H__ */
7f207e10
AM
8768diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
8769--- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 8770+++ linux/fs/aufs/dinfo.c 2015-01-25 13:00:38.631047076 +0100
38d290e6 8771@@ -0,0 +1,544 @@
1facf9fc 8772+/*
523b37e3 8773+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 8774+ *
8775+ * This program, aufs is free software; you can redistribute it and/or modify
8776+ * it under the terms of the GNU General Public License as published by
8777+ * the Free Software Foundation; either version 2 of the License, or
8778+ * (at your option) any later version.
dece6358
AM
8779+ *
8780+ * This program is distributed in the hope that it will be useful,
8781+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8782+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8783+ * GNU General Public License for more details.
8784+ *
8785+ * You should have received a copy of the GNU General Public License
523b37e3 8786+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 8787+ */
8788+
8789+/*
8790+ * dentry private data
8791+ */
8792+
8793+#include "aufs.h"
8794+
e49829fe 8795+void au_di_init_once(void *_dinfo)
4a4d8108 8796+{
e49829fe
JR
8797+ struct au_dinfo *dinfo = _dinfo;
8798+ static struct lock_class_key aufs_di;
4a4d8108 8799+
e49829fe
JR
8800+ au_rw_init(&dinfo->di_rwsem);
8801+ au_rw_class(&dinfo->di_rwsem, &aufs_di);
4a4d8108
AM
8802+}
8803+
027c5e7a 8804+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc)
1facf9fc 8805+{
8806+ struct au_dinfo *dinfo;
027c5e7a 8807+ int nbr, i;
1facf9fc 8808+
8809+ dinfo = au_cache_alloc_dinfo();
8810+ if (unlikely(!dinfo))
8811+ goto out;
8812+
1facf9fc 8813+ nbr = au_sbend(sb) + 1;
8814+ if (nbr <= 0)
8815+ nbr = 1;
8816+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS);
027c5e7a
AM
8817+ if (dinfo->di_hdentry) {
8818+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc);
8819+ dinfo->di_bstart = -1;
8820+ dinfo->di_bend = -1;
8821+ dinfo->di_bwh = -1;
8822+ dinfo->di_bdiropq = -1;
38d290e6 8823+ dinfo->di_tmpfile = 0;
027c5e7a
AM
8824+ for (i = 0; i < nbr; i++)
8825+ dinfo->di_hdentry[i].hd_id = -1;
8826+ goto out;
8827+ }
1facf9fc 8828+
1facf9fc 8829+ au_cache_free_dinfo(dinfo);
027c5e7a
AM
8830+ dinfo = NULL;
8831+
4f0767ce 8832+out:
027c5e7a 8833+ return dinfo;
1facf9fc 8834+}
8835+
027c5e7a 8836+void au_di_free(struct au_dinfo *dinfo)
4a4d8108 8837+{
4a4d8108
AM
8838+ struct au_hdentry *p;
8839+ aufs_bindex_t bend, bindex;
8840+
8841+ /* dentry may not be revalidated */
027c5e7a 8842+ bindex = dinfo->di_bstart;
4a4d8108 8843+ if (bindex >= 0) {
027c5e7a
AM
8844+ bend = dinfo->di_bend;
8845+ p = dinfo->di_hdentry + bindex;
4a4d8108
AM
8846+ while (bindex++ <= bend)
8847+ au_hdput(p++);
8848+ }
027c5e7a
AM
8849+ kfree(dinfo->di_hdentry);
8850+ au_cache_free_dinfo(dinfo);
8851+}
8852+
8853+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
8854+{
8855+ struct au_hdentry *p;
8856+ aufs_bindex_t bi;
8857+
8858+ AuRwMustWriteLock(&a->di_rwsem);
8859+ AuRwMustWriteLock(&b->di_rwsem);
8860+
8861+#define DiSwap(v, name) \
8862+ do { \
8863+ v = a->di_##name; \
8864+ a->di_##name = b->di_##name; \
8865+ b->di_##name = v; \
8866+ } while (0)
8867+
8868+ DiSwap(p, hdentry);
8869+ DiSwap(bi, bstart);
8870+ DiSwap(bi, bend);
8871+ DiSwap(bi, bwh);
8872+ DiSwap(bi, bdiropq);
8873+ /* smp_mb(); */
8874+
8875+#undef DiSwap
8876+}
8877+
8878+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src)
8879+{
8880+ AuRwMustWriteLock(&dst->di_rwsem);
8881+ AuRwMustWriteLock(&src->di_rwsem);
8882+
8883+ dst->di_bstart = src->di_bstart;
8884+ dst->di_bend = src->di_bend;
8885+ dst->di_bwh = src->di_bwh;
8886+ dst->di_bdiropq = src->di_bdiropq;
8887+ /* smp_mb(); */
8888+}
8889+
8890+int au_di_init(struct dentry *dentry)
8891+{
8892+ int err;
8893+ struct super_block *sb;
8894+ struct au_dinfo *dinfo;
8895+
8896+ err = 0;
8897+ sb = dentry->d_sb;
8898+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD);
8899+ if (dinfo) {
8900+ atomic_set(&dinfo->di_generation, au_sigen(sb));
8901+ /* smp_mb(); */ /* atomic_set */
8902+ dentry->d_fsdata = dinfo;
8903+ } else
8904+ err = -ENOMEM;
8905+
8906+ return err;
8907+}
8908+
8909+void au_di_fin(struct dentry *dentry)
8910+{
8911+ struct au_dinfo *dinfo;
8912+
8913+ dinfo = au_di(dentry);
8914+ AuRwDestroy(&dinfo->di_rwsem);
8915+ au_di_free(dinfo);
4a4d8108
AM
8916+}
8917+
1facf9fc 8918+int au_di_realloc(struct au_dinfo *dinfo, int nbr)
8919+{
8920+ int err, sz;
8921+ struct au_hdentry *hdp;
8922+
1308ab2a 8923+ AuRwMustWriteLock(&dinfo->di_rwsem);
8924+
1facf9fc 8925+ err = -ENOMEM;
8926+ sz = sizeof(*hdp) * (dinfo->di_bend + 1);
8927+ if (!sz)
8928+ sz = sizeof(*hdp);
8929+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS);
8930+ if (hdp) {
8931+ dinfo->di_hdentry = hdp;
8932+ err = 0;
8933+ }
8934+
8935+ return err;
8936+}
8937+
8938+/* ---------------------------------------------------------------------- */
8939+
8940+static void do_ii_write_lock(struct inode *inode, unsigned int lsc)
8941+{
8942+ switch (lsc) {
8943+ case AuLsc_DI_CHILD:
8944+ ii_write_lock_child(inode);
8945+ break;
8946+ case AuLsc_DI_CHILD2:
8947+ ii_write_lock_child2(inode);
8948+ break;
8949+ case AuLsc_DI_CHILD3:
8950+ ii_write_lock_child3(inode);
8951+ break;
8952+ case AuLsc_DI_PARENT:
8953+ ii_write_lock_parent(inode);
8954+ break;
8955+ case AuLsc_DI_PARENT2:
8956+ ii_write_lock_parent2(inode);
8957+ break;
8958+ case AuLsc_DI_PARENT3:
8959+ ii_write_lock_parent3(inode);
8960+ break;
8961+ default:
8962+ BUG();
8963+ }
8964+}
8965+
8966+static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
8967+{
8968+ switch (lsc) {
8969+ case AuLsc_DI_CHILD:
8970+ ii_read_lock_child(inode);
8971+ break;
8972+ case AuLsc_DI_CHILD2:
8973+ ii_read_lock_child2(inode);
8974+ break;
8975+ case AuLsc_DI_CHILD3:
8976+ ii_read_lock_child3(inode);
8977+ break;
8978+ case AuLsc_DI_PARENT:
8979+ ii_read_lock_parent(inode);
8980+ break;
8981+ case AuLsc_DI_PARENT2:
8982+ ii_read_lock_parent2(inode);
8983+ break;
8984+ case AuLsc_DI_PARENT3:
8985+ ii_read_lock_parent3(inode);
8986+ break;
8987+ default:
8988+ BUG();
8989+ }
8990+}
8991+
8992+void di_read_lock(struct dentry *d, int flags, unsigned int lsc)
8993+{
dece6358 8994+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 8995+ if (d->d_inode) {
8996+ if (au_ftest_lock(flags, IW))
8997+ do_ii_write_lock(d->d_inode, lsc);
8998+ else if (au_ftest_lock(flags, IR))
8999+ do_ii_read_lock(d->d_inode, lsc);
9000+ }
9001+}
9002+
9003+void di_read_unlock(struct dentry *d, int flags)
9004+{
9005+ if (d->d_inode) {
027c5e7a
AM
9006+ if (au_ftest_lock(flags, IW)) {
9007+ au_dbg_verify_dinode(d);
1facf9fc 9008+ ii_write_unlock(d->d_inode);
027c5e7a
AM
9009+ } else if (au_ftest_lock(flags, IR)) {
9010+ au_dbg_verify_dinode(d);
1facf9fc 9011+ ii_read_unlock(d->d_inode);
027c5e7a 9012+ }
1facf9fc 9013+ }
dece6358 9014+ au_rw_read_unlock(&au_di(d)->di_rwsem);
1facf9fc 9015+}
9016+
9017+void di_downgrade_lock(struct dentry *d, int flags)
9018+{
1facf9fc 9019+ if (d->d_inode && au_ftest_lock(flags, IR))
9020+ ii_downgrade_lock(d->d_inode);
dece6358 9021+ au_rw_dgrade_lock(&au_di(d)->di_rwsem);
1facf9fc 9022+}
9023+
9024+void di_write_lock(struct dentry *d, unsigned int lsc)
9025+{
dece6358 9026+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc);
1facf9fc 9027+ if (d->d_inode)
9028+ do_ii_write_lock(d->d_inode, lsc);
9029+}
9030+
9031+void di_write_unlock(struct dentry *d)
9032+{
027c5e7a 9033+ au_dbg_verify_dinode(d);
1facf9fc 9034+ if (d->d_inode)
9035+ ii_write_unlock(d->d_inode);
dece6358 9036+ au_rw_write_unlock(&au_di(d)->di_rwsem);
1facf9fc 9037+}
9038+
9039+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir)
9040+{
9041+ AuDebugOn(d1 == d2
9042+ || d1->d_inode == d2->d_inode
9043+ || d1->d_sb != d2->d_sb);
9044+
9045+ if (isdir && au_test_subdir(d1, d2)) {
9046+ di_write_lock_child(d1);
9047+ di_write_lock_child2(d2);
9048+ } else {
9049+ /* there should be no races */
9050+ di_write_lock_child(d2);
9051+ di_write_lock_child2(d1);
9052+ }
9053+}
9054+
9055+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
9056+{
9057+ AuDebugOn(d1 == d2
9058+ || d1->d_inode == d2->d_inode
9059+ || d1->d_sb != d2->d_sb);
9060+
9061+ if (isdir && au_test_subdir(d1, d2)) {
9062+ di_write_lock_parent(d1);
9063+ di_write_lock_parent2(d2);
9064+ } else {
9065+ /* there should be no races */
9066+ di_write_lock_parent(d2);
9067+ di_write_lock_parent2(d1);
9068+ }
9069+}
9070+
9071+void di_write_unlock2(struct dentry *d1, struct dentry *d2)
9072+{
9073+ di_write_unlock(d1);
9074+ if (d1->d_inode == d2->d_inode)
dece6358 9075+ au_rw_write_unlock(&au_di(d2)->di_rwsem);
1facf9fc 9076+ else
9077+ di_write_unlock(d2);
9078+}
9079+
9080+/* ---------------------------------------------------------------------- */
9081+
9082+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
9083+{
9084+ struct dentry *d;
9085+
1308ab2a 9086+ DiMustAnyLock(dentry);
9087+
1facf9fc 9088+ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
9089+ return NULL;
9090+ AuDebugOn(bindex < 0);
9091+ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
c1595e42 9092+ AuDebugOn(d && au_dcount(d) <= 0);
1facf9fc 9093+ return d;
9094+}
9095+
2cbb1c4b
JR
9096+/*
9097+ * extended version of au_h_dptr().
38d290e6
JR
9098+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or
9099+ * error.
2cbb1c4b
JR
9100+ */
9101+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
9102+{
9103+ struct dentry *h_dentry;
9104+ struct inode *inode, *h_inode;
9105+
9106+ inode = dentry->d_inode;
9107+ AuDebugOn(!inode);
9108+
9109+ h_dentry = NULL;
9110+ if (au_dbstart(dentry) <= bindex
9111+ && bindex <= au_dbend(dentry))
9112+ h_dentry = au_h_dptr(dentry, bindex);
38d290e6 9113+ if (h_dentry && !au_d_linkable(h_dentry)) {
2cbb1c4b
JR
9114+ dget(h_dentry);
9115+ goto out; /* success */
9116+ }
9117+
9118+ AuDebugOn(bindex < au_ibstart(inode));
9119+ AuDebugOn(au_ibend(inode) < bindex);
9120+ h_inode = au_h_iptr(inode, bindex);
9121+ h_dentry = d_find_alias(h_inode);
9122+ if (h_dentry) {
9123+ if (!IS_ERR(h_dentry)) {
38d290e6 9124+ if (!au_d_linkable(h_dentry))
2cbb1c4b
JR
9125+ goto out; /* success */
9126+ dput(h_dentry);
9127+ } else
9128+ goto out;
9129+ }
9130+
9131+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
9132+ h_dentry = au_plink_lkup(inode, bindex);
9133+ AuDebugOn(!h_dentry);
9134+ if (!IS_ERR(h_dentry)) {
9135+ if (!au_d_hashed_positive(h_dentry))
9136+ goto out; /* success */
9137+ dput(h_dentry);
9138+ h_dentry = NULL;
9139+ }
9140+ }
9141+
9142+out:
9143+ AuDbgDentry(h_dentry);
9144+ return h_dentry;
9145+}
9146+
1facf9fc 9147+aufs_bindex_t au_dbtail(struct dentry *dentry)
9148+{
9149+ aufs_bindex_t bend, bwh;
9150+
9151+ bend = au_dbend(dentry);
9152+ if (0 <= bend) {
9153+ bwh = au_dbwh(dentry);
9154+ if (!bwh)
9155+ return bwh;
9156+ if (0 < bwh && bwh < bend)
9157+ return bwh - 1;
9158+ }
9159+ return bend;
9160+}
9161+
9162+aufs_bindex_t au_dbtaildir(struct dentry *dentry)
9163+{
9164+ aufs_bindex_t bend, bopq;
9165+
9166+ bend = au_dbtail(dentry);
9167+ if (0 <= bend) {
9168+ bopq = au_dbdiropq(dentry);
9169+ if (0 <= bopq && bopq < bend)
9170+ bend = bopq;
9171+ }
9172+ return bend;
9173+}
9174+
9175+/* ---------------------------------------------------------------------- */
9176+
9177+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
9178+ struct dentry *h_dentry)
9179+{
9180+ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
027c5e7a 9181+ struct au_branch *br;
1facf9fc 9182+
1308ab2a 9183+ DiMustWriteLock(dentry);
9184+
4a4d8108 9185+ au_hdput(hd);
1facf9fc 9186+ hd->hd_dentry = h_dentry;
027c5e7a
AM
9187+ if (h_dentry) {
9188+ br = au_sbr(dentry->d_sb, bindex);
9189+ hd->hd_id = br->br_id;
9190+ }
9191+}
9192+
9193+int au_dbrange_test(struct dentry *dentry)
9194+{
9195+ int err;
9196+ aufs_bindex_t bstart, bend;
9197+
9198+ err = 0;
9199+ bstart = au_dbstart(dentry);
9200+ bend = au_dbend(dentry);
9201+ if (bstart >= 0)
9202+ AuDebugOn(bend < 0 && bstart > bend);
9203+ else {
9204+ err = -EIO;
9205+ AuDebugOn(bend >= 0);
9206+ }
9207+
9208+ return err;
9209+}
9210+
9211+int au_digen_test(struct dentry *dentry, unsigned int sigen)
9212+{
9213+ int err;
9214+
9215+ err = 0;
9216+ if (unlikely(au_digen(dentry) != sigen
9217+ || au_iigen_test(dentry->d_inode, sigen)))
9218+ err = -EIO;
9219+
9220+ return err;
1facf9fc 9221+}
9222+
9223+void au_update_digen(struct dentry *dentry)
9224+{
9225+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb));
9226+ /* smp_mb(); */ /* atomic_set */
9227+}
9228+
9229+void au_update_dbrange(struct dentry *dentry, int do_put_zero)
9230+{
9231+ struct au_dinfo *dinfo;
9232+ struct dentry *h_d;
4a4d8108 9233+ struct au_hdentry *hdp;
1facf9fc 9234+
1308ab2a 9235+ DiMustWriteLock(dentry);
9236+
1facf9fc 9237+ dinfo = au_di(dentry);
9238+ if (!dinfo || dinfo->di_bstart < 0)
9239+ return;
9240+
4a4d8108 9241+ hdp = dinfo->di_hdentry;
1facf9fc 9242+ if (do_put_zero) {
9243+ aufs_bindex_t bindex, bend;
9244+
9245+ bend = dinfo->di_bend;
9246+ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) {
4a4d8108 9247+ h_d = hdp[0 + bindex].hd_dentry;
1facf9fc 9248+ if (h_d && !h_d->d_inode)
9249+ au_set_h_dptr(dentry, bindex, NULL);
9250+ }
9251+ }
9252+
9253+ dinfo->di_bstart = -1;
9254+ while (++dinfo->di_bstart <= dinfo->di_bend)
4a4d8108 9255+ if (hdp[0 + dinfo->di_bstart].hd_dentry)
1facf9fc 9256+ break;
9257+ if (dinfo->di_bstart > dinfo->di_bend) {
9258+ dinfo->di_bstart = -1;
9259+ dinfo->di_bend = -1;
9260+ return;
9261+ }
9262+
9263+ dinfo->di_bend++;
9264+ while (0 <= --dinfo->di_bend)
4a4d8108 9265+ if (hdp[0 + dinfo->di_bend].hd_dentry)
1facf9fc 9266+ break;
9267+ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0);
9268+}
9269+
9270+void au_update_dbstart(struct dentry *dentry)
9271+{
9272+ aufs_bindex_t bindex, bend;
9273+ struct dentry *h_dentry;
9274+
9275+ bend = au_dbend(dentry);
9276+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
9277+ h_dentry = au_h_dptr(dentry, bindex);
9278+ if (!h_dentry)
9279+ continue;
9280+ if (h_dentry->d_inode) {
9281+ au_set_dbstart(dentry, bindex);
9282+ return;
9283+ }
9284+ au_set_h_dptr(dentry, bindex, NULL);
9285+ }
9286+}
9287+
9288+void au_update_dbend(struct dentry *dentry)
9289+{
9290+ aufs_bindex_t bindex, bstart;
9291+ struct dentry *h_dentry;
9292+
9293+ bstart = au_dbstart(dentry);
7f207e10 9294+ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) {
1facf9fc 9295+ h_dentry = au_h_dptr(dentry, bindex);
9296+ if (!h_dentry)
9297+ continue;
9298+ if (h_dentry->d_inode) {
9299+ au_set_dbend(dentry, bindex);
9300+ return;
9301+ }
9302+ au_set_h_dptr(dentry, bindex, NULL);
9303+ }
9304+}
9305+
9306+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry)
9307+{
9308+ aufs_bindex_t bindex, bend;
9309+
9310+ bend = au_dbend(dentry);
9311+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++)
9312+ if (au_h_dptr(dentry, bindex) == h_dentry)
9313+ return bindex;
9314+ return -1;
9315+}
7f207e10
AM
9316diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
9317--- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 9318+++ linux/fs/aufs/dir.c 2015-01-25 13:00:38.631047076 +0100
076b876e 9319@@ -0,0 +1,645 @@
1facf9fc 9320+/*
523b37e3 9321+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 9322+ *
9323+ * This program, aufs is free software; you can redistribute it and/or modify
9324+ * it under the terms of the GNU General Public License as published by
9325+ * the Free Software Foundation; either version 2 of the License, or
9326+ * (at your option) any later version.
dece6358
AM
9327+ *
9328+ * This program is distributed in the hope that it will be useful,
9329+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9330+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9331+ * GNU General Public License for more details.
9332+ *
9333+ * You should have received a copy of the GNU General Public License
523b37e3 9334+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9335+ */
9336+
9337+/*
9338+ * directory operations
9339+ */
9340+
9341+#include <linux/fs_stack.h>
9342+#include "aufs.h"
9343+
9344+void au_add_nlink(struct inode *dir, struct inode *h_dir)
9345+{
9dbd164d
AM
9346+ unsigned int nlink;
9347+
1facf9fc 9348+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9349+
9dbd164d
AM
9350+ nlink = dir->i_nlink;
9351+ nlink += h_dir->i_nlink - 2;
1facf9fc 9352+ if (h_dir->i_nlink < 2)
9dbd164d 9353+ nlink += 2;
f6b6e03d 9354+ smp_mb(); /* for i_nlink */
7eafdf33 9355+ /* 0 can happen in revaliding */
92d182d2 9356+ set_nlink(dir, nlink);
1facf9fc 9357+}
9358+
9359+void au_sub_nlink(struct inode *dir, struct inode *h_dir)
9360+{
9dbd164d
AM
9361+ unsigned int nlink;
9362+
1facf9fc 9363+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode));
9364+
9dbd164d
AM
9365+ nlink = dir->i_nlink;
9366+ nlink -= h_dir->i_nlink - 2;
1facf9fc 9367+ if (h_dir->i_nlink < 2)
9dbd164d 9368+ nlink -= 2;
f6b6e03d 9369+ smp_mb(); /* for i_nlink */
92d182d2 9370+ /* nlink == 0 means the branch-fs is broken */
9dbd164d 9371+ set_nlink(dir, nlink);
1facf9fc 9372+}
9373+
1308ab2a 9374+loff_t au_dir_size(struct file *file, struct dentry *dentry)
9375+{
9376+ loff_t sz;
9377+ aufs_bindex_t bindex, bend;
9378+ struct file *h_file;
9379+ struct dentry *h_dentry;
9380+
9381+ sz = 0;
9382+ if (file) {
c06a8ce3
AM
9383+ AuDebugOn(!file_inode(file));
9384+ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode));
1308ab2a 9385+
4a4d8108 9386+ bend = au_fbend_dir(file);
1308ab2a 9387+ for (bindex = au_fbstart(file);
9388+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9389+ bindex++) {
4a4d8108 9390+ h_file = au_hf_dir(file, bindex);
c06a8ce3
AM
9391+ if (h_file && file_inode(h_file))
9392+ sz += vfsub_f_size_read(h_file);
1308ab2a 9393+ }
9394+ } else {
9395+ AuDebugOn(!dentry);
9396+ AuDebugOn(!dentry->d_inode);
9397+ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
9398+
9399+ bend = au_dbtaildir(dentry);
9400+ for (bindex = au_dbstart(dentry);
9401+ bindex <= bend && sz < KMALLOC_MAX_SIZE;
9402+ bindex++) {
9403+ h_dentry = au_h_dptr(dentry, bindex);
9404+ if (h_dentry && h_dentry->d_inode)
9405+ sz += i_size_read(h_dentry->d_inode);
9406+ }
9407+ }
9408+ if (sz < KMALLOC_MAX_SIZE)
9409+ sz = roundup_pow_of_two(sz);
9410+ if (sz > KMALLOC_MAX_SIZE)
9411+ sz = KMALLOC_MAX_SIZE;
9412+ else if (sz < NAME_MAX) {
9413+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX);
9414+ sz = AUFS_RDBLK_DEF;
9415+ }
9416+ return sz;
9417+}
9418+
1facf9fc 9419+/* ---------------------------------------------------------------------- */
9420+
9421+static int reopen_dir(struct file *file)
9422+{
9423+ int err;
9424+ unsigned int flags;
9425+ aufs_bindex_t bindex, btail, bstart;
9426+ struct dentry *dentry, *h_dentry;
9427+ struct file *h_file;
9428+
9429+ /* open all lower dirs */
9430+ dentry = file->f_dentry;
9431+ bstart = au_dbstart(dentry);
9432+ for (bindex = au_fbstart(file); bindex < bstart; bindex++)
9433+ au_set_h_fptr(file, bindex, NULL);
9434+ au_set_fbstart(file, bstart);
9435+
9436+ btail = au_dbtaildir(dentry);
4a4d8108 9437+ for (bindex = au_fbend_dir(file); btail < bindex; bindex--)
1facf9fc 9438+ au_set_h_fptr(file, bindex, NULL);
4a4d8108 9439+ au_set_fbend_dir(file, btail);
1facf9fc 9440+
4a4d8108 9441+ flags = vfsub_file_flags(file);
1facf9fc 9442+ for (bindex = bstart; bindex <= btail; bindex++) {
9443+ h_dentry = au_h_dptr(dentry, bindex);
9444+ if (!h_dentry)
9445+ continue;
4a4d8108 9446+ h_file = au_hf_dir(file, bindex);
1facf9fc 9447+ if (h_file)
9448+ continue;
9449+
392086de 9450+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9451+ err = PTR_ERR(h_file);
9452+ if (IS_ERR(h_file))
9453+ goto out; /* close all? */
9454+ au_set_h_fptr(file, bindex, h_file);
9455+ }
9456+ au_update_figen(file);
9457+ /* todo: necessary? */
9458+ /* file->f_ra = h_file->f_ra; */
9459+ err = 0;
9460+
4f0767ce 9461+out:
1facf9fc 9462+ return err;
9463+}
9464+
9465+static int do_open_dir(struct file *file, int flags)
9466+{
9467+ int err;
9468+ aufs_bindex_t bindex, btail;
9469+ struct dentry *dentry, *h_dentry;
9470+ struct file *h_file;
9471+
1308ab2a 9472+ FiMustWriteLock(file);
9473+
523b37e3 9474+ err = 0;
1facf9fc 9475+ dentry = file->f_dentry;
1facf9fc 9476+ file->f_version = dentry->d_inode->i_version;
9477+ bindex = au_dbstart(dentry);
9478+ au_set_fbstart(file, bindex);
9479+ btail = au_dbtaildir(dentry);
4a4d8108 9480+ au_set_fbend_dir(file, btail);
1facf9fc 9481+ for (; !err && bindex <= btail; bindex++) {
9482+ h_dentry = au_h_dptr(dentry, bindex);
9483+ if (!h_dentry)
9484+ continue;
9485+
392086de 9486+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
1facf9fc 9487+ if (IS_ERR(h_file)) {
9488+ err = PTR_ERR(h_file);
9489+ break;
9490+ }
9491+ au_set_h_fptr(file, bindex, h_file);
9492+ }
9493+ au_update_figen(file);
9494+ /* todo: necessary? */
9495+ /* file->f_ra = h_file->f_ra; */
9496+ if (!err)
9497+ return 0; /* success */
9498+
9499+ /* close all */
9500+ for (bindex = au_fbstart(file); bindex <= btail; bindex++)
9501+ au_set_h_fptr(file, bindex, NULL);
9502+ au_set_fbstart(file, -1);
4a4d8108
AM
9503+ au_set_fbend_dir(file, -1);
9504+
1facf9fc 9505+ return err;
9506+}
9507+
9508+static int aufs_open_dir(struct inode *inode __maybe_unused,
9509+ struct file *file)
9510+{
4a4d8108
AM
9511+ int err;
9512+ struct super_block *sb;
9513+ struct au_fidir *fidir;
9514+
9515+ err = -ENOMEM;
9516+ sb = file->f_dentry->d_sb;
9517+ si_read_lock(sb, AuLock_FLUSH);
e49829fe 9518+ fidir = au_fidir_alloc(sb);
4a4d8108
AM
9519+ if (fidir) {
9520+ err = au_do_open(file, do_open_dir, fidir);
9521+ if (unlikely(err))
9522+ kfree(fidir);
9523+ }
9524+ si_read_unlock(sb);
9525+ return err;
1facf9fc 9526+}
9527+
9528+static int aufs_release_dir(struct inode *inode __maybe_unused,
9529+ struct file *file)
9530+{
9531+ struct au_vdir *vdir_cache;
4a4d8108
AM
9532+ struct au_finfo *finfo;
9533+ struct au_fidir *fidir;
9534+ aufs_bindex_t bindex, bend;
1facf9fc 9535+
4a4d8108
AM
9536+ finfo = au_fi(file);
9537+ fidir = finfo->fi_hdir;
9538+ if (fidir) {
076b876e
AM
9539+ au_sphl_del(&finfo->fi_hlist,
9540+ &au_sbi(file->f_dentry->d_sb)->si_files);
4a4d8108
AM
9541+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */
9542+ if (vdir_cache)
9543+ au_vdir_free(vdir_cache);
9544+
9545+ bindex = finfo->fi_btop;
9546+ if (bindex >= 0) {
9547+ /*
9548+ * calls fput() instead of filp_close(),
9549+ * since no dnotify or lock for the lower file.
9550+ */
9551+ bend = fidir->fd_bbot;
9552+ for (; bindex <= bend; bindex++)
9553+ au_set_h_fptr(file, bindex, NULL);
9554+ }
9555+ kfree(fidir);
9556+ finfo->fi_hdir = NULL;
1facf9fc 9557+ }
1facf9fc 9558+ au_finfo_fin(file);
1facf9fc 9559+ return 0;
9560+}
9561+
9562+/* ---------------------------------------------------------------------- */
9563+
4a4d8108
AM
9564+static int au_do_flush_dir(struct file *file, fl_owner_t id)
9565+{
9566+ int err;
9567+ aufs_bindex_t bindex, bend;
9568+ struct file *h_file;
9569+
9570+ err = 0;
9571+ bend = au_fbend_dir(file);
9572+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
9573+ h_file = au_hf_dir(file, bindex);
9574+ if (h_file)
9575+ err = vfsub_flush(h_file, id);
9576+ }
9577+ return err;
9578+}
9579+
9580+static int aufs_flush_dir(struct file *file, fl_owner_t id)
9581+{
9582+ return au_do_flush(file, id, au_do_flush_dir);
9583+}
9584+
9585+/* ---------------------------------------------------------------------- */
9586+
1facf9fc 9587+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync)
9588+{
9589+ int err;
9590+ aufs_bindex_t bend, bindex;
9591+ struct inode *inode;
9592+ struct super_block *sb;
9593+
9594+ err = 0;
9595+ sb = dentry->d_sb;
9596+ inode = dentry->d_inode;
9597+ IMustLock(inode);
9598+ bend = au_dbend(dentry);
9599+ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
9600+ struct path h_path;
1facf9fc 9601+
9602+ if (au_test_ro(sb, bindex, inode))
9603+ continue;
9604+ h_path.dentry = au_h_dptr(dentry, bindex);
9605+ if (!h_path.dentry)
9606+ continue;
1facf9fc 9607+
1facf9fc 9608+ h_path.mnt = au_sbr_mnt(sb, bindex);
53392da6 9609+ err = vfsub_fsync(NULL, &h_path, datasync);
1facf9fc 9610+ }
9611+
9612+ return err;
9613+}
9614+
9615+static int au_do_fsync_dir(struct file *file, int datasync)
9616+{
9617+ int err;
9618+ aufs_bindex_t bend, bindex;
9619+ struct file *h_file;
9620+ struct super_block *sb;
9621+ struct inode *inode;
1facf9fc 9622+
9623+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9624+ if (unlikely(err))
9625+ goto out;
9626+
9627+ sb = file->f_dentry->d_sb;
c06a8ce3 9628+ inode = file_inode(file);
4a4d8108 9629+ bend = au_fbend_dir(file);
1facf9fc 9630+ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) {
4a4d8108 9631+ h_file = au_hf_dir(file, bindex);
1facf9fc 9632+ if (!h_file || au_test_ro(sb, bindex, inode))
9633+ continue;
9634+
53392da6 9635+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
1facf9fc 9636+ }
9637+
4f0767ce 9638+out:
1facf9fc 9639+ return err;
9640+}
9641+
9642+/*
9643+ * @file may be NULL
9644+ */
1e00d052
AM
9645+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end,
9646+ int datasync)
1facf9fc 9647+{
9648+ int err;
b752ccd1 9649+ struct dentry *dentry;
1facf9fc 9650+ struct super_block *sb;
1e00d052 9651+ struct mutex *mtx;
1facf9fc 9652+
9653+ err = 0;
1e00d052
AM
9654+ dentry = file->f_dentry;
9655+ mtx = &dentry->d_inode->i_mutex;
9656+ mutex_lock(mtx);
1facf9fc 9657+ sb = dentry->d_sb;
9658+ si_noflush_read_lock(sb);
9659+ if (file)
9660+ err = au_do_fsync_dir(file, datasync);
9661+ else {
9662+ di_write_lock_child(dentry);
9663+ err = au_do_fsync_dir_no_file(dentry, datasync);
9664+ }
9665+ au_cpup_attr_timesizes(dentry->d_inode);
9666+ di_write_unlock(dentry);
9667+ if (file)
9668+ fi_write_unlock(file);
9669+
9670+ si_read_unlock(sb);
1e00d052 9671+ mutex_unlock(mtx);
1facf9fc 9672+ return err;
9673+}
9674+
9675+/* ---------------------------------------------------------------------- */
9676+
392086de 9677+static int aufs_iterate(struct file *file, struct dir_context *ctx)
1facf9fc 9678+{
9679+ int err;
9680+ struct dentry *dentry;
9dbd164d 9681+ struct inode *inode, *h_inode;
1facf9fc 9682+ struct super_block *sb;
9683+
523b37e3 9684+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 9685+
1facf9fc 9686+ dentry = file->f_dentry;
9687+ inode = dentry->d_inode;
9688+ IMustLock(inode);
9689+
9690+ sb = dentry->d_sb;
9691+ si_read_lock(sb, AuLock_FLUSH);
9692+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1);
9693+ if (unlikely(err))
9694+ goto out;
027c5e7a
AM
9695+ err = au_alive_dir(dentry);
9696+ if (!err)
9697+ err = au_vdir_init(file);
1facf9fc 9698+ di_downgrade_lock(dentry, AuLock_IR);
9699+ if (unlikely(err))
9700+ goto out_unlock;
9701+
9dbd164d 9702+ h_inode = au_h_iptr(inode, au_ibstart(inode));
b752ccd1 9703+ if (!au_test_nfsd()) {
392086de 9704+ err = au_vdir_fill_de(file, ctx);
9dbd164d 9705+ fsstack_copy_attr_atime(inode, h_inode);
1facf9fc 9706+ } else {
9707+ /*
9708+ * nfsd filldir may call lookup_one_len(), vfs_getattr(),
9709+ * encode_fh() and others.
9710+ */
9dbd164d 9711+ atomic_inc(&h_inode->i_count);
1facf9fc 9712+ di_read_unlock(dentry, AuLock_IR);
9713+ si_read_unlock(sb);
392086de 9714+ err = au_vdir_fill_de(file, ctx);
1facf9fc 9715+ fsstack_copy_attr_atime(inode, h_inode);
9716+ fi_write_unlock(file);
9dbd164d 9717+ iput(h_inode);
1facf9fc 9718+
9719+ AuTraceErr(err);
9720+ return err;
9721+ }
9722+
4f0767ce 9723+out_unlock:
1facf9fc 9724+ di_read_unlock(dentry, AuLock_IR);
9725+ fi_write_unlock(file);
4f0767ce 9726+out:
1facf9fc 9727+ si_read_unlock(sb);
9728+ return err;
9729+}
9730+
9731+/* ---------------------------------------------------------------------- */
9732+
9733+#define AuTestEmpty_WHONLY 1
dece6358
AM
9734+#define AuTestEmpty_CALLED (1 << 1)
9735+#define AuTestEmpty_SHWH (1 << 2)
1facf9fc 9736+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
7f207e10
AM
9737+#define au_fset_testempty(flags, name) \
9738+ do { (flags) |= AuTestEmpty_##name; } while (0)
9739+#define au_fclr_testempty(flags, name) \
9740+ do { (flags) &= ~AuTestEmpty_##name; } while (0)
1facf9fc 9741+
dece6358
AM
9742+#ifndef CONFIG_AUFS_SHWH
9743+#undef AuTestEmpty_SHWH
9744+#define AuTestEmpty_SHWH 0
9745+#endif
9746+
1facf9fc 9747+struct test_empty_arg {
392086de 9748+ struct dir_context ctx;
1308ab2a 9749+ struct au_nhash *whlist;
1facf9fc 9750+ unsigned int flags;
9751+ int err;
9752+ aufs_bindex_t bindex;
9753+};
9754+
392086de
AM
9755+static int test_empty_cb(struct dir_context *ctx, const char *__name,
9756+ int namelen, loff_t offset __maybe_unused, u64 ino,
dece6358 9757+ unsigned int d_type)
1facf9fc 9758+{
392086de
AM
9759+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg,
9760+ ctx);
1facf9fc 9761+ char *name = (void *)__name;
9762+
9763+ arg->err = 0;
9764+ au_fset_testempty(arg->flags, CALLED);
9765+ /* smp_mb(); */
9766+ if (name[0] == '.'
9767+ && (namelen == 1 || (name[1] == '.' && namelen == 2)))
9768+ goto out; /* success */
9769+
9770+ if (namelen <= AUFS_WH_PFX_LEN
9771+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
9772+ if (au_ftest_testempty(arg->flags, WHONLY)
1308ab2a 9773+ && !au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9774+ arg->err = -ENOTEMPTY;
9775+ goto out;
9776+ }
9777+
9778+ name += AUFS_WH_PFX_LEN;
9779+ namelen -= AUFS_WH_PFX_LEN;
1308ab2a 9780+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
1facf9fc 9781+ arg->err = au_nhash_append_wh
1308ab2a 9782+ (arg->whlist, name, namelen, ino, d_type, arg->bindex,
dece6358 9783+ au_ftest_testempty(arg->flags, SHWH));
1facf9fc 9784+
4f0767ce 9785+out:
1facf9fc 9786+ /* smp_mb(); */
9787+ AuTraceErr(arg->err);
9788+ return arg->err;
9789+}
9790+
9791+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9792+{
9793+ int err;
9794+ struct file *h_file;
9795+
9796+ h_file = au_h_open(dentry, arg->bindex,
9797+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
392086de 9798+ /*file*/NULL, /*force_wr*/0);
1facf9fc 9799+ err = PTR_ERR(h_file);
9800+ if (IS_ERR(h_file))
9801+ goto out;
9802+
9803+ err = 0;
9804+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE)
c06a8ce3 9805+ && !file_inode(h_file)->i_nlink)
1facf9fc 9806+ goto out_put;
9807+
9808+ do {
9809+ arg->err = 0;
9810+ au_fclr_testempty(arg->flags, CALLED);
9811+ /* smp_mb(); */
392086de 9812+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1facf9fc 9813+ if (err >= 0)
9814+ err = arg->err;
9815+ } while (!err && au_ftest_testempty(arg->flags, CALLED));
9816+
4f0767ce 9817+out_put:
1facf9fc 9818+ fput(h_file);
9819+ au_sbr_put(dentry->d_sb, arg->bindex);
4f0767ce 9820+out:
1facf9fc 9821+ return err;
9822+}
9823+
9824+struct do_test_empty_args {
9825+ int *errp;
9826+ struct dentry *dentry;
9827+ struct test_empty_arg *arg;
9828+};
9829+
9830+static void call_do_test_empty(void *args)
9831+{
9832+ struct do_test_empty_args *a = args;
9833+ *a->errp = do_test_empty(a->dentry, a->arg);
9834+}
9835+
9836+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
9837+{
9838+ int err, wkq_err;
9839+ struct dentry *h_dentry;
9840+ struct inode *h_inode;
9841+
9842+ h_dentry = au_h_dptr(dentry, arg->bindex);
9843+ h_inode = h_dentry->d_inode;
53392da6 9844+ /* todo: i_mode changes anytime? */
1facf9fc 9845+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
9846+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ);
9847+ mutex_unlock(&h_inode->i_mutex);
9848+ if (!err)
9849+ err = do_test_empty(dentry, arg);
9850+ else {
9851+ struct do_test_empty_args args = {
9852+ .errp = &err,
9853+ .dentry = dentry,
9854+ .arg = arg
9855+ };
9856+ unsigned int flags = arg->flags;
9857+
9858+ wkq_err = au_wkq_wait(call_do_test_empty, &args);
9859+ if (unlikely(wkq_err))
9860+ err = wkq_err;
9861+ arg->flags = flags;
9862+ }
9863+
9864+ return err;
9865+}
9866+
9867+int au_test_empty_lower(struct dentry *dentry)
9868+{
9869+ int err;
1308ab2a 9870+ unsigned int rdhash;
1facf9fc 9871+ aufs_bindex_t bindex, bstart, btail;
1308ab2a 9872+ struct au_nhash whlist;
392086de
AM
9873+ struct test_empty_arg arg = {
9874+ .ctx = {
9875+ .actor = au_diractor(test_empty_cb)
9876+ }
9877+ };
076b876e 9878+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg);
1facf9fc 9879+
dece6358
AM
9880+ SiMustAnyLock(dentry->d_sb);
9881+
1308ab2a 9882+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
9883+ if (!rdhash)
9884+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry));
9885+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
dece6358 9886+ if (unlikely(err))
1facf9fc 9887+ goto out;
9888+
1facf9fc 9889+ arg.flags = 0;
1308ab2a 9890+ arg.whlist = &whlist;
9891+ bstart = au_dbstart(dentry);
dece6358
AM
9892+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9893+ au_fset_testempty(arg.flags, SHWH);
076b876e
AM
9894+ test_empty = do_test_empty;
9895+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1))
9896+ test_empty = sio_test_empty;
1facf9fc 9897+ arg.bindex = bstart;
076b876e 9898+ err = test_empty(dentry, &arg);
1facf9fc 9899+ if (unlikely(err))
9900+ goto out_whlist;
9901+
9902+ au_fset_testempty(arg.flags, WHONLY);
9903+ btail = au_dbtaildir(dentry);
9904+ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
9905+ struct dentry *h_dentry;
9906+
9907+ h_dentry = au_h_dptr(dentry, bindex);
9908+ if (h_dentry && h_dentry->d_inode) {
9909+ arg.bindex = bindex;
076b876e 9910+ err = test_empty(dentry, &arg);
1facf9fc 9911+ }
9912+ }
9913+
4f0767ce 9914+out_whlist:
1308ab2a 9915+ au_nhash_wh_free(&whlist);
4f0767ce 9916+out:
1facf9fc 9917+ return err;
9918+}
9919+
9920+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
9921+{
9922+ int err;
392086de
AM
9923+ struct test_empty_arg arg = {
9924+ .ctx = {
9925+ .actor = au_diractor(test_empty_cb)
9926+ }
9927+ };
1facf9fc 9928+ aufs_bindex_t bindex, btail;
9929+
9930+ err = 0;
1308ab2a 9931+ arg.whlist = whlist;
1facf9fc 9932+ arg.flags = AuTestEmpty_WHONLY;
dece6358
AM
9933+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH))
9934+ au_fset_testempty(arg.flags, SHWH);
1facf9fc 9935+ btail = au_dbtaildir(dentry);
9936+ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
9937+ struct dentry *h_dentry;
9938+
9939+ h_dentry = au_h_dptr(dentry, bindex);
9940+ if (h_dentry && h_dentry->d_inode) {
9941+ arg.bindex = bindex;
9942+ err = sio_test_empty(dentry, &arg);
9943+ }
9944+ }
9945+
9946+ return err;
9947+}
9948+
9949+/* ---------------------------------------------------------------------- */
9950+
9951+const struct file_operations aufs_dir_fop = {
4a4d8108 9952+ .owner = THIS_MODULE,
027c5e7a 9953+ .llseek = default_llseek,
1facf9fc 9954+ .read = generic_read_dir,
392086de 9955+ .iterate = aufs_iterate,
1facf9fc 9956+ .unlocked_ioctl = aufs_ioctl_dir,
b752ccd1
AM
9957+#ifdef CONFIG_COMPAT
9958+ .compat_ioctl = aufs_compat_ioctl_dir,
9959+#endif
1facf9fc 9960+ .open = aufs_open_dir,
9961+ .release = aufs_release_dir,
4a4d8108 9962+ .flush = aufs_flush_dir,
1facf9fc 9963+ .fsync = aufs_fsync_dir
9964+};
7f207e10
AM
9965diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
9966--- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
9967+++ linux/fs/aufs/dir.h 2015-01-25 13:00:38.631047076 +0100
9968@@ -0,0 +1,130 @@
1facf9fc 9969+/*
523b37e3 9970+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 9971+ *
9972+ * This program, aufs is free software; you can redistribute it and/or modify
9973+ * it under the terms of the GNU General Public License as published by
9974+ * the Free Software Foundation; either version 2 of the License, or
9975+ * (at your option) any later version.
dece6358
AM
9976+ *
9977+ * This program is distributed in the hope that it will be useful,
9978+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9979+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9980+ * GNU General Public License for more details.
9981+ *
9982+ * You should have received a copy of the GNU General Public License
523b37e3 9983+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 9984+ */
9985+
9986+/*
9987+ * directory operations
9988+ */
9989+
9990+#ifndef __AUFS_DIR_H__
9991+#define __AUFS_DIR_H__
9992+
9993+#ifdef __KERNEL__
9994+
9995+#include <linux/fs.h>
1facf9fc 9996+
9997+/* ---------------------------------------------------------------------- */
9998+
9999+/* need to be faster and smaller */
10000+
10001+struct au_nhash {
dece6358
AM
10002+ unsigned int nh_num;
10003+ struct hlist_head *nh_head;
1facf9fc 10004+};
10005+
10006+struct au_vdir_destr {
10007+ unsigned char len;
10008+ unsigned char name[0];
10009+} __packed;
10010+
10011+struct au_vdir_dehstr {
10012+ struct hlist_node hash;
10013+ struct au_vdir_destr *str;
4a4d8108 10014+} ____cacheline_aligned_in_smp;
1facf9fc 10015+
10016+struct au_vdir_de {
10017+ ino_t de_ino;
10018+ unsigned char de_type;
10019+ /* caution: packed */
10020+ struct au_vdir_destr de_str;
10021+} __packed;
10022+
10023+struct au_vdir_wh {
10024+ struct hlist_node wh_hash;
dece6358
AM
10025+#ifdef CONFIG_AUFS_SHWH
10026+ ino_t wh_ino;
1facf9fc 10027+ aufs_bindex_t wh_bindex;
dece6358
AM
10028+ unsigned char wh_type;
10029+#else
10030+ aufs_bindex_t wh_bindex;
10031+#endif
10032+ /* caution: packed */
1facf9fc 10033+ struct au_vdir_destr wh_str;
10034+} __packed;
10035+
10036+union au_vdir_deblk_p {
10037+ unsigned char *deblk;
10038+ struct au_vdir_de *de;
10039+};
10040+
10041+struct au_vdir {
10042+ unsigned char **vd_deblk;
10043+ unsigned long vd_nblk;
1facf9fc 10044+ struct {
10045+ unsigned long ul;
10046+ union au_vdir_deblk_p p;
10047+ } vd_last;
10048+
10049+ unsigned long vd_version;
dece6358 10050+ unsigned int vd_deblk_sz;
1facf9fc 10051+ unsigned long vd_jiffy;
4a4d8108 10052+} ____cacheline_aligned_in_smp;
1facf9fc 10053+
10054+/* ---------------------------------------------------------------------- */
10055+
10056+/* dir.c */
10057+extern const struct file_operations aufs_dir_fop;
10058+void au_add_nlink(struct inode *dir, struct inode *h_dir);
10059+void au_sub_nlink(struct inode *dir, struct inode *h_dir);
1308ab2a 10060+loff_t au_dir_size(struct file *file, struct dentry *dentry);
1facf9fc 10061+int au_test_empty_lower(struct dentry *dentry);
10062+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist);
10063+
10064+/* vdir.c */
1308ab2a 10065+unsigned int au_rdhash_est(loff_t sz);
dece6358
AM
10066+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp);
10067+void au_nhash_wh_free(struct au_nhash *whlist);
1facf9fc 10068+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
10069+ int limit);
dece6358
AM
10070+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen);
10071+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
10072+ unsigned int d_type, aufs_bindex_t bindex,
10073+ unsigned char shwh);
1facf9fc 10074+void au_vdir_free(struct au_vdir *vdir);
10075+int au_vdir_init(struct file *file);
392086de 10076+int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
1facf9fc 10077+
10078+/* ioctl.c */
10079+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg);
10080+
1308ab2a 10081+#ifdef CONFIG_AUFS_RDU
10082+/* rdu.c */
10083+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
10084+#ifdef CONFIG_COMPAT
10085+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd,
10086+ unsigned long arg);
10087+#endif
1308ab2a 10088+#else
c1595e42
JR
10089+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file,
10090+ unsigned int cmd, unsigned long arg)
b752ccd1 10091+#ifdef CONFIG_COMPAT
c1595e42
JR
10092+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file,
10093+ unsigned int cmd, unsigned long arg)
b752ccd1 10094+#endif
1308ab2a 10095+#endif
10096+
1facf9fc 10097+#endif /* __KERNEL__ */
10098+#endif /* __AUFS_DIR_H__ */
7f207e10
AM
10099diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
10100--- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 10101+++ linux/fs/aufs/dynop.c 2015-01-25 13:00:38.631047076 +0100
523b37e3 10102@@ -0,0 +1,379 @@
1facf9fc 10103+/*
523b37e3 10104+ * Copyright (C) 2010-2014 Junjiro R. Okajima
1facf9fc 10105+ *
10106+ * This program, aufs is free software; you can redistribute it and/or modify
10107+ * it under the terms of the GNU General Public License as published by
10108+ * the Free Software Foundation; either version 2 of the License, or
10109+ * (at your option) any later version.
dece6358
AM
10110+ *
10111+ * This program is distributed in the hope that it will be useful,
10112+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10113+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10114+ * GNU General Public License for more details.
10115+ *
10116+ * You should have received a copy of the GNU General Public License
523b37e3 10117+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 10118+ */
10119+
10120+/*
4a4d8108 10121+ * dynamically customizable operations for regular files
1facf9fc 10122+ */
10123+
1facf9fc 10124+#include "aufs.h"
10125+
4a4d8108 10126+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop)
1facf9fc 10127+
4a4d8108
AM
10128+/*
10129+ * How large will these lists be?
10130+ * Usually just a few elements, 20-30 at most for each, I guess.
10131+ */
10132+static struct au_splhead dynop[AuDyLast];
10133+
10134+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
1facf9fc 10135+{
4a4d8108
AM
10136+ struct au_dykey *key, *tmp;
10137+ struct list_head *head;
1facf9fc 10138+
4a4d8108
AM
10139+ key = NULL;
10140+ head = &spl->head;
10141+ rcu_read_lock();
10142+ list_for_each_entry_rcu(tmp, head, dk_list)
10143+ if (tmp->dk_op.dy_hop == h_op) {
10144+ key = tmp;
10145+ kref_get(&key->dk_kref);
10146+ break;
10147+ }
10148+ rcu_read_unlock();
10149+
10150+ return key;
1facf9fc 10151+}
10152+
4a4d8108 10153+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
1facf9fc 10154+{
4a4d8108
AM
10155+ struct au_dykey **k, *found;
10156+ const void *h_op = key->dk_op.dy_hop;
10157+ int i;
1facf9fc 10158+
4a4d8108
AM
10159+ found = NULL;
10160+ k = br->br_dykey;
10161+ for (i = 0; i < AuBrDynOp; i++)
10162+ if (k[i]) {
10163+ if (k[i]->dk_op.dy_hop == h_op) {
10164+ found = k[i];
10165+ break;
10166+ }
10167+ } else
10168+ break;
10169+ if (!found) {
10170+ spin_lock(&br->br_dykey_lock);
10171+ for (; i < AuBrDynOp; i++)
10172+ if (k[i]) {
10173+ if (k[i]->dk_op.dy_hop == h_op) {
10174+ found = k[i];
10175+ break;
10176+ }
10177+ } else {
10178+ k[i] = key;
10179+ break;
10180+ }
10181+ spin_unlock(&br->br_dykey_lock);
10182+ BUG_ON(i == AuBrDynOp); /* expand the array */
10183+ }
10184+
10185+ return found;
1facf9fc 10186+}
10187+
4a4d8108
AM
10188+/* kref_get() if @key is already added */
10189+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
10190+{
10191+ struct au_dykey *tmp, *found;
10192+ struct list_head *head;
10193+ const void *h_op = key->dk_op.dy_hop;
1facf9fc 10194+
4a4d8108
AM
10195+ found = NULL;
10196+ head = &spl->head;
10197+ spin_lock(&spl->spin);
10198+ list_for_each_entry(tmp, head, dk_list)
10199+ if (tmp->dk_op.dy_hop == h_op) {
10200+ kref_get(&tmp->dk_kref);
10201+ found = tmp;
10202+ break;
10203+ }
10204+ if (!found)
10205+ list_add_rcu(&key->dk_list, head);
10206+ spin_unlock(&spl->spin);
1facf9fc 10207+
4a4d8108
AM
10208+ if (!found)
10209+ DyPrSym(key);
10210+ return found;
10211+}
10212+
10213+static void dy_free_rcu(struct rcu_head *rcu)
1facf9fc 10214+{
4a4d8108
AM
10215+ struct au_dykey *key;
10216+
10217+ key = container_of(rcu, struct au_dykey, dk_rcu);
10218+ DyPrSym(key);
10219+ kfree(key);
1facf9fc 10220+}
10221+
4a4d8108
AM
10222+static void dy_free(struct kref *kref)
10223+{
10224+ struct au_dykey *key;
10225+ struct au_splhead *spl;
1facf9fc 10226+
4a4d8108
AM
10227+ key = container_of(kref, struct au_dykey, dk_kref);
10228+ spl = dynop + key->dk_op.dy_type;
10229+ au_spl_del_rcu(&key->dk_list, spl);
10230+ call_rcu(&key->dk_rcu, dy_free_rcu);
10231+}
10232+
10233+void au_dy_put(struct au_dykey *key)
1facf9fc 10234+{
4a4d8108
AM
10235+ kref_put(&key->dk_kref, dy_free);
10236+}
1facf9fc 10237+
4a4d8108
AM
10238+/* ---------------------------------------------------------------------- */
10239+
10240+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *))
10241+
10242+#ifdef CONFIG_AUFS_DEBUG
10243+#define DyDbgDeclare(cnt) unsigned int cnt = 0
4f0767ce 10244+#define DyDbgInc(cnt) do { cnt++; } while (0)
4a4d8108
AM
10245+#else
10246+#define DyDbgDeclare(cnt) do {} while (0)
10247+#define DyDbgInc(cnt) do {} while (0)
10248+#endif
10249+
10250+#define DySet(func, dst, src, h_op, h_sb) do { \
10251+ DyDbgInc(cnt); \
10252+ if (h_op->func) { \
10253+ if (src.func) \
10254+ dst.func = src.func; \
10255+ else \
10256+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \
10257+ } \
10258+} while (0)
10259+
10260+#define DySetForce(func, dst, src) do { \
10261+ AuDebugOn(!src.func); \
10262+ DyDbgInc(cnt); \
10263+ dst.func = src.func; \
10264+} while (0)
10265+
10266+#define DySetAop(func) \
10267+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
10268+#define DySetAopForce(func) \
10269+ DySetForce(func, dyaop->da_op, aufs_aop)
10270+
10271+static void dy_aop(struct au_dykey *key, const void *h_op,
10272+ struct super_block *h_sb __maybe_unused)
10273+{
10274+ struct au_dyaop *dyaop = (void *)key;
10275+ const struct address_space_operations *h_aop = h_op;
10276+ DyDbgDeclare(cnt);
10277+
10278+ AuDbg("%s\n", au_sbtype(h_sb));
10279+
10280+ DySetAop(writepage);
10281+ DySetAopForce(readpage); /* force */
4a4d8108
AM
10282+ DySetAop(writepages);
10283+ DySetAop(set_page_dirty);
10284+ DySetAop(readpages);
10285+ DySetAop(write_begin);
10286+ DySetAop(write_end);
10287+ DySetAop(bmap);
10288+ DySetAop(invalidatepage);
10289+ DySetAop(releasepage);
027c5e7a 10290+ DySetAop(freepage);
4a4d8108
AM
10291+ /* these two will be changed according to an aufs mount option */
10292+ DySetAop(direct_IO);
10293+ DySetAop(get_xip_mem);
10294+ DySetAop(migratepage);
10295+ DySetAop(launder_page);
10296+ DySetAop(is_partially_uptodate);
392086de 10297+ DySetAop(is_dirty_writeback);
4a4d8108 10298+ DySetAop(error_remove_page);
b4510431
AM
10299+ DySetAop(swap_activate);
10300+ DySetAop(swap_deactivate);
4a4d8108
AM
10301+
10302+ DyDbgSize(cnt, *h_aop);
10303+ dyaop->da_get_xip_mem = h_aop->get_xip_mem;
10304+}
10305+
4a4d8108
AM
10306+/* ---------------------------------------------------------------------- */
10307+
10308+static void dy_bug(struct kref *kref)
10309+{
10310+ BUG();
10311+}
10312+
10313+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
10314+{
10315+ struct au_dykey *key, *old;
10316+ struct au_splhead *spl;
b752ccd1 10317+ struct op {
4a4d8108 10318+ unsigned int sz;
b752ccd1
AM
10319+ void (*set)(struct au_dykey *key, const void *h_op,
10320+ struct super_block *h_sb __maybe_unused);
10321+ };
10322+ static const struct op a[] = {
4a4d8108
AM
10323+ [AuDy_AOP] = {
10324+ .sz = sizeof(struct au_dyaop),
b752ccd1 10325+ .set = dy_aop
4a4d8108 10326+ }
b752ccd1
AM
10327+ };
10328+ const struct op *p;
4a4d8108
AM
10329+
10330+ spl = dynop + op->dy_type;
10331+ key = dy_gfind_get(spl, op->dy_hop);
10332+ if (key)
10333+ goto out_add; /* success */
10334+
10335+ p = a + op->dy_type;
10336+ key = kzalloc(p->sz, GFP_NOFS);
10337+ if (unlikely(!key)) {
10338+ key = ERR_PTR(-ENOMEM);
10339+ goto out;
10340+ }
10341+
10342+ key->dk_op.dy_hop = op->dy_hop;
10343+ kref_init(&key->dk_kref);
86dc4139 10344+ p->set(key, op->dy_hop, au_br_sb(br));
4a4d8108
AM
10345+ old = dy_gadd(spl, key);
10346+ if (old) {
10347+ kfree(key);
10348+ key = old;
10349+ }
10350+
10351+out_add:
10352+ old = dy_bradd(br, key);
10353+ if (old)
10354+ /* its ref-count should never be zero here */
10355+ kref_put(&key->dk_kref, dy_bug);
10356+out:
10357+ return key;
10358+}
10359+
10360+/* ---------------------------------------------------------------------- */
10361+/*
10362+ * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
c1595e42 10363+ * This behaviour is necessary to return an error from open(O_DIRECT) instead
4a4d8108
AM
10364+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
10365+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
10366+ * See the aufs manual in detail.
10367+ *
10368+ * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
10369+ * performance of fadvise() and madvise() may be affected.
10370+ */
10371+static void dy_adx(struct au_dyaop *dyaop, int do_dx)
10372+{
10373+ if (!do_dx) {
10374+ dyaop->da_op.direct_IO = NULL;
10375+ dyaop->da_op.get_xip_mem = NULL;
10376+ } else {
10377+ dyaop->da_op.direct_IO = aufs_aop.direct_IO;
10378+ dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
10379+ if (!dyaop->da_get_xip_mem)
10380+ dyaop->da_op.get_xip_mem = NULL;
10381+ }
10382+}
10383+
10384+static struct au_dyaop *dy_aget(struct au_branch *br,
10385+ const struct address_space_operations *h_aop,
10386+ int do_dx)
10387+{
10388+ struct au_dyaop *dyaop;
10389+ struct au_dynop op;
10390+
10391+ op.dy_type = AuDy_AOP;
10392+ op.dy_haop = h_aop;
10393+ dyaop = (void *)dy_get(&op, br);
10394+ if (IS_ERR(dyaop))
10395+ goto out;
10396+ dy_adx(dyaop, do_dx);
10397+
10398+out:
10399+ return dyaop;
10400+}
10401+
10402+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10403+ struct inode *h_inode)
10404+{
10405+ int err, do_dx;
10406+ struct super_block *sb;
10407+ struct au_branch *br;
10408+ struct au_dyaop *dyaop;
10409+
10410+ AuDebugOn(!S_ISREG(h_inode->i_mode));
10411+ IiMustWriteLock(inode);
10412+
10413+ sb = inode->i_sb;
10414+ br = au_sbr(sb, bindex);
10415+ do_dx = !!au_opt_test(au_mntflags(sb), DIO);
10416+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
10417+ err = PTR_ERR(dyaop);
10418+ if (IS_ERR(dyaop))
10419+ /* unnecessary to call dy_fput() */
10420+ goto out;
10421+
10422+ err = 0;
10423+ inode->i_mapping->a_ops = &dyaop->da_op;
10424+
10425+out:
10426+ return err;
10427+}
10428+
b752ccd1
AM
10429+/*
10430+ * Is it safe to replace a_ops during the inode/file is in operation?
10431+ * Yes, I hope so.
10432+ */
10433+int au_dy_irefresh(struct inode *inode)
10434+{
10435+ int err;
10436+ aufs_bindex_t bstart;
10437+ struct inode *h_inode;
10438+
10439+ err = 0;
10440+ if (S_ISREG(inode->i_mode)) {
10441+ bstart = au_ibstart(inode);
10442+ h_inode = au_h_iptr(inode, bstart);
10443+ err = au_dy_iaop(inode, bstart, h_inode);
10444+ }
10445+ return err;
10446+}
10447+
4a4d8108
AM
10448+void au_dy_arefresh(int do_dx)
10449+{
10450+ struct au_splhead *spl;
10451+ struct list_head *head;
10452+ struct au_dykey *key;
10453+
10454+ spl = dynop + AuDy_AOP;
10455+ head = &spl->head;
10456+ spin_lock(&spl->spin);
10457+ list_for_each_entry(key, head, dk_list)
10458+ dy_adx((void *)key, do_dx);
10459+ spin_unlock(&spl->spin);
10460+}
10461+
4a4d8108
AM
10462+/* ---------------------------------------------------------------------- */
10463+
10464+void __init au_dy_init(void)
10465+{
10466+ int i;
10467+
10468+ /* make sure that 'struct au_dykey *' can be any type */
10469+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
4a4d8108
AM
10470+
10471+ for (i = 0; i < AuDyLast; i++)
10472+ au_spl_init(dynop + i);
10473+}
10474+
10475+void au_dy_fin(void)
10476+{
10477+ int i;
10478+
10479+ for (i = 0; i < AuDyLast; i++)
10480+ WARN_ON(!list_empty(&dynop[i].head));
10481+}
7f207e10
AM
10482diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
10483--- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 10484+++ linux/fs/aufs/dynop.h 2015-01-25 13:00:38.631047076 +0100
523b37e3 10485@@ -0,0 +1,75 @@
4a4d8108 10486+/*
523b37e3 10487+ * Copyright (C) 2010-2014 Junjiro R. Okajima
4a4d8108
AM
10488+ *
10489+ * This program, aufs is free software; you can redistribute it and/or modify
10490+ * it under the terms of the GNU General Public License as published by
10491+ * the Free Software Foundation; either version 2 of the License, or
10492+ * (at your option) any later version.
10493+ *
10494+ * This program is distributed in the hope that it will be useful,
10495+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10496+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10497+ * GNU General Public License for more details.
10498+ *
10499+ * You should have received a copy of the GNU General Public License
523b37e3 10500+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10501+ */
10502+
10503+/*
10504+ * dynamically customizable operations (for regular files only)
10505+ */
10506+
10507+#ifndef __AUFS_DYNOP_H__
10508+#define __AUFS_DYNOP_H__
10509+
10510+#ifdef __KERNEL__
10511+
4a4d8108
AM
10512+#include "inode.h"
10513+
2cbb1c4b 10514+enum {AuDy_AOP, AuDyLast};
4a4d8108
AM
10515+
10516+struct au_dynop {
10517+ int dy_type;
10518+ union {
10519+ const void *dy_hop;
10520+ const struct address_space_operations *dy_haop;
4a4d8108
AM
10521+ };
10522+};
10523+
10524+struct au_dykey {
10525+ union {
10526+ struct list_head dk_list;
10527+ struct rcu_head dk_rcu;
10528+ };
10529+ struct au_dynop dk_op;
10530+
10531+ /*
10532+ * during I am in the branch local array, kref is gotten. when the
10533+ * branch is removed, kref is put.
10534+ */
10535+ struct kref dk_kref;
10536+};
10537+
10538+/* stop unioning since their sizes are very different from each other */
10539+struct au_dyaop {
10540+ struct au_dykey da_key;
10541+ struct address_space_operations da_op; /* not const */
10542+ int (*da_get_xip_mem)(struct address_space *, pgoff_t, int,
10543+ void **, unsigned long *);
10544+};
10545+
4a4d8108
AM
10546+/* ---------------------------------------------------------------------- */
10547+
10548+/* dynop.c */
10549+struct au_branch;
10550+void au_dy_put(struct au_dykey *key);
10551+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
10552+ struct inode *h_inode);
b752ccd1 10553+int au_dy_irefresh(struct inode *inode);
4a4d8108 10554+void au_dy_arefresh(int do_dio);
4a4d8108
AM
10555+
10556+void __init au_dy_init(void);
10557+void au_dy_fin(void);
10558+
4a4d8108
AM
10559+#endif /* __KERNEL__ */
10560+#endif /* __AUFS_DYNOP_H__ */
7f207e10
AM
10561diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
10562--- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 10563+++ linux/fs/aufs/export.c 2015-01-25 13:00:38.631047076 +0100
523b37e3 10564@@ -0,0 +1,831 @@
4a4d8108 10565+/*
523b37e3 10566+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
10567+ *
10568+ * This program, aufs is free software; you can redistribute it and/or modify
10569+ * it under the terms of the GNU General Public License as published by
10570+ * the Free Software Foundation; either version 2 of the License, or
10571+ * (at your option) any later version.
10572+ *
10573+ * This program is distributed in the hope that it will be useful,
10574+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10575+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10576+ * GNU General Public License for more details.
10577+ *
10578+ * You should have received a copy of the GNU General Public License
523b37e3 10579+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
10580+ */
10581+
10582+/*
10583+ * export via nfs
10584+ */
10585+
10586+#include <linux/exportfs.h>
7eafdf33 10587+#include <linux/fs_struct.h>
4a4d8108
AM
10588+#include <linux/namei.h>
10589+#include <linux/nsproxy.h>
10590+#include <linux/random.h>
10591+#include <linux/writeback.h>
7eafdf33 10592+#include "../fs/mount.h"
4a4d8108
AM
10593+#include "aufs.h"
10594+
10595+union conv {
10596+#ifdef CONFIG_AUFS_INO_T_64
10597+ __u32 a[2];
10598+#else
10599+ __u32 a[1];
10600+#endif
10601+ ino_t ino;
10602+};
10603+
10604+static ino_t decode_ino(__u32 *a)
10605+{
10606+ union conv u;
10607+
10608+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
10609+ u.a[0] = a[0];
10610+#ifdef CONFIG_AUFS_INO_T_64
10611+ u.a[1] = a[1];
10612+#endif
10613+ return u.ino;
10614+}
10615+
10616+static void encode_ino(__u32 *a, ino_t ino)
10617+{
10618+ union conv u;
10619+
10620+ u.ino = ino;
10621+ a[0] = u.a[0];
10622+#ifdef CONFIG_AUFS_INO_T_64
10623+ a[1] = u.a[1];
10624+#endif
10625+}
10626+
10627+/* NFS file handle */
10628+enum {
10629+ Fh_br_id,
10630+ Fh_sigen,
10631+#ifdef CONFIG_AUFS_INO_T_64
10632+ /* support 64bit inode number */
10633+ Fh_ino1,
10634+ Fh_ino2,
10635+ Fh_dir_ino1,
10636+ Fh_dir_ino2,
10637+#else
10638+ Fh_ino1,
10639+ Fh_dir_ino1,
10640+#endif
10641+ Fh_igen,
10642+ Fh_h_type,
10643+ Fh_tail,
10644+
10645+ Fh_ino = Fh_ino1,
10646+ Fh_dir_ino = Fh_dir_ino1
10647+};
10648+
10649+static int au_test_anon(struct dentry *dentry)
10650+{
027c5e7a 10651+ /* note: read d_flags without d_lock */
4a4d8108
AM
10652+ return !!(dentry->d_flags & DCACHE_DISCONNECTED);
10653+}
10654+
a2a7ad62
AM
10655+int au_test_nfsd(void)
10656+{
10657+ int ret;
10658+ struct task_struct *tsk = current;
10659+ char comm[sizeof(tsk->comm)];
10660+
10661+ ret = 0;
10662+ if (tsk->flags & PF_KTHREAD) {
10663+ get_task_comm(comm, tsk);
10664+ ret = !strcmp(comm, "nfsd");
10665+ }
10666+
10667+ return ret;
10668+}
10669+
4a4d8108
AM
10670+/* ---------------------------------------------------------------------- */
10671+/* inode generation external table */
10672+
b752ccd1 10673+void au_xigen_inc(struct inode *inode)
4a4d8108 10674+{
4a4d8108
AM
10675+ loff_t pos;
10676+ ssize_t sz;
10677+ __u32 igen;
10678+ struct super_block *sb;
10679+ struct au_sbinfo *sbinfo;
10680+
4a4d8108 10681+ sb = inode->i_sb;
b752ccd1 10682+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
1facf9fc 10683+
b752ccd1 10684+ sbinfo = au_sbi(sb);
1facf9fc 10685+ pos = inode->i_ino;
10686+ pos *= sizeof(igen);
10687+ igen = inode->i_generation + 1;
1facf9fc 10688+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
10689+ sizeof(igen), &pos);
10690+ if (sz == sizeof(igen))
b752ccd1 10691+ return; /* success */
1facf9fc 10692+
b752ccd1 10693+ if (unlikely(sz >= 0))
1facf9fc 10694+ AuIOErr("xigen error (%zd)\n", sz);
1facf9fc 10695+}
10696+
10697+int au_xigen_new(struct inode *inode)
10698+{
10699+ int err;
10700+ loff_t pos;
10701+ ssize_t sz;
10702+ struct super_block *sb;
10703+ struct au_sbinfo *sbinfo;
10704+ struct file *file;
10705+
10706+ err = 0;
10707+ /* todo: dirty, at mount time */
10708+ if (inode->i_ino == AUFS_ROOT_INO)
10709+ goto out;
10710+ sb = inode->i_sb;
dece6358 10711+ SiMustAnyLock(sb);
1facf9fc 10712+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
10713+ goto out;
10714+
10715+ err = -EFBIG;
10716+ pos = inode->i_ino;
10717+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
10718+ AuIOErr1("too large i%lld\n", pos);
10719+ goto out;
10720+ }
10721+ pos *= sizeof(inode->i_generation);
10722+
10723+ err = 0;
10724+ sbinfo = au_sbi(sb);
10725+ file = sbinfo->si_xigen;
10726+ BUG_ON(!file);
10727+
c06a8ce3 10728+ if (vfsub_f_size_read(file)
1facf9fc 10729+ < pos + sizeof(inode->i_generation)) {
10730+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
10731+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
10732+ sizeof(inode->i_generation), &pos);
10733+ } else
10734+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
10735+ sizeof(inode->i_generation), &pos);
10736+ if (sz == sizeof(inode->i_generation))
10737+ goto out; /* success */
10738+
10739+ err = sz;
10740+ if (unlikely(sz >= 0)) {
10741+ err = -EIO;
10742+ AuIOErr("xigen error (%zd)\n", sz);
10743+ }
10744+
4f0767ce 10745+out:
1facf9fc 10746+ return err;
10747+}
10748+
10749+int au_xigen_set(struct super_block *sb, struct file *base)
10750+{
10751+ int err;
10752+ struct au_sbinfo *sbinfo;
10753+ struct file *file;
10754+
dece6358
AM
10755+ SiMustWriteLock(sb);
10756+
1facf9fc 10757+ sbinfo = au_sbi(sb);
10758+ file = au_xino_create2(base, sbinfo->si_xigen);
10759+ err = PTR_ERR(file);
10760+ if (IS_ERR(file))
10761+ goto out;
10762+ err = 0;
10763+ if (sbinfo->si_xigen)
10764+ fput(sbinfo->si_xigen);
10765+ sbinfo->si_xigen = file;
10766+
4f0767ce 10767+out:
1facf9fc 10768+ return err;
10769+}
10770+
10771+void au_xigen_clr(struct super_block *sb)
10772+{
10773+ struct au_sbinfo *sbinfo;
10774+
dece6358
AM
10775+ SiMustWriteLock(sb);
10776+
1facf9fc 10777+ sbinfo = au_sbi(sb);
10778+ if (sbinfo->si_xigen) {
10779+ fput(sbinfo->si_xigen);
10780+ sbinfo->si_xigen = NULL;
10781+ }
10782+}
10783+
10784+/* ---------------------------------------------------------------------- */
10785+
10786+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
10787+ ino_t dir_ino)
10788+{
10789+ struct dentry *dentry, *d;
10790+ struct inode *inode;
10791+ unsigned int sigen;
10792+
10793+ dentry = NULL;
10794+ inode = ilookup(sb, ino);
10795+ if (!inode)
10796+ goto out;
10797+
10798+ dentry = ERR_PTR(-ESTALE);
10799+ sigen = au_sigen(sb);
10800+ if (unlikely(is_bad_inode(inode)
10801+ || IS_DEADDIR(inode)
537831f9 10802+ || sigen != au_iigen(inode, NULL)))
1facf9fc 10803+ goto out_iput;
10804+
10805+ dentry = NULL;
10806+ if (!dir_ino || S_ISDIR(inode->i_mode))
10807+ dentry = d_find_alias(inode);
10808+ else {
027c5e7a 10809+ spin_lock(&inode->i_lock);
c1595e42 10810+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 10811+ spin_lock(&d->d_lock);
1facf9fc 10812+ if (!au_test_anon(d)
10813+ && d->d_parent->d_inode->i_ino == dir_ino) {
027c5e7a
AM
10814+ dentry = dget_dlock(d);
10815+ spin_unlock(&d->d_lock);
1facf9fc 10816+ break;
10817+ }
027c5e7a
AM
10818+ spin_unlock(&d->d_lock);
10819+ }
10820+ spin_unlock(&inode->i_lock);
1facf9fc 10821+ }
027c5e7a 10822+ if (unlikely(dentry && au_digen_test(dentry, sigen))) {
2cbb1c4b 10823+ /* need to refresh */
1facf9fc 10824+ dput(dentry);
2cbb1c4b 10825+ dentry = NULL;
1facf9fc 10826+ }
10827+
4f0767ce 10828+out_iput:
1facf9fc 10829+ iput(inode);
4f0767ce 10830+out:
2cbb1c4b 10831+ AuTraceErrPtr(dentry);
1facf9fc 10832+ return dentry;
10833+}
10834+
10835+/* ---------------------------------------------------------------------- */
10836+
10837+/* todo: dirty? */
10838+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */
4a4d8108
AM
10839+
10840+struct au_compare_mnt_args {
10841+ /* input */
10842+ struct super_block *sb;
10843+
10844+ /* output */
10845+ struct vfsmount *mnt;
10846+};
10847+
10848+static int au_compare_mnt(struct vfsmount *mnt, void *arg)
10849+{
10850+ struct au_compare_mnt_args *a = arg;
10851+
10852+ if (mnt->mnt_sb != a->sb)
10853+ return 0;
10854+ a->mnt = mntget(mnt);
10855+ return 1;
10856+}
10857+
1facf9fc 10858+static struct vfsmount *au_mnt_get(struct super_block *sb)
10859+{
4a4d8108 10860+ int err;
7eafdf33 10861+ struct path root;
4a4d8108
AM
10862+ struct au_compare_mnt_args args = {
10863+ .sb = sb
10864+ };
1facf9fc 10865+
7eafdf33 10866+ get_fs_root(current->fs, &root);
523b37e3 10867+ rcu_read_lock();
7eafdf33 10868+ err = iterate_mounts(au_compare_mnt, &args, root.mnt);
523b37e3 10869+ rcu_read_unlock();
7eafdf33 10870+ path_put(&root);
4a4d8108
AM
10871+ AuDebugOn(!err);
10872+ AuDebugOn(!args.mnt);
10873+ return args.mnt;
1facf9fc 10874+}
10875+
10876+struct au_nfsd_si_lock {
4a4d8108 10877+ unsigned int sigen;
027c5e7a 10878+ aufs_bindex_t bindex, br_id;
1facf9fc 10879+ unsigned char force_lock;
10880+};
10881+
027c5e7a
AM
10882+static int si_nfsd_read_lock(struct super_block *sb,
10883+ struct au_nfsd_si_lock *nsi_lock)
1facf9fc 10884+{
027c5e7a 10885+ int err;
1facf9fc 10886+ aufs_bindex_t bindex;
10887+
10888+ si_read_lock(sb, AuLock_FLUSH);
10889+
10890+ /* branch id may be wrapped around */
027c5e7a 10891+ err = 0;
1facf9fc 10892+ bindex = au_br_index(sb, nsi_lock->br_id);
10893+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
10894+ goto out; /* success */
10895+
027c5e7a
AM
10896+ err = -ESTALE;
10897+ bindex = -1;
1facf9fc 10898+ if (!nsi_lock->force_lock)
10899+ si_read_unlock(sb);
1facf9fc 10900+
4f0767ce 10901+out:
027c5e7a
AM
10902+ nsi_lock->bindex = bindex;
10903+ return err;
1facf9fc 10904+}
10905+
10906+struct find_name_by_ino {
392086de 10907+ struct dir_context ctx;
1facf9fc 10908+ int called, found;
10909+ ino_t ino;
10910+ char *name;
10911+ int namelen;
10912+};
10913+
10914+static int
392086de
AM
10915+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen,
10916+ loff_t offset, u64 ino, unsigned int d_type)
1facf9fc 10917+{
392086de
AM
10918+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino,
10919+ ctx);
1facf9fc 10920+
10921+ a->called++;
10922+ if (a->ino != ino)
10923+ return 0;
10924+
10925+ memcpy(a->name, name, namelen);
10926+ a->namelen = namelen;
10927+ a->found = 1;
10928+ return 1;
10929+}
10930+
10931+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
10932+ struct au_nfsd_si_lock *nsi_lock)
10933+{
10934+ struct dentry *dentry, *parent;
10935+ struct file *file;
10936+ struct inode *dir;
392086de
AM
10937+ struct find_name_by_ino arg = {
10938+ .ctx = {
10939+ .actor = au_diractor(find_name_by_ino)
10940+ }
10941+ };
1facf9fc 10942+ int err;
10943+
10944+ parent = path->dentry;
10945+ if (nsi_lock)
10946+ si_read_unlock(parent->d_sb);
4a4d8108 10947+ file = vfsub_dentry_open(path, au_dir_roflags);
1facf9fc 10948+ dentry = (void *)file;
10949+ if (IS_ERR(file))
10950+ goto out;
10951+
10952+ dentry = ERR_PTR(-ENOMEM);
537831f9 10953+ arg.name = (void *)__get_free_page(GFP_NOFS);
1facf9fc 10954+ if (unlikely(!arg.name))
10955+ goto out_file;
10956+ arg.ino = ino;
10957+ arg.found = 0;
10958+ do {
10959+ arg.called = 0;
10960+ /* smp_mb(); */
392086de 10961+ err = vfsub_iterate_dir(file, &arg.ctx);
1facf9fc 10962+ } while (!err && !arg.found && arg.called);
10963+ dentry = ERR_PTR(err);
10964+ if (unlikely(err))
10965+ goto out_name;
1716fcea
AM
10966+ /* instead of ENOENT */
10967+ dentry = ERR_PTR(-ESTALE);
1facf9fc 10968+ if (!arg.found)
10969+ goto out_name;
10970+
b4510431 10971+ /* do not call vfsub_lkup_one() */
1facf9fc 10972+ dir = parent->d_inode;
10973+ mutex_lock(&dir->i_mutex);
10974+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
10975+ mutex_unlock(&dir->i_mutex);
10976+ AuTraceErrPtr(dentry);
10977+ if (IS_ERR(dentry))
10978+ goto out_name;
10979+ AuDebugOn(au_test_anon(dentry));
10980+ if (unlikely(!dentry->d_inode)) {
10981+ dput(dentry);
10982+ dentry = ERR_PTR(-ENOENT);
10983+ }
10984+
4f0767ce 10985+out_name:
537831f9 10986+ free_page((unsigned long)arg.name);
4f0767ce 10987+out_file:
1facf9fc 10988+ fput(file);
4f0767ce 10989+out:
1facf9fc 10990+ if (unlikely(nsi_lock
10991+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
10992+ if (!IS_ERR(dentry)) {
10993+ dput(dentry);
10994+ dentry = ERR_PTR(-ESTALE);
10995+ }
10996+ AuTraceErrPtr(dentry);
10997+ return dentry;
10998+}
10999+
11000+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
11001+ ino_t dir_ino,
11002+ struct au_nfsd_si_lock *nsi_lock)
11003+{
11004+ struct dentry *dentry;
11005+ struct path path;
11006+
11007+ if (dir_ino != AUFS_ROOT_INO) {
11008+ path.dentry = decode_by_ino(sb, dir_ino, 0);
11009+ dentry = path.dentry;
11010+ if (!path.dentry || IS_ERR(path.dentry))
11011+ goto out;
11012+ AuDebugOn(au_test_anon(path.dentry));
11013+ } else
11014+ path.dentry = dget(sb->s_root);
11015+
11016+ path.mnt = au_mnt_get(sb);
11017+ dentry = au_lkup_by_ino(&path, ino, nsi_lock);
11018+ path_put(&path);
11019+
4f0767ce 11020+out:
1facf9fc 11021+ AuTraceErrPtr(dentry);
11022+ return dentry;
11023+}
11024+
11025+/* ---------------------------------------------------------------------- */
11026+
11027+static int h_acceptable(void *expv, struct dentry *dentry)
11028+{
11029+ return 1;
11030+}
11031+
11032+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
11033+ char *buf, int len, struct super_block *sb)
11034+{
11035+ char *p;
11036+ int n;
11037+ struct path path;
11038+
11039+ p = d_path(h_rootpath, buf, len);
11040+ if (IS_ERR(p))
11041+ goto out;
11042+ n = strlen(p);
11043+
11044+ path.mnt = h_rootpath->mnt;
11045+ path.dentry = h_parent;
11046+ p = d_path(&path, buf, len);
11047+ if (IS_ERR(p))
11048+ goto out;
11049+ if (n != 1)
11050+ p += n;
11051+
11052+ path.mnt = au_mnt_get(sb);
11053+ path.dentry = sb->s_root;
11054+ p = d_path(&path, buf, len - strlen(p));
11055+ mntput(path.mnt);
11056+ if (IS_ERR(p))
11057+ goto out;
11058+ if (n != 1)
11059+ p[strlen(p)] = '/';
11060+
4f0767ce 11061+out:
1facf9fc 11062+ AuTraceErrPtr(p);
11063+ return p;
11064+}
11065+
11066+static
027c5e7a
AM
11067+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
11068+ int fh_len, struct au_nfsd_si_lock *nsi_lock)
1facf9fc 11069+{
11070+ struct dentry *dentry, *h_parent, *root;
11071+ struct super_block *h_sb;
11072+ char *pathname, *p;
11073+ struct vfsmount *h_mnt;
11074+ struct au_branch *br;
11075+ int err;
11076+ struct path path;
11077+
027c5e7a 11078+ br = au_sbr(sb, nsi_lock->bindex);
86dc4139 11079+ h_mnt = au_br_mnt(br);
1facf9fc 11080+ h_sb = h_mnt->mnt_sb;
11081+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */
11082+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
11083+ fh_len - Fh_tail, fh[Fh_h_type],
11084+ h_acceptable, /*context*/NULL);
11085+ dentry = h_parent;
11086+ if (unlikely(!h_parent || IS_ERR(h_parent))) {
11087+ AuWarn1("%s decode_fh failed, %ld\n",
11088+ au_sbtype(h_sb), PTR_ERR(h_parent));
11089+ goto out;
11090+ }
11091+ dentry = NULL;
11092+ if (unlikely(au_test_anon(h_parent))) {
11093+ AuWarn1("%s decode_fh returned a disconnected dentry\n",
11094+ au_sbtype(h_sb));
11095+ goto out_h_parent;
11096+ }
11097+
11098+ dentry = ERR_PTR(-ENOMEM);
11099+ pathname = (void *)__get_free_page(GFP_NOFS);
11100+ if (unlikely(!pathname))
11101+ goto out_h_parent;
11102+
11103+ root = sb->s_root;
11104+ path.mnt = h_mnt;
11105+ di_read_lock_parent(root, !AuLock_IR);
027c5e7a 11106+ path.dentry = au_h_dptr(root, nsi_lock->bindex);
1facf9fc 11107+ di_read_unlock(root, !AuLock_IR);
11108+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
11109+ dentry = (void *)p;
11110+ if (IS_ERR(p))
11111+ goto out_pathname;
11112+
11113+ si_read_unlock(sb);
11114+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
11115+ dentry = ERR_PTR(err);
11116+ if (unlikely(err))
11117+ goto out_relock;
11118+
11119+ dentry = ERR_PTR(-ENOENT);
11120+ AuDebugOn(au_test_anon(path.dentry));
11121+ if (unlikely(!path.dentry->d_inode))
11122+ goto out_path;
11123+
11124+ if (ino != path.dentry->d_inode->i_ino)
11125+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
11126+ else
11127+ dentry = dget(path.dentry);
11128+
4f0767ce 11129+out_path:
1facf9fc 11130+ path_put(&path);
4f0767ce 11131+out_relock:
1facf9fc 11132+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
11133+ if (!IS_ERR(dentry)) {
11134+ dput(dentry);
11135+ dentry = ERR_PTR(-ESTALE);
11136+ }
4f0767ce 11137+out_pathname:
1facf9fc 11138+ free_page((unsigned long)pathname);
4f0767ce 11139+out_h_parent:
1facf9fc 11140+ dput(h_parent);
4f0767ce 11141+out:
1facf9fc 11142+ AuTraceErrPtr(dentry);
11143+ return dentry;
11144+}
11145+
11146+/* ---------------------------------------------------------------------- */
11147+
11148+static struct dentry *
11149+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
11150+ int fh_type)
11151+{
11152+ struct dentry *dentry;
11153+ __u32 *fh = fid->raw;
027c5e7a 11154+ struct au_branch *br;
1facf9fc 11155+ ino_t ino, dir_ino;
1facf9fc 11156+ struct au_nfsd_si_lock nsi_lock = {
1facf9fc 11157+ .force_lock = 0
11158+ };
11159+
1facf9fc 11160+ dentry = ERR_PTR(-ESTALE);
4a4d8108
AM
11161+ /* it should never happen, but the file handle is unreliable */
11162+ if (unlikely(fh_len < Fh_tail))
11163+ goto out;
11164+ nsi_lock.sigen = fh[Fh_sigen];
11165+ nsi_lock.br_id = fh[Fh_br_id];
11166+
1facf9fc 11167+ /* branch id may be wrapped around */
027c5e7a
AM
11168+ br = NULL;
11169+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
1facf9fc 11170+ goto out;
11171+ nsi_lock.force_lock = 1;
11172+
11173+ /* is this inode still cached? */
11174+ ino = decode_ino(fh + Fh_ino);
4a4d8108
AM
11175+ /* it should never happen */
11176+ if (unlikely(ino == AUFS_ROOT_INO))
11177+ goto out;
11178+
1facf9fc 11179+ dir_ino = decode_ino(fh + Fh_dir_ino);
11180+ dentry = decode_by_ino(sb, ino, dir_ino);
11181+ if (IS_ERR(dentry))
11182+ goto out_unlock;
11183+ if (dentry)
11184+ goto accept;
11185+
11186+ /* is the parent dir cached? */
027c5e7a
AM
11187+ br = au_sbr(sb, nsi_lock.bindex);
11188+ atomic_inc(&br->br_count);
1facf9fc 11189+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
11190+ if (IS_ERR(dentry))
11191+ goto out_unlock;
11192+ if (dentry)
11193+ goto accept;
11194+
11195+ /* lookup path */
027c5e7a 11196+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
1facf9fc 11197+ if (IS_ERR(dentry))
11198+ goto out_unlock;
11199+ if (unlikely(!dentry))
11200+ /* todo?: make it ESTALE */
11201+ goto out_unlock;
11202+
4f0767ce 11203+accept:
027c5e7a
AM
11204+ if (!au_digen_test(dentry, au_sigen(sb))
11205+ && dentry->d_inode->i_generation == fh[Fh_igen])
1facf9fc 11206+ goto out_unlock; /* success */
11207+
11208+ dput(dentry);
11209+ dentry = ERR_PTR(-ESTALE);
4f0767ce 11210+out_unlock:
027c5e7a
AM
11211+ if (br)
11212+ atomic_dec(&br->br_count);
1facf9fc 11213+ si_read_unlock(sb);
4f0767ce 11214+out:
1facf9fc 11215+ AuTraceErrPtr(dentry);
11216+ return dentry;
11217+}
11218+
11219+#if 0 /* reserved for future use */
11220+/* support subtreecheck option */
11221+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
11222+ int fh_len, int fh_type)
11223+{
11224+ struct dentry *parent;
11225+ __u32 *fh = fid->raw;
11226+ ino_t dir_ino;
11227+
11228+ dir_ino = decode_ino(fh + Fh_dir_ino);
11229+ parent = decode_by_ino(sb, dir_ino, 0);
11230+ if (IS_ERR(parent))
11231+ goto out;
11232+ if (!parent)
11233+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
11234+ dir_ino, fh, fh_len);
11235+
4f0767ce 11236+out:
1facf9fc 11237+ AuTraceErrPtr(parent);
11238+ return parent;
11239+}
11240+#endif
11241+
11242+/* ---------------------------------------------------------------------- */
11243+
0c3ec466
AM
11244+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
11245+ struct inode *dir)
1facf9fc 11246+{
11247+ int err;
0c3ec466 11248+ aufs_bindex_t bindex;
1facf9fc 11249+ struct super_block *sb, *h_sb;
0c3ec466
AM
11250+ struct dentry *dentry, *parent, *h_parent;
11251+ struct inode *h_dir;
1facf9fc 11252+ struct au_branch *br;
11253+
1facf9fc 11254+ err = -ENOSPC;
11255+ if (unlikely(*max_len <= Fh_tail)) {
11256+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
11257+ goto out;
11258+ }
11259+
11260+ err = FILEID_ROOT;
0c3ec466
AM
11261+ if (inode->i_ino == AUFS_ROOT_INO) {
11262+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO);
1facf9fc 11263+ goto out;
11264+ }
11265+
1facf9fc 11266+ h_parent = NULL;
0c3ec466
AM
11267+ sb = inode->i_sb;
11268+ err = si_read_lock(sb, AuLock_FLUSH);
027c5e7a
AM
11269+ if (unlikely(err))
11270+ goto out;
11271+
1facf9fc 11272+#ifdef CONFIG_AUFS_DEBUG
11273+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
11274+ AuWarn1("NFS-exporting requires xino\n");
11275+#endif
027c5e7a 11276+ err = -EIO;
0c3ec466
AM
11277+ parent = NULL;
11278+ ii_read_lock_child(inode);
11279+ bindex = au_ibstart(inode);
11280+ if (!dir) {
c1595e42 11281+ dentry = d_find_any_alias(inode);
0c3ec466
AM
11282+ if (unlikely(!dentry))
11283+ goto out_unlock;
11284+ AuDebugOn(au_test_anon(dentry));
11285+ parent = dget_parent(dentry);
11286+ dput(dentry);
11287+ if (unlikely(!parent))
11288+ goto out_unlock;
11289+ dir = parent->d_inode;
1facf9fc 11290+ }
0c3ec466
AM
11291+
11292+ ii_read_lock_parent(dir);
11293+ h_dir = au_h_iptr(dir, bindex);
11294+ ii_read_unlock(dir);
11295+ if (unlikely(!h_dir))
11296+ goto out_parent;
c1595e42 11297+ h_parent = d_find_any_alias(h_dir);
1facf9fc 11298+ if (unlikely(!h_parent))
0c3ec466 11299+ goto out_hparent;
1facf9fc 11300+
11301+ err = -EPERM;
11302+ br = au_sbr(sb, bindex);
86dc4139 11303+ h_sb = au_br_sb(br);
1facf9fc 11304+ if (unlikely(!h_sb->s_export_op)) {
11305+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
0c3ec466 11306+ goto out_hparent;
1facf9fc 11307+ }
11308+
11309+ fh[Fh_br_id] = br->br_id;
11310+ fh[Fh_sigen] = au_sigen(sb);
11311+ encode_ino(fh + Fh_ino, inode->i_ino);
0c3ec466 11312+ encode_ino(fh + Fh_dir_ino, dir->i_ino);
1facf9fc 11313+ fh[Fh_igen] = inode->i_generation;
11314+
11315+ *max_len -= Fh_tail;
11316+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
11317+ max_len,
11318+ /*connectable or subtreecheck*/0);
11319+ err = fh[Fh_h_type];
11320+ *max_len += Fh_tail;
11321+ /* todo: macros? */
1716fcea 11322+ if (err != FILEID_INVALID)
1facf9fc 11323+ err = 99;
11324+ else
11325+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
11326+
0c3ec466 11327+out_hparent:
1facf9fc 11328+ dput(h_parent);
0c3ec466 11329+out_parent:
1facf9fc 11330+ dput(parent);
0c3ec466
AM
11331+out_unlock:
11332+ ii_read_unlock(inode);
11333+ si_read_unlock(sb);
4f0767ce 11334+out:
1facf9fc 11335+ if (unlikely(err < 0))
1716fcea 11336+ err = FILEID_INVALID;
1facf9fc 11337+ return err;
11338+}
11339+
11340+/* ---------------------------------------------------------------------- */
11341+
4a4d8108
AM
11342+static int aufs_commit_metadata(struct inode *inode)
11343+{
11344+ int err;
11345+ aufs_bindex_t bindex;
11346+ struct super_block *sb;
11347+ struct inode *h_inode;
11348+ int (*f)(struct inode *inode);
11349+
11350+ sb = inode->i_sb;
e49829fe 11351+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
11352+ ii_write_lock_child(inode);
11353+ bindex = au_ibstart(inode);
11354+ AuDebugOn(bindex < 0);
11355+ h_inode = au_h_iptr(inode, bindex);
11356+
11357+ f = h_inode->i_sb->s_export_op->commit_metadata;
11358+ if (f)
11359+ err = f(h_inode);
11360+ else {
11361+ struct writeback_control wbc = {
11362+ .sync_mode = WB_SYNC_ALL,
11363+ .nr_to_write = 0 /* metadata only */
11364+ };
11365+
11366+ err = sync_inode(h_inode, &wbc);
11367+ }
11368+
11369+ au_cpup_attr_timesizes(inode);
11370+ ii_write_unlock(inode);
11371+ si_read_unlock(sb);
11372+ return err;
11373+}
11374+
11375+/* ---------------------------------------------------------------------- */
11376+
1facf9fc 11377+static struct export_operations aufs_export_op = {
4a4d8108 11378+ .fh_to_dentry = aufs_fh_to_dentry,
1facf9fc 11379+ /* .fh_to_parent = aufs_fh_to_parent, */
4a4d8108
AM
11380+ .encode_fh = aufs_encode_fh,
11381+ .commit_metadata = aufs_commit_metadata
1facf9fc 11382+};
11383+
11384+void au_export_init(struct super_block *sb)
11385+{
11386+ struct au_sbinfo *sbinfo;
11387+ __u32 u;
11388+
11389+ sb->s_export_op = &aufs_export_op;
11390+ sbinfo = au_sbi(sb);
11391+ sbinfo->si_xigen = NULL;
11392+ get_random_bytes(&u, sizeof(u));
11393+ BUILD_BUG_ON(sizeof(u) != sizeof(int));
11394+ atomic_set(&sbinfo->si_xigen_next, u);
11395+}
076b876e
AM
11396diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c
11397--- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
11398+++ linux/fs/aufs/fhsm.c 2015-01-25 13:00:38.631047076 +0100
11399@@ -0,0 +1,426 @@
076b876e
AM
11400+/*
11401+ * Copyright (C) 2011-2014 Junjiro R. Okajima
11402+ *
11403+ * This program, aufs is free software; you can redistribute it and/or modify
11404+ * it under the terms of the GNU General Public License as published by
11405+ * the Free Software Foundation; either version 2 of the License, or
11406+ * (at your option) any later version.
11407+ *
11408+ * This program is distributed in the hope that it will be useful,
11409+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11410+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11411+ * GNU General Public License for more details.
11412+ *
11413+ * You should have received a copy of the GNU General Public License
11414+ * along with this program; if not, write to the Free Software
11415+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
11416+ */
11417+
11418+/*
11419+ * File-based Hierarchy Storage Management
11420+ */
11421+
11422+#include <linux/anon_inodes.h>
11423+#include <linux/poll.h>
11424+#include <linux/seq_file.h>
11425+#include <linux/statfs.h>
11426+#include "aufs.h"
11427+
c1595e42
JR
11428+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb)
11429+{
11430+ struct au_sbinfo *sbinfo;
11431+ struct au_fhsm *fhsm;
11432+
11433+ SiMustAnyLock(sb);
11434+
11435+ sbinfo = au_sbi(sb);
11436+ fhsm = &sbinfo->si_fhsm;
11437+ AuDebugOn(!fhsm);
11438+ return fhsm->fhsm_bottom;
11439+}
11440+
11441+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex)
11442+{
11443+ struct au_sbinfo *sbinfo;
11444+ struct au_fhsm *fhsm;
11445+
11446+ SiMustWriteLock(sb);
11447+
11448+ sbinfo = au_sbi(sb);
11449+ fhsm = &sbinfo->si_fhsm;
11450+ AuDebugOn(!fhsm);
11451+ fhsm->fhsm_bottom = bindex;
11452+}
11453+
11454+/* ---------------------------------------------------------------------- */
11455+
076b876e
AM
11456+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br)
11457+{
11458+ struct au_br_fhsm *bf;
11459+
11460+ bf = br->br_fhsm;
11461+ MtxMustLock(&bf->bf_lock);
11462+
11463+ return !bf->bf_readable
11464+ || time_after(jiffies,
11465+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire);
11466+}
11467+
11468+/* ---------------------------------------------------------------------- */
11469+
11470+static void au_fhsm_notify(struct super_block *sb, int val)
11471+{
11472+ struct au_sbinfo *sbinfo;
11473+ struct au_fhsm *fhsm;
11474+
11475+ SiMustAnyLock(sb);
11476+
11477+ sbinfo = au_sbi(sb);
11478+ fhsm = &sbinfo->si_fhsm;
11479+ if (au_fhsm_pid(fhsm)
11480+ && atomic_read(&fhsm->fhsm_readable) != -1) {
11481+ atomic_set(&fhsm->fhsm_readable, val);
11482+ if (val)
11483+ wake_up(&fhsm->fhsm_wqh);
11484+ }
11485+}
11486+
11487+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex,
11488+ struct aufs_stfs *rstfs, int do_lock, int do_notify)
11489+{
11490+ int err;
11491+ struct au_branch *br;
11492+ struct au_br_fhsm *bf;
11493+
11494+ br = au_sbr(sb, bindex);
11495+ AuDebugOn(au_br_rdonly(br));
11496+ bf = br->br_fhsm;
11497+ AuDebugOn(!bf);
11498+
11499+ if (do_lock)
11500+ mutex_lock(&bf->bf_lock);
11501+ else
11502+ MtxMustLock(&bf->bf_lock);
11503+
11504+ /* sb->s_root for NFS is unreliable */
11505+ err = au_br_stfs(br, &bf->bf_stfs);
11506+ if (unlikely(err)) {
11507+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err);
11508+ goto out;
11509+ }
11510+
11511+ bf->bf_jiffy = jiffies;
11512+ bf->bf_readable = 1;
11513+ if (do_notify)
11514+ au_fhsm_notify(sb, /*val*/1);
11515+ if (rstfs)
11516+ *rstfs = bf->bf_stfs;
11517+
11518+out:
11519+ if (do_lock)
11520+ mutex_unlock(&bf->bf_lock);
11521+ au_fhsm_notify(sb, /*val*/1);
11522+
11523+ return err;
11524+}
11525+
11526+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force)
11527+{
11528+ int err;
076b876e
AM
11529+ struct au_sbinfo *sbinfo;
11530+ struct au_fhsm *fhsm;
11531+ struct au_branch *br;
11532+ struct au_br_fhsm *bf;
11533+
11534+ AuDbg("b%d, force %d\n", bindex, force);
11535+ SiMustAnyLock(sb);
11536+
11537+ sbinfo = au_sbi(sb);
11538+ fhsm = &sbinfo->si_fhsm;
c1595e42
JR
11539+ if (!au_ftest_si(sbinfo, FHSM)
11540+ || fhsm->fhsm_bottom == bindex)
076b876e
AM
11541+ return;
11542+
11543+ br = au_sbr(sb, bindex);
11544+ bf = br->br_fhsm;
11545+ AuDebugOn(!bf);
11546+ mutex_lock(&bf->bf_lock);
11547+ if (force
11548+ || au_fhsm_pid(fhsm)
11549+ || au_fhsm_test_jiffy(sbinfo, br))
11550+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0,
11551+ /*do_notify*/1);
11552+ mutex_unlock(&bf->bf_lock);
11553+}
11554+
11555+void au_fhsm_wrote_all(struct super_block *sb, int force)
11556+{
11557+ aufs_bindex_t bindex, bend;
11558+ struct au_branch *br;
11559+
11560+ /* exclude the bottom */
c1595e42 11561+ bend = au_fhsm_bottom(sb);
076b876e
AM
11562+ for (bindex = 0; bindex < bend; bindex++) {
11563+ br = au_sbr(sb, bindex);
11564+ if (au_br_fhsm(br->br_perm))
11565+ au_fhsm_wrote(sb, bindex, force);
11566+ }
11567+}
11568+
11569+/* ---------------------------------------------------------------------- */
11570+
11571+static unsigned int au_fhsm_poll(struct file *file,
11572+ struct poll_table_struct *wait)
11573+{
11574+ unsigned int mask;
11575+ struct au_sbinfo *sbinfo;
11576+ struct au_fhsm *fhsm;
11577+
11578+ mask = 0;
11579+ sbinfo = file->private_data;
11580+ fhsm = &sbinfo->si_fhsm;
11581+ poll_wait(file, &fhsm->fhsm_wqh, wait);
11582+ if (atomic_read(&fhsm->fhsm_readable))
11583+ mask = POLLIN /* | POLLRDNORM */;
11584+
11585+ AuTraceErr((int)mask);
11586+ return mask;
11587+}
11588+
11589+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr,
11590+ struct aufs_stfs *stfs, __s16 brid)
11591+{
11592+ int err;
11593+
11594+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs));
11595+ if (!err)
11596+ err = __put_user(brid, &stbr->brid);
11597+ if (unlikely(err))
11598+ err = -EFAULT;
11599+
11600+ return err;
11601+}
11602+
11603+static ssize_t au_fhsm_do_read(struct super_block *sb,
11604+ struct aufs_stbr __user *stbr, size_t count)
11605+{
11606+ ssize_t err;
11607+ int nstbr;
11608+ aufs_bindex_t bindex, bend;
11609+ struct au_branch *br;
11610+ struct au_br_fhsm *bf;
11611+
11612+ /* except the bottom branch */
11613+ err = 0;
11614+ nstbr = 0;
c1595e42 11615+ bend = au_fhsm_bottom(sb);
076b876e
AM
11616+ for (bindex = 0; !err && bindex < bend; bindex++) {
11617+ br = au_sbr(sb, bindex);
11618+ if (!au_br_fhsm(br->br_perm))
11619+ continue;
11620+
11621+ bf = br->br_fhsm;
11622+ mutex_lock(&bf->bf_lock);
11623+ if (bf->bf_readable) {
11624+ err = -EFAULT;
11625+ if (count >= sizeof(*stbr))
11626+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs,
11627+ br->br_id);
11628+ if (!err) {
11629+ bf->bf_readable = 0;
11630+ count -= sizeof(*stbr);
11631+ nstbr++;
11632+ }
11633+ }
11634+ mutex_unlock(&bf->bf_lock);
11635+ }
11636+ if (!err)
11637+ err = sizeof(*stbr) * nstbr;
11638+
11639+ return err;
11640+}
11641+
11642+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
11643+ loff_t *pos)
11644+{
11645+ ssize_t err;
11646+ int readable;
11647+ aufs_bindex_t nfhsm, bindex, bend;
11648+ struct au_sbinfo *sbinfo;
11649+ struct au_fhsm *fhsm;
11650+ struct au_branch *br;
11651+ struct super_block *sb;
11652+
11653+ err = 0;
11654+ sbinfo = file->private_data;
11655+ fhsm = &sbinfo->si_fhsm;
11656+need_data:
11657+ spin_lock_irq(&fhsm->fhsm_wqh.lock);
11658+ if (!atomic_read(&fhsm->fhsm_readable)) {
11659+ if (vfsub_file_flags(file) & O_NONBLOCK)
11660+ err = -EAGAIN;
11661+ else
11662+ err = wait_event_interruptible_locked_irq
11663+ (fhsm->fhsm_wqh,
11664+ atomic_read(&fhsm->fhsm_readable));
11665+ }
11666+ spin_unlock_irq(&fhsm->fhsm_wqh.lock);
11667+ if (unlikely(err))
11668+ goto out;
11669+
11670+ /* sb may already be dead */
11671+ au_rw_read_lock(&sbinfo->si_rwsem);
11672+ readable = atomic_read(&fhsm->fhsm_readable);
11673+ if (readable > 0) {
11674+ sb = sbinfo->si_sb;
11675+ AuDebugOn(!sb);
11676+ /* exclude the bottom branch */
11677+ nfhsm = 0;
c1595e42 11678+ bend = au_fhsm_bottom(sb);
076b876e
AM
11679+ for (bindex = 0; bindex < bend; bindex++) {
11680+ br = au_sbr(sb, bindex);
11681+ if (au_br_fhsm(br->br_perm))
11682+ nfhsm++;
11683+ }
11684+ err = -EMSGSIZE;
11685+ if (nfhsm * sizeof(struct aufs_stbr) <= count) {
11686+ atomic_set(&fhsm->fhsm_readable, 0);
11687+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
11688+ count);
11689+ }
11690+ }
11691+ au_rw_read_unlock(&sbinfo->si_rwsem);
11692+ if (!readable)
11693+ goto need_data;
11694+
11695+out:
11696+ return err;
11697+}
11698+
11699+static int au_fhsm_release(struct inode *inode, struct file *file)
11700+{
11701+ struct au_sbinfo *sbinfo;
11702+ struct au_fhsm *fhsm;
11703+
11704+ /* sb may already be dead */
11705+ sbinfo = file->private_data;
11706+ fhsm = &sbinfo->si_fhsm;
11707+ spin_lock(&fhsm->fhsm_spin);
11708+ fhsm->fhsm_pid = 0;
11709+ spin_unlock(&fhsm->fhsm_spin);
11710+ kobject_put(&sbinfo->si_kobj);
11711+
11712+ return 0;
11713+}
11714+
11715+static const struct file_operations au_fhsm_fops = {
11716+ .owner = THIS_MODULE,
11717+ .llseek = noop_llseek,
11718+ .read = au_fhsm_read,
11719+ .poll = au_fhsm_poll,
11720+ .release = au_fhsm_release
11721+};
11722+
11723+int au_fhsm_fd(struct super_block *sb, int oflags)
11724+{
11725+ int err, fd;
11726+ struct au_sbinfo *sbinfo;
11727+ struct au_fhsm *fhsm;
11728+
11729+ err = -EPERM;
11730+ if (unlikely(!capable(CAP_SYS_ADMIN)))
11731+ goto out;
11732+
11733+ err = -EINVAL;
11734+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK)))
11735+ goto out;
11736+
11737+ err = 0;
11738+ sbinfo = au_sbi(sb);
11739+ fhsm = &sbinfo->si_fhsm;
11740+ spin_lock(&fhsm->fhsm_spin);
11741+ if (!fhsm->fhsm_pid)
11742+ fhsm->fhsm_pid = current->pid;
11743+ else
11744+ err = -EBUSY;
11745+ spin_unlock(&fhsm->fhsm_spin);
11746+ if (unlikely(err))
11747+ goto out;
11748+
11749+ oflags |= O_RDONLY;
11750+ /* oflags |= FMODE_NONOTIFY; */
11751+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags);
11752+ err = fd;
11753+ if (unlikely(fd < 0))
11754+ goto out_pid;
11755+
11756+ /* succeed reglardless 'fhsm' status */
11757+ kobject_get(&sbinfo->si_kobj);
11758+ si_noflush_read_lock(sb);
11759+ if (au_ftest_si(sbinfo, FHSM))
11760+ au_fhsm_wrote_all(sb, /*force*/0);
11761+ si_read_unlock(sb);
11762+ goto out; /* success */
11763+
11764+out_pid:
11765+ spin_lock(&fhsm->fhsm_spin);
11766+ fhsm->fhsm_pid = 0;
11767+ spin_unlock(&fhsm->fhsm_spin);
11768+out:
11769+ AuTraceErr(err);
11770+ return err;
11771+}
11772+
11773+/* ---------------------------------------------------------------------- */
11774+
11775+int au_fhsm_br_alloc(struct au_branch *br)
11776+{
11777+ int err;
11778+
11779+ err = 0;
11780+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS);
11781+ if (br->br_fhsm)
11782+ au_br_fhsm_init(br->br_fhsm);
11783+ else
11784+ err = -ENOMEM;
11785+
11786+ return err;
11787+}
11788+
11789+/* ---------------------------------------------------------------------- */
11790+
11791+void au_fhsm_fin(struct super_block *sb)
11792+{
11793+ au_fhsm_notify(sb, /*val*/-1);
11794+}
11795+
11796+void au_fhsm_init(struct au_sbinfo *sbinfo)
11797+{
11798+ struct au_fhsm *fhsm;
11799+
11800+ fhsm = &sbinfo->si_fhsm;
11801+ spin_lock_init(&fhsm->fhsm_spin);
11802+ init_waitqueue_head(&fhsm->fhsm_wqh);
11803+ atomic_set(&fhsm->fhsm_readable, 0);
11804+ fhsm->fhsm_expire
11805+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC);
c1595e42 11806+ fhsm->fhsm_bottom = -1;
076b876e
AM
11807+}
11808+
11809+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec)
11810+{
11811+ sbinfo->si_fhsm.fhsm_expire
11812+ = msecs_to_jiffies(sec * MSEC_PER_SEC);
11813+}
11814+
11815+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo)
11816+{
11817+ unsigned int u;
11818+
11819+ if (!au_ftest_si(sbinfo, FHSM))
11820+ return;
11821+
11822+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC;
11823+ if (u != AUFS_FHSM_CACHE_DEF_SEC)
11824+ seq_printf(seq, ",fhsm_sec=%u", u);
11825+}
7f207e10
AM
11826diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
11827--- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
11828+++ linux/fs/aufs/file.c 2015-01-25 13:00:38.631047076 +0100
11829@@ -0,0 +1,829 @@
1facf9fc 11830+/*
523b37e3 11831+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 11832+ *
11833+ * This program, aufs is free software; you can redistribute it and/or modify
11834+ * it under the terms of the GNU General Public License as published by
11835+ * the Free Software Foundation; either version 2 of the License, or
11836+ * (at your option) any later version.
dece6358
AM
11837+ *
11838+ * This program is distributed in the hope that it will be useful,
11839+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11840+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11841+ * GNU General Public License for more details.
11842+ *
11843+ * You should have received a copy of the GNU General Public License
523b37e3 11844+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 11845+ */
11846+
11847+/*
4a4d8108 11848+ * handling file/dir, and address_space operation
1facf9fc 11849+ */
11850+
7eafdf33
AM
11851+#ifdef CONFIG_AUFS_DEBUG
11852+#include <linux/migrate.h>
11853+#endif
4a4d8108 11854+#include <linux/pagemap.h>
1facf9fc 11855+#include "aufs.h"
11856+
4a4d8108
AM
11857+/* drop flags for writing */
11858+unsigned int au_file_roflags(unsigned int flags)
11859+{
11860+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC);
11861+ flags |= O_RDONLY | O_NOATIME;
11862+ return flags;
11863+}
11864+
11865+/* common functions to regular file and dir */
11866+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 11867+ struct file *file, int force_wr)
1facf9fc 11868+{
1308ab2a 11869+ struct file *h_file;
4a4d8108
AM
11870+ struct dentry *h_dentry;
11871+ struct inode *h_inode;
11872+ struct super_block *sb;
11873+ struct au_branch *br;
11874+ struct path h_path;
11875+ int err, exec_flag;
1facf9fc 11876+
4a4d8108
AM
11877+ /* a race condition can happen between open and unlink/rmdir */
11878+ h_file = ERR_PTR(-ENOENT);
11879+ h_dentry = au_h_dptr(dentry, bindex);
b752ccd1 11880+ if (au_test_nfsd() && !h_dentry)
4a4d8108
AM
11881+ goto out;
11882+ h_inode = h_dentry->d_inode;
b752ccd1 11883+ if (au_test_nfsd() && !h_inode)
4a4d8108 11884+ goto out;
027c5e7a
AM
11885+ spin_lock(&h_dentry->d_lock);
11886+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry))
11887+ || !h_inode
11888+ /* || !dentry->d_inode->i_nlink */
11889+ ;
11890+ spin_unlock(&h_dentry->d_lock);
11891+ if (unlikely(err))
4a4d8108 11892+ goto out;
1facf9fc 11893+
4a4d8108
AM
11894+ sb = dentry->d_sb;
11895+ br = au_sbr(sb, bindex);
11896+ h_file = ERR_PTR(-EACCES);
2cbb1c4b 11897+ exec_flag = flags & __FMODE_EXEC;
86dc4139 11898+ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC))
027c5e7a 11899+ goto out;
1facf9fc 11900+
4a4d8108 11901+ /* drop flags for writing */
392086de
AM
11902+ if (au_test_ro(sb, bindex, dentry->d_inode)) {
11903+ if (force_wr && !(flags & O_WRONLY))
11904+ force_wr = 0;
4a4d8108 11905+ flags = au_file_roflags(flags);
392086de
AM
11906+ if (force_wr) {
11907+ h_file = ERR_PTR(-EROFS);
11908+ flags = au_file_roflags(flags);
11909+ if (unlikely(vfsub_native_ro(h_inode)
11910+ || IS_APPEND(h_inode)))
11911+ goto out;
11912+ flags &= ~O_ACCMODE;
11913+ flags |= O_WRONLY;
11914+ }
11915+ }
4a4d8108
AM
11916+ flags &= ~O_CREAT;
11917+ atomic_inc(&br->br_count);
11918+ h_path.dentry = h_dentry;
86dc4139 11919+ h_path.mnt = au_br_mnt(br);
38d290e6 11920+ h_file = vfsub_dentry_open(&h_path, flags);
4a4d8108
AM
11921+ if (IS_ERR(h_file))
11922+ goto out_br;
dece6358 11923+
4a4d8108
AM
11924+ if (exec_flag) {
11925+ err = deny_write_access(h_file);
11926+ if (unlikely(err)) {
11927+ fput(h_file);
11928+ h_file = ERR_PTR(err);
11929+ goto out_br;
11930+ }
11931+ }
953406b4 11932+ fsnotify_open(h_file);
4a4d8108 11933+ goto out; /* success */
1facf9fc 11934+
4f0767ce 11935+out_br:
4a4d8108 11936+ atomic_dec(&br->br_count);
4f0767ce 11937+out:
4a4d8108
AM
11938+ return h_file;
11939+}
1308ab2a 11940+
076b876e
AM
11941+static int au_cmoo(struct dentry *dentry)
11942+{
11943+ int err, cmoo;
11944+ unsigned int udba;
11945+ struct path h_path;
11946+ struct au_pin pin;
11947+ struct au_cp_generic cpg = {
11948+ .dentry = dentry,
11949+ .bdst = -1,
11950+ .bsrc = -1,
11951+ .len = -1,
11952+ .pin = &pin,
11953+ .flags = AuCpup_DTIME | AuCpup_HOPEN
11954+ };
11955+ struct inode *inode, *delegated;
11956+ struct super_block *sb;
11957+ struct au_sbinfo *sbinfo;
11958+ struct au_fhsm *fhsm;
11959+ pid_t pid;
11960+ struct au_branch *br;
11961+ struct dentry *parent;
11962+ struct au_hinode *hdir;
11963+
11964+ DiMustWriteLock(dentry);
11965+ inode = dentry->d_inode;
11966+ IiMustWriteLock(inode);
11967+
11968+ err = 0;
11969+ if (IS_ROOT(dentry))
11970+ goto out;
11971+ cpg.bsrc = au_dbstart(dentry);
11972+ if (!cpg.bsrc)
11973+ goto out;
11974+
11975+ sb = dentry->d_sb;
11976+ sbinfo = au_sbi(sb);
11977+ fhsm = &sbinfo->si_fhsm;
11978+ pid = au_fhsm_pid(fhsm);
11979+ if (pid
11980+ && (current->pid == pid
11981+ || current->real_parent->pid == pid))
11982+ goto out;
11983+
11984+ br = au_sbr(sb, cpg.bsrc);
11985+ cmoo = au_br_cmoo(br->br_perm);
11986+ if (!cmoo)
11987+ goto out;
11988+ if (!S_ISREG(inode->i_mode))
11989+ cmoo &= AuBrAttr_COO_ALL;
11990+ if (!cmoo)
11991+ goto out;
11992+
11993+ parent = dget_parent(dentry);
11994+ di_write_lock_parent(parent);
11995+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1);
11996+ cpg.bdst = err;
11997+ if (unlikely(err < 0)) {
11998+ err = 0; /* there is no upper writable branch */
11999+ goto out_dgrade;
12000+ }
12001+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst);
12002+
12003+ /* do not respect the coo attrib for the target branch */
12004+ err = au_cpup_dirs(dentry, cpg.bdst);
12005+ if (unlikely(err))
12006+ goto out_dgrade;
12007+
12008+ di_downgrade_lock(parent, AuLock_IR);
12009+ udba = au_opt_udba(sb);
12010+ err = au_pin(&pin, dentry, cpg.bdst, udba,
12011+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12012+ if (unlikely(err))
12013+ goto out_parent;
12014+
12015+ err = au_sio_cpup_simple(&cpg);
12016+ au_unpin(&pin);
12017+ if (unlikely(err))
12018+ goto out_parent;
12019+ if (!(cmoo & AuBrWAttr_MOO))
12020+ goto out_parent; /* success */
12021+
12022+ err = au_pin(&pin, dentry, cpg.bsrc, udba,
12023+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12024+ if (unlikely(err))
12025+ goto out_parent;
12026+
12027+ h_path.mnt = au_br_mnt(br);
12028+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc);
12029+ hdir = au_hi(parent->d_inode, cpg.bsrc);
12030+ delegated = NULL;
12031+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1);
12032+ au_unpin(&pin);
12033+ /* todo: keep h_dentry or not? */
12034+ if (unlikely(err == -EWOULDBLOCK)) {
12035+ pr_warn("cannot retry for NFSv4 delegation"
12036+ " for an internal unlink\n");
12037+ iput(delegated);
12038+ }
12039+ if (unlikely(err)) {
12040+ pr_err("unlink %pd after coo failed (%d), ignored\n",
12041+ dentry, err);
12042+ err = 0;
12043+ }
12044+ goto out_parent; /* success */
12045+
12046+out_dgrade:
12047+ di_downgrade_lock(parent, AuLock_IR);
12048+out_parent:
12049+ di_read_unlock(parent, AuLock_IR);
12050+ dput(parent);
12051+out:
12052+ AuTraceErr(err);
12053+ return err;
12054+}
12055+
4a4d8108
AM
12056+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
12057+ struct au_fidir *fidir)
1facf9fc 12058+{
dece6358 12059+ int err;
1facf9fc 12060+ struct dentry *dentry;
076b876e 12061+ struct au_finfo *finfo;
1308ab2a 12062+
4a4d8108
AM
12063+ err = au_finfo_init(file, fidir);
12064+ if (unlikely(err))
12065+ goto out;
1facf9fc 12066+
12067+ dentry = file->f_dentry;
076b876e
AM
12068+ di_write_lock_child(dentry);
12069+ err = au_cmoo(dentry);
12070+ di_downgrade_lock(dentry, AuLock_IR);
12071+ if (!err)
12072+ err = open(file, vfsub_file_flags(file));
4a4d8108 12073+ di_read_unlock(dentry, AuLock_IR);
1facf9fc 12074+
076b876e
AM
12075+ finfo = au_fi(file);
12076+ if (!err) {
12077+ finfo->fi_file = file;
12078+ au_sphl_add(&finfo->fi_hlist,
12079+ &au_sbi(file->f_dentry->d_sb)->si_files);
12080+ }
4a4d8108
AM
12081+ fi_write_unlock(file);
12082+ if (unlikely(err)) {
076b876e 12083+ finfo->fi_hdir = NULL;
4a4d8108 12084+ au_finfo_fin(file);
1308ab2a 12085+ }
4a4d8108 12086+
4f0767ce 12087+out:
1308ab2a 12088+ return err;
12089+}
dece6358 12090+
4a4d8108 12091+int au_reopen_nondir(struct file *file)
1308ab2a 12092+{
4a4d8108
AM
12093+ int err;
12094+ aufs_bindex_t bstart;
12095+ struct dentry *dentry;
12096+ struct file *h_file, *h_file_tmp;
1308ab2a 12097+
4a4d8108 12098+ dentry = file->f_dentry;
4a4d8108
AM
12099+ bstart = au_dbstart(dentry);
12100+ h_file_tmp = NULL;
12101+ if (au_fbstart(file) == bstart) {
12102+ h_file = au_hf_top(file);
12103+ if (file->f_mode == h_file->f_mode)
12104+ return 0; /* success */
12105+ h_file_tmp = h_file;
12106+ get_file(h_file_tmp);
12107+ au_set_h_fptr(file, bstart, NULL);
12108+ }
12109+ AuDebugOn(au_fi(file)->fi_hdir);
86dc4139
AM
12110+ /*
12111+ * it can happen
12112+ * file exists on both of rw and ro
12113+ * open --> dbstart and fbstart are both 0
12114+ * prepend a branch as rw, "rw" become ro
12115+ * remove rw/file
12116+ * delete the top branch, "rw" becomes rw again
12117+ * --> dbstart is 1, fbstart is still 0
12118+ * write --> fbstart is 0 but dbstart is 1
12119+ */
12120+ /* AuDebugOn(au_fbstart(file) < bstart); */
1308ab2a 12121+
4a4d8108 12122+ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC,
392086de 12123+ file, /*force_wr*/0);
4a4d8108 12124+ err = PTR_ERR(h_file);
86dc4139
AM
12125+ if (IS_ERR(h_file)) {
12126+ if (h_file_tmp) {
12127+ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count);
12128+ au_set_h_fptr(file, bstart, h_file_tmp);
12129+ h_file_tmp = NULL;
12130+ }
4a4d8108 12131+ goto out; /* todo: close all? */
86dc4139 12132+ }
4a4d8108
AM
12133+
12134+ err = 0;
12135+ au_set_fbstart(file, bstart);
12136+ au_set_h_fptr(file, bstart, h_file);
12137+ au_update_figen(file);
12138+ /* todo: necessary? */
12139+ /* file->f_ra = h_file->f_ra; */
12140+
4f0767ce 12141+out:
4a4d8108
AM
12142+ if (h_file_tmp)
12143+ fput(h_file_tmp);
12144+ return err;
1facf9fc 12145+}
12146+
1308ab2a 12147+/* ---------------------------------------------------------------------- */
12148+
4a4d8108
AM
12149+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
12150+ struct dentry *hi_wh)
1facf9fc 12151+{
4a4d8108
AM
12152+ int err;
12153+ aufs_bindex_t bstart;
12154+ struct au_dinfo *dinfo;
12155+ struct dentry *h_dentry;
12156+ struct au_hdentry *hdp;
1facf9fc 12157+
4a4d8108
AM
12158+ dinfo = au_di(file->f_dentry);
12159+ AuRwMustWriteLock(&dinfo->di_rwsem);
dece6358 12160+
4a4d8108
AM
12161+ bstart = dinfo->di_bstart;
12162+ dinfo->di_bstart = btgt;
12163+ hdp = dinfo->di_hdentry;
12164+ h_dentry = hdp[0 + btgt].hd_dentry;
12165+ hdp[0 + btgt].hd_dentry = hi_wh;
12166+ err = au_reopen_nondir(file);
12167+ hdp[0 + btgt].hd_dentry = h_dentry;
12168+ dinfo->di_bstart = bstart;
1facf9fc 12169+
1facf9fc 12170+ return err;
12171+}
12172+
4a4d8108 12173+static int au_ready_to_write_wh(struct file *file, loff_t len,
86dc4139 12174+ aufs_bindex_t bcpup, struct au_pin *pin)
1facf9fc 12175+{
4a4d8108 12176+ int err;
027c5e7a 12177+ struct inode *inode, *h_inode;
c2b27bf2
AM
12178+ struct dentry *h_dentry, *hi_wh;
12179+ struct au_cp_generic cpg = {
12180+ .dentry = file->f_dentry,
12181+ .bdst = bcpup,
12182+ .bsrc = -1,
12183+ .len = len,
12184+ .pin = pin
12185+ };
1facf9fc 12186+
c2b27bf2
AM
12187+ au_update_dbstart(cpg.dentry);
12188+ inode = cpg.dentry->d_inode;
027c5e7a 12189+ h_inode = NULL;
c2b27bf2
AM
12190+ if (au_dbstart(cpg.dentry) <= bcpup
12191+ && au_dbend(cpg.dentry) >= bcpup) {
12192+ h_dentry = au_h_dptr(cpg.dentry, bcpup);
027c5e7a
AM
12193+ if (h_dentry)
12194+ h_inode = h_dentry->d_inode;
12195+ }
4a4d8108 12196+ hi_wh = au_hi_wh(inode, bcpup);
027c5e7a 12197+ if (!hi_wh && !h_inode)
c2b27bf2 12198+ err = au_sio_cpup_wh(&cpg, file);
4a4d8108
AM
12199+ else
12200+ /* already copied-up after unlink */
12201+ err = au_reopen_wh(file, bcpup, hi_wh);
1facf9fc 12202+
4a4d8108 12203+ if (!err
38d290e6
JR
12204+ && (inode->i_nlink > 1
12205+ || (inode->i_state & I_LINKABLE))
c2b27bf2
AM
12206+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK))
12207+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup));
1308ab2a 12208+
dece6358 12209+ return err;
1facf9fc 12210+}
12211+
4a4d8108
AM
12212+/*
12213+ * prepare the @file for writing.
12214+ */
12215+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin)
1facf9fc 12216+{
4a4d8108 12217+ int err;
c2b27bf2 12218+ aufs_bindex_t dbstart;
c1595e42 12219+ struct dentry *parent;
86dc4139 12220+ struct inode *inode;
1facf9fc 12221+ struct super_block *sb;
4a4d8108 12222+ struct file *h_file;
c2b27bf2
AM
12223+ struct au_cp_generic cpg = {
12224+ .dentry = file->f_dentry,
12225+ .bdst = -1,
12226+ .bsrc = -1,
12227+ .len = len,
12228+ .pin = pin,
12229+ .flags = AuCpup_DTIME
12230+ };
1facf9fc 12231+
c2b27bf2
AM
12232+ sb = cpg.dentry->d_sb;
12233+ inode = cpg.dentry->d_inode;
c2b27bf2
AM
12234+ cpg.bsrc = au_fbstart(file);
12235+ err = au_test_ro(sb, cpg.bsrc, inode);
4a4d8108 12236+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) {
c2b27bf2
AM
12237+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE,
12238+ /*flags*/0);
1facf9fc 12239+ goto out;
4a4d8108 12240+ }
1facf9fc 12241+
027c5e7a 12242+ /* need to cpup or reopen */
c2b27bf2 12243+ parent = dget_parent(cpg.dentry);
4a4d8108 12244+ di_write_lock_parent(parent);
c2b27bf2
AM
12245+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12246+ cpg.bdst = err;
4a4d8108
AM
12247+ if (unlikely(err < 0))
12248+ goto out_dgrade;
12249+ err = 0;
12250+
c2b27bf2
AM
12251+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) {
12252+ err = au_cpup_dirs(cpg.dentry, cpg.bdst);
1facf9fc 12253+ if (unlikely(err))
4a4d8108
AM
12254+ goto out_dgrade;
12255+ }
12256+
c2b27bf2 12257+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108
AM
12258+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
12259+ if (unlikely(err))
12260+ goto out_dgrade;
12261+
c2b27bf2 12262+ dbstart = au_dbstart(cpg.dentry);
c1595e42 12263+ if (dbstart <= cpg.bdst)
c2b27bf2 12264+ cpg.bsrc = cpg.bdst;
027c5e7a 12265+
c2b27bf2
AM
12266+ if (dbstart <= cpg.bdst /* just reopen */
12267+ || !d_unhashed(cpg.dentry) /* copyup and reopen */
027c5e7a 12268+ ) {
392086de 12269+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0);
86dc4139 12270+ if (IS_ERR(h_file))
027c5e7a 12271+ err = PTR_ERR(h_file);
86dc4139 12272+ else {
027c5e7a 12273+ di_downgrade_lock(parent, AuLock_IR);
c2b27bf2
AM
12274+ if (dbstart > cpg.bdst)
12275+ err = au_sio_cpup_simple(&cpg);
027c5e7a
AM
12276+ if (!err)
12277+ err = au_reopen_nondir(file);
c2b27bf2 12278+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file);
027c5e7a 12279+ }
027c5e7a
AM
12280+ } else { /* copyup as wh and reopen */
12281+ /*
12282+ * since writable hfsplus branch is not supported,
12283+ * h_open_pre/post() are unnecessary.
12284+ */
c2b27bf2 12285+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin);
4a4d8108 12286+ di_downgrade_lock(parent, AuLock_IR);
4a4d8108 12287+ }
4a4d8108
AM
12288+
12289+ if (!err) {
12290+ au_pin_set_parent_lflag(pin, /*lflag*/0);
12291+ goto out_dput; /* success */
12292+ }
12293+ au_unpin(pin);
12294+ goto out_unlock;
1facf9fc 12295+
4f0767ce 12296+out_dgrade:
4a4d8108 12297+ di_downgrade_lock(parent, AuLock_IR);
4f0767ce 12298+out_unlock:
4a4d8108 12299+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12300+out_dput:
4a4d8108 12301+ dput(parent);
4f0767ce 12302+out:
1facf9fc 12303+ return err;
12304+}
12305+
4a4d8108
AM
12306+/* ---------------------------------------------------------------------- */
12307+
12308+int au_do_flush(struct file *file, fl_owner_t id,
12309+ int (*flush)(struct file *file, fl_owner_t id))
1facf9fc 12310+{
4a4d8108 12311+ int err;
1facf9fc 12312+ struct super_block *sb;
4a4d8108 12313+ struct inode *inode;
1facf9fc 12314+
c06a8ce3
AM
12315+ inode = file_inode(file);
12316+ sb = inode->i_sb;
4a4d8108
AM
12317+ si_noflush_read_lock(sb);
12318+ fi_read_lock(file);
b752ccd1 12319+ ii_read_lock_child(inode);
1facf9fc 12320+
4a4d8108
AM
12321+ err = flush(file, id);
12322+ au_cpup_attr_timesizes(inode);
1facf9fc 12323+
b752ccd1 12324+ ii_read_unlock(inode);
4a4d8108 12325+ fi_read_unlock(file);
1308ab2a 12326+ si_read_unlock(sb);
dece6358 12327+ return err;
1facf9fc 12328+}
12329+
4a4d8108
AM
12330+/* ---------------------------------------------------------------------- */
12331+
12332+static int au_file_refresh_by_inode(struct file *file, int *need_reopen)
1facf9fc 12333+{
4a4d8108 12334+ int err;
4a4d8108
AM
12335+ struct au_pin pin;
12336+ struct au_finfo *finfo;
c2b27bf2 12337+ struct dentry *parent, *hi_wh;
4a4d8108 12338+ struct inode *inode;
1facf9fc 12339+ struct super_block *sb;
c2b27bf2
AM
12340+ struct au_cp_generic cpg = {
12341+ .dentry = file->f_dentry,
12342+ .bdst = -1,
12343+ .bsrc = -1,
12344+ .len = -1,
12345+ .pin = &pin,
12346+ .flags = AuCpup_DTIME
12347+ };
1facf9fc 12348+
4a4d8108
AM
12349+ FiMustWriteLock(file);
12350+
12351+ err = 0;
12352+ finfo = au_fi(file);
c2b27bf2
AM
12353+ sb = cpg.dentry->d_sb;
12354+ inode = cpg.dentry->d_inode;
12355+ cpg.bdst = au_ibstart(inode);
12356+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry))
1308ab2a 12357+ goto out;
dece6358 12358+
c2b27bf2
AM
12359+ parent = dget_parent(cpg.dentry);
12360+ if (au_test_ro(sb, cpg.bdst, inode)) {
4a4d8108 12361+ di_read_lock_parent(parent, !AuLock_IR);
c2b27bf2
AM
12362+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry);
12363+ cpg.bdst = err;
4a4d8108
AM
12364+ di_read_unlock(parent, !AuLock_IR);
12365+ if (unlikely(err < 0))
12366+ goto out_parent;
12367+ err = 0;
1facf9fc 12368+ }
1facf9fc 12369+
4a4d8108 12370+ di_read_lock_parent(parent, AuLock_IR);
c2b27bf2 12371+ hi_wh = au_hi_wh(inode, cpg.bdst);
7f207e10
AM
12372+ if (!S_ISDIR(inode->i_mode)
12373+ && au_opt_test(au_mntflags(sb), PLINK)
4a4d8108 12374+ && au_plink_test(inode)
c2b27bf2
AM
12375+ && !d_unhashed(cpg.dentry)
12376+ && cpg.bdst < au_dbstart(cpg.dentry)) {
12377+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst);
4a4d8108
AM
12378+ if (unlikely(err))
12379+ goto out_unlock;
12380+
12381+ /* always superio. */
c2b27bf2 12382+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE,
4a4d8108 12383+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 12384+ if (!err) {
c2b27bf2 12385+ err = au_sio_cpup_simple(&cpg);
367653fa
AM
12386+ au_unpin(&pin);
12387+ }
4a4d8108
AM
12388+ } else if (hi_wh) {
12389+ /* already copied-up after unlink */
c2b27bf2 12390+ err = au_reopen_wh(file, cpg.bdst, hi_wh);
4a4d8108
AM
12391+ *need_reopen = 0;
12392+ }
1facf9fc 12393+
4f0767ce 12394+out_unlock:
4a4d8108 12395+ di_read_unlock(parent, AuLock_IR);
4f0767ce 12396+out_parent:
4a4d8108 12397+ dput(parent);
4f0767ce 12398+out:
1308ab2a 12399+ return err;
dece6358 12400+}
1facf9fc 12401+
4a4d8108 12402+static void au_do_refresh_dir(struct file *file)
dece6358 12403+{
4a4d8108
AM
12404+ aufs_bindex_t bindex, bend, new_bindex, brid;
12405+ struct au_hfile *p, tmp, *q;
12406+ struct au_finfo *finfo;
1308ab2a 12407+ struct super_block *sb;
4a4d8108 12408+ struct au_fidir *fidir;
1facf9fc 12409+
4a4d8108 12410+ FiMustWriteLock(file);
1facf9fc 12411+
4a4d8108
AM
12412+ sb = file->f_dentry->d_sb;
12413+ finfo = au_fi(file);
12414+ fidir = finfo->fi_hdir;
12415+ AuDebugOn(!fidir);
12416+ p = fidir->fd_hfile + finfo->fi_btop;
12417+ brid = p->hf_br->br_id;
12418+ bend = fidir->fd_bbot;
12419+ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) {
12420+ if (!p->hf_file)
12421+ continue;
1308ab2a 12422+
4a4d8108
AM
12423+ new_bindex = au_br_index(sb, p->hf_br->br_id);
12424+ if (new_bindex == bindex)
12425+ continue;
12426+ if (new_bindex < 0) {
12427+ au_set_h_fptr(file, bindex, NULL);
12428+ continue;
12429+ }
1308ab2a 12430+
4a4d8108
AM
12431+ /* swap two lower inode, and loop again */
12432+ q = fidir->fd_hfile + new_bindex;
12433+ tmp = *q;
12434+ *q = *p;
12435+ *p = tmp;
12436+ if (tmp.hf_file) {
12437+ bindex--;
12438+ p--;
12439+ }
12440+ }
1308ab2a 12441+
4a4d8108 12442+ p = fidir->fd_hfile;
027c5e7a 12443+ if (!au_test_mmapped(file) && !d_unlinked(file->f_dentry)) {
4a4d8108
AM
12444+ bend = au_sbend(sb);
12445+ for (finfo->fi_btop = 0; finfo->fi_btop <= bend;
12446+ finfo->fi_btop++, p++)
12447+ if (p->hf_file) {
c06a8ce3 12448+ if (file_inode(p->hf_file))
4a4d8108 12449+ break;
c1595e42 12450+ au_hfput(p, file);
4a4d8108
AM
12451+ }
12452+ } else {
12453+ bend = au_br_index(sb, brid);
12454+ for (finfo->fi_btop = 0; finfo->fi_btop < bend;
12455+ finfo->fi_btop++, p++)
12456+ if (p->hf_file)
12457+ au_hfput(p, file);
12458+ bend = au_sbend(sb);
12459+ }
1308ab2a 12460+
4a4d8108
AM
12461+ p = fidir->fd_hfile + bend;
12462+ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop;
12463+ fidir->fd_bbot--, p--)
12464+ if (p->hf_file) {
c06a8ce3 12465+ if (file_inode(p->hf_file))
4a4d8108 12466+ break;
c1595e42 12467+ au_hfput(p, file);
4a4d8108
AM
12468+ }
12469+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
1308ab2a 12470+}
12471+
4a4d8108
AM
12472+/*
12473+ * after branch manipulating, refresh the file.
12474+ */
12475+static int refresh_file(struct file *file, int (*reopen)(struct file *file))
1facf9fc 12476+{
4a4d8108
AM
12477+ int err, need_reopen;
12478+ aufs_bindex_t bend, bindex;
12479+ struct dentry *dentry;
1308ab2a 12480+ struct au_finfo *finfo;
4a4d8108 12481+ struct au_hfile *hfile;
1facf9fc 12482+
4a4d8108 12483+ dentry = file->f_dentry;
1308ab2a 12484+ finfo = au_fi(file);
4a4d8108
AM
12485+ if (!finfo->fi_hdir) {
12486+ hfile = &finfo->fi_htop;
12487+ AuDebugOn(!hfile->hf_file);
12488+ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id);
12489+ AuDebugOn(bindex < 0);
12490+ if (bindex != finfo->fi_btop)
12491+ au_set_fbstart(file, bindex);
12492+ } else {
12493+ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1);
12494+ if (unlikely(err))
12495+ goto out;
12496+ au_do_refresh_dir(file);
12497+ }
1facf9fc 12498+
4a4d8108
AM
12499+ err = 0;
12500+ need_reopen = 1;
12501+ if (!au_test_mmapped(file))
12502+ err = au_file_refresh_by_inode(file, &need_reopen);
027c5e7a 12503+ if (!err && need_reopen && !d_unlinked(dentry))
4a4d8108
AM
12504+ err = reopen(file);
12505+ if (!err) {
12506+ au_update_figen(file);
12507+ goto out; /* success */
12508+ }
12509+
12510+ /* error, close all lower files */
12511+ if (finfo->fi_hdir) {
12512+ bend = au_fbend_dir(file);
12513+ for (bindex = au_fbstart(file); bindex <= bend; bindex++)
12514+ au_set_h_fptr(file, bindex, NULL);
12515+ }
1facf9fc 12516+
4f0767ce 12517+out:
1facf9fc 12518+ return err;
12519+}
12520+
4a4d8108
AM
12521+/* common function to regular file and dir */
12522+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12523+ int wlock)
dece6358 12524+{
1308ab2a 12525+ int err;
4a4d8108
AM
12526+ unsigned int sigen, figen;
12527+ aufs_bindex_t bstart;
12528+ unsigned char pseudo_link;
12529+ struct dentry *dentry;
12530+ struct inode *inode;
1facf9fc 12531+
4a4d8108
AM
12532+ err = 0;
12533+ dentry = file->f_dentry;
12534+ inode = dentry->d_inode;
4a4d8108
AM
12535+ sigen = au_sigen(dentry->d_sb);
12536+ fi_write_lock(file);
12537+ figen = au_figen(file);
12538+ di_write_lock_child(dentry);
12539+ bstart = au_dbstart(dentry);
12540+ pseudo_link = (bstart != au_ibstart(inode));
12541+ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) {
12542+ if (!wlock) {
12543+ di_downgrade_lock(dentry, AuLock_IR);
12544+ fi_downgrade_lock(file);
12545+ }
12546+ goto out; /* success */
12547+ }
dece6358 12548+
4a4d8108 12549+ AuDbg("sigen %d, figen %d\n", sigen, figen);
027c5e7a 12550+ if (au_digen_test(dentry, sigen)) {
4a4d8108 12551+ err = au_reval_dpath(dentry, sigen);
027c5e7a 12552+ AuDebugOn(!err && au_digen_test(dentry, sigen));
4a4d8108 12553+ }
dece6358 12554+
027c5e7a
AM
12555+ if (!err)
12556+ err = refresh_file(file, reopen);
4a4d8108
AM
12557+ if (!err) {
12558+ if (!wlock) {
12559+ di_downgrade_lock(dentry, AuLock_IR);
12560+ fi_downgrade_lock(file);
12561+ }
12562+ } else {
12563+ di_write_unlock(dentry);
12564+ fi_write_unlock(file);
12565+ }
1facf9fc 12566+
4f0767ce 12567+out:
1308ab2a 12568+ return err;
12569+}
1facf9fc 12570+
4a4d8108
AM
12571+/* ---------------------------------------------------------------------- */
12572+
12573+/* cf. aufs_nopage() */
12574+/* for madvise(2) */
12575+static int aufs_readpage(struct file *file __maybe_unused, struct page *page)
1308ab2a 12576+{
4a4d8108
AM
12577+ unlock_page(page);
12578+ return 0;
12579+}
1facf9fc 12580+
4a4d8108
AM
12581+/* it will never be called, but necessary to support O_DIRECT */
12582+static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb,
076b876e 12583+ struct iov_iter *iter, loff_t offset)
4a4d8108 12584+{ BUG(); return 0; }
1facf9fc 12585+
4a4d8108
AM
12586+/*
12587+ * it will never be called, but madvise and fadvise behaves differently
12588+ * when get_xip_mem is defined
12589+ */
12590+static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff,
12591+ int create, void **kmem, unsigned long *pfn)
12592+{ BUG(); return 0; }
1facf9fc 12593+
4a4d8108
AM
12594+/* they will never be called. */
12595+#ifdef CONFIG_AUFS_DEBUG
12596+static int aufs_write_begin(struct file *file, struct address_space *mapping,
12597+ loff_t pos, unsigned len, unsigned flags,
12598+ struct page **pagep, void **fsdata)
12599+{ AuUnsupport(); return 0; }
12600+static int aufs_write_end(struct file *file, struct address_space *mapping,
12601+ loff_t pos, unsigned len, unsigned copied,
12602+ struct page *page, void *fsdata)
12603+{ AuUnsupport(); return 0; }
12604+static int aufs_writepage(struct page *page, struct writeback_control *wbc)
12605+{ AuUnsupport(); return 0; }
1308ab2a 12606+
4a4d8108
AM
12607+static int aufs_set_page_dirty(struct page *page)
12608+{ AuUnsupport(); return 0; }
392086de
AM
12609+static void aufs_invalidatepage(struct page *page, unsigned int offset,
12610+ unsigned int length)
4a4d8108
AM
12611+{ AuUnsupport(); }
12612+static int aufs_releasepage(struct page *page, gfp_t gfp)
12613+{ AuUnsupport(); return 0; }
12614+static int aufs_migratepage(struct address_space *mapping, struct page *newpage,
7eafdf33 12615+ struct page *page, enum migrate_mode mode)
4a4d8108
AM
12616+{ AuUnsupport(); return 0; }
12617+static int aufs_launder_page(struct page *page)
12618+{ AuUnsupport(); return 0; }
12619+static int aufs_is_partially_uptodate(struct page *page,
38d290e6
JR
12620+ unsigned long from,
12621+ unsigned long count)
4a4d8108 12622+{ AuUnsupport(); return 0; }
392086de
AM
12623+static void aufs_is_dirty_writeback(struct page *page, bool *dirty,
12624+ bool *writeback)
12625+{ AuUnsupport(); }
4a4d8108
AM
12626+static int aufs_error_remove_page(struct address_space *mapping,
12627+ struct page *page)
12628+{ AuUnsupport(); return 0; }
b4510431
AM
12629+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file,
12630+ sector_t *span)
12631+{ AuUnsupport(); return 0; }
12632+static void aufs_swap_deactivate(struct file *file)
12633+{ AuUnsupport(); }
4a4d8108
AM
12634+#endif /* CONFIG_AUFS_DEBUG */
12635+
12636+const struct address_space_operations aufs_aop = {
12637+ .readpage = aufs_readpage,
12638+ .direct_IO = aufs_direct_IO,
12639+ .get_xip_mem = aufs_get_xip_mem,
12640+#ifdef CONFIG_AUFS_DEBUG
12641+ .writepage = aufs_writepage,
4a4d8108
AM
12642+ /* no writepages, because of writepage */
12643+ .set_page_dirty = aufs_set_page_dirty,
12644+ /* no readpages, because of readpage */
12645+ .write_begin = aufs_write_begin,
12646+ .write_end = aufs_write_end,
12647+ /* no bmap, no block device */
12648+ .invalidatepage = aufs_invalidatepage,
12649+ .releasepage = aufs_releasepage,
12650+ .migratepage = aufs_migratepage,
12651+ .launder_page = aufs_launder_page,
12652+ .is_partially_uptodate = aufs_is_partially_uptodate,
392086de 12653+ .is_dirty_writeback = aufs_is_dirty_writeback,
b4510431
AM
12654+ .error_remove_page = aufs_error_remove_page,
12655+ .swap_activate = aufs_swap_activate,
12656+ .swap_deactivate = aufs_swap_deactivate
4a4d8108 12657+#endif /* CONFIG_AUFS_DEBUG */
dece6358 12658+};
7f207e10
AM
12659diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
12660--- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
12661+++ linux/fs/aufs/file.h 2015-01-25 13:00:38.631047076 +0100
12662@@ -0,0 +1,284 @@
4a4d8108 12663+/*
523b37e3 12664+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
12665+ *
12666+ * This program, aufs is free software; you can redistribute it and/or modify
12667+ * it under the terms of the GNU General Public License as published by
12668+ * the Free Software Foundation; either version 2 of the License, or
12669+ * (at your option) any later version.
12670+ *
12671+ * This program is distributed in the hope that it will be useful,
12672+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12673+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12674+ * GNU General Public License for more details.
12675+ *
12676+ * You should have received a copy of the GNU General Public License
523b37e3 12677+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12678+ */
1facf9fc 12679+
4a4d8108
AM
12680+/*
12681+ * file operations
12682+ */
1facf9fc 12683+
4a4d8108
AM
12684+#ifndef __AUFS_FILE_H__
12685+#define __AUFS_FILE_H__
1facf9fc 12686+
4a4d8108 12687+#ifdef __KERNEL__
1facf9fc 12688+
2cbb1c4b 12689+#include <linux/file.h>
4a4d8108
AM
12690+#include <linux/fs.h>
12691+#include <linux/poll.h>
4a4d8108 12692+#include "rwsem.h"
1facf9fc 12693+
4a4d8108
AM
12694+struct au_branch;
12695+struct au_hfile {
12696+ struct file *hf_file;
12697+ struct au_branch *hf_br;
12698+};
1facf9fc 12699+
4a4d8108
AM
12700+struct au_vdir;
12701+struct au_fidir {
12702+ aufs_bindex_t fd_bbot;
12703+ aufs_bindex_t fd_nent;
12704+ struct au_vdir *fd_vdir_cache;
12705+ struct au_hfile fd_hfile[];
12706+};
1facf9fc 12707+
4a4d8108 12708+static inline int au_fidir_sz(int nent)
dece6358 12709+{
4f0767ce
JR
12710+ AuDebugOn(nent < 0);
12711+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent;
4a4d8108 12712+}
1facf9fc 12713+
4a4d8108
AM
12714+struct au_finfo {
12715+ atomic_t fi_generation;
dece6358 12716+
4a4d8108
AM
12717+ struct au_rwsem fi_rwsem;
12718+ aufs_bindex_t fi_btop;
12719+
12720+ /* do not union them */
12721+ struct { /* for non-dir */
12722+ struct au_hfile fi_htop;
2cbb1c4b 12723+ atomic_t fi_mmapped;
4a4d8108
AM
12724+ };
12725+ struct au_fidir *fi_hdir; /* for dir only */
523b37e3
AM
12726+
12727+ struct hlist_node fi_hlist;
12728+ struct file *fi_file; /* very ugly */
4a4d8108 12729+} ____cacheline_aligned_in_smp;
1facf9fc 12730+
4a4d8108 12731+/* ---------------------------------------------------------------------- */
1facf9fc 12732+
4a4d8108
AM
12733+/* file.c */
12734+extern const struct address_space_operations aufs_aop;
12735+unsigned int au_file_roflags(unsigned int flags);
12736+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
392086de 12737+ struct file *file, int force_wr);
4a4d8108
AM
12738+int au_do_open(struct file *file, int (*open)(struct file *file, int flags),
12739+ struct au_fidir *fidir);
12740+int au_reopen_nondir(struct file *file);
12741+struct au_pin;
12742+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin);
12743+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file),
12744+ int wlock);
12745+int au_do_flush(struct file *file, fl_owner_t id,
12746+ int (*flush)(struct file *file, fl_owner_t id));
1facf9fc 12747+
4a4d8108
AM
12748+/* poll.c */
12749+#ifdef CONFIG_AUFS_POLL
12750+unsigned int aufs_poll(struct file *file, poll_table *wait);
12751+#endif
1facf9fc 12752+
4a4d8108
AM
12753+#ifdef CONFIG_AUFS_BR_HFSPLUS
12754+/* hfsplus.c */
392086de
AM
12755+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
12756+ int force_wr);
4a4d8108
AM
12757+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
12758+ struct file *h_file);
12759+#else
c1595e42
JR
12760+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry,
12761+ aufs_bindex_t bindex, int force_wr)
4a4d8108
AM
12762+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex,
12763+ struct file *h_file);
12764+#endif
1facf9fc 12765+
4a4d8108
AM
12766+/* f_op.c */
12767+extern const struct file_operations aufs_file_fop;
4a4d8108
AM
12768+int au_do_open_nondir(struct file *file, int flags);
12769+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file);
12770+
4a4d8108
AM
12771+/* finfo.c */
12772+void au_hfput(struct au_hfile *hf, struct file *file);
12773+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
12774+ struct file *h_file);
1facf9fc 12775+
4a4d8108 12776+void au_update_figen(struct file *file);
4a4d8108
AM
12777+struct au_fidir *au_fidir_alloc(struct super_block *sb);
12778+int au_fidir_realloc(struct au_finfo *finfo, int nbr);
1facf9fc 12779+
4a4d8108
AM
12780+void au_fi_init_once(void *_fi);
12781+void au_finfo_fin(struct file *file);
12782+int au_finfo_init(struct file *file, struct au_fidir *fidir);
1facf9fc 12783+
4a4d8108
AM
12784+/* ioctl.c */
12785+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg);
b752ccd1
AM
12786+#ifdef CONFIG_COMPAT
12787+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
12788+ unsigned long arg);
c2b27bf2
AM
12789+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
12790+ unsigned long arg);
b752ccd1 12791+#endif
1facf9fc 12792+
4a4d8108 12793+/* ---------------------------------------------------------------------- */
1facf9fc 12794+
4a4d8108
AM
12795+static inline struct au_finfo *au_fi(struct file *file)
12796+{
38d290e6 12797+ return file->private_data;
4a4d8108 12798+}
1facf9fc 12799+
4a4d8108 12800+/* ---------------------------------------------------------------------- */
1facf9fc 12801+
4a4d8108
AM
12802+/*
12803+ * fi_read_lock, fi_write_lock,
12804+ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock
12805+ */
12806+AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem);
1308ab2a 12807+
4a4d8108
AM
12808+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem)
12809+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem)
12810+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem)
1facf9fc 12811+
1308ab2a 12812+/* ---------------------------------------------------------------------- */
12813+
4a4d8108
AM
12814+/* todo: hard/soft set? */
12815+static inline aufs_bindex_t au_fbstart(struct file *file)
dece6358 12816+{
4a4d8108
AM
12817+ FiMustAnyLock(file);
12818+ return au_fi(file)->fi_btop;
12819+}
dece6358 12820+
4a4d8108
AM
12821+static inline aufs_bindex_t au_fbend_dir(struct file *file)
12822+{
12823+ FiMustAnyLock(file);
12824+ AuDebugOn(!au_fi(file)->fi_hdir);
12825+ return au_fi(file)->fi_hdir->fd_bbot;
12826+}
1facf9fc 12827+
4a4d8108
AM
12828+static inline struct au_vdir *au_fvdir_cache(struct file *file)
12829+{
12830+ FiMustAnyLock(file);
12831+ AuDebugOn(!au_fi(file)->fi_hdir);
12832+ return au_fi(file)->fi_hdir->fd_vdir_cache;
12833+}
1facf9fc 12834+
4a4d8108
AM
12835+static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex)
12836+{
12837+ FiMustWriteLock(file);
12838+ au_fi(file)->fi_btop = bindex;
12839+}
1facf9fc 12840+
4a4d8108
AM
12841+static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex)
12842+{
12843+ FiMustWriteLock(file);
12844+ AuDebugOn(!au_fi(file)->fi_hdir);
12845+ au_fi(file)->fi_hdir->fd_bbot = bindex;
12846+}
1308ab2a 12847+
4a4d8108
AM
12848+static inline void au_set_fvdir_cache(struct file *file,
12849+ struct au_vdir *vdir_cache)
12850+{
12851+ FiMustWriteLock(file);
12852+ AuDebugOn(!au_fi(file)->fi_hdir);
12853+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache;
12854+}
dece6358 12855+
4a4d8108
AM
12856+static inline struct file *au_hf_top(struct file *file)
12857+{
12858+ FiMustAnyLock(file);
12859+ AuDebugOn(au_fi(file)->fi_hdir);
12860+ return au_fi(file)->fi_htop.hf_file;
12861+}
1facf9fc 12862+
4a4d8108
AM
12863+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex)
12864+{
12865+ FiMustAnyLock(file);
12866+ AuDebugOn(!au_fi(file)->fi_hdir);
12867+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file;
dece6358
AM
12868+}
12869+
4a4d8108
AM
12870+/* todo: memory barrier? */
12871+static inline unsigned int au_figen(struct file *f)
dece6358 12872+{
4a4d8108
AM
12873+ return atomic_read(&au_fi(f)->fi_generation);
12874+}
dece6358 12875+
2cbb1c4b
JR
12876+static inline void au_set_mmapped(struct file *f)
12877+{
12878+ if (atomic_inc_return(&au_fi(f)->fi_mmapped))
12879+ return;
0c3ec466 12880+ pr_warn("fi_mmapped wrapped around\n");
2cbb1c4b
JR
12881+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped))
12882+ ;
12883+}
12884+
12885+static inline void au_unset_mmapped(struct file *f)
12886+{
12887+ atomic_dec(&au_fi(f)->fi_mmapped);
12888+}
12889+
4a4d8108
AM
12890+static inline int au_test_mmapped(struct file *f)
12891+{
2cbb1c4b
JR
12892+ return atomic_read(&au_fi(f)->fi_mmapped);
12893+}
12894+
12895+/* customize vma->vm_file */
12896+
12897+static inline void au_do_vm_file_reset(struct vm_area_struct *vma,
12898+ struct file *file)
12899+{
53392da6
AM
12900+ struct file *f;
12901+
12902+ f = vma->vm_file;
2cbb1c4b
JR
12903+ get_file(file);
12904+ vma->vm_file = file;
53392da6 12905+ fput(f);
2cbb1c4b
JR
12906+}
12907+
12908+#ifdef CONFIG_MMU
12909+#define AuDbgVmRegion(file, vma) do {} while (0)
12910+
12911+static inline void au_vm_file_reset(struct vm_area_struct *vma,
12912+ struct file *file)
12913+{
12914+ au_do_vm_file_reset(vma, file);
12915+}
12916+#else
12917+#define AuDbgVmRegion(file, vma) \
12918+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file))
12919+
12920+static inline void au_vm_file_reset(struct vm_area_struct *vma,
12921+ struct file *file)
12922+{
53392da6
AM
12923+ struct file *f;
12924+
2cbb1c4b 12925+ au_do_vm_file_reset(vma, file);
53392da6 12926+ f = vma->vm_region->vm_file;
2cbb1c4b
JR
12927+ get_file(file);
12928+ vma->vm_region->vm_file = file;
53392da6 12929+ fput(f);
2cbb1c4b
JR
12930+}
12931+#endif /* CONFIG_MMU */
12932+
12933+/* handle vma->vm_prfile */
fb47a38f 12934+static inline void au_vm_prfile_set(struct vm_area_struct *vma,
2cbb1c4b
JR
12935+ struct file *file)
12936+{
2cbb1c4b
JR
12937+ get_file(file);
12938+ vma->vm_prfile = file;
12939+#ifndef CONFIG_MMU
12940+ get_file(file);
12941+ vma->vm_region->vm_prfile = file;
12942+#endif
fb47a38f 12943+}
1308ab2a 12944+
4a4d8108
AM
12945+#endif /* __KERNEL__ */
12946+#endif /* __AUFS_FILE_H__ */
7f207e10
AM
12947diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
12948--- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 12949+++ linux/fs/aufs/finfo.c 2015-01-25 13:00:38.631047076 +0100
523b37e3 12950@@ -0,0 +1,156 @@
4a4d8108 12951+/*
523b37e3 12952+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
12953+ *
12954+ * This program, aufs is free software; you can redistribute it and/or modify
12955+ * it under the terms of the GNU General Public License as published by
12956+ * the Free Software Foundation; either version 2 of the License, or
12957+ * (at your option) any later version.
12958+ *
12959+ * This program is distributed in the hope that it will be useful,
12960+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12961+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12962+ * GNU General Public License for more details.
12963+ *
12964+ * You should have received a copy of the GNU General Public License
523b37e3 12965+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 12966+ */
1308ab2a 12967+
4a4d8108
AM
12968+/*
12969+ * file private data
12970+ */
1facf9fc 12971+
4a4d8108 12972+#include "aufs.h"
1facf9fc 12973+
4a4d8108
AM
12974+void au_hfput(struct au_hfile *hf, struct file *file)
12975+{
12976+ /* todo: direct access f_flags */
2cbb1c4b 12977+ if (vfsub_file_flags(file) & __FMODE_EXEC)
4a4d8108
AM
12978+ allow_write_access(hf->hf_file);
12979+ fput(hf->hf_file);
12980+ hf->hf_file = NULL;
e49829fe 12981+ atomic_dec(&hf->hf_br->br_count);
4a4d8108
AM
12982+ hf->hf_br = NULL;
12983+}
1facf9fc 12984+
4a4d8108
AM
12985+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
12986+{
12987+ struct au_finfo *finfo = au_fi(file);
12988+ struct au_hfile *hf;
12989+ struct au_fidir *fidir;
12990+
12991+ fidir = finfo->fi_hdir;
12992+ if (!fidir) {
12993+ AuDebugOn(finfo->fi_btop != bindex);
12994+ hf = &finfo->fi_htop;
12995+ } else
12996+ hf = fidir->fd_hfile + bindex;
12997+
12998+ if (hf && hf->hf_file)
12999+ au_hfput(hf, file);
13000+ if (val) {
13001+ FiMustWriteLock(file);
13002+ hf->hf_file = val;
13003+ hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
1308ab2a 13004+ }
4a4d8108 13005+}
1facf9fc 13006+
4a4d8108
AM
13007+void au_update_figen(struct file *file)
13008+{
13009+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry));
13010+ /* smp_mb(); */ /* atomic_set */
1facf9fc 13011+}
13012+
4a4d8108
AM
13013+/* ---------------------------------------------------------------------- */
13014+
4a4d8108
AM
13015+struct au_fidir *au_fidir_alloc(struct super_block *sb)
13016+{
13017+ struct au_fidir *fidir;
13018+ int nbr;
13019+
13020+ nbr = au_sbend(sb) + 1;
13021+ if (nbr < 2)
13022+ nbr = 2; /* initial allocate for 2 branches */
13023+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS);
13024+ if (fidir) {
13025+ fidir->fd_bbot = -1;
13026+ fidir->fd_nent = nbr;
13027+ fidir->fd_vdir_cache = NULL;
13028+ }
13029+
13030+ return fidir;
13031+}
13032+
13033+int au_fidir_realloc(struct au_finfo *finfo, int nbr)
13034+{
13035+ int err;
13036+ struct au_fidir *fidir, *p;
13037+
13038+ AuRwMustWriteLock(&finfo->fi_rwsem);
13039+ fidir = finfo->fi_hdir;
13040+ AuDebugOn(!fidir);
13041+
13042+ err = -ENOMEM;
13043+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr),
13044+ GFP_NOFS);
13045+ if (p) {
13046+ p->fd_nent = nbr;
13047+ finfo->fi_hdir = p;
13048+ err = 0;
13049+ }
1facf9fc 13050+
dece6358 13051+ return err;
1facf9fc 13052+}
1308ab2a 13053+
13054+/* ---------------------------------------------------------------------- */
13055+
4a4d8108 13056+void au_finfo_fin(struct file *file)
1308ab2a 13057+{
4a4d8108
AM
13058+ struct au_finfo *finfo;
13059+
7f207e10
AM
13060+ au_nfiles_dec(file->f_dentry->d_sb);
13061+
4a4d8108
AM
13062+ finfo = au_fi(file);
13063+ AuDebugOn(finfo->fi_hdir);
13064+ AuRwDestroy(&finfo->fi_rwsem);
13065+ au_cache_free_finfo(finfo);
1308ab2a 13066+}
1308ab2a 13067+
e49829fe 13068+void au_fi_init_once(void *_finfo)
4a4d8108 13069+{
e49829fe 13070+ struct au_finfo *finfo = _finfo;
2cbb1c4b 13071+ static struct lock_class_key aufs_fi;
1308ab2a 13072+
e49829fe
JR
13073+ au_rw_init(&finfo->fi_rwsem);
13074+ au_rw_class(&finfo->fi_rwsem, &aufs_fi);
4a4d8108 13075+}
1308ab2a 13076+
4a4d8108
AM
13077+int au_finfo_init(struct file *file, struct au_fidir *fidir)
13078+{
1716fcea 13079+ int err;
4a4d8108
AM
13080+ struct au_finfo *finfo;
13081+ struct dentry *dentry;
13082+
13083+ err = -ENOMEM;
13084+ dentry = file->f_dentry;
13085+ finfo = au_cache_alloc_finfo();
13086+ if (unlikely(!finfo))
13087+ goto out;
13088+
13089+ err = 0;
7f207e10 13090+ au_nfiles_inc(dentry->d_sb);
1716fcea
AM
13091+ /* verbose coding for lock class name */
13092+ if (!fidir)
13093+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO);
13094+ else
13095+ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO);
4a4d8108
AM
13096+ au_rw_write_lock(&finfo->fi_rwsem);
13097+ finfo->fi_btop = -1;
13098+ finfo->fi_hdir = fidir;
13099+ atomic_set(&finfo->fi_generation, au_digen(dentry));
13100+ /* smp_mb(); */ /* atomic_set */
13101+
13102+ file->private_data = finfo;
13103+
13104+out:
13105+ return err;
13106+}
7f207e10
AM
13107diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
13108--- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 13109+++ linux/fs/aufs/f_op.c 2015-01-25 13:00:38.631047076 +0100
076b876e 13110@@ -0,0 +1,813 @@
dece6358 13111+/*
523b37e3 13112+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
13113+ *
13114+ * This program, aufs is free software; you can redistribute it and/or modify
13115+ * it under the terms of the GNU General Public License as published by
13116+ * the Free Software Foundation; either version 2 of the License, or
13117+ * (at your option) any later version.
13118+ *
13119+ * This program is distributed in the hope that it will be useful,
13120+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13121+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13122+ * GNU General Public License for more details.
13123+ *
13124+ * You should have received a copy of the GNU General Public License
523b37e3 13125+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 13126+ */
1facf9fc 13127+
13128+/*
4a4d8108 13129+ * file and vm operations
1facf9fc 13130+ */
dece6358 13131+
86dc4139 13132+#include <linux/aio.h>
4a4d8108
AM
13133+#include <linux/fs_stack.h>
13134+#include <linux/mman.h>
4a4d8108 13135+#include <linux/security.h>
dece6358
AM
13136+#include "aufs.h"
13137+
4a4d8108 13138+int au_do_open_nondir(struct file *file, int flags)
1facf9fc 13139+{
4a4d8108
AM
13140+ int err;
13141+ aufs_bindex_t bindex;
13142+ struct file *h_file;
13143+ struct dentry *dentry;
13144+ struct au_finfo *finfo;
38d290e6 13145+ struct inode *h_inode;
4a4d8108
AM
13146+
13147+ FiMustWriteLock(file);
13148+
523b37e3 13149+ err = 0;
4a4d8108
AM
13150+ dentry = file->f_dentry;
13151+ finfo = au_fi(file);
13152+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop));
2cbb1c4b 13153+ atomic_set(&finfo->fi_mmapped, 0);
4a4d8108 13154+ bindex = au_dbstart(dentry);
392086de 13155+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
4a4d8108
AM
13156+ if (IS_ERR(h_file))
13157+ err = PTR_ERR(h_file);
13158+ else {
38d290e6
JR
13159+ if ((flags & __O_TMPFILE)
13160+ && !(flags & O_EXCL)) {
13161+ h_inode = file_inode(h_file);
13162+ spin_lock(&h_inode->i_lock);
13163+ h_inode->i_state |= I_LINKABLE;
13164+ spin_unlock(&h_inode->i_lock);
13165+ }
4a4d8108
AM
13166+ au_set_fbstart(file, bindex);
13167+ au_set_h_fptr(file, bindex, h_file);
13168+ au_update_figen(file);
13169+ /* todo: necessary? */
13170+ /* file->f_ra = h_file->f_ra; */
13171+ }
027c5e7a 13172+
4a4d8108 13173+ return err;
1facf9fc 13174+}
13175+
4a4d8108
AM
13176+static int aufs_open_nondir(struct inode *inode __maybe_unused,
13177+ struct file *file)
1facf9fc 13178+{
4a4d8108 13179+ int err;
1308ab2a 13180+ struct super_block *sb;
1facf9fc 13181+
523b37e3
AM
13182+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n",
13183+ file, vfsub_file_flags(file), file->f_mode);
1facf9fc 13184+
4a4d8108
AM
13185+ sb = file->f_dentry->d_sb;
13186+ si_read_lock(sb, AuLock_FLUSH);
13187+ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL);
13188+ si_read_unlock(sb);
13189+ return err;
13190+}
1facf9fc 13191+
4a4d8108
AM
13192+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file)
13193+{
13194+ struct au_finfo *finfo;
13195+ aufs_bindex_t bindex;
1facf9fc 13196+
4a4d8108 13197+ finfo = au_fi(file);
523b37e3 13198+ au_sphl_del(&finfo->fi_hlist, &au_sbi(file->f_dentry->d_sb)->si_files);
4a4d8108 13199+ bindex = finfo->fi_btop;
b4510431 13200+ if (bindex >= 0)
4a4d8108 13201+ au_set_h_fptr(file, bindex, NULL);
7f207e10 13202+
4a4d8108
AM
13203+ au_finfo_fin(file);
13204+ return 0;
1facf9fc 13205+}
13206+
4a4d8108
AM
13207+/* ---------------------------------------------------------------------- */
13208+
13209+static int au_do_flush_nondir(struct file *file, fl_owner_t id)
dece6358 13210+{
1308ab2a 13211+ int err;
4a4d8108
AM
13212+ struct file *h_file;
13213+
13214+ err = 0;
13215+ h_file = au_hf_top(file);
13216+ if (h_file)
13217+ err = vfsub_flush(h_file, id);
13218+ return err;
13219+}
13220+
13221+static int aufs_flush_nondir(struct file *file, fl_owner_t id)
13222+{
13223+ return au_do_flush(file, id, au_do_flush_nondir);
13224+}
13225+
13226+/* ---------------------------------------------------------------------- */
9dbd164d
AM
13227+/*
13228+ * read and write functions acquire [fdi]_rwsem once, but release before
13229+ * mmap_sem. This is because to stop a race condition between mmap(2).
13230+ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping
13231+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in
13232+ * read functions after [fdi]_rwsem are released, but it should be harmless.
13233+ */
4a4d8108
AM
13234+
13235+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count,
13236+ loff_t *ppos)
13237+{
13238+ ssize_t err;
dece6358 13239+ struct dentry *dentry;
4a4d8108 13240+ struct file *h_file;
dece6358 13241+ struct super_block *sb;
1facf9fc 13242+
dece6358
AM
13243+ dentry = file->f_dentry;
13244+ sb = dentry->d_sb;
e49829fe 13245+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108 13246+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
dece6358
AM
13247+ if (unlikely(err))
13248+ goto out;
1facf9fc 13249+
4a4d8108 13250+ h_file = au_hf_top(file);
9dbd164d
AM
13251+ get_file(h_file);
13252+ di_read_unlock(dentry, AuLock_IR);
13253+ fi_read_unlock(file);
13254+
13255+ /* filedata may be obsoleted by concurrent copyup, but no problem */
4a4d8108
AM
13256+ err = vfsub_read_u(h_file, buf, count, ppos);
13257+ /* todo: necessary? */
13258+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13259+ /* update without lock, I don't think it a problem */
c06a8ce3 13260+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13261+ fput(h_file);
1308ab2a 13262+
4f0767ce 13263+out:
dece6358
AM
13264+ si_read_unlock(sb);
13265+ return err;
13266+}
1facf9fc 13267+
e49829fe
JR
13268+/*
13269+ * todo: very ugly
13270+ * it locks both of i_mutex and si_rwsem for read in safe.
13271+ * if the plink maintenance mode continues forever (that is the problem),
13272+ * may loop forever.
13273+ */
13274+static void au_mtx_and_read_lock(struct inode *inode)
13275+{
13276+ int err;
13277+ struct super_block *sb = inode->i_sb;
13278+
13279+ while (1) {
13280+ mutex_lock(&inode->i_mutex);
13281+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13282+ if (!err)
13283+ break;
13284+ mutex_unlock(&inode->i_mutex);
13285+ si_read_lock(sb, AuLock_NOPLMW);
13286+ si_read_unlock(sb);
13287+ }
13288+}
13289+
4a4d8108
AM
13290+static ssize_t aufs_write(struct file *file, const char __user *ubuf,
13291+ size_t count, loff_t *ppos)
dece6358 13292+{
4a4d8108 13293+ ssize_t err;
076b876e
AM
13294+ blkcnt_t blks;
13295+ aufs_bindex_t bstart;
4a4d8108 13296+ struct au_pin pin;
dece6358 13297+ struct dentry *dentry;
076b876e 13298+ struct inode *inode, *h_inode;
9dbd164d 13299+ struct super_block *sb;
4a4d8108
AM
13300+ struct file *h_file;
13301+ char __user *buf = (char __user *)ubuf;
1facf9fc 13302+
dece6358 13303+ dentry = file->f_dentry;
9dbd164d 13304+ sb = dentry->d_sb;
4a4d8108 13305+ inode = dentry->d_inode;
e49829fe 13306+ au_mtx_and_read_lock(inode);
1facf9fc 13307+
4a4d8108
AM
13308+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13309+ if (unlikely(err))
13310+ goto out;
1facf9fc 13311+
4a4d8108
AM
13312+ err = au_ready_to_write(file, -1, &pin);
13313+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13314+ if (unlikely(err)) {
13315+ di_read_unlock(dentry, AuLock_IR);
13316+ fi_write_unlock(file);
13317+ goto out;
13318+ }
1facf9fc 13319+
076b876e 13320+ bstart = au_fbstart(file);
4a4d8108 13321+ h_file = au_hf_top(file);
9dbd164d 13322+ get_file(h_file);
c1595e42 13323+ h_inode = file_inode(h_file);
076b876e 13324+ blks = h_inode->i_blocks;
4a4d8108 13325+ au_unpin(&pin);
9dbd164d
AM
13326+ di_read_unlock(dentry, AuLock_IR);
13327+ fi_write_unlock(file);
13328+
4a4d8108 13329+ err = vfsub_write_u(h_file, buf, count, ppos);
9dbd164d 13330+ ii_write_lock_child(inode);
4a4d8108 13331+ au_cpup_attr_timesizes(inode);
c06a8ce3 13332+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13333+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13334+ if (err > 0)
13335+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13336+ ii_write_unlock(inode);
13337+ fput(h_file);
1facf9fc 13338+
4f0767ce 13339+out:
9dbd164d 13340+ si_read_unlock(sb);
4a4d8108 13341+ mutex_unlock(&inode->i_mutex);
dece6358
AM
13342+ return err;
13343+}
1facf9fc 13344+
076b876e
AM
13345+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio,
13346+ struct iov_iter *iov_iter)
dece6358 13347+{
4a4d8108
AM
13348+ ssize_t err;
13349+ struct file *file;
076b876e
AM
13350+ ssize_t (*iter)(struct kiocb *, struct iov_iter *);
13351+ ssize_t (*aio)(struct kiocb *, const struct iovec *, unsigned long,
13352+ loff_t);
1facf9fc 13353+
4a4d8108
AM
13354+ err = security_file_permission(h_file, rw);
13355+ if (unlikely(err))
13356+ goto out;
1facf9fc 13357+
4a4d8108 13358+ err = -ENOSYS;
076b876e
AM
13359+ iter = NULL;
13360+ aio = NULL;
13361+ if (rw == MAY_READ) {
13362+ iter = h_file->f_op->read_iter;
13363+ aio = h_file->f_op->aio_read;
13364+ } else if (rw == MAY_WRITE) {
13365+ iter = h_file->f_op->write_iter;
13366+ aio = h_file->f_op->aio_write;
13367+ }
13368+
13369+ file = kio->ki_filp;
13370+ kio->ki_filp = h_file;
13371+ if (iter) {
2cbb1c4b 13372+ lockdep_off();
076b876e
AM
13373+ err = iter(kio, iov_iter);
13374+ lockdep_on();
13375+ } else if (aio) {
13376+ lockdep_off();
13377+ err = aio(kio, iov_iter->iov, iov_iter->nr_segs, kio->ki_pos);
2cbb1c4b 13378+ lockdep_on();
4a4d8108
AM
13379+ } else
13380+ /* currently there is no such fs */
13381+ WARN_ON_ONCE(1);
076b876e 13382+ kio->ki_filp = file;
1facf9fc 13383+
4f0767ce 13384+out:
dece6358
AM
13385+ return err;
13386+}
1facf9fc 13387+
076b876e 13388+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1facf9fc 13389+{
4a4d8108
AM
13390+ ssize_t err;
13391+ struct file *file, *h_file;
13392+ struct dentry *dentry;
dece6358 13393+ struct super_block *sb;
1facf9fc 13394+
4a4d8108 13395+ file = kio->ki_filp;
dece6358 13396+ dentry = file->f_dentry;
1308ab2a 13397+ sb = dentry->d_sb;
e49829fe 13398+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13399+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13400+ if (unlikely(err))
13401+ goto out;
13402+
13403+ h_file = au_hf_top(file);
9dbd164d
AM
13404+ get_file(h_file);
13405+ di_read_unlock(dentry, AuLock_IR);
13406+ fi_read_unlock(file);
13407+
076b876e 13408+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
4a4d8108
AM
13409+ /* todo: necessary? */
13410+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13411+ /* update without lock, I don't think it a problem */
c06a8ce3 13412+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13413+ fput(h_file);
1facf9fc 13414+
4f0767ce 13415+out:
4a4d8108 13416+ si_read_unlock(sb);
1308ab2a 13417+ return err;
13418+}
1facf9fc 13419+
076b876e 13420+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter)
1308ab2a 13421+{
4a4d8108 13422+ ssize_t err;
076b876e
AM
13423+ blkcnt_t blks;
13424+ aufs_bindex_t bstart;
4a4d8108
AM
13425+ struct au_pin pin;
13426+ struct dentry *dentry;
076b876e 13427+ struct inode *inode, *h_inode;
4a4d8108 13428+ struct file *file, *h_file;
9dbd164d 13429+ struct super_block *sb;
1308ab2a 13430+
4a4d8108 13431+ file = kio->ki_filp;
1308ab2a 13432+ dentry = file->f_dentry;
9dbd164d 13433+ sb = dentry->d_sb;
1308ab2a 13434+ inode = dentry->d_inode;
e49829fe
JR
13435+ au_mtx_and_read_lock(inode);
13436+
4a4d8108
AM
13437+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13438+ if (unlikely(err))
1308ab2a 13439+ goto out;
1facf9fc 13440+
4a4d8108
AM
13441+ err = au_ready_to_write(file, -1, &pin);
13442+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13443+ if (unlikely(err)) {
13444+ di_read_unlock(dentry, AuLock_IR);
13445+ fi_write_unlock(file);
13446+ goto out;
13447+ }
1facf9fc 13448+
076b876e 13449+ bstart = au_fbstart(file);
4a4d8108 13450+ h_file = au_hf_top(file);
9dbd164d 13451+ get_file(h_file);
c1595e42 13452+ h_inode = file_inode(h_file);
076b876e 13453+ blks = h_inode->i_blocks;
9dbd164d
AM
13454+ au_unpin(&pin);
13455+ di_read_unlock(dentry, AuLock_IR);
13456+ fi_write_unlock(file);
13457+
076b876e 13458+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter);
9dbd164d 13459+ ii_write_lock_child(inode);
4a4d8108 13460+ au_cpup_attr_timesizes(inode);
c06a8ce3 13461+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13462+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13463+ if (err > 0)
13464+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13465+ ii_write_unlock(inode);
13466+ fput(h_file);
1facf9fc 13467+
4f0767ce 13468+out:
9dbd164d 13469+ si_read_unlock(sb);
4a4d8108 13470+ mutex_unlock(&inode->i_mutex);
dece6358 13471+ return err;
1facf9fc 13472+}
13473+
4a4d8108
AM
13474+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
13475+ struct pipe_inode_info *pipe, size_t len,
13476+ unsigned int flags)
1facf9fc 13477+{
4a4d8108
AM
13478+ ssize_t err;
13479+ struct file *h_file;
13480+ struct dentry *dentry;
dece6358 13481+ struct super_block *sb;
1facf9fc 13482+
dece6358 13483+ dentry = file->f_dentry;
dece6358 13484+ sb = dentry->d_sb;
e49829fe 13485+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13486+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13487+ if (unlikely(err))
dece6358 13488+ goto out;
1facf9fc 13489+
4a4d8108
AM
13490+ err = -EINVAL;
13491+ h_file = au_hf_top(file);
9dbd164d 13492+ get_file(h_file);
4a4d8108 13493+ if (au_test_loopback_kthread()) {
87a755f4
AM
13494+ au_warn_loopback(h_file->f_dentry->d_sb);
13495+ if (file->f_mapping != h_file->f_mapping) {
13496+ file->f_mapping = h_file->f_mapping;
13497+ smp_mb(); /* unnecessary? */
13498+ }
1308ab2a 13499+ }
9dbd164d
AM
13500+ di_read_unlock(dentry, AuLock_IR);
13501+ fi_read_unlock(file);
13502+
4a4d8108
AM
13503+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
13504+ /* todo: necessasry? */
13505+ /* file->f_ra = h_file->f_ra; */
9dbd164d 13506+ /* update without lock, I don't think it a problem */
c06a8ce3 13507+ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file));
9dbd164d 13508+ fput(h_file);
1facf9fc 13509+
4f0767ce 13510+out:
4a4d8108 13511+ si_read_unlock(sb);
dece6358 13512+ return err;
1facf9fc 13513+}
13514+
4a4d8108
AM
13515+static ssize_t
13516+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos,
13517+ size_t len, unsigned int flags)
1facf9fc 13518+{
4a4d8108 13519+ ssize_t err;
076b876e
AM
13520+ blkcnt_t blks;
13521+ aufs_bindex_t bstart;
4a4d8108
AM
13522+ struct au_pin pin;
13523+ struct dentry *dentry;
076b876e 13524+ struct inode *inode, *h_inode;
9dbd164d 13525+ struct super_block *sb;
076b876e 13526+ struct file *h_file;
1facf9fc 13527+
4a4d8108 13528+ dentry = file->f_dentry;
9dbd164d 13529+ sb = dentry->d_sb;
4a4d8108 13530+ inode = dentry->d_inode;
e49829fe 13531+ au_mtx_and_read_lock(inode);
9dbd164d 13532+
4a4d8108
AM
13533+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13534+ if (unlikely(err))
13535+ goto out;
1facf9fc 13536+
4a4d8108
AM
13537+ err = au_ready_to_write(file, -1, &pin);
13538+ di_downgrade_lock(dentry, AuLock_IR);
9dbd164d
AM
13539+ if (unlikely(err)) {
13540+ di_read_unlock(dentry, AuLock_IR);
13541+ fi_write_unlock(file);
13542+ goto out;
13543+ }
1facf9fc 13544+
076b876e 13545+ bstart = au_fbstart(file);
4a4d8108 13546+ h_file = au_hf_top(file);
9dbd164d 13547+ get_file(h_file);
c1595e42 13548+ h_inode = file_inode(h_file);
076b876e 13549+ blks = h_inode->i_blocks;
4a4d8108 13550+ au_unpin(&pin);
9dbd164d
AM
13551+ di_read_unlock(dentry, AuLock_IR);
13552+ fi_write_unlock(file);
13553+
4a4d8108 13554+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags);
9dbd164d 13555+ ii_write_lock_child(inode);
4a4d8108 13556+ au_cpup_attr_timesizes(inode);
c06a8ce3 13557+ inode->i_mode = file_inode(h_file)->i_mode;
076b876e
AM
13558+ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks);
13559+ if (err > 0)
13560+ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks);
9dbd164d
AM
13561+ ii_write_unlock(inode);
13562+ fput(h_file);
1facf9fc 13563+
4f0767ce 13564+out:
9dbd164d 13565+ si_read_unlock(sb);
4a4d8108
AM
13566+ mutex_unlock(&inode->i_mutex);
13567+ return err;
13568+}
1facf9fc 13569+
38d290e6
JR
13570+static long aufs_fallocate(struct file *file, int mode, loff_t offset,
13571+ loff_t len)
13572+{
13573+ long err;
13574+ struct au_pin pin;
13575+ struct dentry *dentry;
13576+ struct super_block *sb;
13577+ struct inode *inode;
13578+ struct file *h_file;
13579+
13580+ dentry = file->f_dentry;
13581+ sb = dentry->d_sb;
13582+ inode = dentry->d_inode;
13583+ au_mtx_and_read_lock(inode);
13584+
13585+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13586+ if (unlikely(err))
13587+ goto out;
13588+
13589+ err = au_ready_to_write(file, -1, &pin);
13590+ di_downgrade_lock(dentry, AuLock_IR);
13591+ if (unlikely(err)) {
13592+ di_read_unlock(dentry, AuLock_IR);
13593+ fi_write_unlock(file);
13594+ goto out;
13595+ }
13596+
13597+ h_file = au_hf_top(file);
13598+ get_file(h_file);
13599+ au_unpin(&pin);
13600+ di_read_unlock(dentry, AuLock_IR);
13601+ fi_write_unlock(file);
13602+
13603+ lockdep_off();
13604+ err = do_fallocate(h_file, mode, offset, len);
13605+ lockdep_on();
13606+ ii_write_lock_child(inode);
13607+ au_cpup_attr_timesizes(inode);
13608+ inode->i_mode = file_inode(h_file)->i_mode;
13609+ ii_write_unlock(inode);
13610+ fput(h_file);
13611+
13612+out:
13613+ si_read_unlock(sb);
13614+ mutex_unlock(&inode->i_mutex);
13615+ return err;
13616+}
13617+
4a4d8108
AM
13618+/* ---------------------------------------------------------------------- */
13619+
9dbd164d
AM
13620+/*
13621+ * The locking order around current->mmap_sem.
13622+ * - in most and regular cases
13623+ * file I/O syscall -- aufs_read() or something
13624+ * -- si_rwsem for read -- mmap_sem
13625+ * (Note that [fdi]i_rwsem are released before mmap_sem).
13626+ * - in mmap case
13627+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem
13628+ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for
13629+ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in
13630+ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though.
13631+ * It means that when aufs acquires si_rwsem for write, the process should never
13632+ * acquire mmap_sem.
13633+ *
392086de 13634+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a
9dbd164d
AM
13635+ * problem either since any directory is not able to be mmap-ed.
13636+ * The similar scenario is applied to aufs_readlink() too.
13637+ */
13638+
38d290e6 13639+#if 0 /* stop calling security_file_mmap() */
2dfbb274
AM
13640+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */
13641+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b)
13642+
13643+static unsigned long au_arch_prot_conv(unsigned long flags)
13644+{
13645+ /* currently ppc64 only */
13646+#ifdef CONFIG_PPC64
13647+ /* cf. linux/arch/powerpc/include/asm/mman.h */
13648+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO);
13649+ return AuConv_VM_PROT(flags, SAO);
13650+#else
13651+ AuDebugOn(arch_calc_vm_prot_bits(-1));
13652+ return 0;
13653+#endif
13654+}
13655+
13656+static unsigned long au_prot_conv(unsigned long flags)
13657+{
13658+ return AuConv_VM_PROT(flags, READ)
13659+ | AuConv_VM_PROT(flags, WRITE)
13660+ | AuConv_VM_PROT(flags, EXEC)
13661+ | au_arch_prot_conv(flags);
13662+}
13663+
13664+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */
13665+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b)
13666+
13667+static unsigned long au_flag_conv(unsigned long flags)
13668+{
13669+ return AuConv_VM_MAP(flags, GROWSDOWN)
13670+ | AuConv_VM_MAP(flags, DENYWRITE)
2dfbb274
AM
13671+ | AuConv_VM_MAP(flags, LOCKED);
13672+}
38d290e6 13673+#endif
2dfbb274 13674+
9dbd164d 13675+static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
dece6358 13676+{
4a4d8108
AM
13677+ int err;
13678+ aufs_bindex_t bstart;
13679+ const unsigned char wlock
9dbd164d 13680+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED);
4a4d8108
AM
13681+ struct dentry *dentry;
13682+ struct super_block *sb;
9dbd164d
AM
13683+ struct file *h_file;
13684+ struct au_branch *br;
13685+ struct au_pin pin;
13686+
13687+ AuDbgVmRegion(file, vma);
1308ab2a 13688+
4a4d8108
AM
13689+ dentry = file->f_dentry;
13690+ sb = dentry->d_sb;
9dbd164d 13691+ lockdep_off();
e49829fe 13692+ si_read_lock(sb, AuLock_NOPLMW);
4a4d8108
AM
13693+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13694+ if (unlikely(err))
13695+ goto out;
13696+
4a4d8108 13697+ if (wlock) {
4a4d8108
AM
13698+ err = au_ready_to_write(file, -1, &pin);
13699+ di_write_unlock(dentry);
9dbd164d
AM
13700+ if (unlikely(err)) {
13701+ fi_write_unlock(file);
13702+ goto out;
13703+ }
4a4d8108
AM
13704+ au_unpin(&pin);
13705+ } else
13706+ di_write_unlock(dentry);
9dbd164d 13707+
4a4d8108 13708+ bstart = au_fbstart(file);
9dbd164d
AM
13709+ br = au_sbr(sb, bstart);
13710+ h_file = au_hf_top(file);
13711+ get_file(h_file);
2cbb1c4b 13712+ au_set_mmapped(file);
4a4d8108 13713+ fi_write_unlock(file);
9dbd164d 13714+ lockdep_on();
1308ab2a 13715+
9dbd164d 13716+ au_vm_file_reset(vma, h_file);
38d290e6
JR
13717+ /*
13718+ * we cannot call security_mmap_file() here since it may acquire
13719+ * mmap_sem or i_mutex.
13720+ *
13721+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags),
13722+ * au_flag_conv(vma->vm_flags));
13723+ */
9dbd164d
AM
13724+ if (!err)
13725+ err = h_file->f_op->mmap(h_file, vma);
2cbb1c4b
JR
13726+ if (unlikely(err))
13727+ goto out_reset;
4a4d8108 13728+
fb47a38f 13729+ au_vm_prfile_set(vma, file);
4a4d8108 13730+ /* update without lock, I don't think it a problem */
c06a8ce3 13731+ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file));
2cbb1c4b 13732+ goto out_fput; /* success */
4a4d8108 13733+
2cbb1c4b
JR
13734+out_reset:
13735+ au_unset_mmapped(file);
13736+ au_vm_file_reset(vma, file);
13737+out_fput:
9dbd164d
AM
13738+ fput(h_file);
13739+ lockdep_off();
4f0767ce 13740+out:
9dbd164d
AM
13741+ si_read_unlock(sb);
13742+ lockdep_on();
13743+ AuTraceErr(err);
4a4d8108
AM
13744+ return err;
13745+}
13746+
13747+/* ---------------------------------------------------------------------- */
13748+
1e00d052
AM
13749+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end,
13750+ int datasync)
4a4d8108
AM
13751+{
13752+ int err;
13753+ struct au_pin pin;
b752ccd1 13754+ struct dentry *dentry;
4a4d8108
AM
13755+ struct inode *inode;
13756+ struct file *h_file;
13757+ struct super_block *sb;
13758+
b752ccd1 13759+ dentry = file->f_dentry;
4a4d8108 13760+ inode = dentry->d_inode;
4a4d8108 13761+ sb = dentry->d_sb;
1e00d052 13762+ mutex_lock(&inode->i_mutex);
e49829fe
JR
13763+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
13764+ if (unlikely(err))
13765+ goto out;
4a4d8108
AM
13766+
13767+ err = 0; /* -EBADF; */ /* posix? */
13768+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
e49829fe 13769+ goto out_si;
4a4d8108
AM
13770+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13771+ if (unlikely(err))
e49829fe 13772+ goto out_si;
4a4d8108
AM
13773+
13774+ err = au_ready_to_write(file, -1, &pin);
13775+ di_downgrade_lock(dentry, AuLock_IR);
13776+ if (unlikely(err))
13777+ goto out_unlock;
13778+ au_unpin(&pin);
13779+
13780+ err = -EINVAL;
13781+ h_file = au_hf_top(file);
53392da6
AM
13782+ err = vfsub_fsync(h_file, &h_file->f_path, datasync);
13783+ au_cpup_attr_timesizes(inode);
4a4d8108 13784+
4f0767ce 13785+out_unlock:
4a4d8108 13786+ di_read_unlock(dentry, AuLock_IR);
1308ab2a 13787+ fi_write_unlock(file);
e49829fe 13788+out_si:
953406b4 13789+ si_read_unlock(sb);
e49829fe 13790+out:
1e00d052 13791+ mutex_unlock(&inode->i_mutex);
4a4d8108 13792+ return err;
dece6358
AM
13793+}
13794+
4a4d8108
AM
13795+/* no one supports this operation, currently */
13796+#if 0
13797+static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync)
dece6358 13798+{
4a4d8108
AM
13799+ int err;
13800+ struct au_pin pin;
1308ab2a 13801+ struct dentry *dentry;
4a4d8108
AM
13802+ struct inode *inode;
13803+ struct file *file, *h_file;
1308ab2a 13804+
4a4d8108 13805+ file = kio->ki_filp;
1308ab2a 13806+ dentry = file->f_dentry;
4a4d8108 13807+ inode = dentry->d_inode;
e49829fe 13808+ au_mtx_and_read_lock(inode);
4a4d8108
AM
13809+
13810+ err = 0; /* -EBADF; */ /* posix? */
13811+ if (unlikely(!(file->f_mode & FMODE_WRITE)))
13812+ goto out;
13813+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
13814+ if (unlikely(err))
1308ab2a 13815+ goto out;
13816+
4a4d8108
AM
13817+ err = au_ready_to_write(file, -1, &pin);
13818+ di_downgrade_lock(dentry, AuLock_IR);
13819+ if (unlikely(err))
13820+ goto out_unlock;
13821+ au_unpin(&pin);
1308ab2a 13822+
4a4d8108
AM
13823+ err = -ENOSYS;
13824+ h_file = au_hf_top(file);
523b37e3 13825+ if (h_file->f_op->aio_fsync) {
4a4d8108 13826+ struct mutex *h_mtx;
1308ab2a 13827+
c06a8ce3 13828+ h_mtx = &file_inode(h_file)->i_mutex;
4a4d8108
AM
13829+ if (!is_sync_kiocb(kio)) {
13830+ get_file(h_file);
13831+ fput(file);
13832+ }
13833+ kio->ki_filp = h_file;
13834+ err = h_file->f_op->aio_fsync(kio, datasync);
13835+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
13836+ if (!err)
13837+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL);
13838+ /*ignore*/
13839+ au_cpup_attr_timesizes(inode);
13840+ mutex_unlock(h_mtx);
13841+ }
1308ab2a 13842+
4f0767ce 13843+out_unlock:
4a4d8108
AM
13844+ di_read_unlock(dentry, AuLock_IR);
13845+ fi_write_unlock(file);
4f0767ce 13846+out:
e49829fe 13847+ si_read_unlock(inode->sb);
4a4d8108
AM
13848+ mutex_unlock(&inode->i_mutex);
13849+ return err;
dece6358 13850+}
4a4d8108 13851+#endif
dece6358 13852+
4a4d8108 13853+static int aufs_fasync(int fd, struct file *file, int flag)
dece6358 13854+{
4a4d8108
AM
13855+ int err;
13856+ struct file *h_file;
13857+ struct dentry *dentry;
13858+ struct super_block *sb;
1308ab2a 13859+
4a4d8108
AM
13860+ dentry = file->f_dentry;
13861+ sb = dentry->d_sb;
e49829fe 13862+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
4a4d8108
AM
13863+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
13864+ if (unlikely(err))
13865+ goto out;
13866+
13867+ h_file = au_hf_top(file);
523b37e3 13868+ if (h_file->f_op->fasync)
4a4d8108
AM
13869+ err = h_file->f_op->fasync(fd, h_file, flag);
13870+
13871+ di_read_unlock(dentry, AuLock_IR);
13872+ fi_read_unlock(file);
1308ab2a 13873+
4f0767ce 13874+out:
4a4d8108 13875+ si_read_unlock(sb);
1308ab2a 13876+ return err;
dece6358 13877+}
4a4d8108
AM
13878+
13879+/* ---------------------------------------------------------------------- */
13880+
13881+/* no one supports this operation, currently */
13882+#if 0
13883+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset,
13884+ size_t len, loff_t *pos , int more)
13885+{
13886+}
13887+#endif
13888+
13889+/* ---------------------------------------------------------------------- */
13890+
13891+const struct file_operations aufs_file_fop = {
13892+ .owner = THIS_MODULE,
2cbb1c4b 13893+
027c5e7a 13894+ .llseek = default_llseek,
4a4d8108
AM
13895+
13896+ .read = aufs_read,
13897+ .write = aufs_write,
076b876e
AM
13898+ .read_iter = aufs_read_iter,
13899+ .write_iter = aufs_write_iter,
13900+
4a4d8108
AM
13901+#ifdef CONFIG_AUFS_POLL
13902+ .poll = aufs_poll,
13903+#endif
13904+ .unlocked_ioctl = aufs_ioctl_nondir,
b752ccd1 13905+#ifdef CONFIG_COMPAT
c2b27bf2 13906+ .compat_ioctl = aufs_compat_ioctl_nondir,
b752ccd1 13907+#endif
4a4d8108
AM
13908+ .mmap = aufs_mmap,
13909+ .open = aufs_open_nondir,
13910+ .flush = aufs_flush_nondir,
13911+ .release = aufs_release_nondir,
13912+ .fsync = aufs_fsync_nondir,
13913+ /* .aio_fsync = aufs_aio_fsync_nondir, */
13914+ .fasync = aufs_fasync,
13915+ /* .sendpage = aufs_sendpage, */
13916+ .splice_write = aufs_splice_write,
13917+ .splice_read = aufs_splice_read,
13918+#if 0
13919+ .aio_splice_write = aufs_aio_splice_write,
38d290e6 13920+ .aio_splice_read = aufs_aio_splice_read,
4a4d8108 13921+#endif
38d290e6 13922+ .fallocate = aufs_fallocate
4a4d8108 13923+};
7f207e10
AM
13924diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
13925--- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 13926+++ linux/fs/aufs/fstype.h 2015-01-25 13:00:38.631047076 +0100
523b37e3 13927@@ -0,0 +1,469 @@
4a4d8108 13928+/*
523b37e3 13929+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
13930+ *
13931+ * This program, aufs is free software; you can redistribute it and/or modify
13932+ * it under the terms of the GNU General Public License as published by
13933+ * the Free Software Foundation; either version 2 of the License, or
13934+ * (at your option) any later version.
13935+ *
13936+ * This program is distributed in the hope that it will be useful,
13937+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13938+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13939+ * GNU General Public License for more details.
13940+ *
13941+ * You should have received a copy of the GNU General Public License
523b37e3 13942+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
13943+ */
13944+
13945+/*
13946+ * judging filesystem type
13947+ */
13948+
13949+#ifndef __AUFS_FSTYPE_H__
13950+#define __AUFS_FSTYPE_H__
13951+
13952+#ifdef __KERNEL__
13953+
13954+#include <linux/fs.h>
13955+#include <linux/magic.h>
13956+#include <linux/romfs_fs.h>
4a4d8108
AM
13957+
13958+static inline int au_test_aufs(struct super_block *sb)
13959+{
13960+ return sb->s_magic == AUFS_SUPER_MAGIC;
13961+}
13962+
13963+static inline const char *au_sbtype(struct super_block *sb)
13964+{
13965+ return sb->s_type->name;
13966+}
1308ab2a 13967+
13968+static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
13969+{
13970+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
13971+ return sb->s_magic == ROMFS_MAGIC;
dece6358
AM
13972+#else
13973+ return 0;
13974+#endif
13975+}
13976+
1308ab2a 13977+static inline int au_test_romfs(struct super_block *sb __maybe_unused)
dece6358 13978+{
1308ab2a 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_cramfs(struct super_block *sb __maybe_unused)
dece6358 13987+{
1308ab2a 13988+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
13989+ return sb->s_magic == CRAMFS_MAGIC;
13990+#endif
13991+ return 0;
13992+}
13993+
13994+static inline int au_test_nfs(struct super_block *sb __maybe_unused)
13995+{
13996+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
13997+ return sb->s_magic == NFS_SUPER_MAGIC;
dece6358
AM
13998+#else
13999+ return 0;
14000+#endif
14001+}
14002+
1308ab2a 14003+static inline int au_test_fuse(struct super_block *sb __maybe_unused)
dece6358 14004+{
1308ab2a 14005+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
14006+ return sb->s_magic == FUSE_SUPER_MAGIC;
dece6358
AM
14007+#else
14008+ return 0;
14009+#endif
14010+}
14011+
1308ab2a 14012+static inline int au_test_xfs(struct super_block *sb __maybe_unused)
dece6358 14013+{
1308ab2a 14014+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
14015+ return sb->s_magic == XFS_SB_MAGIC;
dece6358
AM
14016+#else
14017+ return 0;
14018+#endif
14019+}
14020+
1308ab2a 14021+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused)
dece6358 14022+{
1308ab2a 14023+#ifdef CONFIG_TMPFS
14024+ return sb->s_magic == TMPFS_MAGIC;
14025+#else
14026+ return 0;
dece6358 14027+#endif
dece6358
AM
14028+}
14029+
1308ab2a 14030+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
1facf9fc 14031+{
1308ab2a 14032+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
14033+ return !strcmp(au_sbtype(sb), "ecryptfs");
14034+#else
14035+ return 0;
14036+#endif
1facf9fc 14037+}
14038+
1308ab2a 14039+static inline int au_test_ocfs2(struct super_block *sb __maybe_unused)
1facf9fc 14040+{
1308ab2a 14041+#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE)
14042+ return sb->s_magic == OCFS2_SUPER_MAGIC;
14043+#else
14044+ return 0;
14045+#endif
1facf9fc 14046+}
14047+
1308ab2a 14048+static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused)
1facf9fc 14049+{
1308ab2a 14050+#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE)
14051+ return sb->s_magic == DLMFS_MAGIC;
14052+#else
14053+ return 0;
14054+#endif
1facf9fc 14055+}
14056+
1308ab2a 14057+static inline int au_test_coda(struct super_block *sb __maybe_unused)
1facf9fc 14058+{
1308ab2a 14059+#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE)
14060+ return sb->s_magic == CODA_SUPER_MAGIC;
14061+#else
14062+ return 0;
14063+#endif
14064+}
14065+
14066+static inline int au_test_v9fs(struct super_block *sb __maybe_unused)
14067+{
14068+#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE)
14069+ return sb->s_magic == V9FS_MAGIC;
14070+#else
14071+ return 0;
14072+#endif
14073+}
14074+
14075+static inline int au_test_ext4(struct super_block *sb __maybe_unused)
14076+{
c2b27bf2 14077+#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE)
1308ab2a 14078+ return sb->s_magic == EXT4_SUPER_MAGIC;
14079+#else
14080+ return 0;
14081+#endif
14082+}
14083+
14084+static inline int au_test_sysv(struct super_block *sb __maybe_unused)
14085+{
14086+#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE)
14087+ return !strcmp(au_sbtype(sb), "sysv");
14088+#else
14089+ return 0;
14090+#endif
14091+}
14092+
14093+static inline int au_test_ramfs(struct super_block *sb)
14094+{
14095+ return sb->s_magic == RAMFS_MAGIC;
14096+}
14097+
14098+static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
14099+{
14100+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
14101+ return sb->s_magic == UBIFS_SUPER_MAGIC;
14102+#else
14103+ return 0;
14104+#endif
14105+}
14106+
14107+static inline int au_test_procfs(struct super_block *sb __maybe_unused)
14108+{
14109+#ifdef CONFIG_PROC_FS
14110+ return sb->s_magic == PROC_SUPER_MAGIC;
14111+#else
14112+ return 0;
14113+#endif
14114+}
14115+
14116+static inline int au_test_sysfs(struct super_block *sb __maybe_unused)
14117+{
14118+#ifdef CONFIG_SYSFS
14119+ return sb->s_magic == SYSFS_MAGIC;
14120+#else
14121+ return 0;
14122+#endif
14123+}
14124+
14125+static inline int au_test_configfs(struct super_block *sb __maybe_unused)
14126+{
14127+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
14128+ return sb->s_magic == CONFIGFS_MAGIC;
14129+#else
14130+ return 0;
14131+#endif
14132+}
14133+
14134+static inline int au_test_minix(struct super_block *sb __maybe_unused)
14135+{
14136+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
14137+ return sb->s_magic == MINIX3_SUPER_MAGIC
14138+ || sb->s_magic == MINIX2_SUPER_MAGIC
14139+ || sb->s_magic == MINIX2_SUPER_MAGIC2
14140+ || sb->s_magic == MINIX_SUPER_MAGIC
14141+ || sb->s_magic == MINIX_SUPER_MAGIC2;
14142+#else
14143+ return 0;
14144+#endif
14145+}
14146+
14147+static inline int au_test_cifs(struct super_block *sb __maybe_unused)
14148+{
14149+#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE)
14150+ return sb->s_magic == CIFS_MAGIC_NUMBER;
14151+#else
14152+ return 0;
14153+#endif
14154+}
14155+
14156+static inline int au_test_fat(struct super_block *sb __maybe_unused)
14157+{
14158+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
14159+ return sb->s_magic == MSDOS_SUPER_MAGIC;
14160+#else
14161+ return 0;
14162+#endif
14163+}
14164+
14165+static inline int au_test_msdos(struct super_block *sb)
14166+{
14167+ return au_test_fat(sb);
14168+}
14169+
14170+static inline int au_test_vfat(struct super_block *sb)
14171+{
14172+ return au_test_fat(sb);
14173+}
14174+
14175+static inline int au_test_securityfs(struct super_block *sb __maybe_unused)
14176+{
14177+#ifdef CONFIG_SECURITYFS
14178+ return sb->s_magic == SECURITYFS_MAGIC;
14179+#else
14180+ return 0;
14181+#endif
14182+}
14183+
14184+static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
14185+{
14186+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
14187+ return sb->s_magic == SQUASHFS_MAGIC;
14188+#else
14189+ return 0;
14190+#endif
14191+}
14192+
14193+static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
14194+{
14195+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
14196+ return sb->s_magic == BTRFS_SUPER_MAGIC;
14197+#else
14198+ return 0;
14199+#endif
14200+}
14201+
14202+static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
14203+{
14204+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
14205+ return sb->s_magic == XENFS_SUPER_MAGIC;
14206+#else
14207+ return 0;
14208+#endif
14209+}
14210+
14211+static inline int au_test_debugfs(struct super_block *sb __maybe_unused)
14212+{
14213+#ifdef CONFIG_DEBUG_FS
14214+ return sb->s_magic == DEBUGFS_MAGIC;
14215+#else
14216+ return 0;
14217+#endif
14218+}
14219+
14220+static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
14221+{
14222+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
14223+ return sb->s_magic == NILFS_SUPER_MAGIC;
14224+#else
14225+ return 0;
14226+#endif
14227+}
14228+
4a4d8108
AM
14229+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
14230+{
14231+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
14232+ return sb->s_magic == HFSPLUS_SUPER_MAGIC;
14233+#else
14234+ return 0;
14235+#endif
14236+}
14237+
1308ab2a 14238+/* ---------------------------------------------------------------------- */
14239+/*
14240+ * they can't be an aufs branch.
14241+ */
14242+static inline int au_test_fs_unsuppoted(struct super_block *sb)
14243+{
14244+ return
14245+#ifndef CONFIG_AUFS_BR_RAMFS
14246+ au_test_ramfs(sb) ||
14247+#endif
14248+ au_test_procfs(sb)
14249+ || au_test_sysfs(sb)
14250+ || au_test_configfs(sb)
14251+ || au_test_debugfs(sb)
14252+ || au_test_securityfs(sb)
14253+ || au_test_xenfs(sb)
14254+ || au_test_ecryptfs(sb)
14255+ /* || !strcmp(au_sbtype(sb), "unionfs") */
14256+ || au_test_aufs(sb); /* will be supported in next version */
14257+}
14258+
1308ab2a 14259+static inline int au_test_fs_remote(struct super_block *sb)
14260+{
14261+ return !au_test_tmpfs(sb)
14262+#ifdef CONFIG_AUFS_BR_RAMFS
14263+ && !au_test_ramfs(sb)
14264+#endif
14265+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV);
14266+}
14267+
14268+/* ---------------------------------------------------------------------- */
14269+
14270+/*
14271+ * Note: these functions (below) are created after reading ->getattr() in all
14272+ * filesystems under linux/fs. it means we have to do so in every update...
14273+ */
14274+
14275+/*
14276+ * some filesystems require getattr to refresh the inode attributes before
14277+ * referencing.
14278+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs)
14279+ * and leave the work for d_revalidate()
14280+ */
14281+static inline int au_test_fs_refresh_iattr(struct super_block *sb)
14282+{
14283+ return au_test_nfs(sb)
14284+ || au_test_fuse(sb)
1308ab2a 14285+ /* || au_test_ocfs2(sb) */ /* untested */
14286+ /* || au_test_btrfs(sb) */ /* untested */
14287+ /* || au_test_coda(sb) */ /* untested */
14288+ /* || au_test_v9fs(sb) */ /* untested */
14289+ ;
14290+}
14291+
14292+/*
14293+ * filesystems which don't maintain i_size or i_blocks.
14294+ */
14295+static inline int au_test_fs_bad_iattr_size(struct super_block *sb)
14296+{
14297+ return au_test_xfs(sb)
4a4d8108
AM
14298+ || au_test_btrfs(sb)
14299+ || au_test_ubifs(sb)
14300+ || au_test_hfsplus(sb) /* maintained, but incorrect */
1308ab2a 14301+ /* || au_test_ext4(sb) */ /* untested */
14302+ /* || au_test_ocfs2(sb) */ /* untested */
14303+ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */
14304+ /* || au_test_sysv(sb) */ /* untested */
1308ab2a 14305+ /* || au_test_minix(sb) */ /* untested */
14306+ ;
14307+}
14308+
14309+/*
14310+ * filesystems which don't store the correct value in some of their inode
14311+ * attributes.
14312+ */
14313+static inline int au_test_fs_bad_iattr(struct super_block *sb)
14314+{
14315+ return au_test_fs_bad_iattr_size(sb)
14316+ /* || au_test_cifs(sb) */ /* untested */
14317+ || au_test_fat(sb)
14318+ || au_test_msdos(sb)
14319+ || au_test_vfat(sb);
1facf9fc 14320+}
14321+
14322+/* they don't check i_nlink in link(2) */
14323+static inline int au_test_fs_no_limit_nlink(struct super_block *sb)
14324+{
14325+ return au_test_tmpfs(sb)
14326+#ifdef CONFIG_AUFS_BR_RAMFS
14327+ || au_test_ramfs(sb)
14328+#endif
4a4d8108 14329+ || au_test_ubifs(sb)
4a4d8108 14330+ || au_test_hfsplus(sb);
1facf9fc 14331+}
14332+
14333+/*
14334+ * filesystems which sets S_NOATIME and S_NOCMTIME.
14335+ */
14336+static inline int au_test_fs_notime(struct super_block *sb)
14337+{
14338+ return au_test_nfs(sb)
14339+ || au_test_fuse(sb)
dece6358 14340+ || au_test_ubifs(sb)
1facf9fc 14341+ /* || au_test_cifs(sb) */ /* untested */
1facf9fc 14342+ ;
14343+}
14344+
14345+/*
14346+ * filesystems which requires replacing i_mapping.
14347+ */
14348+static inline int au_test_fs_bad_mapping(struct super_block *sb)
14349+{
dece6358
AM
14350+ return au_test_fuse(sb)
14351+ || au_test_ubifs(sb);
1facf9fc 14352+}
14353+
14354+/* temporary support for i#1 in cramfs */
14355+static inline int au_test_fs_unique_ino(struct inode *inode)
14356+{
14357+ if (au_test_cramfs(inode->i_sb))
14358+ return inode->i_ino != 1;
14359+ return 1;
14360+}
14361+
14362+/* ---------------------------------------------------------------------- */
14363+
14364+/*
14365+ * the filesystem where the xino files placed must support i/o after unlink and
14366+ * maintain i_size and i_blocks.
14367+ */
14368+static inline int au_test_fs_bad_xino(struct super_block *sb)
14369+{
14370+ return au_test_fs_remote(sb)
14371+ || au_test_fs_bad_iattr_size(sb)
1facf9fc 14372+ /* don't want unnecessary work for xino */
14373+ || au_test_aufs(sb)
1308ab2a 14374+ || au_test_ecryptfs(sb)
14375+ || au_test_nilfs(sb);
1facf9fc 14376+}
14377+
14378+static inline int au_test_fs_trunc_xino(struct super_block *sb)
14379+{
14380+ return au_test_tmpfs(sb)
14381+ || au_test_ramfs(sb);
14382+}
14383+
14384+/*
14385+ * test if the @sb is real-readonly.
14386+ */
14387+static inline int au_test_fs_rr(struct super_block *sb)
14388+{
14389+ return au_test_squashfs(sb)
14390+ || au_test_iso9660(sb)
14391+ || au_test_cramfs(sb)
14392+ || au_test_romfs(sb);
14393+}
14394+
14395+#endif /* __KERNEL__ */
14396+#endif /* __AUFS_FSTYPE_H__ */
7f207e10
AM
14397diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
14398--- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
14399+++ linux/fs/aufs/hfsnotify.c 2015-01-25 13:00:38.631047076 +0100
14400@@ -0,0 +1,288 @@
1facf9fc 14401+/*
523b37e3 14402+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 14403+ *
14404+ * This program, aufs is free software; you can redistribute it and/or modify
14405+ * it under the terms of the GNU General Public License as published by
14406+ * the Free Software Foundation; either version 2 of the License, or
14407+ * (at your option) any later version.
dece6358
AM
14408+ *
14409+ * This program is distributed in the hope that it will be useful,
14410+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14411+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14412+ * GNU General Public License for more details.
14413+ *
14414+ * You should have received a copy of the GNU General Public License
523b37e3 14415+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 14416+ */
14417+
14418+/*
4a4d8108 14419+ * fsnotify for the lower directories
1facf9fc 14420+ */
14421+
14422+#include "aufs.h"
14423+
4a4d8108
AM
14424+/* FS_IN_IGNORED is unnecessary */
14425+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE
14426+ | FS_CREATE | FS_EVENT_ON_CHILD);
7f207e10 14427+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq);
7eafdf33 14428+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0);
1facf9fc 14429+
0c5527e5 14430+static void au_hfsn_free_mark(struct fsnotify_mark *mark)
1facf9fc 14431+{
0c5527e5
AM
14432+ struct au_hnotify *hn = container_of(mark, struct au_hnotify,
14433+ hn_mark);
4a4d8108 14434+ AuDbg("here\n");
7eafdf33 14435+ au_cache_free_hnotify(hn);
076b876e 14436+ smp_mb__before_atomic();
1716fcea
AM
14437+ if (atomic64_dec_and_test(&au_hfsn_ifree))
14438+ wake_up(&au_hfsn_wq);
4a4d8108 14439+}
1facf9fc 14440+
027c5e7a 14441+static int au_hfsn_alloc(struct au_hinode *hinode)
4a4d8108 14442+{
1716fcea 14443+ int err;
027c5e7a
AM
14444+ struct au_hnotify *hn;
14445+ struct super_block *sb;
14446+ struct au_branch *br;
0c5527e5 14447+ struct fsnotify_mark *mark;
027c5e7a 14448+ aufs_bindex_t bindex;
1facf9fc 14449+
027c5e7a
AM
14450+ hn = hinode->hi_notify;
14451+ sb = hn->hn_aufs_inode->i_sb;
14452+ bindex = au_br_index(sb, hinode->hi_id);
14453+ br = au_sbr(sb, bindex);
1716fcea
AM
14454+ AuDebugOn(!br->br_hfsn);
14455+
0c5527e5
AM
14456+ mark = &hn->hn_mark;
14457+ fsnotify_init_mark(mark, au_hfsn_free_mark);
14458+ mark->mask = AuHfsnMask;
7f207e10
AM
14459+ /*
14460+ * by udba rename or rmdir, aufs assign a new inode to the known
14461+ * h_inode, so specify 1 to allow dups.
14462+ */
c1595e42 14463+ lockdep_off();
1716fcea 14464+ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode,
027c5e7a 14465+ /*mnt*/NULL, /*allow_dups*/1);
1716fcea
AM
14466+ /* even if err */
14467+ fsnotify_put_mark(mark);
c1595e42 14468+ lockdep_on();
1716fcea
AM
14469+
14470+ return err;
1facf9fc 14471+}
14472+
7eafdf33 14473+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn)
1facf9fc 14474+{
0c5527e5 14475+ struct fsnotify_mark *mark;
7eafdf33 14476+ unsigned long long ull;
1716fcea 14477+ struct fsnotify_group *group;
7eafdf33
AM
14478+
14479+ ull = atomic64_inc_return(&au_hfsn_ifree);
14480+ BUG_ON(!ull);
953406b4 14481+
0c5527e5 14482+ mark = &hn->hn_mark;
1716fcea
AM
14483+ spin_lock(&mark->lock);
14484+ group = mark->group;
14485+ fsnotify_get_group(group);
14486+ spin_unlock(&mark->lock);
c1595e42 14487+ lockdep_off();
1716fcea
AM
14488+ fsnotify_destroy_mark(mark, group);
14489+ fsnotify_put_group(group);
c1595e42 14490+ lockdep_on();
7f207e10 14491+
7eafdf33
AM
14492+ /* free hn by myself */
14493+ return 0;
1facf9fc 14494+}
14495+
14496+/* ---------------------------------------------------------------------- */
14497+
4a4d8108 14498+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set)
1facf9fc 14499+{
0c5527e5 14500+ struct fsnotify_mark *mark;
1facf9fc 14501+
0c5527e5
AM
14502+ mark = &hinode->hi_notify->hn_mark;
14503+ spin_lock(&mark->lock);
1facf9fc 14504+ if (do_set) {
0c5527e5
AM
14505+ AuDebugOn(mark->mask & AuHfsnMask);
14506+ mark->mask |= AuHfsnMask;
1facf9fc 14507+ } else {
0c5527e5
AM
14508+ AuDebugOn(!(mark->mask & AuHfsnMask));
14509+ mark->mask &= ~AuHfsnMask;
1facf9fc 14510+ }
0c5527e5 14511+ spin_unlock(&mark->lock);
4a4d8108 14512+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */
1facf9fc 14513+}
14514+
4a4d8108 14515+/* ---------------------------------------------------------------------- */
1facf9fc 14516+
4a4d8108
AM
14517+/* #define AuDbgHnotify */
14518+#ifdef AuDbgHnotify
14519+static char *au_hfsn_name(u32 mask)
14520+{
14521+#ifdef CONFIG_AUFS_DEBUG
c06a8ce3
AM
14522+#define test_ret(flag) \
14523+ do { \
14524+ if (mask & flag) \
14525+ return #flag; \
14526+ } while (0)
4a4d8108
AM
14527+ test_ret(FS_ACCESS);
14528+ test_ret(FS_MODIFY);
14529+ test_ret(FS_ATTRIB);
14530+ test_ret(FS_CLOSE_WRITE);
14531+ test_ret(FS_CLOSE_NOWRITE);
14532+ test_ret(FS_OPEN);
14533+ test_ret(FS_MOVED_FROM);
14534+ test_ret(FS_MOVED_TO);
14535+ test_ret(FS_CREATE);
14536+ test_ret(FS_DELETE);
14537+ test_ret(FS_DELETE_SELF);
14538+ test_ret(FS_MOVE_SELF);
14539+ test_ret(FS_UNMOUNT);
14540+ test_ret(FS_Q_OVERFLOW);
14541+ test_ret(FS_IN_IGNORED);
14542+ test_ret(FS_IN_ISDIR);
14543+ test_ret(FS_IN_ONESHOT);
14544+ test_ret(FS_EVENT_ON_CHILD);
14545+ return "";
14546+#undef test_ret
14547+#else
14548+ return "??";
14549+#endif
1facf9fc 14550+}
4a4d8108 14551+#endif
1facf9fc 14552+
14553+/* ---------------------------------------------------------------------- */
14554+
1716fcea
AM
14555+static void au_hfsn_free_group(struct fsnotify_group *group)
14556+{
14557+ struct au_br_hfsnotify *hfsn = group->private;
14558+
14559+ AuDbg("here\n");
14560+ kfree(hfsn);
14561+}
14562+
4a4d8108 14563+static int au_hfsn_handle_event(struct fsnotify_group *group,
fb47a38f 14564+ struct inode *inode,
0c5527e5
AM
14565+ struct fsnotify_mark *inode_mark,
14566+ struct fsnotify_mark *vfsmount_mark,
fb47a38f
JR
14567+ u32 mask, void *data, int data_type,
14568+ const unsigned char *file_name, u32 cookie)
1facf9fc 14569+{
14570+ int err;
4a4d8108
AM
14571+ struct au_hnotify *hnotify;
14572+ struct inode *h_dir, *h_inode;
fb47a38f 14573+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name));
4a4d8108 14574+
fb47a38f 14575+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE);
1facf9fc 14576+
14577+ err = 0;
0c5527e5 14578+ /* if FS_UNMOUNT happens, there must be another bug */
4a4d8108 14579+ AuDebugOn(mask & FS_UNMOUNT);
0c5527e5 14580+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
1facf9fc 14581+ goto out;
1facf9fc 14582+
fb47a38f
JR
14583+ h_dir = inode;
14584+ h_inode = NULL;
4a4d8108 14585+#ifdef AuDbgHnotify
392086de 14586+ au_debug_on();
4a4d8108
AM
14587+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
14588+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
14589+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
14590+ h_dir->i_ino, mask, au_hfsn_name(mask),
14591+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
14592+ /* WARN_ON(1); */
1facf9fc 14593+ }
392086de 14594+ au_debug_off();
1facf9fc 14595+#endif
4a4d8108 14596+
0c5527e5
AM
14597+ AuDebugOn(!inode_mark);
14598+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
14599+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);
1facf9fc 14600+
4a4d8108
AM
14601+out:
14602+ return err;
14603+}
1facf9fc 14604+
4a4d8108 14605+static struct fsnotify_ops au_hfsn_ops = {
1716fcea
AM
14606+ .handle_event = au_hfsn_handle_event,
14607+ .free_group_priv = au_hfsn_free_group
4a4d8108
AM
14608+};
14609+
14610+/* ---------------------------------------------------------------------- */
14611+
027c5e7a
AM
14612+static void au_hfsn_fin_br(struct au_branch *br)
14613+{
1716fcea 14614+ struct au_br_hfsnotify *hfsn;
027c5e7a 14615+
1716fcea 14616+ hfsn = br->br_hfsn;
c1595e42
JR
14617+ if (hfsn) {
14618+ lockdep_off();
1716fcea 14619+ fsnotify_put_group(hfsn->hfsn_group);
c1595e42
JR
14620+ lockdep_on();
14621+ }
027c5e7a
AM
14622+}
14623+
1716fcea 14624+static int au_hfsn_init_br(struct au_branch *br, int perm)
4a4d8108
AM
14625+{
14626+ int err;
1716fcea
AM
14627+ struct fsnotify_group *group;
14628+ struct au_br_hfsnotify *hfsn;
1facf9fc 14629+
4a4d8108 14630+ err = 0;
1716fcea
AM
14631+ br->br_hfsn = NULL;
14632+ if (!au_br_hnotifyable(perm))
027c5e7a 14633+ goto out;
027c5e7a 14634+
1716fcea
AM
14635+ err = -ENOMEM;
14636+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS);
14637+ if (unlikely(!hfsn))
027c5e7a
AM
14638+ goto out;
14639+
1716fcea
AM
14640+ err = 0;
14641+ group = fsnotify_alloc_group(&au_hfsn_ops);
14642+ if (IS_ERR(group)) {
14643+ err = PTR_ERR(group);
0c5527e5 14644+ pr_err("fsnotify_alloc_group() failed, %d\n", err);
1716fcea 14645+ goto out_hfsn;
4a4d8108 14646+ }
1facf9fc 14647+
1716fcea
AM
14648+ group->private = hfsn;
14649+ hfsn->hfsn_group = group;
14650+ br->br_hfsn = hfsn;
14651+ goto out; /* success */
14652+
14653+out_hfsn:
14654+ kfree(hfsn);
027c5e7a 14655+out:
1716fcea
AM
14656+ return err;
14657+}
14658+
14659+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm)
14660+{
14661+ int err;
14662+
14663+ err = 0;
14664+ if (!br->br_hfsn)
14665+ err = au_hfsn_init_br(br, perm);
14666+
1facf9fc 14667+ return err;
14668+}
14669+
7eafdf33
AM
14670+/* ---------------------------------------------------------------------- */
14671+
14672+static void au_hfsn_fin(void)
14673+{
14674+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree));
14675+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree));
14676+}
14677+
4a4d8108
AM
14678+const struct au_hnotify_op au_hnotify_op = {
14679+ .ctl = au_hfsn_ctl,
14680+ .alloc = au_hfsn_alloc,
14681+ .free = au_hfsn_free,
1facf9fc 14682+
7eafdf33
AM
14683+ .fin = au_hfsn_fin,
14684+
027c5e7a
AM
14685+ .reset_br = au_hfsn_reset_br,
14686+ .fin_br = au_hfsn_fin_br,
14687+ .init_br = au_hfsn_init_br
4a4d8108 14688+};
7f207e10
AM
14689diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c
14690--- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 14691+++ linux/fs/aufs/hfsplus.c 2015-01-25 13:00:38.631047076 +0100
523b37e3 14692@@ -0,0 +1,56 @@
4a4d8108 14693+/*
523b37e3 14694+ * Copyright (C) 2010-2014 Junjiro R. Okajima
4a4d8108
AM
14695+ *
14696+ * This program, aufs is free software; you can redistribute it and/or modify
14697+ * it under the terms of the GNU General Public License as published by
14698+ * the Free Software Foundation; either version 2 of the License, or
14699+ * (at your option) any later version.
14700+ *
14701+ * This program is distributed in the hope that it will be useful,
14702+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14703+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14704+ * GNU General Public License for more details.
14705+ *
14706+ * You should have received a copy of the GNU General Public License
523b37e3 14707+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 14708+ */
1facf9fc 14709+
4a4d8108
AM
14710+/*
14711+ * special support for filesystems which aqucires an inode mutex
14712+ * at final closing a file, eg, hfsplus.
14713+ *
14714+ * This trick is very simple and stupid, just to open the file before really
14715+ * neceeary open to tell hfsplus that this is not the final closing.
14716+ * The caller should call au_h_open_pre() after acquiring the inode mutex,
14717+ * and au_h_open_post() after releasing it.
14718+ */
1facf9fc 14719+
4a4d8108 14720+#include "aufs.h"
1facf9fc 14721+
392086de
AM
14722+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex,
14723+ int force_wr)
4a4d8108
AM
14724+{
14725+ struct file *h_file;
14726+ struct dentry *h_dentry;
1facf9fc 14727+
4a4d8108
AM
14728+ h_dentry = au_h_dptr(dentry, bindex);
14729+ AuDebugOn(!h_dentry);
14730+ AuDebugOn(!h_dentry->d_inode);
4a4d8108
AM
14731+
14732+ h_file = NULL;
14733+ if (au_test_hfsplus(h_dentry->d_sb)
14734+ && S_ISREG(h_dentry->d_inode->i_mode))
14735+ h_file = au_h_open(dentry, bindex,
14736+ O_RDONLY | O_NOATIME | O_LARGEFILE,
392086de 14737+ /*file*/NULL, force_wr);
4a4d8108 14738+ return h_file;
1facf9fc 14739+}
14740+
4a4d8108
AM
14741+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex,
14742+ struct file *h_file)
14743+{
14744+ if (h_file) {
14745+ fput(h_file);
14746+ au_sbr_put(dentry->d_sb, bindex);
14747+ }
14748+}
7f207e10
AM
14749diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
14750--- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 14751+++ linux/fs/aufs/hnotify.c 2015-01-25 13:00:38.631047076 +0100
076b876e 14752@@ -0,0 +1,714 @@
e49829fe 14753+/*
523b37e3 14754+ * Copyright (C) 2005-2014 Junjiro R. Okajima
e49829fe
JR
14755+ *
14756+ * This program, aufs is free software; you can redistribute it and/or modify
14757+ * it under the terms of the GNU General Public License as published by
14758+ * the Free Software Foundation; either version 2 of the License, or
14759+ * (at your option) any later version.
14760+ *
14761+ * This program is distributed in the hope that it will be useful,
14762+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14763+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14764+ * GNU General Public License for more details.
14765+ *
14766+ * You should have received a copy of the GNU General Public License
523b37e3 14767+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
14768+ */
14769+
14770+/*
7f207e10 14771+ * abstraction to notify the direct changes on lower directories
e49829fe
JR
14772+ */
14773+
14774+#include "aufs.h"
14775+
027c5e7a 14776+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode)
e49829fe
JR
14777+{
14778+ int err;
7f207e10 14779+ struct au_hnotify *hn;
1facf9fc 14780+
4a4d8108
AM
14781+ err = -ENOMEM;
14782+ hn = au_cache_alloc_hnotify();
14783+ if (hn) {
14784+ hn->hn_aufs_inode = inode;
027c5e7a
AM
14785+ hinode->hi_notify = hn;
14786+ err = au_hnotify_op.alloc(hinode);
14787+ AuTraceErr(err);
14788+ if (unlikely(err)) {
14789+ hinode->hi_notify = NULL;
4a4d8108
AM
14790+ au_cache_free_hnotify(hn);
14791+ /*
14792+ * The upper dir was removed by udba, but the same named
14793+ * dir left. In this case, aufs assignes a new inode
14794+ * number and set the monitor again.
14795+ * For the lower dir, the old monitnor is still left.
14796+ */
14797+ if (err == -EEXIST)
14798+ err = 0;
14799+ }
1308ab2a 14800+ }
1308ab2a 14801+
027c5e7a 14802+ AuTraceErr(err);
1308ab2a 14803+ return err;
dece6358 14804+}
1facf9fc 14805+
4a4d8108 14806+void au_hn_free(struct au_hinode *hinode)
dece6358 14807+{
4a4d8108 14808+ struct au_hnotify *hn;
1facf9fc 14809+
4a4d8108
AM
14810+ hn = hinode->hi_notify;
14811+ if (hn) {
4a4d8108 14812+ hinode->hi_notify = NULL;
7eafdf33
AM
14813+ if (au_hnotify_op.free(hinode, hn))
14814+ au_cache_free_hnotify(hn);
4a4d8108
AM
14815+ }
14816+}
dece6358 14817+
4a4d8108 14818+/* ---------------------------------------------------------------------- */
dece6358 14819+
4a4d8108
AM
14820+void au_hn_ctl(struct au_hinode *hinode, int do_set)
14821+{
14822+ if (hinode->hi_notify)
14823+ au_hnotify_op.ctl(hinode, do_set);
14824+}
14825+
14826+void au_hn_reset(struct inode *inode, unsigned int flags)
14827+{
14828+ aufs_bindex_t bindex, bend;
14829+ struct inode *hi;
14830+ struct dentry *iwhdentry;
1facf9fc 14831+
1308ab2a 14832+ bend = au_ibend(inode);
4a4d8108
AM
14833+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
14834+ hi = au_h_iptr(inode, bindex);
14835+ if (!hi)
14836+ continue;
1308ab2a 14837+
4a4d8108
AM
14838+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */
14839+ iwhdentry = au_hi_wh(inode, bindex);
14840+ if (iwhdentry)
14841+ dget(iwhdentry);
14842+ au_igrab(hi);
14843+ au_set_h_iptr(inode, bindex, NULL, 0);
14844+ au_set_h_iptr(inode, bindex, au_igrab(hi),
14845+ flags & ~AuHi_XINO);
14846+ iput(hi);
14847+ dput(iwhdentry);
14848+ /* mutex_unlock(&hi->i_mutex); */
1facf9fc 14849+ }
1facf9fc 14850+}
14851+
1308ab2a 14852+/* ---------------------------------------------------------------------- */
1facf9fc 14853+
4a4d8108 14854+static int hn_xino(struct inode *inode, struct inode *h_inode)
1facf9fc 14855+{
4a4d8108
AM
14856+ int err;
14857+ aufs_bindex_t bindex, bend, bfound, bstart;
14858+ struct inode *h_i;
1facf9fc 14859+
4a4d8108
AM
14860+ err = 0;
14861+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14862+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14863+ goto out;
14864+ }
1facf9fc 14865+
4a4d8108
AM
14866+ bfound = -1;
14867+ bend = au_ibend(inode);
14868+ bstart = au_ibstart(inode);
14869+#if 0 /* reserved for future use */
14870+ if (bindex == bend) {
14871+ /* keep this ino in rename case */
14872+ goto out;
14873+ }
14874+#endif
14875+ for (bindex = bstart; bindex <= bend; bindex++)
14876+ if (au_h_iptr(inode, bindex) == h_inode) {
14877+ bfound = bindex;
14878+ break;
14879+ }
14880+ if (bfound < 0)
1308ab2a 14881+ goto out;
1facf9fc 14882+
4a4d8108
AM
14883+ for (bindex = bstart; bindex <= bend; bindex++) {
14884+ h_i = au_h_iptr(inode, bindex);
14885+ if (!h_i)
14886+ continue;
1facf9fc 14887+
4a4d8108
AM
14888+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0);
14889+ /* ignore this error */
14890+ /* bad action? */
1facf9fc 14891+ }
1facf9fc 14892+
4a4d8108 14893+ /* children inode number will be broken */
1facf9fc 14894+
4f0767ce 14895+out:
4a4d8108
AM
14896+ AuTraceErr(err);
14897+ return err;
1facf9fc 14898+}
14899+
4a4d8108 14900+static int hn_gen_tree(struct dentry *dentry)
1facf9fc 14901+{
4a4d8108
AM
14902+ int err, i, j, ndentry;
14903+ struct au_dcsub_pages dpages;
14904+ struct au_dpage *dpage;
14905+ struct dentry **dentries;
1facf9fc 14906+
4a4d8108
AM
14907+ err = au_dpages_init(&dpages, GFP_NOFS);
14908+ if (unlikely(err))
14909+ goto out;
14910+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL);
14911+ if (unlikely(err))
14912+ goto out_dpages;
1facf9fc 14913+
4a4d8108
AM
14914+ for (i = 0; i < dpages.ndpage; i++) {
14915+ dpage = dpages.dpages + i;
14916+ dentries = dpage->dentries;
14917+ ndentry = dpage->ndentry;
14918+ for (j = 0; j < ndentry; j++) {
14919+ struct dentry *d;
14920+
14921+ d = dentries[j];
14922+ if (IS_ROOT(d))
14923+ continue;
14924+
4a4d8108
AM
14925+ au_digen_dec(d);
14926+ if (d->d_inode)
14927+ /* todo: reset children xino?
14928+ cached children only? */
14929+ au_iigen_dec(d->d_inode);
1308ab2a 14930+ }
dece6358 14931+ }
1facf9fc 14932+
4f0767ce 14933+out_dpages:
4a4d8108 14934+ au_dpages_free(&dpages);
dece6358 14935+
027c5e7a 14936+#if 0
4a4d8108
AM
14937+ /* discard children */
14938+ dentry_unhash(dentry);
14939+ dput(dentry);
027c5e7a 14940+#endif
4f0767ce 14941+out:
dece6358
AM
14942+ return err;
14943+}
14944+
1308ab2a 14945+/*
4a4d8108 14946+ * return 0 if processed.
1308ab2a 14947+ */
4a4d8108
AM
14948+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode,
14949+ const unsigned int isdir)
dece6358 14950+{
1308ab2a 14951+ int err;
4a4d8108
AM
14952+ struct dentry *d;
14953+ struct qstr *dname;
1facf9fc 14954+
4a4d8108
AM
14955+ err = 1;
14956+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 14957+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
14958+ err = 0;
14959+ goto out;
14960+ }
dece6358 14961+
4a4d8108
AM
14962+ if (!isdir) {
14963+ AuDebugOn(!name);
14964+ au_iigen_dec(inode);
027c5e7a 14965+ spin_lock(&inode->i_lock);
c1595e42 14966+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) {
027c5e7a 14967+ spin_lock(&d->d_lock);
4a4d8108
AM
14968+ dname = &d->d_name;
14969+ if (dname->len != nlen
027c5e7a
AM
14970+ && memcmp(dname->name, name, nlen)) {
14971+ spin_unlock(&d->d_lock);
4a4d8108 14972+ continue;
027c5e7a 14973+ }
4a4d8108 14974+ err = 0;
4a4d8108
AM
14975+ au_digen_dec(d);
14976+ spin_unlock(&d->d_lock);
14977+ break;
1facf9fc 14978+ }
027c5e7a 14979+ spin_unlock(&inode->i_lock);
1308ab2a 14980+ } else {
027c5e7a 14981+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR);
c1595e42 14982+ d = d_find_any_alias(inode);
4a4d8108
AM
14983+ if (!d) {
14984+ au_iigen_dec(inode);
14985+ goto out;
14986+ }
1facf9fc 14987+
027c5e7a 14988+ spin_lock(&d->d_lock);
4a4d8108 14989+ dname = &d->d_name;
027c5e7a
AM
14990+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) {
14991+ spin_unlock(&d->d_lock);
4a4d8108 14992+ err = hn_gen_tree(d);
027c5e7a
AM
14993+ spin_lock(&d->d_lock);
14994+ }
14995+ spin_unlock(&d->d_lock);
4a4d8108
AM
14996+ dput(d);
14997+ }
1facf9fc 14998+
4f0767ce 14999+out:
4a4d8108 15000+ AuTraceErr(err);
1308ab2a 15001+ return err;
15002+}
dece6358 15003+
4a4d8108 15004+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir)
1facf9fc 15005+{
4a4d8108
AM
15006+ int err;
15007+ struct inode *inode;
1facf9fc 15008+
4a4d8108
AM
15009+ inode = dentry->d_inode;
15010+ if (IS_ROOT(dentry)
15011+ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */
15012+ ) {
0c3ec466 15013+ pr_warn("branch root dir was changed\n");
4a4d8108
AM
15014+ return 0;
15015+ }
1308ab2a 15016+
4a4d8108
AM
15017+ err = 0;
15018+ if (!isdir) {
4a4d8108
AM
15019+ au_digen_dec(dentry);
15020+ if (inode)
15021+ au_iigen_dec(inode);
15022+ } else {
027c5e7a 15023+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR);
4a4d8108
AM
15024+ if (inode)
15025+ err = hn_gen_tree(dentry);
15026+ }
15027+
15028+ AuTraceErr(err);
15029+ return err;
1facf9fc 15030+}
15031+
4a4d8108 15032+/* ---------------------------------------------------------------------- */
1facf9fc 15033+
4a4d8108
AM
15034+/* hnotify job flags */
15035+#define AuHnJob_XINO0 1
15036+#define AuHnJob_GEN (1 << 1)
15037+#define AuHnJob_DIRENT (1 << 2)
15038+#define AuHnJob_ISDIR (1 << 3)
15039+#define AuHnJob_TRYXINO0 (1 << 4)
15040+#define AuHnJob_MNTPNT (1 << 5)
15041+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name)
7f207e10
AM
15042+#define au_fset_hnjob(flags, name) \
15043+ do { (flags) |= AuHnJob_##name; } while (0)
15044+#define au_fclr_hnjob(flags, name) \
15045+ do { (flags) &= ~AuHnJob_##name; } while (0)
1facf9fc 15046+
4a4d8108
AM
15047+enum {
15048+ AuHn_CHILD,
15049+ AuHn_PARENT,
15050+ AuHnLast
15051+};
1facf9fc 15052+
4a4d8108
AM
15053+struct au_hnotify_args {
15054+ struct inode *h_dir, *dir, *h_child_inode;
15055+ u32 mask;
15056+ unsigned int flags[AuHnLast];
15057+ unsigned int h_child_nlen;
15058+ char h_child_name[];
15059+};
1facf9fc 15060+
4a4d8108
AM
15061+struct hn_job_args {
15062+ unsigned int flags;
15063+ struct inode *inode, *h_inode, *dir, *h_dir;
15064+ struct dentry *dentry;
15065+ char *h_name;
15066+ int h_nlen;
15067+};
1308ab2a 15068+
4a4d8108
AM
15069+static int hn_job(struct hn_job_args *a)
15070+{
15071+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR);
076b876e 15072+ int e;
1308ab2a 15073+
4a4d8108
AM
15074+ /* reset xino */
15075+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode)
15076+ hn_xino(a->inode, a->h_inode); /* ignore this error */
1308ab2a 15077+
4a4d8108
AM
15078+ if (au_ftest_hnjob(a->flags, TRYXINO0)
15079+ && a->inode
15080+ && a->h_inode) {
15081+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
38d290e6
JR
15082+ if (!a->h_inode->i_nlink
15083+ && !(a->h_inode->i_state & I_LINKABLE))
4a4d8108
AM
15084+ hn_xino(a->inode, a->h_inode); /* ignore this error */
15085+ mutex_unlock(&a->h_inode->i_mutex);
1308ab2a 15086+ }
1facf9fc 15087+
4a4d8108
AM
15088+ /* make the generation obsolete */
15089+ if (au_ftest_hnjob(a->flags, GEN)) {
076b876e 15090+ e = -1;
4a4d8108 15091+ if (a->inode)
076b876e 15092+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode,
4a4d8108 15093+ isdir);
076b876e 15094+ if (e && a->dentry)
4a4d8108
AM
15095+ hn_gen_by_name(a->dentry, isdir);
15096+ /* ignore this error */
1facf9fc 15097+ }
1facf9fc 15098+
4a4d8108
AM
15099+ /* make dir entries obsolete */
15100+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) {
15101+ struct au_vdir *vdir;
1facf9fc 15102+
4a4d8108
AM
15103+ vdir = au_ivdir(a->inode);
15104+ if (vdir)
15105+ vdir->vd_jiffy = 0;
15106+ /* IMustLock(a->inode); */
15107+ /* a->inode->i_version++; */
15108+ }
1facf9fc 15109+
4a4d8108
AM
15110+ /* can do nothing but warn */
15111+ if (au_ftest_hnjob(a->flags, MNTPNT)
15112+ && a->dentry
15113+ && d_mountpoint(a->dentry))
523b37e3 15114+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry);
1facf9fc 15115+
4a4d8108 15116+ return 0;
1308ab2a 15117+}
1facf9fc 15118+
1308ab2a 15119+/* ---------------------------------------------------------------------- */
1facf9fc 15120+
4a4d8108
AM
15121+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen,
15122+ struct inode *dir)
1308ab2a 15123+{
4a4d8108
AM
15124+ struct dentry *dentry, *d, *parent;
15125+ struct qstr *dname;
1308ab2a 15126+
c1595e42 15127+ parent = d_find_any_alias(dir);
4a4d8108
AM
15128+ if (!parent)
15129+ return NULL;
1308ab2a 15130+
4a4d8108 15131+ dentry = NULL;
027c5e7a 15132+ spin_lock(&parent->d_lock);
c1595e42 15133+ list_for_each_entry(d, &parent->d_subdirs, d_child) {
523b37e3 15134+ /* AuDbg("%pd\n", d); */
027c5e7a 15135+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
4a4d8108
AM
15136+ dname = &d->d_name;
15137+ if (dname->len != nlen || memcmp(dname->name, name, nlen))
027c5e7a
AM
15138+ goto cont_unlock;
15139+ if (au_di(d))
15140+ au_digen_dec(d);
15141+ else
15142+ goto cont_unlock;
c1595e42 15143+ if (au_dcount(d) > 0) {
027c5e7a 15144+ dentry = dget_dlock(d);
4a4d8108 15145+ spin_unlock(&d->d_lock);
027c5e7a 15146+ break;
dece6358 15147+ }
1facf9fc 15148+
f6b6e03d 15149+cont_unlock:
027c5e7a 15150+ spin_unlock(&d->d_lock);
1308ab2a 15151+ }
027c5e7a 15152+ spin_unlock(&parent->d_lock);
4a4d8108 15153+ dput(parent);
1facf9fc 15154+
4a4d8108
AM
15155+ if (dentry)
15156+ di_write_lock_child(dentry);
1308ab2a 15157+
4a4d8108
AM
15158+ return dentry;
15159+}
dece6358 15160+
4a4d8108
AM
15161+static struct inode *lookup_wlock_by_ino(struct super_block *sb,
15162+ aufs_bindex_t bindex, ino_t h_ino)
15163+{
15164+ struct inode *inode;
15165+ ino_t ino;
15166+ int err;
15167+
15168+ inode = NULL;
15169+ err = au_xino_read(sb, bindex, h_ino, &ino);
15170+ if (!err && ino)
15171+ inode = ilookup(sb, ino);
15172+ if (!inode)
15173+ goto out;
15174+
15175+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) {
0c3ec466 15176+ pr_warn("wrong root branch\n");
4a4d8108
AM
15177+ iput(inode);
15178+ inode = NULL;
15179+ goto out;
1308ab2a 15180+ }
15181+
4a4d8108 15182+ ii_write_lock_child(inode);
1308ab2a 15183+
4f0767ce 15184+out:
4a4d8108 15185+ return inode;
dece6358
AM
15186+}
15187+
4a4d8108 15188+static void au_hn_bh(void *_args)
1facf9fc 15189+{
4a4d8108
AM
15190+ struct au_hnotify_args *a = _args;
15191+ struct super_block *sb;
15192+ aufs_bindex_t bindex, bend, bfound;
15193+ unsigned char xino, try_iput;
1facf9fc 15194+ int err;
1308ab2a 15195+ struct inode *inode;
4a4d8108
AM
15196+ ino_t h_ino;
15197+ struct hn_job_args args;
15198+ struct dentry *dentry;
15199+ struct au_sbinfo *sbinfo;
1facf9fc 15200+
4a4d8108
AM
15201+ AuDebugOn(!_args);
15202+ AuDebugOn(!a->h_dir);
15203+ AuDebugOn(!a->dir);
15204+ AuDebugOn(!a->mask);
15205+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n",
15206+ a->mask, a->dir->i_ino, a->h_dir->i_ino,
15207+ a->h_child_inode ? a->h_child_inode->i_ino : 0);
1facf9fc 15208+
4a4d8108
AM
15209+ inode = NULL;
15210+ dentry = NULL;
15211+ /*
15212+ * do not lock a->dir->i_mutex here
15213+ * because of d_revalidate() may cause a deadlock.
15214+ */
15215+ sb = a->dir->i_sb;
15216+ AuDebugOn(!sb);
15217+ sbinfo = au_sbi(sb);
15218+ AuDebugOn(!sbinfo);
7f207e10 15219+ si_write_lock(sb, AuLock_NOPLMW);
1facf9fc 15220+
4a4d8108
AM
15221+ ii_read_lock_parent(a->dir);
15222+ bfound = -1;
15223+ bend = au_ibend(a->dir);
15224+ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++)
15225+ if (au_h_iptr(a->dir, bindex) == a->h_dir) {
15226+ bfound = bindex;
15227+ break;
15228+ }
15229+ ii_read_unlock(a->dir);
15230+ if (unlikely(bfound < 0))
15231+ goto out;
1facf9fc 15232+
4a4d8108
AM
15233+ xino = !!au_opt_test(au_mntflags(sb), XINO);
15234+ h_ino = 0;
15235+ if (a->h_child_inode)
15236+ h_ino = a->h_child_inode->i_ino;
1facf9fc 15237+
4a4d8108
AM
15238+ if (a->h_child_nlen
15239+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN)
15240+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT)))
15241+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen,
15242+ a->dir);
15243+ try_iput = 0;
15244+ if (dentry)
15245+ inode = dentry->d_inode;
15246+ if (xino && !inode && h_ino
15247+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0)
15248+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0)
15249+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
15250+ inode = lookup_wlock_by_ino(sb, bfound, h_ino);
15251+ try_iput = 1;
15252+ }
1facf9fc 15253+
4a4d8108
AM
15254+ args.flags = a->flags[AuHn_CHILD];
15255+ args.dentry = dentry;
15256+ args.inode = inode;
15257+ args.h_inode = a->h_child_inode;
15258+ args.dir = a->dir;
15259+ args.h_dir = a->h_dir;
15260+ args.h_name = a->h_child_name;
15261+ args.h_nlen = a->h_child_nlen;
15262+ err = hn_job(&args);
15263+ if (dentry) {
027c5e7a 15264+ if (au_di(dentry))
4a4d8108
AM
15265+ di_write_unlock(dentry);
15266+ dput(dentry);
15267+ }
15268+ if (inode && try_iput) {
15269+ ii_write_unlock(inode);
15270+ iput(inode);
15271+ }
1facf9fc 15272+
4a4d8108
AM
15273+ ii_write_lock_parent(a->dir);
15274+ args.flags = a->flags[AuHn_PARENT];
15275+ args.dentry = NULL;
15276+ args.inode = a->dir;
15277+ args.h_inode = a->h_dir;
15278+ args.dir = NULL;
15279+ args.h_dir = NULL;
15280+ args.h_name = NULL;
15281+ args.h_nlen = 0;
15282+ err = hn_job(&args);
15283+ ii_write_unlock(a->dir);
1facf9fc 15284+
4f0767ce 15285+out:
4a4d8108
AM
15286+ iput(a->h_child_inode);
15287+ iput(a->h_dir);
15288+ iput(a->dir);
027c5e7a
AM
15289+ si_write_unlock(sb);
15290+ au_nwt_done(&sbinfo->si_nowait);
1308ab2a 15291+ kfree(a);
dece6358 15292+}
1facf9fc 15293+
4a4d8108
AM
15294+/* ---------------------------------------------------------------------- */
15295+
15296+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
15297+ struct qstr *h_child_qstr, struct inode *h_child_inode)
dece6358 15298+{
4a4d8108 15299+ int err, len;
53392da6 15300+ unsigned int flags[AuHnLast], f;
4a4d8108
AM
15301+ unsigned char isdir, isroot, wh;
15302+ struct inode *dir;
15303+ struct au_hnotify_args *args;
15304+ char *p, *h_child_name;
dece6358 15305+
1308ab2a 15306+ err = 0;
4a4d8108
AM
15307+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode);
15308+ dir = igrab(hnotify->hn_aufs_inode);
15309+ if (!dir)
15310+ goto out;
1facf9fc 15311+
4a4d8108
AM
15312+ isroot = (dir->i_ino == AUFS_ROOT_INO);
15313+ wh = 0;
15314+ h_child_name = (void *)h_child_qstr->name;
15315+ len = h_child_qstr->len;
15316+ if (h_child_name) {
15317+ if (len > AUFS_WH_PFX_LEN
15318+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
15319+ h_child_name += AUFS_WH_PFX_LEN;
15320+ len -= AUFS_WH_PFX_LEN;
15321+ wh = 1;
15322+ }
1facf9fc 15323+ }
dece6358 15324+
4a4d8108
AM
15325+ isdir = 0;
15326+ if (h_child_inode)
15327+ isdir = !!S_ISDIR(h_child_inode->i_mode);
15328+ flags[AuHn_PARENT] = AuHnJob_ISDIR;
15329+ flags[AuHn_CHILD] = 0;
15330+ if (isdir)
15331+ flags[AuHn_CHILD] = AuHnJob_ISDIR;
15332+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT);
15333+ au_fset_hnjob(flags[AuHn_CHILD], GEN);
15334+ switch (mask & FS_EVENTS_POSS_ON_CHILD) {
15335+ case FS_MOVED_FROM:
15336+ case FS_MOVED_TO:
15337+ au_fset_hnjob(flags[AuHn_CHILD], XINO0);
15338+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15339+ /*FALLTHROUGH*/
15340+ case FS_CREATE:
fb47a38f 15341+ AuDebugOn(!h_child_name);
4a4d8108 15342+ break;
1facf9fc 15343+
4a4d8108
AM
15344+ case FS_DELETE:
15345+ /*
15346+ * aufs never be able to get this child inode.
15347+ * revalidation should be in d_revalidate()
15348+ * by checking i_nlink, i_generation or d_unhashed().
15349+ */
15350+ AuDebugOn(!h_child_name);
15351+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0);
15352+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT);
15353+ break;
dece6358 15354+
4a4d8108
AM
15355+ default:
15356+ AuDebugOn(1);
15357+ }
1308ab2a 15358+
4a4d8108
AM
15359+ if (wh)
15360+ h_child_inode = NULL;
1308ab2a 15361+
4a4d8108
AM
15362+ err = -ENOMEM;
15363+ /* iput() and kfree() will be called in au_hnotify() */
4a4d8108 15364+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS);
4a4d8108
AM
15365+ if (unlikely(!args)) {
15366+ AuErr1("no memory\n");
15367+ iput(dir);
15368+ goto out;
15369+ }
15370+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT];
15371+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD];
15372+ args->mask = mask;
15373+ args->dir = dir;
15374+ args->h_dir = igrab(h_dir);
15375+ if (h_child_inode)
15376+ h_child_inode = igrab(h_child_inode); /* can be NULL */
15377+ args->h_child_inode = h_child_inode;
15378+ args->h_child_nlen = len;
15379+ if (len) {
15380+ p = (void *)args;
15381+ p += sizeof(*args);
15382+ memcpy(p, h_child_name, len);
15383+ p[len] = 0;
1308ab2a 15384+ }
1308ab2a 15385+
38d290e6 15386+ /* NFS fires the event for silly-renamed one from kworker */
53392da6 15387+ f = 0;
38d290e6
JR
15388+ if (!dir->i_nlink
15389+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE)))
53392da6
AM
15390+ f = AuWkq_NEST;
15391+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f);
4a4d8108
AM
15392+ if (unlikely(err)) {
15393+ pr_err("wkq %d\n", err);
15394+ iput(args->h_child_inode);
15395+ iput(args->h_dir);
15396+ iput(args->dir);
15397+ kfree(args);
1facf9fc 15398+ }
1facf9fc 15399+
4a4d8108 15400+out:
1facf9fc 15401+ return err;
15402+}
15403+
027c5e7a
AM
15404+/* ---------------------------------------------------------------------- */
15405+
15406+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm)
15407+{
15408+ int err;
15409+
15410+ AuDebugOn(!(udba & AuOptMask_UDBA));
15411+
15412+ err = 0;
15413+ if (au_hnotify_op.reset_br)
15414+ err = au_hnotify_op.reset_br(udba, br, perm);
15415+
15416+ return err;
15417+}
15418+
15419+int au_hnotify_init_br(struct au_branch *br, int perm)
15420+{
15421+ int err;
15422+
15423+ err = 0;
15424+ if (au_hnotify_op.init_br)
15425+ err = au_hnotify_op.init_br(br, perm);
15426+
15427+ return err;
15428+}
15429+
15430+void au_hnotify_fin_br(struct au_branch *br)
15431+{
15432+ if (au_hnotify_op.fin_br)
15433+ au_hnotify_op.fin_br(br);
15434+}
15435+
4a4d8108
AM
15436+static void au_hn_destroy_cache(void)
15437+{
15438+ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
15439+ au_cachep[AuCache_HNOTIFY] = NULL;
15440+}
1308ab2a 15441+
4a4d8108 15442+int __init au_hnotify_init(void)
1facf9fc 15443+{
1308ab2a 15444+ int err;
1308ab2a 15445+
4a4d8108
AM
15446+ err = -ENOMEM;
15447+ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
15448+ if (au_cachep[AuCache_HNOTIFY]) {
027c5e7a
AM
15449+ err = 0;
15450+ if (au_hnotify_op.init)
15451+ err = au_hnotify_op.init();
4a4d8108
AM
15452+ if (unlikely(err))
15453+ au_hn_destroy_cache();
1308ab2a 15454+ }
1308ab2a 15455+ AuTraceErr(err);
4a4d8108 15456+ return err;
1308ab2a 15457+}
15458+
4a4d8108 15459+void au_hnotify_fin(void)
1308ab2a 15460+{
027c5e7a
AM
15461+ if (au_hnotify_op.fin)
15462+ au_hnotify_op.fin();
4a4d8108
AM
15463+ /* cf. au_cache_fin() */
15464+ if (au_cachep[AuCache_HNOTIFY])
15465+ au_hn_destroy_cache();
dece6358 15466+}
7f207e10
AM
15467diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
15468--- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 15469+++ linux/fs/aufs/iinfo.c 2015-01-25 13:00:38.631047076 +0100
38d290e6 15470@@ -0,0 +1,277 @@
dece6358 15471+/*
523b37e3 15472+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
15473+ *
15474+ * This program, aufs is free software; you can redistribute it and/or modify
15475+ * it under the terms of the GNU General Public License as published by
15476+ * the Free Software Foundation; either version 2 of the License, or
15477+ * (at your option) any later version.
15478+ *
15479+ * This program is distributed in the hope that it will be useful,
15480+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15481+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15482+ * GNU General Public License for more details.
15483+ *
15484+ * You should have received a copy of the GNU General Public License
523b37e3 15485+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358 15486+ */
1facf9fc 15487+
dece6358 15488+/*
4a4d8108 15489+ * inode private data
dece6358 15490+ */
1facf9fc 15491+
1308ab2a 15492+#include "aufs.h"
1facf9fc 15493+
4a4d8108 15494+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 15495+{
4a4d8108 15496+ struct inode *h_inode;
1facf9fc 15497+
4a4d8108 15498+ IiMustAnyLock(inode);
1facf9fc 15499+
4a4d8108
AM
15500+ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode;
15501+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15502+ return h_inode;
15503+}
1facf9fc 15504+
4a4d8108
AM
15505+/* todo: hard/soft set? */
15506+void au_hiput(struct au_hinode *hinode)
15507+{
15508+ au_hn_free(hinode);
15509+ dput(hinode->hi_whdentry);
15510+ iput(hinode->hi_inode);
15511+}
1facf9fc 15512+
4a4d8108
AM
15513+unsigned int au_hi_flags(struct inode *inode, int isdir)
15514+{
15515+ unsigned int flags;
15516+ const unsigned int mnt_flags = au_mntflags(inode->i_sb);
1facf9fc 15517+
4a4d8108
AM
15518+ flags = 0;
15519+ if (au_opt_test(mnt_flags, XINO))
15520+ au_fset_hi(flags, XINO);
15521+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY))
15522+ au_fset_hi(flags, HNOTIFY);
15523+ return flags;
1facf9fc 15524+}
15525+
4a4d8108
AM
15526+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
15527+ struct inode *h_inode, unsigned int flags)
1308ab2a 15528+{
4a4d8108
AM
15529+ struct au_hinode *hinode;
15530+ struct inode *hi;
15531+ struct au_iinfo *iinfo = au_ii(inode);
1facf9fc 15532+
4a4d8108 15533+ IiMustWriteLock(inode);
dece6358 15534+
4a4d8108
AM
15535+ hinode = iinfo->ii_hinode + bindex;
15536+ hi = hinode->hi_inode;
15537+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0);
15538+
15539+ if (hi)
15540+ au_hiput(hinode);
15541+ hinode->hi_inode = h_inode;
15542+ if (h_inode) {
15543+ int err;
15544+ struct super_block *sb = inode->i_sb;
15545+ struct au_branch *br;
15546+
027c5e7a
AM
15547+ AuDebugOn(inode->i_mode
15548+ && (h_inode->i_mode & S_IFMT)
15549+ != (inode->i_mode & S_IFMT));
4a4d8108
AM
15550+ if (bindex == iinfo->ii_bstart)
15551+ au_cpup_igen(inode, h_inode);
15552+ br = au_sbr(sb, bindex);
15553+ hinode->hi_id = br->br_id;
15554+ if (au_ftest_hi(flags, XINO)) {
15555+ err = au_xino_write(sb, bindex, h_inode->i_ino,
15556+ inode->i_ino);
15557+ if (unlikely(err))
15558+ AuIOErr1("failed au_xino_write() %d\n", err);
15559+ }
15560+
15561+ if (au_ftest_hi(flags, HNOTIFY)
15562+ && au_br_hnotifyable(br->br_perm)) {
027c5e7a 15563+ err = au_hn_alloc(hinode, inode);
4a4d8108
AM
15564+ if (unlikely(err))
15565+ AuIOErr1("au_hn_alloc() %d\n", err);
1308ab2a 15566+ }
15567+ }
4a4d8108 15568+}
dece6358 15569+
4a4d8108
AM
15570+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
15571+ struct dentry *h_wh)
15572+{
15573+ struct au_hinode *hinode;
dece6358 15574+
4a4d8108
AM
15575+ IiMustWriteLock(inode);
15576+
15577+ hinode = au_ii(inode)->ii_hinode + bindex;
15578+ AuDebugOn(hinode->hi_whdentry);
15579+ hinode->hi_whdentry = h_wh;
1facf9fc 15580+}
15581+
537831f9 15582+void au_update_iigen(struct inode *inode, int half)
1308ab2a 15583+{
537831f9
AM
15584+ struct au_iinfo *iinfo;
15585+ struct au_iigen *iigen;
15586+ unsigned int sigen;
15587+
15588+ sigen = au_sigen(inode->i_sb);
15589+ iinfo = au_ii(inode);
15590+ iigen = &iinfo->ii_generation;
15591+ spin_lock(&iinfo->ii_genspin);
15592+ iigen->ig_generation = sigen;
15593+ if (half)
15594+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED);
15595+ else
15596+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED);
15597+ spin_unlock(&iinfo->ii_genspin);
4a4d8108 15598+}
1facf9fc 15599+
4a4d8108
AM
15600+/* it may be called at remount time, too */
15601+void au_update_ibrange(struct inode *inode, int do_put_zero)
15602+{
15603+ struct au_iinfo *iinfo;
027c5e7a 15604+ aufs_bindex_t bindex, bend;
1facf9fc 15605+
4a4d8108 15606+ iinfo = au_ii(inode);
027c5e7a 15607+ if (!iinfo)
4a4d8108 15608+ return;
1facf9fc 15609+
4a4d8108 15610+ IiMustWriteLock(inode);
1facf9fc 15611+
027c5e7a 15612+ if (do_put_zero && iinfo->ii_bstart >= 0) {
4a4d8108
AM
15613+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15614+ bindex++) {
15615+ struct inode *h_i;
1facf9fc 15616+
4a4d8108 15617+ h_i = iinfo->ii_hinode[0 + bindex].hi_inode;
38d290e6
JR
15618+ if (h_i
15619+ && !h_i->i_nlink
15620+ && !(h_i->i_state & I_LINKABLE))
027c5e7a
AM
15621+ au_set_h_iptr(inode, bindex, NULL, 0);
15622+ }
4a4d8108
AM
15623+ }
15624+
027c5e7a
AM
15625+ iinfo->ii_bstart = -1;
15626+ iinfo->ii_bend = -1;
15627+ bend = au_sbend(inode->i_sb);
15628+ for (bindex = 0; bindex <= bend; bindex++)
15629+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15630+ iinfo->ii_bstart = bindex;
4a4d8108 15631+ break;
027c5e7a
AM
15632+ }
15633+ if (iinfo->ii_bstart >= 0)
15634+ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--)
15635+ if (iinfo->ii_hinode[0 + bindex].hi_inode) {
15636+ iinfo->ii_bend = bindex;
15637+ break;
15638+ }
15639+ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend);
1308ab2a 15640+}
1facf9fc 15641+
dece6358 15642+/* ---------------------------------------------------------------------- */
1facf9fc 15643+
4a4d8108 15644+void au_icntnr_init_once(void *_c)
dece6358 15645+{
4a4d8108
AM
15646+ struct au_icntnr *c = _c;
15647+ struct au_iinfo *iinfo = &c->iinfo;
e49829fe 15648+ static struct lock_class_key aufs_ii;
1facf9fc 15649+
537831f9 15650+ spin_lock_init(&iinfo->ii_genspin);
4a4d8108 15651+ au_rw_init(&iinfo->ii_rwsem);
e49829fe 15652+ au_rw_class(&iinfo->ii_rwsem, &aufs_ii);
4a4d8108
AM
15653+ inode_init_once(&c->vfs_inode);
15654+}
1facf9fc 15655+
4a4d8108
AM
15656+int au_iinfo_init(struct inode *inode)
15657+{
15658+ struct au_iinfo *iinfo;
15659+ struct super_block *sb;
15660+ int nbr, i;
1facf9fc 15661+
4a4d8108
AM
15662+ sb = inode->i_sb;
15663+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
15664+ nbr = au_sbend(sb) + 1;
15665+ if (unlikely(nbr <= 0))
15666+ nbr = 1;
15667+ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
15668+ if (iinfo->ii_hinode) {
7f207e10 15669+ au_ninodes_inc(sb);
4a4d8108
AM
15670+ for (i = 0; i < nbr; i++)
15671+ iinfo->ii_hinode[i].hi_id = -1;
1facf9fc 15672+
537831f9 15673+ iinfo->ii_generation.ig_generation = au_sigen(sb);
4a4d8108
AM
15674+ iinfo->ii_bstart = -1;
15675+ iinfo->ii_bend = -1;
15676+ iinfo->ii_vdir = NULL;
15677+ return 0;
1308ab2a 15678+ }
4a4d8108
AM
15679+ return -ENOMEM;
15680+}
1facf9fc 15681+
4a4d8108
AM
15682+int au_ii_realloc(struct au_iinfo *iinfo, int nbr)
15683+{
15684+ int err, sz;
15685+ struct au_hinode *hip;
1facf9fc 15686+
4a4d8108
AM
15687+ AuRwMustWriteLock(&iinfo->ii_rwsem);
15688+
15689+ err = -ENOMEM;
15690+ sz = sizeof(*hip) * (iinfo->ii_bend + 1);
15691+ if (!sz)
15692+ sz = sizeof(*hip);
15693+ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS);
15694+ if (hip) {
15695+ iinfo->ii_hinode = hip;
15696+ err = 0;
1308ab2a 15697+ }
4a4d8108 15698+
1308ab2a 15699+ return err;
1facf9fc 15700+}
15701+
4a4d8108 15702+void au_iinfo_fin(struct inode *inode)
1facf9fc 15703+{
4a4d8108
AM
15704+ struct au_iinfo *iinfo;
15705+ struct au_hinode *hi;
15706+ struct super_block *sb;
b752ccd1
AM
15707+ aufs_bindex_t bindex, bend;
15708+ const unsigned char unlinked = !inode->i_nlink;
1308ab2a 15709+
4a4d8108
AM
15710+ iinfo = au_ii(inode);
15711+ /* bad_inode case */
15712+ if (!iinfo)
15713+ return;
1308ab2a 15714+
b752ccd1 15715+ sb = inode->i_sb;
7f207e10 15716+ au_ninodes_dec(sb);
b752ccd1
AM
15717+ if (si_pid_test(sb))
15718+ au_xino_delete_inode(inode, unlinked);
15719+ else {
15720+ /*
15721+ * it is safe to hide the dependency between sbinfo and
15722+ * sb->s_umount.
15723+ */
15724+ lockdep_off();
15725+ si_noflush_read_lock(sb);
15726+ au_xino_delete_inode(inode, unlinked);
15727+ si_read_unlock(sb);
15728+ lockdep_on();
15729+ }
15730+
4a4d8108
AM
15731+ if (iinfo->ii_vdir)
15732+ au_vdir_free(iinfo->ii_vdir);
1308ab2a 15733+
b752ccd1
AM
15734+ bindex = iinfo->ii_bstart;
15735+ if (bindex >= 0) {
15736+ hi = iinfo->ii_hinode + bindex;
4a4d8108 15737+ bend = iinfo->ii_bend;
b752ccd1
AM
15738+ while (bindex++ <= bend) {
15739+ if (hi->hi_inode)
4a4d8108 15740+ au_hiput(hi);
4a4d8108
AM
15741+ hi++;
15742+ }
15743+ }
4a4d8108 15744+ kfree(iinfo->ii_hinode);
027c5e7a 15745+ iinfo->ii_hinode = NULL;
4a4d8108 15746+ AuRwDestroy(&iinfo->ii_rwsem);
dece6358 15747+}
7f207e10
AM
15748diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
15749--- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
15750+++ linux/fs/aufs/inode.c 2015-01-25 13:00:38.631047076 +0100
15751@@ -0,0 +1,496 @@
4a4d8108 15752+/*
523b37e3 15753+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
15754+ *
15755+ * This program, aufs is free software; you can redistribute it and/or modify
15756+ * it under the terms of the GNU General Public License as published by
15757+ * the Free Software Foundation; either version 2 of the License, or
15758+ * (at your option) any later version.
15759+ *
15760+ * This program is distributed in the hope that it will be useful,
15761+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15762+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15763+ * GNU General Public License for more details.
15764+ *
15765+ * You should have received a copy of the GNU General Public License
523b37e3 15766+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 15767+ */
1facf9fc 15768+
4a4d8108
AM
15769+/*
15770+ * inode functions
15771+ */
1facf9fc 15772+
4a4d8108 15773+#include "aufs.h"
1308ab2a 15774+
4a4d8108
AM
15775+struct inode *au_igrab(struct inode *inode)
15776+{
15777+ if (inode) {
15778+ AuDebugOn(!atomic_read(&inode->i_count));
027c5e7a 15779+ ihold(inode);
1facf9fc 15780+ }
4a4d8108
AM
15781+ return inode;
15782+}
1facf9fc 15783+
4a4d8108
AM
15784+static void au_refresh_hinode_attr(struct inode *inode, int do_version)
15785+{
15786+ au_cpup_attr_all(inode, /*force*/0);
537831f9 15787+ au_update_iigen(inode, /*half*/1);
4a4d8108
AM
15788+ if (do_version)
15789+ inode->i_version++;
dece6358 15790+}
1facf9fc 15791+
027c5e7a 15792+static int au_ii_refresh(struct inode *inode, int *update)
dece6358 15793+{
4a4d8108 15794+ int err, e;
027c5e7a 15795+ umode_t type;
4a4d8108 15796+ aufs_bindex_t bindex, new_bindex;
1308ab2a 15797+ struct super_block *sb;
4a4d8108 15798+ struct au_iinfo *iinfo;
027c5e7a 15799+ struct au_hinode *p, *q, tmp;
1facf9fc 15800+
4a4d8108 15801+ IiMustWriteLock(inode);
1facf9fc 15802+
027c5e7a 15803+ *update = 0;
4a4d8108 15804+ sb = inode->i_sb;
027c5e7a 15805+ type = inode->i_mode & S_IFMT;
4a4d8108
AM
15806+ iinfo = au_ii(inode);
15807+ err = au_ii_realloc(iinfo, au_sbend(sb) + 1);
15808+ if (unlikely(err))
1308ab2a 15809+ goto out;
1facf9fc 15810+
027c5e7a 15811+ AuDebugOn(iinfo->ii_bstart < 0);
4a4d8108 15812+ p = iinfo->ii_hinode + iinfo->ii_bstart;
4a4d8108
AM
15813+ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend;
15814+ bindex++, p++) {
15815+ if (!p->hi_inode)
15816+ continue;
1facf9fc 15817+
027c5e7a 15818+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT));
4a4d8108
AM
15819+ new_bindex = au_br_index(sb, p->hi_id);
15820+ if (new_bindex == bindex)
15821+ continue;
1facf9fc 15822+
4a4d8108 15823+ if (new_bindex < 0) {
027c5e7a 15824+ *update = 1;
4a4d8108
AM
15825+ au_hiput(p);
15826+ p->hi_inode = NULL;
15827+ continue;
1308ab2a 15828+ }
4a4d8108
AM
15829+
15830+ if (new_bindex < iinfo->ii_bstart)
15831+ iinfo->ii_bstart = new_bindex;
15832+ if (iinfo->ii_bend < new_bindex)
15833+ iinfo->ii_bend = new_bindex;
15834+ /* swap two lower inode, and loop again */
15835+ q = iinfo->ii_hinode + new_bindex;
15836+ tmp = *q;
15837+ *q = *p;
15838+ *p = tmp;
15839+ if (tmp.hi_inode) {
15840+ bindex--;
15841+ p--;
1308ab2a 15842+ }
15843+ }
4a4d8108
AM
15844+ au_update_ibrange(inode, /*do_put_zero*/0);
15845+ e = au_dy_irefresh(inode);
15846+ if (unlikely(e && !err))
15847+ err = e;
1facf9fc 15848+
4f0767ce 15849+out:
027c5e7a
AM
15850+ AuTraceErr(err);
15851+ return err;
15852+}
15853+
15854+int au_refresh_hinode_self(struct inode *inode)
15855+{
15856+ int err, update;
15857+
15858+ err = au_ii_refresh(inode, &update);
15859+ if (!err)
15860+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode));
15861+
15862+ AuTraceErr(err);
4a4d8108
AM
15863+ return err;
15864+}
1facf9fc 15865+
4a4d8108
AM
15866+int au_refresh_hinode(struct inode *inode, struct dentry *dentry)
15867+{
027c5e7a 15868+ int err, e, update;
4a4d8108 15869+ unsigned int flags;
027c5e7a 15870+ umode_t mode;
4a4d8108 15871+ aufs_bindex_t bindex, bend;
027c5e7a 15872+ unsigned char isdir;
4a4d8108
AM
15873+ struct au_hinode *p;
15874+ struct au_iinfo *iinfo;
1facf9fc 15875+
027c5e7a 15876+ err = au_ii_refresh(inode, &update);
4a4d8108
AM
15877+ if (unlikely(err))
15878+ goto out;
15879+
15880+ update = 0;
15881+ iinfo = au_ii(inode);
15882+ p = iinfo->ii_hinode + iinfo->ii_bstart;
027c5e7a
AM
15883+ mode = (inode->i_mode & S_IFMT);
15884+ isdir = S_ISDIR(mode);
4a4d8108
AM
15885+ flags = au_hi_flags(inode, isdir);
15886+ bend = au_dbend(dentry);
15887+ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) {
15888+ struct inode *h_i;
15889+ struct dentry *h_d;
15890+
15891+ h_d = au_h_dptr(dentry, bindex);
15892+ if (!h_d || !h_d->d_inode)
15893+ continue;
15894+
027c5e7a 15895+ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT));
4a4d8108
AM
15896+ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) {
15897+ h_i = au_h_iptr(inode, bindex);
15898+ if (h_i) {
15899+ if (h_i == h_d->d_inode)
15900+ continue;
15901+ err = -EIO;
15902+ break;
15903+ }
15904+ }
15905+ if (bindex < iinfo->ii_bstart)
15906+ iinfo->ii_bstart = bindex;
15907+ if (iinfo->ii_bend < bindex)
15908+ iinfo->ii_bend = bindex;
15909+ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags);
15910+ update = 1;
1308ab2a 15911+ }
4a4d8108
AM
15912+ au_update_ibrange(inode, /*do_put_zero*/0);
15913+ e = au_dy_irefresh(inode);
15914+ if (unlikely(e && !err))
15915+ err = e;
027c5e7a
AM
15916+ if (!err)
15917+ au_refresh_hinode_attr(inode, update && isdir);
4a4d8108 15918+
4f0767ce 15919+out:
4a4d8108 15920+ AuTraceErr(err);
1308ab2a 15921+ return err;
dece6358
AM
15922+}
15923+
4a4d8108 15924+static int set_inode(struct inode *inode, struct dentry *dentry)
dece6358 15925+{
4a4d8108
AM
15926+ int err;
15927+ unsigned int flags;
15928+ umode_t mode;
15929+ aufs_bindex_t bindex, bstart, btail;
15930+ unsigned char isdir;
15931+ struct dentry *h_dentry;
15932+ struct inode *h_inode;
15933+ struct au_iinfo *iinfo;
dece6358 15934+
4a4d8108 15935+ IiMustWriteLock(inode);
dece6358 15936+
4a4d8108
AM
15937+ err = 0;
15938+ isdir = 0;
15939+ bstart = au_dbstart(dentry);
15940+ h_inode = au_h_dptr(dentry, bstart)->d_inode;
15941+ mode = h_inode->i_mode;
15942+ switch (mode & S_IFMT) {
15943+ case S_IFREG:
15944+ btail = au_dbtail(dentry);
15945+ inode->i_op = &aufs_iop;
15946+ inode->i_fop = &aufs_file_fop;
15947+ err = au_dy_iaop(inode, bstart, h_inode);
15948+ if (unlikely(err))
15949+ goto out;
15950+ break;
15951+ case S_IFDIR:
15952+ isdir = 1;
15953+ btail = au_dbtaildir(dentry);
15954+ inode->i_op = &aufs_dir_iop;
15955+ inode->i_fop = &aufs_dir_fop;
15956+ break;
15957+ case S_IFLNK:
15958+ btail = au_dbtail(dentry);
15959+ inode->i_op = &aufs_symlink_iop;
15960+ break;
15961+ case S_IFBLK:
15962+ case S_IFCHR:
15963+ case S_IFIFO:
15964+ case S_IFSOCK:
15965+ btail = au_dbtail(dentry);
15966+ inode->i_op = &aufs_iop;
38d290e6 15967+ init_special_inode(inode, mode, h_inode->i_rdev);
4a4d8108
AM
15968+ break;
15969+ default:
15970+ AuIOErr("Unknown file type 0%o\n", mode);
15971+ err = -EIO;
1308ab2a 15972+ goto out;
4a4d8108 15973+ }
dece6358 15974+
4a4d8108
AM
15975+ /* do not set hnotify for whiteouted dirs (SHWH mode) */
15976+ flags = au_hi_flags(inode, isdir);
15977+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)
15978+ && au_ftest_hi(flags, HNOTIFY)
15979+ && dentry->d_name.len > AUFS_WH_PFX_LEN
15980+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
15981+ au_fclr_hi(flags, HNOTIFY);
15982+ iinfo = au_ii(inode);
15983+ iinfo->ii_bstart = bstart;
15984+ iinfo->ii_bend = btail;
15985+ for (bindex = bstart; bindex <= btail; bindex++) {
15986+ h_dentry = au_h_dptr(dentry, bindex);
15987+ if (h_dentry)
15988+ au_set_h_iptr(inode, bindex,
15989+ au_igrab(h_dentry->d_inode), flags);
15990+ }
15991+ au_cpup_attr_all(inode, /*force*/1);
c1595e42
JR
15992+ /*
15993+ * to force calling aufs_get_acl() every time,
15994+ * do not call cache_no_acl() for aufs inode.
15995+ */
dece6358 15996+
4f0767ce 15997+out:
4a4d8108
AM
15998+ return err;
15999+}
dece6358 16000+
027c5e7a
AM
16001+/*
16002+ * successful returns with iinfo write_locked
16003+ * minus: errno
16004+ * zero: success, matched
16005+ * plus: no error, but unmatched
16006+ */
16007+static int reval_inode(struct inode *inode, struct dentry *dentry)
4a4d8108
AM
16008+{
16009+ int err;
537831f9
AM
16010+ unsigned int gen;
16011+ struct au_iigen iigen;
4a4d8108
AM
16012+ aufs_bindex_t bindex, bend;
16013+ struct inode *h_inode, *h_dinode;
dece6358 16014+
4a4d8108
AM
16015+ /*
16016+ * before this function, if aufs got any iinfo lock, it must be only
16017+ * one, the parent dir.
16018+ * it can happen by UDBA and the obsoleted inode number.
16019+ */
16020+ err = -EIO;
16021+ if (unlikely(inode->i_ino == parent_ino(dentry)))
16022+ goto out;
16023+
027c5e7a 16024+ err = 1;
4a4d8108
AM
16025+ ii_write_lock_new_child(inode);
16026+ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode;
16027+ bend = au_ibend(inode);
16028+ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) {
16029+ h_inode = au_h_iptr(inode, bindex);
537831f9
AM
16030+ if (!h_inode || h_inode != h_dinode)
16031+ continue;
16032+
16033+ err = 0;
16034+ gen = au_iigen(inode, &iigen);
16035+ if (gen == au_digen(dentry)
16036+ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED))
4a4d8108 16037+ break;
537831f9
AM
16038+
16039+ /* fully refresh inode using dentry */
16040+ err = au_refresh_hinode(inode, dentry);
16041+ if (!err)
16042+ au_update_iigen(inode, /*half*/0);
16043+ break;
1facf9fc 16044+ }
dece6358 16045+
4a4d8108
AM
16046+ if (unlikely(err))
16047+ ii_write_unlock(inode);
4f0767ce 16048+out:
1facf9fc 16049+ return err;
16050+}
1facf9fc 16051+
4a4d8108
AM
16052+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16053+ unsigned int d_type, ino_t *ino)
1facf9fc 16054+{
4a4d8108
AM
16055+ int err;
16056+ struct mutex *mtx;
1facf9fc 16057+
b752ccd1 16058+ /* prevent hardlinked inode number from race condition */
4a4d8108 16059+ mtx = NULL;
b752ccd1 16060+ if (d_type != DT_DIR) {
4a4d8108
AM
16061+ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx;
16062+ mutex_lock(mtx);
16063+ }
16064+ err = au_xino_read(sb, bindex, h_ino, ino);
16065+ if (unlikely(err))
16066+ goto out;
1308ab2a 16067+
4a4d8108
AM
16068+ if (!*ino) {
16069+ err = -EIO;
16070+ *ino = au_xino_new_ino(sb);
16071+ if (unlikely(!*ino))
1facf9fc 16072+ goto out;
4a4d8108
AM
16073+ err = au_xino_write(sb, bindex, h_ino, *ino);
16074+ if (unlikely(err))
1308ab2a 16075+ goto out;
1308ab2a 16076+ }
1facf9fc 16077+
4f0767ce 16078+out:
b752ccd1 16079+ if (mtx)
4a4d8108 16080+ mutex_unlock(mtx);
1facf9fc 16081+ return err;
16082+}
16083+
4a4d8108
AM
16084+/* successful returns with iinfo write_locked */
16085+/* todo: return with unlocked? */
16086+struct inode *au_new_inode(struct dentry *dentry, int must_new)
1facf9fc 16087+{
b752ccd1 16088+ struct inode *inode, *h_inode;
4a4d8108
AM
16089+ struct dentry *h_dentry;
16090+ struct super_block *sb;
b752ccd1 16091+ struct mutex *mtx;
4a4d8108 16092+ ino_t h_ino, ino;
1716fcea 16093+ int err;
4a4d8108 16094+ aufs_bindex_t bstart;
1facf9fc 16095+
4a4d8108
AM
16096+ sb = dentry->d_sb;
16097+ bstart = au_dbstart(dentry);
16098+ h_dentry = au_h_dptr(dentry, bstart);
b752ccd1
AM
16099+ h_inode = h_dentry->d_inode;
16100+ h_ino = h_inode->i_ino;
16101+
16102+ /*
16103+ * stop 'race'-ing between hardlinks under different
16104+ * parents.
16105+ */
16106+ mtx = NULL;
16107+ if (!S_ISDIR(h_inode->i_mode))
16108+ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;
16109+
4f0767ce 16110+new_ino:
b752ccd1
AM
16111+ if (mtx)
16112+ mutex_lock(mtx);
4a4d8108
AM
16113+ err = au_xino_read(sb, bstart, h_ino, &ino);
16114+ inode = ERR_PTR(err);
16115+ if (unlikely(err))
16116+ goto out;
b752ccd1 16117+
4a4d8108
AM
16118+ if (!ino) {
16119+ ino = au_xino_new_ino(sb);
16120+ if (unlikely(!ino)) {
16121+ inode = ERR_PTR(-EIO);
dece6358
AM
16122+ goto out;
16123+ }
16124+ }
1facf9fc 16125+
4a4d8108
AM
16126+ AuDbg("i%lu\n", (unsigned long)ino);
16127+ inode = au_iget_locked(sb, ino);
16128+ err = PTR_ERR(inode);
16129+ if (IS_ERR(inode))
1facf9fc 16130+ goto out;
1facf9fc 16131+
4a4d8108
AM
16132+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
16133+ if (inode->i_state & I_NEW) {
1716fcea
AM
16134+ /* verbose coding for lock class name */
16135+ if (unlikely(S_ISLNK(h_inode->i_mode)))
16136+ au_rw_class(&au_ii(inode)->ii_rwsem,
16137+ au_lc_key + AuLcSymlink_IIINFO);
16138+ else if (unlikely(S_ISDIR(h_inode->i_mode)))
16139+ au_rw_class(&au_ii(inode)->ii_rwsem,
16140+ au_lc_key + AuLcDir_IIINFO);
16141+ else /* likely */
16142+ au_rw_class(&au_ii(inode)->ii_rwsem,
16143+ au_lc_key + AuLcNonDir_IIINFO);
2dfbb274 16144+
4a4d8108
AM
16145+ ii_write_lock_new_child(inode);
16146+ err = set_inode(inode, dentry);
16147+ if (!err) {
16148+ unlock_new_inode(inode);
16149+ goto out; /* success */
16150+ }
1308ab2a 16151+
027c5e7a
AM
16152+ /*
16153+ * iget_failed() calls iput(), but we need to call
16154+ * ii_write_unlock() after iget_failed(). so dirty hack for
16155+ * i_count.
16156+ */
16157+ atomic_inc(&inode->i_count);
4a4d8108 16158+ iget_failed(inode);
027c5e7a
AM
16159+ ii_write_unlock(inode);
16160+ au_xino_write(sb, bstart, h_ino, /*ino*/0);
16161+ /* ignore this error */
16162+ goto out_iput;
16163+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
b752ccd1
AM
16164+ /*
16165+ * horrible race condition between lookup, readdir and copyup
16166+ * (or something).
16167+ */
16168+ if (mtx)
16169+ mutex_unlock(mtx);
027c5e7a
AM
16170+ err = reval_inode(inode, dentry);
16171+ if (unlikely(err < 0)) {
16172+ mtx = NULL;
16173+ goto out_iput;
16174+ }
16175+
b752ccd1
AM
16176+ if (!err) {
16177+ mtx = NULL;
4a4d8108 16178+ goto out; /* success */
b752ccd1
AM
16179+ } else if (mtx)
16180+ mutex_lock(mtx);
4a4d8108
AM
16181+ }
16182+
16183+ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
16184+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
523b37e3
AM
16185+ " b%d, %s, %pd, hi%lu, i%lu.\n",
16186+ bstart, au_sbtype(h_dentry->d_sb), dentry,
4a4d8108
AM
16187+ (unsigned long)h_ino, (unsigned long)ino);
16188+ ino = 0;
16189+ err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
16190+ if (!err) {
16191+ iput(inode);
b752ccd1
AM
16192+ if (mtx)
16193+ mutex_unlock(mtx);
4a4d8108
AM
16194+ goto new_ino;
16195+ }
1308ab2a 16196+
4f0767ce 16197+out_iput:
4a4d8108 16198+ iput(inode);
4a4d8108 16199+ inode = ERR_PTR(err);
4f0767ce 16200+out:
b752ccd1
AM
16201+ if (mtx)
16202+ mutex_unlock(mtx);
4a4d8108 16203+ return inode;
1facf9fc 16204+}
16205+
4a4d8108 16206+/* ---------------------------------------------------------------------- */
1facf9fc 16207+
4a4d8108
AM
16208+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16209+ struct inode *inode)
16210+{
16211+ int err;
076b876e 16212+ struct inode *hi;
1facf9fc 16213+
4a4d8108 16214+ err = au_br_rdonly(au_sbr(sb, bindex));
1facf9fc 16215+
4a4d8108
AM
16216+ /* pseudo-link after flushed may happen out of bounds */
16217+ if (!err
16218+ && inode
16219+ && au_ibstart(inode) <= bindex
16220+ && bindex <= au_ibend(inode)) {
16221+ /*
16222+ * permission check is unnecessary since vfsub routine
16223+ * will be called later
16224+ */
076b876e 16225+ hi = au_h_iptr(inode, bindex);
4a4d8108
AM
16226+ if (hi)
16227+ err = IS_IMMUTABLE(hi) ? -EROFS : 0;
1facf9fc 16228+ }
16229+
4a4d8108
AM
16230+ return err;
16231+}
dece6358 16232+
4a4d8108
AM
16233+int au_test_h_perm(struct inode *h_inode, int mask)
16234+{
2dfbb274 16235+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
4a4d8108
AM
16236+ return 0;
16237+ return inode_permission(h_inode, mask);
16238+}
1facf9fc 16239+
4a4d8108
AM
16240+int au_test_h_perm_sio(struct inode *h_inode, int mask)
16241+{
16242+ if (au_test_nfs(h_inode->i_sb)
16243+ && (mask & MAY_WRITE)
16244+ && S_ISDIR(h_inode->i_mode))
16245+ mask |= MAY_READ; /* force permission check */
16246+ return au_test_h_perm(h_inode, mask);
1facf9fc 16247+}
7f207e10
AM
16248diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
16249--- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
16250+++ linux/fs/aufs/inode.h 2015-01-25 13:00:38.631047076 +0100
16251@@ -0,0 +1,667 @@
4a4d8108 16252+/*
523b37e3 16253+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
16254+ *
16255+ * This program, aufs is free software; you can redistribute it and/or modify
16256+ * it under the terms of the GNU General Public License as published by
16257+ * the Free Software Foundation; either version 2 of the License, or
16258+ * (at your option) any later version.
16259+ *
16260+ * This program is distributed in the hope that it will be useful,
16261+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16262+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16263+ * GNU General Public License for more details.
16264+ *
16265+ * You should have received a copy of the GNU General Public License
523b37e3 16266+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 16267+ */
1facf9fc 16268+
1308ab2a 16269+/*
4a4d8108 16270+ * inode operations
1308ab2a 16271+ */
dece6358 16272+
4a4d8108
AM
16273+#ifndef __AUFS_INODE_H__
16274+#define __AUFS_INODE_H__
dece6358 16275+
4a4d8108 16276+#ifdef __KERNEL__
1308ab2a 16277+
4a4d8108 16278+#include <linux/fsnotify.h>
4a4d8108 16279+#include "rwsem.h"
1308ab2a 16280+
4a4d8108 16281+struct vfsmount;
1facf9fc 16282+
4a4d8108
AM
16283+struct au_hnotify {
16284+#ifdef CONFIG_AUFS_HNOTIFY
16285+#ifdef CONFIG_AUFS_HFSNOTIFY
7f207e10 16286+ /* never use fsnotify_add_vfsmount_mark() */
0c5527e5 16287+ struct fsnotify_mark hn_mark;
4a4d8108 16288+#endif
7f207e10 16289+ struct inode *hn_aufs_inode; /* no get/put */
4a4d8108
AM
16290+#endif
16291+} ____cacheline_aligned_in_smp;
1facf9fc 16292+
4a4d8108
AM
16293+struct au_hinode {
16294+ struct inode *hi_inode;
16295+ aufs_bindex_t hi_id;
16296+#ifdef CONFIG_AUFS_HNOTIFY
16297+ struct au_hnotify *hi_notify;
16298+#endif
dece6358 16299+
4a4d8108
AM
16300+ /* reference to the copied-up whiteout with get/put */
16301+ struct dentry *hi_whdentry;
16302+};
dece6358 16303+
537831f9
AM
16304+/* ig_flags */
16305+#define AuIG_HALF_REFRESHED 1
16306+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name)
16307+#define au_ig_fset(flags, name) \
16308+ do { (flags) |= AuIG_##name; } while (0)
16309+#define au_ig_fclr(flags, name) \
16310+ do { (flags) &= ~AuIG_##name; } while (0)
16311+
16312+struct au_iigen {
16313+ __u32 ig_generation, ig_flags;
16314+};
16315+
4a4d8108
AM
16316+struct au_vdir;
16317+struct au_iinfo {
537831f9 16318+ spinlock_t ii_genspin;
7a9e40b8 16319+ struct au_iigen ii_generation;
4a4d8108 16320+ struct super_block *ii_hsb1; /* no get/put */
1facf9fc 16321+
4a4d8108
AM
16322+ struct au_rwsem ii_rwsem;
16323+ aufs_bindex_t ii_bstart, ii_bend;
16324+ __u32 ii_higen;
16325+ struct au_hinode *ii_hinode;
16326+ struct au_vdir *ii_vdir;
16327+};
1facf9fc 16328+
4a4d8108
AM
16329+struct au_icntnr {
16330+ struct au_iinfo iinfo;
16331+ struct inode vfs_inode;
16332+} ____cacheline_aligned_in_smp;
1308ab2a 16333+
4a4d8108
AM
16334+/* au_pin flags */
16335+#define AuPin_DI_LOCKED 1
16336+#define AuPin_MNT_WRITE (1 << 1)
16337+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name)
7f207e10
AM
16338+#define au_fset_pin(flags, name) \
16339+ do { (flags) |= AuPin_##name; } while (0)
16340+#define au_fclr_pin(flags, name) \
16341+ do { (flags) &= ~AuPin_##name; } while (0)
4a4d8108
AM
16342+
16343+struct au_pin {
16344+ /* input */
16345+ struct dentry *dentry;
16346+ unsigned int udba;
16347+ unsigned char lsc_di, lsc_hi, flags;
16348+ aufs_bindex_t bindex;
16349+
16350+ /* output */
16351+ struct dentry *parent;
16352+ struct au_hinode *hdir;
16353+ struct vfsmount *h_mnt;
86dc4139
AM
16354+
16355+ /* temporary unlock/relock for copyup */
16356+ struct dentry *h_dentry, *h_parent;
16357+ struct au_branch *br;
16358+ struct task_struct *task;
4a4d8108 16359+};
1facf9fc 16360+
86dc4139 16361+void au_pin_hdir_unlock(struct au_pin *p);
c1595e42 16362+int au_pin_hdir_lock(struct au_pin *p);
86dc4139
AM
16363+int au_pin_hdir_relock(struct au_pin *p);
16364+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task);
16365+void au_pin_hdir_acquire_nest(struct au_pin *p);
16366+void au_pin_hdir_release(struct au_pin *p);
16367+
1308ab2a 16368+/* ---------------------------------------------------------------------- */
16369+
4a4d8108 16370+static inline struct au_iinfo *au_ii(struct inode *inode)
1facf9fc 16371+{
4a4d8108 16372+ struct au_iinfo *iinfo;
1facf9fc 16373+
4a4d8108
AM
16374+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo);
16375+ if (iinfo->ii_hinode)
16376+ return iinfo;
16377+ return NULL; /* debugging bad_inode case */
16378+}
1facf9fc 16379+
4a4d8108 16380+/* ---------------------------------------------------------------------- */
1facf9fc 16381+
4a4d8108
AM
16382+/* inode.c */
16383+struct inode *au_igrab(struct inode *inode);
027c5e7a 16384+int au_refresh_hinode_self(struct inode *inode);
4a4d8108
AM
16385+int au_refresh_hinode(struct inode *inode, struct dentry *dentry);
16386+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
16387+ unsigned int d_type, ino_t *ino);
16388+struct inode *au_new_inode(struct dentry *dentry, int must_new);
16389+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
16390+ struct inode *inode);
16391+int au_test_h_perm(struct inode *h_inode, int mask);
16392+int au_test_h_perm_sio(struct inode *h_inode, int mask);
1facf9fc 16393+
4a4d8108
AM
16394+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex,
16395+ ino_t h_ino, unsigned int d_type, ino_t *ino)
16396+{
16397+#ifdef CONFIG_AUFS_SHWH
16398+ return au_ino(sb, bindex, h_ino, d_type, ino);
16399+#else
16400+ return 0;
16401+#endif
16402+}
1facf9fc 16403+
4a4d8108
AM
16404+/* i_op.c */
16405+extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
1308ab2a 16406+
4a4d8108
AM
16407+/* au_wr_dir flags */
16408+#define AuWrDir_ADD_ENTRY 1
86dc4139
AM
16409+#define AuWrDir_TMP_WHENTRY (1 << 1)
16410+#define AuWrDir_ISDIR (1 << 2)
38d290e6 16411+#define AuWrDir_TMPFILE (1 << 3)
4a4d8108 16412+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name)
7f207e10
AM
16413+#define au_fset_wrdir(flags, name) \
16414+ do { (flags) |= AuWrDir_##name; } while (0)
16415+#define au_fclr_wrdir(flags, name) \
16416+ do { (flags) &= ~AuWrDir_##name; } while (0)
1facf9fc 16417+
4a4d8108
AM
16418+struct au_wr_dir_args {
16419+ aufs_bindex_t force_btgt;
16420+ unsigned char flags;
16421+};
16422+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
16423+ struct au_wr_dir_args *args);
dece6358 16424+
4a4d8108
AM
16425+struct dentry *au_pinned_h_parent(struct au_pin *pin);
16426+void au_pin_init(struct au_pin *pin, struct dentry *dentry,
16427+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
16428+ unsigned int udba, unsigned char flags);
16429+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
16430+ unsigned int udba, unsigned char flags) __must_check;
16431+int au_do_pin(struct au_pin *pin) __must_check;
16432+void au_unpin(struct au_pin *pin);
c1595e42
JR
16433+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen);
16434+
16435+#define AuIcpup_DID_CPUP 1
16436+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name)
16437+#define au_fset_icpup(flags, name) \
16438+ do { (flags) |= AuIcpup_##name; } while (0)
16439+#define au_fclr_icpup(flags, name) \
16440+ do { (flags) &= ~AuIcpup_##name; } while (0)
16441+
16442+struct au_icpup_args {
16443+ unsigned char flags;
16444+ unsigned char pin_flags;
16445+ aufs_bindex_t btgt;
16446+ unsigned int udba;
16447+ struct au_pin pin;
16448+ struct path h_path;
16449+ struct inode *h_inode;
16450+};
16451+
16452+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
16453+ struct au_icpup_args *a);
16454+
16455+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path);
1facf9fc 16456+
4a4d8108
AM
16457+/* i_op_add.c */
16458+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
16459+ struct dentry *h_parent, int isdir);
7eafdf33
AM
16460+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
16461+ dev_t dev);
4a4d8108 16462+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
7eafdf33 16463+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 16464+ bool want_excl);
38d290e6 16465+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode);
4a4d8108
AM
16466+int aufs_link(struct dentry *src_dentry, struct inode *dir,
16467+ struct dentry *dentry);
7eafdf33 16468+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
1facf9fc 16469+
4a4d8108
AM
16470+/* i_op_del.c */
16471+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup);
16472+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
16473+ struct dentry *h_parent, int isdir);
16474+int aufs_unlink(struct inode *dir, struct dentry *dentry);
16475+int aufs_rmdir(struct inode *dir, struct dentry *dentry);
1308ab2a 16476+
4a4d8108
AM
16477+/* i_op_ren.c */
16478+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt);
16479+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry,
16480+ struct inode *dir, struct dentry *dentry);
1facf9fc 16481+
4a4d8108
AM
16482+/* iinfo.c */
16483+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex);
16484+void au_hiput(struct au_hinode *hinode);
16485+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex,
16486+ struct dentry *h_wh);
16487+unsigned int au_hi_flags(struct inode *inode, int isdir);
1308ab2a 16488+
4a4d8108
AM
16489+/* hinode flags */
16490+#define AuHi_XINO 1
16491+#define AuHi_HNOTIFY (1 << 1)
16492+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name)
7f207e10
AM
16493+#define au_fset_hi(flags, name) \
16494+ do { (flags) |= AuHi_##name; } while (0)
16495+#define au_fclr_hi(flags, name) \
16496+ do { (flags) &= ~AuHi_##name; } while (0)
1facf9fc 16497+
4a4d8108
AM
16498+#ifndef CONFIG_AUFS_HNOTIFY
16499+#undef AuHi_HNOTIFY
16500+#define AuHi_HNOTIFY 0
16501+#endif
1facf9fc 16502+
4a4d8108
AM
16503+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex,
16504+ struct inode *h_inode, unsigned int flags);
1facf9fc 16505+
537831f9 16506+void au_update_iigen(struct inode *inode, int half);
4a4d8108 16507+void au_update_ibrange(struct inode *inode, int do_put_zero);
1facf9fc 16508+
4a4d8108
AM
16509+void au_icntnr_init_once(void *_c);
16510+int au_iinfo_init(struct inode *inode);
16511+void au_iinfo_fin(struct inode *inode);
16512+int au_ii_realloc(struct au_iinfo *iinfo, int nbr);
1308ab2a 16513+
e49829fe 16514+#ifdef CONFIG_PROC_FS
4a4d8108 16515+/* plink.c */
e49829fe
JR
16516+int au_plink_maint(struct super_block *sb, int flags);
16517+void au_plink_maint_leave(struct au_sbinfo *sbinfo);
16518+int au_plink_maint_enter(struct super_block *sb);
4a4d8108
AM
16519+#ifdef CONFIG_AUFS_DEBUG
16520+void au_plink_list(struct super_block *sb);
16521+#else
16522+AuStubVoid(au_plink_list, struct super_block *sb)
16523+#endif
16524+int au_plink_test(struct inode *inode);
16525+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex);
16526+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
16527+ struct dentry *h_dentry);
e49829fe
JR
16528+void au_plink_put(struct super_block *sb, int verbose);
16529+void au_plink_clean(struct super_block *sb, int verbose);
4a4d8108 16530+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id);
e49829fe
JR
16531+#else
16532+AuStubInt0(au_plink_maint, struct super_block *sb, int flags);
16533+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo);
16534+AuStubInt0(au_plink_maint_enter, struct super_block *sb);
16535+AuStubVoid(au_plink_list, struct super_block *sb);
16536+AuStubInt0(au_plink_test, struct inode *inode);
16537+AuStub(struct dentry *, au_plink_lkup, return NULL,
16538+ struct inode *inode, aufs_bindex_t bindex);
16539+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex,
16540+ struct dentry *h_dentry);
16541+AuStubVoid(au_plink_put, struct super_block *sb, int verbose);
16542+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose);
16543+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id);
16544+#endif /* CONFIG_PROC_FS */
1facf9fc 16545+
c1595e42
JR
16546+#ifdef CONFIG_AUFS_XATTR
16547+/* xattr.c */
16548+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags);
16549+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size);
16550+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
16551+ size_t size);
16552+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
16553+ size_t size, int flags);
16554+int aufs_removexattr(struct dentry *dentry, const char *name);
16555+
16556+/* void au_xattr_init(struct super_block *sb); */
16557+#else
16558+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src,
16559+ int ignore_flags);
16560+/* AuStubVoid(au_xattr_init, struct super_block *sb); */
16561+#endif
16562+
16563+#ifdef CONFIG_FS_POSIX_ACL
16564+struct posix_acl *aufs_get_acl(struct inode *inode, int type);
16565+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
16566+#endif
16567+
16568+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
16569+enum {
16570+ AU_XATTR_SET,
16571+ AU_XATTR_REMOVE,
16572+ AU_ACL_SET
16573+};
16574+
16575+struct au_srxattr {
16576+ int type;
16577+ union {
16578+ struct {
16579+ const char *name;
16580+ const void *value;
16581+ size_t size;
16582+ int flags;
16583+ } set;
16584+ struct {
16585+ const char *name;
16586+ } remove;
16587+ struct {
16588+ struct posix_acl *acl;
16589+ int type;
16590+ } acl_set;
16591+ } u;
16592+};
16593+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg);
16594+#endif
16595+
4a4d8108 16596+/* ---------------------------------------------------------------------- */
1308ab2a 16597+
4a4d8108
AM
16598+/* lock subclass for iinfo */
16599+enum {
16600+ AuLsc_II_CHILD, /* child first */
16601+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */
16602+ AuLsc_II_CHILD3, /* copyup dirs */
16603+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */
16604+ AuLsc_II_PARENT2,
16605+ AuLsc_II_PARENT3, /* copyup dirs */
16606+ AuLsc_II_NEW_CHILD
16607+};
1308ab2a 16608+
1facf9fc 16609+/*
4a4d8108
AM
16610+ * ii_read_lock_child, ii_write_lock_child,
16611+ * ii_read_lock_child2, ii_write_lock_child2,
16612+ * ii_read_lock_child3, ii_write_lock_child3,
16613+ * ii_read_lock_parent, ii_write_lock_parent,
16614+ * ii_read_lock_parent2, ii_write_lock_parent2,
16615+ * ii_read_lock_parent3, ii_write_lock_parent3,
16616+ * ii_read_lock_new_child, ii_write_lock_new_child,
1facf9fc 16617+ */
4a4d8108
AM
16618+#define AuReadLockFunc(name, lsc) \
16619+static inline void ii_read_lock_##name(struct inode *i) \
16620+{ \
16621+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16622+}
16623+
16624+#define AuWriteLockFunc(name, lsc) \
16625+static inline void ii_write_lock_##name(struct inode *i) \
16626+{ \
16627+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \
16628+}
16629+
16630+#define AuRWLockFuncs(name, lsc) \
16631+ AuReadLockFunc(name, lsc) \
16632+ AuWriteLockFunc(name, lsc)
16633+
16634+AuRWLockFuncs(child, CHILD);
16635+AuRWLockFuncs(child2, CHILD2);
16636+AuRWLockFuncs(child3, CHILD3);
16637+AuRWLockFuncs(parent, PARENT);
16638+AuRWLockFuncs(parent2, PARENT2);
16639+AuRWLockFuncs(parent3, PARENT3);
16640+AuRWLockFuncs(new_child, NEW_CHILD);
16641+
16642+#undef AuReadLockFunc
16643+#undef AuWriteLockFunc
16644+#undef AuRWLockFuncs
1facf9fc 16645+
16646+/*
4a4d8108 16647+ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock
1facf9fc 16648+ */
4a4d8108 16649+AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem);
1facf9fc 16650+
4a4d8108
AM
16651+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem)
16652+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem)
16653+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem)
1facf9fc 16654+
4a4d8108 16655+/* ---------------------------------------------------------------------- */
1308ab2a 16656+
027c5e7a
AM
16657+static inline void au_icntnr_init(struct au_icntnr *c)
16658+{
16659+#ifdef CONFIG_AUFS_DEBUG
16660+ c->vfs_inode.i_mode = 0;
16661+#endif
16662+}
16663+
537831f9 16664+static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen)
4a4d8108 16665+{
537831f9
AM
16666+ unsigned int gen;
16667+ struct au_iinfo *iinfo;
16668+
16669+ iinfo = au_ii(inode);
16670+ spin_lock(&iinfo->ii_genspin);
16671+ if (iigen)
16672+ *iigen = iinfo->ii_generation;
16673+ gen = iinfo->ii_generation.ig_generation;
16674+ spin_unlock(&iinfo->ii_genspin);
16675+
16676+ return gen;
4a4d8108 16677+}
1308ab2a 16678+
4a4d8108
AM
16679+/* tiny test for inode number */
16680+/* tmpfs generation is too rough */
16681+static inline int au_test_higen(struct inode *inode, struct inode *h_inode)
16682+{
16683+ struct au_iinfo *iinfo;
1308ab2a 16684+
4a4d8108
AM
16685+ iinfo = au_ii(inode);
16686+ AuRwMustAnyLock(&iinfo->ii_rwsem);
16687+ return !(iinfo->ii_hsb1 == h_inode->i_sb
16688+ && iinfo->ii_higen == h_inode->i_generation);
16689+}
1308ab2a 16690+
4a4d8108
AM
16691+static inline void au_iigen_dec(struct inode *inode)
16692+{
537831f9
AM
16693+ struct au_iinfo *iinfo;
16694+
16695+ iinfo = au_ii(inode);
16696+ spin_lock(&iinfo->ii_genspin);
16697+ iinfo->ii_generation.ig_generation--;
16698+ spin_unlock(&iinfo->ii_genspin);
027c5e7a
AM
16699+}
16700+
16701+static inline int au_iigen_test(struct inode *inode, unsigned int sigen)
16702+{
16703+ int err;
16704+
16705+ err = 0;
537831f9 16706+ if (unlikely(inode && au_iigen(inode, NULL) != sigen))
027c5e7a
AM
16707+ err = -EIO;
16708+
16709+ return err;
4a4d8108 16710+}
1308ab2a 16711+
4a4d8108 16712+/* ---------------------------------------------------------------------- */
1308ab2a 16713+
4a4d8108
AM
16714+static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
16715+ aufs_bindex_t bindex)
16716+{
16717+ IiMustAnyLock(inode);
16718+ return au_ii(inode)->ii_hinode[0 + bindex].hi_id;
16719+}
1308ab2a 16720+
4a4d8108
AM
16721+static inline aufs_bindex_t au_ibstart(struct inode *inode)
16722+{
16723+ IiMustAnyLock(inode);
16724+ return au_ii(inode)->ii_bstart;
16725+}
1308ab2a 16726+
4a4d8108
AM
16727+static inline aufs_bindex_t au_ibend(struct inode *inode)
16728+{
16729+ IiMustAnyLock(inode);
16730+ return au_ii(inode)->ii_bend;
16731+}
1308ab2a 16732+
4a4d8108
AM
16733+static inline struct au_vdir *au_ivdir(struct inode *inode)
16734+{
16735+ IiMustAnyLock(inode);
16736+ return au_ii(inode)->ii_vdir;
16737+}
1308ab2a 16738+
4a4d8108
AM
16739+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex)
16740+{
16741+ IiMustAnyLock(inode);
16742+ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry;
16743+}
1308ab2a 16744+
4a4d8108 16745+static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16746+{
4a4d8108
AM
16747+ IiMustWriteLock(inode);
16748+ au_ii(inode)->ii_bstart = bindex;
16749+}
1308ab2a 16750+
4a4d8108
AM
16751+static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex)
16752+{
16753+ IiMustWriteLock(inode);
16754+ au_ii(inode)->ii_bend = bindex;
1308ab2a 16755+}
16756+
4a4d8108
AM
16757+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir)
16758+{
16759+ IiMustWriteLock(inode);
16760+ au_ii(inode)->ii_vdir = vdir;
16761+}
1facf9fc 16762+
4a4d8108 16763+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex)
1308ab2a 16764+{
4a4d8108
AM
16765+ IiMustAnyLock(inode);
16766+ return au_ii(inode)->ii_hinode + bindex;
16767+}
dece6358 16768+
4a4d8108 16769+/* ---------------------------------------------------------------------- */
1facf9fc 16770+
4a4d8108
AM
16771+static inline struct dentry *au_pinned_parent(struct au_pin *pin)
16772+{
16773+ if (pin)
16774+ return pin->parent;
16775+ return NULL;
1facf9fc 16776+}
16777+
4a4d8108 16778+static inline struct inode *au_pinned_h_dir(struct au_pin *pin)
1facf9fc 16779+{
4a4d8108
AM
16780+ if (pin && pin->hdir)
16781+ return pin->hdir->hi_inode;
16782+ return NULL;
1308ab2a 16783+}
1facf9fc 16784+
4a4d8108
AM
16785+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin)
16786+{
16787+ if (pin)
16788+ return pin->hdir;
16789+ return NULL;
16790+}
1facf9fc 16791+
4a4d8108 16792+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry)
1308ab2a 16793+{
4a4d8108
AM
16794+ if (pin)
16795+ pin->dentry = dentry;
16796+}
1308ab2a 16797+
4a4d8108
AM
16798+static inline void au_pin_set_parent_lflag(struct au_pin *pin,
16799+ unsigned char lflag)
16800+{
16801+ if (pin) {
7f207e10 16802+ if (lflag)
4a4d8108 16803+ au_fset_pin(pin->flags, DI_LOCKED);
7f207e10 16804+ else
4a4d8108 16805+ au_fclr_pin(pin->flags, DI_LOCKED);
1308ab2a 16806+ }
4a4d8108
AM
16807+}
16808+
16809+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent)
16810+{
16811+ if (pin) {
16812+ dput(pin->parent);
16813+ pin->parent = dget(parent);
1facf9fc 16814+ }
4a4d8108 16815+}
1facf9fc 16816+
4a4d8108
AM
16817+/* ---------------------------------------------------------------------- */
16818+
027c5e7a 16819+struct au_branch;
4a4d8108
AM
16820+#ifdef CONFIG_AUFS_HNOTIFY
16821+struct au_hnotify_op {
16822+ void (*ctl)(struct au_hinode *hinode, int do_set);
027c5e7a 16823+ int (*alloc)(struct au_hinode *hinode);
7eafdf33
AM
16824+
16825+ /*
16826+ * if it returns true, the the caller should free hinode->hi_notify,
16827+ * otherwise ->free() frees it.
16828+ */
16829+ int (*free)(struct au_hinode *hinode,
16830+ struct au_hnotify *hn) __must_check;
4a4d8108
AM
16831+
16832+ void (*fin)(void);
16833+ int (*init)(void);
027c5e7a
AM
16834+
16835+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm);
16836+ void (*fin_br)(struct au_branch *br);
16837+ int (*init_br)(struct au_branch *br, int perm);
4a4d8108
AM
16838+};
16839+
16840+/* hnotify.c */
027c5e7a 16841+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode);
4a4d8108
AM
16842+void au_hn_free(struct au_hinode *hinode);
16843+void au_hn_ctl(struct au_hinode *hinode, int do_set);
16844+void au_hn_reset(struct inode *inode, unsigned int flags);
16845+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask,
16846+ struct qstr *h_child_qstr, struct inode *h_child_inode);
027c5e7a
AM
16847+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm);
16848+int au_hnotify_init_br(struct au_branch *br, int perm);
16849+void au_hnotify_fin_br(struct au_branch *br);
4a4d8108
AM
16850+int __init au_hnotify_init(void);
16851+void au_hnotify_fin(void);
16852+
7f207e10 16853+/* hfsnotify.c */
4a4d8108
AM
16854+extern const struct au_hnotify_op au_hnotify_op;
16855+
16856+static inline
16857+void au_hn_init(struct au_hinode *hinode)
16858+{
16859+ hinode->hi_notify = NULL;
1308ab2a 16860+}
16861+
53392da6
AM
16862+static inline struct au_hnotify *au_hn(struct au_hinode *hinode)
16863+{
16864+ return hinode->hi_notify;
16865+}
16866+
4a4d8108 16867+#else
c1595e42
JR
16868+AuStub(int, au_hn_alloc, return -EOPNOTSUPP,
16869+ struct au_hinode *hinode __maybe_unused,
16870+ struct inode *inode __maybe_unused)
16871+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode)
4a4d8108
AM
16872+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused)
16873+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused,
16874+ int do_set __maybe_unused)
16875+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused,
16876+ unsigned int flags __maybe_unused)
027c5e7a
AM
16877+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused,
16878+ struct au_branch *br __maybe_unused,
16879+ int perm __maybe_unused)
16880+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused,
16881+ int perm __maybe_unused)
16882+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused)
4a4d8108
AM
16883+AuStubInt0(__init au_hnotify_init, void)
16884+AuStubVoid(au_hnotify_fin, void)
16885+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused)
16886+#endif /* CONFIG_AUFS_HNOTIFY */
16887+
16888+static inline void au_hn_suspend(struct au_hinode *hdir)
16889+{
16890+ au_hn_ctl(hdir, /*do_set*/0);
1308ab2a 16891+}
16892+
4a4d8108 16893+static inline void au_hn_resume(struct au_hinode *hdir)
1308ab2a 16894+{
4a4d8108
AM
16895+ au_hn_ctl(hdir, /*do_set*/1);
16896+}
1308ab2a 16897+
4a4d8108
AM
16898+static inline void au_hn_imtx_lock(struct au_hinode *hdir)
16899+{
16900+ mutex_lock(&hdir->hi_inode->i_mutex);
16901+ au_hn_suspend(hdir);
16902+}
dece6358 16903+
4a4d8108
AM
16904+static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
16905+ unsigned int sc __maybe_unused)
16906+{
16907+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc);
16908+ au_hn_suspend(hdir);
1facf9fc 16909+}
1facf9fc 16910+
4a4d8108
AM
16911+static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
16912+{
16913+ au_hn_resume(hdir);
16914+ mutex_unlock(&hdir->hi_inode->i_mutex);
16915+}
16916+
16917+#endif /* __KERNEL__ */
16918+#endif /* __AUFS_INODE_H__ */
7f207e10
AM
16919diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c
16920--- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
16921+++ linux/fs/aufs/ioctl.c 2015-01-25 13:00:38.631047076 +0100
16922@@ -0,0 +1,219 @@
4a4d8108 16923+/*
523b37e3 16924+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
16925+ *
16926+ * This program, aufs is free software; you can redistribute it and/or modify
16927+ * it under the terms of the GNU General Public License as published by
16928+ * the Free Software Foundation; either version 2 of the License, or
16929+ * (at your option) any later version.
16930+ *
16931+ * This program is distributed in the hope that it will be useful,
16932+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16933+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16934+ * GNU General Public License for more details.
16935+ *
16936+ * You should have received a copy of the GNU General Public License
523b37e3 16937+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
16938+ */
16939+
16940+/*
16941+ * ioctl
16942+ * plink-management and readdir in userspace.
16943+ * assist the pathconf(3) wrapper library.
c2b27bf2 16944+ * move-down
076b876e 16945+ * File-based Hierarchical Storage Management.
4a4d8108
AM
16946+ */
16947+
c2b27bf2
AM
16948+#include <linux/compat.h>
16949+#include <linux/file.h>
4a4d8108
AM
16950+#include "aufs.h"
16951+
1e00d052 16952+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
4a4d8108
AM
16953+{
16954+ int err, fd;
16955+ aufs_bindex_t wbi, bindex, bend;
16956+ struct file *h_file;
16957+ struct super_block *sb;
16958+ struct dentry *root;
1e00d052
AM
16959+ struct au_branch *br;
16960+ struct aufs_wbr_fd wbrfd = {
16961+ .oflags = au_dir_roflags,
16962+ .brid = -1
16963+ };
16964+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY
16965+ | O_NOATIME | O_CLOEXEC;
4a4d8108 16966+
1e00d052
AM
16967+ AuDebugOn(wbrfd.oflags & ~valid);
16968+
16969+ if (arg) {
16970+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd));
16971+ if (unlikely(err)) {
16972+ err = -EFAULT;
16973+ goto out;
16974+ }
16975+
16976+ err = -EINVAL;
16977+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid);
16978+ wbrfd.oflags |= au_dir_roflags;
16979+ AuDbg("0%o\n", wbrfd.oflags);
16980+ if (unlikely(wbrfd.oflags & ~valid))
16981+ goto out;
16982+ }
16983+
16984+ fd = get_unused_fd();
16985+ err = fd;
16986+ if (unlikely(fd < 0))
4a4d8108 16987+ goto out;
4a4d8108 16988+
1e00d052 16989+ h_file = ERR_PTR(-EINVAL);
4a4d8108 16990+ wbi = 0;
1e00d052 16991+ br = NULL;
4a4d8108
AM
16992+ sb = path->dentry->d_sb;
16993+ root = sb->s_root;
16994+ aufs_read_lock(root, AuLock_IR);
1e00d052
AM
16995+ bend = au_sbend(sb);
16996+ if (wbrfd.brid >= 0) {
16997+ wbi = au_br_index(sb, wbrfd.brid);
16998+ if (unlikely(wbi < 0 || wbi > bend))
16999+ goto out_unlock;
17000+ }
17001+
17002+ h_file = ERR_PTR(-ENOENT);
17003+ br = au_sbr(sb, wbi);
17004+ if (!au_br_writable(br->br_perm)) {
17005+ if (arg)
17006+ goto out_unlock;
17007+
17008+ bindex = wbi + 1;
17009+ wbi = -1;
17010+ for (; bindex <= bend; bindex++) {
17011+ br = au_sbr(sb, bindex);
17012+ if (au_br_writable(br->br_perm)) {
4a4d8108 17013+ wbi = bindex;
1e00d052 17014+ br = au_sbr(sb, wbi);
4a4d8108
AM
17015+ break;
17016+ }
17017+ }
4a4d8108
AM
17018+ }
17019+ AuDbg("wbi %d\n", wbi);
1e00d052 17020+ if (wbi >= 0)
392086de
AM
17021+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
17022+ /*force_wr*/0);
1e00d052
AM
17023+
17024+out_unlock:
4a4d8108
AM
17025+ aufs_read_unlock(root, AuLock_IR);
17026+ err = PTR_ERR(h_file);
17027+ if (IS_ERR(h_file))
17028+ goto out_fd;
17029+
1e00d052 17030+ atomic_dec(&br->br_count); /* cf. au_h_open() */
4a4d8108
AM
17031+ fd_install(fd, h_file);
17032+ err = fd;
17033+ goto out; /* success */
17034+
4f0767ce 17035+out_fd:
4a4d8108 17036+ put_unused_fd(fd);
4f0767ce 17037+out:
1e00d052 17038+ AuTraceErr(err);
4a4d8108
AM
17039+ return err;
17040+}
17041+
17042+/* ---------------------------------------------------------------------- */
17043+
17044+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
17045+{
17046+ long err;
c1595e42 17047+ struct dentry *dentry;
4a4d8108
AM
17048+
17049+ switch (cmd) {
4a4d8108
AM
17050+ case AUFS_CTL_RDU:
17051+ case AUFS_CTL_RDU_INO:
17052+ err = au_rdu_ioctl(file, cmd, arg);
17053+ break;
17054+
17055+ case AUFS_CTL_WBR_FD:
1e00d052 17056+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
17057+ break;
17058+
027c5e7a
AM
17059+ case AUFS_CTL_IBUSY:
17060+ err = au_ibusy_ioctl(file, arg);
17061+ break;
17062+
076b876e
AM
17063+ case AUFS_CTL_BRINFO:
17064+ err = au_brinfo_ioctl(file, arg);
17065+ break;
17066+
17067+ case AUFS_CTL_FHSM_FD:
c1595e42
JR
17068+ dentry = file->f_dentry;
17069+ if (IS_ROOT(dentry))
17070+ err = au_fhsm_fd(dentry->d_sb, arg);
17071+ else
17072+ err = -ENOTTY;
076b876e
AM
17073+ break;
17074+
4a4d8108
AM
17075+ default:
17076+ /* do not call the lower */
17077+ AuDbg("0x%x\n", cmd);
17078+ err = -ENOTTY;
17079+ }
17080+
17081+ AuTraceErr(err);
17082+ return err;
17083+}
17084+
17085+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
17086+{
17087+ long err;
17088+
17089+ switch (cmd) {
c2b27bf2 17090+ case AUFS_CTL_MVDOWN:
c2b27bf2
AM
17091+ err = au_mvdown(file->f_dentry, (void __user *)arg);
17092+ break;
17093+
4a4d8108 17094+ case AUFS_CTL_WBR_FD:
1e00d052 17095+ err = au_wbr_fd(&file->f_path, (void __user *)arg);
4a4d8108
AM
17096+ break;
17097+
17098+ default:
17099+ /* do not call the lower */
17100+ AuDbg("0x%x\n", cmd);
17101+ err = -ENOTTY;
17102+ }
17103+
17104+ AuTraceErr(err);
17105+ return err;
17106+}
b752ccd1
AM
17107+
17108+#ifdef CONFIG_COMPAT
17109+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
17110+ unsigned long arg)
17111+{
17112+ long err;
17113+
17114+ switch (cmd) {
17115+ case AUFS_CTL_RDU:
17116+ case AUFS_CTL_RDU_INO:
17117+ err = au_rdu_compat_ioctl(file, cmd, arg);
17118+ break;
17119+
027c5e7a
AM
17120+ case AUFS_CTL_IBUSY:
17121+ err = au_ibusy_compat_ioctl(file, arg);
17122+ break;
17123+
076b876e
AM
17124+ case AUFS_CTL_BRINFO:
17125+ err = au_brinfo_compat_ioctl(file, arg);
17126+ break;
17127+
b752ccd1
AM
17128+ default:
17129+ err = aufs_ioctl_dir(file, cmd, arg);
17130+ }
17131+
17132+ AuTraceErr(err);
17133+ return err;
17134+}
17135+
b752ccd1
AM
17136+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd,
17137+ unsigned long arg)
17138+{
17139+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg));
17140+}
17141+#endif
7f207e10
AM
17142diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c
17143--- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
17144+++ linux/fs/aufs/i_op_add.c 2015-01-25 13:00:38.631047076 +0100
17145@@ -0,0 +1,891 @@
4a4d8108 17146+/*
523b37e3 17147+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
17148+ *
17149+ * This program, aufs is free software; you can redistribute it and/or modify
17150+ * it under the terms of the GNU General Public License as published by
17151+ * the Free Software Foundation; either version 2 of the License, or
17152+ * (at your option) any later version.
17153+ *
17154+ * This program is distributed in the hope that it will be useful,
17155+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17156+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17157+ * GNU General Public License for more details.
17158+ *
17159+ * You should have received a copy of the GNU General Public License
523b37e3 17160+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108
AM
17161+ */
17162+
17163+/*
17164+ * inode operations (add entry)
17165+ */
17166+
17167+#include "aufs.h"
17168+
17169+/*
17170+ * final procedure of adding a new entry, except link(2).
17171+ * remove whiteout, instantiate, copyup the parent dir's times and size
17172+ * and update version.
17173+ * if it failed, re-create the removed whiteout.
17174+ */
17175+static int epilog(struct inode *dir, aufs_bindex_t bindex,
17176+ struct dentry *wh_dentry, struct dentry *dentry)
17177+{
17178+ int err, rerr;
17179+ aufs_bindex_t bwh;
17180+ struct path h_path;
076b876e 17181+ struct super_block *sb;
4a4d8108
AM
17182+ struct inode *inode, *h_dir;
17183+ struct dentry *wh;
17184+
17185+ bwh = -1;
076b876e 17186+ sb = dir->i_sb;
4a4d8108
AM
17187+ if (wh_dentry) {
17188+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
17189+ IMustLock(h_dir);
17190+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir);
17191+ bwh = au_dbwh(dentry);
17192+ h_path.dentry = wh_dentry;
076b876e 17193+ h_path.mnt = au_sbr_mnt(sb, bindex);
4a4d8108
AM
17194+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path,
17195+ dentry);
17196+ if (unlikely(err))
17197+ goto out;
17198+ }
17199+
17200+ inode = au_new_inode(dentry, /*must_new*/1);
17201+ if (!IS_ERR(inode)) {
17202+ d_instantiate(dentry, inode);
17203+ dir = dentry->d_parent->d_inode; /* dir inode is locked */
17204+ IMustLock(dir);
17205+ if (au_ibstart(dir) == au_dbstart(dentry))
17206+ au_cpup_attr_timesizes(dir);
17207+ dir->i_version++;
076b876e 17208+ au_fhsm_wrote(sb, bindex, /*force*/0);
4a4d8108
AM
17209+ return 0; /* success */
17210+ }
17211+
17212+ err = PTR_ERR(inode);
17213+ if (!wh_dentry)
17214+ goto out;
17215+
17216+ /* revert */
17217+ /* dir inode is locked */
17218+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent);
17219+ rerr = PTR_ERR(wh);
17220+ if (IS_ERR(wh)) {
523b37e3
AM
17221+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n",
17222+ dentry, err, rerr);
4a4d8108
AM
17223+ err = -EIO;
17224+ } else
17225+ dput(wh);
17226+
4f0767ce 17227+out:
4a4d8108
AM
17228+ return err;
17229+}
17230+
027c5e7a
AM
17231+static int au_d_may_add(struct dentry *dentry)
17232+{
17233+ int err;
17234+
17235+ err = 0;
17236+ if (unlikely(d_unhashed(dentry)))
17237+ err = -ENOENT;
17238+ if (unlikely(dentry->d_inode))
17239+ err = -EEXIST;
17240+ return err;
17241+}
17242+
4a4d8108
AM
17243+/*
17244+ * simple tests for the adding inode operations.
17245+ * following the checks in vfs, plus the parent-child relationship.
17246+ */
17247+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex,
17248+ struct dentry *h_parent, int isdir)
17249+{
17250+ int err;
17251+ umode_t h_mode;
17252+ struct dentry *h_dentry;
17253+ struct inode *h_inode;
17254+
17255+ err = -ENAMETOOLONG;
17256+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17257+ goto out;
17258+
17259+ h_dentry = au_h_dptr(dentry, bindex);
17260+ h_inode = h_dentry->d_inode;
17261+ if (!dentry->d_inode) {
17262+ err = -EEXIST;
17263+ if (unlikely(h_inode))
17264+ goto out;
17265+ } else {
17266+ /* rename(2) case */
17267+ err = -EIO;
17268+ if (unlikely(!h_inode || !h_inode->i_nlink))
17269+ goto out;
17270+
17271+ h_mode = h_inode->i_mode;
17272+ if (!isdir) {
17273+ err = -EISDIR;
17274+ if (unlikely(S_ISDIR(h_mode)))
17275+ goto out;
17276+ } else if (unlikely(!S_ISDIR(h_mode))) {
17277+ err = -ENOTDIR;
17278+ goto out;
17279+ }
17280+ }
17281+
17282+ err = 0;
17283+ /* expected parent dir is locked */
17284+ if (unlikely(h_parent != h_dentry->d_parent))
17285+ err = -EIO;
17286+
4f0767ce 17287+out:
4a4d8108
AM
17288+ AuTraceErr(err);
17289+ return err;
17290+}
17291+
17292+/*
17293+ * initial procedure of adding a new entry.
17294+ * prepare writable branch and the parent dir, lock it,
17295+ * and lookup whiteout for the new entry.
17296+ */
17297+static struct dentry*
17298+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt,
17299+ struct dentry *src_dentry, struct au_pin *pin,
17300+ struct au_wr_dir_args *wr_dir_args)
17301+{
17302+ struct dentry *wh_dentry, *h_parent;
17303+ struct super_block *sb;
17304+ struct au_branch *br;
17305+ int err;
17306+ unsigned int udba;
17307+ aufs_bindex_t bcpup;
17308+
523b37e3 17309+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17310+
17311+ err = au_wr_dir(dentry, src_dentry, wr_dir_args);
17312+ bcpup = err;
17313+ wh_dentry = ERR_PTR(err);
17314+ if (unlikely(err < 0))
17315+ goto out;
17316+
17317+ sb = dentry->d_sb;
17318+ udba = au_opt_udba(sb);
17319+ err = au_pin(pin, dentry, bcpup, udba,
17320+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17321+ wh_dentry = ERR_PTR(err);
17322+ if (unlikely(err))
17323+ goto out;
17324+
17325+ h_parent = au_pinned_h_parent(pin);
17326+ if (udba != AuOpt_UDBA_NONE
17327+ && au_dbstart(dentry) == bcpup)
17328+ err = au_may_add(dentry, bcpup, h_parent,
17329+ au_ftest_wrdir(wr_dir_args->flags, ISDIR));
17330+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
17331+ err = -ENAMETOOLONG;
17332+ wh_dentry = ERR_PTR(err);
17333+ if (unlikely(err))
17334+ goto out_unpin;
17335+
17336+ br = au_sbr(sb, bcpup);
17337+ if (dt) {
17338+ struct path tmp = {
17339+ .dentry = h_parent,
86dc4139 17340+ .mnt = au_br_mnt(br)
4a4d8108
AM
17341+ };
17342+ au_dtime_store(dt, au_pinned_parent(pin), &tmp);
17343+ }
17344+
17345+ wh_dentry = NULL;
17346+ if (bcpup != au_dbwh(dentry))
17347+ goto out; /* success */
17348+
17349+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
17350+
4f0767ce 17351+out_unpin:
4a4d8108
AM
17352+ if (IS_ERR(wh_dentry))
17353+ au_unpin(pin);
4f0767ce 17354+out:
4a4d8108
AM
17355+ return wh_dentry;
17356+}
17357+
17358+/* ---------------------------------------------------------------------- */
17359+
17360+enum { Mknod, Symlink, Creat };
17361+struct simple_arg {
17362+ int type;
17363+ union {
17364+ struct {
7eafdf33 17365+ umode_t mode;
b4510431 17366+ bool want_excl;
4a4d8108
AM
17367+ } c;
17368+ struct {
17369+ const char *symname;
17370+ } s;
17371+ struct {
7eafdf33 17372+ umode_t mode;
4a4d8108
AM
17373+ dev_t dev;
17374+ } m;
17375+ } u;
17376+};
17377+
17378+static int add_simple(struct inode *dir, struct dentry *dentry,
17379+ struct simple_arg *arg)
17380+{
076b876e 17381+ int err, rerr;
4a4d8108
AM
17382+ aufs_bindex_t bstart;
17383+ unsigned char created;
4a4d8108
AM
17384+ struct dentry *wh_dentry, *parent;
17385+ struct inode *h_dir;
c2b27bf2
AM
17386+ /* to reuduce stack size */
17387+ struct {
17388+ struct au_dtime dt;
17389+ struct au_pin pin;
17390+ struct path h_path;
17391+ struct au_wr_dir_args wr_dir_args;
17392+ } *a;
4a4d8108 17393+
523b37e3 17394+ AuDbg("%pd\n", dentry);
4a4d8108
AM
17395+ IMustLock(dir);
17396+
c2b27bf2
AM
17397+ err = -ENOMEM;
17398+ a = kmalloc(sizeof(*a), GFP_NOFS);
17399+ if (unlikely(!a))
17400+ goto out;
17401+ a->wr_dir_args.force_btgt = -1;
17402+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY;
17403+
4a4d8108 17404+ parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17405+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17406+ if (unlikely(err))
c2b27bf2 17407+ goto out_free;
027c5e7a
AM
17408+ err = au_d_may_add(dentry);
17409+ if (unlikely(err))
17410+ goto out_unlock;
4a4d8108 17411+ di_write_lock_parent(parent);
c2b27bf2
AM
17412+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17413+ &a->pin, &a->wr_dir_args);
4a4d8108
AM
17414+ err = PTR_ERR(wh_dentry);
17415+ if (IS_ERR(wh_dentry))
027c5e7a 17416+ goto out_parent;
4a4d8108
AM
17417+
17418+ bstart = au_dbstart(dentry);
c2b27bf2
AM
17419+ a->h_path.dentry = au_h_dptr(dentry, bstart);
17420+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
17421+ h_dir = au_pinned_h_dir(&a->pin);
4a4d8108
AM
17422+ switch (arg->type) {
17423+ case Creat:
c2b27bf2 17424+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode,
537831f9 17425+ arg->u.c.want_excl);
4a4d8108
AM
17426+ break;
17427+ case Symlink:
c2b27bf2 17428+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname);
4a4d8108
AM
17429+ break;
17430+ case Mknod:
c2b27bf2
AM
17431+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode,
17432+ arg->u.m.dev);
4a4d8108
AM
17433+ break;
17434+ default:
17435+ BUG();
17436+ }
17437+ created = !err;
17438+ if (!err)
17439+ err = epilog(dir, bstart, wh_dentry, dentry);
17440+
17441+ /* revert */
c2b27bf2 17442+ if (unlikely(created && err && a->h_path.dentry->d_inode)) {
523b37e3
AM
17443+ /* no delegation since it is just created */
17444+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL,
17445+ /*force*/0);
4a4d8108 17446+ if (rerr) {
523b37e3
AM
17447+ AuIOErr("%pd revert failure(%d, %d)\n",
17448+ dentry, err, rerr);
4a4d8108
AM
17449+ err = -EIO;
17450+ }
c2b27bf2 17451+ au_dtime_revert(&a->dt);
4a4d8108
AM
17452+ }
17453+
c2b27bf2 17454+ au_unpin(&a->pin);
4a4d8108
AM
17455+ dput(wh_dentry);
17456+
027c5e7a
AM
17457+out_parent:
17458+ di_write_unlock(parent);
17459+out_unlock:
4a4d8108
AM
17460+ if (unlikely(err)) {
17461+ au_update_dbstart(dentry);
17462+ d_drop(dentry);
17463+ }
4a4d8108 17464+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
17465+out_free:
17466+ kfree(a);
027c5e7a 17467+out:
4a4d8108
AM
17468+ return err;
17469+}
17470+
7eafdf33
AM
17471+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
17472+ dev_t dev)
4a4d8108
AM
17473+{
17474+ struct simple_arg arg = {
17475+ .type = Mknod,
17476+ .u.m = {
17477+ .mode = mode,
17478+ .dev = dev
17479+ }
17480+ };
17481+ return add_simple(dir, dentry, &arg);
17482+}
17483+
17484+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
17485+{
17486+ struct simple_arg arg = {
17487+ .type = Symlink,
17488+ .u.s.symname = symname
17489+ };
17490+ return add_simple(dir, dentry, &arg);
17491+}
17492+
7eafdf33 17493+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
b4510431 17494+ bool want_excl)
4a4d8108
AM
17495+{
17496+ struct simple_arg arg = {
17497+ .type = Creat,
17498+ .u.c = {
b4510431
AM
17499+ .mode = mode,
17500+ .want_excl = want_excl
4a4d8108
AM
17501+ }
17502+ };
17503+ return add_simple(dir, dentry, &arg);
17504+}
17505+
38d290e6
JR
17506+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
17507+{
17508+ int err;
17509+ aufs_bindex_t bindex;
17510+ struct super_block *sb;
17511+ struct dentry *parent, *h_parent, *h_dentry;
17512+ struct inode *h_dir, *inode;
17513+ struct vfsmount *h_mnt;
17514+ struct au_wr_dir_args wr_dir_args = {
17515+ .force_btgt = -1,
17516+ .flags = AuWrDir_TMPFILE
17517+ };
17518+
17519+ /* copy-up may happen */
17520+ mutex_lock(&dir->i_mutex);
17521+
17522+ sb = dir->i_sb;
17523+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
17524+ if (unlikely(err))
17525+ goto out;
17526+
17527+ err = au_di_init(dentry);
17528+ if (unlikely(err))
17529+ goto out_si;
17530+
17531+ err = -EBUSY;
17532+ parent = d_find_any_alias(dir);
17533+ AuDebugOn(!parent);
17534+ di_write_lock_parent(parent);
17535+ if (unlikely(parent->d_inode != dir))
17536+ goto out_parent;
17537+
17538+ err = au_digen_test(parent, au_sigen(sb));
17539+ if (unlikely(err))
17540+ goto out_parent;
17541+
17542+ bindex = au_dbstart(parent);
17543+ au_set_dbstart(dentry, bindex);
17544+ au_set_dbend(dentry, bindex);
17545+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
17546+ bindex = err;
17547+ if (unlikely(err < 0))
17548+ goto out_parent;
17549+
17550+ err = -EOPNOTSUPP;
17551+ h_dir = au_h_iptr(dir, bindex);
17552+ if (unlikely(!h_dir->i_op->tmpfile))
17553+ goto out_parent;
17554+
17555+ h_mnt = au_sbr_mnt(sb, bindex);
17556+ err = vfsub_mnt_want_write(h_mnt);
17557+ if (unlikely(err))
17558+ goto out_parent;
17559+
17560+ h_parent = au_h_dptr(parent, bindex);
17561+ err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC);
17562+ if (unlikely(err))
17563+ goto out_mnt;
17564+
17565+ err = -ENOMEM;
17566+ h_dentry = d_alloc(h_parent, &dentry->d_name);
17567+ if (unlikely(!h_dentry))
17568+ goto out_mnt;
17569+
17570+ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode);
17571+ if (unlikely(err))
17572+ goto out_dentry;
17573+
17574+ au_set_dbstart(dentry, bindex);
17575+ au_set_dbend(dentry, bindex);
17576+ au_set_h_dptr(dentry, bindex, dget(h_dentry));
17577+ inode = au_new_inode(dentry, /*must_new*/1);
17578+ if (IS_ERR(inode)) {
17579+ err = PTR_ERR(inode);
17580+ au_set_h_dptr(dentry, bindex, NULL);
17581+ au_set_dbstart(dentry, -1);
17582+ au_set_dbend(dentry, -1);
17583+ } else {
17584+ if (!inode->i_nlink)
17585+ set_nlink(inode, 1);
17586+ d_tmpfile(dentry, inode);
17587+ au_di(dentry)->di_tmpfile = 1;
17588+
17589+ /* update without i_mutex */
17590+ if (au_ibstart(dir) == au_dbstart(dentry))
17591+ au_cpup_attr_timesizes(dir);
17592+ }
17593+
17594+out_dentry:
17595+ dput(h_dentry);
17596+out_mnt:
17597+ vfsub_mnt_drop_write(h_mnt);
17598+out_parent:
17599+ di_write_unlock(parent);
17600+ dput(parent);
17601+ di_write_unlock(dentry);
17602+ if (!err)
17603+#if 0
17604+ /* verbose coding for lock class name */
17605+ au_rw_class(&au_di(dentry)->di_rwsem,
17606+ au_lc_key + AuLcNonDir_DIINFO);
17607+#else
17608+ ;
17609+#endif
17610+ else {
17611+ au_di_fin(dentry);
17612+ dentry->d_fsdata = NULL;
17613+ }
17614+out_si:
17615+ si_read_unlock(sb);
17616+out:
17617+ mutex_unlock(&dir->i_mutex);
17618+ return err;
17619+}
17620+
4a4d8108
AM
17621+/* ---------------------------------------------------------------------- */
17622+
17623+struct au_link_args {
17624+ aufs_bindex_t bdst, bsrc;
17625+ struct au_pin pin;
17626+ struct path h_path;
17627+ struct dentry *src_parent, *parent;
17628+};
17629+
17630+static int au_cpup_before_link(struct dentry *src_dentry,
17631+ struct au_link_args *a)
17632+{
17633+ int err;
17634+ struct dentry *h_src_dentry;
c2b27bf2
AM
17635+ struct au_cp_generic cpg = {
17636+ .dentry = src_dentry,
17637+ .bdst = a->bdst,
17638+ .bsrc = a->bsrc,
17639+ .len = -1,
17640+ .pin = &a->pin,
17641+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */
17642+ };
4a4d8108
AM
17643+
17644+ di_read_lock_parent(a->src_parent, AuLock_IR);
17645+ err = au_test_and_cpup_dirs(src_dentry, a->bdst);
17646+ if (unlikely(err))
17647+ goto out;
17648+
17649+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc);
4a4d8108
AM
17650+ err = au_pin(&a->pin, src_dentry, a->bdst,
17651+ au_opt_udba(src_dentry->d_sb),
17652+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17653+ if (unlikely(err))
17654+ goto out;
367653fa 17655+
c2b27bf2 17656+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
17657+ au_unpin(&a->pin);
17658+
4f0767ce 17659+out:
4a4d8108
AM
17660+ di_read_unlock(a->src_parent, AuLock_IR);
17661+ return err;
17662+}
17663+
86dc4139
AM
17664+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry,
17665+ struct au_link_args *a)
4a4d8108
AM
17666+{
17667+ int err;
17668+ unsigned char plink;
86dc4139 17669+ aufs_bindex_t bend;
4a4d8108 17670+ struct dentry *h_src_dentry;
523b37e3 17671+ struct inode *h_inode, *inode, *delegated;
4a4d8108
AM
17672+ struct super_block *sb;
17673+ struct file *h_file;
17674+
17675+ plink = 0;
17676+ h_inode = NULL;
17677+ sb = src_dentry->d_sb;
17678+ inode = src_dentry->d_inode;
17679+ if (au_ibstart(inode) <= a->bdst)
17680+ h_inode = au_h_iptr(inode, a->bdst);
17681+ if (!h_inode || !h_inode->i_nlink) {
17682+ /* copyup src_dentry as the name of dentry. */
86dc4139
AM
17683+ bend = au_dbend(dentry);
17684+ if (bend < a->bsrc)
17685+ au_set_dbend(dentry, a->bsrc);
17686+ au_set_h_dptr(dentry, a->bsrc,
17687+ dget(au_h_dptr(src_dentry, a->bsrc)));
17688+ dget(a->h_path.dentry);
17689+ au_set_h_dptr(dentry, a->bdst, NULL);
c1595e42
JR
17690+ AuDbg("temporary d_inode...\n");
17691+ spin_lock(&dentry->d_lock);
86dc4139 17692+ dentry->d_inode = src_dentry->d_inode; /* tmp */
c1595e42 17693+ spin_unlock(&dentry->d_lock);
392086de 17694+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0);
86dc4139 17695+ if (IS_ERR(h_file))
4a4d8108 17696+ err = PTR_ERR(h_file);
86dc4139 17697+ else {
c2b27bf2
AM
17698+ struct au_cp_generic cpg = {
17699+ .dentry = dentry,
17700+ .bdst = a->bdst,
17701+ .bsrc = -1,
17702+ .len = -1,
17703+ .pin = &a->pin,
17704+ .flags = AuCpup_KEEPLINO
17705+ };
17706+ err = au_sio_cpup_simple(&cpg);
86dc4139
AM
17707+ au_h_open_post(dentry, a->bsrc, h_file);
17708+ if (!err) {
17709+ dput(a->h_path.dentry);
17710+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17711+ } else
17712+ au_set_h_dptr(dentry, a->bdst,
17713+ a->h_path.dentry);
17714+ }
c1595e42 17715+ spin_lock(&dentry->d_lock);
86dc4139 17716+ dentry->d_inode = NULL; /* restore */
c1595e42
JR
17717+ spin_unlock(&dentry->d_lock);
17718+ AuDbg("temporary d_inode...done\n");
86dc4139
AM
17719+ au_set_h_dptr(dentry, a->bsrc, NULL);
17720+ au_set_dbend(dentry, bend);
4a4d8108
AM
17721+ } else {
17722+ /* the inode of src_dentry already exists on a.bdst branch */
17723+ h_src_dentry = d_find_alias(h_inode);
17724+ if (!h_src_dentry && au_plink_test(inode)) {
17725+ plink = 1;
17726+ h_src_dentry = au_plink_lkup(inode, a->bdst);
17727+ err = PTR_ERR(h_src_dentry);
17728+ if (IS_ERR(h_src_dentry))
17729+ goto out;
17730+
17731+ if (unlikely(!h_src_dentry->d_inode)) {
17732+ dput(h_src_dentry);
17733+ h_src_dentry = NULL;
17734+ }
17735+
17736+ }
17737+ if (h_src_dentry) {
523b37e3 17738+ delegated = NULL;
4a4d8108 17739+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17740+ &a->h_path, &delegated);
17741+ if (unlikely(err == -EWOULDBLOCK)) {
17742+ pr_warn("cannot retry for NFSv4 delegation"
17743+ " for an internal link\n");
17744+ iput(delegated);
17745+ }
4a4d8108
AM
17746+ dput(h_src_dentry);
17747+ } else {
17748+ AuIOErr("no dentry found for hi%lu on b%d\n",
17749+ h_inode->i_ino, a->bdst);
17750+ err = -EIO;
17751+ }
17752+ }
17753+
17754+ if (!err && !plink)
17755+ au_plink_append(inode, a->bdst, a->h_path.dentry);
17756+
17757+out:
2cbb1c4b 17758+ AuTraceErr(err);
4a4d8108
AM
17759+ return err;
17760+}
17761+
17762+int aufs_link(struct dentry *src_dentry, struct inode *dir,
17763+ struct dentry *dentry)
17764+{
17765+ int err, rerr;
17766+ struct au_dtime dt;
17767+ struct au_link_args *a;
17768+ struct dentry *wh_dentry, *h_src_dentry;
523b37e3 17769+ struct inode *inode, *delegated;
4a4d8108
AM
17770+ struct super_block *sb;
17771+ struct au_wr_dir_args wr_dir_args = {
17772+ /* .force_btgt = -1, */
17773+ .flags = AuWrDir_ADD_ENTRY
17774+ };
17775+
17776+ IMustLock(dir);
17777+ inode = src_dentry->d_inode;
17778+ IMustLock(inode);
17779+
4a4d8108
AM
17780+ err = -ENOMEM;
17781+ a = kzalloc(sizeof(*a), GFP_NOFS);
17782+ if (unlikely(!a))
17783+ goto out;
17784+
17785+ a->parent = dentry->d_parent; /* dir inode is locked */
027c5e7a
AM
17786+ err = aufs_read_and_write_lock2(dentry, src_dentry,
17787+ AuLock_NOPLM | AuLock_GEN);
e49829fe
JR
17788+ if (unlikely(err))
17789+ goto out_kfree;
38d290e6 17790+ err = au_d_linkable(src_dentry);
027c5e7a
AM
17791+ if (unlikely(err))
17792+ goto out_unlock;
17793+ err = au_d_may_add(dentry);
17794+ if (unlikely(err))
17795+ goto out_unlock;
e49829fe 17796+
4a4d8108 17797+ a->src_parent = dget_parent(src_dentry);
2cbb1c4b 17798+ wr_dir_args.force_btgt = au_ibstart(inode);
4a4d8108
AM
17799+
17800+ di_write_lock_parent(a->parent);
17801+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
17802+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin,
17803+ &wr_dir_args);
17804+ err = PTR_ERR(wh_dentry);
17805+ if (IS_ERR(wh_dentry))
027c5e7a 17806+ goto out_parent;
4a4d8108
AM
17807+
17808+ err = 0;
17809+ sb = dentry->d_sb;
17810+ a->bdst = au_dbstart(dentry);
17811+ a->h_path.dentry = au_h_dptr(dentry, a->bdst);
17812+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
2cbb1c4b
JR
17813+ a->bsrc = au_ibstart(inode);
17814+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
38d290e6
JR
17815+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile)
17816+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc));
2cbb1c4b
JR
17817+ if (!h_src_dentry) {
17818+ a->bsrc = au_dbstart(src_dentry);
17819+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
17820+ AuDebugOn(!h_src_dentry);
38d290e6
JR
17821+ } else if (IS_ERR(h_src_dentry)) {
17822+ err = PTR_ERR(h_src_dentry);
2cbb1c4b 17823+ goto out_parent;
38d290e6 17824+ }
2cbb1c4b 17825+
4a4d8108
AM
17826+ if (au_opt_test(au_mntflags(sb), PLINK)) {
17827+ if (a->bdst < a->bsrc
17828+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
86dc4139 17829+ err = au_cpup_or_link(src_dentry, dentry, a);
523b37e3
AM
17830+ else {
17831+ delegated = NULL;
4a4d8108 17832+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
523b37e3
AM
17833+ &a->h_path, &delegated);
17834+ if (unlikely(err == -EWOULDBLOCK)) {
17835+ pr_warn("cannot retry for NFSv4 delegation"
17836+ " for an internal link\n");
17837+ iput(delegated);
17838+ }
17839+ }
2cbb1c4b 17840+ dput(h_src_dentry);
4a4d8108
AM
17841+ } else {
17842+ /*
17843+ * copyup src_dentry to the branch we process,
17844+ * and then link(2) to it.
17845+ */
2cbb1c4b 17846+ dput(h_src_dentry);
4a4d8108
AM
17847+ if (a->bdst < a->bsrc
17848+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
17849+ au_unpin(&a->pin);
17850+ di_write_unlock(a->parent);
17851+ err = au_cpup_before_link(src_dentry, a);
17852+ di_write_lock_parent(a->parent);
17853+ if (!err)
17854+ err = au_pin(&a->pin, dentry, a->bdst,
17855+ au_opt_udba(sb),
17856+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
17857+ if (unlikely(err))
17858+ goto out_wh;
17859+ }
17860+ if (!err) {
17861+ h_src_dentry = au_h_dptr(src_dentry, a->bdst);
17862+ err = -ENOENT;
523b37e3
AM
17863+ if (h_src_dentry && h_src_dentry->d_inode) {
17864+ delegated = NULL;
4a4d8108
AM
17865+ err = vfsub_link(h_src_dentry,
17866+ au_pinned_h_dir(&a->pin),
523b37e3
AM
17867+ &a->h_path, &delegated);
17868+ if (unlikely(err == -EWOULDBLOCK)) {
17869+ pr_warn("cannot retry"
17870+ " for NFSv4 delegation"
17871+ " for an internal link\n");
17872+ iput(delegated);
17873+ }
17874+ }
4a4d8108
AM
17875+ }
17876+ }
17877+ if (unlikely(err))
17878+ goto out_unpin;
17879+
17880+ if (wh_dentry) {
17881+ a->h_path.dentry = wh_dentry;
17882+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path,
17883+ dentry);
17884+ if (unlikely(err))
17885+ goto out_revert;
17886+ }
17887+
17888+ dir->i_version++;
17889+ if (au_ibstart(dir) == au_dbstart(dentry))
17890+ au_cpup_attr_timesizes(dir);
17891+ inc_nlink(inode);
17892+ inode->i_ctime = dir->i_ctime;
027c5e7a
AM
17893+ d_instantiate(dentry, au_igrab(inode));
17894+ if (d_unhashed(a->h_path.dentry))
4a4d8108
AM
17895+ /* some filesystem calls d_drop() */
17896+ d_drop(dentry);
076b876e
AM
17897+ /* some filesystems consume an inode even hardlink */
17898+ au_fhsm_wrote(sb, a->bdst, /*force*/0);
4a4d8108
AM
17899+ goto out_unpin; /* success */
17900+
4f0767ce 17901+out_revert:
523b37e3
AM
17902+ /* no delegation since it is just created */
17903+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path,
17904+ /*delegated*/NULL, /*force*/0);
027c5e7a 17905+ if (unlikely(rerr)) {
523b37e3 17906+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr);
027c5e7a
AM
17907+ err = -EIO;
17908+ }
4a4d8108 17909+ au_dtime_revert(&dt);
4f0767ce 17910+out_unpin:
4a4d8108 17911+ au_unpin(&a->pin);
4f0767ce 17912+out_wh:
4a4d8108 17913+ dput(wh_dentry);
027c5e7a
AM
17914+out_parent:
17915+ di_write_unlock(a->parent);
17916+ dput(a->src_parent);
4f0767ce 17917+out_unlock:
4a4d8108
AM
17918+ if (unlikely(err)) {
17919+ au_update_dbstart(dentry);
17920+ d_drop(dentry);
17921+ }
4a4d8108 17922+ aufs_read_and_write_unlock2(dentry, src_dentry);
e49829fe 17923+out_kfree:
4a4d8108 17924+ kfree(a);
4f0767ce 17925+out:
86dc4139 17926+ AuTraceErr(err);
4a4d8108
AM
17927+ return err;
17928+}
17929+
7eafdf33 17930+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
4a4d8108
AM
17931+{
17932+ int err, rerr;
17933+ aufs_bindex_t bindex;
17934+ unsigned char diropq;
17935+ struct path h_path;
17936+ struct dentry *wh_dentry, *parent, *opq_dentry;
17937+ struct mutex *h_mtx;
17938+ struct super_block *sb;
17939+ struct {
17940+ struct au_pin pin;
17941+ struct au_dtime dt;
17942+ } *a; /* reduce the stack usage */
17943+ struct au_wr_dir_args wr_dir_args = {
17944+ .force_btgt = -1,
17945+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR
17946+ };
17947+
17948+ IMustLock(dir);
17949+
17950+ err = -ENOMEM;
17951+ a = kmalloc(sizeof(*a), GFP_NOFS);
17952+ if (unlikely(!a))
17953+ goto out;
17954+
027c5e7a
AM
17955+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
17956+ if (unlikely(err))
17957+ goto out_free;
17958+ err = au_d_may_add(dentry);
17959+ if (unlikely(err))
17960+ goto out_unlock;
17961+
4a4d8108
AM
17962+ parent = dentry->d_parent; /* dir inode is locked */
17963+ di_write_lock_parent(parent);
17964+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL,
17965+ &a->pin, &wr_dir_args);
17966+ err = PTR_ERR(wh_dentry);
17967+ if (IS_ERR(wh_dentry))
027c5e7a 17968+ goto out_parent;
4a4d8108
AM
17969+
17970+ sb = dentry->d_sb;
17971+ bindex = au_dbstart(dentry);
17972+ h_path.dentry = au_h_dptr(dentry, bindex);
17973+ h_path.mnt = au_sbr_mnt(sb, bindex);
17974+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode);
17975+ if (unlikely(err))
027c5e7a 17976+ goto out_unpin;
4a4d8108
AM
17977+
17978+ /* make the dir opaque */
17979+ diropq = 0;
17980+ h_mtx = &h_path.dentry->d_inode->i_mutex;
17981+ if (wh_dentry
17982+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) {
17983+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
17984+ opq_dentry = au_diropq_create(dentry, bindex);
17985+ mutex_unlock(h_mtx);
17986+ err = PTR_ERR(opq_dentry);
17987+ if (IS_ERR(opq_dentry))
17988+ goto out_dir;
17989+ dput(opq_dentry);
17990+ diropq = 1;
17991+ }
17992+
17993+ err = epilog(dir, bindex, wh_dentry, dentry);
17994+ if (!err) {
17995+ inc_nlink(dir);
027c5e7a 17996+ goto out_unpin; /* success */
4a4d8108
AM
17997+ }
17998+
17999+ /* revert */
18000+ if (diropq) {
18001+ AuLabel(revert opq);
18002+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
18003+ rerr = au_diropq_remove(dentry, bindex);
18004+ mutex_unlock(h_mtx);
18005+ if (rerr) {
523b37e3
AM
18006+ AuIOErr("%pd reverting diropq failed(%d, %d)\n",
18007+ dentry, err, rerr);
4a4d8108
AM
18008+ err = -EIO;
18009+ }
18010+ }
18011+
4f0767ce 18012+out_dir:
4a4d8108
AM
18013+ AuLabel(revert dir);
18014+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path);
18015+ if (rerr) {
523b37e3
AM
18016+ AuIOErr("%pd reverting dir failed(%d, %d)\n",
18017+ dentry, err, rerr);
4a4d8108
AM
18018+ err = -EIO;
18019+ }
4a4d8108 18020+ au_dtime_revert(&a->dt);
027c5e7a 18021+out_unpin:
4a4d8108
AM
18022+ au_unpin(&a->pin);
18023+ dput(wh_dentry);
027c5e7a
AM
18024+out_parent:
18025+ di_write_unlock(parent);
18026+out_unlock:
4a4d8108
AM
18027+ if (unlikely(err)) {
18028+ au_update_dbstart(dentry);
18029+ d_drop(dentry);
18030+ }
4a4d8108 18031+ aufs_read_unlock(dentry, AuLock_DW);
027c5e7a 18032+out_free:
4a4d8108 18033+ kfree(a);
4f0767ce 18034+out:
4a4d8108
AM
18035+ return err;
18036+}
7f207e10
AM
18037diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
18038--- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
18039+++ linux/fs/aufs/i_op.c 2015-01-25 13:00:38.631047076 +0100
18040@@ -0,0 +1,1306 @@
4a4d8108 18041+/*
523b37e3 18042+ * Copyright (C) 2005-2014 Junjiro R. Okajima
4a4d8108
AM
18043+ *
18044+ * This program, aufs is free software; you can redistribute it and/or modify
18045+ * it under the terms of the GNU General Public License as published by
18046+ * the Free Software Foundation; either version 2 of the License, or
18047+ * (at your option) any later version.
18048+ *
18049+ * This program is distributed in the hope that it will be useful,
18050+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18051+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18052+ * GNU General Public License for more details.
18053+ *
18054+ * You should have received a copy of the GNU General Public License
523b37e3 18055+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4a4d8108 18056+ */
1facf9fc 18057+
1308ab2a 18058+/*
4a4d8108 18059+ * inode operations (except add/del/rename)
1308ab2a 18060+ */
4a4d8108
AM
18061+
18062+#include <linux/device_cgroup.h>
18063+#include <linux/fs_stack.h>
92d182d2 18064+#include <linux/mm.h>
4a4d8108
AM
18065+#include <linux/namei.h>
18066+#include <linux/security.h>
4a4d8108
AM
18067+#include "aufs.h"
18068+
1e00d052 18069+static int h_permission(struct inode *h_inode, int mask,
4a4d8108 18070+ struct vfsmount *h_mnt, int brperm)
1facf9fc 18071+{
1308ab2a 18072+ int err;
4a4d8108 18073+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
1facf9fc 18074+
4a4d8108
AM
18075+ err = -EACCES;
18076+ if ((write_mask && IS_IMMUTABLE(h_inode))
18077+ || ((mask & MAY_EXEC)
18078+ && S_ISREG(h_inode->i_mode)
18079+ && ((h_mnt->mnt_flags & MNT_NOEXEC)
18080+ || !(h_inode->i_mode & S_IXUGO))))
18081+ goto out;
18082+
18083+ /*
18084+ * - skip the lower fs test in the case of write to ro branch.
18085+ * - nfs dir permission write check is optimized, but a policy for
18086+ * link/rename requires a real check.
18087+ */
18088+ if ((write_mask && !au_br_writable(brperm))
18089+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode)
18090+ && write_mask && !(mask & MAY_READ))
18091+ || !h_inode->i_op->permission) {
18092+ /* AuLabel(generic_permission); */
1e00d052 18093+ err = generic_permission(h_inode, mask);
1308ab2a 18094+ } else {
4a4d8108 18095+ /* AuLabel(h_inode->permission); */
1e00d052 18096+ err = h_inode->i_op->permission(h_inode, mask);
4a4d8108
AM
18097+ AuTraceErr(err);
18098+ }
1facf9fc 18099+
4a4d8108
AM
18100+ if (!err)
18101+ err = devcgroup_inode_permission(h_inode, mask);
7f207e10 18102+ if (!err)
4a4d8108 18103+ err = security_inode_permission(h_inode, mask);
4a4d8108
AM
18104+
18105+#if 0
18106+ if (!err) {
18107+ /* todo: do we need to call ima_path_check()? */
18108+ struct path h_path = {
18109+ .dentry =
18110+ .mnt = h_mnt
18111+ };
18112+ err = ima_path_check(&h_path,
18113+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
18114+ IMA_COUNT_LEAVE);
1308ab2a 18115+ }
4a4d8108 18116+#endif
dece6358 18117+
4f0767ce 18118+out:
1308ab2a 18119+ return err;
18120+}
dece6358 18121+
1e00d052 18122+static int aufs_permission(struct inode *inode, int mask)
1308ab2a 18123+{
18124+ int err;
4a4d8108
AM
18125+ aufs_bindex_t bindex, bend;
18126+ const unsigned char isdir = !!S_ISDIR(inode->i_mode),
18127+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
18128+ struct inode *h_inode;
18129+ struct super_block *sb;
18130+ struct au_branch *br;
1facf9fc 18131+
027c5e7a 18132+ /* todo: support rcu-walk? */
1e00d052 18133+ if (mask & MAY_NOT_BLOCK)
027c5e7a
AM
18134+ return -ECHILD;
18135+
4a4d8108
AM
18136+ sb = inode->i_sb;
18137+ si_read_lock(sb, AuLock_FLUSH);
18138+ ii_read_lock_child(inode);
027c5e7a
AM
18139+#if 0
18140+ err = au_iigen_test(inode, au_sigen(sb));
18141+ if (unlikely(err))
18142+ goto out;
18143+#endif
dece6358 18144+
076b876e
AM
18145+ if (!isdir
18146+ || write_mask
18147+ || au_opt_test(au_mntflags(sb), DIRPERM1)) {
4a4d8108
AM
18148+ err = au_busy_or_stale();
18149+ h_inode = au_h_iptr(inode, au_ibstart(inode));
18150+ if (unlikely(!h_inode
18151+ || (h_inode->i_mode & S_IFMT)
18152+ != (inode->i_mode & S_IFMT)))
18153+ goto out;
1facf9fc 18154+
4a4d8108
AM
18155+ err = 0;
18156+ bindex = au_ibstart(inode);
18157+ br = au_sbr(sb, bindex);
86dc4139 18158+ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm);
4a4d8108
AM
18159+ if (write_mask
18160+ && !err
18161+ && !special_file(h_inode->i_mode)) {
18162+ /* test whether the upper writable branch exists */
18163+ err = -EROFS;
18164+ for (; bindex >= 0; bindex--)
18165+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
18166+ err = 0;
18167+ break;
18168+ }
18169+ }
18170+ goto out;
18171+ }
dece6358 18172+
4a4d8108 18173+ /* non-write to dir */
1308ab2a 18174+ err = 0;
4a4d8108
AM
18175+ bend = au_ibend(inode);
18176+ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) {
18177+ h_inode = au_h_iptr(inode, bindex);
18178+ if (h_inode) {
18179+ err = au_busy_or_stale();
18180+ if (unlikely(!S_ISDIR(h_inode->i_mode)))
18181+ break;
18182+
18183+ br = au_sbr(sb, bindex);
86dc4139 18184+ err = h_permission(h_inode, mask, au_br_mnt(br),
4a4d8108
AM
18185+ br->br_perm);
18186+ }
18187+ }
1308ab2a 18188+
4f0767ce 18189+out:
4a4d8108
AM
18190+ ii_read_unlock(inode);
18191+ si_read_unlock(sb);
1308ab2a 18192+ return err;
18193+}
18194+
4a4d8108 18195+/* ---------------------------------------------------------------------- */
1facf9fc 18196+
4a4d8108 18197+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry,
b4510431 18198+ unsigned int flags)
4a4d8108
AM
18199+{
18200+ struct dentry *ret, *parent;
b752ccd1 18201+ struct inode *inode;
4a4d8108 18202+ struct super_block *sb;
1716fcea 18203+ int err, npositive;
dece6358 18204+
4a4d8108 18205+ IMustLock(dir);
1308ab2a 18206+
537831f9
AM
18207+ /* todo: support rcu-walk? */
18208+ ret = ERR_PTR(-ECHILD);
18209+ if (flags & LOOKUP_RCU)
18210+ goto out;
18211+
18212+ ret = ERR_PTR(-ENAMETOOLONG);
18213+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN))
18214+ goto out;
18215+
4a4d8108 18216+ sb = dir->i_sb;
7f207e10
AM
18217+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18218+ ret = ERR_PTR(err);
18219+ if (unlikely(err))
18220+ goto out;
18221+
4a4d8108
AM
18222+ err = au_di_init(dentry);
18223+ ret = ERR_PTR(err);
18224+ if (unlikely(err))
7f207e10 18225+ goto out_si;
1308ab2a 18226+
9dbd164d 18227+ inode = NULL;
027c5e7a 18228+ npositive = 0; /* suppress a warning */
4a4d8108
AM
18229+ parent = dentry->d_parent; /* dir inode is locked */
18230+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
18231+ err = au_alive_dir(parent);
18232+ if (!err)
18233+ err = au_digen_test(parent, au_sigen(sb));
18234+ if (!err) {
18235+ npositive = au_lkup_dentry(dentry, au_dbstart(parent),
537831f9 18236+ /*type*/0);
027c5e7a
AM
18237+ err = npositive;
18238+ }
4a4d8108 18239+ di_read_unlock(parent, AuLock_IR);
4a4d8108
AM
18240+ ret = ERR_PTR(err);
18241+ if (unlikely(err < 0))
18242+ goto out_unlock;
1308ab2a 18243+
4a4d8108 18244+ if (npositive) {
b752ccd1 18245+ inode = au_new_inode(dentry, /*must_new*/0);
c1595e42
JR
18246+ if (IS_ERR(inode)) {
18247+ ret = (void *)inode;
18248+ inode = NULL;
18249+ goto out_unlock;
18250+ }
9dbd164d 18251+ }
4a4d8108 18252+
c1595e42
JR
18253+ if (inode)
18254+ atomic_inc(&inode->i_count);
4a4d8108 18255+ ret = d_splice_alias(inode, dentry);
c1595e42
JR
18256+ if (IS_ERR(ret)
18257+ && PTR_ERR(ret) == -EIO
18258+ && inode
18259+ && S_ISDIR(inode->i_mode)) {
18260+ atomic_inc(&inode->i_count);
18261+ ret = d_materialise_unique(dentry, inode);
18262+ if (!IS_ERR(ret))
18263+ ii_write_unlock(inode);
18264+ }
537831f9
AM
18265+#if 0
18266+ if (unlikely(d_need_lookup(dentry))) {
18267+ spin_lock(&dentry->d_lock);
18268+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
18269+ spin_unlock(&dentry->d_lock);
18270+ } else
18271+#endif
c1595e42
JR
18272+ if (inode) {
18273+ if (!IS_ERR(ret))
18274+ iput(inode);
18275+ else {
18276+ ii_write_unlock(inode);
18277+ iput(inode);
18278+ inode = NULL;
18279+ }
7f207e10 18280+ }
1facf9fc 18281+
4f0767ce 18282+out_unlock:
4a4d8108 18283+ di_write_unlock(dentry);
2dfbb274 18284+ if (inode) {
1716fcea
AM
18285+ /* verbose coding for lock class name */
18286+ if (unlikely(S_ISLNK(inode->i_mode)))
18287+ au_rw_class(&au_di(dentry)->di_rwsem,
18288+ au_lc_key + AuLcSymlink_DIINFO);
18289+ else if (unlikely(S_ISDIR(inode->i_mode)))
18290+ au_rw_class(&au_di(dentry)->di_rwsem,
18291+ au_lc_key + AuLcDir_DIINFO);
18292+ else /* likely */
18293+ au_rw_class(&au_di(dentry)->di_rwsem,
18294+ au_lc_key + AuLcNonDir_DIINFO);
9dbd164d 18295+ }
7f207e10 18296+out_si:
4a4d8108 18297+ si_read_unlock(sb);
7f207e10 18298+out:
4a4d8108
AM
18299+ return ret;
18300+}
1facf9fc 18301+
4a4d8108 18302+/* ---------------------------------------------------------------------- */
1facf9fc 18303+
4a4d8108
AM
18304+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent,
18305+ const unsigned char add_entry, aufs_bindex_t bcpup,
18306+ aufs_bindex_t bstart)
18307+{
18308+ int err;
18309+ struct dentry *h_parent;
18310+ struct inode *h_dir;
1facf9fc 18311+
027c5e7a 18312+ if (add_entry)
4a4d8108 18313+ IMustLock(parent->d_inode);
027c5e7a 18314+ else
4a4d8108
AM
18315+ di_write_lock_parent(parent);
18316+
18317+ err = 0;
18318+ if (!au_h_dptr(parent, bcpup)) {
c2b27bf2
AM
18319+ if (bstart > bcpup)
18320+ err = au_cpup_dirs(dentry, bcpup);
18321+ else if (bstart < bcpup)
4a4d8108
AM
18322+ err = au_cpdown_dirs(dentry, bcpup);
18323+ else
c2b27bf2 18324+ BUG();
4a4d8108 18325+ }
38d290e6 18326+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
4a4d8108
AM
18327+ h_parent = au_h_dptr(parent, bcpup);
18328+ h_dir = h_parent->d_inode;
18329+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
86dc4139
AM
18330+ err = au_lkup_neg(dentry, bcpup,
18331+ au_ftest_wrdir(add_entry, TMP_WHENTRY));
4a4d8108
AM
18332+ /* todo: no unlock here */
18333+ mutex_unlock(&h_dir->i_mutex);
027c5e7a
AM
18334+
18335+ AuDbg("bcpup %d\n", bcpup);
18336+ if (!err) {
18337+ if (!dentry->d_inode)
18338+ au_set_h_dptr(dentry, bstart, NULL);
4a4d8108
AM
18339+ au_update_dbrange(dentry, /*do_put_zero*/0);
18340+ }
1308ab2a 18341+ }
1facf9fc 18342+
4a4d8108
AM
18343+ if (!add_entry)
18344+ di_write_unlock(parent);
18345+ if (!err)
18346+ err = bcpup; /* success */
1308ab2a 18347+
027c5e7a 18348+ AuTraceErr(err);
4a4d8108
AM
18349+ return err;
18350+}
1facf9fc 18351+
4a4d8108
AM
18352+/*
18353+ * decide the branch and the parent dir where we will create a new entry.
18354+ * returns new bindex or an error.
18355+ * copyup the parent dir if needed.
18356+ */
18357+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
18358+ struct au_wr_dir_args *args)
18359+{
18360+ int err;
392086de 18361+ unsigned int flags;
4a4d8108 18362+ aufs_bindex_t bcpup, bstart, src_bstart;
86dc4139
AM
18363+ const unsigned char add_entry
18364+ = au_ftest_wrdir(args->flags, ADD_ENTRY)
38d290e6
JR
18365+ | au_ftest_wrdir(args->flags, TMP_WHENTRY)
18366+ | au_ftest_wrdir(args->flags, TMPFILE);
4a4d8108
AM
18367+ struct super_block *sb;
18368+ struct dentry *parent;
18369+ struct au_sbinfo *sbinfo;
1facf9fc 18370+
4a4d8108
AM
18371+ sb = dentry->d_sb;
18372+ sbinfo = au_sbi(sb);
18373+ parent = dget_parent(dentry);
18374+ bstart = au_dbstart(dentry);
18375+ bcpup = bstart;
18376+ if (args->force_btgt < 0) {
18377+ if (src_dentry) {
18378+ src_bstart = au_dbstart(src_dentry);
18379+ if (src_bstart < bstart)
18380+ bcpup = src_bstart;
18381+ } else if (add_entry) {
392086de
AM
18382+ flags = 0;
18383+ if (au_ftest_wrdir(args->flags, ISDIR))
18384+ au_fset_wbr(flags, DIR);
18385+ err = AuWbrCreate(sbinfo, dentry, flags);
4a4d8108
AM
18386+ bcpup = err;
18387+ }
1facf9fc 18388+
4a4d8108
AM
18389+ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
18390+ if (add_entry)
18391+ err = AuWbrCopyup(sbinfo, dentry);
18392+ else {
18393+ if (!IS_ROOT(dentry)) {
18394+ di_read_lock_parent(parent, !AuLock_IR);
18395+ err = AuWbrCopyup(sbinfo, dentry);
18396+ di_read_unlock(parent, !AuLock_IR);
18397+ } else
18398+ err = AuWbrCopyup(sbinfo, dentry);
18399+ }
18400+ bcpup = err;
18401+ if (unlikely(err < 0))
18402+ goto out;
18403+ }
18404+ } else {
18405+ bcpup = args->force_btgt;
18406+ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
1308ab2a 18407+ }
027c5e7a 18408+
4a4d8108
AM
18409+ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup);
18410+ err = bcpup;
18411+ if (bcpup == bstart)
18412+ goto out; /* success */
4a4d8108
AM
18413+
18414+ /* copyup the new parent into the branch we process */
18415+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart);
027c5e7a
AM
18416+ if (err >= 0) {
18417+ if (!dentry->d_inode) {
18418+ au_set_h_dptr(dentry, bstart, NULL);
18419+ au_set_dbstart(dentry, bcpup);
18420+ au_set_dbend(dentry, bcpup);
18421+ }
38d290e6
JR
18422+ AuDebugOn(add_entry
18423+ && !au_ftest_wrdir(args->flags, TMPFILE)
18424+ && !au_h_dptr(dentry, bcpup));
027c5e7a 18425+ }
86dc4139
AM
18426+
18427+out:
18428+ dput(parent);
18429+ return err;
18430+}
18431+
18432+/* ---------------------------------------------------------------------- */
18433+
18434+void au_pin_hdir_unlock(struct au_pin *p)
18435+{
18436+ if (p->hdir)
18437+ au_hn_imtx_unlock(p->hdir);
18438+}
18439+
c1595e42 18440+int au_pin_hdir_lock(struct au_pin *p)
86dc4139
AM
18441+{
18442+ int err;
18443+
18444+ err = 0;
18445+ if (!p->hdir)
18446+ goto out;
18447+
18448+ /* even if an error happens later, keep this lock */
18449+ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
18450+
18451+ err = -EBUSY;
18452+ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode))
18453+ goto out;
18454+
18455+ err = 0;
18456+ if (p->h_dentry)
18457+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode,
18458+ p->h_parent, p->br);
18459+
18460+out:
18461+ return err;
18462+}
18463+
18464+int au_pin_hdir_relock(struct au_pin *p)
18465+{
18466+ int err, i;
18467+ struct inode *h_i;
18468+ struct dentry *h_d[] = {
18469+ p->h_dentry,
18470+ p->h_parent
18471+ };
18472+
18473+ err = au_pin_hdir_lock(p);
18474+ if (unlikely(err))
18475+ goto out;
18476+
18477+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) {
18478+ if (!h_d[i])
18479+ continue;
18480+ h_i = h_d[i]->d_inode;
18481+ if (h_i)
18482+ err = !h_i->i_nlink;
18483+ }
18484+
18485+out:
18486+ return err;
18487+}
18488+
18489+void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task)
18490+{
18491+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
18492+ p->hdir->hi_inode->i_mutex.owner = task;
18493+#endif
18494+}
18495+
18496+void au_pin_hdir_acquire_nest(struct au_pin *p)
18497+{
18498+ if (p->hdir) {
18499+ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map,
18500+ p->lsc_hi, 0, NULL, _RET_IP_);
18501+ au_pin_hdir_set_owner(p, current);
18502+ }
dece6358 18503+}
1facf9fc 18504+
86dc4139
AM
18505+void au_pin_hdir_release(struct au_pin *p)
18506+{
18507+ if (p->hdir) {
18508+ au_pin_hdir_set_owner(p, p->task);
18509+ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_);
18510+ }
18511+}
1308ab2a 18512+
4a4d8108 18513+struct dentry *au_pinned_h_parent(struct au_pin *pin)
1308ab2a 18514+{
4a4d8108
AM
18515+ if (pin && pin->parent)
18516+ return au_h_dptr(pin->parent, pin->bindex);
18517+ return NULL;
dece6358 18518+}
1facf9fc 18519+
4a4d8108 18520+void au_unpin(struct au_pin *p)
dece6358 18521+{
86dc4139
AM
18522+ if (p->hdir)
18523+ au_pin_hdir_unlock(p);
e49829fe 18524+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE))
b4510431 18525+ vfsub_mnt_drop_write(p->h_mnt);
4a4d8108
AM
18526+ if (!p->hdir)
18527+ return;
1facf9fc 18528+
4a4d8108
AM
18529+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18530+ di_read_unlock(p->parent, AuLock_IR);
18531+ iput(p->hdir->hi_inode);
18532+ dput(p->parent);
18533+ p->parent = NULL;
18534+ p->hdir = NULL;
18535+ p->h_mnt = NULL;
86dc4139 18536+ /* do not clear p->task */
4a4d8108 18537+}
1308ab2a 18538+
4a4d8108
AM
18539+int au_do_pin(struct au_pin *p)
18540+{
18541+ int err;
18542+ struct super_block *sb;
4a4d8108
AM
18543+ struct inode *h_dir;
18544+
18545+ err = 0;
18546+ sb = p->dentry->d_sb;
86dc4139 18547+ p->br = au_sbr(sb, p->bindex);
4a4d8108
AM
18548+ if (IS_ROOT(p->dentry)) {
18549+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18550+ p->h_mnt = au_br_mnt(p->br);
b4510431 18551+ err = vfsub_mnt_want_write(p->h_mnt);
4a4d8108
AM
18552+ if (unlikely(err)) {
18553+ au_fclr_pin(p->flags, MNT_WRITE);
18554+ goto out_err;
18555+ }
18556+ }
dece6358 18557+ goto out;
1facf9fc 18558+ }
18559+
86dc4139 18560+ p->h_dentry = NULL;
4a4d8108 18561+ if (p->bindex <= au_dbend(p->dentry))
86dc4139 18562+ p->h_dentry = au_h_dptr(p->dentry, p->bindex);
dece6358 18563+
4a4d8108
AM
18564+ p->parent = dget_parent(p->dentry);
18565+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18566+ di_read_lock(p->parent, AuLock_IR, p->lsc_di);
dece6358 18567+
4a4d8108 18568+ h_dir = NULL;
86dc4139 18569+ p->h_parent = au_h_dptr(p->parent, p->bindex);
4a4d8108
AM
18570+ p->hdir = au_hi(p->parent->d_inode, p->bindex);
18571+ if (p->hdir)
18572+ h_dir = p->hdir->hi_inode;
dece6358 18573+
b752ccd1
AM
18574+ /*
18575+ * udba case, or
18576+ * if DI_LOCKED is not set, then p->parent may be different
18577+ * and h_parent can be NULL.
18578+ */
86dc4139 18579+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) {
e49829fe 18580+ err = -EBUSY;
4a4d8108
AM
18581+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18582+ di_read_unlock(p->parent, AuLock_IR);
18583+ dput(p->parent);
18584+ p->parent = NULL;
18585+ goto out_err;
18586+ }
1308ab2a 18587+
4a4d8108 18588+ if (au_ftest_pin(p->flags, MNT_WRITE)) {
86dc4139 18589+ p->h_mnt = au_br_mnt(p->br);
b4510431 18590+ err = vfsub_mnt_want_write(p->h_mnt);
dece6358 18591+ if (unlikely(err)) {
4a4d8108 18592+ au_fclr_pin(p->flags, MNT_WRITE);
86dc4139
AM
18593+ if (!au_ftest_pin(p->flags, DI_LOCKED))
18594+ di_read_unlock(p->parent, AuLock_IR);
18595+ dput(p->parent);
18596+ p->parent = NULL;
18597+ goto out_err;
dece6358
AM
18598+ }
18599+ }
4a4d8108 18600+
86dc4139
AM
18601+ au_igrab(h_dir);
18602+ err = au_pin_hdir_lock(p);
18603+ if (!err)
18604+ goto out; /* success */
18605+
076b876e
AM
18606+ au_unpin(p);
18607+
4f0767ce 18608+out_err:
4a4d8108
AM
18609+ pr_err("err %d\n", err);
18610+ err = au_busy_or_stale();
4f0767ce 18611+out:
1facf9fc 18612+ return err;
18613+}
18614+
4a4d8108
AM
18615+void au_pin_init(struct au_pin *p, struct dentry *dentry,
18616+ aufs_bindex_t bindex, int lsc_di, int lsc_hi,
18617+ unsigned int udba, unsigned char flags)
18618+{
18619+ p->dentry = dentry;
18620+ p->udba = udba;
18621+ p->lsc_di = lsc_di;
18622+ p->lsc_hi = lsc_hi;
18623+ p->flags = flags;
18624+ p->bindex = bindex;
18625+
18626+ p->parent = NULL;
18627+ p->hdir = NULL;
18628+ p->h_mnt = NULL;
86dc4139
AM
18629+
18630+ p->h_dentry = NULL;
18631+ p->h_parent = NULL;
18632+ p->br = NULL;
18633+ p->task = current;
4a4d8108
AM
18634+}
18635+
18636+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex,
18637+ unsigned int udba, unsigned char flags)
18638+{
18639+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2,
18640+ udba, flags);
18641+ return au_do_pin(pin);
18642+}
18643+
dece6358
AM
18644+/* ---------------------------------------------------------------------- */
18645+
1308ab2a 18646+/*
4a4d8108
AM
18647+ * ->setattr() and ->getattr() are called in various cases.
18648+ * chmod, stat: dentry is revalidated.
18649+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be
18650+ * unhashed.
18651+ * for ->setattr(), ia->ia_file is passed from ftruncate only.
1308ab2a 18652+ */
027c5e7a 18653+/* todo: consolidate with do_refresh() and simple_reval_dpath() */
c1595e42 18654+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen)
1facf9fc 18655+{
4a4d8108
AM
18656+ int err;
18657+ struct inode *inode;
18658+ struct dentry *parent;
1facf9fc 18659+
1308ab2a 18660+ err = 0;
4a4d8108 18661+ inode = dentry->d_inode;
027c5e7a 18662+ if (au_digen_test(dentry, sigen)) {
4a4d8108
AM
18663+ parent = dget_parent(dentry);
18664+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a 18665+ err = au_refresh_dentry(dentry, parent);
4a4d8108
AM
18666+ di_read_unlock(parent, AuLock_IR);
18667+ dput(parent);
dece6358 18668+ }
1facf9fc 18669+
4a4d8108 18670+ AuTraceErr(err);
1308ab2a 18671+ return err;
18672+}
dece6358 18673+
c1595e42
JR
18674+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia,
18675+ struct au_icpup_args *a)
1308ab2a 18676+{
18677+ int err;
4a4d8108 18678+ loff_t sz;
e49829fe 18679+ aufs_bindex_t bstart, ibstart;
4a4d8108
AM
18680+ struct dentry *hi_wh, *parent;
18681+ struct inode *inode;
4a4d8108
AM
18682+ struct au_wr_dir_args wr_dir_args = {
18683+ .force_btgt = -1,
18684+ .flags = 0
18685+ };
18686+
18687+ bstart = au_dbstart(dentry);
18688+ inode = dentry->d_inode;
18689+ if (S_ISDIR(inode->i_mode))
18690+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
18691+ /* plink or hi_wh() case */
e49829fe 18692+ ibstart = au_ibstart(inode);
027c5e7a 18693+ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode))
e49829fe 18694+ wr_dir_args.force_btgt = ibstart;
4a4d8108
AM
18695+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
18696+ if (unlikely(err < 0))
18697+ goto out;
18698+ a->btgt = err;
18699+ if (err != bstart)
18700+ au_fset_icpup(a->flags, DID_CPUP);
18701+
18702+ err = 0;
18703+ a->pin_flags = AuPin_MNT_WRITE;
18704+ parent = NULL;
18705+ if (!IS_ROOT(dentry)) {
18706+ au_fset_pin(a->pin_flags, DI_LOCKED);
18707+ parent = dget_parent(dentry);
18708+ di_write_lock_parent(parent);
18709+ }
18710+
18711+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags);
18712+ if (unlikely(err))
18713+ goto out_parent;
18714+
18715+ a->h_path.dentry = au_h_dptr(dentry, bstart);
18716+ a->h_inode = a->h_path.dentry->d_inode;
4a4d8108 18717+ sz = -1;
c1595e42
JR
18718+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
18719+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
18720+ if (ia->ia_size < i_size_read(a->h_inode))
18721+ sz = ia->ia_size;
18722+ mutex_unlock(&a->h_inode->i_mutex);
18723+ }
4a4d8108 18724+
4a4d8108 18725+ hi_wh = NULL;
027c5e7a 18726+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) {
4a4d8108
AM
18727+ hi_wh = au_hi_wh(inode, a->btgt);
18728+ if (!hi_wh) {
c2b27bf2
AM
18729+ struct au_cp_generic cpg = {
18730+ .dentry = dentry,
18731+ .bdst = a->btgt,
18732+ .bsrc = -1,
18733+ .len = sz,
18734+ .pin = &a->pin
18735+ };
18736+ err = au_sio_cpup_wh(&cpg, /*file*/NULL);
4a4d8108
AM
18737+ if (unlikely(err))
18738+ goto out_unlock;
18739+ hi_wh = au_hi_wh(inode, a->btgt);
18740+ /* todo: revalidate hi_wh? */
18741+ }
18742+ }
18743+
18744+ if (parent) {
18745+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0);
18746+ di_downgrade_lock(parent, AuLock_IR);
18747+ dput(parent);
18748+ parent = NULL;
18749+ }
18750+ if (!au_ftest_icpup(a->flags, DID_CPUP))
18751+ goto out; /* success */
18752+
18753+ if (!d_unhashed(dentry)) {
c2b27bf2
AM
18754+ struct au_cp_generic cpg = {
18755+ .dentry = dentry,
18756+ .bdst = a->btgt,
18757+ .bsrc = bstart,
18758+ .len = sz,
18759+ .pin = &a->pin,
18760+ .flags = AuCpup_DTIME | AuCpup_HOPEN
18761+ };
18762+ err = au_sio_cpup_simple(&cpg);
4a4d8108
AM
18763+ if (!err)
18764+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18765+ } else if (!hi_wh)
18766+ a->h_path.dentry = au_h_dptr(dentry, a->btgt);
18767+ else
18768+ a->h_path.dentry = hi_wh; /* do not dget here */
1308ab2a 18769+
4f0767ce 18770+out_unlock:
4a4d8108 18771+ a->h_inode = a->h_path.dentry->d_inode;
86dc4139 18772+ if (!err)
dece6358 18773+ goto out; /* success */
4a4d8108 18774+ au_unpin(&a->pin);
4f0767ce 18775+out_parent:
4a4d8108
AM
18776+ if (parent) {
18777+ di_write_unlock(parent);
18778+ dput(parent);
18779+ }
4f0767ce 18780+out:
86dc4139
AM
18781+ if (!err)
18782+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
1facf9fc 18783+ return err;
18784+}
18785+
4a4d8108 18786+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
1facf9fc 18787+{
4a4d8108 18788+ int err;
523b37e3 18789+ struct inode *inode, *delegated;
4a4d8108
AM
18790+ struct super_block *sb;
18791+ struct file *file;
18792+ struct au_icpup_args *a;
1facf9fc 18793+
4a4d8108
AM
18794+ inode = dentry->d_inode;
18795+ IMustLock(inode);
dece6358 18796+
4a4d8108
AM
18797+ err = -ENOMEM;
18798+ a = kzalloc(sizeof(*a), GFP_NOFS);
18799+ if (unlikely(!a))
18800+ goto out;
1facf9fc 18801+
4a4d8108
AM
18802+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
18803+ ia->ia_valid &= ~ATTR_MODE;
dece6358 18804+
4a4d8108
AM
18805+ file = NULL;
18806+ sb = dentry->d_sb;
e49829fe
JR
18807+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18808+ if (unlikely(err))
18809+ goto out_kfree;
18810+
4a4d8108
AM
18811+ if (ia->ia_valid & ATTR_FILE) {
18812+ /* currently ftruncate(2) only */
18813+ AuDebugOn(!S_ISREG(inode->i_mode));
18814+ file = ia->ia_file;
18815+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
18816+ if (unlikely(err))
18817+ goto out_si;
18818+ ia->ia_file = au_hf_top(file);
18819+ a->udba = AuOpt_UDBA_NONE;
18820+ } else {
18821+ /* fchmod() doesn't pass ia_file */
18822+ a->udba = au_opt_udba(sb);
027c5e7a
AM
18823+ di_write_lock_child(dentry);
18824+ /* no d_unlinked(), to set UDBA_NONE for root */
4a4d8108
AM
18825+ if (d_unhashed(dentry))
18826+ a->udba = AuOpt_UDBA_NONE;
4a4d8108
AM
18827+ if (a->udba != AuOpt_UDBA_NONE) {
18828+ AuDebugOn(IS_ROOT(dentry));
18829+ err = au_reval_for_attr(dentry, au_sigen(sb));
18830+ if (unlikely(err))
18831+ goto out_dentry;
18832+ }
dece6358 18833+ }
dece6358 18834+
4a4d8108
AM
18835+ err = au_pin_and_icpup(dentry, ia, a);
18836+ if (unlikely(err < 0))
18837+ goto out_dentry;
18838+ if (au_ftest_icpup(a->flags, DID_CPUP)) {
18839+ ia->ia_file = NULL;
18840+ ia->ia_valid &= ~ATTR_FILE;
1308ab2a 18841+ }
dece6358 18842+
4a4d8108
AM
18843+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt);
18844+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME))
18845+ == (ATTR_MODE | ATTR_CTIME)) {
7eafdf33 18846+ err = security_path_chmod(&a->h_path, ia->ia_mode);
4a4d8108
AM
18847+ if (unlikely(err))
18848+ goto out_unlock;
18849+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID))
18850+ && (ia->ia_valid & ATTR_CTIME)) {
86dc4139 18851+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid);
4a4d8108
AM
18852+ if (unlikely(err))
18853+ goto out_unlock;
18854+ }
dece6358 18855+
4a4d8108
AM
18856+ if (ia->ia_valid & ATTR_SIZE) {
18857+ struct file *f;
1308ab2a 18858+
953406b4 18859+ if (ia->ia_size < i_size_read(inode))
4a4d8108 18860+ /* unmap only */
953406b4 18861+ truncate_setsize(inode, ia->ia_size);
1308ab2a 18862+
4a4d8108
AM
18863+ f = NULL;
18864+ if (ia->ia_valid & ATTR_FILE)
18865+ f = ia->ia_file;
18866+ mutex_unlock(&a->h_inode->i_mutex);
18867+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f);
18868+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD);
523b37e3
AM
18869+ } else {
18870+ delegated = NULL;
18871+ while (1) {
18872+ err = vfsub_notify_change(&a->h_path, ia, &delegated);
18873+ if (delegated) {
18874+ err = break_deleg_wait(&delegated);
18875+ if (!err)
18876+ continue;
18877+ }
18878+ break;
18879+ }
18880+ }
4a4d8108
AM
18881+ if (!err)
18882+ au_cpup_attr_changeable(inode);
1308ab2a 18883+
4f0767ce 18884+out_unlock:
4a4d8108
AM
18885+ mutex_unlock(&a->h_inode->i_mutex);
18886+ au_unpin(&a->pin);
027c5e7a
AM
18887+ if (unlikely(err))
18888+ au_update_dbstart(dentry);
4f0767ce 18889+out_dentry:
4a4d8108
AM
18890+ di_write_unlock(dentry);
18891+ if (file) {
18892+ fi_write_unlock(file);
18893+ ia->ia_file = file;
18894+ ia->ia_valid |= ATTR_FILE;
18895+ }
4f0767ce 18896+out_si:
4a4d8108 18897+ si_read_unlock(sb);
e49829fe 18898+out_kfree:
4a4d8108 18899+ kfree(a);
4f0767ce 18900+out:
4a4d8108
AM
18901+ AuTraceErr(err);
18902+ return err;
1facf9fc 18903+}
18904+
c1595e42
JR
18905+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL)
18906+static int au_h_path_to_set_attr(struct dentry *dentry,
18907+ struct au_icpup_args *a, struct path *h_path)
18908+{
18909+ int err;
18910+ struct super_block *sb;
18911+
18912+ sb = dentry->d_sb;
18913+ a->udba = au_opt_udba(sb);
18914+ /* no d_unlinked(), to set UDBA_NONE for root */
18915+ if (d_unhashed(dentry))
18916+ a->udba = AuOpt_UDBA_NONE;
18917+ if (a->udba != AuOpt_UDBA_NONE) {
18918+ AuDebugOn(IS_ROOT(dentry));
18919+ err = au_reval_for_attr(dentry, au_sigen(sb));
18920+ if (unlikely(err))
18921+ goto out;
18922+ }
18923+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a);
18924+ if (unlikely(err < 0))
18925+ goto out;
18926+
18927+ h_path->dentry = a->h_path.dentry;
18928+ h_path->mnt = au_sbr_mnt(sb, a->btgt);
18929+
18930+out:
18931+ return err;
18932+}
18933+
18934+ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg)
18935+{
18936+ int err;
18937+ struct path h_path;
18938+ struct super_block *sb;
18939+ struct au_icpup_args *a;
18940+ struct inode *inode, *h_inode;
18941+
18942+ inode = dentry->d_inode;
18943+ IMustLock(inode);
18944+
18945+ err = -ENOMEM;
18946+ a = kzalloc(sizeof(*a), GFP_NOFS);
18947+ if (unlikely(!a))
18948+ goto out;
18949+
18950+ sb = dentry->d_sb;
18951+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
18952+ if (unlikely(err))
18953+ goto out_kfree;
18954+
18955+ h_path.dentry = NULL; /* silence gcc */
18956+ di_write_lock_child(dentry);
18957+ err = au_h_path_to_set_attr(dentry, a, &h_path);
18958+ if (unlikely(err))
18959+ goto out_di;
18960+
18961+ mutex_unlock(&a->h_inode->i_mutex);
18962+ switch (arg->type) {
18963+ case AU_XATTR_SET:
18964+ err = vfsub_setxattr(h_path.dentry,
18965+ arg->u.set.name, arg->u.set.value,
18966+ arg->u.set.size, arg->u.set.flags);
18967+ break;
18968+ case AU_XATTR_REMOVE:
18969+ err = vfsub_removexattr(h_path.dentry, arg->u.remove.name);
18970+ break;
18971+ case AU_ACL_SET:
18972+ err = -EOPNOTSUPP;
18973+ h_inode = h_path.dentry->d_inode;
18974+ if (h_inode->i_op->set_acl)
18975+ err = h_inode->i_op->set_acl(h_inode,
18976+ arg->u.acl_set.acl,
18977+ arg->u.acl_set.type);
18978+ break;
18979+ }
18980+ if (!err)
18981+ au_cpup_attr_timesizes(inode);
18982+
18983+ au_unpin(&a->pin);
18984+ if (unlikely(err))
18985+ au_update_dbstart(dentry);
18986+
18987+out_di:
18988+ di_write_unlock(dentry);
18989+ si_read_unlock(sb);
18990+out_kfree:
18991+ kfree(a);
18992+out:
18993+ AuTraceErr(err);
18994+ return err;
18995+}
18996+#endif
18997+
4a4d8108
AM
18998+static void au_refresh_iattr(struct inode *inode, struct kstat *st,
18999+ unsigned int nlink)
1facf9fc 19000+{
9dbd164d
AM
19001+ unsigned int n;
19002+
4a4d8108 19003+ inode->i_mode = st->mode;
86dc4139
AM
19004+ /* don't i_[ug]id_write() here */
19005+ inode->i_uid = st->uid;
19006+ inode->i_gid = st->gid;
4a4d8108
AM
19007+ inode->i_atime = st->atime;
19008+ inode->i_mtime = st->mtime;
19009+ inode->i_ctime = st->ctime;
1facf9fc 19010+
4a4d8108
AM
19011+ au_cpup_attr_nlink(inode, /*force*/0);
19012+ if (S_ISDIR(inode->i_mode)) {
9dbd164d
AM
19013+ n = inode->i_nlink;
19014+ n -= nlink;
19015+ n += st->nlink;
f6b6e03d 19016+ smp_mb(); /* for i_nlink */
7eafdf33 19017+ /* 0 can happen */
92d182d2 19018+ set_nlink(inode, n);
4a4d8108 19019+ }
1facf9fc 19020+
4a4d8108
AM
19021+ spin_lock(&inode->i_lock);
19022+ inode->i_blocks = st->blocks;
19023+ i_size_write(inode, st->size);
19024+ spin_unlock(&inode->i_lock);
1facf9fc 19025+}
19026+
c1595e42
JR
19027+/*
19028+ * common routine for aufs_getattr() and aufs_getxattr().
19029+ * returns zero or negative (an error).
19030+ * @dentry will be read-locked in success.
19031+ */
19032+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path)
1facf9fc 19033+{
4a4d8108 19034+ int err;
076b876e 19035+ unsigned int mnt_flags, sigen;
c1595e42 19036+ unsigned char udba_none;
4a4d8108 19037+ aufs_bindex_t bindex;
4a4d8108
AM
19038+ struct super_block *sb, *h_sb;
19039+ struct inode *inode;
1facf9fc 19040+
c1595e42
JR
19041+ h_path->mnt = NULL;
19042+ h_path->dentry = NULL;
19043+
19044+ err = 0;
4a4d8108 19045+ sb = dentry->d_sb;
4a4d8108
AM
19046+ mnt_flags = au_mntflags(sb);
19047+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
1facf9fc 19048+
4a4d8108 19049+ /* support fstat(2) */
027c5e7a 19050+ if (!d_unlinked(dentry) && !udba_none) {
076b876e 19051+ sigen = au_sigen(sb);
027c5e7a
AM
19052+ err = au_digen_test(dentry, sigen);
19053+ if (!err) {
4a4d8108 19054+ di_read_lock_child(dentry, AuLock_IR);
027c5e7a 19055+ err = au_dbrange_test(dentry);
c1595e42
JR
19056+ if (unlikely(err)) {
19057+ di_read_unlock(dentry, AuLock_IR);
19058+ goto out;
19059+ }
027c5e7a 19060+ } else {
4a4d8108
AM
19061+ AuDebugOn(IS_ROOT(dentry));
19062+ di_write_lock_child(dentry);
027c5e7a
AM
19063+ err = au_dbrange_test(dentry);
19064+ if (!err)
19065+ err = au_reval_for_attr(dentry, sigen);
c1595e42
JR
19066+ if (!err)
19067+ di_downgrade_lock(dentry, AuLock_IR);
19068+ else {
19069+ di_write_unlock(dentry);
19070+ goto out;
19071+ }
4a4d8108
AM
19072+ }
19073+ } else
19074+ di_read_lock_child(dentry, AuLock_IR);
1facf9fc 19075+
c1595e42 19076+ inode = dentry->d_inode;
4a4d8108 19077+ bindex = au_ibstart(inode);
c1595e42
JR
19078+ h_path->mnt = au_sbr_mnt(sb, bindex);
19079+ h_sb = h_path->mnt->mnt_sb;
19080+ if (!force
19081+ && !au_test_fs_bad_iattr(h_sb)
19082+ && udba_none)
19083+ goto out; /* success */
1facf9fc 19084+
4a4d8108 19085+ if (au_dbstart(dentry) == bindex)
c1595e42 19086+ h_path->dentry = au_h_dptr(dentry, bindex);
4a4d8108 19087+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) {
c1595e42
JR
19088+ h_path->dentry = au_plink_lkup(inode, bindex);
19089+ if (IS_ERR(h_path->dentry))
19090+ /* pretending success */
19091+ h_path->dentry = NULL;
19092+ else
19093+ dput(h_path->dentry);
4a4d8108 19094+ }
c1595e42
JR
19095+
19096+out:
19097+ return err;
19098+}
19099+
19100+static int aufs_getattr(struct vfsmount *mnt __maybe_unused,
19101+ struct dentry *dentry, struct kstat *st)
19102+{
19103+ int err;
19104+ unsigned char positive;
19105+ struct path h_path;
19106+ struct inode *inode;
19107+ struct super_block *sb;
19108+
19109+ inode = dentry->d_inode;
19110+ sb = dentry->d_sb;
19111+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
19112+ if (unlikely(err))
19113+ goto out;
19114+ err = au_h_path_getattr(dentry, /*force*/0, &h_path);
19115+ if (unlikely(err))
19116+ goto out_si;
c06a8ce3 19117+ if (unlikely(!h_path.dentry))
c1595e42 19118+ /* illegally overlapped or something */
4a4d8108
AM
19119+ goto out_fill; /* pretending success */
19120+
c06a8ce3 19121+ positive = !!h_path.dentry->d_inode;
4a4d8108 19122+ if (positive)
c06a8ce3 19123+ err = vfs_getattr(&h_path, st);
4a4d8108
AM
19124+ if (!err) {
19125+ if (positive)
c06a8ce3
AM
19126+ au_refresh_iattr(inode, st,
19127+ h_path.dentry->d_inode->i_nlink);
4a4d8108 19128+ goto out_fill; /* success */
1facf9fc 19129+ }
7f207e10 19130+ AuTraceErr(err);
c1595e42 19131+ goto out_di;
4a4d8108 19132+
4f0767ce 19133+out_fill:
4a4d8108 19134+ generic_fillattr(inode, st);
c1595e42 19135+out_di:
4a4d8108 19136+ di_read_unlock(dentry, AuLock_IR);
c1595e42 19137+out_si:
4a4d8108 19138+ si_read_unlock(sb);
7f207e10
AM
19139+out:
19140+ AuTraceErr(err);
4a4d8108 19141+ return err;
1facf9fc 19142+}
19143+
19144+/* ---------------------------------------------------------------------- */
19145+
4a4d8108
AM
19146+static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
19147+ int bufsiz)
1facf9fc 19148+{
19149+ int err;
4a4d8108
AM
19150+ struct super_block *sb;
19151+ struct dentry *h_dentry;
1facf9fc 19152+
4a4d8108
AM
19153+ err = -EINVAL;
19154+ h_dentry = au_h_dptr(dentry, bindex);
19155+ if (unlikely(!h_dentry->d_inode->i_op->readlink))
19156+ goto out;
1facf9fc 19157+
4a4d8108
AM
19158+ err = security_inode_readlink(h_dentry);
19159+ if (unlikely(err))
dece6358 19160+ goto out;
1facf9fc 19161+
4a4d8108
AM
19162+ sb = dentry->d_sb;
19163+ if (!au_test_ro(sb, bindex, dentry->d_inode)) {
19164+ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry);
19165+ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode);
1facf9fc 19166+ }
4a4d8108 19167+ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
1facf9fc 19168+
4f0767ce 19169+out:
4a4d8108
AM
19170+ return err;
19171+}
1facf9fc 19172+
4a4d8108
AM
19173+static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
19174+{
19175+ int err;
1facf9fc 19176+
027c5e7a
AM
19177+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
19178+ if (unlikely(err))
19179+ goto out;
19180+ err = au_d_hashed_positive(dentry);
19181+ if (!err)
19182+ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz);
4a4d8108 19183+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 19184+
027c5e7a 19185+out:
4a4d8108
AM
19186+ return err;
19187+}
1facf9fc 19188+
4a4d8108
AM
19189+static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd)
19190+{
19191+ int err;
4a4d8108 19192+ mm_segment_t old_fs;
b752ccd1
AM
19193+ union {
19194+ char *k;
19195+ char __user *u;
19196+ } buf;
1facf9fc 19197+
4a4d8108 19198+ err = -ENOMEM;
537831f9 19199+ buf.k = (void *)__get_free_page(GFP_NOFS);
b752ccd1 19200+ if (unlikely(!buf.k))
4a4d8108 19201+ goto out;
1facf9fc 19202+
027c5e7a
AM
19203+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN);
19204+ if (unlikely(err))
19205+ goto out_name;
19206+
19207+ err = au_d_hashed_positive(dentry);
19208+ if (!err) {
19209+ old_fs = get_fs();
19210+ set_fs(KERNEL_DS);
19211+ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX);
19212+ set_fs(old_fs);
19213+ }
4a4d8108 19214+ aufs_read_unlock(dentry, AuLock_IR);
1facf9fc 19215+
4a4d8108 19216+ if (err >= 0) {
b752ccd1 19217+ buf.k[err] = 0;
4a4d8108 19218+ /* will be freed by put_link */
b752ccd1 19219+ nd_set_link(nd, buf.k);
4a4d8108 19220+ return NULL; /* success */
1308ab2a 19221+ }
1facf9fc 19222+
027c5e7a 19223+out_name:
537831f9 19224+ free_page((unsigned long)buf.k);
4f0767ce 19225+out:
4a4d8108
AM
19226+ AuTraceErr(err);
19227+ return ERR_PTR(err);
19228+}
1facf9fc 19229+
4a4d8108
AM
19230+static void aufs_put_link(struct dentry *dentry __maybe_unused,
19231+ struct nameidata *nd, void *cookie __maybe_unused)
19232+{
537831f9
AM
19233+ char *p;
19234+
19235+ p = nd_get_link(nd);
19236+ if (!IS_ERR_OR_NULL(p))
19237+ free_page((unsigned long)p);
4a4d8108 19238+}
1facf9fc 19239+
4a4d8108 19240+/* ---------------------------------------------------------------------- */
1facf9fc 19241+
0c3ec466 19242+static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags)
4a4d8108 19243+{
0c3ec466
AM
19244+ int err;
19245+ struct super_block *sb;
19246+ struct inode *h_inode;
19247+
19248+ sb = inode->i_sb;
19249+ /* mmap_sem might be acquired already, cf. aufs_mmap() */
19250+ lockdep_off();
19251+ si_read_lock(sb, AuLock_FLUSH);
19252+ ii_write_lock_child(inode);
19253+ lockdep_on();
19254+ h_inode = au_h_iptr(inode, au_ibstart(inode));
19255+ err = vfsub_update_time(h_inode, ts, flags);
19256+ lockdep_off();
38d290e6
JR
19257+ if (!err)
19258+ au_cpup_attr_timesizes(inode);
0c3ec466
AM
19259+ ii_write_unlock(inode);
19260+ si_read_unlock(sb);
19261+ lockdep_on();
38d290e6
JR
19262+
19263+ if (!err && (flags & S_VERSION))
19264+ inode_inc_iversion(inode);
19265+
0c3ec466 19266+ return err;
4a4d8108 19267+}
1facf9fc 19268+
4a4d8108 19269+/* ---------------------------------------------------------------------- */
1308ab2a 19270+
4a4d8108
AM
19271+struct inode_operations aufs_symlink_iop = {
19272+ .permission = aufs_permission,
c1595e42
JR
19273+#ifdef CONFIG_FS_POSIX_ACL
19274+ .get_acl = aufs_get_acl,
19275+ .set_acl = aufs_set_acl, /* unsupport for symlink? */
19276+#endif
19277+
4a4d8108
AM
19278+ .setattr = aufs_setattr,
19279+ .getattr = aufs_getattr,
0c3ec466 19280+
c1595e42
JR
19281+#ifdef CONFIG_AUFS_XATTR
19282+ .setxattr = aufs_setxattr,
19283+ .getxattr = aufs_getxattr,
19284+ .listxattr = aufs_listxattr,
19285+ .removexattr = aufs_removexattr,
19286+#endif
19287+
4a4d8108
AM
19288+ .readlink = aufs_readlink,
19289+ .follow_link = aufs_follow_link,
0c3ec466
AM
19290+ .put_link = aufs_put_link,
19291+
19292+ /* .update_time = aufs_update_time */
4a4d8108
AM
19293+};
19294+
19295+struct inode_operations aufs_dir_iop = {
19296+ .create = aufs_create,
19297+ .lookup = aufs_lookup,
19298+ .link = aufs_link,
19299+ .unlink = aufs_unlink,
19300+ .symlink = aufs_symlink,
19301+ .mkdir = aufs_mkdir,
19302+ .rmdir = aufs_rmdir,
19303+ .mknod = aufs_mknod,
19304+ .rename = aufs_rename,
19305+
19306+ .permission = aufs_permission,
c1595e42
JR
19307+#ifdef CONFIG_FS_POSIX_ACL
19308+ .get_acl = aufs_get_acl,
19309+ .set_acl = aufs_set_acl,
19310+#endif
19311+
4a4d8108 19312+ .setattr = aufs_setattr,
0c3ec466
AM
19313+ .getattr = aufs_getattr,
19314+
c1595e42
JR
19315+#ifdef CONFIG_AUFS_XATTR
19316+ .setxattr = aufs_setxattr,
19317+ .getxattr = aufs_getxattr,
19318+ .listxattr = aufs_listxattr,
19319+ .removexattr = aufs_removexattr,
19320+#endif
19321+
38d290e6 19322+ .update_time = aufs_update_time,
b4510431 19323+ /* no support for atomic_open() */
38d290e6
JR
19324+
19325+ .tmpfile = aufs_tmpfile
4a4d8108
AM
19326+};
19327+
19328+struct inode_operations aufs_iop = {
19329+ .permission = aufs_permission,
c1595e42
JR
19330+#ifdef CONFIG_FS_POSIX_ACL
19331+ .get_acl = aufs_get_acl,
19332+ .set_acl = aufs_set_acl,
19333+#endif
19334+
4a4d8108
AM
19335+ .setattr = aufs_setattr,
19336+ .getattr = aufs_getattr,
0c3ec466 19337+
c1595e42
JR
19338+#ifdef CONFIG_AUFS_XATTR
19339+ .setxattr = aufs_setxattr,
19340+ .getxattr = aufs_getxattr,
19341+ .listxattr = aufs_listxattr,
19342+ .removexattr = aufs_removexattr,
19343+#endif
19344+
0c3ec466 19345+ .update_time = aufs_update_time
4a4d8108 19346+};
7f207e10
AM
19347diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c
19348--- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 19349+++ linux/fs/aufs/i_op_del.c 2015-01-25 13:00:38.631047076 +0100
076b876e 19350@@ -0,0 +1,507 @@
1facf9fc 19351+/*
523b37e3 19352+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19353+ *
19354+ * This program, aufs is free software; you can redistribute it and/or modify
19355+ * it under the terms of the GNU General Public License as published by
19356+ * the Free Software Foundation; either version 2 of the License, or
19357+ * (at your option) any later version.
dece6358
AM
19358+ *
19359+ * This program is distributed in the hope that it will be useful,
19360+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19361+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19362+ * GNU General Public License for more details.
19363+ *
19364+ * You should have received a copy of the GNU General Public License
523b37e3 19365+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19366+ */
19367+
19368+/*
4a4d8108 19369+ * inode operations (del entry)
1308ab2a 19370+ */
dece6358 19371+
1308ab2a 19372+#include "aufs.h"
dece6358 19373+
4a4d8108
AM
19374+/*
19375+ * decide if a new whiteout for @dentry is necessary or not.
19376+ * when it is necessary, prepare the parent dir for the upper branch whose
19377+ * branch index is @bcpup for creation. the actual creation of the whiteout will
19378+ * be done by caller.
19379+ * return value:
19380+ * 0: wh is unnecessary
19381+ * plus: wh is necessary
19382+ * minus: error
19383+ */
19384+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
1308ab2a 19385+{
4a4d8108
AM
19386+ int need_wh, err;
19387+ aufs_bindex_t bstart;
19388+ struct super_block *sb;
dece6358 19389+
4a4d8108
AM
19390+ sb = dentry->d_sb;
19391+ bstart = au_dbstart(dentry);
19392+ if (*bcpup < 0) {
19393+ *bcpup = bstart;
19394+ if (au_test_ro(sb, bstart, dentry->d_inode)) {
19395+ err = AuWbrCopyup(au_sbi(sb), dentry);
19396+ *bcpup = err;
19397+ if (unlikely(err < 0))
19398+ goto out;
19399+ }
19400+ } else
19401+ AuDebugOn(bstart < *bcpup
19402+ || au_test_ro(sb, *bcpup, dentry->d_inode));
19403+ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
1308ab2a 19404+
4a4d8108
AM
19405+ if (*bcpup != bstart) {
19406+ err = au_cpup_dirs(dentry, *bcpup);
19407+ if (unlikely(err))
19408+ goto out;
19409+ need_wh = 1;
19410+ } else {
027c5e7a 19411+ struct au_dinfo *dinfo, *tmp;
4a4d8108 19412+
027c5e7a
AM
19413+ need_wh = -ENOMEM;
19414+ dinfo = au_di(dentry);
19415+ tmp = au_di_alloc(sb, AuLsc_DI_TMP);
19416+ if (tmp) {
19417+ au_di_cp(tmp, dinfo);
19418+ au_di_swap(tmp, dinfo);
19419+ /* returns the number of positive dentries */
537831f9 19420+ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0);
027c5e7a
AM
19421+ au_di_swap(tmp, dinfo);
19422+ au_rw_write_unlock(&tmp->di_rwsem);
19423+ au_di_free(tmp);
4a4d8108
AM
19424+ }
19425+ }
19426+ AuDbg("need_wh %d\n", need_wh);
19427+ err = need_wh;
19428+
4f0767ce 19429+out:
4a4d8108 19430+ return err;
1facf9fc 19431+}
19432+
4a4d8108
AM
19433+/*
19434+ * simple tests for the del-entry operations.
19435+ * following the checks in vfs, plus the parent-child relationship.
19436+ */
19437+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
19438+ struct dentry *h_parent, int isdir)
1facf9fc 19439+{
4a4d8108
AM
19440+ int err;
19441+ umode_t h_mode;
19442+ struct dentry *h_dentry, *h_latest;
1308ab2a 19443+ struct inode *h_inode;
1facf9fc 19444+
4a4d8108
AM
19445+ h_dentry = au_h_dptr(dentry, bindex);
19446+ h_inode = h_dentry->d_inode;
19447+ if (dentry->d_inode) {
19448+ err = -ENOENT;
19449+ if (unlikely(!h_inode || !h_inode->i_nlink))
19450+ goto out;
1facf9fc 19451+
4a4d8108
AM
19452+ h_mode = h_inode->i_mode;
19453+ if (!isdir) {
19454+ err = -EISDIR;
19455+ if (unlikely(S_ISDIR(h_mode)))
19456+ goto out;
19457+ } else if (unlikely(!S_ISDIR(h_mode))) {
19458+ err = -ENOTDIR;
19459+ goto out;
19460+ }
19461+ } else {
19462+ /* rename(2) case */
19463+ err = -EIO;
19464+ if (unlikely(h_inode))
19465+ goto out;
19466+ }
1facf9fc 19467+
4a4d8108
AM
19468+ err = -ENOENT;
19469+ /* expected parent dir is locked */
19470+ if (unlikely(h_parent != h_dentry->d_parent))
19471+ goto out;
19472+ err = 0;
19473+
19474+ /*
19475+ * rmdir a dir may break the consistency on some filesystem.
19476+ * let's try heavy test.
19477+ */
19478+ err = -EACCES;
076b876e
AM
19479+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)
19480+ && au_test_h_perm(h_parent->d_inode,
19481+ MAY_EXEC | MAY_WRITE)))
4a4d8108
AM
19482+ goto out;
19483+
076b876e 19484+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent);
4a4d8108
AM
19485+ err = -EIO;
19486+ if (IS_ERR(h_latest))
19487+ goto out;
19488+ if (h_latest == h_dentry)
19489+ err = 0;
19490+ dput(h_latest);
19491+
4f0767ce 19492+out:
4a4d8108 19493+ return err;
1308ab2a 19494+}
1facf9fc 19495+
4a4d8108
AM
19496+/*
19497+ * decide the branch where we operate for @dentry. the branch index will be set
19498+ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
19499+ * dir for reverting.
19500+ * when a new whiteout is necessary, create it.
19501+ */
19502+static struct dentry*
19503+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
19504+ struct au_dtime *dt, struct au_pin *pin)
1308ab2a 19505+{
4a4d8108
AM
19506+ struct dentry *wh_dentry;
19507+ struct super_block *sb;
19508+ struct path h_path;
19509+ int err, need_wh;
19510+ unsigned int udba;
19511+ aufs_bindex_t bcpup;
dece6358 19512+
4a4d8108
AM
19513+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
19514+ wh_dentry = ERR_PTR(need_wh);
19515+ if (unlikely(need_wh < 0))
19516+ goto out;
19517+
19518+ sb = dentry->d_sb;
19519+ udba = au_opt_udba(sb);
19520+ bcpup = *rbcpup;
19521+ err = au_pin(pin, dentry, bcpup, udba,
19522+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
19523+ wh_dentry = ERR_PTR(err);
19524+ if (unlikely(err))
19525+ goto out;
19526+
19527+ h_path.dentry = au_pinned_h_parent(pin);
19528+ if (udba != AuOpt_UDBA_NONE
19529+ && au_dbstart(dentry) == bcpup) {
19530+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
19531+ wh_dentry = ERR_PTR(err);
19532+ if (unlikely(err))
19533+ goto out_unpin;
19534+ }
19535+
19536+ h_path.mnt = au_sbr_mnt(sb, bcpup);
19537+ au_dtime_store(dt, au_pinned_parent(pin), &h_path);
19538+ wh_dentry = NULL;
19539+ if (!need_wh)
19540+ goto out; /* success, no need to create whiteout */
19541+
19542+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
19543+ if (IS_ERR(wh_dentry))
19544+ goto out_unpin;
19545+
19546+ /* returns with the parent is locked and wh_dentry is dget-ed */
19547+ goto out; /* success */
19548+
4f0767ce 19549+out_unpin:
4a4d8108 19550+ au_unpin(pin);
4f0767ce 19551+out:
4a4d8108 19552+ return wh_dentry;
1facf9fc 19553+}
19554+
4a4d8108
AM
19555+/*
19556+ * when removing a dir, rename it to a unique temporary whiteout-ed name first
19557+ * in order to be revertible and save time for removing many child whiteouts
19558+ * under the dir.
19559+ * returns 1 when there are too many child whiteout and caller should remove
19560+ * them asynchronously. returns 0 when the number of children is enough small to
19561+ * remove now or the branch fs is a remote fs.
19562+ * otherwise return an error.
19563+ */
19564+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
19565+ struct au_nhash *whlist, struct inode *dir)
1facf9fc 19566+{
4a4d8108
AM
19567+ int rmdir_later, err, dirwh;
19568+ struct dentry *h_dentry;
19569+ struct super_block *sb;
19570+
19571+ sb = dentry->d_sb;
19572+ SiMustAnyLock(sb);
19573+ h_dentry = au_h_dptr(dentry, bindex);
19574+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
19575+ if (unlikely(err))
19576+ goto out;
19577+
19578+ /* stop monitoring */
19579+ au_hn_free(au_hi(dentry->d_inode, bindex));
19580+
19581+ if (!au_test_fs_remote(h_dentry->d_sb)) {
19582+ dirwh = au_sbi(sb)->si_dirwh;
19583+ rmdir_later = (dirwh <= 1);
19584+ if (!rmdir_later)
19585+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
19586+ dirwh);
19587+ if (rmdir_later)
19588+ return rmdir_later;
19589+ }
1facf9fc 19590+
4a4d8108
AM
19591+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
19592+ if (unlikely(err)) {
523b37e3
AM
19593+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
19594+ h_dentry, bindex, err);
4a4d8108
AM
19595+ err = 0;
19596+ }
dece6358 19597+
4f0767ce 19598+out:
4a4d8108
AM
19599+ AuTraceErr(err);
19600+ return err;
19601+}
1308ab2a 19602+
4a4d8108
AM
19603+/*
19604+ * final procedure for deleting a entry.
19605+ * maintain dentry and iattr.
19606+ */
19607+static void epilog(struct inode *dir, struct dentry *dentry,
19608+ aufs_bindex_t bindex)
19609+{
19610+ struct inode *inode;
1308ab2a 19611+
4a4d8108
AM
19612+ inode = dentry->d_inode;
19613+ d_drop(dentry);
19614+ inode->i_ctime = dir->i_ctime;
1308ab2a 19615+
4a4d8108
AM
19616+ if (au_ibstart(dir) == bindex)
19617+ au_cpup_attr_timesizes(dir);
19618+ dir->i_version++;
1facf9fc 19619+}
19620+
4a4d8108
AM
19621+/*
19622+ * when an error happened, remove the created whiteout and revert everything.
19623+ */
7f207e10
AM
19624+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
19625+ aufs_bindex_t bwh, struct dentry *wh_dentry,
19626+ struct dentry *dentry, struct au_dtime *dt)
1facf9fc 19627+{
4a4d8108
AM
19628+ int rerr;
19629+ struct path h_path = {
19630+ .dentry = wh_dentry,
7f207e10 19631+ .mnt = au_sbr_mnt(dir->i_sb, bindex)
4a4d8108 19632+ };
dece6358 19633+
7f207e10 19634+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
4a4d8108
AM
19635+ if (!rerr) {
19636+ au_set_dbwh(dentry, bwh);
19637+ au_dtime_revert(dt);
19638+ return 0;
19639+ }
dece6358 19640+
523b37e3 19641+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr);
4a4d8108 19642+ return -EIO;
1facf9fc 19643+}
19644+
4a4d8108 19645+/* ---------------------------------------------------------------------- */
1facf9fc 19646+
4a4d8108 19647+int aufs_unlink(struct inode *dir, struct dentry *dentry)
1308ab2a 19648+{
4a4d8108
AM
19649+ int err;
19650+ aufs_bindex_t bwh, bindex, bstart;
523b37e3 19651+ struct inode *inode, *h_dir, *delegated;
4a4d8108 19652+ struct dentry *parent, *wh_dentry;
c2b27bf2
AM
19653+ /* to reuduce stack size */
19654+ struct {
19655+ struct au_dtime dt;
19656+ struct au_pin pin;
19657+ struct path h_path;
19658+ } *a;
1facf9fc 19659+
4a4d8108 19660+ IMustLock(dir);
027c5e7a 19661+
c2b27bf2
AM
19662+ err = -ENOMEM;
19663+ a = kmalloc(sizeof(*a), GFP_NOFS);
19664+ if (unlikely(!a))
19665+ goto out;
19666+
027c5e7a
AM
19667+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
19668+ if (unlikely(err))
c2b27bf2 19669+ goto out_free;
027c5e7a
AM
19670+ err = au_d_hashed_positive(dentry);
19671+ if (unlikely(err))
19672+ goto out_unlock;
4a4d8108 19673+ inode = dentry->d_inode;
4a4d8108 19674+ IMustLock(inode);
027c5e7a
AM
19675+ err = -EISDIR;
19676+ if (unlikely(S_ISDIR(inode->i_mode)))
19677+ goto out_unlock; /* possible? */
1facf9fc 19678+
4a4d8108
AM
19679+ bstart = au_dbstart(dentry);
19680+ bwh = au_dbwh(dentry);
19681+ bindex = -1;
027c5e7a
AM
19682+ parent = dentry->d_parent; /* dir inode is locked */
19683+ di_write_lock_parent(parent);
c2b27bf2
AM
19684+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
19685+ &a->pin);
4a4d8108
AM
19686+ err = PTR_ERR(wh_dentry);
19687+ if (IS_ERR(wh_dentry))
027c5e7a 19688+ goto out_parent;
1facf9fc 19689+
c2b27bf2
AM
19690+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
19691+ a->h_path.dentry = au_h_dptr(dentry, bstart);
19692+ dget(a->h_path.dentry);
4a4d8108 19693+ if (bindex == bstart) {
c2b27bf2 19694+ h_dir = au_pinned_h_dir(&a->pin);
523b37e3
AM
19695+ delegated = NULL;
19696+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0);
19697+ if (unlikely(err == -EWOULDBLOCK)) {
19698+ pr_warn("cannot retry for NFSv4 delegation"
19699+ " for an internal unlink\n");
19700+ iput(delegated);
19701+ }
4a4d8108
AM
19702+ } else {
19703+ /* dir inode is locked */
19704+ h_dir = wh_dentry->d_parent->d_inode;
19705+ IMustLock(h_dir);
19706+ err = 0;
19707+ }
dece6358 19708+
4a4d8108 19709+ if (!err) {
7f207e10 19710+ vfsub_drop_nlink(inode);
4a4d8108
AM
19711+ epilog(dir, dentry, bindex);
19712+
19713+ /* update target timestamps */
19714+ if (bindex == bstart) {
c2b27bf2
AM
19715+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
19716+ /*ignore*/
19717+ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
4a4d8108
AM
19718+ } else
19719+ /* todo: this timestamp may be reverted later */
19720+ inode->i_ctime = h_dir->i_ctime;
027c5e7a 19721+ goto out_unpin; /* success */
1facf9fc 19722+ }
19723+
4a4d8108
AM
19724+ /* revert */
19725+ if (wh_dentry) {
19726+ int rerr;
19727+
c2b27bf2
AM
19728+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19729+ &a->dt);
4a4d8108
AM
19730+ if (rerr)
19731+ err = rerr;
dece6358 19732+ }
1facf9fc 19733+
027c5e7a 19734+out_unpin:
c2b27bf2 19735+ au_unpin(&a->pin);
4a4d8108 19736+ dput(wh_dentry);
c2b27bf2 19737+ dput(a->h_path.dentry);
027c5e7a 19738+out_parent:
4a4d8108 19739+ di_write_unlock(parent);
027c5e7a 19740+out_unlock:
4a4d8108 19741+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19742+out_free:
19743+ kfree(a);
027c5e7a 19744+out:
4a4d8108 19745+ return err;
dece6358
AM
19746+}
19747+
4a4d8108 19748+int aufs_rmdir(struct inode *dir, struct dentry *dentry)
1308ab2a 19749+{
4a4d8108
AM
19750+ int err, rmdir_later;
19751+ aufs_bindex_t bwh, bindex, bstart;
4a4d8108
AM
19752+ struct inode *inode;
19753+ struct dentry *parent, *wh_dentry, *h_dentry;
19754+ struct au_whtmp_rmdir *args;
c2b27bf2
AM
19755+ /* to reuduce stack size */
19756+ struct {
19757+ struct au_dtime dt;
19758+ struct au_pin pin;
19759+ } *a;
1facf9fc 19760+
4a4d8108 19761+ IMustLock(dir);
027c5e7a 19762+
c2b27bf2
AM
19763+ err = -ENOMEM;
19764+ a = kmalloc(sizeof(*a), GFP_NOFS);
19765+ if (unlikely(!a))
19766+ goto out;
19767+
027c5e7a
AM
19768+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
19769+ if (unlikely(err))
c2b27bf2 19770+ goto out_free;
53392da6
AM
19771+ err = au_alive_dir(dentry);
19772+ if (unlikely(err))
027c5e7a 19773+ goto out_unlock;
53392da6 19774+ inode = dentry->d_inode;
4a4d8108 19775+ IMustLock(inode);
027c5e7a
AM
19776+ err = -ENOTDIR;
19777+ if (unlikely(!S_ISDIR(inode->i_mode)))
19778+ goto out_unlock; /* possible? */
dece6358 19779+
4a4d8108
AM
19780+ err = -ENOMEM;
19781+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
19782+ if (unlikely(!args))
19783+ goto out_unlock;
dece6358 19784+
4a4d8108
AM
19785+ parent = dentry->d_parent; /* dir inode is locked */
19786+ di_write_lock_parent(parent);
19787+ err = au_test_empty(dentry, &args->whlist);
19788+ if (unlikely(err))
027c5e7a 19789+ goto out_parent;
1facf9fc 19790+
4a4d8108
AM
19791+ bstart = au_dbstart(dentry);
19792+ bwh = au_dbwh(dentry);
19793+ bindex = -1;
c2b27bf2
AM
19794+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
19795+ &a->pin);
4a4d8108
AM
19796+ err = PTR_ERR(wh_dentry);
19797+ if (IS_ERR(wh_dentry))
027c5e7a 19798+ goto out_parent;
1facf9fc 19799+
4a4d8108
AM
19800+ h_dentry = au_h_dptr(dentry, bstart);
19801+ dget(h_dentry);
19802+ rmdir_later = 0;
19803+ if (bindex == bstart) {
19804+ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
19805+ if (err > 0) {
19806+ rmdir_later = err;
19807+ err = 0;
19808+ }
19809+ } else {
19810+ /* stop monitoring */
19811+ au_hn_free(au_hi(inode, bstart));
19812+
19813+ /* dir inode is locked */
19814+ IMustLock(wh_dentry->d_parent->d_inode);
1facf9fc 19815+ err = 0;
19816+ }
19817+
4a4d8108 19818+ if (!err) {
027c5e7a 19819+ vfsub_dead_dir(inode);
4a4d8108
AM
19820+ au_set_dbdiropq(dentry, -1);
19821+ epilog(dir, dentry, bindex);
1308ab2a 19822+
4a4d8108
AM
19823+ if (rmdir_later) {
19824+ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
19825+ args = NULL;
19826+ }
1308ab2a 19827+
4a4d8108 19828+ goto out_unpin; /* success */
1facf9fc 19829+ }
19830+
4a4d8108
AM
19831+ /* revert */
19832+ AuLabel(revert);
19833+ if (wh_dentry) {
19834+ int rerr;
1308ab2a 19835+
c2b27bf2
AM
19836+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
19837+ &a->dt);
4a4d8108
AM
19838+ if (rerr)
19839+ err = rerr;
1facf9fc 19840+ }
19841+
4f0767ce 19842+out_unpin:
c2b27bf2 19843+ au_unpin(&a->pin);
4a4d8108
AM
19844+ dput(wh_dentry);
19845+ dput(h_dentry);
027c5e7a 19846+out_parent:
4a4d8108
AM
19847+ di_write_unlock(parent);
19848+ if (args)
19849+ au_whtmp_rmdir_free(args);
4f0767ce 19850+out_unlock:
4a4d8108 19851+ aufs_read_unlock(dentry, AuLock_DW);
c2b27bf2
AM
19852+out_free:
19853+ kfree(a);
4f0767ce 19854+out:
4a4d8108
AM
19855+ AuTraceErr(err);
19856+ return err;
dece6358 19857+}
7f207e10
AM
19858diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c
19859--- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 19860+++ linux/fs/aufs/i_op_ren.c 2015-01-25 13:00:38.631047076 +0100
076b876e 19861@@ -0,0 +1,1034 @@
1facf9fc 19862+/*
523b37e3 19863+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 19864+ *
19865+ * This program, aufs is free software; you can redistribute it and/or modify
19866+ * it under the terms of the GNU General Public License as published by
19867+ * the Free Software Foundation; either version 2 of the License, or
19868+ * (at your option) any later version.
dece6358
AM
19869+ *
19870+ * This program is distributed in the hope that it will be useful,
19871+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19872+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19873+ * GNU General Public License for more details.
19874+ *
19875+ * You should have received a copy of the GNU General Public License
523b37e3 19876+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 19877+ */
19878+
19879+/*
4a4d8108
AM
19880+ * inode operation (rename entry)
19881+ * todo: this is crazy monster
1facf9fc 19882+ */
19883+
19884+#include "aufs.h"
19885+
4a4d8108
AM
19886+enum { AuSRC, AuDST, AuSrcDst };
19887+enum { AuPARENT, AuCHILD, AuParentChild };
1facf9fc 19888+
4a4d8108
AM
19889+#define AuRen_ISDIR 1
19890+#define AuRen_ISSAMEDIR (1 << 1)
19891+#define AuRen_WHSRC (1 << 2)
19892+#define AuRen_WHDST (1 << 3)
19893+#define AuRen_MNT_WRITE (1 << 4)
19894+#define AuRen_DT_DSTDIR (1 << 5)
19895+#define AuRen_DIROPQ (1 << 6)
19896+#define AuRen_CPUP (1 << 7)
19897+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name)
7f207e10
AM
19898+#define au_fset_ren(flags, name) \
19899+ do { (flags) |= AuRen_##name; } while (0)
19900+#define au_fclr_ren(flags, name) \
19901+ do { (flags) &= ~AuRen_##name; } while (0)
1facf9fc 19902+
4a4d8108
AM
19903+struct au_ren_args {
19904+ struct {
19905+ struct dentry *dentry, *h_dentry, *parent, *h_parent,
19906+ *wh_dentry;
19907+ struct inode *dir, *inode;
19908+ struct au_hinode *hdir;
19909+ struct au_dtime dt[AuParentChild];
19910+ aufs_bindex_t bstart;
19911+ } sd[AuSrcDst];
1facf9fc 19912+
4a4d8108
AM
19913+#define src_dentry sd[AuSRC].dentry
19914+#define src_dir sd[AuSRC].dir
19915+#define src_inode sd[AuSRC].inode
19916+#define src_h_dentry sd[AuSRC].h_dentry
19917+#define src_parent sd[AuSRC].parent
19918+#define src_h_parent sd[AuSRC].h_parent
19919+#define src_wh_dentry sd[AuSRC].wh_dentry
19920+#define src_hdir sd[AuSRC].hdir
19921+#define src_h_dir sd[AuSRC].hdir->hi_inode
19922+#define src_dt sd[AuSRC].dt
19923+#define src_bstart sd[AuSRC].bstart
1facf9fc 19924+
4a4d8108
AM
19925+#define dst_dentry sd[AuDST].dentry
19926+#define dst_dir sd[AuDST].dir
19927+#define dst_inode sd[AuDST].inode
19928+#define dst_h_dentry sd[AuDST].h_dentry
19929+#define dst_parent sd[AuDST].parent
19930+#define dst_h_parent sd[AuDST].h_parent
19931+#define dst_wh_dentry sd[AuDST].wh_dentry
19932+#define dst_hdir sd[AuDST].hdir
19933+#define dst_h_dir sd[AuDST].hdir->hi_inode
19934+#define dst_dt sd[AuDST].dt
19935+#define dst_bstart sd[AuDST].bstart
19936+
19937+ struct dentry *h_trap;
19938+ struct au_branch *br;
19939+ struct au_hinode *src_hinode;
19940+ struct path h_path;
19941+ struct au_nhash whlist;
027c5e7a 19942+ aufs_bindex_t btgt, src_bwh, src_bdiropq;
1facf9fc 19943+
1308ab2a 19944+ unsigned int flags;
1facf9fc 19945+
4a4d8108
AM
19946+ struct au_whtmp_rmdir *thargs;
19947+ struct dentry *h_dst;
19948+};
1308ab2a 19949+
4a4d8108 19950+/* ---------------------------------------------------------------------- */
1308ab2a 19951+
4a4d8108
AM
19952+/*
19953+ * functions for reverting.
19954+ * when an error happened in a single rename systemcall, we should revert
19955+ * everything as if nothing happend.
19956+ * we don't need to revert the copied-up/down the parent dir since they are
19957+ * harmless.
19958+ */
1facf9fc 19959+
4a4d8108
AM
19960+#define RevertFailure(fmt, ...) do { \
19961+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \
19962+ ##__VA_ARGS__, err, rerr); \
19963+ err = -EIO; \
19964+} while (0)
1facf9fc 19965+
4a4d8108 19966+static void au_ren_rev_diropq(int err, struct au_ren_args *a)
1facf9fc 19967+{
4a4d8108 19968+ int rerr;
1facf9fc 19969+
4a4d8108
AM
19970+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
19971+ rerr = au_diropq_remove(a->src_dentry, a->btgt);
19972+ au_hn_imtx_unlock(a->src_hinode);
027c5e7a 19973+ au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
4a4d8108 19974+ if (rerr)
523b37e3 19975+ RevertFailure("remove diropq %pd", a->src_dentry);
4a4d8108 19976+}
1facf9fc 19977+
4a4d8108
AM
19978+static void au_ren_rev_rename(int err, struct au_ren_args *a)
19979+{
19980+ int rerr;
523b37e3 19981+ struct inode *delegated;
1facf9fc 19982+
b4510431
AM
19983+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name,
19984+ a->src_h_parent);
4a4d8108
AM
19985+ rerr = PTR_ERR(a->h_path.dentry);
19986+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 19987+ RevertFailure("lkup one %pd", a->src_dentry);
4a4d8108 19988+ return;
1facf9fc 19989+ }
19990+
523b37e3 19991+ delegated = NULL;
4a4d8108
AM
19992+ rerr = vfsub_rename(a->dst_h_dir,
19993+ au_h_dptr(a->src_dentry, a->btgt),
523b37e3
AM
19994+ a->src_h_dir, &a->h_path, &delegated);
19995+ if (unlikely(rerr == -EWOULDBLOCK)) {
19996+ pr_warn("cannot retry for NFSv4 delegation"
19997+ " for an internal rename\n");
19998+ iput(delegated);
19999+ }
4a4d8108
AM
20000+ d_drop(a->h_path.dentry);
20001+ dput(a->h_path.dentry);
20002+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
20003+ if (rerr)
523b37e3 20004+ RevertFailure("rename %pd", a->src_dentry);
1facf9fc 20005+}
20006+
4a4d8108 20007+static void au_ren_rev_cpup(int err, struct au_ren_args *a)
1facf9fc 20008+{
4a4d8108 20009+ int rerr;
1facf9fc 20010+
4a4d8108 20011+ a->h_path.dentry = a->dst_h_dentry;
523b37e3
AM
20012+ /* no delegation since it is just created */
20013+ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*delegated*/NULL,
20014+ /*force*/0);
4a4d8108
AM
20015+ au_set_h_dptr(a->src_dentry, a->btgt, NULL);
20016+ au_set_dbstart(a->src_dentry, a->src_bstart);
20017+ if (rerr)
523b37e3 20018+ RevertFailure("unlink %pd", a->dst_h_dentry);
1facf9fc 20019+}
20020+
4a4d8108 20021+static void au_ren_rev_whtmp(int err, struct au_ren_args *a)
1facf9fc 20022+{
4a4d8108 20023+ int rerr;
523b37e3 20024+ struct inode *delegated;
dece6358 20025+
b4510431
AM
20026+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name,
20027+ a->dst_h_parent);
4a4d8108
AM
20028+ rerr = PTR_ERR(a->h_path.dentry);
20029+ if (IS_ERR(a->h_path.dentry)) {
523b37e3 20030+ RevertFailure("lkup one %pd", a->dst_dentry);
4a4d8108
AM
20031+ return;
20032+ }
20033+ if (a->h_path.dentry->d_inode) {
20034+ d_drop(a->h_path.dentry);
20035+ dput(a->h_path.dentry);
20036+ return;
dece6358
AM
20037+ }
20038+
523b37e3
AM
20039+ delegated = NULL;
20040+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path,
20041+ &delegated);
20042+ if (unlikely(rerr == -EWOULDBLOCK)) {
20043+ pr_warn("cannot retry for NFSv4 delegation"
20044+ " for an internal rename\n");
20045+ iput(delegated);
20046+ }
4a4d8108
AM
20047+ d_drop(a->h_path.dentry);
20048+ dput(a->h_path.dentry);
20049+ if (!rerr)
20050+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst));
20051+ else
523b37e3 20052+ RevertFailure("rename %pd", a->h_dst);
4a4d8108 20053+}
1308ab2a 20054+
4a4d8108
AM
20055+static void au_ren_rev_whsrc(int err, struct au_ren_args *a)
20056+{
20057+ int rerr;
1308ab2a 20058+
4a4d8108
AM
20059+ a->h_path.dentry = a->src_wh_dentry;
20060+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry);
027c5e7a 20061+ au_set_dbwh(a->src_dentry, a->src_bwh);
4a4d8108 20062+ if (rerr)
523b37e3 20063+ RevertFailure("unlink %pd", a->src_wh_dentry);
4a4d8108 20064+}
4a4d8108 20065+#undef RevertFailure
1facf9fc 20066+
1308ab2a 20067+/* ---------------------------------------------------------------------- */
20068+
4a4d8108
AM
20069+/*
20070+ * when we have to copyup the renaming entry, do it with the rename-target name
20071+ * in order to minimize the cost (the later actual rename is unnecessary).
20072+ * otherwise rename it on the target branch.
20073+ */
20074+static int au_ren_or_cpup(struct au_ren_args *a)
1facf9fc 20075+{
dece6358 20076+ int err;
4a4d8108 20077+ struct dentry *d;
523b37e3 20078+ struct inode *delegated;
1facf9fc 20079+
4a4d8108
AM
20080+ d = a->src_dentry;
20081+ if (au_dbstart(d) == a->btgt) {
20082+ a->h_path.dentry = a->dst_h_dentry;
20083+ if (au_ftest_ren(a->flags, DIROPQ)
20084+ && au_dbdiropq(d) == a->btgt)
20085+ au_fclr_ren(a->flags, DIROPQ);
20086+ AuDebugOn(au_dbstart(d) != a->btgt);
523b37e3 20087+ delegated = NULL;
4a4d8108 20088+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt),
523b37e3
AM
20089+ a->dst_h_dir, &a->h_path, &delegated);
20090+ if (unlikely(err == -EWOULDBLOCK)) {
20091+ pr_warn("cannot retry for NFSv4 delegation"
20092+ " for an internal rename\n");
20093+ iput(delegated);
20094+ }
c2b27bf2 20095+ } else
86dc4139 20096+ BUG();
1308ab2a 20097+
027c5e7a
AM
20098+ if (!err && a->h_dst)
20099+ /* it will be set to dinfo later */
20100+ dget(a->h_dst);
1facf9fc 20101+
dece6358
AM
20102+ return err;
20103+}
1facf9fc 20104+
4a4d8108
AM
20105+/* cf. aufs_rmdir() */
20106+static int au_ren_del_whtmp(struct au_ren_args *a)
dece6358 20107+{
4a4d8108
AM
20108+ int err;
20109+ struct inode *dir;
1facf9fc 20110+
4a4d8108
AM
20111+ dir = a->dst_dir;
20112+ SiMustAnyLock(dir->i_sb);
20113+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt,
20114+ au_sbi(dir->i_sb)->si_dirwh)
20115+ || au_test_fs_remote(a->h_dst->d_sb)) {
20116+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist);
20117+ if (unlikely(err))
523b37e3
AM
20118+ pr_warn("failed removing whtmp dir %pd (%d), "
20119+ "ignored.\n", a->h_dst, err);
4a4d8108
AM
20120+ } else {
20121+ au_nhash_wh_free(&a->thargs->whlist);
20122+ a->thargs->whlist = a->whlist;
20123+ a->whlist.nh_num = 0;
20124+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs);
20125+ dput(a->h_dst);
20126+ a->thargs = NULL;
20127+ }
20128+
20129+ return 0;
1308ab2a 20130+}
1facf9fc 20131+
4a4d8108
AM
20132+/* make it 'opaque' dir. */
20133+static int au_ren_diropq(struct au_ren_args *a)
20134+{
20135+ int err;
20136+ struct dentry *diropq;
1facf9fc 20137+
4a4d8108 20138+ err = 0;
027c5e7a 20139+ a->src_bdiropq = au_dbdiropq(a->src_dentry);
4a4d8108
AM
20140+ a->src_hinode = au_hi(a->src_inode, a->btgt);
20141+ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
20142+ diropq = au_diropq_create(a->src_dentry, a->btgt);
20143+ au_hn_imtx_unlock(a->src_hinode);
20144+ if (IS_ERR(diropq))
20145+ err = PTR_ERR(diropq);
076b876e
AM
20146+ else
20147+ dput(diropq);
1facf9fc 20148+
4a4d8108
AM
20149+ return err;
20150+}
1facf9fc 20151+
4a4d8108
AM
20152+static int do_rename(struct au_ren_args *a)
20153+{
20154+ int err;
20155+ struct dentry *d, *h_d;
1facf9fc 20156+
4a4d8108
AM
20157+ /* prepare workqueue args for asynchronous rmdir */
20158+ h_d = a->dst_h_dentry;
20159+ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) {
20160+ err = -ENOMEM;
20161+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS);
20162+ if (unlikely(!a->thargs))
20163+ goto out;
20164+ a->h_dst = dget(h_d);
20165+ }
1facf9fc 20166+
4a4d8108
AM
20167+ /* create whiteout for src_dentry */
20168+ if (au_ftest_ren(a->flags, WHSRC)) {
027c5e7a
AM
20169+ a->src_bwh = au_dbwh(a->src_dentry);
20170+ AuDebugOn(a->src_bwh >= 0);
4a4d8108
AM
20171+ a->src_wh_dentry
20172+ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent);
20173+ err = PTR_ERR(a->src_wh_dentry);
20174+ if (IS_ERR(a->src_wh_dentry))
20175+ goto out_thargs;
20176+ }
1facf9fc 20177+
4a4d8108
AM
20178+ /* lookup whiteout for dentry */
20179+ if (au_ftest_ren(a->flags, WHDST)) {
20180+ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name,
20181+ a->br);
20182+ err = PTR_ERR(h_d);
20183+ if (IS_ERR(h_d))
20184+ goto out_whsrc;
20185+ if (!h_d->d_inode)
20186+ dput(h_d);
20187+ else
20188+ a->dst_wh_dentry = h_d;
20189+ }
1facf9fc 20190+
4a4d8108
AM
20191+ /* rename dentry to tmpwh */
20192+ if (a->thargs) {
20193+ err = au_whtmp_ren(a->dst_h_dentry, a->br);
20194+ if (unlikely(err))
20195+ goto out_whdst;
dece6358 20196+
4a4d8108
AM
20197+ d = a->dst_dentry;
20198+ au_set_h_dptr(d, a->btgt, NULL);
86dc4139 20199+ err = au_lkup_neg(d, a->btgt, /*wh*/0);
4a4d8108
AM
20200+ if (unlikely(err))
20201+ goto out_whtmp;
20202+ a->dst_h_dentry = au_h_dptr(d, a->btgt);
20203+ }
1facf9fc 20204+
c2b27bf2 20205+ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt);
1facf9fc 20206+
4a4d8108
AM
20207+ /* rename by vfs_rename or cpup */
20208+ d = a->dst_dentry;
20209+ if (au_ftest_ren(a->flags, ISDIR)
20210+ && (a->dst_wh_dentry
20211+ || au_dbdiropq(d) == a->btgt
20212+ /* hide the lower to keep xino */
20213+ || a->btgt < au_dbend(d)
20214+ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ)))
20215+ au_fset_ren(a->flags, DIROPQ);
20216+ err = au_ren_or_cpup(a);
20217+ if (unlikely(err))
20218+ /* leave the copied-up one */
20219+ goto out_whtmp;
1308ab2a 20220+
4a4d8108
AM
20221+ /* make dir opaque */
20222+ if (au_ftest_ren(a->flags, DIROPQ)) {
20223+ err = au_ren_diropq(a);
20224+ if (unlikely(err))
20225+ goto out_rename;
20226+ }
1308ab2a 20227+
4a4d8108
AM
20228+ /* update target timestamps */
20229+ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
20230+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt);
20231+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/
20232+ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
1facf9fc 20233+
4a4d8108
AM
20234+ /* remove whiteout for dentry */
20235+ if (a->dst_wh_dentry) {
20236+ a->h_path.dentry = a->dst_wh_dentry;
20237+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path,
20238+ a->dst_dentry);
20239+ if (unlikely(err))
20240+ goto out_diropq;
20241+ }
1facf9fc 20242+
4a4d8108
AM
20243+ /* remove whtmp */
20244+ if (a->thargs)
20245+ au_ren_del_whtmp(a); /* ignore this error */
1308ab2a 20246+
076b876e 20247+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0);
4a4d8108
AM
20248+ err = 0;
20249+ goto out_success;
20250+
4f0767ce 20251+out_diropq:
4a4d8108
AM
20252+ if (au_ftest_ren(a->flags, DIROPQ))
20253+ au_ren_rev_diropq(err, a);
4f0767ce 20254+out_rename:
4a4d8108
AM
20255+ if (!au_ftest_ren(a->flags, CPUP))
20256+ au_ren_rev_rename(err, a);
20257+ else
20258+ au_ren_rev_cpup(err, a);
027c5e7a 20259+ dput(a->h_dst);
4f0767ce 20260+out_whtmp:
4a4d8108
AM
20261+ if (a->thargs)
20262+ au_ren_rev_whtmp(err, a);
4f0767ce 20263+out_whdst:
4a4d8108
AM
20264+ dput(a->dst_wh_dentry);
20265+ a->dst_wh_dentry = NULL;
4f0767ce 20266+out_whsrc:
4a4d8108
AM
20267+ if (a->src_wh_dentry)
20268+ au_ren_rev_whsrc(err, a);
4f0767ce 20269+out_success:
4a4d8108
AM
20270+ dput(a->src_wh_dentry);
20271+ dput(a->dst_wh_dentry);
4f0767ce 20272+out_thargs:
4a4d8108
AM
20273+ if (a->thargs) {
20274+ dput(a->h_dst);
20275+ au_whtmp_rmdir_free(a->thargs);
20276+ a->thargs = NULL;
20277+ }
4f0767ce 20278+out:
4a4d8108 20279+ return err;
dece6358 20280+}
1facf9fc 20281+
1308ab2a 20282+/* ---------------------------------------------------------------------- */
1facf9fc 20283+
4a4d8108
AM
20284+/*
20285+ * test if @dentry dir can be rename destination or not.
20286+ * success means, it is a logically empty dir.
20287+ */
20288+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist)
1308ab2a 20289+{
4a4d8108 20290+ return au_test_empty(dentry, whlist);
1308ab2a 20291+}
1facf9fc 20292+
4a4d8108
AM
20293+/*
20294+ * test if @dentry dir can be rename source or not.
20295+ * if it can, return 0 and @children is filled.
20296+ * success means,
20297+ * - it is a logically empty dir.
20298+ * - or, it exists on writable branch and has no children including whiteouts
20299+ * on the lower branch.
20300+ */
20301+static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt)
20302+{
20303+ int err;
20304+ unsigned int rdhash;
20305+ aufs_bindex_t bstart;
1facf9fc 20306+
4a4d8108
AM
20307+ bstart = au_dbstart(dentry);
20308+ if (bstart != btgt) {
20309+ struct au_nhash whlist;
dece6358 20310+
4a4d8108
AM
20311+ SiMustAnyLock(dentry->d_sb);
20312+ rdhash = au_sbi(dentry->d_sb)->si_rdhash;
20313+ if (!rdhash)
20314+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL,
20315+ dentry));
20316+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS);
20317+ if (unlikely(err))
20318+ goto out;
20319+ err = au_test_empty(dentry, &whlist);
20320+ au_nhash_wh_free(&whlist);
20321+ goto out;
20322+ }
dece6358 20323+
4a4d8108
AM
20324+ if (bstart == au_dbtaildir(dentry))
20325+ return 0; /* success */
dece6358 20326+
4a4d8108 20327+ err = au_test_empty_lower(dentry);
1facf9fc 20328+
4f0767ce 20329+out:
4a4d8108
AM
20330+ if (err == -ENOTEMPTY) {
20331+ AuWarn1("renaming dir who has child(ren) on multiple branches,"
20332+ " is not supported\n");
20333+ err = -EXDEV;
20334+ }
20335+ return err;
20336+}
1308ab2a 20337+
4a4d8108
AM
20338+/* side effect: sets whlist and h_dentry */
20339+static int au_ren_may_dir(struct au_ren_args *a)
1308ab2a 20340+{
4a4d8108
AM
20341+ int err;
20342+ unsigned int rdhash;
20343+ struct dentry *d;
1facf9fc 20344+
4a4d8108
AM
20345+ d = a->dst_dentry;
20346+ SiMustAnyLock(d->d_sb);
1facf9fc 20347+
4a4d8108
AM
20348+ err = 0;
20349+ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) {
20350+ rdhash = au_sbi(d->d_sb)->si_rdhash;
20351+ if (!rdhash)
20352+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d));
20353+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS);
20354+ if (unlikely(err))
20355+ goto out;
1308ab2a 20356+
4a4d8108
AM
20357+ au_set_dbstart(d, a->dst_bstart);
20358+ err = may_rename_dstdir(d, &a->whlist);
20359+ au_set_dbstart(d, a->btgt);
20360+ }
20361+ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d));
20362+ if (unlikely(err))
20363+ goto out;
20364+
20365+ d = a->src_dentry;
20366+ a->src_h_dentry = au_h_dptr(d, au_dbstart(d));
20367+ if (au_ftest_ren(a->flags, ISDIR)) {
20368+ err = may_rename_srcdir(d, a->btgt);
20369+ if (unlikely(err)) {
20370+ au_nhash_wh_free(&a->whlist);
20371+ a->whlist.nh_num = 0;
20372+ }
20373+ }
4f0767ce 20374+out:
4a4d8108 20375+ return err;
1facf9fc 20376+}
20377+
4a4d8108 20378+/* ---------------------------------------------------------------------- */
1facf9fc 20379+
4a4d8108
AM
20380+/*
20381+ * simple tests for rename.
20382+ * following the checks in vfs, plus the parent-child relationship.
20383+ */
20384+static int au_may_ren(struct au_ren_args *a)
20385+{
20386+ int err, isdir;
20387+ struct inode *h_inode;
1facf9fc 20388+
4a4d8108
AM
20389+ if (a->src_bstart == a->btgt) {
20390+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent,
20391+ au_ftest_ren(a->flags, ISDIR));
20392+ if (unlikely(err))
20393+ goto out;
20394+ err = -EINVAL;
20395+ if (unlikely(a->src_h_dentry == a->h_trap))
20396+ goto out;
20397+ }
1facf9fc 20398+
4a4d8108
AM
20399+ err = 0;
20400+ if (a->dst_bstart != a->btgt)
20401+ goto out;
1facf9fc 20402+
027c5e7a
AM
20403+ err = -ENOTEMPTY;
20404+ if (unlikely(a->dst_h_dentry == a->h_trap))
20405+ goto out;
20406+
4a4d8108
AM
20407+ err = -EIO;
20408+ h_inode = a->dst_h_dentry->d_inode;
20409+ isdir = !!au_ftest_ren(a->flags, ISDIR);
20410+ if (!a->dst_dentry->d_inode) {
20411+ if (unlikely(h_inode))
20412+ goto out;
20413+ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent,
20414+ isdir);
20415+ } else {
20416+ if (unlikely(!h_inode || !h_inode->i_nlink))
20417+ goto out;
20418+ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent,
20419+ isdir);
20420+ if (unlikely(err))
20421+ goto out;
4a4d8108 20422+ }
1facf9fc 20423+
4f0767ce 20424+out:
4a4d8108
AM
20425+ if (unlikely(err == -ENOENT || err == -EEXIST))
20426+ err = -EIO;
20427+ AuTraceErr(err);
20428+ return err;
20429+}
1facf9fc 20430+
1308ab2a 20431+/* ---------------------------------------------------------------------- */
1facf9fc 20432+
4a4d8108
AM
20433+/*
20434+ * locking order
20435+ * (VFS)
20436+ * - src_dir and dir by lock_rename()
20437+ * - inode if exitsts
20438+ * (aufs)
20439+ * - lock all
20440+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls,
20441+ * + si_read_lock
20442+ * + di_write_lock2_child()
20443+ * + di_write_lock_child()
20444+ * + ii_write_lock_child()
20445+ * + di_write_lock_child2()
20446+ * + ii_write_lock_child2()
20447+ * + src_parent and parent
20448+ * + di_write_lock_parent()
20449+ * + ii_write_lock_parent()
20450+ * + di_write_lock_parent2()
20451+ * + ii_write_lock_parent2()
20452+ * + lower src_dir and dir by vfsub_lock_rename()
20453+ * + verify the every relationships between child and parent. if any
20454+ * of them failed, unlock all and return -EBUSY.
20455+ */
20456+static void au_ren_unlock(struct au_ren_args *a)
1308ab2a 20457+{
4a4d8108
AM
20458+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir,
20459+ a->dst_h_parent, a->dst_hdir);
86dc4139
AM
20460+ if (au_ftest_ren(a->flags, MNT_WRITE))
20461+ vfsub_mnt_drop_write(au_br_mnt(a->br));
1308ab2a 20462+}
20463+
4a4d8108 20464+static int au_ren_lock(struct au_ren_args *a)
1308ab2a 20465+{
4a4d8108
AM
20466+ int err;
20467+ unsigned int udba;
1308ab2a 20468+
4a4d8108
AM
20469+ err = 0;
20470+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt);
20471+ a->src_hdir = au_hi(a->src_dir, a->btgt);
20472+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt);
20473+ a->dst_hdir = au_hi(a->dst_dir, a->btgt);
86dc4139
AM
20474+
20475+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
20476+ if (unlikely(err))
20477+ goto out;
20478+ au_fset_ren(a->flags, MNT_WRITE);
4a4d8108
AM
20479+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir,
20480+ a->dst_h_parent, a->dst_hdir);
20481+ udba = au_opt_udba(a->src_dentry->d_sb);
20482+ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode
20483+ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode))
20484+ err = au_busy_or_stale();
20485+ if (!err && au_dbstart(a->src_dentry) == a->btgt)
20486+ err = au_h_verify(a->src_h_dentry, udba,
20487+ a->src_h_parent->d_inode, a->src_h_parent,
20488+ a->br);
20489+ if (!err && au_dbstart(a->dst_dentry) == a->btgt)
20490+ err = au_h_verify(a->dst_h_dentry, udba,
20491+ a->dst_h_parent->d_inode, a->dst_h_parent,
20492+ a->br);
86dc4139 20493+ if (!err)
4a4d8108 20494+ goto out; /* success */
4a4d8108
AM
20495+
20496+ err = au_busy_or_stale();
4a4d8108 20497+ au_ren_unlock(a);
86dc4139 20498+
4f0767ce 20499+out:
4a4d8108 20500+ return err;
1facf9fc 20501+}
20502+
20503+/* ---------------------------------------------------------------------- */
20504+
4a4d8108 20505+static void au_ren_refresh_dir(struct au_ren_args *a)
1facf9fc 20506+{
4a4d8108 20507+ struct inode *dir;
dece6358 20508+
4a4d8108
AM
20509+ dir = a->dst_dir;
20510+ dir->i_version++;
20511+ if (au_ftest_ren(a->flags, ISDIR)) {
20512+ /* is this updating defined in POSIX? */
20513+ au_cpup_attr_timesizes(a->src_inode);
20514+ au_cpup_attr_nlink(dir, /*force*/1);
4a4d8108 20515+ }
027c5e7a 20516+
4a4d8108
AM
20517+ if (au_ibstart(dir) == a->btgt)
20518+ au_cpup_attr_timesizes(dir);
dece6358 20519+
4a4d8108
AM
20520+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20521+ return;
dece6358 20522+
4a4d8108
AM
20523+ dir = a->src_dir;
20524+ dir->i_version++;
20525+ if (au_ftest_ren(a->flags, ISDIR))
20526+ au_cpup_attr_nlink(dir, /*force*/1);
20527+ if (au_ibstart(dir) == a->btgt)
20528+ au_cpup_attr_timesizes(dir);
1facf9fc 20529+}
20530+
4a4d8108 20531+static void au_ren_refresh(struct au_ren_args *a)
1facf9fc 20532+{
4a4d8108
AM
20533+ aufs_bindex_t bend, bindex;
20534+ struct dentry *d, *h_d;
20535+ struct inode *i, *h_i;
20536+ struct super_block *sb;
dece6358 20537+
027c5e7a
AM
20538+ d = a->dst_dentry;
20539+ d_drop(d);
20540+ if (a->h_dst)
20541+ /* already dget-ed by au_ren_or_cpup() */
20542+ au_set_h_dptr(d, a->btgt, a->h_dst);
20543+
20544+ i = a->dst_inode;
20545+ if (i) {
20546+ if (!au_ftest_ren(a->flags, ISDIR))
20547+ vfsub_drop_nlink(i);
20548+ else {
20549+ vfsub_dead_dir(i);
20550+ au_cpup_attr_timesizes(i);
20551+ }
20552+ au_update_dbrange(d, /*do_put_zero*/1);
20553+ } else {
20554+ bend = a->btgt;
20555+ for (bindex = au_dbstart(d); bindex < bend; bindex++)
20556+ au_set_h_dptr(d, bindex, NULL);
20557+ bend = au_dbend(d);
20558+ for (bindex = a->btgt + 1; bindex <= bend; bindex++)
20559+ au_set_h_dptr(d, bindex, NULL);
20560+ au_update_dbrange(d, /*do_put_zero*/0);
20561+ }
20562+
4a4d8108
AM
20563+ d = a->src_dentry;
20564+ au_set_dbwh(d, -1);
20565+ bend = au_dbend(d);
20566+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20567+ h_d = au_h_dptr(d, bindex);
20568+ if (h_d)
20569+ au_set_h_dptr(d, bindex, NULL);
20570+ }
20571+ au_set_dbend(d, a->btgt);
20572+
20573+ sb = d->d_sb;
20574+ i = a->src_inode;
20575+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i))
20576+ return; /* success */
20577+
20578+ bend = au_ibend(i);
20579+ for (bindex = a->btgt + 1; bindex <= bend; bindex++) {
20580+ h_i = au_h_iptr(i, bindex);
20581+ if (h_i) {
20582+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0);
20583+ /* ignore this error */
20584+ au_set_h_iptr(i, bindex, NULL, 0);
20585+ }
20586+ }
20587+ au_set_ibend(i, a->btgt);
1308ab2a 20588+}
dece6358 20589+
4a4d8108
AM
20590+/* ---------------------------------------------------------------------- */
20591+
20592+/* mainly for link(2) and rename(2) */
20593+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt)
1308ab2a 20594+{
4a4d8108
AM
20595+ aufs_bindex_t bdiropq, bwh;
20596+ struct dentry *parent;
20597+ struct au_branch *br;
20598+
20599+ parent = dentry->d_parent;
20600+ IMustLock(parent->d_inode); /* dir is locked */
20601+
20602+ bdiropq = au_dbdiropq(parent);
20603+ bwh = au_dbwh(dentry);
20604+ br = au_sbr(dentry->d_sb, btgt);
20605+ if (au_br_rdonly(br)
20606+ || (0 <= bdiropq && bdiropq < btgt)
20607+ || (0 <= bwh && bwh < btgt))
20608+ btgt = -1;
20609+
20610+ AuDbg("btgt %d\n", btgt);
20611+ return btgt;
1facf9fc 20612+}
20613+
4a4d8108
AM
20614+/* sets src_bstart, dst_bstart and btgt */
20615+static int au_ren_wbr(struct au_ren_args *a)
1facf9fc 20616+{
4a4d8108
AM
20617+ int err;
20618+ struct au_wr_dir_args wr_dir_args = {
20619+ /* .force_btgt = -1, */
20620+ .flags = AuWrDir_ADD_ENTRY
20621+ };
dece6358 20622+
4a4d8108
AM
20623+ a->src_bstart = au_dbstart(a->src_dentry);
20624+ a->dst_bstart = au_dbstart(a->dst_dentry);
20625+ if (au_ftest_ren(a->flags, ISDIR))
20626+ au_fset_wrdir(wr_dir_args.flags, ISDIR);
20627+ wr_dir_args.force_btgt = a->src_bstart;
20628+ if (a->dst_inode && a->dst_bstart < a->src_bstart)
20629+ wr_dir_args.force_btgt = a->dst_bstart;
20630+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt);
20631+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args);
20632+ a->btgt = err;
dece6358 20633+
4a4d8108 20634+ return err;
1facf9fc 20635+}
20636+
4a4d8108 20637+static void au_ren_dt(struct au_ren_args *a)
1facf9fc 20638+{
4a4d8108
AM
20639+ a->h_path.dentry = a->src_h_parent;
20640+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path);
20641+ if (!au_ftest_ren(a->flags, ISSAMEDIR)) {
20642+ a->h_path.dentry = a->dst_h_parent;
20643+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path);
20644+ }
1facf9fc 20645+
4a4d8108
AM
20646+ au_fclr_ren(a->flags, DT_DSTDIR);
20647+ if (!au_ftest_ren(a->flags, ISDIR))
20648+ return;
dece6358 20649+
4a4d8108
AM
20650+ a->h_path.dentry = a->src_h_dentry;
20651+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path);
20652+ if (a->dst_h_dentry->d_inode) {
20653+ au_fset_ren(a->flags, DT_DSTDIR);
20654+ a->h_path.dentry = a->dst_h_dentry;
20655+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path);
20656+ }
1308ab2a 20657+}
dece6358 20658+
4a4d8108 20659+static void au_ren_rev_dt(int err, struct au_ren_args *a)
1308ab2a 20660+{
4a4d8108
AM
20661+ struct dentry *h_d;
20662+ struct mutex *h_mtx;
20663+
20664+ au_dtime_revert(a->src_dt + AuPARENT);
20665+ if (!au_ftest_ren(a->flags, ISSAMEDIR))
20666+ au_dtime_revert(a->dst_dt + AuPARENT);
20667+
20668+ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) {
20669+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry;
20670+ h_mtx = &h_d->d_inode->i_mutex;
20671+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20672+ au_dtime_revert(a->src_dt + AuCHILD);
20673+ mutex_unlock(h_mtx);
20674+
20675+ if (au_ftest_ren(a->flags, DT_DSTDIR)) {
20676+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry;
20677+ h_mtx = &h_d->d_inode->i_mutex;
20678+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD);
20679+ au_dtime_revert(a->dst_dt + AuCHILD);
20680+ mutex_unlock(h_mtx);
1facf9fc 20681+ }
20682+ }
20683+}
20684+
4a4d8108
AM
20685+/* ---------------------------------------------------------------------- */
20686+
20687+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
20688+ struct inode *_dst_dir, struct dentry *_dst_dentry)
1facf9fc 20689+{
e49829fe 20690+ int err, flags;
4a4d8108
AM
20691+ /* reduce stack space */
20692+ struct au_ren_args *a;
20693+
523b37e3 20694+ AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry);
4a4d8108
AM
20695+ IMustLock(_src_dir);
20696+ IMustLock(_dst_dir);
20697+
20698+ err = -ENOMEM;
20699+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
20700+ a = kzalloc(sizeof(*a), GFP_NOFS);
20701+ if (unlikely(!a))
20702+ goto out;
20703+
20704+ a->src_dir = _src_dir;
20705+ a->src_dentry = _src_dentry;
20706+ a->src_inode = a->src_dentry->d_inode;
20707+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
20708+ a->dst_dir = _dst_dir;
20709+ a->dst_dentry = _dst_dentry;
20710+ a->dst_inode = a->dst_dentry->d_inode;
20711+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
20712+ if (a->dst_inode) {
20713+ IMustLock(a->dst_inode);
20714+ au_igrab(a->dst_inode);
1facf9fc 20715+ }
1facf9fc 20716+
4a4d8108 20717+ err = -ENOTDIR;
027c5e7a 20718+ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
4a4d8108
AM
20719+ if (S_ISDIR(a->src_inode->i_mode)) {
20720+ au_fset_ren(a->flags, ISDIR);
20721+ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
20722+ goto out_free;
e49829fe
JR
20723+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20724+ AuLock_DIR | flags);
4a4d8108 20725+ } else
e49829fe
JR
20726+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
20727+ flags);
20728+ if (unlikely(err))
20729+ goto out_free;
1facf9fc 20730+
027c5e7a
AM
20731+ err = au_d_hashed_positive(a->src_dentry);
20732+ if (unlikely(err))
20733+ goto out_unlock;
20734+ err = -ENOENT;
20735+ if (a->dst_inode) {
20736+ /*
20737+ * If it is a dir, VFS unhash dst_dentry before this
20738+ * function. It means we cannot rely upon d_unhashed().
20739+ */
20740+ if (unlikely(!a->dst_inode->i_nlink))
20741+ goto out_unlock;
20742+ if (!S_ISDIR(a->dst_inode->i_mode)) {
20743+ err = au_d_hashed_positive(a->dst_dentry);
20744+ if (unlikely(err))
20745+ goto out_unlock;
20746+ } else if (unlikely(IS_DEADDIR(a->dst_inode)))
20747+ goto out_unlock;
20748+ } else if (unlikely(d_unhashed(a->dst_dentry)))
20749+ goto out_unlock;
20750+
7eafdf33
AM
20751+ /*
20752+ * is it possible?
20753+ * yes, it happend (in linux-3.3-rcN) but I don't know why.
20754+ * there may exist a problem somewhere else.
20755+ */
20756+ err = -EINVAL;
20757+ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode))
20758+ goto out_unlock;
20759+
4a4d8108
AM
20760+ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
20761+ di_write_lock_parent(a->dst_parent);
1facf9fc 20762+
4a4d8108
AM
20763+ /* which branch we process */
20764+ err = au_ren_wbr(a);
20765+ if (unlikely(err < 0))
027c5e7a 20766+ goto out_parent;
4a4d8108 20767+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
86dc4139 20768+ a->h_path.mnt = au_br_mnt(a->br);
1facf9fc 20769+
4a4d8108
AM
20770+ /* are they available to be renamed */
20771+ err = au_ren_may_dir(a);
20772+ if (unlikely(err))
20773+ goto out_children;
1facf9fc 20774+
4a4d8108
AM
20775+ /* prepare the writable parent dir on the same branch */
20776+ if (a->dst_bstart == a->btgt) {
20777+ au_fset_ren(a->flags, WHDST);
20778+ } else {
20779+ err = au_cpup_dirs(a->dst_dentry, a->btgt);
20780+ if (unlikely(err))
20781+ goto out_children;
20782+ }
1facf9fc 20783+
4a4d8108
AM
20784+ if (a->src_dir != a->dst_dir) {
20785+ /*
20786+ * this temporary unlock is safe,
20787+ * because both dir->i_mutex are locked.
20788+ */
20789+ di_write_unlock(a->dst_parent);
20790+ di_write_lock_parent(a->src_parent);
20791+ err = au_wr_dir_need_wh(a->src_dentry,
20792+ au_ftest_ren(a->flags, ISDIR),
20793+ &a->btgt);
20794+ di_write_unlock(a->src_parent);
20795+ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
20796+ au_fclr_ren(a->flags, ISSAMEDIR);
20797+ } else
20798+ err = au_wr_dir_need_wh(a->src_dentry,
20799+ au_ftest_ren(a->flags, ISDIR),
20800+ &a->btgt);
20801+ if (unlikely(err < 0))
20802+ goto out_children;
20803+ if (err)
20804+ au_fset_ren(a->flags, WHSRC);
1facf9fc 20805+
86dc4139
AM
20806+ /* cpup src */
20807+ if (a->src_bstart != a->btgt) {
86dc4139
AM
20808+ struct au_pin pin;
20809+
20810+ err = au_pin(&pin, a->src_dentry, a->btgt,
20811+ au_opt_udba(a->src_dentry->d_sb),
20812+ AuPin_DI_LOCKED | AuPin_MNT_WRITE);
367653fa 20813+ if (!err) {
c2b27bf2
AM
20814+ struct au_cp_generic cpg = {
20815+ .dentry = a->src_dentry,
20816+ .bdst = a->btgt,
20817+ .bsrc = a->src_bstart,
20818+ .len = -1,
20819+ .pin = &pin,
20820+ .flags = AuCpup_DTIME | AuCpup_HOPEN
20821+ };
367653fa 20822+ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart);
c2b27bf2 20823+ err = au_sio_cpup_simple(&cpg);
367653fa 20824+ au_unpin(&pin);
86dc4139 20825+ }
86dc4139
AM
20826+ if (unlikely(err))
20827+ goto out_children;
20828+ a->src_bstart = a->btgt;
20829+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt);
20830+ au_fset_ren(a->flags, WHSRC);
20831+ }
20832+
4a4d8108
AM
20833+ /* lock them all */
20834+ err = au_ren_lock(a);
20835+ if (unlikely(err))
86dc4139 20836+ /* leave the copied-up one */
4a4d8108 20837+ goto out_children;
1facf9fc 20838+
4a4d8108
AM
20839+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
20840+ err = au_may_ren(a);
20841+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
20842+ err = -ENAMETOOLONG;
20843+ if (unlikely(err))
20844+ goto out_hdir;
1facf9fc 20845+
4a4d8108
AM
20846+ /* store timestamps to be revertible */
20847+ au_ren_dt(a);
1facf9fc 20848+
4a4d8108
AM
20849+ /* here we go */
20850+ err = do_rename(a);
20851+ if (unlikely(err))
20852+ goto out_dt;
20853+
20854+ /* update dir attributes */
20855+ au_ren_refresh_dir(a);
20856+
20857+ /* dput/iput all lower dentries */
20858+ au_ren_refresh(a);
20859+
20860+ goto out_hdir; /* success */
20861+
4f0767ce 20862+out_dt:
4a4d8108 20863+ au_ren_rev_dt(err, a);
4f0767ce 20864+out_hdir:
4a4d8108 20865+ au_ren_unlock(a);
4f0767ce 20866+out_children:
4a4d8108 20867+ au_nhash_wh_free(&a->whlist);
027c5e7a
AM
20868+ if (err && a->dst_inode && a->dst_bstart != a->btgt) {
20869+ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
20870+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
20871+ au_set_dbstart(a->dst_dentry, a->dst_bstart);
4a4d8108 20872+ }
027c5e7a 20873+out_parent:
4a4d8108
AM
20874+ if (!err)
20875+ d_move(a->src_dentry, a->dst_dentry);
027c5e7a
AM
20876+ else {
20877+ au_update_dbstart(a->dst_dentry);
20878+ if (!a->dst_inode)
20879+ d_drop(a->dst_dentry);
20880+ }
4a4d8108
AM
20881+ if (au_ftest_ren(a->flags, ISSAMEDIR))
20882+ di_write_unlock(a->dst_parent);
20883+ else
20884+ di_write_unlock2(a->src_parent, a->dst_parent);
027c5e7a 20885+out_unlock:
4a4d8108 20886+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
4f0767ce 20887+out_free:
4a4d8108
AM
20888+ iput(a->dst_inode);
20889+ if (a->thargs)
20890+ au_whtmp_rmdir_free(a->thargs);
20891+ kfree(a);
4f0767ce 20892+out:
4a4d8108
AM
20893+ AuTraceErr(err);
20894+ return err;
1308ab2a 20895+}
7f207e10
AM
20896diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig
20897--- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
20898+++ linux/fs/aufs/Kconfig 2015-01-25 13:00:38.627713742 +0100
20899@@ -0,0 +1,185 @@
4a4d8108
AM
20900+config AUFS_FS
20901+ tristate "Aufs (Advanced multi layered unification filesystem) support"
4a4d8108
AM
20902+ help
20903+ Aufs is a stackable unification filesystem such as Unionfs,
20904+ which unifies several directories and provides a merged single
20905+ directory.
20906+ In the early days, aufs was entirely re-designed and
20907+ re-implemented Unionfs Version 1.x series. Introducing many
20908+ original ideas, approaches and improvements, it becomes totally
20909+ different from Unionfs while keeping the basic features.
1facf9fc 20910+
4a4d8108
AM
20911+if AUFS_FS
20912+choice
20913+ prompt "Maximum number of branches"
20914+ default AUFS_BRANCH_MAX_127
20915+ help
20916+ Specifies the maximum number of branches (or member directories)
20917+ in a single aufs. The larger value consumes more system
20918+ resources and has a minor impact to performance.
20919+config AUFS_BRANCH_MAX_127
20920+ bool "127"
20921+ help
20922+ Specifies the maximum number of branches (or member directories)
20923+ in a single aufs. The larger value consumes more system
20924+ resources and has a minor impact to performance.
20925+config AUFS_BRANCH_MAX_511
20926+ bool "511"
20927+ help
20928+ Specifies the maximum number of branches (or member directories)
20929+ in a single aufs. The larger value consumes more system
20930+ resources and has a minor impact to performance.
20931+config AUFS_BRANCH_MAX_1023
20932+ bool "1023"
20933+ help
20934+ Specifies the maximum number of branches (or member directories)
20935+ in a single aufs. The larger value consumes more system
20936+ resources and has a minor impact to performance.
20937+config AUFS_BRANCH_MAX_32767
20938+ bool "32767"
20939+ help
20940+ Specifies the maximum number of branches (or member directories)
20941+ in a single aufs. The larger value consumes more system
20942+ resources and has a minor impact to performance.
20943+endchoice
1facf9fc 20944+
e49829fe
JR
20945+config AUFS_SBILIST
20946+ bool
20947+ depends on AUFS_MAGIC_SYSRQ || PROC_FS
20948+ default y
20949+ help
20950+ Automatic configuration for internal use.
20951+ When aufs supports Magic SysRq or /proc, enabled automatically.
20952+
4a4d8108
AM
20953+config AUFS_HNOTIFY
20954+ bool "Detect direct branch access (bypassing aufs)"
20955+ help
20956+ If you want to modify files on branches directly, eg. bypassing aufs,
20957+ and want aufs to detect the changes of them fully, then enable this
20958+ option and use 'udba=notify' mount option.
7f207e10 20959+ Currently there is only one available configuration, "fsnotify".
4a4d8108
AM
20960+ It will have a negative impact to the performance.
20961+ See detail in aufs.5.
dece6358 20962+
4a4d8108
AM
20963+choice
20964+ prompt "method" if AUFS_HNOTIFY
20965+ default AUFS_HFSNOTIFY
20966+config AUFS_HFSNOTIFY
20967+ bool "fsnotify"
20968+ select FSNOTIFY
4a4d8108 20969+endchoice
1facf9fc 20970+
4a4d8108
AM
20971+config AUFS_EXPORT
20972+ bool "NFS-exportable aufs"
2cbb1c4b 20973+ depends on EXPORTFS
4a4d8108
AM
20974+ help
20975+ If you want to export your mounted aufs via NFS, then enable this
20976+ option. There are several requirements for this configuration.
20977+ See detail in aufs.5.
1facf9fc 20978+
4a4d8108
AM
20979+config AUFS_INO_T_64
20980+ bool
20981+ depends on AUFS_EXPORT
20982+ depends on 64BIT && !(ALPHA || S390)
20983+ default y
20984+ help
20985+ Automatic configuration for internal use.
20986+ /* typedef unsigned long/int __kernel_ino_t */
20987+ /* alpha and s390x are int */
1facf9fc 20988+
c1595e42
JR
20989+config AUFS_XATTR
20990+ bool "support for XATTR/EA (including Security Labels)"
20991+ help
20992+ If your branch fs supports XATTR/EA and you want to make them
20993+ available in aufs too, then enable this opsion and specify the
20994+ branch attributes for EA.
20995+ See detail in aufs.5.
20996+
076b876e
AM
20997+config AUFS_FHSM
20998+ bool "File-based Hierarchical Storage Management"
20999+ help
21000+ Hierarchical Storage Management (or HSM) is a well-known feature
21001+ in the storage world. Aufs provides this feature as file-based.
21002+ with multiple branches.
21003+ These multiple branches are prioritized, ie. the topmost one
21004+ should be the fastest drive and be used heavily.
21005+
4a4d8108
AM
21006+config AUFS_RDU
21007+ bool "Readdir in userspace"
21008+ help
21009+ Aufs has two methods to provide a merged view for a directory,
21010+ by a user-space library and by kernel-space natively. The latter
21011+ is always enabled but sometimes large and slow.
21012+ If you enable this option, install the library in aufs2-util
21013+ package, and set some environment variables for your readdir(3),
21014+ then the work will be handled in user-space which generally
21015+ shows better performance in most cases.
21016+ See detail in aufs.5.
1facf9fc 21017+
4a4d8108
AM
21018+config AUFS_SHWH
21019+ bool "Show whiteouts"
21020+ help
21021+ If you want to make the whiteouts in aufs visible, then enable
21022+ this option and specify 'shwh' mount option. Although it may
21023+ sounds like philosophy or something, but in technically it
21024+ simply shows the name of whiteout with keeping its behaviour.
1facf9fc 21025+
4a4d8108
AM
21026+config AUFS_BR_RAMFS
21027+ bool "Ramfs (initramfs/rootfs) as an aufs branch"
21028+ help
21029+ If you want to use ramfs as an aufs branch fs, then enable this
21030+ option. Generally tmpfs is recommended.
21031+ Aufs prohibited them to be a branch fs by default, because
21032+ initramfs becomes unusable after switch_root or something
21033+ generally. If you sets initramfs as an aufs branch and boot your
21034+ system by switch_root, you will meet a problem easily since the
21035+ files in initramfs may be inaccessible.
21036+ Unless you are going to use ramfs as an aufs branch fs without
21037+ switch_root or something, leave it N.
1facf9fc 21038+
4a4d8108
AM
21039+config AUFS_BR_FUSE
21040+ bool "Fuse fs as an aufs branch"
21041+ depends on FUSE_FS
21042+ select AUFS_POLL
21043+ help
21044+ If you want to use fuse-based userspace filesystem as an aufs
21045+ branch fs, then enable this option.
21046+ It implements the internal poll(2) operation which is
21047+ implemented by fuse only (curretnly).
1facf9fc 21048+
4a4d8108
AM
21049+config AUFS_POLL
21050+ bool
21051+ help
21052+ Automatic configuration for internal use.
1facf9fc 21053+
4a4d8108
AM
21054+config AUFS_BR_HFSPLUS
21055+ bool "Hfsplus as an aufs branch"
21056+ depends on HFSPLUS_FS
21057+ default y
21058+ help
21059+ If you want to use hfsplus fs as an aufs branch fs, then enable
21060+ this option. This option introduces a small overhead at
21061+ copying-up a file on hfsplus.
1facf9fc 21062+
4a4d8108
AM
21063+config AUFS_BDEV_LOOP
21064+ bool
21065+ depends on BLK_DEV_LOOP
21066+ default y
21067+ help
21068+ Automatic configuration for internal use.
21069+ Convert =[ym] into =y.
1308ab2a 21070+
4a4d8108
AM
21071+config AUFS_DEBUG
21072+ bool "Debug aufs"
21073+ help
21074+ Enable this to compile aufs internal debug code.
21075+ It will have a negative impact to the performance.
21076+
21077+config AUFS_MAGIC_SYSRQ
21078+ bool
21079+ depends on AUFS_DEBUG && MAGIC_SYSRQ
21080+ default y
21081+ help
21082+ Automatic configuration for internal use.
21083+ When aufs supports Magic SysRq, enabled automatically.
21084+endif
7f207e10
AM
21085diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c
21086--- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 21087+++ linux/fs/aufs/loop.c 2015-01-25 13:00:38.631047076 +0100
523b37e3 21088@@ -0,0 +1,145 @@
1facf9fc 21089+/*
523b37e3 21090+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 21091+ *
21092+ * This program, aufs is free software; you can redistribute it and/or modify
21093+ * it under the terms of the GNU General Public License as published by
21094+ * the Free Software Foundation; either version 2 of the License, or
21095+ * (at your option) any later version.
dece6358
AM
21096+ *
21097+ * This program is distributed in the hope that it will be useful,
21098+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21099+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21100+ * GNU General Public License for more details.
21101+ *
21102+ * You should have received a copy of the GNU General Public License
523b37e3 21103+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21104+ */
21105+
21106+/*
21107+ * support for loopback block device as a branch
21108+ */
21109+
1facf9fc 21110+#include "aufs.h"
21111+
392086de
AM
21112+/* added into drivers/block/loop.c */
21113+static struct file *(*backing_file_func)(struct super_block *sb);
21114+
1facf9fc 21115+/*
21116+ * test if two lower dentries have overlapping branches.
21117+ */
b752ccd1 21118+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
1facf9fc 21119+{
b752ccd1 21120+ struct super_block *h_sb;
392086de
AM
21121+ struct file *backing_file;
21122+
21123+ if (unlikely(!backing_file_func)) {
21124+ /* don't load "loop" module here */
21125+ backing_file_func = symbol_get(loop_backing_file);
21126+ if (unlikely(!backing_file_func))
21127+ /* "loop" module is not loaded */
21128+ return 0;
21129+ }
1facf9fc 21130+
b752ccd1 21131+ h_sb = h_adding->d_sb;
392086de
AM
21132+ backing_file = backing_file_func(h_sb);
21133+ if (!backing_file)
1facf9fc 21134+ return 0;
21135+
392086de 21136+ h_adding = backing_file->f_dentry;
b752ccd1
AM
21137+ /*
21138+ * h_adding can be local NFS.
21139+ * in this case aufs cannot detect the loop.
21140+ */
21141+ if (unlikely(h_adding->d_sb == sb))
1facf9fc 21142+ return 1;
b752ccd1 21143+ return !!au_test_subdir(h_adding, sb->s_root);
1facf9fc 21144+}
21145+
21146+/* true if a kernel thread named 'loop[0-9].*' accesses a file */
21147+int au_test_loopback_kthread(void)
21148+{
b752ccd1
AM
21149+ int ret;
21150+ struct task_struct *tsk = current;
a2a7ad62 21151+ char c, comm[sizeof(tsk->comm)];
b752ccd1
AM
21152+
21153+ ret = 0;
21154+ if (tsk->flags & PF_KTHREAD) {
a2a7ad62
AM
21155+ get_task_comm(comm, tsk);
21156+ c = comm[4];
b752ccd1 21157+ ret = ('0' <= c && c <= '9'
a2a7ad62 21158+ && !strncmp(comm, "loop", 4));
b752ccd1 21159+ }
1facf9fc 21160+
b752ccd1 21161+ return ret;
1facf9fc 21162+}
87a755f4
AM
21163+
21164+/* ---------------------------------------------------------------------- */
21165+
21166+#define au_warn_loopback_step 16
21167+static int au_warn_loopback_nelem = au_warn_loopback_step;
21168+static unsigned long *au_warn_loopback_array;
21169+
21170+void au_warn_loopback(struct super_block *h_sb)
21171+{
21172+ int i, new_nelem;
21173+ unsigned long *a, magic;
21174+ static DEFINE_SPINLOCK(spin);
21175+
21176+ magic = h_sb->s_magic;
21177+ spin_lock(&spin);
21178+ a = au_warn_loopback_array;
21179+ for (i = 0; i < au_warn_loopback_nelem && *a; i++)
21180+ if (a[i] == magic) {
21181+ spin_unlock(&spin);
21182+ return;
21183+ }
21184+
21185+ /* h_sb is new to us, print it */
21186+ if (i < au_warn_loopback_nelem) {
21187+ a[i] = magic;
21188+ goto pr;
21189+ }
21190+
21191+ /* expand the array */
21192+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step;
21193+ a = au_kzrealloc(au_warn_loopback_array,
21194+ au_warn_loopback_nelem * sizeof(unsigned long),
21195+ new_nelem * sizeof(unsigned long), GFP_ATOMIC);
21196+ if (a) {
21197+ au_warn_loopback_nelem = new_nelem;
21198+ au_warn_loopback_array = a;
21199+ a[i] = magic;
21200+ goto pr;
21201+ }
21202+
21203+ spin_unlock(&spin);
21204+ AuWarn1("realloc failed, ignored\n");
21205+ return;
21206+
21207+pr:
21208+ spin_unlock(&spin);
0c3ec466
AM
21209+ pr_warn("you may want to try another patch for loopback file "
21210+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic);
87a755f4
AM
21211+}
21212+
21213+int au_loopback_init(void)
21214+{
21215+ int err;
21216+ struct super_block *sb __maybe_unused;
21217+
21218+ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long));
21219+
21220+ err = 0;
21221+ au_warn_loopback_array = kcalloc(au_warn_loopback_step,
21222+ sizeof(unsigned long), GFP_NOFS);
21223+ if (unlikely(!au_warn_loopback_array))
21224+ err = -ENOMEM;
21225+
21226+ return err;
21227+}
21228+
21229+void au_loopback_fin(void)
21230+{
392086de 21231+ symbol_put(loop_backing_file);
87a755f4
AM
21232+ kfree(au_warn_loopback_array);
21233+}
7f207e10
AM
21234diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h
21235--- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 21236+++ linux/fs/aufs/loop.h 2015-01-25 13:00:38.631047076 +0100
523b37e3 21237@@ -0,0 +1,52 @@
1facf9fc 21238+/*
523b37e3 21239+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 21240+ *
21241+ * This program, aufs is free software; you can redistribute it and/or modify
21242+ * it under the terms of the GNU General Public License as published by
21243+ * the Free Software Foundation; either version 2 of the License, or
21244+ * (at your option) any later version.
dece6358
AM
21245+ *
21246+ * This program is distributed in the hope that it will be useful,
21247+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21248+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21249+ * GNU General Public License for more details.
21250+ *
21251+ * You should have received a copy of the GNU General Public License
523b37e3 21252+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21253+ */
21254+
21255+/*
21256+ * support for loopback mount as a branch
21257+ */
21258+
21259+#ifndef __AUFS_LOOP_H__
21260+#define __AUFS_LOOP_H__
21261+
21262+#ifdef __KERNEL__
21263+
dece6358
AM
21264+struct dentry;
21265+struct super_block;
1facf9fc 21266+
21267+#ifdef CONFIG_AUFS_BDEV_LOOP
392086de
AM
21268+/* drivers/block/loop.c */
21269+struct file *loop_backing_file(struct super_block *sb);
21270+
1facf9fc 21271+/* loop.c */
b752ccd1 21272+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding);
1facf9fc 21273+int au_test_loopback_kthread(void);
87a755f4
AM
21274+void au_warn_loopback(struct super_block *h_sb);
21275+
21276+int au_loopback_init(void);
21277+void au_loopback_fin(void);
1facf9fc 21278+#else
4a4d8108 21279+AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
b752ccd1 21280+ struct dentry *h_adding)
4a4d8108 21281+AuStubInt0(au_test_loopback_kthread, void)
87a755f4
AM
21282+AuStubVoid(au_warn_loopback, struct super_block *h_sb)
21283+
21284+AuStubInt0(au_loopback_init, void)
21285+AuStubVoid(au_loopback_fin, void)
1facf9fc 21286+#endif /* BLK_DEV_LOOP */
21287+
21288+#endif /* __KERNEL__ */
21289+#endif /* __AUFS_LOOP_H__ */
7f207e10
AM
21290diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk
21291--- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100
c1595e42 21292+++ linux/fs/aufs/magic.mk 2015-01-25 13:00:38.631047076 +0100
4a4d8108 21293@@ -0,0 +1,54 @@
1facf9fc 21294+
21295+# defined in ${srctree}/fs/fuse/inode.c
21296+# tristate
21297+ifdef CONFIG_FUSE_FS
21298+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546
21299+endif
21300+
21301+# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h
21302+# tristate
21303+ifdef CONFIG_OCFS2_FS
21304+ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f
21305+endif
21306+
21307+# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h
21308+# tristate
21309+ifdef CONFIG_OCFS2_FS_O2CB
21310+ccflags-y += -DDLMFS_MAGIC=0x76a9f425
21311+endif
21312+
1facf9fc 21313+# defined in ${srctree}/fs/cifs/cifsfs.c
21314+# tristate
21315+ifdef CONFIG_CIFS_FS
21316+ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42
21317+endif
21318+
21319+# defined in ${srctree}/fs/xfs/xfs_sb.h
21320+# tristate
21321+ifdef CONFIG_XFS_FS
21322+ccflags-y += -DXFS_SB_MAGIC=0x58465342
21323+endif
21324+
21325+# defined in ${srctree}/fs/configfs/mount.c
21326+# tristate
21327+ifdef CONFIG_CONFIGFS_FS
21328+ccflags-y += -DCONFIGFS_MAGIC=0x62656570
21329+endif
21330+
21331+# defined in ${srctree}/fs/9p/v9fs.h
21332+# tristate
21333+ifdef CONFIG_9P_FS
21334+ccflags-y += -DV9FS_MAGIC=0x01021997
21335+endif
21336+
21337+# defined in ${srctree}/fs/ubifs/ubifs.h
21338+# tristate
21339+ifdef CONFIG_UBIFS_FS
21340+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905
21341+endif
4a4d8108
AM
21342+
21343+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h
21344+# tristate
21345+ifdef CONFIG_HFSPLUS_FS
21346+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b
21347+endif
7f207e10
AM
21348diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile
21349--- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
21350+++ linux/fs/aufs/Makefile 2015-01-25 13:00:38.627713742 +0100
21351@@ -0,0 +1,44 @@
4a4d8108
AM
21352+
21353+include ${src}/magic.mk
21354+ifeq (${CONFIG_AUFS_FS},m)
21355+include ${src}/conf.mk
21356+endif
21357+-include ${src}/priv_def.mk
21358+
21359+# cf. include/linux/kernel.h
21360+# enable pr_debug
21361+ccflags-y += -DDEBUG
f6c5ef8b
AM
21362+# sparse requires the full pathname
21363+ifdef M
523b37e3 21364+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h
f6c5ef8b 21365+else
523b37e3 21366+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
f6c5ef8b 21367+endif
4a4d8108
AM
21368+
21369+obj-$(CONFIG_AUFS_FS) += aufs.o
21370+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \
21371+ wkq.o vfsub.o dcsub.o \
e49829fe 21372+ cpup.o whout.o wbr_policy.o \
4a4d8108
AM
21373+ dinfo.o dentry.o \
21374+ dynop.o \
21375+ finfo.o file.o f_op.o \
21376+ dir.o vdir.o \
21377+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \
c2b27bf2 21378+ mvdown.o ioctl.o
4a4d8108
AM
21379+
21380+# all are boolean
e49829fe 21381+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o
4a4d8108
AM
21382+aufs-$(CONFIG_SYSFS) += sysfs.o
21383+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o
21384+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o
21385+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o
21386+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o
4a4d8108 21387+aufs-$(CONFIG_AUFS_EXPORT) += export.o
c1595e42
JR
21388+aufs-$(CONFIG_AUFS_XATTR) += xattr.o
21389+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
076b876e 21390+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o
4a4d8108
AM
21391+aufs-$(CONFIG_AUFS_POLL) += poll.o
21392+aufs-$(CONFIG_AUFS_RDU) += rdu.o
4a4d8108
AM
21393+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o
21394+aufs-$(CONFIG_AUFS_DEBUG) += debug.o
21395+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o
7f207e10
AM
21396diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
21397--- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 21398+++ linux/fs/aufs/module.c 2015-01-25 13:00:38.634380408 +0100
076b876e 21399@@ -0,0 +1,210 @@
1facf9fc 21400+/*
523b37e3 21401+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 21402+ *
21403+ * This program, aufs is free software; you can redistribute it and/or modify
21404+ * it under the terms of the GNU General Public License as published by
21405+ * the Free Software Foundation; either version 2 of the License, or
21406+ * (at your option) any later version.
dece6358
AM
21407+ *
21408+ * This program is distributed in the hope that it will be useful,
21409+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21410+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21411+ * GNU General Public License for more details.
21412+ *
21413+ * You should have received a copy of the GNU General Public License
523b37e3 21414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21415+ */
21416+
21417+/*
21418+ * module global variables and operations
21419+ */
21420+
21421+#include <linux/module.h>
21422+#include <linux/seq_file.h>
21423+#include "aufs.h"
21424+
21425+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp)
21426+{
21427+ if (new_sz <= nused)
21428+ return p;
21429+
21430+ p = krealloc(p, new_sz, gfp);
21431+ if (p)
21432+ memset(p + nused, 0, new_sz - nused);
21433+ return p;
21434+}
21435+
21436+/* ---------------------------------------------------------------------- */
21437+
21438+/*
21439+ * aufs caches
21440+ */
21441+struct kmem_cache *au_cachep[AuCache_Last];
21442+static int __init au_cache_init(void)
21443+{
4a4d8108 21444+ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
1facf9fc 21445+ if (au_cachep[AuCache_DINFO])
027c5e7a 21446+ /* SLAB_DESTROY_BY_RCU */
4a4d8108
AM
21447+ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
21448+ au_icntnr_init_once);
1facf9fc 21449+ if (au_cachep[AuCache_ICNTNR])
4a4d8108
AM
21450+ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
21451+ au_fi_init_once);
1facf9fc 21452+ if (au_cachep[AuCache_FINFO])
21453+ au_cachep[AuCache_VDIR] = AuCache(au_vdir);
21454+ if (au_cachep[AuCache_VDIR])
21455+ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
21456+ if (au_cachep[AuCache_DEHSTR])
21457+ return 0;
21458+
21459+ return -ENOMEM;
21460+}
21461+
21462+static void au_cache_fin(void)
21463+{
21464+ int i;
4a4d8108 21465+
537831f9
AM
21466+ /*
21467+ * Make sure all delayed rcu free inodes are flushed before we
21468+ * destroy cache.
21469+ */
21470+ rcu_barrier();
21471+
7eafdf33
AM
21472+ /* excluding AuCache_HNOTIFY */
21473+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
21474+ for (i = 0; i < AuCache_HNOTIFY; i++)
1facf9fc 21475+ if (au_cachep[i]) {
21476+ kmem_cache_destroy(au_cachep[i]);
21477+ au_cachep[i] = NULL;
21478+ }
21479+}
21480+
21481+/* ---------------------------------------------------------------------- */
21482+
21483+int au_dir_roflags;
21484+
e49829fe 21485+#ifdef CONFIG_AUFS_SBILIST
1e00d052
AM
21486+/*
21487+ * iterate_supers_type() doesn't protect us from
21488+ * remounting (branch management)
21489+ */
e49829fe
JR
21490+struct au_splhead au_sbilist;
21491+#endif
21492+
9dbd164d
AM
21493+struct lock_class_key au_lc_key[AuLcKey_Last];
21494+
1facf9fc 21495+/*
21496+ * functions for module interface.
21497+ */
21498+MODULE_LICENSE("GPL");
21499+/* MODULE_LICENSE("GPL v2"); */
dece6358 21500+MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
1facf9fc 21501+MODULE_DESCRIPTION(AUFS_NAME
21502+ " -- Advanced multi layered unification filesystem");
21503+MODULE_VERSION(AUFS_VERSION);
c06a8ce3 21504+MODULE_ALIAS_FS(AUFS_NAME);
1facf9fc 21505+
1facf9fc 21506+/* this module parameter has no meaning when SYSFS is disabled */
21507+int sysaufs_brs = 1;
21508+MODULE_PARM_DESC(brs, "use <sysfs>/fs/aufs/si_*/brN");
21509+module_param_named(brs, sysaufs_brs, int, S_IRUGO);
21510+
076b876e
AM
21511+/* this module parameter has no meaning when USER_NS is disabled */
21512+static bool au_userns;
21513+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns");
21514+module_param_named(allow_userns, au_userns, bool, S_IRUGO);
21515+
1facf9fc 21516+/* ---------------------------------------------------------------------- */
21517+
21518+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */
21519+
21520+int au_seq_path(struct seq_file *seq, struct path *path)
21521+{
21522+ return seq_path(seq, path, au_esc_chars);
21523+}
21524+
21525+/* ---------------------------------------------------------------------- */
21526+
21527+static int __init aufs_init(void)
21528+{
21529+ int err, i;
21530+ char *p;
21531+
21532+ p = au_esc_chars;
21533+ for (i = 1; i <= ' '; i++)
21534+ *p++ = i;
21535+ *p++ = '\\';
21536+ *p++ = '\x7f';
21537+ *p = 0;
21538+
21539+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE);
21540+
e49829fe 21541+ au_sbilist_init();
1facf9fc 21542+ sysaufs_brs_init();
21543+ au_debug_init();
4a4d8108 21544+ au_dy_init();
1facf9fc 21545+ err = sysaufs_init();
21546+ if (unlikely(err))
21547+ goto out;
e49829fe 21548+ err = au_procfs_init();
4f0767ce 21549+ if (unlikely(err))
953406b4 21550+ goto out_sysaufs;
e49829fe
JR
21551+ err = au_wkq_init();
21552+ if (unlikely(err))
21553+ goto out_procfs;
87a755f4 21554+ err = au_loopback_init();
1facf9fc 21555+ if (unlikely(err))
21556+ goto out_wkq;
87a755f4
AM
21557+ err = au_hnotify_init();
21558+ if (unlikely(err))
21559+ goto out_loopback;
1facf9fc 21560+ err = au_sysrq_init();
21561+ if (unlikely(err))
21562+ goto out_hin;
21563+ err = au_cache_init();
21564+ if (unlikely(err))
21565+ goto out_sysrq;
076b876e
AM
21566+
21567+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0;
1facf9fc 21568+ err = register_filesystem(&aufs_fs_type);
21569+ if (unlikely(err))
21570+ goto out_cache;
076b876e 21571+
4a4d8108
AM
21572+ /* since we define pr_fmt, call printk directly */
21573+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
1facf9fc 21574+ goto out; /* success */
21575+
4f0767ce 21576+out_cache:
1facf9fc 21577+ au_cache_fin();
4f0767ce 21578+out_sysrq:
1facf9fc 21579+ au_sysrq_fin();
4f0767ce 21580+out_hin:
4a4d8108 21581+ au_hnotify_fin();
87a755f4
AM
21582+out_loopback:
21583+ au_loopback_fin();
4f0767ce 21584+out_wkq:
1facf9fc 21585+ au_wkq_fin();
e49829fe
JR
21586+out_procfs:
21587+ au_procfs_fin();
4f0767ce 21588+out_sysaufs:
1facf9fc 21589+ sysaufs_fin();
4a4d8108 21590+ au_dy_fin();
4f0767ce 21591+out:
1facf9fc 21592+ return err;
21593+}
21594+
21595+static void __exit aufs_exit(void)
21596+{
21597+ unregister_filesystem(&aufs_fs_type);
21598+ au_cache_fin();
21599+ au_sysrq_fin();
4a4d8108 21600+ au_hnotify_fin();
87a755f4 21601+ au_loopback_fin();
1facf9fc 21602+ au_wkq_fin();
e49829fe 21603+ au_procfs_fin();
1facf9fc 21604+ sysaufs_fin();
4a4d8108 21605+ au_dy_fin();
1facf9fc 21606+}
21607+
21608+module_init(aufs_init);
21609+module_exit(aufs_exit);
7f207e10
AM
21610diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
21611--- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 21612+++ linux/fs/aufs/module.h 2015-01-25 13:00:38.634380408 +0100
523b37e3 21613@@ -0,0 +1,104 @@
1facf9fc 21614+/*
523b37e3 21615+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 21616+ *
21617+ * This program, aufs is free software; you can redistribute it and/or modify
21618+ * it under the terms of the GNU General Public License as published by
21619+ * the Free Software Foundation; either version 2 of the License, or
21620+ * (at your option) any later version.
dece6358
AM
21621+ *
21622+ * This program is distributed in the hope that it will be useful,
21623+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21624+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21625+ * GNU General Public License for more details.
21626+ *
21627+ * You should have received a copy of the GNU General Public License
523b37e3 21628+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 21629+ */
21630+
21631+/*
21632+ * module initialization and module-global
21633+ */
21634+
21635+#ifndef __AUFS_MODULE_H__
21636+#define __AUFS_MODULE_H__
21637+
21638+#ifdef __KERNEL__
21639+
21640+#include <linux/slab.h>
21641+
dece6358
AM
21642+struct path;
21643+struct seq_file;
21644+
1facf9fc 21645+/* module parameters */
1facf9fc 21646+extern int sysaufs_brs;
21647+
21648+/* ---------------------------------------------------------------------- */
21649+
21650+extern int au_dir_roflags;
21651+
9dbd164d
AM
21652+enum {
21653+ AuLcNonDir_FIINFO,
21654+ AuLcNonDir_DIINFO,
21655+ AuLcNonDir_IIINFO,
21656+
21657+ AuLcDir_FIINFO,
21658+ AuLcDir_DIINFO,
21659+ AuLcDir_IIINFO,
21660+
21661+ AuLcSymlink_DIINFO,
21662+ AuLcSymlink_IIINFO,
21663+
21664+ AuLcKey_Last
21665+};
21666+extern struct lock_class_key au_lc_key[AuLcKey_Last];
21667+
1facf9fc 21668+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp);
21669+int au_seq_path(struct seq_file *seq, struct path *path);
21670+
e49829fe
JR
21671+#ifdef CONFIG_PROC_FS
21672+/* procfs.c */
21673+int __init au_procfs_init(void);
21674+void au_procfs_fin(void);
21675+#else
21676+AuStubInt0(au_procfs_init, void);
21677+AuStubVoid(au_procfs_fin, void);
21678+#endif
21679+
4f0767ce
JR
21680+/* ---------------------------------------------------------------------- */
21681+
21682+/* kmem cache */
1facf9fc 21683+enum {
21684+ AuCache_DINFO,
21685+ AuCache_ICNTNR,
21686+ AuCache_FINFO,
21687+ AuCache_VDIR,
21688+ AuCache_DEHSTR,
7eafdf33 21689+ AuCache_HNOTIFY, /* must be last */
1facf9fc 21690+ AuCache_Last
21691+};
21692+
4a4d8108
AM
21693+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
21694+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags)
21695+#define AuCacheCtor(type, ctor) \
21696+ kmem_cache_create(#type, sizeof(struct type), \
21697+ __alignof__(struct type), AuCacheFlags, ctor)
1facf9fc 21698+
21699+extern struct kmem_cache *au_cachep[];
21700+
21701+#define AuCacheFuncs(name, index) \
4a4d8108 21702+static inline struct au_##name *au_cache_alloc_##name(void) \
1facf9fc 21703+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
4a4d8108 21704+static inline void au_cache_free_##name(struct au_##name *p) \
1facf9fc 21705+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
21706+
21707+AuCacheFuncs(dinfo, DINFO);
21708+AuCacheFuncs(icntnr, ICNTNR);
21709+AuCacheFuncs(finfo, FINFO);
21710+AuCacheFuncs(vdir, VDIR);
4a4d8108
AM
21711+AuCacheFuncs(vdir_dehstr, DEHSTR);
21712+#ifdef CONFIG_AUFS_HNOTIFY
21713+AuCacheFuncs(hnotify, HNOTIFY);
21714+#endif
1facf9fc 21715+
4a4d8108
AM
21716+#endif /* __KERNEL__ */
21717+#endif /* __AUFS_MODULE_H__ */
c2b27bf2
AM
21718diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c
21719--- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
21720+++ linux/fs/aufs/mvdown.c 2015-01-25 13:00:38.634380408 +0100
21721@@ -0,0 +1,694 @@
c2b27bf2 21722+/*
523b37e3 21723+ * Copyright (C) 2011-2014 Junjiro R. Okajima
c2b27bf2
AM
21724+ *
21725+ * This program, aufs is free software; you can redistribute it and/or modify
21726+ * it under the terms of the GNU General Public License as published by
21727+ * the Free Software Foundation; either version 2 of the License, or
21728+ * (at your option) any later version.
21729+ *
21730+ * This program is distributed in the hope that it will be useful,
21731+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21732+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21733+ * GNU General Public License for more details.
21734+ *
21735+ * You should have received a copy of the GNU General Public License
523b37e3
AM
21736+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21737+ */
21738+
21739+/*
21740+ * move-down, opposite of copy-up
c2b27bf2
AM
21741+ */
21742+
21743+#include "aufs.h"
21744+
c2b27bf2
AM
21745+struct au_mvd_args {
21746+ struct {
c2b27bf2
AM
21747+ struct super_block *h_sb;
21748+ struct dentry *h_parent;
21749+ struct au_hinode *hdir;
392086de 21750+ struct inode *h_dir, *h_inode;
c1595e42 21751+ struct au_pin pin;
c2b27bf2
AM
21752+ } info[AUFS_MVDOWN_NARRAY];
21753+
21754+ struct aufs_mvdown mvdown;
21755+ struct dentry *dentry, *parent;
21756+ struct inode *inode, *dir;
21757+ struct super_block *sb;
21758+ aufs_bindex_t bopq, bwh, bfound;
21759+ unsigned char rename_lock;
c2b27bf2
AM
21760+};
21761+
392086de 21762+#define mvd_errno mvdown.au_errno
076b876e
AM
21763+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex
21764+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid
21765+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex
21766+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid
c2b27bf2 21767+
392086de
AM
21768+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb
21769+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent
21770+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir
21771+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir
21772+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode
c1595e42 21773+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin
392086de
AM
21774+
21775+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb
21776+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent
21777+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir
21778+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir
21779+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode
c1595e42 21780+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin
c2b27bf2
AM
21781+
21782+#define AU_MVD_PR(flag, ...) do { \
21783+ if (flag) \
21784+ pr_err(__VA_ARGS__); \
21785+ } while (0)
21786+
076b876e
AM
21787+static int find_lower_writable(struct au_mvd_args *a)
21788+{
21789+ struct super_block *sb;
21790+ aufs_bindex_t bindex, bend;
21791+ struct au_branch *br;
21792+
21793+ sb = a->sb;
21794+ bindex = a->mvd_bsrc;
21795+ bend = au_sbend(sb);
21796+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER)
21797+ for (bindex++; bindex <= bend; bindex++) {
21798+ br = au_sbr(sb, bindex);
21799+ if (au_br_fhsm(br->br_perm)
21800+ && (!(au_br_sb(br)->s_flags & MS_RDONLY)))
21801+ return bindex;
21802+ }
21803+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER))
21804+ for (bindex++; bindex <= bend; bindex++) {
21805+ br = au_sbr(sb, bindex);
21806+ if (!au_br_rdonly(br))
21807+ return bindex;
21808+ }
21809+ else
21810+ for (bindex++; bindex <= bend; bindex++) {
21811+ br = au_sbr(sb, bindex);
21812+ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) {
21813+ if (au_br_rdonly(br))
21814+ a->mvdown.flags
21815+ |= AUFS_MVDOWN_ROLOWER_R;
21816+ return bindex;
21817+ }
21818+ }
21819+
21820+ return -1;
21821+}
21822+
c2b27bf2 21823+/* make the parent dir on bdst */
392086de 21824+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21825+{
21826+ int err;
21827+
21828+ err = 0;
21829+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc);
21830+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst);
21831+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc);
21832+ a->mvd_h_dst_parent = NULL;
21833+ if (au_dbend(a->parent) >= a->mvd_bdst)
21834+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
21835+ if (!a->mvd_h_dst_parent) {
21836+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst);
21837+ if (unlikely(err)) {
392086de 21838+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n");
c2b27bf2
AM
21839+ goto out;
21840+ }
21841+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst);
21842+ }
21843+
21844+out:
21845+ AuTraceErr(err);
21846+ return err;
21847+}
21848+
21849+/* lock them all */
392086de 21850+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21851+{
21852+ int err;
21853+ struct dentry *h_trap;
21854+
21855+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc);
21856+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst);
c1595e42
JR
21857+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst,
21858+ au_opt_udba(a->sb),
21859+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21860+ AuTraceErr(err);
21861+ if (unlikely(err)) {
21862+ AU_MVD_PR(dmsg, "pin_dst failed\n");
21863+ goto out;
21864+ }
21865+
c2b27bf2
AM
21866+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) {
21867+ a->rename_lock = 0;
c1595e42
JR
21868+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
21869+ AuLsc_DI_PARENT, AuLsc_I_PARENT3,
21870+ au_opt_udba(a->sb),
21871+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21872+ err = au_do_pin(&a->mvd_pin_src);
21873+ AuTraceErr(err);
21874+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
21875+ if (unlikely(err)) {
21876+ AU_MVD_PR(dmsg, "pin_src failed\n");
21877+ goto out_dst;
21878+ }
21879+ goto out; /* success */
c2b27bf2
AM
21880+ }
21881+
c2b27bf2 21882+ a->rename_lock = 1;
c1595e42
JR
21883+ au_pin_hdir_unlock(&a->mvd_pin_dst);
21884+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc,
21885+ au_opt_udba(a->sb),
21886+ AuPin_MNT_WRITE | AuPin_DI_LOCKED);
21887+ AuTraceErr(err);
21888+ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode;
21889+ if (unlikely(err)) {
21890+ AU_MVD_PR(dmsg, "pin_src failed\n");
21891+ au_pin_hdir_lock(&a->mvd_pin_dst);
21892+ goto out_dst;
21893+ }
21894+ au_pin_hdir_unlock(&a->mvd_pin_src);
c2b27bf2
AM
21895+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21896+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
21897+ if (h_trap) {
21898+ err = (h_trap != a->mvd_h_src_parent);
21899+ if (err)
21900+ err = (h_trap != a->mvd_h_dst_parent);
21901+ }
21902+ BUG_ON(err); /* it should never happen */
c1595e42
JR
21903+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) {
21904+ err = -EBUSY;
21905+ AuTraceErr(err);
21906+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21907+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
21908+ au_pin_hdir_lock(&a->mvd_pin_src);
21909+ au_unpin(&a->mvd_pin_src);
21910+ au_pin_hdir_lock(&a->mvd_pin_dst);
21911+ goto out_dst;
21912+ }
21913+ goto out; /* success */
c2b27bf2 21914+
c1595e42
JR
21915+out_dst:
21916+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
21917+out:
21918+ AuTraceErr(err);
21919+ return err;
21920+}
21921+
392086de 21922+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2 21923+{
c1595e42
JR
21924+ if (!a->rename_lock)
21925+ au_unpin(&a->mvd_pin_src);
21926+ else {
c2b27bf2
AM
21927+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src,
21928+ a->mvd_h_dst_parent, a->mvd_hdir_dst);
c1595e42
JR
21929+ au_pin_hdir_lock(&a->mvd_pin_src);
21930+ au_unpin(&a->mvd_pin_src);
21931+ au_pin_hdir_lock(&a->mvd_pin_dst);
21932+ }
21933+ au_unpin(&a->mvd_pin_dst);
c2b27bf2
AM
21934+}
21935+
21936+/* copy-down the file */
392086de 21937+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21938+{
21939+ int err;
21940+ struct au_cp_generic cpg = {
21941+ .dentry = a->dentry,
21942+ .bdst = a->mvd_bdst,
21943+ .bsrc = a->mvd_bsrc,
21944+ .len = -1,
c1595e42 21945+ .pin = &a->mvd_pin_dst,
c2b27bf2
AM
21946+ .flags = AuCpup_DTIME | AuCpup_HOPEN
21947+ };
21948+
21949+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst);
392086de
AM
21950+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
21951+ au_fset_cpup(cpg.flags, OVERWRITE);
21952+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER)
21953+ au_fset_cpup(cpg.flags, RWDST);
c2b27bf2
AM
21954+ err = au_sio_cpdown_simple(&cpg);
21955+ if (unlikely(err))
392086de 21956+ AU_MVD_PR(dmsg, "cpdown failed\n");
c2b27bf2
AM
21957+
21958+ AuTraceErr(err);
21959+ return err;
21960+}
21961+
21962+/*
21963+ * unlink the whiteout on bdst if exist which may be created by UDBA while we
21964+ * were sleeping
21965+ */
392086de 21966+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
21967+{
21968+ int err;
21969+ struct path h_path;
21970+ struct au_branch *br;
523b37e3 21971+ struct inode *delegated;
c2b27bf2
AM
21972+
21973+ br = au_sbr(a->sb, a->mvd_bdst);
21974+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br);
21975+ err = PTR_ERR(h_path.dentry);
21976+ if (IS_ERR(h_path.dentry)) {
392086de 21977+ AU_MVD_PR(dmsg, "wh_lkup failed\n");
c2b27bf2
AM
21978+ goto out;
21979+ }
21980+
21981+ err = 0;
21982+ if (h_path.dentry->d_inode) {
21983+ h_path.mnt = au_br_mnt(br);
523b37e3 21984+ delegated = NULL;
c2b27bf2 21985+ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path,
523b37e3
AM
21986+ &delegated, /*force*/0);
21987+ if (unlikely(err == -EWOULDBLOCK)) {
21988+ pr_warn("cannot retry for NFSv4 delegation"
21989+ " for an internal unlink\n");
21990+ iput(delegated);
21991+ }
c2b27bf2 21992+ if (unlikely(err))
392086de 21993+ AU_MVD_PR(dmsg, "wh_unlink failed\n");
c2b27bf2
AM
21994+ }
21995+ dput(h_path.dentry);
21996+
21997+out:
21998+ AuTraceErr(err);
21999+ return err;
22000+}
22001+
22002+/*
22003+ * unlink the topmost h_dentry
c2b27bf2 22004+ */
392086de 22005+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22006+{
22007+ int err;
22008+ struct path h_path;
523b37e3 22009+ struct inode *delegated;
c2b27bf2
AM
22010+
22011+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc);
22012+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc);
523b37e3
AM
22013+ delegated = NULL;
22014+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0);
22015+ if (unlikely(err == -EWOULDBLOCK)) {
22016+ pr_warn("cannot retry for NFSv4 delegation"
22017+ " for an internal unlink\n");
22018+ iput(delegated);
22019+ }
c2b27bf2 22020+ if (unlikely(err))
392086de 22021+ AU_MVD_PR(dmsg, "unlink failed\n");
c2b27bf2
AM
22022+
22023+ AuTraceErr(err);
22024+ return err;
22025+}
22026+
076b876e
AM
22027+/* Since mvdown succeeded, we ignore an error of this function */
22028+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a)
22029+{
22030+ int err;
22031+ struct au_branch *br;
22032+
22033+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED;
22034+ br = au_sbr(a->sb, a->mvd_bsrc);
22035+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs);
22036+ if (!err) {
22037+ br = au_sbr(a->sb, a->mvd_bdst);
22038+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id;
22039+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs);
22040+ }
22041+ if (!err)
22042+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED;
22043+ else
22044+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err);
22045+}
22046+
c2b27bf2
AM
22047+/*
22048+ * copy-down the file and unlink the bsrc file.
22049+ * - unlink the bdst whout if exist
22050+ * - copy-down the file (with whtmp name and rename)
22051+ * - unlink the bsrc file
22052+ */
392086de 22053+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22054+{
22055+ int err;
22056+
392086de 22057+ err = au_do_mkdir(dmsg, a);
c2b27bf2 22058+ if (!err)
392086de 22059+ err = au_do_lock(dmsg, a);
c2b27bf2
AM
22060+ if (unlikely(err))
22061+ goto out;
22062+
22063+ /*
22064+ * do not revert the activities we made on bdst since they should be
22065+ * harmless in aufs.
22066+ */
22067+
392086de 22068+ err = au_do_cpdown(dmsg, a);
c2b27bf2 22069+ if (!err)
392086de
AM
22070+ err = au_do_unlink_wh(dmsg, a);
22071+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER))
22072+ err = au_do_unlink(dmsg, a);
c2b27bf2
AM
22073+ if (unlikely(err))
22074+ goto out_unlock;
22075+
c1595e42
JR
22076+ AuDbg("%pd2, 0x%x, %d --> %d\n",
22077+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst);
076b876e
AM
22078+ if (find_lower_writable(a) < 0)
22079+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM;
22080+
22081+ if (a->mvdown.flags & AUFS_MVDOWN_STFS)
22082+ au_do_stfs(dmsg, a);
22083+
c2b27bf2 22084+ /* maintain internal array */
392086de
AM
22085+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) {
22086+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL);
22087+ au_set_dbstart(a->dentry, a->mvd_bdst);
22088+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0);
22089+ au_set_ibstart(a->inode, a->mvd_bdst);
22090+ }
c2b27bf2
AM
22091+ if (au_dbend(a->dentry) < a->mvd_bdst)
22092+ au_set_dbend(a->dentry, a->mvd_bdst);
c2b27bf2
AM
22093+ if (au_ibend(a->inode) < a->mvd_bdst)
22094+ au_set_ibend(a->inode, a->mvd_bdst);
22095+
22096+out_unlock:
392086de 22097+ au_do_unlock(dmsg, a);
c2b27bf2
AM
22098+out:
22099+ AuTraceErr(err);
22100+ return err;
22101+}
22102+
22103+/* ---------------------------------------------------------------------- */
22104+
c2b27bf2 22105+/* make sure the file is idle */
392086de 22106+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22107+{
22108+ int err, plinked;
c2b27bf2
AM
22109+
22110+ err = 0;
c2b27bf2
AM
22111+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK);
22112+ if (au_dbstart(a->dentry) == a->mvd_bsrc
c1595e42 22113+ && au_dcount(a->dentry) == 1
c2b27bf2 22114+ && atomic_read(&a->inode->i_count) == 1
392086de 22115+ /* && a->mvd_h_src_inode->i_nlink == 1 */
c2b27bf2
AM
22116+ && (!plinked || !au_plink_test(a->inode))
22117+ && a->inode->i_nlink == 1)
22118+ goto out;
22119+
22120+ err = -EBUSY;
392086de 22121+ AU_MVD_PR(dmsg,
c1595e42
JR
22122+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n",
22123+ a->mvd_bsrc, au_dbstart(a->dentry), au_dcount(a->dentry),
c2b27bf2 22124+ atomic_read(&a->inode->i_count), a->inode->i_nlink,
392086de 22125+ a->mvd_h_src_inode->i_nlink,
c2b27bf2
AM
22126+ plinked, plinked ? au_plink_test(a->inode) : 0);
22127+
22128+out:
22129+ AuTraceErr(err);
22130+ return err;
22131+}
22132+
22133+/* make sure the parent dir is fine */
392086de 22134+static int au_mvd_args_parent(const unsigned char dmsg,
c2b27bf2
AM
22135+ struct au_mvd_args *a)
22136+{
22137+ int err;
22138+ aufs_bindex_t bindex;
22139+
22140+ err = 0;
22141+ if (unlikely(au_alive_dir(a->parent))) {
22142+ err = -ENOENT;
392086de 22143+ AU_MVD_PR(dmsg, "parent dir is dead\n");
c2b27bf2
AM
22144+ goto out;
22145+ }
22146+
22147+ a->bopq = au_dbdiropq(a->parent);
22148+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst);
22149+ AuDbg("b%d\n", bindex);
22150+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst)
22151+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) {
22152+ err = -EINVAL;
392086de
AM
22153+ a->mvd_errno = EAU_MVDOWN_OPAQUE;
22154+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n",
c2b27bf2
AM
22155+ a->bopq, a->mvd_bdst);
22156+ }
22157+
22158+out:
22159+ AuTraceErr(err);
22160+ return err;
22161+}
22162+
392086de 22163+static int au_mvd_args_intermediate(const unsigned char dmsg,
c2b27bf2
AM
22164+ struct au_mvd_args *a)
22165+{
22166+ int err;
22167+ struct au_dinfo *dinfo, *tmp;
22168+
22169+ /* lookup the next lower positive entry */
22170+ err = -ENOMEM;
22171+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP);
22172+ if (unlikely(!tmp))
22173+ goto out;
22174+
22175+ a->bfound = -1;
22176+ a->bwh = -1;
22177+ dinfo = au_di(a->dentry);
22178+ au_di_cp(tmp, dinfo);
22179+ au_di_swap(tmp, dinfo);
22180+
22181+ /* returns the number of positive dentries */
22182+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0);
22183+ if (!err)
22184+ a->bwh = au_dbwh(a->dentry);
22185+ else if (err > 0)
22186+ a->bfound = au_dbstart(a->dentry);
22187+
22188+ au_di_swap(tmp, dinfo);
22189+ au_rw_write_unlock(&tmp->di_rwsem);
22190+ au_di_free(tmp);
22191+ if (unlikely(err < 0))
392086de 22192+ AU_MVD_PR(dmsg, "failed look-up lower\n");
c2b27bf2
AM
22193+
22194+ /*
22195+ * here, we have these cases.
22196+ * bfound == -1
22197+ * no positive dentry under bsrc. there are more sub-cases.
22198+ * bwh < 0
22199+ * there no whiteout, we can safely move-down.
22200+ * bwh <= bsrc
22201+ * impossible
22202+ * bsrc < bwh && bwh < bdst
22203+ * there is a whiteout on RO branch. cannot proceed.
22204+ * bwh == bdst
22205+ * there is a whiteout on the RW target branch. it should
22206+ * be removed.
22207+ * bdst < bwh
22208+ * there is a whiteout somewhere unrelated branch.
22209+ * -1 < bfound && bfound <= bsrc
22210+ * impossible.
22211+ * bfound < bdst
22212+ * found, but it is on RO branch between bsrc and bdst. cannot
22213+ * proceed.
22214+ * bfound == bdst
22215+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return
22216+ * error.
22217+ * bdst < bfound
22218+ * found, after we create the file on bdst, it will be hidden.
22219+ */
22220+
22221+ AuDebugOn(a->bfound == -1
22222+ && a->bwh != -1
22223+ && a->bwh <= a->mvd_bsrc);
22224+ AuDebugOn(-1 < a->bfound
22225+ && a->bfound <= a->mvd_bsrc);
22226+
22227+ err = -EINVAL;
22228+ if (a->bfound == -1
22229+ && a->mvd_bsrc < a->bwh
22230+ && a->bwh != -1
22231+ && a->bwh < a->mvd_bdst) {
392086de
AM
22232+ a->mvd_errno = EAU_MVDOWN_WHITEOUT;
22233+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n",
c2b27bf2
AM
22234+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh);
22235+ goto out;
22236+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) {
392086de
AM
22237+ a->mvd_errno = EAU_MVDOWN_UPPER;
22238+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n",
c2b27bf2
AM
22239+ a->mvd_bdst, a->bfound);
22240+ goto out;
22241+ }
22242+
22243+ err = 0; /* success */
22244+
22245+out:
22246+ AuTraceErr(err);
22247+ return err;
22248+}
22249+
392086de 22250+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22251+{
22252+ int err;
22253+
392086de
AM
22254+ err = 0;
22255+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER)
22256+ && a->bfound == a->mvd_bdst)
22257+ err = -EEXIST;
c2b27bf2
AM
22258+ AuTraceErr(err);
22259+ return err;
22260+}
22261+
392086de 22262+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a)
c2b27bf2
AM
22263+{
22264+ int err;
22265+ struct au_branch *br;
22266+
22267+ err = -EISDIR;
22268+ if (unlikely(S_ISDIR(a->inode->i_mode)))
22269+ goto out;
22270+
22271+ err = -EINVAL;
392086de
AM
22272+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER))
22273+ a->mvd_bsrc = au_ibstart(a->inode);
22274+ else {
22275+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid);
22276+ if (unlikely(a->mvd_bsrc < 0
22277+ || (a->mvd_bsrc < au_dbstart(a->dentry)
22278+ || au_dbend(a->dentry) < a->mvd_bsrc
22279+ || !au_h_dptr(a->dentry, a->mvd_bsrc))
22280+ || (a->mvd_bsrc < au_ibstart(a->inode)
22281+ || au_ibend(a->inode) < a->mvd_bsrc
22282+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) {
22283+ a->mvd_errno = EAU_MVDOWN_NOUPPER;
22284+ AU_MVD_PR(dmsg, "no upper\n");
22285+ goto out;
22286+ }
22287+ }
c2b27bf2 22288+ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) {
392086de
AM
22289+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
22290+ AU_MVD_PR(dmsg, "on the bottom\n");
c2b27bf2
AM
22291+ goto out;
22292+ }
392086de 22293+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc);
c2b27bf2
AM
22294+ br = au_sbr(a->sb, a->mvd_bsrc);
22295+ err = au_br_rdonly(br);
392086de
AM
22296+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) {
22297+ if (unlikely(err))
22298+ goto out;
22299+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode)
22300+ || IS_APPEND(a->mvd_h_src_inode))) {
22301+ if (err)
22302+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R;
22303+ /* go on */
22304+ } else
c2b27bf2
AM
22305+ goto out;
22306+
22307+ err = -EINVAL;
392086de
AM
22308+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) {
22309+ a->mvd_bdst = find_lower_writable(a);
22310+ if (unlikely(a->mvd_bdst < 0)) {
22311+ a->mvd_errno = EAU_MVDOWN_BOTTOM;
22312+ AU_MVD_PR(dmsg, "no writable lower branch\n");
22313+ goto out;
22314+ }
22315+ } else {
22316+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid);
22317+ if (unlikely(a->mvd_bdst < 0
22318+ || au_sbend(a->sb) < a->mvd_bdst)) {
22319+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR;
22320+ AU_MVD_PR(dmsg, "no lower brid\n");
22321+ goto out;
22322+ }
c2b27bf2
AM
22323+ }
22324+
392086de 22325+ err = au_mvd_args_busy(dmsg, a);
c2b27bf2 22326+ if (!err)
392086de 22327+ err = au_mvd_args_parent(dmsg, a);
c2b27bf2 22328+ if (!err)
392086de 22329+ err = au_mvd_args_intermediate(dmsg, a);
c2b27bf2 22330+ if (!err)
392086de 22331+ err = au_mvd_args_exist(dmsg, a);
c2b27bf2
AM
22332+ if (!err)
22333+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst);
22334+
22335+out:
22336+ AuTraceErr(err);
22337+ return err;
22338+}
22339+
22340+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg)
22341+{
392086de
AM
22342+ int err, e;
22343+ unsigned char dmsg;
22344+ struct au_mvd_args *args;
c2b27bf2
AM
22345+
22346+ err = -EPERM;
22347+ if (unlikely(!capable(CAP_SYS_ADMIN)))
22348+ goto out;
22349+
392086de
AM
22350+ err = -ENOMEM;
22351+ args = kmalloc(sizeof(*args), GFP_NOFS);
22352+ if (unlikely(!args))
22353+ goto out;
22354+
22355+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown));
22356+ if (!err)
22357+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg));
c2b27bf2
AM
22358+ if (unlikely(err)) {
22359+ err = -EFAULT;
392086de
AM
22360+ AuTraceErr(err);
22361+ goto out_free;
c2b27bf2 22362+ }
392086de
AM
22363+ AuDbg("flags 0x%x\n", args->mvdown.flags);
22364+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R);
22365+ args->mvdown.au_errno = 0;
22366+ args->dentry = dentry;
22367+ args->inode = dentry->d_inode;
22368+ args->sb = dentry->d_sb;
c2b27bf2 22369+
392086de
AM
22370+ err = -ENOENT;
22371+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG);
22372+ args->parent = dget_parent(dentry);
22373+ args->dir = args->parent->d_inode;
22374+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT);
22375+ dput(args->parent);
22376+ if (unlikely(args->parent != dentry->d_parent)) {
22377+ AU_MVD_PR(dmsg, "parent dir is moved\n");
c2b27bf2
AM
22378+ goto out_dir;
22379+ }
22380+
392086de 22381+ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD);
c2b27bf2
AM
22382+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH);
22383+ if (unlikely(err))
22384+ goto out_inode;
22385+
392086de
AM
22386+ di_write_lock_parent(args->parent);
22387+ err = au_mvd_args(dmsg, args);
c2b27bf2
AM
22388+ if (unlikely(err))
22389+ goto out_parent;
22390+
392086de 22391+ err = au_do_mvdown(dmsg, args);
c2b27bf2
AM
22392+ if (unlikely(err))
22393+ goto out_parent;
c2b27bf2 22394+
392086de
AM
22395+ au_cpup_attr_timesizes(args->dir);
22396+ au_cpup_attr_timesizes(args->inode);
22397+ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst));
c2b27bf2
AM
22398+ /* au_digen_dec(dentry); */
22399+
22400+out_parent:
392086de 22401+ di_write_unlock(args->parent);
c2b27bf2
AM
22402+ aufs_read_unlock(dentry, AuLock_DW);
22403+out_inode:
392086de 22404+ mutex_unlock(&args->inode->i_mutex);
c2b27bf2 22405+out_dir:
392086de
AM
22406+ mutex_unlock(&args->dir->i_mutex);
22407+out_free:
22408+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown));
22409+ if (unlikely(e))
22410+ err = -EFAULT;
22411+ kfree(args);
c2b27bf2
AM
22412+out:
22413+ AuTraceErr(err);
22414+ return err;
22415+}
22416diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
22417--- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
22418+++ linux/fs/aufs/opts.c 2015-01-25 13:00:38.634380408 +0100
22419@@ -0,0 +1,1850 @@
1facf9fc 22420+/*
523b37e3 22421+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 22422+ *
22423+ * This program, aufs is free software; you can redistribute it and/or modify
22424+ * it under the terms of the GNU General Public License as published by
22425+ * the Free Software Foundation; either version 2 of the License, or
22426+ * (at your option) any later version.
dece6358
AM
22427+ *
22428+ * This program is distributed in the hope that it will be useful,
22429+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22430+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22431+ * GNU General Public License for more details.
22432+ *
22433+ * You should have received a copy of the GNU General Public License
523b37e3 22434+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 22435+ */
22436+
22437+/*
22438+ * mount options/flags
22439+ */
22440+
dece6358 22441+#include <linux/namei.h>
1facf9fc 22442+#include <linux/types.h> /* a distribution requires */
22443+#include <linux/parser.h>
22444+#include "aufs.h"
22445+
22446+/* ---------------------------------------------------------------------- */
22447+
22448+enum {
22449+ Opt_br,
22450+ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend,
22451+ Opt_idel, Opt_imod, Opt_ireorder,
22452+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir,
dece6358 22453+ Opt_rdblk_def, Opt_rdhash_def,
1facf9fc 22454+ Opt_xino, Opt_zxino, Opt_noxino,
22455+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino,
22456+ Opt_trunc_xino_path, Opt_itrunc_xino,
22457+ Opt_trunc_xib, Opt_notrunc_xib,
dece6358 22458+ Opt_shwh, Opt_noshwh,
1facf9fc 22459+ Opt_plink, Opt_noplink, Opt_list_plink,
22460+ Opt_udba,
4a4d8108 22461+ Opt_dio, Opt_nodio,
1facf9fc 22462+ /* Opt_lock, Opt_unlock, */
22463+ Opt_cmd, Opt_cmd_args,
22464+ Opt_diropq_a, Opt_diropq_w,
22465+ Opt_warn_perm, Opt_nowarn_perm,
22466+ Opt_wbr_copyup, Opt_wbr_create,
076b876e 22467+ Opt_fhsm_sec,
1facf9fc 22468+ Opt_refrof, Opt_norefrof,
22469+ Opt_verbose, Opt_noverbose,
22470+ Opt_sum, Opt_nosum, Opt_wsum,
076b876e 22471+ Opt_dirperm1, Opt_nodirperm1,
c1595e42 22472+ Opt_acl, Opt_noacl,
1facf9fc 22473+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err
22474+};
22475+
22476+static match_table_t options = {
22477+ {Opt_br, "br=%s"},
22478+ {Opt_br, "br:%s"},
22479+
22480+ {Opt_add, "add=%d:%s"},
22481+ {Opt_add, "add:%d:%s"},
22482+ {Opt_add, "ins=%d:%s"},
22483+ {Opt_add, "ins:%d:%s"},
22484+ {Opt_append, "append=%s"},
22485+ {Opt_append, "append:%s"},
22486+ {Opt_prepend, "prepend=%s"},
22487+ {Opt_prepend, "prepend:%s"},
22488+
22489+ {Opt_del, "del=%s"},
22490+ {Opt_del, "del:%s"},
22491+ /* {Opt_idel, "idel:%d"}, */
22492+ {Opt_mod, "mod=%s"},
22493+ {Opt_mod, "mod:%s"},
22494+ /* {Opt_imod, "imod:%d:%s"}, */
22495+
22496+ {Opt_dirwh, "dirwh=%d"},
22497+
22498+ {Opt_xino, "xino=%s"},
22499+ {Opt_noxino, "noxino"},
22500+ {Opt_trunc_xino, "trunc_xino"},
22501+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"},
22502+ {Opt_notrunc_xino, "notrunc_xino"},
22503+ {Opt_trunc_xino_path, "trunc_xino=%s"},
22504+ {Opt_itrunc_xino, "itrunc_xino=%d"},
22505+ /* {Opt_zxino, "zxino=%s"}, */
22506+ {Opt_trunc_xib, "trunc_xib"},
22507+ {Opt_notrunc_xib, "notrunc_xib"},
22508+
e49829fe 22509+#ifdef CONFIG_PROC_FS
1facf9fc 22510+ {Opt_plink, "plink"},
e49829fe
JR
22511+#else
22512+ {Opt_ignore_silent, "plink"},
22513+#endif
22514+
1facf9fc 22515+ {Opt_noplink, "noplink"},
e49829fe 22516+
1facf9fc 22517+#ifdef CONFIG_AUFS_DEBUG
22518+ {Opt_list_plink, "list_plink"},
22519+#endif
22520+
22521+ {Opt_udba, "udba=%s"},
22522+
4a4d8108
AM
22523+ {Opt_dio, "dio"},
22524+ {Opt_nodio, "nodio"},
22525+
076b876e
AM
22526+#ifdef CONFIG_AUFS_FHSM
22527+ {Opt_fhsm_sec, "fhsm_sec=%d"},
22528+#else
22529+ {Opt_ignore_silent, "fhsm_sec=%d"},
22530+#endif
22531+
1facf9fc 22532+ {Opt_diropq_a, "diropq=always"},
22533+ {Opt_diropq_a, "diropq=a"},
22534+ {Opt_diropq_w, "diropq=whiteouted"},
22535+ {Opt_diropq_w, "diropq=w"},
22536+
22537+ {Opt_warn_perm, "warn_perm"},
22538+ {Opt_nowarn_perm, "nowarn_perm"},
22539+
22540+ /* keep them temporary */
1facf9fc 22541+ {Opt_ignore_silent, "nodlgt"},
1facf9fc 22542+ {Opt_ignore_silent, "clean_plink"},
22543+
dece6358
AM
22544+#ifdef CONFIG_AUFS_SHWH
22545+ {Opt_shwh, "shwh"},
22546+#endif
22547+ {Opt_noshwh, "noshwh"},
22548+
076b876e
AM
22549+ {Opt_dirperm1, "dirperm1"},
22550+ {Opt_nodirperm1, "nodirperm1"},
22551+
1facf9fc 22552+ {Opt_rendir, "rendir=%d"},
22553+
22554+ {Opt_refrof, "refrof"},
22555+ {Opt_norefrof, "norefrof"},
22556+
22557+ {Opt_verbose, "verbose"},
22558+ {Opt_verbose, "v"},
22559+ {Opt_noverbose, "noverbose"},
22560+ {Opt_noverbose, "quiet"},
22561+ {Opt_noverbose, "q"},
22562+ {Opt_noverbose, "silent"},
22563+
22564+ {Opt_sum, "sum"},
22565+ {Opt_nosum, "nosum"},
22566+ {Opt_wsum, "wsum"},
22567+
22568+ {Opt_rdcache, "rdcache=%d"},
22569+ {Opt_rdblk, "rdblk=%d"},
dece6358 22570+ {Opt_rdblk_def, "rdblk=def"},
1facf9fc 22571+ {Opt_rdhash, "rdhash=%d"},
dece6358 22572+ {Opt_rdhash_def, "rdhash=def"},
1facf9fc 22573+
22574+ {Opt_wbr_create, "create=%s"},
22575+ {Opt_wbr_create, "create_policy=%s"},
22576+ {Opt_wbr_copyup, "cpup=%s"},
22577+ {Opt_wbr_copyup, "copyup=%s"},
22578+ {Opt_wbr_copyup, "copyup_policy=%s"},
22579+
c1595e42
JR
22580+ /* generic VFS flag */
22581+#ifdef CONFIG_FS_POSIX_ACL
22582+ {Opt_acl, "acl"},
22583+ {Opt_noacl, "noacl"},
22584+#else
22585+ {Opt_ignore_silent, "acl"},
22586+ {Opt_ignore_silent, "noacl"},
22587+#endif
22588+
1facf9fc 22589+ /* internal use for the scripts */
22590+ {Opt_ignore_silent, "si=%s"},
22591+
22592+ {Opt_br, "dirs=%s"},
22593+ {Opt_ignore, "debug=%d"},
22594+ {Opt_ignore, "delete=whiteout"},
22595+ {Opt_ignore, "delete=all"},
22596+ {Opt_ignore, "imap=%s"},
22597+
1308ab2a 22598+ /* temporary workaround, due to old mount(8)? */
22599+ {Opt_ignore_silent, "relatime"},
22600+
1facf9fc 22601+ {Opt_err, NULL}
22602+};
22603+
22604+/* ---------------------------------------------------------------------- */
22605+
076b876e 22606+static const char *au_parser_pattern(int val, match_table_t tbl)
1facf9fc 22607+{
076b876e
AM
22608+ struct match_token *p;
22609+
22610+ p = tbl;
22611+ while (p->pattern) {
22612+ if (p->token == val)
22613+ return p->pattern;
22614+ p++;
1facf9fc 22615+ }
22616+ BUG();
22617+ return "??";
22618+}
22619+
076b876e
AM
22620+static const char *au_optstr(int *val, match_table_t tbl)
22621+{
22622+ struct match_token *p;
22623+ int v;
22624+
22625+ v = *val;
22626+ p = tbl;
22627+ while (p->token) {
22628+ if ((v & p->token) == p->token) {
22629+ *val &= ~p->token;
22630+ return p->pattern;
22631+ }
22632+ p++;
22633+ }
22634+ return NULL;
22635+}
22636+
1facf9fc 22637+/* ---------------------------------------------------------------------- */
22638+
1e00d052 22639+static match_table_t brperm = {
1facf9fc 22640+ {AuBrPerm_RO, AUFS_BRPERM_RO},
22641+ {AuBrPerm_RR, AUFS_BRPERM_RR},
22642+ {AuBrPerm_RW, AUFS_BRPERM_RW},
1e00d052
AM
22643+ {0, NULL}
22644+};
1facf9fc 22645+
86dc4139 22646+static match_table_t brattr = {
076b876e
AM
22647+ /* general */
22648+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG},
22649+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL},
c1595e42 22650+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */
86dc4139 22651+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN},
076b876e 22652+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM},
c1595e42
JR
22653+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX},
22654+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC},
22655+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS},
22656+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR},
22657+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR},
22658+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH},
076b876e
AM
22659+
22660+ /* ro/rr branch */
1e00d052 22661+ {AuBrRAttr_WH, AUFS_BRRATTR_WH},
076b876e
AM
22662+
22663+ /* rw branch */
22664+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO},
1e00d052 22665+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH},
076b876e 22666+
1e00d052 22667+ {0, NULL}
1facf9fc 22668+};
22669+
1e00d052
AM
22670+static int br_attr_val(char *str, match_table_t table, substring_t args[])
22671+{
22672+ int attr, v;
22673+ char *p;
22674+
22675+ attr = 0;
22676+ do {
22677+ p = strchr(str, '+');
22678+ if (p)
22679+ *p = 0;
22680+ v = match_token(str, table, args);
076b876e
AM
22681+ if (v) {
22682+ if (v & AuBrAttr_CMOO_Mask)
22683+ attr &= ~AuBrAttr_CMOO_Mask;
1e00d052 22684+ attr |= v;
076b876e 22685+ } else {
1e00d052
AM
22686+ if (p)
22687+ *p = '+';
0c3ec466 22688+ pr_warn("ignored branch attribute %s\n", str);
1e00d052
AM
22689+ break;
22690+ }
22691+ if (p)
22692+ str = p + 1;
22693+ } while (p);
22694+
22695+ return attr;
22696+}
22697+
076b876e
AM
22698+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm)
22699+{
22700+ int sz;
22701+ const char *p;
22702+ char *q;
22703+
076b876e
AM
22704+ q = str->a;
22705+ *q = 0;
22706+ p = au_optstr(&perm, brattr);
22707+ if (p) {
22708+ sz = strlen(p);
22709+ memcpy(q, p, sz + 1);
22710+ q += sz;
22711+ } else
22712+ goto out;
22713+
22714+ do {
22715+ p = au_optstr(&perm, brattr);
22716+ if (p) {
22717+ *q++ = '+';
22718+ sz = strlen(p);
22719+ memcpy(q, p, sz + 1);
22720+ q += sz;
22721+ }
22722+ } while (p);
22723+
22724+out:
c1595e42 22725+ return q - str->a;
076b876e
AM
22726+}
22727+
4a4d8108 22728+static int noinline_for_stack br_perm_val(char *perm)
1facf9fc 22729+{
076b876e
AM
22730+ int val, bad, sz;
22731+ char *p;
1facf9fc 22732+ substring_t args[MAX_OPT_ARGS];
076b876e 22733+ au_br_perm_str_t attr;
1facf9fc 22734+
1e00d052
AM
22735+ p = strchr(perm, '+');
22736+ if (p)
22737+ *p = 0;
22738+ val = match_token(perm, brperm, args);
22739+ if (!val) {
22740+ if (p)
22741+ *p = '+';
0c3ec466 22742+ pr_warn("ignored branch permission %s\n", perm);
1e00d052
AM
22743+ val = AuBrPerm_RO;
22744+ goto out;
22745+ }
22746+ if (!p)
22747+ goto out;
22748+
076b876e
AM
22749+ val |= br_attr_val(p + 1, brattr, args);
22750+
22751+ bad = 0;
86dc4139 22752+ switch (val & AuBrPerm_Mask) {
1e00d052
AM
22753+ case AuBrPerm_RO:
22754+ case AuBrPerm_RR:
076b876e
AM
22755+ bad = val & AuBrWAttr_Mask;
22756+ val &= ~AuBrWAttr_Mask;
1e00d052
AM
22757+ break;
22758+ case AuBrPerm_RW:
076b876e
AM
22759+ bad = val & AuBrRAttr_Mask;
22760+ val &= ~AuBrRAttr_Mask;
1e00d052
AM
22761+ break;
22762+ }
c1595e42
JR
22763+
22764+ /*
22765+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs
22766+ * does not treat it as an error, just warning.
22767+ * this is a tiny guard for the user operation.
22768+ */
22769+ if (val & AuBrAttr_UNPIN) {
22770+ bad |= AuBrAttr_UNPIN;
22771+ val &= ~AuBrAttr_UNPIN;
22772+ }
22773+
076b876e
AM
22774+ if (unlikely(bad)) {
22775+ sz = au_do_optstr_br_attr(&attr, bad);
22776+ AuDebugOn(!sz);
22777+ pr_warn("ignored branch attribute %s\n", attr.a);
22778+ }
1e00d052
AM
22779+
22780+out:
1facf9fc 22781+ return val;
22782+}
22783+
076b876e 22784+void au_optstr_br_perm(au_br_perm_str_t *str, int perm)
1facf9fc 22785+{
076b876e
AM
22786+ au_br_perm_str_t attr;
22787+ const char *p;
22788+ char *q;
1e00d052
AM
22789+ int sz;
22790+
076b876e
AM
22791+ q = str->a;
22792+ p = au_optstr(&perm, brperm);
22793+ AuDebugOn(!p || !*p);
22794+ sz = strlen(p);
22795+ memcpy(q, p, sz + 1);
22796+ q += sz;
1e00d052 22797+
076b876e
AM
22798+ sz = au_do_optstr_br_attr(&attr, perm);
22799+ if (sz) {
22800+ *q++ = '+';
22801+ memcpy(q, attr.a, sz + 1);
1e00d052
AM
22802+ }
22803+
076b876e 22804+ AuDebugOn(strlen(str->a) >= sizeof(str->a));
1facf9fc 22805+}
22806+
22807+/* ---------------------------------------------------------------------- */
22808+
22809+static match_table_t udbalevel = {
22810+ {AuOpt_UDBA_REVAL, "reval"},
22811+ {AuOpt_UDBA_NONE, "none"},
4a4d8108
AM
22812+#ifdef CONFIG_AUFS_HNOTIFY
22813+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */
22814+#ifdef CONFIG_AUFS_HFSNOTIFY
22815+ {AuOpt_UDBA_HNOTIFY, "fsnotify"},
4a4d8108 22816+#endif
1facf9fc 22817+#endif
22818+ {-1, NULL}
22819+};
22820+
4a4d8108 22821+static int noinline_for_stack udba_val(char *str)
1facf9fc 22822+{
22823+ substring_t args[MAX_OPT_ARGS];
22824+
7f207e10 22825+ return match_token(str, udbalevel, args);
1facf9fc 22826+}
22827+
22828+const char *au_optstr_udba(int udba)
22829+{
076b876e 22830+ return au_parser_pattern(udba, udbalevel);
1facf9fc 22831+}
22832+
22833+/* ---------------------------------------------------------------------- */
22834+
22835+static match_table_t au_wbr_create_policy = {
22836+ {AuWbrCreate_TDP, "tdp"},
22837+ {AuWbrCreate_TDP, "top-down-parent"},
22838+ {AuWbrCreate_RR, "rr"},
22839+ {AuWbrCreate_RR, "round-robin"},
22840+ {AuWbrCreate_MFS, "mfs"},
22841+ {AuWbrCreate_MFS, "most-free-space"},
22842+ {AuWbrCreate_MFSV, "mfs:%d"},
22843+ {AuWbrCreate_MFSV, "most-free-space:%d"},
22844+
22845+ {AuWbrCreate_MFSRR, "mfsrr:%d"},
22846+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"},
22847+ {AuWbrCreate_PMFS, "pmfs"},
22848+ {AuWbrCreate_PMFSV, "pmfs:%d"},
392086de
AM
22849+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"},
22850+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"},
1facf9fc 22851+
22852+ {-1, NULL}
22853+};
22854+
dece6358
AM
22855+/*
22856+ * cf. linux/lib/parser.c and cmdline.c
22857+ * gave up calling memparse() since it uses simple_strtoull() instead of
9dbd164d 22858+ * kstrto...().
dece6358 22859+ */
4a4d8108
AM
22860+static int noinline_for_stack
22861+au_match_ull(substring_t *s, unsigned long long *result)
1facf9fc 22862+{
22863+ int err;
22864+ unsigned int len;
22865+ char a[32];
22866+
22867+ err = -ERANGE;
22868+ len = s->to - s->from;
22869+ if (len + 1 <= sizeof(a)) {
22870+ memcpy(a, s->from, len);
22871+ a[len] = '\0';
9dbd164d 22872+ err = kstrtoull(a, 0, result);
1facf9fc 22873+ }
22874+ return err;
22875+}
22876+
22877+static int au_wbr_mfs_wmark(substring_t *arg, char *str,
22878+ struct au_opt_wbr_create *create)
22879+{
22880+ int err;
22881+ unsigned long long ull;
22882+
22883+ err = 0;
22884+ if (!au_match_ull(arg, &ull))
22885+ create->mfsrr_watermark = ull;
22886+ else {
4a4d8108 22887+ pr_err("bad integer in %s\n", str);
1facf9fc 22888+ err = -EINVAL;
22889+ }
22890+
22891+ return err;
22892+}
22893+
22894+static int au_wbr_mfs_sec(substring_t *arg, char *str,
22895+ struct au_opt_wbr_create *create)
22896+{
22897+ int n, err;
22898+
22899+ err = 0;
027c5e7a 22900+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC)
1facf9fc 22901+ create->mfs_second = n;
22902+ else {
4a4d8108 22903+ pr_err("bad integer in %s\n", str);
1facf9fc 22904+ err = -EINVAL;
22905+ }
22906+
22907+ return err;
22908+}
22909+
4a4d8108
AM
22910+static int noinline_for_stack
22911+au_wbr_create_val(char *str, struct au_opt_wbr_create *create)
1facf9fc 22912+{
22913+ int err, e;
22914+ substring_t args[MAX_OPT_ARGS];
22915+
22916+ err = match_token(str, au_wbr_create_policy, args);
22917+ create->wbr_create = err;
22918+ switch (err) {
22919+ case AuWbrCreate_MFSRRV:
392086de 22920+ case AuWbrCreate_PMFSRRV:
1facf9fc 22921+ e = au_wbr_mfs_wmark(&args[0], str, create);
22922+ if (!e)
22923+ e = au_wbr_mfs_sec(&args[1], str, create);
22924+ if (unlikely(e))
22925+ err = e;
22926+ break;
22927+ case AuWbrCreate_MFSRR:
392086de 22928+ case AuWbrCreate_PMFSRR:
1facf9fc 22929+ e = au_wbr_mfs_wmark(&args[0], str, create);
22930+ if (unlikely(e)) {
22931+ err = e;
22932+ break;
22933+ }
22934+ /*FALLTHROUGH*/
22935+ case AuWbrCreate_MFS:
22936+ case AuWbrCreate_PMFS:
027c5e7a 22937+ create->mfs_second = AUFS_MFS_DEF_SEC;
1facf9fc 22938+ break;
22939+ case AuWbrCreate_MFSV:
22940+ case AuWbrCreate_PMFSV:
22941+ e = au_wbr_mfs_sec(&args[0], str, create);
22942+ if (unlikely(e))
22943+ err = e;
22944+ break;
22945+ }
22946+
22947+ return err;
22948+}
22949+
22950+const char *au_optstr_wbr_create(int wbr_create)
22951+{
076b876e 22952+ return au_parser_pattern(wbr_create, au_wbr_create_policy);
1facf9fc 22953+}
22954+
22955+static match_table_t au_wbr_copyup_policy = {
22956+ {AuWbrCopyup_TDP, "tdp"},
22957+ {AuWbrCopyup_TDP, "top-down-parent"},
22958+ {AuWbrCopyup_BUP, "bup"},
22959+ {AuWbrCopyup_BUP, "bottom-up-parent"},
22960+ {AuWbrCopyup_BU, "bu"},
22961+ {AuWbrCopyup_BU, "bottom-up"},
22962+ {-1, NULL}
22963+};
22964+
4a4d8108 22965+static int noinline_for_stack au_wbr_copyup_val(char *str)
1facf9fc 22966+{
22967+ substring_t args[MAX_OPT_ARGS];
22968+
22969+ return match_token(str, au_wbr_copyup_policy, args);
22970+}
22971+
22972+const char *au_optstr_wbr_copyup(int wbr_copyup)
22973+{
076b876e 22974+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy);
1facf9fc 22975+}
22976+
22977+/* ---------------------------------------------------------------------- */
22978+
22979+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
22980+
22981+static void dump_opts(struct au_opts *opts)
22982+{
22983+#ifdef CONFIG_AUFS_DEBUG
22984+ /* reduce stack space */
22985+ union {
22986+ struct au_opt_add *add;
22987+ struct au_opt_del *del;
22988+ struct au_opt_mod *mod;
22989+ struct au_opt_xino *xino;
22990+ struct au_opt_xino_itrunc *xino_itrunc;
22991+ struct au_opt_wbr_create *create;
22992+ } u;
22993+ struct au_opt *opt;
22994+
22995+ opt = opts->opt;
22996+ while (opt->type != Opt_tail) {
22997+ switch (opt->type) {
22998+ case Opt_add:
22999+ u.add = &opt->add;
23000+ AuDbg("add {b%d, %s, 0x%x, %p}\n",
23001+ u.add->bindex, u.add->pathname, u.add->perm,
23002+ u.add->path.dentry);
23003+ break;
23004+ case Opt_del:
23005+ case Opt_idel:
23006+ u.del = &opt->del;
23007+ AuDbg("del {%s, %p}\n",
23008+ u.del->pathname, u.del->h_path.dentry);
23009+ break;
23010+ case Opt_mod:
23011+ case Opt_imod:
23012+ u.mod = &opt->mod;
23013+ AuDbg("mod {%s, 0x%x, %p}\n",
23014+ u.mod->path, u.mod->perm, u.mod->h_root);
23015+ break;
23016+ case Opt_append:
23017+ u.add = &opt->add;
23018+ AuDbg("append {b%d, %s, 0x%x, %p}\n",
23019+ u.add->bindex, u.add->pathname, u.add->perm,
23020+ u.add->path.dentry);
23021+ break;
23022+ case Opt_prepend:
23023+ u.add = &opt->add;
23024+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n",
23025+ u.add->bindex, u.add->pathname, u.add->perm,
23026+ u.add->path.dentry);
23027+ break;
23028+ case Opt_dirwh:
23029+ AuDbg("dirwh %d\n", opt->dirwh);
23030+ break;
23031+ case Opt_rdcache:
23032+ AuDbg("rdcache %d\n", opt->rdcache);
23033+ break;
23034+ case Opt_rdblk:
23035+ AuDbg("rdblk %u\n", opt->rdblk);
23036+ break;
dece6358
AM
23037+ case Opt_rdblk_def:
23038+ AuDbg("rdblk_def\n");
23039+ break;
1facf9fc 23040+ case Opt_rdhash:
23041+ AuDbg("rdhash %u\n", opt->rdhash);
23042+ break;
dece6358
AM
23043+ case Opt_rdhash_def:
23044+ AuDbg("rdhash_def\n");
23045+ break;
1facf9fc 23046+ case Opt_xino:
23047+ u.xino = &opt->xino;
523b37e3 23048+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file);
1facf9fc 23049+ break;
23050+ case Opt_trunc_xino:
23051+ AuLabel(trunc_xino);
23052+ break;
23053+ case Opt_notrunc_xino:
23054+ AuLabel(notrunc_xino);
23055+ break;
23056+ case Opt_trunc_xino_path:
23057+ case Opt_itrunc_xino:
23058+ u.xino_itrunc = &opt->xino_itrunc;
23059+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex);
23060+ break;
23061+
23062+ case Opt_noxino:
23063+ AuLabel(noxino);
23064+ break;
23065+ case Opt_trunc_xib:
23066+ AuLabel(trunc_xib);
23067+ break;
23068+ case Opt_notrunc_xib:
23069+ AuLabel(notrunc_xib);
23070+ break;
dece6358
AM
23071+ case Opt_shwh:
23072+ AuLabel(shwh);
23073+ break;
23074+ case Opt_noshwh:
23075+ AuLabel(noshwh);
23076+ break;
076b876e
AM
23077+ case Opt_dirperm1:
23078+ AuLabel(dirperm1);
23079+ break;
23080+ case Opt_nodirperm1:
23081+ AuLabel(nodirperm1);
23082+ break;
1facf9fc 23083+ case Opt_plink:
23084+ AuLabel(plink);
23085+ break;
23086+ case Opt_noplink:
23087+ AuLabel(noplink);
23088+ break;
23089+ case Opt_list_plink:
23090+ AuLabel(list_plink);
23091+ break;
23092+ case Opt_udba:
23093+ AuDbg("udba %d, %s\n",
23094+ opt->udba, au_optstr_udba(opt->udba));
23095+ break;
4a4d8108
AM
23096+ case Opt_dio:
23097+ AuLabel(dio);
23098+ break;
23099+ case Opt_nodio:
23100+ AuLabel(nodio);
23101+ break;
1facf9fc 23102+ case Opt_diropq_a:
23103+ AuLabel(diropq_a);
23104+ break;
23105+ case Opt_diropq_w:
23106+ AuLabel(diropq_w);
23107+ break;
23108+ case Opt_warn_perm:
23109+ AuLabel(warn_perm);
23110+ break;
23111+ case Opt_nowarn_perm:
23112+ AuLabel(nowarn_perm);
23113+ break;
23114+ case Opt_refrof:
23115+ AuLabel(refrof);
23116+ break;
23117+ case Opt_norefrof:
23118+ AuLabel(norefrof);
23119+ break;
23120+ case Opt_verbose:
23121+ AuLabel(verbose);
23122+ break;
23123+ case Opt_noverbose:
23124+ AuLabel(noverbose);
23125+ break;
23126+ case Opt_sum:
23127+ AuLabel(sum);
23128+ break;
23129+ case Opt_nosum:
23130+ AuLabel(nosum);
23131+ break;
23132+ case Opt_wsum:
23133+ AuLabel(wsum);
23134+ break;
23135+ case Opt_wbr_create:
23136+ u.create = &opt->wbr_create;
23137+ AuDbg("create %d, %s\n", u.create->wbr_create,
23138+ au_optstr_wbr_create(u.create->wbr_create));
23139+ switch (u.create->wbr_create) {
23140+ case AuWbrCreate_MFSV:
23141+ case AuWbrCreate_PMFSV:
23142+ AuDbg("%d sec\n", u.create->mfs_second);
23143+ break;
23144+ case AuWbrCreate_MFSRR:
23145+ AuDbg("%llu watermark\n",
23146+ u.create->mfsrr_watermark);
23147+ break;
23148+ case AuWbrCreate_MFSRRV:
392086de 23149+ case AuWbrCreate_PMFSRRV:
1facf9fc 23150+ AuDbg("%llu watermark, %d sec\n",
23151+ u.create->mfsrr_watermark,
23152+ u.create->mfs_second);
23153+ break;
23154+ }
23155+ break;
23156+ case Opt_wbr_copyup:
23157+ AuDbg("copyup %d, %s\n", opt->wbr_copyup,
23158+ au_optstr_wbr_copyup(opt->wbr_copyup));
23159+ break;
076b876e
AM
23160+ case Opt_fhsm_sec:
23161+ AuDbg("fhsm_sec %u\n", opt->fhsm_second);
23162+ break;
c1595e42
JR
23163+ case Opt_acl:
23164+ AuLabel(acl);
23165+ break;
23166+ case Opt_noacl:
23167+ AuLabel(noacl);
23168+ break;
1facf9fc 23169+ default:
23170+ BUG();
23171+ }
23172+ opt++;
23173+ }
23174+#endif
23175+}
23176+
23177+void au_opts_free(struct au_opts *opts)
23178+{
23179+ struct au_opt *opt;
23180+
23181+ opt = opts->opt;
23182+ while (opt->type != Opt_tail) {
23183+ switch (opt->type) {
23184+ case Opt_add:
23185+ case Opt_append:
23186+ case Opt_prepend:
23187+ path_put(&opt->add.path);
23188+ break;
23189+ case Opt_del:
23190+ case Opt_idel:
23191+ path_put(&opt->del.h_path);
23192+ break;
23193+ case Opt_mod:
23194+ case Opt_imod:
23195+ dput(opt->mod.h_root);
23196+ break;
23197+ case Opt_xino:
23198+ fput(opt->xino.file);
23199+ break;
23200+ }
23201+ opt++;
23202+ }
23203+}
23204+
23205+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
23206+ aufs_bindex_t bindex)
23207+{
23208+ int err;
23209+ struct au_opt_add *add = &opt->add;
23210+ char *p;
23211+
23212+ add->bindex = bindex;
1e00d052 23213+ add->perm = AuBrPerm_RO;
1facf9fc 23214+ add->pathname = opt_str;
23215+ p = strchr(opt_str, '=');
23216+ if (p) {
23217+ *p++ = 0;
23218+ if (*p)
23219+ add->perm = br_perm_val(p);
23220+ }
23221+
23222+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
23223+ if (!err) {
23224+ if (!p) {
23225+ add->perm = AuBrPerm_RO;
23226+ if (au_test_fs_rr(add->path.dentry->d_sb))
23227+ add->perm = AuBrPerm_RR;
23228+ else if (!bindex && !(sb_flags & MS_RDONLY))
23229+ add->perm = AuBrPerm_RW;
23230+ }
23231+ opt->type = Opt_add;
23232+ goto out;
23233+ }
4a4d8108 23234+ pr_err("lookup failed %s (%d)\n", add->pathname, err);
1facf9fc 23235+ err = -EINVAL;
23236+
4f0767ce 23237+out:
1facf9fc 23238+ return err;
23239+}
23240+
23241+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
23242+{
23243+ int err;
23244+
23245+ del->pathname = args[0].from;
23246+ AuDbg("del path %s\n", del->pathname);
23247+
23248+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
23249+ if (unlikely(err))
4a4d8108 23250+ pr_err("lookup failed %s (%d)\n", del->pathname, err);
1facf9fc 23251+
23252+ return err;
23253+}
23254+
23255+#if 0 /* reserved for future use */
23256+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex,
23257+ struct au_opt_del *del, substring_t args[])
23258+{
23259+ int err;
23260+ struct dentry *root;
23261+
23262+ err = -EINVAL;
23263+ root = sb->s_root;
23264+ aufs_read_lock(root, AuLock_FLUSH);
23265+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 23266+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 23267+ goto out;
23268+ }
23269+
23270+ err = 0;
23271+ del->h_path.dentry = dget(au_h_dptr(root, bindex));
23272+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex));
23273+
4f0767ce 23274+out:
1facf9fc 23275+ aufs_read_unlock(root, !AuLock_IR);
23276+ return err;
23277+}
23278+#endif
23279+
4a4d8108
AM
23280+static int noinline_for_stack
23281+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
1facf9fc 23282+{
23283+ int err;
23284+ struct path path;
23285+ char *p;
23286+
23287+ err = -EINVAL;
23288+ mod->path = args[0].from;
23289+ p = strchr(mod->path, '=');
23290+ if (unlikely(!p)) {
4a4d8108 23291+ pr_err("no permssion %s\n", args[0].from);
1facf9fc 23292+ goto out;
23293+ }
23294+
23295+ *p++ = 0;
23296+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
23297+ if (unlikely(err)) {
4a4d8108 23298+ pr_err("lookup failed %s (%d)\n", mod->path, err);
1facf9fc 23299+ goto out;
23300+ }
23301+
23302+ mod->perm = br_perm_val(p);
23303+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
23304+ mod->h_root = dget(path.dentry);
23305+ path_put(&path);
23306+
4f0767ce 23307+out:
1facf9fc 23308+ return err;
23309+}
23310+
23311+#if 0 /* reserved for future use */
23312+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex,
23313+ struct au_opt_mod *mod, substring_t args[])
23314+{
23315+ int err;
23316+ struct dentry *root;
23317+
23318+ err = -EINVAL;
23319+ root = sb->s_root;
23320+ aufs_read_lock(root, AuLock_FLUSH);
23321+ if (bindex < 0 || au_sbend(sb) < bindex) {
4a4d8108 23322+ pr_err("out of bounds, %d\n", bindex);
1facf9fc 23323+ goto out;
23324+ }
23325+
23326+ err = 0;
23327+ mod->perm = br_perm_val(args[1].from);
23328+ AuDbg("mod path %s, perm 0x%x, %s\n",
23329+ mod->path, mod->perm, args[1].from);
23330+ mod->h_root = dget(au_h_dptr(root, bindex));
23331+
4f0767ce 23332+out:
1facf9fc 23333+ aufs_read_unlock(root, !AuLock_IR);
23334+ return err;
23335+}
23336+#endif
23337+
23338+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino,
23339+ substring_t args[])
23340+{
23341+ int err;
23342+ struct file *file;
23343+
23344+ file = au_xino_create(sb, args[0].from, /*silent*/0);
23345+ err = PTR_ERR(file);
23346+ if (IS_ERR(file))
23347+ goto out;
23348+
23349+ err = -EINVAL;
23350+ if (unlikely(file->f_dentry->d_sb == sb)) {
23351+ fput(file);
4a4d8108 23352+ pr_err("%s must be outside\n", args[0].from);
1facf9fc 23353+ goto out;
23354+ }
23355+
23356+ err = 0;
23357+ xino->file = file;
23358+ xino->path = args[0].from;
23359+
4f0767ce 23360+out:
1facf9fc 23361+ return err;
23362+}
23363+
4a4d8108
AM
23364+static int noinline_for_stack
23365+au_opts_parse_xino_itrunc_path(struct super_block *sb,
23366+ struct au_opt_xino_itrunc *xino_itrunc,
23367+ substring_t args[])
1facf9fc 23368+{
23369+ int err;
23370+ aufs_bindex_t bend, bindex;
23371+ struct path path;
23372+ struct dentry *root;
23373+
23374+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
23375+ if (unlikely(err)) {
4a4d8108 23376+ pr_err("lookup failed %s (%d)\n", args[0].from, err);
1facf9fc 23377+ goto out;
23378+ }
23379+
23380+ xino_itrunc->bindex = -1;
23381+ root = sb->s_root;
23382+ aufs_read_lock(root, AuLock_FLUSH);
23383+ bend = au_sbend(sb);
23384+ for (bindex = 0; bindex <= bend; bindex++) {
23385+ if (au_h_dptr(root, bindex) == path.dentry) {
23386+ xino_itrunc->bindex = bindex;
23387+ break;
23388+ }
23389+ }
23390+ aufs_read_unlock(root, !AuLock_IR);
23391+ path_put(&path);
23392+
23393+ if (unlikely(xino_itrunc->bindex < 0)) {
4a4d8108 23394+ pr_err("no such branch %s\n", args[0].from);
1facf9fc 23395+ err = -EINVAL;
23396+ }
23397+
4f0767ce 23398+out:
1facf9fc 23399+ return err;
23400+}
23401+
23402+/* called without aufs lock */
23403+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
23404+{
23405+ int err, n, token;
23406+ aufs_bindex_t bindex;
23407+ unsigned char skipped;
23408+ struct dentry *root;
23409+ struct au_opt *opt, *opt_tail;
23410+ char *opt_str;
23411+ /* reduce the stack space */
23412+ union {
23413+ struct au_opt_xino_itrunc *xino_itrunc;
23414+ struct au_opt_wbr_create *create;
23415+ } u;
23416+ struct {
23417+ substring_t args[MAX_OPT_ARGS];
23418+ } *a;
23419+
23420+ err = -ENOMEM;
23421+ a = kmalloc(sizeof(*a), GFP_NOFS);
23422+ if (unlikely(!a))
23423+ goto out;
23424+
23425+ root = sb->s_root;
23426+ err = 0;
23427+ bindex = 0;
23428+ opt = opts->opt;
23429+ opt_tail = opt + opts->max_opt - 1;
23430+ opt->type = Opt_tail;
23431+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) {
23432+ err = -EINVAL;
23433+ skipped = 0;
23434+ token = match_token(opt_str, options, a->args);
23435+ switch (token) {
23436+ case Opt_br:
23437+ err = 0;
23438+ while (!err && (opt_str = strsep(&a->args[0].from, ":"))
23439+ && *opt_str) {
23440+ err = opt_add(opt, opt_str, opts->sb_flags,
23441+ bindex++);
23442+ if (unlikely(!err && ++opt > opt_tail)) {
23443+ err = -E2BIG;
23444+ break;
23445+ }
23446+ opt->type = Opt_tail;
23447+ skipped = 1;
23448+ }
23449+ break;
23450+ case Opt_add:
23451+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23452+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23453+ break;
23454+ }
23455+ bindex = n;
23456+ err = opt_add(opt, a->args[1].from, opts->sb_flags,
23457+ bindex);
23458+ if (!err)
23459+ opt->type = token;
23460+ break;
23461+ case Opt_append:
23462+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
23463+ /*dummy bindex*/1);
23464+ if (!err)
23465+ opt->type = token;
23466+ break;
23467+ case Opt_prepend:
23468+ err = opt_add(opt, a->args[0].from, opts->sb_flags,
23469+ /*bindex*/0);
23470+ if (!err)
23471+ opt->type = token;
23472+ break;
23473+ case Opt_del:
23474+ err = au_opts_parse_del(&opt->del, a->args);
23475+ if (!err)
23476+ opt->type = token;
23477+ break;
23478+#if 0 /* reserved for future use */
23479+ case Opt_idel:
23480+ del->pathname = "(indexed)";
23481+ if (unlikely(match_int(&args[0], &n))) {
4a4d8108 23482+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23483+ break;
23484+ }
23485+ err = au_opts_parse_idel(sb, n, &opt->del, a->args);
23486+ if (!err)
23487+ opt->type = token;
23488+ break;
23489+#endif
23490+ case Opt_mod:
23491+ err = au_opts_parse_mod(&opt->mod, a->args);
23492+ if (!err)
23493+ opt->type = token;
23494+ break;
23495+#ifdef IMOD /* reserved for future use */
23496+ case Opt_imod:
23497+ u.mod->path = "(indexed)";
23498+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23499+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23500+ break;
23501+ }
23502+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args);
23503+ if (!err)
23504+ opt->type = token;
23505+ break;
23506+#endif
23507+ case Opt_xino:
23508+ err = au_opts_parse_xino(sb, &opt->xino, a->args);
23509+ if (!err)
23510+ opt->type = token;
23511+ break;
23512+
23513+ case Opt_trunc_xino_path:
23514+ err = au_opts_parse_xino_itrunc_path
23515+ (sb, &opt->xino_itrunc, a->args);
23516+ if (!err)
23517+ opt->type = token;
23518+ break;
23519+
23520+ case Opt_itrunc_xino:
23521+ u.xino_itrunc = &opt->xino_itrunc;
23522+ if (unlikely(match_int(&a->args[0], &n))) {
4a4d8108 23523+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23524+ break;
23525+ }
23526+ u.xino_itrunc->bindex = n;
23527+ aufs_read_lock(root, AuLock_FLUSH);
23528+ if (n < 0 || au_sbend(sb) < n) {
4a4d8108 23529+ pr_err("out of bounds, %d\n", n);
1facf9fc 23530+ aufs_read_unlock(root, !AuLock_IR);
23531+ break;
23532+ }
23533+ aufs_read_unlock(root, !AuLock_IR);
23534+ err = 0;
23535+ opt->type = token;
23536+ break;
23537+
23538+ case Opt_dirwh:
23539+ if (unlikely(match_int(&a->args[0], &opt->dirwh)))
23540+ break;
23541+ err = 0;
23542+ opt->type = token;
23543+ break;
23544+
23545+ case Opt_rdcache:
027c5e7a
AM
23546+ if (unlikely(match_int(&a->args[0], &n))) {
23547+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23548+ break;
027c5e7a
AM
23549+ }
23550+ if (unlikely(n > AUFS_RDCACHE_MAX)) {
23551+ pr_err("rdcache must be smaller than %d\n",
23552+ AUFS_RDCACHE_MAX);
23553+ break;
23554+ }
23555+ opt->rdcache = n;
1facf9fc 23556+ err = 0;
23557+ opt->type = token;
23558+ break;
23559+ case Opt_rdblk:
23560+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23561+ || n < 0
1facf9fc 23562+ || n > KMALLOC_MAX_SIZE)) {
4a4d8108 23563+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23564+ break;
23565+ }
1308ab2a 23566+ if (unlikely(n && n < NAME_MAX)) {
4a4d8108
AM
23567+ pr_err("rdblk must be larger than %d\n",
23568+ NAME_MAX);
1facf9fc 23569+ break;
23570+ }
23571+ opt->rdblk = n;
23572+ err = 0;
23573+ opt->type = token;
23574+ break;
23575+ case Opt_rdhash:
23576+ if (unlikely(match_int(&a->args[0], &n)
1308ab2a 23577+ || n < 0
1facf9fc 23578+ || n * sizeof(struct hlist_head)
23579+ > KMALLOC_MAX_SIZE)) {
4a4d8108 23580+ pr_err("bad integer in %s\n", opt_str);
1facf9fc 23581+ break;
23582+ }
23583+ opt->rdhash = n;
23584+ err = 0;
23585+ opt->type = token;
23586+ break;
23587+
23588+ case Opt_trunc_xino:
23589+ case Opt_notrunc_xino:
23590+ case Opt_noxino:
23591+ case Opt_trunc_xib:
23592+ case Opt_notrunc_xib:
dece6358
AM
23593+ case Opt_shwh:
23594+ case Opt_noshwh:
076b876e
AM
23595+ case Opt_dirperm1:
23596+ case Opt_nodirperm1:
1facf9fc 23597+ case Opt_plink:
23598+ case Opt_noplink:
23599+ case Opt_list_plink:
4a4d8108
AM
23600+ case Opt_dio:
23601+ case Opt_nodio:
1facf9fc 23602+ case Opt_diropq_a:
23603+ case Opt_diropq_w:
23604+ case Opt_warn_perm:
23605+ case Opt_nowarn_perm:
23606+ case Opt_refrof:
23607+ case Opt_norefrof:
23608+ case Opt_verbose:
23609+ case Opt_noverbose:
23610+ case Opt_sum:
23611+ case Opt_nosum:
23612+ case Opt_wsum:
dece6358
AM
23613+ case Opt_rdblk_def:
23614+ case Opt_rdhash_def:
c1595e42
JR
23615+ case Opt_acl:
23616+ case Opt_noacl:
1facf9fc 23617+ err = 0;
23618+ opt->type = token;
23619+ break;
23620+
23621+ case Opt_udba:
23622+ opt->udba = udba_val(a->args[0].from);
23623+ if (opt->udba >= 0) {
23624+ err = 0;
23625+ opt->type = token;
23626+ } else
4a4d8108 23627+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23628+ break;
23629+
23630+ case Opt_wbr_create:
23631+ u.create = &opt->wbr_create;
23632+ u.create->wbr_create
23633+ = au_wbr_create_val(a->args[0].from, u.create);
23634+ if (u.create->wbr_create >= 0) {
23635+ err = 0;
23636+ opt->type = token;
23637+ } else
4a4d8108 23638+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23639+ break;
23640+ case Opt_wbr_copyup:
23641+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from);
23642+ if (opt->wbr_copyup >= 0) {
23643+ err = 0;
23644+ opt->type = token;
23645+ } else
4a4d8108 23646+ pr_err("wrong value, %s\n", opt_str);
1facf9fc 23647+ break;
23648+
076b876e
AM
23649+ case Opt_fhsm_sec:
23650+ if (unlikely(match_int(&a->args[0], &n)
23651+ || n < 0)) {
23652+ pr_err("bad integer in %s\n", opt_str);
23653+ break;
23654+ }
23655+ if (sysaufs_brs) {
23656+ opt->fhsm_second = n;
23657+ opt->type = token;
23658+ } else
23659+ pr_warn("ignored %s\n", opt_str);
23660+ err = 0;
23661+ break;
23662+
1facf9fc 23663+ case Opt_ignore:
0c3ec466 23664+ pr_warn("ignored %s\n", opt_str);
1facf9fc 23665+ /*FALLTHROUGH*/
23666+ case Opt_ignore_silent:
23667+ skipped = 1;
23668+ err = 0;
23669+ break;
23670+ case Opt_err:
4a4d8108 23671+ pr_err("unknown option %s\n", opt_str);
1facf9fc 23672+ break;
23673+ }
23674+
23675+ if (!err && !skipped) {
23676+ if (unlikely(++opt > opt_tail)) {
23677+ err = -E2BIG;
23678+ opt--;
23679+ opt->type = Opt_tail;
23680+ break;
23681+ }
23682+ opt->type = Opt_tail;
23683+ }
23684+ }
23685+
23686+ kfree(a);
23687+ dump_opts(opts);
23688+ if (unlikely(err))
23689+ au_opts_free(opts);
23690+
4f0767ce 23691+out:
1facf9fc 23692+ return err;
23693+}
23694+
23695+static int au_opt_wbr_create(struct super_block *sb,
23696+ struct au_opt_wbr_create *create)
23697+{
23698+ int err;
23699+ struct au_sbinfo *sbinfo;
23700+
dece6358
AM
23701+ SiMustWriteLock(sb);
23702+
1facf9fc 23703+ err = 1; /* handled */
23704+ sbinfo = au_sbi(sb);
23705+ if (sbinfo->si_wbr_create_ops->fin) {
23706+ err = sbinfo->si_wbr_create_ops->fin(sb);
23707+ if (!err)
23708+ err = 1;
23709+ }
23710+
23711+ sbinfo->si_wbr_create = create->wbr_create;
23712+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create;
23713+ switch (create->wbr_create) {
23714+ case AuWbrCreate_MFSRRV:
23715+ case AuWbrCreate_MFSRR:
392086de
AM
23716+ case AuWbrCreate_PMFSRR:
23717+ case AuWbrCreate_PMFSRRV:
1facf9fc 23718+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark;
23719+ /*FALLTHROUGH*/
23720+ case AuWbrCreate_MFS:
23721+ case AuWbrCreate_MFSV:
23722+ case AuWbrCreate_PMFS:
23723+ case AuWbrCreate_PMFSV:
e49829fe
JR
23724+ sbinfo->si_wbr_mfs.mfs_expire
23725+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC);
1facf9fc 23726+ break;
23727+ }
23728+
23729+ if (sbinfo->si_wbr_create_ops->init)
23730+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */
23731+
23732+ return err;
23733+}
23734+
23735+/*
23736+ * returns,
23737+ * plus: processed without an error
23738+ * zero: unprocessed
23739+ */
23740+static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
23741+ struct au_opts *opts)
23742+{
23743+ int err;
23744+ struct au_sbinfo *sbinfo;
23745+
dece6358
AM
23746+ SiMustWriteLock(sb);
23747+
1facf9fc 23748+ err = 1; /* handled */
23749+ sbinfo = au_sbi(sb);
23750+ switch (opt->type) {
23751+ case Opt_udba:
23752+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
23753+ sbinfo->si_mntflags |= opt->udba;
23754+ opts->given_udba |= opt->udba;
23755+ break;
23756+
23757+ case Opt_plink:
23758+ au_opt_set(sbinfo->si_mntflags, PLINK);
23759+ break;
23760+ case Opt_noplink:
23761+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
e49829fe 23762+ au_plink_put(sb, /*verbose*/1);
1facf9fc 23763+ au_opt_clr(sbinfo->si_mntflags, PLINK);
23764+ break;
23765+ case Opt_list_plink:
23766+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
23767+ au_plink_list(sb);
23768+ break;
23769+
4a4d8108
AM
23770+ case Opt_dio:
23771+ au_opt_set(sbinfo->si_mntflags, DIO);
23772+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23773+ break;
23774+ case Opt_nodio:
23775+ au_opt_clr(sbinfo->si_mntflags, DIO);
23776+ au_fset_opts(opts->flags, REFRESH_DYAOP);
23777+ break;
23778+
076b876e
AM
23779+ case Opt_fhsm_sec:
23780+ au_fhsm_set(sbinfo, opt->fhsm_second);
23781+ break;
23782+
1facf9fc 23783+ case Opt_diropq_a:
23784+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
23785+ break;
23786+ case Opt_diropq_w:
23787+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
23788+ break;
23789+
23790+ case Opt_warn_perm:
23791+ au_opt_set(sbinfo->si_mntflags, WARN_PERM);
23792+ break;
23793+ case Opt_nowarn_perm:
23794+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
23795+ break;
23796+
23797+ case Opt_refrof:
23798+ au_opt_set(sbinfo->si_mntflags, REFROF);
23799+ break;
23800+ case Opt_norefrof:
23801+ au_opt_clr(sbinfo->si_mntflags, REFROF);
23802+ break;
23803+
23804+ case Opt_verbose:
23805+ au_opt_set(sbinfo->si_mntflags, VERBOSE);
23806+ break;
23807+ case Opt_noverbose:
23808+ au_opt_clr(sbinfo->si_mntflags, VERBOSE);
23809+ break;
23810+
23811+ case Opt_sum:
23812+ au_opt_set(sbinfo->si_mntflags, SUM);
23813+ break;
23814+ case Opt_wsum:
23815+ au_opt_clr(sbinfo->si_mntflags, SUM);
23816+ au_opt_set(sbinfo->si_mntflags, SUM_W);
23817+ case Opt_nosum:
23818+ au_opt_clr(sbinfo->si_mntflags, SUM);
23819+ au_opt_clr(sbinfo->si_mntflags, SUM_W);
23820+ break;
23821+
23822+ case Opt_wbr_create:
23823+ err = au_opt_wbr_create(sb, &opt->wbr_create);
23824+ break;
23825+ case Opt_wbr_copyup:
23826+ sbinfo->si_wbr_copyup = opt->wbr_copyup;
23827+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
23828+ break;
23829+
23830+ case Opt_dirwh:
23831+ sbinfo->si_dirwh = opt->dirwh;
23832+ break;
23833+
23834+ case Opt_rdcache:
e49829fe
JR
23835+ sbinfo->si_rdcache
23836+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
1facf9fc 23837+ break;
23838+ case Opt_rdblk:
23839+ sbinfo->si_rdblk = opt->rdblk;
23840+ break;
dece6358
AM
23841+ case Opt_rdblk_def:
23842+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
23843+ break;
1facf9fc 23844+ case Opt_rdhash:
23845+ sbinfo->si_rdhash = opt->rdhash;
23846+ break;
dece6358
AM
23847+ case Opt_rdhash_def:
23848+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
23849+ break;
23850+
23851+ case Opt_shwh:
23852+ au_opt_set(sbinfo->si_mntflags, SHWH);
23853+ break;
23854+ case Opt_noshwh:
23855+ au_opt_clr(sbinfo->si_mntflags, SHWH);
23856+ break;
1facf9fc 23857+
076b876e
AM
23858+ case Opt_dirperm1:
23859+ au_opt_set(sbinfo->si_mntflags, DIRPERM1);
23860+ break;
23861+ case Opt_nodirperm1:
23862+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
23863+ break;
23864+
1facf9fc 23865+ case Opt_trunc_xino:
23866+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
23867+ break;
23868+ case Opt_notrunc_xino:
23869+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
23870+ break;
23871+
23872+ case Opt_trunc_xino_path:
23873+ case Opt_itrunc_xino:
23874+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
23875+ if (!err)
23876+ err = 1;
23877+ break;
23878+
23879+ case Opt_trunc_xib:
23880+ au_fset_opts(opts->flags, TRUNC_XIB);
23881+ break;
23882+ case Opt_notrunc_xib:
23883+ au_fclr_opts(opts->flags, TRUNC_XIB);
23884+ break;
23885+
c1595e42
JR
23886+ case Opt_acl:
23887+ sb->s_flags |= MS_POSIXACL;
23888+ break;
23889+ case Opt_noacl:
23890+ sb->s_flags &= ~MS_POSIXACL;
23891+ break;
23892+
1facf9fc 23893+ default:
23894+ err = 0;
23895+ break;
23896+ }
23897+
23898+ return err;
23899+}
23900+
23901+/*
23902+ * returns tri-state.
23903+ * plus: processed without an error
23904+ * zero: unprocessed
23905+ * minus: error
23906+ */
23907+static int au_opt_br(struct super_block *sb, struct au_opt *opt,
23908+ struct au_opts *opts)
23909+{
23910+ int err, do_refresh;
23911+
23912+ err = 0;
23913+ switch (opt->type) {
23914+ case Opt_append:
23915+ opt->add.bindex = au_sbend(sb) + 1;
23916+ if (opt->add.bindex < 0)
23917+ opt->add.bindex = 0;
23918+ goto add;
23919+ case Opt_prepend:
23920+ opt->add.bindex = 0;
f6b6e03d 23921+ add: /* indented label */
1facf9fc 23922+ case Opt_add:
23923+ err = au_br_add(sb, &opt->add,
23924+ au_ftest_opts(opts->flags, REMOUNT));
23925+ if (!err) {
23926+ err = 1;
027c5e7a 23927+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23928+ }
23929+ break;
23930+
23931+ case Opt_del:
23932+ case Opt_idel:
23933+ err = au_br_del(sb, &opt->del,
23934+ au_ftest_opts(opts->flags, REMOUNT));
23935+ if (!err) {
23936+ err = 1;
23937+ au_fset_opts(opts->flags, TRUNC_XIB);
027c5e7a 23938+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23939+ }
23940+ break;
23941+
23942+ case Opt_mod:
23943+ case Opt_imod:
23944+ err = au_br_mod(sb, &opt->mod,
23945+ au_ftest_opts(opts->flags, REMOUNT),
23946+ &do_refresh);
23947+ if (!err) {
23948+ err = 1;
027c5e7a
AM
23949+ if (do_refresh)
23950+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 23951+ }
23952+ break;
23953+ }
23954+
23955+ return err;
23956+}
23957+
23958+static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
23959+ struct au_opt_xino **opt_xino,
23960+ struct au_opts *opts)
23961+{
23962+ int err;
23963+ aufs_bindex_t bend, bindex;
23964+ struct dentry *root, *parent, *h_root;
23965+
23966+ err = 0;
23967+ switch (opt->type) {
23968+ case Opt_xino:
23969+ err = au_xino_set(sb, &opt->xino,
23970+ !!au_ftest_opts(opts->flags, REMOUNT));
23971+ if (unlikely(err))
23972+ break;
23973+
23974+ *opt_xino = &opt->xino;
23975+ au_xino_brid_set(sb, -1);
23976+
23977+ /* safe d_parent access */
23978+ parent = opt->xino.file->f_dentry->d_parent;
23979+ root = sb->s_root;
23980+ bend = au_sbend(sb);
23981+ for (bindex = 0; bindex <= bend; bindex++) {
23982+ h_root = au_h_dptr(root, bindex);
23983+ if (h_root == parent) {
23984+ au_xino_brid_set(sb, au_sbr_id(sb, bindex));
23985+ break;
23986+ }
23987+ }
23988+ break;
23989+
23990+ case Opt_noxino:
23991+ au_xino_clr(sb);
23992+ au_xino_brid_set(sb, -1);
23993+ *opt_xino = (void *)-1;
23994+ break;
23995+ }
23996+
23997+ return err;
23998+}
23999+
24000+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
24001+ unsigned int pending)
24002+{
076b876e 24003+ int err, fhsm;
1facf9fc 24004+ aufs_bindex_t bindex, bend;
24005+ unsigned char do_plink, skip, do_free;
24006+ struct au_branch *br;
24007+ struct au_wbr *wbr;
24008+ struct dentry *root;
24009+ struct inode *dir, *h_dir;
24010+ struct au_sbinfo *sbinfo;
24011+ struct au_hinode *hdir;
24012+
dece6358
AM
24013+ SiMustAnyLock(sb);
24014+
1facf9fc 24015+ sbinfo = au_sbi(sb);
24016+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA));
24017+
dece6358
AM
24018+ if (!(sb_flags & MS_RDONLY)) {
24019+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0))))
0c3ec466 24020+ pr_warn("first branch should be rw\n");
dece6358 24021+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH)))
0c3ec466 24022+ pr_warn("shwh should be used with ro\n");
dece6358 24023+ }
1facf9fc 24024+
4a4d8108 24025+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY)
1facf9fc 24026+ && !au_opt_test(sbinfo->si_mntflags, XINO))
0c3ec466 24027+ pr_warn("udba=*notify requires xino\n");
1facf9fc 24028+
076b876e
AM
24029+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1))
24030+ pr_warn("dirperm1 breaks the protection"
24031+ " by the permission bits on the lower branch\n");
24032+
1facf9fc 24033+ err = 0;
076b876e 24034+ fhsm = 0;
1facf9fc 24035+ root = sb->s_root;
4a4d8108 24036+ dir = root->d_inode;
1facf9fc 24037+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK);
24038+ bend = au_sbend(sb);
24039+ for (bindex = 0; !err && bindex <= bend; bindex++) {
24040+ skip = 0;
24041+ h_dir = au_h_iptr(dir, bindex);
24042+ br = au_sbr(sb, bindex);
1facf9fc 24043+
c1595e42
JR
24044+ if ((br->br_perm & AuBrAttr_ICEX)
24045+ && !h_dir->i_op->listxattr)
24046+ br->br_perm &= ~AuBrAttr_ICEX;
24047+#if 0
24048+ if ((br->br_perm & AuBrAttr_ICEX_SEC)
24049+ && (au_br_sb(br)->s_flags & MS_NOSEC))
24050+ br->br_perm &= ~AuBrAttr_ICEX_SEC;
24051+#endif
24052+
24053+ do_free = 0;
1facf9fc 24054+ wbr = br->br_wbr;
24055+ if (wbr)
24056+ wbr_wh_read_lock(wbr);
24057+
1e00d052 24058+ if (!au_br_writable(br->br_perm)) {
1facf9fc 24059+ do_free = !!wbr;
24060+ skip = (!wbr
24061+ || (!wbr->wbr_whbase
24062+ && !wbr->wbr_plink
24063+ && !wbr->wbr_orph));
1e00d052 24064+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 24065+ /* skip = (!br->br_whbase && !br->br_orph); */
24066+ skip = (!wbr || !wbr->wbr_whbase);
24067+ if (skip && wbr) {
24068+ if (do_plink)
24069+ skip = !!wbr->wbr_plink;
24070+ else
24071+ skip = !wbr->wbr_plink;
24072+ }
1e00d052 24073+ } else {
1facf9fc 24074+ /* skip = (br->br_whbase && br->br_ohph); */
24075+ skip = (wbr && wbr->wbr_whbase);
24076+ if (skip) {
24077+ if (do_plink)
24078+ skip = !!wbr->wbr_plink;
24079+ else
24080+ skip = !wbr->wbr_plink;
24081+ }
1facf9fc 24082+ }
24083+ if (wbr)
24084+ wbr_wh_read_unlock(wbr);
24085+
076b876e
AM
24086+ if (au_br_fhsm(br->br_perm)) {
24087+ fhsm++;
24088+ AuDebugOn(!br->br_fhsm);
24089+ }
24090+
1facf9fc 24091+ if (skip)
24092+ continue;
24093+
24094+ hdir = au_hi(dir, bindex);
4a4d8108 24095+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 24096+ if (wbr)
24097+ wbr_wh_write_lock(wbr);
86dc4139 24098+ err = au_wh_init(br, sb);
1facf9fc 24099+ if (wbr)
24100+ wbr_wh_write_unlock(wbr);
4a4d8108 24101+ au_hn_imtx_unlock(hdir);
1facf9fc 24102+
24103+ if (!err && do_free) {
24104+ kfree(wbr);
24105+ br->br_wbr = NULL;
24106+ }
24107+ }
24108+
c1595e42 24109+ if (fhsm >= 2) {
076b876e 24110+ au_fset_si(sbinfo, FHSM);
c1595e42
JR
24111+ for (bindex = bend; bindex >= 0; bindex--) {
24112+ br = au_sbr(sb, bindex);
24113+ if (au_br_fhsm(br->br_perm)) {
24114+ au_fhsm_set_bottom(sb, bindex);
24115+ break;
24116+ }
24117+ }
24118+ } else {
076b876e 24119+ au_fclr_si(sbinfo, FHSM);
c1595e42
JR
24120+ au_fhsm_set_bottom(sb, -1);
24121+ }
076b876e 24122+
1facf9fc 24123+ return err;
24124+}
24125+
24126+int au_opts_mount(struct super_block *sb, struct au_opts *opts)
24127+{
24128+ int err;
24129+ unsigned int tmp;
027c5e7a 24130+ aufs_bindex_t bindex, bend;
1facf9fc 24131+ struct au_opt *opt;
24132+ struct au_opt_xino *opt_xino, xino;
24133+ struct au_sbinfo *sbinfo;
027c5e7a 24134+ struct au_branch *br;
076b876e 24135+ struct inode *dir;
1facf9fc 24136+
dece6358
AM
24137+ SiMustWriteLock(sb);
24138+
1facf9fc 24139+ err = 0;
24140+ opt_xino = NULL;
24141+ opt = opts->opt;
24142+ while (err >= 0 && opt->type != Opt_tail)
24143+ err = au_opt_simple(sb, opt++, opts);
24144+ if (err > 0)
24145+ err = 0;
24146+ else if (unlikely(err < 0))
24147+ goto out;
24148+
24149+ /* disable xino and udba temporary */
24150+ sbinfo = au_sbi(sb);
24151+ tmp = sbinfo->si_mntflags;
24152+ au_opt_clr(sbinfo->si_mntflags, XINO);
24153+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL);
24154+
24155+ opt = opts->opt;
24156+ while (err >= 0 && opt->type != Opt_tail)
24157+ err = au_opt_br(sb, opt++, opts);
24158+ if (err > 0)
24159+ err = 0;
24160+ else if (unlikely(err < 0))
24161+ goto out;
24162+
24163+ bend = au_sbend(sb);
24164+ if (unlikely(bend < 0)) {
24165+ err = -EINVAL;
4a4d8108 24166+ pr_err("no branches\n");
1facf9fc 24167+ goto out;
24168+ }
24169+
24170+ if (au_opt_test(tmp, XINO))
24171+ au_opt_set(sbinfo->si_mntflags, XINO);
24172+ opt = opts->opt;
24173+ while (!err && opt->type != Opt_tail)
24174+ err = au_opt_xino(sb, opt++, &opt_xino, opts);
24175+ if (unlikely(err))
24176+ goto out;
24177+
24178+ err = au_opts_verify(sb, sb->s_flags, tmp);
24179+ if (unlikely(err))
24180+ goto out;
24181+
24182+ /* restore xino */
24183+ if (au_opt_test(tmp, XINO) && !opt_xino) {
24184+ xino.file = au_xino_def(sb);
24185+ err = PTR_ERR(xino.file);
24186+ if (IS_ERR(xino.file))
24187+ goto out;
24188+
24189+ err = au_xino_set(sb, &xino, /*remount*/0);
24190+ fput(xino.file);
24191+ if (unlikely(err))
24192+ goto out;
24193+ }
24194+
24195+ /* restore udba */
027c5e7a 24196+ tmp &= AuOptMask_UDBA;
1facf9fc 24197+ sbinfo->si_mntflags &= ~AuOptMask_UDBA;
027c5e7a
AM
24198+ sbinfo->si_mntflags |= tmp;
24199+ bend = au_sbend(sb);
24200+ for (bindex = 0; bindex <= bend; bindex++) {
24201+ br = au_sbr(sb, bindex);
24202+ err = au_hnotify_reset_br(tmp, br, br->br_perm);
24203+ if (unlikely(err))
24204+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
24205+ bindex, err);
24206+ /* go on even if err */
24207+ }
4a4d8108 24208+ if (au_opt_test(tmp, UDBA_HNOTIFY)) {
076b876e 24209+ dir = sb->s_root->d_inode;
4a4d8108 24210+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO);
1facf9fc 24211+ }
24212+
4f0767ce 24213+out:
1facf9fc 24214+ return err;
24215+}
24216+
24217+int au_opts_remount(struct super_block *sb, struct au_opts *opts)
24218+{
24219+ int err, rerr;
24220+ struct inode *dir;
24221+ struct au_opt_xino *opt_xino;
24222+ struct au_opt *opt;
24223+ struct au_sbinfo *sbinfo;
24224+
dece6358
AM
24225+ SiMustWriteLock(sb);
24226+
1facf9fc 24227+ dir = sb->s_root->d_inode;
24228+ sbinfo = au_sbi(sb);
24229+ err = 0;
24230+ opt_xino = NULL;
24231+ opt = opts->opt;
24232+ while (err >= 0 && opt->type != Opt_tail) {
24233+ err = au_opt_simple(sb, opt, opts);
24234+ if (!err)
24235+ err = au_opt_br(sb, opt, opts);
24236+ if (!err)
24237+ err = au_opt_xino(sb, opt, &opt_xino, opts);
24238+ opt++;
24239+ }
24240+ if (err > 0)
24241+ err = 0;
24242+ AuTraceErr(err);
24243+ /* go on even err */
24244+
24245+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
24246+ if (unlikely(rerr && !err))
24247+ err = rerr;
24248+
24249+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
24250+ rerr = au_xib_trunc(sb);
24251+ if (unlikely(rerr && !err))
24252+ err = rerr;
24253+ }
24254+
24255+ /* will be handled by the caller */
027c5e7a 24256+ if (!au_ftest_opts(opts->flags, REFRESH)
1facf9fc 24257+ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO)))
027c5e7a 24258+ au_fset_opts(opts->flags, REFRESH);
1facf9fc 24259+
24260+ AuDbg("status 0x%x\n", opts->flags);
24261+ return err;
24262+}
24263+
24264+/* ---------------------------------------------------------------------- */
24265+
24266+unsigned int au_opt_udba(struct super_block *sb)
24267+{
24268+ return au_mntflags(sb) & AuOptMask_UDBA;
24269+}
7f207e10
AM
24270diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h
24271--- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 24272+++ linux/fs/aufs/opts.h 2015-01-25 13:00:38.634380408 +0100
076b876e 24273@@ -0,0 +1,213 @@
1facf9fc 24274+/*
523b37e3 24275+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 24276+ *
24277+ * This program, aufs is free software; you can redistribute it and/or modify
24278+ * it under the terms of the GNU General Public License as published by
24279+ * the Free Software Foundation; either version 2 of the License, or
24280+ * (at your option) any later version.
dece6358
AM
24281+ *
24282+ * This program is distributed in the hope that it will be useful,
24283+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24284+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24285+ * GNU General Public License for more details.
24286+ *
24287+ * You should have received a copy of the GNU General Public License
523b37e3 24288+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24289+ */
24290+
24291+/*
24292+ * mount options/flags
24293+ */
24294+
24295+#ifndef __AUFS_OPTS_H__
24296+#define __AUFS_OPTS_H__
24297+
24298+#ifdef __KERNEL__
24299+
dece6358 24300+#include <linux/path.h>
076b876e 24301+#include "branch.h"
1facf9fc 24302+
dece6358
AM
24303+struct file;
24304+struct super_block;
24305+
1facf9fc 24306+/* ---------------------------------------------------------------------- */
24307+
24308+/* mount flags */
24309+#define AuOpt_XINO 1 /* external inode number bitmap
24310+ and translation table */
24311+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */
24312+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */
24313+#define AuOpt_UDBA_REVAL (1 << 3)
4a4d8108 24314+#define AuOpt_UDBA_HNOTIFY (1 << 4)
dece6358
AM
24315+#define AuOpt_SHWH (1 << 5) /* show whiteout */
24316+#define AuOpt_PLINK (1 << 6) /* pseudo-link */
076b876e
AM
24317+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm
24318+ bits */
dece6358
AM
24319+#define AuOpt_REFROF (1 << 8) /* unimplemented */
24320+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */
24321+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
24322+#define AuOpt_SUM_W (1 << 11) /* unimplemented */
24323+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
24324+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */
4a4d8108 24325+#define AuOpt_DIO (1 << 14) /* direct io */
1facf9fc 24326+
4a4d8108
AM
24327+#ifndef CONFIG_AUFS_HNOTIFY
24328+#undef AuOpt_UDBA_HNOTIFY
24329+#define AuOpt_UDBA_HNOTIFY 0
1facf9fc 24330+#endif
dece6358
AM
24331+#ifndef CONFIG_AUFS_SHWH
24332+#undef AuOpt_SHWH
24333+#define AuOpt_SHWH 0
24334+#endif
1facf9fc 24335+
24336+#define AuOpt_Def (AuOpt_XINO \
24337+ | AuOpt_UDBA_REVAL \
24338+ | AuOpt_PLINK \
24339+ /* | AuOpt_DIRPERM1 */ \
24340+ | AuOpt_WARN_PERM)
24341+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \
24342+ | AuOpt_UDBA_REVAL \
4a4d8108 24343+ | AuOpt_UDBA_HNOTIFY)
1facf9fc 24344+
24345+#define au_opt_test(flags, name) (flags & AuOpt_##name)
24346+#define au_opt_set(flags, name) do { \
24347+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \
24348+ ((flags) |= AuOpt_##name); \
24349+} while (0)
24350+#define au_opt_set_udba(flags, name) do { \
24351+ (flags) &= ~AuOptMask_UDBA; \
24352+ ((flags) |= AuOpt_##name); \
24353+} while (0)
7f207e10
AM
24354+#define au_opt_clr(flags, name) do { \
24355+ ((flags) &= ~AuOpt_##name); \
24356+} while (0)
1facf9fc 24357+
e49829fe
JR
24358+static inline unsigned int au_opts_plink(unsigned int mntflags)
24359+{
24360+#ifdef CONFIG_PROC_FS
24361+ return mntflags;
24362+#else
24363+ return mntflags & ~AuOpt_PLINK;
24364+#endif
24365+}
24366+
1facf9fc 24367+/* ---------------------------------------------------------------------- */
24368+
24369+/* policies to select one among multiple writable branches */
24370+enum {
24371+ AuWbrCreate_TDP, /* top down parent */
24372+ AuWbrCreate_RR, /* round robin */
24373+ AuWbrCreate_MFS, /* most free space */
24374+ AuWbrCreate_MFSV, /* mfs with seconds */
24375+ AuWbrCreate_MFSRR, /* mfs then rr */
24376+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */
24377+ AuWbrCreate_PMFS, /* parent and mfs */
24378+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */
392086de
AM
24379+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */
24380+ AuWbrCreate_PMFSRRV, /* plus seconds */
1facf9fc 24381+
24382+ AuWbrCreate_Def = AuWbrCreate_TDP
24383+};
24384+
24385+enum {
24386+ AuWbrCopyup_TDP, /* top down parent */
24387+ AuWbrCopyup_BUP, /* bottom up parent */
24388+ AuWbrCopyup_BU, /* bottom up */
24389+
24390+ AuWbrCopyup_Def = AuWbrCopyup_TDP
24391+};
24392+
24393+/* ---------------------------------------------------------------------- */
24394+
24395+struct au_opt_add {
24396+ aufs_bindex_t bindex;
24397+ char *pathname;
24398+ int perm;
24399+ struct path path;
24400+};
24401+
24402+struct au_opt_del {
24403+ char *pathname;
24404+ struct path h_path;
24405+};
24406+
24407+struct au_opt_mod {
24408+ char *path;
24409+ int perm;
24410+ struct dentry *h_root;
24411+};
24412+
24413+struct au_opt_xino {
24414+ char *path;
24415+ struct file *file;
24416+};
24417+
24418+struct au_opt_xino_itrunc {
24419+ aufs_bindex_t bindex;
24420+};
24421+
24422+struct au_opt_wbr_create {
24423+ int wbr_create;
24424+ int mfs_second;
24425+ unsigned long long mfsrr_watermark;
24426+};
24427+
24428+struct au_opt {
24429+ int type;
24430+ union {
24431+ struct au_opt_xino xino;
24432+ struct au_opt_xino_itrunc xino_itrunc;
24433+ struct au_opt_add add;
24434+ struct au_opt_del del;
24435+ struct au_opt_mod mod;
24436+ int dirwh;
24437+ int rdcache;
24438+ unsigned int rdblk;
24439+ unsigned int rdhash;
24440+ int udba;
24441+ struct au_opt_wbr_create wbr_create;
24442+ int wbr_copyup;
076b876e 24443+ unsigned int fhsm_second;
1facf9fc 24444+ };
24445+};
24446+
24447+/* opts flags */
24448+#define AuOpts_REMOUNT 1
027c5e7a
AM
24449+#define AuOpts_REFRESH (1 << 1)
24450+#define AuOpts_TRUNC_XIB (1 << 2)
24451+#define AuOpts_REFRESH_DYAOP (1 << 3)
1facf9fc 24452+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name)
7f207e10
AM
24453+#define au_fset_opts(flags, name) \
24454+ do { (flags) |= AuOpts_##name; } while (0)
24455+#define au_fclr_opts(flags, name) \
24456+ do { (flags) &= ~AuOpts_##name; } while (0)
1facf9fc 24457+
24458+struct au_opts {
24459+ struct au_opt *opt;
24460+ int max_opt;
24461+
24462+ unsigned int given_udba;
24463+ unsigned int flags;
24464+ unsigned long sb_flags;
24465+};
24466+
24467+/* ---------------------------------------------------------------------- */
24468+
076b876e 24469+void au_optstr_br_perm(au_br_perm_str_t *str, int perm);
1facf9fc 24470+const char *au_optstr_udba(int udba);
24471+const char *au_optstr_wbr_copyup(int wbr_copyup);
24472+const char *au_optstr_wbr_create(int wbr_create);
24473+
24474+void au_opts_free(struct au_opts *opts);
24475+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts);
24476+int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
24477+ unsigned int pending);
24478+int au_opts_mount(struct super_block *sb, struct au_opts *opts);
24479+int au_opts_remount(struct super_block *sb, struct au_opts *opts);
24480+
24481+unsigned int au_opt_udba(struct super_block *sb);
24482+
24483+/* ---------------------------------------------------------------------- */
24484+
24485+#endif /* __KERNEL__ */
24486+#endif /* __AUFS_OPTS_H__ */
7f207e10
AM
24487diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
24488--- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 24489+++ linux/fs/aufs/plink.c 2015-01-25 13:00:38.634380408 +0100
523b37e3 24490@@ -0,0 +1,532 @@
1facf9fc 24491+/*
523b37e3 24492+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 24493+ *
24494+ * This program, aufs is free software; you can redistribute it and/or modify
24495+ * it under the terms of the GNU General Public License as published by
24496+ * the Free Software Foundation; either version 2 of the License, or
24497+ * (at your option) any later version.
dece6358
AM
24498+ *
24499+ * This program is distributed in the hope that it will be useful,
24500+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24501+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24502+ * GNU General Public License for more details.
24503+ *
24504+ * You should have received a copy of the GNU General Public License
523b37e3 24505+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 24506+ */
24507+
24508+/*
24509+ * pseudo-link
24510+ */
24511+
24512+#include "aufs.h"
24513+
24514+/*
e49829fe 24515+ * the pseudo-link maintenance mode.
1facf9fc 24516+ * during a user process maintains the pseudo-links,
24517+ * prohibit adding a new plink and branch manipulation.
e49829fe
JR
24518+ *
24519+ * Flags
24520+ * NOPLM:
24521+ * For entry functions which will handle plink, and i_mutex is already held
24522+ * in VFS.
24523+ * They cannot wait and should return an error at once.
24524+ * Callers has to check the error.
24525+ * NOPLMW:
24526+ * For entry functions which will handle plink, but i_mutex is not held
24527+ * in VFS.
24528+ * They can wait the plink maintenance mode to finish.
24529+ *
24530+ * They behave like F_SETLK and F_SETLKW.
24531+ * If the caller never handle plink, then both flags are unnecessary.
1facf9fc 24532+ */
e49829fe
JR
24533+
24534+int au_plink_maint(struct super_block *sb, int flags)
1facf9fc 24535+{
e49829fe
JR
24536+ int err;
24537+ pid_t pid, ppid;
24538+ struct au_sbinfo *sbi;
dece6358
AM
24539+
24540+ SiMustAnyLock(sb);
24541+
e49829fe
JR
24542+ err = 0;
24543+ if (!au_opt_test(au_mntflags(sb), PLINK))
24544+ goto out;
24545+
24546+ sbi = au_sbi(sb);
24547+ pid = sbi->si_plink_maint_pid;
24548+ if (!pid || pid == current->pid)
24549+ goto out;
24550+
24551+ /* todo: it highly depends upon /sbin/mount.aufs */
24552+ rcu_read_lock();
24553+ ppid = task_pid_vnr(rcu_dereference(current->real_parent));
24554+ rcu_read_unlock();
24555+ if (pid == ppid)
24556+ goto out;
24557+
24558+ if (au_ftest_lock(flags, NOPLMW)) {
027c5e7a
AM
24559+ /* if there is no i_mutex lock in VFS, we don't need to wait */
24560+ /* AuDebugOn(!lockdep_depth(current)); */
e49829fe
JR
24561+ while (sbi->si_plink_maint_pid) {
24562+ si_read_unlock(sb);
24563+ /* gave up wake_up_bit() */
24564+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
24565+
24566+ if (au_ftest_lock(flags, FLUSH))
24567+ au_nwt_flush(&sbi->si_nowait);
24568+ si_noflush_read_lock(sb);
24569+ }
24570+ } else if (au_ftest_lock(flags, NOPLM)) {
24571+ AuDbg("ppid %d, pid %d\n", ppid, pid);
24572+ err = -EAGAIN;
24573+ }
24574+
24575+out:
24576+ return err;
4a4d8108
AM
24577+}
24578+
e49829fe 24579+void au_plink_maint_leave(struct au_sbinfo *sbinfo)
4a4d8108 24580+{
4a4d8108 24581+ spin_lock(&sbinfo->si_plink_maint_lock);
027c5e7a 24582+ sbinfo->si_plink_maint_pid = 0;
4a4d8108 24583+ spin_unlock(&sbinfo->si_plink_maint_lock);
027c5e7a 24584+ wake_up_all(&sbinfo->si_plink_wq);
4a4d8108
AM
24585+}
24586+
e49829fe 24587+int au_plink_maint_enter(struct super_block *sb)
4a4d8108
AM
24588+{
24589+ int err;
4a4d8108
AM
24590+ struct au_sbinfo *sbinfo;
24591+
24592+ err = 0;
4a4d8108
AM
24593+ sbinfo = au_sbi(sb);
24594+ /* make sure i am the only one in this fs */
e49829fe
JR
24595+ si_write_lock(sb, AuLock_FLUSH);
24596+ if (au_opt_test(au_mntflags(sb), PLINK)) {
24597+ spin_lock(&sbinfo->si_plink_maint_lock);
24598+ if (!sbinfo->si_plink_maint_pid)
24599+ sbinfo->si_plink_maint_pid = current->pid;
24600+ else
24601+ err = -EBUSY;
24602+ spin_unlock(&sbinfo->si_plink_maint_lock);
24603+ }
4a4d8108
AM
24604+ si_write_unlock(sb);
24605+
24606+ return err;
1facf9fc 24607+}
24608+
24609+/* ---------------------------------------------------------------------- */
24610+
1facf9fc 24611+#ifdef CONFIG_AUFS_DEBUG
24612+void au_plink_list(struct super_block *sb)
24613+{
86dc4139 24614+ int i;
1facf9fc 24615+ struct au_sbinfo *sbinfo;
86dc4139 24616+ struct hlist_head *plink_hlist;
1facf9fc 24617+ struct pseudo_link *plink;
24618+
dece6358
AM
24619+ SiMustAnyLock(sb);
24620+
1facf9fc 24621+ sbinfo = au_sbi(sb);
24622+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24623+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24624+
86dc4139
AM
24625+ for (i = 0; i < AuPlink_NHASH; i++) {
24626+ plink_hlist = &sbinfo->si_plink[i].head;
24627+ rcu_read_lock();
24628+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
24629+ AuDbg("%lu\n", plink->inode->i_ino);
24630+ rcu_read_unlock();
24631+ }
1facf9fc 24632+}
24633+#endif
24634+
24635+/* is the inode pseudo-linked? */
24636+int au_plink_test(struct inode *inode)
24637+{
86dc4139 24638+ int found, i;
1facf9fc 24639+ struct au_sbinfo *sbinfo;
86dc4139 24640+ struct hlist_head *plink_hlist;
1facf9fc 24641+ struct pseudo_link *plink;
24642+
24643+ sbinfo = au_sbi(inode->i_sb);
dece6358 24644+ AuRwMustAnyLock(&sbinfo->si_rwsem);
1facf9fc 24645+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
e49829fe 24646+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
1facf9fc 24647+
24648+ found = 0;
86dc4139
AM
24649+ i = au_plink_hash(inode->i_ino);
24650+ plink_hlist = &sbinfo->si_plink[i].head;
4a4d8108 24651+ rcu_read_lock();
86dc4139 24652+ hlist_for_each_entry_rcu(plink, plink_hlist, hlist)
1facf9fc 24653+ if (plink->inode == inode) {
24654+ found = 1;
24655+ break;
24656+ }
4a4d8108 24657+ rcu_read_unlock();
1facf9fc 24658+ return found;
24659+}
24660+
24661+/* ---------------------------------------------------------------------- */
24662+
24663+/*
24664+ * generate a name for plink.
24665+ * the file will be stored under AUFS_WH_PLINKDIR.
24666+ */
24667+/* 20 is max digits length of ulong 64 */
24668+#define PLINK_NAME_LEN ((20 + 1) * 2)
24669+
24670+static int plink_name(char *name, int len, struct inode *inode,
24671+ aufs_bindex_t bindex)
24672+{
24673+ int rlen;
24674+ struct inode *h_inode;
24675+
24676+ h_inode = au_h_iptr(inode, bindex);
24677+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
24678+ return rlen;
24679+}
24680+
7f207e10
AM
24681+struct au_do_plink_lkup_args {
24682+ struct dentry **errp;
24683+ struct qstr *tgtname;
24684+ struct dentry *h_parent;
24685+ struct au_branch *br;
24686+};
24687+
24688+static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
24689+ struct dentry *h_parent,
24690+ struct au_branch *br)
24691+{
24692+ struct dentry *h_dentry;
24693+ struct mutex *h_mtx;
24694+
24695+ h_mtx = &h_parent->d_inode->i_mutex;
24696+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
b4510431 24697+ h_dentry = vfsub_lkup_one(tgtname, h_parent);
7f207e10
AM
24698+ mutex_unlock(h_mtx);
24699+ return h_dentry;
24700+}
24701+
24702+static void au_call_do_plink_lkup(void *args)
24703+{
24704+ struct au_do_plink_lkup_args *a = args;
24705+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
24706+}
24707+
1facf9fc 24708+/* lookup the plink-ed @inode under the branch at @bindex */
24709+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
24710+{
24711+ struct dentry *h_dentry, *h_parent;
24712+ struct au_branch *br;
24713+ struct inode *h_dir;
7f207e10 24714+ int wkq_err;
1facf9fc 24715+ char a[PLINK_NAME_LEN];
0c3ec466 24716+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24717+
e49829fe
JR
24718+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
24719+
1facf9fc 24720+ br = au_sbr(inode->i_sb, bindex);
24721+ h_parent = br->br_wbr->wbr_plink;
24722+ h_dir = h_parent->d_inode;
24723+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24724+
2dfbb274 24725+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
7f207e10
AM
24726+ struct au_do_plink_lkup_args args = {
24727+ .errp = &h_dentry,
24728+ .tgtname = &tgtname,
24729+ .h_parent = h_parent,
24730+ .br = br
24731+ };
24732+
24733+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
24734+ if (unlikely(wkq_err))
24735+ h_dentry = ERR_PTR(wkq_err);
24736+ } else
24737+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
24738+
1facf9fc 24739+ return h_dentry;
24740+}
24741+
24742+/* create a pseudo-link */
24743+static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
24744+ struct dentry *h_dentry, struct au_branch *br)
24745+{
24746+ int err;
24747+ struct path h_path = {
86dc4139 24748+ .mnt = au_br_mnt(br)
1facf9fc 24749+ };
523b37e3 24750+ struct inode *h_dir, *delegated;
1facf9fc 24751+
24752+ h_dir = h_parent->d_inode;
7f207e10 24753+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
4f0767ce 24754+again:
b4510431 24755+ h_path.dentry = vfsub_lkup_one(tgt, h_parent);
1facf9fc 24756+ err = PTR_ERR(h_path.dentry);
24757+ if (IS_ERR(h_path.dentry))
24758+ goto out;
24759+
24760+ err = 0;
24761+ /* wh.plink dir is not monitored */
7f207e10 24762+ /* todo: is it really safe? */
1facf9fc 24763+ if (h_path.dentry->d_inode
24764+ && h_path.dentry->d_inode != h_dentry->d_inode) {
523b37e3
AM
24765+ delegated = NULL;
24766+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
24767+ if (unlikely(err == -EWOULDBLOCK)) {
24768+ pr_warn("cannot retry for NFSv4 delegation"
24769+ " for an internal unlink\n");
24770+ iput(delegated);
24771+ }
1facf9fc 24772+ dput(h_path.dentry);
24773+ h_path.dentry = NULL;
24774+ if (!err)
24775+ goto again;
24776+ }
523b37e3
AM
24777+ if (!err && !h_path.dentry->d_inode) {
24778+ delegated = NULL;
24779+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
24780+ if (unlikely(err == -EWOULDBLOCK)) {
24781+ pr_warn("cannot retry for NFSv4 delegation"
24782+ " for an internal link\n");
24783+ iput(delegated);
24784+ }
24785+ }
1facf9fc 24786+ dput(h_path.dentry);
24787+
4f0767ce 24788+out:
7f207e10 24789+ mutex_unlock(&h_dir->i_mutex);
1facf9fc 24790+ return err;
24791+}
24792+
24793+struct do_whplink_args {
24794+ int *errp;
24795+ struct qstr *tgt;
24796+ struct dentry *h_parent;
24797+ struct dentry *h_dentry;
24798+ struct au_branch *br;
24799+};
24800+
24801+static void call_do_whplink(void *args)
24802+{
24803+ struct do_whplink_args *a = args;
24804+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
24805+}
24806+
24807+static int whplink(struct dentry *h_dentry, struct inode *inode,
24808+ aufs_bindex_t bindex, struct au_branch *br)
24809+{
24810+ int err, wkq_err;
24811+ struct au_wbr *wbr;
24812+ struct dentry *h_parent;
24813+ struct inode *h_dir;
24814+ char a[PLINK_NAME_LEN];
0c3ec466 24815+ struct qstr tgtname = QSTR_INIT(a, 0);
1facf9fc 24816+
24817+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
24818+ h_parent = wbr->wbr_plink;
24819+ h_dir = h_parent->d_inode;
24820+ tgtname.len = plink_name(a, sizeof(a), inode, bindex);
24821+
24822+ /* always superio. */
2dfbb274 24823+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
1facf9fc 24824+ struct do_whplink_args args = {
24825+ .errp = &err,
24826+ .tgt = &tgtname,
24827+ .h_parent = h_parent,
24828+ .h_dentry = h_dentry,
24829+ .br = br
24830+ };
24831+ wkq_err = au_wkq_wait(call_do_whplink, &args);
24832+ if (unlikely(wkq_err))
24833+ err = wkq_err;
24834+ } else
24835+ err = do_whplink(&tgtname, h_parent, h_dentry, br);
1facf9fc 24836+
24837+ return err;
24838+}
24839+
24840+/* free a single plink */
24841+static void do_put_plink(struct pseudo_link *plink, int do_del)
24842+{
1facf9fc 24843+ if (do_del)
86dc4139 24844+ hlist_del(&plink->hlist);
4a4d8108
AM
24845+ iput(plink->inode);
24846+ kfree(plink);
24847+}
24848+
24849+static void do_put_plink_rcu(struct rcu_head *rcu)
24850+{
24851+ struct pseudo_link *plink;
24852+
24853+ plink = container_of(rcu, struct pseudo_link, rcu);
24854+ iput(plink->inode);
1facf9fc 24855+ kfree(plink);
24856+}
24857+
24858+/*
24859+ * create a new pseudo-link for @h_dentry on @bindex.
24860+ * the linked inode is held in aufs @inode.
24861+ */
24862+void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
24863+ struct dentry *h_dentry)
24864+{
24865+ struct super_block *sb;
24866+ struct au_sbinfo *sbinfo;
86dc4139 24867+ struct hlist_head *plink_hlist;
4a4d8108 24868+ struct pseudo_link *plink, *tmp;
86dc4139
AM
24869+ struct au_sphlhead *sphl;
24870+ int found, err, cnt, i;
1facf9fc 24871+
24872+ sb = inode->i_sb;
24873+ sbinfo = au_sbi(sb);
24874+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24875+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24876+
86dc4139 24877+ found = au_plink_test(inode);
4a4d8108 24878+ if (found)
1facf9fc 24879+ return;
4a4d8108 24880+
86dc4139
AM
24881+ i = au_plink_hash(inode->i_ino);
24882+ sphl = sbinfo->si_plink + i;
24883+ plink_hlist = &sphl->head;
4a4d8108
AM
24884+ tmp = kmalloc(sizeof(*plink), GFP_NOFS);
24885+ if (tmp)
24886+ tmp->inode = au_igrab(inode);
24887+ else {
24888+ err = -ENOMEM;
24889+ goto out;
1facf9fc 24890+ }
24891+
86dc4139
AM
24892+ spin_lock(&sphl->spin);
24893+ hlist_for_each_entry(plink, plink_hlist, hlist) {
4a4d8108
AM
24894+ if (plink->inode == inode) {
24895+ found = 1;
24896+ break;
24897+ }
1facf9fc 24898+ }
4a4d8108 24899+ if (!found)
86dc4139
AM
24900+ hlist_add_head_rcu(&tmp->hlist, plink_hlist);
24901+ spin_unlock(&sphl->spin);
4a4d8108 24902+ if (!found) {
86dc4139
AM
24903+ cnt = au_sphl_count(sphl);
24904+#define msg "unexpectedly unblanced or too many pseudo-links"
24905+ if (cnt > AUFS_PLINK_WARN)
24906+ AuWarn1(msg ", %d\n", cnt);
24907+#undef msg
1facf9fc 24908+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
4a4d8108
AM
24909+ } else {
24910+ do_put_plink(tmp, 0);
24911+ return;
1facf9fc 24912+ }
24913+
4a4d8108 24914+out:
1facf9fc 24915+ if (unlikely(err)) {
0c3ec466 24916+ pr_warn("err %d, damaged pseudo link.\n", err);
4a4d8108 24917+ if (tmp) {
86dc4139 24918+ au_sphl_del_rcu(&tmp->hlist, sphl);
4a4d8108
AM
24919+ call_rcu(&tmp->rcu, do_put_plink_rcu);
24920+ }
1facf9fc 24921+ }
24922+}
24923+
24924+/* free all plinks */
e49829fe 24925+void au_plink_put(struct super_block *sb, int verbose)
1facf9fc 24926+{
86dc4139 24927+ int i, warned;
1facf9fc 24928+ struct au_sbinfo *sbinfo;
86dc4139
AM
24929+ struct hlist_head *plink_hlist;
24930+ struct hlist_node *tmp;
24931+ struct pseudo_link *plink;
1facf9fc 24932+
dece6358
AM
24933+ SiMustWriteLock(sb);
24934+
1facf9fc 24935+ sbinfo = au_sbi(sb);
24936+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 24937+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 24938+
1facf9fc 24939+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
24940+ warned = 0;
24941+ for (i = 0; i < AuPlink_NHASH; i++) {
24942+ plink_hlist = &sbinfo->si_plink[i].head;
24943+ if (!warned && verbose && !hlist_empty(plink_hlist)) {
24944+ pr_warn("pseudo-link is not flushed");
24945+ warned = 1;
24946+ }
24947+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist)
24948+ do_put_plink(plink, 0);
24949+ INIT_HLIST_HEAD(plink_hlist);
24950+ }
1facf9fc 24951+}
24952+
e49829fe
JR
24953+void au_plink_clean(struct super_block *sb, int verbose)
24954+{
24955+ struct dentry *root;
24956+
24957+ root = sb->s_root;
24958+ aufs_write_lock(root);
24959+ if (au_opt_test(au_mntflags(sb), PLINK))
24960+ au_plink_put(sb, verbose);
24961+ aufs_write_unlock(root);
24962+}
24963+
86dc4139
AM
24964+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
24965+{
24966+ int do_put;
24967+ aufs_bindex_t bstart, bend, bindex;
24968+
24969+ do_put = 0;
24970+ bstart = au_ibstart(inode);
24971+ bend = au_ibend(inode);
24972+ if (bstart >= 0) {
24973+ for (bindex = bstart; bindex <= bend; bindex++) {
24974+ if (!au_h_iptr(inode, bindex)
24975+ || au_ii_br_id(inode, bindex) != br_id)
24976+ continue;
24977+ au_set_h_iptr(inode, bindex, NULL, 0);
24978+ do_put = 1;
24979+ break;
24980+ }
24981+ if (do_put)
24982+ for (bindex = bstart; bindex <= bend; bindex++)
24983+ if (au_h_iptr(inode, bindex)) {
24984+ do_put = 0;
24985+ break;
24986+ }
24987+ } else
24988+ do_put = 1;
24989+
24990+ return do_put;
24991+}
24992+
1facf9fc 24993+/* free the plinks on a branch specified by @br_id */
24994+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
24995+{
24996+ struct au_sbinfo *sbinfo;
86dc4139
AM
24997+ struct hlist_head *plink_hlist;
24998+ struct hlist_node *tmp;
24999+ struct pseudo_link *plink;
1facf9fc 25000+ struct inode *inode;
86dc4139 25001+ int i, do_put;
1facf9fc 25002+
dece6358
AM
25003+ SiMustWriteLock(sb);
25004+
1facf9fc 25005+ sbinfo = au_sbi(sb);
25006+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
e49829fe 25007+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
1facf9fc 25008+
1facf9fc 25009+ /* no spin_lock since sbinfo is write-locked */
86dc4139
AM
25010+ for (i = 0; i < AuPlink_NHASH; i++) {
25011+ plink_hlist = &sbinfo->si_plink[i].head;
25012+ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) {
25013+ inode = au_igrab(plink->inode);
25014+ ii_write_lock_child(inode);
25015+ do_put = au_plink_do_half_refresh(inode, br_id);
dece6358
AM
25016+ if (do_put)
25017+ do_put_plink(plink, 1);
86dc4139
AM
25018+ ii_write_unlock(inode);
25019+ iput(inode);
dece6358 25020+ }
dece6358
AM
25021+ }
25022+}
7f207e10
AM
25023diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c
25024--- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 25025+++ linux/fs/aufs/poll.c 2015-01-25 13:00:38.634380408 +0100
523b37e3 25026@@ -0,0 +1,55 @@
dece6358 25027+/*
523b37e3 25028+ * Copyright (C) 2005-2014 Junjiro R. Okajima
dece6358
AM
25029+ *
25030+ * This program, aufs is free software; you can redistribute it and/or modify
25031+ * it under the terms of the GNU General Public License as published by
25032+ * the Free Software Foundation; either version 2 of the License, or
25033+ * (at your option) any later version.
25034+ *
25035+ * This program is distributed in the hope that it will be useful,
25036+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25037+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25038+ * GNU General Public License for more details.
25039+ *
25040+ * You should have received a copy of the GNU General Public License
523b37e3 25041+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
dece6358
AM
25042+ */
25043+
1308ab2a 25044+/*
25045+ * poll operation
25046+ * There is only one filesystem which implements ->poll operation, currently.
25047+ */
25048+
25049+#include "aufs.h"
25050+
25051+unsigned int aufs_poll(struct file *file, poll_table *wait)
25052+{
25053+ unsigned int mask;
25054+ int err;
25055+ struct file *h_file;
25056+ struct dentry *dentry;
25057+ struct super_block *sb;
25058+
25059+ /* We should pretend an error happened. */
25060+ mask = POLLERR /* | POLLIN | POLLOUT */;
25061+ dentry = file->f_dentry;
25062+ sb = dentry->d_sb;
e49829fe 25063+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
1308ab2a 25064+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0);
25065+ if (unlikely(err))
25066+ goto out;
25067+
25068+ /* it is not an error if h_file has no operation */
25069+ mask = DEFAULT_POLLMASK;
4a4d8108 25070+ h_file = au_hf_top(file);
523b37e3 25071+ if (h_file->f_op->poll)
1308ab2a 25072+ mask = h_file->f_op->poll(h_file, wait);
25073+
25074+ di_read_unlock(dentry, AuLock_IR);
25075+ fi_read_unlock(file);
25076+
4f0767ce 25077+out:
1308ab2a 25078+ si_read_unlock(sb);
25079+ AuTraceErr((int)mask);
25080+ return mask;
25081+}
c1595e42
JR
25082diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c
25083--- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100
25084+++ linux/fs/aufs/posix_acl.c 2015-01-25 13:00:38.634380408 +0100
25085@@ -0,0 +1,99 @@
25086+/*
25087+ * Copyright (C) 2014 Junjiro R. Okajima
25088+ *
25089+ * This program, aufs is free software; you can redistribute it and/or modify
25090+ * it under the terms of the GNU General Public License as published by
25091+ * the Free Software Foundation; either version 2 of the License, or
25092+ * (at your option) any later version.
25093+ *
25094+ * This program is distributed in the hope that it will be useful,
25095+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25096+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25097+ * GNU General Public License for more details.
25098+ *
25099+ * You should have received a copy of the GNU General Public License
25100+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25101+ */
25102+
25103+/*
25104+ * posix acl operations
25105+ */
25106+
25107+#include <linux/fs.h>
25108+#include <linux/posix_acl.h>
25109+#include "aufs.h"
25110+
25111+struct posix_acl *aufs_get_acl(struct inode *inode, int type)
25112+{
25113+ struct posix_acl *acl;
25114+ int err;
25115+ aufs_bindex_t bindex;
25116+ struct inode *h_inode;
25117+ struct super_block *sb;
25118+
25119+ acl = NULL;
25120+ sb = inode->i_sb;
25121+ si_read_lock(sb, AuLock_FLUSH);
25122+ ii_read_lock_child(inode);
25123+ if (!(sb->s_flags & MS_POSIXACL))
25124+ goto out;
25125+
25126+ bindex = au_ibstart(inode);
25127+ h_inode = au_h_iptr(inode, bindex);
25128+ if (unlikely(!h_inode
25129+ || ((h_inode->i_mode & S_IFMT)
25130+ != (inode->i_mode & S_IFMT)))) {
25131+ err = au_busy_or_stale();
25132+ acl = ERR_PTR(err);
25133+ goto out;
25134+ }
25135+
25136+ /* always topmost only */
25137+ acl = get_acl(h_inode, type);
25138+
25139+out:
25140+ ii_read_unlock(inode);
25141+ si_read_unlock(sb);
25142+
25143+ AuTraceErrPtr(acl);
25144+ return acl;
25145+}
25146+
25147+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
25148+{
25149+ int err;
25150+ ssize_t ssz;
25151+ struct dentry *dentry;
25152+ struct au_srxattr arg = {
25153+ .type = AU_ACL_SET,
25154+ .u.acl_set = {
25155+ .acl = acl,
25156+ .type = type
25157+ },
25158+ };
25159+
25160+ mutex_lock(&inode->i_mutex);
25161+ if (inode->i_ino == AUFS_ROOT_INO)
25162+ dentry = dget(inode->i_sb->s_root);
25163+ else {
25164+ dentry = d_find_alias(inode);
25165+ if (!dentry)
25166+ dentry = d_find_any_alias(inode);
25167+ if (!dentry) {
25168+ pr_warn("cannot handle this inode, "
25169+ "please report to aufs-users ML\n");
25170+ err = -ENOENT;
25171+ goto out;
25172+ }
25173+ }
25174+
25175+ ssz = au_srxattr(dentry, &arg);
25176+ dput(dentry);
25177+ err = ssz;
25178+ if (ssz >= 0)
25179+ err = 0;
25180+
25181+out:
25182+ mutex_unlock(&inode->i_mutex);
25183+ return err;
25184+}
7f207e10
AM
25185diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c
25186--- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 25187+++ linux/fs/aufs/procfs.c 2015-01-25 13:00:38.634380408 +0100
523b37e3 25188@@ -0,0 +1,169 @@
e49829fe 25189+/*
523b37e3 25190+ * Copyright (C) 2010-2014 Junjiro R. Okajima
e49829fe
JR
25191+ *
25192+ * This program, aufs is free software; you can redistribute it and/or modify
25193+ * it under the terms of the GNU General Public License as published by
25194+ * the Free Software Foundation; either version 2 of the License, or
25195+ * (at your option) any later version.
25196+ *
25197+ * This program is distributed in the hope that it will be useful,
25198+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25199+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25200+ * GNU General Public License for more details.
25201+ *
25202+ * You should have received a copy of the GNU General Public License
523b37e3 25203+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
e49829fe
JR
25204+ */
25205+
25206+/*
25207+ * procfs interfaces
25208+ */
25209+
25210+#include <linux/proc_fs.h>
25211+#include "aufs.h"
25212+
25213+static int au_procfs_plm_release(struct inode *inode, struct file *file)
25214+{
25215+ struct au_sbinfo *sbinfo;
25216+
25217+ sbinfo = file->private_data;
25218+ if (sbinfo) {
25219+ au_plink_maint_leave(sbinfo);
25220+ kobject_put(&sbinfo->si_kobj);
25221+ }
25222+
25223+ return 0;
25224+}
25225+
25226+static void au_procfs_plm_write_clean(struct file *file)
25227+{
25228+ struct au_sbinfo *sbinfo;
25229+
25230+ sbinfo = file->private_data;
25231+ if (sbinfo)
25232+ au_plink_clean(sbinfo->si_sb, /*verbose*/0);
25233+}
25234+
25235+static int au_procfs_plm_write_si(struct file *file, unsigned long id)
25236+{
25237+ int err;
25238+ struct super_block *sb;
25239+ struct au_sbinfo *sbinfo;
25240+
25241+ err = -EBUSY;
25242+ if (unlikely(file->private_data))
25243+ goto out;
25244+
25245+ sb = NULL;
53392da6 25246+ /* don't use au_sbilist_lock() here */
e49829fe
JR
25247+ spin_lock(&au_sbilist.spin);
25248+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
25249+ if (id == sysaufs_si_id(sbinfo)) {
25250+ kobject_get(&sbinfo->si_kobj);
25251+ sb = sbinfo->si_sb;
25252+ break;
25253+ }
25254+ spin_unlock(&au_sbilist.spin);
25255+
25256+ err = -EINVAL;
25257+ if (unlikely(!sb))
25258+ goto out;
25259+
25260+ err = au_plink_maint_enter(sb);
25261+ if (!err)
25262+ /* keep kobject_get() */
25263+ file->private_data = sbinfo;
25264+ else
25265+ kobject_put(&sbinfo->si_kobj);
25266+out:
25267+ return err;
25268+}
25269+
25270+/*
25271+ * Accept a valid "si=xxxx" only.
25272+ * Once it is accepted successfully, accept "clean" too.
25273+ */
25274+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf,
25275+ size_t count, loff_t *ppos)
25276+{
25277+ ssize_t err;
25278+ unsigned long id;
25279+ /* last newline is allowed */
25280+ char buf[3 + sizeof(unsigned long) * 2 + 1];
25281+
25282+ err = -EACCES;
25283+ if (unlikely(!capable(CAP_SYS_ADMIN)))
25284+ goto out;
25285+
25286+ err = -EINVAL;
25287+ if (unlikely(count > sizeof(buf)))
25288+ goto out;
25289+
25290+ err = copy_from_user(buf, ubuf, count);
25291+ if (unlikely(err)) {
25292+ err = -EFAULT;
25293+ goto out;
25294+ }
25295+ buf[count] = 0;
25296+
25297+ err = -EINVAL;
25298+ if (!strcmp("clean", buf)) {
25299+ au_procfs_plm_write_clean(file);
25300+ goto out_success;
25301+ } else if (unlikely(strncmp("si=", buf, 3)))
25302+ goto out;
25303+
9dbd164d 25304+ err = kstrtoul(buf + 3, 16, &id);
e49829fe
JR
25305+ if (unlikely(err))
25306+ goto out;
25307+
25308+ err = au_procfs_plm_write_si(file, id);
25309+ if (unlikely(err))
25310+ goto out;
25311+
25312+out_success:
25313+ err = count; /* success */
25314+out:
25315+ return err;
25316+}
25317+
25318+static const struct file_operations au_procfs_plm_fop = {
25319+ .write = au_procfs_plm_write,
25320+ .release = au_procfs_plm_release,
25321+ .owner = THIS_MODULE
25322+};
25323+
25324+/* ---------------------------------------------------------------------- */
25325+
25326+static struct proc_dir_entry *au_procfs_dir;
25327+
25328+void au_procfs_fin(void)
25329+{
25330+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir);
25331+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
25332+}
25333+
25334+int __init au_procfs_init(void)
25335+{
25336+ int err;
25337+ struct proc_dir_entry *entry;
25338+
25339+ err = -ENOMEM;
25340+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL);
25341+ if (unlikely(!au_procfs_dir))
25342+ goto out;
25343+
25344+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR,
25345+ au_procfs_dir, &au_procfs_plm_fop);
25346+ if (unlikely(!entry))
25347+ goto out_dir;
25348+
25349+ err = 0;
25350+ goto out; /* success */
25351+
25352+
25353+out_dir:
25354+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL);
25355+out:
25356+ return err;
25357+}
7f207e10
AM
25358diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c
25359--- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 25360+++ linux/fs/aufs/rdu.c 2015-01-25 13:00:38.634380408 +0100
523b37e3 25361@@ -0,0 +1,388 @@
1308ab2a 25362+/*
523b37e3 25363+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1308ab2a 25364+ *
25365+ * This program, aufs is free software; you can redistribute it and/or modify
25366+ * it under the terms of the GNU General Public License as published by
25367+ * the Free Software Foundation; either version 2 of the License, or
25368+ * (at your option) any later version.
25369+ *
25370+ * This program is distributed in the hope that it will be useful,
25371+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25372+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25373+ * GNU General Public License for more details.
25374+ *
25375+ * You should have received a copy of the GNU General Public License
523b37e3 25376+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1308ab2a 25377+ */
25378+
25379+/*
25380+ * readdir in userspace.
25381+ */
25382+
b752ccd1 25383+#include <linux/compat.h>
4a4d8108 25384+#include <linux/fs_stack.h>
1308ab2a 25385+#include <linux/security.h>
1308ab2a 25386+#include "aufs.h"
25387+
25388+/* bits for struct aufs_rdu.flags */
25389+#define AuRdu_CALLED 1
25390+#define AuRdu_CONT (1 << 1)
25391+#define AuRdu_FULL (1 << 2)
25392+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name)
7f207e10
AM
25393+#define au_fset_rdu(flags, name) \
25394+ do { (flags) |= AuRdu_##name; } while (0)
25395+#define au_fclr_rdu(flags, name) \
25396+ do { (flags) &= ~AuRdu_##name; } while (0)
1308ab2a 25397+
25398+struct au_rdu_arg {
392086de 25399+ struct dir_context ctx;
1308ab2a 25400+ struct aufs_rdu *rdu;
25401+ union au_rdu_ent_ul ent;
25402+ unsigned long end;
25403+
25404+ struct super_block *sb;
25405+ int err;
25406+};
25407+
392086de 25408+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen,
1308ab2a 25409+ loff_t offset, u64 h_ino, unsigned int d_type)
25410+{
25411+ int err, len;
392086de 25412+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx);
1308ab2a 25413+ struct aufs_rdu *rdu = arg->rdu;
25414+ struct au_rdu_ent ent;
25415+
25416+ err = 0;
25417+ arg->err = 0;
25418+ au_fset_rdu(rdu->cookie.flags, CALLED);
25419+ len = au_rdu_len(nlen);
25420+ if (arg->ent.ul + len < arg->end) {
25421+ ent.ino = h_ino;
25422+ ent.bindex = rdu->cookie.bindex;
25423+ ent.type = d_type;
25424+ ent.nlen = nlen;
4a4d8108
AM
25425+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
25426+ ent.type = DT_UNKNOWN;
1308ab2a 25427+
9dbd164d 25428+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25429+ err = -EFAULT;
25430+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent)))
25431+ goto out;
25432+ if (copy_to_user(arg->ent.e->name, name, nlen))
25433+ goto out;
25434+ /* the terminating NULL */
25435+ if (__put_user(0, arg->ent.e->name + nlen))
25436+ goto out;
25437+ err = 0;
25438+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */
25439+ arg->ent.ul += len;
25440+ rdu->rent++;
25441+ } else {
25442+ err = -EFAULT;
25443+ au_fset_rdu(rdu->cookie.flags, FULL);
25444+ rdu->full = 1;
25445+ rdu->tail = arg->ent;
25446+ }
25447+
4f0767ce 25448+out:
1308ab2a 25449+ /* AuTraceErr(err); */
25450+ return err;
25451+}
25452+
25453+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg)
25454+{
25455+ int err;
25456+ loff_t offset;
25457+ struct au_rdu_cookie *cookie = &arg->rdu->cookie;
25458+
92d182d2 25459+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */
1308ab2a 25460+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET);
25461+ err = offset;
25462+ if (unlikely(offset != cookie->h_pos))
25463+ goto out;
25464+
25465+ err = 0;
25466+ do {
25467+ arg->err = 0;
25468+ au_fclr_rdu(cookie->flags, CALLED);
25469+ /* smp_mb(); */
392086de 25470+ err = vfsub_iterate_dir(h_file, &arg->ctx);
1308ab2a 25471+ if (err >= 0)
25472+ err = arg->err;
25473+ } while (!err
25474+ && au_ftest_rdu(cookie->flags, CALLED)
25475+ && !au_ftest_rdu(cookie->flags, FULL));
25476+ cookie->h_pos = h_file->f_pos;
25477+
4f0767ce 25478+out:
1308ab2a 25479+ AuTraceErr(err);
25480+ return err;
25481+}
25482+
25483+static int au_rdu(struct file *file, struct aufs_rdu *rdu)
25484+{
25485+ int err;
25486+ aufs_bindex_t bend;
392086de
AM
25487+ struct au_rdu_arg arg = {
25488+ .ctx = {
25489+ .actor = au_diractor(au_rdu_fill)
25490+ }
25491+ };
1308ab2a 25492+ struct dentry *dentry;
25493+ struct inode *inode;
25494+ struct file *h_file;
25495+ struct au_rdu_cookie *cookie = &rdu->cookie;
25496+
25497+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz);
25498+ if (unlikely(err)) {
25499+ err = -EFAULT;
25500+ AuTraceErr(err);
25501+ goto out;
25502+ }
25503+ rdu->rent = 0;
25504+ rdu->tail = rdu->ent;
25505+ rdu->full = 0;
25506+ arg.rdu = rdu;
25507+ arg.ent = rdu->ent;
25508+ arg.end = arg.ent.ul;
25509+ arg.end += rdu->sz;
25510+
25511+ err = -ENOTDIR;
523b37e3 25512+ if (unlikely(!file->f_op->iterate))
1308ab2a 25513+ goto out;
25514+
25515+ err = security_file_permission(file, MAY_READ);
25516+ AuTraceErr(err);
25517+ if (unlikely(err))
25518+ goto out;
25519+
25520+ dentry = file->f_dentry;
25521+ inode = dentry->d_inode;
25522+#if 1
25523+ mutex_lock(&inode->i_mutex);
25524+#else
25525+ err = mutex_lock_killable(&inode->i_mutex);
25526+ AuTraceErr(err);
25527+ if (unlikely(err))
25528+ goto out;
25529+#endif
1308ab2a 25530+
25531+ arg.sb = inode->i_sb;
e49829fe
JR
25532+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM);
25533+ if (unlikely(err))
25534+ goto out_mtx;
027c5e7a
AM
25535+ err = au_alive_dir(dentry);
25536+ if (unlikely(err))
25537+ goto out_si;
e49829fe 25538+ /* todo: reval? */
1308ab2a 25539+ fi_read_lock(file);
25540+
25541+ err = -EAGAIN;
25542+ if (unlikely(au_ftest_rdu(cookie->flags, CONT)
25543+ && cookie->generation != au_figen(file)))
25544+ goto out_unlock;
25545+
25546+ err = 0;
25547+ if (!rdu->blk) {
25548+ rdu->blk = au_sbi(arg.sb)->si_rdblk;
25549+ if (!rdu->blk)
25550+ rdu->blk = au_dir_size(file, /*dentry*/NULL);
25551+ }
25552+ bend = au_fbstart(file);
25553+ if (cookie->bindex < bend)
25554+ cookie->bindex = bend;
4a4d8108 25555+ bend = au_fbend_dir(file);
1308ab2a 25556+ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */
25557+ for (; !err && cookie->bindex <= bend;
25558+ cookie->bindex++, cookie->h_pos = 0) {
4a4d8108 25559+ h_file = au_hf_dir(file, cookie->bindex);
1308ab2a 25560+ if (!h_file)
25561+ continue;
25562+
25563+ au_fclr_rdu(cookie->flags, FULL);
25564+ err = au_rdu_do(h_file, &arg);
25565+ AuTraceErr(err);
25566+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err))
25567+ break;
25568+ }
25569+ AuDbg("rent %llu\n", rdu->rent);
25570+
25571+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) {
25572+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH);
25573+ au_fset_rdu(cookie->flags, CONT);
25574+ cookie->generation = au_figen(file);
25575+ }
25576+
25577+ ii_read_lock_child(inode);
25578+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
25579+ ii_read_unlock(inode);
25580+
4f0767ce 25581+out_unlock:
1308ab2a 25582+ fi_read_unlock(file);
027c5e7a 25583+out_si:
1308ab2a 25584+ si_read_unlock(arg.sb);
4f0767ce 25585+out_mtx:
1308ab2a 25586+ mutex_unlock(&inode->i_mutex);
4f0767ce 25587+out:
1308ab2a 25588+ AuTraceErr(err);
25589+ return err;
25590+}
25591+
25592+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu)
25593+{
25594+ int err;
25595+ ino_t ino;
25596+ unsigned long long nent;
25597+ union au_rdu_ent_ul *u;
25598+ struct au_rdu_ent ent;
25599+ struct super_block *sb;
25600+
25601+ err = 0;
25602+ nent = rdu->nent;
25603+ u = &rdu->ent;
25604+ sb = file->f_dentry->d_sb;
25605+ si_read_lock(sb, AuLock_FLUSH);
25606+ while (nent-- > 0) {
9dbd164d 25607+ /* unnecessary to support mmap_sem since this is a dir */
1308ab2a 25608+ err = copy_from_user(&ent, u->e, sizeof(ent));
4a4d8108
AM
25609+ if (!err)
25610+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino));
1308ab2a 25611+ if (unlikely(err)) {
25612+ err = -EFAULT;
25613+ AuTraceErr(err);
25614+ break;
25615+ }
25616+
25617+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */
25618+ if (!ent.wh)
25619+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino);
25620+ else
25621+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type,
25622+ &ino);
25623+ if (unlikely(err)) {
25624+ AuTraceErr(err);
25625+ break;
25626+ }
25627+
25628+ err = __put_user(ino, &u->e->ino);
25629+ if (unlikely(err)) {
25630+ err = -EFAULT;
25631+ AuTraceErr(err);
25632+ break;
25633+ }
25634+ u->ul += au_rdu_len(ent.nlen);
25635+ }
25636+ si_read_unlock(sb);
25637+
25638+ return err;
25639+}
25640+
25641+/* ---------------------------------------------------------------------- */
25642+
25643+static int au_rdu_verify(struct aufs_rdu *rdu)
25644+{
b752ccd1 25645+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | "
1308ab2a 25646+ "%llu, b%d, 0x%x, g%u}\n",
b752ccd1 25647+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ],
1308ab2a 25648+ rdu->blk,
25649+ rdu->rent, rdu->shwh, rdu->full,
25650+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags,
25651+ rdu->cookie.generation);
dece6358 25652+
b752ccd1 25653+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu))
1308ab2a 25654+ return 0;
dece6358 25655+
b752ccd1
AM
25656+ AuDbg("%u:%u\n",
25657+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu));
1308ab2a 25658+ return -EINVAL;
25659+}
25660+
25661+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dece6358 25662+{
1308ab2a 25663+ long err, e;
25664+ struct aufs_rdu rdu;
25665+ void __user *p = (void __user *)arg;
dece6358 25666+
1308ab2a 25667+ err = copy_from_user(&rdu, p, sizeof(rdu));
25668+ if (unlikely(err)) {
25669+ err = -EFAULT;
25670+ AuTraceErr(err);
25671+ goto out;
25672+ }
25673+ err = au_rdu_verify(&rdu);
dece6358
AM
25674+ if (unlikely(err))
25675+ goto out;
25676+
1308ab2a 25677+ switch (cmd) {
25678+ case AUFS_CTL_RDU:
25679+ err = au_rdu(file, &rdu);
25680+ if (unlikely(err))
25681+ break;
dece6358 25682+
1308ab2a 25683+ e = copy_to_user(p, &rdu, sizeof(rdu));
25684+ if (unlikely(e)) {
25685+ err = -EFAULT;
25686+ AuTraceErr(err);
25687+ }
25688+ break;
25689+ case AUFS_CTL_RDU_INO:
25690+ err = au_rdu_ino(file, &rdu);
25691+ break;
25692+
25693+ default:
4a4d8108 25694+ /* err = -ENOTTY; */
1308ab2a 25695+ err = -EINVAL;
25696+ }
dece6358 25697+
4f0767ce 25698+out:
1308ab2a 25699+ AuTraceErr(err);
25700+ return err;
1facf9fc 25701+}
b752ccd1
AM
25702+
25703+#ifdef CONFIG_COMPAT
25704+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
25705+{
25706+ long err, e;
25707+ struct aufs_rdu rdu;
25708+ void __user *p = compat_ptr(arg);
25709+
25710+ /* todo: get_user()? */
25711+ err = copy_from_user(&rdu, p, sizeof(rdu));
25712+ if (unlikely(err)) {
25713+ err = -EFAULT;
25714+ AuTraceErr(err);
25715+ goto out;
25716+ }
25717+ rdu.ent.e = compat_ptr(rdu.ent.ul);
25718+ err = au_rdu_verify(&rdu);
25719+ if (unlikely(err))
25720+ goto out;
25721+
25722+ switch (cmd) {
25723+ case AUFS_CTL_RDU:
25724+ err = au_rdu(file, &rdu);
25725+ if (unlikely(err))
25726+ break;
25727+
25728+ rdu.ent.ul = ptr_to_compat(rdu.ent.e);
25729+ rdu.tail.ul = ptr_to_compat(rdu.tail.e);
25730+ e = copy_to_user(p, &rdu, sizeof(rdu));
25731+ if (unlikely(e)) {
25732+ err = -EFAULT;
25733+ AuTraceErr(err);
25734+ }
25735+ break;
25736+ case AUFS_CTL_RDU_INO:
25737+ err = au_rdu_ino(file, &rdu);
25738+ break;
25739+
25740+ default:
25741+ /* err = -ENOTTY; */
25742+ err = -EINVAL;
25743+ }
25744+
4f0767ce 25745+out:
b752ccd1
AM
25746+ AuTraceErr(err);
25747+ return err;
25748+}
25749+#endif
7f207e10
AM
25750diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h
25751--- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 25752+++ linux/fs/aufs/rwsem.h 2015-01-25 13:00:38.634380408 +0100
076b876e 25753@@ -0,0 +1,191 @@
1facf9fc 25754+/*
523b37e3 25755+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25756+ *
25757+ * This program, aufs is free software; you can redistribute it and/or modify
25758+ * it under the terms of the GNU General Public License as published by
25759+ * the Free Software Foundation; either version 2 of the License, or
25760+ * (at your option) any later version.
dece6358
AM
25761+ *
25762+ * This program is distributed in the hope that it will be useful,
25763+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25764+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25765+ * GNU General Public License for more details.
25766+ *
25767+ * You should have received a copy of the GNU General Public License
523b37e3 25768+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25769+ */
25770+
25771+/*
25772+ * simple read-write semaphore wrappers
25773+ */
25774+
25775+#ifndef __AUFS_RWSEM_H__
25776+#define __AUFS_RWSEM_H__
25777+
25778+#ifdef __KERNEL__
25779+
4a4d8108 25780+#include "debug.h"
dece6358
AM
25781+
25782+struct au_rwsem {
25783+ struct rw_semaphore rwsem;
25784+#ifdef CONFIG_AUFS_DEBUG
25785+ /* just for debugging, not almighty counter */
25786+ atomic_t rcnt, wcnt;
25787+#endif
25788+};
25789+
25790+#ifdef CONFIG_AUFS_DEBUG
25791+#define AuDbgCntInit(rw) do { \
25792+ atomic_set(&(rw)->rcnt, 0); \
25793+ atomic_set(&(rw)->wcnt, 0); \
25794+ smp_mb(); /* atomic set */ \
25795+} while (0)
25796+
e49829fe 25797+#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt)
dece6358 25798+#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0)
e49829fe 25799+#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt)
dece6358
AM
25800+#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0)
25801+#else
25802+#define AuDbgCntInit(rw) do {} while (0)
25803+#define AuDbgRcntInc(rw) do {} while (0)
25804+#define AuDbgRcntDec(rw) do {} while (0)
25805+#define AuDbgWcntInc(rw) do {} while (0)
25806+#define AuDbgWcntDec(rw) do {} while (0)
25807+#endif /* CONFIG_AUFS_DEBUG */
25808+
25809+/* to debug easier, do not make them inlined functions */
25810+#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list))
25811+/* rwsem_is_locked() is unusable */
25812+#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0)
25813+#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0)
25814+#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \
25815+ && atomic_read(&(rw)->wcnt) <= 0)
25816+#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \
25817+ || atomic_read(&(rw)->wcnt))
25818+
e49829fe
JR
25819+#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key)
25820+
dece6358
AM
25821+static inline void au_rw_init(struct au_rwsem *rw)
25822+{
25823+ AuDbgCntInit(rw);
25824+ init_rwsem(&rw->rwsem);
25825+}
25826+
25827+static inline void au_rw_init_wlock(struct au_rwsem *rw)
25828+{
25829+ au_rw_init(rw);
25830+ down_write(&rw->rwsem);
25831+ AuDbgWcntInc(rw);
25832+}
25833+
25834+static inline void au_rw_init_wlock_nested(struct au_rwsem *rw,
25835+ unsigned int lsc)
25836+{
25837+ au_rw_init(rw);
25838+ down_write_nested(&rw->rwsem, lsc);
25839+ AuDbgWcntInc(rw);
25840+}
25841+
25842+static inline void au_rw_read_lock(struct au_rwsem *rw)
25843+{
25844+ down_read(&rw->rwsem);
25845+ AuDbgRcntInc(rw);
25846+}
25847+
25848+static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc)
25849+{
25850+ down_read_nested(&rw->rwsem, lsc);
25851+ AuDbgRcntInc(rw);
25852+}
25853+
25854+static inline void au_rw_read_unlock(struct au_rwsem *rw)
25855+{
25856+ AuRwMustReadLock(rw);
25857+ AuDbgRcntDec(rw);
25858+ up_read(&rw->rwsem);
25859+}
25860+
25861+static inline void au_rw_dgrade_lock(struct au_rwsem *rw)
25862+{
25863+ AuRwMustWriteLock(rw);
25864+ AuDbgRcntInc(rw);
25865+ AuDbgWcntDec(rw);
25866+ downgrade_write(&rw->rwsem);
25867+}
25868+
25869+static inline void au_rw_write_lock(struct au_rwsem *rw)
25870+{
25871+ down_write(&rw->rwsem);
25872+ AuDbgWcntInc(rw);
25873+}
25874+
25875+static inline void au_rw_write_lock_nested(struct au_rwsem *rw,
25876+ unsigned int lsc)
25877+{
25878+ down_write_nested(&rw->rwsem, lsc);
25879+ AuDbgWcntInc(rw);
25880+}
1facf9fc 25881+
dece6358
AM
25882+static inline void au_rw_write_unlock(struct au_rwsem *rw)
25883+{
25884+ AuRwMustWriteLock(rw);
25885+ AuDbgWcntDec(rw);
25886+ up_write(&rw->rwsem);
25887+}
25888+
25889+/* why is not _nested version defined */
25890+static inline int au_rw_read_trylock(struct au_rwsem *rw)
25891+{
076b876e
AM
25892+ int ret;
25893+
25894+ ret = down_read_trylock(&rw->rwsem);
dece6358
AM
25895+ if (ret)
25896+ AuDbgRcntInc(rw);
25897+ return ret;
25898+}
25899+
25900+static inline int au_rw_write_trylock(struct au_rwsem *rw)
25901+{
076b876e
AM
25902+ int ret;
25903+
25904+ ret = down_write_trylock(&rw->rwsem);
dece6358
AM
25905+ if (ret)
25906+ AuDbgWcntInc(rw);
25907+ return ret;
25908+}
25909+
25910+#undef AuDbgCntInit
25911+#undef AuDbgRcntInc
25912+#undef AuDbgRcntDec
25913+#undef AuDbgWcntInc
25914+#undef AuDbgWcntDec
1facf9fc 25915+
25916+#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
25917+static inline void prefix##_read_lock(param) \
dece6358 25918+{ au_rw_read_lock(rwsem); } \
1facf9fc 25919+static inline void prefix##_write_lock(param) \
dece6358 25920+{ au_rw_write_lock(rwsem); } \
1facf9fc 25921+static inline int prefix##_read_trylock(param) \
dece6358 25922+{ return au_rw_read_trylock(rwsem); } \
1facf9fc 25923+static inline int prefix##_write_trylock(param) \
dece6358 25924+{ return au_rw_write_trylock(rwsem); }
1facf9fc 25925+/* why is not _nested version defined */
25926+/* static inline void prefix##_read_trylock_nested(param, lsc)
dece6358 25927+{ au_rw_read_trylock_nested(rwsem, lsc)); }
1facf9fc 25928+static inline void prefix##_write_trylock_nestd(param, lsc)
dece6358 25929+{ au_rw_write_trylock_nested(rwsem, lsc); } */
1facf9fc 25930+
25931+#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \
25932+static inline void prefix##_read_unlock(param) \
dece6358 25933+{ au_rw_read_unlock(rwsem); } \
1facf9fc 25934+static inline void prefix##_write_unlock(param) \
dece6358 25935+{ au_rw_write_unlock(rwsem); } \
1facf9fc 25936+static inline void prefix##_downgrade_lock(param) \
dece6358 25937+{ au_rw_dgrade_lock(rwsem); }
1facf9fc 25938+
25939+#define AuSimpleRwsemFuncs(prefix, param, rwsem) \
25940+ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \
25941+ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem)
25942+
25943+#endif /* __KERNEL__ */
25944+#endif /* __AUFS_RWSEM_H__ */
7f207e10
AM
25945diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
25946--- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 25947+++ linux/fs/aufs/sbinfo.c 2015-01-25 13:00:38.634380408 +0100
076b876e 25948@@ -0,0 +1,353 @@
1facf9fc 25949+/*
523b37e3 25950+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 25951+ *
25952+ * This program, aufs is free software; you can redistribute it and/or modify
25953+ * it under the terms of the GNU General Public License as published by
25954+ * the Free Software Foundation; either version 2 of the License, or
25955+ * (at your option) any later version.
dece6358
AM
25956+ *
25957+ * This program is distributed in the hope that it will be useful,
25958+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25959+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25960+ * GNU General Public License for more details.
25961+ *
25962+ * You should have received a copy of the GNU General Public License
523b37e3 25963+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 25964+ */
25965+
25966+/*
25967+ * superblock private data
25968+ */
25969+
25970+#include "aufs.h"
25971+
25972+/*
25973+ * they are necessary regardless sysfs is disabled.
25974+ */
25975+void au_si_free(struct kobject *kobj)
25976+{
86dc4139 25977+ int i;
1facf9fc 25978+ struct au_sbinfo *sbinfo;
b752ccd1 25979+ char *locked __maybe_unused; /* debug only */
1facf9fc 25980+
25981+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
86dc4139
AM
25982+ for (i = 0; i < AuPlink_NHASH; i++)
25983+ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
e49829fe 25984+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
1facf9fc 25985+
e49829fe 25986+ au_rw_write_lock(&sbinfo->si_rwsem);
1facf9fc 25987+ au_br_free(sbinfo);
e49829fe 25988+ au_rw_write_unlock(&sbinfo->si_rwsem);
b752ccd1
AM
25989+
25990+ AuDebugOn(radix_tree_gang_lookup
25991+ (&sbinfo->au_si_pid.tree, (void **)&locked,
25992+ /*first_index*/PID_MAX_DEFAULT - 1,
25993+ /*max_items*/sizeof(locked)/sizeof(*locked)));
25994+
1facf9fc 25995+ kfree(sbinfo->si_branch);
b752ccd1 25996+ kfree(sbinfo->au_si_pid.bitmap);
1facf9fc 25997+ mutex_destroy(&sbinfo->si_xib_mtx);
dece6358 25998+ AuRwDestroy(&sbinfo->si_rwsem);
1facf9fc 25999+
26000+ kfree(sbinfo);
26001+}
26002+
26003+int au_si_alloc(struct super_block *sb)
26004+{
86dc4139 26005+ int err, i;
1facf9fc 26006+ struct au_sbinfo *sbinfo;
e49829fe 26007+ static struct lock_class_key aufs_si;
1facf9fc 26008+
26009+ err = -ENOMEM;
4a4d8108 26010+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS);
1facf9fc 26011+ if (unlikely(!sbinfo))
26012+ goto out;
26013+
b752ccd1
AM
26014+ BUILD_BUG_ON(sizeof(unsigned long) !=
26015+ sizeof(*sbinfo->au_si_pid.bitmap));
26016+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT),
26017+ sizeof(*sbinfo->au_si_pid.bitmap),
26018+ GFP_NOFS);
26019+ if (unlikely(!sbinfo->au_si_pid.bitmap))
26020+ goto out_sbinfo;
26021+
1facf9fc 26022+ /* will be reallocated separately */
26023+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS);
26024+ if (unlikely(!sbinfo->si_branch))
b752ccd1 26025+ goto out_pidmap;
1facf9fc 26026+
1facf9fc 26027+ err = sysaufs_si_init(sbinfo);
26028+ if (unlikely(err))
26029+ goto out_br;
26030+
26031+ au_nwt_init(&sbinfo->si_nowait);
dece6358 26032+ au_rw_init_wlock(&sbinfo->si_rwsem);
e49829fe 26033+ au_rw_class(&sbinfo->si_rwsem, &aufs_si);
b752ccd1
AM
26034+ spin_lock_init(&sbinfo->au_si_pid.tree_lock);
26035+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL);
26036+
7f207e10 26037+ atomic_long_set(&sbinfo->si_ninodes, 0);
7f207e10
AM
26038+ atomic_long_set(&sbinfo->si_nfiles, 0);
26039+
1facf9fc 26040+ sbinfo->si_bend = -1;
392086de 26041+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2;
1facf9fc 26042+
26043+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def;
26044+ sbinfo->si_wbr_create = AuWbrCreate_Def;
4a4d8108
AM
26045+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup;
26046+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create;
1facf9fc 26047+
076b876e
AM
26048+ au_fhsm_init(sbinfo);
26049+
e49829fe 26050+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def);
1facf9fc 26051+
392086de
AM
26052+ sbinfo->si_xino_jiffy = jiffies;
26053+ sbinfo->si_xino_expire
26054+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC);
1facf9fc 26055+ mutex_init(&sbinfo->si_xib_mtx);
1facf9fc 26056+ sbinfo->si_xino_brid = -1;
26057+ /* leave si_xib_last_pindex and si_xib_next_bit */
26058+
e49829fe 26059+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC);
1facf9fc 26060+ sbinfo->si_rdblk = AUFS_RDBLK_DEF;
26061+ sbinfo->si_rdhash = AUFS_RDHASH_DEF;
26062+ sbinfo->si_dirwh = AUFS_DIRWH_DEF;
26063+
86dc4139
AM
26064+ for (i = 0; i < AuPlink_NHASH; i++)
26065+ au_sphl_init(sbinfo->si_plink + i);
1facf9fc 26066+ init_waitqueue_head(&sbinfo->si_plink_wq);
4a4d8108 26067+ spin_lock_init(&sbinfo->si_plink_maint_lock);
1facf9fc 26068+
523b37e3
AM
26069+ au_sphl_init(&sbinfo->si_files);
26070+
1facf9fc 26071+ /* leave other members for sysaufs and si_mnt. */
26072+ sbinfo->si_sb = sb;
26073+ sb->s_fs_info = sbinfo;
b752ccd1 26074+ si_pid_set(sb);
1facf9fc 26075+ au_debug_sbinfo_init(sbinfo);
26076+ return 0; /* success */
26077+
4f0767ce 26078+out_br:
1facf9fc 26079+ kfree(sbinfo->si_branch);
4f0767ce 26080+out_pidmap:
b752ccd1 26081+ kfree(sbinfo->au_si_pid.bitmap);
4f0767ce 26082+out_sbinfo:
1facf9fc 26083+ kfree(sbinfo);
4f0767ce 26084+out:
1facf9fc 26085+ return err;
26086+}
26087+
26088+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr)
26089+{
26090+ int err, sz;
26091+ struct au_branch **brp;
26092+
dece6358
AM
26093+ AuRwMustWriteLock(&sbinfo->si_rwsem);
26094+
1facf9fc 26095+ err = -ENOMEM;
26096+ sz = sizeof(*brp) * (sbinfo->si_bend + 1);
26097+ if (unlikely(!sz))
26098+ sz = sizeof(*brp);
26099+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS);
26100+ if (brp) {
26101+ sbinfo->si_branch = brp;
26102+ err = 0;
26103+ }
26104+
26105+ return err;
26106+}
26107+
26108+/* ---------------------------------------------------------------------- */
26109+
26110+unsigned int au_sigen_inc(struct super_block *sb)
26111+{
26112+ unsigned int gen;
26113+
dece6358
AM
26114+ SiMustWriteLock(sb);
26115+
1facf9fc 26116+ gen = ++au_sbi(sb)->si_generation;
26117+ au_update_digen(sb->s_root);
537831f9 26118+ au_update_iigen(sb->s_root->d_inode, /*half*/0);
1facf9fc 26119+ sb->s_root->d_inode->i_version++;
26120+ return gen;
26121+}
26122+
26123+aufs_bindex_t au_new_br_id(struct super_block *sb)
26124+{
26125+ aufs_bindex_t br_id;
26126+ int i;
26127+ struct au_sbinfo *sbinfo;
26128+
dece6358
AM
26129+ SiMustWriteLock(sb);
26130+
1facf9fc 26131+ sbinfo = au_sbi(sb);
26132+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) {
26133+ br_id = ++sbinfo->si_last_br_id;
7f207e10 26134+ AuDebugOn(br_id < 0);
1facf9fc 26135+ if (br_id && au_br_index(sb, br_id) < 0)
26136+ return br_id;
26137+ }
26138+
26139+ return -1;
26140+}
26141+
26142+/* ---------------------------------------------------------------------- */
26143+
e49829fe
JR
26144+/* it is ok that new 'nwt' tasks are appended while we are sleeping */
26145+int si_read_lock(struct super_block *sb, int flags)
26146+{
26147+ int err;
26148+
26149+ err = 0;
26150+ if (au_ftest_lock(flags, FLUSH))
26151+ au_nwt_flush(&au_sbi(sb)->si_nowait);
26152+
26153+ si_noflush_read_lock(sb);
26154+ err = au_plink_maint(sb, flags);
26155+ if (unlikely(err))
26156+ si_read_unlock(sb);
26157+
26158+ return err;
26159+}
26160+
26161+int si_write_lock(struct super_block *sb, int flags)
26162+{
26163+ int err;
26164+
26165+ if (au_ftest_lock(flags, FLUSH))
26166+ au_nwt_flush(&au_sbi(sb)->si_nowait);
26167+
26168+ si_noflush_write_lock(sb);
26169+ err = au_plink_maint(sb, flags);
26170+ if (unlikely(err))
26171+ si_write_unlock(sb);
26172+
26173+ return err;
26174+}
26175+
1facf9fc 26176+/* dentry and super_block lock. call at entry point */
e49829fe 26177+int aufs_read_lock(struct dentry *dentry, int flags)
1facf9fc 26178+{
e49829fe 26179+ int err;
027c5e7a 26180+ struct super_block *sb;
e49829fe 26181+
027c5e7a
AM
26182+ sb = dentry->d_sb;
26183+ err = si_read_lock(sb, flags);
26184+ if (unlikely(err))
26185+ goto out;
26186+
26187+ if (au_ftest_lock(flags, DW))
26188+ di_write_lock_child(dentry);
26189+ else
26190+ di_read_lock_child(dentry, flags);
26191+
26192+ if (au_ftest_lock(flags, GEN)) {
26193+ err = au_digen_test(dentry, au_sigen(sb));
26194+ AuDebugOn(!err && au_dbrange_test(dentry));
26195+ if (unlikely(err))
26196+ aufs_read_unlock(dentry, flags);
e49829fe
JR
26197+ }
26198+
027c5e7a 26199+out:
e49829fe 26200+ return err;
1facf9fc 26201+}
26202+
26203+void aufs_read_unlock(struct dentry *dentry, int flags)
26204+{
26205+ if (au_ftest_lock(flags, DW))
26206+ di_write_unlock(dentry);
26207+ else
26208+ di_read_unlock(dentry, flags);
26209+ si_read_unlock(dentry->d_sb);
26210+}
26211+
26212+void aufs_write_lock(struct dentry *dentry)
26213+{
e49829fe 26214+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW);
1facf9fc 26215+ di_write_lock_child(dentry);
26216+}
26217+
26218+void aufs_write_unlock(struct dentry *dentry)
26219+{
26220+ di_write_unlock(dentry);
26221+ si_write_unlock(dentry->d_sb);
26222+}
26223+
e49829fe 26224+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags)
1facf9fc 26225+{
e49829fe 26226+ int err;
027c5e7a
AM
26227+ unsigned int sigen;
26228+ struct super_block *sb;
e49829fe 26229+
027c5e7a
AM
26230+ sb = d1->d_sb;
26231+ err = si_read_lock(sb, flags);
26232+ if (unlikely(err))
26233+ goto out;
26234+
26235+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR));
26236+
26237+ if (au_ftest_lock(flags, GEN)) {
26238+ sigen = au_sigen(sb);
26239+ err = au_digen_test(d1, sigen);
26240+ AuDebugOn(!err && au_dbrange_test(d1));
26241+ if (!err) {
26242+ err = au_digen_test(d2, sigen);
26243+ AuDebugOn(!err && au_dbrange_test(d2));
26244+ }
26245+ if (unlikely(err))
26246+ aufs_read_and_write_unlock2(d1, d2);
26247+ }
26248+
26249+out:
e49829fe 26250+ return err;
1facf9fc 26251+}
26252+
26253+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2)
26254+{
26255+ di_write_unlock2(d1, d2);
26256+ si_read_unlock(d1->d_sb);
26257+}
b752ccd1
AM
26258+
26259+/* ---------------------------------------------------------------------- */
26260+
26261+int si_pid_test_slow(struct super_block *sb)
26262+{
26263+ void *p;
26264+
26265+ rcu_read_lock();
26266+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid);
26267+ rcu_read_unlock();
26268+
027c5e7a 26269+ return (long)!!p;
b752ccd1
AM
26270+}
26271+
26272+void si_pid_set_slow(struct super_block *sb)
26273+{
26274+ int err;
26275+ struct au_sbinfo *sbinfo;
26276+
26277+ AuDebugOn(si_pid_test_slow(sb));
26278+
26279+ sbinfo = au_sbi(sb);
26280+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
26281+ AuDebugOn(err);
26282+ spin_lock(&sbinfo->au_si_pid.tree_lock);
26283+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid,
027c5e7a 26284+ /*any valid ptr*/sb);
b752ccd1
AM
26285+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
26286+ AuDebugOn(err);
26287+ radix_tree_preload_end();
26288+}
26289+
26290+void si_pid_clr_slow(struct super_block *sb)
26291+{
26292+ void *p;
26293+ struct au_sbinfo *sbinfo;
26294+
26295+ AuDebugOn(!si_pid_test_slow(sb));
26296+
26297+ sbinfo = au_sbi(sb);
26298+ spin_lock(&sbinfo->au_si_pid.tree_lock);
26299+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid);
26300+ spin_unlock(&sbinfo->au_si_pid.tree_lock);
b752ccd1 26301+}
7f207e10
AM
26302diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
26303--- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 26304+++ linux/fs/aufs/spl.h 2015-01-25 13:00:38.634380408 +0100
523b37e3 26305@@ -0,0 +1,111 @@
1facf9fc 26306+/*
523b37e3 26307+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26308+ *
26309+ * This program, aufs is free software; you can redistribute it and/or modify
26310+ * it under the terms of the GNU General Public License as published by
26311+ * the Free Software Foundation; either version 2 of the License, or
26312+ * (at your option) any later version.
dece6358
AM
26313+ *
26314+ * This program is distributed in the hope that it will be useful,
26315+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26316+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26317+ * GNU General Public License for more details.
26318+ *
26319+ * You should have received a copy of the GNU General Public License
523b37e3 26320+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26321+ */
26322+
26323+/*
26324+ * simple list protected by a spinlock
26325+ */
26326+
26327+#ifndef __AUFS_SPL_H__
26328+#define __AUFS_SPL_H__
26329+
26330+#ifdef __KERNEL__
26331+
1facf9fc 26332+struct au_splhead {
26333+ spinlock_t spin;
26334+ struct list_head head;
26335+};
26336+
26337+static inline void au_spl_init(struct au_splhead *spl)
26338+{
26339+ spin_lock_init(&spl->spin);
26340+ INIT_LIST_HEAD(&spl->head);
26341+}
26342+
26343+static inline void au_spl_add(struct list_head *list, struct au_splhead *spl)
26344+{
26345+ spin_lock(&spl->spin);
26346+ list_add(list, &spl->head);
26347+ spin_unlock(&spl->spin);
26348+}
26349+
26350+static inline void au_spl_del(struct list_head *list, struct au_splhead *spl)
26351+{
26352+ spin_lock(&spl->spin);
26353+ list_del(list);
26354+ spin_unlock(&spl->spin);
26355+}
26356+
4a4d8108
AM
26357+static inline void au_spl_del_rcu(struct list_head *list,
26358+ struct au_splhead *spl)
26359+{
26360+ spin_lock(&spl->spin);
26361+ list_del_rcu(list);
26362+ spin_unlock(&spl->spin);
26363+}
26364+
86dc4139
AM
26365+/* ---------------------------------------------------------------------- */
26366+
26367+struct au_sphlhead {
26368+ spinlock_t spin;
26369+ struct hlist_head head;
26370+};
26371+
26372+static inline void au_sphl_init(struct au_sphlhead *sphl)
26373+{
26374+ spin_lock_init(&sphl->spin);
26375+ INIT_HLIST_HEAD(&sphl->head);
26376+}
26377+
26378+static inline void au_sphl_add(struct hlist_node *hlist,
26379+ struct au_sphlhead *sphl)
26380+{
26381+ spin_lock(&sphl->spin);
26382+ hlist_add_head(hlist, &sphl->head);
26383+ spin_unlock(&sphl->spin);
26384+}
26385+
26386+static inline void au_sphl_del(struct hlist_node *hlist,
26387+ struct au_sphlhead *sphl)
26388+{
26389+ spin_lock(&sphl->spin);
26390+ hlist_del(hlist);
26391+ spin_unlock(&sphl->spin);
26392+}
26393+
26394+static inline void au_sphl_del_rcu(struct hlist_node *hlist,
26395+ struct au_sphlhead *sphl)
26396+{
26397+ spin_lock(&sphl->spin);
26398+ hlist_del_rcu(hlist);
26399+ spin_unlock(&sphl->spin);
26400+}
26401+
26402+static inline unsigned long au_sphl_count(struct au_sphlhead *sphl)
26403+{
26404+ unsigned long cnt;
26405+ struct hlist_node *pos;
26406+
26407+ cnt = 0;
26408+ spin_lock(&sphl->spin);
26409+ hlist_for_each(pos, &sphl->head)
26410+ cnt++;
26411+ spin_unlock(&sphl->spin);
26412+ return cnt;
26413+}
26414+
1facf9fc 26415+#endif /* __KERNEL__ */
26416+#endif /* __AUFS_SPL_H__ */
7f207e10
AM
26417diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
26418--- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
26419+++ linux/fs/aufs/super.c 2015-01-25 13:00:38.634380408 +0100
26420@@ -0,0 +1,1009 @@
1facf9fc 26421+/*
523b37e3 26422+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 26423+ *
26424+ * This program, aufs is free software; you can redistribute it and/or modify
26425+ * it under the terms of the GNU General Public License as published by
26426+ * the Free Software Foundation; either version 2 of the License, or
26427+ * (at your option) any later version.
dece6358
AM
26428+ *
26429+ * This program is distributed in the hope that it will be useful,
26430+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26431+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26432+ * GNU General Public License for more details.
26433+ *
26434+ * You should have received a copy of the GNU General Public License
523b37e3 26435+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 26436+ */
26437+
26438+/*
26439+ * mount and super_block operations
26440+ */
26441+
f6c5ef8b 26442+#include <linux/mm.h>
dece6358 26443+#include <linux/module.h>
1facf9fc 26444+#include <linux/seq_file.h>
26445+#include <linux/statfs.h>
7f207e10
AM
26446+#include <linux/vmalloc.h>
26447+#include <linux/writeback.h>
1facf9fc 26448+#include "aufs.h"
26449+
26450+/*
26451+ * super_operations
26452+ */
26453+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
26454+{
26455+ struct au_icntnr *c;
26456+
26457+ c = au_cache_alloc_icntnr();
26458+ if (c) {
027c5e7a 26459+ au_icntnr_init(c);
1facf9fc 26460+ c->vfs_inode.i_version = 1; /* sigen(sb); */
26461+ c->iinfo.ii_hinode = NULL;
26462+ return &c->vfs_inode;
26463+ }
26464+ return NULL;
26465+}
26466+
027c5e7a
AM
26467+static void aufs_destroy_inode_cb(struct rcu_head *head)
26468+{
26469+ struct inode *inode = container_of(head, struct inode, i_rcu);
26470+
b4510431 26471+ INIT_HLIST_HEAD(&inode->i_dentry);
027c5e7a
AM
26472+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
26473+}
26474+
1facf9fc 26475+static void aufs_destroy_inode(struct inode *inode)
26476+{
26477+ au_iinfo_fin(inode);
027c5e7a 26478+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
1facf9fc 26479+}
26480+
26481+struct inode *au_iget_locked(struct super_block *sb, ino_t ino)
26482+{
26483+ struct inode *inode;
26484+ int err;
26485+
26486+ inode = iget_locked(sb, ino);
26487+ if (unlikely(!inode)) {
26488+ inode = ERR_PTR(-ENOMEM);
26489+ goto out;
26490+ }
26491+ if (!(inode->i_state & I_NEW))
26492+ goto out;
26493+
26494+ err = au_xigen_new(inode);
26495+ if (!err)
26496+ err = au_iinfo_init(inode);
26497+ if (!err)
26498+ inode->i_version++;
26499+ else {
26500+ iget_failed(inode);
26501+ inode = ERR_PTR(err);
26502+ }
26503+
4f0767ce 26504+out:
1facf9fc 26505+ /* never return NULL */
26506+ AuDebugOn(!inode);
26507+ AuTraceErrPtr(inode);
26508+ return inode;
26509+}
26510+
26511+/* lock free root dinfo */
26512+static int au_show_brs(struct seq_file *seq, struct super_block *sb)
26513+{
26514+ int err;
26515+ aufs_bindex_t bindex, bend;
26516+ struct path path;
4a4d8108 26517+ struct au_hdentry *hdp;
1facf9fc 26518+ struct au_branch *br;
076b876e 26519+ au_br_perm_str_t perm;
1facf9fc 26520+
26521+ err = 0;
26522+ bend = au_sbend(sb);
4a4d8108 26523+ hdp = au_di(sb->s_root)->di_hdentry;
1facf9fc 26524+ for (bindex = 0; !err && bindex <= bend; bindex++) {
26525+ br = au_sbr(sb, bindex);
86dc4139 26526+ path.mnt = au_br_mnt(br);
4a4d8108 26527+ path.dentry = hdp[bindex].hd_dentry;
1facf9fc 26528+ err = au_seq_path(seq, &path);
1e00d052 26529+ if (err > 0) {
076b876e
AM
26530+ au_optstr_br_perm(&perm, br->br_perm);
26531+ err = seq_printf(seq, "=%s", perm.a);
26532+ if (err == -1)
26533+ err = -E2BIG;
1e00d052 26534+ }
1facf9fc 26535+ if (!err && bindex != bend)
26536+ err = seq_putc(seq, ':');
26537+ }
26538+
26539+ return err;
26540+}
26541+
26542+static void au_show_wbr_create(struct seq_file *m, int v,
26543+ struct au_sbinfo *sbinfo)
26544+{
26545+ const char *pat;
26546+
dece6358
AM
26547+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26548+
c2b27bf2 26549+ seq_puts(m, ",create=");
1facf9fc 26550+ pat = au_optstr_wbr_create(v);
26551+ switch (v) {
26552+ case AuWbrCreate_TDP:
26553+ case AuWbrCreate_RR:
26554+ case AuWbrCreate_MFS:
26555+ case AuWbrCreate_PMFS:
c2b27bf2 26556+ seq_puts(m, pat);
1facf9fc 26557+ break;
26558+ case AuWbrCreate_MFSV:
26559+ seq_printf(m, /*pat*/"mfs:%lu",
e49829fe
JR
26560+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26561+ / MSEC_PER_SEC);
1facf9fc 26562+ break;
26563+ case AuWbrCreate_PMFSV:
26564+ seq_printf(m, /*pat*/"pmfs:%lu",
e49829fe
JR
26565+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26566+ / MSEC_PER_SEC);
1facf9fc 26567+ break;
26568+ case AuWbrCreate_MFSRR:
26569+ seq_printf(m, /*pat*/"mfsrr:%llu",
26570+ sbinfo->si_wbr_mfs.mfsrr_watermark);
26571+ break;
26572+ case AuWbrCreate_MFSRRV:
26573+ seq_printf(m, /*pat*/"mfsrr:%llu:%lu",
26574+ sbinfo->si_wbr_mfs.mfsrr_watermark,
e49829fe
JR
26575+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26576+ / MSEC_PER_SEC);
1facf9fc 26577+ break;
392086de
AM
26578+ case AuWbrCreate_PMFSRR:
26579+ seq_printf(m, /*pat*/"pmfsrr:%llu",
26580+ sbinfo->si_wbr_mfs.mfsrr_watermark);
26581+ break;
26582+ case AuWbrCreate_PMFSRRV:
26583+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
26584+ sbinfo->si_wbr_mfs.mfsrr_watermark,
26585+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
26586+ / MSEC_PER_SEC);
26587+ break;
1facf9fc 26588+ }
26589+}
26590+
7eafdf33 26591+static int au_show_xino(struct seq_file *seq, struct super_block *sb)
1facf9fc 26592+{
26593+#ifdef CONFIG_SYSFS
26594+ return 0;
26595+#else
26596+ int err;
26597+ const int len = sizeof(AUFS_XINO_FNAME) - 1;
26598+ aufs_bindex_t bindex, brid;
1facf9fc 26599+ struct qstr *name;
26600+ struct file *f;
26601+ struct dentry *d, *h_root;
4a4d8108 26602+ struct au_hdentry *hdp;
1facf9fc 26603+
dece6358
AM
26604+ AuRwMustAnyLock(&sbinfo->si_rwsem);
26605+
1facf9fc 26606+ err = 0;
1facf9fc 26607+ f = au_sbi(sb)->si_xib;
26608+ if (!f)
26609+ goto out;
26610+
26611+ /* stop printing the default xino path on the first writable branch */
26612+ h_root = NULL;
26613+ brid = au_xino_brid(sb);
26614+ if (brid >= 0) {
26615+ bindex = au_br_index(sb, brid);
4a4d8108
AM
26616+ hdp = au_di(sb->s_root)->di_hdentry;
26617+ h_root = hdp[0 + bindex].hd_dentry;
1facf9fc 26618+ }
26619+ d = f->f_dentry;
26620+ name = &d->d_name;
26621+ /* safe ->d_parent because the file is unlinked */
26622+ if (d->d_parent == h_root
26623+ && name->len == len
26624+ && !memcmp(name->name, AUFS_XINO_FNAME, len))
26625+ goto out;
26626+
26627+ seq_puts(seq, ",xino=");
26628+ err = au_xino_path(seq, f);
26629+
4f0767ce 26630+out:
1facf9fc 26631+ return err;
26632+#endif
26633+}
26634+
26635+/* seq_file will re-call me in case of too long string */
7eafdf33 26636+static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
1facf9fc 26637+{
027c5e7a 26638+ int err;
1facf9fc 26639+ unsigned int mnt_flags, v;
26640+ struct super_block *sb;
26641+ struct au_sbinfo *sbinfo;
26642+
26643+#define AuBool(name, str) do { \
26644+ v = au_opt_test(mnt_flags, name); \
26645+ if (v != au_opt_test(AuOpt_Def, name)) \
26646+ seq_printf(m, ",%s" #str, v ? "" : "no"); \
26647+} while (0)
26648+
26649+#define AuStr(name, str) do { \
26650+ v = mnt_flags & AuOptMask_##name; \
26651+ if (v != (AuOpt_Def & AuOptMask_##name)) \
26652+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \
26653+} while (0)
26654+
26655+#define AuUInt(name, str, val) do { \
26656+ if (val != AUFS_##name##_DEF) \
26657+ seq_printf(m, "," #str "=%u", val); \
26658+} while (0)
26659+
7eafdf33 26660+ sb = dentry->d_sb;
c1595e42
JR
26661+ if (sb->s_flags & MS_POSIXACL)
26662+ seq_puts(m, ",acl");
26663+
26664+ /* lock free root dinfo */
1facf9fc 26665+ si_noflush_read_lock(sb);
26666+ sbinfo = au_sbi(sb);
26667+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo));
26668+
26669+ mnt_flags = au_mntflags(sb);
26670+ if (au_opt_test(mnt_flags, XINO)) {
7eafdf33 26671+ err = au_show_xino(m, sb);
1facf9fc 26672+ if (unlikely(err))
26673+ goto out;
26674+ } else
26675+ seq_puts(m, ",noxino");
26676+
26677+ AuBool(TRUNC_XINO, trunc_xino);
26678+ AuStr(UDBA, udba);
dece6358 26679+ AuBool(SHWH, shwh);
1facf9fc 26680+ AuBool(PLINK, plink);
4a4d8108 26681+ AuBool(DIO, dio);
076b876e 26682+ AuBool(DIRPERM1, dirperm1);
1facf9fc 26683+ /* AuBool(REFROF, refrof); */
26684+
26685+ v = sbinfo->si_wbr_create;
26686+ if (v != AuWbrCreate_Def)
26687+ au_show_wbr_create(m, v, sbinfo);
26688+
26689+ v = sbinfo->si_wbr_copyup;
26690+ if (v != AuWbrCopyup_Def)
26691+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v));
26692+
26693+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ);
26694+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ))
26695+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w');
26696+
26697+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh);
26698+
027c5e7a
AM
26699+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC;
26700+ AuUInt(RDCACHE, rdcache, v);
1facf9fc 26701+
26702+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk);
26703+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash);
26704+
076b876e
AM
26705+ au_fhsm_show(m, sbinfo);
26706+
1facf9fc 26707+ AuBool(SUM, sum);
26708+ /* AuBool(SUM_W, wsum); */
26709+ AuBool(WARN_PERM, warn_perm);
26710+ AuBool(VERBOSE, verbose);
26711+
4f0767ce 26712+out:
1facf9fc 26713+ /* be sure to print "br:" last */
26714+ if (!sysaufs_brs) {
26715+ seq_puts(m, ",br:");
26716+ au_show_brs(m, sb);
26717+ }
26718+ si_read_unlock(sb);
26719+ return 0;
26720+
1facf9fc 26721+#undef AuBool
26722+#undef AuStr
4a4d8108 26723+#undef AuUInt
1facf9fc 26724+}
26725+
26726+/* ---------------------------------------------------------------------- */
26727+
26728+/* sum mode which returns the summation for statfs(2) */
26729+
26730+static u64 au_add_till_max(u64 a, u64 b)
26731+{
26732+ u64 old;
26733+
26734+ old = a;
26735+ a += b;
92d182d2
AM
26736+ if (old <= a)
26737+ return a;
26738+ return ULLONG_MAX;
26739+}
26740+
26741+static u64 au_mul_till_max(u64 a, long mul)
26742+{
26743+ u64 old;
26744+
26745+ old = a;
26746+ a *= mul;
26747+ if (old <= a)
1facf9fc 26748+ return a;
26749+ return ULLONG_MAX;
26750+}
26751+
26752+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
26753+{
26754+ int err;
92d182d2 26755+ long bsize, factor;
1facf9fc 26756+ u64 blocks, bfree, bavail, files, ffree;
26757+ aufs_bindex_t bend, bindex, i;
26758+ unsigned char shared;
7f207e10 26759+ struct path h_path;
1facf9fc 26760+ struct super_block *h_sb;
26761+
92d182d2
AM
26762+ err = 0;
26763+ bsize = LONG_MAX;
26764+ files = 0;
26765+ ffree = 0;
1facf9fc 26766+ blocks = 0;
26767+ bfree = 0;
26768+ bavail = 0;
1facf9fc 26769+ bend = au_sbend(sb);
92d182d2 26770+ for (bindex = 0; bindex <= bend; bindex++) {
7f207e10
AM
26771+ h_path.mnt = au_sbr_mnt(sb, bindex);
26772+ h_sb = h_path.mnt->mnt_sb;
1facf9fc 26773+ shared = 0;
92d182d2 26774+ for (i = 0; !shared && i < bindex; i++)
1facf9fc 26775+ shared = (au_sbr_sb(sb, i) == h_sb);
26776+ if (shared)
26777+ continue;
26778+
26779+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
26780+ h_path.dentry = h_path.mnt->mnt_root;
26781+ err = vfs_statfs(&h_path, buf);
1facf9fc 26782+ if (unlikely(err))
26783+ goto out;
26784+
92d182d2
AM
26785+ if (bsize > buf->f_bsize) {
26786+ /*
26787+ * we will reduce bsize, so we have to expand blocks
26788+ * etc. to match them again
26789+ */
26790+ factor = (bsize / buf->f_bsize);
26791+ blocks = au_mul_till_max(blocks, factor);
26792+ bfree = au_mul_till_max(bfree, factor);
26793+ bavail = au_mul_till_max(bavail, factor);
26794+ bsize = buf->f_bsize;
26795+ }
26796+
26797+ factor = (buf->f_bsize / bsize);
26798+ blocks = au_add_till_max(blocks,
26799+ au_mul_till_max(buf->f_blocks, factor));
26800+ bfree = au_add_till_max(bfree,
26801+ au_mul_till_max(buf->f_bfree, factor));
26802+ bavail = au_add_till_max(bavail,
26803+ au_mul_till_max(buf->f_bavail, factor));
1facf9fc 26804+ files = au_add_till_max(files, buf->f_files);
26805+ ffree = au_add_till_max(ffree, buf->f_ffree);
26806+ }
26807+
92d182d2 26808+ buf->f_bsize = bsize;
1facf9fc 26809+ buf->f_blocks = blocks;
26810+ buf->f_bfree = bfree;
26811+ buf->f_bavail = bavail;
26812+ buf->f_files = files;
26813+ buf->f_ffree = ffree;
92d182d2 26814+ buf->f_frsize = 0;
1facf9fc 26815+
4f0767ce 26816+out:
1facf9fc 26817+ return err;
26818+}
26819+
26820+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf)
26821+{
26822+ int err;
7f207e10 26823+ struct path h_path;
1facf9fc 26824+ struct super_block *sb;
26825+
26826+ /* lock free root dinfo */
26827+ sb = dentry->d_sb;
26828+ si_noflush_read_lock(sb);
7f207e10 26829+ if (!au_opt_test(au_mntflags(sb), SUM)) {
1facf9fc 26830+ /* sb->s_root for NFS is unreliable */
7f207e10
AM
26831+ h_path.mnt = au_sbr_mnt(sb, 0);
26832+ h_path.dentry = h_path.mnt->mnt_root;
26833+ err = vfs_statfs(&h_path, buf);
26834+ } else
1facf9fc 26835+ err = au_statfs_sum(sb, buf);
26836+ si_read_unlock(sb);
26837+
26838+ if (!err) {
26839+ buf->f_type = AUFS_SUPER_MAGIC;
4a4d8108 26840+ buf->f_namelen = AUFS_MAX_NAMELEN;
1facf9fc 26841+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid));
26842+ }
26843+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */
26844+
26845+ return err;
26846+}
26847+
26848+/* ---------------------------------------------------------------------- */
26849+
537831f9
AM
26850+static int aufs_sync_fs(struct super_block *sb, int wait)
26851+{
26852+ int err, e;
26853+ aufs_bindex_t bend, bindex;
26854+ struct au_branch *br;
26855+ struct super_block *h_sb;
26856+
26857+ err = 0;
26858+ si_noflush_read_lock(sb);
26859+ bend = au_sbend(sb);
26860+ for (bindex = 0; bindex <= bend; bindex++) {
26861+ br = au_sbr(sb, bindex);
26862+ if (!au_br_writable(br->br_perm))
26863+ continue;
26864+
26865+ h_sb = au_sbr_sb(sb, bindex);
26866+ if (h_sb->s_op->sync_fs) {
26867+ e = h_sb->s_op->sync_fs(h_sb, wait);
26868+ if (unlikely(e && !err))
26869+ err = e;
26870+ /* go on even if an error happens */
26871+ }
26872+ }
26873+ si_read_unlock(sb);
26874+
26875+ return err;
26876+}
26877+
26878+/* ---------------------------------------------------------------------- */
26879+
1facf9fc 26880+/* final actions when unmounting a file system */
26881+static void aufs_put_super(struct super_block *sb)
26882+{
26883+ struct au_sbinfo *sbinfo;
26884+
26885+ sbinfo = au_sbi(sb);
26886+ if (!sbinfo)
26887+ return;
26888+
1facf9fc 26889+ dbgaufs_si_fin(sbinfo);
26890+ kobject_put(&sbinfo->si_kobj);
26891+}
26892+
26893+/* ---------------------------------------------------------------------- */
26894+
7f207e10
AM
26895+void au_array_free(void *array)
26896+{
26897+ if (array) {
26898+ if (!is_vmalloc_addr(array))
26899+ kfree(array);
26900+ else
26901+ vfree(array);
26902+ }
26903+}
26904+
26905+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg)
26906+{
26907+ void *array;
076b876e 26908+ unsigned long long n, sz;
7f207e10
AM
26909+
26910+ array = NULL;
26911+ n = 0;
26912+ if (!*hint)
26913+ goto out;
26914+
26915+ if (*hint > ULLONG_MAX / sizeof(array)) {
26916+ array = ERR_PTR(-EMFILE);
26917+ pr_err("hint %llu\n", *hint);
26918+ goto out;
26919+ }
26920+
076b876e
AM
26921+ sz = sizeof(array) * *hint;
26922+ array = kzalloc(sz, GFP_NOFS);
7f207e10 26923+ if (unlikely(!array))
076b876e 26924+ array = vzalloc(sz);
7f207e10
AM
26925+ if (unlikely(!array)) {
26926+ array = ERR_PTR(-ENOMEM);
26927+ goto out;
26928+ }
26929+
26930+ n = cb(array, *hint, arg);
26931+ AuDebugOn(n > *hint);
26932+
26933+out:
26934+ *hint = n;
26935+ return array;
26936+}
26937+
26938+static unsigned long long au_iarray_cb(void *a,
26939+ unsigned long long max __maybe_unused,
26940+ void *arg)
26941+{
26942+ unsigned long long n;
26943+ struct inode **p, *inode;
26944+ struct list_head *head;
26945+
26946+ n = 0;
26947+ p = a;
26948+ head = arg;
2cbb1c4b 26949+ spin_lock(&inode_sb_list_lock);
7f207e10
AM
26950+ list_for_each_entry(inode, head, i_sb_list) {
26951+ if (!is_bad_inode(inode)
26952+ && au_ii(inode)->ii_bstart >= 0) {
2cbb1c4b
JR
26953+ spin_lock(&inode->i_lock);
26954+ if (atomic_read(&inode->i_count)) {
26955+ au_igrab(inode);
26956+ *p++ = inode;
26957+ n++;
26958+ AuDebugOn(n > max);
26959+ }
26960+ spin_unlock(&inode->i_lock);
7f207e10
AM
26961+ }
26962+ }
2cbb1c4b 26963+ spin_unlock(&inode_sb_list_lock);
7f207e10
AM
26964+
26965+ return n;
26966+}
26967+
26968+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max)
26969+{
26970+ *max = atomic_long_read(&au_sbi(sb)->si_ninodes);
26971+ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes);
26972+}
26973+
26974+void au_iarray_free(struct inode **a, unsigned long long max)
26975+{
26976+ unsigned long long ull;
26977+
26978+ for (ull = 0; ull < max; ull++)
26979+ iput(a[ull]);
26980+ au_array_free(a);
26981+}
26982+
26983+/* ---------------------------------------------------------------------- */
26984+
1facf9fc 26985+/*
26986+ * refresh dentry and inode at remount time.
26987+ */
027c5e7a
AM
26988+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */
26989+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags,
26990+ struct dentry *parent)
1facf9fc 26991+{
26992+ int err;
1facf9fc 26993+
26994+ di_write_lock_child(dentry);
1facf9fc 26995+ di_read_lock_parent(parent, AuLock_IR);
027c5e7a
AM
26996+ err = au_refresh_dentry(dentry, parent);
26997+ if (!err && dir_flags)
26998+ au_hn_reset(dentry->d_inode, dir_flags);
1facf9fc 26999+ di_read_unlock(parent, AuLock_IR);
1facf9fc 27000+ di_write_unlock(dentry);
27001+
27002+ return err;
27003+}
27004+
027c5e7a
AM
27005+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen,
27006+ struct au_sbinfo *sbinfo,
27007+ const unsigned int dir_flags)
1facf9fc 27008+{
027c5e7a
AM
27009+ int err;
27010+ struct dentry *parent;
27011+ struct inode *inode;
27012+
27013+ err = 0;
27014+ parent = dget_parent(dentry);
27015+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) {
27016+ inode = dentry->d_inode;
27017+ if (inode) {
27018+ if (!S_ISDIR(inode->i_mode))
27019+ err = au_do_refresh(dentry, /*dir_flags*/0,
27020+ parent);
27021+ else {
27022+ err = au_do_refresh(dentry, dir_flags, parent);
27023+ if (unlikely(err))
27024+ au_fset_si(sbinfo, FAILED_REFRESH_DIR);
27025+ }
27026+ } else
27027+ err = au_do_refresh(dentry, /*dir_flags*/0, parent);
27028+ AuDbgDentry(dentry);
27029+ }
27030+ dput(parent);
27031+
27032+ AuTraceErr(err);
27033+ return err;
1facf9fc 27034+}
27035+
027c5e7a 27036+static int au_refresh_d(struct super_block *sb)
1facf9fc 27037+{
27038+ int err, i, j, ndentry, e;
027c5e7a 27039+ unsigned int sigen;
1facf9fc 27040+ struct au_dcsub_pages dpages;
27041+ struct au_dpage *dpage;
027c5e7a
AM
27042+ struct dentry **dentries, *d;
27043+ struct au_sbinfo *sbinfo;
27044+ struct dentry *root = sb->s_root;
27045+ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1);
1facf9fc 27046+
027c5e7a
AM
27047+ err = au_dpages_init(&dpages, GFP_NOFS);
27048+ if (unlikely(err))
1facf9fc 27049+ goto out;
027c5e7a
AM
27050+ err = au_dcsub_pages(&dpages, root, NULL, NULL);
27051+ if (unlikely(err))
1facf9fc 27052+ goto out_dpages;
1facf9fc 27053+
027c5e7a
AM
27054+ sigen = au_sigen(sb);
27055+ sbinfo = au_sbi(sb);
27056+ for (i = 0; i < dpages.ndpage; i++) {
1facf9fc 27057+ dpage = dpages.dpages + i;
27058+ dentries = dpage->dentries;
27059+ ndentry = dpage->ndentry;
027c5e7a 27060+ for (j = 0; j < ndentry; j++) {
1facf9fc 27061+ d = dentries[j];
027c5e7a
AM
27062+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags);
27063+ if (unlikely(e && !err))
27064+ err = e;
27065+ /* go on even err */
1facf9fc 27066+ }
27067+ }
27068+
4f0767ce 27069+out_dpages:
1facf9fc 27070+ au_dpages_free(&dpages);
4f0767ce 27071+out:
1facf9fc 27072+ return err;
27073+}
27074+
027c5e7a 27075+static int au_refresh_i(struct super_block *sb)
1facf9fc 27076+{
027c5e7a
AM
27077+ int err, e;
27078+ unsigned int sigen;
27079+ unsigned long long max, ull;
27080+ struct inode *inode, **array;
1facf9fc 27081+
027c5e7a
AM
27082+ array = au_iarray_alloc(sb, &max);
27083+ err = PTR_ERR(array);
27084+ if (IS_ERR(array))
27085+ goto out;
1facf9fc 27086+
27087+ err = 0;
027c5e7a
AM
27088+ sigen = au_sigen(sb);
27089+ for (ull = 0; ull < max; ull++) {
27090+ inode = array[ull];
076b876e
AM
27091+ if (unlikely(!inode))
27092+ break;
537831f9 27093+ if (au_iigen(inode, NULL) != sigen) {
1facf9fc 27094+ ii_write_lock_child(inode);
027c5e7a 27095+ e = au_refresh_hinode_self(inode);
1facf9fc 27096+ ii_write_unlock(inode);
27097+ if (unlikely(e)) {
027c5e7a 27098+ pr_err("error %d, i%lu\n", e, inode->i_ino);
1facf9fc 27099+ if (!err)
27100+ err = e;
27101+ /* go on even if err */
27102+ }
27103+ }
1facf9fc 27104+ }
27105+
027c5e7a 27106+ au_iarray_free(array, max);
1facf9fc 27107+
4f0767ce 27108+out:
1facf9fc 27109+ return err;
27110+}
27111+
027c5e7a 27112+static void au_remount_refresh(struct super_block *sb)
1facf9fc 27113+{
027c5e7a
AM
27114+ int err, e;
27115+ unsigned int udba;
27116+ aufs_bindex_t bindex, bend;
1facf9fc 27117+ struct dentry *root;
27118+ struct inode *inode;
027c5e7a 27119+ struct au_branch *br;
1facf9fc 27120+
27121+ au_sigen_inc(sb);
027c5e7a 27122+ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR);
1facf9fc 27123+
27124+ root = sb->s_root;
27125+ DiMustNoWaiters(root);
27126+ inode = root->d_inode;
27127+ IiMustNoWaiters(inode);
1facf9fc 27128+
027c5e7a
AM
27129+ udba = au_opt_udba(sb);
27130+ bend = au_sbend(sb);
27131+ for (bindex = 0; bindex <= bend; bindex++) {
27132+ br = au_sbr(sb, bindex);
27133+ err = au_hnotify_reset_br(udba, br, br->br_perm);
1facf9fc 27134+ if (unlikely(err))
027c5e7a
AM
27135+ AuIOErr("hnotify failed on br %d, %d, ignored\n",
27136+ bindex, err);
27137+ /* go on even if err */
1facf9fc 27138+ }
027c5e7a 27139+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1));
1facf9fc 27140+
027c5e7a
AM
27141+ di_write_unlock(root);
27142+ err = au_refresh_d(sb);
27143+ e = au_refresh_i(sb);
27144+ if (unlikely(e && !err))
27145+ err = e;
1facf9fc 27146+ /* aufs_write_lock() calls ..._child() */
27147+ di_write_lock_child(root);
027c5e7a
AM
27148+
27149+ au_cpup_attr_all(inode, /*force*/1);
27150+
27151+ if (unlikely(err))
27152+ AuIOErr("refresh failed, ignored, %d\n", err);
1facf9fc 27153+}
27154+
27155+/* stop extra interpretation of errno in mount(8), and strange error messages */
27156+static int cvt_err(int err)
27157+{
27158+ AuTraceErr(err);
27159+
27160+ switch (err) {
27161+ case -ENOENT:
27162+ case -ENOTDIR:
27163+ case -EEXIST:
27164+ case -EIO:
27165+ err = -EINVAL;
27166+ }
27167+ return err;
27168+}
27169+
27170+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data)
27171+{
4a4d8108
AM
27172+ int err, do_dx;
27173+ unsigned int mntflags;
1facf9fc 27174+ struct au_opts opts;
27175+ struct dentry *root;
27176+ struct inode *inode;
27177+ struct au_sbinfo *sbinfo;
27178+
27179+ err = 0;
27180+ root = sb->s_root;
27181+ if (!data || !*data) {
e49829fe
JR
27182+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
27183+ if (!err) {
27184+ di_write_lock_child(root);
27185+ err = au_opts_verify(sb, *flags, /*pending*/0);
27186+ aufs_write_unlock(root);
27187+ }
1facf9fc 27188+ goto out;
27189+ }
27190+
27191+ err = -ENOMEM;
27192+ memset(&opts, 0, sizeof(opts));
27193+ opts.opt = (void *)__get_free_page(GFP_NOFS);
27194+ if (unlikely(!opts.opt))
27195+ goto out;
27196+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
27197+ opts.flags = AuOpts_REMOUNT;
27198+ opts.sb_flags = *flags;
27199+
27200+ /* parse it before aufs lock */
27201+ err = au_opts_parse(sb, data, &opts);
27202+ if (unlikely(err))
27203+ goto out_opts;
27204+
27205+ sbinfo = au_sbi(sb);
27206+ inode = root->d_inode;
27207+ mutex_lock(&inode->i_mutex);
e49829fe
JR
27208+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
27209+ if (unlikely(err))
27210+ goto out_mtx;
27211+ di_write_lock_child(root);
1facf9fc 27212+
27213+ /* au_opts_remount() may return an error */
27214+ err = au_opts_remount(sb, &opts);
27215+ au_opts_free(&opts);
27216+
027c5e7a
AM
27217+ if (au_ftest_opts(opts.flags, REFRESH))
27218+ au_remount_refresh(sb);
1facf9fc 27219+
4a4d8108
AM
27220+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) {
27221+ mntflags = au_mntflags(sb);
27222+ do_dx = !!au_opt_test(mntflags, DIO);
27223+ au_dy_arefresh(do_dx);
27224+ }
27225+
076b876e 27226+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */
1facf9fc 27227+ aufs_write_unlock(root);
953406b4 27228+
e49829fe
JR
27229+out_mtx:
27230+ mutex_unlock(&inode->i_mutex);
4f0767ce 27231+out_opts:
1facf9fc 27232+ free_page((unsigned long)opts.opt);
4f0767ce 27233+out:
1facf9fc 27234+ err = cvt_err(err);
27235+ AuTraceErr(err);
27236+ return err;
27237+}
27238+
4a4d8108 27239+static const struct super_operations aufs_sop = {
1facf9fc 27240+ .alloc_inode = aufs_alloc_inode,
27241+ .destroy_inode = aufs_destroy_inode,
b752ccd1 27242+ /* always deleting, no clearing */
1facf9fc 27243+ .drop_inode = generic_delete_inode,
27244+ .show_options = aufs_show_options,
27245+ .statfs = aufs_statfs,
27246+ .put_super = aufs_put_super,
537831f9 27247+ .sync_fs = aufs_sync_fs,
1facf9fc 27248+ .remount_fs = aufs_remount_fs
27249+};
27250+
27251+/* ---------------------------------------------------------------------- */
27252+
27253+static int alloc_root(struct super_block *sb)
27254+{
27255+ int err;
27256+ struct inode *inode;
27257+ struct dentry *root;
27258+
27259+ err = -ENOMEM;
27260+ inode = au_iget_locked(sb, AUFS_ROOT_INO);
27261+ err = PTR_ERR(inode);
27262+ if (IS_ERR(inode))
27263+ goto out;
27264+
27265+ inode->i_op = &aufs_dir_iop;
27266+ inode->i_fop = &aufs_dir_fop;
27267+ inode->i_mode = S_IFDIR;
9dbd164d 27268+ set_nlink(inode, 2);
1facf9fc 27269+ unlock_new_inode(inode);
27270+
92d182d2 27271+ root = d_make_root(inode);
1facf9fc 27272+ if (unlikely(!root))
92d182d2 27273+ goto out;
1facf9fc 27274+ err = PTR_ERR(root);
27275+ if (IS_ERR(root))
92d182d2 27276+ goto out;
1facf9fc 27277+
4a4d8108 27278+ err = au_di_init(root);
1facf9fc 27279+ if (!err) {
27280+ sb->s_root = root;
27281+ return 0; /* success */
27282+ }
27283+ dput(root);
1facf9fc 27284+
4f0767ce 27285+out:
1facf9fc 27286+ return err;
1facf9fc 27287+}
27288+
27289+static int aufs_fill_super(struct super_block *sb, void *raw_data,
27290+ int silent __maybe_unused)
27291+{
27292+ int err;
27293+ struct au_opts opts;
27294+ struct dentry *root;
27295+ struct inode *inode;
27296+ char *arg = raw_data;
27297+
27298+ if (unlikely(!arg || !*arg)) {
27299+ err = -EINVAL;
4a4d8108 27300+ pr_err("no arg\n");
1facf9fc 27301+ goto out;
27302+ }
27303+
27304+ err = -ENOMEM;
27305+ memset(&opts, 0, sizeof(opts));
27306+ opts.opt = (void *)__get_free_page(GFP_NOFS);
27307+ if (unlikely(!opts.opt))
27308+ goto out;
27309+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt);
27310+ opts.sb_flags = sb->s_flags;
27311+
27312+ err = au_si_alloc(sb);
27313+ if (unlikely(err))
27314+ goto out_opts;
27315+
27316+ /* all timestamps always follow the ones on the branch */
27317+ sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
27318+ sb->s_op = &aufs_sop;
027c5e7a 27319+ sb->s_d_op = &aufs_dop;
1facf9fc 27320+ sb->s_magic = AUFS_SUPER_MAGIC;
27321+ sb->s_maxbytes = 0;
c1595e42 27322+ sb->s_stack_depth = 1;
1facf9fc 27323+ au_export_init(sb);
c1595e42 27324+ /* au_xattr_init(sb); */
1facf9fc 27325+
27326+ err = alloc_root(sb);
27327+ if (unlikely(err)) {
27328+ si_write_unlock(sb);
27329+ goto out_info;
27330+ }
27331+ root = sb->s_root;
27332+ inode = root->d_inode;
27333+
27334+ /*
27335+ * actually we can parse options regardless aufs lock here.
27336+ * but at remount time, parsing must be done before aufs lock.
27337+ * so we follow the same rule.
27338+ */
27339+ ii_write_lock_parent(inode);
27340+ aufs_write_unlock(root);
27341+ err = au_opts_parse(sb, arg, &opts);
27342+ if (unlikely(err))
27343+ goto out_root;
27344+
27345+ /* lock vfs_inode first, then aufs. */
27346+ mutex_lock(&inode->i_mutex);
1facf9fc 27347+ aufs_write_lock(root);
27348+ err = au_opts_mount(sb, &opts);
27349+ au_opts_free(&opts);
1facf9fc 27350+ aufs_write_unlock(root);
27351+ mutex_unlock(&inode->i_mutex);
4a4d8108
AM
27352+ if (!err)
27353+ goto out_opts; /* success */
1facf9fc 27354+
4f0767ce 27355+out_root:
1facf9fc 27356+ dput(root);
27357+ sb->s_root = NULL;
4f0767ce 27358+out_info:
2cbb1c4b 27359+ dbgaufs_si_fin(au_sbi(sb));
1facf9fc 27360+ kobject_put(&au_sbi(sb)->si_kobj);
27361+ sb->s_fs_info = NULL;
4f0767ce 27362+out_opts:
1facf9fc 27363+ free_page((unsigned long)opts.opt);
4f0767ce 27364+out:
1facf9fc 27365+ AuTraceErr(err);
27366+ err = cvt_err(err);
27367+ AuTraceErr(err);
27368+ return err;
27369+}
27370+
27371+/* ---------------------------------------------------------------------- */
27372+
027c5e7a
AM
27373+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags,
27374+ const char *dev_name __maybe_unused,
27375+ void *raw_data)
1facf9fc 27376+{
027c5e7a 27377+ struct dentry *root;
1facf9fc 27378+ struct super_block *sb;
27379+
27380+ /* all timestamps always follow the ones on the branch */
27381+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */
027c5e7a
AM
27382+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super);
27383+ if (IS_ERR(root))
27384+ goto out;
27385+
27386+ sb = root->d_sb;
27387+ si_write_lock(sb, !AuLock_FLUSH);
27388+ sysaufs_brs_add(sb, 0);
27389+ si_write_unlock(sb);
27390+ au_sbilist_add(sb);
27391+
27392+out:
27393+ return root;
1facf9fc 27394+}
27395+
e49829fe
JR
27396+static void aufs_kill_sb(struct super_block *sb)
27397+{
27398+ struct au_sbinfo *sbinfo;
27399+
27400+ sbinfo = au_sbi(sb);
27401+ if (sbinfo) {
27402+ au_sbilist_del(sb);
27403+ aufs_write_lock(sb->s_root);
076b876e 27404+ au_fhsm_fin(sb);
e49829fe
JR
27405+ if (sbinfo->si_wbr_create_ops->fin)
27406+ sbinfo->si_wbr_create_ops->fin(sb);
27407+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) {
27408+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE);
027c5e7a 27409+ au_remount_refresh(sb);
e49829fe
JR
27410+ }
27411+ if (au_opt_test(sbinfo->si_mntflags, PLINK))
27412+ au_plink_put(sb, /*verbose*/1);
27413+ au_xino_clr(sb);
1e00d052 27414+ sbinfo->si_sb = NULL;
e49829fe 27415+ aufs_write_unlock(sb->s_root);
e49829fe
JR
27416+ au_nwt_flush(&sbinfo->si_nowait);
27417+ }
98d9a5b1 27418+ kill_anon_super(sb);
e49829fe
JR
27419+}
27420+
1facf9fc 27421+struct file_system_type aufs_fs_type = {
27422+ .name = AUFS_FSTYPE,
c06a8ce3
AM
27423+ /* a race between rename and others */
27424+ .fs_flags = FS_RENAME_DOES_D_MOVE,
027c5e7a 27425+ .mount = aufs_mount,
e49829fe 27426+ .kill_sb = aufs_kill_sb,
1facf9fc 27427+ /* no need to __module_get() and module_put(). */
27428+ .owner = THIS_MODULE,
27429+};
7f207e10
AM
27430diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h
27431--- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
27432+++ linux/fs/aufs/super.h 2015-01-25 13:00:38.634380408 +0100
27433@@ -0,0 +1,641 @@
1facf9fc 27434+/*
523b37e3 27435+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 27436+ *
27437+ * This program, aufs is free software; you can redistribute it and/or modify
27438+ * it under the terms of the GNU General Public License as published by
27439+ * the Free Software Foundation; either version 2 of the License, or
27440+ * (at your option) any later version.
dece6358
AM
27441+ *
27442+ * This program is distributed in the hope that it will be useful,
27443+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27444+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27445+ * GNU General Public License for more details.
27446+ *
27447+ * You should have received a copy of the GNU General Public License
523b37e3 27448+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 27449+ */
27450+
27451+/*
27452+ * super_block operations
27453+ */
27454+
27455+#ifndef __AUFS_SUPER_H__
27456+#define __AUFS_SUPER_H__
27457+
27458+#ifdef __KERNEL__
27459+
27460+#include <linux/fs.h>
1facf9fc 27461+#include "rwsem.h"
27462+#include "spl.h"
27463+#include "wkq.h"
27464+
27465+typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *);
27466+typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t,
27467+ loff_t *);
27468+
27469+/* policies to select one among multiple writable branches */
27470+struct au_wbr_copyup_operations {
27471+ int (*copyup)(struct dentry *dentry);
27472+};
27473+
392086de
AM
27474+#define AuWbr_DIR 1 /* target is a dir */
27475+#define AuWbr_PARENT (1 << 1) /* always require a parent */
27476+
27477+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name)
27478+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; }
27479+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; }
27480+
1facf9fc 27481+struct au_wbr_create_operations {
392086de 27482+ int (*create)(struct dentry *dentry, unsigned int flags);
1facf9fc 27483+ int (*init)(struct super_block *sb);
27484+ int (*fin)(struct super_block *sb);
27485+};
27486+
27487+struct au_wbr_mfs {
27488+ struct mutex mfs_lock; /* protect this structure */
27489+ unsigned long mfs_jiffy;
27490+ unsigned long mfs_expire;
27491+ aufs_bindex_t mfs_bindex;
27492+
27493+ unsigned long long mfsrr_bytes;
27494+ unsigned long long mfsrr_watermark;
27495+};
27496+
86dc4139
AM
27497+struct pseudo_link {
27498+ union {
27499+ struct hlist_node hlist;
27500+ struct rcu_head rcu;
27501+ };
27502+ struct inode *inode;
27503+};
27504+
27505+#define AuPlink_NHASH 100
27506+static inline int au_plink_hash(ino_t ino)
27507+{
27508+ return ino % AuPlink_NHASH;
27509+}
27510+
076b876e
AM
27511+/* File-based Hierarchical Storage Management */
27512+struct au_fhsm {
27513+#ifdef CONFIG_AUFS_FHSM
27514+ /* allow only one process who can receive the notification */
27515+ spinlock_t fhsm_spin;
27516+ pid_t fhsm_pid;
27517+ wait_queue_head_t fhsm_wqh;
27518+ atomic_t fhsm_readable;
27519+
c1595e42 27520+ /* these are protected by si_rwsem */
076b876e 27521+ unsigned long fhsm_expire;
c1595e42 27522+ aufs_bindex_t fhsm_bottom;
076b876e
AM
27523+#endif
27524+};
27525+
1facf9fc 27526+struct au_branch;
27527+struct au_sbinfo {
27528+ /* nowait tasks in the system-wide workqueue */
27529+ struct au_nowait_tasks si_nowait;
27530+
b752ccd1
AM
27531+ /*
27532+ * tried sb->s_umount, but failed due to the dependecy between i_mutex.
27533+ * rwsem for au_sbinfo is necessary.
27534+ */
dece6358 27535+ struct au_rwsem si_rwsem;
1facf9fc 27536+
b752ccd1
AM
27537+ /* prevent recursive locking in deleting inode */
27538+ struct {
27539+ unsigned long *bitmap;
27540+ spinlock_t tree_lock;
27541+ struct radix_tree_root tree;
27542+ } au_si_pid;
27543+
7f207e10 27544+ /*
523b37e3
AM
27545+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from
27546+ * remount.
7f207e10
AM
27547+ */
27548+ atomic_long_t si_ninodes, si_nfiles;
27549+
1facf9fc 27550+ /* branch management */
27551+ unsigned int si_generation;
27552+
27553+ /* see above flags */
27554+ unsigned char au_si_status;
27555+
27556+ aufs_bindex_t si_bend;
7f207e10
AM
27557+
27558+ /* dirty trick to keep br_id plus */
27559+ unsigned int si_last_br_id :
27560+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1;
1facf9fc 27561+ struct au_branch **si_branch;
27562+
27563+ /* policy to select a writable branch */
27564+ unsigned char si_wbr_copyup;
27565+ unsigned char si_wbr_create;
27566+ struct au_wbr_copyup_operations *si_wbr_copyup_ops;
27567+ struct au_wbr_create_operations *si_wbr_create_ops;
27568+
27569+ /* round robin */
27570+ atomic_t si_wbr_rr_next;
27571+
27572+ /* most free space */
27573+ struct au_wbr_mfs si_wbr_mfs;
27574+
076b876e
AM
27575+ /* File-based Hierarchical Storage Management */
27576+ struct au_fhsm si_fhsm;
27577+
1facf9fc 27578+ /* mount flags */
27579+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */
27580+ unsigned int si_mntflags;
27581+
27582+ /* external inode number (bitmap and translation table) */
27583+ au_readf_t si_xread;
27584+ au_writef_t si_xwrite;
27585+ struct file *si_xib;
27586+ struct mutex si_xib_mtx; /* protect xib members */
27587+ unsigned long *si_xib_buf;
27588+ unsigned long si_xib_last_pindex;
27589+ int si_xib_next_bit;
27590+ aufs_bindex_t si_xino_brid;
392086de
AM
27591+ unsigned long si_xino_jiffy;
27592+ unsigned long si_xino_expire;
1facf9fc 27593+ /* reserved for future use */
27594+ /* unsigned long long si_xib_limit; */ /* Max xib file size */
27595+
27596+#ifdef CONFIG_AUFS_EXPORT
27597+ /* i_generation */
27598+ struct file *si_xigen;
27599+ atomic_t si_xigen_next;
27600+#endif
27601+
27602+ /* vdir parameters */
e49829fe 27603+ unsigned long si_rdcache; /* max cache time in jiffies */
1facf9fc 27604+ unsigned int si_rdblk; /* deblk size */
27605+ unsigned int si_rdhash; /* hash size */
27606+
27607+ /*
27608+ * If the number of whiteouts are larger than si_dirwh, leave all of
27609+ * them after au_whtmp_ren to reduce the cost of rmdir(2).
27610+ * future fsck.aufs or kernel thread will remove them later.
27611+ * Otherwise, remove all whiteouts and the dir in rmdir(2).
27612+ */
27613+ unsigned int si_dirwh;
27614+
27615+ /*
27616+ * rename(2) a directory with all children.
27617+ */
27618+ /* reserved for future use */
27619+ /* int si_rendir; */
27620+
27621+ /* pseudo_link list */
86dc4139 27622+ struct au_sphlhead si_plink[AuPlink_NHASH];
1facf9fc 27623+ wait_queue_head_t si_plink_wq;
4a4d8108 27624+ spinlock_t si_plink_maint_lock;
e49829fe 27625+ pid_t si_plink_maint_pid;
1facf9fc 27626+
523b37e3
AM
27627+ /* file list */
27628+ struct au_sphlhead si_files;
27629+
1facf9fc 27630+ /*
27631+ * sysfs and lifetime management.
27632+ * this is not a small structure and it may be a waste of memory in case
27633+ * of sysfs is disabled, particulary when many aufs-es are mounted.
27634+ * but using sysfs is majority.
27635+ */
27636+ struct kobject si_kobj;
27637+#ifdef CONFIG_DEBUG_FS
86dc4139
AM
27638+ struct dentry *si_dbgaufs;
27639+ struct dentry *si_dbgaufs_plink;
27640+ struct dentry *si_dbgaufs_xib;
1facf9fc 27641+#ifdef CONFIG_AUFS_EXPORT
27642+ struct dentry *si_dbgaufs_xigen;
27643+#endif
27644+#endif
27645+
e49829fe
JR
27646+#ifdef CONFIG_AUFS_SBILIST
27647+ struct list_head si_list;
27648+#endif
27649+
1facf9fc 27650+ /* dirty, necessary for unmounting, sysfs and sysrq */
27651+ struct super_block *si_sb;
27652+};
27653+
dece6358
AM
27654+/* sbinfo status flags */
27655+/*
27656+ * set true when refresh_dirs() failed at remount time.
27657+ * then try refreshing dirs at access time again.
27658+ * if it is false, refreshing dirs at access time is unnecesary
27659+ */
027c5e7a 27660+#define AuSi_FAILED_REFRESH_DIR 1
076b876e
AM
27661+
27662+#define AuSi_FHSM (1 << 1) /* fhsm is active now */
27663+
27664+#ifndef CONFIG_AUFS_FHSM
27665+#undef AuSi_FHSM
27666+#define AuSi_FHSM 0
27667+#endif
27668+
dece6358
AM
27669+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi,
27670+ unsigned int flag)
27671+{
27672+ AuRwMustAnyLock(&sbi->si_rwsem);
27673+ return sbi->au_si_status & flag;
27674+}
27675+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name)
27676+#define au_fset_si(sbinfo, name) do { \
27677+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27678+ (sbinfo)->au_si_status |= AuSi_##name; \
27679+} while (0)
27680+#define au_fclr_si(sbinfo, name) do { \
27681+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \
27682+ (sbinfo)->au_si_status &= ~AuSi_##name; \
27683+} while (0)
27684+
1facf9fc 27685+/* ---------------------------------------------------------------------- */
27686+
27687+/* policy to select one among writable branches */
4a4d8108
AM
27688+#define AuWbrCopyup(sbinfo, ...) \
27689+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__))
27690+#define AuWbrCreate(sbinfo, ...) \
27691+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__))
1facf9fc 27692+
27693+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */
27694+#define AuLock_DW 1 /* write-lock dentry */
27695+#define AuLock_IR (1 << 1) /* read-lock inode */
27696+#define AuLock_IW (1 << 2) /* write-lock inode */
27697+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */
27698+#define AuLock_DIR (1 << 4) /* target is a dir */
e49829fe
JR
27699+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */
27700+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */
027c5e7a 27701+#define AuLock_GEN (1 << 7) /* test digen/iigen */
1facf9fc 27702+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name)
7f207e10
AM
27703+#define au_fset_lock(flags, name) \
27704+ do { (flags) |= AuLock_##name; } while (0)
27705+#define au_fclr_lock(flags, name) \
27706+ do { (flags) &= ~AuLock_##name; } while (0)
1facf9fc 27707+
27708+/* ---------------------------------------------------------------------- */
27709+
27710+/* super.c */
27711+extern struct file_system_type aufs_fs_type;
27712+struct inode *au_iget_locked(struct super_block *sb, ino_t ino);
7f207e10
AM
27713+typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max,
27714+ void *arg);
27715+void au_array_free(void *array);
27716+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg);
27717+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max);
27718+void au_iarray_free(struct inode **a, unsigned long long max);
1facf9fc 27719+
27720+/* sbinfo.c */
27721+void au_si_free(struct kobject *kobj);
27722+int au_si_alloc(struct super_block *sb);
27723+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr);
27724+
27725+unsigned int au_sigen_inc(struct super_block *sb);
27726+aufs_bindex_t au_new_br_id(struct super_block *sb);
27727+
e49829fe
JR
27728+int si_read_lock(struct super_block *sb, int flags);
27729+int si_write_lock(struct super_block *sb, int flags);
27730+int aufs_read_lock(struct dentry *dentry, int flags);
1facf9fc 27731+void aufs_read_unlock(struct dentry *dentry, int flags);
27732+void aufs_write_lock(struct dentry *dentry);
27733+void aufs_write_unlock(struct dentry *dentry);
e49829fe 27734+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags);
1facf9fc 27735+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2);
27736+
b752ccd1
AM
27737+int si_pid_test_slow(struct super_block *sb);
27738+void si_pid_set_slow(struct super_block *sb);
27739+void si_pid_clr_slow(struct super_block *sb);
27740+
1facf9fc 27741+/* wbr_policy.c */
27742+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[];
27743+extern struct au_wbr_create_operations au_wbr_create_ops[];
27744+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst);
c2b27bf2 27745+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex);
076b876e 27746+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart);
c2b27bf2
AM
27747+
27748+/* mvdown.c */
27749+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg);
1facf9fc 27750+
076b876e
AM
27751+#ifdef CONFIG_AUFS_FHSM
27752+/* fhsm.c */
27753+
27754+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm)
27755+{
27756+ pid_t pid;
27757+
27758+ spin_lock(&fhsm->fhsm_spin);
27759+ pid = fhsm->fhsm_pid;
27760+ spin_unlock(&fhsm->fhsm_spin);
27761+
27762+ return pid;
27763+}
27764+
27765+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force);
27766+void au_fhsm_wrote_all(struct super_block *sb, int force);
27767+int au_fhsm_fd(struct super_block *sb, int oflags);
27768+int au_fhsm_br_alloc(struct au_branch *br);
c1595e42 27769+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex);
076b876e
AM
27770+void au_fhsm_fin(struct super_block *sb);
27771+void au_fhsm_init(struct au_sbinfo *sbinfo);
27772+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec);
27773+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo);
27774+#else
27775+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex,
27776+ int force)
27777+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force)
27778+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags)
c1595e42
JR
27779+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm)
27780+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br)
27781+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex)
076b876e
AM
27782+AuStubVoid(au_fhsm_fin, struct super_block *sb)
27783+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo)
27784+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec)
27785+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo)
27786+#endif
27787+
1facf9fc 27788+/* ---------------------------------------------------------------------- */
27789+
27790+static inline struct au_sbinfo *au_sbi(struct super_block *sb)
27791+{
27792+ return sb->s_fs_info;
27793+}
27794+
27795+/* ---------------------------------------------------------------------- */
27796+
27797+#ifdef CONFIG_AUFS_EXPORT
a2a7ad62 27798+int au_test_nfsd(void);
1facf9fc 27799+void au_export_init(struct super_block *sb);
b752ccd1 27800+void au_xigen_inc(struct inode *inode);
1facf9fc 27801+int au_xigen_new(struct inode *inode);
27802+int au_xigen_set(struct super_block *sb, struct file *base);
27803+void au_xigen_clr(struct super_block *sb);
27804+
27805+static inline int au_busy_or_stale(void)
27806+{
b752ccd1 27807+ if (!au_test_nfsd())
1facf9fc 27808+ return -EBUSY;
27809+ return -ESTALE;
27810+}
27811+#else
b752ccd1 27812+AuStubInt0(au_test_nfsd, void)
a2a7ad62 27813+AuStubVoid(au_export_init, struct super_block *sb)
b752ccd1 27814+AuStubVoid(au_xigen_inc, struct inode *inode)
4a4d8108
AM
27815+AuStubInt0(au_xigen_new, struct inode *inode)
27816+AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base)
27817+AuStubVoid(au_xigen_clr, struct super_block *sb)
c1595e42 27818+AuStub(int, au_busy_or_stale, return -EBUSY, void)
1facf9fc 27819+#endif /* CONFIG_AUFS_EXPORT */
27820+
27821+/* ---------------------------------------------------------------------- */
27822+
e49829fe
JR
27823+#ifdef CONFIG_AUFS_SBILIST
27824+/* module.c */
27825+extern struct au_splhead au_sbilist;
27826+
27827+static inline void au_sbilist_init(void)
27828+{
27829+ au_spl_init(&au_sbilist);
27830+}
27831+
27832+static inline void au_sbilist_add(struct super_block *sb)
27833+{
27834+ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist);
27835+}
27836+
27837+static inline void au_sbilist_del(struct super_block *sb)
27838+{
27839+ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist);
27840+}
53392da6
AM
27841+
27842+#ifdef CONFIG_AUFS_MAGIC_SYSRQ
27843+static inline void au_sbilist_lock(void)
27844+{
27845+ spin_lock(&au_sbilist.spin);
27846+}
27847+
27848+static inline void au_sbilist_unlock(void)
27849+{
27850+ spin_unlock(&au_sbilist.spin);
27851+}
27852+#define AuGFP_SBILIST GFP_ATOMIC
27853+#else
27854+AuStubVoid(au_sbilist_lock, void)
27855+AuStubVoid(au_sbilist_unlock, void)
27856+#define AuGFP_SBILIST GFP_NOFS
27857+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */
e49829fe
JR
27858+#else
27859+AuStubVoid(au_sbilist_init, void)
c1595e42
JR
27860+AuStubVoid(au_sbilist_add, struct super_block *sb)
27861+AuStubVoid(au_sbilist_del, struct super_block *sb)
53392da6
AM
27862+AuStubVoid(au_sbilist_lock, void)
27863+AuStubVoid(au_sbilist_unlock, void)
27864+#define AuGFP_SBILIST GFP_NOFS
e49829fe
JR
27865+#endif
27866+
27867+/* ---------------------------------------------------------------------- */
27868+
1facf9fc 27869+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo)
27870+{
dece6358 27871+ /*
c1595e42 27872+ * This function is a dynamic '__init' function actually,
dece6358
AM
27873+ * so the tiny check for si_rwsem is unnecessary.
27874+ */
27875+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */
1facf9fc 27876+#ifdef CONFIG_DEBUG_FS
27877+ sbinfo->si_dbgaufs = NULL;
86dc4139 27878+ sbinfo->si_dbgaufs_plink = NULL;
1facf9fc 27879+ sbinfo->si_dbgaufs_xib = NULL;
27880+#ifdef CONFIG_AUFS_EXPORT
27881+ sbinfo->si_dbgaufs_xigen = NULL;
27882+#endif
27883+#endif
27884+}
27885+
27886+/* ---------------------------------------------------------------------- */
27887+
b752ccd1
AM
27888+static inline pid_t si_pid_bit(void)
27889+{
27890+ /* the origin of pid is 1, but the bitmap's is 0 */
27891+ return current->pid - 1;
27892+}
27893+
27894+static inline int si_pid_test(struct super_block *sb)
27895+{
076b876e
AM
27896+ pid_t bit;
27897+
27898+ bit = si_pid_bit();
b752ccd1
AM
27899+ if (bit < PID_MAX_DEFAULT)
27900+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
c1595e42 27901+ return si_pid_test_slow(sb);
b752ccd1
AM
27902+}
27903+
27904+static inline void si_pid_set(struct super_block *sb)
27905+{
076b876e
AM
27906+ pid_t bit;
27907+
27908+ bit = si_pid_bit();
b752ccd1
AM
27909+ if (bit < PID_MAX_DEFAULT) {
27910+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
27911+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27912+ /* smp_mb(); */
27913+ } else
27914+ si_pid_set_slow(sb);
27915+}
27916+
27917+static inline void si_pid_clr(struct super_block *sb)
27918+{
076b876e
AM
27919+ pid_t bit;
27920+
27921+ bit = si_pid_bit();
b752ccd1
AM
27922+ if (bit < PID_MAX_DEFAULT) {
27923+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap));
27924+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap);
27925+ /* smp_mb(); */
27926+ } else
27927+ si_pid_clr_slow(sb);
27928+}
27929+
27930+/* ---------------------------------------------------------------------- */
27931+
1facf9fc 27932+/* lock superblock. mainly for entry point functions */
27933+/*
b752ccd1
AM
27934+ * __si_read_lock, __si_write_lock,
27935+ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock
1facf9fc 27936+ */
b752ccd1 27937+AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem);
1facf9fc 27938+
dece6358
AM
27939+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem)
27940+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem)
27941+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem)
27942+
b752ccd1
AM
27943+static inline void si_noflush_read_lock(struct super_block *sb)
27944+{
27945+ __si_read_lock(sb);
27946+ si_pid_set(sb);
27947+}
27948+
27949+static inline int si_noflush_read_trylock(struct super_block *sb)
27950+{
076b876e
AM
27951+ int locked;
27952+
27953+ locked = __si_read_trylock(sb);
b752ccd1
AM
27954+ if (locked)
27955+ si_pid_set(sb);
27956+ return locked;
27957+}
27958+
27959+static inline void si_noflush_write_lock(struct super_block *sb)
27960+{
27961+ __si_write_lock(sb);
27962+ si_pid_set(sb);
27963+}
27964+
27965+static inline int si_noflush_write_trylock(struct super_block *sb)
27966+{
076b876e
AM
27967+ int locked;
27968+
27969+ locked = __si_write_trylock(sb);
b752ccd1
AM
27970+ if (locked)
27971+ si_pid_set(sb);
27972+ return locked;
27973+}
27974+
e49829fe 27975+#if 0 /* unused */
1facf9fc 27976+static inline int si_read_trylock(struct super_block *sb, int flags)
27977+{
27978+ if (au_ftest_lock(flags, FLUSH))
27979+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27980+ return si_noflush_read_trylock(sb);
27981+}
e49829fe 27982+#endif
1facf9fc 27983+
b752ccd1
AM
27984+static inline void si_read_unlock(struct super_block *sb)
27985+{
27986+ si_pid_clr(sb);
27987+ __si_read_unlock(sb);
27988+}
27989+
b752ccd1 27990+#if 0 /* unused */
1facf9fc 27991+static inline int si_write_trylock(struct super_block *sb, int flags)
27992+{
27993+ if (au_ftest_lock(flags, FLUSH))
27994+ au_nwt_flush(&au_sbi(sb)->si_nowait);
27995+ return si_noflush_write_trylock(sb);
27996+}
b752ccd1
AM
27997+#endif
27998+
27999+static inline void si_write_unlock(struct super_block *sb)
28000+{
28001+ si_pid_clr(sb);
28002+ __si_write_unlock(sb);
28003+}
28004+
28005+#if 0 /* unused */
28006+static inline void si_downgrade_lock(struct super_block *sb)
28007+{
28008+ __si_downgrade_lock(sb);
28009+}
28010+#endif
1facf9fc 28011+
28012+/* ---------------------------------------------------------------------- */
28013+
28014+static inline aufs_bindex_t au_sbend(struct super_block *sb)
28015+{
dece6358 28016+ SiMustAnyLock(sb);
1facf9fc 28017+ return au_sbi(sb)->si_bend;
28018+}
28019+
28020+static inline unsigned int au_mntflags(struct super_block *sb)
28021+{
dece6358 28022+ SiMustAnyLock(sb);
1facf9fc 28023+ return au_sbi(sb)->si_mntflags;
28024+}
28025+
28026+static inline unsigned int au_sigen(struct super_block *sb)
28027+{
dece6358 28028+ SiMustAnyLock(sb);
1facf9fc 28029+ return au_sbi(sb)->si_generation;
28030+}
28031+
7f207e10
AM
28032+static inline void au_ninodes_inc(struct super_block *sb)
28033+{
28034+ atomic_long_inc(&au_sbi(sb)->si_ninodes);
28035+}
28036+
28037+static inline void au_ninodes_dec(struct super_block *sb)
28038+{
28039+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes));
28040+ atomic_long_dec(&au_sbi(sb)->si_ninodes);
28041+}
28042+
28043+static inline void au_nfiles_inc(struct super_block *sb)
28044+{
28045+ atomic_long_inc(&au_sbi(sb)->si_nfiles);
28046+}
28047+
28048+static inline void au_nfiles_dec(struct super_block *sb)
28049+{
28050+ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles));
28051+ atomic_long_dec(&au_sbi(sb)->si_nfiles);
28052+}
28053+
1facf9fc 28054+static inline struct au_branch *au_sbr(struct super_block *sb,
28055+ aufs_bindex_t bindex)
28056+{
dece6358 28057+ SiMustAnyLock(sb);
1facf9fc 28058+ return au_sbi(sb)->si_branch[0 + bindex];
28059+}
28060+
28061+static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid)
28062+{
dece6358 28063+ SiMustWriteLock(sb);
1facf9fc 28064+ au_sbi(sb)->si_xino_brid = brid;
28065+}
28066+
28067+static inline aufs_bindex_t au_xino_brid(struct super_block *sb)
28068+{
dece6358 28069+ SiMustAnyLock(sb);
1facf9fc 28070+ return au_sbi(sb)->si_xino_brid;
28071+}
28072+
28073+#endif /* __KERNEL__ */
28074+#endif /* __AUFS_SUPER_H__ */
7f207e10
AM
28075diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c
28076--- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 28077+++ linux/fs/aufs/sysaufs.c 2015-01-25 13:00:38.634380408 +0100
523b37e3 28078@@ -0,0 +1,104 @@
1facf9fc 28079+/*
523b37e3 28080+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28081+ *
28082+ * This program, aufs is free software; you can redistribute it and/or modify
28083+ * it under the terms of the GNU General Public License as published by
28084+ * the Free Software Foundation; either version 2 of the License, or
28085+ * (at your option) any later version.
dece6358
AM
28086+ *
28087+ * This program is distributed in the hope that it will be useful,
28088+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28089+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28090+ * GNU General Public License for more details.
28091+ *
28092+ * You should have received a copy of the GNU General Public License
523b37e3 28093+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28094+ */
28095+
28096+/*
28097+ * sysfs interface and lifetime management
28098+ * they are necessary regardless sysfs is disabled.
28099+ */
28100+
1facf9fc 28101+#include <linux/random.h>
1facf9fc 28102+#include "aufs.h"
28103+
28104+unsigned long sysaufs_si_mask;
e49829fe 28105+struct kset *sysaufs_kset;
1facf9fc 28106+
28107+#define AuSiAttr(_name) { \
28108+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
28109+ .show = sysaufs_si_##_name, \
28110+}
28111+
28112+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path);
28113+struct attribute *sysaufs_si_attrs[] = {
28114+ &sysaufs_si_attr_xi_path.attr,
28115+ NULL,
28116+};
28117+
4a4d8108 28118+static const struct sysfs_ops au_sbi_ops = {
1facf9fc 28119+ .show = sysaufs_si_show
28120+};
28121+
28122+static struct kobj_type au_sbi_ktype = {
28123+ .release = au_si_free,
28124+ .sysfs_ops = &au_sbi_ops,
28125+ .default_attrs = sysaufs_si_attrs
28126+};
28127+
28128+/* ---------------------------------------------------------------------- */
28129+
28130+int sysaufs_si_init(struct au_sbinfo *sbinfo)
28131+{
28132+ int err;
28133+
e49829fe 28134+ sbinfo->si_kobj.kset = sysaufs_kset;
1facf9fc 28135+ /* cf. sysaufs_name() */
28136+ err = kobject_init_and_add
e49829fe 28137+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL,
1facf9fc 28138+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo));
28139+
28140+ dbgaufs_si_null(sbinfo);
28141+ if (!err) {
28142+ err = dbgaufs_si_init(sbinfo);
28143+ if (unlikely(err))
28144+ kobject_put(&sbinfo->si_kobj);
28145+ }
28146+ return err;
28147+}
28148+
28149+void sysaufs_fin(void)
28150+{
28151+ dbgaufs_fin();
e49829fe
JR
28152+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group);
28153+ kset_unregister(sysaufs_kset);
1facf9fc 28154+}
28155+
28156+int __init sysaufs_init(void)
28157+{
28158+ int err;
28159+
28160+ do {
28161+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask));
28162+ } while (!sysaufs_si_mask);
28163+
4a4d8108 28164+ err = -EINVAL;
e49829fe
JR
28165+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj);
28166+ if (unlikely(!sysaufs_kset))
4a4d8108 28167+ goto out;
e49829fe
JR
28168+ err = PTR_ERR(sysaufs_kset);
28169+ if (IS_ERR(sysaufs_kset))
1facf9fc 28170+ goto out;
e49829fe 28171+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group);
1facf9fc 28172+ if (unlikely(err)) {
e49829fe 28173+ kset_unregister(sysaufs_kset);
1facf9fc 28174+ goto out;
28175+ }
28176+
28177+ err = dbgaufs_init();
28178+ if (unlikely(err))
28179+ sysaufs_fin();
4f0767ce 28180+out:
1facf9fc 28181+ return err;
28182+}
7f207e10
AM
28183diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h
28184--- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
28185+++ linux/fs/aufs/sysaufs.h 2015-01-25 13:00:38.634380408 +0100
28186@@ -0,0 +1,101 @@
1facf9fc 28187+/*
523b37e3 28188+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28189+ *
28190+ * This program, aufs is free software; you can redistribute it and/or modify
28191+ * it under the terms of the GNU General Public License as published by
28192+ * the Free Software Foundation; either version 2 of the License, or
28193+ * (at your option) any later version.
dece6358
AM
28194+ *
28195+ * This program is distributed in the hope that it will be useful,
28196+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28197+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28198+ * GNU General Public License for more details.
28199+ *
28200+ * You should have received a copy of the GNU General Public License
523b37e3 28201+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28202+ */
28203+
28204+/*
28205+ * sysfs interface and mount lifetime management
28206+ */
28207+
28208+#ifndef __SYSAUFS_H__
28209+#define __SYSAUFS_H__
28210+
28211+#ifdef __KERNEL__
28212+
1facf9fc 28213+#include <linux/sysfs.h>
1facf9fc 28214+#include "module.h"
28215+
dece6358
AM
28216+struct super_block;
28217+struct au_sbinfo;
28218+
1facf9fc 28219+struct sysaufs_si_attr {
28220+ struct attribute attr;
28221+ int (*show)(struct seq_file *seq, struct super_block *sb);
28222+};
28223+
28224+/* ---------------------------------------------------------------------- */
28225+
28226+/* sysaufs.c */
28227+extern unsigned long sysaufs_si_mask;
e49829fe 28228+extern struct kset *sysaufs_kset;
1facf9fc 28229+extern struct attribute *sysaufs_si_attrs[];
28230+int sysaufs_si_init(struct au_sbinfo *sbinfo);
28231+int __init sysaufs_init(void);
28232+void sysaufs_fin(void);
28233+
28234+/* ---------------------------------------------------------------------- */
28235+
28236+/* some people doesn't like to show a pointer in kernel */
28237+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo)
28238+{
28239+ return sysaufs_si_mask ^ (unsigned long)sbinfo;
28240+}
28241+
28242+#define SysaufsSiNamePrefix "si_"
28243+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16)
28244+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name)
28245+{
28246+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx",
28247+ sysaufs_si_id(sbinfo));
28248+}
28249+
28250+struct au_branch;
28251+#ifdef CONFIG_SYSFS
28252+/* sysfs.c */
28253+extern struct attribute_group *sysaufs_attr_group;
28254+
28255+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb);
28256+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
28257+ char *buf);
076b876e
AM
28258+long au_brinfo_ioctl(struct file *file, unsigned long arg);
28259+#ifdef CONFIG_COMPAT
28260+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg);
28261+#endif
1facf9fc 28262+
28263+void sysaufs_br_init(struct au_branch *br);
28264+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex);
28265+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex);
28266+
28267+#define sysaufs_brs_init() do {} while (0)
28268+
28269+#else
28270+#define sysaufs_attr_group NULL
28271+
4a4d8108 28272+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb)
c1595e42
JR
28273+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj,
28274+ struct attribute *attr, char *buf)
4a4d8108
AM
28275+AuStubVoid(sysaufs_br_init, struct au_branch *br)
28276+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex)
28277+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex)
1facf9fc 28278+
28279+static inline void sysaufs_brs_init(void)
28280+{
28281+ sysaufs_brs = 0;
28282+}
28283+
28284+#endif /* CONFIG_SYSFS */
28285+
28286+#endif /* __KERNEL__ */
28287+#endif /* __SYSAUFS_H__ */
7f207e10
AM
28288diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
28289--- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 28290+++ linux/fs/aufs/sysfs.c 2015-01-25 13:00:38.634380408 +0100
076b876e 28291@@ -0,0 +1,372 @@
1facf9fc 28292+/*
523b37e3 28293+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28294+ *
28295+ * This program, aufs is free software; you can redistribute it and/or modify
28296+ * it under the terms of the GNU General Public License as published by
28297+ * the Free Software Foundation; either version 2 of the License, or
28298+ * (at your option) any later version.
dece6358
AM
28299+ *
28300+ * This program is distributed in the hope that it will be useful,
28301+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28302+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28303+ * GNU General Public License for more details.
28304+ *
28305+ * You should have received a copy of the GNU General Public License
523b37e3 28306+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28307+ */
28308+
28309+/*
28310+ * sysfs interface
28311+ */
28312+
076b876e 28313+#include <linux/compat.h>
1facf9fc 28314+#include <linux/seq_file.h>
1facf9fc 28315+#include "aufs.h"
28316+
4a4d8108
AM
28317+#ifdef CONFIG_AUFS_FS_MODULE
28318+/* this entry violates the "one line per file" policy of sysfs */
28319+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr,
28320+ char *buf)
28321+{
28322+ ssize_t err;
28323+ static char *conf =
28324+/* this file is generated at compiling */
28325+#include "conf.str"
28326+ ;
28327+
28328+ err = snprintf(buf, PAGE_SIZE, conf);
28329+ if (unlikely(err >= PAGE_SIZE))
28330+ err = -EFBIG;
28331+ return err;
28332+}
28333+
28334+static struct kobj_attribute au_config_attr = __ATTR_RO(config);
28335+#endif
28336+
1facf9fc 28337+static struct attribute *au_attr[] = {
4a4d8108
AM
28338+#ifdef CONFIG_AUFS_FS_MODULE
28339+ &au_config_attr.attr,
28340+#endif
1facf9fc 28341+ NULL, /* need to NULL terminate the list of attributes */
28342+};
28343+
28344+static struct attribute_group sysaufs_attr_group_body = {
28345+ .attrs = au_attr
28346+};
28347+
28348+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body;
28349+
28350+/* ---------------------------------------------------------------------- */
28351+
28352+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb)
28353+{
28354+ int err;
28355+
dece6358
AM
28356+ SiMustAnyLock(sb);
28357+
1facf9fc 28358+ err = 0;
28359+ if (au_opt_test(au_mntflags(sb), XINO)) {
28360+ err = au_xino_path(seq, au_sbi(sb)->si_xib);
28361+ seq_putc(seq, '\n');
28362+ }
28363+ return err;
28364+}
28365+
28366+/*
28367+ * the lifetime of branch is independent from the entry under sysfs.
28368+ * sysfs handles the lifetime of the entry, and never call ->show() after it is
28369+ * unlinked.
28370+ */
28371+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb,
392086de 28372+ aufs_bindex_t bindex, int idx)
1facf9fc 28373+{
1e00d052 28374+ int err;
1facf9fc 28375+ struct path path;
28376+ struct dentry *root;
28377+ struct au_branch *br;
076b876e 28378+ au_br_perm_str_t perm;
1facf9fc 28379+
28380+ AuDbg("b%d\n", bindex);
28381+
1e00d052 28382+ err = 0;
1facf9fc 28383+ root = sb->s_root;
28384+ di_read_lock_parent(root, !AuLock_IR);
28385+ br = au_sbr(sb, bindex);
392086de
AM
28386+
28387+ switch (idx) {
28388+ case AuBrSysfs_BR:
28389+ path.mnt = au_br_mnt(br);
28390+ path.dentry = au_h_dptr(root, bindex);
28391+ au_seq_path(seq, &path);
076b876e
AM
28392+ au_optstr_br_perm(&perm, br->br_perm);
28393+ err = seq_printf(seq, "=%s\n", perm.a);
392086de
AM
28394+ break;
28395+ case AuBrSysfs_BRID:
28396+ err = seq_printf(seq, "%d\n", br->br_id);
392086de
AM
28397+ break;
28398+ }
076b876e
AM
28399+ di_read_unlock(root, !AuLock_IR);
28400+ if (err == -1)
28401+ err = -E2BIG;
392086de 28402+
1e00d052 28403+ return err;
1facf9fc 28404+}
28405+
28406+/* ---------------------------------------------------------------------- */
28407+
28408+static struct seq_file *au_seq(char *p, ssize_t len)
28409+{
28410+ struct seq_file *seq;
28411+
28412+ seq = kzalloc(sizeof(*seq), GFP_NOFS);
28413+ if (seq) {
28414+ /* mutex_init(&seq.lock); */
28415+ seq->buf = p;
28416+ seq->size = len;
28417+ return seq; /* success */
28418+ }
28419+
28420+ seq = ERR_PTR(-ENOMEM);
28421+ return seq;
28422+}
28423+
392086de
AM
28424+#define SysaufsBr_PREFIX "br"
28425+#define SysaufsBrid_PREFIX "brid"
1facf9fc 28426+
28427+/* todo: file size may exceed PAGE_SIZE */
28428+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr,
1308ab2a 28429+ char *buf)
1facf9fc 28430+{
28431+ ssize_t err;
392086de 28432+ int idx;
1facf9fc 28433+ long l;
28434+ aufs_bindex_t bend;
28435+ struct au_sbinfo *sbinfo;
28436+ struct super_block *sb;
28437+ struct seq_file *seq;
28438+ char *name;
28439+ struct attribute **cattr;
28440+
28441+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
28442+ sb = sbinfo->si_sb;
1308ab2a 28443+
28444+ /*
28445+ * prevent a race condition between sysfs and aufs.
28446+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which
28447+ * prohibits maintaining the sysfs entries.
28448+ * hew we acquire read lock after sysfs_get_active_two().
28449+ * on the other hand, the remount process may maintain the sysfs/aufs
28450+ * entries after acquiring write lock.
28451+ * it can cause a deadlock.
28452+ * simply we gave up processing read here.
28453+ */
28454+ err = -EBUSY;
28455+ if (unlikely(!si_noflush_read_trylock(sb)))
28456+ goto out;
1facf9fc 28457+
28458+ seq = au_seq(buf, PAGE_SIZE);
28459+ err = PTR_ERR(seq);
28460+ if (IS_ERR(seq))
1308ab2a 28461+ goto out_unlock;
1facf9fc 28462+
28463+ name = (void *)attr->name;
28464+ cattr = sysaufs_si_attrs;
28465+ while (*cattr) {
28466+ if (!strcmp(name, (*cattr)->name)) {
28467+ err = container_of(*cattr, struct sysaufs_si_attr, attr)
28468+ ->show(seq, sb);
28469+ goto out_seq;
28470+ }
28471+ cattr++;
28472+ }
28473+
392086de
AM
28474+ if (!strncmp(name, SysaufsBrid_PREFIX,
28475+ sizeof(SysaufsBrid_PREFIX) - 1)) {
28476+ idx = AuBrSysfs_BRID;
28477+ name += sizeof(SysaufsBrid_PREFIX) - 1;
28478+ } else if (!strncmp(name, SysaufsBr_PREFIX,
28479+ sizeof(SysaufsBr_PREFIX) - 1)) {
28480+ idx = AuBrSysfs_BR;
1facf9fc 28481+ name += sizeof(SysaufsBr_PREFIX) - 1;
392086de
AM
28482+ } else
28483+ BUG();
28484+
28485+ err = kstrtol(name, 10, &l);
28486+ if (!err) {
28487+ bend = au_sbend(sb);
28488+ if (l <= bend)
28489+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx);
28490+ else
28491+ err = -ENOENT;
1facf9fc 28492+ }
1facf9fc 28493+
4f0767ce 28494+out_seq:
1facf9fc 28495+ if (!err) {
28496+ err = seq->count;
28497+ /* sysfs limit */
28498+ if (unlikely(err == PAGE_SIZE))
28499+ err = -EFBIG;
28500+ }
28501+ kfree(seq);
4f0767ce 28502+out_unlock:
1facf9fc 28503+ si_read_unlock(sb);
4f0767ce 28504+out:
1facf9fc 28505+ return err;
28506+}
28507+
28508+/* ---------------------------------------------------------------------- */
28509+
076b876e
AM
28510+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg)
28511+{
28512+ int err;
28513+ int16_t brid;
28514+ aufs_bindex_t bindex, bend;
28515+ size_t sz;
28516+ char *buf;
28517+ struct seq_file *seq;
28518+ struct au_branch *br;
28519+
28520+ si_read_lock(sb, AuLock_FLUSH);
28521+ bend = au_sbend(sb);
28522+ err = bend + 1;
28523+ if (!arg)
28524+ goto out;
28525+
28526+ err = -ENOMEM;
28527+ buf = (void *)__get_free_page(GFP_NOFS);
28528+ if (unlikely(!buf))
28529+ goto out;
28530+
28531+ seq = au_seq(buf, PAGE_SIZE);
28532+ err = PTR_ERR(seq);
28533+ if (IS_ERR(seq))
28534+ goto out_buf;
28535+
28536+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path);
28537+ for (bindex = 0; bindex <= bend; bindex++, arg++) {
28538+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg));
28539+ if (unlikely(err))
28540+ break;
28541+
28542+ br = au_sbr(sb, bindex);
28543+ brid = br->br_id;
28544+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id));
28545+ err = __put_user(brid, &arg->id);
28546+ if (unlikely(err))
28547+ break;
28548+
28549+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm));
28550+ err = __put_user(br->br_perm, &arg->perm);
28551+ if (unlikely(err))
28552+ break;
28553+
28554+ au_seq_path(seq, &br->br_path);
28555+ err = seq_putc(seq, '\0');
28556+ if (!err && seq->count <= sz) {
28557+ err = copy_to_user(arg->path, seq->buf, seq->count);
28558+ seq->count = 0;
28559+ if (unlikely(err))
28560+ break;
28561+ } else {
28562+ err = -E2BIG;
28563+ goto out_seq;
28564+ }
28565+ }
28566+ if (unlikely(err))
28567+ err = -EFAULT;
28568+
28569+out_seq:
28570+ kfree(seq);
28571+out_buf:
28572+ free_page((unsigned long)buf);
28573+out:
28574+ si_read_unlock(sb);
28575+ return err;
28576+}
28577+
28578+long au_brinfo_ioctl(struct file *file, unsigned long arg)
28579+{
28580+ return au_brinfo(file->f_dentry->d_sb, (void __user *)arg);
28581+}
28582+
28583+#ifdef CONFIG_COMPAT
28584+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg)
28585+{
28586+ return au_brinfo(file->f_dentry->d_sb, compat_ptr(arg));
28587+}
28588+#endif
28589+
28590+/* ---------------------------------------------------------------------- */
28591+
1facf9fc 28592+void sysaufs_br_init(struct au_branch *br)
28593+{
392086de
AM
28594+ int i;
28595+ struct au_brsysfs *br_sysfs;
28596+ struct attribute *attr;
4a4d8108 28597+
392086de
AM
28598+ br_sysfs = br->br_sysfs;
28599+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28600+ attr = &br_sysfs->attr;
28601+ sysfs_attr_init(attr);
28602+ attr->name = br_sysfs->name;
28603+ attr->mode = S_IRUGO;
28604+ br_sysfs++;
28605+ }
1facf9fc 28606+}
28607+
28608+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex)
28609+{
28610+ struct au_branch *br;
28611+ struct kobject *kobj;
392086de
AM
28612+ struct au_brsysfs *br_sysfs;
28613+ int i;
1facf9fc 28614+ aufs_bindex_t bend;
28615+
28616+ dbgaufs_brs_del(sb, bindex);
28617+
28618+ if (!sysaufs_brs)
28619+ return;
28620+
28621+ kobj = &au_sbi(sb)->si_kobj;
28622+ bend = au_sbend(sb);
28623+ for (; bindex <= bend; bindex++) {
28624+ br = au_sbr(sb, bindex);
392086de
AM
28625+ br_sysfs = br->br_sysfs;
28626+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28627+ sysfs_remove_file(kobj, &br_sysfs->attr);
28628+ br_sysfs++;
28629+ }
1facf9fc 28630+ }
28631+}
28632+
28633+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex)
28634+{
392086de 28635+ int err, i;
1facf9fc 28636+ aufs_bindex_t bend;
28637+ struct kobject *kobj;
28638+ struct au_branch *br;
392086de 28639+ struct au_brsysfs *br_sysfs;
1facf9fc 28640+
28641+ dbgaufs_brs_add(sb, bindex);
28642+
28643+ if (!sysaufs_brs)
28644+ return;
28645+
28646+ kobj = &au_sbi(sb)->si_kobj;
28647+ bend = au_sbend(sb);
28648+ for (; bindex <= bend; bindex++) {
28649+ br = au_sbr(sb, bindex);
392086de
AM
28650+ br_sysfs = br->br_sysfs;
28651+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name),
28652+ SysaufsBr_PREFIX "%d", bindex);
28653+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name),
28654+ SysaufsBrid_PREFIX "%d", bindex);
28655+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) {
28656+ err = sysfs_create_file(kobj, &br_sysfs->attr);
28657+ if (unlikely(err))
28658+ pr_warn("failed %s under sysfs(%d)\n",
28659+ br_sysfs->name, err);
28660+ br_sysfs++;
28661+ }
1facf9fc 28662+ }
28663+}
7f207e10
AM
28664diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c
28665--- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 28666+++ linux/fs/aufs/sysrq.c 2015-01-25 13:00:38.634380408 +0100
076b876e 28667@@ -0,0 +1,157 @@
1facf9fc 28668+/*
523b37e3 28669+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28670+ *
28671+ * This program, aufs is free software; you can redistribute it and/or modify
28672+ * it under the terms of the GNU General Public License as published by
28673+ * the Free Software Foundation; either version 2 of the License, or
28674+ * (at your option) any later version.
dece6358
AM
28675+ *
28676+ * This program is distributed in the hope that it will be useful,
28677+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28678+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28679+ * GNU General Public License for more details.
28680+ *
28681+ * You should have received a copy of the GNU General Public License
523b37e3 28682+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28683+ */
28684+
28685+/*
28686+ * magic sysrq hanlder
28687+ */
28688+
1facf9fc 28689+/* #include <linux/sysrq.h> */
027c5e7a 28690+#include <linux/writeback.h>
1facf9fc 28691+#include "aufs.h"
28692+
28693+/* ---------------------------------------------------------------------- */
28694+
28695+static void sysrq_sb(struct super_block *sb)
28696+{
28697+ char *plevel;
28698+ struct au_sbinfo *sbinfo;
28699+ struct file *file;
523b37e3
AM
28700+ struct au_sphlhead *files;
28701+ struct au_finfo *finfo;
1facf9fc 28702+
28703+ plevel = au_plevel;
28704+ au_plevel = KERN_WARNING;
1facf9fc 28705+
4a4d8108 28706+ /* since we define pr_fmt, call printk directly */
c06a8ce3
AM
28707+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str)
28708+
28709+ sbinfo = au_sbi(sb);
4a4d8108 28710+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo));
c06a8ce3 28711+ pr("superblock\n");
1facf9fc 28712+ au_dpri_sb(sb);
027c5e7a
AM
28713+
28714+#if 0
c06a8ce3 28715+ pr("root dentry\n");
1facf9fc 28716+ au_dpri_dentry(sb->s_root);
c06a8ce3 28717+ pr("root inode\n");
1facf9fc 28718+ au_dpri_inode(sb->s_root->d_inode);
027c5e7a
AM
28719+#endif
28720+
1facf9fc 28721+#if 0
027c5e7a
AM
28722+ do {
28723+ int err, i, j, ndentry;
28724+ struct au_dcsub_pages dpages;
28725+ struct au_dpage *dpage;
28726+
28727+ err = au_dpages_init(&dpages, GFP_ATOMIC);
28728+ if (unlikely(err))
28729+ break;
28730+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL);
28731+ if (!err)
28732+ for (i = 0; i < dpages.ndpage; i++) {
28733+ dpage = dpages.dpages + i;
28734+ ndentry = dpage->ndentry;
28735+ for (j = 0; j < ndentry; j++)
28736+ au_dpri_dentry(dpage->dentries[j]);
28737+ }
28738+ au_dpages_free(&dpages);
28739+ } while (0);
28740+#endif
28741+
28742+#if 1
28743+ {
28744+ struct inode *i;
076b876e 28745+
c06a8ce3 28746+ pr("isolated inode\n");
2cbb1c4b
JR
28747+ spin_lock(&inode_sb_list_lock);
28748+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
28749+ spin_lock(&i->i_lock);
b4510431 28750+ if (1 || hlist_empty(&i->i_dentry))
027c5e7a 28751+ au_dpri_inode(i);
2cbb1c4b
JR
28752+ spin_unlock(&i->i_lock);
28753+ }
28754+ spin_unlock(&inode_sb_list_lock);
027c5e7a 28755+ }
1facf9fc 28756+#endif
c06a8ce3 28757+ pr("files\n");
523b37e3
AM
28758+ files = &au_sbi(sb)->si_files;
28759+ spin_lock(&files->spin);
28760+ hlist_for_each_entry(finfo, &files->head, fi_hlist) {
4a4d8108 28761+ umode_t mode;
076b876e 28762+
523b37e3 28763+ file = finfo->fi_file;
c06a8ce3 28764+ mode = file_inode(file)->i_mode;
38d290e6 28765+ if (!special_file(mode))
1facf9fc 28766+ au_dpri_file(file);
523b37e3
AM
28767+ }
28768+ spin_unlock(&files->spin);
c06a8ce3 28769+ pr("done\n");
1facf9fc 28770+
c06a8ce3 28771+#undef pr
1facf9fc 28772+ au_plevel = plevel;
1facf9fc 28773+}
28774+
28775+/* ---------------------------------------------------------------------- */
28776+
28777+/* module parameter */
28778+static char *aufs_sysrq_key = "a";
28779+module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO);
28780+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME);
28781+
0c5527e5 28782+static void au_sysrq(int key __maybe_unused)
1facf9fc 28783+{
1facf9fc 28784+ struct au_sbinfo *sbinfo;
28785+
027c5e7a 28786+ lockdep_off();
53392da6 28787+ au_sbilist_lock();
e49829fe 28788+ list_for_each_entry(sbinfo, &au_sbilist.head, si_list)
1facf9fc 28789+ sysrq_sb(sbinfo->si_sb);
53392da6 28790+ au_sbilist_unlock();
027c5e7a 28791+ lockdep_on();
1facf9fc 28792+}
28793+
28794+static struct sysrq_key_op au_sysrq_op = {
28795+ .handler = au_sysrq,
28796+ .help_msg = "Aufs",
28797+ .action_msg = "Aufs",
28798+ .enable_mask = SYSRQ_ENABLE_DUMP
28799+};
28800+
28801+/* ---------------------------------------------------------------------- */
28802+
28803+int __init au_sysrq_init(void)
28804+{
28805+ int err;
28806+ char key;
28807+
28808+ err = -1;
28809+ key = *aufs_sysrq_key;
28810+ if ('a' <= key && key <= 'z')
28811+ err = register_sysrq_key(key, &au_sysrq_op);
28812+ if (unlikely(err))
4a4d8108 28813+ pr_err("err %d, sysrq=%c\n", err, key);
1facf9fc 28814+ return err;
28815+}
28816+
28817+void au_sysrq_fin(void)
28818+{
28819+ int err;
076b876e 28820+
1facf9fc 28821+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op);
28822+ if (unlikely(err))
4a4d8108 28823+ pr_err("err %d (ignored)\n", err);
1facf9fc 28824+}
7f207e10
AM
28825diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
28826--- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 28827+++ linux/fs/aufs/vdir.c 2015-01-25 13:00:38.634380408 +0100
076b876e 28828@@ -0,0 +1,889 @@
1facf9fc 28829+/*
523b37e3 28830+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 28831+ *
28832+ * This program, aufs is free software; you can redistribute it and/or modify
28833+ * it under the terms of the GNU General Public License as published by
28834+ * the Free Software Foundation; either version 2 of the License, or
28835+ * (at your option) any later version.
dece6358
AM
28836+ *
28837+ * This program is distributed in the hope that it will be useful,
28838+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28839+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28840+ * GNU General Public License for more details.
28841+ *
28842+ * You should have received a copy of the GNU General Public License
523b37e3 28843+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 28844+ */
28845+
28846+/*
28847+ * virtual or vertical directory
28848+ */
28849+
28850+#include "aufs.h"
28851+
dece6358 28852+static unsigned int calc_size(int nlen)
1facf9fc 28853+{
dece6358 28854+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t));
1facf9fc 28855+}
28856+
28857+static int set_deblk_end(union au_vdir_deblk_p *p,
28858+ union au_vdir_deblk_p *deblk_end)
28859+{
28860+ if (calc_size(0) <= deblk_end->deblk - p->deblk) {
28861+ p->de->de_str.len = 0;
28862+ /* smp_mb(); */
28863+ return 0;
28864+ }
28865+ return -1; /* error */
28866+}
28867+
28868+/* returns true or false */
28869+static int is_deblk_end(union au_vdir_deblk_p *p,
28870+ union au_vdir_deblk_p *deblk_end)
28871+{
28872+ if (calc_size(0) <= deblk_end->deblk - p->deblk)
28873+ return !p->de->de_str.len;
28874+ return 1;
28875+}
28876+
28877+static unsigned char *last_deblk(struct au_vdir *vdir)
28878+{
28879+ return vdir->vd_deblk[vdir->vd_nblk - 1];
28880+}
28881+
28882+/* ---------------------------------------------------------------------- */
28883+
1308ab2a 28884+/* estimate the apropriate size for name hash table */
28885+unsigned int au_rdhash_est(loff_t sz)
28886+{
28887+ unsigned int n;
28888+
28889+ n = UINT_MAX;
28890+ sz >>= 10;
28891+ if (sz < n)
28892+ n = sz;
28893+ if (sz < AUFS_RDHASH_DEF)
28894+ n = AUFS_RDHASH_DEF;
4a4d8108 28895+ /* pr_info("n %u\n", n); */
1308ab2a 28896+ return n;
28897+}
28898+
1facf9fc 28899+/*
28900+ * the allocated memory has to be freed by
dece6358 28901+ * au_nhash_wh_free() or au_nhash_de_free().
1facf9fc 28902+ */
dece6358 28903+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp)
1facf9fc 28904+{
1facf9fc 28905+ struct hlist_head *head;
dece6358 28906+ unsigned int u;
076b876e 28907+ size_t sz;
1facf9fc 28908+
076b876e
AM
28909+ sz = sizeof(*nhash->nh_head) * num_hash;
28910+ head = kmalloc(sz, gfp);
dece6358
AM
28911+ if (head) {
28912+ nhash->nh_num = num_hash;
28913+ nhash->nh_head = head;
28914+ for (u = 0; u < num_hash; u++)
1facf9fc 28915+ INIT_HLIST_HEAD(head++);
dece6358 28916+ return 0; /* success */
1facf9fc 28917+ }
1facf9fc 28918+
dece6358 28919+ return -ENOMEM;
1facf9fc 28920+}
28921+
dece6358
AM
28922+static void nhash_count(struct hlist_head *head)
28923+{
28924+#if 0
28925+ unsigned long n;
28926+ struct hlist_node *pos;
28927+
28928+ n = 0;
28929+ hlist_for_each(pos, head)
28930+ n++;
4a4d8108 28931+ pr_info("%lu\n", n);
dece6358
AM
28932+#endif
28933+}
28934+
28935+static void au_nhash_wh_do_free(struct hlist_head *head)
1facf9fc 28936+{
c06a8ce3
AM
28937+ struct au_vdir_wh *pos;
28938+ struct hlist_node *node;
1facf9fc 28939+
c06a8ce3
AM
28940+ hlist_for_each_entry_safe(pos, node, head, wh_hash)
28941+ kfree(pos);
1facf9fc 28942+}
28943+
dece6358 28944+static void au_nhash_de_do_free(struct hlist_head *head)
1facf9fc 28945+{
c06a8ce3
AM
28946+ struct au_vdir_dehstr *pos;
28947+ struct hlist_node *node;
1facf9fc 28948+
c06a8ce3
AM
28949+ hlist_for_each_entry_safe(pos, node, head, hash)
28950+ au_cache_free_vdir_dehstr(pos);
1facf9fc 28951+}
28952+
dece6358
AM
28953+static void au_nhash_do_free(struct au_nhash *nhash,
28954+ void (*free)(struct hlist_head *head))
1facf9fc 28955+{
1308ab2a 28956+ unsigned int n;
1facf9fc 28957+ struct hlist_head *head;
1facf9fc 28958+
dece6358 28959+ n = nhash->nh_num;
1308ab2a 28960+ if (!n)
28961+ return;
28962+
dece6358 28963+ head = nhash->nh_head;
1308ab2a 28964+ while (n-- > 0) {
dece6358
AM
28965+ nhash_count(head);
28966+ free(head++);
1facf9fc 28967+ }
dece6358 28968+ kfree(nhash->nh_head);
1facf9fc 28969+}
28970+
dece6358 28971+void au_nhash_wh_free(struct au_nhash *whlist)
1facf9fc 28972+{
dece6358
AM
28973+ au_nhash_do_free(whlist, au_nhash_wh_do_free);
28974+}
1facf9fc 28975+
dece6358
AM
28976+static void au_nhash_de_free(struct au_nhash *delist)
28977+{
28978+ au_nhash_do_free(delist, au_nhash_de_do_free);
1facf9fc 28979+}
28980+
28981+/* ---------------------------------------------------------------------- */
28982+
28983+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt,
28984+ int limit)
28985+{
28986+ int num;
28987+ unsigned int u, n;
28988+ struct hlist_head *head;
c06a8ce3 28989+ struct au_vdir_wh *pos;
1facf9fc 28990+
28991+ num = 0;
28992+ n = whlist->nh_num;
28993+ head = whlist->nh_head;
1308ab2a 28994+ for (u = 0; u < n; u++, head++)
c06a8ce3
AM
28995+ hlist_for_each_entry(pos, head, wh_hash)
28996+ if (pos->wh_bindex == btgt && ++num > limit)
1facf9fc 28997+ return 1;
1facf9fc 28998+ return 0;
28999+}
29000+
29001+static struct hlist_head *au_name_hash(struct au_nhash *nhash,
dece6358 29002+ unsigned char *name,
1facf9fc 29003+ unsigned int len)
29004+{
dece6358
AM
29005+ unsigned int v;
29006+ /* const unsigned int magic_bit = 12; */
29007+
1308ab2a 29008+ AuDebugOn(!nhash->nh_num || !nhash->nh_head);
29009+
dece6358
AM
29010+ v = 0;
29011+ while (len--)
29012+ v += *name++;
29013+ /* v = hash_long(v, magic_bit); */
29014+ v %= nhash->nh_num;
29015+ return nhash->nh_head + v;
29016+}
29017+
29018+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name,
29019+ int nlen)
29020+{
29021+ return str->len == nlen && !memcmp(str->name, name, nlen);
1facf9fc 29022+}
29023+
29024+/* returns found or not */
dece6358 29025+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen)
1facf9fc 29026+{
29027+ struct hlist_head *head;
c06a8ce3 29028+ struct au_vdir_wh *pos;
1facf9fc 29029+ struct au_vdir_destr *str;
29030+
dece6358 29031+ head = au_name_hash(whlist, name, nlen);
c06a8ce3
AM
29032+ hlist_for_each_entry(pos, head, wh_hash) {
29033+ str = &pos->wh_str;
1facf9fc 29034+ AuDbg("%.*s\n", str->len, str->name);
dece6358
AM
29035+ if (au_nhash_test_name(str, name, nlen))
29036+ return 1;
29037+ }
29038+ return 0;
29039+}
29040+
29041+/* returns found(true) or not */
29042+static int test_known(struct au_nhash *delist, char *name, int nlen)
29043+{
29044+ struct hlist_head *head;
c06a8ce3 29045+ struct au_vdir_dehstr *pos;
dece6358
AM
29046+ struct au_vdir_destr *str;
29047+
29048+ head = au_name_hash(delist, name, nlen);
c06a8ce3
AM
29049+ hlist_for_each_entry(pos, head, hash) {
29050+ str = pos->str;
dece6358
AM
29051+ AuDbg("%.*s\n", str->len, str->name);
29052+ if (au_nhash_test_name(str, name, nlen))
1facf9fc 29053+ return 1;
29054+ }
29055+ return 0;
29056+}
29057+
dece6358
AM
29058+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino,
29059+ unsigned char d_type)
29060+{
29061+#ifdef CONFIG_AUFS_SHWH
29062+ wh->wh_ino = ino;
29063+ wh->wh_type = d_type;
29064+#endif
29065+}
29066+
29067+/* ---------------------------------------------------------------------- */
29068+
29069+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
29070+ unsigned int d_type, aufs_bindex_t bindex,
29071+ unsigned char shwh)
1facf9fc 29072+{
29073+ int err;
29074+ struct au_vdir_destr *str;
29075+ struct au_vdir_wh *wh;
29076+
dece6358 29077+ AuDbg("%.*s\n", nlen, name);
1308ab2a 29078+ AuDebugOn(!whlist->nh_num || !whlist->nh_head);
29079+
1facf9fc 29080+ err = -ENOMEM;
dece6358 29081+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS);
1facf9fc 29082+ if (unlikely(!wh))
29083+ goto out;
29084+
29085+ err = 0;
29086+ wh->wh_bindex = bindex;
dece6358
AM
29087+ if (shwh)
29088+ au_shwh_init_wh(wh, ino, d_type);
1facf9fc 29089+ str = &wh->wh_str;
dece6358
AM
29090+ str->len = nlen;
29091+ memcpy(str->name, name, nlen);
29092+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen));
1facf9fc 29093+ /* smp_mb(); */
29094+
4f0767ce 29095+out:
1facf9fc 29096+ return err;
29097+}
29098+
1facf9fc 29099+static int append_deblk(struct au_vdir *vdir)
29100+{
29101+ int err;
dece6358 29102+ unsigned long ul;
1facf9fc 29103+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
29104+ union au_vdir_deblk_p p, deblk_end;
29105+ unsigned char **o;
29106+
29107+ err = -ENOMEM;
dece6358
AM
29108+ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1),
29109+ GFP_NOFS);
1facf9fc 29110+ if (unlikely(!o))
29111+ goto out;
29112+
29113+ vdir->vd_deblk = o;
29114+ p.deblk = kmalloc(deblk_sz, GFP_NOFS);
29115+ if (p.deblk) {
29116+ ul = vdir->vd_nblk++;
29117+ vdir->vd_deblk[ul] = p.deblk;
29118+ vdir->vd_last.ul = ul;
29119+ vdir->vd_last.p.deblk = p.deblk;
29120+ deblk_end.deblk = p.deblk + deblk_sz;
29121+ err = set_deblk_end(&p, &deblk_end);
29122+ }
29123+
4f0767ce 29124+out:
1facf9fc 29125+ return err;
29126+}
29127+
dece6358
AM
29128+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino,
29129+ unsigned int d_type, struct au_nhash *delist)
29130+{
29131+ int err;
29132+ unsigned int sz;
29133+ const unsigned int deblk_sz = vdir->vd_deblk_sz;
29134+ union au_vdir_deblk_p p, *room, deblk_end;
29135+ struct au_vdir_dehstr *dehstr;
29136+
29137+ p.deblk = last_deblk(vdir);
29138+ deblk_end.deblk = p.deblk + deblk_sz;
29139+ room = &vdir->vd_last.p;
29140+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk
29141+ || !is_deblk_end(room, &deblk_end));
29142+
29143+ sz = calc_size(nlen);
29144+ if (unlikely(sz > deblk_end.deblk - room->deblk)) {
29145+ err = append_deblk(vdir);
29146+ if (unlikely(err))
29147+ goto out;
29148+
29149+ p.deblk = last_deblk(vdir);
29150+ deblk_end.deblk = p.deblk + deblk_sz;
29151+ /* smp_mb(); */
29152+ AuDebugOn(room->deblk != p.deblk);
29153+ }
29154+
29155+ err = -ENOMEM;
4a4d8108 29156+ dehstr = au_cache_alloc_vdir_dehstr();
dece6358
AM
29157+ if (unlikely(!dehstr))
29158+ goto out;
29159+
29160+ dehstr->str = &room->de->de_str;
29161+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen));
29162+ room->de->de_ino = ino;
29163+ room->de->de_type = d_type;
29164+ room->de->de_str.len = nlen;
29165+ memcpy(room->de->de_str.name, name, nlen);
29166+
29167+ err = 0;
29168+ room->deblk += sz;
29169+ if (unlikely(set_deblk_end(room, &deblk_end)))
29170+ err = append_deblk(vdir);
29171+ /* smp_mb(); */
29172+
4f0767ce 29173+out:
dece6358
AM
29174+ return err;
29175+}
29176+
29177+/* ---------------------------------------------------------------------- */
29178+
29179+void au_vdir_free(struct au_vdir *vdir)
29180+{
29181+ unsigned char **deblk;
29182+
29183+ deblk = vdir->vd_deblk;
29184+ while (vdir->vd_nblk--)
29185+ kfree(*deblk++);
29186+ kfree(vdir->vd_deblk);
29187+ au_cache_free_vdir(vdir);
29188+}
29189+
1308ab2a 29190+static struct au_vdir *alloc_vdir(struct file *file)
1facf9fc 29191+{
29192+ struct au_vdir *vdir;
1308ab2a 29193+ struct super_block *sb;
1facf9fc 29194+ int err;
29195+
1308ab2a 29196+ sb = file->f_dentry->d_sb;
dece6358
AM
29197+ SiMustAnyLock(sb);
29198+
1facf9fc 29199+ err = -ENOMEM;
29200+ vdir = au_cache_alloc_vdir();
29201+ if (unlikely(!vdir))
29202+ goto out;
29203+
29204+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS);
29205+ if (unlikely(!vdir->vd_deblk))
29206+ goto out_free;
29207+
29208+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk;
1308ab2a 29209+ if (!vdir->vd_deblk_sz) {
29210+ /* estimate the apropriate size for deblk */
29211+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL);
4a4d8108 29212+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */
1308ab2a 29213+ }
1facf9fc 29214+ vdir->vd_nblk = 0;
29215+ vdir->vd_version = 0;
29216+ vdir->vd_jiffy = 0;
29217+ err = append_deblk(vdir);
29218+ if (!err)
29219+ return vdir; /* success */
29220+
29221+ kfree(vdir->vd_deblk);
29222+
4f0767ce 29223+out_free:
1facf9fc 29224+ au_cache_free_vdir(vdir);
4f0767ce 29225+out:
1facf9fc 29226+ vdir = ERR_PTR(err);
29227+ return vdir;
29228+}
29229+
29230+static int reinit_vdir(struct au_vdir *vdir)
29231+{
29232+ int err;
29233+ union au_vdir_deblk_p p, deblk_end;
29234+
29235+ while (vdir->vd_nblk > 1) {
29236+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
29237+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
29238+ vdir->vd_nblk--;
29239+ }
29240+ p.deblk = vdir->vd_deblk[0];
29241+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz;
29242+ err = set_deblk_end(&p, &deblk_end);
29243+ /* keep vd_dblk_sz */
29244+ vdir->vd_last.ul = 0;
29245+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
29246+ vdir->vd_version = 0;
29247+ vdir->vd_jiffy = 0;
29248+ /* smp_mb(); */
29249+ return err;
29250+}
29251+
29252+/* ---------------------------------------------------------------------- */
29253+
1facf9fc 29254+#define AuFillVdir_CALLED 1
29255+#define AuFillVdir_WHABLE (1 << 1)
dece6358 29256+#define AuFillVdir_SHWH (1 << 2)
1facf9fc 29257+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name)
7f207e10
AM
29258+#define au_fset_fillvdir(flags, name) \
29259+ do { (flags) |= AuFillVdir_##name; } while (0)
29260+#define au_fclr_fillvdir(flags, name) \
29261+ do { (flags) &= ~AuFillVdir_##name; } while (0)
1facf9fc 29262+
dece6358
AM
29263+#ifndef CONFIG_AUFS_SHWH
29264+#undef AuFillVdir_SHWH
29265+#define AuFillVdir_SHWH 0
29266+#endif
29267+
1facf9fc 29268+struct fillvdir_arg {
392086de 29269+ struct dir_context ctx;
1facf9fc 29270+ struct file *file;
29271+ struct au_vdir *vdir;
dece6358
AM
29272+ struct au_nhash delist;
29273+ struct au_nhash whlist;
1facf9fc 29274+ aufs_bindex_t bindex;
29275+ unsigned int flags;
29276+ int err;
29277+};
29278+
392086de 29279+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen,
1facf9fc 29280+ loff_t offset __maybe_unused, u64 h_ino,
29281+ unsigned int d_type)
29282+{
392086de 29283+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx);
1facf9fc 29284+ char *name = (void *)__name;
29285+ struct super_block *sb;
1facf9fc 29286+ ino_t ino;
dece6358 29287+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH);
1facf9fc 29288+
1facf9fc 29289+ arg->err = 0;
dece6358 29290+ sb = arg->file->f_dentry->d_sb;
1facf9fc 29291+ au_fset_fillvdir(arg->flags, CALLED);
29292+ /* smp_mb(); */
dece6358 29293+ if (nlen <= AUFS_WH_PFX_LEN
1facf9fc 29294+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
dece6358
AM
29295+ if (test_known(&arg->delist, name, nlen)
29296+ || au_nhash_test_known_wh(&arg->whlist, name, nlen))
29297+ goto out; /* already exists or whiteouted */
1facf9fc 29298+
29299+ sb = arg->file->f_dentry->d_sb;
dece6358 29300+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino);
4a4d8108
AM
29301+ if (!arg->err) {
29302+ if (unlikely(nlen > AUFS_MAX_NAMELEN))
29303+ d_type = DT_UNKNOWN;
dece6358
AM
29304+ arg->err = append_de(arg->vdir, name, nlen, ino,
29305+ d_type, &arg->delist);
4a4d8108 29306+ }
1facf9fc 29307+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) {
29308+ name += AUFS_WH_PFX_LEN;
dece6358
AM
29309+ nlen -= AUFS_WH_PFX_LEN;
29310+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen))
29311+ goto out; /* already whiteouted */
1facf9fc 29312+
dece6358
AM
29313+ if (shwh)
29314+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type,
29315+ &ino);
4a4d8108
AM
29316+ if (!arg->err) {
29317+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN)
29318+ d_type = DT_UNKNOWN;
1facf9fc 29319+ arg->err = au_nhash_append_wh
dece6358
AM
29320+ (&arg->whlist, name, nlen, ino, d_type,
29321+ arg->bindex, shwh);
4a4d8108 29322+ }
1facf9fc 29323+ }
29324+
4f0767ce 29325+out:
1facf9fc 29326+ if (!arg->err)
29327+ arg->vdir->vd_jiffy = jiffies;
29328+ /* smp_mb(); */
29329+ AuTraceErr(arg->err);
29330+ return arg->err;
29331+}
29332+
dece6358
AM
29333+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir,
29334+ struct au_nhash *whlist, struct au_nhash *delist)
29335+{
29336+#ifdef CONFIG_AUFS_SHWH
29337+ int err;
29338+ unsigned int nh, u;
29339+ struct hlist_head *head;
c06a8ce3
AM
29340+ struct au_vdir_wh *pos;
29341+ struct hlist_node *n;
dece6358
AM
29342+ char *p, *o;
29343+ struct au_vdir_destr *destr;
29344+
29345+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH));
29346+
29347+ err = -ENOMEM;
537831f9 29348+ o = p = (void *)__get_free_page(GFP_NOFS);
dece6358
AM
29349+ if (unlikely(!p))
29350+ goto out;
29351+
29352+ err = 0;
29353+ nh = whlist->nh_num;
29354+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
29355+ p += AUFS_WH_PFX_LEN;
29356+ for (u = 0; u < nh; u++) {
29357+ head = whlist->nh_head + u;
c06a8ce3
AM
29358+ hlist_for_each_entry_safe(pos, n, head, wh_hash) {
29359+ destr = &pos->wh_str;
dece6358
AM
29360+ memcpy(p, destr->name, destr->len);
29361+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN,
c06a8ce3 29362+ pos->wh_ino, pos->wh_type, delist);
dece6358
AM
29363+ if (unlikely(err))
29364+ break;
29365+ }
29366+ }
29367+
537831f9 29368+ free_page((unsigned long)o);
dece6358 29369+
4f0767ce 29370+out:
dece6358
AM
29371+ AuTraceErr(err);
29372+ return err;
29373+#else
29374+ return 0;
29375+#endif
29376+}
29377+
1facf9fc 29378+static int au_do_read_vdir(struct fillvdir_arg *arg)
29379+{
29380+ int err;
dece6358 29381+ unsigned int rdhash;
1facf9fc 29382+ loff_t offset;
dece6358
AM
29383+ aufs_bindex_t bend, bindex, bstart;
29384+ unsigned char shwh;
1facf9fc 29385+ struct file *hf, *file;
29386+ struct super_block *sb;
29387+
1facf9fc 29388+ file = arg->file;
29389+ sb = file->f_dentry->d_sb;
dece6358
AM
29390+ SiMustAnyLock(sb);
29391+
29392+ rdhash = au_sbi(sb)->si_rdhash;
1308ab2a 29393+ if (!rdhash)
29394+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL));
dece6358
AM
29395+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS);
29396+ if (unlikely(err))
1facf9fc 29397+ goto out;
dece6358
AM
29398+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS);
29399+ if (unlikely(err))
1facf9fc 29400+ goto out_delist;
29401+
29402+ err = 0;
29403+ arg->flags = 0;
dece6358
AM
29404+ shwh = 0;
29405+ if (au_opt_test(au_mntflags(sb), SHWH)) {
29406+ shwh = 1;
29407+ au_fset_fillvdir(arg->flags, SHWH);
29408+ }
29409+ bstart = au_fbstart(file);
4a4d8108 29410+ bend = au_fbend_dir(file);
dece6358 29411+ for (bindex = bstart; !err && bindex <= bend; bindex++) {
4a4d8108 29412+ hf = au_hf_dir(file, bindex);
1facf9fc 29413+ if (!hf)
29414+ continue;
29415+
29416+ offset = vfsub_llseek(hf, 0, SEEK_SET);
29417+ err = offset;
29418+ if (unlikely(offset))
29419+ break;
29420+
29421+ arg->bindex = bindex;
29422+ au_fclr_fillvdir(arg->flags, WHABLE);
dece6358
AM
29423+ if (shwh
29424+ || (bindex != bend
29425+ && au_br_whable(au_sbr_perm(sb, bindex))))
1facf9fc 29426+ au_fset_fillvdir(arg->flags, WHABLE);
29427+ do {
29428+ arg->err = 0;
29429+ au_fclr_fillvdir(arg->flags, CALLED);
29430+ /* smp_mb(); */
392086de 29431+ err = vfsub_iterate_dir(hf, &arg->ctx);
1facf9fc 29432+ if (err >= 0)
29433+ err = arg->err;
29434+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED));
392086de
AM
29435+
29436+ /*
29437+ * dir_relax() may be good for concurrency, but aufs should not
29438+ * use it since it will cause a lockdep problem.
29439+ */
1facf9fc 29440+ }
dece6358
AM
29441+
29442+ if (!err && shwh)
29443+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist);
29444+
29445+ au_nhash_wh_free(&arg->whlist);
1facf9fc 29446+
4f0767ce 29447+out_delist:
dece6358 29448+ au_nhash_de_free(&arg->delist);
4f0767ce 29449+out:
1facf9fc 29450+ return err;
29451+}
29452+
29453+static int read_vdir(struct file *file, int may_read)
29454+{
29455+ int err;
29456+ unsigned long expire;
29457+ unsigned char do_read;
392086de
AM
29458+ struct fillvdir_arg arg = {
29459+ .ctx = {
29460+ .actor = au_diractor(fillvdir)
29461+ }
29462+ };
1facf9fc 29463+ struct inode *inode;
29464+ struct au_vdir *vdir, *allocated;
29465+
29466+ err = 0;
c06a8ce3 29467+ inode = file_inode(file);
1facf9fc 29468+ IMustLock(inode);
dece6358
AM
29469+ SiMustAnyLock(inode->i_sb);
29470+
1facf9fc 29471+ allocated = NULL;
29472+ do_read = 0;
29473+ expire = au_sbi(inode->i_sb)->si_rdcache;
29474+ vdir = au_ivdir(inode);
29475+ if (!vdir) {
29476+ do_read = 1;
1308ab2a 29477+ vdir = alloc_vdir(file);
1facf9fc 29478+ err = PTR_ERR(vdir);
29479+ if (IS_ERR(vdir))
29480+ goto out;
29481+ err = 0;
29482+ allocated = vdir;
29483+ } else if (may_read
29484+ && (inode->i_version != vdir->vd_version
29485+ || time_after(jiffies, vdir->vd_jiffy + expire))) {
29486+ do_read = 1;
29487+ err = reinit_vdir(vdir);
29488+ if (unlikely(err))
29489+ goto out;
29490+ }
29491+
29492+ if (!do_read)
29493+ return 0; /* success */
29494+
29495+ arg.file = file;
29496+ arg.vdir = vdir;
29497+ err = au_do_read_vdir(&arg);
29498+ if (!err) {
392086de 29499+ /* file->f_pos = 0; */ /* todo: ctx->pos? */
1facf9fc 29500+ vdir->vd_version = inode->i_version;
29501+ vdir->vd_last.ul = 0;
29502+ vdir->vd_last.p.deblk = vdir->vd_deblk[0];
29503+ if (allocated)
29504+ au_set_ivdir(inode, allocated);
29505+ } else if (allocated)
29506+ au_vdir_free(allocated);
29507+
4f0767ce 29508+out:
1facf9fc 29509+ return err;
29510+}
29511+
29512+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src)
29513+{
29514+ int err, rerr;
29515+ unsigned long ul, n;
29516+ const unsigned int deblk_sz = src->vd_deblk_sz;
29517+
29518+ AuDebugOn(tgt->vd_nblk != 1);
29519+
29520+ err = -ENOMEM;
29521+ if (tgt->vd_nblk < src->vd_nblk) {
29522+ unsigned char **p;
29523+
dece6358
AM
29524+ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk,
29525+ GFP_NOFS);
1facf9fc 29526+ if (unlikely(!p))
29527+ goto out;
29528+ tgt->vd_deblk = p;
29529+ }
29530+
1308ab2a 29531+ if (tgt->vd_deblk_sz != deblk_sz) {
29532+ unsigned char *p;
29533+
29534+ tgt->vd_deblk_sz = deblk_sz;
29535+ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS);
29536+ if (unlikely(!p))
29537+ goto out;
29538+ tgt->vd_deblk[0] = p;
29539+ }
1facf9fc 29540+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz);
1facf9fc 29541+ tgt->vd_version = src->vd_version;
29542+ tgt->vd_jiffy = src->vd_jiffy;
29543+
29544+ n = src->vd_nblk;
29545+ for (ul = 1; ul < n; ul++) {
dece6358
AM
29546+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz,
29547+ GFP_NOFS);
29548+ if (unlikely(!tgt->vd_deblk[ul]))
1facf9fc 29549+ goto out;
1308ab2a 29550+ tgt->vd_nblk++;
1facf9fc 29551+ }
1308ab2a 29552+ tgt->vd_nblk = n;
29553+ tgt->vd_last.ul = tgt->vd_last.ul;
29554+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul];
29555+ tgt->vd_last.p.deblk += src->vd_last.p.deblk
29556+ - src->vd_deblk[src->vd_last.ul];
1facf9fc 29557+ /* smp_mb(); */
29558+ return 0; /* success */
29559+
4f0767ce 29560+out:
1facf9fc 29561+ rerr = reinit_vdir(tgt);
29562+ BUG_ON(rerr);
29563+ return err;
29564+}
29565+
29566+int au_vdir_init(struct file *file)
29567+{
29568+ int err;
29569+ struct inode *inode;
29570+ struct au_vdir *vdir_cache, *allocated;
29571+
392086de 29572+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 29573+ err = read_vdir(file, !file->f_pos);
29574+ if (unlikely(err))
29575+ goto out;
29576+
29577+ allocated = NULL;
29578+ vdir_cache = au_fvdir_cache(file);
29579+ if (!vdir_cache) {
1308ab2a 29580+ vdir_cache = alloc_vdir(file);
1facf9fc 29581+ err = PTR_ERR(vdir_cache);
29582+ if (IS_ERR(vdir_cache))
29583+ goto out;
29584+ allocated = vdir_cache;
29585+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) {
392086de 29586+ /* test file->f_pos here instead of ctx->pos */
1facf9fc 29587+ err = reinit_vdir(vdir_cache);
29588+ if (unlikely(err))
29589+ goto out;
29590+ } else
29591+ return 0; /* success */
29592+
c06a8ce3 29593+ inode = file_inode(file);
1facf9fc 29594+ err = copy_vdir(vdir_cache, au_ivdir(inode));
29595+ if (!err) {
29596+ file->f_version = inode->i_version;
29597+ if (allocated)
29598+ au_set_fvdir_cache(file, allocated);
29599+ } else if (allocated)
29600+ au_vdir_free(allocated);
29601+
4f0767ce 29602+out:
1facf9fc 29603+ return err;
29604+}
29605+
29606+static loff_t calc_offset(struct au_vdir *vdir)
29607+{
29608+ loff_t offset;
29609+ union au_vdir_deblk_p p;
29610+
29611+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul];
29612+ offset = vdir->vd_last.p.deblk - p.deblk;
29613+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul;
29614+ return offset;
29615+}
29616+
29617+/* returns true or false */
392086de 29618+static int seek_vdir(struct file *file, struct dir_context *ctx)
1facf9fc 29619+{
29620+ int valid;
29621+ unsigned int deblk_sz;
29622+ unsigned long ul, n;
29623+ loff_t offset;
29624+ union au_vdir_deblk_p p, deblk_end;
29625+ struct au_vdir *vdir_cache;
29626+
29627+ valid = 1;
29628+ vdir_cache = au_fvdir_cache(file);
29629+ offset = calc_offset(vdir_cache);
29630+ AuDbg("offset %lld\n", offset);
392086de 29631+ if (ctx->pos == offset)
1facf9fc 29632+ goto out;
29633+
29634+ vdir_cache->vd_last.ul = 0;
29635+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0];
392086de 29636+ if (!ctx->pos)
1facf9fc 29637+ goto out;
29638+
29639+ valid = 0;
29640+ deblk_sz = vdir_cache->vd_deblk_sz;
392086de 29641+ ul = div64_u64(ctx->pos, deblk_sz);
1facf9fc 29642+ AuDbg("ul %lu\n", ul);
29643+ if (ul >= vdir_cache->vd_nblk)
29644+ goto out;
29645+
29646+ n = vdir_cache->vd_nblk;
29647+ for (; ul < n; ul++) {
29648+ p.deblk = vdir_cache->vd_deblk[ul];
29649+ deblk_end.deblk = p.deblk + deblk_sz;
29650+ offset = ul;
29651+ offset *= deblk_sz;
392086de 29652+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) {
1facf9fc 29653+ unsigned int l;
29654+
29655+ l = calc_size(p.de->de_str.len);
29656+ offset += l;
29657+ p.deblk += l;
29658+ }
29659+ if (!is_deblk_end(&p, &deblk_end)) {
29660+ valid = 1;
29661+ vdir_cache->vd_last.ul = ul;
29662+ vdir_cache->vd_last.p = p;
29663+ break;
29664+ }
29665+ }
29666+
4f0767ce 29667+out:
1facf9fc 29668+ /* smp_mb(); */
29669+ AuTraceErr(!valid);
29670+ return valid;
29671+}
29672+
392086de 29673+int au_vdir_fill_de(struct file *file, struct dir_context *ctx)
1facf9fc 29674+{
1facf9fc 29675+ unsigned int l, deblk_sz;
29676+ union au_vdir_deblk_p deblk_end;
29677+ struct au_vdir *vdir_cache;
29678+ struct au_vdir_de *de;
29679+
29680+ vdir_cache = au_fvdir_cache(file);
392086de 29681+ if (!seek_vdir(file, ctx))
1facf9fc 29682+ return 0;
29683+
29684+ deblk_sz = vdir_cache->vd_deblk_sz;
29685+ while (1) {
29686+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
29687+ deblk_end.deblk += deblk_sz;
29688+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) {
29689+ de = vdir_cache->vd_last.p.de;
29690+ AuDbg("%.*s, off%lld, i%lu, dt%d\n",
392086de 29691+ de->de_str.len, de->de_str.name, ctx->pos,
1facf9fc 29692+ (unsigned long)de->de_ino, de->de_type);
392086de
AM
29693+ if (unlikely(!dir_emit(ctx, de->de_str.name,
29694+ de->de_str.len, de->de_ino,
29695+ de->de_type))) {
1facf9fc 29696+ /* todo: ignore the error caused by udba? */
29697+ /* return err; */
29698+ return 0;
29699+ }
29700+
29701+ l = calc_size(de->de_str.len);
29702+ vdir_cache->vd_last.p.deblk += l;
392086de 29703+ ctx->pos += l;
1facf9fc 29704+ }
29705+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) {
29706+ vdir_cache->vd_last.ul++;
29707+ vdir_cache->vd_last.p.deblk
29708+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul];
392086de 29709+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul;
1facf9fc 29710+ continue;
29711+ }
29712+ break;
29713+ }
29714+
29715+ /* smp_mb(); */
29716+ return 0;
29717+}
7f207e10
AM
29718diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c
29719--- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
29720+++ linux/fs/aufs/vfsub.c 2015-01-25 13:00:38.634380408 +0100
29721@@ -0,0 +1,796 @@
1facf9fc 29722+/*
523b37e3 29723+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 29724+ *
29725+ * This program, aufs is free software; you can redistribute it and/or modify
29726+ * it under the terms of the GNU General Public License as published by
29727+ * the Free Software Foundation; either version 2 of the License, or
29728+ * (at your option) any later version.
dece6358
AM
29729+ *
29730+ * This program is distributed in the hope that it will be useful,
29731+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29732+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29733+ * GNU General Public License for more details.
29734+ *
29735+ * You should have received a copy of the GNU General Public License
523b37e3 29736+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 29737+ */
29738+
29739+/*
29740+ * sub-routines for VFS
29741+ */
29742+
1308ab2a 29743+#include <linux/ima.h>
dece6358
AM
29744+#include <linux/namei.h>
29745+#include <linux/security.h>
29746+#include <linux/splice.h>
1facf9fc 29747+#include "aufs.h"
29748+
29749+int vfsub_update_h_iattr(struct path *h_path, int *did)
29750+{
29751+ int err;
29752+ struct kstat st;
29753+ struct super_block *h_sb;
29754+
29755+ /* for remote fs, leave work for its getattr or d_revalidate */
29756+ /* for bad i_attr fs, handle them in aufs_getattr() */
29757+ /* still some fs may acquire i_mutex. we need to skip them */
29758+ err = 0;
29759+ if (!did)
29760+ did = &err;
29761+ h_sb = h_path->dentry->d_sb;
29762+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb));
29763+ if (*did)
c06a8ce3 29764+ err = vfs_getattr(h_path, &st);
1facf9fc 29765+
29766+ return err;
29767+}
29768+
29769+/* ---------------------------------------------------------------------- */
29770+
4a4d8108 29771+struct file *vfsub_dentry_open(struct path *path, int flags)
1308ab2a 29772+{
29773+ struct file *file;
29774+
b4510431 29775+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */,
7f207e10 29776+ current_cred());
2cbb1c4b
JR
29777+ if (!IS_ERR_OR_NULL(file)
29778+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
29779+ i_readcount_inc(path->dentry->d_inode);
4a4d8108 29780+
1308ab2a 29781+ return file;
29782+}
29783+
1facf9fc 29784+struct file *vfsub_filp_open(const char *path, int oflags, int mode)
29785+{
29786+ struct file *file;
29787+
2cbb1c4b 29788+ lockdep_off();
7f207e10 29789+ file = filp_open(path,
2cbb1c4b 29790+ oflags /* | __FMODE_NONOTIFY */,
7f207e10 29791+ mode);
2cbb1c4b 29792+ lockdep_on();
1facf9fc 29793+ if (IS_ERR(file))
29794+ goto out;
29795+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
29796+
4f0767ce 29797+out:
1facf9fc 29798+ return file;
29799+}
29800+
29801+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
29802+{
29803+ int err;
29804+
1facf9fc 29805+ err = kern_path(name, flags, path);
1facf9fc 29806+ if (!err && path->dentry->d_inode)
29807+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
29808+ return err;
29809+}
29810+
29811+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
29812+ int len)
29813+{
29814+ struct path path = {
29815+ .mnt = NULL
29816+ };
29817+
1308ab2a 29818+ /* VFS checks it too, but by WARN_ON_ONCE() */
1facf9fc 29819+ IMustLock(parent->d_inode);
29820+
29821+ path.dentry = lookup_one_len(name, parent, len);
29822+ if (IS_ERR(path.dentry))
29823+ goto out;
29824+ if (path.dentry->d_inode)
29825+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/
29826+
4f0767ce 29827+out:
4a4d8108 29828+ AuTraceErrPtr(path.dentry);
1facf9fc 29829+ return path.dentry;
29830+}
29831+
b4510431 29832+void vfsub_call_lkup_one(void *args)
2cbb1c4b 29833+{
b4510431
AM
29834+ struct vfsub_lkup_one_args *a = args;
29835+ *a->errp = vfsub_lkup_one(a->name, a->parent);
2cbb1c4b
JR
29836+}
29837+
1facf9fc 29838+/* ---------------------------------------------------------------------- */
29839+
29840+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
29841+ struct dentry *d2, struct au_hinode *hdir2)
29842+{
29843+ struct dentry *d;
29844+
2cbb1c4b 29845+ lockdep_off();
1facf9fc 29846+ d = lock_rename(d1, d2);
2cbb1c4b 29847+ lockdep_on();
4a4d8108 29848+ au_hn_suspend(hdir1);
1facf9fc 29849+ if (hdir1 != hdir2)
4a4d8108 29850+ au_hn_suspend(hdir2);
1facf9fc 29851+
29852+ return d;
29853+}
29854+
29855+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
29856+ struct dentry *d2, struct au_hinode *hdir2)
29857+{
4a4d8108 29858+ au_hn_resume(hdir1);
1facf9fc 29859+ if (hdir1 != hdir2)
4a4d8108 29860+ au_hn_resume(hdir2);
2cbb1c4b 29861+ lockdep_off();
1facf9fc 29862+ unlock_rename(d1, d2);
2cbb1c4b 29863+ lockdep_on();
1facf9fc 29864+}
29865+
29866+/* ---------------------------------------------------------------------- */
29867+
b4510431 29868+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl)
1facf9fc 29869+{
29870+ int err;
29871+ struct dentry *d;
29872+
29873+ IMustLock(dir);
29874+
29875+ d = path->dentry;
29876+ path->dentry = d->d_parent;
b752ccd1 29877+ err = security_path_mknod(path, d, mode, 0);
1facf9fc 29878+ path->dentry = d;
29879+ if (unlikely(err))
29880+ goto out;
29881+
c1595e42 29882+ lockdep_off();
b4510431 29883+ err = vfs_create(dir, path->dentry, mode, want_excl);
c1595e42 29884+ lockdep_on();
1facf9fc 29885+ if (!err) {
29886+ struct path tmp = *path;
29887+ int did;
29888+
29889+ vfsub_update_h_iattr(&tmp, &did);
29890+ if (did) {
29891+ tmp.dentry = path->dentry->d_parent;
29892+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29893+ }
29894+ /*ignore*/
29895+ }
29896+
4f0767ce 29897+out:
1facf9fc 29898+ return err;
29899+}
29900+
29901+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname)
29902+{
29903+ int err;
29904+ struct dentry *d;
29905+
29906+ IMustLock(dir);
29907+
29908+ d = path->dentry;
29909+ path->dentry = d->d_parent;
b752ccd1 29910+ err = security_path_symlink(path, d, symname);
1facf9fc 29911+ path->dentry = d;
29912+ if (unlikely(err))
29913+ goto out;
29914+
c1595e42 29915+ lockdep_off();
1facf9fc 29916+ err = vfs_symlink(dir, path->dentry, symname);
c1595e42 29917+ lockdep_on();
1facf9fc 29918+ if (!err) {
29919+ struct path tmp = *path;
29920+ int did;
29921+
29922+ vfsub_update_h_iattr(&tmp, &did);
29923+ if (did) {
29924+ tmp.dentry = path->dentry->d_parent;
29925+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29926+ }
29927+ /*ignore*/
29928+ }
29929+
4f0767ce 29930+out:
1facf9fc 29931+ return err;
29932+}
29933+
29934+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev)
29935+{
29936+ int err;
29937+ struct dentry *d;
29938+
29939+ IMustLock(dir);
29940+
29941+ d = path->dentry;
29942+ path->dentry = d->d_parent;
027c5e7a 29943+ err = security_path_mknod(path, d, mode, new_encode_dev(dev));
1facf9fc 29944+ path->dentry = d;
29945+ if (unlikely(err))
29946+ goto out;
29947+
c1595e42 29948+ lockdep_off();
1facf9fc 29949+ err = vfs_mknod(dir, path->dentry, mode, dev);
c1595e42 29950+ lockdep_on();
1facf9fc 29951+ if (!err) {
29952+ struct path tmp = *path;
29953+ int did;
29954+
29955+ vfsub_update_h_iattr(&tmp, &did);
29956+ if (did) {
29957+ tmp.dentry = path->dentry->d_parent;
29958+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
29959+ }
29960+ /*ignore*/
29961+ }
29962+
4f0767ce 29963+out:
1facf9fc 29964+ return err;
29965+}
29966+
29967+static int au_test_nlink(struct inode *inode)
29968+{
29969+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */
29970+
29971+ if (!au_test_fs_no_limit_nlink(inode->i_sb)
29972+ || inode->i_nlink < link_max)
29973+ return 0;
29974+ return -EMLINK;
29975+}
29976+
523b37e3
AM
29977+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path,
29978+ struct inode **delegated_inode)
1facf9fc 29979+{
29980+ int err;
29981+ struct dentry *d;
29982+
29983+ IMustLock(dir);
29984+
29985+ err = au_test_nlink(src_dentry->d_inode);
29986+ if (unlikely(err))
29987+ return err;
29988+
b4510431 29989+ /* we don't call may_linkat() */
1facf9fc 29990+ d = path->dentry;
29991+ path->dentry = d->d_parent;
b752ccd1 29992+ err = security_path_link(src_dentry, path, d);
1facf9fc 29993+ path->dentry = d;
29994+ if (unlikely(err))
29995+ goto out;
29996+
2cbb1c4b 29997+ lockdep_off();
523b37e3 29998+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode);
2cbb1c4b 29999+ lockdep_on();
1facf9fc 30000+ if (!err) {
30001+ struct path tmp = *path;
30002+ int did;
30003+
30004+ /* fuse has different memory inode for the same inumber */
30005+ vfsub_update_h_iattr(&tmp, &did);
30006+ if (did) {
30007+ tmp.dentry = path->dentry->d_parent;
30008+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30009+ tmp.dentry = src_dentry;
30010+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30011+ }
30012+ /*ignore*/
30013+ }
30014+
4f0767ce 30015+out:
1facf9fc 30016+ return err;
30017+}
30018+
30019+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
523b37e3
AM
30020+ struct inode *dir, struct path *path,
30021+ struct inode **delegated_inode)
1facf9fc 30022+{
30023+ int err;
30024+ struct path tmp = {
30025+ .mnt = path->mnt
30026+ };
30027+ struct dentry *d;
30028+
30029+ IMustLock(dir);
30030+ IMustLock(src_dir);
30031+
30032+ d = path->dentry;
30033+ path->dentry = d->d_parent;
30034+ tmp.dentry = src_dentry->d_parent;
38d290e6 30035+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0);
1facf9fc 30036+ path->dentry = d;
30037+ if (unlikely(err))
30038+ goto out;
30039+
2cbb1c4b 30040+ lockdep_off();
523b37e3 30041+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry,
38d290e6 30042+ delegated_inode, /*flags*/0);
2cbb1c4b 30043+ lockdep_on();
1facf9fc 30044+ if (!err) {
30045+ int did;
30046+
30047+ tmp.dentry = d->d_parent;
30048+ vfsub_update_h_iattr(&tmp, &did);
30049+ if (did) {
30050+ tmp.dentry = src_dentry;
30051+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30052+ tmp.dentry = src_dentry->d_parent;
30053+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30054+ }
30055+ /*ignore*/
30056+ }
30057+
4f0767ce 30058+out:
1facf9fc 30059+ return err;
30060+}
30061+
30062+int vfsub_mkdir(struct inode *dir, struct path *path, int mode)
30063+{
30064+ int err;
30065+ struct dentry *d;
30066+
30067+ IMustLock(dir);
30068+
30069+ d = path->dentry;
30070+ path->dentry = d->d_parent;
b752ccd1 30071+ err = security_path_mkdir(path, d, mode);
1facf9fc 30072+ path->dentry = d;
30073+ if (unlikely(err))
30074+ goto out;
30075+
c1595e42 30076+ lockdep_off();
1facf9fc 30077+ err = vfs_mkdir(dir, path->dentry, mode);
c1595e42 30078+ lockdep_on();
1facf9fc 30079+ if (!err) {
30080+ struct path tmp = *path;
30081+ int did;
30082+
30083+ vfsub_update_h_iattr(&tmp, &did);
30084+ if (did) {
30085+ tmp.dentry = path->dentry->d_parent;
30086+ vfsub_update_h_iattr(&tmp, /*did*/NULL);
30087+ }
30088+ /*ignore*/
30089+ }
30090+
4f0767ce 30091+out:
1facf9fc 30092+ return err;
30093+}
30094+
30095+int vfsub_rmdir(struct inode *dir, struct path *path)
30096+{
30097+ int err;
30098+ struct dentry *d;
30099+
30100+ IMustLock(dir);
30101+
30102+ d = path->dentry;
30103+ path->dentry = d->d_parent;
b752ccd1 30104+ err = security_path_rmdir(path, d);
1facf9fc 30105+ path->dentry = d;
30106+ if (unlikely(err))
30107+ goto out;
30108+
2cbb1c4b 30109+ lockdep_off();
1facf9fc 30110+ err = vfs_rmdir(dir, path->dentry);
2cbb1c4b 30111+ lockdep_on();
1facf9fc 30112+ if (!err) {
30113+ struct path tmp = {
30114+ .dentry = path->dentry->d_parent,
30115+ .mnt = path->mnt
30116+ };
30117+
30118+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
30119+ }
30120+
4f0767ce 30121+out:
1facf9fc 30122+ return err;
30123+}
30124+
30125+/* ---------------------------------------------------------------------- */
30126+
9dbd164d 30127+/* todo: support mmap_sem? */
1facf9fc 30128+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
30129+ loff_t *ppos)
30130+{
30131+ ssize_t err;
30132+
2cbb1c4b 30133+ lockdep_off();
1facf9fc 30134+ err = vfs_read(file, ubuf, count, ppos);
2cbb1c4b 30135+ lockdep_on();
1facf9fc 30136+ if (err >= 0)
30137+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30138+ return err;
30139+}
30140+
30141+/* todo: kernel_read()? */
30142+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
30143+ loff_t *ppos)
30144+{
30145+ ssize_t err;
30146+ mm_segment_t oldfs;
b752ccd1
AM
30147+ union {
30148+ void *k;
30149+ char __user *u;
30150+ } buf;
1facf9fc 30151+
b752ccd1 30152+ buf.k = kbuf;
1facf9fc 30153+ oldfs = get_fs();
30154+ set_fs(KERNEL_DS);
b752ccd1 30155+ err = vfsub_read_u(file, buf.u, count, ppos);
1facf9fc 30156+ set_fs(oldfs);
30157+ return err;
30158+}
30159+
30160+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
30161+ loff_t *ppos)
30162+{
30163+ ssize_t err;
30164+
2cbb1c4b 30165+ lockdep_off();
1facf9fc 30166+ err = vfs_write(file, ubuf, count, ppos);
2cbb1c4b 30167+ lockdep_on();
1facf9fc 30168+ if (err >= 0)
30169+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30170+ return err;
30171+}
30172+
30173+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos)
30174+{
30175+ ssize_t err;
30176+ mm_segment_t oldfs;
b752ccd1
AM
30177+ union {
30178+ void *k;
30179+ const char __user *u;
30180+ } buf;
1facf9fc 30181+
b752ccd1 30182+ buf.k = kbuf;
1facf9fc 30183+ oldfs = get_fs();
30184+ set_fs(KERNEL_DS);
b752ccd1 30185+ err = vfsub_write_u(file, buf.u, count, ppos);
1facf9fc 30186+ set_fs(oldfs);
30187+ return err;
30188+}
30189+
4a4d8108
AM
30190+int vfsub_flush(struct file *file, fl_owner_t id)
30191+{
30192+ int err;
30193+
30194+ err = 0;
523b37e3 30195+ if (file->f_op->flush) {
2cbb1c4b
JR
30196+ if (!au_test_nfs(file->f_dentry->d_sb))
30197+ err = file->f_op->flush(file, id);
30198+ else {
30199+ lockdep_off();
30200+ err = file->f_op->flush(file, id);
30201+ lockdep_on();
30202+ }
4a4d8108
AM
30203+ if (!err)
30204+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
30205+ /*ignore*/
30206+ }
30207+ return err;
30208+}
30209+
392086de 30210+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx)
1facf9fc 30211+{
30212+ int err;
30213+
523b37e3 30214+ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos);
392086de 30215+
2cbb1c4b 30216+ lockdep_off();
392086de 30217+ err = iterate_dir(file, ctx);
2cbb1c4b 30218+ lockdep_on();
1facf9fc 30219+ if (err >= 0)
30220+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
30221+ return err;
30222+}
30223+
30224+long vfsub_splice_to(struct file *in, loff_t *ppos,
30225+ struct pipe_inode_info *pipe, size_t len,
30226+ unsigned int flags)
30227+{
30228+ long err;
30229+
2cbb1c4b 30230+ lockdep_off();
0fc653ad 30231+ err = do_splice_to(in, ppos, pipe, len, flags);
2cbb1c4b 30232+ lockdep_on();
4a4d8108 30233+ file_accessed(in);
1facf9fc 30234+ if (err >= 0)
30235+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
30236+ return err;
30237+}
30238+
30239+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
30240+ loff_t *ppos, size_t len, unsigned int flags)
30241+{
30242+ long err;
30243+
2cbb1c4b 30244+ lockdep_off();
0fc653ad 30245+ err = do_splice_from(pipe, out, ppos, len, flags);
2cbb1c4b 30246+ lockdep_on();
1facf9fc 30247+ if (err >= 0)
30248+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
30249+ return err;
30250+}
30251+
53392da6
AM
30252+int vfsub_fsync(struct file *file, struct path *path, int datasync)
30253+{
30254+ int err;
30255+
30256+ /* file can be NULL */
30257+ lockdep_off();
30258+ err = vfs_fsync(file, datasync);
30259+ lockdep_on();
30260+ if (!err) {
30261+ if (!path) {
30262+ AuDebugOn(!file);
30263+ path = &file->f_path;
30264+ }
30265+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/
30266+ }
30267+ return err;
30268+}
30269+
1facf9fc 30270+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */
30271+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
30272+ struct file *h_file)
30273+{
30274+ int err;
30275+ struct inode *h_inode;
c06a8ce3 30276+ struct super_block *h_sb;
1facf9fc 30277+
1facf9fc 30278+ if (!h_file) {
c06a8ce3
AM
30279+ err = vfsub_truncate(h_path, length);
30280+ goto out;
1facf9fc 30281+ }
30282+
c06a8ce3
AM
30283+ h_inode = h_path->dentry->d_inode;
30284+ h_sb = h_inode->i_sb;
30285+ lockdep_off();
30286+ sb_start_write(h_sb);
30287+ lockdep_on();
1facf9fc 30288+ err = locks_verify_truncate(h_inode, h_file, length);
30289+ if (!err)
953406b4 30290+ err = security_path_truncate(h_path);
2cbb1c4b
JR
30291+ if (!err) {
30292+ lockdep_off();
1facf9fc 30293+ err = do_truncate(h_path->dentry, length, attr, h_file);
2cbb1c4b
JR
30294+ lockdep_on();
30295+ }
c06a8ce3
AM
30296+ lockdep_off();
30297+ sb_end_write(h_sb);
30298+ lockdep_on();
1facf9fc 30299+
4f0767ce 30300+out:
1facf9fc 30301+ return err;
30302+}
30303+
30304+/* ---------------------------------------------------------------------- */
30305+
30306+struct au_vfsub_mkdir_args {
30307+ int *errp;
30308+ struct inode *dir;
30309+ struct path *path;
30310+ int mode;
30311+};
30312+
30313+static void au_call_vfsub_mkdir(void *args)
30314+{
30315+ struct au_vfsub_mkdir_args *a = args;
30316+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode);
30317+}
30318+
30319+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode)
30320+{
30321+ int err, do_sio, wkq_err;
30322+
30323+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
30324+ if (!do_sio) {
30325+ lockdep_off();
1facf9fc 30326+ err = vfsub_mkdir(dir, path, mode);
c1595e42
JR
30327+ lockdep_on();
30328+ } else {
1facf9fc 30329+ struct au_vfsub_mkdir_args args = {
30330+ .errp = &err,
30331+ .dir = dir,
30332+ .path = path,
30333+ .mode = mode
30334+ };
30335+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args);
30336+ if (unlikely(wkq_err))
30337+ err = wkq_err;
30338+ }
30339+
30340+ return err;
30341+}
30342+
30343+struct au_vfsub_rmdir_args {
30344+ int *errp;
30345+ struct inode *dir;
30346+ struct path *path;
30347+};
30348+
30349+static void au_call_vfsub_rmdir(void *args)
30350+{
30351+ struct au_vfsub_rmdir_args *a = args;
30352+ *a->errp = vfsub_rmdir(a->dir, a->path);
30353+}
30354+
30355+int vfsub_sio_rmdir(struct inode *dir, struct path *path)
30356+{
30357+ int err, do_sio, wkq_err;
30358+
30359+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE);
c1595e42
JR
30360+ if (!do_sio) {
30361+ lockdep_off();
1facf9fc 30362+ err = vfsub_rmdir(dir, path);
c1595e42
JR
30363+ lockdep_on();
30364+ } else {
1facf9fc 30365+ struct au_vfsub_rmdir_args args = {
30366+ .errp = &err,
30367+ .dir = dir,
30368+ .path = path
30369+ };
30370+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args);
30371+ if (unlikely(wkq_err))
30372+ err = wkq_err;
30373+ }
30374+
30375+ return err;
30376+}
30377+
30378+/* ---------------------------------------------------------------------- */
30379+
30380+struct notify_change_args {
30381+ int *errp;
30382+ struct path *path;
30383+ struct iattr *ia;
523b37e3 30384+ struct inode **delegated_inode;
1facf9fc 30385+};
30386+
30387+static void call_notify_change(void *args)
30388+{
30389+ struct notify_change_args *a = args;
30390+ struct inode *h_inode;
30391+
30392+ h_inode = a->path->dentry->d_inode;
30393+ IMustLock(h_inode);
30394+
30395+ *a->errp = -EPERM;
30396+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
c1595e42 30397+ lockdep_off();
523b37e3
AM
30398+ *a->errp = notify_change(a->path->dentry, a->ia,
30399+ a->delegated_inode);
c1595e42 30400+ lockdep_on();
1facf9fc 30401+ if (!*a->errp)
30402+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/
30403+ }
30404+ AuTraceErr(*a->errp);
30405+}
30406+
523b37e3
AM
30407+int vfsub_notify_change(struct path *path, struct iattr *ia,
30408+ struct inode **delegated_inode)
1facf9fc 30409+{
30410+ int err;
30411+ struct notify_change_args args = {
523b37e3
AM
30412+ .errp = &err,
30413+ .path = path,
30414+ .ia = ia,
30415+ .delegated_inode = delegated_inode
1facf9fc 30416+ };
30417+
30418+ call_notify_change(&args);
30419+
30420+ return err;
30421+}
30422+
523b37e3
AM
30423+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
30424+ struct inode **delegated_inode)
1facf9fc 30425+{
30426+ int err, wkq_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+ wkq_err = au_wkq_wait(call_notify_change, &args);
30435+ if (unlikely(wkq_err))
30436+ err = wkq_err;
30437+
30438+ return err;
30439+}
30440+
30441+/* ---------------------------------------------------------------------- */
30442+
30443+struct unlink_args {
30444+ int *errp;
30445+ struct inode *dir;
30446+ struct path *path;
523b37e3 30447+ struct inode **delegated_inode;
1facf9fc 30448+};
30449+
30450+static void call_unlink(void *args)
30451+{
30452+ struct unlink_args *a = args;
30453+ struct dentry *d = a->path->dentry;
30454+ struct inode *h_inode;
30455+ const int stop_sillyrename = (au_test_nfs(d->d_sb)
c1595e42 30456+ && au_dcount(d) == 1);
1facf9fc 30457+
30458+ IMustLock(a->dir);
30459+
30460+ a->path->dentry = d->d_parent;
30461+ *a->errp = security_path_unlink(a->path, d);
30462+ a->path->dentry = d;
30463+ if (unlikely(*a->errp))
30464+ return;
30465+
30466+ if (!stop_sillyrename)
30467+ dget(d);
30468+ h_inode = d->d_inode;
30469+ if (h_inode)
027c5e7a 30470+ ihold(h_inode);
1facf9fc 30471+
2cbb1c4b 30472+ lockdep_off();
523b37e3 30473+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode);
2cbb1c4b 30474+ lockdep_on();
1facf9fc 30475+ if (!*a->errp) {
30476+ struct path tmp = {
30477+ .dentry = d->d_parent,
30478+ .mnt = a->path->mnt
30479+ };
30480+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/
30481+ }
30482+
30483+ if (!stop_sillyrename)
30484+ dput(d);
30485+ if (h_inode)
30486+ iput(h_inode);
30487+
30488+ AuTraceErr(*a->errp);
30489+}
30490+
30491+/*
30492+ * @dir: must be locked.
30493+ * @dentry: target dentry.
30494+ */
523b37e3
AM
30495+int vfsub_unlink(struct inode *dir, struct path *path,
30496+ struct inode **delegated_inode, int force)
1facf9fc 30497+{
30498+ int err;
30499+ struct unlink_args args = {
523b37e3
AM
30500+ .errp = &err,
30501+ .dir = dir,
30502+ .path = path,
30503+ .delegated_inode = delegated_inode
1facf9fc 30504+ };
30505+
30506+ if (!force)
30507+ call_unlink(&args);
30508+ else {
30509+ int wkq_err;
30510+
30511+ wkq_err = au_wkq_wait(call_unlink, &args);
30512+ if (unlikely(wkq_err))
30513+ err = wkq_err;
30514+ }
30515+
30516+ return err;
30517+}
7f207e10
AM
30518diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
30519--- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
30520+++ linux/fs/aufs/vfsub.h 2015-01-25 13:00:38.634380408 +0100
30521@@ -0,0 +1,310 @@
1facf9fc 30522+/*
523b37e3 30523+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30524+ *
30525+ * This program, aufs is free software; you can redistribute it and/or modify
30526+ * it under the terms of the GNU General Public License as published by
30527+ * the Free Software Foundation; either version 2 of the License, or
30528+ * (at your option) any later version.
dece6358
AM
30529+ *
30530+ * This program is distributed in the hope that it will be useful,
30531+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30532+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30533+ * GNU General Public License for more details.
30534+ *
30535+ * You should have received a copy of the GNU General Public License
523b37e3 30536+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30537+ */
30538+
30539+/*
30540+ * sub-routines for VFS
30541+ */
30542+
30543+#ifndef __AUFS_VFSUB_H__
30544+#define __AUFS_VFSUB_H__
30545+
30546+#ifdef __KERNEL__
30547+
30548+#include <linux/fs.h>
0c5527e5 30549+#include <linux/lglock.h>
b4510431 30550+#include <linux/mount.h>
c1595e42 30551+#include <linux/xattr.h>
7f207e10 30552+#include "debug.h"
1facf9fc 30553+
7f207e10 30554+/* copied from linux/fs/internal.h */
2cbb1c4b 30555+/* todo: BAD approach!! */
c06a8ce3 30556+extern void __mnt_drop_write(struct vfsmount *);
2cbb1c4b 30557+extern spinlock_t inode_sb_list_lock;
7f207e10
AM
30558+
30559+/* ---------------------------------------------------------------------- */
1facf9fc 30560+
30561+/* lock subclass for lower inode */
30562+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */
30563+/* reduce? gave up. */
30564+enum {
c1595e42 30565+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */
1facf9fc 30566+ AuLsc_I_PARENT, /* lower inode, parent first */
30567+ AuLsc_I_PARENT2, /* copyup dirs */
dece6358 30568+ AuLsc_I_PARENT3, /* copyup wh */
1facf9fc 30569+ AuLsc_I_CHILD,
30570+ AuLsc_I_CHILD2,
30571+ AuLsc_I_End
30572+};
30573+
30574+/* to debug easier, do not make them inlined functions */
30575+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx))
30576+#define IMustLock(i) MtxMustLock(&(i)->i_mutex)
30577+
30578+/* ---------------------------------------------------------------------- */
30579+
7f207e10
AM
30580+static inline void vfsub_drop_nlink(struct inode *inode)
30581+{
30582+ AuDebugOn(!inode->i_nlink);
30583+ drop_nlink(inode);
30584+}
30585+
027c5e7a
AM
30586+static inline void vfsub_dead_dir(struct inode *inode)
30587+{
30588+ AuDebugOn(!S_ISDIR(inode->i_mode));
30589+ inode->i_flags |= S_DEAD;
30590+ clear_nlink(inode);
30591+}
30592+
392086de
AM
30593+static inline int vfsub_native_ro(struct inode *inode)
30594+{
30595+ return (inode->i_sb->s_flags & MS_RDONLY)
30596+ || IS_RDONLY(inode)
30597+ /* || IS_APPEND(inode) */
30598+ || IS_IMMUTABLE(inode);
30599+}
30600+
7f207e10
AM
30601+/* ---------------------------------------------------------------------- */
30602+
30603+int vfsub_update_h_iattr(struct path *h_path, int *did);
30604+struct file *vfsub_dentry_open(struct path *path, int flags);
30605+struct file *vfsub_filp_open(const char *path, int oflags, int mode);
1facf9fc 30606+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
b4510431 30607+
1facf9fc 30608+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
30609+ int len);
b4510431
AM
30610+
30611+struct vfsub_lkup_one_args {
30612+ struct dentry **errp;
30613+ struct qstr *name;
30614+ struct dentry *parent;
30615+};
30616+
30617+static inline struct dentry *vfsub_lkup_one(struct qstr *name,
30618+ struct dentry *parent)
30619+{
30620+ return vfsub_lookup_one_len(name->name, parent, name->len);
30621+}
30622+
30623+void vfsub_call_lkup_one(void *args);
30624+
30625+/* ---------------------------------------------------------------------- */
30626+
30627+static inline int vfsub_mnt_want_write(struct vfsmount *mnt)
30628+{
30629+ int err;
076b876e 30630+
b4510431
AM
30631+ lockdep_off();
30632+ err = mnt_want_write(mnt);
30633+ lockdep_on();
30634+ return err;
30635+}
30636+
30637+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt)
30638+{
30639+ lockdep_off();
30640+ mnt_drop_write(mnt);
30641+ lockdep_on();
30642+}
1facf9fc 30643+
c06a8ce3
AM
30644+static inline void vfsub_mnt_drop_write_file(struct file *file)
30645+{
30646+ lockdep_off();
30647+ mnt_drop_write_file(file);
30648+ lockdep_on();
30649+}
30650+
1facf9fc 30651+/* ---------------------------------------------------------------------- */
30652+
30653+struct au_hinode;
30654+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
30655+ struct dentry *d2, struct au_hinode *hdir2);
30656+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
30657+ struct dentry *d2, struct au_hinode *hdir2);
30658+
537831f9
AM
30659+int vfsub_create(struct inode *dir, struct path *path, int mode,
30660+ bool want_excl);
1facf9fc 30661+int vfsub_symlink(struct inode *dir, struct path *path,
30662+ const char *symname);
30663+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev);
30664+int vfsub_link(struct dentry *src_dentry, struct inode *dir,
523b37e3 30665+ struct path *path, struct inode **delegated_inode);
1facf9fc 30666+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry,
523b37e3
AM
30667+ struct inode *hdir, struct path *path,
30668+ struct inode **delegated_inode);
1facf9fc 30669+int vfsub_mkdir(struct inode *dir, struct path *path, int mode);
30670+int vfsub_rmdir(struct inode *dir, struct path *path);
30671+
30672+/* ---------------------------------------------------------------------- */
30673+
30674+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
30675+ loff_t *ppos);
30676+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count,
30677+ loff_t *ppos);
30678+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
30679+ loff_t *ppos);
30680+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count,
30681+ loff_t *ppos);
4a4d8108 30682+int vfsub_flush(struct file *file, fl_owner_t id);
392086de
AM
30683+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx);
30684+
30685+/* just for type-check */
30686+static inline filldir_t au_diractor(int (*func)(struct dir_context *,
30687+ const char *, int, loff_t, u64,
30688+ unsigned))
30689+{
30690+ return (filldir_t)func;
30691+}
30692+
1facf9fc 30693+
c06a8ce3
AM
30694+static inline loff_t vfsub_f_size_read(struct file *file)
30695+{
30696+ return i_size_read(file_inode(file));
30697+}
30698+
4a4d8108
AM
30699+static inline unsigned int vfsub_file_flags(struct file *file)
30700+{
30701+ unsigned int flags;
30702+
30703+ spin_lock(&file->f_lock);
30704+ flags = file->f_flags;
30705+ spin_unlock(&file->f_lock);
30706+
30707+ return flags;
30708+}
1308ab2a 30709+
1facf9fc 30710+static inline void vfsub_file_accessed(struct file *h_file)
30711+{
30712+ file_accessed(h_file);
30713+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/
30714+}
30715+
30716+static inline void vfsub_touch_atime(struct vfsmount *h_mnt,
30717+ struct dentry *h_dentry)
30718+{
30719+ struct path h_path = {
30720+ .dentry = h_dentry,
30721+ .mnt = h_mnt
30722+ };
92d182d2 30723+ touch_atime(&h_path);
1facf9fc 30724+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
30725+}
30726+
0c3ec466
AM
30727+static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts,
30728+ int flags)
30729+{
30730+ return update_time(h_inode, ts, flags);
30731+ /* no vfsub_update_h_iattr() since we don't have struct path */
30732+}
30733+
4a4d8108
AM
30734+long vfsub_splice_to(struct file *in, loff_t *ppos,
30735+ struct pipe_inode_info *pipe, size_t len,
30736+ unsigned int flags);
30737+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
30738+ loff_t *ppos, size_t len, unsigned int flags);
c06a8ce3
AM
30739+
30740+static inline long vfsub_truncate(struct path *path, loff_t length)
30741+{
30742+ long err;
076b876e 30743+
c06a8ce3
AM
30744+ lockdep_off();
30745+ err = vfs_truncate(path, length);
30746+ lockdep_on();
30747+ return err;
30748+}
30749+
4a4d8108
AM
30750+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
30751+ struct file *h_file);
53392da6 30752+int vfsub_fsync(struct file *file, struct path *path, int datasync);
4a4d8108 30753+
1facf9fc 30754+/* ---------------------------------------------------------------------- */
30755+
30756+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
30757+{
30758+ loff_t err;
30759+
2cbb1c4b 30760+ lockdep_off();
1facf9fc 30761+ err = vfs_llseek(file, offset, origin);
2cbb1c4b 30762+ lockdep_on();
1facf9fc 30763+ return err;
30764+}
30765+
30766+/* ---------------------------------------------------------------------- */
30767+
30768+/* dirty workaround for strict type of fmode_t */
30769+union vfsub_fmu {
30770+ fmode_t fm;
30771+ unsigned int ui;
30772+};
30773+
30774+static inline unsigned int vfsub_fmode_to_uint(fmode_t fm)
30775+{
30776+ union vfsub_fmu u = {
30777+ .fm = fm
30778+ };
30779+
30780+ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui));
30781+
30782+ return u.ui;
30783+}
30784+
30785+static inline fmode_t vfsub_uint_to_fmode(unsigned int ui)
30786+{
30787+ union vfsub_fmu u = {
30788+ .ui = ui
30789+ };
30790+
30791+ return u.fm;
30792+}
30793+
4a4d8108
AM
30794+/* ---------------------------------------------------------------------- */
30795+
30796+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode);
30797+int vfsub_sio_rmdir(struct inode *dir, struct path *path);
523b37e3
AM
30798+int vfsub_sio_notify_change(struct path *path, struct iattr *ia,
30799+ struct inode **delegated_inode);
30800+int vfsub_notify_change(struct path *path, struct iattr *ia,
30801+ struct inode **delegated_inode);
30802+int vfsub_unlink(struct inode *dir, struct path *path,
30803+ struct inode **delegated_inode, int force);
4a4d8108 30804+
c1595e42
JR
30805+/* ---------------------------------------------------------------------- */
30806+
30807+static inline int vfsub_setxattr(struct dentry *dentry, const char *name,
30808+ const void *value, size_t size, int flags)
30809+{
30810+ int err;
30811+
30812+ lockdep_off();
30813+ err = vfs_setxattr(dentry, name, value, size, flags);
30814+ lockdep_on();
30815+
30816+ return err;
30817+}
30818+
30819+static inline int vfsub_removexattr(struct dentry *dentry, const char *name)
30820+{
30821+ int err;
30822+
30823+ lockdep_off();
30824+ err = vfs_removexattr(dentry, name);
30825+ lockdep_on();
30826+
30827+ return err;
30828+}
30829+
1facf9fc 30830+#endif /* __KERNEL__ */
30831+#endif /* __AUFS_VFSUB_H__ */
7f207e10
AM
30832diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c
30833--- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 30834+++ linux/fs/aufs/wbr_policy.c 2015-01-25 13:00:38.634380408 +0100
076b876e 30835@@ -0,0 +1,765 @@
1facf9fc 30836+/*
523b37e3 30837+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 30838+ *
30839+ * This program, aufs is free software; you can redistribute it and/or modify
30840+ * it under the terms of the GNU General Public License as published by
30841+ * the Free Software Foundation; either version 2 of the License, or
30842+ * (at your option) any later version.
dece6358
AM
30843+ *
30844+ * This program is distributed in the hope that it will be useful,
30845+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30846+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30847+ * GNU General Public License for more details.
30848+ *
30849+ * You should have received a copy of the GNU General Public License
523b37e3 30850+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 30851+ */
30852+
30853+/*
30854+ * policies for selecting one among multiple writable branches
30855+ */
30856+
30857+#include <linux/statfs.h>
30858+#include "aufs.h"
30859+
30860+/* subset of cpup_attr() */
30861+static noinline_for_stack
30862+int au_cpdown_attr(struct path *h_path, struct dentry *h_src)
30863+{
30864+ int err, sbits;
30865+ struct iattr ia;
30866+ struct inode *h_isrc;
30867+
30868+ h_isrc = h_src->d_inode;
30869+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID;
30870+ ia.ia_mode = h_isrc->i_mode;
30871+ ia.ia_uid = h_isrc->i_uid;
30872+ ia.ia_gid = h_isrc->i_gid;
30873+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID));
86dc4139 30874+ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags);
523b37e3
AM
30875+ /* no delegation since it is just created */
30876+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 30877+
30878+ /* is this nfs only? */
30879+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) {
30880+ ia.ia_valid = ATTR_FORCE | ATTR_MODE;
30881+ ia.ia_mode = h_isrc->i_mode;
523b37e3 30882+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL);
1facf9fc 30883+ }
30884+
30885+ return err;
30886+}
30887+
30888+#define AuCpdown_PARENT_OPQ 1
30889+#define AuCpdown_WHED (1 << 1)
30890+#define AuCpdown_MADE_DIR (1 << 2)
30891+#define AuCpdown_DIROPQ (1 << 3)
30892+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name)
7f207e10
AM
30893+#define au_fset_cpdown(flags, name) \
30894+ do { (flags) |= AuCpdown_##name; } while (0)
30895+#define au_fclr_cpdown(flags, name) \
30896+ do { (flags) &= ~AuCpdown_##name; } while (0)
1facf9fc 30897+
1facf9fc 30898+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst,
c2b27bf2 30899+ unsigned int *flags)
1facf9fc 30900+{
30901+ int err;
30902+ struct dentry *opq_dentry;
30903+
30904+ opq_dentry = au_diropq_create(dentry, bdst);
30905+ err = PTR_ERR(opq_dentry);
30906+ if (IS_ERR(opq_dentry))
30907+ goto out;
30908+ dput(opq_dentry);
c2b27bf2 30909+ au_fset_cpdown(*flags, DIROPQ);
1facf9fc 30910+
4f0767ce 30911+out:
1facf9fc 30912+ return err;
30913+}
30914+
30915+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent,
30916+ struct inode *dir, aufs_bindex_t bdst)
30917+{
30918+ int err;
30919+ struct path h_path;
30920+ struct au_branch *br;
30921+
30922+ br = au_sbr(dentry->d_sb, bdst);
30923+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br);
30924+ err = PTR_ERR(h_path.dentry);
30925+ if (IS_ERR(h_path.dentry))
30926+ goto out;
30927+
30928+ err = 0;
30929+ if (h_path.dentry->d_inode) {
86dc4139 30930+ h_path.mnt = au_br_mnt(br);
1facf9fc 30931+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path,
30932+ dentry);
30933+ }
30934+ dput(h_path.dentry);
30935+
4f0767ce 30936+out:
1facf9fc 30937+ return err;
30938+}
30939+
30940+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst,
86dc4139 30941+ struct au_pin *pin,
1facf9fc 30942+ struct dentry *h_parent, void *arg)
30943+{
30944+ int err, rerr;
4a4d8108 30945+ aufs_bindex_t bopq, bstart;
1facf9fc 30946+ struct path h_path;
30947+ struct dentry *parent;
30948+ struct inode *h_dir, *h_inode, *inode, *dir;
c2b27bf2 30949+ unsigned int *flags = arg;
1facf9fc 30950+
30951+ bstart = au_dbstart(dentry);
30952+ /* dentry is di-locked */
30953+ parent = dget_parent(dentry);
30954+ dir = parent->d_inode;
30955+ h_dir = h_parent->d_inode;
30956+ AuDebugOn(h_dir != au_h_iptr(dir, bdst));
30957+ IMustLock(h_dir);
30958+
86dc4139 30959+ err = au_lkup_neg(dentry, bdst, /*wh*/0);
1facf9fc 30960+ if (unlikely(err < 0))
30961+ goto out;
30962+ h_path.dentry = au_h_dptr(dentry, bdst);
30963+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst);
30964+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path,
30965+ S_IRWXU | S_IRUGO | S_IXUGO);
30966+ if (unlikely(err))
30967+ goto out_put;
c2b27bf2 30968+ au_fset_cpdown(*flags, MADE_DIR);
1facf9fc 30969+
1facf9fc 30970+ bopq = au_dbdiropq(dentry);
c2b27bf2
AM
30971+ au_fclr_cpdown(*flags, WHED);
30972+ au_fclr_cpdown(*flags, DIROPQ);
1facf9fc 30973+ if (au_dbwh(dentry) == bdst)
c2b27bf2
AM
30974+ au_fset_cpdown(*flags, WHED);
30975+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst)
30976+ au_fset_cpdown(*flags, PARENT_OPQ);
1facf9fc 30977+ h_inode = h_path.dentry->d_inode;
30978+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
c2b27bf2
AM
30979+ if (au_ftest_cpdown(*flags, WHED)) {
30980+ err = au_cpdown_dir_opq(dentry, bdst, flags);
1facf9fc 30981+ if (unlikely(err)) {
30982+ mutex_unlock(&h_inode->i_mutex);
30983+ goto out_dir;
30984+ }
30985+ }
30986+
30987+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart));
30988+ mutex_unlock(&h_inode->i_mutex);
30989+ if (unlikely(err))
30990+ goto out_opq;
30991+
c2b27bf2 30992+ if (au_ftest_cpdown(*flags, WHED)) {
1facf9fc 30993+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst);
30994+ if (unlikely(err))
30995+ goto out_opq;
30996+ }
30997+
30998+ inode = dentry->d_inode;
30999+ if (au_ibend(inode) < bdst)
31000+ au_set_ibend(inode, bdst);
31001+ au_set_h_iptr(inode, bdst, au_igrab(h_inode),
31002+ au_hi_flags(inode, /*isdir*/1));
076b876e 31003+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0);
1facf9fc 31004+ goto out; /* success */
31005+
31006+ /* revert */
4f0767ce 31007+out_opq:
c2b27bf2 31008+ if (au_ftest_cpdown(*flags, DIROPQ)) {
1facf9fc 31009+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
31010+ rerr = au_diropq_remove(dentry, bdst);
31011+ mutex_unlock(&h_inode->i_mutex);
31012+ if (unlikely(rerr)) {
523b37e3
AM
31013+ AuIOErr("failed removing diropq for %pd b%d (%d)\n",
31014+ dentry, bdst, rerr);
1facf9fc 31015+ err = -EIO;
31016+ goto out;
31017+ }
31018+ }
4f0767ce 31019+out_dir:
c2b27bf2 31020+ if (au_ftest_cpdown(*flags, MADE_DIR)) {
1facf9fc 31021+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path);
31022+ if (unlikely(rerr)) {
523b37e3
AM
31023+ AuIOErr("failed removing %pd b%d (%d)\n",
31024+ dentry, bdst, rerr);
1facf9fc 31025+ err = -EIO;
31026+ }
31027+ }
4f0767ce 31028+out_put:
1facf9fc 31029+ au_set_h_dptr(dentry, bdst, NULL);
31030+ if (au_dbend(dentry) == bdst)
31031+ au_update_dbend(dentry);
4f0767ce 31032+out:
1facf9fc 31033+ dput(parent);
31034+ return err;
31035+}
31036+
31037+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst)
31038+{
31039+ int err;
c2b27bf2 31040+ unsigned int flags;
1facf9fc 31041+
c2b27bf2
AM
31042+ flags = 0;
31043+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags);
1facf9fc 31044+
31045+ return err;
31046+}
31047+
31048+/* ---------------------------------------------------------------------- */
31049+
31050+/* policies for create */
31051+
c2b27bf2 31052+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex)
4a4d8108
AM
31053+{
31054+ int err, i, j, ndentry;
31055+ aufs_bindex_t bopq;
31056+ struct au_dcsub_pages dpages;
31057+ struct au_dpage *dpage;
31058+ struct dentry **dentries, *parent, *d;
31059+
31060+ err = au_dpages_init(&dpages, GFP_NOFS);
31061+ if (unlikely(err))
31062+ goto out;
31063+ parent = dget_parent(dentry);
027c5e7a 31064+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0);
4a4d8108
AM
31065+ if (unlikely(err))
31066+ goto out_free;
31067+
31068+ err = bindex;
31069+ for (i = 0; i < dpages.ndpage; i++) {
31070+ dpage = dpages.dpages + i;
31071+ dentries = dpage->dentries;
31072+ ndentry = dpage->ndentry;
31073+ for (j = 0; j < ndentry; j++) {
31074+ d = dentries[j];
31075+ di_read_lock_parent2(d, !AuLock_IR);
31076+ bopq = au_dbdiropq(d);
31077+ di_read_unlock(d, !AuLock_IR);
31078+ if (bopq >= 0 && bopq < err)
31079+ err = bopq;
31080+ }
31081+ }
31082+
31083+out_free:
31084+ dput(parent);
31085+ au_dpages_free(&dpages);
31086+out:
31087+ return err;
31088+}
31089+
1facf9fc 31090+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex)
31091+{
31092+ for (; bindex >= 0; bindex--)
31093+ if (!au_br_rdonly(au_sbr(sb, bindex)))
31094+ return bindex;
31095+ return -EROFS;
31096+}
31097+
31098+/* top down parent */
392086de
AM
31099+static int au_wbr_create_tdp(struct dentry *dentry,
31100+ unsigned int flags __maybe_unused)
1facf9fc 31101+{
31102+ int err;
31103+ aufs_bindex_t bstart, bindex;
31104+ struct super_block *sb;
31105+ struct dentry *parent, *h_parent;
31106+
31107+ sb = dentry->d_sb;
31108+ bstart = au_dbstart(dentry);
31109+ err = bstart;
31110+ if (!au_br_rdonly(au_sbr(sb, bstart)))
31111+ goto out;
31112+
31113+ err = -EROFS;
31114+ parent = dget_parent(dentry);
31115+ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) {
31116+ h_parent = au_h_dptr(parent, bindex);
31117+ if (!h_parent || !h_parent->d_inode)
31118+ continue;
31119+
31120+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
31121+ err = bindex;
31122+ break;
31123+ }
31124+ }
31125+ dput(parent);
31126+
31127+ /* bottom up here */
4a4d8108 31128+ if (unlikely(err < 0)) {
1facf9fc 31129+ err = au_wbr_bu(sb, bstart - 1);
4a4d8108
AM
31130+ if (err >= 0)
31131+ err = au_wbr_nonopq(dentry, err);
31132+ }
1facf9fc 31133+
4f0767ce 31134+out:
1facf9fc 31135+ AuDbg("b%d\n", err);
31136+ return err;
31137+}
31138+
31139+/* ---------------------------------------------------------------------- */
31140+
31141+/* an exception for the policy other than tdp */
31142+static int au_wbr_create_exp(struct dentry *dentry)
31143+{
31144+ int err;
31145+ aufs_bindex_t bwh, bdiropq;
31146+ struct dentry *parent;
31147+
31148+ err = -1;
31149+ bwh = au_dbwh(dentry);
31150+ parent = dget_parent(dentry);
31151+ bdiropq = au_dbdiropq(parent);
31152+ if (bwh >= 0) {
31153+ if (bdiropq >= 0)
31154+ err = min(bdiropq, bwh);
31155+ else
31156+ err = bwh;
31157+ AuDbg("%d\n", err);
31158+ } else if (bdiropq >= 0) {
31159+ err = bdiropq;
31160+ AuDbg("%d\n", err);
31161+ }
31162+ dput(parent);
31163+
4a4d8108
AM
31164+ if (err >= 0)
31165+ err = au_wbr_nonopq(dentry, err);
31166+
1facf9fc 31167+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err)))
31168+ err = -1;
31169+
31170+ AuDbg("%d\n", err);
31171+ return err;
31172+}
31173+
31174+/* ---------------------------------------------------------------------- */
31175+
31176+/* round robin */
31177+static int au_wbr_create_init_rr(struct super_block *sb)
31178+{
31179+ int err;
31180+
31181+ err = au_wbr_bu(sb, au_sbend(sb));
31182+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */
dece6358 31183+ /* smp_mb(); */
1facf9fc 31184+
31185+ AuDbg("b%d\n", err);
31186+ return err;
31187+}
31188+
392086de 31189+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags)
1facf9fc 31190+{
31191+ int err, nbr;
31192+ unsigned int u;
31193+ aufs_bindex_t bindex, bend;
31194+ struct super_block *sb;
31195+ atomic_t *next;
31196+
31197+ err = au_wbr_create_exp(dentry);
31198+ if (err >= 0)
31199+ goto out;
31200+
31201+ sb = dentry->d_sb;
31202+ next = &au_sbi(sb)->si_wbr_rr_next;
31203+ bend = au_sbend(sb);
31204+ nbr = bend + 1;
31205+ for (bindex = 0; bindex <= bend; bindex++) {
392086de 31206+ if (!au_ftest_wbr(flags, DIR)) {
1facf9fc 31207+ err = atomic_dec_return(next) + 1;
31208+ /* modulo for 0 is meaningless */
31209+ if (unlikely(!err))
31210+ err = atomic_dec_return(next) + 1;
31211+ } else
31212+ err = atomic_read(next);
31213+ AuDbg("%d\n", err);
31214+ u = err;
31215+ err = u % nbr;
31216+ AuDbg("%d\n", err);
31217+ if (!au_br_rdonly(au_sbr(sb, err)))
31218+ break;
31219+ err = -EROFS;
31220+ }
31221+
4a4d8108
AM
31222+ if (err >= 0)
31223+ err = au_wbr_nonopq(dentry, err);
31224+
4f0767ce 31225+out:
1facf9fc 31226+ AuDbg("%d\n", err);
31227+ return err;
31228+}
31229+
31230+/* ---------------------------------------------------------------------- */
31231+
31232+/* most free space */
392086de 31233+static void au_mfs(struct dentry *dentry, struct dentry *parent)
1facf9fc 31234+{
31235+ struct super_block *sb;
31236+ struct au_branch *br;
31237+ struct au_wbr_mfs *mfs;
392086de 31238+ struct dentry *h_parent;
1facf9fc 31239+ aufs_bindex_t bindex, bend;
31240+ int err;
31241+ unsigned long long b, bavail;
7f207e10 31242+ struct path h_path;
1facf9fc 31243+ /* reduce the stack usage */
31244+ struct kstatfs *st;
31245+
31246+ st = kmalloc(sizeof(*st), GFP_NOFS);
31247+ if (unlikely(!st)) {
31248+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM);
31249+ return;
31250+ }
31251+
31252+ bavail = 0;
31253+ sb = dentry->d_sb;
31254+ mfs = &au_sbi(sb)->si_wbr_mfs;
dece6358 31255+ MtxMustLock(&mfs->mfs_lock);
1facf9fc 31256+ mfs->mfs_bindex = -EROFS;
31257+ mfs->mfsrr_bytes = 0;
392086de
AM
31258+ if (!parent) {
31259+ bindex = 0;
31260+ bend = au_sbend(sb);
31261+ } else {
31262+ bindex = au_dbstart(parent);
31263+ bend = au_dbtaildir(parent);
31264+ }
31265+
31266+ for (; bindex <= bend; bindex++) {
31267+ if (parent) {
31268+ h_parent = au_h_dptr(parent, bindex);
31269+ if (!h_parent || !h_parent->d_inode)
31270+ continue;
31271+ }
1facf9fc 31272+ br = au_sbr(sb, bindex);
31273+ if (au_br_rdonly(br))
31274+ continue;
31275+
31276+ /* sb->s_root for NFS is unreliable */
86dc4139 31277+ h_path.mnt = au_br_mnt(br);
7f207e10
AM
31278+ h_path.dentry = h_path.mnt->mnt_root;
31279+ err = vfs_statfs(&h_path, st);
1facf9fc 31280+ if (unlikely(err)) {
31281+ AuWarn1("failed statfs, b%d, %d\n", bindex, err);
31282+ continue;
31283+ }
31284+
31285+ /* when the available size is equal, select the lower one */
31286+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail)
31287+ || sizeof(b) < sizeof(st->f_bsize));
31288+ b = st->f_bavail * st->f_bsize;
31289+ br->br_wbr->wbr_bytes = b;
31290+ if (b >= bavail) {
31291+ bavail = b;
31292+ mfs->mfs_bindex = bindex;
31293+ mfs->mfs_jiffy = jiffies;
31294+ }
31295+ }
31296+
31297+ mfs->mfsrr_bytes = bavail;
31298+ AuDbg("b%d\n", mfs->mfs_bindex);
31299+ kfree(st);
31300+}
31301+
392086de 31302+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
1facf9fc 31303+{
31304+ int err;
392086de 31305+ struct dentry *parent;
1facf9fc 31306+ struct super_block *sb;
31307+ struct au_wbr_mfs *mfs;
31308+
31309+ err = au_wbr_create_exp(dentry);
31310+ if (err >= 0)
31311+ goto out;
31312+
31313+ sb = dentry->d_sb;
392086de
AM
31314+ parent = NULL;
31315+ if (au_ftest_wbr(flags, PARENT))
31316+ parent = dget_parent(dentry);
1facf9fc 31317+ mfs = &au_sbi(sb)->si_wbr_mfs;
31318+ mutex_lock(&mfs->mfs_lock);
31319+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire)
31320+ || mfs->mfs_bindex < 0
31321+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))
392086de 31322+ au_mfs(dentry, parent);
1facf9fc 31323+ mutex_unlock(&mfs->mfs_lock);
31324+ err = mfs->mfs_bindex;
392086de 31325+ dput(parent);
1facf9fc 31326+
4a4d8108
AM
31327+ if (err >= 0)
31328+ err = au_wbr_nonopq(dentry, err);
31329+
4f0767ce 31330+out:
1facf9fc 31331+ AuDbg("b%d\n", err);
31332+ return err;
31333+}
31334+
31335+static int au_wbr_create_init_mfs(struct super_block *sb)
31336+{
31337+ struct au_wbr_mfs *mfs;
31338+
31339+ mfs = &au_sbi(sb)->si_wbr_mfs;
31340+ mutex_init(&mfs->mfs_lock);
31341+ mfs->mfs_jiffy = 0;
31342+ mfs->mfs_bindex = -EROFS;
31343+
31344+ return 0;
31345+}
31346+
31347+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused)
31348+{
31349+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock);
31350+ return 0;
31351+}
31352+
31353+/* ---------------------------------------------------------------------- */
31354+
31355+/* most free space and then round robin */
392086de 31356+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags)
1facf9fc 31357+{
31358+ int err;
31359+ struct au_wbr_mfs *mfs;
31360+
392086de 31361+ err = au_wbr_create_mfs(dentry, flags);
1facf9fc 31362+ if (err >= 0) {
31363+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs;
dece6358 31364+ mutex_lock(&mfs->mfs_lock);
1facf9fc 31365+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark)
392086de 31366+ err = au_wbr_create_rr(dentry, flags);
dece6358 31367+ mutex_unlock(&mfs->mfs_lock);
1facf9fc 31368+ }
31369+
31370+ AuDbg("b%d\n", err);
31371+ return err;
31372+}
31373+
31374+static int au_wbr_create_init_mfsrr(struct super_block *sb)
31375+{
31376+ int err;
31377+
31378+ au_wbr_create_init_mfs(sb); /* ignore */
31379+ err = au_wbr_create_init_rr(sb);
31380+
31381+ return err;
31382+}
31383+
31384+/* ---------------------------------------------------------------------- */
31385+
31386+/* top down parent and most free space */
392086de 31387+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags)
1facf9fc 31388+{
31389+ int err, e2;
31390+ unsigned long long b;
31391+ aufs_bindex_t bindex, bstart, bend;
31392+ struct super_block *sb;
31393+ struct dentry *parent, *h_parent;
31394+ struct au_branch *br;
31395+
392086de 31396+ err = au_wbr_create_tdp(dentry, flags);
1facf9fc 31397+ if (unlikely(err < 0))
31398+ goto out;
31399+ parent = dget_parent(dentry);
31400+ bstart = au_dbstart(parent);
31401+ bend = au_dbtaildir(parent);
31402+ if (bstart == bend)
31403+ goto out_parent; /* success */
31404+
392086de 31405+ e2 = au_wbr_create_mfs(dentry, flags);
1facf9fc 31406+ if (e2 < 0)
31407+ goto out_parent; /* success */
31408+
31409+ /* when the available size is equal, select upper one */
31410+ sb = dentry->d_sb;
31411+ br = au_sbr(sb, err);
31412+ b = br->br_wbr->wbr_bytes;
31413+ AuDbg("b%d, %llu\n", err, b);
31414+
31415+ for (bindex = bstart; bindex <= bend; bindex++) {
31416+ h_parent = au_h_dptr(parent, bindex);
31417+ if (!h_parent || !h_parent->d_inode)
31418+ continue;
31419+
31420+ br = au_sbr(sb, bindex);
31421+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) {
31422+ b = br->br_wbr->wbr_bytes;
31423+ err = bindex;
31424+ AuDbg("b%d, %llu\n", err, b);
31425+ }
31426+ }
31427+
4a4d8108
AM
31428+ if (err >= 0)
31429+ err = au_wbr_nonopq(dentry, err);
31430+
4f0767ce 31431+out_parent:
1facf9fc 31432+ dput(parent);
4f0767ce 31433+out:
1facf9fc 31434+ AuDbg("b%d\n", err);
31435+ return err;
31436+}
31437+
31438+/* ---------------------------------------------------------------------- */
31439+
392086de
AM
31440+/*
31441+ * - top down parent
31442+ * - most free space with parent
31443+ * - most free space round-robin regardless parent
31444+ */
31445+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags)
31446+{
31447+ int err;
31448+ unsigned long long watermark;
31449+ struct super_block *sb;
31450+ struct au_branch *br;
31451+ struct au_wbr_mfs *mfs;
31452+
31453+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT);
31454+ if (unlikely(err < 0))
31455+ goto out;
31456+
31457+ sb = dentry->d_sb;
31458+ br = au_sbr(sb, err);
31459+ mfs = &au_sbi(sb)->si_wbr_mfs;
31460+ mutex_lock(&mfs->mfs_lock);
31461+ watermark = mfs->mfsrr_watermark;
31462+ mutex_unlock(&mfs->mfs_lock);
31463+ if (br->br_wbr->wbr_bytes < watermark)
31464+ /* regardless the parent dir */
31465+ err = au_wbr_create_mfsrr(dentry, flags);
31466+
31467+out:
31468+ AuDbg("b%d\n", err);
31469+ return err;
31470+}
31471+
31472+/* ---------------------------------------------------------------------- */
31473+
1facf9fc 31474+/* policies for copyup */
31475+
31476+/* top down parent */
31477+static int au_wbr_copyup_tdp(struct dentry *dentry)
31478+{
392086de 31479+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0);
1facf9fc 31480+}
31481+
31482+/* bottom up parent */
31483+static int au_wbr_copyup_bup(struct dentry *dentry)
31484+{
31485+ int err;
31486+ aufs_bindex_t bindex, bstart;
31487+ struct dentry *parent, *h_parent;
31488+ struct super_block *sb;
31489+
31490+ err = -EROFS;
31491+ sb = dentry->d_sb;
31492+ parent = dget_parent(dentry);
31493+ bstart = au_dbstart(parent);
31494+ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) {
31495+ h_parent = au_h_dptr(parent, bindex);
31496+ if (!h_parent || !h_parent->d_inode)
31497+ continue;
31498+
31499+ if (!au_br_rdonly(au_sbr(sb, bindex))) {
31500+ err = bindex;
31501+ break;
31502+ }
31503+ }
31504+ dput(parent);
31505+
31506+ /* bottom up here */
31507+ if (unlikely(err < 0))
31508+ err = au_wbr_bu(sb, bstart - 1);
31509+
31510+ AuDbg("b%d\n", err);
31511+ return err;
31512+}
31513+
31514+/* bottom up */
076b876e 31515+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart)
1facf9fc 31516+{
31517+ int err;
31518+
4a4d8108
AM
31519+ err = au_wbr_bu(dentry->d_sb, bstart);
31520+ AuDbg("b%d\n", err);
31521+ if (err > bstart)
31522+ err = au_wbr_nonopq(dentry, err);
1facf9fc 31523+
31524+ AuDbg("b%d\n", err);
31525+ return err;
31526+}
31527+
076b876e
AM
31528+static int au_wbr_copyup_bu(struct dentry *dentry)
31529+{
31530+ int err;
31531+ aufs_bindex_t bstart;
31532+
31533+ bstart = au_dbstart(dentry);
31534+ err = au_wbr_do_copyup_bu(dentry, bstart);
31535+ return err;
31536+}
31537+
1facf9fc 31538+/* ---------------------------------------------------------------------- */
31539+
31540+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = {
31541+ [AuWbrCopyup_TDP] = {
31542+ .copyup = au_wbr_copyup_tdp
31543+ },
31544+ [AuWbrCopyup_BUP] = {
31545+ .copyup = au_wbr_copyup_bup
31546+ },
31547+ [AuWbrCopyup_BU] = {
31548+ .copyup = au_wbr_copyup_bu
31549+ }
31550+};
31551+
31552+struct au_wbr_create_operations au_wbr_create_ops[] = {
31553+ [AuWbrCreate_TDP] = {
31554+ .create = au_wbr_create_tdp
31555+ },
31556+ [AuWbrCreate_RR] = {
31557+ .create = au_wbr_create_rr,
31558+ .init = au_wbr_create_init_rr
31559+ },
31560+ [AuWbrCreate_MFS] = {
31561+ .create = au_wbr_create_mfs,
31562+ .init = au_wbr_create_init_mfs,
31563+ .fin = au_wbr_create_fin_mfs
31564+ },
31565+ [AuWbrCreate_MFSV] = {
31566+ .create = au_wbr_create_mfs,
31567+ .init = au_wbr_create_init_mfs,
31568+ .fin = au_wbr_create_fin_mfs
31569+ },
31570+ [AuWbrCreate_MFSRR] = {
31571+ .create = au_wbr_create_mfsrr,
31572+ .init = au_wbr_create_init_mfsrr,
31573+ .fin = au_wbr_create_fin_mfs
31574+ },
31575+ [AuWbrCreate_MFSRRV] = {
31576+ .create = au_wbr_create_mfsrr,
31577+ .init = au_wbr_create_init_mfsrr,
31578+ .fin = au_wbr_create_fin_mfs
31579+ },
31580+ [AuWbrCreate_PMFS] = {
31581+ .create = au_wbr_create_pmfs,
31582+ .init = au_wbr_create_init_mfs,
31583+ .fin = au_wbr_create_fin_mfs
31584+ },
31585+ [AuWbrCreate_PMFSV] = {
31586+ .create = au_wbr_create_pmfs,
31587+ .init = au_wbr_create_init_mfs,
31588+ .fin = au_wbr_create_fin_mfs
392086de
AM
31589+ },
31590+ [AuWbrCreate_PMFSRR] = {
31591+ .create = au_wbr_create_pmfsrr,
31592+ .init = au_wbr_create_init_mfsrr,
31593+ .fin = au_wbr_create_fin_mfs
31594+ },
31595+ [AuWbrCreate_PMFSRRV] = {
31596+ .create = au_wbr_create_pmfsrr,
31597+ .init = au_wbr_create_init_mfsrr,
31598+ .fin = au_wbr_create_fin_mfs
1facf9fc 31599+ }
31600+};
7f207e10
AM
31601diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
31602--- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 31603+++ linux/fs/aufs/whout.c 2015-01-25 13:00:38.634380408 +0100
076b876e 31604@@ -0,0 +1,1056 @@
1facf9fc 31605+/*
523b37e3 31606+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 31607+ *
31608+ * This program, aufs is free software; you can redistribute it and/or modify
31609+ * it under the terms of the GNU General Public License as published by
31610+ * the Free Software Foundation; either version 2 of the License, or
31611+ * (at your option) any later version.
dece6358
AM
31612+ *
31613+ * This program is distributed in the hope that it will be useful,
31614+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31615+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31616+ * GNU General Public License for more details.
31617+ *
31618+ * You should have received a copy of the GNU General Public License
523b37e3 31619+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 31620+ */
31621+
31622+/*
31623+ * whiteout for logical deletion and opaque directory
31624+ */
31625+
1facf9fc 31626+#include "aufs.h"
31627+
31628+#define WH_MASK S_IRUGO
31629+
31630+/*
31631+ * If a directory contains this file, then it is opaque. We start with the
31632+ * .wh. flag so that it is blocked by lookup.
31633+ */
0c3ec466
AM
31634+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ,
31635+ sizeof(AUFS_WH_DIROPQ) - 1);
1facf9fc 31636+
31637+/*
31638+ * generate whiteout name, which is NOT terminated by NULL.
31639+ * @name: original d_name.name
31640+ * @len: original d_name.len
31641+ * @wh: whiteout qstr
31642+ * returns zero when succeeds, otherwise error.
31643+ * succeeded value as wh->name should be freed by kfree().
31644+ */
31645+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name)
31646+{
31647+ char *p;
31648+
31649+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN))
31650+ return -ENAMETOOLONG;
31651+
31652+ wh->len = name->len + AUFS_WH_PFX_LEN;
31653+ p = kmalloc(wh->len, GFP_NOFS);
31654+ wh->name = p;
31655+ if (p) {
31656+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
31657+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len);
31658+ /* smp_mb(); */
31659+ return 0;
31660+ }
31661+ return -ENOMEM;
31662+}
31663+
31664+/* ---------------------------------------------------------------------- */
31665+
31666+/*
31667+ * test if the @wh_name exists under @h_parent.
31668+ * @try_sio specifies the necessary of super-io.
31669+ */
076b876e 31670+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio)
1facf9fc 31671+{
31672+ int err;
31673+ struct dentry *wh_dentry;
1facf9fc 31674+
1facf9fc 31675+ if (!try_sio)
b4510431 31676+ wh_dentry = vfsub_lkup_one(wh_name, h_parent);
1facf9fc 31677+ else
076b876e 31678+ wh_dentry = au_sio_lkup_one(wh_name, h_parent);
1facf9fc 31679+ err = PTR_ERR(wh_dentry);
31680+ if (IS_ERR(wh_dentry))
31681+ goto out;
31682+
31683+ err = 0;
31684+ if (!wh_dentry->d_inode)
31685+ goto out_wh; /* success */
31686+
31687+ err = 1;
31688+ if (S_ISREG(wh_dentry->d_inode->i_mode))
31689+ goto out_wh; /* success */
31690+
31691+ err = -EIO;
523b37e3
AM
31692+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n",
31693+ wh_dentry, wh_dentry->d_inode->i_mode);
1facf9fc 31694+
4f0767ce 31695+out_wh:
1facf9fc 31696+ dput(wh_dentry);
4f0767ce 31697+out:
1facf9fc 31698+ return err;
31699+}
31700+
31701+/*
31702+ * test if the @h_dentry sets opaque or not.
31703+ */
076b876e 31704+int au_diropq_test(struct dentry *h_dentry)
1facf9fc 31705+{
31706+ int err;
31707+ struct inode *h_dir;
31708+
31709+ h_dir = h_dentry->d_inode;
076b876e 31710+ err = au_wh_test(h_dentry, &diropq_name,
1facf9fc 31711+ au_test_h_perm_sio(h_dir, MAY_EXEC));
31712+ return err;
31713+}
31714+
31715+/*
31716+ * returns a negative dentry whose name is unique and temporary.
31717+ */
31718+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
31719+ struct qstr *prefix)
31720+{
1facf9fc 31721+ struct dentry *dentry;
31722+ int i;
027c5e7a 31723+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
4a4d8108 31724+ *name, *p;
027c5e7a 31725+ /* strict atomic_t is unnecessary here */
1facf9fc 31726+ static unsigned short cnt;
31727+ struct qstr qs;
31728+
4a4d8108
AM
31729+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);
31730+
1facf9fc 31731+ name = defname;
027c5e7a
AM
31732+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
31733+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
1facf9fc 31734+ dentry = ERR_PTR(-ENAMETOOLONG);
4a4d8108 31735+ if (unlikely(qs.len > NAME_MAX))
1facf9fc 31736+ goto out;
31737+ dentry = ERR_PTR(-ENOMEM);
31738+ name = kmalloc(qs.len + 1, GFP_NOFS);
31739+ if (unlikely(!name))
31740+ goto out;
31741+ }
31742+
31743+ /* doubly whiteout-ed */
31744+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
31745+ p = name + AUFS_WH_PFX_LEN * 2;
31746+ memcpy(p, prefix->name, prefix->len);
31747+ p += prefix->len;
31748+ *p++ = '.';
4a4d8108 31749+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);
1facf9fc 31750+
31751+ qs.name = name;
31752+ for (i = 0; i < 3; i++) {
b752ccd1 31753+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
076b876e 31754+ dentry = au_sio_lkup_one(&qs, h_parent);
1facf9fc 31755+ if (IS_ERR(dentry) || !dentry->d_inode)
31756+ goto out_name;
31757+ dput(dentry);
31758+ }
0c3ec466 31759+ /* pr_warn("could not get random name\n"); */
1facf9fc 31760+ dentry = ERR_PTR(-EEXIST);
31761+ AuDbg("%.*s\n", AuLNPair(&qs));
31762+ BUG();
31763+
4f0767ce 31764+out_name:
1facf9fc 31765+ if (name != defname)
31766+ kfree(name);
4f0767ce 31767+out:
4a4d8108 31768+ AuTraceErrPtr(dentry);
1facf9fc 31769+ return dentry;
1facf9fc 31770+}
31771+
31772+/*
31773+ * rename the @h_dentry on @br to the whiteouted temporary name.
31774+ */
31775+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br)
31776+{
31777+ int err;
31778+ struct path h_path = {
86dc4139 31779+ .mnt = au_br_mnt(br)
1facf9fc 31780+ };
523b37e3 31781+ struct inode *h_dir, *delegated;
1facf9fc 31782+ struct dentry *h_parent;
31783+
31784+ h_parent = h_dentry->d_parent; /* dir inode is locked */
31785+ h_dir = h_parent->d_inode;
31786+ IMustLock(h_dir);
31787+
31788+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name);
31789+ err = PTR_ERR(h_path.dentry);
31790+ if (IS_ERR(h_path.dentry))
31791+ goto out;
31792+
31793+ /* under the same dir, no need to lock_rename() */
523b37e3
AM
31794+ delegated = NULL;
31795+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated);
1facf9fc 31796+ AuTraceErr(err);
523b37e3
AM
31797+ if (unlikely(err == -EWOULDBLOCK)) {
31798+ pr_warn("cannot retry for NFSv4 delegation"
31799+ " for an internal rename\n");
31800+ iput(delegated);
31801+ }
1facf9fc 31802+ dput(h_path.dentry);
31803+
4f0767ce 31804+out:
4a4d8108 31805+ AuTraceErr(err);
1facf9fc 31806+ return err;
31807+}
31808+
31809+/* ---------------------------------------------------------------------- */
31810+/*
31811+ * functions for removing a whiteout
31812+ */
31813+
31814+static int do_unlink_wh(struct inode *h_dir, struct path *h_path)
31815+{
523b37e3
AM
31816+ int err, force;
31817+ struct inode *delegated;
1facf9fc 31818+
31819+ /*
31820+ * forces superio when the dir has a sticky bit.
31821+ * this may be a violation of unix fs semantics.
31822+ */
31823+ force = (h_dir->i_mode & S_ISVTX)
0c3ec466 31824+ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid);
523b37e3
AM
31825+ delegated = NULL;
31826+ err = vfsub_unlink(h_dir, h_path, &delegated, force);
31827+ if (unlikely(err == -EWOULDBLOCK)) {
31828+ pr_warn("cannot retry for NFSv4 delegation"
31829+ " for an internal unlink\n");
31830+ iput(delegated);
31831+ }
31832+ return err;
1facf9fc 31833+}
31834+
31835+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
31836+ struct dentry *dentry)
31837+{
31838+ int err;
31839+
31840+ err = do_unlink_wh(h_dir, h_path);
31841+ if (!err && dentry)
31842+ au_set_dbwh(dentry, -1);
31843+
31844+ return err;
31845+}
31846+
31847+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh,
31848+ struct au_branch *br)
31849+{
31850+ int err;
31851+ struct path h_path = {
86dc4139 31852+ .mnt = au_br_mnt(br)
1facf9fc 31853+ };
31854+
31855+ err = 0;
b4510431 31856+ h_path.dentry = vfsub_lkup_one(wh, h_parent);
1facf9fc 31857+ if (IS_ERR(h_path.dentry))
31858+ err = PTR_ERR(h_path.dentry);
31859+ else {
31860+ if (h_path.dentry->d_inode
31861+ && S_ISREG(h_path.dentry->d_inode->i_mode))
31862+ err = do_unlink_wh(h_parent->d_inode, &h_path);
31863+ dput(h_path.dentry);
31864+ }
31865+
31866+ return err;
31867+}
31868+
31869+/* ---------------------------------------------------------------------- */
31870+/*
31871+ * initialize/clean whiteout for a branch
31872+ */
31873+
31874+static void au_wh_clean(struct inode *h_dir, struct path *whpath,
31875+ const int isdir)
31876+{
31877+ int err;
523b37e3 31878+ struct inode *delegated;
1facf9fc 31879+
31880+ if (!whpath->dentry->d_inode)
31881+ return;
31882+
86dc4139
AM
31883+ if (isdir)
31884+ err = vfsub_rmdir(h_dir, whpath);
523b37e3
AM
31885+ else {
31886+ delegated = NULL;
31887+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0);
31888+ if (unlikely(err == -EWOULDBLOCK)) {
31889+ pr_warn("cannot retry for NFSv4 delegation"
31890+ " for an internal unlink\n");
31891+ iput(delegated);
31892+ }
31893+ }
1facf9fc 31894+ if (unlikely(err))
523b37e3
AM
31895+ pr_warn("failed removing %pd (%d), ignored.\n",
31896+ whpath->dentry, err);
1facf9fc 31897+}
31898+
31899+static int test_linkable(struct dentry *h_root)
31900+{
31901+ struct inode *h_dir = h_root->d_inode;
31902+
31903+ if (h_dir->i_op->link)
31904+ return 0;
31905+
523b37e3
AM
31906+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n",
31907+ h_root, au_sbtype(h_root->d_sb));
1facf9fc 31908+ return -ENOSYS;
31909+}
31910+
31911+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */
31912+static int au_whdir(struct inode *h_dir, struct path *path)
31913+{
31914+ int err;
31915+
31916+ err = -EEXIST;
31917+ if (!path->dentry->d_inode) {
31918+ int mode = S_IRWXU;
31919+
31920+ if (au_test_nfs(path->dentry->d_sb))
31921+ mode |= S_IXUGO;
86dc4139 31922+ err = vfsub_mkdir(h_dir, path, mode);
1facf9fc 31923+ } else if (S_ISDIR(path->dentry->d_inode->i_mode))
31924+ err = 0;
31925+ else
523b37e3 31926+ pr_err("unknown %pd exists\n", path->dentry);
1facf9fc 31927+
31928+ return err;
31929+}
31930+
31931+struct au_wh_base {
31932+ const struct qstr *name;
31933+ struct dentry *dentry;
31934+};
31935+
31936+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[],
31937+ struct path *h_path)
31938+{
31939+ h_path->dentry = base[AuBrWh_BASE].dentry;
31940+ au_wh_clean(h_dir, h_path, /*isdir*/0);
31941+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31942+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31943+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31944+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31945+}
31946+
31947+/*
31948+ * returns tri-state,
c1595e42 31949+ * minus: error, caller should print the message
1facf9fc 31950+ * zero: succuess
c1595e42 31951+ * plus: error, caller should NOT print the message
1facf9fc 31952+ */
31953+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr,
31954+ int do_plink, struct au_wh_base base[],
31955+ struct path *h_path)
31956+{
31957+ int err;
31958+ struct inode *h_dir;
31959+
31960+ h_dir = h_root->d_inode;
31961+ h_path->dentry = base[AuBrWh_BASE].dentry;
31962+ au_wh_clean(h_dir, h_path, /*isdir*/0);
31963+ h_path->dentry = base[AuBrWh_PLINK].dentry;
31964+ if (do_plink) {
31965+ err = test_linkable(h_root);
31966+ if (unlikely(err)) {
31967+ err = 1;
31968+ goto out;
31969+ }
31970+
31971+ err = au_whdir(h_dir, h_path);
31972+ if (unlikely(err))
31973+ goto out;
31974+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
31975+ } else
31976+ au_wh_clean(h_dir, h_path, /*isdir*/1);
31977+ h_path->dentry = base[AuBrWh_ORPH].dentry;
31978+ err = au_whdir(h_dir, h_path);
31979+ if (unlikely(err))
31980+ goto out;
31981+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
31982+
4f0767ce 31983+out:
1facf9fc 31984+ return err;
31985+}
31986+
31987+/*
31988+ * for the moment, aufs supports the branch filesystem which does not support
31989+ * link(2). testing on FAT which does not support i_op->setattr() fully either,
31990+ * copyup failed. finally, such filesystem will not be used as the writable
31991+ * branch.
31992+ *
31993+ * returns tri-state, see above.
31994+ */
31995+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr,
31996+ int do_plink, struct au_wh_base base[],
31997+ struct path *h_path)
31998+{
31999+ int err;
32000+ struct inode *h_dir;
32001+
1308ab2a 32002+ WbrWhMustWriteLock(wbr);
32003+
1facf9fc 32004+ err = test_linkable(h_root);
32005+ if (unlikely(err)) {
32006+ err = 1;
32007+ goto out;
32008+ }
32009+
32010+ /*
32011+ * todo: should this create be done in /sbin/mount.aufs helper?
32012+ */
32013+ err = -EEXIST;
32014+ h_dir = h_root->d_inode;
32015+ if (!base[AuBrWh_BASE].dentry->d_inode) {
86dc4139
AM
32016+ h_path->dentry = base[AuBrWh_BASE].dentry;
32017+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true);
1facf9fc 32018+ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode))
32019+ err = 0;
32020+ else
523b37e3 32021+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry);
1facf9fc 32022+ if (unlikely(err))
32023+ goto out;
32024+
32025+ h_path->dentry = base[AuBrWh_PLINK].dentry;
32026+ if (do_plink) {
32027+ err = au_whdir(h_dir, h_path);
32028+ if (unlikely(err))
32029+ goto out;
32030+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry);
32031+ } else
32032+ au_wh_clean(h_dir, h_path, /*isdir*/1);
32033+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry);
32034+
32035+ h_path->dentry = base[AuBrWh_ORPH].dentry;
32036+ err = au_whdir(h_dir, h_path);
32037+ if (unlikely(err))
32038+ goto out;
32039+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry);
32040+
4f0767ce 32041+out:
1facf9fc 32042+ return err;
32043+}
32044+
32045+/*
32046+ * initialize the whiteout base file/dir for @br.
32047+ */
86dc4139 32048+int au_wh_init(struct au_branch *br, struct super_block *sb)
1facf9fc 32049+{
32050+ int err, i;
32051+ const unsigned char do_plink
32052+ = !!au_opt_test(au_mntflags(sb), PLINK);
1facf9fc 32053+ struct inode *h_dir;
86dc4139
AM
32054+ struct path path = br->br_path;
32055+ struct dentry *h_root = path.dentry;
1facf9fc 32056+ struct au_wbr *wbr = br->br_wbr;
32057+ static const struct qstr base_name[] = {
0c3ec466
AM
32058+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME,
32059+ sizeof(AUFS_BASE_NAME) - 1),
32060+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME,
32061+ sizeof(AUFS_PLINKDIR_NAME) - 1),
32062+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME,
32063+ sizeof(AUFS_ORPHDIR_NAME) - 1)
1facf9fc 32064+ };
32065+ struct au_wh_base base[] = {
32066+ [AuBrWh_BASE] = {
32067+ .name = base_name + AuBrWh_BASE,
32068+ .dentry = NULL
32069+ },
32070+ [AuBrWh_PLINK] = {
32071+ .name = base_name + AuBrWh_PLINK,
32072+ .dentry = NULL
32073+ },
32074+ [AuBrWh_ORPH] = {
32075+ .name = base_name + AuBrWh_ORPH,
32076+ .dentry = NULL
32077+ }
32078+ };
32079+
1308ab2a 32080+ if (wbr)
32081+ WbrWhMustWriteLock(wbr);
1facf9fc 32082+
1facf9fc 32083+ for (i = 0; i < AuBrWh_Last; i++) {
32084+ /* doubly whiteouted */
32085+ struct dentry *d;
32086+
32087+ d = au_wh_lkup(h_root, (void *)base[i].name, br);
32088+ err = PTR_ERR(d);
32089+ if (IS_ERR(d))
32090+ goto out;
32091+
32092+ base[i].dentry = d;
32093+ AuDebugOn(wbr
32094+ && wbr->wbr_wh[i]
32095+ && wbr->wbr_wh[i] != base[i].dentry);
32096+ }
32097+
32098+ if (wbr)
32099+ for (i = 0; i < AuBrWh_Last; i++) {
32100+ dput(wbr->wbr_wh[i]);
32101+ wbr->wbr_wh[i] = NULL;
32102+ }
32103+
32104+ err = 0;
1e00d052 32105+ if (!au_br_writable(br->br_perm)) {
4a4d8108 32106+ h_dir = h_root->d_inode;
1facf9fc 32107+ au_wh_init_ro(h_dir, base, &path);
1e00d052 32108+ } else if (!au_br_wh_linkable(br->br_perm)) {
1facf9fc 32109+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path);
32110+ if (err > 0)
32111+ goto out;
32112+ else if (err)
32113+ goto out_err;
1e00d052 32114+ } else {
1facf9fc 32115+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path);
32116+ if (err > 0)
32117+ goto out;
32118+ else if (err)
32119+ goto out_err;
1facf9fc 32120+ }
32121+ goto out; /* success */
32122+
4f0767ce 32123+out_err:
523b37e3
AM
32124+ pr_err("an error(%d) on the writable branch %pd(%s)\n",
32125+ err, h_root, au_sbtype(h_root->d_sb));
4f0767ce 32126+out:
1facf9fc 32127+ for (i = 0; i < AuBrWh_Last; i++)
32128+ dput(base[i].dentry);
32129+ return err;
32130+}
32131+
32132+/* ---------------------------------------------------------------------- */
32133+/*
32134+ * whiteouts are all hard-linked usually.
32135+ * when its link count reaches a ceiling, we create a new whiteout base
32136+ * asynchronously.
32137+ */
32138+
32139+struct reinit_br_wh {
32140+ struct super_block *sb;
32141+ struct au_branch *br;
32142+};
32143+
32144+static void reinit_br_wh(void *arg)
32145+{
32146+ int err;
32147+ aufs_bindex_t bindex;
32148+ struct path h_path;
32149+ struct reinit_br_wh *a = arg;
32150+ struct au_wbr *wbr;
523b37e3 32151+ struct inode *dir, *delegated;
1facf9fc 32152+ struct dentry *h_root;
32153+ struct au_hinode *hdir;
32154+
32155+ err = 0;
32156+ wbr = a->br->br_wbr;
32157+ /* big aufs lock */
32158+ si_noflush_write_lock(a->sb);
32159+ if (!au_br_writable(a->br->br_perm))
32160+ goto out;
32161+ bindex = au_br_index(a->sb, a->br->br_id);
32162+ if (unlikely(bindex < 0))
32163+ goto out;
32164+
1308ab2a 32165+ di_read_lock_parent(a->sb->s_root, AuLock_IR);
1facf9fc 32166+ dir = a->sb->s_root->d_inode;
1facf9fc 32167+ hdir = au_hi(dir, bindex);
32168+ h_root = au_h_dptr(a->sb->s_root, bindex);
86dc4139 32169+ AuDebugOn(h_root != au_br_dentry(a->br));
1facf9fc 32170+
4a4d8108 32171+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
1facf9fc 32172+ wbr_wh_write_lock(wbr);
32173+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
32174+ h_root, a->br);
32175+ if (!err) {
86dc4139
AM
32176+ h_path.dentry = wbr->wbr_whbase;
32177+ h_path.mnt = au_br_mnt(a->br);
523b37e3
AM
32178+ delegated = NULL;
32179+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated,
32180+ /*force*/0);
32181+ if (unlikely(err == -EWOULDBLOCK)) {
32182+ pr_warn("cannot retry for NFSv4 delegation"
32183+ " for an internal unlink\n");
32184+ iput(delegated);
32185+ }
1facf9fc 32186+ } else {
523b37e3 32187+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase);
1facf9fc 32188+ err = 0;
32189+ }
32190+ dput(wbr->wbr_whbase);
32191+ wbr->wbr_whbase = NULL;
32192+ if (!err)
86dc4139 32193+ err = au_wh_init(a->br, a->sb);
1facf9fc 32194+ wbr_wh_write_unlock(wbr);
4a4d8108 32195+ au_hn_imtx_unlock(hdir);
1308ab2a 32196+ di_read_unlock(a->sb->s_root, AuLock_IR);
076b876e
AM
32197+ if (!err)
32198+ au_fhsm_wrote(a->sb, bindex, /*force*/0);
1facf9fc 32199+
4f0767ce 32200+out:
1facf9fc 32201+ if (wbr)
32202+ atomic_dec(&wbr->wbr_wh_running);
32203+ atomic_dec(&a->br->br_count);
1facf9fc 32204+ si_write_unlock(a->sb);
027c5e7a 32205+ au_nwt_done(&au_sbi(a->sb)->si_nowait);
1facf9fc 32206+ kfree(arg);
32207+ if (unlikely(err))
32208+ AuIOErr("err %d\n", err);
32209+}
32210+
32211+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br)
32212+{
32213+ int do_dec, wkq_err;
32214+ struct reinit_br_wh *arg;
32215+
32216+ do_dec = 1;
32217+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1)
32218+ goto out;
32219+
32220+ /* ignore ENOMEM */
32221+ arg = kmalloc(sizeof(*arg), GFP_NOFS);
32222+ if (arg) {
32223+ /*
32224+ * dec(wh_running), kfree(arg) and dec(br_count)
32225+ * in reinit function
32226+ */
32227+ arg->sb = sb;
32228+ arg->br = br;
32229+ atomic_inc(&br->br_count);
53392da6 32230+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0);
1facf9fc 32231+ if (unlikely(wkq_err)) {
32232+ atomic_dec(&br->br_wbr->wbr_wh_running);
32233+ atomic_dec(&br->br_count);
32234+ kfree(arg);
32235+ }
32236+ do_dec = 0;
32237+ }
32238+
4f0767ce 32239+out:
1facf9fc 32240+ if (do_dec)
32241+ atomic_dec(&br->br_wbr->wbr_wh_running);
32242+}
32243+
32244+/* ---------------------------------------------------------------------- */
32245+
32246+/*
32247+ * create the whiteout @wh.
32248+ */
32249+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex,
32250+ struct dentry *wh)
32251+{
32252+ int err;
32253+ struct path h_path = {
32254+ .dentry = wh
32255+ };
32256+ struct au_branch *br;
32257+ struct au_wbr *wbr;
32258+ struct dentry *h_parent;
523b37e3 32259+ struct inode *h_dir, *delegated;
1facf9fc 32260+
32261+ h_parent = wh->d_parent; /* dir inode is locked */
32262+ h_dir = h_parent->d_inode;
32263+ IMustLock(h_dir);
32264+
32265+ br = au_sbr(sb, bindex);
86dc4139 32266+ h_path.mnt = au_br_mnt(br);
1facf9fc 32267+ wbr = br->br_wbr;
32268+ wbr_wh_read_lock(wbr);
32269+ if (wbr->wbr_whbase) {
523b37e3
AM
32270+ delegated = NULL;
32271+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated);
32272+ if (unlikely(err == -EWOULDBLOCK)) {
32273+ pr_warn("cannot retry for NFSv4 delegation"
32274+ " for an internal link\n");
32275+ iput(delegated);
32276+ }
1facf9fc 32277+ if (!err || err != -EMLINK)
32278+ goto out;
32279+
32280+ /* link count full. re-initialize br_whbase. */
32281+ kick_reinit_br_wh(sb, br);
32282+ }
32283+
32284+ /* return this error in this context */
b4510431 32285+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true);
076b876e
AM
32286+ if (!err)
32287+ au_fhsm_wrote(sb, bindex, /*force*/0);
1facf9fc 32288+
4f0767ce 32289+out:
1facf9fc 32290+ wbr_wh_read_unlock(wbr);
32291+ return err;
32292+}
32293+
32294+/* ---------------------------------------------------------------------- */
32295+
32296+/*
32297+ * create or remove the diropq.
32298+ */
32299+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex,
32300+ unsigned int flags)
32301+{
32302+ struct dentry *opq_dentry, *h_dentry;
32303+ struct super_block *sb;
32304+ struct au_branch *br;
32305+ int err;
32306+
32307+ sb = dentry->d_sb;
32308+ br = au_sbr(sb, bindex);
32309+ h_dentry = au_h_dptr(dentry, bindex);
b4510431 32310+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry);
1facf9fc 32311+ if (IS_ERR(opq_dentry))
32312+ goto out;
32313+
32314+ if (au_ftest_diropq(flags, CREATE)) {
32315+ err = link_or_create_wh(sb, bindex, opq_dentry);
32316+ if (!err) {
32317+ au_set_dbdiropq(dentry, bindex);
32318+ goto out; /* success */
32319+ }
32320+ } else {
32321+ struct path tmp = {
32322+ .dentry = opq_dentry,
86dc4139 32323+ .mnt = au_br_mnt(br)
1facf9fc 32324+ };
32325+ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp);
32326+ if (!err)
32327+ au_set_dbdiropq(dentry, -1);
32328+ }
32329+ dput(opq_dentry);
32330+ opq_dentry = ERR_PTR(err);
32331+
4f0767ce 32332+out:
1facf9fc 32333+ return opq_dentry;
32334+}
32335+
32336+struct do_diropq_args {
32337+ struct dentry **errp;
32338+ struct dentry *dentry;
32339+ aufs_bindex_t bindex;
32340+ unsigned int flags;
32341+};
32342+
32343+static void call_do_diropq(void *args)
32344+{
32345+ struct do_diropq_args *a = args;
32346+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags);
32347+}
32348+
32349+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
32350+ unsigned int flags)
32351+{
32352+ struct dentry *diropq, *h_dentry;
32353+
32354+ h_dentry = au_h_dptr(dentry, bindex);
32355+ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE))
32356+ diropq = do_diropq(dentry, bindex, flags);
32357+ else {
32358+ int wkq_err;
32359+ struct do_diropq_args args = {
32360+ .errp = &diropq,
32361+ .dentry = dentry,
32362+ .bindex = bindex,
32363+ .flags = flags
32364+ };
32365+
32366+ wkq_err = au_wkq_wait(call_do_diropq, &args);
32367+ if (unlikely(wkq_err))
32368+ diropq = ERR_PTR(wkq_err);
32369+ }
32370+
32371+ return diropq;
32372+}
32373+
32374+/* ---------------------------------------------------------------------- */
32375+
32376+/*
32377+ * lookup whiteout dentry.
32378+ * @h_parent: lower parent dentry which must exist and be locked
32379+ * @base_name: name of dentry which will be whiteouted
32380+ * returns dentry for whiteout.
32381+ */
32382+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
32383+ struct au_branch *br)
32384+{
32385+ int err;
32386+ struct qstr wh_name;
32387+ struct dentry *wh_dentry;
32388+
32389+ err = au_wh_name_alloc(&wh_name, base_name);
32390+ wh_dentry = ERR_PTR(err);
32391+ if (!err) {
b4510431 32392+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent);
1facf9fc 32393+ kfree(wh_name.name);
32394+ }
32395+ return wh_dentry;
32396+}
32397+
32398+/*
32399+ * link/create a whiteout for @dentry on @bindex.
32400+ */
32401+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
32402+ struct dentry *h_parent)
32403+{
32404+ struct dentry *wh_dentry;
32405+ struct super_block *sb;
32406+ int err;
32407+
32408+ sb = dentry->d_sb;
32409+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex));
32410+ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) {
32411+ err = link_or_create_wh(sb, bindex, wh_dentry);
076b876e 32412+ if (!err) {
1facf9fc 32413+ au_set_dbwh(dentry, bindex);
076b876e
AM
32414+ au_fhsm_wrote(sb, bindex, /*force*/0);
32415+ } else {
1facf9fc 32416+ dput(wh_dentry);
32417+ wh_dentry = ERR_PTR(err);
32418+ }
32419+ }
32420+
32421+ return wh_dentry;
32422+}
32423+
32424+/* ---------------------------------------------------------------------- */
32425+
32426+/* Delete all whiteouts in this directory on branch bindex. */
32427+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist,
32428+ aufs_bindex_t bindex, struct au_branch *br)
32429+{
32430+ int err;
32431+ unsigned long ul, n;
32432+ struct qstr wh_name;
32433+ char *p;
32434+ struct hlist_head *head;
c06a8ce3 32435+ struct au_vdir_wh *pos;
1facf9fc 32436+ struct au_vdir_destr *str;
32437+
32438+ err = -ENOMEM;
537831f9 32439+ p = (void *)__get_free_page(GFP_NOFS);
1facf9fc 32440+ wh_name.name = p;
32441+ if (unlikely(!wh_name.name))
32442+ goto out;
32443+
32444+ err = 0;
32445+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN);
32446+ p += AUFS_WH_PFX_LEN;
32447+ n = whlist->nh_num;
32448+ head = whlist->nh_head;
32449+ for (ul = 0; !err && ul < n; ul++, head++) {
c06a8ce3
AM
32450+ hlist_for_each_entry(pos, head, wh_hash) {
32451+ if (pos->wh_bindex != bindex)
1facf9fc 32452+ continue;
32453+
c06a8ce3 32454+ str = &pos->wh_str;
1facf9fc 32455+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) {
32456+ memcpy(p, str->name, str->len);
32457+ wh_name.len = AUFS_WH_PFX_LEN + str->len;
32458+ err = unlink_wh_name(h_dentry, &wh_name, br);
32459+ if (!err)
32460+ continue;
32461+ break;
32462+ }
32463+ AuIOErr("whiteout name too long %.*s\n",
32464+ str->len, str->name);
32465+ err = -EIO;
32466+ break;
32467+ }
32468+ }
537831f9 32469+ free_page((unsigned long)wh_name.name);
1facf9fc 32470+
4f0767ce 32471+out:
1facf9fc 32472+ return err;
32473+}
32474+
32475+struct del_wh_children_args {
32476+ int *errp;
32477+ struct dentry *h_dentry;
1308ab2a 32478+ struct au_nhash *whlist;
1facf9fc 32479+ aufs_bindex_t bindex;
32480+ struct au_branch *br;
32481+};
32482+
32483+static void call_del_wh_children(void *args)
32484+{
32485+ struct del_wh_children_args *a = args;
1308ab2a 32486+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br);
1facf9fc 32487+}
32488+
32489+/* ---------------------------------------------------------------------- */
32490+
32491+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp)
32492+{
32493+ struct au_whtmp_rmdir *whtmp;
dece6358 32494+ int err;
1308ab2a 32495+ unsigned int rdhash;
dece6358
AM
32496+
32497+ SiMustAnyLock(sb);
1facf9fc 32498+
32499+ whtmp = kmalloc(sizeof(*whtmp), gfp);
dece6358
AM
32500+ if (unlikely(!whtmp)) {
32501+ whtmp = ERR_PTR(-ENOMEM);
1facf9fc 32502+ goto out;
dece6358 32503+ }
1facf9fc 32504+
32505+ whtmp->dir = NULL;
027c5e7a 32506+ whtmp->br = NULL;
1facf9fc 32507+ whtmp->wh_dentry = NULL;
1308ab2a 32508+ /* no estimation for dir size */
32509+ rdhash = au_sbi(sb)->si_rdhash;
32510+ if (!rdhash)
32511+ rdhash = AUFS_RDHASH_DEF;
32512+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp);
32513+ if (unlikely(err)) {
32514+ kfree(whtmp);
32515+ whtmp = ERR_PTR(err);
32516+ }
dece6358 32517+
4f0767ce 32518+out:
dece6358 32519+ return whtmp;
1facf9fc 32520+}
32521+
32522+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp)
32523+{
027c5e7a
AM
32524+ if (whtmp->br)
32525+ atomic_dec(&whtmp->br->br_count);
1facf9fc 32526+ dput(whtmp->wh_dentry);
32527+ iput(whtmp->dir);
dece6358 32528+ au_nhash_wh_free(&whtmp->whlist);
1facf9fc 32529+ kfree(whtmp);
32530+}
32531+
32532+/*
32533+ * rmdir the whiteouted temporary named dir @h_dentry.
32534+ * @whlist: whiteouted children.
32535+ */
32536+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
32537+ struct dentry *wh_dentry, struct au_nhash *whlist)
32538+{
32539+ int err;
32540+ struct path h_tmp;
32541+ struct inode *wh_inode, *h_dir;
32542+ struct au_branch *br;
32543+
32544+ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */
32545+ IMustLock(h_dir);
32546+
32547+ br = au_sbr(dir->i_sb, bindex);
32548+ wh_inode = wh_dentry->d_inode;
32549+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD);
32550+
32551+ /*
32552+ * someone else might change some whiteouts while we were sleeping.
32553+ * it means this whlist may have an obsoleted entry.
32554+ */
32555+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE))
32556+ err = del_wh_children(wh_dentry, whlist, bindex, br);
32557+ else {
32558+ int wkq_err;
32559+ struct del_wh_children_args args = {
32560+ .errp = &err,
32561+ .h_dentry = wh_dentry,
1308ab2a 32562+ .whlist = whlist,
1facf9fc 32563+ .bindex = bindex,
32564+ .br = br
32565+ };
32566+
32567+ wkq_err = au_wkq_wait(call_del_wh_children, &args);
32568+ if (unlikely(wkq_err))
32569+ err = wkq_err;
32570+ }
32571+ mutex_unlock(&wh_inode->i_mutex);
32572+
32573+ if (!err) {
32574+ h_tmp.dentry = wh_dentry;
86dc4139 32575+ h_tmp.mnt = au_br_mnt(br);
1facf9fc 32576+ err = vfsub_rmdir(h_dir, &h_tmp);
1facf9fc 32577+ }
32578+
32579+ if (!err) {
32580+ if (au_ibstart(dir) == bindex) {
7f207e10 32581+ /* todo: dir->i_mutex is necessary */
1facf9fc 32582+ au_cpup_attr_timesizes(dir);
7f207e10 32583+ vfsub_drop_nlink(dir);
1facf9fc 32584+ }
32585+ return 0; /* success */
32586+ }
32587+
523b37e3 32588+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err);
1facf9fc 32589+ return err;
32590+}
32591+
32592+static void call_rmdir_whtmp(void *args)
32593+{
32594+ int err;
e49829fe 32595+ aufs_bindex_t bindex;
1facf9fc 32596+ struct au_whtmp_rmdir *a = args;
32597+ struct super_block *sb;
32598+ struct dentry *h_parent;
32599+ struct inode *h_dir;
1facf9fc 32600+ struct au_hinode *hdir;
32601+
32602+ /* rmdir by nfsd may cause deadlock with this i_mutex */
32603+ /* mutex_lock(&a->dir->i_mutex); */
e49829fe 32604+ err = -EROFS;
1facf9fc 32605+ sb = a->dir->i_sb;
e49829fe
JR
32606+ si_read_lock(sb, !AuLock_FLUSH);
32607+ if (!au_br_writable(a->br->br_perm))
32608+ goto out;
32609+ bindex = au_br_index(sb, a->br->br_id);
32610+ if (unlikely(bindex < 0))
1facf9fc 32611+ goto out;
32612+
32613+ err = -EIO;
1facf9fc 32614+ ii_write_lock_parent(a->dir);
32615+ h_parent = dget_parent(a->wh_dentry);
32616+ h_dir = h_parent->d_inode;
e49829fe 32617+ hdir = au_hi(a->dir, bindex);
86dc4139
AM
32618+ err = vfsub_mnt_want_write(au_br_mnt(a->br));
32619+ if (unlikely(err))
32620+ goto out_mnt;
4a4d8108 32621+ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
e49829fe
JR
32622+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
32623+ a->br);
86dc4139
AM
32624+ if (!err)
32625+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
4a4d8108 32626+ au_hn_imtx_unlock(hdir);
86dc4139
AM
32627+ vfsub_mnt_drop_write(au_br_mnt(a->br));
32628+
32629+out_mnt:
1facf9fc 32630+ dput(h_parent);
32631+ ii_write_unlock(a->dir);
4f0767ce 32632+out:
1facf9fc 32633+ /* mutex_unlock(&a->dir->i_mutex); */
1facf9fc 32634+ au_whtmp_rmdir_free(a);
027c5e7a
AM
32635+ si_read_unlock(sb);
32636+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32637+ if (unlikely(err))
32638+ AuIOErr("err %d\n", err);
32639+}
32640+
32641+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
32642+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args)
32643+{
32644+ int wkq_err;
e49829fe 32645+ struct super_block *sb;
1facf9fc 32646+
32647+ IMustLock(dir);
32648+
32649+ /* all post-process will be done in do_rmdir_whtmp(). */
e49829fe 32650+ sb = dir->i_sb;
1facf9fc 32651+ args->dir = au_igrab(dir);
e49829fe
JR
32652+ args->br = au_sbr(sb, bindex);
32653+ atomic_inc(&args->br->br_count);
1facf9fc 32654+ args->wh_dentry = dget(wh_dentry);
53392da6 32655+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0);
1facf9fc 32656+ if (unlikely(wkq_err)) {
523b37e3 32657+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err);
1facf9fc 32658+ au_whtmp_rmdir_free(args);
32659+ }
32660+}
7f207e10
AM
32661diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h
32662--- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 32663+++ linux/fs/aufs/whout.h 2015-01-25 13:00:38.634380408 +0100
076b876e 32664@@ -0,0 +1,85 @@
1facf9fc 32665+/*
523b37e3 32666+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 32667+ *
32668+ * This program, aufs is free software; you can redistribute it and/or modify
32669+ * it under the terms of the GNU General Public License as published by
32670+ * the Free Software Foundation; either version 2 of the License, or
32671+ * (at your option) any later version.
dece6358
AM
32672+ *
32673+ * This program is distributed in the hope that it will be useful,
32674+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32675+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32676+ * GNU General Public License for more details.
32677+ *
32678+ * You should have received a copy of the GNU General Public License
523b37e3 32679+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32680+ */
32681+
32682+/*
32683+ * whiteout for logical deletion and opaque directory
32684+ */
32685+
32686+#ifndef __AUFS_WHOUT_H__
32687+#define __AUFS_WHOUT_H__
32688+
32689+#ifdef __KERNEL__
32690+
1facf9fc 32691+#include "dir.h"
32692+
32693+/* whout.c */
32694+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name);
32695+struct au_branch;
076b876e
AM
32696+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio);
32697+int au_diropq_test(struct dentry *h_dentry);
1facf9fc 32698+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
32699+ struct qstr *prefix);
32700+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br);
32701+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path,
32702+ struct dentry *dentry);
86dc4139 32703+int au_wh_init(struct au_branch *br, struct super_block *sb);
1facf9fc 32704+
32705+/* diropq flags */
32706+#define AuDiropq_CREATE 1
32707+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name)
7f207e10
AM
32708+#define au_fset_diropq(flags, name) \
32709+ do { (flags) |= AuDiropq_##name; } while (0)
32710+#define au_fclr_diropq(flags, name) \
32711+ do { (flags) &= ~AuDiropq_##name; } while (0)
1facf9fc 32712+
32713+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex,
32714+ unsigned int flags);
32715+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name,
32716+ struct au_branch *br);
32717+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex,
32718+ struct dentry *h_parent);
32719+
32720+/* real rmdir for the whiteout-ed dir */
32721+struct au_whtmp_rmdir {
32722+ struct inode *dir;
e49829fe 32723+ struct au_branch *br;
1facf9fc 32724+ struct dentry *wh_dentry;
dece6358 32725+ struct au_nhash whlist;
1facf9fc 32726+};
32727+
32728+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp);
32729+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp);
32730+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex,
32731+ struct dentry *wh_dentry, struct au_nhash *whlist);
32732+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex,
32733+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args);
32734+
32735+/* ---------------------------------------------------------------------- */
32736+
32737+static inline struct dentry *au_diropq_create(struct dentry *dentry,
32738+ aufs_bindex_t bindex)
32739+{
32740+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE);
32741+}
32742+
32743+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex)
32744+{
32745+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE));
32746+}
32747+
32748+#endif /* __KERNEL__ */
32749+#endif /* __AUFS_WHOUT_H__ */
7f207e10
AM
32750diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
32751--- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100
c1595e42 32752+++ linux/fs/aufs/wkq.c 2015-01-25 13:00:38.634380408 +0100
38d290e6 32753@@ -0,0 +1,213 @@
1facf9fc 32754+/*
523b37e3 32755+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 32756+ *
32757+ * This program, aufs is free software; you can redistribute it and/or modify
32758+ * it under the terms of the GNU General Public License as published by
32759+ * the Free Software Foundation; either version 2 of the License, or
32760+ * (at your option) any later version.
dece6358
AM
32761+ *
32762+ * This program is distributed in the hope that it will be useful,
32763+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32764+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32765+ * GNU General Public License for more details.
32766+ *
32767+ * You should have received a copy of the GNU General Public License
523b37e3 32768+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32769+ */
32770+
32771+/*
32772+ * workqueue for asynchronous/super-io operations
32773+ * todo: try new dredential scheme
32774+ */
32775+
dece6358 32776+#include <linux/module.h>
1facf9fc 32777+#include "aufs.h"
32778+
9dbd164d 32779+/* internal workqueue named AUFS_WKQ_NAME */
b752ccd1 32780+
9dbd164d 32781+static struct workqueue_struct *au_wkq;
1facf9fc 32782+
32783+struct au_wkinfo {
32784+ struct work_struct wk;
7f207e10 32785+ struct kobject *kobj;
1facf9fc 32786+
32787+ unsigned int flags; /* see wkq.h */
32788+
32789+ au_wkq_func_t func;
32790+ void *args;
32791+
1facf9fc 32792+ struct completion *comp;
32793+};
32794+
32795+/* ---------------------------------------------------------------------- */
32796+
1facf9fc 32797+static void wkq_func(struct work_struct *wk)
32798+{
32799+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk);
32800+
2dfbb274 32801+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID));
7f207e10
AM
32802+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY);
32803+
1facf9fc 32804+ wkinfo->func(wkinfo->args);
1facf9fc 32805+ if (au_ftest_wkq(wkinfo->flags, WAIT))
32806+ complete(wkinfo->comp);
32807+ else {
7f207e10 32808+ kobject_put(wkinfo->kobj);
9dbd164d 32809+ module_put(THIS_MODULE); /* todo: ?? */
1facf9fc 32810+ kfree(wkinfo);
32811+ }
32812+}
32813+
32814+/*
32815+ * Since struct completion is large, try allocating it dynamically.
32816+ */
c2b27bf2 32817+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */
1facf9fc 32818+#define AuWkqCompDeclare(name) struct completion *comp = NULL
32819+
32820+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
32821+{
32822+ *comp = kmalloc(sizeof(**comp), GFP_NOFS);
32823+ if (*comp) {
32824+ init_completion(*comp);
32825+ wkinfo->comp = *comp;
32826+ return 0;
32827+ }
32828+ return -ENOMEM;
32829+}
32830+
32831+static void au_wkq_comp_free(struct completion *comp)
32832+{
32833+ kfree(comp);
32834+}
32835+
32836+#else
32837+
32838+/* no braces */
32839+#define AuWkqCompDeclare(name) \
32840+ DECLARE_COMPLETION_ONSTACK(_ ## name); \
32841+ struct completion *comp = &_ ## name
32842+
32843+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
32844+{
32845+ wkinfo->comp = *comp;
32846+ return 0;
32847+}
32848+
32849+static void au_wkq_comp_free(struct completion *comp __maybe_unused)
32850+{
32851+ /* empty */
32852+}
32853+#endif /* 4KSTACKS */
32854+
53392da6 32855+static void au_wkq_run(struct au_wkinfo *wkinfo)
1facf9fc 32856+{
53392da6
AM
32857+ if (au_ftest_wkq(wkinfo->flags, NEST)) {
32858+ if (au_wkq_test()) {
38d290e6
JR
32859+ AuWarn1("wkq from wkq, unless silly-rename on NFS,"
32860+ " due to a dead dir by UDBA?\n");
53392da6
AM
32861+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT));
32862+ }
32863+ } else
32864+ au_dbg_verify_kthread();
32865+
32866+ if (au_ftest_wkq(wkinfo->flags, WAIT)) {
a1f66529 32867+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func);
9dbd164d 32868+ queue_work(au_wkq, &wkinfo->wk);
4a4d8108
AM
32869+ } else {
32870+ INIT_WORK(&wkinfo->wk, wkq_func);
32871+ schedule_work(&wkinfo->wk);
32872+ }
1facf9fc 32873+}
32874+
7f207e10
AM
32875+/*
32876+ * Be careful. It is easy to make deadlock happen.
32877+ * processA: lock, wkq and wait
32878+ * processB: wkq and wait, lock in wkq
32879+ * --> deadlock
32880+ */
b752ccd1 32881+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args)
1facf9fc 32882+{
32883+ int err;
32884+ AuWkqCompDeclare(comp);
32885+ struct au_wkinfo wkinfo = {
b752ccd1 32886+ .flags = flags,
1facf9fc 32887+ .func = func,
32888+ .args = args
32889+ };
32890+
32891+ err = au_wkq_comp_alloc(&wkinfo, &comp);
32892+ if (!err) {
53392da6 32893+ au_wkq_run(&wkinfo);
1facf9fc 32894+ /* no timeout, no interrupt */
32895+ wait_for_completion(wkinfo.comp);
32896+ au_wkq_comp_free(comp);
4a4d8108 32897+ destroy_work_on_stack(&wkinfo.wk);
1facf9fc 32898+ }
32899+
32900+ return err;
32901+
32902+}
32903+
027c5e7a
AM
32904+/*
32905+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a
32906+ * problem in a concurrent umounting.
32907+ */
53392da6
AM
32908+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
32909+ unsigned int flags)
1facf9fc 32910+{
32911+ int err;
32912+ struct au_wkinfo *wkinfo;
32913+
32914+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
32915+
32916+ /*
32917+ * wkq_func() must free this wkinfo.
32918+ * it highly depends upon the implementation of workqueue.
32919+ */
32920+ err = 0;
32921+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
32922+ if (wkinfo) {
7f207e10 32923+ wkinfo->kobj = &au_sbi(sb)->si_kobj;
53392da6 32924+ wkinfo->flags = flags & ~AuWkq_WAIT;
1facf9fc 32925+ wkinfo->func = func;
32926+ wkinfo->args = args;
32927+ wkinfo->comp = NULL;
7f207e10 32928+ kobject_get(wkinfo->kobj);
9dbd164d 32929+ __module_get(THIS_MODULE); /* todo: ?? */
1facf9fc 32930+
53392da6 32931+ au_wkq_run(wkinfo);
1facf9fc 32932+ } else {
32933+ err = -ENOMEM;
e49829fe 32934+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 32935+ }
32936+
32937+ return err;
32938+}
32939+
32940+/* ---------------------------------------------------------------------- */
32941+
32942+void au_nwt_init(struct au_nowait_tasks *nwt)
32943+{
32944+ atomic_set(&nwt->nw_len, 0);
4a4d8108 32945+ /* smp_mb(); */ /* atomic_set */
1facf9fc 32946+ init_waitqueue_head(&nwt->nw_wq);
32947+}
32948+
32949+void au_wkq_fin(void)
32950+{
9dbd164d 32951+ destroy_workqueue(au_wkq);
1facf9fc 32952+}
32953+
32954+int __init au_wkq_init(void)
32955+{
9dbd164d 32956+ int err;
b752ccd1
AM
32957+
32958+ err = 0;
86dc4139 32959+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE);
9dbd164d
AM
32960+ if (IS_ERR(au_wkq))
32961+ err = PTR_ERR(au_wkq);
32962+ else if (!au_wkq)
32963+ err = -ENOMEM;
b752ccd1
AM
32964+
32965+ return err;
1facf9fc 32966+}
7f207e10
AM
32967diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
32968--- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100
c1595e42 32969+++ linux/fs/aufs/wkq.h 2015-01-25 13:00:38.634380408 +0100
523b37e3 32970@@ -0,0 +1,91 @@
1facf9fc 32971+/*
523b37e3 32972+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 32973+ *
32974+ * This program, aufs is free software; you can redistribute it and/or modify
32975+ * it under the terms of the GNU General Public License as published by
32976+ * the Free Software Foundation; either version 2 of the License, or
32977+ * (at your option) any later version.
dece6358
AM
32978+ *
32979+ * This program is distributed in the hope that it will be useful,
32980+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32981+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32982+ * GNU General Public License for more details.
32983+ *
32984+ * You should have received a copy of the GNU General Public License
523b37e3 32985+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 32986+ */
32987+
32988+/*
32989+ * workqueue for asynchronous/super-io operations
32990+ * todo: try new credentials management scheme
32991+ */
32992+
32993+#ifndef __AUFS_WKQ_H__
32994+#define __AUFS_WKQ_H__
32995+
32996+#ifdef __KERNEL__
32997+
dece6358
AM
32998+struct super_block;
32999+
1facf9fc 33000+/* ---------------------------------------------------------------------- */
33001+
33002+/*
33003+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
33004+ */
33005+struct au_nowait_tasks {
33006+ atomic_t nw_len;
33007+ wait_queue_head_t nw_wq;
33008+};
33009+
33010+/* ---------------------------------------------------------------------- */
33011+
33012+typedef void (*au_wkq_func_t)(void *args);
33013+
33014+/* wkq flags */
33015+#define AuWkq_WAIT 1
9dbd164d 33016+#define AuWkq_NEST (1 << 1)
1facf9fc 33017+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name)
7f207e10
AM
33018+#define au_fset_wkq(flags, name) \
33019+ do { (flags) |= AuWkq_##name; } while (0)
33020+#define au_fclr_wkq(flags, name) \
33021+ do { (flags) &= ~AuWkq_##name; } while (0)
1facf9fc 33022+
9dbd164d
AM
33023+#ifndef CONFIG_AUFS_HNOTIFY
33024+#undef AuWkq_NEST
33025+#define AuWkq_NEST 0
33026+#endif
33027+
1facf9fc 33028+/* wkq.c */
b752ccd1 33029+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args);
53392da6
AM
33030+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
33031+ unsigned int flags);
1facf9fc 33032+void au_nwt_init(struct au_nowait_tasks *nwt);
33033+int __init au_wkq_init(void);
33034+void au_wkq_fin(void);
33035+
33036+/* ---------------------------------------------------------------------- */
33037+
53392da6
AM
33038+static inline int au_wkq_test(void)
33039+{
33040+ return current->flags & PF_WQ_WORKER;
33041+}
33042+
b752ccd1 33043+static inline int au_wkq_wait(au_wkq_func_t func, void *args)
1facf9fc 33044+{
b752ccd1 33045+ return au_wkq_do_wait(AuWkq_WAIT, func, args);
1facf9fc 33046+}
33047+
33048+static inline void au_nwt_done(struct au_nowait_tasks *nwt)
33049+{
e49829fe 33050+ if (atomic_dec_and_test(&nwt->nw_len))
1facf9fc 33051+ wake_up_all(&nwt->nw_wq);
33052+}
33053+
33054+static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
33055+{
33056+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
33057+ return 0;
33058+}
33059+
33060+#endif /* __KERNEL__ */
33061+#endif /* __AUFS_WKQ_H__ */
c1595e42
JR
33062diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
33063--- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100
33064+++ linux/fs/aufs/xattr.c 2015-01-25 13:00:38.634380408 +0100
33065@@ -0,0 +1,334 @@
33066+/*
33067+ * Copyright (C) 2014 Junjiro R. Okajima
33068+ *
33069+ * This program, aufs is free software; you can redistribute it and/or modify
33070+ * it under the terms of the GNU General Public License as published by
33071+ * the Free Software Foundation; either version 2 of the License, or
33072+ * (at your option) any later version.
33073+ *
33074+ * This program is distributed in the hope that it will be useful,
33075+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33076+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33077+ * GNU General Public License for more details.
33078+ *
33079+ * You should have received a copy of the GNU General Public License
33080+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
33081+ */
33082+
33083+/*
33084+ * handling xattr functions
33085+ */
33086+
33087+#include <linux/xattr.h>
33088+#include "aufs.h"
33089+
33090+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
33091+{
33092+ if (!ignore_flags)
33093+ goto out;
33094+ switch (err) {
33095+ case -ENOMEM:
33096+ case -EDQUOT:
33097+ goto out;
33098+ }
33099+
33100+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
33101+ err = 0;
33102+ goto out;
33103+ }
33104+
33105+#define cmp(brattr, prefix) do { \
33106+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \
33107+ XATTR_##prefix##_PREFIX_LEN)) { \
33108+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \
33109+ err = 0; \
33110+ goto out; \
33111+ } \
33112+ } while (0)
33113+
33114+ cmp(SEC, SECURITY);
33115+ cmp(SYS, SYSTEM);
33116+ cmp(TR, TRUSTED);
33117+ cmp(USR, USER);
33118+#undef cmp
33119+
33120+ if (ignore_flags & AuBrAttr_ICEX_OTH)
33121+ err = 0;
33122+
33123+out:
33124+ return err;
33125+}
33126+
33127+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
33128+
33129+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
33130+ char *name, char **buf, unsigned int ignore_flags)
33131+{
33132+ int err;
33133+ ssize_t ssz;
33134+ struct inode *h_idst;
33135+
33136+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
33137+ err = ssz;
33138+ if (unlikely(err <= 0)) {
33139+ AuTraceErr(err);
33140+ if (err == -ENODATA
33141+ || (err == -EOPNOTSUPP
33142+ && (ignore_flags & au_xattr_out_of_list)))
33143+ err = 0;
33144+ goto out;
33145+ }
33146+
33147+ /* unlock it temporary */
33148+ h_idst = h_dst->d_inode;
33149+ mutex_unlock(&h_idst->i_mutex);
33150+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
33151+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
33152+ if (unlikely(err)) {
33153+ AuDbg("%s, err %d\n", name, err);
33154+ err = au_xattr_ignore(err, name, ignore_flags);
33155+ }
33156+
33157+out:
33158+ return err;
33159+}
33160+
33161+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags)
33162+{
33163+ int err, unlocked, acl_access, acl_default;
33164+ ssize_t ssz;
33165+ struct inode *h_isrc, *h_idst;
33166+ char *value, *p, *o, *e;
33167+
33168+ /* try stopping to update the source inode while we are referencing */
33169+ /* there should not be the parent-child relation ship between them */
33170+ h_isrc = h_src->d_inode;
33171+ h_idst = h_dst->d_inode;
33172+ mutex_unlock(&h_idst->i_mutex);
33173+ mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
33174+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
33175+ unlocked = 0;
33176+
33177+ /* some filesystems don't list POSIX ACL, for example tmpfs */
33178+ ssz = vfs_listxattr(h_src, NULL, 0);
33179+ err = ssz;
33180+ if (unlikely(err < 0)) {
33181+ AuTraceErr(err);
33182+ if (err == -ENODATA
33183+ || err == -EOPNOTSUPP)
33184+ err = 0; /* ignore */
33185+ goto out;
33186+ }
33187+
33188+ err = 0;
33189+ p = NULL;
33190+ o = NULL;
33191+ if (ssz) {
33192+ err = -ENOMEM;
33193+ p = kmalloc(ssz, GFP_NOFS);
33194+ o = p;
33195+ if (unlikely(!p))
33196+ goto out;
33197+ err = vfs_listxattr(h_src, p, ssz);
33198+ }
33199+ mutex_unlock(&h_isrc->i_mutex);
33200+ unlocked = 1;
33201+ AuDbg("err %d, ssz %zd\n", err, ssz);
33202+ if (unlikely(err < 0))
33203+ goto out_free;
33204+
33205+ err = 0;
33206+ e = p + ssz;
33207+ value = NULL;
33208+ acl_access = 0;
33209+ acl_default = 0;
33210+ while (!err && p < e) {
33211+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
33212+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
33213+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
33214+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
33215+ - 1);
33216+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags);
33217+ p += strlen(p) + 1;
33218+ }
33219+ AuTraceErr(err);
33220+ ignore_flags |= au_xattr_out_of_list;
33221+ if (!err && !acl_access) {
33222+ err = au_do_cpup_xattr(h_dst, h_src,
33223+ XATTR_NAME_POSIX_ACL_ACCESS, &value,
33224+ ignore_flags);
33225+ AuTraceErr(err);
33226+ }
33227+ if (!err && !acl_default) {
33228+ err = au_do_cpup_xattr(h_dst, h_src,
33229+ XATTR_NAME_POSIX_ACL_DEFAULT, &value,
33230+ ignore_flags);
33231+ AuTraceErr(err);
33232+ }
33233+
33234+ kfree(value);
33235+
33236+out_free:
33237+ kfree(o);
33238+out:
33239+ if (!unlocked)
33240+ mutex_unlock(&h_isrc->i_mutex);
33241+ AuTraceErr(err);
33242+ return err;
33243+}
33244+
33245+/* ---------------------------------------------------------------------- */
33246+
33247+enum {
33248+ AU_XATTR_LIST,
33249+ AU_XATTR_GET
33250+};
33251+
33252+struct au_lgxattr {
33253+ int type;
33254+ union {
33255+ struct {
33256+ char *list;
33257+ size_t size;
33258+ } list;
33259+ struct {
33260+ const char *name;
33261+ void *value;
33262+ size_t size;
33263+ } get;
33264+ } u;
33265+};
33266+
33267+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
33268+{
33269+ ssize_t err;
33270+ struct path h_path;
33271+ struct super_block *sb;
33272+
33273+ sb = dentry->d_sb;
33274+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
33275+ if (unlikely(err))
33276+ goto out;
33277+ err = au_h_path_getattr(dentry, /*force*/1, &h_path);
33278+ if (unlikely(err))
33279+ goto out_si;
33280+ if (unlikely(!h_path.dentry))
33281+ /* illegally overlapped or something */
33282+ goto out_di; /* pretending success */
33283+
33284+ /* always topmost entry only */
33285+ switch (arg->type) {
33286+ case AU_XATTR_LIST:
33287+ err = vfs_listxattr(h_path.dentry,
33288+ arg->u.list.list, arg->u.list.size);
33289+ break;
33290+ case AU_XATTR_GET:
33291+ err = vfs_getxattr(h_path.dentry,
33292+ arg->u.get.name, arg->u.get.value,
33293+ arg->u.get.size);
33294+ break;
33295+ }
33296+
33297+out_di:
33298+ di_read_unlock(dentry, AuLock_IR);
33299+out_si:
33300+ si_read_unlock(sb);
33301+out:
33302+ AuTraceErr(err);
33303+ return err;
33304+}
33305+
33306+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
33307+{
33308+ struct au_lgxattr arg = {
33309+ .type = AU_XATTR_LIST,
33310+ .u.list = {
33311+ .list = list,
33312+ .size = size
33313+ },
33314+ };
33315+
33316+ return au_lgxattr(dentry, &arg);
33317+}
33318+
33319+ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
33320+ size_t size)
33321+{
33322+ struct au_lgxattr arg = {
33323+ .type = AU_XATTR_GET,
33324+ .u.get = {
33325+ .name = name,
33326+ .value = value,
33327+ .size = size
33328+ },
33329+ };
33330+
33331+ return au_lgxattr(dentry, &arg);
33332+}
33333+
33334+int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
33335+ size_t size, int flags)
33336+{
33337+ struct au_srxattr arg = {
33338+ .type = AU_XATTR_SET,
33339+ .u.set = {
33340+ .name = name,
33341+ .value = value,
33342+ .size = size,
33343+ .flags = flags
33344+ },
33345+ };
33346+
33347+ return au_srxattr(dentry, &arg);
33348+}
33349+
33350+int aufs_removexattr(struct dentry *dentry, const char *name)
33351+{
33352+ struct au_srxattr arg = {
33353+ .type = AU_XATTR_REMOVE,
33354+ .u.remove = {
33355+ .name = name
33356+ },
33357+ };
33358+
33359+ return au_srxattr(dentry, &arg);
33360+}
33361+
33362+/* ---------------------------------------------------------------------- */
33363+
33364+#if 0
33365+static size_t au_xattr_list(struct dentry *dentry, char *list, size_t list_size,
33366+ const char *name, size_t name_len, int type)
33367+{
33368+ return aufs_listxattr(dentry, list, list_size);
33369+}
33370+
33371+static int au_xattr_get(struct dentry *dentry, const char *name, void *buffer,
33372+ size_t size, int type)
33373+{
33374+ return aufs_getxattr(dentry, name, buffer, size);
33375+}
33376+
33377+static int au_xattr_set(struct dentry *dentry, const char *name,
33378+ const void *value, size_t size, int flags, int type)
33379+{
33380+ return aufs_setxattr(dentry, name, value, size, flags);
33381+}
33382+
33383+static const struct xattr_handler au_xattr_handler = {
33384+ /* no prefix, no flags */
33385+ .list = au_xattr_list,
33386+ .get = au_xattr_get,
33387+ .set = au_xattr_set
33388+ /* why no remove? */
33389+};
33390+
33391+static const struct xattr_handler *au_xattr_handlers[] = {
33392+ &au_xattr_handler
33393+};
33394+
33395+void au_xattr_init(struct super_block *sb)
33396+{
33397+ /* sb->s_xattr = au_xattr_handlers; */
33398+}
33399+#endif
7f207e10
AM
33400diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
33401--- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
33402+++ linux/fs/aufs/xino.c 2015-01-25 13:00:38.634380408 +0100
33403@@ -0,0 +1,1318 @@
1facf9fc 33404+/*
523b37e3 33405+ * Copyright (C) 2005-2014 Junjiro R. Okajima
1facf9fc 33406+ *
33407+ * This program, aufs is free software; you can redistribute it and/or modify
33408+ * it under the terms of the GNU General Public License as published by
33409+ * the Free Software Foundation; either version 2 of the License, or
33410+ * (at your option) any later version.
dece6358
AM
33411+ *
33412+ * This program is distributed in the hope that it will be useful,
33413+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33415+ * GNU General Public License for more details.
33416+ *
33417+ * You should have received a copy of the GNU General Public License
523b37e3 33418+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1facf9fc 33419+ */
33420+
33421+/*
33422+ * external inode number translation table and bitmap
33423+ */
33424+
33425+#include <linux/seq_file.h>
392086de 33426+#include <linux/statfs.h>
1facf9fc 33427+#include "aufs.h"
33428+
9dbd164d 33429+/* todo: unnecessary to support mmap_sem since kernel-space? */
b752ccd1 33430+ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size,
1facf9fc 33431+ loff_t *pos)
33432+{
33433+ ssize_t err;
33434+ mm_segment_t oldfs;
b752ccd1
AM
33435+ union {
33436+ void *k;
33437+ char __user *u;
33438+ } buf;
1facf9fc 33439+
b752ccd1 33440+ buf.k = kbuf;
1facf9fc 33441+ oldfs = get_fs();
33442+ set_fs(KERNEL_DS);
33443+ do {
33444+ /* todo: signal_pending? */
b752ccd1 33445+ err = func(file, buf.u, size, pos);
1facf9fc 33446+ } while (err == -EAGAIN || err == -EINTR);
33447+ set_fs(oldfs);
33448+
33449+#if 0 /* reserved for future use */
33450+ if (err > 0)
33451+ fsnotify_access(file->f_dentry);
33452+#endif
33453+
33454+ return err;
33455+}
33456+
33457+/* ---------------------------------------------------------------------- */
33458+
b752ccd1 33459+static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf,
1facf9fc 33460+ size_t size, loff_t *pos)
33461+{
33462+ ssize_t err;
33463+ mm_segment_t oldfs;
b752ccd1
AM
33464+ union {
33465+ void *k;
33466+ const char __user *u;
33467+ } buf;
1facf9fc 33468+
b752ccd1 33469+ buf.k = kbuf;
1facf9fc 33470+ oldfs = get_fs();
33471+ set_fs(KERNEL_DS);
1facf9fc 33472+ do {
33473+ /* todo: signal_pending? */
b752ccd1 33474+ err = func(file, buf.u, size, pos);
1facf9fc 33475+ } while (err == -EAGAIN || err == -EINTR);
1facf9fc 33476+ set_fs(oldfs);
33477+
33478+#if 0 /* reserved for future use */
33479+ if (err > 0)
33480+ fsnotify_modify(file->f_dentry);
33481+#endif
33482+
33483+ return err;
33484+}
33485+
33486+struct do_xino_fwrite_args {
33487+ ssize_t *errp;
33488+ au_writef_t func;
33489+ struct file *file;
33490+ void *buf;
33491+ size_t size;
33492+ loff_t *pos;
33493+};
33494+
33495+static void call_do_xino_fwrite(void *args)
33496+{
33497+ struct do_xino_fwrite_args *a = args;
33498+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos);
33499+}
33500+
33501+ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size,
33502+ loff_t *pos)
33503+{
33504+ ssize_t err;
33505+
33506+ /* todo: signal block and no wkq? */
b752ccd1
AM
33507+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) {
33508+ lockdep_off();
33509+ err = do_xino_fwrite(func, file, buf, size, pos);
33510+ lockdep_on();
33511+ } else {
33512+ /*
33513+ * it breaks RLIMIT_FSIZE and normal user's limit,
33514+ * users should care about quota and real 'filesystem full.'
33515+ */
1facf9fc 33516+ int wkq_err;
33517+ struct do_xino_fwrite_args args = {
33518+ .errp = &err,
33519+ .func = func,
33520+ .file = file,
33521+ .buf = buf,
33522+ .size = size,
33523+ .pos = pos
33524+ };
33525+
33526+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args);
33527+ if (unlikely(wkq_err))
33528+ err = wkq_err;
b752ccd1 33529+ }
1facf9fc 33530+
33531+ return err;
33532+}
33533+
33534+/* ---------------------------------------------------------------------- */
33535+
33536+/*
33537+ * create a new xinofile at the same place/path as @base_file.
33538+ */
33539+struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
33540+{
33541+ struct file *file;
4a4d8108 33542+ struct dentry *base, *parent;
523b37e3 33543+ struct inode *dir, *delegated;
1facf9fc 33544+ struct qstr *name;
1308ab2a 33545+ struct path path;
4a4d8108 33546+ int err;
1facf9fc 33547+
33548+ base = base_file->f_dentry;
33549+ parent = base->d_parent; /* dir inode is locked */
33550+ dir = parent->d_inode;
33551+ IMustLock(dir);
33552+
33553+ file = ERR_PTR(-EINVAL);
33554+ name = &base->d_name;
4a4d8108
AM
33555+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len);
33556+ if (IS_ERR(path.dentry)) {
33557+ file = (void *)path.dentry;
523b37e3
AM
33558+ pr_err("%pd lookup err %ld\n",
33559+ base, PTR_ERR(path.dentry));
1facf9fc 33560+ goto out;
33561+ }
33562+
33563+ /* no need to mnt_want_write() since we call dentry_open() later */
4a4d8108 33564+ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL);
1facf9fc 33565+ if (unlikely(err)) {
33566+ file = ERR_PTR(err);
523b37e3 33567+ pr_err("%pd create err %d\n", base, err);
1facf9fc 33568+ goto out_dput;
33569+ }
33570+
c06a8ce3 33571+ path.mnt = base_file->f_path.mnt;
4a4d8108 33572+ file = vfsub_dentry_open(&path,
7f207e10 33573+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 33574+ /* | __FMODE_NONOTIFY */);
1facf9fc 33575+ if (IS_ERR(file)) {
523b37e3 33576+ pr_err("%pd open err %ld\n", base, PTR_ERR(file));
1facf9fc 33577+ goto out_dput;
33578+ }
33579+
523b37e3
AM
33580+ delegated = NULL;
33581+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0);
33582+ if (unlikely(err == -EWOULDBLOCK)) {
33583+ pr_warn("cannot retry for NFSv4 delegation"
33584+ " for an internal unlink\n");
33585+ iput(delegated);
33586+ }
1facf9fc 33587+ if (unlikely(err)) {
523b37e3 33588+ pr_err("%pd unlink err %d\n", base, err);
1facf9fc 33589+ goto out_fput;
33590+ }
33591+
33592+ if (copy_src) {
33593+ /* no one can touch copy_src xino */
c06a8ce3 33594+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src));
1facf9fc 33595+ if (unlikely(err)) {
523b37e3 33596+ pr_err("%pd copy err %d\n", base, err);
1facf9fc 33597+ goto out_fput;
33598+ }
33599+ }
33600+ goto out_dput; /* success */
33601+
4f0767ce 33602+out_fput:
1facf9fc 33603+ fput(file);
33604+ file = ERR_PTR(err);
4f0767ce 33605+out_dput:
4a4d8108 33606+ dput(path.dentry);
4f0767ce 33607+out:
1facf9fc 33608+ return file;
33609+}
33610+
33611+struct au_xino_lock_dir {
33612+ struct au_hinode *hdir;
33613+ struct dentry *parent;
33614+ struct mutex *mtx;
33615+};
33616+
33617+static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
33618+ struct au_xino_lock_dir *ldir)
33619+{
33620+ aufs_bindex_t brid, bindex;
33621+
33622+ ldir->hdir = NULL;
33623+ bindex = -1;
33624+ brid = au_xino_brid(sb);
33625+ if (brid >= 0)
33626+ bindex = au_br_index(sb, brid);
33627+ if (bindex >= 0) {
33628+ ldir->hdir = au_hi(sb->s_root->d_inode, bindex);
4a4d8108 33629+ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
1facf9fc 33630+ } else {
33631+ ldir->parent = dget_parent(xino->f_dentry);
33632+ ldir->mtx = &ldir->parent->d_inode->i_mutex;
33633+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT);
33634+ }
33635+}
33636+
33637+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
33638+{
33639+ if (ldir->hdir)
4a4d8108 33640+ au_hn_imtx_unlock(ldir->hdir);
1facf9fc 33641+ else {
33642+ mutex_unlock(ldir->mtx);
33643+ dput(ldir->parent);
33644+ }
33645+}
33646+
33647+/* ---------------------------------------------------------------------- */
33648+
33649+/* trucate xino files asynchronously */
33650+
33651+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex)
33652+{
33653+ int err;
392086de
AM
33654+ unsigned long jiffy;
33655+ blkcnt_t blocks;
1facf9fc 33656+ aufs_bindex_t bi, bend;
392086de 33657+ struct kstatfs *st;
1facf9fc 33658+ struct au_branch *br;
33659+ struct file *new_xino, *file;
33660+ struct super_block *h_sb;
33661+ struct au_xino_lock_dir ldir;
33662+
392086de
AM
33663+ err = -ENOMEM;
33664+ st = kzalloc(sizeof(*st), GFP_NOFS);
33665+ if (unlikely(!st))
33666+ goto out;
33667+
1facf9fc 33668+ err = -EINVAL;
33669+ bend = au_sbend(sb);
33670+ if (unlikely(bindex < 0 || bend < bindex))
392086de 33671+ goto out_st;
1facf9fc 33672+ br = au_sbr(sb, bindex);
33673+ file = br->br_xino.xi_file;
33674+ if (!file)
392086de
AM
33675+ goto out_st;
33676+
33677+ err = vfs_statfs(&file->f_path, st);
33678+ if (unlikely(err))
33679+ AuErr1("statfs err %d, ignored\n", err);
33680+ jiffy = jiffies;
33681+ blocks = file_inode(file)->i_blocks;
33682+ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
33683+ bindex, (u64)blocks, st->f_bfree, st->f_blocks);
1facf9fc 33684+
33685+ au_xino_lock_dir(sb, file, &ldir);
33686+ /* mnt_want_write() is unnecessary here */
33687+ new_xino = au_xino_create2(file, file);
33688+ au_xino_unlock_dir(&ldir);
33689+ err = PTR_ERR(new_xino);
392086de
AM
33690+ if (IS_ERR(new_xino)) {
33691+ pr_err("err %d, ignored\n", err);
33692+ goto out_st;
33693+ }
1facf9fc 33694+ err = 0;
33695+ fput(file);
33696+ br->br_xino.xi_file = new_xino;
33697+
86dc4139 33698+ h_sb = au_br_sb(br);
1facf9fc 33699+ for (bi = 0; bi <= bend; bi++) {
33700+ if (unlikely(bi == bindex))
33701+ continue;
33702+ br = au_sbr(sb, bi);
86dc4139 33703+ if (au_br_sb(br) != h_sb)
1facf9fc 33704+ continue;
33705+
33706+ fput(br->br_xino.xi_file);
33707+ br->br_xino.xi_file = new_xino;
33708+ get_file(new_xino);
33709+ }
33710+
392086de
AM
33711+ err = vfs_statfs(&new_xino->f_path, st);
33712+ if (!err) {
33713+ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n",
33714+ bindex, (u64)file_inode(new_xino)->i_blocks,
33715+ st->f_bfree, st->f_blocks);
33716+ if (file_inode(new_xino)->i_blocks < blocks)
33717+ au_sbi(sb)->si_xino_jiffy = jiffy;
33718+ } else
33719+ AuErr1("statfs err %d, ignored\n", err);
33720+
33721+out_st:
33722+ kfree(st);
4f0767ce 33723+out:
1facf9fc 33724+ return err;
33725+}
33726+
33727+struct xino_do_trunc_args {
33728+ struct super_block *sb;
33729+ struct au_branch *br;
33730+};
33731+
33732+static void xino_do_trunc(void *_args)
33733+{
33734+ struct xino_do_trunc_args *args = _args;
33735+ struct super_block *sb;
33736+ struct au_branch *br;
33737+ struct inode *dir;
33738+ int err;
33739+ aufs_bindex_t bindex;
33740+
33741+ err = 0;
33742+ sb = args->sb;
33743+ dir = sb->s_root->d_inode;
33744+ br = args->br;
33745+
33746+ si_noflush_write_lock(sb);
33747+ ii_read_lock_parent(dir);
33748+ bindex = au_br_index(sb, br->br_id);
33749+ err = au_xino_trunc(sb, bindex);
1facf9fc 33750+ ii_read_unlock(dir);
33751+ if (unlikely(err))
392086de 33752+ pr_warn("err b%d, (%d)\n", bindex, err);
1facf9fc 33753+ atomic_dec(&br->br_xino_running);
33754+ atomic_dec(&br->br_count);
1facf9fc 33755+ si_write_unlock(sb);
027c5e7a 33756+ au_nwt_done(&au_sbi(sb)->si_nowait);
1facf9fc 33757+ kfree(args);
33758+}
33759+
392086de
AM
33760+static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
33761+{
33762+ int err;
33763+ struct kstatfs st;
33764+ struct au_sbinfo *sbinfo;
33765+
33766+ /* todo: si_xino_expire and the ratio should be customizable */
33767+ sbinfo = au_sbi(sb);
33768+ if (time_before(jiffies,
33769+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire))
33770+ return 0;
33771+
33772+ /* truncation border */
33773+ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st);
33774+ if (unlikely(err)) {
33775+ AuErr1("statfs err %d, ignored\n", err);
33776+ return 0;
33777+ }
33778+ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC)
33779+ return 0;
33780+
33781+ return 1;
33782+}
33783+
1facf9fc 33784+static void xino_try_trunc(struct super_block *sb, struct au_branch *br)
33785+{
33786+ struct xino_do_trunc_args *args;
33787+ int wkq_err;
33788+
392086de 33789+ if (!xino_trunc_test(sb, br))
1facf9fc 33790+ return;
33791+
33792+ if (atomic_inc_return(&br->br_xino_running) > 1)
33793+ goto out;
33794+
33795+ /* lock and kfree() will be called in trunc_xino() */
33796+ args = kmalloc(sizeof(*args), GFP_NOFS);
33797+ if (unlikely(!args)) {
33798+ AuErr1("no memory\n");
33799+ goto out_args;
33800+ }
33801+
e49829fe 33802+ atomic_inc(&br->br_count);
1facf9fc 33803+ args->sb = sb;
33804+ args->br = br;
53392da6 33805+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0);
1facf9fc 33806+ if (!wkq_err)
33807+ return; /* success */
33808+
4a4d8108 33809+ pr_err("wkq %d\n", wkq_err);
e49829fe 33810+ atomic_dec(&br->br_count);
1facf9fc 33811+
4f0767ce 33812+out_args:
1facf9fc 33813+ kfree(args);
4f0767ce 33814+out:
e49829fe 33815+ atomic_dec(&br->br_xino_running);
1facf9fc 33816+}
33817+
33818+/* ---------------------------------------------------------------------- */
33819+
33820+static int au_xino_do_write(au_writef_t write, struct file *file,
33821+ ino_t h_ino, ino_t ino)
33822+{
33823+ loff_t pos;
33824+ ssize_t sz;
33825+
33826+ pos = h_ino;
33827+ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) {
33828+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
33829+ return -EFBIG;
33830+ }
33831+ pos *= sizeof(ino);
33832+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos);
33833+ if (sz == sizeof(ino))
33834+ return 0; /* success */
33835+
33836+ AuIOErr("write failed (%zd)\n", sz);
33837+ return -EIO;
33838+}
33839+
33840+/*
33841+ * write @ino to the xinofile for the specified branch{@sb, @bindex}
33842+ * at the position of @h_ino.
33843+ * even if @ino is zero, it is written to the xinofile and means no entry.
33844+ * if the size of the xino file on a specific filesystem exceeds the watermark,
33845+ * try truncating it.
33846+ */
33847+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
33848+ ino_t ino)
33849+{
33850+ int err;
33851+ unsigned int mnt_flags;
33852+ struct au_branch *br;
33853+
33854+ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max)
33855+ || ((loff_t)-1) > 0);
dece6358 33856+ SiMustAnyLock(sb);
1facf9fc 33857+
33858+ mnt_flags = au_mntflags(sb);
33859+ if (!au_opt_test(mnt_flags, XINO))
33860+ return 0;
33861+
33862+ br = au_sbr(sb, bindex);
33863+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
33864+ h_ino, ino);
33865+ if (!err) {
33866+ if (au_opt_test(mnt_flags, TRUNC_XINO)
86dc4139 33867+ && au_test_fs_trunc_xino(au_br_sb(br)))
1facf9fc 33868+ xino_try_trunc(sb, br);
33869+ return 0; /* success */
33870+ }
33871+
33872+ AuIOErr("write failed (%d)\n", err);
33873+ return -EIO;
33874+}
33875+
33876+/* ---------------------------------------------------------------------- */
33877+
33878+/* aufs inode number bitmap */
33879+
33880+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE;
33881+static ino_t xib_calc_ino(unsigned long pindex, int bit)
33882+{
33883+ ino_t ino;
33884+
33885+ AuDebugOn(bit < 0 || page_bits <= bit);
33886+ ino = AUFS_FIRST_INO + pindex * page_bits + bit;
33887+ return ino;
33888+}
33889+
33890+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit)
33891+{
33892+ AuDebugOn(ino < AUFS_FIRST_INO);
33893+ ino -= AUFS_FIRST_INO;
33894+ *pindex = ino / page_bits;
33895+ *bit = ino % page_bits;
33896+}
33897+
33898+static int xib_pindex(struct super_block *sb, unsigned long pindex)
33899+{
33900+ int err;
33901+ loff_t pos;
33902+ ssize_t sz;
33903+ struct au_sbinfo *sbinfo;
33904+ struct file *xib;
33905+ unsigned long *p;
33906+
33907+ sbinfo = au_sbi(sb);
33908+ MtxMustLock(&sbinfo->si_xib_mtx);
33909+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE
33910+ || !au_opt_test(sbinfo->si_mntflags, XINO));
33911+
33912+ if (pindex == sbinfo->si_xib_last_pindex)
33913+ return 0;
33914+
33915+ xib = sbinfo->si_xib;
33916+ p = sbinfo->si_xib_buf;
33917+ pos = sbinfo->si_xib_last_pindex;
33918+ pos *= PAGE_SIZE;
33919+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
33920+ if (unlikely(sz != PAGE_SIZE))
33921+ goto out;
33922+
33923+ pos = pindex;
33924+ pos *= PAGE_SIZE;
c06a8ce3 33925+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE)
1facf9fc 33926+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos);
33927+ else {
33928+ memset(p, 0, PAGE_SIZE);
33929+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos);
33930+ }
33931+ if (sz == PAGE_SIZE) {
33932+ sbinfo->si_xib_last_pindex = pindex;
33933+ return 0; /* success */
33934+ }
33935+
4f0767ce 33936+out:
b752ccd1
AM
33937+ AuIOErr1("write failed (%zd)\n", sz);
33938+ err = sz;
33939+ if (sz >= 0)
33940+ err = -EIO;
33941+ return err;
33942+}
33943+
33944+/* ---------------------------------------------------------------------- */
33945+
33946+static void au_xib_clear_bit(struct inode *inode)
33947+{
33948+ int err, bit;
33949+ unsigned long pindex;
33950+ struct super_block *sb;
33951+ struct au_sbinfo *sbinfo;
33952+
33953+ AuDebugOn(inode->i_nlink);
33954+
33955+ sb = inode->i_sb;
33956+ xib_calc_bit(inode->i_ino, &pindex, &bit);
33957+ AuDebugOn(page_bits <= bit);
33958+ sbinfo = au_sbi(sb);
33959+ mutex_lock(&sbinfo->si_xib_mtx);
33960+ err = xib_pindex(sb, pindex);
33961+ if (!err) {
33962+ clear_bit(bit, sbinfo->si_xib_buf);
33963+ sbinfo->si_xib_next_bit = bit;
33964+ }
33965+ mutex_unlock(&sbinfo->si_xib_mtx);
33966+}
33967+
33968+/* for s_op->delete_inode() */
33969+void au_xino_delete_inode(struct inode *inode, const int unlinked)
33970+{
33971+ int err;
33972+ unsigned int mnt_flags;
33973+ aufs_bindex_t bindex, bend, bi;
33974+ unsigned char try_trunc;
33975+ struct au_iinfo *iinfo;
33976+ struct super_block *sb;
33977+ struct au_hinode *hi;
33978+ struct inode *h_inode;
33979+ struct au_branch *br;
33980+ au_writef_t xwrite;
33981+
33982+ sb = inode->i_sb;
33983+ mnt_flags = au_mntflags(sb);
33984+ if (!au_opt_test(mnt_flags, XINO)
33985+ || inode->i_ino == AUFS_ROOT_INO)
33986+ return;
33987+
33988+ if (unlinked) {
33989+ au_xigen_inc(inode);
33990+ au_xib_clear_bit(inode);
33991+ }
33992+
33993+ iinfo = au_ii(inode);
33994+ if (!iinfo)
33995+ return;
1facf9fc 33996+
b752ccd1
AM
33997+ bindex = iinfo->ii_bstart;
33998+ if (bindex < 0)
33999+ return;
1facf9fc 34000+
b752ccd1
AM
34001+ xwrite = au_sbi(sb)->si_xwrite;
34002+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO);
34003+ hi = iinfo->ii_hinode + bindex;
34004+ bend = iinfo->ii_bend;
34005+ for (; bindex <= bend; bindex++, hi++) {
34006+ h_inode = hi->hi_inode;
34007+ if (!h_inode
34008+ || (!unlinked && h_inode->i_nlink))
34009+ continue;
1facf9fc 34010+
b752ccd1
AM
34011+ /* inode may not be revalidated */
34012+ bi = au_br_index(sb, hi->hi_id);
34013+ if (bi < 0)
34014+ continue;
1facf9fc 34015+
b752ccd1
AM
34016+ br = au_sbr(sb, bi);
34017+ err = au_xino_do_write(xwrite, br->br_xino.xi_file,
34018+ h_inode->i_ino, /*ino*/0);
34019+ if (!err && try_trunc
86dc4139 34020+ && au_test_fs_trunc_xino(au_br_sb(br)))
b752ccd1 34021+ xino_try_trunc(sb, br);
1facf9fc 34022+ }
1facf9fc 34023+}
34024+
34025+/* get an unused inode number from bitmap */
34026+ino_t au_xino_new_ino(struct super_block *sb)
34027+{
34028+ ino_t ino;
34029+ unsigned long *p, pindex, ul, pend;
34030+ struct au_sbinfo *sbinfo;
34031+ struct file *file;
34032+ int free_bit, err;
34033+
34034+ if (!au_opt_test(au_mntflags(sb), XINO))
34035+ return iunique(sb, AUFS_FIRST_INO);
34036+
34037+ sbinfo = au_sbi(sb);
34038+ mutex_lock(&sbinfo->si_xib_mtx);
34039+ p = sbinfo->si_xib_buf;
34040+ free_bit = sbinfo->si_xib_next_bit;
34041+ if (free_bit < page_bits && !test_bit(free_bit, p))
34042+ goto out; /* success */
34043+ free_bit = find_first_zero_bit(p, page_bits);
34044+ if (free_bit < page_bits)
34045+ goto out; /* success */
34046+
34047+ pindex = sbinfo->si_xib_last_pindex;
34048+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) {
34049+ err = xib_pindex(sb, ul);
34050+ if (unlikely(err))
34051+ goto out_err;
34052+ free_bit = find_first_zero_bit(p, page_bits);
34053+ if (free_bit < page_bits)
34054+ goto out; /* success */
34055+ }
34056+
34057+ file = sbinfo->si_xib;
c06a8ce3 34058+ pend = vfsub_f_size_read(file) / PAGE_SIZE;
1facf9fc 34059+ for (ul = pindex + 1; ul <= pend; ul++) {
34060+ err = xib_pindex(sb, ul);
34061+ if (unlikely(err))
34062+ goto out_err;
34063+ free_bit = find_first_zero_bit(p, page_bits);
34064+ if (free_bit < page_bits)
34065+ goto out; /* success */
34066+ }
34067+ BUG();
34068+
4f0767ce 34069+out:
1facf9fc 34070+ set_bit(free_bit, p);
7f207e10 34071+ sbinfo->si_xib_next_bit = free_bit + 1;
1facf9fc 34072+ pindex = sbinfo->si_xib_last_pindex;
34073+ mutex_unlock(&sbinfo->si_xib_mtx);
34074+ ino = xib_calc_ino(pindex, free_bit);
34075+ AuDbg("i%lu\n", (unsigned long)ino);
34076+ return ino;
4f0767ce 34077+out_err:
1facf9fc 34078+ mutex_unlock(&sbinfo->si_xib_mtx);
34079+ AuDbg("i0\n");
34080+ return 0;
34081+}
34082+
34083+/*
34084+ * read @ino from xinofile for the specified branch{@sb, @bindex}
34085+ * at the position of @h_ino.
34086+ * if @ino does not exist and @do_new is true, get new one.
34087+ */
34088+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino,
34089+ ino_t *ino)
34090+{
34091+ int err;
34092+ ssize_t sz;
34093+ loff_t pos;
34094+ struct file *file;
34095+ struct au_sbinfo *sbinfo;
34096+
34097+ *ino = 0;
34098+ if (!au_opt_test(au_mntflags(sb), XINO))
34099+ return 0; /* no xino */
34100+
34101+ err = 0;
34102+ sbinfo = au_sbi(sb);
34103+ pos = h_ino;
34104+ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) {
34105+ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino);
34106+ return -EFBIG;
34107+ }
34108+ pos *= sizeof(*ino);
34109+
34110+ file = au_sbr(sb, bindex)->br_xino.xi_file;
c06a8ce3 34111+ if (vfsub_f_size_read(file) < pos + sizeof(*ino))
1facf9fc 34112+ return 0; /* no ino */
34113+
34114+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos);
34115+ if (sz == sizeof(*ino))
34116+ return 0; /* success */
34117+
34118+ err = sz;
34119+ if (unlikely(sz >= 0)) {
34120+ err = -EIO;
34121+ AuIOErr("xino read error (%zd)\n", sz);
34122+ }
34123+
34124+ return err;
34125+}
34126+
34127+/* ---------------------------------------------------------------------- */
34128+
34129+/* create and set a new xino file */
34130+
34131+struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
34132+{
34133+ struct file *file;
34134+ struct dentry *h_parent, *d;
34135+ struct inode *h_dir;
34136+ int err;
34137+
34138+ /*
34139+ * at mount-time, and the xino file is the default path,
4a4d8108 34140+ * hnotify is disabled so we have no notify events to ignore.
1facf9fc 34141+ * when a user specified the xino, we cannot get au_hdir to be ignored.
34142+ */
7f207e10 34143+ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
2cbb1c4b 34144+ /* | __FMODE_NONOTIFY */,
1facf9fc 34145+ S_IRUGO | S_IWUGO);
34146+ if (IS_ERR(file)) {
34147+ if (!silent)
4a4d8108 34148+ pr_err("open %s(%ld)\n", fname, PTR_ERR(file));
1facf9fc 34149+ return file;
34150+ }
34151+
34152+ /* keep file count */
34153+ h_parent = dget_parent(file->f_dentry);
34154+ h_dir = h_parent->d_inode;
34155+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT);
34156+ /* mnt_want_write() is unnecessary here */
523b37e3
AM
34157+ /* no delegation since it is just created */
34158+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, /*force*/0);
1facf9fc 34159+ mutex_unlock(&h_dir->i_mutex);
34160+ dput(h_parent);
34161+ if (unlikely(err)) {
34162+ if (!silent)
4a4d8108 34163+ pr_err("unlink %s(%d)\n", fname, err);
1facf9fc 34164+ goto out;
34165+ }
34166+
34167+ err = -EINVAL;
34168+ d = file->f_dentry;
34169+ if (unlikely(sb == d->d_sb)) {
34170+ if (!silent)
4a4d8108 34171+ pr_err("%s must be outside\n", fname);
1facf9fc 34172+ goto out;
34173+ }
34174+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) {
34175+ if (!silent)
4a4d8108
AM
34176+ pr_err("xino doesn't support %s(%s)\n",
34177+ fname, au_sbtype(d->d_sb));
1facf9fc 34178+ goto out;
34179+ }
34180+ return file; /* success */
34181+
4f0767ce 34182+out:
1facf9fc 34183+ fput(file);
34184+ file = ERR_PTR(err);
34185+ return file;
34186+}
34187+
34188+/*
34189+ * find another branch who is on the same filesystem of the specified
34190+ * branch{@btgt}. search until @bend.
34191+ */
34192+static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt,
34193+ aufs_bindex_t bend)
34194+{
34195+ aufs_bindex_t bindex;
34196+ struct super_block *tgt_sb = au_sbr_sb(sb, btgt);
34197+
34198+ for (bindex = 0; bindex < btgt; bindex++)
34199+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
34200+ return bindex;
34201+ for (bindex++; bindex <= bend; bindex++)
34202+ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex)))
34203+ return bindex;
34204+ return -1;
34205+}
34206+
34207+/* ---------------------------------------------------------------------- */
34208+
34209+/*
34210+ * initialize the xinofile for the specified branch @br
34211+ * at the place/path where @base_file indicates.
34212+ * test whether another branch is on the same filesystem or not,
34213+ * if @do_test is true.
34214+ */
34215+int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino,
34216+ struct file *base_file, int do_test)
34217+{
34218+ int err;
34219+ ino_t ino;
34220+ aufs_bindex_t bend, bindex;
34221+ struct au_branch *shared_br, *b;
34222+ struct file *file;
34223+ struct super_block *tgt_sb;
34224+
34225+ shared_br = NULL;
34226+ bend = au_sbend(sb);
34227+ if (do_test) {
86dc4139 34228+ tgt_sb = au_br_sb(br);
1facf9fc 34229+ for (bindex = 0; bindex <= bend; bindex++) {
34230+ b = au_sbr(sb, bindex);
86dc4139 34231+ if (tgt_sb == au_br_sb(b)) {
1facf9fc 34232+ shared_br = b;
34233+ break;
34234+ }
34235+ }
34236+ }
34237+
34238+ if (!shared_br || !shared_br->br_xino.xi_file) {
34239+ struct au_xino_lock_dir ldir;
34240+
34241+ au_xino_lock_dir(sb, base_file, &ldir);
34242+ /* mnt_want_write() is unnecessary here */
34243+ file = au_xino_create2(base_file, NULL);
34244+ au_xino_unlock_dir(&ldir);
34245+ err = PTR_ERR(file);
34246+ if (IS_ERR(file))
34247+ goto out;
34248+ br->br_xino.xi_file = file;
34249+ } else {
34250+ br->br_xino.xi_file = shared_br->br_xino.xi_file;
34251+ get_file(br->br_xino.xi_file);
34252+ }
34253+
34254+ ino = AUFS_ROOT_INO;
34255+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file,
34256+ h_ino, ino);
b752ccd1
AM
34257+ if (unlikely(err)) {
34258+ fput(br->br_xino.xi_file);
34259+ br->br_xino.xi_file = NULL;
34260+ }
1facf9fc 34261+
4f0767ce 34262+out:
1facf9fc 34263+ return err;
34264+}
34265+
34266+/* ---------------------------------------------------------------------- */
34267+
34268+/* trucate a xino bitmap file */
34269+
34270+/* todo: slow */
34271+static int do_xib_restore(struct super_block *sb, struct file *file, void *page)
34272+{
34273+ int err, bit;
34274+ ssize_t sz;
34275+ unsigned long pindex;
34276+ loff_t pos, pend;
34277+ struct au_sbinfo *sbinfo;
34278+ au_readf_t func;
34279+ ino_t *ino;
34280+ unsigned long *p;
34281+
34282+ err = 0;
34283+ sbinfo = au_sbi(sb);
dece6358 34284+ MtxMustLock(&sbinfo->si_xib_mtx);
1facf9fc 34285+ p = sbinfo->si_xib_buf;
34286+ func = sbinfo->si_xread;
c06a8ce3 34287+ pend = vfsub_f_size_read(file);
1facf9fc 34288+ pos = 0;
34289+ while (pos < pend) {
34290+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos);
34291+ err = sz;
34292+ if (unlikely(sz <= 0))
34293+ goto out;
34294+
34295+ err = 0;
34296+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) {
34297+ if (unlikely(*ino < AUFS_FIRST_INO))
34298+ continue;
34299+
34300+ xib_calc_bit(*ino, &pindex, &bit);
34301+ AuDebugOn(page_bits <= bit);
34302+ err = xib_pindex(sb, pindex);
34303+ if (!err)
34304+ set_bit(bit, p);
34305+ else
34306+ goto out;
34307+ }
34308+ }
34309+
4f0767ce 34310+out:
1facf9fc 34311+ return err;
34312+}
34313+
34314+static int xib_restore(struct super_block *sb)
34315+{
34316+ int err;
34317+ aufs_bindex_t bindex, bend;
34318+ void *page;
34319+
34320+ err = -ENOMEM;
34321+ page = (void *)__get_free_page(GFP_NOFS);
34322+ if (unlikely(!page))
34323+ goto out;
34324+
34325+ err = 0;
34326+ bend = au_sbend(sb);
34327+ for (bindex = 0; !err && bindex <= bend; bindex++)
34328+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0)
34329+ err = do_xib_restore
34330+ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
34331+ else
34332+ AuDbg("b%d\n", bindex);
34333+ free_page((unsigned long)page);
34334+
4f0767ce 34335+out:
1facf9fc 34336+ return err;
34337+}
34338+
34339+int au_xib_trunc(struct super_block *sb)
34340+{
34341+ int err;
34342+ ssize_t sz;
34343+ loff_t pos;
34344+ struct au_xino_lock_dir ldir;
34345+ struct au_sbinfo *sbinfo;
34346+ unsigned long *p;
34347+ struct file *file;
34348+
dece6358
AM
34349+ SiMustWriteLock(sb);
34350+
1facf9fc 34351+ err = 0;
34352+ sbinfo = au_sbi(sb);
34353+ if (!au_opt_test(sbinfo->si_mntflags, XINO))
34354+ goto out;
34355+
34356+ file = sbinfo->si_xib;
c06a8ce3 34357+ if (vfsub_f_size_read(file) <= PAGE_SIZE)
1facf9fc 34358+ goto out;
34359+
34360+ au_xino_lock_dir(sb, file, &ldir);
34361+ /* mnt_want_write() is unnecessary here */
34362+ file = au_xino_create2(sbinfo->si_xib, NULL);
34363+ au_xino_unlock_dir(&ldir);
34364+ err = PTR_ERR(file);
34365+ if (IS_ERR(file))
34366+ goto out;
34367+ fput(sbinfo->si_xib);
34368+ sbinfo->si_xib = file;
34369+
34370+ p = sbinfo->si_xib_buf;
34371+ memset(p, 0, PAGE_SIZE);
34372+ pos = 0;
34373+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos);
34374+ if (unlikely(sz != PAGE_SIZE)) {
34375+ err = sz;
34376+ AuIOErr("err %d\n", err);
34377+ if (sz >= 0)
34378+ err = -EIO;
34379+ goto out;
34380+ }
34381+
34382+ mutex_lock(&sbinfo->si_xib_mtx);
34383+ /* mnt_want_write() is unnecessary here */
34384+ err = xib_restore(sb);
34385+ mutex_unlock(&sbinfo->si_xib_mtx);
34386+
34387+out:
34388+ return err;
34389+}
34390+
34391+/* ---------------------------------------------------------------------- */
34392+
34393+/*
34394+ * xino mount option handlers
34395+ */
34396+static au_readf_t find_readf(struct file *h_file)
34397+{
34398+ const struct file_operations *fop = h_file->f_op;
34399+
523b37e3
AM
34400+ if (fop->read)
34401+ return fop->read;
34402+ if (fop->aio_read)
34403+ return do_sync_read;
076b876e
AM
34404+ if (fop->read_iter)
34405+ return new_sync_read;
1facf9fc 34406+ return ERR_PTR(-ENOSYS);
34407+}
34408+
34409+static au_writef_t find_writef(struct file *h_file)
34410+{
34411+ const struct file_operations *fop = h_file->f_op;
34412+
523b37e3
AM
34413+ if (fop->write)
34414+ return fop->write;
34415+ if (fop->aio_write)
34416+ return do_sync_write;
076b876e
AM
34417+ if (fop->write_iter)
34418+ return new_sync_write;
1facf9fc 34419+ return ERR_PTR(-ENOSYS);
34420+}
34421+
34422+/* xino bitmap */
34423+static void xino_clear_xib(struct super_block *sb)
34424+{
34425+ struct au_sbinfo *sbinfo;
34426+
dece6358
AM
34427+ SiMustWriteLock(sb);
34428+
1facf9fc 34429+ sbinfo = au_sbi(sb);
34430+ sbinfo->si_xread = NULL;
34431+ sbinfo->si_xwrite = NULL;
34432+ if (sbinfo->si_xib)
34433+ fput(sbinfo->si_xib);
34434+ sbinfo->si_xib = NULL;
34435+ free_page((unsigned long)sbinfo->si_xib_buf);
34436+ sbinfo->si_xib_buf = NULL;
34437+}
34438+
34439+static int au_xino_set_xib(struct super_block *sb, struct file *base)
34440+{
34441+ int err;
34442+ loff_t pos;
34443+ struct au_sbinfo *sbinfo;
34444+ struct file *file;
34445+
dece6358
AM
34446+ SiMustWriteLock(sb);
34447+
1facf9fc 34448+ sbinfo = au_sbi(sb);
34449+ file = au_xino_create2(base, sbinfo->si_xib);
34450+ err = PTR_ERR(file);
34451+ if (IS_ERR(file))
34452+ goto out;
34453+ if (sbinfo->si_xib)
34454+ fput(sbinfo->si_xib);
34455+ sbinfo->si_xib = file;
34456+ sbinfo->si_xread = find_readf(file);
34457+ sbinfo->si_xwrite = find_writef(file);
34458+
34459+ err = -ENOMEM;
34460+ if (!sbinfo->si_xib_buf)
34461+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS);
34462+ if (unlikely(!sbinfo->si_xib_buf))
34463+ goto out_unset;
34464+
34465+ sbinfo->si_xib_last_pindex = 0;
34466+ sbinfo->si_xib_next_bit = 0;
c06a8ce3 34467+ if (vfsub_f_size_read(file) < PAGE_SIZE) {
1facf9fc 34468+ pos = 0;
34469+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf,
34470+ PAGE_SIZE, &pos);
34471+ if (unlikely(err != PAGE_SIZE))
34472+ goto out_free;
34473+ }
34474+ err = 0;
34475+ goto out; /* success */
34476+
4f0767ce 34477+out_free:
1facf9fc 34478+ free_page((unsigned long)sbinfo->si_xib_buf);
b752ccd1
AM
34479+ sbinfo->si_xib_buf = NULL;
34480+ if (err >= 0)
34481+ err = -EIO;
4f0767ce 34482+out_unset:
b752ccd1
AM
34483+ fput(sbinfo->si_xib);
34484+ sbinfo->si_xib = NULL;
34485+ sbinfo->si_xread = NULL;
34486+ sbinfo->si_xwrite = NULL;
4f0767ce 34487+out:
b752ccd1 34488+ return err;
1facf9fc 34489+}
34490+
b752ccd1
AM
34491+/* xino for each branch */
34492+static void xino_clear_br(struct super_block *sb)
34493+{
34494+ aufs_bindex_t bindex, bend;
34495+ struct au_branch *br;
1facf9fc 34496+
b752ccd1
AM
34497+ bend = au_sbend(sb);
34498+ for (bindex = 0; bindex <= bend; bindex++) {
34499+ br = au_sbr(sb, bindex);
34500+ if (!br || !br->br_xino.xi_file)
34501+ continue;
34502+
34503+ fput(br->br_xino.xi_file);
34504+ br->br_xino.xi_file = NULL;
34505+ }
34506+}
34507+
34508+static int au_xino_set_br(struct super_block *sb, struct file *base)
1facf9fc 34509+{
34510+ int err;
b752ccd1
AM
34511+ ino_t ino;
34512+ aufs_bindex_t bindex, bend, bshared;
34513+ struct {
34514+ struct file *old, *new;
34515+ } *fpair, *p;
34516+ struct au_branch *br;
34517+ struct inode *inode;
34518+ au_writef_t writef;
1facf9fc 34519+
b752ccd1
AM
34520+ SiMustWriteLock(sb);
34521+
34522+ err = -ENOMEM;
34523+ bend = au_sbend(sb);
34524+ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS);
34525+ if (unlikely(!fpair))
1facf9fc 34526+ goto out;
34527+
b752ccd1
AM
34528+ inode = sb->s_root->d_inode;
34529+ ino = AUFS_ROOT_INO;
34530+ writef = au_sbi(sb)->si_xwrite;
34531+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
34532+ br = au_sbr(sb, bindex);
34533+ bshared = is_sb_shared(sb, bindex, bindex - 1);
34534+ if (bshared >= 0) {
34535+ /* shared xino */
34536+ *p = fpair[bshared];
34537+ get_file(p->new);
34538+ }
34539+
34540+ if (!p->new) {
34541+ /* new xino */
34542+ p->old = br->br_xino.xi_file;
34543+ p->new = au_xino_create2(base, br->br_xino.xi_file);
34544+ err = PTR_ERR(p->new);
34545+ if (IS_ERR(p->new)) {
34546+ p->new = NULL;
34547+ goto out_pair;
34548+ }
34549+ }
34550+
34551+ err = au_xino_do_write(writef, p->new,
34552+ au_h_iptr(inode, bindex)->i_ino, ino);
34553+ if (unlikely(err))
34554+ goto out_pair;
34555+ }
34556+
34557+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) {
34558+ br = au_sbr(sb, bindex);
34559+ if (br->br_xino.xi_file)
34560+ fput(br->br_xino.xi_file);
34561+ get_file(p->new);
34562+ br->br_xino.xi_file = p->new;
34563+ }
1facf9fc 34564+
4f0767ce 34565+out_pair:
b752ccd1
AM
34566+ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++)
34567+ if (p->new)
34568+ fput(p->new);
34569+ else
34570+ break;
34571+ kfree(fpair);
4f0767ce 34572+out:
1facf9fc 34573+ return err;
34574+}
b752ccd1
AM
34575+
34576+void au_xino_clr(struct super_block *sb)
34577+{
34578+ struct au_sbinfo *sbinfo;
34579+
34580+ au_xigen_clr(sb);
34581+ xino_clear_xib(sb);
34582+ xino_clear_br(sb);
34583+ sbinfo = au_sbi(sb);
34584+ /* lvalue, do not call au_mntflags() */
34585+ au_opt_clr(sbinfo->si_mntflags, XINO);
34586+}
34587+
34588+int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount)
34589+{
34590+ int err, skip;
34591+ struct dentry *parent, *cur_parent;
34592+ struct qstr *dname, *cur_name;
34593+ struct file *cur_xino;
34594+ struct inode *dir;
34595+ struct au_sbinfo *sbinfo;
34596+
34597+ SiMustWriteLock(sb);
34598+
34599+ err = 0;
34600+ sbinfo = au_sbi(sb);
34601+ parent = dget_parent(xino->file->f_dentry);
34602+ if (remount) {
34603+ skip = 0;
34604+ dname = &xino->file->f_dentry->d_name;
34605+ cur_xino = sbinfo->si_xib;
34606+ if (cur_xino) {
34607+ cur_parent = dget_parent(cur_xino->f_dentry);
34608+ cur_name = &cur_xino->f_dentry->d_name;
34609+ skip = (cur_parent == parent
38d290e6 34610+ && au_qstreq(dname, cur_name));
b752ccd1
AM
34611+ dput(cur_parent);
34612+ }
34613+ if (skip)
34614+ goto out;
34615+ }
34616+
34617+ au_opt_set(sbinfo->si_mntflags, XINO);
34618+ dir = parent->d_inode;
34619+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT);
34620+ /* mnt_want_write() is unnecessary here */
34621+ err = au_xino_set_xib(sb, xino->file);
34622+ if (!err)
34623+ err = au_xigen_set(sb, xino->file);
34624+ if (!err)
34625+ err = au_xino_set_br(sb, xino->file);
34626+ mutex_unlock(&dir->i_mutex);
34627+ if (!err)
34628+ goto out; /* success */
34629+
34630+ /* reset all */
34631+ AuIOErr("failed creating xino(%d).\n", err);
c1595e42
JR
34632+ au_xigen_clr(sb);
34633+ xino_clear_xib(sb);
b752ccd1 34634+
4f0767ce 34635+out:
b752ccd1
AM
34636+ dput(parent);
34637+ return err;
34638+}
34639+
34640+/* ---------------------------------------------------------------------- */
34641+
34642+/*
34643+ * create a xinofile at the default place/path.
34644+ */
34645+struct file *au_xino_def(struct super_block *sb)
34646+{
34647+ struct file *file;
34648+ char *page, *p;
34649+ struct au_branch *br;
34650+ struct super_block *h_sb;
34651+ struct path path;
34652+ aufs_bindex_t bend, bindex, bwr;
34653+
34654+ br = NULL;
34655+ bend = au_sbend(sb);
34656+ bwr = -1;
34657+ for (bindex = 0; bindex <= bend; bindex++) {
34658+ br = au_sbr(sb, bindex);
34659+ if (au_br_writable(br->br_perm)
86dc4139 34660+ && !au_test_fs_bad_xino(au_br_sb(br))) {
b752ccd1
AM
34661+ bwr = bindex;
34662+ break;
34663+ }
34664+ }
34665+
7f207e10
AM
34666+ if (bwr >= 0) {
34667+ file = ERR_PTR(-ENOMEM);
537831f9 34668+ page = (void *)__get_free_page(GFP_NOFS);
7f207e10
AM
34669+ if (unlikely(!page))
34670+ goto out;
86dc4139 34671+ path.mnt = au_br_mnt(br);
7f207e10
AM
34672+ path.dentry = au_h_dptr(sb->s_root, bwr);
34673+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME));
34674+ file = (void *)p;
34675+ if (!IS_ERR(p)) {
34676+ strcat(p, "/" AUFS_XINO_FNAME);
34677+ AuDbg("%s\n", p);
34678+ file = au_xino_create(sb, p, /*silent*/0);
34679+ if (!IS_ERR(file))
34680+ au_xino_brid_set(sb, br->br_id);
34681+ }
537831f9 34682+ free_page((unsigned long)page);
7f207e10
AM
34683+ } else {
34684+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
34685+ if (IS_ERR(file))
34686+ goto out;
34687+ h_sb = file->f_dentry->d_sb;
34688+ if (unlikely(au_test_fs_bad_xino(h_sb))) {
34689+ pr_err("xino doesn't support %s(%s)\n",
34690+ AUFS_XINO_DEFPATH, au_sbtype(h_sb));
34691+ fput(file);
34692+ file = ERR_PTR(-EINVAL);
34693+ }
34694+ if (!IS_ERR(file))
34695+ au_xino_brid_set(sb, -1);
34696+ }
0c5527e5 34697+
7f207e10
AM
34698+out:
34699+ return file;
34700+}
34701+
34702+/* ---------------------------------------------------------------------- */
34703+
34704+int au_xino_path(struct seq_file *seq, struct file *file)
34705+{
34706+ int err;
34707+
34708+ err = au_seq_path(seq, &file->f_path);
34709+ if (unlikely(err < 0))
34710+ goto out;
34711+
34712+ err = 0;
34713+#define Deleted "\\040(deleted)"
34714+ seq->count -= sizeof(Deleted) - 1;
34715+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted,
34716+ sizeof(Deleted) - 1));
34717+#undef Deleted
34718+
34719+out:
34720+ return err;
34721+}
537831f9
AM
34722diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h
34723--- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100
c1595e42
JR
34724+++ linux/include/uapi/linux/aufs_type.h 2015-01-25 13:00:38.637713742 +0100
34725@@ -0,0 +1,419 @@
7f207e10 34726+/*
523b37e3 34727+ * Copyright (C) 2005-2014 Junjiro R. Okajima
7f207e10
AM
34728+ *
34729+ * This program, aufs is free software; you can redistribute it and/or modify
34730+ * it under the terms of the GNU General Public License as published by
34731+ * the Free Software Foundation; either version 2 of the License, or
34732+ * (at your option) any later version.
34733+ *
34734+ * This program is distributed in the hope that it will be useful,
34735+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
34736+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34737+ * GNU General Public License for more details.
34738+ *
34739+ * You should have received a copy of the GNU General Public License
523b37e3 34740+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
7f207e10
AM
34741+ */
34742+
34743+#ifndef __AUFS_TYPE_H__
34744+#define __AUFS_TYPE_H__
34745+
f6c5ef8b
AM
34746+#define AUFS_NAME "aufs"
34747+
9dbd164d 34748+#ifdef __KERNEL__
f6c5ef8b
AM
34749+/*
34750+ * define it before including all other headers.
34751+ * sched.h may use pr_* macros before defining "current", so define the
34752+ * no-current version first, and re-define later.
34753+ */
34754+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__
34755+#include <linux/sched.h>
34756+#undef pr_fmt
a2a7ad62
AM
34757+#define pr_fmt(fmt) \
34758+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \
34759+ (int)sizeof(current->comm), current->comm, current->pid
9dbd164d
AM
34760+#else
34761+#include <stdint.h>
34762+#include <sys/types.h>
f6c5ef8b 34763+#endif /* __KERNEL__ */
7f207e10 34764+
f6c5ef8b
AM
34765+#include <linux/limits.h>
34766+
c1595e42 34767+#define AUFS_VERSION "3.18.1+-20150119"
7f207e10
AM
34768+
34769+/* todo? move this to linux-2.6.19/include/magic.h */
34770+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
34771+
34772+/* ---------------------------------------------------------------------- */
34773+
34774+#ifdef CONFIG_AUFS_BRANCH_MAX_127
9dbd164d 34775+typedef int8_t aufs_bindex_t;
7f207e10
AM
34776+#define AUFS_BRANCH_MAX 127
34777+#else
9dbd164d 34778+typedef int16_t aufs_bindex_t;
7f207e10
AM
34779+#ifdef CONFIG_AUFS_BRANCH_MAX_511
34780+#define AUFS_BRANCH_MAX 511
34781+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023)
34782+#define AUFS_BRANCH_MAX 1023
34783+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767)
34784+#define AUFS_BRANCH_MAX 32767
34785+#endif
34786+#endif
34787+
34788+#ifdef __KERNEL__
34789+#ifndef AUFS_BRANCH_MAX
34790+#error unknown CONFIG_AUFS_BRANCH_MAX value
34791+#endif
34792+#endif /* __KERNEL__ */
34793+
34794+/* ---------------------------------------------------------------------- */
34795+
7f207e10
AM
34796+#define AUFS_FSTYPE AUFS_NAME
34797+
34798+#define AUFS_ROOT_INO 2
34799+#define AUFS_FIRST_INO 11
34800+
34801+#define AUFS_WH_PFX ".wh."
34802+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1)
34803+#define AUFS_WH_TMP_LEN 4
86dc4139 34804+/* a limit for rmdir/rename a dir and copyup */
7f207e10
AM
34805+#define AUFS_MAX_NAMELEN (NAME_MAX \
34806+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\
34807+ - 1 /* dot */\
34808+ - AUFS_WH_TMP_LEN) /* hex */
34809+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino"
34810+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME
392086de
AM
34811+#define AUFS_XINO_DEF_SEC 30 /* seconds */
34812+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */
7f207e10
AM
34813+#define AUFS_DIRWH_DEF 3
34814+#define AUFS_RDCACHE_DEF 10 /* seconds */
027c5e7a 34815+#define AUFS_RDCACHE_MAX 3600 /* seconds */
7f207e10
AM
34816+#define AUFS_RDBLK_DEF 512 /* bytes */
34817+#define AUFS_RDHASH_DEF 32
34818+#define AUFS_WKQ_NAME AUFS_NAME "d"
027c5e7a
AM
34819+#define AUFS_MFS_DEF_SEC 30 /* seconds */
34820+#define AUFS_MFS_MAX_SEC 3600 /* seconds */
076b876e 34821+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */
86dc4139 34822+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */
7f207e10
AM
34823+
34824+/* pseudo-link maintenace under /proc */
34825+#define AUFS_PLINK_MAINT_NAME "plink_maint"
34826+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME
34827+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME
34828+
34829+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */
34830+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME
34831+
34832+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME
34833+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk"
34834+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph"
34835+
34836+/* doubly whiteouted */
34837+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME
34838+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME
34839+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME
34840+
1e00d052 34841+/* branch permissions and attributes */
7f207e10
AM
34842+#define AUFS_BRPERM_RW "rw"
34843+#define AUFS_BRPERM_RO "ro"
34844+#define AUFS_BRPERM_RR "rr"
076b876e
AM
34845+#define AUFS_BRATTR_COO_REG "coo_reg"
34846+#define AUFS_BRATTR_COO_ALL "coo_all"
34847+#define AUFS_BRATTR_FHSM "fhsm"
34848+#define AUFS_BRATTR_UNPIN "unpin"
c1595e42
JR
34849+#define AUFS_BRATTR_ICEX "icex"
34850+#define AUFS_BRATTR_ICEX_SEC "icexsec"
34851+#define AUFS_BRATTR_ICEX_SYS "icexsys"
34852+#define AUFS_BRATTR_ICEX_TR "icextr"
34853+#define AUFS_BRATTR_ICEX_USR "icexusr"
34854+#define AUFS_BRATTR_ICEX_OTH "icexoth"
1e00d052
AM
34855+#define AUFS_BRRATTR_WH "wh"
34856+#define AUFS_BRWATTR_NLWH "nolwh"
076b876e
AM
34857+#define AUFS_BRWATTR_MOO "moo"
34858+
34859+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */
34860+#define AuBrPerm_RO (1 << 1) /* readonly */
34861+#define AuBrPerm_RR (1 << 2) /* natively readonly */
34862+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR)
34863+
34864+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */
34865+#define AuBrAttr_COO_ALL (1 << 4)
34866+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL)
34867+
34868+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */
34869+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of
c1595e42
JR
34870+ branch. meaningless since
34871+ linux-3.18-rc1 */
34872+
34873+/* ignore error in copying XATTR */
34874+#define AuBrAttr_ICEX_SEC (1 << 7)
34875+#define AuBrAttr_ICEX_SYS (1 << 8)
34876+#define AuBrAttr_ICEX_TR (1 << 9)
34877+#define AuBrAttr_ICEX_USR (1 << 10)
34878+#define AuBrAttr_ICEX_OTH (1 << 11)
34879+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \
34880+ | AuBrAttr_ICEX_SYS \
34881+ | AuBrAttr_ICEX_TR \
34882+ | AuBrAttr_ICEX_USR \
34883+ | AuBrAttr_ICEX_OTH)
34884+
34885+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */
076b876e
AM
34886+#define AuBrRAttr_Mask AuBrRAttr_WH
34887+
c1595e42
JR
34888+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */
34889+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */
076b876e
AM
34890+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO)
34891+
34892+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO)
34893+
c1595e42 34894+/* #warning test userspace */
076b876e
AM
34895+#ifdef __KERNEL__
34896+#ifndef CONFIG_AUFS_FHSM
34897+#undef AuBrAttr_FHSM
34898+#define AuBrAttr_FHSM 0
34899+#endif
c1595e42
JR
34900+#ifndef CONFIG_AUFS_XATTR
34901+#undef AuBrAttr_ICEX
34902+#define AuBrAttr_ICEX 0
34903+#undef AuBrAttr_ICEX_SEC
34904+#define AuBrAttr_ICEX_SEC 0
34905+#undef AuBrAttr_ICEX_SYS
34906+#define AuBrAttr_ICEX_SYS 0
34907+#undef AuBrAttr_ICEX_TR
34908+#define AuBrAttr_ICEX_TR 0
34909+#undef AuBrAttr_ICEX_USR
34910+#define AuBrAttr_ICEX_USR 0
34911+#undef AuBrAttr_ICEX_OTH
34912+#define AuBrAttr_ICEX_OTH 0
34913+#endif
076b876e
AM
34914+#endif
34915+
34916+/* the longest combination */
c1595e42
JR
34917+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */
34918+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \
34919+ "+" AUFS_BRATTR_COO_REG \
34920+ "+" AUFS_BRATTR_FHSM \
34921+ "+" AUFS_BRATTR_UNPIN \
34922+ "+" AUFS_BRATTR_ICEX_SEC \
34923+ "+" AUFS_BRATTR_ICEX_SYS \
34924+ "+" AUFS_BRATTR_ICEX_USR \
34925+ "+" AUFS_BRATTR_ICEX_OTH \
076b876e
AM
34926+ "+" AUFS_BRWATTR_NLWH)
34927+
34928+typedef struct {
34929+ char a[AuBrPermStrSz];
34930+} au_br_perm_str_t;
34931+
34932+static inline int au_br_writable(int brperm)
34933+{
34934+ return brperm & AuBrPerm_RW;
34935+}
34936+
34937+static inline int au_br_whable(int brperm)
34938+{
34939+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH);
34940+}
34941+
34942+static inline int au_br_wh_linkable(int brperm)
34943+{
34944+ return !(brperm & AuBrWAttr_NoLinkWH);
34945+}
34946+
34947+static inline int au_br_cmoo(int brperm)
34948+{
34949+ return brperm & AuBrAttr_CMOO_Mask;
34950+}
34951+
34952+static inline int au_br_fhsm(int brperm)
34953+{
34954+ return brperm & AuBrAttr_FHSM;
34955+}
7f207e10
AM
34956+
34957+/* ---------------------------------------------------------------------- */
34958+
34959+/* ioctl */
34960+enum {
34961+ /* readdir in userspace */
34962+ AuCtl_RDU,
34963+ AuCtl_RDU_INO,
34964+
076b876e
AM
34965+ AuCtl_WBR_FD, /* pathconf wrapper */
34966+ AuCtl_IBUSY, /* busy inode */
34967+ AuCtl_MVDOWN, /* move-down */
34968+ AuCtl_BR, /* info about branches */
34969+ AuCtl_FHSM_FD /* connection for fhsm */
7f207e10
AM
34970+};
34971+
34972+/* borrowed from linux/include/linux/kernel.h */
34973+#ifndef ALIGN
34974+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1)
34975+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
34976+#endif
34977+
34978+/* borrowed from linux/include/linux/compiler-gcc3.h */
34979+#ifndef __aligned
34980+#define __aligned(x) __attribute__((aligned(x)))
53392da6
AM
34981+#endif
34982+
34983+#ifdef __KERNEL__
34984+#ifndef __packed
7f207e10
AM
34985+#define __packed __attribute__((packed))
34986+#endif
53392da6 34987+#endif
7f207e10
AM
34988+
34989+struct au_rdu_cookie {
9dbd164d
AM
34990+ uint64_t h_pos;
34991+ int16_t bindex;
34992+ uint8_t flags;
34993+ uint8_t pad;
34994+ uint32_t generation;
7f207e10
AM
34995+} __aligned(8);
34996+
34997+struct au_rdu_ent {
9dbd164d
AM
34998+ uint64_t ino;
34999+ int16_t bindex;
35000+ uint8_t type;
35001+ uint8_t nlen;
35002+ uint8_t wh;
7f207e10
AM
35003+ char name[0];
35004+} __aligned(8);
35005+
35006+static inline int au_rdu_len(int nlen)
35007+{
35008+ /* include the terminating NULL */
35009+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1,
9dbd164d 35010+ sizeof(uint64_t));
7f207e10
AM
35011+}
35012+
35013+union au_rdu_ent_ul {
35014+ struct au_rdu_ent __user *e;
9dbd164d 35015+ uint64_t ul;
7f207e10
AM
35016+};
35017+
35018+enum {
35019+ AufsCtlRduV_SZ,
35020+ AufsCtlRduV_End
35021+};
35022+
35023+struct aufs_rdu {
35024+ /* input */
35025+ union {
9dbd164d
AM
35026+ uint64_t sz; /* AuCtl_RDU */
35027+ uint64_t nent; /* AuCtl_RDU_INO */
7f207e10
AM
35028+ };
35029+ union au_rdu_ent_ul ent;
9dbd164d 35030+ uint16_t verify[AufsCtlRduV_End];
7f207e10
AM
35031+
35032+ /* input/output */
9dbd164d 35033+ uint32_t blk;
7f207e10
AM
35034+
35035+ /* output */
35036+ union au_rdu_ent_ul tail;
35037+ /* number of entries which were added in a single call */
9dbd164d
AM
35038+ uint64_t rent;
35039+ uint8_t full;
35040+ uint8_t shwh;
7f207e10
AM
35041+
35042+ struct au_rdu_cookie cookie;
35043+} __aligned(8);
35044+
1e00d052
AM
35045+/* ---------------------------------------------------------------------- */
35046+
35047+struct aufs_wbr_fd {
9dbd164d
AM
35048+ uint32_t oflags;
35049+ int16_t brid;
1e00d052
AM
35050+} __aligned(8);
35051+
35052+/* ---------------------------------------------------------------------- */
35053+
027c5e7a 35054+struct aufs_ibusy {
9dbd164d
AM
35055+ uint64_t ino, h_ino;
35056+ int16_t bindex;
027c5e7a
AM
35057+} __aligned(8);
35058+
1e00d052
AM
35059+/* ---------------------------------------------------------------------- */
35060+
392086de
AM
35061+/* error code for move-down */
35062+/* the actual message strings are implemented in aufs-util.git */
35063+enum {
35064+ EAU_MVDOWN_OPAQUE = 1,
35065+ EAU_MVDOWN_WHITEOUT,
35066+ EAU_MVDOWN_UPPER,
35067+ EAU_MVDOWN_BOTTOM,
35068+ EAU_MVDOWN_NOUPPER,
35069+ EAU_MVDOWN_NOLOWERBR,
35070+ EAU_Last
35071+};
35072+
c2b27bf2 35073+/* flags for move-down */
392086de
AM
35074+#define AUFS_MVDOWN_DMSG 1
35075+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */
35076+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */
35077+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */
35078+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */
35079+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */
35080+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */
35081+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */
35082+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */
076b876e
AM
35083+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */
35084+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */
35085+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */
35086+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */
c2b27bf2 35087+
076b876e 35088+/* index for move-down */
392086de
AM
35089+enum {
35090+ AUFS_MVDOWN_UPPER,
35091+ AUFS_MVDOWN_LOWER,
35092+ AUFS_MVDOWN_NARRAY
35093+};
35094+
076b876e
AM
35095+/*
35096+ * additional info of move-down
35097+ * number of free blocks and inodes.
35098+ * subset of struct kstatfs, but smaller and always 64bit.
35099+ */
35100+struct aufs_stfs {
35101+ uint64_t f_blocks;
35102+ uint64_t f_bavail;
35103+ uint64_t f_files;
35104+ uint64_t f_ffree;
35105+};
35106+
35107+struct aufs_stbr {
35108+ int16_t brid; /* optional input */
35109+ int16_t bindex; /* output */
35110+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */
35111+} __aligned(8);
35112+
c2b27bf2 35113+struct aufs_mvdown {
076b876e
AM
35114+ uint32_t flags; /* input/output */
35115+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */
35116+ int8_t au_errno; /* output */
35117+} __aligned(8);
35118+
35119+/* ---------------------------------------------------------------------- */
35120+
35121+union aufs_brinfo {
35122+ /* PATH_MAX may differ between kernel-space and user-space */
35123+ char _spacer[4096];
392086de 35124+ struct {
076b876e
AM
35125+ int16_t id;
35126+ int perm;
35127+ char path[0];
35128+ };
c2b27bf2
AM
35129+} __aligned(8);
35130+
35131+/* ---------------------------------------------------------------------- */
35132+
7f207e10
AM
35133+#define AuCtlType 'A'
35134+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu)
35135+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu)
1e00d052
AM
35136+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
35137+ struct aufs_wbr_fd)
027c5e7a 35138+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
392086de
AM
35139+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
35140+ struct aufs_mvdown)
076b876e
AM
35141+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
35142+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int)
7f207e10
AM
35143+
35144+#endif /* __AUFS_TYPE_H__ */
c1595e42 35145aufs3.18.1+ loopback patch
93a1a2a2
JR
35146
35147diff --git a/drivers/block/loop.c b/drivers/block/loop.c
076b876e 35148index 30efd68..77b31b4 100644
93a1a2a2
JR
35149--- a/drivers/block/loop.c
35150+++ b/drivers/block/loop.c
35151@@ -514,7 +514,7 @@ out:
35152 }
35153
35154 struct switch_request {
35155- struct file *file;
35156+ struct file *file, *virt_file;
35157 struct completion wait;
35158 };
35159
35160@@ -576,7 +576,8 @@ static int loop_thread(void *data)
35161 * First it needs to flush existing IO, it does this by sending a magic
35162 * BIO down the pipe. The completion of this BIO does the actual switch.
35163 */
35164-static int loop_switch(struct loop_device *lo, struct file *file)
35165+static int loop_switch(struct loop_device *lo, struct file *file,
35166+ struct file *virt_file)
35167 {
35168 struct switch_request w;
35169 struct bio *bio = bio_alloc(GFP_KERNEL, 0);
35170@@ -584,6 +585,7 @@ static int loop_switch(struct loop_device *lo, struct file *file)
35171 return -ENOMEM;
35172 init_completion(&w.wait);
35173 w.file = file;
35174+ w.virt_file = virt_file;
35175 bio->bi_private = &w;
35176 bio->bi_bdev = NULL;
35177 loop_make_request(lo->lo_queue, bio);
35178@@ -600,7 +602,7 @@ static int loop_flush(struct loop_device *lo)
35179 if (!lo->lo_thread)
35180 return 0;
35181
35182- return loop_switch(lo, NULL);
35183+ return loop_switch(lo, NULL, NULL);
35184 }
35185
35186 /*
35187@@ -619,6 +621,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p)
35188 mapping = file->f_mapping;
35189 mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);
35190 lo->lo_backing_file = file;
35191+ lo->lo_backing_virt_file = p->virt_file;
35192 lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?
35193 mapping->host->i_bdev->bd_block_size : PAGE_SIZE;
35194 lo->old_gfp_mask = mapping_gfp_mask(mapping);
35195@@ -627,6 +630,13 @@ out:
35196 complete(&p->wait);
35197 }
35198
35199+static struct file *loop_real_file(struct file *file)
35200+{
35201+ struct file *f = NULL;
35202+ if (file->f_dentry->d_sb->s_op->real_loop)
35203+ f = file->f_dentry->d_sb->s_op->real_loop(file);
35204+ return f;
35205+}
35206
35207 /*
35208 * loop_change_fd switched the backing store of a loopback device to
35209@@ -640,6 +650,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
35210 unsigned int arg)
35211 {
35212 struct file *file, *old_file;
35213+ struct file *f, *virt_file = NULL, *old_virt_file;
35214 struct inode *inode;
35215 int error;
35216
35217@@ -656,9 +667,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
35218 file = fget(arg);
35219 if (!file)
35220 goto out;
35221+ f = loop_real_file(file);
35222+ if (f) {
35223+ virt_file = file;
35224+ file = f;
35225+ get_file(file);
35226+ }
35227
35228 inode = file->f_mapping->host;
35229 old_file = lo->lo_backing_file;
35230+ old_virt_file = lo->lo_backing_virt_file;
35231
35232 error = -EINVAL;
35233
35234@@ -670,17 +688,21 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
35235 goto out_putf;
35236
35237 /* and ... switch */
35238- error = loop_switch(lo, file);
35239+ error = loop_switch(lo, file, virt_file);
35240 if (error)
35241 goto out_putf;
35242
35243 fput(old_file);
35244+ if (old_virt_file)
35245+ fput(old_virt_file);
35246 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
35247 ioctl_by_bdev(bdev, BLKRRPART, 0);
35248 return 0;
35249
35250 out_putf:
35251 fput(file);
35252+ if (virt_file)
35253+ fput(virt_file);
35254 out:
35255 return error;
35256 }
35257@@ -841,7 +863,7 @@ static void loop_config_discard(struct loop_device *lo)
35258 static int loop_set_fd(struct loop_device *lo, fmode_t mode,
35259 struct block_device *bdev, unsigned int arg)
35260 {
35261- struct file *file, *f;
35262+ struct file *file, *f, *virt_file = NULL;
35263 struct inode *inode;
35264 struct address_space *mapping;
35265 unsigned lo_blocksize;
35266@@ -856,6 +878,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
35267 file = fget(arg);
35268 if (!file)
35269 goto out;
35270+ f = loop_real_file(file);
35271+ if (f) {
35272+ virt_file = file;
35273+ file = f;
35274+ get_file(file);
35275+ }
35276
35277 error = -EBUSY;
35278 if (lo->lo_state != Lo_unbound)
35279@@ -904,6 +932,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
35280 lo->lo_device = bdev;
35281 lo->lo_flags = lo_flags;
35282 lo->lo_backing_file = file;
35283+ lo->lo_backing_virt_file = virt_file;
35284 lo->transfer = transfer_none;
35285 lo->ioctl = NULL;
35286 lo->lo_sizelimit = 0;
35287@@ -948,6 +977,7 @@ out_clr:
35288 lo->lo_thread = NULL;
35289 lo->lo_device = NULL;
35290 lo->lo_backing_file = NULL;
35291+ lo->lo_backing_virt_file = NULL;
35292 lo->lo_flags = 0;
35293 set_capacity(lo->lo_disk, 0);
35294 invalidate_bdev(bdev);
35295@@ -957,6 +987,8 @@ out_clr:
35296 lo->lo_state = Lo_unbound;
35297 out_putf:
35298 fput(file);
35299+ if (virt_file)
35300+ fput(virt_file);
35301 out:
35302 /* This is safe: open() is still holding a reference. */
35303 module_put(THIS_MODULE);
35304@@ -1003,6 +1035,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
35305 static int loop_clr_fd(struct loop_device *lo)
35306 {
35307 struct file *filp = lo->lo_backing_file;
35308+ struct file *virt_filp = lo->lo_backing_virt_file;
35309 gfp_t gfp = lo->old_gfp_mask;
35310 struct block_device *bdev = lo->lo_device;
35311
35312@@ -1036,6 +1069,7 @@ static int loop_clr_fd(struct loop_device *lo)
35313
35314 spin_lock_irq(&lo->lo_lock);
35315 lo->lo_backing_file = NULL;
35316+ lo->lo_backing_virt_file = NULL;
35317 spin_unlock_irq(&lo->lo_lock);
35318
35319 loop_release_xfer(lo);
35320@@ -1078,6 +1112,8 @@ static int loop_clr_fd(struct loop_device *lo)
35321 * bd_mutex which is usually taken before lo_ctl_mutex.
35322 */
35323 fput(filp);
35324+ if (virt_filp)
35325+ fput(virt_filp);
35326 return 0;
35327 }
35328
35329diff --git a/drivers/block/loop.h b/drivers/block/loop.h
35330index 90df5d6..cb91822 100644
35331--- a/drivers/block/loop.h
35332+++ b/drivers/block/loop.h
35333@@ -44,7 +44,7 @@ struct loop_device {
35334 int (*ioctl)(struct loop_device *, int cmd,
35335 unsigned long arg);
35336
35337- struct file * lo_backing_file;
35338+ struct file * lo_backing_file, *lo_backing_virt_file;
35339 struct block_device *lo_device;
35340 unsigned lo_blocksize;
35341 void *key_data;
35342diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
c1595e42 35343index 3dd9138..63a424c 100644
93a1a2a2
JR
35344--- a/fs/aufs/f_op.c
35345+++ b/fs/aufs/f_op.c
076b876e 35346@@ -367,7 +367,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
93a1a2a2
JR
35347 err = -EINVAL;
35348 h_file = au_hf_top(file);
35349 get_file(h_file);
35350- if (au_test_loopback_kthread()) {
35351+ if (0 && au_test_loopback_kthread()) {
35352 au_warn_loopback(h_file->f_dentry->d_sb);
35353 if (file->f_mapping != h_file->f_mapping) {
35354 file->f_mapping = h_file->f_mapping;
35355diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c
35356index 3b03b52..4ab749d 100644
35357--- a/fs/aufs/loop.c
35358+++ b/fs/aufs/loop.c
35359@@ -130,3 +130,19 @@ void au_loopback_fin(void)
35360 symbol_put(loop_backing_file);
35361 kfree(au_warn_loopback_array);
35362 }
35363+
35364+/* ---------------------------------------------------------------------- */
35365+
35366+/* support the loopback block device insude aufs */
35367+
35368+struct file *aufs_real_loop(struct file *file)
35369+{
35370+ struct file *f;
35371+
35372+ BUG_ON(!au_test_aufs(file->f_dentry->d_sb));
35373+ fi_read_lock(file);
35374+ f = au_hf_top(file);
35375+ fi_read_unlock(file);
35376+ AuDebugOn(!f);
35377+ return f;
35378+}
35379diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h
35380index da8b756..28cb7ea 100644
35381--- a/fs/aufs/loop.h
35382+++ b/fs/aufs/loop.h
35383@@ -25,7 +25,11 @@ void au_warn_loopback(struct super_block *h_sb);
35384
35385 int au_loopback_init(void);
35386 void au_loopback_fin(void);
35387+
35388+struct file *aufs_real_loop(struct file *file);
35389 #else
35390+AuStub(struct file *, loop_backing_file, return NULL)
35391+
35392 AuStubInt0(au_test_loopback_overlap, struct super_block *sb,
35393 struct dentry *h_adding)
35394 AuStubInt0(au_test_loopback_kthread, void)
35395@@ -33,6 +37,8 @@ AuStubVoid(au_warn_loopback, struct super_block *h_sb)
35396
35397 AuStubInt0(au_loopback_init, void)
35398 AuStubVoid(au_loopback_fin, void)
35399+
35400+AuStub(struct file *, aufs_real_loop, return NULL, struct file *file)
35401 #endif /* BLK_DEV_LOOP */
35402
35403 #endif /* __KERNEL__ */
35404diff --git a/fs/aufs/super.c b/fs/aufs/super.c
c1595e42 35405index 2ec0b4f..65a6781 100644
93a1a2a2
JR
35406--- a/fs/aufs/super.c
35407+++ b/fs/aufs/super.c
c1595e42 35408@@ -812,7 +812,10 @@ static const struct super_operations aufs_sop = {
93a1a2a2
JR
35409 .statfs = aufs_statfs,
35410 .put_super = aufs_put_super,
35411 .sync_fs = aufs_sync_fs,
35412- .remount_fs = aufs_remount_fs
35413+ .remount_fs = aufs_remount_fs,
35414+#ifdef CONFIG_AUFS_BDEV_LOOP
35415+ .real_loop = aufs_real_loop
35416+#endif
35417 };
35418
35419 /* ---------------------------------------------------------------------- */
35420diff --git a/include/linux/fs.h b/include/linux/fs.h
c1595e42 35421index aabcbba..1a634f5 100644
93a1a2a2
JR
35422--- a/include/linux/fs.h
35423+++ b/include/linux/fs.h
c1595e42 35424@@ -1594,6 +1594,10 @@ struct super_operations {
93a1a2a2
JR
35425 int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
35426 long (*nr_cached_objects)(struct super_block *, int);
35427 long (*free_cached_objects)(struct super_block *, long, int);
35428+#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE)
35429+ /* and aufs */
35430+ struct file *(*real_loop)(struct file *);
35431+#endif
35432 };
35433
35434 /*
c1595e42
JR
35435diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
35436index 50777b5..f9c6b3d 100644
35437--- a/include/linux/shmem_fs.h
35438+++ b/include/linux/shmem_fs.h
35439@@ -26,10 +26,13 @@ struct shmem_inode_info {
35440 };
35441
35442 struct shmem_sb_info {
35443+ struct mutex idr_lock;
35444+ bool idr_nouse;
35445+ struct idr idr; /* manages inode-number */
35446 unsigned long max_blocks; /* How many blocks are allowed */
35447 struct percpu_counter used_blocks; /* How many are allocated */
35448- unsigned long max_inodes; /* How many inodes are allowed */
35449- unsigned long free_inodes; /* How many are left for allocation */
35450+ int max_inodes; /* How many inodes are allowed */
35451+ int free_inodes; /* How many are left for allocation */
35452 spinlock_t stat_lock; /* Serialize shmem_sb_info changes */
35453 kuid_t uid; /* Mount uid for root directory */
35454 kgid_t gid; /* Mount gid for root directory */
35455diff --git a/mm/shmem.c b/mm/shmem.c
35456index 185836b..ac7f9fb 100644
35457--- a/mm/shmem.c
35458+++ b/mm/shmem.c
35459@@ -110,9 +110,13 @@ static unsigned long shmem_default_max_blocks(void)
35460 return totalram_pages / 2;
35461 }
35462
35463-static unsigned long shmem_default_max_inodes(void)
35464+static int shmem_default_max_inodes(void)
35465 {
35466- return min(totalram_pages - totalhigh_pages, totalram_pages / 2);
35467+ unsigned long ul;
35468+
35469+ ul = INT_MAX;
35470+ ul = min3(ul, totalram_pages - totalhigh_pages, totalram_pages / 2);
35471+ return ul;
35472 }
35473 #endif
35474
35475@@ -592,6 +596,7 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
35476 static void shmem_evict_inode(struct inode *inode)
35477 {
35478 struct shmem_inode_info *info = SHMEM_I(inode);
35479+ struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
35480
35481 if (inode->i_mapping->a_ops == &shmem_aops) {
35482 shmem_unacct_size(info->flags, inode->i_size);
35483@@ -607,6 +612,11 @@ static void shmem_evict_inode(struct inode *inode)
35484
35485 simple_xattrs_free(&info->xattrs);
35486 WARN_ON(inode->i_blocks);
35487+ if (!sbinfo->idr_nouse && inode->i_ino) {
35488+ mutex_lock(&sbinfo->idr_lock);
35489+ idr_remove(&sbinfo->idr, inode->i_ino);
35490+ mutex_unlock(&sbinfo->idr_lock);
35491+ }
35492 shmem_free_inode(inode->i_sb);
35493 clear_inode(inode);
35494 }
35495@@ -1406,13 +1416,13 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode
35496 struct inode *inode;
35497 struct shmem_inode_info *info;
35498 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
35499+ int ino;
35500
35501 if (shmem_reserve_inode(sb))
35502 return NULL;
35503
35504 inode = new_inode(sb);
35505 if (inode) {
35506- inode->i_ino = get_next_ino();
35507 inode_init_owner(inode, dir, mode);
35508 inode->i_blocks = 0;
35509 inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
35510@@ -1454,6 +1464,25 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode
35511 mpol_shared_policy_init(&info->policy, NULL);
35512 break;
35513 }
35514+
35515+ if (!sbinfo->idr_nouse) {
35516+ /* inum 0 and 1 are unused */
35517+ mutex_lock(&sbinfo->idr_lock);
35518+ ino = idr_alloc(&sbinfo->idr, inode, 2, INT_MAX,
35519+ GFP_NOFS);
35520+ if (ino > 0) {
35521+ inode->i_ino = ino;
35522+ mutex_unlock(&sbinfo->idr_lock);
35523+ __insert_inode_hash(inode, inode->i_ino);
35524+ } else {
35525+ inode->i_ino = 0;
35526+ mutex_unlock(&sbinfo->idr_lock);
35527+ iput(inode);
35528+ /* shmem_free_inode() will be called */
35529+ inode = NULL;
35530+ }
35531+ } else
35532+ inode->i_ino = get_next_ino();
35533 } else
35534 shmem_free_inode(sb);
35535 return inode;
35536@@ -2674,8 +2703,7 @@ static struct dentry *shmem_get_parent(struct dentry *child)
35537 static int shmem_match(struct inode *ino, void *vfh)
35538 {
35539 __u32 *fh = vfh;
35540- __u64 inum = fh[2];
35541- inum = (inum << 32) | fh[1];
35542+ __u64 inum = fh[1];
35543 return ino->i_ino == inum && fh[0] == ino->i_generation;
35544 }
35545
35546@@ -2686,14 +2714,11 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
35547 struct dentry *dentry = NULL;
35548 u64 inum;
35549
35550- if (fh_len < 3)
35551+ if (fh_len < 2)
35552 return NULL;
35553
35554- inum = fid->raw[2];
35555- inum = (inum << 32) | fid->raw[1];
35556-
35557- inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
35558- shmem_match, fid->raw);
35559+ inum = fid->raw[1];
35560+ inode = ilookup5(sb, inum, shmem_match, fid->raw);
35561 if (inode) {
35562 dentry = d_find_alias(inode);
35563 iput(inode);
35564@@ -2705,30 +2730,15 @@ static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
35565 static int shmem_encode_fh(struct inode *inode, __u32 *fh, int *len,
35566 struct inode *parent)
35567 {
35568- if (*len < 3) {
35569- *len = 3;
35570+ if (*len < 2) {
35571+ *len = 2;
35572 return FILEID_INVALID;
35573 }
35574
35575- if (inode_unhashed(inode)) {
35576- /* Unfortunately insert_inode_hash is not idempotent,
35577- * so as we hash inodes here rather than at creation
35578- * time, we need a lock to ensure we only try
35579- * to do it once
35580- */
35581- static DEFINE_SPINLOCK(lock);
35582- spin_lock(&lock);
35583- if (inode_unhashed(inode))
35584- __insert_inode_hash(inode,
35585- inode->i_ino + inode->i_generation);
35586- spin_unlock(&lock);
35587- }
35588-
35589 fh[0] = inode->i_generation;
35590 fh[1] = inode->i_ino;
35591- fh[2] = ((__u64)inode->i_ino) >> 32;
35592
35593- *len = 3;
35594+ *len = 2;
35595 return 1;
35596 }
35597
35598@@ -2793,7 +2803,7 @@ static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo,
35599 goto bad_val;
35600 } else if (!strcmp(this_char,"nr_inodes")) {
35601 sbinfo->max_inodes = memparse(value, &rest);
35602- if (*rest)
35603+ if (*rest || sbinfo->max_inodes < 2)
35604 goto bad_val;
35605 } else if (!strcmp(this_char,"mode")) {
35606 if (remount)
35607@@ -2846,7 +2856,7 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
35608 {
35609 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
35610 struct shmem_sb_info config = *sbinfo;
35611- unsigned long inodes;
35612+ int inodes;
35613 int error = -EINVAL;
35614
35615 config.mpol = NULL;
35616@@ -2894,7 +2904,7 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root)
35617 seq_printf(seq, ",size=%luk",
35618 sbinfo->max_blocks << (PAGE_CACHE_SHIFT - 10));
35619 if (sbinfo->max_inodes != shmem_default_max_inodes())
35620- seq_printf(seq, ",nr_inodes=%lu", sbinfo->max_inodes);
35621+ seq_printf(seq, ",nr_inodes=%d", sbinfo->max_inodes);
35622 if (sbinfo->mode != (S_IRWXUGO | S_ISVTX))
35623 seq_printf(seq, ",mode=%03ho", sbinfo->mode);
35624 if (!uid_eq(sbinfo->uid, GLOBAL_ROOT_UID))
35625@@ -2983,6 +2993,8 @@ static void shmem_put_super(struct super_block *sb)
35626 {
35627 struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
35628
35629+ if (!sbinfo->idr_nouse)
35630+ idr_destroy(&sbinfo->idr);
35631 percpu_counter_destroy(&sbinfo->used_blocks);
35632 mpol_put(sbinfo->mpol);
35633 kfree(sbinfo);
35634@@ -3001,6 +3013,8 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
35635 if (!sbinfo)
35636 return -ENOMEM;
35637
35638+ mutex_init(&sbinfo->idr_lock);
35639+ idr_init(&sbinfo->idr);
35640 sbinfo->mode = S_IRWXUGO | S_ISVTX;
35641 sbinfo->uid = current_fsuid();
35642 sbinfo->gid = current_fsgid();
35643@@ -3104,6 +3118,15 @@ static void shmem_destroy_inodecache(void)
35644 kmem_cache_destroy(shmem_inode_cachep);
35645 }
35646
35647+static __init void shmem_no_idr(struct super_block *sb)
35648+{
35649+ struct shmem_sb_info *sbinfo;
35650+
35651+ sbinfo = SHMEM_SB(sb);
35652+ sbinfo->idr_nouse = true;
35653+ idr_destroy(&sbinfo->idr);
35654+}
35655+
35656 static const struct address_space_operations shmem_aops = {
35657 .writepage = shmem_writepage,
35658 .set_page_dirty = __set_page_dirty_no_writeback,
35659@@ -3246,6 +3269,7 @@ int __init shmem_init(void)
35660 printk(KERN_ERR "Could not kern_mount tmpfs\n");
35661 goto out1;
35662 }
35663+ shmem_no_idr(shm_mnt->mnt_sb);
35664 return 0;
35665
35666 out1:
35667diff --git a/fs/inode.c b/fs/inode.c
35668index 26753ba..61e0af2 100644
35669--- a/fs/inode.c
35670+++ b/fs/inode.c
35671@@ -840,6 +840,8 @@ unsigned int get_next_ino(void)
35672 unsigned int *p = &get_cpu_var(last_ino);
35673 unsigned int res = *p;
35674
35675+start:
35676+
35677 #ifdef CONFIG_SMP
35678 if (unlikely((res & (LAST_INO_BATCH-1)) == 0)) {
35679 static atomic_t shared_last_ino;
35680@@ -849,7 +851,9 @@ unsigned int get_next_ino(void)
35681 }
35682 #endif
35683
35684- *p = ++res;
35685+ if (unlikely(!++res))
35686+ goto start; /* never zero */
35687+ *p = res;
35688 put_cpu_var(last_ino);
35689 return res;
35690 }
This page took 5.821065 seconds and 4 git commands to generate.