https://git.reactos.org/?p=reactos.git;a=commitdiff;h=060427353554079bdae3d9...
commit 060427353554079bdae3d94cb8e53924d3c3cb16 Author: Vincent Franchomme franchomme.vincent@gmail.com AuthorDate: Thu Apr 28 21:33:48 2022 +0200 Commit: Hermès BÉLUSCA - MAÏTO hermes.belusca-maito@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 ...