Skip to content

Commit a421e3f

Browse files
wangrong1069smfrench
authored andcommitted
smb: client: use actual path when queryfs
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]>
1 parent c9432ad commit a421e3f

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

fs/smb/client/cifsfs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,17 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
313313
struct TCP_Server_Info *server = tcon->ses->server;
314314
unsigned int xid;
315315
int rc = 0;
316+
const char *full_path;
317+
void *page;
316318

317319
xid = get_xid();
320+
page = alloc_dentry_path();
321+
322+
full_path = build_path_from_dentry(dentry, page);
323+
if (IS_ERR(full_path)) {
324+
rc = PTR_ERR(full_path);
325+
goto statfs_out;
326+
}
318327

319328
if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0)
320329
buf->f_namelen =
@@ -330,8 +339,10 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
330339
buf->f_ffree = 0; /* unlimited */
331340

332341
if (server->ops->queryfs)
333-
rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
342+
rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf);
334343

344+
statfs_out:
345+
free_dentry_path(page);
335346
free_xid(xid);
336347
return rc;
337348
}

fs/smb/client/cifsglob.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ struct smb_version_operations {
481481
__u16 net_fid, struct cifsInodeInfo *cifs_inode);
482482
/* query remote filesystem */
483483
int (*queryfs)(const unsigned int, struct cifs_tcon *,
484-
struct cifs_sb_info *, struct kstatfs *);
484+
const char *, struct cifs_sb_info *, struct kstatfs *);
485485
/* send mandatory brlock to the server */
486486
int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64,
487487
__u64, __u32, int, int, bool);

fs/smb/client/smb1ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
909909

910910
static int
911911
cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
912-
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
912+
const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
913913
{
914914
int rc = -EOPNOTSUPP;
915915

fs/smb/client/smb2ops.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2838,7 +2838,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
28382838

28392839
static int
28402840
smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
2841-
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
2841+
const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
28422842
{
28432843
struct smb2_query_info_rsp *rsp;
28442844
struct smb2_fs_full_size_info *info = NULL;
@@ -2847,7 +2847,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
28472847
int rc;
28482848

28492849

2850-
rc = smb2_query_info_compound(xid, tcon, "",
2850+
rc = smb2_query_info_compound(xid, tcon, path,
28512851
FILE_READ_ATTRIBUTES,
28522852
FS_FULL_SIZE_INFORMATION,
28532853
SMB2_O_INFO_FILESYSTEM,
@@ -2875,28 +2875,33 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
28752875

28762876
static int
28772877
smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
2878-
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
2878+
const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
28792879
{
28802880
int rc;
2881-
__le16 srch_path = 0; /* Null - open root of share */
2881+
__le16 *utf16_path = NULL;
28822882
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
28832883
struct cifs_open_parms oparms;
28842884
struct cifs_fid fid;
28852885

28862886
if (!tcon->posix_extensions)
2887-
return smb2_queryfs(xid, tcon, cifs_sb, buf);
2887+
return smb2_queryfs(xid, tcon, path, cifs_sb, buf);
28882888

28892889
oparms = (struct cifs_open_parms) {
28902890
.tcon = tcon,
2891-
.path = "",
2891+
.path = path,
28922892
.desired_access = FILE_READ_ATTRIBUTES,
28932893
.disposition = FILE_OPEN,
28942894
.create_options = cifs_create_options(cifs_sb, 0),
28952895
.fid = &fid,
28962896
};
28972897

2898-
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
2898+
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
2899+
if (utf16_path == NULL)
2900+
return -ENOMEM;
2901+
2902+
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
28992903
NULL, NULL);
2904+
kfree(utf16_path);
29002905
if (rc)
29012906
return rc;
29022907

0 commit comments

Comments
 (0)