Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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,
...
@@ -114,6 +114,9 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans,
}
else
{
}
else
{
btrfs_set_node_blockptr
(
parent
,
parent_slot
,
btrfs_set_node_blockptr
(
parent
,
parent_slot
,
cow
->
start
);
cow
->
start
);
WARN_ON
(
trans
->
transid
==
0
);
btrfs_set_node_ptr_generation
(
parent
,
parent_slot
,
trans
->
transid
);
btrfs_mark_buffer_dirty
(
parent
);
btrfs_mark_buffer_dirty
(
parent
);
WARN_ON
(
btrfs_header_generation
(
parent
)
!=
trans
->
transid
);
WARN_ON
(
btrfs_header_generation
(
parent
)
!=
trans
->
transid
);
btrfs_free_extent
(
trans
,
root
,
buf
->
start
,
buf
->
len
,
1
);
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
...
@@ -967,6 +970,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
{
{
struct
extent_buffer
*
b
;
struct
extent_buffer
*
b
;
u64
bytenr
;
u64
bytenr
;
u64
ptr_gen
;
int
slot
;
int
slot
;
int
ret
;
int
ret
;
int
level
;
int
level
;
...
@@ -1031,10 +1035,18 @@ again:
...
@@ -1031,10 +1035,18 @@ again:
if
(
level
==
lowest_level
)
if
(
level
==
lowest_level
)
break
;
break
;
bytenr
=
btrfs_node_blockptr
(
b
,
slot
);
bytenr
=
btrfs_node_blockptr
(
b
,
slot
);
ptr_gen
=
btrfs_node_ptr_generation
(
b
,
slot
);
if
(
should_reada
)
if
(
should_reada
)
reada_for_search
(
root
,
p
,
level
,
slot
);
reada_for_search
(
root
,
p
,
level
,
slot
);
b
=
read_tree_block
(
root
,
bytenr
,
b
=
read_tree_block
(
root
,
bytenr
,
btrfs_level_size
(
root
,
level
-
1
));
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
{
}
else
{
p
->
slots
[
level
]
=
slot
;
p
->
slots
[
level
]
=
slot
;
if
(
ins_len
>
0
&&
btrfs_leaf_free_space
(
root
,
b
)
<
if
(
ins_len
>
0
&&
btrfs_leaf_free_space
(
root
,
b
)
<
...
@@ -1218,6 +1230,8 @@ static int insert_new_root(struct btrfs_trans_handle *trans,
...
@@ -1218,6 +1230,8 @@ static int insert_new_root(struct btrfs_trans_handle *trans,
btrfs_node_key
(
lower
,
&
lower_key
,
0
);
btrfs_node_key
(
lower
,
&
lower_key
,
0
);
btrfs_set_node_key
(
c
,
&
lower_key
,
0
);
btrfs_set_node_key
(
c
,
&
lower_key
,
0
);
btrfs_set_node_blockptr
(
c
,
0
,
lower
->
start
);
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
);
btrfs_mark_buffer_dirty
(
c
);
...
@@ -1261,6 +1275,8 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -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_key
(
lower
,
key
,
slot
);
btrfs_set_node_blockptr
(
lower
,
slot
,
bytenr
);
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_set_header_nritems
(
lower
,
nritems
+
1
);
btrfs_mark_buffer_dirty
(
lower
);
btrfs_mark_buffer_dirty
(
lower
);
return
0
;
return
0
;
...
...
fs/btrfs/ctree.h
View file @
74493f7a
...
@@ -110,7 +110,7 @@ struct btrfs_header {
...
@@ -110,7 +110,7 @@ struct btrfs_header {
#define BTRFS_MAX_LEVEL 8
#define BTRFS_MAX_LEVEL 8
#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \
#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->nodesize - \
sizeof(struct btrfs_header)) / \
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(bs) ((bs) - sizeof(struct btrfs_header))
#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->leafsize))
#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->leafsize))
#define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \
#define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \
...
@@ -168,6 +168,7 @@ struct btrfs_leaf {
...
@@ -168,6 +168,7 @@ struct btrfs_leaf {
struct
btrfs_key_ptr
{
struct
btrfs_key_ptr
{
struct
btrfs_disk_key
key
;
struct
btrfs_disk_key
key
;
__le64
blockptr
;
__le64
blockptr
;
__le64
generation
;
}
__attribute__
((
__packed__
));
}
__attribute__
((
__packed__
));
struct
btrfs_node
{
struct
btrfs_node
{
...
@@ -196,7 +197,13 @@ struct btrfs_path {
...
@@ -196,7 +197,13 @@ struct btrfs_path {
*/
*/
struct
btrfs_extent_item
{
struct
btrfs_extent_item
{
__le32
refs
;
__le32
refs
;
__le64
owner
;
}
__attribute__
((
__packed__
));
struct
btrfs_extent_ref
{
__le64
root
;
__le64
generation
;
__le64
objectid
;
__le64
offset
;
}
__attribute__
((
__packed__
));
}
__attribute__
((
__packed__
));
struct
btrfs_inode_timespec
{
struct
btrfs_inode_timespec
{
...
@@ -402,12 +409,13 @@ struct btrfs_root {
...
@@ -402,12 +409,13 @@ struct btrfs_root {
* are used, and how many references there are to each block
* are used, and how many references there are to each block
*/
*/
#define BTRFS_EXTENT_ITEM_KEY 33
#define BTRFS_EXTENT_ITEM_KEY 33
#define BTRFS_EXTENT_REF_KEY 34
/*
/*
* block groups give us hints into the extent allocation trees. Which
* block groups give us hints into the extent allocation trees. Which
* blocks are free etc etc
* 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
* 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);
...
@@ -529,15 +537,25 @@ BTRFS_SETGET_FUNCS(timespec_nsec, struct btrfs_inode_timespec, nsec, 32);
/* struct btrfs_extent_item */
/* struct btrfs_extent_item */
BTRFS_SETGET_FUNCS
(
extent_refs
,
struct
btrfs_extent_item
,
refs
,
32
);
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
,
BTRFS_SETGET_STACK_FUNCS
(
stack_extent_refs
,
struct
btrfs_extent_item
,
refs
,
32
);
refs
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
stack_extent_owner
,
struct
btrfs_extent_item
,
owner
,
64
);
/* struct btrfs_node */
/* struct btrfs_node */
BTRFS_SETGET_FUNCS
(
key_blockptr
,
struct
btrfs_key_ptr
,
blockptr
,
64
);
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
)
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,
...
@@ -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
);
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
)
static
inline
unsigned
long
btrfs_node_key_ptr_offset
(
int
nr
)
{
{
return
offsetof
(
struct
btrfs_node
,
ptrs
)
+
return
offsetof
(
struct
btrfs_node
,
ptrs
)
+
...
...
fs/btrfs/extent-tree.c
View file @
74493f7a
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
*/
*/
#include <linux/sched.h>
#include <linux/sched.h>
#include "hash.h"
#include "ctree.h"
#include "ctree.h"
#include "disk-io.h"
#include "disk-io.h"
#include "print-tree.h"
#include "print-tree.h"
...
@@ -352,9 +353,63 @@ found:
...
@@ -352,9 +353,63 @@ found:
return
found_group
;
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
,
int
btrfs_inc_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
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
;
struct
btrfs_path
*
path
;
int
ret
;
int
ret
;
...
@@ -386,9 +441,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
...
@@ -386,9 +441,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
path
);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
path
);
btrfs_free_path
(
path
);
finish_current_insert
(
trans
,
root
->
fs_info
->
extent_root
);
finish_current_insert
(
trans
,
root
->
fs_info
->
extent_root
);
del_pending_extents
(
trans
,
root
->
fs_info
->
extent_root
);
del_pending_extents
(
trans
,
root
->
fs_info
->
extent_root
);
btrfs_free_path
(
path
);
return
0
;
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