https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6e0cf03d922dc4773055f…
commit 6e0cf03d922dc4773055f605e53dd985eb4af462
Author: Vincent Franchomme <franchomme.vincent(a)gmail.com>
AuthorDate: Thu Apr 28 21:37:02 2022 +0200
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue May 3 17:30:11 2022 +0200
[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 <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;
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;