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