Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
cfaa7295
Commit
cfaa7295
authored
Feb 21, 2007
by
Chris Mason
Committed by
David Woodhouse
Feb 21, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: extent fixes
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
06ed4b31
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
103 additions
and
61 deletions
+103
-61
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+46
-23
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+5
-0
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+45
-34
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+2
-2
fs/btrfs/mkfs.c
fs/btrfs/mkfs.c
+5
-2
No files found.
fs/btrfs/ctree.c
View file @
cfaa7295
...
...
@@ -354,6 +354,7 @@ int __insert_ptr(struct ctree_root *root,
c
->
header
.
nritems
=
2
;
c
->
header
.
flags
=
node_level
(
level
);
c
->
header
.
blocknr
=
t
->
blocknr
;
c
->
header
.
parentid
=
root
->
node
->
node
.
header
.
parentid
;
lower
=
&
path
->
nodes
[
level
-
1
]
->
node
;
if
(
is_leaf
(
lower
->
header
.
flags
))
lower_key
=
&
((
struct
leaf
*
)
lower
)
->
items
[
0
].
key
;
...
...
@@ -363,7 +364,7 @@ int __insert_ptr(struct ctree_root *root,
memcpy
(
c
->
keys
+
1
,
key
,
sizeof
(
struct
key
));
c
->
blockptrs
[
0
]
=
path
->
nodes
[
level
-
1
]
->
blocknr
;
c
->
blockptrs
[
1
]
=
blocknr
;
/* the
path
has an extra ref to root->node */
/* the
super
has an extra ref to root->node */
tree_block_release
(
root
,
root
->
node
);
root
->
node
=
t
;
t
->
count
++
;
...
...
@@ -439,6 +440,7 @@ int insert_ptr(struct ctree_root *root,
b
=
&
b_buffer
->
node
;
b
->
header
.
flags
=
c
->
header
.
flags
;
b
->
header
.
blocknr
=
b_buffer
->
blocknr
;
b
->
header
.
parentid
=
root
->
node
->
node
.
header
.
parentid
;
mid
=
(
c
->
header
.
nritems
+
1
)
/
2
;
memcpy
(
b
->
keys
,
c
->
keys
+
mid
,
(
c
->
header
.
nritems
-
mid
)
*
sizeof
(
struct
key
));
...
...
@@ -642,6 +644,7 @@ int split_leaf(struct ctree_root *root, struct ctree_path *path, int data_size)
right
->
header
.
nritems
=
nritems
-
mid
;
right
->
header
.
blocknr
=
right_buffer
->
blocknr
;
right
->
header
.
flags
=
node_level
(
0
);
right
->
header
.
parentid
=
root
->
node
->
node
.
header
.
parentid
;
data_copy_size
=
l
->
items
[
mid
].
offset
+
l
->
items
[
mid
].
size
-
leaf_data_end
(
l
);
memcpy
(
right
->
items
,
l
->
items
+
mid
,
...
...
@@ -689,8 +692,12 @@ int insert_item(struct ctree_root *root, struct key *key,
unsigned
int
data_end
;
struct
ctree_path
path
;
refill_alloc_extent
(
root
);
/* create a root if there isn't one */
if
(
!
root
->
node
)
{
BUG
();
#if 0
struct tree_buffer *t;
t = alloc_free_block(root);
BUG_ON(!t);
...
...
@@ -699,6 +706,7 @@ int insert_item(struct ctree_root *root, struct key *key,
t->node.header.blocknr = t->blocknr;
root->node = t;
write_tree_block(root, t);
#endif
}
init_path
(
&
path
);
ret
=
search_slot
(
root
,
key
,
&
path
);
...
...
@@ -758,7 +766,6 @@ int insert_item(struct ctree_root *root, struct key *key,
if
(
leaf_free_space
(
leaf
)
<
0
)
BUG
();
release_path
(
root
,
&
path
);
refill_alloc_extent
(
root
);
return
0
;
}
...
...
@@ -893,7 +900,7 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
int
level
=
1
;
u64
blocknr
;
struct
tree_buffer
*
c
;
struct
tree_buffer
*
next
;
struct
tree_buffer
*
next
=
NULL
;
while
(
level
<
MAX_LEVEL
)
{
if
(
!
path
->
nodes
[
level
])
...
...
@@ -905,6 +912,8 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
continue
;
}
blocknr
=
c
->
node
.
blockptrs
[
slot
];
if
(
next
)
tree_block_release
(
root
,
next
);
next
=
read_tree_block
(
root
,
blocknr
);
break
;
}
...
...
@@ -922,7 +931,7 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
return
0
;
}
int
alloc_extent
(
struct
ctree_root
*
root
,
u64
num_blocks
,
u64
search_start
,
int
alloc_extent
(
struct
ctree_root
*
orig_
root
,
u64
num_blocks
,
u64
search_start
,
u64
search_end
,
u64
owner
,
struct
key
*
ins
)
{
struct
ctree_path
path
;
...
...
@@ -934,6 +943,7 @@ int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start,
int
start_found
=
0
;
struct
leaf
*
l
;
struct
extent_item
extent_item
;
struct
ctree_root
*
root
=
orig_root
->
extent_root
;
init_path
(
&
path
);
ins
->
objectid
=
search_start
;
...
...
@@ -974,13 +984,18 @@ int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start,
start_found
=
1
;
last_block
=
key
->
objectid
+
key
->
offset
;
path
.
slots
[
0
]
++
;
printf
(
"last block is not %lu
\n
"
,
last_block
);
}
// FIXME -ENOSPC
insert:
release_path
(
root
,
&
path
);
extent_item
.
refs
=
1
;
extent_item
.
owner
=
owner
;
ret
=
insert_item
(
root
,
ins
,
&
extent_item
,
sizeof
(
extent_item
));
if
(
root
==
orig_root
&&
root
->
reserve_extent
->
num_blocks
==
0
)
{
root
->
reserve_extent
->
blocknr
=
ins
->
objectid
;
root
->
reserve_extent
->
num_blocks
=
ins
->
offset
;
root
->
reserve_extent
->
num_used
=
0
;
}
ret
=
insert_item
(
root
->
extent_root
,
ins
,
&
extent_item
,
sizeof
(
extent_item
));
return
ret
;
}
...
...
@@ -991,7 +1006,6 @@ static int refill_alloc_extent(struct ctree_root *root)
int
ret
;
int
min_blocks
=
MAX_LEVEL
*
2
;
printf
(
"refill alloc root %p, numused %lu total %lu
\n
"
,
root
,
ae
->
num_used
,
ae
->
num_blocks
);
if
(
ae
->
num_blocks
>
ae
->
num_used
&&
ae
->
num_blocks
-
ae
->
num_used
>
min_blocks
)
return
0
;
...
...
@@ -1007,9 +1021,9 @@ static int refill_alloc_extent(struct ctree_root *root)
BUG
();
return
0
;
}
// FIXME, this recurses
ret
=
alloc_extent
(
root
->
extent_root
,
min_blocks
*
2
,
0
,
(
unsigned
long
)
-
1
,
0
,
&
key
);
ret
=
alloc_extent
(
root
,
min_blocks
*
2
,
0
,
(
unsigned
long
)
-
1
,
root
->
node
->
node
.
header
.
parentid
,
&
key
);
ae
->
blocknr
=
key
.
objectid
;
ae
->
num_blocks
=
key
.
offset
;
ae
->
num_used
=
0
;
...
...
@@ -1021,6 +1035,7 @@ void print_leaf(struct leaf *l)
int
i
;
int
nr
=
l
->
header
.
nritems
;
struct
item
*
item
;
struct
extent_item
*
ei
;
printf
(
"leaf %lu total ptrs %d free space %d
\n
"
,
l
->
header
.
blocknr
,
nr
,
leaf_free_space
(
l
));
fflush
(
stdout
);
...
...
@@ -1032,6 +1047,8 @@ void print_leaf(struct leaf *l)
item
->
offset
,
item
->
size
);
fflush
(
stdout
);
printf
(
"
\t\t
item data %.*s
\n
"
,
item
->
size
,
l
->
data
+
item
->
offset
);
ei
=
(
struct
extent_item
*
)(
l
->
data
+
item
->
offset
);
printf
(
"
\t\t
extent data %u %lu
\n
"
,
ei
->
refs
,
ei
->
owner
);
fflush
(
stdout
);
}
}
...
...
@@ -1080,8 +1097,8 @@ void print_tree(struct ctree_root *root, struct tree_buffer *t)
/* for testing only */
int
next_key
(
int
i
,
int
max_key
)
{
//
return rand() % max_key;
return
i
;
return
rand
()
%
max_key
;
//
return i;
}
int
main
()
{
...
...
@@ -1092,15 +1109,20 @@ int main() {
int
i
;
int
num
;
int
ret
;
int
run_size
=
256
;
int
run_size
=
10000
;
int
max_key
=
100000000
;
int
tree_size
=
0
;
struct
ctree_path
path
;
struct
ctree_super_block
super
;
radix_tree_init
();
root
=
open_ctree
(
"dbfile"
);
root
=
open_ctree
(
"dbfile"
,
&
super
);
printf
(
"root tree
\n
"
);
print_tree
(
root
,
root
->
node
);
printf
(
"map tree
\n
"
);
print_tree
(
root
->
extent_root
,
root
->
extent_root
->
node
);
srand
(
55
);
for
(
i
=
0
;
i
<
run_size
;
i
++
)
{
...
...
@@ -1112,22 +1134,20 @@ int main() {
ins
.
objectid
=
num
;
ins
.
offset
=
0
;
ins
.
flags
=
0
;
printf
(
"insert %d
\n
"
,
i
);
ret
=
insert_item
(
root
,
&
ins
,
buf
,
strlen
(
buf
));
if
(
!
ret
)
tree_size
++
;
printf
(
"done insert %d
\n
"
,
i
);
}
printf
(
"root used: %lu
\n
"
,
root
->
alloc_extent
->
num_used
);
printf
(
"root tree
\n
"
);
print_tree
(
root
,
root
->
node
);
//
print_tree(root, root->node);
printf
(
"map tree
\n
"
);
printf
(
"map used: %lu
\n
"
,
root
->
extent_root
->
alloc_extent
->
num_used
);
print_tree
(
root
->
extent_root
,
root
->
extent_root
->
node
);
exit
(
1
);
// print_tree(root->extent_root, root->extent_root->node);
write_ctree_super
(
root
,
&
super
);
close_ctree
(
root
);
root
=
open_ctree
(
"dbfile"
);
root
=
open_ctree
(
"dbfile"
,
&
super
);
printf
(
"starting search
\n
"
);
srand
(
55
);
for
(
i
=
0
;
i
<
run_size
;
i
++
)
{
...
...
@@ -1142,8 +1162,9 @@ int main() {
}
release_path
(
root
,
&
path
);
}
write_ctree_super
(
root
,
&
super
);
close_ctree
(
root
);
root
=
open_ctree
(
"dbfile"
);
root
=
open_ctree
(
"dbfile"
,
&
super
);
printf
(
"node %p level %d total ptrs %d free spc %lu
\n
"
,
root
->
node
,
node_level
(
root
->
node
->
node
.
header
.
flags
),
root
->
node
->
node
.
header
.
nritems
,
...
...
@@ -1174,8 +1195,9 @@ int main() {
if
(
!
ret
)
tree_size
++
;
}
write_ctree_super
(
root
,
&
super
);
close_ctree
(
root
);
root
=
open_ctree
(
"dbfile"
);
root
=
open_ctree
(
"dbfile"
,
&
super
);
printf
(
"starting search2
\n
"
);
srand
(
128
);
for
(
i
=
0
;
i
<
run_size
;
i
++
)
{
...
...
@@ -1221,6 +1243,7 @@ int main() {
}
release_path
(
root
,
&
path
);
}
write_ctree_super
(
root
,
&
super
);
close_ctree
(
root
);
printf
(
"tree size is now %d
\n
"
,
tree_size
);
return
0
;
...
...
fs/btrfs/ctree.h
View file @
cfaa7295
...
...
@@ -57,6 +57,11 @@ struct ctree_root_info {
u64
snapuuid
[
2
];
/* root specific uuid */
}
__attribute__
((
__packed__
));
struct
ctree_super_block
{
struct
ctree_root_info
root_info
;
struct
ctree_root_info
extent_info
;
}
__attribute__
((
__packed__
));
struct
item
{
struct
key
key
;
u16
offset
;
...
...
fs/btrfs/disk-io.c
View file @
cfaa7295
...
...
@@ -15,7 +15,7 @@ static int allocated_blocks = 0;
static
int
get_free_block
(
struct
ctree_root
*
root
,
u64
*
block
)
{
struct
stat
st
;
int
ret
;
int
ret
=
0
;
if
(
root
->
alloc_extent
->
num_used
>=
root
->
alloc_extent
->
num_blocks
)
return
-
1
;
...
...
@@ -30,9 +30,14 @@ static int get_free_block(struct ctree_root *root, u64 *block)
}
st
.
st_size
=
0
;
ret
=
fstat
(
root
->
fp
,
&
st
);
if
(
st
.
st_size
<
(
*
block
+
1
)
*
CTREE_BLOCKSIZE
)
if
(
st
.
st_size
<
(
*
block
+
1
)
*
CTREE_BLOCKSIZE
)
{
ret
=
ftruncate
(
root
->
fp
,
(
*
block
+
1
)
*
CTREE_BLOCKSIZE
);
if
(
ret
)
{
perror
(
"ftruncate"
);
exit
(
1
);
}
}
return
ret
;
}
...
...
@@ -81,11 +86,7 @@ struct tree_buffer *read_tree_block(struct ctree_root *root, u64 blocknr)
buf
=
radix_tree_lookup
(
&
root
->
cache_radix
,
blocknr
);
if
(
buf
)
{
buf
->
count
++
;
if
(
buf
->
blocknr
!=
blocknr
)
BUG
();
if
(
buf
->
blocknr
!=
buf
->
node
.
header
.
blocknr
)
BUG
();
return
buf
;
goto
test
;
}
buf
=
alloc_tree_block
(
root
,
blocknr
);
if
(
!
buf
)
...
...
@@ -95,8 +96,11 @@ struct tree_buffer *read_tree_block(struct ctree_root *root, u64 blocknr)
free
(
buf
);
return
NULL
;
}
test:
if
(
buf
->
blocknr
!=
buf
->
node
.
header
.
blocknr
)
BUG
();
if
(
root
->
node
&&
buf
->
node
.
header
.
parentid
!=
root
->
node
->
node
.
header
.
parentid
)
BUG
();
return
buf
;
}
...
...
@@ -111,36 +115,30 @@ int write_tree_block(struct ctree_root *root, struct tree_buffer *buf)
ret
=
pwrite
(
root
->
fp
,
&
buf
->
node
,
CTREE_BLOCKSIZE
,
offset
);
if
(
ret
!=
CTREE_BLOCKSIZE
)
return
ret
;
if
(
buf
==
root
->
node
)
return
update_root_block
(
root
);
return
0
;
}
struct
ctree_super_block
{
struct
ctree_root_info
root_info
;
struct
ctree_root_info
extent_info
;
}
__attribute__
((
__packed__
));
static
int
__setup_root
(
struct
ctree_root
*
root
,
struct
ctree_root
*
extent_root
,
struct
ctree_root_info
*
info
,
int
fp
)
{
INIT_RADIX_TREE
(
&
root
->
cache_radix
,
GFP_KERNEL
);
root
->
fp
=
fp
;
root
->
node
=
NULL
;
root
->
node
=
read_tree_block
(
root
,
info
->
tree_root
);
root
->
extent_root
=
extent_root
;
memcpy
(
&
root
->
ai1
,
&
info
->
alloc_extent
,
sizeof
(
info
->
alloc_extent
));
memcpy
(
&
root
->
ai2
,
&
info
->
reserve_extent
,
sizeof
(
info
->
reserve_extent
));
root
->
alloc_extent
=
&
root
->
ai1
;
root
->
reserve_extent
=
&
root
->
ai2
;
INIT_RADIX_TREE
(
&
root
->
cache_radix
,
GFP_KERNEL
);
printf
(
"setup done reading root %p,
used %lu
\n
"
,
root
,
root
->
alloc_extent
->
num_used
);
printf
(
"setup done reading root %p, used %lu available %lu
\n
"
,
root
,
root
->
alloc_extent
->
num_used
,
root
->
alloc_extent
->
num_blocks
);
printf
(
"setup done reading root %p,
reserve used %lu available %lu
\n
"
,
root
,
root
->
reserve_extent
->
num_used
,
root
->
reserve_extent
->
num_blocks
);
return
0
;
}
struct
ctree_root
*
open_ctree
(
char
*
filename
)
struct
ctree_root
*
open_ctree
(
char
*
filename
,
struct
ctree_super_block
*
super
)
{
struct
ctree_root
*
root
=
malloc
(
sizeof
(
struct
ctree_root
));
struct
ctree_root
*
extent_root
=
malloc
(
sizeof
(
struct
ctree_root
));
struct
ctree_super_block
super
;
int
fp
;
int
ret
;
...
...
@@ -149,48 +147,61 @@ struct ctree_root *open_ctree(char *filename)
free
(
root
);
return
NULL
;
}
ret
=
pread
(
fp
,
&
super
,
sizeof
(
struct
ctree_super_block
),
ret
=
pread
(
fp
,
super
,
sizeof
(
struct
ctree_super_block
),
CTREE_SUPER_INFO_OFFSET
(
CTREE_BLOCKSIZE
));
if
(
ret
==
0
)
{
ret
=
mkfs
(
fp
);
if
(
ret
)
return
NULL
;
ret
=
pread
(
fp
,
&
super
,
sizeof
(
struct
ctree_super_block
),
ret
=
pread
(
fp
,
super
,
sizeof
(
struct
ctree_super_block
),
CTREE_SUPER_INFO_OFFSET
(
CTREE_BLOCKSIZE
));
if
(
ret
!=
sizeof
(
struct
ctree_super_block
))
return
NULL
;
}
BUG_ON
(
ret
<
0
);
__setup_root
(
root
,
extent_root
,
&
super
.
root_info
,
fp
);
__setup_root
(
extent_root
,
extent_root
,
&
super
.
extent_info
,
fp
);
__setup_root
(
root
,
extent_root
,
&
super
->
root_info
,
fp
);
__setup_root
(
extent_root
,
extent_root
,
&
super
->
extent_info
,
fp
);
return
root
;
}
int
close_ctree
(
struct
ctree_root
*
root
)
static
int
__update_root
(
struct
ctree_root
*
root
,
struct
ctree_root_info
*
info
)
{
close
(
root
->
fp
);
if
(
root
->
node
)
tree_block_release
(
root
,
root
->
node
);
free
(
root
);
printf
(
"on close %d blocks are allocated
\n
"
,
allocated_blocks
);
info
->
tree_root
=
root
->
node
->
blocknr
;
memcpy
(
&
info
->
alloc_extent
,
root
->
alloc_extent
,
sizeof
(
struct
alloc_extent
));
memcpy
(
&
info
->
reserve_extent
,
root
->
reserve_extent
,
sizeof
(
struct
alloc_extent
));
return
0
;
}
int
update_root_block
(
struct
ctree_root
*
root
)
int
write_ctree_super
(
struct
ctree_root
*
root
,
struct
ctree_super_block
*
s
)
{
int
ret
;
u64
root_block
=
root
->
node
->
blocknr
;
ret
=
pwrite
(
root
->
fp
,
&
root_block
,
sizeof
(
u64
),
0
);
if
(
ret
!=
sizeof
(
u64
))
__update_root
(
root
,
&
s
->
root_info
);
__update_root
(
root
->
extent_root
,
&
s
->
extent_info
);
ret
=
pwrite
(
root
->
fp
,
s
,
sizeof
(
*
s
),
CTREE_SUPER_INFO_OFFSET
(
CTREE_BLOCKSIZE
));
if
(
ret
!=
sizeof
(
*
s
))
{
fprintf
(
stderr
,
"failed to write new super block err %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
int
close_ctree
(
struct
ctree_root
*
root
)
{
close
(
root
->
fp
);
if
(
root
->
node
)
tree_block_release
(
root
,
root
->
node
);
if
(
root
->
extent_root
->
node
)
tree_block_release
(
root
->
extent_root
,
root
->
extent_root
->
node
);
free
(
root
);
printf
(
"on close %d blocks are allocated
\n
"
,
allocated_blocks
);
return
0
;
}
void
tree_block_release
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
buf
)
{
return
;
buf
->
count
--
;
if
(
buf
->
count
<
0
)
BUG
();
if
(
buf
->
count
==
0
)
{
if
(
!
radix_tree_lookup
(
&
root
->
cache_radix
,
buf
->
blocknr
))
BUG
();
...
...
fs/btrfs/disk-io.h
View file @
cfaa7295
...
...
@@ -12,11 +12,11 @@ struct tree_buffer {
struct
tree_buffer
*
read_tree_block
(
struct
ctree_root
*
root
,
u64
blocknr
);
int
write_tree_block
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
buf
);
struct
ctree_root
*
open_ctree
(
char
*
filename
);
struct
ctree_root
*
open_ctree
(
char
*
filename
,
struct
ctree_super_block
*
s
);
int
close_ctree
(
struct
ctree_root
*
root
);
void
tree_block_release
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
buf
);
struct
tree_buffer
*
alloc_free_block
(
struct
ctree_root
*
root
);
int
update_root_block
(
struct
ctree_root
*
root
);
int
write_ctree_super
(
struct
ctree_root
*
root
,
struct
ctree_super_block
*
s
);
int
mkfs
(
int
fd
);
#define CTREE_SUPER_INFO_OFFSET(bs) (16 * (bs))
...
...
fs/btrfs/mkfs.c
View file @
cfaa7295
...
...
@@ -18,12 +18,13 @@ int mkfs(int fd)
struct
extent_item
extent_item
;
int
ret
;
/* setup the super block area */
memset
(
info
,
0
,
sizeof
(
info
));
info
[
0
].
blocknr
=
16
;
info
[
0
].
objectid
=
1
;
info
[
0
].
tree_root
=
17
;
info
[
0
].
alloc_extent
.
blocknr
=
0
;
info
[
0
].
alloc_extent
.
num_blocks
=
20
;
info
[
0
].
alloc_extent
.
num_blocks
=
64
;
/* 0-17 are used (inclusive) */
info
[
0
].
alloc_extent
.
num_used
=
18
;
...
...
@@ -31,12 +32,14 @@ int mkfs(int fd)
info
[
1
].
objectid
=
2
;
info
[
1
].
tree_root
=
64
;
info
[
1
].
alloc_extent
.
blocknr
=
64
;
info
[
1
].
alloc_extent
.
num_blocks
=
8
;
info
[
1
].
alloc_extent
.
num_blocks
=
64
;
info
[
1
].
alloc_extent
.
num_used
=
1
;
ret
=
pwrite
(
fd
,
info
,
sizeof
(
info
),
CTREE_SUPER_INFO_OFFSET
(
CTREE_BLOCKSIZE
));
if
(
ret
!=
sizeof
(
info
))
return
-
1
;
/* create leaves for the tree root and extent root */
memset
(
&
empty_leaf
,
0
,
sizeof
(
empty_leaf
));
empty_leaf
.
header
.
parentid
=
1
;
empty_leaf
.
header
.
blocknr
=
17
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment