@@ -116,7 +116,7 @@ u64 entry_attr_timeout(struct fuse_entry_out *o)
116
116
return time_to_jiffies (o -> attr_valid , o -> attr_valid_nsec );
117
117
}
118
118
119
- static void fuse_invalidate_attr_mask (struct inode * inode , u32 mask )
119
+ void fuse_invalidate_attr_mask (struct inode * inode , u32 mask )
120
120
{
121
121
set_mask_bits (& get_fuse_inode (inode )-> inval_mask , 0 , mask );
122
122
}
@@ -738,14 +738,51 @@ static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir,
738
738
return create_new_entry (fm , & args , dir , entry , S_IFLNK );
739
739
}
740
740
741
- void fuse_update_ctime (struct inode * inode )
741
+ void fuse_flush_time_update (struct inode * inode )
742
+ {
743
+ int err = sync_inode_metadata (inode , 1 );
744
+
745
+ mapping_set_error (inode -> i_mapping , err );
746
+ }
747
+
748
+ static void fuse_update_ctime_in_cache (struct inode * inode )
742
749
{
743
750
if (!IS_NOCMTIME (inode )) {
744
751
inode -> i_ctime = current_time (inode );
745
752
mark_inode_dirty_sync (inode );
753
+ fuse_flush_time_update (inode );
746
754
}
747
755
}
748
756
757
+ void fuse_update_ctime (struct inode * inode )
758
+ {
759
+ fuse_invalidate_attr_mask (inode , STATX_CTIME );
760
+ fuse_update_ctime_in_cache (inode );
761
+ }
762
+
763
+ static void fuse_entry_unlinked (struct dentry * entry )
764
+ {
765
+ struct inode * inode = d_inode (entry );
766
+ struct fuse_conn * fc = get_fuse_conn (inode );
767
+ struct fuse_inode * fi = get_fuse_inode (inode );
768
+
769
+ spin_lock (& fi -> lock );
770
+ fi -> attr_version = atomic64_inc_return (& fc -> attr_version );
771
+ /*
772
+ * If i_nlink == 0 then unlink doesn't make sense, yet this can
773
+ * happen if userspace filesystem is careless. It would be
774
+ * difficult to enforce correct nlink usage so just ignore this
775
+ * condition here
776
+ */
777
+ if (S_ISDIR (inode -> i_mode ))
778
+ clear_nlink (inode );
779
+ else if (inode -> i_nlink > 0 )
780
+ drop_nlink (inode );
781
+ spin_unlock (& fi -> lock );
782
+ fuse_invalidate_entry_cache (entry );
783
+ fuse_update_ctime (inode );
784
+ }
785
+
749
786
static int fuse_unlink (struct inode * dir , struct dentry * entry )
750
787
{
751
788
int err ;
@@ -762,24 +799,8 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
762
799
args .in_args [0 ].value = entry -> d_name .name ;
763
800
err = fuse_simple_request (fm , & args );
764
801
if (!err ) {
765
- struct inode * inode = d_inode (entry );
766
- struct fuse_inode * fi = get_fuse_inode (inode );
767
-
768
- spin_lock (& fi -> lock );
769
- fi -> attr_version = atomic64_inc_return (& fm -> fc -> attr_version );
770
- /*
771
- * If i_nlink == 0 then unlink doesn't make sense, yet this can
772
- * happen if userspace filesystem is careless. It would be
773
- * difficult to enforce correct nlink usage so just ignore this
774
- * condition here
775
- */
776
- if (inode -> i_nlink > 0 )
777
- drop_nlink (inode );
778
- spin_unlock (& fi -> lock );
779
- fuse_invalidate_attr (inode );
780
802
fuse_dir_changed (dir );
781
- fuse_invalidate_entry_cache (entry );
782
- fuse_update_ctime (inode );
803
+ fuse_entry_unlinked (entry );
783
804
} else if (err == - EINTR )
784
805
fuse_invalidate_entry (entry );
785
806
return err ;
@@ -801,9 +822,8 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
801
822
args .in_args [0 ].value = entry -> d_name .name ;
802
823
err = fuse_simple_request (fm , & args );
803
824
if (!err ) {
804
- clear_nlink (d_inode (entry ));
805
825
fuse_dir_changed (dir );
806
- fuse_invalidate_entry_cache (entry );
826
+ fuse_entry_unlinked (entry );
807
827
} else if (err == - EINTR )
808
828
fuse_invalidate_entry (entry );
809
829
return err ;
@@ -833,24 +853,18 @@ static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
833
853
err = fuse_simple_request (fm , & args );
834
854
if (!err ) {
835
855
/* ctime changes */
836
- fuse_invalidate_attr (d_inode (oldent ));
837
856
fuse_update_ctime (d_inode (oldent ));
838
857
839
- if (flags & RENAME_EXCHANGE ) {
840
- fuse_invalidate_attr (d_inode (newent ));
858
+ if (flags & RENAME_EXCHANGE )
841
859
fuse_update_ctime (d_inode (newent ));
842
- }
843
860
844
861
fuse_dir_changed (olddir );
845
862
if (olddir != newdir )
846
863
fuse_dir_changed (newdir );
847
864
848
865
/* newent will end up negative */
849
- if (!(flags & RENAME_EXCHANGE ) && d_really_is_positive (newent )) {
850
- fuse_invalidate_attr (d_inode (newent ));
851
- fuse_invalidate_entry_cache (newent );
852
- fuse_update_ctime (d_inode (newent ));
853
- }
866
+ if (!(flags & RENAME_EXCHANGE ) && d_really_is_positive (newent ))
867
+ fuse_entry_unlinked (newent );
854
868
} else if (err == - EINTR ) {
855
869
/* If request was interrupted, DEITY only knows if the
856
870
rename actually took place. If the invalidation
@@ -916,25 +930,11 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
916
930
args .in_args [1 ].size = newent -> d_name .len + 1 ;
917
931
args .in_args [1 ].value = newent -> d_name .name ;
918
932
err = create_new_entry (fm , & args , newdir , newent , inode -> i_mode );
919
- /* Contrary to "normal" filesystems it can happen that link
920
- makes two "logical" inodes point to the same "physical"
921
- inode. We invalidate the attributes of the old one, so it
922
- will reflect changes in the backing inode (link count,
923
- etc.)
924
- */
925
- if (!err ) {
926
- struct fuse_inode * fi = get_fuse_inode (inode );
927
-
928
- spin_lock (& fi -> lock );
929
- fi -> attr_version = atomic64_inc_return (& fm -> fc -> attr_version );
930
- if (likely (inode -> i_nlink < UINT_MAX ))
931
- inc_nlink (inode );
932
- spin_unlock (& fi -> lock );
933
- fuse_invalidate_attr (inode );
934
- fuse_update_ctime (inode );
935
- } else if (err == - EINTR ) {
933
+ if (!err )
934
+ fuse_update_ctime_in_cache (inode );
935
+ else if (err == - EINTR )
936
936
fuse_invalidate_attr (inode );
937
- }
937
+
938
938
return err ;
939
939
}
940
940
@@ -944,15 +944,6 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
944
944
unsigned int blkbits ;
945
945
struct fuse_conn * fc = get_fuse_conn (inode );
946
946
947
- /* see the comment in fuse_change_attributes() */
948
- if (fc -> writeback_cache && S_ISREG (inode -> i_mode )) {
949
- attr -> size = i_size_read (inode );
950
- attr -> mtime = inode -> i_mtime .tv_sec ;
951
- attr -> mtimensec = inode -> i_mtime .tv_nsec ;
952
- attr -> ctime = inode -> i_ctime .tv_sec ;
953
- attr -> ctimensec = inode -> i_ctime .tv_nsec ;
954
- }
955
-
956
947
stat -> dev = inode -> i_sb -> s_dev ;
957
948
stat -> ino = attr -> ino ;
958
949
stat -> mode = (inode -> i_mode & S_IFMT ) | (attr -> mode & 07777 );
@@ -1030,12 +1021,14 @@ static int fuse_update_get_attr(struct inode *inode, struct file *file,
1030
1021
struct fuse_inode * fi = get_fuse_inode (inode );
1031
1022
int err = 0 ;
1032
1023
bool sync ;
1024
+ u32 inval_mask = READ_ONCE (fi -> inval_mask );
1025
+ u32 cache_mask = fuse_get_cache_mask (inode );
1033
1026
1034
1027
if (flags & AT_STATX_FORCE_SYNC )
1035
1028
sync = true;
1036
1029
else if (flags & AT_STATX_DONT_SYNC )
1037
1030
sync = false;
1038
- else if (request_mask & READ_ONCE ( fi -> inval_mask ) )
1031
+ else if (request_mask & inval_mask & ~ cache_mask )
1039
1032
sync = true;
1040
1033
else
1041
1034
sync = time_before64 (fi -> i_time , get_jiffies_64 ());
@@ -1052,11 +1045,9 @@ static int fuse_update_get_attr(struct inode *inode, struct file *file,
1052
1045
return err ;
1053
1046
}
1054
1047
1055
- int fuse_update_attributes (struct inode * inode , struct file * file )
1048
+ int fuse_update_attributes (struct inode * inode , struct file * file , u32 mask )
1056
1049
{
1057
- /* Do *not* need to get atime for internal purposes */
1058
- return fuse_update_get_attr (inode , file , NULL ,
1059
- STATX_BASIC_STATS & ~STATX_ATIME , 0 );
1050
+ return fuse_update_get_attr (inode , file , NULL , mask , 0 );
1060
1051
}
1061
1052
1062
1053
int fuse_reverse_inval_entry (struct fuse_conn * fc , u64 parent_nodeid ,
@@ -1071,7 +1062,7 @@ int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
1071
1062
if (!parent )
1072
1063
return - ENOENT ;
1073
1064
1074
- inode_lock (parent );
1065
+ inode_lock_nested (parent , I_MUTEX_PARENT );
1075
1066
if (!S_ISDIR (parent -> i_mode ))
1076
1067
goto unlock ;
1077
1068
@@ -1561,10 +1552,10 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
1561
1552
struct fuse_setattr_in inarg ;
1562
1553
struct fuse_attr_out outarg ;
1563
1554
bool is_truncate = false;
1564
- bool is_wb = fc -> writeback_cache ;
1555
+ bool is_wb = fc -> writeback_cache && S_ISREG ( inode -> i_mode ) ;
1565
1556
loff_t oldsize ;
1566
1557
int err ;
1567
- bool trust_local_cmtime = is_wb && S_ISREG ( inode -> i_mode ) ;
1558
+ bool trust_local_cmtime = is_wb ;
1568
1559
bool fault_blocked = false;
1569
1560
1570
1561
if (!fc -> default_permissions )
@@ -1608,7 +1599,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
1608
1599
}
1609
1600
1610
1601
/* Flush dirty data/metadata before non-truncate SETATTR */
1611
- if (is_wb && S_ISREG ( inode -> i_mode ) &&
1602
+ if (is_wb &&
1612
1603
attr -> ia_valid &
1613
1604
(ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET |
1614
1605
ATTR_TIMES_SET )) {
@@ -1676,10 +1667,11 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
1676
1667
}
1677
1668
1678
1669
fuse_change_attributes_common (inode , & outarg .attr ,
1679
- attr_timeout (& outarg ));
1670
+ attr_timeout (& outarg ),
1671
+ fuse_get_cache_mask (inode ));
1680
1672
oldsize = inode -> i_size ;
1681
1673
/* see the comment in fuse_change_attributes() */
1682
- if (!is_wb || is_truncate || ! S_ISREG ( inode -> i_mode ) )
1674
+ if (!is_wb || is_truncate )
1683
1675
i_size_write (inode , outarg .attr .size );
1684
1676
1685
1677
if (is_truncate ) {
0 commit comments