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