@@ -258,7 +258,9 @@ static int mknod_wsl(unsigned int xid, struct inode *inode,
258258{
259259 struct cifs_open_info_data data ;
260260 struct reparse_data_buffer buf ;
261+ struct smb2_create_ea_ctx * cc ;
261262 struct inode * new ;
263+ unsigned int len ;
262264 struct kvec reparse_iov , xattr_iov ;
263265 int rc ;
264266
@@ -275,6 +277,11 @@ static int mknod_wsl(unsigned int xid, struct inode *inode,
275277 .reparse = { .tag = le32_to_cpu (buf .ReparseTag ), .buf = & buf , },
276278 };
277279
280+ cc = xattr_iov .iov_base ;
281+ len = le32_to_cpu (cc -> ctx .DataLength );
282+ memcpy (data .wsl .eas , & cc -> ea , len );
283+ data .wsl .eas_len = len ;
284+
278285 new = smb2_get_reparse_inode (& data , inode -> i_sb ,
279286 xid , tcon , full_path ,
280287 & reparse_iov , & xattr_iov );
@@ -408,6 +415,62 @@ int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
408415 return parse_reparse_point (buf , plen , cifs_sb , true, data );
409416}
410417
418+ static void wsl_to_fattr (struct cifs_open_info_data * data ,
419+ struct cifs_sb_info * cifs_sb ,
420+ u32 tag , struct cifs_fattr * fattr )
421+ {
422+ struct smb2_file_full_ea_info * ea ;
423+ u32 next = 0 ;
424+
425+ switch (tag ) {
426+ case IO_REPARSE_TAG_LX_SYMLINK :
427+ fattr -> cf_mode |= S_IFLNK ;
428+ break ;
429+ case IO_REPARSE_TAG_LX_FIFO :
430+ fattr -> cf_mode |= S_IFIFO ;
431+ break ;
432+ case IO_REPARSE_TAG_AF_UNIX :
433+ fattr -> cf_mode |= S_IFSOCK ;
434+ break ;
435+ case IO_REPARSE_TAG_LX_CHR :
436+ fattr -> cf_mode |= S_IFCHR ;
437+ break ;
438+ case IO_REPARSE_TAG_LX_BLK :
439+ fattr -> cf_mode |= S_IFBLK ;
440+ break ;
441+ }
442+
443+ if (!data -> wsl .eas_len )
444+ goto out ;
445+
446+ ea = (struct smb2_file_full_ea_info * )data -> wsl .eas ;
447+ do {
448+ const char * name ;
449+ void * v ;
450+ u8 nlen ;
451+
452+ ea = (void * )((u8 * )ea + next );
453+ next = le32_to_cpu (ea -> next_entry_offset );
454+ if (!le16_to_cpu (ea -> ea_value_length ))
455+ continue ;
456+
457+ name = ea -> ea_data ;
458+ nlen = ea -> ea_name_length ;
459+ v = (void * )((u8 * )ea -> ea_data + ea -> ea_name_length + 1 );
460+
461+ if (!strncmp (name , SMB2_WSL_XATTR_UID , nlen ))
462+ fattr -> cf_uid = wsl_make_kuid (cifs_sb , v );
463+ else if (!strncmp (name , SMB2_WSL_XATTR_GID , nlen ))
464+ fattr -> cf_gid = wsl_make_kgid (cifs_sb , v );
465+ else if (!strncmp (name , SMB2_WSL_XATTR_MODE , nlen ))
466+ fattr -> cf_mode = (umode_t )le32_to_cpu (* (__le32 * )v );
467+ else if (!strncmp (name , SMB2_WSL_XATTR_DEV , nlen ))
468+ fattr -> cf_rdev = wsl_mkdev (v );
469+ } while (next );
470+ out :
471+ fattr -> cf_dtype = S_DT (fattr -> cf_mode );
472+ }
473+
411474bool cifs_reparse_point_to_fattr (struct cifs_sb_info * cifs_sb ,
412475 struct cifs_fattr * fattr ,
413476 struct cifs_open_info_data * data )
@@ -448,24 +511,11 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
448511
449512 switch (tag ) {
450513 case IO_REPARSE_TAG_LX_SYMLINK :
451- fattr -> cf_mode |= S_IFLNK ;
452- fattr -> cf_dtype = DT_LNK ;
453- break ;
454514 case IO_REPARSE_TAG_LX_FIFO :
455- fattr -> cf_mode |= S_IFIFO ;
456- fattr -> cf_dtype = DT_FIFO ;
457- break ;
458515 case IO_REPARSE_TAG_AF_UNIX :
459- fattr -> cf_mode |= S_IFSOCK ;
460- fattr -> cf_dtype = DT_SOCK ;
461- break ;
462516 case IO_REPARSE_TAG_LX_CHR :
463- fattr -> cf_mode |= S_IFCHR ;
464- fattr -> cf_dtype = DT_CHR ;
465- break ;
466517 case IO_REPARSE_TAG_LX_BLK :
467- fattr -> cf_mode |= S_IFBLK ;
468- fattr -> cf_dtype = DT_BLK ;
518+ wsl_to_fattr (data , cifs_sb , tag , fattr );
469519 break ;
470520 case 0 : /* SMB1 symlink */
471521 case IO_REPARSE_TAG_SYMLINK :
0 commit comments