Skip to content

Commit 9c38568

Browse files
Paulo Alcantarasmfrench
authored andcommitted
smb: client: handle special files and symlinks in SMB3 POSIX
Parse reparse points in SMB3 posix query info as they will be supported and required by the new specification. Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 3ded18a commit 9c38568

File tree

1 file changed

+29
-21
lines changed

1 file changed

+29
-21
lines changed

fs/smb/client/inode.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)