#include <linux/fiemap.h>
 #include <linux/fileattr.h>
 #include <linux/security.h>
+#include <linux/namei.h>
 #include "overlayfs.h"
 
 
        const struct cred *old_cred;
        struct posix_acl *acl;
 
-       if (rcu)
-               return ERR_PTR(-ECHILD);
-
        if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode))
                return NULL;
 
+       if (rcu)
+               return get_cached_acl_rcu(realinode, type);
+
        old_cred = ovl_override_creds(inode->i_sb);
        acl = get_acl(realinode, type);
        revert_creds(old_cred);
 
 #include <linux/xattr.h>
 #include <linux/export.h>
 #include <linux/user_namespace.h>
+#include <linux/namei.h>
 
 static struct posix_acl **acl_by_type(struct inode *inode, int type)
 {
 
 struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type)
 {
-       return rcu_dereference(*acl_by_type(inode, type));
+       struct posix_acl *acl = rcu_dereference(*acl_by_type(inode, type));
+
+       if (acl == ACL_DONT_CACHE) {
+               struct posix_acl *ret;
+
+               ret = inode->i_op->get_acl(inode, type, LOOKUP_RCU);
+               if (!IS_ERR(ret))
+                       acl = ret;
+       }
+
+       return acl;
 }
 EXPORT_SYMBOL(get_cached_acl_rcu);
 
 
 
 struct posix_acl;
 #define ACL_NOT_CACHED ((void *)(-1))
+/*
+ * ACL_DONT_CACHE is for stacked filesystems, that rely on underlying fs to
+ * cache the ACL.  This also means that ->get_acl() can be called in RCU mode
+ * with the LOOKUP_RCU flag.
+ */
 #define ACL_DONT_CACHE ((void *)(-3))
 
 static inline struct posix_acl *
 
 extern int set_posix_acl(struct user_namespace *, struct inode *, int,
                         struct posix_acl *);
 
+struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type);
+
 #ifdef CONFIG_FS_POSIX_ACL
 int posix_acl_chmod(struct user_namespace *, struct inode *, umode_t);
 extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
 extern int simple_acl_create(struct inode *, struct inode *);
 
 struct posix_acl *get_cached_acl(struct inode *inode, int type);
-struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type);
 void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl);
 void forget_cached_acl(struct inode *inode, int type);
 void forget_all_cached_acls(struct inode *inode);