xref: /reactos/drivers/filesystems/btrfs/cache.c (revision 62e630de)
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 
acquire_for_lazy_write(PVOID Context,BOOLEAN Wait)22 static BOOLEAN __stdcall acquire_for_lazy_write(PVOID Context, BOOLEAN Wait) {
23     PFILE_OBJECT FileObject = Context;
24     fcb* fcb = FileObject->FsContext;
25 
26     TRACE("(%p, %u)\n", Context, Wait);
27 
28     if (!ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, Wait))
29         return false;
30 
31     if (!ExAcquireResourceExclusiveLite(fcb->Header.Resource, Wait)) {
32         ExReleaseResourceLite(&fcb->Vcb->tree_lock);
33         return false;
34     }
35 
36     fcb->lazy_writer_thread = KeGetCurrentThread();
37 
38     IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
39 
40     return true;
41 }
42 
release_from_lazy_write(PVOID Context)43 static void __stdcall release_from_lazy_write(PVOID Context) {
44     PFILE_OBJECT FileObject = Context;
45     fcb* fcb = FileObject->FsContext;
46 
47     TRACE("(%p)\n", Context);
48 
49     fcb->lazy_writer_thread = NULL;
50 
51     ExReleaseResourceLite(fcb->Header.Resource);
52 
53     ExReleaseResourceLite(&fcb->Vcb->tree_lock);
54 
55     if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
56         IoSetTopLevelIrp(NULL);
57 }
58 
acquire_for_read_ahead(PVOID Context,BOOLEAN Wait)59 static BOOLEAN __stdcall acquire_for_read_ahead(PVOID Context, BOOLEAN Wait) {
60     PFILE_OBJECT FileObject = Context;
61     fcb* fcb = FileObject->FsContext;
62 
63     TRACE("(%p, %u)\n", Context, Wait);
64 
65     if (!ExAcquireResourceSharedLite(fcb->Header.Resource, Wait))
66         return false;
67 
68     IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
69 
70     return true;
71 }
72 
release_from_read_ahead(PVOID Context)73 static void __stdcall release_from_read_ahead(PVOID Context) {
74     PFILE_OBJECT FileObject = Context;
75     fcb* fcb = FileObject->FsContext;
76 
77     TRACE("(%p)\n", Context);
78 
79     ExReleaseResourceLite(fcb->Header.Resource);
80 
81     if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
82         IoSetTopLevelIrp(NULL);
83 }
84 
init_cache()85 void init_cache() {
86     cache_callbacks.AcquireForLazyWrite = acquire_for_lazy_write;
87     cache_callbacks.ReleaseFromLazyWrite = release_from_lazy_write;
88     cache_callbacks.AcquireForReadAhead = acquire_for_read_ahead;
89     cache_callbacks.ReleaseFromReadAhead = release_from_read_ahead;
90 }
91