xref: /reactos/drivers/filesystems/btrfs/cache.c (revision 62e630de)
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