- Disabled write caching for meta data (FAT, directories) in
[reactos.git] / reactos / ntoskrnl / cc / pin.c
1 /* $Id: pin.c,v 1.5 2002/08/17 15:14:26 hbirr Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/cc/pin.c
6 * PURPOSE: Implements cache managers pinning interface
7 * PROGRAMMER: Hartmut Birr
8 * UPDATE HISTORY:
9 * Created 05.10.2001
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <ddk/ntifs.h>
16 #include <internal/mm.h>
17 #include <internal/cc.h>
18 #include <internal/pool.h>
19 #include <internal/io.h>
20 #include <ntos/minmax.h>
21
22 #define NDEBUG
23 #include <internal/debug.h>
24
25 /* GLOBALS *******************************************************************/
26
27 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
28
29 /* FUNCTIONS *****************************************************************/
30
31 typedef struct _INTERNAL_BCB
32 {
33 PUBLIC_BCB PFCB;
34 PCACHE_SEGMENT CacheSegment;
35 BOOLEAN Dirty;
36 } INTERNAL_BCB, *PINTERNAL_BCB;
37
38 BOOLEAN STDCALL
39 CcMapData (IN PFILE_OBJECT FileObject,
40 IN PLARGE_INTEGER FileOffset,
41 IN ULONG Length,
42 IN BOOLEAN Wait,
43 OUT PVOID *pBcb,
44 OUT PVOID *pBuffer)
45 {
46 ULONG ReadOffset;
47 BOOLEAN Valid;
48 PBCB Bcb;
49 PCACHE_SEGMENT CacheSeg;
50 NTSTATUS Status;
51 PINTERNAL_BCB iBcb;
52 ULONG ROffset;
53
54 DPRINT("CcMapData(FileObject %x, FileOffset %d, Length %d, Wait %d,"
55 " pBcb %x, pBuffer %x)\n", FileObject, (ULONG)FileOffset->QuadPart,
56 Length, Wait, pBcb, pBuffer);
57
58 ReadOffset = FileOffset->QuadPart;
59 Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
60
61 DPRINT("AllocationSize %d, FileSize %d\n",
62 (ULONG)Bcb->AllocationSize.QuadPart,
63 (ULONG)Bcb->FileSize.QuadPart);
64
65 if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
66 {
67 return(FALSE);
68 }
69 ROffset = ROUND_DOWN (ReadOffset, Bcb->CacheSegmentSize);
70 Status = CcRosRequestCacheSegment(Bcb,
71 ROffset,
72 pBuffer,
73 &Valid,
74 &CacheSeg);
75 if (!NT_SUCCESS(Status))
76 {
77 return(FALSE);
78 }
79 if (!Valid)
80 {
81 if (!Wait)
82 {
83 CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
84 return(FALSE);
85 }
86 if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
87 {
88 return(FALSE);
89 }
90 }
91 *pBuffer += ReadOffset % Bcb->CacheSegmentSize;
92 iBcb = ExAllocatePool (NonPagedPool, sizeof(INTERNAL_BCB));
93 if (iBcb == NULL)
94 {
95 CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
96 return FALSE;
97 }
98 iBcb->CacheSegment = CacheSeg;
99 iBcb->Dirty = FALSE;
100 iBcb->PFCB.MappedLength = Length;
101 iBcb->PFCB.MappedFileOffset.QuadPart = FileOffset->QuadPart;
102 *pBcb = (PVOID)iBcb;
103 return(TRUE);
104 }
105
106 VOID STDCALL
107 CcUnpinData (IN PVOID Bcb)
108 {
109 PINTERNAL_BCB iBcb = Bcb;
110 CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE,
111 iBcb->Dirty, FALSE);
112 ExFreePool(iBcb);
113 }
114
115 VOID STDCALL
116 CcSetDirtyPinnedData (IN PVOID Bcb,
117 IN PLARGE_INTEGER Lsn)
118 {
119 PINTERNAL_BCB iBcb = Bcb;
120 #if 0
121 iBcb->Dirty = TRUE;
122 #else
123 WriteCacheSegment(iBcb->CacheSegment);
124 #endif
125 }
126