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
Kirill Smelkov
linux
Commits
123abc88
Commit
123abc88
authored
Mar 14, 2007
by
Chris Mason
Committed by
David Woodhouse
Mar 14, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: variable block size support
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
4beb1b8b
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
238 additions
and
300 deletions
+238
-300
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+111
-114
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+35
-27
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+23
-19
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+4
-5
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+2
-4
fs/btrfs/mkfs.c
fs/btrfs/mkfs.c
+51
-120
fs/btrfs/print-tree.c
fs/btrfs/print-tree.c
+8
-7
fs/btrfs/print-tree.h
fs/btrfs/print-tree.h
+1
-1
fs/btrfs/quick-test.c
fs/btrfs/quick-test.c
+1
-1
fs/btrfs/root-tree.c
fs/btrfs/root-tree.c
+2
-2
No files found.
fs/btrfs/ctree.c
View file @
123abc88
...
@@ -47,7 +47,7 @@ static int btrfs_cow_block(struct btrfs_root *root,
...
@@ -47,7 +47,7 @@ static int btrfs_cow_block(struct btrfs_root *root,
return
0
;
return
0
;
}
}
cow
=
btrfs_alloc_free_block
(
root
);
cow
=
btrfs_alloc_free_block
(
root
);
memcpy
(
&
cow
->
node
,
&
buf
->
node
,
sizeof
(
buf
->
node
)
);
memcpy
(
&
cow
->
node
,
&
buf
->
node
,
root
->
blocksize
);
btrfs_set_header_blocknr
(
&
cow
->
node
.
header
,
cow
->
blocknr
);
btrfs_set_header_blocknr
(
&
cow
->
node
.
header
,
cow
->
blocknr
);
*
cow_ret
=
cow
;
*
cow_ret
=
cow
;
btrfs_inc_ref
(
root
,
buf
);
btrfs_inc_ref
(
root
,
buf
);
...
@@ -72,11 +72,12 @@ static int btrfs_cow_block(struct btrfs_root *root,
...
@@ -72,11 +72,12 @@ static int btrfs_cow_block(struct btrfs_root *root,
* this returns the address of the start of the last item,
* this returns the address of the start of the last item,
* which is the stop of the leaf data stack
* which is the stop of the leaf data stack
*/
*/
static
inline
unsigned
int
leaf_data_end
(
struct
btrfs_leaf
*
leaf
)
static
inline
unsigned
int
leaf_data_end
(
struct
btrfs_root
*
root
,
struct
btrfs_leaf
*
leaf
)
{
{
u32
nr
=
btrfs_header_nritems
(
&
leaf
->
header
);
u32
nr
=
btrfs_header_nritems
(
&
leaf
->
header
);
if
(
nr
==
0
)
if
(
nr
==
0
)
return
sizeof
(
leaf
->
data
);
return
BTRFS_LEAF_DATA_SIZE
(
root
);
return
btrfs_item_offset
(
leaf
->
items
+
nr
-
1
);
return
btrfs_item_offset
(
leaf
->
items
+
nr
-
1
);
}
}
...
@@ -85,12 +86,12 @@ static inline unsigned int leaf_data_end(struct btrfs_leaf *leaf)
...
@@ -85,12 +86,12 @@ static inline unsigned int leaf_data_end(struct btrfs_leaf *leaf)
* the start of the leaf data. IOW, how much room
* the start of the leaf data. IOW, how much room
* the leaf has left for both items and data
* the leaf has left for both items and data
*/
*/
int
btrfs_leaf_free_space
(
struct
btrfs_leaf
*
leaf
)
int
btrfs_leaf_free_space
(
struct
btrfs_
root
*
root
,
struct
btrfs_
leaf
*
leaf
)
{
{
int
data_end
=
leaf_data_end
(
leaf
);
int
data_end
=
leaf_data_end
(
root
,
leaf
);
int
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
int
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
char
*
items_end
=
(
char
*
)(
leaf
->
items
+
nritems
+
1
);
char
*
items_end
=
(
char
*
)(
leaf
->
items
+
nritems
+
1
);
return
(
char
*
)(
leaf
->
data
+
data_end
)
-
(
char
*
)
items_end
;
return
(
char
*
)(
btrfs_leaf_data
(
leaf
)
+
data_end
)
-
(
char
*
)
items_end
;
}
}
/*
/*
...
@@ -117,7 +118,8 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
...
@@ -117,7 +118,8 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
return
0
;
return
0
;
}
}
static
int
check_node
(
struct
btrfs_path
*
path
,
int
level
)
static
int
check_node
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
int
level
)
{
{
int
i
;
int
i
;
struct
btrfs_node
*
parent
=
NULL
;
struct
btrfs_node
*
parent
=
NULL
;
...
@@ -131,22 +133,23 @@ static int check_node(struct btrfs_path *path, int level)
...
@@ -131,22 +133,23 @@ static int check_node(struct btrfs_path *path, int level)
BUG_ON
(
nritems
==
0
);
BUG_ON
(
nritems
==
0
);
if
(
parent
)
{
if
(
parent
)
{
struct
btrfs_disk_key
*
parent_key
;
struct
btrfs_disk_key
*
parent_key
;
parent_key
=
&
parent
->
keys
[
parent_slot
]
;
parent_key
=
&
parent
->
ptrs
[
parent_slot
].
key
;
BUG_ON
(
memcmp
(
parent_key
,
node
->
keys
,
BUG_ON
(
memcmp
(
parent_key
,
&
node
->
ptrs
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
)));
sizeof
(
struct
btrfs_disk_key
)));
BUG_ON
(
btrfs_node_blockptr
(
parent
,
parent_slot
)
!=
BUG_ON
(
btrfs_node_blockptr
(
parent
,
parent_slot
)
!=
btrfs_header_blocknr
(
&
node
->
header
));
btrfs_header_blocknr
(
&
node
->
header
));
}
}
BUG_ON
(
nritems
>
NODEPTRS_PER_BLOCK
);
BUG_ON
(
nritems
>
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
);
for
(
i
=
0
;
nritems
>
1
&&
i
<
nritems
-
2
;
i
++
)
{
for
(
i
=
0
;
nritems
>
1
&&
i
<
nritems
-
2
;
i
++
)
{
struct
btrfs_key
cpukey
;
struct
btrfs_key
cpukey
;
btrfs_disk_key_to_cpu
(
&
cpukey
,
&
node
->
keys
[
i
+
1
]
);
btrfs_disk_key_to_cpu
(
&
cpukey
,
&
node
->
ptrs
[
i
+
1
].
key
);
BUG_ON
(
comp_keys
(
&
node
->
keys
[
i
]
,
&
cpukey
)
>=
0
);
BUG_ON
(
comp_keys
(
&
node
->
ptrs
[
i
].
key
,
&
cpukey
)
>=
0
);
}
}
return
0
;
return
0
;
}
}
static
int
check_leaf
(
struct
btrfs_path
*
path
,
int
level
)
static
int
check_leaf
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
int
level
)
{
{
int
i
;
int
i
;
struct
btrfs_leaf
*
leaf
=
&
path
->
nodes
[
level
]
->
leaf
;
struct
btrfs_leaf
*
leaf
=
&
path
->
nodes
[
level
]
->
leaf
;
...
@@ -157,14 +160,14 @@ static int check_leaf(struct btrfs_path *path, int level)
...
@@ -157,14 +160,14 @@ static int check_leaf(struct btrfs_path *path, int level)
if
(
path
->
nodes
[
level
+
1
])
if
(
path
->
nodes
[
level
+
1
])
parent
=
&
path
->
nodes
[
level
+
1
]
->
node
;
parent
=
&
path
->
nodes
[
level
+
1
]
->
node
;
parent_slot
=
path
->
slots
[
level
+
1
];
parent_slot
=
path
->
slots
[
level
+
1
];
BUG_ON
(
btrfs_leaf_free_space
(
leaf
)
<
0
);
BUG_ON
(
btrfs_leaf_free_space
(
root
,
leaf
)
<
0
);
if
(
nritems
==
0
)
if
(
nritems
==
0
)
return
0
;
return
0
;
if
(
parent
)
{
if
(
parent
)
{
struct
btrfs_disk_key
*
parent_key
;
struct
btrfs_disk_key
*
parent_key
;
parent_key
=
&
parent
->
keys
[
parent_slot
]
;
parent_key
=
&
parent
->
ptrs
[
parent_slot
].
key
;
BUG_ON
(
memcmp
(
parent_key
,
&
leaf
->
items
[
0
].
key
,
BUG_ON
(
memcmp
(
parent_key
,
&
leaf
->
items
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
)));
sizeof
(
struct
btrfs_disk_key
)));
BUG_ON
(
btrfs_node_blockptr
(
parent
,
parent_slot
)
!=
BUG_ON
(
btrfs_node_blockptr
(
parent
,
parent_slot
)
!=
...
@@ -180,17 +183,18 @@ static int check_leaf(struct btrfs_path *path, int level)
...
@@ -180,17 +183,18 @@ static int check_leaf(struct btrfs_path *path, int level)
if
(
i
==
0
)
{
if
(
i
==
0
)
{
BUG_ON
(
btrfs_item_offset
(
leaf
->
items
+
i
)
+
BUG_ON
(
btrfs_item_offset
(
leaf
->
items
+
i
)
+
btrfs_item_size
(
leaf
->
items
+
i
)
!=
btrfs_item_size
(
leaf
->
items
+
i
)
!=
LEAF_DATA_SIZE
);
BTRFS_LEAF_DATA_SIZE
(
root
)
);
}
}
}
}
return
0
;
return
0
;
}
}
static
int
check_block
(
struct
btrfs_path
*
path
,
int
level
)
static
int
check_block
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
int
level
)
{
{
if
(
level
==
0
)
if
(
level
==
0
)
return
check_leaf
(
path
,
level
);
return
check_leaf
(
root
,
path
,
level
);
return
check_node
(
path
,
level
);
return
check_node
(
root
,
path
,
level
);
}
}
/*
/*
...
@@ -242,8 +246,8 @@ static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
...
@@ -242,8 +246,8 @@ static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
key
,
btrfs_header_nritems
(
&
c
->
header
),
key
,
btrfs_header_nritems
(
&
c
->
header
),
slot
);
slot
);
}
else
{
}
else
{
return
generic_bin_search
((
void
*
)
c
->
key
s
,
return
generic_bin_search
((
void
*
)
c
->
ptr
s
,
sizeof
(
struct
btrfs_
disk_key
),
sizeof
(
struct
btrfs_
key_ptr
),
key
,
btrfs_header_nritems
(
&
c
->
header
),
key
,
btrfs_header_nritems
(
&
c
->
header
),
slot
);
slot
);
}
}
...
@@ -311,7 +315,8 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -311,7 +315,8 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
}
}
parent
=
&
parent_buf
->
node
;
parent
=
&
parent_buf
->
node
;
if
(
btrfs_header_nritems
(
&
mid
->
header
)
>
NODEPTRS_PER_BLOCK
/
4
)
if
(
btrfs_header_nritems
(
&
mid
->
header
)
>
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
/
4
)
return
0
;
return
0
;
left_buf
=
read_node_slot
(
root
,
parent_buf
,
pslot
-
1
);
left_buf
=
read_node_slot
(
root
,
parent_buf
,
pslot
-
1
);
...
@@ -351,7 +356,8 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -351,7 +356,8 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
if
(
wret
)
if
(
wret
)
ret
=
wret
;
ret
=
wret
;
}
else
{
}
else
{
memcpy
(
parent
->
keys
+
pslot
+
1
,
right
->
keys
,
memcpy
(
&
parent
->
ptrs
[
pslot
+
1
].
key
,
&
right
->
ptrs
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
sizeof
(
struct
btrfs_disk_key
));
BUG_ON
(
list_empty
(
&
parent_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
parent_buf
->
dirty
));
}
}
...
@@ -387,7 +393,7 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -387,7 +393,7 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
ret
=
wret
;
ret
=
wret
;
}
else
{
}
else
{
/* update the parent key to reflect our changes */
/* update the parent key to reflect our changes */
memcpy
(
parent
->
keys
+
pslot
,
mid
->
keys
,
memcpy
(
&
parent
->
ptrs
[
pslot
].
key
,
&
mid
->
ptrs
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
sizeof
(
struct
btrfs_disk_key
));
BUG_ON
(
list_empty
(
&
parent_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
parent_buf
->
dirty
));
}
}
...
@@ -407,7 +413,7 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -407,7 +413,7 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
}
}
}
}
/* double check we haven't messed things up */
/* double check we haven't messed things up */
check_block
(
path
,
level
);
check_block
(
root
,
path
,
level
);
if
(
orig_ptr
!=
btrfs_node_blockptr
(
&
path
->
nodes
[
level
]
->
node
,
if
(
orig_ptr
!=
btrfs_node_blockptr
(
&
path
->
nodes
[
level
]
->
node
,
path
->
slots
[
level
]))
path
->
slots
[
level
]))
BUG
();
BUG
();
...
@@ -456,7 +462,7 @@ int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key,
...
@@ -456,7 +462,7 @@ int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key,
BUG_ON
(
!
cow
&&
ins_len
);
BUG_ON
(
!
cow
&&
ins_len
);
c
=
&
b
->
node
;
c
=
&
b
->
node
;
p
->
nodes
[
level
]
=
b
;
p
->
nodes
[
level
]
=
b
;
ret
=
check_block
(
p
,
level
);
ret
=
check_block
(
root
,
p
,
level
);
if
(
ret
)
if
(
ret
)
return
-
1
;
return
-
1
;
ret
=
bin_search
(
c
,
key
,
&
slot
);
ret
=
bin_search
(
c
,
key
,
&
slot
);
...
@@ -465,7 +471,7 @@ int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key,
...
@@ -465,7 +471,7 @@ int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key,
slot
-=
1
;
slot
-=
1
;
p
->
slots
[
level
]
=
slot
;
p
->
slots
[
level
]
=
slot
;
if
(
ins_len
>
0
&&
btrfs_header_nritems
(
&
c
->
header
)
==
if
(
ins_len
>
0
&&
btrfs_header_nritems
(
&
c
->
header
)
==
NODEPTRS_PER_BLOCK
)
{
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
)
{
int
sret
=
split_node
(
root
,
p
,
level
);
int
sret
=
split_node
(
root
,
p
,
level
);
BUG_ON
(
sret
>
0
);
BUG_ON
(
sret
>
0
);
if
(
sret
)
if
(
sret
)
...
@@ -488,7 +494,7 @@ int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key,
...
@@ -488,7 +494,7 @@ int btrfs_search_slot(struct btrfs_root *root, struct btrfs_key *key,
}
else
{
}
else
{
struct
btrfs_leaf
*
l
=
(
struct
btrfs_leaf
*
)
c
;
struct
btrfs_leaf
*
l
=
(
struct
btrfs_leaf
*
)
c
;
p
->
slots
[
level
]
=
slot
;
p
->
slots
[
level
]
=
slot
;
if
(
ins_len
>
0
&&
btrfs_leaf_free_space
(
l
)
<
if
(
ins_len
>
0
&&
btrfs_leaf_free_space
(
root
,
l
)
<
sizeof
(
struct
btrfs_item
)
+
ins_len
)
{
sizeof
(
struct
btrfs_item
)
+
ins_len
)
{
int
sret
=
split_leaf
(
root
,
p
,
ins_len
);
int
sret
=
split_leaf
(
root
,
p
,
ins_len
);
BUG_ON
(
sret
>
0
);
BUG_ON
(
sret
>
0
);
...
@@ -525,7 +531,7 @@ static int fixup_low_keys(struct btrfs_root *root,
...
@@ -525,7 +531,7 @@ static int fixup_low_keys(struct btrfs_root *root,
if
(
!
path
->
nodes
[
i
])
if
(
!
path
->
nodes
[
i
])
break
;
break
;
t
=
&
path
->
nodes
[
i
]
->
node
;
t
=
&
path
->
nodes
[
i
]
->
node
;
memcpy
(
t
->
keys
+
tslot
,
key
,
sizeof
(
*
key
));
memcpy
(
&
t
->
ptrs
[
tslot
].
key
,
key
,
sizeof
(
*
key
));
BUG_ON
(
list_empty
(
&
path
->
nodes
[
i
]
->
dirty
));
BUG_ON
(
list_empty
(
&
path
->
nodes
[
i
]
->
dirty
));
if
(
tslot
!=
0
)
if
(
tslot
!=
0
)
break
;
break
;
...
@@ -552,7 +558,7 @@ static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf,
...
@@ -552,7 +558,7 @@ static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf,
src_nritems
=
btrfs_header_nritems
(
&
src
->
header
);
src_nritems
=
btrfs_header_nritems
(
&
src
->
header
);
dst_nritems
=
btrfs_header_nritems
(
&
dst
->
header
);
dst_nritems
=
btrfs_header_nritems
(
&
dst
->
header
);
push_items
=
NODEPTRS_PER_BLOCK
-
dst_nritems
;
push_items
=
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
-
dst_nritems
;
if
(
push_items
<=
0
)
{
if
(
push_items
<=
0
)
{
return
1
;
return
1
;
}
}
...
@@ -560,16 +566,12 @@ static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf,
...
@@ -560,16 +566,12 @@ static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf,
if
(
src_nritems
<
push_items
)
if
(
src_nritems
<
push_items
)
push_items
=
src_nritems
;
push_items
=
src_nritems
;
memcpy
(
dst
->
keys
+
dst_nritems
,
src
->
keys
,
memcpy
(
dst
->
ptrs
+
dst_nritems
,
src
->
ptrs
,
push_items
*
sizeof
(
struct
btrfs_disk_key
));
push_items
*
sizeof
(
struct
btrfs_key_ptr
));
memcpy
(
dst
->
blockptrs
+
dst_nritems
,
src
->
blockptrs
,
push_items
*
sizeof
(
u64
));
if
(
push_items
<
src_nritems
)
{
if
(
push_items
<
src_nritems
)
{
memmove
(
src
->
keys
,
src
->
key
s
+
push_items
,
memmove
(
src
->
ptrs
,
src
->
ptr
s
+
push_items
,
(
src_nritems
-
push_items
)
*
(
src_nritems
-
push_items
)
*
sizeof
(
struct
btrfs_disk_key
));
sizeof
(
struct
btrfs_key_ptr
));
memmove
(
src
->
blockptrs
,
src
->
blockptrs
+
push_items
,
(
src_nritems
-
push_items
)
*
sizeof
(
u64
));
}
}
btrfs_set_header_nritems
(
&
src
->
header
,
src_nritems
-
push_items
);
btrfs_set_header_nritems
(
&
src
->
header
,
src_nritems
-
push_items
);
btrfs_set_header_nritems
(
&
dst
->
header
,
dst_nritems
+
push_items
);
btrfs_set_header_nritems
(
&
dst
->
header
,
dst_nritems
+
push_items
);
...
@@ -601,7 +603,7 @@ static int balance_node_right(struct btrfs_root *root,
...
@@ -601,7 +603,7 @@ static int balance_node_right(struct btrfs_root *root,
src_nritems
=
btrfs_header_nritems
(
&
src
->
header
);
src_nritems
=
btrfs_header_nritems
(
&
src
->
header
);
dst_nritems
=
btrfs_header_nritems
(
&
dst
->
header
);
dst_nritems
=
btrfs_header_nritems
(
&
dst
->
header
);
push_items
=
NODEPTRS_PER_BLOCK
-
dst_nritems
;
push_items
=
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
-
dst_nritems
;
if
(
push_items
<=
0
)
{
if
(
push_items
<=
0
)
{
return
1
;
return
1
;
}
}
...
@@ -613,14 +615,10 @@ static int balance_node_right(struct btrfs_root *root,
...
@@ -613,14 +615,10 @@ static int balance_node_right(struct btrfs_root *root,
if
(
max_push
<
push_items
)
if
(
max_push
<
push_items
)
push_items
=
max_push
;
push_items
=
max_push
;
memmove
(
dst
->
keys
+
push_items
,
dst
->
keys
,
memmove
(
dst
->
ptrs
+
push_items
,
dst
->
ptrs
,
dst_nritems
*
sizeof
(
struct
btrfs_disk_key
));
dst_nritems
*
sizeof
(
struct
btrfs_key_ptr
));
memmove
(
dst
->
blockptrs
+
push_items
,
dst
->
blockptrs
,
memcpy
(
dst
->
ptrs
,
src
->
ptrs
+
src_nritems
-
push_items
,
dst_nritems
*
sizeof
(
u64
));
push_items
*
sizeof
(
struct
btrfs_key_ptr
));
memcpy
(
dst
->
keys
,
src
->
keys
+
src_nritems
-
push_items
,
push_items
*
sizeof
(
struct
btrfs_disk_key
));
memcpy
(
dst
->
blockptrs
,
src
->
blockptrs
+
src_nritems
-
push_items
,
push_items
*
sizeof
(
u64
));
btrfs_set_header_nritems
(
&
src
->
header
,
src_nritems
-
push_items
);
btrfs_set_header_nritems
(
&
src
->
header
,
src_nritems
-
push_items
);
btrfs_set_header_nritems
(
&
dst
->
header
,
dst_nritems
+
push_items
);
btrfs_set_header_nritems
(
&
dst
->
header
,
dst_nritems
+
push_items
);
...
@@ -650,7 +648,7 @@ static int insert_new_root(struct btrfs_root *root,
...
@@ -650,7 +648,7 @@ static int insert_new_root(struct btrfs_root *root,
t
=
btrfs_alloc_free_block
(
root
);
t
=
btrfs_alloc_free_block
(
root
);
c
=
&
t
->
node
;
c
=
&
t
->
node
;
memset
(
c
,
0
,
sizeof
(
c
)
);
memset
(
c
,
0
,
root
->
blocksize
);
btrfs_set_header_nritems
(
&
c
->
header
,
1
);
btrfs_set_header_nritems
(
&
c
->
header
,
1
);
btrfs_set_header_level
(
&
c
->
header
,
level
);
btrfs_set_header_level
(
&
c
->
header
,
level
);
btrfs_set_header_blocknr
(
&
c
->
header
,
t
->
blocknr
);
btrfs_set_header_blocknr
(
&
c
->
header
,
t
->
blocknr
);
...
@@ -660,8 +658,8 @@ static int insert_new_root(struct btrfs_root *root,
...
@@ -660,8 +658,8 @@ static int insert_new_root(struct btrfs_root *root,
if
(
btrfs_is_leaf
(
lower
))
if
(
btrfs_is_leaf
(
lower
))
lower_key
=
&
((
struct
btrfs_leaf
*
)
lower
)
->
items
[
0
].
key
;
lower_key
=
&
((
struct
btrfs_leaf
*
)
lower
)
->
items
[
0
].
key
;
else
else
lower_key
=
lower
->
keys
;
lower_key
=
&
lower
->
ptrs
[
0
].
key
;
memcpy
(
c
->
keys
,
lower_key
,
sizeof
(
struct
btrfs_disk_key
));
memcpy
(
&
c
->
ptrs
[
0
].
key
,
lower_key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_set_node_blockptr
(
c
,
0
,
path
->
nodes
[
level
-
1
]
->
blocknr
);
btrfs_set_node_blockptr
(
c
,
0
,
path
->
nodes
[
level
-
1
]
->
blocknr
);
/* the super has an extra ref to root->node */
/* the super has an extra ref to root->node */
btrfs_block_release
(
root
,
root
->
node
);
btrfs_block_release
(
root
,
root
->
node
);
...
@@ -693,19 +691,15 @@ static int insert_ptr(struct btrfs_root *root,
...
@@ -693,19 +691,15 @@ static int insert_ptr(struct btrfs_root *root,
nritems
=
btrfs_header_nritems
(
&
lower
->
header
);
nritems
=
btrfs_header_nritems
(
&
lower
->
header
);
if
(
slot
>
nritems
)
if
(
slot
>
nritems
)
BUG
();
BUG
();
if
(
nritems
==
NODEPTRS_PER_BLOCK
)
if
(
nritems
==
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
)
BUG
();
BUG
();
if
(
slot
!=
nritems
)
{
if
(
slot
!=
nritems
)
{
memmove
(
lower
->
keys
+
slot
+
1
,
lower
->
keys
+
slot
,
memmove
(
lower
->
ptrs
+
slot
+
1
,
lower
->
ptrs
+
slot
,
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_disk_key
));
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_key_ptr
));
memmove
(
lower
->
blockptrs
+
slot
+
1
,
lower
->
blockptrs
+
slot
,
(
nritems
-
slot
)
*
sizeof
(
u64
));
}
}
memcpy
(
lower
->
keys
+
slot
,
key
,
sizeof
(
struct
btrfs_disk_key
));
memcpy
(
&
lower
->
ptrs
[
slot
].
key
,
key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_set_node_blockptr
(
lower
,
slot
,
blocknr
);
btrfs_set_node_blockptr
(
lower
,
slot
,
blocknr
);
btrfs_set_header_nritems
(
&
lower
->
header
,
nritems
+
1
);
btrfs_set_header_nritems
(
&
lower
->
header
,
nritems
+
1
);
if
(
lower
->
keys
[
1
].
objectid
==
0
)
BUG
();
BUG_ON
(
list_empty
(
&
path
->
nodes
[
level
]
->
dirty
));
BUG_ON
(
list_empty
(
&
path
->
nodes
[
level
]
->
dirty
));
return
0
;
return
0
;
}
}
...
@@ -747,17 +741,16 @@ static int split_node(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -747,17 +741,16 @@ static int split_node(struct btrfs_root *root, struct btrfs_path *path,
btrfs_set_header_parentid
(
&
split
->
header
,
btrfs_set_header_parentid
(
&
split
->
header
,
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
));
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
));
mid
=
(
c_nritems
+
1
)
/
2
;
mid
=
(
c_nritems
+
1
)
/
2
;
memcpy
(
split
->
keys
,
c
->
keys
+
mid
,
memcpy
(
split
->
ptrs
,
c
->
ptrs
+
mid
,
(
c_nritems
-
mid
)
*
sizeof
(
struct
btrfs_disk_key
));
(
c_nritems
-
mid
)
*
sizeof
(
struct
btrfs_key_ptr
));
memcpy
(
split
->
blockptrs
,
c
->
blockptrs
+
mid
,
(
c_nritems
-
mid
)
*
sizeof
(
u64
));
btrfs_set_header_nritems
(
&
split
->
header
,
c_nritems
-
mid
);
btrfs_set_header_nritems
(
&
split
->
header
,
c_nritems
-
mid
);
btrfs_set_header_nritems
(
&
c
->
header
,
mid
);
btrfs_set_header_nritems
(
&
c
->
header
,
mid
);
ret
=
0
;
ret
=
0
;
BUG_ON
(
list_empty
(
&
t
->
dirty
));
BUG_ON
(
list_empty
(
&
t
->
dirty
));
wret
=
insert_ptr
(
root
,
path
,
split
->
keys
,
split_buffer
->
blocknr
,
wret
=
insert_ptr
(
root
,
path
,
&
split
->
ptrs
[
0
].
key
,
path
->
slots
[
level
+
1
]
+
1
,
level
+
1
);
split_buffer
->
blocknr
,
path
->
slots
[
level
+
1
]
+
1
,
level
+
1
);
if
(
wret
)
if
(
wret
)
ret
=
wret
;
ret
=
wret
;
...
@@ -825,7 +818,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -825,7 +818,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
right_buf
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
&
upper
->
node
,
right_buf
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
&
upper
->
node
,
slot
+
1
));
slot
+
1
));
right
=
&
right_buf
->
leaf
;
right
=
&
right_buf
->
leaf
;
free_space
=
btrfs_leaf_free_space
(
right
);
free_space
=
btrfs_leaf_free_space
(
r
oot
,
r
ight
);
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
btrfs_block_release
(
root
,
right_buf
);
btrfs_block_release
(
root
,
right_buf
);
return
1
;
return
1
;
...
@@ -833,7 +826,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -833,7 +826,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
/* cow and double check */
/* cow and double check */
btrfs_cow_block
(
root
,
right_buf
,
upper
,
slot
+
1
,
&
right_buf
);
btrfs_cow_block
(
root
,
right_buf
,
upper
,
slot
+
1
,
&
right_buf
);
right
=
&
right_buf
->
leaf
;
right
=
&
right_buf
->
leaf
;
free_space
=
btrfs_leaf_free_space
(
right
);
free_space
=
btrfs_leaf_free_space
(
r
oot
,
r
ight
);
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
btrfs_block_release
(
root
,
right_buf
);
btrfs_block_release
(
root
,
right_buf
);
return
1
;
return
1
;
...
@@ -857,15 +850,14 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -857,15 +850,14 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
right_nritems
=
btrfs_header_nritems
(
&
right
->
header
);
right_nritems
=
btrfs_header_nritems
(
&
right
->
header
);
/* push left to right */
/* push left to right */
push_space
=
btrfs_item_end
(
left
->
items
+
left_nritems
-
push_items
);
push_space
=
btrfs_item_end
(
left
->
items
+
left_nritems
-
push_items
);
push_space
-=
leaf_data_end
(
left
);
push_space
-=
leaf_data_end
(
root
,
left
);
/* make room in the right data area */
/* make room in the right data area */
memmove
(
right
->
data
+
leaf_data_end
(
right
)
-
push_space
,
memmove
(
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
)
-
right
->
data
+
leaf_data_end
(
right
),
push_space
,
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
),
LEAF_DATA_SIZE
-
leaf_data_end
(
right
));
BTRFS_LEAF_DATA_SIZE
(
root
)
-
leaf_data_end
(
root
,
right
));
/* copy from the left data area */
/* copy from the left data area */
memcpy
(
right
->
data
+
LEAF_DATA_SIZE
-
push_space
,
memcpy
(
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
push_space
,
left
->
data
+
leaf_data_end
(
left
),
btrfs_leaf_data
(
left
)
+
leaf_data_end
(
root
,
left
),
push_space
);
push_space
);
memmove
(
right
->
items
+
push_items
,
right
->
items
,
memmove
(
right
->
items
+
push_items
,
right
->
items
,
right_nritems
*
sizeof
(
struct
btrfs_item
));
right_nritems
*
sizeof
(
struct
btrfs_item
));
/* copy the items from left to right */
/* copy the items from left to right */
...
@@ -875,7 +867,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -875,7 +867,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
/* update the item pointers */
/* update the item pointers */
right_nritems
+=
push_items
;
right_nritems
+=
push_items
;
btrfs_set_header_nritems
(
&
right
->
header
,
right_nritems
);
btrfs_set_header_nritems
(
&
right
->
header
,
right_nritems
);
push_space
=
LEAF_DATA_SIZE
;
push_space
=
BTRFS_LEAF_DATA_SIZE
(
root
)
;
for
(
i
=
0
;
i
<
right_nritems
;
i
++
)
{
for
(
i
=
0
;
i
<
right_nritems
;
i
++
)
{
btrfs_set_item_offset
(
right
->
items
+
i
,
push_space
-
btrfs_set_item_offset
(
right
->
items
+
i
,
push_space
-
btrfs_item_size
(
right
->
items
+
i
));
btrfs_item_size
(
right
->
items
+
i
));
...
@@ -886,7 +878,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -886,7 +878,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
BUG_ON
(
list_empty
(
&
left_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
left_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
right_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
right_buf
->
dirty
));
memcpy
(
upper
->
node
.
keys
+
slot
+
1
,
memcpy
(
&
upper
->
node
.
ptrs
[
slot
+
1
].
key
,
&
right
->
items
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
&
right
->
items
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
BUG_ON
(
list_empty
(
&
upper
->
dirty
));
BUG_ON
(
list_empty
(
&
upper
->
dirty
));
...
@@ -932,7 +924,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -932,7 +924,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
t
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
&
path
->
nodes
[
1
]
->
node
,
t
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
&
path
->
nodes
[
1
]
->
node
,
slot
-
1
));
slot
-
1
));
left
=
&
t
->
leaf
;
left
=
&
t
->
leaf
;
free_space
=
btrfs_leaf_free_space
(
left
);
free_space
=
btrfs_leaf_free_space
(
root
,
left
);
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
btrfs_block_release
(
root
,
t
);
btrfs_block_release
(
root
,
t
);
return
1
;
return
1
;
...
@@ -941,7 +933,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -941,7 +933,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
/* cow and double check */
/* cow and double check */
btrfs_cow_block
(
root
,
t
,
path
->
nodes
[
1
],
slot
-
1
,
&
t
);
btrfs_cow_block
(
root
,
t
,
path
->
nodes
[
1
],
slot
-
1
,
&
t
);
left
=
&
t
->
leaf
;
left
=
&
t
->
leaf
;
free_space
=
btrfs_leaf_free_space
(
left
);
free_space
=
btrfs_leaf_free_space
(
root
,
left
);
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
btrfs_block_release
(
root
,
t
);
btrfs_block_release
(
root
,
t
);
return
1
;
return
1
;
...
@@ -964,17 +956,19 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -964,17 +956,19 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
/* push data from right to left */
/* push data from right to left */
memcpy
(
left
->
items
+
btrfs_header_nritems
(
&
left
->
header
),
memcpy
(
left
->
items
+
btrfs_header_nritems
(
&
left
->
header
),
right
->
items
,
push_items
*
sizeof
(
struct
btrfs_item
));
right
->
items
,
push_items
*
sizeof
(
struct
btrfs_item
));
push_space
=
LEAF_DATA_SIZE
-
push_space
=
BTRFS_LEAF_DATA_SIZE
(
root
)
-
btrfs_item_offset
(
right
->
items
+
push_items
-
1
);
btrfs_item_offset
(
right
->
items
+
push_items
-
1
);
memcpy
(
left
->
data
+
leaf_data_end
(
left
)
-
push_space
,
memcpy
(
btrfs_leaf_data
(
left
)
+
leaf_data_end
(
root
,
left
)
-
push_space
,
right
->
data
+
btrfs_item_offset
(
right
->
items
+
push_items
-
1
),
btrfs_leaf_data
(
right
)
+
btrfs_item_offset
(
right
->
items
+
push_items
-
1
),
push_space
);
push_space
);
old_left_nritems
=
btrfs_header_nritems
(
&
left
->
header
);
old_left_nritems
=
btrfs_header_nritems
(
&
left
->
header
);
BUG_ON
(
old_left_nritems
<
0
);
BUG_ON
(
old_left_nritems
<
0
);
for
(
i
=
old_left_nritems
;
i
<
old_left_nritems
+
push_items
;
i
++
)
{
for
(
i
=
old_left_nritems
;
i
<
old_left_nritems
+
push_items
;
i
++
)
{
u16
ioff
=
btrfs_item_offset
(
left
->
items
+
i
);
u32
ioff
=
btrfs_item_offset
(
left
->
items
+
i
);
btrfs_set_item_offset
(
left
->
items
+
i
,
ioff
-
(
LEAF_DATA_SIZE
-
btrfs_set_item_offset
(
left
->
items
+
i
,
ioff
-
(
BTRFS_LEAF_DATA_SIZE
(
root
)
-
btrfs_item_offset
(
left
->
items
+
btrfs_item_offset
(
left
->
items
+
old_left_nritems
-
1
)));
old_left_nritems
-
1
)));
}
}
...
@@ -982,16 +976,17 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -982,16 +976,17 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
/* fixup right node */
/* fixup right node */
push_space
=
btrfs_item_offset
(
right
->
items
+
push_items
-
1
)
-
push_space
=
btrfs_item_offset
(
right
->
items
+
push_items
-
1
)
-
leaf_data_end
(
right
);
leaf_data_end
(
root
,
right
);
memmove
(
right
->
data
+
LEAF_DATA_SIZE
-
push_space
,
right
->
data
+
memmove
(
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
leaf_data_end
(
right
),
push_space
);
push_space
,
btrfs_leaf_data
(
right
)
+
leaf_data_end
(
root
,
right
),
push_space
);
memmove
(
right
->
items
,
right
->
items
+
push_items
,
memmove
(
right
->
items
,
right
->
items
+
push_items
,
(
btrfs_header_nritems
(
&
right
->
header
)
-
push_items
)
*
(
btrfs_header_nritems
(
&
right
->
header
)
-
push_items
)
*
sizeof
(
struct
btrfs_item
));
sizeof
(
struct
btrfs_item
));
btrfs_set_header_nritems
(
&
right
->
header
,
btrfs_set_header_nritems
(
&
right
->
header
,
btrfs_header_nritems
(
&
right
->
header
)
-
btrfs_header_nritems
(
&
right
->
header
)
-
push_items
);
push_items
);
push_space
=
LEAF_DATA_SIZE
;
push_space
=
BTRFS_LEAF_DATA_SIZE
(
root
)
;
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
);
i
++
)
{
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
);
i
++
)
{
btrfs_set_item_offset
(
right
->
items
+
i
,
push_space
-
btrfs_set_item_offset
(
right
->
items
+
i
,
push_space
-
...
@@ -1051,12 +1046,12 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -1051,12 +1046,12 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
if
(
wret
<
0
)
if
(
wret
<
0
)
return
wret
;
return
wret
;
}
}
l_buf
=
path
->
nodes
[
0
];
l_buf
=
path
->
nodes
[
0
];
l
=
&
l_buf
->
leaf
;
l
=
&
l_buf
->
leaf
;
/* did the pushes work? */
/* did the pushes work? */
if
(
btrfs_leaf_free_space
(
l
)
>=
sizeof
(
struct
btrfs_item
)
+
data_size
)
if
(
btrfs_leaf_free_space
(
root
,
l
)
>=
sizeof
(
struct
btrfs_item
)
+
data_size
)
return
0
;
return
0
;
if
(
!
path
->
nodes
[
1
])
{
if
(
!
path
->
nodes
[
1
])
{
...
@@ -1071,16 +1066,16 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -1071,16 +1066,16 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
BUG_ON
(
!
right_buffer
);
BUG_ON
(
!
right_buffer
);
BUG_ON
(
mid
==
nritems
);
BUG_ON
(
mid
==
nritems
);
right
=
&
right_buffer
->
leaf
;
right
=
&
right_buffer
->
leaf
;
memset
(
right
,
0
,
sizeof
(
*
right
));
memset
(
&
right
->
header
,
0
,
sizeof
(
right
->
header
));
if
(
mid
<=
slot
)
{
if
(
mid
<=
slot
)
{
/* FIXME, just alloc a new leaf here */
/* FIXME, just alloc a new leaf here */
if
(
leaf_space_used
(
l
,
mid
,
nritems
-
mid
)
+
space_needed
>
if
(
leaf_space_used
(
l
,
mid
,
nritems
-
mid
)
+
space_needed
>
LEAF_DATA_SIZE
)
BTRFS_LEAF_DATA_SIZE
(
root
)
)
BUG
();
BUG
();
}
else
{
}
else
{
/* FIXME, just alloc a new leaf here */
/* FIXME, just alloc a new leaf here */
if
(
leaf_space_used
(
l
,
0
,
mid
+
1
)
+
space_needed
>
if
(
leaf_space_used
(
l
,
0
,
mid
+
1
)
+
space_needed
>
LEAF_DATA_SIZE
)
BTRFS_LEAF_DATA_SIZE
(
root
)
)
BUG
();
BUG
();
}
}
btrfs_set_header_nritems
(
&
right
->
header
,
nritems
-
mid
);
btrfs_set_header_nritems
(
&
right
->
header
,
nritems
-
mid
);
...
@@ -1088,15 +1083,18 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
...
@@ -1088,15 +1083,18 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
btrfs_set_header_level
(
&
right
->
header
,
0
);
btrfs_set_header_level
(
&
right
->
header
,
0
);
btrfs_set_header_parentid
(
&
right
->
header
,
btrfs_set_header_parentid
(
&
right
->
header
,
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
));
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
));
data_copy_size
=
btrfs_item_end
(
l
->
items
+
mid
)
-
leaf_data_end
(
l
);
data_copy_size
=
btrfs_item_end
(
l
->
items
+
mid
)
-
leaf_data_end
(
root
,
l
);
memcpy
(
right
->
items
,
l
->
items
+
mid
,
memcpy
(
right
->
items
,
l
->
items
+
mid
,
(
nritems
-
mid
)
*
sizeof
(
struct
btrfs_item
));
(
nritems
-
mid
)
*
sizeof
(
struct
btrfs_item
));
memcpy
(
right
->
data
+
LEAF_DATA_SIZE
-
data_copy_size
,
memcpy
(
btrfs_leaf_data
(
right
)
+
BTRFS_LEAF_DATA_SIZE
(
root
)
-
l
->
data
+
leaf_data_end
(
l
),
data_copy_size
);
data_copy_size
,
btrfs_leaf_data
(
l
)
+
rt_data_off
=
LEAF_DATA_SIZE
-
btrfs_item_end
(
l
->
items
+
mid
);
leaf_data_end
(
root
,
l
),
data_copy_size
);
rt_data_off
=
BTRFS_LEAF_DATA_SIZE
(
root
)
-
btrfs_item_end
(
l
->
items
+
mid
);
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
);
i
++
)
{
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
);
i
++
)
{
u
16
ioff
=
btrfs_item_offset
(
right
->
items
+
i
);
u
32
ioff
=
btrfs_item_offset
(
right
->
items
+
i
);
btrfs_set_item_offset
(
right
->
items
+
i
,
ioff
+
rt_data_off
);
btrfs_set_item_offset
(
right
->
items
+
i
,
ioff
+
rt_data_off
);
}
}
...
@@ -1156,9 +1154,9 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
...
@@ -1156,9 +1154,9 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
leaf
=
&
leaf_buf
->
leaf
;
leaf
=
&
leaf_buf
->
leaf
;
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
data_end
=
leaf_data_end
(
leaf
);
data_end
=
leaf_data_end
(
root
,
leaf
);
if
(
btrfs_leaf_free_space
(
leaf
)
<
if
(
btrfs_leaf_free_space
(
root
,
leaf
)
<
sizeof
(
struct
btrfs_item
)
+
data_size
)
sizeof
(
struct
btrfs_item
)
+
data_size
)
BUG
();
BUG
();
...
@@ -1173,7 +1171,7 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
...
@@ -1173,7 +1171,7 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
*/
*/
/* first correct the data pointers */
/* first correct the data pointers */
for
(
i
=
slot
;
i
<
nritems
;
i
++
)
{
for
(
i
=
slot
;
i
<
nritems
;
i
++
)
{
u
16
ioff
=
btrfs_item_offset
(
leaf
->
items
+
i
);
u
32
ioff
=
btrfs_item_offset
(
leaf
->
items
+
i
);
btrfs_set_item_offset
(
leaf
->
items
+
i
,
btrfs_set_item_offset
(
leaf
->
items
+
i
,
ioff
-
data_size
);
ioff
-
data_size
);
}
}
...
@@ -1183,7 +1181,8 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
...
@@ -1183,7 +1181,8 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_item
));
(
nritems
-
slot
)
*
sizeof
(
struct
btrfs_item
));
/* shift the data */
/* shift the data */
memmove
(
leaf
->
data
+
data_end
-
data_size
,
leaf
->
data
+
memmove
(
btrfs_leaf_data
(
leaf
)
+
data_end
-
data_size
,
btrfs_leaf_data
(
leaf
)
+
data_end
,
old_data
-
data_end
);
data_end
,
old_data
-
data_end
);
data_end
=
old_data
;
data_end
=
old_data
;
}
}
...
@@ -1192,7 +1191,7 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
...
@@ -1192,7 +1191,7 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
sizeof
(
struct
btrfs_disk_key
));
sizeof
(
struct
btrfs_disk_key
));
btrfs_set_item_offset
(
leaf
->
items
+
slot
,
data_end
-
data_size
);
btrfs_set_item_offset
(
leaf
->
items
+
slot
,
data_end
-
data_size
);
btrfs_set_item_size
(
leaf
->
items
+
slot
,
data_size
);
btrfs_set_item_size
(
leaf
->
items
+
slot
,
data_size
);
memcpy
(
leaf
->
data
+
data_end
-
data_size
,
data
,
data_size
);
memcpy
(
btrfs_leaf_data
(
leaf
)
+
data_end
-
data_size
,
data
,
data_size
);
btrfs_set_header_nritems
(
&
leaf
->
header
,
nritems
+
1
);
btrfs_set_header_nritems
(
&
leaf
->
header
,
nritems
+
1
);
ret
=
0
;
ret
=
0
;
...
@@ -1200,9 +1199,9 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
...
@@ -1200,9 +1199,9 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
ret
=
fixup_low_keys
(
root
,
&
path
,
&
disk_key
,
1
);
ret
=
fixup_low_keys
(
root
,
&
path
,
&
disk_key
,
1
);
BUG_ON
(
list_empty
(
&
leaf_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
leaf_buf
->
dirty
));
if
(
btrfs_leaf_free_space
(
leaf
)
<
0
)
if
(
btrfs_leaf_free_space
(
root
,
leaf
)
<
0
)
BUG
();
BUG
();
check_leaf
(
&
path
,
0
);
check_leaf
(
root
,
&
path
,
0
);
out:
out:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
return
ret
;
return
ret
;
...
@@ -1227,11 +1226,8 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
...
@@ -1227,11 +1226,8 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
node
=
&
parent
->
node
;
node
=
&
parent
->
node
;
nritems
=
btrfs_header_nritems
(
&
node
->
header
);
nritems
=
btrfs_header_nritems
(
&
node
->
header
);
if
(
slot
!=
nritems
-
1
)
{
if
(
slot
!=
nritems
-
1
)
{
memmove
(
node
->
keys
+
slot
,
node
->
keys
+
slot
+
1
,
memmove
(
node
->
ptrs
+
slot
,
node
->
ptrs
+
slot
+
1
,
sizeof
(
struct
btrfs_disk_key
)
*
(
nritems
-
slot
-
1
));
sizeof
(
struct
btrfs_key_ptr
)
*
(
nritems
-
slot
-
1
));
memmove
(
node
->
blockptrs
+
slot
,
node
->
blockptrs
+
slot
+
1
,
sizeof
(
u64
)
*
(
nritems
-
slot
-
1
));
}
}
nritems
--
;
nritems
--
;
btrfs_set_header_nritems
(
&
node
->
header
,
nritems
);
btrfs_set_header_nritems
(
&
node
->
header
,
nritems
);
...
@@ -1240,7 +1236,8 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
...
@@ -1240,7 +1236,8 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
/* just turn the root into a leaf and break */
/* just turn the root into a leaf and break */
btrfs_set_header_level
(
&
root
->
node
->
node
.
header
,
0
);
btrfs_set_header_level
(
&
root
->
node
->
node
.
header
,
0
);
}
else
if
(
slot
==
0
)
{
}
else
if
(
slot
==
0
)
{
wret
=
fixup_low_keys
(
root
,
path
,
node
->
keys
,
level
+
1
);
wret
=
fixup_low_keys
(
root
,
path
,
&
node
->
ptrs
[
0
].
key
,
level
+
1
);
if
(
wret
)
if
(
wret
)
ret
=
wret
;
ret
=
wret
;
}
}
...
@@ -1272,12 +1269,12 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
...
@@ -1272,12 +1269,12 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
if
(
slot
!=
nritems
-
1
)
{
if
(
slot
!=
nritems
-
1
)
{
int
i
;
int
i
;
int
data_end
=
leaf_data_end
(
leaf
);
int
data_end
=
leaf_data_end
(
root
,
leaf
);
memmove
(
leaf
->
data
+
data_end
+
dsize
,
memmove
(
btrfs_leaf_data
(
leaf
)
+
data_end
+
dsize
,
leaf
->
data
+
data_end
,
btrfs_leaf_data
(
leaf
)
+
data_end
,
doff
-
data_end
);
doff
-
data_end
);
for
(
i
=
slot
+
1
;
i
<
nritems
;
i
++
)
{
for
(
i
=
slot
+
1
;
i
<
nritems
;
i
++
)
{
u
16
ioff
=
btrfs_item_offset
(
leaf
->
items
+
i
);
u
32
ioff
=
btrfs_item_offset
(
leaf
->
items
+
i
);
btrfs_set_item_offset
(
leaf
->
items
+
i
,
ioff
+
dsize
);
btrfs_set_item_offset
(
leaf
->
items
+
i
,
ioff
+
dsize
);
}
}
memmove
(
leaf
->
items
+
slot
,
leaf
->
items
+
slot
+
1
,
memmove
(
leaf
->
items
+
slot
,
leaf
->
items
+
slot
+
1
,
...
@@ -1311,7 +1308,7 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
...
@@ -1311,7 +1308,7 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
BUG_ON
(
list_empty
(
&
leaf_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
leaf_buf
->
dirty
));
/* delete the leaf if it is mostly empty */
/* delete the leaf if it is mostly empty */
if
(
used
<
LEAF_DATA_SIZE
/
3
)
{
if
(
used
<
BTRFS_LEAF_DATA_SIZE
(
root
)
/
3
)
{
/* push_leaf_left fixes the path.
/* push_leaf_left fixes the path.
* make sure the path still points to our leaf
* make sure the path still points to our leaf
* for possible call to del_ptr below
* for possible call to del_ptr below
...
...
fs/btrfs/ctree.h
View file @
123abc88
...
@@ -5,7 +5,6 @@
...
@@ -5,7 +5,6 @@
#include "kerncompat.h"
#include "kerncompat.h"
#define BTRFS_MAGIC "_BtRfS_M"
#define BTRFS_MAGIC "_BtRfS_M"
#define BTRFS_BLOCKSIZE 1024
#define BTRFS_ROOT_TREE_OBJECTID 1
#define BTRFS_ROOT_TREE_OBJECTID 1
#define BTRFS_EXTENT_TREE_OBJECTID 2
#define BTRFS_EXTENT_TREE_OBJECTID 2
...
@@ -52,8 +51,11 @@ struct btrfs_header {
...
@@ -52,8 +51,11 @@ struct btrfs_header {
}
__attribute__
((
__packed__
));
}
__attribute__
((
__packed__
));
#define BTRFS_MAX_LEVEL 8
#define BTRFS_MAX_LEVEL 8
#define NODEPTRS_PER_BLOCK ((BTRFS_BLOCKSIZE - sizeof(struct btrfs_header)) / \
#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->blocksize - \
sizeof(struct btrfs_header)) / \
(sizeof(struct btrfs_disk_key) + sizeof(u64)))
(sizeof(struct btrfs_disk_key) + sizeof(u64)))
#define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header))
#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->blocksize))
struct
btrfs_buffer
;
struct
btrfs_buffer
;
...
@@ -86,6 +88,7 @@ struct btrfs_root {
...
@@ -86,6 +88,7 @@ struct btrfs_root {
int
ref_cows
;
int
ref_cows
;
struct
btrfs_root_item
root_item
;
struct
btrfs_root_item
root_item
;
struct
btrfs_key
root_key
;
struct
btrfs_key
root_key
;
u32
blocksize
;
};
};
/*
/*
...
@@ -97,7 +100,7 @@ struct btrfs_super_block {
...
@@ -97,7 +100,7 @@ struct btrfs_super_block {
__le64
blocknr
;
/* this block number */
__le64
blocknr
;
/* this block number */
__le32
csum
;
__le32
csum
;
__le64
magic
;
__le64
magic
;
__le
16
blocksize
;
__le
32
blocksize
;
__le64
generation
;
__le64
generation
;
__le64
root
;
__le64
root
;
__le64
total_blocks
;
__le64
total_blocks
;
...
@@ -111,7 +114,7 @@ struct btrfs_super_block {
...
@@ -111,7 +114,7 @@ struct btrfs_super_block {
*/
*/
struct
btrfs_item
{
struct
btrfs_item
{
struct
btrfs_disk_key
key
;
struct
btrfs_disk_key
key
;
__le
16
offset
;
__le
32
offset
;
__le16
size
;
__le16
size
;
}
__attribute__
((
__packed__
));
}
__attribute__
((
__packed__
));
...
@@ -122,24 +125,23 @@ struct btrfs_item {
...
@@ -122,24 +125,23 @@ struct btrfs_item {
* The data is separate from the items to get the keys closer together
* The data is separate from the items to get the keys closer together
* during searches.
* during searches.
*/
*/
#define LEAF_DATA_SIZE (BTRFS_BLOCKSIZE - sizeof(struct btrfs_header))
struct
btrfs_leaf
{
struct
btrfs_leaf
{
struct
btrfs_header
header
;
struct
btrfs_header
header
;
union
{
struct
btrfs_item
items
[];
struct
btrfs_item
items
[
LEAF_DATA_SIZE
/
sizeof
(
struct
btrfs_item
)];
u8
data
[
BTRFS_BLOCKSIZE
-
sizeof
(
struct
btrfs_header
)];
};
}
__attribute__
((
__packed__
));
}
__attribute__
((
__packed__
));
/*
/*
* all non-leaf blocks are nodes, they hold only keys and pointers to
* all non-leaf blocks are nodes, they hold only keys and pointers to
* other blocks
* other blocks
*/
*/
struct
btrfs_key_ptr
{
struct
btrfs_disk_key
key
;
__le64
blockptr
;
}
__attribute__
((
__packed__
));
struct
btrfs_node
{
struct
btrfs_node
{
struct
btrfs_header
header
;
struct
btrfs_header
header
;
struct
btrfs_disk_key
keys
[
NODEPTRS_PER_BLOCK
];
struct
btrfs_key_ptr
ptrs
[];
__le64
blockptrs
[
NODEPTRS_PER_BLOCK
];
}
__attribute__
((
__packed__
));
}
__attribute__
((
__packed__
));
/*
/*
...
@@ -186,28 +188,28 @@ static inline void btrfs_set_extent_refs(struct btrfs_extent_item *ei, u32 val)
...
@@ -186,28 +188,28 @@ static inline void btrfs_set_extent_refs(struct btrfs_extent_item *ei, u32 val)
static
inline
u64
btrfs_node_blockptr
(
struct
btrfs_node
*
n
,
int
nr
)
static
inline
u64
btrfs_node_blockptr
(
struct
btrfs_node
*
n
,
int
nr
)
{
{
return
le64_to_cpu
(
n
->
blockptrs
[
nr
]
);
return
le64_to_cpu
(
n
->
ptrs
[
nr
].
blockptr
);
}
}
static
inline
void
btrfs_set_node_blockptr
(
struct
btrfs_node
*
n
,
int
nr
,
static
inline
void
btrfs_set_node_blockptr
(
struct
btrfs_node
*
n
,
int
nr
,
u64
val
)
u64
val
)
{
{
n
->
blockptrs
[
nr
]
=
cpu_to_le64
(
val
);
n
->
ptrs
[
nr
].
blockptr
=
cpu_to_le64
(
val
);
}
}
static
inline
u
16
btrfs_item_offset
(
struct
btrfs_item
*
item
)
static
inline
u
32
btrfs_item_offset
(
struct
btrfs_item
*
item
)
{
{
return
le
16
_to_cpu
(
item
->
offset
);
return
le
32
_to_cpu
(
item
->
offset
);
}
}
static
inline
void
btrfs_set_item_offset
(
struct
btrfs_item
*
item
,
u
16
val
)
static
inline
void
btrfs_set_item_offset
(
struct
btrfs_item
*
item
,
u
32
val
)
{
{
item
->
offset
=
cpu_to_le
16
(
val
);
item
->
offset
=
cpu_to_le
32
(
val
);
}
}
static
inline
u
16
btrfs_item_end
(
struct
btrfs_item
*
item
)
static
inline
u
32
btrfs_item_end
(
struct
btrfs_item
*
item
)
{
{
return
le
16
_to_cpu
(
item
->
offset
)
+
le16_to_cpu
(
item
->
size
);
return
le
32
_to_cpu
(
item
->
offset
)
+
le16_to_cpu
(
item
->
size
);
}
}
static
inline
u16
btrfs_item_size
(
struct
btrfs_item
*
item
)
static
inline
u16
btrfs_item_size
(
struct
btrfs_item
*
item
)
...
@@ -390,20 +392,26 @@ static inline void btrfs_set_super_blocks_used(struct btrfs_super_block *s,
...
@@ -390,20 +392,26 @@ static inline void btrfs_set_super_blocks_used(struct btrfs_super_block *s,
s
->
blocks_used
=
cpu_to_le64
(
val
);
s
->
blocks_used
=
cpu_to_le64
(
val
);
}
}
static
inline
u
16
btrfs_super_blocksize
(
struct
btrfs_super_block
*
s
)
static
inline
u
32
btrfs_super_blocksize
(
struct
btrfs_super_block
*
s
)
{
{
return
le
16
_to_cpu
(
s
->
blocksize
);
return
le
32
_to_cpu
(
s
->
blocksize
);
}
}
static
inline
void
btrfs_set_super_blocksize
(
struct
btrfs_super_block
*
s
,
static
inline
void
btrfs_set_super_blocksize
(
struct
btrfs_super_block
*
s
,
u16
val
)
u32
val
)
{
s
->
blocksize
=
cpu_to_le32
(
val
);
}
static
inline
u8
*
btrfs_leaf_data
(
struct
btrfs_leaf
*
l
)
{
{
s
->
blocksize
=
cpu_to_le16
(
val
)
;
return
(
u8
*
)
l
->
items
;
}
}
/* helper function to cast into the data area of the leaf. */
/* helper function to cast into the data area of the leaf. */
#define btrfs_item_ptr(leaf, slot, type) \
#define btrfs_item_ptr(leaf, slot, type) \
((type *)((leaf)->data + btrfs_item_offset((leaf)->items + (slot))))
((type *)(btrfs_leaf_data(leaf) + \
btrfs_item_offset((leaf)->items + (slot))))
struct
btrfs_buffer
*
btrfs_alloc_free_block
(
struct
btrfs_root
*
root
);
struct
btrfs_buffer
*
btrfs_alloc_free_block
(
struct
btrfs_root
*
root
);
int
btrfs_inc_ref
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
buf
);
int
btrfs_inc_ref
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
buf
);
...
@@ -416,7 +424,7 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path);
...
@@ -416,7 +424,7 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path);
int
btrfs_insert_item
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
key
,
int
btrfs_insert_item
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
key
,
void
*
data
,
int
data_size
);
void
*
data
,
int
data_size
);
int
btrfs_next_leaf
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
);
int
btrfs_next_leaf
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
);
int
btrfs_leaf_free_space
(
struct
btrfs_leaf
*
leaf
);
int
btrfs_leaf_free_space
(
struct
btrfs_
root
*
root
,
struct
btrfs_
leaf
*
leaf
);
int
btrfs_drop_snapshot
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
snap
);
int
btrfs_drop_snapshot
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
snap
);
int
btrfs_finish_extent_commit
(
struct
btrfs_root
*
root
);
int
btrfs_finish_extent_commit
(
struct
btrfs_root
*
root
);
int
btrfs_del_root
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
key
);
int
btrfs_del_root
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
key
);
...
...
fs/btrfs/disk-io.c
View file @
123abc88
...
@@ -46,7 +46,8 @@ struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
...
@@ -46,7 +46,8 @@ struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
{
{
struct
btrfs_buffer
*
buf
;
struct
btrfs_buffer
*
buf
;
int
ret
;
int
ret
;
buf
=
malloc
(
sizeof
(
struct
btrfs_buffer
));
buf
=
malloc
(
sizeof
(
struct
btrfs_buffer
)
+
root
->
blocksize
);
if
(
!
buf
)
if
(
!
buf
)
return
buf
;
return
buf
;
allocated_blocks
++
;
allocated_blocks
++
;
...
@@ -84,7 +85,7 @@ struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr)
...
@@ -84,7 +85,7 @@ struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr)
struct
btrfs_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
)
struct
btrfs_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
)
{
{
loff_t
offset
=
blocknr
*
BTRFS_BLOCKSIZE
;
loff_t
offset
=
blocknr
*
root
->
blocksize
;
struct
btrfs_buffer
*
buf
;
struct
btrfs_buffer
*
buf
;
int
ret
;
int
ret
;
...
@@ -95,8 +96,8 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
...
@@ -95,8 +96,8 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
buf
=
alloc_tree_block
(
root
,
blocknr
);
buf
=
alloc_tree_block
(
root
,
blocknr
);
if
(
!
buf
)
if
(
!
buf
)
return
NULL
;
return
NULL
;
ret
=
pread
(
root
->
fp
,
&
buf
->
node
,
BTRFS_BLOCKSIZE
,
offset
);
ret
=
pread
(
root
->
fp
,
&
buf
->
node
,
root
->
blocksize
,
offset
);
if
(
ret
!=
BTRFS_BLOCKSIZE
)
{
if
(
ret
!=
root
->
blocksize
)
{
free
(
buf
);
free
(
buf
);
return
NULL
;
return
NULL
;
}
}
...
@@ -127,13 +128,13 @@ int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
...
@@ -127,13 +128,13 @@ int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
int
write_tree_block
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
buf
)
int
write_tree_block
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
buf
)
{
{
u64
blocknr
=
buf
->
blocknr
;
u64
blocknr
=
buf
->
blocknr
;
loff_t
offset
=
blocknr
*
BTRFS_BLOCKSIZE
;
loff_t
offset
=
blocknr
*
root
->
blocksize
;
int
ret
;
int
ret
;
if
(
buf
->
blocknr
!=
btrfs_header_blocknr
(
&
buf
->
node
.
header
))
if
(
buf
->
blocknr
!=
btrfs_header_blocknr
(
&
buf
->
node
.
header
))
BUG
();
BUG
();
ret
=
pwrite
(
root
->
fp
,
&
buf
->
node
,
BTRFS_BLOCKSIZE
,
offset
);
ret
=
pwrite
(
root
->
fp
,
&
buf
->
node
,
root
->
blocksize
,
offset
);
if
(
ret
!=
BTRFS_BLOCKSIZE
)
if
(
ret
!=
root
->
blocksize
)
return
ret
;
return
ret
;
return
0
;
return
0
;
}
}
...
@@ -215,7 +216,8 @@ int btrfs_commit_transaction(struct btrfs_root *root,
...
@@ -215,7 +216,8 @@ int btrfs_commit_transaction(struct btrfs_root *root,
return
ret
;
return
ret
;
}
}
static
int
__setup_root
(
struct
btrfs_root
*
root
,
u64
objectid
,
int
fp
)
static
int
__setup_root
(
struct
btrfs_super_block
*
super
,
struct
btrfs_root
*
root
,
u64
objectid
,
int
fp
)
{
{
INIT_LIST_HEAD
(
&
root
->
trans
);
INIT_LIST_HEAD
(
&
root
->
trans
);
INIT_LIST_HEAD
(
&
root
->
cache
);
INIT_LIST_HEAD
(
&
root
->
cache
);
...
@@ -223,6 +225,8 @@ static int __setup_root(struct btrfs_root *root, u64 objectid, int fp)
...
@@ -223,6 +225,8 @@ static int __setup_root(struct btrfs_root *root, u64 objectid, int fp)
root
->
fp
=
fp
;
root
->
fp
=
fp
;
root
->
node
=
NULL
;
root
->
node
=
NULL
;
root
->
commit_root
=
NULL
;
root
->
commit_root
=
NULL
;
root
->
blocksize
=
btrfs_super_blocksize
(
super
);
root
->
ref_cows
=
0
;
memset
(
&
root
->
current_insert
,
0
,
sizeof
(
root
->
current_insert
));
memset
(
&
root
->
current_insert
,
0
,
sizeof
(
root
->
current_insert
));
memset
(
&
root
->
last_insert
,
0
,
sizeof
(
root
->
last_insert
));
memset
(
&
root
->
last_insert
,
0
,
sizeof
(
root
->
last_insert
));
memset
(
&
root
->
root_key
,
0
,
sizeof
(
root
->
root_key
));
memset
(
&
root
->
root_key
,
0
,
sizeof
(
root
->
root_key
));
...
@@ -230,19 +234,19 @@ static int __setup_root(struct btrfs_root *root, u64 objectid, int fp)
...
@@ -230,19 +234,19 @@ static int __setup_root(struct btrfs_root *root, u64 objectid, int fp)
return
0
;
return
0
;
}
}
static
int
find_and_setup_root
(
struct
btrfs_root
*
tree_root
,
u64
objectid
,
static
int
find_and_setup_root
(
struct
btrfs_super_block
*
super
,
struct
btrfs_root
*
tree_root
,
u64
objectid
,
struct
btrfs_root
*
root
,
int
fp
)
struct
btrfs_root
*
root
,
int
fp
)
{
{
int
ret
;
int
ret
;
__setup_root
(
root
,
objectid
,
fp
);
__setup_root
(
super
,
root
,
objectid
,
fp
);
ret
=
btrfs_find_last_root
(
tree_root
,
objectid
,
ret
=
btrfs_find_last_root
(
tree_root
,
objectid
,
&
root
->
root_item
,
&
root
->
root_key
);
&
root
->
root_item
,
&
root
->
root_key
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
root
->
node
=
read_tree_block
(
root
,
root
->
node
=
read_tree_block
(
root
,
btrfs_root_blocknr
(
&
root
->
root_item
));
btrfs_root_blocknr
(
&
root
->
root_item
));
root
->
ref_cows
=
0
;
BUG_ON
(
!
root
->
node
);
BUG_ON
(
!
root
->
node
);
return
0
;
return
0
;
}
}
...
@@ -277,28 +281,28 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
...
@@ -277,28 +281,28 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
INIT_RADIX_TREE
(
&
tree_root
->
cache_radix
,
GFP_KERNEL
);
INIT_RADIX_TREE
(
&
tree_root
->
cache_radix
,
GFP_KERNEL
);
ret
=
pread
(
fp
,
super
,
sizeof
(
struct
btrfs_super_block
),
ret
=
pread
(
fp
,
super
,
sizeof
(
struct
btrfs_super_block
),
BTRFS_SUPER_INFO_OFFSET
(
BTRFS_BLOCKSIZE
)
);
BTRFS_SUPER_INFO_OFFSET
);
if
(
ret
==
0
||
btrfs_super_root
(
super
)
==
0
)
{
if
(
ret
==
0
||
btrfs_super_root
(
super
)
==
0
)
{
printf
(
"making new FS!
\n
"
);
printf
(
"making new FS!
\n
"
);
ret
=
mkfs
(
fp
,
0
,
BTRFS_BLOCKSIZE
);
ret
=
mkfs
(
fp
,
0
,
1024
);
if
(
ret
)
if
(
ret
)
return
NULL
;
return
NULL
;
ret
=
pread
(
fp
,
super
,
sizeof
(
struct
btrfs_super_block
),
ret
=
pread
(
fp
,
super
,
sizeof
(
struct
btrfs_super_block
),
BTRFS_SUPER_INFO_OFFSET
(
BTRFS_BLOCKSIZE
)
);
BTRFS_SUPER_INFO_OFFSET
);
if
(
ret
!=
sizeof
(
struct
btrfs_super_block
))
if
(
ret
!=
sizeof
(
struct
btrfs_super_block
))
return
NULL
;
return
NULL
;
}
}
BUG_ON
(
ret
<
0
);
BUG_ON
(
ret
<
0
);
__setup_root
(
tree_root
,
BTRFS_ROOT_TREE_OBJECTID
,
fp
);
__setup_root
(
super
,
tree_root
,
BTRFS_ROOT_TREE_OBJECTID
,
fp
);
tree_root
->
node
=
read_tree_block
(
tree_root
,
btrfs_super_root
(
super
));
tree_root
->
node
=
read_tree_block
(
tree_root
,
btrfs_super_root
(
super
));
BUG_ON
(
!
tree_root
->
node
);
BUG_ON
(
!
tree_root
->
node
);
ret
=
find_and_setup_root
(
tree_root
,
BTRFS_EXTENT_TREE_OBJECTID
,
ret
=
find_and_setup_root
(
super
,
tree_root
,
BTRFS_EXTENT_TREE_OBJECTID
,
extent_root
,
fp
);
extent_root
,
fp
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
ret
=
find_and_setup_root
(
tree_root
,
BTRFS_FS_TREE_OBJECTID
,
ret
=
find_and_setup_root
(
super
,
tree_root
,
BTRFS_FS_TREE_OBJECTID
,
root
,
fp
);
root
,
fp
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
...
@@ -313,7 +317,7 @@ int write_ctree_super(struct btrfs_root *root, struct btrfs_super_block *s)
...
@@ -313,7 +317,7 @@ int write_ctree_super(struct btrfs_root *root, struct btrfs_super_block *s)
int
ret
;
int
ret
;
btrfs_set_super_root
(
s
,
root
->
tree_root
->
node
->
blocknr
);
btrfs_set_super_root
(
s
,
root
->
tree_root
->
node
->
blocknr
);
ret
=
pwrite
(
root
->
fp
,
s
,
sizeof
(
*
s
),
ret
=
pwrite
(
root
->
fp
,
s
,
sizeof
(
*
s
),
BTRFS_SUPER_INFO_OFFSET
(
BTRFS_BLOCKSIZE
)
);
BTRFS_SUPER_INFO_OFFSET
);
if
(
ret
!=
sizeof
(
*
s
))
{
if
(
ret
!=
sizeof
(
*
s
))
{
fprintf
(
stderr
,
"failed to write new super block err %d
\n
"
,
ret
);
fprintf
(
stderr
,
"failed to write new super block err %d
\n
"
,
ret
);
return
ret
;
return
ret
;
...
...
fs/btrfs/disk-io.h
View file @
123abc88
...
@@ -5,12 +5,12 @@
...
@@ -5,12 +5,12 @@
struct
btrfs_buffer
{
struct
btrfs_buffer
{
u64
blocknr
;
u64
blocknr
;
int
count
;
int
count
;
struct
list_head
dirty
;
struct
list_head
cache
;
union
{
union
{
struct
btrfs_node
node
;
struct
btrfs_node
node
;
struct
btrfs_leaf
leaf
;
struct
btrfs_leaf
leaf
;
};
};
struct
list_head
dirty
;
struct
list_head
cache
;
};
};
struct
btrfs_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
);
struct
btrfs_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
);
...
@@ -24,9 +24,8 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *s);
...
@@ -24,9 +24,8 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *s);
int
close_ctree
(
struct
btrfs_root
*
root
,
struct
btrfs_super_block
*
s
);
int
close_ctree
(
struct
btrfs_root
*
root
,
struct
btrfs_super_block
*
s
);
void
btrfs_block_release
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
buf
);
void
btrfs_block_release
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
buf
);
int
write_ctree_super
(
struct
btrfs_root
*
root
,
struct
btrfs_super_block
*
s
);
int
write_ctree_super
(
struct
btrfs_root
*
root
,
struct
btrfs_super_block
*
s
);
int
mkfs
(
int
fd
,
u64
num_blocks
,
u16
blocksize
);
int
mkfs
(
int
fd
,
u64
num_blocks
,
u32
blocksize
);
#define BTRFS_SUPER_INFO_OFFSET
(bs) (16 * (bs)
)
#define BTRFS_SUPER_INFO_OFFSET
(16 * 1024
)
#endif
#endif
fs/btrfs/extent-tree.c
View file @
123abc88
...
@@ -143,7 +143,6 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks)
...
@@ -143,7 +143,6 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks)
struct
btrfs_key
key
;
struct
btrfs_key
key
;
struct
btrfs_root
*
extent_root
=
root
->
extent_root
;
struct
btrfs_root
*
extent_root
=
root
->
extent_root
;
int
ret
;
int
ret
;
struct
btrfs_item
*
item
;
struct
btrfs_extent_item
*
ei
;
struct
btrfs_extent_item
*
ei
;
struct
btrfs_key
ins
;
struct
btrfs_key
ins
;
u32
refs
;
u32
refs
;
...
@@ -161,9 +160,8 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks)
...
@@ -161,9 +160,8 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks)
printf
(
"failed to find %Lu
\n
"
,
key
.
objectid
);
printf
(
"failed to find %Lu
\n
"
,
key
.
objectid
);
BUG
();
BUG
();
}
}
item
=
path
.
nodes
[
0
]
->
leaf
.
items
+
path
.
slots
[
0
];
ei
=
btrfs_item_ptr
(
&
path
.
nodes
[
0
]
->
leaf
,
path
.
slots
[
0
],
ei
=
(
struct
btrfs_extent_item
*
)(
path
.
nodes
[
0
]
->
leaf
.
data
+
struct
btrfs_extent_item
);
btrfs_item_offset
(
item
));
BUG_ON
(
ei
->
refs
==
0
);
BUG_ON
(
ei
->
refs
==
0
);
refs
=
btrfs_extent_refs
(
ei
)
-
1
;
refs
=
btrfs_extent_refs
(
ei
)
-
1
;
btrfs_set_extent_refs
(
ei
,
refs
);
btrfs_set_extent_refs
(
ei
,
refs
);
...
...
fs/btrfs/mkfs.c
View file @
123abc88
...
@@ -10,19 +10,20 @@
...
@@ -10,19 +10,20 @@
#include "ctree.h"
#include "ctree.h"
#include "disk-io.h"
#include "disk-io.h"
int
mkfs
(
int
fd
,
u64
num_blocks
,
u
16
blocksize
)
int
mkfs
(
int
fd
,
u64
num_blocks
,
u
32
blocksize
)
{
{
struct
btrfs_super_block
super
;
struct
btrfs_super_block
super
;
struct
btrfs_leaf
empty_leaf
;
struct
btrfs_leaf
*
empty_leaf
;
struct
btrfs_root_item
root_item
;
struct
btrfs_root_item
root_item
;
struct
btrfs_item
item
;
struct
btrfs_item
item
;
struct
btrfs_extent_item
extent_item
;
struct
btrfs_extent_item
extent_item
;
char
*
block
;
char
*
block
;
int
ret
;
int
ret
;
u16
itemoff
;
u32
itemoff
;
u32
start_block
=
BTRFS_SUPER_INFO_OFFSET
/
blocksize
;
btrfs_set_super_blocknr
(
&
super
,
16
);
btrfs_set_super_blocknr
(
&
super
,
start_block
);
btrfs_set_super_root
(
&
super
,
17
);
btrfs_set_super_root
(
&
super
,
start_block
+
1
);
strcpy
((
char
*
)(
&
super
.
magic
),
BTRFS_MAGIC
);
strcpy
((
char
*
)(
&
super
.
magic
),
BTRFS_MAGIC
);
btrfs_set_super_blocksize
(
&
super
,
blocksize
);
btrfs_set_super_blocksize
(
&
super
,
blocksize
);
btrfs_set_super_total_blocks
(
&
super
,
num_blocks
);
btrfs_set_super_total_blocks
(
&
super
,
num_blocks
);
...
@@ -32,168 +33,98 @@ int mkfs(int fd, u64 num_blocks, u16 blocksize)
...
@@ -32,168 +33,98 @@ int mkfs(int fd, u64 num_blocks, u16 blocksize)
memset
(
block
,
0
,
blocksize
);
memset
(
block
,
0
,
blocksize
);
BUG_ON
(
sizeof
(
super
)
>
blocksize
);
BUG_ON
(
sizeof
(
super
)
>
blocksize
);
memcpy
(
block
,
&
super
,
sizeof
(
super
));
memcpy
(
block
,
&
super
,
sizeof
(
super
));
ret
=
pwrite
(
fd
,
block
,
blocksize
,
BTRFS_SUPER_INFO_OFFSET
(
blocksize
)
);
ret
=
pwrite
(
fd
,
block
,
blocksize
,
BTRFS_SUPER_INFO_OFFSET
);
BUG_ON
(
ret
!=
blocksize
);
BUG_ON
(
ret
!=
blocksize
);
/* create the tree of root objects */
/* create the tree of root objects */
memset
(
&
empty_leaf
,
0
,
sizeof
(
empty_leaf
));
empty_leaf
=
malloc
(
blocksize
);
btrfs_set_header_parentid
(
&
empty_leaf
.
header
,
BTRFS_ROOT_TREE_OBJECTID
);
memset
(
empty_leaf
,
0
,
blocksize
);
btrfs_set_header_blocknr
(
&
empty_leaf
.
header
,
17
);
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
btrfs_set_header_nritems
(
&
empty_leaf
.
header
,
2
);
BTRFS_ROOT_TREE_OBJECTID
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
1
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
2
);
/* create the items for the root tree */
/* create the items for the root tree */
btrfs_set_root_blocknr
(
&
root_item
,
18
);
btrfs_set_root_blocknr
(
&
root_item
,
start_block
+
2
);
btrfs_set_root_refs
(
&
root_item
,
1
);
btrfs_set_root_refs
(
&
root_item
,
1
);
itemoff
=
LEAF_DATA_SIZE
-
sizeof
(
root_item
);
itemoff
=
__BTRFS_LEAF_DATA_SIZE
(
blocksize
)
-
sizeof
(
root_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_size
(
&
item
,
sizeof
(
root_item
));
btrfs_set_item_size
(
&
item
,
sizeof
(
root_item
));
btrfs_set_key_objectid
(
&
item
.
key
,
BTRFS_EXTENT_TREE_OBJECTID
);
btrfs_set_key_objectid
(
&
item
.
key
,
BTRFS_EXTENT_TREE_OBJECTID
);
btrfs_set_key_offset
(
&
item
.
key
,
0
);
btrfs_set_key_offset
(
&
item
.
key
,
0
);
btrfs_set_key_flags
(
&
item
.
key
,
0
);
btrfs_set_key_flags
(
&
item
.
key
,
0
);
memcpy
(
empty_leaf
.
items
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
->
items
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
.
data
+
itemoff
,
&
root_item
,
sizeof
(
root_item
));
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
itemoff
,
&
root_item
,
sizeof
(
root_item
));
btrfs_set_root_blocknr
(
&
root_item
,
19
);
btrfs_set_root_blocknr
(
&
root_item
,
start_block
+
3
);
itemoff
=
itemoff
-
sizeof
(
root_item
);
itemoff
=
itemoff
-
sizeof
(
root_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_key_objectid
(
&
item
.
key
,
BTRFS_FS_TREE_OBJECTID
);
btrfs_set_key_objectid
(
&
item
.
key
,
BTRFS_FS_TREE_OBJECTID
);
memcpy
(
empty_leaf
.
items
+
1
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
->
items
+
1
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
.
data
+
itemoff
,
&
root_item
,
sizeof
(
root_item
));
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
itemoff
,
ret
=
pwrite
(
fd
,
&
empty_leaf
,
blocksize
,
17
*
blocksize
);
&
root_item
,
sizeof
(
root_item
));
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
1
)
*
blocksize
);
/* create the items for the extent tree */
/* create the items for the extent tree */
btrfs_set_header_parentid
(
&
empty_leaf
.
header
,
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
BTRFS_EXTENT_TREE_OBJECTID
);
BTRFS_EXTENT_TREE_OBJECTID
);
btrfs_set_header_blocknr
(
&
empty_leaf
.
header
,
18
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
2
);
btrfs_set_header_nritems
(
&
empty_leaf
.
header
,
4
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
4
);
/* item1, reserve blocks 0-16 */
/* item1, reserve blocks 0-16 */
btrfs_set_key_objectid
(
&
item
.
key
,
0
);
btrfs_set_key_objectid
(
&
item
.
key
,
0
);
btrfs_set_key_offset
(
&
item
.
key
,
17
);
btrfs_set_key_offset
(
&
item
.
key
,
start_block
+
1
);
btrfs_set_key_flags
(
&
item
.
key
,
0
);
btrfs_set_key_flags
(
&
item
.
key
,
0
);
itemoff
=
LEAF_DATA_SIZE
-
sizeof
(
struct
btrfs_extent_item
);
itemoff
=
__BTRFS_LEAF_DATA_SIZE
(
blocksize
)
-
sizeof
(
struct
btrfs_extent_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_size
(
&
item
,
sizeof
(
struct
btrfs_extent_item
));
btrfs_set_item_size
(
&
item
,
sizeof
(
struct
btrfs_extent_item
));
btrfs_set_extent_refs
(
&
extent_item
,
1
);
btrfs_set_extent_refs
(
&
extent_item
,
1
);
btrfs_set_extent_owner
(
&
extent_item
,
0
);
btrfs_set_extent_owner
(
&
extent_item
,
0
);
memcpy
(
empty_leaf
.
items
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
->
items
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
.
data
+
btrfs_item_offset
(
&
item
),
&
extent_item
,
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
)
,
btrfs_item_size
(
&
item
));
&
extent_item
,
btrfs_item_size
(
&
item
));
/* item2, give block 17 to the root */
/* item2, give block 17 to the root */
btrfs_set_key_objectid
(
&
item
.
key
,
17
);
btrfs_set_key_objectid
(
&
item
.
key
,
start_block
+
1
);
btrfs_set_key_offset
(
&
item
.
key
,
1
);
btrfs_set_key_offset
(
&
item
.
key
,
1
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_ROOT_TREE_OBJECTID
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_ROOT_TREE_OBJECTID
);
memcpy
(
empty_leaf
.
items
+
1
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
->
items
+
1
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
.
data
+
btrfs_item_offset
(
&
item
),
&
extent_item
,
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
)
,
btrfs_item_size
(
&
item
));
&
extent_item
,
btrfs_item_size
(
&
item
));
/* item3, give block 18 to the extent root */
/* item3, give block 18 to the extent root */
btrfs_set_key_objectid
(
&
item
.
key
,
18
);
btrfs_set_key_objectid
(
&
item
.
key
,
start_block
+
2
);
btrfs_set_key_offset
(
&
item
.
key
,
1
);
btrfs_set_key_offset
(
&
item
.
key
,
1
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_EXTENT_TREE_OBJECTID
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_EXTENT_TREE_OBJECTID
);
memcpy
(
empty_leaf
.
items
+
2
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
->
items
+
2
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
.
data
+
btrfs_item_offset
(
&
item
),
&
extent_item
,
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
)
,
btrfs_item_size
(
&
item
));
&
extent_item
,
btrfs_item_size
(
&
item
));
/* item4, give block 19 to the FS root */
/* item4, give block 19 to the FS root */
btrfs_set_key_objectid
(
&
item
.
key
,
19
);
btrfs_set_key_objectid
(
&
item
.
key
,
start_block
+
3
);
btrfs_set_key_offset
(
&
item
.
key
,
1
);
btrfs_set_key_offset
(
&
item
.
key
,
1
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_FS_TREE_OBJECTID
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_FS_TREE_OBJECTID
);
memcpy
(
empty_leaf
.
items
+
3
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
->
items
+
3
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
.
data
+
btrfs_item_offset
(
&
item
),
&
extent_item
,
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
)
,
btrfs_item_size
(
&
item
));
&
extent_item
,
btrfs_item_size
(
&
item
));
ret
=
pwrite
(
fd
,
&
empty_leaf
,
blocksize
,
18
*
blocksize
);
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
2
)
*
blocksize
);
if
(
ret
!=
sizeof
(
empty_leaf
)
)
if
(
ret
!=
blocksize
)
return
-
1
;
return
-
1
;
/* finally create the FS root */
/* finally create the FS root */
btrfs_set_header_parentid
(
&
empty_leaf
.
header
,
BTRFS_FS_TREE_OBJECTID
);
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
BTRFS_FS_TREE_OBJECTID
);
btrfs_set_header_blocknr
(
&
empty_leaf
.
header
,
19
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
3
);
btrfs_set_header_nritems
(
&
empty_leaf
.
header
,
0
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
0
);
ret
=
pwrite
(
fd
,
&
empty_leaf
,
blocksize
,
19
*
blocksize
);
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
3
)
*
blocksize
);
if
(
ret
!=
sizeof
(
empty_leaf
)
)
if
(
ret
!=
blocksize
)
return
-
1
;
return
-
1
;
return
0
;
return
0
;
}
}
#if 0
int mkfs(int fd)
{
struct btrfs_root_info info[2];
struct btrfs_leaf empty_leaf;
struct btrfs_item item;
struct btrfs_extent_item extent_item;
int ret;
/* setup the super block area */
memset(info, 0, sizeof(info));
btrfs_set_root_blocknr(info, 16);
btrfs_set_root_objectid(info, 1);
btrfs_set_root_tree_root(info, 17);
btrfs_set_root_blocknr(info + 1, 16);
btrfs_set_root_objectid(info + 1, 2);
btrfs_set_root_tree_root(info + 1, 18);
ret = pwrite(fd, info, sizeof(info),
BTRFS_SUPER_INFO_OFFSET(BTRFS_BLOCKSIZE));
if (ret != sizeof(info))
return -1;
/* create leaves for the tree root and extent root */
memset(&empty_leaf, 0, sizeof(empty_leaf));
btrfs_set_header_parentid(&empty_leaf.header, 1);
btrfs_set_header_blocknr(&empty_leaf.header, 17);
ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 17 * BTRFS_BLOCKSIZE);
if (ret != sizeof(empty_leaf))
return -1;
btrfs_set_header_parentid(&empty_leaf.header, 2);
btrfs_set_header_blocknr(&empty_leaf.header, 18);
btrfs_set_header_nritems(&empty_leaf.header, 3);
/* item1, reserve blocks 0-16 */
btrfs_set_key_objectid(&item.key, 0);
btrfs_set_key_offset(&item.key, 17);
btrfs_set_key_flags(&item.key, 0);
btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
sizeof(struct btrfs_extent_item));
btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
btrfs_set_extent_refs(&extent_item, 1);
btrfs_set_extent_owner(&extent_item, 0);
memcpy(empty_leaf.items, &item, sizeof(item));
memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
btrfs_item_size(&item));
/* item2, give block 17 to the root */
btrfs_set_key_objectid(&item.key, 17);
btrfs_set_key_offset(&item.key, 1);
btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
sizeof(struct btrfs_extent_item) * 2);
btrfs_set_extent_owner(&extent_item, 1);
memcpy(empty_leaf.items + 1, &item, sizeof(item));
memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
btrfs_item_size(&item));
/* item3, give block 18 for the extent root */
btrfs_set_key_objectid(&item.key, 18);
btrfs_set_key_offset(&item.key, 1);
btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
sizeof(struct btrfs_extent_item) * 3);
btrfs_set_extent_owner(&extent_item, 2);
memcpy(empty_leaf.items + 2, &item, sizeof(item));
memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
btrfs_item_size(&item));
ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 18 * BTRFS_BLOCKSIZE);
if (ret != sizeof(empty_leaf))
return -1;
return 0;
}
#endif
fs/btrfs/print-tree.c
View file @
123abc88
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
#include "ctree.h"
#include "ctree.h"
#include "disk-io.h"
#include "disk-io.h"
void
btrfs_print_leaf
(
struct
btrfs_leaf
*
l
)
void
btrfs_print_leaf
(
struct
btrfs_
root
*
root
,
struct
btrfs_
leaf
*
l
)
{
{
int
i
;
int
i
;
u32
nr
=
btrfs_header_nritems
(
&
l
->
header
);
u32
nr
=
btrfs_header_nritems
(
&
l
->
header
);
...
@@ -13,7 +13,8 @@ void btrfs_print_leaf(struct btrfs_leaf *l)
...
@@ -13,7 +13,8 @@ void btrfs_print_leaf(struct btrfs_leaf *l)
struct
btrfs_extent_item
*
ei
;
struct
btrfs_extent_item
*
ei
;
struct
btrfs_root_item
*
ri
;
struct
btrfs_root_item
*
ri
;
printf
(
"leaf %Lu total ptrs %d free space %d
\n
"
,
printf
(
"leaf %Lu total ptrs %d free space %d
\n
"
,
btrfs_header_blocknr
(
&
l
->
header
),
nr
,
btrfs_leaf_free_space
(
l
));
btrfs_header_blocknr
(
&
l
->
header
),
nr
,
btrfs_leaf_free_space
(
root
,
l
));
fflush
(
stdout
);
fflush
(
stdout
);
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
item
=
l
->
items
+
i
;
item
=
l
->
items
+
i
;
...
@@ -25,7 +26,7 @@ void btrfs_print_leaf(struct btrfs_leaf *l)
...
@@ -25,7 +26,7 @@ void btrfs_print_leaf(struct btrfs_leaf *l)
btrfs_item_offset
(
item
),
btrfs_item_offset
(
item
),
btrfs_item_size
(
item
));
btrfs_item_size
(
item
));
printf
(
"
\t\t
item data %.*s
\n
"
,
btrfs_item_size
(
item
),
printf
(
"
\t\t
item data %.*s
\n
"
,
btrfs_item_size
(
item
),
l
->
data
+
btrfs_item_offset
(
item
));
btrfs_leaf_data
(
l
)
+
btrfs_item_offset
(
item
));
ei
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_extent_item
);
ei
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_extent_item
);
printf
(
"
\t\t
extent data refs %u owner %Lu
\n
"
,
printf
(
"
\t\t
extent data refs %u owner %Lu
\n
"
,
btrfs_extent_refs
(
ei
),
btrfs_extent_owner
(
ei
));
btrfs_extent_refs
(
ei
),
btrfs_extent_owner
(
ei
));
...
@@ -46,18 +47,18 @@ void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t)
...
@@ -46,18 +47,18 @@ void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t)
c
=
&
t
->
node
;
c
=
&
t
->
node
;
nr
=
btrfs_header_nritems
(
&
c
->
header
);
nr
=
btrfs_header_nritems
(
&
c
->
header
);
if
(
btrfs_is_leaf
(
c
))
{
if
(
btrfs_is_leaf
(
c
))
{
btrfs_print_leaf
((
struct
btrfs_leaf
*
)
c
);
btrfs_print_leaf
(
root
,
(
struct
btrfs_leaf
*
)
c
);
return
;
return
;
}
}
printf
(
"node %Lu level %d total ptrs %d free spc %u
\n
"
,
t
->
blocknr
,
printf
(
"node %Lu level %d total ptrs %d free spc %u
\n
"
,
t
->
blocknr
,
btrfs_header_level
(
&
c
->
header
),
nr
,
btrfs_header_level
(
&
c
->
header
),
nr
,
(
u32
)
NODEPTRS_PER_BLOCK
-
nr
);
(
u32
)
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
-
nr
);
fflush
(
stdout
);
fflush
(
stdout
);
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
printf
(
"
\t
key %d (%Lu %u %Lu) block %Lu
\n
"
,
printf
(
"
\t
key %d (%Lu %u %Lu) block %Lu
\n
"
,
i
,
i
,
c
->
keys
[
i
].
objectid
,
c
->
keys
[
i
].
flags
,
c
->
keys
[
i
].
offset
,
c
->
ptrs
[
i
].
key
.
objectid
,
c
->
ptrs
[
i
].
key
.
flags
,
btrfs_node_blockptr
(
c
,
i
));
c
->
ptrs
[
i
].
key
.
offset
,
btrfs_node_blockptr
(
c
,
i
));
fflush
(
stdout
);
fflush
(
stdout
);
}
}
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
...
...
fs/btrfs/print-tree.h
View file @
123abc88
void
btrfs_print_leaf
(
struct
btrfs_leaf
*
l
);
void
btrfs_print_leaf
(
struct
btrfs_
root
*
root
,
struct
btrfs_
leaf
*
l
);
void
btrfs_print_tree
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
t
);
void
btrfs_print_tree
(
struct
btrfs_root
*
root
,
struct
btrfs_buffer
*
t
);
fs/btrfs/quick-test.c
View file @
123abc88
...
@@ -73,7 +73,7 @@ int main(int ac, char **av) {
...
@@ -73,7 +73,7 @@ int main(int ac, char **av) {
printf
(
"node %p level %d total ptrs %d free spc %lu
\n
"
,
root
->
node
,
printf
(
"node %p level %d total ptrs %d free spc %lu
\n
"
,
root
->
node
,
btrfs_header_level
(
&
root
->
node
->
node
.
header
),
btrfs_header_level
(
&
root
->
node
->
node
.
header
),
btrfs_header_nritems
(
&
root
->
node
->
node
.
header
),
btrfs_header_nritems
(
&
root
->
node
->
node
.
header
),
NODEPTRS_PER_BLOCK
-
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
-
btrfs_header_nritems
(
&
root
->
node
->
node
.
header
));
btrfs_header_nritems
(
&
root
->
node
->
node
.
header
));
printf
(
"all searches good, deleting some items
\n
"
);
printf
(
"all searches good, deleting some items
\n
"
);
i
=
0
;
i
=
0
;
...
...
fs/btrfs/root-tree.c
View file @
123abc88
...
@@ -31,7 +31,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
...
@@ -31,7 +31,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
ret
=
1
;
ret
=
1
;
goto
out
;
goto
out
;
}
}
memcpy
(
item
,
l
->
data
+
btrfs_item_offset
(
l
->
items
+
slot
),
memcpy
(
item
,
btrfs_item_ptr
(
l
,
slot
,
struct
btrfs_root_item
),
sizeof
(
*
item
));
sizeof
(
*
item
));
btrfs_disk_key_to_cpu
(
key
,
&
l
->
items
[
slot
].
key
);
btrfs_disk_key_to_cpu
(
key
,
&
l
->
items
[
slot
].
key
);
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
...
@@ -55,7 +55,7 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
...
@@ -55,7 +55,7 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
BUG_ON
(
ret
!=
0
);
BUG_ON
(
ret
!=
0
);
l
=
&
path
.
nodes
[
0
]
->
leaf
;
l
=
&
path
.
nodes
[
0
]
->
leaf
;
slot
=
path
.
slots
[
0
];
slot
=
path
.
slots
[
0
];
memcpy
(
l
->
data
+
btrfs_item_offset
(
l
->
items
+
slot
),
item
,
memcpy
(
btrfs_item_ptr
(
l
,
slot
,
struct
btrfs_root_item
),
item
,
sizeof
(
*
item
));
sizeof
(
*
item
));
out:
out:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
...
...
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