@@ -116,7 +116,7 @@ u64 entry_attr_timeout(struct fuse_entry_out *o)
116116 return time_to_jiffies (o -> attr_valid , o -> attr_valid_nsec );
117117}
118118
119- static void fuse_invalidate_attr_mask (struct inode * inode , u32 mask )
119+ void fuse_invalidate_attr_mask (struct inode * inode , u32 mask )
120120{
121121 set_mask_bits (& get_fuse_inode (inode )-> inval_mask , 0 , mask );
122122}
@@ -738,14 +738,51 @@ static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir,
738738 return create_new_entry (fm , & args , dir , entry , S_IFLNK );
739739}
740740
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 )
742749{
743750 if (!IS_NOCMTIME (inode )) {
744751 inode -> i_ctime = current_time (inode );
745752 mark_inode_dirty_sync (inode );
753+ fuse_flush_time_update (inode );
746754 }
747755}
748756
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+
749786static int fuse_unlink (struct inode * dir , struct dentry * entry )
750787{
751788 int err ;
@@ -762,24 +799,8 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
762799 args .in_args [0 ].value = entry -> d_name .name ;
763800 err = fuse_simple_request (fm , & args );
764801 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 );
780802 fuse_dir_changed (dir );
781- fuse_invalidate_entry_cache (entry );
782- fuse_update_ctime (inode );
803+ fuse_entry_unlinked (entry );
783804 } else if (err == - EINTR )
784805 fuse_invalidate_entry (entry );
785806 return err ;
@@ -801,9 +822,8 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
801822 args .in_args [0 ].value = entry -> d_name .name ;
802823 err = fuse_simple_request (fm , & args );
803824 if (!err ) {
804- clear_nlink (d_inode (entry ));
805825 fuse_dir_changed (dir );
806- fuse_invalidate_entry_cache (entry );
826+ fuse_entry_unlinked (entry );
807827 } else if (err == - EINTR )
808828 fuse_invalidate_entry (entry );
809829 return err ;
@@ -833,24 +853,18 @@ static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
833853 err = fuse_simple_request (fm , & args );
834854 if (!err ) {
835855 /* ctime changes */
836- fuse_invalidate_attr (d_inode (oldent ));
837856 fuse_update_ctime (d_inode (oldent ));
838857
839- if (flags & RENAME_EXCHANGE ) {
840- fuse_invalidate_attr (d_inode (newent ));
858+ if (flags & RENAME_EXCHANGE )
841859 fuse_update_ctime (d_inode (newent ));
842- }
843860
844861 fuse_dir_changed (olddir );
845862 if (olddir != newdir )
846863 fuse_dir_changed (newdir );
847864
848865 /* 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 );
854868 } else if (err == - EINTR ) {
855869 /* If request was interrupted, DEITY only knows if the
856870 rename actually took place. If the invalidation
@@ -916,25 +930,11 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
916930 args .in_args [1 ].size = newent -> d_name .len + 1 ;
917931 args .in_args [1 ].value = newent -> d_name .name ;
918932 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 )
936936 fuse_invalidate_attr (inode );
937- }
937+
938938 return err ;
939939}
940940
@@ -944,15 +944,6 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
944944 unsigned int blkbits ;
945945 struct fuse_conn * fc = get_fuse_conn (inode );
946946
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-
956947 stat -> dev = inode -> i_sb -> s_dev ;
957948 stat -> ino = attr -> ino ;
958949 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,
10301021 struct fuse_inode * fi = get_fuse_inode (inode );
10311022 int err = 0 ;
10321023 bool sync ;
1024+ u32 inval_mask = READ_ONCE (fi -> inval_mask );
1025+ u32 cache_mask = fuse_get_cache_mask (inode );
10331026
10341027 if (flags & AT_STATX_FORCE_SYNC )
10351028 sync = true;
10361029 else if (flags & AT_STATX_DONT_SYNC )
10371030 sync = false;
1038- else if (request_mask & READ_ONCE ( fi -> inval_mask ) )
1031+ else if (request_mask & inval_mask & ~ cache_mask )
10391032 sync = true;
10401033 else
10411034 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,
10521045 return err ;
10531046}
10541047
1055- int fuse_update_attributes (struct inode * inode , struct file * file )
1048+ int fuse_update_attributes (struct inode * inode , struct file * file , u32 mask )
10561049{
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 );
10601051}
10611052
10621053int 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,
10711062 if (!parent )
10721063 return - ENOENT ;
10731064
1074- inode_lock (parent );
1065+ inode_lock_nested (parent , I_MUTEX_PARENT );
10751066 if (!S_ISDIR (parent -> i_mode ))
10761067 goto unlock ;
10771068
@@ -1561,10 +1552,10 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
15611552 struct fuse_setattr_in inarg ;
15621553 struct fuse_attr_out outarg ;
15631554 bool is_truncate = false;
1564- bool is_wb = fc -> writeback_cache ;
1555+ bool is_wb = fc -> writeback_cache && S_ISREG ( inode -> i_mode ) ;
15651556 loff_t oldsize ;
15661557 int err ;
1567- bool trust_local_cmtime = is_wb && S_ISREG ( inode -> i_mode ) ;
1558+ bool trust_local_cmtime = is_wb ;
15681559 bool fault_blocked = false;
15691560
15701561 if (!fc -> default_permissions )
@@ -1608,7 +1599,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
16081599 }
16091600
16101601 /* Flush dirty data/metadata before non-truncate SETATTR */
1611- if (is_wb && S_ISREG ( inode -> i_mode ) &&
1602+ if (is_wb &&
16121603 attr -> ia_valid &
16131604 (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET |
16141605 ATTR_TIMES_SET )) {
@@ -1676,10 +1667,11 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
16761667 }
16771668
16781669 fuse_change_attributes_common (inode , & outarg .attr ,
1679- attr_timeout (& outarg ));
1670+ attr_timeout (& outarg ),
1671+ fuse_get_cache_mask (inode ));
16801672 oldsize = inode -> i_size ;
16811673 /* see the comment in fuse_change_attributes() */
1682- if (!is_wb || is_truncate || ! S_ISREG ( inode -> i_mode ) )
1674+ if (!is_wb || is_truncate )
16831675 i_size_write (inode , outarg .attr .size );
16841676
16851677 if (is_truncate ) {
0 commit comments