https://git.reactos.org/?p=reactos.git;a=commitdiff;h=060427353554079bdae3d…
commit 060427353554079bdae3d94cb8e53924d3c3cb16
Author: Vincent Franchomme <franchomme.vincent(a)gmail.com>
AuthorDate: Thu Apr 28 21:33:48 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.7.4 (#4417)
v1.7.4 (2020-08-23):
- Fixed issue when running compressed EXEs
- Changed build system to cmake
- Upgraded zstd to version 1.4.5
- Added support for FSCTL_GET_RETRIEVAL_POINTERS
- Miscellaneous bug fixes
---
dll/shellext/shellbtrfs/CMakeLists.txt | 9 +-
dll/shellext/shellbtrfs/balance.cpp | 14 +-
dll/shellext/shellbtrfs/contextmenu.cpp | 12 +-
dll/shellext/shellbtrfs/main.cpp | 4 +-
dll/shellext/shellbtrfs/recv.cpp | 170 +-
dll/shellext/shellbtrfs/scrub.cpp | 14 +-
dll/shellext/shellbtrfs/send.cpp | 22 +-
dll/shellext/shellbtrfs/shellbtrfs.rc | 8 +-
dll/shellext/shellbtrfs/volpropsheet.cpp | 21 +-
dll/win32/ubtrfs/ubtrfs.rc | 8 +-
drivers/filesystems/btrfs/CMakeLists.txt | 47 +-
drivers/filesystems/btrfs/boot.c | 4 +
drivers/filesystems/btrfs/btrfs.c | 147 +-
drivers/filesystems/btrfs/btrfs.rc | 8 +-
drivers/filesystems/btrfs/btrfs_drv.h | 87 +-
drivers/filesystems/btrfs/btrfsioctl.h | 8 +
drivers/filesystems/btrfs/compress.c | 17 +-
drivers/filesystems/btrfs/crc32c-amd64.S | 113 -
.../filesystems/btrfs/{crc32c-x86.S => crc32c.S} | 100 +-
drivers/filesystems/btrfs/crc32c.h | 8 +
drivers/filesystems/btrfs/create.c | 8 +-
drivers/filesystems/btrfs/dirctrl.c | 2 +-
drivers/filesystems/btrfs/fastio.c | 16 +
drivers/filesystems/btrfs/fileinfo.c | 8 +-
drivers/filesystems/btrfs/flushthread.c | 5 +-
drivers/filesystems/btrfs/fsctl.c | 369 +-
drivers/filesystems/btrfs/pnp.c | 2 +
drivers/filesystems/btrfs/read.c | 75 +-
drivers/filesystems/btrfs/reparse.c | 19 +-
drivers/filesystems/btrfs/scrub.c | 19 +-
drivers/filesystems/btrfs/security.c | 4 +-
drivers/filesystems/btrfs/volume.c | 94 +-
drivers/filesystems/btrfs/write.c | 6 +-
drivers/filesystems/btrfs/xor.S | 342 ++
drivers/filesystems/btrfs/zstd/bitstream.h | 81 +-
drivers/filesystems/btrfs/zstd/compiler.h | 78 +-
drivers/filesystems/btrfs/zstd/cpu.h | 4 +-
drivers/filesystems/btrfs/zstd/debug.h | 75 +-
drivers/filesystems/btrfs/zstd/entropy_common.c | 46 +-
drivers/filesystems/btrfs/zstd/error_private.c | 9 +-
drivers/filesystems/btrfs/zstd/error_private.h | 8 +-
drivers/filesystems/btrfs/zstd/fse.h | 50 +-
drivers/filesystems/btrfs/zstd/fse_compress.c | 90 +-
drivers/filesystems/btrfs/zstd/fse_decompress.c | 48 +-
drivers/filesystems/btrfs/zstd/hist.c | 88 +-
drivers/filesystems/btrfs/zstd/hist.h | 63 +-
drivers/filesystems/btrfs/zstd/huf.h | 78 +-
drivers/filesystems/btrfs/zstd/huf_compress.c | 271 +-
drivers/filesystems/btrfs/zstd/huf_decompress.c | 414 ++-
drivers/filesystems/btrfs/zstd/mem.h | 77 +-
drivers/filesystems/btrfs/zstd/zstd.h | 2168 +++++++-----
drivers/filesystems/btrfs/zstd/zstd_common.c | 6 +-
drivers/filesystems/btrfs/zstd/zstd_compress.c | 3690 +++++++++++---------
.../btrfs/zstd/zstd_compress_internal.h | 495 ++-
.../btrfs/zstd/zstd_compress_literals.c | 158 +
.../btrfs/zstd/zstd_compress_literals.h | 29 +
.../btrfs/zstd/zstd_compress_sequences.c | 419 +++
.../btrfs/zstd/zstd_compress_sequences.h | 54 +
.../btrfs/zstd/zstd_compress_superblock.c | 845 +++++
.../btrfs/zstd/zstd_compress_superblock.h | 32 +
drivers/filesystems/btrfs/zstd/zstd_cwksp.h | 525 +++
drivers/filesystems/btrfs/zstd/zstd_ddict.c | 244 ++
drivers/filesystems/btrfs/zstd/zstd_ddict.h | 44 +
drivers/filesystems/btrfs/zstd/zstd_decompress.c | 2513 ++++---------
.../filesystems/btrfs/zstd/zstd_decompress_block.c | 1432 ++++++++
.../filesystems/btrfs/zstd/zstd_decompress_block.h | 59 +
.../btrfs/zstd/zstd_decompress_internal.h | 189 +
drivers/filesystems/btrfs/zstd/zstd_double_fast.c | 116 +-
drivers/filesystems/btrfs/zstd/zstd_double_fast.h | 2 +-
drivers/filesystems/btrfs/zstd/zstd_errors.h | 4 +-
drivers/filesystems/btrfs/zstd/zstd_fast.c | 443 ++-
drivers/filesystems/btrfs/zstd/zstd_fast.h | 2 +-
drivers/filesystems/btrfs/zstd/zstd_internal.h | 236 +-
drivers/filesystems/btrfs/zstd/zstd_lazy.c | 159 +-
drivers/filesystems/btrfs/zstd/zstd_lazy.h | 4 +-
drivers/filesystems/btrfs/zstd/zstd_ldm.c | 127 +-
drivers/filesystems/btrfs/zstd/zstd_ldm.h | 15 +-
drivers/filesystems/btrfs/zstd/zstd_opt.c | 402 ++-
drivers/filesystems/btrfs/zstd/zstd_opt.h | 10 +-
sdk/lib/fslib/btrfslib/CMakeLists.txt | 9 +-
80 files changed, 11286 insertions(+), 6415 deletions(-)
diff --git a/dll/shellext/shellbtrfs/CMakeLists.txt
b/dll/shellext/shellbtrfs/CMakeLists.txt
index 6cbd3b04271..8fe8aa4d7ae 100644
--- a/dll/shellext/shellbtrfs/CMakeLists.txt
+++ b/dll/shellext/shellbtrfs/CMakeLists.txt
@@ -22,10 +22,17 @@ list(APPEND SOURCE
volpropsheet.cpp)
list(APPEND PCH_SKIP_SOURCE
- guid.c)
+ guid.c
+ ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs/crc32c.c)
+
+if((ARCH STREQUAL "i386") OR (ARCH STREQUAL "amd64"))
+ list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs/crc32c.S)
+ add_asm_files(btrfs_asm ${ASM_SOURCE})
+endif()
add_library(shellbtrfs MODULE
${SOURCE}
+ ${btrfs_asm}
${PCH_SKIP_SOURCE}
shellbtrfs.rc
${CMAKE_CURRENT_BINARY_DIR}/shellbtrfs.def)
diff --git a/dll/shellext/shellbtrfs/balance.cpp b/dll/shellext/shellbtrfs/balance.cpp
index b73978167fc..baa2d07ce38 100644
--- a/dll/shellext/shellbtrfs/balance.cpp
+++ b/dll/shellext/shellbtrfs/balance.cpp
@@ -1061,11 +1061,7 @@ static void unserialize(void* data, ULONG len, WCHAR* s) {
}
}
-#ifdef __REACTOS__
-extern "C" {
-#endif
-
-void CALLBACK StartBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
+extern "C" void CALLBACK StartBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
try {
WCHAR *s, *vol, *block;
win_handle h, token;
@@ -1126,7 +1122,7 @@ void CALLBACK StartBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int
}
}
-void CALLBACK PauseBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
+extern "C" void CALLBACK PauseBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
try {
win_handle h, token;
TOKEN_PRIVILEGES tp;
@@ -1173,7 +1169,7 @@ void CALLBACK PauseBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int
}
}
-void CALLBACK StopBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
+extern "C" void CALLBACK StopBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
try {
win_handle h, token;
TOKEN_PRIVILEGES tp;
@@ -1217,7 +1213,3 @@ void CALLBACK StopBalanceW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int n
error_message(hwnd, e.what());
}
}
-
-#ifdef __REACTOS__
-} /* extern "C" */
-#endif
diff --git a/dll/shellext/shellbtrfs/contextmenu.cpp
b/dll/shellext/shellbtrfs/contextmenu.cpp
index 3fbca1cb7c2..004ac00057c 100644
--- a/dll/shellext/shellbtrfs/contextmenu.cpp
+++ b/dll/shellext/shellbtrfs/contextmenu.cpp
@@ -1643,11 +1643,7 @@ static void reflink_copy2(const wstring& srcfn, const
wstring& destdir, const ws
}
}
-#ifdef __REACTOS__
-extern "C" {
-#endif
-
-void CALLBACK ReflinkCopyW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
+extern "C" void CALLBACK ReflinkCopyW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
vector<wstring> args;
command_line_to_args(lpszCmdLine, args);
@@ -1719,8 +1715,4 @@ void CALLBACK ReflinkCopyW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int n
}
}
}
-}
-
-#ifdef __REACTOS__
-} /* extern "C" */
-#endif
+}
\ No newline at end of file
diff --git a/dll/shellext/shellbtrfs/main.cpp b/dll/shellext/shellbtrfs/main.cpp
index 9ba209ab664..55b4121a090 100644
--- a/dll/shellext/shellbtrfs/main.cpp
+++ b/dll/shellext/shellbtrfs/main.cpp
@@ -309,7 +309,7 @@ static void write_reg_key(HKEY root, const wstring& keyname, const
WCHAR* val, c
static void register_clsid(const GUID clsid, const WCHAR* description) {
WCHAR* clsidstring;
- wstring inproc, progid, clsidkeyname;
+ wstring inproc, clsidkeyname;
WCHAR dllpath[MAX_PATH];
StringFromCLSID(clsid, &clsidstring);
@@ -317,11 +317,9 @@ static void register_clsid(const GUID clsid, const WCHAR*
description) {
try {
#ifndef __REACTOS__
inproc = L"CLSID\\"s + clsidstring + L"\\InprocServer32"s;
- progid = L"CLSID\\"s + clsidstring + L"\\ProgId"s;
clsidkeyname = L"CLSID\\"s + clsidstring;
#else
inproc = wstring(L"CLSID\\") + clsidstring +
wstring(L"\\InprocServer32");
- progid = wstring(L"CLSID\\") + clsidstring +
wstring(L"\\ProgId");
clsidkeyname = wstring(L"CLSID\\") + clsidstring;
#endif
diff --git a/dll/shellext/shellbtrfs/recv.cpp b/dll/shellext/shellbtrfs/recv.cpp
index c18b5c92627..0c1ff3ef589 100644
--- a/dll/shellext/shellbtrfs/recv.cpp
+++ b/dll/shellext/shellbtrfs/recv.cpp
@@ -23,16 +23,15 @@
#include <iostream>
#include "recv.h"
#include "resource.h"
+#include "crc32c.h"
+
-#ifndef __REACTOS__
#ifndef _MSC_VER
#include <cpuid.h>
#else
#include <intrin.h>
#endif
-#include <smmintrin.h>
-#endif
const string EA_NTACL = "security.NTACL";
const string EA_DOSATTRIB = "user.DOSATTRIB";
@@ -40,118 +39,6 @@ const string EA_REPARSE = "user.reparse";
const string EA_EA = "user.EA";
const string XATTR_USER = "user.";
-#ifndef __REACTOS__
-bool have_sse42 = false;
-#endif
-
-static const uint32_t crctable[] = {
- 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8,
0xd4ca64eb,
- 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x4d43cfd0, 0xbf284cd3, 0xac78bf27,
0x5e133c24,
- 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087,
0xc494a384,
- 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc, 0xbc267848,
0x4e4dfb4b,
- 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, 0xe72719c1, 0x154c9ac2, 0x061c6936,
0xf477ea35,
- 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9,
0x7eaeb2fa,
- 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad, 0x1642ae59,
0xe4292d5a,
- 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, 0x7da08661, 0x8fcb0562, 0x9c9bf696,
0x6ef07595,
- 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54,
0x95b17957,
- 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f, 0xed03a29b,
0x1f682198,
- 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, 0x96bf4dcc, 0x64d4cecf, 0x77843d3b,
0x85efbe38,
- 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4,
0x0f36e6f7,
- 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e, 0x4767748a,
0xb50cf789,
- 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45,
0x3fd5af46,
- 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5,
0xa55230e6,
- 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a,
0x2f8b6829,
- 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, 0x456cac67, 0xb7072f64, 0xa457dc90,
0x563c5f93,
- 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f,
0xdce5075c,
- 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b, 0xb4091bff,
0x466298fc,
- 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330,
0xccbbc033,
- 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e,
0x7681d14d,
- 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975, 0x0e330a81,
0xfc588982,
- 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, 0x758fe5d6, 0x87e466d5, 0x94b49521,
0x66df1622,
- 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee,
0xec064eed,
- 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8, 0xe52cc12c,
0x1747422f,
- 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, 0x8ecee914, 0x7ca56a17, 0x6ff599e3,
0x9d9e1ae0,
- 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643,
0x07198540,
- 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c,
0x8dc0dd8f,
- 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2,
0x37faccf1,
- 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d,
0xbd23943e,
- 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69, 0xd5cf889d,
0x27a40b9e,
- 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052,
0xad7d5351,
-};
-
-// HW code taken from
https://github.com/rurban/smhasher/blob/master/crc32_hw.c
-#define ALIGN_SIZE 0x08UL
-#define ALIGN_MASK (ALIGN_SIZE - 1)
-#define CALC_CRC(op, crc, type, buf, len) \
-do { \
- for (; (len) >= sizeof (type); (len) -= (ULONG)sizeof(type), buf += sizeof (type))
{ \
- (crc) = (uint32_t)op((crc), *(type *) (buf)); \
- } \
-} while(0)
-
-#ifndef __REACTOS__
-static uint32_t crc32c_hw(const void *input, ULONG len, uint32_t crc) {
- const char* buf = (const char*)input;
-
- // Annoyingly, the CRC32 intrinsics don't work properly in modern versions of
MSVC -
- // it compiles _mm_crc32_u8 as if it was _mm_crc32_u32. And because we're
apparently
- // not allowed to use inline asm on amd64, there's no easy way to fix this!
-
- for (; (len > 0) && ((size_t)buf & ALIGN_MASK); len--, buf++) {
-#ifdef _MSC_VER
- crc = crctable[(crc ^ *buf) & 0xff] ^ (crc >> 8);
-#else
- crc = _mm_crc32_u8(crc, *buf);
-#endif
- }
-
-#ifdef _AMD64_
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4244) // _mm_crc32_u64 wants to return uint64_t(!)
-#pragma warning(disable:4242)
-#endif
- CALC_CRC(_mm_crc32_u64, crc, uint64_t, buf, len);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-#endif
- CALC_CRC(_mm_crc32_u32, crc, uint32_t, buf, len);
-
-#ifdef _MSC_VER
- for (; len > 0; len--, buf++) {
- crc = crctable[(crc ^ *buf) & 0xff] ^ (crc >> 8);
- }
-#else
- CALC_CRC(_mm_crc32_u16, crc, uint16_t, buf, len);
- CALC_CRC(_mm_crc32_u8, crc, uint8_t, buf, len);
-#endif
-
- return crc;
-}
-#endif
-
-static uint32_t calc_crc32c(uint32_t seed, uint8_t* msg, ULONG msglen) {
-#ifndef __REACTOS__
- if (have_sse42)
- return crc32c_hw(msg, msglen, seed);
- else {
-#endif
- uint32_t rem;
- ULONG i;
-
- rem = seed;
-
- for (i = 0; i < msglen; i++) {
- rem = crctable[(rem ^ msg[i]) & 0xff] ^ (rem >> 8);
- }
-
- return rem;
-#ifndef __REACTOS__
- }
-#endif
-}
-
bool BtrfsRecv::find_tlv(uint8_t* data, ULONG datalen, uint16_t type, void** value,
ULONG* len) {
size_t off = 0;
@@ -1473,6 +1360,33 @@ void BtrfsRecv::do_recv(const win_handle& f, uint64_t* pos,
uint64_t size, const
}
}
+#if defined(_X86_) || defined(_AMD64_)
+static void check_cpu() {
+ bool have_sse42 = false;
+
+#ifndef _MSC_VER
+ {
+ uint32_t eax, ebx, ecx, edx;
+
+ __cpuid(1, eax, ebx, ecx, edx);
+
+ if (__get_cpuid(1, &eax, &ebx, &ecx, &edx))
+ have_sse42 = ecx & bit_SSE4_2;
+ }
+#else
+ {
+ int cpu_info[4];
+
+ __cpuid(cpu_info, 1);
+ have_sse42 = (unsigned int)cpu_info[2] & (1 << 20);
+ }
+#endif
+
+ if (have_sse42)
+ calc_crc32c = calc_crc32c_hw;
+}
+#endif
+
DWORD BtrfsRecv::recv_thread() {
LARGE_INTEGER size;
uint64_t pos = 0;
@@ -1612,22 +1526,12 @@ static INT_PTR CALLBACK stub_RecvProgressDlgProc(HWND hwndDlg,
UINT uMsg, WPARAM
}
void BtrfsRecv::Open(HWND hwnd, const wstring& file, const wstring& path, bool
quiet) {
-#ifndef __REACTOS__
- uint32_t cpuInfo[4];
-#endif
-
streamfile = file;
dirpath = path;
subvolpath = L"";
-#ifndef __REACTOS__
-#ifndef _MSC_VER
- __get_cpuid(1, &cpuInfo[0], &cpuInfo[1], &cpuInfo[2], &cpuInfo[3]);
- have_sse42 = cpuInfo[2] & bit_SSE4_2;
-#else
- __cpuid((int*)cpuInfo, 1);
- have_sse42 = cpuInfo[2] & (1 << 20);
-#endif
+#if defined(_X86_) || defined(_AMD64_)
+ check_cpu();
#endif
if (quiet)
@@ -1638,11 +1542,7 @@ void BtrfsRecv::Open(HWND hwnd, const wstring& file, const
wstring& path, bool q
}
}
-#ifdef __REACTOS__
-extern "C" {
-#endif
-
-void CALLBACK RecvSubvolGUIW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int
nCmdShow) {
+extern "C" void CALLBACK RecvSubvolGUIW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
try {
OPENFILENAMEW ofn;
WCHAR file[MAX_PATH];
@@ -1714,7 +1614,7 @@ void CALLBACK RecvSubvolGUIW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int
}
}
-void CALLBACK RecvSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
+extern "C" void CALLBACK RecvSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
try {
vector<wstring> args;
@@ -1774,7 +1674,3 @@ void CALLBACK RecvSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nC
cerr << "Error: " << e.what() << endl;
}
}
-
-#ifdef __REACTOS__
-} /* extern "C" */
-#endif
diff --git a/dll/shellext/shellbtrfs/scrub.cpp b/dll/shellext/shellbtrfs/scrub.cpp
index c0b39c0ad4b..f04091851d8 100644
--- a/dll/shellext/shellbtrfs/scrub.cpp
+++ b/dll/shellext/shellbtrfs/scrub.cpp
@@ -483,11 +483,7 @@ static INT_PTR CALLBACK stub_ScrubDlgProc(HWND hwndDlg, UINT uMsg,
WPARAM wParam
return false;
}
-#ifdef __REACTOS__
-extern "C" {
-#endif
-
-void CALLBACK ShowScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
+extern "C" void CALLBACK ShowScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
try {
win_handle token;
TOKEN_PRIVILEGES tp;
@@ -516,7 +512,7 @@ void CALLBACK ShowScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCm
}
}
-void CALLBACK StartScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
+extern "C" void CALLBACK StartScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
vector<wstring> args;
command_line_to_args(lpszCmdLine, args);
@@ -552,7 +548,7 @@ void CALLBACK StartScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nC
}
}
-void CALLBACK StopScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) {
+extern "C" void CALLBACK StopScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
vector<wstring> args;
command_line_to_args(lpszCmdLine, args);
@@ -587,7 +583,3 @@ void CALLBACK StopScrubW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCm
}
}
}
-
-#ifdef __REACTOS__
-} /* extern "C" */
-#endif
diff --git a/dll/shellext/shellbtrfs/send.cpp b/dll/shellext/shellbtrfs/send.cpp
index f61e7510c3e..74ba33774e0 100644
--- a/dll/shellext/shellbtrfs/send.cpp
+++ b/dll/shellext/shellbtrfs/send.cpp
@@ -532,11 +532,7 @@ void BtrfsSend::Open(HWND hwnd, LPWSTR path) {
throw last_error(GetLastError());
}
-#ifdef __REACTOS__
-extern "C" {
-#endif
-
-void CALLBACK SendSubvolGUIW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int
nCmdShow) {
+extern "C" void CALLBACK SendSubvolGUIW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
try {
win_handle token;
TOKEN_PRIVILEGES tp;
@@ -565,10 +561,6 @@ void CALLBACK SendSubvolGUIW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int
}
}
-#ifdef __REACTOS__
-} /* extern "C" */
-#endif
-
static void send_subvol(const wstring& subvol, const wstring& file, const
wstring& parent, const vector<wstring>& clones) {
char* buf;
win_handle dirh, stream;
@@ -682,11 +674,7 @@ static void send_subvol(const wstring& subvol, const wstring&
file, const wstrin
free(buf);
}
-#ifdef __REACTOS__
-extern "C" {
-#endif
-
-void CALLBACK SendSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
+extern "C" void CALLBACK SendSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nCmdShow) {
vector<wstring> args;
wstring subvol = L"", parent = L"", file = L"";
vector<wstring> clones;
@@ -741,8 +729,4 @@ void CALLBACK SendSubvolW(HWND hwnd, HINSTANCE hinst, LPWSTR
lpszCmdLine, int nC
}
}
}
-}
-
-#ifdef __REACTOS__
-} /* extern "C" */
-#endif
+}
\ No newline at end of file
diff --git a/dll/shellext/shellbtrfs/shellbtrfs.rc
b/dll/shellext/shellbtrfs/shellbtrfs.rc
index efc8aa1e581..4b6bbe2e883 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,3,0
- PRODUCTVERSION 1,7,3,0
+ FILEVERSION 1,7,4,0
+ PRODUCTVERSION 1,7,4,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -78,12 +78,12 @@ BEGIN
BLOCK "080904b0"
BEGIN
VALUE "FileDescription", "WinBtrfs shell extension"
- VALUE "FileVersion", "1.7.3"
+ VALUE "FileVersion", "1.7.4"
VALUE "InternalName", "btrfs"
VALUE "LegalCopyright", "Copyright (c) Mark Harmstone
2016-20"
VALUE "OriginalFilename", "shellbtrfs.dll"
VALUE "ProductName", "WinBtrfs"
- VALUE "ProductVersion", "1.7.3"
+ VALUE "ProductVersion", "1.7.4"
END
END
BLOCK "VarFileInfo"
diff --git a/dll/shellext/shellbtrfs/volpropsheet.cpp
b/dll/shellext/shellbtrfs/volpropsheet.cpp
index 97de35ae3e1..ddc7dc24af0 100644
--- a/dll/shellext/shellbtrfs/volpropsheet.cpp
+++ b/dll/shellext/shellbtrfs/volpropsheet.cpp
@@ -1590,9 +1590,7 @@ INT_PTR BtrfsChangeDriveLetter::DlgProc(HWND hwndDlg, UINT uMsg,
WPARAM wParam,
return false;
}
-#ifdef __REACTOS__
-INT_PTR CALLBACK VolPropSheetDlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
-{
+static INT_PTR __stdcall dlg_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BtrfsChangeDriveLetter* bcdl;
if (uMsg == WM_INITDIALOG) {
@@ -1603,24 +1601,9 @@ INT_PTR CALLBACK VolPropSheetDlgproc(HWND hwndDlg, UINT uMsg,
WPARAM wParam, LPA
return bcdl->DlgProc(hwndDlg, uMsg, wParam, lParam);
}
-#endif
void BtrfsChangeDriveLetter::show() {
-#ifndef __REACTOS__
- DialogBoxParamW(module, MAKEINTRESOURCEW(IDD_DRIVE_LETTER), hwnd, [](HWND hwndDlg,
UINT uMsg, WPARAM wParam, LPARAM lParam) {
- BtrfsChangeDriveLetter* bcdl;
-
- if (uMsg == WM_INITDIALOG) {
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)lParam);
- bcdl = (BtrfsChangeDriveLetter*)lParam;
- } else
- bcdl = (BtrfsChangeDriveLetter*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- return bcdl->DlgProc(hwndDlg, uMsg, wParam, lParam);
- }, (LPARAM)this);
-#else
- DialogBoxParamW(module, MAKEINTRESOURCEW(IDD_DRIVE_LETTER), hwnd,
VolPropSheetDlgproc, (LPARAM)this);
-#endif
+ DialogBoxParamW(module, MAKEINTRESOURCEW(IDD_DRIVE_LETTER), hwnd, dlg_proc,
(LPARAM)this);
}
#ifdef __cplusplus
diff --git a/dll/win32/ubtrfs/ubtrfs.rc b/dll/win32/ubtrfs/ubtrfs.rc
index add9d0a5752..903edb0c9a5 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,3,0
- PRODUCTVERSION 1,7,3,0
+ FILEVERSION 1,7,4,0
+ PRODUCTVERSION 1,7,4,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BLOCK "080904b0"
BEGIN
VALUE "FileDescription", "Btrfs utility DLL"
- VALUE "FileVersion", "1.7.3"
+ VALUE "FileVersion", "1.7.4"
VALUE "InternalName", "ubtrfs"
VALUE "LegalCopyright", "Copyright (c) Mark Harmstone
2016-20"
VALUE "OriginalFilename", "ubtrfs.dll"
VALUE "ProductName", "WinBtrfs"
- VALUE "ProductVersion", "1.7.3"
+ VALUE "ProductVersion", "1.7.4"
END
END
BLOCK "VarFileInfo"
diff --git a/drivers/filesystems/btrfs/CMakeLists.txt
b/drivers/filesystems/btrfs/CMakeLists.txt
index b86b210542e..bbe29b2b838 100644
--- a/drivers/filesystems/btrfs/CMakeLists.txt
+++ b/drivers/filesystems/btrfs/CMakeLists.txt
@@ -3,6 +3,28 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/drivers
${REACTOS_SOURCE_DIR}/sdk/include/reactos/libs/zlib
inc)
+set(ZSTD_SRC_FILES
+ zstd/entropy_common.c
+ zstd/error_private.c
+ zstd/fse_compress.c
+ zstd/fse_decompress.c
+ zstd/hist.c
+ zstd/huf_compress.c
+ zstd/huf_decompress.c
+ zstd/zstd_common.c
+ zstd/zstd_compress.c
+ zstd/zstd_compress_literals.c
+ zstd/zstd_compress_sequences.c
+ zstd/zstd_compress_superblock.c
+ zstd/zstd_ddict.c
+ zstd/zstd_decompress.c
+ zstd/zstd_decompress_block.c
+ zstd/zstd_double_fast.c
+ zstd/zstd_fast.c
+ zstd/zstd_lazy.c
+ zstd/zstd_ldm.c
+ zstd/zstd_opt.c)
+
list(APPEND SOURCE
balance.c
blake2b-ref.c
@@ -38,31 +60,14 @@ list(APPEND SOURCE
worker-thread.c
write.c
xxhash.c
- zstd/entropy_common.c
- zstd/fse_compress.c
- zstd/hist.c
- zstd/huf_decompress.c
- zstd/zstd_common.c
- zstd/zstd_decompress.c
- zstd/zstd_fast.c
- zstd/zstd_ldm.c
- zstd/error_private.c
- zstd/fse_decompress.c
- zstd/huf_compress.c
- zstd/zstd_compress.c
- zstd/zstd_double_fast.c
- zstd/zstd_lazy.c
- zstd/zstd_opt.c
+ ${ZSTD_SRC_FILES}
btrfs_drv.h)
-if(ARCH STREQUAL "i386")
- list(APPEND ASM_SOURCE crc32c-x86.S)
-elseif(ARCH STREQUAL "amd64")
- list(APPEND ASM_SOURCE crc32c-amd64.S)
+if((ARCH STREQUAL "i386") OR (ARCH STREQUAL "amd64"))
+ list(APPEND ASM_SOURCE crc32c.S xor.S)
+ add_asm_files(btrfs_asm ${ASM_SOURCE})
endif()
-add_asm_files(btrfs_asm ${ASM_SOURCE})
-
add_library(btrfs MODULE ${SOURCE} ${btrfs_asm} btrfs.rc)
if(MSVC)
diff --git a/drivers/filesystems/btrfs/boot.c b/drivers/filesystems/btrfs/boot.c
index 810717e9da1..43486cfad33 100644
--- a/drivers/filesystems/btrfs/boot.c
+++ b/drivers/filesystems/btrfs/boot.c
@@ -506,6 +506,10 @@ void __stdcall check_system_root(PDRIVER_OBJECT DriverObject, PVOID
Context, ULO
TRACE("(%p, %p, %lu)\n", DriverObject, Context, Count);
+ UNUSED(DriverObject);
+ UNUSED(Context);
+ UNUSED(Count);
+
// wait for any PNP notifications in progress to finish
ExAcquireResourceExclusiveLite(&boot_lock, TRUE);
ExReleaseResourceLite(&boot_lock);
diff --git a/drivers/filesystems/btrfs/btrfs.c b/drivers/filesystems/btrfs/btrfs.c
index 227e5d438c6..4824af9c87b 100644
--- a/drivers/filesystems/btrfs/btrfs.c
+++ b/drivers/filesystems/btrfs/btrfs.c
@@ -63,9 +63,6 @@ DEFINE_GUID(BtrfsBusInterface, 0x4d414874, 0x6865, 0x6761, 0x6d, 0x65,
0x83, 0x6
PDRIVER_OBJECT drvobj;
PDEVICE_OBJECT master_devobj, busobj;
-#ifndef __REACTOS__
-bool have_sse2 = false;
-#endif
uint64_t num_reads = 0;
LIST_ENTRY uid_map_list, gid_map_list;
LIST_ENTRY VcbList;
@@ -123,6 +120,9 @@ static void init_serial(bool first_time);
#endif
static NTSTATUS close_file(_In_ PFILE_OBJECT FileObject, _In_ PIRP Irp);
+static void __stdcall do_xor_basic(uint8_t* buf1, uint8_t* buf2, uint32_t len);
+
+xor_func do_xor = do_xor_basic;
typedef struct {
KEVENT Event;
@@ -282,6 +282,49 @@ bool is_top_level(_In_ PIRP Irp) {
return false;
}
+static void __stdcall do_xor_basic(uint8_t* buf1, uint8_t* buf2, uint32_t len) {
+ uint32_t j;
+
+#if defined(_ARM_) || defined(_ARM64_)
+ uint64x2_t x1, x2;
+
+ if (((uintptr_t)buf1 & 0xf) == 0 && ((uintptr_t)buf2 & 0xf) == 0) {
+ while (len >= 16) {
+ x1 = vld1q_u64((const uint64_t*)buf1);
+ x2 = vld1q_u64((const uint64_t*)buf2);
+ x1 = veorq_u64(x1, x2);
+ vst1q_u64((uint64_t*)buf1, x1);
+
+ buf1 += 16;
+ buf2 += 16;
+ len -= 16;
+ }
+ }
+#endif
+
+#if defined(_AMD64_) || defined(_ARM64_)
+ while (len > 8) {
+ *(uint64_t*)buf1 ^= *(uint64_t*)buf2;
+ buf1 += 8;
+ buf2 += 8;
+ len -= 8;
+ }
+#endif
+
+ while (len > 4) {
+ *(uint32_t*)buf1 ^= *(uint32_t*)buf2;
+ buf1 += 4;
+ buf2 += 4;
+ len -= 4;
+ }
+
+ for (j = 0; j < len; j++) {
+ *buf1 ^= *buf2;
+ buf1++;
+ buf2++;
+ }
+}
+
_Function_class_(DRIVER_UNLOAD)
static void __stdcall DriverUnload(_In_ PDRIVER_OBJECT DriverObject) {
UNICODE_STRING dosdevice_nameW;
@@ -520,7 +563,7 @@ static NTSTATUS __stdcall drv_flush_buffers(_In_ PDEVICE_OBJECT
DeviceObject, _I
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_flush_buffers(DeviceObject, Irp);
+ Status = STATUS_SUCCESS;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_SUCCESS;
@@ -726,14 +769,8 @@ NTSTATUS utf8_to_utf16(WCHAR* dest, ULONG dest_max, ULONG* dest_len,
char* src,
uint8_t* in = (uint8_t*)src;
uint16_t* out = (uint16_t*)dest;
ULONG needed = 0, left = dest_max / sizeof(uint16_t);
-#ifdef __REACTOS__
- ULONG i;
-
- for (i = 0; i < src_len; ++i) {
-#else
for (ULONG i = 0; i < src_len; i++) {
-#endif
uint32_t cp;
if (!(in[i] & 0x80))
@@ -816,14 +853,8 @@ NTSTATUS utf16_to_utf8(char* dest, ULONG dest_max, ULONG* dest_len,
WCHAR* src,
uint8_t* out = (uint8_t*)dest;
ULONG in_len = src_len / sizeof(uint16_t);
ULONG needed = 0, left = dest_max;
-#ifdef __REACTOS__
- ULONG i = 0;
-
- for (i = 0; i < in_len; i++) {
-#else
for (ULONG i = 0; i < in_len; i++) {
-#endif
uint32_t cp = *in;
in++;
@@ -934,7 +965,7 @@ static NTSTATUS __stdcall drv_query_volume_information(_In_
PDEVICE_OBJECT Devic
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_query_volume_information(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
@@ -1091,9 +1122,9 @@ static NTSTATUS __stdcall drv_query_volume_information(_In_
PDEVICE_OBJECT Devic
orig_label_len = label_len;
- if (IrpSp->Parameters.QueryVolume.Length <
sizeof(FILE_FS_VOLUME_INFORMATION) - sizeof(WCHAR) + label_len) {
- if (IrpSp->Parameters.QueryVolume.Length >
sizeof(FILE_FS_VOLUME_INFORMATION) - sizeof(WCHAR))
- label_len = IrpSp->Parameters.QueryVolume.Length -
sizeof(FILE_FS_VOLUME_INFORMATION) + sizeof(WCHAR);
+ if (IrpSp->Parameters.QueryVolume.Length <
offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + label_len) {
+ if (IrpSp->Parameters.QueryVolume.Length >
offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel))
+ label_len = IrpSp->Parameters.QueryVolume.Length -
offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel);
else
label_len = 0;
@@ -1102,12 +1133,12 @@ static NTSTATUS __stdcall drv_query_volume_information(_In_
PDEVICE_OBJECT Devic
TRACE("label_len = %lu\n", label_len);
- ffvi.VolumeCreationTime.QuadPart = 0; // FIXME
+ RtlZeroMemory(&ffvi, offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel));
+
ffvi.VolumeSerialNumber = Vcb->superblock.uuid.uuid[12] << 24 |
Vcb->superblock.uuid.uuid[13] << 16 | Vcb->superblock.uuid.uuid[14] << 8
| Vcb->superblock.uuid.uuid[15];
ffvi.VolumeLabelLength = orig_label_len;
- ffvi.SupportsObjects = false;
- RtlCopyMemory(data, &ffvi, min(sizeof(FILE_FS_VOLUME_INFORMATION) -
sizeof(WCHAR), IrpSp->Parameters.QueryVolume.Length));
+ RtlCopyMemory(data, &ffvi, min(offsetof(FILE_FS_VOLUME_INFORMATION,
VolumeLabel), IrpSp->Parameters.QueryVolume.Length));
if (label_len > 0) {
ULONG bytecount;
@@ -1124,7 +1155,7 @@ static NTSTATUS __stdcall drv_query_volume_information(_In_
PDEVICE_OBJECT Devic
ExReleaseResourceLite(&Vcb->tree_lock);
- BytesCopied = sizeof(FILE_FS_VOLUME_INFORMATION) - sizeof(WCHAR) +
label_len;
+ BytesCopied = offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + label_len;
Status = overflow ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
break;
}
@@ -1384,7 +1415,7 @@ static NTSTATUS __stdcall drv_set_volume_information(_In_
PDEVICE_OBJECT DeviceO
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_set_volume_information(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
@@ -1779,12 +1810,8 @@ void reap_fcbs(device_extension* Vcb) {
}
void free_fileref(_Inout_ file_ref* fr) {
- LONG rc;
-
- rc = InterlockedDecrement(&fr->refcount);
-#ifdef __REACTOS__
- (void)rc;
-#endif
+#if defined(_DEBUG) || defined(DEBUG_FCB_REFCOUNTS)
+ LONG rc = InterlockedDecrement(&fr->refcount);
#ifdef DEBUG_FCB_REFCOUNTS
ERR("fileref %p: refcount now %i\n", fr, rc);
@@ -1796,6 +1823,9 @@ void free_fileref(_Inout_ file_ref* fr) {
int3;
}
#endif
+#else
+ InterlockedDecrement(&fr->refcount);
+#endif
}
void reap_fileref(device_extension* Vcb, file_ref* fr) {
@@ -2383,7 +2413,8 @@ static NTSTATUS __stdcall drv_cleanup(_In_ PDEVICE_OBJECT
DeviceObject, _In_ PIR
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_cleanup(DeviceObject, Irp);
+ Irp->IoStatus.Information = 0;
+ Status = STATUS_SUCCESS;
goto exit;
} else if (DeviceObject == master_devobj) {
TRACE("closing file system\n");
@@ -5215,7 +5246,7 @@ static NTSTATUS __stdcall drv_file_system_control(_In_
PDEVICE_OBJECT DeviceObje
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_file_system_control(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || (Vcb->type != VCB_TYPE_FS && Vcb->type !=
VCB_TYPE_CONTROL)) {
Status = STATUS_INVALID_PARAMETER;
@@ -5295,7 +5326,7 @@ static NTSTATUS __stdcall drv_lock_control(_In_ PDEVICE_OBJECT
DeviceObject, _In
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_lock_control(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -5460,7 +5491,7 @@ static NTSTATUS __stdcall drv_shutdown(_In_ PDEVICE_OBJECT
DeviceObject, _In_ PI
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_shutdown(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
}
@@ -5888,15 +5919,28 @@ static void init_serial(bool first_time) {
#if !defined(__REACTOS__) && (defined(_X86_) || defined(_AMD64_))
static void check_cpu() {
- bool have_sse42;
+ bool have_sse2 = false, have_sse42 = false, have_avx2 = false;
#ifndef _MSC_VER
{
- uint32_t eax, ebx, ecx, edx;
+ uint32_t eax, ebx, ecx, edx, xcr0;
__cpuid(1, eax, ebx, ecx, edx);
- have_sse42 = ecx & bit_SSE4_2;
- have_sse2 = edx & bit_SSE2;
+
+ if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
+ have_sse42 = ecx & bit_SSE4_2;
+ have_sse2 = edx & bit_SSE2;
+ }
+
+ if (__get_cpuid_count(7, 0, &eax, &ebx, &ecx, &edx))
+ have_avx2 = ebx & bit_AVX2;
+
+ if (have_avx2) { // check if supported by OS
+ __asm__("xgetbv" : "=a" (xcr0) : "c" (0) :
"edx" );
+
+ if ((xcr0 & 6) != 6)
+ have_avx2 = false;
+ }
}
#else
{
@@ -5905,6 +5949,16 @@ static void check_cpu() {
__cpuid(cpu_info, 1);
have_sse42 = cpu_info[2] & (1 << 20);
have_sse2 = cpu_info[3] & (1 << 26);
+
+ __cpuidex(cpu_info, 7, 0);
+ have_avx2 = cpu_info[1] & (1 << 5);
+
+ if (have_avx2) {
+ uint32_t xcr0 = (uint32_t)_xgetbv(0);
+
+ if ((xcr0 & 6) != 6)
+ have_avx2 = false;
+ }
}
#endif
@@ -5914,10 +5968,19 @@ static void check_cpu() {
} else
TRACE("SSE4.2 not supported\n");
- if (have_sse2)
+ if (have_sse2) {
TRACE("SSE2 is supported\n");
- else
+
+ if (!have_avx2)
+ do_xor = do_xor_sse2;
+ } else
TRACE("SSE2 is not supported\n");
+
+ if (have_avx2) {
+ TRACE("AVX2 is supported\n");
+ do_xor = do_xor_avx2;
+ } else
+ TRACE("AVX2 is not supported\n");
}
#endif
@@ -6047,6 +6110,8 @@ NTSTATUS __stdcall AddDevice(PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT Physica
TRACE("(%p, %p)\n", DriverObject, PhysicalDeviceObject);
+ UNUSED(DriverObject);
+
ExAcquireResourceSharedLite(&pdo_list_lock, true);
le = pdo_list.Flink;
diff --git a/drivers/filesystems/btrfs/btrfs.rc b/drivers/filesystems/btrfs/btrfs.rc
index 44920b9aeee..8a0116a2646 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,3,0
- PRODUCTVERSION 1,7,3,0
+ FILEVERSION 1,7,4,0
+ PRODUCTVERSION 1,7,4,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BLOCK "080904b0"
BEGIN
VALUE "FileDescription", "WinBtrfs"
- VALUE "FileVersion", "1.7.3"
+ VALUE "FileVersion", "1.7.4"
VALUE "InternalName", "btrfs"
VALUE "LegalCopyright", "Copyright (c) Mark Harmstone
2016-20"
VALUE "OriginalFilename", "btrfs.sys"
VALUE "ProductName", "WinBtrfs"
- VALUE "ProductVersion", "1.7.3"
+ VALUE "ProductVersion", "1.7.4"
END
END
BLOCK "VarFileInfo"
diff --git a/drivers/filesystems/btrfs/btrfs_drv.h
b/drivers/filesystems/btrfs/btrfs_drv.h
index 8b92af9ea83..17c58e4e5d5 100644
--- a/drivers/filesystems/btrfs/btrfs_drv.h
+++ b/drivers/filesystems/btrfs/btrfs_drv.h
@@ -66,10 +66,6 @@
#include "btrfs.h"
#include "btrfsioctl.h"
-#if !defined(__REACTOS__) && (defined(_X86_) || defined(_AMD64_))
-#include <emmintrin.h>
-#endif
-
#ifdef __REACTOS__
C_ASSERT(sizeof(bool) == 1);
#endif
@@ -134,14 +130,16 @@ C_ASSERT(sizeof(bool) == 1);
#define try __try
#define except __except
#define finally __finally
+#define leave __leave
#else
#define try if (1)
#define except(x) if (0 && (x))
#define finally if (1)
+#define leave
#endif
#ifndef __REACTOS__
-#ifdef __GNUC__
+#ifndef InterlockedIncrement64
#define InterlockedIncrement64(a) __sync_add_and_fetch(a, 1)
#endif
#endif // __REACTOS__
@@ -1102,6 +1100,12 @@ __inline static uint32_t get_extent_data_refcount(uint8_t type,
void* data) {
}
}
+// in xor-gas.S
+#if defined(_X86_) || defined(_AMD64_)
+void __stdcall do_xor_sse2(uint8_t* buf1, uint8_t* buf2, uint32_t len);
+void __stdcall do_xor_avx2(uint8_t* buf1, uint8_t* buf2, uint32_t len);
+#endif
+
// in btrfs.c
_Ret_maybenull_
device* find_device_from_uuid(_In_ device_extension* Vcb, _In_ BTRFS_UUID* uuid);
@@ -1131,6 +1135,10 @@ bool is_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix,
_In_ bool stre
void send_notification_fileref(_In_ file_ref* fileref, _In_ ULONG filter_match, _In_
ULONG action, _In_opt_ PUNICODE_STRING stream);
void queue_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_match, _In_ ULONG
action, _In_opt_ PUNICODE_STRING stream);
+typedef void (__stdcall *xor_func)(uint8_t* buf1, uint8_t* buf2, uint32_t len);
+
+extern xor_func do_xor;
+
#ifdef DEBUG_CHUNK_LOCKS
#define acquire_chunk_lock(c, Vcb) { ExAcquireResourceExclusiveLite(&c->lock,
true); InterlockedIncrement(&Vcb->chunk_locks_held); }
#define release_chunk_lock(c, Vcb) { InterlockedDecrement(&Vcb->chunk_locks_held);
ExReleaseResourceLite(&c->lock); }
@@ -1176,8 +1184,6 @@ bool check_superblock_checksum(superblock* sb);
#define funcname __func__
#endif
-extern bool have_sse2;
-
extern uint32_t mount_compress;
extern uint32_t mount_compress_force;
extern uint32_t mount_compress_type;
@@ -1229,8 +1235,8 @@ void _debug_message(_In_ const char* func, _In_ char* s, ...)
__attribute__((for
#else
-#define TRACE(s, ...)
-#define WARN(s, ...)
+#define TRACE(s, ...) do { } while(0)
+#define WARN(s, ...) do { } while(0)
#define FIXME(s, ...) DbgPrint("Btrfs FIXME : %s : " s, funcname,
##__VA_ARGS__)
#define ERR(s, ...) DbgPrint("Btrfs ERR : %s : " s, funcname, ##__VA_ARGS__)
@@ -1424,10 +1430,10 @@ void insert_dir_child_into_hash_lists(fcb* fcb, dir_child* dc);
void remove_dir_child_from_hash_lists(fcb* fcb, dir_child* dc);
// in reparse.c
-NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, void*
buffer, DWORD buflen, ULONG_PTR* retlen);
+NTSTATUS get_reparse_point(PFILE_OBJECT FileObject, void* buffer, DWORD buflen,
ULONG_PTR* retlen);
NTSTATUS set_reparse_point2(fcb* fcb, REPARSE_DATA_BUFFER* rdb, ULONG buflen, ccb* ccb,
file_ref* fileref, PIRP Irp, LIST_ENTRY* rollback);
-NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-NTSTATUS delete_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS set_reparse_point(PIRP Irp);
+NTSTATUS delete_reparse_point(PIRP Irp);
// in create.c
@@ -1605,21 +1611,7 @@ NTSTATUS vol_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS vol_close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS vol_read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS vol_write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_query_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_set_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_flush_buffers(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_query_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_set_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_cleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_file_system_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_lock_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_shutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
-NTSTATUS vol_set_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
void add_volume_device(superblock* sb, PUNICODE_STRING devpath, uint64_t length, ULONG
disk_num, ULONG part_num);
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath);
@@ -1734,49 +1726,6 @@ static __inline bool write_fcb_compressed(fcb* fcb) {
return false;
}
-static __inline void do_xor(uint8_t* buf1, uint8_t* buf2, uint32_t len) {
- uint32_t j;
-#ifndef __REACTOS__
-#if defined(_X86_) || defined(_AMD64_)
- __m128i x1, x2;
-
- if (have_sse2 && ((uintptr_t)buf1 & 0xf) == 0 && ((uintptr_t)buf2
& 0xf) == 0) {
- while (len >= 16) {
- x1 = _mm_load_si128((__m128i*)buf1);
- x2 = _mm_load_si128((__m128i*)buf2);
- x1 = _mm_xor_si128(x1, x2);
- _mm_store_si128((__m128i*)buf1, x1);
-
- buf1 += 16;
- buf2 += 16;
- len -= 16;
- }
- }
-#elif defined(_ARM_) || defined(_ARM64_)
- uint64x2_t x1, x2;
-
- if (((uintptr_t)buf1 & 0xf) == 0 && ((uintptr_t)buf2 & 0xf) == 0) {
- while (len >= 16) {
- x1 = vld1q_u64((const uint64_t*)buf1);
- x2 = vld1q_u64((const uint64_t*)buf2);
- x1 = veorq_u64(x1, x2);
- vst1q_u64((uint64_t*)buf1, x1);
-
- buf1 += 16;
- buf2 += 16;
- len -= 16;
- }
- }
-#endif
-#endif // __REACTOS__
-
- for (j = 0; j < len; j++) {
- *buf1 ^= *buf2;
- buf1++;
- buf2++;
- }
-}
-
#ifdef DEBUG_FCB_REFCOUNTS
#ifdef DEBUG_LONG_MESSAGES
#define increase_fileref_refcount(fileref) {\
diff --git a/drivers/filesystems/btrfs/btrfsioctl.h
b/drivers/filesystems/btrfs/btrfsioctl.h
index 0ba18cf837a..dc1cccd89fe 100644
--- a/drivers/filesystems/btrfs/btrfsioctl.h
+++ b/drivers/filesystems/btrfs/btrfsioctl.h
@@ -37,6 +37,7 @@
#define FSCTL_BTRFS_READ_SEND_BUFFER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x847,
METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define FSCTL_BTRFS_RESIZE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x848, METHOD_IN_DIRECT,
FILE_ANY_ACCESS)
#define IOCTL_BTRFS_UNLOAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x849, METHOD_NEITHER,
FILE_ANY_ACCESS)
+#define FSCTL_BTRFS_GET_CSUM_INFO CTL_CODE(FILE_DEVICE_UNKNOWN, 0x84a, METHOD_BUFFERED,
FILE_READ_ACCESS)
typedef struct {
uint64_t subvol;
@@ -279,3 +280,10 @@ typedef struct {
uint64_t device;
uint64_t size;
} btrfs_resize;
+
+typedef struct {
+ uint8_t csum_type;
+ uint8_t csum_length;
+ uint64_t num_sectors;
+ uint8_t data[1];
+} btrfs_csum_info;
diff --git a/drivers/filesystems/btrfs/compress.c b/drivers/filesystems/btrfs/compress.c
index 786bca33254..d5d229905b6 100644
--- a/drivers/filesystems/btrfs/compress.c
+++ b/drivers/filesystems/btrfs/compress.c
@@ -703,13 +703,18 @@ NTSTATUS zstd_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t*
outbuf, uint32
output.size = outlen;
output.pos = 0;
- read = ZSTD_decompressStream(stream, &output, &input);
+ do {
+ read = ZSTD_decompressStream(stream, &output, &input);
- if (ZSTD_isError(read)) {
- ERR("ZSTD_decompressStream failed: %s\n", ZSTD_getErrorName(read));
- Status = STATUS_INTERNAL_ERROR;
- goto end;
- }
+ if (ZSTD_isError(read)) {
+ ERR("ZSTD_decompressStream failed: %s\n",
ZSTD_getErrorName(read));
+ Status = STATUS_INTERNAL_ERROR;
+ goto end;
+ }
+
+ if (output.pos == output.size)
+ break;
+ } while (read != 0);
Status = STATUS_SUCCESS;
diff --git a/drivers/filesystems/btrfs/crc32c-amd64.S
b/drivers/filesystems/btrfs/crc32c-amd64.S
deleted file mode 100644
index dbe035487c7..00000000000
--- a/drivers/filesystems/btrfs/crc32c-amd64.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Copyright (c) Mark Harmstone 2020
- *
- * This file is part of WinBtrfs.
- *
- * WinBtrfs is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public Licence as published by
- * the Free Software Foundation, either version 3 of the Licence, or
- * (at your option) any later version.
- *
- * WinBtrfs is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public Licence for more details.
- *
- * You should have received a copy of the GNU Lesser General Public Licence
- * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
-
-#include <asm.inc>
-
-EXTERN crctable:QWORD
-
-.code64
-
-
-/* uint32_t __stdcall calc_crc32c_sw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
-
-PUBLIC calc_crc32c_sw
-calc_crc32c_sw:
-
-/* rax = crc / seed
- * rdx = buf
- * r8 = len
- * rcx = tmp
- * r10 = tmp2 */
-
-mov rax, rcx
-
-crcloop:
-test r8, r8
-jz crcend
-
-mov rcx, rax
-shr rcx, 8
-mov r10b, byte ptr [rdx]
-xor al, r10b
-and rax, 255
-shl rax, 2
-lea r10, [rip+crctable]
-mov eax, dword ptr [r10 + rax]
-xor rax, rcx
-
-inc rdx
-dec r8
-
-jmp crcloop
-
-crcend:
-ret
-
-/****************************************************/
-
-/* uint32_t __stdcall calc_crc32c_hw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
-
-PUBLIC calc_crc32c_hw
-calc_crc32c_hw:
-
-/* rax = crc / seed
- * rdx = buf
- * r8 = len */
-
-mov rax, rcx
-
-crchw_loop:
-cmp r8, 8
-jl crchw_stragglers
-
-crc32 rax, qword ptr [rdx]
-
-add rdx, 8
-sub r8, 8
-jmp crchw_loop
-
-crchw_stragglers:
-cmp r8, 4
-jl crchw_stragglers2
-
-crc32 eax, dword ptr [rdx]
-
-add rdx, 4
-sub r8, 4
-
-crchw_stragglers2:
-cmp r8, 2
-jl crchw_stragglers3
-
-crc32 eax, word ptr [rdx]
-
-add rdx, 2
-sub r8, 2
-
-crchw_stragglers3:
-test r8, r8
-jz crchw_end
-
-crc32 eax, byte ptr [rdx]
-inc rdx
-dec r8
-jmp crchw_stragglers3
-
-crchw_end:
-ret
-
-END
diff --git a/drivers/filesystems/btrfs/crc32c-x86.S b/drivers/filesystems/btrfs/crc32c.S
similarity index 62%
rename from drivers/filesystems/btrfs/crc32c-x86.S
rename to drivers/filesystems/btrfs/crc32c.S
index 991eec8dc57..516a911d18c 100644
--- a/drivers/filesystems/btrfs/crc32c-x86.S
+++ b/drivers/filesystems/btrfs/crc32c.S
@@ -17,8 +17,105 @@
#include <asm.inc>
-EXTERN _crctable:DWORD
+#ifdef __x86_64__
+
+EXTERN crctable:QWORD
+
+.code64
+
+/* uint32_t __stdcall calc_crc32c_sw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
+
+PUBLIC calc_crc32c_sw
+calc_crc32c_sw:
+
+/* rax = crc / seed
+ * rdx = buf
+ * r8 = len
+ * rcx = tmp
+ * r10 = tmp2 */
+
+mov rax, rcx
+
+crcloop:
+test r8, r8
+jz crcend
+
+mov rcx, rax
+shr rcx, 8
+mov r10b, byte ptr [rdx]
+xor al, r10b
+and rax, 255
+shl rax, 2
+lea r10, [rip+crctable]
+mov eax, dword ptr [r10 + rax]
+xor rax, rcx
+
+inc rdx
+dec r8
+
+jmp crcloop
+
+crcend:
+ret
+
+/****************************************************/
+
+/* uint32_t __stdcall calc_crc32c_hw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
+
+PUBLIC calc_crc32c_hw
+
+calc_crc32c_hw:
+
+/* rax = crc / seed
+ * rdx = buf
+ * r8 = len */
+mov rax, rcx
+
+crchw_loop:
+cmp r8, 8
+jl crchw_stragglers
+
+crc32 rax, qword ptr [rdx]
+
+add rdx, 8
+sub r8, 8
+jmp crchw_loop
+
+crchw_stragglers:
+cmp r8, 4
+jl crchw_stragglers2
+
+crc32 eax, dword ptr [rdx]
+
+add rdx, 4
+sub r8, 4
+
+crchw_stragglers2:
+cmp r8, 2
+jl crchw_stragglers3
+
+crc32 eax, word ptr [rdx]
+
+add rdx, 2
+sub r8, 2
+
+crchw_stragglers3:
+test r8, r8
+jz crchw_end
+
+crc32 eax, byte ptr [rdx]
+inc rdx
+dec r8
+jmp crchw_stragglers3
+
+crchw_end:
+ret
+
+END
+#elif defined(_X86_)
+
+EXTERN _crctable:DWORD
.code
/* uint32_t __stdcall calc_crc32c_sw(uint32_t seed, uint8_t* msg, uint32_t msglen); */
@@ -120,3 +217,4 @@ pop ebp
ret 12
END
+#endif
diff --git a/drivers/filesystems/btrfs/crc32c.h b/drivers/filesystems/btrfs/crc32c.h
index 73bd9697af3..c012642159f 100644
--- a/drivers/filesystems/btrfs/crc32c.h
+++ b/drivers/filesystems/btrfs/crc32c.h
@@ -2,6 +2,10 @@
#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if defined(_X86_) || defined(_AMD64_)
uint32_t __stdcall calc_crc32c_hw(uint32_t seed, uint8_t* msg, uint32_t msglen);
#endif
@@ -11,3 +15,7 @@ uint32_t __stdcall calc_crc32c_sw(uint32_t seed, uint8_t* msg, uint32_t
msglen);
typedef uint32_t (__stdcall *crc_func)(uint32_t seed, uint8_t* msg, uint32_t msglen);
extern crc_func calc_crc32c;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/drivers/filesystems/btrfs/create.c b/drivers/filesystems/btrfs/create.c
index 0dee14dc7fd..699228e95a1 100644
--- a/drivers/filesystems/btrfs/create.c
+++ b/drivers/filesystems/btrfs/create.c
@@ -387,7 +387,7 @@ static NTSTATUS split_path(device_extension* Vcb, PUNICODE_STRING
path, LIST_ENT
if (nb->us.Buffer[i] == ':') {
name_bit* nb2;
- if (nb->us.Buffer[i+1] == 0) {
+ if (i + 1 == nb->us.Length / sizeof(WCHAR)) {
WARN("zero-length stream name\n");
Status = STATUS_OBJECT_NAME_INVALID;
goto cleanup;
@@ -709,7 +709,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock)
_Requires_exclusive_lo
bool atts_set = false, sd_set = false, no_data;
LIST_ENTRY* lastle = NULL;
EXTENT_DATA* ed = NULL;
- uint64_t fcbs_version;
+ uint64_t fcbs_version = 0;
uint32_t hash;
hash = calc_crc32c(0xffffffff, (uint8_t*)&inode, sizeof(uint64_t));
@@ -1687,7 +1687,7 @@ NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock)
_Requires_exclusiv
UNICODE_STRING fnus2;
file_ref *dir, *sf, *sf2;
LIST_ENTRY parts;
- bool has_stream;
+ bool has_stream = false;
NTSTATUS Status;
LIST_ENTRY* le;
@@ -4658,7 +4658,7 @@ loaded:
if (!NT_SUCCESS(Status))
goto exit;
} else {
- file_ref* existing_file;
+ file_ref* existing_file = NULL;
Status = file_create(Irp, Vcb, FileObject, related, loaded_related, &fn,
RequestedDisposition, options, &existing_file, rollback);
diff --git a/drivers/filesystems/btrfs/dirctrl.c b/drivers/filesystems/btrfs/dirctrl.c
index 2d0a5fdb351..b13dd2a22ff 100644
--- a/drivers/filesystems/btrfs/dirctrl.c
+++ b/drivers/filesystems/btrfs/dirctrl.c
@@ -1174,7 +1174,7 @@ NTSTATUS __stdcall drv_directory_control(IN PDEVICE_OBJECT
DeviceObject, IN PIRP
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_directory_control(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
diff --git a/drivers/filesystems/btrfs/fastio.c b/drivers/filesystems/btrfs/fastio.c
index 465e191dfa6..e073f3f9b1d 100644
--- a/drivers/filesystems/btrfs/fastio.c
+++ b/drivers/filesystems/btrfs/fastio.c
@@ -25,6 +25,8 @@ static BOOLEAN __stdcall fast_query_basic_info(PFILE_OBJECT FileObject,
BOOLEAN
fcb* fcb;
ccb* ccb;
+ UNUSED(DeviceObject);
+
FsRtlEnterFileSystem();
TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fbi, IoStatus,
DeviceObject);
@@ -99,6 +101,8 @@ static BOOLEAN __stdcall fast_query_standard_info(PFILE_OBJECT
FileObject, BOOLE
bool ads;
ULONG adssize;
+ UNUSED(DeviceObject);
+
FsRtlEnterFileSystem();
TRACE("(%p, %u, %p, %p, %p)\n", FileObject, wait, fsi, IoStatus,
DeviceObject);
@@ -198,6 +202,10 @@ static BOOLEAN __stdcall fast_io_query_network_open_info(PFILE_OBJECT
FileObject
ccb* ccb;
file_ref* fileref;
+ UNUSED(Wait);
+ UNUSED(IoStatus); // FIXME - really? What about IoStatus->Information?
+ UNUSED(DeviceObject);
+
FsRtlEnterFileSystem();
TRACE("(%p, %u, %p, %p, %p)\n", FileObject, Wait, fnoi, IoStatus,
DeviceObject);
@@ -372,6 +380,8 @@ static BOOLEAN __stdcall fast_io_lock(PFILE_OBJECT FileObject,
PLARGE_INTEGER Fi
BOOLEAN ret;
fcb* fcb = FileObject->FsContext;
+ UNUSED(DeviceObject);
+
TRACE("(%p, %I64x, %I64x, %p, %lx, %u, %u, %p, %p)\n", FileObject,
FileOffset ? FileOffset->QuadPart : 0, Length ? Length->QuadPart : 0,
ProcessId, Key, FailImmediately, ExclusiveLock, IoStatus, DeviceObject);
@@ -402,6 +412,8 @@ static BOOLEAN __stdcall fast_io_unlock_single(PFILE_OBJECT
FileObject, PLARGE_I
ULONG Key, PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject) {
fcb* fcb = FileObject->FsContext;
+ UNUSED(DeviceObject);
+
TRACE("(%p, %I64x, %I64x, %p, %lx, %p, %p)\n", FileObject, FileOffset ?
FileOffset->QuadPart : 0, Length ? Length->QuadPart : 0,
ProcessId, Key, IoStatus, DeviceObject);
@@ -428,6 +440,8 @@ _Function_class_(FAST_IO_UNLOCK_ALL)
static BOOLEAN __stdcall fast_io_unlock_all(PFILE_OBJECT FileObject, PEPROCESS ProcessId,
PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) {
fcb* fcb = FileObject->FsContext;
+ UNUSED(DeviceObject);
+
TRACE("(%p, %p, %p, %p)\n", FileObject, ProcessId, IoStatus,
DeviceObject);
IoStatus->Information = 0;
@@ -458,6 +472,8 @@ static BOOLEAN __stdcall fast_io_unlock_all_by_key(PFILE_OBJECT
FileObject, PVOI
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject) {
fcb* fcb = FileObject->FsContext;
+ UNUSED(DeviceObject);
+
TRACE("(%p, %p, %lx, %p, %p)\n", FileObject, ProcessId, Key, IoStatus,
DeviceObject);
IoStatus->Information = 0;
diff --git a/drivers/filesystems/btrfs/fileinfo.c b/drivers/filesystems/btrfs/fileinfo.c
index 81c0f06816a..85006b55fc5 100644
--- a/drivers/filesystems/btrfs/fileinfo.c
+++ b/drivers/filesystems/btrfs/fileinfo.c
@@ -3826,7 +3826,7 @@ NTSTATUS __stdcall drv_set_information(IN PDEVICE_OBJECT
DeviceObject, IN PIRP I
Irp->IoStatus.Information = 0;
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_set_information(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
@@ -5345,7 +5345,7 @@ NTSTATUS __stdcall drv_query_information(IN PDEVICE_OBJECT
DeviceObject, IN PIRP
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_query_information(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
@@ -5399,7 +5399,7 @@ NTSTATUS __stdcall drv_query_ea(IN PDEVICE_OBJECT DeviceObject, IN
PIRP Irp) {
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_query_ea(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
@@ -5635,7 +5635,7 @@ NTSTATUS __stdcall drv_set_ea(IN PDEVICE_OBJECT DeviceObject, IN
PIRP Irp) {
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_set_ea(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
diff --git a/drivers/filesystems/btrfs/flushthread.c
b/drivers/filesystems/btrfs/flushthread.c
index 6495859ab63..e6354b36822 100644
--- a/drivers/filesystems/btrfs/flushthread.c
+++ b/drivers/filesystems/btrfs/flushthread.c
@@ -5816,6 +5816,8 @@ static NTSTATUS partial_stripe_read(device_extension* Vcb, chunk* c,
partial_str
}
i = (parity + 1) % c->chunk_item->num_stripes;
+ logstripe = (c->chunk_item->num_stripes +
c->chunk_item->num_stripes - 1 - parity + stripe) %
c->chunk_item->num_stripes;
+
for (k = 0; k < c->chunk_item->num_stripes; k++) {
if (i != stripe) {
if (c->devices[i]->devobj) {
@@ -5835,8 +5837,7 @@ static NTSTATUS partial_stripe_read(device_extension* Vcb, chunk* c,
partial_str
ExFreePool(scratch);
return STATUS_UNEXPECTED_IO_ERROR;
}
- } else
- logstripe = k;
+ }
i = (i + 1) % c->chunk_item->num_stripes;
}
diff --git a/drivers/filesystems/btrfs/fsctl.c b/drivers/filesystems/btrfs/fsctl.c
index 70a954d04aa..f1bb68c22a0 100644
--- a/drivers/filesystems/btrfs/fsctl.c
+++ b/drivers/filesystems/btrfs/fsctl.c
@@ -17,6 +17,7 @@
#include "btrfs_drv.h"
#include "btrfsioctl.h"
+#include "crc32c.h"
#include <ntddstor.h>
#include <ntdddisk.h>
#ifndef __REACTOS__
@@ -2179,10 +2180,10 @@ end:
return Status;
}
-static NTSTATUS get_object_id(device_extension* Vcb, PFILE_OBJECT FileObject,
FILE_OBJECTID_BUFFER* buf, ULONG buflen, ULONG_PTR* retlen) {
+static NTSTATUS get_object_id(PFILE_OBJECT FileObject, FILE_OBJECTID_BUFFER* buf, ULONG
buflen, ULONG_PTR* retlen) {
fcb* fcb;
- TRACE("(%p, %p, %p, %lx, %p)\n", Vcb, FileObject, buf, buflen, retlen);
+ TRACE("(%p, %p, %lx, %p)\n", FileObject, buf, buflen, retlen);
if (!FileObject) {
ERR("FileObject was NULL\n");
@@ -4965,6 +4966,343 @@ static NTSTATUS fsctl_oplock(device_extension* Vcb, PIRP* Pirp) {
return Status;
}
+static NTSTATUS get_retrieval_pointers(device_extension* Vcb, PFILE_OBJECT FileObject,
STARTING_VCN_INPUT_BUFFER* in,
+ ULONG inlen, RETRIEVAL_POINTERS_BUFFER* out, ULONG
outlen, ULONG_PTR* retlen) {
+ NTSTATUS Status;
+ fcb* fcb;
+
+ TRACE("get_retrieval_pointers(%p, %p, %p, %lx, %p, %lx, %p)\n", Vcb,
FileObject, in, inlen,
+ out, outlen,
retlen);
+
+ if (!FileObject)
+ return STATUS_INVALID_PARAMETER;
+
+ fcb = FileObject->FsContext;
+
+ if (!fcb)
+ return STATUS_INVALID_PARAMETER;
+
+ if (inlen < sizeof(STARTING_VCN_INPUT_BUFFER) || in->StartingVcn.QuadPart <
0)
+ return STATUS_INVALID_PARAMETER;
+
+ if (!out)
+ return STATUS_INVALID_PARAMETER;
+
+ if (outlen < offsetof(RETRIEVAL_POINTERS_BUFFER, Extents[0]))
+ return STATUS_BUFFER_TOO_SMALL;
+
+ ExAcquireResourceSharedLite(fcb->Header.Resource, true);
+
+ try {
+ LIST_ENTRY* le = fcb->extents.Flink;
+ extent* first_ext = NULL;
+ unsigned int num_extents = 0, first_extent_num = 0, i;
+ uint64_t num_sectors, last_off = 0;
+
+ num_sectors = (fcb->inode_item.st_size + Vcb->superblock.sector_size - 1)
>> Vcb->sector_shift;
+
+ while (le != &fcb->extents) {
+ extent* ext = CONTAINING_RECORD(le, extent, list_entry);
+
+ if (ext->ignore || ext->extent_data.type == EXTENT_TYPE_INLINE) {
+ le = le->Flink;
+ continue;
+ }
+
+ if (ext->offset > last_off)
+ num_extents++;
+
+ if ((ext->offset >> Vcb->sector_shift) <=
(uint64_t)in->StartingVcn.QuadPart &&
+ (ext->offset + ext->extent_data.decoded_size) >>
Vcb->sector_shift > (uint64_t)in->StartingVcn.QuadPart) {
+ first_ext = ext;
+ first_extent_num = num_extents;
+ }
+
+ num_extents++;
+
+ last_off = ext->offset + ext->extent_data.decoded_size;
+
+ le = le->Flink;
+ }
+
+ if (num_sectors > last_off >> Vcb->sector_shift)
+ num_extents++;
+
+ if (!first_ext) {
+ Status = STATUS_END_OF_FILE;
+ leave;
+ }
+
+ out->ExtentCount = num_extents - first_extent_num;
+ out->StartingVcn.QuadPart = first_ext->offset >>
Vcb->sector_shift;
+ outlen -= offsetof(RETRIEVAL_POINTERS_BUFFER, Extents[0]);
+ *retlen = offsetof(RETRIEVAL_POINTERS_BUFFER, Extents[0]);
+
+ le = &first_ext->list_entry;
+ i = 0;
+ last_off = 0;
+
+ while (le != &fcb->extents) {
+ extent* ext = CONTAINING_RECORD(le, extent, list_entry);
+
+ if (ext->ignore || ext->extent_data.type == EXTENT_TYPE_INLINE) {
+ le = le->Flink;
+ continue;
+ }
+
+ if (ext->offset > last_off) {
+ if (outlen < sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER)) {
+ Status = STATUS_BUFFER_OVERFLOW;
+ leave;
+ }
+
+ out->Extents[i].NextVcn.QuadPart = ext->offset >>
Vcb->sector_shift;
+ out->Extents[i].Lcn.QuadPart = -1;
+
+ outlen -= sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER);
+ *retlen += sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER);
+ i++;
+ }
+
+ if (outlen < sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER)) {
+ Status = STATUS_BUFFER_OVERFLOW;
+ leave;
+ }
+
+ out->Extents[i].NextVcn.QuadPart = (ext->offset +
ext->extent_data.decoded_size) >> Vcb->sector_shift;
+
+ if (ext->extent_data.compression == BTRFS_COMPRESSION_NONE) {
+ EXTENT_DATA2* ed2 = (EXTENT_DATA2*)ext->extent_data.data;
+
+ out->Extents[i].Lcn.QuadPart = (ed2->address + ed2->offset)
>> Vcb->sector_shift;
+ } else
+ out->Extents[i].Lcn.QuadPart = -1;
+
+ outlen -= sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER);
+ *retlen += sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER);
+ i++;
+
+ le = le->Flink;
+ }
+
+ if (num_sectors << Vcb->sector_shift > last_off) {
+ if (outlen < sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER)) {
+ Status = STATUS_BUFFER_OVERFLOW;
+ leave;
+ }
+
+ out->Extents[i].NextVcn.QuadPart = num_sectors;
+ out->Extents[i].Lcn.QuadPart = -1;
+
+ outlen -= sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER);
+ *retlen += sizeof(LARGE_INTEGER) + sizeof(LARGE_INTEGER);
+ }
+
+ Status = STATUS_SUCCESS;
+ } finally {
+ ExReleaseResourceLite(fcb->Header.Resource);
+ }
+
+ return Status;
+}
+
+static NTSTATUS add_csum_sparse_extents(device_extension* Vcb, uint64_t sparse_extents,
uint8_t** ptr, bool found, void* hash_ptr) {
+ if (!found) {
+ uint8_t* sector = ExAllocatePoolWithTag(PagedPool,
Vcb->superblock.sector_size, ALLOC_TAG);
+
+ if (!sector) {
+ ERR("out of memory\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ memset(sector, 0, Vcb->superblock.sector_size);
+
+ get_sector_csum(Vcb, sector, hash_ptr);
+
+ ExFreePool(sector);
+ }
+
+ switch (Vcb->superblock.csum_type) {
+ case CSUM_TYPE_CRC32C: {
+ uint32_t* csum = (uint32_t*)*ptr;
+ uint32_t sparse_hash = *(uint32_t*)hash_ptr;
+
+ for (uint64_t i = 0; i < sparse_extents; i++) {
+ csum[i] = sparse_hash;
+ }
+
+ break;
+ }
+
+ case CSUM_TYPE_XXHASH: {
+ uint64_t* csum = (uint64_t*)*ptr;
+ uint64_t sparse_hash = *(uint64_t*)hash_ptr;
+
+ for (uint64_t i = 0; i < sparse_extents; i++) {
+ csum[i] = sparse_hash;
+ }
+
+ break;
+ }
+
+ case CSUM_TYPE_SHA256:
+ case CSUM_TYPE_BLAKE2: {
+ uint8_t* csum = (uint8_t*)*ptr;
+
+ for (uint64_t i = 0; i < sparse_extents; i++) {
+ memcpy(csum, hash_ptr, 32);
+ csum += 32;
+ }
+
+ break;
+ }
+
+ default:
+ ERR("unrecognized hash type %x\n", Vcb->superblock.csum_type);
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ *ptr += sparse_extents * Vcb->csum_size;
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS get_csum_info(device_extension* Vcb, PFILE_OBJECT FileObject,
btrfs_csum_info* buf, ULONG buflen,
+ ULONG_PTR* retlen, KPROCESSOR_MODE processor_mode) {
+ NTSTATUS Status;
+ fcb* fcb;
+ ccb* ccb;
+
+ TRACE("get_csum_info(%p, %p, %p, %lx, %p, %x)\n", Vcb, FileObject, buf,
buflen, retlen, processor_mode);
+
+ if (!FileObject)
+ return STATUS_INVALID_PARAMETER;
+
+ fcb = FileObject->FsContext;
+ ccb = FileObject->FsContext2;
+
+ if (!fcb || !ccb)
+ return STATUS_INVALID_PARAMETER;
+
+ if (!buf)
+ return STATUS_INVALID_PARAMETER;
+
+ if (buflen < offsetof(btrfs_csum_info, data[0]))
+ return STATUS_BUFFER_TOO_SMALL;
+
+
+ if (processor_mode == UserMode && !(ccb->access & (FILE_READ_DATA |
FILE_WRITE_DATA))) {
+ WARN("insufficient privileges\n");
+ return STATUS_ACCESS_DENIED;
+ }
+
+ ExAcquireResourceSharedLite(fcb->Header.Resource, true);
+
+ try {
+ LIST_ENTRY* le;
+ uint8_t* ptr;
+ uint64_t last_off;
+ uint8_t sparse_hash[MAX_HASH_SIZE];
+ bool sparse_hash_found = false;
+
+ if (fcb->ads) {
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ leave;
+ }
+
+ if (fcb->type == BTRFS_TYPE_DIRECTORY) {
+ Status = STATUS_FILE_IS_A_DIRECTORY;
+ leave;
+ }
+
+ if (fcb->inode_item.flags & BTRFS_INODE_NODATASUM) {
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ leave;
+ }
+
+ buf->csum_type = Vcb->superblock.csum_type;
+ buf->csum_length = Vcb->csum_size;
+
+ le = fcb->extents.Flink;
+ while (le != &fcb->extents) {
+ extent* ext = CONTAINING_RECORD(le, extent, list_entry);
+
+ if (ext->ignore) {
+ le = le->Flink;
+ continue;
+ }
+
+ if (ext->extent_data.type == EXTENT_TYPE_INLINE) {
+ buf->num_sectors = 0;
+ *retlen = offsetof(btrfs_csum_info, data[0]);
+ Status = STATUS_SUCCESS;
+ leave;
+ }
+
+ le = le->Flink;
+ }
+
+ buf->num_sectors = (fcb->inode_item.st_size +
Vcb->superblock.sector_size - 1) >> Vcb->sector_shift;
+
+ if (buflen < offsetof(btrfs_csum_info, data[0]) + (buf->csum_length *
buf->num_sectors)) {
+ Status = STATUS_BUFFER_OVERFLOW;
+ *retlen = offsetof(btrfs_csum_info, data[0]);
+ leave;
+ }
+
+ ptr = buf->data;
+ last_off = 0;
+
+ le = fcb->extents.Flink;
+ while (le != &fcb->extents) {
+ extent* ext = CONTAINING_RECORD(le, extent, list_entry);
+ EXTENT_DATA2* ed2;
+
+ if (ext->ignore || ext->extent_data.type == EXTENT_TYPE_INLINE) {
+ le = le->Flink;
+ continue;
+ }
+
+ if (ext->offset > last_off) {
+ uint64_t sparse_extents = (ext->offset - last_off) >>
Vcb->sector_shift;
+
+ add_csum_sparse_extents(Vcb, sparse_extents, &ptr, sparse_hash_found,
sparse_hash);
+ sparse_hash_found = true;
+ }
+
+ ed2 = (EXTENT_DATA2*)ext->extent_data.data;
+
+ if (ext->extent_data.compression != BTRFS_COMPRESSION_NONE)
+ memset(ptr, 0, (ed2->num_bytes >> Vcb->sector_shift) *
Vcb->csum_size); // dummy value for compressed extents
+ else {
+ if (ext->csum)
+ memcpy(ptr, ext->csum, (ed2->num_bytes >>
Vcb->sector_shift) * Vcb->csum_size);
+ else
+ memset(ptr, 0, (ed2->num_bytes >> Vcb->sector_shift) *
Vcb->csum_size);
+
+ ptr += (ed2->num_bytes >> Vcb->sector_shift) *
Vcb->csum_size;
+ }
+
+ last_off = ext->offset + ed2->num_bytes;
+
+ le = le->Flink;
+ }
+
+ if (buf->num_sectors > last_off >> Vcb->sector_shift) {
+ uint64_t sparse_extents = buf->num_sectors - (last_off >>
Vcb->sector_shift);
+
+ add_csum_sparse_extents(Vcb, sparse_extents, &ptr, sparse_hash_found,
sparse_hash);
+ }
+
+ *retlen = offsetof(btrfs_csum_info, data[0]) + (buf->csum_length *
buf->num_sectors);
+ Status = STATUS_SUCCESS;
+ } finally {
+ ExReleaseResourceLite(fcb->Header.Resource);
+ }
+
+ return Status;
+}
+
NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp, uint32_t type) {
PIRP Irp = *Pirp;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
@@ -5065,8 +5403,11 @@ NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp,
uint32_t type) {
break;
case FSCTL_GET_RETRIEVAL_POINTERS:
- WARN("STUB: FSCTL_GET_RETRIEVAL_POINTERS\n");
- Status = STATUS_INVALID_DEVICE_REQUEST;
+ Status = get_retrieval_pointers(DeviceObject->DeviceExtension,
IrpSp->FileObject,
+
IrpSp->Parameters.FileSystemControl.Type3InputBuffer,
+
IrpSp->Parameters.FileSystemControl.InputBufferLength,
+ Irp->UserBuffer,
IrpSp->Parameters.FileSystemControl.OutputBufferLength,
+ &Irp->IoStatus.Information);
break;
case FSCTL_MOVE_FILE:
@@ -5093,8 +5434,8 @@ NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp,
uint32_t type) {
break;
case FSCTL_GET_OBJECT_ID:
- Status = get_object_id(DeviceObject->DeviceExtension,
IrpSp->FileObject, Irp->UserBuffer,
-
IrpSp->Parameters.FileSystemControl.OutputBufferLength,
&Irp->IoStatus.Information);
+ Status = get_object_id(IrpSp->FileObject, Irp->UserBuffer,
IrpSp->Parameters.FileSystemControl.OutputBufferLength,
+ &Irp->IoStatus.Information);
break;
case FSCTL_DELETE_OBJECT_ID:
@@ -5103,16 +5444,16 @@ NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp,
uint32_t type) {
break;
case FSCTL_SET_REPARSE_POINT:
- Status = set_reparse_point(DeviceObject, Irp);
+ Status = set_reparse_point(Irp);
break;
case FSCTL_GET_REPARSE_POINT:
- Status = get_reparse_point(DeviceObject, IrpSp->FileObject,
Irp->AssociatedIrp.SystemBuffer,
+ Status = get_reparse_point(IrpSp->FileObject,
Irp->AssociatedIrp.SystemBuffer,
IrpSp->Parameters.FileSystemControl.OutputBufferLength,
&Irp->IoStatus.Information);
break;
case FSCTL_DELETE_REPARSE_POINT:
- Status = delete_reparse_point(DeviceObject, Irp);
+ Status = delete_reparse_point(Irp);
break;
case FSCTL_ENUM_USN_DATA:
@@ -5136,8 +5477,8 @@ NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp,
uint32_t type) {
break;
case FSCTL_CREATE_OR_GET_OBJECT_ID:
- Status = get_object_id(DeviceObject->DeviceExtension,
IrpSp->FileObject, Irp->UserBuffer,
-
IrpSp->Parameters.FileSystemControl.OutputBufferLength,
&Irp->IoStatus.Information);
+ Status = get_object_id(IrpSp->FileObject, Irp->UserBuffer,
IrpSp->Parameters.FileSystemControl.OutputBufferLength,
+ &Irp->IoStatus.Information);
break;
case FSCTL_SET_SPARSE:
@@ -5558,6 +5899,12 @@ NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp,
uint32_t type) {
IrpSp->Parameters.FileSystemControl.InputBufferLength, Irp);
break;
+ case FSCTL_BTRFS_GET_CSUM_INFO:
+ Status = get_csum_info(DeviceObject->DeviceExtension,
IrpSp->FileObject, Irp->AssociatedIrp.SystemBuffer,
+
IrpSp->Parameters.FileSystemControl.OutputBufferLength,
&Irp->IoStatus.Information,
+ Irp->RequestorMode);
+ break;
+
default:
WARN("unknown control code %lx (DeviceType = %lx, Access = %lx, Function
= %lx, Method = %lx)\n",
IrpSp->Parameters.FileSystemControl.FsControlCode,
(IrpSp->Parameters.FileSystemControl.FsControlCode & 0xff0000) >> 16,
diff --git a/drivers/filesystems/btrfs/pnp.c b/drivers/filesystems/btrfs/pnp.c
index 96401908fba..02314ba7a1f 100644
--- a/drivers/filesystems/btrfs/pnp.c
+++ b/drivers/filesystems/btrfs/pnp.c
@@ -79,6 +79,8 @@ NTSTATUS pnp_surprise_removal(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
TRACE("(%p, %p)\n", DeviceObject, Irp);
+ UNUSED(Irp);
+
if (DeviceObject->Vpb->Flags & VPB_MOUNTED) {
ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
diff --git a/drivers/filesystems/btrfs/read.c b/drivers/filesystems/btrfs/read.c
index 091a0b0b7fe..824a1c17b29 100644
--- a/drivers/filesystems/btrfs/read.c
+++ b/drivers/filesystems/btrfs/read.c
@@ -466,7 +466,7 @@ static NTSTATUS read_data_raid0(device_extension* Vcb, uint8_t* buf,
uint64_t ad
static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t addr,
uint32_t length, read_data_context* context,
CHUNK_ITEM* ci, device** devices, uint64_t generation,
uint64_t offset) {
- uint16_t stripe;
+ uint16_t stripe = 0;
NTSTATUS Status;
bool checksum_error = false;
CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&ci[1];
@@ -653,7 +653,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf,
uint64_t ad
NTSTATUS Status;
bool checksum_error = false;
CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&ci[1];
- uint16_t j, stripe;
+ uint16_t j, stripe = 0;
bool no_success = true;
for (j = 0; j < ci->num_stripes; j++) {
@@ -950,7 +950,7 @@ void raid6_recover2(uint8_t* sectors, uint16_t num_stripes, ULONG
sector_size, u
if (missing != 0)
galois_divpower(out, (uint8_t)missing, sector_size);
} else { // reconstruct from p and q
- uint16_t x, y, stripe;
+ uint16_t x = missing1, y = missing2, stripe;
uint8_t gyx, gx, denom, a, b, *p, *q, *pxy, *qxy;
uint32_t j;
@@ -962,11 +962,6 @@ void raid6_recover2(uint8_t* sectors, uint16_t num_stripes, ULONG
sector_size, u
if (stripe == missing1 || stripe == missing2) {
RtlZeroMemory(qxy, sector_size);
RtlZeroMemory(pxy, sector_size);
-
- if (stripe == missing1)
- x = stripe;
- else
- y = stripe;
} else {
RtlCopyMemory(qxy, sectors + (stripe * sector_size), sector_size);
RtlCopyMemory(pxy, sectors + (stripe * sector_size), sector_size);
@@ -980,10 +975,7 @@ void raid6_recover2(uint8_t* sectors, uint16_t num_stripes, ULONG
sector_size, u
if (stripe != missing1 && stripe != missing2) {
do_xor(qxy, sectors + (stripe * sector_size), sector_size);
do_xor(pxy, sectors + (stripe * sector_size), sector_size);
- } else if (stripe == missing1)
- x = stripe;
- else if (stripe == missing2)
- y = stripe;
+ }
} while (stripe > 0);
gyx = gpow2(y > x ? (y-x) : (255-x+y));
@@ -1015,7 +1007,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf,
uint64_t ad
NTSTATUS Status;
bool checksum_error = false;
CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&ci[1];
- uint16_t stripe, j;
+ uint16_t stripe = 0, j;
bool no_success = true;
for (j = 0; j < ci->num_stripes; j++) {
@@ -1117,7 +1109,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf,
uint64_t ad
if (context->tree) {
uint8_t* sector;
- uint16_t k, physstripe, parity1, parity2, error_stripe;
+ uint16_t k, physstripe, parity1, parity2, error_stripe = 0;
uint64_t off;
bool recovered = false, failed = false;
ULONG num_errors = 0;
@@ -1321,7 +1313,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf,
uint64_t ad
physstripe = (parity2 + stripe + 1) % ci->num_stripes;
if (!devices[physstripe] || !devices[physstripe]->devobj ||
(context->csum && !check_sector_csum(Vcb, buf + (i <<
Vcb->sector_shift), ptr))) {
- uint16_t error_stripe;
+ uint16_t error_stripe = 0;
bool recovered = false, failed = false;
ULONG num_errors = 0;
@@ -2018,7 +2010,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr,
_In_ uint32_t
uint16_t endoffstripe, parity;
uint32_t *stripeoff, pos;
PMDL master_mdl;
- PFN_NUMBER *pfns, dummy;
+ PFN_NUMBER *pfns, dummy = 0;
bool need_dummy = false;
get_raid0_offset(addr - offset, ci->stripe_length, ci->num_stripes - 1,
&startoff, &startoffstripe);
@@ -2277,7 +2269,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr,
_In_ uint32_t
uint16_t endoffstripe, parity1;
uint32_t *stripeoff, pos;
PMDL master_mdl;
- PFN_NUMBER *pfns, dummy;
+ PFN_NUMBER *pfns, dummy = 0;
bool need_dummy = false;
get_raid0_offset(addr - offset, ci->stripe_length, ci->num_stripes - 2,
&startoff, &startoffstripe);
@@ -3243,48 +3235,49 @@ nextitem:
inpageoff = inoff % LZO_PAGE_SIZE;
}
- if (off2 != 0) {
- outlen = off2 + min(rp->read,
(uint32_t)(rp->extents[i].ed_num_bytes - rp->extents[i].off));
+ /* Previous versions of this code decompressed directly into the
destination buffer,
+ * but unfortunately that can't be relied on - Windows likes to use
dummy pages sometimes
+ * when mmap-ing, which breaks the backtracking used by e.g. zstd. */
- decomp = ExAllocatePoolWithTag(pool_type, outlen, ALLOC_TAG);
- if (!decomp) {
- ERR("out of memory\n");
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto exit;
- }
- } else
+ if (off2 != 0)
+ outlen = off2 + min(rp->read,
(uint32_t)(rp->extents[i].ed_num_bytes - rp->extents[i].off));
+ else
outlen = min(rp->read, (uint32_t)(rp->extents[i].ed_num_bytes -
rp->extents[i].off));
+ decomp = ExAllocatePoolWithTag(pool_type, outlen, ALLOC_TAG);
+ if (!decomp) {
+ ERR("out of memory\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto exit;
+ }
+
ccj = (comp_calc_job*)ExAllocatePoolWithTag(pool_type,
sizeof(comp_calc_job), ALLOC_TAG);
if (!ccj) {
ERR("out of memory\n");
- if (decomp)
- ExFreePool(decomp);
+ ExFreePool(decomp);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
- Status = add_calc_job_decomp(fcb->Vcb, rp->compression, buf2,
inlen, decomp ? decomp : rp->data, outlen,
+ ccj->data = rp->data;
+ ccj->decomp = decomp;
+
+ ccj->offset = off2;
+ ccj->length = (size_t)min(rp->read, rp->extents[i].ed_num_bytes
- rp->extents[i].off);
+
+ Status = add_calc_job_decomp(fcb->Vcb, rp->compression, buf2,
inlen, decomp, outlen,
inpageoff, &ccj->cj);
if (!NT_SUCCESS(Status)) {
ERR("add_calc_job_decomp returned %08lx\n", Status);
- if (decomp)
- ExFreePool(decomp);
-
+ ExFreePool(decomp);
ExFreePool(ccj);
goto exit;
}
- ccj->data = rp->data;
- ccj->decomp = decomp;
-
- ccj->offset = off2;
- ccj->length = (size_t)min(rp->read, rp->extents[i].ed_num_bytes
- rp->extents[i].off);
-
InsertTailList(&calc_jobs, &ccj->list_entry);
buf += rp->extents[i].ed_size;
@@ -3317,10 +3310,8 @@ nextitem:
if (!NT_SUCCESS(ccj->cj->Status))
Status = ccj->cj->Status;
- if (ccj->decomp) {
- RtlCopyMemory(ccj->data, (uint8_t*)ccj->decomp + ccj->offset,
ccj->length);
- ExFreePool(ccj->decomp);
- }
+ RtlCopyMemory(ccj->data, (uint8_t*)ccj->decomp + ccj->offset,
ccj->length);
+ ExFreePool(ccj->decomp);
ExFreePool(ccj);
}
diff --git a/drivers/filesystems/btrfs/reparse.c b/drivers/filesystems/btrfs/reparse.c
index e6a8145b0d3..03708228d46 100644
--- a/drivers/filesystems/btrfs/reparse.c
+++ b/drivers/filesystems/btrfs/reparse.c
@@ -24,7 +24,7 @@ typedef struct {
char name[1];
} REPARSE_DATA_BUFFER_LX_SYMLINK;
-NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, void*
buffer, DWORD buflen, ULONG_PTR* retlen) {
+NTSTATUS get_reparse_point(PFILE_OBJECT FileObject, void* buffer, DWORD buflen,
ULONG_PTR* retlen) {
USHORT subnamelen, printnamelen, i;
ULONG stringlen;
DWORD reqlen;
@@ -33,7 +33,7 @@ NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT
FileObject,
ccb* ccb = FileObject->FsContext2;
NTSTATUS Status;
- TRACE("(%p, %p, %p, %lx, %p)\n", DeviceObject, FileObject, buffer, buflen,
retlen);
+ TRACE("(%p, %p, %lx, %p)\n", FileObject, buffer, buflen, retlen);
if (!ccb)
return STATUS_INVALID_PARAMETER;
@@ -234,15 +234,16 @@ static NTSTATUS set_symlink(PIRP Irp, file_ref* fileref, fcb* fcb,
ccb* ccb, REP
REPARSE_DATA_BUFFER_LX_SYMLINK* buf;
if (buflen < offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
rdb->ReparseDataLength) {
- WARN("buffer was less than expected length (%lu < %u)\n",
buflen,
- offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
rdb->ReparseDataLength);
+ WARN("buffer was less than expected length (%lu < %lu)\n",
buflen,
+ (unsigned long)(offsetof(REPARSE_DATA_BUFFER,
GenericReparseBuffer.DataBuffer) + rdb->ReparseDataLength));
return STATUS_INVALID_PARAMETER;
}
buf = (REPARSE_DATA_BUFFER_LX_SYMLINK*)rdb->GenericReparseBuffer.DataBuffer;
if (buflen < offsetof(REPARSE_DATA_BUFFER_LX_SYMLINK, name)) {
- WARN("buffer was less than minimum length (%u < %u)\n",
rdb->ReparseDataLength, offsetof(REPARSE_DATA_BUFFER_LX_SYMLINK, name));
+ WARN("buffer was less than minimum length (%u < %lu)\n",
rdb->ReparseDataLength,
+ (unsigned long)(offsetof(REPARSE_DATA_BUFFER_LX_SYMLINK, name)));
return STATUS_INVALID_PARAMETER;
}
@@ -397,7 +398,7 @@ NTSTATUS set_reparse_point2(fcb* fcb, REPARSE_DATA_BUFFER* rdb, ULONG
buflen, cc
return STATUS_SUCCESS;
}
-NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
+NTSTATUS set_reparse_point(PIRP Irp) {
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
void* buffer = Irp->AssociatedIrp.SystemBuffer;
@@ -409,7 +410,7 @@ NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
file_ref* fileref;
LIST_ENTRY rollback;
- TRACE("(%p, %p)\n", DeviceObject, Irp);
+ TRACE("(%p)\n", Irp);
InitializeListHead(&rollback);
@@ -470,7 +471,7 @@ end:
return Status;
}
-NTSTATUS delete_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
+NTSTATUS delete_reparse_point(PIRP Irp) {
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
REPARSE_DATA_BUFFER* rdb = Irp->AssociatedIrp.SystemBuffer;
@@ -481,7 +482,7 @@ NTSTATUS delete_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
file_ref* fileref;
LIST_ENTRY rollback;
- TRACE("(%p, %p)\n", DeviceObject, Irp);
+ TRACE("(%p)\n", Irp);
InitializeListHead(&rollback);
diff --git a/drivers/filesystems/btrfs/scrub.c b/drivers/filesystems/btrfs/scrub.c
index 40938a38077..01160f73654 100644
--- a/drivers/filesystems/btrfs/scrub.c
+++ b/drivers/filesystems/btrfs/scrub.c
@@ -1377,7 +1377,7 @@ static NTSTATUS scrub_extent(device_extension* Vcb, chunk* c, ULONG
type, uint64
scrub_context context;
CHUNK_ITEM_STRIPE* cis;
NTSTATUS Status;
- uint16_t startoffstripe, num_missing, allowed_missing;
+ uint16_t startoffstripe = 0, num_missing, allowed_missing;
TRACE("(%p, %p, %lx, %I64x, %x, %p)\n", Vcb, c, type, offset, size, csum);
@@ -1788,8 +1788,8 @@ static void scrub_raid5_stripe(device_extension* Vcb, chunk* c,
scrub_context_ra
return;
for (ULONG i = 0; i < sectors_per_stripe; i++) {
- ULONG num_errors = 0, bad_off;
- uint64_t bad_stripe;
+ ULONG num_errors = 0, bad_off = 0;
+ uint64_t bad_stripe = 0;
bool alloc = false;
stripe = (parity + 1) % c->chunk_item->num_stripes;
@@ -2006,8 +2006,8 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c,
scrub_context_ra
for (ULONG i = 0; i < sectors_per_stripe; i++) {
ULONG num_errors = 0;
- uint64_t bad_stripe1, bad_stripe2;
- ULONG bad_off1, bad_off2;
+ uint64_t bad_stripe1 = 0, bad_stripe2 = 0;
+ ULONG bad_off1 = 0, bad_off2 = 0;
bool alloc = false;
stripe = (parity1 + 2) % c->chunk_item->num_stripes;
@@ -2071,7 +2071,6 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c,
scrub_context_ra
}
} else if (num_errors == 1) {
uint32_t len;
- uint16_t stripe_num, bad_stripe_num;
uint64_t addr = c->offset + (stripe_start *
(c->chunk_item->num_stripes - 2) * c->chunk_item->stripe_length) + (bad_off1
<< Vcb->sector_shift);
uint8_t* scratch;
@@ -2091,6 +2090,8 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c,
scrub_context_ra
stripe = parity1 == 0 ? (c->chunk_item->num_stripes - 1) : (parity1 -
1);
if (c->devices[parity2]->devobj) {
+ uint16_t stripe_num, bad_stripe_num = 0;
+
stripe_num = c->chunk_item->num_stripes - 3;
while (stripe != parity2) {
galois_double(scratch, len);
@@ -2275,7 +2276,7 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c,
scrub_context_ra
ExFreePool(scratch);
} else if (num_errors == 2 && missing_devices == 0) {
- uint16_t x, y, k;
+ uint16_t x = 0, y = 0, k;
uint64_t addr;
uint32_t len = (RtlCheckBit(&context->is_tree, bad_off1) ||
RtlCheckBit(&context->is_tree, bad_off2)) ? Vcb->superblock.node_size :
Vcb->superblock.sector_size;
uint8_t gyx, gx, denom, a, b, *p, *q, *pxy, *qxy;
@@ -2837,7 +2838,7 @@ static NTSTATUS scrub_chunk_raid56(device_extension* Vcb, chunk* c,
uint64_t* of
KEY searchkey;
traverse_ptr tp;
bool b;
- uint64_t full_stripe_len, stripe, stripe_start, stripe_end, total_data = 0;
+ uint64_t full_stripe_len, stripe, stripe_start = 0, stripe_end = 0, total_data = 0;
ULONG num_extents = 0, num_parity_stripes = c->chunk_item->type &
BLOCK_FLAG_RAID6 ? 2 : 1;
full_stripe_len = (c->chunk_item->num_stripes - num_parity_stripes) *
c->chunk_item->stripe_length;
@@ -2925,7 +2926,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c,
uint64_t* offset, b
traverse_ptr tp;
bool b = false, tree_run = false;
ULONG type, num_extents = 0;
- uint64_t total_data = 0, tree_run_start, tree_run_end;
+ uint64_t total_data = 0, tree_run_start = 0, tree_run_end = 0;
TRACE("chunk %I64x\n", c->offset);
diff --git a/drivers/filesystems/btrfs/security.c b/drivers/filesystems/btrfs/security.c
index f6769d05606..2761c63a915 100644
--- a/drivers/filesystems/btrfs/security.c
+++ b/drivers/filesystems/btrfs/security.c
@@ -678,7 +678,7 @@ NTSTATUS __stdcall drv_query_security(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Ir
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_query_security(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
@@ -842,7 +842,7 @@ NTSTATUS __stdcall drv_set_security(IN PDEVICE_OBJECT DeviceObject, IN
PIRP Irp)
top_level = is_top_level(Irp);
if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
- Status = vol_set_security(DeviceObject, Irp);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
goto end;
} else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
Status = STATUS_INVALID_PARAMETER;
diff --git a/drivers/filesystems/btrfs/volume.c b/drivers/filesystems/btrfs/volume.c
index e89b6154d31..3ee63ed29f6 100644
--- a/drivers/filesystems/btrfs/volume.c
+++ b/drivers/filesystems/btrfs/volume.c
@@ -303,74 +303,6 @@ end:
return Status;
}
-NTSTATUS vol_query_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_set_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_flush_buffers(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS vol_query_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_set_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_cleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- Irp->IoStatus.Information = 0;
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS vol_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_file_system_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_lock_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
static NTSTATUS vol_query_device_name(volume_device_extension* vde, PIRP Irp) {
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PMOUNTDEV_NAME name;
@@ -877,17 +809,15 @@ NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp) {
return vol_get_disk_extents(vde, Irp);
default: { // pass ioctl through if only one child device
- ULONG code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
NTSTATUS Status = vol_ioctl_passthrough(vde, Irp);
-
-#ifdef __REACTOS__
- &code;
-#endif
+#ifdef _DEBUG
+ ULONG code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
if (NT_SUCCESS(Status))
TRACE("passing through ioctl %lx (returning %08lx)\n", code,
Status);
else
WARN("passing through ioctl %lx (returning %08lx)\n", code,
Status);
+#endif
return Status;
}
@@ -896,24 +826,6 @@ NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp) {
return STATUS_INVALID_DEVICE_REQUEST;
}
-NTSTATUS vol_shutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
-NTSTATUS vol_set_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
- TRACE("(%p, %p)\n", DeviceObject, Irp);
-
- return STATUS_INVALID_DEVICE_REQUEST;
-}
-
NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath) {
NTSTATUS Status;
ULONG mmdltsize;
diff --git a/drivers/filesystems/btrfs/write.c b/drivers/filesystems/btrfs/write.c
index b73c17d689c..e8e354280c3 100644
--- a/drivers/filesystems/btrfs/write.c
+++ b/drivers/filesystems/btrfs/write.c
@@ -552,9 +552,7 @@ NTSTATUS alloc_chunk(device_extension* Vcb, uint64_t flags, chunk**
pc, bool ful
}
}
- if (type == 0 || type == BLOCK_FLAG_DUPLICATE || type == BLOCK_FLAG_RAID1 || type ==
BLOCK_FLAG_RAID1C3 || type == BLOCK_FLAG_RAID1C4)
- factor = 1;
- else if (type == BLOCK_FLAG_RAID0)
+ if (type == BLOCK_FLAG_RAID0)
factor = num_stripes;
else if (type == BLOCK_FLAG_RAID10)
factor = num_stripes / sub_stripes;
@@ -562,6 +560,8 @@ NTSTATUS alloc_chunk(device_extension* Vcb, uint64_t flags, chunk**
pc, bool ful
factor = num_stripes - 1;
else if (type == BLOCK_FLAG_RAID6)
factor = num_stripes - 2;
+ else
+ factor = 1; // SINGLE, DUPLICATE, RAID1, RAID1C3, RAID1C4
if (stripe_size * factor > max_chunk_size)
stripe_size = max_chunk_size / factor;
diff --git a/drivers/filesystems/btrfs/xor.S b/drivers/filesystems/btrfs/xor.S
new file mode 100644
index 00000000000..0a2b7e21580
--- /dev/null
+++ b/drivers/filesystems/btrfs/xor.S
@@ -0,0 +1,342 @@
+/* Copyright (c) Mark Harmstone 2020
+ *
+ * This file is part of WinBtrfs.
+ *
+ * WinBtrfs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public Licence as published by
+ * the Free Software Foundation, either version 3 of the Licence, or
+ * (at your option) any later version.
+ *
+ * WinBtrfs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public Licence
+ * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <asm.inc>
+
+#ifdef __x86_64__
+
+.code64
+
+/* void do_xor_sse2(uint8_t* buf1, uint8_t* buf2, uint32_t len); */
+PUBLIC do_xor_sse2
+do_xor_sse2:
+ /* rcx = buf1
+ * rdx = buf2
+ * r8d = len
+ * rax = tmp1
+ * r9 = tmp2
+ * xmm0 = tmp3
+ * xmm1 = tmp4 */
+
+ mov rax, rcx
+ and rax, 15
+ cmp rax, 0
+ jne stragglers2
+
+ mov rax, rdx
+ and rax, 15
+ cmp rax, 0
+ jne stragglers2
+
+do_xor_sse2_loop:
+ cmp r8d, 16
+ jl stragglers2
+
+ movdqa xmm0, [rcx]
+ movdqa xmm1, [rdx]
+ pxor xmm0, xmm1
+ movdqa [rcx], xmm0
+
+ add rcx, 16
+ add rdx, 16
+ sub r8d, 16
+
+ jmp do_xor_sse2_loop
+
+stragglers2:
+
+ cmp r8d, 8
+ jl stragglers
+
+ mov rax, [rcx]
+ mov r9, [rdx]
+ xor rax, r9
+ mov [rcx], rax
+
+ add rcx, 8
+ add rdx, 8
+ sub r8d, 8
+
+ jmp stragglers2
+
+stragglers:
+
+ cmp r8d, 0
+ je do_xor_sse2_end
+
+ mov al, [rcx]
+ mov r9b, [rdx]
+ xor al, r9b
+ mov [rcx], al
+
+ inc rcx
+ inc rdx
+ dec r8d
+
+ jmp stragglers
+
+do_xor_sse2_end:
+ ret
+
+/* void do_xor_avx2(uint8_t* buf1, uint8_t* buf2, uint32_t len); */
+PUBLIC do_xor_avx2
+do_xor_avx2:
+ /* rcx = buf1
+ * rdx = buf2
+ * r8d = len
+ * rax = tmp1
+ * r9 = tmp2
+ * xmm0 = tmp3
+ * xmm1 = tmp4 */
+
+ mov rax, rcx
+ and rax, 31
+ cmp rax, 0
+ jne stragglers4
+
+ mov rax, rdx
+ and rax, 31
+ cmp rax, 0
+ jne stragglers4
+
+do_xor_avx2_loop:
+ cmp r8d, 32
+ jl stragglers4
+
+ vmovdqa ymm0, YMMWORD PTR[rcx]
+ vmovdqa ymm1, YMMWORD PTR[rdx]
+ vpxor ymm0, ymm0, ymm1
+ vmovdqa YMMWORD PTR[rcx], ymm0
+
+ add rcx, 32
+ add rdx, 32
+ sub r8d, 32
+
+ jmp do_xor_avx2_loop
+
+stragglers4:
+
+ cmp r8d, 8
+ jl stragglers3
+
+ mov rax, [rcx]
+ mov r9, [rdx]
+ xor rax, r9
+ mov [rcx], rax
+
+ add rcx, 8
+ add rdx, 8
+ sub r8d, 8
+
+ jmp stragglers4
+
+stragglers3:
+
+ cmp r8d, 0
+ je do_xor_avx2_end
+
+ mov al, [rcx]
+ mov r9b, [rdx]
+ xor al, r9b
+ mov [rcx], al
+
+ inc rcx
+ inc rdx
+ dec r8d
+
+ jmp stragglers3
+
+do_xor_avx2_end:
+ ret
+END
+#else
+
+.code
+
+/* void __stdcall do_xor_sse2(uint8_t* buf1, uint8_t* buf2, uint32_t len); */
+PUBLIC _do_xor_sse2@12
+_do_xor_sse2@12:
+ /* edi = buf1
+ * edx = buf2
+ * esi = len
+ * eax = tmp1
+ * ecx = tmp2
+ * xmm0 = tmp3
+ * xmm1 = tmp4 */
+
+ push ebp
+ mov ebp, esp
+
+ push esi
+ push edi
+
+ mov edi, [ebp+8]
+ mov edx, [ebp+12]
+ mov esi, [ebp+16]
+
+ mov eax, edi
+ and eax, 15
+ cmp eax, 0
+ jne stragglers2
+
+ mov eax, edx
+ and eax, 15
+ cmp eax, 0
+ jne stragglers2
+
+do_xor_sse2_loop:
+ cmp esi, 16
+ jl stragglers2
+
+ movdqa xmm0, [edi]
+ movdqa xmm1, [edx]
+ pxor xmm0, xmm1
+ movdqa [edi], xmm0
+
+ add edi, 16
+ add edx, 16
+ sub esi, 16
+
+ jmp do_xor_sse2_loop
+
+stragglers2:
+
+ cmp esi, 4
+ jl stragglers
+
+ mov eax, [edi]
+ mov ecx, [edx]
+ xor eax, ecx
+ mov [edi], eax
+
+ add edi, 4
+ add edx, 4
+ sub esi, 4
+
+ jmp stragglers2
+
+stragglers:
+
+ cmp esi, 0
+ je do_xor_sse2_end
+
+ mov al, [edi]
+ mov cl, [edx]
+ xor al, cl
+ mov [edi], al
+
+ inc edi
+ inc edx
+ dec esi
+
+ jmp stragglers
+
+do_xor_sse2_end:
+ pop edi
+ pop esi
+ pop ebp
+
+ ret 12
+
+/* void __stdcall do_xor_avx2(uint8_t* buf1, uint8_t* buf2, uint32_t len); */
+PUBLIC _do_xor_avx2@12
+_do_xor_avx2@12:
+ /* edi = buf1
+ * edx = buf2
+ * esi = len
+ * eax = tmp1
+ * ecx = tmp2
+ * xmm0 = tmp3
+ * xmm1 = tmp4 */
+
+ push ebp
+ mov ebp, esp
+
+ push esi
+ push edi
+
+ mov edi, [ebp+8]
+ mov edx, [ebp+12]
+ mov esi, [ebp+16]
+
+ mov eax, edi
+ and eax, 31
+ cmp eax, 0
+ jne stragglers4
+
+ mov eax, edx
+ and eax, 31
+ cmp eax, 0
+ jne stragglers4
+
+do_xor_avx2_loop:
+ cmp esi, 32
+ jl stragglers4
+
+ vmovdqa ymm0, YMMWORD PTR[edi]
+ vmovdqa ymm1, YMMWORD PTR[edx]
+ vpxor ymm0, ymm0, ymm1
+ vmovdqa YMMWORD PTR[edi], ymm0
+
+ add edi, 32
+ add edx, 32
+ sub esi, 32
+
+ jmp do_xor_avx2_loop
+
+stragglers4:
+
+ cmp esi, 4
+ jl stragglers3
+
+ mov eax, [edi]
+ mov ecx, [edx]
+ xor eax, ecx
+ mov [edi], eax
+
+ add edi, 4
+ add edx, 4
+ sub esi, 4
+
+ jmp stragglers4
+
+stragglers3:
+
+ cmp esi, 0
+ je do_xor_avx2_end
+
+ mov al, [edi]
+ mov cl, [edx]
+ xor al, cl
+ mov [edi], al
+
+ inc edi
+ inc edx
+ dec esi
+
+ jmp stragglers3
+
+do_xor_avx2_end:
+ pop edi
+ pop esi
+ pop ebp
+
+ ret 12
+
+END
+
+#endif
diff --git a/drivers/filesystems/btrfs/zstd/bitstream.h
b/drivers/filesystems/btrfs/zstd/bitstream.h
index ef89b9878e2..37b99c01eed 100644
--- a/drivers/filesystems/btrfs/zstd/bitstream.h
+++ b/drivers/filesystems/btrfs/zstd/bitstream.h
@@ -1,35 +1,15 @@
/* ******************************************************************
- bitstream
- Part of FSE library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * bitstream
+ * Part of FSE library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
#ifndef BITSTREAM_H_MODULE
#define BITSTREAM_H_MODULE
@@ -48,6 +28,7 @@ extern "C" {
* Dependencies
******************************************/
#include "mem.h" /* unaligned access routines */
+#include "compiler.h" /* UNLIKELY() */
#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
#include "error_private.h" /* error codes and messages */
@@ -57,6 +38,8 @@ extern "C" {
=========================================*/
#if defined(__BMI__) && defined(__GNUC__)
# include <immintrin.h> /* support for bextr (experimental) */
+#elif defined(__ICCARM__)
+# include <intrinsics.h>
#endif
#define STREAM_ACCUMULATOR_MIN_32 25
@@ -159,10 +142,11 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val)
{
# if defined(_MSC_VER) /* Visual */
unsigned long r=0;
- _BitScanReverse ( &r, val );
- return (unsigned) r;
+ return _BitScanReverse ( &r, val ) ? (unsigned)r : 0;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
- return 31 - __builtin_clz (val);
+ return __builtin_clz (val) ^ 31;
+# elif defined(__ICCARM__) /* IAR Intrinsic */
+ return 31 - __CLZ(val);
# else /* Software version */
static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
11, 14, 16, 18, 22, 25, 3, 30,
@@ -240,9 +224,9 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
{
size_t const nbBytes = bitC->bitPos >> 3;
assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
+ assert(bitC->ptr <= bitC->endPtr);
MEM_writeLEST(bitC->ptr, bitC->bitContainer);
bitC->ptr += nbBytes;
- assert(bitC->ptr <= bitC->endPtr);
bitC->bitPos &= 7;
bitC->bitContainer >>= nbBytes*8;
}
@@ -256,6 +240,7 @@ MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
{
size_t const nbBytes = bitC->bitPos >> 3;
assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
+ assert(bitC->ptr <= bitC->endPtr);
MEM_writeLEST(bitC->ptr, bitC->bitContainer);
bitC->ptr += nbBytes;
if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
@@ -389,7 +374,7 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
* Read (consume) next n bits from local register and update.
* Pay attention to not read more than nbBits contained into local register.
* @return : extracted value. */
-MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
+MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
{
size_t const value = BIT_lookBits(bitD, nbBits);
BIT_skipBits(bitD, nbBits);
@@ -398,7 +383,7 @@ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
/*! BIT_readBitsFast() :
* unsafe version; only works only if nbBits >= 1 */
-MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
+MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
{
size_t const value = BIT_lookBitsFast(bitD, nbBits);
assert(nbBits >= 1);
@@ -406,6 +391,23 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
return value;
}
+/*! BIT_reloadDStreamFast() :
+ * Similar to BIT_reloadDStream(), but with two differences:
+ * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold!
+ * 2. Returns BIT_DStream_overflow when bitD->ptr < bitD->limitPtr, at this
+ * point you must use BIT_reloadDStream() to reload.
+ */
+MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
+{
+ if (UNLIKELY(bitD->ptr < bitD->limitPtr))
+ return BIT_DStream_overflow;
+ assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8);
+ bitD->ptr -= bitD->bitsConsumed >> 3;
+ bitD->bitsConsumed &= 7;
+ bitD->bitContainer = MEM_readLEST(bitD->ptr);
+ return BIT_DStream_unfinished;
+}
+
/*! BIT_reloadDStream() :
* Refill `bitD` from buffer previously set in BIT_initDStream() .
* This function is safe, it guarantees it will not read beyond src buffer.
@@ -417,10 +419,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
return BIT_DStream_overflow;
if (bitD->ptr >= bitD->limitPtr) {
- bitD->ptr -= bitD->bitsConsumed >> 3;
- bitD->bitsConsumed &= 7;
- bitD->bitContainer = MEM_readLEST(bitD->ptr);
- return BIT_DStream_unfinished;
+ return BIT_reloadDStreamFast(bitD);
}
if (bitD->ptr == bitD->start) {
if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return
BIT_DStream_endOfBuffer;
diff --git a/drivers/filesystems/btrfs/zstd/compiler.h
b/drivers/filesystems/btrfs/zstd/compiler.h
index 07f875e4d38..95e9483521d 100644
--- a/drivers/filesystems/btrfs/zstd/compiler.h
+++ b/drivers/filesystems/btrfs/zstd/compiler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -15,13 +15,15 @@
* Compiler specifics
*********************************************************/
/* force inlining */
-#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) &&
__STDC_VERSION__ >= 199901L /* C99 */
+
+#if !defined(ZSTD_NO_INLINE)
+#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) ||
defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# define INLINE_KEYWORD inline
#else
# define INLINE_KEYWORD
#endif
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__ICCARM__)
# define FORCE_INLINE_ATTR __attribute__((always_inline))
#elif defined(_MSC_VER)
# define FORCE_INLINE_ATTR __forceinline
@@ -29,9 +31,16 @@
# define FORCE_INLINE_ATTR
#endif
+#else
+
+#define INLINE_KEYWORD
+#define FORCE_INLINE_ATTR
+
+#endif
+
/**
* FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
- * parameters. They must be inlined for the compiler to elimininate the constant
+ * parameters. They must be inlined for the compiler to eliminate the constant
* branches.
*/
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
@@ -52,11 +61,18 @@
# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
#endif
+/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
+#if defined(__GNUC__)
+# define UNUSED_ATTR __attribute__((unused))
+#else
+# define UNUSED_ATTR
+#endif
+
/* force no inlining */
#ifdef _MSC_VER
# define FORCE_NOINLINE static __declspec(noinline)
#else
-# ifdef __GNUC__
+# if defined(__GNUC__) || defined(__ICCARM__)
# define FORCE_NOINLINE static __attribute__((__noinline__))
# else
# define FORCE_NOINLINE static
@@ -67,7 +83,7 @@
#ifndef __has_attribute
#define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__ICCARM__)
# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
#else
# define TARGET_ATTRIBUTE(target)
@@ -89,23 +105,24 @@
#endif
/* prefetch
- * can be disabled, by declaring NO_PREFETCH macro
- * All prefetch invocations use a single default locality 2,
- * generating instruction prefetcht1,
- * which, according to Intel, means "load data into L2 cache".
- * This is a good enough "middle ground" for the time being,
- * though in theory, it would be better to specialize locality depending on data being
prefetched.
- * Tests could not determine any sensible difference based on locality value. */
+ * can be disabled, by declaring NO_PREFETCH build macro */
#if defined(NO_PREFETCH)
-# define PREFETCH(ptr) (void)(ptr) /* disabled */
+# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
+# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
#else
# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /*
_mm_prefetch() is not defined outside of x86/x64 */
# include <mmintrin.h> /*
https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
-# define PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
+# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
+# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
+# elif defined(__aarch64__)
+# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0"
::"Q"(*(ptr)))
+# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0"
::"Q"(*(ptr)))
# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) &&
(__GNUC_MINOR__ >= 1) ) )
-# define PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality
*/)
+# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality
*/)
+# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality
*/)
# else
-# define PREFETCH(ptr) (void)(ptr) /* disabled */
+# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
+# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
# endif
#endif /* NO_PREFETCH */
@@ -116,10 +133,35 @@
size_t const _size = (size_t)(s); \
size_t _pos; \
for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
- PREFETCH(_ptr + _pos); \
+ PREFETCH_L2(_ptr + _pos); \
} \
}
+/* vectorization
+ * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */
+#if !defined(__INTEL_COMPILER) && !defined(__clang__) &&
defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
+# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
+# else
+# define DONT_VECTORIZE _Pragma("GCC
optimize(\"no-tree-vectorize\")")
+# endif
+#else
+# define DONT_VECTORIZE
+#endif
+
+/* Tell the compiler that a branch is likely or unlikely.
+ * Only use these macros if it causes the compiler to generate better code.
+ * If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc
+ * and clang, please do.
+ */
+#if defined(__GNUC__)
+#define LIKELY(x) (__builtin_expect((x), 1))
+#define UNLIKELY(x) (__builtin_expect((x), 0))
+#else
+#define LIKELY(x) (x)
+#define UNLIKELY(x) (x)
+#endif
+
/* disable warnings */
#ifdef _MSC_VER /* Visual Studio */
# include <intrin.h> /* For Visual 2005 */
diff --git a/drivers/filesystems/btrfs/zstd/cpu.h b/drivers/filesystems/btrfs/zstd/cpu.h
index eeb428ad5f6..6e8a974f62d 100644
--- a/drivers/filesystems/btrfs/zstd/cpu.h
+++ b/drivers/filesystems/btrfs/zstd/cpu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-present, Facebook, Inc.
+ * Copyright (c) 2018-2020, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -78,7 +78,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
__asm__(
"pushl %%ebx\n\t"
"cpuid\n\t"
- "movl %%ebx, %%eax\n\r"
+ "movl %%ebx, %%eax\n\t"
"popl %%ebx"
: "=a"(f7b), "=c"(f7c)
: "a"(7), "c"(0)
diff --git a/drivers/filesystems/btrfs/zstd/debug.h
b/drivers/filesystems/btrfs/zstd/debug.h
index 0c04ad2cc98..ac6224888d8 100644
--- a/drivers/filesystems/btrfs/zstd/debug.h
+++ b/drivers/filesystems/btrfs/zstd/debug.h
@@ -1,35 +1,15 @@
/* ******************************************************************
- debug
- Part of FSE library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * debug
+ * Part of FSE library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
@@ -57,9 +37,9 @@ extern "C" {
#endif
-/* static assert is triggered at compile time, leaving no runtime artefact,
- * but can only work with compile-time constants.
- * This variant can only be used inside a function. */
+/* static assert is triggered at compile time, leaving no runtime artefact.
+ * static assert only works with compile-time constants.
+ * Also, this variant can only be used inside a function. */
#define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1])
@@ -70,9 +50,19 @@ extern "C" {
# define DEBUGLEVEL 0
#endif
+
+/* DEBUGFILE can be defined externally,
+ * typically through compiler command line.
+ * note : currently useless.
+ * Value must be stderr or stdout */
+#ifndef DEBUGFILE
+# define DEBUGFILE stderr
+#endif
+
+
/* recommended values for DEBUGLEVEL :
- * 0 : no debug, all run-time functions disabled
- * 1 : no display, enables assert() only
+ * 0 : release mode, no debug, all run-time checks disabled
+ * 1 : enables assert() only, no display
* 2 : reserved, for currently active debug path
* 3 : events once per object lifetime (CCtx, CDict, etc.)
* 4 : events once per frame
@@ -81,7 +71,7 @@ extern "C" {
* 7+: events at every position (*very* verbose)
*
* It's generally inconvenient to output traces > 5.
- * In which case, it's possible to selectively enable higher verbosity levels
+ * In which case, it's possible to selectively trigger high verbosity levels
* by modifying g_debug_level.
*/
@@ -95,11 +85,12 @@ extern "C" {
#if (DEBUGLEVEL>=2)
# include <stdio.h>
-extern int g_debuglevel; /* here, this variable is only declared,
- it actually lives in debug.c,
- and is shared by the whole process.
- It's typically used to enable very verbose levels
- on selective conditions (such as position in src) */
+extern int g_debuglevel; /* the variable is only declared,
+ it actually lives in debug.c,
+ and is shared by the whole process.
+ It's not thread-safe.
+ It's useful when enabling very verbose levels
+ on selective conditions (such as position in src) */
# define RAWLOG(l, ...) { \
if (l<=g_debuglevel) { \
diff --git a/drivers/filesystems/btrfs/zstd/entropy_common.c
b/drivers/filesystems/btrfs/zstd/entropy_common.c
index b12944e1de9..9d3e4e8e36a 100644
--- a/drivers/filesystems/btrfs/zstd/entropy_common.c
+++ b/drivers/filesystems/btrfs/zstd/entropy_common.c
@@ -1,36 +1,16 @@
-/*
- Common functions of New Generation Entropy library
- Copyright (C) 2016, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE+HUF source repository :
https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum :
https://groups.google.com/forum/#!forum/lz4c
-*************************************************************************** */
+/* ******************************************************************
+ * Common functions of New Generation Entropy library
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE+HUF source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+****************************************************************** */
/* *************************************
* Dependencies
diff --git a/drivers/filesystems/btrfs/zstd/error_private.c
b/drivers/filesystems/btrfs/zstd/error_private.c
index d004ee636c6..cd437529c12 100644
--- a/drivers/filesystems/btrfs/zstd/error_private.c
+++ b/drivers/filesystems/btrfs/zstd/error_private.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -14,6 +14,10 @@
const char* ERR_getErrorString(ERR_enum code)
{
+#ifdef ZSTD_STRIP_ERROR_STRINGS
+ (void)code;
+ return "Error strings stripped";
+#else
static const char* const notErrorCode = "Unspecified error code";
switch( code )
{
@@ -39,10 +43,13 @@ const char* ERR_getErrorString(ERR_enum code)
case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from
provided samples";
case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
case PREFIX(srcSize_wrong): return "Src size is incorrect";
+ case PREFIX(dstBuffer_null): return "Operation on NULL destination
buffer";
/* following error codes are not stable and may be removed or changed in a future
version */
case PREFIX(frameIndex_tooLarge): return "Frame index is too large";
case PREFIX(seekableIO): return "An I/O error occurred when
reading/seeking";
+ case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong";
case PREFIX(maxCode):
default: return notErrorCode;
}
+#endif
}
diff --git a/drivers/filesystems/btrfs/zstd/error_private.h
b/drivers/filesystems/btrfs/zstd/error_private.h
index 0d2fa7e34b0..982cf8e9fe6 100644
--- a/drivers/filesystems/btrfs/zstd/error_private.h
+++ b/drivers/filesystems/btrfs/zstd/error_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -49,7 +49,7 @@ typedef ZSTD_ErrorCode ERR_enum;
/*-****************************************
* Error codes handling
******************************************/
-#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
+#undef ERROR /* already defined on Visual Studio */
#define ERROR(name) ZSTD_ERROR(name)
#define ZSTD_ERROR(name) ((size_t)-PREFIX(name))
@@ -57,6 +57,10 @@ ERR_STATIC unsigned ERR_isError(size_t code) { return (code >
ERROR(maxCode)); }
ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return
(ERR_enum)0; return (ERR_enum) (0-code); }
+/* check and forward error code */
+#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
+#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
+
/*-****************************************
* Error Strings
diff --git a/drivers/filesystems/btrfs/zstd/fse.h b/drivers/filesystems/btrfs/zstd/fse.h
index a5a6b6d4db7..ff54e70ea75 100644
--- a/drivers/filesystems/btrfs/zstd/fse.h
+++ b/drivers/filesystems/btrfs/zstd/fse.h
@@ -1,35 +1,15 @@
/* ******************************************************************
- FSE : Finite State Entropy codec
- Public Prototypes declaration
- Copyright (C) 2013-2016, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * FSE : Finite State Entropy codec
+ * Public Prototypes declaration
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
#if defined (__cplusplus)
@@ -308,7 +288,7 @@ If there is an error, the function will return an error code, which
can be teste
*******************************************/
/* FSE buffer bounds */
#define FSE_NCOUNTBOUND 512
-#define FSE_BLOCKBOUND(size) (size + (size>>7))
+#define FSE_BLOCKBOUND(size) (size + (size>>7) + 4 /* fse states */ +
sizeof(size_t) /* bitContainer */)
#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro
version, useful for static allocation */
/* It is possible to statically allocate FSE CTable/DTable as a table of
FSE_CTable/FSE_DTable using below macros */
@@ -358,7 +338,7 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void*
cSrc, size
typedef enum {
FSE_repeat_none, /**< Cannot use the previous table */
FSE_repeat_check, /**< Can use the previous table but it must be checked */
- FSE_repeat_valid /**< Can use the previous table and it is asumed to be valid */
+ FSE_repeat_valid /**< Can use the previous table and it is assumed to be valid */
} FSE_repeat;
/* *****************************************
@@ -512,7 +492,7 @@ MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const
FSE_CTable* ct)
const U32 tableLog = MEM_read16(ptr);
statePtr->value = (ptrdiff_t)1<<tableLog;
statePtr->stateTable = u16ptr+2;
- statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) :
1));
+ statePtr->symbolTT = ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1);
statePtr->stateLog = tableLog;
}
@@ -531,7 +511,7 @@ MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const
FSE_CTable* ct, U3
}
}
-MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32
symbol)
+MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, unsigned
symbol)
{
FSE_symbolCompressionTransform const symbolTT = ((const
FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
const U16* const stateTable = (const U16*)(statePtr->stateTable);
diff --git a/drivers/filesystems/btrfs/zstd/fse_compress.c
b/drivers/filesystems/btrfs/zstd/fse_compress.c
index c84f1d87ec9..419ad23b090 100644
--- a/drivers/filesystems/btrfs/zstd/fse_compress.c
+++ b/drivers/filesystems/btrfs/zstd/fse_compress.c
@@ -1,35 +1,15 @@
/* ******************************************************************
- FSE : Finite State Entropy encoder
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE source repository :
https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ * FSE : Finite State Entropy encoder
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* **************************************************************
@@ -118,7 +98,7 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
/* symbol start positions */
{ U32 u;
cumul[0] = 0;
- for (u=1; u<=maxSymbolValue+1; u++) {
+ for (u=1; u <= maxSymbolValue+1; u++) {
if (normalizedCounter[u-1]==-1) { /* Low proba symbol */
cumul[u] = cumul[u-1] + 1;
tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
@@ -132,9 +112,9 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
{ U32 position = 0;
U32 symbol;
for (symbol=0; symbol<=maxSymbolValue; symbol++) {
- int nbOccurences;
+ int nbOccurrences;
int const freq = normalizedCounter[symbol];
- for (nbOccurences=0; nbOccurences<freq; nbOccurences++) {
+ for (nbOccurrences=0; nbOccurrences<freq; nbOccurrences++) {
tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
position = (position + step) & tableMask;
while (position > highThreshold)
@@ -194,17 +174,8 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned
maxSymbolValue, unsigned tableLog)
{
- FSE_FUNCTION_TYPE* tableSymbol = ExAllocatePoolWithTag(NonPagedPool,
sizeof(FSE_FUNCTION_TYPE) * FSE_MAX_TABLESIZE, FSEC_ALLOC_TAG);
- size_t ret;
-
- if (!tableSymbol)
- return 0;
-
- ret = FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog,
tableSymbol, sizeof(FSE_FUNCTION_TYPE) * FSE_MAX_TABLESIZE);
-
- ExFreePool(tableSymbol);
-
- return ret;
+ FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary,
even if static analyzer complain about it */
+ return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog,
tableSymbol, sizeof(tableSymbol));
}
@@ -657,9 +628,6 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
-#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
-#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
-
/* FSE_compress_wksp() :
* Same as FSE_compress2(), but using an externally allocated scratch buffer
(`workSpace`).
* `wkspSize` size must be `(1<<tableLog)`.
@@ -670,7 +638,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src,
size_t src
BYTE* op = ostart;
BYTE* const oend = ostart + dstSize;
- U32 count[FSE_MAX_SYMBOL_VALUE+1];
+ unsigned count[FSE_MAX_SYMBOL_VALUE+1];
S16 norm[FSE_MAX_SYMBOL_VALUE+1];
FSE_CTable* CTable = (FSE_CTable*)workSpace;
size_t const CTableSize = FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue);
@@ -684,7 +652,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src,
size_t src
if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
/* Scan input and build symbol stats */
- { CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize,
(unsigned*)scratchBuffer) );
+ { CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize,
scratchBuffer, scratchBufferSize) );
if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
if (maxCount == 1) return 0; /* each symbol present maximum once =>
not compressible */
if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not
compressible enough */
@@ -718,24 +686,10 @@ typedef struct {
size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned tableLog)
{
- fseWkspMax_t* scratchBuffer;
- size_t ret;
-
- DEBUG_STATIC_ASSERT(sizeof(fseWkspMax_t) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG,
FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large
enough */
-
- if (tableLog > FSE_MAX_TABLELOG)
- return ERROR(tableLog_tooLarge);
-
- scratchBuffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(fseWkspMax_t),
FSEC_ALLOC_TAG);
-
- if (!scratchBuffer)
- return 0;
-
- ret = FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog,
scratchBuffer, sizeof(fseWkspMax_t));
-
- ExFreePool(scratchBuffer);
-
- return ret;
+ fseWkspMax_t scratchBuffer;
+ DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG,
FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large
enough */
+ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
+ return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog,
&scratchBuffer, sizeof(scratchBuffer));
}
size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
diff --git a/drivers/filesystems/btrfs/zstd/fse_decompress.c
b/drivers/filesystems/btrfs/zstd/fse_decompress.c
index 987813eb97e..aabf08abc69 100644
--- a/drivers/filesystems/btrfs/zstd/fse_decompress.c
+++ b/drivers/filesystems/btrfs/zstd/fse_decompress.c
@@ -1,35 +1,15 @@
/* ******************************************************************
- FSE : Finite State Entropy decoder
- Copyright (C) 2013-2015, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE source repository :
https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ * FSE : Finite State Entropy decoder
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
@@ -53,9 +33,6 @@
#define FSE_isError ERR_isError
#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable
declarations */
-/* check and forward error code */
-#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; }
-
/* **************************************************************
* Templates
@@ -81,7 +58,6 @@
#define FSED_ALLOC_TAG 0x64455346 // "FSEd"
-
/* Function templates */
FSE_DTable* FSE_createDTable (unsigned tableLog)
{
@@ -289,7 +265,7 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void*
cSrc, size
/* normal FSE decoding mode */
size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue,
&tableLog, istart, cSrcSize);
if (FSE_isError(NCountLength)) return NCountLength;
- //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input
size; supposed to be already checked in NCountLength, only remaining case :
NCountLength==cSrcSize */
+ /* if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); */ /* too small
input size; supposed to be already checked in NCountLength, only remaining case :
NCountLength==cSrcSize */
if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
ip += NCountLength;
cSrcSize -= NCountLength;
diff --git a/drivers/filesystems/btrfs/zstd/hist.c
b/drivers/filesystems/btrfs/zstd/hist.c
index 714a27e8d07..c17b9725f0d 100644
--- a/drivers/filesystems/btrfs/zstd/hist.c
+++ b/drivers/filesystems/btrfs/zstd/hist.c
@@ -1,36 +1,16 @@
/* ******************************************************************
- hist : Histogram functions
- part of Finite State Entropy project
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE source repository :
https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ * hist : Histogram functions
+ * part of Finite State Entropy project
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* --- dependencies --- */
@@ -38,10 +18,7 @@
#include "debug.h" /* assert, DEBUGLOG */
#include "error_private.h" /* ERROR */
#include "hist.h"
-#include <ntifs.h>
-#include <ntddk.h>
-#define HIST_ALLOC_TAG 0x54534948 // "HIST"
/* --- Error management --- */
unsigned HIST_isError(size_t code) { return ERR_isError(code); }
@@ -76,6 +53,7 @@ unsigned HIST_count_simple(unsigned* count, unsigned*
maxSymbolValuePtr,
return largestCount;
}
+typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;
/* HIST_count_parallel_wksp() :
* store histogram into 4 intermediate tables, recombined at the end.
@@ -88,8 +66,8 @@ unsigned HIST_count_simple(unsigned* count, unsigned*
maxSymbolValuePtr,
static size_t HIST_count_parallel_wksp(
unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize,
- unsigned checkMax,
- unsigned* const workSpace)
+ HIST_checkInput_e check,
+ U32* const workSpace)
{
const BYTE* ip = (const BYTE*)source;
const BYTE* const iend = ip+sourceSize;
@@ -140,7 +118,7 @@ static size_t HIST_count_parallel_wksp(
/* finish last symbols */
while (ip<iend) Counting1[*ip++]++;
- if (checkMax) { /* verify stats will fit into destination table */
+ if (check) { /* verify stats will fit into destination table */
U32 s; for (s=255; s>maxSymbolValue; s--) {
Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
@@ -160,48 +138,46 @@ static size_t HIST_count_parallel_wksp(
/* HIST_countFast_wksp() :
* Same as HIST_countFast(), but using an externally provided scratch buffer.
- * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */
+ * `workSpace` is a writable buffer which must be 4-bytes aligned,
+ * `workSpaceSize` must be >= HIST_WKSP_SIZE
+ */
size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize,
- unsigned* workSpace)
+ void* workSpace, size_t workSpaceSize)
{
if (sourceSize < 1500) /* heuristic threshold */
return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize);
- return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0,
workSpace);
+ if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes
boundaries */
+ if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
+ return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize,
trustInput, (U32*)workSpace);
}
/* fast variant (unsafe : won't check if src contains values beyond count[] limit)
*/
size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize)
{
- unsigned* tmpCounters = ExAllocatePoolWithTag(NonPagedPool, sizeof(unsigned) *
HIST_WKSP_SIZE_U32, HIST_ALLOC_TAG);
- size_t ret;
-
- if (!tmpCounters)
- return 0;
-
- ret = HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize,
tmpCounters);
-
- ExFreePool(tmpCounters);
-
- return ret;
+ unsigned tmpCounters[HIST_WKSP_SIZE_U32];
+ return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters,
sizeof(tmpCounters));
}
/* HIST_count_wksp() :
* Same as HIST_count(), but using an externally provided scratch buffer.
* `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */
size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
- const void* source, size_t sourceSize, unsigned* workSpace)
+ const void* source, size_t sourceSize,
+ void* workSpace, size_t workSpaceSize)
{
+ if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes
boundaries */
+ if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
if (*maxSymbolValuePtr < 255)
- return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1,
workSpace);
+ return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize,
checkMaxSymbolValue, (U32*)workSpace);
*maxSymbolValuePtr = 255;
- return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace);
+ return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace,
workSpaceSize);
}
size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize)
{
unsigned tmpCounters[HIST_WKSP_SIZE_U32];
- return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters);
+ return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters,
sizeof(tmpCounters));
}
diff --git a/drivers/filesystems/btrfs/zstd/hist.h
b/drivers/filesystems/btrfs/zstd/hist.h
index 8b1991a90bd..77e3ec4fb19 100644
--- a/drivers/filesystems/btrfs/zstd/hist.h
+++ b/drivers/filesystems/btrfs/zstd/hist.h
@@ -1,36 +1,16 @@
/* ******************************************************************
- hist : Histogram functions
- part of Finite State Entropy project
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE source repository :
https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ * hist : Histogram functions
+ * part of Finite State Entropy project
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* --- dependencies --- */
@@ -41,11 +21,11 @@
/*! HIST_count():
* Provides the precise count of each byte within a table 'count'.
- * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).
+ * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).
* Updates *maxSymbolValuePtr with actual largest symbol value detected.
- * @return : count of the most frequent symbol (which isn't identified).
- * or an error code, which can be tested using HIST_isError().
- * note : if return == srcSize, there is only one symbol.
+ * @return : count of the most frequent symbol (which isn't identified).
+ * or an error code, which can be tested using HIST_isError().
+ * note : if return == srcSize, there is only one symbol.
*/
size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize);
@@ -56,14 +36,16 @@ unsigned HIST_isError(size_t code); /**< tells if a return value
is an error co
/* --- advanced histogram functions --- */
#define HIST_WKSP_SIZE_U32 1024
+#define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned))
/** HIST_count_wksp() :
* Same as HIST_count(), but using an externally provided scratch buffer.
* Benefit is this function will use very little stack space.
- * `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32
+ * `workSpace` is a writable buffer which must be 4-bytes aligned,
+ * `workSpaceSize` must be >= HIST_WKSP_SIZE
*/
size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize,
- unsigned* workSpace);
+ void* workSpace, size_t workSpaceSize);
/** HIST_countFast() :
* same as HIST_count(), but blindly trusts that all byte values within src are <=
*maxSymbolValuePtr.
@@ -74,11 +56,12 @@ size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
/** HIST_countFast_wksp() :
* Same as HIST_countFast(), but using an externally provided scratch buffer.
- * `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32
+ * `workSpace` is a writable buffer which must be 4-bytes aligned,
+ * `workSpaceSize` must be >= HIST_WKSP_SIZE
*/
size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize,
- unsigned* workSpace);
+ void* workSpace, size_t workSpaceSize);
/*! HIST_count_simple() :
* Same as HIST_countFast(), this function is unsafe,
diff --git a/drivers/filesystems/btrfs/zstd/huf.h b/drivers/filesystems/btrfs/zstd/huf.h
index dc84f7ab114..ef432685dac 100644
--- a/drivers/filesystems/btrfs/zstd/huf.h
+++ b/drivers/filesystems/btrfs/zstd/huf.h
@@ -1,35 +1,15 @@
/* ******************************************************************
- huff0 huffman codec,
- part of Finite State Entropy library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - Source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * huff0 huffman codec,
+ * part of Finite State Entropy library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - Source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
#if defined (__cplusplus)
@@ -110,7 +90,7 @@ HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity,
/** HUF_compress4X_wksp() :
* Same as HUF_compress2(), but uses externally allocated `workSpace`.
* `workspace` must have minimum alignment of 4, and be at least as large as
HUF_WORKSPACE_SIZE */
-#define HUF_WORKSPACE_SIZE (6 << 10)
+#define HUF_WORKSPACE_SIZE ((6 << 10) + 256)
#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))
HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
@@ -163,21 +143,29 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t
dstCapacity,
/* static allocation of HUF's DTable */
typedef U32 HUF_DTable;
#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog)))
+#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \
+ HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) *
0x01000001) }
+#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
+ HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) *
0x01000001) }
/* ****************************************
* Advanced decompression functions
******************************************/
size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
/**< single-symbol decoder */
+#ifndef HUF_FORCE_DECOMPRESS_X1
size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
/**< double-symbols decoder */
+#endif
size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void*
cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */
size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void*
cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */
size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const
void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and
uncompressed as errors */
size_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void*
cSrc, size_t cSrcSize); /**< single-symbol decoder */
size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const
void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol
decoder */
+#ifndef HUF_FORCE_DECOMPRESS_X1
size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void*
cSrc, size_t cSrcSize); /**< double-symbols decoder */
size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const
void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols
decoder */
+#endif
/* ****************************************
@@ -200,6 +188,8 @@ typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */
size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue,
unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which
case, CTable will overwrite count content */
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned
maxSymbolValue, unsigned huffLog);
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t
srcSize, const HUF_CElt* CTable);
+size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned
maxSymbolValue);
+int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned
maxSymbolValue);
typedef enum {
HUF_repeat_none, /**< Cannot use the previous table */
@@ -224,7 +214,7 @@ size_t HUF_compress4X_repeat(void* dst, size_t dstSize,
#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1)
#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned))
size_t HUF_buildCTable_wksp (HUF_CElt* tree,
- const U32* count, U32 maxSymbolValue, U32 maxNbBits,
+ const unsigned* count, U32 maxSymbolValue, U32 maxNbBits,
void* workSpace, size_t wkspSize);
/*! HUF_readStats() :
@@ -238,7 +228,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize,
/** HUF_readCTable() :
* Loading a CTable saved with HUF_writeCTable() */
-size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src,
size_t srcSize);
+size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src,
size_t srcSize, unsigned *hasZeroWeights);
/** HUF_getNbBits() :
* Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <=
HUF_SYMBOLVALUE_MAX
@@ -273,14 +263,22 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10)
#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32))
+#ifndef HUF_FORCE_DECOMPRESS_X2
size_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize);
size_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void*
workSpace, size_t wkspSize);
+#endif
+#ifndef HUF_FORCE_DECOMPRESS_X1
size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize);
size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void*
workSpace, size_t wkspSize);
+#endif
size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc,
size_t cSrcSize, const HUF_DTable* DTable);
+#ifndef HUF_FORCE_DECOMPRESS_X2
size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc,
size_t cSrcSize, const HUF_DTable* DTable);
+#endif
+#ifndef HUF_FORCE_DECOMPRESS_X1
size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc,
size_t cSrcSize, const HUF_DTable* DTable);
+#endif
/* ====================== */
@@ -302,24 +300,36 @@ size_t HUF_compress1X_repeat(void* dst, size_t dstSize,
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int
bmi2);
size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
/* single-symbol decoder */
+#ifndef HUF_FORCE_DECOMPRESS_X1
size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
/* double-symbol decoder */
+#endif
size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void*
cSrc, size_t cSrcSize);
size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const
void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);
+#ifndef HUF_FORCE_DECOMPRESS_X2
size_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void*
cSrc, size_t cSrcSize); /**< single-symbol decoder */
size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const
void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol
decoder */
+#endif
+#ifndef HUF_FORCE_DECOMPRESS_X1
size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void*
cSrc, size_t cSrcSize); /**< double-symbols decoder */
size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const
void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols
decoder */
+#endif
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc,
size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or
double symbol decoder, based on DTable */
+#ifndef HUF_FORCE_DECOMPRESS_X2
size_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc,
size_t cSrcSize, const HUF_DTable* DTable);
+#endif
+#ifndef HUF_FORCE_DECOMPRESS_X1
size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc,
size_t cSrcSize, const HUF_DTable* DTable);
+#endif
/* BMI2 variants.
* If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.
*/
size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc,
size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
+#ifndef HUF_FORCE_DECOMPRESS_X2
size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize,
const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
+#endif
size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc,
size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize,
const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
diff --git a/drivers/filesystems/btrfs/zstd/huf_compress.c
b/drivers/filesystems/btrfs/zstd/huf_compress.c
index 1510fda2db9..4efffbb542a 100644
--- a/drivers/filesystems/btrfs/zstd/huf_compress.c
+++ b/drivers/filesystems/btrfs/zstd/huf_compress.c
@@ -1,35 +1,15 @@
/* ******************************************************************
- Huffman encoder, part of New Generation Entropy library
- Copyright (C) 2013-2016, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- You can contact the author at :
- - FSE+HUF source repository :
https://github.com/Cyan4973/FiniteStateEntropy
- - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ * Huffman encoder, part of New Generation Entropy library
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
+ *
+ * You can contact the author at :
+ * - FSE+HUF source repository :
https://github.com/Cyan4973/FiniteStateEntropy
+ * - Public forum :
https://groups.google.com/forum/#!forum/lz4c
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
****************************************************************** */
/* **************************************************************
@@ -53,10 +33,6 @@
#define HUF_STATIC_LINKING_ONLY
#include "huf.h"
#include "error_private.h"
-#include <ntifs.h>
-#include <ntddk.h>
-
-#define HUFC_ALLOC_TAG 0x63465548 // "HUFc"
/* **************************************************************
@@ -64,8 +40,6 @@
****************************************************************/
#define HUF_isError ERR_isError
#define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable
declarations */
-#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
-#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
/* **************************************************************
@@ -92,13 +66,13 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const
void* weight
BYTE* op = ostart;
BYTE* const oend = ostart + dstSize;
- U32 maxSymbolValue = HUF_TABLELOG_MAX;
+ unsigned maxSymbolValue = HUF_TABLELOG_MAX;
U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER,
HUF_TABLELOG_MAX)];
BYTE scratchBuffer[1<<MAX_FSE_TABLELOG_FOR_HUFF_HEADER];
- U32 count[HUF_TABLELOG_MAX+1];
+ unsigned count[HUF_TABLELOG_MAX+1];
S16 norm[HUF_TABLELOG_MAX+1];
/* init conditions */
@@ -114,18 +88,18 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const
void* weight
CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
/* Write table description header */
- { CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
+ { CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), norm, maxSymbolValue,
tableLog) );
op += hSize;
}
/* Compress */
CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer,
sizeof(scratchBuffer)) );
- { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize,
CTable) );
+ { CHECK_V_F(cSize, FSE_compress_usingCTable(op, (size_t)(oend - op), weightTable,
wtSize, CTable) );
if (cSize == 0) return 0; /* not enough space for compressed data */
op += cSize;
}
- return op-ostart;
+ return (size_t)(op-ostart);
}
@@ -138,7 +112,7 @@ struct HUF_CElt_s {
`CTable` : Huffman tree to save, using huf representation.
@return : size of saved CTable */
size_t HUF_writeCTable (void* dst, size_t maxDstSize,
- const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
+ const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned
huffLog)
{
BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */
BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
@@ -173,7 +147,7 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
}
-size_t HUF_readCTable (HUF_CElt* CTable, U32* maxSymbolValuePtr, const void* src, size_t
srcSize)
+size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src,
size_t srcSize, unsigned* hasZeroWeights)
{
BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some
static analyzer may complain */
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16
*/
@@ -196,9 +170,11 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32* maxSymbolValuePtr,
const void* src
} }
/* fill nbBits */
+ *hasZeroWeights = 0;
{ U32 n; for (n=0; n<nbSymbols; n++) {
const U32 w = huffWeight[n];
- CTable[n].nbBits = (BYTE)(tableLog + 1 - w);
+ *hasZeroWeights |= (w == 0);
+ CTable[n].nbBits = (BYTE)(tableLog + 1 - w) & -(w != 0);
} }
/* fill val */
@@ -244,7 +220,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32
maxNbBits)
/* there are several too large elements (at least >= 2) */
{ int totalCost = 0;
const U32 baseCost = 1 << (largestBits - maxNbBits);
- U32 n = lastNonNull;
+ int n = (int)lastNonNull;
while (huffNode[n].nbBits > maxNbBits) {
totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
@@ -259,22 +235,22 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32
maxNbBits)
/* repay normalized cost */
{ U32 const noSymbol = 0xF0F0F0F0;
U32 rankLast[HUF_TABLELOG_MAX+2];
- int pos;
/* Get pos of last (smallest) symbol per rank */
memset(rankLast, 0xF0, sizeof(rankLast));
{ U32 currentNbBits = maxNbBits;
+ int pos;
for (pos=n ; pos >= 0; pos--) {
if (huffNode[pos].nbBits >= currentNbBits) continue;
currentNbBits = huffNode[pos].nbBits; /* < maxNbBits */
- rankLast[maxNbBits-currentNbBits] = pos;
+ rankLast[maxNbBits-currentNbBits] = (U32)pos;
} }
while (totalCost > 0) {
- U32 nBitsToDecrease = BIT_highbit32(totalCost) + 1;
+ U32 nBitsToDecrease = BIT_highbit32((U32)totalCost) + 1;
for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
- U32 highPos = rankLast[nBitsToDecrease];
- U32 lowPos = rankLast[nBitsToDecrease-1];
+ U32 const highPos = rankLast[nBitsToDecrease];
+ U32 const lowPos = rankLast[nBitsToDecrease-1];
if (highPos == noSymbol) continue;
if (lowPos == noSymbol) break;
{ U32 const highTotal = huffNode[highPos].count;
@@ -301,7 +277,8 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32
maxNbBits)
if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using
maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */
while (huffNode[n].nbBits == maxNbBits) n--;
huffNode[n+1].nbBits--;
- rankLast[1] = n+1;
+ assert(n >= 0);
+ rankLast[1] = (U32)(n+1);
totalCost++;
continue;
}
@@ -313,29 +290,36 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32
maxNbBits)
return maxNbBits;
}
-
typedef struct {
U32 base;
U32 current;
} rankPos;
-static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
+typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];
+
+#define RANK_POSITION_TABLE_SIZE 32
+
+typedef struct {
+ huffNodeTable huffNodeTbl;
+ rankPos rankPosition[RANK_POSITION_TABLE_SIZE];
+} HUF_buildCTable_wksp_tables;
+
+static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue,
rankPos* rankPosition)
{
- rankPos rank[32];
U32 n;
- memset(rank, 0, sizeof(rank));
+ memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE);
for (n=0; n<=maxSymbolValue; n++) {
U32 r = BIT_highbit32(count[n] + 1);
- rank[r].base ++;
+ rankPosition[r].base ++;
}
- for (n=30; n>0; n--) rank[n-1].base += rank[n].base;
- for (n=0; n<32; n++) rank[n].current = rank[n].base;
+ for (n=30; n>0; n--) rankPosition[n-1].base += rankPosition[n].base;
+ for (n=0; n<32; n++) rankPosition[n].current = rankPosition[n].base;
for (n=0; n<=maxSymbolValue; n++) {
U32 const c = count[n];
U32 const r = BIT_highbit32(c+1) + 1;
- U32 pos = rank[r].current++;
- while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) {
+ U32 pos = rankPosition[r].current++;
+ while ((pos > rankPosition[r].base) && (c > huffNode[pos-1].count))
{
huffNode[pos] = huffNode[pos-1];
pos--;
}
@@ -347,45 +331,48 @@ static void HUF_sort(nodeElt* huffNode, const U32* count, U32
maxSymbolValue)
/** HUF_buildCTable_wksp() :
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
- * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a
table of HUF_CTABLE_WORKSPACE_SIZE_U32 unsigned.
+ * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as
sizeof(HUF_buildCTable_wksp_tables).
*/
#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
-typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];
-size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32
maxNbBits, void* workSpace, size_t wkspSize)
+
+size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue,
U32 maxNbBits, void* workSpace, size_t wkspSize)
{
- nodeElt* const huffNode0 = (nodeElt*)workSpace;
+ HUF_buildCTable_wksp_tables* const wksp_tables =
(HUF_buildCTable_wksp_tables*)workSpace;
+ nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
nodeElt* const huffNode = huffNode0+1;
- U32 n, nonNullRank;
+ int nonNullRank;
int lowS, lowN;
- U16 nodeNb = STARTNODE;
- U32 nodeRoot;
+ int nodeNb = STARTNODE;
+ int n, nodeRoot;
/* safety checks */
if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on
4-bytes boundaries */
- if (wkspSize < sizeof(huffNodeTable)) return ERROR(workSpace_tooSmall);
+ if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
+ return ERROR(workSpace_tooSmall);
if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
- if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
+ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
+ return ERROR(maxSymbolValue_tooLarge);
memset(huffNode0, 0, sizeof(huffNodeTable));
/* sort, decreasing order */
- HUF_sort(huffNode, count, maxSymbolValue);
+ HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition);
/* init for parents */
- nonNullRank = maxSymbolValue;
+ nonNullRank = (int)maxSymbolValue;
while(huffNode[nonNullRank].count == 0) nonNullRank--;
lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb;
huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count;
- huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;
+ huffNode[lowS].parent = huffNode[lowS-1].parent = (U16)nodeNb;
nodeNb++; lowS-=2;
for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */
/* create parents */
while (nodeNb <= nodeRoot) {
- U32 n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
- U32 n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
+ int const n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- :
lowN++;
+ int const n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- :
lowN++;
huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count;
- huffNode[n1].parent = huffNode[n2].parent = nodeNb;
+ huffNode[n1].parent = huffNode[n2].parent = (U16)nodeNb;
nodeNb++;
}
@@ -397,24 +384,25 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32
maxSymbolValu
huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
/* enforce maxTableLog */
- maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
+ maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits);
/* fill result into tree (val, nbBits) */
{ U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
+ int const alphabetSize = (int)(maxSymbolValue + 1);
if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into
table */
for (n=0; n<=nonNullRank; n++)
nbPerRank[huffNode[n].nbBits]++;
/* determine stating value per rank */
{ U16 min = 0;
- for (n=maxNbBits; n>0; n--) {
+ for (n=(int)maxNbBits; n>0; n--) {
valPerRank[n] = min; /* get starting value within each rank */
min += nbPerRank[n];
min >>= 1;
} }
- for (n=0; n<=maxSymbolValue; n++)
+ for (n=0; n<alphabetSize; n++)
tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per
symbol, symbol order */
- for (n=0; n<=maxSymbolValue; n++)
+ for (n=0; n<alphabetSize; n++)
tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank,
symbol order */
}
@@ -425,22 +413,13 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32
maxSymbolValu
* @return : maxNbBits
* Note : count is used before tree is written, so they can safely overlap
*/
-size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32
maxNbBits)
+size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue,
unsigned maxNbBits)
{
- huffNodeTable* nodeTable = ExAllocatePoolWithTag(NonPagedPool, sizeof(huffNodeTable),
HUFC_ALLOC_TAG);
- size_t ret;
-
- if (!nodeTable)
- return 0;
-
- ret = HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, nodeTable,
sizeof(huffNodeTable));
-
- ExFreePool(nodeTable);
-
- return ret;
+ HUF_buildCTable_wksp_tables workspace;
+ return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace,
sizeof(workspace));
}
-static size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const unsigned* count,
unsigned maxSymbolValue)
+size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned
maxSymbolValue)
{
size_t nbBits = 0;
int s;
@@ -450,7 +429,7 @@ static size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const
unsigned* count
return nbBits >> 3;
}
-static int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned
maxSymbolValue) {
+int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned
maxSymbolValue) {
int bad = 0;
int s;
for (s = 0; s <= (int)maxSymbolValue; ++s) {
@@ -489,7 +468,7 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
/* init */
if (dstSize < 8) return 0; /* not enough space to compress */
- { size_t const initErr = BIT_initCStream(&bitC, op, oend-op);
+ { size_t const initErr = BIT_initCStream(&bitC, op, (size_t)(oend-op));
if (HUF_isError(initErr)) return 0; }
n = srcSize & ~3; /* join to mod 4 */
@@ -586,7 +565,8 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
if (srcSize < 12) return 0; /* no saving possible : too small input */
op += 6; /* jumpTable */
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip,
segmentSize, CTable, bmi2) );
+ assert(op <= oend);
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip,
segmentSize, CTable, bmi2) );
if (cSize==0) return 0;
assert(cSize <= 65535);
MEM_writeLE16(ostart, (U16)cSize);
@@ -594,7 +574,8 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
}
ip += segmentSize;
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip,
segmentSize, CTable, bmi2) );
+ assert(op <= oend);
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip,
segmentSize, CTable, bmi2) );
if (cSize==0) return 0;
assert(cSize <= 65535);
MEM_writeLE16(ostart+2, (U16)cSize);
@@ -602,7 +583,8 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
}
ip += segmentSize;
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip,
segmentSize, CTable, bmi2) );
+ assert(op <= oend);
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip,
segmentSize, CTable, bmi2) );
if (cSize==0) return 0;
assert(cSize <= 65535);
MEM_writeLE16(ostart+4, (U16)cSize);
@@ -610,12 +592,14 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
}
ip += segmentSize;
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, iend-ip,
CTable, bmi2) );
+ assert(op <= oend);
+ assert(ip <= iend);
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip,
(size_t)(iend-ip), CTable, bmi2) );
if (cSize==0) return 0;
op += cSize;
}
- return op-ostart;
+ return (size_t)(op-ostart);
}
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t
srcSize, const HUF_CElt* CTable)
@@ -623,48 +607,52 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const
void* src, si
return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /*
bmi2 */ 0);
}
+typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e;
static size_t HUF_compressCTable_internal(
BYTE* const ostart, BYTE* op, BYTE* const oend,
const void* src, size_t srcSize,
- unsigned singleStream, const HUF_CElt* CTable, const int bmi2)
+ HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int bmi2)
{
- size_t const cSize = singleStream ?
- HUF_compress1X_usingCTable_internal(op, oend - op, src, srcSize,
CTable, bmi2) :
- HUF_compress4X_usingCTable_internal(op, oend - op, src, srcSize,
CTable, bmi2);
+ size_t const cSize = (nbStreams==HUF_singleStream) ?
+ HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op),
src, srcSize, CTable, bmi2) :
+ HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op),
src, srcSize, CTable, bmi2);
if (HUF_isError(cSize)) { return cSize; }
if (cSize==0) { return 0; } /* uncompressible */
op += cSize;
/* check compressibility */
+ assert(op >= ostart);
if ((size_t)(op-ostart) >= srcSize-1) { return 0; }
- return op-ostart;
+ return (size_t)(op-ostart);
}
typedef struct {
- U32 count[HUF_SYMBOLVALUE_MAX + 1];
+ unsigned count[HUF_SYMBOLVALUE_MAX + 1];
HUF_CElt CTable[HUF_SYMBOLVALUE_MAX + 1];
- huffNodeTable nodeTable;
+ HUF_buildCTable_wksp_tables buildCTable_wksp;
} HUF_compress_tables_t;
/* HUF_compress_internal() :
* `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
-static size_t HUF_compress_internal (
- void* dst, size_t dstSize,
- const void* src, size_t srcSize,
- unsigned maxSymbolValue, unsigned huffLog,
- unsigned singleStream,
- void* workSpace, size_t wkspSize,
- HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
- const int bmi2)
+static size_t
+HUF_compress_internal (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog,
+ HUF_nbStreams_e nbStreams,
+ void* workSpace, size_t wkspSize,
+ HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
+ const int bmi2)
{
HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace;
BYTE* const ostart = (BYTE*)dst;
BYTE* const oend = ostart + dstSize;
BYTE* op = ostart;
+ HUF_STATIC_ASSERT(sizeof(*table) <= HUF_WORKSPACE_SIZE);
+
/* checks & inits */
if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on
4-bytes boundaries */
- if (wkspSize < sizeof(*table)) return ERROR(workSpace_tooSmall);
+ if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);
if (!srcSize) return 0; /* Uncompressed */
if (!dstSize) return 0; /* cannot fit anything within dst budget */
if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block
size limit */
@@ -677,11 +665,11 @@ static size_t HUF_compress_internal (
if (preferRepeat && repeat && *repeat == HUF_repeat_valid) {
return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize,
- singleStream, oldHufTable, bmi2);
+ nbStreams, oldHufTable, bmi2);
}
/* Scan input and build symbol stats */
- { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const
BYTE*)src, srcSize, table->count) );
+ { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const
BYTE*)src, srcSize, workSpace, wkspSize) );
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /*
single symbol, rle */
if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not
compressible enough */
}
@@ -696,14 +684,15 @@ static size_t HUF_compress_internal (
if (preferRepeat && repeat && *repeat != HUF_repeat_none) {
return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize,
- singleStream, oldHufTable, bmi2);
+ nbStreams, oldHufTable, bmi2);
}
/* Build Huffman Tree */
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
- { CHECK_V_F(maxBits, HUF_buildCTable_wksp(table->CTable, table->count,
- maxSymbolValue, huffLog,
- table->nodeTable,
sizeof(table->nodeTable)) );
+ { size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count,
+ maxSymbolValue, huffLog,
+ &table->buildCTable_wksp,
sizeof(table->buildCTable_wksp));
+ CHECK_F(maxBits);
huffLog = (U32)maxBits;
/* Zero unused symbols in CTable, so we can check it for validity */
memset(table->CTable + (maxSymbolValue + 1), 0,
@@ -719,7 +708,7 @@ static size_t HUF_compress_internal (
if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize,
- singleStream, oldHufTable, bmi2);
+ nbStreams, oldHufTable, bmi2);
} }
/* Use the new huffman table */
@@ -731,7 +720,7 @@ static size_t HUF_compress_internal (
}
return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize,
- singleStream, table->CTable, bmi2);
+ nbStreams, table->CTable, bmi2);
}
@@ -741,7 +730,7 @@ size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
void* workSpace, size_t wkspSize)
{
return HUF_compress_internal(dst, dstSize, src, srcSize,
- maxSymbolValue, huffLog, 1 /*single stream*/,
+ maxSymbolValue, huffLog, HUF_singleStream,
workSpace, wkspSize,
NULL, NULL, 0, 0 /*bmi2*/);
}
@@ -753,7 +742,7 @@ size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int
bmi2)
{
return HUF_compress_internal(dst, dstSize, src, srcSize,
- maxSymbolValue, huffLog, 1 /*single stream*/,
+ maxSymbolValue, huffLog, HUF_singleStream,
workSpace, wkspSize, hufTable,
repeat, preferRepeat, bmi2);
}
@@ -762,17 +751,8 @@ size_t HUF_compress1X (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog)
{
- unsigned* workSpace = ExAllocatePoolWithTag(NonPagedPool, sizeof(unsigned) *
HUF_WORKSPACE_SIZE_U32, HUFC_ALLOC_TAG);
- size_t ret;
-
- if (!workSpace)
- return 0;
-
- ret = HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog,
workSpace, sizeof(unsigned) * HUF_WORKSPACE_SIZE_U32);
-
- ExFreePool(workSpace);
-
- return ret;
+ unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
+ return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog,
workSpace, sizeof(workSpace));
}
/* HUF_compress4X_repeat():
@@ -784,7 +764,7 @@ size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
void* workSpace, size_t wkspSize)
{
return HUF_compress_internal(dst, dstSize, src, srcSize,
- maxSymbolValue, huffLog, 0 /*4 streams*/,
+ maxSymbolValue, huffLog, HUF_fourStreams,
workSpace, wkspSize,
NULL, NULL, 0, 0 /*bmi2*/);
}
@@ -799,7 +779,7 @@ size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int
bmi2)
{
return HUF_compress_internal(dst, dstSize, src, srcSize,
- maxSymbolValue, huffLog, 0 /* 4 streams */,
+ maxSymbolValue, huffLog, HUF_fourStreams,
workSpace, wkspSize,
hufTable, repeat, preferRepeat, bmi2);
}
@@ -808,17 +788,8 @@ size_t HUF_compress2 (void* dst, size_t dstSize,
const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog)
{
- unsigned* workSpace = ExAllocatePoolWithTag(NonPagedPool, sizeof(unsigned) *
HUF_WORKSPACE_SIZE_U32, HUFC_ALLOC_TAG);
- size_t ret;
-
- if (!workSpace)
- return 0;
-
- ret = HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog,
workSpace, sizeof(unsigned) * HUF_WORKSPACE_SIZE_U32);
-
- ExFreePool(workSpace);
-
- return ret;
+ unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
+ return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog,
workSpace, sizeof(workSpace));
}
size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
diff --git a/drivers/filesystems/btrfs/zstd/huf_decompress.c
b/drivers/filesystems/btrfs/zstd/huf_decompress.c
index 51bb417f179..ab5db481c36 100644
--- a/drivers/filesystems/btrfs/zstd/huf_decompress.c
+++ b/drivers/filesystems/btrfs/zstd/huf_decompress.c
@@ -1,35 +1,15 @@
/* ******************************************************************
- huff0 huffman decoder,
- part of Finite State Entropy library
- Copyright (C) 2013-present, Yann Collet.
-
- BSD 2-Clause License (
http://www.opensource.org/licenses/bsd-license.php)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
... 19742 lines suppressed ...