1c2c66affSColin Finck /* Copyright (c) Mark Harmstone 2016-17
2c2c66affSColin Finck *
3c2c66affSColin Finck * This file is part of WinBtrfs.
4c2c66affSColin Finck *
5c2c66affSColin Finck * WinBtrfs is free software: you can redistribute it and/or modify
6c2c66affSColin Finck * it under the terms of the GNU Lesser General Public Licence as published by
7c2c66affSColin Finck * the Free Software Foundation, either version 3 of the Licence, or
8c2c66affSColin Finck * (at your option) any later version.
9c2c66affSColin Finck *
10c2c66affSColin Finck * WinBtrfs is distributed in the hope that it will be useful,
11c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
12c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c2c66affSColin Finck * GNU Lesser General Public Licence for more details.
14c2c66affSColin Finck *
15c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public Licence
16c2c66affSColin Finck * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
17c2c66affSColin Finck
18c2c66affSColin Finck #include "btrfs_drv.h"
19c2c66affSColin Finck
20*62e630deSPierre Schweitzer CACHE_MANAGER_CALLBACKS cache_callbacks;
21c2c66affSColin Finck
acquire_for_lazy_write(PVOID Context,BOOLEAN Wait)22318da0c1SPierre Schweitzer static BOOLEAN __stdcall acquire_for_lazy_write(PVOID Context, BOOLEAN Wait) {
23c2c66affSColin Finck PFILE_OBJECT FileObject = Context;
24c2c66affSColin Finck fcb* fcb = FileObject->FsContext;
25c2c66affSColin Finck
26c2c66affSColin Finck TRACE("(%p, %u)\n", Context, Wait);
27c2c66affSColin Finck
28c2c66affSColin Finck if (!ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, Wait))
29318da0c1SPierre Schweitzer return false;
30c2c66affSColin Finck
31c2c66affSColin Finck if (!ExAcquireResourceExclusiveLite(fcb->Header.Resource, Wait)) {
32c2c66affSColin Finck ExReleaseResourceLite(&fcb->Vcb->tree_lock);
33318da0c1SPierre Schweitzer return false;
34c2c66affSColin Finck }
35c2c66affSColin Finck
36c2c66affSColin Finck fcb->lazy_writer_thread = KeGetCurrentThread();
37c2c66affSColin Finck
38c2c66affSColin Finck IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
39c2c66affSColin Finck
40318da0c1SPierre Schweitzer return true;
41c2c66affSColin Finck }
42c2c66affSColin Finck
release_from_lazy_write(PVOID Context)43318da0c1SPierre Schweitzer static void __stdcall release_from_lazy_write(PVOID Context) {
44c2c66affSColin Finck PFILE_OBJECT FileObject = Context;
45c2c66affSColin Finck fcb* fcb = FileObject->FsContext;
46c2c66affSColin Finck
47c2c66affSColin Finck TRACE("(%p)\n", Context);
48c2c66affSColin Finck
49c2c66affSColin Finck fcb->lazy_writer_thread = NULL;
50c2c66affSColin Finck
51c2c66affSColin Finck ExReleaseResourceLite(fcb->Header.Resource);
52c2c66affSColin Finck
53c2c66affSColin Finck ExReleaseResourceLite(&fcb->Vcb->tree_lock);
54c2c66affSColin Finck
55c2c66affSColin Finck if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
56c2c66affSColin Finck IoSetTopLevelIrp(NULL);
57c2c66affSColin Finck }
58c2c66affSColin Finck
acquire_for_read_ahead(PVOID Context,BOOLEAN Wait)59318da0c1SPierre Schweitzer static BOOLEAN __stdcall acquire_for_read_ahead(PVOID Context, BOOLEAN Wait) {
60c2c66affSColin Finck PFILE_OBJECT FileObject = Context;
61c2c66affSColin Finck fcb* fcb = FileObject->FsContext;
62c2c66affSColin Finck
63c2c66affSColin Finck TRACE("(%p, %u)\n", Context, Wait);
64c2c66affSColin Finck
65c2c66affSColin Finck if (!ExAcquireResourceSharedLite(fcb->Header.Resource, Wait))
66318da0c1SPierre Schweitzer return false;
67c2c66affSColin Finck
68c2c66affSColin Finck IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
69c2c66affSColin Finck
70318da0c1SPierre Schweitzer return true;
71c2c66affSColin Finck }
72c2c66affSColin Finck
release_from_read_ahead(PVOID Context)73318da0c1SPierre Schweitzer static void __stdcall release_from_read_ahead(PVOID Context) {
74c2c66affSColin Finck PFILE_OBJECT FileObject = Context;
75c2c66affSColin Finck fcb* fcb = FileObject->FsContext;
76c2c66affSColin Finck
77c2c66affSColin Finck TRACE("(%p)\n", Context);
78c2c66affSColin Finck
79c2c66affSColin Finck ExReleaseResourceLite(fcb->Header.Resource);
80c2c66affSColin Finck
81c2c66affSColin Finck if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
82c2c66affSColin Finck IoSetTopLevelIrp(NULL);
83c2c66affSColin Finck }
84c2c66affSColin Finck
init_cache()85*62e630deSPierre Schweitzer void init_cache() {
86*62e630deSPierre Schweitzer cache_callbacks.AcquireForLazyWrite = acquire_for_lazy_write;
87*62e630deSPierre Schweitzer cache_callbacks.ReleaseFromLazyWrite = release_from_lazy_write;
88*62e630deSPierre Schweitzer cache_callbacks.AcquireForReadAhead = acquire_for_read_ahead;
89*62e630deSPierre Schweitzer cache_callbacks.ReleaseFromReadAhead = release_from_read_ahead;
90c2c66affSColin Finck }
91