]> Git Repo - linux.git/commitdiff
smb: client: use actual path when queryfs
authorwangrong <[email protected]>
Thu, 20 Jun 2024 08:37:29 +0000 (16:37 +0800)
committerSteve French <[email protected]>
Wed, 2 Oct 2024 02:47:16 +0000 (21:47 -0500)
Due to server permission control, the client does not have access to
the shared root directory, but can access subdirectories normally, so
users usually mount the shared subdirectories directly. In this case,
queryfs should use the actual path instead of the root directory to
avoid the call returning an error (EACCES).

Signed-off-by: wangrong <[email protected]>
Reviewed-by: Paulo Alcantara (Red Hat) <[email protected]>
Cc: [email protected]
Signed-off-by: Steve French <[email protected]>
fs/smb/client/cifsfs.c
fs/smb/client/cifsglob.h
fs/smb/client/smb1ops.c
fs/smb/client/smb2ops.c

index 2a2523c93944de68e82528f485de5ae19d7d23d8..33e2860010158c9c0ad8a3e4f3b92bf7a1acaa11 100644 (file)
@@ -313,8 +313,17 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct TCP_Server_Info *server = tcon->ses->server;
        unsigned int xid;
        int rc = 0;
+       const char *full_path;
+       void *page;
 
        xid = get_xid();
+       page = alloc_dentry_path();
+
+       full_path = build_path_from_dentry(dentry, page);
+       if (IS_ERR(full_path)) {
+               rc = PTR_ERR(full_path);
+               goto statfs_out;
+       }
 
        if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0)
                buf->f_namelen =
@@ -330,8 +339,10 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_ffree = 0;       /* unlimited */
 
        if (server->ops->queryfs)
-               rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
+               rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf);
 
+statfs_out:
+       free_dentry_path(page);
        free_xid(xid);
        return rc;
 }
index da35c160e7dd43a48bbc5586239e16c4016b3f01..589438b867a96336aef63e120b69f0f41405fe40 100644 (file)
@@ -481,7 +481,7 @@ struct smb_version_operations {
                        __u16 net_fid, struct cifsInodeInfo *cifs_inode);
        /* query remote filesystem */
        int (*queryfs)(const unsigned int, struct cifs_tcon *,
-                      struct cifs_sb_info *, struct kstatfs *);
+                      const char *, struct cifs_sb_info *, struct kstatfs *);
        /* send mandatory brlock to the server */
        int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64,
                         __u64, __u32, int, int, bool);
index e03c91a49650fd46cb84dc20b549574d05f9d168..9a6ece66c4d34ef7cc068d1ba94aca62a92a3a0f 100644 (file)
@@ -909,7 +909,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
 
 static int
 cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-            struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+            const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        int rc = -EOPNOTSUPP;
 
index 177173072bfa9e9731de498cdd5d7e7f0ea7ae36..cd6ff224015a27fde518e4eb74ba42d506b55963 100644 (file)
@@ -2838,7 +2838,7 @@ out_free_path:
 
 static int
 smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-            struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+            const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        struct smb2_query_info_rsp *rsp;
        struct smb2_fs_full_size_info *info = NULL;
@@ -2847,7 +2847,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
        int rc;
 
 
-       rc = smb2_query_info_compound(xid, tcon, "",
+       rc = smb2_query_info_compound(xid, tcon, path,
                                      FILE_READ_ATTRIBUTES,
                                      FS_FULL_SIZE_INFORMATION,
                                      SMB2_O_INFO_FILESYSTEM,
@@ -2875,28 +2875,33 @@ qfs_exit:
 
 static int
 smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
-              struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
+              const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
 {
        int rc;
-       __le16 srch_path = 0; /* Null - open root of share */
+       __le16 *utf16_path = NULL;
        u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
        struct cifs_open_parms oparms;
        struct cifs_fid fid;
 
        if (!tcon->posix_extensions)
-               return smb2_queryfs(xid, tcon, cifs_sb, buf);
+               return smb2_queryfs(xid, tcon, path, cifs_sb, buf);
 
        oparms = (struct cifs_open_parms) {
                .tcon = tcon,
-               .path = "",
+               .path = path,
                .desired_access = FILE_READ_ATTRIBUTES,
                .disposition = FILE_OPEN,
                .create_options = cifs_create_options(cifs_sb, 0),
                .fid = &fid,
        };
 
-       rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
+       utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
+       if (utf16_path == NULL)
+               return -ENOMEM;
+
+       rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
                       NULL, NULL);
+       kfree(utf16_path);
        if (rc)
                return rc;
 
This page took 0.075279 seconds and 4 git commands to generate.