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
7518a238
Commit
7518a238
authored
Mar 12, 2007
by
Chris Mason
Committed by
David Woodhouse
Mar 12, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: get/set for struct header fields
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
83e15a28
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
230 additions
and
172 deletions
+230
-172
fs/btrfs/Makefile
fs/btrfs/Makefile
+1
-1
fs/btrfs/TODO
fs/btrfs/TODO
+1
-0
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+126
-98
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+59
-4
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+4
-3
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+13
-40
fs/btrfs/mkfs.c
fs/btrfs/mkfs.c
+5
-5
fs/btrfs/print-tree.c
fs/btrfs/print-tree.c
+12
-14
fs/btrfs/quick-test.c
fs/btrfs/quick-test.c
+7
-5
fs/btrfs/random-test.c
fs/btrfs/random-test.c
+2
-2
No files found.
fs/btrfs/Makefile
View file @
7518a238
...
@@ -25,7 +25,7 @@ tester: $(objects) random-test.o
...
@@ -25,7 +25,7 @@ tester: $(objects) random-test.o
quick-test
:
$(objects) quick-test.o
quick-test
:
$(objects) quick-test.o
gcc
$(CFLAGS)
-o
quick-test
$(objects)
quick-test.o
gcc
$(CFLAGS)
-o
quick-test
$(objects)
quick-test.o
$(objects)
:
$(headers)
$(objects)
:
$(headers)
clean
:
clean
:
rm
debug-tree tester
*
.o
rm
debug-tree tester
*
.o
...
...
fs/btrfs/TODO
View file @
7518a238
* cleanup, add more error checking, get rid of BUG_ONs
* cleanup, add more error checking, get rid of BUG_ONs
* endian fixes
* Make IO functions look more like the page cache
* Make IO functions look more like the page cache
* Fix ENOSPC handling
* Fix ENOSPC handling
* make blocksize a mkfs parameter instead of #define
* make blocksize a mkfs parameter instead of #define
...
...
fs/btrfs/ctree.c
View file @
7518a238
...
@@ -48,7 +48,7 @@ int btrfs_cow_block(struct ctree_root *root,
...
@@ -48,7 +48,7 @@ int btrfs_cow_block(struct ctree_root *root,
}
}
cow
=
alloc_free_block
(
root
);
cow
=
alloc_free_block
(
root
);
memcpy
(
&
cow
->
node
,
&
buf
->
node
,
sizeof
(
buf
->
node
));
memcpy
(
&
cow
->
node
,
&
buf
->
node
,
sizeof
(
buf
->
node
));
cow
->
node
.
header
.
blocknr
=
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
);
if
(
buf
==
root
->
node
)
{
if
(
buf
==
root
->
node
)
{
...
@@ -73,7 +73,7 @@ int btrfs_cow_block(struct ctree_root *root,
...
@@ -73,7 +73,7 @@ int btrfs_cow_block(struct ctree_root *root,
*/
*/
static
inline
unsigned
int
leaf_data_end
(
struct
leaf
*
leaf
)
static
inline
unsigned
int
leaf_data_end
(
struct
leaf
*
leaf
)
{
{
u
nsigned
int
nr
=
leaf
->
header
.
nritems
;
u
32
nr
=
btrfs_header_nritems
(
&
leaf
->
header
)
;
if
(
nr
==
0
)
if
(
nr
==
0
)
return
sizeof
(
leaf
->
data
);
return
sizeof
(
leaf
->
data
);
return
leaf
->
items
[
nr
-
1
].
offset
;
return
leaf
->
items
[
nr
-
1
].
offset
;
...
@@ -87,7 +87,7 @@ static inline unsigned int leaf_data_end(struct leaf *leaf)
...
@@ -87,7 +87,7 @@ static inline unsigned int leaf_data_end(struct leaf *leaf)
int
leaf_free_space
(
struct
leaf
*
leaf
)
int
leaf_free_space
(
struct
leaf
*
leaf
)
{
{
int
data_end
=
leaf_data_end
(
leaf
);
int
data_end
=
leaf_data_end
(
leaf
);
int
nritems
=
leaf
->
header
.
nritems
;
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
*
)(
leaf
->
data
+
data_end
)
-
(
char
*
)
items_end
;
}
}
...
@@ -118,18 +118,21 @@ int check_node(struct ctree_path *path, int level)
...
@@ -118,18 +118,21 @@ int check_node(struct ctree_path *path, int level)
struct
node
*
parent
=
NULL
;
struct
node
*
parent
=
NULL
;
struct
node
*
node
=
&
path
->
nodes
[
level
]
->
node
;
struct
node
*
node
=
&
path
->
nodes
[
level
]
->
node
;
int
parent_slot
;
int
parent_slot
;
u32
nritems
=
btrfs_header_nritems
(
&
node
->
header
);
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
];
if
(
parent
&&
node
->
header
.
nritems
>
0
)
{
BUG_ON
(
nritems
==
0
);
if
(
parent
)
{
struct
key
*
parent_key
;
struct
key
*
parent_key
;
parent_key
=
&
parent
->
keys
[
parent_slot
];
parent_key
=
&
parent
->
keys
[
parent_slot
];
BUG_ON
(
memcmp
(
parent_key
,
node
->
keys
,
sizeof
(
struct
key
)));
BUG_ON
(
memcmp
(
parent_key
,
node
->
keys
,
sizeof
(
struct
key
)));
BUG_ON
(
parent
->
blockptrs
[
parent_slot
]
!=
node
->
header
.
blocknr
);
BUG_ON
(
parent
->
blockptrs
[
parent_slot
]
!=
btrfs_header_blocknr
(
&
node
->
header
));
}
}
BUG_ON
(
n
ode
->
header
.
n
ritems
>
NODEPTRS_PER_BLOCK
);
BUG_ON
(
nritems
>
NODEPTRS_PER_BLOCK
);
for
(
i
=
0
;
i
<
node
->
header
.
nritems
-
2
;
i
++
)
{
for
(
i
=
0
;
nritems
>
1
&&
i
<
nritems
-
2
;
i
++
)
{
BUG_ON
(
comp_keys
(
&
node
->
keys
[
i
],
&
node
->
keys
[
i
+
1
])
>=
0
);
BUG_ON
(
comp_keys
(
&
node
->
keys
[
i
],
&
node
->
keys
[
i
+
1
])
>=
0
);
}
}
return
0
;
return
0
;
...
@@ -141,18 +144,25 @@ int check_leaf(struct ctree_path *path, int level)
...
@@ -141,18 +144,25 @@ int check_leaf(struct ctree_path *path, int level)
struct
leaf
*
leaf
=
&
path
->
nodes
[
level
]
->
leaf
;
struct
leaf
*
leaf
=
&
path
->
nodes
[
level
]
->
leaf
;
struct
node
*
parent
=
NULL
;
struct
node
*
parent
=
NULL
;
int
parent_slot
;
int
parent_slot
;
u32
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
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
];
if
(
parent
&&
leaf
->
header
.
nritems
>
0
)
{
BUG_ON
(
leaf_free_space
(
leaf
)
<
0
);
if
(
nritems
==
0
)
return
0
;
if
(
parent
)
{
struct
key
*
parent_key
;
struct
key
*
parent_key
;
parent_key
=
&
parent
->
keys
[
parent_slot
];
parent_key
=
&
parent
->
keys
[
parent_slot
];
BUG_ON
(
memcmp
(
parent_key
,
&
leaf
->
items
[
0
].
key
,
BUG_ON
(
memcmp
(
parent_key
,
&
leaf
->
items
[
0
].
key
,
sizeof
(
struct
key
)));
sizeof
(
struct
key
)));
BUG_ON
(
parent
->
blockptrs
[
parent_slot
]
!=
leaf
->
header
.
blocknr
);
BUG_ON
(
parent
->
blockptrs
[
parent_slot
]
!=
btrfs_header_blocknr
(
&
leaf
->
header
));
}
}
for
(
i
=
0
;
i
<
leaf
->
header
.
nritems
-
2
;
i
++
)
{
for
(
i
=
0
;
nritems
>
1
&&
i
<
nritems
-
2
;
i
++
)
{
BUG_ON
(
comp_keys
(
&
leaf
->
items
[
i
].
key
,
BUG_ON
(
comp_keys
(
&
leaf
->
items
[
i
].
key
,
&
leaf
->
items
[
i
+
1
].
key
)
>=
0
);
&
leaf
->
items
[
i
+
1
].
key
)
>=
0
);
BUG_ON
(
leaf
->
items
[
i
].
offset
!=
leaf
->
items
[
i
+
1
].
offset
+
BUG_ON
(
leaf
->
items
[
i
].
offset
!=
leaf
->
items
[
i
+
1
].
offset
+
...
@@ -162,7 +172,6 @@ int check_leaf(struct ctree_path *path, int level)
...
@@ -162,7 +172,6 @@ int check_leaf(struct ctree_path *path, int level)
LEAF_DATA_SIZE
);
LEAF_DATA_SIZE
);
}
}
}
}
BUG_ON
(
leaf_free_space
(
leaf
)
<
0
);
return
0
;
return
0
;
}
}
...
@@ -215,13 +224,15 @@ int generic_bin_search(char *p, int item_size, struct key *key,
...
@@ -215,13 +224,15 @@ int generic_bin_search(char *p, int item_size, struct key *key,
*/
*/
int
bin_search
(
struct
node
*
c
,
struct
key
*
key
,
int
*
slot
)
int
bin_search
(
struct
node
*
c
,
struct
key
*
key
,
int
*
slot
)
{
{
if
(
is_leaf
(
c
->
header
.
flags
))
{
if
(
btrfs_is_leaf
(
c
))
{
struct
leaf
*
l
=
(
struct
leaf
*
)
c
;
struct
leaf
*
l
=
(
struct
leaf
*
)
c
;
return
generic_bin_search
((
void
*
)
l
->
items
,
sizeof
(
struct
item
),
return
generic_bin_search
((
void
*
)
l
->
items
,
sizeof
(
struct
item
),
key
,
c
->
header
.
nritems
,
slot
);
key
,
btrfs_header_nritems
(
&
c
->
header
),
slot
);
}
else
{
}
else
{
return
generic_bin_search
((
void
*
)
c
->
keys
,
sizeof
(
struct
key
),
return
generic_bin_search
((
void
*
)
c
->
keys
,
sizeof
(
struct
key
),
key
,
c
->
header
.
nritems
,
slot
);
key
,
btrfs_header_nritems
(
&
c
->
header
),
slot
);
}
}
return
-
1
;
return
-
1
;
}
}
...
@@ -233,7 +244,7 @@ struct tree_buffer *read_node_slot(struct ctree_root *root,
...
@@ -233,7 +244,7 @@ struct tree_buffer *read_node_slot(struct ctree_root *root,
struct
node
*
node
=
&
parent_buf
->
node
;
struct
node
*
node
=
&
parent_buf
->
node
;
if
(
slot
<
0
)
if
(
slot
<
0
)
return
NULL
;
return
NULL
;
if
(
slot
>=
node
->
header
.
nritems
)
if
(
slot
>=
btrfs_header_nritems
(
&
node
->
header
)
)
return
NULL
;
return
NULL
;
return
read_tree_block
(
root
,
node
->
blockptrs
[
slot
]);
return
read_tree_block
(
root
,
node
->
blockptrs
[
slot
]);
}
}
...
@@ -270,7 +281,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
...
@@ -270,7 +281,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
struct
tree_buffer
*
child
;
struct
tree_buffer
*
child
;
u64
blocknr
=
mid_buf
->
blocknr
;
u64
blocknr
=
mid_buf
->
blocknr
;
if
(
mid
->
header
.
nritems
!=
1
)
if
(
btrfs_header_nritems
(
&
mid
->
header
)
!=
1
)
return
0
;
return
0
;
/* promote the child to a root */
/* promote the child to a root */
...
@@ -287,7 +298,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
...
@@ -287,7 +298,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
}
}
parent
=
&
parent_buf
->
node
;
parent
=
&
parent_buf
->
node
;
if
(
mid
->
header
.
nritems
>
NODEPTRS_PER_BLOCK
/
4
)
if
(
btrfs_header_nritems
(
&
mid
->
header
)
>
NODEPTRS_PER_BLOCK
/
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
);
...
@@ -298,7 +309,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
...
@@ -298,7 +309,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
btrfs_cow_block
(
root
,
left_buf
,
parent_buf
,
btrfs_cow_block
(
root
,
left_buf
,
parent_buf
,
pslot
-
1
,
&
left_buf
);
pslot
-
1
,
&
left_buf
);
left
=
&
left_buf
->
node
;
left
=
&
left_buf
->
node
;
orig_slot
+=
left
->
header
.
nritems
;
orig_slot
+=
btrfs_header_nritems
(
&
left
->
header
)
;
wret
=
push_node_left
(
root
,
left_buf
,
mid_buf
);
wret
=
push_node_left
(
root
,
left_buf
,
mid_buf
);
if
(
wret
<
0
)
if
(
wret
<
0
)
ret
=
wret
;
ret
=
wret
;
...
@@ -314,7 +325,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
...
@@ -314,7 +325,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
wret
=
push_node_left
(
root
,
mid_buf
,
right_buf
);
wret
=
push_node_left
(
root
,
mid_buf
,
right_buf
);
if
(
wret
<
0
)
if
(
wret
<
0
)
ret
=
wret
;
ret
=
wret
;
if
(
right
->
header
.
nritems
==
0
)
{
if
(
btrfs_header_nritems
(
&
right
->
header
)
==
0
)
{
u64
blocknr
=
right_buf
->
blocknr
;
u64
blocknr
=
right_buf
->
blocknr
;
tree_block_release
(
root
,
right_buf
);
tree_block_release
(
root
,
right_buf
);
clean_tree_block
(
root
,
right_buf
);
clean_tree_block
(
root
,
right_buf
);
...
@@ -332,7 +343,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
...
@@ -332,7 +343,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
BUG_ON
(
list_empty
(
&
parent_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
parent_buf
->
dirty
));
}
}
}
}
if
(
mid
->
header
.
nritems
==
1
)
{
if
(
btrfs_header_nritems
(
&
mid
->
header
)
==
1
)
{
/*
/*
* we're not allowed to leave a node with one item in the
* we're not allowed to leave a node with one item in the
* tree during a delete. A deletion from lower in the tree
* tree during a delete. A deletion from lower in the tree
...
@@ -348,7 +359,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
...
@@ -348,7 +359,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
ret
=
wret
;
ret
=
wret
;
BUG_ON
(
wret
==
1
);
BUG_ON
(
wret
==
1
);
}
}
if
(
mid
->
header
.
nritems
==
0
)
{
if
(
btrfs_header_nritems
(
&
mid
->
header
)
==
0
)
{
/* we've managed to empty the middle node, drop it */
/* we've managed to empty the middle node, drop it */
u64
blocknr
=
mid_buf
->
blocknr
;
u64
blocknr
=
mid_buf
->
blocknr
;
tree_block_release
(
root
,
mid_buf
);
tree_block_release
(
root
,
mid_buf
);
...
@@ -369,7 +380,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
...
@@ -369,7 +380,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
/* update the path */
/* update the path */
if
(
left_buf
)
{
if
(
left_buf
)
{
if
(
left
->
header
.
nritems
>
orig_slot
)
{
if
(
btrfs_header_nritems
(
&
left
->
header
)
>
orig_slot
)
{
left_buf
->
count
++
;
// released below
left_buf
->
count
++
;
// released below
path
->
nodes
[
level
]
=
left_buf
;
path
->
nodes
[
level
]
=
left_buf
;
path
->
slots
[
level
+
1
]
-=
1
;
path
->
slots
[
level
+
1
]
-=
1
;
...
@@ -377,7 +388,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
...
@@ -377,7 +388,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
if
(
mid_buf
)
if
(
mid_buf
)
tree_block_release
(
root
,
mid_buf
);
tree_block_release
(
root
,
mid_buf
);
}
else
{
}
else
{
orig_slot
-=
left
->
header
.
nritems
;
orig_slot
-=
btrfs_header_nritems
(
&
left
->
header
)
;
path
->
slots
[
level
]
=
orig_slot
;
path
->
slots
[
level
]
=
orig_slot
;
}
}
}
}
...
@@ -420,7 +431,7 @@ int search_slot(struct ctree_root *root, struct key *key,
...
@@ -420,7 +431,7 @@ int search_slot(struct ctree_root *root, struct key *key,
b
=
root
->
node
;
b
=
root
->
node
;
b
->
count
++
;
b
->
count
++
;
while
(
b
)
{
while
(
b
)
{
level
=
node_level
(
b
->
node
.
header
.
flags
);
level
=
btrfs_header_level
(
&
b
->
node
.
header
);
if
(
cow
)
{
if
(
cow
)
{
int
wret
;
int
wret
;
wret
=
btrfs_cow_block
(
root
,
b
,
p
->
nodes
[
level
+
1
],
wret
=
btrfs_cow_block
(
root
,
b
,
p
->
nodes
[
level
+
1
],
...
@@ -434,12 +445,12 @@ int search_slot(struct ctree_root *root, struct key *key,
...
@@ -434,12 +445,12 @@ int search_slot(struct ctree_root *root, struct key *key,
if
(
ret
)
if
(
ret
)
return
-
1
;
return
-
1
;
ret
=
bin_search
(
c
,
key
,
&
slot
);
ret
=
bin_search
(
c
,
key
,
&
slot
);
if
(
!
is_leaf
(
c
->
header
.
flags
))
{
if
(
!
btrfs_is_leaf
(
c
))
{
if
(
ret
&&
slot
>
0
)
if
(
ret
&&
slot
>
0
)
slot
-=
1
;
slot
-=
1
;
p
->
slots
[
level
]
=
slot
;
p
->
slots
[
level
]
=
slot
;
if
(
ins_len
>
0
&&
if
(
ins_len
>
0
&&
btrfs_header_nritems
(
&
c
->
header
)
==
c
->
header
.
nritems
==
NODEPTRS_PER_BLOCK
)
{
NODEPTRS_PER_BLOCK
)
{
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
)
...
@@ -456,7 +467,7 @@ int search_slot(struct ctree_root *root, struct key *key,
...
@@ -456,7 +467,7 @@ int search_slot(struct ctree_root *root, struct key *key,
goto
again
;
goto
again
;
c
=
&
b
->
node
;
c
=
&
b
->
node
;
slot
=
p
->
slots
[
level
];
slot
=
p
->
slots
[
level
];
BUG_ON
(
c
->
header
.
nritems
==
1
);
BUG_ON
(
btrfs_header_nritems
(
&
c
->
header
)
==
1
);
}
}
b
=
read_tree_block
(
root
,
c
->
blockptrs
[
slot
]);
b
=
read_tree_block
(
root
,
c
->
blockptrs
[
slot
]);
}
else
{
}
else
{
...
@@ -524,8 +535,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
...
@@ -524,8 +535,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
int
dst_nritems
;
int
dst_nritems
;
int
ret
=
0
;
int
ret
=
0
;
src_nritems
=
src
->
header
.
nritems
;
src_nritems
=
btrfs_header_nritems
(
&
src
->
header
)
;
dst_nritems
=
dst
->
header
.
nritems
;
dst_nritems
=
btrfs_header_nritems
(
&
dst
->
header
)
;
push_items
=
NODEPTRS_PER_BLOCK
-
dst_nritems
;
push_items
=
NODEPTRS_PER_BLOCK
-
dst_nritems
;
if
(
push_items
<=
0
)
{
if
(
push_items
<=
0
)
{
return
1
;
return
1
;
...
@@ -544,9 +555,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
...
@@ -544,9 +555,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
memmove
(
src
->
blockptrs
,
src
->
blockptrs
+
push_items
,
memmove
(
src
->
blockptrs
,
src
->
blockptrs
+
push_items
,
(
src_nritems
-
push_items
)
*
sizeof
(
u64
));
(
src_nritems
-
push_items
)
*
sizeof
(
u64
));
}
}
src
->
header
.
nritems
-=
push_items
;
btrfs_set_header_nritems
(
&
src
->
header
,
src_nritems
-
push_items
);
dst
->
header
.
nritems
+=
push_items
;
btrfs_set_header_nritems
(
&
dst
->
header
,
dst_nritems
+
push_items
);
BUG_ON
(
list_empty
(
&
src_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
src_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
dst_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
dst_buf
->
dirty
));
return
ret
;
return
ret
;
...
@@ -573,8 +583,8 @@ static int balance_node_right(struct ctree_root *root,
...
@@ -573,8 +583,8 @@ static int balance_node_right(struct ctree_root *root,
int
dst_nritems
;
int
dst_nritems
;
int
ret
=
0
;
int
ret
=
0
;
src_nritems
=
src
->
header
.
nritems
;
src_nritems
=
btrfs_header_nritems
(
&
src
->
header
)
;
dst_nritems
=
dst
->
header
.
nritems
;
dst_nritems
=
btrfs_header_nritems
(
&
dst
->
header
)
;
push_items
=
NODEPTRS_PER_BLOCK
-
dst_nritems
;
push_items
=
NODEPTRS_PER_BLOCK
-
dst_nritems
;
if
(
push_items
<=
0
)
{
if
(
push_items
<=
0
)
{
return
1
;
return
1
;
...
@@ -596,8 +606,8 @@ static int balance_node_right(struct ctree_root *root,
...
@@ -596,8 +606,8 @@ static int balance_node_right(struct ctree_root *root,
memcpy
(
dst
->
blockptrs
,
src
->
blockptrs
+
src_nritems
-
push_items
,
memcpy
(
dst
->
blockptrs
,
src
->
blockptrs
+
src_nritems
-
push_items
,
push_items
*
sizeof
(
u64
));
push_items
*
sizeof
(
u64
));
src
->
header
.
nritems
-=
push_items
;
btrfs_set_header_nritems
(
&
src
->
header
,
src_nritems
-
push_items
)
;
dst
->
header
.
nritems
+=
push_items
;
btrfs_set_header_nritems
(
&
dst
->
header
,
dst_nritems
+
push_items
)
;
BUG_ON
(
list_empty
(
&
src_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
src_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
dst_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
dst_buf
->
dirty
));
...
@@ -625,12 +635,13 @@ static int insert_new_root(struct ctree_root *root,
...
@@ -625,12 +635,13 @@ static int insert_new_root(struct ctree_root *root,
t
=
alloc_free_block
(
root
);
t
=
alloc_free_block
(
root
);
c
=
&
t
->
node
;
c
=
&
t
->
node
;
memset
(
c
,
0
,
sizeof
(
c
));
memset
(
c
,
0
,
sizeof
(
c
));
c
->
header
.
nritems
=
1
;
btrfs_set_header_nritems
(
&
c
->
header
,
1
);
c
->
header
.
flags
=
node_level
(
level
);
btrfs_set_header_level
(
&
c
->
header
,
level
);
c
->
header
.
blocknr
=
t
->
blocknr
;
btrfs_set_header_blocknr
(
&
c
->
header
,
t
->
blocknr
);
c
->
header
.
parentid
=
root
->
node
->
node
.
header
.
parentid
;
btrfs_set_header_parentid
(
&
c
->
header
,
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
));
lower
=
&
path
->
nodes
[
level
-
1
]
->
node
;
lower
=
&
path
->
nodes
[
level
-
1
]
->
node
;
if
(
is_leaf
(
lower
->
header
.
flags
))
if
(
btrfs_is_leaf
(
lower
))
lower_key
=
&
((
struct
leaf
*
)
lower
)
->
items
[
0
].
key
;
lower_key
=
&
((
struct
leaf
*
)
lower
)
->
items
[
0
].
key
;
else
else
lower_key
=
lower
->
keys
;
lower_key
=
lower
->
keys
;
...
@@ -663,7 +674,7 @@ static int insert_ptr(struct ctree_root *root,
...
@@ -663,7 +674,7 @@ static int insert_ptr(struct ctree_root *root,
BUG_ON
(
!
path
->
nodes
[
level
]);
BUG_ON
(
!
path
->
nodes
[
level
]);
lower
=
&
path
->
nodes
[
level
]
->
node
;
lower
=
&
path
->
nodes
[
level
]
->
node
;
nritems
=
lower
->
header
.
nritems
;
nritems
=
btrfs_header_nritems
(
&
lower
->
header
)
;
if
(
slot
>
nritems
)
if
(
slot
>
nritems
)
BUG
();
BUG
();
if
(
nritems
==
NODEPTRS_PER_BLOCK
)
if
(
nritems
==
NODEPTRS_PER_BLOCK
)
...
@@ -676,7 +687,7 @@ static int insert_ptr(struct ctree_root *root,
...
@@ -676,7 +687,7 @@ static int insert_ptr(struct ctree_root *root,
}
}
memcpy
(
lower
->
keys
+
slot
,
key
,
sizeof
(
struct
key
));
memcpy
(
lower
->
keys
+
slot
,
key
,
sizeof
(
struct
key
));
lower
->
blockptrs
[
slot
]
=
blocknr
;
lower
->
blockptrs
[
slot
]
=
blocknr
;
lower
->
header
.
nritems
++
;
btrfs_set_header_nritems
(
&
lower
->
header
,
nritems
+
1
)
;
if
(
lower
->
keys
[
1
].
objectid
==
0
)
if
(
lower
->
keys
[
1
].
objectid
==
0
)
BUG
();
BUG
();
BUG_ON
(
list_empty
(
&
path
->
nodes
[
level
]
->
dirty
));
BUG_ON
(
list_empty
(
&
path
->
nodes
[
level
]
->
dirty
));
...
@@ -702,6 +713,7 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
...
@@ -702,6 +713,7 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
int
mid
;
int
mid
;
int
ret
;
int
ret
;
int
wret
;
int
wret
;
u32
c_nritems
;
t
=
path
->
nodes
[
level
];
t
=
path
->
nodes
[
level
];
c
=
&
t
->
node
;
c
=
&
t
->
node
;
...
@@ -711,18 +723,20 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
...
@@ -711,18 +723,20 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
}
}
c_nritems
=
btrfs_header_nritems
(
&
c
->
header
);
split_buffer
=
alloc_free_block
(
root
);
split_buffer
=
alloc_free_block
(
root
);
split
=
&
split_buffer
->
node
;
split
=
&
split_buffer
->
node
;
split
->
header
.
flags
=
c
->
header
.
flags
;
btrfs_set_header_flags
(
&
split
->
header
,
btrfs_header_flags
(
&
c
->
header
));
split
->
header
.
blocknr
=
split_buffer
->
blocknr
;
btrfs_set_header_blocknr
(
&
split
->
header
,
split_buffer
->
blocknr
);
split
->
header
.
parentid
=
root
->
node
->
node
.
header
.
parentid
;
btrfs_set_header_parentid
(
&
split
->
header
,
mid
=
(
c
->
header
.
nritems
+
1
)
/
2
;
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
));
mid
=
(
c_nritems
+
1
)
/
2
;
memcpy
(
split
->
keys
,
c
->
keys
+
mid
,
memcpy
(
split
->
keys
,
c
->
keys
+
mid
,
(
c
->
header
.
nritems
-
mid
)
*
sizeof
(
struct
key
));
(
c
_
nritems
-
mid
)
*
sizeof
(
struct
key
));
memcpy
(
split
->
blockptrs
,
c
->
blockptrs
+
mid
,
memcpy
(
split
->
blockptrs
,
c
->
blockptrs
+
mid
,
(
c
->
header
.
nritems
-
mid
)
*
sizeof
(
u64
));
(
c
_
nritems
-
mid
)
*
sizeof
(
u64
));
split
->
header
.
nritems
=
c
->
header
.
nritems
-
mid
;
btrfs_set_header_nritems
(
&
split
->
header
,
c_nritems
-
mid
)
;
c
->
header
.
nritems
=
mid
;
btrfs_set_header_nritems
(
&
c
->
header
,
mid
)
;
ret
=
0
;
ret
=
0
;
BUG_ON
(
list_empty
(
&
t
->
dirty
));
BUG_ON
(
list_empty
(
&
t
->
dirty
));
...
@@ -781,13 +795,15 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
...
@@ -781,13 +795,15 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
int
push_space
=
0
;
int
push_space
=
0
;
int
push_items
=
0
;
int
push_items
=
0
;
struct
item
*
item
;
struct
item
*
item
;
u32
left_nritems
;
u32
right_nritems
;
slot
=
path
->
slots
[
1
];
slot
=
path
->
slots
[
1
];
if
(
!
path
->
nodes
[
1
])
{
if
(
!
path
->
nodes
[
1
])
{
return
1
;
return
1
;
}
}
upper
=
path
->
nodes
[
1
];
upper
=
path
->
nodes
[
1
];
if
(
slot
>=
upper
->
node
.
header
.
nritems
-
1
)
{
if
(
slot
>=
btrfs_header_nritems
(
&
upper
->
node
.
header
)
-
1
)
{
return
1
;
return
1
;
}
}
right_buf
=
read_tree_block
(
root
,
upper
->
node
.
blockptrs
[
slot
+
1
]);
right_buf
=
read_tree_block
(
root
,
upper
->
node
.
blockptrs
[
slot
+
1
]);
...
@@ -806,7 +822,8 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
...
@@ -806,7 +822,8 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
return
1
;
return
1
;
}
}
for
(
i
=
left
->
header
.
nritems
-
1
;
i
>=
0
;
i
--
)
{
left_nritems
=
btrfs_header_nritems
(
&
left
->
header
);
for
(
i
=
left_nritems
-
1
;
i
>=
0
;
i
--
)
{
item
=
left
->
items
+
i
;
item
=
left
->
items
+
i
;
if
(
path
->
slots
[
0
]
==
i
)
if
(
path
->
slots
[
0
]
==
i
)
push_space
+=
data_size
+
sizeof
(
*
item
);
push_space
+=
data_size
+
sizeof
(
*
item
);
...
@@ -819,9 +836,10 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
...
@@ -819,9 +836,10 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
tree_block_release
(
root
,
right_buf
);
tree_block_release
(
root
,
right_buf
);
return
1
;
return
1
;
}
}
right_nritems
=
btrfs_header_nritems
(
&
right
->
header
);
/* push left to right */
/* push left to right */
push_space
=
left
->
items
[
left
->
header
.
nritems
-
push_items
].
offset
+
push_space
=
left
->
items
[
left
_
nritems
-
push_items
].
offset
+
left
->
items
[
left
->
header
.
nritems
-
push_items
].
size
;
left
->
items
[
left
_
nritems
-
push_items
].
size
;
push_space
-=
leaf_data_end
(
left
);
push_space
-=
leaf_data_end
(
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
(
right
->
data
+
leaf_data_end
(
right
)
-
push_space
,
...
@@ -832,19 +850,21 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
...
@@ -832,19 +850,21 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
left
->
data
+
leaf_data_end
(
left
),
left
->
data
+
leaf_data_end
(
left
),
push_space
);
push_space
);
memmove
(
right
->
items
+
push_items
,
right
->
items
,
memmove
(
right
->
items
+
push_items
,
right
->
items
,
right
->
header
.
nritems
*
sizeof
(
struct
item
));
right
_
nritems
*
sizeof
(
struct
item
));
/* copy the items from left to right */
/* copy the items from left to right */
memcpy
(
right
->
items
,
left
->
items
+
left
->
header
.
nritems
-
push_items
,
memcpy
(
right
->
items
,
left
->
items
+
left
_
nritems
-
push_items
,
push_items
*
sizeof
(
struct
item
));
push_items
*
sizeof
(
struct
item
));
/* update the item pointers */
/* update the item pointers */
right
->
header
.
nritems
+=
push_items
;
right_nritems
+=
push_items
;
btrfs_set_header_nritems
(
&
right
->
header
,
right_nritems
);
push_space
=
LEAF_DATA_SIZE
;
push_space
=
LEAF_DATA_SIZE
;
for
(
i
=
0
;
i
<
right
->
header
.
nritems
;
i
++
)
{
for
(
i
=
0
;
i
<
right
_
nritems
;
i
++
)
{
right
->
items
[
i
].
offset
=
push_space
-
right
->
items
[
i
].
size
;
right
->
items
[
i
].
offset
=
push_space
-
right
->
items
[
i
].
size
;
push_space
=
right
->
items
[
i
].
offset
;
push_space
=
right
->
items
[
i
].
offset
;
}
}
left
->
header
.
nritems
-=
push_items
;
left_nritems
-=
push_items
;
btrfs_set_header_nritems
(
&
left
->
header
,
left_nritems
);
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
));
...
@@ -853,8 +873,8 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
...
@@ -853,8 +873,8 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
BUG_ON
(
list_empty
(
&
upper
->
dirty
));
BUG_ON
(
list_empty
(
&
upper
->
dirty
));
/* then fixup the leaf pointer in the path */
/* then fixup the leaf pointer in the path */
if
(
path
->
slots
[
0
]
>=
left
->
header
.
nritems
)
{
if
(
path
->
slots
[
0
]
>=
left
_
nritems
)
{
path
->
slots
[
0
]
-=
left
->
header
.
nritems
;
path
->
slots
[
0
]
-=
left
_
nritems
;
tree_block_release
(
root
,
path
->
nodes
[
0
]);
tree_block_release
(
root
,
path
->
nodes
[
0
]);
path
->
nodes
[
0
]
=
right_buf
;
path
->
nodes
[
0
]
=
right_buf
;
path
->
slots
[
1
]
+=
1
;
path
->
slots
[
1
]
+=
1
;
...
@@ -880,7 +900,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
...
@@ -880,7 +900,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
int
push_space
=
0
;
int
push_space
=
0
;
int
push_items
=
0
;
int
push_items
=
0
;
struct
item
*
item
;
struct
item
*
item
;
int
old_left_nritems
;
u32
old_left_nritems
;
int
ret
=
0
;
int
ret
=
0
;
int
wret
;
int
wret
;
...
@@ -908,7 +928,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
...
@@ -908,7 +928,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
return
1
;
return
1
;
}
}
for
(
i
=
0
;
i
<
right
->
header
.
nritems
;
i
++
)
{
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
)
;
i
++
)
{
item
=
right
->
items
+
i
;
item
=
right
->
items
+
i
;
if
(
path
->
slots
[
0
]
==
i
)
if
(
path
->
slots
[
0
]
==
i
)
push_space
+=
data_size
+
sizeof
(
*
item
);
push_space
+=
data_size
+
sizeof
(
*
item
);
...
@@ -922,31 +942,34 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
...
@@ -922,31 +942,34 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
return
1
;
return
1
;
}
}
/* push data from right to left */
/* push data from right to left */
memcpy
(
left
->
items
+
left
->
header
.
nritems
,
memcpy
(
left
->
items
+
btrfs_header_nritems
(
&
left
->
header
)
,
right
->
items
,
push_items
*
sizeof
(
struct
item
));
right
->
items
,
push_items
*
sizeof
(
struct
item
));
push_space
=
LEAF_DATA_SIZE
-
right
->
items
[
push_items
-
1
].
offset
;
push_space
=
LEAF_DATA_SIZE
-
right
->
items
[
push_items
-
1
].
offset
;
memcpy
(
left
->
data
+
leaf_data_end
(
left
)
-
push_space
,
memcpy
(
left
->
data
+
leaf_data_end
(
left
)
-
push_space
,
right
->
data
+
right
->
items
[
push_items
-
1
].
offset
,
right
->
data
+
right
->
items
[
push_items
-
1
].
offset
,
push_space
);
push_space
);
old_left_nritems
=
left
->
header
.
nritems
;
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
++
)
{
left
->
items
[
i
].
offset
-=
LEAF_DATA_SIZE
-
left
->
items
[
i
].
offset
-=
LEAF_DATA_SIZE
-
left
->
items
[
old_left_nritems
-
1
].
offset
;
left
->
items
[
old_left_nritems
-
1
].
offset
;
}
}
left
->
header
.
nritems
+=
push_items
;
btrfs_set_header_nritems
(
&
left
->
header
,
old_left_nritems
+
push_items
)
;
/* fixup right node */
/* fixup right node */
push_space
=
right
->
items
[
push_items
-
1
].
offset
-
leaf_data_end
(
right
);
push_space
=
right
->
items
[
push_items
-
1
].
offset
-
leaf_data_end
(
right
);
memmove
(
right
->
data
+
LEAF_DATA_SIZE
-
push_space
,
right
->
data
+
memmove
(
right
->
data
+
LEAF_DATA_SIZE
-
push_space
,
right
->
data
+
leaf_data_end
(
right
),
push_space
);
leaf_data_end
(
right
),
push_space
);
memmove
(
right
->
items
,
right
->
items
+
push_items
,
memmove
(
right
->
items
,
right
->
items
+
push_items
,
(
right
->
header
.
nritems
-
push_items
)
*
sizeof
(
struct
item
));
(
btrfs_header_nritems
(
&
right
->
header
)
-
push_items
)
*
right
->
header
.
nritems
-=
push_items
;
sizeof
(
struct
item
));
btrfs_set_header_nritems
(
&
right
->
header
,
btrfs_header_nritems
(
&
right
->
header
)
-
push_items
);
push_space
=
LEAF_DATA_SIZE
;
push_space
=
LEAF_DATA_SIZE
;
for
(
i
=
0
;
i
<
right
->
header
.
nritems
;
i
++
)
{
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
)
;
i
++
)
{
right
->
items
[
i
].
offset
=
push_space
-
right
->
items
[
i
].
size
;
right
->
items
[
i
].
offset
=
push_space
-
right
->
items
[
i
].
size
;
push_space
=
right
->
items
[
i
].
offset
;
push_space
=
right
->
items
[
i
].
offset
;
}
}
...
@@ -983,7 +1006,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
...
@@ -983,7 +1006,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
{
{
struct
tree_buffer
*
l_buf
;
struct
tree_buffer
*
l_buf
;
struct
leaf
*
l
;
struct
leaf
*
l
;
int
nritems
;
u32
nritems
;
int
mid
;
int
mid
;
int
slot
;
int
slot
;
struct
leaf
*
right
;
struct
leaf
*
right
;
...
@@ -1008,7 +1031,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
...
@@ -1008,7 +1031,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
return
ret
;
return
ret
;
}
}
slot
=
path
->
slots
[
0
];
slot
=
path
->
slots
[
0
];
nritems
=
l
->
header
.
nritems
;
nritems
=
btrfs_header_nritems
(
&
l
->
header
)
;
mid
=
(
nritems
+
1
)
/
2
;
mid
=
(
nritems
+
1
)
/
2
;
right_buffer
=
alloc_free_block
(
root
);
right_buffer
=
alloc_free_block
(
root
);
BUG_ON
(
!
right_buffer
);
BUG_ON
(
!
right_buffer
);
...
@@ -1026,10 +1049,11 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
...
@@ -1026,10 +1049,11 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
LEAF_DATA_SIZE
)
LEAF_DATA_SIZE
)
BUG
();
BUG
();
}
}
right
->
header
.
nritems
=
nritems
-
mid
;
btrfs_set_header_nritems
(
&
right
->
header
,
nritems
-
mid
);
right
->
header
.
blocknr
=
right_buffer
->
blocknr
;
btrfs_set_header_blocknr
(
&
right
->
header
,
right_buffer
->
blocknr
);
right
->
header
.
flags
=
node_level
(
0
);
btrfs_set_header_level
(
&
right
->
header
,
0
);
right
->
header
.
parentid
=
root
->
node
->
node
.
header
.
parentid
;
btrfs_set_header_parentid
(
&
right
->
header
,
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
));
data_copy_size
=
l
->
items
[
mid
].
offset
+
l
->
items
[
mid
].
size
-
data_copy_size
=
l
->
items
[
mid
].
offset
+
l
->
items
[
mid
].
size
-
leaf_data_end
(
l
);
leaf_data_end
(
l
);
memcpy
(
right
->
items
,
l
->
items
+
mid
,
memcpy
(
right
->
items
,
l
->
items
+
mid
,
...
@@ -1039,10 +1063,10 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
...
@@ -1039,10 +1063,10 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
rt_data_off
=
LEAF_DATA_SIZE
-
rt_data_off
=
LEAF_DATA_SIZE
-
(
l
->
items
[
mid
].
offset
+
l
->
items
[
mid
].
size
);
(
l
->
items
[
mid
].
offset
+
l
->
items
[
mid
].
size
);
for
(
i
=
0
;
i
<
right
->
header
.
nritems
;
i
++
)
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
)
;
i
++
)
right
->
items
[
i
].
offset
+=
rt_data_off
;
right
->
items
[
i
].
offset
+=
rt_data_off
;
l
->
header
.
nritems
=
mid
;
btrfs_set_header_nritems
(
&
l
->
header
,
mid
)
;
ret
=
0
;
ret
=
0
;
wret
=
insert_ptr
(
root
,
path
,
&
right
->
items
[
0
].
key
,
wret
=
insert_ptr
(
root
,
path
,
&
right
->
items
[
0
].
key
,
right_buffer
->
blocknr
,
path
->
slots
[
1
]
+
1
,
1
);
right_buffer
->
blocknr
,
path
->
slots
[
1
]
+
1
,
1
);
...
@@ -1074,7 +1098,7 @@ int insert_item(struct ctree_root *root, struct key *key,
...
@@ -1074,7 +1098,7 @@ int insert_item(struct ctree_root *root, struct key *key,
int
slot_orig
;
int
slot_orig
;
struct
leaf
*
leaf
;
struct
leaf
*
leaf
;
struct
tree_buffer
*
leaf_buf
;
struct
tree_buffer
*
leaf_buf
;
u
nsigned
int
nritems
;
u
32
nritems
;
unsigned
int
data_end
;
unsigned
int
data_end
;
struct
ctree_path
path
;
struct
ctree_path
path
;
...
@@ -1094,7 +1118,7 @@ int insert_item(struct ctree_root *root, struct key *key,
...
@@ -1094,7 +1118,7 @@ int insert_item(struct ctree_root *root, struct key *key,
leaf_buf
=
path
.
nodes
[
0
];
leaf_buf
=
path
.
nodes
[
0
];
leaf
=
&
leaf_buf
->
leaf
;
leaf
=
&
leaf_buf
->
leaf
;
nritems
=
leaf
->
header
.
nritems
;
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
)
;
data_end
=
leaf_data_end
(
leaf
);
data_end
=
leaf_data_end
(
leaf
);
if
(
leaf_free_space
(
leaf
)
<
sizeof
(
struct
item
)
+
data_size
)
if
(
leaf_free_space
(
leaf
)
<
sizeof
(
struct
item
)
+
data_size
)
...
@@ -1128,7 +1152,7 @@ int insert_item(struct ctree_root *root, struct key *key,
...
@@ -1128,7 +1152,7 @@ int insert_item(struct ctree_root *root, struct key *key,
leaf
->
items
[
slot
].
offset
=
data_end
-
data_size
;
leaf
->
items
[
slot
].
offset
=
data_end
-
data_size
;
leaf
->
items
[
slot
].
size
=
data_size
;
leaf
->
items
[
slot
].
size
=
data_size
;
memcpy
(
leaf
->
data
+
data_end
-
data_size
,
data
,
data_size
);
memcpy
(
leaf
->
data
+
data_end
-
data_size
,
data
,
data_size
);
leaf
->
header
.
nritems
+=
1
;
btrfs_set_header_nritems
(
&
leaf
->
header
,
nritems
+
1
)
;
ret
=
0
;
ret
=
0
;
if
(
slot
==
0
)
if
(
slot
==
0
)
...
@@ -1155,12 +1179,12 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
...
@@ -1155,12 +1179,12 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
{
{
struct
node
*
node
;
struct
node
*
node
;
struct
tree_buffer
*
parent
=
path
->
nodes
[
level
];
struct
tree_buffer
*
parent
=
path
->
nodes
[
level
];
int
nritems
;
u32
nritems
;
int
ret
=
0
;
int
ret
=
0
;
int
wret
;
int
wret
;
node
=
&
parent
->
node
;
node
=
&
parent
->
node
;
nritems
=
node
->
header
.
nritems
;
nritems
=
btrfs_header_nritems
(
&
node
->
header
)
;
if
(
slot
!=
nritems
-
1
)
{
if
(
slot
!=
nritems
-
1
)
{
memmove
(
node
->
keys
+
slot
,
node
->
keys
+
slot
+
1
,
memmove
(
node
->
keys
+
slot
,
node
->
keys
+
slot
+
1
,
sizeof
(
struct
key
)
*
(
nritems
-
slot
-
1
));
sizeof
(
struct
key
)
*
(
nritems
-
slot
-
1
));
...
@@ -1168,11 +1192,12 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
...
@@ -1168,11 +1192,12 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
node
->
blockptrs
+
slot
+
1
,
node
->
blockptrs
+
slot
+
1
,
sizeof
(
u64
)
*
(
nritems
-
slot
-
1
));
sizeof
(
u64
)
*
(
nritems
-
slot
-
1
));
}
}
node
->
header
.
nritems
--
;
nritems
--
;
if
(
node
->
header
.
nritems
==
0
&&
parent
==
root
->
node
)
{
btrfs_set_header_nritems
(
&
node
->
header
,
nritems
);
BUG_ON
(
node_level
(
root
->
node
->
node
.
header
.
flags
)
!=
1
);
if
(
nritems
==
0
&&
parent
==
root
->
node
)
{
BUG_ON
(
btrfs_header_level
(
&
root
->
node
->
node
.
header
)
!=
1
);
/* just turn the root into a leaf and break */
/* just turn the root into a leaf and break */
root
->
node
->
node
.
header
.
flags
=
node_level
(
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
->
keys
,
level
+
1
);
if
(
wret
)
if
(
wret
)
...
@@ -1195,30 +1220,33 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
...
@@ -1195,30 +1220,33 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
int
dsize
;
int
dsize
;
int
ret
=
0
;
int
ret
=
0
;
int
wret
;
int
wret
;
u32
nritems
;
leaf_buf
=
path
->
nodes
[
0
];
leaf_buf
=
path
->
nodes
[
0
];
leaf
=
&
leaf_buf
->
leaf
;
leaf
=
&
leaf_buf
->
leaf
;
slot
=
path
->
slots
[
0
];
slot
=
path
->
slots
[
0
];
doff
=
leaf
->
items
[
slot
].
offset
;
doff
=
leaf
->
items
[
slot
].
offset
;
dsize
=
leaf
->
items
[
slot
].
size
;
dsize
=
leaf
->
items
[
slot
].
size
;
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
if
(
slot
!=
leaf
->
header
.
nritems
-
1
)
{
if
(
slot
!=
nritems
-
1
)
{
int
i
;
int
i
;
int
data_end
=
leaf_data_end
(
leaf
);
int
data_end
=
leaf_data_end
(
leaf
);
memmove
(
leaf
->
data
+
data_end
+
dsize
,
memmove
(
leaf
->
data
+
data_end
+
dsize
,
leaf
->
data
+
data_end
,
leaf
->
data
+
data_end
,
doff
-
data_end
);
doff
-
data_end
);
for
(
i
=
slot
+
1
;
i
<
leaf
->
header
.
nritems
;
i
++
)
for
(
i
=
slot
+
1
;
i
<
nritems
;
i
++
)
leaf
->
items
[
i
].
offset
+=
dsize
;
leaf
->
items
[
i
].
offset
+=
dsize
;
memmove
(
leaf
->
items
+
slot
,
leaf
->
items
+
slot
+
1
,
memmove
(
leaf
->
items
+
slot
,
leaf
->
items
+
slot
+
1
,
sizeof
(
struct
item
)
*
sizeof
(
struct
item
)
*
(
leaf
->
header
.
nritems
-
slot
-
1
));
(
nritems
-
slot
-
1
));
}
}
leaf
->
header
.
nritems
-=
1
;
btrfs_set_header_nritems
(
&
leaf
->
header
,
nritems
-
1
);
nritems
--
;
/* delete the leaf if we've emptied it */
/* delete the leaf if we've emptied it */
if
(
leaf
->
header
.
nritems
==
0
)
{
if
(
nritems
==
0
)
{
if
(
leaf_buf
==
root
->
node
)
{
if
(
leaf_buf
==
root
->
node
)
{
leaf
->
header
.
flags
=
node_level
(
0
);
btrfs_set_header_level
(
&
leaf
->
header
,
0
);
BUG_ON
(
list_empty
(
&
leaf_buf
->
dirty
));
BUG_ON
(
list_empty
(
&
leaf_buf
->
dirty
));
}
else
{
}
else
{
clean_tree_block
(
root
,
leaf_buf
);
clean_tree_block
(
root
,
leaf_buf
);
...
@@ -1230,7 +1258,7 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
...
@@ -1230,7 +1258,7 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
ret
=
wret
;
ret
=
wret
;
}
}
}
else
{
}
else
{
int
used
=
leaf_space_used
(
leaf
,
0
,
leaf
->
header
.
nritems
);
int
used
=
leaf_space_used
(
leaf
,
0
,
nritems
);
if
(
slot
==
0
)
{
if
(
slot
==
0
)
{
wret
=
fixup_low_keys
(
root
,
path
,
wret
=
fixup_low_keys
(
root
,
path
,
&
leaf
->
items
[
0
].
key
,
1
);
&
leaf
->
items
[
0
].
key
,
1
);
...
@@ -1251,12 +1279,12 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
...
@@ -1251,12 +1279,12 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
if
(
wret
<
0
)
if
(
wret
<
0
)
ret
=
wret
;
ret
=
wret
;
if
(
path
->
nodes
[
0
]
==
leaf_buf
&&
if
(
path
->
nodes
[
0
]
==
leaf_buf
&&
leaf
->
header
.
nritems
)
{
btrfs_header_nritems
(
&
leaf
->
header
)
)
{
wret
=
push_leaf_right
(
root
,
path
,
1
);
wret
=
push_leaf_right
(
root
,
path
,
1
);
if
(
wret
<
0
)
if
(
wret
<
0
)
ret
=
wret
;
ret
=
wret
;
}
}
if
(
leaf
->
header
.
nritems
==
0
)
{
if
(
btrfs_header_nritems
(
&
leaf
->
header
)
==
0
)
{
u64
blocknr
=
leaf_buf
->
blocknr
;
u64
blocknr
=
leaf_buf
->
blocknr
;
clean_tree_block
(
root
,
leaf_buf
);
clean_tree_block
(
root
,
leaf_buf
);
wret
=
del_ptr
(
root
,
path
,
1
,
slot
);
wret
=
del_ptr
(
root
,
path
,
1
,
slot
);
...
@@ -1292,7 +1320,7 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
...
@@ -1292,7 +1320,7 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
return
1
;
return
1
;
slot
=
path
->
slots
[
level
]
+
1
;
slot
=
path
->
slots
[
level
]
+
1
;
c
=
path
->
nodes
[
level
];
c
=
path
->
nodes
[
level
];
if
(
slot
>=
c
->
node
.
header
.
nritems
)
{
if
(
slot
>=
btrfs_header_nritems
(
&
c
->
node
.
header
)
)
{
level
++
;
level
++
;
continue
;
continue
;
}
}
...
...
fs/btrfs/ctree.h
View file @
7518a238
...
@@ -35,13 +35,10 @@ struct header {
...
@@ -35,13 +35,10 @@ struct header {
/* generation flags to be added */
/* generation flags to be added */
}
__attribute__
((
__packed__
));
}
__attribute__
((
__packed__
));
#define MAX_LEVEL 8
#define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct header)) / \
#define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct header)) / \
(sizeof(struct key) + sizeof(u64)))
(sizeof(struct key) + sizeof(u64)))
#define MAX_LEVEL 8
#define node_level(f) ((f) & (MAX_LEVEL-1))
#define is_leaf(f) (node_level(f) == 0)
struct
tree_buffer
;
struct
tree_buffer
;
/*
/*
...
@@ -144,6 +141,64 @@ struct ctree_path {
...
@@ -144,6 +141,64 @@ struct ctree_path {
int
slots
[
MAX_LEVEL
];
int
slots
[
MAX_LEVEL
];
};
};
static
inline
u64
btrfs_header_blocknr
(
struct
header
*
h
)
{
return
h
->
blocknr
;
}
static
inline
void
btrfs_set_header_blocknr
(
struct
header
*
h
,
u64
blocknr
)
{
h
->
blocknr
=
blocknr
;
}
static
inline
u64
btrfs_header_parentid
(
struct
header
*
h
)
{
return
h
->
parentid
;
}
static
inline
void
btrfs_set_header_parentid
(
struct
header
*
h
,
u64
parentid
)
{
h
->
parentid
=
parentid
;
}
static
inline
u32
btrfs_header_nritems
(
struct
header
*
h
)
{
return
h
->
nritems
;
}
static
inline
void
btrfs_set_header_nritems
(
struct
header
*
h
,
u32
val
)
{
h
->
nritems
=
val
;
}
static
inline
u32
btrfs_header_flags
(
struct
header
*
h
)
{
return
h
->
flags
;
}
static
inline
void
btrfs_set_header_flags
(
struct
header
*
h
,
u32
val
)
{
h
->
flags
=
val
;
}
static
inline
int
btrfs_header_level
(
struct
header
*
h
)
{
return
btrfs_header_flags
(
h
)
&
(
MAX_LEVEL
-
1
);
}
static
inline
void
btrfs_set_header_level
(
struct
header
*
h
,
int
level
)
{
u32
flags
;
BUG_ON
(
level
>
MAX_LEVEL
);
flags
=
btrfs_header_flags
(
h
)
&
~
(
MAX_LEVEL
-
1
);
btrfs_set_header_flags
(
h
,
flags
|
level
);
}
static
inline
int
btrfs_is_leaf
(
struct
node
*
n
)
{
return
(
btrfs_header_level
(
&
n
->
header
)
==
0
);
}
struct
tree_buffer
*
alloc_free_block
(
struct
ctree_root
*
root
);
struct
tree_buffer
*
alloc_free_block
(
struct
ctree_root
*
root
);
int
btrfs_inc_ref
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
buf
);
int
btrfs_inc_ref
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
buf
);
int
free_extent
(
struct
ctree_root
*
root
,
u64
blocknr
,
u64
num_blocks
);
int
free_extent
(
struct
ctree_root
*
root
,
u64
blocknr
,
u64
num_blocks
);
...
...
fs/btrfs/disk-io.c
View file @
7518a238
...
@@ -15,9 +15,10 @@ int cache_max = 10000;
...
@@ -15,9 +15,10 @@ int cache_max = 10000;
static
int
check_tree_block
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
buf
)
static
int
check_tree_block
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
buf
)
{
{
if
(
buf
->
blocknr
!=
b
uf
->
node
.
header
.
blocknr
)
if
(
buf
->
blocknr
!=
b
trfs_header_blocknr
(
&
buf
->
node
.
header
)
)
BUG
();
BUG
();
if
(
root
->
node
&&
buf
->
node
.
header
.
parentid
!=
root
->
node
->
node
.
header
.
parentid
)
if
(
root
->
node
&&
btrfs_header_parentid
(
&
buf
->
node
.
header
)
!=
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
))
BUG
();
BUG
();
return
0
;
return
0
;
}
}
...
@@ -129,7 +130,7 @@ int write_tree_block(struct ctree_root *root, struct tree_buffer *buf)
...
@@ -129,7 +130,7 @@ int write_tree_block(struct ctree_root *root, struct tree_buffer *buf)
loff_t
offset
=
blocknr
*
CTREE_BLOCKSIZE
;
loff_t
offset
=
blocknr
*
CTREE_BLOCKSIZE
;
int
ret
;
int
ret
;
if
(
buf
->
blocknr
!=
b
uf
->
node
.
header
.
blocknr
)
if
(
buf
->
blocknr
!=
b
trfs_header_blocknr
(
&
buf
->
node
.
header
)
)
BUG
();
BUG
();
ret
=
pwrite
(
root
->
fp
,
&
buf
->
node
,
CTREE_BLOCKSIZE
,
offset
);
ret
=
pwrite
(
root
->
fp
,
&
buf
->
node
,
CTREE_BLOCKSIZE
,
offset
);
if
(
ret
!=
CTREE_BLOCKSIZE
)
if
(
ret
!=
CTREE_BLOCKSIZE
)
...
...
fs/btrfs/extent-tree.c
View file @
7518a238
...
@@ -79,10 +79,10 @@ int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf)
...
@@ -79,10 +79,10 @@ int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf)
if
(
root
==
root
->
extent_root
)
if
(
root
==
root
->
extent_root
)
return
0
;
return
0
;
if
(
is_leaf
(
buf
->
node
.
header
.
flags
))
if
(
btrfs_is_leaf
(
&
buf
->
node
))
return
0
;
return
0
;
for
(
i
=
0
;
i
<
b
uf
->
node
.
header
.
nritems
;
i
++
)
{
for
(
i
=
0
;
i
<
b
trfs_header_nritems
(
&
buf
->
node
.
header
)
;
i
++
)
{
blocknr
=
buf
->
node
.
blockptrs
[
i
];
blocknr
=
buf
->
node
.
blockptrs
[
i
];
inc_block_ref
(
root
,
blocknr
);
inc_block_ref
(
root
,
blocknr
);
}
}
...
@@ -119,7 +119,8 @@ static int finish_current_insert(struct ctree_root *extent_root)
...
@@ -119,7 +119,8 @@ static int finish_current_insert(struct ctree_root *extent_root)
int
ret
;
int
ret
;
extent_item
.
refs
=
1
;
extent_item
.
refs
=
1
;
extent_item
.
owner
=
extent_root
->
node
->
node
.
header
.
parentid
;
extent_item
.
owner
=
btrfs_header_parentid
(
&
extent_root
->
node
->
node
.
header
);
ins
.
offset
=
1
;
ins
.
offset
=
1
;
ins
.
flags
=
0
;
ins
.
flags
=
0
;
...
@@ -269,7 +270,7 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
...
@@ -269,7 +270,7 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
struct
ctree_root
*
root
=
orig_root
->
extent_root
;
struct
ctree_root
*
root
=
orig_root
->
extent_root
;
int
total_needed
=
num_blocks
;
int
total_needed
=
num_blocks
;
total_needed
+=
(
node_level
(
root
->
node
->
node
.
header
.
flags
)
+
1
)
*
3
;
total_needed
+=
(
btrfs_header_level
(
&
root
->
node
->
node
.
header
)
+
1
)
*
3
;
if
(
root
->
last_insert
.
objectid
>
search_start
)
if
(
root
->
last_insert
.
objectid
>
search_start
)
search_start
=
root
->
last_insert
.
objectid
;
search_start
=
root
->
last_insert
.
objectid
;
check_failed:
check_failed:
...
@@ -288,7 +289,7 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
...
@@ -288,7 +289,7 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
while
(
1
)
{
while
(
1
)
{
l
=
&
path
.
nodes
[
0
]
->
leaf
;
l
=
&
path
.
nodes
[
0
]
->
leaf
;
slot
=
path
.
slots
[
0
];
slot
=
path
.
slots
[
0
];
if
(
slot
>=
l
->
header
.
nritems
)
{
if
(
slot
>=
btrfs_header_nritems
(
&
l
->
header
)
)
{
ret
=
next_leaf
(
root
,
&
path
);
ret
=
next_leaf
(
root
,
&
path
);
if
(
ret
==
0
)
if
(
ret
==
0
)
continue
;
continue
;
...
@@ -404,7 +405,7 @@ struct tree_buffer *alloc_free_block(struct ctree_root *root)
...
@@ -404,7 +405,7 @@ struct tree_buffer *alloc_free_block(struct ctree_root *root)
struct
tree_buffer
*
buf
;
struct
tree_buffer
*
buf
;
ret
=
alloc_extent
(
root
,
1
,
0
,
(
unsigned
long
)
-
1
,
ret
=
alloc_extent
(
root
,
1
,
0
,
(
unsigned
long
)
-
1
,
root
->
node
->
node
.
header
.
parentid
,
btrfs_header_parentid
(
&
root
->
node
->
node
.
header
)
,
&
ins
);
&
ins
);
if
(
ret
)
{
if
(
ret
)
{
BUG
();
BUG
();
...
@@ -429,7 +430,8 @@ int walk_down_tree(struct ctree_root *root, struct ctree_path *path, int *level)
...
@@ -429,7 +430,8 @@ int walk_down_tree(struct ctree_root *root, struct ctree_path *path, int *level)
goto
out
;
goto
out
;
while
(
*
level
>
0
)
{
while
(
*
level
>
0
)
{
cur
=
path
->
nodes
[
*
level
];
cur
=
path
->
nodes
[
*
level
];
if
(
path
->
slots
[
*
level
]
>=
cur
->
node
.
header
.
nritems
)
if
(
path
->
slots
[
*
level
]
>=
btrfs_header_nritems
(
&
cur
->
node
.
header
))
break
;
break
;
blocknr
=
cur
->
node
.
blockptrs
[
path
->
slots
[
*
level
]];
blocknr
=
cur
->
node
.
blockptrs
[
path
->
slots
[
*
level
]];
ret
=
lookup_block_ref
(
root
,
blocknr
,
&
refs
);
ret
=
lookup_block_ref
(
root
,
blocknr
,
&
refs
);
...
@@ -444,7 +446,7 @@ int walk_down_tree(struct ctree_root *root, struct ctree_path *path, int *level)
...
@@ -444,7 +446,7 @@ int walk_down_tree(struct ctree_root *root, struct ctree_path *path, int *level)
if
(
path
->
nodes
[
*
level
-
1
])
if
(
path
->
nodes
[
*
level
-
1
])
tree_block_release
(
root
,
path
->
nodes
[
*
level
-
1
]);
tree_block_release
(
root
,
path
->
nodes
[
*
level
-
1
]);
path
->
nodes
[
*
level
-
1
]
=
next
;
path
->
nodes
[
*
level
-
1
]
=
next
;
*
level
=
node_level
(
next
->
node
.
header
.
flags
);
*
level
=
btrfs_header_level
(
&
next
->
node
.
header
);
path
->
slots
[
*
level
]
=
0
;
path
->
slots
[
*
level
]
=
0
;
}
}
out:
out:
...
@@ -463,7 +465,8 @@ int walk_up_tree(struct ctree_root *root, struct ctree_path *path, int *level)
...
@@ -463,7 +465,8 @@ int walk_up_tree(struct ctree_root *root, struct ctree_path *path, int *level)
int
ret
;
int
ret
;
for
(
i
=
*
level
;
i
<
MAX_LEVEL
-
1
&&
path
->
nodes
[
i
];
i
++
)
{
for
(
i
=
*
level
;
i
<
MAX_LEVEL
-
1
&&
path
->
nodes
[
i
];
i
++
)
{
slot
=
path
->
slots
[
i
];
slot
=
path
->
slots
[
i
];
if
(
slot
<
path
->
nodes
[
i
]
->
node
.
header
.
nritems
-
1
)
{
if
(
slot
<
btrfs_header_nritems
(
&
path
->
nodes
[
i
]
->
node
.
header
)
-
1
)
{
path
->
slots
[
i
]
++
;
path
->
slots
[
i
]
++
;
*
level
=
i
;
*
level
=
i
;
return
0
;
return
0
;
...
@@ -489,7 +492,7 @@ int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap)
...
@@ -489,7 +492,7 @@ int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap)
init_path
(
&
path
);
init_path
(
&
path
);
level
=
node_level
(
snap
->
node
.
header
.
flags
);
level
=
btrfs_header_level
(
&
snap
->
node
.
header
);
orig_level
=
level
;
orig_level
=
level
;
path
.
nodes
[
level
]
=
snap
;
path
.
nodes
[
level
]
=
snap
;
path
.
slots
[
level
]
=
0
;
path
.
slots
[
level
]
=
0
;
...
@@ -509,33 +512,3 @@ int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap)
...
@@ -509,33 +512,3 @@ int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap)
return
0
;
return
0
;
}
}
#if 0
int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap)
{
int ret;
int level;
int refs;
u64 blocknr = snap->blocknr;
level = node_level(snap->node.header.flags);
ret = lookup_block_ref(root, snap->blocknr, &refs);
BUG_ON(ret);
if (refs == 1 && level != 0) {
struct node *n = &snap->node;
struct tree_buffer *b;
int i;
for (i = 0; i < n->header.nritems; i++) {
b = read_tree_block(root, n->blockptrs[i]);
/* FIXME, don't recurse here */
ret = btrfs_drop_snapshot(root, b);
BUG_ON(ret);
tree_block_release(root, b);
}
}
ret = free_extent(root, blocknr, 1);
BUG_ON(ret);
return 0;
}
#endif
fs/btrfs/mkfs.c
View file @
7518a238
...
@@ -34,15 +34,15 @@ int mkfs(int fd)
...
@@ -34,15 +34,15 @@ int mkfs(int fd)
/* create leaves for the tree root and extent root */
/* create leaves for the tree root and extent root */
memset
(
&
empty_leaf
,
0
,
sizeof
(
empty_leaf
));
memset
(
&
empty_leaf
,
0
,
sizeof
(
empty_leaf
));
empty_leaf
.
header
.
parentid
=
1
;
btrfs_set_header_parentid
(
&
empty_leaf
.
header
,
1
)
;
empty_leaf
.
header
.
blocknr
=
17
;
btrfs_set_header_blocknr
(
&
empty_leaf
.
header
,
17
)
;
ret
=
pwrite
(
fd
,
&
empty_leaf
,
sizeof
(
empty_leaf
),
17
*
CTREE_BLOCKSIZE
);
ret
=
pwrite
(
fd
,
&
empty_leaf
,
sizeof
(
empty_leaf
),
17
*
CTREE_BLOCKSIZE
);
if
(
ret
!=
sizeof
(
empty_leaf
))
if
(
ret
!=
sizeof
(
empty_leaf
))
return
-
1
;
return
-
1
;
empty_leaf
.
header
.
parentid
=
2
;
btrfs_set_header_parentid
(
&
empty_leaf
.
header
,
2
)
;
empty_leaf
.
header
.
blocknr
=
18
;
btrfs_set_header_blocknr
(
&
empty_leaf
.
header
,
18
)
;
empty_leaf
.
header
.
nritems
=
3
;
btrfs_set_header_nritems
(
&
empty_leaf
.
header
,
3
)
;
/* item1, reserve blocks 0-16 */
/* item1, reserve blocks 0-16 */
item
.
key
.
objectid
=
0
;
item
.
key
.
objectid
=
0
;
...
...
fs/btrfs/print-tree.c
View file @
7518a238
...
@@ -8,11 +8,11 @@
...
@@ -8,11 +8,11 @@
void
print_leaf
(
struct
leaf
*
l
)
void
print_leaf
(
struct
leaf
*
l
)
{
{
int
i
;
int
i
;
int
nr
=
l
->
header
.
nritems
;
u32
nr
=
btrfs_header_nritems
(
&
l
->
header
)
;
struct
item
*
item
;
struct
item
*
item
;
struct
extent_item
*
ei
;
struct
extent_item
*
ei
;
printf
(
"leaf %Lu total ptrs %d free space %d
\n
"
,
l
->
header
.
blocknr
,
nr
,
printf
(
"leaf %Lu total ptrs %d free space %d
\n
"
,
leaf_free_space
(
l
));
btrfs_header_blocknr
(
&
l
->
header
),
nr
,
leaf_free_space
(
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
;
...
@@ -32,22 +32,20 @@ void print_leaf(struct leaf *l)
...
@@ -32,22 +32,20 @@ void print_leaf(struct leaf *l)
void
print_tree
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
t
)
void
print_tree
(
struct
ctree_root
*
root
,
struct
tree_buffer
*
t
)
{
{
int
i
;
int
i
;
int
nr
;
u32
nr
;
struct
node
*
c
;
struct
node
*
c
;
if
(
!
t
)
if
(
!
t
)
return
;
return
;
c
=
&
t
->
node
;
c
=
&
t
->
node
;
nr
=
c
->
header
.
nritems
;
nr
=
btrfs_header_nritems
(
&
c
->
header
);
if
(
c
->
header
.
blocknr
!=
t
->
blocknr
)
if
(
btrfs_is_leaf
(
c
))
{
BUG
();
if
(
is_leaf
(
c
->
header
.
flags
))
{
print_leaf
((
struct
leaf
*
)
c
);
print_leaf
((
struct
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
,
node_level
(
c
->
header
.
flags
),
c
->
header
.
nritems
,
btrfs_header_level
(
&
c
->
header
),
nr
,
(
u32
)
NODEPTRS_PER_BLOCK
-
c
->
header
.
nritems
);
(
u32
)
NODEPTRS_PER_BLOCK
-
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
"
,
...
@@ -60,11 +58,11 @@ void print_tree(struct ctree_root *root, struct tree_buffer *t)
...
@@ -60,11 +58,11 @@ void print_tree(struct ctree_root *root, struct tree_buffer *t)
struct
tree_buffer
*
next_buf
=
read_tree_block
(
root
,
struct
tree_buffer
*
next_buf
=
read_tree_block
(
root
,
c
->
blockptrs
[
i
]);
c
->
blockptrs
[
i
]);
struct
node
*
next
=
&
next_buf
->
node
;
struct
node
*
next
=
&
next_buf
->
node
;
if
(
is_leaf
(
next
->
header
.
flags
)
&&
if
(
btrfs_is_leaf
(
next
)
&&
node_level
(
c
->
header
.
flags
)
!=
1
)
btrfs_header_level
(
&
c
->
header
)
!=
1
)
BUG
();
BUG
();
if
(
node_level
(
next
->
header
.
flags
)
!=
if
(
btrfs_header_level
(
&
next
->
header
)
!=
node_level
(
c
->
header
.
flags
)
-
1
)
btrfs_header_level
(
&
c
->
header
)
-
1
)
BUG
();
BUG
();
print_tree
(
root
,
next_buf
);
print_tree
(
root
,
next_buf
);
tree_block_release
(
root
,
next_buf
);
tree_block_release
(
root
,
next_buf
);
...
...
fs/btrfs/quick-test.c
View file @
7518a238
...
@@ -71,9 +71,10 @@ int main(int ac, char **av) {
...
@@ -71,9 +71,10 @@ int main(int ac, char **av) {
close_ctree
(
root
,
&
super
);
close_ctree
(
root
,
&
super
);
root
=
open_ctree
(
"dbfile"
,
&
super
);
root
=
open_ctree
(
"dbfile"
,
&
super
);
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
,
node_level
(
root
->
node
->
node
.
header
.
flags
),
btrfs_header_level
(
&
root
->
node
->
node
.
header
),
root
->
node
->
node
.
header
.
nritems
,
btrfs_header_nritems
(
&
root
->
node
->
node
.
header
),
NODEPTRS_PER_BLOCK
-
root
->
node
->
node
.
header
.
nritems
);
NODEPTRS_PER_BLOCK
-
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
;
srand
(
55
);
srand
(
55
);
...
@@ -126,7 +127,8 @@ int main(int ac, char **av) {
...
@@ -126,7 +127,8 @@ int main(int ac, char **av) {
release_path
(
root
,
&
path
);
release_path
(
root
,
&
path
);
}
}
printf
(
"starting big long delete run
\n
"
);
printf
(
"starting big long delete run
\n
"
);
while
(
root
->
node
&&
root
->
node
->
node
.
header
.
nritems
>
0
)
{
while
(
root
->
node
&&
btrfs_header_nritems
(
&
root
->
node
->
node
.
header
)
>
0
)
{
struct
leaf
*
leaf
;
struct
leaf
*
leaf
;
int
slot
;
int
slot
;
ins
.
objectid
=
(
u64
)
-
1
;
ins
.
objectid
=
(
u64
)
-
1
;
...
@@ -137,7 +139,7 @@ int main(int ac, char **av) {
...
@@ -137,7 +139,7 @@ int main(int ac, char **av) {
leaf
=
&
path
.
nodes
[
0
]
->
leaf
;
leaf
=
&
path
.
nodes
[
0
]
->
leaf
;
slot
=
path
.
slots
[
0
];
slot
=
path
.
slots
[
0
];
if
(
slot
!=
leaf
->
header
.
nritems
)
if
(
slot
!=
btrfs_header_nritems
(
&
leaf
->
header
)
)
BUG
();
BUG
();
while
(
path
.
slots
[
0
]
>
0
)
{
while
(
path
.
slots
[
0
]
>
0
)
{
path
.
slots
[
0
]
-=
1
;
path
.
slots
[
0
]
-=
1
;
...
...
fs/btrfs/random-test.c
View file @
7518a238
...
@@ -358,8 +358,8 @@ int main(int ac, char **av)
...
@@ -358,8 +358,8 @@ int main(int ac, char **av)
}
}
if
(
i
&&
i
%
5000
==
0
)
{
if
(
i
&&
i
%
5000
==
0
)
{
printf
(
"open & close, root level %d nritems %d
\n
"
,
printf
(
"open & close, root level %d nritems %d
\n
"
,
node_level
(
root
->
node
->
node
.
header
.
flags
),
btrfs_header_level
(
&
root
->
node
->
node
.
header
),
root
->
node
->
node
.
header
.
nritems
);
btrfs_header_nritems
(
&
root
->
node
->
node
.
header
)
);
close_ctree
(
root
,
&
super
);
close_ctree
(
root
,
&
super
);
root
=
open_ctree
(
"dbfile"
,
&
super
);
root
=
open_ctree
(
"dbfile"
,
&
super
);
}
}
...
...
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