[FASTFAT]
authorPierre Schweitzer <pierre@reactos.org>
Sun, 24 Sep 2017 08:56:06 +0000 (08:56 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sun, 24 Sep 2017 08:56:06 +0000 (08:56 +0000)
Start implementing statistics support. So far, everything is just nulled.
These 0 can be properly queried with fsutil fsinfo statistics.

svn path=/trunk/; revision=75937

reactos/drivers/filesystems/fastfat/fsctl.c
reactos/drivers/filesystems/fastfat/iface.c
reactos/drivers/filesystems/fastfat/vfat.h

index ef0a137..a406276 100644 (file)
@@ -532,6 +532,7 @@ VfatMount(
     UNICODE_STRING VolumeLabelU;
     ULONG HashTableSize;
     ULONG eocMark;
+    ULONG i;
     FATINFO FatInfo;
 
     DPRINT("VfatMount(IrpContext %p)\n", IrpContext);
@@ -669,6 +670,23 @@ VfatMount(
         goto ByeBye;
     }
 
+    DeviceExt->Statistics = ExAllocatePoolWithTag(NonPagedPool,
+                                                  sizeof(STATISTICS) * VfatGlobalData->NumberProcessors,
+                                                  TAG_VFAT);
+    if (DeviceExt->Statistics == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto ByeBye;
+    }
+
+    RtlZeroMemory(DeviceExt->Statistics, sizeof(STATISTICS) * VfatGlobalData->NumberProcessors);
+    for (i = 0; i < VfatGlobalData->NumberProcessors; ++i)
+    {
+        DeviceExt->Statistics[i].Base.FileSystemType = FILESYSTEM_STATISTICS_TYPE_FAT;
+        DeviceExt->Statistics[i].Base.Version = 1;
+        DeviceExt->Statistics[i].Base.SizeOfCompleteStructure = sizeof(STATISTICS);
+    }
+
     DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
     Fcb = vfatNewFCB(DeviceExt, &NameU);
     if (Fcb == NULL)
@@ -776,6 +794,8 @@ ByeBye:
             ObDereferenceObject (DeviceExt->FATFileObject);
         if (DeviceExt && DeviceExt->SpareVPB)
             ExFreePoolWithTag(DeviceExt->SpareVPB, TAG_VFAT);
+        if (DeviceExt && DeviceExt->Statistics)
+            ExFreePoolWithTag(DeviceExt->Statistics, TAG_VFAT);
         if (Fcb)
             vfatDestroyFCB(Fcb);
         if (Ccb)
@@ -1188,6 +1208,46 @@ VfatDismountVolume(
     return STATUS_SUCCESS;
 }
 
+static
+NTSTATUS
+VfatGetStatistics(
+    PVFAT_IRP_CONTEXT IrpContext)
+{
+    PVOID Buffer;
+    ULONG Length;
+    NTSTATUS Status;
+    PDEVICE_EXTENSION DeviceExt;
+
+    DeviceExt = IrpContext->DeviceExt;
+    Length = IrpContext->Stack->Parameters.FileSystemControl.OutputBufferLength;
+    Buffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
+
+    if (Length < sizeof(FILESYSTEM_STATISTICS))
+    {
+        return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    if (Buffer == NULL)
+    {
+        return STATUS_INVALID_USER_BUFFER;
+    }
+
+    if (Length >= sizeof(STATISTICS) * VfatGlobalData->NumberProcessors)
+    {
+        Length = sizeof(STATISTICS) * VfatGlobalData->NumberProcessors;
+        Status = STATUS_SUCCESS;
+    }
+    else
+    {
+        Status = STATUS_BUFFER_OVERFLOW;
+    }
+
+    RtlCopyMemory(Buffer, DeviceExt->Statistics, Length);
+    IrpContext->Irp->IoStatus.Information = Length;
+
+    return Status;
+}
+
 /*
  * FUNCTION: File system control
  */
@@ -1243,6 +1303,10 @@ VfatFileSystemControl(
                     Status = VfatDismountVolume(IrpContext);
                     break;
 
+                case FSCTL_FILESYSTEM_GET_STATISTICS:
+                    Status = VfatGetStatistics(IrpContext);
+                    break;
+
                 default:
                     Status = STATUS_INVALID_DEVICE_REQUEST;
             }
index 8d56448..c334a95 100644 (file)
@@ -91,6 +91,7 @@ DriverEntry(
     RtlZeroMemory (VfatGlobalData, sizeof(VFAT_GLOBAL_DATA));
     VfatGlobalData->DriverObject = DriverObject;
     VfatGlobalData->DeviceObject = DeviceObject;
+    VfatGlobalData->NumberProcessors = KeNumberProcessors;
     /* Enable this to enter the debugger when file system corruption
      * has been detected:
     VfatGlobalData->Flags = VFAT_BREAK_ON_CORRUPTION; */
index 55ac7dc..97dd924 100644 (file)
@@ -289,6 +289,13 @@ typedef struct _VFAT_DISPATCH
     PGET_NEXT_DIR_ENTRY GetNextDirEntry;
 } VFAT_DISPATCH, *PVFAT_DISPATCH;
 
+#define STATISTICS_SIZE_NO_PAD (sizeof(FILESYSTEM_STATISTICS) + sizeof(FAT_STATISTICS))
+typedef struct _STATISTICS {
+    FILESYSTEM_STATISTICS Base;
+    FAT_STATISTICS Fat;
+    UCHAR Pad[((STATISTICS_SIZE_NO_PAD + 0x3f) & ~0x3f) - STATISTICS_SIZE_NO_PAD];
+} STATISTICS, *PSTATISTICS;
+
 typedef struct DEVICE_EXTENSION
 {
     ERESOURCE DirResource;
@@ -308,6 +315,7 @@ typedef struct DEVICE_EXTENSION
     BOOLEAN AvailableClustersValid;
     ULONG Flags;
     struct _VFATFCB *VolumeFcb;
+    PSTATISTICS Statistics;
 
     /* Pointers to functions for manipulating FAT. */
     PGET_NEXT_CLUSTER GetNextCluster;
@@ -383,6 +391,7 @@ typedef struct
     PDRIVER_OBJECT DriverObject;
     PDEVICE_OBJECT DeviceObject;
     ULONG Flags;
+    ULONG NumberProcessors;
     ERESOURCE VolumeListLock;
     LIST_ENTRY VolumeListHead;
     NPAGED_LOOKASIDE_LIST FcbLookasideList;