- Started the rewriting of the cache manger. - The new cache manager uses section objects and maps the content of cached files into the kernel address space for functions like CcCopyRead. - The implementation isn't complete. It works for me to compile ros on ros if enough ram is available. Modified: branches/cache_manager_rewrite/reactos/drivers/fs/cdfs/cdfs.h Modified: branches/cache_manager_rewrite/reactos/drivers/fs/ntfs/ntfs.h Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/cleanup.c Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/close.c Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/create.c Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/fcb.c Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/finfo.c Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/vfat.h Modified: branches/cache_manager_rewrite/reactos/include/reactos/exeformat.h Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/cc/copy.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/cc/fs.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/cc/pin.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/cc/view.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/include/config.h Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/include/internal/cc.h Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/include/internal/mm.h Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/kd/kdebug.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/ldr/init.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/ldr/loader.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/elf.inc.h Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/freelist.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/mm.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/mminit.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/mpw.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/npool.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/pageop.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/pe.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/rmap.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/mm/section.c Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/ntoskrnl.def _____
Modified: branches/cache_manager_rewrite/reactos/drivers/fs/cdfs/cdfs.h --- branches/cache_manager_rewrite/reactos/drivers/fs/cdfs/cdfs.h 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/drivers/fs/cdfs/cdfs.h 2005-02-14 17:34:10 UTC (rev 13570) @@ -3,7 +3,7 @@
#include <ddk/ntifs.h>
-#define USE_ROS_CC_AND_FS +//#define USE_ROS_CC_AND_FS
#define CDFS_BASIC_SECTOR 2048 #define CDFS_PRIMARY_DESCRIPTOR_LOCATION 16 _____
Modified: branches/cache_manager_rewrite/reactos/drivers/fs/ntfs/ntfs.h --- branches/cache_manager_rewrite/reactos/drivers/fs/ntfs/ntfs.h 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/drivers/fs/ntfs/ntfs.h 2005-02-14 17:34:10 UTC (rev 13570) @@ -3,7 +3,7 @@
#include <ddk/ntifs.h>
-#define USE_ROS_CC_AND_FS +//#define USE_ROS_CC_AND_FS
#define CACHEPAGESIZE(pDeviceExt) \ _____
Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/cleanup.c --- branches/cache_manager_rewrite/reactos/drivers/fs/vfat/cleanup.c 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/drivers/fs/vfat/cleanup.c 2005-02-14 17:34:10 UTC (rev 13570) @@ -25,46 +25,94 @@
PFILE_OBJECT FileObject = IrpContext->FileObject;
DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n", - IrpContext->DeviceExt, FileObject); + IrpContext->DeviceExt, FileObject);
/* FIXME: handle file/directory deletion here */ pFcb = (PVFATFCB) FileObject->FsContext; if (pFcb) { - if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) && - FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) - { - /* remove all locks this process have on this file */ - FsRtlFastUnlockAll(&pFcb->FileLock, - FileObject, - IoGetRequestorProcess(IrpContext->Irp), - NULL); - } + DPRINT("'%wZ'\n", &pFcb->PathNameU); + if (pFcb->Flags & FCB_IS_VOLUME) + { + CHECKPOINT1; + pFcb->OpenHandleCount--;
- if (pFcb->Flags & FCB_IS_DIRTY) - { - VfatUpdateEntry (pFcb); - } + if (pFcb->OpenHandleCount != 0) + { + IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess); + } + } + else + { + if(!ExAcquireResourceExclusiveLite (&pFcb->MainResource, + (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) + { + CHECKPOINT1; + return STATUS_PENDING; + } + if(!ExAcquireResourceExclusiveLite (&pFcb->PagingIoResource, + (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) + { + ExReleaseResourceLite (&pFcb->MainResource); + CHECKPOINT; + return STATUS_PENDING; + } + + pFcb->OpenHandleCount--;
- if (pFcb->Flags & FCB_DELETE_PENDING && - pFcb->OpenHandleCount == 1) - { + if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) && + FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) + { + /* remove all locks this process have on this file */ + FsRtlFastUnlockAll(&pFcb->FileLock, + FileObject, + IoGetRequestorProcess(IrpContext->Irp), + NULL); + } + + if (pFcb->Flags & FCB_IS_DIRTY) + { + CHECKPOINT; + VfatUpdateEntry (pFcb); + } + + if (pFcb->Flags & FCB_DELETE_PENDING && + pFcb->OpenHandleCount == 0) + { + DPRINT("'%wZ'\n", &pFcb->PathNameU); #if 0 - /* FIXME: - * CcPurgeCacheSection is unimplemented. - */ - CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE); + /* FIXME: + * CcPurgeCacheSection is unimplemented. + */ + CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, FALSE); #endif - } - /* Uninitialize file cache if. */ +// VfatDelEntry(IrpContext->DeviceExt, pFcb); +// pFcb->RFCB.FileSize.QuadPart = 0; +// pFcb->RFCB.AllocationSize.QuadPart = 0; +// pFcb->RFCB.ValidDataLength.QuadPart = 0; + + } + /* Uninitialize file cache if. */ #ifdef USE_ROS_CC_AND_FS - CcRosReleaseFileCache (FileObject); + CcRosReleaseFileCache (FileObject); #else - CcUninitializeCacheMap (FileObject, NULL, NULL); + if (FileObject->SectionObjectPointer->SharedCacheMap) + { + CcUninitializeCacheMap (FileObject, &pFcb->RFCB.FileSize, NULL); + } #endif - pFcb->OpenHandleCount--; - IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess); + if (pFcb->OpenHandleCount != 0) + { + IoRemoveShareAccess(FileObject, &pFcb->FCBShareAccess); + } + + FileObject->Flags |= FO_CLEANUP_COMPLETE; + + ExReleaseResourceLite (&pFcb->PagingIoResource); + ExReleaseResourceLite (&pFcb->MainResource); + } } + CHECKPOINT; return STATUS_SUCCESS; }
@@ -86,6 +134,7 @@ if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT))) { + CHECKPOINT; return VfatQueueRequest (IrpContext); }
@@ -93,12 +142,19 @@
ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
+ if (Status == STATUS_PENDING) + { + CHECKPOINT; + return VfatQueueRequest(IrpContext); + } + ByeBye: IrpContext->Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT); VfatFreeIrpContext(IrpContext); + CHECKPOINT; return (Status); }
_____
Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/close.c --- branches/cache_manager_rewrite/reactos/drivers/fs/vfat/close.c 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/drivers/fs/vfat/close.c 2005-02-14 17:34:10 UTC (rev 13570) @@ -32,11 +32,14 @@
pCcb = (PVFATCCB) (FileObject->FsContext2); pFcb = (PVFATFCB) (FileObject->FsContext);
+ FileObject->FsContext2 = NULL; + if (pFcb == NULL) { return STATUS_SUCCESS; }
+ DPRINT("'%wZ'\n", &pFcb->PathNameU); if (pFcb->Flags & FCB_IS_VOLUME) { DPRINT1("Volume\n"); @@ -48,7 +51,7 @@ // This a FO, that was created outside from FSD. // Some FO's are created with IoCreateStreamFileObject() insid from FSD. // This FO's haven't a FileName. - if (FileObject->DeletePending) +// if (FileObject->DeletePending) { if (pFcb->Flags & FCB_DELETE_PENDING) { @@ -62,7 +65,6 @@ vfatReleaseFCB (DeviceExt, pFcb); }
- FileObject->FsContext2 = NULL; FileObject->FsContext = NULL; FileObject->SectionObjectPointer = NULL;
@@ -70,7 +72,7 @@ { vfatDestroyCCB(pCcb); } - + CHECKPOINT; return Status; }
_____
Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/create.c --- branches/cache_manager_rewrite/reactos/drivers/fs/vfat/create.c 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/drivers/fs/vfat/create.c 2005-02-14 17:34:10 UTC (rev 13570) @@ -637,7 +637,24 @@
VfatCloseFile (DeviceExt, FileObject); return(STATUS_NOT_A_DIRECTORY); } - +#if 1 + if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)) + { + if (Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA || + RequestedDisposition == FILE_OVERWRITE || + RequestedDisposition == FILE_OVERWRITE_IF) + { + if (!MmFlushImageSection(&pFcb->SectionObjectPointers, MmFlushForWrite)) + { + DPRINT1("%wZ\n", &pFcb->PathNameU); + DPRINT1("%d %d %d\n", Stack->Parameters.Create.SecurityContext->DesiredAccess & FILE_WRITE_DATA, + RequestedDisposition == FILE_OVERWRITE, RequestedDisposition == FILE_OVERWRITE_IF); + VfatCloseFile (DeviceExt, FileObject); + return STATUS_SHARING_VIOLATION; + } + } + } +#endif if (PagingFileCreate) { /* FIXME: _____
Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/fcb.c --- branches/cache_manager_rewrite/reactos/drivers/fs/vfat/fcb.c 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/drivers/fs/vfat/fcb.c 2005-02-14 17:34:10 UTC (rev 13570) @@ -369,7 +369,7 @@
/* FIXME: Guard by SEH. */ CcInitializeCacheMap(fileObject, (PCC_FILE_SIZES)(&fcb->RFCB.AllocationSize), - FALSE, + TRUE, &VfatGlobalData->CacheMgrCallbacks, fcb); #endif _____
Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/finfo.c --- branches/cache_manager_rewrite/reactos/drivers/fs/vfat/finfo.c 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/drivers/fs/vfat/finfo.c 2005-02-14 17:34:10 UTC (rev 13570) @@ -101,6 +101,34 @@
}
static NTSTATUS +VfatGetAttributeTagInformation(PVFATFCB FCB, + PFILE_ATTRIBUTE_TAG_INFORMATION AttributeTagInfo, + PULONG BufferLength) +{ + if (*BufferLength < sizeof(FILE_ATTRIBUTE_TAG_INFORMATION)) + return STATUS_BUFFER_OVERFLOW; + + /* PRECONDITION */ + ASSERT(StandardInfo != NULL); + ASSERT(FCB != NULL); + + AttributeTagInfo->FileAttributes = *FCB->Attributes & 0x3f; + /* Synthesize FILE_ATTRIBUTE_NORMAL */ + if (0 == (AttributeTagInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY | + FILE_ATTRIBUTE_ARCHIVE | + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY))) + { + AttributeTagInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL; + } + AttributeTagInfo->ReparseTag = 0; + + *BufferLength -= sizeof(FILE_ATTRIBUTE_TAG_INFORMATION); + return(STATUS_SUCCESS); +} + +static NTSTATUS VfatSetPositionInformation(PFILE_OBJECT FileObject, PFILE_POSITION_INFORMATION PositionInfo) { @@ -309,7 +337,7 @@ } else { - DPRINT("MmFlushImageSection returned FALSE\n"); + DPRINT1("MmFlushImageSection returned FALSE\n"); Status = STATUS_CANNOT_DELETE; } if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB)) @@ -762,6 +790,12 @@ &BufferLength); break;
+ case FileAttributeTagInformation: + RC = VfatGetAttributeTagInformation(FCB, + SystemBuffer, + &BufferLength); + break; + case FileAlternateNameInformation: RC = STATUS_NOT_IMPLEMENTED; break; @@ -848,6 +882,7 @@ SystemBuffer); break; case FileRenameInformation: + case FileAttributeTagInformation: RC = STATUS_NOT_IMPLEMENTED; break; default: _____
Modified: branches/cache_manager_rewrite/reactos/drivers/fs/vfat/vfat.h --- branches/cache_manager_rewrite/reactos/drivers/fs/vfat/vfat.h 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/drivers/fs/vfat/vfat.h 2005-02-14 17:34:10 UTC (rev 13570) @@ -1,11 +1,19 @@
/* $Id$ */
+//#define USE_ROS_CC_AND_FS + +#ifndef USE_ROS_CC_AND_FS +#ifdef WINVER +#undef WINVER +#endif +#define WINVER 0x0400 +#endif + #include <ddk/ntifs.h> #include <ddk/ntdddisk.h> #include <limits.h> #include <debug.h>
-#define USE_ROS_CC_AND_FS
/* FIXME */ #ifdef __USE_W32API _____
Modified: branches/cache_manager_rewrite/reactos/include/reactos/exeformat.h --- branches/cache_manager_rewrite/reactos/include/reactos/exeformat.h 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/include/reactos/exeformat.h 2005-02-14 17:34:10 UTC (rev 13570) @@ -34,7 +34,8 @@
typedef NTSTATUS (NTAPI * PEXEFMT_CB_READ_FILE) ( - IN PVOID File, + IN PFILE_OBJECT FileObject, + ULONG SectorSize, IN PLARGE_INTEGER Offset, IN ULONG Length, OUT PVOID * Data, @@ -51,7 +52,7 @@ ( IN CONST VOID * FileHeader, IN SIZE_T FileHeaderSize, - IN PVOID File, + IN PFILE_OBJECT FileObject, OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, OUT PULONG Flags, IN PEXEFMT_CB_READ_FILE ReadFileCb, _____
Modified: branches/cache_manager_rewrite/reactos/ntoskrnl/cc/copy.c --- branches/cache_manager_rewrite/reactos/ntoskrnl/cc/copy.c 2005-02-14 17:10:20 UTC (rev 13569) +++ branches/cache_manager_rewrite/reactos/ntoskrnl/cc/copy.c 2005-02-14 17:34:10 UTC (rev 13570) @@ -37,9 +37,16 @@
ULONG CcFastReadNoWait; ULONG CcFastReadResourceMiss;
+extern FAST_MUTEX CcCacheViewLock; +extern LIST_ENTRY CcFreeCacheViewListHead; +extern LIST_ENTRY CcInUseCacheViewListHead;
/* FUNCTIONS *****************************************************************/
+NTSTATUS STDCALL +MmMapViewInSystemCache(PCACHE_VIEW); + + VOID CcInitCacheZeroPage(VOID) { @@ -59,226 +66,6 @@ } }
-NTSTATUS -ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length, - PVOID Buffer) -{ - PCACHE_SEGMENT head; - PCACHE_SEGMENT current; - PCACHE_SEGMENT previous; - IO_STATUS_BLOCK Iosb; - LARGE_INTEGER SegOffset; - NTSTATUS Status; - ULONG TempLength; - KEVENT Event; - PMDL Mdl; - - Mdl = alloca(MmSizeOfMdl(NULL, MAX_RW_LENGTH)); - - Status = CcRosGetCacheSegmentChain(Bcb, ReadOffset, Length, &head); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - current = head; - while (current != NULL) - { - /* - * If the current segment is valid then copy it into the - * user buffer. - */ - if (current->Valid) - { - TempLength = min(Bcb->CacheSegmentSize, Length); - memcpy(Buffer, current->BaseAddress, TempLength); -#if defined(__GNUC__) - Buffer += TempLength; -#else - { - char* pTemp = Buffer; - pTemp += TempLength; - Buffer = pTemp; - } -#endif - 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_TYPE 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_TYPE)(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 += 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); -#if defined(__GNUC__) - Buffer += TempLength; -#else - { - char* pTemp = Buffer; - pTemp += TempLength; - Buffer = pTemp; - } -#endif - Length = Length - TempLength; - CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE); - current_size += Bcb->CacheSegmentSize; - } - } - } - return(STATUS_SUCCESS); -} - -NTSTATUS -ReadCacheSegment(PCACHE_SEGMENT CacheSeg) -{ - ULONG Size; - PMDL Mdl; - NTSTATUS Status; - LARGE_INTEGER SegOffset; - IO_STATUS_BLOCK IoStatus; - KEVENT Event; - - SegOffset.QuadPart = CacheSeg->FileOffset; - Size = (ULONG)(CacheSeg->Bcb->AllocationSize.QuadPart - CacheSeg->FileOffset); - if (Size > CacheSeg->Bcb->CacheSegmentSize) - { - Size = CacheSeg->Bcb->CacheSegmentSize; - } - Mdl = alloca(MmSizeOfMdl(CacheSeg->BaseAddress, Size)); - MmInitializeMdl(Mdl, CacheSeg->BaseAddress, Size); - MmBuildMdlForNonPagedPool(Mdl); - Mdl->MdlFlags |= MDL_IO_PAGE_READ; - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Status = IoPageRead(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, & Event, &IoStatus); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = IoStatus.Status; - } - - if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE) - { - DPRINT1("IoPageRead failed, Status %x\n", Status); - return Status; - } - if (CacheSeg->Bcb->CacheSegmentSize > Size) - { - memset ((char*)CacheSeg->BaseAddress + Size, 0, - CacheSeg->Bcb->CacheSegmentSize - Size); - } - return STATUS_SUCCESS; -} - -NTSTATUS -WriteCacheSegment(PCACHE_SEGMENT CacheSeg) -{ - ULONG Size; - PMDL Mdl; - NTSTATUS Status; - IO_STATUS_BLOCK IoStatus; - LARGE_INTEGER SegOffset; - KEVENT Event; - - CacheSeg->Dirty = FALSE; - SegOffset.QuadPart = CacheSeg->FileOffset; - Size = (ULONG)(CacheSeg->Bcb->AllocationSize.QuadPart - CacheSeg->FileOffset); - if (Size > CacheSeg->Bcb->CacheSegmentSize) - { - Size = CacheSeg->Bcb->CacheSegmentSize; - } - Mdl = alloca(MmSizeOfMdl(CacheSeg->BaseAddress, Size)); - MmInitializeMdl(Mdl, CacheSeg->BaseAddress, Size); - MmBuildMdlForNonPagedPool(Mdl); - Mdl->MdlFlags |= MDL_IO_PAGE_READ; - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Status = IoPageWrite(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, &Event, &IoStatus); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = IoStatus.Status; - } - if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) - { - DPRINT1("IoPageWrite failed, Status %x\n", Status); - CacheSeg->Dirty = TRUE; - return(Status); - } - return(STATUS_SUCCESS); -} - - /* * @unimplemented */ @@ -293,10 +80,6 @@ return FALSE; }
- -/* - * @implemented - */ BOOLEAN STDCALL CcCopyRead (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, @@ -305,234 +88,295 @@ 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 %x, FileOffset %x, " - "Length %d, Wait %d, Buffer %x, IoStatus %x)\n", - FileObject, (ULONG)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); + ULONG Index; + PBCB Bcb; + LARGE_INTEGER Offset; + PLIST_ENTRY entry; + PCACHE_VIEW current = NULL; + ULONG CurrentLength; + NTSTATUS Status;
- /* - * 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); - } + DPRINT("CcCopyRead(%x, %x, %x, %x, %x, %x\n", + FileObject, FileOffset, Length, Wait, Buffer, IoStatus);
- 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)) + if (!Wait) + { + IoStatus->Information = 0; + IoStatus->Status = STATUS_UNSUCCESSFUL; + CHECKPOINT; + return FALSE; + } + + IoStatus->Information = Length; + IoStatus->Status = STATUS_SUCCESS; + + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + + if (FileOffset->QuadPart + Length > Bcb->FileSizes.FileSize.QuadPart) + { + KEBUGCHECK(0); + } + + if (Bcb->FileSizes.AllocationSize.QuadPart > sizeof(Bcb->CacheView) / sizeof(Bcb->CacheView[0]) * CACHE_VIEW_SIZE) + { + /* not implemented */ + KEBUGCHECK(0); + } + + Offset = *FileOffset; + + ExAcquireFastMutex(&CcCacheViewLock); + while (Length) + { + Index = Offset.QuadPart / CACHE_VIEW_SIZE; + if (Bcb->CacheView[Index] && Bcb->CacheView[Index]->Bcb == Bcb) + { + CHECKPOINT; + if (Bcb->CacheView[Index]->RefCount == 0) + { + RemoveEntryList(&Bcb->CacheView[Index]->ListEntry); + InsertHeadList(&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry); + } + Bcb->CacheView[Index]->RefCount++; + } + else + { + CHECKPOINT; + if (IsListEmpty(&CcFreeCacheViewListHead)) + { + /* not implemented */ + KEBUGCHECK(0); + } + + entry = CcFreeCacheViewListHead.Flink; + while (entry != &CcFreeCacheViewListHead) + { + current = CONTAINING_RECORD(entry, CACHE_VIEW, ListEntry); + entry = entry->Flink; + if (current->Bcb == NULL) { - IoStatus->Information = 0; - IoStatus->Status = Status; - CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); - return FALSE; + break; } - } - 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) - { - TempLength = min(max(Bcb->CacheSegmentSize, MAX_RW_LENGTH), Length); - ReadCacheSegmentChain(Bcb, ReadOffset, TempLength, Buffer); - ReadLength += TempLength; - Length -= TempLength; - ReadOffset += TempLength; -#if defined(__GNUC__) - Buffer += TempLength; -#else - { - char* pTemp = Buffer; - pTemp += TempLength; - Buffer = pTemp; - } -#endif - } - IoStatus->Status = STATUS_SUCCESS; - IoStatus->Information = ReadLength; - DPRINT("CcCopyRead O.K.\n"); - return TRUE; + } + if (entry == &CcFreeCacheViewListHead) + { + KEBUGCHECK(0); + } + + if (current->Bcb) + { + current->Bcb->CacheView[current->SectionData.ViewOffset / CACHE_VIEW_SIZE] = NULL; + } + Bcb->CacheView[Index] = current; + + + if(Bcb->CacheView[Index]->Bcb != NULL) + { + DPRINT1("%x\n", Bcb->CacheView[Index]->Bcb); + /* not implemented */ + KEBUGCHECK(0); + } + Bcb->CacheView[Index]->RefCount = 1; + Bcb->CacheView[Index]->Bcb = Bcb; + Bcb->CacheView[Index]->SectionData.ViewOffset = Index * CACHE_VIEW_SIZE; + Bcb->CacheView[Index]->SectionData.Section = Bcb->Section; + Bcb->CacheView[Index]->SectionData.Segment = Bcb->Section->Segment; + + Status = MmMapViewInSystemCache(Bcb->CacheView[Index]); + + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } + } + ExReleaseFastMutex(&CcCacheViewLock); + + if (Offset.QuadPart % CACHE_VIEW_SIZE) + { + if (Length > CACHE_VIEW_SIZE - Offset.u.LowPart % CACHE_VIEW_SIZE) + { + CurrentLength = CACHE_VIEW_SIZE - Offset.u.LowPart % CACHE_VIEW_SIZE; + } + else + { + CurrentLength = Length; + } + memcpy(Buffer, Bcb->CacheView[Index]->BaseAddress + Offset.u.LowPart % CACHE_VIEW_SIZE, CurrentLength); + Buffer += CurrentLength; + Length -= CurrentLength; + Offset.QuadPart += CurrentLength; + } + else + { + CurrentLength = Length > CACHE_VIEW_SIZE ? CACHE_VIEW_SIZE : Length; + memcpy(Buffer, Bcb->CacheView[Index]->BaseAddress, CurrentLength); + Buffer += CurrentLength; + Length -= CurrentLength; + Offset.QuadPart += CurrentLength; + } + ExAcquireFastMutex(&CcCacheViewLock); + + Bcb->CacheView[Index]->RefCount--; + if (Bcb->CacheView[Index]->RefCount == 0) + { + RemoveEntryList(&Bcb->CacheView[Index]->ListEntry); + InsertHeadList(&CcFreeCacheViewListHead, &Bcb->CacheView[Index]->ListEntry); + } + } + ExReleaseFastMutex(&CcCacheViewLock); + + CHECKPOINT; + + return TRUE; }
/* * @implemented */ BOOLEAN STDCALL -CcCopyWrite (IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN PVOID Buffer) +CcCopyWrite(IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN PVOID Buffer) { - NTSTATUS Status; - ULONG WriteOffset; - KIRQL oldirql; + + ULONG Index; PBCB Bcb; - PLIST_ENTRY current_entry; - PCACHE_SEGMENT CacheSeg; - ULONG TempLength; - PVOID BaseAddress; - BOOLEAN Valid; + LARGE_INTEGER Offset; + PLIST_ENTRY entry; + PCACHE_VIEW current = NULL; + ULONG CurrentLength; + NTSTATUS Status;
- DPRINT("CcCopyWrite(FileObject %x, FileOffset %x, " - "Length %d, Wait %d, Buffer %x)\n", - FileObject, (ULONG)FileOffset->QuadPart, Length, Wait, Buffer); + DPRINT("CcCopyWrite(%x, %x, %x, %x, %x\n", + FileObject, FileOffset, Length, Wait, Buffer);
+ if (!Wait) + { + CHECKPOINT; + return FALSE; + } + 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) + if (FileOffset->QuadPart + Length > Bcb->FileSizes.FileSize.QuadPart) + { + KEBUGCHECK(0); + } + + if (Bcb->FileSizes.AllocationSize.QuadPart > sizeof(Bcb->CacheView) / sizeof(Bcb->CacheView[0]) * CACHE_VIEW_SIZE) + { + /* not implemented */ + KEBUGCHECK(0); + } + + Offset = *FileOffset; + + ExAcquireFastMutex(&CcCacheViewLock); + while (Length) + { + Index = Offset.QuadPart / CACHE_VIEW_SIZE; + if (Bcb->CacheView[Index] && Bcb->CacheView[Index]->Bcb == Bcb) + { + CHECKPOINT; + if (Bcb->CacheView[Index]->RefCount == 0) + { + RemoveEntryList(&Bcb->CacheView[Index]->ListEntry); + InsertHeadList(&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry); + } + Bcb->CacheView[Index]->RefCount++; + } + else + { + CHECKPOINT; + if (IsListEmpty(&CcFreeCacheViewListHead)) + { + /* not implemented */ + KEBUGCHECK(0); + } + + entry = CcFreeCacheViewListHead.Flink; + while (entry != &CcFreeCacheViewListHead) + { + current = CONTAINING_RECORD(entry, CACHE_VIEW, ListEntry); + entry = entry->Flink; + if (current->Bcb == NULL) + { + break; + } + } + if (entry == &CcFreeCacheViewListHead) + { + KEBUGCHECK(0); + } + + if (current->Bcb) { - CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, - BcbSegmentListEntry); - if (!CacheSeg->Valid) - { [truncated at 1000 lines; 7554 more skipped]