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
|
|
|
*
|
2016-05-26 12:09:05 +00:00
|
|
|
* PROGRAMMERS: ?
|
|
|
|
Pierre Schweitzer (pierre@reactos.org)
|
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
|
|
|
|
2018-02-24 12:35:17 +00:00
|
|
|
/* Counters:
|
|
|
|
* - Number of calls to CcMapData that could wait
|
|
|
|
* - Number of calls to CcMapData that couldn't wait
|
2018-02-24 12:47:15 +00:00
|
|
|
* - Number of calls to CcPinRead that could wait
|
|
|
|
* - Number of calls to CcPinRead that couldn't wait
|
2018-02-24 12:35:17 +00:00
|
|
|
*/
|
2018-02-24 12:28:45 +00:00
|
|
|
ULONG CcMapDataWait = 0;
|
|
|
|
ULONG CcMapDataNoWait = 0;
|
2018-02-24 12:47:15 +00:00
|
|
|
ULONG CcPinReadWait = 0;
|
|
|
|
ULONG CcPinReadNoWait = 0;
|
2018-02-24 12:28:45 +00:00
|
|
|
|
2003-01-11 15:22:31 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
2001-10-10 21:49:15 +00:00
|
|
|
|
2018-09-09 09:14:42 +00:00
|
|
|
static
|
2010-12-28 14:49:53 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
2018-09-09 09:14:42 +00:00
|
|
|
CcpMapData(
|
2010-12-28 14:49:53 +00:00
|
|
|
IN PFILE_OBJECT FileObject,
|
2012-12-19 11:11:34 +00:00
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN ULONG Flags,
|
|
|
|
OUT PVOID *pBcb,
|
|
|
|
OUT PVOID *pBuffer)
|
2001-10-10 21:49:15 +00:00
|
|
|
{
|
2018-01-13 20:27:29 +00:00
|
|
|
LONGLONG ReadOffset;
|
2010-12-28 14:49:53 +00:00
|
|
|
BOOLEAN Valid;
|
2014-04-12 10:59:48 +00:00
|
|
|
PROS_SHARED_CACHE_MAP SharedCacheMap;
|
2014-04-12 09:31:07 +00:00
|
|
|
PROS_VACB Vacb;
|
2010-12-28 14:49:53 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PINTERNAL_BCB iBcb;
|
2018-01-13 20:27:29 +00:00
|
|
|
LONGLONG ROffset;
|
2018-09-02 12:37:47 +00:00
|
|
|
KIRQL OldIrql;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2018-01-13 20:27:29 +00:00
|
|
|
ReadOffset = 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
|
|
|
|
2014-04-12 10:59:48 +00:00
|
|
|
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
|
|
|
|
ASSERT(SharedCacheMap);
|
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
|
|
|
|
2014-04-12 11:19:38 +00:00
|
|
|
DPRINT("SectionSize %I64x, FileSize %I64x\n",
|
|
|
|
SharedCacheMap->SectionSize.QuadPart,
|
2014-04-12 10:59:48 +00:00
|
|
|
SharedCacheMap->FileSize.QuadPart);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2013-09-30 19:40:09 +00:00
|
|
|
if (ReadOffset % VACB_MAPPING_GRANULARITY + Length > VACB_MAPPING_GRANULARITY)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
|
|
|
|
FileObject, FileOffset, Length, Flags);
|
2010-12-28 14:49:53 +00:00
|
|
|
return FALSE;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2012-12-19 11:11:34 +00:00
|
|
|
|
[NTOSKRNL] Warn about unimplemented feature in CcMapData() (in all callers)
Currently, our CcMapData() behavior (same goes for CcPinRead()) is broken
and is the total opposite of what Windows kernel does. By default, the later
will let you map a view in memory without even attempting to bring its
data in memory. On first access, there will be a fault and memory will
be read from the hardware and brought to memory. If you want to force read
on mapping/pinning, you have to set the MAP_NO_READ (or PIN_NO_READ) flag
where kernel will fault on your behalf (hence the need for MAP_WAIT/PIN_WAIT).
On ReactOS, by default, on mapping (and thus pinning), we will force a view
read so that data is in memory. The way our cache memory is managed at the
moment seems not to allow to fault on invalid access and if we don't force
read, the memory content will just be zeroed.
So trying to match Windows behavior, by default, now CcMapData() will enforce
the MAP_NO_READ flag and warn once about this behavior change.
2018-08-31 17:43:04 +00:00
|
|
|
if (!BooleanFlagOn(Flags, MAP_NO_READ))
|
|
|
|
{
|
|
|
|
static int Warned = 0;
|
|
|
|
|
|
|
|
SetFlag(Flags, MAP_NO_READ);
|
|
|
|
if (!Warned)
|
|
|
|
{
|
|
|
|
DPRINT1("Mapping/pinning with no read not implemented. Forcing read, might fail if wait not allowed\n");
|
|
|
|
Warned++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-30 19:40:09 +00:00
|
|
|
ROffset = ROUND_DOWN(ReadOffset, VACB_MAPPING_GRANULARITY);
|
2014-04-12 10:59:48 +00:00
|
|
|
Status = CcRosRequestVacb(SharedCacheMap,
|
2014-04-12 09:31:07 +00:00
|
|
|
ROffset,
|
|
|
|
pBuffer,
|
|
|
|
&Valid,
|
|
|
|
&Vacb);
|
2010-12-28 14:49:53 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
|
|
|
|
FileObject, FileOffset, Length, Flags);
|
2016-07-10 14:46:37 +00:00
|
|
|
ExRaiseStatus(Status);
|
2010-12-28 14:49:53 +00:00
|
|
|
return FALSE;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2012-12-19 11:11:34 +00:00
|
|
|
|
[NTOSKRNL] Warn about unimplemented feature in CcMapData() (in all callers)
Currently, our CcMapData() behavior (same goes for CcPinRead()) is broken
and is the total opposite of what Windows kernel does. By default, the later
will let you map a view in memory without even attempting to bring its
data in memory. On first access, there will be a fault and memory will
be read from the hardware and brought to memory. If you want to force read
on mapping/pinning, you have to set the MAP_NO_READ (or PIN_NO_READ) flag
where kernel will fault on your behalf (hence the need for MAP_WAIT/PIN_WAIT).
On ReactOS, by default, on mapping (and thus pinning), we will force a view
read so that data is in memory. The way our cache memory is managed at the
moment seems not to allow to fault on invalid access and if we don't force
read, the memory content will just be zeroed.
So trying to match Windows behavior, by default, now CcMapData() will enforce
the MAP_NO_READ flag and warn once about this behavior change.
2018-08-31 17:43:04 +00:00
|
|
|
if (!Valid && BooleanFlagOn(Flags, MAP_NO_READ))
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
[NTOSKRNL] Warn about unimplemented feature in CcMapData() (in all callers)
Currently, our CcMapData() behavior (same goes for CcPinRead()) is broken
and is the total opposite of what Windows kernel does. By default, the later
will let you map a view in memory without even attempting to bring its
data in memory. On first access, there will be a fault and memory will
be read from the hardware and brought to memory. If you want to force read
on mapping/pinning, you have to set the MAP_NO_READ (or PIN_NO_READ) flag
where kernel will fault on your behalf (hence the need for MAP_WAIT/PIN_WAIT).
On ReactOS, by default, on mapping (and thus pinning), we will force a view
read so that data is in memory. The way our cache memory is managed at the
moment seems not to allow to fault on invalid access and if we don't force
read, the memory content will just be zeroed.
So trying to match Windows behavior, by default, now CcMapData() will enforce
the MAP_NO_READ flag and warn once about this behavior change.
2018-08-31 17:43:04 +00:00
|
|
|
if (!BooleanFlagOn(Flags, MAP_WAIT))
|
2010-12-28 14:49:53 +00:00
|
|
|
{
|
2014-04-12 10:59:48 +00:00
|
|
|
CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
|
|
|
|
FileObject, FileOffset, Length, Flags);
|
2010-12-28 14:49:53 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2012-12-19 11:11:34 +00:00
|
|
|
|
2016-07-10 14:46:37 +00:00
|
|
|
Status = CcReadVirtualAddress(Vacb);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2010-12-28 14:49:53 +00:00
|
|
|
{
|
2014-04-12 10:59:48 +00:00
|
|
|
CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
|
|
|
|
FileObject, FileOffset, Length, Flags);
|
2016-07-10 14:46:37 +00:00
|
|
|
ExRaiseStatus(Status);
|
2012-12-19 11:11:34 +00:00
|
|
|
return FALSE;
|
2010-12-28 14:49:53 +00:00
|
|
|
}
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2005-07-05 00:57:47 +00:00
|
|
|
|
2018-01-13 20:27:29 +00:00
|
|
|
*pBuffer = (PUCHAR)*pBuffer + ReadOffset % VACB_MAPPING_GRANULARITY;
|
2010-12-28 14:49:53 +00:00
|
|
|
iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
|
|
|
|
if (iBcb == NULL)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2014-04-12 10:59:48 +00:00
|
|
|
CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> FALSE\n",
|
|
|
|
FileObject, FileOffset, Length, Flags);
|
2016-07-10 14:46:37 +00:00
|
|
|
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
|
2010-12-28 14:49:53 +00:00
|
|
|
return FALSE;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2012-12-19 11:11:34 +00:00
|
|
|
|
2013-09-30 20:06:18 +00:00
|
|
|
RtlZeroMemory(iBcb, sizeof(*iBcb));
|
2010-12-28 14:49:53 +00:00
|
|
|
iBcb->PFCB.NodeTypeCode = 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */
|
|
|
|
iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB);
|
|
|
|
iBcb->PFCB.MappedLength = Length;
|
|
|
|
iBcb->PFCB.MappedFileOffset = *FileOffset;
|
2014-04-12 09:31:07 +00:00
|
|
|
iBcb->Vacb = Vacb;
|
2010-12-28 14:49:53 +00:00
|
|
|
iBcb->Dirty = FALSE;
|
2016-05-26 12:09:05 +00:00
|
|
|
iBcb->Pinned = FALSE;
|
2010-12-28 14:49:53 +00:00
|
|
|
iBcb->RefCount = 1;
|
2016-05-26 12:09:05 +00:00
|
|
|
ExInitializeResourceLite(&iBcb->Lock);
|
2010-12-28 14:49:53 +00:00
|
|
|
*pBcb = (PVOID)iBcb;
|
2012-12-19 11:11:34 +00:00
|
|
|
|
2018-09-02 12:37:47 +00:00
|
|
|
KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
|
|
|
|
InsertTailList(&SharedCacheMap->BcbList, &iBcb->BcbEntry);
|
|
|
|
KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
|
|
|
|
|
2010-12-28 14:49:53 +00:00
|
|
|
return TRUE;
|
2001-10-10 21:49:15 +00:00
|
|
|
}
|
|
|
|
|
2018-09-09 09:14:42 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
CcMapData (
|
|
|
|
IN PFILE_OBJECT FileObject,
|
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN ULONG Flags,
|
|
|
|
OUT PVOID *pBcb,
|
|
|
|
OUT PVOID *pBuffer)
|
|
|
|
{
|
|
|
|
BOOLEAN Ret;
|
|
|
|
|
|
|
|
DPRINT("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %lu, Flags 0x%lx,"
|
|
|
|
" pBcb 0x%p, pBuffer 0x%p)\n", FileObject, FileOffset->QuadPart,
|
|
|
|
Length, Flags, pBcb, pBuffer);
|
|
|
|
|
|
|
|
if (Flags & MAP_WAIT)
|
|
|
|
{
|
|
|
|
++CcMapDataWait;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
++CcMapDataNoWait;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ret = CcpMapData(FileObject, FileOffset, Length, Flags, pBcb, pBuffer);
|
|
|
|
|
|
|
|
CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx -> %d Bcb=%p\n",
|
|
|
|
FileObject, FileOffset, Length, Flags, Ret, *pBcb);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
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 (
|
2012-12-19 11:11:34 +00:00
|
|
|
IN PFILE_OBJECT FileObject,
|
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN ULONG Flags,
|
|
|
|
OUT PVOID * Bcb)
|
2001-10-10 21:49:15 +00:00
|
|
|
{
|
2018-08-26 20:04:46 +00:00
|
|
|
BOOLEAN Result;
|
2018-08-26 19:49:05 +00:00
|
|
|
PINTERNAL_BCB iBcb;
|
2016-05-26 11:50:42 +00:00
|
|
|
PROS_SHARED_CACHE_MAP SharedCacheMap;
|
|
|
|
|
2018-08-31 17:48:03 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
|
2014-11-29 21:43:39 +00:00
|
|
|
FileObject, FileOffset, Length, Flags);
|
|
|
|
|
2016-05-26 11:50:42 +00:00
|
|
|
ASSERT(FileObject);
|
|
|
|
ASSERT(FileObject->SectionObjectPointer);
|
|
|
|
ASSERT(FileObject->SectionObjectPointer->SharedCacheMap);
|
|
|
|
|
|
|
|
SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
|
|
|
|
ASSERT(SharedCacheMap);
|
2018-09-01 10:39:05 +00:00
|
|
|
if (!SharedCacheMap->PinAccess)
|
|
|
|
{
|
|
|
|
DPRINT1("FIXME: Pinning a file with no pin access!\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2016-05-26 11:50:42 +00:00
|
|
|
|
2018-08-26 19:49:05 +00:00
|
|
|
iBcb = *Bcb;
|
|
|
|
ASSERT(iBcb->Pinned == FALSE);
|
|
|
|
|
|
|
|
iBcb->Pinned = TRUE;
|
|
|
|
iBcb->Vacb->PinCount++;
|
|
|
|
|
2018-08-26 20:04:46 +00:00
|
|
|
if (BooleanFlagOn(Flags, PIN_EXCLUSIVE))
|
2018-08-26 19:49:05 +00:00
|
|
|
{
|
2018-08-26 20:04:46 +00:00
|
|
|
Result = ExAcquireResourceExclusiveLite(&iBcb->Lock, BooleanFlagOn(Flags, PIN_WAIT));
|
2018-08-26 19:49:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-08-26 20:47:48 +00:00
|
|
|
Result = ExAcquireSharedStarveExclusive(&iBcb->Lock, BooleanFlagOn(Flags, PIN_WAIT));
|
2018-08-26 19:49:05 +00:00
|
|
|
}
|
|
|
|
|
2018-08-26 20:56:25 +00:00
|
|
|
if (!Result)
|
|
|
|
{
|
|
|
|
iBcb->Pinned = FALSE;
|
|
|
|
iBcb->Vacb->PinCount--;
|
|
|
|
}
|
|
|
|
|
2018-08-26 20:04:46 +00:00
|
|
|
return Result;
|
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 (
|
2012-12-19 11:11:34 +00:00
|
|
|
IN PFILE_OBJECT FileObject,
|
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN ULONG Flags,
|
|
|
|
OUT PVOID * Bcb,
|
|
|
|
OUT PVOID * Buffer)
|
2004-06-21 04:11:44 +00:00
|
|
|
{
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "FileOffset=%p FileOffset=%p Length=%lu Flags=0x%lx\n",
|
|
|
|
FileObject, FileOffset, Length, Flags);
|
|
|
|
|
2018-02-24 12:47:15 +00:00
|
|
|
if (Flags & PIN_WAIT)
|
|
|
|
{
|
|
|
|
++CcPinReadWait;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
++CcPinReadNoWait;
|
|
|
|
}
|
|
|
|
|
2018-08-26 19:49:05 +00:00
|
|
|
/* Map first */
|
2018-09-09 09:14:42 +00:00
|
|
|
if (!CcpMapData(FileObject, FileOffset, Length, Flags, Bcb, Buffer))
|
2012-12-19 11:11:34 +00:00
|
|
|
{
|
2018-08-26 19:49:05 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2016-05-26 12:09:05 +00:00
|
|
|
|
2018-08-26 19:49:05 +00:00
|
|
|
/* Pin then */
|
|
|
|
if (!CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
|
|
|
|
{
|
|
|
|
CcUnpinData(*Bcb);
|
|
|
|
return FALSE;
|
2012-12-19 11:11:34 +00:00
|
|
|
}
|
2018-08-26 19:49:05 +00:00
|
|
|
|
|
|
|
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
|
|
|
CcPreparePinWrite (
|
2012-12-19 11:11:34 +00:00
|
|
|
IN PFILE_OBJECT FileObject,
|
|
|
|
IN PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN BOOLEAN Zero,
|
|
|
|
IN ULONG Flags,
|
|
|
|
OUT PVOID * Bcb,
|
|
|
|
OUT PVOID * Buffer)
|
2004-06-21 04:11:44 +00:00
|
|
|
{
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "FileOffset=%p FileOffset=%p Length=%lu Zero=%d Flags=0x%lx\n",
|
|
|
|
FileObject, FileOffset, Length, Zero, Flags);
|
|
|
|
|
2012-12-19 11:11:34 +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
|
2014-11-15 22:47:51 +00:00
|
|
|
* prepare the VACBs and zero them out if Zero != FALSE.
|
2012-12-19 11:11:34 +00:00
|
|
|
*
|
|
|
|
* For now calling CcPinRead is better than returning error or
|
|
|
|
* just having UNIMPLEMENTED here.
|
|
|
|
*/
|
|
|
|
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
|
2012-12-19 11:11:34 +00:00
|
|
|
CcSetDirtyPinnedData (
|
|
|
|
IN PVOID Bcb,
|
|
|
|
IN PLARGE_INTEGER Lsn)
|
2001-10-10 21:49:15 +00:00
|
|
|
{
|
2012-12-19 11:11:34 +00:00
|
|
|
PINTERNAL_BCB iBcb = Bcb;
|
2014-11-29 21:43:39 +00:00
|
|
|
|
|
|
|
CCTRACE(CC_API_DEBUG, "Bcb=%p Lsn=%p\n",
|
|
|
|
Bcb, Lsn);
|
|
|
|
|
2012-12-19 11:11:34 +00:00
|
|
|
iBcb->Dirty = TRUE;
|
2018-04-29 18:34:28 +00:00
|
|
|
if (!iBcb->Vacb->Dirty)
|
|
|
|
{
|
|
|
|
CcRosMarkDirtyVacb(iBcb->Vacb);
|
|
|
|
}
|
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
|
2012-12-19 11:11:34 +00:00
|
|
|
CcUnpinData (
|
|
|
|
IN PVOID Bcb)
|
2004-06-21 04:11:44 +00:00
|
|
|
{
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "Bcb=%p\n", Bcb);
|
|
|
|
|
2016-05-26 12:09:05 +00:00
|
|
|
CcUnpinDataForThread(Bcb, (ERESOURCE_THREAD)PsGetCurrentThread());
|
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 (
|
2012-12-19 11:11:34 +00:00
|
|
|
IN PVOID Bcb,
|
|
|
|
IN ERESOURCE_THREAD ResourceThreadId)
|
2004-06-21 04:11:44 +00:00
|
|
|
{
|
2016-03-20 18:33:54 +00:00
|
|
|
PINTERNAL_BCB iBcb = Bcb;
|
|
|
|
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "Bcb=%p ResourceThreadId=%lu\n", Bcb, ResourceThreadId);
|
|
|
|
|
2016-05-26 12:09:05 +00:00
|
|
|
if (iBcb->Pinned)
|
2016-03-20 18:33:54 +00:00
|
|
|
{
|
2016-05-26 12:09:05 +00:00
|
|
|
ExReleaseResourceForThreadLite(&iBcb->Lock, ResourceThreadId);
|
|
|
|
iBcb->Pinned = FALSE;
|
2016-07-25 08:48:50 +00:00
|
|
|
iBcb->Vacb->PinCount--;
|
2016-03-20 18:33:54 +00:00
|
|
|
}
|
|
|
|
|
2016-05-26 12:09:05 +00:00
|
|
|
if (--iBcb->RefCount == 0)
|
|
|
|
{
|
2018-09-02 12:37:47 +00:00
|
|
|
KIRQL OldIrql;
|
|
|
|
PROS_SHARED_CACHE_MAP SharedCacheMap;
|
|
|
|
|
|
|
|
SharedCacheMap = iBcb->Vacb->SharedCacheMap;
|
|
|
|
CcRosReleaseVacb(SharedCacheMap,
|
2018-01-28 10:09:21 +00:00
|
|
|
iBcb->Vacb,
|
|
|
|
TRUE,
|
|
|
|
iBcb->Dirty,
|
|
|
|
FALSE);
|
|
|
|
|
2018-09-02 12:37:47 +00:00
|
|
|
KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
|
|
|
|
RemoveEntryList(&iBcb->BcbEntry);
|
|
|
|
KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
|
|
|
|
|
2016-05-26 12:09:05 +00:00
|
|
|
ExDeleteResourceLite(&iBcb->Lock);
|
|
|
|
ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
|
|
|
|
}
|
2004-06-21 04:11:44 +00:00
|
|
|
}
|
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 (
|
2012-12-19 11:11:34 +00:00
|
|
|
IN PVOID Bcb)
|
2004-08-25 15:08:29 +00:00
|
|
|
{
|
2012-12-19 11:11:34 +00:00
|
|
|
PINTERNAL_BCB iBcb = Bcb;
|
2014-11-29 21:43:39 +00:00
|
|
|
|
|
|
|
CCTRACE(CC_API_DEBUG, "Bcb=%p\n", Bcb);
|
|
|
|
|
2012-12-19 11:11:34 +00:00
|
|
|
iBcb->RefCount++;
|
2004-08-25 15:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
VOID
|
2008-11-29 20:47:48 +00:00
|
|
|
NTAPI
|
2004-08-25 15:08:29 +00:00
|
|
|
CcUnpinRepinnedBcb (
|
2012-12-19 11:11:34 +00:00
|
|
|
IN PVOID Bcb,
|
|
|
|
IN BOOLEAN WriteThrough,
|
|
|
|
IN PIO_STATUS_BLOCK IoStatus)
|
2004-08-25 15:08:29 +00:00
|
|
|
{
|
2012-12-19 11:11:34 +00:00
|
|
|
PINTERNAL_BCB iBcb = Bcb;
|
2018-09-02 12:37:47 +00:00
|
|
|
KIRQL OldIrql;
|
|
|
|
PROS_SHARED_CACHE_MAP SharedCacheMap;
|
2004-08-25 15:08:29 +00:00
|
|
|
|
2014-11-29 21:43:39 +00:00
|
|
|
CCTRACE(CC_API_DEBUG, "Bcb=%p WriteThrough=%d\n", Bcb, WriteThrough);
|
|
|
|
|
2012-12-19 23:49:13 +00:00
|
|
|
IoStatus->Status = STATUS_SUCCESS;
|
2012-12-19 11:11:34 +00:00
|
|
|
if (--iBcb->RefCount == 0)
|
2004-08-25 15:08:29 +00:00
|
|
|
{
|
2012-12-19 11:11:34 +00:00
|
|
|
IoStatus->Information = 0;
|
|
|
|
if (WriteThrough)
|
2004-08-25 15:08:29 +00:00
|
|
|
{
|
2014-04-12 09:31:07 +00:00
|
|
|
if (iBcb->Vacb->Dirty)
|
2004-08-25 15:08:29 +00:00
|
|
|
{
|
2014-04-12 09:31:07 +00:00
|
|
|
IoStatus->Status = CcRosFlushVacb(iBcb->Vacb);
|
2004-08-25 15:08:29 +00:00
|
|
|
}
|
2012-12-19 11:11:34 +00:00
|
|
|
else
|
2004-08-25 15:08:29 +00:00
|
|
|
{
|
2012-12-19 11:11:34 +00:00
|
|
|
IoStatus->Status = STATUS_SUCCESS;
|
2004-08-25 15:08:29 +00:00
|
|
|
}
|
|
|
|
}
|
2012-12-19 11:11:34 +00:00
|
|
|
else
|
2004-08-25 15:08:29 +00:00
|
|
|
{
|
2012-12-19 11:11:34 +00:00
|
|
|
IoStatus->Status = STATUS_SUCCESS;
|
2004-08-25 15:08:29 +00:00
|
|
|
}
|
|
|
|
|
2016-05-26 12:09:05 +00:00
|
|
|
if (iBcb->Pinned)
|
|
|
|
{
|
|
|
|
ExReleaseResourceLite(&iBcb->Lock);
|
|
|
|
iBcb->Pinned = FALSE;
|
2016-07-25 08:48:50 +00:00
|
|
|
iBcb->Vacb->PinCount--;
|
2018-03-17 10:56:25 +00:00
|
|
|
ASSERT(iBcb->Vacb->PinCount == 0);
|
2016-05-26 12:09:05 +00:00
|
|
|
}
|
2018-03-17 10:56:25 +00:00
|
|
|
|
2018-09-02 12:37:47 +00:00
|
|
|
SharedCacheMap = iBcb->Vacb->SharedCacheMap;
|
2018-03-17 10:56:25 +00:00
|
|
|
CcRosReleaseVacb(iBcb->Vacb->SharedCacheMap,
|
|
|
|
iBcb->Vacb,
|
|
|
|
TRUE,
|
|
|
|
iBcb->Dirty,
|
|
|
|
FALSE);
|
|
|
|
|
2018-09-02 12:37:47 +00:00
|
|
|
KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
|
|
|
|
RemoveEntryList(&iBcb->BcbEntry);
|
|
|
|
KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
|
|
|
|
|
2016-05-26 12:09:05 +00:00
|
|
|
ExDeleteResourceLite(&iBcb->Lock);
|
2012-12-19 11:11:34 +00:00
|
|
|
ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
|
2004-08-25 15:08:29 +00:00
|
|
|
}
|
|
|
|
}
|