goto retry;
                }
 
-               error = vfs_setxattr(&init_user_ns, new, name, value, size, 0);
+               error = ovl_do_setxattr(OVL_FS(sb), new, name, value, size, 0);
                if (error) {
                        if (error != -EOPNOTSUPP || ovl_must_copy_xattr(name))
                                break;
        if (IS_ERR(fh))
                return PTR_ERR(fh);
 
-       err = ovl_do_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len);
+       err = ovl_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len);
 
        kfree(fh);
        return err;
        return true;
 }
 
-static ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value)
+static ssize_t ovl_getxattr_value(struct ovl_fs *ofs, struct dentry *dentry,
+                                 char *name, char **value)
 {
        ssize_t res;
        char *buf;
 
-       res = vfs_getxattr(&init_user_ns, dentry, name, NULL, 0);
+       res = ovl_do_getxattr(ofs, dentry, name, NULL, 0);
        if (res == -ENODATA || res == -EOPNOTSUPP)
                res = 0;
 
                if (!buf)
                        return -ENOMEM;
 
-               res = vfs_getxattr(&init_user_ns, dentry, name, buf, res);
+               res = ovl_do_getxattr(ofs, dentry, name, buf, res);
                if (res < 0)
                        kfree(buf);
                else
                return -EIO;
 
        if (c->stat.size) {
-               err = cap_size = ovl_getxattr(upperpath.dentry, XATTR_NAME_CAPS,
-                                             &capability);
+               err = cap_size = ovl_getxattr_value(ofs, upperpath.dentry,
+                                                   XATTR_NAME_CAPS, &capability);
                if (cap_size < 0)
                        goto out;
        }
         * don't want that to happen for normal copy-up operation.
         */
        if (capability) {
-               err = vfs_setxattr(&init_user_ns, upperpath.dentry,
-                                  XATTR_NAME_CAPS, capability, cap_size, 0);
+               err = ovl_do_setxattr(ofs, upperpath.dentry, XATTR_NAME_CAPS,
+                                     capability, cap_size, 0);
                if (err)
                        goto out_free;
        }
 
 
-       err = ovl_do_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY);
+       err = ovl_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY);
        if (err)
                goto out_free;
 
 
        return ERR_PTR(err);
 }
 
-static int ovl_set_upper_acl(struct dentry *upperdentry, const char *name,
-                            const struct posix_acl *acl)
+static int ovl_set_upper_acl(struct ovl_fs *ofs, struct dentry *upperdentry,
+                            const char *name, const struct posix_acl *acl)
 {
        void *buffer;
        size_t size;
        if (err < 0)
                goto out_free;
 
-       err = vfs_setxattr(&init_user_ns, upperdentry, name, buffer, size, XATTR_CREATE);
+       err = ovl_do_setxattr(ofs, upperdentry, name, buffer, size, XATTR_CREATE);
 out_free:
        kfree(buffer);
        return err;
 static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
                                    struct ovl_cattr *cattr)
 {
+       struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
        struct dentry *workdir = ovl_workdir(dentry);
        struct inode *wdir = workdir->d_inode;
        struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
                        goto out_cleanup;
        }
        if (!hardlink) {
-               err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_ACCESS,
-                                       acl);
+               err = ovl_set_upper_acl(ofs, newdentry,
+                                       XATTR_NAME_POSIX_ACL_ACCESS, acl);
                if (err)
                        goto out_cleanup;
 
-               err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_DEFAULT,
-                                       default_acl);
+               err = ovl_set_upper_acl(ofs, newdentry,
+                                       XATTR_NAME_POSIX_ACL_DEFAULT, default_acl);
                if (err)
                        goto out_cleanup;
        }
 
                  const void *value, size_t size, int flags)
 {
        int err;
+       struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
        struct dentry *upperdentry = ovl_i_dentry_upper(inode);
        struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry);
        const struct cred *old_cred;
        }
 
        old_cred = ovl_override_creds(dentry->d_sb);
-       if (value)
-               err = vfs_setxattr(&init_user_ns, realdentry, name, value, size,
-                                  flags);
-       else {
+       if (value) {
+               err = ovl_do_setxattr(ofs, realdentry, name, value, size,
+                                     flags);
+       } else {
                WARN_ON(flags != XATTR_REPLACE);
-               err = vfs_removexattr(&init_user_ns, realdentry, name);
+               err = ovl_do_removexattr(ofs, realdentry, name);
        }
        revert_creds(old_cred);
 
        if (WARN_ON(len >= sizeof(buf)))
                return -EIO;
 
-       return ovl_do_setxattr(OVL_FS(inode->i_sb), ovl_dentry_upper(dentry),
-                              OVL_XATTR_NLINK, buf, len);
+       return ovl_setxattr(OVL_FS(inode->i_sb), ovl_dentry_upper(dentry),
+                           OVL_XATTR_NLINK, buf, len);
 }
 
 int ovl_set_nlink_upper(struct dentry *dentry)
        if (!lowerdentry || !upperdentry || d_inode(lowerdentry)->i_nlink == 1)
                return fallback;
 
-       err = ovl_do_getxattr(ofs, upperdentry, OVL_XATTR_NLINK,
+       err = ovl_getxattr(ofs, upperdentry, OVL_XATTR_NLINK,
                              &buf, sizeof(buf) - 1);
        if (err < 0)
                goto fail;
 
        int res, err;
        struct ovl_fh *fh = NULL;
 
-       res = ovl_do_getxattr(ofs, dentry, ox, NULL, 0);
+       res = ovl_getxattr(ofs, dentry, ox, NULL, 0);
        if (res < 0) {
                if (res == -ENODATA || res == -EOPNOTSUPP)
                        return NULL;
        if (!fh)
                return ERR_PTR(-ENOMEM);
 
-       res = ovl_do_getxattr(ofs, dentry, ox, fh->buf, res);
+       res = ovl_getxattr(ofs, dentry, ox, fh->buf, res);
        if (res < 0)
                goto fail;
 
 
        err = ovl_verify_fh(ofs, dentry, ox, fh);
        if (set && err == -ENODATA)
-               err = ovl_do_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len);
+               err = ovl_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len);
        if (err)
                goto fail;
 
 
 }
 
 static inline ssize_t ovl_do_getxattr(struct ovl_fs *ofs, struct dentry *dentry,
-                                     enum ovl_xattr ox, void *value,
+                                     const char *name, void *value,
                                      size_t size)
 {
-       const char *name = ovl_xattr(ofs, ox);
        int err = vfs_getxattr(&init_user_ns, dentry, name, value, size);
        int len = (value && err > 0) ? err : 0;
 
        return err;
 }
 
+static inline ssize_t ovl_getxattr(struct ovl_fs *ofs, struct dentry *dentry,
+                                  enum ovl_xattr ox, void *value,
+                                  size_t size)
+{
+       return ovl_do_getxattr(ofs, dentry, ovl_xattr(ofs, ox), value, size);
+}
+
 static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry,
-                                 enum ovl_xattr ox, const void *value,
-                                 size_t size)
+                                 const char *name, const void *value,
+                                 size_t size, int flags)
 {
-       const char *name = ovl_xattr(ofs, ox);
-       int err = vfs_setxattr(&init_user_ns, dentry, name, value, size, 0);
-       pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, 0) = %i\n",
-                dentry, name, min((int)size, 48), value, size, err);
+       int err = vfs_setxattr(&init_user_ns, dentry, name, value, size, flags);
+
+       pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n",
+                dentry, name, min((int)size, 48), value, size, flags, err);
        return err;
 }
 
+static inline int ovl_setxattr(struct ovl_fs *ofs, struct dentry *dentry,
+                              enum ovl_xattr ox, const void *value,
+                              size_t size)
+{
+       return ovl_do_setxattr(ofs, dentry, ovl_xattr(ofs, ox), value, size, 0);
+}
+
 static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry,
-                                    enum ovl_xattr ox)
+                                    const char *name)
 {
-       const char *name = ovl_xattr(ofs, ox);
        int err = vfs_removexattr(&init_user_ns, dentry, name);
        pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err);
        return err;
 }
 
+static inline int ovl_removexattr(struct ovl_fs *ofs, struct dentry *dentry,
+                                 enum ovl_xattr ox)
+{
+       return ovl_do_removexattr(ofs, dentry, ovl_xattr(ofs, ox));
+}
+
 static inline int ovl_do_rename(struct inode *olddir, struct dentry *olddentry,
                                struct inode *newdir, struct dentry *newdentry,
                                unsigned int flags)
 
                 * Removing the "impure" xattr is best effort.
                 */
                if (!ovl_want_write(dentry)) {
-                       ovl_do_removexattr(ofs, ovl_dentry_upper(dentry),
-                                          OVL_XATTR_IMPURE);
+                       ovl_removexattr(ofs, ovl_dentry_upper(dentry),
+                                       OVL_XATTR_IMPURE);
                        ovl_drop_write(dentry);
                }
                ovl_clear_flag(OVL_IMPURE, d_inode(dentry));
 
                 * allowed as upper are limited to "normal" ones, where checking
                 * for the above two errors is sufficient.
                 */
-               err = vfs_removexattr(&init_user_ns, work,
-                                     XATTR_NAME_POSIX_ACL_DEFAULT);
+               err = ovl_do_removexattr(ofs, work,
+                                        XATTR_NAME_POSIX_ACL_DEFAULT);
                if (err && err != -ENODATA && err != -EOPNOTSUPP)
                        goto out_dput;
 
-               err = vfs_removexattr(&init_user_ns, work,
-                                     XATTR_NAME_POSIX_ACL_ACCESS);
+               err = ovl_do_removexattr(ofs, work,
+                                        XATTR_NAME_POSIX_ACL_ACCESS);
                if (err && err != -ENODATA && err != -EOPNOTSUPP)
                        goto out_dput;
 
        /*
         * Check if upper/work fs supports (trusted|user).overlay.* xattr
         */
-       err = ovl_do_setxattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE, "0", 1);
+       err = ovl_setxattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE, "0", 1);
        if (err) {
                ofs->noxattr = true;
                if (ofs->config.index || ofs->config.metacopy) {
                }
                err = 0;
        } else {
-               ovl_do_removexattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE);
+               ovl_removexattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE);
        }
 
        /*
 
 {
        int res;
 
-       res = ovl_do_getxattr(ofs, dentry, OVL_XATTR_ORIGIN, NULL, 0);
+       res = ovl_getxattr(ofs, dentry, OVL_XATTR_ORIGIN, NULL, 0);
 
        /* Zero size value means "copied up but origin unknown" */
        if (res >= 0)
        if (!d_is_dir(dentry))
                return false;
 
-       res = ovl_do_getxattr(OVL_FS(sb), dentry, ox, &val, 1);
+       res = ovl_getxattr(OVL_FS(sb), dentry, ox, &val, 1);
        if (res == 1 && val == 'y')
                return true;
 
        if (ofs->noxattr)
                return xerr;
 
-       err = ovl_do_setxattr(ofs, upperdentry, ox, value, size);
+       err = ovl_setxattr(ofs, upperdentry, ox, value, size);
 
        if (err == -EOPNOTSUPP) {
                pr_warn("cannot set %s xattr on upper\n", ovl_xattr(ofs, ox));
        char buf[OVL_PROTATTR_MAX+1];
        int res, n;
 
-       res = ovl_do_getxattr(ofs, upper, OVL_XATTR_PROTATTR, buf,
+       res = ovl_getxattr(ofs, upper, OVL_XATTR_PROTATTR, buf,
                              OVL_PROTATTR_MAX);
        if (res < 0)
                return;
                err = ovl_check_setxattr(ofs, upper, OVL_XATTR_PROTATTR,
                                         buf, len, -EPERM);
        } else if (inode->i_flags & OVL_PROT_I_FLAGS_MASK) {
-               err = ovl_do_removexattr(ofs, upper, OVL_XATTR_PROTATTR);
+               err = ovl_removexattr(ofs, upper, OVL_XATTR_PROTATTR);
                if (err == -EOPNOTSUPP || err == -ENODATA)
                        err = 0;
        }
        if (!S_ISREG(d_inode(dentry)->i_mode))
                return 0;
 
-       res = ovl_do_getxattr(ofs, dentry, OVL_XATTR_METACOPY, NULL, 0);
+       res = ovl_getxattr(ofs, dentry, OVL_XATTR_METACOPY, NULL, 0);
        if (res < 0) {
                if (res == -ENODATA || res == -EOPNOTSUPP)
                        return 0;
        int res;
        char *s, *next, *buf = NULL;
 
-       res = ovl_do_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, NULL, 0);
+       res = ovl_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, NULL, 0);
        if (res == -ENODATA || res == -EOPNOTSUPP)
                return NULL;
        if (res < 0)
        if (!buf)
                return ERR_PTR(-ENOMEM);
 
-       res = ovl_do_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, buf, res);
+       res = ovl_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, buf, res);
        if (res < 0)
                goto fail;
        if (res == 0)