ReactOS 0.4.15-dev-8076-g06e89b2
btrfslib.c File Reference
#include <stdlib.h>
#include <stddef.h>
#include <time.h>
#include <ntstatus.h>
#include <windef.h>
#include <winbase.h>
#include <winternl.h>
#include <devioctl.h>
#include <ntdddisk.h>
#include <ntddscsi.h>
#include <ntddstor.h>
#include <ata.h>
#include <mountmgr.h>
#include <stringapiset.h>
#include <stdbool.h>
#include "../btrfs.h"
#include "../btrfsioctl.h"
#include "../crc32c.h"
#include "../xxhash.h"
Include dependency graph for btrfslib.c:

Go to the source code of this file.

Classes

struct  DSTRING
 
struct  STREAM_MESSAGE
 
struct  options
 
struct  btrfs_item
 
struct  btrfs_chunk
 
struct  btrfs_root
 
struct  btrfs_dev
 
struct  TEXTOUTPUT
 
struct  EXTENT_ITEM_METADATA
 
struct  EXTENT_ITEM_METADATA2
 

Macros

#define WIN32_NO_STATUS
 
#define SHA256_HASH_SIZE   32
 
#define BLAKE2_HASH_SIZE   32
 
#define FSCTL_LOCK_VOLUME   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
#define FSCTL_UNLOCK_VOLUME   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
#define FSCTL_DISMOUNT_VOLUME   CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
#define DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED   0x80000000
 
#define FORMAT_FLAG_QUICK_FORMAT   0x00000001
 
#define FORMAT_FLAG_UNKNOWN1   0x00000002
 
#define FORMAT_FLAG_DISMOUNT_FIRST   0x00000004
 
#define FORMAT_FLAG_UNKNOWN2   0x00000040
 
#define FORMAT_FLAG_LARGE_RECORDS   0x00000100
 
#define FORMAT_FLAG_INTEGRITY_DISABLE   0x00000100
 
#define keycmp(key1, key2)
 

Typedefs

typedef struct TEXTOUTPUTPTEXTOUTPUT
 
typedef BOOLEAN(NTAPIPFMIFSCALLBACK) (CALLBACKCOMMAND Command, ULONG SubAction, PVOID ActionInfo)
 

Enumerations

enum  FMIFS_MEDIA_FLAG {
  FMIFS_UNKNOWN0 , FMIFS_UNKNOWN1 , FMIFS_UNKNOWN2 , FMIFS_UNKNOWN3 ,
  FMIFS_UNKNOWN4 , FMIFS_UNKNOWN5 , FMIFS_UNKNOWN6 , FMIFS_UNKNOWN7 ,
  FMIFS_FLOPPY , FMIFS_UNKNOWN9 , FMIFS_UNKNOWN10 , FMIFS_REMOVABLE ,
  FMIFS_HARDDISK , FMIFS_UNKNOWN13 , FMIFS_UNKNOWN14 , FMIFS_UNKNOWN15 ,
  FMIFS_UNKNOWN16 , FMIFS_UNKNOWN17 , FMIFS_UNKNOWN18 , FMIFS_UNKNOWN19 ,
  FMIFS_UNKNOWN20 , FMIFS_UNKNOWN21 , FMIFS_UNKNOWN22 , FMIFS_UNKNOWN23 ,
  FMIFS_UNKNOWN0 , FMIFS_UNKNOWN1 , FMIFS_UNKNOWN2 , FMIFS_UNKNOWN3 ,
  FMIFS_UNKNOWN4 , FMIFS_UNKNOWN5 , FMIFS_UNKNOWN6 , FMIFS_UNKNOWN7 ,
  FMIFS_FLOPPY , FMIFS_UNKNOWN9 , FMIFS_UNKNOWN10 , FMIFS_REMOVABLE ,
  FMIFS_HARDDISK , FMIFS_UNKNOWN13 , FMIFS_UNKNOWN14 , FMIFS_UNKNOWN15 ,
  FMIFS_UNKNOWN16 , FMIFS_UNKNOWN17 , FMIFS_UNKNOWN18 , FMIFS_UNKNOWN19 ,
  FMIFS_UNKNOWN20 , FMIFS_UNKNOWN21 , FMIFS_UNKNOWN22 , FMIFS_UNKNOWN23
}
 
enum  CALLBACKCOMMAND {
  PROGRESS , DONEWITHSTRUCTURE , UNKNOWN2 , UNKNOWN3 ,
  UNKNOWN4 , UNKNOWN5 , INSUFFICIENTRIGHTS , FSNOTSUPPORTED ,
  VOLUMEINUSE , UNKNOWN9 , UNKNOWNA , DONE ,
  UNKNOWNC , UNKNOWND , OUTPUT , STRUCTUREPROGRESS ,
  CLUSTERSIZETOOSMALL , PROGRESS , DONEWITHSTRUCTURE , UNKNOWN2 ,
  UNKNOWN3 , UNKNOWN4 , UNKNOWN5 , INSUFFICIENTRIGHTS ,
  FSNOTSUPPORTED , VOLUMEINUSE , UNKNOWN9 , UNKNOWNA ,
  DONE , UNKNOWNC , UNKNOWND , OUTPUT ,
  STRUCTUREPROGRESS , CLUSTERSIZETOOSMALL
}
 

Functions

void calc_sha256 (uint8_t *hash, const void *input, size_t len)
 
void blake2b (void *out, size_t outlen, const void *in, size_t inlen)
 
NTSTATUS NTAPI NtWriteFile (HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
 
NTSTATUS NTAPI NtReadFile (HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
 
FORCEINLINE VOID InitializeListHead (PLIST_ENTRY ListHead)
 
FORCEINLINE VOID InsertTailList (PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
 
NTSTATUS WINAPI ChkdskEx (PUNICODE_STRING DriveRoot, BOOLEAN FixErrors, BOOLEAN Verbose, BOOLEAN CheckOnlyIfDirty, BOOLEAN ScanDrive, PFMIFSCALLBACK Callback)
 
static btrfs_rootadd_root (LIST_ENTRY *roots, uint64_t id)
 
static void free_roots (LIST_ENTRY *roots)
 
static void free_chunks (LIST_ENTRY *chunks)
 
static void add_item (btrfs_root *r, uint64_t obj_id, uint8_t obj_type, uint64_t offset, void *data, uint16_t size)
 
static uint64_t find_chunk_offset (uint64_t size, uint64_t offset, btrfs_dev *dev, btrfs_root *dev_root, BTRFS_UUID *chunkuuid)
 
static btrfs_chunkadd_chunk (LIST_ENTRY *chunks, uint64_t flags, btrfs_root *chunk_root, btrfs_dev *dev, btrfs_root *dev_root, BTRFS_UUID *chunkuuid, uint32_t sector_size)
 
static bool superblock_collision (btrfs_chunk *c, uint64_t address)
 
static uint64_t get_next_address (btrfs_chunk *c)
 
static void assign_addresses (LIST_ENTRY *roots, btrfs_chunk *sys_chunk, btrfs_chunk *metadata_chunk, uint32_t node_size, btrfs_root *root_root, btrfs_root *extent_root, bool skinny)
 
static NTSTATUS write_data (HANDLE h, uint64_t address, btrfs_chunk *c, void *data, ULONG size)
 
static void calc_tree_checksum (tree_header *th, uint32_t node_size)
 
static NTSTATUS write_roots (HANDLE h, LIST_ENTRY *roots, uint32_t node_size, BTRFS_UUID *fsuuid, BTRFS_UUID *chunkuuid)
 
static void get_uuid (BTRFS_UUID *uuid)
 
static void init_device (btrfs_dev *dev, uint64_t id, uint64_t size, BTRFS_UUID *fsuuid, uint32_t sector_size)
 
static void calc_superblock_checksum (superblock *sb)
 
static NTSTATUS write_superblocks (HANDLE h, btrfs_dev *dev, btrfs_root *chunk_root, btrfs_root *root_root, btrfs_root *extent_root, btrfs_chunk *sys_chunk, uint32_t node_size, BTRFS_UUID *fsuuid, uint32_t sector_size, PUNICODE_STRING label, uint64_t incompat_flags)
 
static __inline void win_time_to_unix (LARGE_INTEGER t, BTRFS_TIME *out)
 
static void add_inode_ref (btrfs_root *r, uint64_t inode, uint64_t parent, uint64_t index, const char *name)
 
static void init_fs_tree (btrfs_root *r, uint32_t node_size)
 
static void add_block_group_items (LIST_ENTRY *chunks, btrfs_root *extent_root)
 
static NTSTATUS clear_first_megabyte (HANDLE h)
 
static bool is_ssd (HANDLE h)
 
static void add_dir_item (btrfs_root *root, uint64_t inode, uint32_t hash, uint64_t key_objid, uint8_t key_type, uint64_t key_offset, uint64_t transid, uint8_t type, const char *name)
 
static void set_default_subvol (btrfs_root *root_root, uint32_t node_size)
 
static NTSTATUS write_btrfs (HANDLE h, uint64_t size, PUNICODE_STRING label, uint32_t sector_size, uint32_t node_size, uint64_t incompat_flags)
 
static bool look_for_device (btrfs_filesystem *bfs, BTRFS_UUID *devuuid)
 
static bool check_superblock_checksum (superblock *sb)
 
static bool is_mounted_multi_device (HANDLE h, uint32_t sector_size)
 
static void do_full_trim (HANDLE h)
 
static bool is_power_of_two (ULONG i)
 
static NTSTATUS NTAPI FormatEx2 (PUNICODE_STRING DriveRoot, FMIFS_MEDIA_FLAG MediaFlag, PUNICODE_STRING Label, BOOLEAN QuickFormat, ULONG ClusterSize, PFMIFSCALLBACK Callback)
 
BOOL __stdcall FormatEx (DSTRING *root, STREAM_MESSAGE *message, options *opts, uint32_t unk1)
 
void __stdcall SetSizes (ULONG sector, ULONG node)
 
void __stdcall SetIncompatFlags (uint64_t incompat_flags)
 
void __stdcall SetCsumType (uint16_t csum_type)
 
BOOL __stdcall GetFilesystemInformation (uint32_t unk1, uint32_t unk2, void *unk3)
 
BOOL APIENTRY DllMain (HANDLE hModule, DWORD dwReason, void *lpReserved)
 

Variables

HMODULE module
 
ULONG def_sector_size = 0
 
ULONG def_node_size = 0
 
uint64_t def_incompat_flags = BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF | BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA
 
uint16_t def_csum_type = CSUM_TYPE_CRC32C
 

Macro Definition Documentation

◆ BLAKE2_HASH_SIZE

#define BLAKE2_HASH_SIZE   32

Definition at line 70 of file btrfslib.c.

◆ DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED

#define DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED   0x80000000

Definition at line 79 of file btrfslib.c.

◆ FORMAT_FLAG_DISMOUNT_FIRST

#define FORMAT_FLAG_DISMOUNT_FIRST   0x00000004

Definition at line 108 of file btrfslib.c.

◆ FORMAT_FLAG_INTEGRITY_DISABLE

#define FORMAT_FLAG_INTEGRITY_DISABLE   0x00000100

Definition at line 111 of file btrfslib.c.

◆ FORMAT_FLAG_LARGE_RECORDS

#define FORMAT_FLAG_LARGE_RECORDS   0x00000100

Definition at line 110 of file btrfslib.c.

◆ FORMAT_FLAG_QUICK_FORMAT

#define FORMAT_FLAG_QUICK_FORMAT   0x00000001

Definition at line 106 of file btrfslib.c.

◆ FORMAT_FLAG_UNKNOWN1

#define FORMAT_FLAG_UNKNOWN1   0x00000002

Definition at line 107 of file btrfslib.c.

◆ FORMAT_FLAG_UNKNOWN2

#define FORMAT_FLAG_UNKNOWN2   0x00000040

Definition at line 109 of file btrfslib.c.

◆ FSCTL_DISMOUNT_VOLUME

Definition at line 76 of file btrfslib.c.

◆ FSCTL_LOCK_VOLUME

Definition at line 74 of file btrfslib.c.

◆ FSCTL_UNLOCK_VOLUME

Definition at line 75 of file btrfslib.c.

◆ keycmp

#define keycmp (   key1,
  key2 
)
Value:
((key1.obj_id < key2.obj_id) ? -1 :\
((key1.obj_id > key2.obj_id) ? 1 :\
((key1.obj_type < key2.obj_type) ? -1 :\
((key1.obj_type > key2.obj_type) ? 1 :\
((key1.offset < key2.offset) ? -1 :\
((key1.offset > key2.offset) ? 1 :\
0))))))
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608

Definition at line 168 of file btrfslib.c.

◆ SHA256_HASH_SIZE

#define SHA256_HASH_SIZE   32

Definition at line 67 of file btrfslib.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 22 of file btrfslib.c.

Typedef Documentation

◆ PFMIFSCALLBACK

typedef BOOLEAN(NTAPI * PFMIFSCALLBACK) (CALLBACKCOMMAND Command, ULONG SubAction, PVOID ActionInfo)

Definition at line 237 of file btrfslib.c.

◆ PTEXTOUTPUT

Enumeration Type Documentation

◆ CALLBACKCOMMAND

Enumerator
PROGRESS 
DONEWITHSTRUCTURE 
UNKNOWN2 
UNKNOWN3 
UNKNOWN4 
UNKNOWN5 
INSUFFICIENTRIGHTS 
FSNOTSUPPORTED 
VOLUMEINUSE 
UNKNOWN9 
UNKNOWNA 
DONE 
UNKNOWNC 
UNKNOWND 
OUTPUT 
STRUCTUREPROGRESS 
CLUSTERSIZETOOSMALL 
PROGRESS 
DONEWITHSTRUCTURE 
UNKNOWN2 
UNKNOWN3 
UNKNOWN4 
UNKNOWN5 
INSUFFICIENTRIGHTS 
FSNOTSUPPORTED 
VOLUMEINUSE 
UNKNOWN9 
UNKNOWNA 
DONE 
UNKNOWNC 
UNKNOWND 
OUTPUT 
STRUCTUREPROGRESS 
CLUSTERSIZETOOSMALL 

Definition at line 217 of file btrfslib.c.

217 {
218 PROGRESS,
220 UNKNOWN2,
221 UNKNOWN3,
222 UNKNOWN4,
223 UNKNOWN5,
227 UNKNOWN9,
228 UNKNOWNA,
229 DONE,
230 UNKNOWNC,
231 UNKNOWND,
232 OUTPUT,
CALLBACKCOMMAND
Definition: btrfslib.c:217
@ UNKNOWN9
Definition: btrfslib.c:227
@ OUTPUT
Definition: btrfslib.c:232
@ FSNOTSUPPORTED
Definition: btrfslib.c:225
@ UNKNOWND
Definition: btrfslib.c:231
@ VOLUMEINUSE
Definition: btrfslib.c:226
@ UNKNOWN4
Definition: btrfslib.c:222
@ UNKNOWNA
Definition: btrfslib.c:228
@ STRUCTUREPROGRESS
Definition: btrfslib.c:233
@ DONE
Definition: btrfslib.c:229
@ CLUSTERSIZETOOSMALL
Definition: btrfslib.c:234
@ DONEWITHSTRUCTURE
Definition: btrfslib.c:219
@ INSUFFICIENTRIGHTS
Definition: btrfslib.c:224
@ PROGRESS
Definition: btrfslib.c:218
@ UNKNOWN5
Definition: btrfslib.c:223
@ UNKNOWN2
Definition: btrfslib.c:220
@ UNKNOWN3
Definition: btrfslib.c:221
@ UNKNOWNC
Definition: btrfslib.c:230

◆ FMIFS_MEDIA_FLAG

Enumerator
FMIFS_UNKNOWN0 
FMIFS_UNKNOWN1 
FMIFS_UNKNOWN2 
FMIFS_UNKNOWN3 
FMIFS_UNKNOWN4 
FMIFS_UNKNOWN5 
FMIFS_UNKNOWN6 
FMIFS_UNKNOWN7 
FMIFS_FLOPPY 
FMIFS_UNKNOWN9 
FMIFS_UNKNOWN10 
FMIFS_REMOVABLE 
FMIFS_HARDDISK 
FMIFS_UNKNOWN13 
FMIFS_UNKNOWN14 
FMIFS_UNKNOWN15 
FMIFS_UNKNOWN16 
FMIFS_UNKNOWN17 
FMIFS_UNKNOWN18 
FMIFS_UNKNOWN19 
FMIFS_UNKNOWN20 
FMIFS_UNKNOWN21 
FMIFS_UNKNOWN22 
FMIFS_UNKNOWN23 
FMIFS_UNKNOWN0 
FMIFS_UNKNOWN1 
FMIFS_UNKNOWN2 
FMIFS_UNKNOWN3 
FMIFS_UNKNOWN4 
FMIFS_UNKNOWN5 
FMIFS_UNKNOWN6 
FMIFS_UNKNOWN7 
FMIFS_FLOPPY 
FMIFS_UNKNOWN9 
FMIFS_UNKNOWN10 
FMIFS_REMOVABLE 
FMIFS_HARDDISK 
FMIFS_UNKNOWN13 
FMIFS_UNKNOWN14 
FMIFS_UNKNOWN15 
FMIFS_UNKNOWN16 
FMIFS_UNKNOWN17 
FMIFS_UNKNOWN18 
FMIFS_UNKNOWN19 
FMIFS_UNKNOWN20 
FMIFS_UNKNOWN21 
FMIFS_UNKNOWN22 
FMIFS_UNKNOWN23 

Definition at line 190 of file btrfslib.c.

190 {
FMIFS_MEDIA_FLAG
Definition: btrfslib.c:190
@ FMIFS_UNKNOWN14
Definition: btrfslib.c:205
@ FMIFS_UNKNOWN23
Definition: btrfslib.c:214
@ FMIFS_UNKNOWN13
Definition: btrfslib.c:204
@ FMIFS_UNKNOWN22
Definition: btrfslib.c:213
@ FMIFS_UNKNOWN17
Definition: btrfslib.c:208
@ FMIFS_UNKNOWN4
Definition: btrfslib.c:195
@ FMIFS_UNKNOWN1
Definition: btrfslib.c:192
@ FMIFS_FLOPPY
Definition: btrfslib.c:199
@ FMIFS_UNKNOWN3
Definition: btrfslib.c:194
@ FMIFS_UNKNOWN10
Definition: btrfslib.c:201
@ FMIFS_UNKNOWN18
Definition: btrfslib.c:209
@ FMIFS_UNKNOWN0
Definition: btrfslib.c:191
@ FMIFS_UNKNOWN21
Definition: btrfslib.c:212
@ FMIFS_UNKNOWN15
Definition: btrfslib.c:206
@ FMIFS_UNKNOWN16
Definition: btrfslib.c:207
@ FMIFS_UNKNOWN7
Definition: btrfslib.c:198
@ FMIFS_UNKNOWN20
Definition: btrfslib.c:211
@ FMIFS_UNKNOWN19
Definition: btrfslib.c:210
@ FMIFS_UNKNOWN6
Definition: btrfslib.c:197
@ FMIFS_REMOVABLE
Definition: btrfslib.c:202
@ FMIFS_UNKNOWN5
Definition: btrfslib.c:196
@ FMIFS_UNKNOWN9
Definition: btrfslib.c:200
@ FMIFS_HARDDISK
Definition: btrfslib.c:203
@ FMIFS_UNKNOWN2
Definition: btrfslib.c:193

Function Documentation

◆ add_block_group_items()

static void add_block_group_items ( LIST_ENTRY chunks,
btrfs_root extent_root 
)
static

Definition at line 940 of file btrfslib.c.

940 {
941 LIST_ENTRY* le;
942
943 le = chunks->Flink;
944 while (le != chunks) {
947
948 bgi.used = c->used;
949 bgi.chunk_tree = 0x100;
950 bgi.flags = c->chunk_item->type;
951 add_item(extent_root, c->offset, TYPE_BLOCK_GROUP_ITEM, c->chunk_item->size, &bgi, sizeof(BLOCK_GROUP_ITEM));
952
953 le = le->Flink;
954 }
955}
static void add_item(btrfs_root *r, uint64_t obj_id, uint8_t obj_type, uint64_t offset, void *data, uint16_t size)
Definition: btrfslib.c:339
#define TYPE_BLOCK_GROUP_ITEM
Definition: btrfs.h:42
const GLubyte * c
Definition: glext.h:8905
uint64_t chunk_tree
Definition: btrfs.h:425
uint64_t flags
Definition: btrfs.h:426
uint64_t used
Definition: btrfs.h:424
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: list.h:27
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by write_btrfs().

◆ add_chunk()

static btrfs_chunk * add_chunk ( LIST_ENTRY chunks,
uint64_t  flags,
btrfs_root chunk_root,
btrfs_dev dev,
btrfs_root dev_root,
BTRFS_UUID chunkuuid,
uint32_t  sector_size 
)
static

Definition at line 392 of file btrfslib.c.

392 {
393 uint64_t off, size;
394 uint16_t stripes, i;
395 btrfs_chunk* c;
396 LIST_ENTRY* le;
398
399 off = 0xc00000;
400 le = chunks->Flink;
401 while (le != chunks) {
403
404 if (c->offset + c->chunk_item->size > off)
405 off = c->offset + c->chunk_item->size;
406
407 le = le->Flink;
408 }
409
411 if (dev->dev_item.num_bytes > 0xC80000000) // 50 GB
412 size = 0x40000000; // 1 GB
413 else
414 size = 0x10000000; // 256 MB
415 } else if (flags & BLOCK_FLAG_SYSTEM)
416 size = 0x800000;
417
418 size = min(size, dev->dev_item.num_bytes / 10); // cap at 10%
419 size &= ~(sector_size - 1);
420
421 stripes = flags & BLOCK_FLAG_DUPLICATE ? 2 : 1;
422
423 if (dev->dev_item.num_bytes - dev->dev_item.bytes_used < stripes * size) // not enough space
424 return NULL;
425
426 c = malloc(sizeof(btrfs_chunk));
427 c->offset = off;
428 c->lastoff = off;
429 c->used = 0;
430
431 c->chunk_item = malloc(sizeof(CHUNK_ITEM) + (stripes * sizeof(CHUNK_ITEM_STRIPE)));
432
433 c->chunk_item->size = size;
434 c->chunk_item->root_id = BTRFS_ROOT_EXTENT;
435 c->chunk_item->stripe_length = max(sector_size, 0x10000);
436 c->chunk_item->type = flags;
437 c->chunk_item->opt_io_alignment = max(sector_size, 0x10000);
438 c->chunk_item->opt_io_width = max(sector_size, 0x10000);
439 c->chunk_item->sector_size = sector_size;
440 c->chunk_item->num_stripes = stripes;
441 c->chunk_item->sub_stripes = 0;
442
443 cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
444
445 for (i = 0; i < stripes; i++) {
446 cis[i].dev_id = dev->dev_item.dev_id;
447 cis[i].offset = find_chunk_offset(size, c->offset, dev, dev_root, chunkuuid);
448 cis[i].dev_uuid = dev->dev_item.device_uuid;
449 }
450
451 add_item(chunk_root, 0x100, TYPE_CHUNK_ITEM, c->offset, c->chunk_item, sizeof(CHUNK_ITEM) + (stripes * sizeof(CHUNK_ITEM_STRIPE)));
452
453 InsertTailList(chunks, &c->list_entry);
454
455 return c;
456}
unsigned short int uint16_t
Definition: acefiex.h:54
static uint64_t find_chunk_offset(uint64_t size, uint64_t offset, btrfs_dev *dev, btrfs_root *dev_root, BTRFS_UUID *chunkuuid)
Definition: btrfslib.c:372
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
UINT64 uint64_t
Definition: types.h:77
#define TYPE_CHUNK_ITEM
Definition: btrfs.h:48
#define BTRFS_ROOT_EXTENT
Definition: btrfs.h:55
#define InsertTailList(ListHead, Entry)
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
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 c
Definition: ke_i.h:80
__u8 sector_size[2]
Definition: mkdosfs.c:3
#define for
Definition: utility.h:88
#define min(a, b)
Definition: monoChain.cc:55
#define BLOCK_FLAG_DUPLICATE
Definition: shellext.h:80
#define BLOCK_FLAG_SYSTEM
Definition: shellext.h:76
#define BLOCK_FLAG_METADATA
Definition: shellext.h:77
BTRFS_UUID dev_uuid
Definition: btrfs.h:354
uint64_t offset
Definition: btrfs.h:353
uint64_t dev_id
Definition: btrfs.h:352
uint64_t dev_id
#define max(a, b)
Definition: svc.c:63

Referenced by write_btrfs().

◆ add_dir_item()

static void add_dir_item ( btrfs_root root,
uint64_t  inode,
uint32_t  hash,
uint64_t  key_objid,
uint8_t  key_type,
uint64_t  key_offset,
uint64_t  transid,
uint8_t  type,
const char name 
)
static

Definition at line 1010 of file btrfslib.c.

1011 {
1012 uint16_t name_len = (uint16_t)strlen(name);
1013 DIR_ITEM* di = malloc(offsetof(DIR_ITEM, name[0]) + name_len);
1014
1015 di->key.obj_id = key_objid;
1016 di->key.obj_type = key_type;
1017 di->key.offset = key_offset;
1018 di->transid = transid;
1019 di->m = 0;
1020 di->n = name_len;
1021 di->type = type;
1022 memcpy(di->name, name, name_len);
1023
1024 add_item(root, inode, TYPE_DIR_ITEM, hash, di, (uint16_t)(offsetof(DIR_ITEM, name[0]) + di->m + di->n));
1025
1026 free(di);
1027}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define free
Definition: debug_ros.c:5
#define TYPE_DIR_ITEM
Definition: btrfs.h:28
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define uint16_t
Definition: nsiface.idl:60
#define offsetof(TYPE, MEMBER)
uint16_t m
Definition: btrfs.h:275
uint8_t type
Definition: btrfs.h:277
char name[1]
Definition: btrfs.h:278
uint64_t transid
Definition: btrfs.h:274
uint16_t n
Definition: btrfs.h:276
KEY key
Definition: btrfs.h:273
uint8_t obj_type
Definition: btrfs.h:145
uint64_t obj_id
Definition: btrfs.h:144
uint64_t offset
Definition: btrfs.h:146
Definition: _hash_fun.h:40
Definition: fs.h:78
Definition: name.c:39

Referenced by set_default_subvol().

◆ add_inode_ref()

static void add_inode_ref ( btrfs_root r,
uint64_t  inode,
uint64_t  parent,
uint64_t  index,
const char name 
)
static

Definition at line 903 of file btrfslib.c.

903 {
904 uint16_t name_len = (uint16_t)strlen(name);
905 INODE_REF* ir = malloc(offsetof(INODE_REF, name[0]) + name_len);
906
907 ir->index = 0;
908 ir->n = name_len;
909 memcpy(ir->name, name, name_len);
910
912
913 free(ir);
914}
r parent
Definition: btrfs.c:3010
#define TYPE_INODE_REF
Definition: btrfs.h:24
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
uint64_t index
Definition: btrfs.h:375
char name[1]
Definition: btrfs.h:377
uint16_t n
Definition: btrfs.h:376

Referenced by init_fs_tree(), and set_default_subvol().

◆ add_item()

static void add_item ( btrfs_root r,
uint64_t  obj_id,
uint8_t  obj_type,
uint64_t  offset,
void data,
uint16_t  size 
)
static

Definition at line 339 of file btrfslib.c.

339 {
340 LIST_ENTRY* le;
342
343 item = malloc(sizeof(btrfs_item));
344
345 item->key.obj_id = obj_id;
346 item->key.obj_type = obj_type;
347 item->key.offset = offset;
348 item->size = size;
349
350 if (size == 0)
351 item->data = NULL;
352 else {
353 item->data = malloc(size);
354 memcpy(item->data, data, size);
355 }
356
357 le = r->items.Flink;
358 while (le != &r->items) {
360
361 if (keycmp(item->key, i2->key) != 1) {
362 InsertTailList(le, &item->list_entry);
363 return;
364 }
365
366 le = le->Flink;
367 }
368
369 InsertTailList(&r->items, &item->list_entry);
370}
#define keycmp(key1, key2)
Definition: btrfslib.c:168
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLintptr offset
Definition: glext.h:5920
static ATOM item
Definition: dde.c:856
struct btrfs_disk_key key
Definition: btrfs.h:110

Referenced by add_block_group_items(), add_chunk(), add_dir_item(), add_inode_ref(), assign_addresses(), find_chunk_offset(), init_fs_tree(), set_default_subvol(), and write_btrfs().

◆ add_root()

static btrfs_root * add_root ( LIST_ENTRY roots,
uint64_t  id 
)
static

Definition at line 284 of file btrfslib.c.

284 {
286
287 root = malloc(sizeof(btrfs_root));
288
289 root->id = id;
290 RtlZeroMemory(&root->header, sizeof(tree_header));
291 InitializeListHead(&root->items);
293
294 return root;
295}
struct _root root
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
GLuint id
Definition: glext.h:5910
uint64_t id
Definition: btrfs_drv.h:451
LIST_ENTRY list_entry
Definition: btrfs_drv.h:466
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by look_for_roots(), mount_vol(), and write_btrfs().

◆ assign_addresses()

static void assign_addresses ( LIST_ENTRY roots,
btrfs_chunk sys_chunk,
btrfs_chunk metadata_chunk,
uint32_t  node_size,
btrfs_root root_root,
btrfs_root extent_root,
bool  skinny 
)
static

Definition at line 507 of file btrfslib.c.

508 {
509 LIST_ENTRY* le;
510
511 le = roots->Flink;
512 while (le != roots) {
514 btrfs_chunk* c = r->id == BTRFS_ROOT_CHUNK ? sys_chunk : metadata_chunk;
515
516 r->header.address = get_next_address(c);
517 r->c = c;
518 c->lastoff = r->header.address + node_size;
519 c->used += node_size;
520
521 if (skinny) {
523
524 eim.ei.refcount = 1;
525 eim.ei.generation = 1;
528 eim.tbr.offset = r->id;
529
530 add_item(extent_root, r->header.address, TYPE_METADATA_ITEM, 0, &eim, sizeof(EXTENT_ITEM_METADATA));
531 } else {
533 KEY firstitem;
534
535 if (r->items.Flink == &r->items) {
536 firstitem.obj_id = 0;
537 firstitem.obj_type = 0;
538 firstitem.offset = 0;
539 } else {
540 btrfs_item* bi = CONTAINING_RECORD(r->items.Flink, btrfs_item, list_entry);
541
542 firstitem = bi->key;
543 }
544
545 eim2.ei.refcount = 1;
546 eim2.ei.generation = 1;
548 eim2.ei2.firstitem = firstitem;
549 eim2.ei2.level = 0;
551 eim2.tbr.offset = r->id;
552
553 add_item(extent_root, r->header.address, TYPE_EXTENT_ITEM, node_size, &eim2, sizeof(EXTENT_ITEM_METADATA2));
554 }
555
556 if (r->id != BTRFS_ROOT_ROOT && r->id != BTRFS_ROOT_CHUNK) {
557 ROOT_ITEM ri;
558
559 memset(&ri, 0, sizeof(ROOT_ITEM));
560
561 ri.inode.generation = 1;
562 ri.inode.st_size = 3;
563 ri.inode.st_blocks = node_size;
564 ri.inode.st_nlink = 1;
565 ri.inode.st_mode = 040755;
566 ri.generation = 1;
567 ri.objid = r->id == 5 || r->id >= 0x100 ? SUBVOL_ROOT_INODE : 0;
568 ri.block_number = r->header.address;
569 ri.bytes_used = node_size;
570 ri.num_references = 1;
571 ri.generation2 = ri.generation;
572
573 add_item(root_root, r->id, TYPE_ROOT_ITEM, 0, &ri, sizeof(ROOT_ITEM));
574 }
575
576 le = le->Flink;
577 }
578}
static uint64_t get_next_address(btrfs_chunk *c)
Definition: btrfslib.c:479
#define TYPE_EXTENT_ITEM
Definition: btrfs.h:35
#define EXTENT_ITEM_TREE_BLOCK
Definition: btrfs.h:388
#define TYPE_TREE_BLOCK_REF
Definition: btrfs.h:37
#define BTRFS_ROOT_CHUNK
Definition: btrfs.h:56
#define BTRFS_ROOT_ROOT
Definition: btrfs.h:54
#define TYPE_ROOT_ITEM
Definition: btrfs.h:32
#define TYPE_METADATA_ITEM
Definition: btrfs.h:36
#define SUBVOL_ROOT_INODE
Definition: propsheet.cpp:42
#define memset(x, y, z)
Definition: compat.h:39
KEY firstitem
Definition: btrfs.h:398
uint8_t level
Definition: btrfs.h:399
EXTENT_ITEM ei
Definition: btrfslib.c:501
EXTENT_ITEM2 ei2
Definition: btrfslib.c:502
TREE_BLOCK_REF tbr
Definition: btrfslib.c:504
TREE_BLOCK_REF tbr
Definition: btrfslib.c:497
EXTENT_ITEM ei
Definition: btrfslib.c:495
uint64_t generation
Definition: btrfs.h:393
uint64_t flags
Definition: btrfs.h:394
uint64_t refcount
Definition: btrfs.h:392
uint32_t st_mode
Definition: btrfs.h:295
uint32_t st_nlink
Definition: btrfs.h:292
uint64_t st_size
Definition: btrfs.h:289
uint64_t st_blocks
Definition: btrfs.h:290
uint64_t generation
Definition: btrfs.h:287
Definition: btrfs.h:143
uint64_t bytes_used
Definition: btrfs.h:317
uint32_t num_references
Definition: btrfs.h:320
uint64_t objid
Definition: btrfs.h:314
uint64_t block_number
Definition: btrfs.h:315
uint64_t generation2
Definition: btrfs.h:324
uint64_t generation
Definition: btrfs.h:313
INODE_ITEM inode
Definition: btrfs.h:312
uint64_t offset
Definition: btrfs.h:413

Referenced by write_btrfs().

◆ blake2b()

void blake2b ( void out,
size_t  outlen,
const void in,
size_t  inlen 
)

Definition at line 237 of file blake2b-ref.c.

238{
239 blake2b_state S[1];
240
241 blake2b_init( S, outlen );
242
243 blake2b_update( S, ( const uint8_t * )in, inlen );
244 blake2b_final( S, out, outlen );
245}
static int blake2b_final(blake2b_state *S, void *out, size_t outlen)
Definition: blake2b-ref.c:212
static void blake2b_init(blake2b_state *S, size_t outlen)
Definition: blake2b-ref.c:97
static int blake2b_update(blake2b_state *S, const void *in, size_t inlen)
Definition: blake2b-ref.c:185
GLuint in
Definition: glext.h:9616
BYTE uint8_t
Definition: msvideo1.c:66
static FILE * out
Definition: regtests2xml.c:44
Definition: movable.cpp:9

Referenced by calc_superblock_checksum(), calc_thread_main(), calc_tree_checksum(), check_sector_csum(), check_superblock_checksum(), check_tree_checksum(), get_sector_csum(), and get_tree_checksum().

◆ calc_sha256()

void calc_sha256 ( uint8_t hash,
const void input,
size_t  len 
)

Definition at line 126 of file sha256.c.

127{
128 /*
129 * Note 1: All integers (expect indexes) are 32-bit unsigned integers and addition is calculated modulo 2^32.
130 * Note 2: For each round, there is one round constant k[i] and one entry in the message schedule array w[i], 0 = i = 63
131 * Note 3: The compression function uses 8 working variables, a through h
132 * Note 4: Big-endian convention is used when expressing the constants in this pseudocode,
133 * and when parsing message block data from bytes to words, for example,
134 * the first word of the input message "abc" after padding is 0x61626380
135 */
136
137 /*
138 * Initialize hash values:
139 * (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
140 */
141 uint32_t h[] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
142 unsigned i, j;
143
144 /* 512-bit chunks is what we will operate on. */
145 uint8_t chunk[64];
146
147 struct buffer_state state;
148
150
151 while (calc_chunk(chunk, &state)) {
152 uint32_t ah[8];
153
154 const uint8_t *p = chunk;
155
156 /* Initialize working variables to current hash value: */
157 for (i = 0; i < 8; i++)
158 ah[i] = h[i];
159
160 /* Compression function main loop: */
161 for (i = 0; i < 4; i++) {
162 /*
163 * The w-array is really w[64], but since we only need
164 * 16 of them at a time, we save stack by calculating
165 * 16 at a time.
166 *
167 * This optimization was not there initially and the
168 * rest of the comments about w[64] are kept in their
169 * initial state.
170 */
171
172 /*
173 * create a 64-entry message schedule array w[0..63] of 32-bit words
174 * (The initial values in w[0..63] don't matter, so many implementations zero them here)
175 * copy chunk into first 16 words w[0..15] of the message schedule array
176 */
177 uint32_t w[16];
178
179 for (j = 0; j < 16; j++) {
180 if (i == 0) {
181 w[j] = (uint32_t) p[0] << 24 | (uint32_t) p[1] << 16 |
182 (uint32_t) p[2] << 8 | (uint32_t) p[3];
183 p += 4;
184 } else {
185 /* Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array: */
186 const uint32_t s0 = right_rot(w[(j + 1) & 0xf], 7) ^ right_rot(w[(j + 1) & 0xf], 18) ^ (w[(j + 1) & 0xf] >> 3);
187 const uint32_t s1 = right_rot(w[(j + 14) & 0xf], 17) ^ right_rot(w[(j + 14) & 0xf], 19) ^ (w[(j + 14) & 0xf] >> 10);
188 w[j] = w[j] + s0 + w[(j + 9) & 0xf] + s1;
189 }
190 {
191 const uint32_t s1 = right_rot(ah[4], 6) ^ right_rot(ah[4], 11) ^ right_rot(ah[4], 25);
192 const uint32_t ch = (ah[4] & ah[5]) ^ (~ah[4] & ah[6]);
193 const uint32_t temp1 = ah[7] + s1 + ch + k[i << 4 | j] + w[j];
194 const uint32_t s0 = right_rot(ah[0], 2) ^ right_rot(ah[0], 13) ^ right_rot(ah[0], 22);
195 const uint32_t maj = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]);
196 const uint32_t temp2 = s0 + maj;
197
198 ah[7] = ah[6];
199 ah[6] = ah[5];
200 ah[5] = ah[4];
201 ah[4] = ah[3] + temp1;
202 ah[3] = ah[2];
203 ah[2] = ah[1];
204 ah[1] = ah[0];
205 ah[0] = temp1 + temp2;
206 }
207 }
208 }
209
210 /* Add the compressed chunk to the current hash value: */
211 for (i = 0; i < 8; i++)
212 h[i] += ah[i];
213 }
214
215 /* Produce the final hash value (big-endian): */
216 for (i = 0, j = 0; i < 8; i++)
217 {
218 hash[j++] = (uint8_t) (h[i] >> 24);
219 hash[j++] = (uint8_t) (h[i] >> 16);
220 hash[j++] = (uint8_t) (h[i] >> 8);
221 hash[j++] = (uint8_t) h[i];
222 }
223}
static int state
Definition: maze.c:121
UINT32 uint32_t
Definition: types.h:75
static uint32_t right_rot(uint32_t value, unsigned int count)
Definition: sha256.c:43
static void init_buf_state(struct buffer_state *state, const void *input, size_t len)
Definition: sha256.c:52
static const uint32_t k[]
Definition: sha256.c:24
static int calc_chunk(uint8_t chunk[CHUNK_SIZE], struct buffer_state *state)
Definition: sha256.c:62
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
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
struct S1 s1
#define uint32_t
Definition: nsiface.idl:61
#define uint8_t
Definition: nsiface.idl:59

Referenced by calc_superblock_checksum(), calc_tree_checksum(), and check_superblock_checksum().

◆ calc_superblock_checksum()

static void calc_superblock_checksum ( superblock sb)
static

Definition at line 732 of file btrfslib.c.

732 {
733 switch (def_csum_type) {
734 case CSUM_TYPE_CRC32C:
735 *(uint32_t*)sb = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
736 break;
737
738 case CSUM_TYPE_XXHASH:
739 *(uint64_t*)sb = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0);
740 break;
741
742 case CSUM_TYPE_SHA256:
743 calc_sha256((uint8_t*)sb, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
744 break;
745
746 case CSUM_TYPE_BLAKE2:
747 blake2b((uint8_t*)sb, BLAKE2_HASH_SIZE, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
748 break;
749 }
750}
void blake2b(void *out, size_t outlen, const void *in, size_t inlen)
Definition: blake2b-ref.c:237
uint16_t def_csum_type
Definition: btrfslib.c:180
#define BLAKE2_HASH_SIZE
Definition: btrfslib.c:70
void calc_sha256(uint8_t *hash, const void *input, size_t len)
Definition: sha256.c:126
crc_func calc_crc32c
Definition: crc32c.c:23
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
BTRFS_UUID uuid
Definition: btrfs.h:225
uint8_t checksum[32]
Definition: btrfs.h:224
uint32_t ULONG
Definition: typedefs.h:59
XXH_PUBLIC_API unsigned long long XXH64(const void *input, size_t len, unsigned long long seed)
Definition: xxhash.c:555

Referenced by write_superblocks().

◆ calc_tree_checksum()

static void calc_tree_checksum ( tree_header th,
uint32_t  node_size 
)
static

Definition at line 600 of file btrfslib.c.

600 {
601 switch (def_csum_type) {
602 case CSUM_TYPE_CRC32C:
603 *(uint32_t*)th = ~calc_crc32c(0xffffffff, (uint8_t*)&th->fs_uuid, node_size - sizeof(th->csum));
604 break;
605
606 case CSUM_TYPE_XXHASH:
607 *(uint64_t*)th = XXH64((uint8_t*)&th->fs_uuid, node_size - sizeof(th->csum), 0);
608 break;
609
610 case CSUM_TYPE_SHA256:
611 calc_sha256((uint8_t*)th, &th->fs_uuid, node_size - sizeof(th->csum));
612 break;
613
614 case CSUM_TYPE_BLAKE2:
615 blake2b((uint8_t*)th, BLAKE2_HASH_SIZE, &th->fs_uuid, node_size - sizeof(th->csum));
616 break;
617 }
618}
uint8_t csum[32]
Definition: btrfs.h:154
BTRFS_UUID fs_uuid
Definition: btrfs.h:155

Referenced by write_roots().

◆ check_superblock_checksum()

static bool check_superblock_checksum ( superblock sb)
static

Definition at line 1165 of file btrfslib.c.

1165 {
1166 switch (sb->csum_type) {
1167 case CSUM_TYPE_CRC32C: {
1168 uint32_t crc32 = ~calc_crc32c(0xffffffff, (uint8_t*)&sb->uuid, (ULONG)sizeof(superblock) - sizeof(sb->checksum));
1169
1170 return crc32 == *(uint32_t*)sb;
1171 }
1172
1173 case CSUM_TYPE_XXHASH: {
1174 uint64_t hash = XXH64(&sb->uuid, sizeof(superblock) - sizeof(sb->checksum), 0);
1175
1176 return hash == *(uint64_t*)sb;
1177 }
1178
1179 case CSUM_TYPE_SHA256: {
1181
1182 calc_sha256(hash, &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
1183
1184 return !memcmp(hash, sb, SHA256_HASH_SIZE);
1185 }
1186
1187 case CSUM_TYPE_BLAKE2: {
1189
1190 blake2b(hash, sizeof(hash), &sb->uuid, sizeof(superblock) - sizeof(sb->checksum));
1191
1192 return !memcmp(hash, sb, BLAKE2_HASH_SIZE);
1193 }
1194
1195 default:
1196 return false;
1197 }
1198}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define SHA256_HASH_SIZE
Definition: btrfslib.c:67
#define crc32(crc, buf, len)
Definition: inflate.c:1081
uint16_t csum_type
Definition: btrfs.h:247

Referenced by is_mounted_multi_device().

◆ ChkdskEx()

NTSTATUS WINAPI ChkdskEx ( PUNICODE_STRING  DriveRoot,
BOOLEAN  FixErrors,
BOOLEAN  Verbose,
BOOLEAN  CheckOnlyIfDirty,
BOOLEAN  ScanDrive,
PFMIFSCALLBACK  Callback 
)

Definition at line 246 of file btrfslib.c.

247 {
248#else
250NTAPI
252 IN PUNICODE_STRING DriveRoot,
256 IN BOOLEAN CheckOnlyIfDirty,
257 IN BOOLEAN ScanDrive,
258 IN PVOID pUnknown1,
259 IN PVOID pUnknown2,
260 IN PVOID pUnknown3,
261 IN PVOID pUnknown4,
263{
264#endif
265 // STUB
266
267 if (Callback) {
269
270 TextOut.Lines = 1;
271 TextOut.Output = "stub, not implemented";
272
273 Callback(OUTPUT, 0, &TextOut);
274 }
275
276#ifndef __REACTOS__
277 return STATUS_SUCCESS;
278#else
280 return TRUE;
281#endif
282}
unsigned char BOOLEAN
BOOL FixErrors
Definition: chkdsk.c:69
BOOL Verbose
Definition: chkdsk.c:72
BOOLEAN(NTAPI * PFMIFSCALLBACK)(CALLBACKCOMMAND Command, ULONG SubAction, PVOID ActionInfo)
Definition: btrfslib.c:237
BOOLEAN NTAPI BtrfsChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
#define TRUE
Definition: types.h:120
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:867
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
#define TextOut
Definition: wingdi.h:4483

◆ clear_first_megabyte()

static NTSTATUS clear_first_megabyte ( HANDLE  h)
static

Definition at line 957 of file btrfslib.c.

957 {
961 uint8_t* mb;
962
963 mb = malloc(0x100000);
964 memset(mb, 0, 0x100000);
965
966 zero.QuadPart = 0;
967
968 Status = NtWriteFile(h, NULL, NULL, NULL, &iosb, mb, 0x100000, &zero, NULL);
969
970 free(mb);
971
972 return Status;
973}
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI NtWriteFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
Status
Definition: gdiplustypes.h:25
static PIO_STATUS_BLOCK iosb
Definition: file.c:98
int zero
Definition: sehframes.cpp:29

Referenced by write_btrfs().

◆ DllMain()

BOOL APIENTRY DllMain ( HANDLE  hModule,
DWORD  dwReason,
void lpReserved 
)

Definition at line 1581 of file btrfslib.c.

1581 {
1584
1585 return true;
1586}
DWORD dwReason
Definition: misc.cpp:154
HMODULE hModule
Definition: animate.c:44
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
HANDLE HMODULE
Definition: typedefs.h:77

◆ do_full_trim()

static void do_full_trim ( HANDLE  h)
static

Definition at line 1297 of file btrfslib.c.

1297 {
1300
1302
1306 dmdsa.ParameterBlockOffset = 0;
1307 dmdsa.ParameterBlockLength = 0;
1308 dmdsa.DataSetRangesOffset = 0;
1309 dmdsa.DataSetRangesLength = 0;
1310
1312}
#define DEVICE_DSM_FLAG_TRIM_NOT_FS_ALLOCATED
Definition: btrfslib.c:79
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
struct _DEVICE_MANAGE_DATA_SET_ATTRIBUTES DEVICE_MANAGE_DATA_SET_ATTRIBUTES
#define DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE
Definition: ntddstor.h:306
#define IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES
Definition: ntddstor.h:181
#define DeviceDsmAction_Trim
Definition: ntddstor.h:276
DEVICE_DATA_MANAGEMENT_SET_ACTION Action
Definition: ntddstor.h:773

Referenced by FormatEx2().

◆ find_chunk_offset()

static uint64_t find_chunk_offset ( uint64_t  size,
uint64_t  offset,
btrfs_dev dev,
btrfs_root dev_root,
BTRFS_UUID chunkuuid 
)
static

Definition at line 372 of file btrfslib.c.

372 {
373 uint64_t off;
374 DEV_EXTENT de;
375
376 off = dev->last_alloc;
377 dev->last_alloc += size;
378
379 dev->dev_item.bytes_used += size;
380
382 de.objid = 0x100;
383 de.address = offset;
384 de.length = size;
385 de.chunktree_uuid = *chunkuuid;
386
387 add_item(dev_root, dev->dev_item.dev_id, TYPE_DEV_EXTENT, off, &de, sizeof(DEV_EXTENT));
388
389 return off;
390}
#define TYPE_DEV_EXTENT
Definition: btrfs.h:46
uint64_t address
Definition: btrfs.h:471
BTRFS_UUID chunktree_uuid
Definition: btrfs.h:473
uint64_t chunktree
Definition: btrfs.h:469
uint64_t objid
Definition: btrfs.h:470
uint64_t length
Definition: btrfs.h:472

Referenced by add_chunk().

◆ FormatEx()

BOOL __stdcall FormatEx ( DSTRING root,
STREAM_MESSAGE message,
options opts,
uint32_t  unk1 
)

Definition at line 1533 of file btrfslib.c.

1533 {
1534 UNICODE_STRING DriveRoot, Label;
1536
1537 if (!root || !root->string)
1538 return false;
1539
1540 DriveRoot.Length = DriveRoot.MaximumLength = (USHORT)(wcslen(root->string) * sizeof(WCHAR));
1541 DriveRoot.Buffer = root->string;
1542
1543 if (opts && opts->label && opts->label->string) {
1544 Label.Length = Label.MaximumLength = (USHORT)(wcslen(opts->label->string) * sizeof(WCHAR));
1545 Label.Buffer = opts->label->string;
1546 } else {
1547 Label.Length = Label.MaximumLength = 0;
1548 Label.Buffer = NULL;
1549 }
1550
1551 Status = FormatEx2(&DriveRoot, FMIFS_HARDDISK, &Label, opts && opts->flags & FORMAT_FLAG_QUICK_FORMAT, 0, NULL);
1552
1553 return NT_SUCCESS(Status);
1554}
PWCHAR Label
Definition: format.c:70
#define FORMAT_FLAG_QUICK_FORMAT
Definition: btrfslib.c:106
static NTSTATUS NTAPI FormatEx2(PUNICODE_STRING DriveRoot, FMIFS_MEDIA_FLAG MediaFlag, PUNICODE_STRING Label, BOOLEAN QuickFormat, ULONG ClusterSize, PFMIFSCALLBACK Callback)
Definition: btrfslib.c:1336
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
unsigned short USHORT
Definition: pedump.c:61
WCHAR * string
Definition: btrfslib.c:99
USHORT MaximumLength
Definition: env_spec_w32.h:370
DSTRING * label
Definition: btrfslib.c:117
uint32_t flags
Definition: btrfslib.c:116
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ FormatEx2()

static NTSTATUS NTAPI FormatEx2 ( PUNICODE_STRING  DriveRoot,
FMIFS_MEDIA_FLAG  MediaFlag,
PUNICODE_STRING  Label,
BOOLEAN  QuickFormat,
ULONG  ClusterSize,
PFMIFSCALLBACK  Callback 
)
static

Definition at line 1336 of file btrfslib.c.

1338{
1340 HANDLE h, btrfsh;
1344 DISK_GEOMETRY dg;
1345 uint32_t sector_size, node_size;
1346 UNICODE_STRING btrfsus;
1347#ifndef __REACTOS__
1348 HANDLE token;
1350 LUID luid;
1351#endif
1352 uint64_t incompat_flags;
1353 UNICODE_STRING empty_label;
1354
1355 static WCHAR btrfs[] = L"\\Btrfs";
1356
1357#ifndef __REACTOS__
1360
1361 if (!LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &luid)) {
1364 }
1365
1366 tp.PrivilegeCount = 1;
1367 tp.Privileges[0].Luid = luid;
1368 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1369
1370 if (!AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
1373 }
1374
1376
1377#if defined(_X86_) || defined(_AMD64_)
1378 check_cpu();
1379#endif
1380#endif
1381
1385
1387
1390
1391 if (!NT_SUCCESS(Status))
1392 return Status;
1393
1395 if (!NT_SUCCESS(Status)) {
1396 NtClose(h);
1397 return Status;
1398 }
1399
1400 // MSDN tells us to use IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, but there are
1401 // some instances where it fails and IOCTL_DISK_GET_DRIVE_GEOMETRY succeeds -
1402 // such as with spanned volumes.
1404 if (!NT_SUCCESS(Status)) {
1405 NtClose(h);
1406 return Status;
1407 }
1408
1409 if (def_sector_size == 0) {
1411
1412 if (sector_size == 0x200 || sector_size == 0)
1413 sector_size = 0x1000;
1414 } else {
1416 NtClose(h);
1418 }
1419
1421 }
1422
1423 if (def_node_size == 0)
1424 node_size = 0x4000;
1425 else {
1427 NtClose(h);
1429 }
1430
1431 node_size = def_node_size;
1432 }
1433
1434 if (Callback) {
1435 ULONG pc = 0;
1436 Callback(PROGRESS, 0, (PVOID)&pc);
1437 }
1438
1440
1443 goto end;
1444 }
1445
1446 do_full_trim(h);
1447
1448 incompat_flags = def_incompat_flags;
1450
1451 if (!Label) {
1452 empty_label.Buffer = NULL;
1453 empty_label.Length = empty_label.MaximumLength = 0;
1454 Label = &empty_label;
1455 }
1456
1457 Status = write_btrfs(h, gli.Length.QuadPart, Label, sector_size, node_size, incompat_flags);
1458
1460
1461end:
1463
1464 NtClose(h);
1465
1466 if (NT_SUCCESS(Status)) {
1467 btrfsus.Buffer = btrfs;
1468 btrfsus.Length = btrfsus.MaximumLength = (USHORT)(wcslen(btrfs) * sizeof(WCHAR));
1469
1470 InitializeObjectAttributes(&attr, &btrfsus, 0, NULL, NULL);
1471
1474
1475 if (NT_SUCCESS(Status)) {
1476 MOUNTDEV_NAME* mdn;
1477 ULONG mdnsize;
1478
1479 mdnsize = (ULONG)(offsetof(MOUNTDEV_NAME, Name[0]) + DriveRoot->Length);
1480 mdn = malloc(mdnsize);
1481
1482 mdn->NameLength = DriveRoot->Length;
1483 memcpy(mdn->Name, DriveRoot->Buffer, DriveRoot->Length);
1484
1485 NtDeviceIoControlFile(btrfsh, NULL, NULL, NULL, &iosb, IOCTL_BTRFS_PROBE_VOLUME, mdn, mdnsize, NULL, 0);
1486
1487 free(mdn);
1488
1489 NtClose(btrfsh);
1490 }
1491
1493 }
1494
1495#ifndef __REACTOS__
1496 if (Callback) {
1497 bool success = NT_SUCCESS(Status);
1498 Callback(DONE, 0, (PVOID)&success);
1499 }
1500#endif
1501
1502 return Status;
1503}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define IOCTL_BTRFS_PROBE_VOLUME
Definition: btrfsioctl.h:28
uint64_t def_incompat_flags
Definition: btrfslib.c:179
#define FSCTL_LOCK_VOLUME
Definition: btrfslib.c:74
static bool is_power_of_two(ULONG i)
Definition: btrfslib.c:1314
#define FSCTL_UNLOCK_VOLUME
Definition: btrfslib.c:75
static NTSTATUS write_btrfs(HANDLE h, uint64_t size, PUNICODE_STRING label, uint32_t sector_size, uint32_t node_size, uint64_t incompat_flags)
Definition: btrfslib.c:1061
ULONG def_node_size
Definition: btrfslib.c:178
static bool is_mounted_multi_device(HANDLE h, uint32_t sector_size)
Definition: btrfslib.c:1200
static void do_full_trim(HANDLE h)
Definition: btrfslib.c:1297
#define FSCTL_DISMOUNT_VOLUME
Definition: btrfslib.c:76
ULONG def_sector_size
Definition: btrfslib.c:178
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
BOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpPrivilegeName, PLUID lpLuid)
Definition: misc.c:782
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:374
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
#define CloseHandle
Definition: compat.h:739
#define GetCurrentProcess()
Definition: compat.h:759
#define FILE_SHARE_READ
Definition: compat.h:136
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
#define BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF
Definition: btrfs.h:115
#define BTRFS_INCOMPAT_FLAGS_BIG_METADATA
Definition: btrfs.h:120
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
GLuint GLuint end
Definition: gl.h:1545
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 token
Definition: glfuncs.h:210
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
#define L(x)
Definition: ntvdm.h:50
LARGE_INTEGER Length
Definition: winioctl.h:560
ULONG BytesPerSector
Definition: ntdddisk.h:409
USHORT NameLength
Definition: imports.h:143
WCHAR Name[1]
Definition: imports.h:144
Definition: cookie.c:202
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONGLONG QuadPart
Definition: typedefs.h:114
#define success(from, fromstr, to, tostr)
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:930
#define TOKEN_QUERY
Definition: setypes.h:928
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63

Referenced by FormatEx().

◆ free_chunks()

static void free_chunks ( LIST_ENTRY chunks)
static

Definition at line 324 of file btrfslib.c.

324 {
325 LIST_ENTRY* le;
326
327 le = chunks->Flink;
328 while (le != chunks) {
329 LIST_ENTRY *le2 = le->Flink;
331
332 free(c->chunk_item);
333 free(c);
334
335 le = le2;
336 }
337}

Referenced by write_btrfs().

◆ free_roots()

static void free_roots ( LIST_ENTRY roots)
static

Definition at line 297 of file btrfslib.c.

297 {
298 LIST_ENTRY* le;
299
300 le = roots->Flink;
301 while (le != roots) {
302 LIST_ENTRY *le2 = le->Flink, *le3;
304
305 le3 = r->items.Flink;
306 while (le3 != &r->items) {
307 LIST_ENTRY* le4 = le3->Flink;
309
310 if (item->data)
311 free(item->data);
312
313 free(item);
314
315 le3 = le4;
316 }
317
318 free(r);
319
320 le = le2;
321 }
322}

Referenced by write_btrfs().

◆ get_next_address()

static uint64_t get_next_address ( btrfs_chunk c)
static

Definition at line 479 of file btrfslib.c.

479 {
481
482 addr = c->lastoff;
483
484 while (superblock_collision(c, addr)) {
485 addr = addr - ((addr - c->offset) % c->chunk_item->stripe_length) + c->chunk_item->stripe_length;
486
487 if (addr >= c->offset + c->chunk_item->size) // chunk has been exhausted
488 return 0;
489 }
490
491 return addr;
492}
static bool superblock_collision(btrfs_chunk *c, uint64_t address)
Definition: btrfslib.c:458
GLenum const GLvoid * addr
Definition: glext.h:9621

Referenced by assign_addresses().

◆ get_uuid()

static void get_uuid ( BTRFS_UUID uuid)
static

Definition at line 687 of file btrfslib.c.

687 {
688#else
689static void get_uuid(BTRFS_UUID* uuid, ULONG* seed) {
690#endif
691 uint8_t i;
692
693 for (i = 0; i < 16; i+=2) {
694#ifndef __REACTOS__
695 ULONG r = rand();
696#else
697 ULONG r = RtlRandom(seed);
698#endif
699
700 uuid->uuid[i] = (r & 0xff00) >> 8;
701 uuid->uuid[i+1] = r & 0xff;
702 }
703}
static void get_uuid(BTRFS_UUID *uuid)
Definition: btrfslib.c:687
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
Definition: msctf.idl:550
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)

Referenced by get_uuid(), init_device(), and write_btrfs().

◆ GetFilesystemInformation()

BOOL __stdcall GetFilesystemInformation ( uint32_t  unk1,
uint32_t  unk2,
void unk3 
)

Definition at line 1574 of file btrfslib.c.

1574 {
1575 // STUB - undocumented
1576
1577 return true;
1578}

◆ init_device()

static void init_device ( btrfs_dev dev,
uint64_t  id,
uint64_t  size,
BTRFS_UUID fsuuid,
uint32_t  sector_size 
)
static

Definition at line 706 of file btrfslib.c.

706 {
707#else
709#endif
710 dev->dev_item.dev_id = id;
711 dev->dev_item.num_bytes = size;
712 dev->dev_item.bytes_used = 0;
713 dev->dev_item.optimal_io_align = sector_size;
714 dev->dev_item.optimal_io_width = sector_size;
715 dev->dev_item.minimal_io_size = sector_size;
716 dev->dev_item.type = 0;
717 dev->dev_item.generation = 0;
718 dev->dev_item.start_offset = 0;
719 dev->dev_item.dev_group = 0;
720 dev->dev_item.seek_speed = 0;
721 dev->dev_item.bandwidth = 0;
722#ifndef __REACTOS__
723 get_uuid(&dev->dev_item.device_uuid);
724#else
725 get_uuid(&dev->dev_item.device_uuid, seed);
726#endif
727 dev->dev_item.fs_uuid = *fsuuid;
728
729 dev->last_alloc = 0x100000; // skip first megabyte
730}
static void init_device(btrfs_dev *dev, uint64_t id, uint64_t size, BTRFS_UUID *fsuuid, uint32_t sector_size)
Definition: btrfslib.c:706

Referenced by init_device(), and write_btrfs().

◆ init_fs_tree()

static void init_fs_tree ( btrfs_root r,
uint32_t  node_size 
)
static

Definition at line 916 of file btrfslib.c.

916 {
917 INODE_ITEM ii;
920
921 memset(&ii, 0, sizeof(INODE_ITEM));
922
923 ii.generation = 1;
924 ii.st_blocks = node_size;
925 ii.st_nlink = 1;
926 ii.st_mode = 040755;
927
929 time.LowPart = filetime.dwLowDateTime;
930 time.HighPart = filetime.dwHighDateTime;
931
933 ii.st_ctime = ii.st_mtime = ii.st_atime;
934
936
938}
static void add_inode_ref(btrfs_root *r, uint64_t inode, uint64_t parent, uint64_t index, const char *name)
Definition: btrfslib.c:903
static __inline void win_time_to_unix(LARGE_INTEGER t, BTRFS_TIME *out)
Definition: btrfslib.c:877
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define TYPE_INODE_ITEM
Definition: btrfs.h:23
__u16 time
Definition: mkdosfs.c:8
BTRFS_TIME st_mtime
Definition: btrfs.h:303
BTRFS_TIME st_atime
Definition: btrfs.h:301
BTRFS_TIME st_ctime
Definition: btrfs.h:302

Referenced by write_btrfs().

◆ InitializeListHead()

FORCEINLINE VOID InitializeListHead ( PLIST_ENTRY  ListHead)

Definition at line 121 of file btrfslib.c.

121 {
122 ListHead->Flink = ListHead->Blink = ListHead;
123}
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122

◆ InsertTailList()

FORCEINLINE VOID InsertTailList ( PLIST_ENTRY  ListHead,
PLIST_ENTRY  Entry 
)

Definition at line 125 of file btrfslib.c.

125 {
126 PLIST_ENTRY Blink;
127
128 Blink = ListHead->Blink;
129 Entry->Flink = ListHead;
130 Entry->Blink = Blink;
131 Blink->Flink = Entry;
132 ListHead->Blink = Entry;
133}
base of all file and directory entries
Definition: entries.h:83

◆ is_mounted_multi_device()

static bool is_mounted_multi_device ( HANDLE  h,
uint32_t  sector_size 
)
static

Definition at line 1200 of file btrfslib.c.

1200 {
1202 superblock* sb;
1203 ULONG sblen;
1205 LARGE_INTEGER off;
1206 BTRFS_UUID fsuuid, devuuid;
1209 HANDLE h2;
1210 btrfs_filesystem *bfs = NULL, *bfs2;
1211 ULONG bfssize;
1212 bool ret = false;
1213
1214 static WCHAR btrfs[] = L"\\Btrfs";
1215
1216 sblen = sizeof(*sb);
1217 if (sblen & (sector_size - 1))
1218 sblen = (sblen & sector_size) + sector_size;
1219
1220 sb = malloc(sblen);
1221
1222 off.QuadPart = superblock_addrs[0];
1223
1224 Status = NtReadFile(h, NULL, NULL, NULL, &iosb, sb, sblen, &off, NULL);
1225 if (!NT_SUCCESS(Status)) {
1226 free(sb);
1227 return false;
1228 }
1229
1230 if (sb->magic != BTRFS_MAGIC) {
1231 free(sb);
1232 return false;
1233 }
1234
1236 free(sb);
1237 return false;
1238 }
1239
1240 fsuuid = sb->uuid;
1241 devuuid = sb->dev_item.device_uuid;
1242
1243 free(sb);
1244
1245 us.Length = us.MaximumLength = (USHORT)(wcslen(btrfs) * sizeof(WCHAR));
1246 us.Buffer = btrfs;
1247
1249
1252 if (!NT_SUCCESS(Status)) // not a problem, it usually just means the driver isn't loaded
1253 return false;
1254
1255 bfssize = 0;
1256
1257 do {
1258 bfssize += 1024;
1259
1260 if (bfs) free(bfs);
1261 bfs = malloc(bfssize);
1262
1264 } while (Status == STATUS_BUFFER_OVERFLOW);
1265
1266 if (!NT_SUCCESS(Status))
1267 goto end;
1268
1269 if (bfs->num_devices != 0) {
1270 bfs2 = bfs;
1271 while (true) {
1272 if (RtlCompareMemory(&bfs2->uuid, &fsuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
1273 if (bfs2->num_devices == 1)
1274 ret = false;
1275 else
1276 ret = look_for_device(bfs2, &devuuid);
1277
1278 goto end;
1279 }
1280
1281 if (bfs2->next_entry == 0)
1282 break;
1283 else
1284 bfs2 = (btrfs_filesystem*)((uint8_t*)bfs2 + bfs2->next_entry);
1285 }
1286 }
1287
1288end:
1289 NtClose(h2);
1290
1291 if (bfs)
1292 free(bfs);
1293
1294 return ret;
1295}
#define BTRFS_MAGIC
Definition: btrfs.h:42
_In_ uint16_t _Out_ ULONG * atts
Definition: btrfs_drv.h:1107
#define IOCTL_BTRFS_QUERY_FILESYSTEMS
Definition: btrfsioctl.h:21
static bool check_superblock_checksum(superblock *sb)
Definition: btrfslib.c:1165
static bool look_for_device(btrfs_filesystem *bfs, BTRFS_UUID *devuuid)
Definition: btrfslib.c:1148
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
static const uint64_t superblock_addrs[]
Definition: btrfs.h:16
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
static const BYTE us[]
Definition: encode.c:689
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
BTRFS_UUID device_uuid
Definition: btrfs.h:190
uint32_t num_devices
Definition: btrfsioctl.h:191
uint64_t magic
Definition: btrfs.h:228
DEV_ITEM dev_item
Definition: btrfs.h:251
int ret

Referenced by FormatEx2().

◆ is_power_of_two()

static bool is_power_of_two ( ULONG  i)
static

Definition at line 1314 of file btrfslib.c.

1314 {
1315 return ((i != 0) && !(i & (i - 1)));
1316}

Referenced by FormatEx2().

◆ is_ssd()

static bool is_ssd ( HANDLE  h)
static

Definition at line 975 of file btrfslib.c.

975 {
976 ULONG aptelen;
981
982 aptelen = sizeof(ATA_PASS_THROUGH_EX) + 512;
983 apte = malloc(aptelen);
984
985 RtlZeroMemory(apte, aptelen);
986
987 apte->Length = sizeof(ATA_PASS_THROUGH_EX);
989 apte->DataTransferLength = aptelen - sizeof(ATA_PASS_THROUGH_EX);
990 apte->TimeOutValue = 3;
991 apte->DataBufferOffset = apte->Length;
993
994 Status = NtDeviceIoControlFile(h, NULL, NULL, NULL, &iosb, IOCTL_ATA_PASS_THROUGH, apte, aptelen, apte, aptelen);
995
996 if (NT_SUCCESS(Status)) {
997 idd = (IDENTIFY_DEVICE_DATA*)((uint8_t*)apte + sizeof(ATA_PASS_THROUGH_EX));
998
999 if (idd->NominalMediaRotationRate == 1) {
1000 free(apte);
1001 return true;
1002 }
1003 }
1004
1005 free(apte);
1006
1007 return false;
1008}
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
#define IOCTL_ATA_PASS_THROUGH
Definition: ntddscsi.h:40
struct _ATA_PASS_THROUGH_EX ATA_PASS_THROUGH_EX
ULONG DataTransferLength
Definition: ntddscsi.h:198
UCHAR CurrentTaskFile[8]
Definition: ntddscsi.h:203
ULONG_PTR DataBufferOffset
Definition: ntddscsi.h:201
USHORT NominalMediaRotationRate
Definition: ata.h:243
#define ATA_FLAGS_DATA_IN
Definition: uata_ctl.h:222

Referenced by write_btrfs().

◆ look_for_device()

static bool look_for_device ( btrfs_filesystem bfs,
BTRFS_UUID devuuid 
)
static

Definition at line 1148 of file btrfslib.c.

1148 {
1149 uint32_t i;
1151
1152 for (i = 0; i < bfs->num_devices; i++) {
1153 if (i == 0)
1154 dev = &bfs->device;
1155 else
1157
1158 if (RtlCompareMemory(&dev->uuid, devuuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID))
1159 return true;
1160 }
1161
1162 return false;
1163}
btrfs_filesystem_device device
Definition: btrfsioctl.h:192

Referenced by is_mounted_multi_device().

◆ NtReadFile()

NTSTATUS NTAPI NtReadFile ( HANDLE  FileHandle,
HANDLE  Event,
PIO_APC_ROUTINE  ApcRoutine,
PVOID  ApcContext,
PIO_STATUS_BLOCK  IoStatusBlock,
PVOID  Buffer,
ULONG  Length,
PLARGE_INTEGER  ByteOffset,
PULONG  Key 
)

Referenced by is_mounted_multi_device().

◆ NtWriteFile()

NTSTATUS NTAPI NtWriteFile ( HANDLE  FileHandle,
HANDLE  Event,
PIO_APC_ROUTINE  ApcRoutine,
PVOID  ApcContext,
PIO_STATUS_BLOCK  IoStatusBlock,
PVOID  Buffer,
ULONG  Length,
PLARGE_INTEGER  ByteOffset,
PULONG  Key 
)

◆ set_default_subvol()

static void set_default_subvol ( btrfs_root root_root,
uint32_t  node_size 
)
static

Definition at line 1029 of file btrfslib.c.

1029 {
1030 INODE_ITEM ii;
1033
1034 static const char default_subvol[] = "default";
1035 static const uint32_t default_hash = 0x8dbfc2d2;
1036
1037 add_inode_ref(root_root, BTRFS_ROOT_FSTREE, BTRFS_ROOT_TREEDIR, 0, default_subvol);
1038
1039 memset(&ii, 0, sizeof(INODE_ITEM));
1040
1041 ii.generation = 1;
1042 ii.st_blocks = node_size;
1043 ii.st_nlink = 1;
1044 ii.st_mode = 040755;
1045
1047 time.LowPart = filetime.dwLowDateTime;
1048 time.HighPart = filetime.dwHighDateTime;
1049
1051 ii.st_ctime = ii.st_mtime = ii.otime = ii.st_atime;
1052
1053 add_item(root_root, BTRFS_ROOT_TREEDIR, TYPE_INODE_ITEM, 0, &ii, sizeof(INODE_ITEM));
1054
1056
1058 0xffffffffffffffff, 0, BTRFS_TYPE_DIRECTORY, default_subvol);
1059}
static void add_dir_item(btrfs_root *root, uint64_t inode, uint32_t hash, uint64_t key_objid, uint8_t key_type, uint64_t key_offset, uint64_t transid, uint8_t type, const char *name)
Definition: btrfslib.c:1010
#define BTRFS_ROOT_TREEDIR
Definition: btrfs.h:59
#define BTRFS_ROOT_FSTREE
Definition: btrfs.h:58
#define BTRFS_TYPE_DIRECTORY
Definition: shellext.h:86
BTRFS_TIME otime
Definition: btrfs.h:304

Referenced by write_btrfs().

◆ SetCsumType()

void __stdcall SetCsumType ( uint16_t  csum_type)

Definition at line 1570 of file btrfslib.c.

1570 {
1571 def_csum_type = csum_type;
1572}

◆ SetIncompatFlags()

void __stdcall SetIncompatFlags ( uint64_t  incompat_flags)

Definition at line 1566 of file btrfslib.c.

1566 {
1567 def_incompat_flags = incompat_flags;
1568}

◆ SetSizes()

void __stdcall SetSizes ( ULONG  sector,
ULONG  node 
)

Definition at line 1558 of file btrfslib.c.

1558 {
1559 if (sector != 0)
1561
1562 if (node != 0)
1564}
uint32_t sector
Definition: isohybrid.c:61
Definition: dlist.c:348

◆ superblock_collision()

static bool superblock_collision ( btrfs_chunk c,
uint64_t  address 
)
static

Definition at line 458 of file btrfslib.c.

458 {
459 CHUNK_ITEM_STRIPE* cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
460 uint64_t stripe = (address - c->offset) / c->chunk_item->stripe_length;
461 uint16_t i, j;
462
463 for (i = 0; i < c->chunk_item->num_stripes; i++) {
464 j = 0;
465 while (superblock_addrs[j] != 0) {
466 if (superblock_addrs[j] >= cis[i].offset) {
467 uint64_t stripe2 = (superblock_addrs[j] - cis[i].offset) / c->chunk_item->stripe_length;
468
469 if (stripe2 == stripe)
470 return true;
471 }
472 j++;
473 }
474 }
475
476 return false;
477}
GLuint address
Definition: glext.h:9393
if(dx< 0)
Definition: linetemp.h:194
Definition: write.c:113

Referenced by get_next_address().

◆ win_time_to_unix()

static __inline void win_time_to_unix ( LARGE_INTEGER  t,
BTRFS_TIME out 
)
static

Definition at line 877 of file btrfslib.c.

877 {
878 ULONGLONG l = t.QuadPart - 116444736000000000;
879
880 out->seconds = l / 10000000;
881 out->nanoseconds = (l % 10000000) * 100;
882}
r l[0]
Definition: byte_order.h:168
GLdouble GLdouble t
Definition: gl.h:2047
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by init_fs_tree(), and set_default_subvol().

◆ write_btrfs()

static NTSTATUS write_btrfs ( HANDLE  h,
uint64_t  size,
PUNICODE_STRING  label,
uint32_t  sector_size,
uint32_t  node_size,
uint64_t  incompat_flags 
)
static

Definition at line 1061 of file btrfslib.c.

1061 {
1063 LIST_ENTRY roots, chunks;
1064 btrfs_root *root_root, *chunk_root, *extent_root, *dev_root, *fs_root, *reloc_root;
1065 btrfs_chunk *sys_chunk, *metadata_chunk;
1066 btrfs_dev dev;
1067 BTRFS_UUID fsuuid, chunkuuid;
1068 bool ssd;
1069 uint64_t metadata_flags;
1070#ifdef __REACTOS__
1071 ULONG seed;
1072#endif
1073
1074#ifndef __REACTOS__
1075 srand((unsigned int)time(0));
1076 get_uuid(&fsuuid);
1077 get_uuid(&chunkuuid);
1078#else
1079 seed = NtGetTickCount();
1080 get_uuid(&fsuuid, &seed);
1081 get_uuid(&chunkuuid, &seed);
1082#endif
1083
1084 InitializeListHead(&roots);
1085 InitializeListHead(&chunks);
1086
1087 root_root = add_root(&roots, BTRFS_ROOT_ROOT);
1088 chunk_root = add_root(&roots, BTRFS_ROOT_CHUNK);
1089 extent_root = add_root(&roots, BTRFS_ROOT_EXTENT);
1090 dev_root = add_root(&roots, BTRFS_ROOT_DEVTREE);
1092 fs_root = add_root(&roots, BTRFS_ROOT_FSTREE);
1094
1095#ifndef __REACTOS__
1096 init_device(&dev, 1, size, &fsuuid, sector_size);
1097#else
1098 init_device(&dev, 1, size, &fsuuid, sector_size, &seed);
1099#endif
1100
1101 ssd = is_ssd(h);
1102
1103 sys_chunk = add_chunk(&chunks, BLOCK_FLAG_SYSTEM | (ssd ? 0 : BLOCK_FLAG_DUPLICATE), chunk_root, &dev, dev_root, &chunkuuid, sector_size);
1104 if (!sys_chunk)
1105 return STATUS_INTERNAL_ERROR;
1106
1107 metadata_flags = BLOCK_FLAG_METADATA;
1108
1109 if (!ssd && !(incompat_flags & BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS))
1110 metadata_flags |= BLOCK_FLAG_DUPLICATE;
1111
1112 if (incompat_flags & BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS)
1113 metadata_flags |= BLOCK_FLAG_DATA;
1114
1115 metadata_chunk = add_chunk(&chunks, metadata_flags, chunk_root, &dev, dev_root, &chunkuuid, sector_size);
1116 if (!metadata_chunk)
1117 return STATUS_INTERNAL_ERROR;
1118
1119 add_item(chunk_root, 1, TYPE_DEV_ITEM, dev.dev_item.dev_id, &dev.dev_item, sizeof(DEV_ITEM));
1120
1121 set_default_subvol(root_root, node_size);
1122
1123 init_fs_tree(fs_root, node_size);
1124 init_fs_tree(reloc_root, node_size);
1125
1126 assign_addresses(&roots, sys_chunk, metadata_chunk, node_size, root_root, extent_root, incompat_flags & BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA);
1127
1128 add_block_group_items(&chunks, extent_root);
1129
1130 Status = write_roots(h, &roots, node_size, &fsuuid, &chunkuuid);
1131 if (!NT_SUCCESS(Status))
1132 return Status;
1133
1135 if (!NT_SUCCESS(Status))
1136 return Status;
1137
1138 Status = write_superblocks(h, &dev, chunk_root, root_root, extent_root, sys_chunk, node_size, &fsuuid, sector_size, label, incompat_flags);
1139 if (!NT_SUCCESS(Status))
1140 return Status;
1141
1142 free_roots(&roots);
1143 free_chunks(&chunks);
1144
1145 return STATUS_SUCCESS;
1146}
static bool is_ssd(HANDLE h)
Definition: btrfslib.c:975
static btrfs_chunk * add_chunk(LIST_ENTRY *chunks, uint64_t flags, btrfs_root *chunk_root, btrfs_dev *dev, btrfs_root *dev_root, BTRFS_UUID *chunkuuid, uint32_t sector_size)
Definition: btrfslib.c:392
static NTSTATUS write_superblocks(HANDLE h, btrfs_dev *dev, btrfs_root *chunk_root, btrfs_root *root_root, btrfs_root *extent_root, btrfs_chunk *sys_chunk, uint32_t node_size, BTRFS_UUID *fsuuid, uint32_t sector_size, PUNICODE_STRING label, uint64_t incompat_flags)
Definition: btrfslib.c:752
static NTSTATUS clear_first_megabyte(HANDLE h)
Definition: btrfslib.c:957
static void add_block_group_items(LIST_ENTRY *chunks, btrfs_root *extent_root)
Definition: btrfslib.c:940
static btrfs_root * add_root(LIST_ENTRY *roots, uint64_t id)
Definition: btrfslib.c:284
static NTSTATUS write_roots(HANDLE h, LIST_ENTRY *roots, uint32_t node_size, BTRFS_UUID *fsuuid, BTRFS_UUID *chunkuuid)
Definition: btrfslib.c:620
static void init_fs_tree(btrfs_root *r, uint32_t node_size)
Definition: btrfslib.c:916
static void free_roots(LIST_ENTRY *roots)
Definition: btrfslib.c:297
static void set_default_subvol(btrfs_root *root_root, uint32_t node_size)
Definition: btrfslib.c:1029
static void free_chunks(LIST_ENTRY *chunks)
Definition: btrfslib.c:324
static void assign_addresses(LIST_ENTRY *roots, btrfs_chunk *sys_chunk, btrfs_chunk *metadata_chunk, uint32_t node_size, btrfs_root *root_root, btrfs_root *extent_root, bool skinny)
Definition: btrfslib.c:507
#define BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA
Definition: btrfs.h:123
#define BTRFS_ROOT_DATA_RELOC
Definition: btrfs.h:63
#define TYPE_DEV_ITEM
Definition: btrfs.h:47
#define BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS
Definition: btrfs.h:117
#define BTRFS_ROOT_DEVTREE
Definition: btrfs.h:57
#define BTRFS_ROOT_CHECKSUM
Definition: btrfs.h:60
void __cdecl srand(_In_ unsigned int _Seed)
char * reloc_root
Definition: mkisofs.c:177
static const WCHAR label[]
Definition: itemdlg.c:1546
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define NtGetTickCount
Definition: rtlp.h:163
#define BLOCK_FLAG_DATA
Definition: shellext.h:75

Referenced by FormatEx2().

◆ write_data()

static NTSTATUS write_data ( HANDLE  h,
uint64_t  address,
btrfs_chunk c,
void data,
ULONG  size 
)
static

Definition at line 580 of file btrfslib.c.

580 {
582 uint16_t i;
584 LARGE_INTEGER off;
586
587 cis = (CHUNK_ITEM_STRIPE*)&c->chunk_item[1];
588
589 for (i = 0; i < c->chunk_item->num_stripes; i++) {
590 off.QuadPart = cis[i].offset + address - c->offset;
591
592 Status = NtWriteFile(h, NULL, NULL, NULL, &iosb, data, size, &off, NULL);
593 if (!NT_SUCCESS(Status))
594 return Status;
595 }
596
597 return STATUS_SUCCESS;
598}

◆ write_roots()

static NTSTATUS write_roots ( HANDLE  h,
LIST_ENTRY roots,
uint32_t  node_size,
BTRFS_UUID fsuuid,
BTRFS_UUID chunkuuid 
)
static

Definition at line 620 of file btrfslib.c.

620 {
621 LIST_ENTRY *le, *le2;
623 uint8_t* tree;
624
625 tree = malloc(node_size);
626
627 le = roots->Flink;
628 while (le != roots) {
630 uint8_t* dp;
631 leaf_node* ln;
632
633 memset(tree, 0, node_size);
634
635 r->header.num_items = 0;
636 r->header.fs_uuid = *fsuuid;
638 r->header.chunk_tree_uuid = *chunkuuid;
639 r->header.generation = 1;
640 r->header.tree_id = r->id;
641
642 ln = (leaf_node*)(tree + sizeof(tree_header));
643
644 dp = tree + node_size;
645
646 le2 = r->items.Flink;
647 while (le2 != &r->items) {
649
650 ln->key = item->key;
651 ln->size = item->size;
652
653 if (item->size > 0) {
654 dp -= item->size;
655 memcpy(dp, item->data, item->size);
656
657 ln->offset = (uint32_t)(dp - tree - sizeof(tree_header));
658 } else
659 ln->offset = 0;
660
661 ln = &ln[1];
662
663 r->header.num_items++;
664
665 le2 = le2->Flink;
666 }
667
668 memcpy(tree, &r->header, sizeof(tree_header));
669
670 calc_tree_checksum((tree_header*)tree, node_size);
671
672 Status = write_data(h, r->header.address, r->c, tree, node_size);
673 if (!NT_SUCCESS(Status)) {
674 free(tree);
675 return Status;
676 }
677
678 le = le->Flink;
679 }
680
681 free(tree);
682
683 return STATUS_SUCCESS;
684}
struct _tree tree
static void calc_tree_checksum(tree_header *th, uint32_t node_size)
Definition: btrfslib.c:600
#define HEADER_FLAG_WRITTEN
Definition: btrfs.h:149
#define HEADER_FLAG_MIXED_BACKREF
Definition: btrfs.h:151
tree_header header
Definition: btrfs_drv.h:426
uint32_t offset
Definition: btrfs.h:167
KEY key
Definition: btrfs.h:166
uint32_t size
Definition: btrfs.h:168

Referenced by write_btrfs().

◆ write_superblocks()

static NTSTATUS write_superblocks ( HANDLE  h,
btrfs_dev dev,
btrfs_root chunk_root,
btrfs_root root_root,
btrfs_root extent_root,
btrfs_chunk sys_chunk,
uint32_t  node_size,
BTRFS_UUID fsuuid,
uint32_t  sector_size,
PUNICODE_STRING  label,
uint64_t  incompat_flags 
)
static

Definition at line 752 of file btrfslib.c.

753 {
756 ULONG sblen;
757 int i;
758 superblock* sb;
759 KEY* key;
760 uint64_t bytes_used;
761 LIST_ENTRY* le;
762
763 sblen = sizeof(*sb);
764 if (sblen & (sector_size - 1))
765 sblen = (sblen & sector_size) + sector_size;
766
767 bytes_used = 0;
768
769 le = extent_root->items.Flink;
770 while (le != &extent_root->items) {
772
773 if (item->key.obj_type == TYPE_EXTENT_ITEM)
774 bytes_used += item->key.offset;
775 else if (item->key.obj_type == TYPE_METADATA_ITEM)
776 bytes_used += node_size;
777
778 le = le->Flink;
779 }
780
781 sb = malloc(sblen);
782 memset(sb, 0, sblen);
783
784 sb->uuid = *fsuuid;
785 sb->flags = 1;
787 sb->generation = 1;
788 sb->root_tree_addr = root_root->header.address;
789 sb->chunk_tree_addr = chunk_root->header.address;
790 sb->total_bytes = dev->dev_item.num_bytes;
791 sb->bytes_used = bytes_used;
793 sb->num_devices = 1;
795 sb->node_size = node_size;
796 sb->leaf_size = node_size;
798 sb->n = sizeof(KEY) + sizeof(CHUNK_ITEM) + (sys_chunk->chunk_item->num_stripes * sizeof(CHUNK_ITEM_STRIPE));
800 sb->incompat_flags = incompat_flags;
802 memcpy(&sb->dev_item, &dev->dev_item, sizeof(DEV_ITEM));
803
804 if (label->Length > 0) {
805#ifdef __REACTOS__
806 ANSI_STRING as;
807 unsigned int i;
808
809 for (i = 0; i < label->Length / sizeof(WCHAR); i++) {
810#else
811 ULONG utf8len;
812
813 for (unsigned int i = 0; i < label->Length / sizeof(WCHAR); i++) {
814#endif
815 if (label->Buffer[i] == '/' || label->Buffer[i] == '\\') {
816 free(sb);
818 }
819 }
820
821#ifndef __REACTOS__
822 utf8len = WideCharToMultiByte(CP_UTF8, 0, label->Buffer, label->Length / sizeof(WCHAR), NULL, 0, NULL, NULL);
823
824 if (utf8len == 0 || utf8len > MAX_LABEL_SIZE) {
825 free(sb);
827 }
828
829 if (WideCharToMultiByte(CP_UTF8, 0, label->Buffer, label->Length / sizeof(WCHAR), sb->label, utf8len, NULL, NULL) == 0) {
830#else
831 as.Buffer = sb->label;
832 as.Length = 0;
834
836 {
837#endif
838 free(sb);
840 }
841 }
842 sb->cache_generation = 0xffffffffffffffff;
843
845 key->obj_id = 0x100;
846 key->obj_type = TYPE_CHUNK_ITEM;
847 key->offset = sys_chunk->offset;
848 memcpy(&key[1], sys_chunk->chunk_item, sizeof(CHUNK_ITEM) + (sys_chunk->chunk_item->num_stripes * sizeof(CHUNK_ITEM_STRIPE)));
849
850 i = 0;
851 while (superblock_addrs[i] != 0) {
852 LARGE_INTEGER off;
853
854 if (superblock_addrs[i] > dev->dev_item.num_bytes)
855 break;
856
858
860
862
863 Status = NtWriteFile(h, NULL, NULL, NULL, &iosb, sb, sblen, &off, NULL);
864 if (!NT_SUCCESS(Status)) {
865 free(sb);
866 return Status;
867 }
868
869 i++;
870 }
871
872 free(sb);
873
874 return STATUS_SUCCESS;
875}
static void calc_superblock_checksum(superblock *sb)
Definition: btrfslib.c:732
#define FALSE
Definition: types.h:117
#define WideCharToMultiByte
Definition: compat.h:111
#define MAX_LABEL_SIZE
Definition: btrfs.h:19
#define KEY
Definition: profile.c:30
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define CP_UTF8
Definition: nls.h:20
USHORT MaximumLength
Definition: env_spec_w32.h:377
LIST_ENTRY items
Definition: btrfslib.c:159
tree_header header
Definition: btrfslib.c:157
Definition: copy.c:22
uint64_t flags
Definition: btrfs.h:227
uint32_t sector_size
Definition: btrfs.h:238
uint64_t bytes_used
Definition: btrfs.h:235
uint64_t root_tree_addr
Definition: btrfs.h:230
uint64_t chunk_root_generation
Definition: btrfs.h:243
uint64_t root_dir_objectid
Definition: btrfs.h:236
uint32_t node_size
Definition: btrfs.h:239
uint32_t leaf_size
Definition: btrfs.h:240
uint32_t stripe_size
Definition: btrfs.h:241
uint64_t sb_phys_addr
Definition: btrfs.h:226
uint8_t sys_chunk_array[SYS_CHUNK_ARRAY_SIZE]
Definition: btrfs.h:257
uint64_t incompat_flags
Definition: btrfs.h:246
uint64_t generation
Definition: btrfs.h:229
char label[MAX_LABEL_SIZE]
Definition: btrfs.h:252
uint64_t cache_generation
Definition: btrfs.h:253
uint64_t num_devices
Definition: btrfs.h:237
uint64_t chunk_tree_addr
Definition: btrfs.h:231
uint32_t n
Definition: btrfs.h:242
uint64_t total_bytes
Definition: btrfs.h:234
uint64_t address
Definition: btrfs.h:156
#define STATUS_INVALID_VOLUME_LABEL
Definition: udferr_usr.h:156

Referenced by write_btrfs().

Variable Documentation

◆ def_csum_type

◆ def_incompat_flags

◆ def_node_size

ULONG def_node_size = 0

Definition at line 178 of file btrfslib.c.

Referenced by FormatEx2(), and SetSizes().

◆ def_sector_size

ULONG def_sector_size = 0

Definition at line 178 of file btrfslib.c.

Referenced by FormatEx2(), and SetSizes().

◆ module

Definition at line 177 of file btrfslib.c.