From: Timo Kreuzer Date: Wed, 19 Dec 2012 11:11:34 +0000 (+0000) Subject: [NTOSKRNL] X-Git-Tag: backups/ros-csrss@60644~104^2~81 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=49a76c78e0605c65f3c0502247f6c227b31c3f05 [NTOSKRNL] Formatting, no functional change svn path=/trunk/; revision=57951 --- diff --git a/reactos/ntoskrnl/cc/copy.c b/reactos/ntoskrnl/cc/copy.c index 81f20a50715..784c517f9b6 100644 --- a/reactos/ntoskrnl/cc/copy.c +++ b/reactos/ntoskrnl/cc/copy.c @@ -17,8 +17,8 @@ static PFN_NUMBER CcZeroPage = 0; -#define MAX_ZERO_LENGTH (256 * 1024) -#define MAX_RW_LENGTH (256 * 1024) +#define MAX_ZERO_LENGTH (256 * 1024) +#define MAX_RW_LENGTH (256 * 1024) ULONG CcFastMdlReadWait; ULONG CcFastMdlReadNotPossible; @@ -31,160 +31,165 @@ ULONG CcFastReadResourceMiss; VOID NTAPI -MiZeroPhysicalPage( +MiZeroPhysicalPage ( IN PFN_NUMBER PageFrameIndex ); VOID NTAPI -CcInitCacheZeroPage(VOID) +CcInitCacheZeroPage ( + VOID) { - NTSTATUS Status; - - MI_SET_USAGE(MI_USAGE_CACHE); - //MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName); - Status = MmRequestPageMemoryConsumer(MC_SYSTEM, TRUE, &CcZeroPage); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Can't allocate CcZeroPage.\n"); - KeBugCheck(CACHE_MANAGER); - } - MiZeroPhysicalPage(CcZeroPage); + NTSTATUS Status; + + MI_SET_USAGE(MI_USAGE_CACHE); + //MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName); + Status = MmRequestPageMemoryConsumer(MC_SYSTEM, TRUE, &CcZeroPage); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Can't allocate CcZeroPage.\n"); + KeBugCheck(CACHE_MANAGER); + } + MiZeroPhysicalPage(CcZeroPage); } NTSTATUS NTAPI -ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length, - PVOID Buffer) +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; - KEVENT Event; - PMDL Mdl; - - Mdl = _alloca(MmSizeOfMdl(NULL, MAX_RW_LENGTH)); - - Status = CcRosGetCacheSegmentChain(Bcb, ReadOffset, Length, &head); - if (!NT_SUCCESS(Status)) + PCACHE_SEGMENT head; + PCACHE_SEGMENT current; + PCACHE_SEGMENT previous; + IO_STATUS_BLOCK Iosb; + LARGE_INTEGER SegOffset; + NTSTATUS Status; + ULONG TempLength; + KEVENT Event; + PMDL Mdl; + + Mdl = _alloca(MmSizeOfMdl(NULL, MAX_RW_LENGTH)); + + Status = CcRosGetCacheSegmentChain(Bcb, ReadOffset, Length, &head); + if (!NT_SUCCESS(Status)) { - return(Status); + return Status; } - current = head; - while (current != NULL) + 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 = (PVOID)((ULONG_PTR)Buffer + TempLength); - - Length = Length - TempLength; - previous = current; - current = current->NextInChain; - CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE); - } - /* - * Otherwise read in as much as we can. - */ - else - { - PCACHE_SEGMENT current2; - ULONG current_size; - ULONG i; - PPFN_NUMBER MdlPages; - - /* - * Count the maximum number of bytes we could read starting - * from the current segment. - */ - current2 = current; - current_size = 0; - while (current2 != NULL && !current2->Valid && current_size < MAX_RW_LENGTH) - { - current2 = current2->NextInChain; - current_size += Bcb->CacheSegmentSize; - } - - /* - * Create an MDL which contains all their pages. - */ - MmInitializeMdl(Mdl, NULL, current_size); - Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); - current2 = current; - current_size = 0; - MdlPages = (PPFN_NUMBER)(Mdl + 1); - while (current2 != NULL && !current2->Valid && current_size < MAX_RW_LENGTH) - { - PVOID address = current2->BaseAddress; - for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++, address = RVA(address, PAGE_SIZE)) - { - *MdlPages++ = MmGetPfnForProcess(NULL, address); - } - current2 = current2->NextInChain; - current_size += Bcb->CacheSegmentSize; - } - - /* - * Read in the information. - */ - SegOffset.QuadPart = current->FileOffset; - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Status = IoPageRead(Bcb->FileObject, - Mdl, - &SegOffset, - &Event, - &Iosb); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = Iosb.Status; - } - if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) - { - MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); - } - 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); - } - current_size = 0; - while (current != NULL && !current->Valid && current_size < MAX_RW_LENGTH) - { - previous = current; - current = current->NextInChain; - TempLength = min(Bcb->CacheSegmentSize, Length); - memcpy(Buffer, previous->BaseAddress, TempLength); - - Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength); - - Length = Length - TempLength; - CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE); - current_size += Bcb->CacheSegmentSize; - } - } + /* + * 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 = (PVOID)((ULONG_PTR)Buffer + TempLength); + + Length = Length - TempLength; + previous = current; + current = current->NextInChain; + CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE); + } + /* + * Otherwise read in as much as we can. + */ + else + { + PCACHE_SEGMENT current2; + ULONG current_size; + ULONG i; + PPFN_NUMBER MdlPages; + + /* + * Count the maximum number of bytes we could read starting + * from the current segment. + */ + current2 = current; + current_size = 0; + while ((current2 != NULL) && !current2->Valid && (current_size < MAX_RW_LENGTH)) + { + current2 = current2->NextInChain; + current_size += Bcb->CacheSegmentSize; + } + + /* + * Create an MDL which contains all their pages. + */ + MmInitializeMdl(Mdl, NULL, current_size); + Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); + current2 = current; + current_size = 0; + MdlPages = (PPFN_NUMBER)(Mdl + 1); + while ((current2 != NULL) && !current2->Valid && (current_size < MAX_RW_LENGTH)) + { + PVOID address = current2->BaseAddress; + for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++, address = RVA(address, PAGE_SIZE)) + { + *MdlPages++ = MmGetPfnForProcess(NULL, address); + } + current2 = current2->NextInChain; + current_size += Bcb->CacheSegmentSize; + } + + /* + * Read in the information. + */ + SegOffset.QuadPart = current->FileOffset; + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Status = IoPageRead(Bcb->FileObject, + Mdl, + &SegOffset, + &Event, + &Iosb); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = Iosb.Status; + } + if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) + { + MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); + } + 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; + } + current_size = 0; + while (current != NULL && !current->Valid && current_size < MAX_RW_LENGTH) + { + previous = current; + current = current->NextInChain; + TempLength = min(Bcb->CacheSegmentSize, Length); + memcpy(Buffer, previous->BaseAddress, TempLength); + + Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength); + + Length = Length - TempLength; + CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE); + current_size += Bcb->CacheSegmentSize; + } + } } - return(STATUS_SUCCESS); + return STATUS_SUCCESS; } NTSTATUS NTAPI -ReadCacheSegment(PCACHE_SEGMENT CacheSeg) +ReadCacheSegment ( + PCACHE_SEGMENT CacheSeg) { ULONG Size; PMDL Mdl; @@ -205,6 +210,7 @@ ReadCacheSegment(PCACHE_SEGMENT CacheSeg) { return STATUS_INSUFFICIENT_RESOURCES; } + MmBuildMdlForNonPagedPool(Mdl); Mdl->MdlFlags |= MDL_IO_PAGE_READ; KeInitializeEvent(&Event, NotificationEvent, FALSE); @@ -217,7 +223,7 @@ ReadCacheSegment(PCACHE_SEGMENT CacheSeg) IoFreeMdl(Mdl); - if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE) + if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) { DPRINT1("IoPageRead failed, Status %x\n", Status); return Status; @@ -226,7 +232,7 @@ ReadCacheSegment(PCACHE_SEGMENT CacheSeg) if (CacheSeg->Bcb->CacheSegmentSize > Size) { RtlZeroMemory((char*)CacheSeg->BaseAddress + Size, - CacheSeg->Bcb->CacheSegmentSize - Size); + CacheSeg->Bcb->CacheSegmentSize - Size); } return STATUS_SUCCESS; @@ -234,7 +240,8 @@ ReadCacheSegment(PCACHE_SEGMENT CacheSeg) NTSTATUS NTAPI -WriteCacheSegment(PCACHE_SEGMENT CacheSeg) +WriteCacheSegment ( + PCACHE_SEGMENT CacheSeg) { ULONG Size; PMDL Mdl; @@ -291,244 +298,254 @@ WriteCacheSegment(PCACHE_SEGMENT CacheSeg) /* * @unimplemented */ -BOOLEAN NTAPI +BOOLEAN +NTAPI CcCanIWrite ( - IN PFILE_OBJECT FileObject, - IN ULONG BytesToWrite, - IN BOOLEAN Wait, - IN BOOLEAN Retrying) + IN PFILE_OBJECT FileObject, + IN ULONG BytesToWrite, + IN BOOLEAN Wait, + IN BOOLEAN Retrying) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* * @implemented */ -BOOLEAN NTAPI -CcCopyRead (IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus) +BOOLEAN +NTAPI +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; - - DPRINT("CcCopyRead(FileObject 0x%p, FileOffset %I64x, " - "Length %d, Wait %d, Buffer 0x%p, IoStatus 0x%p)\n", - FileObject, FileOffset->QuadPart, Length, Wait, - Buffer, IoStatus); - - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - ReadOffset = (ULONG)FileOffset->QuadPart; - - DPRINT("AllocationSize %d, FileSize %d\n", - (ULONG)Bcb->AllocationSize.QuadPart, - (ULONG)Bcb->FileSize.QuadPart); - - /* - * Check for the nowait case that all the cache segments that would - * cover this read are in memory. - */ - if (!Wait) + 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 0x%p, FileOffset %I64x, " + "Length %d, Wait %d, Buffer 0x%p, IoStatus 0x%p)\n", + FileObject, FileOffset->QuadPart, Length, Wait, + Buffer, IoStatus); + + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + ReadOffset = (ULONG)FileOffset->QuadPart; + + DPRINT("AllocationSize %d, FileSize %d\n", + (ULONG)Bcb->AllocationSize.QuadPart, + (ULONG)Bcb->FileSize.QuadPart); + + /* + * 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); + 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 = 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; - CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); - return FALSE; - } - } - memcpy (Buffer, (char*)BaseAddress + ReadOffset % Bcb->CacheSegmentSize, - TempLength); - CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); - ReadLength += TempLength; - Length -= TempLength; - ReadOffset += TempLength; - Buffer = (PVOID)((char*)Buffer + TempLength); + 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; + CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); + return FALSE; + } + } + memcpy (Buffer, (char*)BaseAddress + ReadOffset % Bcb->CacheSegmentSize, + TempLength); + CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); + ReadLength += TempLength; + Length -= TempLength; + ReadOffset += TempLength; + Buffer = (PVOID)((char*)Buffer + TempLength); } - while (Length > 0) + + while (Length > 0) { - TempLength = min(max(Bcb->CacheSegmentSize, MAX_RW_LENGTH), Length); - Status = ReadCacheSegmentChain(Bcb, ReadOffset, TempLength, Buffer); - if (!NT_SUCCESS(Status)) + TempLength = min(max(Bcb->CacheSegmentSize, MAX_RW_LENGTH), Length); + Status = ReadCacheSegmentChain(Bcb, ReadOffset, TempLength, Buffer); + if (!NT_SUCCESS(Status)) { - IoStatus->Information = 0; - IoStatus->Status = Status; - DPRINT("ReadCacheSegmentChain failed, Status %x\n", Status); - return FALSE; + IoStatus->Information = 0; + IoStatus->Status = Status; + DPRINT("ReadCacheSegmentChain failed, Status %x\n", Status); + return FALSE; } - ReadLength += TempLength; - Length -= TempLength; - ReadOffset += TempLength; + ReadLength += TempLength; + Length -= TempLength; + ReadOffset += TempLength; - Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength); + Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength); } - IoStatus->Status = STATUS_SUCCESS; - IoStatus->Information = ReadLength; - DPRINT("CcCopyRead O.K.\n"); - return TRUE; + + IoStatus->Status = STATUS_SUCCESS; + IoStatus->Information = ReadLength; + DPRINT("CcCopyRead O.K.\n"); + return TRUE; } /* * @implemented */ -BOOLEAN NTAPI -CcCopyWrite (IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN PVOID Buffer) +BOOLEAN +NTAPI +CcCopyWrite ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN PVOID Buffer) { - NTSTATUS Status; - ULONG WriteOffset; - KIRQL oldirql; - PBCB Bcb; - PLIST_ENTRY current_entry; - PCACHE_SEGMENT CacheSeg; - ULONG TempLength; - PVOID BaseAddress; - BOOLEAN Valid; - - DPRINT("CcCopyWrite(FileObject 0x%p, FileOffset %I64x, " - "Length %d, Wait %d, Buffer 0x%p)\n", - FileObject, FileOffset->QuadPart, Length, Wait, Buffer); - - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - WriteOffset = (ULONG)FileOffset->QuadPart; - - if (!Wait) - { - /* testing, if the requested datas are available */ - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - current_entry = Bcb->BcbSegmentListHead.Flink; - while (current_entry != &Bcb->BcbSegmentListHead) - { - CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, - BcbSegmentListEntry); - if (!CacheSeg->Valid) - { - if ((WriteOffset >= CacheSeg->FileOffset && - WriteOffset < CacheSeg->FileOffset + Bcb->CacheSegmentSize) - || (WriteOffset + Length > CacheSeg->FileOffset && - WriteOffset + Length <= CacheSeg->FileOffset + - Bcb->CacheSegmentSize)) - { - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - /* datas not available */ - return(FALSE); - } - } - current_entry = current_entry->Flink; - } - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - } - - TempLength = WriteOffset % Bcb->CacheSegmentSize; - if (TempLength != 0) - { - ULONG ROffset; - ROffset = ROUND_DOWN(WriteOffset, Bcb->CacheSegmentSize); - TempLength = min (Length, Bcb->CacheSegmentSize - TempLength); - Status = CcRosRequestCacheSegment(Bcb, ROffset, - &BaseAddress, &Valid, &CacheSeg); - if (!NT_SUCCESS(Status)) - { - return(FALSE); - } - if (!Valid) - { - if (!NT_SUCCESS(ReadCacheSegment(CacheSeg))) - { - return(FALSE); - } - } - memcpy ((char*)BaseAddress + WriteOffset % Bcb->CacheSegmentSize, - Buffer, TempLength); - CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE); - - Length -= TempLength; - WriteOffset += TempLength; - - Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength); - } - - while (Length > 0) - { - TempLength = min (Bcb->CacheSegmentSize, Length); - Status = CcRosRequestCacheSegment(Bcb, WriteOffset, - &BaseAddress, &Valid, &CacheSeg); - if (!NT_SUCCESS(Status)) - { - return(FALSE); - } - if (!Valid && TempLength < Bcb->CacheSegmentSize) - { - if (!NT_SUCCESS(ReadCacheSegment(CacheSeg))) - { - CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); - return FALSE; - } - } - memcpy (BaseAddress, Buffer, TempLength); - CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE); - Length -= TempLength; - WriteOffset += TempLength; - - Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength); - } - return(TRUE); + NTSTATUS Status; + ULONG WriteOffset; + KIRQL oldirql; + PBCB Bcb; + PLIST_ENTRY current_entry; + PCACHE_SEGMENT CacheSeg; + ULONG TempLength; + PVOID BaseAddress; + BOOLEAN Valid; + + DPRINT("CcCopyWrite(FileObject 0x%p, FileOffset %I64x, " + "Length %d, Wait %d, Buffer 0x%p)\n", + FileObject, FileOffset->QuadPart, Length, Wait, Buffer); + + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + WriteOffset = (ULONG)FileOffset->QuadPart; + + if (!Wait) + { + /* testing, if the requested datas are available */ + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + current_entry = Bcb->BcbSegmentListHead.Flink; + while (current_entry != &Bcb->BcbSegmentListHead) + { + CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, + BcbSegmentListEntry); + if (!CacheSeg->Valid) + { + if (((WriteOffset >= CacheSeg->FileOffset) && + (WriteOffset < CacheSeg->FileOffset + Bcb->CacheSegmentSize)) + || ((WriteOffset + Length > CacheSeg->FileOffset) && + (WriteOffset + Length <= CacheSeg->FileOffset + + Bcb->CacheSegmentSize))) + { + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + /* datas not available */ + return FALSE; + } + } + current_entry = current_entry->Flink; + } + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + } + + TempLength = WriteOffset % Bcb->CacheSegmentSize; + if (TempLength != 0) + { + ULONG ROffset; + ROffset = ROUND_DOWN(WriteOffset, Bcb->CacheSegmentSize); + TempLength = min (Length, Bcb->CacheSegmentSize - TempLength); + Status = CcRosRequestCacheSegment(Bcb, ROffset, + &BaseAddress, &Valid, &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + if (!Valid) + { + if (!NT_SUCCESS(ReadCacheSegment(CacheSeg))) + { + return FALSE; + } + } + memcpy ((char*)BaseAddress + WriteOffset % Bcb->CacheSegmentSize, + Buffer, TempLength); + CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE); + + Length -= TempLength; + WriteOffset += TempLength; + + Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength); + } + + while (Length > 0) + { + TempLength = min (Bcb->CacheSegmentSize, Length); + Status = CcRosRequestCacheSegment(Bcb, + WriteOffset, + &BaseAddress, + &Valid, + &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + if (!Valid && TempLength < Bcb->CacheSegmentSize) + { + if (!NT_SUCCESS(ReadCacheSegment(CacheSeg))) + { + CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); + return FALSE; + } + } + memcpy (BaseAddress, Buffer, TempLength); + CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE); + Length -= TempLength; + WriteOffset += TempLength; + + Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength); + } + return TRUE; } /* @@ -537,15 +554,14 @@ CcCopyWrite (IN PFILE_OBJECT FileObject, VOID NTAPI CcDeferWrite ( - IN PFILE_OBJECT FileObject, - IN PCC_POST_DEFERRED_WRITE PostRoutine, - IN PVOID Context1, - IN PVOID Context2, - IN ULONG BytesToWrite, - IN BOOLEAN Retrying - ) + IN PFILE_OBJECT FileObject, + IN PCC_POST_DEFERRED_WRITE PostRoutine, + IN PVOID Context1, + IN PVOID Context2, + IN ULONG BytesToWrite, + IN BOOLEAN Retrying) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -554,28 +570,27 @@ CcDeferWrite ( VOID NTAPI CcFastCopyRead ( - IN PFILE_OBJECT FileObject, - IN ULONG FileOffset, - IN ULONG Length, - IN ULONG PageCount, + IN PFILE_OBJECT FileObject, + IN ULONG FileOffset, + IN ULONG Length, + IN ULONG PageCount, OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus - ) + OUT PIO_STATUS_BLOCK IoStatus) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* * @unimplemented */ VOID NTAPI -CcFastCopyWrite( - IN PFILE_OBJECT FileObject, - IN ULONG FileOffset, - IN ULONG Length, - IN PVOID Buffer) +CcFastCopyWrite ( + IN PFILE_OBJECT FileObject, + IN ULONG FileOffset, + IN ULONG Length, + IN PVOID Buffer) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -584,174 +599,177 @@ CcFastCopyWrite( NTSTATUS NTAPI CcWaitForCurrentLazyWriterActivity ( - VOID - ) + VOID) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } /* * @implemented */ -BOOLEAN NTAPI -CcZeroData (IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER StartOffset, - IN PLARGE_INTEGER EndOffset, - IN BOOLEAN Wait) +BOOLEAN +NTAPI +CcZeroData ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER StartOffset, + IN PLARGE_INTEGER EndOffset, + IN BOOLEAN Wait) { - NTSTATUS Status; - LARGE_INTEGER WriteOffset; - ULONG Length; - ULONG CurrentLength; - PMDL Mdl; - ULONG i; - IO_STATUS_BLOCK Iosb; - KEVENT Event; - - DPRINT("CcZeroData(FileObject 0x%p, StartOffset %I64x, EndOffset %I64x, " - "Wait %d)\n", FileObject, StartOffset->QuadPart, EndOffset->QuadPart, - Wait); - - Length = EndOffset->u.LowPart - StartOffset->u.LowPart; - WriteOffset.QuadPart = StartOffset->QuadPart; - - if (FileObject->SectionObjectPointer->SharedCacheMap == NULL) + NTSTATUS Status; + LARGE_INTEGER WriteOffset; + ULONG Length; + ULONG CurrentLength; + PMDL Mdl; + ULONG i; + IO_STATUS_BLOCK Iosb; + KEVENT Event; + + DPRINT("CcZeroData(FileObject 0x%p, StartOffset %I64x, EndOffset %I64x, " + "Wait %d)\n", FileObject, StartOffset->QuadPart, EndOffset->QuadPart, + Wait); + + Length = EndOffset->u.LowPart - StartOffset->u.LowPart; + WriteOffset.QuadPart = StartOffset->QuadPart; + + if (FileObject->SectionObjectPointer->SharedCacheMap == NULL) { - /* File is not cached */ - - Mdl = _alloca(MmSizeOfMdl(NULL, MAX_ZERO_LENGTH)); - - while (Length > 0) - { - if (Length + WriteOffset.u.LowPart % PAGE_SIZE > MAX_ZERO_LENGTH) - { - CurrentLength = MAX_ZERO_LENGTH - WriteOffset.u.LowPart % PAGE_SIZE; - } - else - { - CurrentLength = Length; - } - MmInitializeMdl(Mdl, (PVOID)(ULONG_PTR)WriteOffset.QuadPart, CurrentLength); - Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); - for (i = 0; i < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); i++) - { - ((PPFN_NUMBER)(Mdl + 1))[i] = CcZeroPage; - } - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Status = IoSynchronousPageWrite(FileObject, Mdl, &WriteOffset, &Event, &Iosb); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = Iosb.Status; - } - if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) + /* File is not cached */ + + Mdl = _alloca(MmSizeOfMdl(NULL, MAX_ZERO_LENGTH)); + + while (Length > 0) { - MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); + if (Length + WriteOffset.u.LowPart % PAGE_SIZE > MAX_ZERO_LENGTH) + { + CurrentLength = MAX_ZERO_LENGTH - WriteOffset.u.LowPart % PAGE_SIZE; + } + else + { + CurrentLength = Length; + } + MmInitializeMdl(Mdl, (PVOID)(ULONG_PTR)WriteOffset.QuadPart, CurrentLength); + Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); + for (i = 0; i < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); i++) + { + ((PPFN_NUMBER)(Mdl + 1))[i] = CcZeroPage; + } + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Status = IoSynchronousPageWrite(FileObject, Mdl, &WriteOffset, &Event, &Iosb); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = Iosb.Status; + } + if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) + { + MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); + } + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + WriteOffset.QuadPart += CurrentLength; + Length -= CurrentLength; } - if (!NT_SUCCESS(Status)) - { - return(FALSE); - } - WriteOffset.QuadPart += CurrentLength; - Length -= CurrentLength; - } } - else + else { - /* File is cached */ - KIRQL oldirql; - PBCB Bcb; - PLIST_ENTRY current_entry; - PCACHE_SEGMENT CacheSeg, current, previous; - ULONG TempLength; - - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - if (Wait) - { - /* testing, if the requested datas are available */ - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - current_entry = Bcb->BcbSegmentListHead.Flink; - while (current_entry != &Bcb->BcbSegmentListHead) - { - CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, - BcbSegmentListEntry); - if (!CacheSeg->Valid) - { - if ((WriteOffset.u.LowPart >= CacheSeg->FileOffset && - WriteOffset.u.LowPart < CacheSeg->FileOffset + Bcb->CacheSegmentSize) - || (WriteOffset.u.LowPart + Length > CacheSeg->FileOffset && - WriteOffset.u.LowPart + Length <= - CacheSeg->FileOffset + Bcb->CacheSegmentSize)) - { - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - /* datas not available */ - return(FALSE); - } - } - current_entry = current_entry->Flink; - } - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - } - while (Length > 0) - { - ULONG Offset; - Offset = WriteOffset.u.LowPart % Bcb->CacheSegmentSize; - if (Length + Offset > MAX_ZERO_LENGTH) - { - CurrentLength = MAX_ZERO_LENGTH - Offset; - } - else - { - CurrentLength = Length; - } - Status = CcRosGetCacheSegmentChain (Bcb, WriteOffset.u.LowPart - Offset, - Offset + CurrentLength, &CacheSeg); - if (!NT_SUCCESS(Status)) - { - return FALSE; - } - current = CacheSeg; - - while (current != NULL) - { - Offset = WriteOffset.u.LowPart % Bcb->CacheSegmentSize; - if (Offset != 0 || - Offset + CurrentLength < Bcb->CacheSegmentSize) - { - if (!current->Valid) - { - /* read the segment */ - Status = ReadCacheSegment(current); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ReadCacheSegment failed, status %x\n", - Status); - } - } - TempLength = min (CurrentLength, Bcb->CacheSegmentSize - Offset); - } - else - { - TempLength = Bcb->CacheSegmentSize; - } - memset ((PUCHAR)current->BaseAddress + Offset, 0, TempLength); - - WriteOffset.QuadPart += TempLength; - CurrentLength -= TempLength; - Length -= TempLength; - - current = current->NextInChain; - } - - current = CacheSeg; - while (current != NULL) - { - previous = current; - current = current->NextInChain; - CcRosReleaseCacheSegment(Bcb, previous, TRUE, TRUE, FALSE); - } - } + /* File is cached */ + KIRQL oldirql; + PBCB Bcb; + PLIST_ENTRY current_entry; + PCACHE_SEGMENT CacheSeg, current, previous; + ULONG TempLength; + + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + if (Wait) + { + /* testing, if the requested datas are available */ + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + current_entry = Bcb->BcbSegmentListHead.Flink; + while (current_entry != &Bcb->BcbSegmentListHead) + { + CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, + BcbSegmentListEntry); + if (!CacheSeg->Valid) + { + if (((WriteOffset.u.LowPart >= CacheSeg->FileOffset) && + (WriteOffset.u.LowPart < CacheSeg->FileOffset + Bcb->CacheSegmentSize)) + || ((WriteOffset.u.LowPart + Length > CacheSeg->FileOffset) && + (WriteOffset.u.LowPart + Length <= + CacheSeg->FileOffset + Bcb->CacheSegmentSize))) + { + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + /* datas not available */ + return FALSE; + } + } + current_entry = current_entry->Flink; + } + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + } + + while (Length > 0) + { + ULONG Offset; + Offset = WriteOffset.u.LowPart % Bcb->CacheSegmentSize; + if (Length + Offset > MAX_ZERO_LENGTH) + { + CurrentLength = MAX_ZERO_LENGTH - Offset; + } + else + { + CurrentLength = Length; + } + Status = CcRosGetCacheSegmentChain (Bcb, WriteOffset.u.LowPart - Offset, + Offset + CurrentLength, &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + current = CacheSeg; + + while (current != NULL) + { + Offset = WriteOffset.u.LowPart % Bcb->CacheSegmentSize; + if ((Offset != 0) || + (Offset + CurrentLength < Bcb->CacheSegmentSize)) + { + if (!current->Valid) + { + /* read the segment */ + Status = ReadCacheSegment(current); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ReadCacheSegment failed, status %x\n", + Status); + } + } + TempLength = min (CurrentLength, Bcb->CacheSegmentSize - Offset); + } + else + { + TempLength = Bcb->CacheSegmentSize; + } + memset ((PUCHAR)current->BaseAddress + Offset, 0, TempLength); + + WriteOffset.QuadPart += TempLength; + CurrentLength -= TempLength; + Length -= TempLength; + + current = current->NextInChain; + } + + current = CacheSeg; + while (current != NULL) + { + previous = current; + current = current->NextInChain; + CcRosReleaseCacheSegment(Bcb, previous, TRUE, TRUE, FALSE); + } + } } - return(TRUE); + + return TRUE; } diff --git a/reactos/ntoskrnl/cc/fs.c b/reactos/ntoskrnl/cc/fs.c index e2e4c2d0148..322ca103db6 100644 --- a/reactos/ntoskrnl/cc/fs.c +++ b/reactos/ntoskrnl/cc/fs.c @@ -32,16 +32,15 @@ NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg); LARGE_INTEGER NTAPI CcGetDirtyPages ( - IN PVOID LogHandle, - IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine, - IN PVOID Context1, - IN PVOID Context2 - ) + IN PVOID LogHandle, + IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine, + IN PVOID Context1, + IN PVOID Context2) { - LARGE_INTEGER i; - UNIMPLEMENTED; - i.QuadPart = 0; - return i; + LARGE_INTEGER i; + UNIMPLEMENTED; + i.QuadPart = 0; + return i; } /* @@ -50,11 +49,10 @@ CcGetDirtyPages ( PFILE_OBJECT NTAPI CcGetFileObjectFromBcb ( - IN PVOID Bcb - ) + IN PVOID Bcb) { - PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb; - return iBcb->CacheSegment->Bcb->FileObject; + PINTERNAL_BCB iBcb = (PINTERNAL_BCB)Bcb; + return iBcb->CacheSegment->Bcb->FileObject; } /* @@ -63,14 +61,13 @@ CcGetFileObjectFromBcb ( LARGE_INTEGER NTAPI CcGetLsnForFileObject ( - IN PFILE_OBJECT FileObject, - OUT PLARGE_INTEGER OldestLsn OPTIONAL - ) + IN PFILE_OBJECT FileObject, + OUT PLARGE_INTEGER OldestLsn OPTIONAL) { - LARGE_INTEGER i; - UNIMPLEMENTED; - i.QuadPart = 0; - return i; + LARGE_INTEGER i; + UNIMPLEMENTED; + i.QuadPart = 0; + return i; } /* @@ -79,20 +76,19 @@ CcGetLsnForFileObject ( VOID NTAPI CcInitializeCacheMap ( - IN PFILE_OBJECT FileObject, - IN PCC_FILE_SIZES FileSizes, - IN BOOLEAN PinAccess, - IN PCACHE_MANAGER_CALLBACKS CallBacks, - IN PVOID LazyWriterContext - ) + IN PFILE_OBJECT FileObject, + IN PCC_FILE_SIZES FileSizes, + IN BOOLEAN PinAccess, + IN PCACHE_MANAGER_CALLBACKS CallBacks, + IN PVOID LazyWriterContext) { ASSERT(FileObject); ASSERT(FileSizes); /* Call old ROS cache init function */ CcRosInitializeFileCache(FileObject, - /*PAGE_SIZE*/ VACB_MAPPING_GRANULARITY, CallBacks, - LazyWriterContext); + /*PAGE_SIZE*/ VACB_MAPPING_GRANULARITY, CallBacks, + LazyWriterContext); } /* @@ -101,11 +97,10 @@ CcInitializeCacheMap ( BOOLEAN NTAPI CcIsThereDirtyData ( - IN PVPB Vpb - ) + IN PVPB Vpb) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -114,14 +109,13 @@ CcIsThereDirtyData ( BOOLEAN NTAPI CcPurgeCacheSection ( - IN PSECTION_OBJECT_POINTERS SectionObjectPointer, - IN PLARGE_INTEGER FileOffset OPTIONAL, - IN ULONG Length, - IN BOOLEAN UninitializeCacheMaps - ) + IN PSECTION_OBJECT_POINTERS SectionObjectPointer, + IN PLARGE_INTEGER FileOffset OPTIONAL, + IN ULONG Length, + IN BOOLEAN UninitializeCacheMaps) { - //UNIMPLEMENTED; - return FALSE; + //UNIMPLEMENTED; + return FALSE; } @@ -129,91 +123,92 @@ CcPurgeCacheSection ( * @implemented */ VOID NTAPI -CcSetFileSizes (IN PFILE_OBJECT FileObject, - IN PCC_FILE_SIZES FileSizes) +CcSetFileSizes ( + IN PFILE_OBJECT FileObject, + IN PCC_FILE_SIZES FileSizes) { - KIRQL oldirql; - PBCB Bcb; - PLIST_ENTRY current_entry; - PCACHE_SEGMENT current; - LIST_ENTRY FreeListHead; - NTSTATUS Status; + KIRQL oldirql; + PBCB Bcb; + PLIST_ENTRY current_entry; + PCACHE_SEGMENT current; + LIST_ENTRY FreeListHead; + NTSTATUS Status; - DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n", - FileObject, FileSizes); - DPRINT("AllocationSize %d, FileSize %d, ValidDataLength %d\n", - (ULONG)FileSizes->AllocationSize.QuadPart, - (ULONG)FileSizes->FileSize.QuadPart, - (ULONG)FileSizes->ValidDataLength.QuadPart); + DPRINT("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n", + FileObject, FileSizes); + DPRINT("AllocationSize %d, FileSize %d, ValidDataLength %d\n", + (ULONG)FileSizes->AllocationSize.QuadPart, + (ULONG)FileSizes->FileSize.QuadPart, + (ULONG)FileSizes->ValidDataLength.QuadPart); - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - /* - * It is valid to call this function on file objects that weren't - * initialized for caching. In this case it's simple no-op. - */ - if (Bcb == NULL) - return; + /* + * It is valid to call this function on file objects that weren't + * initialized for caching. In this case it's simple no-op. + */ + if (Bcb == NULL) + return; - if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart) - { - InitializeListHead(&FreeListHead); - KeAcquireGuardedMutex(&ViewLock); - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart) + { + InitializeListHead(&FreeListHead); + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - current_entry = Bcb->BcbSegmentListHead.Flink; - while (current_entry != &Bcb->BcbSegmentListHead) - { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); - current_entry = current_entry->Flink; - if (current->FileOffset > FileSizes->AllocationSize.QuadPart || - (current->FileOffset == 0 && FileSizes->AllocationSize.QuadPart == 0)) - { - if (current->ReferenceCount == 0 || (current->ReferenceCount == 1 && current->Dirty)) - { - RemoveEntryList(¤t->BcbSegmentListEntry); - RemoveEntryList(¤t->CacheSegmentListEntry); - RemoveEntryList(¤t->CacheSegmentLRUListEntry); - if (current->Dirty) - { - RemoveEntryList(¤t->DirtySegmentListEntry); - DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; - } - InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry); - } - else - { - DPRINT1("Anyone has referenced a cache segment behind the new size.\n"); - KeBugCheck(CACHE_MANAGER); - } - } - } + current_entry = Bcb->BcbSegmentListHead.Flink; + while (current_entry != &Bcb->BcbSegmentListHead) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); + current_entry = current_entry->Flink; + if (current->FileOffset > FileSizes->AllocationSize.QuadPart || + (current->FileOffset == 0 && FileSizes->AllocationSize.QuadPart == 0)) + { + if ((current->ReferenceCount == 0) || ((current->ReferenceCount == 1) && current->Dirty)) + { + RemoveEntryList(¤t->BcbSegmentListEntry); + RemoveEntryList(¤t->CacheSegmentListEntry); + RemoveEntryList(¤t->CacheSegmentLRUListEntry); + if (current->Dirty) + { + RemoveEntryList(¤t->DirtySegmentListEntry); + DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; + } + InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry); + } + else + { + DPRINT1("Anyone has referenced a cache segment behind the new size.\n"); + KeBugCheck(CACHE_MANAGER); + } + } + } - Bcb->AllocationSize = FileSizes->AllocationSize; - Bcb->FileSize = FileSizes->FileSize; - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - KeReleaseGuardedMutex(&ViewLock); + Bcb->AllocationSize = FileSizes->AllocationSize; + Bcb->FileSize = FileSizes->FileSize; + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + KeReleaseGuardedMutex(&ViewLock); - current_entry = FreeListHead.Flink; - while(current_entry != &FreeListHead) - { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); - current_entry = current_entry->Flink; - Status = CcRosInternalFreeCacheSegment(current); - if (!NT_SUCCESS(Status)) + current_entry = FreeListHead.Flink; + while(current_entry != &FreeListHead) { - DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n", Status); - KeBugCheck(CACHE_MANAGER); + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); + current_entry = current_entry->Flink; + Status = CcRosInternalFreeCacheSegment(current); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n", Status); + KeBugCheck(CACHE_MANAGER); + } } - } - } - else - { - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - Bcb->AllocationSize = FileSizes->AllocationSize; - Bcb->FileSize = FileSizes->FileSize; - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - } + } + else + { + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + Bcb->AllocationSize = FileSizes->AllocationSize; + Bcb->FileSize = FileSizes->FileSize; + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + } } /* @@ -222,12 +217,11 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject, VOID NTAPI CcSetLogHandleForFile ( - IN PFILE_OBJECT FileObject, - IN PVOID LogHandle, - IN PFLUSH_TO_LSN FlushToLsnRoutine - ) + IN PFILE_OBJECT FileObject, + IN PVOID LogHandle, + IN PFLUSH_TO_LSN FlushToLsnRoutine) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -236,14 +230,13 @@ CcSetLogHandleForFile ( BOOLEAN NTAPI CcUninitializeCacheMap ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER TruncateSize OPTIONAL, - IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL - ) + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER TruncateSize OPTIONAL, + IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL) { #if 0 - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; #else return NT_SUCCESS(CcRosReleaseFileCache(FileObject)); #endif @@ -251,18 +244,18 @@ CcUninitializeCacheMap ( BOOLEAN NTAPI -CcGetFileSizes -(IN PFILE_OBJECT FileObject, - IN PCC_FILE_SIZES FileSizes) +CcGetFileSizes ( + IN PFILE_OBJECT FileObject, + IN PCC_FILE_SIZES FileSizes) { - PBCB Bcb; - - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + PBCB Bcb; + + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - if (!Bcb) - return FALSE; + if (!Bcb) + return FALSE; - FileSizes->AllocationSize = Bcb->AllocationSize; - FileSizes->FileSize = FileSizes->ValidDataLength = Bcb->FileSize; - return TRUE; + FileSizes->AllocationSize = Bcb->AllocationSize; + FileSizes->FileSize = FileSizes->ValidDataLength = Bcb->FileSize; + return TRUE; } diff --git a/reactos/ntoskrnl/cc/mdl.c b/reactos/ntoskrnl/cc/mdl.c index 0d1419a8ebb..bcd50309555 100644 --- a/reactos/ntoskrnl/cc/mdl.c +++ b/reactos/ntoskrnl/cc/mdl.c @@ -20,19 +20,19 @@ */ VOID NTAPI -CcMdlRead( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - OUT PMDL * MdlChain, - OUT PIO_STATUS_BLOCK IoStatus - ) +CcMdlRead ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + OUT PMDL * MdlChain, + OUT PIO_STATUS_BLOCK IoStatus + ) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* - * NAME INTERNAL + * NAME INTERNAL * CcMdlReadComplete2@8 * * DESCRIPTION @@ -45,13 +45,14 @@ CcMdlRead( * None. * * NOTE - * Used by CcMdlReadComplete@8 and FsRtl + * Used by CcMdlReadComplete@8 and FsRtl * */ VOID NTAPI -CcMdlReadComplete2(IN PMDL MemoryDescriptorList, - IN PFILE_OBJECT FileObject) +CcMdlReadComplete2 ( + IN PMDL MemoryDescriptorList, + IN PFILE_OBJECT FileObject) { PMDL Mdl; @@ -82,8 +83,9 @@ CcMdlReadComplete2(IN PMDL MemoryDescriptorList, */ VOID NTAPI -CcMdlReadComplete(IN PFILE_OBJECT FileObject, - IN PMDL MdlChain) +CcMdlReadComplete ( + IN PFILE_OBJECT FileObject, + IN PMDL MdlChain) { PDEVICE_OBJECT DeviceObject = NULL; PFAST_IO_DISPATCH FastDispatch; @@ -110,9 +112,10 @@ CcMdlReadComplete(IN PFILE_OBJECT FileObject, */ VOID NTAPI -CcMdlWriteComplete(IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN PMDL MdlChain) +CcMdlWriteComplete ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain) { PDEVICE_OBJECT DeviceObject = NULL; PFAST_IO_DISPATCH FastDispatch; @@ -137,11 +140,10 @@ CcMdlWriteComplete(IN PFILE_OBJECT FileObject, VOID NTAPI -CcMdlWriteComplete2( +CcMdlWriteComplete2 ( IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, - IN PMDL MdlChain -) + IN PMDL MdlChain) { UNIMPLEMENTED; } @@ -153,10 +155,9 @@ VOID NTAPI CcMdlWriteAbort ( IN PFILE_OBJECT FileObject, - IN PMDL MdlChain - ) + IN PMDL MdlChain) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -165,12 +166,11 @@ CcMdlWriteAbort ( VOID NTAPI CcPrepareMdlWrite ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - OUT PMDL * MdlChain, - OUT PIO_STATUS_BLOCK IoStatus - ) + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + OUT PMDL * MdlChain, + OUT PIO_STATUS_BLOCK IoStatus) { - UNIMPLEMENTED; + UNIMPLEMENTED; } diff --git a/reactos/ntoskrnl/cc/pin.c b/reactos/ntoskrnl/cc/pin.c index d6e764a25a4..9b71078110f 100644 --- a/reactos/ntoskrnl/cc/pin.c +++ b/reactos/ntoskrnl/cc/pin.c @@ -24,13 +24,13 @@ extern NPAGED_LOOKASIDE_LIST iBcbLookasideList; */ BOOLEAN NTAPI -CcMapData( +CcMapData ( IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG Flags, - OUT PVOID *pBcb, - OUT PVOID *pBuffer) + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG Flags, + OUT PVOID *pBcb, + OUT PVOID *pBuffer) { ULONG ReadOffset; BOOLEAN Valid; @@ -61,14 +61,18 @@ CcMapData( { return FALSE; } - ROffset = ROUND_DOWN (ReadOffset, Bcb->CacheSegmentSize); - Status = CcRosRequestCacheSegment(Bcb, ROffset, - pBuffer, &Valid, + + ROffset = ROUND_DOWN(ReadOffset, Bcb->CacheSegmentSize); + Status = CcRosRequestCacheSegment(Bcb, + ROffset, + pBuffer, + &Valid, &CacheSeg); if (!NT_SUCCESS(Status)) { return FALSE; } + if (!Valid) { if (!(Flags & MAP_WAIT)) @@ -76,10 +80,11 @@ CcMapData( CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); return FALSE; } + if (!NT_SUCCESS(ReadCacheSegment(CacheSeg))) { CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); - return FALSE; + return FALSE; } } @@ -90,6 +95,7 @@ CcMapData( CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); return FALSE; } + memset(iBcb, 0, sizeof(INTERNAL_BCB)); iBcb->PFCB.NodeTypeCode = 0xDE45; /* Undocumented (CAPTIVE_PUBLIC_BCB_NODETYPECODE) */ iBcb->PFCB.NodeByteSize = sizeof(PUBLIC_BCB); @@ -99,6 +105,7 @@ CcMapData( iBcb->Dirty = FALSE; iBcb->RefCount = 1; *pBcb = (PVOID)iBcb; + return TRUE; } @@ -108,15 +115,14 @@ CcMapData( BOOLEAN NTAPI CcPinMappedData ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG Flags, - OUT PVOID * Bcb - ) + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG Flags, + OUT PVOID * Bcb) { - /* no-op for current implementation. */ - return TRUE; + /* no-op for current implementation. */ + return TRUE; } /* @@ -125,22 +131,21 @@ CcPinMappedData ( BOOLEAN NTAPI CcPinRead ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN ULONG Flags, - OUT PVOID * Bcb, - OUT PVOID * Buffer - ) + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG Flags, + OUT PVOID * Bcb, + OUT PVOID * Buffer) { - if (CcMapData(FileObject, FileOffset, Length, Flags, Bcb, Buffer)) - { - if (CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb)) - return TRUE; - else - CcUnpinData(Bcb); - } - return FALSE; + if (CcMapData(FileObject, FileOffset, Length, Flags, Bcb, Buffer)) + { + if (CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb)) + return TRUE; + else + CcUnpinData(Bcb); + } + return FALSE; } /* @@ -149,35 +154,35 @@ CcPinRead ( BOOLEAN NTAPI CcPreparePinWrite ( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Zero, - IN ULONG Flags, - OUT PVOID * Bcb, - OUT PVOID * Buffer - ) + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Zero, + IN ULONG Flags, + OUT PVOID * Bcb, + OUT PVOID * Buffer) { - /* - * 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. - */ - return CcPinRead(FileObject, FileOffset, Length, Flags, Bcb, Buffer); + /* + * 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. + */ + return CcPinRead(FileObject, FileOffset, Length, Flags, Bcb, Buffer); } /* * @implemented */ VOID NTAPI -CcSetDirtyPinnedData (IN PVOID Bcb, - IN PLARGE_INTEGER Lsn) +CcSetDirtyPinnedData ( + IN PVOID Bcb, + IN PLARGE_INTEGER Lsn) { - PINTERNAL_BCB iBcb = Bcb; - iBcb->Dirty = TRUE; + PINTERNAL_BCB iBcb = Bcb; + iBcb->Dirty = TRUE; } @@ -185,15 +190,20 @@ CcSetDirtyPinnedData (IN PVOID Bcb, * @implemented */ VOID NTAPI -CcUnpinData (IN PVOID Bcb) +CcUnpinData ( + IN PVOID Bcb) { - PINTERNAL_BCB iBcb = Bcb; - CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE, - iBcb->Dirty, FALSE); - if (--iBcb->RefCount == 0) - { - ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); - } + PINTERNAL_BCB iBcb = Bcb; + + CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, + iBcb->CacheSegment, + TRUE, + iBcb->Dirty, + FALSE); + if (--iBcb->RefCount == 0) + { + ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); + } } /* @@ -202,11 +212,10 @@ CcUnpinData (IN PVOID Bcb) VOID NTAPI CcUnpinDataForThread ( - IN PVOID Bcb, - IN ERESOURCE_THREAD ResourceThreadId - ) + IN PVOID Bcb, + IN ERESOURCE_THREAD ResourceThreadId) { - UNIMPLEMENTED; + UNIMPLEMENTED; } /* @@ -215,11 +224,10 @@ CcUnpinDataForThread ( VOID NTAPI CcRepinBcb ( - IN PVOID Bcb - ) + IN PVOID Bcb) { - PINTERNAL_BCB iBcb = Bcb; - iBcb->RefCount++; + PINTERNAL_BCB iBcb = Bcb; + iBcb->RefCount++; } /* @@ -228,38 +236,37 @@ CcRepinBcb ( VOID NTAPI CcUnpinRepinnedBcb ( - IN PVOID Bcb, - IN BOOLEAN WriteThrough, - IN PIO_STATUS_BLOCK IoStatus - ) + IN PVOID Bcb, + IN BOOLEAN WriteThrough, + IN PIO_STATUS_BLOCK IoStatus) { - PINTERNAL_BCB iBcb = Bcb; + PINTERNAL_BCB iBcb = Bcb; - if (--iBcb->RefCount == 0) + if (--iBcb->RefCount == 0) { - IoStatus->Information = 0; - if (WriteThrough) + IoStatus->Information = 0; + if (WriteThrough) { KeWaitForSingleObject(&iBcb->CacheSegment->Mutex, Executive, KernelMode, FALSE, NULL); - if (iBcb->CacheSegment->Dirty) + if (iBcb->CacheSegment->Dirty) { - IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment); + IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment); } - else + else { - IoStatus->Status = STATUS_SUCCESS; + IoStatus->Status = STATUS_SUCCESS; } - KeReleaseMutex(&iBcb->CacheSegment->Mutex, 0); + KeReleaseMutex(&iBcb->CacheSegment->Mutex, 0); } - else + else { - IoStatus->Status = STATUS_SUCCESS; + IoStatus->Status = STATUS_SUCCESS; } - ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); + ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb); } } diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index b55b4ad22e1..dc12c7fd134 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -58,7 +58,7 @@ ULONG DirtyPageCount=0; KGUARDED_MUTEX ViewLock; #ifdef CACHE_BITMAP -#define CI_CACHESEG_MAPPING_REGION_SIZE (128*1024*1024) +#define CI_CACHESEG_MAPPING_REGION_SIZE (128*1024*1024) static PVOID CiCacheSegMappingRegionBase = NULL; static RTL_BITMAP CiCacheSegMappingRegionAllocMap; @@ -73,21 +73,21 @@ static NPAGED_LOOKASIDE_LIST CacheSegLookasideList; #if DBG static void CcRosCacheSegmentIncRefCount_ ( PCACHE_SEGMENT cs, const char* file, int line ) { - ++cs->ReferenceCount; - if ( cs->Bcb->Trace ) - { - DbgPrint("(%s:%i) CacheSegment %p ++RefCount=%d, Dirty %d, PageOut %d\n", - file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut ); - } + ++cs->ReferenceCount; + if ( cs->Bcb->Trace ) + { + DbgPrint("(%s:%i) CacheSegment %p ++RefCount=%d, Dirty %d, PageOut %d\n", + file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut ); + } } static void CcRosCacheSegmentDecRefCount_ ( PCACHE_SEGMENT cs, const char* file, int line ) { - --cs->ReferenceCount; - if ( cs->Bcb->Trace ) - { - DbgPrint("(%s:%i) CacheSegment %p --RefCount=%d, Dirty %d, PageOut %d\n", - file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut ); - } + --cs->ReferenceCount; + if ( cs->Bcb->Trace ) + { + DbgPrint("(%s:%i) CacheSegment %p --RefCount=%d, Dirty %d, PageOut %d\n", + file, line, cs, cs->ReferenceCount, cs->Dirty, cs->PageOut ); + } } #define CcRosCacheSegmentIncRefCount(cs) CcRosCacheSegmentIncRefCount_(cs,__FILE__,__LINE__) #define CcRosCacheSegmentDecRefCount(cs) CcRosCacheSegmentDecRefCount_(cs,__FILE__,__LINE__) @@ -105,77 +105,81 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg); VOID NTAPI CcRosTraceCacheMap ( - PBCB Bcb, - BOOLEAN Trace ) + PBCB Bcb, + BOOLEAN Trace ) { #if DBG - KIRQL oldirql; - PLIST_ENTRY current_entry; - PCACHE_SEGMENT current; - - if ( !Bcb ) - return; - - Bcb->Trace = Trace; - - if ( Trace ) - { - DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", Bcb ); - - KeAcquireGuardedMutex(&ViewLock); - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - - current_entry = Bcb->BcbSegmentListHead.Flink; - while (current_entry != &Bcb->BcbSegmentListHead) - { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); - current_entry = current_entry->Flink; - - DPRINT1(" CacheSegment 0x%p enabled, RefCount %d, Dirty %d, PageOut %d\n", - current, current->ReferenceCount, current->Dirty, current->PageOut ); - } - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - KeReleaseGuardedMutex(&ViewLock); - } - else - { - DPRINT1("Disabling Tracing for CacheMap 0x%p:\n", Bcb ); - } + KIRQL oldirql; + PLIST_ENTRY current_entry; + PCACHE_SEGMENT current; + + if ( !Bcb ) + return; + + Bcb->Trace = Trace; + + if ( Trace ) + { + DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", Bcb ); + + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + + current_entry = Bcb->BcbSegmentListHead.Flink; + while (current_entry != &Bcb->BcbSegmentListHead) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); + current_entry = current_entry->Flink; + + DPRINT1(" CacheSegment 0x%p enabled, RefCount %d, Dirty %d, PageOut %d\n", + current, current->ReferenceCount, current->Dirty, current->PageOut ); + } + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + KeReleaseGuardedMutex(&ViewLock); + } + else + { + DPRINT1("Disabling Tracing for CacheMap 0x%p:\n", Bcb ); + } #else - Bcb = Bcb; - Trace = Trace; + Bcb = Bcb; + Trace = Trace; #endif } NTSTATUS NTAPI -CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment) +CcRosFlushCacheSegment ( + PCACHE_SEGMENT CacheSegment) { NTSTATUS Status; KIRQL oldIrql; - + Status = WriteCacheSegment(CacheSegment); if (NT_SUCCESS(Status)) { KeAcquireGuardedMutex(&ViewLock); KeAcquireSpinLock(&CacheSegment->Bcb->BcbLock, &oldIrql); - + CacheSegment->Dirty = FALSE; RemoveEntryList(&CacheSegment->DirtySegmentListEntry); DirtyPageCount -= CacheSegment->Bcb->CacheSegmentSize / PAGE_SIZE; - CcRosCacheSegmentDecRefCount ( CacheSegment ); - + CcRosCacheSegmentDecRefCount(CacheSegment); + KeReleaseSpinLock(&CacheSegment->Bcb->BcbLock, oldIrql); KeReleaseGuardedMutex(&ViewLock); } - + return(Status); } NTSTATUS NTAPI -CcRosFlushDirtyPages(ULONG Target, PULONG Count, BOOLEAN Wait) +CcRosFlushDirtyPages ( + ULONG Target, + PULONG Count, + BOOLEAN Wait) { PLIST_ENTRY current_entry; PCACHE_SEGMENT current; @@ -183,22 +187,22 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count, BOOLEAN Wait) BOOLEAN Locked; NTSTATUS Status; LARGE_INTEGER ZeroTimeout; - + DPRINT("CcRosFlushDirtyPages(Target %d)\n", Target); - + (*Count) = 0; ZeroTimeout.QuadPart = 0; - + KeEnterCriticalRegion(); KeAcquireGuardedMutex(&ViewLock); - + current_entry = DirtySegmentListHead.Flink; if (current_entry == &DirtySegmentListHead) { DPRINT("No Dirty pages\n"); } - - while (current_entry != &DirtySegmentListHead && Target > 0) + + while ((current_entry != &DirtySegmentListHead) && (Target > 0)) { current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, DirtySegmentListEntry); @@ -207,7 +211,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count, BOOLEAN Wait) CcRosCacheSegmentIncRefCount(current); Locked = current->Bcb->Callbacks->AcquireForLazyWrite( - current->Bcb->LazyWriteContext, Wait); + current->Bcb->LazyWriteContext, Wait); if (!Locked) { CcRosCacheSegmentDecRefCount(current); @@ -248,7 +252,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count, BOOLEAN Wait) KeReleaseMutex(¤t->Mutex, 0); current->Bcb->Callbacks->ReleaseFromLazyWrite( current->Bcb->LazyWriteContext); - + KeAcquireGuardedMutex(&ViewLock); CcRosCacheSegmentDecRefCount(current); @@ -264,16 +268,19 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count, BOOLEAN Wait) current_entry = DirtySegmentListHead.Flink; } - + KeReleaseGuardedMutex(&ViewLock); KeLeaveCriticalRegion(); - + DPRINT("CcRosFlushDirtyPages() finished\n"); return(STATUS_SUCCESS); } NTSTATUS -CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) +CcRosTrimCache ( + ULONG Target, + ULONG Priority, + PULONG NrFreed) /* * FUNCTION: Try to free some memory from the file cache. * ARGUMENTS: @@ -361,7 +368,7 @@ retry: KeReleaseGuardedMutex(&ViewLock); /* Try flushing pages if we haven't met our target */ - if (Target > 0 && !FlushedPages) + if ((Target > 0) && !FlushedPages) { /* Flush dirty pages to disk */ CcRosFlushDirtyPages(Target, &PagesFreed, FALSE); @@ -394,66 +401,69 @@ retry: NTSTATUS NTAPI -CcRosReleaseCacheSegment(PBCB Bcb, - PCACHE_SEGMENT CacheSeg, - BOOLEAN Valid, - BOOLEAN Dirty, - BOOLEAN Mapped) +CcRosReleaseCacheSegment ( + PBCB Bcb, + PCACHE_SEGMENT CacheSeg, + BOOLEAN Valid, + BOOLEAN Dirty, + BOOLEAN Mapped) { - BOOLEAN WasDirty; - KIRQL oldIrql; + BOOLEAN WasDirty; + KIRQL oldIrql; + + ASSERT(Bcb); - ASSERT(Bcb); + DPRINT("CcReleaseCacheSegment(Bcb 0x%p, CacheSeg 0x%p, Valid %d)\n", + Bcb, CacheSeg, Valid); - DPRINT("CcReleaseCacheSegment(Bcb 0x%p, CacheSeg 0x%p, Valid %d)\n", - Bcb, CacheSeg, Valid); + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); - KeAcquireGuardedMutex(&ViewLock); - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + CacheSeg->Valid = Valid; - CacheSeg->Valid = Valid; + WasDirty = CacheSeg->Dirty; + CacheSeg->Dirty = CacheSeg->Dirty || Dirty; - WasDirty = CacheSeg->Dirty; - CacheSeg->Dirty = CacheSeg->Dirty || Dirty; + if (!WasDirty && CacheSeg->Dirty) + { + InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); + DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; + } - if (!WasDirty && CacheSeg->Dirty) + if (Mapped) { - InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); - DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; + CacheSeg->MappedCount++; + } + CcRosCacheSegmentDecRefCount(CacheSeg); + if (Mapped && (CacheSeg->MappedCount == 1)) + { + CcRosCacheSegmentIncRefCount(CacheSeg); + } + if (!WasDirty && CacheSeg->Dirty) + { + CcRosCacheSegmentIncRefCount(CacheSeg); } - if (Mapped) - { - CacheSeg->MappedCount++; - } - CcRosCacheSegmentDecRefCount(CacheSeg); - if (Mapped && CacheSeg->MappedCount == 1) - { - CcRosCacheSegmentIncRefCount(CacheSeg); - } - if (!WasDirty && CacheSeg->Dirty) - { - CcRosCacheSegmentIncRefCount(CacheSeg); - } - - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - KeReleaseGuardedMutex(&ViewLock); - KeReleaseMutex(&CacheSeg->Mutex, 0); - - return(STATUS_SUCCESS); + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); + KeReleaseMutex(&CacheSeg->Mutex, 0); + + return(STATUS_SUCCESS); } /* Returns with Cache Segment Lock Held! */ PCACHE_SEGMENT NTAPI -CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset) +CcRosLookupCacheSegment ( + PBCB Bcb, + ULONG FileOffset) { PLIST_ENTRY current_entry; PCACHE_SEGMENT current; KIRQL oldIrql; - + ASSERT(Bcb); - + DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %d)\n", Bcb, FileOffset); KeAcquireGuardedMutex(&ViewLock); @@ -464,8 +474,8 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset) { current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); - if (current->FileOffset <= FileOffset && - (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset) + if ((current->FileOffset <= FileOffset) && + ((current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)) { CcRosCacheSegmentIncRefCount(current); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); @@ -488,525 +498,546 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset) NTSTATUS NTAPI -CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset) +CcRosMarkDirtyCacheSegment ( + PBCB Bcb, + ULONG FileOffset) { - PCACHE_SEGMENT CacheSeg; - KIRQL oldIrql; + PCACHE_SEGMENT CacheSeg; + KIRQL oldIrql; - ASSERT(Bcb); + ASSERT(Bcb); - DPRINT("CcRosMarkDirtyCacheSegment(Bcb 0x%p, FileOffset %d)\n", Bcb, FileOffset); + DPRINT("CcRosMarkDirtyCacheSegment(Bcb 0x%p, FileOffset %d)\n", Bcb, FileOffset); - CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset); - if (CacheSeg == NULL) + CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset); + if (CacheSeg == NULL) { - KeBugCheck(CACHE_MANAGER); + KeBugCheck(CACHE_MANAGER); } - KeAcquireGuardedMutex(&ViewLock); - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); - if (!CacheSeg->Dirty) - { - InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); - DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; - } - else - { - CcRosCacheSegmentDecRefCount(CacheSeg); - } + if (!CacheSeg->Dirty) + { + InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); + DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; + } + else + { + CcRosCacheSegmentDecRefCount(CacheSeg); + } - /* Move to the tail of the LRU list */ - RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry); - InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry); + /* Move to the tail of the LRU list */ + RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry); + InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry); - CacheSeg->Dirty = TRUE; + CacheSeg->Dirty = TRUE; - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - KeReleaseGuardedMutex(&ViewLock); - KeReleaseMutex(&CacheSeg->Mutex, 0); + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); + KeReleaseMutex(&CacheSeg->Mutex, 0); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } NTSTATUS NTAPI -CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty) +CcRosUnmapCacheSegment ( + PBCB Bcb, + ULONG FileOffset, + BOOLEAN NowDirty) { - PCACHE_SEGMENT CacheSeg; - BOOLEAN WasDirty; - KIRQL oldIrql; + PCACHE_SEGMENT CacheSeg; + BOOLEAN WasDirty; + KIRQL oldIrql; - ASSERT(Bcb); + ASSERT(Bcb); - DPRINT("CcRosUnmapCacheSegment(Bcb 0x%p, FileOffset %d, NowDirty %d)\n", - Bcb, FileOffset, NowDirty); + DPRINT("CcRosUnmapCacheSegment(Bcb 0x%p, FileOffset %d, NowDirty %d)\n", + Bcb, FileOffset, NowDirty); - CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset); - if (CacheSeg == NULL) + CacheSeg = CcRosLookupCacheSegment(Bcb, FileOffset); + if (CacheSeg == NULL) { - return(STATUS_UNSUCCESSFUL); + return(STATUS_UNSUCCESSFUL); } - KeAcquireGuardedMutex(&ViewLock); - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); - WasDirty = CacheSeg->Dirty; - CacheSeg->Dirty = CacheSeg->Dirty || NowDirty; + WasDirty = CacheSeg->Dirty; + CacheSeg->Dirty = CacheSeg->Dirty || NowDirty; - CacheSeg->MappedCount--; + CacheSeg->MappedCount--; - if (!WasDirty && NowDirty) - { - InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); - DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; - } + if (!WasDirty && NowDirty) + { + InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); + DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; + } - CcRosCacheSegmentDecRefCount(CacheSeg); - if (!WasDirty && NowDirty) - { - CcRosCacheSegmentIncRefCount(CacheSeg); - } - if (CacheSeg->MappedCount == 0) - { - CcRosCacheSegmentDecRefCount(CacheSeg); - } + CcRosCacheSegmentDecRefCount(CacheSeg); + if (!WasDirty && NowDirty) + { + CcRosCacheSegmentIncRefCount(CacheSeg); + } + if (CacheSeg->MappedCount == 0) + { + CcRosCacheSegmentDecRefCount(CacheSeg); + } - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - KeReleaseGuardedMutex(&ViewLock); - KeReleaseMutex(&CacheSeg->Mutex, 0); + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); + KeReleaseMutex(&CacheSeg->Mutex, 0); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } static NTSTATUS -CcRosCreateCacheSegment(PBCB Bcb, - ULONG FileOffset, - PCACHE_SEGMENT* CacheSeg) +CcRosCreateCacheSegment ( + PBCB Bcb, + ULONG FileOffset, + PCACHE_SEGMENT* CacheSeg) { - PCACHE_SEGMENT current; - PCACHE_SEGMENT previous; - PLIST_ENTRY current_entry; - NTSTATUS Status; - KIRQL oldIrql; + PCACHE_SEGMENT current; + PCACHE_SEGMENT previous; + PLIST_ENTRY current_entry; + NTSTATUS Status; + KIRQL oldIrql; #ifdef CACHE_BITMAP - ULONG StartingOffset; + ULONG StartingOffset; #endif - PHYSICAL_ADDRESS BoundaryAddressMultiple; + PHYSICAL_ADDRESS BoundaryAddressMultiple; - ASSERT(Bcb); + ASSERT(Bcb); - DPRINT("CcRosCreateCacheSegment()\n"); + DPRINT("CcRosCreateCacheSegment()\n"); - BoundaryAddressMultiple.QuadPart = 0; - if (FileOffset >= Bcb->FileSize.u.LowPart) - { - CacheSeg = NULL; - return STATUS_INVALID_PARAMETER; - } + BoundaryAddressMultiple.QuadPart = 0; + if (FileOffset >= Bcb->FileSize.u.LowPart) + { + CacheSeg = NULL; + return STATUS_INVALID_PARAMETER; + } - current = ExAllocateFromNPagedLookasideList(&CacheSegLookasideList); - current->Valid = FALSE; - current->Dirty = FALSE; - current->PageOut = FALSE; - current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize); - current->Bcb = Bcb; -#if DBG - if ( Bcb->Trace ) - { - DPRINT1("CacheMap 0x%p: new Cache Segment: 0x%p\n", Bcb, current ); - } -#endif - current->MappedCount = 0; - current->DirtySegmentListEntry.Flink = NULL; - current->DirtySegmentListEntry.Blink = NULL; - current->ReferenceCount = 1; - KeInitializeMutex(¤t->Mutex, 0); - KeWaitForSingleObject(¤t->Mutex, - Executive, - KernelMode, - FALSE, - NULL); - KeAcquireGuardedMutex(&ViewLock); - - *CacheSeg = current; - /* There is window between the call to CcRosLookupCacheSegment - * and CcRosCreateCacheSegment. We must check if a segment on - * the fileoffset exist. If there exist a segment, we release - * our new created segment and return the existing one. - */ - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); - current_entry = Bcb->BcbSegmentListHead.Flink; - previous = NULL; - while (current_entry != &Bcb->BcbSegmentListHead) - { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, - BcbSegmentListEntry); - if (current->FileOffset <= FileOffset && - (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset) - { - CcRosCacheSegmentIncRefCount(current); - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + current = ExAllocateFromNPagedLookasideList(&CacheSegLookasideList); + current->Valid = FALSE; + current->Dirty = FALSE; + current->PageOut = FALSE; + current->FileOffset = ROUND_DOWN(FileOffset, Bcb->CacheSegmentSize); + current->Bcb = Bcb; #if DBG - if ( Bcb->Trace ) - { - DPRINT1("CacheMap 0x%p: deleting newly created Cache Segment 0x%p ( found existing one 0x%p )\n", - Bcb, - (*CacheSeg), - current ); - } + if ( Bcb->Trace ) + { + DPRINT1("CacheMap 0x%p: new Cache Segment: 0x%p\n", Bcb, current ); + } #endif - KeReleaseMutex(&(*CacheSeg)->Mutex, 0); - KeReleaseGuardedMutex(&ViewLock); - ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg); - *CacheSeg = current; + current->MappedCount = 0; + current->DirtySegmentListEntry.Flink = NULL; + current->DirtySegmentListEntry.Blink = NULL; + current->ReferenceCount = 1; + KeInitializeMutex(¤t->Mutex, 0); KeWaitForSingleObject(¤t->Mutex, Executive, KernelMode, FALSE, NULL); - return STATUS_SUCCESS; - } - if (current->FileOffset < FileOffset) - { - if (previous == NULL) - { - previous = current; - } - else - { - if (previous->FileOffset < current->FileOffset) - { - previous = current; - } - } - } - current_entry = current_entry->Flink; - } - /* There was no existing segment. */ - current = *CacheSeg; - if (previous) - { - InsertHeadList(&previous->BcbSegmentListEntry, ¤t->BcbSegmentListEntry); - } - else - { - InsertHeadList(&Bcb->BcbSegmentListHead, ¤t->BcbSegmentListEntry); - } - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry); - InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); - KeReleaseGuardedMutex(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); + + *CacheSeg = current; + /* There is window between the call to CcRosLookupCacheSegment + * and CcRosCreateCacheSegment. We must check if a segment on + * the fileoffset exist. If there exist a segment, we release + * our new created segment and return the existing one. + */ + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + current_entry = Bcb->BcbSegmentListHead.Flink; + previous = NULL; + while (current_entry != &Bcb->BcbSegmentListHead) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, + BcbSegmentListEntry); + if (current->FileOffset <= FileOffset && + (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset) + { + CcRosCacheSegmentIncRefCount(current); + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); +#if DBG + if ( Bcb->Trace ) + { + DPRINT1("CacheMap 0x%p: deleting newly created Cache Segment 0x%p ( found existing one 0x%p )\n", + Bcb, + (*CacheSeg), + current ); + } +#endif + KeReleaseMutex(&(*CacheSeg)->Mutex, 0); + KeReleaseGuardedMutex(&ViewLock); + ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg); + *CacheSeg = current; + KeWaitForSingleObject(¤t->Mutex, + Executive, + KernelMode, + FALSE, + NULL); + return STATUS_SUCCESS; + } + if (current->FileOffset < FileOffset) + { + if (previous == NULL) + { + previous = current; + } + else + { + if (previous->FileOffset < current->FileOffset) + { + previous = current; + } + } + } + current_entry = current_entry->Flink; + } + /* There was no existing segment. */ + current = *CacheSeg; + if (previous) + { + InsertHeadList(&previous->BcbSegmentListEntry, ¤t->BcbSegmentListEntry); + } + else + { + InsertHeadList(&Bcb->BcbSegmentListHead, ¤t->BcbSegmentListEntry); + } + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry); + InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); + KeReleaseGuardedMutex(&ViewLock); #ifdef CACHE_BITMAP - KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql); + KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql); - StartingOffset = RtlFindClearBitsAndSet(&CiCacheSegMappingRegionAllocMap, Bcb->CacheSegmentSize / PAGE_SIZE, CiCacheSegMappingRegionHint); + StartingOffset = RtlFindClearBitsAndSet(&CiCacheSegMappingRegionAllocMap, Bcb->CacheSegmentSize / PAGE_SIZE, CiCacheSegMappingRegionHint); - if (StartingOffset == 0xffffffff) - { - DPRINT1("Out of CacheSeg mapping space\n"); - KeBugCheck(CACHE_MANAGER); - } + if (StartingOffset == 0xffffffff) + { + DPRINT1("Out of CacheSeg mapping space\n"); + KeBugCheck(CACHE_MANAGER); + } - current->BaseAddress = CiCacheSegMappingRegionBase + StartingOffset * PAGE_SIZE; + current->BaseAddress = CiCacheSegMappingRegionBase + StartingOffset * PAGE_SIZE; - if (CiCacheSegMappingRegionHint == StartingOffset) - { - CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE; - } + if (CiCacheSegMappingRegionHint == StartingOffset) + { + CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE; + } - KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql); + KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql); #else - MmLockAddressSpace(MmGetKernelAddressSpace()); - current->BaseAddress = NULL; - Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), - 0, // nothing checks for cache_segment mareas, so set to 0 - ¤t->BaseAddress, - Bcb->CacheSegmentSize, - PAGE_READWRITE, - (PMEMORY_AREA*)¤t->MemoryArea, - FALSE, - 0, - BoundaryAddressMultiple); - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(CACHE_MANAGER); - } + MmLockAddressSpace(MmGetKernelAddressSpace()); + current->BaseAddress = NULL; + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + 0, // nothing checks for cache_segment mareas, so set to 0 + ¤t->BaseAddress, + Bcb->CacheSegmentSize, + PAGE_READWRITE, + (PMEMORY_AREA*)¤t->MemoryArea, + FALSE, + 0, + BoundaryAddressMultiple); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(CACHE_MANAGER); + } #endif - /* Create a virtual mapping for this memory area */ - MI_SET_USAGE(MI_USAGE_CACHE); + /* Create a virtual mapping for this memory area */ + MI_SET_USAGE(MI_USAGE_CACHE); #if MI_TRACE_PFNS - PWCHAR pos = NULL; - ULONG len = 0; - if ((Bcb->FileObject) && (Bcb->FileObject->FileName.Buffer)) - { - pos = wcsrchr(Bcb->FileObject->FileName.Buffer, '\\'); - len = wcslen(pos) * sizeof(WCHAR); - if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos); - } + PWCHAR pos = NULL; + ULONG len = 0; + if ((Bcb->FileObject) && (Bcb->FileObject->FileName.Buffer)) + { + pos = wcsrchr(Bcb->FileObject->FileName.Buffer, '\\'); + len = wcslen(pos) * sizeof(WCHAR); + if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos); + } #endif - MmMapMemoryArea(current->BaseAddress, Bcb->CacheSegmentSize, - MC_CACHE, PAGE_READWRITE); + MmMapMemoryArea(current->BaseAddress, Bcb->CacheSegmentSize, + MC_CACHE, PAGE_READWRITE); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } NTSTATUS NTAPI -CcRosGetCacheSegmentChain(PBCB Bcb, - ULONG FileOffset, - ULONG Length, - PCACHE_SEGMENT* CacheSeg) +CcRosGetCacheSegmentChain ( + PBCB Bcb, + ULONG FileOffset, + ULONG Length, + PCACHE_SEGMENT* CacheSeg) { - PCACHE_SEGMENT current; - ULONG i; - PCACHE_SEGMENT* CacheSegList; - PCACHE_SEGMENT Previous = NULL; + PCACHE_SEGMENT current; + ULONG i; + PCACHE_SEGMENT* CacheSegList; + PCACHE_SEGMENT Previous = NULL; - ASSERT(Bcb); + ASSERT(Bcb); - DPRINT("CcRosGetCacheSegmentChain()\n"); + DPRINT("CcRosGetCacheSegmentChain()\n"); - Length = ROUND_UP(Length, Bcb->CacheSegmentSize); + Length = ROUND_UP(Length, Bcb->CacheSegmentSize); - CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) * - (Length / Bcb->CacheSegmentSize)); + CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) * + (Length / Bcb->CacheSegmentSize)); - /* - * Look for a cache segment already mapping the same data. - */ - for (i = 0; i < (Length / Bcb->CacheSegmentSize); i++) + /* + * 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) - { - KeAcquireGuardedMutex(&ViewLock); - - /* Move to tail of LRU list */ - RemoveEntryList(¤t->CacheSegmentLRUListEntry); - InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); - - KeReleaseGuardedMutex(&ViewLock); - - CacheSegList[i] = current; - } - else - { - CcRosCreateCacheSegment(Bcb, CurrentOffset, ¤t); - CacheSegList[i] = current; - } + ULONG CurrentOffset = FileOffset + (i * Bcb->CacheSegmentSize); + current = CcRosLookupCacheSegment(Bcb, CurrentOffset); + if (current != NULL) + { + KeAcquireGuardedMutex(&ViewLock); + + /* Move to tail of LRU list */ + RemoveEntryList(¤t->CacheSegmentLRUListEntry); + InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); + + KeReleaseGuardedMutex(&ViewLock); + + CacheSegList[i] = current; + } + else + { + CcRosCreateCacheSegment(Bcb, CurrentOffset, ¤t); + CacheSegList[i] = current; + } } - for (i = 0; i < (Length / Bcb->CacheSegmentSize); i++) + for (i = 0; i < (Length / Bcb->CacheSegmentSize); i++) { - if (i == 0) - { - *CacheSeg = CacheSegList[i]; - Previous = CacheSegList[i]; - } - else - { - Previous->NextInChain = CacheSegList[i]; - Previous = CacheSegList[i]; - } + if (i == 0) + { + *CacheSeg = CacheSegList[i]; + Previous = CacheSegList[i]; + } + else + { + Previous->NextInChain = CacheSegList[i]; + Previous = CacheSegList[i]; + } } - ASSERT(Previous); - Previous->NextInChain = NULL; + ASSERT(Previous); + Previous->NextInChain = NULL; - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } NTSTATUS NTAPI -CcRosGetCacheSegment(PBCB Bcb, - ULONG FileOffset, - PULONG BaseOffset, - PVOID* BaseAddress, - PBOOLEAN UptoDate, - PCACHE_SEGMENT* CacheSeg) +CcRosGetCacheSegment ( + PBCB Bcb, + ULONG FileOffset, + PULONG BaseOffset, + PVOID* BaseAddress, + PBOOLEAN UptoDate, + PCACHE_SEGMENT* CacheSeg) { - PCACHE_SEGMENT current; - NTSTATUS Status; - - ASSERT(Bcb); - - DPRINT("CcRosGetCacheSegment()\n"); - - /* - * Look for a cache segment already mapping the same data. - */ - current = CcRosLookupCacheSegment(Bcb, FileOffset); - if (current == NULL) - { - /* - * Otherwise create a new segment. - */ - Status = CcRosCreateCacheSegment(Bcb, FileOffset, ¤t); - if (!NT_SUCCESS(Status)) - { - return Status; - } - } - - KeAcquireGuardedMutex(&ViewLock); - - /* Move to the tail of the LRU list */ - RemoveEntryList(¤t->CacheSegmentLRUListEntry); - InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); - - KeReleaseGuardedMutex(&ViewLock); - - /* - * Return information about the segment to the caller. - */ - *UptoDate = current->Valid; - *BaseAddress = current->BaseAddress; - DPRINT("*BaseAddress %p\n", *BaseAddress); - *CacheSeg = current; - *BaseOffset = current->FileOffset; - return(STATUS_SUCCESS); + PCACHE_SEGMENT current; + NTSTATUS Status; + + ASSERT(Bcb); + + DPRINT("CcRosGetCacheSegment()\n"); + + /* + * Look for a cache segment already mapping the same data. + */ + current = CcRosLookupCacheSegment(Bcb, FileOffset); + if (current == NULL) + { + /* + * Otherwise create a new segment. + */ + Status = CcRosCreateCacheSegment(Bcb, FileOffset, ¤t); + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + + KeAcquireGuardedMutex(&ViewLock); + + /* Move to the tail of the LRU list */ + RemoveEntryList(¤t->CacheSegmentLRUListEntry); + InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); + + KeReleaseGuardedMutex(&ViewLock); + + /* + * Return information about the segment to the caller. + */ + *UptoDate = current->Valid; + *BaseAddress = current->BaseAddress; + DPRINT("*BaseAddress %p\n", *BaseAddress); + *CacheSeg = current; + *BaseOffset = current->FileOffset; + return(STATUS_SUCCESS); } -NTSTATUS NTAPI -CcRosRequestCacheSegment(PBCB Bcb, - ULONG FileOffset, - PVOID* BaseAddress, - PBOOLEAN UptoDate, - PCACHE_SEGMENT* CacheSeg) +NTSTATUS +NTAPI +CcRosRequestCacheSegment ( + PBCB Bcb, + ULONG FileOffset, + PVOID* BaseAddress, + PBOOLEAN UptoDate, + PCACHE_SEGMENT* CacheSeg) /* * FUNCTION: Request a page mapping for a BCB */ { - ULONG BaseOffset; + ULONG BaseOffset; - ASSERT(Bcb); + ASSERT(Bcb); - if ((FileOffset % Bcb->CacheSegmentSize) != 0) + if ((FileOffset % Bcb->CacheSegmentSize) != 0) { - DPRINT1("Bad fileoffset %x should be multiple of %x", - FileOffset, Bcb->CacheSegmentSize); - KeBugCheck(CACHE_MANAGER); + DPRINT1("Bad fileoffset %x should be multiple of %x", + FileOffset, Bcb->CacheSegmentSize); + KeBugCheck(CACHE_MANAGER); } - return(CcRosGetCacheSegment(Bcb, - FileOffset, - &BaseOffset, - BaseAddress, - UptoDate, - CacheSeg)); + return(CcRosGetCacheSegment(Bcb, + FileOffset, + &BaseOffset, + BaseAddress, + UptoDate, + CacheSeg)); } #ifdef CACHE_BITMAP #else -static VOID -CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, - PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty) +static +VOID +CcFreeCachePage ( + PVOID Context, + MEMORY_AREA* MemoryArea, + PVOID Address, + PFN_NUMBER Page, + SWAPENTRY SwapEntry, + BOOLEAN Dirty) { - ASSERT(SwapEntry == 0); - if (Page != 0) + ASSERT(SwapEntry == 0); + if (Page != 0) { ASSERT(MmGetReferenceCountPage(Page) == 1); - MmReleasePageMemoryConsumer(MC_CACHE, Page); + MmReleasePageMemoryConsumer(MC_CACHE, Page); } } #endif NTSTATUS -CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg) +CcRosInternalFreeCacheSegment ( + PCACHE_SEGMENT CacheSeg) /* * FUNCTION: Releases a cache segment associated with a BCB */ { #ifdef CACHE_BITMAP - ULONG i; - ULONG RegionSize; - ULONG Base; - PFN_NUMBER Page; - KIRQL oldIrql; + ULONG i; + ULONG RegionSize; + ULONG Base; + PFN_NUMBER Page; + KIRQL oldIrql; #endif - DPRINT("Freeing cache segment 0x%p\n", CacheSeg); + DPRINT("Freeing cache segment 0x%p\n", CacheSeg); #if DBG - if ( CacheSeg->Bcb->Trace ) - { - DPRINT1("CacheMap 0x%p: deleting Cache Segment: 0x%p\n", CacheSeg->Bcb, CacheSeg ); - } + if ( CacheSeg->Bcb->Trace ) + { + DPRINT1("CacheMap 0x%p: deleting Cache Segment: 0x%p\n", CacheSeg->Bcb, CacheSeg ); + } #endif #ifdef CACHE_BITMAP - RegionSize = CacheSeg->Bcb->CacheSegmentSize / PAGE_SIZE; + RegionSize = CacheSeg->Bcb->CacheSegmentSize / PAGE_SIZE; - /* Unmap all the pages. */ - for (i = 0; i < RegionSize; i++) + /* Unmap all the pages. */ + for (i = 0; i < RegionSize; i++) { - MmDeleteVirtualMapping(NULL, - CacheSeg->BaseAddress + (i * PAGE_SIZE), - FALSE, - NULL, - &Page); - MmReleasePageMemoryConsumer(MC_CACHE, Page); + MmDeleteVirtualMapping(NULL, + CacheSeg->BaseAddress + (i * PAGE_SIZE), + FALSE, + NULL, + &Page); + MmReleasePageMemoryConsumer(MC_CACHE, Page); } - KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql); - /* Deallocate all the pages used. */ - Base = (ULONG)(CacheSeg->BaseAddress - CiCacheSegMappingRegionBase) / PAGE_SIZE; + KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql); + /* Deallocate all the pages used. */ + Base = (ULONG)(CacheSeg->BaseAddress - CiCacheSegMappingRegionBase) / PAGE_SIZE; - RtlClearBits(&CiCacheSegMappingRegionAllocMap, Base, RegionSize); + RtlClearBits(&CiCacheSegMappingRegionAllocMap, Base, RegionSize); - CiCacheSegMappingRegionHint = min (CiCacheSegMappingRegionHint, Base); + CiCacheSegMappingRegionHint = min (CiCacheSegMappingRegionHint, Base); - KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql); + KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql); #else - MmLockAddressSpace(MmGetKernelAddressSpace()); - MmFreeMemoryArea(MmGetKernelAddressSpace(), - CacheSeg->MemoryArea, - CcFreeCachePage, - NULL); - MmUnlockAddressSpace(MmGetKernelAddressSpace()); + MmLockAddressSpace(MmGetKernelAddressSpace()); + MmFreeMemoryArea(MmGetKernelAddressSpace(), + CacheSeg->MemoryArea, + CcFreeCachePage, + NULL); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); #endif - ExFreeToNPagedLookasideList(&CacheSegLookasideList, CacheSeg); - return(STATUS_SUCCESS); + ExFreeToNPagedLookasideList(&CacheSegLookasideList, CacheSeg); + return(STATUS_SUCCESS); } NTSTATUS NTAPI -CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg) +CcRosFreeCacheSegment ( + PBCB Bcb, + PCACHE_SEGMENT CacheSeg) { - NTSTATUS Status; - KIRQL oldIrql; - - ASSERT(Bcb); - - DPRINT("CcRosFreeCacheSegment(Bcb 0x%p, CacheSeg 0x%p)\n", - Bcb, CacheSeg); - - KeAcquireGuardedMutex(&ViewLock); - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); - RemoveEntryList(&CacheSeg->BcbSegmentListEntry); - RemoveEntryList(&CacheSeg->CacheSegmentListEntry); - RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry); - if (CacheSeg->Dirty) - { - RemoveEntryList(&CacheSeg->DirtySegmentListEntry); - DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; - - } - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - KeReleaseGuardedMutex(&ViewLock); - - Status = CcRosInternalFreeCacheSegment(CacheSeg); - return(Status); + NTSTATUS Status; + KIRQL oldIrql; + + ASSERT(Bcb); + + DPRINT("CcRosFreeCacheSegment(Bcb 0x%p, CacheSeg 0x%p)\n", + Bcb, CacheSeg); + + KeAcquireGuardedMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + RemoveEntryList(&CacheSeg->BcbSegmentListEntry); + RemoveEntryList(&CacheSeg->CacheSegmentListEntry); + RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry); + if (CacheSeg->Dirty) + { + RemoveEntryList(&CacheSeg->DirtySegmentListEntry); + DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; + + } + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + KeReleaseGuardedMutex(&ViewLock); + + Status = CcRosInternalFreeCacheSegment(CacheSeg); + return(Status); } /* * @implemented */ -VOID NTAPI -CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, - IN PLARGE_INTEGER FileOffset OPTIONAL, - IN ULONG Length, - OUT PIO_STATUS_BLOCK IoStatus) +VOID +NTAPI +CcFlushCache ( + IN PSECTION_OBJECT_POINTERS SectionObjectPointers, + IN PLARGE_INTEGER FileOffset OPTIONAL, + IN ULONG Length, + OUT PIO_STATUS_BLOCK IoStatus) { PBCB Bcb; LARGE_INTEGER Offset; @@ -1051,7 +1082,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, } } KeReleaseMutex(¤t->Mutex, 0); - + KeAcquireGuardedMutex(&ViewLock); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); CcRosCacheSegmentDecRefCount(current); @@ -1081,7 +1112,9 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, NTSTATUS NTAPI -CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) +CcRosDeleteFileCache ( + PFILE_OBJECT FileObject, + PBCB Bcb) /* * FUNCTION: Releases the BCB associated with a file object */ @@ -1152,284 +1185,295 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) VOID NTAPI -CcRosReferenceCache(PFILE_OBJECT FileObject) +CcRosReferenceCache ( + PFILE_OBJECT FileObject) { - PBCB Bcb; - KeAcquireGuardedMutex(&ViewLock); - Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap; - ASSERT(Bcb); - if (Bcb->RefCount == 0) - { - ASSERT(Bcb->BcbRemoveListEntry.Flink != NULL); - RemoveEntryList(&Bcb->BcbRemoveListEntry); - Bcb->BcbRemoveListEntry.Flink = NULL; - - } - else - { - ASSERT(Bcb->BcbRemoveListEntry.Flink == NULL); - } - Bcb->RefCount++; - KeReleaseGuardedMutex(&ViewLock); + PBCB Bcb; + KeAcquireGuardedMutex(&ViewLock); + Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap; + ASSERT(Bcb); + if (Bcb->RefCount == 0) + { + ASSERT(Bcb->BcbRemoveListEntry.Flink != NULL); + RemoveEntryList(&Bcb->BcbRemoveListEntry); + Bcb->BcbRemoveListEntry.Flink = NULL; + + } + else + { + ASSERT(Bcb->BcbRemoveListEntry.Flink == NULL); + } + Bcb->RefCount++; + KeReleaseGuardedMutex(&ViewLock); } VOID NTAPI -CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer) +CcRosSetRemoveOnClose ( + PSECTION_OBJECT_POINTERS SectionObjectPointer) { - PBCB Bcb; - DPRINT("CcRosSetRemoveOnClose()\n"); - KeAcquireGuardedMutex(&ViewLock); - Bcb = (PBCB)SectionObjectPointer->SharedCacheMap; - if (Bcb) - { - Bcb->RemoveOnClose = TRUE; - if (Bcb->RefCount == 0) + PBCB Bcb; + DPRINT("CcRosSetRemoveOnClose()\n"); + KeAcquireGuardedMutex(&ViewLock); + Bcb = (PBCB)SectionObjectPointer->SharedCacheMap; + if (Bcb) { - CcRosDeleteFileCache(Bcb->FileObject, Bcb); + Bcb->RemoveOnClose = TRUE; + if (Bcb->RefCount == 0) + { + CcRosDeleteFileCache(Bcb->FileObject, Bcb); + } } - } - KeReleaseGuardedMutex(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } VOID NTAPI -CcRosDereferenceCache(PFILE_OBJECT FileObject) +CcRosDereferenceCache ( + PFILE_OBJECT FileObject) { - PBCB Bcb; - KeAcquireGuardedMutex(&ViewLock); - Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap; - ASSERT(Bcb); - if (Bcb->RefCount > 0) - { - Bcb->RefCount--; - if (Bcb->RefCount == 0) + PBCB Bcb; + KeAcquireGuardedMutex(&ViewLock); + Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap; + ASSERT(Bcb); + if (Bcb->RefCount > 0) { - MmFreeSectionSegments(Bcb->FileObject); - CcRosDeleteFileCache(FileObject, Bcb); + Bcb->RefCount--; + if (Bcb->RefCount == 0) + { + MmFreeSectionSegments(Bcb->FileObject); + CcRosDeleteFileCache(FileObject, Bcb); + } } - } - KeReleaseGuardedMutex(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } -NTSTATUS NTAPI -CcRosReleaseFileCache(PFILE_OBJECT FileObject) +NTSTATUS +NTAPI +CcRosReleaseFileCache ( + PFILE_OBJECT FileObject) /* * FUNCTION: Called by the file system when a handle to a file object * has been closed. */ { - PBCB Bcb; + PBCB Bcb; - KeAcquireGuardedMutex(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); - if (FileObject->SectionObjectPointer->SharedCacheMap != NULL) - { - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - if (FileObject->PrivateCacheMap != NULL) + if (FileObject->SectionObjectPointer->SharedCacheMap != NULL) { - FileObject->PrivateCacheMap = NULL; - if (Bcb->RefCount > 0) - { - Bcb->RefCount--; - if (Bcb->RefCount == 0) - { - MmFreeSectionSegments(Bcb->FileObject); - CcRosDeleteFileCache(FileObject, Bcb); - } - } + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + if (FileObject->PrivateCacheMap != NULL) + { + FileObject->PrivateCacheMap = NULL; + if (Bcb->RefCount > 0) + { + Bcb->RefCount--; + if (Bcb->RefCount == 0) + { + MmFreeSectionSegments(Bcb->FileObject); + CcRosDeleteFileCache(FileObject, Bcb); + } + } + } } - } - KeReleaseGuardedMutex(&ViewLock); - return(STATUS_SUCCESS); + KeReleaseGuardedMutex(&ViewLock); + return(STATUS_SUCCESS); } NTSTATUS NTAPI -CcTryToInitializeFileCache(PFILE_OBJECT FileObject) +CcTryToInitializeFileCache ( + PFILE_OBJECT FileObject) { - PBCB Bcb; - NTSTATUS Status; - - KeAcquireGuardedMutex(&ViewLock); - - ASSERT(FileObject->SectionObjectPointer); - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - if (Bcb == NULL) - { - Status = STATUS_UNSUCCESSFUL; - } - else - { - if (FileObject->PrivateCacheMap == NULL) - { - FileObject->PrivateCacheMap = Bcb; - Bcb->RefCount++; - } - if (Bcb->BcbRemoveListEntry.Flink != NULL) - { - RemoveEntryList(&Bcb->BcbRemoveListEntry); - Bcb->BcbRemoveListEntry.Flink = NULL; - } - Status = STATUS_SUCCESS; - } - KeReleaseGuardedMutex(&ViewLock); - - return Status; + PBCB Bcb; + NTSTATUS Status; + + KeAcquireGuardedMutex(&ViewLock); + + ASSERT(FileObject->SectionObjectPointer); + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + if (Bcb == NULL) + { + Status = STATUS_UNSUCCESSFUL; + } + else + { + if (FileObject->PrivateCacheMap == NULL) + { + FileObject->PrivateCacheMap = Bcb; + Bcb->RefCount++; + } + if (Bcb->BcbRemoveListEntry.Flink != NULL) + { + RemoveEntryList(&Bcb->BcbRemoveListEntry); + Bcb->BcbRemoveListEntry.Flink = NULL; + } + Status = STATUS_SUCCESS; + } + KeReleaseGuardedMutex(&ViewLock); + + return Status; } -NTSTATUS NTAPI -CcRosInitializeFileCache(PFILE_OBJECT FileObject, - ULONG CacheSegmentSize, - PCACHE_MANAGER_CALLBACKS CallBacks, - PVOID LazyWriterContext) +NTSTATUS +NTAPI +CcRosInitializeFileCache ( + PFILE_OBJECT FileObject, + ULONG CacheSegmentSize, + PCACHE_MANAGER_CALLBACKS CallBacks, + PVOID LazyWriterContext) /* * FUNCTION: Initializes a BCB for a file object */ { - PBCB Bcb; + PBCB Bcb; - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - DPRINT("CcRosInitializeFileCache(FileObject 0x%p, Bcb 0x%p, CacheSegmentSize %d)\n", + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + DPRINT("CcRosInitializeFileCache(FileObject 0x%p, Bcb 0x%p, CacheSegmentSize %d)\n", FileObject, Bcb, CacheSegmentSize); - KeAcquireGuardedMutex(&ViewLock); - if (Bcb == NULL) - { - Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList); - if (Bcb == NULL) - { - KeReleaseGuardedMutex(&ViewLock); - return(STATUS_UNSUCCESSFUL); - } - memset(Bcb, 0, sizeof(BCB)); - ObReferenceObjectByPointer(FileObject, - FILE_ALL_ACCESS, - NULL, - KernelMode); - Bcb->FileObject = FileObject; - Bcb->CacheSegmentSize = CacheSegmentSize; - Bcb->Callbacks = CallBacks; - Bcb->LazyWriteContext = LazyWriterContext; - if (FileObject->FsContext) - { - Bcb->AllocationSize = - ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->AllocationSize; - Bcb->FileSize = - ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize; - } - KeInitializeSpinLock(&Bcb->BcbLock); - InitializeListHead(&Bcb->BcbSegmentListHead); - FileObject->SectionObjectPointer->SharedCacheMap = Bcb; - } - if (FileObject->PrivateCacheMap == NULL) - { - FileObject->PrivateCacheMap = Bcb; - Bcb->RefCount++; - } - if (Bcb->BcbRemoveListEntry.Flink != NULL) - { - RemoveEntryList(&Bcb->BcbRemoveListEntry); - Bcb->BcbRemoveListEntry.Flink = NULL; - } - KeReleaseGuardedMutex(&ViewLock); - - return(STATUS_SUCCESS); + KeAcquireGuardedMutex(&ViewLock); + if (Bcb == NULL) + { + Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList); + if (Bcb == NULL) + { + KeReleaseGuardedMutex(&ViewLock); + return(STATUS_UNSUCCESSFUL); + } + memset(Bcb, 0, sizeof(BCB)); + ObReferenceObjectByPointer(FileObject, + FILE_ALL_ACCESS, + NULL, + KernelMode); + Bcb->FileObject = FileObject; + Bcb->CacheSegmentSize = CacheSegmentSize; + Bcb->Callbacks = CallBacks; + Bcb->LazyWriteContext = LazyWriterContext; + if (FileObject->FsContext) + { + Bcb->AllocationSize = + ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->AllocationSize; + Bcb->FileSize = + ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize; + } + KeInitializeSpinLock(&Bcb->BcbLock); + InitializeListHead(&Bcb->BcbSegmentListHead); + FileObject->SectionObjectPointer->SharedCacheMap = Bcb; + } + if (FileObject->PrivateCacheMap == NULL) + { + FileObject->PrivateCacheMap = Bcb; + Bcb->RefCount++; + } + if (Bcb->BcbRemoveListEntry.Flink != NULL) + { + RemoveEntryList(&Bcb->BcbRemoveListEntry); + Bcb->BcbRemoveListEntry.Flink = NULL; + } + KeReleaseGuardedMutex(&ViewLock); + + return(STATUS_SUCCESS); } /* * @implemented */ -PFILE_OBJECT NTAPI -CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointers) +PFILE_OBJECT +NTAPI +CcGetFileObjectFromSectionPtrs ( + IN PSECTION_OBJECT_POINTERS SectionObjectPointers) { - PBCB Bcb; - if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap) - { - Bcb = (PBCB)SectionObjectPointers->SharedCacheMap; - ASSERT(Bcb); - return Bcb->FileObject; - } - return NULL; + PBCB Bcb; + if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap) + { + Bcb = (PBCB)SectionObjectPointers->SharedCacheMap; + ASSERT(Bcb); + return Bcb->FileObject; + } + return NULL; } VOID INIT_FUNCTION NTAPI -CcInitView(VOID) +CcInitView ( + VOID) { #ifdef CACHE_BITMAP - PMEMORY_AREA marea; - PVOID Buffer; - PHYSICAL_ADDRESS BoundaryAddressMultiple; + PMEMORY_AREA marea; + PVOID Buffer; + PHYSICAL_ADDRESS BoundaryAddressMultiple; #endif - DPRINT("CcInitView()\n"); + DPRINT("CcInitView()\n"); #ifdef CACHE_BITMAP - BoundaryAddressMultiple.QuadPart = 0; - CiCacheSegMappingRegionHint = 0; - CiCacheSegMappingRegionBase = NULL; - - MmLockAddressSpace(MmGetKernelAddressSpace()); - - Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), - MEMORY_AREA_CACHE_SEGMENT, - &CiCacheSegMappingRegionBase, - CI_CACHESEG_MAPPING_REGION_SIZE, - PAGE_READWRITE, - &marea, - FALSE, - 0, - BoundaryAddressMultiple); - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - if (!NT_SUCCESS(Status)) + BoundaryAddressMultiple.QuadPart = 0; + CiCacheSegMappingRegionHint = 0; + CiCacheSegMappingRegionBase = NULL; + + MmLockAddressSpace(MmGetKernelAddressSpace()); + + Status = MmCreateMemoryArea(MmGetKernelAddressSpace(), + MEMORY_AREA_CACHE_SEGMENT, + &CiCacheSegMappingRegionBase, + CI_CACHESEG_MAPPING_REGION_SIZE, + PAGE_READWRITE, + &marea, + FALSE, + 0, + BoundaryAddressMultiple); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + if (!NT_SUCCESS(Status)) { - KeBugCheck(CACHE_MANAGER); + KeBugCheck(CACHE_MANAGER); } - Buffer = ExAllocatePool(NonPagedPool, CI_CACHESEG_MAPPING_REGION_SIZE / (PAGE_SIZE * 8)); - if (!Buffer) - { - KeBugCheck(CACHE_MANAGER); - } + Buffer = ExAllocatePool(NonPagedPool, CI_CACHESEG_MAPPING_REGION_SIZE / (PAGE_SIZE * 8)); + if (!Buffer) + { + KeBugCheck(CACHE_MANAGER); + } - RtlInitializeBitMap(&CiCacheSegMappingRegionAllocMap, Buffer, CI_CACHESEG_MAPPING_REGION_SIZE / PAGE_SIZE); - RtlClearAllBits(&CiCacheSegMappingRegionAllocMap); + RtlInitializeBitMap(&CiCacheSegMappingRegionAllocMap, Buffer, CI_CACHESEG_MAPPING_REGION_SIZE / PAGE_SIZE); + RtlClearAllBits(&CiCacheSegMappingRegionAllocMap); - KeInitializeSpinLock(&CiCacheSegMappingRegionLock); + KeInitializeSpinLock(&CiCacheSegMappingRegionLock); #endif - InitializeListHead(&CacheSegmentListHead); - InitializeListHead(&DirtySegmentListHead); - InitializeListHead(&CacheSegmentLRUListHead); - InitializeListHead(&ClosedListHead); - KeInitializeGuardedMutex(&ViewLock); - ExInitializeNPagedLookasideList (&iBcbLookasideList, - NULL, - NULL, - 0, - sizeof(INTERNAL_BCB), - TAG_IBCB, - 20); - ExInitializeNPagedLookasideList (&BcbLookasideList, - NULL, - NULL, - 0, - sizeof(BCB), - TAG_BCB, - 20); - ExInitializeNPagedLookasideList (&CacheSegLookasideList, - NULL, - NULL, - 0, - sizeof(CACHE_SEGMENT), - TAG_CSEG, - 20); - - MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache); - - CcInitCacheZeroPage(); + InitializeListHead(&CacheSegmentListHead); + InitializeListHead(&DirtySegmentListHead); + InitializeListHead(&CacheSegmentLRUListHead); + InitializeListHead(&ClosedListHead); + KeInitializeGuardedMutex(&ViewLock); + ExInitializeNPagedLookasideList (&iBcbLookasideList, + NULL, + NULL, + 0, + sizeof(INTERNAL_BCB), + TAG_IBCB, + 20); + ExInitializeNPagedLookasideList (&BcbLookasideList, + NULL, + NULL, + 0, + sizeof(BCB), + TAG_BCB, + 20); + ExInitializeNPagedLookasideList (&CacheSegLookasideList, + NULL, + NULL, + 0, + sizeof(CACHE_SEGMENT), + TAG_CSEG, + 20); + + MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache); + + CcInitCacheZeroPage(); }