diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2021-08-18 22:08:24 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2021-08-18 22:08:24 +0200 |
commit | 332f606b32b6291a944c8cf23b91f53a6e676525 (patch) | |
tree | c3a46cae0901eec40dd900a9a64c8ad1e51647ba /fs/overlayfs | |
parent | 0cad6246621b5887d5b33fea84219d2a71f2f99a (diff) |
ovl: enable RCU'd ->get_acl()
Overlayfs does not cache ACL's (to avoid double caching). Instead it just
calls the underlying filesystem's i_op->get_acl(), which will return the
cached value, if possible.
In rcu path walk, however, get_cached_acl_rcu() is employed to get the
value from the cache, which will fail on overlayfs resulting in dropping
out of rcu walk mode. This can result in a big performance hit in certain
situations.
Fix by calling ->get_acl() with rcu=true in case of ACL_DONT_CACHE (which
indicates pass-through)
Reported-by: garyhuang <zjh.20052005@163.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r-- | fs/overlayfs/inode.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index ea335d3e55cf..832b17589733 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -13,6 +13,7 @@ #include <linux/fiemap.h> #include <linux/fileattr.h> #include <linux/security.h> +#include <linux/namei.h> #include "overlayfs.h" @@ -452,12 +453,12 @@ struct posix_acl *ovl_get_acl(struct inode *inode, int type, bool rcu) 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); |