Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
74493f7a
Commit
74493f7a
authored
Dec 11, 2007
by
Chris Mason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: Implement generation numbers in block pointers
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
17636e03
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
115 additions
and
8 deletions
+115
-8
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+16
-0
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+41
-6
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+58
-2
No files found.
fs/btrfs/ctree.c
View file @
74493f7a
...
...
@@ -114,6 +114,9 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans,
}
else
{
btrfs_set_node_blockptr
(
parent
,
parent_slot
,
cow
->
start
);
WARN_ON
(
trans
->
transid
==
0
);
btrfs_set_node_ptr_generation
(
parent
,
parent_slot
,
trans
->
transid
);
btrfs_mark_buffer_dirty
(
parent
);
WARN_ON
(
btrfs_header_generation
(
parent
)
!=
trans
->
transid
);
btrfs_free_extent
(
trans
,
root
,
buf
->
start
,
buf
->
len
,
1
);
...
...
@@ -967,6 +970,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
{
struct
extent_buffer
*
b
;
u64
bytenr
;
u64
ptr_gen
;
int
slot
;
int
ret
;
int
level
;
...
...
@@ -1031,10 +1035,18 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
level
==
lowest_level
)
break
;
bytenr
=
btrfs_node_blockptr
(
b
,
slot
);
ptr_gen
=
btrfs_node_ptr_generation
(
b
,
slot
);
if
(
should_reada
)
reada_for_search
(
root
,
p
,
level
,
slot
);
b
=
read_tree_block
(
root
,
bytenr
,
btrfs_level_size
(
root
,
level
-
1
));
if
(
ptr_gen
!=
btrfs_header_generation
(
b
))
{
printk
(
"block %llu bad gen wanted %llu "
"found %llu
\n
"
,
(
unsigned
long
long
)
b
->
start
,
(
unsigned
long
long
)
ptr_gen
,
(
unsigned
long
long
)
btrfs_header_generation
(
b
));
}
}
else
{
p
->
slots
[
level
]
=
slot
;
if
(
ins_len
>
0
&&
btrfs_leaf_free_space
(
root
,
b
)
<
...
...
@@ -1218,6 +1230,8 @@ static int insert_new_root(struct btrfs_trans_handle *trans,
btrfs_node_key
(
lower
,
&
lower_key
,
0
);
btrfs_set_node_key
(
c
,
&
lower_key
,
0
);
btrfs_set_node_blockptr
(
c
,
0
,
lower
->
start
);
WARN_ON
(
btrfs_header_generation
(
lower
)
==
0
);
btrfs_set_node_ptr_generation
(
c
,
0
,
btrfs_header_generation
(
lower
));
btrfs_mark_buffer_dirty
(
c
);
...
...
@@ -1261,6 +1275,8 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
}
btrfs_set_node_key
(
lower
,
key
,
slot
);
btrfs_set_node_blockptr
(
lower
,
slot
,
bytenr
);
WARN_ON
(
trans
->
transid
==
0
);
btrfs_set_node_ptr_generation
(
lower
,
slot
,
trans
->
transid
);
btrfs_set_header_nritems
(
lower
,
nritems
+
1
);
btrfs_mark_buffer_dirty
(
lower
);
return
0
;
...
...
fs/btrfs/ctree.h
View file @
74493f7a
...
...
@@ -110,7 +110,7 @@ struct btrfs_header {
#define BTRFS_MAX_LEVEL 8
#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \
sizeof(struct btrfs_header)) / \
(sizeof(struct btrfs_disk_key) + sizeof(u64)
))
sizeof(struct btrfs_key_ptr
))
#define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header))
#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->leafsize))
#define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \
...
...
@@ -168,6 +168,7 @@ struct btrfs_leaf {
struct
btrfs_key_ptr
{
struct
btrfs_disk_key
key
;
__le64
blockptr
;
__le64
generation
;
}
__attribute__
((
__packed__
));
struct
btrfs_node
{
...
...
@@ -196,7 +197,13 @@ struct btrfs_path {
*/
struct
btrfs_extent_item
{
__le32
refs
;
__le64
owner
;
}
__attribute__
((
__packed__
));
struct
btrfs_extent_ref
{
__le64
root
;
__le64
generation
;
__le64
objectid
;
__le64
offset
;
}
__attribute__
((
__packed__
));
struct
btrfs_inode_timespec
{
...
...
@@ -402,12 +409,13 @@ struct btrfs_root {
* are used, and how many references there are to each block
*/
#define BTRFS_EXTENT_ITEM_KEY 33
#define BTRFS_EXTENT_REF_KEY 34
/*
* block groups give us hints into the extent allocation trees. Which
* blocks are free etc etc
*/
#define BTRFS_BLOCK_GROUP_ITEM_KEY
34
#define BTRFS_BLOCK_GROUP_ITEM_KEY
50
/*
* string items are for debugging. They just store a short string of
...
...
@@ -529,15 +537,25 @@ BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_inode_timespec, nsec, 32);
/* struct btrfs_extent_item */
BTRFS_SETGET_FUNCS
(
extent_refs
,
struct
btrfs_extent_item
,
refs
,
32
);
BTRFS_SETGET_FUNCS
(
extent_owner
,
struct
btrfs_extent_item
,
owner
,
64
);
/* struct btrfs_extent_ref */
BTRFS_SETGET_FUNCS
(
ref_root
,
struct
btrfs_extent_ref
,
root
,
64
);
BTRFS_SETGET_FUNCS
(
ref_generation
,
struct
btrfs_extent_ref
,
generation
,
64
);
BTRFS_SETGET_FUNCS
(
ref_objectid
,
struct
btrfs_extent_ref
,
objectid
,
64
);
BTRFS_SETGET_FUNCS
(
ref_offset
,
struct
btrfs_extent_ref
,
offset
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
ref_root
,
struct
btrfs_extent_ref
,
root
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
ref_generation
,
struct
btrfs_extent_ref
,
generation
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
ref_objectid
,
struct
btrfs_extent_ref
,
objectid
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
ref_offset
,
struct
btrfs_extent_ref
,
offset
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
stack_extent_refs
,
struct
btrfs_extent_item
,
refs
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
stack_extent_owner
,
struct
btrfs_extent_item
,
owner
,
64
);
/* struct btrfs_node */
BTRFS_SETGET_FUNCS
(
key_blockptr
,
struct
btrfs_key_ptr
,
blockptr
,
64
);
BTRFS_SETGET_FUNCS
(
key_generation
,
struct
btrfs_key_ptr
,
generation
,
64
);
static
inline
u64
btrfs_node_blockptr
(
struct
extent_buffer
*
eb
,
int
nr
)
{
...
...
@@ -556,6 +574,23 @@ static inline void btrfs_set_node_blockptr(struct extent_buffer *eb,
btrfs_set_key_blockptr
(
eb
,
(
struct
btrfs_key_ptr
*
)
ptr
,
val
);
}
static
inline
u64
btrfs_node_ptr_generation
(
struct
extent_buffer
*
eb
,
int
nr
)
{
unsigned
long
ptr
;
ptr
=
offsetof
(
struct
btrfs_node
,
ptrs
)
+
sizeof
(
struct
btrfs_key_ptr
)
*
nr
;
return
btrfs_key_generation
(
eb
,
(
struct
btrfs_key_ptr
*
)
ptr
);
}
static
inline
void
btrfs_set_node_ptr_generation
(
struct
extent_buffer
*
eb
,
int
nr
,
u64
val
)
{
unsigned
long
ptr
;
ptr
=
offsetof
(
struct
btrfs_node
,
ptrs
)
+
sizeof
(
struct
btrfs_key_ptr
)
*
nr
;
btrfs_set_key_generation
(
eb
,
(
struct
btrfs_key_ptr
*
)
ptr
,
val
);
}
static
inline
unsigned
long
btrfs_node_key_ptr_offset
(
int
nr
)
{
return
offsetof
(
struct
btrfs_node
,
ptrs
)
+
...
...
fs/btrfs/extent-tree.c
View file @
74493f7a
...
...
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
#include "hash.h"
#include "ctree.h"
#include "disk-io.h"
#include "print-tree.h"
...
...
@@ -352,9 +353,63 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
return
found_group
;
}
static
u64
hash_extent_ref
(
u64
root_objectid
,
u64
root_generation
,
u64
owner
,
u64
owner_offset
)
{
u32
high_crc
=
~
(
u32
)
0
;
u32
low_crc
=
~
(
u32
)
0
;
__le64
lenum
;
lenum
=
cpu_to_le64
(
root_objectid
);
high_crc
=
crc32c
(
high_crc
,
&
lenum
,
sizeof
(
lenum
));
lenum
=
cpu_to_le64
(
root_generation
);
high_crc
=
crc32c
(
high_crc
,
&
lenum
,
sizeof
(
lenum
));
lenum
=
cpu_to_le64
(
owner
);
low_crc
=
crc32c
(
low_crc
,
&
lenum
,
sizeof
(
lenum
));
lenum
=
cpu_to_le64
(
owner_offset
);
low_crc
=
crc32c
(
low_crc
,
&
lenum
,
sizeof
(
lenum
));
return
((
u64
)
high_crc
<<
32
)
|
(
u64
)
low_crc
;
}
int
insert_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
bytenr
,
u64
root_objectid
,
u64
root_generation
,
u64
owner
,
u64
owner_offset
)
{
u64
hash
;
struct
btrfs_key
key
;
struct
btrfs_extent_ref
ref
;
struct
extent_buffer
*
l
;
struct
btrfs_extent_item
*
item
;
int
ret
;
btrfs_set_stack_ref_root
(
&
ref
,
root_objectid
);
btrfs_set_stack_ref_generation
(
&
ref
,
root_generation
);
btrfs_set_stack_ref_objectid
(
&
ref
,
owner
);
btrfs_set_stack_ref_offset
(
&
ref
,
owner_offset
);
ret
=
btrfs_name_hash
(
&
ref
,
sizeof
(
ref
),
&
hash
);
key
.
offset
=
hash
;
key
.
objectid
=
bytenr
;
key
.
type
=
BTRFS_EXTENT_REF_KEY
;
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
key
,
sizeof
(
ref
));
while
(
ret
==
-
EEXIST
)
{
}
}
int
btrfs_inc_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
bytenr
,
u64
num_bytes
)
u64
bytenr
,
u64
num_bytes
,
u64
root_objectid
,
u64
root_generation
,
u64
owner
,
u64
owner_offset
)
{
struct
btrfs_path
*
path
;
int
ret
;
...
...
@@ -386,9 +441,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
path
);
btrfs_free_path
(
path
);
finish_current_insert
(
trans
,
root
->
fs_info
->
extent_root
);
del_pending_extents
(
trans
,
root
->
fs_info
->
extent_root
);
btrfs_free_path
(
path
);
return
0
;
}
...
...
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