[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
This commit is contained in:
Vincent Franchomme 2022-04-28 21:37:02 +02:00 committed by Hermès BÉLUSCA - MAÏTO
parent f5556fdc10
commit 6e0cf03d92
18 changed files with 111 additions and 234 deletions

View file

@ -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"

View file

@ -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"

View file

@ -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));

View file

@ -9,6 +9,9 @@
#pragma once
#include <stdint.h>
#ifndef __REACTOS__
#include <assert.h>
#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;

View file

@ -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]

View file

@ -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"

View file

@ -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();

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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';

View file

@ -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;