@@ -112,7 +112,7 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
112
112
return - ENOMEM ;
113
113
114
114
if (!size ) {
115
- ;
115
+ /* EA info persists, but xattr is empty. Looks like EA problem. */
116
116
} else if (attr_ea -> non_res ) {
117
117
struct runs_tree run ;
118
118
@@ -259,7 +259,7 @@ static int ntfs_get_ea(struct inode *inode, const char *name, size_t name_len,
259
259
260
260
static noinline int ntfs_set_ea (struct inode * inode , const char * name ,
261
261
size_t name_len , const void * value ,
262
- size_t val_size , int flags )
262
+ size_t val_size , int flags , bool locked )
263
263
{
264
264
struct ntfs_inode * ni = ntfs_i (inode );
265
265
struct ntfs_sb_info * sbi = ni -> mi .sbi ;
@@ -278,7 +278,8 @@ static noinline int ntfs_set_ea(struct inode *inode, const char *name,
278
278
u64 new_sz ;
279
279
void * p ;
280
280
281
- ni_lock (ni );
281
+ if (!locked )
282
+ ni_lock (ni );
282
283
283
284
run_init (& ea_run );
284
285
@@ -467,7 +468,8 @@ static noinline int ntfs_set_ea(struct inode *inode, const char *name,
467
468
mark_inode_dirty (& ni -> vfs_inode );
468
469
469
470
out :
470
- ni_unlock (ni );
471
+ if (!locked )
472
+ ni_unlock (ni );
471
473
472
474
run_close (& ea_run );
473
475
kfree (ea_all );
@@ -541,7 +543,7 @@ struct posix_acl *ntfs_get_acl(struct inode *inode, int type, bool rcu)
541
543
542
544
static noinline int ntfs_set_acl_ex (struct user_namespace * mnt_userns ,
543
545
struct inode * inode , struct posix_acl * acl ,
544
- int type )
546
+ int type , bool init_acl )
545
547
{
546
548
const char * name ;
547
549
size_t size , name_len ;
@@ -554,8 +556,9 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
554
556
555
557
switch (type ) {
556
558
case ACL_TYPE_ACCESS :
557
- if (acl ) {
558
- umode_t mode = inode -> i_mode ;
559
+ /* Do not change i_mode if we are in init_acl */
560
+ if (acl && !init_acl ) {
561
+ umode_t mode ;
559
562
560
563
err = posix_acl_update_mode (mnt_userns , inode , & mode ,
561
564
& acl );
@@ -598,7 +601,7 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
598
601
flags = 0 ;
599
602
}
600
603
601
- err = ntfs_set_ea (inode , name , name_len , value , size , flags );
604
+ err = ntfs_set_ea (inode , name , name_len , value , size , flags , 0 );
602
605
if (err == - ENODATA && !size )
603
606
err = 0 ; /* Removing non existed xattr. */
604
607
if (!err )
@@ -616,7 +619,68 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
616
619
int ntfs_set_acl (struct user_namespace * mnt_userns , struct inode * inode ,
617
620
struct posix_acl * acl , int type )
618
621
{
619
- return ntfs_set_acl_ex (mnt_userns , inode , acl , type );
622
+ return ntfs_set_acl_ex (mnt_userns , inode , acl , type , false);
623
+ }
624
+
625
+ static int ntfs_xattr_get_acl (struct user_namespace * mnt_userns ,
626
+ struct inode * inode , int type , void * buffer ,
627
+ size_t size )
628
+ {
629
+ struct posix_acl * acl ;
630
+ int err ;
631
+
632
+ if (!(inode -> i_sb -> s_flags & SB_POSIXACL )) {
633
+ ntfs_inode_warn (inode , "add mount option \"acl\" to use acl" );
634
+ return - EOPNOTSUPP ;
635
+ }
636
+
637
+ acl = ntfs_get_acl (inode , type , false);
638
+ if (IS_ERR (acl ))
639
+ return PTR_ERR (acl );
640
+
641
+ if (!acl )
642
+ return - ENODATA ;
643
+
644
+ err = posix_acl_to_xattr (mnt_userns , acl , buffer , size );
645
+ posix_acl_release (acl );
646
+
647
+ return err ;
648
+ }
649
+
650
+ static int ntfs_xattr_set_acl (struct user_namespace * mnt_userns ,
651
+ struct inode * inode , int type , const void * value ,
652
+ size_t size )
653
+ {
654
+ struct posix_acl * acl ;
655
+ int err ;
656
+
657
+ if (!(inode -> i_sb -> s_flags & SB_POSIXACL )) {
658
+ ntfs_inode_warn (inode , "add mount option \"acl\" to use acl" );
659
+ return - EOPNOTSUPP ;
660
+ }
661
+
662
+ if (!inode_owner_or_capable (mnt_userns , inode ))
663
+ return - EPERM ;
664
+
665
+ if (!value ) {
666
+ acl = NULL ;
667
+ } else {
668
+ acl = posix_acl_from_xattr (mnt_userns , value , size );
669
+ if (IS_ERR (acl ))
670
+ return PTR_ERR (acl );
671
+
672
+ if (acl ) {
673
+ err = posix_acl_valid (mnt_userns , acl );
674
+ if (err )
675
+ goto release_and_out ;
676
+ }
677
+ }
678
+
679
+ err = ntfs_set_acl (mnt_userns , inode , acl , type );
680
+
681
+ release_and_out :
682
+ posix_acl_release (acl );
683
+ return err ;
620
684
}
621
685
622
686
/*
@@ -636,7 +700,7 @@ int ntfs_init_acl(struct user_namespace *mnt_userns, struct inode *inode,
636
700
637
701
if (default_acl ) {
638
702
err = ntfs_set_acl_ex (mnt_userns , inode , default_acl ,
639
- ACL_TYPE_DEFAULT );
703
+ ACL_TYPE_DEFAULT , true );
640
704
posix_acl_release (default_acl );
641
705
} else {
642
706
inode -> i_default_acl = NULL ;
@@ -647,7 +711,7 @@ int ntfs_init_acl(struct user_namespace *mnt_userns, struct inode *inode,
647
711
else {
648
712
if (!err )
649
713
err = ntfs_set_acl_ex (mnt_userns , inode , acl ,
650
- ACL_TYPE_ACCESS );
714
+ ACL_TYPE_ACCESS , true );
651
715
posix_acl_release (acl );
652
716
}
653
717
@@ -785,6 +849,23 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
785
849
goto out ;
786
850
}
787
851
852
+ #ifdef CONFIG_NTFS3_FS_POSIX_ACL
853
+ if ((name_len == sizeof (XATTR_NAME_POSIX_ACL_ACCESS ) - 1 &&
854
+ !memcmp (name , XATTR_NAME_POSIX_ACL_ACCESS ,
855
+ sizeof (XATTR_NAME_POSIX_ACL_ACCESS ))) ||
856
+ (name_len == sizeof (XATTR_NAME_POSIX_ACL_DEFAULT ) - 1 &&
857
+ !memcmp (name , XATTR_NAME_POSIX_ACL_DEFAULT ,
858
+ sizeof (XATTR_NAME_POSIX_ACL_DEFAULT )))) {
859
+ /* TODO: init_user_ns? */
860
+ err = ntfs_xattr_get_acl (
861
+ & init_user_ns , inode ,
862
+ name_len == sizeof (XATTR_NAME_POSIX_ACL_ACCESS ) - 1
863
+ ? ACL_TYPE_ACCESS
864
+ : ACL_TYPE_DEFAULT ,
865
+ buffer , size );
866
+ goto out ;
867
+ }
868
+ #endif
788
869
/* Deal with NTFS extended attribute. */
789
870
err = ntfs_get_ea (inode , name , name_len , buffer , size , NULL );
790
871
@@ -897,10 +978,29 @@ static noinline int ntfs_setxattr(const struct xattr_handler *handler,
897
978
goto out ;
898
979
}
899
980
981
+ #ifdef CONFIG_NTFS3_FS_POSIX_ACL
982
+ if ((name_len == sizeof (XATTR_NAME_POSIX_ACL_ACCESS ) - 1 &&
983
+ !memcmp (name , XATTR_NAME_POSIX_ACL_ACCESS ,
984
+ sizeof (XATTR_NAME_POSIX_ACL_ACCESS ))) ||
985
+ (name_len == sizeof (XATTR_NAME_POSIX_ACL_DEFAULT ) - 1 &&
986
+ !memcmp (name , XATTR_NAME_POSIX_ACL_DEFAULT ,
987
+ sizeof (XATTR_NAME_POSIX_ACL_DEFAULT )))) {
988
+ err = ntfs_xattr_set_acl (
989
+ mnt_userns , inode ,
990
+ name_len == sizeof (XATTR_NAME_POSIX_ACL_ACCESS ) - 1
991
+ ? ACL_TYPE_ACCESS
992
+ : ACL_TYPE_DEFAULT ,
993
+ value , size );
994
+ goto out ;
995
+ }
996
+ #endif
900
997
/* Deal with NTFS extended attribute. */
901
- err = ntfs_set_ea (inode , name , name_len , value , size , flags );
998
+ err = ntfs_set_ea (inode , name , name_len , value , size , flags , 0 );
902
999
903
1000
out :
1001
+ inode -> i_ctime = current_time (inode );
1002
+ mark_inode_dirty (inode );
1003
+
904
1004
return err ;
905
1005
}
906
1006
@@ -913,35 +1013,37 @@ int ntfs_save_wsl_perm(struct inode *inode)
913
1013
{
914
1014
int err ;
915
1015
__le32 value ;
1016
+ struct ntfs_inode * ni = ntfs_i (inode );
916
1017
917
- /* TODO: refactor this, so we don't lock 4 times in ntfs_set_ea */
1018
+ ni_lock ( ni );
918
1019
value = cpu_to_le32 (i_uid_read (inode ));
919
1020
err = ntfs_set_ea (inode , "$LXUID" , sizeof ("$LXUID" ) - 1 , & value ,
920
- sizeof (value ), 0 );
1021
+ sizeof (value ), 0 , true); /* true == already locked. */
921
1022
if (err )
922
1023
goto out ;
923
1024
924
1025
value = cpu_to_le32 (i_gid_read (inode ));
925
1026
err = ntfs_set_ea (inode , "$LXGID" , sizeof ("$LXGID" ) - 1 , & value ,
926
- sizeof (value ), 0 );
1027
+ sizeof (value ), 0 , true );
927
1028
if (err )
928
1029
goto out ;
929
1030
930
1031
value = cpu_to_le32 (inode -> i_mode );
931
1032
err = ntfs_set_ea (inode , "$LXMOD" , sizeof ("$LXMOD" ) - 1 , & value ,
932
- sizeof (value ), 0 );
1033
+ sizeof (value ), 0 , true );
933
1034
if (err )
934
1035
goto out ;
935
1036
936
1037
if (S_ISCHR (inode -> i_mode ) || S_ISBLK (inode -> i_mode )) {
937
1038
value = cpu_to_le32 (inode -> i_rdev );
938
1039
err = ntfs_set_ea (inode , "$LXDEV" , sizeof ("$LXDEV" ) - 1 , & value ,
939
- sizeof (value ), 0 );
1040
+ sizeof (value ), 0 , true );
940
1041
if (err )
941
1042
goto out ;
942
1043
}
943
1044
944
1045
out :
1046
+ ni_unlock (ni );
945
1047
/* In case of error should we delete all WSL xattr? */
946
1048
return err ;
947
1049
}
0 commit comments