1 /* Copyright (c) Mark Harmstone 2016-17
3 * This file is part of WinBtrfs.
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.
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.
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/>. */
18 #include "btrfs_drv.h"
20 CACHE_MANAGER_CALLBACKS
* cache_callbacks
;
23 static BOOLEAN NTAPI
acquire_for_lazy_write(PVOID Context
, BOOLEAN Wait
) {
25 static BOOLEAN
acquire_for_lazy_write(PVOID Context
, BOOLEAN Wait
) {
27 PFILE_OBJECT FileObject
= Context
;
28 fcb
* fcb
= FileObject
->FsContext
;
30 TRACE("(%p, %u)\n", Context
, Wait
);
32 if (!ExAcquireResourceSharedLite(&fcb
->Vcb
->tree_lock
, Wait
))
35 if (!ExAcquireResourceExclusiveLite(fcb
->Header
.Resource
, Wait
)) {
36 ExReleaseResourceLite(&fcb
->Vcb
->tree_lock
);
40 fcb
->lazy_writer_thread
= KeGetCurrentThread();
42 IoSetTopLevelIrp((PIRP
)FSRTL_CACHE_TOP_LEVEL_IRP
);
48 static void NTAPI
release_from_lazy_write(PVOID Context
) {
50 static void release_from_lazy_write(PVOID Context
) {
52 PFILE_OBJECT FileObject
= Context
;
53 fcb
* fcb
= FileObject
->FsContext
;
55 TRACE("(%p)\n", Context
);
57 fcb
->lazy_writer_thread
= NULL
;
59 ExReleaseResourceLite(fcb
->Header
.Resource
);
61 ExReleaseResourceLite(&fcb
->Vcb
->tree_lock
);
63 if (IoGetTopLevelIrp() == (PIRP
)FSRTL_CACHE_TOP_LEVEL_IRP
)
64 IoSetTopLevelIrp(NULL
);
68 static BOOLEAN NTAPI
acquire_for_read_ahead(PVOID Context
, BOOLEAN Wait
) {
70 static BOOLEAN
acquire_for_read_ahead(PVOID Context
, BOOLEAN Wait
) {
72 PFILE_OBJECT FileObject
= Context
;
73 fcb
* fcb
= FileObject
->FsContext
;
75 TRACE("(%p, %u)\n", Context
, Wait
);
77 if (!ExAcquireResourceSharedLite(fcb
->Header
.Resource
, Wait
))
80 IoSetTopLevelIrp((PIRP
)FSRTL_CACHE_TOP_LEVEL_IRP
);
86 static void NTAPI
release_from_read_ahead(PVOID Context
) {
88 static void release_from_read_ahead(PVOID Context
) {
90 PFILE_OBJECT FileObject
= Context
;
91 fcb
* fcb
= FileObject
->FsContext
;
93 TRACE("(%p)\n", Context
);
95 ExReleaseResourceLite(fcb
->Header
.Resource
);
97 if (IoGetTopLevelIrp() == (PIRP
)FSRTL_CACHE_TOP_LEVEL_IRP
)
98 IoSetTopLevelIrp(NULL
);
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
;
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
;
113 return STATUS_SUCCESS
;
117 ExFreePool(cache_callbacks
);