From 9f237c513c6235e85fb8c1eab1c003aeb434b70f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= Date: Thu, 27 Dec 2018 13:21:04 +0100 Subject: [PATCH] - update aufs patch --- kernel-aufs4.patch | 714 +++++++++++++++++++++++++++------------------ 1 file changed, 435 insertions(+), 279 deletions(-) diff --git a/kernel-aufs4.patch b/kernel-aufs4.patch index a25984be..01990861 100644 --- a/kernel-aufs4.patch +++ b/kernel-aufs4.patch @@ -26,10 +26,10 @@ SPDX-License-Identifier: GPL-2.0 aufs4.x-rcN base patch diff --git a/MAINTAINERS b/MAINTAINERS -index 6ac000c..16404bb 100644 +index 8119141..5e84420 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -2605,6 +2605,19 @@ F: include/linux/audit.h +@@ -2590,6 +2590,19 @@ F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -50,10 +50,10 @@ index 6ac000c..16404bb 100644 M: Miguel Ojeda Sandonis S: Maintained diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index ea9debf..9e534a3 100644 +index cb0cc86..470dd02 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -739,6 +739,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -738,6 +738,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, return error; } @@ -79,10 +79,10 @@ index ea9debf..9e534a3 100644 static ssize_t loop_attr_show(struct device *dev, char *page, diff --git a/fs/dcache.c b/fs/dcache.c -index 2e7e8d8..9f57bd8 100644 +index 2593153..6369b30 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1238,7 +1238,7 @@ enum d_walk_ret { +@@ -1224,7 +1224,7 @@ enum d_walk_ret { * * The @enter() callbacks are called with d_lock held. */ @@ -92,7 +92,7 @@ index 2e7e8d8..9f57bd8 100644 { struct dentry *this_parent; diff --git a/fs/fcntl.c b/fs/fcntl.c -index 4137d96..c91b3e3 100644 +index 0831851..78234ee 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -32,7 +32,7 @@ @@ -114,10 +114,10 @@ index 4137d96..c91b3e3 100644 return error; diff --git a/fs/inode.c b/fs/inode.c -index 42f6d25..fa6ae6a 100644 +index 35d2108..d2395eb 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -1657,7 +1657,7 @@ EXPORT_SYMBOL(generic_update_time); +@@ -1660,7 +1660,7 @@ EXPORT_SYMBOL(generic_update_time); * This does the actual work of updating an inodes time or version. Must have * had called mnt_want_write() before calling this. */ @@ -127,7 +127,7 @@ index 42f6d25..fa6ae6a 100644 int (*update_time)(struct inode *, struct timespec64 *, int); diff --git a/fs/namespace.c b/fs/namespace.c -index 9918655..72c93f3 100644 +index a7f9126..46ed643 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -770,6 +770,12 @@ static inline int check_mnt(struct mount *mnt) @@ -144,7 +144,7 @@ index 9918655..72c93f3 100644 * vfsmount lock must be held for write */ diff --git a/fs/read_write.c b/fs/read_write.c -index 8a2737f..42f64cc 100644 +index 58f3053..a2a55ea 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -489,6 +489,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, @@ -177,10 +177,10 @@ index 8a2737f..42f64cc 100644 { mm_segment_t old_fs; diff --git a/fs/splice.c b/fs/splice.c -index b3daa97..1dd7f96 100644 +index de2ede0..5dcf77b 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -838,8 +838,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); +@@ -837,8 +837,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); /* * Attempt to initiate a splice from pipe to file. */ @@ -191,7 +191,7 @@ index b3daa97..1dd7f96 100644 { ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -@@ -855,9 +855,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -854,9 +854,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. */ @@ -218,10 +218,10 @@ index b54e054..2860782 100644 if (wait) sync_inodes_sb(sb); diff --git a/include/linux/fs.h b/include/linux/fs.h -index 897eae8..7fb92a9 100644 +index c95c080..0e44705 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1286,6 +1286,7 @@ extern void fasync_free(struct fasync_struct *); +@@ -1305,6 +1305,7 @@ extern void fasync_free(struct fasync_struct *); /* can be called from interrupts */ extern void kill_fasync(struct fasync_struct **, int, int); @@ -229,7 +229,7 @@ index 897eae8..7fb92a9 100644 extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); extern int f_setown(struct file *filp, unsigned long arg, int force); extern void f_delown(struct file *filp); -@@ -1747,6 +1748,7 @@ struct file_operations { +@@ -1797,6 +1798,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); @@ -237,7 +237,7 @@ index 897eae8..7fb92a9 100644 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); -@@ -1818,6 +1820,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, +@@ -1867,6 +1869,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, struct iovec *fast_pointer, struct iovec **ret_pointer); @@ -250,7 +250,7 @@ index 897eae8..7fb92a9 100644 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); -@@ -2243,6 +2251,7 @@ extern int current_umask(void); +@@ -2292,6 +2300,7 @@ extern int current_umask(void); extern void ihold(struct inode * inode); extern void iput(struct inode *); extern int generic_update_time(struct inode *, struct timespec64 *, int); @@ -258,7 +258,7 @@ index 897eae8..7fb92a9 100644 /* /sys/fs */ extern struct kobject *fs_kobj; -@@ -2530,6 +2539,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb) +@@ -2579,6 +2588,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb) return false; } #endif @@ -267,10 +267,10 @@ index 897eae8..7fb92a9 100644 extern const struct file_operations def_blk_fops; extern const struct file_operations def_chr_fops; diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h -index b0d0b51..f73ffaa 100644 +index 1fd82ff..a5ccac5 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h -@@ -313,6 +313,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, +@@ -308,6 +308,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, return lock->key == key; } @@ -279,7 +279,7 @@ index b0d0b51..f73ffaa 100644 /* * Acquire a lock. * -@@ -439,6 +441,7 @@ struct lockdep_map { }; +@@ -434,6 +436,7 @@ struct lockdep_map { }; #define lockdep_depth(tsk) (0) @@ -322,12 +322,12 @@ index 74b4911..19789fb 100644 + unsigned int flags); #endif diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index dd13f86..fa6f559 100644 +index 1efada2..447bc0b 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -140,7 +140,7 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES]; unsigned long nr_lock_classes; - static struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; + struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; -static inline struct lock_class *hlock_class(struct held_lock *hlock) +inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) @@ -346,7 +346,7 @@ SPDX-License-Identifier: GPL-2.0 aufs4.x-rcN mmap patch diff --git a/fs/proc/base.c b/fs/proc/base.c -index 7e9f07bf..3ab5901 100644 +index ce34654..28508b1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2016,7 +2016,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) @@ -375,7 +375,7 @@ index 3b63be6..fb9913b 100644 ino = inode->i_ino; } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 5ea1d64..7865a470 100644 +index 47c3764..e37e4b5 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -305,7 +305,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) @@ -390,7 +390,7 @@ index 5ea1d64..7865a470 100644 dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; -@@ -1727,7 +1730,7 @@ static int show_numa_map(struct seq_file *m, void *v) +@@ -1729,7 +1732,7 @@ static int show_numa_map(struct seq_file *m, void *v) struct proc_maps_private *proc_priv = &numa_priv->proc_maps; struct vm_area_struct *vma = v; struct numa_maps *md = &numa_priv->md; @@ -416,10 +416,10 @@ index 0b63d68..400d1c5 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 0416a72..4a298a9 100644 +index 5411de9..b3cd025 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -1440,6 +1440,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, +@@ -1460,6 +1460,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, unmap_mapping_range(mapping, holebegin, holelen, 0); } @@ -469,10 +469,10 @@ index 5ed8f62..0122975 100644 atomic_long_t swap_readahead_info; diff --git a/kernel/fork.c b/kernel/fork.c -index f0b5847..fa562c3 100644 +index 07cddff..d837e55 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -505,7 +505,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, +@@ -546,7 +546,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, struct inode *inode = file_inode(file); struct address_space *mapping = file->f_mapping; @@ -482,7 +482,7 @@ index f0b5847..fa562c3 100644 atomic_dec(&inode->i_writecount); i_mmap_lock_write(mapping); diff --git a/mm/Makefile b/mm/Makefile -index 26ef77a..b2869af 100644 +index d210cc9..e77e80c 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ @@ -493,12 +493,12 @@ index 26ef77a..b2869af 100644 + prfile.o debug.o $(mmu-y) obj-y += init-mm.o - + obj-y += memblock.o diff --git a/mm/filemap.c b/mm/filemap.c -index 52517f2..250f675 100644 +index 81adec8..8507cec 100644 --- a/mm/filemap.c +++ b/mm/filemap.c -@@ -2700,7 +2700,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) +@@ -2609,7 +2609,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) vm_fault_t ret = VM_FAULT_LOCKED; sb_start_pagefault(inode->i_sb); @@ -508,7 +508,7 @@ index 52517f2..250f675 100644 if (page->mapping != inode->i_mapping) { unlock_page(page); diff --git a/mm/mmap.c b/mm/mmap.c -index f7cd9cb..515e88a 100644 +index 6c04292..f3629c1 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -180,7 +180,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) @@ -520,7 +520,7 @@ index f7cd9cb..515e88a 100644 mpol_put(vma_policy(vma)); vm_area_free(vma); return next; -@@ -905,7 +905,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, +@@ -929,7 +929,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, if (remove_next) { if (file) { uprobe_munmap(next, next->vm_start, next->vm_end); @@ -529,7 +529,7 @@ index f7cd9cb..515e88a 100644 } if (next->anon_vma) anon_vma_merge(vma, next); -@@ -1821,8 +1821,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, +@@ -1845,8 +1845,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, return addr; unmap_and_free_vma: @@ -539,7 +539,7 @@ index f7cd9cb..515e88a 100644 /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2641,7 +2641,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2665,7 +2665,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, goto out_free_mpol; if (new->vm_file) @@ -548,7 +548,7 @@ index f7cd9cb..515e88a 100644 if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); -@@ -2660,7 +2660,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2684,7 +2684,7 @@ 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) @@ -557,7 +557,7 @@ index f7cd9cb..515e88a 100644 unlink_anon_vmas(new); out_free_mpol: mpol_put(vma_policy(new)); -@@ -2822,7 +2822,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2874,7 +2874,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, struct vm_area_struct *vma; unsigned long populate = 0; unsigned long ret = -EINVAL; @@ -566,7 +566,7 @@ index f7cd9cb..515e88a 100644 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", current->comm, current->pid); -@@ -2897,10 +2897,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2949,10 +2949,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, } } @@ -595,7 +595,7 @@ index f7cd9cb..515e88a 100644 out: up_write(&mm->mmap_sem); if (populate) -@@ -3206,7 +3223,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -3258,7 +3275,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) @@ -605,7 +605,7 @@ index f7cd9cb..515e88a 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 e4aac33..b27b200 100644 +index 749276b..d56f8f2 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -625,7 +625,7 @@ static void __put_nommu_region(struct vm_region *region) @@ -740,10 +740,10 @@ SPDX-License-Identifier: GPL-2.0 aufs4.x-rcN standalone patch diff --git a/fs/dcache.c b/fs/dcache.c -index 9f57bd8..328a136 100644 +index 6369b30..df4a5fe 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1343,6 +1343,7 @@ void d_walk(struct dentry *parent, void *data, +@@ -1329,6 +1329,7 @@ void d_walk(struct dentry *parent, void *data, seq = 1; goto again; } @@ -751,7 +751,7 @@ index 9f57bd8..328a136 100644 struct check_mount { struct vfsmount *mnt; -@@ -2837,6 +2838,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) +@@ -2817,6 +2818,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) write_sequnlock(&rename_lock); } @@ -760,7 +760,7 @@ index 9f57bd8..328a136 100644 /** * d_ancestor - search for an ancestor diff --git a/fs/exec.c b/fs/exec.c -index 1ebf6e5..a72c294 100644 +index fc281b7..65eaaca 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -109,6 +109,7 @@ bool path_noexec(const struct path *path) @@ -772,7 +772,7 @@ index 1ebf6e5..a72c294 100644 #ifdef CONFIG_USELIB /* diff --git a/fs/fcntl.c b/fs/fcntl.c -index c91b3e3..7751309 100644 +index 78234ee..2072f69 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -85,6 +85,7 @@ int setfl(int fd, struct file * filp, unsigned long arg) @@ -812,10 +812,10 @@ index e49af4c..569020f 100644 void __init files_init(void) { diff --git a/fs/inode.c b/fs/inode.c -index fa6ae6a..69d4a6c 100644 +index d2395eb..b8be7be 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -1666,6 +1666,7 @@ int update_time(struct inode *inode, struct timespec64 *time, int flags) +@@ -1669,6 +1669,7 @@ int update_time(struct inode *inode, struct timespec64 *time, int flags) return update_time(inode, time, flags); } @@ -824,7 +824,7 @@ index fa6ae6a..69d4a6c 100644 /** * touch_atime - update the access time diff --git a/fs/namespace.c b/fs/namespace.c -index 72c93f3..c49803c 100644 +index 46ed643..44502c2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -437,6 +437,7 @@ void __mnt_drop_write(struct vfsmount *mnt) @@ -843,7 +843,7 @@ index 72c93f3..c49803c 100644 /* * vfsmount lock must be held for write -@@ -1832,6 +1834,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, +@@ -1844,6 +1846,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, } return 0; } @@ -888,10 +888,10 @@ index c03b836..817f22c 100644 int fsnotify_fasync(int fd, struct file *file, int on) { diff --git a/fs/notify/mark.c b/fs/notify/mark.c -index 59cdb27..ce365c7 100644 +index d2dd16c..cf709b7 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c -@@ -263,6 +263,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) +@@ -289,6 +289,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) queue_delayed_work(system_unbound_wq, &reaper_work, FSNOTIFY_REAPER_DELAY); } @@ -899,7 +899,7 @@ index 59cdb27..ce365c7 100644 /* * Get mark reference when we found the mark via lockless traversal of object -@@ -417,6 +418,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, +@@ -443,6 +444,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, mutex_unlock(&group->mark_mutex); fsnotify_free_mark(mark); } @@ -907,7 +907,7 @@ index 59cdb27..ce365c7 100644 /* * Sorting function for lists of fsnotify marks. -@@ -632,6 +634,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp, +@@ -658,6 +660,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp, mutex_unlock(&group->mark_mutex); return ret; } @@ -915,7 +915,7 @@ index 59cdb27..ce365c7 100644 /* * Given a list of marks, find the mark associated with given group. If found -@@ -754,6 +757,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, +@@ -781,6 +784,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, fsnotify_get_group(group); mark->group = group; } @@ -936,7 +936,7 @@ index 0285ce7..cb81623 100644 long vfs_truncate(const struct path *path, loff_t length) { diff --git a/fs/read_write.c b/fs/read_write.c -index 42f64cc..d9cb969 100644 +index a2a55ea..a1366ed 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -459,6 +459,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) @@ -972,10 +972,10 @@ index 42f64cc..d9cb969 100644 static inline loff_t file_pos_read(struct file *file) { diff --git a/fs/splice.c b/fs/splice.c -index 1dd7f96..a5e3bcb 100644 +index 5dcf77b..63fe265 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -851,6 +851,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -850,6 +850,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, return splice_write(pipe, out, ppos, len, flags); } @@ -983,7 +983,7 @@ index 1dd7f96..a5e3bcb 100644 /* * Attempt to initiate a splice from a file to a pipe. -@@ -880,6 +881,7 @@ long do_splice_to(struct file *in, loff_t *ppos, +@@ -879,6 +880,7 @@ long do_splice_to(struct file *in, loff_t *ppos, return splice_read(in, ppos, pipe, len, flags); } @@ -1016,7 +1016,7 @@ index 0d6a6a4..7ce4701 100644 ssize_t __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index fa6f559..7ac19ef 100644 +index 447bc0b..4e7581c 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -151,6 +151,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) @@ -1037,10 +1037,10 @@ index 0fef395..83fb1ec 100644 } +EXPORT_SYMBOL_GPL(task_work_run); diff --git a/security/commoncap.c b/security/commoncap.c -index 2e489d6..1e146da 100644 +index 18a4fdf..e49f723 100644 --- a/security/commoncap.c +++ b/security/commoncap.c -@@ -1336,12 +1336,14 @@ int cap_mmap_addr(unsigned long addr) +@@ -1333,12 +1333,14 @@ int cap_mmap_addr(unsigned long addr) } return ret; } @@ -1073,10 +1073,10 @@ index cd97929..424fd23 100644 } +EXPORT_SYMBOL_GPL(__devcgroup_check_permission); diff --git a/security/security.c b/security/security.c -index 736e78d..b314539 100644 +index 04d173e..470af62 100644 --- a/security/security.c +++ b/security/security.c -@@ -542,6 +542,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) +@@ -553,6 +553,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) return 0; return call_int_hook(path_rmdir, 0, dir, dentry); } @@ -1084,7 +1084,7 @@ index 736e78d..b314539 100644 int security_path_unlink(const struct path *dir, struct dentry *dentry) { -@@ -558,6 +559,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry, +@@ -569,6 +570,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry, return 0; return call_int_hook(path_symlink, 0, dir, dentry, old_name); } @@ -1092,7 +1092,7 @@ index 736e78d..b314539 100644 int security_path_link(struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry) -@@ -566,6 +568,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir, +@@ -577,6 +579,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir, return 0; return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); } @@ -1100,7 +1100,7 @@ index 736e78d..b314539 100644 int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry, -@@ -593,6 +596,7 @@ int security_path_truncate(const struct path *path) +@@ -604,6 +607,7 @@ int security_path_truncate(const struct path *path) return 0; return call_int_hook(path_truncate, 0, path); } @@ -1108,7 +1108,7 @@ index 736e78d..b314539 100644 int security_path_chmod(const struct path *path, umode_t mode) { -@@ -600,6 +604,7 @@ int security_path_chmod(const struct path *path, umode_t mode) +@@ -611,6 +615,7 @@ int security_path_chmod(const struct path *path, umode_t mode) return 0; return call_int_hook(path_chmod, 0, path, mode); } @@ -1116,7 +1116,7 @@ index 736e78d..b314539 100644 int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) { -@@ -607,6 +612,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) +@@ -618,6 +623,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) return 0; return call_int_hook(path_chown, 0, path, uid, gid); } @@ -1124,7 +1124,7 @@ index 736e78d..b314539 100644 int security_path_chroot(const struct path *path) { -@@ -692,6 +698,7 @@ int security_inode_readlink(struct dentry *dentry) +@@ -703,6 +709,7 @@ int security_inode_readlink(struct dentry *dentry) return 0; return call_int_hook(inode_readlink, 0, dentry); } @@ -1132,7 +1132,7 @@ index 736e78d..b314539 100644 int security_inode_follow_link(struct dentry *dentry, struct inode *inode, bool rcu) -@@ -707,6 +714,7 @@ int security_inode_permission(struct inode *inode, int mask) +@@ -718,6 +725,7 @@ int security_inode_permission(struct inode *inode, int mask) return 0; return call_int_hook(inode_permission, 0, inode, mask); } @@ -1140,7 +1140,7 @@ index 736e78d..b314539 100644 int security_inode_setattr(struct dentry *dentry, struct iattr *attr) { -@@ -878,6 +886,7 @@ int security_file_permission(struct file *file, int mask) +@@ -889,6 +897,7 @@ int security_file_permission(struct file *file, int mask) return fsnotify_perm(file, mask); } @@ -1148,7 +1148,7 @@ index 736e78d..b314539 100644 int security_file_alloc(struct file *file) { -@@ -937,6 +946,7 @@ int security_mmap_file(struct file *file, unsigned long prot, +@@ -948,6 +957,7 @@ int security_mmap_file(struct file *file, unsigned long prot, return ret; return ima_file_mmap(file, prot); } @@ -2651,8 +2651,8 @@ 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 2018-10-23 12:33:35.579375203 +0200 -@@ -0,0 +1,394 @@ ++++ linux/Documentation/filesystems/aufs/README 2018-12-27 13:19:17.705082621 +0100 +@@ -0,0 +1,395 @@ + +Aufs4 -- advanced multi layered unification filesystem version 4.x +http://aufs.sf.net @@ -3030,6 +3030,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta +Tomasz Szewczyk made a donation (2016/4). +James Burry made a donation (2016/12). +Carsten Rose made a donation (2018/9). ++Porteus Kiosk made a donation (2018/10). + +Thank you very much. +Donations are always, including future donations, very important and @@ -3115,7 +3116,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 2018-10-23 12:33:35.592708932 +0200 ++++ linux/fs/aufs/branch.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,1422 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -3172,7 +3173,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + + if (br->br_fhsm) { + au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); ++ au_kfree_try_rcu(br->br_fhsm); + } + + key = br->br_dykey; @@ -3187,12 +3188,12 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + lockdep_off(); + path_put(&br->br_path); + lockdep_on(); -+ kfree(wbr); ++ au_kfree_rcu(wbr); + au_lcnt_wait_for_fin(&br->br_nfiles); + au_lcnt_wait_for_fin(&br->br_count); + /* I don't know why, but percpu_refcount requires this */ + /* synchronize_rcu(); */ -+ kfree(br); ++ au_kfree_rcu(br); +} + +/* @@ -3293,13 +3294,13 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + return add_branch; /* success */ + +out_wbr: -+ kfree(add_branch->br_wbr); ++ au_kfree_rcu(add_branch->br_wbr); +out_hnotify: + au_hnotify_fin_br(add_branch); +out_xino: + au_xino_put(add_branch); +out_br: -+ kfree(add_branch); ++ au_kfree_rcu(add_branch); +out: + return ERR_PTR(err); +} @@ -3465,7 +3466,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + br->br_perm = old_perm; + + if (!err && wbr && !au_br_writable(new_perm)) { -+ kfree(wbr); ++ au_kfree_rcu(wbr); + br->br_wbr = NULL; + } + @@ -4492,7 +4493,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + if (br->br_wbr) { + err = au_wbr_init(br, sb, mod->perm); + if (unlikely(err)) { -+ kfree(br->br_wbr); ++ au_kfree_rcu(br->br_wbr); + br->br_wbr = NULL; + } + } @@ -4504,7 +4505,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + if (!au_br_fhsm(mod->perm)) { + /* fhsm --> non-fhsm */ + au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); ++ au_kfree_rcu(br->br_fhsm); + br->br_fhsm = NULL; + } + } else if (au_br_fhsm(mod->perm)) @@ -4516,7 +4517,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c + goto out; /* success */ + +out_bf: -+ kfree(bf); ++ au_kfree_try_rcu(bf); +out: + AuTraceErr(err); + return err; @@ -4541,8 +4542,8 @@ 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 2018-10-23 12:33:35.592708932 +0200 -@@ -0,0 +1,367 @@ ++++ linux/fs/aufs/branch.h 2018-12-27 13:19:17.708416053 +0100 +@@ -0,0 +1,365 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -4594,9 +4595,7 @@ diff -urN /usr/share/empty/fs/aufs/branch.h linux/fs/aufs/branch.h + } xi_nondir; + + struct mutex xi_mtx; /* protects xi_file array */ -+ /* reserved for future use */ -+ /* wait_queue_head_t xi_wq; */ -+ /* atomic_t xi_pending; */ ++ struct hlist_bl_head xi_writing; + + atomic_t xi_truncating; + @@ -4956,8 +4955,8 @@ 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 2018-10-23 12:33:35.596042364 +0200 -@@ -0,0 +1,1444 @@ ++++ linux/fs/aufs/cpup.c 2018-12-27 13:19:17.708416053 +0100 +@@ -0,0 +1,1458 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -5297,9 +5296,11 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + unsigned long blksize; + unsigned char do_kfree; + char *buf; ++ struct super_block *h_sb; + + err = -ENOMEM; -+ blksize = dst->f_path.dentry->d_sb->s_blocksize; ++ h_sb = file_inode(dst)->i_sb; ++ blksize = h_sb->s_blocksize; + if (!blksize || PAGE_SIZE < blksize) + blksize = PAGE_SIZE; + AuDbg("blksize %lu\n", blksize); @@ -5317,9 +5318,10 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + src->f_pos = 0; + dst->f_pos = 0; + err = au_do_copy_file(dst, src, len, buf, blksize); -+ if (do_kfree) -+ kfree(buf); -+ else ++ if (do_kfree) { ++ AuDebugOn(!au_kfree_do_sz_test(blksize)); ++ au_kfree_do_rcu(buf); ++ } else + free_page((unsigned long)buf); + +out: @@ -5350,26 +5352,36 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c +static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len) +{ + int err; ++ loff_t lo; + struct super_block *h_src_sb; + struct inode *h_src_inode; + + h_src_inode = file_inode(src); + h_src_sb = h_src_inode->i_sb; + if (h_src_sb != file_inode(dst)->i_sb -+ || !dst->f_op->clone_file_range) { ++ || !dst->f_op->remap_file_range) { + err = au_do_copy(dst, src, len); + goto out; + } + + if (!au_test_nfs(h_src_sb)) { + inode_unlock_shared(h_src_inode); -+ err = vfsub_clone_file_range(src, dst, len); ++ lo = vfsub_clone_file_range(src, dst, len); + inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); + } else -+ err = vfsub_clone_file_range(src, dst, len); -+ /* older XFS has a condition in cloning */ -+ if (unlikely(err != -EOPNOTSUPP)) ++ lo = vfsub_clone_file_range(src, dst, len); ++ if (lo == len) { ++ err = 0; ++ goto out; /* success */ ++ } else if (lo >= 0) ++ /* todo: possible? */ ++ /* paritially succeeded */ ++ AuDbg("lo %lld, len %lld. Retrying.\n", lo, len); ++ else if (lo != -EOPNOTSUPP) { ++ /* older XFS has a condition in cloning */ ++ err = lo; + goto out; ++ } + + /* the backend fs on NFS may not support cloning */ + err = au_do_copy(dst, src, len); @@ -5393,18 +5405,15 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + struct dentry *dentry; + int force_wr; + struct file *file; -+ void *label; + } *f, file[] = { + { + .bindex = cpg->bsrc, + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, -+ .label = &&out + }, + { + .bindex = cpg->bdst, + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, + .force_wr = !!au_ftest_cpup(cpg->flags, RWDST), -+ .label = &&out_src + } + }; + struct au_branch *br; @@ -5419,9 +5428,13 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + f->dentry = au_h_dptr(cpg->dentry, f->bindex); + f->file = au_h_open(cpg->dentry, f->bindex, f->flags, + /*file*/NULL, f->force_wr); -+ err = PTR_ERR(f->file); -+ if (IS_ERR(f->file)) -+ goto *f->label; ++ if (IS_ERR(f->file)) { ++ err = PTR_ERR(f->file); ++ if (i == SRC) ++ goto out; ++ else ++ goto out_src; ++ } + } + + /* try stopping to update while we copyup */ @@ -5911,7 +5924,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c + } +out_parent: + dput(dst_parent); -+ kfree(a); ++ au_kfree_rcu(a); +out: + return err; +} @@ -6508,8 +6521,8 @@ 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 2018-10-23 12:33:35.596042364 +0200 -@@ -0,0 +1,519 @@ ++++ linux/fs/aufs/dbgaufs.c 2018-12-27 13:19:17.708416053 +0100 +@@ -0,0 +1,526 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -6554,7 +6567,14 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c +static int dbgaufs_xi_release(struct inode *inode __maybe_unused, + struct file *file) +{ -+ kfree(file->private_data); ++ void *p; ++ ++ p = file->private_data; ++ if (p) { ++ /* this is struct dbgaufs_arg */ ++ AuDebugOn(!au_kfree_sz_test(p)); ++ au_kfree_do_rcu(p); ++ } + return 0; +} + @@ -7088,7 +7108,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 2018-08-12 23:43:05.453457863 +0200 ++++ linux/fs/aufs/dcsub.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -7145,7 +7165,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c + return 0; /* success */ + +out_dpages: -+ kfree(dpages->dpages); ++ au_kfree_try_rcu(dpages->dpages); +out: + return err; +} @@ -7158,7 +7178,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c + p = dpages->dpages; + for (i = 0; i < dpages->ndpage; i++) + au_dpage_free(p++); -+ kfree(dpages->dpages); ++ au_kfree_try_rcu(dpages->dpages); +} + +static int au_dpages_append(struct au_dcsub_pages *dpages, @@ -7458,7 +7478,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 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/debug.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,440 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -7798,7 +7818,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c + a->mnt.mnt_sb = sb; + a->fake.br_path.mnt = &a->mnt; + err = do_pri_br(-1, &a->fake); -+ kfree(a); ++ au_kfree_rcu(a); + dpri("dev 0x%x\n", sb->s_dev); + if (err || !au_test_aufs(sb)) + return; @@ -8132,7 +8152,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 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/dentry.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,1153 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -8370,7 +8390,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c + +out_parent: + dput(parent); -+ kfree(args.whname.name); ++ au_kfree_try_rcu(args.whname.name); + if (dirren) + au_dr_lkup_fin(&args); +out: @@ -9289,8 +9309,8 @@ 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 2018-08-12 23:43:05.453457863 +0200 -@@ -0,0 +1,267 @@ ++++ linux/fs/aufs/dentry.h 2018-12-27 13:19:17.708416053 +0100 +@@ -0,0 +1,268 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -9334,6 +9354,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h + aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq; + unsigned char di_tmpfile; /* to allow the different name */ + struct au_hdentry *di_hdentry; ++ struct rcu_head rcu; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -9560,7 +9581,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 2018-08-12 23:43:05.453457863 +0200 ++++ linux/fs/aufs/dinfo.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,554 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -9638,7 +9659,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c + while (bindex++ <= bbot) + au_hdput(p++); + } -+ kfree(dinfo->di_hdentry); ++ au_kfree_try_rcu(dinfo->di_hdentry); + au_cache_free_dinfo(dinfo); +} + @@ -10118,7 +10139,7 @@ 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 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/dir.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,762 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -10279,7 +10300,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c +out: + dput(a->dentry); + au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(arg); ++ au_kfree_try_rcu(arg); +} + +void au_dir_ts(struct inode *dir, aufs_bindex_t bindex) @@ -10315,7 +10336,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + if (unlikely(wkq_err)) { + pr_err("wkq %d\n", wkq_err); + dput(dentry); -+ kfree(arg); ++ au_kfree_try_rcu(arg); + } + +out: @@ -10434,7 +10455,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + }; + err = au_do_open(file, &args); + if (unlikely(err)) -+ kfree(fidir); ++ au_kfree_rcu(fidir); + } + si_read_unlock(sb); + return err; @@ -10470,7 +10491,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c + if (hf->hf_file) + au_hfput(hf, /*execed*/0); + } -+ kfree(fidir); ++ au_kfree_rcu(fidir); + finfo->fi_hdir = NULL; + } + au_finfo_fin(file); @@ -10884,8 +10905,8 @@ 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 2018-08-12 23:43:05.453457863 +0200 -@@ -0,0 +1,132 @@ ++++ linux/fs/aufs/dir.h 2018-12-27 13:19:17.708416053 +0100 +@@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -10932,6 +10953,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h +struct au_vdir_dehstr { + struct hlist_node hash; + struct au_vdir_destr *str; ++ struct rcu_head rcu; +} ____cacheline_aligned_in_smp; + +struct au_vdir_de { @@ -10969,7 +10991,8 @@ diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h + + u64 vd_version; + unsigned int vd_deblk_sz; -+ unsigned long vd_jiffy; ++ unsigned long vd_jiffy; ++ struct rcu_head rcu; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -11020,7 +11043,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/dirren.c linux/fs/aufs/dirren.c --- /usr/share/empty/fs/aufs/dirren.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/dirren.c 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/dirren.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,1316 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -11142,7 +11165,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + hbl = dr->dr_h_ino + i; + /* no spinlock since sbinfo must be write-locked */ + hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode) -+ kfree(ent); ++ au_kfree_rcu(ent); + INIT_HLIST_BL_HEAD(hbl); + } +} @@ -11584,7 +11607,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + *ret = *drinfo; + ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos); + if (unlikely(ssz != len)) { -+ kfree(ret); ++ au_kfree_rcu(ret); + ret = ERR_PTR(-EIO); + AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file); + goto out; @@ -11780,7 +11803,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + +static void au_drinfo_store_work_fin(struct au_drinfo_store *w) +{ -+ kfree(w->fdata); ++ au_kfree_rcu(w->fdata); +} + +static void au_drinfo_store_rev(struct au_drinfo_rev *rev, @@ -11817,7 +11840,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + elm->info_last->oldname, + elm->info_last->oldnamelen); + err = au_drinfo_store_sio(w, /*elm*/NULL); -+ kfree(elm->info_last); ++ au_kfree_rcu(elm->info_last); + } + if (unlikely(err)) + AuIOErr("%d, %s\n", err, w->whname); @@ -11893,7 +11916,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + if (unlikely(err)) { + /* revert all drinfo */ + au_drinfo_store_rev(rev, &work); -+ kfree(rev); ++ au_kfree_try_rcu(rev); + *p = NULL; + } + au_hn_inode_unlock(hdir); @@ -11949,7 +11972,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + /* revert */ + if (!already) + au_dr_hino_del(dr, ent); -+ kfree(ent); ++ au_kfree_rcu(ent); + +out: + AuTraceErr(err); @@ -11966,9 +11989,9 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + elm = rev->elm; + for (nelm = rev->nelm; nelm > 0; nelm--, elm++) { + dput(elm->info_dentry); -+ kfree(elm->info_last); ++ au_kfree_rcu(elm->info_last); + } -+ kfree(rev); ++ au_kfree_try_rcu(rev); +} + +void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev) @@ -12000,10 +12023,10 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + ent = au_dr_hino_find(dr, h_inode->i_ino); + BUG_ON(!ent); + au_dr_hino_del(dr, ent); -+ kfree(ent); ++ au_kfree_rcu(ent); + +out: -+ kfree(rev); ++ au_kfree_try_rcu(rev); + if (unlikely(err)) + pr_err("failed to remove dirren info\n"); +} @@ -12128,7 +12151,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + oldname.name = drinfo->oldname; + if (au_qstreq(w->qname, &oldname)) { + /* the name is renamed back */ -+ kfree(drinfo); ++ au_kfree_rcu(drinfo); + drinfo = NULL; + + infopath.dentry = info_dentry; @@ -12143,7 +12166,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + if (unlikely(e == -EWOULDBLOCK)) + iput(delegated); + } -+ kfree(w->drinfo[bindex]); ++ au_kfree_rcu(w->drinfo[bindex]); + w->drinfo[bindex] = drinfo; + dput(info_dentry); + @@ -12159,8 +12182,8 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + struct au_drinfo **p = drinfo; + + while (n-- > 0) -+ kfree(*drinfo++); -+ kfree(p); ++ au_kfree_rcu(*drinfo++); ++ au_kfree_try_rcu(p); +} + +int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry, @@ -12213,7 +12236,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino); + AuDebugOn(!ent); + au_dr_hino_del(&br->br_dirren, ent); -+ kfree(ent); ++ au_kfree_rcu(ent); + } + goto out; /* success */ + @@ -12244,7 +12267,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.c linux/fs/aufs/dirren.c + if (!drinfo) + goto out; + -+ kfree(lkup->whname.name); ++ au_kfree_try_rcu(lkup->whname.name); + lkup->whname.name = NULL; + lkup->dirren.dr_name.len = drinfo->oldnamelen; + lkup->dirren.dr_name.name = drinfo->oldname; @@ -12484,7 +12507,7 @@ diff -urN /usr/share/empty/fs/aufs/dirren.h linux/fs/aufs/dirren.h +#endif /* __AUFS_DIRREN_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 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/dynop.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -12602,7 +12625,7 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c + + key = container_of(rcu, struct au_dykey, dk_rcu); + DyPrSym(key); -+ kfree(key); ++ au_kfree_rcu(key); +} + +static void dy_free(struct kref *kref) @@ -12730,7 +12753,7 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c + p->set(key, op->dy_hop, au_br_sb(br)); + old = dy_gadd(hbl, key); + if (old) { -+ kfree(key); ++ au_kfree_rcu(key); + key = old; + } + @@ -15077,8 +15100,8 @@ 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 2018-08-12 23:43:05.456791299 +0200 -@@ -0,0 +1,341 @@ ++++ linux/fs/aufs/file.h 2018-12-27 13:19:17.708416053 +0100 +@@ -0,0 +1,342 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -15147,6 +15170,7 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h + + struct hlist_bl_node fi_hlist; + struct file *fi_file; /* very ugly */ ++ struct rcu_head rcu; +} ____cacheline_aligned_in_smp; + +/* ---------------------------------------------------------------------- */ @@ -16872,7 +16896,7 @@ diff -urN /usr/share/empty/fs/aufs/hbl.h linux/fs/aufs/hbl.h +#endif /* __AUFS_HBL_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 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/hfsnotify.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -17032,7 +17056,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c + struct au_br_hfsnotify *hfsn = group->private; + + /* AuDbg("here\n"); */ -+ kfree(hfsn); ++ au_kfree_try_rcu(hfsn); +} + +static int au_hfsn_handle_event(struct fsnotify_group *group, @@ -17128,7 +17152,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c + goto out; /* success */ + +out_hfsn: -+ kfree(hfsn); ++ au_kfree_try_rcu(hfsn); +out: + return err; +} @@ -17229,7 +17253,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 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/hnotify.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,720 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -17774,7 +17798,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c + iput(a->dir); + si_write_unlock(sb); + au_nwt_done(&sbinfo->si_nowait); -+ kfree(a); ++ au_kfree_rcu(a); +} + +/* ---------------------------------------------------------------------- */ @@ -17880,7 +17904,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c + iput(args->h_child_inode); + iput(args->h_dir); + iput(args->dir); -+ kfree(args); ++ au_kfree_rcu(args); + } + +out: @@ -17953,7 +17977,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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/iinfo.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -18238,7 +18262,7 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c + hi++; + } + } -+ kfree(iinfo->ii_hinode); ++ au_kfree_rcu(iinfo->ii_hinode); + AuRwDestroy(&iinfo->ii_rwsem); +} diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c @@ -18775,8 +18799,8 @@ 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 2018-08-12 23:43:05.460124736 +0200 -@@ -0,0 +1,696 @@ ++++ linux/fs/aufs/inode.h 2018-12-27 13:19:17.711749485 +0100 +@@ -0,0 +1,698 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -18816,6 +18840,7 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h + struct fsnotify_mark hn_mark; +#endif + struct inode *hn_aufs_inode; /* no get/put */ ++ struct rcu_head rcu; +#endif +} ____cacheline_aligned_in_smp; + @@ -18856,9 +18881,10 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h +}; + +struct au_icntnr { -+ struct au_iinfo iinfo; -+ struct inode vfs_inode; -+ struct hlist_bl_node plink; ++ struct au_iinfo iinfo; ++ struct inode vfs_inode; ++ struct hlist_bl_node plink; ++ struct rcu_head rcu; +} ____cacheline_aligned_in_smp; + +/* au_pin flags */ @@ -19699,7 +19725,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 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/i_op_add.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,935 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -20063,7 +20089,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + if (!try_aopen) + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_kfree_rcu(a); +out: + return err; +} @@ -20523,7 +20549,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + } + aufs_read_and_write_unlock2(dentry, src_dentry); +out_kfree: -+ kfree(a); ++ au_kfree_rcu(a); +out: + AuTraceErr(err); + return err; @@ -20632,13 +20658,13 @@ diff -urN /usr/share/empty/fs/aufs/i_op_add.c linux/fs/aufs/i_op_add.c + } + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_kfree_rcu(a); +out: + return err; +} 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 2018-10-23 12:33:35.596042364 +0200 ++++ linux/fs/aufs/i_op.c 2018-12-27 13:19:17.708416053 +0100 @@ -0,0 +1,1506 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -21698,7 +21724,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c +out_si: + si_read_unlock(sb); +out_kfree: -+ kfree(a); ++ au_kfree_rcu(a); +out: + AuTraceErr(err); + return err; @@ -21789,7 +21815,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c + di_write_unlock(dentry); + si_read_unlock(sb); +out_kfree: -+ kfree(a); ++ au_kfree_rcu(a); +out: + AuTraceErr(err); + return err; @@ -22148,7 +22174,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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/i_op_del.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,512 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -22547,7 +22573,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c +out_unlock: + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_kfree_rcu(a); +out: + return err; +} @@ -22657,14 +22683,14 @@ diff -urN /usr/share/empty/fs/aufs/i_op_del.c linux/fs/aufs/i_op_del.c +out_unlock: + aufs_read_unlock(dentry, AuLock_DW); +out_free: -+ kfree(a); ++ au_kfree_rcu(a); +out: + AuTraceErr(err); + return err; +} 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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/i_op_ren.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,1249 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -23910,7 +23936,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op_ren.c linux/fs/aufs/i_op_ren.c + iput(a->dst_inode); + if (a->thargs) + au_whtmp_rmdir_free(a->thargs); -+ kfree(a); ++ au_kfree_rcu(a); +out: + AuTraceErr(err); + return err; @@ -24310,7 +24336,7 @@ diff -urN /usr/share/empty/fs/aufs/lcnt.h linux/fs/aufs/lcnt.h +#endif /* __AUFS_LCNT_H__ */ 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 2018-08-12 23:43:05.460124736 +0200 ++++ linux/fs/aufs/loop.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -24458,7 +24484,7 @@ diff -urN /usr/share/empty/fs/aufs/loop.c linux/fs/aufs/loop.c +{ + if (backing_file_func) + symbol_put(loop_backing_file); -+ kfree(au_warn_loopback_array); ++ au_kfree_try_rcu(au_warn_loopback_array); +} 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 @@ -24604,7 +24630,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 2018-08-12 23:43:05.460124736 +0200 ++++ linux/fs/aufs/module.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -24643,7 +24669,7 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c + if (p) { +#if 0 /* unused */ + if (!new_sz) { -+ kfree(p); ++ au_kfree_rcu(p); + p = NULL; + goto out; + } @@ -24667,7 +24693,7 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c + if (q) { + if (p) { + memcpy(q, p, new_sz); -+ kfree(p); ++ au_kfree_try_rcu(p); + } + p = q; + } else @@ -24881,8 +24907,8 @@ 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 2018-08-12 23:43:05.460124736 +0200 -@@ -0,0 +1,102 @@ ++++ linux/fs/aufs/module.h 2018-12-27 13:19:17.711749485 +0100 +@@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -24911,6 +24937,11 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h +#ifdef __KERNEL__ + +#include ++#include "debug.h" ++#include "dentry.h" ++#include "dir.h" ++#include "file.h" ++#include "inode.h" + +struct path; +struct seq_file; @@ -24927,6 +24958,53 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, + int may_shrink); + ++/* ++ * Comparing the size of the object with sizeof(struct rcu_head) ++ * case 1: object is always larger ++ * --> au_kfree_rcu() or au_kfree_do_rcu() ++ * case 2: object is always smaller ++ * --> au_kfree_small() ++ * case 3: object can be any size ++ * --> au_kfree_try_rcu() ++ */ ++ ++static inline void au_kfree_do_rcu(const void *p) ++{ ++ struct { ++ struct rcu_head rcu; ++ } *a = (void *)p; ++ ++ kfree_rcu(a, rcu); ++} ++ ++#define au_kfree_rcu(_p) do { \ ++ typeof(_p) p = (_p); \ ++ BUILD_BUG_ON(sizeof(*p) < sizeof(struct rcu_head)); \ ++ if (p) \ ++ au_kfree_do_rcu(p); \ ++ } while (0) ++ ++#define au_kfree_do_sz_test(sz) (sz >= sizeof(struct rcu_head)) ++#define au_kfree_sz_test(p) (p && au_kfree_do_sz_test(ksize(p))) ++ ++static inline void au_kfree_try_rcu(const void *p) ++{ ++ if (!p) ++ return; ++ if (au_kfree_sz_test(p)) ++ au_kfree_do_rcu(p); ++ else ++ kfree(p); ++} ++ ++static inline void au_kfree_small(const void *p) ++{ ++ if (!p) ++ return; ++ AuDebugOn(au_kfree_sz_test(p)); ++ kfree(p); ++} ++ +static inline int au_kmidx_sub(size_t sz, size_t new_sz) +{ +#ifndef CONFIG_SLOB @@ -24968,11 +25046,23 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h + kmem_cache_create(#type, sizeof(struct type), \ + __alignof__(struct type), AuCacheFlags, ctor) + -+#define AuCacheFuncs(name, index) \ -+static inline struct au_##name *au_cache_alloc_##name(void) \ -+{ return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \ -+static inline void au_cache_free_##name(struct au_##name *p) \ -+{ kmem_cache_free(au_cache[AuCache_##index], p); } ++#define AuCacheFuncs(name, index) \ ++ static inline struct au_##name *au_cache_alloc_##name(void) \ ++ { return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \ ++ static inline void au_cache_free_##name##_norcu(struct au_##name *p) \ ++ { kmem_cache_free(au_cache[AuCache_##index], p); } \ ++ \ ++ static inline void au_cache_free_##name##_rcu_cb(struct rcu_head *rcu) \ ++ { void *p = rcu; \ ++ p -= offsetof(struct au_##name, rcu); \ ++ kmem_cache_free(au_cache[AuCache_##index], p); } \ ++ static inline void au_cache_free_##name##_rcu(struct au_##name *p) \ ++ { BUILD_BUG_ON(sizeof(struct au_##name) < sizeof(struct rcu_head)); \ ++ call_rcu(&p->rcu, au_cache_free_##name##_rcu_cb); } \ ++ \ ++ static inline void au_cache_free_##name(struct au_##name *p) \ ++ { /* au_cache_free_##name##_norcu(p); */ \ ++ au_cache_free_##name##_rcu(p); } + +AuCacheFuncs(dinfo, DINFO); +AuCacheFuncs(icntnr, ICNTNR); @@ -24987,7 +25077,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 2018-08-12 23:43:05.460124736 +0200 ++++ linux/fs/aufs/mvdown.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,705 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -25689,14 +25779,14 @@ diff -urN /usr/share/empty/fs/aufs/mvdown.c linux/fs/aufs/mvdown.c + e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown)); + if (unlikely(e)) + err = -EFAULT; -+ kfree(args); ++ au_kfree_rcu(args); +out: + AuTraceErr(err); + return err; +} 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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/opts.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,1877 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -26960,7 +27050,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + } + } + -+ kfree(a); ++ au_kfree_rcu(a); + dump_opts(opts); + if (unlikely(err)) + au_opts_free(opts); @@ -27390,7 +27480,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c + au_hn_inode_unlock(hdir); + + if (!err && do_free) { -+ kfree(wbr); ++ au_kfree_rcu(wbr); + br->br_wbr = NULL; + } + } @@ -29126,7 +29216,7 @@ 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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/sbinfo.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -29176,13 +29266,13 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c + au_br_free(sbinfo); + au_rw_write_unlock(&sbinfo->si_rwsem); + -+ kfree(sbinfo->si_branch); ++ au_kfree_try_rcu(sbinfo->si_branch); + mutex_destroy(&sbinfo->si_xib_mtx); + AuRwDestroy(&sbinfo->si_rwsem); + + au_lcnt_wait_for_fin(&sbinfo->si_ninodes); + /* si_nfiles is waited too */ -+ kfree(sbinfo); ++ au_kfree_rcu(sbinfo); +} + +int au_si_alloc(struct super_block *sb) @@ -29258,9 +29348,9 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c + return 0; /* success */ + +out_br: -+ kfree(sbinfo->si_branch); ++ au_kfree_try_rcu(sbinfo->si_branch); +out_sbinfo: -+ kfree(sbinfo); ++ au_kfree_rcu(sbinfo); +out: + return err; +} @@ -31291,7 +31381,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 2018-08-12 23:43:05.463458173 +0200 ++++ linux/fs/aufs/sysfs.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -31505,7 +31595,7 @@ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c + if (unlikely(err == PAGE_SIZE)) + err = -EFBIG; + } -+ kfree(seq); ++ au_kfree_rcu(seq); +out_unlock: + si_read_unlock(sb); +out: @@ -31576,7 +31666,7 @@ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c + err = -EFAULT; + +out_seq: -+ kfree(seq); ++ au_kfree_rcu(seq); +out_buf: + free_page((unsigned long)buf); +out: @@ -31832,7 +31922,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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/vdir.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,895 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -31947,7 +32037,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c + struct hlist_node *node; + + hlist_for_each_entry_safe(pos, node, head, wh_hash) -+ kfree(pos); ++ au_kfree_rcu(pos); +} + +static void au_nhash_de_do_free(struct hlist_head *head) @@ -31974,7 +32064,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c + nhash_count(head); + free(head++); + } -+ kfree(nhash->nh_head); ++ au_kfree_try_rcu(nhash->nh_head); +} + +void au_nhash_wh_free(struct au_nhash *whlist) @@ -32193,8 +32283,8 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c + + deblk = vdir->vd_deblk; + while (vdir->vd_nblk--) -+ kfree(*deblk++); -+ kfree(vdir->vd_deblk); ++ au_kfree_try_rcu(*deblk++); ++ au_kfree_try_rcu(vdir->vd_deblk); + au_cache_free_vdir(vdir); +} + @@ -32229,7 +32319,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c + if (!err) + return vdir; /* success */ + -+ kfree(vdir->vd_deblk); ++ au_kfree_try_rcu(vdir->vd_deblk); + +out_free: + au_cache_free_vdir(vdir); @@ -32244,7 +32334,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c + union au_vdir_deblk_p p, deblk_end; + + while (vdir->vd_nblk > 1) { -+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); ++ au_kfree_try_rcu(vdir->vd_deblk[vdir->vd_nblk - 1]); + /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ + vdir->vd_nblk--; + } @@ -33637,7 +33727,7 @@ 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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/vfsub.h 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,355 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -33913,13 +34003,13 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h + * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such + * ioctl. + */ -+static inline int vfsub_clone_file_range(struct file *src, struct file *dst, -+ u64 len) ++static inline loff_t vfsub_clone_file_range(struct file *src, struct file *dst, ++ loff_t len) +{ -+ int err; ++ loff_t err; + + lockdep_off(); -+ err = vfs_clone_file_range(src, 0, dst, 0, len); ++ err = vfs_clone_file_range(src, 0, dst, 0, len, /*remap_flags*/0); + lockdep_on(); + + return err; @@ -33996,7 +34086,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 2018-08-12 23:43:05.463458173 +0200 ++++ linux/fs/aufs/wbr_policy.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,830 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -34461,7 +34551,7 @@ diff -urN /usr/share/empty/fs/aufs/wbr_policy.c linux/fs/aufs/wbr_policy.c + + mfs->mfsrr_bytes = bavail; + AuDbg("b%d\n", mfs->mfs_bindex); -+ kfree(st); ++ au_kfree_rcu(st); +} + +static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags) @@ -34830,7 +34920,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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/whout.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,1062 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -34997,7 +35087,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + +out_name: + if (name != defname) -+ kfree(name); ++ au_kfree_try_rcu(name); +out: + AuTraceErrPtr(dentry); + return dentry; @@ -35437,7 +35527,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + au_lcnt_dec(&a->br->br_count); + si_write_unlock(a->sb); + au_nwt_done(&au_sbi(a->sb)->si_nowait); -+ kfree(arg); ++ au_kfree_rcu(a); + if (unlikely(err)) + AuIOErr("err %d\n", err); +} @@ -35465,7 +35555,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + if (unlikely(wkq_err)) { + atomic_dec(&br->br_wbr->wbr_wh_running); + au_lcnt_dec(&br->br_count); -+ kfree(arg); ++ au_kfree_rcu(arg); + } + do_dec = 0; + } @@ -35624,7 +35714,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + wh_dentry = ERR_PTR(err); + if (!err) { + wh_dentry = vfsub_lkup_one(&wh_name, h_parent); -+ kfree(wh_name.name); ++ au_kfree_try_rcu(wh_name.name); + } + return wh_dentry; +} @@ -35742,7 +35832,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + rdhash = AUFS_RDHASH_DEF; + err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); + if (unlikely(err)) { -+ kfree(whtmp); ++ au_kfree_rcu(whtmp); + whtmp = ERR_PTR(err); + } + @@ -35757,7 +35847,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c + dput(whtmp->wh_dentry); + iput(whtmp->dir); + au_nhash_wh_free(&whtmp->whlist); -+ kfree(whtmp); ++ au_kfree_rcu(whtmp); +} + +/* @@ -35986,7 +36076,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 2018-10-23 12:33:35.599375796 +0200 ++++ linux/fs/aufs/wkq.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -36162,7 +36252,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c + +static void au_wkq_lockdep_free(struct au_wkinfo *wkinfo) +{ -+ kfree(wkinfo->hlock); ++ au_kfree_try_rcu(wkinfo->hlock); +} + +static void au_wkq_lockdep_pre(struct au_wkinfo *wkinfo) @@ -36214,7 +36304,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c + else { + kobject_put(wkinfo->kobj); + module_put(THIS_MODULE); /* todo: ?? */ -+ kfree(wkinfo); ++ au_kfree_rcu(wkinfo); + } +} + @@ -36237,7 +36327,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c + +static void au_wkq_comp_free(struct completion *comp) +{ -+ kfree(comp); ++ au_kfree_rcu(comp); +} + +#else @@ -36475,7 +36565,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 2018-08-12 23:43:05.466791610 +0200 ++++ linux/fs/aufs/xattr.c 2018-12-27 13:19:17.711749485 +0100 @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: GPL-2.0 +/* @@ -36658,10 +36748,10 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c + AuTraceErr(err); + } + -+ kfree(value); ++ au_kfree_try_rcu(value); + +out_free: -+ kfree(o); ++ au_kfree_try_rcu(o); +out: + if (!unlocked) + inode_unlock_shared(h_isrc); @@ -36835,8 +36925,8 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c +} 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 2018-10-23 12:33:35.599375796 +0200 -@@ -0,0 +1,1890 @@ ++++ linux/fs/aufs/xino.c 2018-12-27 13:19:17.715082917 +0100 +@@ -0,0 +1,1956 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -37311,7 +37401,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + au_sbi(sb)->si_xino_jiffy = jiffy; + +out_st: -+ kfree(st); ++ au_kfree_rcu(st); +out: + return err; +} @@ -37348,7 +37438,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + au_lcnt_dec(&br->br_count); + si_write_unlock(sb); + au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(args); ++ au_kfree_rcu(args); +} + +/* @@ -37420,7 +37510,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + + pr_err("wkq %d\n", wkq_err); + au_lcnt_dec(&br->br_count); -+ kfree(args); ++ au_kfree_rcu(args); + +out: + atomic_dec(&br->br_xino->xi_truncating); @@ -37486,6 +37576,11 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + ino_t ino; +}; + ++struct au_xi_writing { ++ struct hlist_bl_node node; ++ ino_t h_ino, ino; ++}; ++ +static int au_xino_do_write(vfs_writef_t write, struct file *file, + struct au_xi_calc *calc, ino_t ino); + @@ -37497,6 +37592,9 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + struct au_sbinfo *sbi; + struct inode *root; + struct file *file; ++ struct au_xi_writing *del, *p; ++ struct hlist_bl_head *hbl; ++ struct hlist_bl_node *pos; + int err; + + br = a->br; @@ -37506,20 +37604,39 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + root = d_inode(sb->s_root); + ii_read_lock_child(root); + err = au_xino_do_new_async(sb, br, &a->calc); -+ if (!err) { -+ file = au_xino_file(br->br_xino, a->calc.idx); -+ if (file) -+ err = au_xino_do_write(sbi->si_xwrite, file, &a->calc, -+ a->ino); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+ } else ++ if (unlikely(err)) { ++ AuIOErr("err %d\n", err); ++ goto out; ++ } ++ ++ file = au_xino_file(br->br_xino, a->calc.idx); ++ AuDebugOn(!file); ++ err = au_xino_do_write(sbi->si_xwrite, file, &a->calc, a->ino); ++ if (unlikely(err)) { + AuIOErr("err %d\n", err); ++ goto out; ++ } ++ ++ del = NULL; ++ hbl = &br->br_xino->xi_writing; ++ hlist_bl_lock(hbl); ++ au_hbl_for_each(pos, hbl) { ++ p = container_of(pos, struct au_xi_writing, node); ++ if (p->ino == a->ino) { ++ del = p; ++ hlist_bl_del(&p->node); ++ break; ++ } ++ } ++ hlist_bl_unlock(hbl); ++ au_kfree_rcu(del); ++ ++out: + au_lcnt_dec(&br->br_count); + ii_read_unlock(root); + si_read_unlock(sb); + au_nwt_done(&sbi->si_nowait); -+ kfree(args); ++ au_kfree_rcu(a); +} + +/* @@ -37545,7 +37662,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + if (unlikely(err)) { + pr_err("wkq %d\n", err); + au_lcnt_dec(&br->br_count); -+ kfree(arg); ++ au_kfree_rcu(arg); + } + +out: @@ -37564,6 +37681,10 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + struct au_xi_calc calc; + struct au_sbinfo *sbinfo; + struct file *file; ++ struct au_xino *xi; ++ struct hlist_bl_head *hbl; ++ struct hlist_bl_node *pos; ++ struct au_xi_writing *p; + + *ino = 0; + if (!au_opt_test(au_mntflags(sb), XINO)) @@ -37571,10 +37692,24 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + + err = 0; + au_xi_calc(sb, h_ino, &calc); -+ file = au_xino_file(au_sbr(sb, bindex)->br_xino, calc.idx); -+ if (!file -+ || vfsub_f_size_read(file) < calc.pos + sizeof(*ino)) -+ return 0; /* no ino */ ++ xi = au_sbr(sb, bindex)->br_xino; ++ file = au_xino_file(xi, calc.idx); ++ if (!file) { ++ hbl = &xi->xi_writing; ++ hlist_bl_lock(hbl); ++ au_hbl_for_each(pos, hbl) { ++ p = container_of(pos, struct au_xi_writing, node); ++ if (p->h_ino == h_ino) { ++ AuDbg("hi%llu, i%llu, found\n", ++ (u64)p->h_ino, (u64)p->ino); ++ *ino = p->ino; ++ break; ++ } ++ } ++ hlist_bl_unlock(hbl); ++ return 0; ++ } else if (vfsub_f_size_read(file) < calc.pos + sizeof(*ino)) ++ return 0; /* no xino */ + + sbinfo = au_sbi(sb); + sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &calc.pos); @@ -37618,6 +37753,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + struct file *file; + struct au_branch *br; + struct au_xino *xi; ++ struct au_xi_writing *p; + + SiMustAnyLock(sb); + @@ -37630,6 +37766,12 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + xi = br->br_xino; + file = au_xino_file(xi, calc.idx); + if (!file) { ++ /* store the inum pair into the list */ ++ p = kmalloc(sizeof(*p), GFP_NOFS | __GFP_NOFAIL); ++ p->h_ino = h_ino; ++ p->ino = ino; ++ au_hbl_add(&p->node, &xi->xi_writing); ++ + /* create and write a new xino file asynchronously */ + err = au_xino_new_async(sb, br, &calc, ino); + if (!err) @@ -38077,16 +38219,15 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + spin_lock_init(&xi->xi_nondir.spin); + init_waitqueue_head(&xi->xi_nondir.wqh); + mutex_init(&xi->xi_mtx); -+ /* init_waitqueue_head(&xi->xi_wq); */ -+ /* atomic_set(&xi->xi_pending, 0); */ ++ INIT_HLIST_BL_HEAD(&xi->xi_writing); + atomic_set(&xi->xi_truncating, 0); + kref_init(&xi->xi_kref); + goto out; /* success */ + +out_file: -+ kfree(xi->xi_file); ++ au_kfree_try_rcu(xi->xi_file); +out_free: -+ kfree(xi); ++ au_kfree_rcu(xi); + xi = NULL; +out: + return xi; @@ -38118,6 +38259,10 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c +{ + struct au_xino *xi; + int i; ++ unsigned long ul; ++ struct hlist_bl_head *hbl; ++ struct hlist_bl_node *pos, *n; ++ struct au_xi_writing *p; + + xi = container_of(kref, struct au_xino, xi_kref); + for (i = 0; i < xi->xi_nfile; i++) @@ -38126,9 +38271,20 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c + for (i = xi->xi_nondir.total - 1; i >= 0; i--) + AuDebugOn(xi->xi_nondir.array[i]); + mutex_destroy(&xi->xi_mtx); -+ kfree(xi->xi_file); -+ kfree(xi->xi_nondir.array); -+ kfree(xi); ++ hbl = &xi->xi_writing; ++ ul = au_hbl_count(hbl); ++ if (unlikely(ul)) { ++ pr_warn("xi_writing %lu\n", ul); ++ hlist_bl_lock(hbl); ++ hlist_bl_for_each_entry_safe (p, pos, n, hbl, node) { ++ hlist_bl_del(&p->node); ++ au_kfree_rcu(p); ++ } ++ hlist_bl_unlock(hbl); ++ } ++ au_kfree_try_rcu(xi->xi_file); ++ au_kfree_try_rcu(xi->xi_nondir.array); ++ au_kfree_rcu(xi); +} + +int au_xino_put(struct au_branch *br) @@ -38729,7 +38885,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 2018-10-23 12:33:35.602709228 +0200 ++++ linux/include/uapi/linux/aufs_type.h 2018-12-27 13:19:17.715082917 +0100 @@ -0,0 +1,448 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* @@ -38773,7 +38929,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin + +#include + -+#define AUFS_VERSION "4.x-rcN-20181022" ++#define AUFS_VERSION "4.x-rcN-20181217" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -39183,10 +39339,10 @@ SPDX-License-Identifier: GPL-2.0 aufs4.x-rcN loopback patch diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 9e534a3..74cd74e 100644 +index 470dd02..20dc3ec 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -626,6 +626,15 @@ static inline void loop_update_dio(struct loop_device *lo) +@@ -625,6 +625,15 @@ static inline void loop_update_dio(struct loop_device *lo) lo->use_dio); } @@ -39202,7 +39358,7 @@ index 9e534a3..74cd74e 100644 static void loop_reread_partitions(struct loop_device *lo, struct block_device *bdev) { -@@ -690,6 +699,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -689,6 +698,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, unsigned int arg) { struct file *file, *old_file; @@ -39210,7 +39366,7 @@ index 9e534a3..74cd74e 100644 int error; error = -ENXIO; -@@ -705,12 +715,19 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -704,12 +714,19 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, file = fget(arg); if (!file) goto out; @@ -39230,7 +39386,7 @@ index 9e534a3..74cd74e 100644 error = -EINVAL; -@@ -722,6 +739,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -721,6 +738,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, blk_mq_freeze_queue(lo->lo_queue); mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); lo->lo_backing_file = file; @@ -39238,7 +39394,7 @@ index 9e534a3..74cd74e 100644 lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping); mapping_set_gfp_mask(file->f_mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); -@@ -729,12 +747,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -728,12 +746,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, blk_mq_unfreeze_queue(lo->lo_queue); fput(old_file); @@ -39255,7 +39411,7 @@ index 9e534a3..74cd74e 100644 out: return error; } -@@ -922,7 +944,7 @@ static int loop_prepare_queue(struct loop_device *lo) +@@ -921,7 +943,7 @@ static int loop_prepare_queue(struct loop_device *lo) static int loop_set_fd(struct loop_device *lo, fmode_t mode, struct block_device *bdev, unsigned int arg) { @@ -39264,7 +39420,7 @@ index 9e534a3..74cd74e 100644 struct inode *inode; struct address_space *mapping; int lo_flags = 0; -@@ -936,6 +958,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, +@@ -935,6 +957,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, file = fget(arg); if (!file) goto out; @@ -39277,7 +39433,7 @@ index 9e534a3..74cd74e 100644 error = -EBUSY; if (lo->lo_state != Lo_unbound) -@@ -968,6 +996,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, +@@ -967,6 +995,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, lo->lo_device = bdev; lo->lo_flags = lo_flags; lo->lo_backing_file = file; @@ -39285,7 +39441,7 @@ index 9e534a3..74cd74e 100644 lo->transfer = NULL; lo->ioctl = NULL; lo->lo_sizelimit = 0; -@@ -1001,6 +1030,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, +@@ -1000,6 +1029,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, out_putf: fput(file); @@ -39294,7 +39450,7 @@ index 9e534a3..74cd74e 100644 out: /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); -@@ -1047,6 +1078,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, +@@ -1046,6 +1077,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, static int loop_clr_fd(struct loop_device *lo) { struct file *filp = lo->lo_backing_file; @@ -39302,7 +39458,7 @@ index 9e534a3..74cd74e 100644 gfp_t gfp = lo->old_gfp_mask; struct block_device *bdev = lo->lo_device; -@@ -1078,6 +1110,7 @@ static int loop_clr_fd(struct loop_device *lo) +@@ -1077,6 +1109,7 @@ static int loop_clr_fd(struct loop_device *lo) spin_lock_irq(&lo->lo_lock); lo->lo_state = Lo_rundown; lo->lo_backing_file = NULL; @@ -39310,7 +39466,7 @@ index 9e534a3..74cd74e 100644 spin_unlock_irq(&lo->lo_lock); loop_release_xfer(lo); -@@ -1126,6 +1159,8 @@ static int loop_clr_fd(struct loop_device *lo) +@@ -1125,6 +1158,8 @@ static int loop_clr_fd(struct loop_device *lo) * bd_mutex which is usually taken before lo_ctl_mutex. */ fput(filp); @@ -39346,12 +39502,12 @@ index 5309874..1a334cf 100644 if (file->f_mapping != h_file->f_mapping) { file->f_mapping = h_file->f_mapping; diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c -index 3d84349..a642de5 100644 +index 3f3577d..3b44158 100644 --- a/fs/aufs/loop.c +++ b/fs/aufs/loop.c @@ -133,3 +133,19 @@ void au_loopback_fin(void) symbol_put(loop_backing_file); - kfree(au_warn_loopback_array); + au_kfree_try_rcu(au_warn_loopback_array); } + +/* ---------------------------------------------------------------------- */ @@ -39411,10 +39567,10 @@ index 777503e..7130061 100644 /* ---------------------------------------------------------------------- */ diff --git a/include/linux/fs.h b/include/linux/fs.h -index 7fb92a9..cff3ca3 100644 +index 0e44705..59fb8ae 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1882,6 +1882,10 @@ struct super_operations { +@@ -1931,6 +1931,10 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); -- 2.43.0