https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0917c64812c6ed182c8f771309dfc628127eee2d
commit 0917c64812c6ed182c8f771309dfc628127eee2d Author: Pierre Schweitzer <pie...@reactos.org> AuthorDate: Sun Dec 23 11:08:01 2018 +0100 Commit: Pierre Schweitzer <pie...@reactos.org> CommitDate: Sun Dec 23 11:19:14 2018 +0100 [NTOSKRNL] When growing a file, invalid the last VACB so that it can be refreshed This will avoid corruption when a file size is little grown and read afterwards. Up to now, FSD where reading 0es instead of expected data, causing corruption. This fixes MS FastFAT not being able to mount a FAT volume in ReactOS, corrupting the FAT. This also fixes the CcSetFileSizes kmtest tests. This is based on a patch by Thomas Faber. CORE-11819 --- ntoskrnl/cc/fs.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/ntoskrnl/cc/fs.c b/ntoskrnl/cc/fs.c index e31a17b87b..5798f56a91 100644 --- a/ntoskrnl/cc/fs.c +++ b/ntoskrnl/cc/fs.c @@ -301,6 +301,43 @@ CcSetFileSizes ( 0, FALSE); } + else + { + PROS_VACB LastVacb; + + /* + * If file (allocation) size has increased, then we need to check whether + * it just grows in a single VACB (the last one). + * If so, we must mark the VACB as invalid to trigger a read to the + * FSD at the next VACB usage, and thus avoid returning garbage + */ + + /* Check for allocation size and the last VACB */ + if (SharedCacheMap->SectionSize.QuadPart < FileSizes->AllocationSize.QuadPart && + SharedCacheMap->SectionSize.QuadPart % VACB_MAPPING_GRANULARITY) + { + LastVacb = CcRosLookupVacb(SharedCacheMap, + SharedCacheMap->SectionSize.QuadPart); + if (LastVacb != NULL) + { + /* Mark it as invalid */ + CcRosReleaseVacb(SharedCacheMap, LastVacb, LastVacb->Dirty ? LastVacb->Valid : FALSE, FALSE, FALSE); + } + } + + /* Check for file size and the last VACB */ + if (SharedCacheMap->FileSize.QuadPart < FileSizes->FileSize.QuadPart && + SharedCacheMap->FileSize.QuadPart % VACB_MAPPING_GRANULARITY) + { + LastVacb = CcRosLookupVacb(SharedCacheMap, + SharedCacheMap->FileSize.QuadPart); + if (LastVacb != NULL) + { + /* Mark it as invalid */ + CcRosReleaseVacb(SharedCacheMap, LastVacb, LastVacb->Dirty ? LastVacb->Valid : FALSE, FALSE, FALSE); + } + } + } KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldirql); SharedCacheMap->SectionSize = FileSizes->AllocationSize;