2008-03-09 14:11:42 +00:00
|
|
|
/*
|
2001-10-10 21:49:15 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/cc/pin.c
|
|
|
|
* PURPOSE: Implements cache managers pinning interface
|
2005-01-26 13:58:37 +00:00
|
|
|
*
|
2007-10-19 23:21:45 +00:00
|
|
|
* PROGRAMMERS:
|
2001-10-10 21:49:15 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
2001-10-10 21:49:15 +00:00
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
2001-10-10 21:49:15 +00:00
|
|
|
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
2003-01-11 15:22:31 +00:00
|
|
|
extern NPAGED_LOOKASIDE_LIST iBcbLookasideList;
|
2001-10-10 21:49:15 +00:00
|
|
|
|
2003-01-11 15:22:31 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
2001-10-10 21:49:15 +00:00
|
|
|
|
2003-07-10 06:27:13 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2010-12-28 14:49:53 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
CcMapData(
|
|
|
|
IN PFILE_OBJECT FileObject,
|
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN ULONG Flags,
|
|
|
|
OUT PVOID *pBcb,
|
|
|
|
OUT PVOID *pBuffer)
|
2001-10-10 21:49:15 +00:00
|
|
|
{
|
2010-12-28 14:49:53 +00:00
|
|
|
ULONG ReadOffset;
|
|
|
|
BOOLEAN Valid;
|
|
|
|
PBCB Bcb;
|
|
|
|
PCACHE_SEGMENT CacheSeg;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PINTERNAL_BCB iBcb;
|
|
|
|
ULONG ROffset;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2010-12-28 14:49:53 +00:00
|
|
|
DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %d, Flags %d,"
|
|
|
|
" pBcb 0x%p, pBuffer 0x%p)\n", FileObject, FileOffset->QuadPart,
|
|
|
|
Length, Flags, pBcb, pBuffer);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2010-12-28 14:49:53 +00:00
|
|
|
ReadOffset = (ULONG)FileOffset->QuadPart;
|
2008-01-19 17:24:52 +00:00
|
|
|
|
2010-12-28 14:49:53 +00:00
|
|
|
ASSERT(FileObject);
|
|
|
|
ASSERT(FileObject->SectionObjectPointer);
|
|
|
|
ASSERT(FileObject->SectionObjectPointer->SharedCacheMap);
|
2008-01-19 17:24:52 +00:00
|
|
|
|
2010-12-28 14:49:53 +00:00
|
|
|
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
|
|
|
ASSERT(Bcb);
|
2002-12-15 Casper S. Hornstrup <chorns@users.sourceforge.net>
* drivers/fs/vfat/cleanup.c (VfatCleanupFile): Only uninitialize caching
when initialized.
* drivers/fs/vfat/fcb.c (vfatReleaseFCB): Ditto.
* lib/kernel32/mem/section.c (CreateFileMappingW): Pass NULL as
MaximumSize to NtCreateSection if dwMaximumSizeHigh and dwMaximumSizeLow
are both 0.
* ntoskrnl/cc/pin.c (CcMapData): Assert if Bcb is NULL.
* ntoskrnl/cc/view.c (CcRosReleaseCacheSegment, CcRosLookupCacheSegment,
CcRosMarkDirtyCacheSegment, CcRosUnmapCacheSegment,
CcRosCreateCacheSegment, CcRosGetCacheSegmentChain,
CcRosGetCacheSegment, CcRosRequestCacheSegment, CcFlushCache,
CcRosDeleteFileCache, CcRosReferenceCache, CcRosDereferenceCache,
CcRosReleaseFileCache, CcGetFileObjectFromSectionPtrs): Ditto.
* ntoskrnl/mm/section.c (MiReadPage): Assert if Fcb->Bcb is NULL.
(MmCreateDataFileSection): Make sure caching is initialized for the file
stream.
svn path=/trunk/; revision=3879
2002-12-15 17:01:52 +00:00
|
|
|
|
2010-12-28 14:49:53 +00:00
|
|
|
DPRINT("AllocationSize %I64x, FileSize %I64x\n",
|
|
|
|
Bcb->AllocationSize.QuadPart,
|
|
|
|
Bcb->FileSize.QuadPart);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2010-12-28 14:49:53 +00:00
|
|
|
if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2010-12-28 14:49:53 +00:00
|
|
|
return FALSE;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2010-12-28 14:49:53 +00:00
|
|
|
ROffset = ROUND_DOWN (ReadOffset, Bcb->CacheSegmentSize);
|
|
|
|
Status = CcRosRequestCacheSegment(Bcb, ROffset,
|
|
|
|
pBuffer, &Valid,
|
|
|
|
&CacheSeg);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2010-12-28 14:49:53 +00:00
|
|
|
return FALSE;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2010-12-28 14:49:53 +00:00
|
|
|
if (!Valid)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2010-12-28 14:49:53 +00:00
|
|
|
if (!(Flags & MAP_WAIT))
|
|
|
|
{
|
|
|
|
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
|
|
|
|
{
|
|
|
|
CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2005-07-05 00:57:47 +00:00
|
|
|
|
2010-12-28 14:49:53 +00:00
|
|
|
*pBuffer = (PVOID)((ULONG_PTR)(*pBuffer) + (ReadOffset % Bcb->CacheSegmentSize));
|
|
|
|
iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
|
|
|
|
if (iBcb == NULL)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2010-12-28 14:49:53 +00:00
|
|
|
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
|
|
|
|
return FALSE;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2010-12-28 14:49:53 +00:00
|
|
|
memset(iBcb, 0, sizeof(INTERNAL_BCB));
|
|
|
|
iBcb->PFCB.NodeTypeCode = 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
|
|
|
|
iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB);
|
|
|
|
iBcb->PFCB.MappedLength = Length;
|
|
|
|
iBcb->PFCB.MappedFileOffset = *FileOffset;
|
|
|
|
iBcb->CacheSegment = CacheSeg;
|
|
|
|
iBcb->Dirty = FALSE;
|
|
|
|
iBcb->RefCount = 1;
|
|
|
|
*pBcb = (PVOID)iBcb;
|
|
|
|
return TRUE;
|
2001-10-10 21:49:15 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 06:27:13 +00:00
|
|
|
/*
|
2004-06-21 04:11:44 +00:00
|
|
|
* @unimplemented
|
2003-07-10 06:27:13 +00:00
|
|
|
*/
|
2004-06-21 04:11:44 +00:00
|
|
|
BOOLEAN
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2004-06-21 04:11:44 +00:00
|
|
|
CcPinMappedData (
|
|
|
|
IN PFILE_OBJECT FileObject,
|
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
2005-01-01 01:51:05 +00:00
|
|
|
IN ULONG Flags,
|
2004-06-21 04:11:44 +00:00
|
|
|
OUT PVOID * Bcb
|
|
|
|
)
|
2001-10-10 21:49:15 +00:00
|
|
|
{
|
2004-08-25 15:08:29 +00:00
|
|
|
/* no-op for current implementation. */
|
|
|
|
return TRUE;
|
2004-06-21 04:11:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
BOOLEAN
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2004-06-21 04:11:44 +00:00
|
|
|
CcPinRead (
|
|
|
|
IN PFILE_OBJECT FileObject,
|
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
2005-01-01 01:51:05 +00:00
|
|
|
IN ULONG Flags,
|
2004-06-21 04:11:44 +00:00
|
|
|
OUT PVOID * Bcb,
|
|
|
|
OUT PVOID * Buffer
|
|
|
|
)
|
|
|
|
{
|
2005-01-01 01:51:05 +00:00
|
|
|
if (CcMapData(FileObject, FileOffset, Length, Flags, Bcb, Buffer))
|
2004-08-25 15:08:29 +00:00
|
|
|
{
|
2005-01-01 01:51:05 +00:00
|
|
|
if (CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
|
2004-08-25 15:08:29 +00:00
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
CcUnpinData(Bcb);
|
|
|
|
}
|
|
|
|
return FALSE;
|
2004-06-21 04:11:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
BOOLEAN
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2004-06-21 04:11:44 +00:00
|
|
|
CcPreparePinWrite (
|
|
|
|
IN PFILE_OBJECT FileObject,
|
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN BOOLEAN Zero,
|
2005-01-01 01:51:05 +00:00
|
|
|
IN ULONG Flags,
|
2004-06-21 04:11:44 +00:00
|
|
|
OUT PVOID * Bcb,
|
|
|
|
OUT PVOID * Buffer
|
|
|
|
)
|
|
|
|
{
|
2004-08-25 15:08:29 +00:00
|
|
|
/*
|
|
|
|
* FIXME: This is function is similar to CcPinRead, but doesn't
|
|
|
|
* read the data if they're not present. Instead it should just
|
|
|
|
* prepare the cache segments and zero them out if Zero == TRUE.
|
|
|
|
*
|
|
|
|
* For now calling CcPinRead is better than returning error or
|
|
|
|
* just having UNIMPLEMENTED here.
|
|
|
|
*/
|
2005-01-01 01:51:05 +00:00
|
|
|
return CcPinRead(FileObject, FileOffset, Length, Flags, Bcb, Buffer);
|
2001-10-10 21:49:15 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 06:27:13 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-11-29 20:47:48 +00:00
|
|
|
VOID NTAPI
|
2002-07-17 21:04:57 +00:00
|
|
|
CcSetDirtyPinnedData (IN PVOID Bcb,
|
|
|
|
IN PLARGE_INTEGER Lsn)
|
2001-10-10 21:49:15 +00:00
|
|
|
{
|
|
|
|
PINTERNAL_BCB iBcb = Bcb;
|
2002-08-14 20:58:39 +00:00
|
|
|
iBcb->Dirty = TRUE;
|
2001-10-10 21:49:15 +00:00
|
|
|
}
|
|
|
|
|
2004-06-21 04:11:44 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-11-29 20:47:48 +00:00
|
|
|
VOID NTAPI
|
2004-06-21 04:11:44 +00:00
|
|
|
CcUnpinData (IN PVOID Bcb)
|
|
|
|
{
|
|
|
|
PINTERNAL_BCB iBcb = Bcb;
|
2005-05-09 01:38:29 +00:00
|
|
|
CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE,
|
2004-08-25 15:08:29 +00:00
|
|
|
iBcb->Dirty, FALSE);
|
|
|
|
if (--iBcb->RefCount == 0)
|
|
|
|
{
|
|
|
|
ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
|
|
|
|
}
|
2004-06-21 04:11:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2004-06-21 04:11:44 +00:00
|
|
|
CcUnpinDataForThread (
|
|
|
|
IN PVOID Bcb,
|
|
|
|
IN ERESOURCE_THREAD ResourceThreadId
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
}
|
2004-08-25 15:08:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2004-08-25 15:08:29 +00:00
|
|
|
CcRepinBcb (
|
|
|
|
IN PVOID Bcb
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PINTERNAL_BCB iBcb = Bcb;
|
|
|
|
iBcb->RefCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2004-08-25 15:08:29 +00:00
|
|
|
CcUnpinRepinnedBcb (
|
|
|
|
IN PVOID Bcb,
|
|
|
|
IN BOOLEAN WriteThrough,
|
|
|
|
IN PIO_STATUS_BLOCK IoStatus
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PINTERNAL_BCB iBcb = Bcb;
|
|
|
|
|
|
|
|
if (--iBcb->RefCount == 0)
|
|
|
|
{
|
|
|
|
IoStatus->Information = 0;
|
|
|
|
if (WriteThrough)
|
|
|
|
{
|
2011-12-21 19:08:59 +00:00
|
|
|
KeWaitForSingleObject(&iBcb->CacheSegment->Mutex,
|
|
|
|
Executive,
|
|
|
|
KernelMode,
|
|
|
|
FALSE,
|
|
|
|
NULL);
|
2004-08-25 15:08:29 +00:00
|
|
|
if (iBcb->CacheSegment->Dirty)
|
|
|
|
{
|
|
|
|
IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IoStatus->Status = STATUS_SUCCESS;
|
|
|
|
}
|
2011-12-21 19:08:59 +00:00
|
|
|
KeReleaseMutex(&iBcb->CacheSegment->Mutex, 0);
|
2004-08-25 15:08:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IoStatus->Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
|
|
|
|
}
|
|
|
|
}
|