From aebf70e07f43a85d2ffd6e95ef91bf45da328be6 Mon Sep 17 00:00:00 2001 From: David Welch Date: Sat, 26 Jan 2002 21:21:02 +0000 Subject: [PATCH] Present large reads to the filesystem from CcCopyRead svn path=/trunk/; revision=2561 --- reactos/ntoskrnl/cc/copy.c | 351 ++++++++++++++++--------- reactos/ntoskrnl/cc/view.c | 213 ++++++++++----- reactos/ntoskrnl/include/internal/cc.h | 15 +- reactos/ntoskrnl/include/internal/ps.h | 12 +- reactos/ntoskrnl/ps/win32.c | 30 ++- 5 files changed, 420 insertions(+), 201 deletions(-) diff --git a/reactos/ntoskrnl/cc/copy.c b/reactos/ntoskrnl/cc/copy.c index 5cfa30c06cf..a95ebd1ff37 100644 --- a/reactos/ntoskrnl/cc/copy.c +++ b/reactos/ntoskrnl/cc/copy.c @@ -1,4 +1,4 @@ -/* $Id: copy.c,v 1.3 2001/12/29 14:32:21 dwelch Exp $ +/* $Id: copy.c,v 1.4 2002/01/26 21:21:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -28,7 +28,120 @@ /* FUNCTIONS *****************************************************************/ -NTSTATUS ReadCacheSegment(PCACHE_SEGMENT CacheSeg) +NTSTATUS +ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length, + PVOID Buffer) +{ + PCACHE_SEGMENT head; + PCACHE_SEGMENT current; + PCACHE_SEGMENT previous; + IO_STATUS_BLOCK Iosb; + LARGE_INTEGER SegOffset; + NTSTATUS Status; + ULONG TempLength; + + Status = CcRosGetCacheSegmentChain(Bcb, ReadOffset, Length, &head); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + current = head; + while (current != NULL) + { + /* + * If the current segment is valid then copy it into the + * user buffer. + */ + if (current->Valid) + { + TempLength = min(Bcb->CacheSegmentSize, Length); + memcpy(Buffer, current->BaseAddress, TempLength); + Buffer += TempLength; + Length = Length - TempLength; + previous = current; + current = current->NextInChain; + CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE); + } + /* + * Otherwise read in a much as we can. + */ + else + { + PCACHE_SEGMENT current2; + ULONG current_size; + PMDL Mdl; + ULONG i; + ULONG offset; + + /* + * Count the maximum number of bytes we could read starting + * from the current segment. + */ + current2 = current; + current_size = 0; + while (current2 != NULL && !current2->Valid) + { + current2 = current2->NextInChain; + current_size += Bcb->CacheSegmentSize; + } + + /* + * Create an MDL which contains all their pages. + */ + Mdl = MmCreateMdl(NULL, NULL, current_size); + Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); + current2 = current; + offset = 0; + while (current2 != NULL && !current2->Valid) + { + for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++) + { + PVOID address; + ULONG page; + address = current2->BaseAddress + (i * PAGESIZE); + page = MmGetPhysicalAddressForProcess(NULL, address); + ((PULONG)(Mdl + 1))[offset] = page; + offset++; + } + current2 = current2->NextInChain; + } + + /* + * Read in the information. + */ + SegOffset.QuadPart = current->FileOffset; + Status = IoPageRead(Bcb->FileObject, + Mdl, + &SegOffset, + &Iosb, + TRUE); + if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE) + { + while (current != NULL) + { + previous = current; + current = current->NextInChain; + CcRosReleaseCacheSegment(Bcb, previous, FALSE, FALSE, FALSE); + } + return(Status); + } + while (current != NULL && !current->Valid) + { + previous = current; + current = current->NextInChain; + TempLength = min(Bcb->CacheSegmentSize, Length); + memcpy(Buffer, previous->BaseAddress, TempLength); + Buffer += TempLength; + Length = Length - TempLength; + CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE); + } + } + } + return(STATUS_SUCCESS); +} + +NTSTATUS +ReadCacheSegment(PCACHE_SEGMENT CacheSeg) { ULONG Size; PMDL Mdl; @@ -39,22 +152,24 @@ NTSTATUS ReadCacheSegment(PCACHE_SEGMENT CacheSeg) SegOffset.QuadPart = CacheSeg->FileOffset; Size = CacheSeg->Bcb->AllocationSize.QuadPart - CacheSeg->FileOffset; if (Size > CacheSeg->Bcb->CacheSegmentSize) - { - Size = CacheSeg->Bcb->CacheSegmentSize; - } + { + Size = CacheSeg->Bcb->CacheSegmentSize; + } Mdl = MmCreateMdl(NULL, CacheSeg->BaseAddress, Size); MmBuildMdlForNonPagedPool(Mdl); - Status = IoPageRead(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &IoStatus, TRUE); + Status = IoPageRead(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &IoStatus, + TRUE); if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE) - { - CcRosReleaseCacheSegment(CacheSeg->Bcb, CacheSeg, FALSE, FALSE, FALSE); - DPRINT1("IoPageRead failed, Status %x\n", Status); - return Status; - } + { + CcRosReleaseCacheSegment(CacheSeg->Bcb, CacheSeg, FALSE, FALSE, FALSE); + DPRINT1("IoPageRead failed, Status %x\n", Status); + return Status; + } if (CacheSeg->Bcb->CacheSegmentSize > Size) - { - memset (CacheSeg->BaseAddress + Size, 0, CacheSeg->Bcb->CacheSegmentSize - Size); - } + { + memset (CacheSeg->BaseAddress + Size, 0, + CacheSeg->Bcb->CacheSegmentSize - Size); + } return STATUS_SUCCESS; } @@ -83,123 +198,109 @@ NTSTATUS WriteCacheSegment(PCACHE_SEGMENT CacheSeg) } BOOLEAN STDCALL -CcCopyRead ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus) +CcCopyRead (IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + OUT PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus) { - ULONG ReadOffset; - ULONG TempLength; - NTSTATUS Status = STATUS_SUCCESS; - PVOID BaseAddress; - PCACHE_SEGMENT CacheSeg; - BOOLEAN Valid; - ULONG ReadLength = 0; - PBCB Bcb; - KIRQL oldirql; - PLIST_ENTRY current_entry; - PCACHE_SEGMENT current; + ULONG ReadOffset; + ULONG TempLength; + NTSTATUS Status = STATUS_SUCCESS; + PVOID BaseAddress; + PCACHE_SEGMENT CacheSeg; + BOOLEAN Valid; + ULONG ReadLength = 0; + PBCB Bcb; + KIRQL oldirql; + PLIST_ENTRY current_entry; + PCACHE_SEGMENT current; + + DPRINT("CcCopyRead(FileObject %x, FileOffset %x, " + "Length %d, Wait %d, Buffer %x, IoStatus %x)\n", + FileObject, (ULONG)FileOffset->QuadPart, Length, Wait, + Buffer, IoStatus); - DPRINT("CcCopyRead(FileObject %x, FileOffset %x, " - "Length %d, Wait %d, Buffer %x, IoStatus %x)\n", - FileObject, (ULONG)FileOffset->QuadPart, Length, Wait, - Buffer, IoStatus); - - Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; - ReadOffset = FileOffset->QuadPart; - - DPRINT("AllocationSize %d, FileSize %d\n", + Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; + ReadOffset = FileOffset->QuadPart; + + DPRINT("AllocationSize %d, FileSize %d\n", (ULONG)Bcb->AllocationSize.QuadPart, (ULONG)Bcb->FileSize.QuadPart); - if (!Wait) - { - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - current_entry = Bcb->BcbSegmentListHead.Flink; - while (current_entry != &Bcb->BcbSegmentListHead) - { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); - if (!current->Valid && current->FileOffset < ReadOffset + Length - && current->FileOffset + Bcb->CacheSegmentSize > ReadOffset) - { - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - IoStatus->Status = STATUS_UNSUCCESSFUL; - IoStatus->Information = 0; - return FALSE; - } - current_entry = current_entry->Flink; - } - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - } + /* + * Check for the nowait case that all the cache segments that would + * cover this read are in memory. + */ + if (!Wait) + { + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + current_entry = Bcb->BcbSegmentListHead.Flink; + while (current_entry != &Bcb->BcbSegmentListHead) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, + BcbSegmentListEntry); + if (!current->Valid && current->FileOffset < ReadOffset + Length + && current->FileOffset + Bcb->CacheSegmentSize > ReadOffset) + { + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + IoStatus->Status = STATUS_UNSUCCESSFUL; + IoStatus->Information = 0; + return FALSE; + } + current_entry = current_entry->Flink; + } + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + } - TempLength = ReadOffset % Bcb->CacheSegmentSize; - if (TempLength != 0) - { - TempLength = min (Length, Bcb->CacheSegmentSize - TempLength); - Status = CcRosRequestCacheSegment(Bcb, - ROUND_DOWN(ReadOffset, Bcb->CacheSegmentSize), - &BaseAddress, &Valid, &CacheSeg); - if (!NT_SUCCESS(Status)) - { - IoStatus->Information = 0; - IoStatus->Status = Status; - DPRINT("CcRosRequestCacheSegment faild, Status %x\n", Status); - return FALSE; - } - if (!Valid) - { - Status = ReadCacheSegment(CacheSeg); - if (!NT_SUCCESS(Status)) - { - IoStatus->Information = 0; - IoStatus->Status = Status; - return FALSE; - } - } - memcpy (Buffer, BaseAddress + ReadOffset % Bcb->CacheSegmentSize, TempLength); - CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); - ReadLength += TempLength; - Length -= TempLength; - ReadOffset += TempLength; - Buffer += TempLength; - } - - while (Length > 0) - { - TempLength = min (Bcb->CacheSegmentSize, Length); - Status = CcRosRequestCacheSegment(Bcb, ReadOffset, - &BaseAddress, &Valid, &CacheSeg); - if (!NT_SUCCESS(Status)) - { - IoStatus->Information = 0; - IoStatus->Status = Status; - DPRINT("CcRosRequestCacheSegment faild, Status %x\n", Status); - return FALSE; - } - if (!Valid) - { - Status = ReadCacheSegment(CacheSeg); - if (!NT_SUCCESS(Status)) - { - IoStatus->Information = 0; - IoStatus->Status = Status; - return FALSE; - } - } - memcpy (Buffer, BaseAddress, TempLength); - CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); - ReadLength += TempLength; - Length -= TempLength; - ReadOffset += TempLength; - Buffer += TempLength; - } - IoStatus->Status = STATUS_SUCCESS; - IoStatus->Information = ReadLength; - DPRINT("CcCopyRead O.K.\n"); - return TRUE; + TempLength = ReadOffset % Bcb->CacheSegmentSize; + if (TempLength != 0) + { + TempLength = min (Length, Bcb->CacheSegmentSize - TempLength); + Status = CcRosRequestCacheSegment(Bcb, + ROUND_DOWN(ReadOffset, + Bcb->CacheSegmentSize), + &BaseAddress, &Valid, &CacheSeg); + if (!NT_SUCCESS(Status)) + { + IoStatus->Information = 0; + IoStatus->Status = Status; + DPRINT("CcRosRequestCacheSegment faild, Status %x\n", Status); + return FALSE; + } + if (!Valid) + { + Status = ReadCacheSegment(CacheSeg); + if (!NT_SUCCESS(Status)) + { + IoStatus->Information = 0; + IoStatus->Status = Status; + return FALSE; + } + } + memcpy (Buffer, BaseAddress + ReadOffset % Bcb->CacheSegmentSize, + TempLength); + CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); + ReadLength += TempLength; + Length -= TempLength; + ReadOffset += TempLength; + Buffer += TempLength; + } + + while (Length > 0) + { + TempLength = min(max(Bcb->CacheSegmentSize, 65536), Length); + ReadCacheSegmentChain(Bcb, ReadOffset, TempLength, Buffer); + ReadLength += TempLength; + Length -= TempLength; + ReadOffset += TempLength; + Buffer += TempLength; + } + IoStatus->Status = STATUS_SUCCESS; + IoStatus->Information = ReadLength; + DPRINT("CcCopyRead O.K.\n"); + return TRUE; } BOOLEAN STDCALL diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index be229f590f1..9a2c26d0a81 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -16,7 +16,7 @@ * 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.35 2002/01/08 00:49:00 dwelch Exp $ +/* $Id: view.c,v 1.36 2002/01/26 21:21:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -98,7 +98,8 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) current_entry = CacheSegmentLRUListHead.Flink; while (current_entry != &CacheSegmentLRUListHead && Target > 0) { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, CacheSegmentLRUListEntry); + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, + CacheSegmentLRUListEntry); current_entry = current_entry->Flink; Locked = ExTryToAcquireFastMutex(¤t->Lock); if (!Locked) @@ -229,6 +230,144 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty) return(STATUS_SUCCESS); } +NTSTATUS STATIC +CcRosCreateCacheSegment(PBCB Bcb, + ULONG FileOffset, + PCACHE_SEGMENT* CacheSeg, + BOOLEAN Lock) +{ + ULONG i; + PCACHE_SEGMENT current; + NTSTATUS Status; + KIRQL oldIrql; + + current = ExAllocatePoolWithTag(NonPagedPool, sizeof(CACHE_SEGMENT), + TAG_CSEG); + + MmLockAddressSpace(MmGetKernelAddressSpace()); + current->BaseAddress = NULL; + Status = MmCreateMemoryArea(KernelMode, + MmGetKernelAddressSpace(), + MEMORY_AREA_CACHE_SEGMENT, + ¤t->BaseAddress, + Bcb->CacheSegmentSize, + PAGE_READWRITE, + (PMEMORY_AREA*)¤t->MemoryArea, + FALSE); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + KeBugCheck(0); + } + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + current->Valid = FALSE; + current->Dirty = FALSE; + current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize); + current->Bcb = Bcb; + current->MappedCount = 0; + ExInitializeFastMutex(¤t->Lock); + current->ReferenceCount = 1; + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + InsertTailList(&Bcb->BcbSegmentListHead, ¤t->BcbSegmentListEntry); + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry); + InsertTailList(&CacheSegmentLRUListHead, + ¤t->CacheSegmentLRUListEntry); + current->DirtySegmentListEntry.Flink = + current->DirtySegmentListEntry.Blink = NULL; + if (Lock) + { + ExAcquireFastMutex(¤t->Lock); + } + ExReleaseFastMutex(&ViewLock); + for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++) + { + PVOID Page; + + Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(0); + } + + Status = MmCreateVirtualMapping(NULL, + current->BaseAddress + (i * PAGESIZE), + PAGE_READWRITE, + (ULONG)Page, + TRUE); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(0); + } + } + *CacheSeg = current; + return(STATUS_SUCCESS); +} + +NTSTATUS +CcRosGetCacheSegmentChain(PBCB Bcb, + ULONG FileOffset, + ULONG Length, + PCACHE_SEGMENT* CacheSeg) +{ + PCACHE_SEGMENT current; + ULONG i; + PCACHE_SEGMENT* CacheSegList; + PCACHE_SEGMENT Previous; + + Length = ROUND_UP(Length, Bcb->CacheSegmentSize); + + CacheSegList = alloca(sizeof(PCACHE_SEGMENT) * + (Length / Bcb->CacheSegmentSize)); + + /* + * Acquire the global lock. + */ + ExAcquireFastMutex(&ViewLock); + + /* + * Look for a cache segment already mapping the same data. + */ + for (i = 0; i < (Length / Bcb->CacheSegmentSize); i++) + { + ULONG CurrentOffset = FileOffset + (i * Bcb->CacheSegmentSize); + current = CcRosLookupCacheSegment(Bcb, CurrentOffset); + if (current != NULL) + { + /* + * Make sure the cache segment can't go away outside of our control. + */ + current->ReferenceCount++; + CacheSegList[i] = current; + } + else + { + CcRosCreateCacheSegment(Bcb, CurrentOffset, ¤t, FALSE); + CacheSegList[i] = current; + ExAcquireFastMutex(&ViewLock); + } + } + ExReleaseFastMutex(&ViewLock); + + for (i = 0; i < (Length / Bcb->CacheSegmentSize); i++) + { + ExAcquireFastMutex(&CacheSegList[i]->Lock); + if (i == 0) + { + *CacheSeg = CacheSegList[i]; + Previous = CacheSegList[i]; + } + else + { + Previous->NextInChain = CacheSegList[i]; + Previous = CacheSegList[i]; + } + } + Previous->NextInChain = NULL; + + return(STATUS_SUCCESS); +} + NTSTATUS CcRosGetCacheSegment(PBCB Bcb, ULONG FileOffset, @@ -238,9 +377,7 @@ CcRosGetCacheSegment(PBCB Bcb, PCACHE_SEGMENT* CacheSeg) { PCACHE_SEGMENT current; - ULONG i; NTSTATUS Status; - KIRQL oldIrql; /* * Acquire the global lock. @@ -267,6 +404,7 @@ CcRosGetCacheSegment(PBCB Bcb, */ *UptoDate = current->Valid; *BaseAddress = current->BaseAddress; + DPRINT("*BaseAddress 0x%.8X\n", *BaseAddress); *CacheSeg = current; *BaseOffset = current->FileOffset; return(STATUS_SUCCESS); @@ -275,64 +413,13 @@ CcRosGetCacheSegment(PBCB Bcb, /* * Otherwise create a new segment. */ - current = ExAllocatePoolWithTag(NonPagedPool, sizeof(CACHE_SEGMENT), - TAG_CSEG); - - MmLockAddressSpace(MmGetKernelAddressSpace()); - current->BaseAddress = NULL; - Status = MmCreateMemoryArea(KernelMode, - MmGetKernelAddressSpace(), - MEMORY_AREA_CACHE_SEGMENT, - ¤t->BaseAddress, - Bcb->CacheSegmentSize, - PAGE_READWRITE, - (PMEMORY_AREA*)¤t->MemoryArea, - FALSE); - if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - KeBugCheck(0); - } - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - current->Valid = FALSE; - current->Dirty = FALSE; - current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize); - current->Bcb = Bcb; - current->MappedCount = 0; - ExInitializeFastMutex(¤t->Lock); - current->ReferenceCount = 1; - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); - InsertTailList(&Bcb->BcbSegmentListHead, ¤t->BcbSegmentListEntry); - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry); - InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); - current->DirtySegmentListEntry.Flink = current->DirtySegmentListEntry.Blink = NULL; - ExAcquireFastMutex(¤t->Lock); - ExReleaseFastMutex(&ViewLock); + Status = CcRosCreateCacheSegment(Bcb, FileOffset, ¤t, TRUE); *UptoDate = current->Valid; *BaseAddress = current->BaseAddress; + DPRINT("*BaseAddress 0x%.8X\n", *BaseAddress); *CacheSeg = current; *BaseOffset = current->FileOffset; - for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++) - { - PVOID Page; - - Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(0); - } - - Status = MmCreateVirtualMapping(NULL, - current->BaseAddress + (i * PAGESIZE), - PAGE_READWRITE, - (ULONG)Page, - TRUE); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(0); - } - } + return(STATUS_SUCCESS); } @@ -364,8 +451,8 @@ CcRosRequestCacheSegment(PBCB Bcb, } STATIC VOID -CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr, - SWAPENTRY SwapEntry, BOOLEAN Dirty) +CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, + ULONG PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty) { assert(SwapEntry == 0); if (PhysAddr != 0) @@ -414,7 +501,8 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb) PLIST_ENTRY current_entry; PCACHE_SEGMENT current; - DPRINT("CcRosReleaseFileCache(FileObject %x, Bcb %x)\n", Bcb->FileObject, Bcb); + DPRINT("CcRosReleaseFileCache(FileObject %x, Bcb %x)\n", Bcb->FileObject, + Bcb); MmFreeSectionSegments(Bcb->FileObject); @@ -460,7 +548,8 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject, { (*Bcb)->AllocationSize = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->AllocationSize; - (*Bcb)->FileSize = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->FileSize; + (*Bcb)->FileSize = + ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->FileSize; } KeInitializeSpinLock(&(*Bcb)->BcbLock); InitializeListHead(&(*Bcb)->BcbSegmentListHead); diff --git a/reactos/ntoskrnl/include/internal/cc.h b/reactos/ntoskrnl/include/internal/cc.h index 09a47e66f2f..b8f264c83f7 100644 --- a/reactos/ntoskrnl/include/internal/cc.h +++ b/reactos/ntoskrnl/include/internal/cc.h @@ -1,6 +1,6 @@ #ifndef __INCLUDE_INTERNAL_CC_H #define __INCLUDE_INTERNAL_CC_H -/* $Id: cc.h,v 1.9 2001/12/31 01:53:44 dwelch Exp $ */ +/* $Id: cc.h,v 1.10 2002/01/26 21:21:02 dwelch Exp $ */ #include typedef struct _BCB @@ -17,7 +17,10 @@ typedef struct _CACHE_SEGMENT { /* Base address of the region where the cache segment data is mapped. */ PVOID BaseAddress; - /* Memory area representing the region where the cache segment data is mapped. */ + /* + * Memory area representing the region where the cache segment data is + * mapped. + */ struct _MEMORY_AREA* MemoryArea; /* Are the contents of the cache segment data valid. */ BOOLEAN Valid; @@ -39,6 +42,8 @@ typedef struct _CACHE_SEGMENT ULONG ReferenceCount; /* Pointer to the BCB for the file which this cache segment maps data for. */ PBCB Bcb; + /* Pointer to the next cache segment in a chain. */ + struct _CACHE_SEGMENT* NextInChain; } CACHE_SEGMENT; VOID STDCALL @@ -66,5 +71,9 @@ NTSTATUS CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty); NTSTATUS CcRosSuggestFreeCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty); - +NTSTATUS +CcRosGetCacheSegmentChain(PBCB Bcb, + ULONG FileOffset, + ULONG Length, + PCACHE_SEGMENT* CacheSeg); #endif diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index c8fa367a35d..e02d818dc47 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: ps.h,v 1.28 2002/01/15 02:51:32 dwelch Exp $ +/* $Id: ps.h,v 1.29 2002/01/26 21:21:02 dwelch Exp $ * * FILE: ntoskrnl/ke/kthread.c * PURPOSE: Process manager definitions @@ -285,7 +285,7 @@ typedef struct _ETHREAD */ struct _EPROCESS* OldProcess; /* 240/26C */ - PW32THREAD Win32Thread; + struct _W32THREAD* Win32Thread; } __attribute__((packed)) ETHREAD, *PETHREAD; @@ -354,12 +354,6 @@ typedef struct _KPROCESS UCHAR DisableBoost; /* 067 */ } KPROCESS, *PKPROCESS; - -typedef struct _W32PROCESS -{ -} __attribute__((packed)) W32PROCESS, *PW32PROCESS; - - struct _EPROCESS { /* Microkernel specific process state. */ @@ -459,7 +453,7 @@ struct _EPROCESS UCHAR SubSystemMinorVersion; UCHAR SubSystemMajorVersion; USHORT SubSystemVersion; - PW32PROCESS Win32Process; + struct _W32PROCESS* Win32Process; HANDLE Win32WindowStation; /* diff --git a/reactos/ntoskrnl/ps/win32.c b/reactos/ntoskrnl/ps/win32.c index d4af9a93598..a0df541a4d4 100644 --- a/reactos/ntoskrnl/ps/win32.c +++ b/reactos/ntoskrnl/ps/win32.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: win32.c,v 1.2 2002/01/13 22:52:07 dwelch Exp $ +/* $Id: win32.c,v 1.3 2002/01/26 21:21:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -31,12 +31,14 @@ #include #include +#include /* TYPES *******************************************************************/ /* GLOBALS ******************************************************************/ static ULONG PspWin32ProcessSize = 0; +static ULONG PspWin32ThreadSize = 0; /* FUNCTIONS ***************************************************************/ @@ -46,6 +48,29 @@ PsGetWin32Thread(VOID) return(PsGetCurrentThread()->Win32Thread); } +NTSTATUS STDCALL +PsCreateWin32Thread(PETHREAD Thread) +{ + if (Thread->Win32Thread != NULL) + return(STATUS_SUCCESS); + + Thread->Win32Thread = ExAllocatePool(NonPagedPool, + PspWin32ThreadSize); + if (Thread->Win32Thread == NULL) + return(STATUS_NO_MEMORY); + + RtlZeroMemory(Thread->Win32Thread, + PspWin32ThreadSize); + + return(STATUS_SUCCESS); +} + +PW32PROCESS STDCALL +PsGetWin32Process(VOID) +{ + return(PsGetCurrentProcess()->Win32Process); +} + NTSTATUS STDCALL PsCreateWin32Process(PEPROCESS Process) { @@ -69,10 +94,11 @@ PsEstablishWin32Callouts(PVOID Param1, PVOID Param2, PVOID Param3, PVOID Param4, - PVOID Param5, + ULONG W32ThreadSize, ULONG W32ProcessSize) { PspWin32ProcessSize = W32ProcessSize; + PspWin32ThreadSize = W32ThreadSize; } /* EOF */