xref: /reactos/drivers/filesystems/btrfs/cache.c (revision 5100859e)
1 /* Copyright (c) Mark Harmstone 2016-17
2  *
3  * This file is part of WinBtrfs.
4  *
5  * WinBtrfs is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public Licence as published by
7  * the Free Software Foundation, either version 3 of the Licence, or
8  * (at your option) any later version.
9  *
10  * WinBtrfs is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public Licence for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public Licence
16  * along with WinBtrfs.  If not, see <http://www.gnu.org/licenses/>. */
17 
18 #include "btrfs_drv.h"
19 
20 CACHE_MANAGER_CALLBACKS* cache_callbacks;
21 
22 #ifdef __REACTOS__
23 static BOOLEAN NTAPI acquire_for_lazy_write(PVOID Context, BOOLEAN Wait) {
24 #else
25 static BOOLEAN acquire_for_lazy_write(PVOID Context, BOOLEAN Wait) {
26 #endif
27     PFILE_OBJECT FileObject = Context;
28     fcb* fcb = FileObject->FsContext;
29 
30     TRACE("(%p, %u)\n", Context, Wait);
31 
32     if (!ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, Wait))
33         return FALSE;
34 
35     if (!ExAcquireResourceExclusiveLite(fcb->Header.Resource, Wait)) {
36         ExReleaseResourceLite(&fcb->Vcb->tree_lock);
37         return FALSE;
38     }
39 
40     fcb->lazy_writer_thread = KeGetCurrentThread();
41 
42     IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
43 
44     return TRUE;
45 }
46 
47 #ifdef __REACTOS__
48 static void NTAPI release_from_lazy_write(PVOID Context) {
49 #else
50 static void release_from_lazy_write(PVOID Context) {
51 #endif
52     PFILE_OBJECT FileObject = Context;
53     fcb* fcb = FileObject->FsContext;
54 
55     TRACE("(%p)\n", Context);
56 
57     fcb->lazy_writer_thread = NULL;
58 
59     ExReleaseResourceLite(fcb->Header.Resource);
60 
61     ExReleaseResourceLite(&fcb->Vcb->tree_lock);
62 
63     if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
64         IoSetTopLevelIrp(NULL);
65 }
66 
67 #ifdef __REACTOS__
68 static BOOLEAN NTAPI acquire_for_read_ahead(PVOID Context, BOOLEAN Wait) {
69 #else
70 static BOOLEAN acquire_for_read_ahead(PVOID Context, BOOLEAN Wait) {
71 #endif
72     PFILE_OBJECT FileObject = Context;
73     fcb* fcb = FileObject->FsContext;
74 
75     TRACE("(%p, %u)\n", Context, Wait);
76 
77     if (!ExAcquireResourceSharedLite(fcb->Header.Resource, Wait))
78         return FALSE;
79 
80     IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
81 
82     return TRUE;
83 }
84 
85 #ifdef __REACTOS__
86 static void NTAPI release_from_read_ahead(PVOID Context) {
87 #else
88 static void release_from_read_ahead(PVOID Context) {
89 #endif
90     PFILE_OBJECT FileObject = Context;
91     fcb* fcb = FileObject->FsContext;
92 
93     TRACE("(%p)\n", Context);
94 
95     ExReleaseResourceLite(fcb->Header.Resource);
96 
97     if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
98         IoSetTopLevelIrp(NULL);
99 }
100 
101 NTSTATUS init_cache() {
102     cache_callbacks = ExAllocatePoolWithTag(NonPagedPool, sizeof(CACHE_MANAGER_CALLBACKS), ALLOC_TAG);
103     if (!cache_callbacks) {
104         ERR("out of memory\n");
105         return STATUS_INSUFFICIENT_RESOURCES;
106     }
107 
108     cache_callbacks->AcquireForLazyWrite = acquire_for_lazy_write;
109     cache_callbacks->ReleaseFromLazyWrite = release_from_lazy_write;
110     cache_callbacks->AcquireForReadAhead = acquire_for_read_ahead;
111     cache_callbacks->ReleaseFromReadAhead = release_from_read_ahead;
112 
113     return STATUS_SUCCESS;
114 }
115 
116 void free_cache() {
117     ExFreePool(cache_callbacks);
118 }
119