https://git.reactos.org/?p=reactos.git;a=commitdiff;h=704baed2df04470ab134c…
commit 704baed2df04470ab134cef207847764e3d95e2e
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sat Jun 9 12:36:43 2018 +0200
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Sat Jun 9 12:36:43 2018 +0200
[FASTFAT] Start implementing FAT32 statistics support
Not fully perfect yet, chkdsk still complains.
CORE-3877
---
drivers/filesystems/fastfat/dirwr.c | 8 ++++
drivers/filesystems/fastfat/fat.c | 85 +++++++++++++++++++++++++++++++++++++
drivers/filesystems/fastfat/finfo.c | 9 ++++
drivers/filesystems/fastfat/rw.c | 6 +++
drivers/filesystems/fastfat/vfat.h | 6 +++
5 files changed, 114 insertions(+)
diff --git a/drivers/filesystems/fastfat/dirwr.c b/drivers/filesystems/fastfat/dirwr.c
index ab5d9b3ee4..ac1b7a5549 100644
--- a/drivers/filesystems/fastfat/dirwr.c
+++ b/drivers/filesystems/fastfat/dirwr.c
@@ -1021,12 +1021,20 @@ FATDelEntry(
/* In case of moving, don't delete data */
if (MoveContext == NULL)
{
+ ULONG ClusterCount = 0;
+
while (CurrentCluster && CurrentCluster != 0xffffffff)
{
GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
/* FIXME: check status */
WriteCluster(DeviceExt, CurrentCluster, 0);
CurrentCluster = NextCluster;
+ ClusterCount++;
+ }
+
+ if (ClusterCount != 0 && DeviceExt->FatInfo.FatType == FAT32)
+ {
+ FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, TRUE);
}
}
diff --git a/drivers/filesystems/fastfat/fat.c b/drivers/filesystems/fastfat/fat.c
index 95ef6958d5..b291ff2843 100644
--- a/drivers/filesystems/fastfat/fat.c
+++ b/drivers/filesystems/fastfat/fat.c
@@ -1212,4 +1212,89 @@ FAT32SetDirtyStatus(
#endif
}
+NTSTATUS
+FAT32UpdateFreeClustersCount(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG Count,
+ BOOLEAN Freed)
+{
+ LARGE_INTEGER Offset;
+ ULONG Length;
+#ifdef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ NTSTATUS Status;
+#else
+ PVOID Context;
+#endif
+ struct _FsInfoSector * Sector;
+
+ /* We'll read (and then write) the fsinfo sector */
+ Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector *
DeviceExt->FatInfo.BytesPerSector;
+ Length = DeviceExt->FatInfo.BytesPerSector;
+#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ /* Go through Cc for this */
+ _SEH2_TRY
+ {
+ CcPinRead(DeviceExt->VolumeFcb->FileObject, &Offset, Length, PIN_WAIT,
&Context, (PVOID *)&Sector);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+#else
+ /* No Cc, do it the old way:
+ * - Allocate a big enough buffer
+ * - And read the disk
+ */
+ Sector = ExAllocatePoolWithTag(NonPagedPool, Length, TAG_VFAT);
+ if (Sector == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = VfatReadDisk(DeviceExt->StorageDevice, &Offset, Length,
(PUCHAR)Sector, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Sector, TAG_VFAT);
+ return Status;
+ }
+#endif
+
+ /* Make sure we have a FSINFO sector */
+ if (Sector->ExtBootSignature2 != 0x41615252 ||
+ Sector->FSINFOSignature != 0x61417272 ||
+ Sector->Signatur2 != 0xaa550000)
+ {
+ ASSERT(FALSE);
+#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ CcUnpinData(Context);
+#else
+ ExFreePoolWithTag(Sector, TAG_VFAT);
+#endif
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+
+ /* Update the free clusters count */
+ if (Freed)
+ {
+ Sector->FreeCluster += Count;
+ }
+ else
+ {
+ Sector->FreeCluster -= Count;
+ }
+
+#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ /* Mark FSINFO sector dirty so that it gets written to the disk */
+ CcSetDirtyPinnedData(Context, NULL);
+ CcUnpinData(Context);
+ return STATUS_SUCCESS;
+#else
+ /* Write back the FSINFO sector to the disk */
+ Status = VfatWriteDisk(DeviceExt->StorageDevice, &Offset, Length,
(PUCHAR)Sector, FALSE);
+ ExFreePoolWithTag(Sector, TAG_VFAT);
+ return Status;
+#endif
+}
+
/* EOF */
diff --git a/drivers/filesystems/fastfat/finfo.c b/drivers/filesystems/fastfat/finfo.c
index af2e1ce62a..2840b1369b 100644
--- a/drivers/filesystems/fastfat/finfo.c
+++ b/drivers/filesystems/fastfat/finfo.c
@@ -1344,6 +1344,8 @@ VfatSetAllocationSizeInformation(
}
else if (NewSize + ClusterSize <= Fcb->RFCB.AllocationSize.u.LowPart)
{
+ ULONG ClusterCount;
+
DPRINT("Check for the ability to set file size\n");
if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
(PLARGE_INTEGER)AllocationSize))
@@ -1391,11 +1393,18 @@ VfatSetAllocationSizeInformation(
Status = STATUS_SUCCESS;
}
+ ClusterCount = 0;
while (NT_SUCCESS(Status) && 0xffffffff != Cluster && Cluster
> 1)
{
Status = NextCluster(DeviceExt, FirstCluster, &NCluster, FALSE);
WriteCluster(DeviceExt, Cluster, 0);
Cluster = NCluster;
+ ClusterCount++;
+ }
+
+ if (ClusterCount != 0 && DeviceExt->FatInfo.FatType == FAT32)
+ {
+ FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, TRUE);
}
}
else
diff --git a/drivers/filesystems/fastfat/rw.c b/drivers/filesystems/fastfat/rw.c
index 043bafef6c..d78054eced 100644
--- a/drivers/filesystems/fastfat/rw.c
+++ b/drivers/filesystems/fastfat/rw.c
@@ -539,6 +539,12 @@ VfatWriteFileData(
Status = IrpContext->Irp->IoStatus.Status;
}
}
+
+ if (NT_SUCCESS(Status) && ClusterCount != 0 &&
DeviceExt->FatInfo.FatType == FAT32)
+ {
+ FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, FALSE);
+ }
+
return Status;
}
diff --git a/drivers/filesystems/fastfat/vfat.h b/drivers/filesystems/fastfat/vfat.h
index fcb22b9c5a..64a96796a0 100644
--- a/drivers/filesystems/fastfat/vfat.h
+++ b/drivers/filesystems/fastfat/vfat.h
@@ -929,6 +929,12 @@ FAT32SetDirtyStatus(
PDEVICE_EXTENSION DeviceExt,
BOOLEAN DirtyStatus);
+NTSTATUS
+FAT32UpdateFreeClustersCount(
+ PDEVICE_EXTENSION DeviceExt,
+ ULONG Count,
+ BOOLEAN Freed);
+
/* fcb.c */
PVFATFCB