vfs_setxattr(), vfs_getxattr(), vfs_listxattr() and vfs_removexattr()
along with their __vfs_setxattr_locked()/__vfs_removexattr_locked()
counterparts and the do_setxattr()/do_getxattr()/listxattr()/
removexattr() syscall helpers take a struct mnt_idmap and a struct
dentry even though callers either already hold a struct path (or a
struct file) or have to pass &nop_mnt_idmap because no idmapped
mount is involved.  Switch them all to take a struct path instead
and derive the idmap and dentry from it where needed.

__vfs_setxattr_noperm(), __vfs_getxattr(), __vfs_setxattr(),
__vfs_removexattr() and vfs_getxattr_alloc() keep taking the idmap
and dentry as they are only called from contexts that operate on
bare dentries such as LSM internals.  The SELinux and Smack
inode_setsecctx implementations now pass the path they got from the
previous patch straight through.

The security_inode_*xattr() hooks invoked from fs/xattr.c keep
taking the idmap and dentry for now; they will be converted together
with the LSM hooks themselves in separate patches.

evm_calc_hmac_or_hash() contains a redundant xattr size sanity check
which calls vfs_getxattr() only to emit a debug message when the
kernel-side and user-space-side xattr sizes differ, without ever
influencing the result.  Because that function only has a dentry, the
call cannot be migrated to the new path-based signature; drop the
check and the now unused user_space_size variable instead.

Assisted-by: opencode: glm-5.3
Signed-off-by: Cai Xinchen <[email protected]>
---
 drivers/block/zloop.c               |   4 +-
 fs/cachefiles/xattr.c               |  32 ++++----
 fs/ecryptfs/inode.c                 |   8 +-
 fs/nfsd/nfs4ctl.h                   |   4 +-
 fs/nfsd/vfs.c                       |  57 +++++++-------
 fs/overlayfs/copy_up.c              |   4 +-
 fs/overlayfs/overlayfs.h            |  18 +++--
 fs/overlayfs/xattrs.c               |  13 +++-
 fs/smb/server/smb2pdu.c             |  75 +++++++------------
 fs/smb/server/smb_common.c          |   2 -
 fs/smb/server/smbacl.c              |  19 +++--
 fs/smb/server/tests/smbacl_kunit.c  |   6 +-
 fs/smb/server/vfs.c                 | 112 ++++++++++++----------------
 fs/smb/server/vfs.h                 |  39 ++++------
 fs/smb/server/vfs_cache.c           |   3 +-
 fs/xattr.c                          |  92 ++++++++++++-----------
 include/linux/xattr.h               |  22 +++---
 security/integrity/evm/evm_crypto.c |   8 +-
 security/selinux/hooks.c            |   4 +-
 security/smack/smack_lsm.c          |   4 +-
 20 files changed, 243 insertions(+), 283 deletions(-)

diff --git a/drivers/block/zloop.c b/drivers/block/zloop.c
index f0ca221524db..d77b114d69fc 100644
--- a/drivers/block/zloop.c
+++ b/drivers/block/zloop.c
@@ -710,7 +710,7 @@ static int zloop_record_safe_wps(struct zloop_device *zlo)
 
                if (!zloop_zone_is_active(zone))
                        continue;
-               ret = vfs_setxattr(file_mnt_idmap(file), file_dentry(file),
+               ret = vfs_setxattr(&file->f_path,
                                "user.zloop.wp", &zone->wp, sizeof(zone->wp), 
0);
                if (ret) {
                        pr_err("%pg: failed to record write pointer (%d)\n",
@@ -1395,7 +1395,7 @@ static void zloop_forget_cache(struct zloop_device *zlo)
                if (!zloop_zone_is_active(zone))
                        continue;
 
-               ret = vfs_getxattr(file_mnt_idmap(file), file_dentry(file),
+               ret = vfs_getxattr(&file->f_path,
                                "user.zloop.wp", &old_wp, sizeof(old_wp));
                if (ret == -ENODATA) {
                        old_wp = 0;
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index c70bf67e52b0..5a0b50bcfb73 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -40,14 +40,12 @@ struct cachefiles_vol_xattr {
 int cachefiles_set_object_xattr(struct cachefiles_object *object)
 {
        struct cachefiles_xattr *buf;
-       struct dentry *dentry;
        struct file *file = object->file;
        unsigned int len = object->cookie->aux_len;
        int ret;
 
        if (!file)
                return -ESTALE;
-       dentry = file->f_path.dentry;
 
        _enter("%x,#%d", object->debug_id, len);
 
@@ -69,7 +67,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object 
*object)
        if (ret == 0) {
                ret = mnt_want_write_file(file);
                if (ret == 0) {
-                       ret = vfs_setxattr(&nop_mnt_idmap, dentry,
+                       ret = vfs_setxattr(&file->f_path,
                                           cachefiles_xattr_cache, buf,
                                           sizeof(struct cachefiles_xattr) + 
len, 0);
                        mnt_drop_write_file(file);
@@ -102,7 +100,6 @@ int cachefiles_set_object_xattr(struct cachefiles_object 
*object)
 int cachefiles_check_auxdata(struct cachefiles_object *object, struct file 
*file)
 {
        struct cachefiles_xattr *buf;
-       struct dentry *dentry = file->f_path.dentry;
        unsigned int len = object->cookie->aux_len, tlen;
        const void *p = fscache_get_aux(object->cookie);
        enum cachefiles_coherency_trace why;
@@ -117,7 +114,7 @@ int cachefiles_check_auxdata(struct cachefiles_object 
*object, struct file *file
 
        xlen = cachefiles_inject_read_error();
        if (xlen == 0)
-               xlen = vfs_getxattr(&nop_mnt_idmap, dentry, 
cachefiles_xattr_cache, buf, tlen);
+               xlen = vfs_getxattr(&file->f_path, cachefiles_xattr_cache, buf, 
tlen);
        if (xlen != tlen) {
                if (xlen < 0) {
                        ret = xlen;
@@ -161,14 +158,14 @@ int cachefiles_remove_object_xattr(struct 
cachefiles_cache *cache,
                                   struct cachefiles_object *object,
                                   struct dentry *dentry)
 {
+       struct path path = { .mnt = cache->mnt, .dentry = dentry };
        int ret;
 
        ret = cachefiles_inject_remove_error();
        if (ret == 0) {
                ret = mnt_want_write(cache->mnt);
                if (ret == 0) {
-                       ret = vfs_removexattr(&nop_mnt_idmap, dentry,
-                                             cachefiles_xattr_cache);
+                       ret = vfs_removexattr(&path, cachefiles_xattr_cache);
                        mnt_drop_write(cache->mnt);
                }
        }
@@ -214,7 +211,8 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume 
*volume)
        struct cachefiles_vol_xattr *buf;
        unsigned int len = volume->vcookie->coherency_len;
        const void *p = volume->vcookie->coherency;
-       struct dentry *dentry = volume->dentry;
+       struct path path = { .mnt = volume->cache->mnt,
+                            .dentry = volume->dentry };
        int ret;
 
        _enter("%x,#%d", volume->vcookie->debug_id, len);
@@ -230,22 +228,21 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume 
*volume)
        if (ret == 0) {
                ret = mnt_want_write(volume->cache->mnt);
                if (ret == 0) {
-                       ret = vfs_setxattr(&nop_mnt_idmap, dentry,
-                                          cachefiles_xattr_cache,
+                       ret = vfs_setxattr(&path, cachefiles_xattr_cache,
                                           buf, len, 0);
                        mnt_drop_write(volume->cache->mnt);
                }
        }
        if (ret < 0) {
-               trace_cachefiles_vfs_error(NULL, d_inode(dentry), ret,
+               trace_cachefiles_vfs_error(NULL, d_inode(path.dentry), ret,
                                           cachefiles_trace_setxattr_error);
-               trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino,
+               trace_cachefiles_vol_coherency(volume, 
d_inode(path.dentry)->i_ino,
                                               
cachefiles_coherency_vol_set_fail);
                if (ret != -ENOMEM)
                        cachefiles_io_error(
                                volume->cache, "Failed to set xattr with error 
%d", ret);
        } else {
-               trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino,
+               trace_cachefiles_vol_coherency(volume, 
d_inode(path.dentry)->i_ino,
                                               cachefiles_coherency_vol_set_ok);
        }
 
@@ -260,9 +257,10 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume 
*volume)
 int cachefiles_check_volume_xattr(struct cachefiles_volume *volume)
 {
        struct cachefiles_vol_xattr *buf;
-       struct dentry *dentry = volume->dentry;
        unsigned int len = volume->vcookie->coherency_len;
        const void *p = volume->vcookie->coherency;
+       struct path path = { .mnt = volume->cache->mnt,
+                            .dentry = volume->dentry };
        enum cachefiles_coherency_trace why;
        ssize_t xlen;
        int ret = -ESTALE;
@@ -276,11 +274,11 @@ int cachefiles_check_volume_xattr(struct 
cachefiles_volume *volume)
 
        xlen = cachefiles_inject_read_error();
        if (xlen == 0)
-               xlen = vfs_getxattr(&nop_mnt_idmap, dentry, 
cachefiles_xattr_cache, buf, len);
+               xlen = vfs_getxattr(&path, cachefiles_xattr_cache, buf, len);
        if (xlen != len) {
                if (xlen < 0) {
                        ret = xlen;
-                       trace_cachefiles_vfs_error(NULL, d_inode(dentry), xlen,
+                       trace_cachefiles_vfs_error(NULL, d_inode(path.dentry), 
xlen,
                                                   
cachefiles_trace_getxattr_error);
                        if (xlen == -EIO)
                                cachefiles_io_error(
@@ -297,7 +295,7 @@ int cachefiles_check_volume_xattr(struct cachefiles_volume 
*volume)
                ret = 0;
        }
 
-       trace_cachefiles_vol_coherency(volume, d_inode(dentry)->i_ino, why);
+       trace_cachefiles_vol_coherency(volume, d_inode(path.dentry)->i_ino, 
why);
        kfree(buf);
        _leave(" = %d", ret);
        return ret;
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 627d456f9c38..3307cf13b5b4 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -991,17 +991,17 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode 
*inode,
                  size_t size, int flags)
 {
        int rc;
-       struct dentry *lower_dentry;
+       struct path lower_path;
        struct inode *lower_inode;
 
-       lower_dentry = ecryptfs_dentry_to_lower(dentry);
-       lower_inode = d_inode(lower_dentry);
+       lower_path = ecryptfs_lower_path(dentry);
+       lower_inode = d_inode(lower_path.dentry);
        if (!(lower_inode->i_opflags & IOP_XATTR)) {
                rc = -EOPNOTSUPP;
                goto out;
        }
        inode_lock(lower_inode);
-       rc = __vfs_setxattr_locked(&nop_mnt_idmap, lower_dentry, name, value, 
size, flags, NULL);
+       rc = __vfs_setxattr_locked(&lower_path, name, value, size, flags, NULL);
        inode_unlock(lower_inode);
        if (!rc && inode)
                fsstack_copy_attr_all(inode, lower_inode);
diff --git a/fs/nfsd/nfs4ctl.h b/fs/nfsd/nfs4ctl.h
index bcec4c4ef1d5..97ab3d4212aa 100644
--- a/fs/nfsd/nfs4ctl.h
+++ b/fs/nfsd/nfs4ctl.h
@@ -38,7 +38,7 @@ int nfsd4_create_laundry_wq(void);
 void nfsd4_destroy_laundry_wq(void);
 bool nfsd_wait_for_delegreturn(struct svc_rqst *rqstp, struct inode *inode);
 
-extern int nfsd4_is_junction(struct dentry *dentry);
+extern int nfsd4_is_junction(const struct path *path);
 extern int register_cld_notifier(void);
 extern void unregister_cld_notifier(void);
 #ifdef CONFIG_NFSD_V4_2_INTER_SSC
@@ -68,7 +68,7 @@ static inline bool nfsd_wait_for_delegreturn(struct svc_rqst 
*rqstp,
        return false;
 }
 
-static inline int nfsd4_is_junction(struct dentry *dentry)
+static inline int nfsd4_is_junction(const struct path *path)
 {
        return 0;
 }
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 922337083fe9..a3b86fa60dca 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -233,11 +233,13 @@ static int nfsd_lookup_parent(struct svc_rqst *rqstp, 
struct dentry *dparent, st
  */
 int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
 {
+       struct path path = { .mnt = exp->ex_path.mnt, .dentry = dentry };
+
        if (!d_inode(dentry))
                return 0;
        if (exp->ex_flags & NFSEXP_V4ROOT)
                return 1;
-       if (nfsd4_is_junction(dentry))
+       if (nfsd4_is_junction(&path))
                return 1;
        if (d_managed(dentry))
                /*
@@ -684,14 +686,14 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
 /**
  * nfsd4_is_junction - Test if an object could be an NFS junction
  *
- * @dentry: object to test
+ * @path: object to test
  *
- * Returns 1 if "dentry" appears to contain NFS junction information.
+ * Returns 1 if "path" appears to contain NFS junction information.
  * Otherwise 0 is returned.
  */
-int nfsd4_is_junction(struct dentry *dentry)
+int nfsd4_is_junction(const struct path *path)
 {
-       struct inode *inode = d_inode(dentry);
+       struct inode *inode = d_inode(path->dentry);
 
        if (inode == NULL)
                return 0;
@@ -699,8 +701,7 @@ int nfsd4_is_junction(struct dentry *dentry)
                return 0;
        if (!(inode->i_mode & S_ISVTX))
                return 0;
-       if (vfs_getxattr(&nop_mnt_idmap, dentry, NFSD_JUNCTION_XATTR_NAME,
-                        NULL, 0) <= 0)
+       if (vfs_getxattr(path, NFSD_JUNCTION_XATTR_NAME, NULL, 0) <= 0)
                return 0;
        return 1;
 }
@@ -2619,19 +2620,20 @@ nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh 
*fhp, char *name,
        __be32 err;
        char *buf;
        struct inode *inode;
-       struct dentry *dentry;
+       struct path path;
 
        err = fh_verify(rqstp, fhp, 0, NFSD_MAY_READ);
        if (err)
                return err;
 
        err = nfs_ok;
-       dentry = fhp->fh_dentry;
-       inode = d_inode(dentry);
+       path.mnt = fhp->fh_export->ex_path.mnt;
+       path.dentry = fhp->fh_dentry;
+       inode = d_inode(path.dentry);
 
        inode_lock_shared(inode);
 
-       len = vfs_getxattr(&nop_mnt_idmap, dentry, name, NULL, 0);
+       len = vfs_getxattr(&path, name, NULL, 0);
 
        /*
         * Zero-length attribute, just return.
@@ -2658,7 +2660,7 @@ nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 
char *name,
                goto out;
        }
 
-       len = vfs_getxattr(&nop_mnt_idmap, dentry, name, buf, len);
+       len = vfs_getxattr(&path, name, buf, len);
        if (len <= 0) {
                kvfree(buf);
                buf = NULL;
@@ -2692,19 +2694,20 @@ nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh 
*fhp, char **bufp,
        __be32 err;
        char *buf;
        struct inode *inode;
-       struct dentry *dentry;
+       struct path path;
 
        err = fh_verify(rqstp, fhp, 0, NFSD_MAY_READ);
        if (err)
                return err;
 
-       dentry = fhp->fh_dentry;
-       inode = d_inode(dentry);
+       path.mnt = fhp->fh_export->ex_path.mnt;
+       path.dentry = fhp->fh_dentry;
+       inode = d_inode(path.dentry);
        *lenp = 0;
 
        inode_lock_shared(inode);
 
-       len = vfs_listxattr(dentry, NULL, 0);
+       len = vfs_listxattr(&path, NULL, 0);
        if (len <= 0) {
                err = nfsd_xattr_errno(len);
                goto out;
@@ -2721,7 +2724,7 @@ nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh 
*fhp, char **bufp,
                goto out;
        }
 
-       len = vfs_listxattr(dentry, buf, len);
+       len = vfs_listxattr(&path, buf, len);
        if (len <= 0) {
                kvfree(buf);
                err = nfsd_xattr_errno(len);
@@ -2754,6 +2757,7 @@ nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh 
*fhp, char *name)
 {
        __be32 err;
        int ret;
+       struct path path;
 
        err = fh_verify(rqstp, fhp, 0, NFSD_MAY_WRITE);
        if (err)
@@ -2763,16 +2767,17 @@ nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh 
*fhp, char *name)
        if (ret)
                return nfserrno(ret);
 
-       inode_lock(fhp->fh_dentry->d_inode);
+       path.mnt = fhp->fh_export->ex_path.mnt;
+       path.dentry = fhp->fh_dentry;
+       inode_lock(d_inode(path.dentry));
        err = fh_fill_pre_attrs(fhp);
        if (err != nfs_ok)
                goto out_unlock;
-       ret = __vfs_removexattr_locked(&nop_mnt_idmap, fhp->fh_dentry,
-                                      name, NULL);
+       ret = __vfs_removexattr_locked(&path, name, NULL);
        err = nfsd_xattr_errno(ret);
        fh_fill_post_attrs(fhp);
 out_unlock:
-       inode_unlock(fhp->fh_dentry->d_inode);
+       inode_unlock(d_inode(path.dentry));
        fh_drop_write(fhp);
 
        return err;
@@ -2784,6 +2789,7 @@ nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, 
char *name,
 {
        __be32 err;
        int ret;
+       struct path path;
 
        err = fh_verify(rqstp, fhp, 0, NFSD_MAY_WRITE);
        if (err)
@@ -2792,16 +2798,17 @@ nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh 
*fhp, char *name,
        ret = fh_want_write(fhp);
        if (ret)
                return nfserrno(ret);
-       inode_lock(fhp->fh_dentry->d_inode);
+       path.mnt = fhp->fh_export->ex_path.mnt;
+       path.dentry = fhp->fh_dentry;
+       inode_lock(d_inode(path.dentry));
        err = fh_fill_pre_attrs(fhp);
        if (err != nfs_ok)
                goto out_unlock;
-       ret = __vfs_setxattr_locked(&nop_mnt_idmap, fhp->fh_dentry,
-                                   name, buf, len, flags, NULL);
+       ret = __vfs_setxattr_locked(&path, name, buf, len, flags, NULL);
        fh_fill_post_attrs(fhp);
        err = nfsd_xattr_errno(ret);
 out_unlock:
-       inode_unlock(fhp->fh_dentry->d_inode);
+       inode_unlock(d_inode(path.dentry));
        fh_drop_write(fhp);
        return err;
 }
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index e963701b4c87..6dc241f195a6 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -83,7 +83,7 @@ int ovl_copy_xattr(struct super_block *sb, const struct path 
*oldpath, struct de
        if (!old->d_inode->i_op->listxattr || !new->d_inode->i_op->listxattr)
                return 0;
 
-       list_size = vfs_listxattr(old, NULL, 0);
+       list_size = vfs_listxattr(oldpath, NULL, 0);
        if (list_size <= 0) {
                if (list_size == -EOPNOTSUPP)
                        return 0;
@@ -94,7 +94,7 @@ int ovl_copy_xattr(struct super_block *sb, const struct path 
*oldpath, struct de
        if (!buf)
                return -ENOMEM;
 
-       list_size = vfs_listxattr(old, buf, list_size);
+       list_size = vfs_listxattr(oldpath, buf, list_size);
        if (list_size <= 0) {
                error = list_size;
                goto out;
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index d915b87c0b06..c13f6b2c915c 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -291,8 +291,7 @@ static inline ssize_t ovl_do_getxattr(const struct path 
*path, const char *name,
 
        WARN_ON(path->dentry->d_sb != path->mnt->mnt_sb);
 
-       err = vfs_getxattr(mnt_idmap(path->mnt), path->dentry,
-                              name, value, size);
+       err = vfs_getxattr(path, name, value, size);
        len = (value && err > 0) ? err : 0;
 
        pr_debug("getxattr(%pd2, \"%s\", \"%*pE\", %zu, 0) = %i\n",
@@ -325,9 +324,13 @@ static inline int ovl_do_setxattr(struct ovl_fs *ofs, 
struct dentry *dentry,
                                  const char *name, const void *value,
                                  size_t size, int flags)
 {
+       struct path path = {
+               .mnt = ovl_upper_mnt(ofs),
+               .dentry = dentry,
+       };
+
        /* Use vfs_setxattr(), not __vfs_setxattr(): it idmaps the 
security.capability rootid. */
-       int err = vfs_setxattr(ovl_upper_mnt_idmap(ofs), dentry, name,
-                              value, size, flags);
+       int err = vfs_setxattr(&path, name, value, size, flags);
 
        pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n",
                 dentry, name, min((int)size, 48), value, size, flags, err);
@@ -344,7 +347,12 @@ static inline int ovl_setxattr(struct ovl_fs *ofs, struct 
dentry *dentry,
 static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry,
                                     const char *name)
 {
-       int err = vfs_removexattr(ovl_upper_mnt_idmap(ofs), dentry, name);
+       struct path path = {
+               .mnt = ovl_upper_mnt(ofs),
+               .dentry = dentry,
+       };
+
+       int err = vfs_removexattr(&path, name);
        pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err);
        return err;
 }
diff --git a/fs/overlayfs/xattrs.c b/fs/overlayfs/xattrs.c
index 5ae44b9c8790..b4658324b9f3 100644
--- a/fs/overlayfs/xattrs.c
+++ b/fs/overlayfs/xattrs.c
@@ -45,7 +45,7 @@ static int ovl_xattr_set(struct dentry *dentry, struct inode 
*inode, const char
        if (!value && !upperdentry) {
                ovl_path_lower(dentry, &realpath);
                with_ovl_creds(dentry->d_sb)
-                       err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, 
name, NULL, 0);
+                       err = vfs_getxattr(&realpath, name, NULL, 0);
                if (err < 0)
                        goto out;
        }
@@ -86,7 +86,7 @@ static int ovl_xattr_get(struct dentry *dentry, struct inode 
*inode, const char
        ovl_i_path_real(inode, &realpath);
        /* Use vfs_getxattr(), not __vfs_getxattr(): it idmaps the 
security.capability rootid. */
        with_ovl_creds(dentry->d_sb)
-               return vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, 
name, value, size);
+               return vfs_getxattr(&realpath, name, value, size);
 }
 
 static bool ovl_can_list(struct super_block *sb, const char *s)
@@ -105,15 +105,20 @@ static bool ovl_can_list(struct super_block *sb, const 
char *s)
 
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
 {
-       struct dentry *realdentry = ovl_dentry_real(dentry);
+       struct path realpath;
        struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
        ssize_t res;
        size_t len;
        char *s;
        size_t prefix_len, name_len;
 
+       if (ovl_dentry_upper(dentry))
+               ovl_path_upper(dentry, &realpath);
+       else
+               ovl_path_lower(dentry, &realpath);
+
        with_ovl_creds(dentry->d_sb)
-               res = vfs_listxattr(realdentry, list, size);
+               res = vfs_listxattr(&realpath, list, size);
        if (res <= 0 || size == 0)
                return res;
 
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index fb3ee170db3c..b5db5f280701 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -3293,7 +3293,6 @@ static bool smb2_is_private_ea(const char *name, size_t 
name_len)
 static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
                       const struct path *path, bool get_write)
 {
-       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
        char *attr_name = NULL, *value;
        int rc = 0;
        unsigned int next = 0;
@@ -3333,16 +3332,14 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, 
unsigned int buf_len,
                value = (char *)&eabuf->name + eabuf->EaNameLength + 1;
 
                if (!eabuf->EaValueLength) {
-                       rc = ksmbd_vfs_casexattr_len(idmap,
-                                                    path->dentry,
+                       rc = ksmbd_vfs_casexattr_len(path,
                                                     attr_name,
                                                     XATTR_USER_PREFIX_LEN +
                                                     eabuf->EaNameLength);
 
                        /* delete the EA only when it exits */
                        if (rc > 0) {
-                               rc = ksmbd_vfs_remove_xattr(idmap,
-                                                           path,
+                               rc = ksmbd_vfs_remove_xattr(path,
                                                            attr_name,
                                                            get_write);
 
@@ -3357,7 +3354,7 @@ static int smb2_set_ea(struct smb2_ea_info *eabuf, 
unsigned int buf_len,
                        /* if the EA doesn't exist, just do nothing. */
                        rc = 0;
                } else {
-                       rc = ksmbd_vfs_setxattr(idmap, path, attr_name, value,
+                       rc = ksmbd_vfs_setxattr(path, attr_name, value,
                                                
le16_to_cpu(eabuf->EaValueLength),
                                                0, get_write);
                        if (rc < 0) {
@@ -3394,7 +3391,6 @@ static noinline int smb2_set_stream_name_xattr(const 
struct path *path,
                                               struct ksmbd_file *fp,
                                               char *stream_name, int s_type)
 {
-       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
        size_t xattr_stream_size;
        char *xattr_stream_name;
        int rc;
@@ -3410,8 +3406,7 @@ static noinline int smb2_set_stream_name_xattr(const 
struct path *path,
        fp->stream.size = xattr_stream_size;
 
        /* Check if there is stream prefix in xattr space */
-       rc = ksmbd_vfs_casexattr_len(idmap,
-                                    path->dentry,
+       rc = ksmbd_vfs_casexattr_len(path,
                                     xattr_stream_name,
                                     xattr_stream_size);
        if (rc >= 0)
@@ -3438,7 +3433,7 @@ static noinline int smb2_set_stream_name_xattr(const 
struct path *path,
                                0x00, 0x00, 0x01, 0x00, /* version */
                                [15] = 0x80,            /* backup time */
                        };
-                       rc = ksmbd_vfs_setxattr(idmap, path, xattr_stream_name,
+                       rc = ksmbd_vfs_setxattr(path, xattr_stream_name,
                                                (void *)afpinfo_empty,
                                                sizeof(afpinfo_empty), 0, 
false);
                        return rc < 0 ? rc : 0;
@@ -3447,7 +3442,7 @@ static noinline int smb2_set_stream_name_xattr(const 
struct path *path,
                return -EBADF;
        }
 
-       rc = ksmbd_vfs_setxattr(idmap, path, xattr_stream_name, NULL, 0, 0, 
false);
+       rc = ksmbd_vfs_setxattr(path, xattr_stream_name, NULL, 0, 0, false);
        if (rc < 0)
                pr_err("Failed to store XATTR stream name :%d\n", rc);
        return 0;
@@ -3462,8 +3457,7 @@ static noinline int smb2_set_stream_name_xattr(const 
struct path *path,
  */
 static loff_t ksmbd_stream_eof(struct ksmbd_file *fp)
 {
-       ssize_t slen = ksmbd_vfs_casexattr_len(file_mnt_idmap(fp->filp),
-                                              fp->filp->f_path.dentry,
+       ssize_t slen = ksmbd_vfs_casexattr_len(&fp->filp->f_path,
                                               fp->stream.name,
                                               fp->stream.size);
        return slen < 0 ? 0 : (loff_t)slen;
@@ -3471,12 +3465,11 @@ static loff_t ksmbd_stream_eof(struct ksmbd_file *fp)
 
 static int smb2_remove_smb_xattrs(const struct path *path)
 {
-       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
        char *name, *xattr_list = NULL;
        ssize_t xattr_list_len;
        int err = 0;
 
-       xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
+       xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list);
        if (xattr_list_len < 0) {
                goto out;
        } else if (!xattr_list_len) {
@@ -3491,8 +3484,7 @@ static int smb2_remove_smb_xattrs(const struct path *path)
                if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
                    !strncmp(&name[XATTR_USER_PREFIX_LEN], STREAM_PREFIX,
                             STREAM_PREFIX_LEN)) {
-                       err = ksmbd_vfs_remove_xattr(idmap, path,
-                                                    name, true);
+                       err = ksmbd_vfs_remove_xattr(path, name, true);
                        if (err)
                                ksmbd_debug(SMB, "remove xattr failed : %s\n",
                                            name);
@@ -3538,7 +3530,7 @@ static void smb2_new_xattrs(struct ksmbd_tree_connect 
*tcon, const struct path *
        da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
                XATTR_DOSINFO_ITIME;
 
-       rc = ksmbd_vfs_set_dos_attrib_xattr(mnt_idmap(path->mnt), path, &da, 
true);
+       rc = ksmbd_vfs_set_dos_attrib_xattr(path, &da, true);
        if (rc)
                ksmbd_debug(SMB, "failed to store file attribute into xattr\n");
 }
@@ -3547,6 +3539,7 @@ static bool smb2_parent_compressed(struct 
ksmbd_tree_connect *tcon,
                                   const struct path *path)
 {
        struct dentry *parent = dget_parent(path->dentry);
+       struct path parent_path = { .mnt = path->mnt, .dentry = parent };
        struct file_kattr fa = { .flags_valid = true };
        struct xattr_dos_attrib da;
        bool compressed = false;
@@ -3558,7 +3551,7 @@ static bool smb2_parent_compressed(struct 
ksmbd_tree_connect *tcon,
                goto out;
        }
 
-       rc = ksmbd_vfs_get_dos_attrib_xattr(mnt_idmap(path->mnt), parent, &da);
+       rc = ksmbd_vfs_get_dos_attrib_xattr(&parent_path, &da);
        if (rc > 0 && da.attr & FILE_ATTRIBUTE_COMPRESSED)
                compressed = true;
 
@@ -3578,8 +3571,7 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect 
*tcon,
        fp->f_ci->m_fattr &= ~(FILE_ATTRIBUTE_HIDDEN_LE | 
FILE_ATTRIBUTE_SYSTEM_LE);
 
        /* get FileAttributes from XATTR_NAME_DOS_ATTRIBUTE */
-       rc = ksmbd_vfs_get_dos_attrib_xattr(mnt_idmap(path->mnt),
-                                           path->dentry, &da);
+       rc = ksmbd_vfs_get_dos_attrib_xattr(path, &da);
        if (rc > 0) {
                if (store_dos_attrs) {
                        fp->f_ci->m_fattr = cpu_to_le32(da.attr);
@@ -4524,8 +4516,7 @@ int smb2_open(struct ksmbd_work *work)
 
                        if (test_share_config_flag(tcon->share_conf,
                                                   
KSMBD_SHARE_FLAG_STORE_DOS_ATTRS) &&
-                           ksmbd_vfs_get_dos_attrib_xattr(mnt_idmap(path.mnt),
-                                                        path.dentry, &da) > 0 
&&
+                           ksmbd_vfs_get_dos_attrib_xattr(&path, &da) > 0 &&
                            da.attr & FILE_ATTRIBUTE_READONLY) {
                                rsp->hdr.Status = STATUS_CANNOT_DELETE;
                                rc = -EACCES;
@@ -4863,7 +4854,6 @@ int smb2_open(struct ksmbd_work *work)
                                        }
 
                                        rc = ksmbd_vfs_set_sd_xattr(conn,
-                                                                   idmap,
                                                                    &path,
                                                                    pntsd,
                                                                    pntsd_size,
@@ -5886,7 +5876,6 @@ static int process_query_dir_entries(struct 
smb2_query_dir_private *priv)
                ksmbd_kstat.kstat = &kstat;
                if (priv->info_level != FILE_NAMES_INFORMATION) {
                        rc = ksmbd_vfs_fill_dentry_attrs(priv->work,
-                                                        idmap,
                                                         dent,
                                                         &ksmbd_kstat);
                        if (rc) {
@@ -6428,7 +6417,6 @@ static int smb2_get_ea(struct ksmbd_work *work, struct 
ksmbd_file *fp,
        ssize_t buf_free_len, alignment_bytes, next_offset, rsp_data_cnt = 0;
        struct smb2_ea_info_req *ea_req = NULL;
        const struct path *path;
-       struct mnt_idmap *idmap = file_mnt_idmap(fp->filp);
 
        if (!(fp->daccess & FILE_READ_EA_LE)) {
                pr_err("Not permitted to read ext attr : 0x%x\n",
@@ -6465,7 +6453,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct 
ksmbd_file *fp,
        if (buf_free_len < 0)
                return -EINVAL;
 
-       rc = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
+       rc = ksmbd_vfs_listxattr(path, &xattr_list);
        if (rc < 0) {
                rsp->hdr.Status = STATUS_INVALID_HANDLE;
                goto out;
@@ -6511,8 +6499,7 @@ static int smb2_get_ea(struct ksmbd_work *work, struct 
ksmbd_file *fp,
                buf_free_len -= (offsetof(struct smb2_ea_info, name) +
                                name_len + 1);
                /* bailout if xattr can't fit in buf_free_len */
-               value_len = ksmbd_vfs_getxattr(idmap, path->dentry,
-                                              name, &buf);
+               value_len = ksmbd_vfs_getxattr(path, name, &buf);
                if (value_len <= 0) {
                        rc = -ENOENT;
                        rsp->hdr.Status = STATUS_INVALID_HANDLE;
@@ -6802,7 +6789,7 @@ static char *smb2_get_normalized_stream_name(struct 
ksmbd_file *fp)
        if (!ksmbd_stream_fd(fp))
                return NULL;
 
-       xattr_list_len = ksmbd_vfs_listxattr(fp->filp->f_path.dentry,
+       xattr_list_len = ksmbd_vfs_listxattr(&fp->filp->f_path,
                                             &xattr_list);
        if (xattr_list_len <= 0)
                goto out;
@@ -6905,7 +6892,7 @@ static int get_file_stream_info(struct ksmbd_work *work,
        if (buf_free_len < 0)
                goto out;
 
-       xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
+       xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list);
        if (xattr_list_len < 0) {
                goto out;
        } else if (!xattr_list_len) {
@@ -6950,8 +6937,7 @@ static int get_file_stream_info(struct ksmbd_work *work,
                streamlen *= 2;
                kfree(stream_buf);
                file_info->StreamNameLength = cpu_to_le32(streamlen);
-               slen = ksmbd_vfs_xattr_len(file_mnt_idmap(fp->filp),
-                                          path->dentry, stream_name);
+               slen = ksmbd_vfs_xattr_len(path, stream_name);
                ssize = slen < 0 ? 0 : (loff_t)slen;
                file_info->StreamSize = cpu_to_le64(ssize);
                file_info->StreamAllocationSize = cpu_to_le64(ssize);
@@ -7689,8 +7675,8 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
 
        if (test_share_config_flag(work->tcon->share_conf,
                                   KSMBD_SHARE_FLAG_ACL_XATTR))
-               ppntsd_size = ksmbd_vfs_get_sd_xattr(work->conn, idmap,
-                                                    fp->filp->f_path.dentry,
+               ppntsd_size = ksmbd_vfs_get_sd_xattr(work->conn,
+                                                    &fp->filp->f_path,
                                                     &ppntsd);
 
        /* Check if sd buffer size exceeds response buffer size */
@@ -8051,8 +8037,7 @@ static int smb2_rename(struct ksmbd_work *work,
                                goto out;
                        }
 
-                       stream_buf_len = 
ksmbd_vfs_getcasexattr(file_mnt_idmap(fp->filp),
-                                                               
fp->filp->f_path.dentry,
+                       stream_buf_len = 
ksmbd_vfs_getcasexattr(&fp->filp->f_path,
                                                                fp->stream.name,
                                                                fp->stream.size,
                                                                &stream_buf);
@@ -8063,8 +8048,7 @@ static int smb2_rename(struct ksmbd_work *work,
                        }
                }
 
-               rc = ksmbd_vfs_setxattr(file_mnt_idmap(fp->filp),
-                                       &fp->filp->f_path,
+               rc = ksmbd_vfs_setxattr(&fp->filp->f_path,
                                        xattr_stream_name,
                                        stream_buf, stream_buf_len, 0, true);
                kfree(stream_buf);
@@ -8171,7 +8155,6 @@ static int set_file_basic_info(struct ksmbd_file *fp,
        struct iattr attrs;
        struct file *filp;
        struct inode *inode;
-       struct mnt_idmap *idmap;
        __le32 attrs_mask = FILE_ATTRIBUTE_DIRECTORY_LE |
                FILE_ATTRIBUTE_COMPRESSED_LE;
        int rc = 0;
@@ -8182,7 +8165,6 @@ static int set_file_basic_info(struct ksmbd_file *fp,
        attrs.ia_valid = 0;
        filp = fp->filp;
        inode = file_inode(filp);
-       idmap = file_mnt_idmap(filp);
 
        if (file_info->CreationTime)
                fp->create_time = le64_to_cpu(file_info->CreationTime);
@@ -8227,7 +8209,7 @@ static int set_file_basic_info(struct ksmbd_file *fp,
                da.flags = XATTR_DOSINFO_ATTRIB | XATTR_DOSINFO_CREATE_TIME |
                        XATTR_DOSINFO_ITIME;
 
-               rc = ksmbd_vfs_set_dos_attrib_xattr(idmap, &filp->f_path, &da,
+               rc = ksmbd_vfs_set_dos_attrib_xattr(&filp->f_path, &da,
                                true);
                if (rc)
                        ksmbd_debug(SMB,
@@ -10780,7 +10762,6 @@ static inline int fsctl_set_sparse(struct ksmbd_work 
*work, u64 id,
                                   struct file_sparse *sparse)
 {
        struct ksmbd_file *fp;
-       struct mnt_idmap *idmap;
        int ret = 0;
        __le32 old_fattr;
 
@@ -10804,8 +10785,6 @@ static inline int fsctl_set_sparse(struct ksmbd_work 
*work, u64 id,
                goto out;
        }
 
-       idmap = file_mnt_idmap(fp->filp);
-
        old_fattr = fp->f_ci->m_fattr;
        if (!sparse->SetSparse &&
            (old_fattr & FILE_ATTRIBUTE_SPARSE_FILE_LE)) {
@@ -10823,8 +10802,7 @@ static inline int fsctl_set_sparse(struct ksmbd_work 
*work, u64 id,
                const struct cred *saved_cred;
                struct xattr_dos_attrib da = {0};
 
-               ret = ksmbd_vfs_get_dos_attrib_xattr(idmap,
-                                                    fp->filp->f_path.dentry, 
&da);
+               ret = ksmbd_vfs_get_dos_attrib_xattr(&fp->filp->f_path, &da);
                if (ret <= 0) {
                        da.version = 4;
                        da.itime = fp->itime;
@@ -10836,8 +10814,7 @@ static inline int fsctl_set_sparse(struct ksmbd_work 
*work, u64 id,
                da.attr = le32_to_cpu(fp->f_ci->m_fattr);
                da.flags |= XATTR_DOSINFO_ATTRIB;
                saved_cred = override_creds(fp->filp->f_cred);
-               ret = ksmbd_vfs_set_dos_attrib_xattr(idmap,
-                                                    &fp->filp->f_path,
+               ret = ksmbd_vfs_set_dos_attrib_xattr(&fp->filp->f_path,
                                                     &da, true);
                revert_creds(saved_cred);
                if (ret)
diff --git a/fs/smb/server/smb_common.c b/fs/smb/server/smb_common.c
index 086a1b85e5f4..2cc8e24dcd6c 100644
--- a/fs/smb/server/smb_common.c
+++ b/fs/smb/server/smb_common.c
@@ -467,7 +467,6 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work 
*work, int info_level,
 {
        int i, rc = 0;
        struct ksmbd_conn *conn = work->conn;
-       struct mnt_idmap *idmap = file_mnt_idmap(dir->filp);
 
        for (i = 0; i < 2; i++) {
                struct kstat kstat;
@@ -493,7 +492,6 @@ int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work 
*work, int info_level,
 
                        ksmbd_kstat.kstat = &kstat;
                        rc = ksmbd_vfs_fill_dentry_attrs(work,
-                                                        idmap,
                                                         dentry,
                                                         &ksmbd_kstat);
                        if (rc)
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index fcace71b0a29..f81e06918cfb 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -1199,8 +1199,8 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
        struct smb_acl *parent_pdacl;
        struct smb_ntsd *parent_pntsd = NULL;
        struct smb_sid owner_sid, group_sid;
-       struct dentry *parent = path->dentry->d_parent;
-       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
+       struct path parent_path = { .mnt = path->mnt,
+                                   .dentry = path->dentry->d_parent };
        int inherited_flags = 0, flags = 0, i, nt_size = 0, pdacl_size;
        int rc = 0, pntsd_type, ppntsd_size, acl_len, aces_size;
        unsigned int dacloffset;
@@ -1209,8 +1209,8 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
        char *aces_base;
        bool is_dir = S_ISDIR(d_inode(path->dentry)->i_mode);
 
-       ppntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
-                                           parent, &parent_pntsd);
+       ppntsd_size = ksmbd_vfs_get_sd_xattr(conn, &parent_path,
+                                           &parent_pntsd);
        if (ppntsd_size <= 0)
                return -ENOENT;
 
@@ -1427,7 +1427,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
                        pntsd_size += sizeof(struct smb_acl) + nt_size;
                }
 
-               ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size, 
false);
+               ksmbd_vfs_set_sd_xattr(conn, path, pntsd, pntsd_size, false);
                kfree(pntsd);
        }
 
@@ -1476,8 +1476,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const 
struct path *path,
        vfsuid_t vfsuid;
 
        ksmbd_debug(SMB, "check permission using windows acl\n");
-       pntsd_size = ksmbd_vfs_get_sd_xattr(conn, idmap,
-                                           path->dentry, &pntsd);
+       pntsd_size = ksmbd_vfs_get_sd_xattr(conn, path, &pntsd);
        if (pntsd_size <= 0 || !pntsd)
                goto err_out;
 
@@ -1701,7 +1700,7 @@ int set_info_sec(struct ksmbd_conn *conn, struct 
ksmbd_tree_connect *tcon,
        newattrs.ia_valid |= ATTR_MODE;
        newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
 
-       ksmbd_vfs_remove_acl_xattrs(idmap, path);
+       ksmbd_vfs_remove_acl_xattrs(path);
        /* Update posix acls */
        if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
                rc = set_posix_acl(idmap, path->dentry,
@@ -1732,8 +1731,8 @@ int set_info_sec(struct ksmbd_conn *conn, struct 
ksmbd_tree_connect *tcon,
 
        if (test_share_config_flag(tcon->share_conf, 
KSMBD_SHARE_FLAG_ACL_XATTR)) {
                /* Update WinACL in xattr */
-               ksmbd_vfs_remove_sd_xattrs(idmap, path);
-               ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len,
+               ksmbd_vfs_remove_sd_xattrs(path);
+               ksmbd_vfs_set_sd_xattr(conn, path, pntsd, ntsd_len,
                                get_write);
        }
 
diff --git a/fs/smb/server/tests/smbacl_kunit.c 
b/fs/smb/server/tests/smbacl_kunit.c
index 33496b4d31a3..0e918b72f94f 100644
--- a/fs/smb/server/tests/smbacl_kunit.c
+++ b/fs/smb/server/tests/smbacl_kunit.c
@@ -221,8 +221,7 @@ static void ksmbd_smb_check_perm_dacl_boundary_test(struct 
kunit *test)
                                mk_vma_flags(VMA_NORESERVE_BIT));
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, file);
 
-       rc = ksmbd_vfs_set_sd_xattr(NULL, mnt_idmap(file->f_path.mnt),
-                                   &file->f_path, pntsd, ntsd_size,
+       rc = ksmbd_vfs_set_sd_xattr(NULL, &file->f_path, pntsd, ntsd_size,
                                    false);
        KUNIT_EXPECT_EQ(test, 0, rc);
        if (rc)
@@ -263,8 +262,7 @@ ksmbd_smb_check_perm_dacl_maximal_boundary_test(struct 
kunit *test)
                                mk_vma_flags(VMA_NORESERVE_BIT));
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, file);
 
-       rc = ksmbd_vfs_set_sd_xattr(NULL, mnt_idmap(file->f_path.mnt),
-                                   &file->f_path, pntsd, ntsd_size,
+       rc = ksmbd_vfs_set_sd_xattr(NULL, &file->f_path, pntsd, ntsd_size,
                                    false);
        KUNIT_EXPECT_EQ(test, 0, rc);
        if (rc)
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c
index db0f2de2bab3..eb904cf9ef2d 100644
--- a/fs/smb/server/vfs.c
+++ b/fs/smb/server/vfs.c
@@ -217,14 +217,14 @@ int ksmbd_vfs_mkdir(struct ksmbd_work *work, const char 
*name, umode_t mode)
        return err;
 }
 
-ssize_t ksmbd_vfs_getcasexattr(struct mnt_idmap *idmap,
-                              struct dentry *dentry, char *attr_name,
+ssize_t ksmbd_vfs_getcasexattr(const struct path *path,
+                              char *attr_name,
                               int attr_name_len, char **attr_value)
 {
        char *name, *xattr_list = NULL;
        ssize_t value_len = -ENOENT, xattr_list_len;
 
-       xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
+       xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list);
        if (xattr_list_len <= 0)
                goto out;
 
@@ -234,8 +234,7 @@ ssize_t ksmbd_vfs_getcasexattr(struct mnt_idmap *idmap,
                if (strncasecmp(attr_name, name, attr_name_len))
                        continue;
 
-               value_len = ksmbd_vfs_getxattr(idmap,
-                                              dentry,
+               value_len = ksmbd_vfs_getxattr(path,
                                               name,
                                               attr_value);
                if (value_len < 0)
@@ -259,8 +258,7 @@ static int ksmbd_vfs_stream_read(struct ksmbd_file *fp, 
char *buf, loff_t *pos,
                    *pos, count);
 
        saved_cred = override_creds(fp->filp->f_cred);
-       v_len = ksmbd_vfs_getcasexattr(file_mnt_idmap(fp->filp),
-                                      fp->filp->f_path.dentry,
+       v_len = ksmbd_vfs_getcasexattr(&fp->filp->f_path,
                                       fp->stream.name,
                                       fp->stream.size,
                                       &stream_buf);
@@ -387,7 +385,6 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, 
char *buf, loff_t *pos,
 {
        const struct cred *saved_cred;
        char *stream_buf = NULL, *wbuf;
-       struct mnt_idmap *idmap = file_mnt_idmap(fp->filp);
        size_t size;
        ssize_t v_len;
        int err = 0;
@@ -407,8 +404,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, 
char *buf, loff_t *pos,
        }
 
        saved_cred = override_creds(fp->filp->f_cred);
-       v_len = ksmbd_vfs_getcasexattr(idmap,
-                                      fp->filp->f_path.dentry,
+       v_len = ksmbd_vfs_getcasexattr(&fp->filp->f_path,
                                       fp->stream.name,
                                       fp->stream.size,
                                       &stream_buf);
@@ -433,8 +429,7 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, 
char *buf, loff_t *pos,
 
        memcpy(&stream_buf[*pos], buf, count);
 
-       err = ksmbd_vfs_setxattr(idmap,
-                                &fp->filp->f_path,
+       err = ksmbd_vfs_setxattr(&fp->filp->f_path,
                                 fp->stream.name,
                                 (void *)stream_buf,
                                 size,
@@ -813,17 +808,17 @@ int ksmbd_vfs_truncate(struct ksmbd_work *work,
 
 /**
  * ksmbd_vfs_listxattr() - vfs helper for smb list extended attributes
- * @dentry:    dentry of file for listing xattrs
+ * @path:      path of file for listing xattrs
  * @list:      destination buffer
  *
  * Return:     xattr list length on success, otherwise error
  */
-ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)
+ssize_t ksmbd_vfs_listxattr(const struct path *path, char **list)
 {
        ssize_t size;
        char *vlist = NULL;
 
-       size = vfs_listxattr(dentry, NULL, 0);
+       size = vfs_listxattr(path, NULL, 0);
        if (size <= 0)
                return size;
 
@@ -832,7 +827,7 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char 
**list)
                return -ENOMEM;
 
        *list = vlist;
-       size = vfs_listxattr(dentry, vlist, size);
+       size = vfs_listxattr(path, vlist, size);
        if (size < 0) {
                ksmbd_debug(VFS, "listxattr failed\n");
                kvfree(vlist);
@@ -842,30 +837,27 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char 
**list)
        return size;
 }
 
-ssize_t ksmbd_vfs_xattr_len(struct mnt_idmap *idmap,
-                           struct dentry *dentry, char *xattr_name)
+ssize_t ksmbd_vfs_xattr_len(const struct path *path, char *xattr_name)
 {
-       return vfs_getxattr(idmap, dentry, xattr_name, NULL, 0);
+       return vfs_getxattr(path, xattr_name, NULL, 0);
 }
 
 /**
  * ksmbd_vfs_getxattr() - vfs helper for smb get extended attributes value
- * @idmap:     idmap
- * @dentry:    dentry of file for getting xattrs
+ * @path:      path of file for getting xattrs
  * @xattr_name:        name of xattr name to query
  * @xattr_buf: destination buffer xattr value
  *
  * Return:     read xattr value length on success, otherwise error
  */
-ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
-                          struct dentry *dentry,
+ssize_t ksmbd_vfs_getxattr(const struct path *path,
                           char *xattr_name, char **xattr_buf)
 {
        ssize_t xattr_len;
        char *buf;
 
        *xattr_buf = NULL;
-       xattr_len = ksmbd_vfs_xattr_len(idmap, dentry, xattr_name);
+       xattr_len = ksmbd_vfs_xattr_len(path, xattr_name);
        if (xattr_len < 0)
                return xattr_len;
 
@@ -873,8 +865,7 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
        if (!buf)
                return -ENOMEM;
 
-       xattr_len = vfs_getxattr(idmap, dentry, xattr_name,
-                                (void *)buf, xattr_len);
+       xattr_len = vfs_getxattr(path, xattr_name, (void *)buf, xattr_len);
        if (xattr_len > 0)
                *xattr_buf = buf;
        else
@@ -884,7 +875,6 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
 
 /**
  * ksmbd_vfs_setxattr() - vfs helper for smb set extended attributes value
- * @idmap:     idmap of the relevant mount
  * @path:      path of dentry to set XATTR at
  * @attr_name: xattr name for setxattr
  * @attr_value:        xattr value to set
@@ -894,8 +884,7 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
  *
  * Return:     0 on success, otherwise error
  */
-int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
-                      const struct path *path, const char *attr_name,
+int ksmbd_vfs_setxattr(const struct path *path, const char *attr_name,
                       void *attr_value, size_t attr_size, int flags,
                       bool get_write)
 {
@@ -907,8 +896,7 @@ int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
                        return err;
        }
 
-       err = vfs_setxattr(idmap,
-                          path->dentry,
+       err = vfs_setxattr(path,
                           attr_name,
                           attr_value,
                           attr_size,
@@ -1178,8 +1166,7 @@ int ksmbd_vfs_query_allocated_ranges(struct ksmbd_file 
*fp, loff_t start,
        return ret;
 }
 
-int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
-                          const struct path *path, char *attr_name,
+int ksmbd_vfs_remove_xattr(const struct path *path, char *attr_name,
                           bool get_write)
 {
        int err;
@@ -1190,7 +1177,7 @@ int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
                        return err;
        }
 
-       err = vfs_removexattr(idmap, path->dentry, attr_name);
+       err = vfs_removexattr(path, attr_name);
 
        if (get_write == true)
                mnt_drop_write(path->mnt);
@@ -1472,14 +1459,13 @@ struct dentry *ksmbd_vfs_kern_path_create(struct 
ksmbd_work *work,
        return dent;
 }
 
-int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
-                               const struct path *path)
+int ksmbd_vfs_remove_acl_xattrs(const struct path *path)
 {
        char *name, *xattr_list = NULL;
        ssize_t xattr_list_len;
        int err = 0;
 
-       xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
+       xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list);
        if (xattr_list_len < 0) {
                goto out;
        } else if (!xattr_list_len) {
@@ -1499,7 +1485,8 @@ int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
                             sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1) ||
                    !strncmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
                             sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) {
-                       err = vfs_remove_acl(idmap, path->dentry, name);
+                       err = vfs_remove_acl(mnt_idmap(path->mnt),
+                                            path->dentry, name);
                        if (err)
                                ksmbd_debug(SMB,
                                            "remove acl xattr failed : %s\n", 
name);
@@ -1512,13 +1499,13 @@ int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
        return err;
 }
 
-int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path 
*path)
+int ksmbd_vfs_remove_sd_xattrs(const struct path *path)
 {
        char *name, *xattr_list = NULL;
        ssize_t xattr_list_len;
        int err = 0;
 
-       xattr_list_len = ksmbd_vfs_listxattr(path->dentry, &xattr_list);
+       xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list);
        if (xattr_list_len < 0) {
                goto out;
        } else if (!xattr_list_len) {
@@ -1531,7 +1518,7 @@ int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, 
const struct path *path)
                ksmbd_debug(SMB, "%s, len %zd\n", name, strlen(name));
 
                if (!strncmp(name, XATTR_NAME_SD, XATTR_NAME_SD_LEN)) {
-                       err = ksmbd_vfs_remove_xattr(idmap, path, name, true);
+                       err = ksmbd_vfs_remove_xattr(path, name, true);
                        if (err)
                                ksmbd_debug(SMB, "remove xattr failed : %s\n", 
name);
                }
@@ -1607,7 +1594,6 @@ static struct xattr_smb_acl 
*ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id
 }
 
 int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
-                          struct mnt_idmap *idmap,
                           const struct path *path,
                           struct smb_ntsd *pntsd, int len,
                           bool get_write)
@@ -1618,6 +1604,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
        struct xattr_smb_acl *smb_acl, *def_smb_acl = NULL;
        struct dentry *dentry = path->dentry;
        struct inode *inode = d_inode(dentry);
+       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
 
        acl.version = 4;
        acl.hash_type = XATTR_SD_HASH_TYPE_SHA256;
@@ -1659,7 +1646,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
                goto out;
        }
 
-       rc = ksmbd_vfs_setxattr(idmap, path,
+       rc = ksmbd_vfs_setxattr(path,
                                XATTR_NAME_SD, sd_ndr.data,
                                sd_ndr.offset, 0, get_write);
        if (rc < 0)
@@ -1675,19 +1662,19 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
 EXPORT_SYMBOL_IF_KUNIT(ksmbd_vfs_set_sd_xattr);
 
 int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
-                          struct mnt_idmap *idmap,
-                          struct dentry *dentry,
+                          const struct path *path,
                           struct smb_ntsd **pntsd)
 {
        int rc;
        struct ndr n;
-       struct inode *inode = d_inode(dentry);
+       struct inode *inode = d_inode(path->dentry);
        struct ndr acl_ndr = {0};
        struct xattr_ntacl acl = {0};
        struct xattr_smb_acl *smb_acl = NULL, *def_smb_acl = NULL;
+       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
        __u8 cmp_hash[XATTR_SD_HASH_SIZE] = {0};
 
-       rc = ksmbd_vfs_getxattr(idmap, dentry, XATTR_NAME_SD, &n.data);
+       rc = ksmbd_vfs_getxattr(path, XATTR_NAME_SD, &n.data);
        if (rc <= 0)
                return rc;
 
@@ -1744,8 +1731,7 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
        return rc;
 }
 
-int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
-                                  const struct path *path,
+int ksmbd_vfs_set_dos_attrib_xattr(const struct path *path,
                                   struct xattr_dos_attrib *da,
                                   bool get_write)
 {
@@ -1756,7 +1742,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap 
*idmap,
        if (err)
                goto out;
 
-       err = ksmbd_vfs_setxattr(idmap, path, XATTR_NAME_DOS_ATTRIBUTE,
+       err = ksmbd_vfs_setxattr(path, XATTR_NAME_DOS_ATTRIBUTE,
                                 (void *)n.data, n.offset, 0, get_write);
        if (err)
                ksmbd_debug(SMB, "failed to store dos attribute in xattr\n");
@@ -1766,14 +1752,13 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap 
*idmap,
        return err;
 }
 
-int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap,
-                                  struct dentry *dentry,
+int ksmbd_vfs_get_dos_attrib_xattr(const struct path *path,
                                   struct xattr_dos_attrib *da)
 {
        struct ndr n;
        int err;
 
-       err = ksmbd_vfs_getxattr(idmap, dentry, XATTR_NAME_DOS_ATTRIBUTE,
+       err = ksmbd_vfs_getxattr(path, XATTR_NAME_DOS_ATTRIBUTE,
                                 (char **)&n.data);
        if (err > 0) {
                n.length = err;
@@ -1822,7 +1807,6 @@ void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat 
*ksmbd_kstat)
 }
 
 int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
-                               struct mnt_idmap *idmap,
                                struct dentry *dentry,
                                struct ksmbd_kstat *ksmbd_kstat)
 {
@@ -1856,7 +1840,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
                                   KSMBD_SHARE_FLAG_STORE_DOS_ATTRS)) {
                struct xattr_dos_attrib da;
 
-               rc = ksmbd_vfs_get_dos_attrib_xattr(idmap, dentry, &da);
+               rc = ksmbd_vfs_get_dos_attrib_xattr(&path, &da);
                if (rc > 0) {
                        ksmbd_kstat->file_attributes = cpu_to_le32(da.attr);
                        ksmbd_kstat->create_time = da.create_time;
@@ -1879,7 +1863,7 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
                char *xattr_list = NULL, *name;
                ssize_t xattr_list_len;
 
-               xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
+               xattr_list_len = ksmbd_vfs_listxattr(&path, &xattr_list);
                if (xattr_list_len > 0) {
                        for (name = xattr_list;
                             name - xattr_list < xattr_list_len;
@@ -1897,14 +1881,14 @@ int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
        return 0;
 }
 
-ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap,
-                               struct dentry *dentry, char *attr_name,
+ssize_t ksmbd_vfs_casexattr_len(const struct path *path,
+                               char *attr_name,
                                int attr_name_len)
 {
        char *name, *xattr_list = NULL;
        ssize_t value_len = -ENOENT, xattr_list_len;
 
-       xattr_list_len = ksmbd_vfs_listxattr(dentry, &xattr_list);
+       xattr_list_len = ksmbd_vfs_listxattr(path, &xattr_list);
        if (xattr_list_len <= 0)
                goto out;
 
@@ -1914,7 +1898,7 @@ ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap,
                if (strncasecmp(attr_name, name, attr_name_len))
                        continue;
 
-               value_len = ksmbd_vfs_xattr_len(idmap, dentry, name);
+               value_len = ksmbd_vfs_xattr_len(path, name);
                break;
        }
 
@@ -2067,8 +2051,7 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
 
                saved_cred = override_creds(src_fp->filp->f_cred);
                src_file_size = ksmbd_vfs_casexattr_len(
-                               file_mnt_idmap(src_fp->filp),
-                               src_fp->filp->f_path.dentry,
+                               &src_fp->filp->f_path,
                                src_fp->stream.name, src_fp->stream.size);
                revert_creds(saved_cred);
                if (src_file_size < 0)
@@ -2386,7 +2369,7 @@ static int __ksmbd_vfs_set_compression(struct ksmbd_work 
*work,
        if (fp->f_ci->m_fattr != old_fattr) {
                struct xattr_dos_attrib da = {0};
 
-               rc = ksmbd_vfs_get_dos_attrib_xattr(idmap, dentry, &da);
+               rc = ksmbd_vfs_get_dos_attrib_xattr(&fp->filp->f_path, &da);
                if (rc <= 0) {
                        da.version = 4;
                        da.itime = fp->itime;
@@ -2397,8 +2380,7 @@ static int __ksmbd_vfs_set_compression(struct ksmbd_work 
*work,
 
                da.attr = le32_to_cpu(fp->f_ci->m_fattr);
                da.flags |= XATTR_DOSINFO_ATTRIB;
-               rc = ksmbd_vfs_set_dos_attrib_xattr(idmap,
-                                                   &fp->filp->f_path,
+               rc = ksmbd_vfs_set_dos_attrib_xattr(&fp->filp->f_path,
                                                    &da, true);
                if (rc)
                        rc = 0;
diff --git a/fs/smb/server/vfs.h b/fs/smb/server/vfs.h
index 566c670c90be..a0cf77a7a2c7 100644
--- a/fs/smb/server/vfs.h
+++ b/fs/smb/server/vfs.h
@@ -103,27 +103,24 @@ int ksmbd_vfs_copy_file_ranges(struct ksmbd_work *work,
                               unsigned int *chunk_count_written,
                               unsigned int *chunk_size_written,
                               loff_t  *total_size_written);
-ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list);
-ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
-                          struct dentry *dentry,
+ssize_t ksmbd_vfs_listxattr(const struct path *path, char **list);
+ssize_t ksmbd_vfs_getxattr(const struct path *path,
                           char *xattr_name,
                           char **xattr_buf);
-ssize_t ksmbd_vfs_xattr_len(struct mnt_idmap *idmap,
-                           struct dentry *dentry, char *xattr_name);
-ssize_t ksmbd_vfs_getcasexattr(struct mnt_idmap *idmap,
-                              struct dentry *dentry, char *attr_name,
+ssize_t ksmbd_vfs_xattr_len(const struct path *path,
+                           char *xattr_name);
+ssize_t ksmbd_vfs_getcasexattr(const struct path *path,
+                              char *attr_name,
                               int attr_name_len, char **attr_value);
-ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap,
-                               struct dentry *dentry, char *attr_name,
+ssize_t ksmbd_vfs_casexattr_len(const struct path *path,
+                               char *attr_name,
                                int attr_name_len);
-int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
-                      const struct path *path, const char *attr_name,
+int ksmbd_vfs_setxattr(const struct path *path, const char *attr_name,
                       void *attr_value, size_t attr_size, int flags,
                       bool get_write);
 int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
                                size_t *xattr_stream_name_size, int s_type);
-int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
-                          const struct path *path, char *attr_name,
+int ksmbd_vfs_remove_xattr(const struct path *path, char *attr_name,
                           bool get_write);
 int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name,
                        unsigned int flags,
@@ -152,29 +149,23 @@ int ksmbd_vfs_query_allocated_ranges(struct ksmbd_file 
*fp, loff_t start,
 int ksmbd_vfs_unlink(struct file *filp);
 void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat);
 int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
-                               struct mnt_idmap *idmap,
                                struct dentry *dentry,
                                struct ksmbd_kstat *ksmbd_kstat);
 void ksmbd_vfs_posix_lock_wait(struct file_lock *flock);
 void ksmbd_vfs_posix_lock_unblock(struct file_lock *flock);
-int ksmbd_vfs_remove_acl_xattrs(struct mnt_idmap *idmap,
-                               const struct path *path);
-int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path 
*path);
+int ksmbd_vfs_remove_acl_xattrs(const struct path *path);
+int ksmbd_vfs_remove_sd_xattrs(const struct path *path);
 int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
-                          struct mnt_idmap *idmap,
                           const struct path *path,
                           struct smb_ntsd *pntsd, int len,
                           bool get_write);
 int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
-                          struct mnt_idmap *idmap,
-                          struct dentry *dentry,
+                          const struct path *path,
                           struct smb_ntsd **pntsd);
-int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
-                                  const struct path *path,
+int ksmbd_vfs_set_dos_attrib_xattr(const struct path *path,
                                   struct xattr_dos_attrib *da,
                                   bool get_write);
-int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap,
-                                  struct dentry *dentry,
+int ksmbd_vfs_get_dos_attrib_xattr(const struct path *path,
                                   struct xattr_dos_attrib *da);
 int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
                                 const struct path *path);
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index a96b764c4db5..b5700c6f096f 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -538,8 +538,7 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
                        const struct cred *saved_cred;
 
                        saved_cred = override_creds(filp->f_cred);
-                       err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp),
-                                                    &filp->f_path,
+                       err = ksmbd_vfs_remove_xattr(&filp->f_path,
                                                     fp->stream.name,
                                                     true);
                        revert_creds(saved_cred);
diff --git a/fs/xattr.c b/fs/xattr.c
index d58979115200..818d6652b6d9 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -285,8 +285,7 @@ int __vfs_setxattr_noperm(struct mnt_idmap *idmap,
  * __vfs_setxattr_locked - set an extended attribute while holding the inode
  * lock
  *
- *  @idmap: idmap of the mount of the target inode
- *  @dentry: object to perform setxattr on
+ *  @path: object to perform setxattr on
  *  @name: xattr name to set
  *  @value: value to set @name to
  *  @size: size of @value
@@ -295,10 +294,12 @@ int __vfs_setxattr_noperm(struct mnt_idmap *idmap,
  *  a delegation was broken on, NULL if none.
  */
 int
-__vfs_setxattr_locked(struct mnt_idmap *idmap, struct dentry *dentry,
-                     const char *name, const void *value, size_t size,
-                     int flags, struct delegated_inode *delegated_inode)
+__vfs_setxattr_locked(const struct path *path, const char *name,
+                     const void *value, size_t size, int flags,
+                     struct delegated_inode *delegated_inode)
 {
+       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
+       struct dentry *dentry = path->dentry;
        struct inode *inode = dentry->d_inode;
        int error;
 
@@ -324,9 +325,11 @@ __vfs_setxattr_locked(struct mnt_idmap *idmap, struct 
dentry *dentry,
 EXPORT_SYMBOL_GPL(__vfs_setxattr_locked);
 
 int
-vfs_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
-            const char *name, const void *value, size_t size, int flags)
+vfs_setxattr(const struct path *path, const char *name, const void *value,
+            size_t size, int flags)
 {
+       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
+       struct dentry *dentry = path->dentry;
        struct inode *inode = dentry->d_inode;
        struct delegated_inode delegated_inode = { };
        const void  *orig_value = value;
@@ -341,7 +344,7 @@ vfs_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
 
 retry_deleg:
        inode_lock(inode);
-       error = __vfs_setxattr_locked(idmap, dentry, name, value, size,
+       error = __vfs_setxattr_locked(path, name, value, size,
                                      flags, &delegated_inode);
        inode_unlock(inode);
 
@@ -448,9 +451,11 @@ __vfs_getxattr(struct dentry *dentry, struct inode *inode, 
const char *name,
 EXPORT_SYMBOL(__vfs_getxattr);
 
 ssize_t
-vfs_getxattr(struct mnt_idmap *idmap, struct dentry *dentry,
-            const char *name, void *value, size_t size)
+vfs_getxattr(const struct path *path, const char *name, void *value,
+            size_t size)
 {
+       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
+       struct dentry *dentry = path->dentry;
        struct inode *inode = dentry->d_inode;
        int error;
 
@@ -482,12 +487,12 @@ EXPORT_SYMBOL_GPL(vfs_getxattr);
 
 /**
  * vfs_listxattr - retrieve \0 separated list of xattr names
- * @dentry: the dentry from whose inode the xattr names are retrieved
+ * @path: the path from whose inode the xattr names are retrieved
  * @list: buffer to store xattr names into
  * @size: size of the buffer
  *
  * This function returns the names of all xattrs associated with the
- * inode of @dentry.
+ * inode of @path->dentry.
  *
  * Note, for legacy reasons the vfs_listxattr() function lists POSIX
  * ACLs as well. Since POSIX ACLs are decoupled from IOP_XATTR the
@@ -503,8 +508,9 @@ EXPORT_SYMBOL_GPL(vfs_getxattr);
  *         negative error code.
  */
 ssize_t
-vfs_listxattr(struct dentry *dentry, char *list, size_t size)
+vfs_listxattr(const struct path *path, char *list, size_t size)
 {
+       struct dentry *dentry = path->dentry;
        struct inode *inode = d_inode(dentry);
        ssize_t error;
 
@@ -550,17 +556,17 @@ EXPORT_SYMBOL(__vfs_removexattr);
  * __vfs_removexattr_locked - set an extended attribute while holding the inode
  * lock
  *
- *  @idmap: idmap of the mount of the target inode
- *  @dentry: object to perform setxattr on
+ *  @path: object to perform removexattr on
  *  @name: name of xattr to remove
  *  @delegated_inode: on return, will contain an inode pointer that
  *  a delegation was broken on, NULL if none.
  */
 int
-__vfs_removexattr_locked(struct mnt_idmap *idmap,
-                        struct dentry *dentry, const char *name,
+__vfs_removexattr_locked(const struct path *path, const char *name,
                         struct delegated_inode *delegated_inode)
 {
+       struct mnt_idmap *idmap = mnt_idmap(path->mnt);
+       struct dentry *dentry = path->dentry;
        struct inode *inode = dentry->d_inode;
        int error;
 
@@ -589,17 +595,16 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap,
 EXPORT_SYMBOL_GPL(__vfs_removexattr_locked);
 
 int
-vfs_removexattr(struct mnt_idmap *idmap, struct dentry *dentry,
-               const char *name)
+vfs_removexattr(const struct path *path, const char *name)
 {
+       struct dentry *dentry = path->dentry;
        struct inode *inode = dentry->d_inode;
        struct delegated_inode delegated_inode = { };
        int error;
 
 retry_deleg:
        inode_lock(inode);
-       error = __vfs_removexattr_locked(idmap, dentry,
-                                        name, &delegated_inode);
+       error = __vfs_removexattr_locked(path, name, &delegated_inode);
        inode_unlock(inode);
 
        if (is_delegated(&delegated_inode)) {
@@ -652,14 +657,13 @@ int setxattr_copy(const char __user *name, struct 
kernel_xattr_ctx *ctx)
        return error;
 }
 
-static int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
-               struct kernel_xattr_ctx *ctx)
+static int do_setxattr(const struct path *path, struct kernel_xattr_ctx *ctx)
 {
        if (is_posix_acl_xattr(ctx->kname->name))
-               return do_set_acl(idmap, dentry, ctx->kname->name,
-                                 ctx->kvalue, ctx->size);
+               return do_set_acl(mnt_idmap(path->mnt), path->dentry,
+                                 ctx->kname->name, ctx->kvalue, ctx->size);
 
-       return vfs_setxattr(idmap, dentry, ctx->kname->name,
+       return vfs_setxattr(path, ctx->kname->name,
                        ctx->kvalue, ctx->size, ctx->flags);
 }
 
@@ -669,7 +673,7 @@ int file_setxattr(struct file *f, struct kernel_xattr_ctx 
*ctx)
 
        if (!error) {
                audit_file(f);
-               error = do_setxattr(file_mnt_idmap(f), f->f_path.dentry, ctx);
+               error = do_setxattr(&f->f_path, ctx);
                mnt_drop_write_file(f);
        }
        return error;
@@ -687,7 +691,7 @@ int filename_setxattr(int dfd, struct filename *filename,
                return error;
        error = mnt_want_write(path.mnt);
        if (!error) {
-               error = do_setxattr(mnt_idmap(path.mnt), path.dentry, ctx);
+               error = do_setxattr(&path, ctx);
                mnt_drop_write(path.mnt);
        }
        path_put(&path);
@@ -787,8 +791,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, 
name,
  * Extended attribute GET operations
  */
 static ssize_t
-do_getxattr(struct mnt_idmap *idmap, struct dentry *d,
-       struct kernel_xattr_ctx *ctx)
+do_getxattr(const struct path *path, struct kernel_xattr_ctx *ctx)
 {
        ssize_t error;
        char *kname = ctx->kname->name;
@@ -803,9 +806,10 @@ do_getxattr(struct mnt_idmap *idmap, struct dentry *d,
        }
 
        if (is_posix_acl_xattr(kname))
-               error = do_get_acl(idmap, d, kname, kvalue, ctx->size);
+               error = do_get_acl(mnt_idmap(path->mnt), path->dentry,
+                                  kname, kvalue, ctx->size);
        else
-               error = vfs_getxattr(idmap, d, kname, kvalue, ctx->size);
+               error = vfs_getxattr(path, kname, kvalue, ctx->size);
        if (error > 0) {
                if (ctx->size && copy_to_user(ctx->value, kvalue, error))
                        error = -EFAULT;
@@ -822,7 +826,7 @@ do_getxattr(struct mnt_idmap *idmap, struct dentry *d,
 ssize_t file_getxattr(struct file *f, struct kernel_xattr_ctx *ctx)
 {
        audit_file(f);
-       return do_getxattr(file_mnt_idmap(f), f->f_path.dentry, ctx);
+       return do_getxattr(&f->f_path, ctx);
 }
 
 ssize_t filename_getxattr(int dfd, struct filename *filename,
@@ -834,7 +838,7 @@ ssize_t filename_getxattr(int dfd, struct filename 
*filename,
        error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);
        if (error)
                return error;
-       error = do_getxattr(mnt_idmap(path.mnt), path.dentry, ctx);
+       error = do_getxattr(&path, ctx);
        path_put(&path);
        if (retry_estale(error, lookup_flags)) {
                lookup_flags |= LOOKUP_REVAL;
@@ -925,7 +929,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, 
name,
  * Extended attribute LIST operations
  */
 static ssize_t
-listxattr(struct dentry *d, char __user *list, size_t size)
+listxattr(const struct path *path, char __user *list, size_t size)
 {
        ssize_t error;
        char *klist = NULL;
@@ -938,7 +942,7 @@ listxattr(struct dentry *d, char __user *list, size_t size)
                        return -ENOMEM;
        }
 
-       error = vfs_listxattr(d, klist, size);
+       error = vfs_listxattr(path, klist, size);
        if (error > 0) {
                if (size && copy_to_user(list, klist, error))
                        error = -EFAULT;
@@ -957,7 +961,7 @@ static
 ssize_t file_listxattr(struct file *f, char __user *list, size_t size)
 {
        audit_file(f);
-       return listxattr(f->f_path.dentry, list, size);
+       return listxattr(&f->f_path, list, size);
 }
 
 static
@@ -971,7 +975,7 @@ ssize_t filename_listxattr(int dfd, struct filename 
*filename,
        error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);
        if (error)
                return error;
-       error = listxattr(path.dentry, list, size);
+       error = listxattr(&path, list, size);
        path_put(&path);
        if (retry_estale(error, lookup_flags)) {
                lookup_flags |= LOOKUP_REVAL;
@@ -1029,11 +1033,12 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, 
list, size_t, size)
  * Extended attribute REMOVE operations
  */
 static long
-removexattr(struct mnt_idmap *idmap, struct dentry *d, const char *name)
+removexattr(const struct path *path, const char *name)
 {
        if (is_posix_acl_xattr(name))
-               return vfs_remove_acl(idmap, d, name);
-       return vfs_removexattr(idmap, d, name);
+               return vfs_remove_acl(mnt_idmap(path->mnt), path->dentry,
+                                     name);
+       return vfs_removexattr(path, name);
 }
 
 static int file_removexattr(struct file *f, struct xattr_name *kname)
@@ -1042,8 +1047,7 @@ static int file_removexattr(struct file *f, struct 
xattr_name *kname)
 
        if (!error) {
                audit_file(f);
-               error = removexattr(file_mnt_idmap(f),
-                                   f->f_path.dentry, kname->name);
+               error = removexattr(&f->f_path, kname->name);
                mnt_drop_write_file(f);
        }
        return error;
@@ -1061,7 +1065,7 @@ static int filename_removexattr(int dfd, struct filename 
*filename,
                return error;
        error = mnt_want_write(path.mnt);
        if (!error) {
-               error = removexattr(mnt_idmap(path.mnt), path.dentry, 
kname->name);
+               error = removexattr(&path, kname->name);
                mnt_drop_write(path.mnt);
        }
        path_put(&path);
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 54ac3cbc133f..85042618fd81 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -77,22 +77,22 @@ struct xattr {
 };
 
 ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, 
size_t);
-ssize_t vfs_getxattr(struct mnt_idmap *, struct dentry *, const char *,
-                    void *, size_t);
-ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
+ssize_t vfs_getxattr(const struct path *path, const char *name, void *value,
+                    size_t size);
+ssize_t vfs_listxattr(const struct path *path, char *list, size_t size);
 int __vfs_setxattr(struct mnt_idmap *, struct dentry *, struct inode *,
                   const char *, const void *, size_t, int);
 int __vfs_setxattr_noperm(struct mnt_idmap *, struct dentry *,
                          const char *, const void *, size_t, int);
-int __vfs_setxattr_locked(struct mnt_idmap *, struct dentry *,
-                         const char *, const void *, size_t, int,
-                         struct delegated_inode *);
-int vfs_setxattr(struct mnt_idmap *, struct dentry *, const char *,
-                const void *, size_t, int);
+int __vfs_setxattr_locked(const struct path *path, const char *name,
+                         const void *value, size_t size, int flags,
+                         struct delegated_inode *delegated_inode);
+int vfs_setxattr(const struct path *path, const char *name,
+                const void *value, size_t size, int flags);
 int __vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *);
-int __vfs_removexattr_locked(struct mnt_idmap *, struct dentry *,
-                            const char *, struct delegated_inode *);
-int vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *);
+int __vfs_removexattr_locked(const struct path *path, const char *name,
+                            struct delegated_inode *delegated_inode);
+int vfs_removexattr(const struct path *path, const char *name);
 
 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t 
buffer_size);
 int vfs_getxattr_alloc(struct mnt_idmap *idmap,
diff --git a/security/integrity/evm/evm_crypto.c 
b/security/integrity/evm/evm_crypto.c
index 1c41af2f91a6..3d759efd3c6c 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -237,7 +237,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
        size_t xattr_size = 0;
        char *xattr_value = NULL;
        int error;
-       int size, user_space_size;
+       int size;
        bool ima_present = false;
        u64 i_version = 0;
 
@@ -287,12 +287,6 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
                if (size < 0)
                        continue;
 
-               user_space_size = vfs_getxattr(&nop_mnt_idmap, dentry,
-                                              xattr->name, NULL, 0);
-               if (user_space_size != size)
-                       pr_debug("file %s: xattr %s size mismatch (kernel: %d, 
user: %d)\n",
-                                dentry->d_name.name, xattr->name, size,
-                                user_space_size);
                error = 0;
                xattr_size = size;
                crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8af024fe4fb5..1d06b08f3c41 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -7168,8 +7168,8 @@ static int selinux_inode_notifysecctx(struct inode 
*inode, void *ctx, u32 ctxlen
  */
 static int selinux_inode_setsecctx(const struct path *path, void *ctx, u32 
ctxlen)
 {
-       return __vfs_setxattr_locked(&nop_mnt_idmap, path->dentry,
-                                    XATTR_NAME_SELINUX, ctx, ctxlen, 0, NULL);
+       return __vfs_setxattr_locked(path, XATTR_NAME_SELINUX,
+                                    ctx, ctxlen, 0, NULL);
 }
 
 static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index d9e9f4a52567..e517809c230d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4980,8 +4980,8 @@ static int smack_inode_notifysecctx(struct inode *inode, 
void *ctx, u32 ctxlen)
 
 static int smack_inode_setsecctx(const struct path *path, void *ctx, u32 
ctxlen)
 {
-       return __vfs_setxattr_locked(&nop_mnt_idmap, path->dentry,
-                                    XATTR_NAME_SMACK, ctx, ctxlen, 0, NULL);
+       return __vfs_setxattr_locked(path, XATTR_NAME_SMACK,
+                                    ctx, ctxlen, 0, NULL);
 }
 
 static int smack_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
-- 
2.18.0.huawei.25


Reply via email to