update for HEAD-2003021201
[reactos.git] / ntoskrnl / cc / pin.c
1 /* $Id$
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 extern NPAGED_LOOKASIDE_LIST iBcbLookasideList;
30
31 /* FUNCTIONS *****************************************************************/
32
33 BOOLEAN STDCALL
34 CcMapData (IN PFILE_OBJECT FileObject,
35            IN PLARGE_INTEGER FileOffset,
36            IN ULONG Length,
37            IN BOOLEAN Wait,
38            OUT PVOID *pBcb,
39            OUT PVOID *pBuffer)
40 {
41   ULONG ReadOffset;
42   BOOLEAN Valid;
43   PBCB Bcb;
44   PCACHE_SEGMENT CacheSeg;
45   NTSTATUS Status;
46   PINTERNAL_BCB iBcb;
47   ULONG ROffset;
48   
49   DPRINT("CcMapData(FileObject %x, FileOffset %d, Length %d, Wait %d,"
50          " pBcb %x, pBuffer %x)\n", FileObject, (ULONG)FileOffset->QuadPart,
51          Length, Wait, pBcb, pBuffer);
52   
53   ReadOffset = FileOffset->QuadPart;
54   Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb;
55   assert(Bcb);
56
57   DPRINT("AllocationSize %d, FileSize %d\n",
58          (ULONG)Bcb->AllocationSize.QuadPart,
59          (ULONG)Bcb->FileSize.QuadPart);
60   
61   if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
62     {
63       return(FALSE);
64     }
65   ROffset = ROUND_DOWN (ReadOffset, Bcb->CacheSegmentSize);
66   Status = CcRosRequestCacheSegment(Bcb,
67                                     ROffset,
68                                     pBuffer,
69                                     &Valid,
70                                     &CacheSeg);
71   if (!NT_SUCCESS(Status))
72     {
73       return(FALSE);
74     }
75   if (!Valid)
76     {
77       if (!Wait)
78         {
79           CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
80           return(FALSE);
81         }
82       if (!NT_SUCCESS(ReadCacheSegment(CacheSeg)))
83         {
84           CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE);
85           return(FALSE);
86         }
87     }
88   *pBuffer += ReadOffset % Bcb->CacheSegmentSize;
89   iBcb = ExAllocateFromNPagedLookasideList(&iBcbLookasideList);
90   if (iBcb == NULL)
91     {
92       CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
93       return FALSE;
94     }
95   memset(iBcb, 0, sizeof(INTERNAL_BCB));
96   iBcb->CacheSegment = CacheSeg;
97   iBcb->Dirty = FALSE;
98   iBcb->PFCB.MappedLength = Length;
99   iBcb->PFCB.MappedFileOffset.QuadPart = FileOffset->QuadPart;
100   *pBcb = (PVOID)iBcb;
101   return(TRUE);
102 }
103
104 VOID STDCALL
105 CcUnpinData (IN PVOID Bcb)
106 {
107   PINTERNAL_BCB iBcb = Bcb;
108   CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE, 
109                            iBcb->Dirty, FALSE);
110   ExFreeToNPagedLookasideList(&iBcbLookasideList, iBcb);
111 }
112
113 VOID STDCALL
114 CcSetDirtyPinnedData (IN PVOID Bcb,
115                       IN PLARGE_INTEGER Lsn)
116 {
117    PINTERNAL_BCB iBcb = Bcb;
118    iBcb->Dirty = TRUE;
119 }
120