From 194ea909fdff60294ce2d5434cbded63f5377754 Mon Sep 17 00:00:00 2001 From: Victor Perevertkin Date: Thu, 23 Apr 2020 05:38:57 +0300 Subject: [PATCH] [BTRFS][UBTRFS][SHELLBTRFS] Upgrade to 1.7.2 CORE-16679 --- dll/shellext/shellbtrfs/balance.cpp | 12 +- dll/shellext/shellbtrfs/devices.cpp | 2 +- dll/shellext/shellbtrfs/main.cpp | 2 +- dll/shellext/shellbtrfs/resource.h | 10 +- dll/shellext/shellbtrfs/shellbtrfs.rc | 99 +- dll/shellext/shellbtrfs/volpropsheet.cpp | 12 +- dll/win32/ubtrfs/resource.h | 1 + dll/win32/ubtrfs/ubtrfs.rc | 10 +- drivers/filesystems/btrfs/CMakeLists.txt | 14 +- drivers/filesystems/btrfs/balance.c | 248 ++-- drivers/filesystems/btrfs/blake2-impl.h | 194 +++ drivers/filesystems/btrfs/blake2b-ref.c | 245 ++++ drivers/filesystems/btrfs/boot.c | 535 +++++--- drivers/filesystems/btrfs/btrfs.c | 646 +++++++--- drivers/filesystems/btrfs/btrfs.h | 12 +- drivers/filesystems/btrfs/btrfs.rc | 10 +- drivers/filesystems/btrfs/btrfs_drv.h | 155 ++- drivers/filesystems/btrfs/calcthread.c | 306 ++++- drivers/filesystems/btrfs/compress.c | 1087 +++++++++-------- drivers/filesystems/btrfs/crc32c-amd64.S | 112 ++ drivers/filesystems/btrfs/crc32c-x86.S | 122 ++ drivers/filesystems/btrfs/crc32c.c | 86 +- drivers/filesystems/btrfs/crc32c.h | 13 + drivers/filesystems/btrfs/create.c | 279 +++-- drivers/filesystems/btrfs/devctrl.c | 23 +- drivers/filesystems/btrfs/dirctrl.c | 61 +- drivers/filesystems/btrfs/extent-tree.c | 209 ++-- drivers/filesystems/btrfs/fastio.c | 6 +- drivers/filesystems/btrfs/fileinfo.c | 212 ++-- drivers/filesystems/btrfs/flushthread.c | 718 ++++++----- drivers/filesystems/btrfs/free-space.c | 131 +- drivers/filesystems/btrfs/fsctl.c | 217 ++-- drivers/filesystems/btrfs/galois.c | 4 +- drivers/filesystems/btrfs/pnp.c | 14 +- drivers/filesystems/btrfs/read.c | 936 +++++++++----- drivers/filesystems/btrfs/registry.c | 71 +- drivers/filesystems/btrfs/reparse.c | 36 +- drivers/filesystems/btrfs/resource.h | 2 +- drivers/filesystems/btrfs/scrub.c | 307 +++-- drivers/filesystems/btrfs/search.c | 83 +- drivers/filesystems/btrfs/security.c | 133 +- drivers/filesystems/btrfs/send.c | 261 ++-- drivers/filesystems/btrfs/sha256.c | 221 ++++ drivers/filesystems/btrfs/treefuncs.c | 75 +- drivers/filesystems/btrfs/volume.c | 46 +- drivers/filesystems/btrfs/worker-thread.c | 14 +- drivers/filesystems/btrfs/write.c | 362 +++--- drivers/filesystems/btrfs/{zstd => }/xxhash.c | 32 +- drivers/filesystems/btrfs/{zstd => }/xxhash.h | 0 .../filesystems/btrfs/zstd/zstd_internal.h | 2 +- media/doc/README.FSD | 6 +- media/inf/btrfs.inf | 30 +- sdk/lib/fslib/btrfslib/CMakeLists.txt | 18 +- sdk/lib/fslib/btrfslib/btrfslib.c | 247 ++-- 54 files changed, 5525 insertions(+), 3164 deletions(-) create mode 100644 drivers/filesystems/btrfs/blake2-impl.h create mode 100644 drivers/filesystems/btrfs/blake2b-ref.c create mode 100644 drivers/filesystems/btrfs/crc32c-amd64.S create mode 100644 drivers/filesystems/btrfs/crc32c-x86.S create mode 100644 drivers/filesystems/btrfs/crc32c.h create mode 100644 drivers/filesystems/btrfs/sha256.c rename drivers/filesystems/btrfs/{zstd => }/xxhash.c (98%) rename drivers/filesystems/btrfs/{zstd => }/xxhash.h (100%) diff --git a/dll/shellext/shellbtrfs/balance.cpp b/dll/shellext/shellbtrfs/balance.cpp index 11503112410..b73978167fc 100644 --- a/dll/shellext/shellbtrfs/balance.cpp +++ b/dll/shellext/shellbtrfs/balance.cpp @@ -383,6 +383,8 @@ void BtrfsBalance::SaveBalanceOpts(HWND hwndDlg) { if (IsDlgButtonChecked(hwndDlg, IDC_PROFILES_RAID10) == BST_CHECKED) opts->profiles |= BLOCK_FLAG_RAID10; if (IsDlgButtonChecked(hwndDlg, IDC_PROFILES_RAID5) == BST_CHECKED) opts->profiles |= BLOCK_FLAG_RAID5; if (IsDlgButtonChecked(hwndDlg, IDC_PROFILES_RAID6) == BST_CHECKED) opts->profiles |= BLOCK_FLAG_RAID6; + if (IsDlgButtonChecked(hwndDlg, IDC_PROFILES_RAID1C3) == BST_CHECKED) opts->profiles |= BLOCK_FLAG_RAID1C3; + if (IsDlgButtonChecked(hwndDlg, IDC_PROFILES_RAID1C4) == BST_CHECKED) opts->profiles |= BLOCK_FLAG_RAID1C4; } if (IsDlgButtonChecked(hwndDlg, IDC_DEVID) == BST_CHECKED) { @@ -515,7 +517,7 @@ INT_PTR CALLBACK BtrfsBalance::BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARA HWND devcb, convcb; btrfs_device* bd; btrfs_balance_opts* opts; - static int convtypes[] = { IDS_SINGLE2, IDS_DUP, IDS_RAID0, IDS_RAID1, IDS_RAID5, IDS_RAID6, IDS_RAID10, 0 }; + static int convtypes[] = { IDS_SINGLE2, IDS_DUP, IDS_RAID0, IDS_RAID1, IDS_RAID5, IDS_RAID1C3, IDS_RAID6, IDS_RAID10, IDS_RAID1C4, 0 }; int i, num_devices = 0, num_writeable_devices = 0; wstring s, u; bool balance_started = balance_status & (BTRFS_BALANCE_RUNNING | BTRFS_BALANCE_PAUSED); @@ -601,7 +603,7 @@ INT_PTR CALLBACK BtrfsBalance::BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARA break; else if (num_writeable_devices < 3 && i == 4) break; - else if (num_writeable_devices < 4 && i == 5) + else if (num_writeable_devices < 4 && i == 6) break; } @@ -615,6 +617,8 @@ INT_PTR CALLBACK BtrfsBalance::BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARA CheckDlgButton(hwndDlg, IDC_PROFILES_RAID10, opts->profiles & BLOCK_FLAG_RAID10 ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_PROFILES_RAID5, opts->profiles & BLOCK_FLAG_RAID5 ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwndDlg, IDC_PROFILES_RAID6, opts->profiles & BLOCK_FLAG_RAID6 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_RAID1C3, opts->profiles & BLOCK_FLAG_RAID1C3 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PROFILES_RAID1C4, opts->profiles & BLOCK_FLAG_RAID1C4 ? BST_CHECKED : BST_UNCHECKED); EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_SINGLE), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_DUP), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); @@ -623,6 +627,8 @@ INT_PTR CALLBACK BtrfsBalance::BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARA EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID10), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID5), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID6), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID1C3), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID1C4), !balance_started && opts->flags & BTRFS_BALANCE_OPTS_PROFILES ? true : false); EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES), balance_started ? false : true); // usage @@ -752,6 +758,8 @@ INT_PTR CALLBACK BtrfsBalance::BalanceOptsDlgProc(HWND hwndDlg, UINT uMsg, WPARA EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID10), enabled); EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID5), enabled); EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID6), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID1C3), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROFILES_RAID1C4), enabled); break; } diff --git a/dll/shellext/shellbtrfs/devices.cpp b/dll/shellext/shellbtrfs/devices.cpp index dfa10647256..e95cace5c52 100755 --- a/dll/shellext/shellbtrfs/devices.cpp +++ b/dll/shellext/shellbtrfs/devices.cpp @@ -205,7 +205,7 @@ static void find_devices(HWND hwnd, const GUID* guid, const mountmgr& mm, vector if (ss > 0) { WCHAR* desc3 = (WCHAR*)malloc(ss * sizeof(WCHAR)); - if (MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, desc2.c_str(), -1, desc3, (int)(ss * sizeof(WCHAR)))) + if (MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, desc2.c_str(), -1, desc3, ss)) dev.friendly_name = desc3; free(desc3); diff --git a/dll/shellext/shellbtrfs/main.cpp b/dll/shellext/shellbtrfs/main.cpp index d11b81e9f82..9ba209ab664 100755 --- a/dll/shellext/shellbtrfs/main.cpp +++ b/dll/shellext/shellbtrfs/main.cpp @@ -327,7 +327,7 @@ static void register_clsid(const GUID clsid, const WCHAR* description) { write_reg_key(HKEY_CLASSES_ROOT, clsidkeyname, nullptr, description); - GetModuleFileNameW(module, dllpath, sizeof(dllpath)); + GetModuleFileNameW(module, dllpath, sizeof(dllpath) / sizeof(WCHAR)); write_reg_key(HKEY_CLASSES_ROOT, inproc, nullptr, dllpath); diff --git a/dll/shellext/shellbtrfs/resource.h b/dll/shellext/shellbtrfs/resource.h index da6f5bd3627..d48bec6ae16 100755 --- a/dll/shellext/shellbtrfs/resource.h +++ b/dll/shellext/shellbtrfs/resource.h @@ -1,4 +1,4 @@ -//{{NO_DEPENDENCIES}} +//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by shellbtrfs.rc // @@ -134,6 +134,7 @@ #define IDS_OUT_OF_MEMORY 215 #define IDS_RECV_UNKNOWN_COMMAND 216 #define IDS_RECV_CANT_OPEN_PATH 217 +#define IDS_RAID1C3 218 #define IDS_RECV_CREATE_SUBVOL_FAILED 219 #define IDS_RECV_MISSING_PARAM 220 #define IDS_RECV_SHORT_PARAM 221 @@ -145,6 +146,7 @@ #define IDS_RECV_CREATEHARDLINK_FAILED 227 #define IDS_RECV_SETENDOFFILE_FAILED 228 #define IDS_RECV_CANT_CREATE_FILE 229 +#define IDS_RAID1C4 230 #define IDS_RECV_SETINODEINFO_FAILED 231 #define IDS_RECV_SUCCESS 232 #define IDS_RECV_BUTTON_OK 233 @@ -309,7 +311,9 @@ #define IDC_SOFT 1057 #define IDC_PAUSE_SCRUB 1057 #define IDC_CANCEL_SCRUB 1058 +#define IDC_PROFILES_RAID1C3 1058 #define IDC_SCRUB_PROGRESS 1059 +#define IDC_PROFILES_RAID1C4 1059 #define IDC_SCRUB_STATUS 1060 #define IDC_COMPRESS_TYPE 1061 #define IDC_CHECK1 1062 @@ -334,10 +338,10 @@ #define IDC_DRIVE_LETTER_COMBO 1074 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 178 +#define _APS_NEXT_RESOURCE_VALUE 179 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1075 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/dll/shellext/shellbtrfs/shellbtrfs.rc b/dll/shellext/shellbtrfs/shellbtrfs.rc index 0adfa2c6cf5..86034752e45 100755 --- a/dll/shellext/shellbtrfs/shellbtrfs.rc +++ b/dll/shellext/shellbtrfs/shellbtrfs.rc @@ -25,18 +25,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#include ""winres.h""\r\n" "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "\r\n" "\0" @@ -61,8 +61,8 @@ IDI_ICON1 ICON "subvol.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,0,0 - PRODUCTVERSION 1,5,0,0 + FILEVERSION 1,7,2,0 + PRODUCTVERSION 1,7,2,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -78,12 +78,12 @@ BEGIN BLOCK "080904b0" BEGIN VALUE "FileDescription", "WinBtrfs shell extension" - VALUE "FileVersion", "1.5" + VALUE "FileVersion", "1.7.2" VALUE "InternalName", "btrfs" - VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-19" + VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-20" VALUE "OriginalFilename", "shellbtrfs.dll" VALUE "ProductName", "WinBtrfs" - VALUE "ProductVersion", "1.5" + VALUE "ProductVersion", "1.7.2" END END BLOCK "VarFileInfo" @@ -112,8 +112,8 @@ BEGIN LTEXT "Group:",IDC_STATIC,14,141,22,8 EDITTEXT IDC_UID,94,123,40,14,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_GID,94,139,40,14,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "User",IDC_STATIC,14,172,15,8 - LTEXT "Group",IDC_STATIC,14,182,20,8 + LTEXT "User",IDC_STATIC,14,175,15,8 + LTEXT "Group",IDC_STATIC,14,186,20,8 LTEXT "Others",IDC_STATIC,14,196,22,8 LTEXT "Read",IDC_STATIC,50,162,17,8 LTEXT "Write",IDC_STATIC,89,162,18,8 @@ -209,9 +209,11 @@ BEGIN CONTROL "DUP",IDC_PROFILES_DUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,30,29,10 CONTROL "RAID0",IDC_PROFILES_RAID0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,41,36,10 CONTROL "RAID1",IDC_PROFILES_RAID1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,52,36,10 - CONTROL "RAID10",IDC_PROFILES_RAID10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,19,39,10 - CONTROL "RAID5",IDC_PROFILES_RAID5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,30,36,10 - CONTROL "RAID6",IDC_PROFILES_RAID6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,41,36,10 + CONTROL "RAID10",IDC_PROFILES_RAID10,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,63,39,10 + CONTROL "RAID5",IDC_PROFILES_RAID5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,19,36,10 + CONTROL "RAID6",IDC_PROFILES_RAID6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,30,36,10 + CONTROL "RAID1C3",IDC_PROFILES_RAID1C3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,41,44,10 + CONTROL "RAID1C4",IDC_PROFILES_RAID1C4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,52,44,10 CONTROL "&Usage:",IDC_USAGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,80,37,10 EDITTEXT IDC_USAGE_START,7,94,19,14,ES_AUTOHSCROLL | ES_NUMBER CONTROL "",IDC_USAGE_START_SPINNER,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,25,94,11,14 @@ -535,6 +537,11 @@ BEGIN 0 END +IDD_BALANCE_OPTIONS AFX_DIALOG_LAYOUT +BEGIN + 0 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -627,9 +634,9 @@ BEGIN IDS_DEVLIST_READONLY_NO "No" IDS_DEVLIST_ALLOC "Allocated" IDS_DEVLIST_ALLOC_PC "%" - IDS_BALANCE_RUNNING_REMOVAL + IDS_BALANCE_RUNNING_REMOVAL "Currently removing device %llu (%llu out of %llu chunks processed, %1.1f%%)" - IDS_BALANCE_PAUSED_REMOVAL + IDS_BALANCE_PAUSED_REMOVAL "Removal of device %llu paused (%llu out of %llu chunks processed, %1.1f%%)" IDS_BALANCE_CANCELLED_REMOVAL "Device removal cancelled." IDS_BALANCE_COMPLETE_REMOVAL "Device removal completed successfully." @@ -640,12 +647,12 @@ END STRINGTABLE BEGIN IDS_CANNOT_REMOVE_RAID "The current RAID levels do not allow this device to be removed. You must do a conversion balance before you will be able to proceed." - IDS_REMOVE_DEVICE_CONFIRMATION + IDS_REMOVE_DEVICE_CONFIRMATION "Are you sure that you want to remove device %s, %s?" IDS_CONFIRMATION_TITLE "Confirmation" - IDS_ADD_DEVICE_CONFIRMATION + IDS_ADD_DEVICE_CONFIRMATION "Are you sure that you want to add this device?" - IDS_ADD_DEVICE_CONFIRMATION_FS + IDS_ADD_DEVICE_CONFIRMATION_FS "Are you sure that you want to add this device? It already appears to contain a filesystem (%s)." IDS_BALANCE_FAILED "Balance failed (error %08x, %s)" IDS_BALANCE_FAILED_REMOVAL "Device removal failed (error %08x, %s)" @@ -656,32 +663,32 @@ BEGIN IDS_SCRUB_FINISHED "Scrub finished." IDS_SCRUB_PAUSED "Scrub paused (%llu out of %llu chunks processed, %1.1f%%)" IDS_SCRUB_MSG_STARTED "Scrub started at %s %s." - IDS_SCRUB_MSG_RECOVERABLE_DATA + IDS_SCRUB_MSG_RECOVERABLE_DATA "Recovered from data checksum error at %llx on device %llx." - IDS_SCRUB_MSG_RECOVERABLE_METADATA + IDS_SCRUB_MSG_RECOVERABLE_METADATA "Recovered from metadata checksum error at %llx on device %llx." END STRINGTABLE BEGIN - IDS_SCRUB_MSG_UNRECOVERABLE_DATA + IDS_SCRUB_MSG_UNRECOVERABLE_DATA "Unrecoverable data checksum error at %llx on device %llx (%.*s, offset %llx)" - IDS_SCRUB_MSG_UNRECOVERABLE_DATA_SUBVOL + IDS_SCRUB_MSG_UNRECOVERABLE_DATA_SUBVOL "Unrecoverable data checksum error at %llx on device %llx (subvol %llx, %.*s, offset %llx)" - IDS_SCRUB_MSG_UNRECOVERABLE_METADATA + IDS_SCRUB_MSG_UNRECOVERABLE_METADATA "Unrecoverable metadata checksum error at %llx on device %llx (root %llx, level %x)" - IDS_SCRUB_MSG_UNRECOVERABLE_METADATA_FIRSTITEM + IDS_SCRUB_MSG_UNRECOVERABLE_METADATA_FIRSTITEM "Unrecoverable metadata checksum error at %llx on device %llx (root %llx, level %x, first item %llx,%x,%llx)" IDS_SCRUB_MSG_FINISHED "Scrub finished at %s %s." IDS_SCRUB_MSG_SUMMARY "Scrubbed %s in %llu seconds (%s/s)." IDS_BALANCE_SCRUB_RUNNING "Cannot start balance while scrub running." IDS_SCRUB_BALANCE_RUNNING "Cannot start scrub while balance running." IDS_SCRUB_MSG_SUMMARY_ERRORS_RECOVERABLE "Recovered from %llu error(s)." - IDS_SCRUB_MSG_SUMMARY_ERRORS_UNRECOVERABLE + IDS_SCRUB_MSG_SUMMARY_ERRORS_UNRECOVERABLE "%llu unrecoverable error(s) found." IDS_SCRUB_FAILED "Scrub failed with error %08x." IDS_LOCK_FAILED "Unable to lock volume: error %08x. Make sure that there are no files open, and that you have closed any Explorer windows." - IDS_SCRUB_MSG_RECOVERABLE_PARITY + IDS_SCRUB_MSG_RECOVERABLE_PARITY "Recovered from parity error at %llx on device %llx." IDS_COMPRESS_ANY "(any)" IDS_COMPRESS_ZLIB "Zlib" @@ -700,12 +707,13 @@ BEGIN IDS_OUT_OF_MEMORY "Out of memory." IDS_RECV_UNKNOWN_COMMAND "Unrecognized command %u encountered." IDS_RECV_CANT_OPEN_PATH "Couldn't open path %s (error %u, %s)." - IDS_RECV_CREATE_SUBVOL_FAILED + IDS_RAID1C3 "RAID1C3" + IDS_RECV_CREATE_SUBVOL_FAILED "FSCTL_BTRFS_CREATE_SUBVOL returned %08x (%s)." IDS_RECV_MISSING_PARAM "%S: could not find %s parameter." IDS_RECV_SHORT_PARAM "%S: length of parameter %s was %u, expected %u." IDS_RECV_MKNOD_FAILED "FSCTL_BTRFS_MKNOD returned %08x (%s)." - IDS_RECV_SET_REPARSE_POINT_FAILED + IDS_RECV_SET_REPARSE_POINT_FAILED "FSCTL_SET_REPARSE_POINT returned %08x (%s)." END @@ -714,17 +722,18 @@ BEGIN IDS_RECV_MOVEFILE_FAILED "MoveFile (%s -> %s) failed (error %u, %s)." IDS_RECV_SETFILEPOINTER_FAILED "SetFilePointer failed (error %u, %s)." IDS_RECV_WRITEFILE_FAILED "WriteFile failed (error %u, %s)." - IDS_RECV_CREATEHARDLINK_FAILED + IDS_RECV_CREATEHARDLINK_FAILED "CreateHardLink (%s -> %s) failed (error %u, %s)." IDS_RECV_SETENDOFFILE_FAILED "SetEndOfFile failed (error %u, %s)." IDS_RECV_CANT_CREATE_FILE "Couldn't create %s (error %u, %s)." - IDS_RECV_SETINODEINFO_FAILED + IDS_RAID1C4 "RAID1C4" + IDS_RECV_SETINODEINFO_FAILED "FSCTL_BTRFS_SET_INODE_INFO returned %08x (%s)." IDS_RECV_SUCCESS "Received 1 subvolume successfully." IDS_RECV_BUTTON_OK "OK" - IDS_RECV_SETFILEATTRIBUTES_FAILED + IDS_RECV_SETFILEATTRIBUTES_FAILED "SetFileAttributes failed (error %u, %s)." - IDS_RECV_GETFILEATTRIBUTES_FAILED + IDS_RECV_GETFILEATTRIBUTES_FAILED "GetFileAttributes failed (error %u, %s)." IDS_RECV_CSUM_ERROR "Checksum error." IDS_RECV_NOT_A_SEND_STREAM "File was not a send stream." @@ -734,28 +743,28 @@ END STRINGTABLE BEGIN - IDS_RECV_RECEIVED_SUBVOL_FAILED + IDS_RECV_RECEIVED_SUBVOL_FAILED "FSCTL_BTRFS_RECEIVED_SUBVOL returned %08x (%s)." - IDS_RECV_SETSECURITYOBJECT_FAILED + IDS_RECV_SETSECURITYOBJECT_FAILED "NtSetSecurityObject returned %08x (%s)." IDS_RECV_SETXATTR_FAILED "FSCTL_BTRFS_SET_XATTR returned %08x (%s)." IDS_RECV_CREATETHREAD_FAILED "CreateThread failed (error %u, %s)." IDS_RECV_FILE_TRUNCATED "File was truncated." - IDS_RECV_RESERVE_SUBVOL_FAILED + IDS_RECV_RESERVE_SUBVOL_FAILED "FSCTL_BTRFS_RESERVE_SUBVOL returned %08x (%s)." IDS_RECV_CANCELLED "Receiving cancelled." IDS_RECV_CANT_FIND_PARENT_SUBVOL "Could not find parent subvolume." IDS_RECV_FIND_SUBVOL_FAILED "FSCTL_BTRFS_FIND_SUBVOL returned %08x (%s)." - IDS_RECV_CREATE_SNAPSHOT_FAILED + IDS_RECV_CREATE_SNAPSHOT_FAILED "FSCTL_BTRFS_CREATE_SNAPSHOT returned %08x (%s)." - IDS_RECV_GETVOLUMEPATHNAME_FAILED + IDS_RECV_GETVOLUMEPATHNAME_FAILED "GetVolumePathName failed (error %u, %s)." IDS_RECV_DELETEFILE_FAILED "DeleteFile failed for %s (error %u, %s)." - IDS_RECV_REMOVEDIRECTORY_FAILED + IDS_RECV_REMOVEDIRECTORY_FAILED "RemoveDirectory failed for %s (error %u, %s)." IDS_RECV_CANT_FIND_CLONE_SUBVOL "Could not find clone subvolume." IDS_RECV_GETFILESIZEEX_FAILED "GetFileSizeEx failed (error %u, %s)." - IDS_RECV_DUPLICATE_EXTENTS_FAILED + IDS_RECV_DUPLICATE_EXTENTS_FAILED "FSCTL_DUPLICATE_EXTENTS_TO_FILE returned %08x (%s)." END @@ -766,13 +775,13 @@ BEGIN IDS_SEND_SUBVOL_HELP "Exports a subvolume so that it can be recreated on another volume." IDS_SEND_CANT_OPEN_FILE "Error opening file %s (error %u, %s)." IDS_SEND_CANT_OPEN_DIR "Error opening directory %s (error %u, %s)." - IDS_SEND_FSCTL_BTRFS_SEND_SUBVOL_FAILED + IDS_SEND_FSCTL_BTRFS_SEND_SUBVOL_FAILED "FSCTL_BTRFS_SEND_SUBVOL returned error %08x (%s)." - IDS_SEND_FSCTL_BTRFS_READ_SEND_BUFFER_FAILED + IDS_SEND_FSCTL_BTRFS_READ_SEND_BUFFER_FAILED "FSCTL_BTRFS_READ_SEND_BUFFER returned error %08x (%s)." IDS_SEND_SUCCESS "Stream written successfully." IDS_SEND_WRITEFILE_FAILED "Writing to file failed (error %u, %s)." - IDS_SEND_GET_FILE_INFO_FAILED + IDS_SEND_GET_FILE_INFO_FAILED "GetFileInformationByHandle failed (error %u, %s)." IDS_SEND_NOT_READONLY "Subvolume not readonly." IDS_NOT_SUBVOL "Directory was not a subvolume." @@ -788,9 +797,9 @@ BEGIN IDS_SEND_WRITING "Writing..." IDS_MISSING "(missing)" IDS_RESIZE_SUCCESSFUL "Device %llx successfully resized to %s." - IDS_BALANCE_RUNNING_SHRINK + IDS_BALANCE_RUNNING_SHRINK "Currently shrinking device %llu (%llu out of %llu chunks processed, %1.1f%%)" - IDS_BALANCE_PAUSED_SHRINK + IDS_BALANCE_PAUSED_SHRINK "Shrinking of device %llu paused (%llu out of %llu chunks processed, %1.1f%%)" IDS_BALANCE_CANCELLED_SHRINK "Device shrinking cancelled." IDS_BALANCE_COMPLETE_SHRINK "Device successfully shrunk." @@ -799,7 +808,7 @@ BEGIN IDS_REGCREATEKEY_FAILED "RegCreateKey returned %08x" IDS_REGSETVALUEEX_FAILED "RegSetValueEx returned %08x" IDS_REGCLOSEKEY_FAILED "RegCloseKey returned %08x" - IDS_CANT_REFLINK_DIFFERENT_FS + IDS_CANT_REFLINK_DIFFERENT_FS "Cannot create a reflink between two different filesystems." END diff --git a/dll/shellext/shellbtrfs/volpropsheet.cpp b/dll/shellext/shellbtrfs/volpropsheet.cpp index 9c23456d2b5..97de35ae3e1 100755 --- a/dll/shellext/shellbtrfs/volpropsheet.cpp +++ b/dll/shellext/shellbtrfs/volpropsheet.cpp @@ -172,8 +172,12 @@ void BtrfsVolPropSheet::FormatUsage(HWND hwndDlg, wstring& s, btrfs_usage* usage static const uint64_t types[] = { BLOCK_FLAG_DATA, BLOCK_FLAG_DATA | BLOCK_FLAG_METADATA, BLOCK_FLAG_METADATA, BLOCK_FLAG_SYSTEM }; static const ULONG typestrings[] = { IDS_USAGE_DATA, IDS_USAGE_MIXED, IDS_USAGE_METADATA, IDS_USAGE_SYSTEM }; - static const uint64_t duptypes[] = { 0, BLOCK_FLAG_DUPLICATE, BLOCK_FLAG_RAID0, BLOCK_FLAG_RAID1, BLOCK_FLAG_RAID10, BLOCK_FLAG_RAID5, BLOCK_FLAG_RAID6 }; - static const ULONG dupstrings[] = { IDS_SINGLE, IDS_DUP, IDS_RAID0, IDS_RAID1, IDS_RAID10, IDS_RAID5, IDS_RAID6 }; + static const uint64_t duptypes[] = { 0, BLOCK_FLAG_DUPLICATE, BLOCK_FLAG_RAID0, BLOCK_FLAG_RAID1, BLOCK_FLAG_RAID10, BLOCK_FLAG_RAID5, + BLOCK_FLAG_RAID6, BLOCK_FLAG_RAID1C3, BLOCK_FLAG_RAID1C4 }; + static const ULONG dupstrings[] = { IDS_SINGLE, IDS_DUP, IDS_RAID0, IDS_RAID1, IDS_RAID10, IDS_RAID5, IDS_RAID6, IDS_RAID1C3, IDS_RAID1C4 }; + + static const uint64_t raid_types = BLOCK_FLAG_DUPLICATE | BLOCK_FLAG_RAID0 | BLOCK_FLAG_RAID1 | BLOCK_FLAG_RAID10 | BLOCK_FLAG_RAID5 | + BLOCK_FLAG_RAID6 | BLOCK_FLAG_RAID1C3 | BLOCK_FLAG_RAID1C4; s = L""; @@ -327,9 +331,7 @@ void BtrfsVolPropSheet::FormatUsage(HWND hwndDlg, wstring& s, btrfs_usage* usage bue = usage; while (true) { - if ((bue->type & types[i]) == types[i] && - ((duptypes[j] == 0 && (bue->type & (BLOCK_FLAG_DUPLICATE | BLOCK_FLAG_RAID0 | BLOCK_FLAG_RAID1 | BLOCK_FLAG_RAID10 | BLOCK_FLAG_RAID5 | BLOCK_FLAG_RAID6)) == 0) - || bue->type & duptypes[j])) { + if ((bue->type & types[i]) == types[i] && ((duptypes[j] == 0 && (bue->type & raid_types) == 0) || bue->type & duptypes[j])) { wstring sizestring, usedstring, typestring, dupstring; if (bue->type & BLOCK_FLAG_DATA && bue->type & BLOCK_FLAG_METADATA && (types[i] == BLOCK_FLAG_DATA || types[i] == BLOCK_FLAG_METADATA)) diff --git a/dll/win32/ubtrfs/resource.h b/dll/win32/ubtrfs/resource.h index f805e977efd..fbccb724bc5 100644 --- a/dll/win32/ubtrfs/resource.h +++ b/dll/win32/ubtrfs/resource.h @@ -1,6 +1,7 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ubtrfs.rc +// // Next default values for new objects // diff --git a/dll/win32/ubtrfs/ubtrfs.rc b/dll/win32/ubtrfs/ubtrfs.rc index 1720597df5b..e43daf348e7 100644 --- a/dll/win32/ubtrfs/ubtrfs.rc +++ b/dll/win32/ubtrfs/ubtrfs.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,0,0 - PRODUCTVERSION 1,5,0,0 + FILEVERSION 1,7,2,0 + PRODUCTVERSION 1,7,2,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BLOCK "080904b0" BEGIN VALUE "FileDescription", "Btrfs utility DLL" - VALUE "FileVersion", "1.5" + VALUE "FileVersion", "1.7.2" VALUE "InternalName", "ubtrfs" - VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-19" + VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-20" VALUE "OriginalFilename", "ubtrfs.dll" VALUE "ProductName", "WinBtrfs" - VALUE "ProductVersion", "1.5" + VALUE "ProductVersion", "1.7.2" END END BLOCK "VarFileInfo" diff --git a/drivers/filesystems/btrfs/CMakeLists.txt b/drivers/filesystems/btrfs/CMakeLists.txt index 14e78425fed..b45a57cb470 100644 --- a/drivers/filesystems/btrfs/CMakeLists.txt +++ b/drivers/filesystems/btrfs/CMakeLists.txt @@ -5,6 +5,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/drivers list(APPEND SOURCE balance.c + blake2b-ref.c boot.c btrfs.c cache.c @@ -30,11 +31,13 @@ list(APPEND SOURCE scrub.c search.c security.c + sha256.c send.c treefuncs.c volume.c worker-thread.c write.c + xxhash.c zstd/entropy_common.c zstd/fse_compress.c zstd/hist.c @@ -46,14 +49,21 @@ list(APPEND SOURCE zstd/error_private.c zstd/fse_decompress.c zstd/huf_compress.c - zstd/xxhash.c zstd/zstd_compress.c zstd/zstd_double_fast.c zstd/zstd_lazy.c zstd/zstd_opt.c btrfs_drv.h) -add_library(btrfs MODULE ${SOURCE} btrfs.rc) +if(ARCH STREQUAL "i386") + list(APPEND ASM_SOURCE crc32c-x86.S) +elseif(ARCH STREQUAL "amd64") + list(APPEND ASM_SOURCE crc32c-amd64.S) +endif() + +add_asm_files(btrfs_asm ${ASM_SOURCE}) + +add_library(btrfs MODULE ${SOURCE} ${btrfs_asm} btrfs.rc) add_definitions(-D__KERNEL__) set_module_type(btrfs kernelmodedriver) diff --git a/drivers/filesystems/btrfs/balance.c b/drivers/filesystems/btrfs/balance.c index 1a2c6a2dc6a..fc47f97f608 100644 --- a/drivers/filesystems/btrfs/balance.c +++ b/drivers/filesystems/btrfs/balance.c @@ -17,6 +17,7 @@ #include "btrfs_drv.h" #include "btrfsioctl.h" +#include "crc32c.h" #include typedef struct { @@ -96,7 +97,7 @@ static NTSTATUS add_metadata_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_l Status = delete_tree_item(Vcb, tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(mr); return Status; } @@ -191,7 +192,7 @@ static NTSTATUS add_metadata_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_l Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } else if (tp2.item->key.obj_type == TYPE_SHARED_BLOCK_REF) { @@ -209,7 +210,7 @@ static NTSTATUS add_metadata_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_l Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } @@ -252,7 +253,7 @@ static NTSTATUS add_metadata_reloc_parent(_Requires_exclusive_lock_held_(_Curr_- Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -273,7 +274,7 @@ static NTSTATUS add_metadata_reloc_parent(_Requires_exclusive_lock_held_(_Curr_- Status = add_metadata_reloc(Vcb, items, &tp, skinny, mr2, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_metadata_reloc returned %08x\n", Status); + ERR("add_metadata_reloc returned %08lx\n", Status); return Status; } @@ -414,7 +415,7 @@ static NTSTATUS add_metadata_reloc_extent_item(_Requires_exclusive_lock_held_(_C Status = insert_tree_item(Vcb, Vcb->extent_root, mr->new_address, TYPE_EXTENT_ITEM, Vcb->superblock.node_size, ei, inline_len, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ei); return Status; } @@ -428,13 +429,13 @@ static NTSTATUS add_metadata_reloc_extent_item(_Requires_exclusive_lock_held_(_C if (ref->type == TYPE_TREE_BLOCK_REF) { Status = insert_tree_item(Vcb, Vcb->extent_root, mr->new_address, TYPE_TREE_BLOCK_REF, ref->tbr.offset, NULL, 0, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } } else if (ref->type == TYPE_SHARED_BLOCK_REF) { Status = insert_tree_item(Vcb, Vcb->extent_root, mr->new_address, TYPE_SHARED_BLOCK_REF, ref->parent->new_address, NULL, 0, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } } @@ -458,7 +459,7 @@ static NTSTATUS add_metadata_reloc_extent_item(_Requires_exclusive_lock_held_(_C Status = increase_extent_refcount(Vcb, in[i].address, Vcb->superblock.node_size, TYPE_SHARED_BLOCK_REF, &sbr, NULL, 0, NULL); if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount returned %08x\n", Status); + ERR("increase_extent_refcount returned %08lx\n", Status); return Status; } @@ -467,7 +468,7 @@ static NTSTATUS add_metadata_reloc_extent_item(_Requires_exclusive_lock_held_(_C Status = decrease_extent_refcount(Vcb, in[i].address, Vcb->superblock.node_size, TYPE_SHARED_BLOCK_REF, &sbr, NULL, 0, sbr.offset, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("decrease_extent_refcount returned %08x\n", Status); + ERR("decrease_extent_refcount returned %08lx\n", Status); return Status; } } @@ -495,7 +496,7 @@ static NTSTATUS add_metadata_reloc_extent_item(_Requires_exclusive_lock_held_(_C Status = increase_extent_refcount(Vcb, ed2->address, ed2->size, TYPE_SHARED_DATA_REF, &sdr, NULL, 0, NULL); if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount returned %08x\n", Status); + ERR("increase_extent_refcount returned %08lx\n", Status); return Status; } @@ -504,7 +505,7 @@ static NTSTATUS add_metadata_reloc_extent_item(_Requires_exclusive_lock_held_(_C Status = decrease_extent_refcount(Vcb, ed2->address, ed2->size, TYPE_SHARED_DATA_REF, &sdr, NULL, 0, sdr.offset, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("decrease_extent_refcount returned %08x\n", Status); + ERR("decrease_extent_refcount returned %08lx\n", Status); return Status; } @@ -591,7 +592,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = read_data(Vcb, mr->address, Vcb->superblock.node_size, NULL, true, (uint8_t*)mr->data, c && mr->address >= c->offset && mr->address < c->offset + c->chunk_item->size ? c : NULL, &pc, NULL, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); return Status; } @@ -656,7 +657,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = find_item_to_level(Vcb, r, &tp, firstitem, false, mr->data->level + 1, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) { - ERR("find_item_to_level returned %08x\n", Status); + ERR("find_item_to_level returned %08lx\n", Status); return Status; } @@ -672,7 +673,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = add_metadata_reloc_parent(Vcb, items, t->header.address, &mr2, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_metadata_reloc_parent returned %08x\n", Status); + ERR("add_metadata_reloc_parent returned %08lx\n", Status); return Status; } @@ -683,7 +684,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = add_metadata_reloc_parent(Vcb, items, ref->sbr.offset, &mr2, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_metadata_reloc_parent returned %08x\n", Status); + ERR("add_metadata_reloc_parent returned %08lx\n", Status); return Status; } @@ -788,7 +789,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = alloc_chunk(Vcb, flags, &newchunk, false); if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->chunk_lock); goto end; } @@ -880,7 +881,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -901,13 +902,13 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); goto end; } Status = insert_tree_item(Vcb, Vcb->root_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, ri, sizeof(ROOT_ITEM), NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); goto end; } } @@ -1025,7 +1026,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree t3 = t4; } - *((uint32_t*)mr->data) = ~calc_crc32c(0xffffffff, (uint8_t*)&mr->data->fs_uuid, Vcb->superblock.node_size - sizeof(mr->data->csum)); + calc_tree_checksum(Vcb, mr->data); tw = ExAllocatePoolWithTag(PagedPool, sizeof(tree_write), ALLOC_TAG); if (!tw) { @@ -1068,7 +1069,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = do_tree_writes(Vcb, &tree_writes, true); if (!NT_SUCCESS(Status)) { - ERR("do_tree_writes returned %08x\n", Status); + ERR("do_tree_writes returned %08lx\n", Status); goto end; } @@ -1078,7 +1079,7 @@ static NTSTATUS write_metadata_items(_Requires_exclusive_lock_held_(_Curr_->tree Status = add_metadata_reloc_extent_item(Vcb, mr); if (!NT_SUCCESS(Status)) { - ERR("add_metadata_reloc_extent_item returned %08x\n", Status); + ERR("add_metadata_reloc_extent_item returned %08lx\n", Status); goto end; } @@ -1121,7 +1122,7 @@ static NTSTATUS balance_metadata_chunk(device_extension* Vcb, chunk* c, bool* ch Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -1149,7 +1150,7 @@ static NTSTATUS balance_metadata_chunk(device_extension* Vcb, chunk* c, bool* ch Status = add_metadata_reloc(Vcb, &items, &tp, skinny, NULL, c, &rollback); if (!NT_SUCCESS(Status)) { - ERR("add_metadata_reloc returned %08x\n", Status); + ERR("add_metadata_reloc returned %08lx\n", Status); goto end; } @@ -1175,7 +1176,7 @@ static NTSTATUS balance_metadata_chunk(device_extension* Vcb, chunk* c, bool* ch Status = write_metadata_items(Vcb, &items, NULL, c, &rollback); if (!NT_SUCCESS(Status)) { - ERR("write_metadata_items returned %08x\n", Status); + ERR("write_metadata_items returned %08lx\n", Status); goto end; } @@ -1187,7 +1188,7 @@ end: if (NT_SUCCESS(Status)) { Status = do_write(Vcb, NULL); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); } if (NT_SUCCESS(Status)) @@ -1241,7 +1242,7 @@ static NTSTATUS data_reloc_add_tree_edr(_Requires_lock_held_(_Curr_->tree_lock) } if (!r) { - ERR("could not find subvol %I64x\n", edr->count); + ERR("could not find subvol %I64x\n", edr->root); return STATUS_INTERNAL_ERROR; } @@ -1251,7 +1252,7 @@ static NTSTATUS data_reloc_add_tree_edr(_Requires_lock_held_(_Curr_->tree_lock) Status = find_item(Vcb, r, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -1293,7 +1294,7 @@ static NTSTATUS data_reloc_add_tree_edr(_Requires_lock_held_(_Curr_->tree_lock) Status = add_metadata_reloc_parent(Vcb, metadata_items, tp.tree->header.address, &mr, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_metadata_reloc_parent returned %08x\n", Status); + ERR("add_metadata_reloc_parent returned %08lx\n", Status); ExFreePool(ref); return Status; } @@ -1338,7 +1339,7 @@ static NTSTATUS add_data_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = delete_tree_item(Vcb, tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1384,7 +1385,7 @@ static NTSTATUS add_data_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = data_reloc_add_tree_edr(Vcb, metadata_items, dr, edr, rollback); if (!NT_SUCCESS(Status)) { - ERR("data_reloc_add_tree_edr returned %08x\n", Status); + ERR("data_reloc_add_tree_edr returned %08lx\n", Status); return Status; } } else if (secttype == TYPE_SHARED_DATA_REF) { @@ -1403,7 +1404,7 @@ static NTSTATUS add_data_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = add_metadata_reloc_parent(Vcb, metadata_items, ref->sdr.offset, &mr, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_metadata_reloc_parent returned %08x\n", Status); + ERR("add_metadata_reloc_parent returned %08lx\n", Status); ExFreePool(ref); return Status; } @@ -1431,13 +1432,13 @@ static NTSTATUS add_data_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_lock) if (tp2.item->key.obj_type == TYPE_EXTENT_DATA_REF && tp2.item->size >= sizeof(EXTENT_DATA_REF)) { Status = data_reloc_add_tree_edr(Vcb, metadata_items, dr, (EXTENT_DATA_REF*)tp2.item->data, rollback); if (!NT_SUCCESS(Status)) { - ERR("data_reloc_add_tree_edr returned %08x\n", Status); + ERR("data_reloc_add_tree_edr returned %08lx\n", Status); return Status; } Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } else if (tp2.item->key.obj_type == TYPE_SHARED_DATA_REF && tp2.item->size >= sizeof(uint32_t)) { @@ -1456,7 +1457,7 @@ static NTSTATUS add_data_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = add_metadata_reloc_parent(Vcb, metadata_items, ref->sdr.offset, &mr, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_metadata_reloc_parent returned %08x\n", Status); + ERR("add_metadata_reloc_parent returned %08lx\n", Status); ExFreePool(ref); return Status; } @@ -1466,7 +1467,7 @@ static NTSTATUS add_data_reloc(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } @@ -1620,7 +1621,7 @@ static NTSTATUS add_data_reloc_extent_item(_Requires_exclusive_lock_held_(_Curr_ Status = insert_tree_item(Vcb, Vcb->extent_root, dr->new_address, TYPE_EXTENT_ITEM, dr->size, ei, inline_len, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1643,7 +1644,7 @@ static NTSTATUS add_data_reloc_extent_item(_Requires_exclusive_lock_held_(_Curr_ Status = insert_tree_item(Vcb, Vcb->extent_root, dr->new_address, TYPE_EXTENT_DATA_REF, ref->hash, edr, sizeof(EXTENT_DATA_REF), NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } } else if (ref->type == TYPE_SHARED_DATA_REF) { @@ -1659,7 +1660,7 @@ static NTSTATUS add_data_reloc_extent_item(_Requires_exclusive_lock_held_(_Curr_ Status = insert_tree_item(Vcb, Vcb->extent_root, dr->new_address, TYPE_SHARED_DATA_REF, ref->parent->new_address, sdr, sizeof(uint32_t), NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } } @@ -1695,7 +1696,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -1719,7 +1720,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = add_data_reloc(Vcb, &items, &metadata_items, &tp, c, &rollback); if (!NT_SUCCESS(Status)) { - ERR("add_data_reloc returned %08x\n", Status); + ERR("add_data_reloc returned %08lx\n", Status); goto end; } @@ -1756,7 +1757,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change data_reloc* dr = CONTAINING_RECORD(le, data_reloc, list_entry); bool done = false; LIST_ENTRY* le2; - uint32_t* csum; + void* csum; RTL_BITMAP bmp; ULONG* bmparr; ULONG bmplen, runlength, index, lastoff; @@ -1805,7 +1806,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = alloc_chunk(Vcb, Vcb->data_flags, &newchunk, false); if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->chunk_lock); goto end; } @@ -1842,7 +1843,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change goto end; } - csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(dr->size * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(dr->size * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!csum) { ERR("out of memory\n"); ExFreePool(bmparr); @@ -1859,7 +1860,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = find_item(Vcb, Vcb->checksum_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); ExFreePool(csum); ExFreePool(bmparr); goto end; @@ -1872,13 +1873,13 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change if (tp.item->key.obj_type == TYPE_EXTENT_CSUM) { if (tp.item->key.offset >= dr->address + dr->size) break; - else if (tp.item->size >= sizeof(uint32_t) && tp.item->key.offset + (tp.item->size * Vcb->superblock.sector_size / sizeof(uint32_t)) >= dr->address) { + else if (tp.item->size >= Vcb->csum_size && tp.item->key.offset + (tp.item->size * Vcb->superblock.sector_size / Vcb->csum_size) >= dr->address) { uint64_t cs = max(dr->address, tp.item->key.offset); - uint64_t ce = min(dr->address + dr->size, tp.item->key.offset + (tp.item->size * Vcb->superblock.sector_size / sizeof(uint32_t))); + uint64_t ce = min(dr->address + dr->size, tp.item->key.offset + (tp.item->size * Vcb->superblock.sector_size / Vcb->csum_size)); - RtlCopyMemory(csum + ((cs - dr->address) / Vcb->superblock.sector_size), - tp.item->data + ((cs - tp.item->key.offset) * sizeof(uint32_t) / Vcb->superblock.sector_size), - (ULONG)((ce - cs) * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory((uint8_t*)csum + ((cs - dr->address) * Vcb->csum_size / Vcb->superblock.sector_size), + tp.item->data + ((cs - tp.item->key.offset) * Vcb->csum_size / Vcb->superblock.sector_size), + (ULONG)((ce - cs) * Vcb->csum_size / Vcb->superblock.sector_size)); RtlClearBits(&bmp, (ULONG)((cs - dr->address) / Vcb->superblock.sector_size), (ULONG)((ce - cs) / Vcb->superblock.sector_size)); @@ -1924,7 +1925,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = read_data(Vcb, dr->address + (off * Vcb->superblock.sector_size), rl * Vcb->superblock.sector_size, NULL, false, data, c, NULL, NULL, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); ExFreePool(csum); ExFreePool(bmparr); goto end; @@ -1933,7 +1934,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = write_data_complete(Vcb, dr->new_address + (off * Vcb->superblock.sector_size), data, rl * Vcb->superblock.sector_size, NULL, newchunk, false, 0, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); ExFreePool(csum); ExFreePool(bmparr); goto end; @@ -1944,7 +1945,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change } while (size > 0); } - add_checksum_entry(Vcb, dr->new_address + (index * Vcb->superblock.sector_size), runlength, &csum[index], NULL); + add_checksum_entry(Vcb, dr->new_address + (index * Vcb->superblock.sector_size), runlength, (uint8_t*)csum + (index * Vcb->csum_size), NULL); add_checksum_entry(Vcb, dr->address + (index * Vcb->superblock.sector_size), runlength, NULL, NULL); // handle csum run @@ -1956,10 +1957,10 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change else rl = runlength; - Status = read_data(Vcb, dr->address + (index * Vcb->superblock.sector_size), rl * Vcb->superblock.sector_size, &csum[index], false, data, - c, NULL, NULL, 0, false, NormalPagePriority); + Status = read_data(Vcb, dr->address + (index * Vcb->superblock.sector_size), rl * Vcb->superblock.sector_size, + (uint8_t*)csum + (index * Vcb->csum_size), false, data, c, NULL, NULL, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); ExFreePool(csum); ExFreePool(bmparr); goto end; @@ -1968,7 +1969,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = write_data_complete(Vcb, dr->new_address + (index * Vcb->superblock.sector_size), data, rl * Vcb->superblock.sector_size, NULL, newchunk, false, 0, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); ExFreePool(csum); ExFreePool(bmparr); goto end; @@ -2001,14 +2002,14 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = read_data(Vcb, dr->address + (off * Vcb->superblock.sector_size), rl * Vcb->superblock.sector_size, NULL, false, data, c, NULL, NULL, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); goto end; } Status = write_data_complete(Vcb, dr->new_address + (off * Vcb->superblock.sector_size), data, rl * Vcb->superblock.sector_size, NULL, newchunk, false, 0, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); goto end; } @@ -2025,7 +2026,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = write_metadata_items(Vcb, &metadata_items, &items, NULL, &rollback); if (!NT_SUCCESS(Status)) { - ERR("write_metadata_items returned %08x\n", Status); + ERR("write_metadata_items returned %08lx\n", Status); goto end; } @@ -2035,7 +2036,7 @@ static NTSTATUS balance_data_chunk(device_extension* Vcb, chunk* c, bool* change Status = add_data_reloc_extent_item(Vcb, dr); if (!NT_SUCCESS(Status)) { - ERR("add_data_reloc_extent_item returned %08x\n", Status); + ERR("add_data_reloc_extent_item returned %08lx\n", Status); goto end; } @@ -2117,7 +2118,7 @@ end: Status = do_write(Vcb, NULL); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); } if (NT_SUCCESS(Status)) { @@ -2217,6 +2218,10 @@ static __inline uint64_t get_chunk_dup_type(chunk* c) { return BLOCK_FLAG_RAID5; else if (c->chunk_item->type & BLOCK_FLAG_RAID6) return BLOCK_FLAG_RAID6; + else if (c->chunk_item->type & BLOCK_FLAG_RAID1C3) + return BLOCK_FLAG_RAID1C3; + else if (c->chunk_item->type & BLOCK_FLAG_RAID1C4) + return BLOCK_FLAG_RAID1C4; else return BLOCK_FLAG_SINGLE; } @@ -2266,7 +2271,7 @@ static bool should_balance_chunk(device_extension* Vcb, uint8_t sort, chunk* c) factor = c->chunk_item->num_stripes - 1; else if (c->chunk_item->type & BLOCK_FLAG_RAID6) factor = c->chunk_item->num_stripes - 2; - else // SINGLE, DUPLICATE, RAID1 + else // SINGLE, DUPLICATE, RAID1, RAID1C3, RAID1C4 factor = 1; physsize = c->chunk_item->size / factor; @@ -2388,14 +2393,14 @@ static NTSTATUS add_balance_item(device_extension* Vcb) { Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); goto end; } } @@ -2426,7 +2431,7 @@ static NTSTATUS add_balance_item(device_extension* Vcb) { Status = insert_tree_item(Vcb, Vcb->root_root, BALANCE_ITEM_ID, TYPE_TEMP_ITEM, 0, bi, sizeof(BALANCE_ITEM), NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(bi); goto end; } @@ -2437,7 +2442,7 @@ end: if (NT_SUCCESS(Status)) { Status = do_write(Vcb, NULL); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); } free_trees(Vcb); @@ -2460,20 +2465,20 @@ static NTSTATUS remove_balance_item(device_extension* Vcb) { Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); goto end; } Status = do_write(Vcb, NULL); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); goto end; } @@ -2593,7 +2598,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr Status = do_write(Vcb, NULL); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); } else Status = STATUS_SUCCESS; @@ -2610,7 +2615,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr Status = find_item(Vcb, Vcb->chunk_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -2618,7 +2623,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } @@ -2631,7 +2636,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr Status = find_item(Vcb, Vcb->dev_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -2639,7 +2644,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } @@ -2656,7 +2661,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr Status = do_write(Vcb, NULL); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); free_trees(Vcb); @@ -2666,7 +2671,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr if (!dev->readonly && dev->devobj) { Status = remove_superblocks(dev); if (!NT_SUCCESS(Status)) - WARN("remove_superblocks returned %08x\n", Status); + WARN("remove_superblocks returned %08lx\n", Status); } // remove entry in volume list @@ -2693,13 +2698,13 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &FileObject, &mountmgr); if (!NT_SUCCESS(Status)) - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); else { MOUNTDEV_NAME mdn; Status = dev_ioctl(dev->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &mdn, sizeof(MOUNTDEV_NAME), true, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); else { MOUNTDEV_NAME* mdn2; ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength; @@ -2710,7 +2715,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr else { Status = dev_ioctl(dev->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL); if (!NT_SUCCESS(Status)) - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); else { UNICODE_STRING name; @@ -2719,7 +2724,7 @@ static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tr Status = mountmgr_add_drive_letter(mountmgr, &name); if (!NT_SUCCESS(Status)) - WARN("mountmgr_add_drive_letter returned %08x\n", Status); + WARN("mountmgr_add_drive_letter returned %08lx\n", Status); } ExFreePool(mdn2); @@ -2817,7 +2822,7 @@ static void trim_unalloc_space(_Requires_lock_held_(_Curr_->tree_lock) device_ex Status = find_item(Vcb, Vcb->dev_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return; } @@ -2833,7 +2838,7 @@ static void trim_unalloc_space(_Requires_lock_held_(_Curr_->tree_lock) device_ex lastoff = tp.item->key.offset + de->length; } else { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DEV_EXTENT)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DEV_EXTENT)); return; } } @@ -2885,7 +2890,7 @@ static void trim_unalloc_space(_Requires_lock_held_(_Curr_->tree_lock) device_ex Status = dev_ioctl(dev->devobj, IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, dmdsa, datalen, NULL, 0, true, NULL); if (!NT_SUCCESS(Status)) - WARN("IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES returned %08x\n", Status); + WARN("IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES returned %08lx\n", Status); ExFreePool(dmdsa); @@ -2947,7 +2952,7 @@ static NTSTATUS try_consolidation(device_extension* Vcb, uint64_t flags, chunk** Status = balance_data_chunk(Vcb, rc, &changed); if (!NT_SUCCESS(Status)) { - ERR("balance_data_chunk returned %08x\n", Status); + ERR("balance_data_chunk returned %08lx\n", Status); Vcb->balance.status = Status; rc->list_entry_balance.Flink = NULL; rc->reloc = false; @@ -2971,7 +2976,7 @@ static NTSTATUS try_consolidation(device_extension* Vcb, uint64_t flags, chunk** Status = do_write(Vcb, NULL); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); return Status; } @@ -2988,7 +2993,7 @@ static NTSTATUS try_consolidation(device_extension* Vcb, uint64_t flags, chunk** *newchunk = rc; return Status; } else { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); return Status; } } @@ -3027,7 +3032,7 @@ static NTSTATUS regenerate_space_list(device_extension* Vcb, device* dev) { factor = c->chunk_item->num_stripes - 1; else if (c->chunk_item->type & BLOCK_FLAG_RAID6) factor = c->chunk_item->num_stripes - 2; - else // SINGLE, DUP, RAID1 + else // SINGLE, DUP, RAID1, RAID1C3, RAID1C4 factor = 1; stripe_size = c->chunk_item->size / factor; @@ -3092,7 +3097,7 @@ void __stdcall balance_thread(void* context) { if (!Vcb->balance.removing && !Vcb->balance.shrinking) { Status = add_balance_item(Vcb); if (!NT_SUCCESS(Status)) { - ERR("add_balance_item returned %08x\n", Status); + ERR("add_balance_item returned %08lx\n", Status); Vcb->balance.status = Status; goto end; } @@ -3103,7 +3108,7 @@ void __stdcall balance_thread(void* context) { free_trees(Vcb); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); Vcb->balance.status = Status; goto end; } @@ -3155,7 +3160,7 @@ void __stdcall balance_thread(void* context) { Status = load_cache_chunk(Vcb, c, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); Vcb->balance.status = Status; release_chunk_lock(c, Vcb); ExReleaseResourceLite(&Vcb->chunk_lock); @@ -3182,7 +3187,7 @@ void __stdcall balance_thread(void* context) { if (NT_SUCCESS(Status)) c->balance_num = Vcb->balance.balance_num; else if (Status != STATUS_DISK_FULL || consolidated) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->chunk_lock); Vcb->balance.status = Status; goto end; @@ -3193,7 +3198,7 @@ void __stdcall balance_thread(void* context) { if (Status == STATUS_DISK_FULL) { Status = try_consolidation(Vcb, Vcb->metadata_flags, &c); if (!NT_SUCCESS(Status)) { - ERR("try_consolidation returned %08x\n", Status); + ERR("try_consolidation returned %08lx\n", Status); Vcb->balance.status = Status; goto end; } else @@ -3213,7 +3218,7 @@ void __stdcall balance_thread(void* context) { if (NT_SUCCESS(Status)) c->balance_num = Vcb->balance.balance_num; else if (Status != STATUS_DISK_FULL || consolidated) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->chunk_lock); Vcb->balance.status = Status; goto end; @@ -3224,7 +3229,7 @@ void __stdcall balance_thread(void* context) { if (Status == STATUS_DISK_FULL) { Status = try_consolidation(Vcb, Vcb->data_flags, &c); if (!NT_SUCCESS(Status)) { - ERR("try_consolidation returned %08x\n", Status); + ERR("try_consolidation returned %08lx\n", Status); Vcb->balance.status = Status; goto end; } else @@ -3244,7 +3249,7 @@ void __stdcall balance_thread(void* context) { if (NT_SUCCESS(Status)) c->balance_num = Vcb->balance.balance_num; else if (Status != STATUS_DISK_FULL || consolidated) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->chunk_lock); Vcb->balance.status = Status; goto end; @@ -3255,7 +3260,7 @@ void __stdcall balance_thread(void* context) { if (Status == STATUS_DISK_FULL) { Status = try_consolidation(Vcb, Vcb->system_flags, &c); if (!NT_SUCCESS(Status)) { - ERR("try_consolidation returned %08x\n", Status); + ERR("try_consolidation returned %08lx\n", Status); Vcb->balance.status = Status; goto end; } else @@ -3296,7 +3301,7 @@ void __stdcall balance_thread(void* context) { Status = balance_data_chunk(Vcb, c, &changed); if (!NT_SUCCESS(Status)) { - ERR("balance_data_chunk returned %08x\n", Status); + ERR("balance_data_chunk returned %08lx\n", Status); Vcb->balance.status = Status; goto end; } @@ -3340,7 +3345,7 @@ void __stdcall balance_thread(void* context) { do { Status = balance_metadata_chunk(Vcb, c, &changed); if (!NT_SUCCESS(Status)) { - ERR("balance_metadata_chunk returned %08x\n", Status); + ERR("balance_metadata_chunk returned %08lx\n", Status); Vcb->balance.status = Status; goto end; } @@ -3410,7 +3415,7 @@ end: Status = finish_removing_device(Vcb, dev); if (!NT_SUCCESS(Status)) { - ERR("finish_removing_device returned %08x\n", Status); + ERR("finish_removing_device returned %08lx\n", Status); dev->reloc = false; } } else @@ -3444,7 +3449,7 @@ end: if (dev) { Status = regenerate_space_list(Vcb, dev); if (!NT_SUCCESS(Status)) - WARN("regenerate_space_list returned %08x\n", Status); + WARN("regenerate_space_list returned %08lx\n", Status); } } else { uint64_t old_size; @@ -3454,19 +3459,19 @@ end: Status = update_dev_item(Vcb, dev, NULL); if (!NT_SUCCESS(Status)) { - ERR("update_dev_item returned %08x\n", Status); + ERR("update_dev_item returned %08lx\n", Status); dev->devitem.num_bytes = old_size; Vcb->balance.status = Status; Status = regenerate_space_list(Vcb, dev); if (!NT_SUCCESS(Status)) - WARN("regenerate_space_list returned %08x\n", Status); + WARN("regenerate_space_list returned %08lx\n", Status); } else { Vcb->superblock.total_bytes -= old_size - dev->devitem.num_bytes; Status = do_write(Vcb, NULL); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); free_trees(Vcb); } @@ -3479,7 +3484,7 @@ end: } else { Status = remove_balance_item(Vcb); if (!NT_SUCCESS(Status)) { - ERR("remove_balance_item returned %08x\n", Status); + ERR("remove_balance_item returned %08lx\n", Status); goto end; } } @@ -3546,7 +3551,8 @@ NTSTATUS start_balance(device_extension* Vcb, void* data, ULONG length, KPROCESS if (bsb->opts[i].flags & BTRFS_BALANCE_OPTS_ENABLED) { if (bsb->opts[i].flags & BTRFS_BALANCE_OPTS_PROFILES) { bsb->opts[i].profiles &= BLOCK_FLAG_RAID0 | BLOCK_FLAG_RAID1 | BLOCK_FLAG_DUPLICATE | BLOCK_FLAG_RAID10 | - BLOCK_FLAG_RAID5 | BLOCK_FLAG_RAID6 | BLOCK_FLAG_SINGLE; + BLOCK_FLAG_RAID5 | BLOCK_FLAG_RAID6 | BLOCK_FLAG_SINGLE | BLOCK_FLAG_RAID1C3 | + BLOCK_FLAG_RAID1C4; if (bsb->opts[i].profiles == 0) return STATUS_INVALID_PARAMETER; @@ -3595,7 +3601,8 @@ NTSTATUS start_balance(device_extension* Vcb, void* data, ULONG length, KPROCESS if (bsb->opts[i].convert != BLOCK_FLAG_RAID0 && bsb->opts[i].convert != BLOCK_FLAG_RAID1 && bsb->opts[i].convert != BLOCK_FLAG_DUPLICATE && bsb->opts[i].convert != BLOCK_FLAG_RAID10 && bsb->opts[i].convert != BLOCK_FLAG_RAID5 && bsb->opts[i].convert != BLOCK_FLAG_RAID6 && - bsb->opts[i].convert != BLOCK_FLAG_SINGLE) + bsb->opts[i].convert != BLOCK_FLAG_SINGLE && bsb->opts[i].convert != BLOCK_FLAG_RAID1C3 && + bsb->opts[i].convert != BLOCK_FLAG_RAID1C4) return STATUS_INVALID_PARAMETER; } } @@ -3615,7 +3622,7 @@ NTSTATUS start_balance(device_extension* Vcb, void* data, ULONG length, KPROCESS Status = PsCreateSystemThread(&Vcb->balance.thread, 0, &oa, NULL, NULL, balance_thread, Vcb); if (!NT_SUCCESS(Status)) { - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); return Status; } @@ -3636,7 +3643,7 @@ NTSTATUS look_for_balance_item(_Requires_lock_held_(_Curr_->tree_lock) device_ex Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -3646,7 +3653,7 @@ NTSTATUS look_for_balance_item(_Requires_lock_held_(_Curr_->tree_lock) device_ex } if (tp.item->size < sizeof(BALANCE_ITEM)) { - WARN("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + WARN("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(BALANCE_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -3698,7 +3705,7 @@ NTSTATUS look_for_balance_item(_Requires_lock_held_(_Curr_->tree_lock) device_ex Status = PsCreateSystemThread(&Vcb->balance.thread, 0, &oa, NULL, NULL, balance_thread, Vcb); if (!NT_SUCCESS(Status)) { - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); return Status; } @@ -3802,7 +3809,7 @@ NTSTATUS remove_device(device_extension* Vcb, void* data, ULONG length, KPROCESS uint64_t num_rw_devices; OBJECT_ATTRIBUTES oa; - TRACE("(%p, %p, %x)\n", Vcb, data, length); + TRACE("(%p, %p, %lx)\n", Vcb, data, length); if (!SeSinglePrivilegeCheck(RtlConvertLongToLuid(SE_MANAGE_VOLUME_PRIVILEGE), processor_mode)) return STATUS_PRIVILEGE_NOT_HELD; @@ -3849,16 +3856,21 @@ NTSTATUS remove_device(device_extension* Vcb, void* data, ULONG length, KPROCESS if (num_rw_devices == 4 && ((Vcb->data_flags & BLOCK_FLAG_RAID10 || Vcb->metadata_flags & BLOCK_FLAG_RAID10 || Vcb->system_flags & BLOCK_FLAG_RAID10) || - (Vcb->data_flags & BLOCK_FLAG_RAID6 || Vcb->metadata_flags & BLOCK_FLAG_RAID6 || Vcb->system_flags & BLOCK_FLAG_RAID6)) + (Vcb->data_flags & BLOCK_FLAG_RAID6 || Vcb->metadata_flags & BLOCK_FLAG_RAID6 || Vcb->system_flags & BLOCK_FLAG_RAID6) || + (Vcb->data_flags & BLOCK_FLAG_RAID1C4 || Vcb->metadata_flags & BLOCK_FLAG_RAID1C4 || Vcb->system_flags & BLOCK_FLAG_RAID1C4) + ) ) { ExReleaseResourceLite(&Vcb->tree_lock); - ERR("would not be enough devices to satisfy RAID requirement (RAID6/10)\n"); + ERR("would not be enough devices to satisfy RAID requirement (RAID6/10/1C4)\n"); return STATUS_CANNOT_DELETE; } - if (num_rw_devices == 3 && (Vcb->data_flags & BLOCK_FLAG_RAID5 || Vcb->metadata_flags & BLOCK_FLAG_RAID5 || Vcb->system_flags & BLOCK_FLAG_RAID5)) { + if (num_rw_devices == 3 && + ((Vcb->data_flags & BLOCK_FLAG_RAID5 || Vcb->metadata_flags & BLOCK_FLAG_RAID5 || Vcb->system_flags & BLOCK_FLAG_RAID5) || + (Vcb->data_flags & BLOCK_FLAG_RAID1C3 || Vcb->metadata_flags & BLOCK_FLAG_RAID1C3 || Vcb->system_flags & BLOCK_FLAG_RAID1C3)) + ) { ExReleaseResourceLite(&Vcb->tree_lock); - ERR("would not be enough devices to satisfy RAID requirement (RAID5)\n"); + ERR("would not be enough devices to satisfy RAID requirement (RAID5/1C3)\n"); return STATUS_CANNOT_DELETE; } @@ -3898,7 +3910,7 @@ NTSTATUS remove_device(device_extension* Vcb, void* data, ULONG length, KPROCESS Status = PsCreateSystemThread(&Vcb->balance.thread, 0, &oa, NULL, NULL, balance_thread, Vcb); if (!NT_SUCCESS(Status)) { - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); dev->reloc = false; return Status; } diff --git a/drivers/filesystems/btrfs/blake2-impl.h b/drivers/filesystems/btrfs/blake2-impl.h new file mode 100644 index 00000000000..d6b05c09f15 --- /dev/null +++ b/drivers/filesystems/btrfs/blake2-impl.h @@ -0,0 +1,194 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ +#pragma once + +#include +#include + +#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) + #if defined(_MSC_VER) + #define BLAKE2_INLINE __inline + #elif defined(__GNUC__) + #define BLAKE2_INLINE __inline__ + #else + #define BLAKE2_INLINE + #endif +#else + #define BLAKE2_INLINE inline +#endif + +static BLAKE2_INLINE uint32_t load32( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + return (( uint32_t )( p[0] ) << 0) | + (( uint32_t )( p[1] ) << 8) | + (( uint32_t )( p[2] ) << 16) | + (( uint32_t )( p[3] ) << 24) ; +#endif +} + +static BLAKE2_INLINE uint64_t load64( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + return (( uint64_t )( p[0] ) << 0) | + (( uint64_t )( p[1] ) << 8) | + (( uint64_t )( p[2] ) << 16) | + (( uint64_t )( p[3] ) << 24) | + (( uint64_t )( p[4] ) << 32) | + (( uint64_t )( p[5] ) << 40) | + (( uint64_t )( p[6] ) << 48) | + (( uint64_t )( p[7] ) << 56) ; +#endif +} + +static BLAKE2_INLINE uint16_t load16( const void *src ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + uint16_t w; + memcpy(&w, src, sizeof w); + return w; +#else + const uint8_t *p = ( const uint8_t * )src; + return ( uint16_t )((( uint32_t )( p[0] ) << 0) | + (( uint32_t )( p[1] ) << 8)); +#endif +} + +static BLAKE2_INLINE void store16( void *dst, uint16_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + *p++ = ( uint8_t )w; w >>= 8; + *p++ = ( uint8_t )w; +#endif +} + +static BLAKE2_INLINE void store32( void *dst, uint32_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); +#endif +} + +static BLAKE2_INLINE void store64( void *dst, uint64_t w ) +{ +#if defined(NATIVE_LITTLE_ENDIAN) + memcpy(dst, &w, sizeof w); +#else + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); + p[4] = (uint8_t)(w >> 32); + p[5] = (uint8_t)(w >> 40); + p[6] = (uint8_t)(w >> 48); + p[7] = (uint8_t)(w >> 56); +#endif +} + +static BLAKE2_INLINE uint64_t load48( const void *src ) +{ + const uint8_t *p = ( const uint8_t * )src; + return (( uint64_t )( p[0] ) << 0) | + (( uint64_t )( p[1] ) << 8) | + (( uint64_t )( p[2] ) << 16) | + (( uint64_t )( p[3] ) << 24) | + (( uint64_t )( p[4] ) << 32) | + (( uint64_t )( p[5] ) << 40) ; +} + +static BLAKE2_INLINE void store48( void *dst, uint64_t w ) +{ + uint8_t *p = ( uint8_t * )dst; + p[0] = (uint8_t)(w >> 0); + p[1] = (uint8_t)(w >> 8); + p[2] = (uint8_t)(w >> 16); + p[3] = (uint8_t)(w >> 24); + p[4] = (uint8_t)(w >> 32); + p[5] = (uint8_t)(w >> 40); +} + +static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 32 - c ) ); +} + +static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) +{ + return ( w >> c ) | ( w << ( 64 - c ) ); +} + +#if defined(_MSC_VER) +#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) +#else +#define BLAKE2_PACKED(x) x __attribute__((packed)) +#endif + +enum blake2b_constant +{ + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 +}; + +typedef struct blake2b_state__ +{ + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + size_t buflen; + size_t outlen; + uint8_t last_node; +} blake2b_state; + +BLAKE2_PACKED(struct blake2b_param__ +{ + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint32_t leaf_length; /* 8 */ + uint32_t node_offset; /* 12 */ + uint32_t xof_length; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ +}); + +typedef struct blake2b_param__ blake2b_param; diff --git a/drivers/filesystems/btrfs/blake2b-ref.c b/drivers/filesystems/btrfs/blake2b-ref.c new file mode 100644 index 00000000000..752ed39f2e4 --- /dev/null +++ b/drivers/filesystems/btrfs/blake2b-ref.c @@ -0,0 +1,245 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Copyright 2012, Samuel Neves . You may use this under the + terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at + your option. The terms of these licenses can be found at: + + - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 + - OpenSSL license : https://www.openssl.org/source/license.html + - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + + More information about the BLAKE2 hash function can be found at + https://blake2.net. +*/ + +#include +#include +#include + +#include "blake2-impl.h" + +static const uint64_t blake2b_IV[8] = +{ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + +static int blake2b_update(blake2b_state* S, const void* in, size_t inlen); + +static void blake2b_set_lastnode( blake2b_state *S ) +{ + S->f[1] = (uint64_t)-1; +} + +/* Some helper functions, not necessarily useful */ +static int blake2b_is_lastblock( const blake2b_state *S ) +{ + return S->f[0] != 0; +} + +static void blake2b_set_lastblock( blake2b_state *S ) +{ + if( S->last_node ) blake2b_set_lastnode( S ); + + S->f[0] = (uint64_t)-1; +} + +static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) +{ + S->t[0] += inc; + S->t[1] += ( S->t[0] < inc ); +} + +static void blake2b_init0( blake2b_state *S ) +{ + size_t i; + memset( S, 0, sizeof( blake2b_state ) ); + + for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; +} + +/* init xors IV with input parameter block */ +static void blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + const uint8_t *p = ( const uint8_t * )( P ); + size_t i; + + blake2b_init0( S ); + + /* IV XOR ParamBlock */ + for( i = 0; i < 8; ++i ) + S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + + S->outlen = P->digest_length; +} + + + +static void blake2b_init( blake2b_state *S, size_t outlen ) +{ + blake2b_param P[1]; + + P->digest_length = (uint8_t)outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + store32( &P->leaf_length, 0 ); + store32( &P->node_offset, 0 ); + store32( &P->xof_length, 0 ); + P->node_depth = 0; + P->inner_length = 0; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + + blake2b_init_param( S, P ); +} + +#define G(r,i,a,b,c,d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2*i+0]]; \ + d = rotr64(d ^ a, 32); \ + c = c + d; \ + b = rotr64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2*i+1]]; \ + d = rotr64(d ^ a, 16); \ + c = c + d; \ + b = rotr64(b ^ c, 63); \ + } while(0) + +#define ROUND(r) \ + do { \ + G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ + G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ + G(r,2,v[ 2],v[ 6],v[10],v[14]); \ + G(r,3,v[ 3],v[ 7],v[11],v[15]); \ + G(r,4,v[ 0],v[ 5],v[10],v[15]); \ + G(r,5,v[ 1],v[ 6],v[11],v[12]); \ + G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ + G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ + } while(0) + +static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) +{ + uint64_t m[16]; + uint64_t v[16]; + size_t i; + + for( i = 0; i < 16; ++i ) { + m[i] = load64( block + i * sizeof( m[i] ) ); + } + + for( i = 0; i < 8; ++i ) { + v[i] = S->h[i]; + } + + v[ 8] = blake2b_IV[0]; + v[ 9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = blake2b_IV[4] ^ S->t[0]; + v[13] = blake2b_IV[5] ^ S->t[1]; + v[14] = blake2b_IV[6] ^ S->f[0]; + v[15] = blake2b_IV[7] ^ S->f[1]; + + ROUND( 0 ); + ROUND( 1 ); + ROUND( 2 ); + ROUND( 3 ); + ROUND( 4 ); + ROUND( 5 ); + ROUND( 6 ); + ROUND( 7 ); + ROUND( 8 ); + ROUND( 9 ); + ROUND( 10 ); + ROUND( 11 ); + + for( i = 0; i < 8; ++i ) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } +} + +#undef G +#undef ROUND + +static int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) +{ + const unsigned char * in = (const unsigned char *)pin; + if( inlen > 0 ) + { + size_t left = S->buflen; + size_t fill = BLAKE2B_BLOCKBYTES - left; + if( inlen > fill ) + { + S->buflen = 0; + memcpy( S->buf + left, in, fill ); /* Fill buffer */ + blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); + blake2b_compress( S, S->buf ); /* Compress */ + in += fill; inlen -= fill; + while(inlen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress( S, in ); + in += BLAKE2B_BLOCKBYTES; + inlen -= BLAKE2B_BLOCKBYTES; + } + } + memcpy( S->buf + S->buflen, in, inlen ); + S->buflen += inlen; + } + return 0; +} + +static int blake2b_final( blake2b_state *S, void *out, size_t outlen ) +{ + uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; + size_t i; + + if( out == NULL || outlen < S->outlen ) + return -1; + + if( blake2b_is_lastblock( S ) ) + return -1; + + blake2b_increment_counter( S, S->buflen ); + blake2b_set_lastblock( S ); + memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ + blake2b_compress( S, S->buf ); + + for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); + + memcpy( out, buffer, S->outlen ); + + return 0; +} + +/* inlen, at least, should be uint64_t. Others can be size_t. */ +void blake2b( void *out, size_t outlen, const void *in, size_t inlen ) +{ + blake2b_state S[1]; + + blake2b_init( S, outlen ); + + blake2b_update( S, ( const uint8_t * )in, inlen ); + blake2b_final( S, out, outlen ); +} diff --git a/drivers/filesystems/btrfs/boot.c b/drivers/filesystems/btrfs/boot.c index 34fee170ec7..aa5a4373df2 100755 --- a/drivers/filesystems/btrfs/boot.c +++ b/drivers/filesystems/btrfs/boot.c @@ -30,6 +30,9 @@ extern LIST_ENTRY pdo_list; extern ERESOURCE boot_lock; extern PDRIVER_OBJECT drvobj; +BTRFS_UUID boot_uuid; // initialized to 0 +uint64_t boot_subvol = 0; + #ifndef _MSC_VER NTSTATUS RtlUnicodeStringPrintf(PUNICODE_STRING DestinationString, const WCHAR* pszFormat, ...); // not in mingw #endif @@ -47,113 +50,198 @@ typedef struct { ULONG ExtensionFlags; } DEVOBJ_EXTENSION2; -static bool get_system_root_partition(uint32_t* disk_num, uint32_t* partition_num) { +typedef enum { + system_root_unknown, + system_root_partition, + system_root_btrfs +} system_root_type; + +typedef struct { + uint32_t disk_num; + uint32_t partition_num; + BTRFS_UUID uuid; + system_root_type type; +} system_root; + +static void get_system_root(system_root* sr) { NTSTATUS Status; HANDLE h; UNICODE_STRING us, target; OBJECT_ATTRIBUTES objatt; - WCHAR* s; - ULONG retlen = 0, left; + ULONG retlen = 0; + bool second_time = false; static const WCHAR system_root[] = L"\\SystemRoot"; + static const WCHAR boot_device[] = L"\\Device\\BootDevice"; static const WCHAR arc_prefix[] = L"\\ArcName\\multi(0)disk(0)rdisk("; static const WCHAR arc_middle[] = L")partition("; + static const WCHAR arc_btrfs_prefix[] = L"\\ArcName\\btrfs("; us.Buffer = (WCHAR*)system_root; us.Length = us.MaximumLength = sizeof(system_root) - sizeof(WCHAR); InitializeObjectAttributes(&objatt, &us, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); - Status = ZwOpenSymbolicLinkObject(&h, GENERIC_READ, &objatt); - if (!NT_SUCCESS(Status)) { - ERR("ZwOpenSymbolicLinkObject returned %08x\n", Status); - return false; - } + while (true) { + Status = ZwOpenSymbolicLinkObject(&h, GENERIC_READ, &objatt); + if (!NT_SUCCESS(Status)) { + ERR("ZwOpenSymbolicLinkObject returned %08lx\n", Status); + return; + } - target.Length = target.MaximumLength = 0; + target.Length = target.MaximumLength = 0; + + Status = ZwQuerySymbolicLinkObject(h, &target, &retlen); + if (Status != STATUS_BUFFER_TOO_SMALL) { + ERR("ZwQuerySymbolicLinkObject returned %08lx\n", Status); + NtClose(h); + return; + } + + if (retlen == 0) { + NtClose(h); + return; + } + + target.Buffer = ExAllocatePoolWithTag(NonPagedPool, retlen, ALLOC_TAG); + if (!target.Buffer) { + ERR("out of memory\n"); + NtClose(h); + return; + } + + target.Length = target.MaximumLength = (USHORT)retlen; + + Status = ZwQuerySymbolicLinkObject(h, &target, NULL); + if (!NT_SUCCESS(Status)) { + ERR("ZwQuerySymbolicLinkObject returned %08lx\n", Status); + NtClose(h); + ExFreePool(target.Buffer); + return; + } - Status = ZwQuerySymbolicLinkObject(h, &target, &retlen); - if (Status != STATUS_BUFFER_TOO_SMALL) { - ERR("ZwQuerySymbolicLinkObject returned %08x\n", Status); NtClose(h); - return false; + + if (second_time) { + TRACE("boot device is %.*S\n", (int)(target.Length / sizeof(WCHAR)), target.Buffer); + } else { + TRACE("system root is %.*S\n", (int)(target.Length / sizeof(WCHAR)), target.Buffer); + } + + if (!second_time && target.Length >= sizeof(boot_device) - sizeof(WCHAR) && + RtlCompareMemory(target.Buffer, boot_device, sizeof(boot_device) - sizeof(WCHAR)) == sizeof(boot_device) - sizeof(WCHAR)) { + ExFreePool(target.Buffer); + + us.Buffer = (WCHAR*)boot_device; + us.Length = us.MaximumLength = sizeof(boot_device) - sizeof(WCHAR); + + second_time = true; + } else + break; } - if (retlen == 0) { - NtClose(h); - return false; - } + sr->type = system_root_unknown; - target.Buffer = ExAllocatePoolWithTag(NonPagedPool, retlen, ALLOC_TAG); - if (!target.Buffer) { - ERR("out of memory\n"); - NtClose(h); - return false; - } + if (target.Length >= sizeof(arc_prefix) - sizeof(WCHAR) && + RtlCompareMemory(target.Buffer, arc_prefix, sizeof(arc_prefix) - sizeof(WCHAR)) == sizeof(arc_prefix) - sizeof(WCHAR)) { + WCHAR* s = &target.Buffer[(sizeof(arc_prefix) / sizeof(WCHAR)) - 1]; + ULONG left = ((target.Length - sizeof(arc_prefix)) / sizeof(WCHAR)) + 1; - target.Length = target.MaximumLength = (USHORT)retlen; + if (left == 0 || s[0] < '0' || s[0] > '9') { + ExFreePool(target.Buffer); + return; + } - Status = ZwQuerySymbolicLinkObject(h, &target, NULL); - if (!NT_SUCCESS(Status)) { - ERR("ZwQuerySymbolicLinkObject returned %08x\n", Status); - NtClose(h); - ExFreePool(target.Buffer); - return false; - } + sr->disk_num = 0; - NtClose(h); + while (left > 0 && s[0] >= '0' && s[0] <= '9') { + sr->disk_num *= 10; + sr->disk_num += s[0] - '0'; + s++; + left--; + } - TRACE("system root is %.*S\n", target.Length / sizeof(WCHAR), target.Buffer); + if (left <= (sizeof(arc_middle) / sizeof(WCHAR)) - 1 || + RtlCompareMemory(s, arc_middle, sizeof(arc_middle) - sizeof(WCHAR)) != sizeof(arc_middle) - sizeof(WCHAR)) { + ExFreePool(target.Buffer); + return; + } - if (target.Length <= sizeof(arc_prefix) - sizeof(WCHAR) || - RtlCompareMemory(target.Buffer, arc_prefix, sizeof(arc_prefix) - sizeof(WCHAR)) != sizeof(arc_prefix) - sizeof(WCHAR)) { - ExFreePool(target.Buffer); - return false; - } + s = &s[(sizeof(arc_middle) / sizeof(WCHAR)) - 1]; + left -= (sizeof(arc_middle) / sizeof(WCHAR)) - 1; - s = &target.Buffer[(sizeof(arc_prefix) / sizeof(WCHAR)) - 1]; - left = ((target.Length - sizeof(arc_prefix)) / sizeof(WCHAR)) + 1; + if (left == 0 || s[0] < '0' || s[0] > '9') { + ExFreePool(target.Buffer); + return; + } - if (left == 0 || s[0] < '0' || s[0] > '9') { - ExFreePool(target.Buffer); - return false; - } + sr->partition_num = 0; - *disk_num = 0; + while (left > 0 && s[0] >= '0' && s[0] <= '9') { + sr->partition_num *= 10; + sr->partition_num += s[0] - '0'; + s++; + left--; + } - while (left > 0 && s[0] >= '0' && s[0] <= '9') { - *disk_num *= 10; - *disk_num += s[0] - '0'; - s++; - left--; - } + sr->type = system_root_partition; + } else if (target.Length >= sizeof(arc_btrfs_prefix) - sizeof(WCHAR) && + RtlCompareMemory(target.Buffer, arc_btrfs_prefix, sizeof(arc_btrfs_prefix) - sizeof(WCHAR)) == sizeof(arc_btrfs_prefix) - sizeof(WCHAR)) { + WCHAR* s = &target.Buffer[(sizeof(arc_btrfs_prefix) / sizeof(WCHAR)) - 1]; +#ifdef __REACTOS__ + unsigned int i; +#endif // __REACTOS__ - if (left <= (sizeof(arc_middle) / sizeof(WCHAR)) - 1 || - RtlCompareMemory(s, arc_middle, sizeof(arc_middle) - sizeof(WCHAR)) != sizeof(arc_middle) - sizeof(WCHAR)) { - ExFreePool(target.Buffer); - return false; - } +#ifndef __REACTOS__ + for (unsigned int i = 0; i < 16; i++) { +#else + for (i = 0; i < 16; i++) { +#endif // __REACTOS__ + if (*s >= '0' && *s <= '9') + sr->uuid.uuid[i] = (*s - '0') << 4; + else if (*s >= 'a' && *s <= 'f') + sr->uuid.uuid[i] = (*s - 'a' + 0xa) << 4; + else if (*s >= 'A' && *s <= 'F') + sr->uuid.uuid[i] = (*s - 'A' + 0xa) << 4; + else { + ExFreePool(target.Buffer); + return; + } - s = &s[(sizeof(arc_middle) / sizeof(WCHAR)) - 1]; - left -= (sizeof(arc_middle) / sizeof(WCHAR)) - 1; + s++; - if (left == 0 || s[0] < '0' || s[0] > '9') { - ExFreePool(target.Buffer); - return false; - } + if (*s >= '0' && *s <= '9') + sr->uuid.uuid[i] |= *s - '0'; + else if (*s >= 'a' && *s <= 'f') + sr->uuid.uuid[i] |= *s - 'a' + 0xa; + else if (*s >= 'A' && *s <= 'F') + sr->uuid.uuid[i] |= *s - 'A' + 0xa; + else { + ExFreePool(target.Buffer); + return; + } - *partition_num = 0; + s++; - while (left > 0 && s[0] >= '0' && s[0] <= '9') { - *partition_num *= 10; - *partition_num += s[0] - '0'; - s++; - left--; + if (i == 3 || i == 5 || i == 7 || i == 9) { + if (*s != '-') { + ExFreePool(target.Buffer); + return; + } + + s++; + } + } + + if (*s != ')') { + ExFreePool(target.Buffer); + return; + } + + sr->type = system_root_btrfs; } ExFreePool(target.Buffer); - - return true; } static void change_symlink(uint32_t disk_num, uint32_t partition_num, BTRFS_UUID* uuid) { @@ -170,13 +258,13 @@ static void change_symlink(uint32_t disk_num, uint32_t partition_num, BTRFS_UUID Status = RtlUnicodeStringPrintf(&us, L"\\Device\\Harddisk%u\\Partition%u", disk_num, partition_num); if (!NT_SUCCESS(Status)) { - ERR("RtlUnicodeStringPrintf returned %08x\n", Status); + ERR("RtlUnicodeStringPrintf returned %08lx\n", Status); return; } Status = IoDeleteSymbolicLink(&us); if (!NT_SUCCESS(Status)) - ERR("IoDeleteSymbolicLink returned %08x\n", Status); + ERR("IoDeleteSymbolicLink returned %08lx\n", Status); RtlCopyMemory(target, BTRFS_VOLUME_PREFIX, sizeof(BTRFS_VOLUME_PREFIX) - sizeof(WCHAR)); @@ -203,7 +291,7 @@ static void change_symlink(uint32_t disk_num, uint32_t partition_num, BTRFS_UUID Status = IoCreateSymbolicLink(&us, &us2); if (!NT_SUCCESS(Status)) - ERR("IoCreateSymbolicLink returned %08x\n", Status); + ERR("IoCreateSymbolicLink returned %08lx\n", Status); } static void mountmgr_notification(BTRFS_UUID* uuid) { @@ -221,7 +309,7 @@ static void mountmgr_notification(BTRFS_UUID* uuid) { RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &FileObject, &mountmgr); if (!NT_SUCCESS(Status)) { - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); return; } @@ -257,7 +345,7 @@ static void mountmgr_notification(BTRFS_UUID* uuid) { Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, mmtn, mmtnlen, NULL, 0, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION returned %08x\n", Status); + ERR("IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION returned %08lx\n", Status); ExFreePool(mmtn); return; } @@ -265,6 +353,110 @@ static void mountmgr_notification(BTRFS_UUID* uuid) { ExFreePool(mmtn); } +static void check_boot_options() { + NTSTATUS Status; + WCHAR* s; + + static const WCHAR pathw[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control"; + static const WCHAR namew[] = L"SystemStartOptions"; + static const WCHAR subvol[] = L"SUBVOL="; + + _SEH2_TRY { + HANDLE control; + OBJECT_ATTRIBUTES oa; + UNICODE_STRING path; + ULONG kvfilen = sizeof(KEY_VALUE_FULL_INFORMATION) - sizeof(WCHAR) + (255 * sizeof(WCHAR)); + KEY_VALUE_FULL_INFORMATION* kvfi; + UNICODE_STRING name; + WCHAR* options; + + path.Buffer = (WCHAR*)pathw; + path.Length = path.MaximumLength = sizeof(pathw) - sizeof(WCHAR); + + InitializeObjectAttributes(&oa, &path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); + + Status = ZwOpenKey(&control, KEY_QUERY_VALUE, &oa); + if (!NT_SUCCESS(Status)) { + ERR("ZwOpenKey returned %08lx\n", Status); + return; + } + + // FIXME - don't fail if value too long (can we query for the length?) + + kvfi = ExAllocatePoolWithTag(PagedPool, kvfilen, ALLOC_TAG); + if (!kvfi) { + ERR("out of memory\n"); + NtClose(control); + return; + } + + name.Buffer = (WCHAR*)namew; + name.Length = name.MaximumLength = sizeof(namew) - sizeof(WCHAR); + + Status = ZwQueryValueKey(control, &name, KeyValueFullInformation, kvfi, + kvfilen, &kvfilen); + if (!NT_SUCCESS(Status)) { + ERR("ZwQueryValueKey returned %08lx\n", Status); + NtClose(control); + return; + } + + NtClose(control); + + options = (WCHAR*)((uint8_t*)kvfi + kvfi->DataOffset); + options[kvfi->DataLength / sizeof(WCHAR)] = 0; // FIXME - make sure buffer long enough to allow this + + s = wcsstr(options, subvol); + + if (!s) + return; + + s += (sizeof(subvol) / sizeof(WCHAR)) - 1; + + boot_subvol = 0; + + while (true) { + if (*s >= '0' && *s <= '9') { + boot_subvol <<= 4; + boot_subvol |= *s - '0'; + } else if (*s >= 'a' && *s <= 'f') { + boot_subvol <<= 4; + boot_subvol |= *s - 'a' + 0xa; + } else if (*s >= 'A' && *s <= 'F') { + boot_subvol <<= 4; + boot_subvol |= *s - 'A' + 0xa; + } else + break; + + s++; + } + } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { + return; + } _SEH2_END; + + if (boot_subvol != 0) { + TRACE("passed subvol %I64x in boot options\n", boot_subvol); + } +} + +void boot_add_device(DEVICE_OBJECT* pdo) { + pdo_device_extension* pdode = pdo->DeviceExtension; + + AddDevice(drvobj, pdo); + + // To stop Windows sneakily setting DOE_START_PENDING + pdode->dont_report = true; + + if (pdo->DeviceObjectExtension) { + ((DEVOBJ_EXTENSION2*)pdo->DeviceObjectExtension)->ExtensionFlags &= ~DOE_START_PENDING; + + if (pdode && pdode->vde && pdode->vde->device) + ((DEVOBJ_EXTENSION2*)pdode->vde->device->DeviceObjectExtension)->ExtensionFlags &= ~DOE_START_PENDING; + } + + mountmgr_notification(&pdode->uuid); +} + /* If booting from Btrfs, Windows will pass the device object for the raw partition to * mount_vol - which is no good to us, as we only use the \Device\Btrfs{} devices we * create so that RAID works correctly. @@ -276,109 +468,156 @@ static void mountmgr_notification(BTRFS_UUID* uuid) { * point to. */ void __stdcall check_system_root(PDRIVER_OBJECT DriverObject, PVOID Context, ULONG Count) { - uint32_t disk_num, partition_num; + system_root sr; LIST_ENTRY* le; bool done = false; PDEVICE_OBJECT pdo_to_add = NULL; + volume_child* boot_vc = NULL; - TRACE("(%p, %p, %u)\n", DriverObject, Context, Count); + TRACE("(%p, %p, %lu)\n", DriverObject, Context, Count); // wait for any PNP notifications in progress to finish ExAcquireResourceExclusiveLite(&boot_lock, TRUE); ExReleaseResourceLite(&boot_lock); - if (!get_system_root_partition(&disk_num, &partition_num)) - return; + get_system_root(&sr); - TRACE("system boot partition is disk %u, partition %u\n", disk_num, partition_num); + if (sr.type == system_root_partition) { + TRACE("system boot partition is disk %u, partition %u\n", sr.disk_num, sr.partition_num); - ExAcquireResourceSharedLite(&pdo_list_lock, true); + ExAcquireResourceSharedLite(&pdo_list_lock, true); - le = pdo_list.Flink; - while (le != &pdo_list) { - LIST_ENTRY* le2; - pdo_device_extension* pdode = CONTAINING_RECORD(le, pdo_device_extension, list_entry); + le = pdo_list.Flink; + while (le != &pdo_list) { + LIST_ENTRY* le2; + pdo_device_extension* pdode = CONTAINING_RECORD(le, pdo_device_extension, list_entry); - ExAcquireResourceSharedLite(&pdode->child_lock, true); + ExAcquireResourceSharedLite(&pdode->child_lock, true); - le2 = pdode->children.Flink; + le2 = pdode->children.Flink; - while (le2 != &pdode->children) { - volume_child* vc = CONTAINING_RECORD(le2, volume_child, list_entry); + while (le2 != &pdode->children) { + volume_child* vc = CONTAINING_RECORD(le2, volume_child, list_entry); - if (vc->disk_num == disk_num && vc->part_num == partition_num) { - change_symlink(disk_num, partition_num, &pdode->uuid); - done = true; + if (vc->disk_num == sr.disk_num && vc->part_num == sr.partition_num) { + change_symlink(sr.disk_num, sr.partition_num, &pdode->uuid); + done = true; + vc->boot_volume = true; + boot_uuid = pdode->uuid; + + if (!pdode->vde) + pdo_to_add = pdode->pdo; + + boot_vc = vc; + + break; + } + + le2 = le2->Flink; + } + + if (done) { + le2 = pdode->children.Flink; + + while (le2 != &pdode->children) { + volume_child* vc = CONTAINING_RECORD(le2, volume_child, list_entry); + + /* On Windows 7 we need to clear the DO_SYSTEM_BOOT_PARTITION flag of + * all of our underlying partition objects - otherwise IopMountVolume + * will bugcheck with UNMOUNTABLE_BOOT_VOLUME when it tries and fails + * to mount one. */ + if (vc->devobj) { + PDEVICE_OBJECT dev = vc->devobj; + + ObReferenceObject(dev); + + while (dev) { + PDEVICE_OBJECT dev2 = IoGetLowerDeviceObject(dev); + + dev->Flags &= ~DO_SYSTEM_BOOT_PARTITION; + + ObDereferenceObject(dev); + + dev = dev2; + } + } + + le2 = le2->Flink; + } + + ExReleaseResourceLite(&pdode->child_lock); + + break; + } + + ExReleaseResourceLite(&pdode->child_lock); + + le = le->Flink; + } + + ExReleaseResourceLite(&pdo_list_lock); + } else if (sr.type == system_root_btrfs) { + boot_uuid = sr.uuid; + + ExAcquireResourceSharedLite(&pdo_list_lock, true); + + le = pdo_list.Flink; + while (le != &pdo_list) { + pdo_device_extension* pdode = CONTAINING_RECORD(le, pdo_device_extension, list_entry); + + if (RtlCompareMemory(&pdode->uuid, &sr.uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { if (!pdode->vde) pdo_to_add = pdode->pdo; break; } - le2 = le2->Flink; + le = le->Flink; } - if (done) { - le2 = pdode->children.Flink; - - while (le2 != &pdode->children) { - volume_child* vc = CONTAINING_RECORD(le2, volume_child, list_entry); - - /* On Windows 7 we need to clear the DO_SYSTEM_BOOT_PARTITION flag of - * all of our underlying partition objects - otherwise IopMountVolume - * will bugcheck with UNMOUNTABLE_BOOT_VOLUME when it tries and fails - * to mount one. */ - if (vc->devobj) { - PDEVICE_OBJECT dev = vc->devobj; - - ObReferenceObject(dev); - - while (dev) { - PDEVICE_OBJECT dev2 = IoGetLowerDeviceObject(dev); - - dev->Flags &= ~DO_SYSTEM_BOOT_PARTITION; - - ObDereferenceObject(dev); - - dev = dev2; - } - } - - le2 = le2->Flink; - } - - ExReleaseResourceLite(&pdode->child_lock); - - break; - } - - ExReleaseResourceLite(&pdode->child_lock); - - le = le->Flink; + ExReleaseResourceLite(&pdo_list_lock); } - ExReleaseResourceLite(&pdo_list_lock); + if (boot_vc) { + NTSTATUS Status; + UNICODE_STRING name; + + /* On Windows 8, mountmgr!MountMgrFindBootVolume returns the first volume in its database + * with the DO_SYSTEM_BOOT_PARTITION flag set. We've cleared the bit on the underlying devices, + * but as it caches it we need to disable and re-enable the volume so mountmgr receives a PNP + * notification to refresh its list. */ + + static const WCHAR prefix[] = L"\\??"; + + name.Length = name.MaximumLength = boot_vc->pnp_name.Length + sizeof(prefix) - sizeof(WCHAR); + + name.Buffer = ExAllocatePoolWithTag(PagedPool, name.MaximumLength, ALLOC_TAG); + if (!name.Buffer) + ERR("out of memory\n"); + else { + RtlCopyMemory(name.Buffer, prefix, sizeof(prefix) - sizeof(WCHAR)); + RtlCopyMemory(&name.Buffer[(sizeof(prefix) / sizeof(WCHAR)) - 1], boot_vc->pnp_name.Buffer, boot_vc->pnp_name.Length); + + Status = IoSetDeviceInterfaceState(&name, false); + if (!NT_SUCCESS(Status)) + ERR("IoSetDeviceInterfaceState returned %08lx\n", Status); + + Status = IoSetDeviceInterfaceState(&name, true); + if (!NT_SUCCESS(Status)) + ERR("IoSetDeviceInterfaceState returned %08lx\n", Status); + + ExFreePool(name.Buffer); + } + } + + if (sr.type == system_root_btrfs || boot_vc) + check_boot_options(); // If our FS depends on volumes that aren't there when we do our IoRegisterPlugPlayNotification calls // in DriverEntry, bus_query_device_relations won't get called until it's too late. We need to do our // own call to AddDevice here as a result. We need to clear the DOE_START_PENDING bits, or NtOpenFile // will return STATUS_NO_SUCH_DEVICE. - if (pdo_to_add) { - pdo_device_extension* pdode = pdo_to_add->DeviceExtension; - - AddDevice(drvobj, pdo_to_add); - - // To stop Windows sneakily setting DOE_START_PENDING - pdode->dont_report = true; - - if (pdo_to_add->DeviceObjectExtension) { - ((DEVOBJ_EXTENSION2*)pdo_to_add->DeviceObjectExtension)->ExtensionFlags &= ~DOE_START_PENDING; - - if (pdode && pdode->vde && pdode->vde->device) - ((DEVOBJ_EXTENSION2*)pdode->vde->device->DeviceObjectExtension)->ExtensionFlags &= ~DOE_START_PENDING; - } - - mountmgr_notification(&pdode->uuid); - } + if (pdo_to_add) + boot_add_device(pdo_to_add); } diff --git a/drivers/filesystems/btrfs/btrfs.c b/drivers/filesystems/btrfs/btrfs.c index 2080c5d70f7..84495cd36c8 100644 --- a/drivers/filesystems/btrfs/btrfs.c +++ b/drivers/filesystems/btrfs/btrfs.c @@ -20,13 +20,15 @@ #endif #include "btrfs_drv.h" +#include "xxhash.h" +#include "crc32c.h" #ifndef __REACTOS__ #ifndef _MSC_VER #include #else #include #endif -#endif +#endif // __REACTOS__ #include #include "btrfs.h" #include @@ -55,7 +57,7 @@ NTSTATUS RtlStringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat #define INCOMPAT_SUPPORTED (BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF | BTRFS_INCOMPAT_FLAGS_DEFAULT_SUBVOL | BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS | \ BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO | BTRFS_INCOMPAT_FLAGS_BIG_METADATA | BTRFS_INCOMPAT_FLAGS_RAID56 | \ BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF | BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA | BTRFS_INCOMPAT_FLAGS_NO_HOLES | \ - BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD) + BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD | BTRFS_INCOMPAT_FLAGS_METADATA_UUID | BTRFS_INCOMPAT_FLAGS_RAID1C34) #define COMPAT_RO_SUPPORTED (BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE | BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE_VALID) static const WCHAR device_name[] = {'\\','B','t','r','f','s',0}; @@ -66,7 +68,7 @@ DEFINE_GUID(BtrfsBusInterface, 0x4d414874, 0x6865, 0x6761, 0x6d, 0x65, 0x83, 0x6 PDRIVER_OBJECT drvobj; PDEVICE_OBJECT master_devobj, busobj; #ifndef __REACTOS__ -bool have_sse42 = false, have_sse2 = false; +bool have_sse2 = false; #endif uint64_t num_reads = 0; LIST_ENTRY uid_map_list, gid_map_list; @@ -111,6 +113,7 @@ bool degraded_wait = true; KEVENT mountmgr_thread_event; bool shutting_down = false; ERESOURCE boot_lock; +extern uint64_t boot_subvol; #ifdef _DEBUG PFILE_OBJECT comfo = NULL; @@ -169,9 +172,9 @@ void _debug_message(_In_ const char* func, _In_ char* s, ...) { } #ifdef DEBUG_LONG_MESSAGES - sprintf(buf2, "%p:%s:%s:%u:", PsGetCurrentThread(), func, file, line); + sprintf(buf2, "%p:%s:%s:%u:", (void*)PsGetCurrentThread(), func, file, line); #else - sprintf(buf2, "%p:%s:", PsGetCurrentThread(), func); + sprintf(buf2, "%p:%s:", (void*)PsGetCurrentThread(), func); #endif buf = &buf2[strlen(buf2)]; @@ -245,7 +248,7 @@ void _debug_message(_In_ const char* func, _In_ char* s, ...) { IoFreeMdl(Irp->MdlAddress); if (!NT_SUCCESS(Status)) { - DbgPrint("failed to write to COM1 - error %08x\n", Status); + DbgPrint("failed to write to COM1 - error %08lx\n", Status); goto exit; } @@ -259,7 +262,7 @@ exit: Status = ZwWriteFile(log_handle, NULL, NULL, NULL, &iosb, buf2, length, NULL, NULL); if (!NT_SUCCESS(Status)) { - DbgPrint("failed to write to file - error %08x\n", Status); + DbgPrint("failed to write to file - error %08lx\n", Status); } } @@ -350,7 +353,7 @@ static bool get_last_inode(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock Status = find_item(Vcb, r, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return false; } @@ -438,7 +441,7 @@ bool get_xattr(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vc Status = find_item(Vcb, subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return false; } @@ -448,7 +451,7 @@ bool get_xattr(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vc } if (tp.item->size < sizeof(DIR_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM)); return false; } @@ -496,7 +499,7 @@ end: if (top_level) IoSetTopLevelIrp(NULL); - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); FsRtlExitFileSystem(); @@ -561,7 +564,7 @@ static NTSTATUS __stdcall drv_flush_buffers(_In_ PDEVICE_OBJECT DeviceObject, _I end: IoCompleteRequest(Irp, IO_NO_INCREMENT); - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); if (top_level) IoSetTopLevelIrp(NULL); @@ -583,12 +586,18 @@ static void calculate_total_space(_In_ device_extension* Vcb, _Out_ uint64_t* to } else if (Vcb->data_flags & BLOCK_FLAG_RAID6) { nfactor = Vcb->superblock.num_devices - 2; dfactor = Vcb->superblock.num_devices; + } else if (Vcb->data_flags & BLOCK_FLAG_RAID1C3) { + nfactor = 1; + dfactor = 3; + } else if (Vcb->data_flags & BLOCK_FLAG_RAID1C4) { + nfactor = 1; + dfactor = 4; } else { nfactor = 1; dfactor = 1; } - sectors_used = Vcb->superblock.bytes_used / Vcb->superblock.sector_size; + sectors_used = (Vcb->superblock.bytes_used / Vcb->superblock.sector_size) * nfactor / dfactor; *totalsize = (Vcb->superblock.total_bytes / Vcb->superblock.sector_size) * nfactor / dfactor; *freespace = sectors_used > *totalsize ? 0 : (*totalsize - sectors_used); @@ -631,7 +640,7 @@ static bool lie_about_fs_type() { Status = ZwQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), &retlen); if (!NT_SUCCESS(Status)) { - ERR("ZwQueryInformationProcess returned %08x\n", Status); + ERR("ZwQueryInformationProcess returned %08lx\n", Status); return false; } @@ -712,7 +721,7 @@ static bool lie_about_fs_type() { return false; } -#endif +#endif // __REACTOS__ // version of RtlUTF8ToUnicodeN for Vista and below NTSTATUS utf8_to_utf16(WCHAR* dest, ULONG dest_max, ULONG* dest_len, char* src, ULONG src_len) { @@ -1072,13 +1081,13 @@ static NTSTATUS __stdcall drv_query_volume_information(_In_ PDEVICE_OBJECT Devic ULONG label_len, orig_label_len; TRACE("FileFsVolumeInformation\n"); - TRACE("max length = %u\n", IrpSp->Parameters.QueryVolume.Length); + TRACE("max length = %lu\n", IrpSp->Parameters.QueryVolume.Length); ExAcquireResourceSharedLite(&Vcb->tree_lock, true); Status = utf8_to_utf16(NULL, 0, &label_len, Vcb->superblock.label, (ULONG)strlen(Vcb->superblock.label)); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 returned %08x\n", Status); + ERR("utf8_to_utf16 returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->tree_lock); break; } @@ -1094,7 +1103,7 @@ static NTSTATUS __stdcall drv_query_volume_information(_In_ PDEVICE_OBJECT Devic overflow = true; } - TRACE("label_len = %u\n", label_len); + TRACE("label_len = %lu\n", label_len); ffvi.VolumeCreationTime.QuadPart = 0; // FIXME 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]; @@ -1108,12 +1117,12 @@ static NTSTATUS __stdcall drv_query_volume_information(_In_ PDEVICE_OBJECT Devic Status = utf8_to_utf16(&data->VolumeLabel[0], label_len, &bytecount, Vcb->superblock.label, (ULONG)strlen(Vcb->superblock.label)); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) { - ERR("utf8_to_utf16 returned %08x\n", Status); + ERR("utf8_to_utf16 returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->tree_lock); break; } - TRACE("label = %.*S\n", label_len / sizeof(WCHAR), data->VolumeLabel); + TRACE("label = %.*S\n", (int)(label_len / sizeof(WCHAR)), data->VolumeLabel); } ExReleaseResourceLite(&Vcb->tree_lock); @@ -1142,6 +1151,7 @@ static NTSTATUS __stdcall drv_query_volume_information(_In_ PDEVICE_OBJECT Devic data->Flags |= SSINFO_FLAGS_TRIM_ENABLED; BytesCopied = sizeof(FILE_FS_SECTOR_SIZE_INFORMATION); + Status = STATUS_SUCCESS; break; } @@ -1167,7 +1177,7 @@ end: if (top_level) IoSetTopLevelIrp(NULL); - TRACE("query volume information returning %08x\n", Status); + TRACE("query volume information returning %08lx\n", Status); FsRtlExitFileSystem(); @@ -1249,6 +1259,7 @@ NTSTATUS create_root(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) devi r->root_item.num_references = 1; r->fcbs_version = 0; r->checked_for_orphans = true; + r->dropped = false; InitializeListHead(&r->fcbs); RtlZeroMemory(r->fcbs_ptrs, sizeof(LIST_ENTRY*) * 256); @@ -1259,7 +1270,7 @@ NTSTATUS create_root(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) devi Status = insert_tree_item(Vcb, Vcb->root_root, id, TYPE_ROOT_ITEM, offset, ri, sizeof(ROOT_ITEM), &tp, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ri); if (t) @@ -1315,7 +1326,7 @@ static NTSTATUS set_label(_In_ device_extension* Vcb, _In_ FILE_FS_LABEL_INFORMA NTSTATUS Status; ULONG vollen, i; - TRACE("label = %.*S\n", ffli->VolumeLabelLength / sizeof(WCHAR), ffli->VolumeLabel); + TRACE("label = %.*S\n", (int)(ffli->VolumeLabelLength / sizeof(WCHAR)), ffli->VolumeLabel); vollen = ffli->VolumeLabelLength; @@ -1360,7 +1371,7 @@ release: ExReleaseResourceLite(&Vcb->tree_lock); end: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); return Status; } @@ -1423,7 +1434,7 @@ end: Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); IoCompleteRequest( Irp, IO_NO_INCREMENT ); @@ -1445,7 +1456,7 @@ void send_notification_fileref(_In_ file_ref* fileref, _In_ ULONG filter_match, fn.Length = fn.MaximumLength = 0; Status = fileref_get_filename(fileref, &fn, NULL, &reqlen); if (Status != STATUS_BUFFER_OVERFLOW) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); return; } @@ -1465,7 +1476,7 @@ void send_notification_fileref(_In_ file_ref* fileref, _In_ ULONG filter_match, Status = fileref_get_filename(fileref, &fn, &name_offset, &reqlen); if (!NT_SUCCESS(Status)) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); ExFreePool(fn.Buffer); return; } @@ -1496,7 +1507,7 @@ static void send_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_matc Status = open_fileref_by_inode(fcb->Vcb, fcb->subvol, hl->parent, &parfr, NULL); if (!NT_SUCCESS(Status)) - ERR("open_fileref_by_inode returned %08x\n", Status); + ERR("open_fileref_by_inode returned %08lx\n", Status); else if (!parfr->deleted) { UNICODE_STRING fn; ULONG pathlen; @@ -1504,7 +1515,7 @@ static void send_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_matc fn.Length = fn.MaximumLength = 0; Status = fileref_get_filename(parfr, &fn, NULL, &pathlen); if (Status != STATUS_BUFFER_OVERFLOW) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); free_fileref(parfr); break; } @@ -1528,7 +1539,7 @@ static void send_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_matc Status = fileref_get_filename(parfr, &fn, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); free_fileref(parfr); ExFreePool(fn.Buffer); break; @@ -1669,9 +1680,16 @@ void reap_fcb(fcb* fcb) { fcb->subvol->fcbs_ptrs[c] = NULL; } - if (fcb->list_entry.Flink) + if (fcb->list_entry.Flink) { RemoveEntryList(&fcb->list_entry); + if (fcb->subvol && fcb->subvol->dropped && IsListEmpty(&fcb->subvol->fcbs)) { + ExDeleteResourceLite(&fcb->subvol->nonpaged->load_tree_lock); + ExFreePool(fcb->subvol->nonpaged); + ExFreePool(fcb->subvol); + } + } + if (fcb->list_entry_all.Flink) RemoveEntryList(&fcb->list_entry_all); @@ -1779,7 +1797,7 @@ void free_fileref(_Inout_ file_ref* fr) { #ifdef _DEBUG if (rc < 0) { - ERR("fileref %p: refcount now %i\n", fr, rc); + ERR("fileref %p: refcount now %li\n", fr, rc); int3; } #endif @@ -1937,7 +1955,9 @@ void uninit(_In_ device_extension* Vcb) { Vcb->Vpb->DeviceObject = NULL; IoReleaseVpbSpinLock(irql); - RemoveEntryList(&Vcb->list_entry); + // FIXME - needs global_loading_lock to be held + if (Vcb->list_entry.Flink) + RemoveEntryList(&Vcb->list_entry); if (Vcb->balance.thread) { Vcb->balance.paused = false; @@ -1984,7 +2004,7 @@ void uninit(_In_ device_extension* Vcb) { Status = registry_mark_volume_unmounted(&Vcb->superblock.uuid); if (!NT_SUCCESS(Status) && Status != STATUS_TOO_LATE) - WARN("registry_mark_volume_unmounted returned %08x\n", Status); + WARN("registry_mark_volume_unmounted returned %08lx\n", Status); for (i = 0; i < Vcb->calcthreads.num_threads; i++) { Vcb->calcthreads.threads[i].quit = true; @@ -1998,7 +2018,6 @@ void uninit(_In_ device_extension* Vcb) { ZwClose(Vcb->calcthreads.threads[i].handle); } - ExDeleteResourceLite(&Vcb->calcthreads.lock); ExFreePool(Vcb->calcthreads.threads); time.QuadPart = 0; @@ -2137,7 +2156,7 @@ static NTSTATUS delete_fileref_fcb(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT if (fileref->fcb->type != BTRFS_TYPE_DIRECTORY && fileref->fcb->inode_item.st_size > 0) { Status = excise_extents(fileref->fcb->Vcb, fileref->fcb, 0, sector_align(fileref->fcb->inode_item.st_size, fileref->fcb->Vcb->superblock.sector_size), Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); return Status; } } @@ -2162,7 +2181,7 @@ static NTSTATUS delete_fileref_fcb(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("CcSetFileSizes threw exception %08x\n", Status); + ERR("CcSetFileSizes threw exception %08lx\n", Status); return Status; } } @@ -2228,7 +2247,7 @@ NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT FileObject } else { Status = delete_fileref_fcb(fileref, FileObject, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref_fcb returned %08x\n", Status); + ERR("delete_fileref_fcb returned %08lx\n", Status); ExReleaseResourceLite(fileref->fcb->Header.Resource); return Status; } @@ -2290,7 +2309,7 @@ NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT FileObject // remove dir_child from parent if (fileref->dc) { - TRACE("delete file %.*S\n", fileref->dc->name.Length / sizeof(WCHAR), fileref->dc->name.Buffer); + TRACE("delete file %.*S\n", (int)(fileref->dc->name.Length / sizeof(WCHAR)), fileref->dc->name.Buffer); ExAcquireResourceExclusiveLite(&fileref->parent->fcb->nonpaged->dir_children_lock, true); RemoveEntryList(&fileref->dc->list_entry_index); @@ -2407,7 +2426,7 @@ static NTSTATUS __stdcall drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIR fileref = ccb ? ccb->fileref : NULL; TRACE("cleanup called for FileObject %p\n", FileObject); - TRACE("fileref %p, refcount = %u, open_count = %u\n", fileref, fileref ? fileref->refcount : 0, fileref ? fileref->open_count : 0); + TRACE("fileref %p, refcount = %li, open_count = %li\n", fileref, fileref ? fileref->refcount : 0, fileref ? fileref->open_count : 0); ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, true); @@ -2455,7 +2474,7 @@ static NTSTATUS __stdcall drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIR Status = delete_fileref_fcb(fileref, FileObject, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref_fcb returned %08x\n", Status); + ERR("delete_fileref_fcb returned %08lx\n", Status); do_rollback(fcb->Vcb, &rollback); ExReleaseResourceLite(fileref->fcb->Header.Resource); ExReleaseResourceLite(&fcb->Vcb->tree_lock); @@ -2486,7 +2505,7 @@ static NTSTATUS __stdcall drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIR Status = delete_fileref(fileref, FileObject, oc > 0 && fileref->posix_delete, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref returned %08x\n", Status); + ERR("delete_fileref returned %08lx\n", Status); do_rollback(fcb->Vcb, &rollback); ExReleaseResourceLite(&fcb->Vcb->fileref_lock); ExReleaseResourceLite(&fcb->Vcb->tree_lock); @@ -2498,11 +2517,16 @@ static NTSTATUS __stdcall drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIR clear_rollback(&rollback); } else if (FileObject->Flags & FO_CACHE_SUPPORTED && FileObject->SectionObjectPointer->DataSectionObject) { IO_STATUS_BLOCK iosb; + + if (locked) { + ExReleaseResourceLite(fcb->Header.Resource); + locked = false; + } + CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, &iosb); - if (!NT_SUCCESS(iosb.Status)) { - ERR("CcFlushCache returned %08x\n", iosb.Status); - } + if (!NT_SUCCESS(iosb.Status)) + ERR("CcFlushCache returned %08lx\n", iosb.Status); if (!ExIsResourceAcquiredSharedLite(fcb->Header.PagingIoResource)) { ExAcquireResourceExclusiveLite(fcb->Header.PagingIoResource, true); @@ -2531,7 +2555,7 @@ static NTSTATUS __stdcall drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIR Status = STATUS_SUCCESS; exit: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; @@ -2563,7 +2587,7 @@ bool get_file_attributes_from_xattr(_In_reads_bytes_(len) char* val, _In_ uint16 dosnum |= val[i] + 10 - 'a'; } - TRACE("DOSATTRIB: %08x\n", dosnum); + TRACE("DOSATTRIB: %08lx\n", dosnum); *atts = dosnum; @@ -2700,7 +2724,7 @@ NTSTATUS sync_read_phys(_In_ PDEVICE_OBJECT DeviceObject, _In_ PFILE_OBJECT File } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(Irp->MdlAddress); goto exit; } @@ -2734,6 +2758,63 @@ exit: return Status; } +bool check_superblock_checksum(superblock* sb) { + switch (sb->csum_type) { + case CSUM_TYPE_CRC32C: { + uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); + + if (crc32 == *((uint32_t*)sb->checksum)) + return true; + + WARN("crc32 was %08x, expected %08x\n", crc32, *((uint32_t*)sb->checksum)); + + break; + } + + case CSUM_TYPE_XXHASH: { + uint64_t hash = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0); + + if (hash == *((uint64_t*)sb->checksum)) + return true; + + WARN("superblock hash was %I64x, expected %I64x\n", hash, *((uint64_t*)sb->checksum)); + + break; + } + + case CSUM_TYPE_SHA256: { + uint8_t hash[SHA256_HASH_SIZE]; + + calc_sha256(hash, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum)); + + if (RtlCompareMemory(hash, sb, SHA256_HASH_SIZE) == SHA256_HASH_SIZE) + return true; + + WARN("superblock hash was invalid\n"); + + break; + } + + case CSUM_TYPE_BLAKE2: { + uint8_t hash[BLAKE2_HASH_SIZE]; + + blake2b(hash, sizeof(hash), &sb->uuid, sizeof(superblock) - sizeof(sb->checksum)); + + if (RtlCompareMemory(hash, sb, BLAKE2_HASH_SIZE) == BLAKE2_HASH_SIZE) + return true; + + WARN("superblock hash was invalid\n"); + + break; + } + + default: + WARN("unrecognized csum type %x\n", sb->csum_type); + } + + return false; +} + static NTSTATUS read_superblock(_In_ device_extension* Vcb, _In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj, _In_ uint64_t length) { NTSTATUS Status; superblock* sb; @@ -2758,14 +2839,12 @@ static NTSTATUS read_superblock(_In_ device_extension* Vcb, _In_ PDEVICE_OBJECT valid_superblocks = 0; while (superblock_addrs[i] > 0) { - uint32_t crc32; - if (i > 0 && superblock_addrs[i] + to_read > length) break; Status = sync_read_phys(device, fileobj, superblock_addrs[i], to_read, (PUCHAR)sb, false); if (!NT_SUCCESS(Status)) { - ERR("Failed to read superblock %u: %08x\n", i, Status); + ERR("Failed to read superblock %lu: %08lx\n", i, Status); ExFreePool(sb); return Status; } @@ -2777,19 +2856,15 @@ static NTSTATUS read_superblock(_In_ device_extension* Vcb, _In_ PDEVICE_OBJECT return STATUS_UNRECOGNIZED_VOLUME; } } else { - TRACE("got superblock %u!\n", i); + TRACE("got superblock %lu!\n", i); - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - - if (crc32 != *((uint32_t*)sb->checksum)) - WARN("crc32 was %08x, expected %08x\n", crc32, *((uint32_t*)sb->checksum)); - else if (sb->sector_size == 0) + if (sb->sector_size == 0) WARN("superblock sector size was 0\n"); else if (sb->node_size < sizeof(tree_header) + sizeof(internal_node) || sb->node_size > 0x10000) WARN("invalid node size %x\n", sb->node_size); else if ((sb->node_size % sb->sector_size) != 0) WARN("node size %x was not a multiple of sector_size %x\n", sb->node_size, sb->sector_size); - else if (valid_superblocks == 0 || sb->generation > Vcb->superblock.generation) { + else if (check_superblock_checksum(sb) && (valid_superblocks == 0 || sb->generation > Vcb->superblock.generation)) { RtlCopyMemory(&Vcb->superblock, sb, sizeof(superblock)); valid_superblocks++; } @@ -2870,6 +2945,7 @@ static NTSTATUS add_root(_Inout_ device_extension* Vcb, _In_ uint64_t id, _In_ u r->send_ops = 0; r->fcbs_version = 0; r->checked_for_orphans = false; + r->dropped = false; InitializeListHead(&r->fcbs); RtlZeroMemory(r->fcbs_ptrs, sizeof(LIST_ENTRY*) * 256); @@ -2950,7 +3026,7 @@ static NTSTATUS look_for_roots(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -2961,13 +3037,13 @@ static NTSTATUS look_for_roots(_Requires_exclusive_lock_held_(_Curr_->tree_lock) ROOT_ITEM* ri = (ROOT_ITEM*)tp.item->data; if (tp.item->size < offsetof(ROOT_ITEM, byte_limit)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(ROOT_ITEM, byte_limit)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(ROOT_ITEM, byte_limit)); } else { TRACE("root %I64x - address %I64x\n", tp.item->key.obj_id, ri->block_number); Status = add_root(Vcb, tp.item->key.obj_id, ri->block_number, ri->generation, &tp); if (!NT_SUCCESS(Status)) { - ERR("add_root returned %08x\n", Status); + ERR("add_root returned %08lx\n", Status); return Status; } } @@ -2997,7 +3073,7 @@ static NTSTATUS look_for_roots(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = create_root(Vcb, BTRFS_ROOT_DATA_RELOC, &reloc_root, false, 0, Irp); if (!NT_SUCCESS(Status)) { - ERR("create_root returned %08x\n", Status); + ERR("create_root returned %08lx\n", Status); return Status; } @@ -3030,7 +3106,7 @@ static NTSTATUS look_for_roots(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = insert_tree_item(Vcb, reloc_root, SUBVOL_ROOT_INODE, TYPE_INODE_ITEM, 0, ii, sizeof(INODE_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ii); return Status; } @@ -3049,7 +3125,7 @@ static NTSTATUS look_for_roots(_Requires_exclusive_lock_held_(_Curr_->tree_lock) Status = insert_tree_item(Vcb, reloc_root, SUBVOL_ROOT_INODE, TYPE_INODE_REF, SUBVOL_ROOT_INODE, ir, irlen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ir); return Status; } @@ -3084,7 +3160,7 @@ static NTSTATUS find_disk_holes(_In_ _Requires_lock_held_(_Curr_->tree_lock) dev Status = find_item(Vcb, Vcb->dev_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -3098,14 +3174,14 @@ static NTSTATUS find_disk_holes(_In_ _Requires_lock_held_(_Curr_->tree_lock) dev if (tp.item->key.offset > lastaddr) { Status = add_space_entry(&dev->space, NULL, lastaddr, tp.item->key.offset - lastaddr); if (!NT_SUCCESS(Status)) { - ERR("add_space_entry returned %08x\n", Status); + ERR("add_space_entry returned %08lx\n", Status); return Status; } } lastaddr = tp.item->key.offset + de->length; } else { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DEV_EXTENT)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DEV_EXTENT)); } } @@ -3121,7 +3197,7 @@ static NTSTATUS find_disk_holes(_In_ _Requires_lock_held_(_Curr_->tree_lock) dev if (lastaddr < dev->devitem.num_bytes) { Status = add_space_entry(&dev->space, NULL, lastaddr, dev->devitem.num_bytes - lastaddr); if (!NT_SUCCESS(Status)) { - ERR("add_space_entry returned %08x\n", Status); + ERR("add_space_entry returned %08lx\n", Status); return Status; } } @@ -3243,7 +3319,7 @@ static bool is_device_removable(_In_ PDEVICE_OBJECT devobj) { Status = dev_ioctl(devobj, IOCTL_STORAGE_GET_HOTPLUG_INFO, NULL, 0, &shi, sizeof(STORAGE_HOTPLUG_INFO), true, NULL); if (!NT_SUCCESS(Status)) { - ERR("dev_ioctl returned %08x\n", Status); + ERR("dev_ioctl returned %08lx\n", Status); return false; } @@ -3258,7 +3334,7 @@ static ULONG get_device_change_count(_In_ PDEVICE_OBJECT devobj) { Status = dev_ioctl(devobj, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, &cc, sizeof(ULONG), true, &iosb); if (!NT_SUCCESS(Status)) { - ERR("dev_ioctl returned %08x\n", Status); + ERR("dev_ioctl returned %08lx\n", Status); return 0; } @@ -3287,7 +3363,7 @@ void init_device(_In_ device_extension* Vcb, _Inout_ device* dev, _In_ bool get_ &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL); if (!NT_SUCCESS(Status)) { - WARN("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08x\n", Status); + WARN("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status); dev->disk_num = 0xffffffff; dev->part_num = 0xffffffff; } else { @@ -3330,7 +3406,7 @@ void init_device(_In_ device_extension* Vcb, _Inout_ device* dev, _In_ bool get_ apte, aptelen, true, NULL); if (!NT_SUCCESS(Status)) - TRACE("IOCTL_ATA_PASS_THROUGH returned %08x for IDENTIFY DEVICE\n", Status); + TRACE("IOCTL_ATA_PASS_THROUGH returned %08lx for IDENTIFY DEVICE\n", Status); else { IDENTIFY_DEVICE_DATA* idd = (IDENTIFY_DEVICE_DATA*)((uint8_t*)apte + sizeof(ATA_PASS_THROUGH_EX)); @@ -3384,7 +3460,7 @@ static NTSTATUS load_chunk_root(_In_ _Requires_lock_held_(_Curr_->tree_lock) dev Status = find_item(Vcb, Vcb->chunk_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -3393,7 +3469,7 @@ static NTSTATUS load_chunk_root(_In_ _Requires_lock_held_(_Curr_->tree_lock) dev if (tp.item->key.obj_id == 1 && tp.item->key.obj_type == TYPE_DEV_ITEM) { if (tp.item->size < sizeof(DEV_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DEV_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DEV_ITEM)); } else { DEV_ITEM* di = (DEV_ITEM*)tp.item->data; LIST_ENTRY* le; @@ -3498,7 +3574,7 @@ static NTSTATUS load_chunk_root(_In_ _Requires_lock_held_(_Curr_->tree_lock) dev } } else if (tp.item->key.obj_type == TYPE_CHUNK_ITEM) { if (tp.item->size < sizeof(CHUNK_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(CHUNK_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(CHUNK_ITEM)); } else { c = ExAllocatePoolWithTag(NonPagedPool, sizeof(chunk), ALLOC_TAG); @@ -3562,7 +3638,7 @@ static NTSTATUS load_chunk_root(_In_ _Requires_lock_held_(_Curr_->tree_lock) dev for (i = 0; i < c->chunk_item->num_stripes; i++) { c->devices[i] = find_device_from_uuid(Vcb, &cis[i].dev_uuid); - TRACE("device %I64u = %p\n", i, c->devices[i]); + TRACE("device %u = %p\n", i, c->devices[i]); if (!c->devices[i]) { ERR("missing device\n"); @@ -3711,7 +3787,7 @@ void protect_superblocks(_Inout_ chunk* c) { space_list_subtract(c, false, c->offset + off_start, off_end - off_start, NULL); } } - } else { // SINGLE, DUPLICATE, RAID1 + } else { // SINGLE, DUPLICATE, RAID1, RAID1C3, RAID1C4 for (j = 0; j < ci->num_stripes; j++) { if (cis[j].offset + ci->size > superblock_addrs[i] && cis[j].offset <= superblock_addrs[i] + sizeof(superblock)) { TRACE("cut out superblock in chunk %I64x\n", c->offset); @@ -3742,6 +3818,12 @@ uint64_t chunk_estimate_phys_size(device_extension* Vcb, chunk* c, uint64_t u) { } else if (c->chunk_item->type & BLOCK_FLAG_RAID6) { nfactor = Vcb->superblock.num_devices - 2; dfactor = Vcb->superblock.num_devices; + } else if (c->chunk_item->type & BLOCK_FLAG_RAID1C3) { + nfactor = 1; + dfactor = 3; + } else if (c->chunk_item->type & BLOCK_FLAG_RAID1C4) { + nfactor = 1; + dfactor = 4; } else { nfactor = 1; dfactor = 1; @@ -3770,7 +3852,7 @@ NTSTATUS find_chunk_usage(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_ex Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -3784,7 +3866,7 @@ NTSTATUS find_chunk_usage(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_ex Vcb->superblock.bytes_used += chunk_estimate_phys_size(Vcb, c, bgi->used); } else { - ERR("(%I64x;%I64x,%x,%I64x) is %u bytes, expected %u\n", + ERR("(%I64x;%I64x,%x,%I64x) is %u bytes, expected %Iu\n", Vcb->extent_root->id, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(BLOCK_GROUP_ITEM)); } } @@ -3885,7 +3967,7 @@ root* find_default_subvol(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_ex Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -3895,14 +3977,14 @@ root* find_default_subvol(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_ex } if (tp.item->size < sizeof(DIR_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM)); goto end; } di = (DIR_ITEM*)tp.item->data; if (tp.item->size < sizeof(DIR_ITEM) - 1 + di->n) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM) - 1 + di->n); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM) - 1 + di->n); goto end; } @@ -3982,7 +4064,7 @@ static NTSTATUS create_calc_threads(_In_ PDEVICE_OBJECT DeviceObject) { } InitializeListHead(&Vcb->calcthreads.job_list); - ExInitializeResourceLite(&Vcb->calcthreads.lock); + KeInitializeSpinLock(&Vcb->calcthreads.spinlock); KeInitializeEvent(&Vcb->calcthreads.event, NotificationEvent, false); RtlZeroMemory(Vcb->calcthreads.threads, sizeof(drv_calc_thread) * Vcb->calcthreads.num_threads); @@ -3993,13 +4075,14 @@ static NTSTATUS create_calc_threads(_In_ PDEVICE_OBJECT DeviceObject) { NTSTATUS Status; Vcb->calcthreads.threads[i].DeviceObject = DeviceObject; + Vcb->calcthreads.threads[i].number = i; KeInitializeEvent(&Vcb->calcthreads.threads[i].finished, NotificationEvent, false); Status = PsCreateSystemThread(&Vcb->calcthreads.threads[i].handle, 0, &oa, NULL, NULL, calc_thread, &Vcb->calcthreads.threads[i]); if (!NT_SUCCESS(Status)) { ULONG j; - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); for (j = 0; j < i; j++) { Vcb->calcthreads.threads[i].quit = true; @@ -4021,7 +4104,7 @@ static bool is_btrfs_volume(_In_ PDEVICE_OBJECT DeviceObject) { Status = dev_ioctl(DeviceObject, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &mdn, sizeof(MOUNTDEV_NAME), true, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); return false; } @@ -4035,7 +4118,7 @@ static bool is_btrfs_volume(_In_ PDEVICE_OBJECT DeviceObject) { Status = dev_ioctl(DeviceObject, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL); if (!NT_SUCCESS(Status)) { - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); ExFreePool(mdn2); return false; } @@ -4057,7 +4140,7 @@ static NTSTATUS get_device_pnp_name_guid(_In_ PDEVICE_OBJECT DeviceObject, _Out_ Status = IoGetDeviceInterfaces((PVOID)guid, NULL, 0, &list); if (!NT_SUCCESS(Status)) { - ERR("IoGetDeviceInterfaces returned %08x\n", Status); + ERR("IoGetDeviceInterfaces returned %08lx\n", Status); return Status; } @@ -4135,7 +4218,6 @@ static NTSTATUS check_mount_device(_In_ PDEVICE_OBJECT DeviceObject, _Out_ bool* NTSTATUS Status; ULONG to_read; superblock* sb; - uint32_t crc32; UNICODE_STRING pnp_name; const GUID* guid; @@ -4149,7 +4231,7 @@ static NTSTATUS check_mount_device(_In_ PDEVICE_OBJECT DeviceObject, _Out_ bool* Status = sync_read_phys(DeviceObject, NULL, superblock_addrs[0], to_read, (PUCHAR)sb, true); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); goto end; } @@ -4158,10 +4240,7 @@ static NTSTATUS check_mount_device(_In_ PDEVICE_OBJECT DeviceObject, _Out_ bool* goto end; } - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - - if (crc32 != *((uint32_t*)sb->checksum)) { - WARN("crc32 was %08x, expected %08x\n", crc32, *((uint32_t*)sb->checksum)); + if (!check_superblock_checksum(sb)) { Status = STATUS_SUCCESS; goto end; } @@ -4172,7 +4251,7 @@ static NTSTATUS check_mount_device(_In_ PDEVICE_OBJECT DeviceObject, _Out_ bool* Status = get_device_pnp_name(DeviceObject, &pnp_name, &guid); if (!NT_SUCCESS(Status)) { - WARN("get_device_pnp_name returned %08x\n", Status); + WARN("get_device_pnp_name returned %08lx\n", Status); pnp_name.Length = 0; } @@ -4207,7 +4286,7 @@ static bool still_has_superblock(_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT f Status = sync_read_phys(device, fileobj, superblock_addrs[0], to_read, (PUCHAR)sb, true); if (!NT_SUCCESS(Status)) { - ERR("Failed to read superblock: %08x\n", Status); + ERR("Failed to read superblock: %08lx\n", Status); ExFreePool(sb); return false; } @@ -4217,10 +4296,7 @@ static bool still_has_superblock(_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT f ExFreePool(sb); return false; } else { - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - - if (crc32 != *((uint32_t*)sb->checksum)) { - WARN("crc32 was %08x, expected %08x\n", crc32, *((uint32_t*)sb->checksum)); + if (!check_superblock_checksum(sb)) { ExFreePool(sb); return false; } @@ -4286,7 +4362,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = check_mount_device(DeviceToMount, ¬_pnp); if (!NT_SUCCESS(Status)) - WARN("check_mount_device returned %08x\n", Status); + WARN("check_mount_device returned %08lx\n", Status); if (!not_pnp) { Status = STATUS_UNRECOGNIZED_VOLUME; @@ -4386,7 +4462,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { &gli, sizeof(gli), true, NULL); if (!NT_SUCCESS(Status)) { - ERR("error reading length information: %08x\n", Status); + ERR("error reading length information: %08lx\n", Status); goto exit; } @@ -4395,7 +4471,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = IoCreateDevice(drvobj, sizeof(device_extension), NULL, FILE_DEVICE_DISK_FILE_SYSTEM, 0, false, &NewDeviceObject); if (!NT_SUCCESS(Status)) { - ERR("IoCreateDevice returned %08x\n", Status); + ERR("IoCreateDevice returned %08lx\n", Status); Status = STATUS_UNRECOGNIZED_VOLUME; goto exit; } @@ -4447,12 +4523,15 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = registry_load_volume_options(Vcb); if (!NT_SUCCESS(Status)) { - ERR("registry_load_volume_options returned %08x\n", Status); + ERR("registry_load_volume_options returned %08lx\n", Status); goto exit; } + if (pdode && RtlCompareMemory(&boot_uuid, &pdode->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID) && boot_subvol != 0) + Vcb->options.subvol_id = boot_subvol; + if (pdode && pdode->children_loaded < pdode->num_children && (!Vcb->options.allow_degraded || !finished_probing || degraded_wait)) { - ERR("could not mount as %u device(s) missing\n", pdode->num_children - pdode->children_loaded); + ERR("could not mount as %I64u device(s) missing\n", pdode->num_children - pdode->children_loaded); Status = STATUS_DEVICE_NOT_READY; goto exit; } @@ -4469,6 +4548,9 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { goto exit; } + if (!(Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_METADATA_UUID)) + Vcb->superblock.metadata_uuid = Vcb->superblock.uuid; + Vcb->readonly = false; if (Vcb->superblock.compat_ro_flags & ~COMPAT_RO_SUPPORTED) { WARN("mounting read-only because of unsupported flags (%I64x)\n", Vcb->superblock.compat_ro_flags & ~COMPAT_RO_SUPPORTED); @@ -4481,6 +4563,33 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Vcb->superblock.generation++; Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF; + if (Vcb->superblock.log_tree_addr != 0) { + FIXME("FIXME - replay transaction log (clearing for now)\n"); + Vcb->superblock.log_tree_addr = 0; + } + + switch (Vcb->superblock.csum_type) { + case CSUM_TYPE_CRC32C: + Vcb->csum_size = sizeof(uint32_t); + break; + + case CSUM_TYPE_XXHASH: + Vcb->csum_size = sizeof(uint64_t); + break; + + case CSUM_TYPE_SHA256: + Vcb->csum_size = SHA256_HASH_SIZE; + break; + + case CSUM_TYPE_BLAKE2: + Vcb->csum_size = BLAKE2_HASH_SIZE; + break; + + default: + ERR("unrecognized csum type %x\n", Vcb->superblock.csum_type); + break; + } + InitializeListHead(&Vcb->devices); dev = ExAllocatePoolWithTag(NonPagedPool, sizeof(device), ALLOC_TAG); if (!dev) { @@ -4532,7 +4641,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { InitializeListHead(&Vcb->sys_chunks); Status = load_sys_chunks(Vcb); if (!NT_SUCCESS(Status)) { - ERR("load_sys_chunks returned %08x\n", Status); + ERR("load_sys_chunks returned %08lx\n", Status); goto exit; } @@ -4567,13 +4676,13 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = load_chunk_root(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("load_chunk_root returned %08x\n", Status); + ERR("load_chunk_root returned %08lx\n", Status); goto exit; } if (Vcb->superblock.num_devices > 1) { if (Vcb->devices_loaded < Vcb->superblock.num_devices && (!Vcb->options.allow_degraded || !finished_probing)) { - ERR("could not mount as %u device(s) missing\n", Vcb->superblock.num_devices - Vcb->devices_loaded); + ERR("could not mount as %I64u device(s) missing\n", Vcb->superblock.num_devices - Vcb->devices_loaded); IoRaiseInformationalHardError(IO_ERR_INTERNAL_ERROR, NULL, NULL); @@ -4619,14 +4728,14 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = look_for_roots(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("look_for_roots returned %08x\n", Status); + ERR("look_for_roots returned %08lx\n", Status); goto exit; } if (!Vcb->readonly) { Status = find_chunk_usage(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_chunk_usage returned %08x\n", Status); + ERR("find_chunk_usage returned %08lx\n", Status); goto exit; } } @@ -4647,7 +4756,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = clear_free_space_cache(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("clear_free_space_cache returned %08x\n", Status); + ERR("clear_free_space_cache returned %08lx\n", Status); clear_batch_list(Vcb, &batchlist); goto exit; } @@ -4655,7 +4764,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = commit_batch_list(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list returned %08x\n", Status); + ERR("commit_batch_list returned %08lx\n", Status); goto exit; } @@ -4729,7 +4838,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = load_dir_children(Vcb, root_fcb, true, Irp); if (!NT_SUCCESS(Status)) { - ERR("load_dir_children returned %08x\n", Status); + ERR("load_dir_children returned %08lx\n", Status); goto exit; } @@ -4739,7 +4848,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = find_item(Vcb, root_fcb->subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto exit; } @@ -4756,6 +4865,9 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { root_fcb->atts = get_file_attributes(Vcb, root_fcb->subvol, root_fcb->inode, root_fcb->type, false, false, Irp); + if (root_fcb->subvol->id == BTRFS_ROOT_FSTREE) + root_fcb->atts &= ~FILE_ATTRIBUTE_HIDDEN; + Vcb->root_fileref = create_fileref(Vcb); if (!Vcb->root_fileref) { ERR("out of memory\n"); @@ -4802,7 +4914,7 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = find_disk_holes(Vcb, dev2, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_disk_holes returned %08x\n", Status); + ERR("find_disk_holes returned %08lx\n", Status); goto exit; } @@ -4827,23 +4939,23 @@ static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { Status = PsCreateSystemThread(&Vcb->flush_thread_handle, 0, &oa, NULL, NULL, flush_thread, NewDeviceObject); if (!NT_SUCCESS(Status)) { - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); goto exit; } Status = create_calc_threads(NewDeviceObject); if (!NT_SUCCESS(Status)) { - ERR("create_calc_threads returned %08x\n", Status); + ERR("create_calc_threads returned %08lx\n", Status); goto exit; } Status = registry_mark_volume_mounted(&Vcb->superblock.uuid); if (!NT_SUCCESS(Status)) - WARN("registry_mark_volume_mounted returned %08x\n", Status); + WARN("registry_mark_volume_mounted returned %08lx\n", Status); Status = look_for_balance_item(Vcb); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) - WARN("look_for_balance_item returned %08x\n", Status); + WARN("look_for_balance_item returned %08lx\n", Status); Status = STATUS_SUCCESS; @@ -4928,7 +5040,6 @@ exit2: static NTSTATUS verify_device(_In_ device_extension* Vcb, _Inout_ device* dev) { NTSTATUS Status; superblock* sb; - uint32_t crc32; ULONG to_read, cc; if (!dev->devobj) @@ -4940,7 +5051,7 @@ static NTSTATUS verify_device(_In_ device_extension* Vcb, _Inout_ device* dev) { Status = dev_ioctl(dev->devobj, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, &cc, sizeof(ULONG), true, &iosb); if (IoIsErrorUserInduced(Status)) { - ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08x (user-induced)\n", Status); + ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08lx (user-induced)\n", Status); if (Vcb->vde) { pdo_device_extension* pdode = Vcb->vde->pdode; @@ -4969,7 +5080,7 @@ static NTSTATUS verify_device(_In_ device_extension* Vcb, _Inout_ device* dev) { ExReleaseResourceLite(&pdode->child_lock); } } else if (!NT_SUCCESS(Status)) { - ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08x\n", Status); + ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08lx\n", Status); return Status; } else if (iosb.Information < sizeof(ULONG)) { ERR("iosb.Information was too short\n"); @@ -4989,7 +5100,7 @@ static NTSTATUS verify_device(_In_ device_extension* Vcb, _Inout_ device* dev) { Status = sync_read_phys(dev->devobj, dev->fileobj, superblock_addrs[0], to_read, (PUCHAR)sb, true); if (!NT_SUCCESS(Status)) { - ERR("Failed to read superblock: %08x\n", Status); + ERR("Failed to read superblock: %08lx\n", Status); ExFreePool(sb); return Status; } @@ -5000,11 +5111,7 @@ static NTSTATUS verify_device(_In_ device_extension* Vcb, _Inout_ device* dev) { return STATUS_WRONG_VOLUME; } - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - TRACE("crc32 was %08x, expected %08x\n", crc32, *((uint32_t*)sb->checksum)); - - if (crc32 != *((uint32_t*)sb->checksum)) { - ERR("checksum error\n"); + if (!check_superblock_checksum(sb)) { ExFreePool(sb); return STATUS_WRONG_VOLUME; } @@ -5146,7 +5253,7 @@ static NTSTATUS __stdcall drv_file_system_control(_In_ PDEVICE_OBJECT DeviceObje } end: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); if (Irp) { Irp->IoStatus.Status = Status; @@ -5199,7 +5306,7 @@ static NTSTATUS __stdcall drv_lock_control(_In_ PDEVICE_OBJECT DeviceObject, _In fcb->Header.IsFastIoPossible = fast_io_possible(fcb); exit: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); if (top_level) IoSetTopLevelIrp(NULL); @@ -5222,12 +5329,16 @@ void do_shutdown(PIRP Irp) { device_extension* Vcb = CONTAINING_RECORD(le, device_extension, list_entry); volume_device_extension* vde = Vcb->vde; + PDEVICE_OBJECT devobj = vde ? vde->device : NULL; TRACE("shutting down Vcb %p\n", Vcb); if (vde) InterlockedIncrement(&vde->open_count); + if (devobj) + ObReferenceObject(devobj); + dismount_volume(Vcb, true, Irp); if (vde) { @@ -5236,11 +5347,12 @@ void do_shutdown(PIRP Irp) { PDEVICE_OBJECT mountmgr; PFILE_OBJECT mountmgrfo; KIRQL irql; + PVPB newvpb; RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr); if (!NT_SUCCESS(Status)) - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); else { remove_drive_letter(mountmgr, &vde->name); @@ -5249,14 +5361,30 @@ void do_shutdown(PIRP Irp) { vde->removing = true; + newvpb = ExAllocatePoolWithTag(NonPagedPool, sizeof(VPB), ALLOC_TAG); + if (!newvpb) { + ERR("out of memory\n"); + return; + } + + RtlZeroMemory(newvpb, sizeof(VPB)); + + newvpb->Type = IO_TYPE_VPB; + newvpb->Size = sizeof(VPB); + newvpb->RealDevice = newvpb->DeviceObject = vde->device; + newvpb->Flags = VPB_DIRECT_WRITES_ALLOWED; + IoAcquireVpbSpinLock(&irql); - vde->device->Vpb->DeviceObject = vde->device; + vde->device->Vpb = newvpb; IoReleaseVpbSpinLock(irql); if (InterlockedDecrement(&vde->open_count) == 0) free_vol(vde); } + if (devobj) + ObDereferenceObject(devobj); + le = le2; } @@ -5342,6 +5470,114 @@ end: return Status; } +static bool device_still_valid(device* dev, uint64_t expected_generation) { + NTSTATUS Status; + unsigned int to_read; + superblock* sb; + + to_read = (unsigned int)(dev->devobj->SectorSize == 0 ? sizeof(superblock) : sector_align(sizeof(superblock), dev->devobj->SectorSize)); + + sb = ExAllocatePoolWithTag(NonPagedPool, to_read, ALLOC_TAG); + if (!sb) { + ERR("out of memory\n"); + return false; + } + + Status = sync_read_phys(dev->devobj, dev->fileobj, superblock_addrs[0], to_read, (PUCHAR)sb, false); + if (!NT_SUCCESS(Status)) { + ERR("sync_read_phys returned %08lx\n", Status); + ExFreePool(sb); + return false; + } + + if (sb->magic != BTRFS_MAGIC) { + ERR("magic not found\n"); + ExFreePool(sb); + return false; + } + + if (!check_superblock_checksum(sb)) { + ExFreePool(sb); + return false; + } + + if (sb->generation > expected_generation) { + ERR("generation was %I64x, expected %I64x\n", sb->generation, expected_generation); + ExFreePool(sb); + return false; + } + + ExFreePool(sb); + + return true; +} + +_Function_class_(IO_WORKITEM_ROUTINE) +static void __stdcall check_after_wakeup(PDEVICE_OBJECT DeviceObject, PVOID con) { + device_extension* Vcb = (device_extension*)con; + LIST_ENTRY* le; + + UNUSED(DeviceObject); + + ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true); + + le = Vcb->devices.Flink; + + // FIXME - do reads in parallel? + + while (le != &Vcb->devices) { + device* dev = CONTAINING_RECORD(le, device, list_entry); + + if (dev->devobj) { + if (!device_still_valid(dev, Vcb->superblock.generation - 1)) { + PDEVICE_OBJECT voldev = Vcb->Vpb->RealDevice; + KIRQL irql; + PVPB newvpb; + + WARN("forcing remount\n"); + + newvpb = ExAllocatePoolWithTag(NonPagedPool, sizeof(VPB), ALLOC_TAG); + if (!newvpb) { + ERR("out of memory\n"); + return; + } + + RtlZeroMemory(newvpb, sizeof(VPB)); + + newvpb->Type = IO_TYPE_VPB; + newvpb->Size = sizeof(VPB); + newvpb->RealDevice = voldev; + newvpb->Flags = VPB_DIRECT_WRITES_ALLOWED; + + Vcb->removing = true; + + IoAcquireVpbSpinLock(&irql); + voldev->Vpb = newvpb; + IoReleaseVpbSpinLock(irql); + + Vcb->vde = NULL; + + ExReleaseResourceLite(&Vcb->tree_lock); + + if (Vcb->open_files == 0) + uninit(Vcb); + else { // remove from VcbList + ExAcquireResourceExclusiveLite(&global_loading_lock, true); + RemoveEntryList(&Vcb->list_entry); + Vcb->list_entry.Flink = NULL; + ExReleaseResourceLite(&global_loading_lock); + } + + return; + } + } + + le = le->Flink; + } + + ExReleaseResourceLite(&Vcb->tree_lock); +} + _Dispatch_type_(IRP_MJ_POWER) _Function_class_(DRIVER_DISPATCH) static NTSTATUS __stdcall drv_power(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) { @@ -5350,7 +5586,7 @@ static NTSTATUS __stdcall drv_power(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP device_extension* Vcb = DeviceObject->DeviceExtension; bool top_level; - FsRtlEnterFileSystem(); + // no need for FsRtlEnterFileSystem, as this only ever gets called in a system thread top_level = is_top_level(Irp); @@ -5359,6 +5595,46 @@ static NTSTATUS __stdcall drv_power(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP if (Vcb && Vcb->type == VCB_TYPE_VOLUME) { volume_device_extension* vde = DeviceObject->DeviceExtension; + if (IrpSp->MinorFunction == IRP_MN_QUERY_POWER && IrpSp->Parameters.Power.Type == SystemPowerState && + IrpSp->Parameters.Power.State.SystemState != PowerSystemWorking && vde->mounted_device) { + device_extension* Vcb2 = vde->mounted_device->DeviceExtension; + + /* If power state is about to go to sleep or hibernate, do a flush. We do this on IRP_MJ_QUERY_POWER + * rather than IRP_MJ_SET_POWER because we know that the hard disks are still awake. */ + + if (Vcb2) { + ExAcquireResourceExclusiveLite(&Vcb2->tree_lock, true); + + if (Vcb2->need_write && !Vcb2->readonly) { + TRACE("doing protective flush on power state change\n"); + Status = do_write(Vcb2, NULL); + } else + Status = STATUS_SUCCESS; + + free_trees(Vcb2); + + if (!NT_SUCCESS(Status)) + ERR("do_write returned %08lx\n", Status); + + ExReleaseResourceLite(&Vcb2->tree_lock); + } + } else if (IrpSp->MinorFunction == IRP_MN_SET_POWER && IrpSp->Parameters.Power.Type == SystemPowerState && + IrpSp->Parameters.Power.State.SystemState == PowerSystemWorking && vde->mounted_device) { + device_extension* Vcb2 = vde->mounted_device->DeviceExtension; + + /* If waking up, make sure that the FS hasn't been changed while we've been out (e.g., by dual-boot Linux) */ + + if (Vcb2) { + PIO_WORKITEM work_item; + + work_item = IoAllocateWorkItem(DeviceObject); + if (!work_item) { + ERR("out of memory\n"); + } else + IoQueueWorkItem(work_item, check_after_wakeup, DelayedWorkQueue, Vcb2); + } + } + PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); Status = PoCallDriver(vde->attached_device, Irp); @@ -5393,8 +5669,6 @@ exit: if (top_level) IoSetTopLevelIrp(NULL); - FsRtlExitFileSystem(); - return Status; } @@ -5583,7 +5857,7 @@ static void init_serial(bool first_time) { Status = IoGetDeviceObjectPointer(&log_device, FILE_WRITE_DATA, &comfo, &comdo); if (!NT_SUCCESS(Status)) { - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); if (first_time) { OBJECT_ATTRIBUTES oa; @@ -5592,7 +5866,7 @@ static void init_serial(bool first_time) { Status = PsCreateSystemThread(&serial_thread_handle, 0, &oa, NULL, NULL, serial_thread, NULL); if (!NT_SUCCESS(Status)) { - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); return; } } @@ -5600,22 +5874,25 @@ static void init_serial(bool first_time) { } #endif -#ifndef __REACTOS__ +#if !defined(__REACTOS__) && (defined(_X86_) || defined(_AMD64_)) static void check_cpu() { unsigned int cpuInfo[4]; + bool have_sse42; + #ifndef _MSC_VER __get_cpuid(1, &cpuInfo[0], &cpuInfo[1], &cpuInfo[2], &cpuInfo[3]); have_sse42 = cpuInfo[2] & bit_SSE4_2; have_sse2 = cpuInfo[3] & bit_SSE2; #else - __cpuid(cpuInfo, 1); - have_sse42 = cpuInfo[2] & (1 << 20); - have_sse2 = cpuInfo[3] & (1 << 26); + __cpuid(cpuInfo, 1); + have_sse42 = cpuInfo[2] & (1 << 20); + have_sse2 = cpuInfo[3] & (1 << 26); #endif - if (have_sse42) + if (have_sse42) { TRACE("SSE4.2 is supported\n"); - else + calc_crc32c = calc_crc32c_hw; + } else TRACE("SSE4.2 not supported\n"); if (have_sse2) @@ -5645,7 +5922,7 @@ static void init_logging() { FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_ALERT, NULL, 0); if (!NT_SUCCESS(Status)) { - ERR("ZwCreateFile returned %08x\n", Status); + ERR("ZwCreateFile returned %08lx\n", Status); goto end; } @@ -5660,7 +5937,7 @@ static void init_logging() { Status = ZwQueryInformationFile(log_handle, &iosb, &fsi, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!NT_SUCCESS(Status)) { - ERR("ZwQueryInformationFile returned %08x\n", Status); + ERR("ZwQueryInformationFile returned %08lx\n", Status); goto end; } @@ -5669,14 +5946,14 @@ static void init_logging() { Status = ZwSetInformationFile(log_handle, &iosb, &fpi, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation); if (!NT_SUCCESS(Status)) { - ERR("ZwSetInformationFile returned %08x\n", Status); + ERR("ZwSetInformationFile returned %08lx\n", Status); goto end; } Status = ZwWriteFile(log_handle, NULL, NULL, NULL, &iosb, (void*)delim, sizeof(delim) - 1, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("ZwWriteFile returned %08x\n", Status); + ERR("ZwWriteFile returned %08lx\n", Status); goto end; } } @@ -5699,7 +5976,7 @@ static void init_logging() { ExFreePool(dateline); if (!NT_SUCCESS(Status)) { - ERR("ZwWriteFile returned %08x\n", Status); + ERR("ZwWriteFile returned %08lx\n", Status); goto end; } } @@ -5737,10 +6014,17 @@ NTSTATUS __stdcall AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Physica LIST_ENTRY* le; NTSTATUS Status; UNICODE_STRING volname; - ULONG i, j; + ULONG i; + WCHAR* s; pdo_device_extension* pdode = NULL; PDEVICE_OBJECT voldev; volume_device_extension* vde; + UNICODE_STRING arc_name_us; + WCHAR* anp; + + static const WCHAR arc_name_prefix[] = L"\\ArcName\\btrfs("; + + WCHAR arc_name[(sizeof(arc_name_prefix) / sizeof(WCHAR)) - 1 + 37]; TRACE("(%p, %p)\n", DriverObject, PhysicalDeviceObject); @@ -5781,27 +6065,44 @@ NTSTATUS __stdcall AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Physica } RtlCopyMemory(volname.Buffer, BTRFS_VOLUME_PREFIX, sizeof(BTRFS_VOLUME_PREFIX) - sizeof(WCHAR)); + RtlCopyMemory(arc_name, arc_name_prefix, sizeof(arc_name_prefix) - sizeof(WCHAR)); + + anp = &arc_name[(sizeof(arc_name_prefix) / sizeof(WCHAR)) - 1]; + s = &volname.Buffer[(sizeof(BTRFS_VOLUME_PREFIX) / sizeof(WCHAR)) - 1]; - j = (sizeof(BTRFS_VOLUME_PREFIX) / sizeof(WCHAR)) - 1; for (i = 0; i < 16; i++) { - volname.Buffer[j] = hex_digit(pdode->uuid.uuid[i] >> 4); j++; - volname.Buffer[j] = hex_digit(pdode->uuid.uuid[i] & 0xf); j++; + *s = *anp = hex_digit(pdode->uuid.uuid[i] >> 4); + s++; + anp++; + + *s = *anp = hex_digit(pdode->uuid.uuid[i] & 0xf); + s++; + anp++; if (i == 3 || i == 5 || i == 7 || i == 9) { - volname.Buffer[j] = '-'; - j++; + *s = *anp = '-'; + s++; + anp++; } } - volname.Buffer[j] = '}'; + *s = '}'; + *anp = ')'; Status = IoCreateDevice(drvobj, sizeof(volume_device_extension), &volname, FILE_DEVICE_DISK, WdmlibRtlIsNtDdiVersionAvailable(NTDDI_WIN8) ? FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL : 0, false, &voldev); if (!NT_SUCCESS(Status)) { - ERR("IoCreateDevice returned %08x\n", Status); + ERR("IoCreateDevice returned %08lx\n", Status); goto end2; } + arc_name_us.Buffer = arc_name; + arc_name_us.Length = arc_name_us.MaximumLength = sizeof(arc_name); + + Status = IoCreateSymbolicLink(&arc_name_us, &volname); + if (!NT_SUCCESS(Status)) + WARN("IoCreateSymbolicLink returned %08lx\n", Status); + voldev->SectorSize = PhysicalDeviceObject->SectorSize; voldev->Flags |= DO_DIRECT_IO; @@ -5818,7 +6119,7 @@ NTSTATUS __stdcall AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Physica Status = IoRegisterDeviceInterface(PhysicalDeviceObject, &GUID_DEVINTERFACE_VOLUME, NULL, &vde->bus_name); if (!NT_SUCCESS(Status)) - WARN("IoRegisterDeviceInterface returned %08x\n", Status); + WARN("IoRegisterDeviceInterface returned %08lx\n", Status); vde->attached_device = IoAttachDeviceToDeviceStack(voldev, PhysicalDeviceObject); @@ -5827,11 +6128,16 @@ NTSTATUS __stdcall AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Physica if (pdode->removable) voldev->Characteristics |= FILE_REMOVABLE_MEDIA; + if (RtlCompareMemory(&boot_uuid, &pdode->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { + voldev->Flags |= DO_SYSTEM_BOOT_PARTITION; + PhysicalDeviceObject->Flags |= DO_SYSTEM_BOOT_PARTITION; + } + voldev->Flags &= ~DO_DEVICE_INITIALIZING; Status = IoSetDeviceInterfaceState(&vde->bus_name, true); if (!NT_SUCCESS(Status)) - WARN("IoSetDeviceInterfaceState returned %08x\n", Status); + WARN("IoSetDeviceInterfaceState returned %08lx\n", Status); Status = STATUS_SUCCESS; @@ -5890,7 +6196,7 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S TRACE("DriverEntry\n"); -#ifndef __REACTOS__ +#if !defined(__REACTOS__) && (defined(_X86_) || defined(_AMD64_)) check_cpu(); #endif @@ -6003,7 +6309,7 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S Status = IoCreateDevice(DriverObject, sizeof(control_device_extension), &device_nameW, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN, false, &DeviceObject); if (!NT_SUCCESS(Status)) { - ERR("IoCreateDevice returned %08x\n", Status); + ERR("IoCreateDevice returned %08lx\n", Status); return Status; } @@ -6018,7 +6324,7 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S Status = IoCreateSymbolicLink(&dosdevice_nameW, &device_nameW); if (!NT_SUCCESS(Status)) { - ERR("IoCreateSymbolicLink returned %08x\n", Status); + ERR("IoCreateSymbolicLink returned %08lx\n", Status); return Status; } @@ -6033,7 +6339,7 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwCreateKey(®h, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos); if (!NT_SUCCESS(Status)) { - ERR("ZwCreateKey returned %08x\n", Status); + ERR("ZwCreateKey returned %08lx\n", Status); return Status; } @@ -6042,7 +6348,7 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S Status = IoCreateDevice(DriverObject, sizeof(bus_device_extension), NULL, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, false, &busobj); if (!NT_SUCCESS(Status)) { - ERR("IoCreateDevice returned %08x\n", Status); + ERR("IoCreateDevice returned %08lx\n", Status); return Status; } @@ -6055,13 +6361,13 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &bde->buspdo); if (!NT_SUCCESS(Status)) { - ERR("IoReportDetectedDevice returned %08x\n", Status); + ERR("IoReportDetectedDevice returned %08lx\n", Status); return Status; } Status = IoRegisterDeviceInterface(bde->buspdo, &BtrfsBusInterface, NULL, &bde->bus_name); if (!NT_SUCCESS(Status)) - WARN("IoRegisterDeviceInterface returned %08x\n", Status); + WARN("IoRegisterDeviceInterface returned %08lx\n", Status); bde->attached_device = IoAttachDeviceToDeviceStack(busobj, bde->buspdo); @@ -6069,7 +6375,7 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S Status = IoSetDeviceInterfaceState(&bde->bus_name, true); if (!NT_SUCCESS(Status)) - WARN("IoSetDeviceInterfaceState returned %08x\n", Status); + WARN("IoSetDeviceInterfaceState returned %08lx\n", Status); IoInvalidateDeviceRelations(bde->buspdo, BusRelations); @@ -6077,24 +6383,24 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S Status = PsCreateSystemThread(°raded_wait_handle, 0, &system_thread_attributes, NULL, NULL, degraded_wait_thread, NULL); if (!NT_SUCCESS(Status)) - WARN("PsCreateSystemThread returned %08x\n", Status); + WARN("PsCreateSystemThread returned %08lx\n", Status); ExInitializeResourceLite(&boot_lock); Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&GUID_DEVINTERFACE_VOLUME, DriverObject, volume_notification, DriverObject, ¬ification_entry2); if (!NT_SUCCESS(Status)) - ERR("IoRegisterPlugPlayNotification returned %08x\n", Status); + ERR("IoRegisterPlugPlayNotification returned %08lx\n", Status); Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&GUID_DEVINTERFACE_HIDDEN_VOLUME, DriverObject, volume_notification, DriverObject, ¬ification_entry3); if (!NT_SUCCESS(Status)) - ERR("IoRegisterPlugPlayNotification returned %08x\n", Status); + ERR("IoRegisterPlugPlayNotification returned %08lx\n", Status); Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&GUID_DEVINTERFACE_DISK, DriverObject, pnp_notification, DriverObject, ¬ification_entry); if (!NT_SUCCESS(Status)) - ERR("IoRegisterPlugPlayNotification returned %08x\n", Status); + ERR("IoRegisterPlugPlayNotification returned %08lx\n", Status); finished_probing = true; @@ -6102,7 +6408,7 @@ NTSTATUS __stdcall DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_S Status = PsCreateSystemThread(&mountmgr_thread_handle, 0, &system_thread_attributes, NULL, NULL, mountmgr_thread, NULL); if (!NT_SUCCESS(Status)) - WARN("PsCreateSystemThread returned %08x\n", Status); + WARN("PsCreateSystemThread returned %08lx\n", Status); IoRegisterFileSystem(DeviceObject); diff --git a/drivers/filesystems/btrfs/btrfs.h b/drivers/filesystems/btrfs/btrfs.h index 780bb5d0bab..6ff680234df 100644 --- a/drivers/filesystems/btrfs/btrfs.h +++ b/drivers/filesystems/btrfs/btrfs.h @@ -80,6 +80,8 @@ static const uint64_t superblock_addrs[] = { 0x10000, 0x4000000, 0x4000000000, 0 #define BLOCK_FLAG_RAID10 0x040 #define BLOCK_FLAG_RAID5 0x080 #define BLOCK_FLAG_RAID6 0x100 +#define BLOCK_FLAG_RAID1C3 0x200 +#define BLOCK_FLAG_RAID1C4 0x400 #define FREE_SPACE_CACHE_ID 0xFFFFFFFFFFFFFFF5 #define EXTENT_CSUM_ID 0xFFFFFFFFFFFFFFF6 @@ -113,11 +115,18 @@ static const uint64_t superblock_addrs[] = { 0x10000, 0x4000000, 0x4000000000, 0 #define BTRFS_INCOMPAT_FLAGS_RAID56 0x0080 #define BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA 0x0100 #define BTRFS_INCOMPAT_FLAGS_NO_HOLES 0x0200 +#define BTRFS_INCOMPAT_FLAGS_METADATA_UUID 0x0400 +#define BTRFS_INCOMPAT_FLAGS_RAID1C34 0x0800 #define BTRFS_SUPERBLOCK_FLAGS_SEEDING 0x100000000 #define BTRFS_ORPHAN_INODE_OBJID 0xFFFFFFFFFFFFFFFB +#define CSUM_TYPE_CRC32C 0 +#define CSUM_TYPE_XXHASH 1 +#define CSUM_TYPE_SHA256 2 +#define CSUM_TYPE_BLAKE2 3 + #pragma pack(push, 1) typedef struct { @@ -236,7 +245,8 @@ typedef struct { char label[MAX_LABEL_SIZE]; uint64_t cache_generation; uint64_t uuid_tree_generation; - uint64_t reserved[30]; + BTRFS_UUID metadata_uuid; + uint64_t reserved[28]; uint8_t sys_chunk_array[SYS_CHUNK_ARRAY_SIZE]; superblock_backup backup[BTRFS_NUM_BACKUP_ROOTS]; uint8_t reserved2[565]; diff --git a/drivers/filesystems/btrfs/btrfs.rc b/drivers/filesystems/btrfs/btrfs.rc index a594c6014d1..759ad42a474 100644 --- a/drivers/filesystems/btrfs/btrfs.rc +++ b/drivers/filesystems/btrfs/btrfs.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,0,0 - PRODUCTVERSION 1,5,0,0 + FILEVERSION 1,7,2,0 + PRODUCTVERSION 1,7,2,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,12 +68,12 @@ BEGIN BLOCK "080904b0" BEGIN VALUE "FileDescription", "WinBtrfs" - VALUE "FileVersion", "1.5" + VALUE "FileVersion", "1.7.2" VALUE "InternalName", "btrfs" - VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-19" + VALUE "LegalCopyright", "Copyright (c) Mark Harmstone 2016-20" VALUE "OriginalFilename", "btrfs.sys" VALUE "ProductName", "WinBtrfs" - VALUE "ProductVersion", "1.5" + VALUE "ProductVersion", "1.7.2" END END BLOCK "VarFileInfo" diff --git a/drivers/filesystems/btrfs/btrfs_drv.h b/drivers/filesystems/btrfs/btrfs_drv.h index 24307d93810..344223ebb53 100644 --- a/drivers/filesystems/btrfs/btrfs_drv.h +++ b/drivers/filesystems/btrfs/btrfs_drv.h @@ -63,13 +63,13 @@ #include #include #include -#ifndef __REACTOS__ -// Not actually used -#include -#endif /* __REACTOS__ */ #include "btrfs.h" #include "btrfsioctl.h" +#if !defined(__REACTOS__) && (defined(_X86_) || defined(_AMD64_)) +#include +#endif + #ifdef __REACTOS__ C_ASSERT(sizeof(bool) == 1); #endif @@ -117,12 +117,16 @@ C_ASSERT(sizeof(bool) == 1); #define READ_AHEAD_GRANULARITY COMPRESSED_EXTENT_SIZE // really ought to be a multiple of COMPRESSED_EXTENT_SIZE -#define IO_REPARSE_TAG_LXSS_SYMLINK 0xa000001d // undocumented? +#ifndef IO_REPARSE_TAG_LX_SYMLINK -#define IO_REPARSE_TAG_LXSS_SOCKET 0x80000023 -#define IO_REPARSE_TAG_LXSS_FIFO 0x80000024 -#define IO_REPARSE_TAG_LXSS_CHARDEV 0x80000025 -#define IO_REPARSE_TAG_LXSS_BLOCKDEV 0x80000026 +#define IO_REPARSE_TAG_LX_SYMLINK 0xa000001d + +#define IO_REPARSE_TAG_AF_UNIX 0x80000023 +#define IO_REPARSE_TAG_LX_FIFO 0x80000024 +#define IO_REPARSE_TAG_LX_CHR 0x80000025 +#define IO_REPARSE_TAG_LX_BLK 0x80000026 + +#endif #define BTRFS_VOLUME_PREFIX L"\\Device\\Btrfs{" @@ -140,7 +144,7 @@ C_ASSERT(sizeof(bool) == 1); #ifdef __GNUC__ #define InterlockedIncrement64(a) __sync_add_and_fetch(a, 1) #endif -#endif +#endif // __REACTOS__ #ifndef FILE_SUPPORTS_BLOCK_REFCOUNTING #define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000 @@ -154,10 +158,22 @@ C_ASSERT(sizeof(bool) == 1); #define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 0x00020000 #endif +#ifndef __REACTOS__ +#ifndef _MSC_VER typedef struct _FILE_ID_128 { UCHAR Identifier[16]; } FILE_ID_128, *PFILE_ID_128; +#define FILE_CS_FLAG_CASE_SENSITIVE_DIR 1 +#endif +#else +typedef struct _FILE_ID_128 { + UCHAR Identifier[16]; +} FILE_ID_128, *PFILE_ID_128; + +#define FILE_CS_FLAG_CASE_SENSITIVE_DIR 1 +#endif // __REACTOS__ + typedef struct _DUPLICATE_EXTENTS_DATA { HANDLE FileHandle; LARGE_INTEGER SourceFileOffset; @@ -190,9 +206,6 @@ typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER { #define _Requires_lock_held_(a) #define _Requires_exclusive_lock_held_(a) #define _Releases_lock_(a) -#define _Out_writes_bytes_opt_(a) -#define _Pre_satisfies_(a) -#define _Post_satisfies_(a) #define _Releases_exclusive_lock_(a) #define _Dispatch_type_(a) #define _Create_lock_level_(a) @@ -202,12 +215,14 @@ typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER { #define _Acquires_exclusive_lock_(a) #define _Acquires_shared_lock_(a) #endif -#endif +#endif // __REACTOS__ _Create_lock_level_(tree_lock) _Create_lock_level_(fcb_lock) _Lock_level_order_(tree_lock, fcb_lock) +#define MAX_HASH_SIZE 32 + struct _device_extension; typedef struct _fcb_nonpaged { @@ -226,7 +241,7 @@ typedef struct { bool unique; bool ignore; bool inserted; - uint32_t* csum; + void* csum; LIST_ENTRY list_entry; @@ -461,6 +476,7 @@ typedef struct _root { LONG send_ops; uint64_t fcbs_version; bool checked_for_orphans; + bool dropped; LIST_ENTRY fcbs; LIST_ENTRY* fcbs_ptrs[256]; LIST_ENTRY list_entry; @@ -617,27 +633,42 @@ typedef struct { LIST_ENTRY list_entry; } sys_chunk; +enum calc_thread_type { + calc_thread_crc32c, + calc_thread_xxhash, + calc_thread_sha256, + calc_thread_blake2, + calc_thread_decomp_zlib, + calc_thread_decomp_lzo, + calc_thread_decomp_zstd, + calc_thread_comp_zlib, + calc_thread_comp_lzo, + calc_thread_comp_zstd, +}; + typedef struct { - uint8_t* data; - uint32_t* csum; - uint32_t sectors; - LONG pos, done; - KEVENT event; - LONG refcount; LIST_ENTRY list_entry; + void* in; + void* out; + unsigned int inlen, outlen, off, space_left; + LONG left, not_started; + KEVENT event; + enum calc_thread_type type; + NTSTATUS Status; } calc_job; typedef struct { PDEVICE_OBJECT DeviceObject; HANDLE handle; KEVENT finished; + unsigned int number; bool quit; } drv_calc_thread; typedef struct { ULONG num_threads; LIST_ENTRY job_list; - ERESOURCE lock; + KSPIN_LOCK spinlock; drv_calc_thread* threads; KEVENT event; } drv_calc_threads; @@ -744,6 +775,7 @@ typedef struct _device_extension { #endif uint64_t devices_loaded; superblock superblock; + unsigned int csum_size; bool readonly; bool removing; bool locked; @@ -839,6 +871,7 @@ typedef struct { void* notification_entry; ULONG disk_num; ULONG part_num; + bool boot_volume; LIST_ENTRY list_entry; } volume_child; @@ -1134,6 +1167,7 @@ _Ret_maybenull_ root* find_default_subvol(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _In_opt_ PIRP Irp); void do_shutdown(PIRP Irp); +bool check_superblock_checksum(superblock* sb); #ifdef _MSC_VER #define funcname __FUNCTION__ @@ -1159,6 +1193,10 @@ extern uint32_t mount_readonly; extern uint32_t mount_no_root_dir; extern uint32_t no_pnp; +#ifndef __GNUC__ +#define __attribute__(x) +#endif + #ifdef _DEBUG extern bool log_started; @@ -1166,25 +1204,25 @@ extern uint32_t debug_log_level; #ifdef DEBUG_LONG_MESSAGES -#define MSG(fn, file, line, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, file, line, s, ##__VA_ARGS__) : 0 +#define MSG(fn, file, line, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, file, line, s, ##__VA_ARGS__) : (void)0 #define TRACE(s, ...) MSG(funcname, __FILE__, __LINE__, s, 3, ##__VA_ARGS__) #define WARN(s, ...) MSG(funcname, __FILE__, __LINE__, s, 2, ##__VA_ARGS__) #define FIXME(s, ...) MSG(funcname, __FILE__, __LINE__, s, 1, ##__VA_ARGS__) #define ERR(s, ...) MSG(funcname, __FILE__, __LINE__, s, 1, ##__VA_ARGS__) -void _debug_message(_In_ const char* func, _In_ const char* file, _In_ unsigned int line, _In_ char* s, ...); +void _debug_message(_In_ const char* func, _In_ const char* file, _In_ unsigned int line, _In_ char* s, ...) __attribute__((format(printf, 4, 5))); #else -#define MSG(fn, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, s, ##__VA_ARGS__) : 0 +#define MSG(fn, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, s, ##__VA_ARGS__) : (void)0 #define TRACE(s, ...) MSG(funcname, s, 3, ##__VA_ARGS__) #define WARN(s, ...) MSG(funcname, s, 2, ##__VA_ARGS__) #define FIXME(s, ...) MSG(funcname, s, 1, ##__VA_ARGS__) #define ERR(s, ...) MSG(funcname, s, 1, ##__VA_ARGS__) -void _debug_message(_In_ const char* func, _In_ char* s, ...); +void _debug_message(_In_ const char* func, _In_ char* s, ...) __attribute__((format(printf, 2, 3))); #endif @@ -1205,8 +1243,13 @@ void _free_fcb(_Inout_ fcb* fcb, _In_ const char* func); // in fastio.c void init_fast_io_dispatch(FAST_IO_DISPATCH** fiod); -// in crc32c.c -uint32_t calc_crc32c(_In_ uint32_t seed, _In_reads_bytes_(msglen) uint8_t* msg, _In_ ULONG msglen); +// in sha256.c +void calc_sha256(uint8_t* hash, const void* input, size_t len); +#define SHA256_HASH_SIZE 32 + +// in blake2b-ref.c +void blake2b(void *out, size_t outlen, const void* in, size_t inlen); +#define BLAKE2_HASH_SIZE 32 typedef struct { LIST_ENTRY* list; @@ -1315,14 +1358,11 @@ bool insert_extent_chunk(_In_ device_extension* Vcb, _In_ fcb* fcb, _In_ chunk* _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback, _In_ uint8_t compression, _In_ uint64_t decoded_size, _In_ bool file_write, _In_ uint64_t irp_offset); NTSTATUS do_write_file(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, PIRP Irp, bool file_write, uint32_t irp_offset, LIST_ENTRY* rollback); -NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, PIRP Irp, LIST_ENTRY* rollback); bool find_data_address_in_chunk(device_extension* Vcb, chunk* c, uint64_t length, uint64_t* address); void get_raid56_lock_range(chunk* c, uint64_t address, uint64_t length, uint64_t* lockaddr, uint64_t* locklen); -NTSTATUS calc_csum(_In_ device_extension* Vcb, _In_reads_bytes_(sectors*Vcb->superblock.sector_size) uint8_t* data, - _In_ uint32_t sectors, _Out_writes_bytes_(sectors*sizeof(uint32_t)) uint32_t* csum); void add_insert_extent_rollback(LIST_ENTRY* rollback, fcb* fcb, extent* ext); NTSTATUS add_extent_to_fcb(_In_ fcb* fcb, _In_ uint64_t offset, _In_reads_bytes_(edsize) EXTENT_DATA* ed, _In_ uint16_t edsize, - _In_ bool unique, _In_opt_ _When_(return >= 0, __drv_aliasesMem) uint32_t* csum, _In_ LIST_ENTRY* rollback); + _In_ bool unique, _In_opt_ _When_(return >= 0, __drv_aliasesMem) void* csum, _In_ LIST_ENTRY* rollback); void add_extent(_In_ fcb* fcb, _In_ LIST_ENTRY* prevextle, _In_ __drv_aliasesMem extent* newext); // in dirctrl.c @@ -1393,7 +1433,7 @@ NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusiv _In_ bool case_sensitive, _In_opt_ PIRP Irp); NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension* Vcb, root* subvol, uint64_t inode, uint8_t type, PANSI_STRING utf8, bool always_add_hl, fcb* parent, fcb** pfcb, POOL_TYPE pooltype, PIRP Irp); -NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, uint32_t* csum, uint64_t start, uint64_t length, PIRP Irp); +NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, void* csum, uint64_t start, uint64_t length, PIRP Irp); NTSTATUS load_dir_children(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, fcb* fcb, bool ignore_size, PIRP Irp); NTSTATUS add_dir_child(fcb* fcb, uint64_t inode, bool subvol, PANSI_STRING utf8, PUNICODE_STRING name, uint8_t type, dir_child** pdc); NTSTATUS open_fileref_child(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension* Vcb, @@ -1425,13 +1465,14 @@ NTSTATUS write_data_phys(_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj, _In_reads_bytes_(length) void* data, _In_ uint32_t length); bool is_tree_unique(device_extension* Vcb, tree* t, PIRP Irp); NTSTATUS do_tree_writes(device_extension* Vcb, LIST_ENTRY* tree_writes, bool no_free); -void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, uint32_t* csum, PIRP Irp); +void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, void* csum, PIRP Irp); bool find_metadata_address_in_chunk(device_extension* Vcb, chunk* c, uint64_t* address); void add_trim_entry_avoid_sb(device_extension* Vcb, device* dev, uint64_t address, uint64_t size); NTSTATUS insert_tree_item_batch(LIST_ENTRY* batchlist, device_extension* Vcb, root* r, uint64_t objid, uint8_t objtype, uint64_t offset, _In_opt_ _When_(return >= 0, __drv_aliasesMem) void* data, uint16_t datalen, enum batch_operation operation); NTSTATUS flush_partial_stripe(device_extension* Vcb, chunk* c, partial_stripe* ps); NTSTATUS update_dev_item(device_extension* Vcb, device* device, PIRP Irp); +void calc_tree_checksum(device_extension* Vcb, tree_header* th); // in read.c @@ -1439,14 +1480,18 @@ _Dispatch_type_(IRP_MJ_READ) _Function_class_(DRIVER_DISPATCH) NTSTATUS __stdcall drv_read(PDEVICE_OBJECT DeviceObject, PIRP Irp); -NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t length, _In_reads_bytes_opt_(length*sizeof(uint32_t)/Vcb->superblock.sector_size) uint32_t* csum, +NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t length, _In_reads_bytes_opt_(length*sizeof(uint32_t)/Vcb->superblock.sector_size) void* csum, _In_ bool is_tree, _Out_writes_bytes_(length) uint8_t* buf, _In_opt_ chunk* c, _Out_opt_ chunk** pc, _In_opt_ PIRP Irp, _In_ uint64_t generation, _In_ bool file_read, _In_ ULONG priority); NTSTATUS read_file(fcb* fcb, uint8_t* data, uint64_t start, uint64_t length, ULONG* pbr, PIRP Irp); NTSTATUS read_stream(fcb* fcb, uint8_t* data, uint64_t start, ULONG length, ULONG* pbr); NTSTATUS do_read(PIRP Irp, bool wait, ULONG* bytes_read); -NTSTATUS check_csum(device_extension* Vcb, uint8_t* data, uint32_t sectors, uint32_t* csum); +NTSTATUS check_csum(device_extension* Vcb, uint8_t* data, uint32_t sectors, void* csum); void raid6_recover2(uint8_t* sectors, uint16_t num_stripes, ULONG sector_size, uint16_t missing1, uint16_t missing2, uint8_t* out); +void get_tree_checksum(device_extension* Vcb, tree_header* th, void* csum); +bool check_tree_checksum(device_extension* Vcb, tree_header* th); +void get_sector_csum(device_extension* Vcb, void* buf, void* csum); +bool check_sector_csum(device_extension* Vcb, void* buf, void* csum); // in pnp.c @@ -1505,7 +1550,10 @@ void watch_registry(HANDLE regh); NTSTATUS zlib_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen); NTSTATUS lzo_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, uint32_t inpageoff); NTSTATUS zstd_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen); -NTSTATUS write_compressed_bit(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, bool* compressed, PIRP Irp, LIST_ENTRY* rollback); +NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, PIRP Irp, LIST_ENTRY* rollback); +NTSTATUS zlib_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, unsigned int level, unsigned int* space_left); +NTSTATUS lzo_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, unsigned int* space_left); +NTSTATUS zstd_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, uint32_t level, unsigned int* space_left); // in galois.c void galois_double(uint8_t* data, uint32_t len); @@ -1525,8 +1573,12 @@ NTSTATUS __stdcall drv_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Ir _Function_class_(KSTART_ROUTINE) void __stdcall calc_thread(void* context); -NTSTATUS add_calc_job(device_extension* Vcb, uint8_t* data, uint32_t sectors, uint32_t* csum, calc_job** pcj); -void free_calc_job(calc_job* cj); +void do_calc_job(device_extension* Vcb, uint8_t* data, uint32_t sectors, void* csum); +NTSTATUS add_calc_job_decomp(device_extension* Vcb, uint8_t compression, void* in, unsigned int inlen, + void* out, unsigned int outlen, unsigned int off, calc_job** pcj); +NTSTATUS add_calc_job_comp(device_extension* Vcb, uint8_t compression, void* in, unsigned int inlen, + void* out, unsigned int outlen, calc_job** pcj); +void calc_thread_main(device_extension* Vcb, calc_job* cj); // in balance.c NTSTATUS start_balance(device_extension* Vcb, void* data, ULONG length, KPROCESSOR_MODE processor_mode); @@ -1584,6 +1636,8 @@ NTSTATUS __stdcall compat_FsRtlValidateReparsePointBuffer(IN ULONG BufferLength, // in boot.c void __stdcall check_system_root(PDRIVER_OBJECT DriverObject, PVOID Context, ULONG Count); +void boot_add_device(DEVICE_OBJECT* pdo); +extern BTRFS_UUID boot_uuid; // based on function in sys/sysmacros.h #define makedev(major, minor) (((minor) & 0xFF) | (((major) & 0xFFF) << 8) | (((uint64_t)((minor) & ~0xFF)) << 12) | (((uint64_t)((major) & ~0xFFF)) << 32)) @@ -1624,7 +1678,7 @@ typedef struct { } FSRTL_ADVANCED_FCB_HEADER_NEW; #define FSRTL_FCB_HEADER_V2 2 -#endif +#endif // __REACTOS__ static __inline POPLOCK fcb_oplock(fcb* fcb) { if (fcb->Header.Version >= FSRTL_FCB_HEADER_V2) @@ -1675,10 +1729,9 @@ static __inline bool write_fcb_compressed(fcb* fcb) { 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; -#endif -#ifndef __REACTOS__ if (have_sse2 && ((uintptr_t)buf1 & 0xf) == 0 && ((uintptr_t)buf2 & 0xf) == 0) { while (len >= 16) { x1 = _mm_load_si128((__m128i*)buf1); @@ -1686,12 +1739,28 @@ static __inline void do_xor(uint8_t* buf1, uint8_t* buf2, uint32_t len) { 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; @@ -1895,7 +1964,7 @@ typedef struct _PEB { PVOID Reserved7[1]; ULONG SessionId; } PEB,*PPEB; -#endif +#endif /* __REACTOS__ */ #ifdef _MSC_VER __kernel_entry diff --git a/drivers/filesystems/btrfs/calcthread.c b/drivers/filesystems/btrfs/calcthread.c index 3784428f40f..faeb9b3300b 100644 --- a/drivers/filesystems/btrfs/calcthread.c +++ b/drivers/filesystems/btrfs/calcthread.c @@ -16,11 +16,174 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "xxhash.h" +#include "crc32c.h" -#define SECTOR_BLOCK 16 +void calc_thread_main(device_extension* Vcb, calc_job* cj) { + while (true) { + KIRQL irql; + calc_job* cj2; + uint8_t* src; + void* dest; + bool last_one = false; -NTSTATUS add_calc_job(device_extension* Vcb, uint8_t* data, uint32_t sectors, uint32_t* csum, calc_job** pcj) { + KeAcquireSpinLock(&Vcb->calcthreads.spinlock, &irql); + + if (cj && cj->not_started == 0) { + KeReleaseSpinLock(&Vcb->calcthreads.spinlock, irql); + break; + } + + if (cj) + cj2 = cj; + else { + if (IsListEmpty(&Vcb->calcthreads.job_list)) { + KeReleaseSpinLock(&Vcb->calcthreads.spinlock, irql); + break; + } + + cj2 = CONTAINING_RECORD(Vcb->calcthreads.job_list.Flink, calc_job, list_entry); + } + + src = cj2->in; + dest = cj2->out; + + switch (cj2->type) { + case calc_thread_crc32c: + case calc_thread_xxhash: + case calc_thread_sha256: + case calc_thread_blake2: + cj2->in = (uint8_t*)cj2->in + Vcb->superblock.sector_size; + cj2->out = (uint8_t*)cj2->out + Vcb->csum_size; + break; + + default: + break; + } + + cj2->not_started--; + + if (cj2->not_started == 0) { + RemoveEntryList(&cj2->list_entry); + last_one = true; + } + + KeReleaseSpinLock(&Vcb->calcthreads.spinlock, irql); + + switch (cj2->type) { + case calc_thread_crc32c: + *(uint32_t*)dest = ~calc_crc32c(0xffffffff, src, Vcb->superblock.sector_size); + break; + + case calc_thread_xxhash: + *(uint64_t*)dest = XXH64(src, Vcb->superblock.sector_size, 0); + break; + + case calc_thread_sha256: + calc_sha256(dest, src, Vcb->superblock.sector_size); + break; + + case calc_thread_blake2: + blake2b(dest, BLAKE2_HASH_SIZE, src, Vcb->superblock.sector_size); + break; + + case calc_thread_decomp_zlib: + cj2->Status = zlib_decompress(src, cj2->inlen, dest, cj2->outlen); + + if (!NT_SUCCESS(cj2->Status)) + ERR("zlib_decompress returned %08lx\n", cj2->Status); + break; + + case calc_thread_decomp_lzo: + cj2->Status = lzo_decompress(src, cj2->inlen, dest, cj2->outlen, cj2->off); + + if (!NT_SUCCESS(cj2->Status)) + ERR("lzo_decompress returned %08lx\n", cj2->Status); + break; + + case calc_thread_decomp_zstd: + cj2->Status = zstd_decompress(src, cj2->inlen, dest, cj2->outlen); + + if (!NT_SUCCESS(cj2->Status)) + ERR("zstd_decompress returned %08lx\n", cj2->Status); + break; + + case calc_thread_comp_zlib: + cj2->Status = zlib_compress(src, cj2->inlen, dest, cj2->outlen, Vcb->options.zlib_level, &cj2->space_left); + + if (!NT_SUCCESS(cj2->Status)) + ERR("zlib_compress returned %08lx\n", cj2->Status); + break; + + case calc_thread_comp_lzo: + cj2->Status = lzo_compress(src, cj2->inlen, dest, cj2->outlen, &cj2->space_left); + + if (!NT_SUCCESS(cj2->Status)) + ERR("lzo_compress returned %08lx\n", cj2->Status); + break; + + case calc_thread_comp_zstd: + cj2->Status = zstd_compress(src, cj2->inlen, dest, cj2->outlen, Vcb->options.zstd_level, &cj2->space_left); + + if (!NT_SUCCESS(cj2->Status)) + ERR("zstd_compress returned %08lx\n", cj2->Status); + break; + } + + if (InterlockedDecrement(&cj2->left) == 0) + KeSetEvent(&cj2->event, 0, false); + + if (last_one) + break; + } +} + +void do_calc_job(device_extension* Vcb, uint8_t* data, uint32_t sectors, void* csum) { + KIRQL irql; + calc_job cj; + + cj.in = data; + cj.out = csum; + cj.left = cj.not_started = sectors; + + switch (Vcb->superblock.csum_type) { + case CSUM_TYPE_CRC32C: + cj.type = calc_thread_crc32c; + break; + + case CSUM_TYPE_XXHASH: + cj.type = calc_thread_xxhash; + break; + + case CSUM_TYPE_SHA256: + cj.type = calc_thread_sha256; + break; + + case CSUM_TYPE_BLAKE2: + cj.type = calc_thread_blake2; + break; + } + + KeInitializeEvent(&cj.event, NotificationEvent, false); + + KeAcquireSpinLock(&Vcb->calcthreads.spinlock, &irql); + + InsertTailList(&Vcb->calcthreads.job_list, &cj.list_entry); + + KeSetEvent(&Vcb->calcthreads.event, 0, false); + KeClearEvent(&Vcb->calcthreads.event); + + KeReleaseSpinLock(&Vcb->calcthreads.spinlock, irql); + + calc_thread_main(Vcb, &cj); + + KeWaitForSingleObject(&cj.event, Executive, KernelMode, false, NULL); +} + +NTSTATUS add_calc_job_decomp(device_extension* Vcb, uint8_t compression, void* in, unsigned int inlen, + void* out, unsigned int outlen, unsigned int off, calc_job** pcj) { calc_job* cj; + KIRQL irql; cj = ExAllocatePoolWithTag(NonPagedPool, sizeof(calc_job), ALLOC_TAG); if (!cj) { @@ -28,67 +191,100 @@ NTSTATUS add_calc_job(device_extension* Vcb, uint8_t* data, uint32_t sectors, ui return STATUS_INSUFFICIENT_RESOURCES; } - cj->data = data; - cj->sectors = sectors; - cj->csum = csum; - cj->pos = 0; - cj->done = 0; - cj->refcount = 1; + cj->in = in; + cj->inlen = inlen; + cj->out = out; + cj->outlen = outlen; + cj->off = off; + cj->left = cj->not_started = 1; + cj->Status = STATUS_SUCCESS; + + switch (compression) { + case BTRFS_COMPRESSION_ZLIB: + cj->type = calc_thread_decomp_zlib; + break; + + case BTRFS_COMPRESSION_LZO: + cj->type = calc_thread_decomp_lzo; + break; + + case BTRFS_COMPRESSION_ZSTD: + cj->type = calc_thread_decomp_zstd; + break; + + default: + ERR("unexpected compression type %x\n", compression); + ExFreePool(cj); + return STATUS_NOT_SUPPORTED; + } + KeInitializeEvent(&cj->event, NotificationEvent, false); - ExAcquireResourceExclusiveLite(&Vcb->calcthreads.lock, true); + KeAcquireSpinLock(&Vcb->calcthreads.spinlock, &irql); InsertTailList(&Vcb->calcthreads.job_list, &cj->list_entry); KeSetEvent(&Vcb->calcthreads.event, 0, false); KeClearEvent(&Vcb->calcthreads.event); - ExReleaseResourceLite(&Vcb->calcthreads.lock); + KeReleaseSpinLock(&Vcb->calcthreads.spinlock, irql); *pcj = cj; return STATUS_SUCCESS; } -void free_calc_job(calc_job* cj) { - LONG rc = InterlockedDecrement(&cj->refcount); +NTSTATUS add_calc_job_comp(device_extension* Vcb, uint8_t compression, void* in, unsigned int inlen, + void* out, unsigned int outlen, calc_job** pcj) { + calc_job* cj; + KIRQL irql; - if (rc == 0) - ExFreePool(cj); -} - -static bool do_calc(device_extension* Vcb, calc_job* cj) { - LONG pos, done; - uint32_t* csum; - uint8_t* data; - ULONG blocksize, i; - - pos = InterlockedIncrement(&cj->pos) - 1; - - if ((uint32_t)pos * SECTOR_BLOCK >= cj->sectors) - return false; - - csum = &cj->csum[pos * SECTOR_BLOCK]; - data = cj->data + (pos * SECTOR_BLOCK * Vcb->superblock.sector_size); - - blocksize = min(SECTOR_BLOCK, cj->sectors - (pos * SECTOR_BLOCK)); - for (i = 0; i < blocksize; i++) { - *csum = ~calc_crc32c(0xffffffff, data, Vcb->superblock.sector_size); - csum++; - data += Vcb->superblock.sector_size; + cj = ExAllocatePoolWithTag(NonPagedPool, sizeof(calc_job), ALLOC_TAG); + if (!cj) { + ERR("out of memory\n"); + return STATUS_INSUFFICIENT_RESOURCES; } - done = InterlockedIncrement(&cj->done); + cj->in = in; + cj->inlen = inlen; + cj->out = out; + cj->outlen = outlen; + cj->left = cj->not_started = 1; + cj->Status = STATUS_SUCCESS; - if ((uint32_t)done * SECTOR_BLOCK >= cj->sectors) { - ExAcquireResourceExclusiveLite(&Vcb->calcthreads.lock, true); - RemoveEntryList(&cj->list_entry); - ExReleaseResourceLite(&Vcb->calcthreads.lock); + switch (compression) { + case BTRFS_COMPRESSION_ZLIB: + cj->type = calc_thread_comp_zlib; + break; - KeSetEvent(&cj->event, 0, false); + case BTRFS_COMPRESSION_LZO: + cj->type = calc_thread_comp_lzo; + break; + + case BTRFS_COMPRESSION_ZSTD: + cj->type = calc_thread_comp_zstd; + break; + + default: + ERR("unexpected compression type %x\n", compression); + ExFreePool(cj); + return STATUS_NOT_SUPPORTED; } - return true; + KeInitializeEvent(&cj->event, NotificationEvent, false); + + KeAcquireSpinLock(&Vcb->calcthreads.spinlock, &irql); + + InsertTailList(&Vcb->calcthreads.job_list, &cj->list_entry); + + KeSetEvent(&Vcb->calcthreads.event, 0, false); + KeClearEvent(&Vcb->calcthreads.event); + + KeReleaseSpinLock(&Vcb->calcthreads.spinlock, irql); + + *pcj = cj; + + return STATUS_SUCCESS; } _Function_class_(KSTART_ROUTINE) @@ -98,32 +294,12 @@ void __stdcall calc_thread(void* context) { ObReferenceObject(thread->DeviceObject); + KeSetSystemAffinityThread((KAFFINITY)(1 << thread->number)); + while (true) { KeWaitForSingleObject(&Vcb->calcthreads.event, Executive, KernelMode, false, NULL); - while (true) { - calc_job* cj; - bool b; - - ExAcquireResourceExclusiveLite(&Vcb->calcthreads.lock, true); - - if (IsListEmpty(&Vcb->calcthreads.job_list)) { - ExReleaseResourceLite(&Vcb->calcthreads.lock); - break; - } - - cj = CONTAINING_RECORD(Vcb->calcthreads.job_list.Flink, calc_job, list_entry); - cj->refcount++; - - ExReleaseResourceLite(&Vcb->calcthreads.lock); - - b = do_calc(Vcb, cj); - - free_calc_job(cj); - - if (!b) - break; - } + calc_thread_main(Vcb, NULL); if (thread->quit) break; diff --git a/drivers/filesystems/btrfs/compress.c b/drivers/filesystems/btrfs/compress.c index 56ac3c5621a..eecc00576cd 100644 --- a/drivers/filesystems/btrfs/compress.c +++ b/drivers/filesystems/btrfs/compress.c @@ -37,7 +37,7 @@ #include "zlib/inflate.h" #else #include -#endif +#endif // __REACTOS__ #define ZSTD_STATIC_LINKING_ONLY @@ -287,7 +287,7 @@ NTSTATUS lzo_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_ partlen = *(uint32_t*)&inbuf[inoff]; if (partlen + inoff > inlen) { - ERR("overflow: %x + %x > %I64x\n", partlen, inoff, inlen); + ERR("overflow: %x + %x > %x\n", partlen, inoff, inlen); return STATUS_INTERNAL_ERROR; } @@ -302,7 +302,7 @@ NTSTATUS lzo_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_ Status = do_lzo_decompress(&stream); if (!NT_SUCCESS(Status)) { - ERR("do_lzo_decompress returned %08x\n", Status); + ERR("do_lzo_decompress returned %08lx\n", Status); return Status; } @@ -333,6 +333,47 @@ static void zlib_free(void* opaque, void* ptr) { ExFreePool(ptr); } +NTSTATUS zlib_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, unsigned int level, unsigned int* space_left) { + z_stream c_stream; + int ret; + + c_stream.zalloc = zlib_alloc; + c_stream.zfree = zlib_free; + c_stream.opaque = (voidpf)0; + + ret = deflateInit(&c_stream, level); + + if (ret != Z_OK) { + ERR("deflateInit returned %i\n", ret); + return STATUS_INTERNAL_ERROR; + } + + c_stream.next_in = inbuf; + c_stream.avail_in = inlen; + + c_stream.next_out = outbuf; + c_stream.avail_out = outlen; + + do { + ret = deflate(&c_stream, Z_FINISH); + + if (ret != Z_OK && ret != Z_STREAM_END) { + ERR("deflate returned %i\n", ret); + deflateEnd(&c_stream); + return STATUS_INTERNAL_ERROR; + } + + if (c_stream.avail_in == 0 || c_stream.avail_out == 0) + break; + } while (ret != Z_STREAM_END); + + deflateEnd(&c_stream); + + *space_left = c_stream.avail_in > 0 ? 0 : c_stream.avail_out; + + return STATUS_SUCCESS; +} + NTSTATUS zlib_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen) { z_stream c_stream; int ret; @@ -344,7 +385,7 @@ NTSTATUS zlib_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32 ret = inflateInit(&c_stream); if (ret != Z_OK) { - ERR("inflateInit returned %08x\n", ret); + ERR("inflateInit returned %i\n", ret); return STATUS_INTERNAL_ERROR; } @@ -358,7 +399,7 @@ NTSTATUS zlib_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32 ret = inflate(&c_stream, Z_NO_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) { - ERR("inflate returned %08x\n", ret); + ERR("inflate returned %i\n", ret); inflateEnd(&c_stream); return STATUS_INTERNAL_ERROR; } @@ -370,7 +411,7 @@ NTSTATUS zlib_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32 ret = inflateEnd(&c_stream); if (ret != Z_OK) { - ERR("inflateEnd returned %08x\n", ret); + ERR("inflateEnd returned %i\n", ret); return STATUS_INTERNAL_ERROR; } @@ -379,153 +420,6 @@ NTSTATUS zlib_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32 return STATUS_SUCCESS; } -static NTSTATUS zlib_write_compressed_bit(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, bool* compressed, PIRP Irp, LIST_ENTRY* rollback) { - NTSTATUS Status; - uint8_t compression; - uint32_t comp_length; - uint8_t* comp_data; - uint32_t out_left; - LIST_ENTRY* le; - chunk* c; - z_stream c_stream; - int ret; - - comp_data = ExAllocatePoolWithTag(PagedPool, (uint32_t)(end_data - start_data), ALLOC_TAG); - if (!comp_data) { - ERR("out of memory\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Status = excise_extents(fcb->Vcb, fcb, start_data, end_data, Irp, rollback); - if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); - ExFreePool(comp_data); - return Status; - } - - c_stream.zalloc = zlib_alloc; - c_stream.zfree = zlib_free; - c_stream.opaque = (voidpf)0; - - ret = deflateInit(&c_stream, fcb->Vcb->options.zlib_level); - - if (ret != Z_OK) { - ERR("deflateInit returned %08x\n", ret); - ExFreePool(comp_data); - return STATUS_INTERNAL_ERROR; - } - - c_stream.avail_in = (uint32_t)(end_data - start_data); - c_stream.next_in = data; - c_stream.avail_out = (uint32_t)(end_data - start_data); - c_stream.next_out = comp_data; - - do { - ret = deflate(&c_stream, Z_FINISH); - - if (ret == Z_STREAM_ERROR) { - ERR("deflate returned %x\n", ret); - ExFreePool(comp_data); - return STATUS_INTERNAL_ERROR; - } - } while (c_stream.avail_in > 0 && c_stream.avail_out > 0); - - out_left = c_stream.avail_out; - - ret = deflateEnd(&c_stream); - - if (ret != Z_OK) { - ERR("deflateEnd returned %08x\n", ret); - ExFreePool(comp_data); - return STATUS_INTERNAL_ERROR; - } - - if (out_left < fcb->Vcb->superblock.sector_size) { // compressed extent would be larger than or same size as uncompressed extent - ExFreePool(comp_data); - - comp_length = (uint32_t)(end_data - start_data); - comp_data = data; - compression = BTRFS_COMPRESSION_NONE; - - *compressed = false; - } else { - uint32_t cl; - - compression = BTRFS_COMPRESSION_ZLIB; - cl = (uint32_t)(end_data - start_data - out_left); - comp_length = (uint32_t)sector_align(cl, fcb->Vcb->superblock.sector_size); - - RtlZeroMemory(comp_data + cl, comp_length - cl); - - *compressed = true; - } - - ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true); - - le = fcb->Vcb->chunks.Flink; - while (le != &fcb->Vcb->chunks) { - c = CONTAINING_RECORD(le, chunk, list_entry); - - if (!c->readonly && !c->reloc) { - acquire_chunk_lock(c, fcb->Vcb); - - if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) { - if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) { - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_SUCCESS; - } - } - - release_chunk_lock(c, fcb->Vcb); - } - - le = le->Flink; - } - - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true); - - Status = alloc_chunk(fcb->Vcb, fcb->Vcb->data_flags, &c, false); - - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return Status; - } - - if (c) { - acquire_chunk_lock(c, fcb->Vcb); - - if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) { - if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) { - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_SUCCESS; - } - } - - release_chunk_lock(c, fcb->Vcb); - } - - WARN("couldn't find any data chunks with %I64x bytes free\n", comp_length); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_DISK_FULL; -} - static NTSTATUS lzo_do_compress(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t* out_len, void* wrkmem) { const uint8_t* ip; uint32_t dv; @@ -767,357 +661,6 @@ static __inline uint32_t lzo_max_outlen(uint32_t inlen) { return inlen + (inlen / 16) + 64 + 3; // formula comes from LZO.FAQ } -static NTSTATUS lzo_write_compressed_bit(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, bool* compressed, PIRP Irp, LIST_ENTRY* rollback) { - NTSTATUS Status; - uint8_t compression; - uint64_t comp_length; - ULONG comp_data_len, num_pages, i; - uint8_t* comp_data; - bool skip_compression = false; - lzo_stream stream; - uint32_t* out_size; - LIST_ENTRY* le; - chunk* c; - - num_pages = (ULONG)((sector_align(end_data - start_data, LZO_PAGE_SIZE)) / LZO_PAGE_SIZE); - - // Four-byte overall header - // Another four-byte header page - // Each page has a maximum size of lzo_max_outlen(LZO_PAGE_SIZE) - // Plus another four bytes for possible padding - comp_data_len = sizeof(uint32_t) + ((lzo_max_outlen(LZO_PAGE_SIZE) + (2 * sizeof(uint32_t))) * num_pages); - - comp_data = ExAllocatePoolWithTag(PagedPool, comp_data_len, ALLOC_TAG); - if (!comp_data) { - ERR("out of memory\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - stream.wrkmem = ExAllocatePoolWithTag(PagedPool, LZO1X_MEM_COMPRESS, ALLOC_TAG); - if (!stream.wrkmem) { - ERR("out of memory\n"); - ExFreePool(comp_data); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Status = excise_extents(fcb->Vcb, fcb, start_data, end_data, Irp, rollback); - if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); - ExFreePool(comp_data); - ExFreePool(stream.wrkmem); - return Status; - } - - out_size = (uint32_t*)comp_data; - *out_size = sizeof(uint32_t); - - stream.in = data; - stream.out = comp_data + (2 * sizeof(uint32_t)); - - for (i = 0; i < num_pages; i++) { - uint32_t* pagelen = (uint32_t*)(stream.out - sizeof(uint32_t)); - - stream.inlen = (uint32_t)min(LZO_PAGE_SIZE, end_data - start_data - (i * LZO_PAGE_SIZE)); - - Status = lzo1x_1_compress(&stream); - if (!NT_SUCCESS(Status)) { - ERR("lzo1x_1_compress returned %08x\n", Status); - skip_compression = true; - break; - } - - *pagelen = stream.outlen; - *out_size += stream.outlen + sizeof(uint32_t); - - stream.in += LZO_PAGE_SIZE; - stream.out += stream.outlen + sizeof(uint32_t); - - if (LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE) < sizeof(uint32_t)) { - RtlZeroMemory(stream.out, LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE)); - stream.out += LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE); - *out_size += LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE); - } - } - - ExFreePool(stream.wrkmem); - - if (skip_compression || *out_size >= end_data - start_data - fcb->Vcb->superblock.sector_size) { // compressed extent would be larger than or same size as uncompressed extent - ExFreePool(comp_data); - - comp_length = end_data - start_data; - comp_data = data; - compression = BTRFS_COMPRESSION_NONE; - - *compressed = false; - } else { - compression = BTRFS_COMPRESSION_LZO; - comp_length = sector_align(*out_size, fcb->Vcb->superblock.sector_size); - - RtlZeroMemory(comp_data + *out_size, (ULONG)(comp_length - *out_size)); - - *compressed = true; - } - - ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true); - - le = fcb->Vcb->chunks.Flink; - while (le != &fcb->Vcb->chunks) { - c = CONTAINING_RECORD(le, chunk, list_entry); - - if (!c->readonly && !c->reloc) { - acquire_chunk_lock(c, fcb->Vcb); - - if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) { - if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) { - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_SUCCESS; - } - } - - release_chunk_lock(c, fcb->Vcb); - } - - le = le->Flink; - } - - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true); - - Status = alloc_chunk(fcb->Vcb, fcb->Vcb->data_flags, &c, false); - - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return Status; - } - - if (c) { - acquire_chunk_lock(c, fcb->Vcb); - - if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) { - if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) { - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_SUCCESS; - } - } - - release_chunk_lock(c, fcb->Vcb); - } - - WARN("couldn't find any data chunks with %I64x bytes free\n", comp_length); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_DISK_FULL; -} - -static NTSTATUS zstd_write_compressed_bit(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, bool* compressed, PIRP Irp, LIST_ENTRY* rollback) { - NTSTATUS Status; - uint8_t compression; - uint32_t comp_length; - uint8_t* comp_data; - uint32_t out_left; - LIST_ENTRY* le; - chunk* c; - ZSTD_CStream* stream; - size_t init_res, written; - ZSTD_inBuffer input; - ZSTD_outBuffer output; - ZSTD_parameters params; - - comp_data = ExAllocatePoolWithTag(PagedPool, (uint32_t)(end_data - start_data), ALLOC_TAG); - if (!comp_data) { - ERR("out of memory\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Status = excise_extents(fcb->Vcb, fcb, start_data, end_data, Irp, rollback); - if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); - ExFreePool(comp_data); - return Status; - } - - stream = ZSTD_createCStream_advanced(zstd_mem); - - if (!stream) { - ERR("ZSTD_createCStream failed.\n"); - ExFreePool(comp_data); - return STATUS_INTERNAL_ERROR; - } - - params = ZSTD_getParams(fcb->Vcb->options.zstd_level, (uint32_t)(end_data - start_data), 0); - - if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG) - params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG; - - init_res = ZSTD_initCStream_advanced(stream, NULL, 0, params, (uint32_t)(end_data - start_data)); - - if (ZSTD_isError(init_res)) { - ERR("ZSTD_initCStream_advanced failed: %s\n", ZSTD_getErrorName(init_res)); - ZSTD_freeCStream(stream); - ExFreePool(comp_data); - return STATUS_INTERNAL_ERROR; - } - - input.src = data; - input.size = (uint32_t)(end_data - start_data); - input.pos = 0; - - output.dst = comp_data; - output.size = (uint32_t)(end_data - start_data); - output.pos = 0; - - while (input.pos < input.size && output.pos < output.size) { - written = ZSTD_compressStream(stream, &output, &input); - - if (ZSTD_isError(written)) { - ERR("ZSTD_compressStream failed: %s\n", ZSTD_getErrorName(written)); - ZSTD_freeCStream(stream); - ExFreePool(comp_data); - return STATUS_INTERNAL_ERROR; - } - } - - written = ZSTD_endStream(stream, &output); - if (ZSTD_isError(written)) { - ERR("ZSTD_endStream failed: %s\n", ZSTD_getErrorName(written)); - ZSTD_freeCStream(stream); - ExFreePool(comp_data); - return STATUS_INTERNAL_ERROR; - } - - ZSTD_freeCStream(stream); - - out_left = output.size - output.pos; - - if (out_left < fcb->Vcb->superblock.sector_size) { // compressed extent would be larger than or same size as uncompressed extent - ExFreePool(comp_data); - - comp_length = (uint32_t)(end_data - start_data); - comp_data = data; - compression = BTRFS_COMPRESSION_NONE; - - *compressed = false; - } else { - uint32_t cl; - - compression = BTRFS_COMPRESSION_ZSTD; - cl = (uint32_t)(end_data - start_data - out_left); - comp_length = (uint32_t)sector_align(cl, fcb->Vcb->superblock.sector_size); - - RtlZeroMemory(comp_data + cl, comp_length - cl); - - *compressed = true; - } - - ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true); - - le = fcb->Vcb->chunks.Flink; - while (le != &fcb->Vcb->chunks) { - c = CONTAINING_RECORD(le, chunk, list_entry); - - if (!c->readonly && !c->reloc) { - acquire_chunk_lock(c, fcb->Vcb); - - if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) { - if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) { - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_SUCCESS; - } - } - - release_chunk_lock(c, fcb->Vcb); - } - - le = le->Flink; - } - - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true); - - Status = alloc_chunk(fcb->Vcb, fcb->Vcb->data_flags, &c, false); - - ExReleaseResourceLite(&fcb->Vcb->chunk_lock); - - if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return Status; - } - - if (c) { - acquire_chunk_lock(c, fcb->Vcb); - - if (c->chunk_item->type == fcb->Vcb->data_flags && (c->chunk_item->size - c->used) >= comp_length) { - if (insert_extent_chunk(fcb->Vcb, fcb, c, start_data, comp_length, false, comp_data, Irp, rollback, compression, end_data - start_data, false, 0)) { - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_SUCCESS; - } - } - - release_chunk_lock(c, fcb->Vcb); - } - - WARN("couldn't find any data chunks with %I64x bytes free\n", comp_length); - - if (compression != BTRFS_COMPRESSION_NONE) - ExFreePool(comp_data); - - return STATUS_DISK_FULL; -} - -NTSTATUS write_compressed_bit(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, bool* compressed, PIRP Irp, LIST_ENTRY* rollback) { - uint8_t type; - - if (fcb->Vcb->options.compress_type != 0 && fcb->prop_compression == PropCompression_None) - type = fcb->Vcb->options.compress_type; - else { - if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD) && fcb->prop_compression == PropCompression_ZSTD) - type = BTRFS_COMPRESSION_ZSTD; - else if (fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD && fcb->prop_compression != PropCompression_Zlib && fcb->prop_compression != PropCompression_LZO) - type = BTRFS_COMPRESSION_ZSTD; - else if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO) && fcb->prop_compression == PropCompression_LZO) - type = BTRFS_COMPRESSION_LZO; - else if (fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO && fcb->prop_compression != PropCompression_Zlib) - type = BTRFS_COMPRESSION_LZO; - else - type = BTRFS_COMPRESSION_ZLIB; - } - - if (type == BTRFS_COMPRESSION_ZSTD) { - fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD; - return zstd_write_compressed_bit(fcb, start_data, end_data, data, compressed, Irp, rollback); - } else if (type == BTRFS_COMPRESSION_LZO) { - fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO; - return lzo_write_compressed_bit(fcb, start_data, end_data, data, compressed, Irp, rollback); - } else - return zlib_write_compressed_bit(fcb, start_data, end_data, data, compressed, Irp, rollback); -} - static void* zstd_malloc(void* opaque, size_t size) { UNUSED(opaque); @@ -1175,3 +718,539 @@ end: return Status; } + +NTSTATUS lzo_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, unsigned int* space_left) { + NTSTATUS Status; + unsigned int num_pages; + unsigned int comp_data_len; + uint8_t* comp_data; + lzo_stream stream; + uint32_t* out_size; +#ifdef __REACTOS__ + unsigned int i; +#endif // __REACTOS__ + + num_pages = (unsigned int)sector_align(inlen, LZO_PAGE_SIZE) / LZO_PAGE_SIZE; + + // Four-byte overall header + // Another four-byte header page + // Each page has a maximum size of lzo_max_outlen(LZO_PAGE_SIZE) + // Plus another four bytes for possible padding + comp_data_len = sizeof(uint32_t) + ((lzo_max_outlen(LZO_PAGE_SIZE) + (2 * sizeof(uint32_t))) * num_pages); + + // FIXME - can we write this so comp_data isn't necessary? + + comp_data = ExAllocatePoolWithTag(PagedPool, comp_data_len, ALLOC_TAG); + if (!comp_data) { + ERR("out of memory\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + stream.wrkmem = ExAllocatePoolWithTag(PagedPool, LZO1X_MEM_COMPRESS, ALLOC_TAG); + if (!stream.wrkmem) { + ERR("out of memory\n"); + ExFreePool(comp_data); + return STATUS_INSUFFICIENT_RESOURCES; + } + + out_size = (uint32_t*)comp_data; + *out_size = sizeof(uint32_t); + + stream.in = inbuf; + stream.out = comp_data + (2 * sizeof(uint32_t)); + +#ifndef __REACTOS__ + for (unsigned int i = 0; i < num_pages; i++) { +#else + for (i = 0; i < num_pages; i++) { +#endif // __REACTOS__ + uint32_t* pagelen = (uint32_t*)(stream.out - sizeof(uint32_t)); + + stream.inlen = (uint32_t)min(LZO_PAGE_SIZE, outlen - (i * LZO_PAGE_SIZE)); + + Status = lzo1x_1_compress(&stream); + if (!NT_SUCCESS(Status)) { + ERR("lzo1x_1_compress returned %08lx\n", Status); + ExFreePool(comp_data); + return Status; + } + + *pagelen = stream.outlen; + *out_size += stream.outlen + sizeof(uint32_t); + + stream.in += LZO_PAGE_SIZE; + stream.out += stream.outlen + sizeof(uint32_t); + + // new page needs to start at a 32-bit boundary + if (LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE) < sizeof(uint32_t)) { + RtlZeroMemory(stream.out, LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE)); + stream.out += LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE); + *out_size += LZO_PAGE_SIZE - (*out_size % LZO_PAGE_SIZE); + } + } + + ExFreePool(stream.wrkmem); + + if (*out_size >= outlen) + *space_left = 0; + else { + *space_left = outlen - *out_size; + + RtlCopyMemory(outbuf, comp_data, *out_size); + } + + ExFreePool(comp_data); + + return STATUS_SUCCESS; +} + +NTSTATUS zstd_compress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, uint32_t level, unsigned int* space_left) { + ZSTD_CStream* stream; + size_t init_res, written; + ZSTD_inBuffer input; + ZSTD_outBuffer output; + ZSTD_parameters params; + + stream = ZSTD_createCStream_advanced(zstd_mem); + + if (!stream) { + ERR("ZSTD_createCStream failed.\n"); + return STATUS_INTERNAL_ERROR; + } + + params = ZSTD_getParams(level, inlen, 0); + + if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG) + params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG; + + init_res = ZSTD_initCStream_advanced(stream, NULL, 0, params, inlen); + + if (ZSTD_isError(init_res)) { + ERR("ZSTD_initCStream_advanced failed: %s\n", ZSTD_getErrorName(init_res)); + ZSTD_freeCStream(stream); + return STATUS_INTERNAL_ERROR; + } + + input.src = inbuf; + input.size = inlen; + input.pos = 0; + + output.dst = outbuf; + output.size = outlen; + output.pos = 0; + + while (input.pos < input.size && output.pos < output.size) { + written = ZSTD_compressStream(stream, &output, &input); + + if (ZSTD_isError(written)) { + ERR("ZSTD_compressStream failed: %s\n", ZSTD_getErrorName(written)); + ZSTD_freeCStream(stream); + return STATUS_INTERNAL_ERROR; + } + } + + written = ZSTD_endStream(stream, &output); + if (ZSTD_isError(written)) { + ERR("ZSTD_endStream failed: %s\n", ZSTD_getErrorName(written)); + ZSTD_freeCStream(stream); + return STATUS_INTERNAL_ERROR; + } + + ZSTD_freeCStream(stream); + + if (input.pos < input.size) // output would be larger than input + *space_left = 0; + else + *space_left = output.size - output.pos; + + return STATUS_SUCCESS; +} + +typedef struct { + uint8_t buf[COMPRESSED_EXTENT_SIZE]; + uint8_t compression_type; + unsigned int inlen; + unsigned int outlen; + calc_job* cj; +} comp_part; + +NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, PIRP Irp, LIST_ENTRY* rollback) { + NTSTATUS Status; + uint64_t i; + unsigned int num_parts = (unsigned int)sector_align(end_data - start_data, COMPRESSED_EXTENT_SIZE) / COMPRESSED_EXTENT_SIZE; + uint8_t type; + comp_part* parts; + unsigned int buflen = 0; + uint8_t* buf; + chunk* c = NULL; + LIST_ENTRY* le; + uint64_t address, extaddr; + void* csum = NULL; +#ifdef __REACTOS__ + int32_t i2; + uint32_t i3; +#endif // __REACTOS__ + + if (fcb->Vcb->options.compress_type != 0 && fcb->prop_compression == PropCompression_None) + type = fcb->Vcb->options.compress_type; + else { + if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD) && fcb->prop_compression == PropCompression_ZSTD) + type = BTRFS_COMPRESSION_ZSTD; + else if (fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD && fcb->prop_compression != PropCompression_Zlib && fcb->prop_compression != PropCompression_LZO) + type = BTRFS_COMPRESSION_ZSTD; + else if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO) && fcb->prop_compression == PropCompression_LZO) + type = BTRFS_COMPRESSION_LZO; + else if (fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO && fcb->prop_compression != PropCompression_Zlib) + type = BTRFS_COMPRESSION_LZO; + else + type = BTRFS_COMPRESSION_ZLIB; + } + + Status = excise_extents(fcb->Vcb, fcb, start_data, end_data, Irp, rollback); + if (!NT_SUCCESS(Status)) { + ERR("excise_extents returned %08lx\n", Status); + return Status; + } + + parts = ExAllocatePoolWithTag(PagedPool, sizeof(comp_part) * num_parts, ALLOC_TAG); + if (!parts) { + ERR("out of memory\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + for (i = 0; i < num_parts; i++) { + if (i == num_parts - 1) + parts[i].inlen = ((unsigned int)(end_data - start_data) - ((num_parts - 1) * COMPRESSED_EXTENT_SIZE)); + else + parts[i].inlen = COMPRESSED_EXTENT_SIZE; + + Status = add_calc_job_comp(fcb->Vcb, type, (uint8_t*)data + (i * COMPRESSED_EXTENT_SIZE), parts[i].inlen, + parts[i].buf, parts[i].inlen, &parts[i].cj); + if (!NT_SUCCESS(Status)) { + ERR("add_calc_job_comp returned %08lx\n", Status); + + for (unsigned int j = 0; j < i; j++) { + KeWaitForSingleObject(&parts[j].cj->event, Executive, KernelMode, false, NULL); + ExFreePool(parts[j].cj); + } + + ExFreePool(parts); + return Status; + } + } + + Status = STATUS_SUCCESS; + +#ifndef __REACTOS__ + for (int i = num_parts - 1; i >= 0; i--) { + calc_thread_main(fcb->Vcb, parts[i].cj); + + KeWaitForSingleObject(&parts[i].cj->event, Executive, KernelMode, false, NULL); + + if (!NT_SUCCESS(parts[i].cj->Status)) + Status = parts[i].cj->Status; + } +#else + for (i2 = num_parts - 1; i2 >= 0; i2--) { + calc_thread_main(fcb->Vcb, parts[i].cj); + + KeWaitForSingleObject(&parts[i2].cj->event, Executive, KernelMode, false, NULL); + + if (!NT_SUCCESS(parts[i2].cj->Status)) + Status = parts[i2].cj->Status; + } +#endif // __REACTOS__ + + if (!NT_SUCCESS(Status)) { + ERR("calc job returned %08lx\n", Status); + +#ifndef __REACTOS__ + for (unsigned int i = 0; i < num_parts; i++) { + ExFreePool(parts[i].cj); + } +#else + for (i3 = 0; i3 < num_parts; i3++) { + ExFreePool(parts[i3].cj); + } +#endif // __REACTOS__ + + ExFreePool(parts); + return Status; + } + +#ifndef __REACTOS__ + for (unsigned int i = 0; i < num_parts; i++) { + if (parts[i].cj->space_left >= fcb->Vcb->superblock.sector_size) { + parts[i].compression_type = type; + parts[i].outlen = parts[i].inlen - parts[i].cj->space_left; + + if (type == BTRFS_COMPRESSION_LZO) + fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO; + else if (type == BTRFS_COMPRESSION_ZSTD) + fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD; + + if ((parts[i].outlen % fcb->Vcb->superblock.sector_size) != 0) { + unsigned int newlen = (unsigned int)sector_align(parts[i].outlen, fcb->Vcb->superblock.sector_size); + + RtlZeroMemory(parts[i].buf + parts[i].outlen, newlen - parts[i].outlen); + + parts[i].outlen = newlen; + } + } else { + parts[i].compression_type = BTRFS_COMPRESSION_NONE; + parts[i].outlen = (unsigned int)sector_align(parts[i].inlen, fcb->Vcb->superblock.sector_size); + } + + buflen += parts[i].outlen; + ExFreePool(parts[i].cj); + } +#else + for (i3 = 0; i3 < num_parts; i3++) { + if (parts[i3].cj->space_left >= fcb->Vcb->superblock.sector_size) { + parts[i3].compression_type = type; + parts[i3].outlen = parts[i3].inlen - parts[i3].cj->space_left; + + if (type == BTRFS_COMPRESSION_LZO) + fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO; + else if (type == BTRFS_COMPRESSION_ZSTD) + fcb->Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD; + + if ((parts[i3].outlen % fcb->Vcb->superblock.sector_size) != 0) { + unsigned int newlen = (unsigned int)sector_align(parts[i3].outlen, fcb->Vcb->superblock.sector_size); + + RtlZeroMemory(parts[i3].buf + parts[i3].outlen, newlen - parts[i3].outlen); + + parts[i3].outlen = newlen; + } + } else { + parts[i3].compression_type = BTRFS_COMPRESSION_NONE; + parts[i3].outlen = (unsigned int)sector_align(parts[i3].inlen, fcb->Vcb->superblock.sector_size); + } + + buflen += parts[i3].outlen; + ExFreePool(parts[i3].cj); + } +#endif // __REACTOS__ + + // check if first 128 KB of file is incompressible + + if (start_data == 0 && parts[0].compression_type == BTRFS_COMPRESSION_NONE && !fcb->Vcb->options.compress_force) { + TRACE("adding nocompress flag to subvol %I64x, inode %I64x\n", fcb->subvol->id, fcb->inode); + + fcb->inode_item.flags |= BTRFS_INODE_NOCOMPRESS; + fcb->inode_item_changed = true; + mark_fcb_dirty(fcb); + } + + // join together into continuous buffer + + buf = ExAllocatePoolWithTag(PagedPool, buflen, ALLOC_TAG); + if (!buf) { + ERR("out of memory\n"); + ExFreePool(parts); + return STATUS_INSUFFICIENT_RESOURCES; + } + + { + uint8_t* buf2 = buf; + + for (i = 0; i < num_parts; i++) { + if (parts[i].compression_type == BTRFS_COMPRESSION_NONE) + RtlCopyMemory(buf2, (uint8_t*)data + (i * COMPRESSED_EXTENT_SIZE), parts[i].outlen); + else + RtlCopyMemory(buf2, parts[i].buf, parts[i].outlen); + + buf2 += parts[i].outlen; + } + } + + // find an address + + ExAcquireResourceSharedLite(&fcb->Vcb->chunk_lock, true); + + le = fcb->Vcb->chunks.Flink; + while (le != &fcb->Vcb->chunks) { + chunk* c2 = CONTAINING_RECORD(le, chunk, list_entry); + + if (!c2->readonly && !c2->reloc) { + acquire_chunk_lock(c2, fcb->Vcb); + + if (c2->chunk_item->type == fcb->Vcb->data_flags && (c2->chunk_item->size - c2->used) >= buflen) { + if (find_data_address_in_chunk(fcb->Vcb, c2, buflen, &address)) { + c = c2; + c->used += buflen; + space_list_subtract(c, false, address, buflen, rollback); + release_chunk_lock(c2, fcb->Vcb); + break; + } + } + + release_chunk_lock(c2, fcb->Vcb); + } + + le = le->Flink; + } + + ExReleaseResourceLite(&fcb->Vcb->chunk_lock); + + if (!c) { + chunk* c2; + + ExAcquireResourceExclusiveLite(&fcb->Vcb->chunk_lock, true); + + Status = alloc_chunk(fcb->Vcb, fcb->Vcb->data_flags, &c2, false); + + ExReleaseResourceLite(&fcb->Vcb->chunk_lock); + + if (!NT_SUCCESS(Status)) { + ERR("alloc_chunk returned %08lx\n", Status); + ExFreePool(buf); + ExFreePool(parts); + return Status; + } + + acquire_chunk_lock(c2, fcb->Vcb); + + if (find_data_address_in_chunk(fcb->Vcb, c2, buflen, &address)) { + c = c2; + c->used += buflen; + space_list_subtract(c, false, address, buflen, rollback); + } + + release_chunk_lock(c2, fcb->Vcb); + } + + if (!c) { + WARN("couldn't find any data chunks with %x bytes free\n", buflen); + ExFreePool(buf); + ExFreePool(parts); + return STATUS_DISK_FULL; + } + + // write to disk + + TRACE("writing %x bytes to %I64x\n", buflen, address); + + Status = write_data_complete(fcb->Vcb, address, buf, buflen, Irp, NULL, false, 0, + fcb->Header.Flags2 & FSRTL_FLAG2_IS_PAGING_FILE ? HighPagePriority : NormalPagePriority); + if (!NT_SUCCESS(Status)) { + ERR("write_data_complete returned %08lx\n", Status); + ExFreePool(buf); + ExFreePool(parts); + return Status; + } + + // FIXME - do rest of the function while we're waiting for I/O to finish? + + // calculate csums if necessary + + if (!(fcb->inode_item.flags & BTRFS_INODE_NODATASUM)) { + unsigned int sl = buflen / fcb->Vcb->superblock.sector_size; + + csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG); + if (!csum) { + ERR("out of memory\n"); + ExFreePool(buf); + ExFreePool(parts); + return STATUS_INSUFFICIENT_RESOURCES; + } + + do_calc_job(fcb->Vcb, buf, sl, csum); + } + + ExFreePool(buf); + + // add extents to fcb + + extaddr = address; + + for (i = 0; i < num_parts; i++) { + EXTENT_DATA* ed; + EXTENT_DATA2* ed2; + void* csum2; + + ed = ExAllocatePoolWithTag(PagedPool, offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2), ALLOC_TAG); + if (!ed) { + ERR("out of memory\n"); + ExFreePool(parts); + + if (csum) + ExFreePool(csum); + + return STATUS_INSUFFICIENT_RESOURCES; + } + + ed->generation = fcb->Vcb->superblock.generation; + ed->decoded_size = parts[i].inlen; + ed->compression = parts[i].compression_type; + ed->encryption = BTRFS_ENCRYPTION_NONE; + ed->encoding = BTRFS_ENCODING_NONE; + ed->type = EXTENT_TYPE_REGULAR; + + ed2 = (EXTENT_DATA2*)ed->data; + ed2->address = extaddr; + ed2->size = parts[i].outlen; + ed2->offset = 0; + ed2->num_bytes = parts[i].inlen; + + if (csum) { + csum2 = ExAllocatePoolWithTag(PagedPool, parts[i].outlen * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size, ALLOC_TAG); + if (!csum2) { + ERR("out of memory\n"); + ExFreePool(ed); + ExFreePool(parts); + ExFreePool(csum); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyMemory(csum2, (uint8_t*)csum + ((extaddr - address) * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size), + parts[i].outlen * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size); + } else + csum2 = NULL; + + Status = add_extent_to_fcb(fcb, start_data + (i * COMPRESSED_EXTENT_SIZE), ed, offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2), + true, csum2, rollback); + if (!NT_SUCCESS(Status)) { + ERR("add_extent_to_fcb returned %08lx\n", Status); + ExFreePool(ed); + ExFreePool(parts); + + if (csum) + ExFreePool(csum); + + return Status; + } + + ExFreePool(ed); + + fcb->inode_item.st_blocks += parts[i].inlen; + + extaddr += parts[i].outlen; + } + + if (csum) + ExFreePool(csum); + + // update extent refcounts + + ExAcquireResourceExclusiveLite(&c->changed_extents_lock, true); + + extaddr = address; + + for (i = 0; i < num_parts; i++) { + add_changed_extent_ref(c, extaddr, parts[i].outlen, fcb->subvol->id, fcb->inode, + start_data + (i * COMPRESSED_EXTENT_SIZE), 1, fcb->inode_item.flags & BTRFS_INODE_NODATASUM); + + extaddr += parts[i].outlen; + } + + ExReleaseResourceLite(&c->changed_extents_lock); + + fcb->extents_changed = true; + fcb->inode_item_changed = true; + mark_fcb_dirty(fcb); + + ExFreePool(parts); + + return STATUS_SUCCESS; +} diff --git a/drivers/filesystems/btrfs/crc32c-amd64.S b/drivers/filesystems/btrfs/crc32c-amd64.S new file mode 100644 index 00000000000..3a6c910a32e --- /dev/null +++ b/drivers/filesystems/btrfs/crc32c-amd64.S @@ -0,0 +1,112 @@ +/* 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 . */ + +#include + +EXTERN _crctable:QWORD + +.code64 + + +/* uint32_t __stdcall calc_crc32c_sw(uint32_t seed, uint8_t* msg, uint32_t msglen); */ + +PUBLIC _calc_crc32c_sw@12 +_calc_crc32c_sw@12: + +/* 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 +mov rax, dword ptr [_crctable + 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@12: +_calc_crc32c_hw@12: + +/* 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-x86.S new file mode 100644 index 00000000000..991eec8dc57 --- /dev/null +++ b/drivers/filesystems/btrfs/crc32c-x86.S @@ -0,0 +1,122 @@ +/* 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 . */ + +#include + +EXTERN _crctable:DWORD + +.code + +/* uint32_t __stdcall calc_crc32c_sw(uint32_t seed, uint8_t* msg, uint32_t msglen); */ + +PUBLIC _calc_crc32c_sw@12 +_calc_crc32c_sw@12: + +push ebp +mov ebp, esp + +push esi +push ebx + +mov eax, [ebp+8] +mov edx, [ebp+12] +mov ebx, [ebp+16] + +/* eax = crc / seed + * ebx = len + * esi = tmp + * edx = buf + * ecx = tmp2 */ + +crcloop: +test ebx, ebx +jz crcend + +mov esi, eax +shr esi, 8 +mov cl, byte ptr [edx] +xor al, cl +and eax, 255 +shl eax, 2 +mov eax, [_crctable + eax] +xor eax, esi + +inc edx +dec ebx + +jmp crcloop + +crcend: +pop ebx +pop esi + +pop ebp + +ret 12 + +/****************************************************/ + +/* uint32_t __stdcall calc_crc32c_hw(uint32_t seed, uint8_t* msg, uint32_t msglen); */ + +PUBLIC _calc_crc32c_hw@12 +_calc_crc32c_hw@12: + +push ebp +mov ebp, esp + +mov eax, [ebp+8] +mov edx, [ebp+12] +mov ecx, [ebp+16] + +/* eax = crc / seed + * ecx = len + * edx = buf */ + +crchw_loop: +cmp ecx, 4 +jl crchw_stragglers + +crc32 eax, dword ptr [edx] + +add edx, 4 +sub ecx, 4 +jmp crchw_loop + +crchw_stragglers: +cmp ecx, 2 +jl crchw_stragglers2 + +crc32 eax, word ptr [edx] + +add edx, 2 +sub ecx, 2 + +crchw_stragglers2: +test ecx, ecx +jz crchw_end + +crc32 eax, byte ptr [edx] +inc edx +dec ecx +jmp crchw_stragglers2 + +crchw_end: +pop ebp + +ret 12 + +END diff --git a/drivers/filesystems/btrfs/crc32c.c b/drivers/filesystems/btrfs/crc32c.c index 8d09cad0faf..ef4572bbfde 100644 --- a/drivers/filesystems/btrfs/crc32c.c +++ b/drivers/filesystems/btrfs/crc32c.c @@ -15,18 +15,14 @@ * You should have received a copy of the GNU Lesser General Public Licence * along with WinBtrfs. If not, see . */ -#include -#ifndef __REACTOS__ -#include -#endif /* __REACTOS__ */ +#include "crc32c.h" #include #include +#include -#ifndef __REACTOS__ -extern bool have_sse42; -#endif /* __REACTOS__ */ +crc_func calc_crc32c = calc_crc32c_sw; -static const uint32_t crctable[] = { +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, @@ -61,75 +57,15 @@ static const uint32_t crctable[] = { 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351, }; -#ifndef __REACTOS__ -// 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) -= sizeof(type), buf += sizeof (type)) { \ - (crc) = op((crc), *(type *) (buf)); \ - } \ - } while(0) +// x86 and amd64 versions live in asm files +#if !defined(_X86_) && !defined(_AMD64_) +uint32_t __stdcall calc_crc32c_sw(_In_ uint32_t seed, _In_reads_bytes_(msglen) uint8_t* msg, _In_ uint32_t msglen) { + uint32_t rem = seed; -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 + for (uint32_t i = 0; i < msglen; i++) { + rem = crctable[(rem ^ msg[i]) & 0xff] ^ (rem >> 8); } -#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 - -uint32_t calc_crc32c(_In_ uint32_t seed, _In_reads_bytes_(msglen) uint8_t* msg, _In_ ULONG msglen) { - uint32_t rem; - ULONG i; - -#ifndef __REACTOS__ - if (have_sse42) { - return crc32c_hw(msg, msglen, seed); - } else { -#endif - rem = seed; - - for (i = 0; i < msglen; i++) { - rem = crctable[(rem ^ msg[i]) & 0xff] ^ (rem >> 8); - } -#ifndef __REACTOS__ - } -#endif - return rem; } +#endif diff --git a/drivers/filesystems/btrfs/crc32c.h b/drivers/filesystems/btrfs/crc32c.h new file mode 100644 index 00000000000..73bd9697af3 --- /dev/null +++ b/drivers/filesystems/btrfs/crc32c.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +#if defined(_X86_) || defined(_AMD64_) +uint32_t __stdcall calc_crc32c_hw(uint32_t seed, uint8_t* msg, uint32_t msglen); +#endif + +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; diff --git a/drivers/filesystems/btrfs/create.c b/drivers/filesystems/btrfs/create.c index 4eebef939b1..082159053bb 100644 --- a/drivers/filesystems/btrfs/create.c +++ b/drivers/filesystems/btrfs/create.c @@ -19,6 +19,7 @@ #include #endif /* __REACTOS__ */ #include "btrfs_drv.h" +#include "crc32c.h" #include extern PDEVICE_OBJECT master_devobj; @@ -33,8 +34,21 @@ static const WCHAR root_dir_utf16[] = L"$Root"; // Windows 10 #define ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED 0x0002 +#define ATOMIC_CREATE_ECP_IN_FLAG_OP_FLAGS_SPECIFIED 0x0080 #define ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT 0x0100 + #define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET 0x0002 +#define ATOMIC_CREATE_ECP_OUT_FLAG_OP_FLAGS_HONORED 0x0080 + +#define ATOMIC_CREATE_ECP_IN_OP_FLAG_CASE_SENSITIVE_FLAGS_SPECIFIED 1 +#define ATOMIC_CREATE_ECP_OUT_OP_FLAG_CASE_SENSITIVE_FLAGS_SET 1 + +typedef struct _FILE_TIMESTAMPS { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; +} FILE_TIMESTAMPS, *PFILE_TIMESTAMPS; typedef struct _ATOMIC_CREATE_ECP_CONTEXT { USHORT Size; @@ -44,9 +58,23 @@ typedef struct _ATOMIC_CREATE_ECP_CONTEXT { PREPARSE_DATA_BUFFER ReparseBuffer; LONGLONG FileSize; LONGLONG ValidDataLength; + PFILE_TIMESTAMPS FileTimestamps; + ULONG FileAttributes; + ULONG UsnSourceInfo; + USN Usn; + ULONG SuppressFileAttributeInheritanceMask; + ULONG InOpFlags; + ULONG OutOpFlags; + ULONG InGenFlags; + ULONG OutGenFlags; + ULONG CaseSensitiveFlagsMask; + ULONG InCaseSensitiveFlags; + ULONG OutCaseSensitiveFlags; } ATOMIC_CREATE_ECP_CONTEXT, *PATOMIC_CREATE_ECP_CONTEXT; static const GUID GUID_ECP_ATOMIC_CREATE = { 0x4720bd83, 0x52ac, 0x4104, { 0xa1, 0x30, 0xd1, 0xec, 0x6a, 0x8c, 0xc8, 0xe5 } }; +static const GUID GUID_ECP_QUERY_ON_CREATE = { 0x1aca62e9, 0xabb4, 0x4ff2, { 0xbb, 0x5c, 0x1c, 0x79, 0x02, 0x5e, 0x41, 0x7f } }; +static const GUID GUID_ECP_CREATE_REDIRECTION = { 0x188d6bd6, 0xa126, 0x4fa8, { 0xbd, 0xf2, 0x1c, 0xcd, 0xf8, 0x96, 0xf3, 0xe0 } }; fcb* create_fcb(device_extension* Vcb, POOL_TYPE pool_type) { fcb* fcb; @@ -160,7 +188,7 @@ NTSTATUS find_file_in_dir(PUNICODE_STRING filename, fcb* fcb, root** subvol, uin Status = RtlUpcaseUnicodeString(&fnus, filename, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); return Status; } } else @@ -415,12 +443,13 @@ cleanup: return Status; } -NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, uint32_t* csum, uint64_t start, uint64_t length, PIRP Irp) { +NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, void* csum, uint64_t start, uint64_t length, PIRP Irp) { NTSTATUS Status; KEY searchkey; traverse_ptr tp, next_tp; uint64_t i, j; bool b; + void* ptr = csum; searchkey.obj_id = EXTENT_CSUM_ID; searchkey.obj_type = TYPE_EXTENT_CSUM; @@ -428,7 +457,7 @@ NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb Status = find_item(Vcb, Vcb->checksum_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -442,13 +471,15 @@ NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb else j = ((start - tp.item->key.offset) / Vcb->superblock.sector_size) + i; - if (j * sizeof(uint32_t) > tp.item->size || tp.item->key.offset > start + (i * Vcb->superblock.sector_size)) { + if (j * Vcb->csum_size > tp.item->size || tp.item->key.offset > start + (i * Vcb->superblock.sector_size)) { ERR("checksum not found for %I64x\n", start + (i * Vcb->superblock.sector_size)); return STATUS_INTERNAL_ERROR; } - readlen = (ULONG)min((tp.item->size / sizeof(uint32_t)) - j, length - i); - RtlCopyMemory(&csum[i], tp.item->data + (j * sizeof(uint32_t)), readlen * sizeof(uint32_t)); + readlen = (ULONG)min((tp.item->size / Vcb->csum_size) - j, length - i); + RtlCopyMemory(ptr, tp.item->data + (j * Vcb->csum_size), readlen * Vcb->csum_size); + + ptr = (uint8_t*)ptr + (readlen * Vcb->csum_size); i += readlen; if (i == length) @@ -501,7 +532,7 @@ NTSTATUS load_dir_children(_Requires_lock_held_(_Curr_->tree_lock) device_extens Status = find_item(Vcb, fcb->subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -518,7 +549,7 @@ NTSTATUS load_dir_children(_Requires_lock_held_(_Curr_->tree_lock) device_extens ULONG utf16len; if (tp.item->size < sizeof(DIR_ITEM)) { - WARN("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM)); + WARN("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM)); goto cont; } @@ -529,7 +560,7 @@ NTSTATUS load_dir_children(_Requires_lock_held_(_Curr_->tree_lock) device_extens Status = utf8_to_utf16(NULL, 0, &utf16len, di->name, di->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); goto cont; } @@ -568,7 +599,7 @@ NTSTATUS load_dir_children(_Requires_lock_held_(_Curr_->tree_lock) device_extens Status = utf8_to_utf16(dc->name.Buffer, utf16len, &utf16len, di->name, di->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(dc->utf8.Buffer); ExFreePool(dc->name.Buffer); ExFreePool(dc); @@ -577,7 +608,7 @@ NTSTATUS load_dir_children(_Requires_lock_held_(_Curr_->tree_lock) device_extens Status = RtlUpcaseUnicodeString(&dc->name_uc, &dc->name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); ExFreePool(dc->utf8.Buffer); ExFreePool(dc->name.Buffer); ExFreePool(dc); @@ -646,7 +677,7 @@ cont: Status = RtlUpcaseUnicodeString(&dc->name_uc, &dc->name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); ExFreePool(dc->utf8.Buffer); ExFreePool(dc->name.Buffer); ExFreePool(dc); @@ -750,7 +781,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = find_item(Vcb, subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); reap_fcb(fcb); return Status; } @@ -822,7 +853,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = utf8_to_utf16(NULL, 0, &stringlen, ir->name, ir->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); ExFreePool(hl); reap_fcb(fcb); return Status; @@ -844,7 +875,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = utf8_to_utf16(hl->name.Buffer, stringlen, &stringlen, ir->name, ir->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(hl->name.Buffer); ExFreePool(hl); reap_fcb(fcb); @@ -887,7 +918,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = utf8_to_utf16(NULL, 0, &stringlen, ier->name, ier->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); ExFreePool(hl); reap_fcb(fcb); return Status; @@ -909,7 +940,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = utf8_to_utf16(hl->name.Buffer, stringlen, &stringlen, ier->name, ier->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(hl->name.Buffer); ExFreePool(hl); reap_fcb(fcb); @@ -929,7 +960,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo static const char xapref[] = "user."; if (tp.item->size < offsetof(DIR_ITEM, name[0])) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(DIR_ITEM, name[0])); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(DIR_ITEM, name[0])); continue; } @@ -961,7 +992,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = IoCheckEaBufferValidity((FILE_FULL_EA_INFORMATION*)&di->name[di->n], di->m, &offset); if (!NT_SUCCESS(Status)) - WARN("IoCheckEaBufferValidity returned %08x (error at offset %u)\n", Status, offset); + WARN("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset); else { FILE_FULL_EA_INFORMATION* eainfo; @@ -1055,7 +1086,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = utf8_to_utf16(NULL, 0, &utf16len, &di->name[sizeof(xapref) - 1], di->n + 1 - sizeof(xapref)); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); reap_fcb(fcb); return Status; } @@ -1092,7 +1123,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = utf8_to_utf16(dc->name.Buffer, utf16len, &utf16len, dc->utf8.Buffer, dc->utf8.Length); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(dc->utf8.Buffer); ExFreePool(dc->name.Buffer); ExFreePool(dc); @@ -1102,7 +1133,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo Status = RtlUpcaseUnicodeString(&dc->name_uc, &dc->name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); ExFreePool(dc->utf8.Buffer); ExFreePool(dc->name.Buffer); ExFreePool(dc); @@ -1145,7 +1176,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo ed = (EXTENT_DATA*)tp.item->data; if (tp.item->size < sizeof(EXTENT_DATA)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA)); reap_fcb(fcb); @@ -1156,7 +1187,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo EXTENT_DATA2* ed2 = (EXTENT_DATA2*)&ed->data[0]; if (tp.item->size < sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2)); reap_fcb(fcb); @@ -1192,7 +1223,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo if (fcb->type == BTRFS_TYPE_DIRECTORY) { Status = load_dir_children(Vcb, fcb, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("load_dir_children returned %08x\n", Status); + ERR("load_dir_children returned %08lx\n", Status); reap_fcb(fcb); return Status; } @@ -1309,7 +1340,7 @@ NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lo } } - if (fcb->inode == SUBVOL_ROOT_INODE && fcb->subvol->id == BTRFS_ROOT_FSTREE) + if (fcb->inode == SUBVOL_ROOT_INODE && fcb->subvol->id == BTRFS_ROOT_FSTREE && fcb->subvol != Vcb->root_fileref->fcb->subvol) fcb->atts |= FILE_ATTRIBUTE_HIDDEN; subvol->fcbs_version++; @@ -1382,7 +1413,7 @@ static NTSTATUS open_fcb_stream(_Requires_lock_held_(_Curr_->tree_lock) _Require Status = find_item(Vcb, parent->subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); reap_fcb(fcb); return Status; } @@ -1439,7 +1470,7 @@ NTSTATUS open_fileref_child(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ex if (!case_sensitive) { Status = RtlUpcaseUnicodeString(&name_uc, name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); return Status; } } @@ -1496,7 +1527,7 @@ NTSTATUS open_fileref_child(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ex Status = open_fcb_stream(Vcb, dc, sf->fcb, &fcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fcb_stream returned %08x\n", Status); + ERR("open_fcb_stream returned %08lx\n", Status); return Status; } @@ -1569,11 +1600,11 @@ NTSTATUS open_fileref_child(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ex Status = find_file_in_dir(name, sf->fcb, &subvol, &inode, &dc, case_sensitive); if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { - TRACE("could not find %.*S\n", name->Length / sizeof(WCHAR), name->Buffer); + TRACE("could not find %.*S\n", (int)(name->Length / sizeof(WCHAR)), name->Buffer); return lastpart ? STATUS_OBJECT_NAME_NOT_FOUND : STATUS_OBJECT_PATH_NOT_FOUND; } else if (!NT_SUCCESS(Status)) { - ERR("find_file_in_dir returned %08x\n", Status); + ERR("find_file_in_dir returned %08lx\n", Status); return Status; } else { fcb* fcb; @@ -1597,7 +1628,7 @@ NTSTATUS open_fileref_child(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ex Status = open_fcb(Vcb, subvol, inode, dc->type, &dc->utf8, false, sf->fcb, &fcb, pooltype, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fcb returned %08x\n", Status); + ERR("open_fcb returned %08lx\n", Status); return Status; } } @@ -1679,7 +1710,7 @@ NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusiv dir = related; } else { if (fnus2.Buffer[0] != '\\') { - ERR("error - filename %.*S did not begin with \\\n", fnus2.Length / sizeof(WCHAR), fnus2.Buffer); + ERR("error - filename %.*S did not begin with \\\n", (int)(fnus2.Length / sizeof(WCHAR)), fnus2.Buffer); return STATUS_OBJECT_PATH_NOT_FOUND; } @@ -1713,7 +1744,7 @@ NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusiv if (dir->fcb->type != BTRFS_TYPE_DIRECTORY && (fnus->Length < sizeof(WCHAR) || fnus->Buffer[0] != ':')) { WARN("passed related fileref which isn't a directory (fnus = %.*S)\n", - fnus->Length / sizeof(WCHAR), fnus->Buffer); + (int)(fnus->Length / sizeof(WCHAR)), fnus->Buffer); return STATUS_OBJECT_PATH_NOT_FOUND; } @@ -1723,7 +1754,7 @@ NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusiv (fnus->Length != sizeof(datastring) - sizeof(WCHAR) || RtlCompareMemory(fnus->Buffer, datastring, sizeof(datastring) - sizeof(WCHAR)) != sizeof(datastring) - sizeof(WCHAR))) { Status = split_path(Vcb, &fnus2, &parts, &has_stream); if (!NT_SUCCESS(Status)) { - ERR("split_path returned %08x\n", Status); + ERR("split_path returned %08lx\n", Status); return Status; } } @@ -1773,9 +1804,9 @@ NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusiv if (!NT_SUCCESS(Status)) { if (Status == STATUS_OBJECT_PATH_NOT_FOUND || Status == STATUS_OBJECT_NAME_NOT_FOUND) - TRACE("open_fileref_child returned %08x\n", Status); + TRACE("open_fileref_child returned %08lx\n", Status); else - ERR("open_fileref_child returned %08x\n", Status); + ERR("open_fileref_child returned %08lx\n", Status); goto end; } @@ -1822,7 +1853,7 @@ end: } end2: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); return Status; } @@ -1867,7 +1898,7 @@ NTSTATUS add_dir_child(fcb* fcb, uint64_t inode, bool subvol, PANSI_STRING utf8, Status = RtlUpcaseUnicodeString(&dc->name_uc, name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); ExFreePool(dc->utf8.Buffer); ExFreePool(dc->name.Buffer); ExFreePool(dc); @@ -2161,7 +2192,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr Status = utf16_to_utf8(NULL, 0, &utf8len, fpus->Buffer, fpus->Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 returned %08x\n", Status); + ERR("utf16_to_utf8 returned %08lx\n", Status); return Status; } @@ -2173,7 +2204,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr Status = utf16_to_utf8(utf8, utf8len, &utf8len, fpus->Buffer, fpus->Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 returned %08x\n", Status); + ERR("utf16_to_utf8 returned %08lx\n", Status); ExFreePool(utf8); return Status; } @@ -2183,7 +2214,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr KeQuerySystemTime(&time); win_time_to_unix(time, &now); - TRACE("create file %.*S\n", fpus->Length / sizeof(WCHAR), fpus->Buffer); + TRACE("create file %.*S\n", (int)(fpus->Length / sizeof(WCHAR)), fpus->Buffer); ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true); TRACE("parfileref->fcb->inode_item.st_size (inode %I64x) was %I64x\n", parfileref->fcb->inode, parfileref->fcb->inode_item.st_size); parfileref->fcb->inode_item.st_size += utf8len * 2; @@ -2365,7 +2396,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr Status = fcb_get_new_sd(fcb, parfileref, IrpSp->Parameters.Create.SecurityContext->AccessState); if (!NT_SUCCESS(Status)) { - ERR("fcb_get_new_sd returned %08x\n", Status); + ERR("fcb_get_new_sd returned %08lx\n", Status); free_fcb(fcb); ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true); @@ -2382,7 +2413,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr if (ea && ealen > 0) { Status = file_create_parse_ea(fcb, ea); if (!NT_SUCCESS(Status)) { - ERR("file_create_parse_ea returned %08x\n", Status); + ERR("file_create_parse_ea returned %08lx\n", Status); free_fcb(fcb); ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true); @@ -2415,7 +2446,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr Status = extend_file(fcb, fileref, Irp->Overlay.AllocationSize.QuadPart, true, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("extend_file returned %08x\n", Status); + ERR("extend_file returned %08lx\n", Status); reap_fileref(Vcb, fileref); ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true); @@ -2501,7 +2532,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr Status = RtlUpcaseUnicodeString(&fpusuc, fpus, true); if (!NT_SUCCESS(Status)) { ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock); - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); reap_fileref(Vcb, fileref); ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true); @@ -2517,7 +2548,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr uint32_t dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length); #else dc_hash = calc_crc32c(0xffffffff, (uint8_t*)fpusuc.Buffer, fpusuc.Length); -#endif +#endif // __REACTOS__ if (parfileref->fcb->hash_ptrs_uc[dc_hash >> 24]) { LIST_ENTRY* le = parfileref->fcb->hash_ptrs_uc[dc_hash >> 24]; @@ -2556,7 +2587,7 @@ static NTSTATUS file_create2(_In_ PIRP Irp, _Requires_exclusive_lock_held_(_Curr Status = add_dir_child(parfileref->fcb, fcb->inode, false, &utf8as, fpus, fcb->type, &dc); if (!NT_SUCCESS(Status)) { ExReleaseResourceLite(&parfileref->fcb->nonpaged->dir_children_lock); - ERR("add_dir_child returned %08x\n", Status); + ERR("add_dir_child returned %08lx\n", Status); reap_fileref(Vcb, fileref); ExAcquireResourceExclusiveLite(parfileref->fcb->Header.Resource, true); @@ -2617,8 +2648,8 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ LIST_ENTRY* le; #endif - TRACE("fpus = %.*S\n", fpus->Length / sizeof(WCHAR), fpus->Buffer); - TRACE("stream = %.*S\n", stream->Length / sizeof(WCHAR), stream->Buffer); + TRACE("fpus = %.*S\n", (int)(fpus->Length / sizeof(WCHAR)), fpus->Buffer); + TRACE("stream = %.*S\n", (int)(stream->Length / sizeof(WCHAR)), stream->Buffer); parfileref = *pparfileref; @@ -2658,7 +2689,7 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ Status = file_create2(Irp, Vcb, &fpus2, parfileref, options, NULL, 0, &newpar, case_sensitive, rollback); if (!NT_SUCCESS(Status)) { - ERR("file_create2 returned %08x\n", Status); + ERR("file_create2 returned %08lx\n", Status); ExFreePool(fpus2.Buffer); return Status; } else if (Status != STATUS_OBJECT_NAME_COLLISION) { @@ -2668,7 +2699,7 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ ExFreePool(fpus2.Buffer); } else if (!NT_SUCCESS(Status)) { - ERR("open_fileref returned %08x\n", Status); + ERR("open_fileref returned %08lx\n", Status); return Status; } @@ -2740,7 +2771,7 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ Status = utf16_to_utf8(NULL, 0, &utf8len, stream->Buffer, stream->Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 1 returned %08x\n", Status); + ERR("utf16_to_utf8 1 returned %08lx\n", Status); reap_fcb(fcb); free_fileref(parfileref); return Status; @@ -2760,7 +2791,7 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ Status = utf16_to_utf8(&fcb->adsxattr.Buffer[sizeof(xapref) - 1], utf8len, &utf8len, stream->Buffer, stream->Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 2 returned %08x\n", Status); + ERR("utf16_to_utf8 2 returned %08lx\n", Status); reap_fcb(fcb); free_fileref(parfileref); return Status; @@ -2779,7 +2810,7 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ Status = find_item(Vcb, parfileref->fcb->subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); reap_fcb(fcb); free_fileref(parfileref); return Status; @@ -2793,7 +2824,7 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ fcb->adsmaxlen = Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node) - (sizeof(DIR_ITEM) - 1); if (utf8len + sizeof(xapref) - 1 + overhead > fcb->adsmaxlen) { - WARN("not enough room for new DIR_ITEM (%u + %u > %u)", utf8len + sizeof(xapref) - 1, overhead, fcb->adsmaxlen); + WARN("not enough room for new DIR_ITEM (%Iu + %lu > %lu)", utf8len + sizeof(xapref) - 1, overhead, fcb->adsmaxlen); reap_fcb(fcb); free_fileref(parfileref); return STATUS_DISK_FULL; @@ -2858,7 +2889,7 @@ static NTSTATUS create_stream(_Requires_lock_held_(_Curr_->tree_lock) _Requires_ Status = RtlUpcaseUnicodeString(&dc->name_uc, &dc->name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); ExFreePool(dc->utf8.Buffer); ExFreePool(dc->name.Buffer); ExFreePool(dc); @@ -2948,7 +2979,7 @@ static __inline bool called_from_lxss() { Status = ZwQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), &retlen); if (!NT_SUCCESS(Status)) { - ERR("ZwQueryInformationProcess returned %08x\n", Status); + ERR("ZwQueryInformationProcess returned %08lx\n", Status); return false; } @@ -2975,7 +3006,7 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R LONG oc; #endif - TRACE("(%p, %p, %p, %.*S, %x, %x)\n", Irp, Vcb, FileObject, fnus->Length / sizeof(WCHAR), fnus->Buffer, disposition, options); + TRACE("(%p, %p, %p, %.*S, %lx, %lx)\n", Irp, Vcb, FileObject, (int)(fnus->Length / sizeof(WCHAR)), fnus->Buffer, disposition, options); if (Vcb->readonly) return STATUS_MEDIA_WRITE_PROTECTED; @@ -2997,11 +3028,15 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R if (ctxsize >= sizeof(ATOMIC_CREATE_ECP_CONTEXT)) acec = ctx; else { - ERR("GUID_ECP_ATOMIC_CREATE context was too short: %u bytes, expected %u\n", ctxsize, + ERR("GUID_ECP_ATOMIC_CREATE context was too short: %lu bytes, expected %Iu\n", ctxsize, sizeof(ATOMIC_CREATE_ECP_CONTEXT)); } - } else { - WARN("unhandled ECP {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", type.Data1, type.Data2, + } else if (RtlCompareMemory(&type, &GUID_ECP_QUERY_ON_CREATE, sizeof(GUID)) == sizeof(GUID)) + WARN("unhandled ECP GUID_ECP_QUERY_ON_CREATE\n"); + else if (RtlCompareMemory(&type, &GUID_ECP_CREATE_REDIRECTION, sizeof(GUID)) == sizeof(GUID)) + WARN("unhandled ECP GUID_ECP_CREATE_REDIRECTION\n"); + else { + WARN("unhandled ECP {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", type.Data1, type.Data2, type.Data3, type.Data4[0], type.Data4[1], type.Data4[2], type.Data4[3], type.Data4[4], type.Data4[5], type.Data4[6], type.Data4[7]); } @@ -3058,7 +3093,7 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R lb.Buffer = &fpus.Buffer[(fpus.Length - dsus.Length)/sizeof(WCHAR)]; lb.Length = lb.MaximumLength = dsus.Length; - TRACE("lb = %.*S\n", lb.Length/sizeof(WCHAR), lb.Buffer); + TRACE("lb = %.*S\n", (int)(lb.Length/sizeof(WCHAR)), lb.Buffer); if (FsRtlAreNamesEqual(&dsus, &lb, true, NULL)) { TRACE("ignoring :$DATA suffix\n"); @@ -3068,7 +3103,7 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R if (fpus.Length > sizeof(WCHAR) && fpus.Buffer[(fpus.Length-1)/sizeof(WCHAR)] == ':') fpus.Length -= sizeof(WCHAR); - TRACE("fpus = %.*S\n", fpus.Length / sizeof(WCHAR), fpus.Buffer); + TRACE("fpus = %.*S\n", (int)(fpus.Length / sizeof(WCHAR)), fpus.Buffer); } } @@ -3087,7 +3122,7 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R if (stream.Length > 0) { Status = create_stream(Vcb, &fileref, &parfileref, &fpus, &stream, Irp, options, pool_type, IrpSp->Flags & SL_CASE_SENSITIVE, rollback); if (!NT_SUCCESS(Status)) { - ERR("create_stream returned %08x\n", Status); + ERR("create_stream returned %08lx\n", Status); goto end; } @@ -3118,7 +3153,7 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R Status = IoCheckEaBufferValidity(Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength, &offset); if (!NT_SUCCESS(Status)) { - ERR("IoCheckEaBufferValidity returned %08x (error at offset %u)\n", Status, offset); + ERR("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset); goto end; } } @@ -3130,7 +3165,7 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R *existing_fileref = fileref; goto end; } else if (!NT_SUCCESS(Status)) { - ERR("file_create2 returned %08x\n", Status); + ERR("file_create2 returned %08lx\n", Status); goto end; } @@ -3201,7 +3236,7 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R } else { Status = set_reparse_point2(fileref->fcb, acec->ReparseBuffer, acec->ReparseBufferLength, NULL, NULL, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("set_reparse_point2 returned %08x\n", Status); + ERR("set_reparse_point2 returned %08lx\n", Status); fileref->deleted = true; fileref->fcb->deleted = true; @@ -3219,6 +3254,20 @@ static NTSTATUS file_create(PIRP Irp, _Requires_lock_held_(_Curr_->tree_lock) _R acec->OutFlags |= ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET; } + if (acec && acec->InFlags & ATOMIC_CREATE_ECP_IN_FLAG_OP_FLAGS_SPECIFIED) { + if (acec->InOpFlags & ATOMIC_CREATE_ECP_IN_OP_FLAG_CASE_SENSITIVE_FLAGS_SPECIFIED && fileref->fcb->atts & FILE_ATTRIBUTE_DIRECTORY) { + if ((acec->InCaseSensitiveFlags & acec->CaseSensitiveFlagsMask) & FILE_CS_FLAG_CASE_SENSITIVE_DIR) { + acec->OutCaseSensitiveFlags = FILE_CS_FLAG_CASE_SENSITIVE_DIR; + fileref->fcb->case_sensitive = true; + ccb->case_sensitive = true; + } + + acec->OutOpFlags |= ATOMIC_CREATE_ECP_OUT_OP_FLAG_CASE_SENSITIVE_FLAGS_SET; + } + + acec->OutFlags |= ATOMIC_CREATE_ECP_OUT_FLAG_OP_FLAGS_HONORED; + } + fileref->dc->type = fileref->fcb->type; end: @@ -3350,7 +3399,7 @@ static __inline void debug_create_options(ULONG RequestedOptions) { } if (options) - TRACE(" unknown options: %x\n", options); + TRACE(" unknown options: %lx\n", options); } else { TRACE("requested options: (none)\n"); } @@ -3381,7 +3430,7 @@ static NTSTATUS get_reparse_block(fcb* fcb, uint8_t** data) { Status = read_file(fcb, *data, 0, size, &bytes_read, NULL); if (!NT_SUCCESS(Status)) { - ERR("read_file_fcb returned %08x\n", Status); + ERR("read_file_fcb returned %08lx\n", Status); ExFreePool(*data); return Status; } @@ -3393,7 +3442,7 @@ static NTSTATUS get_reparse_block(fcb* fcb, uint8_t** data) { Status = utf8_to_utf16(NULL, 0, &stringlen, (char*)*data, bytes_read); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); ExFreePool(*data); return Status; } @@ -3424,7 +3473,7 @@ static NTSTATUS get_reparse_block(fcb* fcb, uint8_t** data) { stringlen, &stringlen, (char*)*data, size); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(rdb); ExFreePool(*data); return Status; @@ -3445,7 +3494,7 @@ static NTSTATUS get_reparse_block(fcb* fcb, uint8_t** data) { } else { Status = fFsRtlValidateReparsePointBuffer(bytes_read, (REPARSE_DATA_BUFFER*)*data); if (!NT_SUCCESS(Status)) { - ERR("FsRtlValidateReparsePointBuffer returned %08x\n", Status); + ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status); ExFreePool(*data); return Status; } @@ -3461,7 +3510,7 @@ static NTSTATUS get_reparse_block(fcb* fcb, uint8_t** data) { Status = fFsRtlValidateReparsePointBuffer(fcb->reparse_xattr.Length, (REPARSE_DATA_BUFFER*)fcb->reparse_xattr.Buffer); if (!NT_SUCCESS(Status)) { - ERR("FsRtlValidateReparsePointBuffer returned %08x\n", Status); + ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status); return Status; } @@ -3498,7 +3547,7 @@ static void fcb_load_csums(_Requires_lock_held_(_Curr_->tree_lock) device_extens len = (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->num_bytes : ed2->size) / Vcb->superblock.sector_size; - ext->csum = ExAllocatePoolWithTag(NonPagedPool, (ULONG)(len * sizeof(uint32_t)), ALLOC_TAG); + ext->csum = ExAllocatePoolWithTag(NonPagedPool, (ULONG)(len * Vcb->csum_size), ALLOC_TAG); if (!ext->csum) { ERR("out of memory\n"); goto end; @@ -3507,7 +3556,7 @@ static void fcb_load_csums(_Requires_lock_held_(_Curr_->tree_lock) device_extens Status = load_csum(Vcb, ext->csum, ed2->address + (ext->extent_data.compression == BTRFS_COMPRESSION_NONE ? ed2->offset : 0), len, Irp); if (!NT_SUCCESS(Status)) { - ERR("load_csum returned %08x\n", Status); + ERR("load_csum returned %08lx\n", Status); goto end; } } @@ -3559,7 +3608,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO IoGetFileObjectGenericMapping(), IrpSp->Flags & SL_FORCE_ACCESS_CHECK ? UserMode : Irp->RequestorMode, granted_access, &Status)) { SeUnlockSubjectContext(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext); - TRACE("SeAccessCheck failed, returning %08x\n", Status); + TRACE("SeAccessCheck failed, returning %08lx\n", Status); free_fileref(fileref); @@ -3636,7 +3685,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO Status = get_reparse_block(fileref->fcb, (uint8_t**)&data); if (!NT_SUCCESS(Status)) { - ERR("get_reparse_block returned %08x\n", Status); + ERR("get_reparse_block returned %08lx\n", Status); Status = STATUS_SUCCESS; } else { Irp->IoStatus.Information = data->ReparseTag; @@ -3671,9 +3720,9 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO if (!NT_SUCCESS(Status)) { if (Status == STATUS_SHARING_VIOLATION) - TRACE("IoCheckShareAccess failed, returning %08x\n", Status); + TRACE("IoCheckShareAccess failed, returning %08lx\n", Status); else - WARN("IoCheckShareAccess failed, returning %08x\n", Status); + WARN("IoCheckShareAccess failed, returning %08lx\n", Status); free_fileref(fileref); @@ -3698,7 +3747,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO // FIXME - this can block waiting for network IO, while we're holding fileref_lock and tree_lock Status = FsRtlCheckOplock(fcb_oplock(fileref->fcb), Irp, NULL, NULL, NULL); if (!NT_SUCCESS(Status)) { - WARN("FsRtlCheckOplock returned %08x\n", Status); + WARN("FsRtlCheckOplock returned %08lx\n", Status); free_fileref(fileref); return Status; @@ -3730,7 +3779,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO if (fileref->fcb->ads) { Status = stream_set_end_of_file_information(Vcb, 0, fileref->fcb, fileref, false); if (!NT_SUCCESS(Status)) { - ERR("stream_set_end_of_file_information returned %08x\n", Status); + ERR("stream_set_end_of_file_information returned %08lx\n", Status); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); @@ -3741,7 +3790,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO } else { Status = truncate_file(fileref->fcb, 0, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("truncate_file returned %08x\n", Status); + ERR("truncate_file returned %08lx\n", Status); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); @@ -3755,7 +3804,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO Status = extend_file(fileref->fcb, fileref, Irp->Overlay.AllocationSize.QuadPart, true, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("extend_file returned %08x\n", Status); + ERR("extend_file returned %08lx\n", Status); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); @@ -3774,7 +3823,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO Status = IoCheckEaBufferValidity(Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Create.EaLength, &offset); if (!NT_SUCCESS(Status)) { - ERR("IoCheckEaBufferValidity returned %08x (error at offset %u)\n", Status, offset); + ERR("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset); IoRemoveShareAccess(FileObject, &fileref->fcb->share_access); @@ -3842,7 +3891,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO Status = open_fileref_child(Vcb, fileref, &dc->name, true, true, true, PagedPool, &fr2, NULL); if (!NT_SUCCESS(Status)) - WARN("open_fileref_child returned %08x\n", Status); + WARN("open_fileref_child returned %08lx\n", Status); } if (dc->fileref) { @@ -3850,7 +3899,7 @@ static NTSTATUS open_file2(device_extension* Vcb, ULONG RequestedDisposition, PO Status = delete_fileref(dc->fileref, NULL, false, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref returned %08x\n", Status); + ERR("delete_fileref returned %08lx\n", Status); free_fileref(fileref); @@ -4027,7 +4076,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = open_fcb(Vcb, subvol, inode, 0, NULL, true, NULL, &fcb, PagedPool, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fcb returned %08x\n", Status); + ERR("open_fcb returned %08lx\n", Status); return Status; } @@ -4081,7 +4130,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = find_item(Vcb, subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); free_fcb(fcb); return Status; } @@ -4111,7 +4160,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = utf8_to_utf16(NULL, 0, &stringlen, ir->name, ir->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); free_fcb(fcb); return Status; } @@ -4131,7 +4180,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = utf8_to_utf16(name.Buffer, stringlen, &stringlen, ir->name, ir->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(name.Buffer); free_fcb(fcb); return Status; @@ -4161,7 +4210,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = utf8_to_utf16(NULL, 0, &stringlen, ier->name, ier->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); free_fcb(fcb); return Status; } @@ -4181,7 +4230,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = utf8_to_utf16(name.Buffer, stringlen, &stringlen, ier->name, ier->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(name.Buffer); free_fcb(fcb); return Status; @@ -4227,7 +4276,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); free_fcb(fcb); return Status; } @@ -4239,13 +4288,13 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) ULONG stringlen; if (tp.item->size < sizeof(ROOT_REF)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(ROOT_REF)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(ROOT_REF)); free_fcb(fcb); return STATUS_INTERNAL_ERROR; } if (tp.item->size < offsetof(ROOT_REF, name[0]) + rr->n) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(ROOT_REF, name[0]) + rr->n); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(ROOT_REF, name[0]) + rr->n); free_fcb(fcb); return STATUS_INTERNAL_ERROR; } @@ -4270,14 +4319,14 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = open_fileref_by_inode(Vcb, r, rr->dir, &parfr, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref_by_inode returned %08x\n", Status); + ERR("open_fileref_by_inode returned %08lx\n", Status); free_fcb(fcb); return Status; } Status = utf8_to_utf16(NULL, 0, &stringlen, rr->name, rr->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); free_fcb(fcb); return Status; } @@ -4300,7 +4349,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) Status = utf8_to_utf16(name.Buffer, stringlen, &stringlen, rr->name, rr->n); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(name.Buffer); free_fcb(fcb); return Status; @@ -4312,7 +4361,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) if (!Vcb->options.no_root_dir && subvol->id == BTRFS_ROOT_FSTREE && Vcb->root_fileref->fcb->subvol != subvol) { Status = open_fileref_by_inode(Vcb, Vcb->root_fileref->fcb->subvol, SUBVOL_ROOT_INODE, &parfr, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref_by_inode returned %08x\n", Status); + ERR("open_fileref_by_inode returned %08lx\n", Status); free_fcb(fcb); return Status; } @@ -4328,7 +4377,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) } else { Status = open_fileref_by_inode(Vcb, subvol, parent, &parfr, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref_by_inode returned %08x\n", Status); + ERR("open_fileref_by_inode returned %08lx\n", Status); free_fcb(fcb); return Status; } @@ -4340,7 +4389,7 @@ NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) ExFreePool(name.Buffer); if (!NT_SUCCESS(Status)) { - ERR("open_fileref_child returned %08x\n", Status); + ERR("open_fileref_child returned %08lx\n", Status); free_fcb(fcb); free_fileref(parfr); @@ -4422,14 +4471,14 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur break; default: - ERR("unknown disposition: %x\n", RequestedDisposition); + ERR("unknown disposition: %lx\n", RequestedDisposition); Status = STATUS_NOT_IMPLEMENTED; goto exit; } fn = FileObject->FileName; - TRACE("(%.*S)\n", fn.Length / sizeof(WCHAR), fn.Buffer); + TRACE("(%.*S)\n", (int)(fn.Length / sizeof(WCHAR)), fn.Buffer); TRACE("FileObject = %p\n", FileObject); if (Vcb->readonly && (RequestedDisposition == FILE_SUPERSEDE || RequestedDisposition == FILE_CREATE || RequestedDisposition == FILE_OVERWRITE)) { @@ -4453,7 +4502,7 @@ static NTSTATUS open_file(PDEVICE_OBJECT DeviceObject, _Requires_lock_held_(_Cur goto exit; } - RtlCopyMemory(&inode, fn.Buffer, sizeof(uint64_t)); + inode = (*(uint64_t*)fn.Buffer) & 0xffffffffff; if (related->fcb == Vcb->root_fileref->fcb && inode == 0) inode = Vcb->root_fileref->fcb->inode; @@ -4548,7 +4597,7 @@ loaded: ExReleaseResourceLite(fileref->fcb->Header.Resource); if (!NT_SUCCESS(Status)) { - ERR("get_reparse_block returned %08x\n", Status); + ERR("get_reparse_block returned %08lx\n", Status); Status = STATUS_SUCCESS; } else { @@ -4583,10 +4632,10 @@ loaded: goto exit; } } else if (Status == STATUS_OBJECT_PATH_NOT_FOUND) { - TRACE("open_fileref returned %08x\n", Status); + TRACE("open_fileref returned %08lx\n", Status); goto exit; } else { - ERR("open_fileref returned %08x\n", Status); + ERR("open_fileref returned %08lx\n", Status); goto exit; } @@ -4639,7 +4688,7 @@ exit: fcb_load_csums(Vcb, fcb2, Irp); ExReleaseResourceLite(fcb2->Header.Resource); } else if (Status != STATUS_REPARSE && Status != STATUS_OBJECT_NAME_NOT_FOUND && Status != STATUS_OBJECT_PATH_NOT_FOUND) - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); return Status; } @@ -4662,10 +4711,10 @@ static NTSTATUS verify_vcb(device_extension* Vcb, PIRP Irp) { Status = dev_ioctl(dev->devobj, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, &cc, sizeof(ULONG), true, &iosb); if (IoIsErrorUserInduced(Status)) { - ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08x (user-induced)\n", Status); + ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08lx (user-induced)\n", Status); need_verify = true; } else if (!NT_SUCCESS(Status)) { - ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08x\n", Status); + ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08lx\n", Status); goto end; } else if (iosb.Information < sizeof(ULONG)) { ERR("iosb.Information was too short\n"); @@ -4727,7 +4776,7 @@ NTSTATUS __stdcall drv_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { FsRtlEnterFileSystem(); - TRACE("create (flags = %x)\n", Irp->Flags); + TRACE("create (flags = %lx)\n", Irp->Flags); top_level = is_top_level(Irp); @@ -4759,7 +4808,7 @@ NTSTATUS __stdcall drv_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { Status = verify_vcb(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("verify_vcb returned %08x\n", Status); + ERR("verify_vcb returned %08lx\n", Status); goto exit; } @@ -4884,7 +4933,7 @@ NTSTATUS __stdcall drv_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { InitializeListHead(&rollback); - TRACE("file name: %.*S\n", IrpSp->FileObject->FileName.Length / sizeof(WCHAR), IrpSp->FileObject->FileName.Buffer); + TRACE("file name: %.*S\n", (int)(IrpSp->FileObject->FileName.Length / sizeof(WCHAR)), IrpSp->FileObject->FileName.Buffer); if (IrpSp->FileObject->RelatedFileObject) TRACE("related file = %p\n", IrpSp->FileObject->RelatedFileObject); @@ -4914,7 +4963,7 @@ exit: Irp->IoStatus.Status = Status; IoCompleteRequest( Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT ); - TRACE("create returning %08x\n", Status); + TRACE("create returning %08lx\n", Status); if (locked) ExReleaseResourceLite(&Vcb->load_lock); diff --git a/drivers/filesystems/btrfs/devctrl.c b/drivers/filesystems/btrfs/devctrl.c index e3c69c97124..4c729ec4c8e 100644 --- a/drivers/filesystems/btrfs/devctrl.c +++ b/drivers/filesystems/btrfs/devctrl.c @@ -119,7 +119,7 @@ static NTSTATUS query_filesystems(void* data, ULONG length) { Status = dev_ioctl(dev->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &mdn, sizeof(MOUNTDEV_NAME), true, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { ExReleaseResourceLite(&Vcb->tree_lock); - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); goto end; } @@ -132,7 +132,7 @@ static NTSTATUS query_filesystems(void* data, ULONG length) { Status = dev_ioctl(dev->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &bfd->name_length, (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength, true, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { ExReleaseResourceLite(&Vcb->tree_lock); - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); goto end; } @@ -173,7 +173,7 @@ static NTSTATUS probe_volume(void* data, ULONG length, KPROCESSOR_MODE processor if (length < offsetof(MOUNTDEV_NAME, Name[0]) + mdn->NameLength) return STATUS_INVALID_PARAMETER; - TRACE("%.*S\n", mdn->NameLength / sizeof(WCHAR), mdn->Name); + TRACE("%.*S\n", (int)(mdn->NameLength / sizeof(WCHAR)), mdn->Name); if (!SeSinglePrivilegeCheck(RtlConvertLongToLuid(SE_MANAGE_VOLUME_PRIVILEGE), processor_mode)) return STATUS_PRIVILEGE_NOT_HELD; @@ -183,13 +183,13 @@ static NTSTATUS probe_volume(void* data, ULONG length, KPROCESSOR_MODE processor Status = IoGetDeviceObjectPointer(&path, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if (!NT_SUCCESS(Status)) { - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); return Status; } Status = get_device_pnp_name(DeviceObject, &pnp_name, &guid); if (!NT_SUCCESS(Status)) { - ERR("get_device_pnp_name returned %08x\n", Status); + ERR("get_device_pnp_name returned %08lx\n", Status); ObDereferenceObject(FileObject); return Status; } @@ -197,7 +197,7 @@ static NTSTATUS probe_volume(void* data, ULONG length, KPROCESSOR_MODE processor if (RtlCompareMemory(guid, &GUID_DEVINTERFACE_DISK, sizeof(GUID)) == sizeof(GUID)) { Status = dev_ioctl(DeviceObject, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, NULL, 0, true, NULL); if (!NT_SUCCESS(Status)) - WARN("IOCTL_DISK_UPDATE_PROPERTIES returned %08x\n", Status); + WARN("IOCTL_DISK_UPDATE_PROPERTIES returned %08lx\n", Status); } ObDereferenceObject(FileObject); @@ -241,7 +241,7 @@ static NTSTATUS control_ioctl(PIRP Irp) { break; default: - TRACE("unhandled ioctl %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); + TRACE("unhandled ioctl %lx\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); Status = STATUS_NOT_IMPLEMENTED; break; } @@ -279,11 +279,6 @@ NTSTATUS __stdcall drv_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Ir goto end; } - if (!IrpSp->FileObject || IrpSp->FileObject->FsContext != Vcb->volume_fcb) { - Status = STATUS_INVALID_PARAMETER; - goto end; - } - switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_MOUNTDEV_QUERY_STABLE_GUID: Status = mountdev_query_stable_guid(Vcb, Irp); @@ -294,7 +289,7 @@ NTSTATUS __stdcall drv_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Ir goto end; default: - TRACE("unhandled control code %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); + TRACE("unhandled control code %lx\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); break; } @@ -311,7 +306,7 @@ end: IoCompleteRequest(Irp, IO_NO_INCREMENT); end2: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); if (top_level) IoSetTopLevelIrp(NULL); diff --git a/drivers/filesystems/btrfs/dirctrl.c b/drivers/filesystems/btrfs/dirctrl.c index e6e96fe5fa0..2d0a5fdb351 100644 --- a/drivers/filesystems/btrfs/dirctrl.c +++ b/drivers/filesystems/btrfs/dirctrl.c @@ -16,6 +16,7 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "crc32c.h" #ifndef __REACTOS__ // not currently in mingw @@ -63,7 +64,7 @@ typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION { #else #define FileIdExtdDirectoryInformation (enum _FILE_INFORMATION_CLASS)60 #define FileIdExtdBothDirectoryInformation (enum _FILE_INFORMATION_CLASS)63 -#endif +#endif // __REACTOS__ enum DirEntryType { DirEntryType_File, @@ -95,7 +96,7 @@ ULONG get_reparse_tag_fcb(fcb* fcb) { Status = read_file(fcb, (uint8_t*)&tag, 0, sizeof(ULONG), &br, NULL); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); return 0; } } @@ -112,13 +113,13 @@ ULONG get_reparse_tag(device_extension* Vcb, root* subvol, uint64_t inode, uint8 return IO_REPARSE_TAG_SYMLINK; else if (lxss) { if (type == BTRFS_TYPE_SOCKET) - return IO_REPARSE_TAG_LXSS_SOCKET; + return IO_REPARSE_TAG_AF_UNIX; else if (type == BTRFS_TYPE_FIFO) - return IO_REPARSE_TAG_LXSS_FIFO; + return IO_REPARSE_TAG_LX_FIFO; else if (type == BTRFS_TYPE_CHARDEV) - return IO_REPARSE_TAG_LXSS_CHARDEV; + return IO_REPARSE_TAG_LX_CHR; else if (type == BTRFS_TYPE_BLOCKDEV) - return IO_REPARSE_TAG_LXSS_BLOCKDEV; + return IO_REPARSE_TAG_LX_BLK; } if (type != BTRFS_TYPE_FILE && type != BTRFS_TYPE_DIRECTORY) @@ -129,7 +130,7 @@ ULONG get_reparse_tag(device_extension* Vcb, root* subvol, uint64_t inode, uint8 Status = open_fcb(Vcb, subvol, inode, type, NULL, false, NULL, &fcb, PagedPool, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fcb returned %08x\n", Status); + ERR("open_fcb returned %08lx\n", Status); return 0; } @@ -155,7 +156,7 @@ static ULONG get_ea_len(device_extension* Vcb, root* subvol, uint64_t inode, PIR Status = IoCheckEaBufferValidity((FILE_FULL_EA_INFORMATION*)eadata, len, &offset); if (!NT_SUCCESS(Status)) { - WARN("IoCheckEaBufferValidity returned %08x (error at offset %u)\n", Status, offset); + WARN("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset); ExFreePool(eadata); return 0; } else { @@ -251,7 +252,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir Status = find_item(fcb->Vcb, r, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -328,7 +329,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir needed = sizeof(FILE_BOTH_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length; if (needed > *len) { - TRACE("buffer overflow - %u > %u\n", needed, *len); + TRACE("buffer overflow - %li > %lu\n", needed, *len); return STATUS_BUFFER_OVERFLOW; } @@ -368,7 +369,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir needed = sizeof(FILE_DIRECTORY_INFORMATION) - sizeof(WCHAR) + de->name.Length; if (needed > *len) { - TRACE("buffer overflow - %u > %u\n", needed, *len); + TRACE("buffer overflow - %li > %lu\n", needed, *len); return STATUS_BUFFER_OVERFLOW; } @@ -406,7 +407,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir needed = sizeof(FILE_FULL_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length; if (needed > *len) { - TRACE("buffer overflow - %u > %u\n", needed, *len); + TRACE("buffer overflow - %li > %lu\n", needed, *len); return STATUS_BUFFER_OVERFLOW; } @@ -445,7 +446,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir needed = sizeof(FILE_ID_BOTH_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length; if (needed > *len) { - TRACE("buffer overflow - %u > %u\n", needed, *len); + TRACE("buffer overflow - %li > %lu\n", needed, *len); return STATUS_BUFFER_OVERFLOW; } @@ -486,7 +487,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir needed = sizeof(FILE_ID_FULL_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length; if (needed > *len) { - TRACE("buffer overflow - %u > %u\n", needed, *len); + TRACE("buffer overflow - %li > %lu\n", needed, *len); return STATUS_BUFFER_OVERFLOW; } @@ -531,7 +532,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir needed = offsetof(FILE_ID_EXTD_DIR_INFORMATION, FileName[0]) + de->name.Length; if (needed > *len) { - TRACE("buffer overflow - %u > %u\n", needed, *len); + TRACE("buffer overflow - %li > %lu\n", needed, *len); return STATUS_BUFFER_OVERFLOW; } @@ -574,7 +575,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir needed = offsetof(FILE_ID_EXTD_BOTH_DIR_INFORMATION, FileName[0]) + de->name.Length; if (needed > *len) { - TRACE("buffer overflow - %u > %u\n", needed, *len); + TRACE("buffer overflow - %li > %lu\n", needed, *len); return STATUS_BUFFER_OVERFLOW; } @@ -624,7 +625,7 @@ static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Ir needed = sizeof(FILE_NAMES_INFORMATION) - sizeof(WCHAR) + de->name.Length; if (needed > *len) { - TRACE("buffer overflow - %u > %u\n", needed, *len); + TRACE("buffer overflow - %li > %lu\n", needed, *len); return STATUS_BUFFER_OVERFLOW; } @@ -812,7 +813,7 @@ static NTSTATUS query_directory(PIRP Irp) { } if (flags != 0) - TRACE(" unknown flags: %u\n", flags); + TRACE(" unknown flags: %lu\n", flags); } if (IrpSp->Flags & SL_RESTART_SCAN) { @@ -830,7 +831,7 @@ static NTSTATUS query_directory(PIRP Irp) { initial = !ccb->query_string.Buffer; if (IrpSp->Parameters.QueryDirectory.FileName && IrpSp->Parameters.QueryDirectory.FileName->Length > 1) { - TRACE("QD filename: %.*S\n", IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR), IrpSp->Parameters.QueryDirectory.FileName->Buffer); + TRACE("QD filename: %.*S\n", (int)(IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR)), IrpSp->Parameters.QueryDirectory.FileName->Buffer); if (IrpSp->Parameters.QueryDirectory.FileName->Length > sizeof(WCHAR) || IrpSp->Parameters.QueryDirectory.FileName->Buffer[0] != L'*') { specific_file = true; @@ -872,7 +873,7 @@ static NTSTATUS query_directory(PIRP Irp) { } if (ccb->query_string.Buffer) { - TRACE("query string = %.*S\n", ccb->query_string.Length / sizeof(WCHAR), ccb->query_string.Buffer); + TRACE("query string = %.*S\n", (int)(ccb->query_string.Length / sizeof(WCHAR)), ccb->query_string.Buffer); } newoffset = ccb->query_dir_offset; @@ -913,7 +914,7 @@ static NTSTATUS query_directory(PIRP Irp) { if (!ccb->case_sensitive) { Status = RtlUpcaseUnicodeString(&us, &ccb->query_string, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); goto end; } @@ -996,8 +997,8 @@ static NTSTATUS query_directory(PIRP Irp) { } } - TRACE("file(0) = %.*S\n", de.name.Length / sizeof(WCHAR), de.name.Buffer); - TRACE("offset = %u\n", ccb->query_dir_offset - 1); + TRACE("file(0) = %.*S\n", (int)(de.name.Length / sizeof(WCHAR)), de.name.Buffer); + TRACE("offset = %I64u\n", ccb->query_dir_offset - 1); Status = query_dir_item(fcb, ccb, buf, &length, Irp, &de, fcb->subvol); @@ -1041,8 +1042,8 @@ static NTSTATUS query_directory(PIRP Irp) { curitem = (uint8_t*)buf + IrpSp->Parameters.QueryDirectory.Length - length; count++; - TRACE("file(%u) %u = %.*S\n", count, curitem - (uint8_t*)buf, de.name.Length / sizeof(WCHAR), de.name.Buffer); - TRACE("offset = %u\n", ccb->query_dir_offset - 1); + TRACE("file(%lu) %Iu = %.*S\n", count, curitem - (uint8_t*)buf, (int)(de.name.Length / sizeof(WCHAR)), de.name.Buffer); + TRACE("offset = %I64u\n", ccb->query_dir_offset - 1); status2 = query_dir_item(fcb, ccb, curitem, &length, Irp, &de, fcb->subvol); @@ -1075,7 +1076,7 @@ end: ExReleaseResourceLite(&Vcb->tree_lock); - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); return Status; } @@ -1135,11 +1136,11 @@ static NTSTATUS notify_change_directory(device_extension* Vcb, PIRP Irp) { Status = fileref_get_filename(fileref, &ccb->filename, NULL, &reqlen); if (!NT_SUCCESS(Status)) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); goto end; } } else { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); goto end; } } @@ -1196,7 +1197,7 @@ NTSTATUS __stdcall drv_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP break; default: - WARN("unknown minor %u\n", func); + WARN("unknown minor %lu\n", func); Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = Status; break; @@ -1211,7 +1212,7 @@ end: IoCompleteRequest(Irp, IO_DISK_INCREMENT); exit: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); if (top_level) IoSetTopLevelIrp(NULL); diff --git a/drivers/filesystems/btrfs/extent-tree.c b/drivers/filesystems/btrfs/extent-tree.c index 0c804caef67..1e03af7bdbc 100644 --- a/drivers/filesystems/btrfs/extent-tree.c +++ b/drivers/filesystems/btrfs/extent-tree.c @@ -16,6 +16,7 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "crc32c.h" typedef struct { uint8_t type; @@ -314,7 +315,7 @@ static NTSTATUS construct_extent_item(device_extension* Vcb, uint64_t address, u Status = insert_tree_item(Vcb, Vcb->extent_root, address, TYPE_EXTENT_ITEM, size, ei, inline_len, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ei); return Status; } @@ -356,7 +357,7 @@ static NTSTATUS construct_extent_item(device_extension* Vcb, uint64_t address, u Status = insert_tree_item(Vcb, Vcb->extent_root, address, er->type, er->hash, data, len, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); if (data) ExFreePool(data); return Status; } @@ -383,7 +384,7 @@ static NTSTATUS convert_old_extent(device_extension* Vcb, uint64_t address, bool Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -396,7 +397,7 @@ static NTSTATUS convert_old_extent(device_extension* Vcb, uint64_t address, bool Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -410,27 +411,27 @@ static NTSTATUS convert_old_extent(device_extension* Vcb, uint64_t address, bool if (tp.item->key.offset == tp.item->key.obj_id) { // top of the tree Status = add_tree_block_extent_ref(&extent_refs, erv0->root); if (!NT_SUCCESS(Status)) { - ERR("add_tree_block_extent_ref returned %08x\n", Status); + ERR("add_tree_block_extent_ref returned %08lx\n", Status); goto end; } } else { Status = add_shared_block_extent_ref(&extent_refs, tp.item->key.offset); if (!NT_SUCCESS(Status)) { - ERR("add_shared_block_extent_ref returned %08x\n", Status); + ERR("add_shared_block_extent_ref returned %08lx\n", Status); goto end; } } } else { Status = add_shared_data_extent_ref(&extent_refs, tp.item->key.offset, erv0->count); if (!NT_SUCCESS(Status)) { - ERR("add_shared_data_extent_ref returned %08x\n", Status); + ERR("add_shared_data_extent_ref returned %08lx\n", Status); goto end; } } Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); goto end; } } @@ -442,7 +443,7 @@ static NTSTATUS convert_old_extent(device_extension* Vcb, uint64_t address, bool Status = construct_extent_item(Vcb, address, size, tree ? (EXTENT_ITEM_TREE_BLOCK | EXTENT_ITEM_SHARED_BACKREFS) : EXTENT_ITEM_DATA, &extent_refs, firstitem, level, Irp); if (!NT_SUCCESS(Status)) - ERR("construct_extent_item returned %08x\n", Status); + ERR("construct_extent_item returned %08lx\n", Status); end: free_extent_refs(&extent_refs); @@ -475,7 +476,7 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -516,7 +517,7 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = insert_tree_item(Vcb, Vcb->extent_root, address, TYPE_EXTENT_ITEM, size, ei, eisize, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -532,7 +533,7 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = convert_old_extent(Vcb, address, is_tree, firstitem, level, Irp); if (!NT_SUCCESS(Status)) { - ERR("convert_old_extent returned %08x\n", Status); + ERR("convert_old_extent returned %08lx\n", Status); return Status; } @@ -540,7 +541,7 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 } if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -551,7 +552,7 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->flags & EXTENT_ITEM_TREE_BLOCK && !skinny) { if (tp.item->size < sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); return STATUS_INTERNAL_ERROR; } @@ -571,7 +572,7 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 len--; if (sectlen > len) { - ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); + ERR("(%I64x,%x,%I64x): %lx bytes left, expecting at least %lx\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); return STATUS_INTERNAL_ERROR; } @@ -606,13 +607,13 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -655,13 +656,13 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -729,13 +730,13 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size + sizeof(uint8_t) + datalen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -753,13 +754,13 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = find_item(Vcb, Vcb->extent_root, &tp2, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } if (!keycmp(tp2.item->key, searchkey)) { if (type == TYPE_SHARED_DATA_REF && tp2.item->size < sizeof(uint32_t)) { - ERR("(%I64x,%x,%I64x) was %x bytes, expecting %x\n", tp2.item->key.obj_id, tp2.item->key.obj_type, tp2.item->key.offset, tp2.item->size, sizeof(uint32_t)); + ERR("(%I64x,%x,%I64x) was %x bytes, expecting %Ix\n", tp2.item->key.obj_id, tp2.item->key.obj_type, tp2.item->key.offset, tp2.item->size, sizeof(uint32_t)); return STATUS_INTERNAL_ERROR; } else if (type != TYPE_SHARED_DATA_REF && tp2.item->size < datalen) { ERR("(%I64x,%x,%I64x) was %x bytes, expecting %x\n", tp2.item->key.obj_id, tp2.item->key.obj_type, tp2.item->key.offset, tp2.item->size, datalen); @@ -794,13 +795,13 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp2.item->key.obj_id, tp2.item->key.obj_type, tp2.item->key.offset, data2, tp2.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -816,13 +817,13 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -859,7 +860,7 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = insert_tree_item(Vcb, Vcb->extent_root, address, type, offset, data2, datalen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -875,13 +876,13 @@ NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -919,7 +920,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -934,7 +935,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -952,7 +953,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = convert_old_extent(Vcb, address, is_tree, firstitem, level, Irp); if (!NT_SUCCESS(Status)) { - ERR("convert_old_extent returned %08x\n", Status); + ERR("convert_old_extent returned %08lx\n", Status); return Status; } @@ -961,7 +962,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 } if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -972,7 +973,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->flags & EXTENT_ITEM_TREE_BLOCK && !skinny) { if (tp.item->size < sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); return STATUS_INTERNAL_ERROR; } @@ -997,7 +998,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 len--; if (sectlen > len) { - ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); + ERR("(%I64x,%x,%I64x): %lx bytes left, expecting at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); return STATUS_INTERNAL_ERROR; } @@ -1018,7 +1019,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->refcount == edr->count) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1061,13 +1062,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, neweilen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1084,7 +1085,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->refcount == sectsdr->count) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1127,13 +1128,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, neweilen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1150,7 +1151,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->refcount == 1) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1174,13 +1175,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, neweilen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1197,7 +1198,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->refcount == 1) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1221,13 +1222,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, neweilen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1260,7 +1261,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = find_item(Vcb, Vcb->extent_root, &tp2, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -1270,7 +1271,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 } if (tp2.item->size < datalen) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp2.item->key.obj_id, tp2.item->key.obj_type, tp2.item->key.offset, tp2.item->size, datalen); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %lu\n", tp2.item->key.obj_id, tp2.item->key.obj_type, tp2.item->key.offset, tp2.item->size, datalen); return STATUS_INTERNAL_ERROR; } @@ -1284,13 +1285,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->refcount == edr->count) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1307,7 +1308,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1325,7 +1326,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = insert_tree_item(Vcb, Vcb->extent_root, tp2.item->key.obj_id, tp2.item->key.obj_type, tp2.item->key.offset, newedr, tp2.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } } @@ -1342,13 +1343,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1367,13 +1368,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->refcount == sdr->count) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1390,7 +1391,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1406,7 +1407,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = insert_tree_item(Vcb, Vcb->extent_root, tp2.item->key.obj_id, tp2.item->key.obj_type, tp2.item->key.offset, newsdr, tp2.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } } @@ -1423,13 +1424,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1444,13 +1445,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->refcount == 1) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1459,7 +1460,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1475,13 +1476,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1493,13 +1494,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 if (ei->refcount == erv0->count) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1511,7 +1512,7 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp2); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -1527,13 +1528,13 @@ NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint6 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newei, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } @@ -1576,7 +1577,7 @@ static uint32_t find_extent_data_refcount(device_extension* Vcb, uint64_t addres Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return 0; } @@ -1603,7 +1604,7 @@ static uint32_t find_extent_data_refcount(device_extension* Vcb, uint64_t addres len--; if (sectlen > len) { - ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); + ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %lx\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); return 0; } @@ -1630,13 +1631,13 @@ static uint32_t find_extent_data_refcount(device_extension* Vcb, uint64_t addres Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return 0; } if (!keycmp(searchkey, tp.item->key)) { if (tp.item->size < sizeof(EXTENT_DATA_REF)) - ERR("(%I64x,%x,%I64x) has size %u, not %u as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA_REF)); + ERR("(%I64x,%x,%I64x) has size %u, not %Iu as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA_REF)); else { EXTENT_DATA_REF* edr = (EXTENT_DATA_REF*)tp.item->data; @@ -1659,7 +1660,7 @@ uint64_t get_extent_refcount(device_extension* Vcb, uint64_t address, uint64_t s Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return 0; } @@ -1683,8 +1684,8 @@ uint64_t get_extent_refcount(device_extension* Vcb, uint64_t address, uint64_t s return eiv0->refcount; } else if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %x bytes, expected at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, - tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %x bytes, expected at least %Ix\n", tp.item->key.obj_id, tp.item->key.obj_type, + tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return 0; } @@ -1717,7 +1718,7 @@ bool is_extent_unique(device_extension* Vcb, uint64_t address, uint64_t size, PI Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - WARN("error - find_item returned %08x\n", Status); + WARN("error - find_item returned %08lx\n", Status); return false; } @@ -1730,7 +1731,7 @@ bool is_extent_unique(device_extension* Vcb, uint64_t address, uint64_t size, PI return false; if (tp.item->size < sizeof(EXTENT_ITEM)) { - WARN("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + WARN("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return false; } @@ -1741,7 +1742,7 @@ bool is_extent_unique(device_extension* Vcb, uint64_t address, uint64_t size, PI if (ei->flags & EXTENT_ITEM_TREE_BLOCK) { if (tp.item->size < sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)) { - WARN("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); + WARN("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); return false; } @@ -1761,7 +1762,7 @@ bool is_extent_unique(device_extension* Vcb, uint64_t address, uint64_t size, PI len--; if (sectlen > len) { - WARN("(%I64x,%x,%I64x): %x bytes left, expecting at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); + WARN("(%I64x,%x,%I64x): %x bytes left, expecting at least %lx\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); return false; } @@ -1799,7 +1800,7 @@ bool is_extent_unique(device_extension* Vcb, uint64_t address, uint64_t size, PI EXTENT_DATA_REF* edr = (EXTENT_DATA_REF*)tp.item->data; if (tp.item->size < sizeof(EXTENT_DATA_REF)) { - WARN("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + WARN("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); return false; } @@ -1843,7 +1844,7 @@ uint64_t get_extent_flags(device_extension* Vcb, uint64_t address, PIRP Irp) { Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return 0; } @@ -1862,8 +1863,8 @@ uint64_t get_extent_flags(device_extension* Vcb, uint64_t address, PIRP Irp) { if (tp.item->size == sizeof(EXTENT_ITEM_V0)) return 0; else if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %x bytes, expected at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, - tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %x bytes, expected at least %Ix\n", tp.item->key.obj_id, tp.item->key.obj_type, + tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return 0; } @@ -1884,7 +1885,7 @@ void update_extent_flags(device_extension* Vcb, uint64_t address, uint64_t flags Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return; } @@ -1903,8 +1904,8 @@ void update_extent_flags(device_extension* Vcb, uint64_t address, uint64_t flags if (tp.item->size == sizeof(EXTENT_ITEM_V0)) return; else if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %x bytes, expected at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, - tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %x bytes, expected at least %Ix\n", tp.item->key.obj_id, tp.item->key.obj_type, + tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return; } @@ -1974,7 +1975,7 @@ NTSTATUS update_changed_extent_ref(device_extension* Vcb, chunk* c, uint64_t add Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -1999,7 +2000,7 @@ NTSTATUS update_changed_extent_ref(device_extension* Vcb, chunk* c, uint64_t add ce->count = ce->old_count = ei->refcount; } else { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); Status = STATUS_INTERNAL_ERROR; goto end; } @@ -2130,7 +2131,7 @@ uint64_t find_extent_shared_tree_refcount(device_extension* Vcb, uint64_t addres Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return 0; } @@ -2140,12 +2141,12 @@ uint64_t find_extent_shared_tree_refcount(device_extension* Vcb, uint64_t addres } if (tp.item->key.obj_type == TYPE_EXTENT_ITEM && tp.item->key.offset != Vcb->superblock.node_size) { - ERR("extent %I64x had size %I64x, not %I64x as expected\n", address, tp.item->key.offset, Vcb->superblock.node_size); + ERR("extent %I64x had size %I64x, not %x as expected\n", address, tp.item->key.offset, Vcb->superblock.node_size); return 0; } if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x): size was %u, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x): size was %u, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return 0; } @@ -2157,8 +2158,8 @@ uint64_t find_extent_shared_tree_refcount(device_extension* Vcb, uint64_t addres if (searchkey.obj_type == TYPE_EXTENT_ITEM && ei->flags & EXTENT_ITEM_TREE_BLOCK) { if (tp.item->size < sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)) { - ERR("(%I64x,%x,%I64x): size was %u, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, - tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); + ERR("(%I64x,%x,%I64x): size was %u, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); return 0; } @@ -2174,7 +2175,7 @@ uint64_t find_extent_shared_tree_refcount(device_extension* Vcb, uint64_t addres len--; if (sectlen > len) { - ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); + ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %lx\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); return 0; } @@ -2206,7 +2207,7 @@ uint64_t find_extent_shared_tree_refcount(device_extension* Vcb, uint64_t addres Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return 0; } @@ -2231,7 +2232,7 @@ uint32_t find_extent_shared_data_refcount(device_extension* Vcb, uint64_t addres Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return 0; } @@ -2241,7 +2242,7 @@ uint32_t find_extent_shared_data_refcount(device_extension* Vcb, uint64_t addres } if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x): size was %u, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x): size was %u, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return 0; } @@ -2259,7 +2260,7 @@ uint32_t find_extent_shared_data_refcount(device_extension* Vcb, uint64_t addres len--; if (sectlen > len) { - ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); + ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %lx\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); return 0; } @@ -2291,13 +2292,13 @@ uint32_t find_extent_shared_data_refcount(device_extension* Vcb, uint64_t addres Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return 0; } if (!keycmp(searchkey, tp.item->key)) { if (tp.item->size < sizeof(uint32_t)) - ERR("(%I64x,%x,%I64x) has size %u, not %u as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(uint32_t)); + ERR("(%I64x,%x,%I64x) has size %u, not %Iu as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(uint32_t)); else { uint32_t* count = (uint32_t*)tp.item->data; return *count; diff --git a/drivers/filesystems/btrfs/fastio.c b/drivers/filesystems/btrfs/fastio.c index 5c2b8aaaf8b..465e191dfa6 100644 --- a/drivers/filesystems/btrfs/fastio.c +++ b/drivers/filesystems/btrfs/fastio.c @@ -372,7 +372,7 @@ static BOOLEAN __stdcall fast_io_lock(PFILE_OBJECT FileObject, PLARGE_INTEGER Fi BOOLEAN ret; fcb* fcb = FileObject->FsContext; - TRACE("(%p, %I64x, %I64x, %p, %x, %u, %u, %p, %p)\n", FileObject, FileOffset ? FileOffset->QuadPart : 0, Length ? Length->QuadPart : 0, + 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); if (fcb->type != BTRFS_TYPE_FILE) { @@ -402,7 +402,7 @@ 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; - TRACE("(%p, %I64x, %I64x, %p, %x, %p, %p)\n", FileObject, FileOffset ? FileOffset->QuadPart : 0, Length ? Length->QuadPart : 0, + TRACE("(%p, %I64x, %I64x, %p, %lx, %p, %p)\n", FileObject, FileOffset ? FileOffset->QuadPart : 0, Length ? Length->QuadPart : 0, ProcessId, Key, IoStatus, DeviceObject); IoStatus->Information = 0; @@ -458,7 +458,7 @@ static BOOLEAN __stdcall fast_io_unlock_all_by_key(PFILE_OBJECT FileObject, PVOI PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { fcb* fcb = FileObject->FsContext; - TRACE("(%p, %p, %x, %p, %p)\n", FileObject, ProcessId, Key, IoStatus, 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 206a5529deb..70ce2061c81 100644 --- a/drivers/filesystems/btrfs/fileinfo.c +++ b/drivers/filesystems/btrfs/fileinfo.c @@ -16,6 +16,7 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "crc32c.h" #if (NTDDI_VERSION >= NTDDI_WIN10) // not currently in mingw - introduced with Windows 10 @@ -28,6 +29,7 @@ #define FileStatLxInformation (enum _FILE_INFORMATION_CLASS)70 #define FileCaseSensitiveInformation (enum _FILE_INFORMATION_CLASS)71 #define FileLinkInformationEx (enum _FILE_INFORMATION_CLASS)72 +#define FileStorageReserveIdInformation (enum _FILE_INFORMATION_CLASS)74 typedef struct _FILE_ID_INFORMATION { ULONGLONG VolumeSerialNumber; @@ -139,8 +141,6 @@ typedef struct _FILE_LINKS_FULL_ID_INFORMATION { #define FILE_LINK_FORCE_RESIZE_TARGET_SR 0x080 #define FILE_LINK_FORCE_RESIZE_SOURCE_SR 0x100 -#define FILE_CS_FLAG_CASE_SENSITIVE_DIR 1 - #else #define FILE_RENAME_INFORMATION_EX FILE_RENAME_INFORMATION @@ -210,7 +210,7 @@ static NTSTATUS set_basic_information(device_extension* Vcb, PIRP Irp, PFILE_OBJ return STATUS_INVALID_PARAMETER; } - TRACE("file = %p, attributes = %x\n", FileObject, fbi->FileAttributes); + TRACE("file = %p, attributes = %lx\n", FileObject, fbi->FileAttributes); ExAcquireResourceExclusiveLite(fcb->Header.Resource, true); @@ -389,7 +389,7 @@ static NTSTATUS set_disposition_information(device_extension* Vcb, PIRP Irp, PFI } else atts = fcb->atts; - TRACE("atts = %x\n", atts); + TRACE("atts = %lx\n", atts); if (atts & FILE_ATTRIBUTE_READONLY) { TRACE("not allowing readonly file to be deleted\n"); @@ -714,7 +714,7 @@ static NTSTATUS add_children_to_move_list(device_extension* Vcb, move_entry* me, Status = open_fileref_child(Vcb, me->fileref, &dc->name, true, true, dc->index == 0 ? true : false, PagedPool, &fr, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref_child returned %08x\n", Status); + ERR("open_fileref_child returned %08lx\n", Status); ExReleaseResourceLite(&me->fileref->fcb->nonpaged->dir_children_lock); return Status; } @@ -818,7 +818,7 @@ static NTSTATUS create_directory_fcb(device_extension* Vcb, root* r, fcb* parfcb if (!NT_SUCCESS(Status)) { reap_fcb(fcb); - ERR("SeAssignSecurity returned %08x\n", Status); + ERR("SeAssignSecurity returned %08lx\n", Status); return Status; } @@ -830,7 +830,7 @@ static NTSTATUS create_directory_fcb(device_extension* Vcb, root* r, fcb* parfcb Status = RtlGetOwnerSecurityDescriptor(fcb->sd, &owner, &defaulted); if (!NT_SUCCESS(Status)) { - ERR("RtlGetOwnerSecurityDescriptor returned %08x\n", Status); + ERR("RtlGetOwnerSecurityDescriptor returned %08lx\n", Status); fcb->inode_item.st_uid = UID_NOBODY; fcb->sd_dirty = true; } else { @@ -929,7 +929,7 @@ static NTSTATUS move_across_subvols(file_ref* fileref, ccb* ccb, file_ref* destd Status = add_children_to_move_list(fileref->fcb->Vcb, me, Irp); if (!NT_SUCCESS(Status)) { - ERR("add_children_to_move_list returned %08x\n", Status); + ERR("add_children_to_move_list returned %08lx\n", Status); goto end; } } @@ -957,7 +957,7 @@ static NTSTATUS move_across_subvols(file_ref* fileref, ccb* ccb, file_ref* destd Status = duplicate_fcb(me->fileref->fcb, &me->dummyfcb); if (!NT_SUCCESS(Status)) { - ERR("duplicate_fcb returned %08x\n", Status); + ERR("duplicate_fcb returned %08lx\n", Status); ExReleaseResourceLite(me->fileref->fcb->Header.Resource); goto end; } @@ -1031,7 +1031,7 @@ static NTSTATUS move_across_subvols(file_ref* fileref, ccb* ccb, file_ref* destd ext->offset - ed2->offset, 1, me->fileref->fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); ExReleaseResourceLite(me->fileref->fcb->Header.Resource); goto end; } @@ -1136,7 +1136,7 @@ static NTSTATUS move_across_subvols(file_ref* fileref, ccb* ccb, file_ref* destd Status = create_directory_fcb(me->fileref->fcb->Vcb, r, me->fileref->parent->fcb, &me->fileref->fcb); if (!NT_SUCCESS(Status)) { - ERR("create_directory_fcb returnd %08x\n", Status); + ERR("create_directory_fcb returned %08lx\n", Status); goto end; } @@ -1235,7 +1235,7 @@ static NTSTATUS move_across_subvols(file_ref* fileref, ccb* ccb, file_ref* destd Status = RtlUpcaseUnicodeString(&fileref->dc->name_uc, &fileref->dc->name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); goto end; } @@ -1316,7 +1316,7 @@ static NTSTATUS move_across_subvols(file_ref* fileref, ccb* ccb, file_ref* destd if (!me->dummyfileref->fcb->ads) { Status = delete_fileref(me->dummyfileref, NULL, false, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref returned %08x\n", Status); + ERR("delete_fileref returned %08lx\n", Status); goto end; } } @@ -1372,7 +1372,7 @@ static NTSTATUS move_across_subvols(file_ref* fileref, ccb* ccb, file_ref* destd if (me->dummyfileref->fcb->ads && me->parent->dummyfileref->fcb->deleted) { Status = delete_fileref(me->dummyfileref, NULL, false, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref returned %08x\n", Status); + ERR("delete_fileref returned %08lx\n", Status); goto end; } } @@ -1712,7 +1712,7 @@ static NTSTATUS rename_stream_to_file(device_extension* Vcb, file_ref* fileref, Status = add_extent_to_fcb(fileref->fcb, 0, ed, (uint16_t)(offsetof(EXTENT_DATA, data[0]) + adsdata.Length), false, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_extent_to_fcb returned %08x\n", Status); + ERR("add_extent_to_fcb returned %08lx\n", Status); ExFreePool(ed); reap_fcb(dummyfcb); return Status; @@ -1740,7 +1740,7 @@ static NTSTATUS rename_stream_to_file(device_extension* Vcb, file_ref* fileref, if (!make_inline) { Status = do_write_file(fileref->fcb, 0, adsdata.Length, adsdata.Buffer, Irp, false, 0, rollback); if (!NT_SUCCESS(Status)) { - ERR("do_write_file returned %08x\n", Status); + ERR("do_write_file returned %08lx\n", Status); ExFreePool(adsdata.Buffer); reap_fcb(dummyfcb); return Status; @@ -1840,7 +1840,7 @@ static NTSTATUS rename_stream(device_extension* Vcb, file_ref* fileref, ccb* ccb return rename_stream_to_file(Vcb, fileref, ccb, flags, Irp, rollback); if (!is_file_name_valid(&fn, false, true)) { - WARN("invalid stream name %.*S\n", fn.Length / sizeof(WCHAR), fn.Buffer); + WARN("invalid stream name %.*S\n", (int)(fn.Length / sizeof(WCHAR)), fn.Buffer); return STATUS_OBJECT_NAME_INVALID; } @@ -1877,12 +1877,12 @@ static NTSTATUS rename_stream(device_extension* Vcb, file_ref* fileref, ccb* ccb Status = delete_fileref(sf, NULL, false, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref returned %08x\n", Status); + ERR("delete_fileref returned %08lx\n", Status); goto end; } } } else { - ERR("open_fileref_child returned %08x\n", Status); + ERR("open_fileref_child returned %08lx\n", Status); goto end; } } @@ -1966,7 +1966,7 @@ static NTSTATUS rename_stream(device_extension* Vcb, file_ref* fileref, ccb* ccb Status = RtlUpcaseUnicodeString(&utf16uc, &fn, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n"); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); ExFreePool(utf8.Buffer); ExFreePool(utf16.Buffer); ExFreePool(adsxattr.Buffer); @@ -2079,7 +2079,7 @@ static NTSTATUS rename_file_to_stream(device_extension* Vcb, file_ref* fileref, } if (!is_file_name_valid(&fn, false, true)) { - WARN("invalid stream name %.*S\n", fn.Length / sizeof(WCHAR), fn.Buffer); + WARN("invalid stream name %.*S\n", (int)(fn.Length / sizeof(WCHAR)), fn.Buffer); return STATUS_OBJECT_NAME_INVALID; } @@ -2116,12 +2116,12 @@ static NTSTATUS rename_file_to_stream(device_extension* Vcb, file_ref* fileref, Status = delete_fileref(sf, NULL, false, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref returned %08x\n", Status); + ERR("delete_fileref returned %08lx\n", Status); goto end; } } } else { - ERR("open_fileref_child returned %08x\n", Status); + ERR("open_fileref_child returned %08lx\n", Status); goto end; } } @@ -2205,7 +2205,7 @@ static NTSTATUS rename_file_to_stream(device_extension* Vcb, file_ref* fileref, Status = RtlUpcaseUnicodeString(&utf16uc, &fn, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n"); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); ExFreePool(utf8.Buffer); ExFreePool(utf16.Buffer); ExFreePool(adsxattr.Buffer); @@ -2274,7 +2274,7 @@ static NTSTATUS rename_file_to_stream(device_extension* Vcb, file_ref* fileref, Status = duplicate_fcb(fileref->fcb, &dummyfcb); if (!NT_SUCCESS(Status)) { - ERR("duplicate_fcb returned %08x\n", Status); + ERR("duplicate_fcb returned %08lx\n", Status); ExFreePool(utf8.Buffer); ExFreePool(utf16.Buffer); ExFreePool(utf16uc.Buffer); @@ -2318,7 +2318,7 @@ static NTSTATUS rename_file_to_stream(device_extension* Vcb, file_ref* fileref, Status = excise_extents(Vcb, dummyfcb, 0, sector_align(fileref->fcb->inode_item.st_size, Vcb->superblock.sector_size), Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); ExFreePool(utf8.Buffer); ExFreePool(utf16.Buffer); ExFreePool(utf16uc.Buffer); @@ -2480,9 +2480,9 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB flags = fri->ReplaceIfExists ? FILE_RENAME_REPLACE_IF_EXISTS : 0; TRACE("tfo = %p\n", tfo); - TRACE("Flags = %x\n", flags); + TRACE("Flags = %lx\n", flags); TRACE("RootDirectory = %p\n", fri->RootDirectory); - TRACE("FileName = %.*S\n", fri->FileNameLength / sizeof(WCHAR), fri->FileName); + TRACE("FileName = %.*S\n", (int)(fri->FileNameLength / sizeof(WCHAR)), fri->FileName); fn = fri->FileName; fnlen = fri->FileNameLength / sizeof(WCHAR); @@ -2526,7 +2526,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, &iosb); if (!NT_SUCCESS(iosb.Status)) { - ERR("CcFlushCache returned %08x\n", iosb.Status); + ERR("CcFlushCache returned %08lx\n", iosb.Status); Status = iosb.Status; goto end; } @@ -2540,7 +2540,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, &iosb); if (!NT_SUCCESS(iosb.Status)) { - ERR("CcFlushCache returned %08x\n", iosb.Status); + ERR("CcFlushCache returned %08lx\n", iosb.Status); Status = iosb.Status; goto end; } @@ -2553,7 +2553,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB fnus.Buffer = fn; fnus.Length = fnus.MaximumLength = (uint16_t)(fnlen * sizeof(WCHAR)); - TRACE("fnus = %.*S\n", fnus.Length / sizeof(WCHAR), fnus.Buffer); + TRACE("fnus = %.*S\n", (int)(fnus.Length / sizeof(WCHAR)), fnus.Buffer); #ifndef __REACTOS__ for (unsigned int i = 0 ; i < fnus.Length / sizeof(WCHAR); i++) { @@ -2632,7 +2632,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB Status = open_fileref(Vcb, &related, &fnus, NULL, true, NULL, NULL, PagedPool, ccb->case_sensitive, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref returned %08x\n", Status); + ERR("open_fileref returned %08lx\n", Status); goto end; } } @@ -2647,7 +2647,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB if (!SeAccessCheck(related->fcb->sd, &subjcont, false, fcb->type == BTRFS_TYPE_DIRECTORY ? FILE_ADD_SUBDIRECTORY : FILE_ADD_FILE, 0, NULL, IoGetFileObjectGenericMapping(), Irp->RequestorMode, &access, &Status)) { SeReleaseSubjectContext(&subjcont); - TRACE("SeAccessCheck failed, returning %08x\n", Status); + TRACE("SeAccessCheck failed, returning %08lx\n", Status); goto end; } @@ -2665,7 +2665,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB if (!SeAccessCheck(oldfileref->fcb->sd, &subjcont, false, DELETE, 0, NULL, IoGetFileObjectGenericMapping(), Irp->RequestorMode, &access, &Status)) { SeReleaseSubjectContext(&subjcont); - TRACE("SeAccessCheck failed, returning %08x\n", Status); + TRACE("SeAccessCheck failed, returning %08lx\n", Status); goto end; } @@ -2678,7 +2678,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB Status = delete_fileref(oldfileref, NULL, oldfileref->open_count > 0 && flags & FILE_RENAME_POSIX_SEMANTICS, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref returned %08x\n", Status); + ERR("delete_fileref returned %08lx\n", Status); goto end; } } @@ -2686,7 +2686,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB if (fileref->parent->fcb->subvol != related->fcb->subvol && (fileref->fcb->subvol == fileref->parent->fcb->subvol || fileref->fcb == Vcb->dummy_fcb)) { Status = move_across_subvols(fileref, ccb, related, &utf8, &fnus, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("move_across_subvols returned %08x\n", Status); + ERR("move_across_subvols returned %08lx\n", Status); } goto end; } @@ -2700,7 +2700,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB Status = fileref_get_filename(fileref, &oldfn, &name_offset, &reqlen); if (Status != STATUS_BUFFER_OVERFLOW) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); goto end; } @@ -2715,7 +2715,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB Status = fileref_get_filename(fileref, &oldfn, &name_offset, &reqlen); if (!NT_SUCCESS(Status)) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); ExFreePool(oldfn.Buffer); goto end; } @@ -2734,7 +2734,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB RtlCopyMemory(fileref->oldutf8.Buffer, fileref->dc->utf8.Buffer, fileref->dc->utf8.Length); } - TRACE("renaming %.*S to %.*S\n", fileref->dc->name.Length / sizeof(WCHAR), fileref->dc->name.Buffer, fnus.Length / sizeof(WCHAR), fnus.Buffer); + TRACE("renaming %.*S to %.*S\n", (int)(fileref->dc->name.Length / sizeof(WCHAR)), fileref->dc->name.Buffer, (int)(fnus.Length / sizeof(WCHAR)), fnus.Buffer); mark_fileref_dirty(fileref); @@ -2771,7 +2771,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB Status = RtlUpcaseUnicodeString(&fileref->dc->name_uc, &fileref->dc->name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); ExReleaseResourceLite(&fileref->parent->fcb->nonpaged->dir_children_lock); ExFreePool(oldfn.Buffer); goto end; @@ -2791,7 +2791,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB Status = fileref_get_filename(fileref, &newfn, &name_offset, &reqlen); if (Status != STATUS_BUFFER_OVERFLOW) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); ExFreePool(oldfn.Buffer); goto end; } @@ -2808,7 +2808,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB Status = fileref_get_filename(fileref, &newfn, &name_offset, &reqlen); if (!NT_SUCCESS(Status)) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); ExFreePool(oldfn.Buffer); ExFreePool(newfn.Buffer); goto end; @@ -2941,7 +2941,7 @@ static NTSTATUS set_rename_information(device_extension* Vcb, PIRP Irp, PFILE_OB Status = RtlUpcaseUnicodeString(&fileref->dc->name_uc, &fileref->dc->name, true); if (!NT_SUCCESS(Status)) { - ERR("RtlUpcaseUnicodeString returned %08x\n", Status); + ERR("RtlUpcaseUnicodeString returned %08lx\n", Status); goto end; } @@ -3108,7 +3108,7 @@ NTSTATUS stream_set_end_of_file_information(device_extension* Vcb, uint16_t end, LARGE_INTEGER time; BTRFS_TIME now; - TRACE("setting new end to %I64x bytes (currently %x)\n", end, fcb->adsdata.Length); + TRACE("setting new end to %x bytes (currently %x)\n", end, fcb->adsdata.Length); if (!fileref || !fileref->parent) { ERR("no fileref for stream\n"); @@ -3119,14 +3119,14 @@ NTSTATUS stream_set_end_of_file_information(device_extension* Vcb, uint16_t end, if (advance_only) return STATUS_SUCCESS; - TRACE("truncating stream to %I64x bytes\n", end); + TRACE("truncating stream to %x bytes\n", end); fcb->adsdata.Length = end; } else if (end > fcb->adsdata.Length) { - TRACE("extending stream to %I64x bytes\n", end); + TRACE("extending stream to %x bytes\n", end); if (end > fcb->adsmaxlen) { - ERR("error - xattr too long (%u > %u)\n", end, fcb->adsmaxlen); + ERR("error - xattr too long (%u > %lu)\n", end, fcb->adsmaxlen); return STATUS_DISK_FULL; } @@ -3264,12 +3264,6 @@ static NTSTATUS set_end_of_file_information(device_extension* Vcb, PIRP Irp, PFI goto end; } } else if ((uint64_t)feofi->EndOfFile.QuadPart > fcb->inode_item.st_size) { - if (Irp->Flags & IRP_PAGING_IO) { - TRACE("paging IO tried to extend file size\n"); - Status = STATUS_SUCCESS; - goto end; - } - TRACE("extending file to %I64x bytes\n", feofi->EndOfFile.QuadPart); Status = extend_file(fcb, fileref, feofi->EndOfFile.QuadPart, prealloc, NULL, &rollback); @@ -3317,7 +3311,7 @@ end: } _SEH2_END; if (!NT_SUCCESS(Status)) - ERR("CcSetFileSizes threw exception %08x\n", Status); + ERR("CcSetFileSizes threw exception %08lx\n", Status); } ExReleaseResourceLite(&Vcb->tree_lock); @@ -3366,10 +3360,10 @@ static NTSTATUS set_link_information(device_extension* Vcb, PIRP Irp, PFILE_OBJE else flags = fli->ReplaceIfExists ? FILE_LINK_REPLACE_IF_EXISTS : 0; - TRACE("flags = %x\n", flags); + TRACE("flags = %lx\n", flags); TRACE("RootDirectory = %p\n", fli->RootDirectory); - TRACE("FileNameLength = %x\n", fli->FileNameLength); - TRACE("FileName = %.*S\n", fli->FileNameLength / sizeof(WCHAR), fli->FileName); + TRACE("FileNameLength = %lx\n", fli->FileNameLength); + TRACE("FileName = %.*S\n", (int)(fli->FileNameLength / sizeof(WCHAR)), fli->FileName); fn = fli->FileName; fnlen = fli->FileNameLength / sizeof(WCHAR); @@ -3427,7 +3421,7 @@ static NTSTATUS set_link_information(device_extension* Vcb, PIRP Irp, PFILE_OBJE fnus.Buffer = fn; fnus.Length = fnus.MaximumLength = (uint16_t)(fnlen * sizeof(WCHAR)); - TRACE("fnus = %.*S\n", fnus.Length / sizeof(WCHAR), fnus.Buffer); + TRACE("fnus = %.*S\n", (int)(fnus.Length / sizeof(WCHAR)), fnus.Buffer); Status = utf16_to_utf8(NULL, 0, &utf8len, fn, (ULONG)fnlen * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) @@ -3487,7 +3481,7 @@ static NTSTATUS set_link_information(device_extension* Vcb, PIRP Irp, PFILE_OBJE Status = open_fileref(Vcb, &related, &fnus, NULL, true, NULL, NULL, PagedPool, ccb->case_sensitive, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref returned %08x\n", Status); + ERR("open_fileref returned %08lx\n", Status); goto end; } } @@ -3497,7 +3491,7 @@ static NTSTATUS set_link_information(device_extension* Vcb, PIRP Irp, PFILE_OBJE if (!SeAccessCheck(related->fcb->sd, &subjcont, false, FILE_ADD_FILE, 0, NULL, IoGetFileObjectGenericMapping(), Irp->RequestorMode, &access, &Status)) { SeReleaseSubjectContext(&subjcont); - TRACE("SeAccessCheck failed, returning %08x\n", Status); + TRACE("SeAccessCheck failed, returning %08lx\n", Status); goto end; } @@ -3515,7 +3509,7 @@ static NTSTATUS set_link_information(device_extension* Vcb, PIRP Irp, PFILE_OBJE if (!SeAccessCheck(oldfileref->fcb->sd, &subjcont, false, DELETE, 0, NULL, IoGetFileObjectGenericMapping(), Irp->RequestorMode, &access, &Status)) { SeReleaseSubjectContext(&subjcont); - TRACE("SeAccessCheck failed, returning %08x\n", Status); + TRACE("SeAccessCheck failed, returning %08lx\n", Status); goto end; } @@ -3528,7 +3522,7 @@ static NTSTATUS set_link_information(device_extension* Vcb, PIRP Irp, PFILE_OBJE Status = delete_fileref(oldfileref, NULL, oldfileref->open_count > 0 && flags & FILE_RENAME_POSIX_SEMANTICS, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("delete_fileref returned %08x\n", Status); + ERR("delete_fileref returned %08lx\n", Status); goto end; } } @@ -3543,7 +3537,7 @@ static NTSTATUS set_link_information(device_extension* Vcb, PIRP Irp, PFILE_OBJE Status = add_dir_child(related->fcb, fcb->inode, false, &utf8, &fnus, fcb->type, &dc); if (!NT_SUCCESS(Status)) - WARN("add_dir_child returned %08x\n", Status); + WARN("add_dir_child returned %08lx\n", Status); fr2->dc = dc; dc->fileref = fr2; @@ -3700,7 +3694,7 @@ static NTSTATUS set_valid_data_length_information(device_extension* Vcb, PIRP Ir ULONG filter; if (IrpSp->Parameters.SetFile.Length < sizeof(FILE_VALID_DATA_LENGTH_INFORMATION)) { - ERR("input buffer length was %u, expected %u\n", IrpSp->Parameters.SetFile.Length, sizeof(FILE_VALID_DATA_LENGTH_INFORMATION)); + ERR("input buffer length was %lu, expected %Iu\n", IrpSp->Parameters.SetFile.Length, sizeof(FILE_VALID_DATA_LENGTH_INFORMATION)); return STATUS_INVALID_PARAMETER; } @@ -3771,7 +3765,7 @@ end: } _SEH2_END; if (!NT_SUCCESS(Status)) - ERR("CcSetFileSizes threw exception %08x\n", Status); + ERR("CcSetFileSizes threw exception %08lx\n", Status); else fcb->Header.AllocationSize = ccfs.AllocationSize; } @@ -4008,6 +4002,11 @@ NTSTATUS __stdcall drv_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP I Status = set_case_sensitive_information(Irp); break; + + case FileStorageReserveIdInformation: + WARN("unimplemented FileInformationClass FileStorageReserveIdInformation\n"); + break; + #ifndef _MSC_VER #pragma GCC diagnostic pop #endif @@ -4020,7 +4019,7 @@ NTSTATUS __stdcall drv_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP I end: Irp->IoStatus.Status = Status; - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -4267,7 +4266,7 @@ static NTSTATUS fill_in_file_name_information(FILE_NAME_INFORMATION* fni, fcb* f *length -= (LONG)offsetof(FILE_NAME_INFORMATION, FileName[0]); - TRACE("maximum length is %u\n", *length); + TRACE("maximum length is %li\n", *length); fni->FileNameLength = 0; fni->FileName[0] = 0; @@ -4278,7 +4277,7 @@ static NTSTATUS fill_in_file_name_information(FILE_NAME_INFORMATION* fni, fcb* f Status = fileref_get_filename(fileref, &fn, NULL, &reqlen); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); return Status; } @@ -4300,11 +4299,11 @@ static NTSTATUS fill_in_file_name_information(FILE_NAME_INFORMATION* fni, fcb* f if (Status == STATUS_BUFFER_OVERFLOW) { *length = -1; fni->FileNameLength = reqlen; - TRACE("%.*S (truncated)\n", fn.Length / sizeof(WCHAR), fn.Buffer); + TRACE("%.*S (truncated)\n", (int)(fn.Length / sizeof(WCHAR)), fn.Buffer); } else { *length -= fn.Length; fni->FileNameLength = fn.Length; - TRACE("%.*S\n", fn.Length / sizeof(WCHAR), fn.Buffer); + TRACE("%.*S\n", (int)(fn.Length / sizeof(WCHAR)), fn.Buffer); } return Status; @@ -4368,7 +4367,7 @@ static NTSTATUS fill_in_file_stream_information(FILE_STREAM_INFORMATION* fsi, fi le = le->Flink; } - TRACE("length = %i, reqsize = %u\n", *length, reqsize); + TRACE("length = %li, reqsize = %lu\n", *length, reqsize); if (reqsize > *length) { Status = STATUS_BUFFER_OVERFLOW; @@ -4537,12 +4536,12 @@ static NTSTATUS fill_in_hard_link_information(FILE_LINKS_INFORMATION* fli, file_ hardlink* hl = CONTAINING_RECORD(le, hardlink, list_entry); file_ref* parfr; - TRACE("parent %I64x, index %I64x, name %.*S\n", hl->parent, hl->index, hl->name.Length / sizeof(WCHAR), hl->name.Buffer); + TRACE("parent %I64x, index %I64x, name %.*S\n", hl->parent, hl->index, (int)(hl->name.Length / sizeof(WCHAR)), hl->name.Buffer); Status = open_fileref_by_inode(fcb->Vcb, fcb->subvol, hl->parent, &parfr, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref_by_inode returned %08x\n", Status); + ERR("open_fileref_by_inode returned %08lx\n", Status); } else if (!parfr->deleted) { LIST_ENTRY* le2; bool found = false, deleted = false; @@ -4569,7 +4568,7 @@ static NTSTATUS fill_in_hard_link_information(FILE_LINKS_INFORMATION* fli, file_ fn = &hl->name; if (!deleted) { - TRACE("fn = %.*S (found = %u)\n", fn->Length / sizeof(WCHAR), fn->Buffer, found); + TRACE("fn = %.*S (found = %u)\n", (int)(fn->Length / sizeof(WCHAR)), fn->Buffer, found); if (feli) bytes_needed = (LONG)sector_align(bytes_needed, 8); @@ -4705,12 +4704,12 @@ static NTSTATUS fill_in_hard_link_full_id_information(FILE_LINKS_FULL_ID_INFORMA hardlink* hl = CONTAINING_RECORD(le, hardlink, list_entry); file_ref* parfr; - TRACE("parent %I64x, index %I64x, name %.*S\n", hl->parent, hl->index, hl->name.Length / sizeof(WCHAR), hl->name.Buffer); + TRACE("parent %I64x, index %I64x, name %.*S\n", hl->parent, hl->index, (int)(hl->name.Length / sizeof(WCHAR)), hl->name.Buffer); Status = open_fileref_by_inode(fcb->Vcb, fcb->subvol, hl->parent, &parfr, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref_by_inode returned %08x\n", Status); + ERR("open_fileref_by_inode returned %08lx\n", Status); } else if (!parfr->deleted) { LIST_ENTRY* le2; bool found = false, deleted = false; @@ -4737,7 +4736,7 @@ static NTSTATUS fill_in_hard_link_full_id_information(FILE_LINKS_FULL_ID_INFORMA fn = &hl->name; if (!deleted) { - TRACE("fn = %.*S (found = %u)\n", fn->Length / sizeof(WCHAR), fn->Buffer, found); + TRACE("fn = %.*S (found = %u)\n", (int)(fn->Length / sizeof(WCHAR)), fn->Buffer, found); if (flefii) bytes_needed = (LONG)sector_align(bytes_needed, 8); @@ -4802,8 +4801,7 @@ static NTSTATUS fill_in_file_id_information(FILE_ID_INFORMATION* fii, fcb* fcb, static NTSTATUS fill_in_file_stat_information(FILE_STAT_INFORMATION* fsi, fcb* fcb, ccb* ccb, LONG* length) { INODE_ITEM* ii; - fsi->FileId.LowPart = (uint32_t)fcb->inode; - fsi->FileId.HighPart = (uint32_t)fcb->subvol->id; + fsi->FileId.QuadPart = make_file_id(fcb->subvol, fcb->inode); if (fcb->ads) ii = &ccb->fileref->parent->fcb->inode_item; @@ -4832,13 +4830,13 @@ static NTSTATUS fill_in_file_stat_information(FILE_STAT_INFORMATION* fsi, fcb* f } if (fcb->type == BTRFS_TYPE_SOCKET) - fsi->ReparseTag = IO_REPARSE_TAG_LXSS_SOCKET; + fsi->ReparseTag = IO_REPARSE_TAG_AF_UNIX; else if (fcb->type == BTRFS_TYPE_FIFO) - fsi->ReparseTag = IO_REPARSE_TAG_LXSS_FIFO; + fsi->ReparseTag = IO_REPARSE_TAG_LX_FIFO; else if (fcb->type == BTRFS_TYPE_CHARDEV) - fsi->ReparseTag = IO_REPARSE_TAG_LXSS_CHARDEV; + fsi->ReparseTag = IO_REPARSE_TAG_LX_CHR; else if (fcb->type == BTRFS_TYPE_BLOCKDEV) - fsi->ReparseTag = IO_REPARSE_TAG_LXSS_BLOCKDEV; + fsi->ReparseTag = IO_REPARSE_TAG_LX_BLK; else if (!(fsi->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) fsi->ReparseTag = 0; else @@ -4862,8 +4860,7 @@ static NTSTATUS fill_in_file_stat_information(FILE_STAT_INFORMATION* fsi, fcb* f static NTSTATUS fill_in_file_stat_lx_information(FILE_STAT_LX_INFORMATION* fsli, fcb* fcb, ccb* ccb, LONG* length) { INODE_ITEM* ii; - fsli->FileId.LowPart = (uint32_t)fcb->inode; - fsli->FileId.HighPart = (uint32_t)fcb->subvol->id; + fsli->FileId.QuadPart = make_file_id(fcb->subvol, fcb->inode); if (fcb->ads) ii = &ccb->fileref->parent->fcb->inode_item; @@ -4892,13 +4889,13 @@ static NTSTATUS fill_in_file_stat_lx_information(FILE_STAT_LX_INFORMATION* fsli, } if (fcb->type == BTRFS_TYPE_SOCKET) - fsli->ReparseTag = IO_REPARSE_TAG_LXSS_SOCKET; + fsli->ReparseTag = IO_REPARSE_TAG_AF_UNIX; else if (fcb->type == BTRFS_TYPE_FIFO) - fsli->ReparseTag = IO_REPARSE_TAG_LXSS_FIFO; + fsli->ReparseTag = IO_REPARSE_TAG_LX_FIFO; else if (fcb->type == BTRFS_TYPE_CHARDEV) - fsli->ReparseTag = IO_REPARSE_TAG_LXSS_CHARDEV; + fsli->ReparseTag = IO_REPARSE_TAG_LX_CHR; else if (fcb->type == BTRFS_TYPE_BLOCKDEV) - fsli->ReparseTag = IO_REPARSE_TAG_LXSS_BLOCKDEV; + fsli->ReparseTag = IO_REPARSE_TAG_LX_BLK; else if (!(fsli->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) fsli->ReparseTag = 0; else @@ -4942,7 +4939,21 @@ static NTSTATUS fill_in_file_case_sensitive_information(FILE_CASE_SENSITIVE_INFO return STATUS_SUCCESS; } -#endif + +#endif // __REACTOS__ + +static NTSTATUS fill_in_file_compression_information(FILE_COMPRESSION_INFORMATION* fci, LONG* length, fcb* fcb) { + *length -= sizeof(FILE_COMPRESSION_INFORMATION); + + memset(fci, 0, sizeof(FILE_COMPRESSION_INFORMATION)); + + if (fcb->ads) + fci->CompressedFileSize.QuadPart = fcb->adsdata.Length; + else if (!S_ISDIR(fcb->inode_item.st_mode)) + fci->CompressedFileSize.QuadPart = fcb->inode_item.st_size; + + return STATUS_SUCCESS; +} static NTSTATUS query_info(device_extension* Vcb, PFILE_OBJECT FileObject, PIRP Irp) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -5073,9 +5084,14 @@ static NTSTATUS query_info(device_extension* Vcb, PFILE_OBJECT FileObject, PIRP } case FileCompressionInformation: - FIXME("STUB: FileCompressionInformation\n"); - Status = STATUS_INVALID_PARAMETER; - goto exit; + { + FILE_COMPRESSION_INFORMATION* fci = Irp->AssociatedIrp.SystemBuffer; + + TRACE("FileCompressionInformation\n"); + + Status = fill_in_file_compression_information(fci, &length, fcb); + break; + } case FileEaInformation: { @@ -5310,7 +5326,7 @@ static NTSTATUS query_info(device_extension* Vcb, PFILE_OBJECT FileObject, PIRP Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - length; exit: - TRACE("query_info returning %08x\n", Status); + TRACE("query_info returning %08lx\n", Status); return Status; } @@ -5349,7 +5365,7 @@ NTSTATUS __stdcall drv_query_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Status = query_info(fcb->Vcb, IrpSp->FileObject, Irp); end: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); Irp->IoStatus.Status = Status; @@ -5577,7 +5593,7 @@ end2: ExReleaseResourceLite(fcb->Header.Resource); end: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW ? retlen : 0; @@ -5640,7 +5656,7 @@ NTSTATUS __stdcall drv_set_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { Status = IoCheckEaBufferValidity(ffei, IrpSp->Parameters.SetEa.Length, &offset); if (!NT_SUCCESS(Status)) { - ERR("IoCheckEaBufferValidity returned %08x (error at offset %u)\n", Status, offset); + ERR("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset); goto end; } @@ -5936,7 +5952,7 @@ end2: } end: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; diff --git a/drivers/filesystems/btrfs/flushthread.c b/drivers/filesystems/btrfs/flushthread.c index 456c8541370..42d45332e94 100644 --- a/drivers/filesystems/btrfs/flushthread.c +++ b/drivers/filesystems/btrfs/flushthread.c @@ -16,6 +16,8 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "xxhash.h" +#include "crc32c.h" #include #include #include @@ -108,7 +110,7 @@ NTSTATUS write_data_phys(_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj, } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(Irp->MdlAddress); goto exit; } @@ -133,7 +135,7 @@ NTSTATUS write_data_phys(_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj, } if (!NT_SUCCESS(Status)) { - ERR("IoCallDriver returned %08x\n", Status); + ERR("IoCallDriver returned %08lx\n", Status); } if (device->Flags & DO_DIRECT_IO) { @@ -177,6 +179,10 @@ static void clean_space_cache_chunk(device_extension* Vcb, chunk* c) { type = BLOCK_FLAG_RAID5; else if (c->chunk_item->type & BLOCK_FLAG_RAID6) type = BLOCK_FLAG_RAID6; + else if (c->chunk_item->type & BLOCK_FLAG_RAID1C3) + type = BLOCK_FLAG_DUPLICATE; + else if (c->chunk_item->type & BLOCK_FLAG_RAID1C4) + type = BLOCK_FLAG_DUPLICATE; else // SINGLE type = BLOCK_FLAG_DUPLICATE; } @@ -599,7 +605,7 @@ static NTSTATUS add_parents(device_extension* Vcb, PIRP Irp) { for (level = 0; level <= 255; level++) { bool nothing_found = true; - TRACE("level = %u\n", level); + TRACE("level = %lu\n", level); le = Vcb->trees.Flink; while (le != &Vcb->trees) { @@ -629,7 +635,7 @@ static NTSTATUS add_parents(device_extension* Vcb, PIRP Irp) { Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -650,14 +656,14 @@ static NTSTATUS add_parents(device_extension* Vcb, PIRP Irp) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(ri); return Status; } Status = insert_tree_item(Vcb, Vcb->root_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, ri, sizeof(ROOT_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ri); return Status; } @@ -712,7 +718,7 @@ static bool insert_tree_extent_skinny(device_extension* Vcb, uint8_t level, uint Status = insert_tree_item(Vcb, Vcb->extent_root, address, TYPE_METADATA_ITEM, level, eism, sizeof(EXTENT_ITEM_SKINNY_METADATA), &insert_tp, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(eism); return false; } @@ -741,7 +747,7 @@ bool find_metadata_address_in_chunk(device_extension* Vcb, chunk* c, uint64_t* a NTSTATUS Status = load_cache_chunk(Vcb, c, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); return false; } } @@ -815,7 +821,7 @@ static bool insert_tree_extent(device_extension* Vcb, uint8_t level, uint64_t ro EXTENT_ITEM_TREE2* eit2; traverse_ptr insert_tp; - TRACE("(%p, %x, %I64x, %p, %p, %p, %p)\n", Vcb, level, root_id, c, new_address, rollback); + TRACE("(%p, %x, %I64x, %p, %p, %p, %p)\n", Vcb, level, root_id, c, new_address, Irp, rollback); if (!find_metadata_address_in_chunk(Vcb, c, &address)) return false; @@ -844,7 +850,7 @@ static bool insert_tree_extent(device_extension* Vcb, uint8_t level, uint64_t ro Status = insert_tree_item(Vcb, Vcb->extent_root, address, TYPE_EXTENT_ITEM, Vcb->superblock.node_size, eit2, sizeof(EXTENT_ITEM_TREE2), &insert_tp, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(eit2); return false; } @@ -914,7 +920,7 @@ NTSTATUS get_tree_new_address(device_extension* Vcb, tree* t, PIRP Irp, LIST_ENT Status = alloc_chunk(Vcb, flags, &c, false); if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->chunk_lock); return Status; } @@ -959,7 +965,7 @@ static NTSTATUS reduce_tree_extent(device_extension* Vcb, uint64_t address, tree Status = decrease_extent_refcount_tree(Vcb, address, Vcb->superblock.node_size, root, level, Irp); if (!NT_SUCCESS(Status)) { - ERR("decrease_extent_refcount_tree returned %08x\n", Status); + ERR("decrease_extent_refcount_tree returned %08lx\n", Status); return Status; } @@ -973,7 +979,7 @@ static NTSTATUS reduce_tree_extent(device_extension* Vcb, uint64_t address, tree Status = load_cache_chunk(Vcb, c, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); release_chunk_lock(c, Vcb); return Status; } @@ -1073,7 +1079,7 @@ static bool shared_tree_is_unique(device_extension* Vcb, tree* t, PIRP Irp, LIST if (!t->updated_extents && t->has_address) { Status = update_tree_extents(Vcb, t, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_tree_extents returned %08x\n", Status); + ERR("update_tree_extents returned %08lx\n", Status); return false; } } @@ -1084,7 +1090,7 @@ static bool shared_tree_is_unique(device_extension* Vcb, tree* t, PIRP Irp, LIST Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return false; } @@ -1150,20 +1156,20 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI if (ce) { Status = add_changed_extent_ref_edr(ce, &edr, true); if (!NT_SUCCESS(Status)) { - ERR("add_changed_extent_ref_edr returned %08x\n", Status); + ERR("add_changed_extent_ref_edr returned %08lx\n", Status); return Status; } Status = add_changed_extent_ref_edr(ce, &edr, false); if (!NT_SUCCESS(Status)) { - ERR("add_changed_extent_ref_edr returned %08x\n", Status); + ERR("add_changed_extent_ref_edr returned %08lx\n", Status); return Status; } } Status = increase_extent_refcount(Vcb, ed2->address, ed2->size, TYPE_EXTENT_DATA_REF, &edr, NULL, 0, Irp); if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount returned %08x\n", Status); + ERR("increase_extent_refcount returned %08lx\n", Status); return Status; } @@ -1179,7 +1185,7 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI Status = decrease_extent_refcount(Vcb, ed2->address, ed2->size, TYPE_SHARED_DATA_REF, &sdr, NULL, 0, t->header.address, ce ? ce->superseded : false, Irp); if (!NT_SUCCESS(Status)) { - ERR("decrease_extent_refcount returned %08x\n", Status); + ERR("decrease_extent_refcount returned %08lx\n", Status); return Status; } @@ -1242,7 +1248,7 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI Status = increase_extent_refcount(Vcb, td->treeholder.address, Vcb->superblock.node_size, TYPE_TREE_BLOCK_REF, &tbr, &td->key, t->header.level - 1, Irp); if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount returned %08x\n", Status); + ERR("increase_extent_refcount returned %08lx\n", Status); return Status; } @@ -1257,7 +1263,7 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI Status = decrease_extent_refcount(Vcb, td->treeholder.address, Vcb->superblock.node_size, TYPE_SHARED_BLOCK_REF, &sbr, NULL, 0, t->header.address, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("decrease_extent_refcount returned %08x\n", Status); + ERR("decrease_extent_refcount returned %08lx\n", Status); return Status; } } @@ -1281,7 +1287,7 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI Status = decrease_extent_refcount(Vcb, t->header.address, Vcb->superblock.node_size, TYPE_SHARED_BLOCK_REF, &sbr, NULL, 0, t->parent->header.address, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("decrease_extent_refcount returned %08x\n", Status); + ERR("decrease_extent_refcount returned %08lx\n", Status); return Status; } } @@ -1295,7 +1301,7 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI Status = increase_extent_refcount(Vcb, t->header.address, Vcb->superblock.node_size, TYPE_TREE_BLOCK_REF, &tbr, t->parent ? &t->paritem->key : NULL, t->header.level, Irp); if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount returned %08x\n", Status); + ERR("increase_extent_refcount returned %08lx\n", Status); return Status; } @@ -1308,7 +1314,7 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI Status = reduce_tree_extent(Vcb, t->header.address, t, t->parent ? t->parent->header.tree_id : t->header.tree_id, t->header.level, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("reduce_tree_extent returned %08x\n", Status); + ERR("reduce_tree_extent returned %08lx\n", Status); return Status; } } @@ -1344,7 +1350,7 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI } if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount returned %08x\n", Status); + ERR("increase_extent_refcount returned %08lx\n", Status); return Status; } } @@ -1393,13 +1399,13 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI if (ce) { Status = add_changed_extent_ref_sdr(ce, &sdr, true); if (!NT_SUCCESS(Status)) { - ERR("add_changed_extent_ref_edr returned %08x\n", Status); + ERR("add_changed_extent_ref_edr returned %08lx\n", Status); return Status; } Status = add_changed_extent_ref_sdr(ce, &sdr, false); if (!NT_SUCCESS(Status)) { - ERR("add_changed_extent_ref_edr returned %08x\n", Status); + ERR("add_changed_extent_ref_edr returned %08lx\n", Status); return Status; } } @@ -1416,13 +1422,13 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI if (ce) { Status = add_changed_extent_ref_edr(ce, &edr, true); if (!NT_SUCCESS(Status)) { - ERR("add_changed_extent_ref_edr returned %08x\n", Status); + ERR("add_changed_extent_ref_edr returned %08lx\n", Status); return Status; } Status = add_changed_extent_ref_edr(ce, &edr, false); if (!NT_SUCCESS(Status)) { - ERR("add_changed_extent_ref_edr returned %08x\n", Status); + ERR("add_changed_extent_ref_edr returned %08lx\n", Status); return Status; } } @@ -1431,7 +1437,7 @@ static NTSTATUS update_tree_extents(device_extension* Vcb, tree* t, PIRP Irp, LI } if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount returned %08x\n", Status); + ERR("increase_extent_refcount returned %08lx\n", Status); return Status; } } @@ -1475,7 +1481,7 @@ static NTSTATUS allocate_tree_extents(device_extension* Vcb, PIRP Irp, LIST_ENTR Status = load_cache_chunk(Vcb, c, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); release_chunk_lock(c, Vcb); return Status; } @@ -1488,7 +1494,7 @@ static NTSTATUS allocate_tree_extents(device_extension* Vcb, PIRP Irp, LIST_ENTR Status = get_tree_new_address(Vcb, t, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("get_tree_new_address returned %08x\n", Status); + ERR("get_tree_new_address returned %08lx\n", Status); return Status; } @@ -1524,7 +1530,7 @@ static NTSTATUS allocate_tree_extents(device_extension* Vcb, PIRP Irp, LIST_ENTR if (t->write && !t->updated_extents && t->has_address && t->header.level == level) { Status = update_tree_extents(Vcb, t, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_tree_extents returned %08x\n", Status); + ERR("update_tree_extents returned %08lx\n", Status); return Status; } } @@ -1562,7 +1568,7 @@ static NTSTATUS update_root_root(device_extension* Vcb, bool no_cache, PIRP Irp, Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -1596,7 +1602,7 @@ static NTSTATUS update_root_root(device_extension* Vcb, bool no_cache, PIRP Irp, ExReleaseResourceLite(&Vcb->chunk_lock); if (!NT_SUCCESS(Status)) { - ERR("update_chunk_caches returned %08x\n", Status); + ERR("update_chunk_caches returned %08lx\n", Status); return Status; } } @@ -1695,7 +1701,7 @@ NTSTATUS do_tree_writes(device_extension* Vcb, LIST_ENTRY* tree_writes, bool no_ Status = write_data(Vcb, tw->address, tw->data, tw->length, &wtc[bit_num], NULL, NULL, false, 0, HighPagePriority); if (!NT_SUCCESS(Status)) { - ERR("write_data returned %08x\n", Status); + ERR("write_data returned %08lx\n", Status); for (i = 0; i < num_bits; i++) { free_write_data_stripes(&wtc[i]); @@ -1774,7 +1780,7 @@ NTSTATUS do_tree_writes(device_extension* Vcb, LIST_ENTRY* tree_writes, bool no_ ExFreePool(ps); if (!NT_SUCCESS(Status)) { - ERR("flush_partial_stripe returned %08x\n", Status); + ERR("flush_partial_stripe returned %08lx\n", Status); ExReleaseResourceLite(&c->partial_stripes_lock); return Status; } @@ -1790,10 +1796,29 @@ NTSTATUS do_tree_writes(device_extension* Vcb, LIST_ENTRY* tree_writes, bool no_ return STATUS_SUCCESS; } +void calc_tree_checksum(device_extension* Vcb, tree_header* th) { + switch (Vcb->superblock.csum_type) { + case CSUM_TYPE_CRC32C: + *((uint32_t*)th) = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + break; + + case CSUM_TYPE_XXHASH: + *((uint64_t*)th) = XXH64((uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum), 0); + break; + + case CSUM_TYPE_SHA256: + calc_sha256((uint8_t*)th, &th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + break; + + case CSUM_TYPE_BLAKE2: + blake2b((uint8_t*)th, BLAKE2_HASH_SIZE, &th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + break; + } +} + static NTSTATUS write_trees(device_extension* Vcb, PIRP Irp) { ULONG level; uint8_t *data, *body; - uint32_t crc32; NTSTATUS Status; LIST_ENTRY* le; LIST_ENTRY tree_writes; @@ -1806,7 +1831,7 @@ static NTSTATUS write_trees(device_extension* Vcb, PIRP Irp) { for (level = 0; level <= 255; level++) { bool nothing_found = true; - TRACE("level = %u\n", level); + TRACE("level = %lu\n", level); le = Vcb->trees.Flink; while (le != &Vcb->trees) { @@ -1847,7 +1872,7 @@ static NTSTATUS write_trees(device_extension* Vcb, PIRP Irp) { Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -1857,7 +1882,7 @@ static NTSTATUS write_trees(device_extension* Vcb, PIRP Irp) { } if (tp.item->size < sizeof(EXTENT_ITEM_TREE)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM_TREE)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM_TREE)); return STATUS_INTERNAL_ERROR; } @@ -1937,7 +1962,7 @@ static NTSTATUS write_trees(device_extension* Vcb, PIRP Irp) { } if (t->size > Vcb->superblock.node_size - sizeof(tree_header)) { - ERR("tree %I64x, level %x: tried to write overlarge tree (%x > %x)\n", t->root->id, t->header.level, t->size, Vcb->superblock.node_size - sizeof(tree_header)); + ERR("tree %I64x, level %x: tried to write overlarge tree (%x > %Ix)\n", t->root->id, t->header.level, t->size, Vcb->superblock.node_size - sizeof(tree_header)); crash = true; } @@ -1958,7 +1983,7 @@ static NTSTATUS write_trees(device_extension* Vcb, PIRP Irp) { t->header.generation = Vcb->superblock.generation; t->header.tree_id = t->root->id; t->header.flags |= HEADER_FLAG_MIXED_BACKREF; - t->header.fs_uuid = Vcb->superblock.uuid; + t->header.fs_uuid = Vcb->superblock.metadata_uuid; t->has_address = true; data = ExAllocatePoolWithTag(NonPagedPool, Vcb->superblock.node_size, ALLOC_TAG); @@ -2013,10 +2038,7 @@ static NTSTATUS write_trees(device_extension* Vcb, PIRP Irp) { } } - crc32 = calc_crc32c(0xffffffff, (uint8_t*)&((tree_header*)data)->fs_uuid, Vcb->superblock.node_size - sizeof(((tree_header*)data)->csum)); - crc32 = ~crc32; - *((uint32_t*)data) = crc32; - TRACE("setting crc32 to %08x\n", crc32); + calc_tree_checksum(Vcb, (tree_header*)data); tw = ExAllocatePoolWithTag(PagedPool, sizeof(tree_write), ALLOC_TAG); if (!tw) { @@ -2059,7 +2081,7 @@ static NTSTATUS write_trees(device_extension* Vcb, PIRP Irp) { Status = do_tree_writes(Vcb, &tree_writes, false); if (!NT_SUCCESS(Status)) { - ERR("do_tree_writes returned %08x\n", Status); + ERR("do_tree_writes returned %08lx\n", Status); goto end; } @@ -2179,6 +2201,26 @@ static NTSTATUS __stdcall write_superblock_completion(PDEVICE_OBJECT DeviceObjec return STATUS_MORE_PROCESSING_REQUIRED; } +static void calc_superblock_checksum(superblock* sb) { + switch (sb->csum_type) { + case CSUM_TYPE_CRC32C: + *(uint32_t*)sb = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); + break; + + case CSUM_TYPE_XXHASH: + *(uint64_t*)sb = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0); + break; + + case CSUM_TYPE_SHA256: + calc_sha256((uint8_t*)sb, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum)); + break; + + case CSUM_TYPE_BLAKE2: + blake2b((uint8_t*)sb, BLAKE2_HASH_SIZE, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum)); + break; + } +} + static NTSTATUS write_superblock(device_extension* Vcb, device* device, write_superblocks_context* context) { unsigned int i = 0; @@ -2188,7 +2230,6 @@ static NTSTATUS write_superblock(device_extension* Vcb, device* device, write_su while (superblock_addrs[i] > 0 && device->devitem.num_bytes >= superblock_addrs[i] + sizeof(superblock)) { ULONG sblen = (ULONG)sector_align(sizeof(superblock), Vcb->superblock.sector_size); superblock* sb; - uint32_t crc32; write_superblocks_stripe* stripe; PIO_STACK_LOCATION IrpSp; @@ -2206,8 +2247,7 @@ static NTSTATUS write_superblock(device_extension* Vcb, device* device, write_su RtlCopyMemory(&sb->dev_item, &device->devitem, sizeof(DEV_ITEM)); sb->sb_phys_addr = superblock_addrs[i]; - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - RtlCopyMemory(&sb->checksum, &crc32, sizeof(uint32_t)); + calc_superblock_checksum(sb); stripe = ExAllocatePoolWithTag(NonPagedPool, sizeof(write_superblocks_stripe), ALLOC_TAG); if (!stripe) { @@ -2319,7 +2359,7 @@ static NTSTATUS write_superblocks(device_extension* Vcb, PIRP Irp) { if (dev->devobj && !dev->readonly) { Status = write_superblock(Vcb, dev, &context); if (!NT_SUCCESS(Status)) { - ERR("write_superblock returned %08x\n", Status); + ERR("write_superblock returned %08lx\n", Status); goto end; } } @@ -2349,7 +2389,7 @@ static NTSTATUS write_superblocks(device_extension* Vcb, PIRP Irp) { write_superblocks_stripe* stripe = CONTAINING_RECORD(le, write_superblocks_stripe, list_entry); if (!NT_SUCCESS(stripe->Status)) { - ERR("device %I64x returned %08x\n", stripe->device->devitem.dev_id, stripe->Status); + ERR("device %I64x returned %08lx\n", stripe->device->devitem.dev_id, stripe->Status); log_device_error(Vcb, stripe->device, BTRFS_DEV_STAT_WRITE_ERRORS); Status = stripe->Status; goto end; @@ -2426,7 +2466,7 @@ static NTSTATUS flush_changed_extent(device_extension* Vcb, chunk* c, changed_ex Status = increase_extent_refcount_data(Vcb, ce->address, old_size, cer->edr.root, cer->edr.objid, cer->edr.offset, cer->edr.count - old_count, Irp); if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount_data returned %08x\n", Status); + ERR("increase_extent_refcount_data returned %08lx\n", Status); return Status; } } @@ -2477,7 +2517,7 @@ static NTSTATUS flush_changed_extent(device_extension* Vcb, chunk* c, changed_ex old_count - cer->edr.count, ce->superseded, Irp); if (!NT_SUCCESS(Status)) { - ERR("decrease_extent_refcount_data returned %08x\n", Status); + ERR("decrease_extent_refcount_data returned %08lx\n", Status); return Status; } } @@ -2493,7 +2533,7 @@ static NTSTATUS flush_changed_extent(device_extension* Vcb, chunk* c, changed_ex Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -2516,14 +2556,14 @@ static NTSTATUS flush_changed_extent(device_extension* Vcb, chunk* c, changed_ex Status = insert_tree_item(Vcb, Vcb->extent_root, ce->address, TYPE_EXTENT_ITEM, ce->size, data, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); if (data) ExFreePool(data); return Status; } Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } @@ -2552,18 +2592,17 @@ end: return STATUS_SUCCESS; } -void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, uint32_t* csum, PIRP Irp) { +void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, void* csum, PIRP Irp) { KEY searchkey; traverse_ptr tp, next_tp; NTSTATUS Status; uint64_t startaddr, endaddr; ULONG len; - uint32_t* checksums; RTL_BITMAP bmp; ULONG* bmparr; ULONG runlength, index; - TRACE("(%p, %I64x, %x, %p, %p)\n", Vcb, address, length, csum, Irp); + TRACE("(%p, %I64x, %lx, %p, %p)\n", Vcb, address, length, csum, Irp); searchkey.obj_id = EXTENT_CSUM_ID; searchkey.obj_type = TYPE_EXTENT_CSUM; @@ -2576,23 +2615,23 @@ void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, u if (csum) { // not deleted ULONG length2 = length; uint64_t off = address; - uint32_t* data = csum; + void* data = csum; do { - uint16_t il = (uint16_t)min(length2, MAX_CSUM_SIZE / sizeof(uint32_t)); + uint16_t il = (uint16_t)min(length2, MAX_CSUM_SIZE / Vcb->csum_size); - checksums = ExAllocatePoolWithTag(PagedPool, il * sizeof(uint32_t), ALLOC_TAG); + void* checksums = ExAllocatePoolWithTag(PagedPool, il * Vcb->csum_size, ALLOC_TAG); if (!checksums) { ERR("out of memory\n"); return; } - RtlCopyMemory(checksums, data, il * sizeof(uint32_t)); + RtlCopyMemory(checksums, data, il * Vcb->csum_size); Status = insert_tree_item(Vcb, Vcb->checksum_root, EXTENT_CSUM_ID, TYPE_EXTENT_CSUM, off, checksums, - il * sizeof(uint32_t), NULL, Irp); + il * Vcb->csum_size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(checksums); return; } @@ -2601,19 +2640,20 @@ void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, u if (length2 > 0) { off += il * Vcb->superblock.sector_size; - data += il; + data = (uint8_t*)data + (il * Vcb->csum_size); } } while (length2 > 0); } } else if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return; } else { uint32_t tplen; + void* checksums; // FIXME - check entry is TYPE_EXTENT_CSUM? - if (tp.item->key.offset < address && tp.item->key.offset + (tp.item->size * Vcb->superblock.sector_size / sizeof(uint32_t)) >= address) + if (tp.item->key.offset < address && tp.item->key.offset + (tp.item->size * Vcb->superblock.sector_size / Vcb->csum_size) >= address) startaddr = tp.item->key.offset; else startaddr = address; @@ -2624,24 +2664,24 @@ void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, u Status = find_item(Vcb, Vcb->checksum_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return; } - tplen = tp.item->size / sizeof(uint32_t); + tplen = tp.item->size / Vcb->csum_size; if (tp.item->key.offset + (tplen * Vcb->superblock.sector_size) >= address + (length * Vcb->superblock.sector_size)) endaddr = tp.item->key.offset + (tplen * Vcb->superblock.sector_size); else endaddr = address + (length * Vcb->superblock.sector_size); - TRACE("cs starts at %I64x (%x sectors)\n", address, length); + TRACE("cs starts at %I64x (%lx sectors)\n", address, length); TRACE("startaddr = %I64x\n", startaddr); TRACE("endaddr = %I64x\n", endaddr); len = (ULONG)((endaddr - startaddr) / Vcb->superblock.sector_size); - checksums = ExAllocatePoolWithTag(PagedPool, sizeof(uint32_t) * len, ALLOC_TAG); + checksums = ExAllocatePoolWithTag(PagedPool, Vcb->csum_size * len, ALLOC_TAG); if (!checksums) { ERR("out of memory\n"); return; @@ -2663,7 +2703,7 @@ void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, u Status = find_item(Vcb, Vcb->checksum_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); ExFreePool(checksums); ExFreePool(bmparr); return; @@ -2674,15 +2714,16 @@ void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, u while (tp.item->key.offset < endaddr) { if (tp.item->key.offset >= startaddr) { if (tp.item->size > 0) { - ULONG itemlen = (ULONG)min((len - (tp.item->key.offset - startaddr) / Vcb->superblock.sector_size) * sizeof(uint32_t), tp.item->size); + ULONG itemlen = (ULONG)min((len - (tp.item->key.offset - startaddr) / Vcb->superblock.sector_size) * Vcb->csum_size, tp.item->size); - RtlCopyMemory(&checksums[(tp.item->key.offset - startaddr) / Vcb->superblock.sector_size], tp.item->data, itemlen); - RtlClearBits(&bmp, (ULONG)((tp.item->key.offset - startaddr) / Vcb->superblock.sector_size), itemlen / sizeof(uint32_t)); + RtlCopyMemory((uint8_t*)checksums + ((tp.item->key.offset - startaddr) * Vcb->csum_size / Vcb->superblock.sector_size), + tp.item->data, itemlen); + RtlClearBits(&bmp, (ULONG)((tp.item->key.offset - startaddr) / Vcb->superblock.sector_size), itemlen / Vcb->csum_size); } Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(checksums); ExFreePool(bmparr); return; @@ -2698,7 +2739,8 @@ void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, u if (!csum) { // deleted RtlSetBits(&bmp, (ULONG)((address - startaddr) / Vcb->superblock.sector_size), length); } else { - RtlCopyMemory(&checksums[(address - startaddr) / Vcb->superblock.sector_size], csum, length * sizeof(uint32_t)); + RtlCopyMemory((uint8_t*)checksums + ((address - startaddr) * Vcb->csum_size / Vcb->superblock.sector_size), + csum, length * Vcb->csum_size); RtlClearBits(&bmp, (ULONG)((address - startaddr) / Vcb->superblock.sector_size), length); } @@ -2718,14 +2760,14 @@ void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, u do { uint16_t rl; uint64_t off; - uint32_t* data; + void* data; - if (runlength * sizeof(uint32_t) > MAX_CSUM_SIZE) - rl = MAX_CSUM_SIZE / sizeof(uint32_t); + if (runlength * Vcb->csum_size > MAX_CSUM_SIZE) + rl = (uint16_t)(MAX_CSUM_SIZE / Vcb->csum_size); else rl = (uint16_t)runlength; - data = ExAllocatePoolWithTag(PagedPool, sizeof(uint32_t) * rl, ALLOC_TAG); + data = ExAllocatePoolWithTag(PagedPool, Vcb->csum_size * rl, ALLOC_TAG); if (!data) { ERR("out of memory\n"); ExFreePool(bmparr); @@ -2733,13 +2775,13 @@ void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, u return; } - RtlCopyMemory(data, &checksums[index], sizeof(uint32_t) * rl); + RtlCopyMemory(data, (uint8_t*)checksums + (Vcb->csum_size * index), Vcb->csum_size * rl); off = startaddr + UInt32x32To64(index, Vcb->superblock.sector_size); - Status = insert_tree_item(Vcb, Vcb->checksum_root, EXTENT_CSUM_ID, TYPE_EXTENT_CSUM, off, data, sizeof(uint32_t) * rl, NULL, Irp); + Status = insert_tree_item(Vcb, Vcb->checksum_root, EXTENT_CSUM_ID, TYPE_EXTENT_CSUM, off, data, Vcb->csum_size * rl, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(data); ExFreePool(bmparr); ExFreePool(checksums); @@ -2779,7 +2821,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* Status = load_cache_chunk(Vcb, c, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); release_chunk_lock(c, Vcb); goto end; } @@ -2792,7 +2834,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* Status = flush_changed_extent(Vcb, c, ce, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("flush_changed_extent returned %08x\n", Status); + ERR("flush_changed_extent returned %08lx\n", Status); release_chunk_lock(c, Vcb); goto end; } @@ -2805,7 +2847,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* if (c->created) { Status = create_chunk(Vcb, c, Irp); if (!NT_SUCCESS(Status)) { - ERR("create_chunk returned %08x\n", Status); + ERR("create_chunk returned %08lx\n", Status); release_chunk_lock(c, Vcb); goto end; } @@ -2819,7 +2861,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* Status = flush_fcb(c->old_cache, false, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("flush_fcb returned %08x\n", Status); + ERR("flush_fcb returned %08lx\n", Status); release_chunk_lock(c, Vcb); clear_batch_list(Vcb, &batchlist); goto end; @@ -2827,7 +2869,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* Status = commit_batch_list(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list returned %08x\n", Status); + ERR("commit_batch_list returned %08lx\n", Status); release_chunk_lock(c, Vcb); goto end; } @@ -2851,7 +2893,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); release_chunk_lock(c, Vcb); goto end; } @@ -2864,7 +2906,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* } if (tp.item->size < sizeof(BLOCK_GROUP_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(BLOCK_GROUP_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(BLOCK_GROUP_ITEM)); Status = STATUS_INTERNAL_ERROR; release_chunk_lock(c, Vcb); goto end; @@ -2892,7 +2934,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(bgi); release_chunk_lock(c, Vcb); goto end; @@ -2900,7 +2942,7 @@ static NTSTATUS update_chunk_usage(device_extension* Vcb, PIRP Irp, LIST_ENTRY* Status = insert_tree_item(Vcb, Vcb->extent_root, searchkey.obj_id, searchkey.obj_type, searchkey.offset, bgi, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(bgi); release_chunk_lock(c, Vcb); goto end; @@ -3186,7 +3228,7 @@ static NTSTATUS split_tree(device_extension* Vcb, tree* t) { ds = sizeof(internal_node); if (numitems == 0 && ds > Vcb->superblock.node_size - sizeof(tree_header)) { - ERR("(%I64x,%x,%I64x) in tree %I64x is too large (%x > %x)\n", + ERR("(%I64x,%x,%I64x) in tree %I64x is too large (%x > %Ix)\n", td->key.obj_id, td->key.obj_type, td->key.offset, t->root->id, ds, Vcb->superblock.node_size - sizeof(tree_header)); return STATUS_INTERNAL_ERROR; @@ -3227,7 +3269,7 @@ bool is_tree_unique(device_extension* Vcb, tree* t, PIRP Irp) { Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -3300,7 +3342,7 @@ static NTSTATUS try_tree_amalgamate(device_extension* Vcb, tree* t, bool* done, if (!nextparitem->treeholder.tree) { Status = do_load_tree(Vcb, &nextparitem->treeholder, t->root, t->parent, nextparitem, NULL); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return Status; } } @@ -3313,7 +3355,7 @@ static NTSTATUS try_tree_amalgamate(device_extension* Vcb, tree* t, bool* done, if (!next_tree->updated_extents && next_tree->has_address) { Status = update_tree_extents(Vcb, next_tree, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_tree_extents returned %08x\n", Status); + ERR("update_tree_extents returned %08lx\n", Status); return Status; } } @@ -3377,14 +3419,14 @@ static NTSTATUS try_tree_amalgamate(device_extension* Vcb, tree* t, bool* done, Status = reduce_tree_extent(Vcb, next_tree->new_address, next_tree, next_tree->parent->header.tree_id, next_tree->header.level, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("reduce_tree_extent returned %08x\n", Status); + ERR("reduce_tree_extent returned %08lx\n", Status); return Status; } } else if (next_tree->has_address) { Status = reduce_tree_extent(Vcb, next_tree->header.address, next_tree, next_tree->parent->header.tree_id, next_tree->header.level, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("reduce_tree_extent returned %08x\n", Status); + ERR("reduce_tree_extent returned %08lx\n", Status); return Status; } } @@ -3511,7 +3553,7 @@ static NTSTATUS update_extent_level(device_extension* Vcb, uint64_t address, tre Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -3532,14 +3574,14 @@ static NTSTATUS update_extent_level(device_extension* Vcb, uint64_t address, tre Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); if (eism) ExFreePool(eism); return Status; } Status = insert_tree_item(Vcb, Vcb->extent_root, address, TYPE_METADATA_ITEM, level, eism, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); if (eism) ExFreePool(eism); return Status; } @@ -3554,7 +3596,7 @@ static NTSTATUS update_extent_level(device_extension* Vcb, uint64_t address, tre Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -3562,7 +3604,7 @@ static NTSTATUS update_extent_level(device_extension* Vcb, uint64_t address, tre EXTENT_ITEM_TREE* eit; if (tp.item->size < sizeof(EXTENT_ITEM_TREE)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM_TREE)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM_TREE)); return STATUS_INTERNAL_ERROR; } @@ -3577,7 +3619,7 @@ static NTSTATUS update_extent_level(device_extension* Vcb, uint64_t address, tre Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(eit); return Status; } @@ -3586,7 +3628,7 @@ static NTSTATUS update_extent_level(device_extension* Vcb, uint64_t address, tre Status = insert_tree_item(Vcb, Vcb->extent_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, eit, tp.item->size, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(eit); return Status; } @@ -3610,7 +3652,7 @@ static NTSTATUS update_tree_extents_recursive(device_extension* Vcb, tree* t, PI Status = update_tree_extents(Vcb, t, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_tree_extents returned %08x\n", Status); + ERR("update_tree_extents returned %08lx\n", Status); return Status; } @@ -3633,7 +3675,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) empty = true; - TRACE("doing level %u\n", level); + TRACE("doing level %lu\n", level); le = Vcb->trees.Flink; @@ -3657,7 +3699,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = reduce_tree_extent(Vcb, t->new_address, t, t->parent->header.tree_id, t->header.level, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("reduce_tree_extent returned %08x\n", Status); + ERR("reduce_tree_extent returned %08lx\n", Status); return Status; } @@ -3666,7 +3708,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = reduce_tree_extent(Vcb,t->header.address, t, t->parent->header.tree_id, t->header.level, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("reduce_tree_extent returned %08x\n", Status); + ERR("reduce_tree_extent returned %08lx\n", Status); return Status; } @@ -3689,7 +3731,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = update_extent_level(Vcb, t->new_address, t, 0, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_extent_level returned %08x\n", Status); + ERR("update_extent_level returned %08lx\n", Status); return Status; } } @@ -3697,12 +3739,12 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) t->header.level = 0; } } else if (t->size > Vcb->superblock.node_size - sizeof(tree_header)) { - TRACE("splitting overlarge tree (%x > %x)\n", t->size, Vcb->superblock.node_size - sizeof(tree_header)); + TRACE("splitting overlarge tree (%x > %Ix)\n", t->size, Vcb->superblock.node_size - sizeof(tree_header)); if (!t->updated_extents && t->has_address) { Status = update_tree_extents_recursive(Vcb, t, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_tree_extents_recursive returned %08x\n", Status); + ERR("update_tree_extents_recursive returned %08lx\n", Status); return Status; } } @@ -3710,7 +3752,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = split_tree(Vcb, t); if (!NT_SUCCESS(Status)) { - ERR("split_tree returned %08x\n", Status); + ERR("split_tree returned %08lx\n", Status); return Status; } } @@ -3722,7 +3764,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) if (!empty) { max_level = level; } else { - TRACE("nothing found for level %u\n", level); + TRACE("nothing found for level %lu\n", level); break; } } @@ -3744,7 +3786,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) do { Status = try_tree_amalgamate(Vcb, t, &done, &done_deletions, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("try_tree_amalgamate returned %08x\n", Status); + ERR("try_tree_amalgamate returned %08lx\n", Status); return Status; } } while (done && t->size < min_size); @@ -3784,7 +3826,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = reduce_tree_extent(Vcb, t->new_address, t, t->header.tree_id, t->header.level, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("reduce_tree_extent returned %08x\n", Status); + ERR("reduce_tree_extent returned %08lx\n", Status); return Status; } @@ -3793,7 +3835,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = reduce_tree_extent(Vcb,t->header.address, t, t->header.tree_id, t->header.level, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("reduce_tree_extent returned %08x\n", Status); + ERR("reduce_tree_extent returned %08lx\n", Status); return Status; } @@ -3806,7 +3848,7 @@ static NTSTATUS do_splits(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = find_item(Vcb, t->root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } } @@ -3851,7 +3893,7 @@ static NTSTATUS remove_root_extents(device_extension* Vcb, root* r, tree_holder* Status = read_data(Vcb, th->address, Vcb->superblock.node_size, NULL, true, buf, NULL, &c, Irp, th->generation, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned 0x%08x\n", Status); + ERR("read_data returned 0x%08lx\n", Status); ExFreePool(buf); return Status; } @@ -3862,7 +3904,7 @@ static NTSTATUS remove_root_extents(device_extension* Vcb, root* r, tree_holder* ExFreePool(buf); if (!NT_SUCCESS(Status)) { - ERR("load_tree(%I64x) returned %08x\n", th->address, Status); + ERR("load_tree(%I64x) returned %08lx\n", th->address, Status); return Status; } } @@ -3877,7 +3919,7 @@ static NTSTATUS remove_root_extents(device_extension* Vcb, root* r, tree_holder* Status = remove_root_extents(Vcb, r, &td->treeholder, th->tree->header.level - 1, th->tree, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("remove_root_extents returned %08x\n", Status); + ERR("remove_root_extents returned %08lx\n", Status); return Status; } } @@ -3889,7 +3931,7 @@ static NTSTATUS remove_root_extents(device_extension* Vcb, root* r, tree_holder* if (th->tree && !th->tree->updated_extents && th->tree->has_address) { Status = update_tree_extents(Vcb, th->tree, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_tree_extents returned %08x\n", Status); + ERR("update_tree_extents returned %08lx\n", Status); return Status; } } @@ -3898,7 +3940,7 @@ static NTSTATUS remove_root_extents(device_extension* Vcb, root* r, tree_holder* Status = reduce_tree_extent(Vcb, th->address, NULL, parent ? parent->header.tree_id : r->id, level, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("reduce_tree_extent(%I64x) returned %08x\n", th->address, Status); + ERR("reduce_tree_extent(%I64x) returned %08lx\n", th->address, Status); return Status; } } @@ -3913,7 +3955,7 @@ static NTSTATUS drop_root(device_extension* Vcb, root* r, PIRP Irp, LIST_ENTRY* Status = remove_root_extents(Vcb, r, &r->treeholder, r->root_item.root_level, NULL, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("remove_root_extents returned %08x\n", Status); + ERR("remove_root_extents returned %08lx\n", Status); return Status; } @@ -3926,12 +3968,12 @@ static NTSTATUS drop_root(device_extension* Vcb, root* r, PIRP Irp, LIST_ENTRY* if (searchkey.obj_id != 0 || searchkey.offset != 0) { Status = find_item(Vcb, Vcb->uuid_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - WARN("find_item returned %08x\n", Status); + WARN("find_item returned %08lx\n", Status); } else { if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } else @@ -3946,7 +3988,7 @@ static NTSTATUS drop_root(device_extension* Vcb, root* r, PIRP Irp, LIST_ENTRY* Status = find_item(Vcb, Vcb->uuid_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) - WARN("find_item returned %08x\n", Status); + WARN("find_item returned %08lx\n", Status); else { if (!keycmp(tp.item->key, searchkey)) { if (tp.item->size == sizeof(uint64_t)) { @@ -3955,7 +3997,7 @@ static NTSTATUS drop_root(device_extension* Vcb, root* r, PIRP Irp, LIST_ENTRY* if (*id == r->id) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } @@ -3981,7 +4023,7 @@ static NTSTATUS drop_root(device_extension* Vcb, root* r, PIRP Irp, LIST_ENTRY* Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(ne); return Status; } @@ -3989,7 +4031,7 @@ static NTSTATUS drop_root(device_extension* Vcb, root* r, PIRP Irp, LIST_ENTRY* Status = insert_tree_item(Vcb, Vcb->uuid_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, ne, tp.item->size - sizeof(uint64_t), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ne); return Status; } @@ -4012,7 +4054,7 @@ static NTSTATUS drop_root(device_extension* Vcb, root* r, PIRP Irp, LIST_ENTRY* Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -4020,7 +4062,7 @@ static NTSTATUS drop_root(device_extension* Vcb, root* r, PIRP Irp, LIST_ENTRY* Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } else @@ -4044,7 +4086,7 @@ static NTSTATUS drop_roots(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback Status = drop_root(Vcb, r, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("drop_root(%I64x) returned %08x\n", r->id, Status); + ERR("drop_root(%I64x) returned %08lx\n", r->id, Status); return Status; } @@ -4066,7 +4108,7 @@ NTSTATUS update_dev_item(device_extension* Vcb, device* device, PIRP Irp) { Status = find_item(Vcb, Vcb->chunk_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -4077,7 +4119,7 @@ NTSTATUS update_dev_item(device_extension* Vcb, device* device, PIRP Irp) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -4091,7 +4133,7 @@ NTSTATUS update_dev_item(device_extension* Vcb, device* device, PIRP Irp) { Status = insert_tree_item(Vcb, Vcb->chunk_root, 1, TYPE_DEV_ITEM, device->devitem.dev_id, di, sizeof(DEV_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(di); return Status; } @@ -4192,7 +4234,7 @@ static NTSTATUS create_chunk(device_extension* Vcb, chunk* c, PIRP Irp) { if (c->chunk_item->type & BLOCK_FLAG_SYSTEM) { Status = add_to_bootstrap(Vcb, 0x100, TYPE_CHUNK_ITEM, c->offset, ci, c->size); if (!NT_SUCCESS(Status)) { - ERR("add_to_bootstrap returned %08x\n", Status); + ERR("add_to_bootstrap returned %08lx\n", Status); return Status; } } @@ -4224,7 +4266,7 @@ static NTSTATUS create_chunk(device_extension* Vcb, chunk* c, PIRP Irp) { factor = c->chunk_item->num_stripes - 1; else if (c->chunk_item->type & BLOCK_FLAG_RAID6) factor = c->chunk_item->num_stripes - 2; - else // SINGLE, DUPLICATE, RAID1 + else // SINGLE, DUPLICATE, RAID1, RAID1C3, RAID1C4 factor = 1; // add DEV_EXTENTs to tree 4 @@ -4248,7 +4290,7 @@ static NTSTATUS create_chunk(device_extension* Vcb, chunk* c, PIRP Irp) { Status = insert_tree_item(Vcb, Vcb->dev_root, c->devices[i]->devitem.dev_id, TYPE_DEV_EXTENT, cis[i].offset, de, sizeof(DEV_EXTENT), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(de); return Status; } @@ -4256,7 +4298,7 @@ static NTSTATUS create_chunk(device_extension* Vcb, chunk* c, PIRP Irp) { // FIXME - no point in calling this twice for the same device Status = update_dev_item(Vcb, c->devices[i], Irp); if (!NT_SUCCESS(Status)) { - ERR("update_dev_item returned %08x\n", Status); + ERR("update_dev_item returned %08lx\n", Status); return Status; } } @@ -4320,7 +4362,7 @@ static NTSTATUS set_xattr(device_extension* Vcb, LIST_ENTRY* batchlist, root* su Status = insert_tree_item_batch(batchlist, Vcb, subvol, inode, TYPE_XATTR_ITEM, crc32, xa, xasize, Batch_SetXattr); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(xa); return Status; } @@ -4355,7 +4397,7 @@ static NTSTATUS delete_xattr(device_extension* Vcb, LIST_ENTRY* batchlist, root* Status = insert_tree_item_batch(batchlist, Vcb, subvol, inode, TYPE_XATTR_ITEM, crc32, xa, xasize, Batch_DeleteXattr); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(xa); return Status; } @@ -4391,7 +4433,7 @@ static NTSTATUS insert_sparse_extent(fcb* fcb, LIST_ENTRY* batchlist, uint64_t s Status = insert_tree_item_batch(batchlist, fcb->Vcb, fcb->subvol, fcb->inode, TYPE_EXTENT_DATA, start, ed, sizeof(EXTENT_DATA) - 1 + sizeof(EXTENT_DATA2), Batch_Insert); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(ed); return Status; } @@ -4589,7 +4631,7 @@ cont: Status = update_changed_extent_ref(fcb->Vcb, er->chunk, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, -1, fcb->inode_item.flags & BTRFS_INODE_NODATASUM, true, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); goto end; } @@ -4615,7 +4657,7 @@ cont: NTSTATUS Status = load_cache_chunk(fcb->Vcb, er->chunk, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); release_chunk_lock(er->chunk, fcb->Vcb); goto end; } @@ -4645,7 +4687,7 @@ cont: Status = update_changed_extent_ref(fcb->Vcb, er->chunk, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, -1, fcb->inode_item.flags & BTRFS_INODE_NODATASUM, true, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); goto end; } @@ -4669,7 +4711,7 @@ cont: NTSTATUS Status = load_cache_chunk(fcb->Vcb, er->chunk, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); release_chunk_lock(er->chunk, fcb->Vcb); goto end; } @@ -4741,7 +4783,7 @@ cont: Status = update_changed_extent_ref(fcb->Vcb, er2->chunk, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, -1, fcb->inode_item.flags & BTRFS_INODE_NODATASUM, true, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); goto end; } @@ -4788,14 +4830,14 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { if (fcb->deleted) { Status = delete_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, fcb->adsxattr.Buffer, fcb->adsxattr.Length, fcb->adshash); if (!NT_SUCCESS(Status)) { - ERR("delete_xattr returned %08x\n", Status); + ERR("delete_xattr returned %08lx\n", Status); goto end; } } else { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, fcb->adsxattr.Buffer, fcb->adsxattr.Length, fcb->adshash, (uint8_t*)fcb->adsdata.Buffer, fcb->adsdata.Length); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } } @@ -4807,7 +4849,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { if (fcb->deleted) { Status = insert_tree_item_batch(batchlist, fcb->Vcb, fcb->subvol, fcb->inode, TYPE_INODE_ITEM, 0xffffffffffffffff, NULL, 0, Batch_DeleteInode); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); goto end; } @@ -4815,7 +4857,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = insert_tree_item_batch(batchlist, fcb->Vcb, fcb->subvol, BTRFS_ORPHAN_INODE_OBJID, TYPE_ORPHAN_INODE, fcb->inode, NULL, 0, Batch_Delete); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); goto end; } } @@ -4892,18 +4934,18 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { if (ext->extent_data.compression == BTRFS_COMPRESSION_NONE && ext->csum) { ULONG len = (ULONG)((ed2->num_bytes + ned2->num_bytes) / fcb->Vcb->superblock.sector_size); - uint32_t* csum; + void* csum; - csum = ExAllocatePoolWithTag(NonPagedPool, len * sizeof(uint32_t), ALLOC_TAG); + csum = ExAllocatePoolWithTag(NonPagedPool, len * fcb->Vcb->csum_size, ALLOC_TAG); if (!csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto end; } - RtlCopyMemory(csum, ext->csum, (ULONG)(ed2->num_bytes * sizeof(uint32_t) / fcb->Vcb->superblock.sector_size)); - RtlCopyMemory(&csum[ed2->num_bytes / fcb->Vcb->superblock.sector_size], nextext->csum, - (ULONG)(ned2->num_bytes * sizeof(uint32_t) / fcb->Vcb->superblock.sector_size)); + RtlCopyMemory(csum, ext->csum, (ULONG)(ed2->num_bytes * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size)); + RtlCopyMemory((uint8_t*)csum + (ed2->num_bytes * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size), nextext->csum, + (ULONG)(ned2->num_bytes * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size)); ExFreePool(ext->csum); ext->csum = csum; @@ -4927,7 +4969,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = update_changed_extent_ref(fcb->Vcb, c, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, -1, fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); goto end; } } @@ -4946,7 +4988,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = insert_tree_item_batch(batchlist, fcb->Vcb, fcb->subvol, fcb->inode, TYPE_EXTENT_DATA, 0, NULL, 0, Batch_DeleteExtentData); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); goto end; } } @@ -4965,7 +5007,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { if (!(fcb->Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_NO_HOLES) && ext->offset > last_end) { Status = insert_sparse_extent(fcb, batchlist, last_end, ext->offset - last_end); if (!NT_SUCCESS(Status)) { - ERR("insert_sparse_extent returned %08x\n", Status); + ERR("insert_sparse_extent returned %08lx\n", Status); goto end; } } @@ -4982,7 +5024,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = insert_tree_item_batch(batchlist, fcb->Vcb, fcb->subvol, fcb->inode, TYPE_EXTENT_DATA, ext->offset, ed, ext->datalen, Batch_Insert); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); goto end; } @@ -5009,7 +5051,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { sector_align(fcb->inode_item.st_size, fcb->Vcb->superblock.sector_size) > last_end) { Status = insert_sparse_extent(fcb, batchlist, last_end, sector_align(fcb->inode_item.st_size, fcb->Vcb->superblock.sector_size) - last_end); if (!NT_SUCCESS(Status)) { - ERR("insert_sparse_extent returned %08x\n", Status); + ERR("insert_sparse_extent returned %08lx\n", Status); goto end; } } @@ -5033,7 +5075,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = find_item(fcb->Vcb, fcb->subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -5050,7 +5092,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = insert_tree_item(fcb->Vcb, fcb->subvol, fcb->inode, TYPE_INODE_ITEM, 0, ii, sizeof(INODE_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); goto end; } @@ -5073,7 +5115,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { if (!cache) { Status = delete_tree_item(fcb->Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); goto end; } } else { @@ -5083,7 +5125,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = find_item(fcb->Vcb, fcb->subvol, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -5119,7 +5161,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = insert_tree_item_batch(batchlist, fcb->Vcb, fcb->subvol, fcb->inode, TYPE_INODE_ITEM, ii_offset, ii, sizeof(INODE_ITEM), Batch_Insert); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); goto end; } @@ -5131,13 +5173,13 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_NTACL, sizeof(EA_NTACL) - 1, EA_NTACL_HASH, (uint8_t*)fcb->sd, (uint16_t)RtlLengthSecurityDescriptor(fcb->sd)); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } } else { Status = delete_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_NTACL, sizeof(EA_NTACL) - 1, EA_NTACL_HASH); if (!NT_SUCCESS(Status)) { - ERR("delete_xattr returned %08x\n", Status); + ERR("delete_xattr returned %08lx\n", Status); goto end; } } @@ -5173,13 +5215,13 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_DOSATTRIB, sizeof(EA_DOSATTRIB) - 1, EA_DOSATTRIB_HASH, val2, (uint16_t)(val + sizeof(val) - val2)); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } } else { Status = delete_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_DOSATTRIB, sizeof(EA_DOSATTRIB) - 1, EA_DOSATTRIB_HASH); if (!NT_SUCCESS(Status)) { - ERR("delete_xattr returned %08x\n", Status); + ERR("delete_xattr returned %08lx\n", Status); goto end; } } @@ -5193,13 +5235,13 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_REPARSE, sizeof(EA_REPARSE) - 1, EA_REPARSE_HASH, (uint8_t*)fcb->reparse_xattr.Buffer, (uint16_t)fcb->reparse_xattr.Length); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } } else { Status = delete_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_REPARSE, sizeof(EA_REPARSE) - 1, EA_REPARSE_HASH); if (!NT_SUCCESS(Status)) { - ERR("delete_xattr returned %08x\n", Status); + ERR("delete_xattr returned %08lx\n", Status); goto end; } } @@ -5212,13 +5254,13 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_EA, sizeof(EA_EA) - 1, EA_EA_HASH, (uint8_t*)fcb->ea_xattr.Buffer, (uint16_t)fcb->ea_xattr.Length); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } } else { Status = delete_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_EA, sizeof(EA_EA) - 1, EA_EA_HASH); if (!NT_SUCCESS(Status)) { - ERR("delete_xattr returned %08x\n", Status); + ERR("delete_xattr returned %08lx\n", Status); goto end; } } @@ -5230,7 +5272,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { if (fcb->prop_compression == PropCompression_None) { Status = delete_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_PROP_COMPRESSION, sizeof(EA_PROP_COMPRESSION) - 1, EA_PROP_COMPRESSION_HASH); if (!NT_SUCCESS(Status)) { - ERR("delete_xattr returned %08x\n", Status); + ERR("delete_xattr returned %08lx\n", Status); goto end; } } else if (fcb->prop_compression == PropCompression_Zlib) { @@ -5239,7 +5281,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_PROP_COMPRESSION, sizeof(EA_PROP_COMPRESSION) - 1, EA_PROP_COMPRESSION_HASH, (uint8_t*)zlib, sizeof(zlib) - 1); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } } else if (fcb->prop_compression == PropCompression_LZO) { @@ -5248,7 +5290,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_PROP_COMPRESSION, sizeof(EA_PROP_COMPRESSION) - 1, EA_PROP_COMPRESSION_HASH, (uint8_t*)lzo, sizeof(lzo) - 1); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } } else if (fcb->prop_compression == PropCompression_ZSTD) { @@ -5257,7 +5299,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_PROP_COMPRESSION, sizeof(EA_PROP_COMPRESSION) - 1, EA_PROP_COMPRESSION_HASH, (uint8_t*)zstd, sizeof(zstd) - 1); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } } @@ -5279,7 +5321,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { if (xa->valuelen == 0) { Status = delete_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, xa->data, xa->namelen, hash); if (!NT_SUCCESS(Status)) { - ERR("delete_xattr returned %08x\n", Status); + ERR("delete_xattr returned %08lx\n", Status); goto end; } @@ -5289,7 +5331,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, xa->data, xa->namelen, hash, (uint8_t*)&xa->data[xa->namelen], xa->valuelen); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } @@ -5307,7 +5349,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = delete_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_CASE_SENSITIVE, sizeof(EA_CASE_SENSITIVE) - 1, EA_CASE_SENSITIVE_HASH); if (!NT_SUCCESS(Status)) { - ERR("delete_xattr returned %08x\n", Status); + ERR("delete_xattr returned %08lx\n", Status); goto end; } @@ -5316,7 +5358,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = set_xattr(fcb->Vcb, batchlist, fcb->subvol, fcb->inode, EA_CASE_SENSITIVE, sizeof(EA_CASE_SENSITIVE) - 1, EA_CASE_SENSITIVE_HASH, (uint8_t*)"1", 1); if (!NT_SUCCESS(Status)) { - ERR("set_xattr returned %08x\n", Status); + ERR("set_xattr returned %08lx\n", Status); goto end; } @@ -5327,7 +5369,7 @@ NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp) { Status = insert_tree_item_batch(batchlist, fcb->Vcb, fcb->subvol, BTRFS_ORPHAN_INODE_OBJID, TYPE_ORPHAN_INODE, fcb->inode, NULL, 0, Batch_Insert); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); goto end; } @@ -5400,7 +5442,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis factor = c->chunk_item->num_stripes - 1; else if (c->chunk_item->type & BLOCK_FLAG_RAID6) factor = c->chunk_item->num_stripes - 2; - else // SINGLE, DUPLICATE, RAID1 + else // SINGLE, DUPLICATE, RAID1, RAID1C3, RAID1C4 factor = 1; // do TRIM @@ -5417,7 +5459,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = load_stored_free_space_cache(Vcb, c, true, Irp); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) - WARN("load_stored_free_space_cache returned %08x\n", Status); + WARN("load_stored_free_space_cache returned %08lx\n", Status); } // remove free space cache @@ -5426,7 +5468,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = excise_extents(Vcb, c->cache, 0, c->cache->inode_item.st_size, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); return Status; } @@ -5438,7 +5480,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis reap_fcb(c->cache); if (!NT_SUCCESS(Status)) { - ERR("flush_fcb returned %08x\n", Status); + ERR("flush_fcb returned %08lx\n", Status); return Status; } @@ -5448,14 +5490,14 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } @@ -5465,7 +5507,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = insert_tree_item_batch(batchlist, Vcb, Vcb->space_root, c->offset, TYPE_FREE_SPACE_INFO, c->chunk_item->size, NULL, 0, Batch_DeleteFreeSpace); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); return Status; } } @@ -5479,14 +5521,14 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = find_item(Vcb, Vcb->dev_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -5528,14 +5570,14 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = find_item(Vcb, Vcb->chunk_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -5549,7 +5591,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = insert_tree_item(Vcb, Vcb->chunk_root, 1, TYPE_DEV_ITEM, c->devices[i]->devitem.dev_id, di, sizeof(DEV_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } } @@ -5569,7 +5611,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = find_item(Vcb, Vcb->chunk_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -5577,7 +5619,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } else @@ -5590,7 +5632,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -5598,7 +5640,7 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } else @@ -5632,11 +5674,33 @@ static NTSTATUS drop_chunk(device_extension* Vcb, chunk* c, LIST_ENTRY* batchlis Vcb->superblock.incompat_flags &= ~BTRFS_INCOMPAT_FLAGS_RAID56; } + // clear raid1c34 incompat flag if dropping last RAID5/6 chunk + + if (c->chunk_item->type & BLOCK_FLAG_RAID1C3 || c->chunk_item->type & BLOCK_FLAG_RAID1C4) { + LIST_ENTRY* le; + bool clear_flag = true; + + le = Vcb->chunks.Flink; + while (le != &Vcb->chunks) { + chunk* c2 = CONTAINING_RECORD(le, chunk, list_entry); + + if (c2->chunk_item->type & BLOCK_FLAG_RAID1C3 || c2->chunk_item->type & BLOCK_FLAG_RAID1C4) { + clear_flag = false; + break; + } + + le = le->Flink; + } + + if (clear_flag) + Vcb->superblock.incompat_flags &= ~BTRFS_INCOMPAT_FLAGS_RAID1C34; + } + #ifndef __REACTOS__ uint64_t phys_used = chunk_estimate_phys_size(Vcb, c, c->oldused); #else phys_used = chunk_estimate_phys_size(Vcb, c, c->oldused); -#endif +#endif // __REACTOS__ if (phys_used < Vcb->superblock.bytes_used) Vcb->superblock.bytes_used -= phys_used; @@ -5687,7 +5751,7 @@ static NTSTATUS partial_stripe_read(device_extension* Vcb, chunk* c, partial_str Status = sync_read_phys(c->devices[stripe]->devobj, c->devices[stripe]->fileobj, cis[stripe].offset + startoff + ((offset % sl) * Vcb->superblock.sector_size), readlen * Vcb->superblock.sector_size, ps->data + (offset * Vcb->superblock.sector_size), false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); return Status; } } else if (c->chunk_item->type & BLOCK_FLAG_RAID5) { @@ -5711,7 +5775,7 @@ static NTSTATUS partial_stripe_read(device_extension* Vcb, chunk* c, partial_str Status = sync_read_phys(c->devices[i]->devobj, c->devices[i]->fileobj, cis[i].offset + startoff + ((offset % sl) * Vcb->superblock.sector_size), readlen * Vcb->superblock.sector_size, ps->data + (offset * Vcb->superblock.sector_size), false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); ExFreePool(scratch); return Status; } @@ -5719,7 +5783,7 @@ static NTSTATUS partial_stripe_read(device_extension* Vcb, chunk* c, partial_str Status = sync_read_phys(c->devices[i]->devobj, c->devices[i]->fileobj, cis[i].offset + startoff + ((offset % sl) * Vcb->superblock.sector_size), readlen * Vcb->superblock.sector_size, scratch, false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); ExFreePool(scratch); return Status; } @@ -5747,7 +5811,7 @@ static NTSTATUS partial_stripe_read(device_extension* Vcb, chunk* c, partial_str Status = sync_read_phys(c->devices[i]->devobj, c->devices[i]->fileobj, cis[i].offset + startoff + ((offset % sl) * Vcb->superblock.sector_size), readlen * Vcb->superblock.sector_size, scratch + (k * readlen * Vcb->superblock.sector_size), false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); num_errors++; error_stripe = k; } @@ -5833,7 +5897,7 @@ NTSTATUS flush_partial_stripe(device_extension* Vcb, chunk* c, partial_stripe* p if (index > last1) { Status = partial_stripe_read(Vcb, c, ps, startoff, parity2, last1, index - last1); if (!NT_SUCCESS(Status)) { - ERR("partial_stripe_read returned %08x\n", Status); + ERR("partial_stripe_read returned %08lx\n", Status); return Status; } } @@ -5846,7 +5910,7 @@ NTSTATUS flush_partial_stripe(device_extension* Vcb, chunk* c, partial_stripe* p if (last1 < ps_length / Vcb->superblock.sector_size) { Status = partial_stripe_read(Vcb, c, ps, startoff, parity2, last1, (ULONG)((ps_length / Vcb->superblock.sector_size) - last1)); if (!NT_SUCCESS(Status)) { - ERR("partial_stripe_read returned %08x\n", Status); + ERR("partial_stripe_read returned %08lx\n", Status); return Status; } } @@ -5889,7 +5953,7 @@ NTSTATUS flush_partial_stripe(device_extension* Vcb, chunk* c, partial_stripe* p if (c->devices[stripe]->devobj) { Status = write_data_phys(c->devices[stripe]->devobj, c->devices[stripe]->fileobj, cis[stripe].offset + startoff, data, stripe_length); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); return Status; } } @@ -5909,7 +5973,7 @@ NTSTATUS flush_partial_stripe(device_extension* Vcb, chunk* c, partial_stripe* p Status = write_data_phys(c->devices[parity2]->devobj, c->devices[parity2]->fileobj, cis[parity2].offset + startoff, ps->data, stripe_length); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); return Status; } } @@ -5948,7 +6012,7 @@ NTSTATUS flush_partial_stripe(device_extension* Vcb, chunk* c, partial_stripe* p if (c->devices[parity1]->devobj) { Status = write_data_phys(c->devices[parity1]->devobj, c->devices[parity1]->fileobj, cis[parity1].offset + startoff, scratch, stripe_length); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); ExFreePool(scratch); return Status; } @@ -5958,7 +6022,7 @@ NTSTATUS flush_partial_stripe(device_extension* Vcb, chunk* c, partial_stripe* p Status = write_data_phys(c->devices[parity2]->devobj, c->devices[parity2]->fileobj, cis[parity2].offset + startoff, scratch + stripe_length, stripe_length); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); ExFreePool(scratch); return Status; } @@ -6004,7 +6068,7 @@ static NTSTATUS update_chunks(device_extension* Vcb, LIST_ENTRY* batchlist, PIRP ExFreePool(ps); if (!NT_SUCCESS(Status)) { - ERR("flush_partial_stripe returned %08x\n", Status); + ERR("flush_partial_stripe returned %08lx\n", Status); ExReleaseResourceLite(&c->partial_stripes_lock); release_chunk_lock(c, Vcb); ExReleaseResourceLite(&Vcb->chunk_lock); @@ -6051,7 +6115,7 @@ static NTSTATUS update_chunks(device_extension* Vcb, LIST_ENTRY* batchlist, PIRP if (used_minus_cache == 0) { Status = drop_chunk(Vcb, c, batchlist, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("drop_chunk returned %08x\n", Status); + ERR("drop_chunk returned %08lx\n", Status); release_chunk_lock(c, Vcb); ExReleaseResourceLite(&Vcb->chunk_lock); return Status; @@ -6063,7 +6127,7 @@ static NTSTATUS update_chunks(device_extension* Vcb, LIST_ENTRY* batchlist, PIRP } else if (c->created) { Status = create_chunk(Vcb, c, Irp); if (!NT_SUCCESS(Status)) { - ERR("create_chunk returned %08x\n", Status); + ERR("create_chunk returned %08lx\n", Status); release_chunk_lock(c, Vcb); ExReleaseResourceLite(&Vcb->chunk_lock); return Status; @@ -6095,13 +6159,13 @@ static NTSTATUS delete_root_ref(device_extension* Vcb, uint64_t subvolid, uint64 Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } if (!keycmp(searchkey, tp.item->key)) { if (tp.item->size < sizeof(ROOT_REF)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(ROOT_REF)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(ROOT_REF)); return STATUS_INTERNAL_ERROR; } else { ROOT_REF* rr; @@ -6125,7 +6189,7 @@ static NTSTATUS delete_root_ref(device_extension* Vcb, uint64_t subvolid, uint64 Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -6153,7 +6217,7 @@ static NTSTATUS delete_root_ref(device_extension* Vcb, uint64_t subvolid, uint64 Status = insert_tree_item(Vcb, Vcb->root_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, newrr, newlen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(newrr); return Status; } @@ -6192,7 +6256,7 @@ static NTSTATUS add_root_ref(_In_ device_extension* Vcb, _In_ uint64_t subvolid, Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -6214,21 +6278,21 @@ static NTSTATUS add_root_ref(_In_ device_extension* Vcb, _In_ uint64_t subvolid, Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(rr2); return Status; } Status = insert_tree_item(Vcb, Vcb->root_root, searchkey.obj_id, searchkey.obj_type, searchkey.offset, rr2, rrsize, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(rr2); return Status; } } else { Status = insert_tree_item(Vcb, Vcb->root_root, searchkey.obj_id, searchkey.obj_type, searchkey.offset, rr, (uint16_t)offsetof(ROOT_REF, name[0]) + rr->n, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(rr); return Status; } @@ -6253,7 +6317,7 @@ static NTSTATUS update_root_backref(device_extension* Vcb, uint64_t subvolid, ui Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -6278,7 +6342,7 @@ static NTSTATUS update_root_backref(device_extension* Vcb, uint64_t subvolid, ui Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); if (datalen > 0) ExFreePool(data); @@ -6289,7 +6353,7 @@ static NTSTATUS update_root_backref(device_extension* Vcb, uint64_t subvolid, ui if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); if (datalen > 0) ExFreePool(data); @@ -6301,7 +6365,7 @@ static NTSTATUS update_root_backref(device_extension* Vcb, uint64_t subvolid, ui if (datalen > 0) { Status = insert_tree_item(Vcb, Vcb->root_root, subvolid, TYPE_ROOT_BACKREF, parsubvolid, data, datalen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(data); return Status; } @@ -6321,7 +6385,7 @@ static NTSTATUS add_root_item_to_cache(device_extension* Vcb, uint64_t root, PIR Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -6344,14 +6408,14 @@ static NTSTATUS add_root_item_to_cache(device_extension* Vcb, uint64_t root, PIR Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(ri); return Status; } Status = insert_tree_item(Vcb, Vcb->root_root, searchkey.obj_id, searchkey.obj_type, tp.item->key.offset, ri, sizeof(ROOT_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ri); return Status; } @@ -6417,14 +6481,14 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->parent->fcb->inode, TYPE_DIR_INDEX, fileref->dc->index, di, disize, Batch_Insert); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); return Status; } Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->parent->fcb->inode, TYPE_DIR_ITEM, crc32, di2, disize, Batch_DirItem); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); return Status; } @@ -6444,7 +6508,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->fcb->subvol, fileref->fcb->inode, TYPE_INODE_REF, fileref->parent->fcb->inode, ir, sizeof(INODE_REF) - 1 + ir->n, Batch_InodeRef); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); return Status; } } else if (fileref->fcb != fileref->fcb->Vcb->dummy_fcb) { @@ -6466,13 +6530,13 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = add_root_ref(fileref->fcb->Vcb, fileref->fcb->subvol->id, fileref->parent->fcb->subvol->id, rr, Irp); if (!NT_SUCCESS(Status)) { - ERR("add_root_ref returned %08x\n", Status); + ERR("add_root_ref returned %08lx\n", Status); return Status; } Status = update_root_backref(fileref->fcb->Vcb, fileref->fcb->subvol->id, fileref->parent->fcb->subvol->id, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_root_backref returned %08x\n", Status); + ERR("update_root_backref returned %08lx\n", Status); return Status; } } @@ -6502,7 +6566,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->parent->fcb->inode, TYPE_DIR_ITEM, crc32, di, sizeof(DIR_ITEM) - 1 + name->Length, Batch_DeleteDirItem); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); return Status; } @@ -6524,19 +6588,19 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->fcb->inode, TYPE_INODE_REF, fileref->parent->fcb->inode, ir, sizeof(INODE_REF) - 1 + name->Length, Batch_DeleteInodeRef); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); return Status; } } else if (fileref->fcb != fileref->fcb->Vcb->dummy_fcb) { // subvolume Status = delete_root_ref(fileref->fcb->Vcb, fileref->fcb->subvol->id, fileref->parent->fcb->subvol->id, fileref->parent->fcb->inode, name, Irp); if (!NT_SUCCESS(Status)) { - ERR("delete_root_ref returned %08x\n", Status); + ERR("delete_root_ref returned %08lx\n", Status); return Status; } Status = update_root_backref(fileref->fcb->Vcb, fileref->fcb->subvol->id, fileref->parent->fcb->subvol->id, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_root_backref returned %08x\n", Status); + ERR("update_root_backref returned %08lx\n", Status); return Status; } } @@ -6546,7 +6610,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->parent->fcb->inode, TYPE_DIR_INDEX, fileref->oldindex, NULL, 0, Batch_Delete); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); return Status; } @@ -6582,7 +6646,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->parent->fcb->inode, TYPE_DIR_ITEM, oldcrc32, olddi, sizeof(DIR_ITEM) - 1 + oldutf8->Length, Batch_DeleteDirItem); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(olddi); return Status; } @@ -6626,7 +6690,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->parent->fcb->inode, TYPE_DIR_ITEM, crc32, di, disize, Batch_DirItem); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(di2); ExFreePool(di); return Status; @@ -6651,7 +6715,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->fcb->subvol, fileref->fcb->inode, TYPE_INODE_REF, fileref->parent->fcb->inode, ir, sizeof(INODE_REF) - 1 + ir->n, Batch_DeleteInodeRef); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(ir); ExFreePool(di2); return Status; @@ -6673,7 +6737,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->fcb->subvol, fileref->fcb->inode, TYPE_INODE_REF, fileref->parent->fcb->inode, ir2, sizeof(INODE_REF) - 1 + ir2->n, Batch_InodeRef); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(ir2); ExFreePool(di2); return Status; @@ -6684,7 +6748,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = delete_root_ref(fileref->fcb->Vcb, fileref->fcb->subvol->id, fileref->parent->fcb->subvol->id, fileref->parent->fcb->inode, oldutf8, Irp); if (!NT_SUCCESS(Status)) { - ERR("delete_root_ref returned %08x\n", Status); + ERR("delete_root_ref returned %08lx\n", Status); ExFreePool(di2); return Status; } @@ -6705,14 +6769,14 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = add_root_ref(fileref->fcb->Vcb, fileref->fcb->subvol->id, fileref->parent->fcb->subvol->id, rr, Irp); if (!NT_SUCCESS(Status)) { - ERR("add_root_ref returned %08x\n", Status); + ERR("add_root_ref returned %08lx\n", Status); ExFreePool(di2); return Status; } Status = update_root_backref(fileref->fcb->Vcb, fileref->fcb->subvol->id, fileref->parent->fcb->subvol->id, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_root_backref returned %08x\n", Status); + ERR("update_root_backref returned %08lx\n", Status); ExFreePool(di2); return Status; } @@ -6723,7 +6787,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->parent->fcb->inode, TYPE_DIR_INDEX, fileref->dc->index, NULL, 0, Batch_Delete); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(di2); return Status; } @@ -6733,7 +6797,7 @@ static NTSTATUS flush_fileref(file_ref* fileref, LIST_ENTRY* batchlist, PIRP Irp Status = insert_tree_item_batch(batchlist, fileref->fcb->Vcb, fileref->parent->fcb->subvol, fileref->parent->fcb->inode, TYPE_DIR_INDEX, fileref->dc->index, di2, disize, Batch_Insert); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(di2); return Status; } @@ -6858,14 +6922,14 @@ static NTSTATUS flush_changed_dev_stats(device_extension* Vcb, device* dev, PIRP Status = find_item(Vcb, Vcb->dev_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } } @@ -6881,7 +6945,7 @@ static NTSTATUS flush_changed_dev_stats(device_extension* Vcb, device* dev, PIRP Status = insert_tree_item(Vcb, Vcb->dev_root, 0, TYPE_DEV_STATS, dev->devitem.dev_id, stats, statslen, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(stats); return Status; } @@ -6903,7 +6967,7 @@ static NTSTATUS flush_subvol(device_extension* Vcb, root* r, PIRP Irp) { Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -6922,13 +6986,13 @@ static NTSTATUS flush_subvol(device_extension* Vcb, root* r, PIRP Irp) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = insert_tree_item(Vcb, Vcb->root_root, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, ri, sizeof(ROOT_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); return Status; } } @@ -6945,7 +7009,7 @@ static NTSTATUS flush_subvol(device_extension* Vcb, root* r, PIRP Irp) { Status = create_root(Vcb, BTRFS_ROOT_UUID, &uuid_root, false, 0, Irp); if (!NT_SUCCESS(Status)) { - ERR("create_root returned %08x\n", Status); + ERR("create_root returned %08lx\n", Status); return Status; } @@ -6958,7 +7022,7 @@ static NTSTATUS flush_subvol(device_extension* Vcb, root* r, PIRP Irp) { Status = find_item(Vcb, Vcb->uuid_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -6977,14 +7041,14 @@ static NTSTATUS flush_subvol(device_extension* Vcb, root* r, PIRP Irp) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(ids); return Status; } Status = insert_tree_item(Vcb, Vcb->uuid_root, searchkey.obj_id, searchkey.obj_type, searchkey.offset, ids, tp.item->size + sizeof(uint64_t), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ids); return Status; } @@ -7002,7 +7066,7 @@ static NTSTATUS flush_subvol(device_extension* Vcb, root* r, PIRP Irp) { Status = insert_tree_item(Vcb, Vcb->uuid_root, searchkey.obj_id, searchkey.obj_type, searchkey.offset, root_num, sizeof(uint64_t), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(root_num); return Status; } @@ -7128,6 +7192,61 @@ static NTSTATUS test_not_full(device_extension* Vcb) { le = le->Flink; } + } else if (Vcb->metadata_flags & BLOCK_FLAG_RAID1C3) { + uint64_t s1 = 0, s2 = 0, s3 = 0; + + le = Vcb->devices.Flink; + while (le != &Vcb->devices) { + device* dev = CONTAINING_RECORD(le, device, list_entry); + + if (!dev->readonly) { + uint64_t space = dev->devitem.num_bytes - dev->devitem.bytes_used; + + if (space >= s1) { + s3 = s2; + s2 = s1; + s1 = space; + } else if (space >= s2) { + s3 = s2; + s2 = space; + } else if (space >= s3) + s3 = space; + } + + le = le->Flink; + } + + could_alloc = s3; + } else if (Vcb->metadata_flags & BLOCK_FLAG_RAID1C4) { + uint64_t s1 = 0, s2 = 0, s3 = 0, s4 = 0; + + le = Vcb->devices.Flink; + while (le != &Vcb->devices) { + device* dev = CONTAINING_RECORD(le, device, list_entry); + + if (!dev->readonly) { + uint64_t space = dev->devitem.num_bytes - dev->devitem.bytes_used; + + if (space >= s1) { + s4 = s3; + s3 = s2; + s2 = s1; + s1 = space; + } else if (space >= s2) { + s4 = s3; + s3 = s2; + s2 = space; + } else if (space >= s3) { + s4 = s3; + s3 = space; + } else if (space >= s4) + s4 = space; + } + + le = le->Flink; + } + + could_alloc = s4; } else { // SINGLE le = Vcb->devices.Flink; while (le != &Vcb->devices) { @@ -7181,7 +7300,7 @@ static NTSTATUS check_for_orphans_root(device_extension* Vcb, root* r, PIRP Irp) Status = find_item(Vcb, r, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -7198,13 +7317,13 @@ static NTSTATUS check_for_orphans_root(device_extension* Vcb, root* r, PIRP Irp) Status = open_fcb(Vcb, r, tp.item->key.offset, 0, NULL, false, NULL, &fcb, PagedPool, Irp); if (!NT_SUCCESS(Status)) - ERR("open_fcb returned %08x\n", Status); + ERR("open_fcb returned %08lx\n", Status); else { if (fcb->inode_item.st_nlink == 0) { if (fcb->type != BTRFS_TYPE_DIRECTORY && fcb->inode_item.st_size > 0) { Status = excise_extents(Vcb, fcb, 0, sector_align(fcb->inode_item.st_size, Vcb->superblock.sector_size), Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); goto end; } } @@ -7218,7 +7337,7 @@ static NTSTATUS check_for_orphans_root(device_extension* Vcb, root* r, PIRP Irp) Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); goto end; } } @@ -7254,7 +7373,7 @@ static NTSTATUS check_for_orphans(device_extension* Vcb, PIRP Irp) { if (!fr->fcb->subvol->checked_for_orphans) { Status = check_for_orphans_root(Vcb, fr->fcb->subvol, Irp); if (!NT_SUCCESS(Status)) { - ERR("check_for_orphans_root returned %08x\n", Status); + ERR("check_for_orphans_root returned %08lx\n", Status); return Status; } @@ -7291,7 +7410,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = check_for_orphans(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("check_for_orphans returned %08x\n", Status); + ERR("check_for_orphans returned %08lx\n", Status); return Status; } @@ -7312,7 +7431,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = commit_batch_list(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list returned %08x\n", Status); + ERR("commit_batch_list returned %08lx\n", Status); return Status; } @@ -7344,7 +7463,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) free_fcb(fcb); if (!NT_SUCCESS(Status)) { - ERR("flush_fcb returned %08x\n", Status); + ERR("flush_fcb returned %08lx\n", Status); clear_batch_list(Vcb, &batchlist); ExReleaseResourceLite(&Vcb->dirty_fcbs_lock); return Status; @@ -7360,7 +7479,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = commit_batch_list(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list returned %08x\n", Status); + ERR("commit_batch_list returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->dirty_fcbs_lock); return Status; } @@ -7377,7 +7496,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) free_fcb(fcb); if (!NT_SUCCESS(Status)) { - ERR("flush_fcb returned %08x\n", Status); + ERR("flush_fcb returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->dirty_fcbs_lock); return Status; } @@ -7394,7 +7513,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = commit_batch_list(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list returned %08x\n", Status); + ERR("commit_batch_list returned %08lx\n", Status); return Status; } @@ -7410,7 +7529,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = flush_subvol(Vcb, r, Irp); if (!NT_SUCCESS(Status)) { - ERR("flush_subvol returned %08x\n", Status); + ERR("flush_subvol returned %08lx\n", Status); return Status; } } @@ -7419,7 +7538,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = drop_roots(Vcb, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("drop_roots returned %08x\n", Status); + ERR("drop_roots returned %08lx\n", Status); return Status; } } @@ -7427,7 +7546,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = update_chunks(Vcb, &batchlist, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_chunks returned %08x\n", Status); + ERR("update_chunks returned %08lx\n", Status); return Status; } @@ -7446,7 +7565,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -7456,7 +7575,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) // make sure we always update the extent tree Status = add_root_item_to_cache(Vcb, BTRFS_ROOT_EXTENT, Irp); if (!NT_SUCCESS(Status)) { - ERR("add_root_item_to_cache returned %08x\n", Status); + ERR("add_root_item_to_cache returned %08lx\n", Status); return Status; } @@ -7468,7 +7587,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) if (dev->stats_changed) { Status = flush_changed_dev_stats(Vcb, dev, Irp); if (!NT_SUCCESS(Status)) { - ERR("flush_changed_dev_stats returned %08x\n", Status); + ERR("flush_changed_dev_stats returned %08lx\n", Status); return Status; } dev->stats_changed = false; @@ -7483,25 +7602,25 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) do { Status = add_parents(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("add_parents returned %08x\n", Status); + ERR("add_parents returned %08lx\n", Status); goto end; } Status = allocate_tree_extents(Vcb, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("allocate_tree_extents returned %08x\n", Status); + ERR("allocate_tree_extents returned %08lx\n", Status); goto end; } Status = do_splits(Vcb, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("do_splits returned %08x\n", Status); + ERR("do_splits returned %08lx\n", Status); goto end; } Status = update_chunk_usage(Vcb, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_chunk_usage returned %08x\n", Status); + ERR("update_chunk_usage returned %08lx\n", Status); goto end; } @@ -7509,7 +7628,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) if (!no_cache) { Status = allocate_cache(Vcb, &cache_changed, Irp, rollback); if (!NT_SUCCESS(Status)) { - WARN("allocate_cache returned %08x\n", Status); + WARN("allocate_cache returned %08lx\n", Status); no_cache = true; cache_changed = false; } @@ -7517,7 +7636,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) } else { Status = update_chunk_caches_tree(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_chunk_caches_tree returned %08x\n", Status); + ERR("update_chunk_caches_tree returned %08lx\n", Status); goto end; } } @@ -7538,19 +7657,19 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = update_root_root(Vcb, no_cache, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("update_root_root returned %08x\n", Status); + ERR("update_root_root returned %08lx\n", Status); goto end; } Status = write_trees(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("write_trees returned %08x\n", Status); + ERR("write_trees returned %08lx\n", Status); goto end; } Status = test_not_full(Vcb); if (!NT_SUCCESS(Status)) { - ERR("test_not_full returned %08x\n", Status); + ERR("test_not_full returned %08lx\n", Status); goto end; } @@ -7567,7 +7686,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -7578,7 +7697,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -7600,7 +7719,7 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) Status = write_superblocks(Vcb, Irp); if (!NT_SUCCESS(Status)) { - ERR("write_superblocks returned %08x\n", Status); + ERR("write_superblocks returned %08lx\n", Status); goto end; } @@ -7653,13 +7772,16 @@ static NTSTATUS do_write2(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback) while (!IsListEmpty(&Vcb->drop_roots)) { root* r = CONTAINING_RECORD(RemoveHeadList(&Vcb->drop_roots), root, list_entry); - ExDeleteResourceLite(&r->nonpaged->load_tree_lock); - ExFreePool(r->nonpaged); - ExFreePool(r); + if (IsListEmpty(&r->fcbs)) { + ExDeleteResourceLite(&r->nonpaged->load_tree_lock); + ExFreePool(r->nonpaged); + ExFreePool(r); + } else + r->dropped = true; } end: - TRACE("do_write returning %08x\n", Status); + TRACE("do_write returning %08lx\n", Status); return Status; } @@ -7673,7 +7795,7 @@ NTSTATUS do_write(device_extension* Vcb, PIRP Irp) { Status = do_write2(Vcb, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("do_write2 returned %08x, dropping into readonly mode\n", Status); + ERR("do_write2 returned %08lx, dropping into readonly mode\n", Status); Vcb->readonly = true; FsRtlNotifyVolumeEvent(Vcb->root_file, FSRTL_VOLUME_FORCED_CLOSED); do_rollback(Vcb, &rollback); @@ -7696,7 +7818,7 @@ static void do_flush(device_extension* Vcb) { free_trees(Vcb); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->tree_lock); } diff --git a/drivers/filesystems/btrfs/free-space.c b/drivers/filesystems/btrfs/free-space.c index 56f94faec9f..62a912f2a6c 100644 --- a/drivers/filesystems/btrfs/free-space.c +++ b/drivers/filesystems/btrfs/free-space.c @@ -16,6 +16,7 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "crc32c.h" // Number of increments in the size of each cache inode, in sectors. Should // this be a constant number of sectors, a constant 256 KB, or what? @@ -27,7 +28,7 @@ static NTSTATUS remove_free_space_inode(device_extension* Vcb, uint64_t inode, L Status = open_fcb(Vcb, Vcb->root_root, inode, BTRFS_TYPE_FILE, NULL, false, NULL, &fcb, PagedPool, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fcb returned %08x\n", Status); + ERR("open_fcb returned %08lx\n", Status); return Status; } @@ -36,7 +37,7 @@ static NTSTATUS remove_free_space_inode(device_extension* Vcb, uint64_t inode, L if (fcb->inode_item.st_size > 0) { Status = excise_extents(fcb->Vcb, fcb, 0, sector_align(fcb->inode_item.st_size, fcb->Vcb->superblock.sector_size), Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); return Status; } } @@ -45,7 +46,7 @@ static NTSTATUS remove_free_space_inode(device_extension* Vcb, uint64_t inode, L Status = flush_fcb(fcb, false, batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("flush_fcb returned %08x\n", Status); + ERR("flush_fcb returned %08lx\n", Status); free_fcb(fcb); return Status; } @@ -70,7 +71,7 @@ NTSTATUS clear_free_space_cache(device_extension* Vcb, LIST_ENTRY* batchlist, PI Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -81,7 +82,7 @@ NTSTATUS clear_free_space_cache(device_extension* Vcb, LIST_ENTRY* batchlist, PI if (tp.item->key.obj_id == searchkey.obj_id && tp.item->key.obj_type == searchkey.obj_type) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -96,7 +97,7 @@ NTSTATUS clear_free_space_cache(device_extension* Vcb, LIST_ENTRY* batchlist, PI Status = remove_free_space_inode(Vcb, fsi->key.obj_id, batchlist, Irp, &rollback); if (!NT_SUCCESS(Status)) - ERR("remove_free_space_inode for (%I64x,%x,%I64x) returned %08x\n", fsi->key.obj_id, fsi->key.obj_type, fsi->key.offset, Status); + ERR("remove_free_space_inode for (%I64x,%x,%I64x) returned %08lx\n", fsi->key.obj_id, fsi->key.obj_type, fsi->key.offset, Status); le = Vcb->chunks.Flink; while (le != &Vcb->chunks) { @@ -111,7 +112,7 @@ NTSTATUS clear_free_space_cache(device_extension* Vcb, LIST_ENTRY* batchlist, PI } } } else - WARN("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); + WARN("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); } b = find_next_item(Vcb, &tp, &next_tp, false, Irp); @@ -133,14 +134,14 @@ NTSTATUS clear_free_space_cache(device_extension* Vcb, LIST_ENTRY* batchlist, PI Status = find_item(Vcb, Vcb->space_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } do { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } @@ -165,7 +166,7 @@ NTSTATUS clear_free_space_cache(device_extension* Vcb, LIST_ENTRY* batchlist, PI Status = load_cache_chunk(Vcb, c, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk(%I64x) returned %08x\n", c->offset, Status); + ERR("load_cache_chunk(%I64x) returned %08lx\n", c->offset, Status); release_chunk_lock(c, Vcb); ExReleaseResourceLite(&Vcb->chunk_lock); return Status; @@ -385,7 +386,7 @@ static NTSTATUS get_superblock_size(chunk* c, uint64_t* size) { Status = add_superblock_stripe(&stripes, off_start / ci->stripe_length, 1); if (!NT_SUCCESS(Status)) { - ERR("add_superblock_stripe returned %08x\n", Status); + ERR("add_superblock_stripe returned %08lx\n", Status); goto end; } } @@ -403,7 +404,7 @@ static NTSTATUS get_superblock_size(chunk* c, uint64_t* size) { Status = add_superblock_stripe(&stripes, off_start / ci->stripe_length, (off_end - off_start) / ci->stripe_length); if (!NT_SUCCESS(Status)) { - ERR("add_superblock_stripe returned %08x\n", Status); + ERR("add_superblock_stripe returned %08lx\n", Status); goto end; } } @@ -421,12 +422,12 @@ static NTSTATUS get_superblock_size(chunk* c, uint64_t* size) { Status = add_superblock_stripe(&stripes, off_start / ci->stripe_length, (off_end - off_start) / ci->stripe_length); if (!NT_SUCCESS(Status)) { - ERR("add_superblock_stripe returned %08x\n", Status); + ERR("add_superblock_stripe returned %08lx\n", Status); goto end; } } } - } else { // SINGLE, DUPLICATE, RAID1 + } else { // SINGLE, DUPLICATE, RAID1, RAID1C3, RAID1C4 for (j = 0; j < ci->num_stripes; j++) { if (cis[j].offset + ci->size > superblock_addrs[i] && cis[j].offset <= superblock_addrs[i] + sizeof(superblock)) { off_start = ((superblock_addrs[i] - cis[j].offset) / c->chunk_item->stripe_length) * c->chunk_item->stripe_length; @@ -434,7 +435,7 @@ static NTSTATUS get_superblock_size(chunk* c, uint64_t* size) { Status = add_superblock_stripe(&stripes, off_start / ci->stripe_length, (off_end - off_start) / ci->stripe_length); if (!NT_SUCCESS(Status)) { - ERR("add_superblock_stripe returned %08x\n", Status); + ERR("add_superblock_stripe returned %08lx\n", Status); goto end; } } @@ -484,7 +485,7 @@ NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -494,7 +495,7 @@ NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load } if (tp.item->size < sizeof(FREE_SPACE_ITEM)) { - WARN("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); + WARN("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); return STATUS_NOT_FOUND; } @@ -511,7 +512,7 @@ NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load Status = open_fcb(Vcb, Vcb->root_root, inode, BTRFS_TYPE_FILE, NULL, false, NULL, &c->cache, PagedPool, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fcb returned %08x\n", Status); + ERR("open_fcb returned %08lx\n", Status); return STATUS_NOT_FOUND; } @@ -548,7 +549,7 @@ NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load Status = read_file(c->cache, data, 0, c->cache->inode_item.st_size, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(data); c->cache->deleted = true; @@ -576,7 +577,7 @@ NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load num_valid_sectors = (ULONG)((sector_align(extent_length, Vcb->superblock.sector_size) / Vcb->superblock.sector_size) + num_bitmaps); if (num_valid_sectors > num_sectors) { - ERR("free space cache for %I64x was %I64x sectors, expected at least %I64x\n", c->offset, num_sectors, num_valid_sectors); + ERR("free space cache for %I64x was %u sectors, expected at least %u\n", c->offset, num_sectors, num_valid_sectors); goto clearcache; } @@ -591,7 +592,7 @@ NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load crc32 = ~calc_crc32c(0xffffffff, &data[sizeof(uint32_t) * num_sectors], ((i + 1) * Vcb->superblock.sector_size) - (sizeof(uint32_t) * num_sectors)); if (crc32 != checksums[i]) { - WARN("checksum %I64u was %08x, expected %08x\n", i, crc32, checksums[i]); + WARN("checksum %u was %08x, expected %08x\n", i, crc32, checksums[i]); goto clearcache; } } @@ -608,7 +609,7 @@ NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load if (fse->type == FREE_SPACE_EXTENT) { Status = add_space_entry(&c->space, &c->space_size, fse->offset, fse->size); if (!NT_SUCCESS(Status)) { - ERR("add_space_entry returned %08x\n", Status); + ERR("add_space_entry returned %08lx\n", Status); ExFreePool(data); return Status; } @@ -645,7 +646,7 @@ NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load Status = get_superblock_size(c, &superblock_size); if (!NT_SUCCESS(Status)) { - ERR("get_superblock_size returned %08x\n", Status); + ERR("get_superblock_size returned %08lx\n", Status); ExFreePool(data); return Status; } @@ -691,13 +692,13 @@ clearcache: Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); return Status; } Status = excise_extents(Vcb, c->cache, 0, c->cache->inode_item.st_size, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); do_rollback(Vcb, &rollback); return Status; } @@ -744,7 +745,7 @@ static NTSTATUS load_stored_free_space_tree(device_extension* Vcb, chunk* c, PIR Status = find_item(Vcb, Vcb->space_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -754,7 +755,7 @@ static NTSTATUS load_stored_free_space_tree(device_extension* Vcb, chunk* c, PIR } if (tp.item->size < sizeof(FREE_SPACE_INFO)) { - WARN("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_INFO)); + WARN("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_INFO)); return STATUS_NOT_FOUND; } @@ -767,7 +768,7 @@ static NTSTATUS load_stored_free_space_tree(device_extension* Vcb, chunk* c, PIR if (tp.item->key.obj_type == TYPE_FREE_SPACE_EXTENT) { Status = add_space_entry(&c->space, &c->space_size, tp.item->key.obj_id, tp.item->key.offset); if (!NT_SUCCESS(Status)) { - ERR("add_space_entry returned %08x\n", Status); + ERR("add_space_entry returned %08lx\n", Status); if (bmparr) ExFreePool(bmparr); return Status; } @@ -780,7 +781,7 @@ static NTSTATUS load_stored_free_space_tree(device_extension* Vcb, chunk* c, PIR explen = (ULONG)(tp.item->key.offset / (Vcb->superblock.sector_size * 8)); if (tp.item->size < explen) { - WARN("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, explen); + WARN("(%I64x,%x,%I64x) was %u bytes, expected %lu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, explen); return STATUS_NOT_FOUND; } else if (tp.item->size == 0) { WARN("(%I64x,%x,%I64x) has size of 0\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset); @@ -829,7 +830,7 @@ static NTSTATUS load_stored_free_space_tree(device_extension* Vcb, chunk* c, PIR if (runstart > lastoff) { Status = add_space_entry(&c->space, &c->space_size, lastoff, runstart - lastoff); if (!NT_SUCCESS(Status)) { - ERR("add_space_entry returned %08x\n", Status); + ERR("add_space_entry returned %08lx\n", Status); if (bmparr) ExFreePool(bmparr); return Status; } @@ -843,7 +844,7 @@ static NTSTATUS load_stored_free_space_tree(device_extension* Vcb, chunk* c, PIR if (lastoff < tp.item->key.obj_id + tp.item->key.offset) { Status = add_space_entry(&c->space, &c->space_size, lastoff, tp.item->key.obj_id + tp.item->key.offset - lastoff); if (!NT_SUCCESS(Status)) { - ERR("add_space_entry returned %08x\n", Status); + ERR("add_space_entry returned %08lx\n", Status); if (bmparr) ExFreePool(bmparr); return Status; } @@ -894,14 +895,14 @@ static NTSTATUS load_free_space_cache(device_extension* Vcb, chunk* c, PIRP Irp) Status = load_stored_free_space_tree(Vcb, c, Irp); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) { - ERR("load_stored_free_space_tree returned %08x\n", Status); + ERR("load_stored_free_space_tree returned %08lx\n", Status); return Status; } } else if (Vcb->superblock.generation - 1 == Vcb->superblock.cache_generation) { Status = load_stored_free_space_cache(Vcb, c, false, Irp); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) { - ERR("load_stored_free_space_cache returned %08x\n", Status); + ERR("load_stored_free_space_cache returned %08lx\n", Status); return Status; } } else @@ -916,7 +917,7 @@ static NTSTATUS load_free_space_cache(device_extension* Vcb, chunk* c, PIRP Irp) Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -984,7 +985,7 @@ NTSTATUS load_cache_chunk(device_extension* Vcb, chunk* c, PIRP Irp) { Status = load_free_space_cache(Vcb, c, Irp); if (!NT_SUCCESS(Status)) { - ERR("load_free_space_cache returned %08x\n", Status); + ERR("load_free_space_cache returned %08lx\n", Status); return Status; } @@ -1023,7 +1024,7 @@ static NTSTATUS insert_cache_extent(fcb* fcb, uint64_t start, uint64_t length, L Status = alloc_chunk(fcb->Vcb, flags, &c, false); if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); return Status; } @@ -1169,7 +1170,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); ExFreePool(fsi); reap_fcb(c->cache); c->cache = NULL; @@ -1179,7 +1180,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan if (!keycmp(searchkey, tp.item->key)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(fsi); reap_fcb(c->cache); c->cache = NULL; @@ -1193,7 +1194,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = insert_tree_item(Vcb, Vcb->root_root, FREE_SPACE_CACHE_ID, 0, c->offset, fsi, sizeof(FREE_SPACE_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(fsi); reap_fcb(c->cache); c->cache = NULL; @@ -1204,7 +1205,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = insert_cache_extent(c->cache, 0, new_cache_size, rollback); if (!NT_SUCCESS(Status)) { - ERR("insert_cache_extent returned %08x\n", Status); + ERR("insert_cache_extent returned %08lx\n", Status); reap_fcb(c->cache); c->cache = NULL; return Status; @@ -1215,7 +1216,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = flush_fcb(c->cache, true, batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("flush_fcb returned %08x\n", Status); + ERR("flush_fcb returned %08lx\n", Status); free_fcb(c->cache); c->cache = NULL; return Status; @@ -1236,7 +1237,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -1246,7 +1247,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan } if (tp.item->size < sizeof(FREE_SPACE_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -1278,7 +1279,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = excise_extents(Vcb, c->cache, 0, c->cache->inode_item.st_size, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); return Status; } } @@ -1287,7 +1288,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = insert_cache_extent(c->cache, 0, new_cache_size, rollback); if (!NT_SUCCESS(Status)) { - ERR("insert_cache_extent returned %08x\n", Status); + ERR("insert_cache_extent returned %08lx\n", Status); return Status; } @@ -1298,7 +1299,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = flush_fcb(c->cache, true, batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("flush_fcb returned %08x\n", Status); + ERR("flush_fcb returned %08lx\n", Status); return Status; } @@ -1315,7 +1316,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -1332,7 +1333,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = insert_tree_item(Vcb, Vcb->root_root, c->cache->inode, TYPE_INODE_ITEM, 0, ii, sizeof(INODE_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ii); return Status; } @@ -1340,7 +1341,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan *changed = true; } else { if (tp.item->size < sizeof(INODE_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(INODE_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(INODE_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -1353,7 +1354,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); return Status; } @@ -1363,7 +1364,7 @@ static NTSTATUS allocate_cache_chunk(device_extension* Vcb, chunk* c, bool* chan } if (tp.item->size < sizeof(FREE_SPACE_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -1400,7 +1401,7 @@ NTSTATUS allocate_cache(device_extension* Vcb, bool* changed, PIRP Irp, LIST_ENT *changed = true; if (!NT_SUCCESS(Status)) { - ERR("allocate_cache_chunk(%I64x) returned %08x\n", c->offset, Status); + ERR("allocate_cache_chunk(%I64x) returned %08lx\n", c->offset, Status); ExReleaseResourceLite(&Vcb->chunk_lock); clear_batch_list(Vcb, &batchlist); return Status; @@ -1414,7 +1415,7 @@ NTSTATUS allocate_cache(device_extension* Vcb, bool* changed, PIRP Irp, LIST_ENT Status = commit_batch_list(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list returned %08x\n", Status); + ERR("commit_batch_list returned %08lx\n", Status); return Status; } @@ -1719,7 +1720,7 @@ static NTSTATUS update_chunk_cache(device_extension* Vcb, chunk* c, BTRFS_TIME* Status = flush_fcb(c->cache, true, batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("flush_fcb returned %08x\n", Status); + ERR("flush_fcb returned %08lx\n", Status); goto end; } @@ -1731,7 +1732,7 @@ static NTSTATUS update_chunk_cache(device_extension* Vcb, chunk* c, BTRFS_TIME* Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -1742,7 +1743,7 @@ static NTSTATUS update_chunk_cache(device_extension* Vcb, chunk* c, BTRFS_TIME* } if (tp.item->size < sizeof(FREE_SPACE_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(FREE_SPACE_ITEM)); Status = STATUS_INTERNAL_ERROR; goto end; } @@ -1777,7 +1778,7 @@ static NTSTATUS update_chunk_cache(device_extension* Vcb, chunk* c, BTRFS_TIME* Status = do_write_file(c->cache, 0, c->cache->inode_item.st_size, data, NULL, false, 0, rollback); if (!NT_SUCCESS(Status)) { - ERR("do_write_file returned %08x\n", Status); + ERR("do_write_file returned %08lx\n", Status); // Writing the cache isn't critical, so we don't return an error if writing fails. This means // we can still flush on a degraded mount if metadata is RAID1 but data is RAID0. @@ -1816,7 +1817,7 @@ static NTSTATUS update_chunk_cache_tree(device_extension* Vcb, chunk* c, LIST_EN Status = insert_tree_item_batch(batchlist, Vcb, Vcb->space_root, s->address, TYPE_FREE_SPACE_EXTENT, s->size, NULL, 0, Batch_Insert); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(fsi); return Status; } @@ -1827,7 +1828,7 @@ static NTSTATUS update_chunk_cache_tree(device_extension* Vcb, chunk* c, LIST_EN Status = insert_tree_item_batch(batchlist, Vcb, Vcb->space_root, c->offset, TYPE_FREE_SPACE_INFO, c->chunk_item->size, NULL, 0, Batch_DeleteFreeSpace); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(fsi); return Status; } @@ -1835,7 +1836,7 @@ static NTSTATUS update_chunk_cache_tree(device_extension* Vcb, chunk* c, LIST_EN Status = insert_tree_item_batch(batchlist, Vcb, Vcb->space_root, c->offset, TYPE_FREE_SPACE_INFO, c->chunk_item->size, fsi, sizeof(FREE_SPACE_INFO), Batch_Insert); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item_batch returned %08x\n", Status); + ERR("insert_tree_item_batch returned %08lx\n", Status); ExFreePool(fsi); return Status; } @@ -1865,7 +1866,7 @@ NTSTATUS update_chunk_caches(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollba release_chunk_lock(c, Vcb); if (!NT_SUCCESS(Status)) { - ERR("update_chunk_cache(%I64x) returned %08x\n", c->offset, Status); + ERR("update_chunk_cache(%I64x) returned %08lx\n", c->offset, Status); clear_batch_list(Vcb, &batchlist); return Status; } @@ -1876,7 +1877,7 @@ NTSTATUS update_chunk_caches(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollba Status = commit_batch_list(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list returned %08x\n", Status); + ERR("commit_batch_list returned %08lx\n", Status); return Status; } @@ -1898,7 +1899,7 @@ NTSTATUS update_chunk_caches(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollba ExFreePool(ps); if (!NT_SUCCESS(Status)) { - ERR("flush_partial_stripe returned %08x\n", Status); + ERR("flush_partial_stripe returned %08lx\n", Status); ExReleaseResourceLite(&c->partial_stripes_lock); return Status; } @@ -1934,7 +1935,7 @@ NTSTATUS update_chunk_caches_tree(device_extension* Vcb, PIRP Irp) { release_chunk_lock(c, Vcb); if (!NT_SUCCESS(Status)) { - ERR("update_chunk_cache_tree(%I64x) returned %08x\n", c->offset, Status); + ERR("update_chunk_cache_tree(%I64x) returned %08lx\n", c->offset, Status); ExReleaseResourceLite(&Vcb->chunk_lock); clear_batch_list(Vcb, &batchlist); return Status; @@ -1948,7 +1949,7 @@ NTSTATUS update_chunk_caches_tree(device_extension* Vcb, PIRP Irp) { Status = commit_batch_list(Vcb, &batchlist, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list returned %08x\n", Status); + ERR("commit_batch_list returned %08lx\n", Status); return Status; } diff --git a/drivers/filesystems/btrfs/fsctl.c b/drivers/filesystems/btrfs/fsctl.c index 52698383d3f..b5c8861bed0 100644 --- a/drivers/filesystems/btrfs/fsctl.c +++ b/drivers/filesystems/btrfs/fsctl.c @@ -107,7 +107,7 @@ static NTSTATUS snapshot_tree_copy(device_extension* Vcb, uint64_t addr, root* s Status = read_data(Vcb, addr, Vcb->superblock.node_size, NULL, true, buf, NULL, NULL, Irp, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); goto end; } @@ -120,7 +120,7 @@ static NTSTATUS snapshot_tree_copy(device_extension* Vcb, uint64_t addr, root* s Status = get_tree_new_address(Vcb, &t, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("get_tree_new_address returned %08x\n", Status); + ERR("get_tree_new_address returned %08lx\n", Status); goto end; } @@ -143,7 +143,7 @@ static NTSTATUS snapshot_tree_copy(device_extension* Vcb, uint64_t addr, root* s th->address = t.new_address; th->tree_id = subvol->id; th->generation = Vcb->superblock.generation; - th->fs_uuid = Vcb->superblock.uuid; + th->fs_uuid = Vcb->superblock.metadata_uuid; if (th->level == 0) { uint32_t i; @@ -160,7 +160,7 @@ static NTSTATUS snapshot_tree_copy(device_extension* Vcb, uint64_t addr, root* s Status = increase_extent_refcount_data(Vcb, ed2->address, ed2->size, subvol->id, ln[i].key.obj_id, ln[i].key.offset - ed2->offset, 1, Irp); if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount_data returned %08x\n", Status); + ERR("increase_extent_refcount_data returned %08lx\n", Status); goto end; } } @@ -178,13 +178,13 @@ static NTSTATUS snapshot_tree_copy(device_extension* Vcb, uint64_t addr, root* s Status = increase_extent_refcount(Vcb, in[i].address, Vcb->superblock.node_size, TYPE_TREE_BLOCK_REF, &tbr, NULL, th->level - 1, Irp); if (!NT_SUCCESS(Status)) { - ERR("increase_extent_refcount returned %08x\n", Status); + ERR("increase_extent_refcount returned %08lx\n", Status); goto end; } } } - *((uint32_t*)buf) = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + calc_tree_checksum(Vcb, th); KeInitializeEvent(&wtc.Event, NotificationEvent, false); InitializeListHead(&wtc.stripes); @@ -192,7 +192,7 @@ static NTSTATUS snapshot_tree_copy(device_extension* Vcb, uint64_t addr, root* s Status = write_data(Vcb, t.new_address, buf, Vcb->superblock.node_size, &wtc, NULL, NULL, false, 0, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("write_data returned %08x\n", Status); + ERR("write_data returned %08lx\n", Status); goto end; } @@ -305,7 +305,7 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f free_trees(Vcb); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); return Status; } @@ -317,7 +317,7 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f Status = create_root(Vcb, id, &r, true, Vcb->superblock.generation, Irp); if (!NT_SUCCESS(Status)) { - ERR("create_root returned %08x\n", Status); + ERR("create_root returned %08lx\n", Status); goto end; } @@ -331,7 +331,7 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f Status = create_root(Vcb, BTRFS_ROOT_UUID, &uuid_root, false, 0, Irp); if (!NT_SUCCESS(Status)) { - ERR("create_root returned %08x\n", Status); + ERR("create_root returned %08lx\n", Status); goto end; } @@ -361,7 +361,7 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f Status = insert_tree_item(Vcb, Vcb->uuid_root, searchkey.obj_id, searchkey.obj_type, searchkey.offset, root_num, sizeof(uint64_t), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(root_num); goto end; } @@ -372,13 +372,13 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } Status = snapshot_tree_copy(Vcb, subvol->root_item.block_number, r, &address, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("snapshot_tree_copy returned %08x\n", Status); + ERR("snapshot_tree_copy returned %08lx\n", Status); goto end; } @@ -436,7 +436,7 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f Status = open_fcb(Vcb, r, r->root_item.objid, BTRFS_TYPE_DIRECTORY, utf8, false, fcb, &fr->fcb, PagedPool, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fcb returned %08x\n", Status); + ERR("open_fcb returned %08lx\n", Status); free_fileref(fr); goto end; } @@ -445,7 +445,7 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f Status = add_dir_child(fileref->fcb, r->id, true, utf8, name, BTRFS_TYPE_DIRECTORY, &dc); if (!NT_SUCCESS(Status)) - WARN("add_dir_child returned %08x\n", Status); + WARN("add_dir_child returned %08lx\n", Status); fr->dc = dc; dc->fileref = fr; @@ -509,7 +509,7 @@ static NTSTATUS do_create_snapshot(device_extension* Vcb, PFILE_OBJECT parent, f free_trees(Vcb); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); end: if (NT_SUCCESS(Status)) @@ -607,7 +607,7 @@ static NTSTATUS create_snapshot(device_extension* Vcb, PFILE_OBJECT FileObject, Status = utf16_to_utf8(NULL, 0, &len, nameus.Buffer, nameus.Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 failed with error %08x\n", Status); + ERR("utf16_to_utf8 failed with error %08lx\n", Status); return Status; } @@ -631,7 +631,7 @@ static NTSTATUS create_snapshot(device_extension* Vcb, PFILE_OBJECT FileObject, Status = utf16_to_utf8(utf8.Buffer, len, &len, nameus.Buffer, nameus.Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 failed with error %08x\n", Status); + ERR("utf16_to_utf8 failed with error %08lx\n", Status); goto end2; } @@ -649,13 +649,13 @@ static NTSTATUS create_snapshot(device_extension* Vcb, PFILE_OBJECT FileObject, } else free_fileref(fr2); } else if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) { - ERR("open_fileref returned %08x\n", Status); + ERR("open_fileref returned %08lx\n", Status); goto end3; } Status = ObReferenceObjectByHandle(subvolh, 0, *IoFileObjectType, Irp->RequestorMode, (void**)&subvol_obj, NULL); if (!NT_SUCCESS(Status)) { - ERR("ObReferenceObjectByHandle returned %08x\n", Status); + ERR("ObReferenceObjectByHandle returned %08lx\n", Status); goto end3; } @@ -724,7 +724,7 @@ static NTSTATUS create_snapshot(device_extension* Vcb, PFILE_OBJECT FileObject, Status = open_fileref(Vcb, &fr, &nameus, fileref, false, NULL, NULL, PagedPool, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("open_fileref returned %08x\n", Status); + ERR("open_fileref returned %08lx\n", Status); Status = STATUS_SUCCESS; } else { send_notification_fileref(fr, FILE_NOTIFY_CHANGE_DIR_NAME, FILE_ACTION_ADDED, NULL); @@ -829,7 +829,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = utf16_to_utf8(NULL, 0, &len, nameus.Buffer, nameus.Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 failed with error %08x\n", Status); + ERR("utf16_to_utf8 failed with error %08lx\n", Status); return Status; } @@ -853,7 +853,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = utf16_to_utf8(utf8.Buffer, len, &len, nameus.Buffer, nameus.Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 failed with error %08x\n", Status); + ERR("utf16_to_utf8 failed with error %08lx\n", Status); goto end2; } @@ -874,7 +874,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo } else free_fileref(fr2); } else if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) { - ERR("open_fileref returned %08x\n", Status); + ERR("open_fileref returned %08lx\n", Status); goto end; } @@ -882,7 +882,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = create_root(Vcb, id, &r, false, 0, Irp); if (!NT_SUCCESS(Status)) { - ERR("create_root returned %08x\n", Status); + ERR("create_root returned %08lx\n", Status); goto end; } @@ -896,7 +896,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = create_root(Vcb, BTRFS_ROOT_UUID, &uuid_root, false, 0, Irp); if (!NT_SUCCESS(Status)) { - ERR("create_root returned %08x\n", Status); + ERR("create_root returned %08lx\n", Status); goto end; } @@ -926,7 +926,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = insert_tree_item(Vcb, Vcb->uuid_root, searchkey.obj_id, searchkey.obj_type, searchkey.offset, root_num, sizeof(uint64_t), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(root_num); goto end; } @@ -980,7 +980,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = SeAssignSecurity(fcb->sd, NULL, (void**)&rootfcb->sd, true, &subjcont, IoGetFileObjectGenericMapping(), PagedPool); if (!NT_SUCCESS(Status)) { - ERR("SeAssignSecurity returned %08x\n", Status); + ERR("SeAssignSecurity returned %08lx\n", Status); goto end; } @@ -992,7 +992,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = RtlGetOwnerSecurityDescriptor(rootfcb->sd, &owner, &defaulted); if (!NT_SUCCESS(Status)) { - ERR("RtlGetOwnerSecurityDescriptor returned %08x\n", Status); + ERR("RtlGetOwnerSecurityDescriptor returned %08lx\n", Status); rootfcb->inode_item.st_uid = UID_NOBODY; rootfcb->sd_dirty = true; } else { @@ -1041,7 +1041,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = insert_tree_item(Vcb, r, r->root_item.objid, TYPE_INODE_REF, r->root_item.objid, ir, irsize, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(ir); goto end; } @@ -1066,7 +1066,7 @@ static NTSTATUS create_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, vo Status = add_dir_child(fileref->fcb, r->id, true, &utf8, &nameus, BTRFS_TYPE_DIRECTORY, &dc); if (!NT_SUCCESS(Status)) - WARN("add_dir_child returned %08x\n", Status); + WARN("add_dir_child returned %08lx\n", Status); fr->dc = dc; dc->fileref = fr; @@ -1523,7 +1523,7 @@ static NTSTATUS get_usage(device_extension* Vcb, void* data, ULONG length, PIRP ExReleaseResourceLite(&Vcb->tree_lock); if (!NT_SUCCESS(Status)) { - ERR("find_chunk_usage returned %08x\n", Status); + ERR("find_chunk_usage returned %08lx\n", Status); return Status; } } @@ -1841,7 +1841,7 @@ static NTSTATUS zero_data(device_extension* Vcb, fcb* fcb, uint64_t start, uint6 Status = read_file(fcb, data + buf_head, start_data, end_data - start_data, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(data); return Status; } @@ -1855,7 +1855,7 @@ static NTSTATUS zero_data(device_extension* Vcb, fcb* fcb, uint64_t start, uint6 Status = excise_extents(Vcb, fcb, 0, sector_align(end_data, Vcb->superblock.sector_size), Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); ExFreePool(data); return Status; } @@ -1871,7 +1871,7 @@ static NTSTATUS zero_data(device_extension* Vcb, fcb* fcb, uint64_t start, uint6 Status = add_extent_to_fcb(fcb, 0, ed, edsize, false, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_extent_to_fcb returned %08x\n", Status); + ERR("add_extent_to_fcb returned %08lx\n", Status); ExFreePool(data); return Status; } @@ -1885,7 +1885,7 @@ static NTSTATUS zero_data(device_extension* Vcb, fcb* fcb, uint64_t start, uint6 ExFreePool(data); if (!NT_SUCCESS(Status)) { - ERR("write_compressed returned %08x\n", Status); + ERR("write_compressed returned %08lx\n", Status); return Status; } } else { @@ -1894,7 +1894,7 @@ static NTSTATUS zero_data(device_extension* Vcb, fcb* fcb, uint64_t start, uint6 ExFreePool(data); if (!NT_SUCCESS(Status)) { - ERR("do_write_file returned %08x\n", Status); + ERR("do_write_file returned %08lx\n", Status); return Status; } } @@ -1999,7 +1999,7 @@ static NTSTATUS set_zero_data(device_extension* Vcb, PFILE_OBJECT FileObject, vo if (ext->extent_data.type == EXTENT_TYPE_INLINE) { Status = zero_data(Vcb, fcb, fzdi->FileOffset.QuadPart, fzdi->BeyondFinalZero.QuadPart - fzdi->FileOffset.QuadPart, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("zero_data returned %08x\n", Status); + ERR("zero_data returned %08lx\n", Status); goto end; } } else { @@ -2013,14 +2013,14 @@ static NTSTATUS set_zero_data(device_extension* Vcb, PFILE_OBJECT FileObject, vo if (end <= start) { Status = zero_data(Vcb, fcb, fzdi->FileOffset.QuadPart, fzdi->BeyondFinalZero.QuadPart - fzdi->FileOffset.QuadPart, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("zero_data returned %08x\n", Status); + ERR("zero_data returned %08lx\n", Status); goto end; } } else { if (start > (uint64_t)fzdi->FileOffset.QuadPart) { Status = zero_data(Vcb, fcb, fzdi->FileOffset.QuadPart, start - fzdi->FileOffset.QuadPart, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("zero_data returned %08x\n", Status); + ERR("zero_data returned %08lx\n", Status); goto end; } } @@ -2028,7 +2028,7 @@ static NTSTATUS set_zero_data(device_extension* Vcb, PFILE_OBJECT FileObject, vo if (end < (uint64_t)fzdi->BeyondFinalZero.QuadPart) { Status = zero_data(Vcb, fcb, end, fzdi->BeyondFinalZero.QuadPart - end, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("zero_data returned %08x\n", Status); + ERR("zero_data returned %08lx\n", Status); goto end; } } @@ -2036,7 +2036,7 @@ static NTSTATUS set_zero_data(device_extension* Vcb, PFILE_OBJECT FileObject, vo if (end > start) { Status = excise_extents(Vcb, fcb, start, end, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); goto end; } } @@ -2182,7 +2182,7 @@ end: static NTSTATUS get_object_id(device_extension* Vcb, PFILE_OBJECT FileObject, FILE_OBJECTID_BUFFER* buf, ULONG buflen, ULONG_PTR* retlen) { fcb* fcb; - TRACE("(%p, %p, %p, %x, %p)\n", Vcb, FileObject, buf, buflen, retlen); + TRACE("(%p, %p, %p, %lx, %p)\n", Vcb, FileObject, buf, buflen, retlen); if (!FileObject) { ERR("FileObject was NULL\n"); @@ -2285,7 +2285,7 @@ static NTSTATUS lock_volume(device_extension* Vcb, PIRP Irp) { ExReleaseResourceLite(&Vcb->tree_lock); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); goto end; } @@ -2382,7 +2382,7 @@ static NTSTATUS invalidate_volumes(PIRP Irp) { Status = ObReferenceObjectByHandle(h, 0, *IoFileObjectType, Irp->RequestorMode, (void**)&fileobj, NULL); if (!NT_SUCCESS(Status)) { - ERR("ObReferenceObjectByHandle returned %08x\n", Status); + ERR("ObReferenceObjectByHandle returned %08lx\n", Status); return Status; } @@ -2410,6 +2410,8 @@ static NTSTATUS invalidate_volumes(PIRP Irp) { RtlZeroMemory(newvpb, sizeof(VPB)); + ObReferenceObject(devobj); + ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true); Vcb->removing = true; @@ -2430,9 +2432,10 @@ static NTSTATUS invalidate_volumes(PIRP Irp) { free_trees(Vcb); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->tree_lock); ExFreePool(newvpb); + ObDereferenceObject(devobj); goto end; } @@ -2459,6 +2462,8 @@ static NTSTATUS invalidate_volumes(PIRP Irp) { if (Vcb->open_files == 0) uninit(Vcb); + + ObDereferenceObject(devobj); } break; @@ -2587,7 +2592,7 @@ NTSTATUS dismount_volume(device_extension* Vcb, bool shutdown, PIRP Irp) { Status = FsRtlNotifyVolumeEvent(Vcb->root_file, FSRTL_VOLUME_DISMOUNT); if (!NT_SUCCESS(Status)) { - WARN("FsRtlNotifyVolumeEvent returned %08x\n", Status); + WARN("FsRtlNotifyVolumeEvent returned %08lx\n", Status); } } @@ -2600,7 +2605,7 @@ NTSTATUS dismount_volume(device_extension* Vcb, bool shutdown, PIRP Irp) { Status = do_write(Vcb, Irp); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); } } @@ -2627,7 +2632,6 @@ static NTSTATUS is_device_part_of_mounted_btrfs_raid(PDEVICE_OBJECT devobj, PFIL NTSTATUS Status; ULONG to_read; superblock* sb; - uint32_t crc32; BTRFS_UUID fsuuid, devuuid; LIST_ENTRY* le; @@ -2641,7 +2645,7 @@ static NTSTATUS is_device_part_of_mounted_btrfs_raid(PDEVICE_OBJECT devobj, PFIL Status = sync_read_phys(devobj, fileobj, superblock_addrs[0], to_read, (uint8_t*)sb, true); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); ExFreePool(sb); return Status; } @@ -2652,9 +2656,7 @@ static NTSTATUS is_device_part_of_mounted_btrfs_raid(PDEVICE_OBJECT devobj, PFIL return STATUS_SUCCESS; } - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - - if (crc32 != *((uint32_t*)sb->checksum)) { + if (!check_superblock_checksum(sb)) { TRACE("device has Btrfs magic, but invalid superblock checksum\n"); ExFreePool(sb); return STATUS_SUCCESS; @@ -2721,7 +2723,7 @@ void trim_whole_device(device* dev) { Status = dev_ioctl(dev->devobj, IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, &dmdsa, sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES), NULL, 0, true, NULL); if (!NT_SUCCESS(Status)) - WARN("IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES returned %08x\n", Status); + WARN("IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES returned %08lx\n", Status); } static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE processor_mode) { @@ -2779,7 +2781,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = ObReferenceObjectByHandle(h, 0, *IoFileObjectType, Irp->RequestorMode, (void**)&fileobj, NULL); if (!NT_SUCCESS(Status)) { - ERR("ObReferenceObjectByHandle returned %08x\n", Status); + ERR("ObReferenceObjectByHandle returned %08lx\n", Status); return Status; } @@ -2787,7 +2789,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = get_device_pnp_name(DeviceObject, &pnp_name, &pnp_guid); if (!NT_SUCCESS(Status)) { - ERR("get_device_pnp_name returned %08x\n", Status); + ERR("get_device_pnp_name returned %08lx\n", Status); ObDereferenceObject(fileobj); return Status; } @@ -2798,14 +2800,14 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = dev_ioctl(DeviceObject, IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0, true, NULL); if (!NT_SUCCESS(Status)) { - ERR("IOCTL_DISK_IS_WRITABLE returned %08x\n", Status); + ERR("IOCTL_DISK_IS_WRITABLE returned %08lx\n", Status); ObDereferenceObject(fileobj); return Status; } Status = is_device_part_of_mounted_btrfs_raid(DeviceObject, fileobj); if (!NT_SUCCESS(Status)) { - ERR("is_device_part_of_mounted_btrfs_raid returned %08x\n", Status); + ERR("is_device_part_of_mounted_btrfs_raid returned %08lx\n", Status); ObDereferenceObject(fileobj); return Status; } @@ -2859,7 +2861,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = dev_ioctl(DeviceObject, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), true, NULL); if (!NT_SUCCESS(Status)) { - ERR("error reading length information: %08x\n", Status); + ERR("error reading length information: %08lx\n", Status); ObDereferenceObject(fileobj); return Status; } @@ -2884,7 +2886,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc free_trees(Vcb); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); goto end; } @@ -2907,7 +2909,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc if (size > 0x100000) { // add disk hole - the first MB is marked as used Status = add_space_entry(&dev->space, NULL, 0x100000, size - 0x100000); if (!NT_SUCCESS(Status)) { - ERR("add_space_entry returned %08x\n", Status); + ERR("add_space_entry returned %08lx\n", Status); goto end; } } @@ -2951,7 +2953,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = insert_tree_item(Vcb, Vcb->chunk_root, 1, TYPE_DEV_ITEM, di->dev_id, di, sizeof(DEV_ITEM), NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(di); goto end; } @@ -2972,7 +2974,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = find_item(Vcb, Vcb->dev_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); ExFreePool(stats); goto end; } @@ -2980,7 +2982,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc if (!keycmp(tp.item->key, searchkey)) { Status = delete_tree_item(Vcb, &tp); if (!NT_SUCCESS(Status)) { - ERR("delete_tree_item returned %08x\n", Status); + ERR("delete_tree_item returned %08lx\n", Status); ExFreePool(stats); goto end; } @@ -2988,7 +2990,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = insert_tree_item(Vcb, Vcb->dev_root, 0, TYPE_DEV_STATS, di->dev_id, stats, sizeof(uint64_t) * 5, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("insert_tree_item returned %08x\n", Status); + ERR("insert_tree_item returned %08lx\n", Status); ExFreePool(stats); goto end; } @@ -3008,7 +3010,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = write_data_phys(DeviceObject, fileobj, 0, mb, 0x100000); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); ExFreePool(mb); goto end; } @@ -3031,11 +3033,12 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc vc->devobj = DeviceObject; vc->fileobj = fileobj; vc->notification_entry = NULL; + vc->boot_volume = false; Status = IoRegisterPlugPlayNotification(EventCategoryTargetDeviceChange, 0, fileobj, drvobj, pnp_removal, vde->pdode, &vc->notification_entry); if (!NT_SUCCESS(Status)) - WARN("IoRegisterPlugPlayNotification returned %08x\n", Status); + WARN("IoRegisterPlugPlayNotification returned %08lx\n", Status); pnp_name2 = pnp_name; @@ -3076,11 +3079,11 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr); if (!NT_SUCCESS(Status)) - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); else { Status = remove_drive_letter(mountmgr, &pnp_name); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) - WARN("remove_drive_letter returned %08x\n", Status); + WARN("remove_drive_letter returned %08lx\n", Status); vc->had_drive_letter = NT_SUCCESS(Status); @@ -3098,7 +3101,7 @@ static NTSTATUS add_device(device_extension* Vcb, PIRP Irp, KPROCESSOR_MODE proc Status = do_write(Vcb, Irp); if (!NT_SUCCESS(Status)) - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); ObReferenceObject(fileobj); @@ -3287,7 +3290,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject Status = ObReferenceObjectByHandle(ded->FileHandle, 0, *IoFileObjectType, Irp->RequestorMode, (void**)&sourcefo, NULL); if (!NT_SUCCESS(Status)) { - ERR("ObReferenceObjectByHandle returned %08x\n", Status); + ERR("ObReferenceObjectByHandle returned %08lx\n", Status); return Status; } @@ -3400,7 +3403,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject Status = read_file(fcb, data2, ded->TargetFileOffset.QuadPart - dataoff, dataoff, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(data2); goto end; } @@ -3409,14 +3412,14 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject if (sourcefcb->ads) { Status = read_stream(sourcefcb, data2 + dataoff, ded->SourceFileOffset.QuadPart, (ULONG)ded->ByteCount.QuadPart, &bytes_read); if (!NT_SUCCESS(Status)) { - ERR("read_stream returned %08x\n", Status); + ERR("read_stream returned %08lx\n", Status); ExFreePool(data2); goto end; } } else { Status = read_file(sourcefcb, data2 + dataoff, ded->SourceFileOffset.QuadPart, ded->ByteCount.QuadPart, &bytes_read, Irp); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(data2); goto end; } @@ -3433,7 +3436,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject Status = excise_extents(Vcb, fcb, 0, sector_align(fcb->inode_item.st_size, Vcb->superblock.sector_size), Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); ExFreePool(data2); goto end; } @@ -3459,7 +3462,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject Status = add_extent_to_fcb(fcb, 0, ed, edsize, false, NULL, &rollback); if (!NT_SUCCESS(Status)) { - ERR("add_extent_to_fcb returned %08x\n", Status); + ERR("add_extent_to_fcb returned %08lx\n", Status); ExFreePool(data2); goto end; } @@ -3470,7 +3473,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject Status = do_write_file(fcb, start, start + datalen2, data2, Irp, false, 0, &rollback); if (!NT_SUCCESS(Status)) { - ERR("do_write_file returned %08x\n", Status); + ERR("do_write_file returned %08lx\n", Status); ExFreePool(data2); goto end; } @@ -3540,7 +3543,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject if (ext->csum) { if (ext->extent_data.compression == BTRFS_COMPRESSION_NONE) { - ext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2d->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + ext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2d->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!ext2->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -3548,10 +3551,10 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject goto end; } - RtlCopyMemory(ext2->csum, &ext->csum[(ed2d->offset - ed2s->offset) / Vcb->superblock.sector_size], - (ULONG)(ed2d->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory(ext2->csum, (uint8_t*)ext->csum + ((ed2d->offset - ed2s->offset) * Vcb->csum_size / Vcb->superblock.sector_size), + (ULONG)(ed2d->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size)); } else { - ext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2d->size * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + ext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2d->size * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!ext2->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -3559,7 +3562,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject goto end; } - RtlCopyMemory(ext2->csum, ext->csum, (ULONG)(ed2s->size * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory(ext2->csum, ext->csum, (ULONG)(ed2s->size * Vcb->csum_size / Vcb->superblock.sector_size)); } } else ext2->csum = NULL; @@ -3576,7 +3579,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject Status = update_changed_extent_ref(Vcb, c, ed2s->address, ed2s->size, fcb->subvol->id, fcb->inode, ext2->offset - ed2d->offset, 1, fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); goto end; } @@ -3589,7 +3592,7 @@ static NTSTATUS duplicate_extents(device_extension* Vcb, PFILE_OBJECT FileObject Status = excise_extents(Vcb, fcb, ded->TargetFileOffset.QuadPart, ded->TargetFileOffset.QuadPart + ded->ByteCount.QuadPart, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); while (!IsListEmpty(&newexts)) { extent* ext = CONTAINING_RECORD(RemoveHeadList(&newexts), extent, list_entry); @@ -3708,7 +3711,7 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data PSID owner; BOOLEAN defaulted; - TRACE("(%p, %p, %p, %u)\n", Vcb, FileObject, data, datalen); + TRACE("(%p, %p, %p, %lu)\n", Vcb, FileObject, data, datalen); if (!FileObject || !FileObject->FsContext || !FileObject->FsContext2 || FileObject->FsContext == Vcb->volume_fcb) return STATUS_INVALID_PARAMETER; @@ -3765,7 +3768,7 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data Status = utf16_to_utf8(NULL, 0, &len, bmn->name, bmn->namelen); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 return %08x\n", Status); + ERR("utf16_to_utf8 returned %08lx\n", Status); return Status; } @@ -3775,7 +3778,7 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data } if (len > 0xffff) { - ERR("len was too long (%x)\n", len); + ERR("len was too long (%lx)\n", len); return STATUS_INVALID_PARAMETER; } @@ -3789,7 +3792,7 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data Status = utf16_to_utf8(utf8.Buffer, len, &len, bmn->name, bmn->namelen); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 failed with error %08x\n", Status); + ERR("utf16_to_utf8 failed with error %08lx\n", Status); ExFreePool(utf8.Buffer); return Status; } @@ -3799,7 +3802,7 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data Status = find_file_in_dir(&name, parfcb, &subvol, &inode, &dc, true); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) { - ERR("find_file_in_dir returned %08x\n", Status); + ERR("find_file_in_dir returned %08lx\n", Status); goto end; } @@ -3901,14 +3904,14 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data SEF_SACL_AUTO_INHERIT, &subjcont, IoGetFileObjectGenericMapping(), PagedPool); if (!NT_SUCCESS(Status)) { - ERR("SeAssignSecurityEx returned %08x\n", Status); + ERR("SeAssignSecurityEx returned %08lx\n", Status); reap_fcb(fcb); goto end; } Status = RtlGetOwnerSecurityDescriptor(fcb->sd, &owner, &defaulted); if (!NT_SUCCESS(Status)) { - WARN("RtlGetOwnerSecurityDescriptor returned %08x\n", Status); + WARN("RtlGetOwnerSecurityDescriptor returned %08lx\n", Status); fcb->sd_dirty = true; } else { fcb->inode_item.st_uid = sid_to_uid(owner); @@ -3982,7 +3985,7 @@ static NTSTATUS mknod(device_extension* Vcb, PFILE_OBJECT FileObject, void* data Status = add_dir_child(fileref->parent->fcb, fcb->inode, false, &utf8, &name, fcb->type, &dc); if (!NT_SUCCESS(Status)) - WARN("add_dir_child returned %08x\n", Status); + WARN("add_dir_child returned %08lx\n", Status); fileref->dc = dc; dc->fileref = fileref; @@ -4080,7 +4083,7 @@ static NTSTATUS recvd_subvol(device_extension* Vcb, PFILE_OBJECT FileObject, voi LARGE_INTEGER time; BTRFS_TIME now; - TRACE("(%p, %p, %p, %u)\n", Vcb, FileObject, data, datalen); + TRACE("(%p, %p, %p, %lu)\n", Vcb, FileObject, data, datalen); if (!data || datalen < sizeof(btrfs_received_subvol)) return STATUS_INVALID_PARAMETER; @@ -4198,7 +4201,7 @@ static NTSTATUS fsctl_set_xattr(device_extension* Vcb, PFILE_OBJECT FileObject, static const char stream_pref[] = "user."; - TRACE("(%p, %p, %p, %u)\n", Vcb, FileObject, data, datalen); + TRACE("(%p, %p, %p, %lu)\n", Vcb, FileObject, data, datalen); if (!data || datalen < sizeof(btrfs_set_xattr)) return STATUS_INVALID_PARAMETER; @@ -4346,7 +4349,7 @@ static NTSTATUS fsctl_set_xattr(device_extension* Vcb, PFILE_OBJECT FileObject, Status = IoCheckEaBufferValidity((FILE_FULL_EA_INFORMATION*)(bsxa->data + bsxa->namelen), bsxa->valuelen, &offset); if (!NT_SUCCESS(Status)) - WARN("IoCheckEaBufferValidity returned %08x (error at offset %u)\n", Status, offset); + WARN("IoCheckEaBufferValidity returned %08lx (error at offset %lu)\n", Status, offset); else { FILE_FULL_EA_INFORMATION* eainfo; @@ -4517,7 +4520,7 @@ static NTSTATUS get_subvol_path(device_extension* Vcb, uint64_t id, WCHAR* out, Status = open_fileref_by_inode(Vcb, r, r->root_item.objid, &fr, Irp); if (!NT_SUCCESS(Status)) { ExReleaseResourceLite(&Vcb->fileref_lock); - ERR("open_fileref_by_inode returned %08x\n", Status); + ERR("open_fileref_by_inode returned %08lx\n", Status); return Status; } @@ -4530,7 +4533,7 @@ static NTSTATUS get_subvol_path(device_extension* Vcb, uint64_t id, WCHAR* out, if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW) out[us.Length / sizeof(WCHAR)] = 0; else - ERR("fileref_get_filename returned %08x\n", Status); + ERR("fileref_get_filename returned %08lx\n", Status); free_fileref(fr); @@ -4571,7 +4574,7 @@ static NTSTATUS find_subvol(device_extension* Vcb, void* in, ULONG inlen, void* Status = find_item(Vcb, Vcb->uuid_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -4588,7 +4591,7 @@ static NTSTATUS find_subvol(device_extension* Vcb, void* in, ULONG inlen, void* Status = find_item(Vcb, Vcb->root_root, &tp2, &searchkey2, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -4614,7 +4617,7 @@ static NTSTATUS find_subvol(device_extension* Vcb, void* in, ULONG inlen, void* Status = find_item(Vcb, Vcb->uuid_root, &tp, &searchkey, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -4633,7 +4636,7 @@ static NTSTATUS find_subvol(device_extension* Vcb, void* in, ULONG inlen, void* Status = find_item(Vcb, Vcb->root_root, &tp2, &searchkey2, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -4669,7 +4672,7 @@ static NTSTATUS resize_device(device_extension* Vcb, void* data, ULONG len, PIRP LIST_ENTRY* le; device* dev = NULL; - TRACE("(%p, %p, %u)\n", Vcb, data, len); + TRACE("(%p, %p, %lu)\n", Vcb, data, len); if (!data || len < sizeof(btrfs_resize) || (br->size % Vcb->superblock.sector_size) != 0) return STATUS_INVALID_PARAMETER; @@ -4766,7 +4769,7 @@ static NTSTATUS resize_device(device_extension* Vcb, void* data, ULONG len, PIRP Status = PsCreateSystemThread(&Vcb->balance.thread, 0, &oa, NULL, NULL, balance_thread, Vcb); if (!NT_SUCCESS(Status)) { - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); goto end; } @@ -4780,7 +4783,7 @@ static NTSTATUS resize_device(device_extension* Vcb, void* data, ULONG len, PIRP Status = update_dev_item(Vcb, dev, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_dev_item returned %08x\n", Status); + ERR("update_dev_item returned %08lx\n", Status); dev->devitem.num_bytes = old_size; goto end; } @@ -4795,7 +4798,7 @@ static NTSTATUS resize_device(device_extension* Vcb, void* data, ULONG len, PIRP Status = dev_ioctl(dev->devobj, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), true, NULL); if (!NT_SUCCESS(Status)) { - ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08x\n", Status); + ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08lx\n", Status); goto end; } @@ -4826,7 +4829,7 @@ static NTSTATUS resize_device(device_extension* Vcb, void* data, ULONG len, PIRP Status = update_dev_item(Vcb, dev, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_dev_item returned %08x\n", Status); + ERR("update_dev_item returned %08lx\n", Status); dev->devitem.num_bytes = old_size; goto end; } @@ -5556,7 +5559,7 @@ NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp, uint32_t type) { break; default: - WARN("unknown control code %x (DeviceType = %x, Access = %x, Function = %x, Method = %x)\n", + WARN("unknown control code %lx (DeviceType = %lx, Access = %lx, Function = %lx, Method = %lx)\n", IrpSp->Parameters.FileSystemControl.FsControlCode, (IrpSp->Parameters.FileSystemControl.FsControlCode & 0xff0000) >> 16, (IrpSp->Parameters.FileSystemControl.FsControlCode & 0xc000) >> 14, (IrpSp->Parameters.FileSystemControl.FsControlCode & 0x3ffc) >> 2, IrpSp->Parameters.FileSystemControl.FsControlCode & 0x3); diff --git a/drivers/filesystems/btrfs/galois.c b/drivers/filesystems/btrfs/galois.c index f50d3289c00..b10354f4d4b 100644 --- a/drivers/filesystems/btrfs/galois.c +++ b/drivers/filesystems/btrfs/galois.c @@ -94,7 +94,7 @@ uint8_t gdiv(uint8_t a, uint8_t b) { // "The mathematics of RAID-6", by H. Peter Anvin. // https://www.kernel.org/pub/linux/kernel/people/hpa/raid6.pdf -#ifdef _AMD64_ +#if defined(_AMD64_) || defined(_ARM64_) __inline static uint64_t galois_double_mask64(uint64_t v) { v &= 0x8080808080808080; return (v << 1) - (v >> 7); @@ -109,7 +109,7 @@ __inline static uint32_t galois_double_mask32(uint32_t v) { void galois_double(uint8_t* data, uint32_t len) { // FIXME - SIMD? -#ifdef _AMD64_ +#if defined(_AMD64_) || defined(_ARM64_) while (len > sizeof(uint64_t)) { uint64_t v = *((uint64_t*)data), vv; diff --git a/drivers/filesystems/btrfs/pnp.c b/drivers/filesystems/btrfs/pnp.c index 3313d82831b..bae4c2ffccd 100644 --- a/drivers/filesystems/btrfs/pnp.c +++ b/drivers/filesystems/btrfs/pnp.c @@ -167,7 +167,7 @@ static NTSTATUS pnp_cancel_remove_device(PDEVICE_OBJECT DeviceObject) { Status = send_disks_pnp_message(Vcb, IRP_MN_CANCEL_REMOVE_DEVICE); if (!NT_SUCCESS(Status)) { - WARN("send_disks_pnp_message returned %08x\n", Status); + WARN("send_disks_pnp_message returned %08lx\n", Status); goto end; } @@ -191,7 +191,7 @@ NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp) { Status = send_disks_pnp_message(Vcb, IRP_MN_QUERY_REMOVE_DEVICE); if (!NT_SUCCESS(Status)) { - WARN("send_disks_pnp_message returned %08x\n", Status); + WARN("send_disks_pnp_message returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->tree_lock); return Status; } @@ -204,7 +204,7 @@ NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp) { free_trees(Vcb); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->tree_lock); return Status; } @@ -227,14 +227,14 @@ static NTSTATUS pnp_remove_device(PDEVICE_OBJECT DeviceObject) { Status = send_disks_pnp_message(Vcb, IRP_MN_REMOVE_DEVICE); if (!NT_SUCCESS(Status)) - WARN("send_disks_pnp_message returned %08x\n", Status); + WARN("send_disks_pnp_message returned %08lx\n", Status); ExReleaseResourceLite(&Vcb->tree_lock); if (DeviceObject->Vpb->Flags & VPB_MOUNTED) { Status = FsRtlNotifyVolumeEvent(Vcb->root_file, FSRTL_VOLUME_DISMOUNT); if (!NT_SUCCESS(Status)) { - WARN("FsRtlNotifyVolumeEvent returned %08x\n", Status); + WARN("FsRtlNotifyVolumeEvent returned %08lx\n", Status); } if (Vcb->vde) @@ -532,7 +532,7 @@ static NTSTATUS pdo_device_usage_notification(pdo_device_extension* pdode, PIRP KeWaitForSingleObject(&context.Event, Executive, KernelMode, false, NULL); if (!NT_SUCCESS(context.Status)) { - ERR("IoCallDriver returned %08x\n", context.Status); + ERR("IoCallDriver returned %08lx\n", context.Status); ExReleaseResourceLite(&pdode->child_lock); return context.Status; } @@ -682,7 +682,7 @@ end: IoCompleteRequest(Irp, IO_NO_INCREMENT); exit: - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); if (top_level) IoSetTopLevelIrp(NULL); diff --git a/drivers/filesystems/btrfs/read.c b/drivers/filesystems/btrfs/read.c index ae7a270bb18..ab3e96eaf47 100644 --- a/drivers/filesystems/btrfs/read.c +++ b/drivers/filesystems/btrfs/read.c @@ -16,6 +16,8 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "xxhash.h" +#include "crc32c.h" enum read_data_status { ReadDataStatus_Pending, @@ -49,7 +51,7 @@ typedef struct { uint64_t type; uint32_t sector_size; uint16_t firstoff, startoffstripe, sectors_per_stripe; - uint32_t* csum; + void* csum; bool tree; read_data_stripe* stripes; uint8_t* va; @@ -82,55 +84,155 @@ static NTSTATUS __stdcall read_data_completion(PDEVICE_OBJECT DeviceObject, PIRP return STATUS_MORE_PROCESSING_REQUIRED; } -NTSTATUS check_csum(device_extension* Vcb, uint8_t* data, uint32_t sectors, uint32_t* csum) { - NTSTATUS Status; - calc_job* cj; - uint32_t* csum2; +NTSTATUS check_csum(device_extension* Vcb, uint8_t* data, uint32_t sectors, void* csum) { + void* csum2; - // From experimenting, it seems that 40 sectors is roughly the crossover - // point where offloading the crc32 calculation becomes worth it. - - if (sectors < 40 || get_num_of_processors() < 2) { - ULONG j; - - for (j = 0; j < sectors; j++) { - uint32_t crc32 = ~calc_crc32c(0xffffffff, data + (j * Vcb->superblock.sector_size), Vcb->superblock.sector_size); - - if (crc32 != csum[j]) { - return STATUS_CRC_ERROR; - } - } - - return STATUS_SUCCESS; - } - - csum2 = ExAllocatePoolWithTag(PagedPool, sizeof(uint32_t) * sectors, ALLOC_TAG); + csum2 = ExAllocatePoolWithTag(PagedPool, Vcb->csum_size * sectors, ALLOC_TAG); if (!csum2) { ERR("out of memory\n"); return STATUS_INSUFFICIENT_RESOURCES; } - Status = add_calc_job(Vcb, data, sectors, csum2, &cj); - if (!NT_SUCCESS(Status)) { - ERR("add_calc_job returned %08x\n", Status); - ExFreePool(csum2); - return Status; - } + do_calc_job(Vcb, data, sectors, csum2); - KeWaitForSingleObject(&cj->event, Executive, KernelMode, false, NULL); - - if (RtlCompareMemory(csum2, csum, sectors * sizeof(uint32_t)) != sectors * sizeof(uint32_t)) { - free_calc_job(cj); + if (RtlCompareMemory(csum2, csum, sectors * Vcb->csum_size) != sectors * Vcb->csum_size) { ExFreePool(csum2); return STATUS_CRC_ERROR; } - free_calc_job(cj); ExFreePool(csum2); return STATUS_SUCCESS; } +void get_tree_checksum(device_extension* Vcb, tree_header* th, void* csum) { + switch (Vcb->superblock.csum_type) { + case CSUM_TYPE_CRC32C: + *(uint32_t*)csum = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + break; + + case CSUM_TYPE_XXHASH: + *(uint64_t*)csum = XXH64((uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum), 0); + break; + + case CSUM_TYPE_SHA256: + calc_sha256(csum, &th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + break; + + case CSUM_TYPE_BLAKE2: + blake2b(csum, BLAKE2_HASH_SIZE, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + break; + } +} + +bool check_tree_checksum(device_extension* Vcb, tree_header* th) { + switch (Vcb->superblock.csum_type) { + case CSUM_TYPE_CRC32C: { + uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + + if (crc32 == *((uint32_t*)th->csum)) + return true; + + WARN("hash was %08x, expected %08x\n", crc32, *((uint32_t*)th->csum)); + + break; + } + + case CSUM_TYPE_XXHASH: { + uint64_t hash = XXH64((uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum), 0); + + if (hash == *((uint64_t*)th->csum)) + return true; + + WARN("hash was %I64x, expected %I64x\n", hash, *((uint64_t*)th->csum)); + + break; + } + + case CSUM_TYPE_SHA256: { + uint8_t hash[SHA256_HASH_SIZE]; + + calc_sha256(hash, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + + if (RtlCompareMemory(hash, th, SHA256_HASH_SIZE) == SHA256_HASH_SIZE) + return true; + + WARN("hash was invalid\n"); + + break; + } + + case CSUM_TYPE_BLAKE2: { + uint8_t hash[BLAKE2_HASH_SIZE]; + + blake2b(hash, sizeof(hash), (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + + if (RtlCompareMemory(hash, th, BLAKE2_HASH_SIZE) == BLAKE2_HASH_SIZE) + return true; + + WARN("hash was invalid\n"); + + break; + } + } + + return false; +} + +void get_sector_csum(device_extension* Vcb, void* buf, void* csum) { + switch (Vcb->superblock.csum_type) { + case CSUM_TYPE_CRC32C: + *(uint32_t*)csum = ~calc_crc32c(0xffffffff, buf, Vcb->superblock.sector_size); + break; + + case CSUM_TYPE_XXHASH: + *(uint64_t*)csum = XXH64(buf, Vcb->superblock.sector_size, 0); + break; + + case CSUM_TYPE_SHA256: + calc_sha256(csum, buf, Vcb->superblock.sector_size); + break; + + case CSUM_TYPE_BLAKE2: + blake2b(csum, BLAKE2_HASH_SIZE, buf, Vcb->superblock.sector_size); + break; + } +} + +bool check_sector_csum(device_extension* Vcb, void* buf, void* csum) { + switch (Vcb->superblock.csum_type) { + case CSUM_TYPE_CRC32C: { + uint32_t crc32 = ~calc_crc32c(0xffffffff, buf, Vcb->superblock.sector_size); + + return *(uint32_t*)csum == crc32; + } + + case CSUM_TYPE_XXHASH: { + uint64_t hash = XXH64(buf, Vcb->superblock.sector_size, 0); + + return *(uint64_t*)csum == hash; + } + + case CSUM_TYPE_SHA256: { + uint8_t hash[SHA256_HASH_SIZE]; + + calc_sha256(hash, buf, Vcb->superblock.sector_size); + + return RtlCompareMemory(hash, csum, SHA256_HASH_SIZE) == SHA256_HASH_SIZE; + } + + case CSUM_TYPE_BLAKE2: { + uint8_t hash[BLAKE2_HASH_SIZE]; + + blake2b(hash, sizeof(hash), buf, Vcb->superblock.sector_size); + + return RtlCompareMemory(hash, csum, BLAKE2_HASH_SIZE) == BLAKE2_HASH_SIZE; + } + } + + return false; +} + static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr, read_data_context* context, CHUNK_ITEM* ci, device** devices, uint64_t generation) { ULONG i; @@ -141,7 +243,7 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr for (j = 0; j < ci->num_stripes; j++) { if (context->stripes[j].status == ReadDataStatus_Error) { - WARN("stripe %u returned error %08x\n", j, context->stripes[j].iosb.Status); + WARN("stripe %u returned error %08lx\n", j, context->stripes[j].iosb.Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); return context->stripes[j].iosb.Status; } else if (context->stripes[j].status == ReadDataStatus_Success) { @@ -155,11 +257,8 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr if (context->tree) { tree_header* th = (tree_header*)buf; - uint32_t crc32; - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, context->buflen - sizeof(th->csum)); - - if (th->address != context->address || crc32 != *((uint32_t*)th->csum)) { + if (th->address != context->address || !check_tree_checksum(Vcb, th)) { checksum_error = true; log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); } else if (generation != 0 && th->generation != generation) { @@ -173,7 +272,7 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr checksum_error = true; log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); } else if (!NT_SUCCESS(Status)) { - ERR("check_csum returned %08x\n", Status); + ERR("check_csum returned %08lx\n", Status); return Status; } } @@ -199,12 +298,12 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr Status = sync_read_phys(devices[j]->devobj, devices[j]->fileobj, cis[j].offset + context->stripes[stripe].stripestart, Vcb->superblock.node_size, (uint8_t*)t2, false); if (!NT_SUCCESS(Status)) { - WARN("sync_read_phys returned %08x\n", Status); + WARN("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); } else { - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&t2->fs_uuid, Vcb->superblock.node_size - sizeof(t2->csum)); + bool checksum_error = !check_tree_checksum(Vcb, t2); - if (t2->address == addr && crc32 == *((uint32_t*)t2->csum) && (generation == 0 || t2->generation == generation)) { + if (t2->address == addr && !checksum_error && (generation == 0 || t2->generation == generation)) { RtlCopyMemory(buf, t2, Vcb->superblock.node_size); ERR("recovering from checksum error at %I64x, device %I64x\n", addr, devices[stripe]->devitem.dev_id); recovered = true; @@ -213,13 +312,13 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr Status = write_data_phys(devices[stripe]->devobj, devices[stripe]->fileobj, cis[stripe].offset + context->stripes[stripe].stripestart, t2, Vcb->superblock.node_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } break; - } else if (t2->address != addr || crc32 != *((uint32_t*)t2->csum)) + } else if (t2->address != addr || checksum_error) log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_CORRUPTION_ERRORS); else log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_GENERATION_ERRORS); @@ -237,6 +336,7 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr } else { ULONG sectors = (ULONG)context->stripes[stripe].Irp->IoStatus.Information / Vcb->superblock.sector_size; uint8_t* sector; + void* ptr = context->csum; sector = ExAllocatePoolWithTag(NonPagedPool, Vcb->superblock.sector_size, ALLOC_TAG); if (!sector) { @@ -245,9 +345,7 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr } for (i = 0; i < sectors; i++) { - uint32_t crc32 = ~calc_crc32c(0xffffffff, buf + (i * Vcb->superblock.sector_size), Vcb->superblock.sector_size); - - if (context->csum[i] != crc32) { + if (!check_sector_csum(Vcb, buf + (i * Vcb->superblock.sector_size), ptr)) { bool recovered = false; for (j = 0; j < ci->num_stripes; j++) { @@ -256,12 +354,10 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr cis[j].offset + context->stripes[stripe].stripestart + UInt32x32To64(i, Vcb->superblock.sector_size), Vcb->superblock.sector_size, sector, false); if (!NT_SUCCESS(Status)) { - WARN("sync_read_phys returned %08x\n", Status); + WARN("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); } else { - uint32_t crc32b = ~calc_crc32c(0xffffffff, sector, Vcb->superblock.sector_size); - - if (crc32b == context->csum[i]) { + if (check_sector_csum(Vcb, sector, ptr)) { RtlCopyMemory(buf + (i * Vcb->superblock.sector_size), sector, Vcb->superblock.sector_size); ERR("recovering from checksum error at %I64x, device %I64x\n", addr + UInt32x32To64(i, Vcb->superblock.sector_size), devices[stripe]->devitem.dev_id); recovered = true; @@ -271,7 +367,7 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr cis[stripe].offset + context->stripes[stripe].stripestart + UInt32x32To64(i, Vcb->superblock.sector_size), sector, Vcb->superblock.sector_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -289,6 +385,8 @@ static NTSTATUS read_data_dup(device_extension* Vcb, uint8_t* buf, uint64_t addr return STATUS_CRC_ERROR; } } + + ptr = (uint8_t*)ptr + Vcb->csum_size; } ExFreePool(sector); @@ -303,7 +401,7 @@ static NTSTATUS read_data_raid0(device_extension* Vcb, uint8_t* buf, uint64_t ad for (i = 0; i < ci->num_stripes; i++) { if (context->stripes[i].status == ReadDataStatus_Error) { - WARN("stripe %I64u returned error %08x\n", i, context->stripes[i].iosb.Status); + WARN("stripe %I64u returned error %08lx\n", i, context->stripes[i].iosb.Status); log_device_error(Vcb, devices[i], BTRFS_DEV_STAT_READ_ERRORS); return context->stripes[i].iosb.Status; } @@ -311,9 +409,9 @@ static NTSTATUS read_data_raid0(device_extension* Vcb, uint8_t* buf, uint64_t ad if (context->tree) { // shouldn't happen, as trees shouldn't cross stripe boundaries tree_header* th = (tree_header*)buf; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); + bool checksum_error = !check_tree_checksum(Vcb, th); - if (crc32 != *((uint32_t*)th->csum) || addr != th->address || (generation != 0 && generation != th->generation)) { + if (checksum_error || addr != th->address || (generation != 0 && generation != th->generation)) { uint64_t off; uint16_t stripe; @@ -321,8 +419,7 @@ static NTSTATUS read_data_raid0(device_extension* Vcb, uint8_t* buf, uint64_t ad ERR("unrecoverable checksum error at %I64x, device %I64x\n", addr, devices[stripe]->devitem.dev_id); - if (crc32 != *((uint32_t*)th->csum)) { - WARN("crc32 was %08x, expected %08x\n", crc32, *((uint32_t*)th->csum)); + if (checksum_error) { log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); return STATUS_CRC_ERROR; } else if (addr != th->address) { @@ -341,10 +438,10 @@ static NTSTATUS read_data_raid0(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = check_csum(Vcb, buf, length / Vcb->superblock.sector_size, context->csum); if (Status == STATUS_CRC_ERROR) { - for (i = 0; i < length / Vcb->superblock.sector_size; i++) { - uint32_t crc32 = ~calc_crc32c(0xffffffff, buf + (i * Vcb->superblock.sector_size), Vcb->superblock.sector_size); + void* ptr = context->csum; - if (context->csum[i] != crc32) { + for (i = 0; i < length / Vcb->superblock.sector_size; i++) { + if (!check_sector_csum(Vcb, buf + (i * Vcb->superblock.sector_size), ptr)) { uint64_t off; uint16_t stripe; @@ -356,11 +453,13 @@ static NTSTATUS read_data_raid0(device_extension* Vcb, uint8_t* buf, uint64_t ad return Status; } + + ptr = (uint8_t*)ptr + Vcb->csum_size; } return Status; } else if (!NT_SUCCESS(Status)) { - ERR("check_csum returned %08x\n", Status); + ERR("check_csum returned %08lx\n", Status); return Status; } } @@ -378,7 +477,7 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a for (j = 0; j < ci->num_stripes; j++) { if (context->stripes[j].status == ReadDataStatus_Error) { - WARN("stripe %I64u returned error %08x\n", j, context->stripes[j].iosb.Status); + WARN("stripe %u returned error %08lx\n", j, context->stripes[j].iosb.Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); return context->stripes[j].iosb.Status; } else if (context->stripes[j].status == ReadDataStatus_Success) @@ -387,10 +486,8 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a if (context->tree) { tree_header* th = (tree_header*)buf; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (crc32 != *((uint32_t*)th->csum)) { - WARN("crc32 was %08x, expected %08x\n", crc32, *((uint32_t*)th->csum)); + if (!check_tree_checksum(Vcb, th)) { checksum_error = true; log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); } else if (addr != th->address) { @@ -408,7 +505,7 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a if (Status == STATUS_CRC_ERROR) checksum_error = true; else if (!NT_SUCCESS(Status)) { - ERR("check_csum returned %08x\n", Status); + ERR("check_csum returned %08lx\n", Status); return Status; } } @@ -444,12 +541,12 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a Status = sync_read_phys(devices[stripe + j]->devobj, devices[stripe + j]->fileobj, cis[stripe + j].offset + off, Vcb->superblock.node_size, (uint8_t*)t2, false); if (!NT_SUCCESS(Status)) { - WARN("sync_read_phys returned %08x\n", Status); + WARN("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[stripe + j], BTRFS_DEV_STAT_READ_ERRORS); } else { - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&t2->fs_uuid, Vcb->superblock.node_size - sizeof(t2->csum)); + bool checksum_error = !check_tree_checksum(Vcb, t2); - if (t2->address == addr && crc32 == *((uint32_t*)t2->csum) && (generation == 0 || t2->generation == generation)) { + if (t2->address == addr && !checksum_error && (generation == 0 || t2->generation == generation)) { RtlCopyMemory(buf, t2, Vcb->superblock.node_size); ERR("recovering from checksum error at %I64x, device %I64x\n", addr, devices[stripe + j]->devitem.dev_id); recovered = true; @@ -458,13 +555,13 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a Status = write_data_phys(devices[stripe + badsubstripe]->devobj, devices[stripe + badsubstripe]->fileobj, cis[stripe + badsubstripe].offset + off, t2, Vcb->superblock.node_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[stripe + badsubstripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } break; - } else if (t2->address != addr || crc32 != *((uint32_t*)t2->csum)) + } else if (t2->address != addr || checksum_error) log_device_error(Vcb, devices[stripe + j], BTRFS_DEV_STAT_CORRUPTION_ERRORS); else log_device_error(Vcb, devices[stripe + j], BTRFS_DEV_STAT_GENERATION_ERRORS); @@ -482,6 +579,7 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a } else { ULONG sectors = length / Vcb->superblock.sector_size; uint8_t* sector; + void* ptr = context->csum; sector = ExAllocatePoolWithTag(NonPagedPool, Vcb->superblock.sector_size, ALLOC_TAG); if (!sector) { @@ -490,9 +588,7 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a } for (i = 0; i < sectors; i++) { - uint32_t crc32 = ~calc_crc32c(0xffffffff, buf + (i * Vcb->superblock.sector_size), Vcb->superblock.sector_size); - - if (context->csum[i] != crc32) { + if (!check_sector_csum(Vcb, buf + (i * Vcb->superblock.sector_size), ptr)) { uint64_t off; uint16_t stripe2, badsubstripe = 0; bool recovered = false; @@ -516,12 +612,10 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a Status = sync_read_phys(devices[stripe2 + j]->devobj, devices[stripe2 + j]->fileobj, cis[stripe2 + j].offset + off, Vcb->superblock.sector_size, sector, false); if (!NT_SUCCESS(Status)) { - WARN("sync_read_phys returned %08x\n", Status); + WARN("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[stripe2 + j], BTRFS_DEV_STAT_READ_ERRORS); } else { - uint32_t crc32b = ~calc_crc32c(0xffffffff, sector, Vcb->superblock.sector_size); - - if (crc32b == context->csum[i]) { + if (check_sector_csum(Vcb, sector, ptr)) { RtlCopyMemory(buf + (i * Vcb->superblock.sector_size), sector, Vcb->superblock.sector_size); ERR("recovering from checksum error at %I64x, device %I64x\n", addr + UInt32x32To64(i, Vcb->superblock.sector_size), devices[stripe2 + j]->devitem.dev_id); recovered = true; @@ -530,7 +624,7 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a Status = write_data_phys(devices[stripe2 + badsubstripe]->devobj, devices[stripe2 + badsubstripe]->fileobj, cis[stripe2 + badsubstripe].offset + off, sector, Vcb->superblock.sector_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[stripe2 + badsubstripe], BTRFS_DEV_STAT_READ_ERRORS); } } @@ -548,6 +642,8 @@ static NTSTATUS read_data_raid10(device_extension* Vcb, uint8_t* buf, uint64_t a return STATUS_CRC_ERROR; } } + + ptr = (uint8_t*)ptr + Vcb->csum_size; } ExFreePool(sector); @@ -567,7 +663,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad for (j = 0; j < ci->num_stripes; j++) { if (context->stripes[j].status == ReadDataStatus_Error) { - WARN("stripe %u returned error %08x\n", j, context->stripes[j].iosb.Status); + WARN("stripe %u returned error %08lx\n", j, context->stripes[j].iosb.Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); return context->stripes[j].iosb.Status; } else if (context->stripes[j].status == ReadDataStatus_Success) { @@ -633,9 +729,8 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad if (context->tree) { tree_header* th = (tree_header*)buf; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (addr != th->address || crc32 != *((uint32_t*)th->csum)) { + if (addr != th->address || !check_tree_checksum(Vcb, th)) { checksum_error = true; if (!no_success && !degraded) log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -652,7 +747,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad WARN("checksum error\n"); checksum_error = true; } else if (!NT_SUCCESS(Status)) { - ERR("check_csum returned %08x\n", Status); + ERR("check_csum returned %08lx\n", Status); return Status; } } else if (degraded) @@ -685,7 +780,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad if (first) { Status = sync_read_phys(devices[j]->devobj, devices[j]->fileobj, cis[j].offset + off, Vcb->superblock.node_size, t2, false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); failed = true; break; @@ -695,7 +790,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad } else { Status = sync_read_phys(devices[j]->devobj, devices[j]->fileobj, cis[j].offset + off, Vcb->superblock.node_size, t2 + Vcb->superblock.node_size, false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); failed = true; break; @@ -712,9 +807,8 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad if (!failed) { tree_header* t3 = (tree_header*)t2; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&t3->fs_uuid, Vcb->superblock.node_size - sizeof(t3->csum)); - if (t3->address == addr && crc32 == *((uint32_t*)t3->csum) && (generation == 0 || t3->generation == generation)) { + if (t3->address == addr && check_tree_checksum(Vcb, t3) && (generation == 0 || t3->generation == generation)) { RtlCopyMemory(buf, t2, Vcb->superblock.node_size); if (!degraded) @@ -725,7 +819,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad if (!Vcb->readonly && devices[stripe] && !devices[stripe]->readonly && devices[stripe]->devobj) { // write good data over bad Status = write_data_phys(devices[stripe]->devobj, devices[stripe]->fileobj, cis[stripe].offset + off, t2, Vcb->superblock.node_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -742,6 +836,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad } else { ULONG sectors = length / Vcb->superblock.sector_size; uint8_t* sector; + void* ptr = context->csum; sector = ExAllocatePoolWithTag(NonPagedPool, Vcb->superblock.sector_size * 2, ALLOC_TAG); if (!sector) { @@ -752,10 +847,6 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad for (i = 0; i < sectors; i++) { uint16_t parity; uint64_t off; - uint32_t crc32; - - if (context->csum) - crc32 = ~calc_crc32c(0xffffffff, buf + (i * Vcb->superblock.sector_size), Vcb->superblock.sector_size); get_raid0_offset(addr - offset + UInt32x32To64(i, Vcb->superblock.sector_size), ci->stripe_length, ci->num_stripes - 1, &off, &stripe); @@ -764,7 +855,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad stripe = (parity + stripe + 1) % ci->num_stripes; - if (!devices[stripe] || !devices[stripe]->devobj || (context->csum && context->csum[i] != crc32)) { + if (!devices[stripe] || !devices[stripe]->devobj || (ptr && !check_sector_csum(Vcb, buf + (i * Vcb->superblock.sector_size), ptr))) { bool recovered = false, first = true, failed = false; if (devices[stripe] && devices[stripe]->devobj) @@ -776,7 +867,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad if (first) { Status = sync_read_phys(devices[j]->devobj, devices[j]->fileobj, cis[j].offset + off, Vcb->superblock.sector_size, sector, false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); failed = true; log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); break; @@ -787,7 +878,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = sync_read_phys(devices[j]->devobj, devices[j]->fileobj, cis[j].offset + off, Vcb->superblock.sector_size, sector + Vcb->superblock.sector_size, false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); failed = true; log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); break; @@ -803,10 +894,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad } if (!failed) { - if (context->csum) - crc32 = ~calc_crc32c(0xffffffff, sector, Vcb->superblock.sector_size); - - if (!context->csum || crc32 == context->csum[i]) { + if (!ptr || check_sector_csum(Vcb, sector, ptr)) { RtlCopyMemory(buf + (i * Vcb->superblock.sector_size), sector, Vcb->superblock.sector_size); if (!degraded) @@ -818,7 +906,7 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = write_data_phys(devices[stripe]->devobj, devices[stripe]->fileobj, cis[stripe].offset + off, sector, Vcb->superblock.sector_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -831,6 +919,9 @@ static NTSTATUS read_data_raid5(device_extension* Vcb, uint8_t* buf, uint64_t ad return STATUS_CRC_ERROR; } } + + if (ptr) + ptr = (uint8_t*)ptr + Vcb->csum_size; } ExFreePool(sector); @@ -936,7 +1027,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad for (j = 0; j < ci->num_stripes; j++) { if (context->stripes[j].status == ReadDataStatus_Error) { - WARN("stripe %u returned error %08x\n", j, context->stripes[j].iosb.Status); + WARN("stripe %u returned error %08lx\n", j, context->stripes[j].iosb.Status); if (devices[j]) log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); @@ -1004,9 +1095,8 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad if (context->tree) { tree_header* th = (tree_header*)buf; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (addr != th->address || crc32 != *((uint32_t*)th->csum)) { + if (addr != th->address || !check_tree_checksum(Vcb, th)) { checksum_error = true; if (!no_success && !degraded && devices[stripe]) log_device_error(Vcb, devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -1023,7 +1113,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad WARN("checksum error\n"); checksum_error = true; } else if (!NT_SUCCESS(Status)) { - ERR("check_csum returned %08x\n", Status); + ERR("check_csum returned %08lx\n", Status); return Status; } } else if (degraded) @@ -1060,7 +1150,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = sync_read_phys(devices[j]->devobj, devices[j]->fileobj, cis[j].offset + off, Vcb->superblock.node_size, sector + (k * Vcb->superblock.node_size), false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); num_errors++; error_stripe = k; @@ -1087,7 +1177,6 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad if (!failed) { if (num_errors == 0) { tree_header* th = (tree_header*)(sector + (stripe * Vcb->superblock.node_size)); - uint32_t crc32; RtlCopyMemory(sector + (stripe * Vcb->superblock.node_size), sector + ((ci->num_stripes - 2) * Vcb->superblock.node_size), Vcb->superblock.node_size); @@ -1097,9 +1186,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad do_xor(sector + (stripe * Vcb->superblock.node_size), sector + (j * Vcb->superblock.node_size), Vcb->superblock.node_size); } - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - - if (th->address == addr && crc32 == *((uint32_t*)th->csum) && (generation == 0 || th->generation == generation)) { + if (th->address == addr && check_tree_checksum(Vcb, th) && (generation == 0 || th->generation == generation)) { RtlCopyMemory(buf, sector + (stripe * Vcb->superblock.node_size), Vcb->superblock.node_size); if (devices[physstripe] && devices[physstripe]->devobj) @@ -1111,7 +1198,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = write_data_phys(devices[physstripe]->devobj, devices[physstripe]->fileobj, cis[physstripe].offset + off, sector + (stripe * Vcb->superblock.node_size), Vcb->superblock.node_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[physstripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -1119,7 +1206,6 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad } if (!recovered) { - uint32_t crc32; tree_header* th = (tree_header*)(sector + (ci->num_stripes * Vcb->superblock.node_size)); bool read_q = false; @@ -1127,7 +1213,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = sync_read_phys(devices[parity2]->devobj, devices[parity2]->fileobj, cis[parity2].offset + off, Vcb->superblock.node_size, sector + ((ci->num_stripes - 1) * Vcb->superblock.node_size), false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); } else read_q = true; @@ -1137,18 +1223,14 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad if (num_errors == 1) { raid6_recover2(sector, ci->num_stripes, Vcb->superblock.node_size, stripe, error_stripe, sector + (ci->num_stripes * Vcb->superblock.node_size)); - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - - if (th->address == addr && crc32 == *((uint32_t*)th->csum) && (generation == 0 || th->generation == generation)) + if (th->address == addr && check_tree_checksum(Vcb, th) && (generation == 0 || th->generation == generation)) recovered = true; } else { for (j = 0; j < ci->num_stripes - 1; j++) { if (j != stripe) { raid6_recover2(sector, ci->num_stripes, Vcb->superblock.node_size, stripe, j, sector + (ci->num_stripes * Vcb->superblock.node_size)); - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - - if (th->address == addr && crc32 == *((uint32_t*)th->csum) && (generation == 0 || th->generation == generation)) { + if (th->address == addr && check_tree_checksum(Vcb, th) && (generation == 0 || th->generation == generation)) { recovered = true; error_stripe = j; break; @@ -1170,7 +1252,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = write_data_phys(devices[physstripe]->devobj, devices[physstripe]->fileobj, cis[physstripe].offset + off, sector + (ci->num_stripes * Vcb->superblock.node_size), Vcb->superblock.node_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[physstripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -1207,7 +1289,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = write_data_phys(devices[error_stripe_phys]->devobj, devices[error_stripe_phys]->fileobj, cis[error_stripe_phys].offset + off, sector + (error_stripe * Vcb->superblock.node_size), Vcb->superblock.node_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[error_stripe_phys], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -1225,6 +1307,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad } else { ULONG sectors = length / Vcb->superblock.sector_size; uint8_t* sector; + void* ptr = context->csum; sector = ExAllocatePoolWithTag(NonPagedPool, Vcb->superblock.sector_size * (ci->num_stripes + 2), ALLOC_TAG); if (!sector) { @@ -1235,10 +1318,6 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad for (i = 0; i < sectors; i++) { uint64_t off; uint16_t physstripe, parity1, parity2; - uint32_t crc32; - - if (context->csum) - crc32 = ~calc_crc32c(0xffffffff, buf + (i * Vcb->superblock.sector_size), Vcb->superblock.sector_size); get_raid0_offset(addr - offset + UInt32x32To64(i, Vcb->superblock.sector_size), ci->stripe_length, ci->num_stripes - 2, &off, &stripe); @@ -1248,7 +1327,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 && context->csum[i] != crc32)) { + if (!devices[physstripe] || !devices[physstripe]->devobj || (context->csum && !check_sector_csum(Vcb, buf + (i * Vcb->superblock.sector_size), ptr))) { uint16_t k, error_stripe; bool recovered = false, failed = false; ULONG num_errors = 0; @@ -1264,7 +1343,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = sync_read_phys(devices[j]->devobj, devices[j]->fileobj, cis[j].offset + off, Vcb->superblock.sector_size, sector + (k * Vcb->superblock.sector_size), false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[j], BTRFS_DEV_STAT_READ_ERRORS); num_errors++; error_stripe = k; @@ -1297,10 +1376,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad do_xor(sector + (stripe * Vcb->superblock.sector_size), sector + (j * Vcb->superblock.sector_size), Vcb->superblock.sector_size); } - if (context->csum) - crc32 = ~calc_crc32c(0xffffffff, sector + (stripe * Vcb->superblock.sector_size), Vcb->superblock.sector_size); - - if (!context->csum || crc32 == context->csum[i]) { + if (!ptr || check_sector_csum(Vcb, sector + (stripe * Vcb->superblock.sector_size), ptr)) { RtlCopyMemory(buf + (i * Vcb->superblock.sector_size), sector + (stripe * Vcb->superblock.sector_size), Vcb->superblock.sector_size); if (devices[physstripe] && devices[physstripe]->devobj) @@ -1313,7 +1389,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = write_data_phys(devices[physstripe]->devobj, devices[physstripe]->fileobj, cis[physstripe].offset + off, sector + (stripe * Vcb->superblock.sector_size), Vcb->superblock.sector_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[physstripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -1327,7 +1403,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = sync_read_phys(devices[parity2]->devobj, devices[parity2]->fileobj, cis[parity2].offset + off, Vcb->superblock.sector_size, sector + ((ci->num_stripes - 1) * Vcb->superblock.sector_size), false); if (!NT_SUCCESS(Status)) { - ERR("sync_read_phys returned %08x\n", Status); + ERR("sync_read_phys returned %08lx\n", Status); log_device_error(Vcb, devices[parity2], BTRFS_DEV_STAT_READ_ERRORS); } else read_q = true; @@ -1339,20 +1415,14 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad if (!devices[physstripe] || !devices[physstripe]->devobj) recovered = true; - else { - crc32 = ~calc_crc32c(0xffffffff, sector + (ci->num_stripes * Vcb->superblock.sector_size), Vcb->superblock.sector_size); - - if (crc32 == context->csum[i]) - recovered = true; - } + else + recovered = check_sector_csum(Vcb, sector + (ci->num_stripes * Vcb->superblock.sector_size), ptr); } else { for (j = 0; j < ci->num_stripes - 1; j++) { if (j != stripe) { raid6_recover2(sector, ci->num_stripes, Vcb->superblock.sector_size, stripe, j, sector + (ci->num_stripes * Vcb->superblock.sector_size)); - crc32 = ~calc_crc32c(0xffffffff, sector + (ci->num_stripes * Vcb->superblock.sector_size), Vcb->superblock.sector_size); - - if (crc32 == context->csum[i]) { + if (check_sector_csum(Vcb, sector + (ci->num_stripes * Vcb->superblock.sector_size), ptr)) { recovered = true; error_stripe = j; break; @@ -1375,7 +1445,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = write_data_phys(devices[physstripe]->devobj, devices[physstripe]->fileobj, cis[physstripe].offset + off, sector + (ci->num_stripes * Vcb->superblock.sector_size), Vcb->superblock.sector_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[physstripe], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -1414,7 +1484,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad Status = write_data_phys(devices[error_stripe_phys]->devobj, devices[error_stripe_phys]->fileobj, cis[error_stripe_phys].offset + off, sector + (error_stripe * Vcb->superblock.sector_size), Vcb->superblock.sector_size); if (!NT_SUCCESS(Status)) { - WARN("write_data_phys returned %08x\n", Status); + WARN("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, devices[error_stripe_phys], BTRFS_DEV_STAT_WRITE_ERRORS); } } @@ -1428,6 +1498,9 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad return STATUS_CRC_ERROR; } } + + if (ptr) + ptr = (uint8_t*)ptr + Vcb->csum_size; } ExFreePool(sector); @@ -1436,7 +1509,7 @@ static NTSTATUS read_data_raid6(device_extension* Vcb, uint8_t* buf, uint64_t ad return STATUS_SUCCESS; } -NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t length, _In_reads_bytes_opt_(length*sizeof(uint32_t)/Vcb->superblock.sector_size) uint32_t* csum, +NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t length, _In_reads_bytes_opt_(length*sizeof(uint32_t)/Vcb->superblock.sector_size) void* csum, _In_ bool is_tree, _Out_writes_bytes_(length) uint8_t* buf, _In_opt_ chunk* c, _Out_opt_ chunk** pc, _In_opt_ PIRP Irp, _In_ uint64_t generation, _In_ bool file_read, _In_ ULONG priority) { CHUNK_ITEM* ci; @@ -1528,6 +1601,12 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } else if (ci->type & BLOCK_FLAG_RAID6) { type = BLOCK_FLAG_RAID6; allowed_missing = 2; + } else if (ci->type & BLOCK_FLAG_RAID1C3) { + type = BLOCK_FLAG_DUPLICATE; + allowed_missing = 2; + } else if (ci->type & BLOCK_FLAG_RAID1C4) { + type = BLOCK_FLAG_DUPLICATE; + allowed_missing = 3; } else { // SINGLE type = BLOCK_FLAG_DUPLICATE; allowed_missing = 0; @@ -1607,7 +1686,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(master_mdl); goto exit; } @@ -1743,7 +1822,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(master_mdl); goto exit; } @@ -1937,7 +2016,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); goto exit; } } @@ -1979,7 +2058,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(master_mdl); goto exit; } @@ -2238,7 +2317,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(master_mdl); goto exit; } @@ -2577,7 +2656,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t if (type == BLOCK_FLAG_RAID0) { Status = read_data_raid0(Vcb, file_read ? context.va : buf, addr, length, &context, ci, devices, generation, offset); if (!NT_SUCCESS(Status)) { - ERR("read_data_raid0 returned %08x\n", Status); + ERR("read_data_raid0 returned %08lx\n", Status); if (file_read) ExFreePool(context.va); @@ -2593,7 +2672,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t Status = read_data_raid10(Vcb, file_read ? context.va : buf, addr, length, &context, ci, devices, generation, offset); if (!NT_SUCCESS(Status)) { - ERR("read_data_raid10 returned %08x\n", Status); + ERR("read_data_raid10 returned %08lx\n", Status); if (file_read) ExFreePool(context.va); @@ -2608,7 +2687,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } else if (type == BLOCK_FLAG_DUPLICATE) { Status = read_data_dup(Vcb, file_read ? context.va : buf, addr, &context, ci, devices, generation); if (!NT_SUCCESS(Status)) { - ERR("read_data_dup returned %08x\n", Status); + ERR("read_data_dup returned %08lx\n", Status); if (file_read) ExFreePool(context.va); @@ -2623,7 +2702,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } else if (type == BLOCK_FLAG_RAID5) { Status = read_data_raid5(Vcb, file_read ? context.va : buf, addr, length, &context, ci, devices, offset, generation, c, missing_devices > 0 ? true : false); if (!NT_SUCCESS(Status)) { - ERR("read_data_raid5 returned %08x\n", Status); + ERR("read_data_raid5 returned %08lx\n", Status); if (file_read) ExFreePool(context.va); @@ -2638,7 +2717,7 @@ NTSTATUS read_data(_In_ device_extension* Vcb, _In_ uint64_t addr, _In_ uint32_t } else if (type == BLOCK_FLAG_RAID6) { Status = read_data_raid6(Vcb, file_read ? context.va : buf, addr, length, &context, ci, devices, offset, generation, c, missing_devices > 0 ? true : false); if (!NT_SUCCESS(Status)) { - ERR("read_data_raid6 returned %08x\n", Status); + ERR("read_data_raid6 returned %08lx\n", Status); if (file_read) ExFreePool(context.va); @@ -2685,7 +2764,7 @@ exit: NTSTATUS read_stream(fcb* fcb, uint8_t* data, uint64_t start, ULONG length, ULONG* pbr) { ULONG readlen; - TRACE("(%p, %p, %I64x, %I64x, %p)\n", fcb, data, start, length, pbr); + TRACE("(%p, %p, %I64x, %lx, %p)\n", fcb, data, start, length, pbr); if (pbr) *pbr = 0; @@ -2705,20 +2784,54 @@ NTSTATUS read_stream(fcb* fcb, uint8_t* data, uint64_t start, ULONG length, ULON readlen = fcb->adsdata.Length - (ULONG)start; if (readlen > 0) - RtlCopyMemory(data + start, fcb->adsdata.Buffer, readlen); + RtlCopyMemory(data, fcb->adsdata.Buffer + start, readlen); if (pbr) *pbr = readlen; return STATUS_SUCCESS; } +typedef struct { + uint64_t off; + uint64_t ed_size; + uint64_t ed_offset; + uint64_t ed_num_bytes; +} read_part_extent; + +typedef struct { + LIST_ENTRY list_entry; + uint64_t addr; + chunk* c; + uint32_t read; + uint32_t to_read; + void* csum; + bool csum_free; + uint8_t* buf; + bool buf_free; + uint32_t bumpoff; + bool mdl; + void* data; + uint8_t compression; + unsigned int num_extents; + read_part_extent extents[1]; +} read_part; + +typedef struct { + LIST_ENTRY list_entry; + calc_job* cj; + void* decomp; + void* data; + unsigned int offset; + size_t length; +} comp_calc_job; + NTSTATUS read_file(fcb* fcb, uint8_t* data, uint64_t start, uint64_t length, ULONG* pbr, PIRP Irp) { NTSTATUS Status; - EXTENT_DATA* ed; uint32_t bytes_read = 0; uint64_t last_end; LIST_ENTRY* le; POOL_TYPE pool_type; + LIST_ENTRY read_parts, calc_jobs; TRACE("(%p, %p, %I64x, %I64x, %p)\n", fcb, data, start, length, pbr); @@ -2727,10 +2840,12 @@ NTSTATUS read_file(fcb* fcb, uint8_t* data, uint64_t start, uint64_t length, ULO if (start >= fcb->inode_item.st_size) { WARN("Tried to read beyond end of file\n"); - Status = STATUS_END_OF_FILE; - goto exit; + return STATUS_END_OF_FILE; } + InitializeListHead(&read_parts); + InitializeListHead(&calc_jobs); + pool_type = fcb->Header.Flags2 & FSRTL_FLAG2_IS_PAGING_FILE ? NonPagedPool : PagedPool; le = fcb->extents.Flink; @@ -2740,12 +2855,10 @@ NTSTATUS read_file(fcb* fcb, uint8_t* data, uint64_t start, uint64_t length, ULO while (le != &fcb->extents) { uint64_t len; extent* ext = CONTAINING_RECORD(le, extent, list_entry); - EXTENT_DATA2* ed2; if (!ext->ignore) { - ed = &ext->extent_data; - - ed2 = (ed->type == EXTENT_TYPE_REGULAR || ed->type == EXTENT_TYPE_PREALLOC) ? (EXTENT_DATA2*)ed->data : NULL; + EXTENT_DATA* ed = &ext->extent_data; + EXTENT_DATA2* ed2 = (ed->type == EXTENT_TYPE_REGULAR || ed->type == EXTENT_TYPE_PREALLOC) ? (EXTENT_DATA2*)ed->data : NULL; len = ed2 ? ed2->num_bytes : ed->decoded_size; @@ -2817,7 +2930,7 @@ NTSTATUS read_file(fcb* fcb, uint8_t* data, uint64_t start, uint64_t length, ULO if (ed->compression == BTRFS_COMPRESSION_ZLIB) { Status = zlib_decompress(ed->data, inlen, decomp, (uint32_t)(read + off)); if (!NT_SUCCESS(Status)) { - ERR("zlib_decompress returned %08x\n", Status); + ERR("zlib_decompress returned %08lx\n", Status); if (decomp_alloc) ExFreePool(decomp); goto exit; } @@ -2832,14 +2945,14 @@ NTSTATUS read_file(fcb* fcb, uint8_t* data, uint64_t start, uint64_t length, ULO Status = lzo_decompress(ed->data + sizeof(uint32_t), inlen, decomp, (uint32_t)(read + off), sizeof(uint32_t)); if (!NT_SUCCESS(Status)) { - ERR("lzo_decompress returned %08x\n", Status); + ERR("lzo_decompress returned %08lx\n", Status); if (decomp_alloc) ExFreePool(decomp); goto exit; } } else if (ed->compression == BTRFS_COMPRESSION_ZSTD) { Status = zstd_decompress(ed->data, inlen, decomp, (uint32_t)(read + off)); if (!NT_SUCCESS(Status)) { - ERR("zstd_decompress returned %08x\n", Status); + ERR("zstd_decompress returned %08lx\n", Status); if (decomp_alloc) ExFreePool(decomp); goto exit; } @@ -2863,192 +2976,87 @@ NTSTATUS read_file(fcb* fcb, uint8_t* data, uint64_t start, uint64_t length, ULO case EXTENT_TYPE_REGULAR: { - uint64_t off = start + bytes_read - ext->offset; - uint32_t to_read, read; - uint8_t* buf; - bool mdl = (Irp && Irp->MdlAddress) ? true : false; - bool buf_free; - uint32_t bumpoff = 0, *csum; - uint64_t addr; - chunk* c; + read_part* rp; - read = (uint32_t)(len - off); - if (read > length) read = (uint32_t)length; + rp = ExAllocatePoolWithTag(pool_type, sizeof(read_part), ALLOC_TAG); + if (!rp) { + ERR("out of memory\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + + rp->mdl = (Irp && Irp->MdlAddress) ? true : false; + rp->extents[0].off = start + bytes_read - ext->offset; + rp->bumpoff = 0; + rp->num_extents = 1; + rp->csum_free = false; + + rp->read = (uint32_t)(len - rp->extents[0].off); + if (rp->read > length) rp->read = (uint32_t)length; if (ed->compression == BTRFS_COMPRESSION_NONE) { - addr = ed2->address + ed2->offset + off; - to_read = (uint32_t)sector_align(read, fcb->Vcb->superblock.sector_size); + rp->addr = ed2->address + ed2->offset + rp->extents[0].off; + rp->to_read = (uint32_t)sector_align(rp->read, fcb->Vcb->superblock.sector_size); - if (addr % fcb->Vcb->superblock.sector_size > 0) { - bumpoff = addr % fcb->Vcb->superblock.sector_size; - addr -= bumpoff; - to_read = (uint32_t)sector_align(read + bumpoff, fcb->Vcb->superblock.sector_size); + if (rp->addr % fcb->Vcb->superblock.sector_size > 0) { + rp->bumpoff = rp->addr % fcb->Vcb->superblock.sector_size; + rp->addr -= rp->bumpoff; + rp->to_read = (uint32_t)sector_align(rp->read + rp->bumpoff, fcb->Vcb->superblock.sector_size); } } else { - addr = ed2->address; - to_read = (uint32_t)sector_align(ed2->size, fcb->Vcb->superblock.sector_size); + rp->addr = ed2->address; + rp->to_read = (uint32_t)sector_align(ed2->size, fcb->Vcb->superblock.sector_size); } if (ed->compression == BTRFS_COMPRESSION_NONE && start % fcb->Vcb->superblock.sector_size == 0 && length % fcb->Vcb->superblock.sector_size == 0) { - buf = data + bytes_read; - buf_free = false; + rp->buf = data + bytes_read; + rp->buf_free = false; } else { - buf = ExAllocatePoolWithTag(pool_type, to_read, ALLOC_TAG); - buf_free = true; + rp->buf = ExAllocatePoolWithTag(pool_type, rp->to_read, ALLOC_TAG); + rp->buf_free = true; - if (!buf) { + if (!rp->buf) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; + ExFreePool(rp); goto exit; } - mdl = false; + rp->mdl = false; } - c = get_chunk_from_address(fcb->Vcb, addr); + rp->c = get_chunk_from_address(fcb->Vcb, rp->addr); - if (!c) { - ERR("get_chunk_from_address(%I64x) failed\n", addr); + if (!rp->c) { + ERR("get_chunk_from_address(%I64x) failed\n", rp->addr); - if (buf_free) - ExFreePool(buf); + if (rp->buf_free) + ExFreePool(rp->buf); + + ExFreePool(rp); goto exit; } if (ext->csum) { - if (ed->compression == BTRFS_COMPRESSION_NONE) - csum = &ext->csum[off / fcb->Vcb->superblock.sector_size]; - else - csum = ext->csum; - } else - csum = NULL; - - Status = read_data(fcb->Vcb, addr, to_read, csum, false, buf, c, NULL, Irp, 0, mdl, - fcb && fcb->Header.Flags2 & FSRTL_FLAG2_IS_PAGING_FILE ? HighPagePriority : NormalPagePriority); - if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); - - if (buf_free) - ExFreePool(buf); - - goto exit; - } - - if (ed->compression == BTRFS_COMPRESSION_NONE) { - if (buf_free) - RtlCopyMemory(data + bytes_read, buf + bumpoff, read); - } else { - uint8_t *decomp = NULL, *buf2; - ULONG outlen, inlen, off2; - uint32_t inpageoff = 0; - - off2 = (ULONG)(ed2->offset + off); - buf2 = buf; - inlen = (ULONG)ed2->size; - - if (ed->compression == BTRFS_COMPRESSION_LZO) { - ULONG inoff = sizeof(uint32_t); - - inlen -= sizeof(uint32_t); - - // If reading a few sectors in, skip to the interesting bit - while (off2 > LZO_PAGE_SIZE) { - uint32_t partlen; - - if (inlen < sizeof(uint32_t)) - break; - - partlen = *(uint32_t*)(buf2 + inoff); - - if (partlen < inlen) { - off2 -= LZO_PAGE_SIZE; - inoff += partlen + sizeof(uint32_t); - inlen -= partlen + sizeof(uint32_t); - - if (LZO_PAGE_SIZE - (inoff % LZO_PAGE_SIZE) < sizeof(uint32_t)) - inoff = ((inoff / LZO_PAGE_SIZE) + 1) * LZO_PAGE_SIZE; - } else - break; - } - - buf2 = &buf2[inoff]; - inpageoff = inoff % LZO_PAGE_SIZE; - } - - if (off2 != 0) { - outlen = off2 + min(read, (uint32_t)(ed2->num_bytes - off)); - - decomp = ExAllocatePoolWithTag(pool_type, outlen, ALLOC_TAG); - if (!decomp) { - ERR("out of memory\n"); - ExFreePool(buf); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto exit; - } + if (ed->compression == BTRFS_COMPRESSION_NONE) { + rp->csum = (uint8_t*)ext->csum + (fcb->Vcb->csum_size * (rp->extents[0].off / fcb->Vcb->superblock.sector_size)); } else - outlen = min(read, (uint32_t)(ed2->num_bytes - off)); + rp->csum = ext->csum; + } else + rp->csum = NULL; - if (ed->compression == BTRFS_COMPRESSION_ZLIB) { - Status = zlib_decompress(buf2, inlen, decomp ? decomp : (data + bytes_read), outlen); + rp->data = data + bytes_read; + rp->compression = ed->compression; + rp->extents[0].ed_offset = ed2->offset; + rp->extents[0].ed_size = ed2->size; + rp->extents[0].ed_num_bytes = ed2->num_bytes; - if (!NT_SUCCESS(Status)) { - ERR("zlib_decompress returned %08x\n", Status); - ExFreePool(buf); + InsertTailList(&read_parts, &rp->list_entry); - if (decomp) - ExFreePool(decomp); - - goto exit; - } - } else if (ed->compression == BTRFS_COMPRESSION_LZO) { - Status = lzo_decompress(buf2, inlen, decomp ? decomp : (data + bytes_read), outlen, inpageoff); - - if (!NT_SUCCESS(Status)) { - ERR("lzo_decompress returned %08x\n", Status); - ExFreePool(buf); - - if (decomp) - ExFreePool(decomp); - - goto exit; - } - } else if (ed->compression == BTRFS_COMPRESSION_ZSTD) { - Status = zstd_decompress(buf2, inlen, decomp ? decomp : (data + bytes_read), outlen); - - if (!NT_SUCCESS(Status)) { - ERR("zstd_decompress returned %08x\n", Status); - ExFreePool(buf); - - if (decomp) - ExFreePool(decomp); - - goto exit; - } - } else { - ERR("unsupported compression type %x\n", ed->compression); - Status = STATUS_NOT_SUPPORTED; - - ExFreePool(buf); - - if (decomp) - ExFreePool(decomp); - - goto exit; - } - - if (decomp) { - RtlCopyMemory(data + bytes_read, decomp + off2, (size_t)min(read, ed2->num_bytes - off)); - ExFreePool(decomp); - } - } - - if (buf_free) - ExFreePool(buf); - - bytes_read += read; - length -= read; + bytes_read += rp->read; + length -= rp->read; break; } @@ -3084,6 +3092,211 @@ nextitem: le = le->Flink; } + if (!IsListEmpty(&read_parts) && read_parts.Flink->Flink != &read_parts) { // at least two entries in list + read_part* last_rp = CONTAINING_RECORD(read_parts.Flink, read_part, list_entry); + + le = read_parts.Flink->Flink; + while (le != &read_parts) { + LIST_ENTRY* le2 = le->Flink; + read_part* rp = CONTAINING_RECORD(le, read_part, list_entry); + + // merge together runs + if (rp->compression != BTRFS_COMPRESSION_NONE && rp->compression == last_rp->compression && rp->addr == last_rp->addr + last_rp->to_read && + rp->data == (uint8_t*)last_rp->data + last_rp->read && rp->c == last_rp->c && ((rp->csum && last_rp->csum) || (!rp->csum && !last_rp->csum))) { + read_part* rp2; + + rp2 = ExAllocatePoolWithTag(pool_type, offsetof(read_part, extents) + (sizeof(read_part_extent) * (last_rp->num_extents + 1)), ALLOC_TAG); + + rp2->addr = last_rp->addr; + rp2->c = last_rp->c; + rp2->read = last_rp->read + rp->read; + rp2->to_read = last_rp->to_read + rp->to_read; + rp2->csum_free = false; + + if (last_rp->csum) { + uint32_t sectors = (last_rp->to_read + rp->to_read) / fcb->Vcb->superblock.sector_size; + + rp2->csum = ExAllocatePoolWithTag(pool_type, sectors * fcb->Vcb->csum_size, ALLOC_TAG); + if (!rp2->csum) { + ERR("out of memory\n"); + ExFreePool(rp2); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + + RtlCopyMemory(rp2->csum, last_rp->csum, last_rp->to_read * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size); + RtlCopyMemory((uint8_t*)rp2->csum + (last_rp->to_read * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size), rp->csum, + rp->to_read * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size); + + rp2->csum_free = true; + } else + rp2->csum = NULL; + + rp2->buf = ExAllocatePoolWithTag(pool_type, rp2->to_read, ALLOC_TAG); + if (!rp2->buf) { + ERR("out of memory\n"); + + if (rp2->csum) + ExFreePool(rp2->csum); + + ExFreePool(rp2); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + + rp2->buf_free = true; + rp2->bumpoff = 0; + rp2->mdl = false; + rp2->data = last_rp->data; + rp2->compression = last_rp->compression; + rp2->num_extents = last_rp->num_extents + 1; + + RtlCopyMemory(rp2->extents, last_rp->extents, last_rp->num_extents * sizeof(read_part_extent)); + RtlCopyMemory(&rp2->extents[last_rp->num_extents], rp->extents, sizeof(read_part_extent)); + + InsertHeadList(le->Blink, &rp2->list_entry); + + if (rp->buf_free) + ExFreePool(rp->buf); + + if (rp->csum_free) + ExFreePool(rp->csum); + + RemoveEntryList(&rp->list_entry); + + ExFreePool(rp); + + if (last_rp->buf_free) + ExFreePool(last_rp->buf); + + if (last_rp->csum_free) + ExFreePool(last_rp->csum); + + RemoveEntryList(&last_rp->list_entry); + + ExFreePool(last_rp); + + last_rp = rp2; + } else + last_rp = rp; + + le = le2; + } + } + + le = read_parts.Flink; + while (le != &read_parts) { + read_part* rp = CONTAINING_RECORD(le, read_part, list_entry); + + Status = read_data(fcb->Vcb, rp->addr, rp->to_read, rp->csum, false, rp->buf, rp->c, NULL, Irp, 0, rp->mdl, + fcb && fcb->Header.Flags2 & FSRTL_FLAG2_IS_PAGING_FILE ? HighPagePriority : NormalPagePriority); + if (!NT_SUCCESS(Status)) { + ERR("read_data returned %08lx\n", Status); + goto exit; + } + + if (rp->compression == BTRFS_COMPRESSION_NONE) { + if (rp->buf_free) + RtlCopyMemory(rp->data, rp->buf + rp->bumpoff, rp->read); + } else { + uint8_t* buf = rp->buf; +#ifdef __REACTOS__ + unsigned int i; + for (i = 0; i < rp->num_extents; i++) { +#else + for (unsigned int i = 0; i < rp->num_extents; i++) { +#endif // __REACTOS__ + uint8_t *decomp = NULL, *buf2; + ULONG outlen, inlen, off2; + uint32_t inpageoff = 0; + comp_calc_job* ccj; + + off2 = (ULONG)(rp->extents[i].ed_offset + rp->extents[i].off); + buf2 = buf; + inlen = (ULONG)rp->extents[i].ed_size; + + if (rp->compression == BTRFS_COMPRESSION_LZO) { + ULONG inoff = sizeof(uint32_t); + + inlen -= sizeof(uint32_t); + + // If reading a few sectors in, skip to the interesting bit + while (off2 > LZO_PAGE_SIZE) { + uint32_t partlen; + + if (inlen < sizeof(uint32_t)) + break; + + partlen = *(uint32_t*)(buf2 + inoff); + + if (partlen < inlen) { + off2 -= LZO_PAGE_SIZE; + inoff += partlen + sizeof(uint32_t); + inlen -= partlen + sizeof(uint32_t); + + if (LZO_PAGE_SIZE - (inoff % LZO_PAGE_SIZE) < sizeof(uint32_t)) + inoff = ((inoff / LZO_PAGE_SIZE) + 1) * LZO_PAGE_SIZE; + } else + break; + } + + buf2 = &buf2[inoff]; + 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)); + + decomp = ExAllocatePoolWithTag(pool_type, outlen, ALLOC_TAG); + if (!decomp) { + ERR("out of memory\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + } else + outlen = min(rp->read, (uint32_t)(rp->extents[i].ed_num_bytes - rp->extents[i].off)); + + ccj = (comp_calc_job*)ExAllocatePoolWithTag(pool_type, sizeof(comp_calc_job), ALLOC_TAG); + if (!ccj) { + ERR("out of memory\n"); + + if (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, + inpageoff, &ccj->cj); + if (!NT_SUCCESS(Status)) { + ERR("add_calc_job_decomp returned %08lx\n", Status); + + if (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; + rp->data = (uint8_t*)rp->data + rp->extents[i].ed_num_bytes - rp->extents[i].off; + rp->read -= (uint32_t)(rp->extents[i].ed_num_bytes - rp->extents[i].off); + } + } + + le = le->Flink; + } + if (length > 0 && start + bytes_read < fcb->inode_item.st_size) { uint32_t read = (uint32_t)min(fcb->inode_item.st_size - start - bytes_read, length); @@ -3094,10 +3307,54 @@ nextitem: } Status = STATUS_SUCCESS; + + while (!IsListEmpty(&calc_jobs)) { + comp_calc_job* ccj = CONTAINING_RECORD(RemoveTailList(&calc_jobs), comp_calc_job, list_entry); + + calc_thread_main(fcb->Vcb, ccj->cj); + + KeWaitForSingleObject(&ccj->cj->event, Executive, KernelMode, false, NULL); + + 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); + } + + ExFreePool(ccj); + } + if (pbr) *pbr = bytes_read; exit: + while (!IsListEmpty(&read_parts)) { + read_part* rp = CONTAINING_RECORD(RemoveHeadList(&read_parts), read_part, list_entry); + + if (rp->buf_free) + ExFreePool(rp->buf); + + if (rp->csum_free) + ExFreePool(rp->csum); + + ExFreePool(rp); + } + + while (!IsListEmpty(&calc_jobs)) { + comp_calc_job* ccj = CONTAINING_RECORD(RemoveHeadList(&calc_jobs), comp_calc_job, list_entry); + + KeWaitForSingleObject(&ccj->cj->event, Executive, KernelMode, false, NULL); + + if (ccj->decomp) + ExFreePool(ccj->decomp); + + ExFreePool(ccj->cj); + + ExFreePool(ccj); + } + return Status; } @@ -3115,7 +3372,7 @@ NTSTATUS do_read(PIRP Irp, bool wait, ULONG* bytes_read) { return STATUS_INTERNAL_ERROR; TRACE("fcb = %p\n", fcb); - TRACE("offset = %I64x, length = %x\n", start, length); + TRACE("offset = %I64x, length = %lx\n", start, length); TRACE("paging_io = %s, no cache = %s\n", Irp->Flags & IRP_PAGING_IO ? "true" : "false", Irp->Flags & IRP_NOCACHE ? "true" : "false"); if (!fcb->ads && fcb->type == BTRFS_TYPE_DIRECTORY) @@ -3178,9 +3435,9 @@ NTSTATUS do_read(PIRP Irp, bool wait, ULONG* bytes_read) { CcMdlRead(FileObject,&IrpSp->Parameters.Read.ByteOffset, length, &Irp->MdlAddress, &Irp->IoStatus); } else { if (fCcCopyReadEx) { - TRACE("CcCopyReadEx(%p, %I64x, %x, %u, %p, %p, %p, %p)\n", FileObject, IrpSp->Parameters.Read.ByteOffset.QuadPart, + TRACE("CcCopyReadEx(%p, %I64x, %lx, %u, %p, %p, %p)\n", FileObject, IrpSp->Parameters.Read.ByteOffset.QuadPart, length, wait, data, &Irp->IoStatus, Irp->Tail.Overlay.Thread); - TRACE("sizes = %I64x, %I64x, %I64x\n", fcb->Header.AllocationSize, fcb->Header.FileSize, fcb->Header.ValidDataLength); + TRACE("sizes = %I64x, %I64x, %I64x\n", fcb->Header.AllocationSize.QuadPart, fcb->Header.FileSize.QuadPart, fcb->Header.ValidDataLength.QuadPart); if (!fCcCopyReadEx(FileObject, &IrpSp->Parameters.Read.ByteOffset, length, wait, data, &Irp->IoStatus, Irp->Tail.Overlay.Thread)) { TRACE("CcCopyReadEx could not wait\n"); @@ -3189,8 +3446,8 @@ NTSTATUS do_read(PIRP Irp, bool wait, ULONG* bytes_read) { } TRACE("CcCopyReadEx finished\n"); } else { - TRACE("CcCopyRead(%p, %I64x, %x, %u, %p, %p)\n", FileObject, IrpSp->Parameters.Read.ByteOffset.QuadPart, length, wait, data, &Irp->IoStatus); - TRACE("sizes = %I64x, %I64x, %I64x\n", fcb->Header.AllocationSize, fcb->Header.FileSize, fcb->Header.ValidDataLength); + TRACE("CcCopyRead(%p, %I64x, %lx, %u, %p, %p)\n", FileObject, IrpSp->Parameters.Read.ByteOffset.QuadPart, length, wait, data, &Irp->IoStatus); + TRACE("sizes = %I64x, %I64x, %I64x\n", fcb->Header.AllocationSize.QuadPart, fcb->Header.FileSize.QuadPart, fcb->Header.ValidDataLength.QuadPart); if (!CcCopyRead(FileObject, &IrpSp->Parameters.Read.ByteOffset, length, wait, data, &Irp->IoStatus)) { TRACE("CcCopyRead could not wait\n"); @@ -3209,7 +3466,7 @@ NTSTATUS do_read(PIRP Irp, bool wait, ULONG* bytes_read) { Irp->IoStatus.Information += addon; *bytes_read = (ULONG)Irp->IoStatus.Information; } else - ERR("EXCEPTION - %08x\n", Status); + ERR("EXCEPTION - %08lx\n", Status); return Status; } else { @@ -3220,13 +3477,20 @@ NTSTATUS do_read(PIRP Irp, bool wait, ULONG* bytes_read) { return STATUS_PENDING; } - if (fcb->ads) + if (fcb->ads) { Status = read_stream(fcb, data, start, length, bytes_read); - else + + if (!NT_SUCCESS(Status)) + ERR("read_stream returned %08lx\n", Status); + } else { Status = read_file(fcb, data, start, length, bytes_read, Irp); + if (!NT_SUCCESS(Status)) + ERR("read_file returned %08lx\n", Status); + } + *bytes_read += addon; - TRACE("read %u bytes\n", *bytes_read); + TRACE("read %lu bytes\n", *bytes_read); Irp->IoStatus.Information = *bytes_read; @@ -3333,7 +3597,7 @@ NTSTATUS __stdcall drv_read(PDEVICE_OBJECT DeviceObject, PIRP Irp) { CcFlushCache(FileObject->SectionObjectPointer, &IrpSp->Parameters.Read.ByteOffset, IrpSp->Parameters.Read.Length, &iosb); if (!NT_SUCCESS(iosb.Status)) { - ERR("CcFlushCache returned %08x\n", iosb.Status); + ERR("CcFlushCache returned %08lx\n", iosb.Status); return iosb.Status; } } @@ -3360,9 +3624,9 @@ exit: end: Irp->IoStatus.Status = Status; - TRACE("Irp->IoStatus.Status = %08x\n", Irp->IoStatus.Status); - TRACE("Irp->IoStatus.Information = %lu\n", Irp->IoStatus.Information); - TRACE("returning %08x\n", Status); + TRACE("Irp->IoStatus.Status = %08lx\n", Irp->IoStatus.Status); + TRACE("Irp->IoStatus.Information = %Iu\n", Irp->IoStatus.Information); + TRACE("returning %08lx\n", Status); if (Status != STATUS_PENDING) IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/drivers/filesystems/btrfs/registry.c b/drivers/filesystems/btrfs/registry.c index 398d700b637..3f70cf83b14 100644 --- a/drivers/filesystems/btrfs/registry.c +++ b/drivers/filesystems/btrfs/registry.c @@ -101,7 +101,7 @@ NTSTATUS registry_load_volume_options(device_extension* Vcb) { Status = STATUS_SUCCESS; goto end; } else if (!NT_SUCCESS(Status)) { - ERR("ZwOpenKey returned %08x\n", Status); + ERR("ZwOpenKey returned %08lx\n", Status); goto end; } @@ -201,7 +201,7 @@ NTSTATUS registry_load_volume_options(device_extension* Vcb) { options->no_root_dir = *val; } } else if (Status != STATUS_NO_MORE_ENTRIES) { - ERR("ZwEnumerateValueKey returned %08x\n", Status); + ERR("ZwEnumerateValueKey returned %08lx\n", Status); goto end2; } } while (NT_SUCCESS(Status)); @@ -270,7 +270,7 @@ NTSTATUS registry_mark_volume_mounted(BTRFS_UUID* uuid) { Status = ZwCreateKey(&h, KEY_SET_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); if (!NT_SUCCESS(Status)) { - ERR("ZwCreateKey returned %08x\n", Status); + ERR("ZwCreateKey returned %08lx\n", Status); goto end; } @@ -281,7 +281,7 @@ NTSTATUS registry_mark_volume_mounted(BTRFS_UUID* uuid) { Status = ZwSetValueKey(h, &mountedus, 0, REG_DWORD, &data, sizeof(DWORD)); if (!NT_SUCCESS(Status)) { - ERR("ZwSetValueKey returned %08x\n", Status); + ERR("ZwSetValueKey returned %08lx\n", Status); goto end2; } @@ -318,7 +318,7 @@ static NTSTATUS registry_mark_volume_unmounted_path(PUNICODE_STRING path) { Status = ZwOpenKey(&h, KEY_QUERY_VALUE | KEY_SET_VALUE | DELETE, &oa); if (!NT_SUCCESS(Status)) { - ERR("ZwOpenKey returned %08x\n", Status); + ERR("ZwOpenKey returned %08lx\n", Status); goto end; } @@ -343,7 +343,7 @@ static NTSTATUS registry_mark_volume_unmounted_path(PUNICODE_STRING path) { break; } } else if (Status != STATUS_NO_MORE_ENTRIES) { - ERR("ZwEnumerateValueKey returned %08x\n", Status); + ERR("ZwEnumerateValueKey returned %08lx\n", Status); goto end2; } } while (NT_SUCCESS(Status)); @@ -353,13 +353,13 @@ static NTSTATUS registry_mark_volume_unmounted_path(PUNICODE_STRING path) { Status = ZwSetValueKey(h, &mountedus, 0, REG_DWORD, &data, sizeof(DWORD)); if (!NT_SUCCESS(Status)) { - ERR("ZwSetValueKey returned %08x\n", Status); + ERR("ZwSetValueKey returned %08lx\n", Status); goto end2; } } else { Status = ZwDeleteKey(h); if (!NT_SUCCESS(Status)) { - ERR("ZwDeleteKey returned %08x\n", Status); + ERR("ZwDeleteKey returned %08lx\n", Status); goto end2; } } @@ -408,7 +408,7 @@ NTSTATUS registry_mark_volume_unmounted(BTRFS_UUID* uuid) { Status = registry_mark_volume_unmounted_path(&path); if (!NT_SUCCESS(Status)) { - ERR("registry_mark_volume_unmounted_path returned %08x\n", Status); + ERR("registry_mark_volume_unmounted_path returned %08lx\n", Status); goto end; } @@ -466,7 +466,7 @@ static void reset_subkeys(HANDLE h, PUNICODE_STRING reg_path) { if (NT_SUCCESS(Status)) { key_name* kn; - TRACE("key: %.*S\n", kbi->NameLength / sizeof(WCHAR), kbi->Name); + TRACE("key: %.*S\n", (int)(kbi->NameLength / sizeof(WCHAR)), kbi->Name); if (is_uuid(kbi->NameLength, kbi->Name)) { kn = ExAllocatePoolWithTag(PagedPool, sizeof(key_name), ALLOC_TAG); @@ -489,7 +489,7 @@ static void reset_subkeys(HANDLE h, PUNICODE_STRING reg_path) { InsertTailList(&key_names, &kn->list_entry); } } else if (Status != STATUS_NO_MORE_ENTRIES) - ERR("ZwEnumerateKey returned %08x\n", Status); + ERR("ZwEnumerateKey returned %08lx\n", Status); } while (NT_SUCCESS(Status)); le = key_names.Flink; @@ -511,7 +511,7 @@ static void reset_subkeys(HANDLE h, PUNICODE_STRING reg_path) { Status = registry_mark_volume_unmounted_path(&path); if (!NT_SUCCESS(Status)) - WARN("registry_mark_volume_unmounted_path returned %08x\n", Status); + WARN("registry_mark_volume_unmounted_path returned %08lx\n", Status); ExFreePool(path.Buffer); @@ -568,7 +568,7 @@ static void read_mappings(PUNICODE_STRING regpath) { Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos); if (!NT_SUCCESS(Status)) { - ERR("ZwCreateKey returned %08x\n", Status); + ERR("ZwCreateKey returned %08lx\n", Status); ExFreePool(path); return; } @@ -596,7 +596,7 @@ static void read_mappings(PUNICODE_STRING regpath) { RtlCopyMemory(&val, (uint8_t*)kvfi + kvfi->DataOffset, min(kvfi->DataLength, sizeof(uint32_t))); - TRACE("entry %u = %.*S = %u\n", i, kvfi->NameLength / sizeof(WCHAR), kvfi->Name, val); + TRACE("entry %lu = %.*S = %u\n", i, (int)(kvfi->NameLength / sizeof(WCHAR)), kvfi->Name, val); add_user_mapping(kvfi->Name, kvfi->NameLength / sizeof(WCHAR), val); } @@ -646,7 +646,7 @@ static void read_group_mappings(PUNICODE_STRING regpath) { Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos); if (!NT_SUCCESS(Status)) { - ERR("ZwCreateKey returned %08x\n", Status); + ERR("ZwCreateKey returned %08lx\n", Status); ExFreePool(path); return; } @@ -675,7 +675,7 @@ static void read_group_mappings(PUNICODE_STRING regpath) { RtlCopyMemory(&val, (uint8_t*)kvfi + kvfi->DataOffset, min(kvfi->DataLength, sizeof(uint32_t))); - TRACE("entry %u = %.*S = %u\n", i, kvfi->NameLength / sizeof(WCHAR), kvfi->Name, val); + TRACE("entry %lu = %.*S = %u\n", i, (int)(kvfi->NameLength / sizeof(WCHAR)), kvfi->Name, val); add_group_mapping(kvfi->Name, kvfi->NameLength / sizeof(WCHAR), val); } @@ -685,7 +685,8 @@ static void read_group_mappings(PUNICODE_STRING regpath) { ExFreePool(kvfi); } else if (dispos == REG_CREATED_NEW_KEY) { - WCHAR* builtin_users = L"S-1-5-32-545"; + static const WCHAR builtin_users[] = L"S-1-5-32-545"; + UNICODE_STRING us2; DWORD val; @@ -701,7 +702,7 @@ static void read_group_mappings(PUNICODE_STRING regpath) { val = 100; Status = ZwSetValueKey(h, &us2, 0, REG_DWORD, &val, sizeof(DWORD)); if (!NT_SUCCESS(Status)) { - ERR("ZwSetValueKey returned %08x\n", Status); + ERR("ZwSetValueKey returned %08lx\n", Status); ZwClose(h); return; } @@ -744,12 +745,12 @@ static void get_registry_value(HANDLE h, WCHAR* string, ULONG type, void* val, U } else { Status = ZwDeleteValueKey(h, &us); if (!NT_SUCCESS(Status)) { - ERR("ZwDeleteValueKey returned %08x\n", Status); + ERR("ZwDeleteValueKey returned %08lx\n", Status); } Status = ZwSetValueKey(h, &us, 0, type, val, size); if (!NT_SUCCESS(Status)) { - ERR("ZwSetValueKey returned %08x\n", Status); + ERR("ZwSetValueKey returned %08lx\n", Status); } } } @@ -759,10 +760,10 @@ static void get_registry_value(HANDLE h, WCHAR* string, ULONG type, void* val, U Status = ZwSetValueKey(h, &us, 0, type, val, size); if (!NT_SUCCESS(Status)) { - ERR("ZwSetValueKey returned %08x\n", Status); + ERR("ZwSetValueKey returned %08lx\n", Status); } } else { - ERR("ZwQueryValueKey returned %08x\n", Status); + ERR("ZwQueryValueKey returned %08lx\n", Status); } } @@ -791,7 +792,7 @@ void read_registry(PUNICODE_STRING regpath, bool refresh) { Status = ZwCreateKey(&h, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos); if (!NT_SUCCESS(Status)) { - ERR("ZwCreateKey returned %08x\n", Status); + ERR("ZwCreateKey returned %08lx\n", Status); return; } @@ -861,18 +862,18 @@ void read_registry(PUNICODE_STRING regpath, bool refresh) { if (log_device.Buffer[(log_device.Length / sizeof(WCHAR)) - 1] == 0) log_device.Length -= sizeof(WCHAR); } else { - ERR("LogDevice was type %u, length %u\n", kvfi->Type, kvfi->DataLength); + ERR("LogDevice was type %lu, length %lu\n", kvfi->Type, kvfi->DataLength); Status = ZwDeleteValueKey(h, &us); if (!NT_SUCCESS(Status)) { - ERR("ZwDeleteValueKey returned %08x\n", Status); + ERR("ZwDeleteValueKey returned %08lx\n", Status); } } } ExFreePool(kvfi); } else if (Status != STATUS_OBJECT_NAME_NOT_FOUND) { - ERR("ZwQueryValueKey returned %08x\n", Status); + ERR("ZwQueryValueKey returned %08lx\n", Status); } ExAcquireResourceExclusiveLite(&log_lock, true); @@ -893,7 +894,7 @@ void read_registry(PUNICODE_STRING regpath, bool refresh) { if (log_device.Length > 0 && debug_log_level > 0) { Status = IoGetDeviceObjectPointer(&log_device, FILE_WRITE_DATA, &comfo, &comdo); if (!NT_SUCCESS(Status)) - DbgPrint("IoGetDeviceObjectPointer returned %08x\n", Status); + DbgPrint("IoGetDeviceObjectPointer returned %08lx\n", Status); } } @@ -938,16 +939,16 @@ void read_registry(PUNICODE_STRING regpath, bool refresh) { if (log_file.Buffer[(log_file.Length / sizeof(WCHAR)) - 1] == 0) log_file.Length -= sizeof(WCHAR); } else { - ERR("LogFile was type %u, length %u\n", kvfi->Type, kvfi->DataLength); + ERR("LogFile was type %lu, length %lu\n", kvfi->Type, kvfi->DataLength); Status = ZwDeleteValueKey(h, &us); if (!NT_SUCCESS(Status)) - ERR("ZwDeleteValueKey returned %08x\n", Status); + ERR("ZwDeleteValueKey returned %08lx\n", Status); log_file.Length = 0; } } else { - ERR("ZwQueryValueKey returned %08\n", Status); + ERR("ZwQueryValueKey returned %08lx\n", Status); log_file.Length = 0; } @@ -956,11 +957,11 @@ void read_registry(PUNICODE_STRING regpath, bool refresh) { Status = ZwSetValueKey(h, &us, 0, REG_SZ, (void*)def_log_file, sizeof(def_log_file)); if (!NT_SUCCESS(Status)) - ERR("ZwSetValueKey returned %08x\n", Status); + ERR("ZwSetValueKey returned %08lx\n", Status); log_file.Length = 0; } else { - ERR("ZwQueryValueKey returned %08x\n", Status); + ERR("ZwQueryValueKey returned %08lx\n", Status); log_file.Length = 0; } @@ -994,7 +995,7 @@ void read_registry(PUNICODE_STRING regpath, bool refresh) { Status = ZwCreateFile(&log_handle, FILE_WRITE_DATA, &oa, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_ALERT, NULL, 0); if (!NT_SUCCESS(Status)) { - DbgPrint("ZwCreateFile returned %08x\n", Status); + DbgPrint("ZwCreateFile returned %08lx\n", Status); log_handle = NULL; } } @@ -1021,7 +1022,7 @@ static void __stdcall registry_work_item(PVOID Parameter) { Status = ZwNotifyChangeKey(regh, NULL, (PVOID)&wqi, (PVOID)DelayedWorkQueue, &iosb, REG_NOTIFY_CHANGE_LAST_SET, true, NULL, 0, true); if (!NT_SUCCESS(Status)) - ERR("ZwNotifyChangeKey returned %08x\n", Status); + ERR("ZwNotifyChangeKey returned %08lx\n", Status); } void watch_registry(HANDLE regh) { @@ -1032,5 +1033,5 @@ void watch_registry(HANDLE regh) { Status = ZwNotifyChangeKey(regh, NULL, (PVOID)&wqi, (PVOID)DelayedWorkQueue, &iosb, REG_NOTIFY_CHANGE_LAST_SET, true, NULL, 0, true); if (!NT_SUCCESS(Status)) - ERR("ZwNotifyChangeKey returned %08x\n", Status); + ERR("ZwNotifyChangeKey returned %08lx\n", Status); } diff --git a/drivers/filesystems/btrfs/reparse.c b/drivers/filesystems/btrfs/reparse.c index a926bbd4a73..8112c4a2143 100644 --- a/drivers/filesystems/btrfs/reparse.c +++ b/drivers/filesystems/btrfs/reparse.c @@ -28,7 +28,7 @@ NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, ccb* ccb = FileObject->FsContext2; NTSTATUS Status; - TRACE("(%p, %p, %p, %x, %p)\n", DeviceObject, FileObject, buffer, buflen, retlen); + TRACE("(%p, %p, %p, %lx, %p)\n", DeviceObject, FileObject, buffer, buflen, retlen); if (!ccb) return STATUS_INVALID_PARAMETER; @@ -45,7 +45,7 @@ NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, goto end; } - rdb->ReparseTag = IO_REPARSE_TAG_LXSS_SYMLINK; + rdb->ReparseTag = IO_REPARSE_TAG_LX_SYMLINK; rdb->ReparseDataLength = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) + sizeof(uint32_t); rdb->Reserved = 0; @@ -67,18 +67,18 @@ NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, goto end; } - TRACE("data = %p, size = %x\n", data, fcb->inode_item.st_size); + TRACE("data = %p, size = %I64x\n", data, fcb->inode_item.st_size); Status = read_file(fcb, (uint8_t*)data, 0, fcb->inode_item.st_size, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(data); goto end; } Status = utf8_to_utf16(NULL, 0, &stringlen, data, (ULONG)fcb->inode_item.st_size); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); ExFreePool(data); goto end; } @@ -114,7 +114,7 @@ NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, stringlen, &stringlen, data, (ULONG)fcb->inode_item.st_size); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(data); goto end; } @@ -141,7 +141,7 @@ NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, Status = read_file(fcb, buffer, 0, buflen, &len, NULL); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); } *retlen = len; @@ -184,7 +184,7 @@ static NTSTATUS set_symlink(PIRP Irp, file_ref* fileref, fcb* fcb, ccb* ccb, REP if (write) { minlen = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + sizeof(WCHAR); if (buflen < minlen) { - WARN("buffer was less than minimum length (%u < %u)\n", buflen, minlen); + WARN("buffer was less than minimum length (%lu < %lu)\n", buflen, minlen); return STATUS_INVALID_PARAMETER; } @@ -196,7 +196,7 @@ static NTSTATUS set_symlink(PIRP Irp, file_ref* fileref, fcb* fcb, ccb* ccb, REP subname.Buffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)]; subname.MaximumLength = subname.Length = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength; - TRACE("substitute name = %.*S\n", subname.Length / sizeof(WCHAR), subname.Buffer); + TRACE("substitute name = %.*S\n", (int)(subname.Length / sizeof(WCHAR)), subname.Buffer); } fcb->type = BTRFS_TYPE_SYMLINK; @@ -209,13 +209,13 @@ static NTSTATUS set_symlink(PIRP Irp, file_ref* fileref, fcb* fcb, ccb* ccb, REP if (write) { Status = truncate_file(fcb, 0, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("truncate_file returned %08x\n", Status); + ERR("truncate_file returned %08lx\n", Status); return Status; } Status = utf16_to_utf8(NULL, 0, (PULONG)&target.Length, subname.Buffer, subname.Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 1 failed with error %08x\n", Status); + ERR("utf16_to_utf8 1 failed with error %08lx\n", Status); return Status; } @@ -228,7 +228,7 @@ static NTSTATUS set_symlink(PIRP Irp, file_ref* fileref, fcb* fcb, ccb* ccb, REP Status = utf16_to_utf8(target.Buffer, target.Length, (PULONG)&target.Length, subname.Buffer, subname.Length); if (!NT_SUCCESS(Status)) { - ERR("utf16_to_utf8 2 failed with error %08x\n", Status); + ERR("utf16_to_utf8 2 failed with error %08lx\n", Status); ExFreePool(target.Buffer); return Status; } @@ -290,14 +290,14 @@ NTSTATUS set_reparse_point2(fcb* fcb, REPARSE_DATA_BUFFER* rdb, ULONG buflen, cc Status = fFsRtlValidateReparsePointBuffer(buflen, rdb); if (!NT_SUCCESS(Status)) { - ERR("FsRtlValidateReparsePointBuffer returned %08x\n", Status); + ERR("FsRtlValidateReparsePointBuffer returned %08lx\n", Status); return Status; } RtlCopyMemory(&tag, rdb, sizeof(ULONG)); if (fcb->type == BTRFS_TYPE_FILE && - ((tag == IO_REPARSE_TAG_SYMLINK && rdb->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) || tag == IO_REPARSE_TAG_LXSS_SYMLINK)) { + ((tag == IO_REPARSE_TAG_SYMLINK && rdb->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) || tag == IO_REPARSE_TAG_LX_SYMLINK)) { Status = set_symlink(Irp, fileref, fcb, ccb, rdb, buflen, tag == IO_REPARSE_TAG_SYMLINK, rollback); fcb->atts |= FILE_ATTRIBUTE_REPARSE_POINT; } else { @@ -326,7 +326,7 @@ NTSTATUS set_reparse_point2(fcb* fcb, REPARSE_DATA_BUFFER* rdb, ULONG buflen, cc } else { // otherwise, store as file data Status = truncate_file(fcb, 0, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("truncate_file returned %08x\n", Status); + ERR("truncate_file returned %08lx\n", Status); return Status; } @@ -334,7 +334,7 @@ NTSTATUS set_reparse_point2(fcb* fcb, REPARSE_DATA_BUFFER* rdb, ULONG buflen, cc Status = write_file2(fcb->Vcb, Irp, offset, rdb, &buflen, false, true, true, false, false, rollback); if (!NT_SUCCESS(Status)) { - ERR("write_file2 returned %08x\n", Status); + ERR("write_file2 returned %08lx\n", Status); return Status; } } @@ -419,7 +419,7 @@ NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp) { Status = set_reparse_point2(fcb, rdb, buflen, ccb, fileref, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("set_reparse_point2 returned %08x\n", Status); + ERR("set_reparse_point2 returned %08lx\n", Status); goto end; } @@ -550,7 +550,7 @@ NTSTATUS delete_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp) { Status = truncate_file(fcb, 0, Irp, &rollback); if (!NT_SUCCESS(Status)) { - ERR("truncate_file returned %08x\n", Status); + ERR("truncate_file returned %08lx\n", Status); goto end; } diff --git a/drivers/filesystems/btrfs/resource.h b/drivers/filesystems/btrfs/resource.h index 5ec2813c79a..28ddb4b1010 100644 --- a/drivers/filesystems/btrfs/resource.h +++ b/drivers/filesystems/btrfs/resource.h @@ -1,4 +1,4 @@ -//{{NO_DEPENDENCIES}} +//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by btrfs.rc // diff --git a/drivers/filesystems/btrfs/scrub.c b/drivers/filesystems/btrfs/scrub.c index e4d70d02e5e..40588c2f935 100644 --- a/drivers/filesystems/btrfs/scrub.c +++ b/drivers/filesystems/btrfs/scrub.c @@ -29,7 +29,7 @@ typedef struct { IO_STATUS_BLOCK iosb; uint8_t* buf; bool csum_error; - uint32_t* bad_csums; + void* bad_csums; } scrub_context_stripe; typedef struct _scrub_context { @@ -88,7 +88,7 @@ static void log_file_checksum_error(device_extension* Vcb, uint64_t addr, uint64 Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -97,12 +97,12 @@ static void log_file_checksum_error(device_extension* Vcb, uint64_t addr, uint64 path_part* pp; if (tp.item->size < sizeof(ROOT_REF)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(ROOT_REF)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(ROOT_REF)); goto end; } if (tp.item->size < offsetof(ROOT_REF, name[0]) + rr->n) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(ROOT_REF, name[0]) + rr->n); goto end; } @@ -151,7 +151,7 @@ static void log_file_checksum_error(device_extension* Vcb, uint64_t addr, uint64 Status = find_item(Vcb, r, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -160,12 +160,12 @@ static void log_file_checksum_error(device_extension* Vcb, uint64_t addr, uint64 path_part* pp; if (tp.item->size < sizeof(INODE_REF)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(INODE_REF)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(INODE_REF)); goto end; } if (tp.item->size < offsetof(INODE_REF, name[0]) + ir->n) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(INODE_REF, name[0]) + ir->n); goto end; } @@ -191,13 +191,13 @@ static void log_file_checksum_error(device_extension* Vcb, uint64_t addr, uint64 path_part* pp; if (tp.item->size < sizeof(INODE_EXTREF)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, - tp.item->size, sizeof(INODE_EXTREF)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + tp.item->size, sizeof(INODE_EXTREF)); goto end; } if (tp.item->size < offsetof(INODE_EXTREF, name[0]) + ier->n) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(INODE_EXTREF, name[0]) + ier->n); goto end; } @@ -280,7 +280,7 @@ static void log_file_checksum_error(device_extension* Vcb, uint64_t addr, uint64 Status = utf8_to_utf16(NULL, 0, &utf16len, fn.Buffer, fn.Length); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 1 returned %08x\n", Status); + ERR("utf8_to_utf16 1 returned %08lx\n", Status); ExFreePool(fn.Buffer); goto end; } @@ -304,7 +304,7 @@ static void log_file_checksum_error(device_extension* Vcb, uint64_t addr, uint64 Status = utf8_to_utf16(err->data.filename, utf16len, &utf16len, fn.Buffer, fn.Length); if (!NT_SUCCESS(Status)) { - ERR("utf8_to_utf16 2 returned %08x\n", Status); + ERR("utf8_to_utf16 2 returned %08lx\n", Status); ExFreePool(fn.Buffer); ExFreePool(err); goto end; @@ -341,7 +341,7 @@ static void log_file_checksum_error_shared(device_extension* Vcb, uint64_t treea Status = read_data(Vcb, treeaddr, Vcb->superblock.node_size, NULL, true, (uint8_t*)tree, NULL, NULL, NULL, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); goto end; } @@ -417,7 +417,7 @@ static void log_tree_checksum_error_shared(device_extension* Vcb, uint64_t offse Status = read_data(Vcb, offset, Vcb->superblock.node_size, NULL, true, (uint8_t*)tree, NULL, NULL, NULL, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); goto end; } @@ -457,7 +457,7 @@ static void log_unrecoverable_error(device_extension* Vcb, uint64_t address, uin Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return; } @@ -469,7 +469,7 @@ static void log_unrecoverable_error(device_extension* Vcb, uint64_t address, uin return; if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return; } @@ -479,8 +479,8 @@ static void log_unrecoverable_error(device_extension* Vcb, uint64_t address, uin if (tp.item->key.obj_id == TYPE_EXTENT_ITEM && ei->flags & EXTENT_ITEM_TREE_BLOCK) { if (tp.item->size < sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, - tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + tp.item->size, sizeof(EXTENT_ITEM) + sizeof(EXTENT_ITEM2)); return; } @@ -502,7 +502,7 @@ static void log_unrecoverable_error(device_extension* Vcb, uint64_t address, uin TREE_BLOCK_REF* tbr; if (len < sizeof(TREE_BLOCK_REF)) { - ERR("TREE_BLOCK_REF takes up %u bytes, but only %u remaining\n", sizeof(TREE_BLOCK_REF), len); + ERR("TREE_BLOCK_REF takes up %Iu bytes, but only %lu remaining\n", sizeof(TREE_BLOCK_REF), len); break; } @@ -518,7 +518,7 @@ static void log_unrecoverable_error(device_extension* Vcb, uint64_t address, uin EXTENT_DATA_REF* edr; if (len < sizeof(EXTENT_DATA_REF)) { - ERR("EXTENT_DATA_REF takes up %u bytes, but only %u remaining\n", sizeof(EXTENT_DATA_REF), len); + ERR("EXTENT_DATA_REF takes up %Iu bytes, but only %lu remaining\n", sizeof(EXTENT_DATA_REF), len); break; } @@ -534,7 +534,7 @@ static void log_unrecoverable_error(device_extension* Vcb, uint64_t address, uin SHARED_BLOCK_REF* sbr; if (len < sizeof(SHARED_BLOCK_REF)) { - ERR("SHARED_BLOCK_REF takes up %u bytes, but only %u remaining\n", sizeof(SHARED_BLOCK_REF), len); + ERR("SHARED_BLOCK_REF takes up %Iu bytes, but only %lu remaining\n", sizeof(SHARED_BLOCK_REF), len); break; } @@ -550,7 +550,7 @@ static void log_unrecoverable_error(device_extension* Vcb, uint64_t address, uin SHARED_DATA_REF* sdr; if (len < sizeof(SHARED_DATA_REF)) { - ERR("SHARED_DATA_REF takes up %u bytes, but only %u remaining\n", sizeof(SHARED_DATA_REF), len); + ERR("SHARED_DATA_REF takes up %Iu bytes, but only %lu remaining\n", sizeof(SHARED_DATA_REF), len); break; } @@ -584,8 +584,8 @@ static void log_unrecoverable_error(device_extension* Vcb, uint64_t address, uin EXTENT_DATA_REF* edr; if (tp.item->size < sizeof(EXTENT_DATA_REF)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, - tp.item->size, sizeof(EXTENT_DATA_REF)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + tp.item->size, sizeof(EXTENT_DATA_REF)); break; } @@ -664,7 +664,7 @@ static NTSTATUS __stdcall scrub_read_completion(PDEVICE_OBJECT DeviceObject, PIR return STATUS_MORE_PROCESSING_REQUIRED; } -static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offset, uint32_t* csum, scrub_context* context) { +static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offset, void* csum, scrub_context* context) { NTSTATUS Status; bool csum_error = false; ULONG i; @@ -693,7 +693,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse csum_error = true; log_device_error(Vcb, c->devices[i], BTRFS_DEV_STAT_CORRUPTION_ERRORS); } else if (!NT_SUCCESS(Status)) { - ERR("check_csum returned %08x\n", Status); + ERR("check_csum returned %08lx\n", Status); return Status; } else good_stripe = i; @@ -718,9 +718,8 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse } else { for (j = 0; j < context->stripes[i].length / Vcb->superblock.node_size; j++) { tree_header* th = (tree_header*)&context->stripes[i].buf[j * Vcb->superblock.node_size]; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (crc32 != *((uint32_t*)th->csum) || th->address != offset + UInt32x32To64(j, Vcb->superblock.node_size)) { + if (!check_tree_checksum(Vcb, th) || th->address != offset + UInt32x32To64(j, Vcb->superblock.node_size)) { context->stripes[i].csum_error = true; csum_error = true; log_device_error(Vcb, c->devices[i], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -742,21 +741,17 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse for (i = 0; i < c->chunk_item->num_stripes; i++) { if (context->stripes[i].csum_error) { if (csum) { - context->stripes[i].bad_csums = ExAllocatePoolWithTag(PagedPool, context->stripes[i].length * sizeof(uint32_t) / Vcb->superblock.sector_size, ALLOC_TAG); + context->stripes[i].bad_csums = ExAllocatePoolWithTag(PagedPool, context->stripes[i].length * Vcb->csum_size / Vcb->superblock.sector_size, ALLOC_TAG); if (!context->stripes[i].bad_csums) { ERR("out of memory\n"); return STATUS_INSUFFICIENT_RESOURCES; } - Status = calc_csum(Vcb, context->stripes[i].buf, context->stripes[i].length / Vcb->superblock.sector_size, context->stripes[i].bad_csums); - if (!NT_SUCCESS(Status)) { - ERR("calc_csum returned %08x\n", Status); - return Status; - } + do_calc_job(Vcb, context->stripes[i].buf, context->stripes[i].length / Vcb->superblock.sector_size, context->stripes[i].bad_csums); } else { ULONG j; - context->stripes[i].bad_csums = ExAllocatePoolWithTag(PagedPool, context->stripes[i].length * sizeof(uint32_t) / Vcb->superblock.node_size, ALLOC_TAG); + context->stripes[i].bad_csums = ExAllocatePoolWithTag(PagedPool, context->stripes[i].length * Vcb->csum_size / Vcb->superblock.node_size, ALLOC_TAG); if (!context->stripes[i].bad_csums) { ERR("out of memory\n"); return STATUS_INSUFFICIENT_RESOURCES; @@ -764,9 +759,8 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse for (j = 0; j < context->stripes[i].length / Vcb->superblock.node_size; j++) { tree_header* th = (tree_header*)&context->stripes[i].buf[j * Vcb->superblock.node_size]; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - context->stripes[i].bad_csums[j] = crc32; + get_tree_checksum(Vcb, th, (uint8_t*)context->stripes[i].bad_csums + (Vcb->csum_size * j)); } } } @@ -791,7 +785,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse if (csum) { for (j = 0; j < context->stripes[i].length / Vcb->superblock.sector_size; j++) { - if (context->stripes[i].bad_csums[j] != csum[j]) { + if (RtlCompareMemory((uint8_t*)context->stripes[i].bad_csums + (j * Vcb->csum_size), (uint8_t*)csum + (j + Vcb->csum_size), Vcb->csum_size) != Vcb->csum_size) { uint64_t addr = offset + UInt32x32To64(j, Vcb->superblock.sector_size); log_error(Vcb, addr, c->devices[i]->devitem.dev_id, false, true, false); @@ -803,7 +797,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse tree_header* th = (tree_header*)&context->stripes[i].buf[j * Vcb->superblock.node_size]; uint64_t addr = offset + UInt32x32To64(j, Vcb->superblock.node_size); - if (context->stripes[i].bad_csums[j] != *((uint32_t*)th->csum) || th->address != addr) { + if (RtlCompareMemory((uint8_t*)context->stripes[i].bad_csums + (j * Vcb->csum_size), th, Vcb->csum_size) != Vcb->csum_size || th->address != addr) { log_error(Vcb, addr, c->devices[i]->devitem.dev_id, true, true, false); log_device_error(Vcb, c->devices[i], BTRFS_DEV_STAT_CORRUPTION_ERRORS); } @@ -820,7 +814,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse context->stripes[good_stripe].buf, context->stripes[i].length); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, c->devices[i], BTRFS_DEV_STAT_WRITE_ERRORS); return Status; } @@ -838,13 +832,15 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse if (c->devices[i]->devobj) { if (csum) { for (j = 0; j < context->stripes[i].length / Vcb->superblock.sector_size; j++) { - if (context->stripes[i].bad_csums[j] != csum[j]) { + if (RtlCompareMemory((uint8_t*)context->stripes[i].bad_csums + (j * Vcb->csum_size), (uint8_t*)csum + (j * Vcb->csum_size), Vcb->csum_size) != Vcb->csum_size) { ULONG k; uint64_t addr = offset + UInt32x32To64(j, Vcb->superblock.sector_size); bool recovered = false; for (k = 0; k < c->chunk_item->num_stripes; k++) { - if (i != k && c->devices[k]->devobj && context->stripes[k].bad_csums[j] == csum[j]) { + if (i != k && c->devices[k]->devobj && + RtlCompareMemory((uint8_t*)context->stripes[k].bad_csums + (j * Vcb->csum_size), + (uint8_t*)csum + (j * Vcb->csum_size), Vcb->csum_size) == Vcb->csum_size) { log_error(Vcb, addr, c->devices[i]->devitem.dev_id, false, true, false); log_device_error(Vcb, c->devices[i], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -867,7 +863,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse tree_header* th = (tree_header*)&context->stripes[i].buf[j * Vcb->superblock.node_size]; uint64_t addr = offset + UInt32x32To64(j, Vcb->superblock.node_size); - if (context->stripes[i].bad_csums[j] != *((uint32_t*)th->csum) || th->address != addr) { + if (RtlCompareMemory((uint8_t*)context->stripes[i].bad_csums + (j * Vcb->csum_size), th, Vcb->csum_size) != Vcb->csum_size || th->address != addr) { ULONG k; bool recovered = false; @@ -875,7 +871,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse if (i != k && c->devices[k]->devobj) { tree_header* th2 = (tree_header*)&context->stripes[k].buf[j * Vcb->superblock.node_size]; - if (context->stripes[k].bad_csums[j] == *((uint32_t*)th2->csum) && th2->address == addr) { + if (RtlCompareMemory((uint8_t*)context->stripes[k].bad_csums + (j * Vcb->csum_size), th2, Vcb->csum_size) == Vcb->csum_size && th2->address == addr) { log_error(Vcb, addr, c->devices[i]->devitem.dev_id, true, true, false); log_device_error(Vcb, c->devices[i], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -904,7 +900,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse Status = write_data_phys(c->devices[i]->devobj, c->devices[i]->fileobj, cis[i].offset + offset - c->offset, context->stripes[i].buf, context->stripes[i].length); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, c->devices[i], BTRFS_DEV_STAT_CORRUPTION_ERRORS); return Status; } @@ -920,7 +916,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse if (csum) { for (j = 0; j < context->stripes[i].length / Vcb->superblock.sector_size; j++) { - if (context->stripes[i].bad_csums[j] != csum[j]) { + if (RtlCompareMemory((uint8_t*)context->stripes[i].bad_csums + (j * Vcb->csum_size), (uint8_t*)csum + (j + Vcb->csum_size), Vcb->csum_size) != Vcb->csum_size) { uint64_t addr = offset + UInt32x32To64(j, Vcb->superblock.sector_size); log_error(Vcb, addr, c->devices[i]->devitem.dev_id, false, false, false); @@ -931,7 +927,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse tree_header* th = (tree_header*)&context->stripes[i].buf[j * Vcb->superblock.node_size]; uint64_t addr = offset + UInt32x32To64(j, Vcb->superblock.node_size); - if (context->stripes[i].bad_csums[j] != *((uint32_t*)th->csum) || th->address != addr) + if (RtlCompareMemory((uint8_t*)context->stripes[i].bad_csums + (j * Vcb->csum_size), th, Vcb->csum_size) != Vcb->csum_size || th->address != addr) log_error(Vcb, addr, c->devices[i]->devitem.dev_id, true, false, false); } } @@ -941,7 +937,7 @@ static NTSTATUS scrub_extent_dup(device_extension* Vcb, chunk* c, uint64_t offse return STATUS_SUCCESS; } -static NTSTATUS scrub_extent_raid0(device_extension* Vcb, chunk* c, uint64_t offset, uint32_t length, uint16_t startoffstripe, uint32_t* csum, scrub_context* context) { +static NTSTATUS scrub_extent_raid0(device_extension* Vcb, chunk* c, uint64_t offset, uint32_t length, uint16_t startoffstripe, void* csum, scrub_context* context) { ULONG j; uint16_t stripe; uint32_t pos, *stripeoff; @@ -966,9 +962,7 @@ static NTSTATUS scrub_extent_raid0(device_extension* Vcb, chunk* c, uint64_t off if (csum) { for (j = 0; j < readlen; j += Vcb->superblock.sector_size) { - uint32_t crc32 = ~calc_crc32c(0xffffffff, context->stripes[stripe].buf + stripeoff[stripe], Vcb->superblock.sector_size); - - if (crc32 != csum[pos / Vcb->superblock.sector_size]) { + if (!check_sector_csum(Vcb, context->stripes[stripe].buf + stripeoff[stripe], (uint8_t*)csum + (pos * Vcb->csum_size / Vcb->superblock.sector_size))) { uint64_t addr = offset + pos; log_error(Vcb, addr, c->devices[stripe]->devitem.dev_id, false, false, false); @@ -981,10 +975,9 @@ static NTSTATUS scrub_extent_raid0(device_extension* Vcb, chunk* c, uint64_t off } else { for (j = 0; j < readlen; j += Vcb->superblock.node_size) { tree_header* th = (tree_header*)(context->stripes[stripe].buf + stripeoff[stripe]); - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); uint64_t addr = offset + pos; - if (crc32 != *((uint32_t*)th->csum) || th->address != addr) { + if (!check_tree_checksum(Vcb, th) || th->address != addr) { log_error(Vcb, addr, c->devices[stripe]->devitem.dev_id, true, false, false); log_device_error(Vcb, c->devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); } @@ -1002,7 +995,7 @@ static NTSTATUS scrub_extent_raid0(device_extension* Vcb, chunk* c, uint64_t off return STATUS_SUCCESS; } -static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t offset, uint32_t length, uint16_t startoffstripe, uint32_t* csum, scrub_context* context) { +static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t offset, uint32_t length, uint16_t startoffstripe, void* csum, scrub_context* context) { ULONG j; uint16_t stripe, sub_stripes = max(c->chunk_item->sub_stripes, 1); uint32_t pos, *stripeoff; @@ -1045,9 +1038,8 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of } } else { for (j = 0; j < readlen; j += Vcb->superblock.sector_size) { - uint32_t crc32 = ~calc_crc32c(0xffffffff, context->stripes[(stripe * sub_stripes) + k].buf + stripeoff[stripe] + j, Vcb->superblock.sector_size); - - if (crc32 != csum[(pos + j) / Vcb->superblock.sector_size]) { + if (!check_sector_csum(Vcb, context->stripes[(stripe * sub_stripes) + k].buf + stripeoff[stripe] + j, + (uint8_t*)csum + ((pos + j) * Vcb->csum_size / Vcb->superblock.sector_size))) { csum_error = true; context->stripes[(stripe * sub_stripes) + k].csum_error = true; log_device_error(Vcb, c->devices[(stripe * sub_stripes) + k], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -1081,10 +1073,9 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of } else { for (j = 0; j < readlen; j += Vcb->superblock.node_size) { tree_header* th = (tree_header*)(context->stripes[(stripe * sub_stripes) + k].buf + stripeoff[stripe] + j); - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); uint64_t addr = offset + pos + j; - if (crc32 != *((uint32_t*)th->csum) || th->address != addr) { + if (!check_tree_checksum(Vcb, th) || th->address != addr) { csum_error = true; context->stripes[(stripe * sub_stripes) + k].csum_error = true; log_device_error(Vcb, c->devices[(stripe * sub_stripes) + k], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -1198,7 +1189,7 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of context->stripes[j + goodstripe].buf, context->stripes[j + goodstripe].length); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, c->devices[j + k], BTRFS_DEV_STAT_WRITE_ERRORS); goto end; } @@ -1213,18 +1204,15 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of if (csum) { for (k = 0; k < sub_stripes; k++) { if (c->devices[j + k]->devobj) { - context->stripes[j + k].bad_csums = ExAllocatePoolWithTag(PagedPool, context->stripes[j + k].length * sizeof(uint32_t) / Vcb->superblock.sector_size, ALLOC_TAG); + context->stripes[j + k].bad_csums = ExAllocatePoolWithTag(PagedPool, context->stripes[j + k].length * Vcb->csum_size / Vcb->superblock.sector_size, + ALLOC_TAG); if (!context->stripes[j + k].bad_csums) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto end; } - Status = calc_csum(Vcb, context->stripes[j + k].buf, context->stripes[j + k].length / Vcb->superblock.sector_size, context->stripes[j + k].bad_csums); - if (!NT_SUCCESS(Status)) { - ERR("calc_csum returned %08x\n", Status); - goto end; - } + do_calc_job(Vcb, context->stripes[j + k].buf, context->stripes[j + k].length / Vcb->superblock.sector_size, context->stripes[j + k].bad_csums); } } } else { @@ -1232,7 +1220,8 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of if (c->devices[j + k]->devobj) { ULONG l; - context->stripes[j + k].bad_csums = ExAllocatePoolWithTag(PagedPool, context->stripes[j + k].length * sizeof(uint32_t) / Vcb->superblock.node_size, ALLOC_TAG); + context->stripes[j + k].bad_csums = ExAllocatePoolWithTag(PagedPool, context->stripes[j + k].length * Vcb->csum_size / Vcb->superblock.node_size, + ALLOC_TAG); if (!context->stripes[j + k].bad_csums) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -1241,9 +1230,8 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of for (l = 0; l < context->stripes[j + k].length / Vcb->superblock.node_size; l++) { tree_header* th = (tree_header*)&context->stripes[j + k].buf[l * Vcb->superblock.node_size]; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - context->stripes[j + k].bad_csums[l] = crc32; + get_tree_checksum(Vcb, th, (uint8_t*)context->stripes[j + k].bad_csums + (Vcb->csum_size * l)); } } } @@ -1266,15 +1254,16 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of if (csum) { for (l = 0; l < readlen; l += Vcb->superblock.sector_size) { - uint32_t crc32 = csum[pos / Vcb->superblock.sector_size]; bool has_error = false; goodstripe = 0xffffffff; for (k = 0; k < sub_stripes; k++) { if (c->devices[j + k]->devobj) { - if (context->stripes[j + k].bad_csums[so / Vcb->superblock.sector_size] != crc32) + if (RtlCompareMemory((uint8_t*)context->stripes[j + k].bad_csums + (so * Vcb->csum_size / Vcb->superblock.sector_size), + (uint8_t*)csum + (pos * Vcb->csum_size / Vcb->superblock.sector_size), + Vcb->csum_size) != Vcb->csum_size) { has_error = true; - else + } else goodstripe = k; } } @@ -1282,7 +1271,10 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of if (has_error) { if (goodstripe != 0xffffffff) { for (k = 0; k < sub_stripes; k++) { - if (c->devices[j + k]->devobj && context->stripes[j + k].bad_csums[so / Vcb->superblock.sector_size] != crc32) { + if (c->devices[j + k]->devobj && + RtlCompareMemory((uint8_t*)context->stripes[j + k].bad_csums + (so * Vcb->csum_size / Vcb->superblock.sector_size), + (uint8_t*)csum + (pos * Vcb->csum_size / Vcb->superblock.sector_size), + Vcb->csum_size) != Vcb->csum_size) { uint64_t addr = offset + pos; log_error(Vcb, addr, c->devices[j + k]->devitem.dev_id, false, true, false); @@ -1315,7 +1307,7 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of tree_header* th = (tree_header*)&context->stripes[j + k].buf[so]; uint64_t addr = offset + pos; - if (context->stripes[j + k].bad_csums[so / Vcb->superblock.node_size] != *((uint32_t*)th->csum) || th->address != addr) { + if (RtlCompareMemory((uint8_t*)context->stripes[j + k].bad_csums + (so * Vcb->csum_size / Vcb->superblock.node_size), th, Vcb->csum_size) != Vcb->csum_size || th->address != addr) { ULONG m; recovered = false; @@ -1324,7 +1316,7 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of if (m != k) { tree_header* th2 = (tree_header*)&context->stripes[j + m].buf[so]; - if (context->stripes[j + m].bad_csums[so / Vcb->superblock.node_size] == *((uint32_t*)th2->csum) && th2->address == addr) { + if (RtlCompareMemory((uint8_t*)context->stripes[j + m].bad_csums + (so * Vcb->csum_size / Vcb->superblock.node_size), th2, Vcb->csum_size) == Vcb->csum_size && th2->address == addr) { log_error(Vcb, addr, c->devices[j + k]->devitem.dev_id, true, true, false); RtlCopyMemory(th, th2, Vcb->superblock.node_size); @@ -1363,7 +1355,7 @@ static NTSTATUS scrub_extent_raid10(device_extension* Vcb, chunk* c, uint64_t of context->stripes[j + k].buf, context->stripes[j + k].length); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, c->devices[j + k], BTRFS_DEV_STAT_WRITE_ERRORS); goto end; } @@ -1382,14 +1374,14 @@ end: return Status; } -static NTSTATUS scrub_extent(device_extension* Vcb, chunk* c, ULONG type, uint64_t offset, uint32_t size, uint32_t* csum) { +static NTSTATUS scrub_extent(device_extension* Vcb, chunk* c, ULONG type, uint64_t offset, uint32_t size, void* csum) { ULONG i; scrub_context context; CHUNK_ITEM_STRIPE* cis; NTSTATUS Status; uint16_t startoffstripe, num_missing, allowed_missing; - TRACE("(%p, %p, %I64x, %I64x, %p)\n", Vcb, c, offset, size, csum); + TRACE("(%p, %p, %lx, %I64x, %x, %p)\n", Vcb, c, type, offset, size, csum); context.stripes = ExAllocatePoolWithTag(NonPagedPool, sizeof(scrub_context_stripe) * c->chunk_item->num_stripes, ALLOC_TAG); if (!context.stripes) { @@ -1481,7 +1473,7 @@ static NTSTATUS scrub_extent(device_extension* Vcb, chunk* c, ULONG type, uint64 context.stripes[i].start = offset - c->offset; context.stripes[i].length = size; } else if (type != BLOCK_FLAG_RAID0 && type != BLOCK_FLAG_RAID10) { - ERR("unexpected chunk type %x\n", type); + ERR("unexpected chunk type %lx\n", type); Status = STATUS_INTERNAL_ERROR; goto end; } @@ -1543,7 +1535,7 @@ static NTSTATUS scrub_extent(device_extension* Vcb, chunk* c, ULONG type, uint64 } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(context.stripes[i].Irp->MdlAddress); context.stripes[i].Irp->MdlAddress = NULL; goto end; @@ -1591,19 +1583,19 @@ static NTSTATUS scrub_extent(device_extension* Vcb, chunk* c, ULONG type, uint64 if (type == BLOCK_FLAG_DUPLICATE) { Status = scrub_extent_dup(Vcb, c, offset, csum, &context); if (!NT_SUCCESS(Status)) { - ERR("scrub_extent_dup returned %08x\n", Status); + ERR("scrub_extent_dup returned %08lx\n", Status); goto end; } } else if (type == BLOCK_FLAG_RAID0) { Status = scrub_extent_raid0(Vcb, c, offset, size, startoffstripe, csum, &context); if (!NT_SUCCESS(Status)) { - ERR("scrub_extent_raid0 returned %08x\n", Status); + ERR("scrub_extent_raid0 returned %08lx\n", Status); goto end; } } else if (type == BLOCK_FLAG_RAID10) { Status = scrub_extent_raid10(Vcb, c, offset, size, startoffstripe, csum, &context); if (!NT_SUCCESS(Status)) { - ERR("scrub_extent_raid10 returned %08x\n", Status); + ERR("scrub_extent_raid10 returned %08lx\n", Status); goto end; } } @@ -1632,7 +1624,7 @@ end: return Status; } -static NTSTATUS scrub_data_extent(device_extension* Vcb, chunk* c, uint64_t offset, ULONG type, uint32_t* csum, RTL_BITMAP* bmp, ULONG bmplen) { +static NTSTATUS scrub_data_extent(device_extension* Vcb, chunk* c, uint64_t offset, ULONG type, void* csum, RTL_BITMAP* bmp, ULONG bmplen) { NTSTATUS Status; ULONG runlength, index; @@ -1657,9 +1649,10 @@ static NTSTATUS scrub_data_extent(device_extension* Vcb, chunk* c, uint64_t offs else rl = runlength; - Status = scrub_extent(Vcb, c, type, offset + UInt32x32To64(index, Vcb->superblock.sector_size), rl * Vcb->superblock.sector_size, &csum[index]); + Status = scrub_extent(Vcb, c, type, offset + UInt32x32To64(index, Vcb->superblock.sector_size), + rl * Vcb->superblock.sector_size, (uint8_t*)csum + (index * Vcb->csum_size)); if (!NT_SUCCESS(Status)) { - ERR("scrub_data_extent_dup returned %08x\n", Status); + ERR("scrub_data_extent_dup returned %08lx\n", Status); return Status; } @@ -1691,7 +1684,7 @@ typedef struct { RTL_BITMAP alloc; RTL_BITMAP has_csum; RTL_BITMAP is_tree; - uint32_t* csum; + void* csum; uint8_t* parity_scratch; uint8_t* parity_scratch2; } scrub_context_raid56; @@ -1733,9 +1726,8 @@ static void scrub_raid5_stripe(device_extension* Vcb, chunk* c, scrub_context_ra if (RtlCheckBit(&context->is_tree, off)) { tree_header* th = (tree_header*)&context->stripes[stripe].buf[stripeoff * Vcb->superblock.sector_size]; uint64_t addr = c->offset + (stripe_start * (c->chunk_item->num_stripes - 1) * c->chunk_item->stripe_length) + (off * Vcb->superblock.sector_size); - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (crc32 != *((uint32_t*)th->csum) || th->address != addr) { + if (!check_tree_checksum(Vcb, th) || th->address != addr) { RtlSetBits(&context->stripes[stripe].error, i, Vcb->superblock.node_size / Vcb->superblock.sector_size); log_device_error(Vcb, c->devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -1749,9 +1741,7 @@ static void scrub_raid5_stripe(device_extension* Vcb, chunk* c, scrub_context_ra continue; } else if (RtlCheckBit(&context->has_csum, off)) { - uint32_t crc32 = ~calc_crc32c(0xffffffff, context->stripes[stripe].buf + (stripeoff * Vcb->superblock.sector_size), Vcb->superblock.sector_size); - - if (crc32 != context->csum[off]) { + if (!check_sector_csum(Vcb, context->stripes[stripe].buf + (stripeoff * Vcb->superblock.sector_size), (uint8_t*)context->csum + (Vcb->csum_size * off))) { RtlSetBit(&context->stripes[stripe].error, i); log_device_error(Vcb, c->devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -1843,7 +1833,6 @@ static void scrub_raid5_stripe(device_extension* Vcb, chunk* c, scrub_context_ra log_error(Vcb, addr, c->devices[parity]->devitem.dev_id, false, true, true); log_device_error(Vcb, c->devices[parity], BTRFS_DEV_STAT_CORRUPTION_ERRORS); } else if (num_errors == 1) { - uint32_t crc32; uint64_t addr = c->offset + (stripe_start * (c->chunk_item->num_stripes - 1) * c->chunk_item->stripe_length) + (bad_off * Vcb->superblock.sector_size); if (RtlCheckBit(&context->is_tree, bad_off)) { @@ -1854,9 +1843,8 @@ static void scrub_raid5_stripe(device_extension* Vcb, chunk* c, scrub_context_ra Vcb->superblock.node_size); th = (tree_header*)&context->parity_scratch[i * Vcb->superblock.sector_size]; - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (crc32 == *((uint32_t*)th->csum) && th->address == addr) { + if (check_tree_checksum(Vcb, th) && th->address == addr) { RtlCopyMemory(&context->stripes[bad_stripe].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.node_size); @@ -1868,13 +1856,15 @@ static void scrub_raid5_stripe(device_extension* Vcb, chunk* c, scrub_context_ra } else log_error(Vcb, addr, c->devices[bad_stripe]->devitem.dev_id, true, false, false); } else { + uint8_t hash[MAX_HASH_SIZE]; + do_xor(&context->parity_scratch[i * Vcb->superblock.sector_size], &context->stripes[bad_stripe].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], Vcb->superblock.sector_size); - crc32 = ~calc_crc32c(0xffffffff, &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.sector_size); + get_sector_csum(Vcb, &context->parity_scratch[i * Vcb->superblock.sector_size], hash); - if (crc32 == context->csum[bad_off]) { + if (RtlCompareMemory(hash, (uint8_t*)context->csum + (Vcb->csum_size * bad_off), Vcb->csum_size) == Vcb->csum_size) { RtlCopyMemory(&context->stripes[bad_stripe].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.sector_size); @@ -1929,9 +1919,8 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra if (RtlCheckBit(&context->is_tree, off)) { tree_header* th = (tree_header*)&context->stripes[stripe].buf[stripeoff * Vcb->superblock.sector_size]; uint64_t addr = c->offset + (stripe_start * (c->chunk_item->num_stripes - 2) * c->chunk_item->stripe_length) + (off * Vcb->superblock.sector_size); - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (crc32 != *((uint32_t*)th->csum) || th->address != addr) { + if (!check_tree_checksum(Vcb, th) || th->address != addr) { RtlSetBits(&context->stripes[stripe].error, i, Vcb->superblock.node_size / Vcb->superblock.sector_size); log_device_error(Vcb, c->devices[stripe], BTRFS_DEV_STAT_CORRUPTION_ERRORS); @@ -1945,9 +1934,11 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra continue; } else if (RtlCheckBit(&context->has_csum, off)) { - uint32_t crc32 = ~calc_crc32c(0xffffffff, context->stripes[stripe].buf + (stripeoff * Vcb->superblock.sector_size), Vcb->superblock.sector_size); + uint8_t hash[MAX_HASH_SIZE]; - if (crc32 != context->csum[off]) { + get_sector_csum(Vcb, context->stripes[stripe].buf + (stripeoff * Vcb->superblock.sector_size), hash); + + if (RtlCompareMemory(hash, (uint8_t*)context->csum + (Vcb->csum_size * off), Vcb->csum_size) != Vcb->csum_size) { uint64_t addr = c->offset + (stripe_start * (c->chunk_item->num_stripes - 2) * c->chunk_item->stripe_length) + (off * Vcb->superblock.sector_size); RtlSetBit(&context->stripes[stripe].error, i); @@ -2081,7 +2072,7 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra log_device_error(Vcb, c->devices[parity2], BTRFS_DEV_STAT_CORRUPTION_ERRORS); } } else if (num_errors == 1) { - uint32_t crc32a, crc32b, len; + 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->superblock.sector_size); uint8_t* scratch; @@ -2122,21 +2113,23 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra } if (RtlCheckBit(&context->is_tree, bad_off1)) { + uint8_t hash1[MAX_HASH_SIZE]; + uint8_t hash2[MAX_HASH_SIZE]; tree_header *th1 = NULL, *th2 = NULL; if (c->devices[parity1]->devobj) { th1 = (tree_header*)&context->parity_scratch[i * Vcb->superblock.sector_size]; - crc32a = ~calc_crc32c(0xffffffff, (uint8_t*)&th1->fs_uuid, Vcb->superblock.node_size - sizeof(th1->csum)); + get_tree_checksum(Vcb, th1, hash1); } if (c->devices[parity2]->devobj) { th2 = (tree_header*)scratch; - crc32b = ~calc_crc32c(0xffffffff, (uint8_t*)&th2->fs_uuid, Vcb->superblock.node_size - sizeof(th2->csum)); + get_tree_checksum(Vcb, th2, hash2); } - if ((c->devices[parity1]->devobj && crc32a == *((uint32_t*)th1->csum) && th1->address == addr) || - (c->devices[parity2]->devobj && crc32b == *((uint32_t*)th2->csum) && th2->address == addr)) { - if (!c->devices[parity1]->devobj || crc32a != *((uint32_t*)th1->csum) || th1->address != addr) { + if ((c->devices[parity1]->devobj && RtlCompareMemory(hash1, th1, Vcb->csum_size) == Vcb->csum_size && th1->address == addr) || + (c->devices[parity2]->devobj && RtlCompareMemory(hash2, th2, Vcb->csum_size) == Vcb->csum_size && th2->address == addr)) { + if (!c->devices[parity1]->devobj || RtlCompareMemory(hash1, th1, Vcb->csum_size) != Vcb->csum_size || th1->address != addr) { RtlCopyMemory(&context->stripes[bad_stripe1].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], scratch, Vcb->superblock.node_size); @@ -2168,7 +2161,7 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra RtlCopyMemory(&context->stripes[bad_stripe1].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.node_size); - if (!c->devices[parity2]->devobj || crc32b != *((uint32_t*)th2->csum) || th2->address != addr) { + if (!c->devices[parity2]->devobj || RtlCompareMemory(hash2, th2, Vcb->csum_size) != Vcb->csum_size || th2->address != addr) { // fix parity 2 stripe = parity1 == 0 ? (c->chunk_item->num_stripes - 1) : (parity1 - 1); @@ -2205,18 +2198,22 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra } else log_error(Vcb, addr, c->devices[bad_stripe1]->devitem.dev_id, true, false, false); } else { + uint8_t hash1[MAX_HASH_SIZE]; + uint8_t hash2[MAX_HASH_SIZE]; + if (c->devices[parity1]->devobj) - crc32a = ~calc_crc32c(0xffffffff, &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.sector_size); + get_sector_csum(Vcb, &context->parity_scratch[i * Vcb->superblock.sector_size], hash1); if (c->devices[parity2]->devobj) - crc32b = ~calc_crc32c(0xffffffff, scratch, Vcb->superblock.sector_size); + get_sector_csum(Vcb, scratch, hash2); - if ((c->devices[parity1]->devobj && crc32a == context->csum[bad_off1]) || (c->devices[parity2]->devobj && crc32b == context->csum[bad_off1])) { - if (c->devices[parity2]->devobj && crc32b == context->csum[bad_off1]) { + if ((c->devices[parity1]->devobj && RtlCompareMemory(hash1, (uint8_t*)context->csum + (bad_off1 * Vcb->csum_size), Vcb->csum_size) == Vcb->csum_size) || + (c->devices[parity2]->devobj && RtlCompareMemory(hash2, (uint8_t*)context->csum + (bad_off1 * Vcb->csum_size), Vcb->csum_size) == Vcb->csum_size)) { + if (c->devices[parity2]->devobj && RtlCompareMemory(hash2, (uint8_t*)context->csum + (bad_off1 * Vcb->csum_size), Vcb->csum_size) == Vcb->csum_size) { RtlCopyMemory(&context->stripes[bad_stripe1].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], scratch, Vcb->superblock.sector_size); - if (c->devices[parity1]->devobj && crc32a != context->csum[bad_off1]) { + if (c->devices[parity1]->devobj && RtlCompareMemory(hash1, (uint8_t*)context->csum + (bad_off1 * Vcb->csum_size), Vcb->csum_size) != Vcb->csum_size) { // fix parity 1 stripe = (parity1 + 2) % c->chunk_item->num_stripes; @@ -2244,7 +2241,7 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra RtlCopyMemory(&context->stripes[bad_stripe1].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.sector_size); - if (c->devices[parity2]->devobj && crc32b != context->csum[bad_off1]) { + if (c->devices[parity2]->devobj && RtlCompareMemory(hash2, (uint8_t*)context->csum + (bad_off1 * Vcb->csum_size), Vcb->csum_size) != Vcb->csum_size) { // fix parity 2 stripe = parity1 == 0 ? (c->chunk_item->num_stripes - 1) : (parity1 - 1); @@ -2355,9 +2352,8 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra if (RtlCheckBit(&context->is_tree, bad_off1)) { tree_header* th = (tree_header*)&context->parity_scratch[i * Vcb->superblock.sector_size]; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (crc32 == *((uint32_t*)th->csum) && th->address == addr) { + if (check_tree_checksum(Vcb, th) && th->address == addr) { RtlCopyMemory(&context->stripes[bad_stripe1].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.node_size); @@ -2369,9 +2365,7 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra } else log_error(Vcb, addr, c->devices[bad_stripe1]->devitem.dev_id, true, false, false); } else { - uint32_t crc32 = ~calc_crc32c(0xffffffff, &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.sector_size); - - if (crc32 == context->csum[bad_off1]) { + if (check_sector_csum(Vcb, &context->parity_scratch[i * Vcb->superblock.sector_size], (uint8_t*)context->csum + (Vcb->csum_size * bad_off1))) { RtlCopyMemory(&context->stripes[bad_stripe1].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], &context->parity_scratch[i * Vcb->superblock.sector_size], Vcb->superblock.sector_size); @@ -2386,9 +2380,8 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra if (RtlCheckBit(&context->is_tree, bad_off2)) { tree_header* th = (tree_header*)&context->parity_scratch2[i * Vcb->superblock.sector_size]; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, Vcb->superblock.node_size - sizeof(th->csum)); - if (crc32 == *((uint32_t*)th->csum) && th->address == addr) { + if (check_tree_checksum(Vcb, th) && th->address == addr) { RtlCopyMemory(&context->stripes[bad_stripe2].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], &context->parity_scratch2[i * Vcb->superblock.sector_size], Vcb->superblock.node_size); @@ -2400,9 +2393,7 @@ static void scrub_raid6_stripe(device_extension* Vcb, chunk* c, scrub_context_ra } else log_error(Vcb, addr, c->devices[bad_stripe2]->devitem.dev_id, true, false, false); } else { - uint32_t crc32 = ~calc_crc32c(0xffffffff, &context->parity_scratch2[i * Vcb->superblock.sector_size], Vcb->superblock.sector_size); - - if (crc32 == context->csum[bad_off2]) { + if (check_sector_csum(Vcb, &context->parity_scratch2[i * Vcb->superblock.sector_size], (uint8_t*)context->csum + (Vcb->csum_size * bad_off2))) { RtlCopyMemory(&context->stripes[bad_stripe2].buf[(num * c->chunk_item->stripe_length) + (i * Vcb->superblock.sector_size)], &context->parity_scratch2[i * Vcb->superblock.sector_size], Vcb->superblock.sector_size); @@ -2456,7 +2447,7 @@ static NTSTATUS scrub_chunk_raid56_stripe_run(device_extension* Vcb, chunk* c, u Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -2503,7 +2494,7 @@ static NTSTATUS scrub_chunk_raid56_stripe_run(device_extension* Vcb, chunk* c, u RtlInitializeBitMap(&context.has_csum, csumarr, num_sectors); RtlClearAllBits(&context.has_csum); - context.csum = ExAllocatePoolWithTag(PagedPool, num_sectors * sizeof(uint32_t), ALLOC_TAG); + context.csum = ExAllocatePoolWithTag(PagedPool, num_sectors * Vcb->csum_size, ALLOC_TAG); if (!context.csum) { ERR("out of memory\n"); ExFreePool(allocarr); @@ -2553,7 +2544,7 @@ static NTSTATUS scrub_chunk_raid56_stripe_run(device_extension* Vcb, chunk* c, u EXTENT_ITEM* ei = (EXTENT_ITEM*)tp.item->data; if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); Status = STATUS_INTERNAL_ERROR; goto end; } @@ -2574,7 +2565,7 @@ static NTSTATUS scrub_chunk_raid56_stripe_run(device_extension* Vcb, chunk* c, u Status = find_item(Vcb, Vcb->checksum_root, &tp2, &searchkey, false, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); goto end; } @@ -2586,13 +2577,13 @@ static NTSTATUS scrub_chunk_raid56_stripe_run(device_extension* Vcb, chunk* c, u if (tp2.item->key.offset >= extent_start) { uint64_t csum_start = max(extent_start, tp2.item->key.offset); - uint64_t csum_end = min(extent_end, tp2.item->key.offset + (tp2.item->size * Vcb->superblock.sector_size / sizeof(uint32_t))); + uint64_t csum_end = min(extent_end, tp2.item->key.offset + (tp2.item->size * Vcb->superblock.sector_size / Vcb->csum_size)); RtlSetBits(&context.has_csum, (ULONG)((csum_start - run_start) / Vcb->superblock.sector_size), (ULONG)((csum_end - csum_start) / Vcb->superblock.sector_size)); - RtlCopyMemory(&context.csum[(csum_start - run_start) / Vcb->superblock.sector_size], - tp2.item->data + ((csum_start - tp2.item->key.offset) * sizeof(uint32_t) / Vcb->superblock.sector_size), - (ULONG)((csum_end - csum_start) * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory((uint8_t*)context.csum + ((csum_start - run_start) * Vcb->csum_size / Vcb->superblock.sector_size), + tp2.item->data + ((csum_start - tp2.item->key.offset) * Vcb->csum_size / Vcb->superblock.sector_size), + (ULONG)((csum_end - csum_start) * Vcb->csum_size / Vcb->superblock.sector_size)); } b2 = find_next_item(Vcb, &tp2, &next_tp2, false, NULL); @@ -2723,7 +2714,7 @@ static NTSTATUS scrub_chunk_raid56_stripe_run(device_extension* Vcb, chunk* c, u } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(context.stripes[i].Irp->MdlAddress); goto end3; } @@ -2806,7 +2797,7 @@ end3: context.stripes[i].buf, (uint32_t)(read_stripes * c->chunk_item->stripe_length)); if (!NT_SUCCESS(Status)) { - ERR("write_data_phys returned %08x\n", Status); + ERR("write_data_phys returned %08lx\n", Status); log_device_error(Vcb, c->devices[i], BTRFS_DEV_STAT_WRITE_ERRORS); goto end2; } @@ -2862,7 +2853,7 @@ static NTSTATUS scrub_chunk_raid56(device_extension* Vcb, chunk* c, uint64_t* of Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -2880,7 +2871,7 @@ static NTSTATUS scrub_chunk_raid56(device_extension* Vcb, chunk* c, uint64_t* of TRACE("%I64x\n", tp.item->key.obj_id); if (size < Vcb->superblock.sector_size) { - ERR("extent %I64x has size less than sector_size (%I64x < %x)\n", tp.item->key.obj_id, Vcb->superblock.sector_size); + ERR("extent %I64x has size less than sector_size (%I64x < %x)\n", tp.item->key.obj_id, size, Vcb->superblock.sector_size); return STATUS_INTERNAL_ERROR; } @@ -2890,7 +2881,7 @@ static NTSTATUS scrub_chunk_raid56(device_extension* Vcb, chunk* c, uint64_t* of if (stripe > stripe_end + 1) { Status = scrub_chunk_raid56_stripe_run(Vcb, c, stripe_start, stripe_end); if (!NT_SUCCESS(Status)) { - ERR("scrub_chunk_raid56_stripe_run returned %08x\n", Status); + ERR("scrub_chunk_raid56_stripe_run returned %08lx\n", Status); return Status; } @@ -2920,7 +2911,7 @@ static NTSTATUS scrub_chunk_raid56(device_extension* Vcb, chunk* c, uint64_t* of if (*changed) { Status = scrub_chunk_raid56_stripe_run(Vcb, c, stripe_start, stripe_end); if (!NT_SUCCESS(Status)) { - ERR("scrub_chunk_raid56_stripe_run returned %08x\n", Status); + ERR("scrub_chunk_raid56_stripe_run returned %08lx\n", Status); return Status; } @@ -2956,7 +2947,11 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b } else if (c->chunk_item->type & BLOCK_FLAG_RAID6) { Status = scrub_chunk_raid56(Vcb, c, offset, changed); goto end; - } else // SINGLE + } else if (c->chunk_item->type & BLOCK_FLAG_RAID1C3) + type = BLOCK_FLAG_DUPLICATE; + else if (c->chunk_item->type & BLOCK_FLAG_RAID1C4) + type = BLOCK_FLAG_DUPLICATE; + else // SINGLE type = BLOCK_FLAG_DUPLICATE; searchkey.obj_id = *offset; @@ -2965,7 +2960,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("error - find_item returned %08x\n", Status); + ERR("error - find_item returned %08lx\n", Status); goto end; } @@ -2978,7 +2973,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b if (tp.item->key.obj_id >= *offset && (tp.item->key.obj_type == TYPE_EXTENT_ITEM || tp.item->key.obj_type == TYPE_METADATA_ITEM)) { uint64_t size = tp.item->key.obj_type == TYPE_METADATA_ITEM ? Vcb->superblock.node_size : tp.item->key.offset; bool is_tree; - uint32_t* csum = NULL; + void* csum = NULL; RTL_BITMAP bmp; ULONG* bmparr = NULL, bmplen; @@ -2992,7 +2987,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b EXTENT_ITEM* ei = (EXTENT_ITEM*)tp.item->data; if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); Status = STATUS_INTERNAL_ERROR; goto end; } @@ -3002,7 +2997,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b } if (size < Vcb->superblock.sector_size) { - ERR("extent %I64x has size less than sector_size (%I64x < %x)\n", tp.item->key.obj_id, Vcb->superblock.sector_size); + ERR("extent %I64x has size less than sector_size (%I64x < %x)\n", tp.item->key.obj_id, size, Vcb->superblock.sector_size); Status = STATUS_INTERNAL_ERROR; goto end; } @@ -3011,7 +3006,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b if (!is_tree) { traverse_ptr tp2; - csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(sizeof(uint32_t) * size / Vcb->superblock.sector_size), ALLOC_TAG); + csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(Vcb->csum_size * size / Vcb->superblock.sector_size), ALLOC_TAG); if (!csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -3037,7 +3032,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b Status = find_item(Vcb, Vcb->checksum_root, &tp2, &searchkey, false, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); ExFreePool(csum); ExFreePool(bmparr); goto end; @@ -3050,13 +3045,13 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b if (tp2.item->key.obj_type == TYPE_EXTENT_CSUM) { if (tp2.item->key.offset >= tp.item->key.obj_id + size) break; - else if (tp2.item->size >= sizeof(uint32_t) && tp2.item->key.offset + (tp2.item->size * Vcb->superblock.sector_size / sizeof(uint32_t)) >= tp.item->key.obj_id) { + else if (tp2.item->size >= Vcb->csum_size && tp2.item->key.offset + (tp2.item->size * Vcb->superblock.sector_size / Vcb->csum_size) >= tp.item->key.obj_id) { uint64_t cs = max(tp.item->key.obj_id, tp2.item->key.offset); - uint64_t ce = min(tp.item->key.obj_id + size, tp2.item->key.offset + (tp2.item->size * Vcb->superblock.sector_size / sizeof(uint32_t))); + uint64_t ce = min(tp.item->key.obj_id + size, tp2.item->key.offset + (tp2.item->size * Vcb->superblock.sector_size / Vcb->csum_size)); - RtlCopyMemory(csum + ((cs - tp.item->key.obj_id) / Vcb->superblock.sector_size), - tp2.item->data + ((cs - tp2.item->key.offset) * sizeof(uint32_t) / Vcb->superblock.sector_size), - (ULONG)((ce - cs) * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory((uint8_t*)csum + ((cs - tp.item->key.obj_id) * Vcb->csum_size / Vcb->superblock.sector_size), + tp2.item->data + ((cs - tp2.item->key.offset) * Vcb->csum_size / Vcb->superblock.sector_size), + (ULONG)((ce - cs) * Vcb->csum_size / Vcb->superblock.sector_size)); RtlClearBits(&bmp, (ULONG)((cs - tp.item->key.obj_id) / Vcb->superblock.sector_size), (ULONG)((ce - cs) / Vcb->superblock.sector_size)); @@ -3077,7 +3072,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b if (!is_tree || tp.item->key.obj_id > tree_run_end) { Status = scrub_extent(Vcb, c, type, tree_run_start, (uint32_t)(tree_run_end - tree_run_start), NULL); if (!NT_SUCCESS(Status)) { - ERR("scrub_extent returned %08x\n", Status); + ERR("scrub_extent returned %08lx\n", Status); goto end; } @@ -3098,7 +3093,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b if (!is_tree) { Status = scrub_data_extent(Vcb, c, tp.item->key.obj_id, type, csum, &bmp, bmplen); if (!NT_SUCCESS(Status)) { - ERR("scrub_data_extent returned %08x\n", Status); + ERR("scrub_data_extent returned %08lx\n", Status); ExFreePool(csum); ExFreePool(bmparr); goto end; @@ -3128,7 +3123,7 @@ static NTSTATUS scrub_chunk(device_extension* Vcb, chunk* c, uint64_t* offset, b if (tree_run) { Status = scrub_extent(Vcb, c, type, tree_run_start, (uint32_t)(tree_run_end - tree_run_start), NULL); if (!NT_SUCCESS(Status)) { - ERR("scrub_extent returned %08x\n", Status); + ERR("scrub_extent returned %08lx\n", Status); goto end; } } @@ -3163,7 +3158,7 @@ static void __stdcall scrub_thread(void* context) { if (!NT_SUCCESS(Status)) { ExReleaseResourceLite(&Vcb->tree_lock); - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); Vcb->scrub.error = Status; goto end; } @@ -3226,7 +3221,7 @@ static void __stdcall scrub_thread(void* context) { Status = scrub_chunk(Vcb, c, &offset, &changed); if (!NT_SUCCESS(Status)) { - ERR("scrub_chunk returned %08x\n", Status); + ERR("scrub_chunk returned %08lx\n", Status); Vcb->scrub.stopping = true; Vcb->scrub.error = Status; break; @@ -3297,7 +3292,7 @@ NTSTATUS start_scrub(device_extension* Vcb, KPROCESSOR_MODE processor_mode) { Status = PsCreateSystemThread(&Vcb->scrub.thread, 0, &oa, NULL, NULL, scrub_thread, Vcb); if (!NT_SUCCESS(Status)) { - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); return Status; } diff --git a/drivers/filesystems/btrfs/search.c b/drivers/filesystems/btrfs/search.c index 3d824d9f767..c44e95f7c79 100644 --- a/drivers/filesystems/btrfs/search.c +++ b/drivers/filesystems/btrfs/search.c @@ -83,7 +83,7 @@ static bool fs_ignored(BTRFS_UUID* uuid) { Status = ZwCreateKey(&h, KEY_QUERY_VALUE, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos); if (!NT_SUCCESS(Status)) { - TRACE("ZwCreateKey returned %08x\n", Status); + TRACE("ZwCreateKey returned %08lx\n", Status); ExFreePool(path.Buffer); return false; } @@ -122,7 +122,7 @@ static void test_vol(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, uint8_t* data = NULL; uint32_t sector_size; - TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer); + TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer); sector_size = DeviceObject->SectorSize; @@ -134,20 +134,20 @@ static void test_vol(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, &geometry, sizeof(DISK_GEOMETRY), true, &iosb); if (!NT_SUCCESS(Status)) { - ERR("%.*S had a sector size of 0, and IOCTL_DISK_GET_DRIVE_GEOMETRY returned %08x\n", - devpath->Length / sizeof(WCHAR), devpath->Buffer, Status); + ERR("%.*S had a sector size of 0, and IOCTL_DISK_GET_DRIVE_GEOMETRY returned %08lx\n", + (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer, Status); goto deref; } if (iosb.Information < sizeof(DISK_GEOMETRY)) { - ERR("%.*S: IOCTL_DISK_GET_DRIVE_GEOMETRY returned %u bytes, expected %u\n", - devpath->Length / sizeof(WCHAR), devpath->Buffer, iosb.Information, sizeof(DISK_GEOMETRY)); + ERR("%.*S: IOCTL_DISK_GET_DRIVE_GEOMETRY returned %Iu bytes, expected %Iu\n", + (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer, iosb.Information, sizeof(DISK_GEOMETRY)); } sector_size = geometry.BytesPerSector; if (sector_size == 0) { - ERR("%.*S had a sector size of 0\n", devpath->Length / sizeof(WCHAR), devpath->Buffer); + ERR("%.*S had a sector size of 0\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer); goto deref; } } @@ -163,11 +163,8 @@ static void test_vol(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, if (NT_SUCCESS(Status) && ((superblock*)data)->magic == BTRFS_MAGIC) { superblock* sb = (superblock*)data; - uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - if (crc32 != *((uint32_t*)sb->checksum)) - ERR("checksum error on superblock\n"); - else { + if (check_superblock_checksum(sb)) { TRACE("volume found\n"); if (length >= superblock_addrs[1] + toread) { @@ -183,9 +180,7 @@ static void test_vol(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, Status = sync_read_phys(DeviceObject, FileObject, superblock_addrs[i], toread, (PUCHAR)sb2, true); if (NT_SUCCESS(Status) && sb2->magic == BTRFS_MAGIC) { - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb2->uuid, (ULONG)sizeof(superblock) - sizeof(sb2->checksum)); - - if (crc32 == *((uint32_t*)sb2->checksum) && sb2->generation > sb->generation) + if (check_superblock_checksum(sb2) && sb2->generation > sb->generation) RtlCopyMemory(sb, sb2, toread); } @@ -232,7 +227,7 @@ NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath) { Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, &mmps1, sizeof(MOUNTMGR_MOUNT_POINTS), false, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { - ERR("IOCTL_MOUNTMGR_DELETE_POINTS 1 returned %08x\n", Status); + ERR("IOCTL_MOUNTMGR_DELETE_POINTS 1 returned %08lx\n", Status); ExFreePool(mmp); return Status; } @@ -252,7 +247,7 @@ NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath) { Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_DELETE_POINTS, mmp, mmpsize, mmps2, mmps1.Size, false, NULL); if (!NT_SUCCESS(Status)) - ERR("IOCTL_MOUNTMGR_DELETE_POINTS 2 returned %08x\n", Status); + ERR("IOCTL_MOUNTMGR_DELETE_POINTS 2 returned %08lx\n", Status); ExFreePool(mmps2); ExFreePool(mmp); @@ -277,7 +272,7 @@ void disk_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath) { Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj); if (!NT_SUCCESS(Status)) { ExReleaseResourceLite(&boot_lock); - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); return; } @@ -311,18 +306,18 @@ void disk_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath) { &gli, sizeof(gli), true, NULL); if (!NT_SUCCESS(Status)) { - ERR("error reading length information: %08x\n", Status); + ERR("error reading length information: %08lx\n", Status); goto end; } Status = dev_ioctl(devobj, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL); if (!NT_SUCCESS(Status)) { - TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08x\n", Status); + TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status); sdn.DeviceNumber = 0xffffffff; sdn.PartitionNumber = 0; } else - TRACE("DeviceType = %u, DeviceNumber = %u, PartitionNumber = %u\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber); + TRACE("DeviceType = %lu, DeviceNumber = %lu, PartitionNumber = %lu\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber); test_vol(devobj, fileobj, devpath, sdn.DeviceNumber, sdn.PartitionNumber, gli.Length.QuadPart); @@ -348,13 +343,13 @@ void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lo if (vde->mounted_device && (!Vcb || !Vcb->options.allow_degraded)) { Status = pnp_surprise_removal(vde->mounted_device, NULL); if (!NT_SUCCESS(Status)) - ERR("pnp_surprise_removal returned %08x\n", Status); + ERR("pnp_surprise_removal returned %08lx\n", Status); } if (!Vcb || !Vcb->options.allow_degraded) { Status = IoSetDeviceInterfaceState(&vde->bus_name, false); if (!NT_SUCCESS(Status)) - WARN("IoSetDeviceInterfaceState returned %08x\n", Status); + WARN("IoSetDeviceInterfaceState returned %08lx\n", Status); } if (pdode->children_loaded > 0) { @@ -367,7 +362,7 @@ void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lo RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &FileObject, &mountmgr); if (!NT_SUCCESS(Status)) - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); else { le = pdode->children.Flink; @@ -379,7 +374,7 @@ void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lo Status = dev_ioctl(vc2->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &mdn, sizeof(MOUNTDEV_NAME), true, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); else { MOUNTDEV_NAME* mdn2; ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength; @@ -390,7 +385,7 @@ void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lo else { Status = dev_ioctl(vc2->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL); if (!NT_SUCCESS(Status)) - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); else { UNICODE_STRING name; @@ -399,7 +394,7 @@ void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lo Status = mountmgr_add_drive_letter(mountmgr, &name); if (!NT_SUCCESS(Status)) - WARN("mountmgr_add_drive_letter returned %08x\n", Status); + WARN("mountmgr_add_drive_letter returned %08lx\n", Status); } ExFreePool(mdn2); @@ -463,7 +458,7 @@ void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lo Status = IoSetDeviceInterfaceState(&vde->bus_name, false); if (!NT_SUCCESS(Status)) - WARN("IoSetDeviceInterfaceState returned %08x\n", Status); + WARN("IoSetDeviceInterfaceState returned %08lx\n", Status); if (vde->pdo->AttachedDevice) IoDetachDevice(vde->pdo); @@ -501,14 +496,14 @@ void volume_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath) { GET_LENGTH_INFORMATION gli; NTSTATUS Status; - TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer); + TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer); ExAcquireResourceSharedLite(&boot_lock, TRUE); Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &fileobj, &devobj); if (!NT_SUCCESS(Status)) { ExReleaseResourceLite(&boot_lock); - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); return; } @@ -519,22 +514,22 @@ void volume_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath) { Status = dev_ioctl(devobj, IOCTL_VOLUME_ONLINE, NULL, 0, NULL, 0, true, NULL); if (!NT_SUCCESS(Status)) - TRACE("IOCTL_VOLUME_ONLINE returned %08x\n", Status); + TRACE("IOCTL_VOLUME_ONLINE returned %08lx\n", Status); Status = dev_ioctl(devobj, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), true, NULL); if (!NT_SUCCESS(Status)) { - ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08x\n", Status); + ERR("IOCTL_DISK_GET_LENGTH_INFO returned %08lx\n", Status); goto end; } Status = dev_ioctl(devobj, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL); if (!NT_SUCCESS(Status)) { - TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08x\n", Status); + TRACE("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status); sdn.DeviceNumber = 0xffffffff; sdn.PartitionNumber = 0; } else - TRACE("DeviceType = %u, DeviceNumber = %u, PartitionNumber = %u\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber); + TRACE("DeviceType = %lu, DeviceNumber = %lu, PartitionNumber = %lu\n", sdn.DeviceType, sdn.DeviceNumber, sdn.PartitionNumber); // If we've just added a partition to a whole-disk filesystem, unmount it if (sdn.DeviceNumber != 0xffffffff && sdn.PartitionNumber != 0) { @@ -592,7 +587,7 @@ void volume_removal(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath) { LIST_ENTRY* le; UNICODE_STRING devpath2; - TRACE("%.*S\n", devpath->Length / sizeof(WCHAR), devpath->Buffer); + TRACE("%.*S\n", (int)(devpath->Length / sizeof(WCHAR)), devpath->Buffer); UNUSED(DriverObject); @@ -624,8 +619,10 @@ void volume_removal(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath) { if (vc->pnp_name.Length == devpath2.Length && RtlCompareMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length) == devpath2.Length) { TRACE("removing device\n"); - remove_volume_child(pdode->vde, vc, false); - changed = true; + if (!vc->boot_volume) { + remove_volume_child(pdode->vde, vc, false); + changed = true; + } break; } @@ -761,7 +758,7 @@ static void mountmgr_process_drive(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devi Status = dev_ioctl(vc->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, &mdn, sizeof(MOUNTDEV_NAME), true, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); else { MOUNTDEV_NAME* mdn2; ULONG mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength; @@ -772,7 +769,7 @@ static void mountmgr_process_drive(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devi else { Status = dev_ioctl(vc->devobj, IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, NULL, 0, mdn2, mdnsize, true, NULL); if (!NT_SUCCESS(Status)) - ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08x\n", Status); + ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status); else { if (mdn2->NameLength == device_name->Length && RtlCompareMemory(mdn2->Name, device_name->Buffer, device_name->Length) == device_name->Length) { vc2 = vc; @@ -802,7 +799,7 @@ static void mountmgr_process_drive(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devi if (need_remove) { Status = remove_drive_letter(mountmgr, device_name); if (!NT_SUCCESS(Status)) - ERR("remove_drive_letter returned %08x\n", Status); + ERR("remove_drive_letter returned %08lx\n", Status); else vc2->had_drive_letter = true; } @@ -851,7 +848,7 @@ void __stdcall mountmgr_thread(_In_ void* context) { RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &FileObject, &mountmgr); if (!NT_SUCCESS(Status)) { - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); return; } @@ -884,7 +881,7 @@ void __stdcall mountmgr_thread(_In_ void* context) { break; if (!NT_SUCCESS(Status)) { - ERR("IOCTL_MOUNTMGR_CHANGE_NOTIFY returned %08x\n", Status); + ERR("IOCTL_MOUNTMGR_CHANGE_NOTIFY returned %08lx\n", Status); break; } @@ -896,7 +893,7 @@ void __stdcall mountmgr_thread(_In_ void* context) { false, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) - ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08x\n", Status); + ERR("IOCTL_MOUNTMGR_QUERY_POINTS 1 returned %08lx\n", Status); else if (mmps.Size > 0) { MOUNTMGR_MOUNT_POINTS* mmps2; @@ -909,7 +906,7 @@ void __stdcall mountmgr_thread(_In_ void* context) { Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_QUERY_POINTS, &mmp, sizeof(MOUNTMGR_MOUNT_POINTS), mmps2, mmps.Size, false, NULL); if (!NT_SUCCESS(Status)) - ERR("IOCTL_MOUNTMGR_QUERY_POINTS returned %08x\n", Status); + ERR("IOCTL_MOUNTMGR_QUERY_POINTS returned %08lx\n", Status); else mountmgr_updated(mountmgr, mmps2); diff --git a/drivers/filesystems/btrfs/security.c b/drivers/filesystems/btrfs/security.c index bf5cff0fdfc..7f429e27274 100644 --- a/drivers/filesystems/btrfs/security.c +++ b/drivers/filesystems/btrfs/security.c @@ -106,7 +106,7 @@ void add_user_mapping(WCHAR* sidstring, ULONG sidstringlength, uint32_t uid) { } i++; - TRACE("val = %u, i = %u, ssl = %u\n", (uint32_t)val, i, sidstringlength); + TRACE("val = %u, i = %u, ssl = %lu\n", (uint32_t)val, i, sidstringlength); if (np == 0) { sid->auth[0] = (uint8_t)((val & 0xff0000000000) >> 40); @@ -191,7 +191,7 @@ void add_group_mapping(WCHAR* sidstring, ULONG sidstringlength, uint32_t gid) { } i++; - TRACE("val = %u, i = %u, ssl = %u\n", (uint32_t)val, i, sidstringlength); + TRACE("val = %u, i = %u, ssl = %lu\n", (uint32_t)val, i, sidstringlength); if (np == 0) { sid->auth[0] = (uint8_t)((val & 0xff0000000000) >> 40); @@ -422,20 +422,20 @@ static void get_top_level_sd(fcb* fcb) { Status = RtlCreateSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { - ERR("RtlCreateSecurityDescriptor returned %08x\n", Status); + ERR("RtlCreateSecurityDescriptor returned %08lx\n", Status); goto end; } Status = uid_to_sid(fcb->inode_item.st_uid, &usersid); if (!NT_SUCCESS(Status)) { - ERR("uid_to_sid returned %08x\n", Status); + ERR("uid_to_sid returned %08lx\n", Status); goto end; } Status = RtlSetOwnerSecurityDescriptor(&sd, usersid, false); if (!NT_SUCCESS(Status)) { - ERR("RtlSetOwnerSecurityDescriptor returned %08x\n", Status); + ERR("RtlSetOwnerSecurityDescriptor returned %08lx\n", Status); goto end; } @@ -448,7 +448,7 @@ static void get_top_level_sd(fcb* fcb) { Status = RtlSetGroupSecurityDescriptor(&sd, groupsid, false); if (!NT_SUCCESS(Status)) { - ERR("RtlSetGroupSecurityDescriptor returned %08x\n", Status); + ERR("RtlSetGroupSecurityDescriptor returned %08lx\n", Status); goto end; } @@ -462,7 +462,7 @@ static void get_top_level_sd(fcb* fcb) { Status = RtlSetDaclSecurityDescriptor(&sd, true, acl, false); if (!NT_SUCCESS(Status)) { - ERR("RtlSetDaclSecurityDescriptor returned %08x\n", Status); + ERR("RtlSetDaclSecurityDescriptor returned %08lx\n", Status); goto end; } @@ -473,7 +473,7 @@ static void get_top_level_sd(fcb* fcb) { // get sd size Status = RtlAbsoluteToSelfRelativeSD(&sd, NULL, &buflen); if (Status != STATUS_SUCCESS && Status != STATUS_BUFFER_TOO_SMALL) { - ERR("RtlAbsoluteToSelfRelativeSD 1 returned %08x\n", Status); + ERR("RtlAbsoluteToSelfRelativeSD 1 returned %08lx\n", Status); goto end; } @@ -491,7 +491,7 @@ static void get_top_level_sd(fcb* fcb) { Status = RtlAbsoluteToSelfRelativeSD(&sd, fcb->sd, &buflen); if (!NT_SUCCESS(Status)) { - ERR("RtlAbsoluteToSelfRelativeSD 2 returned %08x\n", Status); + ERR("RtlAbsoluteToSelfRelativeSD 2 returned %08lx\n", Status); ExFreePool(fcb->sd); fcb->sd = NULL; goto end; @@ -513,6 +513,12 @@ void fcb_get_sd(fcb* fcb, struct _fcb* parent, bool look_for_xattr, PIRP Irp) { PSID usersid = NULL, groupsid = NULL; SECURITY_SUBJECT_CONTEXT subjcont; ULONG buflen; + PSECURITY_DESCRIPTOR* abssd; + PSECURITY_DESCRIPTOR newsd; + PACL dacl, sacl; + PSID owner, group; + ULONG abssdlen = 0, dacllen = 0, sacllen = 0, ownerlen = 0, grouplen = 0; + uint8_t* buf; if (look_for_xattr && get_xattr(fcb->Vcb, fcb->subvol, fcb->inode, EA_NTACL, EA_NTACL_HASH, (uint8_t**)&fcb->sd, (uint16_t*)&buflen, Irp)) return; @@ -527,29 +533,104 @@ void fcb_get_sd(fcb* fcb, struct _fcb* parent, bool look_for_xattr, PIRP Irp) { Status = SeAssignSecurityEx(parent->sd, NULL, (void**)&fcb->sd, NULL, fcb->type == BTRFS_TYPE_DIRECTORY, SEF_DACL_AUTO_INHERIT, &subjcont, IoGetFileObjectGenericMapping(), PagedPool); if (!NT_SUCCESS(Status)) { - ERR("SeAssignSecurityEx returned %08x\n", Status); + ERR("SeAssignSecurityEx returned %08lx\n", Status); + return; + } + + Status = RtlSelfRelativeToAbsoluteSD(fcb->sd, NULL, &abssdlen, NULL, &dacllen, NULL, &sacllen, NULL, &ownerlen, + NULL, &grouplen); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) { + ERR("RtlSelfRelativeToAbsoluteSD returned %08lx\n", Status); + return; + } + + if (abssdlen + dacllen + sacllen + ownerlen + grouplen == 0) { + ERR("RtlSelfRelativeToAbsoluteSD returned zero lengths\n"); + return; + } + + buf = (uint8_t*)ExAllocatePoolWithTag(PagedPool, abssdlen + dacllen + sacllen + ownerlen + grouplen, ALLOC_TAG); + if (!buf) { + ERR("out of memory\n"); + return; + } + + abssd = (PSECURITY_DESCRIPTOR)buf; + dacl = (PACL)(buf + abssdlen); + sacl = (PACL)(buf + abssdlen + dacllen); + owner = (PSID)(buf + abssdlen + dacllen + sacllen); + group = (PSID)(buf + abssdlen + dacllen + sacllen + ownerlen); + + Status = RtlSelfRelativeToAbsoluteSD(fcb->sd, abssd, &abssdlen, dacl, &dacllen, sacl, &sacllen, owner, &ownerlen, + group, &grouplen); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) { + ERR("RtlSelfRelativeToAbsoluteSD returned %08lx\n", Status); + ExFreePool(buf); return; } Status = uid_to_sid(fcb->inode_item.st_uid, &usersid); if (!NT_SUCCESS(Status)) { - ERR("uid_to_sid returned %08x\n", Status); + ERR("uid_to_sid returned %08lx\n", Status); + ExFreePool(buf); return; } - RtlSetOwnerSecurityDescriptor(&fcb->sd, usersid, false); + RtlSetOwnerSecurityDescriptor(abssd, usersid, false); gid_to_sid(fcb->inode_item.st_gid, &groupsid); if (!groupsid) { ERR("out of memory\n"); ExFreePool(usersid); + ExFreePool(buf); return; } - RtlSetGroupSecurityDescriptor(&fcb->sd, groupsid, false); + RtlSetGroupSecurityDescriptor(abssd, groupsid, false); + + buflen = 0; + + Status = RtlAbsoluteToSelfRelativeSD(abssd, NULL, &buflen); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) { + ERR("RtlAbsoluteToSelfRelativeSD returned %08lx\n", Status); + ExFreePool(usersid); + ExFreePool(groupsid); + ExFreePool(buf); + return; + } + + if (buflen == 0) { + ERR("RtlAbsoluteToSelfRelativeSD returned a buffer size of 0\n"); + ExFreePool(usersid); + ExFreePool(groupsid); + ExFreePool(buf); + return; + } + + newsd = ExAllocatePoolWithTag(PagedPool, buflen, ALLOC_TAG); + if (!newsd) { + ERR("out of memory\n"); + ExFreePool(usersid); + ExFreePool(groupsid); + ExFreePool(buf); + return; + } + + Status = RtlAbsoluteToSelfRelativeSD(abssd, newsd, &buflen); + if (!NT_SUCCESS(Status)) { + ERR("RtlAbsoluteToSelfRelativeSD returned %08lx\n", Status); + ExFreePool(usersid); + ExFreePool(groupsid); + ExFreePool(buf); + return; + } + + ExFreePool(fcb->sd); + fcb->sd = newsd; ExFreePool(usersid); ExFreePool(groupsid); + ExFreePool(buf); } static NTSTATUS get_file_security(PFILE_OBJECT FileObject, SECURITY_DESCRIPTOR* relsd, ULONG* buflen, SECURITY_INFORMATION flags) { @@ -571,9 +652,9 @@ static NTSTATUS get_file_security(PFILE_OBJECT FileObject, SECURITY_DESCRIPTOR* Status = SeQuerySecurityDescriptorInfo(&flags, relsd, buflen, (void**)&fcb->sd); if (Status == STATUS_BUFFER_TOO_SMALL) - TRACE("SeQuerySecurityDescriptorInfo returned %08x\n", Status); + TRACE("SeQuerySecurityDescriptorInfo returned %08lx\n", Status); else if (!NT_SUCCESS(Status)) - ERR("SeQuerySecurityDescriptorInfo returned %08x\n", Status); + ERR("SeQuerySecurityDescriptorInfo returned %08lx\n", Status); return Status; } @@ -632,7 +713,7 @@ NTSTATUS __stdcall drv_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Ir if (IrpSp->Parameters.QuerySecurity.SecurityInformation & SACL_SECURITY_INFORMATION) TRACE("SACL_SECURITY_INFORMATION\n"); - TRACE("length = %u\n", IrpSp->Parameters.QuerySecurity.Length); + TRACE("length = %lu\n", IrpSp->Parameters.QuerySecurity.Length); sd = map_user_buffer(Irp, NormalPagePriority); TRACE("sd = %p\n", sd); @@ -656,7 +737,7 @@ NTSTATUS __stdcall drv_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Ir Irp->IoStatus.Information = 0; end: - TRACE("Irp->IoStatus.Information = %u\n", Irp->IoStatus.Information); + TRACE("Irp->IoStatus.Information = %Iu\n", Irp->IoStatus.Information); Irp->IoStatus.Status = Status; @@ -665,7 +746,7 @@ end: if (top_level) IoSetTopLevelIrp(NULL); - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); FsRtlExitFileSystem(); @@ -681,7 +762,7 @@ static NTSTATUS set_file_security(device_extension* Vcb, PFILE_OBJECT FileObject LARGE_INTEGER time; BTRFS_TIME now; - TRACE("(%p, %p, %p, %x)\n", Vcb, FileObject, sd, *flags); + TRACE("(%p, %p, %p, %lx)\n", Vcb, FileObject, sd, *flags); if (Vcb->readonly) return STATUS_MEDIA_WRITE_PROTECTED; @@ -710,7 +791,7 @@ static NTSTATUS set_file_security(device_extension* Vcb, PFILE_OBJECT FileObject Status = SeSetSecurityDescriptorInfo(NULL, flags, sd, (void**)&fcb->sd, PagedPool, IoGetFileObjectGenericMapping()); if (!NT_SUCCESS(Status)) { - ERR("SeSetSecurityDescriptorInfo returned %08x\n", Status); + ERR("SeSetSecurityDescriptorInfo returned %08lx\n", Status); goto end; } @@ -812,7 +893,7 @@ end: IoCompleteRequest(Irp, IO_NO_INCREMENT); - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); if (top_level) IoSetTopLevelIrp(NULL); @@ -860,7 +941,7 @@ void find_gid(struct _fcb* fcb, struct _fcb* parfcb, PSECURITY_SUBJECT_CONTEXT s Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenOwner, (void**)&to); if (!NT_SUCCESS(Status)) - ERR("SeQueryInformationToken returned %08x\n", Status); + ERR("SeQueryInformationToken returned %08lx\n", Status); else { if (search_for_gid(fcb, to->Owner)) { ExReleaseResourceLite(&mapping_lock); @@ -873,7 +954,7 @@ void find_gid(struct _fcb* fcb, struct _fcb* parfcb, PSECURITY_SUBJECT_CONTEXT s Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenPrimaryGroup, (void**)&tpg); if (!NT_SUCCESS(Status)) - ERR("SeQueryInformationToken returned %08x\n", Status); + ERR("SeQueryInformationToken returned %08lx\n", Status); else { if (search_for_gid(fcb, tpg->PrimaryGroup)) { ExReleaseResourceLite(&mapping_lock); @@ -886,7 +967,7 @@ void find_gid(struct _fcb* fcb, struct _fcb* parfcb, PSECURITY_SUBJECT_CONTEXT s Status = SeQueryInformationToken(subjcont->PrimaryToken, TokenGroups, (void**)&tg); if (!NT_SUCCESS(Status)) - ERR("SeQueryInformationToken returned %08x\n", Status); + ERR("SeQueryInformationToken returned %08lx\n", Status); else { ULONG i; @@ -913,13 +994,13 @@ NTSTATUS fcb_get_new_sd(fcb* fcb, file_ref* parfileref, ACCESS_STATE* as) { SEF_SACL_AUTO_INHERIT, &as->SubjectSecurityContext, IoGetFileObjectGenericMapping(), PagedPool); if (!NT_SUCCESS(Status)) { - ERR("SeAssignSecurityEx returned %08x\n", Status); + ERR("SeAssignSecurityEx returned %08lx\n", Status); return Status; } Status = RtlGetOwnerSecurityDescriptor(fcb->sd, &owner, &defaulted); if (!NT_SUCCESS(Status)) { - ERR("RtlGetOwnerSecurityDescriptor returned %08x\n", Status); + ERR("RtlGetOwnerSecurityDescriptor returned %08lx\n", Status); fcb->inode_item.st_uid = UID_NOBODY; } else { fcb->inode_item.st_uid = sid_to_uid(owner); diff --git a/drivers/filesystems/btrfs/send.c b/drivers/filesystems/btrfs/send.c index 2090131dc99..5e7a673744f 100644 --- a/drivers/filesystems/btrfs/send.c +++ b/drivers/filesystems/btrfs/send.c @@ -16,6 +16,7 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "crc32c.h" typedef struct send_dir { LIST_ENTRY list_entry; @@ -187,7 +188,7 @@ static NTSTATUS get_orphan_name(send_context* context, uint64_t inode, uint64_t Status = find_item(context->Vcb, context->root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -197,7 +198,7 @@ static NTSTATUS get_orphan_name(send_context* context, uint64_t inode, uint64_t if (context->parent) { Status = find_item(context->Vcb, context->parent, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -243,7 +244,7 @@ static NTSTATUS send_read_symlink(send_context* context, uint64_t inode, char** Status = find_item(context->Vcb, context->root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -253,7 +254,7 @@ static NTSTATUS send_read_symlink(send_context* context, uint64_t inode, char** } if (tp.item->size < sizeof(EXTENT_DATA)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA)); return STATUS_INTERNAL_ERROR; } @@ -268,7 +269,7 @@ static NTSTATUS send_read_symlink(send_context* context, uint64_t inode, char** } if (tp.item->size < offsetof(EXTENT_DATA, data[0]) + ed->decoded_size) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected %I64u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(EXTENT_DATA, data[0]) + ed->decoded_size); return STATUS_INTERNAL_ERROR; } @@ -287,7 +288,7 @@ static NTSTATUS send_inode(send_context* context, traverse_ptr* tp, traverse_ptr INODE_ITEM* ii2 = (INODE_ITEM*)tp2->item->data; if (tp2->item->size < sizeof(INODE_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, tp2->item->size, sizeof(INODE_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -306,7 +307,7 @@ static NTSTATUS send_inode(send_context* context, traverse_ptr* tp, traverse_ptr ii = (INODE_ITEM*)tp->item->data; if (tp->item->size < sizeof(INODE_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, tp->item->size, sizeof(INODE_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -336,7 +337,7 @@ static NTSTATUS send_inode(send_context* context, traverse_ptr* tp, traverse_ptr LIST_ENTRY* le; if (tp2->item->size < sizeof(INODE_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, tp2->item->size, sizeof(INODE_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -370,7 +371,7 @@ static NTSTATUS send_inode(send_context* context, traverse_ptr* tp, traverse_ptr Status = find_send_dir(context, tp->item->key.obj_id, ii->generation, &sd, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_send_dir returned %08x\n", Status); + ERR("find_send_dir returned %08lx\n", Status); return Status; } @@ -427,7 +428,7 @@ static NTSTATUS send_inode(send_context* context, traverse_ptr* tp, traverse_ptr Status = get_orphan_name(context, tp->item->key.obj_id, ii->generation, name); if (!NT_SUCCESS(Status)) { - ERR("get_orphan_name returned %08x\n", Status); + ERR("get_orphan_name returned %08lx\n", Status); return Status; } @@ -445,7 +446,7 @@ static NTSTATUS send_inode(send_context* context, traverse_ptr* tp, traverse_ptr Status = send_read_symlink(context, tp->item->key.obj_id, &link, &linklen); if (!NT_SUCCESS(Status)) { - ERR("send_read_symlink returned %08x\n", Status); + ERR("send_read_symlink returned %08lx\n", Status); return Status; } @@ -457,7 +458,7 @@ static NTSTATUS send_inode(send_context* context, traverse_ptr* tp, traverse_ptr if (ii->st_mode & __S_IFDIR) { Status = find_send_dir(context, tp->item->key.obj_id, ii->generation, &sd, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_send_dir returned %08x\n", Status); + ERR("find_send_dir returned %08lx\n", Status); return Status; } @@ -692,7 +693,7 @@ static NTSTATUS find_send_dir(send_context* context, uint64_t dir, uint64_t gene if (dir == SUBVOL_ROOT_INODE) { Status = send_add_dir(context, dir, NULL, NULL, 0, false, le, psd); if (!NT_SUCCESS(Status)) { - ERR("send_add_dir returned %08x\n", Status); + ERR("send_add_dir returned %08lx\n", Status); return Status; } @@ -712,7 +713,7 @@ static NTSTATUS find_send_dir(send_context* context, uint64_t dir, uint64_t gene Status = find_item(context->Vcb, context->parent, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -730,14 +731,14 @@ static NTSTATUS find_send_dir(send_context* context, uint64_t dir, uint64_t gene else { Status = find_send_dir(context, tp.item->key.offset, generation, &parent, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_send_dir returned %08x\n", Status); + ERR("find_send_dir returned %08lx\n", Status); return Status; } } Status = send_add_dir(context, dir, parent, ir->name, ir->n, true, NULL, psd); if (!NT_SUCCESS(Status)) { - ERR("send_add_dir returned %08x\n", Status); + ERR("send_add_dir returned %08lx\n", Status); return Status; } @@ -750,13 +751,13 @@ static NTSTATUS find_send_dir(send_context* context, uint64_t dir, uint64_t gene Status = get_orphan_name(context, dir, generation, name); if (!NT_SUCCESS(Status)) { - ERR("get_orphan_name returned %08x\n", Status); + ERR("get_orphan_name returned %08lx\n", Status); return Status; } Status = send_add_dir(context, dir, NULL, name, (uint16_t)strlen(name), true, le, psd); if (!NT_SUCCESS(Status)) { - ERR("send_add_dir returned %08x\n", Status); + ERR("send_add_dir returned %08lx\n", Status); return Status; } @@ -779,7 +780,7 @@ static NTSTATUS send_inode_ref(send_context* context, traverse_ptr* tp, bool tre return STATUS_SUCCESS; if (tp->item->size < sizeof(INODE_REF)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, tp->item->size, sizeof(INODE_REF)); return STATUS_INTERNAL_ERROR; } @@ -789,7 +790,7 @@ static NTSTATUS send_inode_ref(send_context* context, traverse_ptr* tp, bool tre Status = find_send_dir(context, dir, context->root->root_item.ctransid, &sd, &added_dummy); if (!NT_SUCCESS(Status)) { - ERR("find_send_dir returned %08x\n", Status); + ERR("find_send_dir returned %08lx\n", Status); return Status; } @@ -873,7 +874,7 @@ static NTSTATUS send_inode_extref(send_context* context, traverse_ptr* tp, bool uint16_t len; if (tp->item->size < sizeof(INODE_EXTREF)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, tp->item->size, sizeof(INODE_EXTREF)); return STATUS_INTERNAL_ERROR; } @@ -898,7 +899,7 @@ static NTSTATUS send_inode_extref(send_context* context, traverse_ptr* tp, bool Status = find_send_dir(context, ier->dir, context->root->root_item.ctransid, &sd, &added_dummy); if (!NT_SUCCESS(Status)) { - ERR("find_send_dir returned %08x\n", Status); + ERR("find_send_dir returned %08lx\n", Status); return Status; } @@ -1070,7 +1071,7 @@ static NTSTATUS get_dir_last_child(send_context* context, uint64_t* last_inode) Status = find_item(context->Vcb, context->parent, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -1142,7 +1143,7 @@ static NTSTATUS look_for_collision(send_context* context, send_dir* sd, char* na Status = find_item(context->Vcb, context->parent, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -1213,14 +1214,14 @@ static NTSTATUS make_file_orphan(send_context* context, uint64_t inode, bool dir Status = get_orphan_name(context, inode, generation, name); if (!NT_SUCCESS(Status)) { - ERR("get_orphan_name returned %08x\n", Status); + ERR("get_orphan_name returned %08lx\n", Status); return Status; } if (dir) { Status = find_send_dir(context, inode, generation, &sd, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_send_dir returned %08x\n", Status); + ERR("find_send_dir returned %08lx\n", Status); return Status; } @@ -1294,7 +1295,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt if (!context->lastinode.sd) { Status = find_send_dir(context, context->lastinode.inode, context->lastinode.gen, &context->lastinode.sd, false); if (!NT_SUCCESS(Status)) { - ERR("find_send_dir returned %08x\n", Status); + ERR("find_send_dir returned %08lx\n", Status); return Status; } } @@ -1306,14 +1307,14 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt Status = look_for_collision(context, r->sd, r->name, r->namelen, &inode, &dir); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) { - ERR("look_for_collision returned %08x\n", Status); + ERR("look_for_collision returned %08lx\n", Status); return Status; } if (Status == STATUS_OBJECT_NAME_COLLISION && inode > context->lastinode.inode) { Status = make_file_orphan(context, inode, dir, context->parent->root_item.ctransid, r); if (!NT_SUCCESS(Status)) { - ERR("make_file_orphan returned %08x\n", Status); + ERR("make_file_orphan returned %08lx\n", Status); return Status; } } @@ -1321,7 +1322,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt if (context->lastinode.o) { Status = found_path(context, r->sd, r->name, r->namelen); if (!NT_SUCCESS(Status)) { - ERR("found_path returned %08x\n", Status); + ERR("found_path returned %08lx\n", Status); return Status; } @@ -1369,7 +1370,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt } else if (r && !or) { // new Status = found_path(context, r->sd, r->name, r->namelen); if (!NT_SUCCESS(Status)) { - ERR("found_path returned %08x\n", Status); + ERR("found_path returned %08lx\n", Status); return Status; } @@ -1380,7 +1381,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt Status = get_dir_last_child(context, &last_inode); if (!NT_SUCCESS(Status)) { - ERR("get_dir_last_child returned %08x\n", Status); + ERR("get_dir_last_child returned %08lx\n", Status); return Status; } @@ -1395,7 +1396,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt Status = get_orphan_name(context, context->lastinode.inode, context->lastinode.gen, name); if (!NT_SUCCESS(Status)) { - ERR("get_orphan_name returned %08x\n", Status); + ERR("get_orphan_name returned %08lx\n", Status); return Status; } @@ -1422,7 +1423,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt Status = add_pending_rmdir(context, last_inode); if (!NT_SUCCESS(Status)) { - ERR("add_pending_rmdir returned %08x\n", Status); + ERR("add_pending_rmdir returned %08lx\n", Status); return Status; } } @@ -1494,14 +1495,14 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt if (context->parent) { Status = look_for_collision(context, r->sd, r->name, r->namelen, &inode, &dir); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) { - ERR("look_for_collision returned %08x\n", Status); + ERR("look_for_collision returned %08lx\n", Status); return Status; } if (Status == STATUS_OBJECT_NAME_COLLISION && inode > context->lastinode.inode) { Status = make_file_orphan(context, inode, dir, context->lastinode.gen, r); if (!NT_SUCCESS(Status)) { - ERR("make_file_orphan returned %08x\n", Status); + ERR("make_file_orphan returned %08lx\n", Status); return Status; } } @@ -1510,7 +1511,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt if (context->datalen > SEND_BUFFER_LENGTH) { Status = wait_for_flush(context, tp1, tp2); if (!NT_SUCCESS(Status)) { - ERR("wait_for_flush returned %08x\n", Status); + ERR("wait_for_flush returned %08lx\n", Status); return Status; } @@ -1520,7 +1521,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt Status = found_path(context, r->sd, r->name, r->namelen); if (!NT_SUCCESS(Status)) { - ERR("found_path returned %08x\n", Status); + ERR("found_path returned %08lx\n", Status); return Status; } @@ -1555,7 +1556,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt if (context->datalen > SEND_BUFFER_LENGTH) { Status = wait_for_flush(context, tp1, tp2); if (!NT_SUCCESS(Status)) { - ERR("wait_for_flush returned %08x\n", Status); + ERR("wait_for_flush returned %08lx\n", Status); return Status; } @@ -1565,7 +1566,7 @@ static NTSTATUS flush_refs(send_context* context, traverse_ptr* tp1, traverse_pt Status = send_unlink_command(context, or->sd, or->namelen, or->name); if (!NT_SUCCESS(Status)) { - ERR("send_unlink_command returned %08x\n", Status); + ERR("send_unlink_command returned %08lx\n", Status); return Status; } @@ -1622,7 +1623,7 @@ static NTSTATUS wait_for_flush(send_context* context, traverse_ptr* tp1, travers if (tp1) { Status = find_item(context->Vcb, context->root, tp1, &key1, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -1635,7 +1636,7 @@ static NTSTATUS wait_for_flush(send_context* context, traverse_ptr* tp1, travers if (tp2) { Status = find_item(context->Vcb, context->parent, tp2, &key2, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -1801,13 +1802,13 @@ static NTSTATUS sync_ext_cutoff_points(send_context* context) { if (len1 < len2) { Status = divide_ext(ext2, len1, false); if (!NT_SUCCESS(Status)) { - ERR("divide_ext returned %08x\n", Status); + ERR("divide_ext returned %08lx\n", Status); return Status; } } else if (len2 < len1) { Status = divide_ext(ext1, len2, false); if (!NT_SUCCESS(Status)) { - ERR("divide_ext returned %08x\n", Status); + ERR("divide_ext returned %08lx\n", Status); return Status; } } @@ -1824,13 +1825,13 @@ static NTSTATUS sync_ext_cutoff_points(send_context* context) { Status = divide_ext(ext1, context->lastinode.size - ext1->offset, true); if (!NT_SUCCESS(Status)) { - ERR("divide_ext returned %08x\n", Status); + ERR("divide_ext returned %08lx\n", Status); return Status; } Status = divide_ext(ext2, context->lastinode.size - ext2->offset, true); if (!NT_SUCCESS(Status)) { - ERR("divide_ext returned %08x\n", Status); + ERR("divide_ext returned %08lx\n", Status); return Status; } @@ -1854,7 +1855,7 @@ static bool send_add_tlv_clone_path(send_context* context, root* r, uint64_t ino Status = find_item(context->Vcb, r, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return false; } @@ -1901,7 +1902,7 @@ static bool send_add_tlv_clone_path(send_context* context, root* r, uint64_t ino Status = find_item(context->Vcb, r, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return false; } @@ -1963,7 +1964,7 @@ static bool try_clone_edr(send_context* context, send_ext* se, EXTENT_DATA_REF* Status = find_item(context->Vcb, r, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return false; } @@ -1972,13 +1973,13 @@ static bool try_clone_edr(send_context* context, send_ext* se, EXTENT_DATA_REF* if (tp.item->key.obj_id == searchkey.obj_id && tp.item->key.obj_type == searchkey.obj_type) { if (tp.item->size < sizeof(EXTENT_DATA)) - ERR("(%I64x,%x,%I64x) has size %u, not at least %u as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA)); + ERR("(%I64x,%x,%I64x) has size %u, not at least %Iu as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA)); else { EXTENT_DATA* ed = (EXTENT_DATA*)tp.item->data; if (ed->type == EXTENT_TYPE_REGULAR) { if (tp.item->size < offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2)) - ERR("(%I64x,%x,%I64x) has size %u, not %u as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, + ERR("(%I64x,%x,%I64x) has size %u, not %Iu as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2)); else { EXTENT_DATA2* ed2 = (EXTENT_DATA2*)ed->data; @@ -2038,7 +2039,7 @@ static bool try_clone(send_context* context, send_ext* se) { Status = find_item(context->Vcb, context->Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return false; } @@ -2048,7 +2049,7 @@ static bool try_clone(send_context* context, send_ext* se) { } if (tp.item->size < sizeof(EXTENT_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_ITEM)); return false; } @@ -2066,7 +2067,7 @@ static bool try_clone(send_context* context, send_ext* se) { len--; if (sectlen > len) { - ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); + ERR("(%I64x,%x,%I64x): %x bytes left, expecting at least %lx\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, len, sectlen); return false; } @@ -2097,7 +2098,7 @@ static bool try_clone(send_context* context, send_ext* se) { Status = find_item(context->Vcb, context->Vcb->extent_root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return false; } @@ -2106,7 +2107,7 @@ static bool try_clone(send_context* context, send_ext* se) { if (tp.item->key.obj_id == searchkey.obj_id && tp.item->key.obj_type == searchkey.obj_type) { if (tp.item->size < sizeof(EXTENT_DATA_REF)) - ERR("(%I64x,%x,%I64x) has size %u, not %u as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA_REF)); + ERR("(%I64x,%x,%I64x) has size %u, not %Iu as expected\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(EXTENT_DATA_REF)); else { if (try_clone_edr(context, se, (EXTENT_DATA_REF*)tp.item->data)) return true; @@ -2132,19 +2133,19 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse if (context->parent) { Status = add_ext_holes(context->Vcb, &context->lastinode.exts, context->lastinode.size); if (!NT_SUCCESS(Status)) { - ERR("add_ext_holes returned %08x\n", Status); + ERR("add_ext_holes returned %08lx\n", Status); return Status; } Status = add_ext_holes(context->Vcb, &context->lastinode.oldexts, context->lastinode.size); if (!NT_SUCCESS(Status)) { - ERR("add_ext_holes returned %08x\n", Status); + ERR("add_ext_holes returned %08lx\n", Status); return Status; } Status = sync_ext_cutoff_points(context); if (!NT_SUCCESS(Status)) { - ERR("sync_ext_cutoff_points returned %08x\n", Status); + ERR("sync_ext_cutoff_points returned %08lx\n", Status); return Status; } } @@ -2196,7 +2197,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse if (se->data.compression == BTRFS_COMPRESSION_ZLIB) { Status = zlib_decompress(se->data.data, inlen, &context->data[context->datalen - se->data.decoded_size], (uint32_t)se->data.decoded_size); if (!NT_SUCCESS(Status)) { - ERR("zlib_decompress returned %08x\n", Status); + ERR("zlib_decompress returned %08lx\n", Status); ExFreePool(se); if (se2) ExFreePool(se2); return Status; @@ -2212,7 +2213,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse Status = lzo_decompress(se->data.data + sizeof(uint32_t), inlen, &context->data[context->datalen - se->data.decoded_size], (uint32_t)se->data.decoded_size, sizeof(uint32_t)); if (!NT_SUCCESS(Status)) { - ERR("lzo_decompress returned %08x\n", Status); + ERR("lzo_decompress returned %08lx\n", Status); ExFreePool(se); if (se2) ExFreePool(se2); return Status; @@ -2220,7 +2221,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse } else if (se->data.compression == BTRFS_COMPRESSION_ZSTD) { Status = zstd_decompress(se->data.data, inlen, &context->data[context->datalen - se->data.decoded_size], (uint32_t)se->data.decoded_size); if (!NT_SUCCESS(Status)) { - ERR("zlib_decompress returned %08x\n", Status); + ERR("zlib_decompress returned %08lx\n", Status); ExFreePool(se); if (se2) ExFreePool(se2); return Status; @@ -2259,7 +2260,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse if (context->datalen > SEND_BUFFER_LENGTH) { Status = wait_for_flush(context, tp1, tp2); if (!NT_SUCCESS(Status)) { - ERR("wait_for_flush returned %08x\n", Status); + ERR("wait_for_flush returned %08lx\n", Status); ExFreePool(se); if (se2) ExFreePool(se2); return Status; @@ -2302,12 +2303,12 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse uint16_t length = (uint16_t)min(ed2->offset + ed2->num_bytes - off, MAX_SEND_WRITE); ULONG skip_start; uint64_t addr = ed2->address + off; - uint32_t* csum; + void* csum; if (context->datalen > SEND_BUFFER_LENGTH) { Status = wait_for_flush(context, tp1, tp2); if (!NT_SUCCESS(Status)) { - ERR("wait_for_flush returned %08x\n", Status); + ERR("wait_for_flush returned %08lx\n", Status); ExFreePool(buf); ExFreePool(se); if (se2) ExFreePool(se2); @@ -2332,7 +2333,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse len = (uint32_t)sector_align(length + skip_start, context->Vcb->superblock.sector_size) / context->Vcb->superblock.sector_size; - csum = ExAllocatePoolWithTag(PagedPool, len * sizeof(uint32_t), ALLOC_TAG); + csum = ExAllocatePoolWithTag(PagedPool, len * context->Vcb->csum_size, ALLOC_TAG); if (!csum) { ERR("out of memory\n"); ExFreePool(buf); @@ -2343,7 +2344,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse Status = load_csum(context->Vcb, csum, addr, len, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_csum returned %08x\n", Status); + ERR("load_csum returned %08lx\n", Status); ExFreePool(csum); ExFreePool(buf); ExFreePool(se); @@ -2355,7 +2356,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse Status = read_data(context->Vcb, addr, (uint32_t)sector_align(length + skip_start, context->Vcb->superblock.sector_size), csum, false, buf, NULL, NULL, NULL, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); ExFreePool(buf); ExFreePool(se); if (se2) ExFreePool(se2); @@ -2385,7 +2386,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse } else { uint8_t *buf, *compbuf; uint64_t off; - uint32_t* csum; + void* csum; buf = ExAllocatePoolWithTag(PagedPool, (ULONG)se->data.decoded_size, ALLOC_TAG); if (!buf) { @@ -2411,7 +2412,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse len = (uint32_t)(ed2->size / context->Vcb->superblock.sector_size); - csum = ExAllocatePoolWithTag(PagedPool, len * sizeof(uint32_t), ALLOC_TAG); + csum = ExAllocatePoolWithTag(PagedPool, len * context->Vcb->csum_size, ALLOC_TAG); if (!csum) { ERR("out of memory\n"); ExFreePool(compbuf); @@ -2423,7 +2424,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse Status = load_csum(context->Vcb, csum, ed2->address, len, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_csum returned %08x\n", Status); + ERR("load_csum returned %08lx\n", Status); ExFreePool(csum); ExFreePool(compbuf); ExFreePool(buf); @@ -2435,7 +2436,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse Status = read_data(context->Vcb, ed2->address, (uint32_t)ed2->size, csum, false, compbuf, NULL, NULL, NULL, 0, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned %08x\n", Status); + ERR("read_data returned %08lx\n", Status); ExFreePool(compbuf); ExFreePool(buf); ExFreePool(se); @@ -2450,7 +2451,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse if (se->data.compression == BTRFS_COMPRESSION_ZLIB) { Status = zlib_decompress(compbuf, (uint32_t)ed2->size, buf, (uint32_t)se->data.decoded_size); if (!NT_SUCCESS(Status)) { - ERR("zlib_decompress returned %08x\n", Status); + ERR("zlib_decompress returned %08lx\n", Status); ExFreePool(compbuf); ExFreePool(buf); ExFreePool(se); @@ -2460,7 +2461,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse } else if (se->data.compression == BTRFS_COMPRESSION_LZO) { Status = lzo_decompress(&compbuf[sizeof(uint32_t)], (uint32_t)ed2->size, buf, (uint32_t)se->data.decoded_size, sizeof(uint32_t)); if (!NT_SUCCESS(Status)) { - ERR("lzo_decompress returned %08x\n", Status); + ERR("lzo_decompress returned %08lx\n", Status); ExFreePool(compbuf); ExFreePool(buf); ExFreePool(se); @@ -2470,7 +2471,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse } else if (se->data.compression == BTRFS_COMPRESSION_ZSTD) { Status = zstd_decompress(compbuf, (uint32_t)ed2->size, buf, (uint32_t)se->data.decoded_size); if (!NT_SUCCESS(Status)) { - ERR("zstd_decompress returned %08x\n", Status); + ERR("zstd_decompress returned %08lx\n", Status); ExFreePool(compbuf); ExFreePool(buf); ExFreePool(se); @@ -2488,7 +2489,7 @@ static NTSTATUS flush_extents(send_context* context, traverse_ptr* tp1, traverse if (context->datalen > SEND_BUFFER_LENGTH) { Status = wait_for_flush(context, tp1, tp2); if (!NT_SUCCESS(Status)) { - ERR("wait_for_flush returned %08x\n", Status); + ERR("wait_for_flush returned %08lx\n", Status); ExFreePool(buf); ExFreePool(se); if (se2) ExFreePool(se2); @@ -2534,7 +2535,7 @@ static NTSTATUS finish_inode(send_context* context, traverse_ptr* tp1, traverse_ if (!IsListEmpty(&context->lastinode.refs) || !IsListEmpty(&context->lastinode.oldrefs)) { NTSTATUS Status = flush_refs(context, tp1, tp2); if (!NT_SUCCESS(Status)) { - ERR("flush_refs returned %08x\n", Status); + ERR("flush_refs returned %08lx\n", Status); return Status; } @@ -2546,7 +2547,7 @@ static NTSTATUS finish_inode(send_context* context, traverse_ptr* tp1, traverse_ if (context->lastinode.file) { NTSTATUS Status = flush_extents(context, tp1, tp2); if (!NT_SUCCESS(Status)) { - ERR("flush_extents returned %08x\n", Status); + ERR("flush_extents returned %08lx\n", Status); return Status; } @@ -2624,7 +2625,7 @@ static NTSTATUS send_extent_data(send_context* context, traverse_ptr* tp, traver if (!IsListEmpty(&context->lastinode.refs) || !IsListEmpty(&context->lastinode.oldrefs)) { Status = flush_refs(context, tp, tp2); if (!NT_SUCCESS(Status)) { - ERR("flush_refs returned %08x\n", Status); + ERR("flush_refs returned %08lx\n", Status); return Status; } @@ -2640,7 +2641,7 @@ static NTSTATUS send_extent_data(send_context* context, traverse_ptr* tp, traver EXTENT_DATA2* ed2 = NULL; if (tp->item->size < sizeof(EXTENT_DATA)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, tp->item->size, sizeof(EXTENT_DATA)); return STATUS_INTERNAL_ERROR; } @@ -2665,7 +2666,7 @@ static NTSTATUS send_extent_data(send_context* context, traverse_ptr* tp, traver if (ed->type == EXTENT_TYPE_REGULAR) { if (tp->item->size < offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, tp->item->size, offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2)); return STATUS_INTERNAL_ERROR; } @@ -2673,7 +2674,7 @@ static NTSTATUS send_extent_data(send_context* context, traverse_ptr* tp, traver ed2 = (EXTENT_DATA2*)ed->data; } else if (ed->type == EXTENT_TYPE_INLINE) { if (tp->item->size < offsetof(EXTENT_DATA, data[0]) + ed->decoded_size && ed->compression == BTRFS_COMPRESSION_NONE) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected %I64u\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, tp->item->size, offsetof(EXTENT_DATA, data[0]) + ed->decoded_size); return STATUS_INTERNAL_ERROR; } @@ -2699,7 +2700,7 @@ static NTSTATUS send_extent_data(send_context* context, traverse_ptr* tp, traver EXTENT_DATA2* ed2 = NULL; if (tp2->item->size < sizeof(EXTENT_DATA)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, tp2->item->size, sizeof(EXTENT_DATA)); return STATUS_INTERNAL_ERROR; } @@ -2724,7 +2725,7 @@ static NTSTATUS send_extent_data(send_context* context, traverse_ptr* tp, traver if (ed->type == EXTENT_TYPE_REGULAR) { if (tp2->item->size < offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, tp2->item->size, offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2)); return STATUS_INTERNAL_ERROR; } @@ -2732,7 +2733,7 @@ static NTSTATUS send_extent_data(send_context* context, traverse_ptr* tp, traver ed2 = (EXTENT_DATA2*)ed->data; } else if (ed->type == EXTENT_TYPE_INLINE) { if (tp2->item->size < offsetof(EXTENT_DATA, data[0]) + ed->decoded_size) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected %u\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected %I64u\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, tp2->item->size, offsetof(EXTENT_DATA, data[0]) + ed->decoded_size); return STATUS_INTERNAL_ERROR; } @@ -2773,7 +2774,7 @@ static NTSTATUS send_xattr(send_context* context, traverse_ptr* tp, traverse_ptr if (!IsListEmpty(&context->lastinode.refs) || !IsListEmpty(&context->lastinode.oldrefs)) { NTSTATUS Status = flush_refs(context, tp, tp2); if (!NT_SUCCESS(Status)) { - ERR("flush_refs returned %08x\n", Status); + ERR("flush_refs returned %08lx\n", Status); return Status; } @@ -2782,13 +2783,13 @@ static NTSTATUS send_xattr(send_context* context, traverse_ptr* tp, traverse_ptr } if (tp && tp->item->size < sizeof(DIR_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp->item->key.obj_id, tp->item->key.obj_type, tp->item->key.offset, tp->item->size, sizeof(DIR_ITEM)); return STATUS_INTERNAL_ERROR; } if (tp2 && tp2->item->size < sizeof(DIR_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp2->item->key.obj_id, tp2->item->key.obj_type, tp2->item->key.offset, tp2->item->size, sizeof(DIR_ITEM)); return STATUS_INTERNAL_ERROR; } @@ -3001,7 +3002,7 @@ static void __stdcall send_thread(void* ctx) { free_trees(context->Vcb); if (!NT_SUCCESS(Status)) { - ERR("do_write returned %08x\n", Status); + ERR("do_write returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3013,7 +3014,7 @@ static void __stdcall send_thread(void* ctx) { Status = find_item(context->Vcb, context->root, &tp, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3022,7 +3023,7 @@ static void __stdcall send_thread(void* ctx) { bool ended1 = false, ended2 = false; Status = find_item(context->Vcb, context->parent, &tp2, &searchkey, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3047,7 +3048,7 @@ static void __stdcall send_thread(void* ctx) { if (!ended1) { Status = find_item(context->Vcb, context->root, &tp, &key1, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3063,7 +3064,7 @@ static void __stdcall send_thread(void* ctx) { if (!ended2) { Status = find_item(context->Vcb, context->parent, &tp2, &key2, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3080,7 +3081,7 @@ static void __stdcall send_thread(void* ctx) { while (!ended1 && !ended2 && tp.tree->header.address == tp2.tree->header.address) { Status = skip_to_difference(context->Vcb, &tp, &tp2, &ended1, &ended2); if (!NT_SUCCESS(Status)) { - ERR("skip_to_difference returned %08x\n", Status); + ERR("skip_to_difference returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3094,7 +3095,7 @@ static void __stdcall send_thread(void* ctx) { if (context->lastinode.inode != 0 && tp.item->key.obj_id > context->lastinode.inode) { Status = finish_inode(context, ended1 ? NULL : &tp, ended2 ? NULL : &tp2); if (!NT_SUCCESS(Status)) { - ERR("finish_inode returned %08x\n", Status); + ERR("finish_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3139,7 +3140,7 @@ static void __stdcall send_thread(void* ctx) { Status = send_inode(context, NULL, &tp2); if (!NT_SUCCESS(Status)) { - ERR("send_inode returned %08x\n", Status); + ERR("send_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3158,14 +3159,14 @@ static void __stdcall send_thread(void* ctx) { if (tp2.item->key.obj_type == TYPE_INODE_REF) { Status = send_inode_ref(context, &tp2, true); if (!NT_SUCCESS(Status)) { - ERR("send_inode_ref returned %08x\n", Status); + ERR("send_inode_ref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp2.item->key.obj_type == TYPE_INODE_EXTREF) { Status = send_inode_extref(context, &tp2, true); if (!NT_SUCCESS(Status)) { - ERR("send_inode_extref returned %08x\n", Status); + ERR("send_inode_extref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3174,7 +3175,7 @@ static void __stdcall send_thread(void* ctx) { Status = finish_inode(context, ended1 ? NULL : &tp, ended2 ? NULL : &tp2); if (!NT_SUCCESS(Status)) { - ERR("finish_inode returned %08x\n", Status); + ERR("finish_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3188,14 +3189,14 @@ static void __stdcall send_thread(void* ctx) { Status = send_inode(context, &tp, NULL); if (!NT_SUCCESS(Status)) { - ERR("send_inode returned %08x\n", Status); + ERR("send_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else { Status = send_inode(context, &tp, &tp2); if (!NT_SUCCESS(Status)) { - ERR("send_inode returned %08x\n", Status); + ERR("send_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3203,35 +3204,35 @@ static void __stdcall send_thread(void* ctx) { } else if (tp.item->key.obj_type == TYPE_INODE_REF) { Status = send_inode_ref(context, &tp, false); if (!NT_SUCCESS(Status)) { - ERR("send_inode_ref returned %08x\n", Status); + ERR("send_inode_ref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } Status = send_inode_ref(context, &tp2, true); if (!NT_SUCCESS(Status)) { - ERR("send_inode_ref returned %08x\n", Status); + ERR("send_inode_ref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp.item->key.obj_type == TYPE_INODE_EXTREF) { Status = send_inode_extref(context, &tp, false); if (!NT_SUCCESS(Status)) { - ERR("send_inode_extref returned %08x\n", Status); + ERR("send_inode_extref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } Status = send_inode_extref(context, &tp2, true); if (!NT_SUCCESS(Status)) { - ERR("send_inode_extref returned %08x\n", Status); + ERR("send_inode_extref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp.item->key.obj_type == TYPE_EXTENT_DATA) { Status = send_extent_data(context, &tp, &tp2); if (!NT_SUCCESS(Status)) { - ERR("send_extent_data returned %08x\n", Status); + ERR("send_extent_data returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3243,7 +3244,7 @@ static void __stdcall send_thread(void* ctx) { } else if (tp.item->key.obj_type == TYPE_XATTR_ITEM) { Status = send_xattr(context, &tp, &tp2); if (!NT_SUCCESS(Status)) { - ERR("send_xattr returned %08x\n", Status); + ERR("send_xattr returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3273,7 +3274,7 @@ static void __stdcall send_thread(void* ctx) { if (context->lastinode.inode != 0 && tp.item->key.obj_id > context->lastinode.inode) { Status = finish_inode(context, ended1 ? NULL : &tp, ended2 ? NULL : &tp2); if (!NT_SUCCESS(Status)) { - ERR("finish_inode returned %08x\n", Status); + ERR("finish_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3287,28 +3288,28 @@ static void __stdcall send_thread(void* ctx) { if (tp.item->key.obj_type == TYPE_INODE_ITEM) { Status = send_inode(context, &tp, NULL); if (!NT_SUCCESS(Status)) { - ERR("send_inode returned %08x\n", Status); + ERR("send_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp.item->key.obj_type == TYPE_INODE_REF) { Status = send_inode_ref(context, &tp, false); if (!NT_SUCCESS(Status)) { - ERR("send_inode_ref returned %08x\n", Status); + ERR("send_inode_ref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp.item->key.obj_type == TYPE_INODE_EXTREF) { Status = send_inode_extref(context, &tp, false); if (!NT_SUCCESS(Status)) { - ERR("send_inode_extref returned %08x\n", Status); + ERR("send_inode_extref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp.item->key.obj_type == TYPE_EXTENT_DATA) { Status = send_extent_data(context, &tp, NULL); if (!NT_SUCCESS(Status)) { - ERR("send_extent_data returned %08x\n", Status); + ERR("send_extent_data returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3320,7 +3321,7 @@ static void __stdcall send_thread(void* ctx) { } else if (tp.item->key.obj_type == TYPE_XATTR_ITEM) { Status = send_xattr(context, &tp, NULL); if (!NT_SUCCESS(Status)) { - ERR("send_xattr returned %08x\n", Status); + ERR("send_xattr returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3341,7 +3342,7 @@ static void __stdcall send_thread(void* ctx) { if (context->lastinode.inode != 0 && tp2.item->key.obj_id > context->lastinode.inode) { Status = finish_inode(context, ended1 ? NULL : &tp, ended2 ? NULL : &tp2); if (!NT_SUCCESS(Status)) { - ERR("finish_inode returned %08x\n", Status); + ERR("finish_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3355,28 +3356,28 @@ static void __stdcall send_thread(void* ctx) { if (tp2.item->key.obj_type == TYPE_INODE_ITEM) { Status = send_inode(context, NULL, &tp2); if (!NT_SUCCESS(Status)) { - ERR("send_inode returned %08x\n", Status); + ERR("send_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp2.item->key.obj_type == TYPE_INODE_REF) { Status = send_inode_ref(context, &tp2, true); if (!NT_SUCCESS(Status)) { - ERR("send_inode_ref returned %08x\n", Status); + ERR("send_inode_ref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp2.item->key.obj_type == TYPE_INODE_EXTREF) { Status = send_inode_extref(context, &tp2, true); if (!NT_SUCCESS(Status)) { - ERR("send_inode_extref returned %08x\n", Status); + ERR("send_inode_extref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp2.item->key.obj_type == TYPE_EXTENT_DATA && !context->lastinode.deleting) { Status = send_extent_data(context, NULL, &tp2); if (!NT_SUCCESS(Status)) { - ERR("send_extent_data returned %08x\n", Status); + ERR("send_extent_data returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3388,7 +3389,7 @@ static void __stdcall send_thread(void* ctx) { } else if (tp2.item->key.obj_type == TYPE_XATTR_ITEM && !context->lastinode.deleting) { Status = send_xattr(context, NULL, &tp2); if (!NT_SUCCESS(Status)) { - ERR("send_xattr returned %08x\n", Status); + ERR("send_xattr returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3425,7 +3426,7 @@ static void __stdcall send_thread(void* ctx) { Status = find_item(context->Vcb, context->root, &tp, &key, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3441,7 +3442,7 @@ static void __stdcall send_thread(void* ctx) { if (context->lastinode.inode != 0 && tp.item->key.obj_id > context->lastinode.inode) { Status = finish_inode(context, &tp, NULL); if (!NT_SUCCESS(Status)) { - ERR("finish_inode returned %08x\n", Status); + ERR("finish_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3455,28 +3456,28 @@ static void __stdcall send_thread(void* ctx) { if (tp.item->key.obj_type == TYPE_INODE_ITEM) { Status = send_inode(context, &tp, NULL); if (!NT_SUCCESS(Status)) { - ERR("send_inode returned %08x\n", Status); + ERR("send_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp.item->key.obj_type == TYPE_INODE_REF) { Status = send_inode_ref(context, &tp, false); if (!NT_SUCCESS(Status)) { - ERR("send_inode_ref returned %08x\n", Status); + ERR("send_inode_ref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp.item->key.obj_type == TYPE_INODE_EXTREF) { Status = send_inode_extref(context, &tp, false); if (!NT_SUCCESS(Status)) { - ERR("send_inode_extref returned %08x\n", Status); + ERR("send_inode_extref returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } } else if (tp.item->key.obj_type == TYPE_EXTENT_DATA) { Status = send_extent_data(context, &tp, NULL); if (!NT_SUCCESS(Status)) { - ERR("send_extent_data returned %08x\n", Status); + ERR("send_extent_data returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3488,7 +3489,7 @@ static void __stdcall send_thread(void* ctx) { } else if (tp.item->key.obj_type == TYPE_XATTR_ITEM) { Status = send_xattr(context, &tp, NULL); if (!NT_SUCCESS(Status)) { - ERR("send_xattr returned %08x\n", Status); + ERR("send_xattr returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3509,7 +3510,7 @@ static void __stdcall send_thread(void* ctx) { if (context->lastinode.inode != 0) { Status = finish_inode(context, NULL, NULL); if (!NT_SUCCESS(Status)) { - ERR("finish_inode returned %08x\n", Status); + ERR("finish_inode returned %08lx\n", Status); ExReleaseResourceLite(&context->Vcb->tree_lock); goto end; } @@ -3655,7 +3656,7 @@ NTSTATUS send_subvol(device_extension* Vcb, void* data, ULONG datalen, PFILE_OBJ Status = ObReferenceObjectByHandle(parent, 0, *IoFileObjectType, Irp->RequestorMode, (void**)&fileobj, NULL); if (!NT_SUCCESS(Status)) { - ERR("ObReferenceObjectByHandle returned %08x\n", Status); + ERR("ObReferenceObjectByHandle returned %08lx\n", Status); return Status; } @@ -3706,7 +3707,7 @@ NTSTATUS send_subvol(device_extension* Vcb, void* data, ULONG datalen, PFILE_OBJ Status = ObReferenceObjectByHandle(h, 0, *IoFileObjectType, Irp->RequestorMode, (void**)&fileobj, NULL); if (!NT_SUCCESS(Status)) { - ERR("ObReferenceObjectByHandle returned %08x\n", Status); + ERR("ObReferenceObjectByHandle returned %08lx\n", Status); ExFreePool(clones); return Status; } @@ -3815,7 +3816,7 @@ NTSTATUS send_subvol(device_extension* Vcb, void* data, ULONG datalen, PFILE_OBJ Status = PsCreateSystemThread(&send->thread, 0, &oa, NULL, NULL, send_thread, context); if (!NT_SUCCESS(Status)) { - ERR("PsCreateSystemThread returned %08x\n", Status); + ERR("PsCreateSystemThread returned %08lx\n", Status); ccb->send = NULL; InterlockedDecrement(&Vcb->running_sends); ExFreePool(send); diff --git a/drivers/filesystems/btrfs/sha256.c b/drivers/filesystems/btrfs/sha256.c new file mode 100644 index 00000000000..a9ee8c1b93f --- /dev/null +++ b/drivers/filesystems/btrfs/sha256.c @@ -0,0 +1,221 @@ +#include +#include + +// Public domain code from https://github.com/amosnier/sha-2 + +// FIXME - x86 SHA extensions + +#define CHUNK_SIZE 64 +#define TOTAL_LEN_LEN 8 + +/* + * ABOUT bool: this file does not use bool in order to be as pre-C99 compatible as possible. + */ + +/* + * Comments from pseudo-code at https://en.wikipedia.org/wiki/SHA-2 are reproduced here. + * When useful for clarification, portions of the pseudo-code are reproduced here too. + */ + +/* + * Initialize array of round constants: + * (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311): + */ +static const uint32_t k[] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +struct buffer_state { + const uint8_t * p; + size_t len; + size_t total_len; + int single_one_delivered; /* bool */ + int total_len_delivered; /* bool */ +}; + +static inline uint32_t right_rot(uint32_t value, unsigned int count) +{ + /* + * Defined behaviour in standard C for all count where 0 < count < 32, + * which is what we need here. + */ + return value >> count | value << (32 - count); +} + +static void init_buf_state(struct buffer_state * state, const void * input, size_t len) +{ + state->p = input; + state->len = len; + state->total_len = len; + state->single_one_delivered = 0; + state->total_len_delivered = 0; +} + +/* Return value: bool */ +static int calc_chunk(uint8_t chunk[CHUNK_SIZE], struct buffer_state * state) +{ + size_t space_in_chunk; + + if (state->total_len_delivered) { + return 0; + } + + if (state->len >= CHUNK_SIZE) { + memcpy(chunk, state->p, CHUNK_SIZE); + state->p += CHUNK_SIZE; + state->len -= CHUNK_SIZE; + return 1; + } + + memcpy(chunk, state->p, state->len); + chunk += state->len; + space_in_chunk = CHUNK_SIZE - state->len; + state->p += state->len; + state->len = 0; + + /* If we are here, space_in_chunk is one at minimum. */ + if (!state->single_one_delivered) { + *chunk++ = 0x80; + space_in_chunk -= 1; + state->single_one_delivered = 1; + } + + /* + * Now: + * - either there is enough space left for the total length, and we can conclude, + * - or there is too little space left, and we have to pad the rest of this chunk with zeroes. + * In the latter case, we will conclude at the next invokation of this function. + */ + if (space_in_chunk >= TOTAL_LEN_LEN) { + const size_t left = space_in_chunk - TOTAL_LEN_LEN; + size_t len = state->total_len; + int i; + memset(chunk, 0x00, left); + chunk += left; + + /* Storing of len * 8 as a big endian 64-bit without overflow. */ + chunk[7] = (uint8_t) (len << 3); + len >>= 5; + for (i = 6; i >= 0; i--) { + chunk[i] = (uint8_t) len; + len >>= 8; + } + state->total_len_delivered = 1; + } else { + memset(chunk, 0x00, space_in_chunk); + } + + return 1; +} + +/* + * Limitations: + * - Since input is a pointer in RAM, the data to hash should be in RAM, which could be a problem + * for large data sizes. + * - SHA algorithms theoretically operate on bit strings. However, this implementation has no support + * for bit string lengths that are not multiples of eight, and it really operates on arrays of bytes. + * In particular, the len parameter is a number of bytes. + */ +void calc_sha256(uint8_t* hash, const void* input, size_t len) +{ + /* + * Note 1: All integers (expect indexes) are 32-bit unsigned integers and addition is calculated modulo 2^32. + * Note 2: For each round, there is one round constant k[i] and one entry in the message schedule array w[i], 0 = i = 63 + * Note 3: The compression function uses 8 working variables, a through h + * Note 4: Big-endian convention is used when expressing the constants in this pseudocode, + * and when parsing message block data from bytes to words, for example, + * the first word of the input message "abc" after padding is 0x61626380 + */ + + /* + * Initialize hash values: + * (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19): + */ + uint32_t h[] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; + unsigned i, j; + + /* 512-bit chunks is what we will operate on. */ + uint8_t chunk[64]; + + struct buffer_state state; + + init_buf_state(&state, input, len); + + while (calc_chunk(chunk, &state)) { + uint32_t ah[8]; + + const uint8_t *p = chunk; + + /* Initialize working variables to current hash value: */ + for (i = 0; i < 8; i++) + ah[i] = h[i]; + + /* Compression function main loop: */ + for (i = 0; i < 4; i++) { + /* + * The w-array is really w[64], but since we only need + * 16 of them at a time, we save stack by calculating + * 16 at a time. + * + * This optimization was not there initially and the + * rest of the comments about w[64] are kept in their + * initial state. + */ + + /* + * create a 64-entry message schedule array w[0..63] of 32-bit words + * (The initial values in w[0..63] don't matter, so many implementations zero them here) + * copy chunk into first 16 words w[0..15] of the message schedule array + */ + uint32_t w[16]; + + for (j = 0; j < 16; j++) { + if (i == 0) { + w[j] = (uint32_t) p[0] << 24 | (uint32_t) p[1] << 16 | + (uint32_t) p[2] << 8 | (uint32_t) p[3]; + p += 4; + } else { + /* Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array: */ + const uint32_t s0 = right_rot(w[(j + 1) & 0xf], 7) ^ right_rot(w[(j + 1) & 0xf], 18) ^ (w[(j + 1) & 0xf] >> 3); + const uint32_t s1 = right_rot(w[(j + 14) & 0xf], 17) ^ right_rot(w[(j + 14) & 0xf], 19) ^ (w[(j + 14) & 0xf] >> 10); + w[j] = w[j] + s0 + w[(j + 9) & 0xf] + s1; + } + const uint32_t s1 = right_rot(ah[4], 6) ^ right_rot(ah[4], 11) ^ right_rot(ah[4], 25); + const uint32_t ch = (ah[4] & ah[5]) ^ (~ah[4] & ah[6]); + const uint32_t temp1 = ah[7] + s1 + ch + k[i << 4 | j] + w[j]; + const uint32_t s0 = right_rot(ah[0], 2) ^ right_rot(ah[0], 13) ^ right_rot(ah[0], 22); + const uint32_t maj = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]); + const uint32_t temp2 = s0 + maj; + + ah[7] = ah[6]; + ah[6] = ah[5]; + ah[5] = ah[4]; + ah[4] = ah[3] + temp1; + ah[3] = ah[2]; + ah[2] = ah[1]; + ah[1] = ah[0]; + ah[0] = temp1 + temp2; + } + } + + /* Add the compressed chunk to the current hash value: */ + for (i = 0; i < 8; i++) + h[i] += ah[i]; + } + + /* Produce the final hash value (big-endian): */ + for (i = 0, j = 0; i < 8; i++) + { + hash[j++] = (uint8_t) (h[i] >> 24); + hash[j++] = (uint8_t) (h[i] >> 16); + hash[j++] = (uint8_t) (h[i] >> 8); + hash[j++] = (uint8_t) h[i]; + } +} diff --git a/drivers/filesystems/btrfs/treefuncs.c b/drivers/filesystems/btrfs/treefuncs.c index 100553b942b..c05f7035d45 100644 --- a/drivers/filesystems/btrfs/treefuncs.c +++ b/drivers/filesystems/btrfs/treefuncs.c @@ -16,6 +16,7 @@ * along with WinBtrfs. If not, see . */ #include "btrfs_drv.h" +#include "crc32c.h" NTSTATUS load_tree(device_extension* Vcb, uint64_t addr, uint8_t* buf, root* r, tree** pt) { tree_header* th; @@ -66,7 +67,7 @@ NTSTATUS load_tree(device_extension* Vcb, uint64_t addr, uint8_t* buf, root* r, unsigned int i; if ((t->header.num_items * sizeof(leaf_node)) + sizeof(tree_header) > Vcb->superblock.node_size) { - ERR("tree at %I64x has more items than expected (%x)\n", t->header.num_items); + ERR("tree at %I64x has more items than expected (%x)\n", addr, t->header.num_items); ExFreePool(t); return STATUS_INSUFFICIENT_RESOURCES; } @@ -87,7 +88,7 @@ NTSTATUS load_tree(device_extension* Vcb, uint64_t addr, uint8_t* buf, root* r, td->data = NULL; if (ln[i].size + sizeof(tree_header) + sizeof(leaf_node) > Vcb->superblock.node_size) { - ERR("overlarge item in tree %I64x: %u > %u\n", addr, ln[i].size, Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node)); + ERR("overlarge item in tree %I64x: %u > %Iu\n", addr, ln[i].size, Vcb->superblock.node_size - sizeof(tree_header) - sizeof(leaf_node)); ExFreeToPagedLookasideList(&t->Vcb->tree_data_lookaside, td); ExFreePool(t); return STATUS_INTERNAL_ERROR; @@ -109,7 +110,7 @@ NTSTATUS load_tree(device_extension* Vcb, uint64_t addr, uint8_t* buf, root* r, unsigned int i; if ((t->header.num_items * sizeof(internal_node)) + sizeof(tree_header) > Vcb->superblock.node_size) { - ERR("tree at %I64x has more items than expected (%x)\n", t->header.num_items); + ERR("tree at %I64x has more items than expected (%x)\n", addr, t->header.num_items); ExFreePool(t); return STATUS_INSUFFICIENT_RESOURCES; } @@ -197,7 +198,7 @@ static NTSTATUS do_load_tree2(device_extension* Vcb, tree_holder* th, uint8_t* b Status = load_tree(Vcb, th->address, buf, r, &nt); if (!NT_SUCCESS(Status)) { - ERR("load_tree returned %08x\n", Status); + ERR("load_tree returned %08lx\n", Status); return Status; } @@ -229,7 +230,7 @@ NTSTATUS do_load_tree(device_extension* Vcb, tree_holder* th, root* r, tree* t, Status = read_data(Vcb, th->address, Vcb->superblock.node_size, NULL, true, buf, NULL, &c, Irp, th->generation, false, NormalPagePriority); if (!NT_SUCCESS(Status)) { - ERR("read_data returned 0x%08x\n", Status); + ERR("read_data returned 0x%08lx\n", Status); ExFreePool(buf); return Status; } @@ -250,7 +251,7 @@ NTSTATUS do_load_tree(device_extension* Vcb, tree_holder* th, root* r, tree* t, ExFreePool(buf); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree2 returned %08x\n", Status); + ERR("do_load_tree2 returned %08lx\n", Status); return Status; } @@ -387,7 +388,7 @@ NTSTATUS skip_to_difference(device_extension* Vcb, traverse_ptr* tp, traverse_pt if (Status == STATUS_NOT_FOUND) *ended1 = true; else if (!NT_SUCCESS(Status)) { - ERR("next_item2 returned %08x\n", Status); + ERR("next_item2 returned %08lx\n", Status); return Status; } @@ -395,7 +396,7 @@ NTSTATUS skip_to_difference(device_extension* Vcb, traverse_ptr* tp, traverse_pt if (Status == STATUS_NOT_FOUND) *ended2 = true; else if (!NT_SUCCESS(Status)) { - ERR("next_item2 returned %08x\n", Status); + ERR("next_item2 returned %08lx\n", Status); return Status; } @@ -403,13 +404,13 @@ NTSTATUS skip_to_difference(device_extension* Vcb, traverse_ptr* tp, traverse_pt if (!*ended1) { Status = find_item(Vcb, t1->root, tp, &tp3.item->key, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } } else if (!*ended2) { Status = find_item(Vcb, t2->root, tp2, &tp4.item->key, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } } @@ -420,13 +421,13 @@ NTSTATUS skip_to_difference(device_extension* Vcb, traverse_ptr* tp, traverse_pt if (tp3.tree->header.address != tp4.tree->header.address) { Status = find_item(Vcb, t1->root, tp, &tp3.item->key, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } Status = find_item(Vcb, t2->root, tp2, &tp4.item->key, false, NULL); if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -534,7 +535,7 @@ static NTSTATUS find_item_in_tree(device_extension* Vcb, tree* t, traverse_ptr* if (!td->treeholder.tree) { Status = do_load_tree(Vcb, &td->treeholder, t->root, t, td, Irp); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return Status; } } @@ -552,14 +553,14 @@ NTSTATUS find_item(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension if (!r->treeholder.tree) { Status = do_load_tree(Vcb, &r->treeholder, r, NULL, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return Status; } } Status = find_item_in_tree(Vcb, r->treeholder.tree, tp, searchkey, ignore, 0, Irp); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) { - ERR("find_item_in_tree returned %08x\n", Status); + ERR("find_item_in_tree returned %08lx\n", Status); } return Status; @@ -571,14 +572,14 @@ NTSTATUS find_item_to_level(device_extension* Vcb, root* r, traverse_ptr* tp, co if (!r->treeholder.tree) { Status = do_load_tree(Vcb, &r->treeholder, r, NULL, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return Status; } } Status = find_item_in_tree(Vcb, r->treeholder.tree, tp, searchkey, ignore, level, Irp); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND) { - ERR("find_item_in_tree returned %08x\n", Status); + ERR("find_item_in_tree returned %08lx\n", Status); } if (Status == STATUS_NOT_FOUND) { @@ -635,7 +636,7 @@ bool find_next_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vc if (!td->treeholder.tree) { Status = do_load_tree(Vcb, &td->treeholder, t->parent->root, t->parent, td, Irp); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return false; } } @@ -650,7 +651,7 @@ bool find_next_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vc if (!fi->treeholder.tree) { Status = do_load_tree(Vcb, &fi->treeholder, t->parent->root, t, fi, Irp); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return false; } } @@ -724,7 +725,7 @@ bool find_prev_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vc if (!td->treeholder.tree) { Status = do_load_tree(Vcb, &td->treeholder, t->parent->root, t->parent, td, Irp); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return false; } } @@ -739,7 +740,7 @@ bool find_prev_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vc if (!li->treeholder.tree) { Status = do_load_tree(Vcb, &li->treeholder, t->parent->root, t, li, Irp); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return false; } } @@ -814,7 +815,7 @@ void free_trees(device_extension* Vcb) { r->treeholder.tree = NULL; if (IsListEmpty(&Vcb->trees)) - return; + break; } else if (t->header.level > level) empty = false; @@ -880,7 +881,7 @@ NTSTATUS insert_tree_item(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) if (!r->treeholder.tree) { Status = do_load_tree(Vcb, &r->treeholder, r, NULL, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("do_load_tree returned %08x\n", Status); + ERR("do_load_tree returned %08lx\n", Status); return Status; } } @@ -893,11 +894,11 @@ NTSTATUS insert_tree_item(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) return STATUS_INTERNAL_ERROR; } } else { - ERR("error: find_item returned %08x\n", Status); + ERR("error: find_item returned %08lx\n", Status); return Status; } } else if (!NT_SUCCESS(Status)) { - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -1073,7 +1074,7 @@ void do_rollback(device_extension* Vcb, LIST_ENTRY* rollback) { re->fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, NULL); if (!NT_SUCCESS(Status)) - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); } re->fcb->inode_item.st_blocks -= ed2->num_bytes; @@ -1102,7 +1103,7 @@ void do_rollback(device_extension* Vcb, LIST_ENTRY* rollback) { re->fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, NULL); if (!NT_SUCCESS(Status)) - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); } re->fcb->inode_item.st_blocks += ed2->num_bytes; @@ -1273,7 +1274,7 @@ static NTSTATUS handle_batch_collision(device_extension* Vcb, batch_item* bi, tr switch (bi->operation) { case Batch_SetXattr: { if (td->size < sizeof(DIR_ITEM)) { - ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %u\n", bi->key.obj_id, bi->key.obj_type, bi->key.offset, td->size, sizeof(DIR_ITEM)); + ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", bi->key.obj_id, bi->key.obj_type, bi->key.offset, td->size, sizeof(DIR_ITEM)); } else { uint8_t* newdata; ULONG size = td->size; @@ -1296,7 +1297,7 @@ static NTSTATUS handle_batch_collision(device_extension* Vcb, batch_item* bi, tr // replace if (td->size + bi->datalen - oldxasize > maxlen) - ERR("DIR_ITEM would be over maximum size, truncating (%u + %u - %u > %u)\n", td->size, bi->datalen, oldxasize, maxlen); + ERR("DIR_ITEM would be over maximum size, truncating (%u + %u - %lu > %u)\n", td->size, bi->datalen, oldxasize, maxlen); newdata = ExAllocatePoolWithTag(PagedPool, td->size + bi->datalen - oldxasize, ALLOC_TAG); if (!newdata) { @@ -1492,7 +1493,7 @@ static NTSTATUS handle_batch_collision(device_extension* Vcb, batch_item* bi, tr case Batch_DeleteDirItem: { if (td->size < sizeof(DIR_ITEM)) { - ERR("DIR_ITEM was %u bytes, expected at least %u\n", td->size, sizeof(DIR_ITEM)); + ERR("DIR_ITEM was %u bytes, expected at least %Iu\n", td->size, sizeof(DIR_ITEM)); return STATUS_INTERNAL_ERROR; } else { DIR_ITEM *di, *deldi; @@ -1567,7 +1568,7 @@ static NTSTATUS handle_batch_collision(device_extension* Vcb, batch_item* bi, tr case Batch_DeleteInodeRef: { if (td->size < sizeof(INODE_REF)) { - ERR("INODE_REF was %u bytes, expected at least %u\n", td->size, sizeof(INODE_REF)); + ERR("INODE_REF was %u bytes, expected at least %Iu\n", td->size, sizeof(INODE_REF)); return STATUS_INTERNAL_ERROR; } else { INODE_REF *ir, *delir; @@ -1664,7 +1665,7 @@ static NTSTATUS handle_batch_collision(device_extension* Vcb, batch_item* bi, tr case Batch_DeleteInodeExtRef: { if (td->size < sizeof(INODE_EXTREF)) { - ERR("INODE_EXTREF was %u bytes, expected at least %u\n", td->size, sizeof(INODE_EXTREF)); + ERR("INODE_EXTREF was %u bytes, expected at least %Iu\n", td->size, sizeof(INODE_EXTREF)); return STATUS_INTERNAL_ERROR; } else { INODE_EXTREF *ier, *delier; @@ -1745,7 +1746,7 @@ static NTSTATUS handle_batch_collision(device_extension* Vcb, batch_item* bi, tr case Batch_DeleteXattr: { if (td->size < sizeof(DIR_ITEM)) { - ERR("XATTR_ITEM was %u bytes, expected at least %u\n", td->size, sizeof(DIR_ITEM)); + ERR("XATTR_ITEM was %u bytes, expected at least %Iu\n", td->size, sizeof(DIR_ITEM)); return STATUS_INTERNAL_ERROR; } else { DIR_ITEM *di, *deldi; @@ -1870,7 +1871,7 @@ static NTSTATUS commit_batch_list_root(_Requires_exclusive_lock_held_(_Curr_->tr Status = find_item(Vcb, br->r, &tp, &bi->key, true, Irp); if (!NT_SUCCESS(Status)) { // FIXME - handle STATUS_NOT_FOUND - ERR("find_item returned %08x\n", Status); + ERR("find_item returned %08lx\n", Status); return Status; } @@ -2116,7 +2117,7 @@ static NTSTATUS commit_batch_list_root(_Requires_exclusive_lock_held_(_Curr_->tr } else { Status = handle_batch_collision(Vcb, bi, tp.tree, tp.item, td, &br->items, &ignore); if (!NT_SUCCESS(Status)) { - ERR("handle_batch_collision returned %08x\n", Status); + ERR("handle_batch_collision returned %08lx\n", Status); if (td) ExFreeToPagedLookasideList(&Vcb->tree_data_lookaside, td); @@ -2197,7 +2198,7 @@ static NTSTATUS commit_batch_list_root(_Requires_exclusive_lock_held_(_Curr_->tr } else { Status = handle_batch_collision(Vcb, bi2, tp.tree, td2, td, &br->items, &ignore); if (!NT_SUCCESS(Status)) { - ERR("handle_batch_collision returned %08x\n", Status); + ERR("handle_batch_collision returned %08lx\n", Status); return Status; } } @@ -2286,7 +2287,7 @@ NTSTATUS commit_batch_list(_Requires_exclusive_lock_held_(_Curr_->tree_lock) dev Status = commit_batch_list_root(Vcb, br2, Irp); if (!NT_SUCCESS(Status)) { - ERR("commit_batch_list_root returned %08x\n", Status); + ERR("commit_batch_list_root returned %08lx\n", Status); return Status; } diff --git a/drivers/filesystems/btrfs/volume.c b/drivers/filesystems/btrfs/volume.c index 0718bb8d9de..d78d33712cc 100644 --- a/drivers/filesystems/btrfs/volume.c +++ b/drivers/filesystems/btrfs/volume.c @@ -487,7 +487,7 @@ static NTSTATUS vol_get_disk_extents(volume_device_extension* vde, PIRP Irp) { Status = dev_ioctl(vc->devobj, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &ext2, sizeof(VOLUME_DISK_EXTENTS), false, NULL); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { - ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08x\n", Status); + ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08lx\n", Status); goto end; } @@ -525,7 +525,7 @@ static NTSTATUS vol_get_disk_extents(volume_device_extension* vde, PIRP Irp) { Status = dev_ioctl(vc->devobj, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, ext3, (ULONG)offsetof(VOLUME_DISK_EXTENTS, Extents[0]) + (max_extents * sizeof(DISK_EXTENT)), false, NULL); if (!NT_SUCCESS(Status)) { - ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08x\n", Status); + ERR("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS returned %08lx\n", Status); ExFreePool(ext3); goto end; } @@ -876,8 +876,21 @@ NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: return vol_get_disk_extents(vde, Irp); - default: // pass ioctl through if only one child device - return vol_ioctl_passthrough(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 + + 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); + + return Status; + } } return STATUS_INVALID_DEVICE_REQUEST; @@ -917,12 +930,12 @@ NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devp mmdlt->DeviceNameLength = devpath->Length; RtlCopyMemory(&mmdlt->DeviceName, devpath->Buffer, devpath->Length); - TRACE("mmdlt = %.*S\n", mmdlt->DeviceNameLength / sizeof(WCHAR), mmdlt->DeviceName); + TRACE("mmdlt = %.*S\n", (int)(mmdlt->DeviceNameLength / sizeof(WCHAR)), mmdlt->DeviceName); Status = dev_ioctl(mountmgr, IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER, mmdlt, mmdltsize, &mmdli, sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION), false, NULL); if (!NT_SUCCESS(Status)) - ERR("IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER returned %08x\n", Status); + ERR("IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER returned %08lx\n", Status); else TRACE("DriveLetterWasAssigned = %u, CurrentDriveLetter = %c\n", mmdli.DriveLetterWasAssigned, mmdli.CurrentDriveLetter); @@ -995,7 +1008,7 @@ static bool allow_degraded_mount(BTRFS_UUID* uuid) { if (Status == STATUS_OBJECT_NAME_NOT_FOUND) goto end; else if (!NT_SUCCESS(Status)) { - ERR("ZwOpenKey returned %08x\n", Status); + ERR("ZwOpenKey returned %08lx\n", Status); goto end; } @@ -1095,7 +1108,7 @@ static void drive_letter_callback2(pdo_device_extension* pdode, PDEVICE_OBJECT m dlr->Status = remove_drive_letter(mountmgr, &dlr->name); if (!NT_SUCCESS(dlr->Status) && dlr->Status != STATUS_NOT_FOUND) - WARN("remove_drive_letter returned %08x\n", dlr->Status); + WARN("remove_drive_letter returned %08lx\n", dlr->Status); le = le->Flink; } @@ -1137,7 +1150,7 @@ static void __stdcall drive_letter_callback(pdo_device_extension* pdode) { RtlInitUnicodeString(&mmdevpath, MOUNTMGR_DEVICE_NAME); Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr); if (!NT_SUCCESS(Status)) { - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); return; } @@ -1177,7 +1190,7 @@ void add_volume_device(superblock* sb, PUNICODE_STRING devpath, uint64_t length, Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if (!NT_SUCCESS(Status)) { - ERR("IoGetDeviceObjectPointer returned %08x\n", Status); + ERR("IoGetDeviceObjectPointer returned %08lx\n", Status); ExReleaseResourceLite(&pdo_list_lock); return; } @@ -1187,7 +1200,7 @@ void add_volume_device(superblock* sb, PUNICODE_STRING devpath, uint64_t length, Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo); if (!NT_SUCCESS(Status)) { - ERR("IoReportDetectedDevice returned %08x\n", Status); + ERR("IoReportDetectedDevice returned %08lx\n", Status); ExReleaseResourceLite(&pdo_list_lock); return; } @@ -1203,7 +1216,7 @@ void add_volume_device(superblock* sb, PUNICODE_STRING devpath, uint64_t length, Status = IoCreateDevice(drvobj, sizeof(pdo_device_extension), NULL, FILE_DEVICE_DISK, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, false, &pdo); if (!NT_SUCCESS(Status)) { - ERR("IoCreateDevice returned %08x\n", Status); + ERR("IoCreateDevice returned %08lx\n", Status); ExReleaseResourceLite(&pdo_list_lock); goto fail; } @@ -1263,11 +1276,12 @@ void add_volume_device(superblock* sb, PUNICODE_STRING devpath, uint64_t length, vc->devid = sb->dev_item.dev_id; vc->generation = sb->generation; vc->notification_entry = NULL; + vc->boot_volume = false; Status = IoRegisterPlugPlayNotification(EventCategoryTargetDeviceChange, 0, FileObject, drvobj, pnp_removal, pdode, &vc->notification_entry); if (!NT_SUCCESS(Status)) - WARN("IoRegisterPlugPlayNotification returned %08x\n", Status); + WARN("IoRegisterPlugPlayNotification returned %08lx\n", Status); vc->devobj = DeviceObject; vc->fileobj = FileObject; @@ -1354,7 +1368,7 @@ void add_volume_device(superblock* sb, PUNICODE_STRING devpath, uint64_t length, if ((!new_pdo || !no_pnp) && pdode->vde) { Status = IoSetDeviceInterfaceState(&pdode->vde->bus_name, true); if (!NT_SUCCESS(Status)) - WARN("IoSetDeviceInterfaceState returned %08x\n", Status); + WARN("IoSetDeviceInterfaceState returned %08lx\n", Status); } process_drive_letters = true; @@ -1371,7 +1385,9 @@ void add_volume_device(superblock* sb, PUNICODE_STRING devpath, uint64_t length, drive_letter_callback(pdode); if (new_pdo) { - if (no_pnp) + if (RtlCompareMemory(&sb->uuid, &boot_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) + boot_add_device(pdo); + else if (no_pnp) AddDevice(drvobj, pdo); else { bus_device_extension* bde = busobj->DeviceExtension; diff --git a/drivers/filesystems/btrfs/worker-thread.c b/drivers/filesystems/btrfs/worker-thread.c index 0fcf5868953..196a459d011 100644 --- a/drivers/filesystems/btrfs/worker-thread.c +++ b/drivers/filesystems/btrfs/worker-thread.c @@ -49,18 +49,18 @@ NTSTATUS do_read_job(PIRP Irp) { ExReleaseResourceLite(fcb->Header.Resource); if (!NT_SUCCESS(Status)) - ERR("do_read returned %08x\n", Status); + ERR("do_read returned %08lx\n", Status); Irp->IoStatus.Status = Status; - TRACE("read %lu bytes\n", Irp->IoStatus.Information); + TRACE("read %Iu bytes\n", Irp->IoStatus.Information); IoCompleteRequest(Irp, IO_NO_INCREMENT); if (top_level) IoSetTopLevelIrp(NULL); - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); return Status; } @@ -76,18 +76,18 @@ NTSTATUS do_write_job(device_extension* Vcb, PIRP Irp) { } _SEH2_END; if (!NT_SUCCESS(Status)) - ERR("write_file returned %08x\n", Status); + ERR("write_file returned %08lx\n", Status); Irp->IoStatus.Status = Status; - TRACE("wrote %u bytes\n", Irp->IoStatus.Information); + TRACE("wrote %Iu bytes\n", Irp->IoStatus.Information); IoCompleteRequest(Irp, IO_NO_INCREMENT); if (top_level) IoSetTopLevelIrp(NULL); - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); return Status; } @@ -147,7 +147,7 @@ bool add_thread_job(device_extension* Vcb, PIRP Irp) { _SEH2_TRY { MmProbeAndLockPages(Mdl, Irp->RequestorMode, op); } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { - ERR("MmProbeAndLockPages raised status %08x\n", _SEH2_GetExceptionCode()); + ERR("MmProbeAndLockPages raised status %08lx\n", _SEH2_GetExceptionCode()); IoFreeMdl(Mdl); Irp->MdlAddress = NULL; diff --git a/drivers/filesystems/btrfs/write.c b/drivers/filesystems/btrfs/write.c index 96ae287e02c..65b8c8d512c 100644 --- a/drivers/filesystems/btrfs/write.c +++ b/drivers/filesystems/btrfs/write.c @@ -48,7 +48,7 @@ bool find_data_address_in_chunk(device_extension* Vcb, chunk* c, uint64_t length NTSTATUS Status = load_cache_chunk(Vcb, c, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); return false; } } @@ -436,6 +436,18 @@ NTSTATUS alloc_chunk(device_extension* Vcb, uint64_t flags, chunk** pc, bool ful sub_stripes = 1; type = BLOCK_FLAG_RAID6; allowed_missing = 2; + } else if (flags & BLOCK_FLAG_RAID1C3) { + min_stripes = 3; + max_stripes = 3; + sub_stripes = 1; + type = BLOCK_FLAG_RAID1C3; + allowed_missing = 2; + } else if (flags & BLOCK_FLAG_RAID1C4) { + min_stripes = 4; + max_stripes = 4; + sub_stripes = 1; + type = BLOCK_FLAG_RAID1C4; + allowed_missing = 3; } else { // SINGLE min_stripes = 1; max_stripes = 1; @@ -449,6 +461,9 @@ NTSTATUS alloc_chunk(device_extension* Vcb, uint64_t flags, chunk** pc, bool ful max_stripe_size = max_chunk_size / min_stripes; } + if (max_stripe_size > total_size / (10 * min_stripes)) + max_stripe_size = total_size / (10 * min_stripes); + TRACE("would allocate a new chunk of %I64x bytes and stripe %I64x\n", max_chunk_size, max_stripe_size); stripes = ExAllocatePoolWithTag(PagedPool, sizeof(stripe) * max_stripes, ALLOC_TAG); @@ -464,8 +479,7 @@ NTSTATUS alloc_chunk(device_extension* Vcb, uint64_t flags, chunk** pc, bool ful if (!find_new_dup_stripes(Vcb, stripes, max_stripe_size, full_size)) { Status = STATUS_DISK_FULL; goto end; - } - else + } else num_stripes = max_stripes; } else { for (i = 0; i < max_stripes; i++) { @@ -532,7 +546,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) + 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) factor = num_stripes; @@ -749,7 +763,7 @@ static NTSTATUS prepare_raid0_write(_Pre_satisfies_(_Curr_->chunk_item->num_stri } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(master_mdl); return Status; } @@ -877,7 +891,7 @@ static NTSTATUS prepare_raid10_write(_Pre_satisfies_(_Curr_->chunk_item->sub_str } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(master_mdl); return Status; } @@ -983,7 +997,7 @@ static NTSTATUS add_partial_stripe(device_extension* Vcb, chunk *c, uint64_t add if (RtlAreBitsClear(&ps->bmp, 0, (ULONG)((num_data_stripes * c->chunk_item->stripe_length) / Vcb->superblock.sector_size))) { Status = flush_partial_stripe(Vcb, c, ps); if (!NT_SUCCESS(Status)) { - ERR("flush_partial_stripe returned %08x\n", Status); + ERR("flush_partial_stripe returned %08lx\n", Status); goto end; } @@ -1059,10 +1073,10 @@ static NTSTATUS prepare_raid5_write(device_extension* Vcb, chunk* c, uint64_t ad if ((address + length - c->offset) % (num_data_stripes * c->chunk_item->stripe_length) > 0) { uint64_t delta = (address + length - c->offset) % (num_data_stripes * c->chunk_item->stripe_length); - delta = min(irp_offset + length, delta); - Status = add_partial_stripe(Vcb, c, address + length - delta, (uint32_t)delta, (uint8_t*)data + irp_offset + length - delta); + delta = min(length, delta); + Status = add_partial_stripe(Vcb, c, address + length - delta, (uint32_t)delta, (uint8_t*)data + length - delta); if (!NT_SUCCESS(Status)) { - ERR("add_partial_stripe returned %08x\n", Status); + ERR("add_partial_stripe returned %08lx\n", Status); goto exit; } @@ -1072,15 +1086,16 @@ static NTSTATUS prepare_raid5_write(device_extension* Vcb, chunk* c, uint64_t ad if (length > 0 && (address - c->offset) % (num_data_stripes * c->chunk_item->stripe_length) > 0) { uint64_t delta = (num_data_stripes * c->chunk_item->stripe_length) - ((address - c->offset) % (num_data_stripes * c->chunk_item->stripe_length)); - Status = add_partial_stripe(Vcb, c, address, (uint32_t)delta, (uint8_t*)data + irp_offset); + Status = add_partial_stripe(Vcb, c, address, (uint32_t)delta, data); if (!NT_SUCCESS(Status)) { - ERR("add_partial_stripe returned %08x\n", Status); + ERR("add_partial_stripe returned %08lx\n", Status); goto exit; } address += delta; length -= (uint32_t)delta; irp_offset += delta; + data = (uint8_t*)data + delta; } if (length == 0) { @@ -1240,7 +1255,7 @@ static NTSTATUS prepare_raid5_write(device_extension* Vcb, chunk* c, uint64_t ad goto exit; } - RtlCopyMemory(wtc->scratch, (uint8_t*)data + irp_offset, length); + RtlCopyMemory(wtc->scratch, data, length); master_mdl = IoAllocateMdl(wtc->scratch, length, false, false, NULL); if (!master_mdl) { @@ -1253,7 +1268,7 @@ static NTSTATUS prepare_raid5_write(device_extension* Vcb, chunk* c, uint64_t ad wtc->mdl = master_mdl; } else { - master_mdl = IoAllocateMdl((uint8_t*)data + irp_offset, length, false, false, NULL); + master_mdl = IoAllocateMdl(data, length, false, false, NULL); if (!master_mdl) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -1269,7 +1284,7 @@ static NTSTATUS prepare_raid5_write(device_extension* Vcb, chunk* c, uint64_t ad } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(master_mdl); return Status; } @@ -1456,10 +1471,10 @@ static NTSTATUS prepare_raid6_write(device_extension* Vcb, chunk* c, uint64_t ad if ((address + length - c->offset) % (num_data_stripes * c->chunk_item->stripe_length) > 0) { uint64_t delta = (address + length - c->offset) % (num_data_stripes * c->chunk_item->stripe_length); - delta = min(irp_offset + length, delta); - Status = add_partial_stripe(Vcb, c, address + length - delta, (uint32_t)delta, (uint8_t*)data + irp_offset + length - delta); + delta = min(length, delta); + Status = add_partial_stripe(Vcb, c, address + length - delta, (uint32_t)delta, (uint8_t*)data + length - delta); if (!NT_SUCCESS(Status)) { - ERR("add_partial_stripe returned %08x\n", Status); + ERR("add_partial_stripe returned %08lx\n", Status); goto exit; } @@ -1469,15 +1484,16 @@ static NTSTATUS prepare_raid6_write(device_extension* Vcb, chunk* c, uint64_t ad if (length > 0 && (address - c->offset) % (num_data_stripes * c->chunk_item->stripe_length) > 0) { uint64_t delta = (num_data_stripes * c->chunk_item->stripe_length) - ((address - c->offset) % (num_data_stripes * c->chunk_item->stripe_length)); - Status = add_partial_stripe(Vcb, c, address, (uint32_t)delta, (uint8_t*)data + irp_offset); + Status = add_partial_stripe(Vcb, c, address, (uint32_t)delta, data); if (!NT_SUCCESS(Status)) { - ERR("add_partial_stripe returned %08x\n", Status); + ERR("add_partial_stripe returned %08lx\n", Status); goto exit; } address += delta; length -= (uint32_t)delta; irp_offset += delta; + data = (uint8_t*)data + delta; } if (length == 0) { @@ -1655,7 +1671,7 @@ static NTSTATUS prepare_raid6_write(device_extension* Vcb, chunk* c, uint64_t ad goto exit; } - RtlCopyMemory(wtc->scratch, (uint8_t*)data + irp_offset, length); + RtlCopyMemory(wtc->scratch, data, length); master_mdl = IoAllocateMdl(wtc->scratch, length, false, false, NULL); if (!master_mdl) { @@ -1668,7 +1684,7 @@ static NTSTATUS prepare_raid6_write(device_extension* Vcb, chunk* c, uint64_t ad wtc->mdl = master_mdl; } else { - master_mdl = IoAllocateMdl((uint8_t*)data + irp_offset, length, false, false, NULL); + master_mdl = IoAllocateMdl(data, length, false, false, NULL); if (!master_mdl) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -1684,7 +1700,7 @@ static NTSTATUS prepare_raid6_write(device_extension* Vcb, chunk* c, uint64_t ad } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(master_mdl); goto exit; } @@ -1910,7 +1926,7 @@ NTSTATUS write_data(_In_ device_extension* Vcb, _In_ uint64_t address, _In_reads if (c->chunk_item->type & BLOCK_FLAG_RAID0) { Status = prepare_raid0_write(c, address, data, length, stripes, file_write ? Irp : NULL, irp_offset, wtc); if (!NT_SUCCESS(Status)) { - ERR("prepare_raid0_write returned %08x\n", Status); + ERR("prepare_raid0_write returned %08lx\n", Status); goto prepare_failed; } @@ -1918,7 +1934,7 @@ NTSTATUS write_data(_In_ device_extension* Vcb, _In_ uint64_t address, _In_reads } else if (c->chunk_item->type & BLOCK_FLAG_RAID10) { Status = prepare_raid10_write(c, address, data, length, stripes, file_write ? Irp : NULL, irp_offset, wtc); if (!NT_SUCCESS(Status)) { - ERR("prepare_raid10_write returned %08x\n", Status); + ERR("prepare_raid10_write returned %08lx\n", Status); goto prepare_failed; } @@ -1926,7 +1942,7 @@ NTSTATUS write_data(_In_ device_extension* Vcb, _In_ uint64_t address, _In_reads } else if (c->chunk_item->type & BLOCK_FLAG_RAID5) { Status = prepare_raid5_write(Vcb, c, address, data, length, stripes, file_write ? Irp : NULL, irp_offset, priority, wtc); if (!NT_SUCCESS(Status)) { - ERR("prepare_raid5_write returned %08x\n", Status); + ERR("prepare_raid5_write returned %08lx\n", Status); goto prepare_failed; } @@ -1934,12 +1950,12 @@ NTSTATUS write_data(_In_ device_extension* Vcb, _In_ uint64_t address, _In_reads } else if (c->chunk_item->type & BLOCK_FLAG_RAID6) { Status = prepare_raid6_write(Vcb, c, address, data, length, stripes, file_write ? Irp : NULL, irp_offset, priority, wtc); if (!NT_SUCCESS(Status)) { - ERR("prepare_raid6_write returned %08x\n", Status); + ERR("prepare_raid6_write returned %08lx\n", Status); goto prepare_failed; } allowed_missing = 2; - } else { // write same data to every location - SINGLE, DUP, RAID1 + } else { // write same data to every location - SINGLE, DUP, RAID1, RAID1C3, RAID1C4 for (i = 0; i < c->chunk_item->num_stripes; i++) { stripes[i].start = address - c->offset; stripes[i].end = stripes[i].start + length; @@ -1978,7 +1994,7 @@ NTSTATUS write_data(_In_ device_extension* Vcb, _In_ uint64_t address, _In_reads } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); IoFreeMdl(stripes[i].mdl); stripes[i].mdl = NULL; goto prepare_failed; @@ -1997,7 +2013,7 @@ NTSTATUS write_data(_In_ device_extension* Vcb, _In_ uint64_t address, _In_reads } if (missing > allowed_missing) { - ERR("cannot write as %u missing devices (maximum %u)\n", missing, allowed_missing); + ERR("cannot write as %lu missing devices (maximum %lu)\n", missing, allowed_missing); Status = STATUS_DEVICE_NOT_READY; goto prepare_failed; } @@ -2194,7 +2210,7 @@ NTSTATUS write_data_complete(device_extension* Vcb, uint64_t address, void* data } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("write_data returned %08x\n", Status); + ERR("write_data returned %08lx\n", Status); if (c->chunk_item->type & BLOCK_FLAG_RAID5 || c->chunk_item->type & BLOCK_FLAG_RAID6) chunk_unlock_range(Vcb, c, lockaddr, locklen); @@ -2414,7 +2430,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui Status = update_changed_extent_ref(Vcb, c, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, -1, fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); goto end; } } @@ -2458,7 +2474,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui if (ext->csum) { if (ed->compression == BTRFS_COMPRESSION_NONE) { - newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ned2->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ned2->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!newext->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -2466,10 +2482,10 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui goto end; } - RtlCopyMemory(newext->csum, &ext->csum[(end_data - ext->offset) / Vcb->superblock.sector_size], - (ULONG)(ned2->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory(newext->csum, (uint8_t*)ext->csum + ((end_data - ext->offset) * Vcb->csum_size / Vcb->superblock.sector_size), + (ULONG)(ned2->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size)); } else { - newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2->size * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2->size * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!newext->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -2477,7 +2493,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui goto end; } - RtlCopyMemory(newext->csum, ext->csum, (ULONG)(ed2->size * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory(newext->csum, ext->csum, (ULONG)(ed2->size * Vcb->csum_size / Vcb->superblock.sector_size)); } } else newext->csum = NULL; @@ -2522,7 +2538,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui if (ext->csum) { if (ed->compression == BTRFS_COMPRESSION_NONE) { - newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ned2->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ned2->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!newext->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -2530,9 +2546,9 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui goto end; } - RtlCopyMemory(newext->csum, ext->csum, (ULONG)(ned2->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory(newext->csum, ext->csum, (ULONG)(ned2->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size)); } else { - newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2->size * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + newext->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2->size * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!newext->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -2540,7 +2556,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui goto end; } - RtlCopyMemory(newext->csum, ext->csum, (ULONG)(ed2->size * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory(newext->csum, ext->csum, (ULONG)(ed2->size * Vcb->csum_size / Vcb->superblock.sector_size)); } } else newext->csum = NULL; @@ -2566,7 +2582,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui Status = update_changed_extent_ref(Vcb, c, ed2->address, ed2->size, fcb->subvol->id, fcb->inode, ext->offset - ed2->offset, 1, fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); goto end; } } @@ -2627,7 +2643,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui if (ext->csum) { if (ed->compression == BTRFS_COMPRESSION_NONE) { - newext1->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(neda2->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + newext1->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(neda2->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!newext1->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -2636,7 +2652,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui goto end; } - newext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(nedb2->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + newext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(nedb2->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!newext2->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -2646,11 +2662,11 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui goto end; } - RtlCopyMemory(newext1->csum, ext->csum, (ULONG)(neda2->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size)); - RtlCopyMemory(newext2->csum, &ext->csum[(end_data - ext->offset) / Vcb->superblock.sector_size], - (ULONG)(nedb2->num_bytes * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory(newext1->csum, ext->csum, (ULONG)(neda2->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size)); + RtlCopyMemory(newext2->csum, (uint8_t*)ext->csum + ((end_data - ext->offset) * Vcb->csum_size / Vcb->superblock.sector_size), + (ULONG)(nedb2->num_bytes * Vcb->csum_size / Vcb->superblock.sector_size)); } else { - newext1->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2->size * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + newext1->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2->size * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!newext1->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -2659,7 +2675,7 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui goto end; } - newext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2->size * sizeof(uint32_t) / Vcb->superblock.sector_size), ALLOC_TAG); + newext2->csum = ExAllocatePoolWithTag(PagedPool, (ULONG)(ed2->size * Vcb->csum_size / Vcb->superblock.sector_size), ALLOC_TAG); if (!newext2->csum) { ERR("out of memory\n"); Status = STATUS_INSUFFICIENT_RESOURCES; @@ -2669,8 +2685,8 @@ NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, ui goto end; } - RtlCopyMemory(newext1->csum, ext->csum, (ULONG)(ed2->size * sizeof(uint32_t) / Vcb->superblock.sector_size)); - RtlCopyMemory(newext2->csum, ext->csum, (ULONG)(ed2->size * sizeof(uint32_t) / Vcb->superblock.sector_size)); + RtlCopyMemory(newext1->csum, ext->csum, (ULONG)(ed2->size * Vcb->csum_size / Vcb->superblock.sector_size)); + RtlCopyMemory(newext2->csum, ext->csum, (ULONG)(ed2->size * Vcb->csum_size / Vcb->superblock.sector_size)); } } else { newext1->csum = NULL; @@ -2718,7 +2734,7 @@ void add_insert_extent_rollback(LIST_ENTRY* rollback, fcb* fcb, extent* ext) { #pragma warning(suppress: 28194) #endif NTSTATUS add_extent_to_fcb(_In_ fcb* fcb, _In_ uint64_t offset, _In_reads_bytes_(edsize) EXTENT_DATA* ed, _In_ uint16_t edsize, - _In_ bool unique, _In_opt_ _When_(return >= 0, __drv_aliasesMem) uint32_t* csum, _In_ LIST_ENTRY* rollback) { + _In_ bool unique, _In_opt_ _When_(return >= 0, __drv_aliasesMem) void* csum, _In_ LIST_ENTRY* rollback) { extent* ext; LIST_ENTRY* le; @@ -2779,36 +2795,6 @@ static void remove_fcb_extent(fcb* fcb, extent* ext, LIST_ENTRY* rollback) { } } -NTSTATUS calc_csum(_In_ device_extension* Vcb, _In_reads_bytes_(sectors*Vcb->superblock.sector_size) uint8_t* data, - _In_ uint32_t sectors, _Out_writes_bytes_(sectors*sizeof(uint32_t)) uint32_t* csum) { - NTSTATUS Status; - calc_job* cj; - - // From experimenting, it seems that 40 sectors is roughly the crossover - // point where offloading the crc32 calculation becomes worth it. - - if (sectors < 40 || get_num_of_processors() < 2) { - ULONG j; - - for (j = 0; j < sectors; j++) { - csum[j] = ~calc_crc32c(0xffffffff, data + (j * Vcb->superblock.sector_size), Vcb->superblock.sector_size); - } - - return STATUS_SUCCESS; - } - - Status = add_calc_job(Vcb, data, sectors, csum, &cj); - if (!NT_SUCCESS(Status)) { - ERR("add_calc_job returned %08x\n", Status); - return Status; - } - - KeWaitForSingleObject(&cj->event, Executive, KernelMode, false, NULL); - free_calc_job(cj); - - return STATUS_SUCCESS; -} - _Requires_lock_held_(c->lock) _When_(return != 0, _Releases_lock_(c->lock)) bool insert_extent_chunk(_In_ device_extension* Vcb, _In_ fcb* fcb, _In_ chunk* c, _In_ uint64_t start_data, _In_ uint64_t length, _In_ bool prealloc, _In_opt_ void* data, @@ -2818,7 +2804,7 @@ bool insert_extent_chunk(_In_ device_extension* Vcb, _In_ fcb* fcb, _In_ chunk* EXTENT_DATA* ed; EXTENT_DATA2* ed2; uint16_t edsize = (uint16_t)(offsetof(EXTENT_DATA, data[0]) + sizeof(EXTENT_DATA2)); - uint32_t* csum = NULL; + void* csum = NULL; TRACE("(%p, (%I64x, %I64x), %I64x, %I64x, %I64x, %u, %p, %p)\n", Vcb, fcb->subvol->id, fcb->inode, c->offset, start_data, length, prealloc, data, rollback); @@ -2848,25 +2834,19 @@ bool insert_extent_chunk(_In_ device_extension* Vcb, _In_ fcb* fcb, _In_ chunk* if (!prealloc && data && !(fcb->inode_item.flags & BTRFS_INODE_NODATASUM)) { ULONG sl = (ULONG)(length / Vcb->superblock.sector_size); - csum = ExAllocatePoolWithTag(PagedPool, sl * sizeof(uint32_t), ALLOC_TAG); + csum = ExAllocatePoolWithTag(PagedPool, sl * Vcb->csum_size, ALLOC_TAG); if (!csum) { ERR("out of memory\n"); ExFreePool(ed); return false; } - Status = calc_csum(Vcb, data, sl, csum); - if (!NT_SUCCESS(Status)) { - ERR("calc_csum returned %08x\n", Status); - ExFreePool(csum); - ExFreePool(ed); - return false; - } + do_calc_job(Vcb, data, sl, csum); } Status = add_extent_to_fcb(fcb, start_data, ed, edsize, true, csum, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_extent_to_fcb returned %08x\n", Status); + ERR("add_extent_to_fcb returned %08lx\n", Status); if (csum) ExFreePool(csum); ExFreePool(ed); return false; @@ -2895,7 +2875,7 @@ bool insert_extent_chunk(_In_ device_extension* Vcb, _In_ fcb* fcb, _In_ chunk* Status = write_data_complete(Vcb, address, data, (uint32_t)length, Irp, NULL, file_write, irp_offset, fcb->Header.Flags2 & FSRTL_FLAG2_IS_PAGING_FILE ? HighPagePriority : NormalPagePriority); if (!NT_SUCCESS(Status)) - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); } return true; @@ -2961,7 +2941,7 @@ static bool try_extend_data(device_extension* Vcb, fcb* fcb, uint64_t start_data NTSTATUS Status = load_cache_chunk(Vcb, c, NULL); if (!NT_SUCCESS(Status)) { - ERR("load_cache_chunk returned %08x\n", Status); + ERR("load_cache_chunk returned %08lx\n", Status); release_chunk_lock(c, Vcb); return false; } @@ -3008,7 +2988,7 @@ static NTSTATUS insert_chunk_fragmented(fcb* fcb, uint64_t start, uint64_t lengt } while (NT_SUCCESS(Status)); if (Status != STATUS_DISK_FULL) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); ExReleaseResourceLite(&fcb->Vcb->chunk_lock); return Status; } @@ -3092,7 +3072,7 @@ static NTSTATUS insert_prealloc_extent(fcb* fcb, uint64_t start, uint64_t length ExReleaseResourceLite(&fcb->Vcb->chunk_lock); if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); goto end; } @@ -3107,7 +3087,7 @@ static NTSTATUS insert_prealloc_extent(fcb* fcb, uint64_t start, uint64_t length Status = insert_chunk_fragmented(fcb, start, length, NULL, true, rollback); if (!NT_SUCCESS(Status)) - ERR("insert_chunk_fragmented returned %08x\n", Status); + ERR("insert_chunk_fragmented returned %08lx\n", Status); goto end; @@ -3197,7 +3177,7 @@ static NTSTATUS insert_extent(device_extension* Vcb, fcb* fcb, uint64_t start_da ExReleaseResourceLite(&Vcb->chunk_lock); if (!NT_SUCCESS(Status)) { - ERR("alloc_chunk returned %08x\n", Status); + ERR("alloc_chunk returned %08lx\n", Status); return Status; } @@ -3224,7 +3204,7 @@ static NTSTATUS insert_extent(device_extension* Vcb, fcb* fcb, uint64_t start_da if (!done) { Status = insert_chunk_fragmented(fcb, start_data, length, data, false, rollback); if (!NT_SUCCESS(Status)) - ERR("insert_chunk_fragmented returned %08x\n", Status); + ERR("insert_chunk_fragmented returned %08lx\n", Status); return Status; } @@ -3250,14 +3230,14 @@ NTSTATUS truncate_file(fcb* fcb, uint64_t end, PIRP Irp, LIST_ENTRY* rollback) { Status = read_file(fcb, make_inline ? (buf + offsetof(EXTENT_DATA, data[0])) : buf, 0, end, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(buf); return Status; } Status = excise_extents(fcb->Vcb, fcb, 0, fcb->inode_item.st_size, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); ExFreePool(buf); return Status; } @@ -3267,7 +3247,7 @@ NTSTATUS truncate_file(fcb* fcb, uint64_t end, PIRP Irp, LIST_ENTRY* rollback) { Status = do_write_file(fcb, 0, sector_align(end, fcb->Vcb->superblock.sector_size), buf, Irp, false, 0, rollback); if (!NT_SUCCESS(Status)) { - ERR("do_write_file returned %08x\n", Status); + ERR("do_write_file returned %08lx\n", Status); ExFreePool(buf); return Status; } @@ -3283,7 +3263,7 @@ NTSTATUS truncate_file(fcb* fcb, uint64_t end, PIRP Irp, LIST_ENTRY* rollback) { Status = add_extent_to_fcb(fcb, 0, ed, (uint16_t)(offsetof(EXTENT_DATA, data[0]) + end), false, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_extent_to_fcb returned %08x\n", Status); + ERR("add_extent_to_fcb returned %08lx\n", Status); ExFreePool(buf); return Status; } @@ -3298,7 +3278,7 @@ NTSTATUS truncate_file(fcb* fcb, uint64_t end, PIRP Irp, LIST_ENTRY* rollback) { Status = excise_extents(fcb->Vcb, fcb, sector_align(end, fcb->Vcb->superblock.sector_size), sector_align(fcb->inode_item.st_size, fcb->Vcb->superblock.sector_size), Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); return Status; } @@ -3321,7 +3301,7 @@ NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, P bool cur_inline; NTSTATUS Status; - TRACE("(%p, %p, %x, %u)\n", fcb, fileref, end, prealloc); + TRACE("(%p, %p, %I64x, %u)\n", fcb, fileref, end, prealloc); if (fcb->ads) { if (end > 0xffff) @@ -3372,7 +3352,7 @@ NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, P Status = read_file(fcb, data, 0, origlength, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(data); return Status; } @@ -3381,14 +3361,14 @@ NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, P Status = excise_extents(fcb->Vcb, fcb, 0, fcb->inode_item.st_size, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); ExFreePool(data); return Status; } Status = do_write_file(fcb, 0, length, data, Irp, false, 0, rollback); if (!NT_SUCCESS(Status)) { - ERR("do_write_file returned %08x\n", Status); + ERR("do_write_file returned %08lx\n", Status); ExFreePool(data); return Status; } @@ -3419,7 +3399,7 @@ NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, P Status = read_file(fcb, ed->data, ext->offset, oldalloc, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(ed); return Status; } @@ -3430,7 +3410,7 @@ NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, P Status = add_extent_to_fcb(fcb, ext->offset, ed, edsize, ext->unique, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_extent_to_fcb returned %08x\n", Status); + ERR("add_extent_to_fcb returned %08lx\n", Status); ExFreePool(ed); return Status; } @@ -3459,7 +3439,7 @@ NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, P Status = insert_prealloc_extent(fcb, oldalloc, newalloc - oldalloc, rollback); if (!NT_SUCCESS(Status)) { - ERR("insert_prealloc_extent returned %08x\n", Status); + ERR("insert_prealloc_extent returned %08lx\n", Status); return Status; } } @@ -3486,7 +3466,7 @@ NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, P Status = insert_prealloc_extent(fcb, 0, newalloc, rollback); if (!NT_SUCCESS(Status)) { - ERR("insert_prealloc_extent returned %08x\n", Status); + ERR("insert_prealloc_extent returned %08lx\n", Status); return Status; } } @@ -3525,7 +3505,7 @@ NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, P Status = add_extent_to_fcb(fcb, 0, ed, edsize, false, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_extent_to_fcb returned %08x\n", Status); + ERR("add_extent_to_fcb returned %08lx\n", Status); ExFreePool(ed); return Status; } @@ -3572,13 +3552,13 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat Status = write_data_complete(fcb->Vcb, ed2->address + ed2->offset, (uint8_t*)data + ext->offset - start_data, (uint32_t)ed2->num_bytes, Irp, NULL, file_write, irp_offset + ext->offset - start_data, priority); if (!NT_SUCCESS(Status)) { - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); return Status; } if (!(fcb->inode_item.flags & BTRFS_INODE_NODATASUM)) { ULONG sl = (ULONG)(ed2->num_bytes / fcb->Vcb->superblock.sector_size); - uint32_t* csum = ExAllocatePoolWithTag(PagedPool, sl * sizeof(uint32_t), ALLOC_TAG); + void* csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG); if (!csum) { ERR("out of memory\n"); @@ -3586,13 +3566,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat return STATUS_INSUFFICIENT_RESOURCES; } - Status = calc_csum(fcb->Vcb, (uint8_t*)data + ext->offset - start_data, sl, csum); - if (!NT_SUCCESS(Status)) { - ERR("calc_csum returned %08x\n", Status); - ExFreePool(csum); - ExFreePool(newext); - return Status; - } + do_calc_job(fcb->Vcb, (uint8_t*)data + ext->offset - start_data, sl, csum); newext->csum = csum; } else @@ -3642,7 +3616,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat Status = write_data_complete(fcb->Vcb, ed2->address + ed2->offset, (uint8_t*)data + ext->offset - start_data, (uint32_t)(end_data - ext->offset), Irp, NULL, file_write, irp_offset + ext->offset - start_data, priority); if (!NT_SUCCESS(Status)) { - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); ExFreePool(newext1); ExFreePool(newext2); return Status; @@ -3650,7 +3624,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat if (!(fcb->inode_item.flags & BTRFS_INODE_NODATASUM)) { ULONG sl = (ULONG)((end_data - ext->offset) / fcb->Vcb->superblock.sector_size); - uint32_t* csum = ExAllocatePoolWithTag(PagedPool, sl * sizeof(uint32_t), ALLOC_TAG); + void* csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG); if (!csum) { ERR("out of memory\n"); @@ -3659,14 +3633,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat return STATUS_INSUFFICIENT_RESOURCES; } - Status = calc_csum(fcb->Vcb, (uint8_t*)data + ext->offset - start_data, sl, csum); - if (!NT_SUCCESS(Status)) { - ERR("calc_csum returned %08x\n", Status); - ExFreePool(newext1); - ExFreePool(newext2); - ExFreePool(csum); - return Status; - } + do_calc_job(fcb->Vcb, (uint8_t*)data + ext->offset - start_data, sl, csum); newext1->csum = csum; } else @@ -3702,7 +3669,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); return Status; } } @@ -3739,7 +3706,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat Status = write_data_complete(fcb->Vcb, ed2->address + ned2->offset, data, (uint32_t)ned2->num_bytes, Irp, NULL, file_write, irp_offset, priority); if (!NT_SUCCESS(Status)) { - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); ExFreePool(newext1); ExFreePool(newext2); return Status; @@ -3747,7 +3714,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat if (!(fcb->inode_item.flags & BTRFS_INODE_NODATASUM)) { ULONG sl = (ULONG)(ned2->num_bytes / fcb->Vcb->superblock.sector_size); - uint32_t* csum = ExAllocatePoolWithTag(PagedPool, sl * sizeof(uint32_t), ALLOC_TAG); + void* csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG); if (!csum) { ERR("out of memory\n"); @@ -3756,14 +3723,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat return STATUS_INSUFFICIENT_RESOURCES; } - Status = calc_csum(fcb->Vcb, data, sl, csum); - if (!NT_SUCCESS(Status)) { - ERR("calc_csum returned %08x\n", Status); - ExFreePool(newext1); - ExFreePool(newext2); - ExFreePool(csum); - return Status; - } + do_calc_job(fcb->Vcb, data, sl, csum); newext2->csum = csum; } else @@ -3799,7 +3759,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); return Status; } } @@ -3849,7 +3809,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat ned2 = (EXTENT_DATA2*)newext2->extent_data.data; Status = write_data_complete(fcb->Vcb, ed2->address + ned2->offset, data, (uint32_t)(end_data - start_data), Irp, NULL, file_write, irp_offset, priority); if (!NT_SUCCESS(Status)) { - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); ExFreePool(newext1); ExFreePool(newext2); ExFreePool(newext3); @@ -3858,7 +3818,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat if (!(fcb->inode_item.flags & BTRFS_INODE_NODATASUM)) { ULONG sl = (ULONG)((end_data - start_data) / fcb->Vcb->superblock.sector_size); - uint32_t* csum = ExAllocatePoolWithTag(PagedPool, sl * sizeof(uint32_t), ALLOC_TAG); + void* csum = ExAllocatePoolWithTag(PagedPool, sl * fcb->Vcb->csum_size, ALLOC_TAG); if (!csum) { ERR("out of memory\n"); @@ -3868,15 +3828,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat return STATUS_INSUFFICIENT_RESOURCES; } - Status = calc_csum(fcb->Vcb, data, sl, csum); - if (!NT_SUCCESS(Status)) { - ERR("calc_csum returned %08x\n", Status); - ExFreePool(newext1); - ExFreePool(newext2); - ExFreePool(newext3); - ExFreePool(csum); - return Status; - } + do_calc_job(fcb->Vcb, data, sl, csum); newext2->csum = csum; } else @@ -3922,7 +3874,7 @@ static NTSTATUS do_write_file_prealloc(fcb* fcb, extent* ext, uint64_t start_dat fcb->inode_item.flags & BTRFS_INODE_NODATASUM, false, Irp); if (!NT_SUCCESS(Status)) { - ERR("update_changed_extent_ref returned %08x\n", Status); + ERR("update_changed_extent_ref returned %08lx\n", Status); return Status; } } @@ -3976,13 +3928,13 @@ NTSTATUS do_write_file(fcb* fcb, uint64_t start, uint64_t end_data, void* data, Status = excise_extents(fcb->Vcb, fcb, start_write, ext->offset, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); return Status; } Status = insert_extent(fcb->Vcb, fcb, start_write, ext->offset - start_write, (uint8_t*)data + written, Irp, file_write, irp_offset + written, rollback); if (!NT_SUCCESS(Status)) { - ERR("insert_extent returned %08x\n", Status); + ERR("insert_extent returned %08lx\n", Status); return Status; } @@ -4002,7 +3954,7 @@ NTSTATUS do_write_file(fcb* fcb, uint64_t start, uint64_t end_data, void* data, Status = write_data_complete(fcb->Vcb, writeaddr, (uint8_t*)data + written, (uint32_t)write_len, Irp, NULL, file_write, irp_offset + written, priority); if (!NT_SUCCESS(Status)) { - ERR("write_data_complete returned %08x\n", Status); + ERR("write_data_complete returned %08lx\n", Status); return Status; } @@ -4012,8 +3964,8 @@ NTSTATUS do_write_file(fcb* fcb, uint64_t start, uint64_t end_data, void* data, // This shouldn't ever get called - nocow files should always also be nosum. if (!(fcb->inode_item.flags & BTRFS_INODE_NODATASUM)) { - calc_csum(fcb->Vcb, (uint8_t*)data + written, (uint32_t)(write_len / fcb->Vcb->superblock.sector_size), - &ext->csum[(start + written - ext->offset) / fcb->Vcb->superblock.sector_size]); + do_calc_job(fcb->Vcb, (uint8_t*)data + written, (uint32_t)(write_len / fcb->Vcb->superblock.sector_size), + (uint8_t*)ext->csum + ((start + written - ext->offset) * fcb->Vcb->csum_size / fcb->Vcb->superblock.sector_size)); ext->inserted = true; extents_changed = true; @@ -4030,7 +3982,7 @@ NTSTATUS do_write_file(fcb* fcb, uint64_t start, uint64_t end_data, void* data, Status = do_write_file_prealloc(fcb, ext, start + written, end_data, (uint8_t*)data + written, &write_len, Irp, file_write, irp_offset + written, priority, rollback); if (!NT_SUCCESS(Status)) { - ERR("do_write_file_prealloc returned %08x\n", Status); + ERR("do_write_file_prealloc returned %08lx\n", Status); return Status; } @@ -4058,13 +4010,13 @@ nextitem: Status = excise_extents(fcb->Vcb, fcb, start_write, end_data, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("excise_extents returned %08x\n", Status); + ERR("excise_extents returned %08lx\n", Status); return Status; } Status = insert_extent(fcb->Vcb, fcb, start_write, end_data - start_write, (uint8_t*)data + written, Irp, file_write, irp_offset + written, rollback); if (!NT_SUCCESS(Status)) { - ERR("insert_extent returned %08x\n", Status); + ERR("insert_extent returned %08lx\n", Status); return Status; } } @@ -4100,48 +4052,6 @@ nextitem: return STATUS_SUCCESS; } -NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, PIRP Irp, LIST_ENTRY* rollback) { - NTSTATUS Status; - uint64_t i; - - for (i = 0; i < sector_align(end_data - start_data, COMPRESSED_EXTENT_SIZE) / COMPRESSED_EXTENT_SIZE; i++) { - uint64_t s2, e2; - bool compressed; - - s2 = start_data + (i * COMPRESSED_EXTENT_SIZE); - e2 = min(s2 + COMPRESSED_EXTENT_SIZE, end_data); - - Status = write_compressed_bit(fcb, s2, e2, (uint8_t*)data + (i * COMPRESSED_EXTENT_SIZE), &compressed, Irp, rollback); - - if (!NT_SUCCESS(Status)) { - ERR("write_compressed_bit returned %08x\n", Status); - return Status; - } - - // If the first 128 KB of a file is incompressible, we set the nocompress flag so we don't - // bother with the rest of it. - if (s2 == 0 && e2 == COMPRESSED_EXTENT_SIZE && !compressed && !fcb->Vcb->options.compress_force) { - fcb->inode_item.flags |= BTRFS_INODE_NOCOMPRESS; - fcb->inode_item_changed = true; - mark_fcb_dirty(fcb); - - // write subsequent data non-compressed - if (e2 < end_data) { - Status = do_write_file(fcb, e2, end_data, (uint8_t*)data + e2, Irp, false, 0, rollback); - - if (!NT_SUCCESS(Status)) { - ERR("do_write_file returned %08x\n", Status); - return Status; - } - } - - return STATUS_SUCCESS; - } - } - - return STATUS_SUCCESS; -} - NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void* buf, ULONG* length, bool paging_io, bool no_cache, bool wait, bool deferred_write, bool write_irp, LIST_ENTRY* rollback) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -4161,7 +4071,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void bool paging_lock = false, acquired_fcb_lock = false, acquired_tree_lock = false, pagefile; ULONG filter = 0; - TRACE("(%p, %p, %I64x, %p, %x, %u, %u)\n", Vcb, FileObject, offset.QuadPart, buf, *length, paging_io, no_cache); + TRACE("(%p, %p, %I64x, %p, %lx, %u, %u)\n", Vcb, FileObject, offset.QuadPart, buf, *length, paging_io, no_cache); if (*length == 0) { TRACE("returning success for zero-length write\n"); @@ -4204,7 +4114,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void if (!NT_SUCCESS(iosb.Status)) { ExReleaseResourceLite(fcb->Header.PagingIoResource); - ERR("CcFlushCache returned %08x\n", iosb.Status); + ERR("CcFlushCache returned %08lx\n", iosb.Status); return iosb.Status; } @@ -4255,9 +4165,10 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void if (off64 + *length > newlength) { if (paging_io) { if (off64 >= newlength) { - TRACE("paging IO tried to write beyond end of file (file size = %I64x, offset = %I64x, length = %x)\n", newlength, off64, *length); + TRACE("paging IO tried to write beyond end of file (file size = %I64x, offset = %I64x, length = %lx)\n", newlength, off64, *length); TRACE("FileObject: AllocationSize = %I64x, FileSize = %I64x, ValidDataLength = %I64x\n", fcb->Header.AllocationSize.QuadPart, fcb->Header.FileSize.QuadPart, fcb->Header.ValidDataLength.QuadPart); + Irp->IoStatus.Information = 0; Status = STATUS_SUCCESS; goto end; } @@ -4293,7 +4204,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void Status = extend_file(fcb, fileref, newlength, false, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("extend_file returned %08x\n", Status); + ERR("extend_file returned %08lx\n", Status); goto end; } } else if (!fcb->ads) @@ -4331,20 +4242,22 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void goto end; } else { if (fCcCopyWriteEx) { - TRACE("CcCopyWriteEx(%p, %I64x, %x, %u, %p, %p)\n", FileObject, off64, *length, wait, buf, Irp->Tail.Overlay.Thread); + TRACE("CcCopyWriteEx(%p, %I64x, %lx, %u, %p, %p)\n", FileObject, off64, *length, wait, buf, Irp->Tail.Overlay.Thread); if (!fCcCopyWriteEx(FileObject, &offset, *length, wait, buf, Irp->Tail.Overlay.Thread)) { Status = STATUS_PENDING; goto end; } TRACE("CcCopyWriteEx finished\n"); } else { - TRACE("CcCopyWrite(%p, %I64x, %x, %u, %p)\n", FileObject, off64, *length, wait, buf); + TRACE("CcCopyWrite(%p, %I64x, %lx, %u, %p)\n", FileObject, off64, *length, wait, buf); if (!CcCopyWrite(FileObject, &offset, *length, wait, buf)) { Status = STATUS_PENDING; goto end; } TRACE("CcCopyWrite finished\n"); } + + Irp->IoStatus.Information = *length; } } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); @@ -4363,7 +4276,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void char* data2; if (newlength > fcb->adsmaxlen) { - ERR("error - xattr too long (%I64u > %u)\n", newlength, fcb->adsmaxlen); + ERR("error - xattr too long (%I64u > %lu)\n", newlength, fcb->adsmaxlen); Status = STATUS_DISK_FULL; goto end; } @@ -4452,7 +4365,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void Status = read_file(fcb, data + bufhead, start_data, end_data - start_data, NULL, Irp); if (!NT_SUCCESS(Status)) { - ERR("read_file returned %08x\n", Status); + ERR("read_file returned %08lx\n", Status); ExFreePool(data); goto end; } @@ -4464,7 +4377,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void if (make_inline) { Status = excise_extents(fcb->Vcb, fcb, start_data, end_data, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("error - excise_extents returned %08x\n", Status); + ERR("error - excise_extents returned %08lx\n", Status); ExFreePool(data); goto end; } @@ -4479,7 +4392,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void Status = add_extent_to_fcb(fcb, 0, ed2, (uint16_t)(offsetof(EXTENT_DATA, data[0]) + newlength), false, NULL, rollback); if (!NT_SUCCESS(Status)) { - ERR("add_extent_to_fcb returned %08x\n", Status); + ERR("add_extent_to_fcb returned %08lx\n", Status); ExFreePool(data); goto end; } @@ -4489,7 +4402,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void Status = write_compressed(fcb, start_data, end_data, data, Irp, rollback); if (!NT_SUCCESS(Status)) { - ERR("write_compressed returned %08x\n", Status); + ERR("write_compressed returned %08lx\n", Status); ExFreePool(data); goto end; } @@ -4507,7 +4420,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void } _SEH2_END; if (!NT_SUCCESS(Status)) { - ERR("MmProbeAndLockPages threw exception %08x\n", Status); + ERR("MmProbeAndLockPages threw exception %08lx\n", Status); goto end; } } @@ -4529,7 +4442,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void } if (!NT_SUCCESS(Status)) { - ERR("do_write_file returned %08x\n", Status); + ERR("do_write_file returned %08lx\n", Status); if (!no_buf) ExFreePool(data); goto end; } @@ -4604,6 +4517,7 @@ NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void fcb->subvol->root_item.ctime = now; Status = STATUS_SUCCESS; + Irp->IoStatus.Information = *length; if (filter != 0) queue_notification_fcb(fcb->ads ? fileref->parent : fileref, filter, fcb->ads ? FILE_ACTION_MODIFIED_STREAM : FILE_ACTION_MODIFIED, @@ -4644,7 +4558,7 @@ NTSTATUS write_file(device_extension* Vcb, PIRP Irp, bool wait, bool deferred_wr Irp->IoStatus.Information = 0; TRACE("offset = %I64x\n", offset.QuadPart); - TRACE("length = %x\n", IrpSp->Parameters.Write.Length); + TRACE("length = %lx\n", IrpSp->Parameters.Write.Length); if (!Irp->AssociatedIrp.SystemBuffer) { buf = map_user_buffer(Irp, fcb && fcb->Header.Flags2 & FSRTL_FLAG2_IS_PAGING_FILE ? HighPagePriority : NormalPagePriority); @@ -4671,13 +4585,11 @@ NTSTATUS write_file(device_extension* Vcb, PIRP Irp, bool wait, bool deferred_wr if (Status == STATUS_PENDING) goto exit; else if (!NT_SUCCESS(Status)) { - ERR("write_file2 returned %08x\n", Status); + ERR("write_file2 returned %08lx\n", Status); goto exit; } if (NT_SUCCESS(Status)) { - Irp->IoStatus.Information = IrpSp->Parameters.Write.Length; - if (diskacc && Status != STATUS_PENDING && Irp->Flags & IRP_NOCACHE) { PETHREAD thread = NULL; @@ -4793,7 +4705,7 @@ NTSTATUS __stdcall drv_write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { end: Irp->IoStatus.Status = Status; - TRACE("wrote %u bytes\n", Irp->IoStatus.Information); + TRACE("wrote %Iu bytes\n", Irp->IoStatus.Information); if (Status != STATUS_PENDING) IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -4808,7 +4720,7 @@ exit: if (top_level) IoSetTopLevelIrp(NULL); - TRACE("returning %08x\n", Status); + TRACE("returning %08lx\n", Status); FsRtlExitFileSystem(); diff --git a/drivers/filesystems/btrfs/zstd/xxhash.c b/drivers/filesystems/btrfs/xxhash.c similarity index 98% rename from drivers/filesystems/btrfs/zstd/xxhash.c rename to drivers/filesystems/btrfs/xxhash.c index 333e458707c..57ae7aa6556 100644 --- a/drivers/filesystems/btrfs/zstd/xxhash.c +++ b/drivers/filesystems/btrfs/xxhash.c @@ -99,8 +99,16 @@ /* for malloc(), free() */ #include #include /* size_t */ +#ifndef __REACTOS__ #include #include +#endif // __REACTOS__ + +#ifndef _USRDLL +#ifdef __REACTOS__ +#include +#include +#endif // __REACTOS__ #define XXH_ALLOC_TAG 0x32485858 // "XXH " @@ -108,10 +116,32 @@ static void* XXH_malloc(size_t s) { return ExAllocatePoolWithTag(PagedPool, s, XXH_ALLOC_TAG); } -static void XXH_free (void* p) { +static void XXH_free(void* p) { ExFreePool(p); } +#else +#ifndef __REACTOS__ +static void* XXH_malloc(size_t s) { + return malloc(s); +} + +static void XXH_free(void* p) { + free(p); +} +#else +#include + +static void* XXH_malloc(size_t s) { + return RtlAllocateHeap(RtlGetProcessHeap(), 0, s); +} + +static void XXH_free(void* p) { + RtlFreeHeap(RtlGetProcessHeap(), 0, p); +} +#endif // __REACTOS__ +#endif + /* for memcpy() */ #include static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } diff --git a/drivers/filesystems/btrfs/zstd/xxhash.h b/drivers/filesystems/btrfs/xxhash.h similarity index 100% rename from drivers/filesystems/btrfs/zstd/xxhash.h rename to drivers/filesystems/btrfs/xxhash.h diff --git a/drivers/filesystems/btrfs/zstd/zstd_internal.h b/drivers/filesystems/btrfs/zstd/zstd_internal.h index e75adfa6132..16001d214ac 100644 --- a/drivers/filesystems/btrfs/zstd/zstd_internal.h +++ b/drivers/filesystems/btrfs/zstd/zstd_internal.h @@ -32,7 +32,7 @@ #ifndef XXH_STATIC_LINKING_ONLY # define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */ #endif -#include "xxhash.h" /* XXH_reset, update, digest */ +#include "../xxhash.h" /* XXH_reset, update, digest */ #if defined (__cplusplus) diff --git a/media/doc/README.FSD b/media/doc/README.FSD index 28ff44cb991..cc671e5639a 100644 --- a/media/doc/README.FSD +++ b/media/doc/README.FSD @@ -3,9 +3,9 @@ The following FSD are shared with: https://github.com/maharmstone/btrfs. -reactos/drivers/filesystems/btrfs # Synced to 1.5 -reactos/dll/shellext/shellbtrfs # Synced to 1.5 -reactos/sdk/lib/fslib/btrfslib # Synced to 1.5 +reactos/drivers/filesystems/btrfs # Synced to 1.7.2 +reactos/dll/shellext/shellbtrfs # Synced to 1.7.2 +reactos/sdk/lib/fslib/btrfslib # Synced to 1.7.2 The following FSD are shared with: http://www.ext2fsd.com/ diff --git a/media/inf/btrfs.inf b/media/inf/btrfs.inf index cc81318d515..e7f4833ee35 100644 --- a/media/inf/btrfs.inf +++ b/media/inf/btrfs.inf @@ -2,7 +2,7 @@ ;;; WinBtrfs ;;; ;;; -;;; Copyright (c) 2016-19 Mark Harmstone +;;; Copyright (c) 2016-20 Mark Harmstone ;;; [Version] @@ -10,7 +10,7 @@ Signature = "$Windows NT$" Class = Volume ClassGuid = {71a27cdd-812a-11d0-bec7-08002be2092f} Provider = %Me% -DriverVer = 06/08/2019,1.3.0.0 +DriverVer = 04/10/2020,1.7.2.0 CatalogFile = btrfs.cat [DestinationDirs] @@ -32,21 +32,28 @@ CopyINF = btrfs.inf AddService = %ServiceName%,0x802,Btrfs.Service [Manufacturer] -%Me%=Standard,NTamd64,NTx86 +%Me%=Standard,NTamd64,NTx86,NTarm,NTarm64 [Standard.NTamd64] %VolumeName% = Btrfs_Install, BtrfsVolume %ControllerName% = Btrfs_Install, ROOT\btrfs -%ControllerName% = Btrfs_Install, ROOT\btrfs -%ControllerName% = Btrfs_Install, DETECTED\BTRFS [Standard.NTx86] %VolumeName% = Btrfs_Install, BtrfsVolume %ControllerName% = Btrfs_Install, ROOT\btrfs -%ControllerName% = Btrfs_Install, DETECTED\BTRFS + +[Standard.NTarm] +%VolumeName% = Btrfs_Install, BtrfsVolume +%ControllerName% = Btrfs_Install, ROOT\btrfs + +[Standard.NTarm64] +%VolumeName% = Btrfs_Install, BtrfsVolume +%ControllerName% = Btrfs_Install, ROOT\btrfs [Btrfs_Install] OptionDesc = %ServiceDescription% +CopyFiles = Btrfs.DriverFiles,Btrfs.DllFiles +RegisterDlls = shellbtrfs [Btrfs_Install.Services] AddService = %ServiceName%,2,Btrfs.Service @@ -90,6 +97,11 @@ shellbtrfs.dll ubtrfs.dll mkbtrfs.exe +[SourceDisksFiles] +btrfs.sys = 1,, +shellbtrfs.dll = 1,, +ubtrfs.dll = 1,, +mkbtrfs.exe = 1,, [SourceDisksNames.x86] 1 = %DiskId1%,,,\x86 @@ -97,6 +109,12 @@ mkbtrfs.exe [SourceDisksNames.amd64] 1 = %DiskId1%,,,\x64 +[SourceDisksNames.arm] +1 = %DiskId1%,,,\arm + +[SourceDisksNames.arm64] +1 = %DiskId1%,,,\aarch64 + ;; ;; String Section ;; diff --git a/sdk/lib/fslib/btrfslib/CMakeLists.txt b/sdk/lib/fslib/btrfslib/CMakeLists.txt index 3c4eca0190a..82b4c2740f5 100644 --- a/sdk/lib/fslib/btrfslib/CMakeLists.txt +++ b/sdk/lib/fslib/btrfslib/CMakeLists.txt @@ -2,5 +2,21 @@ include_directories( ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs) -add_library(btrfslib btrfslib.c) +list(APPEND SOURCE + ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs/blake2b-ref.c + ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs/crc32c.c + ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs/sha256.c + ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs/xxhash.c + btrfslib.c) + +if(ARCH STREQUAL "i386") + list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs/crc32c-x86.S) +elseif(ARCH STREQUAL "amd64") + list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/drivers/filesystems/btrfs/crc32c-amd64.S) +endif() + +add_asm_files(btrfs_asm ${ASM_SOURCE}) + +add_library(btrfslib ${SOURCE} ${btrfs_asm}) +target_compile_definitions(btrfslib PRIVATE _USRDLL) add_dependencies(btrfslib psdk) diff --git a/sdk/lib/fslib/btrfslib/btrfslib.c b/sdk/lib/fslib/btrfslib/btrfslib.c index 254873089df..f47a47cd3be 100644 --- a/sdk/lib/fslib/btrfslib/btrfslib.c +++ b/sdk/lib/fslib/btrfslib/btrfslib.c @@ -37,13 +37,33 @@ #include #ifdef __REACTOS__ #include +#include #include "btrfs.h" #include "btrfsioctl.h" +#include "crc32c.h" +#include "xxhash.h" #else #include +#include #include "../btrfs.h" #include "../btrfsioctl.h" +#include "../crc32c.h" +#include "../xxhash.h" + +#if defined(_X86_) || defined(_AMD64_) +#ifndef _MSC_VER +#include +#else +#include #endif +#endif +#endif // __REACTOS__ + +#define SHA256_HASH_SIZE 32 +void calc_sha256(uint8_t* hash, const void* input, size_t len); + +#define BLAKE2_HASH_SIZE 32 +void blake2b(void *out, size_t outlen, const void* in, size_t inlen); #ifndef __REACTOS__ #define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS) @@ -67,7 +87,7 @@ NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRo #ifdef __cplusplus } #endif -#endif +#endif // __REACTOS__ // These are undocumented, and what comes from format.exe typedef struct { @@ -154,6 +174,7 @@ typedef struct { HMODULE module; ULONG def_sector_size = 0, def_node_size = 0; uint64_t def_incompat_flags = BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF | BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA; +uint16_t def_csum_type = CSUM_TYPE_CRC32C; // the following definitions come from fmifs.h in ReactOS @@ -211,54 +232,6 @@ typedef enum { typedef BOOLEAN (NTAPI* PFMIFSCALLBACK)(CALLBACKCOMMAND Command, ULONG SubAction, PVOID ActionInfo); -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, -}; - -static uint32_t calc_crc32c(uint32_t seed, uint8_t* msg, ULONG msglen) { - 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__ NTSTATUS WINAPI ChkdskEx(PUNICODE_STRING DriveRoot, BOOLEAN FixErrors, BOOLEAN Verbose, BOOLEAN CheckOnlyIfDirty, #else @@ -490,7 +463,7 @@ static btrfs_chunk* add_chunk(LIST_ENTRY* chunks, uint64_t flags, btrfs_root* ch return c; } -static BOOL superblock_collision(btrfs_chunk* c, uint64_t address) { +static bool superblock_collision(btrfs_chunk* c, uint64_t address) { CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1]; uint64_t stripe = (address - c->offset) / c->chunk_item->stripe_length; uint16_t i, j; @@ -502,13 +475,13 @@ static BOOL superblock_collision(btrfs_chunk* c, uint64_t address) { uint64_t stripe2 = (superblock_addrs[j] - cis[i].offset) / c->chunk_item->stripe_length; if (stripe2 == stripe) - return TRUE; + return true; } j++; } } - return FALSE; + return false; } static uint64_t get_next_address(btrfs_chunk* c) { @@ -540,7 +513,7 @@ typedef struct { } EXTENT_ITEM_METADATA2; static void assign_addresses(LIST_ENTRY* roots, btrfs_chunk* sys_chunk, btrfs_chunk* metadata_chunk, uint32_t node_size, - btrfs_root* root_root, btrfs_root* extent_root, BOOL skinny) { + btrfs_root* root_root, btrfs_root* extent_root, bool skinny) { LIST_ENTRY* le; le = roots->Flink; @@ -632,6 +605,26 @@ static NTSTATUS write_data(HANDLE h, uint64_t address, btrfs_chunk* c, void* dat return STATUS_SUCCESS; } +static void calc_tree_checksum(tree_header* th, uint32_t node_size) { + switch (def_csum_type) { + case CSUM_TYPE_CRC32C: + *(uint32_t*)th = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, node_size - sizeof(th->csum)); + break; + + case CSUM_TYPE_XXHASH: + *(uint64_t*)th = XXH64((uint8_t*)&th->fs_uuid, node_size - sizeof(th->csum), 0); + break; + + case CSUM_TYPE_SHA256: + calc_sha256((uint8_t*)th, &th->fs_uuid, node_size - sizeof(th->csum)); + break; + + case CSUM_TYPE_BLAKE2: + blake2b((uint8_t*)th, BLAKE2_HASH_SIZE, &th->fs_uuid, node_size - sizeof(th->csum)); + break; + } +} + static NTSTATUS write_roots(HANDLE h, LIST_ENTRY* roots, uint32_t node_size, BTRFS_UUID* fsuuid, BTRFS_UUID* chunkuuid) { LIST_ENTRY *le, *le2; NTSTATUS Status; @@ -648,7 +641,6 @@ static NTSTATUS write_roots(HANDLE h, LIST_ENTRY* roots, uint32_t node_size, BTR btrfs_root* r = CONTAINING_RECORD(le, btrfs_root, list_entry); uint8_t* dp; leaf_node* ln; - uint32_t crc32; memset(tree, 0, node_size); @@ -674,7 +666,7 @@ static NTSTATUS write_roots(HANDLE h, LIST_ENTRY* roots, uint32_t node_size, BTR dp -= item->size; memcpy(dp, item->data, item->size); - ln->offset = dp - tree - sizeof(tree_header); + ln->offset = (uint32_t)(dp - tree - sizeof(tree_header)); } else ln->offset = 0; @@ -687,8 +679,7 @@ static NTSTATUS write_roots(HANDLE h, LIST_ENTRY* roots, uint32_t node_size, BTR memcpy(tree, &r->header, sizeof(tree_header)); - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&((tree_header*)tree)->fs_uuid, node_size - sizeof(((tree_header*)tree)->csum)); - memcpy(tree, &crc32, sizeof(uint32_t)); + calc_tree_checksum((tree_header*)tree, node_size); Status = write_data(h, r->header.address, r->c, tree, node_size); if (!NT_SUCCESS(Status)) { @@ -758,13 +749,32 @@ static void init_device(btrfs_dev* dev, uint64_t id, uint64_t size, BTRFS_UUID* dev->last_alloc = 0x100000; // skip first megabyte } +static void calc_superblock_checksum(superblock* sb) { + switch (def_csum_type) { + case CSUM_TYPE_CRC32C: + *(uint32_t*)sb = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); + break; + + case CSUM_TYPE_XXHASH: + *(uint64_t*)sb = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0); + break; + + case CSUM_TYPE_SHA256: + calc_sha256((uint8_t*)sb, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum)); + break; + + case CSUM_TYPE_BLAKE2: + blake2b((uint8_t*)sb, BLAKE2_HASH_SIZE, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum)); + break; + } +} + static NTSTATUS write_superblocks(HANDLE h, btrfs_dev* dev, btrfs_root* chunk_root, btrfs_root* root_root, btrfs_root* extent_root, btrfs_chunk* sys_chunk, uint32_t node_size, BTRFS_UUID* fsuuid, uint32_t sector_size, PUNICODE_STRING label, uint64_t incompat_flags) { NTSTATUS Status; IO_STATUS_BLOCK iosb; ULONG sblen; int i; - uint32_t crc32; superblock* sb; KEY* key; uint64_t bytes_used; @@ -812,6 +822,7 @@ static NTSTATUS write_superblocks(HANDLE h, btrfs_dev* dev, btrfs_root* chunk_ro sb->n = sizeof(KEY) + sizeof(CHUNK_ITEM) + (sys_chunk->chunk_item->num_stripes * sizeof(CHUNK_ITEM_STRIPE)); sb->chunk_root_generation = 1; sb->incompat_flags = incompat_flags; + sb->csum_type = def_csum_type; memcpy(&sb->dev_item, &dev->dev_item, sizeof(DEV_ITEM)); if (label->Length > 0) { @@ -876,8 +887,7 @@ static NTSTATUS write_superblocks(HANDLE h, btrfs_dev* dev, btrfs_root* chunk_ro sb->sb_phys_addr = superblock_addrs[i]; - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - memcpy(&sb->checksum, &crc32, sizeof(uint32_t)); + calc_superblock_checksum(sb); off.QuadPart = superblock_addrs[i]; @@ -1017,7 +1027,7 @@ static NTSTATUS clear_first_megabyte(HANDLE h) { return Status; } -static BOOL is_ssd(HANDLE h) { +static bool is_ssd(HANDLE h) { ULONG aptelen; ATA_PASS_THROUGH_EX* apte; IO_STATUS_BLOCK iosb; @@ -1051,7 +1061,7 @@ static BOOL is_ssd(HANDLE h) { #else RtlFreeHeap(RtlGetProcessHeap(), 0, apte); #endif - return TRUE; + return true; } } @@ -1061,7 +1071,7 @@ static BOOL is_ssd(HANDLE h) { RtlFreeHeap(RtlGetProcessHeap(), 0, apte); #endif - return FALSE; + return false; } static void add_dir_item(btrfs_root* root, uint64_t inode, uint32_t hash, uint64_t key_objid, uint8_t key_type, @@ -1130,7 +1140,7 @@ static NTSTATUS write_btrfs(HANDLE h, uint64_t size, PUNICODE_STRING label, uint btrfs_chunk *sys_chunk, *metadata_chunk; btrfs_dev dev; BTRFS_UUID fsuuid, chunkuuid; - BOOL ssd; + bool ssd; uint64_t metadata_flags; #ifdef __REACTOS__ ULONG seed; @@ -1210,7 +1220,7 @@ static NTSTATUS write_btrfs(HANDLE h, uint64_t size, PUNICODE_STRING label, uint return STATUS_SUCCESS; } -static BOOL look_for_device(btrfs_filesystem* bfs, BTRFS_UUID* devuuid) { +static bool look_for_device(btrfs_filesystem* bfs, BTRFS_UUID* devuuid) { uint32_t i; btrfs_filesystem_device* dev; @@ -1221,26 +1231,60 @@ static BOOL look_for_device(btrfs_filesystem* bfs, BTRFS_UUID* devuuid) { dev = (btrfs_filesystem_device*)((uint8_t*)dev + offsetof(btrfs_filesystem_device, name[0]) + dev->name_length); if (RtlCompareMemory(&dev->uuid, devuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) - return TRUE; + return true; } - return FALSE; + return false; } -static BOOL is_mounted_multi_device(HANDLE h, uint32_t sector_size) { +static bool check_superblock_checksum(superblock* sb) { + switch (sb->csum_type) { + case CSUM_TYPE_CRC32C: { + uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); + + return crc32 == *(uint32_t*)sb; + } + + case CSUM_TYPE_XXHASH: { + uint64_t hash = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0); + + return hash == *(uint64_t*)sb; + } + + case CSUM_TYPE_SHA256: { + uint8_t hash[SHA256_HASH_SIZE]; + + calc_sha256(hash, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum)); + + return !memcmp(hash, sb, SHA256_HASH_SIZE); + } + + case CSUM_TYPE_BLAKE2: { + uint8_t hash[BLAKE2_HASH_SIZE]; + + blake2b(hash, sizeof(hash), &sb->uuid, sizeof(superblock) - sizeof(sb->checksum)); + + return !memcmp(hash, sb, BLAKE2_HASH_SIZE); + } + + default: + return false; + } +} + +static bool is_mounted_multi_device(HANDLE h, uint32_t sector_size) { NTSTATUS Status; superblock* sb; ULONG sblen; IO_STATUS_BLOCK iosb; LARGE_INTEGER off; BTRFS_UUID fsuuid, devuuid; - uint32_t crc32; UNICODE_STRING us; OBJECT_ATTRIBUTES atts; HANDLE h2; btrfs_filesystem *bfs = NULL, *bfs2; ULONG bfssize; - BOOL ret = FALSE; + bool ret = false; static WCHAR btrfs[] = L"\\Btrfs"; @@ -1263,7 +1307,7 @@ static BOOL is_mounted_multi_device(HANDLE h, uint32_t sector_size) { #else RtlFreeHeap(RtlGetProcessHeap(), 0, sb); #endif - return FALSE; + return false; } if (sb->magic != BTRFS_MAGIC) { @@ -1272,17 +1316,16 @@ static BOOL is_mounted_multi_device(HANDLE h, uint32_t sector_size) { #else RtlFreeHeap(RtlGetProcessHeap(), 0, sb); #endif - return FALSE; + return false; } - crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum)); - if (crc32 != *((uint32_t*)sb)) { + if (!check_superblock_checksum(sb)) { #ifndef __REACTOS__ free(sb); #else RtlFreeHeap(RtlGetProcessHeap(), 0, sb); #endif - return FALSE; + return false; } fsuuid = sb->uuid; @@ -1302,7 +1345,7 @@ static BOOL is_mounted_multi_device(HANDLE h, uint32_t sector_size) { Status = NtOpenFile(&h2, SYNCHRONIZE | FILE_READ_ATTRIBUTES, &atts, &iosb, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT); if (!NT_SUCCESS(Status)) // not a problem, it usually just means the driver isn't loaded - return FALSE; + return false; bfssize = 0; @@ -1320,7 +1363,7 @@ static BOOL is_mounted_multi_device(HANDLE h, uint32_t sector_size) { Status = NtDeviceIoControlFile(h2, NULL, NULL, NULL, &iosb, IOCTL_BTRFS_QUERY_FILESYSTEMS, NULL, 0, bfs, bfssize); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { NtClose(h2); - return FALSE; + return false; } } while (Status == STATUS_BUFFER_OVERFLOW); @@ -1329,10 +1372,10 @@ static BOOL is_mounted_multi_device(HANDLE h, uint32_t sector_size) { if (bfs->num_devices != 0) { bfs2 = bfs; - while (TRUE) { + while (true) { if (RtlCompareMemory(&bfs2->uuid, &fsuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) { if (bfs2->num_devices == 1) - ret = FALSE; + ret = false; else ret = look_for_device(bfs2, &devuuid); @@ -1376,15 +1419,33 @@ static void do_full_trim(HANDLE h) { NtDeviceIoControlFile(h, NULL, NULL, NULL, &iosb, IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, &dmdsa, sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES), NULL, 0); } -static BOOL is_power_of_two(ULONG i) { +static bool is_power_of_two(ULONG i) { return ((i != 0) && !(i & (i - 1))); } +#if !defined(__REACTOS__) && (defined(_X86_) || defined(_AMD64_)) +static void check_cpu() { + unsigned int cpuInfo[4]; + bool have_sse42; + +#ifndef _MSC_VER + __get_cpuid(1, &cpuInfo[0], &cpuInfo[1], &cpuInfo[2], &cpuInfo[3]); + have_sse42 = cpuInfo[2] & bit_SSE4_2; +#else + __cpuid(cpuInfo, 1); + have_sse42 = cpuInfo[2] & (1 << 20); +#endif + + if (have_sse42) + calc_crc32c = calc_crc32c_hw; +} +#endif + #ifndef __REACTOS__ static NTSTATUS NTAPI FormatEx2(PUNICODE_STRING DriveRoot, FMIFS_MEDIA_FLAG MediaFlag, PUNICODE_STRING Label, #else NTSTATUS NTAPI BtrfsFormatEx(PUNICODE_STRING DriveRoot, FMIFS_MEDIA_FLAG MediaFlag, PUNICODE_STRING Label, -#endif +#endif // __REACTOS__ BOOLEAN QuickFormat, ULONG ClusterSize, PFMIFSCALLBACK Callback) { NTSTATUS Status; @@ -1418,13 +1479,21 @@ NTSTATUS NTAPI BtrfsFormatEx(PUNICODE_STRING DriveRoot, FMIFS_MEDIA_FLAG MediaFl tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { + if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { CloseHandle(token); return STATUS_PRIVILEGE_NOT_HELD; } CloseHandle(token); + +#if defined(_X86_) || defined(_AMD64_) + check_cpu(); #endif +#endif + + if (def_csum_type != CSUM_TYPE_CRC32C && def_csum_type != CSUM_TYPE_XXHASH && def_csum_type != CSUM_TYPE_SHA256 && + def_csum_type != CSUM_TYPE_BLAKE2) + return STATUS_INVALID_PARAMETER; InitializeObjectAttributes(&attr, DriveRoot, OBJ_CASE_INSENSITIVE, NULL, NULL); @@ -1519,7 +1588,7 @@ end: MOUNTDEV_NAME* mdn; ULONG mdnsize; - mdnsize = offsetof(MOUNTDEV_NAME, Name[0]) + DriveRoot->Length; + mdnsize = (ULONG)(offsetof(MOUNTDEV_NAME, Name[0]) + DriveRoot->Length); #ifndef __REACTOS__ mdn = malloc(mdnsize); #else @@ -1544,7 +1613,7 @@ end: } if (Callback) { - BOOL success = NT_SUCCESS(Status); + bool success = NT_SUCCESS(Status); Callback(DONE, 0, (PVOID)&success); } @@ -1556,7 +1625,7 @@ BOOL __stdcall FormatEx(DSTRING* root, STREAM_MESSAGE* message, options* opts, u NTSTATUS Status; if (!root || !root->string) - return FALSE; + return false; DriveRoot.Length = DriveRoot.MaximumLength = (USHORT)(wcslen(root->string) * sizeof(WCHAR)); DriveRoot.Buffer = root->string; @@ -1590,10 +1659,14 @@ void __stdcall SetIncompatFlags(uint64_t incompat_flags) { def_incompat_flags = incompat_flags; } +void __stdcall SetCsumType(uint16_t csum_type) { + def_csum_type = csum_type; +} + BOOL __stdcall GetFilesystemInformation(uint32_t unk1, uint32_t unk2, void* unk3) { // STUB - undocumented - return TRUE; + return true; } #ifndef __REACTOS__ @@ -1601,6 +1674,6 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) module = (HMODULE)hModule; - return TRUE; + return true; } #endif