[FASTFAT] Use the FastFAT mechanism for counting clusters already implemented

This allows us having more accurate statistics regarding available clusters
count. Even though FastFAT and chkdsk still don't agree!

CORE-3877
This commit is contained in:
Pierre Schweitzer 2018-06-09 18:21:32 +02:00
parent f133d01f20
commit 6aa4beeefb
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
6 changed files with 22 additions and 31 deletions

View file

@ -670,6 +670,11 @@ FATAddEntry(
} }
return STATUS_DISK_FULL; return STATUS_DISK_FULL;
} }
if (DeviceExt->FatInfo.FatType == FAT32)
{
FAT32UpdateFreeClustersCount(DeviceExt);
}
} }
else else
{ {
@ -1021,20 +1026,17 @@ FATDelEntry(
/* In case of moving, don't delete data */ /* In case of moving, don't delete data */
if (MoveContext == NULL) if (MoveContext == NULL)
{ {
ULONG ClusterCount = 0;
while (CurrentCluster && CurrentCluster != 0xffffffff) while (CurrentCluster && CurrentCluster != 0xffffffff)
{ {
GetNextCluster(DeviceExt, CurrentCluster, &NextCluster); GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
/* FIXME: check status */ /* FIXME: check status */
WriteCluster(DeviceExt, CurrentCluster, 0); WriteCluster(DeviceExt, CurrentCluster, 0);
CurrentCluster = NextCluster; CurrentCluster = NextCluster;
ClusterCount++;
} }
if (ClusterCount != 0 && DeviceExt->FatInfo.FatType == FAT32) if (DeviceExt->FatInfo.FatType == FAT32)
{ {
FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, TRUE); FAT32UpdateFreeClustersCount(DeviceExt);
} }
} }

View file

@ -557,7 +557,10 @@ CountAvailableClusters(
else else
Status = FAT32CountAvailableClusters(DeviceExt); Status = FAT32CountAvailableClusters(DeviceExt);
} }
if (Clusters != NULL)
{
Clusters->QuadPart = DeviceExt->AvailableClusters; Clusters->QuadPart = DeviceExt->AvailableClusters;
}
ExReleaseResourceLite (&DeviceExt->FatResource); ExReleaseResourceLite (&DeviceExt->FatResource);
return Status; return Status;
@ -1214,9 +1217,7 @@ FAT32SetDirtyStatus(
NTSTATUS NTSTATUS
FAT32UpdateFreeClustersCount( FAT32UpdateFreeClustersCount(
PDEVICE_EXTENSION DeviceExt, PDEVICE_EXTENSION DeviceExt)
ULONG Count,
BOOLEAN Freed)
{ {
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
ULONG Length; ULONG Length;
@ -1227,6 +1228,11 @@ FAT32UpdateFreeClustersCount(
#endif #endif
struct _FsInfoSector * Sector; struct _FsInfoSector * Sector;
if (!DeviceExt->AvailableClustersValid)
{
return STATUS_INVALID_PARAMETER;
}
/* We'll read (and then write) the fsinfo sector */ /* We'll read (and then write) the fsinfo sector */
Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector; Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector;
Length = DeviceExt->FatInfo.BytesPerSector; Length = DeviceExt->FatInfo.BytesPerSector;
@ -1275,14 +1281,7 @@ FAT32UpdateFreeClustersCount(
} }
/* Update the free clusters count */ /* Update the free clusters count */
if (Freed) Sector->FreeCluster = InterlockedCompareExchange((PLONG)&DeviceExt->AvailableClusters, 0, 0);
{
Sector->FreeCluster += Count;
}
else
{
Sector->FreeCluster -= Count;
}
#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
/* Mark FSINFO sector dirty so that it gets written to the disk */ /* Mark FSINFO sector dirty so that it gets written to the disk */

View file

@ -1344,8 +1344,6 @@ VfatSetAllocationSizeInformation(
} }
else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart) else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
{ {
ULONG ClusterCount;
DPRINT("Check for the ability to set file size\n"); DPRINT("Check for the ability to set file size\n");
if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer, if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
(PLARGE_INTEGER)AllocationSize)) (PLARGE_INTEGER)AllocationSize))
@ -1393,18 +1391,16 @@ VfatSetAllocationSizeInformation(
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
ClusterCount = 0;
while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1) while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster > 1)
{ {
Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE); Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster(DeviceExt, Cluster, 0); WriteCluster(DeviceExt, Cluster, 0);
Cluster = NCluster; Cluster = NCluster;
ClusterCount++;
} }
if (ClusterCount != 0 && DeviceExt->FatInfo.FatType == FAT32) if (DeviceExt->FatInfo.FatType == FAT32)
{ {
FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, TRUE); FAT32UpdateFreeClustersCount(DeviceExt);
} }
} }
else else

View file

@ -737,6 +737,7 @@ VfatMount(
_SEH2_END; _SEH2_END;
DeviceExt->LastAvailableCluster = 2; DeviceExt->LastAvailableCluster = 2;
CountAvailableClusters(DeviceExt, NULL);
ExInitializeResourceLite(&DeviceExt->FatResource); ExInitializeResourceLite(&DeviceExt->FatResource);
InitializeListHead(&DeviceExt->FcbListHead); InitializeListHead(&DeviceExt->FcbListHead);

View file

@ -540,11 +540,6 @@ VfatWriteFileData(
} }
} }
if (NT_SUCCESS(Status) && ClusterCount != 0 && DeviceExt->FatInfo.FatType == FAT32)
{
FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, FALSE);
}
return Status; return Status;
} }

View file

@ -931,9 +931,7 @@ FAT32SetDirtyStatus(
NTSTATUS NTSTATUS
FAT32UpdateFreeClustersCount( FAT32UpdateFreeClustersCount(
PDEVICE_EXTENSION DeviceExt, PDEVICE_EXTENSION DeviceExt);
ULONG Count,
BOOLEAN Freed);
/* fcb.c */ /* fcb.c */