ReactOS 0.4.15-dev-7942-gd23573b
btrfs.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for btrfs.c:

Go to the source code of this file.

Classes

struct  _BTRFS_INFO
 

Macros

#define TAG_BTRFS_INFO   'IftB'
 
#define TAG_BTRFS_CHUNK_MAP   'CftB'
 
#define TAG_BTRFS_NODE   'NftB'
 
#define TAG_BTRFS_FILE   'FftB'
 
#define TAG_BTRFS_LINK   'LftB'
 
#define INVALID_INODE   _UI64_MAX
 
#define INVALID_ADDRESS   _UI64_MAX
 
#define READ_ERROR   _UI64_MAX
 

Typedefs

typedef struct _BTRFS_INFO BTRFS_INFO
 
typedef int(* cmp_func) (const void *ptr1, const void *ptr2)
 

Functions

 DBG_DEFAULT_CHANNEL (FILESYSTEM)
 
static int bin_search (void *ptr, int item_size, void *cmp_item, cmp_func func, int min, int max, int *slot)
 
static int btrfs_comp_chunk_map (struct btrfs_chunk_map_item *m1, struct btrfs_chunk_map_item *m2)
 
static void insert_chunk_item (struct btrfs_chunk_map *chunk_map, struct btrfs_chunk_map_item *item)
 
static void insert_map (struct btrfs_chunk_map *chunk_map, const struct btrfs_disk_key *key, struct btrfs_chunk *chunk)
 
static unsigned long btrfs_chunk_item_size (int num_stripes)
 
static void init_path (const struct btrfs_super_block *sb, struct btrfs_path *path)
 
static void free_path (struct btrfs_path *path)
 
static struct btrfs_itempath_current_item (struct btrfs_path *path)
 
static UCHARpath_current_data (struct btrfs_path *path)
 
static const struct btrfs_disk_keypath_current_disk_key (struct btrfs_path *path)
 
static int btrfs_comp_keys (const struct btrfs_disk_key *k1, const struct btrfs_disk_key *k2)
 
static int btrfs_comp_keys_type (const struct btrfs_disk_key *k1, const struct btrfs_disk_key *k2)
 
static u64 logical_physical (struct btrfs_chunk_map *chunk_map, u64 logical)
 
static BOOLEAN disk_read (ULONG DeviceId, u64 physical, void *dest, u32 count)
 
static BOOLEAN _BtrFsSearchTree (PBTRFS_INFO BtrFsInfo, u64 loffset, u8 level, struct btrfs_disk_key *key, struct btrfs_path *path)
 
static BOOLEAN BtrFsSearchTree (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, struct btrfs_disk_key *key, struct btrfs_path *path)
 
static BOOLEAN BtrFsSearchTreeType (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 objectid, u8 type, struct btrfs_path *path)
 
static int next_slot (PBTRFS_INFO BtrFsInfo, struct btrfs_disk_key *key, struct btrfs_path *path)
 
static int prev_slot (struct btrfs_disk_key *key, struct btrfs_path *path)
 
static void btrfs_read_sys_chunk_array (PBTRFS_INFO BtrFsInfo)
 
static void btrfs_read_chunk_tree (PBTRFS_INFO BtrFsInfo)
 
static BOOLEAN verify_dir_item (struct btrfs_dir_item *item, u32 start, u32 total)
 
static struct btrfs_dir_itemBtrFsMatchDirItemName (struct btrfs_path *path, const char *name, int name_len)
 
static BOOLEAN BtrFsLookupDirItem (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 dir, const char *name, int name_len, struct btrfs_dir_item *item)
 
static BOOLEAN BtrFsLookupDirItemI (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 dir_haystack, const char *name, int name_len, struct btrfs_dir_item *ret_item)
 
static u64 btrfs_read_extent_inline (struct btrfs_path *path, struct btrfs_file_extent_item *extent, u64 offset, u64 size, char *out)
 
static u64 btrfs_read_extent_reg (PBTRFS_INFO BtrFsInfo, struct btrfs_path *path, struct btrfs_file_extent_item *extent, u64 offset, u64 size, char *out)
 
static u64 btrfs_file_read (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, u64 offset, u64 size, char *buf)
 
static u64 btrfs_lookup_inode_ref (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, struct btrfs_inode_ref *refp, char *name)
 
static int btrfs_lookup_inode (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, struct btrfs_disk_key *location, struct btrfs_inode_item *item, struct btrfs_root_item *new_root)
 
static BOOLEAN btrfs_readlink (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, char **target)
 
static u64 get_parent_inode (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, struct btrfs_inode_item *inode_item)
 
static int next_length (const char *path)
 
static const charskip_current_directories (const char *cur)
 
static u64 btrfs_lookup_path (PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, const char *path, u8 *type_p, struct btrfs_inode_item *inode_item_p, int symlink_limit)
 
ARC_STATUS BtrFsClose (ULONG FileId)
 
ARC_STATUS BtrFsGetFileInformation (ULONG FileId, FILEINFORMATION *Information)
 
ARC_STATUS BtrFsOpen (CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
 
ARC_STATUS BtrFsRead (ULONG FileId, VOID *Buffer, ULONG Size, ULONG *BytesRead)
 
ARC_STATUS BtrFsSeek (ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
 
const DEVVTBLBtrFsMount (ULONG DeviceId)
 

Variables

PBTRFS_INFO BtrFsVolumes [MAX_FDS]
 
const DEVVTBL BtrFsFuncTable
 

Macro Definition Documentation

◆ INVALID_ADDRESS

#define INVALID_ADDRESS   _UI64_MAX

Definition at line 22 of file btrfs.c.

◆ INVALID_INODE

#define INVALID_INODE   _UI64_MAX

Definition at line 21 of file btrfs.c.

◆ READ_ERROR

#define READ_ERROR   _UI64_MAX

Definition at line 23 of file btrfs.c.

◆ TAG_BTRFS_CHUNK_MAP

#define TAG_BTRFS_CHUNK_MAP   'CftB'

Definition at line 16 of file btrfs.c.

◆ TAG_BTRFS_FILE

#define TAG_BTRFS_FILE   'FftB'

Definition at line 18 of file btrfs.c.

◆ TAG_BTRFS_INFO

#define TAG_BTRFS_INFO   'IftB'

Definition at line 15 of file btrfs.c.

◆ TAG_BTRFS_LINK

#define TAG_BTRFS_LINK   'LftB'

Definition at line 19 of file btrfs.c.

◆ TAG_BTRFS_NODE

#define TAG_BTRFS_NODE   'NftB'

Definition at line 17 of file btrfs.c.

Typedef Documentation

◆ BTRFS_INFO

◆ cmp_func

typedef int(* cmp_func) (const void *ptr1, const void *ptr2)

Definition at line 37 of file btrfs.c.

Function Documentation

◆ _BtrFsSearchTree()

static BOOLEAN _BtrFsSearchTree ( PBTRFS_INFO  BtrFsInfo,
u64  loffset,
u8  level,
struct btrfs_disk_key key,
struct btrfs_path path 
)
static

Definition at line 281 of file btrfs.c.

283{
284 union tree_buf *tree_buf = path->tree_buf;
285 int slot, ret, lvl;
286 u64 physical, logical = loffset;
287
288 TRACE("BtrFsSearchTree called: offset: 0x%llx, level: %u (%llu %u %llu)\n",
289 loffset, level, key->objectid, key->type, key->offset);
290
291 if (!tree_buf)
292 {
293 ERR("Path struct is not allocated\n");
294 return FALSE;
295 }
296
297 for (lvl = level; lvl >= 0; lvl--)
298 {
299 physical = logical_physical(&BtrFsInfo->ChunkMap, logical);
300
301 if (!disk_read(BtrFsInfo->DeviceId, physical, &tree_buf->header,
302 BtrFsInfo->SuperBlock.nodesize))
303 {
304 ERR("Error when reading tree node, loffset: 0x%llx, poffset: 0x%llx, level: %u\n",
305 logical, physical, lvl);
306 return FALSE;
307 }
308
309 if (tree_buf->header.level != lvl)
310 {
311 ERR("Error when searching in tree: expected lvl=%u but got %u\n",
312 lvl, tree_buf->header.level);
313 return FALSE;
314 }
315
316 TRACE("BtrFsSearchTree loop, level %u, loffset: 0x%llx\n", lvl, logical);
317
318 if (lvl)
319 {
320 ret = bin_search(tree_buf->node.ptrs,
321 sizeof(struct btrfs_key_ptr),
323 path->slots[lvl],
324 tree_buf->header.nritems, &slot);
325 TRACE("Inner node, min=%lu max=%lu\n", path->slots[0], tree_buf->header.nritems);
326 if (ret && slot > path->slots[lvl])
327 --slot;
328 }
329 else
330 {
331 ret = bin_search(tree_buf->leaf.items,
332 sizeof(struct btrfs_item),
334 path->slots[0],
335 tree_buf->header.nritems, &slot);
336 TRACE("Leaf node, min=%lu max=%lu\n", path->slots[0], tree_buf->header.nritems);
337 if (slot == tree_buf->header.nritems)
338 --slot;
339 }
340
341 path->itemsnr[lvl] = tree_buf->header.nritems;
342 path->offsets[lvl] = logical;
343 path->slots[lvl] = slot;
344
345 logical = tree_buf->node.ptrs[slot].blockptr;
346 }
347
348 TRACE("Found slot no=%lu\n", slot);
349
350 TRACE("BtrFsSearchTree found item (%llu %u %llu) offset: %lu, size: %lu, returning %lu\n",
353
354 return !ret;
355}
#define ERR(fmt,...)
Definition: debug.h:110
ULONG64 u64
Definition: btrfs.h:15
static const struct btrfs_disk_key * path_current_disk_key(struct btrfs_path *path)
Definition: btrfs.c:188
static struct btrfs_item * path_current_item(struct btrfs_path *path)
Definition: btrfs.c:178
static u64 logical_physical(struct btrfs_chunk_map *chunk_map, u64 logical)
Definition: btrfs.c:231
static int btrfs_comp_keys(const struct btrfs_disk_key *k1, const struct btrfs_disk_key *k2)
Definition: btrfs.c:194
static int bin_search(void *ptr, int item_size, void *cmp_item, cmp_func func, int min, int max, int *slot)
Definition: btrfs.c:40
static BOOLEAN disk_read(ULONG DeviceId, u64 physical, void *dest, u32 count)
Definition: btrfs.c:253
int(* cmp_func)(const void *ptr1, const void *ptr2)
Definition: btrfs.c:37
#define FALSE
Definition: types.h:117
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
#define TRACE(s)
Definition: solgame.cpp:4
struct btrfs_super_block SuperBlock
Definition: btrfs.c:28
ULONG DeviceId
Definition: btrfs.c:27
struct btrfs_chunk_map ChunkMap
Definition: btrfs.c:29
Definition: vfat.h:185
Definition: copy.c:22
struct btrfs_leaf leaf
Definition: btrfs.h:386
struct btrfs_header header
Definition: btrfs.h:384
struct btrfs_node node
Definition: btrfs.h:385
struct _slot slot
Definition: vfat.h:196
int ret

Referenced by btrfs_read_chunk_tree(), BtrFsSearchTree(), BtrFsSearchTreeType(), and next_slot().

◆ bin_search()

static int bin_search ( void ptr,
int  item_size,
void cmp_item,
cmp_func  func,
int  min,
int  max,
int slot 
)
static

Definition at line 40 of file btrfs.c.

42{
43 int low = min;
44 int high = max;
45 int mid;
46 int ret;
47 unsigned long offset;
48 UCHAR *item;
49
50 while (low < high)
51 {
52 mid = (low + high) / 2;
53 offset = mid * item_size;
54
55 item = (UCHAR *) ptr + offset;
56 ret = func((void *) item, cmp_item);
57
58 if (ret < 0)
59 {
60 low = mid + 1;
61 }
62 else if (ret > 0)
63 {
64 high = mid;
65 }
66 else
67 {
68 *slot = mid;
69 return 0;
70 }
71 }
72 *slot = low;
73 return 1;
74}
GLenum func
Definition: glext.h:6028
static PVOID ptr
Definition: dispmode.c:27
static ATOM item
Definition: dde.c:856
#define min(a, b)
Definition: monoChain.cc:55
#define max(a, b)
Definition: svc.c:63
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by _BtrFsSearchTree(), insert_chunk_item(), and logical_physical().

◆ btrfs_chunk_item_size()

static unsigned long btrfs_chunk_item_size ( int  num_stripes)
inlinestatic

Definition at line 161 of file btrfs.c.

162{
163 return sizeof(struct btrfs_chunk) +
165}
__u16 num_stripes
Definition: btrfs.h:206
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList

Referenced by btrfs_read_sys_chunk_array().

◆ btrfs_comp_chunk_map()

static int btrfs_comp_chunk_map ( struct btrfs_chunk_map_item m1,
struct btrfs_chunk_map_item m2 
)
static

Definition at line 76 of file btrfs.c.

78{
79 if (m1->logical > m2->logical)
80 return 1;
81 if (m1->logical < m2->logical)
82 return -1;
83 return 0;
84}

Referenced by insert_chunk_item(), and logical_physical().

◆ btrfs_comp_keys()

static int btrfs_comp_keys ( const struct btrfs_disk_key k1,
const struct btrfs_disk_key k2 
)
static

Definition at line 194 of file btrfs.c.

196{
197 if (k1->objectid > k2->objectid)
198 return 1;
199 if (k1->objectid < k2->objectid)
200 return -1;
201 if (k1->type > k2->type)
202 return 1;
203 if (k1->type < k2->type)
204 return -1;
205 if (k1->offset > k2->offset)
206 return 1;
207 if (k1->offset < k2->offset)
208 return -1;
209 return 0;
210}
__u8 type
Definition: btrfs.h:90
__u64 offset
Definition: btrfs.h:91
__u64 objectid
Definition: btrfs.h:89

Referenced by _BtrFsSearchTree(), and btrfs_file_read().

◆ btrfs_comp_keys_type()

static int btrfs_comp_keys_type ( const struct btrfs_disk_key k1,
const struct btrfs_disk_key k2 
)
static

Definition at line 213 of file btrfs.c.

215{
216 if (k1->objectid > k2->objectid)
217 return 1;
218 if (k1->objectid < k2->objectid)
219 return -1;
220 if (k1->type > k2->type)
221 return 1;
222 if (k1->type < k2->type)
223 return -1;
224 return 0;
225}

Referenced by btrfs_file_read(), btrfs_read_chunk_tree(), BtrFsLookupDirItemI(), BtrFsSearchTreeType(), next_slot(), and prev_slot().

◆ btrfs_file_read()

static u64 btrfs_file_read ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
u64  inr,
u64  offset,
u64  size,
char buf 
)
static

Definition at line 769 of file btrfs.c.

772{
773 struct btrfs_path path;
774 struct btrfs_disk_key key;
776 int res = 0;
777 u64 rd, seek_pointer = READ_ERROR, offset_in_extent;
778 BOOLEAN find_res;
779
780 TRACE("btrfs_file_read inr=%llu offset=%llu size=%llu\n", inr, offset, size);
781
782 key.objectid = inr;
784 key.offset = offset;
785 init_path(&BtrFsInfo->SuperBlock, &path);
786
787 find_res = BtrFsSearchTree(BtrFsInfo, root, &key, &path);
788
789 /* if we found greater key, switch to the previous one */
790 if (!find_res && btrfs_comp_keys(&key, path_current_disk_key(&path)) < 0)
791 {
792 if (prev_slot(&key, &path))
793 goto out;
794
796 {
797 goto out;
798 }
799
800 seek_pointer = offset;
801
802 do
803 {
804 TRACE("Current extent: (%llu %u %llu) \n",
805 path_current_disk_key(&path)->objectid,
808
810
811 offset_in_extent = seek_pointer;
812 /* check if we need clean extent offset when switching to the next extent */
813 if ((seek_pointer) >= path_current_disk_key(&path)->offset)
814 offset_in_extent -= path_current_disk_key(&path)->offset;
815
816 if (extent->type == BTRFS_FILE_EXTENT_INLINE)
817 {
818 rd = btrfs_read_extent_inline(&path, extent, offset_in_extent, size, buf);
819 }
820 else
821 {
822 rd = btrfs_read_extent_reg(BtrFsInfo, &path, extent, offset_in_extent, size, buf);
823 }
824
825 if (rd == READ_ERROR)
826 {
827 ERR("Error while reading extent\n");
828 seek_pointer = READ_ERROR;
829 goto out;
830 }
831
832 buf += rd;
833 seek_pointer += rd;
834 size -= rd;
835 TRACE("file_read size=%llu rd=%llu seek_pointer=%llu\n", size, rd, seek_pointer);
836
837 if (!size)
838 break;
839 } while (!(res = next_slot(BtrFsInfo, &key, &path)));
840
841 if (res)
842 {
843 seek_pointer = READ_ERROR;
844 goto out;
845 }
846
847 seek_pointer -= offset;
848out:
849 free_path(&path);
850 return seek_pointer;
851}
unsigned char BOOLEAN
#define BTRFS_EXTENT_DATA_KEY
Definition: btrfs.h:52
#define BTRFS_FILE_EXTENT_INLINE
Definition: btrfs.h:65
static u64 btrfs_read_extent_reg(PBTRFS_INFO BtrFsInfo, struct btrfs_path *path, struct btrfs_file_extent_item *extent, u64 offset, u64 size, char *out)
Definition: btrfs.c:686
static void free_path(struct btrfs_path *path)
Definition: btrfs.c:173
static BOOLEAN BtrFsSearchTree(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, struct btrfs_disk_key *key, struct btrfs_path *path)
Definition: btrfs.c:358
static int next_slot(PBTRFS_INFO BtrFsInfo, struct btrfs_disk_key *key, struct btrfs_path *path)
Definition: btrfs.c:384
static void init_path(const struct btrfs_super_block *sb, struct btrfs_path *path)
Definition: btrfs.c:167
static u64 btrfs_read_extent_inline(struct btrfs_path *path, struct btrfs_file_extent_item *extent, u64 offset, u64 size, char *out)
Definition: btrfs.c:652
static UCHAR * path_current_data(struct btrfs_path *path)
Definition: btrfs.c:183
static int btrfs_comp_keys_type(const struct btrfs_disk_key *k1, const struct btrfs_disk_key *k2)
Definition: btrfs.c:213
#define READ_ERROR
Definition: btrfs.c:23
static int prev_slot(struct btrfs_disk_key *key, struct btrfs_path *path)
Definition: btrfs.c:425
GLuint res
Definition: glext.h:9613
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static FILE * out
Definition: regtests2xml.c:44
int rd
Definition: scanf.h:134

Referenced by BtrFsRead().

◆ btrfs_lookup_inode()

static int btrfs_lookup_inode ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
struct btrfs_disk_key location,
struct btrfs_inode_item item,
struct btrfs_root_item new_root 
)
static

Definition at line 880 of file btrfs.c.

885{
886 const struct btrfs_root_item tmp_root = *root;
887 struct btrfs_path path;
888 int res = -1;
889
890// if (location->type == BTRFS_ROOT_ITEM_KEY) {
891// if (btrfs_find_root(location->objectid, &tmp_root, NULL))
892// return -1;
893//
894// location->objectid = tmp_root.root_dirid;
895// location->type = BTRFS_INODE_ITEM_KEY;
896// location->offset = 0;
897// }
898 init_path(&BtrFsInfo->SuperBlock, &path);
899 TRACE("Searching inode (%llu %u %llu)\n", location->objectid, location->type, location->offset);
900
901 if (BtrFsSearchTree(BtrFsInfo, &tmp_root, location, &path))
902 {
903 if (item)
904 *item = *((struct btrfs_inode_item *) path_current_data(&path));
905
906 if (new_root)
907 *new_root = tmp_root;
908
909 res = 0;
910 }
911
912 free_path(&path);
913 return res;
914}
struct _root root
ULONG_PTR offset

Referenced by btrfs_lookup_path(), and get_parent_inode().

◆ btrfs_lookup_inode_ref()

static u64 btrfs_lookup_inode_ref ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
u64  inr,
struct btrfs_inode_ref refp,
char name 
)
static

Definition at line 858 of file btrfs.c.

861{
862 struct btrfs_path path;
863 struct btrfs_inode_ref *ref;
865 init_path(&BtrFsInfo->SuperBlock, &path);
866
867 if (BtrFsSearchTreeType(BtrFsInfo, root, inr, BTRFS_INODE_REF_KEY, &path))
868 {
870
871 if (refp)
872 *refp = *ref;
873 ret = path_current_disk_key(&path)->offset;
874 }
875
876 free_path(&path);
877 return ret;
878}
#define BTRFS_INODE_REF_KEY
Definition: btrfs.h:56
#define INVALID_INODE
Definition: btrfs.c:21
static BOOLEAN BtrFsSearchTreeType(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 objectid, u8 type, struct btrfs_path *path)
Definition: btrfs.c:365
Definition: send.c:48

Referenced by get_parent_inode().

◆ btrfs_lookup_path()

static u64 btrfs_lookup_path ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
u64  inr,
const char path,
u8 type_p,
struct btrfs_inode_item inode_item_p,
int  symlink_limit 
)
static

Definition at line 1052 of file btrfs.c.

1055{
1056 struct btrfs_dir_item item;
1057 struct btrfs_inode_item inode_item;
1059 int len, have_inode = 0;
1060 const char *cur = path;
1061 struct btrfs_disk_key key;
1062 char *link_target = NULL;
1063
1064 if (*cur == '/' || *cur == '\\')
1065 {
1066 ++cur;
1067 inr = root->root_dirid;
1068 }
1069
1070 do
1071 {
1073
1074 len = next_length(cur);
1075 if (len > BTRFS_NAME_MAX)
1076 {
1077 ERR("%s: Name too long at \"%.*s\"\n", BTRFS_NAME_MAX, cur);
1078 return INVALID_INODE;
1079 }
1080
1081 if (len == 1 && cur[0] == '.')
1082 break;
1083
1084 if (len == 2 && cur[0] == '.' && cur[1] == '.')
1085 {
1086 cur += 2;
1087 inr = get_parent_inode(BtrFsInfo, root, inr, &inode_item);
1088 if (inr == INVALID_INODE)
1089 return INVALID_INODE;
1090
1092 continue;
1093 }
1094
1095 if (!*cur)
1096 break;
1097
1098 if (!BtrFsLookupDirItem(BtrFsInfo, root, inr, cur, len, &item))
1099 {
1100 TRACE("Try to find case-insensitive, path=%s inr=%llu s=%.*s\n", path, inr, len, cur);
1101 if (!BtrFsLookupDirItemI(BtrFsInfo, root, inr, cur, len, &item))
1102 return INVALID_INODE;
1103 }
1104
1105 type = item.type;
1106 have_inode = 1;
1107 if (btrfs_lookup_inode(BtrFsInfo, root, &item.location, &inode_item, NULL))
1108 return INVALID_INODE;
1109
1110 if (type == BTRFS_FT_SYMLINK && symlink_limit >= 0)
1111 {
1112 if (!symlink_limit)
1113 {
1114 TRACE("%s: Too much symlinks!\n");
1115 return INVALID_INODE;
1116 }
1117
1118 /* btrfs_readlink allocates link_target by itself */
1119 if (!btrfs_readlink(BtrFsInfo, root, item.location.objectid, &link_target))
1120 return INVALID_INODE;
1121
1122 inr = btrfs_lookup_path(BtrFsInfo, root, inr, link_target, &type, &inode_item, symlink_limit - 1);
1123
1124 FrLdrTempFree(link_target, TAG_BTRFS_LINK);
1125
1126 if (inr == INVALID_INODE)
1127 return INVALID_INODE;
1128 } else if (type != BTRFS_FT_DIR && cur[len])
1129 {
1130 TRACE("%s: \"%.*s\" not a directory\n", (int) (cur - path + len), path);
1131 return INVALID_INODE;
1132 } else
1133 {
1134 inr = item.location.objectid;
1135 }
1136
1137 cur += len;
1138 } while (*cur);
1139
1140 if (type_p)
1141 *type_p = type;
1142
1143 if (inode_item_p)
1144 {
1145 if (!have_inode)
1146 {
1147 key.objectid = inr;
1149 key.offset = 0;
1150
1151 if (btrfs_lookup_inode(BtrFsInfo, root, &key, &inode_item, NULL))
1152 return INVALID_INODE;
1153 }
1154
1155 *inode_item_p = inode_item;
1156 }
1157
1158 return inr;
1159}
#define BTRFS_FT_DIR
Definition: btrfs.h:75
#define BTRFS_FT_SYMLINK
Definition: btrfs.h:76
UCHAR u8
Definition: btrfs.h:12
#define BTRFS_INODE_ITEM_KEY
Definition: btrfs.h:55
#define BTRFS_NAME_MAX
Definition: btrfs.h:40
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197
static u64 get_parent_inode(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, struct btrfs_inode_item *inode_item)
Definition: btrfs.c:975
#define TAG_BTRFS_LINK
Definition: btrfs.c:19
static BOOLEAN BtrFsLookupDirItemI(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 dir_haystack, const char *name, int name_len, struct btrfs_dir_item *ret_item)
Definition: btrfs.c:598
static int btrfs_lookup_inode(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, struct btrfs_disk_key *location, struct btrfs_inode_item *item, struct btrfs_root_item *new_root)
Definition: btrfs.c:880
static int next_length(const char *path)
Definition: btrfs.c:1029
static BOOLEAN BtrFsLookupDirItem(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 dir, const char *name, int name_len, struct btrfs_dir_item *item)
Definition: btrfs.c:569
static BOOLEAN btrfs_readlink(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, char **target)
Definition: btrfs.c:916
static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, const char *path, u8 *type_p, struct btrfs_inode_item *inode_item_p, int symlink_limit)
Definition: btrfs.c:1052
static const char * skip_current_directories(const char *cur)
Definition: btrfs.c:1037
#define NULL
Definition: types.h:112
FxCollectionEntry * cur
GLenum GLsizei len
Definition: glext.h:6722

Referenced by btrfs_lookup_path(), and BtrFsOpen().

◆ btrfs_read_chunk_tree()

static void btrfs_read_chunk_tree ( PBTRFS_INFO  BtrFsInfo)
static

Definition at line 476 of file btrfs.c.

477{
478 const struct btrfs_super_block *sb = &BtrFsInfo->SuperBlock;
479 struct btrfs_disk_key ignore_key;
480 struct btrfs_disk_key search_key;
481 struct btrfs_chunk *chunk;
482 struct btrfs_path path;
483
485 {
486 if (sb->num_devices > 1)
487 TRACE("warning: only support single device btrfs\n");
488
489 ignore_key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
490 ignore_key.type = BTRFS_DEV_ITEM_KEY;
491
492 /* read chunk from chunk_tree */
493 search_key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
494 search_key.type = BTRFS_CHUNK_ITEM_KEY;
495 search_key.offset = 0;
496 init_path(sb, &path);
497 _BtrFsSearchTree(BtrFsInfo, sb->chunk_root, sb->chunk_root_level, &search_key, &path);
498 do
499 {
500 /* skip information about underlying block
501 * devices.
502 */
504 continue;
506 break;
507
508 chunk = (struct btrfs_chunk *) (path_current_data(&path));
510 } while (!next_slot(BtrFsInfo, &search_key, &path));
511 free_path(&path);
512 }
513}
#define BTRFS_SUPER_FLAG_METADUMP
Definition: btrfs.h:46
#define BTRFS_FIRST_CHUNK_TREE_OBJECTID
Definition: btrfs.h:63
#define BTRFS_DEV_ITEMS_OBJECTID
Definition: btrfs.h:72
#define BTRFS_DEV_ITEM_KEY
Definition: btrfs.h:48
#define BTRFS_CHUNK_ITEM_KEY
Definition: btrfs.h:49
static BOOLEAN _BtrFsSearchTree(PBTRFS_INFO BtrFsInfo, u64 loffset, u8 level, struct btrfs_disk_key *key, struct btrfs_path *path)
Definition: btrfs.c:281
static void insert_map(struct btrfs_chunk_map *chunk_map, const struct btrfs_disk_key *key, struct btrfs_chunk *chunk)
Definition: btrfs.c:122
superblock * sb
Definition: btrfs.c:4261
uint8_t chunk_root_level
Definition: btrfs.h:249
uint64_t flags
Definition: btrfs.h:227
uint64_t num_devices
Definition: btrfs.h:237

Referenced by BtrFsMount().

◆ btrfs_read_extent_inline()

static u64 btrfs_read_extent_inline ( struct btrfs_path path,
struct btrfs_file_extent_item extent,
u64  offset,
u64  size,
char out 
)
static

Definition at line 652 of file btrfs.c.

655{
656 u32 dlen;
657 const char *cbuf;
658 const int data_off = offsetof(
659 struct btrfs_file_extent_item, disk_bytenr);
660
661 cbuf = (const char *) extent + data_off;
662 dlen = extent->ram_bytes;
663
664 TRACE("read_extent_inline offset=%llu size=%llu gener=%llu\n", offset, size, extent->generation);
665
666 if (offset > dlen)
667 {
668 ERR("Tried to read offset (%llu) beyond extent length (%lu)\n", offset, dlen);
669 return READ_ERROR;
670 }
671
672 if (size > dlen - offset)
673 size = dlen - offset;
674
675 if (extent->compression == BTRFS_COMPRESS_NONE)
676 {
677 TRACE("read_extent_inline %lu, \n", data_off);
678 memcpy(out, cbuf + offset, size);
679 return size;
680 }
681
682 ERR("No compression supported right now\n");
683 return READ_ERROR;
684}
ULONG32 u32
Definition: btrfs.h:14
#define BTRFS_COMPRESS_NONE
Definition: btrfs.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define offsetof(TYPE, MEMBER)

Referenced by btrfs_file_read().

◆ btrfs_read_extent_reg()

static u64 btrfs_read_extent_reg ( PBTRFS_INFO  BtrFsInfo,
struct btrfs_path path,
struct btrfs_file_extent_item extent,
u64  offset,
u64  size,
char out 
)
static

Definition at line 686 of file btrfs.c.

690{
691 u64 physical, dlen;
692 char *temp_out;
693 dlen = extent->num_bytes;
694
695 if (offset > dlen)
696 {
697 ERR("Tried to read offset (%llu) beyond extent length (%lu)\n", offset, dlen);
698 return READ_ERROR;
699 }
700
701 if (size > dlen - offset)
702 size = dlen - offset;
703
704 /* Handle sparse extent */
705 if (extent->disk_bytenr == 0 && extent->disk_num_bytes == 0)
706 {
708 return size;
709 }
710
711 physical = logical_physical(&BtrFsInfo->ChunkMap, extent->disk_bytenr);
712 if (physical == INVALID_ADDRESS)
713 {
714 ERR("Unable to convert logical address to physical: %llu\n", extent->disk_bytenr);
715 return READ_ERROR;
716 }
717
718 if (extent->compression == BTRFS_COMPRESS_NONE)
719 {
720 physical += extent->offset + offset;
721
722 /* If somebody tried to do unaligned access */
723 if (physical & (SECTOR_SIZE - 1))
724 {
725 u32 shift;
726
728
729 if (!disk_read(BtrFsInfo->DeviceId,
730 ALIGN_DOWN_BY(physical, SECTOR_SIZE),
731 temp_out, SECTOR_SIZE))
732 {
733 FrLdrTempFree(temp_out, TAG_BTRFS_FILE);
734 return READ_ERROR;
735 }
736
737 shift = (u32)(physical & (SECTOR_SIZE - 1));
738
739 if (size <= SECTOR_SIZE - shift)
740 {
741 memcpy(out, temp_out + shift, size);
742 FrLdrTempFree(temp_out, TAG_BTRFS_FILE);
743 return size;
744 }
745
746 memcpy(out, temp_out + shift, SECTOR_SIZE - shift);
747 FrLdrTempFree(temp_out, TAG_BTRFS_FILE);
748
749 if (!disk_read(BtrFsInfo->DeviceId,
750 physical + SECTOR_SIZE - shift,
753 {
754 return READ_ERROR;
755 }
756 } else
757 {
758 if (!disk_read(BtrFsInfo->DeviceId, physical, out, size))
759 return READ_ERROR;
760 }
761
762 return size;
763 }
764
765 ERR("No compression supported right now\n");
766 return READ_ERROR;
767}
#define ALIGN_DOWN_BY(size, align)
#define SECTOR_SIZE
Definition: fs.h:22
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
#define INVALID_ADDRESS
Definition: btrfs.c:22
#define TAG_BTRFS_FILE
Definition: btrfs.c:18
#define shift
Definition: input.c:1755
#define u32
Definition: types.h:9
uint64_t offset
Definition: btrfs_drv.h:228
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by btrfs_file_read().

◆ btrfs_read_sys_chunk_array()

static void btrfs_read_sys_chunk_array ( PBTRFS_INFO  BtrFsInfo)
static

Definition at line 440 of file btrfs.c.

441{
442 const struct btrfs_super_block *sb = &BtrFsInfo->SuperBlock;
443 struct btrfs_disk_key *key;
444 struct btrfs_chunk *chunk;
445 u16 cur;
446
447 /* read chunk array in superblock */
448 TRACE("reading chunk array\n-----------------------------\n");
449 cur = 0;
450 while (cur < sb->sys_chunk_array_size)
451 {
452 key = (struct btrfs_disk_key *) (sb->sys_chunk_array + cur);
453 TRACE("chunk key objectid: %llx, offset: %llx, type: %u\n",
454 key->objectid, key->offset, key->type);
455 cur += sizeof(*key);
456 chunk = (struct btrfs_chunk *) (sb->sys_chunk_array + cur);
457 TRACE("chunk length: %llx\n", chunk->length);
458 TRACE("chunk owner: %llu\n", chunk->owner);
459 TRACE("chunk stripe_len: %llx\n", chunk->stripe_len);
460 TRACE("chunk type: %llu\n", chunk->type);
461 TRACE("chunk io_align: %u\n", chunk->io_align);
462 TRACE("chunk io_width: %u\n", chunk->io_width);
463 TRACE("chunk sector_size: %u\n", chunk->sector_size);
464 TRACE("chunk num_stripes: %u\n", chunk->num_stripes);
465 TRACE("chunk sub_stripes: %u\n", chunk->sub_stripes);
466
467 cur += btrfs_chunk_item_size(chunk->num_stripes);
468 TRACE("read_sys_chunk_array() cur=%d\n", cur);
469 insert_map(&BtrFsInfo->ChunkMap, key, chunk);
470 }
471}
USHORT u16
Definition: btrfs.h:13
static unsigned long btrfs_chunk_item_size(int num_stripes)
Definition: btrfs.c:161
uint8_t sys_chunk_array[SYS_CHUNK_ARRAY_SIZE]
Definition: btrfs.h:257

Referenced by BtrFsMount().

◆ btrfs_readlink()

static BOOLEAN btrfs_readlink ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
u64  inr,
char **  target 
)
static

Definition at line 916 of file btrfs.c.

919{
920 struct btrfs_path path;
922 char *data_ptr;
923 BOOLEAN res = FALSE;
924
925 init_path(&BtrFsInfo->SuperBlock, &path);
926
927 if (!BtrFsSearchTreeType(BtrFsInfo, root, inr, BTRFS_EXTENT_DATA_KEY, &path))
928 goto out;
929
931 if (extent->type != BTRFS_FILE_EXTENT_INLINE)
932 {
933 ERR("Extent for symlink %llu not of INLINE type\n", inr);
934 goto out;
935 }
936
937 if (extent->compression != BTRFS_COMPRESS_NONE)
938 {
939 ERR("Symlink %llu extent data compressed!\n", inr);
940 goto out;
941 }
942 else if (extent->encryption != 0)
943 {
944 ERR("Symlink %llu extent data encrypted!\n", inr);
945 goto out;
946 }
947 else if (extent->ram_bytes >= BtrFsInfo->SuperBlock.sectorsize)
948 {
949 ERR("Symlink %llu extent data too long (%llu)!\n", inr, extent->ram_bytes);
950 goto out;
951 }
952
953 data_ptr = (char *) extent + offsetof(
955
956 *target = FrLdrTempAlloc(extent->ram_bytes + 1, TAG_BTRFS_LINK);
957 if (!*target)
958 {
959 ERR("Cannot allocate %llu bytes\n", extent->ram_bytes + 1);
960 goto out;
961 }
962
963 memcpy(*target, data_ptr, extent->ram_bytes);
964 (*target)[extent->ram_bytes] = '\0';
965
966 res = TRUE;
967
968out:
969 free_path(&path);
970 return res;
971}
#define TRUE
Definition: types.h:120
GLenum target
Definition: glext.h:7315

Referenced by btrfs_lookup_path().

◆ BtrFsClose()

ARC_STATUS BtrFsClose ( ULONG  FileId)

Definition at line 1162 of file btrfs.c.

1163{
1164 pbtrfs_file_info phandle = FsGetDeviceSpecific(FileId);
1165 TRACE("BtrFsClose %lu\n", FileId);
1166
1167 FrLdrTempFree(phandle, TAG_BTRFS_FILE);
1168 return ESUCCESS;
1169}
VOID * FsGetDeviceSpecific(ULONG FileId)
Definition: fs.c:418
@ ESUCCESS
Definition: arc.h:32

◆ BtrFsGetFileInformation()

ARC_STATUS BtrFsGetFileInformation ( ULONG  FileId,
FILEINFORMATION Information 
)

Definition at line 1171 of file btrfs.c.

1172{
1173 pbtrfs_file_info phandle = FsGetDeviceSpecific(FileId);
1174
1176 Information->EndingAddress.QuadPart = phandle->inode.size;
1177 Information->CurrentAddress.QuadPart = phandle->position;
1178
1179 TRACE("BtrFsGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
1180 FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);
1181
1182 return ESUCCESS;
1183}
struct btrfs_inode_item inode
Definition: btrfs.h:417
u64 position
Definition: btrfs.h:416
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

◆ BtrFsLookupDirItem()

static BOOLEAN BtrFsLookupDirItem ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
u64  dir,
const char name,
int  name_len,
struct btrfs_dir_item item 
)
static

Definition at line 569 of file btrfs.c.

573{
574 struct btrfs_path path;
575 struct btrfs_disk_key key;
576 struct btrfs_dir_item *res = NULL;
577
578 key.objectid = dir;
579 key.type = BTRFS_DIR_ITEM_KEY;
580 key.offset = btrfs_crc32c(name, name_len);
581 init_path(&BtrFsInfo->SuperBlock, &path);
582
583 if (!BtrFsSearchTree(BtrFsInfo, root, &key, &path))
584 {
585 free_path(&path);
586 return FALSE;
587 }
588
590 if (res)
591 *item = *res;
592 free_path(&path);
593
594 return res != NULL;
595}
unsigned int dir
Definition: maze.c:112
#define btrfs_crc32c(name, len)
Definition: btrfs.h:23
#define BTRFS_DIR_ITEM_KEY
Definition: btrfs.h:53
static struct btrfs_dir_item * BtrFsMatchDirItemName(struct btrfs_path *path, const char *name, int name_len)
Definition: btrfs.c:545
__u16 name_len
Definition: btrfs.h:259
Definition: name.c:39

Referenced by btrfs_lookup_path().

◆ BtrFsLookupDirItemI()

static BOOLEAN BtrFsLookupDirItemI ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
u64  dir_haystack,
const char name,
int  name_len,
struct btrfs_dir_item ret_item 
)
static

Definition at line 598 of file btrfs.c.

602{
603 struct btrfs_path path;
604 struct btrfs_disk_key key;
605 struct btrfs_dir_item *item;
606 char *name_buf;
608
609 key.objectid = dir_haystack;
611 key.offset = 0;
612 init_path(&BtrFsInfo->SuperBlock, &path);
613
614 BtrFsSearchTree(BtrFsInfo, root, &key, &path);
615
617 goto cleanup;
618
619 do
620 {
622 // TRACE("slot: %ld, KEY (%llu %u %llu) %.*s\n",
623 // path.slots[0], path.item.key.objectid, path.item.key.type,
624 // path.item.key.offset, item->name_len, (char *)item + sizeof(*item));
625
626 if (verify_dir_item(item, 0, sizeof(*item) + item->name_len))
627 continue;
628 if (item->type == BTRFS_FT_XATTR)
629 continue;
630
631 name_buf = (char *) item + sizeof(*item);
632 TRACE("Compare names %.*s and %.*s\n", name_len, name, item->name_len, name_buf);
633
634 if (name_len == item->name_len && _strnicmp(name, name_buf, name_len) == 0)
635 {
636 *ret_item = *item;
637 result = TRUE;
638 goto cleanup;
639 }
640
641 } while (!next_slot(BtrFsInfo, &key, &path));
642
643cleanup:
644 free_path(&path);
645 return result;
646}
#define BTRFS_DIR_INDEX_KEY
Definition: btrfs.h:54
#define BTRFS_FT_XATTR
Definition: btrfs.h:77
static BOOLEAN verify_dir_item(struct btrfs_dir_item *item, u32 start, u32 total)
Definition: btrfs.c:519
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
static void cleanup(void)
Definition: main.c:1335
GLuint64EXT * result
Definition: glext.h:11304

Referenced by btrfs_lookup_path().

◆ BtrFsMatchDirItemName()

static struct btrfs_dir_item * BtrFsMatchDirItemName ( struct btrfs_path path,
const char name,
int  name_len 
)
static

Definition at line 545 of file btrfs.c.

546{
548 u32 cur = 0, this_len;
549 const char *name_ptr;
550
551 while (cur < path_current_item(path)->size)
552 {
553 this_len = sizeof(*item) + item->name_len + item->data_len;
554 name_ptr = (const char *) item + sizeof(*item);
555
556 if (verify_dir_item(item, cur, this_len))
557 return NULL;
558 if (item->name_len == name_len && !memcmp(name_ptr, name, name_len))
559 return item;
560
561 cur += this_len;
562 item = (struct btrfs_dir_item *) ((u8 *) item + this_len);
563 }
564
565 return NULL;
566}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112

Referenced by BtrFsLookupDirItem().

◆ BtrFsMount()

const DEVVTBL * BtrFsMount ( ULONG  DeviceId)

Definition at line 1297 of file btrfs.c.

1298{
1299 PBTRFS_INFO BtrFsInfo;
1300 struct btrfs_path path;
1301 struct btrfs_root_item fs_root_item;
1302
1303 TRACE("Enter BtrFsMount(%lu)\n", DeviceId);
1304
1305 BtrFsInfo = FrLdrTempAlloc(sizeof(BTRFS_INFO), TAG_BTRFS_INFO);
1306 if (!BtrFsInfo)
1307 return NULL;
1308 RtlZeroMemory(BtrFsInfo, sizeof(BTRFS_INFO));
1309
1310 /* Read the SuperBlock */
1311 if (!disk_read(DeviceId, BTRFS_SUPER_INFO_OFFSET,
1312 &BtrFsInfo->SuperBlock, sizeof(BtrFsInfo->SuperBlock)))
1313 {
1314 FrLdrTempFree(BtrFsInfo, TAG_BTRFS_INFO);
1315 return NULL;
1316 }
1317
1318 /* Check if SuperBlock is valid. If yes, return BTRFS function table */
1319 if (BtrFsInfo->SuperBlock.magic != BTRFS_MAGIC_N)
1320 {
1321 FrLdrTempFree(BtrFsInfo, TAG_BTRFS_INFO);
1322 return NULL;
1323 }
1324
1325 BtrFsInfo->DeviceId = DeviceId;
1326 TRACE("BtrFsMount(%lu) superblock magic ok\n", DeviceId);
1327
1329
1330 btrfs_read_sys_chunk_array(BtrFsInfo);
1331 btrfs_read_chunk_tree(BtrFsInfo);
1332
1333 /* setup roots */
1334 fs_root_item.bytenr = BtrFsInfo->SuperBlock.root;
1335 fs_root_item.level = BtrFsInfo->SuperBlock.root_level;
1336
1337 init_path(&BtrFsInfo->SuperBlock, &path);
1338 if (!BtrFsSearchTreeType(BtrFsInfo, &fs_root_item, BTRFS_FS_TREE_OBJECTID, BTRFS_ROOT_ITEM_KEY, &path))
1339 {
1340 free_path(&path);
1341 FrLdrTempFree(BtrFsInfo, TAG_BTRFS_INFO);
1342 return NULL;
1343 }
1344
1345 BtrFsInfo->FsRoot = *(struct btrfs_root_item *) path_current_data(&path);
1346
1347 free_path(&path);
1348
1349 /* Remember BTRFS volume information */
1350 BtrFsVolumes[DeviceId] = BtrFsInfo;
1351
1352 TRACE("BtrFsMount(%lu) success\n", DeviceId);
1353 return &BtrFsFuncTable;
1354}
#define BTRFS_FS_TREE_OBJECTID
Definition: btrfs.h:59
#define BTRFS_ROOT_ITEM_KEY
Definition: btrfs.h:51
#define BTRFS_SUPER_INFO_OFFSET
Definition: btrfs.h:25
#define BTRFS_MAGIC_N
Definition: btrfs.h:44
static void btrfs_init_crc32c(void)
Definition: crc32c.h:39
static void btrfs_read_chunk_tree(PBTRFS_INFO BtrFsInfo)
Definition: btrfs.c:476
PBTRFS_INFO BtrFsVolumes[MAX_FDS]
Definition: btrfs.c:34
static void btrfs_read_sys_chunk_array(PBTRFS_INFO BtrFsInfo)
Definition: btrfs.c:440
#define TAG_BTRFS_INFO
Definition: btrfs.c:15
const DEVVTBL BtrFsFuncTable
Definition: btrfs.c:1287
struct btrfs_root_item FsRoot
Definition: btrfs.c:30

Referenced by ArcOpen().

◆ BtrFsOpen()

ARC_STATUS BtrFsOpen ( CHAR Path,
OPENMODE  OpenMode,
ULONG FileId 
)

Definition at line 1185 of file btrfs.c.

1186{
1187 PBTRFS_INFO BtrFsInfo;
1188 ULONG DeviceId;
1189 u64 inr;
1190 u8 type;
1191
1192 btrfs_file_info temp_file_info;
1193 pbtrfs_file_info phandle;
1194
1195 TRACE("BtrFsOpen %s\n", Path);
1196
1197 /* Check parameters */
1198 if (OpenMode != OpenReadOnly)
1199 return EACCES;
1200
1201 /* Get underlying device */
1202 DeviceId = FsGetDeviceId(*FileId);
1203 BtrFsInfo = BtrFsVolumes[DeviceId];
1204
1205 inr = btrfs_lookup_path(BtrFsInfo, &BtrFsInfo->FsRoot,
1206 BtrFsInfo->FsRoot.root_dirid,
1207 Path, &type, &temp_file_info.inode, 40);
1208
1209 if (inr == INVALID_INODE)
1210 {
1211 TRACE("Cannot lookup file %s\n", Path);
1212 return ENOENT;
1213 }
1214
1215 if (type != BTRFS_FT_REG_FILE)
1216 {
1217 TRACE("Not a regular file: %s\n", Path);
1218 return EISDIR;
1219 }
1220
1221 TRACE("found inode inr=%llu size=%llu\n", inr, temp_file_info.inode.size);
1222
1223 temp_file_info.inr = inr;
1224 temp_file_info.position = 0;
1225
1226 phandle = FrLdrTempAlloc(sizeof(btrfs_file_info), TAG_BTRFS_FILE);
1227 if (!phandle)
1228 return ENOMEM;
1229
1230 RtlCopyMemory(phandle, &temp_file_info, sizeof(btrfs_file_info));
1231 phandle->Volume = BtrFsInfo;
1232
1233 FsSetDeviceSpecific(*FileId, phandle);
1234 return ESUCCESS;
1235}
PRTL_UNICODE_STRING_BUFFER Path
#define ENOENT
Definition: acclib.h:79
#define ENOMEM
Definition: acclib.h:84
#define EACCES
Definition: acclib.h:85
#define BTRFS_FT_REG_FILE
Definition: btrfs.h:74
ULONG FsGetDeviceId(ULONG FileId)
Definition: fs.c:425
VOID FsSetDeviceSpecific(ULONG FileId, VOID *Specific)
Definition: fs.c:411
#define EISDIR
Definition: errno.h:27
@ OpenReadOnly
Definition: arc.h:65
PBTRFS_INFO Volume
Definition: btrfs.h:418
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59

◆ BtrFsRead()

ARC_STATUS BtrFsRead ( ULONG  FileId,
VOID Buffer,
ULONG  Size,
ULONG BytesRead 
)

Definition at line 1237 of file btrfs.c.

1238{
1239 pbtrfs_file_info phandle = FsGetDeviceSpecific(FileId);
1240 u64 rd;
1241
1242 TRACE("BtrFsRead %lu, size=%lu \n", FileId, Size);
1243
1244 if (!Size)
1245 Size = phandle->inode.size;
1246
1247 if (Size > phandle->inode.size)
1248 Size = phandle->inode.size;
1249
1250 rd = btrfs_file_read(phandle->Volume, &phandle->Volume->FsRoot,
1251 phandle->inr, phandle->position, Size, Buffer);
1252 if (rd == READ_ERROR)
1253 {
1254 TRACE("An error occured while reading file %lu\n", FileId);
1255 return ENOENT;
1256 }
1257
1258 phandle->position += rd;
1259 *BytesRead = rd;
1260 return ESUCCESS;
1261}
static u64 btrfs_file_read(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, u64 offset, u64 size, char *buf)
Definition: btrfs.c:769
Definition: bufpool.h:45
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870

◆ BtrFsSearchTree()

static BOOLEAN BtrFsSearchTree ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
struct btrfs_disk_key key,
struct btrfs_path path 
)
inlinestatic

Definition at line 358 of file btrfs.c.

360{
361 return _BtrFsSearchTree(BtrFsInfo, root->bytenr, root->level, key, path);
362}

Referenced by btrfs_file_read(), btrfs_lookup_inode(), BtrFsLookupDirItem(), and BtrFsLookupDirItemI().

◆ BtrFsSearchTreeType()

static BOOLEAN BtrFsSearchTreeType ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
u64  objectid,
u8  type,
struct btrfs_path path 
)
inlinestatic

Definition at line 365 of file btrfs.c.

367{
368 struct btrfs_disk_key key;
369
370 key.objectid = objectid;
371 key.type = type;
372 key.offset = 0;
373
374 if (!_BtrFsSearchTree(BtrFsInfo, root->bytenr, root->level, &key, path))
375 return FALSE;
376
378 return TRUE;
379 else
380 return FALSE;
381}

Referenced by btrfs_lookup_inode_ref(), btrfs_readlink(), and BtrFsMount().

◆ BtrFsSeek()

ARC_STATUS BtrFsSeek ( ULONG  FileId,
LARGE_INTEGER Position,
SEEKMODE  SeekMode 
)

Definition at line 1263 of file btrfs.c.

1264{
1265 pbtrfs_file_info phandle = FsGetDeviceSpecific(FileId);
1266 LARGE_INTEGER NewPosition = *Position;
1267
1268 switch (SeekMode)
1269 {
1270 case SeekAbsolute:
1271 break;
1272 case SeekRelative:
1273 NewPosition.QuadPart += phandle->position;
1274 break;
1275 default:
1276 ASSERT(FALSE);
1277 return EINVAL;
1278 }
1279
1280 if (NewPosition.QuadPart >= phandle->inode.size)
1281 return EINVAL;
1282
1283 phandle->position = NewPosition.QuadPart;
1284 return ESUCCESS;
1285}
#define EINVAL
Definition: acclib.h:90
#define ASSERT(a)
Definition: mode.c:44
@ SeekRelative
Definition: arc.h:60
@ SeekAbsolute
Definition: arc.h:59
static COORD Position
Definition: mouse.c:34
LONGLONG QuadPart
Definition: typedefs.h:114

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( FILESYSTEM  )

◆ disk_read()

static BOOLEAN disk_read ( ULONG  DeviceId,
u64  physical,
void dest,
u32  count 
)
static

Definition at line 253 of file btrfs.c.

254{
256 ULONG Count;
258
259 if (!dest)
260 return FALSE;
261
262 Position.QuadPart = physical;
263 Status = ArcSeek(DeviceId, &Position, SeekAbsolute);
264 if (Status != ESUCCESS)
265 {
266 ERR("ArcSeek returned status %lu\n", Status);
267 return FALSE;
268 }
269
270 Status = ArcRead(DeviceId, dest, count, &Count);
271 if (Status != ESUCCESS || Count != count)
272 {
273 ERR("ArcRead returned status %lu\n", Status);
274 return FALSE;
275 }
276
277 return TRUE;
278}
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:245
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:238
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei count
Definition: gl.h:1545
static char * dest
Definition: rtl.c:135
int Count
Definition: noreturn.cpp:7
ULONG ARC_STATUS
Definition: arc.h:4

Referenced by _BtrFsSearchTree(), btrfs_read_extent_reg(), BtrFsMount(), f_lseek(), f_mkfs(), f_read(), f_write(), main(), and move_window().

◆ free_path()

static void free_path ( struct btrfs_path path)
inlinestatic

◆ get_parent_inode()

static u64 get_parent_inode ( PBTRFS_INFO  BtrFsInfo,
const struct btrfs_root_item root,
u64  inr,
struct btrfs_inode_item inode_item 
)
static

Definition at line 975 of file btrfs.c.

978{
979 struct btrfs_disk_key key;
980 u64 res;
981
982 if (inr == BTRFS_FIRST_FREE_OBJECTID)
983 {
984// if (root->objectid != btrfs_info.fs_root.objectid) {
985// u64 parent;
986// struct btrfs_root_ref ref;
987//
988// parent = btrfs_lookup_root_ref(root->objectid, &ref,
989// NULL);
990// if (parent == -1ULL)
991// return -1ULL;
992//
993// if (btrfs_find_root(parent, root, NULL))
994// return -1ULL;
995//
996// inr = ref.dirid;
997// }
998
999 if (inode_item)
1000 {
1001 key.objectid = inr;
1003 key.offset = 0;
1004
1005 if (btrfs_lookup_inode(BtrFsInfo, root, &key, inode_item, NULL))
1006 return INVALID_INODE;
1007 }
1008
1009 return inr;
1010 }
1011
1012 res = btrfs_lookup_inode_ref(BtrFsInfo, root, inr, NULL, NULL);
1013 if (res == INVALID_INODE)
1014 return INVALID_INODE;
1015
1016 if (inode_item)
1017 {
1018 key.objectid = res;
1020 key.offset = 0;
1021
1022 if (btrfs_lookup_inode(BtrFsInfo, root, &key, inode_item, NULL))
1023 return INVALID_INODE;
1024 }
1025
1026 return res;
1027}
#define BTRFS_FIRST_FREE_OBJECTID
Definition: btrfs.h:61
static u64 btrfs_lookup_inode_ref(PBTRFS_INFO BtrFsInfo, const struct btrfs_root_item *root, u64 inr, struct btrfs_inode_ref *refp, char *name)
Definition: btrfs.c:858

Referenced by btrfs_lookup_path().

◆ init_path()

static void init_path ( const struct btrfs_super_block sb,
struct btrfs_path path 
)
inlinestatic

◆ insert_chunk_item()

static void insert_chunk_item ( struct btrfs_chunk_map chunk_map,
struct btrfs_chunk_map_item item 
)
static

Definition at line 87 of file btrfs.c.

88{
89 int ret;
90 int slot;
91 int i;
92
93 if (chunk_map->map == NULL)
94 {
95 /* first item */
97 chunk_map->map = FrLdrTempAlloc(chunk_map->map_length * sizeof(chunk_map->map[0]), TAG_BTRFS_CHUNK_MAP);
98 chunk_map->map[0] = *item;
99 chunk_map->cur_length = 1;
100 return;
101 }
102 ret = bin_search(chunk_map->map, sizeof(*item), item,
104 chunk_map->cur_length, &slot);
105 if (ret == 0)/* already in map */
106 return;
107
108 if (chunk_map->cur_length == BTRFS_MAX_CHUNK_ENTRIES)
109 {
110 /* should be impossible */
111 TRACE("too many chunk items\n");
112 return;
113 }
114
115 for (i = chunk_map->cur_length; i > slot; i--)
116 chunk_map->map[i] = chunk_map->map[i - 1];
117
118 chunk_map->map[slot] = *item;
119 chunk_map->cur_length++;
120}
#define BTRFS_MAX_CHUNK_ENTRIES
Definition: btrfs.h:70
#define TAG_BTRFS_CHUNK_MAP
Definition: btrfs.c:16
static int btrfs_comp_chunk_map(struct btrfs_chunk_map_item *m1, struct btrfs_chunk_map_item *m2)
Definition: btrfs.c:76
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
struct btrfs_chunk_map_item * map
Definition: btrfs.h:407
u32 map_length
Definition: btrfs.h:408
u32 cur_length
Definition: btrfs.h:409

Referenced by insert_map().

◆ insert_map()

static void insert_map ( struct btrfs_chunk_map chunk_map,
const struct btrfs_disk_key key,
struct btrfs_chunk chunk 
)
inlinestatic

Definition at line 122 of file btrfs.c.

125{
126 struct btrfs_stripe *stripe = &chunk->stripe;
127 struct btrfs_stripe *stripe_end = stripe + chunk->num_stripes;
129
130 item.logical = key->offset;
131 item.length = chunk->length;
132 for (; stripe < stripe_end; stripe++)
133 {
134 TRACE("stripe: %p\n", stripe);
135 item.devid = stripe->devid;
136 item.physical = stripe->offset;
137 TRACE("inserting chunk log: %llx len: %llx devid: %llx phys: %llx\n",
138 item.logical, item.length, item.devid, item.physical);
139 insert_chunk_item(chunk_map, &item);
140 }
141
142#if 0
143 struct btrfs_chunk_map_item *itm;
144 int i;
145
146 TRACE("insert finished. Printing chunk map:\n------------------------------\n");
147
148 for (i = 0; i < chunk_map->cur_length; i++)
149 {
150 itm = &chunk_map->map[i];
151 TRACE("%llx..%llx -> %llx..%llx, devid: %llu\n",
152 itm->logical,
153 itm->logical + itm->length,
154 itm->physical,
155 itm->physical + itm->length,
156 itm->devid);
157 }
158#endif
159}
static void insert_chunk_item(struct btrfs_chunk_map *chunk_map, struct btrfs_chunk_map_item *item)
Definition: btrfs.c:87
Definition: write.c:113

Referenced by btrfs_read_chunk_tree(), and btrfs_read_sys_chunk_array().

◆ logical_physical()

static u64 logical_physical ( struct btrfs_chunk_map chunk_map,
u64  logical 
)
static

Definition at line 231 of file btrfs.c.

232{
234 int slot, ret;
235
236 item.logical = logical;
237 ret = bin_search(chunk_map->map, sizeof(chunk_map->map[0]), &item,
239 chunk_map->cur_length, &slot);
240 if (ret == 0)
241 slot++;
242 else if (slot == 0)
243 return INVALID_ADDRESS;
244 if (logical >= chunk_map->map[slot - 1].logical + chunk_map->map[slot - 1].length)
245 return INVALID_ADDRESS;
246
247 TRACE("Address translation: 0x%llx -> 0x%llx\n", logical,
248 chunk_map->map[slot - 1].physical + logical - chunk_map->map[slot - 1].logical);
249
250 return chunk_map->map[slot - 1].physical + logical - chunk_map->map[slot - 1].logical;
251}

Referenced by _BtrFsSearchTree(), and btrfs_read_extent_reg().

◆ next_length()

static int next_length ( const char path)
inlinestatic

Definition at line 1029 of file btrfs.c.

1030{
1031 int res = 0;
1032 while (*path != '\0' && *path != '/' && *path != '\\' && res <= BTRFS_NAME_MAX)
1033 ++res, ++path;
1034 return res;
1035}

Referenced by btrfs_lookup_path().

◆ next_slot()

static int next_slot ( PBTRFS_INFO  BtrFsInfo,
struct btrfs_disk_key key,
struct btrfs_path path 
)
static

Definition at line 384 of file btrfs.c.

386{
387 int slot, level = 1;
388
389 if (!path->itemsnr[0])
390 return 1;
391 slot = path->slots[0] + 1;
392 if (slot >= path->itemsnr[0])
393 {
394 /* jumping to next leaf */
395 while (level < BTRFS_MAX_LEVEL)
396 {
397 if (!path->itemsnr[level]) /* no more nodes */
398 return 1;
399 slot = path->slots[level] + 1;
400 if (slot >= path->itemsnr[level])
401 {
402 level++;
403 continue;
404 }
405 path->slots[level] = slot;
406 path->slots[level - 1] = 0; /* reset low level slots info */
407 path->itemsnr[level - 1] = 0;
408 path->offsets[level - 1] = 0;
409 _BtrFsSearchTree(BtrFsInfo, path->offsets[level], level, key, path);
410 break;
411 }
412 if (level == BTRFS_MAX_LEVEL)
413 return 1;
414 goto out;
415 }
416 path->slots[0] = slot;
417
418out:
420 return 0;
421 else
422 return 1;
423}
#define BTRFS_MAX_LEVEL
Definition: btrfs.h:69

Referenced by btrfs_file_read(), btrfs_read_chunk_tree(), and BtrFsLookupDirItemI().

◆ path_current_data()

static UCHAR * path_current_data ( struct btrfs_path path)
inlinestatic

◆ path_current_disk_key()

static const struct btrfs_disk_key * path_current_disk_key ( struct btrfs_path path)
inlinestatic

◆ path_current_item()

static struct btrfs_item * path_current_item ( struct btrfs_path path)
inlinestatic

Definition at line 178 of file btrfs.c.

179{
180 return &path->tree_buf->leaf.items[path->slots[0]];
181}

Referenced by _BtrFsSearchTree(), BtrFsMatchDirItemName(), path_current_data(), and path_current_disk_key().

◆ prev_slot()

static int prev_slot ( struct btrfs_disk_key key,
struct btrfs_path path 
)
static

Definition at line 425 of file btrfs.c.

427{
428 if (!path->slots[0])
429 return 1;
430 --path->slots[0];
432 return 0;
433 else
434 return 1;
435}

Referenced by btrfs_file_read().

◆ skip_current_directories()

static const char * skip_current_directories ( const char cur)
inlinestatic

Definition at line 1037 of file btrfs.c.

1038{
1039 while (1)
1040 {
1041 if (cur[0] == '/' || cur[0] == '\\')
1042 ++cur;
1043 else if (cur[0] == '.' && (cur[1] == '/' || cur[1] == '\\'))
1044 cur += 2;
1045 else
1046 break;
1047 }
1048
1049 return cur;
1050}

Referenced by btrfs_lookup_path().

◆ verify_dir_item()

static BOOLEAN verify_dir_item ( struct btrfs_dir_item item,
u32  start,
u32  total 
)
static

Definition at line 519 of file btrfs.c.

520{
521 u16 max_len = BTRFS_NAME_MAX;
522 u32 end;
523
524 if (item->type >= BTRFS_FT_MAX)
525 {
526 ERR("Invalid dir item type: %i\n", item->type);
527 return TRUE;
528 }
529
530 if (item->type == BTRFS_FT_XATTR)
531 max_len = 255; /* XATTR_NAME_MAX */
532
533 end = start + sizeof(*item) + item->name_len;
534 if (item->name_len > max_len || end > total)
535 {
536 ERR("Invalid dir item name len: %u\n", item->name_len);
537 return TRUE;
538 }
539
540 return FALSE;
541}
#define BTRFS_FT_MAX
Definition: btrfs.h:78
size_t total
GLuint start
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545

Referenced by BtrFsLookupDirItemI(), and BtrFsMatchDirItemName().

Variable Documentation

◆ BtrFsFuncTable

const DEVVTBL BtrFsFuncTable
Initial value:
=
{
L"btrfs",
}
ARC_STATUS BtrFsClose(ULONG FileId)
Definition: btrfs.c:1162
ARC_STATUS BtrFsOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: btrfs.c:1185
ARC_STATUS BtrFsSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: btrfs.c:1263
ARC_STATUS BtrFsRead(ULONG FileId, VOID *Buffer, ULONG Size, ULONG *BytesRead)
Definition: btrfs.c:1237
ARC_STATUS BtrFsGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: btrfs.c:1171
#define L(x)
Definition: ntvdm.h:50

Definition at line 1287 of file btrfs.c.

Referenced by BtrFsMount().

◆ BtrFsVolumes

PBTRFS_INFO BtrFsVolumes[MAX_FDS]

Definition at line 34 of file btrfs.c.

Referenced by BtrFsMount(), and BtrFsOpen().