[BTRFS]
[reactos.git] / reactos / drivers / filesystems / btrfs / flushthread.c
1 /* Copyright (c) Mark Harmstone 2016
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 static void do_flush(device_extension* Vcb) {
21 LIST_ENTRY rollback;
22
23 InitializeListHead(&rollback);
24
25 FsRtlEnterFileSystem();
26
27 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);
28
29 if (Vcb->need_write && !Vcb->readonly)
30 do_write(Vcb, NULL, &rollback);
31
32 free_trees(Vcb);
33
34 clear_rollback(&rollback);
35
36 ExReleaseResourceLite(&Vcb->tree_lock);
37
38 FsRtlExitFileSystem();
39 }
40
41 void STDCALL flush_thread(void* context) {
42 DEVICE_OBJECT* devobj = context;
43 device_extension* Vcb = devobj->DeviceExtension;
44 LARGE_INTEGER due_time;
45
46 ObReferenceObject(devobj);
47
48 KeInitializeTimer(&Vcb->flush_thread_timer);
49
50 due_time.QuadPart = (UINT64)Vcb->options.flush_interval * -10000000;
51
52 KeSetTimer(&Vcb->flush_thread_timer, due_time, NULL);
53
54 while (TRUE) {
55 KeWaitForSingleObject(&Vcb->flush_thread_timer, Executive, KernelMode, FALSE, NULL);
56
57 if (!(devobj->Vpb->Flags & VPB_MOUNTED) || Vcb->removing)
58 break;
59
60 do_flush(Vcb);
61
62 KeSetTimer(&Vcb->flush_thread_timer, due_time, NULL);
63 }
64
65 ObDereferenceObject(devobj);
66 KeCancelTimer(&Vcb->flush_thread_timer);
67
68 KeSetEvent(&Vcb->flush_thread_finished, 0, FALSE);
69
70 PsTerminateSystemThread(STATUS_SUCCESS);
71 }