diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 3a0263df104b..cb5515a50f74 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -1215,7 +1215,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data, break; case IO_REPARSE_TAG_INTERNAL: rc = 0; - if (le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY) { + if (cifs_open_data_attrs(data) & ATTR_DIRECTORY) { cifs_create_junction_fattr(fattr, sb); goto out; } @@ -1239,7 +1239,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data, */ if (rc == -EOPNOTSUPP && IS_REPARSE_TAG_NAME_SURROGATE(data->reparse.tag) && - (le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY)) { + (cifs_open_data_attrs(data) & ATTR_DIRECTORY)) { rc = 0; cifs_create_junction_fattr(fattr, sb); goto out; @@ -1257,13 +1257,14 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data, } if (data->reparse.tag == IO_REPARSE_TAG_SYMLINK && !rc) { - bool directory = le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY; + bool directory = cifs_open_data_attrs(data) & ATTR_DIRECTORY; + rc = smb2_fix_symlink_target_type(&data->symlink_target, directory, cifs_sb); } break; } - if (tcon->posix_extensions) + if (data->contains_posix_file_info) smb311_posix_info_to_fattr(fattr, data, sb); else cifs_open_info_to_fattr(fattr, data, sb); diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h index 0164dc47bdfd..49efd85b1e94 100644 --- a/fs/smb/client/reparse.h +++ b/fs/smb/client/reparse.h @@ -98,15 +98,21 @@ static inline bool reparse_inode_match(struct inode *inode, timespec64_equal(&ctime, &fattr->cf_ctime); } +static inline u32 cifs_open_data_attrs(const struct cifs_open_info_data *data) +{ + if (data->contains_posix_file_info) + return le32_to_cpu(data->posix_fi.DosAttributes); + + return le32_to_cpu(data->fi.Attributes); +} + static inline bool cifs_open_data_reparse(struct cifs_open_info_data *data) { - u32 attrs; - bool ret; + u32 attrs = cifs_open_data_attrs(data); if (data->contains_posix_file_info) { struct smb311_posix_qinfo *fi = &data->posix_fi; - attrs = le32_to_cpu(fi->DosAttributes); if (data->reparse_point) { attrs |= ATTR_REPARSE_POINT; fi->DosAttributes = cpu_to_le32(attrs); @@ -115,16 +121,13 @@ static inline bool cifs_open_data_reparse(struct cifs_open_info_data *data) } else { struct smb2_file_all_info *fi = &data->fi; - attrs = le32_to_cpu(fi->Attributes); if (data->reparse_point) { attrs |= ATTR_REPARSE_POINT; fi->Attributes = cpu_to_le32(attrs); } } - ret = attrs & ATTR_REPARSE_POINT; - - return ret; + return attrs & ATTR_REPARSE_POINT; } bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb, diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 058b05f7a3e5..bcaa44814b71 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -22,6 +22,7 @@ #include "smb2glob.h" #include "smb2proto.h" #include "cached_dir.h" +#include "reparse.h" #include "../common/smb2status.h" #include "../common/smbfsctl.h" @@ -1002,12 +1003,13 @@ int smb2_query_path_info(const unsigned int xid, /* * If the symlink was already parsed in create response then it is needed to fix * its type now (after the second call with OPEN_REPARSE_POINT which filled the - * data->fi.Attributes). If the symlink was not parsed in create response then + * metadata attributes). If the symlink was not parsed in create response then * the data->symlink_target was not filled yet and then the type will be fixed * later after data->symlink_target is filled. */ if (data->reparse.tag == IO_REPARSE_TAG_SYMLINK && !rc && data->symlink_target) { - bool directory = le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY; + bool directory = cifs_open_data_attrs(data) & ATTR_DIRECTORY; + rc = smb2_fix_symlink_target_type(&data->symlink_target, directory, cifs_sb); } break;