@@ -258,7 +258,9 @@ static int mknod_wsl(unsigned int xid, struct inode *inode,
258
258
{
259
259
struct cifs_open_info_data data ;
260
260
struct reparse_data_buffer buf ;
261
+ struct smb2_create_ea_ctx * cc ;
261
262
struct inode * new ;
263
+ unsigned int len ;
262
264
struct kvec reparse_iov , xattr_iov ;
263
265
int rc ;
264
266
@@ -275,6 +277,11 @@ static int mknod_wsl(unsigned int xid, struct inode *inode,
275
277
.reparse = { .tag = le32_to_cpu (buf .ReparseTag ), .buf = & buf , },
276
278
};
277
279
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
+
278
285
new = smb2_get_reparse_inode (& data , inode -> i_sb ,
279
286
xid , tcon , full_path ,
280
287
& reparse_iov , & xattr_iov );
@@ -408,6 +415,62 @@ int smb2_parse_reparse_point(struct cifs_sb_info *cifs_sb,
408
415
return parse_reparse_point (buf , plen , cifs_sb , true, data );
409
416
}
410
417
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
+
411
474
bool cifs_reparse_point_to_fattr (struct cifs_sb_info * cifs_sb ,
412
475
struct cifs_fattr * fattr ,
413
476
struct cifs_open_info_data * data )
@@ -448,24 +511,11 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
448
511
449
512
switch (tag ) {
450
513
case IO_REPARSE_TAG_LX_SYMLINK :
451
- fattr -> cf_mode |= S_IFLNK ;
452
- fattr -> cf_dtype = DT_LNK ;
453
- break ;
454
514
case IO_REPARSE_TAG_LX_FIFO :
455
- fattr -> cf_mode |= S_IFIFO ;
456
- fattr -> cf_dtype = DT_FIFO ;
457
- break ;
458
515
case IO_REPARSE_TAG_AF_UNIX :
459
- fattr -> cf_mode |= S_IFSOCK ;
460
- fattr -> cf_dtype = DT_SOCK ;
461
- break ;
462
516
case IO_REPARSE_TAG_LX_CHR :
463
- fattr -> cf_mode |= S_IFCHR ;
464
- fattr -> cf_dtype = DT_CHR ;
465
- break ;
466
517
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 );
469
519
break ;
470
520
case 0 : /* SMB1 symlink */
471
521
case IO_REPARSE_TAG_SYMLINK :
0 commit comments