Skip to content

Commit ddca502

Browse files
author
Steve French
committed
smb3.1.1: fix posix mounts to older servers
Some servers which implement the SMB3.1.1 POSIX extensions did not set the file type in the mode in the infolevel 100 response. With the recent changes for checking the file type via the mode field, this can cause the root directory to be reported incorrectly and mounts (e.g. to ksmbd) to fail. Fixes: 6a832bc ("fs/smb/client: Implement new SMB3 POSIX type") Cc: [email protected] Acked-by: Paulo Alcantara (Red Hat) <[email protected]> Cc: Ralph Boehme <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 8cb0bc5 commit ddca502

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

fs/smb/client/cifsproto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode,
669669
int cifs_sfu_make_node(unsigned int xid, struct inode *inode,
670670
struct dentry *dentry, struct cifs_tcon *tcon,
671671
const char *full_path, umode_t mode, dev_t dev);
672-
umode_t wire_mode_to_posix(u32 wire);
672+
umode_t wire_mode_to_posix(u32 wire, bool is_dir);
673673

674674
#ifdef CONFIG_CIFS_DFS_UPCALL
675675
static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,

fs/smb/client/inode.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -814,13 +814,17 @@ static u32 wire_filetype_to_posix(u32 wire_type)
814814
return posix_filetypes[wire_type];
815815
}
816816

817-
umode_t wire_mode_to_posix(u32 wire)
817+
umode_t wire_mode_to_posix(u32 wire, bool is_dir)
818818
{
819819
u32 wire_type;
820820
u32 mode;
821821

822822
wire_type = (wire & POSIX_FILETYPE_MASK) >> POSIX_FILETYPE_SHIFT;
823-
mode = (wire_perms_to_posix(wire) | wire_filetype_to_posix(wire_type));
823+
/* older servers do not set POSIX file type in the mode field in the response */
824+
if ((wire_type == 0) && is_dir)
825+
mode = wire_perms_to_posix(wire) | S_IFDIR;
826+
else
827+
mode = (wire_perms_to_posix(wire) | wire_filetype_to_posix(wire_type));
824828
return (umode_t)mode;
825829
}
826830

@@ -860,7 +864,8 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr,
860864
fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
861865
fattr->cf_createtime = le64_to_cpu(info->CreationTime);
862866
fattr->cf_nlink = le32_to_cpu(info->HardLinks);
863-
fattr->cf_mode = wire_mode_to_posix(le32_to_cpu(info->Mode));
867+
fattr->cf_mode = wire_mode_to_posix(le32_to_cpu(info->Mode),
868+
fattr->cf_cifsattrs & ATTR_DIRECTORY);
864869

865870
if (cifs_open_data_reparse(data) &&
866871
cifs_reparse_point_to_fattr(cifs_sb, fattr, data))

fs/smb/client/readdir.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info,
261261
fattr->cf_cifstag = le32_to_cpu(info->ReparseTag);
262262

263263
/* The Mode field in the response can now include the file type as well */
264-
fattr->cf_mode = wire_mode_to_posix(le32_to_cpu(info->Mode));
264+
fattr->cf_mode = wire_mode_to_posix(le32_to_cpu(info->Mode),
265+
fattr->cf_cifsattrs & ATTR_DIRECTORY);
265266
fattr->cf_dtype = S_DT(le32_to_cpu(info->Mode));
266267

267268
switch (fattr->cf_mode & S_IFMT) {

0 commit comments

Comments
 (0)