From 6aa4beeefb2c2fbb025c5fb97cc74cd799c6622b Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 9 Jun 2018 18:21:32 +0200 Subject: [PATCH 1/1] [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 --- drivers/filesystems/fastfat/dirwr.c | 12 +++++++----- drivers/filesystems/fastfat/fat.c | 23 +++++++++++------------ drivers/filesystems/fastfat/finfo.c | 8 ++------ drivers/filesystems/fastfat/fsctl.c | 1 + drivers/filesystems/fastfat/rw.c | 5 ----- drivers/filesystems/fastfat/vfat.h | 4 +--- 6 files changed, 22 insertions(+), 31 deletions(-) diff --git a/drivers/filesystems/fastfat/dirwr.c b/drivers/filesystems/fastfat/dirwr.c index ac1b7a5549c..b4a2a94b599 100644 --- a/drivers/filesystems/fastfat/dirwr.c +++ b/drivers/filesystems/fastfat/dirwr.c @@ -670,6 +670,11 @@ FATAddEntry( } return STATUS_DISK_FULL; } + + if (DeviceExt->FatInfo.FatType == FAT32) + { + FAT32UpdateFreeClustersCount(DeviceExt); + } } else { @@ -1021,20 +1026,17 @@ 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) + if (DeviceExt->FatInfo.FatType == FAT32) { - FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, TRUE); + FAT32UpdateFreeClustersCount(DeviceExt); } } diff --git a/drivers/filesystems/fastfat/fat.c b/drivers/filesystems/fastfat/fat.c index b291ff2843d..5842091a303 100644 --- a/drivers/filesystems/fastfat/fat.c +++ b/drivers/filesystems/fastfat/fat.c @@ -557,7 +557,10 @@ CountAvailableClusters( else Status = FAT32CountAvailableClusters(DeviceExt); } - Clusters->QuadPart = DeviceExt->AvailableClusters; + if (Clusters != NULL) + { + Clusters->QuadPart = DeviceExt->AvailableClusters; + } ExReleaseResourceLite (&DeviceExt->FatResource); return Status; @@ -1214,9 +1217,7 @@ FAT32SetDirtyStatus( NTSTATUS FAT32UpdateFreeClustersCount( - PDEVICE_EXTENSION DeviceExt, - ULONG Count, - BOOLEAN Freed) + PDEVICE_EXTENSION DeviceExt) { LARGE_INTEGER Offset; ULONG Length; @@ -1227,6 +1228,11 @@ FAT32UpdateFreeClustersCount( #endif struct _FsInfoSector * Sector; + if (!DeviceExt->AvailableClustersValid) + { + return STATUS_INVALID_PARAMETER; + } + /* We'll read (and then write) the fsinfo sector */ Offset.QuadPart = DeviceExt->FatInfo.FSInfoSector * DeviceExt->FatInfo.BytesPerSector; Length = DeviceExt->FatInfo.BytesPerSector; @@ -1275,14 +1281,7 @@ FAT32UpdateFreeClustersCount( } /* Update the free clusters count */ - if (Freed) - { - Sector->FreeCluster += Count; - } - else - { - Sector->FreeCluster -= Count; - } + Sector->FreeCluster = InterlockedCompareExchange((PLONG)&DeviceExt->AvailableClusters, 0, 0); #ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT /* Mark FSINFO sector dirty so that it gets written to the disk */ diff --git a/drivers/filesystems/fastfat/finfo.c b/drivers/filesystems/fastfat/finfo.c index 2840b1369be..517d7381d61 100644 --- a/drivers/filesystems/fastfat/finfo.c +++ b/drivers/filesystems/fastfat/finfo.c @@ -1344,8 +1344,6 @@ 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)) @@ -1393,18 +1391,16 @@ 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) + if (DeviceExt->FatInfo.FatType == FAT32) { - FAT32UpdateFreeClustersCount(DeviceExt, ClusterCount, TRUE); + FAT32UpdateFreeClustersCount(DeviceExt); } } else diff --git a/drivers/filesystems/fastfat/fsctl.c b/drivers/filesystems/fastfat/fsctl.c index 486535d1290..b849bf41194 100644 --- a/drivers/filesystems/fastfat/fsctl.c +++ b/drivers/filesystems/fastfat/fsctl.c @@ -737,6 +737,7 @@ VfatMount( _SEH2_END; DeviceExt->LastAvailableCluster = 2; + CountAvailableClusters(DeviceExt, NULL); ExInitializeResourceLite(&DeviceExt->FatResource); InitializeListHead(&DeviceExt->FcbListHead); diff --git a/drivers/filesystems/fastfat/rw.c b/drivers/filesystems/fastfat/rw.c index d78054eced0..60713e104c4 100644 --- a/drivers/filesystems/fastfat/rw.c +++ b/drivers/filesystems/fastfat/rw.c @@ -540,11 +540,6 @@ VfatWriteFileData( } } - 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 64a96796a0a..bec3dc83941 100644 --- a/drivers/filesystems/fastfat/vfat.h +++ b/drivers/filesystems/fastfat/vfat.h @@ -931,9 +931,7 @@ FAT32SetDirtyStatus( NTSTATUS FAT32UpdateFreeClustersCount( - PDEVICE_EXTENSION DeviceExt, - ULONG Count, - BOOLEAN Freed); + PDEVICE_EXTENSION DeviceExt); /* fcb.c */ -- 2.17.1