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"
21 device_extension
* Vcb
;
26 void do_read_job(PIRP Irp
) {
29 BOOL top_level
= is_top_level(Irp
);
30 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
31 PFILE_OBJECT FileObject
= IrpSp
->FileObject
;
32 fcb
* fcb
= FileObject
->FsContext
;
33 BOOL fcb_lock
= FALSE
;
35 Irp
->IoStatus
.Information
= 0;
37 if (!ExIsResourceAcquiredSharedLite(fcb
->Header
.Resource
)) {
38 ExAcquireResourceSharedLite(fcb
->Header
.Resource
, TRUE
);
43 Status
= do_read(Irp
, TRUE
, &bytes_read
);
44 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER
) {
45 Status
= _SEH2_GetExceptionCode();
49 ExReleaseResourceLite(fcb
->Header
.Resource
);
51 if (!NT_SUCCESS(Status
))
52 ERR("do_read returned %08x\n", Status
);
54 Irp
->IoStatus
.Status
= Status
;
56 TRACE("read %lu bytes\n", Irp
->IoStatus
.Information
);
58 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
61 IoSetTopLevelIrp(NULL
);
63 TRACE("returning %08x\n", Status
);
66 void do_write_job(device_extension
* Vcb
, PIRP Irp
) {
67 BOOL top_level
= is_top_level(Irp
);
71 Status
= write_file(Vcb
, Irp
, TRUE
, TRUE
);
72 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER
) {
73 Status
= _SEH2_GetExceptionCode();
76 if (!NT_SUCCESS(Status
))
77 ERR("write_file returned %08x\n", Status
);
79 Irp
->IoStatus
.Status
= Status
;
81 TRACE("wrote %u bytes\n", Irp
->IoStatus
.Information
);
83 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
86 IoSetTopLevelIrp(NULL
);
88 TRACE("returning %08x\n", Status
);
91 _Function_class_(WORKER_THREAD_ROUTINE
)
93 static void NTAPI
do_job(void* context
) {
95 static void do_job(void* context
) {
97 job_info
* ji
= context
;
98 PIO_STACK_LOCATION IrpSp
= ji
->Irp
? IoGetCurrentIrpStackLocation(ji
->Irp
) : NULL
;
100 if (IrpSp
->MajorFunction
== IRP_MJ_READ
) {
101 do_read_job(ji
->Irp
);
102 } else if (IrpSp
->MajorFunction
== IRP_MJ_WRITE
) {
103 do_write_job(ji
->Vcb
, ji
->Irp
);
109 BOOL
add_thread_job(device_extension
* Vcb
, PIRP Irp
) {
112 ji
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(job_info
), ALLOC_TAG
);
114 ERR("out of memory\n");
121 if (!Irp
->MdlAddress
) {
125 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
127 if (IrpSp
->MajorFunction
== IRP_MJ_READ
) {
129 len
= IrpSp
->Parameters
.Read
.Length
;
130 } else if (IrpSp
->MajorFunction
== IRP_MJ_WRITE
) {
132 len
= IrpSp
->Parameters
.Write
.Length
;
134 ERR("unexpected major function %u\n", IrpSp
->MajorFunction
);
139 Mdl
= IoAllocateMdl(Irp
->UserBuffer
, len
, FALSE
, FALSE
, Irp
);
142 ERR("out of memory\n");
148 MmProbeAndLockPages(Mdl
, Irp
->RequestorMode
, op
);
149 } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER
) {
150 ERR("MmProbeAndLockPages raised status %08x\n", _SEH2_GetExceptionCode());
153 Irp
->MdlAddress
= NULL
;
156 _SEH2_YIELD(return FALSE
);
160 ExInitializeWorkItem(&ji
->item
, do_job
, ji
);
161 ExQueueWorkItem(&ji
->item
, DelayedWorkQueue
);