@@ -444,20 +444,11 @@ impl fuser::Filesystem for Filesystem {
444
444
. get_path_or_panic ( ino) ;
445
445
let ops = self . ops . clone ( ) ;
446
446
self . tokio_handle . spawn ( async move {
447
- match ops. stat_entry ( & path) . await {
448
- Ok ( stat) => reply
449
- . manual ( )
450
- . attr ( & TTL , & entry_stat_to_file_attr ( stat, ino, uid, gid) ) ,
451
- Err ( err) => match err {
452
- WorkspaceStatEntryError :: EntryNotFound => reply. manual ( ) . error ( libc:: ENOENT ) ,
453
- WorkspaceStatEntryError :: Offline => reply. manual ( ) . error ( libc:: EHOSTUNREACH ) ,
454
- WorkspaceStatEntryError :: NoRealmAccess => reply. manual ( ) . error ( libc:: EPERM ) ,
455
- WorkspaceStatEntryError :: Stopped
456
- | WorkspaceStatEntryError :: InvalidKeysBundle ( _)
457
- | WorkspaceStatEntryError :: InvalidCertificate ( _)
458
- | WorkspaceStatEntryError :: InvalidManifest ( _)
459
- | WorkspaceStatEntryError :: Internal ( _) => reply. manual ( ) . error ( libc:: EIO ) ,
460
- } ,
447
+ let res = getattr_from_path ( & ops, path, ino, uid, gid) . await ;
448
+
449
+ match res {
450
+ Ok ( stat) => reply. manual ( ) . attr ( & TTL , & stat) ,
451
+ Err ( errno) => reply. manual ( ) . error ( errno) ,
461
452
}
462
453
} ) ;
463
454
}
@@ -1033,6 +1024,7 @@ impl fuser::Filesystem for Filesystem {
1033
1024
1034
1025
return ;
1035
1026
} else {
1027
+ // FIXME: Currently I'm only returning the file attributes without truncating the file
1036
1028
// Truncate file by path
1037
1029
1038
1030
let path = {
@@ -1121,7 +1113,26 @@ impl fuser::Filesystem for Filesystem {
1121
1113
1122
1114
// TODO: support atime/utime change ?
1123
1115
1124
- reply. manual ( ) . error ( libc:: ENOSYS ) ;
1116
+ // Nothing to set, just return the file attr
1117
+ // Seems benign but it's important for `setattr` to return the file attributes even if
1118
+ // nothing changed.
1119
+ // Previously we where returning an error and that caused the issues #8976 and #8991
1120
+
1121
+ let path = {
1122
+ let inodes_guard = self . inodes . lock ( ) . expect ( "Mutex is poisoned" ) ;
1123
+ inodes_guard. get_path_or_panic ( ino)
1124
+ } ;
1125
+
1126
+ let ops = self . ops . clone ( ) ;
1127
+
1128
+ self . tokio_handle . spawn ( async move {
1129
+ let res = getattr_from_path ( & ops, path, ino, uid, gid) . await ;
1130
+
1131
+ match res {
1132
+ Ok ( attr) => reply. manual ( ) . attr ( & TTL , & attr) ,
1133
+ Err ( errno) => reply. manual ( ) . error ( errno) ,
1134
+ }
1135
+ } ) ;
1125
1136
}
1126
1137
1127
1138
fn read (
@@ -1636,3 +1647,31 @@ impl fuser::Filesystem for Filesystem {
1636
1647
// TODO: Fuser exposes a `copy_file_range` method for FUSE >= 7.28. This
1637
1648
// would speed up file copy a lot by reusing the same blocks !
1638
1649
}
1650
+
1651
+ async fn getattr_from_path (
1652
+ ops : & WorkspaceOps ,
1653
+ path : FsPath ,
1654
+ ino : u64 ,
1655
+ uid : u32 ,
1656
+ gid : u32 ,
1657
+ ) -> Result < fuser:: FileAttr , i32 > {
1658
+ match ops
1659
+ . stat_entry ( & path)
1660
+ . await
1661
+ . map ( |stat| entry_stat_to_file_attr ( stat, ino, uid, gid) )
1662
+ . inspect ( |stat| log:: trace!( "File stat for {ino}: {stat:?}" ) )
1663
+ . inspect_err ( |e| log:: trace!( "File stat for {ino} result in error: {e:?}" ) )
1664
+ {
1665
+ Ok ( stat) => Ok ( stat) ,
1666
+ Err ( err) => match err {
1667
+ WorkspaceStatEntryError :: EntryNotFound => Err ( libc:: ENOENT ) ,
1668
+ WorkspaceStatEntryError :: Offline => Err ( libc:: EHOSTUNREACH ) ,
1669
+ WorkspaceStatEntryError :: NoRealmAccess => Err ( libc:: EPERM ) ,
1670
+ WorkspaceStatEntryError :: Stopped
1671
+ | WorkspaceStatEntryError :: InvalidKeysBundle ( _)
1672
+ | WorkspaceStatEntryError :: InvalidCertificate ( _)
1673
+ | WorkspaceStatEntryError :: InvalidManifest ( _)
1674
+ | WorkspaceStatEntryError :: Internal ( _) => Err ( libc:: EIO ) ,
1675
+ } ,
1676
+ }
1677
+ }
0 commit comments