@@ -13,12 +13,22 @@ public FuseHandlesManager(StreamsAccess streamsAccess, VirtualFileSystemOptions
1313 {
1414 }
1515
16+ /// <summary>
17+ /// Provides an enumerable collection of all currently active handles managed by the instance.
18+ /// </summary>
19+ /// <remarks>
20+ /// The handles are returned as a snapshot of the internal collection to prevent race conditions
21+ /// when accessing or enumerating the data. Any modifications to the collection are thread-safe
22+ /// and do not affect the snapshot returned by this property.
23+ /// </remarks>
1624 public IEnumerable < IDisposable > OpenHandles
1725 {
1826 get
1927 {
28+ // Return a snapshot - the live collection could be mutated
29+ // by another thread while the caller is enumerating it
2030 lock ( handles )
21- return handles . Values ;
31+ return handles . Values . ToArray ( ) ;
2232 }
2333 }
2434
@@ -38,7 +48,11 @@ public override ulong OpenFileHandle(string ciphertextPath, FileMode mode, FileA
3848 // A file cannot be opened with both FileMode.Append and FileMode.Read, but opening it with
3949 // FileMode.Write would cause an error when writing, as the stream needs to be readable.
4050 Mode = mode == FileMode . Append ? FileMode . Open : mode ,
41- Access = FileAccess . ReadWrite ,
51+
52+ // Writes require read access as well (chunks are read-modify-write), but read-only
53+ // opens must not request write access. Otherwise, files with read-only permissions
54+ // (or vaults on read-only media) could not be opened at all
55+ Access = access == FileAccess . Read ? FileAccess . Read : FileAccess . ReadWrite ,
4256 Share = share | FileShare . Delete ,
4357 Options = options
4458 } ) ;
0 commit comments