reactos/drivers/filesystems/fastfat/kdbg.c
Pierre Schweitzer 50b00f0fcc
[FASTFAT] Implement delayed close
When we're about to close a file (ie, forget everything about it
and release any associated structure), actually delay it.
This allows keep data fresh in memory for faster reuse in case
it would be required. The effective closing will only happen after some time.

For specific operations, this will produce a real speed up in ReactOS.
For instance, with that patch, Winamp starts within seconds, instead of dozen
of minutes.
In most cases, it will bring ReactOS to performances it had before fixing
the huge leak in FastFAT (commit 94ead99) without leaking the whole FS.

For now, due to regressions, this is only activated for files and not
for directories. Once it gets fixed, it will be enabled for both.

CORE-14826
CORE-14917
2018-08-18 19:03:30 +02:00

163 lines
4.4 KiB
C

/*
* FILE: drivers/filesystems/fastfat/kdbg.c
* PURPOSE: KDBG extension.
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PROGRAMMER: Pierre Schweitzer (pierre@reactos.org)
*/
/* ------------------------------------------------------- INCLUDES */
#include "vfat.h"
#define NDEBUG
#include <debug.h>
#include <stdio.h>
/* -------------------------------------------------------- DEFINES */
#ifdef KDBG
UNICODE_STRING DebugFile = {0, 0, NULL};
BOOLEAN
NTAPI
vfatKdbgHandler(
IN PCHAR Command,
IN ULONG Argc,
IN PCH Argv[])
{
ULONG Len;
Len = strlen(Command);
if (Len < sizeof("?fat."))
{
return FALSE;
}
if (Command[0] != '?' || Command[1] != 'f' ||
Command[2] != 'a' || Command[3] != 't' ||
Command[4] != '.')
{
return FALSE;
}
Command += (sizeof("?fat.") - sizeof(ANSI_NULL));
if (strcmp(Command, "vols") == 0)
{
ULONG Count = 0;
PLIST_ENTRY ListEntry;
PDEVICE_EXTENSION DeviceExt;
for (ListEntry = VfatGlobalData->VolumeListHead.Flink;
ListEntry != &VfatGlobalData->VolumeListHead;
ListEntry = ListEntry->Flink)
{
DeviceExt = CONTAINING_RECORD(ListEntry, DEVICE_EXTENSION, VolumeListEntry);
DPRINT1("Volume: %p with VCB: %p\n", DeviceExt->VolumeDevice, DeviceExt);
++Count;
}
if (Count == 0)
{
DPRINT1("No volume found\n");
}
}
else if (strcmp(Command, "files") == 0)
{
if (Argc != 2)
{
DPRINT1("Please provide a volume or a VCB!\n");
}
else
{
PLIST_ENTRY ListEntry;
PDEVICE_EXTENSION DeviceExt;
for (ListEntry = VfatGlobalData->VolumeListHead.Flink;
ListEntry != &VfatGlobalData->VolumeListHead;
ListEntry = ListEntry->Flink)
{
CHAR Volume[17];
DeviceExt = CONTAINING_RECORD(ListEntry, DEVICE_EXTENSION, VolumeListEntry);
sprintf(Volume, "%p", DeviceExt);
if (strcmp(Volume, Argv[1]) == 0)
{
break;
}
sprintf(Volume, "%p", DeviceExt->VolumeDevice);
if (strcmp(Volume, Argv[1]) == 0)
{
break;
}
DeviceExt = NULL;
}
if (DeviceExt == NULL)
{
DPRINT1("No volume %s found!\n", Argv[1]);
}
else
{
PVFATFCB Fcb;
for (ListEntry = DeviceExt->FcbListHead.Flink;
ListEntry != &DeviceExt->FcbListHead;
ListEntry = ListEntry->Flink)
{
Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
DPRINT1("FCB %p (ref: %d, oc: %d %s %s %s) for FO %p with path: %.*S\n",
Fcb, Fcb->RefCount, Fcb->OpenHandleCount,
((Fcb->Flags & FCB_CLEANED_UP) ? "U" : "NU"),
((Fcb->Flags & FCB_CLOSED) ? "C" : "NC"),
((Fcb->Flags & FCB_DELAYED_CLOSE) ? "D" : "ND"),
Fcb->FileObject, Fcb->PathNameU.Length, Fcb->PathNameU.Buffer);
}
}
}
}
else if (strcmp(Command, "setdbgfile") == 0)
{
if (Argc < 2)
{
if (DebugFile.Buffer != NULL)
{
ExFreePool(DebugFile.Buffer);
DebugFile.Length = 0;
DebugFile.MaximumLength = 0;
}
DPRINT1("Debug file reset\n");
}
else
{
NTSTATUS Status;
ANSI_STRING Source;
if (DebugFile.Buffer != NULL)
{
ExFreePool(DebugFile.Buffer);
DebugFile.Length = 0;
DebugFile.MaximumLength = 0;
}
RtlInitAnsiString(&Source, Argv[1]);
Status = RtlAnsiStringToUnicodeString(&DebugFile, &Source, TRUE);
if (NT_SUCCESS(Status))
{
DPRINT1("Debug file set to: %.*S\n", DebugFile.Length, DebugFile.Buffer);
}
}
}
else
{
DPRINT1("Unknown command: %s\n", Command);
}
return TRUE;
}
#endif