mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Present large reads to the filesystem from CcCopyRead
svn path=/trunk/; revision=2561
This commit is contained in:
parent
b51e21217f
commit
aebf70e07f
5 changed files with 420 additions and 201 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 <ddk/ntifs.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 <ddk/ntddk.h>
|
||||
#include <internal/ps.h>
|
||||
#include <napi/win32.h>
|
||||
|
||||
/* 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 */
|
||||
|
|
Loading…
Reference in a new issue