From febd17d6c05fa4f2ce04ec0aa2818133296e19e0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Sun, 24 Apr 2016 18:34:45 +0200 Subject: [PATCH] - updated aufs patch --- kernel-aufs4.patch | 1037 ++++++++++++++++++++++---------------------- 1 file changed, 515 insertions(+), 522 deletions(-) diff --git a/kernel-aufs4.patch b/kernel-aufs4.patch index e9aae06c..4b720526 100644 --- a/kernel-aufs4.patch +++ b/kernel-aufs4.patch @@ -1,10 +1,10 @@ -aufs4.4 kbuild patch +aufs4.5 kbuild patch diff --git a/fs/Kconfig b/fs/Kconfig -index 6ce72d8..4aa31ea 100644 +index 9adee0d..5e9cfb2 100644 --- a/fs/Kconfig +++ b/fs/Kconfig -@@ -221,6 +221,7 @@ source "fs/pstore/Kconfig" +@@ -232,6 +232,7 @@ source "fs/pstore/Kconfig" source "fs/sysv/Kconfig" source "fs/ufs/Kconfig" source "fs/exofs/Kconfig" @@ -22,7 +22,7 @@ index 79f5225..a7c7f16 100644 obj-$(CONFIG_EFIVAR_FS) += efivarfs/ +obj-$(CONFIG_AUFS_FS) += aufs/ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild -index c2e5d6c..d736c11 100644 +index ebd10e6..32152e7 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -59,6 +59,7 @@ header-y += atmsvc.h @@ -33,13 +33,13 @@ index c2e5d6c..d736c11 100644 header-y += auto_fs4.h header-y += auto_fs.h header-y += auxvec.h -aufs4.4 base patch +aufs4.5 base patch diff --git a/MAINTAINERS b/MAINTAINERS -index 233f834..c250892 100644 +index 6ee06ea..3147250 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -2029,6 +2029,19 @@ F: include/linux/audit.h +@@ -2082,6 +2082,19 @@ F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -60,7 +60,7 @@ index 233f834..c250892 100644 M: Miguel Ojeda Sandonis W: http://miguelojeda.es/auxdisplay.htm diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 423f4ca..abfdd2b 100644 +index 423f4ca..0b816b2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -706,6 +706,24 @@ static inline int is_loop_device(struct file *file) @@ -83,16 +83,16 @@ index 423f4ca..abfdd2b 100644 + } + return ret; +} -+EXPORT_SYMBOL(loop_backing_file); ++EXPORT_SYMBOL_GPL(loop_backing_file); + /* loop sysfs attributes */ static ssize_t loop_attr_show(struct device *dev, char *page, diff --git a/fs/dcache.c b/fs/dcache.c -index 5c33aeb..8aa7f26 100644 +index 2398f9f9..318c329 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1167,7 +1167,7 @@ enum d_walk_ret { +@@ -1156,7 +1156,7 @@ enum d_walk_ret { * * The @enter() and @finish() callbacks are called with d_lock held. */ @@ -101,11 +101,33 @@ index 5c33aeb..8aa7f26 100644 enum d_walk_ret (*enter)(void *, struct dentry *), void (*finish)(void *)) { +diff --git a/fs/fcntl.c b/fs/fcntl.c +index 350a2c8..6f42279 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -29,7 +29,7 @@ + + #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) + +-static int setfl(int fd, struct file * filp, unsigned long arg) ++int setfl(int fd, struct file * filp, unsigned long arg) + { + struct inode * inode = file_inode(filp); + int error = 0; +@@ -60,6 +60,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg) + + if (filp->f_op->check_flags) + error = filp->f_op->check_flags(arg); ++ if (!error && filp->f_op->setfl) ++ error = filp->f_op->setfl(filp, arg); + if (error) + return error; + diff --git a/fs/read_write.c b/fs/read_write.c -index 819ef3f..fd0414e 100644 +index dadf24e..c8b5b7a 100644 --- a/fs/read_write.c +++ b/fs/read_write.c -@@ -494,6 +494,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, +@@ -534,6 +534,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, } EXPORT_SYMBOL(__vfs_write); @@ -135,10 +157,10 @@ index 819ef3f..fd0414e 100644 { mm_segment_t old_fs; diff --git a/fs/splice.c b/fs/splice.c -index 4cf700d..30a091d 100644 +index 82bc0d6..93aee51 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -1110,8 +1110,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); +@@ -1108,8 +1108,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); /* * Attempt to initiate a splice from pipe to file. */ @@ -149,7 +171,7 @@ index 4cf700d..30a091d 100644 { ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -@@ -1127,9 +1127,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -1125,9 +1125,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, /* * Attempt to initiate a splice from a file to a pipe. */ @@ -175,10 +197,26 @@ index f87d308..9a290b3 100644 static inline void fput_light(struct file *file, int fput_needed) { diff --git a/include/linux/fs.h b/include/linux/fs.h -index 3aa5142..8d48506 100644 +index ae68100..99fc2bd 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1672,6 +1672,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, +@@ -1260,6 +1260,7 @@ extern void fasync_free(struct fasync_struct *); + /* can be called from interrupts */ + extern void kill_fasync(struct fasync_struct **, int, int); + ++extern int setfl(int fd, struct file * filp, unsigned long arg); + extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); + extern void f_setown(struct file *filp, unsigned long arg, int force); + extern void f_delown(struct file *filp); +@@ -1646,6 +1647,7 @@ struct file_operations { + ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); + unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); + int (*check_flags)(int); ++ int (*setfl)(struct file *, unsigned long); + int (*flock) (struct file *, int, struct file_lock *); + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); + ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); +@@ -1704,6 +1706,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, struct iovec *fast_pointer, struct iovec **ret_pointer); @@ -206,13 +244,13 @@ index da2751d..2e0fca6 100644 + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); #endif -aufs4.4 mmap patch +aufs4.5 mmap patch diff --git a/fs/proc/base.c b/fs/proc/base.c -index 4bd5d31..aa41f2a 100644 +index 4f764c2..229de5e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c -@@ -1921,7 +1921,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path) +@@ -1933,7 +1933,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); if (vma && vma->vm_file) { @@ -238,10 +276,10 @@ index f8595e8..cb8eda0 100644 ino = inode->i_ino; } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 187b3b5..e03793e 100644 +index fa95ab2..d440354 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c -@@ -281,7 +281,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) +@@ -298,7 +298,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) const char *name = NULL; if (file) { @@ -253,7 +291,7 @@ index 187b3b5..e03793e 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; -@@ -1505,7 +1508,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) +@@ -1576,7 +1579,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) struct proc_maps_private *proc_priv = &numa_priv->proc_maps; struct vm_area_struct *vma = v; struct numa_maps *md = &numa_priv->md; @@ -263,10 +301,10 @@ index 187b3b5..e03793e 100644 struct mm_walk walk = { .hugetlb_entry = gather_hugetlb_stats, diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c -index e0d64c9..7aa92db 100644 +index faacb0c..17b43be 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c -@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma, +@@ -163,7 +163,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma, file = vma->vm_file; if (file) { @@ -279,10 +317,10 @@ index e0d64c9..7aa92db 100644 ino = inode->i_ino; pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; diff --git a/include/linux/mm.h b/include/linux/mm.h -index 00bad77..cc616b0 100644 +index 516e149..ddd5454 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -1183,6 +1183,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, +@@ -1217,6 +1217,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, } #endif @@ -312,10 +350,10 @@ index 00bad77..cc616b0 100644 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, void *buf, int len, int write); diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index f8d1492..c3a3760 100644 +index 624b78b..1be91c5 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h -@@ -272,6 +272,7 @@ struct vm_region { +@@ -269,6 +269,7 @@ struct vm_region { unsigned long vm_top; /* region allocated to here */ unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ struct file *vm_file; /* the backing file or NULL */ @@ -323,7 +361,7 @@ index f8d1492..c3a3760 100644 int vm_usage; /* region usage count (access under nommu_region_sem) */ bool vm_icache_flushed : 1; /* true if the icache has been flushed for -@@ -346,6 +347,7 @@ struct vm_area_struct { +@@ -343,6 +344,7 @@ struct vm_area_struct { unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE units, *not* PAGE_CACHE_SIZE */ struct file * vm_file; /* File we map to (can be NULL). */ @@ -332,10 +370,10 @@ index f8d1492..c3a3760 100644 #ifndef CONFIG_MMU diff --git a/kernel/fork.c b/kernel/fork.c -index 1155eac..c001ea4 100644 +index 2e391c7..6c4215c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -465,7 +465,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +@@ -464,7 +464,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) struct inode *inode = file_inode(file); struct address_space *mapping = file->f_mapping; @@ -358,10 +396,10 @@ index 2ed4319..e3a53f5 100644 obj-y += init-mm.o diff --git a/mm/filemap.c b/mm/filemap.c -index 1bb0076..8eaece8 100644 +index da7a35d..f800f87 100644 --- a/mm/filemap.c +++ b/mm/filemap.c -@@ -2128,7 +2128,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +@@ -2229,7 +2229,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) int ret = VM_FAULT_LOCKED; sb_start_pagefault(inode->i_sb); @@ -371,10 +409,10 @@ index 1bb0076..8eaece8 100644 if (page->mapping != inode->i_mapping) { unlock_page(page); diff --git a/mm/memory.c b/mm/memory.c -index c387430..d434404 100644 +index 8132787..3f7de66 100644 --- a/mm/memory.c +++ b/mm/memory.c -@@ -2035,7 +2035,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, +@@ -2042,7 +2042,7 @@ static inline int wp_page_reuse(struct mm_struct *mm, } if (!page_mkwrite) @@ -384,10 +422,10 @@ index c387430..d434404 100644 return VM_FAULT_WRITE; diff --git a/mm/mmap.c b/mm/mmap.c -index 2ce04a6..f555c0a 100644 +index 76d1ec2..fdd163e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c -@@ -275,7 +275,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) +@@ -290,7 +290,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) if (vma->vm_ops && vma->vm_ops->close) vma->vm_ops->close(vma); if (vma->vm_file) @@ -396,7 +434,7 @@ index 2ce04a6..f555c0a 100644 mpol_put(vma_policy(vma)); kmem_cache_free(vm_area_cachep, vma); return next; -@@ -887,7 +887,7 @@ again: remove_next = 1 + (end > next->vm_end); +@@ -909,7 +909,7 @@ again: remove_next = 1 + (end > next->vm_end); if (remove_next) { if (file) { uprobe_munmap(next, next->vm_start, next->vm_end); @@ -405,7 +443,7 @@ index 2ce04a6..f555c0a 100644 } if (next->anon_vma) anon_vma_merge(vma, next); -@@ -1681,8 +1681,8 @@ out: +@@ -1683,8 +1683,8 @@ out: return addr; unmap_and_free_vma: @@ -415,7 +453,7 @@ index 2ce04a6..f555c0a 100644 /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2488,7 +2488,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2479,7 +2479,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, goto out_free_mpol; if (new->vm_file) @@ -424,7 +462,7 @@ index 2ce04a6..f555c0a 100644 if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); -@@ -2507,7 +2507,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2498,7 +2498,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, if (new->vm_ops && new->vm_ops->close) new->vm_ops->close(new); if (new->vm_file) @@ -433,7 +471,7 @@ index 2ce04a6..f555c0a 100644 unlink_anon_vmas(new); out_free_mpol: mpol_put(vma_policy(new)); -@@ -2649,7 +2649,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2640,7 +2640,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, struct vm_area_struct *vma; unsigned long populate = 0; unsigned long ret = -EINVAL; @@ -441,8 +479,8 @@ index 2ce04a6..f555c0a 100644 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. " "See Documentation/vm/remap_file_pages.txt.\n", -@@ -2693,10 +2692,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, - munlock_vma_pages_range(vma, start, start + size); +@@ -2708,10 +2707,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, + } } - file = get_file(vma->vm_file); @@ -454,7 +492,7 @@ index 2ce04a6..f555c0a 100644 out: up_write(&mm->mmap_sem); if (populate) -@@ -2966,7 +2965,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2982,7 +2981,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, if (anon_vma_clone(new_vma, vma)) goto out_free_mempol; if (new_vma->vm_file) @@ -464,7 +502,7 @@ index 2ce04a6..f555c0a 100644 new_vma->vm_ops->open(new_vma); vma_link(mm, new_vma, prev, rb_link, rb_parent); diff --git a/mm/nommu.c b/mm/nommu.c -index 92be862..29179f7 100644 +index fbf6f0f1..1a4a06d 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -671,7 +671,7 @@ static void __put_nommu_region(struct vm_region *region) @@ -599,41 +637,53 @@ index 0000000..b323b8a + fput(pr); +} +#endif /* !CONFIG_MMU */ -aufs4.4 standalone patch +aufs4.5 standalone patch diff --git a/fs/dcache.c b/fs/dcache.c -index 8aa7f26..f997345 100644 +index 318c329..72d3cc8 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1272,6 +1272,7 @@ rename_retry: +@@ -1261,6 +1261,7 @@ rename_retry: seq = 1; goto again; } -+EXPORT_SYMBOL(d_walk); ++EXPORT_SYMBOL_GPL(d_walk); /* * Search for at least 1 mount point in the dentry's subdirs. diff --git a/fs/exec.c b/fs/exec.c -index b06623a..b9206c5 100644 +index dcd4ac7..09a7818 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -103,6 +103,7 @@ bool path_noexec(const struct path *path) return (path->mnt->mnt_flags & MNT_NOEXEC) || (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); } -+EXPORT_SYMBOL(path_noexec); ++EXPORT_SYMBOL_GPL(path_noexec); #ifdef CONFIG_USELIB /* +diff --git a/fs/fcntl.c b/fs/fcntl.c +index 6f42279..04fd33c 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -82,6 +82,7 @@ int setfl(int fd, struct file * filp, unsigned long arg) + out: + return error; + } ++EXPORT_SYMBOL_GPL(setfl); + + static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, + int force) diff --git a/fs/file_table.c b/fs/file_table.c -index ad17e05..38e046a 100644 +index ad17e05..ae9f267 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -147,6 +147,7 @@ over: } return ERR_PTR(-ENFILE); } -+EXPORT_SYMBOL(get_empty_filp); ++EXPORT_SYMBOL_GPL(get_empty_filp); /** * alloc_file - allocate and initialize a 'struct file' @@ -641,7 +691,7 @@ index ad17e05..38e046a 100644 { delayed_fput(NULL); } -+EXPORT_SYMBOL(flush_delayed_fput); ++EXPORT_SYMBOL_GPL(flush_delayed_fput); static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput); @@ -649,7 +699,7 @@ index ad17e05..38e046a 100644 } EXPORT_SYMBOL(fput); -+EXPORT_SYMBOL(__fput_sync); ++EXPORT_SYMBOL_GPL(__fput_sync); void put_filp(struct file *file) { @@ -657,12 +707,12 @@ index ad17e05..38e046a 100644 file_free(file); } } -+EXPORT_SYMBOL(put_filp); ++EXPORT_SYMBOL_GPL(put_filp); void __init files_init(void) { diff --git a/fs/namespace.c b/fs/namespace.c -index 0570729..ec560d8 100644 +index 4fb1691..97654d2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt) @@ -673,16 +723,16 @@ index 0570729..ec560d8 100644 /** * mnt_drop_write - give up write access to a mount -@@ -1803,6 +1804,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, +@@ -1811,6 +1812,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, } return 0; } -+EXPORT_SYMBOL(iterate_mounts); ++EXPORT_SYMBOL_GPL(iterate_mounts); static void cleanup_group_ids(struct mount *mnt, struct mount *end) { diff --git a/fs/notify/group.c b/fs/notify/group.c -index d16b62c..06ca6bc 100644 +index d16b62c..53e45b6 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -22,6 +22,7 @@ @@ -697,7 +747,7 @@ index d16b62c..06ca6bc 100644 { atomic_inc(&group->refcnt); } -+EXPORT_SYMBOL(fsnotify_get_group); ++EXPORT_SYMBOL_GPL(fsnotify_get_group); /* * Drop a reference to a group. Free it if it's through. @@ -705,7 +755,7 @@ index d16b62c..06ca6bc 100644 if (atomic_dec_and_test(&group->refcnt)) fsnotify_final_destroy_group(group); } -+EXPORT_SYMBOL(fsnotify_put_group); ++EXPORT_SYMBOL_GPL(fsnotify_put_group); /* * Create a new fsnotify_group and hold a reference for the group returned. @@ -713,55 +763,55 @@ index d16b62c..06ca6bc 100644 return group; } -+EXPORT_SYMBOL(fsnotify_alloc_group); ++EXPORT_SYMBOL_GPL(fsnotify_alloc_group); int fsnotify_fasync(int fd, struct file *file, int on) { diff --git a/fs/notify/mark.c b/fs/notify/mark.c -index fc0df44..325b5c6 100644 +index 7115c5d..ac2bd69 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c -@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) +@@ -113,6 +113,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) mark->free_mark(mark); } } -+EXPORT_SYMBOL(fsnotify_put_mark); ++EXPORT_SYMBOL_GPL(fsnotify_put_mark); /* Calculate mask of events for a list of marks */ u32 fsnotify_recalc_mask(struct hlist_head *head) -@@ -208,6 +209,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, +@@ -213,6 +214,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, mutex_unlock(&group->mark_mutex); fsnotify_free_mark(mark); } -+EXPORT_SYMBOL(fsnotify_destroy_mark); ++EXPORT_SYMBOL_GPL(fsnotify_destroy_mark); void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock) { -@@ -392,6 +394,7 @@ err: +@@ -398,6 +400,7 @@ err: return ret; } -+EXPORT_SYMBOL(fsnotify_add_mark); ++EXPORT_SYMBOL_GPL(fsnotify_add_mark); int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, struct inode *inode, struct vfsmount *mnt, int allow_dups) -@@ -492,6 +495,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, +@@ -498,6 +501,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, atomic_set(&mark->refcnt, 1); mark->free_mark = free_mark; } -+EXPORT_SYMBOL(fsnotify_init_mark); ++EXPORT_SYMBOL_GPL(fsnotify_init_mark); - static int fsnotify_mark_destroy(void *ignored) + static void fsnotify_mark_destroy(struct work_struct *work) { diff --git a/fs/open.c b/fs/open.c -index b6f1e96..4ab0d4e 100644 +index 55bdc75..fd1df73 100644 --- a/fs/open.c +++ b/fs/open.c @@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, - mutex_unlock(&dentry->d_inode->i_mutex); + inode_unlock(dentry->d_inode); return ret; } -+EXPORT_SYMBOL(do_truncate); ++EXPORT_SYMBOL_GPL(do_truncate); long vfs_truncate(struct path *path, loff_t length) { @@ -769,92 +819,92 @@ index b6f1e96..4ab0d4e 100644 } return 0; } -+EXPORT_SYMBOL(open_check_o_direct); ++EXPORT_SYMBOL_GPL(open_check_o_direct); static int do_dentry_open(struct file *f, struct inode *inode, diff --git a/fs/read_write.c b/fs/read_write.c -index fd0414e..8ace6ec 100644 +index c8b5b7a..9461d12 100644 --- a/fs/read_write.c +++ b/fs/read_write.c -@@ -504,6 +504,7 @@ vfs_readf_t vfs_readf(struct file *file) +@@ -544,6 +544,7 @@ vfs_readf_t vfs_readf(struct file *file) return new_sync_read; return ERR_PTR(-ENOSYS); } -+EXPORT_SYMBOL(vfs_readf); ++EXPORT_SYMBOL_GPL(vfs_readf); vfs_writef_t vfs_writef(struct file *file) { -@@ -515,6 +516,7 @@ vfs_writef_t vfs_writef(struct file *file) +@@ -555,6 +556,7 @@ vfs_writef_t vfs_writef(struct file *file) return new_sync_write; return ERR_PTR(-ENOSYS); } -+EXPORT_SYMBOL(vfs_writef); ++EXPORT_SYMBOL_GPL(vfs_writef); ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos) { diff --git a/fs/splice.c b/fs/splice.c -index 30a091d..c37c311 100644 +index 93aee51..52d2f5b 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -1123,6 +1123,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -1121,6 +1121,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, return splice_write(pipe, out, ppos, len, flags); } -+EXPORT_SYMBOL(do_splice_from); ++EXPORT_SYMBOL_GPL(do_splice_from); /* * Attempt to initiate a splice from a file to a pipe. -@@ -1149,6 +1150,7 @@ long do_splice_to(struct file *in, loff_t *ppos, +@@ -1147,6 +1148,7 @@ long do_splice_to(struct file *in, loff_t *ppos, return splice_read(in, ppos, pipe, len, flags); } -+EXPORT_SYMBOL(do_splice_to); ++EXPORT_SYMBOL_GPL(do_splice_to); /** * splice_direct_to_actor - splices data directly between two non-pipes diff --git a/fs/xattr.c b/fs/xattr.c -index 9b932b9..44c457a 100644 +index 4861322..c4bb039 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -207,6 +207,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, *xattr_value = value; return error; } -+EXPORT_SYMBOL(vfs_getxattr_alloc); ++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); - /* Compare an extended attribute value with the given value */ - int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name, + ssize_t + vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) diff --git a/kernel/task_work.c b/kernel/task_work.c -index 53fa971..f80d564 100644 +index 53fa971..bce3211 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -118,3 +118,4 @@ void task_work_run(void) } while (work); } } -+EXPORT_SYMBOL(task_work_run); ++EXPORT_SYMBOL_GPL(task_work_run); diff --git a/security/commoncap.c b/security/commoncap.c -index 1832cf7..987ff5f 100644 +index 48071ed..50a1a40 100644 --- a/security/commoncap.c +++ b/security/commoncap.c -@@ -1053,12 +1053,14 @@ int cap_mmap_addr(unsigned long addr) +@@ -1058,12 +1058,14 @@ int cap_mmap_addr(unsigned long addr) } return ret; } -+EXPORT_SYMBOL(cap_mmap_addr); ++EXPORT_SYMBOL_GPL(cap_mmap_addr); int cap_mmap_file(struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags) { return 0; } -+EXPORT_SYMBOL(cap_mmap_file); ++EXPORT_SYMBOL_GPL(cap_mmap_file); #ifdef CONFIG_SECURITY diff --git a/security/device_cgroup.c b/security/device_cgroup.c -index 03c1652..b00aa76 100644 +index 03c1652..f88c84b 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -7,6 +7,7 @@ @@ -869,19 +919,19 @@ index 03c1652..b00aa76 100644 return __devcgroup_check_permission(type, imajor(inode), iminor(inode), access); } -+EXPORT_SYMBOL(__devcgroup_inode_permission); ++EXPORT_SYMBOL_GPL(__devcgroup_inode_permission); int devcgroup_inode_mknod(int mode, dev_t dev) { diff --git a/security/security.c b/security/security.c -index 46f405c..54488b0 100644 +index e8ffd92..51fa026 100644 --- a/security/security.c +++ b/security/security.c @@ -433,6 +433,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry) return 0; return call_int_hook(path_rmdir, 0, dir, dentry); } -+EXPORT_SYMBOL(security_path_rmdir); ++EXPORT_SYMBOL_GPL(security_path_rmdir); int security_path_unlink(struct path *dir, struct dentry *dentry) { @@ -889,7 +939,7 @@ index 46f405c..54488b0 100644 return 0; return call_int_hook(path_symlink, 0, dir, dentry, old_name); } -+EXPORT_SYMBOL(security_path_symlink); ++EXPORT_SYMBOL_GPL(security_path_symlink); int security_path_link(struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry) @@ -897,7 +947,7 @@ index 46f405c..54488b0 100644 return 0; return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); } -+EXPORT_SYMBOL(security_path_link); ++EXPORT_SYMBOL_GPL(security_path_link); int security_path_rename(struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry, @@ -905,7 +955,7 @@ index 46f405c..54488b0 100644 return 0; return call_int_hook(path_truncate, 0, path); } -+EXPORT_SYMBOL(security_path_truncate); ++EXPORT_SYMBOL_GPL(security_path_truncate); int security_path_chmod(struct path *path, umode_t mode) { @@ -913,7 +963,7 @@ index 46f405c..54488b0 100644 return 0; return call_int_hook(path_chmod, 0, path, mode); } -+EXPORT_SYMBOL(security_path_chmod); ++EXPORT_SYMBOL_GPL(security_path_chmod); int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) { @@ -921,7 +971,7 @@ index 46f405c..54488b0 100644 return 0; return call_int_hook(path_chown, 0, path, uid, gid); } -+EXPORT_SYMBOL(security_path_chown); ++EXPORT_SYMBOL_GPL(security_path_chown); int security_path_chroot(struct path *path) { @@ -929,7 +979,7 @@ index 46f405c..54488b0 100644 return 0; return call_int_hook(inode_readlink, 0, dentry); } -+EXPORT_SYMBOL(security_inode_readlink); ++EXPORT_SYMBOL_GPL(security_inode_readlink); int security_inode_follow_link(struct dentry *dentry, struct inode *inode, bool rcu) @@ -937,7 +987,7 @@ index 46f405c..54488b0 100644 return 0; return call_int_hook(inode_permission, 0, inode, mask); } -+EXPORT_SYMBOL(security_inode_permission); ++EXPORT_SYMBOL_GPL(security_inode_permission); int security_inode_setattr(struct dentry *dentry, struct iattr *attr) { @@ -945,7 +995,7 @@ index 46f405c..54488b0 100644 return fsnotify_perm(file, mask); } -+EXPORT_SYMBOL(security_file_permission); ++EXPORT_SYMBOL_GPL(security_file_permission); int security_file_alloc(struct file *file) { @@ -953,13 +1003,13 @@ index 46f405c..54488b0 100644 return ret; return ima_file_mmap(file, prot); } -+EXPORT_SYMBOL(security_mmap_file); ++EXPORT_SYMBOL_GPL(security_mmap_file); int security_mmap_addr(unsigned long addr) { diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Documentation/ABI/testing/debugfs-aufs --- /usr/share/empty/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/ABI/testing/debugfs-aufs 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/ABI/testing/debugfs-aufs 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,50 @@ +What: /debug/aufs/si_/ +Date: March 2009 @@ -1013,7 +1063,7 @@ diff -urN /usr/share/empty/Documentation/ABI/testing/debugfs-aufs linux/Document + will be empty. About XINO files, see the aufs manual. diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentation/ABI/testing/sysfs-aufs --- /usr/share/empty/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/ABI/testing/sysfs-aufs 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/ABI/testing/sysfs-aufs 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,31 @@ +What: /sys/fs/aufs/si_/ +Date: March 2009 @@ -1048,7 +1098,7 @@ diff -urN /usr/share/empty/Documentation/ABI/testing/sysfs-aufs linux/Documentat + will be empty. About XINO files, see the aufs manual. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt linux/Documentation/filesystems/aufs/design/01intro.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/01intro.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/01intro.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,170 @@ + +# Copyright (C) 2005-2016 Junjiro R. Okajima @@ -1222,7 +1272,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/01intro.txt lin +about it. But currently I have implemented it in kernel space. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt linux/Documentation/filesystems/aufs/design/02struct.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/02struct.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/02struct.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,258 @@ + +# Copyright (C) 2005-2016 Junjiro R. Okajima @@ -1484,7 +1534,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/02struct.txt li +For this purpose, use "aumvdown" command in aufs-util.git. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt linux/Documentation/filesystems/aufs/design/03atomic_open.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/03atomic_open.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,85 @@ + +# Copyright (C) 2015-2016 Junjiro R. Okajima @@ -1573,7 +1623,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03atomic_open.t + be implemented in aufs, but not all I am afraid. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt linux/Documentation/filesystems/aufs/design/03lookup.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/03lookup.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,113 @@ + +# Copyright (C) 2005-2016 Junjiro R. Okajima @@ -1690,7 +1740,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/03lookup.txt li + by over-mounting something (or another method). diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt linux/Documentation/filesystems/aufs/design/04branch.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/04branch.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/04branch.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,74 @@ + +# Copyright (C) 2005-2016 Junjiro R. Okajima @@ -1768,7 +1818,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/04branch.txt li + same named entry on the upper branch. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt linux/Documentation/filesystems/aufs/design/05wbr_policy.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/05wbr_policy.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,64 @@ + +# Copyright (C) 2005-2016 Junjiro R. Okajima @@ -1836,7 +1886,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/05wbr_policy.tx + copyup policy. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linux/Documentation/filesystems/aufs/design/06fhsm.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/06fhsm.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,120 @@ + +# Copyright (C) 2011-2016 Junjiro R. Okajima @@ -1960,7 +2010,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06fhsm.txt linu +should restore the original file state after an error happens. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linux/Documentation/filesystems/aufs/design/06mmap.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/06mmap.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,72 @@ + +# Copyright (C) 2005-2016 Junjiro R. Okajima @@ -2036,7 +2086,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06mmap.txt linu +I have to give up this "looks-smater" approach. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt linux/Documentation/filesystems/aufs/design/06xattr.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/06xattr.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,96 @@ + +# Copyright (C) 2014-2016 Junjiro R. Okajima @@ -2136,7 +2186,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/06xattr.txt lin +now, aufs implements the branch attributes to ignore the error. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt linux/Documentation/filesystems/aufs/design/07export.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/07export.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/07export.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,58 @@ + +# Copyright (C) 2005-2016 Junjiro R. Okajima @@ -2198,7 +2248,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/07export.txt li + lookup_one_len(), vfs_getattr(), encode_fh() and others. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linux/Documentation/filesystems/aufs/design/08shwh.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/08shwh.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,52 @@ + +# Copyright (C) 2005-2016 Junjiro R. Okajima @@ -2254,7 +2304,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/08shwh.txt linu +initramfs will use it to replace the old one at the next boot. diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt linux/Documentation/filesystems/aufs/design/10dynop.txt --- /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/design/10dynop.txt 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,47 @@ + +# Copyright (C) 2010-2016 Junjiro R. Okajima @@ -2305,7 +2355,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt lin +regular files only. diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README --- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/README 2016-02-28 11:26:32.569971135 +0100 ++++ linux/Documentation/filesystems/aufs/README 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,391 @@ + +Aufs4 -- advanced multi layered unification filesystem version 4.x @@ -2700,7 +2750,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta +# End: ; diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h --- /usr/share/empty/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/aufs.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/aufs.h 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -2763,7 +2813,7 @@ diff -urN /usr/share/empty/fs/aufs/aufs.h linux/fs/aufs/aufs.h +#endif /* __AUFS_H__ */ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c --- /usr/share/empty/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/branch.c 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/branch.c 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,1407 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -3062,7 +3112,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c +{ + int err, old_perm; + aufs_bindex_t bindex; -+ struct mutex *h_mtx; ++ struct inode *h_inode; + struct au_wbr *wbr; + struct au_hinode *hdir; + struct dentry *h_dentry; @@ -3075,15 +3125,15 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + old_perm = br->br_perm; + br->br_perm = new_perm; + hdir = NULL; -+ h_mtx = NULL; ++ h_inode = NULL; + bindex = au_br_index(sb, br->br_id); + if (0 <= bindex) { + hdir = au_hi(d_inode(sb->s_root), bindex); + au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT); + } else { + h_dentry = au_br_dentry(br); -+ h_mtx = &d_inode(h_dentry)->i_mutex; -+ mutex_lock_nested(h_mtx, AuLsc_I_PARENT); ++ h_inode = d_inode(h_dentry); ++ inode_lock_nested(h_inode, AuLsc_I_PARENT); + } + if (!wbr) + err = au_wh_init(br, sb); @@ -3095,7 +3145,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + if (hdir) + au_hn_imtx_unlock(hdir); + else -+ mutex_unlock(h_mtx); ++ inode_unlock(h_inode); + vfsub_mnt_drop_write(au_br_mnt(br)); + br->br_perm = old_perm; + @@ -4174,7 +4224,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c +} diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h --- /usr/share/empty/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/branch.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/branch.h 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -4457,7 +4507,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h +#endif /* __AUFS_BRANCH_H__ */ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk --- /usr/share/empty/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/conf.mk 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/conf.mk 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,38 @@ + +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS} @@ -4499,7 +4549,7 @@ diff -urN /usr/share/empty/fs/aufs/conf.mk linux/fs/aufs/conf.mk +-include ${srctree}/${src}/conf_priv.mk diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c --- /usr/share/empty/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/cpup.c 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/cpup.c 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,1379 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -4741,7 +4791,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + size_t sz, rbytes, wbytes; + unsigned char all_zero; + char *p, *zp; -+ struct mutex *h_mtx; ++ struct inode *h_inode; + /* reduce stack usage */ + struct iattr *ia; + @@ -4821,12 +4871,12 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + ia->ia_size = dst->f_pos; + ia->ia_valid = ATTR_SIZE | ATTR_FILE; + ia->ia_file = dst; -+ h_mtx = &file_inode(dst)->i_mutex; -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2); ++ h_inode = file_inode(dst); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD2); + /* no delegation since it is just created */ + err = vfsub_notify_change(&dst->f_path, ia, + /*delegated*/NULL); -+ mutex_unlock(h_mtx); ++ inode_unlock(h_inode); + } + } + @@ -4954,7 +5004,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + cpg->len = l; + if (cpg->len) { + /* try stopping to update while we are referencing */ -+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(h_src_inode, AuLsc_I_CHILD); + au_pin_hdir_unlock(cpg->pin); + + h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc); @@ -4963,17 +5013,17 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + if (!au_test_nfs(h_src_inode->i_sb)) + err = vfs_getattr(&h_path, &h_src_attr->st); + else { -+ mutex_unlock(&h_src_inode->i_mutex); ++ inode_unlock(h_src_inode); + err = vfs_getattr(&h_path, &h_src_attr->st); -+ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(h_src_inode, AuLsc_I_CHILD); + } + if (unlikely(err)) { -+ mutex_unlock(&h_src_inode->i_mutex); ++ inode_unlock(h_src_inode); + goto out; + } + h_src_attr->valid = 1; + err = au_cp_regular(cpg); -+ mutex_unlock(&h_src_inode->i_mutex); ++ inode_unlock(h_src_inode); + rerr = au_pin_hdir_relock(cpg->pin); + if (!err && rerr) + err = rerr; @@ -5324,7 +5374,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + if (unlikely(err)) + goto out_rev; + dst_inode = d_inode(h_dst); -+ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); ++ inode_lock_nested(dst_inode, AuLsc_I_CHILD2); + /* todo: necessary? */ + /* au_pin_hdir_unlock(cpg->pin); */ + @@ -5332,7 +5382,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + if (unlikely(err)) { + /* todo: necessary? */ + /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */ -+ mutex_unlock(&dst_inode->i_mutex); ++ inode_unlock(dst_inode); + goto out_rev; + } + @@ -5342,7 +5392,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + if (unlikely(err)) { + /* ignore an error */ + /* au_pin_hdir_relock(cpg->pin); */ -+ mutex_unlock(&dst_inode->i_mutex); ++ inode_unlock(dst_inode); + goto out_rev; + } + } @@ -5354,7 +5404,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + + /* todo: necessary? */ + /* err = au_pin_hdir_relock(cpg->pin); */ -+ mutex_unlock(&dst_inode->i_mutex); ++ inode_unlock(dst_inode); + if (unlikely(err)) + goto out_rev; + @@ -5728,7 +5778,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + h_tmpdir = d_inode(h_orph); + au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); + -+ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3); ++ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3); + /* todo: au_h_open_pre()? */ + + pin_orig = cpg->pin; @@ -5752,7 +5802,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + } + + if (h_orph) { -+ mutex_unlock(&h_tmpdir->i_mutex); ++ inode_unlock(h_tmpdir); + /* todo: au_h_open_post()? */ + au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); + au_set_h_dptr(parent, bdst, h_parent); @@ -5882,7 +5932,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c +} diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h --- /usr/share/empty/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/cpup.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/cpup.h 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -5980,7 +6030,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.h linux/fs/aufs/cpup.h +#endif /* __AUFS_CPUP_H__ */ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c --- /usr/share/empty/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dbgaufs.c 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dbgaufs.c 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -6416,7 +6466,7 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c +} diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h --- /usr/share/empty/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dbgaufs.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dbgaufs.h 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -6468,7 +6518,7 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.h linux/fs/aufs/dbgaufs.h +#endif /* __DBGAUFS_H__ */ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c --- /usr/share/empty/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dcsub.c 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dcsub.c 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -6696,7 +6746,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c +} diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h --- /usr/share/empty/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dcsub.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dcsub.h 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -6836,7 +6886,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.h linux/fs/aufs/dcsub.h +#endif /* __AUFS_DCSUB_H__ */ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c --- /usr/share/empty/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/debug.c 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/debug.c 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,438 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -7278,7 +7328,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c +} diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h --- /usr/share/empty/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/debug.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/debug.h 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -7507,7 +7557,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.h linux/fs/aufs/debug.h +#endif /* __AUFS_DEBUG_H__ */ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c --- /usr/share/empty/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dentry.c 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dentry.c 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,1136 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -7612,9 +7662,9 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + || (d_really_is_positive(dentry) && !d_is_dir(dentry))) + goto out; /* success */ + -+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + opq = au_diropq_test(h_dentry); -+ mutex_unlock(&h_inode->i_mutex); ++ inode_unlock(h_inode); + if (opq > 0) + au_set_dbdiropq(dentry, bindex); + else if (unlikely(opq < 0)) { @@ -7691,10 +7741,10 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + continue; + + h_dir = d_inode(h_parent); -+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ inode_lock_nested(h_dir, AuLsc_I_PARENT); + h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname, + &args); -+ mutex_unlock(&h_dir->i_mutex); ++ inode_unlock(h_dir); + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) + goto out_parent; @@ -8647,7 +8697,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c +}; diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h --- /usr/share/empty/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dentry.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dentry.h 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -8885,7 +8935,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h +#endif /* __AUFS_DENTRY_H__ */ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c --- /usr/share/empty/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dinfo.c 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dinfo.c 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -9439,8 +9489,8 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c +} diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c --- /usr/share/empty/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dir.c 2016-02-28 11:26:32.569971135 +0100 -@@ -0,0 +1,758 @@ ++++ linux/fs/aufs/dir.c 2016-04-24 18:32:51.390353525 +0200 +@@ -0,0 +1,756 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -9884,13 +9934,11 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + struct dentry *dentry; + struct inode *inode; + struct super_block *sb; -+ struct mutex *mtx; + + err = 0; + dentry = file->f_path.dentry; + inode = d_inode(dentry); -+ mtx = &inode->i_mutex; -+ mutex_lock(mtx); ++ inode_lock(inode); + sb = dentry->d_sb; + si_noflush_read_lock(sb); + if (file) @@ -9905,7 +9953,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + fi_write_unlock(file); + + si_read_unlock(sb); -+ mutex_unlock(mtx); ++ inode_unlock(inode); + return err; +} + @@ -10079,9 +10127,9 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + h_dentry = au_h_dptr(dentry, arg->bindex); + h_inode = d_inode(h_dentry); + /* todo: i_mode changes anytime? */ -+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ); -+ mutex_unlock(&h_inode->i_mutex); ++ inode_unlock(h_inode); + if (!err) + err = do_test_empty(dentry, arg); + else { @@ -10201,7 +10249,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c +}; diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h --- /usr/share/empty/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dir.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dir.h 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -10336,7 +10384,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h +#endif /* __AUFS_DIR_H__ */ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c --- /usr/share/empty/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dynop.c 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dynop.c 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2010-2016 Junjiro R. Okajima @@ -10709,7 +10757,7 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c +} diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h --- /usr/share/empty/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dynop.h 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/dynop.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010-2016 Junjiro R. Okajima @@ -10787,8 +10835,8 @@ diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h +#endif /* __AUFS_DYNOP_H__ */ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c --- /usr/share/empty/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/export.c 2016-02-28 11:26:32.569971135 +0100 -@@ -0,0 +1,832 @@ ++++ linux/fs/aufs/export.c 2016-04-24 18:32:51.393686895 +0200 +@@ -0,0 +1,830 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -11197,9 +11245,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c + + /* do not call vfsub_lkup_one() */ + dir = d_inode(parent); -+ mutex_lock(&dir->i_mutex); -+ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen); -+ mutex_unlock(&dir->i_mutex); ++ dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen); + AuTraceErrPtr(dentry); + if (IS_ERR(dentry)) + goto out_name; @@ -11623,7 +11669,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c +} diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c --- /usr/share/empty/fs/aufs/fhsm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/fhsm.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/fhsm.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2011-2016 Junjiro R. Okajima @@ -12053,7 +12099,7 @@ diff -urN /usr/share/empty/fs/aufs/fhsm.c linux/fs/aufs/fhsm.c +} diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c --- /usr/share/empty/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/file.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/file.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,844 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -12901,7 +12947,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c +}; diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h --- /usr/share/empty/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/file.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/file.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -13196,7 +13242,7 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h +#endif /* __AUFS_FILE_H__ */ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c --- /usr/share/empty/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/finfo.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/finfo.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -13356,8 +13402,8 @@ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c +} diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c --- /usr/share/empty/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/f_op.c 2016-02-28 11:26:32.569971135 +0100 -@@ -0,0 +1,748 @@ ++++ linux/fs/aufs/f_op.c 2016-04-24 18:32:51.393686895 +0200 +@@ -0,0 +1,770 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -13633,11 +13679,11 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + struct super_block *sb = inode->i_sb; + + while (1) { -+ mutex_lock(&inode->i_mutex); ++ inode_lock(inode); + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); + if (!err) + break; -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); + si_read_lock(sb, AuLock_NOPLMW); + si_read_unlock(sb); + } @@ -13665,7 +13711,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + +out: + si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); + return err; +} + @@ -13750,7 +13796,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + +out: + si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); + return err; +} + @@ -13813,7 +13859,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + +out: + si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); + return err; +} + @@ -13840,7 +13886,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + +out: + si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); + return err; +} + @@ -13983,7 +14029,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + +out_unlock: + si_read_unlock(inode->i_sb); -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); +out: + return err; +} @@ -13994,7 +14040,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c +{ + int err; + struct au_write_pre wpre; -+ struct inode *inode; ++ struct inode *inode, *h_inode; + struct file *file, *h_file; + + err = 0; /* -EBADF; */ /* posix? */ @@ -14013,26 +14059,24 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + err = -ENOSYS; + h_file = au_hf_top(file); + if (h_file->f_op->aio_fsync) { -+ struct mutex *h_mtx; -+ -+ h_mtx = &file_inode(h_file)->i_mutex; ++ h_inode = file_inode(h_file); + if (!is_sync_kiocb(kio)) { + get_file(h_file); + fput(file); + } + kio->ki_filp = h_file; + err = h_file->f_op->aio_fsync(kio, datasync); -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + if (!err) + vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); + /*ignore*/ -+ mutex_unlock(h_mtx); ++ inode_unlock(h_inode); + } + au_write_post(inode, h_file, &wpre, /*written*/0); + +out_unlock: + si_read_unlock(inode->sb); -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); +out: + return err; +} @@ -14061,6 +14105,29 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + return err; +} + ++static int aufs_setfl(struct file *file, unsigned long arg) ++{ ++ int err; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ sb = file->f_path.dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ ++ h_file = au_read_pre(file, /*keep_fi*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ arg |= vfsub_file_flags(file) & FASYNC; /* stop calling h_file->fasync */ ++ err = setfl(/*unused fd*/-1, h_file, arg); ++ fput(h_file); /* instead of au_read_post() */ ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ +/* ---------------------------------------------------------------------- */ + +/* no one supports this operation, currently */ @@ -14098,6 +14165,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c + /* .aio_fsync = aufs_aio_fsync_nondir, */ + .fasync = aufs_fasync, + /* .sendpage = aufs_sendpage, */ ++ .setfl = aufs_setfl, + .splice_write = aufs_splice_write, + .splice_read = aufs_splice_read, +#if 0 @@ -14108,7 +14176,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c +}; diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h --- /usr/share/empty/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/fstype.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/fstype.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -14512,7 +14580,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h +#endif /* __AUFS_FSTYPE_H__ */ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c --- /usr/share/empty/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/hfsnotify.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/hfsnotify.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -14804,7 +14872,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c +}; diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c --- /usr/share/empty/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/hfsplus.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/hfsplus.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010-2016 Junjiro R. Okajima @@ -14864,7 +14932,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsplus.c linux/fs/aufs/hfsplus.c +} diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c --- /usr/share/empty/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/hnotify.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/hnotify.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,710 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -14951,7 +15019,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c + if (!hi) + continue; + -+ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */ ++ /* inode_lock_nested(hi, AuLsc_I_CHILD); */ + iwhdentry = au_hi_wh(inode, bindex); + if (iwhdentry) + dget(iwhdentry); @@ -14961,7 +15029,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c + flags & ~AuHi_XINO); + iput(hi); + dput(iwhdentry); -+ /* mutex_unlock(&hi->i_mutex); */ ++ /* inode_unlock(hi); */ + } +} + @@ -15190,11 +15258,11 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c + if (au_ftest_hnjob(a->flags, TRYXINO0) + && a->inode + && a->h_inode) { -+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); + if (!a->h_inode->i_nlink + && !(a->h_inode->i_state & I_LINKABLE)) + hn_xino(a->inode, a->h_inode); /* ignore this error */ -+ mutex_unlock(&a->h_inode->i_mutex); ++ inode_unlock(a->h_inode); + } + + /* make the generation obsolete */ @@ -15578,7 +15646,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c +} diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c --- /usr/share/empty/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/iinfo.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/iinfo.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -15859,7 +15927,7 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c +} diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c --- /usr/share/empty/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/inode.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/inode.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -16390,7 +16458,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c +} diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h --- /usr/share/empty/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/inode.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/inode.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,685 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -17058,28 +17126,28 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h + +static inline void au_hn_imtx_lock(struct au_hinode *hdir) +{ -+ mutex_lock(&hdir->hi_inode->i_mutex); ++ inode_lock(hdir->hi_inode); + au_hn_suspend(hdir); +} + +static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir, + unsigned int sc __maybe_unused) +{ -+ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc); ++ inode_lock_nested(hdir->hi_inode, sc); + au_hn_suspend(hdir); +} + +static inline void au_hn_imtx_unlock(struct au_hinode *hdir) +{ + au_hn_resume(hdir); -+ mutex_unlock(&hdir->hi_inode->i_mutex); ++ inode_unlock(hdir->hi_inode); +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_INODE_H__ */ diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c --- /usr/share/empty/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/ioctl.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/ioctl.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -17302,7 +17370,7 @@ diff -urN /usr/share/empty/fs/aufs/ioctl.c linux/fs/aufs/ioctl.c +#endif diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c --- /usr/share/empty/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/i_op_add.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/i_op_add.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,932 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -17720,7 +17788,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + }; + + /* copy-up may happen */ -+ mutex_lock(&dir->i_mutex); ++ inode_lock(dir); + + sb = dir->i_sb; + err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); @@ -17817,7 +17885,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c +out_si: + si_read_unlock(sb); +out: -+ mutex_unlock(&dir->i_mutex); ++ inode_unlock(dir); + return err; +} + @@ -18136,7 +18204,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + unsigned char diropq; + struct path h_path; + struct dentry *wh_dentry, *parent, *opq_dentry; -+ struct mutex *h_mtx; ++ struct inode *h_inode; + struct super_block *sb; + struct { + struct au_pin pin; @@ -18179,12 +18247,12 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + + /* make the dir opaque */ + diropq = 0; -+ h_mtx = &d_inode(h_path.dentry)->i_mutex; ++ h_inode = d_inode(h_path.dentry); + if (wh_dentry + || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + opq_dentry = au_diropq_create(dentry, bindex); -+ mutex_unlock(h_mtx); ++ inode_unlock(h_inode); + err = PTR_ERR(opq_dentry); + if (IS_ERR(opq_dentry)) + goto out_dir; @@ -18201,9 +18269,9 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + /* revert */ + if (diropq) { + AuLabel(revert opq); -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + rerr = au_diropq_remove(dentry, bindex); -+ mutex_unlock(h_mtx); ++ inode_unlock(h_inode); + if (rerr) { + AuIOErr("%pd reverting diropq failed(%d, %d)\n", + dentry, err, rerr); @@ -18238,8 +18306,8 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c +} diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c --- /usr/share/empty/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/i_op.c 2016-02-28 11:26:32.573304539 +0100 -@@ -0,0 +1,1490 @@ ++++ linux/fs/aufs/i_op.c 2016-04-24 18:32:51.393686895 +0200 +@@ -0,0 +1,1419 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -18669,10 +18737,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) { + h_parent = au_h_dptr(parent, bcpup); + h_dir = d_inode(h_parent); -+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ inode_lock_nested(h_dir, AuLsc_I_PARENT); + err = au_lkup_neg(dentry, bcpup, /*wh*/0); + /* todo: no unlock here */ -+ mutex_unlock(&h_dir->i_mutex); ++ inode_unlock(h_dir); + + AuDbg("bcpup %d\n", bcpup); + if (!err) { @@ -19056,10 +19124,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + sz = -1; + a->h_inode = d_inode(a->h_path.dentry); + if (ia && (ia->ia_valid & ATTR_SIZE)) { -+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); + if (ia->ia_size < i_size_read(a->h_inode)) + sz = ia->ia_size; -+ mutex_unlock(&a->h_inode->i_mutex); ++ inode_unlock(a->h_inode); + } + + hi_wh = NULL; @@ -19119,7 +19187,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + } +out: + if (!err) -+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); + return err; +} + @@ -19203,9 +19271,9 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + f = NULL; + if (ia->ia_valid & ATTR_FILE) + f = ia->ia_file; -+ mutex_unlock(&a->h_inode->i_mutex); ++ inode_unlock(a->h_inode); + err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f); -+ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); + } else { + delegated = NULL; + while (1) { @@ -19228,7 +19296,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + au_cpup_attr_changeable(inode); + +out_unlock: -+ mutex_unlock(&a->h_inode->i_mutex); ++ inode_unlock(a->h_inode); + au_unpin(&a->pin); + if (unlikely(err)) + au_update_dbstart(dentry); @@ -19304,7 +19372,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + if (unlikely(err)) + goto out_di; + -+ mutex_unlock(&a->h_inode->i_mutex); ++ inode_unlock(a->h_inode); + switch (arg->type) { + case AU_XATTR_SET: + err = vfsub_setxattr(h_path.dentry, @@ -19489,62 +19557,20 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + +/* ---------------------------------------------------------------------- */ + -+/* -+ * Assumption: -+ * - the number of symlinks is not so many. -+ * -+ * Structure: -+ * - sbinfo (instead of iinfo) contains an hlist of struct au_symlink. -+ * If iinfo contained the hlist, then it would be rather large waste of memory -+ * I am afraid. -+ * - struct au_symlink contains the necessary info for h_inode follow_link() and -+ * put_link(). -+ */ -+ -+struct au_symlink { -+ union { -+ struct hlist_node hlist; -+ struct rcu_head rcu; -+ }; -+ -+ struct inode *h_inode; -+ void *h_cookie; -+}; -+ -+static void au_symlink_add(struct super_block *sb, struct au_symlink *slink, -+ struct inode *h_inode, void *cookie) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ ihold(h_inode); -+ slink->h_inode = h_inode; -+ slink->h_cookie = cookie; -+ sbinfo = au_sbi(sb); -+ au_sphl_add(&slink->hlist, &sbinfo->si_symlink); -+} -+ -+static void au_symlink_del(struct super_block *sb, struct au_symlink *slink) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ /* do not iput() within rcu */ -+ iput(slink->h_inode); -+ slink->h_inode = NULL; -+ sbinfo = au_sbi(sb); -+ au_sphl_del_rcu(&slink->hlist, &sbinfo->si_symlink); -+ kfree_rcu(slink, rcu); -+} -+ -+static const char *aufs_follow_link(struct dentry *dentry, void **cookie) ++static const char *aufs_get_link(struct dentry *dentry, struct inode *inode, ++ struct delayed_call *done) +{ + const char *ret; -+ struct inode *inode, *h_inode; + struct dentry *h_dentry; -+ struct au_symlink *slink; ++ struct inode *h_inode; + int err; + aufs_bindex_t bindex; + + ret = NULL; /* suppress a warning */ ++ err = -ECHILD; ++ if (!dentry) ++ goto out; ++ + err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN); + if (unlikely(err)) + goto out; @@ -19557,12 +19583,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + inode = d_inode(dentry); + bindex = au_ibstart(inode); + h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(!h_inode->i_op->follow_link)) -+ goto out_unlock; -+ -+ err = -ENOMEM; -+ slink = kmalloc(sizeof(*slink), GFP_NOFS); -+ if (unlikely(!slink)) ++ if (unlikely(!h_inode->i_op->get_link)) + goto out_unlock; + + err = -EBUSY; @@ -19576,28 +19597,20 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + h_dentry = d_find_any_alias(h_inode); + if (IS_ERR(h_dentry)) { + err = PTR_ERR(h_dentry); -+ goto out_free; ++ goto out_unlock; + } + } + if (unlikely(!h_dentry)) -+ goto out_free; ++ goto out_unlock; + + err = 0; -+ AuDbg("%pf\n", h_inode->i_op->follow_link); ++ AuDbg("%pf\n", h_inode->i_op->get_link); + AuDbgDentry(h_dentry); -+ ret = h_inode->i_op->follow_link(h_dentry, cookie); ++ ret = h_inode->i_op->get_link(h_dentry, h_inode, done); + dput(h_dentry); ++ if (IS_ERR(ret)) ++ err = PTR_ERR(ret); + -+ if (!IS_ERR_OR_NULL(ret)) { -+ au_symlink_add(inode->i_sb, slink, h_inode, *cookie); -+ *cookie = slink; -+ AuDbg("slink %p\n", slink); -+ goto out_unlock; /* success */ -+ } -+ -+out_free: -+ slink->h_inode = NULL; -+ kfree_rcu(slink, rcu); +out_unlock: + aufs_read_unlock(dentry, AuLock_IR); +out: @@ -19607,21 +19620,6 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + return ret; +} + -+static void aufs_put_link(struct inode *inode, void *cookie) -+{ -+ struct au_symlink *slink; -+ struct inode *h_inode; -+ -+ slink = cookie; -+ AuDbg("slink %p\n", slink); -+ h_inode = slink->h_inode; -+ AuDbg("%pf\n", h_inode->i_op->put_link); -+ AuDbgInode(h_inode); -+ if (h_inode->i_op->put_link) -+ h_inode->i_op->put_link(h_inode, slink->h_cookie); -+ au_symlink_del(inode->i_sb, slink); -+} -+ +/* ---------------------------------------------------------------------- */ + +static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags) @@ -19674,8 +19672,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c +#endif + + .readlink = generic_readlink, -+ .follow_link = aufs_follow_link, -+ .put_link = aufs_put_link, ++ .get_link = aufs_get_link, + + /* .update_time = aufs_update_time */ + }, @@ -19732,7 +19729,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c +}; diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c --- /usr/share/empty/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/i_op_del.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/i_op_del.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,510 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -20246,7 +20243,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c +} diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c --- /usr/share/empty/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/i_op_ren.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/i_op_ren.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,1015 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -21026,7 +21023,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c +static void au_ren_rev_dt(int err, struct au_ren_args *a) +{ + struct dentry *h_d; -+ struct mutex *h_mtx; ++ struct inode *h_inode; + + au_dtime_revert(a->src_dt + AuPARENT); + if (!au_ftest_ren(a->flags, ISSAMEDIR)) @@ -21034,17 +21031,17 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + + if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) { + h_d = a->src_dt[AuCHILD].dt_h_path.dentry; -+ h_mtx = &d_inode(h_d)->i_mutex; -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ h_inode = d_inode(h_d); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + au_dtime_revert(a->src_dt + AuCHILD); -+ mutex_unlock(h_mtx); ++ inode_unlock(h_inode); + + if (au_ftest_ren(a->flags, DT_DSTDIR)) { + h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; -+ h_mtx = &d_inode(h_d)->i_mutex; -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ h_inode = d_inode(h_d); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + au_dtime_revert(a->dst_dt + AuCHILD); -+ mutex_unlock(h_mtx); ++ inode_unlock(h_inode); + } + } +} @@ -21265,7 +21262,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c +} diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig --- /usr/share/empty/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/Kconfig 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/Kconfig 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,185 @@ +config AUFS_FS + tristate "Aufs (Advanced multi layered unification filesystem) support" @@ -21454,7 +21451,7 @@ diff -urN /usr/share/empty/fs/aufs/Kconfig linux/fs/aufs/Kconfig +endif diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c --- /usr/share/empty/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/loop.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/loop.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -21604,7 +21601,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c +} diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h --- /usr/share/empty/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/loop.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/loop.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -21660,7 +21657,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.h linux/fs/aufs/loop.h +#endif /* __AUFS_LOOP_H__ */ diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk --- /usr/share/empty/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/magic.mk 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/magic.mk 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,30 @@ + +# defined in ${srctree}/fs/fuse/inode.c @@ -21694,7 +21691,7 @@ diff -urN /usr/share/empty/fs/aufs/magic.mk linux/fs/aufs/magic.mk +endif diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile --- /usr/share/empty/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/Makefile 2016-02-28 11:26:32.569971135 +0100 ++++ linux/fs/aufs/Makefile 2016-04-24 18:32:51.390353525 +0200 @@ -0,0 +1,44 @@ + +include ${src}/magic.mk @@ -21742,7 +21739,7 @@ diff -urN /usr/share/empty/fs/aufs/Makefile linux/fs/aufs/Makefile +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c --- /usr/share/empty/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/module.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/module.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -21967,7 +21964,7 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c +module_exit(aufs_exit); diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h --- /usr/share/empty/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/module.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/module.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -22076,7 +22073,7 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h +#endif /* __AUFS_MODULE_H__ */ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c --- /usr/share/empty/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/mvdown.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/mvdown.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,703 @@ +/* + * Copyright (C) 2011-2016 Junjiro R. Okajima @@ -22738,14 +22735,14 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c + dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG); + args->parent = dget_parent(dentry); + args->dir = d_inode(args->parent); -+ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT); ++ inode_lock_nested(args->dir, I_MUTEX_PARENT); + dput(args->parent); + if (unlikely(args->parent != dentry->d_parent)) { + AU_MVD_PR(dmsg, "parent dir is moved\n"); + goto out_dir; + } + -+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); ++ inode_lock_nested(inode, I_MUTEX_CHILD); + err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW); + if (unlikely(err)) + goto out_inode; @@ -22769,9 +22766,9 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c + di_write_unlock(args->parent); + aufs_read_unlock(dentry, AuLock_DW); +out_inode: -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); +out_dir: -+ mutex_unlock(&args->dir->i_mutex); ++ inode_unlock(args->dir); +out_free: + e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown)); + if (unlikely(e)) @@ -22783,7 +22780,7 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c +} diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c --- /usr/share/empty/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/opts.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/opts.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,1859 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -24372,16 +24369,16 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) + pr_warn("first branch should be rw\n"); + if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH))) -+ pr_warn("shwh should be used with ro\n"); ++ pr_warn_once("shwh should be used with ro\n"); + } + + if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY) + && !au_opt_test(sbinfo->si_mntflags, XINO)) -+ pr_warn("udba=*notify requires xino\n"); ++ pr_warn_once("udba=*notify requires xino\n"); + + if (au_opt_test(sbinfo->si_mntflags, DIRPERM1)) -+ pr_warn("dirperm1 breaks the protection" -+ " by the permission bits on the lower branch\n"); ++ pr_warn_once("dirperm1 breaks the protection" ++ " by the permission bits on the lower branch\n"); + + err = 0; + fhsm = 0; @@ -24646,7 +24643,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c +} diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h --- /usr/share/empty/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/opts.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/opts.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -24861,7 +24858,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.h linux/fs/aufs/opts.h +#endif /* __AUFS_OPTS_H__ */ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c --- /usr/share/empty/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/plink.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/plink.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,528 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -25065,12 +25062,12 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + struct au_branch *br) +{ + struct dentry *h_dentry; -+ struct mutex *h_mtx; ++ struct inode *h_inode; + -+ h_mtx = &d_inode(h_parent)->i_mutex; -+ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2); ++ h_inode = d_inode(h_parent); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD2); + h_dentry = vfsub_lkup_one(tgtname, h_parent); -+ mutex_unlock(h_mtx); ++ inode_unlock(h_inode); + return h_dentry; +} + @@ -25123,7 +25120,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + struct inode *h_dir, *delegated; + + h_dir = d_inode(h_parent); -+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); ++ inode_lock_nested(h_dir, AuLsc_I_CHILD2); +again: + h_path.dentry = vfsub_lkup_one(tgt, h_parent); + err = PTR_ERR(h_path.dentry); @@ -25159,7 +25156,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c + dput(h_path.dentry); + +out: -+ mutex_unlock(&h_dir->i_mutex); ++ inode_unlock(h_dir); + return err; +} + @@ -25393,7 +25390,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c +} diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c --- /usr/share/empty/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/poll.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/poll.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -25449,7 +25446,7 @@ diff -urN /usr/share/empty/fs/aufs/poll.c linux/fs/aufs/poll.c +} diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c --- /usr/share/empty/fs/aufs/posix_acl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/posix_acl.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/posix_acl.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2014-2016 Junjiro R. Okajima @@ -25524,7 +25521,7 @@ diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c + }, + }; + -+ mutex_lock(&inode->i_mutex); ++ inode_lock(inode); + if (inode->i_ino == AUFS_ROOT_INO) + dentry = dget(inode->i_sb->s_root); + else { @@ -25546,12 +25543,12 @@ diff -urN /usr/share/empty/fs/aufs/posix_acl.c linux/fs/aufs/posix_acl.c + err = 0; + +out: -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); + return err; +} diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c --- /usr/share/empty/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/procfs.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/procfs.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2010-2016 Junjiro R. Okajima @@ -25724,8 +25721,8 @@ diff -urN /usr/share/empty/fs/aufs/procfs.c linux/fs/aufs/procfs.c +} diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c --- /usr/share/empty/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/rdu.c 2016-02-28 11:26:32.573304539 +0100 -@@ -0,0 +1,388 @@ ++++ linux/fs/aufs/rdu.c 2016-04-24 18:32:51.393686895 +0200 +@@ -0,0 +1,389 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -25887,8 +25884,9 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c + dentry = file->f_path.dentry; + inode = d_inode(dentry); +#if 1 -+ mutex_lock(&inode->i_mutex); ++ inode_lock(inode); +#else ++ /* todo: create a new inline func inode_lock_killable() */ + err = mutex_lock_killable(&inode->i_mutex); + AuTraceErr(err); + if (unlikely(err)) @@ -25950,7 +25948,7 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c +out_si: + si_read_unlock(arg.sb); +out_mtx: -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); +out: + AuTraceErr(err); + return err; @@ -26116,7 +26114,7 @@ diff -urN /usr/share/empty/fs/aufs/rdu.c linux/fs/aufs/rdu.c +#endif diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h --- /usr/share/empty/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/rwsem.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/rwsem.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -26311,8 +26309,8 @@ diff -urN /usr/share/empty/fs/aufs/rwsem.h linux/fs/aufs/rwsem.h +#endif /* __AUFS_RWSEM_H__ */ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c --- /usr/share/empty/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sbinfo.c 2016-02-28 11:26:32.573304539 +0100 -@@ -0,0 +1,366 @@ ++++ linux/fs/aufs/sbinfo.c 2016-04-24 18:32:51.393686895 +0200 +@@ -0,0 +1,350 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -26350,19 +26348,14 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c + AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head)); + AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len)); + -+ AuDebugOn(!hlist_empty(&sbinfo->si_symlink.head)); -+ + au_rw_write_lock(&sbinfo->si_rwsem); + au_br_free(sbinfo); + au_rw_write_unlock(&sbinfo->si_rwsem); + -+ AuDebugOn(radix_tree_gang_lookup -+ (&sbinfo->au_si_pid.tree, (void **)&locked, -+ /*first_index*/PID_MAX_DEFAULT - 1, -+ /*max_items*/sizeof(locked)/sizeof(*locked))); -+ + kfree(sbinfo->si_branch); -+ kfree(sbinfo->au_si_pid.bitmap); ++ for (i = 0; i < AU_NPIDMAP; i++) ++ kfree(sbinfo->au_si_pid.pid_bitmap[i]); ++ mutex_destroy(&sbinfo->au_si_pid.pid_mtx); + mutex_destroy(&sbinfo->si_xib_mtx); + AuRwDestroy(&sbinfo->si_rwsem); + @@ -26380,18 +26373,10 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c + if (unlikely(!sbinfo)) + goto out; + -+ BUILD_BUG_ON(sizeof(unsigned long) != -+ sizeof(*sbinfo->au_si_pid.bitmap)); -+ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT), -+ sizeof(*sbinfo->au_si_pid.bitmap), -+ GFP_NOFS); -+ if (unlikely(!sbinfo->au_si_pid.bitmap)) -+ goto out_sbinfo; -+ + /* will be reallocated separately */ + sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); + if (unlikely(!sbinfo->si_branch)) -+ goto out_pidmap; ++ goto out_sbinfo; + + err = sysaufs_si_init(sbinfo); + if (unlikely(err)) @@ -26400,8 +26385,7 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c + au_nwt_init(&sbinfo->si_nowait); + au_rw_init_wlock(&sbinfo->si_rwsem); + au_rw_class(&sbinfo->si_rwsem, &aufs_si); -+ spin_lock_init(&sbinfo->au_si_pid.tree_lock); -+ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL); ++ mutex_init(&sbinfo->au_si_pid.pid_mtx); + + atomic_long_set(&sbinfo->si_ninodes, 0); + atomic_long_set(&sbinfo->si_nfiles, 0); @@ -26418,8 +26402,6 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c + + sbinfo->si_mntflags = au_opts_plink(AuOpt_Def); + -+ au_sphl_init(&sbinfo->si_symlink); -+ + sbinfo->si_xino_jiffy = jiffies; + sbinfo->si_xino_expire + = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC); @@ -26452,8 +26434,6 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c + +out_br: + kfree(sbinfo->si_branch); -+out_pidmap: -+ kfree(sbinfo->au_si_pid.bitmap); +out_sbinfo: + kfree(sbinfo); +out: @@ -26638,50 +26618,52 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c + +/* ---------------------------------------------------------------------- */ + -+int si_pid_test_slow(struct super_block *sb) -+{ -+ void *p; -+ -+ rcu_read_lock(); -+ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid); -+ rcu_read_unlock(); -+ -+ return (long)!!p; -+} -+ -+void si_pid_set_slow(struct super_block *sb) ++static void si_pid_alloc(struct au_si_pid *au_si_pid, int idx) +{ -+ int err; -+ struct au_sbinfo *sbinfo; ++ unsigned long *p; + -+ AuDebugOn(si_pid_test_slow(sb)); ++ BUILD_BUG_ON(sizeof(unsigned long) != ++ sizeof(*au_si_pid->pid_bitmap)); + -+ sbinfo = au_sbi(sb); -+ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL); -+ AuDebugOn(err); -+ spin_lock(&sbinfo->au_si_pid.tree_lock); -+ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid, -+ /*any valid ptr*/sb); -+ spin_unlock(&sbinfo->au_si_pid.tree_lock); -+ AuDebugOn(err); -+ radix_tree_preload_end(); ++ mutex_lock(&au_si_pid->pid_mtx); ++ p = au_si_pid->pid_bitmap[idx]; ++ while (!p) { ++ /* ++ * bad approach. ++ * but keeping 'si_pid_set()' void is more important. ++ */ ++ p = kcalloc(BITS_TO_LONGS(AU_PIDSTEP), ++ sizeof(*au_si_pid->pid_bitmap), ++ GFP_NOFS); ++ if (p) ++ break; ++ cond_resched(); ++ } ++ au_si_pid->pid_bitmap[idx] = p; ++ mutex_unlock(&au_si_pid->pid_mtx); +} + -+void si_pid_clr_slow(struct super_block *sb) ++void si_pid_set(struct super_block *sb) +{ -+ void *p; -+ struct au_sbinfo *sbinfo; -+ -+ AuDebugOn(!si_pid_test_slow(sb)); -+ -+ sbinfo = au_sbi(sb); -+ spin_lock(&sbinfo->au_si_pid.tree_lock); -+ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid); -+ spin_unlock(&sbinfo->au_si_pid.tree_lock); ++ pid_t bit; ++ int idx; ++ unsigned long *bitmap; ++ struct au_si_pid *au_si_pid; ++ ++ si_pid_idx_bit(&idx, &bit); ++ au_si_pid = &au_sbi(sb)->au_si_pid; ++ bitmap = au_si_pid->pid_bitmap[idx]; ++ if (!bitmap) { ++ si_pid_alloc(au_si_pid, idx); ++ bitmap = au_si_pid->pid_bitmap[idx]; ++ } ++ AuDebugOn(test_bit(bit, bitmap)); ++ set_bit(bit, bitmap); ++ /* smp_mb(); */ +} diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h --- /usr/share/empty/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/spl.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/spl.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -26796,7 +26778,7 @@ diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h +#endif /* __AUFS_SPL_H__ */ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c --- /usr/share/empty/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/super.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/super.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,1039 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -27604,7 +27586,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + + sbinfo = au_sbi(sb); + inode = d_inode(root); -+ mutex_lock(&inode->i_mutex); ++ inode_lock(inode); + err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); + if (unlikely(err)) + goto out_mtx; @@ -27627,7 +27609,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + aufs_write_unlock(root); + +out_mtx: -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); +out_opts: + free_page((unsigned long)opts.opt); +out: @@ -27746,7 +27728,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + goto out_root; + + /* lock vfs_inode first, then aufs. */ -+ mutex_lock(&inode->i_mutex); ++ inode_lock(inode); + aufs_write_lock(root); + err = au_opts_mount(sb, &opts); + au_opts_free(&opts); @@ -27758,7 +27740,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c + au_refresh_iop(inode, /*force_getattr*/0); + } + aufs_write_unlock(root); -+ mutex_unlock(&inode->i_mutex); ++ inode_unlock(inode); + if (!err) + goto out_opts; /* success */ + @@ -27839,8 +27821,8 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c +}; diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h --- /usr/share/empty/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/super.h 2016-02-28 11:26:32.573304539 +0100 -@@ -0,0 +1,641 @@ ++++ linux/fs/aufs/super.h 2016-04-24 18:32:51.393686895 +0200 +@@ -0,0 +1,632 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -27930,6 +27912,13 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h +#endif +}; + ++#define AU_PIDSTEP (int)(BITS_TO_LONGS(PID_MAX_DEFAULT) * BITS_PER_LONG) ++#define AU_NPIDMAP (int)DIV_ROUND_UP(PID_MAX_LIMIT, AU_PIDSTEP) ++struct au_si_pid { ++ unsigned long *pid_bitmap[AU_NPIDMAP]; ++ struct mutex pid_mtx; ++}; ++ +struct au_branch; +struct au_sbinfo { + /* nowait tasks in the system-wide workqueue */ @@ -27942,11 +27931,7 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h + struct au_rwsem si_rwsem; + + /* prevent recursive locking in deleting inode */ -+ struct { -+ unsigned long *bitmap; -+ spinlock_t tree_lock; -+ struct radix_tree_root tree; -+ } au_si_pid; ++ struct au_si_pid au_si_pid; + + /* + * dirty approach to protect sb->sb_inodes and ->s_files (gone) from @@ -27986,9 +27971,6 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h + /* include/asm-ia64/siginfo.h defines a macro named si_flags */ + unsigned int si_mntflags; + -+ /* symlink to follow_link() and put_link() */ -+ struct au_sphlhead si_symlink; -+ + /* external inode number (bitmap and translation table) */ + vfs_readf_t si_xread; + vfs_writef_t si_xwrite; @@ -28144,10 +28126,6 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h +int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags); +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); + -+int si_pid_test_slow(struct super_block *sb); -+void si_pid_set_slow(struct super_block *sb); -+void si_pid_clr_slow(struct super_block *sb); -+ +/* wbr_policy.c */ +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; +extern struct au_wbr_create_operations au_wbr_create_ops[]; @@ -28295,48 +28273,43 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h + +/* ---------------------------------------------------------------------- */ + -+static inline pid_t si_pid_bit(void) ++static inline void si_pid_idx_bit(int *idx, pid_t *bit) +{ + /* the origin of pid is 1, but the bitmap's is 0 */ -+ return current->pid - 1; ++ *bit = current->pid - 1; ++ *idx = *bit / AU_PIDSTEP; ++ *bit %= AU_PIDSTEP; +} + +static inline int si_pid_test(struct super_block *sb) +{ + pid_t bit; ++ int idx; ++ unsigned long *bitmap; + -+ bit = si_pid_bit(); -+ if (bit < PID_MAX_DEFAULT) -+ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap); -+ return si_pid_test_slow(sb); -+} -+ -+static inline void si_pid_set(struct super_block *sb) -+{ -+ pid_t bit; -+ -+ bit = si_pid_bit(); -+ if (bit < PID_MAX_DEFAULT) { -+ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap)); -+ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap); -+ /* smp_mb(); */ -+ } else -+ si_pid_set_slow(sb); ++ si_pid_idx_bit(&idx, &bit); ++ bitmap = au_sbi(sb)->au_si_pid.pid_bitmap[idx]; ++ if (bitmap) ++ return test_bit(bit, bitmap); ++ return 0; +} + +static inline void si_pid_clr(struct super_block *sb) +{ + pid_t bit; ++ int idx; ++ unsigned long *bitmap; + -+ bit = si_pid_bit(); -+ if (bit < PID_MAX_DEFAULT) { -+ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap)); -+ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap); -+ /* smp_mb(); */ -+ } else -+ si_pid_clr_slow(sb); ++ si_pid_idx_bit(&idx, &bit); ++ bitmap = au_sbi(sb)->au_si_pid.pid_bitmap[idx]; ++ BUG_ON(!bitmap); ++ AuDebugOn(!test_bit(bit, bitmap)); ++ clear_bit(bit, bitmap); ++ /* smp_mb(); */ +} + ++void si_pid_set(struct super_block *sb); ++ +/* ---------------------------------------------------------------------- */ + +/* lock superblock. mainly for entry point functions */ @@ -28484,7 +28457,7 @@ diff -urN /usr/share/empty/fs/aufs/super.h linux/fs/aufs/super.h +#endif /* __AUFS_SUPER_H__ */ diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c --- /usr/share/empty/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sysaufs.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/sysaufs.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -28592,7 +28565,7 @@ diff -urN /usr/share/empty/fs/aufs/sysaufs.c linux/fs/aufs/sysaufs.c +} diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h --- /usr/share/empty/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sysaufs.h 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/sysaufs.h 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -28697,7 +28670,7 @@ diff -urN /usr/share/empty/fs/aufs/sysaufs.h linux/fs/aufs/sysaufs.h +#endif /* __SYSAUFS_H__ */ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c --- /usr/share/empty/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sysfs.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/sysfs.c 2016-04-24 18:32:51.393686895 +0200 @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -29077,7 +29050,7 @@ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c +} diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c --- /usr/share/empty/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/sysrq.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/sysrq.c 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -29238,7 +29211,7 @@ diff -urN /usr/share/empty/fs/aufs/sysrq.c linux/fs/aufs/sysrq.c +} diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c --- /usr/share/empty/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/vdir.c 2016-02-28 11:26:32.573304539 +0100 ++++ linux/fs/aufs/vdir.c 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,888 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -30130,8 +30103,8 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c +} diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c --- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/vfsub.c 2016-02-28 11:26:32.573304539 +0100 -@@ -0,0 +1,866 @@ ++++ linux/fs/aufs/vfsub.c 2016-04-24 18:32:51.397020264 +0200 +@@ -0,0 +1,884 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -30289,6 +30262,24 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + return err; +} + ++struct dentry *vfsub_lookup_one_len_unlocked(const char *name, ++ struct dentry *parent, int len) ++{ ++ struct path path = { ++ .mnt = NULL ++ }; ++ ++ path.dentry = lookup_one_len_unlocked(name, parent, len); ++ if (IS_ERR(path.dentry)) ++ goto out; ++ if (d_is_positive(path.dentry)) ++ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ ++ ++out: ++ AuTraceErrPtr(path.dentry); ++ return path.dentry; ++} ++ +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, + int len) +{ @@ -31000,8 +30991,8 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c +} diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h --- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/vfsub.h 2016-02-28 11:26:32.576637942 +0100 -@@ -0,0 +1,308 @@ ++++ linux/fs/aufs/vfsub.h 2016-04-24 18:32:51.397020264 +0200 +@@ -0,0 +1,310 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima + * @@ -31056,7 +31047,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h + +/* to debug easier, do not make them inlined functions */ +#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) -+#define IMustLock(i) MtxMustLock(&(i)->i_mutex) ++#define IMustLock(i) AuDebugOn(!inode_is_locked(i)) + +/* ---------------------------------------------------------------------- */ + @@ -31103,6 +31094,8 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h + struct vfsub_aopen_args *args, struct au_branch *br); +int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); + ++struct dentry *vfsub_lookup_one_len_unlocked(const char *name, ++ struct dentry *parent, int len); +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, + int len); + @@ -31312,7 +31305,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h +#endif /* __AUFS_VFSUB_H__ */ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c --- /usr/share/empty/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/wbr_policy.c 2016-02-28 11:26:32.576637942 +0100 ++++ linux/fs/aufs/wbr_policy.c 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,765 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -31456,17 +31449,17 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst) + au_fset_cpdown(*flags, PARENT_OPQ); + h_inode = d_inode(h_path.dentry); -+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + if (au_ftest_cpdown(*flags, WHED)) { + err = au_cpdown_dir_opq(dentry, bdst, flags); + if (unlikely(err)) { -+ mutex_unlock(&h_inode->i_mutex); ++ inode_unlock(h_inode); + goto out_dir; + } + } + + err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart)); -+ mutex_unlock(&h_inode->i_mutex); ++ inode_unlock(h_inode); + if (unlikely(err)) + goto out_opq; + @@ -31487,9 +31480,9 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + /* revert */ +out_opq: + if (au_ftest_cpdown(*flags, DIROPQ)) { -+ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(h_inode, AuLsc_I_CHILD); + rerr = au_diropq_remove(dentry, bdst); -+ mutex_unlock(&h_inode->i_mutex); ++ inode_unlock(h_inode); + if (unlikely(rerr)) { + AuIOErr("failed removing diropq for %pd b%d (%d)\n", + dentry, bdst, rerr); @@ -32081,7 +32074,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c +}; diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c --- /usr/share/empty/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/whout.c 2016-02-28 11:26:32.576637942 +0100 ++++ linux/fs/aufs/whout.c 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,1060 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -33027,7 +33020,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + + br = au_sbr(dir->i_sb, bindex); + wh_inode = d_inode(wh_dentry); -+ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD); ++ inode_lock_nested(wh_inode, AuLsc_I_CHILD); + + /* + * someone else might change some whiteouts while we were sleeping. @@ -33049,7 +33042,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + if (unlikely(wkq_err)) + err = wkq_err; + } -+ mutex_unlock(&wh_inode->i_mutex); ++ inode_unlock(wh_inode); + + if (!err) { + h_tmp.dentry = wh_dentry; @@ -33085,7 +33078,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + struct au_hinode *hdir; + + /* rmdir by nfsd may cause deadlock with this i_mutex */ -+ /* mutex_lock(&a->dir->i_mutex); */ ++ /* inode_lock(a->dir); */ + err = -EROFS; + sb = a->dir->i_sb; + si_read_lock(sb, !AuLock_FLUSH); @@ -33115,7 +33108,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + dput(h_parent); + ii_write_unlock(a->dir); +out: -+ /* mutex_unlock(&a->dir->i_mutex); */ ++ /* inode_unlock(a->dir); */ + au_whtmp_rmdir_free(a); + si_read_unlock(sb); + au_nwt_done(&au_sbi(sb)->si_nowait); @@ -33145,7 +33138,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c +} diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h --- /usr/share/empty/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/whout.h 2016-02-28 11:26:32.576637942 +0100 ++++ linux/fs/aufs/whout.h 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -33234,7 +33227,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.h linux/fs/aufs/whout.h +#endif /* __AUFS_WHOUT_H__ */ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c --- /usr/share/empty/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/wkq.c 2016-02-28 11:26:32.576637942 +0100 ++++ linux/fs/aufs/wkq.c 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -33451,7 +33444,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c +} diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h --- /usr/share/empty/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/wkq.h 2016-02-28 11:26:32.576637942 +0100 ++++ linux/fs/aufs/wkq.h 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -33546,7 +33539,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h +#endif /* __AUFS_WKQ_H__ */ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c --- /usr/share/empty/fs/aufs/xattr.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/xattr.c 2016-02-28 11:26:32.576637942 +0100 ++++ linux/fs/aufs/xattr.c 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2014-2016 Junjiro R. Okajima @@ -33638,9 +33631,9 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c + + /* unlock it temporary */ + h_idst = d_inode(h_dst); -+ mutex_unlock(&h_idst->i_mutex); ++ inode_unlock(h_idst); + err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0); -+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2); ++ inode_lock_nested(h_idst, AuLsc_I_CHILD2); + if (unlikely(err)) { + if (verbose || au_debug_test()) + pr_err("%s, err %d\n", name, err); @@ -33663,9 +33656,9 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c + /* there should not be the parent-child relationship between them */ + h_isrc = d_inode(h_src); + h_idst = d_inode(h_dst); -+ mutex_unlock(&h_idst->i_mutex); -+ mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD); -+ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2); ++ inode_unlock(h_idst); ++ inode_lock_nested(h_isrc, AuLsc_I_CHILD); ++ inode_lock_nested(h_idst, AuLsc_I_CHILD2); + unlocked = 0; + + /* some filesystems don't list POSIX ACL, for example tmpfs */ @@ -33690,7 +33683,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c + goto out; + err = vfs_listxattr(h_src, p, ssz); + } -+ mutex_unlock(&h_isrc->i_mutex); ++ inode_unlock(h_isrc); + unlocked = 1; + AuDbg("err %d, ssz %zd\n", err, ssz); + if (unlikely(err < 0)) @@ -33732,7 +33725,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c + kfree(o); +out: + if (!unlocked) -+ mutex_unlock(&h_isrc->i_mutex); ++ inode_unlock(h_isrc); + AuTraceErr(err); + return err; +} @@ -33894,7 +33887,7 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c +#endif diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c --- /usr/share/empty/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/xino.c 2016-02-28 11:26:32.576637942 +0100 ++++ linux/fs/aufs/xino.c 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,1318 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -34128,7 +34121,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c +struct au_xino_lock_dir { + struct au_hinode *hdir; + struct dentry *parent; -+ struct mutex *mtx; ++ struct inode *dir; +}; + +static void au_xino_lock_dir(struct super_block *sb, struct file *xino, @@ -34146,8 +34139,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT); + } else { + ldir->parent = dget_parent(xino->f_path.dentry); -+ ldir->mtx = &d_inode(ldir->parent)->i_mutex; -+ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT); ++ ldir->dir = d_inode(ldir->parent); ++ inode_lock_nested(ldir->dir, AuLsc_I_PARENT); + } +} + @@ -34156,7 +34149,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + if (ldir->hdir) + au_hn_imtx_unlock(ldir->hdir); + else { -+ mutex_unlock(ldir->mtx); ++ inode_unlock(ldir->dir); + dput(ldir->parent); + } +} @@ -34671,13 +34664,13 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + inode = file_inode(file); + h_parent = dget_parent(file->f_path.dentry); + h_dir = d_inode(h_parent); -+ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ inode_lock_nested(h_dir, AuLsc_I_PARENT); + /* mnt_want_write() is unnecessary here */ + /* no delegation since it is just created */ + if (inode->i_nlink) + err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, + /*force*/0); -+ mutex_unlock(&h_dir->i_mutex); ++ inode_unlock(h_dir); + dput(h_parent); + if (unlikely(err)) { + if (!silent) @@ -35112,14 +35105,14 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + + au_opt_set(sbinfo->si_mntflags, XINO); + dir = d_inode(parent); -+ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); ++ inode_lock_nested(dir, AuLsc_I_PARENT); + /* mnt_want_write() is unnecessary here */ + err = au_xino_set_xib(sb, xino->file); + if (!err) + err = au_xigen_set(sb, xino->file); + if (!err) + err = au_xino_set_br(sb, xino->file); -+ mutex_unlock(&dir->i_mutex); ++ inode_unlock(dir); + if (!err) + goto out; /* success */ + @@ -35216,7 +35209,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c +} diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h --- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/include/uapi/linux/aufs_type.h 2016-02-28 11:26:32.576637942 +0100 ++++ linux/include/uapi/linux/aufs_type.h 2016-04-24 18:32:51.397020264 +0200 @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2005-2016 Junjiro R. Okajima @@ -35259,7 +35252,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin + +#include + -+#define AUFS_VERSION "4.4-20160223" ++#define AUFS_VERSION "4.5-20160328" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -35637,10 +35630,10 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin +#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int) + +#endif /* __AUFS_TYPE_H__ */ -aufs4.4 loopback patch +aufs4.5 loopback patch diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index abfdd2b..a2e3c43 100644 +index 0b816b2..86dd454 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -556,7 +556,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq) @@ -35819,7 +35812,7 @@ index fb2237c..c3888c5 100644 unsigned lo_blocksize; void *key_data; diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c -index 2baacd7..22bcb89 100644 +index ac1304a..0cefd8a 100644 --- a/fs/aufs/f_op.c +++ b/fs/aufs/f_op.c @@ -399,7 +399,7 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, @@ -35881,7 +35874,7 @@ index 48bf070..66afec7 100644 #endif /* __KERNEL__ */ diff --git a/fs/aufs/super.c b/fs/aufs/super.c -index b41d789..51d2fb9 100644 +index 7928a50..9466cc9 100644 --- a/fs/aufs/super.c +++ b/fs/aufs/super.c @@ -832,7 +832,10 @@ static const struct super_operations aufs_sop = { @@ -35897,10 +35890,10 @@ index b41d789..51d2fb9 100644 /* ---------------------------------------------------------------------- */ diff --git a/include/linux/fs.h b/include/linux/fs.h -index 8d48506..5246785 100644 +index 99fc2bd..842a2e0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1719,6 +1719,10 @@ struct super_operations { +@@ -1759,6 +1759,10 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); -- 2.44.0