@@ -691,29 +691,36 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr,
691691 fattr -> cf_mtime .tv_sec += tcon -> ses -> server -> timeAdj ;
692692 }
693693
694+ /*
695+ * The srv fs device id is overridden on network mount so setting
696+ * @fattr->cf_rdev isn't needed here.
697+ */
694698 fattr -> cf_eof = le64_to_cpu (info -> EndOfFile );
695699 fattr -> cf_bytes = le64_to_cpu (info -> AllocationSize );
696700 fattr -> cf_createtime = le64_to_cpu (info -> CreationTime );
697-
698701 fattr -> cf_nlink = le32_to_cpu (info -> HardLinks );
699702 fattr -> cf_mode = (umode_t ) le32_to_cpu (info -> Mode );
700- /* The srv fs device id is overridden on network mount so setting rdev isn't needed here */
701- /* fattr->cf_rdev = le32_to_cpu(info->DeviceId); */
702703
703- if (data -> symlink ) {
704- fattr -> cf_mode |= S_IFLNK ;
705- fattr -> cf_dtype = DT_LNK ;
706- fattr -> cf_symlink_target = data -> symlink_target ;
707- data -> symlink_target = NULL ;
708- } else if (fattr -> cf_cifsattrs & ATTR_DIRECTORY ) {
704+ if (cifs_open_data_reparse ( data ) &&
705+ cifs_reparse_point_to_fattr ( cifs_sb , fattr , data ))
706+ goto out_reparse ;
707+
708+ fattr -> cf_mode &= ~ S_IFMT ;
709+ if (fattr -> cf_cifsattrs & ATTR_DIRECTORY ) {
709710 fattr -> cf_mode |= S_IFDIR ;
710711 fattr -> cf_dtype = DT_DIR ;
711712 } else { /* file */
712713 fattr -> cf_mode |= S_IFREG ;
713714 fattr -> cf_dtype = DT_REG ;
714715 }
715- /* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */
716716
717+ out_reparse :
718+ if (S_ISLNK (fattr -> cf_mode )) {
719+ if (likely (data -> symlink_target ))
720+ fattr -> cf_eof = strnlen (data -> symlink_target , PATH_MAX );
721+ fattr -> cf_symlink_target = data -> symlink_target ;
722+ data -> symlink_target = NULL ;
723+ }
717724 sid_to_id (cifs_sb , owner , fattr , SIDOWNER );
718725 sid_to_id (cifs_sb , group , fattr , SIDGROUP );
719726
@@ -738,25 +745,25 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
738745 if (tag == IO_REPARSE_TAG_NFS && buf ) {
739746 switch (le64_to_cpu (buf -> InodeType )) {
740747 case NFS_SPECFILE_CHR :
741- fattr -> cf_mode |= S_IFCHR | cifs_sb -> ctx -> file_mode ;
748+ fattr -> cf_mode |= S_IFCHR ;
742749 fattr -> cf_dtype = DT_CHR ;
743750 fattr -> cf_rdev = nfs_mkdev (buf );
744751 break ;
745752 case NFS_SPECFILE_BLK :
746- fattr -> cf_mode |= S_IFBLK | cifs_sb -> ctx -> file_mode ;
753+ fattr -> cf_mode |= S_IFBLK ;
747754 fattr -> cf_dtype = DT_BLK ;
748755 fattr -> cf_rdev = nfs_mkdev (buf );
749756 break ;
750757 case NFS_SPECFILE_FIFO :
751- fattr -> cf_mode |= S_IFIFO | cifs_sb -> ctx -> file_mode ;
758+ fattr -> cf_mode |= S_IFIFO ;
752759 fattr -> cf_dtype = DT_FIFO ;
753760 break ;
754761 case NFS_SPECFILE_SOCK :
755- fattr -> cf_mode |= S_IFSOCK | cifs_sb -> ctx -> file_mode ;
762+ fattr -> cf_mode |= S_IFSOCK ;
756763 fattr -> cf_dtype = DT_SOCK ;
757764 break ;
758765 case NFS_SPECFILE_LNK :
759- fattr -> cf_mode = S_IFLNK | cifs_sb -> ctx -> file_mode ;
766+ fattr -> cf_mode | = S_IFLNK ;
760767 fattr -> cf_dtype = DT_LNK ;
761768 break ;
762769 default :
@@ -768,29 +775,29 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
768775
769776 switch (tag ) {
770777 case IO_REPARSE_TAG_LX_SYMLINK :
771- fattr -> cf_mode |= S_IFLNK | cifs_sb -> ctx -> file_mode ;
778+ fattr -> cf_mode |= S_IFLNK ;
772779 fattr -> cf_dtype = DT_LNK ;
773780 break ;
774781 case IO_REPARSE_TAG_LX_FIFO :
775- fattr -> cf_mode |= S_IFIFO | cifs_sb -> ctx -> file_mode ;
782+ fattr -> cf_mode |= S_IFIFO ;
776783 fattr -> cf_dtype = DT_FIFO ;
777784 break ;
778785 case IO_REPARSE_TAG_AF_UNIX :
779- fattr -> cf_mode |= S_IFSOCK | cifs_sb -> ctx -> file_mode ;
786+ fattr -> cf_mode |= S_IFSOCK ;
780787 fattr -> cf_dtype = DT_SOCK ;
781788 break ;
782789 case IO_REPARSE_TAG_LX_CHR :
783- fattr -> cf_mode |= S_IFCHR | cifs_sb -> ctx -> file_mode ;
790+ fattr -> cf_mode |= S_IFCHR ;
784791 fattr -> cf_dtype = DT_CHR ;
785792 break ;
786793 case IO_REPARSE_TAG_LX_BLK :
787- fattr -> cf_mode |= S_IFBLK | cifs_sb -> ctx -> file_mode ;
794+ fattr -> cf_mode |= S_IFBLK ;
788795 fattr -> cf_dtype = DT_BLK ;
789796 break ;
790797 case 0 : /* SMB1 symlink */
791798 case IO_REPARSE_TAG_SYMLINK :
792799 case IO_REPARSE_TAG_NFS :
793- fattr -> cf_mode = S_IFLNK | cifs_sb -> ctx -> file_mode ;
800+ fattr -> cf_mode | = S_IFLNK ;
794801 fattr -> cf_dtype = DT_LNK ;
795802 break ;
796803 default :
@@ -830,6 +837,7 @@ static void cifs_open_info_to_fattr(struct cifs_fattr *fattr,
830837 fattr -> cf_createtime = le64_to_cpu (info -> CreationTime );
831838 fattr -> cf_nlink = le32_to_cpu (info -> NumberOfLinks );
832839
840+ fattr -> cf_mode = cifs_sb -> ctx -> file_mode ;
833841 if (cifs_open_data_reparse (data ) &&
834842 cifs_reparse_point_to_fattr (cifs_sb , fattr , data ))
835843 goto out_reparse ;
0 commit comments