ReactOS 0.4.15-dev-5858-g16decc6
copy.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/cc/copy.c
5 * PURPOSE: Implements cache managers copy interface
6 *
7 * PROGRAMMERS: Some people?
8 * Pierre Schweitzer (pierre@reactos.org)
9 */
10
11/* INCLUDES ******************************************************************/
12
13#include <ntoskrnl.h>
14#define NDEBUG
15#include <debug.h>
16
17/* GLOBALS *******************************************************************/
18
20
21#define MAX_ZERO_LENGTH (256 * 1024)
22
24{
30
38
39/* Counters:
40 * - Amount of pages flushed to the disk
41 * - Number of flush operations
42 */
45
46/* FUNCTIONS *****************************************************************/
47
48VOID
51 IN PFN_NUMBER PageFrameIndex
52);
53
54VOID
57 VOID)
58{
60
62 //MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
64 if (!NT_SUCCESS(Status))
65 {
66 DbgPrint("Can't allocate CcZeroPage.\n");
67 KeBugCheck(CACHE_MANAGER);
68 }
70}
71
72VOID
74{
75 LIST_ENTRY ToInsertBack;
76
77 InitializeListHead(&ToInsertBack);
78
79 /* We'll try to write as much as we can */
80 while (TRUE)
81 {
82 PDEFERRED_WRITE DeferredWrite;
83 PLIST_ENTRY ListEntry;
84
85 DeferredWrite = NULL;
86
88
89 if (!ListEntry)
90 break;
91
92 DeferredWrite = CONTAINING_RECORD(ListEntry, DEFERRED_WRITE, DeferredWriteLinks);
93
94 /* Check if we can write */
95 if (CcCanIWrite(DeferredWrite->FileObject, DeferredWrite->BytesToWrite, FALSE, RetryForceCheckPerFile))
96 {
97 /* If we have an event, set it and go along */
98 if (DeferredWrite->Event)
99 {
100 KeSetEvent(DeferredWrite->Event, IO_NO_INCREMENT, FALSE);
101 }
102 /* Otherwise, call the write routine and free the context */
103 else
104 {
105 DeferredWrite->PostRoutine(DeferredWrite->Context1, DeferredWrite->Context2);
106 ExFreePoolWithTag(DeferredWrite, 'CcDw');
107 }
108 continue;
109 }
110
111 /* Keep it for later */
112 InsertHeadList(&ToInsertBack, &DeferredWrite->DeferredWriteLinks);
113
114 /* If we don't accept modified pages, stop here */
115 if (!DeferredWrite->LimitModifiedPages)
116 {
117 break;
118 }
119 }
120
121 /* Insert what we couldn't write back in the list */
122 while (!IsListEmpty(&ToInsertBack))
123 {
124 PLIST_ENTRY ListEntry = RemoveTailList(&ToInsertBack);
126 }
127}
128
129VOID
132{
134 LONGLONG CurrentOffset;
136 PROS_SHARED_CACHE_MAP SharedCacheMap;
137 PROS_VACB Vacb;
138 ULONG PartialLength;
140 PPRIVATE_CACHE_MAP PrivateCacheMap;
142
143 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
144
145 /* Critical:
146 * PrivateCacheMap might disappear in-between if the handle
147 * to the file is closed (private is attached to the handle not to
148 * the file), so we need to lock the master lock while we deal with
149 * it. It won't disappear without attempting to lock such lock.
150 */
152 PrivateCacheMap = FileObject->PrivateCacheMap;
153 /* If the handle was closed since the read ahead was scheduled, just quit */
154 if (PrivateCacheMap == NULL)
155 {
158 return;
159 }
160 /* Otherwise, extract read offset and length and release private map */
161 else
162 {
164 CurrentOffset = PrivateCacheMap->ReadAheadOffset[1].QuadPart;
165 Length = PrivateCacheMap->ReadAheadLength[1];
167 }
169
170 /* Time to go! */
171 DPRINT("Doing ReadAhead for %p\n", FileObject);
172 /* Lock the file, first */
173 if (!SharedCacheMap->Callbacks->AcquireForReadAhead(SharedCacheMap->LazyWriteContext, FALSE))
174 {
175 Locked = FALSE;
176 goto Clear;
177 }
178
179 /* Remember it's locked */
180 Locked = TRUE;
181
182 /* Don't read past the end of the file */
183 if (CurrentOffset >= SharedCacheMap->FileSize.QuadPart)
184 {
185 goto Clear;
186 }
187 if (CurrentOffset + Length > SharedCacheMap->FileSize.QuadPart)
188 {
189 Length = SharedCacheMap->FileSize.QuadPart - CurrentOffset;
190 }
191
192 /* Next of the algorithm will lock like CcCopyData with the slight
193 * difference that we don't copy data back to an user-backed buffer
194 * We just bring data into Cc
195 */
196 PartialLength = CurrentOffset % VACB_MAPPING_GRANULARITY;
197 if (PartialLength != 0)
198 {
199 PartialLength = min(Length, VACB_MAPPING_GRANULARITY - PartialLength);
200 Status = CcRosRequestVacb(SharedCacheMap,
201 ROUND_DOWN(CurrentOffset, VACB_MAPPING_GRANULARITY),
202 &Vacb);
203 if (!NT_SUCCESS(Status))
204 {
205 DPRINT1("Failed to request VACB: %lx!\n", Status);
206 goto Clear;
207 }
208
210 CurrentOffset % VACB_MAPPING_GRANULARITY, PartialLength);
211 if (!NT_SUCCESS(Status))
212 {
213 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
214 DPRINT1("Failed to read data: %lx!\n", Status);
215 goto Clear;
216 }
217
218 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
219
220 Length -= PartialLength;
221 CurrentOffset += PartialLength;
222 }
223
224 while (Length > 0)
225 {
226 ASSERT(CurrentOffset % VACB_MAPPING_GRANULARITY == 0);
227 PartialLength = min(VACB_MAPPING_GRANULARITY, Length);
228 Status = CcRosRequestVacb(SharedCacheMap,
229 CurrentOffset,
230 &Vacb);
231 if (!NT_SUCCESS(Status))
232 {
233 DPRINT1("Failed to request VACB: %lx!\n", Status);
234 goto Clear;
235 }
236
237 Status = CcRosEnsureVacbResident(Vacb, TRUE, FALSE, 0, PartialLength);
238 if (!NT_SUCCESS(Status))
239 {
240 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
241 DPRINT1("Failed to read data: %lx!\n", Status);
242 goto Clear;
243 }
244
245 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
246
247 Length -= PartialLength;
248 CurrentOffset += PartialLength;
249 }
250
251Clear:
252 /* See previous comment about private cache map */
254 PrivateCacheMap = FileObject->PrivateCacheMap;
255 if (PrivateCacheMap != NULL)
256 {
257 /* Mark read ahead as unactive */
259 InterlockedAnd((volatile long *)&PrivateCacheMap->UlongFlags, ~PRIVATE_CACHE_MAP_READ_AHEAD_ACTIVE);
261 }
263
264 /* If file was locked, release it */
265 if (Locked)
266 {
267 SharedCacheMap->Callbacks->ReleaseFromReadAhead(SharedCacheMap->LazyWriteContext);
268 }
269
270 /* And drop our extra reference (See: CcScheduleReadAhead) */
272
273 return;
274}
275
276/*
277 * @unimplemented
278 */
280NTAPI
283 IN ULONG BytesToWrite,
285 IN BOOLEAN Retrying)
286{
288 KEVENT WaitEvent;
289 ULONG Length, Pages;
290 BOOLEAN PerFileDefer;
293 CC_CAN_WRITE_RETRY TryContext;
294 PROS_SHARED_CACHE_MAP SharedCacheMap;
295
296 CCTRACE(CC_API_DEBUG, "FileObject=%p BytesToWrite=%lu Wait=%d Retrying=%d\n",
297 FileObject, BytesToWrite, Wait, Retrying);
298
299 /* Write through is always OK */
301 {
302 return TRUE;
303 }
304
305 TryContext = Retrying;
306 /* Allow remote file if not from posted */
308 {
309 return TRUE;
310 }
311
312 /* Don't exceed max tolerated size */
314 if (BytesToWrite < MAX_ZERO_LENGTH)
315 {
316 Length = BytesToWrite;
317 }
318
319 Pages = BYTES_TO_PAGES(Length);
320
321 /* By default, assume limits per file won't be hit */
322 PerFileDefer = FALSE;
323 Fcb = FileObject->FsContext;
324 /* Do we have to check for limits per file? */
325 if (TryContext >= RetryForceCheckPerFile ||
327 {
328 /* If master is not locked, lock it now */
329 if (TryContext != RetryMasterLocked)
330 {
332 }
333
334 /* Let's not assume the file is cached... */
335 if (FileObject->SectionObjectPointer != NULL &&
336 FileObject->SectionObjectPointer->SharedCacheMap != NULL)
337 {
338 SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
339 /* Do we have limits per file set? */
340 if (SharedCacheMap->DirtyPageThreshold != 0 &&
341 SharedCacheMap->DirtyPages != 0)
342 {
343 /* Yes, check whether they are blocking */
344 if (Pages + SharedCacheMap->DirtyPages > SharedCacheMap->DirtyPageThreshold)
345 {
346 PerFileDefer = TRUE;
347 }
348 }
349 }
350
351 /* And don't forget to release master */
352 if (TryContext != RetryMasterLocked)
353 {
355 }
356 }
357
358 /* So, now allow write if:
359 * - Not the first try or we have no throttling yet
360 * AND:
361 * - We don't exceed threshold!
362 * - We don't exceed what Mm can allow us to use
363 * + If we're above top, that's fine
364 * + If we're above bottom with limited modified pages, that's fine
365 * + Otherwise, throttle!
366 */
367 if ((TryContext != FirstTry || IsListEmpty(&CcDeferredWrites)) &&
371 !PerFileDefer)
372 {
373 return TRUE;
374 }
375
376 /* If we can wait, we'll start the wait loop for waiting till we can
377 * write for real
378 */
379 if (!Wait)
380 {
381 return FALSE;
382 }
383
384 /* Initialize our wait event */
386
387 /* And prepare a dummy context */
388 Context.NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
389 Context.NodeByteSize = sizeof(DEFERRED_WRITE);
390 Context.FileObject = FileObject;
391 Context.BytesToWrite = BytesToWrite;
393 Context.Event = &WaitEvent;
394
395 /* And queue it */
396 if (Retrying)
397 {
398 /* To the top, if that's a retry */
400 &Context.DeferredWriteLinks,
402 }
403 else
404 {
405 /* To the bottom, if that's a first time */
407 &Context.DeferredWriteLinks,
409 }
410
411 /* Now make sure that the lazy scan writer will be active */
416
417#if DBG
418 DPRINT1("Actively deferring write for: %p\n", FileObject);
419 DPRINT1("Because:\n");
421 DPRINT1(" There are too many cache dirty pages: %x + %x >= %x\n", CcTotalDirtyPages, Pages, CcDirtyPageThreshold);
423 DPRINT1(" Available pages are below throttle top: %lx <= %lx\n", MmAvailablePages, MmThrottleTop);
424 if (MmModifiedPageListHead.Total >= 1000)
425 DPRINT1(" There are too many modified pages: %lu >= 1000\n", MmModifiedPageListHead.Total);
427 DPRINT1(" Available pages are below throttle bottom: %lx <= %lx\n", MmAvailablePages, MmThrottleBottom);
428#endif
429 /* Now, we'll loop until our event is set. When it is set, it means that caller
430 * can immediately write, and has to
431 */
432 do
433 {
436
437 return TRUE;
438}
439
440static
441int
443{
444 ULONG_PTR ExceptionAddress;
445 ULONG_PTR BeginAddress = (ULONG_PTR)Buffer;
446 ULONG_PTR EndAddress = (ULONG_PTR)Buffer + Length;
447
450 if (Except->ExceptionRecord->NumberParameters < 2)
452
453 ExceptionAddress = Except->ExceptionRecord->ExceptionInformation[1];
454 if ((ExceptionAddress >= BeginAddress) && (ExceptionAddress < EndAddress))
456
458}
459
460/*
461 * @implemented
462 */
464NTAPI
472{
473 PROS_VACB Vacb;
474 PROS_SHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
476 LONGLONG CurrentOffset;
477 LONGLONG ReadEnd = FileOffset->QuadPart + Length;
478 ULONG ReadLength = 0;
479
480 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%I64d Length=%lu Wait=%d\n",
481 FileObject, FileOffset->QuadPart, Length, Wait);
482
483 DPRINT("CcCopyRead(FileObject 0x%p, FileOffset %I64x, "
484 "Length %lu, Wait %u, Buffer 0x%p, IoStatus 0x%p)\n",
485 FileObject, FileOffset->QuadPart, Length, Wait,
487
488 if (!SharedCacheMap)
489 return FALSE;
490
491 /* Documented to ASSERT, but KMTests test this case... */
492 // ASSERT((FileOffset->QuadPart + Length) <= SharedCacheMap->FileSize.QuadPart);
493
494 CurrentOffset = FileOffset->QuadPart;
495 while(CurrentOffset < ReadEnd)
496 {
497 Status = CcRosGetVacb(SharedCacheMap, CurrentOffset, &Vacb);
498 if (!NT_SUCCESS(Status))
499 {
501 return FALSE;
502 }
503
505 {
506 ULONG VacbOffset = CurrentOffset % VACB_MAPPING_GRANULARITY;
507 ULONG VacbLength = min(Length, VACB_MAPPING_GRANULARITY - VacbOffset);
508 SIZE_T CopyLength = VacbLength;
509
510 if (!CcRosEnsureVacbResident(Vacb, Wait, FALSE, VacbOffset, VacbLength))
511 return FALSE;
512
514 {
515 RtlCopyMemory(Buffer, (PUCHAR)Vacb->BaseAddress + VacbOffset, CopyLength);
516 }
518 {
520 }
521 _SEH2_END;
522
523 ReadLength += VacbLength;
524
525 Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength);
526 CurrentOffset += VacbLength;
527 Length -= VacbLength;
528 }
530 {
531 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
532 }
533 _SEH2_END;
534 }
535
536 IoStatus->Status = STATUS_SUCCESS;
537 IoStatus->Information = ReadLength;
538
539#if 0
540 /* If that was a successful sync read operation, let's handle read ahead */
541 if (Length == 0 && Wait)
542 {
543 PPRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
544
545 /* If file isn't random access and next read may get us cross VACB boundary,
546 * schedule next read
547 */
549 (CurrentOffset - 1) / VACB_MAPPING_GRANULARITY != (CurrentOffset + ReadLength - 1) / VACB_MAPPING_GRANULARITY)
550 {
552 }
553
554 /* And update read history in private cache map */
555 PrivateCacheMap->FileOffset1.QuadPart = PrivateCacheMap->FileOffset2.QuadPart;
556 PrivateCacheMap->BeyondLastByte1.QuadPart = PrivateCacheMap->BeyondLastByte2.QuadPart;
557 PrivateCacheMap->FileOffset2.QuadPart = FileOffset->QuadPart;
558 PrivateCacheMap->BeyondLastByte2.QuadPart = FileOffset->QuadPart + ReadLength;
559 }
560#endif
561
562 return TRUE;
563}
564
565/*
566 * @implemented
567 */
569NTAPI
576{
577 PROS_VACB Vacb;
578 PROS_SHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
580 LONGLONG CurrentOffset;
581 LONGLONG WriteEnd;
582
583 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%I64d Length=%lu Wait=%d Buffer=%p\n",
584 FileObject, FileOffset->QuadPart, Length, Wait, Buffer);
585
586 DPRINT("CcCopyWrite(FileObject 0x%p, FileOffset %I64x, "
587 "Length %lu, Wait %u, Buffer 0x%p)\n",
588 FileObject, FileOffset->QuadPart, Length, Wait, Buffer);
589
590 if (!SharedCacheMap)
591 return FALSE;
592
593 Status = RtlLongLongAdd(FileOffset->QuadPart, Length, &WriteEnd);
594 if (!NT_SUCCESS(Status))
596
597 ASSERT(WriteEnd <= SharedCacheMap->SectionSize.QuadPart);
598
599 CurrentOffset = FileOffset->QuadPart;
600 while(CurrentOffset < WriteEnd)
601 {
602 ULONG VacbOffset = CurrentOffset % VACB_MAPPING_GRANULARITY;
603 ULONG VacbLength = min(WriteEnd - CurrentOffset, VACB_MAPPING_GRANULARITY - VacbOffset);
604
605 Status = CcRosGetVacb(SharedCacheMap, CurrentOffset, &Vacb);
606 if (!NT_SUCCESS(Status))
607 {
609 return FALSE;
610 }
611
613 {
614 if (!CcRosEnsureVacbResident(Vacb, Wait, FALSE, VacbOffset, VacbLength))
615 {
616 return FALSE;
617 }
618
620 {
621 RtlCopyMemory((PVOID)((ULONG_PTR)Vacb->BaseAddress + VacbOffset), Buffer, VacbLength);
622 }
624 {
626 }
627 _SEH2_END;
628
629 Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength);
630 CurrentOffset += VacbLength;
631
632 /* Tell Mm */
633 Status = MmMakePagesDirty(NULL, Add2Ptr(Vacb->BaseAddress, VacbOffset), VacbLength);
634 if (!NT_SUCCESS(Status))
636 }
638 {
639 /* Do not mark the VACB as dirty if an exception was raised */
640 CcRosReleaseVacb(SharedCacheMap, Vacb, !_SEH2_AbnormalTermination(), FALSE);
641 }
642 _SEH2_END;
643 }
644
645 /* Flush if needed */
646 if (FileObject->Flags & FO_WRITE_THROUGH)
647 CcFlushCache(FileObject->SectionObjectPointer, FileOffset, Length, NULL);
648
649 return TRUE;
650}
651
652/*
653 * @implemented
654 */
655VOID
656NTAPI
659 IN PCC_POST_DEFERRED_WRITE PostRoutine,
662 IN ULONG BytesToWrite,
663 IN BOOLEAN Retrying)
664{
668
669 CCTRACE(CC_API_DEBUG, "FileObject=%p PostRoutine=%p Context1=%p Context2=%p BytesToWrite=%lu Retrying=%d\n",
670 FileObject, PostRoutine, Context1, Context2, BytesToWrite, Retrying);
671
672 /* Try to allocate a context for queueing the write operation */
674 /* If it failed, immediately execute the operation! */
675 if (Context == NULL)
676 {
677 PostRoutine(Context1, Context2);
678 return;
679 }
680
681 Fcb = FileObject->FsContext;
682
683 /* Otherwise, initialize the context */
685 Context->NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
686 Context->NodeByteSize = sizeof(DEFERRED_WRITE);
687 Context->FileObject = FileObject;
688 Context->PostRoutine = PostRoutine;
689 Context->Context1 = Context1;
690 Context->Context2 = Context2;
691 Context->BytesToWrite = BytesToWrite;
693
694 /* And queue it */
695 if (Retrying)
696 {
697 /* To the top, if that's a retry */
699 &Context->DeferredWriteLinks,
701 }
702 else
703 {
704 /* To the bottom, if that's a first time */
706 &Context->DeferredWriteLinks,
708 }
709
710 /* Try to execute the posted writes */
712
713 /* Schedule a lazy writer run to handle deferred writes */
716 {
718 }
720}
721
722/*
723 * @unimplemented
724 */
725VOID
726NTAPI
731 IN ULONG PageCount,
734{
735 LARGE_INTEGER LargeFileOffset;
737
738 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%lu Length=%lu PageCount=%lu Buffer=%p\n",
739 FileObject, FileOffset, Length, PageCount, Buffer);
740
742
743 LargeFileOffset.QuadPart = FileOffset;
745 &LargeFileOffset,
746 Length,
747 TRUE,
748 Buffer,
749 IoStatus);
750 ASSERT(Success == TRUE);
751}
752
753/*
754 * @unimplemented
755 */
756VOID
757NTAPI
763{
764 LARGE_INTEGER LargeFileOffset;
766
767 CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%lu Length=%lu Buffer=%p\n",
769
770 LargeFileOffset.QuadPart = FileOffset;
772 &LargeFileOffset,
773 Length,
774 TRUE,
775 Buffer);
776 ASSERT(Success == TRUE);
777}
778
779/*
780 * @implemented
781 */
783NTAPI
786 IN PLARGE_INTEGER StartOffset,
787 IN PLARGE_INTEGER EndOffset,
789{
793 PROS_VACB Vacb;
794 PROS_SHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
795
796 CCTRACE(CC_API_DEBUG, "FileObject=%p StartOffset=%I64u EndOffset=%I64u Wait=%d\n",
797 FileObject, StartOffset->QuadPart, EndOffset->QuadPart, Wait);
798
799 DPRINT("CcZeroData(FileObject 0x%p, StartOffset %I64x, EndOffset %I64x, "
800 "Wait %u)\n", FileObject, StartOffset->QuadPart, EndOffset->QuadPart,
801 Wait);
802
803 Length = EndOffset->QuadPart - StartOffset->QuadPart;
804 WriteOffset.QuadPart = StartOffset->QuadPart;
805
806 if (!SharedCacheMap)
807 {
808 /* Make this a non-cached write */
811 PMDL Mdl;
812 ULONG i;
813 ULONG CurrentLength;
814 PPFN_NUMBER PfnArray;
815
816 /* Setup our Mdl */
818 if (!Mdl)
820
821 PfnArray = MmGetMdlPfnArray(Mdl);
822 for (i = 0; i < BYTES_TO_PAGES(Mdl->ByteCount); i++)
823 PfnArray[i] = CcZeroPage;
824 Mdl->MdlFlags |= MDL_PAGES_LOCKED;
825
826 /* Perform the write sequencially */
827 while (Length > 0)
828 {
829 CurrentLength = min(Length, MAX_ZERO_LENGTH);
830
831 Mdl->ByteCount = CurrentLength;
832
835 if (Status == STATUS_PENDING)
836 {
838 Status = Iosb.Status;
839 }
840 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
841 {
842 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
843 }
844 if (!NT_SUCCESS(Status))
845 {
846 IoFreeMdl(Mdl);
848 }
849 WriteOffset.QuadPart += CurrentLength;
850 Length -= CurrentLength;
851 }
852
853 IoFreeMdl(Mdl);
854
855 return TRUE;
856 }
857
858 /* See if we should simply truncate the valid data length */
859 if ((StartOffset->QuadPart < SharedCacheMap->ValidDataLength.QuadPart) && (EndOffset->QuadPart >= SharedCacheMap->ValidDataLength.QuadPart))
860 {
861 DPRINT1("Truncating VDL.\n");
862 SharedCacheMap->ValidDataLength = *StartOffset;
863 return TRUE;
864 }
865
866 ASSERT(EndOffset->QuadPart <= SharedCacheMap->SectionSize.QuadPart);
867
868 while(WriteOffset.QuadPart < EndOffset->QuadPart)
869 {
870 ULONG VacbOffset = WriteOffset.QuadPart % VACB_MAPPING_GRANULARITY;
871 ULONG VacbLength = min(Length, VACB_MAPPING_GRANULARITY - VacbOffset);
872
873 Status = CcRosGetVacb(SharedCacheMap, WriteOffset.QuadPart, &Vacb);
874 if (!NT_SUCCESS(Status))
875 {
877 return FALSE;
878 }
879
881 {
882 if (!CcRosEnsureVacbResident(Vacb, Wait, FALSE, VacbOffset, VacbLength))
883 {
884 return FALSE;
885 }
886
887 RtlZeroMemory((PVOID)((ULONG_PTR)Vacb->BaseAddress + VacbOffset), VacbLength);
888
889 WriteOffset.QuadPart += VacbLength;
890 Length -= VacbLength;
891
892 /* Tell Mm */
893 Status = MmMakePagesDirty(NULL, Add2Ptr(Vacb->BaseAddress, VacbOffset), VacbLength);
894 if (!NT_SUCCESS(Status))
896 }
898 {
899 /* Do not mark the VACB as dirty if an exception was raised */
900 CcRosReleaseVacb(SharedCacheMap, Vacb, !_SEH2_AbnormalTermination(), FALSE);
901 }
902 _SEH2_END;
903 }
904
905 /* Flush if needed */
906 if (FileObject->Flags & FO_WRITE_THROUGH)
907 CcFlushCache(FileObject->SectionObjectPointer, StartOffset, EndOffset->QuadPart - StartOffset->QuadPart, NULL);
908
909 return TRUE;
910}
ULONG ReadLength
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
VOID NTAPI CcScheduleReadAhead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length)
Definition: cachesub.c:92
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
_In_ PFCB Fcb
Definition: cdprocs.h:159
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
return Iosb
Definition: create.c:4402
#define ULONG_PTR
Definition: config.h:101
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define RemoveTailList(ListHead)
Definition: env_spec_w32.h:975
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ Success
Definition: eventcreate.c:712
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FSRTL_FLAG_LIMIT_MODIFIED_PAGES
Definition: fsrtltypes.h:47
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define DbgPrint
Definition: hal.h:12
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
#define InterlockedAnd
Definition: interlocked.h:62
NTSTATUS NTAPI IoSynchronousPageWrite(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1146
#define Add2Ptr(PTR, INC)
LARGE_INTEGER CcIdleDelay
Definition: lazywrite.c:46
VOID CcScheduleLazyWriteScan(IN BOOLEAN NoDelay)
Definition: lazywrite.c:200
LAZY_WRITER LazyWriter
Definition: lazywrite.c:37
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
static void Clear(void)
Definition: treeview.c:386
#define min(a, b)
Definition: monoChain.cc:55
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
#define PRIVATE_CACHE_MAP_READ_AHEAD_ACTIVE
Definition: cctypes.h:64
struct _DEFERRED_WRITE DEFERRED_WRITE
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:209
#define DBG_UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:318
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
VOID NTAPI CcFastCopyWrite(IN PFILE_OBJECT FileObject, IN ULONG FileOffset, IN ULONG Length, IN PVOID Buffer)
Definition: copy.c:758
ULONG CcFastMdlReadNotPossible
Definition: copy.c:33
ULONG CcFastReadResourceMiss
Definition: copy.c:37
VOID CcPostDeferredWrites(VOID)
Definition: copy.c:73
static int CcpCheckInvalidUserBuffer(PEXCEPTION_POINTERS Except, PVOID Buffer, ULONG Length)
Definition: copy.c:442
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copy.c:570
static PFN_NUMBER CcZeroPage
Definition: copy.c:19
VOID NTAPI CcInitCacheZeroPage(VOID)
Definition: copy.c:56
ULONG CcFastReadNoWait
Definition: copy.c:36
VOID CcPerformReadAhead(IN PFILE_OBJECT FileObject)
Definition: copy.c:130
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN BOOLEAN Retrying)
Definition: copy.c:281
ULONG CcDataPages
Definition: copy.c:43
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)
Definition: copy.c:465
BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
Definition: copy.c:784
ULONG CcDataFlushes
Definition: copy.c:44
_CC_CAN_WRITE_RETRY
Definition: copy.c:24
@ RetryForceCheckPerFile
Definition: copy.c:27
@ FirstTry
Definition: copy.c:25
@ RetryAllowRemote
Definition: copy.c:26
@ RetryMasterLocked
Definition: copy.c:28
ULONG CcFastReadNotPossible
Definition: copy.c:34
ULONG CcRosTraceLevel
Definition: copy.c:31
ULONG CcFastMdlReadWait
Definition: copy.c:32
enum _CC_CAN_WRITE_RETRY CC_CAN_WRITE_RETRY
#define MAX_ZERO_LENGTH
Definition: copy.c:21
VOID NTAPI CcFastCopyRead(IN PFILE_OBJECT FileObject, IN ULONG FileOffset, IN ULONG Length, IN ULONG PageCount, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copy.c:727
ULONG CcFastReadWait
Definition: copy.c:35
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)
Definition: copy.c:657
KSPIN_LOCK CcDeferredWriteSpinLock
Definition: view.c:58
NTSTATUS CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:453
NTSTATUS CcRosRequestVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:914
LIST_ENTRY CcDeferredWrites
Definition: view.c:57
BOOLEAN CcRosEnsureVacbResident(_In_ PROS_VACB Vacb, _In_ BOOLEAN Wait, _In_ BOOLEAN NoRead, _In_ ULONG Offset, _In_ ULONG Length)
Definition: view.c:816
NTSTATUS CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:863
ULONG CcDirtyPageThreshold
Definition: view.c:55
ULONG CcTotalDirtyPages
Definition: view.c:56
#define NODE_TYPE_DEFERRED_WRITE
Definition: cc.h:286
#define CC_API_DEBUG
Definition: cc.h:11
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
@ MI_USAGE_CACHE
Definition: mm.h:342
ULONG MmThrottleTop
Definition: mminit.c:396
#define MC_SYSTEM
Definition: mm.h:115
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
#define MI_SET_USAGE(x)
Definition: mm.h:317
NTSTATUS NTAPI MmMakePagesDirty(_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
Definition: section.c:5103
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:281
ULONG MmThrottleBottom
Definition: mminit.c:397
#define ExRaiseStatus
Definition: ntoskrnl.h:108
BOOLEAN NTAPI IoIsFileOriginRemote(IN PFILE_OBJECT FileObject)
Definition: file.c:3278
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
ULONG * PPFN_NUMBER
Definition: ke.h:9
ULONG PFN_NUMBER
Definition: ke.h:9
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PACQUIRE_FOR_READ_AHEAD AcquireForReadAhead
Definition: cctypes.h:41
PRELEASE_FROM_READ_AHEAD ReleaseFromReadAhead
Definition: cctypes.h:42
PCC_POST_DEFERRED_WRITE PostRoutine
Definition: cctypes.h:175
PKEVENT Event
Definition: cctypes.h:174
ULONG BytesToWrite
Definition: cctypes.h:172
BOOLEAN LimitModifiedPages
Definition: cctypes.h:178
PVOID Context1
Definition: cctypes.h:176
PFILE_OBJECT FileObject
Definition: cctypes.h:171
PVOID Context2
Definition: cctypes.h:177
LIST_ENTRY DeferredWriteLinks
Definition: cctypes.h:173
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
ULONG Flags
Definition: ntfs.h:536
BOOLEAN ScanActive
Definition: cc.h:246
Definition: typedefs.h:120
PFN_NUMBER Total
Definition: mm.h:443
LARGE_INTEGER BeyondLastByte1
Definition: cctypes.h:78
LARGE_INTEGER FileOffset2
Definition: cctypes.h:79
LARGE_INTEGER FileOffset1
Definition: cctypes.h:77
ULONG ReadAheadLength[2]
Definition: cctypes.h:82
LARGE_INTEGER ReadAheadOffset[2]
Definition: cctypes.h:81
KSPIN_LOCK ReadAheadSpinLock
Definition: cctypes.h:83
ULONG UlongFlags
Definition: cctypes.h:73
LARGE_INTEGER BeyondLastByte2
Definition: cctypes.h:80
LARGE_INTEGER FileSize
Definition: cc.h:175
LARGE_INTEGER ValidDataLength
Definition: cc.h:178
PCACHE_MANAGER_CALLBACKS Callbacks
Definition: cc.h:185
ULONG DirtyPageThreshold
Definition: cc.h:188
PVOID LazyWriteContext
Definition: cc.h:186
ULONG DirtyPages
Definition: cc.h:180
LARGE_INTEGER SectionSize
Definition: cc.h:177
Definition: cc.h:207
PVOID BaseAddress
Definition: cc.h:209
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT Context1
Definition: tdikrnl.h:1095
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT _In_ PTDI_PNP_CONTEXT Context2
Definition: tdikrnl.h:1096
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
Definition: wdfusb.h:1921
#define VACB_MAPPING_GRANULARITY
VOID(NTAPI * PCC_POST_DEFERRED_WRITE)(_In_ PVOID Context1, _In_ PVOID Context2)
Definition: cctypes.h:66
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define FO_RANDOM_ACCESS
Definition: iotypes.h:1796
* PFILE_OBJECT
Definition: iotypes.h:1998
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
@ Executive
Definition: ketypes.h:403
@ LockQueueMasterLock
Definition: ketypes.h:651
#define BYTES_TO_PAGES(Size)
#define MmGetMdlPfnArray(_Mdl)
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
#define ObDereferenceObject
Definition: obfuncs.h:203