ReactOS 0.4.15-dev-8109-gd7be748
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}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#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:113
#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
#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
5303 break;
5304
5306 TRACE("IRP_MN_USER_FS_REQUEST\n");
5307
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 _IO_STACK_LOCATION::@3983::@3998 FileSystemControl
union _IO_STACK_LOCATION::@1568 Parameters
#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 }
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
struct _IO_STACK_LOCATION::@3983::@4019 Power
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) {
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
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:115
#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
struct _IO_STACK_LOCATION::@3983::@3996 QueryVolume
#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:114
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
struct _IO_STACK_LOCATION::@3983::@3997 SetVolume
#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:3604
_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  )

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:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
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 }