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
43 CcMdlReadCompleteDev (IN PMDL MdlChain,
44 IN PDEVICE_OBJECT DeviceObject)
50 /**********************************************************************
62 * From Bo Branten's ntifs.h v13.
65 CcMdlReadComplete (IN PFILE_OBJECT FileObject,
68 PDEVICE_OBJECT DeviceObject = NULL;
70 DeviceObject = IoGetRelatedDeviceObject (FileObject);
71 /* FIXME: try fast I/O first */
72 CcMdlReadCompleteDev (MdlChain,
77 CcSetFileSizes (IN PFILE_OBJECT FileObject,
78 IN PCC_FILE_SIZES FileSizes)
82 PLIST_ENTRY current_entry;
83 PCACHE_SEGMENT current;
84 LIST_ENTRY FreeListHead;
87 DPRINT("CcSetFileSizes(FileObject %x, FileSizes %x)\n",
88 FileObject, FileSizes);
89 DPRINT("AllocationSize %d, FileSize %d, ValidDataLength %d\n",
90 (ULONG)FileSizes->AllocationSize.QuadPart,
91 (ULONG)FileSizes->FileSize.QuadPart,
92 (ULONG)FileSizes->ValidDataLength.QuadPart);
94 Bcb = FileObject->SectionObjectPointers->SharedCacheMap;
97 if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart)
99 InitializeListHead(&FreeListHead);
100 ExAcquireFastMutex(&ViewLock);
101 KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
103 current_entry = Bcb->BcbSegmentListHead.Flink;
104 while (current_entry != &Bcb->BcbSegmentListHead)
106 current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
107 current_entry = current_entry->Flink;
108 if (current->FileOffset > FileSizes->AllocationSize.QuadPart)
110 if (current->ReferenceCount == 0 || (current->ReferenceCount == 1 && current->Dirty))
112 RemoveEntryList(¤t->BcbSegmentListEntry);
113 RemoveEntryList(¤t->CacheSegmentListEntry);
114 RemoveEntryList(¤t->CacheSegmentLRUListEntry);
117 RemoveEntryList(¤t->DirtySegmentListEntry);
118 DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE;
120 InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry);
124 DPRINT1("Anyone has referenced a cache segment behind the new size.\n");
130 Bcb->AllocationSize = FileSizes->AllocationSize;
131 Bcb->FileSize = FileSizes->FileSize;
132 KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
133 ExReleaseFastMutex(&ViewLock);
135 current_entry = FreeListHead.Flink;
136 while(current_entry != &FreeListHead)
138 current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
139 current_entry = current_entry->Flink;
140 Status = CcRosInternalFreeCacheSegment(current);
141 if (!NT_SUCCESS(Status))
143 DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n");
150 KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
151 Bcb->AllocationSize = FileSizes->AllocationSize;
152 Bcb->FileSize = FileSizes->FileSize;
153 KeReleaseSpinLock(&Bcb->BcbLock, oldirql);