-/* $Id: rw.c,v 1.21 2001/03/02 15:59:16 cnettel Exp $
+/* $Id: rw.c,v 1.22 2001/04/03 17:25:50 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/*
* Copy the data from the cache to the caller
*/
- memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
+ if (InternalOffset != 0 || !NoCache)
+ {
+ memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
+ }
if (!NoCache)
{
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
/*
* Copy the data from the cache to the caller
*/
- memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
+ if (InternalOffset != 0 || !NoCache)
+ {
+ memcpy(Destination, BaseAddress + InternalOffset, InternalLength);
+ }
if (!NoCache)
{
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: view.c,v 1.22 2001/03/25 02:34:27 dwelch Exp $
+/* $Id: view.c,v 1.23 2001/04/03 17:25:48 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* GLOBALS *******************************************************************/
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
-#define ROUND_DOWN(N, S) (ROUND_UP(N, S) - S)
+#define ROUND_DOWN(N, S) (((N) % (S)) ? ROUND_UP(N, S) - S : N)
#define TAG_CSEG TAG('C', 'S', 'E', 'G')
#define TAG_BCB TAG('B', 'C', 'B', ' ')
return(STATUS_SUCCESS);
}
-NTSTATUS STDCALL
-CcRequestCacheSegment(PBCB Bcb,
- ULONG FileOffset,
- PVOID* BaseAddress,
- PBOOLEAN UptoDate,
- PCACHE_SEGMENT* CacheSeg)
-/*
- * FUNCTION: Request a page mapping for a BCB
- */
+NTSTATUS
+CcGetCacheSegment(PBCB Bcb,
+ ULONG FileOffset,
+ PULONG BaseOffset,
+ PVOID* BaseAddress,
+ PBOOLEAN UptoDate,
+ PCACHE_SEGMENT* CacheSeg)
{
KIRQL oldirql;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
ULONG i;
- if ((FileOffset % Bcb->CacheSegmentSize) != 0)
- {
- KeBugCheck(0);
- }
-
- DPRINT("CcRequestCachePage(Bcb %x, FileOffset %x, BaseAddress %x, "
- "UptoDate %x, CacheSeg %x)\n", Bcb, FileOffset, BaseAddress,
- UptoDate, CacheSeg);
-
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->CacheSegmentListHead.Flink;
while (current_entry != &Bcb->CacheSegmentListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
- if (current->FileOffset == FileOffset)
+ if (current->FileOffset <= FileOffset &&
+ (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
{
- DPRINT("Found existing segment at %x\n", current);
current->ReferenceCount++;
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
- DPRINT("Waiting for segment\n");
KeWaitForSingleObject(¤t->Lock,
Executive,
KernelMode,
*UptoDate = current->Valid;
*BaseAddress = current->BaseAddress;
*CacheSeg = current;
- DPRINT("Returning %x (UptoDate %d)\n", current, current->Valid);
+ *BaseOffset = current->FileOffset;
return(STATUS_SUCCESS);
}
current_entry = current_entry->Flink;
(PMEMORY_AREA*)¤t->MemoryArea,
FALSE);
current->Valid = FALSE;
- current->FileOffset = FileOffset;
+ current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize);
current->Bcb = Bcb;
KeInitializeEvent(¤t->Lock, SynchronizationEvent, FALSE);
current->ReferenceCount = 1;
*UptoDate = current->Valid;
*BaseAddress = current->BaseAddress;
*CacheSeg = current;
+ *BaseOffset = current->FileOffset;
for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++)
{
MmCreateVirtualMapping(NULL,
}
- DPRINT("Returning %x (BaseAddress %x)\n", current, *BaseAddress);
return(STATUS_SUCCESS);
}
+NTSTATUS STDCALL
+CcRequestCacheSegment(PBCB Bcb,
+ ULONG FileOffset,
+ PVOID* BaseAddress,
+ PBOOLEAN UptoDate,
+ PCACHE_SEGMENT* CacheSeg)
+/*
+ * FUNCTION: Request a page mapping for a BCB
+ */
+{
+ ULONG BaseOffset;
+
+ if ((FileOffset % Bcb->CacheSegmentSize) != 0)
+ {
+ KeBugCheck(0);
+ }
+
+ return(CcGetCacheSegment(Bcb,
+ FileOffset,
+ &BaseOffset,
+ BaseAddress,
+ UptoDate,
+ CacheSeg));
+}
+
STATIC VOID
CcFreeCachePage(PVOID Context, PVOID Address, ULONG PhysAddr)
{
#ifndef __INCLUDE_INTERNAL_CC_H
-#define __INCLUDE_INTERNAL_CCS_H
-/* $Id: cc.h,v 1.2 2000/12/28 03:38:07 dwelch Exp $ */
+#define __INCLUDE_INTERNAL_CC_H
+/* $Id: cc.h,v 1.3 2001/04/03 17:25:48 dwelch Exp $ */
+#include <ddk/ntifs.h>
VOID STDCALL
CcMdlReadCompleteDev (IN PMDL MdlChain,
IN PDEVICE_OBJECT DeviceObject);
+NTSTATUS
+CcGetCacheSegment(PBCB Bcb,
+ ULONG FileOffset,
+ PULONG BaseOffset,
+ PVOID* BaseAddress,
+ PBOOLEAN UptoDate,
+ PCACHE_SEGMENT* CacheSeg);
#endif
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: io.h,v 1.8 2001/01/13 18:38:08 dwelch Exp $
+/* $Id: io.h,v 1.9 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
VOID IoShutdownRegisteredDevices(VOID);
VOID IoShutdownRegisteredFileSystems(VOID);
-NTSTATUS STDCALL IoPageRead (PFILE_OBJECT FileObject,
- PMDL Mdl,
- PLARGE_INTEGER Offset,
- PIO_STATUS_BLOCK StatusBlock,
- ULONG PagingIo);
+NTSTATUS STDCALL
+IoPageRead (PFILE_OBJECT FileObject,
+ PMDL Mdl,
+ PLARGE_INTEGER Offset,
+ PIO_STATUS_BLOCK StatusBlock,
+ BOOLEAN PagingIo);
NTSTATUS STDCALL IoPageWrite (PFILE_OBJECT FileObject,
PMDL Mdl,
PLARGE_INTEGER Offset,
-/* $Id: buildirp.c,v 1.24 2001/03/07 16:48:41 dwelch Exp $
+/* $Id: buildirp.c,v 1.25 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
}
-PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
- PDEVICE_OBJECT DeviceObject,
- PMDL Mdl,
- PLARGE_INTEGER StartingOffset,
- PKEVENT Event,
- PIO_STATUS_BLOCK IoStatusBlock,
- ULONG PagingIo)
+PIRP
+IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
+ PDEVICE_OBJECT DeviceObject,
+ PMDL Mdl,
+ PLARGE_INTEGER StartingOffset,
+ PKEVENT Event,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ BOOLEAN PagingIo)
/*
* FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
* level driver(s)
-/* $Id: page.c,v 1.11 2001/01/13 18:38:09 dwelch Exp $
+/* $Id: page.c,v 1.12 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
}
-NTSTATUS STDCALL IoPageRead(PFILE_OBJECT FileObject,
- PMDL Mdl,
- PLARGE_INTEGER Offset,
- PIO_STATUS_BLOCK StatusBlock,
- ULONG PagingIo)
+NTSTATUS STDCALL
+IoPageRead(PFILE_OBJECT FileObject,
+ PMDL Mdl,
+ PLARGE_INTEGER Offset,
+ PIO_STATUS_BLOCK StatusBlock,
+ BOOLEAN PagingIo)
{
PIRP Irp;
KEVENT Event;
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: dpc.c,v 1.20 2001/04/02 04:07:49 phreak Exp $
+/* $Id: dpc.c,v 1.21 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
current_entry = RemoveHeadList(&DpcQueueHead);
- DpcQueueSize--;
+ if (current_entry != &DpcQueueHead)
+ {
+ DpcQueueSize--;
+ }
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
current->Lock=FALSE;
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
current_entry = RemoveHeadList(&DpcQueueHead);
- DpcQueueSize--;
+ if (current_entry != &DpcQueueHead)
+ {
+ DpcQueueSize--;
+ }
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
current->Lock=FALSE;
-/* $Id: mdl.c,v 1.33 2001/03/25 02:34:28 dwelch Exp $
+/* $Id: mdl.c,v 1.34 2001/04/03 17:25:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
return((PVOID)MdlPages[((ULONG)Offset) / PAGESIZE]);
}
-VOID STDCALL MmUnlockPages(PMDL Mdl)
+VOID STDCALL
+MmUnlockPages(PMDL Mdl)
/*
* FUNCTION: Unlocks the physical pages described by a given MDL
* ARGUMENTS:
NTSTATUS Status;
DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
+
+ if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
+ {
+ return(Mdl->MappedSystemVa);
+ }
MmLockAddressSpace(MmGetKernelAddressSpace());
}
-VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
+VOID STDCALL
+MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
/*
* FUNCTION: Releases a mapping set up by a preceding call to MmMapLockedPages
* ARGUMENTS:
*/
{
DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", Mdl, BaseAddress);
+
+ /*
+ * In this case, the MDL has the same system address as the base address
+ * so there is no need to free it
+ */
+ if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
+ {
+ return;
+ }
+
MmLockAddressSpace(MmGetKernelAddressSpace());
(VOID)MmFreeMemoryArea(MmGetKernelAddressSpace(),
BaseAddress - Mdl->ByteOffset,
}
-VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages)
+VOID
+MmBuildMdlFromPages(PMDL Mdl, PULONG Pages)
{
ULONG i;
PULONG MdlPages;
}
-VOID STDCALL MmBuildMdlForNonPagedPool (PMDL Mdl)
+VOID STDCALL
+MmBuildMdlForNonPagedPool (PMDL Mdl)
/*
* FUNCTION: Fills in the corresponding physical page array of a given
* MDL for a buffer in nonpaged system space
*/
{
int va;
- Mdl->MdlFlags = Mdl->MdlFlags | MDL_SOURCE_IS_NONPAGED_POOL;
- for (va=0; va<Mdl->Size; va++)
+ Mdl->MdlFlags = Mdl->MdlFlags |
+ (MDL_SOURCE_IS_NONPAGED_POOL | MDL_PAGES_LOCKED);
+ for (va=0; va < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); va++)
{
((PULONG)(Mdl + 1))[va] =
(MmGetPhysicalAddress(Mdl->StartVa + (va * PAGESIZE))).u.LowPart;
}
-PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList,
- PVOID Base,
- ULONG Length)
+PMDL STDCALL
+MmCreateMdl (PMDL MemoryDescriptorList,
+ PVOID Base,
+ ULONG Length)
/*
* FUNCTION: Allocates and initalizes an MDL
* ARGUMENTS:
return(MemoryDescriptorList);
}
-
-VOID STDCALL MmMapMemoryDumpMdl (PVOID Unknown0)
+VOID STDCALL
+MmMapMemoryDumpMdl (PVOID Unknown0)
/*
* FIXME: Has something to do with crash dumps. Do we want to implement
* this?
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: section.c,v 1.54 2001/03/30 15:14:53 dwelch Exp $
+/* $Id: section.c,v 1.55 2001/04/03 17:25:49 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c
#include <internal/io.h>
#include <internal/ps.h>
#include <internal/pool.h>
+#include <internal/cc.h>
#include <ddk/ntifs.h>
#define NDEBUG
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
}
+NTSTATUS
+MiReadPage(PMEMORY_AREA MemoryArea,
+ PLARGE_INTEGER Offset,
+ PVOID* Page)
+{
+ IO_STATUS_BLOCK IoStatus;
+ PFILE_OBJECT FileObject;
+ PMDL Mdl;
+ NTSTATUS Status;
+ PREACTOS_COMMON_FCB_HEADER Fcb;
+
+ FileObject = MemoryArea->Data.SectionData.Section->FileObject;
+ Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext;
+
+ if (FileObject->Flags & FO_DIRECT_CACHE_PAGING_READ &&
+ (Offset->QuadPart % PAGESIZE) == 0)
+ {
+ ULONG BaseOffset;
+ PVOID BaseAddress;
+ BOOLEAN UptoDate;
+ PCACHE_SEGMENT CacheSeg;
+ LARGE_INTEGER SegOffset;
+ PHYSICAL_ADDRESS Addr;
+
+ Status = CcGetCacheSegment(Fcb->Bcb,
+ (ULONG)Offset->QuadPart,
+ &BaseOffset,
+ &BaseAddress,
+ &UptoDate,
+ &CacheSeg);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ if (!UptoDate)
+ {
+ Mdl = MmCreateMdl(NULL, BaseAddress, Fcb->Bcb->CacheSegmentSize);
+ MmBuildMdlForNonPagedPool(Mdl);
+
+ SegOffset.QuadPart = BaseOffset;
+ Status = IoPageRead(FileObject,
+ Mdl,
+ &SegOffset,
+ &IoStatus,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ CcReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE);
+ return(Status);
+ }
+ }
+
+ Addr = MmGetPhysicalAddress(BaseAddress +
+ Offset->QuadPart - BaseOffset);
+ (*Page) = (PVOID)(ULONG)Addr.QuadPart;
+ MmReferencePage((*Page));
+
+ CcReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE);
+ return(STATUS_SUCCESS);
+ }
+ else
+ {
+
+ /*
+ * Allocate a page, this is rather complicated by the possibility
+ * we might have to move other things out of memory
+ */
+ (*Page) = MmAllocPage(0);
+ while ((*Page) == NULL)
+ {
+ MmWaitForFreePages();
+ (*Page) = MmAllocPage(0);
+ }
+
+ /*
+ * Create an mdl to hold the page we are going to read data into.
+ */
+ Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
+ MmBuildMdlFromPages(Mdl, (PULONG)Page);
+
+ /*
+ * Call the FSD to read the page
+ */
+ Status = IoPageRead(FileObject,
+ Mdl,
+ Offset,
+ &IoStatus,
+ FALSE);
+ return(Status);
+ }
+}
NTSTATUS
MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
BOOLEAN Locked)
{
LARGE_INTEGER Offset;
- IO_STATUS_BLOCK IoStatus;
- PMDL Mdl;
PVOID Page;
NTSTATUS Status;
ULONG PAddress;
* If the entry is zero (and it can't change because we have
* locked the segment) then we need to load the page.
*/
-
- /*
- * Allocate a page, this is rather complicated by the possibility
- * we might have to move other things out of memory
- */
- Page = MmAllocPage(0);
- while (Page == NULL)
- {
- MmUnlockSectionSegment(Segment);
- MmUnlockSection(Section);
- MmUnlockAddressSpace(AddressSpace);
- MmWaitForFreePages();
- MmLockAddressSpace(AddressSpace);
- MmLockSection(Section);
- MmLockSectionSegment(Segment);
- Page = MmAllocPage(0);
- }
-
- /*
- * Create an mdl to hold the page we are going to read data into.
- */
- Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
- MmBuildMdlFromPages(Mdl, (PULONG)&Page);
-
+
/*
* Release all our locks and read in the page from disk
*/
MmUnlockSectionSegment(Segment);
MmUnlockSection(Section);
MmUnlockAddressSpace(AddressSpace);
- Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
- Mdl,
- &Offset,
- &IoStatus,
- FALSE);
+
+ Status = MiReadPage(MemoryArea, &Offset, &Page);
if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
{
/*