From 6e0cf03d922dc4773055f605e53dd985eb4af462 Mon Sep 17 00:00:00 2001 From: Vincent Franchomme Date: Thu, 28 Apr 2022 21:37:02 +0200 Subject: [PATCH] [BTRFS][UBTRFS][SHELLBTRFS] Upgrade to 1.8.0 (#4417) v1.8 (2022-03-12): - Added minimal support for fs-verity - ~~Added test suite~~ Not in ReactOS - Fixed incorrect disk usage statistics - Fixed potential crashes when renaming stream to file or file to stream - Fixed potential crashes when querying hard links on file - Fixed potential hang when opening oplocked file - Fixed minor issues also uncovered by test suite --- dll/shellext/shellbtrfs/shellbtrfs.rc | 10 ++-- dll/win32/ubtrfs/ubtrfs.rc | 10 ++-- drivers/filesystems/btrfs/btrfs.c | 34 ++----------- drivers/filesystems/btrfs/btrfs.h | 13 ++++- drivers/filesystems/btrfs/btrfs.inf | 4 +- drivers/filesystems/btrfs/btrfs.rc | 10 ++-- drivers/filesystems/btrfs/btrfs_drv.h | 1 - drivers/filesystems/btrfs/compress.c | 60 ---------------------- drivers/filesystems/btrfs/create.c | 67 +++++++++++++++---------- drivers/filesystems/btrfs/dirctrl.c | 12 ----- drivers/filesystems/btrfs/fastio.c | 8 +-- drivers/filesystems/btrfs/fileinfo.c | 31 +++++++++--- drivers/filesystems/btrfs/flushthread.c | 47 ++--------------- drivers/filesystems/btrfs/fsctl.c | 6 ++- drivers/filesystems/btrfs/pnp.c | 1 + drivers/filesystems/btrfs/read.c | 27 +--------- drivers/filesystems/btrfs/security.c | 2 +- drivers/filesystems/btrfs/write.c | 2 - 18 files changed, 111 insertions(+), 234 deletions(-) diff --git a/dll/shellext/shellbtrfs/shellbtrfs.rc b/dll/shellext/shellbtrfs/shellbtrfs.rc index 980929f108c..b83d7288147 100644 --- a/dll/shellext/shellbtrfs/shellbtrfs.rc +++ b/dll/shellext/shellbtrfs/shellbtrfs.rc @@ -61,8 +61,8 @@ IDI_ICON1 ICON "subvol.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,7,9,0 - PRODUCTVERSION 1,7,9,0 + FILEVERSION 1,8,0,0 + PRODUCTVERSION 1,8,0,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -78,12 +78,12 @@ BEGIN BLOCK "080904b0" BEGIN VALUE "FileDescription", "WinBtrfs shell extension" - VALUE "FileVersion", "1.7.9" + VALUE "FileVersion", "1.8.0" VALUE "InternalName", "btrfs" - VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-21" + VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-22" VALUE "OriginalFilename", "shellbtrfs.dll" VALUE "ProductName", "WinBtrfs" - VALUE "ProductVersion", "1.7.9" + VALUE "ProductVersion", "1.8.0" END END BLOCK "VarFileInfo" diff --git a/dll/win32/ubtrfs/ubtrfs.rc b/dll/win32/ubtrfs/ubtrfs.rc index 79609cf3464..e723033ba8e 100644 --- a/dll/win32/ubtrfs/ubtrfs.rc +++ b/dll/win32/ubtrfs/ubtrfs.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,7,9,0 - PRODUCTVERSION 1,7,9,0 + FILEVERSION 1,8,0,0 + PRODUCTVERSION 1,8,0,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BLOCK "080904b0" BEGIN VALUE "FileDescription", "Btrfs utility DLL" - VALUE "FileVersion", "1.7.9" + VALUE "FileVersion", "1.8.0" VALUE "InternalName", "ubtrfs" - VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-21" + VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-22" VALUE "OriginalFilename", "ubtrfs.dll" VALUE "ProductName", "WinBtrfs" - VALUE "ProductVersion", "1.7.9" + VALUE "ProductVersion", "1.8.0" END END BLOCK "VarFileInfo" diff --git a/drivers/filesystems/btrfs/btrfs.c b/drivers/filesystems/btrfs/btrfs.c index ea5d2f5cc20..866f80a9205 100644 --- a/drivers/filesystems/btrfs/btrfs.c +++ b/drivers/filesystems/btrfs/btrfs.c @@ -54,7 +54,8 @@ BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO | BTRFS_INCOMPAT_FLAGS_BIG_METADATA | BTRFS_INCOMPAT_FLAGS_RAID56 | \ BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF | BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA | BTRFS_INCOMPAT_FLAGS_NO_HOLES | \ BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD | BTRFS_INCOMPAT_FLAGS_METADATA_UUID | BTRFS_INCOMPAT_FLAGS_RAID1C34) -#define COMPAT_RO_SUPPORTED (BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE | BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE_VALID) +#define COMPAT_RO_SUPPORTED (BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE | BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE_VALID | \ + BTRFS_COMPAT_RO_FLAGS_VERITY) static const WCHAR device_name[] = {'\\','B','t','r','f','s',0}; static const WCHAR dosdevice_name[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','B','t','r','f','s',0}; @@ -3116,7 +3117,8 @@ static NTSTATUS look_for_roots(_Requires_exclusive_lock_held_(_Curr_->tree_lock) reloc_root->root_item.inode.st_blocks = Vcb->superblock.node_size; reloc_root->root_item.inode.st_nlink = 1; reloc_root->root_item.inode.st_mode = 040755; - reloc_root->root_item.inode.flags = 0xffffffff80000000; + reloc_root->root_item.inode.flags = 0x80000000; + reloc_root->root_item.inode.flags_ro = 0xffffffff; reloc_root->root_item.objid = SUBVOL_ROOT_INODE; reloc_root->root_item.bytes_used = Vcb->superblock.node_size; @@ -3840,32 +3842,6 @@ void protect_superblocks(_Inout_ chunk* c) { } } -uint64_t chunk_estimate_phys_size(device_extension* Vcb, chunk* c, uint64_t u) { - uint64_t nfactor, dfactor; - - if (c->chunk_item->type & BLOCK_FLAG_DUPLICATE || c->chunk_item->type & BLOCK_FLAG_RAID1 || c->chunk_item->type & BLOCK_FLAG_RAID10) { - nfactor = 1; - dfactor = 2; - } else if (c->chunk_item->type & BLOCK_FLAG_RAID5) { - nfactor = Vcb->superblock.num_devices - 1; - dfactor = Vcb->superblock.num_devices; - } else if (c->chunk_item->type & BLOCK_FLAG_RAID6) { - nfactor = Vcb->superblock.num_devices - 2; - dfactor = Vcb->superblock.num_devices; - } else if (c->chunk_item->type & BLOCK_FLAG_RAID1C3) { - nfactor = 1; - dfactor = 3; - } else if (c->chunk_item->type & BLOCK_FLAG_RAID1C4) { - nfactor = 1; - dfactor = 4; - } else { - nfactor = 1; - dfactor = 1; - } - - return u * dfactor / nfactor; -} - NTSTATUS find_chunk_usage(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _In_opt_ PIRP Irp) { LIST_ENTRY* le = Vcb->chunks.Flink; chunk* c; @@ -3898,7 +3874,7 @@ NTSTATUS find_chunk_usage(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_ex TRACE("chunk %I64x has %I64x bytes used\n", c->offset, c->used); - Vcb->superblock.bytes_used += chunk_estimate_phys_size(Vcb, c, bgi->used); + Vcb->superblock.bytes_used += bgi->used; } else { ERR("(%I64x;%I64x,%x,%I64x) is %u bytes, expected %Iu\n", Vcb->extent_root->id, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(BLOCK_GROUP_ITEM)); diff --git a/drivers/filesystems/btrfs/btrfs.h b/drivers/filesystems/btrfs/btrfs.h index b0b7fbd0015..962ede35ab9 100644 --- a/drivers/filesystems/btrfs/btrfs.h +++ b/drivers/filesystems/btrfs/btrfs.h @@ -9,6 +9,9 @@ #pragma once #include +#ifndef __REACTOS__ +#include +#endif // __REACTOS__ static const uint64_t superblock_addrs[] = { 0x10000, 0x4000000, 0x4000000000, 0x4000000000000, 0 }; @@ -101,10 +104,13 @@ static const uint64_t superblock_addrs[] = { 0x10000, 0x4000000, 0x4000000000, 0 #define BTRFS_INODE_DIRSYNC 0x400 #define BTRFS_INODE_COMPRESS 0x800 +#define BTRFS_INODE_RO_VERITY 0x1 + #define BTRFS_SUBVOL_READONLY 0x1 #define BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE 0x1 #define BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE_VALID 0x2 +#define BTRFS_COMPAT_RO_FLAGS_VERITY 0x4 #define BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF 0x0001 #define BTRFS_INCOMPAT_FLAGS_DEFAULT_SUBVOL 0x0002 @@ -288,7 +294,8 @@ typedef struct { uint32_t st_gid; uint32_t st_mode; uint64_t st_rdev; - uint64_t flags; + uint32_t flags; + uint32_t flags_ro; uint64_t sequence; uint8_t reserved[32]; BTRFS_TIME st_atime; @@ -297,6 +304,10 @@ typedef struct { BTRFS_TIME otime; } INODE_ITEM; +#ifndef __REACTOS__ +static_assert(sizeof(INODE_ITEM) == 0xa0, "INODE_ITEM has wrong size"); +#endif // __REACTOS__ + typedef struct { INODE_ITEM inode; uint64_t generation; diff --git a/drivers/filesystems/btrfs/btrfs.inf b/drivers/filesystems/btrfs/btrfs.inf index faeec384225..18dc5cd25e9 100644 --- a/drivers/filesystems/btrfs/btrfs.inf +++ b/drivers/filesystems/btrfs/btrfs.inf @@ -2,7 +2,7 @@ ;;; WinBtrfs ;;; ;;; -;;; Copyright (c) 2016-21 Mark Harmstone +;;; Copyright (c) 2016-22 Mark Harmstone ;;; [Version] @@ -10,7 +10,7 @@ Signature = "$Windows NT$" Class = Volume ClassGuid = {71a27cdd-812a-11d0-bec7-08002be2092f} Provider = %Me% -DriverVer = 10/02/2021,1.7.9 +DriverVer = 03/12/2022,1.8.0 CatalogFile = btrfs.cat [DestinationDirs] diff --git a/drivers/filesystems/btrfs/btrfs.rc b/drivers/filesystems/btrfs/btrfs.rc index 6b0d46874ef..59f9d2ccb1f 100644 --- a/drivers/filesystems/btrfs/btrfs.rc +++ b/drivers/filesystems/btrfs/btrfs.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,7,9,0 - PRODUCTVERSION 1,7,9,0 + FILEVERSION 1,8,0,0 + PRODUCTVERSION 1,8,0,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BLOCK "080904b0" BEGIN VALUE "FileDescription", "WinBtrfs" - VALUE "FileVersion", "1.7.9" + VALUE "FileVersion", "1.8.0" VALUE "InternalName", "btrfs" - VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-21" + VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-22" VALUE "OriginalFilename", "btrfs.sys" VALUE "ProductName", "WinBtrfs" - VALUE "ProductVersion", "1.7.9" + VALUE "ProductVersion", "1.8.0" END END BLOCK "VarFileInfo" diff --git a/drivers/filesystems/btrfs/btrfs_drv.h b/drivers/filesystems/btrfs/btrfs_drv.h index d033b789934..e06770adfac 100644 --- a/drivers/filesystems/btrfs/btrfs_drv.h +++ b/drivers/filesystems/btrfs/btrfs_drv.h @@ -1152,7 +1152,6 @@ void reap_fcb(fcb* fcb); void reap_fcbs(device_extension* Vcb); void reap_fileref(device_extension* Vcb, file_ref* fr); void reap_filerefs(device_extension* Vcb, file_ref* fr); -uint64_t chunk_estimate_phys_size(device_extension* Vcb, chunk* c, uint64_t u); NTSTATUS utf8_to_utf16(WCHAR* dest, ULONG dest_max, ULONG* dest_len, char* src, ULONG src_len); NTSTATUS utf16_to_utf8(char* dest, ULONG dest_max, ULONG* dest_len, WCHAR* src, ULONG src_len); uint32_t get_num_of_processors(); diff --git a/drivers/filesystems/btrfs/compress.c b/drivers/filesystems/btrfs/compress.c index d5d229905b6..6890add012d 100644 --- a/drivers/filesystems/btrfs/compress.c +++ b/drivers/filesystems/btrfs/compress.c @@ -731,9 +731,6 @@ NTSTATUS lzo_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t uint8_t* comp_data; lzo_stream stream; uint32_t* out_size; -#ifdef __REACTOS__ - unsigned int i; -#endif // __REACTOS__ num_pages = (unsigned int)sector_align(inlen, LZO_PAGE_SIZE) / LZO_PAGE_SIZE; @@ -764,11 +761,7 @@ NTSTATUS lzo_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t stream.in = inbuf; stream.out = comp_data + (2 * sizeof(uint32_t)); -#ifndef __REACTOS__ for (unsigned int i = 0; i < num_pages; i++) { -#else - for (i = 0; i < num_pages; i++) { -#endif // __REACTOS__ uint32_t* pagelen = (uint32_t*)(stream.out - sizeof(uint32_t)); stream.inlen = (uint32_t)min(LZO_PAGE_SIZE, outlen - (i * LZO_PAGE_SIZE)); @@ -891,10 +884,6 @@ NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void LIST_ENTRY* le; uint64_t address, extaddr; void* csum = NULL; -#ifdef __REACTOS__ - int32_t i2; - uint32_t i3, j; -#endif // __REACTOS__ if (fcb->Vcb->options.compress_type != 0 && fcb->prop_compression == PropCompression_None) type = fcb->Vcb->options.compress_type; @@ -934,11 +923,7 @@ NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void if (!NT_SUCCESS(Status)) { ERR("add_calc_job_comp returned %08lx\n", Status); -#ifndef __REACTOS__ for (unsigned int j = 0; j < i; j++) { -#else - for (j = 0; j < i; j++) { -#endif // __REACTOS__ KeWaitForSingleObject(&parts[j].cj->event, Executive, KernelMode, false, NULL); ExFreePool(parts[j].cj); } @@ -950,7 +935,6 @@ NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void Status = STATUS_SUCCESS; -#ifndef __REACTOS__ for (int i = num_parts - 1; i >= 0; i--) { calc_thread_main(fcb->Vcb, parts[i].cj); @@ -959,35 +943,18 @@ NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void if (!NT_SUCCESS(parts[i].cj->Status)) Status = parts[i].cj->Status; } -#else - for (i2 = num_parts - 1; i2 >= 0; i2--) { - calc_thread_main(fcb->Vcb, parts[i].cj); - - KeWaitForSingleObject(&parts[i2].cj->event, Executive, KernelMode, false, NULL); - - if (!NT_SUCCESS(parts[i2].cj->Status)) - Status = parts[i2].cj->Status; - } -#endif // __REACTOS__ if (!NT_SUCCESS(Status)) { ERR("calc job returned %08lx\n", Status); -#ifndef __REACTOS__ for (unsigned int i = 0; i < num_parts; i++) { ExFreePool(parts[i].cj); } -#else - for (i3 = 0; i3 < num_parts; i3++) { - ExFreePool(parts[i3].cj); - } -#endif // __REACTOS__ ExFreePool(parts); return Status; } -#ifndef __REACTOS__ for (unsigned int i = 0; i < num_parts; i++) { if (parts[i].cj->space_left >= fcb->Vcb->superblock.sector_size) { parts[i].compression_type = type; @@ -1013,33 +980,6 @@ NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void buflen += parts[i].outlen; ExFreePool(parts[i].cj); } -#else - for (i3 = 0; i3 < num_parts; i3++) { - if (parts[i3].cj->space_left >= fcb->Vcb->superblock.sector_size) { - parts[i3].compression_type = type; - parts[i3].outlen = parts[i3].inlen - parts[i3].cj->space_left; - - if (type == BTRFS_COMPRESSION_LZO) - fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO; - else if (type == BTRFS_COMPRESSION_ZSTD) - fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD; - - if ((parts[i3].outlen % fcb->Vcb->superblock.sector_size) != 0) { - unsigned int newlen = (unsigned int)sector_align(parts[i3].outlen, fcb->Vcb->superblock.sector_size); - - RtlZeroMemory(parts[i3].buf + parts[i3].outlen, newlen - parts[i3].outlen); - - parts[i3].outlen = newlen; - } - } else { - parts[i3].compression_type = BTRFS_COMPRESSION_NONE; - parts[i3].outlen = (unsigned int)sector_align(parts[i3].inlen, fcb->Vcb->superblock.sector_size); - } - - buflen += parts[i3].outlen; - ExFreePool(parts[i3].cj); - } -#endif // __REACTOS__ // check if first 128 KB of file is incompressible diff --git a/drivers/filesystems/btrfs/create.c b/drivers/filesystems/btrfs/create.c index 17e2e722acc..c5d27d1ce27 100644 --- a/drivers/filesystems/btrfs/create.c +++ b/drivers/filesystems/btrfs/create.c @@ -84,6 +84,8 @@ typedef struct { device_extension* Vcb; ACCESS_MASK granted_access; file_ref* fileref; + NTSTATUS Status; + KEVENT event; } oplock_context; fcb* create_fcb(device_extension* Vcb, POOL_TYPE pool_type) { @@ -2458,7 +2460,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr fileref->fcb = fcb; - if (Irp->Overlay.AllocationSize.QuadPart > 0 && !write_fcb_compressed(fcb)) { + if (Irp->Overlay.AllocationSize.QuadPart > 0 && !write_fcb_compressed(fcb) && fcb->type != BTRFS_TYPE_DIRECTORY) { Status = extend_file(fcb, fileref, Irp->Overlay.AllocationSize.QuadPart, true, NULL, rollback); if (!NT_SUCCESS(Status)) { @@ -2541,9 +2543,6 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr } } else { UNICODE_STRING fpusuc; -#ifdef __REACTOS__ - UINT32 dc_hash; -#endif Status = RtlUpcaseUnicodeString(&fpusuc, fpus, true); if (!NT_SUCCESS(Status)) { @@ -2560,11 +2559,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr return Status; } -#ifndef __REACTOS__ uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length); -#else - dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length); -#endif // __REACTOS__ if (parfileref->fcb->hash_ptrs_uc[dc_hash >> 24]) { LIST_ENTRY* le = parfileref->fcb->hash_ptrs_uc[dc_hash >> 24]; @@ -2669,12 +2664,16 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ if (parfileref->fcb == Vcb->dummy_fcb) return STATUS_ACCESS_DENIED; + Status = check_file_name_valid(stream, false, true); + if (!NT_SUCCESS(Status)) + return Status; + Status = open_fileref(Vcb, &newpar, fpus, parfileref, false, NULL, NULL, PagedPool, case_sensitive, Irp); if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { UNICODE_STRING fpus2; - Status = check_file_name_valid(fpus, false, true); + Status = check_file_name_valid(fpus, false, false); if (!NT_SUCCESS(Status)) return Status; @@ -3856,7 +3855,7 @@ static NTSTATUS open_file3(device_extension* Vcb, PIRP Irp, ACCESS_MASK granted_ return STATUS_SUCCESS; } -static void oplock_complete(PVOID Context, PIRP Irp) { +static void __stdcall oplock_complete(PVOID Context, PIRP Irp) { NTSTATUS Status; LIST_ENTRY rollback; bool skip_lock; @@ -3924,11 +3923,14 @@ static void oplock_complete(PVOID Context, PIRP Irp) { Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT); - ExFreePool(ctx); + ctx->Status = Status; + + KeSetEvent(&ctx->event, 0, false); } static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, file_ref* fileref, ACCESS_MASK* granted_access, - PFILE_OBJECT FileObject, UNICODE_STRING* fn, ULONG options, PIRP Irp, LIST_ENTRY* rollback) { + PFILE_OBJECT FileObject, UNICODE_STRING* fn, ULONG options, PIRP Irp, LIST_ENTRY* rollback, + oplock_context** opctx) { NTSTATUS Status; file_ref* sf; bool readonly; @@ -3992,6 +3994,8 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, fi goto end; } + readonly |= fileref->fcb->inode_item.flags_ro & BTRFS_INODE_RO_VERITY; + if (readonly) { ACCESS_MASK allowed; @@ -4090,13 +4094,16 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, fi ctx->Vcb = Vcb; ctx->granted_access = *granted_access; ctx->fileref = fileref; + KeInitializeEvent(&ctx->event, NotificationEvent, false); #ifdef __REACTOS__ Status = FsRtlCheckOplock(fcb_oplock(fileref->fcb), Irp, ctx, (POPLOCK_WAIT_COMPLETE_ROUTINE) oplock_complete, NULL); #else Status = FsRtlCheckOplock(fcb_oplock(fileref->fcb), Irp, ctx, oplock_complete, NULL); #endif /* __REACTOS__ */ - if (Status == STATUS_PENDING) + if (Status == STATUS_PENDING) { + *opctx = ctx; return Status; + } ExFreePool(ctx); @@ -4451,7 +4458,8 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) return STATUS_SUCCESS; } -static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) { +static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, PIRP Irp, + LIST_ENTRY* rollback, oplock_context** opctx) { PFILE_OBJECT FileObject = NULL; ULONG RequestedDisposition; ULONG options; @@ -4685,9 +4693,10 @@ loaded: goto exit; } - if (NT_SUCCESS(Status)) // file already exists - Status = open_file2(Vcb, RequestedDisposition, fileref, &granted_access, FileObject, &fn, options, Irp, rollback); - else { + if (NT_SUCCESS(Status)) { // file already exists + Status = open_file2(Vcb, RequestedDisposition, fileref, &granted_access, FileObject, &fn, + options, Irp, rollback, opctx); + } else { file_ref* existing_file = NULL; Status = file_create(Irp, Vcb, FileObject, related, loaded_related, &fn, RequestedDisposition, options, &existing_file, rollback); @@ -4695,7 +4704,8 @@ loaded: if (Status == STATUS_OBJECT_NAME_COLLISION) { // already exists fileref = existing_file; - Status = open_file2(Vcb, RequestedDisposition, fileref, &granted_access, FileObject, &fn, options, Irp, rollback); + Status = open_file2(Vcb, RequestedDisposition, fileref, &granted_access, FileObject, &fn, + options, Irp, rollback, opctx); } else { Irp->IoStatus.Information = NT_SUCCESS(Status) ? FILE_CREATED : 0; granted_access = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; @@ -4815,6 +4825,7 @@ NTSTATUS __stdcall drv_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpSp; device_extension* Vcb = DeviceObject->DeviceExtension; bool top_level, locked = false; + oplock_context* opctx = NULL; FsRtlEnterFileSystem(); @@ -4993,7 +5004,7 @@ NTSTATUS __stdcall drv_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { ExAcquireResourceSharedLite(&Vcb->fileref_lock, true); - Status = open_file(DeviceObject, Vcb, Irp, &rollback); + Status = open_file(DeviceObject, Vcb, Irp, &rollback, &opctx); if (!NT_SUCCESS(Status)) do_rollback(Vcb, &rollback); @@ -5007,18 +5018,22 @@ NTSTATUS __stdcall drv_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { } exit: - Irp->IoStatus.Status = Status; - - if (Status == STATUS_PENDING) - IoMarkIrpPending(Irp); - else + if (Status != STATUS_PENDING) { + Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT); - - TRACE("create returning %08lx\n", Status); + } if (locked) ExReleaseResourceLite(&Vcb->load_lock); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&opctx->event, Executive, KernelMode, false, NULL); + Status = opctx->Status; + ExFreePool(opctx); + } + + TRACE("create returning %08lx\n", Status); + if (top_level) IoSetTopLevelIrp(NULL); diff --git a/drivers/filesystems/btrfs/dirctrl.c b/drivers/filesystems/btrfs/dirctrl.c index 6b7b66cba4f..ce42fcf1e5d 100644 --- a/drivers/filesystems/btrfs/dirctrl.c +++ b/drivers/filesystems/btrfs/dirctrl.c @@ -640,18 +640,6 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir return STATUS_SUCCESS; } - case FileObjectIdInformation: - FIXME("STUB: FileObjectIdInformation\n"); - return STATUS_NOT_IMPLEMENTED; - - case FileQuotaInformation: - FIXME("STUB: FileQuotaInformation\n"); - return STATUS_NOT_IMPLEMENTED; - - case FileReparsePointInformation: - FIXME("STUB: FileReparsePointInformation\n"); - return STATUS_NOT_IMPLEMENTED; - default: WARN("Unknown FileInformationClass %u\n", IrpSp->Parameters.QueryDirectory.FileInformationClass); return STATUS_NOT_IMPLEMENTED; diff --git a/drivers/filesystems/btrfs/fastio.c b/drivers/filesystems/btrfs/fastio.c index a5f577efb93..76c2d96dc81 100644 --- a/drivers/filesystems/btrfs/fastio.c +++ b/drivers/filesystems/btrfs/fastio.c @@ -494,10 +494,8 @@ static BOOLEAN __stdcall fast_io_unlock_all_by_key(PFILE_OBJECT FileObject, PVOI #ifdef __REACTOS__ _Function_class_(FAST_IO_ACQUIRE_FILE) -static void __stdcall fast_io_acquire_for_create_section(_In_ PFILE_OBJECT FileObject) { -#else -static void fast_io_acquire_for_create_section(_In_ PFILE_OBJECT FileObject) { #endif /* __REACTOS__ */ +static void __stdcall fast_io_acquire_for_create_section(_In_ PFILE_OBJECT FileObject) { fcb* fcb; TRACE("(%p)\n", FileObject); @@ -516,10 +514,8 @@ static void fast_io_acquire_for_create_section(_In_ PFILE_OBJECT FileObject) { #ifdef __REACTOS__ _Function_class_(FAST_IO_RELEASE_FILE) -static void __stdcall fast_io_release_for_create_section(_In_ PFILE_OBJECT FileObject) { -#else -static void fast_io_release_for_create_section(_In_ PFILE_OBJECT FileObject) { #endif /* __REACTOS__ */ +static void __stdcall fast_io_release_for_create_section(_In_ PFILE_OBJECT FileObject) { fcb* fcb; TRACE("(%p)\n", FileObject); diff --git a/drivers/filesystems/btrfs/fileinfo.c b/drivers/filesystems/btrfs/fileinfo.c index cd21a9ce8f4..16febd612d6 100644 --- a/drivers/filesystems/btrfs/fileinfo.c +++ b/drivers/filesystems/btrfs/fileinfo.c @@ -1679,12 +1679,18 @@ static NTSTATUS rename_stream_to_file(device_extension* Vcb, file_ref* fileref, fileref->fcb->adsdata.Buffer = NULL; fileref->fcb->adsdata.Length = fileref->fcb->adsdata.MaximumLength = 0; + acquire_fcb_lock_exclusive(Vcb); + + RemoveEntryList(&fileref->fcb->list_entry); InsertHeadList(ofr->fcb->list_entry.Blink, &fileref->fcb->list_entry); if (fileref->fcb->subvol->fcbs_ptrs[fileref->fcb->hash >> 24] == &ofr->fcb->list_entry) fileref->fcb->subvol->fcbs_ptrs[fileref->fcb->hash >> 24] = &fileref->fcb->list_entry; RemoveEntryList(&ofr->fcb->list_entry); + + release_fcb_lock(Vcb); + ofr->fcb->list_entry.Flink = ofr->fcb->list_entry.Blink = NULL; mark_fcb_dirty(fileref->fcb); @@ -2475,8 +2481,6 @@ static NTSTATUS rename_file_to_stream(device_extension* Vcb, file_ref* fileref, mark_fileref_dirty(dummyfileref); - free_fileref(dummyfileref); - // change fcb values fileref->fcb->hash_ptrs = NULL; @@ -4577,6 +4581,12 @@ static NTSTATUS fill_in_hard_link_information(FILE_LINKS_INFORMATION* fli, file_ ExAcquireResourceExclusiveLite(&fcb->Vcb->fileref_lock, true); if (IsListEmpty(&fcb->hardlinks)) { + if (!fileref->dc) { + ExReleaseResourceLite(&fcb->Vcb->fileref_lock); + Status = STATUS_INVALID_PARAMETER; + goto end; + } + bytes_needed += sizeof(FILE_LINK_ENTRY_INFORMATION) + fileref->dc->name.Length - sizeof(WCHAR); if (bytes_needed > *length) @@ -4615,7 +4625,7 @@ static NTSTATUS fill_in_hard_link_information(FILE_LINKS_INFORMATION* fli, file_ while (le2 != &parfr->children) { file_ref* fr2 = CONTAINING_RECORD(le2, file_ref, list_entry); - if (fr2->dc->index == hl->index) { + if (fr2->dc && fr2->dc->index == hl->index) { found = true; deleted = fr2->deleted; @@ -4676,6 +4686,7 @@ static NTSTATUS fill_in_hard_link_information(FILE_LINKS_INFORMATION* fli, file_ Status = overflow ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS; +end: ExReleaseResourceLite(fcb->Header.Resource); return Status; @@ -5312,7 +5323,7 @@ static NTSTATUS query_info(device_extension* Vcb, PFILE_OBJECT FileObject, PIRP { FILE_STAT_INFORMATION* fsi = Irp->AssociatedIrp.SystemBuffer; - if (IrpSp->Parameters.QueryFile.Length < sizeof(FILE_STAT_LX_INFORMATION)) { + if (IrpSp->Parameters.QueryFile.Length < sizeof(FILE_STAT_INFORMATION)) { WARN("overflow\n"); Status = STATUS_BUFFER_OVERFLOW; goto exit; @@ -5510,10 +5521,12 @@ NTSTATUS __stdcall drv_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { ExAcquireResourceSharedLite(fcb->Header.Resource, true); - Status = STATUS_SUCCESS; - - if (fcb->ea_xattr.Length == 0) + if (fcb->ea_xattr.Length == 0) { + Status = STATUS_NO_EAS_ON_FILE; goto end2; + } + + Status = STATUS_SUCCESS; if (IrpSp->Parameters.QueryEa.EaList) { FILE_FULL_EA_INFORMATION *ea, *out; @@ -5610,8 +5623,10 @@ NTSTATUS __stdcall drv_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { ULONG i; for (i = 0; i < index; i++) { - if (ea->NextEntryOffset == 0) // last item + if (ea->NextEntryOffset == 0) { // last item + Status = STATUS_NO_MORE_EAS; goto end2; + } ea = (FILE_FULL_EA_INFORMATION*)(((uint8_t*)ea) + ea->NextEntryOffset); } diff --git a/drivers/filesystems/btrfs/flushthread.c b/drivers/filesystems/btrfs/flushthread.c index a574d433192..bdaf15bf69e 100644 --- a/drivers/filesystems/btrfs/flushthread.c +++ b/drivers/filesystems/btrfs/flushthread.c @@ -633,9 +633,6 @@ static NTSTATUS add_parents(device_extension* Vcb, PIRP Irp) { KEY searchkey; traverse_ptr tp; NTSTATUS Status; -#ifdef __REACTOS__ - tree* t2; -#endif searchkey.obj_id = t->root->id; searchkey.obj_type = TYPE_ROOT_ITEM; @@ -677,11 +674,7 @@ static NTSTATUS add_parents(device_extension* Vcb, PIRP Irp) { } } -#ifndef __REACTOS__ tree* t2 = tp.tree; -#else - t2 = tp.tree; -#endif while (t2) { t2->write = true; @@ -2892,9 +2885,6 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* } if (c->used != c->oldused) { -#ifdef __REACTOS__ - uint64_t old_phys_used, phys_used; -#endif searchkey.obj_id = c->offset; searchkey.obj_type = TYPE_BLOCK_GROUP_ITEM; searchkey.offset = c->chunk_item->size; @@ -2956,19 +2946,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* goto end; } -#ifndef __REACTOS__ - uint64_t old_phys_used = chunk_estimate_phys_size(Vcb, c, c->oldused); - uint64_t phys_used = chunk_estimate_phys_size(Vcb, c, c->used); -#else - old_phys_used = chunk_estimate_phys_size(Vcb, c, c->oldused); - phys_used = chunk_estimate_phys_size(Vcb, c, c->used); -#endif - - if (Vcb->superblock.bytes_used + phys_used > old_phys_used) - Vcb->superblock.bytes_used += phys_used - old_phys_used; - else - Vcb->superblock.bytes_used = 0; - + Vcb->superblock.bytes_used += c->used - c->oldused; c->oldused = c->used; } @@ -4316,7 +4294,7 @@ static NTSTATUS create_chunk(device_extension* Vcb, chunk* c, PIRP Irp) { c->created = false; c->oldused = c->used; - Vcb->superblock.bytes_used += chunk_estimate_phys_size(Vcb, c, c->used); + Vcb->superblock.bytes_used += c->used; return STATUS_SUCCESS; } @@ -5437,9 +5415,6 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis KEY searchkey; traverse_ptr tp; uint64_t i, factor; -#ifdef __REACTOS__ - uint64_t phys_used; -#endif CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];; TRACE("dropping chunk %I64x\n", c->offset); @@ -5706,16 +5681,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Vcb->superblock.incompat_flags &= ~BTRFS_INCOMPAT_FLAGS_RAID1C34; } -#ifndef __REACTOS__ - uint64_t phys_used = chunk_estimate_phys_size(Vcb, c, c->oldused); -#else - phys_used = chunk_estimate_phys_size(Vcb, c, c->oldused); -#endif // __REACTOS__ - - if (phys_used < Vcb->superblock.bytes_used) - Vcb->superblock.bytes_used -= phys_used; - else - Vcb->superblock.bytes_used = 0; + Vcb->superblock.bytes_used -= c->oldused; ExFreePool(c->chunk_item); ExFreePool(c->devices); @@ -6828,9 +6794,6 @@ static void flush_disk_caches(device_extension* Vcb) { LIST_ENTRY* le; ioctl_context context; ULONG num; -#ifdef __REACTOS__ - unsigned int i; -#endif context.left = 0; @@ -6908,11 +6871,7 @@ nextdev: KeWaitForSingleObject(&context.Event, Executive, KernelMode, false, NULL); -#ifndef __REACTOS__ for (unsigned int i = 0; i < num; i++) { -#else - for (i = 0; i < num; i++) { -#endif if (context.stripes[i].Irp) IoFreeIrp(context.stripes[i].Irp); } diff --git a/drivers/filesystems/btrfs/fsctl.c b/drivers/filesystems/btrfs/fsctl.c index 191dda11aa7..356031e395f 100644 --- a/drivers/filesystems/btrfs/fsctl.c +++ b/drivers/filesystems/btrfs/fsctl.c @@ -387,7 +387,8 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f r->root_item.inode.st_blocks = subvol->root_item.inode.st_blocks; r->root_item.inode.st_nlink = 1; r->root_item.inode.st_mode = __S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; // 40755 - r->root_item.inode.flags = 0xffffffff80000000; // FIXME - find out what these mean + r->root_item.inode.flags = 0x80000000; // FIXME - find out what these mean + r->root_item.inode.flags_ro = 0xffffffff; // FIXME - find out what these mean r->root_item.generation = Vcb->superblock.generation; r->root_item.objid = subvol->root_item.objid; r->root_item.block_number = address; @@ -935,7 +936,8 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo r->root_item.inode.st_blocks = Vcb->superblock.node_size; r->root_item.inode.st_nlink = 1; r->root_item.inode.st_mode = __S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; // 40755 - r->root_item.inode.flags = 0xffffffff80000000; // FIXME - find out what these mean + r->root_item.inode.flags = 0x80000000; // FIXME - find out what these mean + r->root_item.inode.flags_ro = 0xffffffff; // FIXME - find out what these mean if (bcs->readonly) r->root_item.flags |= BTRFS_SUBVOL_READONLY; diff --git a/drivers/filesystems/btrfs/pnp.c b/drivers/filesystems/btrfs/pnp.c index 54426102b9b..5a44b0198a6 100644 --- a/drivers/filesystems/btrfs/pnp.c +++ b/drivers/filesystems/btrfs/pnp.c @@ -200,6 +200,7 @@ static NTSTATUS bus_pnp(bus_device_extension* bde, PIRP Irp) { Status = STATUS_UNSUCCESSFUL; handled = true; break; + case IRP_MN_QUERY_CAPABILITIES: Status = bus_query_capabilities(Irp); handled = true; diff --git a/drivers/filesystems/btrfs/read.c b/drivers/filesystems/btrfs/read.c index 824a1c17b29..a7d4b872659 100644 --- a/drivers/filesystems/btrfs/read.c +++ b/drivers/filesystems/btrfs/read.c @@ -683,9 +683,6 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad runlength = RtlFindFirstRunClear(&ps->bmp, &index); while (runlength != 0) { -#ifdef __REACTOS__ - uint64_t runstart, runend, start, end; -#endif if (index >= ps->bmplen) break; @@ -695,17 +692,11 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad if (runlength == 0) break; } -#ifndef __REACTOS__ + uint64_t runstart = ps->address + (index << Vcb->sector_shift); uint64_t runend = runstart + (runlength << Vcb->sector_shift); uint64_t start = max(runstart, addr); uint64_t end = min(runend, addr + length); -#else - runstart = ps->address + (index * Vcb->sector_shift); - runend = runstart + (runlength * Vcb->sector_shift); - start = max(runstart, addr); - end = min(runend, addr + length); -#endif if (end > start) RtlCopyMemory(buf + start - addr, &ps->data[start - ps->address], (ULONG)(end - start)); @@ -1039,9 +1030,6 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad runlength = RtlFindFirstRunClear(&ps->bmp, &index); while (runlength != 0) { -#ifdef __REACTOS__ - uint64_t runstart, runend, start, end; -#endif if (index >= ps->bmplen) break; @@ -1052,17 +1040,10 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad break; } -#ifndef __REACTOS__ uint64_t runstart = ps->address + (index << Vcb->sector_shift); uint64_t runend = runstart + (runlength << Vcb->sector_shift); uint64_t start = max(runstart, addr); uint64_t end = min(runend, addr + length); -#else - runstart = ps->address + (index * Vcb->sector_shift); - runend = runstart + (runlength * Vcb->sector_shift); - start = max(runstart, addr); - end = min(runend, addr + length); -#endif if (end > start) RtlCopyMemory(buf + start - addr, &ps->data[start - ps->address], (ULONG)(end - start)); @@ -3191,12 +3172,8 @@ nextitem: RtlCopyMemory(rp->data, rp->buf + rp->bumpoff, rp->read); } else { uint8_t* buf = rp->buf; -#ifdef __REACTOS__ - unsigned int i; - for (i = 0; i < rp->num_extents; i++) { -#else + for (unsigned int i = 0; i < rp->num_extents; i++) { -#endif // __REACTOS__ uint8_t *decomp = NULL, *buf2; ULONG outlen, inlen, off2; uint32_t inpageoff = 0; diff --git a/drivers/filesystems/btrfs/security.c b/drivers/filesystems/btrfs/security.c index c1183de2465..2761c63a915 100644 --- a/drivers/filesystems/btrfs/security.c +++ b/drivers/filesystems/btrfs/security.c @@ -95,7 +95,7 @@ void add_user_mapping(WCHAR* sidstring, ULONG sidstringlength, uint32_t uid) { while (sidstringlength > 0) { val = 0; i = 0; - while (i < sidstringlength && sidstring[i] != '-') { + while (sidstring[i] != '-' && i < sidstringlength) { if (sidstring[i] >= '0' && sidstring[i] <= '9') { val *= 10; val += sidstring[i] - '0'; diff --git a/drivers/filesystems/btrfs/write.c b/drivers/filesystems/btrfs/write.c index f4661598400..f4056508035 100644 --- a/drivers/filesystems/btrfs/write.c +++ b/drivers/filesystems/btrfs/write.c @@ -4228,8 +4228,6 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void if (fcb->ads) make_inline = false; - else if (fcb->type == BTRFS_TYPE_SYMLINK) - make_inline = newlength <= (Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node) - offsetof(EXTENT_DATA, data[0])); else make_inline = newlength <= fcb->Vcb->options.max_inline;