ReactOS 0.4.15-dev-7788-g1ad9096
btrfs.c File Reference
#include "btrfs_drv.h"
#include "xxhash.h"
#include "crc32c.h"
#include <cpuid.h>
#include <ntddscsi.h>
#include "btrfs.h"
#include <ata.h>
#include <initguid.h>
#include <ntddstor.h>
#include <ntdddisk.h>
#include <ntddvol.h>
#include <ntstrsafe.h>
Include dependency graph for btrfs.c:

Go to the source code of this file.

Classes

struct  read_context
 
struct  notification_fcb
 

Macros

#define INCOMPAT_SUPPORTED
 
#define COMPAT_RO_SUPPORTED
 
#define INIT_UNICODE_STRING(var, val)   UNICODE_STRING us##var; us##var.Buffer = (WCHAR*)val; us##var.Length = us##var.MaximumLength = sizeof(val) - sizeof(WCHAR);
 

Functions

 DEFINE_GUID (BtrfsBusInterface, 0x4d414874, 0x6865, 0x6761, 0x6d, 0x65, 0x83, 0x69, 0x17, 0x9a, 0x7d, 0x1d)
 
static NTSTATUS close_file (_In_ PFILE_OBJECT FileObject, _In_ PIRP Irp)
 
static void __stdcall do_xor_basic (uint8_t *buf1, uint8_t *buf2, uint32_t len)
 
BOOLEAN WdmlibRtlIsNtDdiVersionAvailable (ULONG Version)
 
bool is_top_level (_In_ PIRP Irp)
 
 _Function_class_ (DRIVER_UNLOAD)
 
static bool get_last_inode (_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _In_opt_ PIRP Irp)
 
 _Success_ (return)
 
 _Dispatch_type_ (IRP_MJ_CLOSE)
 
 _Dispatch_type_ (IRP_MJ_FLUSH_BUFFERS)
 
static void calculate_total_space (_In_ device_extension *Vcb, _Out_ uint64_t *totalsize, _Out_ uint64_t *freespace)
 
static bool compare_strings (const UNICODE_STRING *us1, const UNICODE_STRING *us2)
 
static bool lie_about_fs_type ()
 
NTSTATUS utf8_to_utf16 (WCHAR *dest, ULONG dest_max, ULONG *dest_len, char *src, ULONG src_len)
 
NTSTATUS utf16_to_utf8 (char *dest, ULONG dest_max, ULONG *dest_len, WCHAR *src, ULONG src_len)
 
 _Dispatch_type_ (IRP_MJ_QUERY_VOLUME_INFORMATION)
 
 _Function_class_ (IO_COMPLETION_ROUTINE)
 
NTSTATUS create_root (_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ uint64_t id, _Out_ root **rootptr, _In_ bool no_tree, _In_ uint64_t offset, _In_opt_ PIRP Irp)
 
static NTSTATUS set_label (_In_ device_extension *Vcb, _In_ FILE_FS_LABEL_INFORMATION *ffli)
 
 _Dispatch_type_ (IRP_MJ_SET_VOLUME_INFORMATION)
 
void send_notification_fileref (_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
 
static void send_notification_fcb (_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
 
 _Function_class_ (IO_WORKITEM_ROUTINE)
 
void queue_notification_fcb (_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
 
void mark_fcb_dirty (_In_ fcb *fcb)
 
void mark_fileref_dirty (_In_ file_ref *fileref)
 
void free_fcb (_Inout_ fcb *fcb)
 
void reap_fcb (fcb *fcb)
 
void reap_fcbs (device_extension *Vcb)
 
void free_fileref (_Inout_ file_ref *fr)
 
void reap_fileref (device_extension *Vcb, file_ref *fr)
 
void reap_filerefs (device_extension *Vcb, file_ref *fr)
 
void uninit (_In_ device_extension *Vcb)
 
static NTSTATUS delete_fileref_fcb (_In_ file_ref *fileref, _In_opt_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY *rollback)
 
NTSTATUS delete_fileref (_In_ file_ref *fileref, _In_opt_ PFILE_OBJECT FileObject, _In_ bool make_orphan, _In_opt_ PIRP Irp, _In_ LIST_ENTRY *rollback)
 
 _Dispatch_type_ (IRP_MJ_CLEANUP)
 
ULONG get_file_attributes (_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _In_ uint64_t inode, _In_ uint8_t type, _In_ bool dotfile, _In_ bool ignore_xa, _In_opt_ PIRP Irp)
 
NTSTATUS sync_read_phys (_In_ PDEVICE_OBJECT DeviceObject, _In_ PFILE_OBJECT FileObject, _In_ uint64_t StartingOffset, _In_ ULONG Length, _Out_writes_bytes_(Length) PUCHAR Buffer, _In_ bool override)
 
bool check_superblock_checksum (superblock *sb)
 
static NTSTATUS read_superblock (_In_ device_extension *Vcb, _In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj, _In_ uint64_t length)
 
NTSTATUS dev_ioctl (_In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG ControlCode, _In_reads_bytes_opt_(InputBufferSize) PVOID InputBuffer, _In_ ULONG InputBufferSize, _Out_writes_bytes_opt_(OutputBufferSize) PVOID OutputBuffer, _In_ ULONG OutputBufferSize, _In_ bool Override, _Out_opt_ IO_STATUS_BLOCK *iosb)
 
 _Requires_exclusive_lock_held_ (Vcb->tree_lock) static NTSTATUS add_root(_Inout_ device_extension *Vcb
 
 if (!r)
 
 RtlZeroMemory (r->fcbs_ptrs, sizeof(LIST_ENTRY *) *256)
 
 if (!r->nonpaged)
 
 if (tp)
 
else RtlZeroMemoryr (ROOT_ITEM)
 
 if (!Vcb->readonly &&(r->id==BTRFS_ROOT_ROOT||r->id==BTRFS_ROOT_FSTREE||(r->id >=0x100 &&!(r->id &0xf000000000000000))))
 
 switch (r->id)
 
static NTSTATUS look_for_roots (_Requires_exclusive_lock_held_(_Curr_->tree_lock) _In_ device_extension *Vcb, _In_opt_ PIRP Irp)
 
static NTSTATUS find_disk_holes (_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ device *dev, _In_opt_ PIRP Irp)
 
static void add_device_to_list (_In_ device_extension *Vcb, _In_ device *dev)
 
_Ret_maybenull_ devicefind_device_from_uuid (_In_ device_extension *Vcb, _In_ BTRFS_UUID *uuid)
 
static bool is_device_removable (_In_ PDEVICE_OBJECT devobj)
 
static ULONG get_device_change_count (_In_ PDEVICE_OBJECT devobj)
 
void init_device (_In_ device_extension *Vcb, _Inout_ device *dev, _In_ bool get_nums)
 
static NTSTATUS load_chunk_root (_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_opt_ PIRP Irp)
 
void protect_superblocks (_Inout_ chunk *c)
 
NTSTATUS find_chunk_usage (_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_opt_ PIRP Irp)
 
static NTSTATUS load_sys_chunks (_In_ device_extension *Vcb)
 
_Ret_maybenull_ rootfind_default_subvol (_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_opt_ PIRP Irp)
 
void init_file_cache (_In_ PFILE_OBJECT FileObject, _In_ CC_FILE_SIZES *ccfs)
 
uint32_t get_num_of_processors ()
 
static NTSTATUS create_calc_threads (_In_ PDEVICE_OBJECT DeviceObject)
 
static bool is_btrfs_volume (_In_ PDEVICE_OBJECT DeviceObject)
 
static NTSTATUS get_device_pnp_name_guid (_In_ PDEVICE_OBJECT DeviceObject, _Out_ PUNICODE_STRING pnp_name, _In_ const GUID *guid)
 
NTSTATUS get_device_pnp_name (_In_ PDEVICE_OBJECT DeviceObject, _Out_ PUNICODE_STRING pnp_name, _Out_ const GUID **guid)
 
 _Success_ (return >=0) static NTSTATUS check_mount_device(_In_ PDEVICE_OBJECT DeviceObject
 
 if (!NT_SUCCESS(Status))
 
 if (sb->magic !=BTRFS_MAGIC)
 
 if (!check_superblock_checksum(sb))
 
static bool still_has_superblock (_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj)
 
static void calculate_sector_shift (device_extension *Vcb)
 
static NTSTATUS mount_vol (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
static NTSTATUS verify_device (_In_ device_extension *Vcb, _Inout_ device *dev)
 
static NTSTATUS verify_volume (_In_ PDEVICE_OBJECT devobj)
 
 _Dispatch_type_ (IRP_MJ_FILE_SYSTEM_CONTROL)
 
 _Dispatch_type_ (IRP_MJ_LOCK_CONTROL)
 
void do_shutdown (PIRP Irp)
 
 _Dispatch_type_ (IRP_MJ_SHUTDOWN)
 
static bool device_still_valid (device *dev, uint64_t expected_generation)
 
 _Dispatch_type_ (IRP_MJ_POWER)
 
 _Dispatch_type_ (IRP_MJ_SYSTEM_CONTROL)
 
NTSTATUS check_file_name_valid (_In_ PUNICODE_STRING us, _In_ bool posix, _In_ bool stream)
 
void chunk_lock_range (_In_ device_extension *Vcb, _In_ chunk *c, _In_ uint64_t start, _In_ uint64_t length)
 
void chunk_unlock_range (_In_ device_extension *Vcb, _In_ chunk *c, _In_ uint64_t start, _In_ uint64_t length)
 
void log_device_error (_In_ device_extension *Vcb, _Inout_ device *dev, _In_ int error)
 
 _Function_class_ (KSTART_ROUTINE)
 
 _Function_class_ (DRIVER_ADD_DEVICE)
 
 _Function_class_ (DRIVER_INITIALIZE)
 

Variables

static const WCHAR device_name [] = {'\\','B','t','r','f','s',0}
 
static const WCHAR dosdevice_name [] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','B','t','r','f','s',0}
 
PDRIVER_OBJECT drvobj
 
PDEVICE_OBJECT master_devobj
 
PDEVICE_OBJECT busobj
 
uint64_t num_reads = 0
 
LIST_ENTRY uid_map_list
 
LIST_ENTRY gid_map_list
 
LIST_ENTRY VcbList
 
ERESOURCE global_loading_lock
 
uint32_t debug_log_level = 0
 
uint32_t mount_compress = 0
 
uint32_t mount_compress_force = 0
 
uint32_t mount_compress_type = 0
 
uint32_t mount_zlib_level = 3
 
uint32_t mount_zstd_level = 3
 
uint32_t mount_flush_interval = 30
 
uint32_t mount_max_inline = 2048
 
uint32_t mount_skip_balance = 0
 
uint32_t mount_no_barrier = 0
 
uint32_t mount_no_trim = 0
 
uint32_t mount_clear_cache = 0
 
uint32_t mount_allow_degraded = 0
 
uint32_t mount_readonly = 0
 
uint32_t mount_no_root_dir = 0
 
uint32_t mount_nodatacow = 0
 
uint32_t no_pnp = 0
 
bool log_started = false
 
UNICODE_STRING log_device
 
UNICODE_STRING log_file
 
UNICODE_STRING registry_path
 
tPsUpdateDiskCounters fPsUpdateDiskCounters
 
tCcCopyReadEx fCcCopyReadEx
 
tCcCopyWriteEx fCcCopyWriteEx
 
tCcSetAdditionalCacheAttributesEx fCcSetAdditionalCacheAttributesEx
 
tFsRtlUpdateDiskCounters fFsRtlUpdateDiskCounters
 
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
 
tFsRtlGetEcpListFromIrp fFsRtlGetEcpListFromIrp
 
tFsRtlGetNextExtraCreateParameter fFsRtlGetNextExtraCreateParameter
 
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
 
tFsRtlCheckLockForOplockRequest fFsRtlCheckLockForOplockRequest
 
tFsRtlAreThereCurrentOrInProgressFileLocks fFsRtlAreThereCurrentOrInProgressFileLocks
 
bool diskacc = false
 
voidnotification_entry = NULL
 
voidnotification_entry2 = NULL
 
voidnotification_entry3 = NULL
 
ERESOURCE pdo_list_lock
 
ERESOURCE mapping_lock
 
LIST_ENTRY pdo_list
 
bool finished_probing = false
 
HANDLE degraded_wait_handle = NULL
 
HANDLE mountmgr_thread_handle = NULL
 
bool degraded_wait = true
 
KEVENT mountmgr_thread_event
 
bool shutting_down = false
 
ERESOURCE boot_lock
 
bool is_windows_8
 
uint64_t boot_subvol
 
xor_func do_xor = do_xor_basic
 
_In_ uint64_t id = id
 
_In_ uint64_t _In_ uint64_t addr
 
_In_ uint64_t _In_ uint64_t _In_ uint64_t generation = generation
 
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptrtp
 
r dirty = false
 
r received = false
 
r reserved = NULL
 
r treeholder address = addr
 
r treeholder tree = NULL
 
r parent = 0
 
r send_ops = 0
 
r fcbs_version = 0
 
r checked_for_orphans = false
 
r dropped = false
 
InitializeListHeadr
 
r nonpaged = ExAllocatePoolWithTag(NonPagedPool, sizeof(root_nonpaged), ALLOC_TAG)
 
r lastinode = 0
 
InsertTailListVcb
 
return STATUS_SUCCESS
 
_Out_ boolpno_pnp
 
ULONG to_read = DeviceObject->SectorSize == 0 ? sizeof(superblock) : (ULONG)sector_align(sizeof(superblock), DeviceObject->SectorSize)
 
superblocksb = ExAllocatePoolWithTag(NonPagedPool, to_read, ALLOC_TAG)
 
 Status = sync_read_phys(DeviceObject, NULL, superblock_addrs[0], to_read, (PUCHAR)sb, true)
 
end __pad0__
 

Macro Definition Documentation

◆ COMPAT_RO_SUPPORTED

#define COMPAT_RO_SUPPORTED
Value:
#define BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE
Definition: btrfs.h:111
#define BTRFS_COMPAT_RO_FLAGS_VERITY
Definition: btrfs.h:113
#define BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE_VALID
Definition: btrfs.h:112

Definition at line 57 of file btrfs.c.

◆ INCOMPAT_SUPPORTED

#define INCOMPAT_SUPPORTED
Value:
#define BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA
Definition: btrfs.h:123
#define BTRFS_INCOMPAT_FLAGS_RAID56
Definition: btrfs.h:122
#define BTRFS_INCOMPAT_FLAGS_RAID1C34
Definition: btrfs.h:126
#define BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD
Definition: btrfs.h:119
#define BTRFS_INCOMPAT_FLAGS_DEFAULT_SUBVOL
Definition: btrfs.h:116
#define BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS
Definition: btrfs.h:117
#define BTRFS_INCOMPAT_FLAGS_METADATA_UUID
Definition: btrfs.h:125
#define BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF
Definition: btrfs.h:115
#define BTRFS_INCOMPAT_FLAGS_BIG_METADATA
Definition: btrfs.h:120
#define BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO
Definition: btrfs.h:118
#define BTRFS_INCOMPAT_FLAGS_NO_HOLES
Definition: btrfs.h:124
#define BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF
Definition: btrfs.h:121

Definition at line 53 of file btrfs.c.

◆ INIT_UNICODE_STRING

#define INIT_UNICODE_STRING (   var,
  val 
)    UNICODE_STRING us##var; us##var.Buffer = (WCHAR*)val; us##var.Length = us##var.MaximumLength = sizeof(val) - sizeof(WCHAR);

Definition at line 679 of file btrfs.c.

Function Documentation

◆ _Dispatch_type_() [1/10]

_Dispatch_type_ ( IRP_MJ_CLEANUP  )

Definition at line 2438 of file btrfs.c.

2440 {
2444 device_extension* Vcb = DeviceObject->DeviceExtension;
2445 fcb* fcb = FileObject->FsContext;
2446 bool top_level;
2447
2449
2450 TRACE("cleanup\n");
2451
2452 top_level = is_top_level(Irp);
2453
2454 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
2455 Irp->IoStatus.Information = 0;
2457 goto exit;
2458 } else if (DeviceObject == master_devobj) {
2459 TRACE("closing file system\n");
2461 goto exit;
2462 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
2464 goto exit;
2465 }
2466
2467 if (FileObject->Flags & FO_CLEANUP_COMPLETE) {
2468 TRACE("FileObject %p already cleaned up\n", FileObject);
2470 goto exit;
2471 }
2472
2473 if (!fcb) {
2474 ERR("fcb was NULL\n");
2476 goto exit;
2477 }
2478
2480
2481 // We have to use the pointer to Vcb stored in the fcb, as we can receive cleanup
2482 // messages belonging to other devices.
2483
2484 if (FileObject && FileObject->FsContext) {
2485 ccb* ccb;
2486 file_ref* fileref;
2487 bool locked = true;
2488
2489 ccb = FileObject->FsContext2;
2490 fileref = ccb ? ccb->fileref : NULL;
2491
2492 TRACE("cleanup called for FileObject %p\n", FileObject);
2493 TRACE("fileref %p, refcount = %li, open_count = %li\n", fileref, fileref ? fileref->refcount : 0, fileref ? fileref->open_count : 0);
2494
2495 ExAcquireResourceSharedLite(&fcb->Vcb->tree_lock, true);
2496
2497 ExAcquireResourceExclusiveLite(fcb->Header.Resource, true);
2498
2500
2502
2503 if (ccb)
2504 FsRtlNotifyCleanup(fcb->Vcb->NotifySync, &fcb->Vcb->DirNotifyList, ccb);
2505
2506 if (ccb && ccb->options & FILE_DELETE_ON_CLOSE && fileref)
2507 fileref->delete_on_close = true;
2508
2509 if (fileref && fileref->delete_on_close && fcb->type == BTRFS_TYPE_DIRECTORY && fcb->inode_item.st_size > 0 && fcb != fcb->Vcb->dummy_fcb)
2510 fileref->delete_on_close = false;
2511
2512 if (fcb->Vcb->locked && fcb->Vcb->locked_fileobj == FileObject) {
2513 TRACE("unlocking volume\n");
2516 }
2517
2518 if (ccb && ccb->reserving) {
2519 fcb->subvol->reserved = NULL;
2520 ccb->reserving = false;
2521 // FIXME - flush all of subvol's fcbs
2522 }
2523
2524 if (fileref) {
2525 LONG oc = InterlockedDecrement(&fileref->open_count);
2526#ifdef DEBUG_FCB_REFCOUNTS
2527 ERR("fileref %p: open_count now %i\n", fileref, oc);
2528#endif
2529
2530 if (oc == 0 || (fileref->delete_on_close && fileref->posix_delete)) {
2531 if (!fcb->Vcb->removing) {
2532 if (oc == 0 && fileref->fcb->inode_item.st_nlink == 0 && fileref != fcb->Vcb->root_fileref &&
2533 fcb != fcb->Vcb->volume_fcb && !fcb->ads) { // last handle closed on POSIX-deleted file
2535
2537
2539 if (!NT_SUCCESS(Status)) {
2540 ERR("delete_fileref_fcb returned %08lx\n", Status);
2542 ExReleaseResourceLite(fileref->fcb->Header.Resource);
2543 ExReleaseResourceLite(&fcb->Vcb->tree_lock);
2544 goto exit;
2545 }
2546
2548
2549 mark_fcb_dirty(fileref->fcb);
2550 } else if (fileref->delete_on_close && fileref != fcb->Vcb->root_fileref && fcb != fcb->Vcb->volume_fcb) {
2552
2554
2555 if (!fileref->fcb->ads || fileref->dc) {
2556 if (fileref->fcb->ads) {
2558 FILE_ACTION_REMOVED, &fileref->dc->name);
2559 } else
2561 }
2562
2563 ExReleaseResourceLite(fcb->Header.Resource);
2564 locked = false;
2565
2566 // fileref_lock needs to be acquired before fcb->Header.Resource
2567 ExAcquireResourceExclusiveLite(&fcb->Vcb->fileref_lock, true);
2568
2569 Status = delete_fileref(fileref, FileObject, oc > 0 && fileref->posix_delete, Irp, &rollback);
2570 if (!NT_SUCCESS(Status)) {
2571 ERR("delete_fileref returned %08lx\n", Status);
2573 ExReleaseResourceLite(&fcb->Vcb->fileref_lock);
2574 ExReleaseResourceLite(&fcb->Vcb->tree_lock);
2575 goto exit;
2576 }
2577
2578 ExReleaseResourceLite(&fcb->Vcb->fileref_lock);
2579
2581 } else if (FileObject->Flags & FO_CACHE_SUPPORTED && FileObject->SectionObjectPointer->DataSectionObject) {
2583
2584 if (locked) {
2585 ExReleaseResourceLite(fcb->Header.Resource);
2586 locked = false;
2587 }
2588
2589 CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, &iosb);
2590
2591 if (!NT_SUCCESS(iosb.Status))
2592 ERR("CcFlushCache returned %08lx\n", iosb.Status);
2593
2594 if (!ExIsResourceAcquiredSharedLite(fcb->Header.PagingIoResource)) {
2595 ExAcquireResourceExclusiveLite(fcb->Header.PagingIoResource, true);
2596 ExReleaseResourceLite(fcb->Header.PagingIoResource);
2597 }
2598
2599 CcPurgeCacheSection(FileObject->SectionObjectPointer, NULL, 0, false);
2600
2601 TRACE("flushed cache on close (FileObject = %p, fcb = %p, AllocationSize = %I64x, FileSize = %I64x, ValidDataLength = %I64x)\n",
2602 FileObject, fcb, fcb->Header.AllocationSize.QuadPart, fcb->Header.FileSize.QuadPart, fcb->Header.ValidDataLength.QuadPart);
2603 }
2604 }
2605
2606 if (fcb->Vcb && fcb != fcb->Vcb->volume_fcb)
2608 }
2609 }
2610
2611 if (locked)
2612 ExReleaseResourceLite(fcb->Header.Resource);
2613
2614 ExReleaseResourceLite(&fcb->Vcb->tree_lock);
2615
2617 }
2618
2620
2621exit:
2622 TRACE("returning %08lx\n", Status);
2623
2624 Irp->IoStatus.Status = Status;
2625 Irp->IoStatus.Information = 0;
2626
2628
2629 if (top_level)
2631
2633
2634 return Status;
2635}
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define ERR(fmt,...)
Definition: debug.h:110
#define VCB_TYPE_VOLUME
Definition: btrfs_drv.h:689
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1365
#define VCB_TYPE_FS
Definition: btrfs_drv.h:687
static __inline POPLOCK fcb_oplock(fcb *fcb)
Definition: btrfs_drv.h:1677
void do_rollback(device_extension *Vcb, LIST_ENTRY *rollback) __attribute__((nonnull(1
struct _ccb ccb
NTSTATUS NTSTATUS void clear_rollback(LIST_ENTRY *rollback) __attribute__((nonnull(1)))
void do_unlock_volume(device_extension *Vcb)
Definition: fsctl.c:2326
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
void mark_fcb_dirty(_In_ fcb *fcb)
Definition: btrfs.c:1695
NTSTATUS delete_fileref(_In_ file_ref *fileref, _In_opt_ PFILE_OBJECT FileObject, _In_ bool make_orphan, _In_opt_ PIRP Irp, _In_ LIST_ENTRY *rollback)
Definition: btrfs.c:2270
return STATUS_SUCCESS
Definition: btrfs.c:3080
InsertTailList & Vcb
Definition: btrfs.c:3044
bool is_top_level(_In_ PIRP Irp)
Definition: btrfs.c:278
static NTSTATUS delete_fileref_fcb(_In_ file_ref *fileref, _In_opt_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY *rollback)
Definition: btrfs.c:2214
PDEVICE_OBJECT master_devobj
Definition: btrfs.c:66
void send_notification_fileref(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1517
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL)
Definition: filelock.c:1025
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
Status
Definition: gdiplustypes.h:25
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
#define FSRTL_VOLUME_UNLOCK
Definition: ntifs_ex.h:443
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1663
VOID NTAPI FsRtlNotifyCleanup(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext)
Definition: notify.c:659
NTSTATUS NTAPI FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject, IN ULONG EventCode)
Definition: pnp.c:38
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3478
#define IoCompleteRequest
Definition: irp.c:1240
PEPROCESS NTAPI IoGetRequestorProcess(IN PIRP Irp)
Definition: irp.c:1782
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
NTSTATUS NTAPI FsRtlCheckOplock(IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
Definition: oplock.c:1170
long LONG
Definition: pedump.c:60
#define exit(n)
Definition: config.h:202
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
#define TRACE(s)
Definition: solgame.cpp:4
uint32_t st_nlink
Definition: btrfs.h:292
uint64_t st_size
Definition: btrfs.h:289
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
Definition: typedefs.h:120
bool reserving
Definition: btrfs_drv.h:381
file_ref * fileref
Definition: btrfs_drv.h:383
ULONG options
Definition: btrfs_drv.h:374
bool ads
Definition: btrfs_drv.h:330
FILE_LOCK lock
Definition: btrfs_drv.h:294
INODE_ITEM inode_item
Definition: btrfs_drv.h:292
uint8_t type
Definition: btrfs_drv.h:291
struct _device_extension * Vcb
Definition: btrfs_drv.h:287
struct _root * subvol
Definition: btrfs_drv.h:288
SHARE_ACCESS share_access
Definition: btrfs_drv.h:298
FSRTL_ADVANCED_FCB_HEADER Header
Definition: btrfs_drv.h:283
LONG refcount
Definition: btrfs_drv.h:350
struct _file_ref * parent
Definition: btrfs_drv.h:352
fcb * fcb
Definition: btrfs_drv.h:342
dir_child * dc
Definition: btrfs_drv.h:353
bool posix_delete
Definition: btrfs_drv.h:346
LONG open_count
Definition: btrfs_drv.h:351
bool delete_on_close
Definition: btrfs_drv.h:345
UNICODE_STRING name
Definition: btrfs_drv.h:256
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define FILE_ACTION_REMOVED
#define FILE_NOTIFY_CHANGE_FILE_NAME
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FO_CACHE_SUPPORTED
Definition: iotypes.h:1781
#define FILE_NOTIFY_CHANGE_DIR_NAME

◆ _Dispatch_type_() [2/10]

_Dispatch_type_ ( IRP_MJ_CLOSE  )

Definition at line 503 of file btrfs.c.

505 {
508 device_extension* Vcb = DeviceObject->DeviceExtension;
509 bool top_level;
510
512
513 TRACE("close\n");
514
515 top_level = is_top_level(Irp);
516
518 TRACE("Closing file system\n");
520 goto end;
521 } else if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
523 goto end;
524 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
526 goto end;
527 }
528
530
531 // FIXME - call FsRtlNotifyUninitializeSync(&Vcb->NotifySync) if unmounting
532
534
535end:
536 Irp->IoStatus.Status = Status;
537 Irp->IoStatus.Information = 0;
538
540
541 if (top_level)
543
544 TRACE("returning %08lx\n", Status);
545
547
548 return Status;
549}
NTSTATUS vol_close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: volume.c:95
GLuint GLuint end
Definition: gl.h:1545
static void close_file()
Definition: regtests2xml.c:133
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

◆ _Dispatch_type_() [3/10]

_Dispatch_type_ ( IRP_MJ_FILE_SYSTEM_CONTROL  )

Definition at line 5264 of file btrfs.c.

5266 {
5269 device_extension* Vcb = DeviceObject->DeviceExtension;
5270 bool top_level;
5271
5273
5274 TRACE("file system control\n");
5275
5276 top_level = is_top_level(Irp);
5277
5278 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
5280 goto end;
5281 } else if (!Vcb || (Vcb->type != VCB_TYPE_FS && Vcb->type != VCB_TYPE_CONTROL)) {
5283 goto end;
5284 }
5285
5287
5289
5290 Irp->IoStatus.Information = 0;
5291
5292 switch (IrpSp->MinorFunction) {
5294 TRACE("IRP_MN_MOUNT_VOLUME\n");
5295
5297 break;
5298
5299 case IRP_MN_KERNEL_CALL:
5300 TRACE("IRP_MN_KERNEL_CALL\n");
5301
5302 Status = fsctl_request(DeviceObject, &Irp, IrpSp->Parameters.FileSystemControl.FsControlCode);
5303 break;
5304
5306 TRACE("IRP_MN_USER_FS_REQUEST\n");
5307
5308 Status = fsctl_request(DeviceObject, &Irp, IrpSp->Parameters.FileSystemControl.FsControlCode);
5309 break;
5310
5312 TRACE("IRP_MN_VERIFY_VOLUME\n");
5313
5315
5316 if (!NT_SUCCESS(Status) && Vcb->Vpb->Flags & VPB_MOUNTED) {
5317 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
5318 Vcb->removing = true;
5319 ExReleaseResourceLite(&Vcb->tree_lock);
5320 }
5321
5322 break;
5323
5324 default:
5325 break;
5326 }
5327
5328end:
5329 TRACE("returning %08lx\n", Status);
5330
5331 if (Irp) {
5332 Irp->IoStatus.Status = Status;
5333
5335 }
5336
5337 if (top_level)
5339
5341
5342 return Status;
5343}
#define VCB_TYPE_CONTROL
Definition: btrfs_drv.h:688
NTSTATUS fsctl_request(PDEVICE_OBJECT DeviceObject, PIRP *Pirp, uint32_t type)
Definition: fsctl.c:5345
static NTSTATUS mount_vol(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: btrfs.c:4375
static NTSTATUS verify_volume(_In_ PDEVICE_OBJECT devobj)
Definition: btrfs.c:5203
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define VPB_MOUNTED
Definition: iotypes.h:1807
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403
#define IRP_MN_KERNEL_CALL
Definition: iotypes.h:4408
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404

◆ _Dispatch_type_() [4/10]

_Dispatch_type_ ( IRP_MJ_FLUSH_BUFFERS  )

Definition at line 551 of file btrfs.c.

553 {
557 fcb* fcb = FileObject->FsContext;
558 device_extension* Vcb = DeviceObject->DeviceExtension;
559 bool top_level;
560
562
563 TRACE("flush buffers\n");
564
565 top_level = is_top_level(Irp);
566
567 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
569 goto end;
570 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
572 goto end;
573 }
574
575 if (!fcb) {
576 ERR("fcb was NULL\n");
578 goto end;
579 }
580
581 if (fcb == Vcb->volume_fcb) {
583 goto end;
584 }
585
587
588 Irp->IoStatus.Information = 0;
589
590 fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
591
593 Irp->IoStatus.Status = Status;
594
595 if (fcb->type != BTRFS_TYPE_DIRECTORY) {
596 CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, &Irp->IoStatus);
597
598 if (fcb->Header.PagingIoResource) {
599 ExAcquireResourceExclusiveLite(fcb->Header.PagingIoResource, true);
600 ExReleaseResourceLite(fcb->Header.PagingIoResource);
601 }
602
603 Status = Irp->IoStatus.Status;
604 }
605
606end:
608
609 TRACE("returning %08lx\n", Status);
610
611 if (top_level)
613
615
616 return Status;
617}
static __inline FAST_IO_POSSIBLE fast_io_possible(fcb *fcb)
Definition: btrfs_drv.h:1684

◆ _Dispatch_type_() [5/10]

_Dispatch_type_ ( IRP_MJ_LOCK_CONTROL  )

Definition at line 5345 of file btrfs.c.

5347 {
5350 fcb* fcb = IrpSp->FileObject ? IrpSp->FileObject->FsContext : NULL;
5351 device_extension* Vcb = DeviceObject->DeviceExtension;
5352 bool top_level;
5353
5355
5356 top_level = is_top_level(Irp);
5357
5358 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
5360
5361 Irp->IoStatus.Status = Status;
5363
5364 goto exit;
5365 }
5366
5367 TRACE("lock control\n");
5368
5369 if (!fcb) {
5370 ERR("fcb was NULL\n");
5372 goto exit;
5373 }
5374
5376
5378
5379 fcb->Header.IsFastIoPossible = fast_io_possible(fcb);
5380
5381exit:
5382 TRACE("returning %08lx\n", Status);
5383
5384 if (top_level)
5386
5388
5389 return Status;
5390}
NTSTATUS NTAPI FsRtlProcessFileLock(IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL)
Definition: filelock.c:1152

◆ _Dispatch_type_() [6/10]

_Dispatch_type_ ( IRP_MJ_POWER  )

Definition at line 5654 of file btrfs.c.

5656 {
5659 device_extension* Vcb = DeviceObject->DeviceExtension;
5660 bool top_level;
5661
5662 // no need for FsRtlEnterFileSystem, as this only ever gets called in a system thread
5663
5664 top_level = is_top_level(Irp);
5665
5666 Irp->IoStatus.Information = 0;
5667
5668 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
5669 volume_device_extension* vde = DeviceObject->DeviceExtension;
5670
5672 IrpSp->Parameters.Power.State.SystemState != PowerSystemWorking && vde->mounted_device) {
5674
5675 /* If power state is about to go to sleep or hibernate, do a flush. We do this on IRP_MJ_QUERY_POWER
5676 * rather than IRP_MJ_SET_POWER because we know that the hard disks are still awake. */
5677
5678 if (Vcb2) {
5679 ExAcquireResourceExclusiveLite(&Vcb2->tree_lock, true);
5680
5681 if (Vcb2->need_write && !Vcb2->readonly) {
5682 TRACE("doing protective flush on power state change\n");
5683 Status = do_write(Vcb2, NULL);
5684 } else
5686
5687 free_trees(Vcb2);
5688
5689 if (!NT_SUCCESS(Status))
5690 ERR("do_write returned %08lx\n", Status);
5691
5692 ExReleaseResourceLite(&Vcb2->tree_lock);
5693 }
5694 } else if (IrpSp->MinorFunction == IRP_MN_SET_POWER && IrpSp->Parameters.Power.Type == SystemPowerState &&
5695 IrpSp->Parameters.Power.State.SystemState == PowerSystemWorking && vde->mounted_device) {
5697
5698 /* If waking up, make sure that the FS hasn't been changed while we've been out (e.g., by dual-boot Linux) */
5699
5700 if (Vcb2) {
5701 PIO_WORKITEM work_item;
5702
5703 work_item = IoAllocateWorkItem(DeviceObject);
5704 if (!work_item) {
5705 ERR("out of memory\n");
5706 } else
5707 IoQueueWorkItem(work_item, check_after_wakeup, DelayedWorkQueue, Vcb2);
5708 }
5709 }
5710
5713 Status = PoCallDriver(vde->attached_device, Irp);
5714
5715 goto exit;
5716 } else if (Vcb && Vcb->type == VCB_TYPE_FS) {
5718
5719 Status = IoCallDriver(Vcb->Vpb->RealDevice, Irp);
5720
5721 goto exit;
5722 } else if (Vcb && Vcb->type == VCB_TYPE_BUS) {
5723 bus_device_extension* bde = DeviceObject->DeviceExtension;
5724
5727 Status = PoCallDriver(bde->attached_device, Irp);
5728
5729 goto exit;
5730 }
5731
5733 Irp->IoStatus.Status = STATUS_SUCCESS;
5734
5735 Status = Irp->IoStatus.Status;
5736
5738
5740
5741exit:
5742 if (top_level)
5744
5745 return Status;
5746}
NTSTATUS do_write(device_extension *Vcb, PIRP Irp)
Definition: flushthread.c:7877
#define VCB_TYPE_BUS
Definition: btrfs_drv.h:691
NTSTATUS NTSTATUS bool bool void free_trees(device_extension *Vcb) __attribute__((nonnull(1)))
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
@ PowerSystemWorking
Definition: ntpoapi.h:36
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT attached_device
Definition: btrfs_drv.h:880
PDEVICE_OBJECT mounted_device
Definition: btrfs_drv.h:876
PDEVICE_OBJECT attached_device
Definition: btrfs_drv.h:849
@ DelayedWorkQueue
Definition: extypes.h:190
#define IRP_MN_SET_POWER
_In_ SYSTEM_POWER_STATE SystemPowerState
Definition: iotypes.h:7519
#define IRP_MN_QUERY_POWER

◆ _Dispatch_type_() [7/10]

_Dispatch_type_ ( IRP_MJ_QUERY_VOLUME_INFORMATION  )

Definition at line 997 of file btrfs.c.

999 {
1002 ULONG BytesCopied = 0;
1003 device_extension* Vcb = DeviceObject->DeviceExtension;
1004 bool top_level;
1005
1007
1008 TRACE("query volume information\n");
1009 top_level = is_top_level(Irp);
1010
1011 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
1013 goto end;
1014 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
1016 goto end;
1017 }
1018
1020
1022
1023 switch (IrpSp->Parameters.QueryVolume.FsInformationClass) {
1025 {
1026 FILE_FS_ATTRIBUTE_INFORMATION* data = Irp->AssociatedIrp.SystemBuffer;
1027 bool overflow = false;
1028#ifndef __REACTOS__
1029 static const WCHAR ntfs[] = L"NTFS";
1030#endif
1031 static const WCHAR btrfs[] = L"Btrfs";
1032 const WCHAR* fs_name;
1033 ULONG fs_name_len, orig_fs_name_len;
1034
1035#ifndef __REACTOS__
1036 if (Irp->RequestorMode == UserMode && lie_about_fs_type()) {
1037 fs_name = ntfs;
1038 orig_fs_name_len = fs_name_len = sizeof(ntfs) - sizeof(WCHAR);
1039 } else {
1040 fs_name = btrfs;
1041 orig_fs_name_len = fs_name_len = sizeof(btrfs) - sizeof(WCHAR);
1042 }
1043#else
1044 fs_name = btrfs;
1045 orig_fs_name_len = fs_name_len = sizeof(btrfs) - sizeof(WCHAR);
1046#endif
1047
1048 TRACE("FileFsAttributeInformation\n");
1049
1050 if (IrpSp->Parameters.QueryVolume.Length < sizeof(FILE_FS_ATTRIBUTE_INFORMATION) - sizeof(WCHAR) + fs_name_len) {
1051 if (IrpSp->Parameters.QueryVolume.Length > sizeof(FILE_FS_ATTRIBUTE_INFORMATION) - sizeof(WCHAR))
1052 fs_name_len = IrpSp->Parameters.QueryVolume.Length - sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + sizeof(WCHAR);
1053 else
1054 fs_name_len = 0;
1055
1056 overflow = true;
1057 }
1058
1064 if (Vcb->readonly)
1065 data->FileSystemAttributes |= FILE_READ_ONLY_VOLUME;
1066
1067 // should also be FILE_FILE_COMPRESSION when supported
1068 data->MaximumComponentNameLength = 255; // FIXME - check
1069 data->FileSystemNameLength = orig_fs_name_len;
1070 RtlCopyMemory(data->FileSystemName, fs_name, fs_name_len);
1071
1072 BytesCopied = sizeof(FILE_FS_ATTRIBUTE_INFORMATION) - sizeof(WCHAR) + fs_name_len;
1074 break;
1075 }
1076
1078 {
1079 FILE_FS_DEVICE_INFORMATION* ffdi = Irp->AssociatedIrp.SystemBuffer;
1080
1081 TRACE("FileFsDeviceInformation\n");
1082
1084
1085 ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
1086 ffdi->Characteristics = Vcb->Vpb->RealDevice->Characteristics;
1087 ExReleaseResourceLite(&Vcb->tree_lock);
1088
1089 if (Vcb->readonly)
1091 else
1092 ffdi->Characteristics &= ~FILE_READ_ONLY_DEVICE;
1093
1096
1097 break;
1098 }
1099
1101 {
1102 FILE_FS_FULL_SIZE_INFORMATION* ffsi = Irp->AssociatedIrp.SystemBuffer;
1103
1104 TRACE("FileFsFullSizeInformation\n");
1105
1108 ffsi->SectorsPerAllocationUnit = Vcb->superblock.sector_size / 512;
1109 ffsi->BytesPerSector = 512;
1110
1113
1114 break;
1115 }
1116
1118 {
1119 FILE_FS_OBJECTID_INFORMATION* ffoi = Irp->AssociatedIrp.SystemBuffer;
1120
1121 TRACE("FileFsObjectIdInformation\n");
1122
1123 RtlCopyMemory(ffoi->ObjectId, &Vcb->superblock.uuid.uuid[0], sizeof(UCHAR) * 16);
1124 RtlZeroMemory(ffoi->ExtendedInfo, sizeof(ffoi->ExtendedInfo));
1125
1128
1129 break;
1130 }
1131
1133 {
1134 FILE_FS_SIZE_INFORMATION* ffsi = Irp->AssociatedIrp.SystemBuffer;
1135
1136 TRACE("FileFsSizeInformation\n");
1137
1139 ffsi->SectorsPerAllocationUnit = Vcb->superblock.sector_size / 512;
1140 ffsi->BytesPerSector = 512;
1141
1144
1145 break;
1146 }
1147
1149 {
1150 FILE_FS_VOLUME_INFORMATION* data = Irp->AssociatedIrp.SystemBuffer;
1152 bool overflow = false;
1153 ULONG label_len, orig_label_len;
1154
1155 TRACE("FileFsVolumeInformation\n");
1156 TRACE("max length = %lu\n", IrpSp->Parameters.QueryVolume.Length);
1157
1158 ExAcquireResourceSharedLite(&Vcb->tree_lock, true);
1159
1160 Status = utf8_to_utf16(NULL, 0, &label_len, Vcb->superblock.label, (ULONG)strlen(Vcb->superblock.label));
1161 if (!NT_SUCCESS(Status)) {
1162 ERR("utf8_to_utf16 returned %08lx\n", Status);
1163 ExReleaseResourceLite(&Vcb->tree_lock);
1164 break;
1165 }
1166
1167 orig_label_len = label_len;
1168
1169 if (IrpSp->Parameters.QueryVolume.Length < offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + label_len) {
1170 if (IrpSp->Parameters.QueryVolume.Length > offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel))
1171 label_len = IrpSp->Parameters.QueryVolume.Length - offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel);
1172 else
1173 label_len = 0;
1174
1175 overflow = true;
1176 }
1177
1178 TRACE("label_len = %lu\n", label_len);
1179
1181
1182 ffvi.VolumeSerialNumber = Vcb->superblock.uuid.uuid[12] << 24 | Vcb->superblock.uuid.uuid[13] << 16 | Vcb->superblock.uuid.uuid[14] << 8 | Vcb->superblock.uuid.uuid[15];
1183 ffvi.VolumeLabelLength = orig_label_len;
1184
1185 RtlCopyMemory(data, &ffvi, min(offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel), IrpSp->Parameters.QueryVolume.Length));
1186
1187 if (label_len > 0) {
1188 ULONG bytecount;
1189
1190 Status = utf8_to_utf16(&data->VolumeLabel[0], label_len, &bytecount, Vcb->superblock.label, (ULONG)strlen(Vcb->superblock.label));
1192 ERR("utf8_to_utf16 returned %08lx\n", Status);
1193 ExReleaseResourceLite(&Vcb->tree_lock);
1194 break;
1195 }
1196
1197 TRACE("label = %.*S\n", (int)(label_len / sizeof(WCHAR)), data->VolumeLabel);
1198 }
1199
1200 ExReleaseResourceLite(&Vcb->tree_lock);
1201
1202 BytesCopied = offsetof(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + label_len;
1204 break;
1205 }
1206
1207#ifndef __REACTOS__
1208#ifdef _MSC_VER // not in mingw yet
1209 case FileFsSectorSizeInformation:
1210 {
1211 FILE_FS_SECTOR_SIZE_INFORMATION* data = Irp->AssociatedIrp.SystemBuffer;
1212
1213 data->LogicalBytesPerSector = Vcb->superblock.sector_size;
1214 data->PhysicalBytesPerSectorForAtomicity = Vcb->superblock.sector_size;
1215 data->PhysicalBytesPerSectorForPerformance = Vcb->superblock.sector_size;
1216 data->FileSystemEffectivePhysicalBytesPerSectorForAtomicity = Vcb->superblock.sector_size;
1217 data->ByteOffsetForSectorAlignment = 0;
1218 data->ByteOffsetForPartitionAlignment = 0;
1219
1220 data->Flags = SSINFO_FLAGS_ALIGNED_DEVICE | SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE;
1221
1222 if (Vcb->trim && !Vcb->options.no_trim)
1223 data->Flags |= SSINFO_FLAGS_TRIM_ENABLED;
1224
1225 BytesCopied = sizeof(FILE_FS_SECTOR_SIZE_INFORMATION);
1227
1228 break;
1229 }
1230#endif
1231#endif /* __REACTOS__ */
1232
1233 default:
1235 WARN("unknown FsInformationClass %u\n", IrpSp->Parameters.QueryVolume.FsInformationClass);
1236 break;
1237 }
1238
1240 Irp->IoStatus.Information = 0;
1241 else
1242 Irp->IoStatus.Information = BytesCopied;
1243
1244end:
1245 Irp->IoStatus.Status = Status;
1246
1248
1249 if (top_level)
1251
1252 TRACE("query volume information returning %08lx\n", Status);
1253
1255
1256 return Status;
1257}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define WARN(fmt,...)
Definition: debug.h:112
#define FILE_SUPPORTS_POSIX_UNLINK_RENAME
Definition: btrfs_drv.h:152
#define FILE_SUPPORTS_BLOCK_REFCOUNTING
Definition: btrfs_drv.h:148
UINT64 uint64_t
Definition: types.h:77
static bool lie_about_fs_type()
Definition: btrfs.c:687
static void calculate_total_space(_In_ device_extension *Vcb, _Out_ uint64_t *totalsize, _Out_ uint64_t *freespace)
Definition: btrfs.c:619
NTSTATUS utf8_to_utf16(WCHAR *dest, ULONG dest_max, ULONG *dest_len, char *src, ULONG src_len)
Definition: btrfs.c:811
#define FILE_NAMED_STREAMS
Definition: from_kernel.h:245
#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES
Definition: from_kernel.h:250
#define FILE_SUPPORTS_SPARSE_FILES
Definition: from_kernel.h:239
#define FILE_SUPPORTS_REPARSE_POINTS
Definition: from_kernel.h:240
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
struct _FILE_FS_ATTRIBUTE_INFORMATION FILE_FS_ATTRIBUTE_INFORMATION
#define FILE_SUPPORTS_HARD_LINKS
Definition: from_kernel.h:249
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
@ FileFsSizeInformation
Definition: from_kernel.h:221
#define FILE_SUPPORTS_OBJECT_IDS
Definition: from_kernel.h:243
struct _FILE_FS_SIZE_INFORMATION FILE_FS_SIZE_INFORMATION
#define FILE_PERSISTENT_ACLS
Definition: from_kernel.h:236
#define FILE_CASE_SENSITIVE_SEARCH
Definition: from_kernel.h:233
struct _FILE_FS_FULL_SIZE_INFORMATION FILE_FS_FULL_SIZE_INFORMATION
#define FILE_CASE_PRESERVED_NAMES
Definition: from_kernel.h:234
#define FILE_SUPPORTS_OPEN_BY_FILE_ID
Definition: from_kernel.h:251
#define FILE_UNICODE_ON_DISK
Definition: from_kernel.h:235
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT _In_ PNDIS_PACKET _In_ UINT _Out_ PUINT BytesCopied
Definition: ndis.h:3171
#define UserMode
Definition: asm.h:35
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
#define FileFsObjectIdInformation
Definition: ntifs_ex.h:390
#define L(x)
Definition: ntvdm.h:50
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define offsetof(TYPE, MEMBER)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
LARGE_INTEGER ActualAvailableAllocationUnits
Definition: from_kernel.h:272
LARGE_INTEGER CallerAvailableAllocationUnits
Definition: from_kernel.h:271
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:270
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:263
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
struct _FILE_FS_OBJECTID_INFORMATION FILE_FS_OBJECTID_INFORMATION
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ _Dispatch_type_() [8/10]

_Dispatch_type_ ( IRP_MJ_SET_VOLUME_INFORMATION  )

Definition at line 1447 of file btrfs.c.

1449 {
1451 device_extension* Vcb = DeviceObject->DeviceExtension;
1453 bool top_level;
1454
1456
1457 TRACE("set volume information\n");
1458
1459 top_level = is_top_level(Irp);
1460
1461 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
1463 goto end;
1464 } else if (!Vcb || Vcb->type != VCB_TYPE_FS) {
1466 goto end;
1467 }
1468
1470
1471 if (Vcb->readonly) {
1473 goto end;
1474 }
1475
1476 if (Vcb->removing || Vcb->locked) {
1478 goto end;
1479 }
1480
1481 switch (IrpSp->Parameters.SetVolume.FsInformationClass) {
1483 FIXME("STUB: FileFsControlInformation\n");
1484 break;
1485
1487 TRACE("FileFsLabelInformation\n");
1488
1489 Status = set_label(Vcb, Irp->AssociatedIrp.SystemBuffer);
1490 break;
1491
1493 FIXME("STUB: FileFsObjectIdInformation\n");
1494 break;
1495
1496 default:
1497 WARN("Unrecognized FsInformationClass 0x%x\n", IrpSp->Parameters.SetVolume.FsInformationClass);
1498 break;
1499 }
1500
1501end:
1502 Irp->IoStatus.Status = Status;
1503 Irp->IoStatus.Information = 0;
1504
1505 TRACE("returning %08lx\n", Status);
1506
1508
1509 if (top_level)
1511
1513
1514 return Status;
1515}
#define FIXME(fmt,...)
Definition: debug.h:111
static NTSTATUS set_label(_In_ device_extension *Vcb, _In_ FILE_FS_LABEL_INFORMATION *ffli)
Definition: btrfs.c:1392
@ FileFsControlInformation
Definition: from_kernel.h:224
@ FileFsLabelInformation
Definition: from_kernel.h:220
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

◆ _Dispatch_type_() [9/10]

_Dispatch_type_ ( IRP_MJ_SHUTDOWN  )

Definition at line 5510 of file btrfs.c.

5512 {
5514 bool top_level;
5515 device_extension* Vcb = DeviceObject->DeviceExtension;
5516
5518
5519 TRACE("shutdown\n");
5520
5521 top_level = is_top_level(Irp);
5522
5523 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
5525 goto end;
5526 }
5527
5529
5531
5532end:
5533 Irp->IoStatus.Status = Status;
5534 Irp->IoStatus.Information = 0;
5535
5537
5538 if (top_level)
5540
5542
5543 return Status;
5544}
void do_shutdown(PIRP Irp)
Definition: btrfs.c:5392

◆ _Dispatch_type_() [10/10]

_Dispatch_type_ ( IRP_MJ_SYSTEM_CONTROL  )

Definition at line 5748 of file btrfs.c.

5750 {
5752 device_extension* Vcb = DeviceObject->DeviceExtension;
5753 bool top_level;
5754
5756
5757 top_level = is_top_level(Irp);
5758
5759 Irp->IoStatus.Information = 0;
5760
5761 if (Vcb && Vcb->type == VCB_TYPE_VOLUME) {
5762 volume_device_extension* vde = DeviceObject->DeviceExtension;
5763
5765
5767
5768 goto exit;
5769 } else if (Vcb && Vcb->type == VCB_TYPE_FS) {
5771
5772 Status = IoCallDriver(Vcb->Vpb->RealDevice, Irp);
5773
5774 goto exit;
5775 } else if (Vcb && Vcb->type == VCB_TYPE_BUS) {
5776 bus_device_extension* bde = DeviceObject->DeviceExtension;
5777
5779
5781
5782 goto exit;
5783 }
5784
5785 Status = Irp->IoStatus.Status;
5787
5788exit:
5789 if (top_level)
5791
5793
5794 return Status;
5795}

◆ _Function_class_() [1/6]

_Function_class_ ( DRIVER_ADD_DEVICE  )

Definition at line 6133 of file btrfs.c.

6134 {
6135 LIST_ENTRY* le;
6137 UNICODE_STRING volname;
6138 ULONG i;
6139 WCHAR* s;
6140 pdo_device_extension* pdode = NULL;
6141 PDEVICE_OBJECT voldev;
6143 UNICODE_STRING arc_name_us;
6144 WCHAR* anp;
6145
6146 static const WCHAR arc_name_prefix[] = L"\\ArcName\\btrfs(";
6147
6148 WCHAR arc_name[(sizeof(arc_name_prefix) / sizeof(WCHAR)) - 1 + 37];
6149
6150 TRACE("(%p, %p)\n", DriverObject, PhysicalDeviceObject);
6151
6153
6155
6156 le = pdo_list.Flink;
6157 while (le != &pdo_list) {
6159
6160 if (pdode2->pdo == PhysicalDeviceObject) {
6161 pdode = pdode2;
6162 break;
6163 }
6164
6165 le = le->Flink;
6166 }
6167
6168 if (!pdode) {
6169 WARN("unrecognized PDO %p\n", PhysicalDeviceObject);
6171 goto end;
6172 }
6173
6175
6176 if (pdode->vde) { // if already done, return success
6178 goto end2;
6179 }
6180
6181 volname.Length = volname.MaximumLength = (sizeof(BTRFS_VOLUME_PREFIX) - sizeof(WCHAR)) + ((36 + 1) * sizeof(WCHAR));
6182 volname.Buffer = ExAllocatePoolWithTag(PagedPool, volname.MaximumLength, ALLOC_TAG); // FIXME - when do we free this?
6183
6184 if (!volname.Buffer) {
6185 ERR("out of memory\n");
6187 goto end2;
6188 }
6189
6191 RtlCopyMemory(arc_name, arc_name_prefix, sizeof(arc_name_prefix) - sizeof(WCHAR));
6192
6193 anp = &arc_name[(sizeof(arc_name_prefix) / sizeof(WCHAR)) - 1];
6194 s = &volname.Buffer[(sizeof(BTRFS_VOLUME_PREFIX) / sizeof(WCHAR)) - 1];
6195
6196 for (i = 0; i < 16; i++) {
6197 *s = *anp = hex_digit(pdode->uuid.uuid[i] >> 4);
6198 s++;
6199 anp++;
6200
6201 *s = *anp = hex_digit(pdode->uuid.uuid[i] & 0xf);
6202 s++;
6203 anp++;
6204
6205 if (i == 3 || i == 5 || i == 7 || i == 9) {
6206 *s = *anp = '-';
6207 s++;
6208 anp++;
6209 }
6210 }
6211
6212 *s = '}';
6213 *anp = ')';
6214
6217 if (!NT_SUCCESS(Status)) {
6218 ERR("IoCreateDevice returned %08lx\n", Status);
6219 goto end2;
6220 }
6221
6222 arc_name_us.Buffer = arc_name;
6223 arc_name_us.Length = arc_name_us.MaximumLength = sizeof(arc_name);
6224
6225 Status = IoCreateSymbolicLink(&arc_name_us, &volname);
6226 if (!NT_SUCCESS(Status))
6227 WARN("IoCreateSymbolicLink returned %08lx\n", Status);
6228
6229 voldev->SectorSize = PhysicalDeviceObject->SectorSize;
6230 voldev->Flags |= DO_DIRECT_IO;
6231
6232 vde = voldev->DeviceExtension;
6233 vde->type = VCB_TYPE_VOLUME;
6234 vde->name = volname;
6235 vde->device = voldev;
6236 vde->mounted_device = NULL;
6238 vde->pdode = pdode;
6239 vde->removing = false;
6240 vde->dead = false;
6241 vde->open_count = 0;
6242
6243 Status = IoRegisterDeviceInterface(PhysicalDeviceObject, &GUID_DEVINTERFACE_VOLUME, NULL, &vde->bus_name);
6244 if (!NT_SUCCESS(Status))
6245 WARN("IoRegisterDeviceInterface returned %08lx\n", Status);
6246
6248
6249 pdode->vde = vde;
6250
6251 if (pdode->removable)
6252 voldev->Characteristics |= FILE_REMOVABLE_MEDIA;
6253
6254 if (RtlCompareMemory(&boot_uuid, &pdode->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
6257 }
6258
6259 voldev->Flags &= ~DO_DEVICE_INITIALIZING;
6260
6262 if (!NT_SUCCESS(Status))
6263 WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
6264
6266
6267end2:
6269
6270end:
6272
6273 return Status;
6274}
#define BTRFS_VOLUME_PREFIX
Definition: btrfs_drv.h:127
#define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL
Definition: btrfs_drv.h:156
#define ALLOC_TAG
Definition: btrfs_drv.h:87
#define hex_digit(c)
Definition: btrfs_drv.h:1748
#define UNUSED(x)
Definition: btrfs_drv.h:82
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
BTRFS_UUID boot_uuid
Definition: boot.c:33
PDRIVER_OBJECT drvobj
Definition: btrfs.c:65
LIST_ENTRY pdo_list
Definition: btrfs.c:104
ERESOURCE pdo_list_lock
Definition: btrfs.c:103
bool is_windows_8
Definition: btrfs.c:111
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
#define PagedPool
Definition: env_spec_w32.h:308
GLdouble s
Definition: gl.h:2039
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
uint8_t uuid[16]
Definition: btrfs.h:140
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
struct pdo_device_extension * pdode
Definition: btrfs_drv.h:878
PDEVICE_OBJECT device
Definition: btrfs_drv.h:875
UNICODE_STRING name
Definition: btrfs_drv.h:874
UNICODE_STRING bus_name
Definition: btrfs_drv.h:879
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:877
Definition: list.h:27
ERESOURCE child_lock
Definition: btrfs_drv.h:896
PDEVICE_OBJECT pdo
Definition: btrfs_drv.h:890
volume_device_extension * vde
Definition: btrfs_drv.h:889
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213

◆ _Function_class_() [2/6]

_Function_class_ ( DRIVER_INITIALIZE  )

Definition at line 6276 of file btrfs.c.

6277 {
6280 UNICODE_STRING device_nameW;
6281 UNICODE_STRING dosdevice_nameW;
6284 HANDLE regh;
6285 OBJECT_ATTRIBUTES oa, system_thread_attributes;
6286 ULONG dispos;
6288
6290
6291 Status = RtlGetVersion(&ver);
6292 if (!NT_SUCCESS(Status)) {
6293 ERR("RtlGetVersion returned %08lx\n", Status);
6294 return Status;
6295 }
6296
6297 is_windows_8 = ver.dwMajorVersion > 6 || (ver.dwMajorVersion == 6 && ver.dwMinorVersion >= 2);
6298
6300
6303
6304#ifdef _DEBUG
6305 ExInitializeResourceLite(&log_lock);
6306#endif
6308
6313
6316
6317 if (!registry_path.Buffer) {
6318 ERR("out of memory\n");
6320 }
6321
6323
6325
6326#ifdef _DEBUG
6327 if (debug_log_level > 0)
6328 init_logging();
6329
6330 log_started = true;
6331#endif
6332
6333 TRACE("DriverEntry\n");
6334
6335#if !defined(__REACTOS__) && (defined(_X86_) || defined(_AMD64_))
6336 check_cpu();
6337#endif
6338
6339 if (ver.dwMajorVersion > 6 || (ver.dwMajorVersion == 6 && ver.dwMinorVersion >= 2)) { // Windows 8 or above
6341 tPsIsDiskCountersEnabled fPsIsDiskCountersEnabled;
6342
6343 RtlInitUnicodeString(&name, L"PsIsDiskCountersEnabled");
6344 fPsIsDiskCountersEnabled = (tPsIsDiskCountersEnabled)MmGetSystemRoutineAddress(&name);
6345
6346 if (fPsIsDiskCountersEnabled) {
6347 diskacc = fPsIsDiskCountersEnabled();
6348
6349 RtlInitUnicodeString(&name, L"PsUpdateDiskCounters");
6351
6353 diskacc = false;
6354
6355 RtlInitUnicodeString(&name, L"FsRtlUpdateDiskCounters");
6357 }
6358
6359 RtlInitUnicodeString(&name, L"CcCopyReadEx");
6361
6362 RtlInitUnicodeString(&name, L"CcCopyWriteEx");
6364
6365 RtlInitUnicodeString(&name, L"CcSetAdditionalCacheAttributesEx");
6367
6368 RtlInitUnicodeString(&name, L"FsRtlCheckLockForOplockRequest");
6370 } else {
6377 }
6378
6379 if (ver.dwMajorVersion > 6 || (ver.dwMajorVersion == 6 && ver.dwMinorVersion >= 1)) { // Windows 7 or above
6381
6382 RtlInitUnicodeString(&name, L"IoUnregisterPlugPlayNotificationEx");
6384
6385 RtlInitUnicodeString(&name, L"FsRtlAreThereCurrentOrInProgressFileLocks");
6387 } else {
6390 }
6391
6392 if (ver.dwMajorVersion >= 6) { // Windows Vista or above
6394
6395 RtlInitUnicodeString(&name, L"FsRtlGetEcpListFromIrp");
6397
6398 RtlInitUnicodeString(&name, L"FsRtlGetNextExtraCreateParameter");
6400
6401 RtlInitUnicodeString(&name, L"FsRtlValidateReparsePointBuffer");
6403 } else {
6407 }
6408
6410
6412
6413 DriverObject->DriverExtension->AddDevice = AddDevice;
6414
6415 DriverObject->MajorFunction[IRP_MJ_CREATE] = drv_create;
6416 DriverObject->MajorFunction[IRP_MJ_CLOSE] = drv_close;
6417 DriverObject->MajorFunction[IRP_MJ_READ] = drv_read;
6418 DriverObject->MajorFunction[IRP_MJ_WRITE] = drv_write;
6419 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = drv_query_information;
6420 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = drv_set_information;
6421 DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = drv_query_ea;
6422 DriverObject->MajorFunction[IRP_MJ_SET_EA] = drv_set_ea;
6423 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = drv_flush_buffers;
6424 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = drv_query_volume_information;
6425 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = drv_set_volume_information;
6426 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = drv_directory_control;
6427 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = drv_file_system_control;
6428 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = drv_device_control;
6429 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = drv_shutdown;
6430 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = drv_lock_control;
6431 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = drv_cleanup;
6432 DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = drv_query_security;
6433 DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = drv_set_security;
6434 DriverObject->MajorFunction[IRP_MJ_POWER] = drv_power;
6435 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = drv_system_control;
6436 DriverObject->MajorFunction[IRP_MJ_PNP] = drv_pnp;
6437
6438 init_fast_io_dispatch(&DriverObject->FastIoDispatch);
6439
6440 device_nameW.Buffer = (WCHAR*)device_name;
6441 device_nameW.Length = device_nameW.MaximumLength = sizeof(device_name) - sizeof(WCHAR);
6442 dosdevice_nameW.Buffer = (WCHAR*)dosdevice_name;
6443 dosdevice_nameW.Length = dosdevice_nameW.MaximumLength = sizeof(dosdevice_name) - sizeof(WCHAR);
6444
6447 if (!NT_SUCCESS(Status)) {
6448 ERR("IoCreateDevice returned %08lx\n", Status);
6449 return Status;
6450 }
6451
6454
6456
6457 cde->type = VCB_TYPE_CONTROL;
6458
6459 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
6460
6461 Status = IoCreateSymbolicLink(&dosdevice_nameW, &device_nameW);
6462 if (!NT_SUCCESS(Status)) {
6463 ERR("IoCreateSymbolicLink returned %08lx\n", Status);
6464 return Status;
6465 }
6466
6467 init_cache();
6468
6472
6474
6477 if (!NT_SUCCESS(Status)) {
6478 ERR("ZwCreateKey returned %08lx\n", Status);
6479 return Status;
6480 }
6481
6482 watch_registry(regh);
6483
6486 if (!NT_SUCCESS(Status)) {
6487 ERR("IoCreateDevice returned %08lx\n", Status);
6488 return Status;
6489 }
6490
6492
6493 RtlZeroMemory(bde, sizeof(bus_device_extension));
6494
6495 bde->type = VCB_TYPE_BUS;
6496
6498 NULL, NULL, 0, &bde->buspdo);
6499 if (!NT_SUCCESS(Status)) {
6500 ERR("IoReportDetectedDevice returned %08lx\n", Status);
6501 return Status;
6502 }
6503
6504 Status = IoRegisterDeviceInterface(bde->buspdo, &BtrfsBusInterface, NULL, &bde->bus_name);
6505 if (!NT_SUCCESS(Status))
6506 WARN("IoRegisterDeviceInterface returned %08lx\n", Status);
6507
6509
6510 busobj->Flags &= ~DO_DEVICE_INITIALIZING;
6511
6513 if (!NT_SUCCESS(Status))
6514 WARN("IoSetDeviceInterfaceState returned %08lx\n", Status);
6515
6517
6518 InitializeObjectAttributes(&system_thread_attributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
6519
6520 Status = PsCreateSystemThread(&degraded_wait_handle, 0, &system_thread_attributes, NULL, NULL, degraded_wait_thread, NULL);
6521 if (!NT_SUCCESS(Status))
6522 WARN("PsCreateSystemThread returned %08lx\n", Status);
6523
6525
6527 (PVOID)&GUID_DEVINTERFACE_VOLUME, DriverObject, volume_notification, NULL, &notification_entry2);
6528 if (!NT_SUCCESS(Status))
6529 ERR("IoRegisterPlugPlayNotification returned %08lx\n", Status);
6530
6532 (PVOID)&GUID_DEVINTERFACE_HIDDEN_VOLUME, DriverObject, volume_notification, NULL, &notification_entry3);
6533 if (!NT_SUCCESS(Status))
6534 ERR("IoRegisterPlugPlayNotification returned %08lx\n", Status);
6535
6537 (PVOID)&GUID_DEVINTERFACE_DISK, DriverObject, pnp_notification, DriverObject, &notification_entry);
6538 if (!NT_SUCCESS(Status))
6539 ERR("IoRegisterPlugPlayNotification returned %08lx\n", Status);
6540
6541 finished_probing = true;
6542
6544
6545 // Status = PsCreateSystemThread(&mountmgr_thread_handle, 0, &system_thread_attributes, NULL, NULL, mountmgr_thread, NULL);
6546 // if (!NT_SUCCESS(Status))
6547 // WARN("PsCreateSystemThread returned %08lx\n", Status);
6548
6550
6552
6553 return STATUS_SUCCESS;
6554}
NTSTATUS __stdcall compat_FsRtlValidateReparsePointBuffer(IN ULONG BufferLength, IN PREPARSE_DATA_BUFFER ReparseBuffer)
Definition: fsrtl.c:32
NTSTATUS(__stdcall * tFsRtlValidateReparsePointBuffer)(ULONG BufferLength, PREPARSE_DATA_BUFFER ReparseBuffer)
Definition: btrfs_drv.h:1864
NTSTATUS(__stdcall * tIoUnregisterPlugPlayNotificationEx)(PVOID NotificationEntry)
Definition: btrfs_drv.h:1857
BOOLEAN(__stdcall * tPsIsDiskCountersEnabled)()
Definition: btrfs_drv.h:1833
KSPIN_LOCK fve_data_lock
Definition: search.c:63
VOID(__stdcall * tCcSetAdditionalCacheAttributesEx)(PFILE_OBJECT FileObject, ULONG Flags)
Definition: btrfs_drv.h:1853
BOOLEAN(__stdcall * tFsRtlCheckLockForOplockRequest)(PFILE_LOCK FileLock, PLARGE_INTEGER AllocationSize)
Definition: btrfs_drv.h:1866
void init_cache()
Definition: cache.c:85
VOID(__stdcall * tFsRtlUpdateDiskCounters)(ULONG64 BytesRead, ULONG64 BytesWritten)
Definition: btrfs_drv.h:1855
void init_fast_io_dispatch(FAST_IO_DISPATCH **fiod)
Definition: fastio.c:535
VOID(__stdcall * tPsUpdateDiskCounters)(PEPROCESS Process, ULONG64 BytesRead, ULONG64 BytesWritten, ULONG ReadOperationCount, ULONG WriteOperationCount, ULONG FlushOperationCount)
Definition: btrfs_drv.h:1835
NTSTATUS(__stdcall * tFsRtlGetEcpListFromIrp)(PIRP Irp, PECP_LIST *EcpList)
Definition: btrfs_drv.h:1859
void watch_registry(HANDLE regh)
Definition: registry.c:1036
BOOLEAN(__stdcall * tFsRtlAreThereCurrentOrInProgressFileLocks)(PFILE_LOCK FileLock)
Definition: btrfs_drv.h:1868
NTSTATUS(__stdcall * tFsRtlGetNextExtraCreateParameter)(PECP_LIST EcpList, PVOID CurrentEcpContext, LPGUID NextEcpType, PVOID *NextEcpContext, ULONG *NextEcpContextSize)
Definition: btrfs_drv.h:1861
BOOLEAN(__stdcall * tCcCopyWriteEx)(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, PVOID Buffer, PETHREAD IoIssuerThread)
Definition: btrfs_drv.h:1838
void read_registry(PUNICODE_STRING regpath, bool refresh)
Definition: registry.c:777
BOOLEAN(__stdcall * tCcCopyReadEx)(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PETHREAD IoIssuerThread)
Definition: btrfs_drv.h:1841
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:158
void check_system_root()
Definition: boot.c:336
UNICODE_STRING log_file
Definition: btrfs.c:89
tCcCopyReadEx fCcCopyReadEx
Definition: btrfs.c:91
tCcCopyWriteEx fCcCopyWriteEx
Definition: btrfs.c:92
bool diskacc
Definition: btrfs.c:101
UNICODE_STRING log_device
Definition: btrfs.c:89
LIST_ENTRY VcbList
Definition: btrfs.c:69
UNICODE_STRING registry_path
Definition: btrfs.c:89
tFsRtlAreThereCurrentOrInProgressFileLocks fFsRtlAreThereCurrentOrInProgressFileLocks
Definition: btrfs.c:100
static const WCHAR device_name[]
Definition: btrfs.c:60
KEVENT mountmgr_thread_event
Definition: btrfs.c:108
static const WCHAR dosdevice_name[]
Definition: btrfs.c:61
tCcSetAdditionalCacheAttributesEx fCcSetAdditionalCacheAttributesEx
Definition: btrfs.c:93
tPsUpdateDiskCounters fPsUpdateDiskCounters
Definition: btrfs.c:90
ERESOURCE mapping_lock
Definition: btrfs.c:103
tFsRtlGetEcpListFromIrp fFsRtlGetEcpListFromIrp
Definition: btrfs.c:96
tFsRtlCheckLockForOplockRequest fFsRtlCheckLockForOplockRequest
Definition: btrfs.c:99
tFsRtlUpdateDiskCounters fFsRtlUpdateDiskCounters
Definition: btrfs.c:94
tFsRtlGetNextExtraCreateParameter fFsRtlGetNextExtraCreateParameter
Definition: btrfs.c:97
bool log_started
Definition: btrfs.c:88
ERESOURCE global_loading_lock
Definition: btrfs.c:70
LIST_ENTRY uid_map_list
Definition: btrfs.c:68
void * notification_entry3
Definition: btrfs.c:102
HANDLE degraded_wait_handle
Definition: btrfs.c:106
tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx
Definition: btrfs.c:95
bool finished_probing
Definition: btrfs.c:105
LIST_ENTRY gid_map_list
Definition: btrfs.c:68
tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer
Definition: btrfs.c:98
PDEVICE_OBJECT busobj
Definition: btrfs.c:66
void * notification_entry2
Definition: btrfs.c:102
uint32_t debug_log_level
Definition: btrfs.c:71
ERESOURCE boot_lock
Definition: btrfs.c:110
void * notification_entry
Definition: btrfs.c:102
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static DRIVER_UNLOAD DriverUnload
Definition: kbdclass.c:17
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static ACCESS_MASK const OBJECT_ATTRIBUTES ULONG const UNICODE_STRING ULONG PULONG dispos
Definition: reg.c:132
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define KEY_NOTIFY
Definition: nt_native.h:1020
@ NotificationEvent
VOID NTAPI IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:987
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
DRIVER_ADD_DEVICE AddDevice
Definition: parport.h:72
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
NTSTATUS NTAPI IoRegisterPlugPlayNotification(_In_ IO_NOTIFICATION_EVENT_CATEGORY EventCategory, _In_ ULONG EventCategoryFlags, _In_opt_ PVOID EventCategoryData, _In_ PDRIVER_OBJECT DriverObject, _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, _Inout_opt_ PVOID Context, _Out_ PVOID *NotificationEntry)
Definition: pnpnotify.c:345
NTSTATUS NTAPI IoReportDetectedDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ INTERFACE_TYPE LegacyBusType, _In_ ULONG BusNumber, _In_ ULONG SlotNumber, _In_opt_ PCM_RESOURCE_LIST ResourceList, _In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, _In_ BOOLEAN ResourceAssigned, _Inout_ PDEVICE_OBJECT *DeviceObject)
Definition: pnpreport.c:148
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:114
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:140
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
ULONG dwMinorVersion
Definition: rtltypes.h:248
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:246
ULONG dwMajorVersion
Definition: rtltypes.h:247
UNICODE_STRING bus_name
Definition: btrfs_drv.h:850
PDEVICE_OBJECT buspdo
Definition: btrfs_drv.h:848
Definition: name.c:39
PVOID NTAPI MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
Definition: sysldr.c:3601
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
@ BusRelations
Definition: iotypes.h:2152
#define IRP_MJ_QUERY_EA
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MJ_QUERY_SECURITY
#define IRP_MJ_SET_EA
#define IRP_MJ_SYSTEM_CONTROL
@ EventCategoryDeviceInterfaceChange
Definition: iotypes.h:1226
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_POWER
#define IRP_MJ_SET_SECURITY
#define IRP_MJ_CLEANUP
#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
Definition: iotypes.h:1239
struct _OSVERSIONINFOW RTL_OSVERSIONINFOW

◆ _Function_class_() [3/6]

_Function_class_ ( DRIVER_UNLOAD  )

Definition at line 330 of file btrfs.c.

331 {
332 UNICODE_STRING dosdevice_nameW;
333
334 TRACE("(%p)\n", DriverObject);
335
336 dosdevice_nameW.Buffer = (WCHAR*)dosdevice_name;
337 dosdevice_nameW.Length = dosdevice_nameW.MaximumLength = sizeof(dosdevice_name) - sizeof(WCHAR);
338
339 IoDeleteSymbolicLink(&dosdevice_nameW);
340 IoDeleteDevice(DriverObject->DeviceObject);
341
342 while (!IsListEmpty(&uid_map_list)) {
344 uid_map* um = CONTAINING_RECORD(le, uid_map, listentry);
345
346 ExFreePool(um->sid);
347
348 ExFreePool(um);
349 }
350
351 while (!IsListEmpty(&gid_map_list)) {
353
354 ExFreePool(gm->sid);
355 ExFreePool(gm);
356 }
357
358 // FIXME - free volumes and their devpaths
359
360#ifdef _DEBUG
361 if (comfo)
362 ObDereferenceObject(comfo);
363
364 if (log_handle)
365 ZwClose(log_handle);
366#endif
367
370
371 if (log_device.Buffer)
373
374 if (log_file.Buffer)
376
379
380#ifdef _DEBUG
381 ExDeleteResourceLite(&log_lock);
382#endif
384}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PSID sid
Definition: btrfs_drv.h:910
PSID sid
Definition: btrfs_drv.h:904
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ _Function_class_() [4/6]

_Function_class_ ( IO_COMPLETION_ROUTINE  )

Definition at line 1259 of file btrfs.c.

1260 {
1261 read_context* context = conptr;
1262
1264
1265 context->iosb = Irp->IoStatus;
1266 KeSetEvent(&context->Event, 0, false);
1267
1269}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:7252

◆ _Function_class_() [5/6]

_Function_class_ ( IO_WORKITEM_ROUTINE  )

Definition at line 1648 of file btrfs.c.

1649 {
1650 notification_fcb* nf = con;
1651
1653
1654 ExAcquireResourceSharedLite(&nf->fileref->fcb->Vcb->tree_lock, TRUE); // protect us from fileref being reaped
1655
1657
1658 free_fileref(nf->fileref);
1659
1660 ExReleaseResourceLite(&nf->fileref->fcb->Vcb->tree_lock);
1661
1663
1664 ExFreePool(nf);
1665}
#define TRUE
Definition: types.h:120
void free_fileref(_Inout_ file_ref *fr)
Definition: btrfs.c:1856
static void send_notification_fcb(_In_ file_ref *fileref, _In_ ULONG filter_match, _In_ ULONG action, _In_opt_ PUNICODE_STRING stream)
Definition: btrfs.c:1557
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
ULONG filter_match
Definition: btrfs.c:1642
ULONG action
Definition: btrfs.c:1643
PUNICODE_STRING stream
Definition: btrfs.c:1644
file_ref * fileref
Definition: btrfs.c:1641
PIO_WORKITEM work_item
Definition: btrfs.c:1645

◆ _Function_class_() [6/6]

_Function_class_ ( KSTART_ROUTINE  )

Definition at line 6110 of file btrfs.c.

6111 {
6112 KTIMER timer;
6113 LARGE_INTEGER delay;
6114
6115 UNUSED(context);
6116
6117 KeInitializeTimer(&timer);
6118
6119 delay.QuadPart = -30000000; // wait three seconds
6120 KeSetTimer(&timer, delay, NULL);
6122
6123 TRACE("timer expired\n");
6124
6125 degraded_wait = false;
6126
6129
6131}
bool degraded_wait
Definition: btrfs.c:107
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KernelMode
Definition: asm.h:34
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1145
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
@ Executive
Definition: ketypes.h:415

◆ _Requires_exclusive_lock_held_()

_Requires_exclusive_lock_held_ ( Vcb->  tree_lock)

◆ _Success_() [1/2]

_Success_ ( return >=  0)

◆ _Success_() [2/2]

_Success_ ( return  = = 0)

Definition at line 427 of file btrfs.c.

428 {
429 DIR_ITEM* xa = (DIR_ITEM*)item;
430 USHORT xasize;
431
432 while (true) {
433 if (size < sizeof(DIR_ITEM) || size < (sizeof(DIR_ITEM) - 1 + xa->m + xa->n)) {
434 WARN("DIR_ITEM is truncated\n");
435 return false;
436 }
437
438 if (xa->n == strlen(name) && RtlCompareMemory(name, xa->name, xa->n) == xa->n) {
439 TRACE("found xattr %s\n", name);
440
441 *datalen = xa->m;
442
443 if (xa->m > 0) {
445 if (!*data) {
446 ERR("out of memory\n");
447 return false;
448 }
449
450 RtlCopyMemory(*data, &xa->name[xa->n], xa->m);
451 } else
452 *data = NULL;
453
454 return true;
455 }
456
457 xasize = sizeof(DIR_ITEM) - 1 + xa->m + xa->n;
458
459 if (size > xasize) {
460 size -= xasize;
461 xa = (DIR_ITEM*)&xa->name[xa->m + xa->n];
462 } else
463 break;
464 }
465
466 TRACE("xattr %s not found\n", name);
467
468 return false;
469}
GLsizeiptr size
Definition: glext.h:5919
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1031
if(dx< 0)
Definition: linetemp.h:194
static ATOM item
Definition: dde.c:856
unsigned short USHORT
Definition: pedump.c:61
uint16_t m
Definition: btrfs.h:275
char name[1]
Definition: btrfs.h:278
uint16_t n
Definition: btrfs.h:276

◆ add_device_to_list()

static void add_device_to_list ( _In_ device_extension Vcb,
_In_ device dev 
)
static

Definition at line 3279 of file btrfs.c.

3279 {
3280 LIST_ENTRY* le;
3281
3282 le = Vcb->devices.Flink;
3283
3284 while (le != &Vcb->devices) {
3286
3287 if (dev2->devitem.dev_id > dev->devitem.dev_id) {
3288 InsertHeadList(le->Blink, &dev->list_entry);
3289 return;
3290 }
3291
3292 le = le->Flink;
3293 }
3294
3295 InsertTailList(&Vcb->devices, &dev->list_entry);
3296}
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
uint64_t dev_id
Definition: btrfs.h:178
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
uint64_t dev_id
Definition: devices.h:37
DEV_ITEM devitem
Definition: btrfs_drv.h:527

Referenced by find_device_from_uuid(), and load_chunk_root().

◆ calculate_sector_shift()

static void calculate_sector_shift ( device_extension Vcb)
static

Definition at line 4364 of file btrfs.c.

4364 {
4365 uint32_t ss = Vcb->superblock.sector_size;
4366
4367 Vcb->sector_shift = 0;
4368
4369 while (!(ss & 1)) {
4370 Vcb->sector_shift++;
4371 ss >>= 1;
4372 }
4373}
UINT32 uint32_t
Definition: types.h:75
#define ss
Definition: i386-dis.c:441

Referenced by mount_vol().

◆ calculate_total_space()

static void calculate_total_space ( _In_ device_extension Vcb,
_Out_ uint64_t totalsize,
_Out_ uint64_t freespace 
)
static

Definition at line 619 of file btrfs.c.

619 {
620 uint64_t nfactor, dfactor, sectors_used;
621
622 if (Vcb->data_flags & BLOCK_FLAG_DUPLICATE || Vcb->data_flags & BLOCK_FLAG_RAID1 || Vcb->data_flags & BLOCK_FLAG_RAID10) {
623 nfactor = 1;
624 dfactor = 2;
625 } else if (Vcb->data_flags & BLOCK_FLAG_RAID5) {
626 nfactor = Vcb->superblock.num_devices - 1;
627 dfactor = Vcb->superblock.num_devices;
628 } else if (Vcb->data_flags & BLOCK_FLAG_RAID6) {
629 nfactor = Vcb->superblock.num_devices - 2;
630 dfactor = Vcb->superblock.num_devices;
631 } else if (Vcb->data_flags & BLOCK_FLAG_RAID1C3) {
632 nfactor = 1;
633 dfactor = 3;
634 } else if (Vcb->data_flags & BLOCK_FLAG_RAID1C4) {
635 nfactor = 1;
636 dfactor = 4;
637 } else {
638 nfactor = 1;
639 dfactor = 1;
640 }
641
642 sectors_used = (Vcb->superblock.bytes_used >> Vcb->sector_shift) * nfactor / dfactor;
643
644 *totalsize = (Vcb->superblock.total_bytes >> Vcb->sector_shift) * nfactor / dfactor;
645 *freespace = sectors_used > *totalsize ? 0 : (*totalsize - sectors_used);
646}
#define BLOCK_FLAG_RAID1C4
Definition: btrfs.h:88
#define BLOCK_FLAG_RAID1C3
Definition: btrfs.h:87
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint GLenum GLenum dfactor
Definition: glfuncs.h:252
#define BLOCK_FLAG_RAID5
Definition: shellext.h:82
#define BLOCK_FLAG_DUPLICATE
Definition: shellext.h:80
#define BLOCK_FLAG_RAID10
Definition: shellext.h:81
#define BLOCK_FLAG_RAID6
Definition: shellext.h:83
#define BLOCK_FLAG_RAID1
Definition: shellext.h:79

Referenced by _Dispatch_type_().

◆ check_file_name_valid()

NTSTATUS check_file_name_valid ( _In_ PUNICODE_STRING  us,
_In_ bool  posix,
_In_ bool  stream 
)

Definition at line 5797 of file btrfs.c.

5797 {
5798 ULONG i;
5799
5800 if (us->Length < sizeof(WCHAR))
5802
5803 if (us->Length > 255 * sizeof(WCHAR))
5805
5806 for (i = 0; i < us->Length / sizeof(WCHAR); i++) {
5807 if (us->Buffer[i] == '/' || us->Buffer[i] == 0 ||
5808 (!posix && (us->Buffer[i] == '/' || us->Buffer[i] == ':')) ||
5809 (!posix && !stream && (us->Buffer[i] == '<' || us->Buffer[i] == '>' || us->Buffer[i] == '"' ||
5810 us->Buffer[i] == '|' || us->Buffer[i] == '?' || us->Buffer[i] == '*' || (us->Buffer[i] >= 1 && us->Buffer[i] <= 31))))
5812
5813 /* Don't allow unpaired surrogates ("WTF-16") */
5814
5815 if ((us->Buffer[i] & 0xfc00) == 0xdc00 && (i == 0 || ((us->Buffer[i-1] & 0xfc00) != 0xd800)))
5817
5818 if ((us->Buffer[i] & 0xfc00) == 0xd800 && (i == (us->Length / sizeof(WCHAR)) - 1 || ((us->Buffer[i+1] & 0xfc00) != 0xdc00)))
5820 }
5821
5822 if (us->Buffer[0] == '.' && (us->Length == sizeof(WCHAR) || (us->Length == 2 * sizeof(WCHAR) && us->Buffer[1] == '.')))
5824
5825 /* The Linux driver expects filenames with a maximum length of 255 bytes - make sure
5826 * that our UTF-8 length won't be longer than that. */
5827 if (us->Length >= 85 * sizeof(WCHAR)) {
5829 ULONG utf8len;
5830
5831 Status = utf16_to_utf8(NULL, 0, &utf8len, us->Buffer, us->Length);
5832 if (!NT_SUCCESS(Status))
5833 return Status;
5834
5835 if (utf8len > 255)
5837 else if (stream && utf8len > 250) // minus five bytes for "user."
5839 }
5840
5841 return STATUS_SUCCESS;
5842}
NTSTATUS utf16_to_utf8(char *dest, ULONG dest_max, ULONG *dest_len, WCHAR *src, ULONG src_len)
Definition: btrfs.c:894
static const BYTE us[]
Definition: encode.c:689
Definition: parse.h:23
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148

Referenced by create_snapshot(), create_stream(), create_subvol(), file_create(), find_file_in_dir(), rename_file_to_stream(), rename_stream(), set_link_information(), and set_rename_information().

◆ check_superblock_checksum()

bool check_superblock_checksum ( superblock sb)

Definition at line 2825 of file btrfs.c.

2825 {
2826 switch (sb->csum_type) {
2827 case CSUM_TYPE_CRC32C: {
2828 uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
2829
2830 if (crc32 == *((uint32_t*)sb->checksum))
2831 return true;
2832
2833 WARN("crc32 was %08x, expected %08x\n", crc32, *((uint32_t*)sb->checksum));
2834
2835 break;
2836 }
2837
2838 case CSUM_TYPE_XXHASH: {
2839 uint64_t hash = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0);
2840
2841 if (hash == *((uint64_t*)sb->checksum))
2842 return true;
2843
2844 WARN("superblock hash was %I64x, expected %I64x\n", hash, *((uint64_t*)sb->checksum));
2845
2846 break;
2847 }
2848
2849 case CSUM_TYPE_SHA256: {
2851
2852 calc_sha256(hash, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
2853
2855 return true;
2856
2857 WARN("superblock hash was invalid\n");
2858
2859 break;
2860 }
2861
2862 case CSUM_TYPE_BLAKE2: {
2864
2865 blake2b(hash, sizeof(hash), &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
2866
2868 return true;
2869
2870 WARN("superblock hash was invalid\n");
2871
2872 break;
2873 }
2874
2875 default:
2876 WARN("unrecognized csum type %x\n", sb->csum_type);
2877 }
2878
2879 return false;
2880}
void blake2b(void *out, size_t outlen, const void *in, size_t inlen)
Definition: blake2b-ref.c:237
#define BLAKE2_HASH_SIZE
Definition: btrfs_drv.h:1252
void calc_sha256(uint8_t *hash, const void *input, size_t len)
Definition: sha256.c:126
#define SHA256_HASH_SIZE
Definition: btrfs_drv.h:1248
#define crc32(crc, buf, len)
Definition: inflate.c:1081
superblock * sb
Definition: btrfs.c:4261
#define CSUM_TYPE_SHA256
Definition: btrfs.h:134
#define CSUM_TYPE_XXHASH
Definition: btrfs.h:133
#define CSUM_TYPE_BLAKE2
Definition: btrfs.h:135
#define CSUM_TYPE_CRC32C
Definition: btrfs.h:132
BYTE uint8_t
Definition: msvideo1.c:66
Definition: _hash_fun.h:40
uint16_t csum_type
Definition: btrfs.h:247
BTRFS_UUID uuid
Definition: btrfs.h:225
uint8_t checksum[32]
Definition: btrfs.h:224
XXH_PUBLIC_API unsigned long long XXH64(const void *input, size_t len, unsigned long long seed)
Definition: xxhash.c:555

Referenced by device_still_valid(), is_device_part_of_mounted_btrfs_raid(), read_superblock(), still_has_superblock(), test_vol(), and verify_device().

◆ chunk_lock_range()

void chunk_lock_range ( _In_ device_extension Vcb,
_In_ chunk c,
_In_ uint64_t  start,
_In_ uint64_t  length 
)

Definition at line 5844 of file btrfs.c.

5844 {
5845 LIST_ENTRY* le;
5846 bool locked;
5847 range_lock* rl;
5848
5849 rl = ExAllocateFromNPagedLookasideList(&Vcb->range_lock_lookaside);
5850 if (!rl) {
5851 ERR("out of memory\n");
5852 return;
5853 }
5854
5855 rl->start = start;
5856 rl->length = length;
5857 rl->thread = PsGetCurrentThread();
5858
5859 while (true) {
5860 locked = false;
5861
5862 ExAcquireResourceExclusiveLite(&c->range_locks_lock, true);
5863
5864 le = c->range_locks.Flink;
5865 while (le != &c->range_locks) {
5867
5868 if (rl2->start < start + length && rl2->start + rl2->length > start && rl2->thread != PsGetCurrentThread()) {
5869 locked = true;
5870 break;
5871 }
5872
5873 le = le->Flink;
5874 }
5875
5876 if (!locked) {
5877 InsertTailList(&c->range_locks, &rl->list_entry);
5878
5879 ExReleaseResourceLite(&c->range_locks_lock);
5880 return;
5881 }
5882
5883 KeClearEvent(&c->range_locks_event);
5884
5885 ExReleaseResourceLite(&c->range_locks_lock);
5886
5887 KeWaitForSingleObject(&c->range_locks_event, UserRequest, KernelMode, false, NULL);
5888 }
5889}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
GLuint start
Definition: gl.h:1545
const GLubyte * c
Definition: glext.h:8905
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
uint64_t start
Definition: btrfs_drv.h:546
uint64_t length
Definition: btrfs_drv.h:547
PETHREAD thread
Definition: btrfs_drv.h:548
LIST_ENTRY list_entry
Definition: btrfs_drv.h:549
@ UserRequest
Definition: ketypes.h:421

Referenced by read_data(), and scrub_chunk_raid56_stripe_run().

◆ chunk_unlock_range()

void chunk_unlock_range ( _In_ device_extension Vcb,
_In_ chunk c,
_In_ uint64_t  start,
_In_ uint64_t  length 
)

Definition at line 5891 of file btrfs.c.

5891 {
5892 LIST_ENTRY* le;
5893
5894 ExAcquireResourceExclusiveLite(&c->range_locks_lock, true);
5895
5896 le = c->range_locks.Flink;
5897 while (le != &c->range_locks) {
5899
5900 if (rl->start == start && rl->length == length) {
5902 ExFreeToNPagedLookasideList(&Vcb->range_lock_lookaside, rl);
5903 break;
5904 }
5905
5906 le = le->Flink;
5907 }
5908
5909 KeSetEvent(&c->range_locks_event, 0, false);
5910
5911 ExReleaseResourceLite(&c->range_locks_lock);
5912}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by read_data(), and scrub_chunk_raid56_stripe_run().

◆ close_file()

static NTSTATUS close_file ( _In_ PFILE_OBJECT  FileObject,
_In_ PIRP  Irp 
)
static

Definition at line 1925 of file btrfs.c.

1925 {
1926 fcb* fcb;
1927 ccb* ccb;
1928 file_ref* fileref = NULL;
1929 LONG open_files;
1930
1931 UNUSED(Irp);
1932
1933 TRACE("FileObject = %p\n", FileObject);
1934
1935 fcb = FileObject->FsContext;
1936 if (!fcb) {
1937 TRACE("FCB was NULL, returning success\n");
1938 return STATUS_SUCCESS;
1939 }
1940
1941 open_files = InterlockedDecrement(&fcb->Vcb->open_files);
1942
1943 ccb = FileObject->FsContext2;
1944
1945 TRACE("close called for fcb %p)\n", fcb);
1946
1947 // FIXME - make sure notification gets sent if file is being deleted
1948
1949 if (ccb) {
1950 if (ccb->query_string.Buffer)
1952
1953 if (ccb->filename.Buffer)
1955
1956 // FIXME - use refcounts for fileref
1957 fileref = ccb->fileref;
1958
1959 if (fcb->Vcb->running_sends > 0) {
1960 bool send_cancelled = false;
1961
1962 ExAcquireResourceExclusiveLite(&fcb->Vcb->send_load_lock, true);
1963
1964 if (ccb->send) {
1965 ccb->send->cancelling = true;
1966 send_cancelled = true;
1967 KeSetEvent(&ccb->send->cleared_event, 0, false);
1968 }
1969
1970 ExReleaseResourceLite(&fcb->Vcb->send_load_lock);
1971
1972 if (send_cancelled) {
1973 while (ccb->send) {
1974 ExAcquireResourceExclusiveLite(&fcb->Vcb->send_load_lock, true);
1975 ExReleaseResourceLite(&fcb->Vcb->send_load_lock);
1976 }
1977 }
1978 }
1979
1980 ExFreePool(ccb);
1981 }
1982
1984
1985 if (open_files == 0 && fcb->Vcb->removing) {
1986 uninit(fcb->Vcb);
1987 return STATUS_SUCCESS;
1988 }
1989
1990 if (!(fcb->Vcb->Vpb->Flags & VPB_MOUNTED))
1991 return STATUS_SUCCESS;
1992
1993 if (fileref)
1994 free_fileref(fileref);
1995 else
1996 free_fcb(fcb);
1997
1998 return STATUS_SUCCESS;
1999}
struct _fcb fcb
Definition: btrfs_drv.h:1364
void free_fcb(_Inout_ fcb *fcb)
Definition: btrfs.c:1734
void uninit(_In_ device_extension *Vcb)
Definition: btrfs.c:2001
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
send_info * send
Definition: btrfs_drv.h:392
UNICODE_STRING query_string
Definition: btrfs_drv.h:376
UNICODE_STRING filename
Definition: btrfs_drv.h:384
KEVENT cleared_event
Definition: btrfs_drv.h:365
bool cancelling
Definition: btrfs_drv.h:366

◆ compare_strings()

static bool compare_strings ( const UNICODE_STRING us1,
const UNICODE_STRING us2 
)
static

Definition at line 650 of file btrfs.c.

650 {
651 if (us1->Length != us2->Length)
652 return false;
653
654 WCHAR* s1 = us1->Buffer;
655 WCHAR* s2 = us2->Buffer;
656
657 for (unsigned int i = 0; i < us1->Length; i++) {
658 WCHAR c1 = *s1;
659 WCHAR c2 = *s2;
660
661 if (c1 != c2) {
662 if (c1 >= 'a' && c1 <= 'z')
663 c1 = c1 - 'a' + 'A';
664
665 if (c2 >= 'a' && c2 <= 'z')
666 c2 = c2 - 'a' + 'A';
667
668 if (c1 != c2)
669 return false;
670 }
671
672 s1++;
673 s2++;
674 }
675
676 return true;
677}
struct S1 s1
struct S2 s2

Referenced by lie_about_fs_type().

◆ create_calc_threads()

static NTSTATUS create_calc_threads ( _In_ PDEVICE_OBJECT  DeviceObject)
static

Definition at line 4094 of file btrfs.c.

4094 {
4095 device_extension* Vcb = DeviceObject->DeviceExtension;
4097 ULONG i;
4098
4099 Vcb->calcthreads.num_threads = get_num_of_processors();
4100
4101 Vcb->calcthreads.threads = ExAllocatePoolWithTag(NonPagedPool, sizeof(drv_calc_thread) * Vcb->calcthreads.num_threads, ALLOC_TAG);
4102 if (!Vcb->calcthreads.threads) {
4103 ERR("out of memory\n");
4105 }
4106
4107 InitializeListHead(&Vcb->calcthreads.job_list);
4108 KeInitializeSpinLock(&Vcb->calcthreads.spinlock);
4109 KeInitializeEvent(&Vcb->calcthreads.event, NotificationEvent, false);
4110
4111 RtlZeroMemory(Vcb->calcthreads.threads, sizeof(drv_calc_thread) * Vcb->calcthreads.num_threads);
4112
4114
4115 for (i = 0; i < Vcb->calcthreads.num_threads; i++) {
4117
4118 Vcb->calcthreads.threads[i].DeviceObject = DeviceObject;
4119 Vcb->calcthreads.threads[i].number = i;
4120 KeInitializeEvent(&Vcb->calcthreads.threads[i].finished, NotificationEvent, false);
4121
4122 Status = PsCreateSystemThread(&Vcb->calcthreads.threads[i].handle, 0, &oa, NULL, NULL, calc_thread, &Vcb->calcthreads.threads[i]);
4123 if (!NT_SUCCESS(Status)) {
4124 ULONG j;
4125
4126 ERR("PsCreateSystemThread returned %08lx\n", Status);
4127
4128 for (j = 0; j < i; j++) {
4129 Vcb->calcthreads.threads[i].quit = true;
4130 }
4131
4132 KeSetEvent(&Vcb->calcthreads.event, 0, false);
4133
4134 return Status;
4135 }
4136 }
4137
4138 return STATUS_SUCCESS;
4139}
uint32_t get_num_of_processors()
Definition: btrfs.c:4080
#define NonPagedPool
Definition: env_spec_w32.h:307
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250

Referenced by mount_vol().

◆ create_root()

NTSTATUS create_root ( _In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension Vcb,
_In_ uint64_t  id,
_Out_ root **  rootptr,
_In_ bool  no_tree,
_In_ uint64_t  offset,
_In_opt_ PIRP  Irp 
)

Definition at line 1271 of file btrfs.c.

1272 {
1274 root* r;
1275 ROOT_ITEM* ri;
1277
1279 if (!r) {
1280 ERR("out of memory\n");
1282 }
1283
1285 if (!r->nonpaged) {
1286 ERR("out of memory\n");
1287 ExFreePool(r);
1289 }
1290
1292 if (!ri) {
1293 ERR("out of memory\n");
1294
1295 ExFreePool(r->nonpaged);
1296 ExFreePool(r);
1298 }
1299
1300 r->id = id;
1301 r->treeholder.address = 0;
1302 r->treeholder.generation = Vcb->superblock.generation;
1303 r->treeholder.tree = NULL;
1304 r->lastinode = 0;
1305 r->dirty = false;
1306 r->received = false;
1307 r->reserved = NULL;
1308 r->parent = 0;
1309 r->send_ops = 0;
1310 RtlZeroMemory(&r->root_item, sizeof(ROOT_ITEM));
1311 r->root_item.num_references = 1;
1312 r->fcbs_version = 0;
1313 r->checked_for_orphans = true;
1314 r->dropped = false;
1315 InitializeListHead(&r->fcbs);
1316 RtlZeroMemory(r->fcbs_ptrs, sizeof(LIST_ENTRY*) * 256);
1317
1318 RtlCopyMemory(ri, &r->root_item, sizeof(ROOT_ITEM));
1319
1320 // We ask here for a traverse_ptr to the item we're inserting, so we can
1321 // copy some of the tree's variables
1322
1323 Status = insert_tree_item(Vcb, Vcb->root_root, id, TYPE_ROOT_ITEM, offset, ri, sizeof(ROOT_ITEM), &tp, Irp);
1324 if (!NT_SUCCESS(Status)) {
1325 ERR("insert_tree_item returned %08lx\n", Status);
1326 ExFreePool(ri);
1327 ExFreePool(r->nonpaged);
1328 ExFreePool(r);
1329 return Status;
1330 }
1331
1332 ExInitializeResourceLite(&r->nonpaged->load_tree_lock);
1333
1334 InsertTailList(&Vcb->roots, &r->list_entry);
1335
1336 if (!no_tree) {
1338 if (!t) {
1339 ERR("out of memory\n");
1340
1342
1343 ExFreePool(r->nonpaged);
1344 ExFreePool(r);
1345 ExFreePool(ri);
1347 }
1348
1349 t->nonpaged = NULL;
1350
1351 t->is_unique = true;
1352 t->uniqueness_determined = true;
1353 t->buf = NULL;
1354
1355 r->treeholder.tree = t;
1356
1357 RtlZeroMemory(&t->header, sizeof(tree_header));
1358 t->header.fs_uuid = tp.tree->header.fs_uuid;
1359 t->header.address = 0;
1360 t->header.flags = HEADER_FLAG_MIXED_BACKREF | 1; // 1 == "written"? Why does the Linux driver record this?
1361 t->header.chunk_tree_uuid = tp.tree->header.chunk_tree_uuid;
1362 t->header.generation = Vcb->superblock.generation;
1363 t->header.tree_id = id;
1364 t->header.num_items = 0;
1365 t->header.level = 0;
1366
1367 t->has_address = false;
1368 t->size = 0;
1369 t->Vcb = Vcb;
1370 t->parent = NULL;
1371 t->paritem = NULL;
1372 t->root = r;
1373
1374 InitializeListHead(&t->itemlist);
1375
1376 t->new_address = 0;
1377 t->has_new_address = false;
1378 t->updated_extents = false;
1379
1380 InsertTailList(&Vcb->trees, &t->list_entry);
1381 t->list_entry_hash.Flink = NULL;
1382
1383 t->write = true;
1384 Vcb->need_write = true;
1385 }
1386
1387 *rootptr = r;
1388
1389 return STATUS_SUCCESS;
1390}
NTSTATUS insert_tree_item(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _In_ uint64_t obj_id, _In_ uint8_t obj_type, _In_ uint64_t offset, _In_reads_bytes_opt_(size) _When_(return >=0, __drv_aliasesMem) void *data, _In_ uint16_t size, _Out_opt_ traverse_ptr *ptp, _In_opt_ PIRP Irp) __attribute__((nonnull(1
NTSTATUS NTSTATUS delete_tree_item(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _Inout_ traverse_ptr *tp) __attribute__((nonnull(1
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
InitializeListHead & r
Definition: btrfs.c:3015
_In_ uint64_t id
Definition: btrfs.c:2995
#define HEADER_FLAG_MIXED_BACKREF
Definition: btrfs.h:151
#define TYPE_ROOT_ITEM
Definition: btrfs.h:32
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble t
Definition: gl.h:2047
GLintptr offset
Definition: glext.h:5920
tree_header header
Definition: btrfs_drv.h:426
tree * tree
Definition: btrfs_drv.h:508
BTRFS_UUID chunk_tree_uuid
Definition: btrfs.h:158
BTRFS_UUID fs_uuid
Definition: btrfs.h:155

Referenced by create_subvol(), do_create_snapshot(), flush_subvol(), and look_for_roots().

◆ DEFINE_GUID()

DEFINE_GUID ( BtrfsBusInterface  ,
0x4d414874  ,
0x6865  ,
0x6761  ,
0x6d  ,
0x65  ,
0x83  ,
0x69  ,
0x17  ,
0x9a  ,
0x7d  ,
0x1d   
)

◆ delete_fileref()

NTSTATUS delete_fileref ( _In_ file_ref fileref,
_In_opt_ PFILE_OBJECT  FileObject,
_In_ bool  make_orphan,
_In_opt_ PIRP  Irp,
_In_ LIST_ENTRY rollback 
)

Definition at line 2270 of file btrfs.c.

2270 {
2271 LARGE_INTEGER newlength, time;
2274 ULONG utf8len = 0;
2275
2278
2279 ExAcquireResourceExclusiveLite(fileref->fcb->Header.Resource, true);
2280
2281 if (fileref->deleted) {
2282 ExReleaseResourceLite(fileref->fcb->Header.Resource);
2283 return STATUS_SUCCESS;
2284 }
2285
2286 if (fileref->fcb->subvol->send_ops > 0) {
2287 ExReleaseResourceLite(fileref->fcb->Header.Resource);
2288 return STATUS_ACCESS_DENIED;
2289 }
2290
2291 fileref->deleted = true;
2292 mark_fileref_dirty(fileref);
2293
2294 // delete INODE_ITEM (0x1)
2295
2296 TRACE("nlink = %u\n", fileref->fcb->inode_item.st_nlink);
2297
2298 if (!fileref->fcb->ads) {
2299 if (fileref->parent->fcb->subvol == fileref->fcb->subvol) {
2300 LIST_ENTRY* le;
2301
2302 mark_fcb_dirty(fileref->fcb);
2303
2304 fileref->fcb->inode_item_changed = true;
2305
2306 if (fileref->fcb->inode_item.st_nlink > 1 || make_orphan) {
2307 fileref->fcb->inode_item.st_nlink--;
2308 fileref->fcb->inode_item.transid = fileref->fcb->Vcb->superblock.generation;
2309 fileref->fcb->inode_item.sequence++;
2310 fileref->fcb->inode_item.st_ctime = now;
2311 } else {
2313 if (!NT_SUCCESS(Status)) {
2314 ERR("delete_fileref_fcb returned %08lx\n", Status);
2315 ExReleaseResourceLite(fileref->fcb->Header.Resource);
2316 return Status;
2317 }
2318 }
2319
2320 if (fileref->dc) {
2321 le = fileref->fcb->hardlinks.Flink;
2322 while (le != &fileref->fcb->hardlinks) {
2324
2325 if (hl->parent == fileref->parent->fcb->inode && hl->index == fileref->dc->index) {
2327
2328 if (hl->name.Buffer)
2329 ExFreePool(hl->name.Buffer);
2330
2331 if (hl->utf8.Buffer)
2332 ExFreePool(hl->utf8.Buffer);
2333
2334 ExFreePool(hl);
2335 break;
2336 }
2337
2338 le = le->Flink;
2339 }
2340 }
2341 } else if (fileref->fcb->subvol->parent == fileref->parent->fcb->subvol->id) { // valid subvolume
2342 if (fileref->fcb->subvol->root_item.num_references > 1) {
2343 fileref->fcb->subvol->root_item.num_references--;
2344
2345 mark_fcb_dirty(fileref->fcb); // so ROOT_ITEM gets updated
2346 } else {
2347 LIST_ENTRY* le;
2348
2349 // FIXME - we need a lock here
2350
2351 RemoveEntryList(&fileref->fcb->subvol->list_entry);
2352
2353 InsertTailList(&fileref->fcb->Vcb->drop_roots, &fileref->fcb->subvol->list_entry);
2354
2355 le = fileref->children.Flink;
2356 while (le != &fileref->children) {
2358
2359 if (fr2->fcb->ads) {
2360 fr2->fcb->deleted = true;
2361 mark_fcb_dirty(fr2->fcb);
2362 }
2363
2364 le = le->Flink;
2365 }
2366 }
2367 }
2368 } else {
2369 fileref->fcb->deleted = true;
2370 mark_fcb_dirty(fileref->fcb);
2371 }
2372
2373 // remove dir_child from parent
2374
2375 if (fileref->dc) {
2376 TRACE("delete file %.*S\n", (int)(fileref->dc->name.Length / sizeof(WCHAR)), fileref->dc->name.Buffer);
2377
2378 ExAcquireResourceExclusiveLite(&fileref->parent->fcb->nonpaged->dir_children_lock, true);
2379 RemoveEntryList(&fileref->dc->list_entry_index);
2380
2381 if (!fileref->fcb->ads)
2382 remove_dir_child_from_hash_lists(fileref->parent->fcb, fileref->dc);
2383
2384 ExReleaseResourceLite(&fileref->parent->fcb->nonpaged->dir_children_lock);
2385
2386 if (!fileref->oldutf8.Buffer)
2387 fileref->oldutf8 = fileref->dc->utf8;
2388 else
2389 ExFreePool(fileref->dc->utf8.Buffer);
2390
2391 utf8len = fileref->dc->utf8.Length;
2392
2393 fileref->oldindex = fileref->dc->index;
2394
2395 ExFreePool(fileref->dc->name.Buffer);
2396 ExFreePool(fileref->dc->name_uc.Buffer);
2397 ExFreePool(fileref->dc);
2398
2399 fileref->dc = NULL;
2400 }
2401
2402 // update INODE_ITEM of parent
2403
2404 ExAcquireResourceExclusiveLite(fileref->parent->fcb->Header.Resource, true);
2405
2406 fileref->parent->fcb->inode_item.transid = fileref->fcb->Vcb->superblock.generation;
2407 fileref->parent->fcb->inode_item.sequence++;
2408 fileref->parent->fcb->inode_item.st_ctime = now;
2409
2410 if (!fileref->fcb->ads) {
2411 TRACE("fileref->parent->fcb->inode_item.st_size (inode %I64x) was %I64x\n", fileref->parent->fcb->inode, fileref->parent->fcb->inode_item.st_size);
2412 fileref->parent->fcb->inode_item.st_size -= utf8len * 2;
2413 TRACE("fileref->parent->fcb->inode_item.st_size (inode %I64x) now %I64x\n", fileref->parent->fcb->inode, fileref->parent->fcb->inode_item.st_size);
2414 fileref->parent->fcb->inode_item.st_mtime = now;
2415 }
2416
2417 fileref->parent->fcb->inode_item_changed = true;
2418 ExReleaseResourceLite(fileref->parent->fcb->Header.Resource);
2419
2420 if (!fileref->fcb->ads && fileref->parent->dc)
2422
2423 mark_fcb_dirty(fileref->parent->fcb);
2424
2425 fileref->fcb->subvol->root_item.ctransid = fileref->fcb->Vcb->superblock.generation;
2426 fileref->fcb->subvol->root_item.ctime = now;
2427
2428 newlength.QuadPart = 0;
2429
2430 if (FileObject && !CcUninitializeCacheMap(FileObject, &newlength, NULL))
2431 TRACE("CcUninitializeCacheMap failed\n");
2432
2433 ExReleaseResourceLite(fileref->fcb->Header.Resource);
2434
2435 return STATUS_SUCCESS;
2436}
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfs_drv.h:989
void remove_dir_child_from_hash_lists(fcb *fcb, dir_child *dc)
Definition: fileinfo.c:744
void mark_fileref_dirty(_In_ file_ref *fileref)
Definition: btrfs.c:1717
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
time_t now
Definition: finger.c:65
__u16 time
Definition: mkdosfs.c:8
bool deleted
Definition: btrfs_drv.h:295
#define FILE_ACTION_MODIFIED
#define FILE_NOTIFY_CHANGE_LAST_WRITE

Referenced by _Dispatch_type_(), move_across_subvols(), open_file3(), rename_file_to_stream(), rename_stream(), set_link_information(), and set_rename_information().

◆ delete_fileref_fcb()

static NTSTATUS delete_fileref_fcb ( _In_ file_ref fileref,
_In_opt_ PFILE_OBJECT  FileObject,
_In_opt_ PIRP  Irp,
_In_ LIST_ENTRY rollback 
)
static

Definition at line 2214 of file btrfs.c.

2214 {
2216 LIST_ENTRY* le;
2217
2218 // excise extents
2219
2220 if (fileref->fcb->type != BTRFS_TYPE_DIRECTORY && fileref->fcb->inode_item.st_size > 0) {
2221 Status = excise_extents(fileref->fcb->Vcb, fileref->fcb, 0, sector_align(fileref->fcb->inode_item.st_size, fileref->fcb->Vcb->superblock.sector_size), Irp, rollback);
2222 if (!NT_SUCCESS(Status)) {
2223 ERR("excise_extents returned %08lx\n", Status);
2224 return Status;
2225 }
2226 }
2227
2228 fileref->fcb->Header.AllocationSize.QuadPart = 0;
2229 fileref->fcb->Header.FileSize.QuadPart = 0;
2230 fileref->fcb->Header.ValidDataLength.QuadPart = 0;
2231
2232 if (FileObject) {
2233 CC_FILE_SIZES ccfs;
2234
2235 ccfs.AllocationSize = fileref->fcb->Header.AllocationSize;
2236 ccfs.FileSize = fileref->fcb->Header.FileSize;
2237 ccfs.ValidDataLength = fileref->fcb->Header.ValidDataLength;
2238
2240
2241 _SEH2_TRY {
2242 CcSetFileSizes(FileObject, &ccfs);
2245 } _SEH2_END;
2246
2247 if (!NT_SUCCESS(Status)) {
2248 ERR("CcSetFileSizes threw exception %08lx\n", Status);
2249 return Status;
2250 }
2251 }
2252
2253 fileref->fcb->deleted = true;
2254
2255 le = fileref->children.Flink;
2256 while (le != &fileref->children) {
2258
2259 if (fr2->fcb->ads) {
2260 fr2->fcb->deleted = true;
2261 mark_fcb_dirty(fr2->fcb);
2262 }
2263
2264 le = le->Flink;
2265 }
2266
2267 return STATUS_SUCCESS;
2268}
NTSTATUS NTSTATUS NTSTATUS NTSTATUS NTSTATUS excise_extents(device_extension *Vcb, fcb *fcb, uint64_t start_data, uint64_t end_data, PIRP Irp, LIST_ENTRY *rollback) __attribute__((nonnull(1
static uint64_t __inline sector_align(uint64_t n, uint64_t a)
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
LARGE_INTEGER FileSize
Definition: cctypes.h:16
LARGE_INTEGER ValidDataLength
Definition: cctypes.h:17
LARGE_INTEGER AllocationSize
Definition: cctypes.h:15

Referenced by _Dispatch_type_(), and delete_fileref().

◆ dev_ioctl()

NTSTATUS dev_ioctl ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ ULONG  ControlCode,
_In_reads_bytes_opt_(InputBufferSize) PVOID  InputBuffer,
_In_ ULONG  InputBufferSize,
_Out_writes_bytes_opt_(OutputBufferSize) PVOID  OutputBuffer,
_In_ ULONG  OutputBufferSize,
_In_ bool  Override,
_Out_opt_ IO_STATUS_BLOCK iosb 
)

Definition at line 2954 of file btrfs.c.

2955 {
2956 PIRP Irp;
2957 KEVENT Event;
2961
2963
2967 InputBufferSize,
2969 OutputBufferSize,
2970 false,
2971 &Event,
2972 &IoStatus);
2973
2975
2976 if (Override) {
2979 }
2980
2982
2983 if (Status == STATUS_PENDING) {
2985 Status = IoStatus.Status;
2986 }
2987
2988 if (iosb)
2989 *iosb = IoStatus;
2990
2991 return Status;
2992}
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define STATUS_PENDING
Definition: ntstatus.h:82
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823

Referenced by _Function_class_(), add_device(), disk_arrival(), finish_removing_device(), get_device_change_count(), get_devices(), init_device(), is_btrfs_volume(), is_device_removable(), is_volume_mounted(), mount_vol(), mountmgr_add_drive_letter(), mountmgr_notification(), mountmgr_process_drive(), probe_volume(), query_filesystems(), remove_drive_letter(), remove_volume_child(), resize_device(), test_vol(), trim_unalloc_space(), trim_whole_device(), verify_device(), verify_vcb(), vol_check_verify(), vol_get_disk_extents(), vol_is_writable(), and volume_arrival().

◆ device_still_valid()

static bool device_still_valid ( device dev,
uint64_t  expected_generation 
)
static

Definition at line 5546 of file btrfs.c.

5546 {
5548 unsigned int to_read;
5549 superblock* sb;
5550
5551 to_read = (unsigned int)(dev->devobj->SectorSize == 0 ? sizeof(superblock) : sector_align(sizeof(superblock), dev->devobj->SectorSize));
5552
5554 if (!sb) {
5555 ERR("out of memory\n");
5556 return false;
5557 }
5558
5559 Status = sync_read_phys(dev->devobj, dev->fileobj, superblock_addrs[0], to_read, (PUCHAR)sb, false);
5560 if (!NT_SUCCESS(Status)) {
5561 ERR("sync_read_phys returned %08lx\n", Status);
5562 ExFreePool(sb);
5563 return false;
5564 }
5565
5566 if (sb->magic != BTRFS_MAGIC) {
5567 ERR("magic not found\n");
5568 ExFreePool(sb);
5569 return false;
5570 }
5571
5573 ExFreePool(sb);
5574 return false;
5575 }
5576
5577 if (sb->generation > expected_generation) {
5578 ERR("generation was %I64x, expected %I64x\n", sb->generation, expected_generation);
5579 ExFreePool(sb);
5580 return false;
5581 }
5582
5583 ExFreePool(sb);
5584
5585 return true;
5586}
#define BTRFS_MAGIC
Definition: btrfs.h:42
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
bool check_superblock_checksum(superblock *sb)
Definition: btrfs.c:2825
NTSTATUS sync_read_phys(_In_ PDEVICE_OBJECT DeviceObject, _In_ PFILE_OBJECT FileObject, _In_ uint64_t StartingOffset, _In_ ULONG Length, _Out_writes_bytes_(Length) PUCHAR Buffer, _In_ bool override)
Definition: btrfs.c:2732
ULONG to_read
Definition: btrfs.c:4260
static const uint64_t superblock_addrs[]
Definition: btrfs.h:16
uint64_t magic
Definition: btrfs.h:228
uint64_t generation
Definition: btrfs.h:229
unsigned char * PUCHAR
Definition: typedefs.h:53

◆ do_shutdown()

void do_shutdown ( PIRP  Irp)

Definition at line 5392 of file btrfs.c.

5392 {
5393 LIST_ENTRY* le;
5395
5396 shutting_down = true;
5398
5399 le = VcbList.Flink;
5400 while (le != &VcbList) {
5401 LIST_ENTRY* le2 = le->Flink;
5402
5404 volume_device_extension* vde = Vcb->vde;
5405 PDEVICE_OBJECT devobj = vde ? vde->device : NULL;
5406
5407 TRACE("shutting down Vcb %p\n", Vcb);
5408
5409 if (vde)
5411
5412 if (devobj)
5413 ObReferenceObject(devobj);
5414
5415 dismount_volume(Vcb, true, Irp);
5416
5417 if (vde) {
5419 UNICODE_STRING mmdevpath;
5421 PFILE_OBJECT mountmgrfo;
5422 KIRQL irql;
5423 PVPB newvpb;
5424
5426 Status = IoGetDeviceObjectPointer(&mmdevpath, FILE_READ_ATTRIBUTES, &mountmgrfo, &mountmgr);
5427 if (!NT_SUCCESS(Status))
5428 ERR("IoGetDeviceObjectPointer returned %08lx\n", Status);
5429 else {
5431
5432 ObDereferenceObject(mountmgrfo);
5433 }
5434
5435 vde->removing = true;
5436
5437 newvpb = ExAllocatePoolWithTag(NonPagedPool, sizeof(VPB), ALLOC_TAG);
5438 if (!newvpb) {
5439 ERR("out of memory\n");
5440 return;
5441 }
5442
5443 RtlZeroMemory(newvpb, sizeof(VPB));
5444
5445 newvpb->Type = IO_TYPE_VPB;
5446 newvpb->Size = sizeof(VPB);
5447 newvpb->RealDevice = newvpb->DeviceObject = vde->device;
5449
5451 vde->device->Vpb = newvpb;
5453
5454 if (InterlockedDecrement(&vde->open_count) == 0)
5455 free_vol(vde);
5456 }
5457
5458 if (devobj)
5459 ObDereferenceObject(devobj);
5460
5461 le = le2;
5462 }
5463
5464#ifdef _DEBUG
5465 if (comfo) {
5466 ObDereferenceObject(comfo);
5467 comdo = NULL;
5468 comfo = NULL;
5469 }
5470#endif
5471
5473
5474 if (notification_entry2) {
5477 else
5479
5481 }
5482
5483 if (notification_entry3) {
5486 else
5488
5490 }
5491
5492 if (notification_entry) {
5495 else
5497
5499 }
5500
5501 bde = busobj->DeviceExtension;
5502
5503 if (bde->attached_device)
5505
5508}
#define InterlockedIncrement
Definition: armddk.h:53
void void void NTSTATUS void NTSTATUS NTSTATUS remove_drive_letter(PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath)
Definition: search.c:407
void free_vol(volume_device_extension *vde)
Definition: volume.c:50
NTSTATUS dismount_volume(device_extension *Vcb, bool shutdown, PIRP Irp)
Definition: fsctl.c:2584
bool shutting_down
Definition: btrfs.c:109
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:1056
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:479
Definition: iotypes.h:189
CSHORT Type
Definition: iotypes.h:190
CSHORT Size
Definition: iotypes.h:191
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:194
USHORT Flags
Definition: iotypes.h:192
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:195
#define IO_TYPE_VPB
struct _VPB VPB
#define VPB_DIRECT_WRITES_ALLOWED
Definition: iotypes.h:1812
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by _Dispatch_type_(), and ioctl_unload().

◆ do_xor_basic()

static void __stdcall do_xor_basic ( uint8_t buf1,
uint8_t buf2,
uint32_t  len 
)
static

Definition at line 287 of file btrfs.c.

287 {
288 uint32_t j;
289
290#if defined(_ARM_) || defined(_ARM64_)
291 uint64x2_t x1, x2;
292
293 if (((uintptr_t)buf1 & 0xf) == 0 && ((uintptr_t)buf2 & 0xf) == 0) {
294 while (len >= 16) {
295 x1 = vld1q_u64((const uint64_t*)buf1);
296 x2 = vld1q_u64((const uint64_t*)buf2);
297 x1 = veorq_u64(x1, x2);
298 vst1q_u64((uint64_t*)buf1, x1);
299
300 buf1 += 16;
301 buf2 += 16;
302 len -= 16;
303 }
304 }
305#endif
306
307#if defined(_AMD64_) || defined(_ARM64_)
308 while (len > 8) {
309 *(uint64_t*)buf1 ^= *(uint64_t*)buf2;
310 buf1 += 8;
311 buf2 += 8;
312 len -= 8;
313 }
314#endif
315
316 while (len > 4) {
317 *(uint32_t*)buf1 ^= *(uint32_t*)buf2;
318 buf1 += 4;
319 buf2 += 4;
320 len -= 4;
321 }
322
323 for (j = 0; j < len; j++) {
324 *buf1 ^= *buf2;
325 buf1++;
326 buf2++;
327 }
328}
unsigned int uintptr_t
Definition: crtdefs.h:321
GLenum GLsizei len
Definition: glext.h:6722
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708

◆ find_chunk_usage()

NTSTATUS find_chunk_usage ( _In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension Vcb,
_In_opt_ PIRP  Irp 
)

Definition at line 3876 of file btrfs.c.

3876 {
3877 LIST_ENTRY* le = Vcb->chunks.Flink;
3878 chunk* c;
3879 KEY searchkey;
3881 BLOCK_GROUP_ITEM* bgi;
3883
3884 searchkey.obj_type = TYPE_BLOCK_GROUP_ITEM;
3885
3886 Vcb->superblock.bytes_used = 0;
3887
3888 while (le != &Vcb->chunks) {
3890
3891 searchkey.obj_id = c->offset;
3892 searchkey.offset = c->chunk_item->size;
3893
3894 Status = find_item(Vcb, Vcb->extent_root, &tp, &searchkey, false, Irp);
3895 if (!NT_SUCCESS(Status)) {
3896 ERR("error - find_item returned %08lx\n", Status);
3897 return Status;
3898 }
3899
3900 if (!keycmp(searchkey, tp.item->key)) {
3901 if (tp.item->size >= sizeof(BLOCK_GROUP_ITEM)) {
3902 bgi = (BLOCK_GROUP_ITEM*)tp.item->data;
3903
3904 c->used = c->oldused = bgi->used;
3905
3906 TRACE("chunk %I64x has %I64x bytes used\n", c->offset, c->used);
3907
3908 Vcb->superblock.bytes_used += bgi->used;
3909 } else {
3910 ERR("(%I64x;%I64x,%x,%I64x) is %u bytes, expected %Iu\n",
3911 Vcb->extent_root->id, tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(BLOCK_GROUP_ITEM));
3912 }
3913 }
3914
3915 le = le->Flink;
3916 }
3917
3918 Vcb->chunk_usage_found = true;
3919
3920 return STATUS_SUCCESS;
3921}
#define keycmp(key1, key2)
Definition: btrfs_drv.h:1016
static LONG find_item(PropertyBag *This, LPCOLESTR name)
Definition: propertybag.c:110
#define TYPE_BLOCK_GROUP_ITEM
Definition: btrfs.h:42
#define c
Definition: ke_i.h:80
uint64_t used
Definition: btrfs.h:424
Definition: btrfs.h:143
uint8_t obj_type
Definition: btrfs.h:145
uint64_t obj_id
Definition: btrfs.h:144
uint64_t offset
Definition: btrfs.h:146
uint8_t * data
Definition: btrfs_drv.h:415
uint16_t size
Definition: btrfs_drv.h:414
tree_data * item
Definition: btrfs_drv.h:509

Referenced by get_usage(), and mount_vol().

◆ find_default_subvol()

_Ret_maybenull_ root * find_default_subvol ( _In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension Vcb,
_In_opt_ PIRP  Irp 
)

Definition at line 3981 of file btrfs.c.

3981 {
3982 LIST_ENTRY* le;
3983
3984 static const char fn[] = "default";
3985 static uint32_t crc32 = 0x8dbfc2d2;
3986
3987 if (Vcb->options.subvol_id != 0) {
3988 le = Vcb->roots.Flink;
3989 while (le != &Vcb->roots) {
3991
3992 if (r->id == Vcb->options.subvol_id)
3993 return r;
3994
3995 le = le->Flink;
3996 }
3997 }
3998
3999 if (Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_DEFAULT_SUBVOL) {
4001 KEY searchkey;
4003 DIR_ITEM* di;
4004
4005 searchkey.obj_id = Vcb->superblock.root_dir_objectid;
4006 searchkey.obj_type = TYPE_DIR_ITEM;
4007 searchkey.offset = crc32;
4008
4009 Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp);
4010 if (!NT_SUCCESS(Status)) {
4011 ERR("error - find_item returned %08lx\n", Status);
4012 goto end;
4013 }
4014
4015 if (keycmp(tp.item->key, searchkey)) {
4016 ERR("could not find (%I64x,%x,%I64x) in root tree\n", searchkey.obj_id, searchkey.obj_type, searchkey.offset);
4017 goto end;
4018 }
4019
4020 if (tp.item->size < sizeof(DIR_ITEM)) {
4021 ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM));
4022 goto end;
4023 }
4024
4025 di = (DIR_ITEM*)tp.item->data;
4026
4027 if (tp.item->size < sizeof(DIR_ITEM) - 1 + di->n) {
4028 ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DIR_ITEM) - 1 + di->n);
4029 goto end;
4030 }
4031
4032 if (di->n != strlen(fn) || RtlCompareMemory(di->name, fn, di->n) != di->n) {
4033 ERR("root DIR_ITEM had same CRC32, but was not \"default\"\n");
4034 goto end;
4035 }
4036
4037 if (di->key.obj_type != TYPE_ROOT_ITEM) {
4038 ERR("default root has key (%I64x,%x,%I64x), expected subvolume\n", di->key.obj_id, di->key.obj_type, di->key.offset);
4039 goto end;
4040 }
4041
4042 le = Vcb->roots.Flink;
4043 while (le != &Vcb->roots) {
4045
4046 if (r->id == di->key.obj_id)
4047 return r;
4048
4049 le = le->Flink;
4050 }
4051
4052 ERR("could not find root %I64x, using default instead\n", di->key.obj_id);
4053 }
4054
4055end:
4056 le = Vcb->roots.Flink;
4057 while (le != &Vcb->roots) {
4059
4060 if (r->id == BTRFS_ROOT_FSTREE)
4061 return r;
4062
4063 le = le->Flink;
4064 }
4065
4066 return NULL;
4067}
#define BTRFS_ROOT_FSTREE
Definition: btrfs.h:58
#define TYPE_DIR_ITEM
Definition: btrfs.h:28
KEY key
Definition: btrfs.h:273
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159

Referenced by load_dir_children(), and mount_vol().

◆ find_device_from_uuid()

_Ret_maybenull_ device * find_device_from_uuid ( _In_ device_extension Vcb,
_In_ BTRFS_UUID uuid 
)

Definition at line 3299 of file btrfs.c.

3299 {
3301 pdo_device_extension* pdode;
3302 LIST_ENTRY* le;
3303
3304 le = Vcb->devices.Flink;
3305 while (le != &Vcb->devices) {
3307
3308 TRACE("device %I64x, uuid %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", dev->devitem.dev_id,
3309 dev->devitem.device_uuid.uuid[0], dev->devitem.device_uuid.uuid[1], dev->devitem.device_uuid.uuid[2], dev->devitem.device_uuid.uuid[3], dev->devitem.device_uuid.uuid[4], dev->devitem.device_uuid.uuid[5], dev->devitem.device_uuid.uuid[6], dev->devitem.device_uuid.uuid[7],
3310 dev->devitem.device_uuid.uuid[8], dev->devitem.device_uuid.uuid[9], dev->devitem.device_uuid.uuid[10], dev->devitem.device_uuid.uuid[11], dev->devitem.device_uuid.uuid[12], dev->devitem.device_uuid.uuid[13], dev->devitem.device_uuid.uuid[14], dev->devitem.device_uuid.uuid[15]);
3311
3312 if (RtlCompareMemory(&dev->devitem.device_uuid, uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
3313 TRACE("returning device %I64x\n", dev->devitem.dev_id);
3314 return dev;
3315 }
3316
3317 le = le->Flink;
3318 }
3319
3320 vde = Vcb->vde;
3321
3322 if (!vde)
3323 goto end;
3324
3325 pdode = vde->pdode;
3326
3328
3329 if (Vcb->devices_loaded < Vcb->superblock.num_devices) {
3330 le = pdode->children.Flink;
3331
3332 while (le != &pdode->children) {
3334
3335 if (RtlCompareMemory(uuid, &vc->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
3336 device* dev;
3337
3339 if (!dev) {
3341 ERR("out of memory\n");
3342 return NULL;
3343 }
3344
3345 RtlZeroMemory(dev, sizeof(device));
3346 dev->devobj = vc->devobj;
3347 dev->fileobj = vc->fileobj;
3348 dev->devitem.device_uuid = *uuid;
3349 dev->devitem.dev_id = vc->devid;
3350 dev->devitem.num_bytes = vc->size;
3351 dev->seeding = vc->seeding;
3352 dev->readonly = dev->seeding;
3353 dev->reloc = false;
3354 dev->removable = false;
3355 dev->disk_num = vc->disk_num;
3356 dev->part_num = vc->part_num;
3357 dev->num_trim_entries = 0;
3358 InitializeListHead(&dev->trim_list);
3359
3361 Vcb->devices_loaded++;
3362
3364
3365 return dev;
3366 }
3367
3368 le = le->Flink;
3369 }
3370 }
3371
3373
3374end:
3375 WARN("could not find device with uuid %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
3376 uuid->uuid[0], uuid->uuid[1], uuid->uuid[2], uuid->uuid[3], uuid->uuid[4], uuid->uuid[5], uuid->uuid[6], uuid->uuid[7],
3377 uuid->uuid[8], uuid->uuid[9], uuid->uuid[10], uuid->uuid[11], uuid->uuid[12], uuid->uuid[13], uuid->uuid[14], uuid->uuid[15]);
3378
3379 return NULL;
3380}
static void add_device_to_list(_In_ device_extension *Vcb, _In_ device *dev)
Definition: btrfs.c:3279
Definition: msctf.idl:550
LIST_ENTRY children
Definition: btrfs_drv.h:897
PFILE_OBJECT fileobj
Definition: btrfs_drv.h:858
uint64_t size
Definition: btrfs_drv.h:860
uint64_t devid
Definition: btrfs_drv.h:855
ULONG part_num
Definition: btrfs_drv.h:865
ULONG disk_num
Definition: btrfs_drv.h:864
bool seeding
Definition: btrfs_drv.h:861
PDEVICE_OBJECT devobj
Definition: btrfs_drv.h:857
BTRFS_UUID uuid
Definition: btrfs_drv.h:854

Referenced by load_chunk_root(), and read_data().

◆ find_disk_holes()

static NTSTATUS find_disk_holes ( _In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension Vcb,
_In_ device dev,
_In_opt_ PIRP  Irp 
)
static

Definition at line 3207 of file btrfs.c.

3207 {
3208 KEY searchkey;
3209 traverse_ptr tp, next_tp;
3210 bool b;
3211 uint64_t lastaddr;
3213
3214 InitializeListHead(&dev->space);
3215
3216 searchkey.obj_id = 0;
3217 searchkey.obj_type = TYPE_DEV_STATS;
3218 searchkey.offset = dev->devitem.dev_id;
3219
3220 Status = find_item(Vcb, Vcb->dev_root, &tp, &searchkey, false, Irp);
3221 if (NT_SUCCESS(Status) && !keycmp(tp.item->key, searchkey))
3222 RtlCopyMemory(dev->stats, tp.item->data, min(sizeof(uint64_t) * 5, tp.item->size));
3223
3224 searchkey.obj_id = dev->devitem.dev_id;
3225 searchkey.obj_type = TYPE_DEV_EXTENT;
3226 searchkey.offset = 0;
3227
3228 Status = find_item(Vcb, Vcb->dev_root, &tp, &searchkey, false, Irp);
3229 if (!NT_SUCCESS(Status)) {
3230 ERR("error - find_item returned %08lx\n", Status);
3231 return Status;
3232 }
3233
3234 lastaddr = 0;
3235
3236 do {
3237 if (tp.item->key.obj_id == dev->devitem.dev_id && tp.item->key.obj_type == TYPE_DEV_EXTENT) {
3238 if (tp.item->size >= sizeof(DEV_EXTENT)) {
3239 DEV_EXTENT* de = (DEV_EXTENT*)tp.item->data;
3240
3241 if (tp.item->key.offset > lastaddr) {
3242 Status = add_space_entry(&dev->space, NULL, lastaddr, tp.item->key.offset - lastaddr);
3243 if (!NT_SUCCESS(Status)) {
3244 ERR("add_space_entry returned %08lx\n", Status);
3245 return Status;
3246 }
3247 }
3248
3249 lastaddr = tp.item->key.offset + de->length;
3250 } else {
3251 ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DEV_EXTENT));
3252 }
3253 }
3254
3255 b = find_next_item(Vcb, &tp, &next_tp, false, Irp);
3256
3257 if (b) {
3258 tp = next_tp;
3259 if (tp.item->key.obj_id > searchkey.obj_id || tp.item->key.obj_type > searchkey.obj_type)
3260 break;
3261 }
3262 } while (b);
3263
3264 if (lastaddr < dev->devitem.num_bytes) {
3265 Status = add_space_entry(&dev->space, NULL, lastaddr, dev->devitem.num_bytes - lastaddr);
3266 if (!NT_SUCCESS(Status)) {
3267 ERR("add_space_entry returned %08lx\n", Status);
3268 return Status;
3269 }
3270 }
3271
3272 // The Linux driver doesn't like to allocate chunks within the first megabyte of a device.
3273
3274 space_list_subtract2(&dev->space, NULL, 0, 0x100000, NULL, NULL);
3275
3276 return STATUS_SUCCESS;
3277}
NTSTATUS add_space_entry(LIST_ENTRY *list, LIST_ENTRY *list_size, uint64_t offset, uint64_t size)
Definition: free-space.c:190
void space_list_subtract2(LIST_ENTRY *list, LIST_ENTRY *list_size, uint64_t address, uint64_t length, chunk *c, LIST_ENTRY *rollback)
Definition: free-space.c:2155
NTSTATUS NTSTATUS 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) __attribute__((nonnull(1
#define TYPE_DEV_EXTENT
Definition: btrfs.h:46
#define TYPE_DEV_STATS
Definition: btrfs.h:50
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define b
Definition: ke_i.h:79
uint64_t length
Definition: btrfs.h:472

Referenced by mount_vol().

◆ free_fcb()

void free_fcb ( _Inout_ fcb fcb)

Definition at line 1734 of file btrfs.c.

1734 {
1736#endif
1737
1738#ifdef DEBUG_FCB_REFCOUNTS
1739 ERR("fcb %p (%s): refcount now %i (subvol %I64x, inode %I64x)\n", fcb, func, rc, fcb->subvol ? fcb->subvol->id : 0, fcb->inode);
1740#endif
1741}
GLenum func
Definition: glext.h:6028
uint64_t inode
Definition: btrfs_drv.h:289
LONG refcount
Definition: btrfs_drv.h:285

Referenced by allocate_cache_chunk(), check_for_orphans_root(), close_file(), create_stream(), do_write2(), drop_chunk(), duplicate_fcb(), file_create2(), get_reparse_tag(), load_stored_free_space_cache(), mount_vol(), move_across_subvols(), open_fileref_by_inode(), open_fileref_child(), reap_fileref(), remove_free_space_inode(), rename_stream(), rename_stream_to_file(), and update_chunk_usage().

◆ free_fileref()

void free_fileref ( _Inout_ file_ref fr)

Definition at line 1856 of file btrfs.c.

1856 {
1857#if defined(_DEBUG) || defined(DEBUG_FCB_REFCOUNTS)
1858 LONG rc = InterlockedDecrement(&fr->refcount);
1859
1860#ifdef DEBUG_FCB_REFCOUNTS
1861 ERR("fileref %p: refcount now %i\n", fr, rc);
1862#endif
1863
1864#ifdef _DEBUG
1865 if (rc < 0) {
1866 ERR("fileref %p: refcount now %li\n", fr, rc);
1867 int3;
1868 }
1869#endif
1870#else
1871 InterlockedDecrement(&fr->refcount);
1872#endif
1873}
#define int3
Definition: btrfs_drv.h:1745

Referenced by _Function_class_(), close_file(), create_snapshot(), create_stream(), create_subvol(), do_create_snapshot(), do_write2(), file_create(), fill_in_hard_link_full_id_information(), fill_in_hard_link_information(), get_subvol_path(), mknod(), mount_vol(), move_across_subvols(), open_file(), open_file2(), open_fileref(), open_fileref_by_inode(), oplock_complete(), reap_fileref(), rename_file_to_stream(), rename_stream(), rename_stream_to_file(), send_notification_fcb(), set_link_information(), and set_rename_information().

◆ get_device_change_count()

static ULONG get_device_change_count ( _In_ PDEVICE_OBJECT  devobj)
static

Definition at line 3396 of file btrfs.c.

3396 {
3398 ULONG cc;
3400
3401 Status = dev_ioctl(devobj, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, &cc, sizeof(ULONG), true, &iosb);
3402
3403 if (!NT_SUCCESS(Status)) {
3404 ERR("dev_ioctl returned %08lx\n", Status);
3405 return 0;
3406 }
3407
3408 if (iosb.Information < sizeof(ULONG)) {
3409 ERR("iosb.Information was too short\n");
3410 return 0;
3411 }
3412
3413 return cc;
3414}
NTSTATUS dev_ioctl(_In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG ControlCode, _In_reads_bytes_opt_(InputBufferSize) PVOID InputBuffer, _In_ ULONG InputBufferSize, _Out_writes_bytes_opt_(OutputBufferSize) PVOID OutputBuffer, _In_ ULONG OutputBufferSize, _In_ bool Override, _Out_opt_ IO_STATUS_BLOCK *iosb)
Definition: btrfs.c:2954
uint32_t cc
Definition: isohybrid.c:75
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98

Referenced by init_device().

◆ get_device_pnp_name()

NTSTATUS get_device_pnp_name ( _In_ PDEVICE_OBJECT  DeviceObject,
_Out_ PUNICODE_STRING  pnp_name,
_Out_ const GUID **  guid 
)

Definition at line 4233 of file btrfs.c.

4233 {
4235
4236 Status = get_device_pnp_name_guid(DeviceObject, pnp_name, &GUID_DEVINTERFACE_VOLUME);
4237 if (NT_SUCCESS(Status)) {
4238 *guid = &GUID_DEVINTERFACE_VOLUME;
4239 return Status;
4240 }
4241
4242 Status = get_device_pnp_name_guid(DeviceObject, pnp_name, &GUID_DEVINTERFACE_HIDDEN_VOLUME);
4243 if (NT_SUCCESS(Status)) {
4244 *guid = &GUID_DEVINTERFACE_HIDDEN_VOLUME;
4245 return Status;
4246 }
4247
4248 Status = get_device_pnp_name_guid(DeviceObject, pnp_name, &GUID_DEVINTERFACE_DISK);
4249 if (NT_SUCCESS(Status)) {
4250 *guid = &GUID_DEVINTERFACE_DISK;
4251 return Status;
4252 }
4253
4254 return STATUS_NOT_FOUND;
4255}
static NTSTATUS get_device_pnp_name_guid(_In_ PDEVICE_OBJECT DeviceObject, _Out_ PUNICODE_STRING pnp_name, _In_ const GUID *guid)
Definition: btrfs.c:4178
const GUID * guid
#define STATUS_NOT_FOUND
Definition: shellext.h:72

Referenced by add_device(), and probe_volume().

◆ get_device_pnp_name_guid()

static NTSTATUS get_device_pnp_name_guid ( _In_ PDEVICE_OBJECT  DeviceObject,
_Out_ PUNICODE_STRING  pnp_name,
_In_ const GUID guid 
)
static

Definition at line 4178 of file btrfs.c.

4178 {
4180 WCHAR *list = NULL, *s;
4181
4183 if (!NT_SUCCESS(Status)) {
4184 ERR("IoGetDeviceInterfaces returned %08lx\n", Status);
4185 return Status;
4186 }
4187
4188 s = list;
4189 while (s[0] != 0) {
4191 PDEVICE_OBJECT devobj;
4193
4194 name.Length = name.MaximumLength = (USHORT)wcslen(s) * sizeof(WCHAR);
4195 name.Buffer = s;
4196
4198 if (DeviceObject == devobj || DeviceObject == FileObject->DeviceObject) {
4200
4201 pnp_name->Buffer = ExAllocatePoolWithTag(PagedPool, name.Length, ALLOC_TAG);
4202 if (!pnp_name->Buffer) {
4203 ERR("out of memory\n");
4205 goto end;
4206 }
4207
4208 RtlCopyMemory(pnp_name->Buffer, name.Buffer, name.Length);
4209 pnp_name->Length = pnp_name->MaximumLength = name.Length;
4210
4212 goto end;
4213 }
4214
4216 }
4217
4218 s = &s[wcslen(s) + 1];
4219 }
4220
4221 pnp_name->Length = pnp_name->MaximumLength = 0;
4222 pnp_name->Buffer = 0;
4223
4225
4226end:
4227 if (list)
4229
4230 return Status;
4231}
Definition: list.h:37
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSTATUS NTAPI IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid, IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN ULONG Flags, OUT PWSTR *SymbolicLinkList)
Definition: deviface.c:454
#define list
Definition: rosglue.h:35

Referenced by get_device_pnp_name().

◆ get_file_attributes()

ULONG get_file_attributes ( _In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension Vcb,
_In_ root r,
_In_ uint64_t  inode,
_In_ uint8_t  type,
_In_ bool  dotfile,
_In_ bool  ignore_xa,
_In_opt_ PIRP  Irp 
)

Definition at line 2664 of file btrfs.c.

2665 {
2666 ULONG att;
2667 char* eaval;
2668 uint16_t ealen;
2669
2670 if (!ignore_xa && get_xattr(Vcb, r, inode, EA_DOSATTRIB, EA_DOSATTRIB_HASH, (uint8_t**)&eaval, &ealen, Irp)) {
2671 ULONG dosnum = 0;
2672
2673 if (get_file_attributes_from_xattr(eaval, ealen, &dosnum)) {
2674 ExFreePool(eaval);
2675
2677 dosnum |= FILE_ATTRIBUTE_DIRECTORY;
2678 else if (type == BTRFS_TYPE_SYMLINK)
2680
2682 dosnum &= ~FILE_ATTRIBUTE_DIRECTORY;
2683
2684 if (inode == SUBVOL_ROOT_INODE) {
2685 if (r->root_item.flags & BTRFS_SUBVOL_READONLY)
2686 dosnum |= FILE_ATTRIBUTE_READONLY;
2687 else
2688 dosnum &= ~FILE_ATTRIBUTE_READONLY;
2689 }
2690
2691 return dosnum;
2692 }
2693
2694 ExFreePool(eaval);
2695 }
2696
2697 switch (type) {
2700 break;
2701
2702 case BTRFS_TYPE_SYMLINK:
2704 break;
2705
2706 default:
2707 att = 0;
2708 break;
2709 }
2710
2711 if (dotfile || (r->id == BTRFS_ROOT_FSTREE && inode == SUBVOL_ROOT_INODE))
2712 att |= FILE_ATTRIBUTE_HIDDEN;
2713
2715
2716 if (inode == SUBVOL_ROOT_INODE) {
2717 if (r->root_item.flags & BTRFS_SUBVOL_READONLY)
2719 else
2720 att &= ~FILE_ATTRIBUTE_READONLY;
2721 }
2722
2723 // FIXME - get READONLY from ii->st_mode
2724 // FIXME - return SYSTEM for block/char devices?
2725
2726 if (att == 0)
2728
2729 return att;
2730}
unsigned short int uint16_t
Definition: acefiex.h:54
#define EA_DOSATTRIB_HASH
Definition: btrfs_drv.h:97
#define EA_DOSATTRIB
Definition: btrfs_drv.h:96
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define BTRFS_SUBVOL_READONLY
Definition: btrfs.h:109
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
#define BTRFS_TYPE_SYMLINK
Definition: shellext.h:91
Definition: fs.h:78

Referenced by create_directory_fcb(), create_subvol(), fsctl_set_xattr(), mount_vol(), move_across_subvols(), open_file3(), query_dir_item(), set_basic_information(), and set_sparse().

◆ get_last_inode()

static bool get_last_inode ( _In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension Vcb,
_In_ root r,
_In_opt_ PIRP  Irp 
)
static

Definition at line 386 of file btrfs.c.

386 {
387 KEY searchkey;
388 traverse_ptr tp, prev_tp;
390
391 // get last entry
392 searchkey.obj_id = 0xffffffffffffffff;
393 searchkey.obj_type = 0xff;
394 searchkey.offset = 0xffffffffffffffff;
395
396 Status = find_item(Vcb, r, &tp, &searchkey, false, Irp);
397 if (!NT_SUCCESS(Status)) {
398 ERR("error - find_item returned %08lx\n", Status);
399 return false;
400 }
401
403 r->lastinode = tp.item->key.obj_id;
404 TRACE("last inode for tree %I64x is %I64x\n", r->id, r->lastinode);
405 return true;
406 }
407
408 while (find_prev_item(Vcb, &tp, &prev_tp, Irp)) {
409 tp = prev_tp;
410
411 TRACE("moving on to %I64x,%x,%I64x\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset);
412
414 r->lastinode = tp.item->key.obj_id;
415 TRACE("last inode for tree %I64x is %I64x\n", r->id, r->lastinode);
416 return true;
417 }
418 }
419
420 r->lastinode = SUBVOL_ROOT_INODE;
421
422 WARN("no INODE_ITEMs in tree %I64x\n", r->id);
423
424 return true;
425}
#define BTRFS_LAST_FREE_OBJECTID
Definition: btrfs.h:62
NTSTATUS NTSTATUS bool bool find_prev_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, const traverse_ptr *tp, traverse_ptr *prev_tp, PIRP Irp) __attribute__((nonnull(1
#define TYPE_INODE_ITEM
Definition: btrfs.h:23

Referenced by if().

◆ get_num_of_processors()

uint32_t get_num_of_processors ( )

Definition at line 4080 of file btrfs.c.

4080 {
4082 uint32_t r = 0;
4083
4084 while (p != 0) {
4085 if (p & 1)
4086 r++;
4087
4088 p >>= 1;
4089 }
4090
4091 return r;
4092}
ULONG_PTR KAFFINITY
Definition: compat.h:85
GLfloat GLfloat p
Definition: glext.h:8902
KAFFINITY NTAPI KeQueryActiveProcessors(VOID)
Definition: cpu.c:637

Referenced by create_calc_threads().

◆ if() [1/7]

if ( check_superblock_checksumsb)

Definition at line 4284 of file btrfs.c.

4284 {
4286 goto end;
4287 }

◆ if() [2/7]

if ( NT_SUCCESSStatus)

Definition at line 4274 of file btrfs.c.

4274 {
4275 ERR("sync_read_phys returned %08lx\n", Status);
4276 goto end;
4277 }

◆ if() [3/7]

if ( r)

Definition at line 2998 of file btrfs.c.

2998 {
2999 ERR("out of memory\n");
3001 }

◆ if() [4/7]

if ( !r->  nonpaged)

Definition at line 3019 of file btrfs.c.

3019 {
3020 ERR("out of memory\n");
3021 ExFreePool(r);
3023 }

◆ if() [5/7]

if ( !Vcb->readonly &&  r->id==BTRFS_ROOT_ROOT||r->id==BTRFS_ROOT_FSTREE||(r->id >=0x100 &&!(r->id &0xf000000000000000)))

Definition at line 3036 of file btrfs.c.

3036 { // FS tree root
3037 // FIXME - don't call this if subvol is readonly (though we will have to if we ever toggle this flag)
3039
3040 if (r->id == BTRFS_ROOT_ROOT && r->lastinode < 0x100)
3041 r->lastinode = 0x100;
3042 }
static bool get_last_inode(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _In_opt_ PIRP Irp)
Definition: btrfs.c:386
#define BTRFS_ROOT_ROOT
Definition: btrfs.h:54

◆ if() [6/7]

if ( sb->magic = BTRFS_MAGIC)

Definition at line 4279 of file btrfs.c.

4279 {
4281 goto end;
4282 }

◆ if() [7/7]

if ( tp  )

Definition at line 3029 of file btrfs.c.

3029 {
3030 RtlCopyMemory(&r->root_item, tp->item->data, min(sizeof(ROOT_ITEM), tp->item->size));
3031 if (tp->item->size < sizeof(ROOT_ITEM))
3032 RtlZeroMemory(((uint8_t*)&r->root_item) + tp->item->size, sizeof(ROOT_ITEM) - tp->item->size);
3033 } else

◆ init_device()

void init_device ( _In_ device_extension Vcb,
_Inout_ device dev,
_In_ bool  get_nums 
)

Definition at line 3416 of file btrfs.c.

3416 {
3418 ULONG aptelen;
3419 ATA_PASS_THROUGH_EX* apte;
3422
3423 dev->removable = is_device_removable(dev->devobj);
3424 dev->change_count = dev->removable ? get_device_change_count(dev->devobj) : 0;
3425
3426 if (get_nums) {
3428
3430 &sdn, sizeof(STORAGE_DEVICE_NUMBER), true, NULL);
3431
3432 if (!NT_SUCCESS(Status)) {
3433 WARN("IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n", Status);
3434 dev->disk_num = 0xffffffff;
3435 dev->part_num = 0xffffffff;
3436 } else {
3437 dev->disk_num = sdn.DeviceNumber;
3438 dev->part_num = sdn.PartitionNumber;
3439 }
3440 }
3441
3442 dev->trim = false;
3443 dev->readonly = dev->seeding;
3444 dev->reloc = false;
3445 dev->num_trim_entries = 0;
3446 dev->stats_changed = false;
3447 InitializeListHead(&dev->trim_list);
3448
3449 if (!dev->readonly) {
3451 NULL, 0, true, NULL);
3453 dev->readonly = true;
3454 }
3455
3456 aptelen = sizeof(ATA_PASS_THROUGH_EX) + 512;
3458 if (!apte) {
3459 ERR("out of memory\n");
3460 return;
3461 }
3462
3463 RtlZeroMemory(apte, aptelen);
3464
3465 apte->Length = sizeof(ATA_PASS_THROUGH_EX);
3467 apte->DataTransferLength = aptelen - sizeof(ATA_PASS_THROUGH_EX);
3468 apte->TimeOutValue = 3;
3469 apte->DataBufferOffset = apte->Length;
3471
3472 Status = dev_ioctl(dev->devobj, IOCTL_ATA_PASS_THROUGH, apte, aptelen,
3473 apte, aptelen, true, NULL);
3474
3475 if (!NT_SUCCESS(Status))
3476 TRACE("IOCTL_ATA_PASS_THROUGH returned %08lx for IDENTIFY DEVICE\n", Status);
3477 else {
3479
3480 if (idd->CommandSetSupport.FlushCache) {
3481 dev->can_flush = true;
3482 TRACE("FLUSH CACHE supported\n");
3483 } else
3484 TRACE("FLUSH CACHE not supported\n");
3485 }
3486
3487 ExFreePool(apte);
3488
3489#ifdef DEBUG_TRIM_EMULATION
3490 dev->trim = true;
3491 Vcb->trim = true;
3492#else
3495 spq.AdditionalParameters[0] = 0;
3496
3498 &dtd, sizeof(DEVICE_TRIM_DESCRIPTOR), true, NULL);
3499
3500 if (NT_SUCCESS(Status)) {
3501 if (dtd.TrimEnabled) {
3502 dev->trim = true;
3503 Vcb->trim = true;
3504 TRACE("TRIM supported\n");
3505 } else
3506 TRACE("TRIM not supported\n");
3507 }
3508#endif
3509
3510 RtlZeroMemory(dev->stats, sizeof(uint64_t) * 5);
3511}
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
static ULONG get_device_change_count(_In_ PDEVICE_OBJECT devobj)
Definition: btrfs.c:3396
static bool is_device_removable(_In_ PDEVICE_OBJECT devobj)
Definition: btrfs.c:3382
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:178
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
@ StorageDeviceTrimProperty
Definition: ntddstor.h:520
@ PropertyStandardQuery
Definition: ntddstor.h:505
#define IOCTL_ATA_PASS_THROUGH
Definition: ntddscsi.h:40
struct _ATA_PASS_THROUGH_EX ATA_PASS_THROUGH_EX
ULONG DataTransferLength
Definition: ntddscsi.h:198
UCHAR CurrentTaskFile[8]
Definition: ntddscsi.h:203
ULONG_PTR DataBufferOffset
Definition: ntddscsi.h:201
struct _IDENTIFY_DEVICE_DATA::@1888 CommandSetSupport
STORAGE_QUERY_TYPE QueryType
Definition: ntddstor.h:553
UCHAR AdditionalParameters[1]
Definition: ntddstor.h:554
STORAGE_PROPERTY_ID PropertyId
Definition: ntddstor.h:552
#define ATA_FLAGS_DATA_IN
Definition: uata_ctl.h:222

Referenced by add_device(), add_volume_device(), load_chunk_root(), and mount_vol().

◆ init_file_cache()

void init_file_cache ( _In_ PFILE_OBJECT  FileObject,
_In_ CC_FILE_SIZES ccfs 
)

Definition at line 4069 of file btrfs.c.

4069 {
4070 TRACE("(%p, %p)\n", FileObject, ccfs);
4071
4073
4074 if (diskacc)
4076
4078}
CACHE_MANAGER_CALLBACKS cache_callbacks
Definition: cache.c:20
#define READ_AHEAD_GRANULARITY
Definition: btrfs_drv.h:114
#define CC_ENABLE_DISK_IO_ACCOUNTING
Definition: btrfs_drv.h:1845
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195

Referenced by __attribute__(), and do_read().

◆ is_btrfs_volume()

static bool is_btrfs_volume ( _In_ PDEVICE_OBJECT  DeviceObject)
static

Definition at line 4141 of file btrfs.c.

4141 {
4143 MOUNTDEV_NAME mdn, *mdn2;
4144 ULONG mdnsize;
4145
4148 ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
4149 return false;
4150 }
4151
4152 mdnsize = (ULONG)offsetof(MOUNTDEV_NAME, Name[0]) + mdn.NameLength;
4153
4154 mdn2 = ExAllocatePoolWithTag(PagedPool, mdnsize, ALLOC_TAG);
4155 if (!mdn2) {
4156 ERR("out of memory\n");
4157 return false;
4158 }
4159
4161 if (!NT_SUCCESS(Status)) {
4162 ERR("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME returned %08lx\n", Status);
4163 ExFreePool(mdn2);
4164 return false;
4165 }
4166
4167 if (mdn2->NameLength > (sizeof(BTRFS_VOLUME_PREFIX) - sizeof(WCHAR)) &&
4168 RtlCompareMemory(mdn2->Name, BTRFS_VOLUME_PREFIX, sizeof(BTRFS_VOLUME_PREFIX) - sizeof(WCHAR)) == sizeof(BTRFS_VOLUME_PREFIX) - sizeof(WCHAR)) {
4169 ExFreePool(mdn2);
4170 return true;
4171 }
4172
4173 ExFreePool(mdn2);
4174
4175 return false;
4176}
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
USHORT NameLength
Definition: imports.h:143
WCHAR Name[1]
Definition: imports.h:144

Referenced by mount_vol().

◆ is_device_removable()

static bool is_device_removable ( _In_ PDEVICE_OBJECT  devobj)
static

Definition at line 3382 of file btrfs.c.

3382 {
3385
3386 Status = dev_ioctl(devobj, IOCTL_STORAGE_GET_HOTPLUG_INFO, NULL, 0, &shi, sizeof(STORAGE_HOTPLUG_INFO), true, NULL);
3387
3388 if (!NT_SUCCESS(Status)) {
3389 ERR("dev_ioctl returned %08lx\n", Status);
3390 return false;
3391 }
3392
3393 return shi.MediaRemovable != 0 ? true : false;
3394}
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
#define true
Definition: stdbool.h:36
BOOLEAN MediaRemovable
Definition: imports.h:246

Referenced by init_device().

◆ is_top_level()

bool is_top_level ( _In_ PIRP  Irp)

Definition at line 278 of file btrfs.c.

278 {
279 if (!IoGetTopLevelIrp()) {
281 return true;
282 }
283
284 return false;
285}
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843

Referenced by _Dispatch_type_(), do_read_job(), and do_write_job().

◆ lie_about_fs_type()

static bool lie_about_fs_type ( )
static

Definition at line 687 of file btrfs.c.

687 {
690 PPEB peb;
691 LIST_ENTRY* le;
692 ULONG retlen;
693#ifdef _AMD64_
694 ULONG_PTR wow64info;
695#endif
696
697 INIT_UNICODE_STRING(mpr, L"MPR.DLL");
698 INIT_UNICODE_STRING(cmd, L"CMD.EXE");
699 INIT_UNICODE_STRING(fsutil, L"FSUTIL.EXE");
700 INIT_UNICODE_STRING(storsvc, L"STORSVC.DLL");
701
702 /* Not doing a Volkswagen, honest! Some IFS tests won't run if not recognized FS. */
703 INIT_UNICODE_STRING(ifstest, L"IFSTEST.EXE");
704
705 if (!PsGetCurrentProcess())
706 return false;
707
708#ifdef _AMD64_
710
711 if (NT_SUCCESS(Status) && wow64info != 0)
712 return true;
713#endif
714
716
717 if (!NT_SUCCESS(Status)) {
718 ERR("ZwQueryInformationProcess returned %08lx\n", Status);
719 return false;
720 }
721
722 if (!pbi.PebBaseAddress)
723 return false;
724
725 peb = pbi.PebBaseAddress;
726
727 if (!peb->Ldr)
728 return false;
729
731 while (le != &peb->Ldr->InMemoryOrderModuleList) {
733 bool blacklist = false;
734
735 if (entry->FullDllName.Length >= usmpr.Length) {
737
738 name.Buffer = &entry->FullDllName.Buffer[(entry->FullDllName.Length - usmpr.Length) / sizeof(WCHAR)];
739 name.Length = name.MaximumLength = usmpr.Length;
740
741 blacklist = compare_strings(&name, &usmpr);
742 }
743
744 if (!blacklist && entry->FullDllName.Length >= uscmd.Length) {
746
747 name.Buffer = &entry->FullDllName.Buffer[(entry->FullDllName.Length - uscmd.Length) / sizeof(WCHAR)];
748 name.Length = name.MaximumLength = uscmd.Length;
749
750 blacklist = compare_strings(&name, &uscmd);
751 }
752
753 if (!blacklist && entry->FullDllName.Length >= usfsutil.Length) {
755
756 name.Buffer = &entry->FullDllName.Buffer[(entry->FullDllName.Length - usfsutil.Length) / sizeof(WCHAR)];
757 name.Length = name.MaximumLength = usfsutil.Length;
758
759 blacklist = compare_strings(&name, &usfsutil);
760 }
761
762 if (!blacklist && entry->FullDllName.Length >= usstorsvc.Length) {
764
765 name.Buffer = &entry->FullDllName.Buffer[(entry->FullDllName.Length - usstorsvc.Length) / sizeof(WCHAR)];
766 name.Length = name.MaximumLength = usstorsvc.Length;
767
768 blacklist = compare_strings(&name, &usstorsvc);
769 }
770
771 if (!blacklist && entry->FullDllName.Length >= usifstest.Length) {
773
774 name.Buffer = &entry->FullDllName.Buffer[(entry->FullDllName.Length - usifstest.Length) / sizeof(WCHAR)];
775 name.Length = name.MaximumLength = usifstest.Length;
776
777 blacklist = compare_strings(&name, &usifstest);
778 }
779
780 if (blacklist) {
781 void** frames;
782 ULONG i, num_frames;
783
784 frames = ExAllocatePoolWithTag(PagedPool, 256 * sizeof(void*), ALLOC_TAG);
785 if (!frames) {
786 ERR("out of memory\n");
787 return false;
788 }
789
790 num_frames = RtlWalkFrameChain(frames, 256, 1);
791
792 for (i = 0; i < num_frames; i++) {
793 // entry->Reserved3[1] appears to be the image size
794 if (frames[i] >= entry->DllBase && (ULONG_PTR)frames[i] <= (ULONG_PTR)entry->DllBase + (ULONG_PTR)entry->Reserved3[1]) {
795 ExFreePool(frames);
796 return true;
797 }
798 }
799
800 ExFreePool(frames);
801 }
802
803 le = le->Flink;
804 }
805
806 return false;
807}
ULONG NTAPI RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags)
Definition: libsupp.c:227
#define INIT_UNICODE_STRING(var, val)
Definition: btrfs.c:679
static bool compare_strings(const UNICODE_STRING *us1, const UNICODE_STRING *us2)
Definition: btrfs.c:650
@ ProcessBasicInformation
Definition: winternl.h:394
@ ProcessWow64Information
Definition: winternl.h:396
uint32_t entry
Definition: isohybrid.c:63
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
#define NtCurrentProcess()
Definition: nt_native.h:1657
Definition: btrfs_drv.h:1876
LIST_ENTRY InMemoryOrderModuleList
Definition: btrfs_drv.h:1895
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
Definition: ftp_var.h:139
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by _Dispatch_type_().

◆ load_chunk_root()

static NTSTATUS load_chunk_root ( _In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension Vcb,
_In_opt_ PIRP  Irp 
)
static

Definition at line 3513 of file btrfs.c.

3513 {
3514 traverse_ptr tp, next_tp;
3515 KEY searchkey;
3516 bool b;
3517 chunk* c;
3519
3520 searchkey.obj_id = 0;
3521 searchkey.obj_type = 0;
3522 searchkey.offset = 0;
3523
3524 Vcb->data_flags = 0;
3525 Vcb->metadata_flags = 0;
3526 Vcb->system_flags = 0;
3527
3528 Status = find_item(Vcb, Vcb->chunk_root, &tp, &searchkey, false, Irp);
3529 if (!NT_SUCCESS(Status)) {
3530 ERR("error - find_item returned %08lx\n", Status);
3531 return Status;
3532 }
3533
3534 do {
3535 TRACE("(%I64x,%x,%I64x)\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset);
3536
3537 if (tp.item->key.obj_id == 1 && tp.item->key.obj_type == TYPE_DEV_ITEM) {
3538 if (tp.item->size < sizeof(DEV_ITEM)) {
3539 ERR("(%I64x,%x,%I64x) was %u bytes, expected %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(DEV_ITEM));
3540 } else {
3541 DEV_ITEM* di = (DEV_ITEM*)tp.item->data;
3542 LIST_ENTRY* le;
3543 bool done = false;
3544
3545 le = Vcb->devices.Flink;
3546 while (le != &Vcb->devices) {
3548
3549 if (dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &di->device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
3550 RtlCopyMemory(&dev->devitem, tp.item->data, min(tp.item->size, sizeof(DEV_ITEM)));
3551
3552 if (le != Vcb->devices.Flink)
3553 init_device(Vcb, dev, true);
3554
3555 done = true;
3556 break;
3557 }
3558
3559 le = le->Flink;
3560 }
3561
3562 if (!done && Vcb->vde) {
3563 volume_device_extension* vde = Vcb->vde;
3564 pdo_device_extension* pdode = vde->pdode;
3565
3567
3568 if (Vcb->devices_loaded < Vcb->superblock.num_devices) {
3569 le = pdode->children.Flink;
3570
3571 while (le != &pdode->children) {
3573
3574 if (RtlCompareMemory(&di->device_uuid, &vc->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
3575 device* dev;
3576
3578 if (!dev) {
3580 ERR("out of memory\n");
3582 }
3583
3584 RtlZeroMemory(dev, sizeof(device));
3585
3586 dev->devobj = vc->devobj;
3587 dev->fileobj = vc->fileobj;
3588 RtlCopyMemory(&dev->devitem, di, min(tp.item->size, sizeof(DEV_ITEM)));
3589 dev->seeding = vc->seeding;
3590 init_device(Vcb, dev, false);
3591
3592 if (dev->devitem.num_bytes > vc->size) {
3593 WARN("device %I64x: DEV_ITEM says %I64x bytes, but Windows only reports %I64x\n", tp.item->key.offset,
3594 dev->devitem.num_bytes, vc->size);
3595
3596 dev->devitem.num_bytes = vc->size;
3597 }
3598
3599 dev->disk_num = vc->disk_num;
3600 dev->part_num = vc->part_num;
3602 Vcb->devices_loaded++;
3603
3604 done = true;
3605 break;
3606 }
3607
3608 le = le->Flink;
3609 }
3610
3611 if (!done) {
3612 if (!Vcb->options.allow_degraded) {
3613 ERR("volume not found: device %I64x, uuid %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", tp.item->key.offset,
3614 di->device_uuid.uuid[0], di->device_uuid.uuid[1], di->device_uuid.uuid[2], di->device_uuid.uuid[3], di->device_uuid.uuid[4], di->device_uuid.uuid[5], di->device_uuid.uuid[6], di->device_uuid.uuid[7],
3615 di->device_uuid.uuid[8], di->device_uuid.uuid[9], di->device_uuid.uuid[10], di->device_uuid.uuid[11], di->device_uuid.uuid[12], di->device_uuid.uuid[13], di->device_uuid.uuid[14], di->device_uuid.uuid[15]);
3616 } else {
3617 device* dev;
3618
3620 if (!dev) {
3622 ERR("out of memory\n");
3624 }
3625
3626 RtlZeroMemory(dev, sizeof(device));
3627
3628 // Missing device, so we keep dev->devobj as NULL
3629 RtlCopyMemory(&dev->devitem, di, min(tp.item->size, sizeof(DEV_ITEM)));
3630 InitializeListHead(&dev->trim_list);
3631
3633 Vcb->devices_loaded++;
3634 }
3635 }
3636 } else
3637 ERR("unexpected device %I64x found\n", tp.item->key.offset);
3638
3640 }
3641 }
3642 } else if (tp.item->key.obj_type == TYPE_CHUNK_ITEM) {
3643 if (tp.item->size < sizeof(CHUNK_ITEM)) {
3644 ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, sizeof(CHUNK_ITEM));
3645 } else {
3647
3648 if (!c) {
3649 ERR("out of memory\n");
3651 }
3652
3653 c->size = tp.item->size;
3654 c->offset = tp.item->key.offset;
3655 c->used = c->oldused = 0;
3656 c->cache = c->old_cache = NULL;
3657 c->created = false;
3658 c->readonly = false;
3659 c->reloc = false;
3660 c->cache_loaded = false;
3661 c->changed = false;
3662 c->space_changed = false;
3663 c->balance_num = 0;
3664
3666
3667 if (!c->chunk_item) {
3668 ERR("out of memory\n");
3669 ExFreePool(c);
3671 }
3672
3673 RtlCopyMemory(c->chunk_item, tp.item->data, tp.item->size);
3674
3675 if (c->chunk_item->type & BLOCK_FLAG_DATA && c->chunk_item->type > Vcb->data_flags)
3676 Vcb->data_flags = c->chunk_item->type;
3677
3678 if (c->chunk_item->type & BLOCK_FLAG_METADATA && c->chunk_item->type > Vcb->metadata_flags)
3679 Vcb->metadata_flags = c->chunk_item->type;
3680
3681 if (c->chunk_item->type & BLOCK_FLAG_SYSTEM && c->chunk_item->type > Vcb->system_flags)
3682 Vcb->system_flags = c->chunk_item->type;
3683
3684 if (c->chunk_item->type & BLOCK_FLAG_RAID10) {
3685 if (c->chunk_item->sub_stripes == 0 || c->chunk_item->sub_stripes > c->chunk_item->num_stripes) {
3686 ERR("chunk %I64x: invalid stripes (num_stripes %u, sub_stripes %u)\n", c->offset, c->chunk_item->num_stripes, c->chunk_item->sub_stripes);
3687 ExFreePool(c->chunk_item);
3688 ExFreePool(c);
3689 return STATUS_INTERNAL_ERROR;
3690 }
3691 }
3692
3693 if (c->chunk_item->num_stripes > 0) {
3694 CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
3695 uint16_t i;
3696
3697 c->devices = ExAllocatePoolWithTag(NonPagedPool, sizeof(device*) * c->chunk_item->num_stripes, ALLOC_TAG);
3698
3699 if (!c->devices) {
3700 ERR("out of memory\n");
3701 ExFreePool(c->chunk_item);
3702 ExFreePool(c);
3704 }
3705
3706 for (i = 0; i < c->chunk_item->num_stripes; i++) {
3707 c->devices[i] = find_device_from_uuid(Vcb, &cis[i].dev_uuid);
3708 TRACE("device %u = %p\n", i, c->devices[i]);
3709
3710 if (!c->devices[i]) {
3711 ERR("missing device\n");
3712 ExFreePool(c->chunk_item);
3713 ExFreePool(c);
3714 return STATUS_INTERNAL_ERROR;
3715 }
3716
3717 if (c->devices[i]->readonly)
3718 c->readonly = true;
3719 }
3720 } else {
3721 ERR("chunk %I64x: number of stripes is 0\n", c->offset);
3722 ExFreePool(c->chunk_item);
3723 ExFreePool(c);
3724 return STATUS_INTERNAL_ERROR;
3725 }
3726
3728 ExInitializeResourceLite(&c->changed_extents_lock);
3729
3730 InitializeListHead(&c->space);
3731 InitializeListHead(&c->space_size);
3732 InitializeListHead(&c->deleting);
3733 InitializeListHead(&c->changed_extents);
3734
3735 InitializeListHead(&c->range_locks);
3736 ExInitializeResourceLite(&c->range_locks_lock);
3737 KeInitializeEvent(&c->range_locks_event, NotificationEvent, false);
3738
3739 InitializeListHead(&c->partial_stripes);
3740 ExInitializeResourceLite(&c->partial_stripes_lock);
3741
3742 c->last_alloc_set = false;
3743
3744 c->last_stripe = 0;
3745
3746 InsertTailList(&Vcb->chunks, &c->list_entry);
3747
3748 c->list_entry_balance.Flink = NULL;
3749 }
3750 }
3751
3752 b = find_next_item(Vcb, &tp, &next_tp, false, Irp);
3753
3754 if (b)
3755 tp = next_tp;
3756 } while (b);
3757
3758 Vcb->log_to_phys_loaded = true;
3759
3760 if (Vcb->data_flags == 0)
3761 Vcb->data_flags = BLOCK_FLAG_DATA | (Vcb->superblock.num_devices > 1 ? BLOCK_FLAG_RAID0 : 0);
3762
3763 if (Vcb->metadata_flags == 0)
3764 Vcb->metadata_flags = BLOCK_FLAG_METADATA | (Vcb->superblock.num_devices > 1 ? BLOCK_FLAG_RAID1 : BLOCK_FLAG_DUPLICATE);
3765
3766 if (Vcb->system_flags == 0)
3767 Vcb->system_flags = BLOCK_FLAG_SYSTEM | (Vcb->superblock.num_devices > 1 ? BLOCK_FLAG_RAID1 : BLOCK_FLAG_DUPLICATE);
3768
3769 if (Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS) {
3770 Vcb->metadata_flags |= BLOCK_FLAG_DATA;
3771 Vcb->data_flags = Vcb->metadata_flags;
3772 }
3773
3774 return STATUS_SUCCESS;
3775}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
void init_device(_In_ device_extension *Vcb, _Inout_ device *dev, _In_ bool get_nums)
Definition: btrfs.c:3416
_Ret_maybenull_ device * find_device_from_uuid(_In_ device_extension *Vcb, _In_ BTRFS_UUID *uuid)
Definition: btrfs.c:3299
#define TYPE_DEV_ITEM
Definition: btrfs.h:47
#define TYPE_CHUNK_ITEM
Definition: btrfs.h:48
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define BLOCK_FLAG_DATA
Definition: shellext.h:75
#define BLOCK_FLAG_SYSTEM
Definition: shellext.h:76
#define BLOCK_FLAG_RAID0
Definition: shellext.h:78
#define BLOCK_FLAG_METADATA
Definition: shellext.h:77
BTRFS_UUID device_uuid
Definition: btrfs.h:190

Referenced by mount_vol().

◆ load_sys_chunks()

static NTSTATUS load_sys_chunks ( _In_ device_extension Vcb)
static

Definition at line 3923 of file btrfs.c.

3923 {
3924 KEY key;
3925 ULONG n = Vcb->superblock.n;
3926
3927 while (n > 0) {
3928 if (n > sizeof(KEY)) {
3929 RtlCopyMemory(&key, &Vcb->superblock.sys_chunk_array[Vcb->superblock.n - n], sizeof(KEY));
3930 n -= sizeof(KEY);
3931 } else
3932 return STATUS_SUCCESS;
3933
3934 TRACE("bootstrap: %I64x,%x,%I64x\n", key.obj_id, key.obj_type, key.offset);
3935
3936 if (key.obj_type == TYPE_CHUNK_ITEM) {
3937 CHUNK_ITEM* ci;
3938 USHORT cisize;
3939 sys_chunk* sc;
3940
3941 if (n < sizeof(CHUNK_ITEM))
3942 return STATUS_SUCCESS;
3943
3944 ci = (CHUNK_ITEM*)&Vcb->superblock.sys_chunk_array[Vcb->superblock.n - n];
3945 cisize = sizeof(CHUNK_ITEM) + (ci->num_stripes * sizeof(CHUNK_ITEM_STRIPE));
3946
3947 if (n < cisize)
3948 return STATUS_SUCCESS;
3949
3951
3952 if (!sc) {
3953 ERR("out of memory\n");
3955 }
3956
3957 sc->key = key;
3958 sc->size = cisize;
3960
3961 if (!sc->data) {
3962 ERR("out of memory\n");
3963 ExFreePool(sc);
3965 }
3966
3967 RtlCopyMemory(sc->data, ci, sc->size);
3968 InsertTailList(&Vcb->sys_chunks, &sc->list_entry);
3969
3970 n -= cisize;
3971 } else {
3972 ERR("unexpected item %I64x,%x,%I64x in bootstrap\n", key.obj_id, key.obj_type, key.offset);
3973 return STATUS_INTERNAL_ERROR;
3974 }
3975 }
3976
3977 return STATUS_SUCCESS;
3978}
GLdouble n
Definition: glext.h:7729
#define KEY
Definition: profile.c:30
uint16_t num_stripes
Definition: btrfs.h:347
Definition: copy.c:22
LIST_ENTRY list_entry
Definition: btrfs_drv.h:624
USHORT size
Definition: btrfs_drv.h:623
void * data
Definition: btrfs_drv.h:622

Referenced by mount_vol().

◆ log_device_error()

void log_device_error ( _In_ device_extension Vcb,
_Inout_ device dev,
_In_ int  error 
)

◆ look_for_roots()

static NTSTATUS look_for_roots ( _Requires_exclusive_lock_held_(_Curr_->tree_lock) _In_ device_extension Vcb,
_In_opt_ PIRP  Irp 
)
static

Definition at line 3083 of file btrfs.c.

3083 {
3084 traverse_ptr tp, next_tp;
3085 KEY searchkey;
3086 bool b;
3088
3089 searchkey.obj_id = 0;
3090 searchkey.obj_type = 0;
3091 searchkey.offset = 0;
3092
3093 Status = find_item(Vcb, Vcb->root_root, &tp, &searchkey, false, Irp);
3094 if (!NT_SUCCESS(Status)) {
3095 ERR("error - find_item returned %08lx\n", Status);
3096 return Status;
3097 }
3098
3099 do {
3100 TRACE("(%I64x,%x,%I64x)\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset);
3101
3102 if (tp.item->key.obj_type == TYPE_ROOT_ITEM) {
3103 ROOT_ITEM* ri = (ROOT_ITEM*)tp.item->data;
3104
3105 if (tp.item->size < offsetof(ROOT_ITEM, byte_limit)) {
3106 ERR("(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", tp.item->key.obj_id, tp.item->key.obj_type, tp.item->key.offset, tp.item->size, offsetof(ROOT_ITEM, byte_limit));
3107 } else {
3108 TRACE("root %I64x - address %I64x\n", tp.item->key.obj_id, ri->block_number);
3109
3111 if (!NT_SUCCESS(Status)) {
3112 ERR("add_root returned %08lx\n", Status);
3113 return Status;
3114 }
3115 }
3116 } else if (tp.item->key.obj_type == TYPE_ROOT_BACKREF && !IsListEmpty(&Vcb->roots)) {
3117 root* lastroot = CONTAINING_RECORD(Vcb->roots.Blink, root, list_entry);
3118
3119 if (lastroot->id == tp.item->key.obj_id)
3120 lastroot->parent = tp.item->key.offset;
3121 }
3122
3123 b = find_next_item(Vcb, &tp, &next_tp, false, Irp);
3124
3125 if (b)
3126 tp = next_tp;
3127 } while (b);
3128
3129 if (!Vcb->readonly && !Vcb->data_reloc_root) {
3131 INODE_ITEM* ii;
3132 uint16_t irlen;
3133 INODE_REF* ir;
3136
3137 WARN("data reloc root doesn't exist, creating it\n");
3138
3140
3141 if (!NT_SUCCESS(Status)) {
3142 ERR("create_root returned %08lx\n", Status);
3143 return Status;
3144 }
3145
3146 reloc_root->root_item.inode.generation = 1;
3147 reloc_root->root_item.inode.st_size = 3;
3148 reloc_root->root_item.inode.st_blocks = Vcb->superblock.node_size;
3149 reloc_root->root_item.inode.st_nlink = 1;
3150 reloc_root->root_item.inode.st_mode = 040755;
3151 reloc_root->root_item.inode.flags = 0x80000000;
3152 reloc_root->root_item.inode.flags_ro = 0xffffffff;
3153 reloc_root->root_item.objid = SUBVOL_ROOT_INODE;
3154 reloc_root->root_item.bytes_used = Vcb->superblock.node_size;
3155
3157 if (!ii) {
3158 ERR("out of memory\n");
3160 }
3161
3164
3165 RtlZeroMemory(ii, sizeof(INODE_ITEM));
3166 ii->generation = Vcb->superblock.generation;
3167 ii->st_blocks = Vcb->superblock.node_size;
3168 ii->st_nlink = 1;
3169 ii->st_mode = 040755;
3170 ii->st_atime = now;
3171 ii->st_ctime = now;
3172 ii->st_mtime = now;
3173
3175 if (!NT_SUCCESS(Status)) {
3176 ERR("insert_tree_item returned %08lx\n", Status);
3177 ExFreePool(ii);
3178 return Status;
3179 }
3180
3181 irlen = (uint16_t)offsetof(INODE_REF, name[0]) + 2;
3183 if (!ir) {
3184 ERR("out of memory\n");
3186 }
3187
3188 ir->index = 0;
3189 ir->n = 2;
3190 ir->name[0] = '.';
3191 ir->name[1] = '.';
3192
3194 if (!NT_SUCCESS(Status)) {
3195 ERR("insert_tree_item returned %08lx\n", Status);
3196 ExFreePool(ir);
3197 return Status;
3198 }
3199
3200 Vcb->data_reloc_root = reloc_root;
3201 Vcb->need_write = true;
3202 }
3203
3204 return STATUS_SUCCESS;
3205}
static btrfs_root * add_root(LIST_ENTRY *roots, uint64_t id)
Definition: btrfslib.c:284
NTSTATUS create_root(_In_ _Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ uint64_t id, _Out_ root **rootptr, _In_ bool no_tree, _In_ uint64_t offset, _In_opt_ PIRP Irp)
Definition: btrfs.c:1271
#define BTRFS_ROOT_DATA_RELOC
Definition: btrfs.h:63
#define TYPE_ROOT_BACKREF
Definition: btrfs.h:33
#define TYPE_INODE_REF
Definition: btrfs.h:24
char * reloc_root
Definition: mkisofs.c:177
#define uint16_t
Definition: nsiface.idl:60
uint32_t st_mode
Definition: btrfs.h:295
BTRFS_TIME st_mtime
Definition: btrfs.h:303
BTRFS_TIME st_atime
Definition: btrfs.h:301
uint64_t st_blocks
Definition: btrfs.h:290
BTRFS_TIME st_ctime
Definition: btrfs.h:302
uint64_t generation
Definition: btrfs.h:287
uint64_t index
Definition: btrfs.h:375
char name[1]
Definition: btrfs.h:377
uint16_t n
Definition: btrfs.h:376
uint64_t block_number
Definition: btrfs.h:315
uint64_t generation
Definition: btrfs.h:313
uint64_t id
Definition: btrfs_drv.h:451
uint64_t parent
Definition: btrfs_drv.h:459

Referenced by mount_vol().

◆ mark_fcb_dirty()

void mark_fcb_dirty ( _In_ fcb fcb)

Definition at line 1695 of file btrfs.c.

1695 {
1696 if (!fcb->dirty) {
1697#ifdef DEBUG_FCB_REFCOUNTS
1698 LONG rc;
1699#endif
1700 fcb->dirty = true;
1701
1702#ifdef DEBUG_FCB_REFCOUNTS
1704 WARN("fcb %p: refcount now %i\n", fcb, rc);
1705#else
1707#endif
1708
1709 ExAcquireResourceExclusiveLite(&fcb->Vcb->dirty_fcbs_lock, true);
1710 InsertTailList(&fcb->Vcb->dirty_fcbs, &fcb->list_entry_dirty);
1711 ExReleaseResourceLite(&fcb->Vcb->dirty_fcbs_lock);
1712 }
1713
1714 fcb->Vcb->need_write = true;
1715}
bool dirty
Definition: btrfs_drv.h:320
LIST_ENTRY list_entry_dirty
Definition: btrfs_drv.h:338

Referenced by __attribute__(), _Dispatch_type_(), check_for_orphans_root(), create_directory_fcb(), create_stream(), create_subvol(), delete_fileref(), delete_fileref_fcb(), delete_reparse_point(), do_create_snapshot(), duplicate_extents(), file_create2(), fsctl_set_xattr(), insert_extent_chunk(), load_stored_free_space_cache(), mknod(), move_across_subvols(), open_file3(), remove_free_space_inode(), rename_file_to_stream(), rename_stream(), rename_stream_to_file(), set_basic_information(), set_case_sensitive_information(), set_end_of_file_information(), set_file_security(), set_inode_info(), set_link_information(), set_rename_information(), set_reparse_point2(), set_sparse(), set_symlink(), set_valid_data_length_information(), set_zero_data(), stream_set_end_of_file_information(), and write_compressed().

◆ mark_fileref_dirty()

void mark_fileref_dirty ( _In_ file_ref fileref)

Definition at line 1717 of file btrfs.c.

1717 {
1718 if (!fileref->dirty) {
1719 fileref->dirty = true;
1721
1722 ExAcquireResourceExclusiveLite(&fileref->fcb->Vcb->dirty_filerefs_lock, true);
1723 InsertTailList(&fileref->fcb->Vcb->dirty_filerefs, &fileref->list_entry_dirty);
1724 ExReleaseResourceLite(&fileref->fcb->Vcb->dirty_filerefs_lock);
1725 }
1726
1727 fileref->fcb->Vcb->need_write = true;
1728}
#define increase_fileref_refcount(fileref)
Definition: btrfs_drv.h:1739

Referenced by __attribute__(), create_stream(), create_subvol(), delete_fileref(), delete_reparse_point(), do_create_snapshot(), file_create2(), mknod(), move_across_subvols(), rename_file_to_stream(), rename_stream_to_file(), set_link_information(), set_rename_information(), and set_symlink().

◆ mount_vol()

static NTSTATUS mount_vol ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)
static

Definition at line 4375 of file btrfs.c.

4375 {
4377 PDEVICE_OBJECT NewDeviceObject = NULL;
4378 PDEVICE_OBJECT DeviceToMount, readobj;
4379 PFILE_OBJECT fileobj;
4382 LIST_ENTRY *le, batchlist;
4383 KEY searchkey;
4385 fcb* root_fcb = NULL;
4386 ccb* root_ccb = NULL;
4387 bool init_lookaside = false;
4388 device* dev;
4390 pdo_device_extension* pdode = NULL;
4391 volume_child* vc;
4392 uint64_t readobjsize;
4394 device_extension* real_devext;
4395 KIRQL irql;
4396
4397 TRACE("(%p, %p)\n", DeviceObject, Irp);
4398
4401
4403 DeviceToMount = IrpSp->Parameters.MountVolume.DeviceObject;
4404
4405 real_devext = IrpSp->Parameters.MountVolume.Vpb->RealDevice->DeviceExtension;
4406
4407 // Make sure we're not trying to mount the PDO
4408 if (IrpSp->Parameters.MountVolume.Vpb->RealDevice->DriverObject == drvobj && real_devext->type == VCB_TYPE_PDO)
4410
4411 if (!is_btrfs_volume(DeviceToMount)) {
4412 bool not_pnp = false;
4413
4414 Status = check_mount_device(DeviceToMount, &not_pnp);
4415 if (!NT_SUCCESS(Status))
4416 WARN("check_mount_device returned %08lx\n", Status);
4417
4418 if (!not_pnp) {
4420 goto exit;
4421 }
4422 } else {
4423 PDEVICE_OBJECT pdo;
4424
4425 pdo = DeviceToMount;
4426
4427 ObReferenceObject(pdo);
4428
4429 while (true) {
4431
4433
4434 if (!pdo2)
4435 break;
4436 else
4437 pdo = pdo2;
4438 }
4439
4441
4442 le = pdo_list.Flink;
4443 while (le != &pdo_list) {
4445
4446 if (pdode2->pdo == pdo) {
4447 vde = pdode2->vde;
4448 break;
4449 }
4450
4451 le = le->Flink;
4452 }
4453
4455
4456 if (!vde || vde->type != VCB_TYPE_VOLUME) {
4457 vde = NULL;
4459 goto exit;
4460 }
4461 }
4462
4463 if (vde) {
4464 pdode = vde->pdode;
4465
4467
4468 le = pdode->children.Flink;
4469 while (le != &pdode->children) {
4470 LIST_ENTRY* le2 = le->Flink;
4471
4473
4474 if (!still_has_superblock(vc->devobj, vc->fileobj)) {
4475 remove_volume_child(vde, vc, false);
4476
4477 if (pdode->num_children == 0) {
4478 ERR("error - number of devices is zero\n");
4481 goto exit;
4482 }
4483
4486 goto exit;
4487 }
4488
4489 le = le2;
4490 }
4491
4492 if (pdode->num_children == 0 || pdode->children_loaded == 0) {
4493 ERR("error - number of devices is zero\n");
4496 goto exit;
4497 }
4498
4500
4502
4503 readobj = vc->devobj;
4504 fileobj = vc->fileobj;
4505 readobjsize = vc->size;
4506
4507 vde->device->Characteristics &= ~FILE_DEVICE_SECURE_OPEN;
4508 } else {
4510
4511 vc = NULL;
4512 readobj = DeviceToMount;
4513 fileobj = NULL;
4514
4516 &gli, sizeof(gli), true, NULL);
4517
4518 if (!NT_SUCCESS(Status)) {
4519 ERR("error reading length information: %08lx\n", Status);
4520 goto exit;
4521 }
4522
4523 readobjsize = gli.Length.QuadPart;
4524 }
4525
4526 Status = IoCreateDevice(drvobj, sizeof(device_extension), NULL, FILE_DEVICE_DISK_FILE_SYSTEM, 0, false, &NewDeviceObject);
4527 if (!NT_SUCCESS(Status)) {
4528 ERR("IoCreateDevice returned %08lx\n", Status);
4530
4531 if (pdode)
4533
4534 goto exit;
4535 }
4536
4537 NewDeviceObject->Flags |= DO_DIRECT_IO;
4538
4539 // Some programs seem to expect that the sector size will be 512, for
4540 // FILE_NO_INTERMEDIATE_BUFFERING and the like.
4541 NewDeviceObject->SectorSize = min(DeviceToMount->SectorSize, 512);
4542
4543 Vcb = (PVOID)NewDeviceObject->DeviceExtension;
4545 Vcb->type = VCB_TYPE_FS;
4546 Vcb->vde = vde;
4547
4548 ExInitializeResourceLite(&Vcb->tree_lock);
4549 Vcb->need_write = false;
4550
4551 ExInitializeResourceLite(&Vcb->fcb_lock);
4552 ExInitializeResourceLite(&Vcb->fileref_lock);
4553 ExInitializeResourceLite(&Vcb->chunk_lock);
4554 ExInitializeResourceLite(&Vcb->dirty_fcbs_lock);
4555 ExInitializeResourceLite(&Vcb->dirty_filerefs_lock);
4556 ExInitializeResourceLite(&Vcb->dirty_subvols_lock);
4557 ExInitializeResourceLite(&Vcb->scrub.stats_lock);
4558
4559 ExInitializeResourceLite(&Vcb->load_lock);
4560 ExAcquireResourceExclusiveLite(&Vcb->load_lock, true);
4561
4562 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
4563
4564 DeviceToMount->Flags |= DO_DIRECT_IO;
4565
4566 Status = read_superblock(Vcb, readobj, fileobj, readobjsize);
4567 if (!NT_SUCCESS(Status)) {
4570 else if (Irp->Tail.Overlay.Thread)
4572
4573 if (pdode)
4575
4576 goto exit;
4577 }
4578
4579 if (!vde && Vcb->superblock.num_devices > 1) {
4580 ERR("cannot mount multi-device FS with non-PNP device\n");
4582
4583 if (pdode)
4585
4586 goto exit;
4587 }
4588
4590 if (!NT_SUCCESS(Status)) {
4591 ERR("registry_load_volume_options returned %08lx\n", Status);
4592
4593 if (pdode)
4595
4596 goto exit;
4597 }
4598
4599 if (pdode && RtlCompareMemory(&boot_uuid, &pdode->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID) && boot_subvol != 0)
4600 Vcb->options.subvol_id = boot_subvol;
4601
4602 if (pdode && pdode->children_loaded < pdode->num_children && (!Vcb->options.allow_degraded || !finished_probing || degraded_wait)) {
4603 ERR("could not mount as %I64u device(s) missing\n", pdode->num_children - pdode->children_loaded);
4606 goto exit;
4607 }
4608
4609 if (pdode) {
4610 // Windows holds DeviceObject->DeviceLock, guaranteeing that mount_vol is serialized
4612 }
4613
4614 if (Vcb->options.ignore) {
4615 TRACE("ignoring volume\n");
4617 goto exit;
4618 }
4619
4620 if (Vcb->superblock.incompat_flags & ~INCOMPAT_SUPPORTED) {
4621 WARN("cannot mount because of unsupported incompat flags (%I64x)\n", Vcb->superblock.incompat_flags & ~INCOMPAT_SUPPORTED);
4623 goto exit;
4624 }
4625
4626 if (!(Vcb->superblock.incompat_flags & BTRFS_INCOMPAT_FLAGS_METADATA_UUID))
4627 Vcb->superblock.metadata_uuid = Vcb->superblock.uuid;
4628
4629 Vcb->readonly = false;
4630 if (Vcb->superblock.compat_ro_flags & ~COMPAT_RO_SUPPORTED) {
4631 WARN("mounting read-only because of unsupported flags (%I64x)\n", Vcb->superblock.compat_ro_flags & ~COMPAT_RO_SUPPORTED);
4632 Vcb->readonly = true;
4633 }
4634
4635 if (Vcb->options.readonly)
4636 Vcb->readonly = true;
4637
4639
4640 Vcb->superblock.generation++;
4641 Vcb->superblock.incompat_flags |= BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF;
4642
4643 if (Vcb->superblock.log_tree_addr != 0) {
4644 FIXME("FIXME - replay transaction log (clearing for now)\n");
4645 Vcb->superblock.log_tree_addr = 0;
4646 }
4647
4648 switch (Vcb->superblock.csum_type) {
4649 case CSUM_TYPE_CRC32C:
4650 Vcb->csum_size = sizeof(uint32_t);
4651 break;
4652
4653 case CSUM_TYPE_XXHASH:
4654 Vcb->csum_size = sizeof(uint64_t);
4655 break;
4656
4657 case CSUM_TYPE_SHA256:
4658 Vcb->csum_size = SHA256_HASH_SIZE;
4659 break;
4660
4661 case CSUM_TYPE_BLAKE2:
4662 Vcb->csum_size = BLAKE2_HASH_SIZE;
4663 break;
4664
4665 default:
4666 ERR("unrecognized csum type %x\n", Vcb->superblock.csum_type);
4667 break;
4668 }
4669
4670 InitializeListHead(&Vcb->devices);
4672 if (!dev) {
4673 ERR("out of memory\n");
4675 goto exit;
4676 }
4677
4678 dev->devobj = readobj;
4679 dev->fileobj = fileobj;
4680 RtlCopyMemory(&dev->devitem, &Vcb->superblock.dev_item, sizeof(DEV_ITEM));
4681
4682 if (dev->devitem.num_bytes > readobjsize) {
4683 WARN("device %I64x: DEV_ITEM says %I64x bytes, but Windows only reports %I64x\n", dev->devitem.dev_id,
4684 dev->devitem.num_bytes, readobjsize);
4685
4686 dev->devitem.num_bytes = readobjsize;
4687 }
4688
4689 dev->seeding = Vcb->superblock.flags & BTRFS_SUPERBLOCK_FLAGS_SEEDING ? true : false;
4690
4691 init_device(Vcb, dev, true);
4692
4693 InsertTailList(&Vcb->devices, &dev->list_entry);
4694 Vcb->devices_loaded = 1;
4695
4696 if (DeviceToMount->Flags & DO_SYSTEM_BOOT_PARTITION)
4697 Vcb->disallow_dismount = true;
4698
4699 TRACE("DeviceToMount = %p\n", DeviceToMount);
4700 TRACE("IrpSp->Parameters.MountVolume.Vpb = %p\n", IrpSp->Parameters.MountVolume.Vpb);
4701
4702 NewDeviceObject->StackSize = DeviceToMount->StackSize + 1;
4703 NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
4704
4705 InitializeListHead(&Vcb->roots);
4706 InitializeListHead(&Vcb->drop_roots);
4707
4708 Vcb->log_to_phys_loaded = false;
4709
4710 add_root(Vcb, BTRFS_ROOT_CHUNK, Vcb->superblock.chunk_tree_addr, Vcb->superblock.chunk_root_generation, NULL);
4711
4712 if (!Vcb->chunk_root) {
4713 ERR("Could not load chunk root.\n");
4715 goto exit;
4716 }
4717
4718 InitializeListHead(&Vcb->sys_chunks);
4720 if (!NT_SUCCESS(Status)) {
4721 ERR("load_sys_chunks returned %08lx\n", Status);
4722 goto exit;
4723 }
4724
4725 InitializeListHead(&Vcb->chunks);
4726 InitializeListHead(&Vcb->trees);
4727 InitializeListHead(&Vcb->trees_hash);
4728 InitializeListHead(&Vcb->all_fcbs);
4729 InitializeListHead(&Vcb->dirty_fcbs);
4730 InitializeListHead(&Vcb->dirty_filerefs);
4731 InitializeListHead(&Vcb->dirty_subvols);
4732 InitializeListHead(&Vcb->send_ops);
4733
4734 ExInitializeFastMutex(&Vcb->trees_list_mutex);
4735
4736 InitializeListHead(&Vcb->DirNotifyList);
4737 InitializeListHead(&Vcb->scrub.errors);
4738
4739 FsRtlNotifyInitializeSync(&Vcb->NotifySync);
4740
4741 ExInitializePagedLookasideList(&Vcb->tree_data_lookaside, NULL, NULL, 0, sizeof(tree_data), ALLOC_TAG, 0);
4742 ExInitializePagedLookasideList(&Vcb->traverse_ptr_lookaside, NULL, NULL, 0, sizeof(traverse_ptr), ALLOC_TAG, 0);
4743 ExInitializePagedLookasideList(&Vcb->batch_item_lookaside, NULL, NULL, 0, sizeof(batch_item), ALLOC_TAG, 0);
4744 ExInitializePagedLookasideList(&Vcb->fileref_lookaside, NULL, NULL, 0, sizeof(file_ref), ALLOC_TAG, 0);
4745 ExInitializePagedLookasideList(&Vcb->fcb_lookaside, NULL, NULL, 0, sizeof(fcb), ALLOC_TAG, 0);
4746 ExInitializePagedLookasideList(&Vcb->name_bit_lookaside, NULL, NULL, 0, sizeof(name_bit), ALLOC_TAG, 0);
4747 ExInitializeNPagedLookasideList(&Vcb->range_lock_lookaside, NULL, NULL, 0, sizeof(range_lock), ALLOC_TAG, 0);
4748 ExInitializeNPagedLookasideList(&Vcb->fcb_np_lookaside, NULL, NULL, 0, sizeof(fcb_nonpaged), ALLOC_TAG, 0);
4749 init_lookaside = true;
4750
4751 Vcb->Vpb = IrpSp->Parameters.MountVolume.Vpb;
4752
4754 if (!NT_SUCCESS(Status)) {
4755 ERR("load_chunk_root returned %08lx\n", Status);
4756 goto exit;
4757 }
4758
4759 if (Vcb->superblock.num_devices > 1) {
4760 if (Vcb->devices_loaded < Vcb->superblock.num_devices && (!Vcb->options.allow_degraded || !finished_probing)) {
4761 ERR("could not mount as %I64u device(s) missing\n", Vcb->superblock.num_devices - Vcb->devices_loaded);
4762
4764
4766 goto exit;
4767 }
4768
4769 if (dev->readonly && !Vcb->readonly) {
4770 Vcb->readonly = true;
4771
4772 le = Vcb->devices.Flink;
4773 while (le != &Vcb->devices) {
4775
4776 if (dev2->readonly && !dev2->seeding)
4777 break;
4778
4779 if (!dev2->readonly) {
4780 Vcb->readonly = false;
4781 break;
4782 }
4783
4784 le = le->Flink;
4785 }
4786
4787 if (Vcb->readonly)
4788 WARN("setting volume to readonly\n");
4789 }
4790 } else {
4791 if (dev->readonly) {
4792 WARN("setting volume to readonly as device is readonly\n");
4793 Vcb->readonly = true;
4794 }
4795 }
4796
4797 add_root(Vcb, BTRFS_ROOT_ROOT, Vcb->superblock.root_tree_addr, Vcb->superblock.generation - 1, NULL);
4798
4799 if (!Vcb->root_root) {
4800 ERR("Could not load root of roots.\n");
4802 goto exit;
4803 }
4804
4806 if (!NT_SUCCESS(Status)) {
4807 ERR("look_for_roots returned %08lx\n", Status);
4808 goto exit;
4809 }
4810
4811 if (!Vcb->readonly) {
4813 if (!NT_SUCCESS(Status)) {
4814 ERR("find_chunk_usage returned %08lx\n", Status);
4815 goto exit;
4816 }
4817 }
4818
4819 InitializeListHead(&batchlist);
4820
4821 // We've already increased the generation by one
4822 if (!Vcb->readonly && (
4823 Vcb->options.clear_cache ||
4824 (!(Vcb->superblock.compat_ro_flags & BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE) && Vcb->superblock.generation - 1 != Vcb->superblock.cache_generation) ||
4825 (Vcb->superblock.compat_ro_flags & BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE && !(Vcb->superblock.compat_ro_flags & BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE_VALID)))) {
4826 if (Vcb->options.clear_cache)
4827 WARN("ClearCache option was set, clearing cache...\n");
4828 else if (Vcb->superblock.compat_ro_flags & BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE && !(Vcb->superblock.compat_ro_flags & BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE_VALID))
4829 WARN("clearing free-space tree created by buggy Linux driver\n");
4830 else
4831 WARN("generation was %I64x, free-space cache generation was %I64x; clearing cache...\n", Vcb->superblock.generation - 1, Vcb->superblock.cache_generation);
4832
4833 Status = clear_free_space_cache(Vcb, &batchlist, Irp);
4834 if (!NT_SUCCESS(Status)) {
4835 ERR("clear_free_space_cache returned %08lx\n", Status);
4836 clear_batch_list(Vcb, &batchlist);
4837 goto exit;
4838 }
4839 }
4840
4841 Status = commit_batch_list(Vcb, &batchlist, Irp);
4842 if (!NT_SUCCESS(Status)) {
4843 ERR("commit_batch_list returned %08lx\n", Status);
4844 goto exit;
4845 }
4846
4847 Vcb->volume_fcb = create_fcb(Vcb, NonPagedPool);
4848 if (!Vcb->volume_fcb) {
4849 ERR("out of memory\n");
4851 goto exit;
4852 }
4853
4854 Vcb->volume_fcb->Vcb = Vcb;
4855 Vcb->volume_fcb->sd = NULL;
4856
4857 Vcb->dummy_fcb = create_fcb(Vcb, NonPagedPool);
4858 if (!Vcb->dummy_fcb) {
4859 ERR("out of memory\n");
4861 goto exit;
4862 }
4863
4864 Vcb->dummy_fcb->Vcb = Vcb;
4865 Vcb->dummy_fcb->type = BTRFS_TYPE_DIRECTORY;
4866 Vcb->dummy_fcb->inode = 2;
4867 Vcb->dummy_fcb->subvol = Vcb->root_root;
4868 Vcb->dummy_fcb->atts = FILE_ATTRIBUTE_DIRECTORY;
4869 Vcb->dummy_fcb->inode_item.st_nlink = 1;
4870 Vcb->dummy_fcb->inode_item.st_mode = __S_IFDIR;
4871
4872 Vcb->dummy_fcb->hash_ptrs = ExAllocatePoolWithTag(PagedPool, sizeof(LIST_ENTRY*) * 256, ALLOC_TAG);
4873 if (!Vcb->dummy_fcb->hash_ptrs) {
4874 ERR("out of memory\n");
4876 goto exit;
4877 }
4878
4879 RtlZeroMemory(Vcb->dummy_fcb->hash_ptrs, sizeof(LIST_ENTRY*) * 256);
4880
4881 Vcb->dummy_fcb->hash_ptrs_uc = ExAllocatePoolWithTag(PagedPool, sizeof(LIST_ENTRY*) * 256, ALLOC_TAG);
4882 if (!Vcb->dummy_fcb->hash_ptrs_uc) {
4883 ERR("out of memory\n");
4885 goto exit;
4886 }
4887
4888 RtlZeroMemory(Vcb->dummy_fcb->hash_ptrs_uc, sizeof(LIST_ENTRY*) * 256);
4889
4890 root_fcb = create_fcb(Vcb, NonPagedPool);
4891 if (!root_fcb) {
4892 ERR("out of memory\n");
4894 goto exit;
4895 }
4896
4897 root_fcb->Vcb = Vcb;
4898 root_fcb->inode = SUBVOL_ROOT_INODE;
4899 root_fcb->hash = calc_crc32c(0xffffffff, (uint8_t*)&root_fcb->inode, sizeof(uint64_t));
4900 root_fcb->type = BTRFS_TYPE_DIRECTORY;
4901
4902#ifdef DEBUG_FCB_REFCOUNTS
4903 WARN("volume FCB = %p\n", Vcb->volume_fcb);
4904 WARN("root FCB = %p\n", root_fcb);
4905#endif
4906
4907 root_fcb->subvol = find_default_subvol(Vcb, Irp);
4908
4909 if (!root_fcb->subvol) {
4910 ERR("could not find top subvol\n");
4912 goto exit;
4913 }
4914
4915 Status = load_dir_children(Vcb, root_fcb, true, Irp);
4916 if (!NT_SUCCESS(Status)) {
4917 ERR("load_dir_children returned %08lx\n", Status);
4918 goto exit;
4919 }
4920
4921 searchkey.obj_id = root_fcb->inode;
4922 searchkey.obj_type = TYPE_INODE_ITEM;
4923 searchkey.offset = 0xffffffffffffffff;
4924
4925 Status = find_item(Vcb, root_fcb->subvol, &tp, &searchkey, false, Irp);
4926 if (!NT_SUCCESS(Status)) {
4927 ERR("error - find_item returned %08lx\n", Status);
4928 goto exit;
4929 }
4930
4931 if (tp.item->key.obj_id != searchkey.obj_id || tp.item->key.obj_type != searchkey.obj_type) {
4932 ERR("couldn't find INODE_ITEM for root directory\n");
4934 goto exit;
4935 }
4936
4937 if (tp.item->size > 0)
4938 RtlCopyMemory(&root_fcb->inode_item, tp.item->data, min(sizeof(INODE_ITEM), tp.item->size));
4939
4940 fcb_get_sd(root_fcb, NULL, true, Irp);
4941
4942 root_fcb->atts = get_file_attributes(Vcb, root_fcb->subvol, root_fcb->inode, root_fcb->type, false, false, Irp);
4943
4944 if (root_fcb->subvol->id == BTRFS_ROOT_FSTREE)
4945 root_fcb->atts &= ~FILE_ATTRIBUTE_HIDDEN;
4946
4947 Vcb->root_fileref = create_fileref(Vcb);
4948 if (!Vcb->root_fileref) {
4949 ERR("out of memory\n");
4951 goto exit;
4952 }
4953
4954 Vcb->root_fileref->fcb = root_fcb;
4955 InsertTailList(&root_fcb->subvol->fcbs, &root_fcb->list_entry);
4956 InsertTailList(&Vcb->all_fcbs, &root_fcb->list_entry_all);
4957
4958 root_fcb->subvol->fcbs_ptrs[root_fcb->hash >> 24] = &root_fcb->list_entry;
4959
4960 root_fcb->fileref = Vcb->root_fileref;
4961
4962 root_ccb = ExAllocatePoolWithTag(PagedPool, sizeof(ccb), ALLOC_TAG);
4963 if (!root_ccb) {
4964 ERR("out of memory\n");
4966 goto exit;
4967 }
4968
4969 Vcb->root_file = IoCreateStreamFileObject(NULL, DeviceToMount);
4970 Vcb->root_file->FsContext = root_fcb;
4971 Vcb->root_file->SectionObjectPointer = &root_fcb->nonpaged->segment_object;
4972 Vcb->root_file->Vpb = DeviceObject->Vpb;
4973
4974 RtlZeroMemory(root_ccb, sizeof(ccb));
4975 root_ccb->NodeType = BTRFS_NODE_TYPE_CCB;
4976 root_ccb->NodeSize = sizeof(ccb);
4977
4978 Vcb->root_file->FsContext2 = root_ccb;
4979
4980 _SEH2_TRY {
4981 CcInitializeCacheMap(Vcb->root_file, (PCC_FILE_SIZES)(&root_fcb->Header.AllocationSize), false, &cache_callbacks, Vcb->root_file);
4984 goto exit;
4985 } _SEH2_END;
4986
4987 le = Vcb->devices.Flink;
4988 while (le != &Vcb->devices) {
4990
4991 Status = find_disk_holes(Vcb, dev2, Irp);
4992 if (!NT_SUCCESS(Status)) {
4993 ERR("find_disk_holes returned %08lx\n", Status);
4994 goto exit;
4995 }
4996
4997 le = le->Flink;
4998 }
4999
5001
5002 NewDeviceObject->Vpb = IrpSp->Parameters.MountVolume.Vpb;
5003 IrpSp->Parameters.MountVolume.Vpb->DeviceObject = NewDeviceObject;
5004 IrpSp->Parameters.MountVolume.Vpb->Flags |= VPB_MOUNTED;
5005 NewDeviceObject->Vpb->VolumeLabelLength = 4; // FIXME
5006 NewDeviceObject->Vpb->VolumeLabel[0] = '?';
5007 NewDeviceObject->Vpb->VolumeLabel[1] = 0;
5008 NewDeviceObject->Vpb->ReferenceCount++;
5009
5011
5012 KeInitializeEvent(&Vcb->flush_thread_finished, NotificationEvent, false);
5013
5015
5016 Status = PsCreateSystemThread(&Vcb->flush_thread_handle, 0, &oa, NULL, NULL, flush_thread, NewDeviceObject);
5017 if (!NT_SUCCESS(Status)) {
5018 ERR("PsCreateSystemThread returned %08lx\n", Status);
5019 goto exit;
5020 }
5021
5022 Status = create_calc_threads(NewDeviceObject);
5023 if (!NT_SUCCESS(Status)) {
5024 ERR("create_calc_threads returned %08lx\n", Status);
5025 goto exit;
5026 }
5027
5028 Status = registry_mark_volume_mounted(&Vcb->superblock.uuid);
5029 if (!NT_SUCCESS(Status))
5030 WARN("registry_mark_volume_mounted returned %08lx\n", Status);
5031
5034 WARN("look_for_balance_item returned %08lx\n", Status);
5035
5037
5038 if (vde)
5039 vde->mounted_device = NewDeviceObject;
5040
5041 Vcb->devobj = NewDeviceObject;
5042
5043 ExInitializeResourceLite(&Vcb->send_load_lock);
5044
5045exit:
5046 if (Vcb) {
5047 ExReleaseResourceLite(&Vcb->tree_lock);
5048 ExReleaseResourceLite(&Vcb->load_lock);
5049 }
5050
5051 if (!NT_SUCCESS(Status)) {
5052 if (Vcb) {
5053 if (init_lookaside) {
5054 ExDeletePagedLookasideList(&Vcb->tree_data_lookaside);
5055 ExDeletePagedLookasideList(&Vcb->traverse_ptr_lookaside);
5056 ExDeletePagedLookasideList(&Vcb->batch_item_lookaside);
5057 ExDeletePagedLookasideList(&Vcb->fileref_lookaside);
5058 ExDeletePagedLookasideList(&Vcb->fcb_lookaside);
5059 ExDeletePagedLookasideList(&Vcb->name_bit_lookaside);
5060 ExDeleteNPagedLookasideList(&Vcb->range_lock_lookaside);
5061 ExDeleteNPagedLookasideList(&Vcb->fcb_np_lookaside);
5062 }
5063
5064 if (Vcb->root_file)
5065 ObDereferenceObject(Vcb->root_file);
5066 else if (Vcb->root_fileref)
5067 free_fileref(Vcb->root_fileref);
5068 else if (root_fcb)
5069 free_fcb(root_fcb);
5070
5071 if (root_fcb && root_fcb->refcount == 0)
5072 reap_fcb(root_fcb);
5073
5074 if (Vcb->volume_fcb)
5075 reap_fcb(Vcb->volume_fcb);
5076
5077 ExDeleteResourceLite(&Vcb->tree_lock);
5078 ExDeleteResourceLite(&Vcb->load_lock);
5079 ExDeleteResourceLite(&Vcb->fcb_lock);
5080 ExDeleteResourceLite(&Vcb->fileref_lock);
5081 ExDeleteResourceLite(&Vcb->chunk_lock);
5082 ExDeleteResourceLite(&Vcb->dirty_fcbs_lock);
5083 ExDeleteResourceLite(&Vcb->dirty_filerefs_lock);
5084 ExDeleteResourceLite(&Vcb->dirty_subvols_lock);
5085 ExDeleteResourceLite(&Vcb->scrub.stats_lock);
5086
5087 if (Vcb->devices.Flink) {
5088 while (!IsListEmpty(&Vcb->devices)) {
5090
5091 ExFreePool(dev2);
5092 }
5093 }
5094 }
5095
5096 if (NewDeviceObject)
5097 IoDeleteDevice(NewDeviceObject);
5098 } else {
5100 InsertTailList(&VcbList, &Vcb->list_entry);
5102
5104 }
5105
5106 TRACE("mount_vol done (status: %lx)\n", Status);
5107
5108 return Status;
5109}
NTSTATUS registry_load_volume_options(device_extension *Vcb)
Definition: registry.c:36
void void void NTSTATUS commit_batch_list(_Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension *Vcb, LIST_ENTRY *batchlist, PIRP Irp) __attribute__((nonnull(1
#define __S_IFDIR
Definition: btrfs_drv.h:1754
void fcb_get_sd(fcb *fcb, struct _fcb *parent, bool look_for_xattr, PIRP Irp)
Definition: security.c:511
void void void NTSTATUS void clear_batch_list(device_extension *Vcb, LIST_ENTRY *batchlist) __attribute__((nonnull(1
#define VCB_TYPE_PDO
Definition: btrfs_drv.h:690
NTSTATUS clear_free_space_cache(device_extension *Vcb, LIST_ENTRY *batchlist, PIRP Irp)
Definition: free-space.c:59
void remove_volume_child(_Inout_ _Requires_exclusive_lock_held_(_Curr_->child_lock) _Releases_exclusive_lock_(_Curr_->child_lock) _In_ volume_device_extension *vde, _In_ volume_child *vc, _In_ bool skip_dev)
Definition: search.c:531
NTSTATUS registry_mark_volume_mounted(BTRFS_UUID *uuid)
Definition: registry.c:242
fcb * create_fcb(device_extension *Vcb, POOL_TYPE pool_type)
Definition: create.c:91
file_ref * create_fileref(device_extension *Vcb)
Definition: create.c:160
#define BTRFS_NODE_TYPE_CCB
Definition: btrfs_drv.h:84
NTSTATUS load_dir_children(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, fcb *fcb, bool ignore_size, PIRP Irp)
Definition: create.c:510
crc_func calc_crc32c
Definition: crc32c.c:23
NTSTATUS look_for_balance_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb)
Definition: balance.c:3628
static bool is_btrfs_volume(_In_ PDEVICE_OBJECT DeviceObject)
Definition: btrfs.c:4141
NTSTATUS find_chunk_usage(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_opt_ PIRP Irp)
Definition: btrfs.c:3876
static NTSTATUS look_for_roots(_Requires_exclusive_lock_held_(_Curr_->tree_lock) _In_ device_extension *Vcb, _In_opt_ PIRP Irp)
Definition: btrfs.c:3083
ULONG get_file_attributes(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ root *r, _In_ uint64_t inode, _In_ uint8_t type, _In_ bool dotfile, _In_ bool ignore_xa, _In_opt_ PIRP Irp)
Definition: btrfs.c:2664
uint64_t boot_subvol
Definition: boot.c:34
static NTSTATUS find_disk_holes(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_ device *dev, _In_opt_ PIRP Irp)
Definition: btrfs.c:3207
static NTSTATUS create_calc_threads(_In_ PDEVICE_OBJECT DeviceObject)
Definition: btrfs.c:4094
_Ret_maybenull_ root * find_default_subvol(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_opt_ PIRP Irp)
Definition: btrfs.c:3981
#define INCOMPAT_SUPPORTED
Definition: btrfs.c:53
static bool still_has_superblock(_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj)
Definition: btrfs.c:4313
static NTSTATUS load_chunk_root(_In_ _Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, _In_opt_ PIRP Irp)
Definition: btrfs.c:3513
static NTSTATUS read_superblock(_In_ device_extension *Vcb, _In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj, _In_ uint64_t length)
Definition: btrfs.c:2882
#define COMPAT_RO_SUPPORTED
Definition: btrfs.c:57
static void calculate_sector_shift(device_extension *Vcb)
Definition: btrfs.c:4364
void reap_fcb(fcb *fcb)
Definition: btrfs.c:1743
static NTSTATUS load_sys_chunks(_In_ device_extension *Vcb)
Definition: btrfs.c:3923
#define BTRFS_SUPERBLOCK_FLAGS_SEEDING
Definition: btrfs.h:128
#define BTRFS_ROOT_CHUNK
Definition: btrfs.h:56
#define ExConvertExclusiveToSharedLite(res)
Definition: env_spec_w32.h:652
VOID NTAPI ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:270
VOID NTAPI ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside)
Definition: lookas.c:194
VOID NTAPI ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside)
Definition: lookas.c:170
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define uint32_t
Definition: nsiface.idl:61
#define uint64_t
Definition: nsiface.idl:62
#define FSRTL_VOLUME_MOUNT
Definition: ntifs_ex.h:444
#define IO_ERR_INTERNAL_ERROR
Definition: ntiologc.h:39
VOID NTAPI FsRtlNotifyInitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1590
PDEVICE_OBJECT NTAPI IoGetLowerDeviceObject(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1507
BOOLEAN NTAPI IoRaiseInformationalHardError(IN NTSTATUS ErrorStatus, IN PUNICODE_STRING String, IN PKTHREAD Thread)
Definition: error.c:710
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3187
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
LARGE_INTEGER Length
Definition: winioctl.h:560
CSHORT NodeSize
Definition: btrfs_drv.h:372
USHORT NodeType
Definition: btrfs_drv.h:371
LIST_ENTRY list_entry_all
Definition: btrfs_drv.h:337
ULONG atts
Definition: btrfs_drv.h:297
struct _file_ref * fileref
Definition: btrfs_drv.h:305
LIST_ENTRY list_entry
Definition: btrfs_drv.h:336
uint32_t hash
Definition: btrfs_drv.h:290
struct _fcb_nonpaged * nonpaged
Definition: btrfs_drv.h:284
bool readonly
Definition: btrfs_drv.h:530
bool seeding
Definition: btrfs_drv.h:529
uint64_t children_loaded
Definition: btrfs_drv.h:895
uint64_t num_children
Definition: btrfs_drv.h:894
void * PVOID
Definition: typedefs.h:50
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817

Referenced by _Dispatch_type_().

◆ protect_superblocks()

void protect_superblocks ( _Inout_ chunk c)

Definition at line 3777 of file btrfs.c.

3777 {
3778 uint16_t i = 0, j;
3779 uint64_t off_start, off_end;
3780
3781 // The Linux driver also protects all the space before the first superblock.
3782 // I realize this confuses physical and logical addresses, but this is what btrfs-progs does -
3783 // evidently Linux assumes the chunk at 0 is always SINGLE.
3784 if (c->offset < superblock_addrs[0])
3785 space_list_subtract(c, c->offset, superblock_addrs[0] - c->offset, NULL);
3786
3787 while (superblock_addrs[i] != 0) {
3788 CHUNK_ITEM* ci = c->chunk_item;
3789 CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&ci[1];
3790
3791 if (ci->type & BLOCK_FLAG_RAID0 || ci->type & BLOCK_FLAG_RAID10) {
3792 for (j = 0; j < ci->num_stripes; j++) {
3793 uint16_t sub_stripes = max(ci->sub_stripes, 1);
3794
3795 if (cis[j].offset + (ci->size * ci->num_stripes / sub_stripes) > superblock_addrs[i] && cis[j].offset <= superblock_addrs[i] + sizeof(superblock)) {
3796#ifdef _DEBUG
3797 uint64_t startoff;
3798 uint16_t startoffstripe;
3799#endif
3800
3801 TRACE("cut out superblock in chunk %I64x\n", c->offset);
3802
3803 off_start = superblock_addrs[i] - cis[j].offset;
3804 off_start -= off_start % ci->stripe_length;
3805 off_start *= ci->num_stripes / sub_stripes;
3806 off_start += (j / sub_stripes) * ci->stripe_length;
3807
3808 off_end = off_start + ci->stripe_length;
3809
3810#ifdef _DEBUG
3811 get_raid0_offset(off_start, ci->stripe_length, ci->num_stripes / sub_stripes, &startoff, &startoffstripe);
3812 TRACE("j = %u, startoffstripe = %u\n", j, startoffstripe);
3813 TRACE("startoff = %I64x, superblock = %I64x\n", startoff + cis[j].offset, superblock_addrs[i]);
3814#endif
3815
3816 space_list_subtract(c, c->offset + off_start, off_end - off_start, NULL);
3817 }
3818 }
3819 } else if (ci->type & BLOCK_FLAG_RAID5) {
3820 uint64_t stripe_size = ci->size / (ci->num_stripes - 1);
3821
3822 for (j = 0; j < ci->num_stripes; j++) {
3823 if (cis[j].offset + stripe_size > superblock_addrs[i] && cis[j].offset <= superblock_addrs[i] + sizeof(superblock)) {
3824 TRACE("cut out superblock in chunk %I64x\n", c->offset);
3825
3826 off_start = superblock_addrs[i] - cis[j].offset;
3827 off_start -= off_start % ci->stripe_length;
3828 off_start *= ci->num_stripes - 1;
3829
3830 off_end = sector_align(superblock_addrs[i] - cis[j].offset + sizeof(superblock), ci->stripe_length);
3831 off_end *= ci->num_stripes - 1;
3832
3833 TRACE("cutting out %I64x, size %I64x\n", c->offset + off_start, off_end - off_start);
3834
3835 space_list_subtract(c, c->offset + off_start, off_end - off_start, NULL);
3836 }
3837 }
3838 } else if (ci->type & BLOCK_FLAG_RAID6) {
3839 uint64_t stripe_size = ci->size / (ci->num_stripes - 2);
3840
3841 for (j = 0; j < ci->num_stripes; j++) {
3842 if (cis[j].offset + stripe_size > superblock_addrs[i] && cis[j].offset <= superblock_addrs[i] + sizeof(superblock)) {
3843 TRACE("cut out superblock in chunk %I64x\n", c->offset);
3844
3845 off_start = superblock_addrs[i] - cis[j].offset;
3846 off_start -= off_start % ci->stripe_length;
3847 off_start *= ci->num_stripes - 2;
3848
3849 off_end = sector_align(superblock_addrs[i] - cis[j].offset + sizeof(superblock), ci->stripe_length);
3850 off_end *= ci->num_stripes - 2;
3851
3852 TRACE("cutting out %I64x, size %I64x\n", c->offset + off_start, off_end - off_start);
3853
3854 space_list_subtract(c, c->offset + off_start, off_end - off_start, NULL);
3855 }
3856 }
3857 } else { // SINGLE, DUPLICATE, RAID1, RAID1C3, RAID1C4
3858 for (j = 0; j < ci->num_stripes; j++) {
3859 if (cis[j].offset + ci->size > superblock_addrs[i] && cis[j].offset <= superblock_addrs[i] + sizeof(superblock)) {
3860 TRACE("cut out superblock in chunk %I64x\n", c->offset);
3861
3862 // The Linux driver protects the whole stripe in which the superblock lives
3863
3864 off_start = ((superblock_addrs[i] - cis[j].offset) / c->chunk_item->stripe_length) * c->chunk_item->stripe_length;
3865 off_end = sector_align(superblock_addrs[i] - cis[j].offset + sizeof(superblock), c->chunk_item->stripe_length);
3866
3867 space_list_subtract(c, c->offset + off_start, off_end - off_start, NULL);
3868 }
3869 }
3870 }
3871
3872 i++;
3873 }
3874}
_Post_satisfies_ static stripe __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)
Definition: btrfs_drv.h:997
void space_list_subtract(chunk *c, uint64_t address, uint64_t length, LIST_ENTRY *rollback)
Definition: free-space.c:2234
uint64_t offset
Definition: btrfs.h:353
uint64_t stripe_length
Definition: btrfs.h:342
uint16_t sub_stripes
Definition: btrfs.h:348
uint64_t size
Definition: btrfs.h:340
uint64_t type
Definition: btrfs.h:343
#define max(a, b)
Definition: svc.c:63

Referenced by __attribute__(), and load_cache_chunk().

◆ queue_notification_fcb()

void queue_notification_fcb ( _In_ file_ref fileref,
_In_ ULONG  filter_match,
_In_ ULONG  action,
_In_opt_ PUNICODE_STRING  stream 
)

Definition at line 1667 of file btrfs.c.

1667 {
1668 notification_fcb* nf;
1669 PIO_WORKITEM work_item;
1670
1672 if (!nf) {
1673 ERR("out of memory\n");
1674 return;
1675 }
1676
1677 work_item = IoAllocateWorkItem(master_devobj);
1678 if (!work_item) {
1679 ERR("out of memory\n");
1680 ExFreePool(nf);
1681 return;
1682 }
1683
1684 InterlockedIncrement(&fileref->refcount);
1685
1686 nf->fileref = fileref;
1687 nf->filter_match = filter_match;
1688 nf->action = action;
1689 nf->stream = stream;
1690 nf->work_item = work_item;
1691
1692 IoQueueWorkItem(work_item, notification_work_item, DelayedWorkQueue, nf);
1693}
const WCHAR * action
Definition: action.c:7479

Referenced by __attribute__(), create_stream(), delete_reparse_point(), duplicate_extents(), file_create(), mknod(), open_file3(), set_basic_information(), set_end_of_file_information(), set_file_security(), set_reparse_point(), set_sparse(), set_valid_data_length_information(), and set_zero_data().

◆ r()

◆ read_superblock()

static NTSTATUS read_superblock ( _In_ device_extension Vcb,
_In_ PDEVICE_OBJECT  device,
_In_ PFILE_OBJECT  fileobj,
_In_ uint64_t  length 
)
static

Definition at line 2882 of file btrfs.c.

2882 {
2884 superblock* sb;
2885 ULONG i, to_read;
2886 uint8_t valid_superblocks;
2887
2888 to_read = device->SectorSize == 0 ? sizeof(superblock) : (ULONG)sector_align(sizeof(superblock), device->SectorSize);
2889
2891 if (!sb) {
2892 ERR("out of memory\n");
2894 }
2895
2896 if (superblock_addrs[0] + to_read > length) {
2897 WARN("device was too short to have any superblock\n");
2898 ExFreePool(sb);
2900 }
2901
2902 i = 0;
2903 valid_superblocks = 0;
2904
2905 while (superblock_addrs[i] > 0) {
2906 if (i > 0 && superblock_addrs[i] + to_read > length)
2907 break;
2908
2910 if (!NT_SUCCESS(Status)) {
2911 ERR("Failed to read superblock %lu: %08lx\n", i, Status);
2912 ExFreePool(sb);
2913 return Status;
2914 }
2915
2916 if (sb->magic != BTRFS_MAGIC) {
2917 if (i == 0) {
2918 TRACE("not a BTRFS volume\n");
2919 ExFreePool(sb);
2921 }
2922 } else {
2923 TRACE("got superblock %lu!\n", i);
2924
2925 if (sb->sector_size == 0)
2926 WARN("superblock sector size was 0\n");
2927 else if (sb->sector_size & (sb->sector_size - 1))
2928 WARN("superblock sector size was not power of 2\n");
2929 else if (sb->node_size < sizeof(tree_header) + sizeof(internal_node) || sb->node_size > 0x10000)
2930 WARN("invalid node size %x\n", sb->node_size);
2931 else if ((sb->node_size % sb->sector_size) != 0)
2932 WARN("node size %x was not a multiple of sector_size %x\n", sb->node_size, sb->sector_size);
2933 else if (check_superblock_checksum(sb) && (valid_superblocks == 0 || sb->generation > Vcb->superblock.generation)) {
2934 RtlCopyMemory(&Vcb->superblock, sb, sizeof(superblock));
2935 valid_superblocks++;
2936 }
2937 }
2938
2939 i++;
2940 }
2941
2942 ExFreePool(sb);
2943
2944 if (valid_superblocks == 0) {
2945 ERR("could not find any valid superblocks\n");
2946 return STATUS_INTERNAL_ERROR;
2947 }
2948
2949 TRACE("label is %s\n", Vcb->superblock.label);
2950
2951 return STATUS_SUCCESS;
2952}
uint32_t sector_size
Definition: btrfs.h:238
uint32_t node_size
Definition: btrfs.h:239

Referenced by mount_vol().

◆ reap_fcb()

void reap_fcb ( fcb fcb)

Definition at line 1743 of file btrfs.c.

1743 {
1744 uint8_t c = fcb->hash >> 24;
1745
1746 if (fcb->subvol && fcb->subvol->fcbs_ptrs[c] == &fcb->list_entry) {
1747 if (fcb->list_entry.Flink != &fcb->subvol->fcbs && (CONTAINING_RECORD(fcb->list_entry.Flink, struct _fcb, list_entry)->hash >> 24) == c)
1748 fcb->subvol->fcbs_ptrs[c] = fcb->list_entry.Flink;
1749 else
1750 fcb->subvol->fcbs_ptrs[c] = NULL;
1751 }
1752
1753 if (fcb->list_entry.Flink) {
1755
1756 if (fcb->subvol && fcb->subvol->dropped && IsListEmpty(&fcb->subvol->fcbs)) {
1757 ExDeleteResourceLite(&fcb->subvol->nonpaged->load_tree_lock);
1758 ExFreePool(fcb->subvol->nonpaged);
1760 }
1761 }
1762
1765
1766 ExDeleteResourceLite(&fcb->nonpaged->resource);
1767 ExDeleteResourceLite(&fcb->nonpaged->paging_resource);
1768 ExDeleteResourceLite(&fcb->nonpaged->dir_children_lock);
1769
1770 ExFreeToNPagedLookasideList(&fcb->Vcb->fcb_np_lookaside, fcb->nonpaged);
1771
1772 if (fcb->sd)
1773 ExFreePool(fcb->sd);
1774
1775 if (fcb->adsxattr.Buffer)
1777
1780
1781 if (fcb->ea_xattr.Buffer)
1783
1784 if (fcb->adsdata.Buffer)
1786
1787 while (!IsListEmpty(&fcb->extents)) {
1790
1791 if (ext->csum)
1792 ExFreePool(ext->csum);
1793
1794 ExFreePool(ext);
1795 }
1796
1797 while (!IsListEmpty(&fcb->hardlinks)) {
1800
1801 if (hl->name.Buffer)
1802 ExFreePool(hl->name.Buffer);
1803
1804 if (hl->utf8.Buffer)
1805 ExFreePool(hl->utf8.Buffer);
1806
1807 ExFreePool(hl);
1808 }
1809
1810 while (!IsListEmpty(&fcb->xattrs)) {
1812
1813 ExFreePool(xa);
1814 }
1815
1816 while (!IsListEmpty(&fcb->dir_children_index)) {
1818 dir_child* dc = CONTAINING_RECORD(le, dir_child, list_entry_index);
1819
1820 ExFreePool(dc->utf8.Buffer);
1821 ExFreePool(dc->name.Buffer);
1822 ExFreePool(dc->name_uc.Buffer);
1823 ExFreePool(dc);
1824 }
1825
1826 if (fcb->hash_ptrs)
1828
1829 if (fcb->hash_ptrs_uc)
1831
1834
1835 if (fcb->pool_type == NonPagedPool)
1836 ExFreePool(fcb);
1837 else
1838 ExFreeToPagedLookasideList(&fcb->Vcb->fcb_lookaside, fcb);
1839}
static const WCHAR *const ext[]
Definition: module.c:53
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
static const WCHAR dc[]
VOID NTAPI FsRtlUninitializeOplock(IN POPLOCK Oplock)
Definition: oplock.c:1600
LIST_ENTRY xattrs
Definition: btrfs_drv.h:308
LIST_ENTRY hardlinks
Definition: btrfs_drv.h:304
LIST_ENTRY dir_children_index
Definition: btrfs_drv.h:314
POOL_TYPE pool_type
Definition: btrfs_drv.h:286
LIST_ENTRY extents
Definition: btrfs_drv.h:300
SECURITY_DESCRIPTOR * sd
Definition: btrfs_drv.h:293
ANSI_STRING adsdata
Definition: btrfs_drv.h:334
ANSI_STRING adsxattr
Definition: btrfs_drv.h:333
LIST_ENTRY ** hash_ptrs_uc
Definition: btrfs_drv.h:318
ANSI_STRING reparse_xattr
Definition: btrfs_drv.h:301
LIST_ENTRY ** hash_ptrs
Definition: btrfs_drv.h:317
ANSI_STRING ea_xattr
Definition: btrfs_drv.h:302

Referenced by allocate_cache_chunk(), clear_free_space_cache(), create_directory_fcb(), create_stream(), create_subvol(), drop_chunk(), mknod(), mount_vol(), open_fcb(), open_fcb_stream(), open_fileref_child(), reap_fcbs(), rename_file_to_stream(), rename_stream_to_file(), uninit(), and update_chunk_usage().

◆ reap_fcbs()

void reap_fcbs ( device_extension Vcb)

Definition at line 1841 of file btrfs.c.

1841 {
1842 LIST_ENTRY* le;
1843
1844 le = Vcb->all_fcbs.Flink;
1845 while (le != &Vcb->all_fcbs) {
1846 fcb* fcb = CONTAINING_RECORD(le, struct _fcb, list_entry_all);
1847 LIST_ENTRY* le2 = le->Flink;
1848
1849 if (fcb->refcount == 0)
1850 reap_fcb(fcb);
1851
1852 le = le2;
1853 }
1854}

◆ reap_fileref()

void reap_fileref ( device_extension Vcb,
file_ref fr 
)

Definition at line 1875 of file btrfs.c.

1875 {
1876 // FIXME - do we need a file_ref lock?
1877
1878 // FIXME - do delete if needed
1879
1880 // FIXME - throw error if children not empty
1881
1882 if (fr->fcb->fileref == fr)
1883 fr->fcb->fileref = NULL;
1884
1885 if (fr->dc) {
1886 if (fr->fcb->ads)
1887 fr->dc->size = fr->fcb->adsdata.Length;
1888
1889 fr->dc->fileref = NULL;
1890 }
1891
1892 if (fr->list_entry.Flink)
1894
1895 if (fr->parent)
1896 free_fileref(fr->parent);
1897
1898 free_fcb(fr->fcb);
1899
1900 if (fr->oldutf8.Buffer)
1902
1903 ExFreeToPagedLookasideList(&Vcb->fileref_lookaside, fr);
1904}
LIST_ENTRY list_entry
Definition: btrfs_drv.h:357
ANSI_STRING oldutf8
Definition: btrfs_drv.h:343
ULONG size
Definition: btrfs_drv.h:259
struct _file_ref * fileref
Definition: btrfs_drv.h:260

Referenced by create_stream(), file_create2(), open_fileref_child(), reap_filerefs(), and rename_file_to_stream().

◆ reap_filerefs()

void reap_filerefs ( device_extension Vcb,
file_ref fr 
)

Definition at line 1906 of file btrfs.c.

1906 {
1907 LIST_ENTRY* le;
1908
1909 // FIXME - recursion is a bad idea in kernel mode
1910
1911 le = fr->children.Flink;
1912 while (le != &fr->children) {
1914 LIST_ENTRY* le2 = le->Flink;
1915
1917
1918 le = le2;
1919 }
1920
1921 if (fr->refcount == 0)
1922 reap_fileref(Vcb, fr);
1923}
void reap_filerefs(device_extension *Vcb, file_ref *fr)
Definition: btrfs.c:1906
void reap_fileref(device_extension *Vcb, file_ref *fr)
Definition: btrfs.c:1875
LIST_ENTRY children
Definition: btrfs_drv.h:349

Referenced by reap_filerefs().

◆ RtlZeroMemory()

RtlZeroMemory ( r->  fcbs_ptrs,
sizeof(LIST_ENTRY *) *  256 
)

◆ send_notification_fcb()

static void send_notification_fcb ( _In_ file_ref fileref,
_In_ ULONG  filter_match,
_In_ ULONG  action,
_In_opt_ PUNICODE_STRING  stream 
)
static

Definition at line 1557 of file btrfs.c.

1557 {
1558 fcb* fcb = fileref->fcb;
1559 LIST_ENTRY* le;
1561
1562 // no point looking for hardlinks if st_nlink == 1
1563 if (fileref->fcb->inode_item.st_nlink == 1) {
1564 ExAcquireResourceExclusiveLite(&fcb->Vcb->fileref_lock, true);
1565 send_notification_fileref(fileref, filter_match, action, stream);
1566 ExReleaseResourceLite(&fcb->Vcb->fileref_lock);
1567 return;
1568 }
1569
1570 ExAcquireResourceExclusiveLite(&fcb->Vcb->fileref_lock, true);
1571
1572 le = fcb->hardlinks.Flink;
1573 while (le != &fcb->hardlinks) {
1575 file_ref* parfr;
1576
1578
1579 if (!NT_SUCCESS(Status))
1580 ERR("open_fileref_by_inode returned %08lx\n", Status);
1581 else if (!parfr->deleted) {
1583 ULONG pathlen;
1584
1585 fn.Length = fn.MaximumLength = 0;
1586 Status = fileref_get_filename(parfr, &fn, NULL, &pathlen);
1588 ERR("fileref_get_filename returned %08lx\n", Status);
1589 free_fileref(parfr);
1590 break;
1591 }
1592
1593 if (parfr != fcb->Vcb->root_fileref)
1594 pathlen += sizeof(WCHAR);
1595
1596 if (pathlen + hl->name.Length > 0xffff) {
1597 WARN("pathlen + hl->name.Length was too long for FsRtlNotifyFilterReportChange\n");
1598 free_fileref(parfr);
1599 break;
1600 }
1601
1602 fn.MaximumLength = (USHORT)(pathlen + hl->name.Length);
1603 fn.Buffer = ExAllocatePoolWithTag(PagedPool, fn.MaximumLength, ALLOC_TAG);
1604 if (!fn.Buffer) {
1605 ERR("out of memory\n");
1606 free_fileref(parfr);
1607 break;
1608 }
1609
1610 Status = fileref_get_filename(parfr, &fn, NULL, NULL);
1611 if (!NT_SUCCESS(Status)) {
1612 ERR("fileref_get_filename returned %08lx\n", Status);
1613 free_fileref(parfr);
1614 ExFreePool(fn.Buffer);
1615 break;
1616 }
1617
1618 if (parfr != fcb->Vcb->root_fileref) {
1619 fn.Buffer[(pathlen / sizeof(WCHAR)) - 1] = '\\';
1620 fn.Length += sizeof(WCHAR);
1621 }
1622
1623 RtlCopyMemory(&fn.Buffer[pathlen / sizeof(WCHAR)], hl->name.Buffer, hl->name.Length);
1624 fn.Length += hl->name.Length;
1625
1626 FsRtlNotifyFilterReportChange(fcb->Vcb->NotifySync, &fcb->Vcb->DirNotifyList, (PSTRING)&fn, (USHORT)pathlen,
1627 (PSTRING)stream, NULL, filter_match, action, NULL, NULL);
1628
1629 ExFreePool(fn.Buffer);
1630
1631 free_fileref(parfr);
1632 }
1633
1634 le = le->Flink;
1635 }
1636
1637 ExReleaseResourceLite(&fcb->Vcb->fileref_lock);
1638}
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)
Definition: create.c:4136
NTSTATUS fileref_get_filename(file_ref *fileref, PUNICODE_STRING fn, USHORT *name_offset, ULONG *preqlen)
Definition: fileinfo.c:4245
VOID NTAPI FsRtlNotifyFilterReportChange(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN USHORT TargetNameOffset, IN PSTRING StreamName OPTIONAL, IN PSTRING NormalizedParentName OPTIONAL, IN ULONG FilterMatch, IN ULONG Action, IN PVOID TargetContext, IN PVOID FilterContext)
Definition: notify.c:997
bool deleted
Definition: btrfs_drv.h:347

Referenced by _Function_class_(), and delete_fileref().

◆ send_notification_fileref()

void send_notification_fileref ( _In_ file_ref fileref,
_In_ ULONG  filter_match,
_In_ ULONG  action,
_In_opt_ PUNICODE_STRING  stream 
)

Definition at line 1517 of file btrfs.c.

1517 {
1520 ULONG reqlen;
1521 USHORT name_offset;
1522 fcb* fcb = fileref->fcb;
1523
1524 fn.Length = fn.MaximumLength = 0;
1525 Status = fileref_get_filename(fileref, &fn, NULL, &reqlen);
1527 ERR("fileref_get_filename returned %08lx\n", Status);
1528 return;
1529 }
1530
1531 if (reqlen > 0xffff) {
1532 WARN("reqlen was too long for FsRtlNotifyFilterReportChange\n");
1533 return;
1534 }
1535
1536 fn.Buffer = ExAllocatePoolWithTag(PagedPool, reqlen, ALLOC_TAG);
1537 if (!fn.Buffer) {
1538 ERR("out of memory\n");
1539 return;
1540 }
1541
1542 fn.MaximumLength = (USHORT)reqlen;
1543 fn.Length = 0;
1544
1545 Status = fileref_get_filename(fileref, &fn, &name_offset, &reqlen);
1546 if (!NT_SUCCESS(Status)) {
1547 ERR("fileref_get_filename returned %08lx\n", Status);
1548 ExFreePool(fn.Buffer);
1549 return;
1550 }
1551
1552 FsRtlNotifyFilterReportChange(fcb->Vcb->NotifySync, &fcb->Vcb->DirNotifyList, (PSTRING)&fn, name_offset,
1553 (PSTRING)stream, NULL, filter_match, action, NULL, NULL);
1554 ExFreePool(fn.Buffer);
1555}

Referenced by _Dispatch_type_(), create_snapshot(), create_stream(), create_subvol(), do_create_snapshot(), file_create(), mknod(), move_across_subvols(), send_notification_fcb(), set_link_information(), and set_rename_information().

◆ set_label()

static NTSTATUS set_label ( _In_ device_extension Vcb,
_In_ FILE_FS_LABEL_INFORMATION ffli 
)
static

Definition at line 1392 of file btrfs.c.

1392 {
1393 ULONG utf8len;
1395 ULONG vollen, i;
1396
1397 TRACE("label = %.*S\n", (int)(ffli->VolumeLabelLength / sizeof(WCHAR)), ffli->VolumeLabel);
1398
1399 vollen = ffli->VolumeLabelLength;
1400
1401 for (i = 0; i < ffli->VolumeLabelLength / sizeof(WCHAR); i++) {
1402 if (ffli->VolumeLabel[i] == 0) {
1403 vollen = i * sizeof(WCHAR);
1404 break;
1405 } else if (ffli->VolumeLabel[i] == '/' || ffli->VolumeLabel[i] == '\\') {
1407 goto end;
1408 }
1409 }
1410
1411 if (vollen == 0) {
1412 utf8len = 0;
1413 } else {
1414 Status = utf16_to_utf8(NULL, 0, &utf8len, ffli->VolumeLabel, vollen);
1415 if (!NT_SUCCESS(Status))
1416 goto end;
1417
1418 if (utf8len > MAX_LABEL_SIZE) {
1420 goto end;
1421 }
1422 }
1423
1424 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
1425
1426 if (utf8len > 0) {
1427 Status = utf16_to_utf8((PCHAR)&Vcb->superblock.label, MAX_LABEL_SIZE, &utf8len, ffli->VolumeLabel, vollen);
1428 if (!NT_SUCCESS(Status))
1429 goto release;
1430 } else
1432
1433 if (utf8len < MAX_LABEL_SIZE)
1434 RtlZeroMemory(Vcb->superblock.label + utf8len, MAX_LABEL_SIZE - utf8len);
1435
1436 Vcb->need_write = true;
1437
1438release:
1439 ExReleaseResourceLite(&Vcb->tree_lock);
1440
1441end:
1442 TRACE("returning %08lx\n", Status);
1443
1444 return Status;
1445}
#define MAX_LABEL_SIZE
Definition: btrfs.h:19
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_VOLUME_LABEL
Definition: udferr_usr.h:156

Referenced by _Dispatch_type_().

◆ still_has_superblock()

static bool still_has_superblock ( _In_ PDEVICE_OBJECT  device,
_In_ PFILE_OBJECT  fileobj 
)
static

Definition at line 4313 of file btrfs.c.

4313 {
4315 ULONG to_read;
4316 superblock* sb;
4317
4318 if (!device)
4319 return false;
4320
4321 to_read = device->SectorSize == 0 ? sizeof(superblock) : (ULONG)sector_align(sizeof(superblock), device->SectorSize);
4322
4324 if (!sb) {
4325 ERR("out of memory\n");
4326 return false;
4327 }
4328
4329 Status = sync_read_phys(device, fileobj, superblock_addrs[0], to_read, (PUCHAR)sb, true);
4330 if (!NT_SUCCESS(Status)) {
4331 ERR("Failed to read superblock: %08lx\n", Status);
4332 ExFreePool(sb);
4333 return false;
4334 }
4335
4336 if (sb->magic != BTRFS_MAGIC) {
4337 TRACE("not a BTRFS volume\n");
4338 ExFreePool(sb);
4339 return false;
4340 } else {
4342 ExFreePool(sb);
4343 return false;
4344 }
4345 }
4346
4348
4349 while (device) {
4351
4352 device->Flags &= ~DO_VERIFY_VOLUME;
4353
4355
4356 device = device2;
4357 }
4358
4359 ExFreePool(sb);
4360
4361 return true;
4362}

Referenced by mount_vol().

◆ switch()

switch ( r->  id)

Definition at line 3046 of file btrfs.c.

3046 {
3047 case BTRFS_ROOT_ROOT:
3048 Vcb->root_root = r;
3049 break;
3050
3051 case BTRFS_ROOT_EXTENT:
3052 Vcb->extent_root = r;
3053 break;
3054
3055 case BTRFS_ROOT_CHUNK:
3056 Vcb->chunk_root = r;
3057 break;
3058
3059 case BTRFS_ROOT_DEVTREE:
3060 Vcb->dev_root = r;
3061 break;
3062
3064 Vcb->checksum_root = r;
3065 break;
3066
3067 case BTRFS_ROOT_UUID:
3068 Vcb->uuid_root = r;
3069 break;
3070
3072 Vcb->space_root = r;
3073 break;
3074
3076 Vcb->data_reloc_root = r;
3077 break;
3078 }
#define BTRFS_ROOT_UUID
Definition: btrfs.h:61
#define BTRFS_ROOT_FREE_SPACE
Definition: btrfs.h:62
#define BTRFS_ROOT_DEVTREE
Definition: btrfs.h:57
#define BTRFS_ROOT_EXTENT
Definition: btrfs.h:55
#define BTRFS_ROOT_CHECKSUM
Definition: btrfs.h:60

Referenced by _control87(), _Success_(), AcpiDsInitBufferField(), AcpiUtCopyIelementToIelement(), cff_index_load_offsets(), DispTdiQueryInformation(), DispTdiQueryInformationEx(), EngAlphaBlend(), Fat8dot3ToString(), FreeBT_QueryWmiDataBlock(), FT_Stream_ReadFields(), gl_ArrayElement(), gl_save_ArrayElement(), i8042DeviceControl(), i8042InternalDeviceControl(), i8042KbdDeviceControl(), i8042KbdInternalDeviceControl(), i8042KbdStartIo(), i8042MouInternalDeviceControl(), i8042SendHookWorkItem(), i8042StartIo(), jinit_color_deconverter(), KdSendPacket(), KeyboardInternalDeviceControl(), Main_DirectDraw_GetCaps(), MainWndProc(), ME_StreamOutRTFCharProps(), NdisIDispatchPnp(), CMainToolbar::OnGetDispInfo(), PdoQueryDeviceText(), PdoQueryId(), prepare_for_pass(), CAC97MiniportTopology::PropertyHandler_OnOff(), regstore_get_double(), regstore_set_double(), RPCRT4_process_packet(), RtlRunOnceBeginInitialize(), RtlRunOnceComplete(), ScsiFlopDeviceControl(), SecurityPageCallback(), SenseInfoInterpretByAdditionalSenseCode(), start_pass_main(), TIFFWriteDirectorySec(), USBPORT_HandleGetSetDescriptor(), USBPORT_HandleGetStatus(), USBPORT_HandleSetOrClearFeature(), xdrrec_getoutbase(), and xdrrec_inline().

◆ sync_read_phys()

NTSTATUS sync_read_phys ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PFILE_OBJECT  FileObject,
_In_ uint64_t  StartingOffset,
_In_ ULONG  Length,
_Out_writes_bytes_(Length) PUCHAR  Buffer,
_In_ bool  override 
)

Definition at line 2732 of file btrfs.c.

2733 {
2736 PIRP Irp;
2740
2741 num_reads++;
2742
2745
2746 Offset.QuadPart = (LONGLONG)StartingOffset;
2747
2748 Irp = IoAllocateIrp(DeviceObject->StackSize, false);
2749
2750 if (!Irp) {
2751 ERR("IoAllocateIrp failed\n");
2753 }
2754
2755 Irp->Flags |= IRP_NOCACHE;
2759
2760 if (override)
2762
2763 if (DeviceObject->Flags & DO_BUFFERED_IO) {
2764 Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool, Length, ALLOC_TAG);
2765 if (!Irp->AssociatedIrp.SystemBuffer) {
2766 ERR("out of memory\n");
2768 goto exit;
2769 }
2770
2772
2773 Irp->UserBuffer = Buffer;
2774 } else if (DeviceObject->Flags & DO_DIRECT_IO) {
2775 Irp->MdlAddress = IoAllocateMdl(Buffer, Length, false, false, NULL);
2776 if (!Irp->MdlAddress) {
2777 ERR("IoAllocateMdl failed\n");
2779 goto exit;
2780 }
2781
2783
2784 _SEH2_TRY {
2788 } _SEH2_END;
2789
2790 if (!NT_SUCCESS(Status)) {
2791 ERR("MmProbeAndLockPages threw exception %08lx\n", Status);
2792 IoFreeMdl(Irp->MdlAddress);
2793 goto exit;
2794 }
2795 } else
2796 Irp->UserBuffer = Buffer;
2797
2798 IrpSp->Parameters.Read.Length = Length;
2799 IrpSp->Parameters.Read.ByteOffset = Offset;
2800
2801 Irp->UserIosb = &IoStatus;
2802
2803 Irp->UserEvent = &context.Event;
2804
2805 IoSetCompletionRoutine(Irp, read_completion, &context, true, true, true);
2806
2808
2809 if (Status == STATUS_PENDING) {
2811 Status = context.iosb.Status;
2812 }
2813
2814 if (DeviceObject->Flags & DO_DIRECT_IO) {
2815 MmUnlockPages(Irp->MdlAddress);
2816 IoFreeMdl(Irp->MdlAddress);
2817 }
2818
2819exit:
2820 IoFreeIrp(Irp);
2821
2822 return Status;
2823}
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
Definition: bufpool.h:45
uint64_t num_reads
Definition: btrfs.c:67
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
int64_t LONGLONG
Definition: typedefs.h:68
#define IRP_DEALLOCATE_BUFFER
#define IRP_INPUT_OPERATION
#define IRP_BUFFERED_IO
#define IRP_NOCACHE
@ IoWriteAccess
Definition: ketypes.h:864

Referenced by device_still_valid(), is_device_part_of_mounted_btrfs_raid(), partial_stripe_read(), read_data_dup(), read_data_raid10(), read_data_raid5(), read_data_raid6(), read_superblock(), still_has_superblock(), test_vol(), and verify_device().

◆ uninit()

void uninit ( _In_ device_extension Vcb)

Definition at line 2001 of file btrfs.c.

2001 {
2002 uint64_t i;
2003 KIRQL irql;
2005 LIST_ENTRY* le;
2007
2008 if (!Vcb->removing) {
2009 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
2010 Vcb->removing = true;
2011 ExReleaseResourceLite(&Vcb->tree_lock);
2012 }
2013
2014 if (Vcb->vde && Vcb->vde->mounted_device == Vcb->devobj)
2015 Vcb->vde->mounted_device = NULL;
2016
2018 Vcb->Vpb->Flags &= ~VPB_MOUNTED;
2019 Vcb->Vpb->Flags |= VPB_DIRECT_WRITES_ALLOWED;
2020 Vcb->Vpb->DeviceObject = NULL;
2022
2023 // FIXME - needs global_loading_lock to be held
2024 if (Vcb->list_entry.Flink)
2025 RemoveEntryList(&Vcb->list_entry);
2026
2027 if (Vcb->balance.thread) {
2028 Vcb->balance.paused = false;
2029 Vcb->balance.stopping = true;
2030 KeSetEvent(&Vcb->balance.event, 0, false);
2031 KeWaitForSingleObject(&Vcb->balance.finished, Executive, KernelMode, false, NULL);
2032 }
2033
2034 if (Vcb->scrub.thread) {
2035 Vcb->scrub.paused = false;
2036 Vcb->scrub.stopping = true;
2037 KeSetEvent(&Vcb->scrub.event, 0, false);
2038 KeWaitForSingleObject(&Vcb->scrub.finished, Executive, KernelMode, false, NULL);
2039 }
2040
2041 if (Vcb->running_sends != 0) {
2042 bool send_cancelled = false;
2043
2044 ExAcquireResourceExclusiveLite(&Vcb->send_load_lock, true);
2045
2046 le = Vcb->send_ops.Flink;
2047 while (le != &Vcb->send_ops) {
2049
2050 if (!send->cancelling) {
2051 send->cancelling = true;
2052 send_cancelled = true;
2053 send->ccb = NULL;
2054 KeSetEvent(&send->cleared_event, 0, false);
2055 }
2056
2057 le = le->Flink;
2058 }
2059
2060 ExReleaseResourceLite(&Vcb->send_load_lock);
2061
2062 if (send_cancelled) {
2063 while (Vcb->running_sends != 0) {
2064 ExAcquireResourceExclusiveLite(&Vcb->send_load_lock, true);
2065 ExReleaseResourceLite(&Vcb->send_load_lock);
2066 }
2067 }
2068 }
2069
2070 Status = registry_mark_volume_unmounted(&Vcb->superblock.uuid);
2072 WARN("registry_mark_volume_unmounted returned %08lx\n", Status);
2073
2074 for (i = 0; i < Vcb->calcthreads.num_threads; i++) {
2075 Vcb->calcthreads.threads[i].quit = true;
2076 }
2077
2078 KeSetEvent(&Vcb->calcthreads.event, 0, false);
2079
2080 for (i = 0; i < Vcb->calcthreads.num_threads; i++) {
2081 KeWaitForSingleObject(&Vcb->calcthreads.threads[i].finished, Executive, KernelMode, false, NULL);
2082
2083 ZwClose(Vcb->calcthreads.threads[i].handle);
2084 }
2085
2086 ExFreePool(Vcb->calcthreads.threads);
2087
2088 time.QuadPart = 0;
2089 KeSetTimer(&Vcb->flush_thread_timer, time, NULL); // trigger the timer early
2090 KeWaitForSingleObject(&Vcb->flush_thread_finished, Executive, KernelMode, false, NULL);
2091
2092 reap_fcb(Vcb->volume_fcb);
2093 reap_fcb(Vcb->dummy_fcb);
2094
2095 if (Vcb->root_file)
2096 ObDereferenceObject(Vcb->root_file);
2097
2098 le = Vcb->chunks.Flink;
2099 while (le != &Vcb->chunks) {
2101
2102 if (c->cache) {
2103 reap_fcb(c->cache);
2104 c->cache = NULL;
2105 }
2106
2107 le = le->Flink;
2108 }
2109
2110 while (!IsListEmpty(&Vcb->all_fcbs)) {
2111 fcb* fcb = CONTAINING_RECORD(Vcb->all_fcbs.Flink, struct _fcb, list_entry_all);
2112
2113 reap_fcb(fcb);
2114 }
2115
2116 while (!IsListEmpty(&Vcb->sys_chunks)) {
2118
2119 if (sc->data)
2120 ExFreePool(sc->data);
2121
2122 ExFreePool(sc);
2123 }
2124
2125 while (!IsListEmpty(&Vcb->roots)) {
2127
2128 ExDeleteResourceLite(&r->nonpaged->load_tree_lock);
2129 ExFreePool(r->nonpaged);
2130 ExFreePool(r);
2131 }
2132
2133 while (!IsListEmpty(&Vcb->chunks)) {
2135
2136 while (!IsListEmpty(&c->space)) {
2137 LIST_ENTRY* le2 = RemoveHeadList(&c->space);
2139
2140 ExFreePool(s);
2141 }
2142
2143 while (!IsListEmpty(&c->deleting)) {
2144 LIST_ENTRY* le2 = RemoveHeadList(&c->deleting);
2146
2147 ExFreePool(s);
2148 }
2149
2150 if (c->devices)
2151 ExFreePool(c->devices);
2152
2153 if (c->cache)
2154 reap_fcb(c->cache);
2155
2156 ExDeleteResourceLite(&c->range_locks_lock);
2157 ExDeleteResourceLite(&c->partial_stripes_lock);
2158 ExDeleteResourceLite(&c->lock);
2159 ExDeleteResourceLite(&c->changed_extents_lock);
2160
2161 ExFreePool(c->chunk_item);
2162 ExFreePool(c);
2163 }
2164
2165 while (!IsListEmpty(&Vcb->devices)) {
2167
2168 while (!IsListEmpty(&dev->space)) {
2169 LIST_ENTRY* le2 = RemoveHeadList(&dev->space);
2171
2172 ExFreePool(s);
2173 }
2174
2175 ExFreePool(dev);
2176 }
2177
2178 ExAcquireResourceExclusiveLite(&Vcb->scrub.stats_lock, true);
2179 while (!IsListEmpty(&Vcb->scrub.errors)) {
2181
2182 ExFreePool(err);
2183 }
2184 ExReleaseResourceLite(&Vcb->scrub.stats_lock);
2185
2186 ExDeleteResourceLite(&Vcb->fcb_lock);
2187 ExDeleteResourceLite(&Vcb->fileref_lock);
2188 ExDeleteResourceLite(&Vcb->load_lock);
2189 ExDeleteResourceLite(&Vcb->tree_lock);
2190 ExDeleteResourceLite(&Vcb->chunk_lock);
2191 ExDeleteResourceLite(&Vcb->dirty_fcbs_lock);
2192 ExDeleteResourceLite(&Vcb->dirty_filerefs_lock);
2193 ExDeleteResourceLite(&Vcb->dirty_subvols_lock);
2194 ExDeleteResourceLite(&Vcb->scrub.stats_lock);
2195 ExDeleteResourceLite(&Vcb->send_load_lock);
2196
2197 ExDeletePagedLookasideList(&Vcb->tree_data_lookaside);
2198 ExDeletePagedLookasideList(&Vcb->traverse_ptr_lookaside);
2199 ExDeletePagedLookasideList(&Vcb->batch_item_lookaside);
2200 ExDeletePagedLookasideList(&Vcb->fileref_lookaside);
2201 ExDeletePagedLookasideList(&Vcb->fcb_lookaside);
2202 ExDeletePagedLookasideList(&Vcb->name_bit_lookaside);
2203 ExDeleteNPagedLookasideList(&Vcb->range_lock_lookaside);
2204 ExDeleteNPagedLookasideList(&Vcb->fcb_np_lookaside);
2205
2206 ZwClose(Vcb->flush_thread_handle);
2207
2208 if (Vcb->devobj->AttachedDevice)
2209 IoDetachDevice(Vcb->devobj);
2210
2211 IoDeleteDevice(Vcb->devobj);
2212}
NTSTATUS registry_mark_volume_unmounted(BTRFS_UUID *uuid)
Definition: registry.c:385
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
#define STATUS_TOO_LATE
Definition: ntstatus.h:626
#define err(...)

Referenced by close_file(), dismount_volume(), invalidate_volumes(), pnp_remove_device(), pnp_surprise_removal(), test_validtypes(), and verify_volume().

◆ utf16_to_utf8()

NTSTATUS utf16_to_utf8 ( char dest,
ULONG  dest_max,
ULONG dest_len,
WCHAR src,
ULONG  src_len 
)

Definition at line 894 of file btrfs.c.

894 {
896 uint16_t* in = (uint16_t*)src;
897 uint8_t* out = (uint8_t*)dest;
898 ULONG in_len = src_len / sizeof(uint16_t);
899 ULONG needed = 0, left = dest_max;
900
901 for (ULONG i = 0; i < in_len; i++) {
902 uint32_t cp = *in;
903 in++;
904
905 if ((cp & 0xfc00) == 0xd800) {
906 if (i == in_len - 1 || (*in & 0xfc00) != 0xdc00) {
907 cp = 0xfffd;
909 } else {
910 cp = (cp & 0x3ff) << 10;
911 cp |= *in & 0x3ff;
912 cp += 0x10000;
913
914 in++;
915 i++;
916 }
917 } else if ((cp & 0xfc00) == 0xdc00) {
918 cp = 0xfffd;
920 }
921
922 if (cp > 0x10ffff) {
923 cp = 0xfffd;
925 }
926
927 if (dest) {
928 if (cp < 0x80) {
929 if (left < 1)
931
932 *out = (uint8_t)cp;
933 out++;
934
935 left--;
936 } else if (cp < 0x800) {
937 if (left < 2)
939
940 *out = 0xc0 | ((cp & 0x7c0) >> 6);
941 out++;
942
943 *out = 0x80 | (cp & 0x3f);
944 out++;
945
946 left -= 2;
947 } else if (cp < 0x10000) {
948 if (left < 3)
950
951 *out = 0xe0 | ((cp & 0xf000) >> 12);
952 out++;
953
954 *out = 0x80 | ((cp & 0xfc0) >> 6);
955 out++;
956
957 *out = 0x80 | (cp & 0x3f);
958 out++;
959
960 left -= 3;
961 } else {
962 if (left < 4)
964
965 *out = 0xf0 | ((cp & 0x1c0000) >> 18);
966 out++;
967
968 *out = 0x80 | ((cp & 0x3f000) >> 12);
969 out++;
970
971 *out = 0x80 | ((cp & 0xfc0) >> 6);
972 out++;
973
974 *out = 0x80 | (cp & 0x3f);
975 out++;
976
977 left -= 4;
978 }
979 }
980
981 if (cp < 0x80)
982 needed++;
983 else if (cp < 0x800)
984 needed += 2;
985 else if (cp < 0x10000)
986 needed += 3;
987 else
988 needed += 4;
989 }
990
991 if (dest_len)
992 *dest_len = needed;
993
994 return Status;
995}
GLenum src
Definition: glext.h:6340
GLuint in
Definition: glext.h:9616
GLint left
Definition: glext.h:7726
POINT cp
Definition: magnifier.c:59
static char * dest
Definition: rtl.c:135
#define uint8_t
Definition: nsiface.idl:59
#define STATUS_SOME_NOT_MAPPED
Definition: ntstatus.h:86
static FILE * out
Definition: regtests2xml.c:44

Referenced by check_file_name_valid(), and set_label().

◆ utf8_to_utf16()

NTSTATUS utf8_to_utf16 ( WCHAR dest,
ULONG  dest_max,
ULONG dest_len,
char src,
ULONG  src_len 
)

Definition at line 811 of file btrfs.c.

811 {
813 uint8_t* in = (uint8_t*)src;
815 ULONG needed = 0, left = dest_max / sizeof(uint16_t);
816
817 for (ULONG i = 0; i < src_len; i++) {
818 uint32_t cp;
819
820 if (!(in[i] & 0x80))
821 cp = in[i];
822 else if ((in[i] & 0xe0) == 0xc0) {
823 if (i == src_len - 1 || (in[i+1] & 0xc0) != 0x80) {
824 cp = 0xfffd;
826 } else {
827 cp = ((in[i] & 0x1f) << 6) | (in[i+1] & 0x3f);
828 i++;
829 }
830 } else if ((in[i] & 0xf0) == 0xe0) {
831 if (i >= src_len - 2 || (in[i+1] & 0xc0) != 0x80 || (in[i+2] & 0xc0) != 0x80) {
832 cp = 0xfffd;
834 } else {
835 cp = ((in[i] & 0xf) << 12) | ((in[i+1] & 0x3f) << 6) | (in[i+2] & 0x3f);
836 i += 2;
837 }
838 } else if ((in[i] & 0xf8) == 0xf0) {
839 if (i >= src_len - 3 || (in[i+1] & 0xc0) != 0x80 || (in[i+2] & 0xc0) != 0x80 || (in[i+3] & 0xc0) != 0x80) {
840 cp = 0xfffd;
842 } else {
843 cp = ((in[i] & 0x7) << 18) | ((in[i+1] & 0x3f) << 12) | ((in[i+2] & 0x3f) << 6) | (in[i+3] & 0x3f);
844 i += 3;
845 }
846 } else {
847 cp = 0xfffd;
849 }
850
851 if (cp > 0x10ffff) {
852 cp = 0xfffd;
854 }
855
856 if (dest) {
857 if (cp <= 0xffff) {
858 if (left < 1)
860
861 *out = (uint16_t)cp;
862 out++;
863
864 left--;
865 } else {
866 if (left < 2)
868
869 cp -= 0x10000;
870
871 *out = 0xd800 | ((cp & 0xffc00) >> 10);
872 out++;
873
874 *out = 0xdc00 | (cp & 0x3ff);
875 out++;
876
877 left -= 2;
878 }
879 }
880
881 if (cp <= 0xffff)
882 needed += sizeof(uint16_t);
883 else
884 needed += 2 * sizeof(uint16_t);
885 }
886
887 if (dest_len)
888 *dest_len = needed;
889
890 return Status;
891}

Referenced by _Dispatch_type_().

◆ verify_device()

static NTSTATUS verify_device ( _In_ device_extension Vcb,
_Inout_ device dev 
)
static

Definition at line 5111 of file btrfs.c.

5111 {
5113 superblock* sb;
5114 ULONG to_read, cc;
5115
5116 if (!dev->devobj)
5117 return STATUS_WRONG_VOLUME;
5118
5119 if (dev->removable) {
5121
5122 Status = dev_ioctl(dev->devobj, IOCTL_STORAGE_CHECK_VERIFY, NULL, 0, &cc, sizeof(ULONG), true, &iosb);
5123
5125 ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08lx (user-induced)\n", Status);
5126
5127 if (Vcb->vde) {
5128 pdo_device_extension* pdode = Vcb->vde->pdode;
5129 LIST_ENTRY* le2;
5130 bool changed = false;
5131
5133
5134 le2 = pdode->children.Flink;
5135 while (le2 != &pdode->children) {
5137
5138 if (vc->devobj == dev->devobj) {
5139 TRACE("removing device\n");
5140
5141 remove_volume_child(Vcb->vde, vc, true);
5142 changed = true;
5143
5144 break;
5145 }
5146
5147 le2 = le2->Flink;
5148 }
5149
5150 if (!changed)
5152 }
5153 } else if (!NT_SUCCESS(Status)) {
5154 ERR("IOCTL_STORAGE_CHECK_VERIFY returned %08lx\n", Status);
5155 return Status;
5156 } else if (iosb.Information < sizeof(ULONG)) {
5157 ERR("iosb.Information was too short\n");
5158 return STATUS_INTERNAL_ERROR;
5159 }
5160
5161 dev->change_count = cc;
5162 }
5163
5164 to_read = dev->devobj->SectorSize == 0 ? sizeof(superblock) : (ULONG)sector_align(sizeof(superblock), dev->devobj->SectorSize);
5165
5167 if (!sb) {
5168 ERR("out of memory\n");
5170 }
5171
5172 Status = sync_read_phys(dev->devobj, dev->fileobj, superblock_addrs[0], to_read, (PUCHAR)sb, true);
5173 if (!NT_SUCCESS(Status)) {
5174 ERR("Failed to read superblock: %08lx\n", Status);
5175 ExFreePool(sb);
5176 return Status;
5177 }
5178
5179 if (sb->magic != BTRFS_MAGIC) {
5180 ERR("not a BTRFS volume\n");
5181 ExFreePool(sb);
5182 return STATUS_WRONG_VOLUME;
5183 }
5184
5186 ExFreePool(sb);
5187 return STATUS_WRONG_VOLUME;
5188 }
5189
5190 if (RtlCompareMemory(&sb->uuid, &Vcb->superblock.uuid, sizeof(BTRFS_UUID)) != sizeof(BTRFS_UUID)) {
5191 ERR("different UUIDs\n");
5192 ExFreePool(sb);
5193 return STATUS_WRONG_VOLUME;
5194 }
5195
5196 ExFreePool(sb);
5197
5198 dev->devobj->Flags &= ~DO_VERIFY_VOLUME;
5199
5200 return STATUS_SUCCESS;
5201}
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140

Referenced by verify_volume().

◆ verify_volume()

static NTSTATUS verify_volume ( _In_ PDEVICE_OBJECT  devobj)
static

Definition at line 5203 of file btrfs.c.

5203 {
5204 device_extension* Vcb = devobj->DeviceExtension;
5206 LIST_ENTRY* le;
5207 uint64_t failed_devices = 0;
5208 bool locked = false, remove = false;
5209
5210 if (!(Vcb->Vpb->Flags & VPB_MOUNTED))
5211 return STATUS_WRONG_VOLUME;
5212
5213 if (!ExIsResourceAcquiredExclusive(&Vcb->tree_lock)) {
5214 ExAcquireResourceExclusiveLite(&Vcb->tree_lock, true);
5215 locked = true;
5216 }
5217
5218 if (Vcb->removing) {
5219 if (locked) ExReleaseResourceLite(&Vcb->tree_lock);
5220 return STATUS_WRONG_VOLUME;
5221 }
5222
5224
5225 InterlockedIncrement(&Vcb->open_files); // so pnp_surprise_removal doesn't uninit the device while we're still using it
5226
5227 le = Vcb->devices.Flink;
5228 while (le != &Vcb->devices) {
5230
5232 if (!NT_SUCCESS(Status)) {
5233 failed_devices++;
5234
5235 if (dev->devobj && Vcb->options.allow_degraded)
5236 dev->devobj = NULL;
5237 }
5238
5239 le = le->Flink;
5240 }
5241
5242 InterlockedDecrement(&Vcb->open_files);
5243
5244 if (Vcb->removing && Vcb->open_files == 0)
5245 remove = true;
5246
5247 if (locked)
5248 ExReleaseResourceLite(&Vcb->tree_lock);
5249
5250 if (remove) {
5251 uninit(Vcb);
5252 return Status;
5253 }
5254
5255 if (failed_devices == 0 || (Vcb->options.allow_degraded && failed_devices < Vcb->superblock.num_devices)) {
5256 Vcb->Vpb->RealDevice->Flags &= ~DO_VERIFY_VOLUME;
5257
5258 return STATUS_SUCCESS;
5259 }
5260
5261 return Status;
5262}
static NTSTATUS verify_device(_In_ device_extension *Vcb, _Inout_ device *dev)
Definition: btrfs.c:5111
int remove
Definition: msacm.c:1366
uint64_t num_devices
Definition: btrfs.h:237
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347

Referenced by _Dispatch_type_().

◆ WdmlibRtlIsNtDdiVersionAvailable()

BOOLEAN WdmlibRtlIsNtDdiVersionAvailable ( ULONG  Version)

Variable Documentation

◆ __pad0__

end __pad0__

Definition at line 4307 of file btrfs.c.

◆ addr

Definition at line 2995 of file btrfs.c.

◆ address

r treeholder address = addr

Definition at line 3007 of file btrfs.c.

◆ boot_lock

ERESOURCE boot_lock

Definition at line 110 of file btrfs.c.

Referenced by _Function_class_(), check_system_root(), disk_arrival(), and volume_arrival().

◆ boot_subvol

uint64_t boot_subvol
extern

Definition at line 34 of file boot.c.

Referenced by check_boot_options(), and mount_vol().

◆ busobj

Definition at line 66 of file btrfs.c.

Referenced by _Function_class_(), add_volume_device(), do_shutdown(), and remove_volume_child().

◆ checked_for_orphans

r checked_for_orphans = false

Definition at line 3013 of file btrfs.c.

◆ debug_log_level

uint32_t debug_log_level = 0

Definition at line 71 of file btrfs.c.

Referenced by _Function_class_(), and read_registry().

◆ degraded_wait

bool degraded_wait = true

Definition at line 107 of file btrfs.c.

Referenced by _Function_class_(), and mount_vol().

◆ degraded_wait_handle

HANDLE degraded_wait_handle = NULL

Definition at line 106 of file btrfs.c.

Referenced by _Function_class_().

◆ device_name

◆ dirty

◆ diskacc

bool diskacc = false

Definition at line 101 of file btrfs.c.

Referenced by __attribute__(), _Function_class_(), do_read(), init_file_cache(), and read_data().

◆ do_xor

◆ dosdevice_name

const WCHAR dosdevice_name[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\','B','t','r','f','s',0}
static

Definition at line 61 of file btrfs.c.

Referenced by _Function_class_().

◆ dropped

r dropped = false

Definition at line 3014 of file btrfs.c.

Referenced by CAutoComplete::GetDropDownStatus(), and journal_skip_recovery().

◆ drvobj

◆ fcbs_version

r fcbs_version = 0

Definition at line 3012 of file btrfs.c.

Referenced by open_fcb().

◆ fCcCopyReadEx

tCcCopyReadEx fCcCopyReadEx

Definition at line 91 of file btrfs.c.

Referenced by _Function_class_(), and do_read().

◆ fCcCopyWriteEx

tCcCopyWriteEx fCcCopyWriteEx

Definition at line 92 of file btrfs.c.

Referenced by __attribute__(), and _Function_class_().

◆ fCcSetAdditionalCacheAttributesEx

tCcSetAdditionalCacheAttributesEx fCcSetAdditionalCacheAttributesEx

Definition at line 93 of file btrfs.c.

Referenced by _Function_class_(), and init_file_cache().

◆ fFsRtlAreThereCurrentOrInProgressFileLocks

tFsRtlAreThereCurrentOrInProgressFileLocks fFsRtlAreThereCurrentOrInProgressFileLocks

Definition at line 100 of file btrfs.c.

Referenced by _Function_class_(), and fsctl_oplock().

◆ fFsRtlCheckLockForOplockRequest

tFsRtlCheckLockForOplockRequest fFsRtlCheckLockForOplockRequest

Definition at line 99 of file btrfs.c.

Referenced by _Function_class_(), and fsctl_oplock().

◆ fFsRtlGetEcpListFromIrp

tFsRtlGetEcpListFromIrp fFsRtlGetEcpListFromIrp

Definition at line 96 of file btrfs.c.

Referenced by _Function_class_(), and file_create().

◆ fFsRtlGetNextExtraCreateParameter

tFsRtlGetNextExtraCreateParameter fFsRtlGetNextExtraCreateParameter

Definition at line 97 of file btrfs.c.

Referenced by _Function_class_(), and file_create().

◆ fFsRtlUpdateDiskCounters

tFsRtlUpdateDiskCounters fFsRtlUpdateDiskCounters

Definition at line 94 of file btrfs.c.

Referenced by __attribute__(), _Function_class_(), and read_data().

◆ fFsRtlValidateReparsePointBuffer

tFsRtlValidateReparsePointBuffer fFsRtlValidateReparsePointBuffer

Definition at line 98 of file btrfs.c.

Referenced by _Function_class_(), get_reparse_block(), and set_reparse_point2().

◆ finished_probing

bool finished_probing = false

Definition at line 105 of file btrfs.c.

Referenced by _Function_class_(), and mount_vol().

◆ fIoUnregisterPlugPlayNotificationEx

tIoUnregisterPlugPlayNotificationEx fIoUnregisterPlugPlayNotificationEx

Definition at line 95 of file btrfs.c.

Referenced by _Function_class_(), do_shutdown(), free_vol(), and remove_volume_child().

◆ fPsUpdateDiskCounters

tPsUpdateDiskCounters fPsUpdateDiskCounters

Definition at line 90 of file btrfs.c.

Referenced by _Function_class_(), and do_read().

◆ generation

◆ gid_map_list

LIST_ENTRY gid_map_list

Definition at line 68 of file btrfs.c.

Referenced by _Function_class_().

◆ global_loading_lock

◆ id

r id = id

Definition at line 2995 of file btrfs.c.

Referenced by create_root().

◆ is_windows_8

bool is_windows_8

Definition at line 111 of file btrfs.c.

Referenced by _Function_class_().

◆ lastinode

r lastinode = 0

Definition at line 3027 of file btrfs.c.

Referenced by flush_refs().

◆ log_device

UNICODE_STRING log_device

Definition at line 89 of file btrfs.c.

Referenced by _Function_class_(), and read_registry().

◆ log_file

UNICODE_STRING log_file

Definition at line 89 of file btrfs.c.

Referenced by _Function_class_(), logSource(), and START_TEST().

◆ log_started

bool log_started = false

Definition at line 88 of file btrfs.c.

Referenced by _Function_class_().

◆ mapping_lock

ERESOURCE mapping_lock

Definition at line 103 of file btrfs.c.

Referenced by _Function_class_(), find_gid(), read_registry(), sid_to_uid(), and uid_to_sid().

◆ master_devobj

◆ mount_allow_degraded

uint32_t mount_allow_degraded = 0

Definition at line 83 of file btrfs.c.

Referenced by allow_degraded_mount(), read_registry(), and registry_load_volume_options().

◆ mount_clear_cache

uint32_t mount_clear_cache = 0

Definition at line 82 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_compress

uint32_t mount_compress = 0

Definition at line 72 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_compress_force

uint32_t mount_compress_force = 0

Definition at line 73 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_compress_type

uint32_t mount_compress_type = 0

Definition at line 74 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_flush_interval

uint32_t mount_flush_interval = 30

Definition at line 77 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_max_inline

uint32_t mount_max_inline = 2048

Definition at line 78 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_no_barrier

uint32_t mount_no_barrier = 0

Definition at line 80 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_no_root_dir

uint32_t mount_no_root_dir = 0

Definition at line 85 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_no_trim

uint32_t mount_no_trim = 0

Definition at line 81 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_nodatacow

uint32_t mount_nodatacow = 0

Definition at line 86 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_readonly

uint32_t mount_readonly = 0

Definition at line 84 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_skip_balance

uint32_t mount_skip_balance = 0

Definition at line 79 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_zlib_level

uint32_t mount_zlib_level = 3

Definition at line 75 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mount_zstd_level

uint32_t mount_zstd_level = 3

Definition at line 76 of file btrfs.c.

Referenced by read_registry(), and registry_load_volume_options().

◆ mountmgr_thread_event

KEVENT mountmgr_thread_event

Definition at line 108 of file btrfs.c.

Referenced by _Function_class_(), and do_shutdown().

◆ mountmgr_thread_handle

HANDLE mountmgr_thread_handle = NULL

Definition at line 106 of file btrfs.c.

Referenced by _Function_class_().

◆ no_pnp

uint32_t no_pnp = 0

Definition at line 87 of file btrfs.c.

Referenced by add_volume_device(), bus_pnp(), free_vol(), read_registry(), and remove_volume_child().

◆ nonpaged

Definition at line 3018 of file btrfs.c.

◆ notification_entry

void* notification_entry = NULL

Definition at line 102 of file btrfs.c.

Referenced by _Function_class_(), and do_shutdown().

◆ notification_entry2

void * notification_entry2 = NULL

Definition at line 102 of file btrfs.c.

Referenced by _Function_class_(), and do_shutdown().

◆ notification_entry3

void * notification_entry3 = NULL

Definition at line 102 of file btrfs.c.

Referenced by _Function_class_(), and do_shutdown().

◆ num_reads

uint64_t num_reads = 0

Definition at line 67 of file btrfs.c.

Referenced by sync_read_phys().

◆ parent

r parent = 0

Definition at line 3010 of file btrfs.c.

Referenced by __rb_erase_color(), __rb_rotate_left(), __rb_rotate_right(), _check_item(), _ILCreateControlPanel(), _ILCreatePrinters(), _insert_adjacent_elem(), CMenuDeskBar::_IsSubMenuParent(), CMenuBand::_SetParentBand(), _test_elem_get_parent(), _test_node_get_parent(), acpi_bus_add(), acpi_bus_scan(), acpi_bus_set_power(), add_feature_child(), add_file(), add_folder_child(), add_inode_ref(), add_item(), add_param_to_tree(), add_purpose_dlg_proc(), add_shared_block_extent_ref(), add_shared_data_extent_ref(), adns__query_done(), Bin::adopt(), alloc_object(), append_inf_file(), arbfp_free_ffpshader(), atifs_free_ffpshader(), ShellFolder::attach(), audiomediastream_create(), audiostreamsample_create(), BtrfsSend::BrowseParent(), BrsFolder_NewFolder(), buffer_init(), BUTTON_CheckAutoRadioButton(), BUTTON_WindowProc(), ButtonWndProc_common(), CascadeChildWindows(), CB_Paint(), CB_ThemedPaint(), check_dialog_style(), check_dir(), checkc_queue_childw(), BtrfsRecv::cmd_snapshot(), BtrfsRecv::cmd_subvol(), co_WinPosArrangeIconicWindows(), FxObject::Commit(), CUiMeasure::ComputeMeasure(), create_button(), create_dialog(), create_listbox(), create_listview_controlW(), create_parent(), create_plugin_window(), create_shell_embedding_hwnd(), create_sub_body(), create_syslink(), create_tool_window(), create_trackbar(), create_trackbar2(), create_window_tree(), CreateStatusWindowA(), CreateStatusWindowW(), CreateUpDownControl(), CryptUIWizDigitalSign(), ctrl_container_reparent(), d3d8_device_Release(), d3d8_indexbuffer_wined3d_object_destroyed(), d3d8_pixelshader_wined3d_object_destroyed(), d3d8_swapchain_wined3d_object_released(), d3d8_texture_wined3d_object_destroyed(), d3d8_vertexbuffer_wined3d_object_destroyed(), d3d8_vertexdeclaration_wined3d_object_destroyed(), d3d8_vertexshader_wined3d_object_destroyed(), d3d9_indexbuffer_wined3d_object_destroyed(), d3d9_pixelshader_wined3d_object_destroyed(), d3d9_swapchain_wined3d_object_released(), d3d9_texture_wined3d_object_destroyed(), d3d9_vertexbuffer_wined3d_object_destroyed(), d3d9_vertexdeclaration_wined3d_object_destroyed(), d3d9_vertexshader_wined3d_object_destroyed(), d3d_device3_GetRenderState(), d3drm3_CreateFrame(), d3drm_frame1_GetParent(), d3drm_frame2_GetParent(), d3drm_frame3_AddChild(), d3drm_frame3_GetParent(), d3drm_mesh_builder3_GetParentMesh(), d3dx_parse_effect_typedef(), ddraw_frontbuffer_destroyed(), ddraw_surface_wined3d_object_destroyed(), ddraw_texture_wined3d_object_destroyed(), ddrawmediastream_create(), ddrawstreamsample_create(), DECLARE_INTERFACE_(), decrease_extent_refcount(), DefMDIChildProcW(), delegation_create(), delete_directory(), delete_key(), device_init(), device_parent_surface_created(), device_parent_volume_created(), dialog_create(), dialog_create_window(), DIALOG_CreateIndirect(), dialog_run_message_loop(), CMenuFocusManager::DisableMouseTrack(), display_cert_manager(), display_cpl_sheets(), do_create_snapshot(), do_loop(), BtrfsRecv::do_recv(), doChild(), dwarf2_parse_enumerator(), dwarf2_parse_udt_member(), dwarflookupchildtag(), dwarflookupsubname(), dwarfnextsymat(), empty_dlg_proc3(), enum_gac_assemblies(), enum_gac_assembly_dirs(), EnumSystemGeoID(), enumx_allocate(), event_do_dialog(), ExitWindowsDialog(), ext2_add_entry(), ext2_mkdir(), fcb_get_sd(), fill_content_tree(), BookmarkList::fill_tree(), find_extent_shared_data_refcount(), find_extent_shared_tree_refcount(), find_feature_children(), find_folder_children(), find_or_create_directory(), find_path(), find_path_len(), find_send_dir(), find_window(), fire_event_obj(), FloatUp(), folder_get_ParentFolder(), found_path(), GB_Paint(), GB_ThemedPaint(), geometry_shader_init(), get_child_index(), get_ea_value(), get_first_item(), get_flags(), ShellPath::get_folder(), get_hierarchy_data_from_tree_item(), get_item(), CDefViewDual::get_Parent(), CCommonFolder< TSelf, TItemId, TExtractIcon >::GetUIObjectOf(), ShellPath::GetUIObjectOf(), handle_getexattr(), HTMLOuterWindow_Create(), HTMLScriptElement_put_src(), HTMLScriptElement_put_text(), HTMLTxtRange_parentElement(), HUF_buildCTable_wksp(), icb_hostaddr(), icb_ptr(), IDirectPlay3AImpl_AddGroupToGroup(), IDirectPlay3AImpl_CreateGroupInGroup(), IDirectPlay3AImpl_DeleteGroupFromGroup(), IDirectPlay3AImpl_GetGroupParent(), IDirectPlay3Impl_AddGroupToGroup(), IDirectPlay3Impl_CreateGroupInGroup(), IDirectPlay3Impl_DeleteGroupFromGroup(), IDirectPlay3Impl_GetGroupParent(), IDirectPlay4AImpl_AddGroupToGroup(), IDirectPlay4AImpl_DeleteGroupFromGroup(), IDirectPlay4AImpl_GetGroupParent(), IDirectPlay4Impl_AddGroupToGroup(), IDirectPlay4Impl_DeleteGroupFromGroup(), IDirectPlay4Impl_GetGroupParent(), CToolbarProxy::Initialize(), CRegistryFolderExtractIcon::Initialize(), CFolderItems::Initialize(), insert_adjacent_node(), insert_content_item(), IntDefWindowProc(), IntGetWindowLong(), is_valid_sub_constant(), FxUsbDevice::IsObjectDisposedOnRemove(), keylist_GetCount(), keylist_RemoveAllKeys(), LaunchInternetControlPanel(), LaunchSiteCertDialog(), link_notify_test(), load_progid(), LoadSystemIni(), LogoffWindowsDialog(), lookup_entry(), lookup_symlink(), match_dw_attr_imp(), match_guid_attr_imp(), match_qw_attr_imp(), match_strw_attr_imp(), MCIWND_Create(), mdi_child_wnd_proc_2(), merge_old_directory_into_tree(), MetadataHandlerEnum_Create(), midi_in_port_create(), midi_out_port_create(), MMDevPropStore_Create(), msi_get_target_folder(), MSI_GetFeatureCost(), msi_resolve_source_folder(), msi_resolve_target_folder(), msi_seltree_add_child_features(), MSIREG_DeleteUninstallKey(), name_cache_find_or_create(), name_cache_insert(), name_cache_lookup(), name_cache_remove(), name_cache_search(), name_cache_unlink_children_recursive(), CExplorerBand::NavigateToPIDL(), NC_HandleNCLButtonDown(), need_delegation(), new_body_entry(), new_richedit(), new_richedit_with_style(), new_richeditW(), new_static_wnd(), new_window(), new_windowW(), next_xml_elem(), nfs41_create(), nfs41_delegation_granted(), nfs41_fs_locations(), nfs41_lookup(), nfs41_name_cache_delegreturn(), nfs41_name_cache_insert(), nfs41_name_cache_lookup(), nfs41_name_cache_remove(), nfs41_open(), nfs41_remove(), nfs41_superblock_for_fh(), nsTooltipTextProvider_GetNodeText(), OB_Paint(), OleObject_SetClientSite(), ShellBrowser::OnDefaultCommand(), open_fcb_stream(), open_fileref(), open_fileref_by_inode(), open_update_cache(), FxDevice::OpenSettingsKey(), PAGER_EraseBackground(), parent_wnd_proc(), parse_application_elem(), parse_assembly_elem(), parse_assembly_identity_elem(), parse_binding_redirect_elem(), parse_clr_class_elem(), parse_clr_surrogate_elem(), parse_com_class_elem(), parse_com_class_progid(), parse_com_interface_external_proxy_stub_elem(), parse_cominterface_proxy_stub_elem(), parse_compatibility_application_elem(), parse_compatibility_elem(), parse_dependency_elem(), parse_dependent_assembly_elem(), parse_description_elem(), parse_expect_end_elem(), parse_file_elem(), parse_manifest_buffer(), parse_noinherit_elem(), parse_noinheritable_elem(), parse_requested_execution_level_elem(), parse_requested_privileges_elem(), parse_security_elem(), parse_settings_elem(), parse_supportedos_elem(), parse_trust_info_elem(), parse_typelib_elem(), parse_unknown_elem(), parse_window_class_elem(), parse_windows_settings_elem(), Path(), PB_Paint(), PB_ThemedPaint(), pixel_shader_init(), Window::PostParent(), CMenuFocusManager::ProcessMouseMove(), prop_enum_copy_cb(), PROPSHEET_PropertySheet(), psh_hint_align(), query_feature_state(), r_verify_pidl(), rb_erase(), rb_insert(), rb_insert_color(), rb_link_node(), rb_next(), rb_prev(), rb_replace_node(), REBAR_GetNotifyParent(), REBAR_Notify(), REBAR_SetParent(), recover_open_grace(), recover_open_no_grace(), BtrfsRecv::recv_thread(), remove_root_extents(), reset_enum_callback(), resize_template_hook(), resource_init(), RestartDialogEx(), root_dialog(), RunDlgProc(), scan_subkeys(), SdbFindFirstTag(), SdbFindNextTag(), SdbGetFirstChild(), SdbGetNextChild(), seamless_process_line(), search_dr(), SeiReadInExclude(), send_add_dir(), send_add_tlv_path(), send_subvol(), send_unlink_command(), Window::SendParent(), SendSubvolW(), server_lookup(), server_lookup_loop(), set_de_path(), set_ea_value(), set_item_parents(), SetupDiGetClassDevsA(), SetupDiGetClassDevsExA(), SetupDiGetClassDevsExW(), SetupDiGetClassDevsW(), shader_init(), ShellFolder::ShellFolder(), show_cert_chain(), show_edit_cert_properties_dialog(), ShowClientAuthCerts(), ShowX509EncodedCertificate(), SHRunControlPanel(), ShellPath::split(), srv_wined3d_object_destroyed(), BtrfsSend::StartSend(), STATIC_SendWmCtlColorStatic(), subdirs(), surface_wined3d_object_destroyed(), sw_handle_restack(), swapchain_init(), symt_get_address(), synth_port_create(), test_AttributesRegistration(), test_button_data(), test_button_messages(), test_changing_selection_styles(), test_child_window_from_point(), test_children_zorder(), test_create_tooltip(), test_CreateWindow(), test_customdraw(), test_device_interface_key(), test_dialog_parent(), test_EM_AUTOURLDETECT(), test_EM_SETTEXTEX(), test_EN_LINK(), test_eventMask(), test_extension_wndproc(), test_extents(), test_frame(), test_GetListBoxInfo(), test_hwnd_message(), test_ime_wnd_proc(), test_init_storage(), test_insert_adjacent_elems(), test_item_auto_format(), test_LB_SETCURSEL(), test_LBS_NODATA(), test_MCIWndCreate(), test_MDI_create(), test_missing_lbuttonup(), test_nccalcscroll(), test_null_wndproc(), test_ok_wndproc(), test_ownerdraw(), test_parent_wndproc(), test_rtl_layout(), test_scrolldc(), test_scrollvalidate(), test_set_count(), test_setinfo(), test_SetMenu(), test_SetParent(), test_track(), test_TTM_ADDTOOL(), test_TVS_SINGLEEXPAND(), test_update_region(), test_window(), test_window_tree(), test_WM_MEASUREITEM(), test_wm_notify(), test_WM_NOTIFY(), test_wm_notifyformat(), test_xmlelem(), testGetIssuerCert(), texture1d_init(), texture_init(), BtrfsSend::Thread(), TileChildWindows(), TOOLBAR_AutoSize(), TOOLBAR_EraseBackground(), TransactedSnapshotImpl_FindFirstChild(), TransactedSnapshotImpl_FindNextChild(), TREEVIEW_DeleteItem(), TREEVIEW_DrawItemLines(), TREEVIEW_EnsureVisible(), TREEVIEW_InsertAfter(), TREEVIEW_InsertBefore(), TREEVIEW_IsChildOf(), TREEVIEW_Sort(), TWAIN_UserSelect(), UB_Paint(), ui_seamless_create_window(), vertex_shader_init(), vertexdeclaration_init(), view_wined3d_object_destroyed(), VMR9DefaultAllocatorPresenterImpl_create(), volume_wined3d_object_destroyed(), volumetexture_init(), WbemPathKeyList_create(), window_from_point_proc(), WindowFromAccessibleObject(), wine_rb_put(), wine_rb_remove(), wined3d_blend_state_create(), wined3d_buffer_create(), wined3d_event_query_create(), wined3d_occlusion_query_create(), wined3d_overflow_query_create(), wined3d_pipeline_query_create(), wined3d_query_create(), wined3d_query_init(), wined3d_rasterizer_state_create(), wined3d_rendertarget_view_create(), wined3d_rendertarget_view_create_from_sub_resource(), wined3d_rendertarget_view_init(), wined3d_rendertarget_view_set_parent(), wined3d_resource_set_parent(), wined3d_sampler_create(), wined3d_sampler_init(), wined3d_shader_create_cs(), wined3d_shader_create_ds(), wined3d_shader_create_gs(), wined3d_shader_create_hs(), wined3d_shader_create_ps(), wined3d_shader_create_vs(), wined3d_shader_resource_view_create(), wined3d_shader_resource_view_init(), wined3d_so_statistics_query_create(), wined3d_statistics_query_create(), wined3d_swapchain_create(), wined3d_texture_create(), wined3d_texture_init(), wined3d_texture_set_sub_resource_parent(), wined3d_timestamp_disjoint_query_create(), wined3d_timestamp_query_create(), wined3d_unordered_access_view_create(), wined3d_unordered_access_view_init(), wined3d_vertex_declaration_create(), wined3d_vertex_declaration_create_from_fvf(), WINHELP_GetPopupWindowInfo(), write_iface_procformatstring(), xmlFreeDocElementContent(), xmlSAX2Comment(), xmlSAX2ProcessingInstruction(), xmlSAX2StartElementNs(), xsltAddChild(), xsltCheckInstructionElement(), xsltCheckParentElement(), xsltCheckTopLevelElement(), xsltNewStylesheetInternal(), xsltStylePreCompute(), xsltTestCompMatchDirect(), and xsltTestPredicateMatch().

◆ pdo_list

◆ pdo_list_lock

◆ pno_pnp

DeviceObject Flags &* pno_pnp
Initial value:

Definition at line 4258 of file btrfs.c.

◆ r

◆ received

◆ registry_path

UNICODE_STRING registry_path

Definition at line 89 of file btrfs.c.

Referenced by _Function_class_().

◆ reserved

uint16_t reserved = NULL

Definition at line 3006 of file btrfs.c.

Referenced by apc(), bind_callback_OnLowResource(), bind_callback_OnStartBinding(), BindStatusCallback_OnLowResource(), BLAKE2_PACKED(), cache_CreateAssemblyCacheItem(), cache_Reserved(), CoDisableCallCancellation(), CoDisconnectObject(), CoEnableCallCancellation(), CompareSecurityIds(), CompareStringEx(), CoRegisterSurrogateEx(), CreateAssemblyCache(), CreateAssemblyNameObject(), CreateAsyncBindCtx(), CreateAsyncBindCtxEx(), CreateBindCtx(), CreateFontPackage(), d3d_execute_buffer_Optimize(), d3d_execute_buffer_Validate(), DataCache_UpdateCache(), debugclient_StartProcessServer(), debugclient_StartProcessServerWide(), DECLARE_INTERFACE_(), DllMain(), DownloadBSC_OnLowResource(), downloadcb_OnLowResource(), downloadcb_OnStartBinding(), EnumSystemLocalesEx(), ExternalConnection_AddConnection(), ExternalConnection_ReleaseConnection(), fake_dll_main(), FTPGetFiles3(), FTPGetOneFile3(), FTPPutFiles3(), FTPPutOneFile3(), CVfdShExt::GetCommandString(), GetRunningObjectTable(), gxv_mort_subtable_type0_entry_validate(), gxv_mort_subtable_type1_entry_validate(), gxv_morx_subtable_type0_entry_validate(), gxv_morx_subtable_type1_entry_validate(), gxv_morx_subtable_type2_entry_validate(), gxv_trak_validate(), HlinkResolveMonikerForData(), hls_ReadyToNavigate(), IDirectPlayImpl_SaveSession(), image_uses_split_segs(), InternetDeInitializeAutoProxyDll(), InternetGetCookieExA(), InternetGetCookieExW(), InternetSetCookieExW(), InternetTimeToSystemTimeA(), InternetTimeToSystemTimeW(), IsNTAdmin(), ITSS_IStorageImpl_OpenStorage(), ITStorageImpl_StgCreateDocfile(), ITStorageImpl_StgOpenStorage(), LCMapStringEx(), lfn_add_slot(), macho_map_file(), MAPIAddress(), MAPIDeleteMail(), MAPIDetails(), MAPIFindNext(), MAPILogoff(), MAPILogon(), MAPIReadMail(), MAPIResolveName(), MAPISaveMail(), MAPISendDocuments(), MAPISendMail(), MAPISendMailW(), MsiSourceListForceResolutionA(), MsiSourceListForceResolutionW(), msvcrt_init_exception(), NetShareDel(), NetShareDelSticky(), NetWkstaUserGetInfo(), NetWkstaUserSetInfo(), OleInitialize(), pointer_default(), PropertyStorage_ReadHeaderFromStream(), ProxyBindStatusCallback_OnLowResource(), RegEnumValueW(), RegisterFormatEnumerator(), RegQueryValueExA(), RegQueryValueExW(), CProgressDialog::SetCancelMsg(), CProgressDialog::SetLine(), SetupDiGetClassDevsExA(), SetupDiGetClassDevsExW(), SetupUninstallOEMInfA(), SetupUninstallOEMInfW(), SHLoadIndirectString(), SHRestricted2A(), SHRestricted2W(), START_TEST(), CProgressDialog::StartProgressDialog(), StgCreateDocfile(), StgCreatePropSetStg(), StgCreatePropStg(), StgCreateStorageEx(), StgOpenPropStg(), StgOpenStorage(), StgOpenStorageEx(), STORAGE_CreateOleStream(), StorageBaseImpl_OpenStorage(), test_bsc_marshaling(), test_pack_MIDIHDR(), test_pack_WAVEHDR(), test_stgcreatestorageex(), CProgressDialog::Timer(), WinHttpConnect(), WinHttpReceiveResponse(), WinHttpSetStatusCallback(), WMCreateReader(), WMCreateWriter(), woff_open_font(), and XInputGetKeystroke().

◆ sb

Definition at line 4261 of file btrfs.c.

Referenced by _tiffSizeProc(), add_volume_device(), Subdivider::bbox(), btrfs_read_chunk_tree(), btrfs_read_sys_chunk_array(), calc_superblock_checksum(), check_superblock_checksum(), compat_isdir(), Control_CreateListView(), Control_WndProc(), convert_latin1(), convert_utf16bom(), convert_utf8(), create_browser_service(), descriptor_loc(), detach_browser_service(), device_still_valid(), do_one_pass(), ext2_update_dynamic_rev(), Ext2FreeBlock(), Ext2FreeInode(), Ext2InitializeVcb(), Ext2LoadGroup(), Ext2LoadGroupBH(), Ext2NewBlock(), Ext2NewInode(), Ext2RecoverJournal(), Ext2UpdateGroupDirStat(), ext3_add_entry(), ext3_bg_has_super(), ext3_dentry_get_data(), ext3_find_entry(), ext3_inode_blocks(), ext3_inode_blocks_set(), ext3_is_dir_empty(), ext3_set_de_type(), ext3_warning(), ext4_bg_num_gdb(), ext4_bg_num_gdb_meta(), ext4_bg_num_gdb_nometa(), ext4_block_bitmap(), ext4_block_bitmap_set(), ext4_block_in_group(), ext4_check_descriptors(), ext4_count_dirs(), ext4_count_free_blocks(), ext4_count_free_inodes(), ext4_ext_remove_space(), ext4_free_blks_count(), ext4_free_blks_set(), ext4_free_inodes_count(), ext4_free_inodes_set(), ext4_get_group_desc(), ext4_get_group_no_and_offset(), ext4_group_used_meta_blocks(), ext4_init_block_bitmap(), ext4_init_inode_bitmap(), ext4_inode_bitmap(), ext4_inode_bitmap_set(), ext4_inode_table(), ext4_inode_table_set(), ext4_itable_unused_count(), ext4_itable_unused_set(), EXT4_SB(), ext4_used_dirs_count(), ext4_used_dirs_set(), extents_bread(), extents_bwrite(), fill_pinfo_side(), find_devices(), FsRecIsFfs1Volume(), FsRecIsFfs2Volume(), FsRecIsReiserfsVolume(), FT_MulFix(), id3_to_utf8(), III_antialias(), III_hybrid(), III_i_stereo(), init_path(), is_device_part_of_mounted_btrfs_raid(), is_mounted_multi_device(), IShellBrowserImpl_Construct(), journal_check_available_features(), journal_check_used_features(), journal_convert_superblock_v1(), journal_get_superblock(), journal_load(), journal_recover(), journal_reset(), journal_set_features(), journal_skip_recovery(), journal_update_format(), journal_update_superblock(), journal_wipe(), load_superblock(), main(), map_bh(), mp_add(), mp_sub(), mpg123_add_string(), mpg123_add_substring(), mpg123_chomp_string(), mpg123_delete_string(), mpg123_free_string(), mpg123_grow_string(), mpg123_init_string(), mpg123_new_string(), mpg123_resize_string(), mpg123_set_string(), mpg123_set_substring(), mpg123_store_utf8(), mpg123_strlen(), read_superblock(), remove_superblocks(), sb_bread(), sb_find_get_block(), sb_getblk(), sb_getblk_zero(), searchonefile(), slurpstring(), still_has_superblock(), stime_file(), store_id3_text(), stub_manager_new_ifstub(), test_ShellWindows(), test_vol(), update_backup_superblock(), verify_device(), write_superblock(), and write_superblocks().

◆ send_ops

r send_ops = 0

Definition at line 3011 of file btrfs.c.

◆ shutting_down

bool shutting_down = false

Definition at line 109 of file btrfs.c.

Referenced by _Function_class_(), and do_shutdown().

◆ Status

◆ STATUS_SUCCESS

◆ to_read

◆ tp

Initial value:

Definition at line 2996 of file btrfs.c.

Referenced by __attribute__(), __rpcb_findaddr_timed(), __tcp_checksum_complete(), _Function_class_(), _getsystime(), _i64tow(), _setsystime(), _TIFFprintAsciiBounded(), _ui64tow(), add_balance_item(), add_checksum_entry(), add_data_reloc(), add_device(), add_metadata_reloc(), add_metadata_reloc_parent(), add_parents(), add_root_item_to_cache(), add_root_ref(), AddDeviceW(), allocate_cache_chunk(), balance_data_chunk(), balance_metadata_chunk(), Mapdesc::calcPartialVelocity(), check_for_orphans_root(), check_inode_used(), clear_free_space_cache(), clnt_create_timed(), clnt_create_vers_timed(), clnt_tp_create_timed(), convert_old_extent(), create_root(), create_stream(), create_subvol(), data_reloc_add_tree_edr(), decrease_extent_refcount(), delete_root_ref(), do_create_snapshot(), do_packet(), do_splits(), do_write2(), domap(), draw_cap(), draw_poly(), drop_chunk(), drop_root(), EnablePrivilege(), find_chunk_usage(), find_default_subvol(), find_disk_holes(), find_extent_data_refcount(), find_extent_shared_data_refcount(), find_extent_shared_tree_refcount(), find_send_dir(), find_subvol(), finish_removing_device(), flush_changed_dev_stats(), flush_changed_extent(), flush_fcb(), flush_subvol(), FormatEx2(), get_dir_last_child(), get_extent_flags(), get_extent_refcount(), get_last_inode(), get_ldnumber(), get_orphan_name(), getit(), GetThemeBool(), GetThemeColor(), GetThemeEnumValue(), GetThemeFilename(), GetThemeFont(), GetThemeInt(), GetThemeIntList(), GetThemeMargins(), GetThemeMetric(), GetThemePosition(), GetThemePropertyOrigin(), GetThemeRect(), GetThemeString(), GetThemeSysBool(), GetThemeSysColor(), GetThemeSysFont(), GetThemeSysInt(), GetThemeSysSize(), GetThemeSysString(), if(), increase_extent_refcount(), is_extent_unique(), is_tree_unique(), load_chunk_root(), load_csum(), load_dir_children(), load_free_space_cache(), load_stored_free_space_cache(), load_stored_free_space_tree(), log_file_checksum_error(), log_unrecoverable_error(), look_for_balance_item(), look_for_collision(), look_for_roots(), ME_InsertEndParaFromCursor(), ME_InsertTextFromCursor(), ME_JoinParagraphs(), ME_PrepareParagraphForWrapping(), ME_WrapTextParagraph(), mget(), mount_vol(), mput(), MSSTYLES_FindProperty(), MSSTYLES_GetPropertyBool(), MSSTYLES_GetPropertyColor(), MSSTYLES_GetPropertyFont(), MSSTYLES_GetPropertyInt(), MSSTYLES_GetPropertyIntList(), MSSTYLES_GetPropertyMargins(), MSSTYLES_GetPropertyPosition(), MSSTYLES_GetPropertyRect(), MSSTYLES_GetPropertyString(), MSSTYLES_LFindProperty(), NtQueryInformationToken(), open_fcb(), open_fcb_stream(), open_fileref_by_inode(), parse_date(), PauseBalanceW(), Privilege(), query_dir_item(), RecvSubvolGUIW(), RecvSubvolW(), remove_balance_item(), RemoveDeviceW(), ResetStatsW(), ResizeDeviceW(), RtlIntegerToUnicode(), scrub_chunk(), scrub_chunk_raid56(), scrub_chunk_raid56_stripe_run(), send_add_tlv_clone_path(), send_extent_data(), send_inode(), send_inode_extref(), send_inode_ref(), send_read_symlink(), send_xattr(), SendData(), SendSubvolGUIW(), SendSubvolW(), SeQueryInformationToken(), set_privileges(), SetPrivilege(), shared_tree_is_unique(), ShowScrubW(), StartBalanceW(), StartScrubW(), StopBalanceW(), StopScrubW(), tcp_check_req(), tcp_clear_options(), tcp_fast_path_on(), tcp_init_cwnd(), tcp_may_send_now(), tcp_paws_check(), tcp_snd_test(), test_AdjustTokenPrivileges(), TIFFMergeFieldInfo(), TIFFSwabArrayOfTriples(), trim_unalloc_space(), try_clone(), try_clone_edr(), update_backup_superblock(), update_changed_extent_ref(), update_chunk_cache(), update_chunk_cache_tree(), update_chunk_usage(), update_dev_item(), update_extent_flags(), update_extent_level(), update_root_backref(), update_root_root(), UXTHEME_LoadImage(), UXTHEME_SelectImage(), write_metadata_items(), and write_trees().

◆ tree

r treeholder tree = NULL

Definition at line 3008 of file btrfs.c.

◆ uid_map_list

LIST_ENTRY uid_map_list

Definition at line 68 of file btrfs.c.

Referenced by _Function_class_(), add_user_mapping(), read_mappings(), sid_to_uid(), and uid_to_sid().

◆ Vcb

◆ VcbList