[FASTFAT] Only initialize directory cache on use.

This avoids initializing cache directly on directory
open/create.
The advantage is we reduce the load on cache manager
and on memory manager by avoiding creating everytime
a stream file object, and initializing cache for it.

This will avoid initializing cache for started
applications 'current directory' which is just opened
for having a valid handle but no read/write is performed
in it, by default.

This is a step forward for autochk.

CORE-14629
This commit is contained in:
Pierre Schweitzer 2018-05-18 14:03:20 +02:00
parent f20bdf1994
commit 3c3ebe3320
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B
9 changed files with 181 additions and 80 deletions

View file

@ -88,7 +88,7 @@ VfatCleanupFile(
if (BooleanFlagOn(pFcb->Flags, FCB_IS_DIRTY)) if (BooleanFlagOn(pFcb->Flags, FCB_IS_DIRTY))
{ {
VfatUpdateEntry (pFcb, vfatVolumeIsFatX(DeviceExt)); VfatUpdateEntry (DeviceExt, pFcb);
} }
if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) && if (BooleanFlagOn(pFcb->Flags, FCB_DELETE_PENDING) &&

View file

@ -951,7 +951,7 @@ VfatCreateFile(
&pFcb->entry.Fat.UpdateTime); &pFcb->entry.Fat.UpdateTime);
} }
VfatUpdateEntry(pFcb, vfatVolumeIsFatX(DeviceExt)); VfatUpdateEntry(DeviceExt, pFcb);
} }
ExAcquireResourceExclusiveLite(&(pFcb->MainResource), TRUE); ExAcquireResourceExclusiveLite(&(pFcb->MainResource), TRUE);

View file

@ -599,6 +599,7 @@ DoQuery(
DPRINT("Buffer=%p tofind=%wZ\n", Buffer, &pCcb->SearchPattern); DPRINT("Buffer=%p tofind=%wZ\n", Buffer, &pCcb->SearchPattern);
DirContext.DeviceExt = IrpContext->DeviceExt;
DirContext.LongNameU.Buffer = LongNameBuffer; DirContext.LongNameU.Buffer = LongNameBuffer;
DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer); DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
DirContext.ShortNameU.Buffer = ShortNameBuffer; DirContext.ShortNameU.Buffer = ShortNameBuffer;

View file

@ -41,12 +41,14 @@ vfatDirEntryGetFirstCluster(
BOOLEAN BOOLEAN
FATIsDirectoryEmpty( FATIsDirectoryEmpty(
PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb) PVFATFCB Fcb)
{ {
LARGE_INTEGER FileOffset; LARGE_INTEGER FileOffset;
PVOID Context = NULL; PVOID Context = NULL;
PFAT_DIR_ENTRY FatDirEntry; PFAT_DIR_ENTRY FatDirEntry;
ULONG Index, MaxIndex; ULONG Index, MaxIndex;
NTSTATUS Status;
if (vfatFCBIsRoot(Fcb)) if (vfatFCBIsRoot(Fcb))
{ {
@ -60,6 +62,12 @@ FATIsDirectoryEmpty(
FileOffset.QuadPart = 0; FileOffset.QuadPart = 0;
MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FAT_DIR_ENTRY); MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FAT_DIR_ENTRY);
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, Fcb);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
while (Index < MaxIndex) while (Index < MaxIndex)
{ {
if (Context == NULL || (Index % FAT_ENTRIES_PER_PAGE) == 0) if (Context == NULL || (Index % FAT_ENTRIES_PER_PAGE) == 0)
@ -109,16 +117,24 @@ FATIsDirectoryEmpty(
BOOLEAN BOOLEAN
FATXIsDirectoryEmpty( FATXIsDirectoryEmpty(
PDEVICE_EXTENSION DeviceExt,
PVFATFCB Fcb) PVFATFCB Fcb)
{ {
LARGE_INTEGER FileOffset; LARGE_INTEGER FileOffset;
PVOID Context = NULL; PVOID Context = NULL;
PFATX_DIR_ENTRY FatXDirEntry; PFATX_DIR_ENTRY FatXDirEntry;
ULONG Index = 0, MaxIndex; ULONG Index = 0, MaxIndex;
NTSTATUS Status;
FileOffset.QuadPart = 0; FileOffset.QuadPart = 0;
MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FATX_DIR_ENTRY); MaxIndex = Fcb->RFCB.FileSize.u.LowPart / sizeof(FATX_DIR_ENTRY);
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, Fcb);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
while (Index < MaxIndex) while (Index < MaxIndex)
{ {
if (Context == NULL || (Index % FATX_ENTRIES_PER_PAGE) == 0) if (Context == NULL || (Index % FATX_ENTRIES_PER_PAGE) == 0)
@ -186,12 +202,20 @@ FATGetNextDirEntry(
BOOLEAN Valid = TRUE; BOOLEAN Valid = TRUE;
BOOLEAN Back = FALSE; BOOLEAN Back = FALSE;
NTSTATUS Status;
DirContext->LongNameU.Length = 0; DirContext->LongNameU.Length = 0;
DirContext->LongNameU.Buffer[0] = UNICODE_NULL; DirContext->LongNameU.Buffer[0] = UNICODE_NULL;
FileOffset.u.HighPart = 0; FileOffset.u.HighPart = 0;
FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FAT_DIR_ENTRY), PAGE_SIZE); FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FAT_DIR_ENTRY), PAGE_SIZE);
Status = vfatFCBInitializeCacheFromVolume(DirContext->DeviceExt, pDirFcb);
if (!NT_SUCCESS(Status))
{
return Status;
}
if (*pContext == NULL || (DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0) if (*pContext == NULL || (DirContext->DirIndex % FAT_ENTRIES_PER_PAGE) == 0)
{ {
if (*pContext != NULL) if (*pContext != NULL)
@ -461,6 +485,7 @@ FATXGetNextDirEntry(
PFATX_DIR_ENTRY fatxDirEntry; PFATX_DIR_ENTRY fatxDirEntry;
OEM_STRING StringO; OEM_STRING StringO;
ULONG DirIndex = DirContext->DirIndex; ULONG DirIndex = DirContext->DirIndex;
NTSTATUS Status;
FileOffset.u.HighPart = 0; FileOffset.u.HighPart = 0;
@ -498,6 +523,12 @@ FATXGetNextDirEntry(
} }
} }
Status = vfatFCBInitializeCacheFromVolume(DirContext->DeviceExt, pDirFcb);
if (!NT_SUCCESS(Status))
{
return Status;
}
if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0) if (*pContext == NULL || (DirIndex % FATX_ENTRIES_PER_PAGE) == 0)
{ {
if (*pContext != NULL) if (*pContext != NULL)

View file

@ -16,23 +16,105 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#ifdef KDBG
extern UNICODE_STRING DebugFile;
#endif
NTSTATUS
vfatFCBInitializeCacheFromVolume(
PVCB vcb,
PVFATFCB fcb)
{
PFILE_OBJECT fileObject;
PVFATCCB newCCB;
NTSTATUS status;
BOOLEAN Acquired;
/* Don't re-initialize if already done */
if (BooleanFlagOn(fcb->Flags, FCB_CACHE_INITIALIZED))
{
return STATUS_SUCCESS;
}
ASSERT(vfatFCBIsDirectory(fcb));
Acquired = FALSE;
if (!ExIsResourceAcquiredExclusive(&vcb->DirResource))
{
ExAcquireResourceExclusiveLite(&vcb->DirResource, TRUE);
Acquired = TRUE;
}
fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
#ifdef KDBG
if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
{
DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
}
#endif
newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
if (newCCB == NULL)
{
ObDereferenceObject(fileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(newCCB, sizeof (VFATCCB));
fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
fileObject->FsContext = fcb;
fileObject->FsContext2 = newCCB;
fileObject->Vpb = vcb->IoVPB;
fcb->FileObject = fileObject;
_SEH2_TRY
{
CcInitializeCacheMap(fileObject,
(PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize),
TRUE,
&VfatGlobalData->CacheMgrCallbacks,
fcb);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
status = _SEH2_GetExceptionCode();
fcb->FileObject = NULL;
ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, newCCB);
ObDereferenceObject(fileObject);
return status;
}
_SEH2_END;
vfatGrabFCB(vcb, fcb);
SetFlag(fcb->Flags, FCB_CACHE_INITIALIZED);
if (Acquired)
{
ExReleaseResourceLite(&vcb->DirResource);
}
return STATUS_SUCCESS;
}
/* /*
* update an existing FAT entry * update an existing FAT entry
*/ */
NTSTATUS NTSTATUS
VfatUpdateEntry( VfatUpdateEntry(
IN PVFATFCB pFcb, IN PDEVICE_EXTENSION DeviceExt,
IN BOOLEAN IsFatX) IN PVFATFCB pFcb)
{ {
PVOID Context; PVOID Context;
PDIR_ENTRY PinEntry; PDIR_ENTRY PinEntry;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
ULONG SizeDirEntry; ULONG SizeDirEntry;
ULONG dirIndex; ULONG dirIndex;
NTSTATUS Status;
ASSERT(pFcb); ASSERT(pFcb);
if (IsFatX) if (vfatVolumeIsFatX(DeviceExt))
{ {
SizeDirEntry = sizeof(FATX_DIR_ENTRY); SizeDirEntry = sizeof(FATX_DIR_ENTRY);
dirIndex = pFcb->startIndex; dirIndex = pFcb->startIndex;
@ -52,6 +134,12 @@ VfatUpdateEntry(
ASSERT(pFcb->parentFcb); ASSERT(pFcb->parentFcb);
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
if (!NT_SUCCESS(Status))
{
return Status;
}
Offset.u.HighPart = 0; Offset.u.HighPart = 0;
Offset.u.LowPart = dirIndex * SizeDirEntry; Offset.u.LowPart = dirIndex * SizeDirEntry;
_SEH2_TRY _SEH2_TRY
@ -91,6 +179,12 @@ vfatRenameEntry(
DPRINT("vfatRenameEntry(%p, %p, %wZ, %d)\n", DeviceExt, pFcb, FileName, CaseChangeOnly); DPRINT("vfatRenameEntry(%p, %p, %wZ, %d)\n", DeviceExt, pFcb, FileName, CaseChangeOnly);
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
if (!NT_SUCCESS(Status))
{
return Status;
}
if (vfatVolumeIsFatX(DeviceExt)) if (vfatVolumeIsFatX(DeviceExt))
{ {
VFAT_DIRENTRY_CONTEXT DirContext; VFAT_DIRENTRY_CONTEXT DirContext;
@ -120,6 +214,7 @@ vfatRenameEntry(
pDirEntry->FilenameLength = (unsigned char)NameA.Length; pDirEntry->FilenameLength = (unsigned char)NameA.Length;
/* Update FCB */ /* Update FCB */
DirContext.DeviceExt = DeviceExt;
DirContext.ShortNameU.Length = 0; DirContext.ShortNameU.Length = 0;
DirContext.ShortNameU.MaximumLength = 0; DirContext.ShortNameU.MaximumLength = 0;
DirContext.ShortNameU.Buffer = NULL; DirContext.ShortNameU.Buffer = NULL;
@ -169,6 +264,12 @@ vfatFindDirSpace(
else else
SizeDirEntry = sizeof(FAT_DIR_ENTRY); SizeDirEntry = sizeof(FAT_DIR_ENTRY);
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pDirFcb);
if (!NT_SUCCESS(Status))
{
return Status;
}
count = pDirFcb->RFCB.FileSize.u.LowPart / SizeDirEntry; count = pDirFcb->RFCB.FileSize.u.LowPart / SizeDirEntry;
size = DeviceExt->FatInfo.BytesPerCluster / SizeDirEntry; size = DeviceExt->FatInfo.BytesPerCluster / SizeDirEntry;
for (i = 0; i < count; i++, pFatEntry = (PDIR_ENTRY)((ULONG_PTR)pFatEntry + SizeDirEntry)) for (i = 0; i < count; i++, pFatEntry = (PDIR_ENTRY)((ULONG_PTR)pFatEntry + SizeDirEntry))
@ -343,6 +444,7 @@ FATAddEntry(
NameA.Length = 0; NameA.Length = 0;
NameA.MaximumLength = sizeof(aName); NameA.MaximumLength = sizeof(aName);
DirContext.DeviceExt = DeviceExt;
DirContext.ShortNameU.Buffer = ShortNameBuffer; DirContext.ShortNameU.Buffer = ShortNameBuffer;
DirContext.ShortNameU.Length = 0; DirContext.ShortNameU.Length = 0;
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer); DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
@ -359,6 +461,7 @@ FATAddEntry(
needTilde = TRUE; needTilde = TRUE;
needLong = TRUE; needLong = TRUE;
RtlZeroMemory(&NameContext, sizeof(GENERATE_NAME_CONTEXT)); RtlZeroMemory(&NameContext, sizeof(GENERATE_NAME_CONTEXT));
SearchContext.DeviceExt = DeviceExt;
SearchContext.LongNameU.Buffer = LongNameBuffer; SearchContext.LongNameU.Buffer = LongNameBuffer;
SearchContext.LongNameU.MaximumLength = sizeof(LongNameBuffer); SearchContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
SearchContext.ShortNameU.Buffer = ShortSearchName; SearchContext.ShortNameU.Buffer = ShortSearchName;
@ -577,6 +680,8 @@ FATAddEntry(
DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster; DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster;
} }
/* No need to init cache here, vfatFindDirSpace() will have done it for us */
i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FAT_DIR_ENTRY); i = DeviceExt->FatInfo.BytesPerCluster / sizeof(FAT_DIR_ENTRY);
FileOffset.u.HighPart = 0; FileOffset.u.HighPart = 0;
FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FAT_DIR_ENTRY); FileOffset.u.LowPart = DirContext.StartIndex * sizeof(FAT_DIR_ENTRY);
@ -659,6 +764,12 @@ FATAddEntry(
if (IsDirectory) if (IsDirectory)
{ {
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, (*Fcb));
if (!NT_SUCCESS(Status))
{
return Status;
}
FileOffset.QuadPart = 0; FileOffset.QuadPart = 0;
_SEH2_TRY _SEH2_TRY
{ {
@ -741,6 +852,7 @@ FATXAddEntry(
DirContext.ShortNameU.Buffer = 0; DirContext.ShortNameU.Buffer = 0;
DirContext.ShortNameU.Length = 0; DirContext.ShortNameU.Length = 0;
DirContext.ShortNameU.MaximumLength = 0; DirContext.ShortNameU.MaximumLength = 0;
DirContext.DeviceExt = DeviceExt;
RtlZeroMemory(&DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY)); RtlZeroMemory(&DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
memset(DirContext.DirEntry.FatX.Filename, 0xff, 42); memset(DirContext.DirEntry.FatX.Filename, 0xff, 42);
/* Use cluster, if moving */ /* Use cluster, if moving */
@ -784,6 +896,8 @@ FATXAddEntry(
DirContext.DirEntry.FatX.FileSize = MoveContext->FileSize; DirContext.DirEntry.FatX.FileSize = MoveContext->FileSize;
} }
/* No need to init cache here, vfatFindDirSpace() will have done it for us */
/* add entry into parent directory */ /* add entry into parent directory */
FileOffset.u.HighPart = 0; FileOffset.u.HighPart = 0;
FileOffset.u.LowPart = Index * sizeof(FATX_DIR_ENTRY); FileOffset.u.LowPart = Index * sizeof(FATX_DIR_ENTRY);
@ -829,10 +943,17 @@ FATDelEntry(
PVOID Context = NULL; PVOID Context = NULL;
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
PFAT_DIR_ENTRY pDirEntry = NULL; PFAT_DIR_ENTRY pDirEntry = NULL;
NTSTATUS Status;
ASSERT(pFcb); ASSERT(pFcb);
ASSERT(pFcb->parentFcb); ASSERT(pFcb->parentFcb);
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
if (!NT_SUCCESS(Status))
{
return Status;
}
DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU); DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
DPRINT("delete entry: %u to %u\n", pFcb->startIndex, pFcb->dirIndex); DPRINT("delete entry: %u to %u\n", pFcb->startIndex, pFcb->dirIndex);
Offset.u.HighPart = 0; Offset.u.HighPart = 0;
@ -910,6 +1031,7 @@ FATXDelEntry(
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
PFATX_DIR_ENTRY pDirEntry; PFATX_DIR_ENTRY pDirEntry;
ULONG StartIndex; ULONG StartIndex;
NTSTATUS Status;
ASSERT(pFcb); ASSERT(pFcb);
ASSERT(pFcb->parentFcb); ASSERT(pFcb->parentFcb);
@ -917,6 +1039,12 @@ FATXDelEntry(
StartIndex = pFcb->startIndex; StartIndex = pFcb->startIndex;
Status = vfatFCBInitializeCacheFromVolume(DeviceExt, pFcb->parentFcb);
if (!NT_SUCCESS(Status))
{
return Status;
}
DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU); DPRINT("delEntry PathName \'%wZ\'\n", &pFcb->PathNameU);
DPRINT("delete entry: %u\n", StartIndex); DPRINT("delete entry: %u\n", StartIndex);
Offset.u.HighPart = 0; Offset.u.HighPart = 0;
@ -1004,8 +1132,8 @@ VfatMoveEntry(
return Status; return Status;
} }
extern BOOLEAN FATXIsDirectoryEmpty(PVFATFCB Fcb); extern BOOLEAN FATXIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb);
extern BOOLEAN FATIsDirectoryEmpty(PVFATFCB Fcb); extern BOOLEAN FATIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb);
extern NTSTATUS FATGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First); extern NTSTATUS FATGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First);
extern NTSTATUS FATXGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First); extern NTSTATUS FATXGetNextDirEntry(PVOID *pContext, PVOID *pPage, PVFATFCB pDirFcb, PVFAT_DIRENTRY_CONTEXT DirContext, BOOLEAN First);

View file

@ -640,62 +640,6 @@ vfatGrabFCBFromTable(
return NULL; return NULL;
} }
static
NTSTATUS
vfatFCBInitializeCacheFromVolume(
PVCB vcb,
PVFATFCB fcb)
{
PFILE_OBJECT fileObject;
PVFATCCB newCCB;
NTSTATUS status;
fileObject = IoCreateStreamFileObject (NULL, vcb->StorageDevice);
#ifdef KDBG
if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
{
DPRINT1("Attaching %p to %p (%d)\n", fcb, fileObject, fcb->RefCount);
}
#endif
newCCB = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
if (newCCB == NULL)
{
ObDereferenceObject(fileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(newCCB, sizeof (VFATCCB));
fileObject->SectionObjectPointer = &fcb->SectionObjectPointers;
fileObject->FsContext = fcb;
fileObject->FsContext2 = newCCB;
fileObject->Vpb = vcb->IoVPB;
fcb->FileObject = fileObject;
_SEH2_TRY
{
CcInitializeCacheMap(fileObject,
(PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize),
TRUE,
&VfatGlobalData->CacheMgrCallbacks,
fcb);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
status = _SEH2_GetExceptionCode();
fcb->FileObject = NULL;
ExFreeToNPagedLookasideList(&VfatGlobalData->CcbLookasideList, newCCB);
ObDereferenceObject(fileObject);
return status;
}
_SEH2_END;
vfatGrabFCB(vcb, fcb);
SetFlag(fcb->Flags, FCB_CACHE_INITIALIZED);
return STATUS_SUCCESS;
}
PVFATFCB PVFATFCB
vfatMakeRootFCB( vfatMakeRootFCB(
PDEVICE_EXTENSION pVCB) PDEVICE_EXTENSION pVCB)
@ -788,16 +732,6 @@ vfatMakeFCBFromDirEntry(
vfatInitFCBFromDirEntry(vcb, rcFCB, DirContext); vfatInitFCBFromDirEntry(vcb, rcFCB, DirContext);
rcFCB->RefCount = 1; rcFCB->RefCount = 1;
if (vfatFCBIsDirectory(rcFCB))
{
Status = vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
if (!NT_SUCCESS(Status))
{
vfatReleaseFCB(vcb, rcFCB);
ExFreePoolWithTag(NameU.Buffer, TAG_FCB);
return Status;
}
}
rcFCB->parentFcb = directoryFCB; rcFCB->parentFcb = directoryFCB;
InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry); InsertTailList(&directoryFCB->ParentListHead, &rcFCB->ParentListEntry);
vfatAddFCBToTable(vcb, rcFCB); vfatAddFCBToTable(vcb, rcFCB);
@ -880,6 +814,7 @@ vfatDirFindFile(
DirContext.ShortNameU.Buffer = ShortNameBuffer; DirContext.ShortNameU.Buffer = ShortNameBuffer;
DirContext.ShortNameU.Length = 0; DirContext.ShortNameU.Length = 0;
DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer); DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
DirContext.DeviceExt = pDeviceExt;
while (TRUE) while (TRUE)
{ {

View file

@ -265,7 +265,7 @@ VfatSetBasicInformation(
} }
} }
VfatUpdateEntry(FCB, vfatVolumeIsFatX(DeviceExt)); VfatUpdateEntry(DeviceExt, FCB);
if (NotifyFilter != 0) if (NotifyFilter != 0)
{ {
@ -1407,7 +1407,7 @@ VfatSetAllocationSizeInformation(
Fcb->Flags |= FCB_IS_DIRTY; Fcb->Flags |= FCB_IS_DIRTY;
if (AllocSizeChanged) if (AllocSizeChanged)
{ {
VfatUpdateEntry(Fcb, vfatVolumeIsFatX(DeviceExt)); VfatUpdateEntry(DeviceExt, Fcb);
vfatReportChange(DeviceExt, Fcb, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED); vfatReportChange(DeviceExt, Fcb, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
} }

View file

@ -35,7 +35,7 @@ VfatFlushFile(
if (BooleanFlagOn(Fcb->Flags, FCB_IS_DIRTY)) if (BooleanFlagOn(Fcb->Flags, FCB_IS_DIRTY))
{ {
Status = VfatUpdateEntry(Fcb, vfatVolumeIsFatX(DeviceExt)); Status = VfatUpdateEntry(DeviceExt, Fcb);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
IoStatus.Status = Status; IoStatus.Status = Status;

View file

@ -281,7 +281,7 @@ typedef NTSTATUS (*PGET_NEXT_CLUSTER)(PDEVICE_EXTENSION,ULONG,PULONG);
typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG); typedef NTSTATUS (*PFIND_AND_MARK_AVAILABLE_CLUSTER)(PDEVICE_EXTENSION,PULONG);
typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG); typedef NTSTATUS (*PWRITE_CLUSTER)(PDEVICE_EXTENSION,ULONG,ULONG,PULONG);
typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(struct _VFATFCB*); typedef BOOLEAN (*PIS_DIRECTORY_EMPTY)(PDEVICE_EXTENSION,struct _VFATFCB*);
typedef NTSTATUS (*PADD_ENTRY)(PDEVICE_EXTENSION,PUNICODE_STRING,struct _VFATFCB**,struct _VFATFCB*,ULONG,UCHAR,struct _VFAT_MOVE_CONTEXT*); typedef NTSTATUS (*PADD_ENTRY)(PDEVICE_EXTENSION,PUNICODE_STRING,struct _VFATFCB**,struct _VFATFCB*,ULONG,UCHAR,struct _VFAT_MOVE_CONTEXT*);
typedef NTSTATUS (*PDEL_ENTRY)(PDEVICE_EXTENSION,struct _VFATFCB*,struct _VFAT_MOVE_CONTEXT*); typedef NTSTATUS (*PDEL_ENTRY)(PDEVICE_EXTENSION,struct _VFATFCB*,struct _VFAT_MOVE_CONTEXT*);
typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN); typedef NTSTATUS (*PGET_NEXT_DIR_ENTRY)(PVOID*,PVOID*,struct _VFATFCB*,struct _VFAT_DIRENTRY_CONTEXT*,BOOLEAN);
@ -352,7 +352,7 @@ BOOLEAN
VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt, VfatIsDirectoryEmpty(PDEVICE_EXTENSION DeviceExt,
struct _VFATFCB* Fcb) struct _VFATFCB* Fcb)
{ {
return DeviceExt->Dispatch.IsDirectoryEmpty(Fcb); return DeviceExt->Dispatch.IsDirectoryEmpty(DeviceExt, Fcb);
} }
FORCEINLINE FORCEINLINE
@ -570,6 +570,7 @@ typedef struct _VFAT_DIRENTRY_CONTEXT
DIR_ENTRY DirEntry; DIR_ENTRY DirEntry;
UNICODE_STRING LongNameU; UNICODE_STRING LongNameU;
UNICODE_STRING ShortNameU; UNICODE_STRING ShortNameU;
PDEVICE_EXTENSION DeviceExt;
} VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT; } VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
typedef struct _VFAT_MOVE_CONTEXT typedef struct _VFAT_MOVE_CONTEXT
@ -736,10 +737,15 @@ vfatDirEntryGetFirstCluster(
/* dirwr.c */ /* dirwr.c */
NTSTATUS
vfatFCBInitializeCacheFromVolume(
PVCB vcb,
PVFATFCB fcb);
NTSTATUS NTSTATUS
VfatUpdateEntry( VfatUpdateEntry(
PVFATFCB pFcb, IN PDEVICE_EXTENSION DeviceExt,
IN BOOLEAN IsFatX); PVFATFCB pFcb);
BOOLEAN BOOLEAN
vfatFindDirSpace( vfatFindDirSpace(