1 /* INCLUDES ******************************************************************/
5 #include <internal/mm.h>
6 #include <internal/cc.h>
7 #include <internal/pool.h>
8 #include <internal/io.h>
9 #include <ntos/minmax.h>
12 #include <internal/debug.h>
14 /* GLOBALS *******************************************************************/
16 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
17 #define ROUND_DOWN(N, S) (((N) % (S)) ? ROUND_UP(N, S) - S : N)
19 extern FAST_MUTEX ViewLock;
20 extern ULONG DirtyPageCount;
22 NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
24 /* FUNCTIONS *****************************************************************/
26 /**********************************************************************
28 * CcMdlReadCompleteDev@8
40 * Used by CcMdlReadComplete@8 and FsRtl
44 CcMdlReadCompleteDev (IN PMDL MdlChain,
45 IN PDEVICE_OBJECT DeviceObject)
51 /**********************************************************************
63 * From Bo Branten's ntifs.h v13.
68 CcMdlReadComplete (IN PFILE_OBJECT FileObject,
71 PDEVICE_OBJECT DeviceObject = NULL;
73 DeviceObject = IoGetRelatedDeviceObject (FileObject);
74 /* FIXME: try fast I/O first */
75 CcMdlReadCompleteDev (MdlChain,
83 CcSetFileSizes (IN PFILE_OBJECT FileObject,
84 IN PCC_FILE_SIZES FileSizes)
88 PLIST_ENTRY current_entry;
89 PCACHE_SEGMENT current;
90 LIST_ENTRY FreeListHead;
93 DPRINT("CcSetFileSizes(FileObject %x, FileSizes %x)\n",
94 FileObject, FileSizes);
95 DPRINT("AllocationSize %d, FileSize %d, ValidDataLength %d\n",
96 (ULONG)FileSizes->AllocationSize.QuadPart,
97 (ULONG)FileSizes->FileSize.QuadPart,
98 (ULONG)FileSizes->ValidDataLength.QuadPart);
100 Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
103 if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart)
105 InitializeListHead(&FreeListHead);
106 ExAcquireFastMutex(&ViewLock);
107 KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
109 current_entry = Bcb->BcbSegmentListHead.Flink;
110 while (current_entry != &Bcb->BcbSegmentListHead)
112 current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
113 current_entry = current_entry->Flink;
114 if (current->FileOffset > FileSizes->AllocationSize.QuadPart)
116 if (current->ReferenceCount == 0 || (current->ReferenceCount == 1 && current->Dirty))
118 RemoveEntryList(¤t->BcbSegmentListEntry);
119 RemoveEntryList(¤t->CacheSegmentListEntry);
120 RemoveEntryList(¤t->CacheSegmentLRUListEntry);
123 RemoveEntryList(¤t->DirtySegmentListEntry);
124 DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE;
126 InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry);
130 DPRINT1("Anyone has referenced a cache segment behind the new size.\n");
136 Bcb->AllocationSize = FileSizes->AllocationSize;
137 Bcb->FileSize = FileSizes->FileSize;
138 KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
139 ExReleaseFastMutex(&ViewLock);
141 current_entry = FreeListHead.Flink;
142 while(current_entry != &FreeListHead)
144 current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
145 current_entry = current_entry->Flink;
146 Status = CcRosInternalFreeCacheSegment(current);
147 if (!NT_SUCCESS(Status))
149 DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n");
156 KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
157 Bcb->AllocationSize = FileSizes->AllocationSize;
158 Bcb->FileSize = FileSizes->FileSize;
159 KeReleaseSpinLock(&Bcb->BcbLock, oldirql);