1c2c66affSColin Finck /* Copyright (c) Mark Harmstone 2016-17 2c2c66affSColin Finck * 3c2c66affSColin Finck * This file is part of WinBtrfs. 4c2c66affSColin Finck * 5c2c66affSColin Finck * WinBtrfs is free software: you can redistribute it and/or modify 6c2c66affSColin Finck * it under the terms of the GNU Lesser General Public Licence as published by 7c2c66affSColin Finck * the Free Software Foundation, either version 3 of the Licence, or 8c2c66affSColin Finck * (at your option) any later version. 9c2c66affSColin Finck * 10c2c66affSColin Finck * WinBtrfs is distributed in the hope that it will be useful, 11c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 12c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13c2c66affSColin Finck * GNU Lesser General Public Licence for more details. 14c2c66affSColin Finck * 15c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public Licence 16c2c66affSColin Finck * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */ 17c2c66affSColin Finck 18c2c66affSColin Finck #include "btrfs_drv.h" 19c2c66affSColin Finck 20c2c66affSColin Finck FAST_IO_DISPATCH FastIoDispatch; 21c2c66affSColin Finck 22c2c66affSColin Finck _Function_class_(FAST_IO_QUERY_BASIC_INFO) 23c2c66affSColin Finck #ifdef __REACTOS__ 24c2c66affSColin Finck static BOOLEAN NTAPI fast_query_basic_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_BASIC_INFORMATION fbi, 25c2c66affSColin Finck PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { 26c2c66affSColin Finck #else 27c2c66affSColin Finck static BOOLEAN fast_query_basic_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_BASIC_INFORMATION fbi, 28c2c66affSColin Finck PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { 29c2c66affSColin Finck #endif 30c2c66affSColin Finck fcb* fcb; 31c2c66affSColin Finck ccb* ccb; 32c2c66affSColin Finck 33c2c66affSColin Finck FsRtlEnterFileSystem(); 34c2c66affSColin Finck 35c2c66affSColin Finck TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fbi, IoStatus, DeviceObject); 36c2c66affSColin Finck 37c2c66affSColin Finck if (!FileObject) { 38c2c66affSColin Finck FsRtlExitFileSystem(); 39c2c66affSColin Finck return FALSE; 40c2c66affSColin Finck } 41c2c66affSColin Finck 42c2c66affSColin Finck fcb = FileObject->FsContext; 43c2c66affSColin Finck 44c2c66affSColin Finck if (!fcb) { 45c2c66affSColin Finck FsRtlExitFileSystem(); 46c2c66affSColin Finck return FALSE; 47c2c66affSColin Finck } 48c2c66affSColin Finck 49c2c66affSColin Finck ccb = FileObject->FsContext2; 50c2c66affSColin Finck 51c2c66affSColin Finck if (!ccb) { 52c2c66affSColin Finck FsRtlExitFileSystem(); 53c2c66affSColin Finck return FALSE; 54c2c66affSColin Finck } 55c2c66affSColin Finck 56c2c66affSColin Finck if (!(ccb->access & (FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES))) { 57c2c66affSColin Finck FsRtlExitFileSystem(); 58c2c66affSColin Finck return FALSE; 59c2c66affSColin Finck } 60c2c66affSColin Finck 61c2c66affSColin Finck if (fcb->ads) { 62c2c66affSColin Finck if (!ccb->fileref || !ccb->fileref->parent || !ccb->fileref->parent->fcb) { 63c2c66affSColin Finck FsRtlExitFileSystem(); 64c2c66affSColin Finck return FALSE; 65c2c66affSColin Finck } 66c2c66affSColin Finck 67c2c66affSColin Finck fcb = ccb->fileref->parent->fcb; 68c2c66affSColin Finck } 69c2c66affSColin Finck 70c2c66affSColin Finck if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) { 71c2c66affSColin Finck FsRtlExitFileSystem(); 72c2c66affSColin Finck return FALSE; 73c2c66affSColin Finck } 74c2c66affSColin Finck 75c2c66affSColin Finck if (fcb == fcb->Vcb->dummy_fcb) { 76c2c66affSColin Finck LARGE_INTEGER time; 77c2c66affSColin Finck 78c2c66affSColin Finck KeQuerySystemTime(&time); 79c2c66affSColin Finck fbi->CreationTime = fbi->LastAccessTime = fbi->LastWriteTime = fbi->ChangeTime = time; 80c2c66affSColin Finck } else { 81c2c66affSColin Finck fbi->CreationTime.QuadPart = unix_time_to_win(&fcb->inode_item.otime); 82c2c66affSColin Finck fbi->LastAccessTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_atime); 83c2c66affSColin Finck fbi->LastWriteTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_mtime); 84c2c66affSColin Finck fbi->ChangeTime.QuadPart = unix_time_to_win(&fcb->inode_item.st_ctime); 85c2c66affSColin Finck } 86c2c66affSColin Finck 87c2c66affSColin Finck fbi->FileAttributes = fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fcb->atts; 88c2c66affSColin Finck 89c2c66affSColin Finck IoStatus->Status = STATUS_SUCCESS; 90c2c66affSColin Finck IoStatus->Information = sizeof(FILE_BASIC_INFORMATION); 91c2c66affSColin Finck 92c2c66affSColin Finck ExReleaseResourceLite(fcb->Header.Resource); 93c2c66affSColin Finck 94c2c66affSColin Finck FsRtlExitFileSystem(); 95c2c66affSColin Finck 96c2c66affSColin Finck return TRUE; 97c2c66affSColin Finck } 98c2c66affSColin Finck 99c2c66affSColin Finck _Function_class_(FAST_IO_QUERY_STANDARD_INFO) 100c2c66affSColin Finck #ifdef __REACTOS__ 101c2c66affSColin Finck static BOOLEAN NTAPI fast_query_standard_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_STANDARD_INFORMATION fsi, 102c2c66affSColin Finck PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { 103c2c66affSColin Finck #else 104c2c66affSColin Finck static BOOLEAN fast_query_standard_info(PFILE_OBJECT FileObject, BOOLEAN wait, PFILE_STANDARD_INFORMATION fsi, 105c2c66affSColin Finck PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { 106c2c66affSColin Finck #endif 107c2c66affSColin Finck fcb* fcb; 108c2c66affSColin Finck ccb* ccb; 109c2c66affSColin Finck BOOL ads; 110c2c66affSColin Finck ULONG adssize; 111c2c66affSColin Finck 112c2c66affSColin Finck FsRtlEnterFileSystem(); 113c2c66affSColin Finck 114c2c66affSColin Finck TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fsi, IoStatus, DeviceObject); 115c2c66affSColin Finck 116c2c66affSColin Finck if (!FileObject) { 117c2c66affSColin Finck FsRtlExitFileSystem(); 118c2c66affSColin Finck return FALSE; 119c2c66affSColin Finck } 120c2c66affSColin Finck 121c2c66affSColin Finck fcb = FileObject->FsContext; 122c2c66affSColin Finck ccb = FileObject->FsContext2; 123c2c66affSColin Finck 124c2c66affSColin Finck if (!fcb) { 125c2c66affSColin Finck FsRtlExitFileSystem(); 126c2c66affSColin Finck return FALSE; 127c2c66affSColin Finck } 128c2c66affSColin Finck 129c2c66affSColin Finck if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) { 130c2c66affSColin Finck FsRtlExitFileSystem(); 131c2c66affSColin Finck return FALSE; 132c2c66affSColin Finck } 133c2c66affSColin Finck 134c2c66affSColin Finck ads = fcb->ads; 135c2c66affSColin Finck 136c2c66affSColin Finck if (ads) { 137c2c66affSColin Finck struct _fcb* fcb2; 138c2c66affSColin Finck 139c2c66affSColin Finck if (!ccb || !ccb->fileref || !ccb->fileref->parent || !ccb->fileref->parent->fcb) { 140c2c66affSColin Finck ExReleaseResourceLite(fcb->Header.Resource); 141c2c66affSColin Finck FsRtlExitFileSystem(); 142c2c66affSColin Finck return FALSE; 143c2c66affSColin Finck } 144c2c66affSColin Finck 145c2c66affSColin Finck adssize = fcb->adsdata.Length; 146c2c66affSColin Finck 147c2c66affSColin Finck fcb2 = ccb->fileref->parent->fcb; 148c2c66affSColin Finck 149c2c66affSColin Finck ExReleaseResourceLite(fcb->Header.Resource); 150c2c66affSColin Finck 151c2c66affSColin Finck fcb = fcb2; 152c2c66affSColin Finck 153c2c66affSColin Finck if (!ExAcquireResourceSharedLite(fcb->Header.Resource, wait)) { 154c2c66affSColin Finck FsRtlExitFileSystem(); 155c2c66affSColin Finck return FALSE; 156c2c66affSColin Finck } 157c2c66affSColin Finck 158c2c66affSColin Finck fsi->AllocationSize.QuadPart = fsi->EndOfFile.QuadPart = adssize; 159c2c66affSColin Finck fsi->NumberOfLinks = fcb->inode_item.st_nlink; 160c2c66affSColin Finck fsi->Directory = FALSE; 161c2c66affSColin Finck } else { 162c2c66affSColin Finck fsi->AllocationSize.QuadPart = fcb_alloc_size(fcb); 163c2c66affSColin Finck fsi->EndOfFile.QuadPart = S_ISDIR(fcb->inode_item.st_mode) ? 0 : fcb->inode_item.st_size; 164c2c66affSColin Finck fsi->NumberOfLinks = fcb->inode_item.st_nlink; 165c2c66affSColin Finck fsi->Directory = S_ISDIR(fcb->inode_item.st_mode); 166c2c66affSColin Finck } 167c2c66affSColin Finck 168c2c66affSColin Finck fsi->DeletePending = ccb->fileref ? ccb->fileref->delete_on_close : FALSE; 169c2c66affSColin Finck 170c2c66affSColin Finck IoStatus->Status = STATUS_SUCCESS; 171c2c66affSColin Finck IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION); 172c2c66affSColin Finck 173c2c66affSColin Finck ExReleaseResourceLite(fcb->Header.Resource); 174c2c66affSColin Finck 175c2c66affSColin Finck FsRtlExitFileSystem(); 176c2c66affSColin Finck 177c2c66affSColin Finck return TRUE; 178c2c66affSColin Finck } 179c2c66affSColin Finck 180c2c66affSColin Finck _Function_class_(FAST_IO_CHECK_IF_POSSIBLE) 181c2c66affSColin Finck #ifdef __REACTOS__ 182c2c66affSColin Finck static BOOLEAN NTAPI fast_io_check_if_possible(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, 183c2c66affSColin Finck ULONG LockKey, BOOLEAN CheckForReadOperation, PIO_STATUS_BLOCK IoStatus, 184c2c66affSColin Finck PDEVICE_OBJECT DeviceObject) { 185c2c66affSColin Finck #else 186c2c66affSColin Finck static BOOLEAN fast_io_check_if_possible(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, 187c2c66affSColin Finck ULONG LockKey, BOOLEAN CheckForReadOperation, PIO_STATUS_BLOCK IoStatus, 188c2c66affSColin Finck PDEVICE_OBJECT DeviceObject) { 189c2c66affSColin Finck #endif 190c2c66affSColin Finck fcb* fcb = FileObject->FsContext; 191c2c66affSColin Finck LARGE_INTEGER len2; 192c2c66affSColin Finck 193c2c66affSColin Finck UNUSED(Wait); 194c2c66affSColin Finck UNUSED(IoStatus); 195c2c66affSColin Finck UNUSED(DeviceObject); 196c2c66affSColin Finck 197c2c66affSColin Finck len2.QuadPart = Length; 198c2c66affSColin Finck 199c2c66affSColin Finck if (CheckForReadOperation) { 200c2c66affSColin Finck if (FsRtlFastCheckLockForRead(&fcb->lock, FileOffset, &len2, LockKey, FileObject, PsGetCurrentProcess())) 201c2c66affSColin Finck return TRUE; 202c2c66affSColin Finck } else { 203c2c66affSColin Finck if (!fcb->Vcb->readonly && !is_subvol_readonly(fcb->subvol, NULL) && FsRtlFastCheckLockForWrite(&fcb->lock, FileOffset, &len2, LockKey, FileObject, PsGetCurrentProcess())) 204c2c66affSColin Finck return TRUE; 205c2c66affSColin Finck } 206c2c66affSColin Finck 207c2c66affSColin Finck return FALSE; 208c2c66affSColin Finck } 209c2c66affSColin Finck 210c2c66affSColin Finck _Function_class_(FAST_IO_QUERY_NETWORK_OPEN_INFO) 211c2c66affSColin Finck #ifdef __REACTOS__ 212c2c66affSColin Finck static BOOLEAN NTAPI fast_io_query_network_open_info(PFILE_OBJECT FileObject, BOOLEAN Wait, FILE_NETWORK_OPEN_INFORMATION* fnoi, 213c2c66affSColin Finck PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { 214c2c66affSColin Finck #else 215c2c66affSColin Finck static BOOLEAN fast_io_query_network_open_info(PFILE_OBJECT FileObject, BOOLEAN Wait, FILE_NETWORK_OPEN_INFORMATION* fnoi, 216c2c66affSColin Finck PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { 217c2c66affSColin Finck #endif 218c2c66affSColin Finck fcb* fcb; 219c2c66affSColin Finck ccb* ccb; 220c2c66affSColin Finck file_ref* fileref; 221c2c66affSColin Finck 222c2c66affSColin Finck FsRtlEnterFileSystem(); 223c2c66affSColin Finck 224c2c66affSColin Finck TRACE("(%p, %u, %p, %p, %p)\n", FileObject, Wait, fnoi, IoStatus, DeviceObject); 225c2c66affSColin Finck 226c2c66affSColin Finck RtlZeroMemory(fnoi, sizeof(FILE_NETWORK_OPEN_INFORMATION)); 227c2c66affSColin Finck 228c2c66affSColin Finck fcb = FileObject->FsContext; 229c2c66affSColin Finck 230c2c66affSColin Finck if (!fcb || fcb == fcb->Vcb->volume_fcb) { 231c2c66affSColin Finck FsRtlExitFileSystem(); 232c2c66affSColin Finck return FALSE; 233c2c66affSColin Finck } 234c2c66affSColin Finck 235c2c66affSColin Finck ccb = FileObject->FsContext2; 236c2c66affSColin Finck 237c2c66affSColin Finck if (!ccb) { 238c2c66affSColin Finck FsRtlExitFileSystem(); 239c2c66affSColin Finck return FALSE; 240c2c66affSColin Finck } 241c2c66affSColin Finck 242c2c66affSColin Finck fileref = ccb->fileref; 243c2c66affSColin Finck 244c2c66affSColin Finck if (fcb == fcb->Vcb->dummy_fcb) { 245c2c66affSColin Finck LARGE_INTEGER time; 246c2c66affSColin Finck 247c2c66affSColin Finck KeQuerySystemTime(&time); 248c2c66affSColin Finck fnoi->CreationTime = fnoi->LastAccessTime = fnoi->LastWriteTime = fnoi->ChangeTime = time; 249c2c66affSColin Finck } else { 250c2c66affSColin Finck INODE_ITEM* ii; 251c2c66affSColin Finck 252c2c66affSColin Finck if (fcb->ads) { 253c2c66affSColin Finck if (!fileref || !fileref->parent) { 254c2c66affSColin Finck ERR("no fileref for stream\n"); 255c2c66affSColin Finck FsRtlExitFileSystem(); 256c2c66affSColin Finck return FALSE; 257c2c66affSColin Finck } 258c2c66affSColin Finck 259c2c66affSColin Finck ii = &fileref->parent->fcb->inode_item; 260c2c66affSColin Finck } else 261c2c66affSColin Finck ii = &fcb->inode_item; 262c2c66affSColin Finck 263c2c66affSColin Finck fnoi->CreationTime.QuadPart = unix_time_to_win(&ii->otime); 264c2c66affSColin Finck fnoi->LastAccessTime.QuadPart = unix_time_to_win(&ii->st_atime); 265c2c66affSColin Finck fnoi->LastWriteTime.QuadPart = unix_time_to_win(&ii->st_mtime); 266c2c66affSColin Finck fnoi->ChangeTime.QuadPart = unix_time_to_win(&ii->st_ctime); 267c2c66affSColin Finck } 268c2c66affSColin Finck 269c2c66affSColin Finck if (fcb->ads) { 270c2c66affSColin Finck fnoi->AllocationSize.QuadPart = fnoi->EndOfFile.QuadPart = fcb->adsdata.Length; 271c2c66affSColin Finck fnoi->FileAttributes = fileref->parent->fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fileref->parent->fcb->atts; 272c2c66affSColin Finck } else { 273c2c66affSColin Finck fnoi->AllocationSize.QuadPart = fcb_alloc_size(fcb); 274c2c66affSColin Finck fnoi->EndOfFile.QuadPart = S_ISDIR(fcb->inode_item.st_mode) ? 0 : fcb->inode_item.st_size; 275c2c66affSColin Finck fnoi->FileAttributes = fcb->atts == 0 ? FILE_ATTRIBUTE_NORMAL : fcb->atts; 276c2c66affSColin Finck } 277c2c66affSColin Finck 278c2c66affSColin Finck FsRtlExitFileSystem(); 279c2c66affSColin Finck 280c2c66affSColin Finck return TRUE; 281c2c66affSColin Finck } 282c2c66affSColin Finck 283c2c66affSColin Finck _Function_class_(FAST_IO_ACQUIRE_FOR_MOD_WRITE) 284c2c66affSColin Finck #ifdef __REACTOS__ 285c2c66affSColin Finck static NTSTATUS NTAPI fast_io_acquire_for_mod_write(PFILE_OBJECT FileObject, PLARGE_INTEGER EndingOffset, struct _ERESOURCE **ResourceToRelease, PDEVICE_OBJECT DeviceObject) { 286c2c66affSColin Finck #else 287c2c66affSColin Finck static NTSTATUS fast_io_acquire_for_mod_write(PFILE_OBJECT FileObject, PLARGE_INTEGER EndingOffset, struct _ERESOURCE **ResourceToRelease, PDEVICE_OBJECT DeviceObject) { 288c2c66affSColin Finck #endif 289c2c66affSColin Finck fcb* fcb; 290c2c66affSColin Finck 291c2c66affSColin Finck UNUSED(EndingOffset); 292c2c66affSColin Finck UNUSED(DeviceObject); 293c2c66affSColin Finck 294c2c66affSColin Finck fcb = FileObject->FsContext; 295c2c66affSColin Finck 296c2c66affSColin Finck if (!fcb) 297c2c66affSColin Finck return STATUS_INVALID_PARAMETER; 298c2c66affSColin Finck 299*eb7fbc25SPierre Schweitzer // Make sure we don't get interrupted by the flush thread, which can cause a deadlock 300c2c66affSColin Finck 301*eb7fbc25SPierre Schweitzer if (!ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, FALSE)) 302c2c66affSColin Finck return STATUS_CANT_WAIT; 303c2c66affSColin Finck 304*eb7fbc25SPierre Schweitzer // Ideally this would be PagingIoResource, but that doesn't play well with copy-on-write, 305*eb7fbc25SPierre Schweitzer // as we can't guarantee that we won't need to do any reallocations. 306*eb7fbc25SPierre Schweitzer 307*eb7fbc25SPierre Schweitzer *ResourceToRelease = fcb->Header.Resource; 308*eb7fbc25SPierre Schweitzer 309*eb7fbc25SPierre Schweitzer if (!ExAcquireResourceExclusiveLite(*ResourceToRelease, FALSE)) { 310*eb7fbc25SPierre Schweitzer ExReleaseResourceLite(&fcb->Vcb->tree_lock); 311*eb7fbc25SPierre Schweitzer return STATUS_CANT_WAIT; 312*eb7fbc25SPierre Schweitzer } 313*eb7fbc25SPierre Schweitzer 314c2c66affSColin Finck return STATUS_SUCCESS; 315c2c66affSColin Finck } 316c2c66affSColin Finck 317c2c66affSColin Finck _Function_class_(FAST_IO_RELEASE_FOR_MOD_WRITE) 318c2c66affSColin Finck #ifdef __REACTOS__ 319c2c66affSColin Finck static NTSTATUS NTAPI fast_io_release_for_mod_write(PFILE_OBJECT FileObject, struct _ERESOURCE *ResourceToRelease, PDEVICE_OBJECT DeviceObject) { 320c2c66affSColin Finck #else 321c2c66affSColin Finck static NTSTATUS fast_io_release_for_mod_write(PFILE_OBJECT FileObject, struct _ERESOURCE *ResourceToRelease, PDEVICE_OBJECT DeviceObject) { 322c2c66affSColin Finck #endif 323*eb7fbc25SPierre Schweitzer fcb* fcb; 324*eb7fbc25SPierre Schweitzer 325c2c66affSColin Finck UNUSED(DeviceObject); 326c2c66affSColin Finck 327*eb7fbc25SPierre Schweitzer fcb = FileObject->FsContext; 328*eb7fbc25SPierre Schweitzer 329c2c66affSColin Finck ExReleaseResourceLite(ResourceToRelease); 330c2c66affSColin Finck 331*eb7fbc25SPierre Schweitzer ExReleaseResourceLite(&fcb->Vcb->tree_lock); 332*eb7fbc25SPierre Schweitzer 333c2c66affSColin Finck return STATUS_SUCCESS; 334c2c66affSColin Finck } 335c2c66affSColin Finck 336c2c66affSColin Finck _Function_class_(FAST_IO_ACQUIRE_FOR_CCFLUSH) 337c2c66affSColin Finck #ifdef __REACTOS__ 338c2c66affSColin Finck static NTSTATUS NTAPI fast_io_acquire_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) { 339c2c66affSColin Finck #else 340c2c66affSColin Finck static NTSTATUS fast_io_acquire_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) { 341c2c66affSColin Finck #endif 342c2c66affSColin Finck UNUSED(FileObject); 343c2c66affSColin Finck UNUSED(DeviceObject); 344c2c66affSColin Finck 345c2c66affSColin Finck IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP); 346c2c66affSColin Finck 347c2c66affSColin Finck return STATUS_SUCCESS; 348c2c66affSColin Finck } 349c2c66affSColin Finck 350c2c66affSColin Finck _Function_class_(FAST_IO_RELEASE_FOR_CCFLUSH) 351c2c66affSColin Finck #ifdef __REACTOS__ 352c2c66affSColin Finck static NTSTATUS NTAPI fast_io_release_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) { 353c2c66affSColin Finck #else 354c2c66affSColin Finck static NTSTATUS fast_io_release_for_ccflush(PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject) { 355c2c66affSColin Finck #endif 356c2c66affSColin Finck UNUSED(FileObject); 357c2c66affSColin Finck UNUSED(DeviceObject); 358c2c66affSColin Finck 359c2c66affSColin Finck if (IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP) 360c2c66affSColin Finck IoSetTopLevelIrp(NULL); 361c2c66affSColin Finck 362c2c66affSColin Finck return STATUS_SUCCESS; 363c2c66affSColin Finck } 364c2c66affSColin Finck 365c2c66affSColin Finck _Function_class_(FAST_IO_WRITE) 366c2c66affSColin Finck #ifdef __REACTOS__ 367c2c66affSColin Finck 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) { 368c2c66affSColin Finck #else 369c2c66affSColin Finck 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) { 370c2c66affSColin Finck #endif 371c2c66affSColin Finck if (FsRtlCopyWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject)) { 372c2c66affSColin Finck fcb* fcb = FileObject->FsContext; 373c2c66affSColin Finck 374c2c66affSColin Finck fcb->inode_item.st_size = fcb->Header.FileSize.QuadPart; 375c2c66affSColin Finck 376c2c66affSColin Finck return TRUE; 377c2c66affSColin Finck } 378c2c66affSColin Finck 379c2c66affSColin Finck return FALSE; 380c2c66affSColin Finck } 381c2c66affSColin Finck 382c2c66affSColin Finck void init_fast_io_dispatch(FAST_IO_DISPATCH** fiod) { 383c2c66affSColin Finck RtlZeroMemory(&FastIoDispatch, sizeof(FastIoDispatch)); 384c2c66affSColin Finck 385c2c66affSColin Finck FastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); 386c2c66affSColin Finck 387c2c66affSColin Finck FastIoDispatch.FastIoCheckIfPossible = fast_io_check_if_possible; 388c2c66affSColin Finck FastIoDispatch.FastIoQueryBasicInfo = fast_query_basic_info; 389c2c66affSColin Finck FastIoDispatch.FastIoQueryStandardInfo = fast_query_standard_info; 390c2c66affSColin Finck FastIoDispatch.FastIoQueryNetworkOpenInfo = fast_io_query_network_open_info; 391c2c66affSColin Finck FastIoDispatch.AcquireForModWrite = fast_io_acquire_for_mod_write; 392c2c66affSColin Finck FastIoDispatch.ReleaseForModWrite = fast_io_release_for_mod_write; 393c2c66affSColin Finck FastIoDispatch.AcquireForCcFlush = fast_io_acquire_for_ccflush; 394c2c66affSColin Finck FastIoDispatch.ReleaseForCcFlush = fast_io_release_for_ccflush; 395c2c66affSColin Finck FastIoDispatch.FastIoWrite = fast_io_write; 396c2c66affSColin Finck FastIoDispatch.FastIoRead = FsRtlCopyRead; 397c2c66affSColin Finck FastIoDispatch.MdlRead = FsRtlMdlReadDev; 398c2c66affSColin Finck FastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev; 399c2c66affSColin Finck FastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev; 400c2c66affSColin Finck FastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev; 401c2c66affSColin Finck 402c2c66affSColin Finck *fiod = &FastIoDispatch; 403c2c66affSColin Finck } 404