ReactOS  0.4.13-dev-235-g7373cb3
fastio.c
Go to the documentation of this file.
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 
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,
26 #else
27 static BOOLEAN fast_query_basic_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_BASIC_INFORMATION fbi,
29 #endif
30  fcb* fcb;
31  ccb* ccb;
32 
34 
35  TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fbi, IoStatus, DeviceObject);
36 
37  if (!FileObject) {
39  return FALSE;
40  }
41 
42  fcb = FileObject->FsContext;
43 
44  if (!fcb) {
46  return FALSE;
47  }
48 
49  ccb = FileObject->FsContext2;
50 
51  if (!ccb) {
53  return FALSE;
54  }
55 
58  return FALSE;
59  }
60 
61  if (fcb->ads) {
62  if (!ccb->fileref || !ccb->fileref->parent || !ccb->fileref->parent->fcb) {
64  return FALSE;
65  }
66 
67  fcb = ccb->fileref->parent->fcb;
68  }
69 
70  if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
72  return FALSE;
73  }
74 
75  if (fcb == fcb->Vcb->dummy_fcb) {
77 
79  fbi->CreationTime = fbi->LastAccessTime = fbi->LastWriteTime = fbi->ChangeTime = time;
80  } else {
85  }
86 
88 
89  IoStatus->Status = STATUS_SUCCESS;
90  IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
91 
92  ExReleaseResourceLite(fcb->Header.Resource);
93 
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,
103 #else
104 static BOOLEAN fast_query_standard_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_STANDARD_INFORMATION fsi,
106 #endif
107  fcb* fcb;
108  ccb* ccb;
109  BOOL ads;
110  ULONG adssize;
111 
113 
114  TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fsi, IoStatus, DeviceObject);
115 
116  if (!FileObject) {
118  return FALSE;
119  }
120 
121  fcb = FileObject->FsContext;
122  ccb = FileObject->FsContext2;
123 
124  if (!fcb) {
126  return FALSE;
127  }
128 
129  if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) {
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);
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)) {
155  return FALSE;
156  }
157 
158  fsi->AllocationSize.QuadPart = fsi->EndOfFile.QuadPart = adssize;
160  fsi->Directory = FALSE;
161  } else {
166  }
167 
169 
170  IoStatus->Status = STATUS_SUCCESS;
171  IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
172 
173  ExReleaseResourceLite(fcb->Header.Resource);
174 
176 
177  return TRUE;
178 }
179 
180 _Function_class_(FAST_IO_CHECK_IF_POSSIBLE)
181 #ifdef __REACTOS__
185 #else
186 static BOOLEAN fast_io_check_if_possible(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait,
189 #endif
190  fcb* fcb = FileObject->FsContext;
191  LARGE_INTEGER len2;
192 
193  UNUSED(Wait);
194  UNUSED(IoStatus);
196 
197  len2.QuadPart = Length;
198 
199  if (CheckForReadOperation) {
201  return TRUE;
202  } else {
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,
214 #else
215 static BOOLEAN fast_io_query_network_open_info(PFILE_OBJECT FileObject, BOOLEAN Wait, FILE_NETWORK_OPEN_INFORMATION* fnoi,
217 #endif
218  fcb* fcb;
219  ccb* ccb;
220  file_ref* fileref;
221 
223 
224  TRACE("(%p, %u, %p, %p, %p)\n", FileObject, Wait, fnoi, IoStatus, DeviceObject);
225 
227 
228  fcb = FileObject->FsContext;
229 
230  if (!fcb || fcb == fcb->Vcb->volume_fcb) {
232  return FALSE;
233  }
234 
235  ccb = FileObject->FsContext2;
236 
237  if (!ccb) {
239  return FALSE;
240  }
241 
242  fileref = ccb->fileref;
243 
244  if (fcb == fcb->Vcb->dummy_fcb) {
246 
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");
256  return FALSE;
257  }
258 
259  ii = &fileref->parent->fcb->inode_item;
260  } else
261  ii = &fcb->inode_item;
262 
267  }
268 
269  if (fcb->ads) {
271  fnoi->FileAttributes = fileref->parent->fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fileref->parent->fcb->atts;
272  } else {
276  }
277 
279 
280  return TRUE;
281 }
282 
283 _Function_class_(FAST_IO_ACQUIRE_FOR_MOD_WRITE)
284 #ifdef __REACTOS__
286 #else
288 #endif
289  fcb* fcb;
290 
293 
294  fcb = FileObject->FsContext;
295 
296  if (!fcb)
298 
299  // Make sure we don't get interrupted by the flush thread, which can cause a deadlock
300 
301  if (!ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, FALSE))
302  return STATUS_CANT_WAIT;
303 
304  // Ideally this would be PagingIoResource, but that doesn't play well with copy-on-write,
305  // as we can't guarantee that we won't need to do any reallocations.
306 
307  *ResourceToRelease = fcb->Header.Resource;
308 
310  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
311  return STATUS_CANT_WAIT;
312  }
313 
314  return STATUS_SUCCESS;
315 }
316 
317 _Function_class_(FAST_IO_RELEASE_FOR_MOD_WRITE)
318 #ifdef __REACTOS__
319 static NTSTATUS NTAPI fast_io_release_for_mod_write(PFILE_OBJECT FileObject, struct _ERESOURCE *ResourceToRelease, PDEVICE_OBJECT DeviceObject) {
320 #else
321 static NTSTATUS fast_io_release_for_mod_write(PFILE_OBJECT FileObject, struct _ERESOURCE *ResourceToRelease, PDEVICE_OBJECT DeviceObject) {
322 #endif
323  fcb* fcb;
324 
326 
327  fcb = FileObject->FsContext;
328 
330 
331  ExReleaseResourceLite(&fcb->Vcb->tree_lock);
332 
333  return STATUS_SUCCESS;
334 }
335 
336 _Function_class_(FAST_IO_ACQUIRE_FOR_CCFLUSH)
337 #ifdef __REACTOS__
338 static NTSTATUS NTAPI fast_io_acquire_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) {
339 #else
340 static NTSTATUS fast_io_acquire_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) {
341 #endif
344 
346 
347  return STATUS_SUCCESS;
348 }
349 
350 _Function_class_(FAST_IO_RELEASE_FOR_CCFLUSH)
351 #ifdef __REACTOS__
352 static NTSTATUS NTAPI fast_io_release_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) {
353 #else
354 static NTSTATUS fast_io_release_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) {
355 #endif
358 
361 
362  return STATUS_SUCCESS;
363 }
364 
365 _Function_class_(FAST_IO_WRITE)
366 #ifdef __REACTOS__
368 #else
370 #endif
372  fcb* fcb = FileObject->FsContext;
373 
374  fcb->inode_item.st_size = fcb->Header.FileSize.QuadPart;
375 
376  return TRUE;
377  }
378 
379  return FALSE;
380 }
381 
384 
386 
387  FastIoDispatch.FastIoCheckIfPossible = fast_io_check_if_possible;
388  FastIoDispatch.FastIoQueryBasicInfo = fast_query_basic_info;
389  FastIoDispatch.FastIoQueryStandardInfo = fast_query_standard_info;
390  FastIoDispatch.FastIoQueryNetworkOpenInfo = fast_io_query_network_open_info;
391  FastIoDispatch.AcquireForModWrite = fast_io_acquire_for_mod_write;
392  FastIoDispatch.ReleaseForModWrite = fast_io_release_for_mod_write;
393  FastIoDispatch.AcquireForCcFlush = fast_io_acquire_for_ccflush;
394  FastIoDispatch.ReleaseForCcFlush = fast_io_release_for_ccflush;
395  FastIoDispatch.FastIoWrite = fast_io_write;
401 
402  *fiod = &FastIoDispatch;
403 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
struct _file_ref * parent
Definition: btrfs_drv.h:326
_In_ PLARGE_INTEGER EndingOffset
Definition: iotypes.h:1553
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:752
#define FsRtlEnterFileSystem
adns_state ads
Definition: adh-query.c:35
BTRFS_TIME otime
Definition: btrfs.h:281
#define FsRtlExitFileSystem
BOOLEAN NTAPI FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, IN PMDL MemoryDescriptorList, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:1011
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PLARGE_INTEGER _Out_ struct _ERESOURCE ** ResourceToRelease
Definition: iotypes.h:1554
BOOLEAN NTAPI FsRtlMdlWriteCompleteDev(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:1198
LONG NTSTATUS
Definition: precomp.h:26
void init_fast_io_dispatch(FAST_IO_DISPATCH **fiod)
Definition: fastio.c:382
PFAST_IO_MDL_READ MdlRead
Definition: iotypes.h:1705
PFAST_IO_PREPARE_MDL_WRITE PrepareMdlWrite
Definition: iotypes.h:1707
PFAST_IO_QUERY_NETWORK_OPEN_INFO FastIoQueryNetworkOpenInfo
Definition: iotypes.h:1703
__u16 time
Definition: mkdosfs.c:366
ACCESS_MASK access
Definition: btrfs_drv.h:357
BOOLEAN NTAPI FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:1272
PFAST_IO_RELEASE_FOR_MOD_WRITE ReleaseForModWrite
Definition: iotypes.h:1714
PFAST_IO_MDL_READ_COMPLETE MdlReadComplete
Definition: iotypes.h:1706
BTRFS_TIME st_ctime
Definition: btrfs.h:279
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN CheckForReadOperation
Definition: fatprocs.h:2650
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
UINT32 st_mode
Definition: btrfs.h:273
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
unsigned int BOOL
Definition: ntddk_ex.h:94
PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo
Definition: iotypes.h:1693
_Function_class_(FAST_IO_QUERY_BASIC_INFO)
Definition: fastio.c:22
struct _FAST_IO_DISPATCH FAST_IO_DISPATCH
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define UNUSED(x)
Definition: btrfs_drv.h:81
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
BTRFS_TIME st_mtime
Definition: btrfs.h:280
static __inline uint64_t unix_time_to_win(BTRFS_TIME *t)
Definition: recv.cpp:1180
FILE_LOCK lock
Definition: btrfs_drv.h:267
BOOLEAN NTAPI FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:1025
static __inline UINT64 fcb_alloc_size(fcb *fcb)
Definition: btrfs_drv.h:1775
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:256
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2650
#define TRACE(s)
Definition: solgame.cpp:4
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
struct _fcb fcb
Definition: btrfs_drv.h:1334
static __inline BOOL is_subvol_readonly(root *r, PIRP Irp)
Definition: btrfs_drv.h:1021
#define S_ISDIR(mode)
Definition: various.h:18
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
struct _file_ref * fileref
Definition: btrfs_drv.h:279
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1954
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
BTRFS_TIME st_atime
Definition: btrfs.h:278
BOOL ads
Definition: btrfs_drv.h:300
PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush
Definition: iotypes.h:1715
LARGE_INTEGER CreationTime
Definition: nt_native.h:939
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
INODE_ITEM inode_item
Definition: btrfs_drv.h:265
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
PFAST_IO_ACQUIRE_FOR_MOD_WRITE AcquireForModWrite
Definition: iotypes.h:1704
#define ERR(fmt,...)
Definition: debug.h:109
FAST_IO_DISPATCH FastIoDispatch
Definition: fastio.c:20
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1691
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PFAST_IO_WRITE FastIoWrite
Definition: iotypes.h:1692
ULONG atts
Definition: btrfs_drv.h:270
UINT64 st_size
Definition: btrfs.h:267
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
struct _root * subvol
Definition: btrfs_drv.h:261
ANSI_STRING adsdata
Definition: btrfs_drv.h:304
PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo
Definition: iotypes.h:1694
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
BOOLEAN NTAPI FsRtlCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:64
BOOLEAN NTAPI FsRtlCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:264
PFAST_IO_MDL_WRITE_COMPLETE MdlWriteComplete
Definition: iotypes.h:1708
BOOL delete_on_close
Definition: btrfs_drv.h:319
UINT32 st_nlink
Definition: btrfs.h:270
unsigned int ULONG
Definition: retypes.h:1
PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible
Definition: iotypes.h:1690
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _ccb ccb
file_ref * fileref
Definition: btrfs_drv.h:358
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
return STATUS_SUCCESS
Definition: btrfs.c:2745
PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush
Definition: iotypes.h:1716
BOOLEAN NTAPI FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:786
struct _device_extension * Vcb
Definition: btrfs_drv.h:260
LONGLONG QuadPart
Definition: typedefs.h:112
ULONG SizeOfFastIoDispatch
Definition: iotypes.h:1689
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
IN BOOLEAN Wait
Definition: fatprocs.h:1529
#define FILE_BASIC_INFORMATION
Definition: disk.h:53