1 /* Copyright (c) Mark Harmstone 2016-17 2 * 3 * This file is part of WinBtrfs. 4 * 5 * WinBtrfs is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public Licence as published by 7 * the Free Software Foundation, either version 3 of the Licence, or 8 * (at your option) any later version. 9 * 10 * WinBtrfs is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public Licence for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public Licence 16 * along with WinBtrfs. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #pragma once 19 20 #ifndef __REACTOS__ 21 #undef _WIN32_WINNT 22 #undef NTDDI_VERSION 23 24 #define _WIN32_WINNT 0x0601 25 #define NTDDI_VERSION 0x06020000 // Win 8 26 #define _CRT_SECURE_NO_WARNINGS 27 #define _NO_CRT_STDIO_INLINE 28 #endif /* __REACTOS__ */ 29 30 #ifdef _MSC_VER 31 #pragma warning(push) 32 #pragma warning(disable:4163) 33 #pragma warning(disable:4311) 34 #pragma warning(disable:4312) 35 #else 36 #pragma GCC diagnostic push 37 #pragma GCC diagnostic ignored "-Wsign-compare" 38 #pragma GCC diagnostic ignored "-Wsign-conversion" 39 #endif 40 41 #include <ntifs.h> 42 #include <ntddk.h> 43 #ifdef __REACTOS__ 44 #include <ntdddisk.h> 45 #endif /* __REACTOS__ */ 46 #include <mountmgr.h> 47 #ifdef __REACTOS__ 48 #include <rtlfuncs.h> 49 #include <iotypes.h> 50 #include <pseh/pseh2.h> 51 #endif /* __REACTOS__ */ 52 #include <windef.h> 53 #include <wdm.h> 54 55 #ifdef _MSC_VER 56 #pragma warning(pop) 57 #else 58 #pragma GCC diagnostic pop 59 #endif 60 61 #include <stdio.h> 62 #include <stdarg.h> 63 #include <stddef.h> 64 #include <stdint.h> 65 #include <stdbool.h> 66 #ifndef __REACTOS__ 67 // Not actually used 68 #include <emmintrin.h> 69 #endif /* __REACTOS__ */ 70 #include "btrfs.h" 71 #include "btrfsioctl.h" 72 73 #ifdef __REACTOS__ 74 C_ASSERT(sizeof(bool) == 1); 75 #endif 76 77 #ifdef _DEBUG 78 // #define DEBUG_FCB_REFCOUNTS 79 // #define DEBUG_LONG_MESSAGES 80 // #define DEBUG_FLUSH_TIMES 81 // #define DEBUG_CHUNK_LOCKS 82 // #define DEBUG_TRIM_EMULATION 83 #define DEBUG_PARANOID 84 #endif 85 86 #define UNUSED(x) (void)(x) 87 88 #define BTRFS_NODE_TYPE_CCB 0x2295 89 #define BTRFS_NODE_TYPE_FCB 0x2296 90 91 #define ALLOC_TAG 0x7442484D //'MHBt' 92 #define ALLOC_TAG_ZLIB 0x7A42484D //'MHBz' 93 94 #define UID_NOBODY 65534 95 #define GID_NOBODY 65534 96 97 #define EA_NTACL "security.NTACL" 98 #define EA_NTACL_HASH 0x45922146 99 100 #define EA_DOSATTRIB "user.DOSATTRIB" 101 #define EA_DOSATTRIB_HASH 0x914f9939 102 103 #define EA_REPARSE "user.reparse" 104 #define EA_REPARSE_HASH 0xfabad1fe 105 106 #define EA_EA "user.EA" 107 #define EA_EA_HASH 0x8270dd43 108 109 #define EA_CASE_SENSITIVE "user.casesensitive" 110 #define EA_CASE_SENSITIVE_HASH 0x1a9d97d4 111 112 #define EA_PROP_COMPRESSION "btrfs.compression" 113 #define EA_PROP_COMPRESSION_HASH 0x20ccdf69 114 115 #define MAX_EXTENT_SIZE 0x8000000 // 128 MB 116 #define COMPRESSED_EXTENT_SIZE 0x20000 // 128 KB 117 118 #define READ_AHEAD_GRANULARITY COMPRESSED_EXTENT_SIZE // really ought to be a multiple of COMPRESSED_EXTENT_SIZE 119 120 #define IO_REPARSE_TAG_LXSS_SYMLINK 0xa000001d // undocumented? 121 122 #define IO_REPARSE_TAG_LXSS_SOCKET 0x80000023 123 #define IO_REPARSE_TAG_LXSS_FIFO 0x80000024 124 #define IO_REPARSE_TAG_LXSS_CHARDEV 0x80000025 125 #define IO_REPARSE_TAG_LXSS_BLOCKDEV 0x80000026 126 127 #define BTRFS_VOLUME_PREFIX L"\\Device\\Btrfs{" 128 129 #ifdef _MSC_VER 130 #define try __try 131 #define except __except 132 #define finally __finally 133 #else 134 #define try if (1) 135 #define except(x) if (0 && (x)) 136 #define finally if (1) 137 #endif 138 139 #ifndef FILE_SUPPORTS_BLOCK_REFCOUNTING 140 #define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000 141 #endif 142 143 #ifndef FILE_SUPPORTS_POSIX_UNLINK_RENAME 144 #define FILE_SUPPORTS_POSIX_UNLINK_RENAME 0x00000400 145 #endif 146 147 #ifndef FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 148 #define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 0x00020000 149 #endif 150 151 typedef struct _FILE_ID_128 { 152 UCHAR Identifier[16]; 153 } FILE_ID_128, *PFILE_ID_128; 154 155 typedef struct _DUPLICATE_EXTENTS_DATA { 156 HANDLE FileHandle; 157 LARGE_INTEGER SourceFileOffset; 158 LARGE_INTEGER TargetFileOffset; 159 LARGE_INTEGER ByteCount; 160 } DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA; 161 162 #define FSCTL_DUPLICATE_EXTENTS_TO_FILE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 209, METHOD_BUFFERED, FILE_WRITE_ACCESS) 163 164 typedef struct _FSCTL_GET_INTEGRITY_INFORMATION_BUFFER { 165 WORD ChecksumAlgorithm; 166 WORD Reserved; 167 DWORD Flags; 168 DWORD ChecksumChunkSizeInBytes; 169 DWORD ClusterSizeInBytes; 170 } FSCTL_GET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_GET_INTEGRITY_INFORMATION_BUFFER; 171 172 typedef struct _FSCTL_SET_INTEGRITY_INFORMATION_BUFFER { 173 WORD ChecksumAlgorithm; 174 WORD Reserved; 175 DWORD Flags; 176 } FSCTL_SET_INTEGRITY_INFORMATION_BUFFER, *PFSCTL_SET_INTEGRITY_INFORMATION_BUFFER; 177 178 #define FSCTL_GET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 159, METHOD_BUFFERED, FILE_ANY_ACCESS) 179 #define FSCTL_SET_INTEGRITY_INFORMATION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 160, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) 180 181 #ifndef __REACTOS__ 182 #ifndef _MSC_VER 183 #define __drv_aliasesMem 184 #define _Requires_lock_held_(a) 185 #define _Requires_exclusive_lock_held_(a) 186 #define _Releases_lock_(a) 187 #define _Out_writes_bytes_opt_(a) 188 #define _Pre_satisfies_(a) 189 #define _Post_satisfies_(a) 190 #define _Releases_exclusive_lock_(a) 191 #define _Dispatch_type_(a) 192 #define _Create_lock_level_(a) 193 #define _Lock_level_order_(a,b) 194 #define _Has_lock_level_(a) 195 #define _Requires_lock_not_held_(a) 196 #define _Acquires_exclusive_lock_(a) 197 #define _Acquires_shared_lock_(a) 198 #endif 199 #endif 200 201 _Create_lock_level_(tree_lock) 202 _Create_lock_level_(fcb_lock) 203 _Lock_level_order_(tree_lock, fcb_lock) 204 205 struct _device_extension; 206 207 typedef struct _fcb_nonpaged { 208 FAST_MUTEX HeaderMutex; 209 SECTION_OBJECT_POINTERS segment_object; 210 ERESOURCE resource; 211 ERESOURCE paging_resource; 212 ERESOURCE dir_children_lock; 213 } fcb_nonpaged; 214 215 struct _root; 216 217 typedef struct { 218 uint64_t offset; 219 uint16_t datalen; 220 bool unique; 221 bool ignore; 222 bool inserted; 223 uint32_t* csum; 224 225 LIST_ENTRY list_entry; 226 227 EXTENT_DATA extent_data; 228 } extent; 229 230 typedef struct { 231 uint64_t parent; 232 uint64_t index; 233 UNICODE_STRING name; 234 ANSI_STRING utf8; 235 LIST_ENTRY list_entry; 236 } hardlink; 237 238 struct _file_ref; 239 240 typedef struct { 241 KEY key; 242 uint64_t index; 243 uint8_t type; 244 ANSI_STRING utf8; 245 uint32_t hash; 246 UNICODE_STRING name; 247 uint32_t hash_uc; 248 UNICODE_STRING name_uc; 249 ULONG size; 250 struct _file_ref* fileref; 251 LIST_ENTRY list_entry_index; 252 LIST_ENTRY list_entry_hash; 253 LIST_ENTRY list_entry_hash_uc; 254 } dir_child; 255 256 enum prop_compression_type { 257 PropCompression_None, 258 PropCompression_Zlib, 259 PropCompression_LZO, 260 PropCompression_ZSTD 261 }; 262 263 typedef struct { 264 LIST_ENTRY list_entry; 265 USHORT namelen; 266 USHORT valuelen; 267 bool dirty; 268 char data[1]; 269 } xattr; 270 271 typedef struct _fcb { 272 FSRTL_ADVANCED_FCB_HEADER Header; 273 struct _fcb_nonpaged* nonpaged; 274 LONG refcount; 275 POOL_TYPE pool_type; 276 struct _device_extension* Vcb; 277 struct _root* subvol; 278 uint64_t inode; 279 uint32_t hash; 280 uint8_t type; 281 INODE_ITEM inode_item; 282 SECURITY_DESCRIPTOR* sd; 283 FILE_LOCK lock; 284 bool deleted; 285 PKTHREAD lazy_writer_thread; 286 ULONG atts; 287 SHARE_ACCESS share_access; 288 WCHAR* debug_desc; 289 bool csum_loaded; 290 LIST_ENTRY extents; 291 ANSI_STRING reparse_xattr; 292 ANSI_STRING ea_xattr; 293 ULONG ealen; 294 LIST_ENTRY hardlinks; 295 struct _file_ref* fileref; 296 bool inode_item_changed; 297 enum prop_compression_type prop_compression; 298 LIST_ENTRY xattrs; 299 bool marked_as_orphan; 300 bool case_sensitive; 301 bool case_sensitive_set; 302 303 LIST_ENTRY dir_children_index; 304 LIST_ENTRY dir_children_hash; 305 LIST_ENTRY dir_children_hash_uc; 306 LIST_ENTRY** hash_ptrs; 307 LIST_ENTRY** hash_ptrs_uc; 308 309 bool dirty; 310 bool sd_dirty, sd_deleted; 311 bool atts_changed, atts_deleted; 312 bool extents_changed; 313 bool reparse_xattr_changed; 314 bool ea_changed; 315 bool prop_compression_changed; 316 bool xattrs_changed; 317 bool created; 318 319 bool ads; 320 uint32_t adshash; 321 ULONG adsmaxlen; 322 ANSI_STRING adsxattr; 323 ANSI_STRING adsdata; 324 325 LIST_ENTRY list_entry; 326 LIST_ENTRY list_entry_all; 327 LIST_ENTRY list_entry_dirty; 328 } fcb; 329 330 typedef struct { 331 ERESOURCE fileref_lock; 332 } file_ref_nonpaged; 333 334 typedef struct _file_ref { 335 fcb* fcb; 336 ANSI_STRING oldutf8; 337 uint64_t oldindex; 338 bool delete_on_close; 339 bool posix_delete; 340 bool deleted; 341 bool created; 342 file_ref_nonpaged* nonpaged; 343 LIST_ENTRY children; 344 LONG refcount; 345 LONG open_count; 346 struct _file_ref* parent; 347 WCHAR* debug_desc; 348 dir_child* dc; 349 350 bool dirty; 351 352 LIST_ENTRY list_entry; 353 LIST_ENTRY list_entry_dirty; 354 } file_ref; 355 356 typedef struct { 357 HANDLE thread; 358 struct _ccb* ccb; 359 void* context; 360 KEVENT cleared_event; 361 bool cancelling; 362 LIST_ENTRY list_entry; 363 } send_info; 364 365 typedef struct _ccb { 366 USHORT NodeType; 367 CSHORT NodeSize; 368 ULONG disposition; 369 ULONG options; 370 uint64_t query_dir_offset; 371 UNICODE_STRING query_string; 372 bool has_wildcard; 373 bool specific_file; 374 bool manage_volume_privilege; 375 bool allow_extended_dasd_io; 376 bool reserving; 377 ACCESS_MASK access; 378 file_ref* fileref; 379 UNICODE_STRING filename; 380 ULONG ea_index; 381 bool case_sensitive; 382 bool user_set_creation_time; 383 bool user_set_access_time; 384 bool user_set_write_time; 385 bool user_set_change_time; 386 bool lxss; 387 send_info* send; 388 NTSTATUS send_status; 389 } ccb; 390 391 struct _device_extension; 392 393 typedef struct { 394 uint64_t address; 395 uint64_t generation; 396 struct _tree* tree; 397 } tree_holder; 398 399 typedef struct _tree_data { 400 KEY key; 401 LIST_ENTRY list_entry; 402 bool ignore; 403 bool inserted; 404 405 union { 406 tree_holder treeholder; 407 408 struct { 409 uint16_t size; 410 uint8_t* data; 411 }; 412 }; 413 } tree_data; 414 415 typedef struct { 416 FAST_MUTEX mutex; 417 } tree_nonpaged; 418 419 typedef struct _tree { 420 tree_nonpaged* nonpaged; 421 tree_header header; 422 uint32_t hash; 423 bool has_address; 424 uint32_t size; 425 struct _device_extension* Vcb; 426 struct _tree* parent; 427 tree_data* paritem; 428 struct _root* root; 429 LIST_ENTRY itemlist; 430 LIST_ENTRY list_entry; 431 LIST_ENTRY list_entry_hash; 432 uint64_t new_address; 433 bool has_new_address; 434 bool updated_extents; 435 bool write; 436 bool is_unique; 437 bool uniqueness_determined; 438 uint8_t* buf; 439 } tree; 440 441 typedef struct { 442 ERESOURCE load_tree_lock; 443 } root_nonpaged; 444 445 typedef struct _root { 446 uint64_t id; 447 LONGLONG lastinode; // signed so we can use InterlockedIncrement64 448 tree_holder treeholder; 449 root_nonpaged* nonpaged; 450 ROOT_ITEM root_item; 451 bool dirty; 452 bool received; 453 PEPROCESS reserved; 454 uint64_t parent; 455 LONG send_ops; 456 uint64_t fcbs_version; 457 bool checked_for_orphans; 458 LIST_ENTRY fcbs; 459 LIST_ENTRY* fcbs_ptrs[256]; 460 LIST_ENTRY list_entry; 461 LIST_ENTRY list_entry_dirty; 462 } root; 463 464 enum batch_operation { 465 Batch_Delete, 466 Batch_DeleteInode, 467 Batch_DeleteDirItem, 468 Batch_DeleteInodeRef, 469 Batch_DeleteInodeExtRef, 470 Batch_DeleteXattr, 471 Batch_DeleteExtentData, 472 Batch_DeleteFreeSpace, 473 Batch_Insert, 474 Batch_SetXattr, 475 Batch_DirItem, 476 Batch_InodeRef, 477 Batch_InodeExtRef, 478 }; 479 480 typedef struct { 481 KEY key; 482 void* data; 483 uint16_t datalen; 484 enum batch_operation operation; 485 LIST_ENTRY list_entry; 486 } batch_item; 487 488 typedef struct { 489 root* r; 490 LIST_ENTRY items; 491 LIST_ENTRY list_entry; 492 } batch_root; 493 494 typedef struct { 495 tree* tree; 496 tree_data* item; 497 } traverse_ptr; 498 499 typedef struct _root_cache { 500 root* root; 501 struct _root_cache* next; 502 } root_cache; 503 504 typedef struct { 505 uint64_t address; 506 uint64_t size; 507 LIST_ENTRY list_entry; 508 LIST_ENTRY list_entry_size; 509 } space; 510 511 typedef struct { 512 PDEVICE_OBJECT devobj; 513 PFILE_OBJECT fileobj; 514 DEV_ITEM devitem; 515 bool removable; 516 bool seeding; 517 bool readonly; 518 bool reloc; 519 bool trim; 520 bool can_flush; 521 ULONG change_count; 522 ULONG disk_num; 523 ULONG part_num; 524 uint64_t stats[5]; 525 bool stats_changed; 526 LIST_ENTRY space; 527 LIST_ENTRY list_entry; 528 ULONG num_trim_entries; 529 LIST_ENTRY trim_list; 530 } device; 531 532 typedef struct { 533 uint64_t start; 534 uint64_t length; 535 PETHREAD thread; 536 LIST_ENTRY list_entry; 537 } range_lock; 538 539 typedef struct { 540 uint64_t address; 541 ULONG* bmparr; 542 ULONG bmplen; 543 RTL_BITMAP bmp; 544 LIST_ENTRY list_entry; 545 uint8_t data[1]; 546 } partial_stripe; 547 548 typedef struct { 549 CHUNK_ITEM* chunk_item; 550 uint16_t size; 551 uint64_t offset; 552 uint64_t used; 553 uint64_t oldused; 554 device** devices; 555 fcb* cache; 556 fcb* old_cache; 557 LIST_ENTRY space; 558 LIST_ENTRY space_size; 559 LIST_ENTRY deleting; 560 LIST_ENTRY changed_extents; 561 LIST_ENTRY range_locks; 562 ERESOURCE range_locks_lock; 563 KEVENT range_locks_event; 564 ERESOURCE lock; 565 ERESOURCE changed_extents_lock; 566 bool created; 567 bool readonly; 568 bool reloc; 569 bool last_alloc_set; 570 bool cache_loaded; 571 bool changed; 572 bool space_changed; 573 uint64_t last_alloc; 574 uint16_t last_stripe; 575 LIST_ENTRY partial_stripes; 576 ERESOURCE partial_stripes_lock; 577 ULONG balance_num; 578 579 LIST_ENTRY list_entry; 580 LIST_ENTRY list_entry_balance; 581 } chunk; 582 583 typedef struct { 584 uint64_t address; 585 uint64_t size; 586 uint64_t old_size; 587 uint64_t count; 588 uint64_t old_count; 589 bool no_csum; 590 bool superseded; 591 LIST_ENTRY refs; 592 LIST_ENTRY old_refs; 593 LIST_ENTRY list_entry; 594 } changed_extent; 595 596 typedef struct { 597 uint8_t type; 598 599 union { 600 EXTENT_DATA_REF edr; 601 SHARED_DATA_REF sdr; 602 }; 603 604 LIST_ENTRY list_entry; 605 } changed_extent_ref; 606 607 typedef struct { 608 KEY key; 609 void* data; 610 USHORT size; 611 LIST_ENTRY list_entry; 612 } sys_chunk; 613 614 typedef struct { 615 uint8_t* data; 616 uint32_t* csum; 617 uint32_t sectors; 618 LONG pos, done; 619 KEVENT event; 620 LONG refcount; 621 LIST_ENTRY list_entry; 622 } calc_job; 623 624 typedef struct { 625 PDEVICE_OBJECT DeviceObject; 626 HANDLE handle; 627 KEVENT finished; 628 bool quit; 629 } drv_calc_thread; 630 631 typedef struct { 632 ULONG num_threads; 633 LIST_ENTRY job_list; 634 ERESOURCE lock; 635 drv_calc_thread* threads; 636 KEVENT event; 637 } drv_calc_threads; 638 639 typedef struct { 640 bool ignore; 641 bool compress; 642 bool compress_force; 643 uint8_t compress_type; 644 bool readonly; 645 uint32_t zlib_level; 646 uint32_t zstd_level; 647 uint32_t flush_interval; 648 uint32_t max_inline; 649 uint64_t subvol_id; 650 bool skip_balance; 651 bool no_barrier; 652 bool no_trim; 653 bool clear_cache; 654 bool allow_degraded; 655 } mount_options; 656 657 #define VCB_TYPE_FS 1 658 #define VCB_TYPE_CONTROL 2 659 #define VCB_TYPE_VOLUME 3 660 #define VCB_TYPE_PDO 4 661 #define VCB_TYPE_BUS 5 662 663 #define BALANCE_OPTS_DATA 0 664 #define BALANCE_OPTS_METADATA 1 665 #define BALANCE_OPTS_SYSTEM 2 666 667 typedef struct { 668 HANDLE thread; 669 uint64_t total_chunks; 670 uint64_t chunks_left; 671 btrfs_balance_opts opts[3]; 672 bool paused; 673 bool stopping; 674 bool removing; 675 bool shrinking; 676 bool dev_readonly; 677 ULONG balance_num; 678 NTSTATUS status; 679 KEVENT event; 680 KEVENT finished; 681 } balance_info; 682 683 typedef struct { 684 uint64_t address; 685 uint64_t device; 686 bool recovered; 687 bool is_metadata; 688 bool parity; 689 LIST_ENTRY list_entry; 690 691 union { 692 struct { 693 uint64_t subvol; 694 uint64_t offset; 695 uint16_t filename_length; 696 WCHAR filename[1]; 697 } data; 698 699 struct { 700 uint64_t root; 701 uint8_t level; 702 KEY firstitem; 703 } metadata; 704 }; 705 } scrub_error; 706 707 typedef struct { 708 HANDLE thread; 709 ERESOURCE stats_lock; 710 KEVENT event; 711 KEVENT finished; 712 bool stopping; 713 bool paused; 714 LARGE_INTEGER start_time; 715 LARGE_INTEGER finish_time; 716 LARGE_INTEGER resume_time; 717 LARGE_INTEGER duration; 718 uint64_t total_chunks; 719 uint64_t chunks_left; 720 uint64_t data_scrubbed; 721 NTSTATUS error; 722 ULONG num_errors; 723 LIST_ENTRY errors; 724 } scrub_info; 725 726 struct _volume_device_extension; 727 728 typedef struct _device_extension { 729 uint32_t type; 730 mount_options options; 731 PVPB Vpb; 732 struct _volume_device_extension* vde; 733 LIST_ENTRY devices; 734 #ifdef DEBUG_CHUNK_LOCKS 735 LONG chunk_locks_held; 736 #endif 737 uint64_t devices_loaded; 738 superblock superblock; 739 bool readonly; 740 bool removing; 741 bool locked; 742 bool lock_paused_balance; 743 bool disallow_dismount; 744 LONG page_file_count; 745 bool trim; 746 PFILE_OBJECT locked_fileobj; 747 fcb* volume_fcb; 748 fcb* dummy_fcb; 749 file_ref* root_fileref; 750 LONG open_files; 751 _Has_lock_level_(fcb_lock) ERESOURCE fcb_lock; 752 ERESOURCE fileref_lock; 753 ERESOURCE load_lock; 754 _Has_lock_level_(tree_lock) ERESOURCE tree_lock; 755 PNOTIFY_SYNC NotifySync; 756 LIST_ENTRY DirNotifyList; 757 bool need_write; 758 bool stats_changed; 759 uint64_t data_flags; 760 uint64_t metadata_flags; 761 uint64_t system_flags; 762 LIST_ENTRY roots; 763 LIST_ENTRY drop_roots; 764 root* chunk_root; 765 root* root_root; 766 root* extent_root; 767 root* checksum_root; 768 root* dev_root; 769 root* uuid_root; 770 root* data_reloc_root; 771 root* space_root; 772 bool log_to_phys_loaded; 773 bool chunk_usage_found; 774 LIST_ENTRY sys_chunks; 775 LIST_ENTRY chunks; 776 LIST_ENTRY trees; 777 LIST_ENTRY trees_hash; 778 LIST_ENTRY* trees_ptrs[256]; 779 FAST_MUTEX trees_list_mutex; 780 LIST_ENTRY all_fcbs; 781 LIST_ENTRY dirty_fcbs; 782 ERESOURCE dirty_fcbs_lock; 783 LIST_ENTRY dirty_filerefs; 784 ERESOURCE dirty_filerefs_lock; 785 LIST_ENTRY dirty_subvols; 786 ERESOURCE dirty_subvols_lock; 787 ERESOURCE chunk_lock; 788 HANDLE flush_thread_handle; 789 KTIMER flush_thread_timer; 790 KEVENT flush_thread_finished; 791 drv_calc_threads calcthreads; 792 balance_info balance; 793 scrub_info scrub; 794 ERESOURCE send_load_lock; 795 LONG running_sends; 796 LIST_ENTRY send_ops; 797 PFILE_OBJECT root_file; 798 PAGED_LOOKASIDE_LIST tree_data_lookaside; 799 PAGED_LOOKASIDE_LIST traverse_ptr_lookaside; 800 PAGED_LOOKASIDE_LIST batch_item_lookaside; 801 PAGED_LOOKASIDE_LIST fileref_lookaside; 802 PAGED_LOOKASIDE_LIST fcb_lookaside; 803 PAGED_LOOKASIDE_LIST name_bit_lookaside; 804 NPAGED_LOOKASIDE_LIST range_lock_lookaside; 805 NPAGED_LOOKASIDE_LIST fileref_np_lookaside; 806 NPAGED_LOOKASIDE_LIST fcb_np_lookaside; 807 LIST_ENTRY list_entry; 808 } device_extension; 809 810 typedef struct { 811 uint32_t type; 812 } control_device_extension; 813 814 typedef struct { 815 uint32_t type; 816 PDEVICE_OBJECT buspdo; 817 PDEVICE_OBJECT attached_device; 818 UNICODE_STRING bus_name; 819 } bus_device_extension; 820 821 typedef struct { 822 BTRFS_UUID uuid; 823 uint64_t devid; 824 uint64_t generation; 825 PDEVICE_OBJECT devobj; 826 PFILE_OBJECT fileobj; 827 UNICODE_STRING pnp_name; 828 uint64_t size; 829 bool seeding; 830 bool had_drive_letter; 831 void* notification_entry; 832 ULONG disk_num; 833 ULONG part_num; 834 LIST_ENTRY list_entry; 835 } volume_child; 836 837 struct pdo_device_extension; 838 839 typedef struct _volume_device_extension { 840 uint32_t type; 841 UNICODE_STRING name; 842 PDEVICE_OBJECT device; 843 PDEVICE_OBJECT mounted_device; 844 PDEVICE_OBJECT pdo; 845 struct pdo_device_extension* pdode; 846 UNICODE_STRING bus_name; 847 PDEVICE_OBJECT attached_device; 848 bool removing; 849 LONG open_count; 850 } volume_device_extension; 851 852 typedef struct pdo_device_extension { 853 uint32_t type; 854 BTRFS_UUID uuid; 855 volume_device_extension* vde; 856 PDEVICE_OBJECT pdo; 857 bool removable; 858 859 uint64_t num_children; 860 uint64_t children_loaded; 861 ERESOURCE child_lock; 862 LIST_ENTRY children; 863 864 LIST_ENTRY list_entry; 865 } pdo_device_extension; 866 867 typedef struct { 868 LIST_ENTRY listentry; 869 PSID sid; 870 uint32_t uid; 871 } uid_map; 872 873 typedef struct { 874 LIST_ENTRY listentry; 875 PSID sid; 876 uint32_t gid; 877 } gid_map; 878 879 enum write_data_status { 880 WriteDataStatus_Pending, 881 WriteDataStatus_Success, 882 WriteDataStatus_Error, 883 WriteDataStatus_Cancelling, 884 WriteDataStatus_Cancelled, 885 WriteDataStatus_Ignore 886 }; 887 888 struct _write_data_context; 889 890 typedef struct { 891 struct _write_data_context* context; 892 uint8_t* buf; 893 PMDL mdl; 894 device* device; 895 PIRP Irp; 896 IO_STATUS_BLOCK iosb; 897 enum write_data_status status; 898 LIST_ENTRY list_entry; 899 } write_data_stripe; 900 901 typedef struct _write_data_context { 902 KEVENT Event; 903 LIST_ENTRY stripes; 904 LONG stripes_left; 905 bool need_wait; 906 uint8_t *parity1, *parity2, *scratch; 907 PMDL mdl, parity1_mdl, parity2_mdl; 908 } write_data_context; 909 910 typedef struct { 911 uint64_t address; 912 uint32_t length; 913 uint8_t* data; 914 chunk* c; 915 LIST_ENTRY list_entry; 916 } tree_write; 917 918 typedef struct { 919 UNICODE_STRING us; 920 LIST_ENTRY list_entry; 921 } name_bit; 922 923 _Requires_lock_not_held_(Vcb->fcb_lock) 924 _Acquires_shared_lock_(Vcb->fcb_lock) 925 static __inline void acquire_fcb_lock_shared(device_extension* Vcb) { 926 ExAcquireResourceSharedLite(&Vcb->fcb_lock, true); 927 } 928 929 _Requires_lock_not_held_(Vcb->fcb_lock) 930 _Acquires_exclusive_lock_(Vcb->fcb_lock) 931 static __inline void acquire_fcb_lock_exclusive(device_extension* Vcb) { 932 ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, true); 933 } 934 935 _Requires_lock_held_(Vcb->fcb_lock) 936 _Releases_lock_(Vcb->fcb_lock) 937 static __inline void release_fcb_lock(device_extension* Vcb) { 938 ExReleaseResourceLite(&Vcb->fcb_lock); 939 } 940 941 static __inline void* map_user_buffer(PIRP Irp, ULONG priority) { 942 if (!Irp->MdlAddress) { 943 return Irp->UserBuffer; 944 } else { 945 return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, priority); 946 } 947 } 948 949 static __inline uint64_t unix_time_to_win(BTRFS_TIME* t) { 950 return (t->seconds * 10000000) + (t->nanoseconds / 100) + 116444736000000000; 951 } 952 953 static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME* out) { 954 ULONGLONG l = (ULONGLONG)t.QuadPart - 116444736000000000; 955 956 out->seconds = l / 10000000; 957 out->nanoseconds = (uint32_t)((l % 10000000) * 100); 958 } 959 960 _Post_satisfies_(*stripe>=0&&*stripe<num_stripes) 961 static __inline void get_raid0_offset(_In_ uint64_t off, _In_ uint64_t stripe_length, _In_ uint16_t num_stripes, _Out_ uint64_t* stripeoff, _Out_ uint16_t* stripe) { 962 uint64_t initoff, startoff; 963 964 startoff = off % (num_stripes * stripe_length); 965 initoff = (off / (num_stripes * stripe_length)) * stripe_length; 966 967 *stripe = (uint16_t)(startoff / stripe_length); 968 *stripeoff = initoff + startoff - (*stripe * stripe_length); 969 } 970 971 /* We only have 64 bits for a file ID, which isn't technically enough to be 972 * unique on Btrfs. We fudge it by having three bytes for the subvol and 973 * five for the inode, which should be good enough. 974 * Inodes are also 64 bits on Linux, but the Linux driver seems to get round 975 * this by tricking it into thinking subvols are separate volumes. */ 976 static __inline uint64_t make_file_id(root* r, uint64_t inode) { 977 return (r->id << 40) | (inode & 0xffffffffff); 978 } 979 980 #define keycmp(key1, key2)\ 981 ((key1.obj_id < key2.obj_id) ? -1 :\ 982 ((key1.obj_id > key2.obj_id) ? 1 :\ 983 ((key1.obj_type < key2.obj_type) ? -1 :\ 984 ((key1.obj_type > key2.obj_type) ? 1 :\ 985 ((key1.offset < key2.offset) ? -1 :\ 986 ((key1.offset > key2.offset) ? 1 :\ 987 0)))))) 988 989 _Post_satisfies_(return>=n) 990 __inline static uint64_t sector_align(_In_ uint64_t n, _In_ uint64_t a) { 991 if (n & (a - 1)) 992 n = (n + a) & ~(a - 1); 993 994 return n; 995 } 996 997 __inline static bool is_subvol_readonly(root* r, PIRP Irp) { 998 if (!(r->root_item.flags & BTRFS_SUBVOL_READONLY)) 999 return false; 1000 1001 if (!r->reserved) 1002 return true; 1003 1004 return (!Irp || Irp->RequestorMode == UserMode) && PsGetCurrentProcess() != r->reserved ? true : false; 1005 } 1006 1007 __inline static uint16_t get_extent_data_len(uint8_t type) { 1008 switch (type) { 1009 case TYPE_TREE_BLOCK_REF: 1010 return sizeof(TREE_BLOCK_REF); 1011 1012 case TYPE_EXTENT_DATA_REF: 1013 return sizeof(EXTENT_DATA_REF); 1014 1015 case TYPE_EXTENT_REF_V0: 1016 return sizeof(EXTENT_REF_V0); 1017 1018 case TYPE_SHARED_BLOCK_REF: 1019 return sizeof(SHARED_BLOCK_REF); 1020 1021 case TYPE_SHARED_DATA_REF: 1022 return sizeof(SHARED_DATA_REF); 1023 1024 default: 1025 return 0; 1026 } 1027 } 1028 1029 __inline static uint32_t get_extent_data_refcount(uint8_t type, void* data) { 1030 switch (type) { 1031 case TYPE_TREE_BLOCK_REF: 1032 return 1; 1033 1034 case TYPE_EXTENT_DATA_REF: 1035 { 1036 EXTENT_DATA_REF* edr = (EXTENT_DATA_REF*)data; 1037 return edr->count; 1038 } 1039 1040 case TYPE_EXTENT_REF_V0: 1041 { 1042 EXTENT_REF_V0* erv0 = (EXTENT_REF_V0*)data; 1043 return erv0->count; 1044 } 1045 1046 case TYPE_SHARED_BLOCK_REF: 1047 return 1; 1048 1049 case TYPE_SHARED_DATA_REF: 1050 { 1051 SHARED_DATA_REF* sdr = (SHARED_DATA_REF*)data; 1052 return sdr->count; 1053 } 1054 1055 default: 1056 return 0; 1057 } 1058 } 1059 1060 // in btrfs.c 1061 _Ret_maybenull_ 1062 device* find_device_from_uuid(_In_ device_extension* Vcb, _In_ BTRFS_UUID* uuid); 1063 1064 _Success_(return) 1065 bool get_file_attributes_from_xattr(_In_reads_bytes_(len) char* val, _In_ uint16_t len, _Out_ ULONG* atts); 1066 1067 ULONG get_file_attributes(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _In_ root* r, _In_ uint64_t inode, 1068 _In_ uint8_t type, _In_ bool dotfile, _In_ bool ignore_xa, _In_opt_ PIRP Irp); 1069 1070 _Success_(return) 1071 bool get_xattr(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _In_ root* subvol, _In_ uint64_t inode, _In_z_ char* name, _In_ uint32_t crc32, 1072 _Out_ uint8_t** data, _Out_ uint16_t* datalen, _In_opt_ PIRP Irp); 1073 1074 #ifndef DEBUG_FCB_REFCOUNTS 1075 void free_fcb(_Inout_ fcb* fcb); 1076 #endif 1077 void free_fileref(_Inout_ file_ref* fr); 1078 void protect_superblocks(_Inout_ chunk* c); 1079 bool is_top_level(_In_ PIRP Irp); 1080 NTSTATUS create_root(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _In_ uint64_t id, 1081 _Out_ root** rootptr, _In_ bool no_tree, _In_ uint64_t offset, _In_opt_ PIRP Irp); 1082 void uninit(_In_ device_extension* Vcb); 1083 NTSTATUS dev_ioctl(_In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG ControlCode, _In_reads_bytes_opt_(InputBufferSize) PVOID InputBuffer, _In_ ULONG InputBufferSize, 1084 _Out_writes_bytes_opt_(OutputBufferSize) PVOID OutputBuffer, _In_ ULONG OutputBufferSize, _In_ bool Override, _Out_opt_ IO_STATUS_BLOCK* iosb); 1085 bool is_file_name_valid(_In_ PUNICODE_STRING us, _In_ bool posix); 1086 void send_notification_fileref(_In_ file_ref* fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream); 1087 void send_notification_fcb(_In_ file_ref* fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream); 1088 1089 #ifdef DEBUG_CHUNK_LOCKS 1090 #define acquire_chunk_lock(c, Vcb) { ExAcquireResourceExclusiveLite(&c->lock, true); InterlockedIncrement(&Vcb->chunk_locks_held); } 1091 #define release_chunk_lock(c, Vcb) { InterlockedDecrement(&Vcb->chunk_locks_held); ExReleaseResourceLite(&c->lock); } 1092 #else 1093 #define acquire_chunk_lock(c, Vcb) ExAcquireResourceExclusiveLite(&(c)->lock, true) 1094 #define release_chunk_lock(c, Vcb) ExReleaseResourceLite(&(c)->lock) 1095 #endif 1096 1097 _Ret_z_ 1098 WCHAR* file_desc(_In_ PFILE_OBJECT FileObject); 1099 WCHAR* file_desc_fileref(_In_ file_ref* fileref); 1100 void mark_fcb_dirty(_In_ fcb* fcb); 1101 void mark_fileref_dirty(_In_ file_ref* fileref); 1102 NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT FileObject, _In_ bool make_orphan, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback); 1103 void chunk_lock_range(_In_ device_extension* Vcb, _In_ chunk* c, _In_ uint64_t start, _In_ uint64_t length); 1104 void chunk_unlock_range(_In_ device_extension* Vcb, _In_ chunk* c, _In_ uint64_t start, _In_ uint64_t length); 1105 void init_device(_In_ device_extension* Vcb, _Inout_ device* dev, _In_ bool get_nums); 1106 void init_file_cache(_In_ PFILE_OBJECT FileObject, _In_ CC_FILE_SIZES* ccfs); 1107 NTSTATUS sync_read_phys(_In_ PDEVICE_OBJECT DeviceObject, _In_ PFILE_OBJECT FileObject, _In_ uint64_t StartingOffset, _In_ ULONG Length, 1108 _Out_writes_bytes_(Length) PUCHAR Buffer, _In_ bool override); 1109 NTSTATUS get_device_pnp_name(_In_ PDEVICE_OBJECT DeviceObject, _Out_ PUNICODE_STRING pnp_name, _Out_ const GUID** guid); 1110 void log_device_error(_In_ device_extension* Vcb, _Inout_ device* dev, _In_ int error); 1111 NTSTATUS find_chunk_usage(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _In_opt_ PIRP Irp); 1112 1113 _Function_class_(DRIVER_ADD_DEVICE) 1114 NTSTATUS __stdcall AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject); 1115 1116 void reap_fcb(fcb* fcb); 1117 void reap_fcbs(device_extension* Vcb); 1118 void reap_fileref(device_extension* Vcb, file_ref* fr); 1119 void reap_filerefs(device_extension* Vcb, file_ref* fr); 1120 uint64_t chunk_estimate_phys_size(device_extension* Vcb, chunk* c, uint64_t u); 1121 NTSTATUS utf8_to_utf16(WCHAR* dest, ULONG dest_max, ULONG* dest_len, char* src, ULONG src_len); 1122 NTSTATUS utf16_to_utf8(char* dest, ULONG dest_max, ULONG* dest_len, WCHAR* src, ULONG src_len); 1123 uint32_t get_num_of_processors(); 1124 1125 #ifdef _MSC_VER 1126 #define funcname __FUNCTION__ 1127 #else 1128 #define funcname __func__ 1129 #endif 1130 1131 extern bool have_sse2; 1132 1133 extern uint32_t mount_compress; 1134 extern uint32_t mount_compress_force; 1135 extern uint32_t mount_compress_type; 1136 extern uint32_t mount_zlib_level; 1137 extern uint32_t mount_zstd_level; 1138 extern uint32_t mount_flush_interval; 1139 extern uint32_t mount_max_inline; 1140 extern uint32_t mount_skip_balance; 1141 extern uint32_t mount_no_barrier; 1142 extern uint32_t mount_no_trim; 1143 extern uint32_t mount_clear_cache; 1144 extern uint32_t mount_allow_degraded; 1145 extern uint32_t mount_readonly; 1146 extern uint32_t no_pnp; 1147 1148 #ifdef _DEBUG 1149 1150 extern bool log_started; 1151 extern uint32_t debug_log_level; 1152 1153 #ifdef DEBUG_LONG_MESSAGES 1154 1155 #define MSG(fn, file, line, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, file, line, s, ##__VA_ARGS__) : 0 1156 1157 #define TRACE(s, ...) MSG(funcname, __FILE__, __LINE__, s, 3, ##__VA_ARGS__) 1158 #define WARN(s, ...) MSG(funcname, __FILE__, __LINE__, s, 2, ##__VA_ARGS__) 1159 #define FIXME(s, ...) MSG(funcname, __FILE__, __LINE__, s, 1, ##__VA_ARGS__) 1160 #define ERR(s, ...) MSG(funcname, __FILE__, __LINE__, s, 1, ##__VA_ARGS__) 1161 1162 void _debug_message(_In_ const char* func, _In_ const char* file, _In_ unsigned int line, _In_ char* s, ...); 1163 1164 #else 1165 1166 #define MSG(fn, s, level, ...) (!log_started || level <= debug_log_level) ? _debug_message(fn, s, ##__VA_ARGS__) : 0 1167 1168 #define TRACE(s, ...) MSG(funcname, s, 3, ##__VA_ARGS__) 1169 #define WARN(s, ...) MSG(funcname, s, 2, ##__VA_ARGS__) 1170 #define FIXME(s, ...) MSG(funcname, s, 1, ##__VA_ARGS__) 1171 #define ERR(s, ...) MSG(funcname, s, 1, ##__VA_ARGS__) 1172 1173 void _debug_message(_In_ const char* func, _In_ char* s, ...); 1174 1175 #endif 1176 1177 #else 1178 1179 #define TRACE(s, ...) 1180 #define WARN(s, ...) 1181 #define FIXME(s, ...) DbgPrint("Btrfs FIXME : %s : " s, funcname, ##__VA_ARGS__) 1182 #define ERR(s, ...) DbgPrint("Btrfs ERR : %s : " s, funcname, ##__VA_ARGS__) 1183 1184 #endif 1185 1186 #ifdef DEBUG_FCB_REFCOUNTS 1187 void _free_fcb(_Inout_ fcb* fcb, _In_ const char* func); 1188 #define free_fcb(fcb) _free_fcb(fcb, funcname) 1189 #endif 1190 1191 // in fastio.c 1192 void init_fast_io_dispatch(FAST_IO_DISPATCH** fiod); 1193 1194 // in crc32c.c 1195 uint32_t calc_crc32c(_In_ uint32_t seed, _In_reads_bytes_(msglen) uint8_t* msg, _In_ ULONG msglen); 1196 1197 typedef struct { 1198 LIST_ENTRY* list; 1199 LIST_ENTRY* list_size; 1200 uint64_t address; 1201 uint64_t length; 1202 chunk* chunk; 1203 } rollback_space; 1204 1205 typedef struct { 1206 fcb* fcb; 1207 extent* ext; 1208 } rollback_extent; 1209 1210 enum rollback_type { 1211 ROLLBACK_INSERT_EXTENT, 1212 ROLLBACK_DELETE_EXTENT, 1213 ROLLBACK_ADD_SPACE, 1214 ROLLBACK_SUBTRACT_SPACE 1215 }; 1216 1217 typedef struct { 1218 enum rollback_type type; 1219 void* ptr; 1220 LIST_ENTRY list_entry; 1221 } rollback_item; 1222 1223 typedef struct { 1224 ANSI_STRING name; 1225 ANSI_STRING value; 1226 UCHAR flags; 1227 LIST_ENTRY list_entry; 1228 } ea_item; 1229 1230 static const char lxuid[] = "$LXUID"; 1231 static const char lxgid[] = "$LXGID"; 1232 static const char lxmod[] = "$LXMOD"; 1233 static const char lxdev[] = "$LXDEV"; 1234 1235 // in treefuncs.c 1236 NTSTATUS find_item(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _In_ root* r, _Out_ traverse_ptr* tp, 1237 _In_ const KEY* searchkey, _In_ bool ignore, _In_opt_ PIRP Irp); 1238 NTSTATUS find_item_to_level(device_extension* Vcb, root* r, traverse_ptr* tp, const KEY* searchkey, bool ignore, uint8_t level, PIRP Irp); 1239 bool find_next_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, const traverse_ptr* tp, traverse_ptr* next_tp, bool ignore, PIRP Irp); 1240 bool find_prev_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, const traverse_ptr* tp, traverse_ptr* prev_tp, PIRP Irp); 1241 void free_trees(device_extension* Vcb); 1242 NTSTATUS insert_tree_item(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _In_ root* r, _In_ uint64_t obj_id, 1243 _In_ uint8_t obj_type, _In_ uint64_t offset, _In_reads_bytes_opt_(size) _When_(return >= 0, __drv_aliasesMem) void* data, 1244 _In_ uint16_t size, _Out_opt_ traverse_ptr* ptp, _In_opt_ PIRP Irp); 1245 NTSTATUS delete_tree_item(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension* Vcb, _Inout_ traverse_ptr* tp); 1246 void free_tree(tree* t); 1247 NTSTATUS load_tree(device_extension* Vcb, uint64_t addr, uint8_t* buf, root* r, tree** pt); 1248 NTSTATUS do_load_tree(device_extension* Vcb, tree_holder* th, root* r, tree* t, tree_data* td, PIRP Irp); 1249 void clear_rollback(LIST_ENTRY* rollback); 1250 void do_rollback(device_extension* Vcb, LIST_ENTRY* rollback); 1251 void free_trees_root(device_extension* Vcb, root* r); 1252 void add_rollback(_In_ LIST_ENTRY* rollback, _In_ enum rollback_type type, _In_ __drv_aliasesMem void* ptr); 1253 NTSTATUS commit_batch_list(_Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension* Vcb, LIST_ENTRY* batchlist, PIRP Irp); 1254 void clear_batch_list(device_extension* Vcb, LIST_ENTRY* batchlist); 1255 NTSTATUS skip_to_difference(device_extension* Vcb, traverse_ptr* tp, traverse_ptr* tp2, bool* ended1, bool* ended2); 1256 1257 // in search.c 1258 NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath); 1259 1260 _Function_class_(KSTART_ROUTINE) 1261 void __stdcall mountmgr_thread(_In_ void* context); 1262 1263 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE) 1264 NTSTATUS __stdcall pnp_notification(PVOID NotificationStructure, PVOID Context); 1265 1266 void disk_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath); 1267 void volume_arrival(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath); 1268 void volume_removal(PDRIVER_OBJECT DriverObject, PUNICODE_STRING devpath); 1269 1270 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE) 1271 NTSTATUS __stdcall volume_notification(PVOID NotificationStructure, PVOID Context); 1272 1273 void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lock) _Releases_exclusive_lock_(_Curr_->child_lock) _In_ volume_device_extension* vde, 1274 _In_ volume_child* vc, _In_ bool skip_dev); 1275 1276 // in cache.c 1277 NTSTATUS init_cache(); 1278 void free_cache(); 1279 extern CACHE_MANAGER_CALLBACKS* cache_callbacks; 1280 1281 // in write.c 1282 NTSTATUS write_file(device_extension* Vcb, PIRP Irp, bool wait, bool deferred_write); 1283 NTSTATUS write_file2(device_extension* Vcb, PIRP Irp, LARGE_INTEGER offset, void* buf, ULONG* length, bool paging_io, bool no_cache, 1284 bool wait, bool deferred_write, bool write_irp, LIST_ENTRY* rollback); 1285 NTSTATUS truncate_file(fcb* fcb, uint64_t end, PIRP Irp, LIST_ENTRY* rollback); 1286 NTSTATUS extend_file(fcb* fcb, file_ref* fileref, uint64_t end, bool prealloc, PIRP Irp, LIST_ENTRY* rollback); 1287 NTSTATUS excise_extents(device_extension* Vcb, fcb* fcb, uint64_t start_data, uint64_t end_data, PIRP Irp, LIST_ENTRY* rollback); 1288 chunk* get_chunk_from_address(device_extension* Vcb, uint64_t address); 1289 NTSTATUS alloc_chunk(device_extension* Vcb, uint64_t flags, chunk** pc, bool full_size); 1290 NTSTATUS write_data(_In_ device_extension* Vcb, _In_ uint64_t address, _In_reads_bytes_(length) void* data, _In_ uint32_t length, _In_ write_data_context* wtc, 1291 _In_opt_ PIRP Irp, _In_opt_ chunk* c, _In_ bool file_write, _In_ uint64_t irp_offset, _In_ ULONG priority); 1292 NTSTATUS write_data_complete(device_extension* Vcb, uint64_t address, void* data, uint32_t length, PIRP Irp, chunk* c, bool file_write, uint64_t irp_offset, ULONG priority); 1293 void free_write_data_stripes(write_data_context* wtc); 1294 1295 _Dispatch_type_(IRP_MJ_WRITE) 1296 _Function_class_(DRIVER_DISPATCH) 1297 NTSTATUS __stdcall drv_write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1298 1299 _Requires_lock_held_(c->lock) 1300 _When_(return != 0, _Releases_lock_(c->lock)) 1301 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, 1302 _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); 1303 1304 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); 1305 NTSTATUS write_compressed(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, PIRP Irp, LIST_ENTRY* rollback); 1306 bool find_data_address_in_chunk(device_extension* Vcb, chunk* c, uint64_t length, uint64_t* address); 1307 void get_raid56_lock_range(chunk* c, uint64_t address, uint64_t length, uint64_t* lockaddr, uint64_t* locklen); 1308 NTSTATUS calc_csum(_In_ device_extension* Vcb, _In_reads_bytes_(sectors*Vcb->superblock.sector_size) uint8_t* data, 1309 _In_ uint32_t sectors, _Out_writes_bytes_(sectors*sizeof(uint32_t)) uint32_t* csum); 1310 void add_insert_extent_rollback(LIST_ENTRY* rollback, fcb* fcb, extent* ext); 1311 NTSTATUS add_extent_to_fcb(_In_ fcb* fcb, _In_ uint64_t offset, _In_reads_bytes_(edsize) EXTENT_DATA* ed, _In_ uint16_t edsize, 1312 _In_ bool unique, _In_opt_ _When_(return >= 0, __drv_aliasesMem) uint32_t* csum, _In_ LIST_ENTRY* rollback); 1313 void add_extent(_In_ fcb* fcb, _In_ LIST_ENTRY* prevextle, _In_ __drv_aliasesMem extent* newext); 1314 1315 // in dirctrl.c 1316 1317 _Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL) 1318 _Function_class_(DRIVER_DISPATCH) 1319 NTSTATUS __stdcall drv_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1320 1321 ULONG get_reparse_tag(device_extension* Vcb, root* subvol, uint64_t inode, uint8_t type, ULONG atts, bool lxss, PIRP Irp); 1322 ULONG get_reparse_tag_fcb(fcb* fcb); 1323 1324 // in security.c 1325 1326 _Dispatch_type_(IRP_MJ_QUERY_SECURITY) 1327 _Function_class_(DRIVER_DISPATCH) 1328 NTSTATUS __stdcall drv_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1329 1330 _Dispatch_type_(IRP_MJ_SET_SECURITY) 1331 _Function_class_(DRIVER_DISPATCH) 1332 NTSTATUS __stdcall drv_set_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1333 1334 void fcb_get_sd(fcb* fcb, struct _fcb* parent, bool look_for_xattr, PIRP Irp); 1335 void add_user_mapping(WCHAR* sidstring, ULONG sidstringlength, uint32_t uid); 1336 void add_group_mapping(WCHAR* sidstring, ULONG sidstringlength, uint32_t gid); 1337 uint32_t sid_to_uid(PSID sid); 1338 NTSTATUS uid_to_sid(uint32_t uid, PSID* sid); 1339 NTSTATUS fcb_get_new_sd(fcb* fcb, file_ref* parfileref, ACCESS_STATE* as); 1340 void find_gid(struct _fcb* fcb, struct _fcb* parfcb, PSECURITY_SUBJECT_CONTEXT subjcont); 1341 1342 // in fileinfo.c 1343 1344 _Dispatch_type_(IRP_MJ_SET_INFORMATION) 1345 _Function_class_(DRIVER_DISPATCH) 1346 NTSTATUS __stdcall drv_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1347 1348 _Dispatch_type_(IRP_MJ_QUERY_INFORMATION) 1349 _Function_class_(DRIVER_DISPATCH) 1350 NTSTATUS __stdcall drv_query_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1351 1352 _Dispatch_type_(IRP_MJ_QUERY_EA) 1353 _Function_class_(DRIVER_DISPATCH) 1354 NTSTATUS __stdcall drv_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1355 1356 _Dispatch_type_(IRP_MJ_SET_EA) 1357 _Function_class_(DRIVER_DISPATCH) 1358 NTSTATUS __stdcall drv_set_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1359 1360 bool has_open_children(file_ref* fileref); 1361 NTSTATUS stream_set_end_of_file_information(device_extension* Vcb, uint16_t end, fcb* fcb, file_ref* fileref, bool advance_only); 1362 NTSTATUS fileref_get_filename(file_ref* fileref, PUNICODE_STRING fn, USHORT* name_offset, ULONG* preqlen); 1363 void insert_dir_child_into_hash_lists(fcb* fcb, dir_child* dc); 1364 void remove_dir_child_from_hash_lists(fcb* fcb, dir_child* dc); 1365 1366 // in reparse.c 1367 NTSTATUS get_reparse_point(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, void* buffer, DWORD buflen, ULONG_PTR* retlen); 1368 NTSTATUS set_reparse_point2(fcb* fcb, REPARSE_DATA_BUFFER* rdb, ULONG buflen, ccb* ccb, file_ref* fileref, PIRP Irp, LIST_ENTRY* rollback); 1369 NTSTATUS set_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp); 1370 NTSTATUS delete_reparse_point(PDEVICE_OBJECT DeviceObject, PIRP Irp); 1371 1372 // in create.c 1373 1374 _Dispatch_type_(IRP_MJ_CREATE) 1375 _Function_class_(DRIVER_DISPATCH) 1376 NTSTATUS __stdcall drv_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1377 1378 NTSTATUS open_fileref(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension* Vcb, _Out_ file_ref** pfr, 1379 _In_ PUNICODE_STRING fnus, _In_opt_ file_ref* related, _In_ bool parent, _Out_opt_ USHORT* parsed, _Out_opt_ ULONG* fn_offset, _In_ POOL_TYPE pooltype, 1380 _In_ bool case_sensitive, _In_opt_ PIRP Irp); 1381 NTSTATUS open_fcb(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension* Vcb, 1382 root* subvol, uint64_t inode, uint8_t type, PANSI_STRING utf8, bool always_add_hl, fcb* parent, fcb** pfcb, POOL_TYPE pooltype, PIRP Irp); 1383 NTSTATUS load_csum(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, uint32_t* csum, uint64_t start, uint64_t length, PIRP Irp); 1384 NTSTATUS load_dir_children(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb, fcb* fcb, bool ignore_size, PIRP Irp); 1385 NTSTATUS add_dir_child(fcb* fcb, uint64_t inode, bool subvol, PANSI_STRING utf8, PUNICODE_STRING name, uint8_t type, dir_child** pdc); 1386 NTSTATUS open_fileref_child(_Requires_lock_held_(_Curr_->tree_lock) _Requires_exclusive_lock_held_(_Curr_->fcb_lock) _In_ device_extension* Vcb, 1387 _In_ file_ref* sf, _In_ PUNICODE_STRING name, _In_ bool case_sensitive, _In_ bool lastpart, _In_ bool streampart, 1388 _In_ POOL_TYPE pooltype, _Out_ file_ref** psf2, _In_opt_ PIRP Irp); 1389 fcb* create_fcb(device_extension* Vcb, POOL_TYPE pool_type); 1390 NTSTATUS find_file_in_dir(PUNICODE_STRING filename, fcb* fcb, root** subvol, uint64_t* inode, dir_child** pdc, bool case_sensitive); 1391 uint32_t inherit_mode(fcb* parfcb, bool is_dir); 1392 file_ref* create_fileref(device_extension* Vcb); 1393 NTSTATUS open_fileref_by_inode(_Requires_exclusive_lock_held_(_Curr_->fcb_lock) device_extension* Vcb, root* subvol, uint64_t inode, file_ref** pfr, PIRP Irp); 1394 1395 // in fsctl.c 1396 NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP* Pirp, uint32_t type); 1397 void do_unlock_volume(device_extension* Vcb); 1398 void trim_whole_device(device* dev); 1399 void flush_subvol_fcbs(root* subvol); 1400 bool fcb_is_inline(fcb* fcb); 1401 1402 // in flushthread.c 1403 1404 _Function_class_(KSTART_ROUTINE) 1405 void __stdcall flush_thread(void* context); 1406 1407 NTSTATUS do_write(device_extension* Vcb, PIRP Irp); 1408 NTSTATUS get_tree_new_address(device_extension* Vcb, tree* t, PIRP Irp, LIST_ENTRY* rollback); 1409 NTSTATUS flush_fcb(fcb* fcb, bool cache, LIST_ENTRY* batchlist, PIRP Irp); 1410 NTSTATUS write_data_phys(_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj, _In_ uint64_t address, 1411 _In_reads_bytes_(length) void* data, _In_ uint32_t length); 1412 bool is_tree_unique(device_extension* Vcb, tree* t, PIRP Irp); 1413 NTSTATUS do_tree_writes(device_extension* Vcb, LIST_ENTRY* tree_writes, bool no_free); 1414 void add_checksum_entry(device_extension* Vcb, uint64_t address, ULONG length, uint32_t* csum, PIRP Irp); 1415 bool find_metadata_address_in_chunk(device_extension* Vcb, chunk* c, uint64_t* address); 1416 void add_trim_entry_avoid_sb(device_extension* Vcb, device* dev, uint64_t address, uint64_t size); 1417 NTSTATUS insert_tree_item_batch(LIST_ENTRY* batchlist, device_extension* Vcb, root* r, uint64_t objid, uint8_t objtype, uint64_t offset, 1418 _In_opt_ _When_(return >= 0, __drv_aliasesMem) void* data, uint16_t datalen, enum batch_operation operation); 1419 NTSTATUS flush_partial_stripe(device_extension* Vcb, chunk* c, partial_stripe* ps); 1420 NTSTATUS update_dev_item(device_extension* Vcb, device* device, PIRP Irp); 1421 1422 // in read.c 1423 1424 _Dispatch_type_(IRP_MJ_READ) 1425 _Function_class_(DRIVER_DISPATCH) 1426 NTSTATUS __stdcall drv_read(PDEVICE_OBJECT DeviceObject, PIRP Irp); 1427 1428 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, 1429 _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, 1430 _In_ ULONG priority); 1431 NTSTATUS read_file(fcb* fcb, uint8_t* data, uint64_t start, uint64_t length, ULONG* pbr, PIRP Irp); 1432 NTSTATUS read_stream(fcb* fcb, uint8_t* data, uint64_t start, ULONG length, ULONG* pbr); 1433 NTSTATUS do_read(PIRP Irp, bool wait, ULONG* bytes_read); 1434 NTSTATUS check_csum(device_extension* Vcb, uint8_t* data, uint32_t sectors, uint32_t* csum); 1435 void raid6_recover2(uint8_t* sectors, uint16_t num_stripes, ULONG sector_size, uint16_t missing1, uint16_t missing2, uint8_t* out); 1436 1437 // in pnp.c 1438 1439 _Dispatch_type_(IRP_MJ_PNP) 1440 _Function_class_(DRIVER_DISPATCH) 1441 NTSTATUS __stdcall drv_pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp); 1442 1443 NTSTATUS pnp_surprise_removal(PDEVICE_OBJECT DeviceObject, PIRP Irp); 1444 NTSTATUS pnp_query_remove_device(PDEVICE_OBJECT DeviceObject, PIRP Irp); 1445 1446 // in free-space.c 1447 NTSTATUS load_cache_chunk(device_extension* Vcb, chunk* c, PIRP Irp); 1448 NTSTATUS clear_free_space_cache(device_extension* Vcb, LIST_ENTRY* batchlist, PIRP Irp); 1449 NTSTATUS allocate_cache(device_extension* Vcb, bool* changed, PIRP Irp, LIST_ENTRY* rollback); 1450 NTSTATUS update_chunk_caches(device_extension* Vcb, PIRP Irp, LIST_ENTRY* rollback); 1451 NTSTATUS update_chunk_caches_tree(device_extension* Vcb, PIRP Irp); 1452 NTSTATUS add_space_entry(LIST_ENTRY* list, LIST_ENTRY* list_size, uint64_t offset, uint64_t size); 1453 void space_list_add(chunk* c, uint64_t address, uint64_t length, LIST_ENTRY* rollback); 1454 void space_list_add2(LIST_ENTRY* list, LIST_ENTRY* list_size, uint64_t address, uint64_t length, chunk* c, LIST_ENTRY* rollback); 1455 void space_list_subtract(chunk* c, bool deleting, uint64_t address, uint64_t length, LIST_ENTRY* rollback); 1456 void space_list_subtract2(LIST_ENTRY* list, LIST_ENTRY* list_size, uint64_t address, uint64_t length, chunk* c, LIST_ENTRY* rollback); 1457 NTSTATUS load_stored_free_space_cache(device_extension* Vcb, chunk* c, bool load_only, PIRP Irp); 1458 1459 // in extent-tree.c 1460 NTSTATUS increase_extent_refcount_data(device_extension* Vcb, uint64_t address, uint64_t size, uint64_t root, uint64_t inode, uint64_t offset, uint32_t refcount, PIRP Irp); 1461 NTSTATUS decrease_extent_refcount_data(device_extension* Vcb, uint64_t address, uint64_t size, uint64_t root, uint64_t inode, uint64_t offset, 1462 uint32_t refcount, bool superseded, PIRP Irp); 1463 NTSTATUS decrease_extent_refcount_tree(device_extension* Vcb, uint64_t address, uint64_t size, uint64_t root, uint8_t level, PIRP Irp); 1464 uint64_t get_extent_refcount(device_extension* Vcb, uint64_t address, uint64_t size, PIRP Irp); 1465 bool is_extent_unique(device_extension* Vcb, uint64_t address, uint64_t size, PIRP Irp); 1466 NTSTATUS increase_extent_refcount(device_extension* Vcb, uint64_t address, uint64_t size, uint8_t type, void* data, KEY* firstitem, uint8_t level, PIRP Irp); 1467 uint64_t get_extent_flags(device_extension* Vcb, uint64_t address, PIRP Irp); 1468 void update_extent_flags(device_extension* Vcb, uint64_t address, uint64_t flags, PIRP Irp); 1469 NTSTATUS update_changed_extent_ref(device_extension* Vcb, chunk* c, uint64_t address, uint64_t size, uint64_t root, uint64_t objid, uint64_t offset, 1470 int32_t count, bool no_csum, bool superseded, PIRP Irp); 1471 void add_changed_extent_ref(chunk* c, uint64_t address, uint64_t size, uint64_t root, uint64_t objid, uint64_t offset, uint32_t count, bool no_csum); 1472 uint64_t find_extent_shared_tree_refcount(device_extension* Vcb, uint64_t address, uint64_t parent, PIRP Irp); 1473 uint32_t find_extent_shared_data_refcount(device_extension* Vcb, uint64_t address, uint64_t parent, PIRP Irp); 1474 NTSTATUS decrease_extent_refcount(device_extension* Vcb, uint64_t address, uint64_t size, uint8_t type, void* data, KEY* firstitem, 1475 uint8_t level, uint64_t parent, bool superseded, PIRP Irp); 1476 uint64_t get_extent_data_ref_hash2(uint64_t root, uint64_t objid, uint64_t offset); 1477 1478 // in worker-thread.c 1479 NTSTATUS do_read_job(PIRP Irp); 1480 NTSTATUS do_write_job(device_extension* Vcb, PIRP Irp); 1481 bool add_thread_job(device_extension* Vcb, PIRP Irp); 1482 1483 // in registry.c 1484 void read_registry(PUNICODE_STRING regpath, bool refresh); 1485 NTSTATUS registry_mark_volume_mounted(BTRFS_UUID* uuid); 1486 NTSTATUS registry_mark_volume_unmounted(BTRFS_UUID* uuid); 1487 NTSTATUS registry_load_volume_options(device_extension* Vcb); 1488 void watch_registry(HANDLE regh); 1489 1490 // in compress.c 1491 NTSTATUS zlib_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen); 1492 NTSTATUS lzo_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen, uint32_t inpageoff); 1493 NTSTATUS zstd_decompress(uint8_t* inbuf, uint32_t inlen, uint8_t* outbuf, uint32_t outlen); 1494 NTSTATUS write_compressed_bit(fcb* fcb, uint64_t start_data, uint64_t end_data, void* data, bool* compressed, PIRP Irp, LIST_ENTRY* rollback); 1495 1496 // in galois.c 1497 void galois_double(uint8_t* data, uint32_t len); 1498 void galois_divpower(uint8_t* data, uint8_t div, uint32_t readlen); 1499 uint8_t gpow2(uint8_t e); 1500 uint8_t gmul(uint8_t a, uint8_t b); 1501 uint8_t gdiv(uint8_t a, uint8_t b); 1502 1503 // in devctrl.c 1504 1505 _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 1506 _Function_class_(DRIVER_DISPATCH) 1507 NTSTATUS __stdcall drv_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1508 1509 // in calcthread.c 1510 1511 _Function_class_(KSTART_ROUTINE) 1512 void __stdcall calc_thread(void* context); 1513 1514 NTSTATUS add_calc_job(device_extension* Vcb, uint8_t* data, uint32_t sectors, uint32_t* csum, calc_job** pcj); 1515 void free_calc_job(calc_job* cj); 1516 1517 // in balance.c 1518 NTSTATUS start_balance(device_extension* Vcb, void* data, ULONG length, KPROCESSOR_MODE processor_mode); 1519 NTSTATUS query_balance(device_extension* Vcb, void* data, ULONG length); 1520 NTSTATUS pause_balance(device_extension* Vcb, KPROCESSOR_MODE processor_mode); 1521 NTSTATUS resume_balance(device_extension* Vcb, KPROCESSOR_MODE processor_mode); 1522 NTSTATUS stop_balance(device_extension* Vcb, KPROCESSOR_MODE processor_mode); 1523 NTSTATUS look_for_balance_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension* Vcb); 1524 NTSTATUS remove_device(device_extension* Vcb, void* data, ULONG length, KPROCESSOR_MODE processor_mode); 1525 1526 _Function_class_(KSTART_ROUTINE) 1527 void __stdcall balance_thread(void* context); 1528 1529 // in volume.c 1530 NTSTATUS vol_create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1531 NTSTATUS vol_close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1532 NTSTATUS vol_read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1533 NTSTATUS vol_write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1534 NTSTATUS vol_query_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1535 NTSTATUS vol_set_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1536 NTSTATUS vol_query_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1537 NTSTATUS vol_set_ea(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1538 NTSTATUS vol_flush_buffers(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1539 NTSTATUS vol_query_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1540 NTSTATUS vol_set_volume_information(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1541 NTSTATUS vol_cleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1542 NTSTATUS vol_directory_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1543 NTSTATUS vol_file_system_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1544 NTSTATUS vol_lock_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1545 NTSTATUS vol_device_control(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1546 NTSTATUS vol_shutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1547 NTSTATUS vol_query_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1548 NTSTATUS vol_set_security(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); 1549 void add_volume_device(superblock* sb, PUNICODE_STRING devpath, uint64_t length, ULONG disk_num, ULONG part_num); 1550 NTSTATUS mountmgr_add_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath); 1551 1552 _Function_class_(DRIVER_NOTIFICATION_CALLBACK_ROUTINE) 1553 NTSTATUS __stdcall pnp_removal(PVOID NotificationStructure, PVOID Context); 1554 1555 // in scrub.c 1556 NTSTATUS start_scrub(device_extension* Vcb, KPROCESSOR_MODE processor_mode); 1557 NTSTATUS query_scrub(device_extension* Vcb, KPROCESSOR_MODE processor_mode, void* data, ULONG length); 1558 NTSTATUS pause_scrub(device_extension* Vcb, KPROCESSOR_MODE processor_mode); 1559 NTSTATUS resume_scrub(device_extension* Vcb, KPROCESSOR_MODE processor_mode); 1560 NTSTATUS stop_scrub(device_extension* Vcb, KPROCESSOR_MODE processor_mode); 1561 1562 // in send.c 1563 NTSTATUS send_subvol(device_extension* Vcb, void* data, ULONG datalen, PFILE_OBJECT FileObject, PIRP Irp); 1564 NTSTATUS read_send_buffer(device_extension* Vcb, PFILE_OBJECT FileObject, void* data, ULONG datalen, ULONG_PTR* retlen, KPROCESSOR_MODE processor_mode); 1565 1566 // in fsrtl.c 1567 NTSTATUS compat_FsRtlValidateReparsePointBuffer(IN ULONG BufferLength, IN PREPARSE_DATA_BUFFER ReparseBuffer); 1568 1569 // in boot.c 1570 void __stdcall check_system_root(PDRIVER_OBJECT DriverObject, PVOID Context, ULONG Count); 1571 1572 // based on function in sys/sysmacros.h 1573 #define makedev(major, minor) (((minor) & 0xFF) | (((major) & 0xFFF) << 8) | (((uint64_t)((minor) & ~0xFF)) << 12) | (((uint64_t)((major) & ~0xFFF)) << 32)) 1574 1575 #define fast_io_possible(fcb) (!FsRtlAreThereCurrentFileLocks(&fcb->lock) && !fcb->Vcb->readonly ? FastIoIsPossible : FastIoIsQuestionable) 1576 1577 static __inline void print_open_trees(device_extension* Vcb) { 1578 LIST_ENTRY* le = Vcb->trees.Flink; 1579 while (le != &Vcb->trees) { 1580 tree* t = CONTAINING_RECORD(le, tree, list_entry); 1581 tree_data* td = CONTAINING_RECORD(t->itemlist.Flink, tree_data, list_entry); 1582 ERR("tree %p: root %I64x, level %u, first key (%I64x,%x,%I64x)\n", 1583 t, t->root->id, t->header.level, td->key.obj_id, td->key.obj_type, td->key.offset); 1584 1585 le = le->Flink; 1586 } 1587 } 1588 1589 static __inline bool write_fcb_compressed(fcb* fcb) { 1590 // make sure we don't accidentally write the cache inodes or pagefile compressed 1591 if (fcb->subvol->id == BTRFS_ROOT_ROOT || fcb->Header.Flags2 & FSRTL_FLAG2_IS_PAGING_FILE) 1592 return false; 1593 1594 if (fcb->Vcb->options.compress_force) 1595 return true; 1596 1597 if (fcb->inode_item.flags & BTRFS_INODE_NOCOMPRESS) 1598 return false; 1599 1600 if (fcb->inode_item.flags & BTRFS_INODE_COMPRESS || fcb->Vcb->options.compress) 1601 return true; 1602 1603 return false; 1604 } 1605 1606 static __inline void do_xor(uint8_t* buf1, uint8_t* buf2, uint32_t len) { 1607 uint32_t j; 1608 #ifndef __REACTOS__ 1609 __m128i x1, x2; 1610 #endif 1611 1612 #ifndef __REACTOS__ 1613 if (have_sse2 && ((uintptr_t)buf1 & 0xf) == 0 && ((uintptr_t)buf2 & 0xf) == 0) { 1614 while (len >= 16) { 1615 x1 = _mm_load_si128((__m128i*)buf1); 1616 x2 = _mm_load_si128((__m128i*)buf2); 1617 x1 = _mm_xor_si128(x1, x2); 1618 _mm_store_si128((__m128i*)buf1, x1); 1619 1620 buf1 += 16; 1621 buf2 += 16; 1622 len -= 16; 1623 } 1624 } 1625 #endif 1626 1627 for (j = 0; j < len; j++) { 1628 *buf1 ^= *buf2; 1629 buf1++; 1630 buf2++; 1631 } 1632 } 1633 1634 #ifdef DEBUG_FCB_REFCOUNTS 1635 #ifdef DEBUG_LONG_MESSAGES 1636 #define increase_fileref_refcount(fileref) {\ 1637 LONG rc = InterlockedIncrement(&fileref->refcount);\ 1638 MSG(funcname, __FILE__, __LINE__, "fileref %p: refcount now %i\n", 1, fileref, rc);\ 1639 } 1640 #else 1641 #define increase_fileref_refcount(fileref) {\ 1642 LONG rc = InterlockedIncrement(&fileref->refcount);\ 1643 MSG(funcname, "fileref %p: refcount now %i\n", 1, fileref, rc);\ 1644 } 1645 #endif 1646 #else 1647 #define increase_fileref_refcount(fileref) InterlockedIncrement(&fileref->refcount) 1648 #endif 1649 1650 #ifdef _MSC_VER 1651 #define int3 __debugbreak() 1652 #else 1653 #define int3 asm("int3;") 1654 #endif 1655 1656 #define hex_digit(c) ((c) <= 9) ? ((c) + '0') : ((c) - 10 + 'a') 1657 1658 // FIXME - find a way to catch unfreed trees again 1659 1660 // from sys/stat.h 1661 #define __S_IFMT 0170000 /* These bits determine file type. */ 1662 #define __S_IFDIR 0040000 /* Directory. */ 1663 #define __S_IFCHR 0020000 /* Character device. */ 1664 #define __S_IFBLK 0060000 /* Block device. */ 1665 #define __S_IFREG 0100000 /* Regular file. */ 1666 #define __S_IFIFO 0010000 /* FIFO. */ 1667 #define __S_IFLNK 0120000 /* Symbolic link. */ 1668 #define __S_IFSOCK 0140000 /* Socket. */ 1669 #define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask)) 1670 1671 #ifndef S_ISDIR 1672 #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR) 1673 #endif 1674 1675 #ifndef S_IRUSR 1676 #define S_IRUSR 0000400 1677 #endif 1678 1679 #ifndef S_IWUSR 1680 #define S_IWUSR 0000200 1681 #endif 1682 1683 #ifndef S_IXUSR 1684 #define S_IXUSR 0000100 1685 #endif 1686 1687 #ifdef __REACTOS__ 1688 #define S_IFDIR __S_IFDIR 1689 #define S_IFREG __S_IFREG 1690 #endif /* __REACTOS__ */ 1691 1692 #ifndef S_IRGRP 1693 #define S_IRGRP (S_IRUSR >> 3) 1694 #endif 1695 1696 #ifndef S_IWGRP 1697 #define S_IWGRP (S_IWUSR >> 3) 1698 #endif 1699 1700 #ifndef S_IXGRP 1701 #define S_IXGRP (S_IXUSR >> 3) 1702 #endif 1703 1704 #ifndef S_IROTH 1705 #define S_IROTH (S_IRGRP >> 3) 1706 #endif 1707 1708 #ifndef S_IWOTH 1709 #define S_IWOTH (S_IWGRP >> 3) 1710 #endif 1711 1712 #ifndef S_IXOTH 1713 #define S_IXOTH (S_IXGRP >> 3) 1714 #endif 1715 1716 #ifndef S_ISUID 1717 #define S_ISUID 0004000 1718 #endif 1719 1720 #ifndef S_ISGID 1721 #define S_ISGID 0002000 1722 #endif 1723 1724 #ifndef S_ISVTX 1725 #define S_ISVTX 0001000 1726 #endif 1727 1728 // based on functions in sys/sysmacros.h 1729 #define major(rdev) ((((rdev) >> 8) & 0xFFF) | ((uint32_t)((rdev) >> 32) & ~0xFFF)) 1730 #define minor(rdev) (((rdev) & 0xFF) | ((uint32_t)((rdev) >> 12) & ~0xFF)) 1731 1732 static __inline uint64_t fcb_alloc_size(fcb* fcb) { 1733 if (S_ISDIR(fcb->inode_item.st_mode)) 1734 return 0; 1735 else if (fcb->atts & FILE_ATTRIBUTE_SPARSE_FILE) 1736 return fcb->inode_item.st_blocks; 1737 else 1738 return sector_align(fcb->inode_item.st_size, fcb->Vcb->superblock.sector_size); 1739 } 1740 1741 typedef BOOLEAN (*tPsIsDiskCountersEnabled)(); 1742 1743 typedef VOID (*tPsUpdateDiskCounters)(PEPROCESS Process, ULONG64 BytesRead, ULONG64 BytesWritten, 1744 ULONG ReadOperationCount, ULONG WriteOperationCount, ULONG FlushOperationCount); 1745 1746 typedef BOOLEAN (*tCcCopyWriteEx)(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, 1747 PVOID Buffer, PETHREAD IoIssuerThread); 1748 1749 typedef BOOLEAN (*tCcCopyReadEx)(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, 1750 PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PETHREAD IoIssuerThread); 1751 1752 #ifndef CC_ENABLE_DISK_IO_ACCOUNTING 1753 #define CC_ENABLE_DISK_IO_ACCOUNTING 0x00000010 1754 #endif 1755 1756 #if defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_VISTA) 1757 typedef struct _ECP_LIST ECP_LIST; 1758 typedef struct _ECP_LIST *PECP_LIST; 1759 #endif 1760 1761 typedef VOID (*tCcSetAdditionalCacheAttributesEx)(PFILE_OBJECT FileObject, ULONG Flags); 1762 1763 typedef VOID (*tFsRtlUpdateDiskCounters)(ULONG64 BytesRead, ULONG64 BytesWritten); 1764 1765 typedef NTSTATUS (*tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry); 1766 1767 typedef NTSTATUS (*tFsRtlGetEcpListFromIrp)(PIRP Irp, PECP_LIST* EcpList); 1768 1769 typedef NTSTATUS (*tFsRtlGetNextExtraCreateParameter)(PECP_LIST EcpList, PVOID CurrentEcpContext, LPGUID NextEcpType, 1770 PVOID* NextEcpContext, ULONG* NextEcpContextSize); 1771 1772 typedef NTSTATUS (*tFsRtlValidateReparsePointBuffer)(ULONG BufferLength, PREPARSE_DATA_BUFFER ReparseBuffer); 1773 1774 #ifndef __REACTOS__ 1775 #ifndef _MSC_VER 1776 PEPROCESS PsGetThreadProcess(_In_ PETHREAD Thread); // not in mingw 1777 #endif 1778 1779 // not in DDK headers - taken from winternl.h 1780 typedef struct _LDR_DATA_TABLE_ENTRY { 1781 PVOID Reserved1[2]; 1782 LIST_ENTRY InMemoryOrderLinks; 1783 PVOID Reserved2[2]; 1784 PVOID DllBase; 1785 PVOID Reserved3[2]; 1786 UNICODE_STRING FullDllName; 1787 BYTE Reserved4[8]; 1788 PVOID Reserved5[3]; 1789 union { 1790 ULONG CheckSum; 1791 PVOID Reserved6; 1792 }; 1793 ULONG TimeDateStamp; 1794 } LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY; 1795 1796 typedef struct _PEB_LDR_DATA { 1797 BYTE Reserved1[8]; 1798 PVOID Reserved2[3]; 1799 LIST_ENTRY InMemoryOrderModuleList; 1800 } PEB_LDR_DATA,*PPEB_LDR_DATA; 1801 1802 typedef struct _RTL_USER_PROCESS_PARAMETERS { 1803 BYTE Reserved1[16]; 1804 PVOID Reserved2[10]; 1805 UNICODE_STRING ImagePathName; 1806 UNICODE_STRING CommandLine; 1807 } RTL_USER_PROCESS_PARAMETERS,*PRTL_USER_PROCESS_PARAMETERS; 1808 1809 typedef VOID (NTAPI *PPS_POST_PROCESS_INIT_ROUTINE)(VOID); 1810 1811 typedef struct _PEB { 1812 BYTE Reserved1[2]; 1813 BYTE BeingDebugged; 1814 BYTE Reserved2[1]; 1815 PVOID Reserved3[2]; 1816 PPEB_LDR_DATA Ldr; 1817 PRTL_USER_PROCESS_PARAMETERS ProcessParameters; 1818 BYTE Reserved4[104]; 1819 PVOID Reserved5[52]; 1820 PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; 1821 BYTE Reserved6[128]; 1822 PVOID Reserved7[1]; 1823 ULONG SessionId; 1824 } PEB,*PPEB; 1825 #endif 1826 1827 #ifdef _MSC_VER 1828 __kernel_entry 1829 NTSTATUS NTAPI ZwQueryInformationProcess( 1830 IN HANDLE ProcessHandle, 1831 IN PROCESSINFOCLASS ProcessInformationClass, 1832 OUT PVOID ProcessInformation, 1833 IN ULONG ProcessInformationLength, 1834 OUT PULONG ReturnLength OPTIONAL 1835 ); 1836 #endif 1837