@@ -494,7 +494,8 @@ typedef struct _MEMFS
494494 // memefs: Counter to track allocated memory
495495 volatile UINT64 AllocatedSectors;
496496 volatile UINT64 AllocatedSizesToBeDeleted;
497- std::map<MEMFS_FILE_NODE *, UINT64 >* ToBeDeletedFileNodeSizes;
497+ std::unordered_map<MEMFS_FILE_NODE *, UINT64 >* ToBeDeletedFileNodeSizes;
498+ std::mutex* ToBeDeletedFileNodeSizesMutex;
498499 // memefs: MaxFsSize instead of max. file nodes and individual limits
499500 UINT64 MaxFsSize;
500501 UINT64 CachedMaxFsSize;
@@ -516,7 +517,7 @@ static MEMFS* GlobalMemfs = 0;
516517// memefs: Get the all file sizes and the node map size
517518static inline
518519UINT64 MemefsGetUsedTotalSize (MEMFS * Memfs) {
519- const ULONG nodeMapSize = (ULONG )Memfs->FileNodeMap ->size () * (sizeof (PWSTR ) * MEMFS_MAX_PATH + sizeof (MEMFS_FILE_NODE ) + sizeof (std::mutex));
520+ const ULONG nodeMapSize = (ULONG )Memfs->FileNodeMap ->size () * (sizeof (PWSTR ) * MEMFS_MAX_PATH + sizeof (MEMFS_FILE_NODE ) + sizeof (std::mutex) + sizeof (std::mutex*) );
520521 // EA node map is ignored, because it is insignificant
521522
522523 const SIZE_T sectorSizes = Memfs->AllocatedSectors * (sizeof (MEMEFS_SECTOR ) + sizeof (MEMEFS_SECTOR *));
@@ -583,7 +584,7 @@ BOOL MemefsIsFullyEmpty(MEMFS* Memfs)
583584 }
584585 */
585586
586- return InterlockedExchangeAdd (&Memfs->AllocatedSectors , 0ULL ) == 0 ;
587+ return InterlockedExchangeAdd (&Memfs->AllocatedSectors , 0ULL ) == 0 ;
587588}
588589
589590static inline
@@ -641,14 +642,16 @@ VOID MemfsFileNodeDelete(MEMFS_FILE_NODE* FileNode)
641642#endif
642643
643644 // memefs: SectorFree
644- SectorFree (&FileNode->FileDataSectors , FileNode->FileDataSectorsMutex , &GlobalMemfs->AllocatedSectors );
645-
646645 const auto mapIterator = GlobalMemfs->ToBeDeletedFileNodeSizes ->find (FileNode);
647646 if (mapIterator != GlobalMemfs->ToBeDeletedFileNodeSizes ->end ()) {
648- GlobalMemfs->AllocatedSizesToBeDeleted -= mapIterator->second ;
649- GlobalMemfs->ToBeDeletedFileNodeSizes ->erase (mapIterator->first );
647+ InterlockedExchangeSubtract (&GlobalMemfs->AllocatedSizesToBeDeleted , mapIterator->second );
648+
649+ std::unique_lock writeLock (*GlobalMemfs->ToBeDeletedFileNodeSizesMutex );
650+ GlobalMemfs->ToBeDeletedFileNodeSizes ->erase (mapIterator->first ); // TODO: Thread safe map
650651 }
651652
653+ SectorFree (&FileNode->FileDataSectors , FileNode->FileDataSectorsMutex , &GlobalMemfs->AllocatedSectors );
654+
652655 FileNode->FileDataSectors .~vector ();
653656 delete FileNode->FileDataSectorsMutex ;
654657
@@ -966,7 +969,10 @@ VOID MemfsFileNodeMapRemove(MEMFS_FILE_NODE_MAP* FileNodeMap, MEMFS_FILE_NODE* F
966969 if (ReportDeletedSize)
967970 {
968971 const UINT64 toBeDeletedSizes = FileNode->FileDataSectors .size () * (sizeof (MEMEFS_SECTOR ) + sizeof (MEMEFS_SECTOR *));
969- GlobalMemfs->AllocatedSizesToBeDeleted += toBeDeletedSizes;
972+
973+ InterlockedExchangeAdd (&GlobalMemfs->AllocatedSizesToBeDeleted , toBeDeletedSizes);
974+
975+ std::unique_lock writeLock (*GlobalMemfs->ToBeDeletedFileNodeSizesMutex );
970976 GlobalMemfs->ToBeDeletedFileNodeSizes ->insert_or_assign (FileNode, toBeDeletedSizes);
971977 }
972978
@@ -1267,12 +1273,11 @@ static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM* FileSystem,
12671273{
12681274 MEMFS * Memfs = (MEMFS *)FileSystem->UserContext ;
12691275
1270- const UINT64 toBeDeletedSize = Memfs->AllocatedSizesToBeDeleted ;
1276+ const UINT64 toBeDeletedSize = InterlockedExchangeAdd (& Memfs->AllocatedSizesToBeDeleted , 0ULL ) ;
12711277 const UINT64 maxSize = MemefsGetMaxTotalSize (Memfs);
1272- const UINT64 usedSize = MemefsGetUsedTotalSize (Memfs) - toBeDeletedSize;
12731278 const UINT64 availableSize = MemefsGetAvailableTotalSize (Memfs) + toBeDeletedSize;
12741279
1275- VolumeInfo->TotalSize = max ( maxSize, usedSize) ;
1280+ VolumeInfo->TotalSize = maxSize;
12761281 VolumeInfo->FreeSize = availableSize;
12771282 VolumeInfo->VolumeLabelLength = Memfs->VolumeLabelLength ;
12781283 memcpy (VolumeInfo->VolumeLabel , Memfs->VolumeLabel , Memfs->VolumeLabelLength );
@@ -2670,7 +2675,8 @@ NTSTATUS MemfsCreateFunnel(
26702675 }
26712676
26722677 // memefs: New ToBeDeletedFileNodeSizes
2673- Memfs->ToBeDeletedFileNodeSizes = new std::map<MEMFS_FILE_NODE *, UINT64 >();
2678+ Memfs->ToBeDeletedFileNodeSizes = new std::unordered_map<MEMFS_FILE_NODE *, UINT64 >();
2679+ Memfs->ToBeDeletedFileNodeSizesMutex = new std::mutex ();
26742680
26752681 memset (&VolumeParams, 0 , sizeof VolumeParams);
26762682 VolumeParams.Version = sizeof FSP_FSCTL_VOLUME_PARAMS ;
@@ -2717,6 +2723,7 @@ NTSTATUS MemfsCreateFunnel(
27172723 {
27182724 MemfsFileNodeMapDelete (Memfs->FileNodeMap );
27192725 delete Memfs->ToBeDeletedFileNodeSizes ;
2726+ delete Memfs->ToBeDeletedFileNodeSizesMutex ;
27202727 free (Memfs);
27212728 LocalFree (RootSecurity);
27222729 return Result;
@@ -2786,6 +2793,7 @@ VOID MemfsDelete(MEMFS* Memfs)
27862793
27872794 MemfsFileNodeMapDelete (Memfs->FileNodeMap );
27882795 delete Memfs->ToBeDeletedFileNodeSizes ;
2796+ delete Memfs->ToBeDeletedFileNodeSizesMutex ;
27892797
27902798 free (Memfs);
27912799}
0 commit comments