[REISERFS]
[reactos.git] / reactos / drivers / filesystems / btrfs / fastio.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 FAST_IO_DISPATCH FastIoDispatch;
21
22 static void STDCALL acquire_file_for_create_section(PFILE_OBJECT FileObject) {
23 TRACE("STUB: acquire_file_for_create_section\n");
24 }
25
26 static void STDCALL release_file_for_create_section(PFILE_OBJECT FileObject) {
27 TRACE("STUB: release_file_for_create_section\n");
28 }
29
30 static BOOLEAN STDCALL fast_query_basic_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_BASIC_INFORMATION fbi,
31 PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
32 fcb* fcb;
33 ccb* ccb;
34
35 TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fbi, IoStatus, DeviceObject);
36
37 if (!FileObject)
38 return FALSE;
39
40 fcb = FileObject->FsContext;
41
42 if (!fcb)
43 return FALSE;
44
45 ccb = FileObject->FsContext2;
46
47 if (!ccb)
48 return FALSE;
49
50 if (!(ccb->access & (FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES)))
51 return FALSE;
52
53 if (fcb->ads) {
54 if (!ccb || !ccb->fileref || !ccb->fileref->parent || !ccb->fileref->parent->fcb)
55 return FALSE;
56
57 fcb = ccb->fileref->parent->fcb;
58 }
59
60 FsRtlEnterFileSystem();
61
62 if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
63 FsRtlExitFileSystem();
64 return FALSE;
65 }
66
67 fbi->CreationTime.QuadPart = unix_time_to_win(&fcb->inode_item.otime);
68 fbi->LastAccessTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_atime);
69 fbi->LastWriteTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_mtime);
70 fbi->ChangeTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_ctime);
71 fbi->FileAttributes = fcb->atts;
72
73 IoStatus->Status = STATUS_SUCCESS;
74 IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
75
76 ExReleaseResourceLite(fcb->Header.Resource);
77
78 FsRtlExitFileSystem();
79
80 return TRUE;
81 }
82
83 static BOOLEAN STDCALL fast_query_standard_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_STANDARD_INFORMATION fsi,
84 PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
85 fcb* fcb;
86 ccb* ccb;
87 BOOL ads;
88 ULONG adssize;
89
90 TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fsi, IoStatus, DeviceObject);
91
92 if (!FileObject)
93 return FALSE;
94
95 fcb = FileObject->FsContext;
96 ccb = FileObject->FsContext2;
97
98 if (!fcb)
99 return FALSE;
100
101 FsRtlEnterFileSystem();
102
103 if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
104 FsRtlExitFileSystem();
105 return FALSE;
106 }
107
108 ads = fcb->ads;
109
110 if (ads) {
111 struct _fcb* fcb2;
112
113 if (!ccb || !ccb->fileref || !ccb->fileref->parent || !ccb->fileref->parent->fcb) {
114 ExReleaseResourceLite(fcb->Header.Resource);
115 FsRtlExitFileSystem();
116 return FALSE;
117 }
118
119 adssize = fcb->adsdata.Length;
120
121 fcb2 = ccb->fileref->parent->fcb;
122
123 ExReleaseResourceLite(fcb->Header.Resource);
124
125 fcb = fcb2;
126
127 if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
128 FsRtlExitFileSystem();
129 return FALSE;
130 }
131
132 fsi->AllocationSize.QuadPart = fsi->EndOfFile.QuadPart = adssize;
133 fsi->NumberOfLinks = fcb->inode_item.st_nlink;
134 fsi->Directory = S_ISDIR(fcb->inode_item.st_mode);
135 } else {
136 fsi->AllocationSize.QuadPart = S_ISDIR(fcb->inode_item.st_mode) ? 0 : sector_align(fcb->inode_item.st_size, fcb->Vcb->superblock.sector_size);
137 fsi->EndOfFile.QuadPart = S_ISDIR(fcb->inode_item.st_mode) ? 0 : fcb->inode_item.st_size;
138 fsi->NumberOfLinks = fcb->inode_item.st_nlink;
139 fsi->Directory = S_ISDIR(fcb->inode_item.st_mode);
140 }
141
142 fsi->DeletePending = ccb->fileref ? ccb->fileref->delete_on_close : FALSE;
143
144 IoStatus->Status = STATUS_SUCCESS;
145 IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
146
147 ExReleaseResourceLite(fcb->Header.Resource);
148
149 FsRtlExitFileSystem();
150
151 return TRUE;
152 }
153
154 static BOOLEAN STDCALL fast_io_query_open(PIRP Irp, PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, PDEVICE_OBJECT DeviceObject) {
155 TRACE("STUB: fast_io_query_open\n");
156
157 return FALSE;
158 }
159
160 static BOOLEAN STDCALL fast_io_check_if_possible(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait,
161 ULONG LockKey, BOOLEAN CheckForReadOperation, PIO_STATUS_BLOCK IoStatus,
162 PDEVICE_OBJECT DeviceObject) {
163 fcb* fcb = FileObject->FsContext;
164 LARGE_INTEGER len2;
165
166 TRACE("(%p, %llx, %x, %x, %x, %x, %p, %p)\n", FileObject, FileOffset->QuadPart, Length, Wait, LockKey, CheckForReadOperation, IoStatus, DeviceObject);
167
168 len2.QuadPart = Length;
169
170 if (CheckForReadOperation) {
171 if (FsRtlFastCheckLockForRead(&fcb->lock, FileOffset, &len2, LockKey, FileObject, PsGetCurrentProcess()))
172 return TRUE;
173 } else {
174 if (!fcb->Vcb->readonly && !(fcb->subvol->root_item.flags & BTRFS_SUBVOL_READONLY) && FsRtlFastCheckLockForWrite(&fcb->lock, FileOffset, &len2, LockKey, FileObject, PsGetCurrentProcess()))
175 return TRUE;
176 }
177
178 return FALSE;
179 }
180
181 static BOOLEAN STDCALL fast_io_lock(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject){
182 TRACE("STUB: fast_io_lock\n");
183 return FALSE;
184 }
185
186 static BOOLEAN STDCALL fast_io_unlock_single(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject){
187 TRACE("STUB: fast_io_unlock_single\n");
188 return FALSE;
189 }
190
191 static BOOLEAN STDCALL fast_io_unlock_all(PFILE_OBJECT FileObject, PEPROCESS ProcessId, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject){
192 TRACE("STUB: fast_io_unlock_all\n");
193 return FALSE;
194 }
195
196 static BOOLEAN STDCALL fast_io_unlock_all_by_key(PFILE_OBJECT FileObject, PVOID ProcessId, ULONG Key, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject){
197 TRACE("STUB: fast_io_unlock_all_by_key\n");
198 return FALSE;
199 }
200
201 static BOOLEAN STDCALL fast_io_device_control(PFILE_OBJECT FileObject, BOOLEAN Wait, PVOID InputBuffer OPTIONAL, ULONG InputBufferLength, PVOID OutputBuffer OPTIONAL, ULONG OutputBufferLength, ULONG IoControlCode, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject){
202 TRACE("STUB: fast_io_device_control\n");
203 return FALSE;
204 }
205
206 static VOID STDCALL fast_io_detach_device(PDEVICE_OBJECT SourceDevice, PDEVICE_OBJECT TargetDevice){
207 TRACE("STUB: fast_io_detach_device\n");
208 }
209
210 static BOOLEAN STDCALL fast_io_query_network_open_info(PFILE_OBJECT FileObject, BOOLEAN Wait, struct _FILE_NETWORK_OPEN_INFORMATION *Buffer, struct _IO_STATUS_BLOCK *IoStatus, PDEVICE_OBJECT DeviceObject){
211 TRACE("STUB: fast_io_query_network_open_info\n");
212 return FALSE;
213 }
214
215 static NTSTATUS STDCALL fast_io_acquire_for_mod_write(PFILE_OBJECT FileObject, PLARGE_INTEGER EndingOffset, struct _ERESOURCE **ResourceToRelease, PDEVICE_OBJECT DeviceObject) {
216 fcb* fcb;
217
218 TRACE("(%p, %llx, %p, %p)\n", FileObject, EndingOffset->QuadPart, ResourceToRelease, DeviceObject);
219
220 fcb = FileObject->FsContext;
221
222 if (!fcb)
223 return STATUS_INVALID_PARAMETER;
224
225 *ResourceToRelease = fcb->Header.PagingIoResource;
226
227 if (!ExAcquireResourceSharedLite(*ResourceToRelease, FALSE))
228 return STATUS_CANT_WAIT;
229
230 return STATUS_SUCCESS;
231 }
232
233 static BOOLEAN STDCALL fast_io_read_compressed(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, ULONG LockKey, PVOID Buffer, PMDL *MdlChain, PIO_STATUS_BLOCK IoStatus, struct _COMPRESSED_DATA_INFO *CompressedDataInfo, ULONG CompressedDataInfoLength, PDEVICE_OBJECT DeviceObject){
234 TRACE("STUB: fast_io_read_compressed\n");
235 return FALSE;
236 }
237
238 static BOOLEAN STDCALL fast_io_write_compressed(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, ULONG LockKey, PVOID Buffer, PMDL *MdlChain, PIO_STATUS_BLOCK IoStatus, struct _COMPRESSED_DATA_INFO *CompressedDataInfo, ULONG CompressedDataInfoLength, PDEVICE_OBJECT DeviceObject){
239 TRACE("STUB: fast_io_write_compressed\n");
240 return FALSE;
241 }
242
243 static BOOLEAN STDCALL fast_io_mdl_read_complete_compressed(PFILE_OBJECT FileObject, PMDL MdlChain, PDEVICE_OBJECT DeviceObject){
244 TRACE("STUB: fast_io_mdl_read_complete_compressed\n");
245 return FALSE;
246 }
247
248 static BOOLEAN STDCALL fast_io_mdl_write_complete_compressed(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PMDL MdlChain, PDEVICE_OBJECT DeviceObject){
249 TRACE("STUB: fast_io_mdl_write_complete_compressed\n");
250 return FALSE;
251 }
252
253 static NTSTATUS STDCALL fast_io_release_for_mod_write(PFILE_OBJECT FileObject, struct _ERESOURCE *ResourceToRelease, PDEVICE_OBJECT DeviceObject){
254 TRACE("STUB: fast_io_release_for_mod_write\n");
255 return STATUS_NOT_IMPLEMENTED;
256 }
257
258 static NTSTATUS STDCALL fast_io_acquire_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject){
259 TRACE("STUB: fast_io_acquire_for_ccflush\n");
260 return STATUS_SUCCESS;
261 }
262
263 static NTSTATUS STDCALL fast_io_release_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject){
264 TRACE("STUB: fast_io_release_for_ccflush\n");
265 return STATUS_SUCCESS;
266 }
267
268 static BOOLEAN STDCALL fast_io_write(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
269 TRACE("(%p (%.*S), %llx, %x, %x, %x, %p, %p, %p)\n", FileObject, FileObject->FileName.Length / sizeof(WCHAR), FileObject->FileName.Buffer,
270 *FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
271
272 if (FsRtlCopyWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject)) {
273 fcb* fcb = FileObject->FsContext;
274
275 fcb->inode_item.st_size = fcb->Header.FileSize.QuadPart;
276
277 return TRUE;
278 }
279
280 return FALSE;
281 }
282
283 #ifdef _DEBUG
284 static BOOLEAN STDCALL fast_io_read(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
285 TRACE("(%p, %p, %x, %x, %x, %p, %p, %p)\n", FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
286
287 return FsRtlCopyRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
288 }
289
290 static BOOLEAN STDCALL fast_io_mdl_read(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, ULONG LockKey, PMDL* MdlChain, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
291 TRACE("(%p, %p, %x, %x, %p, %p, %p)\n", FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject);
292
293 return FsRtlMdlReadDev(FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject);
294 }
295
296 static BOOLEAN STDCALL fast_io_mdl_read_complete(PFILE_OBJECT FileObject, PMDL MdlChain, PDEVICE_OBJECT DeviceObject) {
297 TRACE("(%p, %p, %p)\n", FileObject, MdlChain, DeviceObject);
298
299 return FsRtlMdlReadCompleteDev(FileObject, MdlChain, DeviceObject);
300 }
301
302 static BOOLEAN STDCALL fast_io_prepare_mdl_write(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, ULONG LockKey, PMDL* MdlChain, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
303 TRACE("(%p, %p, %x, %x, %p, %p, %p)\n", FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject);
304
305 return FsRtlPrepareMdlWriteDev(FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject);
306 }
307
308 static BOOLEAN STDCALL fast_io_mdl_write_complete(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PMDL MdlChain, PDEVICE_OBJECT DeviceObject) {
309 TRACE("(%p, %p, %p, %p)\n", FileObject, FileOffset, MdlChain, DeviceObject);
310
311 return FsRtlMdlWriteCompleteDev(FileObject, FileOffset, MdlChain, DeviceObject);
312 }
313 #endif
314
315 void __stdcall init_fast_io_dispatch(FAST_IO_DISPATCH** fiod) {
316 RtlZeroMemory(&FastIoDispatch, sizeof(FastIoDispatch));
317
318 FastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
319
320 FastIoDispatch.FastIoCheckIfPossible = fast_io_check_if_possible;
321 FastIoDispatch.FastIoQueryBasicInfo = fast_query_basic_info;
322 FastIoDispatch.FastIoQueryStandardInfo = fast_query_standard_info;
323 FastIoDispatch.FastIoLock = fast_io_lock;
324 FastIoDispatch.FastIoUnlockSingle = fast_io_unlock_single;
325 FastIoDispatch.FastIoUnlockAll = fast_io_unlock_all;
326 FastIoDispatch.FastIoUnlockAllByKey = fast_io_unlock_all_by_key;
327 FastIoDispatch.FastIoDeviceControl = fast_io_device_control;
328 FastIoDispatch.AcquireFileForNtCreateSection = acquire_file_for_create_section;
329 FastIoDispatch.ReleaseFileForNtCreateSection = release_file_for_create_section;
330 FastIoDispatch.FastIoDetachDevice = fast_io_detach_device;
331 FastIoDispatch.FastIoQueryNetworkOpenInfo = fast_io_query_network_open_info;
332 FastIoDispatch.AcquireForModWrite = fast_io_acquire_for_mod_write;
333 FastIoDispatch.FastIoReadCompressed = fast_io_read_compressed;
334 FastIoDispatch.FastIoWriteCompressed = fast_io_write_compressed;
335 FastIoDispatch.MdlReadCompleteCompressed = fast_io_mdl_read_complete_compressed;
336 FastIoDispatch.MdlWriteCompleteCompressed = fast_io_mdl_write_complete_compressed;
337 FastIoDispatch.FastIoQueryOpen = fast_io_query_open;
338 FastIoDispatch.ReleaseForModWrite = fast_io_release_for_mod_write;
339 FastIoDispatch.AcquireForCcFlush = fast_io_acquire_for_ccflush;
340 FastIoDispatch.ReleaseForCcFlush = fast_io_release_for_ccflush;
341 FastIoDispatch.FastIoWrite = fast_io_write;
342
343 #ifdef _DEBUG
344 FastIoDispatch.FastIoRead = fast_io_read;
345 FastIoDispatch.MdlRead = fast_io_mdl_read;
346 FastIoDispatch.MdlReadComplete = fast_io_mdl_read_complete;
347 FastIoDispatch.PrepareMdlWrite = fast_io_prepare_mdl_write;
348 FastIoDispatch.MdlWriteComplete = fast_io_mdl_write_complete;
349 #else
350 FastIoDispatch.FastIoRead = FsRtlCopyRead;
351 FastIoDispatch.MdlRead = FsRtlMdlReadDev;
352 FastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev;
353 FastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev;
354 FastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev;
355 #endif
356
357 *fiod = &FastIoDispatch;
358 }