]> git.pld-linux.org Git - packages/kernel.git/commitdiff
- up to 4.7.1 auto/th/kernel-4.7.1-1
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Wed, 17 Aug 2016 16:36:56 +0000 (18:36 +0200)
committerArkadiusz Miśkiewicz <arekm@maven.pl>
Wed, 17 Aug 2016 16:36:56 +0000 (18:36 +0200)
kernel-apparmor.patch
kernel-aufs4.patch
kernel.spec

index 9d10f82fd89941e0b83f76c31743691b6b391ab5..399ae313d5b93b19d4d277a31a308bc4e83f8376 100644 (file)
@@ -598,28 +598,6 @@ index a689f10..c841b12 100644
        return 1;
  }
 
-commit 9ad29b2e7820895339f90eb71b411d0134cf1ce9
-Author: John Johansen <john.johansen@canonical.com>
-Date:   Wed Nov 18 11:41:05 2015 -0800
-
-    apparmor: fix ref count leak when profile sha1 hash is read
-    
-    Signed-off-by: John Johansen <john.johansen@canonical.com>
-    Acked-by: Seth Arnold <seth.arnold@canonical.com>
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 45a6199..0d8dd71 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -331,6 +331,7 @@ static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
-                       seq_printf(seq, "%.2x", profile->hash[i]);
-               seq_puts(seq, "\n");
-       }
-+      aa_put_profile(profile);
-       return 0;
- }
-
 commit e13f968d154ba9d6a2c4f82f33d3312a63430b54
 Author: John Johansen <john.johansen@canonical.com>
 Date:   Wed Dec 16 18:09:10 2015 -0800
index 64ad03c7eb7187c23a1581c5de02f9df6bd34847..80c6bbfa377347df7645637c46a0cbe3dda0ce59 100644 (file)
@@ -1,4 +1,4 @@
-aufs4.x-rcN kbuild patch
+aufs4.7 kbuild patch
 
 diff --git a/fs/Kconfig b/fs/Kconfig
 index b8fcb41..78adefb 100644
@@ -22,7 +22,7 @@ index 85b6e13..e7bb164 100644
  obj-$(CONFIG_EFIVAR_FS)               += efivarfs/
 +obj-$(CONFIG_AUFS_FS)           += aufs/
 diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
-index 8bdae34..65dbd5f 100644
+index ec10cfe..800211b 100644
 --- a/include/uapi/linux/Kbuild
 +++ b/include/uapi/linux/Kbuild
 @@ -59,6 +59,7 @@ header-y += atmsvc.h
@@ -33,13 +33,13 @@ index 8bdae34..65dbd5f 100644
  header-y += auto_fs4.h
  header-y += auto_fs.h
  header-y += auxvec.h
-aufs4.x-rcN base patch
+aufs4.7 base patch
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 952fd2a..6a8f0f8 100644
+index 8c20323..d170184 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -2210,6 +2210,19 @@ F:      include/linux/audit.h
+@@ -2213,6 +2213,19 @@ F:      include/linux/audit.h
  F:    include/uapi/linux/audit.h
  F:    kernel/audit*
  
@@ -265,7 +265,7 @@ index da2751d..2e0fca6 100644
 +                       struct pipe_inode_info *pipe, size_t len,
 +                       unsigned int flags);
  #endif
-aufs4.x-rcN mmap patch
+aufs4.7 mmap patch
 
 diff --git a/fs/proc/base.c b/fs/proc/base.c
 index a11eb71..8f10865 100644
@@ -430,7 +430,7 @@ index 20f3b1f..ee827ce 100644
        if (page->mapping != inode->i_mapping) {
                unlock_page(page);
 diff --git a/mm/memory.c b/mm/memory.c
-index cd1f29e..f0c204c 100644
+index 9e04681..06980d1 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
 @@ -2100,7 +2100,7 @@ static inline int wp_page_reuse(struct mm_struct *mm,
@@ -675,7 +675,7 @@ index 0000000..b323b8a
 +              fput(pr);
 +}
 +#endif /* !CONFIG_MMU */
-aufs4.x-rcN standalone patch
+aufs4.7 standalone patch
 
 diff --git a/fs/dcache.c b/fs/dcache.c
 index c3c0b6d..c99d2d2 100644
@@ -762,7 +762,7 @@ index aa6d071..f336032 100644
  /**
   *    touch_atime     -       update the access time
 diff --git a/fs/namespace.c b/fs/namespace.c
-index 783004a..44abb2d 100644
+index 419f746..9c0e0af 100644
 --- a/fs/namespace.c
 +++ b/fs/namespace.c
 @@ -463,6 +463,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
@@ -773,7 +773,7 @@ index 783004a..44abb2d 100644
  
  /**
   * mnt_drop_write - give up write access to a mount
-@@ -1811,6 +1812,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
+@@ -1812,6 +1813,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
        }
        return 0;
  }
@@ -2864,8 +2864,8 @@ 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-07-25 19:05:34.811159821 +0200
-@@ -0,0 +1,1406 @@
++++ linux/fs/aufs/branch.c     2016-08-17 18:01:06.095221547 +0200
+@@ -0,0 +1,1409 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -2919,7 +2919,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_delayed_kfree(br->br_fhsm);
 +      }
 +
 +      key = br->br_dykey;
@@ -2933,8 +2933,9 @@ 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);
-+      kfree(br);
++      if (wbr)
++              au_delayed_kfree(wbr);
++      au_delayed_kfree(br);
 +}
 +
 +/*
@@ -3032,11 +3033,12 @@ 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);
++      if (add_branch->br_wbr)
++              au_delayed_kfree(add_branch->br_wbr);
 +out_hnotify:
 +      au_hnotify_fin_br(add_branch);
 +out_br:
-+      kfree(add_branch);
++      au_delayed_kfree(add_branch);
 +out:
 +      return ERR_PTR(err);
 +}
@@ -3202,7 +3204,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_delayed_kfree(wbr);
 +              br->br_wbr = NULL;
 +      }
 +
@@ -4225,7 +4227,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_delayed_kfree(br->br_wbr);
 +                              br->br_wbr = NULL;
 +                      }
 +              }
@@ -4237,7 +4239,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_delayed_kfree(br->br_fhsm);
 +                      br->br_fhsm = NULL;
 +              }
 +      } else if (au_br_fhsm(mod->perm))
@@ -4249,7 +4251,8 @@ diff -urN /usr/share/empty/fs/aufs/branch.c linux/fs/aufs/branch.c
 +      goto out; /* success */
 +
 +out_bf:
-+      kfree(bf);
++      if (bf)
++              au_delayed_kfree(bf);
 +out:
 +      AuTraceErr(err);
 +      return err;
@@ -4629,7 +4632,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-07-25 19:05:34.811159821 +0200
++++ linux/fs/aufs/cpup.c       2016-08-17 18:01:06.095221547 +0200
 @@ -0,0 +1,1383 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -4990,9 +4993,9 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      dst->f_pos = 0;
 +      err = au_do_copy_file(dst, src, len, buf, blksize);
 +      if (do_kfree)
-+              kfree(buf);
++              au_delayed_kfree(buf);
 +      else
-+              free_page((unsigned long)buf);
++              au_delayed_free_page((unsigned long)buf);
 +
 +out:
 +      return err;
@@ -5152,7 +5155,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +              sym.k[symlen] = 0;
 +              err = vfsub_symlink(h_dir, h_path, sym.k);
 +      }
-+      free_page((unsigned long)sym.k);
++      au_delayed_free_page((unsigned long)sym.k);
 +
 +out:
 +      return err;
@@ -5523,7 +5526,7 @@ diff -urN /usr/share/empty/fs/aufs/cpup.c linux/fs/aufs/cpup.c
 +      }
 +out_parent:
 +      dput(dst_parent);
-+      kfree(a);
++      au_delayed_kfree(a);
 +out:
 +      return err;
 +}
@@ -6114,8 +6117,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    2016-07-25 19:05:34.811159821 +0200
-@@ -0,0 +1,432 @@
++++ linux/fs/aufs/dbgaufs.c    2016-08-17 18:01:06.095221547 +0200
+@@ -0,0 +1,435 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -6159,7 +6162,7 @@ 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);
++      au_delayed_kfree(file->private_data);
 +      return 0;
 +}
 +
@@ -6221,7 +6224,7 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
 +static int dbgaufs_plink_release(struct inode *inode __maybe_unused,
 +                               struct file *file)
 +{
-+      free_page((unsigned long)file->private_data);
++      au_delayed_free_page((unsigned long)file->private_data);
 +      return 0;
 +}
 +
@@ -6285,7 +6288,7 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
 +      goto out; /* success */
 +
 +out_free:
-+      free_page((unsigned long)p);
++      au_delayed_free_page((unsigned long)p);
 +out:
 +      return err;
 +}
@@ -6412,8 +6415,11 @@ diff -urN /usr/share/empty/fs/aufs/dbgaufs.c linux/fs/aufs/dbgaufs.c
 +              br = au_sbr(sb, bindex);
 +              xi = &br->br_xino;
 +              AuDebugOn(xi->xi_dbgaufs);
++              /* debugfs acquires the parent i_mutex */
++              lockdep_off();
 +              xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent,
 +                                                   sbinfo, &dbgaufs_xino_fop);
++              lockdep_on();
 +              /* ignore an error */
 +              if (unlikely(!xi->xi_dbgaufs))
 +                      AuWarn1("failed %s under debugfs\n", name);
@@ -6602,7 +6608,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-07-25 19:05:34.811159821 +0200
++++ linux/fs/aufs/dcsub.c      2016-08-17 18:01:06.101888388 +0200
 @@ -0,0 +1,224 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -6635,7 +6641,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
 +      p = dpage->dentries;
 +      for (i = 0; i < dpage->ndentry; i++)
 +              dput(*p++);
-+      free_page((unsigned long)dpage->dentries);
++      au_delayed_free_page((unsigned long)dpage->dentries);
 +}
 +
 +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp)
@@ -6658,7 +6664,7 @@ diff -urN /usr/share/empty/fs/aufs/dcsub.c linux/fs/aufs/dcsub.c
 +      return 0; /* success */
 +
 +out_dpages:
-+      kfree(dpages->dpages);
++      au_delayed_kfree(dpages->dpages);
 +out:
 +      return err;
 +}
@@ -6671,7 +6677,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_delayed_kfree(dpages->dpages);
 +}
 +
 +static int au_dpages_append(struct au_dcsub_pages *dpages,
@@ -6970,8 +6976,8 @@ 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-07-25 19:05:34.811159821 +0200
-@@ -0,0 +1,441 @@
++++ linux/fs/aufs/debug.c      2016-08-17 18:01:06.101888388 +0200
+@@ -0,0 +1,440 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -7310,7 +7316,7 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +      au_br_count_init(&a->fake);
 +      err = do_pri_br(-1, &a->fake);
 +      au_br_count_fin(&a->fake);
-+      kfree(a);
++      au_delayed_kfree(a);
 +      dpri("dev 0x%x\n", sb->s_dev);
 +      if (err || !au_test_aufs(sb))
 +              return;
@@ -7318,9 +7324,8 @@ diff -urN /usr/share/empty/fs/aufs/debug.c linux/fs/aufs/debug.c
 +      sbinfo = au_sbi(sb);
 +      if (!sbinfo)
 +              return;
-+      dpri("nw %lld, gen %u, kobj %d\n",
-+           percpu_counter_sum(&sbinfo->si_nowait.nw_len),
-+           sbinfo->si_generation,
++      dpri("nw %d, gen %u, kobj %d\n",
++           atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation,
 +           atomic_read(&sbinfo->si_kobj.kref.refcount));
 +      for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++)
 +              do_pri_br(bindex, sbinfo->si_branch[0 + bindex]);
@@ -7644,7 +7649,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-07-25 19:05:34.811159821 +0200
++++ linux/fs/aufs/dentry.c     2016-08-17 18:01:06.111888648 +0200
 @@ -0,0 +1,1128 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -7862,7 +7867,7 @@ diff -urN /usr/share/empty/fs/aufs/dentry.c linux/fs/aufs/dentry.c
 +
 +out_parent:
 +      dput(parent);
-+      kfree(whname.name);
++      au_delayed_kfree(whname.name);
 +out:
 +      return err;
 +}
@@ -8776,8 +8781,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     2016-07-25 19:05:34.811159821 +0200
-@@ -0,0 +1,252 @@
++++ linux/fs/aufs/dentry.h     2016-08-17 18:01:06.111888648 +0200
+@@ -0,0 +1,255 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -8818,7 +8823,10 @@ diff -urN /usr/share/empty/fs/aufs/dentry.h linux/fs/aufs/dentry.h
 +      struct au_rwsem         di_rwsem;
 +      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;
++      union {
++              struct au_hdentry       *di_hdentry;
++              struct llist_node       di_lnode;       /* delayed free */
++      };
 +} ____cacheline_aligned_in_smp;
 +
 +/* ---------------------------------------------------------------------- */
@@ -9032,7 +9040,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-07-25 19:05:34.811159821 +0200
++++ linux/fs/aufs/dinfo.c      2016-08-17 18:01:06.111888648 +0200
 @@ -0,0 +1,552 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -9089,7 +9097,7 @@ diff -urN /usr/share/empty/fs/aufs/dinfo.c linux/fs/aufs/dinfo.c
 +              goto out;
 +      }
 +
-+      au_cache_free_dinfo(dinfo);
++      au_cache_dfree_dinfo(dinfo);
 +      dinfo = NULL;
 +
 +out:
@@ -9109,8 +9117,8 @@ 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_cache_free_dinfo(dinfo);
++      au_delayed_kfree(dinfo->di_hdentry);
++      au_cache_dfree_dinfo(dinfo);
 +}
 +
 +void au_di_swap(struct au_dinfo *a, struct au_dinfo *b)
@@ -9588,8 +9596,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-07-25 19:05:34.811159821 +0200
-@@ -0,0 +1,756 @@
++++ linux/fs/aufs/dir.c        2016-08-17 18:01:06.111888648 +0200
+@@ -0,0 +1,762 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -9748,7 +9756,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_delayed_kfree(arg);
 +}
 +
 +void au_dir_ts(struct inode *dir, aufs_bindex_t bindex)
@@ -9784,7 +9792,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_delayed_kfree(arg);
 +      }
 +
 +out:
@@ -9903,7 +9911,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_delayed_kfree(fidir);
 +      }
 +      si_read_unlock(sb);
 +      return err;
@@ -9915,8 +9923,11 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +      struct au_vdir *vdir_cache;
 +      struct au_finfo *finfo;
 +      struct au_fidir *fidir;
++      struct au_hfile *hf;
 +      aufs_bindex_t bindex, bbot;
++      int execed, delayed;
 +
++      delayed = (current->flags & PF_KTHREAD) || in_interrupt();
 +      finfo = au_fi(file);
 +      fidir = finfo->fi_hdir;
 +      if (fidir) {
@@ -9924,22 +9935,25 @@ diff -urN /usr/share/empty/fs/aufs/dir.c linux/fs/aufs/dir.c
 +                          &au_sbi(file->f_path.dentry->d_sb)->si_files);
 +              vdir_cache = fidir->fd_vdir_cache; /* lock-free */
 +              if (vdir_cache)
-+                      au_vdir_free(vdir_cache);
++                      au_vdir_free(vdir_cache, delayed);
 +
 +              bindex = finfo->fi_btop;
 +              if (bindex >= 0) {
++                      execed = vfsub_file_execed(file);
++                      hf = fidir->fd_hfile + bindex;
 +                      /*
 +                       * calls fput() instead of filp_close(),
 +                       * since no dnotify or lock for the lower file.
 +                       */
 +                      bbot = fidir->fd_bbot;
-+                      for (; bindex <= bbot; bindex++)
-+                              au_set_h_fptr(file, bindex, NULL);
++                      for (; bindex <= bbot; bindex++, hf++)
++                              if (hf->hf_file)
++                                      au_hfput(hf, execed);
 +              }
-+              kfree(fidir);
++              au_delayed_kfree(fidir);
 +              finfo->fi_hdir = NULL;
 +      }
-+      au_finfo_fin(file);
++      au_finfo_fin(file, delayed);
 +      return 0;
 +}
 +
@@ -10348,8 +10362,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        2016-07-25 19:05:34.811159821 +0200
-@@ -0,0 +1,131 @@
++++ linux/fs/aufs/dir.h        2016-08-17 18:01:06.111888648 +0200
+@@ -0,0 +1,137 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -10394,7 +10408,10 @@ 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;
++      union {
++              struct au_vdir_destr    *str;
++              struct llist_node       lnode;  /* delayed free */
++      };
 +} ____cacheline_aligned_in_smp;
 +
 +struct au_vdir_de {
@@ -10432,7 +10449,10 @@ diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
 +
 +      unsigned long   vd_version;
 +      unsigned int    vd_deblk_sz;
-+      unsigned long   vd_jiffy;
++      union {
++              unsigned long           vd_jiffy;
++              struct llist_node       vd_lnode;       /* delayed free */
++      };
 +} ____cacheline_aligned_in_smp;
 +
 +/* ---------------------------------------------------------------------- */
@@ -10456,7 +10476,7 @@ diff -urN /usr/share/empty/fs/aufs/dir.h linux/fs/aufs/dir.h
 +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino,
 +                     unsigned int d_type, aufs_bindex_t bindex,
 +                     unsigned char shwh);
-+void au_vdir_free(struct au_vdir *vdir);
++void au_vdir_free(struct au_vdir *vdir, int atonce);
 +int au_vdir_init(struct file *file);
 +int au_vdir_fill_de(struct file *file, struct dir_context *ctx);
 +
@@ -10483,7 +10503,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-07-25 19:05:34.811159821 +0200
++++ linux/fs/aufs/dynop.c      2016-08-17 18:01:21.295617591 +0200
 @@ -0,0 +1,369 @@
 +/*
 + * Copyright (C) 2010-2016 Junjiro R. Okajima
@@ -10514,17 +10534,17 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 + * How large will these lists be?
 + * Usually just a few elements, 20-30 at most for each, I guess.
 + */
-+static struct au_splhead dynop[AuDyLast];
++static struct au_sphlhead dynop[AuDyLast];
 +
-+static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
++static struct au_dykey *dy_gfind_get(struct au_sphlhead *sphl, const void *h_op)
 +{
 +      struct au_dykey *key, *tmp;
-+      struct list_head *head;
++      struct hlist_head *head;
 +
 +      key = NULL;
-+      head = &spl->head;
++      head = &sphl->head;
 +      rcu_read_lock();
-+      list_for_each_entry_rcu(tmp, head, dk_list)
++      hlist_for_each_entry_rcu(tmp, head, dk_hnode)
 +              if (tmp->dk_op.dy_hop == h_op) {
 +                      key = tmp;
 +                      kref_get(&key->dk_kref);
@@ -10571,24 +10591,24 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 +}
 +
 +/* kref_get() if @key is already added */
-+static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
++static struct au_dykey *dy_gadd(struct au_sphlhead *sphl, struct au_dykey *key)
 +{
 +      struct au_dykey *tmp, *found;
-+      struct list_head *head;
++      struct hlist_head *head;
 +      const void *h_op = key->dk_op.dy_hop;
 +
 +      found = NULL;
-+      head = &spl->head;
-+      spin_lock(&spl->spin);
-+      list_for_each_entry(tmp, head, dk_list)
++      head = &sphl->head;
++      spin_lock(&sphl->spin);
++      hlist_for_each_entry(tmp, head, dk_hnode)
 +              if (tmp->dk_op.dy_hop == h_op) {
 +                      kref_get(&tmp->dk_kref);
 +                      found = tmp;
 +                      break;
 +              }
 +      if (!found)
-+              list_add_rcu(&key->dk_list, head);
-+      spin_unlock(&spl->spin);
++              hlist_add_head_rcu(&key->dk_hnode, head);
++      spin_unlock(&sphl->spin);
 +
 +      if (!found)
 +              DyPrSym(key);
@@ -10601,17 +10621,17 @@ 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);
++      kfree(key);     /* not delayed */
 +}
 +
 +static void dy_free(struct kref *kref)
 +{
 +      struct au_dykey *key;
-+      struct au_splhead *spl;
++      struct au_sphlhead *sphl;
 +
 +      key = container_of(kref, struct au_dykey, dk_kref);
-+      spl = dynop + key->dk_op.dy_type;
-+      au_spl_del_rcu(&key->dk_list, spl);
++      sphl = dynop + key->dk_op.dy_type;
++      au_sphl_del_rcu(&key->dk_hnode, sphl);
 +      call_rcu(&key->dk_rcu, dy_free_rcu);
 +}
 +
@@ -10696,7 +10716,7 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 +static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
 +{
 +      struct au_dykey *key, *old;
-+      struct au_splhead *spl;
++      struct au_sphlhead *sphl;
 +      struct op {
 +              unsigned int sz;
 +              void (*set)(struct au_dykey *key, const void *h_op,
@@ -10710,8 +10730,8 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 +      };
 +      const struct op *p;
 +
-+      spl = dynop + op->dy_type;
-+      key = dy_gfind_get(spl, op->dy_hop);
++      sphl = dynop + op->dy_type;
++      key = dy_gfind_get(sphl, op->dy_hop);
 +      if (key)
 +              goto out_add; /* success */
 +
@@ -10725,9 +10745,9 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 +      key->dk_op.dy_hop = op->dy_hop;
 +      kref_init(&key->dk_kref);
 +      p->set(key, op->dy_hop, au_br_sb(br));
-+      old = dy_gadd(spl, key);
++      old = dy_gadd(sphl, key);
 +      if (old) {
-+              kfree(key);
++              au_delayed_kfree(key);
 +              key = old;
 +      }
 +
@@ -10822,16 +10842,16 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 +
 +void au_dy_arefresh(int do_dx)
 +{
-+      struct au_splhead *spl;
-+      struct list_head *head;
++      struct au_sphlhead *sphl;
++      struct hlist_head *head;
 +      struct au_dykey *key;
 +
-+      spl = dynop + AuDy_AOP;
-+      head = &spl->head;
-+      spin_lock(&spl->spin);
-+      list_for_each_entry(key, head, dk_list)
++      sphl = dynop + AuDy_AOP;
++      head = &sphl->head;
++      spin_lock(&sphl->spin);
++      hlist_for_each_entry(key, head, dk_hnode)
 +              dy_adx((void *)key, do_dx);
-+      spin_unlock(&spl->spin);
++      spin_unlock(&sphl->spin);
 +}
 +
 +/* ---------------------------------------------------------------------- */
@@ -10844,7 +10864,7 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 +      BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
 +
 +      for (i = 0; i < AuDyLast; i++)
-+              au_spl_init(dynop + i);
++              au_sphl_init(dynop + i);
 +}
 +
 +void au_dy_fin(void)
@@ -10852,11 +10872,11 @@ diff -urN /usr/share/empty/fs/aufs/dynop.c linux/fs/aufs/dynop.c
 +      int i;
 +
 +      for (i = 0; i < AuDyLast; i++)
-+              WARN_ON(!list_empty(&dynop[i].head));
++              WARN_ON(!hlist_empty(&dynop[i].head));
 +}
 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-07-25 19:05:34.811159821 +0200
++++ linux/fs/aufs/dynop.h      2016-08-17 18:01:06.118555489 +0200
 @@ -0,0 +1,74 @@
 +/*
 + * Copyright (C) 2010-2016 Junjiro R. Okajima
@@ -10899,7 +10919,7 @@ diff -urN /usr/share/empty/fs/aufs/dynop.h linux/fs/aufs/dynop.h
 +
 +struct au_dykey {
 +      union {
-+              struct list_head        dk_list;
++              struct hlist_node       dk_hnode;
 +              struct rcu_head         dk_rcu;
 +      };
 +      struct au_dynop         dk_op;
@@ -10934,7 +10954,7 @@ 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-07-25 19:05:34.811159821 +0200
++++ linux/fs/aufs/export.c     2016-08-17 18:01:06.128555749 +0200
 @@ -0,0 +1,837 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -11355,7 +11375,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +      }
 +
 +out_name:
-+      free_page((unsigned long)arg.name);
++      au_delayed_free_page((unsigned long)arg.name);
 +out_file:
 +      fput(file);
 +out:
@@ -11509,7 +11529,7 @@ diff -urN /usr/share/empty/fs/aufs/export.c linux/fs/aufs/export.c
 +                      dentry = ERR_PTR(-ESTALE);
 +              }
 +out_pathname:
-+      free_page((unsigned long)pathname);
++      au_delayed_free_page((unsigned long)pathname);
 +out_h_parent:
 +      dput(h_parent);
 +out:
@@ -12205,8 +12225,8 @@ 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-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,843 @@
++++ linux/fs/aufs/file.c       2016-08-17 18:01:21.295617591 +0200
+@@ -0,0 +1,845 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -12482,7 +12502,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +      }
 +      if (unlikely(err)) {
 +              finfo->fi_hdir = NULL;
-+              au_finfo_fin(file);
++              au_finfo_fin(file, /*atonce*/0);
 +      }
 +
 +out:
@@ -12802,6 +12822,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +
 +static void au_do_refresh_dir(struct file *file)
 +{
++      int execed;
 +      aufs_bindex_t bindex, bbot, new_bindex, brid;
 +      struct au_hfile *p, tmp, *q;
 +      struct au_finfo *finfo;
@@ -12840,6 +12861,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +              }
 +      }
 +
++      execed = vfsub_file_execed(file);
 +      p = fidir->fd_hfile;
 +      if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) {
 +              bbot = au_sbbot(sb);
@@ -12848,14 +12870,14 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +                      if (p->hf_file) {
 +                              if (file_inode(p->hf_file))
 +                                      break;
-+                              au_hfput(p, file);
++                              au_hfput(p, execed);
 +                      }
 +      } else {
 +              bbot = au_br_index(sb, brid);
 +              for (finfo->fi_btop = 0; finfo->fi_btop < bbot;
 +                   finfo->fi_btop++, p++)
 +                      if (p->hf_file)
-+                              au_hfput(p, file);
++                              au_hfput(p, execed);
 +              bbot = au_sbbot(sb);
 +      }
 +
@@ -12865,7 +12887,7 @@ diff -urN /usr/share/empty/fs/aufs/file.c linux/fs/aufs/file.c
 +              if (p->hf_file) {
 +                      if (file_inode(p->hf_file))
 +                              break;
-+                      au_hfput(p, file);
++                      au_hfput(p, execed);
 +              }
 +      AuDebugOn(fidir->fd_bbot < finfo->fi_btop);
 +}
@@ -13052,8 +13074,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       2016-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,291 @@
++++ linux/fs/aufs/file.h       2016-08-17 18:01:06.135222590 +0200
+@@ -0,0 +1,294 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -13119,7 +13141,10 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
 +      struct au_fidir         *fi_hdir;       /* for dir only */
 +
 +      struct hlist_node       fi_hlist;
-+      struct file             *fi_file;       /* very ugly */
++      union {
++              struct file             *fi_file;       /* very ugly */
++              struct llist_node       fi_lnode;       /* delayed free */
++      };
 +} ____cacheline_aligned_in_smp;
 +
 +/* ---------------------------------------------------------------------- */
@@ -13170,7 +13195,7 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
 +struct file *au_read_pre(struct file *file, int keep_fi);
 +
 +/* finfo.c */
-+void au_hfput(struct au_hfile *hf, struct file *file);
++void au_hfput(struct au_hfile *hf, int execed);
 +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
 +                 struct file *h_file);
 +
@@ -13179,7 +13204,7 @@ diff -urN /usr/share/empty/fs/aufs/file.h linux/fs/aufs/file.h
 +int au_fidir_realloc(struct au_finfo *finfo, int nbr);
 +
 +void au_fi_init_once(void *_fi);
-+void au_finfo_fin(struct file *file);
++void au_finfo_fin(struct file *file, int atonce);
 +int au_finfo_init(struct file *file, struct au_fidir *fidir);
 +
 +/* ioctl.c */
@@ -13347,8 +13372,8 @@ 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-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,149 @@
++++ linux/fs/aufs/finfo.c      2016-08-17 18:01:06.135222590 +0200
+@@ -0,0 +1,151 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -13372,10 +13397,9 @@ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
 +
 +#include "aufs.h"
 +
-+void au_hfput(struct au_hfile *hf, struct file *file)
++void au_hfput(struct au_hfile *hf, int execed)
 +{
-+      /* todo: direct access f_flags */
-+      if (vfsub_file_flags(file) & __FMODE_EXEC)
++      if (execed)
 +              allow_write_access(hf->hf_file);
 +      fput(hf->hf_file);
 +      hf->hf_file = NULL;
@@ -13397,7 +13421,7 @@ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
 +              hf = fidir->fd_hfile + bindex;
 +
 +      if (hf && hf->hf_file)
-+              au_hfput(hf, file);
++              au_hfput(hf, vfsub_file_execed(file));
 +      if (val) {
 +              FiMustWriteLock(file);
 +              AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry));
@@ -13454,7 +13478,7 @@ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+void au_finfo_fin(struct file *file)
++void au_finfo_fin(struct file *file, int atonce)
 +{
 +      struct au_finfo *finfo;
 +
@@ -13463,7 +13487,10 @@ diff -urN /usr/share/empty/fs/aufs/finfo.c linux/fs/aufs/finfo.c
 +      finfo = au_fi(file);
 +      AuDebugOn(finfo->fi_hdir);
 +      AuRwDestroy(&finfo->fi_rwsem);
-+      au_cache_free_finfo(finfo);
++      if (!atonce)
++              au_cache_dfree_finfo(finfo);
++      else
++              au_cache_free_finfo(finfo);
 +}
 +
 +void au_fi_init_once(void *_finfo)
@@ -13500,8 +13527,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-07-25 19:05:34.811159821 +0200
-@@ -0,0 +1,770 @@
++++ linux/fs/aufs/f_op.c       2016-08-17 18:01:06.135222590 +0200
+@@ -0,0 +1,772 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -13603,6 +13630,7 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +{
 +      struct au_finfo *finfo;
 +      aufs_bindex_t bindex;
++      int delayed;
 +
 +      finfo = au_fi(file);
 +      au_sphl_del(&finfo->fi_hlist,
@@ -13611,7 +13639,8 @@ diff -urN /usr/share/empty/fs/aufs/f_op.c linux/fs/aufs/f_op.c
 +      if (bindex >= 0)
 +              au_set_h_fptr(file, bindex, NULL);
 +
-+      au_finfo_fin(file);
++      delayed = (current->flags & PF_KTHREAD) || in_interrupt();
++      au_finfo_fin(file, delayed);
 +      return 0;
 +}
 +
@@ -14274,7 +14303,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-07-25 19:05:34.814493242 +0200
++++ linux/fs/aufs/fstype.h     2016-08-17 18:01:06.145222850 +0200
 @@ -0,0 +1,400 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -14319,7 +14348,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_iso9660(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE)
++#if IS_ENABLED(CONFIG_ISO9660_FS)
 +      return sb->s_magic == ISOFS_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14328,7 +14357,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_romfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE)
++#if IS_ENABLED(CONFIG_ROMFS_FS)
 +      return sb->s_magic == ROMFS_MAGIC;
 +#else
 +      return 0;
@@ -14337,7 +14366,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_cramfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE)
++#if IS_ENABLED(CONFIG_CRAMFS)
 +      return sb->s_magic == CRAMFS_MAGIC;
 +#endif
 +      return 0;
@@ -14345,7 +14374,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_nfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE)
++#if IS_ENABLED(CONFIG_NFS_FS)
 +      return sb->s_magic == NFS_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14354,7 +14383,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_fuse(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE)
++#if IS_ENABLED(CONFIG_FUSE_FS)
 +      return sb->s_magic == FUSE_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14363,7 +14392,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_xfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE)
++#if IS_ENABLED(CONFIG_XFS_FS)
 +      return sb->s_magic == XFS_SB_MAGIC;
 +#else
 +      return 0;
@@ -14381,7 +14410,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE)
++#if IS_ENABLED(CONFIG_ECRYPT_FS)
 +      return !strcmp(au_sbtype(sb), "ecryptfs");
 +#else
 +      return 0;
@@ -14395,7 +14424,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_ubifs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE)
++#if IS_ENABLED(CONFIG_UBIFS_FS)
 +      return sb->s_magic == UBIFS_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14422,7 +14451,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_configfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE)
++#if IS_ENABLED(CONFIG_CONFIGFS_FS)
 +      return sb->s_magic == CONFIGFS_MAGIC;
 +#else
 +      return 0;
@@ -14431,7 +14460,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_minix(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE)
++#if IS_ENABLED(CONFIG_MINIX_FS)
 +      return sb->s_magic == MINIX3_SUPER_MAGIC
 +              || sb->s_magic == MINIX2_SUPER_MAGIC
 +              || sb->s_magic == MINIX2_SUPER_MAGIC2
@@ -14444,7 +14473,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_fat(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE)
++#if IS_ENABLED(CONFIG_FAT_FS)
 +      return sb->s_magic == MSDOS_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14472,7 +14501,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_squashfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE)
++#if IS_ENABLED(CONFIG_SQUASHFS)
 +      return sb->s_magic == SQUASHFS_MAGIC;
 +#else
 +      return 0;
@@ -14481,7 +14510,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_btrfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
++#if IS_ENABLED(CONFIG_BTRFS_FS)
 +      return sb->s_magic == BTRFS_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14490,7 +14519,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_xenfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE)
++#if IS_ENABLED(CONFIG_XENFS)
 +      return sb->s_magic == XENFS_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14508,7 +14537,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_nilfs(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE)
++#if IS_ENABLED(CONFIG_NILFS)
 +      return sb->s_magic == NILFS_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14517,7 +14546,7 @@ diff -urN /usr/share/empty/fs/aufs/fstype.h linux/fs/aufs/fstype.h
 +
 +static inline int au_test_hfsplus(struct super_block *sb __maybe_unused)
 +{
-+#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE)
++#if IS_ENABLED(CONFIG_HFSPLUS_FS)
 +      return sb->s_magic == HFSPLUS_SUPER_MAGIC;
 +#else
 +      return 0;
@@ -14678,7 +14707,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-07-25 19:05:34.814493242 +0200
++++ linux/fs/aufs/hfsnotify.c  2016-08-17 18:01:06.145222850 +0200
 @@ -0,0 +1,287 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -14714,7 +14743,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
 +      struct au_hnotify *hn = container_of(mark, struct au_hnotify,
 +                                           hn_mark);
 +      /* AuDbg("here\n"); */
-+      au_cache_free_hnotify(hn);
++      au_cache_dfree_hnotify(hn);
 +      smp_mb__before_atomic();
 +      if (atomic64_dec_and_test(&au_hfsn_ifree))
 +              wake_up(&au_hfsn_wq);
@@ -14838,7 +14867,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_delayed_kfree(hfsn);
 +}
 +
 +static int au_hfsn_handle_event(struct fsnotify_group *group,
@@ -14932,7 +14961,7 @@ diff -urN /usr/share/empty/fs/aufs/hfsnotify.c linux/fs/aufs/hfsnotify.c
 +      goto out; /* success */
 +
 +out_hfsn:
-+      kfree(hfsn);
++      au_delayed_kfree(hfsn);
 +out:
 +      return err;
 +}
@@ -15029,8 +15058,8 @@ 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-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,710 @@
++++ linux/fs/aufs/hnotify.c    2016-08-17 18:01:06.148556271 +0200
+@@ -0,0 +1,723 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -15068,7 +15097,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +              AuTraceErr(err);
 +              if (unlikely(err)) {
 +                      hinode->hi_notify = NULL;
-+                      au_cache_free_hnotify(hn);
++                      au_cache_dfree_hnotify(hn);
 +                      /*
 +                       * The upper dir was removed by udba, but the same named
 +                       * dir left. In this case, aufs assignes a new inode
@@ -15092,7 +15121,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +      if (hn) {
 +              hinode->hi_notify = NULL;
 +              if (au_hnotify_op.free(hinode, hn))
-+                      au_cache_free_hnotify(hn);
++                      au_cache_dfree_hnotify(hn);
 +      }
 +}
 +
@@ -15526,7 +15555,7 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +              || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) {
 +              inode = lookup_wlock_by_ino(sb, bfound, h_ino);
 +              try_iput = 1;
-+          }
++      }
 +
 +      args.flags = a->flags[AuHn_CHILD];
 +      args.dentry = dentry;
@@ -15565,7 +15594,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_delayed_kfree(a);
 +}
 +
 +/* ---------------------------------------------------------------------- */
@@ -15671,7 +15700,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_delayed_kfree(args);
 +      }
 +
 +out:
@@ -15712,17 +15741,26 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +
 +static void au_hn_destroy_cache(void)
 +{
-+      kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]);
-+      au_cachep[AuCache_HNOTIFY] = NULL;
++      struct au_cache *cp;
++
++      flush_delayed_work(&au_dfree.dwork);
++      cp = au_dfree.cache + AuCache_HNOTIFY;
++      AuDebugOn(!llist_empty(&cp->llist));
++      kmem_cache_destroy(cp->cache);
++      cp->cache = NULL;
 +}
 +
++AU_CACHE_DFREE_FUNC(hnotify, HNOTIFY, hn_lnode);
++
 +int __init au_hnotify_init(void)
 +{
 +      int err;
++      struct au_cache *cp;
 +
 +      err = -ENOMEM;
-+      au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify);
-+      if (au_cachep[AuCache_HNOTIFY]) {
++      cp = au_dfree.cache + AuCache_HNOTIFY;
++      cp->cache = AuCache(au_hnotify);
++      if (cp->cache) {
 +              err = 0;
 +              if (au_hnotify_op.init)
 +                      err = au_hnotify_op.init();
@@ -15735,15 +15773,19 @@ diff -urN /usr/share/empty/fs/aufs/hnotify.c linux/fs/aufs/hnotify.c
 +
 +void au_hnotify_fin(void)
 +{
++      struct au_cache *cp;
++
 +      if (au_hnotify_op.fin)
 +              au_hnotify_op.fin();
++
 +      /* cf. au_cache_fin() */
-+      if (au_cachep[AuCache_HNOTIFY])
++      cp = au_dfree.cache + AuCache_HNOTIFY;
++      if (cp->cache)
 +              au_hn_destroy_cache();
 +}
 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-07-25 19:05:34.814493242 +0200
++++ linux/fs/aufs/iinfo.c      2016-08-17 18:01:06.148556271 +0200
 @@ -0,0 +1,284 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -16014,7 +16056,7 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 +
 +      iinfo = au_ii(inode);
 +      if (iinfo->ii_vdir)
-+              au_vdir_free(iinfo->ii_vdir);
++              au_vdir_free(iinfo->ii_vdir, /*atonce*/0);
 +
 +      bindex = iinfo->ii_btop;
 +      if (bindex >= 0) {
@@ -16026,7 +16068,7 @@ diff -urN /usr/share/empty/fs/aufs/iinfo.c linux/fs/aufs/iinfo.c
 +                      hi++;
 +              }
 +      }
-+      kfree(iinfo->ii_hinode);
++      au_delayed_kfree(iinfo->ii_hinode);
 +      AuRwDestroy(&iinfo->ii_rwsem);
 +}
 diff -urN /usr/share/empty/fs/aufs/inode.c linux/fs/aufs/inode.c
@@ -16552,8 +16594,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      2016-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,694 @@
++++ linux/fs/aufs/inode.h      2016-08-17 18:01:06.151889691 +0200
+@@ -0,0 +1,700 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -16591,7 +16633,10 @@ diff -urN /usr/share/empty/fs/aufs/inode.h linux/fs/aufs/inode.h
 +      /* never use fsnotify_add_vfsmount_mark() */
 +      struct fsnotify_mark            hn_mark;
 +#endif
-+      struct inode                    *hn_aufs_inode; /* no get/put */
++      union {
++              struct inode            *hn_aufs_inode; /* no get/put */
++              struct llist_node       hn_lnode;       /* delayed free */
++      };
 +#endif
 +} ____cacheline_aligned_in_smp;
 +
@@ -16634,7 +16679,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_node plink;
++      union {
++              struct hlist_node       plink;
++              struct llist_node       lnode;  /* delayed free */
++      };
 +} ____cacheline_aligned_in_smp;
 +
 +/* au_pin flags */
@@ -17473,7 +17521,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-07-25 19:05:34.814493242 +0200
++++ linux/fs/aufs/i_op_add.c   2016-08-17 18:01:06.148556271 +0200
 @@ -0,0 +1,924 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -17822,7 +17870,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_delayed_kfree(a);
 +out:
 +      return err;
 +}
@@ -18286,7 +18334,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_delayed_kfree(a);
 +out:
 +      AuTraceErr(err);
 +      return err;
@@ -18395,14 +18443,14 @@ 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_delayed_kfree(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       2016-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,1414 @@
++++ linux/fs/aufs/i_op.c       2016-08-17 18:01:06.148556271 +0200
+@@ -0,0 +1,1413 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -18686,8 +18734,7 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +{
 +      int err, h_opened = *opened;
 +      unsigned int lkup_flags;
-+      struct dentry *parent;
-+      struct dentry *d;
++      struct dentry *parent, *d;
 +      struct au_sphlhead *aopen;
 +      struct vfsub_aopen_args args = {
 +              .open_flag      = open_flag,
@@ -18782,10 +18829,10 @@ diff -urN /usr/share/empty/fs/aufs/i_op.c linux/fs/aufs/i_op.c
 +      di_write_unlock(parent);
 +      aufs_read_unlock(dentry, AuLock_DW);
 +      AuDbgDentry(dentry);
-+      if (unlikely(err))
++      if (unlikely(err < 0))
 +              goto out;
 +out_no_open:
-+      if (!err && !(*opened & FILE_CREATED)) {
++      if (err >= 0 && !(*opened & FILE_CREATED)) {
 +              AuLabel(out_no_open);
 +              dget(dentry);
 +              err = finish_no_open(file, dentry);
@@ -19399,7 +19446,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_delayed_kfree(a);
 +out:
 +      AuTraceErr(err);
 +      return err;
@@ -19492,7 +19539,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_delayed_kfree(a);
 +out:
 +      AuTraceErr(err);
 +      return err;
@@ -19819,7 +19866,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-07-25 19:05:34.814493242 +0200
++++ linux/fs/aufs/i_op_del.c   2016-08-17 18:01:06.148556271 +0200
 @@ -0,0 +1,511 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -20217,7 +20264,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_delayed_kfree(a);
 +out:
 +      return err;
 +}
@@ -20327,14 +20374,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_delayed_kfree(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   2016-07-25 19:05:34.814493242 +0200
++++ linux/fs/aufs/i_op_ren.c   2016-08-17 18:01:06.148556271 +0200
 @@ -0,0 +1,1015 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -21346,7 +21393,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_delayed_kfree(a);
 +out:
 +      AuTraceErr(err);
 +      return err;
@@ -21542,7 +21589,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-07-25 19:05:34.814493242 +0200
++++ linux/fs/aufs/loop.c       2016-08-17 18:01:06.151889691 +0200
 @@ -0,0 +1,146 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -21688,7 +21735,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_delayed_kfree(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
@@ -21830,8 +21877,8 @@ 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-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,223 @@
++++ linux/fs/aufs/module.c     2016-08-17 18:01:06.151889691 +0200
+@@ -0,0 +1,289 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -21869,17 +21916,64 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +}
 +
 +/* ---------------------------------------------------------------------- */
-+
 +/*
 + * aufs caches
 + */
-+struct kmem_cache *au_cachep[AuCache_Last] = {
-+      [0] = NULL
-+};
++
++struct au_dfree au_dfree;
++
++/* delayed free */
++static void au_do_dfree(struct work_struct *work __maybe_unused)
++{
++      struct llist_head *head;
++      struct llist_node *node, *next;
++
++#define AU_CACHE_DFREE_DO_BODY(name, idx, lnode) do {                 \
++              head = &au_dfree.cache[AuCache_##idx].llist;            \
++              node = llist_del_all(head);                             \
++              for (; node; node = next) {                             \
++                      struct au_##name *p =                           \
++                              p = llist_entry(node, struct au_##name, \
++                                              lnode);                 \
++                      next = llist_next(node);                        \
++                      au_cache_free_##name(p);                        \
++              }                                                       \
++      } while (0)
++
++      AU_CACHE_DFREE_DO_BODY(dinfo, DINFO, di_lnode);
++      AU_CACHE_DFREE_DO_BODY(icntnr, ICNTNR, lnode);
++      AU_CACHE_DFREE_DO_BODY(finfo, FINFO, fi_lnode);
++      AU_CACHE_DFREE_DO_BODY(vdir, VDIR, vd_lnode);
++      AU_CACHE_DFREE_DO_BODY(vdir_dehstr, DEHSTR, lnode);
++#ifdef CONFIG_AUFS_HNOTIFY
++      AU_CACHE_DFREE_DO_BODY(hnotify, HNOTIFY, hn_lnode);
++#endif
++
++#define AU_DFREE_DO_BODY(llist, func) do {            \
++              node = llist_del_all(llist);            \
++              for (; node; node = next) {             \
++                      next = llist_next(node);        \
++                      func(node);                     \
++              }                                       \
++      } while (0)
++
++      AU_DFREE_DO_BODY(au_dfree.llist + AU_DFREE_KFREE, kfree);
++      AU_DFREE_DO_BODY(au_dfree.llist + AU_DFREE_FREE_PAGE, au_free_page);
++
++#undef AU_CACHE_DFREE_DO_BODY
++#undef AU_DFREE_DO_BODY
++}
++
++AU_CACHE_DFREE_FUNC(dinfo, DINFO, di_lnode);
++AU_CACHE_DFREE_FUNC(icntnr, ICNTNR, lnode);
++AU_CACHE_DFREE_FUNC(finfo, FINFO, fi_lnode);
++AU_CACHE_DFREE_FUNC(vdir, VDIR, vd_lnode);
++AU_CACHE_DFREE_FUNC(vdir_dehstr, DEHSTR, lnode);
 +
 +static void au_cache_fin(void)
 +{
 +      int i;
++      struct au_cache *cp;
 +
 +      /*
 +       * Make sure all delayed rcu free inodes are flushed before we
@@ -21889,27 +21983,33 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +
 +      /* excluding AuCache_HNOTIFY */
 +      BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last);
++      flush_delayed_work(&au_dfree.dwork);
 +      for (i = 0; i < AuCache_HNOTIFY; i++) {
-+              kmem_cache_destroy(au_cachep[i]);
-+              au_cachep[i] = NULL;
++              cp = au_dfree.cache + i;
++              AuDebugOn(!llist_empty(&cp->llist));
++              kmem_cache_destroy(cp->cache);
++              cp->cache = NULL;
 +      }
 +}
 +
 +static int __init au_cache_init(void)
 +{
-+      au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once);
-+      if (au_cachep[AuCache_DINFO])
++      struct au_cache *cp;
++
++      cp = au_dfree.cache;
++      cp[AuCache_DINFO].cache = AuCacheCtor(au_dinfo, au_di_init_once);
++      if (cp[AuCache_DINFO].cache)
 +              /* SLAB_DESTROY_BY_RCU */
-+              au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr,
-+                                                      au_icntnr_init_once);
-+      if (au_cachep[AuCache_ICNTNR])
-+              au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo,
-+                                                     au_fi_init_once);
-+      if (au_cachep[AuCache_FINFO])
-+              au_cachep[AuCache_VDIR] = AuCache(au_vdir);
-+      if (au_cachep[AuCache_VDIR])
-+              au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr);
-+      if (au_cachep[AuCache_DEHSTR])
++              cp[AuCache_ICNTNR].cache = AuCacheCtor(au_icntnr,
++                                                     au_icntnr_init_once);
++      if (cp[AuCache_ICNTNR].cache)
++              cp[AuCache_FINFO].cache = AuCacheCtor(au_finfo,
++                                                    au_fi_init_once);
++      if (cp[AuCache_FINFO].cache)
++              cp[AuCache_VDIR].cache = AuCache(au_vdir);
++      if (cp[AuCache_VDIR].cache)
++              cp[AuCache_DEHSTR].cache = AuCache(au_vdir_dehstr);
++      if (cp[AuCache_DEHSTR].cache)
 +              return 0;
 +
 +      au_cache_fin();
@@ -21972,6 +22072,7 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +{
 +      int err, i;
 +      char *p;
++      struct au_cache *cp;
 +
 +      p = au_esc_chars;
 +      for (i = 1; i <= ' '; i++)
@@ -21986,6 +22087,16 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +      for (i = 0; i < AuIop_Last; i++)
 +              aufs_iop_nogetattr[i].getattr = NULL;
 +
++      /* First, initialize au_dfree */
++      for (i = 0; i < AuCache_Last; i++) {    /* including hnotify */
++              cp = au_dfree.cache + i;
++              cp->cache = NULL;
++              init_llist_head(&cp->llist);
++      }
++      for (i = 0; i < AU_DFREE_Last; i++)
++              init_llist_head(au_dfree.llist + i);
++      INIT_DELAYED_WORK(&au_dfree.dwork, au_do_dfree);
++
 +      au_sbilist_init();
 +      sysaufs_brs_init();
 +      au_debug_init();
@@ -22036,6 +22147,7 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +out_sysaufs:
 +      sysaufs_fin();
 +      au_dy_fin();
++      flush_delayed_work(&au_dfree.dwork);
 +out:
 +      return err;
 +}
@@ -22051,14 +22163,15 @@ diff -urN /usr/share/empty/fs/aufs/module.c linux/fs/aufs/module.c
 +      au_procfs_fin();
 +      sysaufs_fin();
 +      au_dy_fin();
++      flush_delayed_work(&au_dfree.dwork);
 +}
 +
 +module_init(aufs_init);
 +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-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,89 @@
++++ linux/fs/aufs/module.h     2016-08-17 18:01:06.158556531 +0200
+@@ -0,0 +1,144 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -22086,6 +22199,7 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
 +#ifdef __KERNEL__
 +
 +#include <linux/slab.h>
++#include "debug.h"
 +
 +struct path;
 +struct seq_file;
@@ -22112,7 +22226,7 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
 +
 +/* ---------------------------------------------------------------------- */
 +
-+/* kmem cache */
++/* kmem cache and delayed free */
 +enum {
 +      AuCache_DINFO,
 +      AuCache_ICNTNR,
@@ -22123,19 +22237,54 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
 +      AuCache_Last
 +};
 +
++enum {
++      AU_DFREE_KFREE,
++      AU_DFREE_FREE_PAGE,
++      AU_DFREE_Last
++};
++
++struct au_cache {
++      struct kmem_cache       *cache;
++      struct llist_head       llist;  /* delayed free */
++};
++
++/*
++ * in order to reduce the cost of the internal timer, consolidate all the
++ * delayed free works into a single delayed_work.
++ */
++struct au_dfree {
++      struct au_cache         cache[AuCache_Last];
++      struct llist_head       llist[AU_DFREE_Last];
++      struct delayed_work     dwork;
++};
++
++extern struct au_dfree au_dfree;
++
 +#define AuCacheFlags          (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD)
 +#define AuCache(type)         KMEM_CACHE(type, AuCacheFlags)
 +#define AuCacheCtor(type, ctor)       \
 +      kmem_cache_create(#type, sizeof(struct type), \
 +                        __alignof__(struct type), AuCacheFlags, ctor)
 +
-+extern struct kmem_cache *au_cachep[];
++#define AU_DFREE_DELAY                msecs_to_jiffies(10)
++#define AU_DFREE_BODY(lnode, llist) do {                              \
++              if (llist_add(lnode, llist))                            \
++                      schedule_delayed_work(&au_dfree.dwork,          \
++                                            AU_DFREE_DELAY);          \
++      } while (0)
++#define AU_CACHE_DFREE_FUNC(name, idx, lnode)                         \
++      void au_cache_dfree_##name(struct au_##name *p)                 \
++      {                                                               \
++              struct au_cache *cp = au_dfree.cache + AuCache_##idx;   \
++              AU_DFREE_BODY(&p->lnode, &cp->llist);                   \
++      }
 +
 +#define AuCacheFuncs(name, index) \
 +static inline struct au_##name *au_cache_alloc_##name(void) \
-+{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \
++{ return kmem_cache_alloc(au_dfree.cache[AuCache_##index].cache, GFP_NOFS); } \
 +static inline void au_cache_free_##name(struct au_##name *p) \
-+{ kmem_cache_free(au_cachep[AuCache_##index], p); }
++{ kmem_cache_free(au_dfree.cache[AuCache_##index].cache, p); } \
++void au_cache_dfree_##name(struct au_##name *p)
 +
 +AuCacheFuncs(dinfo, DINFO);
 +AuCacheFuncs(icntnr, ICNTNR);
@@ -22146,11 +22295,30 @@ diff -urN /usr/share/empty/fs/aufs/module.h linux/fs/aufs/module.h
 +AuCacheFuncs(hnotify, HNOTIFY);
 +#endif
 +
++static inline void au_delayed_kfree(const void *p)
++{
++      AuDebugOn(!p);
++      AuDebugOn(ksize(p) < sizeof(struct llist_node));
++
++      AU_DFREE_BODY((void *)p, au_dfree.llist + AU_DFREE_KFREE);
++}
++
++/* cast only */
++static inline void au_free_page(void *p)
++{
++      free_page((unsigned long)p);
++}
++
++static inline void au_delayed_free_page(unsigned long addr)
++{
++      AU_DFREE_BODY((void *)addr, au_dfree.llist + AU_DFREE_FREE_PAGE);
++}
++
 +#endif /* __KERNEL__ */
 +#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-07-25 19:05:34.814493242 +0200
++++ linux/fs/aufs/mvdown.c     2016-08-17 18:01:06.158556531 +0200
 @@ -0,0 +1,704 @@
 +/*
 + * Copyright (C) 2011-2016 Junjiro R. Okajima
@@ -22851,15 +23019,15 @@ 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_delayed_kfree(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       2016-07-25 19:05:34.814493242 +0200
-@@ -0,0 +1,1859 @@
++++ linux/fs/aufs/opts.c       2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,1860 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -24118,7 +24286,7 @@ diff -urN /usr/share/empty/fs/aufs/opts.c linux/fs/aufs/opts.c
 +              }
 +      }
 +
-+      kfree(a);
++      au_delayed_kfree(a);
 +      dump_opts(opts);
 +      if (unlikely(err))
 +              au_opts_free(opts);
@@ -24540,7 +24708,8 @@ 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);
++                      if (wbr)
++                              au_delayed_kfree(wbr);
 +                      br->br_wbr = NULL;
 +              }
 +      }
@@ -24936,8 +25105,8 @@ 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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,502 @@
++++ linux/fs/aufs/plink.c      2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,514 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -24985,6 +25154,7 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +{
 +      int err;
 +      pid_t pid, ppid;
++      struct task_struct *parent, *prev;
 +      struct au_sbinfo *sbi;
 +
 +      SiMustAnyLock(sb);
@@ -24999,11 +25169,22 @@ diff -urN /usr/share/empty/fs/aufs/plink.c linux/fs/aufs/plink.c
 +              goto out;
 +
 +      /* todo: it highly depends upon /sbin/mount.aufs */
++      prev = NULL;
++      parent = current;
++      ppid = 0;
 +      rcu_read_lock();
-+      ppid = task_pid_vnr(rcu_dereference(current->real_parent));
++      while (1) {
++              parent = rcu_dereference(parent->real_parent);
++              if (parent == prev)
++                      break;
++              ppid = task_pid_vnr(parent);
++              if (pid == ppid) {
++                      rcu_read_unlock();
++                      goto out;
++              }
++              prev = parent;
++      }
 +      rcu_read_unlock();
-+      if (pid == ppid)
-+              goto out;
 +
 +      if (au_ftest_lock(flags, NOPLMW)) {
 +              /* if there is no i_mutex lock in VFS, we don't need to wait */
@@ -26360,8 +26541,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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,353 @@
++++ linux/fs/aufs/sbinfo.c     2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,354 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -26397,7 +26578,7 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +      sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
 +      for (i = 0; i < AuPlink_NHASH; i++)
 +              AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head));
-+      au_nwt_fin(&sbinfo->si_nowait);
++      AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));
 +
 +      AuDebugOn(percpu_counter_sum(&sbinfo->si_ninodes));
 +      percpu_counter_destroy(&sbinfo->si_ninodes);
@@ -26408,14 +26589,15 @@ 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_delayed_kfree(sbinfo->si_branch);
 +      for (i = 0; i < AU_NPIDMAP; i++)
-+              kfree(sbinfo->au_si_pid.pid_bitmap[i]);
++              if (sbinfo->au_si_pid.pid_bitmap[i])
++                      au_delayed_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);
 +
-+      kfree(sbinfo);
++      au_delayed_kfree(sbinfo);
 +}
 +
 +int au_si_alloc(struct super_block *sb)
@@ -26487,9 +26669,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_delayed_kfree(sbinfo->si_branch);
 +out_sbinfo:
-+      kfree(sbinfo);
++      au_delayed_kfree(sbinfo);
 +out:
 +      return err;
 +}
@@ -26717,8 +26899,8 @@ diff -urN /usr/share/empty/fs/aufs/sbinfo.c linux/fs/aufs/sbinfo.c
 +}
 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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,111 @@
++++ linux/fs/aufs/spl.h        2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,113 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -26745,6 +26927,7 @@ diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
 +
 +#ifdef __KERNEL__
 +
++#if 0
 +struct au_splhead {
 +      spinlock_t              spin;
 +      struct list_head        head;
@@ -26777,6 +26960,7 @@ diff -urN /usr/share/empty/fs/aufs/spl.h linux/fs/aufs/spl.h
 +      list_del_rcu(list);
 +      spin_unlock(&spl->spin);
 +}
++#endif
 +
 +/* ---------------------------------------------------------------------- */
 +
@@ -26832,8 +27016,8 @@ 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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,1039 @@
++++ linux/fs/aufs/super.c      2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,1038 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -26882,8 +27066,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +{
 +      struct inode *inode = container_of(head, struct inode, i_rcu);
 +
-+      INIT_HLIST_HEAD(&inode->i_dentry);
-+      au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
++      au_cache_dfree_icntnr(container_of(inode, struct au_icntnr, vfs_inode));
 +}
 +
 +static void aufs_destroy_inode(struct inode *inode)
@@ -27665,7 +27848,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +out_mtx:
 +      inode_unlock(inode);
 +out_opts:
-+      free_page((unsigned long)opts.opt);
++      au_delayed_free_page((unsigned long)opts.opt);
 +out:
 +      err = cvt_err(err);
 +      AuTraceErr(err);
@@ -27806,7 +27989,7 @@ diff -urN /usr/share/empty/fs/aufs/super.c linux/fs/aufs/super.c
 +      kobject_put(&sbinfo->si_kobj);
 +      sb->s_fs_info = NULL;
 +out_opts:
-+      free_page((unsigned long)opts.opt);
++      au_delayed_free_page((unsigned long)opts.opt);
 +out:
 +      AuTraceErr(err);
 +      err = cvt_err(err);
@@ -28730,7 +28913,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-07-25 19:05:34.817826663 +0200
++++ linux/fs/aufs/sysfs.c      2016-08-17 18:01:06.161889951 +0200
 @@ -0,0 +1,376 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -28943,7 +29126,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_delayed_kfree(seq);
 +out_unlock:
 +      si_read_unlock(sb);
 +out:
@@ -29014,9 +29197,9 @@ diff -urN /usr/share/empty/fs/aufs/sysfs.c linux/fs/aufs/sysfs.c
 +              err = -EFAULT;
 +
 +out_seq:
-+      kfree(seq);
++      au_delayed_kfree(seq);
 +out_buf:
-+      free_page((unsigned long)buf);
++      au_delayed_free_page((unsigned long)buf);
 +out:
 +      si_read_unlock(sb);
 +      return err;
@@ -29271,8 +29454,8 @@ 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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,889 @@
++++ linux/fs/aufs/vdir.c       2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,899 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -29385,7 +29568,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_delayed_kfree(pos);
 +}
 +
 +static void au_nhash_de_do_free(struct hlist_head *head)
@@ -29394,7 +29577,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, hash)
-+              au_cache_free_vdir_dehstr(pos);
++              au_cache_dfree_vdir_dehstr(pos);
 +}
 +
 +static void au_nhash_do_free(struct au_nhash *nhash,
@@ -29412,7 +29595,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_delayed_kfree(nhash->nh_head);
 +}
 +
 +void au_nhash_wh_free(struct au_nhash *whlist)
@@ -29455,6 +29638,8 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +      AuDebugOn(!nhash->nh_num || !nhash->nh_head);
 +
 +      v = 0;
++      if (len > 8)
++              len = 8;
 +      while (len--)
 +              v += *name++;
 +      /* v = hash_long(v, magic_bit); */
@@ -29623,15 +29808,23 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +
 +/* ---------------------------------------------------------------------- */
 +
-+void au_vdir_free(struct au_vdir *vdir)
++void au_vdir_free(struct au_vdir *vdir, int atonce)
 +{
 +      unsigned char **deblk;
 +
 +      deblk = vdir->vd_deblk;
-+      while (vdir->vd_nblk--)
-+              kfree(*deblk++);
-+      kfree(vdir->vd_deblk);
-+      au_cache_free_vdir(vdir);
++      if (!atonce) {
++              while (vdir->vd_nblk--)
++                      au_delayed_kfree(*deblk++);
++              au_delayed_kfree(vdir->vd_deblk);
++              au_cache_dfree_vdir(vdir);
++      } else {
++              /* not delayed */
++              while (vdir->vd_nblk--)
++                      kfree(*deblk++);
++              kfree(vdir->vd_deblk);
++              au_cache_free_vdir(vdir);
++      }
 +}
 +
 +static struct au_vdir *alloc_vdir(struct file *file)
@@ -29665,10 +29858,10 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +      if (!err)
 +              return vdir; /* success */
 +
-+      kfree(vdir->vd_deblk);
++      au_delayed_kfree(vdir->vd_deblk);
 +
 +out_free:
-+      au_cache_free_vdir(vdir);
++      au_cache_dfree_vdir(vdir);
 +out:
 +      vdir = ERR_PTR(err);
 +      return vdir;
@@ -29680,7 +29873,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_delayed_kfree(vdir->vd_deblk[vdir->vd_nblk - 1]);
 +              /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */
 +              vdir->vd_nblk--;
 +      }
@@ -29811,7 +30004,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +              }
 +      }
 +
-+      free_page((unsigned long)o);
++      au_delayed_free_page((unsigned long)o);
 +
 +out:
 +      AuTraceErr(err);
@@ -29950,7 +30143,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +              if (allocated)
 +                      au_set_ivdir(inode, allocated);
 +      } else if (allocated)
-+              au_vdir_free(allocated);
++              au_vdir_free(allocated, /*atonce*/0);
 +
 +out:
 +      return err;
@@ -30044,7 +30237,7 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c
 +              if (allocated)
 +                      au_set_fvdir_cache(file, allocated);
 +      } else if (allocated)
-+              au_vdir_free(allocated);
++              au_vdir_free(allocated, /*atonce*/0);
 +
 +out:
 +      return err;
@@ -31052,8 +31245,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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,310 @@
++++ linux/fs/aufs/vfsub.h      2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,316 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -31252,6 +31445,12 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h
 +      return flags;
 +}
 +
++static inline int vfsub_file_execed(struct file *file)
++{
++      /* todo: direct access f_flags */
++      return !!(vfsub_file_flags(file) & __FMODE_EXEC);
++}
++
 +#if 0 /* reserved */
 +static inline void vfsub_file_accessed(struct file *h_file)
 +{
@@ -31366,7 +31565,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-07-25 19:05:34.817826663 +0200
++++ linux/fs/aufs/wbr_policy.c 2016-08-17 18:01:06.161889951 +0200
 @@ -0,0 +1,765 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -31831,7 +32030,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_delayed_kfree(st);
 +}
 +
 +static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags)
@@ -32135,7 +32334,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-07-25 19:05:34.817826663 +0200
++++ linux/fs/aufs/whout.c      2016-08-17 18:01:06.161889951 +0200
 @@ -0,0 +1,1060 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -32301,7 +32500,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +
 +out_name:
 +      if (name != defname)
-+              kfree(name);
++              au_delayed_kfree(name);
 +out:
 +      AuTraceErrPtr(dentry);
 +      return dentry;
@@ -32740,7 +32939,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +      au_br_put(a->br);
 +      si_write_unlock(a->sb);
 +      au_nwt_done(&au_sbi(a->sb)->si_nowait);
-+      kfree(arg);
++      au_delayed_kfree(arg);
 +      if (unlikely(err))
 +              AuIOErr("err %d\n", err);
 +}
@@ -32768,7 +32967,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_br_put(br);
-+                      kfree(arg);
++                      au_delayed_kfree(arg);
 +              }
 +              do_dec = 0;
 +      }
@@ -32927,7 +33126,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_delayed_kfree(wh_name.name);
 +      }
 +      return wh_dentry;
 +}
@@ -33003,7 +33202,7 @@ diff -urN /usr/share/empty/fs/aufs/whout.c linux/fs/aufs/whout.c
 +                      break;
 +              }
 +      }
-+      free_page((unsigned long)wh_name.name);
++      au_delayed_free_page((unsigned long)wh_name.name);
 +
 +out:
 +      return err;
@@ -33045,7 +33244,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_delayed_kfree(whtmp);
 +              whtmp = ERR_PTR(err);
 +      }
 +
@@ -33060,7 +33259,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_delayed_kfree(whtmp);
 +}
 +
 +/*
@@ -33288,8 +33487,8 @@ 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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,218 @@
++++ linux/fs/aufs/wkq.c        2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,213 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -33346,7 +33545,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_delayed_kfree(wkinfo);
 +      }
 +}
 +
@@ -33369,7 +33568,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_delayed_kfree(comp);
 +}
 +
 +#else
@@ -33450,7 +33649,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
 +      int err;
 +      struct au_wkinfo *wkinfo;
 +
-+      percpu_counter_inc(&au_sbi(sb)->si_nowait.nw_len);
++      atomic_inc(&au_sbi(sb)->si_nowait.nw_len);
 +
 +      /*
 +       * wkq_func() must free this wkinfo.
@@ -33480,16 +33679,11 @@ diff -urN /usr/share/empty/fs/aufs/wkq.c linux/fs/aufs/wkq.c
 +
 +void au_nwt_init(struct au_nowait_tasks *nwt)
 +{
-+      percpu_counter_init(&nwt->nw_len, 0, GFP_NOFS);
++      atomic_set(&nwt->nw_len, 0);
++      /* smp_mb(); */ /* atomic_set */
 +      init_waitqueue_head(&nwt->nw_wq);
 +}
 +
-+void au_nwt_fin(struct au_nowait_tasks *nwt)
-+{
-+      AuDebugOn(percpu_counter_sum(&nwt->nw_len));
-+      percpu_counter_destroy(&nwt->nw_len);
-+}
-+
 +void au_wkq_fin(void)
 +{
 +      destroy_workqueue(au_wkq);
@@ -33510,8 +33704,8 @@ 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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,95 @@
++++ linux/fs/aufs/wkq.h        2016-08-17 18:01:06.161889951 +0200
+@@ -0,0 +1,93 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -33549,7 +33743,7 @@ diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
 + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue
 + */
 +struct au_nowait_tasks {
-+      struct percpu_counter   nw_len;
++      atomic_t                nw_len;
 +      wait_queue_head_t       nw_wq;
 +};
 +
@@ -33576,7 +33770,6 @@ diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
 +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb,
 +                unsigned int flags);
 +void au_nwt_init(struct au_nowait_tasks *nwt);
-+void au_nwt_fin(struct au_nowait_tasks *nwt);
 +int __init au_wkq_init(void);
 +void au_wkq_fin(void);
 +
@@ -33594,14 +33787,13 @@ diff -urN /usr/share/empty/fs/aufs/wkq.h linux/fs/aufs/wkq.h
 +
 +static inline void au_nwt_done(struct au_nowait_tasks *nwt)
 +{
-+      percpu_counter_dec(&nwt->nw_len);
-+      if (!percpu_counter_sum(&nwt->nw_len))
++      if (atomic_dec_and_test(&nwt->nw_len))
 +              wake_up_all(&nwt->nw_wq);
 +}
 +
 +static inline int au_nwt_flush(struct au_nowait_tasks *nwt)
 +{
-+      wait_event(nwt->nw_wq, !percpu_counter_sum(&nwt->nw_len));
++      wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len));
 +      return 0;
 +}
 +
@@ -33609,8 +33801,8 @@ 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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,345 @@
++++ linux/fs/aufs/xattr.c      2016-08-17 18:01:06.165223371 +0200
+@@ -0,0 +1,347 @@
 +/*
 + * Copyright (C) 2014-2016 Junjiro R. Okajima
 + *
@@ -33789,10 +33981,12 @@ diff -urN /usr/share/empty/fs/aufs/xattr.c linux/fs/aufs/xattr.c
 +              AuTraceErr(err);
 +      }
 +
-+      kfree(value);
++      if (value)
++              au_delayed_kfree(value);
 +
 +out_free:
-+      kfree(o);
++      if (o)
++              au_delayed_kfree(o);
 +out:
 +      if (!unlocked)
 +              inode_unlock(h_isrc);
@@ -33958,8 +34152,8 @@ 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-07-25 19:05:34.817826663 +0200
-@@ -0,0 +1,1317 @@
++++ linux/fs/aufs/xino.c       2016-08-17 18:01:06.165223371 +0200
+@@ -0,0 +1,1318 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
 + *
@@ -34300,7 +34494,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +              AuErr1("statfs err %d, ignored\n", err);
 +
 +out_st:
-+      kfree(st);
++      au_delayed_kfree(st);
 +out:
 +      return err;
 +}
@@ -34335,7 +34529,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      au_br_put(br);
 +      si_write_unlock(sb);
 +      au_nwt_done(&au_sbi(sb)->si_nowait);
-+      kfree(args);
++      au_delayed_kfree(args);
 +}
 +
 +static int xino_trunc_test(struct super_block *sb, struct au_branch *br)
@@ -34377,7 +34571,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      args = kmalloc(sizeof(*args), GFP_NOFS);
 +      if (unlikely(!args)) {
 +              AuErr1("no memory\n");
-+              goto out_args;
++              goto out;
 +      }
 +
 +      au_br_get(br);
@@ -34389,9 +34583,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +
 +      pr_err("wkq %d\n", wkq_err);
 +      au_br_put(br);
++      au_delayed_kfree(args);
 +
-+out_args:
-+      kfree(args);
 +out:
 +      atomic_dec(&br->br_xino_running);
 +}
@@ -34914,7 +35107,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +                              (sb, au_sbr(sb, bindex)->br_xino.xi_file, page);
 +              else
 +                      AuDbg("b%d\n", bindex);
-+      free_page((unsigned long)page);
++      au_delayed_free_page((unsigned long)page);
 +
 +out:
 +      return err;
@@ -34991,7 +35184,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      if (sbinfo->si_xib)
 +              fput(sbinfo->si_xib);
 +      sbinfo->si_xib = NULL;
-+      free_page((unsigned long)sbinfo->si_xib_buf);
++      if (sbinfo->si_xib_buf)
++              au_delayed_free_page((unsigned long)sbinfo->si_xib_buf);
 +      sbinfo->si_xib_buf = NULL;
 +}
 +
@@ -35034,7 +35228,8 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +      goto out; /* success */
 +
 +out_free:
-+      free_page((unsigned long)sbinfo->si_xib_buf);
++      if (sbinfo->si_xib_buf)
++              au_delayed_free_page((unsigned long)sbinfo->si_xib_buf);
 +      sbinfo->si_xib_buf = NULL;
 +      if (err >= 0)
 +              err = -EIO;
@@ -35127,7 +35322,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +                      fput(p->new);
 +              else
 +                      break;
-+      kfree(fpair);
++      au_delayed_kfree(fpair);
 +out:
 +      return err;
 +}
@@ -35238,7 +35433,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c
 +                      if (!IS_ERR(file))
 +                              au_xino_brid_set(sb, br->br_id);
 +              }
-+              free_page((unsigned long)page);
++              au_delayed_free_page((unsigned long)page);
 +      } else {
 +              file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0);
 +              if (IS_ERR(file))
@@ -35279,7 +35474,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-07-25 19:05:34.817826663 +0200
++++ linux/include/uapi/linux/aufs_type.h       2016-08-17 18:01:21.295617591 +0200
 @@ -0,0 +1,419 @@
 +/*
 + * Copyright (C) 2005-2016 Junjiro R. Okajima
@@ -35322,7 +35517,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin
 +
 +#include <linux/limits.h>
 +
-+#define AUFS_VERSION  "4.x-rcN-20160704"
++#define AUFS_VERSION  "4.7-20160815"
 +
 +/* todo? move this to linux-2.6.19/include/magic.h */
 +#define AUFS_SUPER_MAGIC      ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
@@ -35700,7 +35895,7 @@ 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.x-rcN loopback patch
+aufs4.7 loopback patch
 
 diff --git a/drivers/block/loop.c b/drivers/block/loop.c
 index 7339e65..76e5da4 100644
@@ -35882,10 +36077,10 @@ 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 504b767..09426ad 100644
+index 00475fb..01390e1 100644
 --- a/fs/aufs/f_op.c
 +++ b/fs/aufs/f_op.c
-@@ -346,7 +346,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
+@@ -348,7 +348,7 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
        if (IS_ERR(h_file))
                goto out;
  
@@ -35895,12 +36090,12 @@ index 504b767..09426ad 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 5711e7a..9df5d16 100644
+index e92a345..35f4d48 100644
 --- a/fs/aufs/loop.c
 +++ b/fs/aufs/loop.c
 @@ -131,3 +131,19 @@ void au_loopback_fin(void)
                symbol_put(loop_backing_file);
-       kfree(au_warn_loopback_array);
+       au_delayed_kfree(au_warn_loopback_array);
  }
 +
 +/* ---------------------------------------------------------------------- */
@@ -35944,10 +36139,10 @@ index 48bf070..66afec7 100644
  
  #endif /* __KERNEL__ */
 diff --git a/fs/aufs/super.c b/fs/aufs/super.c
-index 8bd2d9c..26581c0 100644
+index 58a773c..75f212c 100644
 --- a/fs/aufs/super.c
 +++ b/fs/aufs/super.c
-@@ -832,7 +832,10 @@ static const struct super_operations aufs_sop = {
+@@ -831,7 +831,10 @@ static const struct super_operations aufs_sop = {
        .statfs         = aufs_statfs,
        .put_super      = aufs_put_super,
        .sync_fs        = aufs_sync_fs,
index b8d64dce05262eec7dbc5ac8574a2d75408ec81b..8b00cb037177733185499f911efa1511269fec9b 100644 (file)
@@ -70,7 +70,7 @@
 
 %define                rel             1
 %define                basever         4.7
-%define                postver         .0
+%define                postver         .1
 
 # define this to '-%{basever}' for longterm branch
 %define                versuffix       %{nil}
@@ -119,7 +119,7 @@ Source0:    https://www.kernel.org/pub/linux/kernel/v4.x/linux-%{basever}.tar.xz
 # Source0-md5: 5276563eb1f39a048e4a8a887408c031
 %if "%{postver}" != ".0"
 Patch0:                https://www.kernel.org/pub/linux/kernel/v4.x/patch-%{version}.xz
-# Patch0-md5:  c8ff415734155965ae7a2a85ef9c9e03
+# Patch0-md5:  b87c3627d4c3e3043f46c6422dfd83b0
 %endif
 Source1:       kernel.sysconfig
 
This page took 0.49604 seconds and 4 git commands to generate.