[USBOHCI_NEW][USBUHCI_NEW] Avoid unnecessary/incorrect status defines.
[reactos.git] / drivers / filesystems / btrfs / fastio.c
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 FAST_IO_DISPATCH FastIoDispatch;
21
22 _Function_class_(FAST_IO_QUERY_BASIC_INFO)
23 #ifdef __REACTOS__
24 static BOOLEAN NTAPI fast_query_basic_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_BASIC_INFORMATION fbi,
25 PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
26 #else
27 static BOOLEAN fast_query_basic_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_BASIC_INFORMATION fbi,
28 PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
29 #endif
30 fcb* fcb;
31 ccb* ccb;
32
33 FsRtlEnterFileSystem();
34
35 TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fbi, IoStatus, DeviceObject);
36
37 if (!FileObject) {
38 FsRtlExitFileSystem();
39 return FALSE;
40 }
41
42 fcb = FileObject->FsContext;
43
44 if (!fcb) {
45 FsRtlExitFileSystem();
46 return FALSE;
47 }
48
49 ccb = FileObject->FsContext2;
50
51 if (!ccb) {
52 FsRtlExitFileSystem();
53 return FALSE;
54 }
55
56 if (!(ccb->access & (FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES))) {
57 FsRtlExitFileSystem();
58 return FALSE;
59 }
60
61 if (fcb->ads) {
62 if (!ccb->fileref || !ccb->fileref->parent || !ccb->fileref->parent->fcb) {
63 FsRtlExitFileSystem();
64 return FALSE;
65 }
66
67 fcb = ccb->fileref->parent->fcb;
68 }
69
70 if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
71 FsRtlExitFileSystem();
72 return FALSE;
73 }
74
75 if (fcb == fcb->Vcb->dummy_fcb) {
76 LARGE_INTEGER time;
77
78 KeQuerySystemTime(&time);
79 fbi->CreationTime = fbi->LastAccessTime = fbi->LastWriteTime = fbi->ChangeTime = time;
80 } else {
81 fbi->CreationTime.QuadPart = unix_time_to_win(&fcb->inode_item.otime);
82 fbi->LastAccessTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_atime);
83 fbi->LastWriteTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_mtime);
84 fbi->ChangeTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_ctime);
85 }
86
87 fbi->FileAttributes = fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fcb->atts;
88
89 IoStatus->Status = STATUS_SUCCESS;
90 IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
91
92 ExReleaseResourceLite(fcb->Header.Resource);
93
94 FsRtlExitFileSystem();
95
96 return TRUE;
97 }
98
99 _Function_class_(FAST_IO_QUERY_STANDARD_INFO)
100 #ifdef __REACTOS__
101 static BOOLEAN NTAPI fast_query_standard_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_STANDARD_INFORMATION fsi,
102 PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
103 #else
104 static BOOLEAN fast_query_standard_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_STANDARD_INFORMATION fsi,
105 PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
106 #endif
107 fcb* fcb;
108 ccb* ccb;
109 BOOL ads;
110 ULONG adssize;
111
112 FsRtlEnterFileSystem();
113
114 TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fsi, IoStatus, DeviceObject);
115
116 if (!FileObject) {
117 FsRtlExitFileSystem();
118 return FALSE;
119 }
120
121 fcb = FileObject->FsContext;
122 ccb = FileObject->FsContext2;
123
124 if (!fcb) {
125 FsRtlExitFileSystem();
126 return FALSE;
127 }
128
129 if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
130 FsRtlExitFileSystem();
131 return FALSE;
132 }
133
134 ads = fcb->ads;
135
136 if (ads) {
137 struct _fcb* fcb2;
138
139 if (!ccb || !ccb->fileref || !ccb->fileref->parent || !ccb->fileref->parent->fcb) {
140 ExReleaseResourceLite(fcb->Header.Resource);
141 FsRtlExitFileSystem();
142 return FALSE;
143 }
144
145 adssize = fcb->adsdata.Length;
146
147 fcb2 = ccb->fileref->parent->fcb;
148
149 ExReleaseResourceLite(fcb->Header.Resource);
150
151 fcb = fcb2;
152
153 if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
154 FsRtlExitFileSystem();
155 return FALSE;
156 }
157
158 fsi->AllocationSize.QuadPart = fsi->EndOfFile.QuadPart = adssize;
159 fsi->NumberOfLinks = fcb->inode_item.st_nlink;
160 fsi->Directory = FALSE;
161 } else {
162 fsi->AllocationSize.QuadPart = fcb_alloc_size(fcb);
163 fsi->EndOfFile.QuadPart = S_ISDIR(fcb->inode_item.st_mode) ? 0 : fcb->inode_item.st_size;
164 fsi->NumberOfLinks = fcb->inode_item.st_nlink;
165 fsi->Directory = S_ISDIR(fcb->inode_item.st_mode);
166 }
167
168 fsi->DeletePending = ccb->fileref ? ccb->fileref->delete_on_close : FALSE;
169
170 IoStatus->Status = STATUS_SUCCESS;
171 IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
172
173 ExReleaseResourceLite(fcb->Header.Resource);
174
175 FsRtlExitFileSystem();
176
177 return TRUE;
178 }
179
180 _Function_class_(FAST_IO_CHECK_IF_POSSIBLE)
181 #ifdef __REACTOS__
182 static BOOLEAN NTAPI fast_io_check_if_possible(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait,
183 ULONG LockKey, BOOLEAN CheckForReadOperation, PIO_STATUS_BLOCK IoStatus,
184 PDEVICE_OBJECT DeviceObject) {
185 #else
186 static BOOLEAN fast_io_check_if_possible(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait,
187 ULONG LockKey, BOOLEAN CheckForReadOperation, PIO_STATUS_BLOCK IoStatus,
188 PDEVICE_OBJECT DeviceObject) {
189 #endif
190 fcb* fcb = FileObject->FsContext;
191 LARGE_INTEGER len2;
192
193 UNUSED(Wait);
194 UNUSED(IoStatus);
195 UNUSED(DeviceObject);
196
197 len2.QuadPart = Length;
198
199 if (CheckForReadOperation) {
200 if (FsRtlFastCheckLockForRead(&fcb->lock, FileOffset, &len2, LockKey, FileObject, PsGetCurrentProcess()))
201 return TRUE;
202 } else {
203 if (!fcb->Vcb->readonly && !is_subvol_readonly(fcb->subvol, NULL) && FsRtlFastCheckLockForWrite(&fcb->lock, FileOffset, &len2, LockKey, FileObject, PsGetCurrentProcess()))
204 return TRUE;
205 }
206
207 return FALSE;
208 }
209
210 _Function_class_(FAST_IO_QUERY_NETWORK_OPEN_INFO)
211 #ifdef __REACTOS__
212 static BOOLEAN NTAPI fast_io_query_network_open_info(PFILE_OBJECT FileObject, BOOLEAN Wait, FILE_NETWORK_OPEN_INFORMATION* fnoi,
213 PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
214 #else
215 static BOOLEAN fast_io_query_network_open_info(PFILE_OBJECT FileObject, BOOLEAN Wait, FILE_NETWORK_OPEN_INFORMATION* fnoi,
216 PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
217 #endif
218 fcb* fcb;
219 ccb* ccb;
220 file_ref* fileref;
221
222 FsRtlEnterFileSystem();
223
224 TRACE("(%p, %u, %p, %p, %p)\n", FileObject, Wait, fnoi, IoStatus, DeviceObject);
225
226 RtlZeroMemory(fnoi, sizeof(FILE_NETWORK_OPEN_INFORMATION));
227
228 fcb = FileObject->FsContext;
229
230 if (!fcb || fcb == fcb->Vcb->volume_fcb) {
231 FsRtlExitFileSystem();
232 return FALSE;
233 }
234
235 ccb = FileObject->FsContext2;
236
237 if (!ccb) {
238 FsRtlExitFileSystem();
239 return FALSE;
240 }
241
242 fileref = ccb->fileref;
243
244 if (fcb == fcb->Vcb->dummy_fcb) {
245 LARGE_INTEGER time;
246
247 KeQuerySystemTime(&time);
248 fnoi->CreationTime = fnoi->LastAccessTime = fnoi->LastWriteTime = fnoi->ChangeTime = time;
249 } else {
250 INODE_ITEM* ii;
251
252 if (fcb->ads) {
253 if (!fileref || !fileref->parent) {
254 ERR("no fileref for stream\n");
255 FsRtlExitFileSystem();
256 return FALSE;
257 }
258
259 ii = &fileref->parent->fcb->inode_item;
260 } else
261 ii = &fcb->inode_item;
262
263 fnoi->CreationTime.QuadPart = unix_time_to_win(&ii->otime);
264 fnoi->LastAccessTime.QuadPart = unix_time_to_win(&ii->st_atime);
265 fnoi->LastWriteTime.QuadPart = unix_time_to_win(&ii->st_mtime);
266 fnoi->ChangeTime.QuadPart = unix_time_to_win(&ii->st_ctime);
267 }
268
269 if (fcb->ads) {
270 fnoi->AllocationSize.QuadPart = fnoi->EndOfFile.QuadPart = fcb->adsdata.Length;
271 fnoi->FileAttributes = fileref->parent->fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fileref->parent->fcb->atts;
272 } else {
273 fnoi->AllocationSize.QuadPart = fcb_alloc_size(fcb);
274 fnoi->EndOfFile.QuadPart = S_ISDIR(fcb->inode_item.st_mode) ? 0 : fcb->inode_item.st_size;
275 fnoi->FileAttributes = fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fcb->atts;
276 }
277
278 FsRtlExitFileSystem();
279
280 return TRUE;
281 }
282
283 _Function_class_(FAST_IO_ACQUIRE_FOR_MOD_WRITE)
284 #ifdef __REACTOS__
285 static NTSTATUS NTAPI fast_io_acquire_for_mod_write(PFILE_OBJECT FileObject, PLARGE_INTEGER EndingOffset, struct _ERESOURCE **ResourceToRelease, PDEVICE_OBJECT DeviceObject) {
286 #else
287 static NTSTATUS fast_io_acquire_for_mod_write(PFILE_OBJECT FileObject, PLARGE_INTEGER EndingOffset, struct _ERESOURCE **ResourceToRelease, PDEVICE_OBJECT DeviceObject) {
288 #endif
289 fcb* fcb;
290
291 UNUSED(EndingOffset);
292 UNUSED(DeviceObject);
293
294 fcb = FileObject->FsContext;
295
296 if (!fcb)
297 return STATUS_INVALID_PARAMETER;
298
299 *ResourceToRelease = fcb->Header.PagingIoResource;
300
301 if (!ExAcquireResourceSharedLite(*ResourceToRelease, FALSE))
302 return STATUS_CANT_WAIT;
303
304 return STATUS_SUCCESS;
305 }
306
307 _Function_class_(FAST_IO_RELEASE_FOR_MOD_WRITE)
308 #ifdef __REACTOS__
309 static NTSTATUS NTAPI fast_io_release_for_mod_write(PFILE_OBJECT FileObject, struct _ERESOURCE *ResourceToRelease, PDEVICE_OBJECT DeviceObject) {
310 #else
311 static NTSTATUS fast_io_release_for_mod_write(PFILE_OBJECT FileObject, struct _ERESOURCE *ResourceToRelease, PDEVICE_OBJECT DeviceObject) {
312 #endif
313 UNUSED(FileObject);
314 UNUSED(DeviceObject);
315
316 ExReleaseResourceLite(ResourceToRelease);
317
318 return STATUS_SUCCESS;
319 }
320
321 _Function_class_(FAST_IO_ACQUIRE_FOR_CCFLUSH)
322 #ifdef __REACTOS__
323 static NTSTATUS NTAPI fast_io_acquire_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) {
324 #else
325 static NTSTATUS fast_io_acquire_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) {
326 #endif
327 UNUSED(FileObject);
328 UNUSED(DeviceObject);
329
330 IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
331
332 return STATUS_SUCCESS;
333 }
334
335 _Function_class_(FAST_IO_RELEASE_FOR_CCFLUSH)
336 #ifdef __REACTOS__
337 static NTSTATUS NTAPI fast_io_release_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) {
338 #else
339 static NTSTATUS fast_io_release_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) {
340 #endif
341 UNUSED(FileObject);
342 UNUSED(DeviceObject);
343
344 if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP)
345 IoSetTopLevelIrp(NULL);
346
347 return STATUS_SUCCESS;
348 }
349
350 _Function_class_(FAST_IO_WRITE)
351 #ifdef __REACTOS__
352 static BOOLEAN NTAPI fast_io_write(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
353 #else
354 static BOOLEAN fast_io_write(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
355 #endif
356 if (FsRtlCopyWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject)) {
357 fcb* fcb = FileObject->FsContext;
358
359 fcb->inode_item.st_size = fcb->Header.FileSize.QuadPart;
360
361 return TRUE;
362 }
363
364 return FALSE;
365 }
366
367 void init_fast_io_dispatch(FAST_IO_DISPATCH** fiod) {
368 RtlZeroMemory(&FastIoDispatch, sizeof(FastIoDispatch));
369
370 FastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
371
372 FastIoDispatch.FastIoCheckIfPossible = fast_io_check_if_possible;
373 FastIoDispatch.FastIoQueryBasicInfo = fast_query_basic_info;
374 FastIoDispatch.FastIoQueryStandardInfo = fast_query_standard_info;
375 FastIoDispatch.FastIoQueryNetworkOpenInfo = fast_io_query_network_open_info;
376 FastIoDispatch.AcquireForModWrite = fast_io_acquire_for_mod_write;
377 FastIoDispatch.ReleaseForModWrite = fast_io_release_for_mod_write;
378 FastIoDispatch.AcquireForCcFlush = fast_io_acquire_for_ccflush;
379 FastIoDispatch.ReleaseForCcFlush = fast_io_release_for_ccflush;
380 FastIoDispatch.FastIoWrite = fast_io_write;
381 FastIoDispatch.FastIoRead = FsRtlCopyRead;
382 FastIoDispatch.MdlRead = FsRtlMdlReadDev;
383 FastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev;
384 FastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev;
385 FastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev;
386
387 *fiod = &FastIoDispatch;
388 }