Skip to content

Commit 4729732

Browse files
wangrong1069gregkh
authored andcommitted
smb: client: use actual path when queryfs
commit a421e3f upstream. 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]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 868e843 commit 4729732

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
@@ -312,8 +312,17 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
312312
struct TCP_Server_Info *server = tcon->ses->server;
313313
unsigned int xid;
314314
int rc = 0;
315+
const char *full_path;
316+
void *page;
315317

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

318327
if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0)
319328
buf->f_namelen =
@@ -329,8 +338,10 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
329338
buf->f_ffree = 0; /* unlimited */
330339

331340
if (server->ops->queryfs)
332-
rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
341+
rc = server->ops->queryfs(xid, tcon, full_path, cifs_sb, buf);
333342

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

fs/smb/client/cifsglob.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ struct smb_version_operations {
485485
__u16 net_fid, struct cifsInodeInfo *cifs_inode);
486486
/* query remote filesystem */
487487
int (*queryfs)(const unsigned int, struct cifs_tcon *,
488-
struct cifs_sb_info *, struct kstatfs *);
488+
const char *, struct cifs_sb_info *, struct kstatfs *);
489489
/* send mandatory brlock to the server */
490490
int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64,
491491
__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
@@ -2783,7 +2783,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
27832783

27842784
static int
27852785
smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
2786-
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
2786+
const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
27872787
{
27882788
struct smb2_query_info_rsp *rsp;
27892789
struct smb2_fs_full_size_info *info = NULL;
@@ -2792,7 +2792,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
27922792
int rc;
27932793

27942794

2795-
rc = smb2_query_info_compound(xid, tcon, "",
2795+
rc = smb2_query_info_compound(xid, tcon, path,
27962796
FILE_READ_ATTRIBUTES,
27972797
FS_FULL_SIZE_INFORMATION,
27982798
SMB2_O_INFO_FILESYSTEM,
@@ -2820,28 +2820,33 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
28202820

28212821
static int
28222822
smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
2823-
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
2823+
const char *path, struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
28242824
{
28252825
int rc;
2826-
__le16 srch_path = 0; /* Null - open root of share */
2826+
__le16 *utf16_path = NULL;
28272827
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
28282828
struct cifs_open_parms oparms;
28292829
struct cifs_fid fid;
28302830

28312831
if (!tcon->posix_extensions)
2832-
return smb2_queryfs(xid, tcon, cifs_sb, buf);
2832+
return smb2_queryfs(xid, tcon, path, cifs_sb, buf);
28332833

28342834
oparms = (struct cifs_open_parms) {
28352835
.tcon = tcon,
2836-
.path = "",
2836+
.path = path,
28372837
.desired_access = FILE_READ_ATTRIBUTES,
28382838
.disposition = FILE_OPEN,
28392839
.create_options = cifs_create_options(cifs_sb, 0),
28402840
.fid = &fid,
28412841
};
28422842

2843-
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
2843+
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
2844+
if (utf16_path == NULL)
2845+
return -ENOMEM;
2846+
2847+
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
28442848
NULL, NULL);
2849+
kfree(utf16_path);
28452850
if (rc)
28462851
return rc;
28472852

0 commit comments

Comments
 (0)