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
ca7a79ad
Commit
ca7a79ad
authored
May 12, 2008
by
Chris Mason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: Pass down the expected generation number when reading tree blocks
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
188de649
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
55 additions
and
64 deletions
+55
-64
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+21
-34
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+13
-17
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+4
-3
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+9
-6
fs/btrfs/print-tree.c
fs/btrfs/print-tree.c
+2
-1
fs/btrfs/tree-defrag.c
fs/btrfs/tree-defrag.c
+6
-3
No files found.
fs/btrfs/ctree.c
View file @
ca7a79ad
...
...
@@ -302,6 +302,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
struct
extent_buffer
*
cur
;
struct
extent_buffer
*
tmp
;
u64
blocknr
;
u64
gen
;
u64
search_start
=
*
last_ret
;
u64
last_block
=
0
;
u64
other
;
...
...
@@ -354,6 +355,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
progress_passed
=
1
;
blocknr
=
btrfs_node_blockptr
(
parent
,
i
);
gen
=
btrfs_node_ptr_generation
(
parent
,
i
);
if
(
last_block
==
0
)
last_block
=
blocknr
;
...
...
@@ -387,15 +389,14 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
}
if
(
!
cur
)
{
cur
=
read_tree_block
(
root
,
blocknr
,
blocksize
);
blocksize
,
gen
);
}
else
if
(
!
uptodate
)
{
btrfs_read_buffer
(
cur
);
btrfs_read_buffer
(
cur
,
gen
);
}
}
if
(
search_start
==
0
)
search_start
=
last_block
;
btrfs_verify_block_csum
(
root
,
cur
);
err
=
__btrfs_cow_block
(
trans
,
root
,
cur
,
parent
,
i
,
&
tmp
,
search_start
,
min
(
16
*
blocksize
,
...
...
@@ -696,12 +697,17 @@ static int bin_search(struct extent_buffer *eb, struct btrfs_key *key,
static
struct
extent_buffer
*
read_node_slot
(
struct
btrfs_root
*
root
,
struct
extent_buffer
*
parent
,
int
slot
)
{
int
level
=
btrfs_header_level
(
parent
);
if
(
slot
<
0
)
return
NULL
;
if
(
slot
>=
btrfs_header_nritems
(
parent
))
return
NULL
;
BUG_ON
(
level
==
0
);
return
read_tree_block
(
root
,
btrfs_node_blockptr
(
parent
,
slot
),
btrfs_level_size
(
root
,
btrfs_header_level
(
parent
)
-
1
));
btrfs_level_size
(
root
,
level
-
1
),
btrfs_node_ptr_generation
(
parent
,
slot
));
}
static
int
balance_level
(
struct
btrfs_trans_handle
*
trans
,
...
...
@@ -1076,7 +1082,8 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
if
((
search
>=
lowest_read
&&
search
<=
highest_read
)
||
(
search
<
lowest_read
&&
lowest_read
-
search
<=
32768
)
||
(
search
>
highest_read
&&
search
-
highest_read
<=
32768
))
{
readahead_tree_block
(
root
,
search
,
blocksize
);
readahead_tree_block
(
root
,
search
,
blocksize
,
btrfs_node_ptr_generation
(
node
,
nr
));
nread
+=
blocksize
;
}
nscan
++
;
...
...
@@ -1109,8 +1116,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
ins_len
,
int
cow
)
{
struct
extent_buffer
*
b
;
u64
bytenr
;
u64
ptr_gen
;
int
slot
;
int
ret
;
int
level
;
...
...
@@ -1174,20 +1179,12 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
/* this is only true while dropping a snapshot */
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
,
key
->
objectid
);
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
));
}
b
=
read_node_slot
(
root
,
b
,
slot
);
}
else
{
p
->
slots
[
level
]
=
slot
;
if
(
ins_len
>
0
&&
btrfs_leaf_free_space
(
root
,
b
)
<
...
...
@@ -1650,8 +1647,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
slot
>=
btrfs_header_nritems
(
upper
)
-
1
)
return
1
;
right
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
upper
,
slot
+
1
),
root
->
leafsize
);
right
=
read_node_slot
(
root
,
upper
,
slot
+
1
);
free_space
=
btrfs_leaf_free_space
(
root
,
right
);
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
free_extent_buffer
(
right
);
...
...
@@ -1826,8 +1822,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
return
1
;
}
left
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
path
->
nodes
[
1
],
slot
-
1
),
root
->
leafsize
);
left
=
read_node_slot
(
root
,
path
->
nodes
[
1
],
slot
-
1
);
free_space
=
btrfs_leaf_free_space
(
root
,
left
);
if
(
free_space
<
data_size
+
sizeof
(
struct
btrfs_item
))
{
free_extent_buffer
(
left
);
...
...
@@ -2742,7 +2737,6 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
*/
int
btrfs_prev_leaf
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
)
{
u64
bytenr
;
int
slot
;
int
level
=
1
;
struct
extent_buffer
*
c
;
...
...
@@ -2762,12 +2756,10 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
}
slot
--
;
bytenr
=
btrfs_node_blockptr
(
c
,
slot
);
if
(
next
)
free_extent_buffer
(
next
);
next
=
read_tree_block
(
root
,
bytenr
,
btrfs_level_size
(
root
,
level
-
1
));
next
=
read_node_slot
(
root
,
c
,
slot
);
break
;
}
path
->
slots
[
level
]
=
slot
;
...
...
@@ -2782,8 +2774,7 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
path
->
slots
[
level
]
=
slot
;
if
(
!
level
)
break
;
next
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
next
,
slot
),
btrfs_level_size
(
root
,
level
-
1
));
next
=
read_node_slot
(
root
,
next
,
slot
);
}
return
0
;
}
...
...
@@ -2797,7 +2788,6 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
{
int
slot
;
int
level
=
1
;
u64
bytenr
;
struct
extent_buffer
*
c
;
struct
extent_buffer
*
next
=
NULL
;
...
...
@@ -2814,15 +2804,13 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
continue
;
}
bytenr
=
btrfs_node_blockptr
(
c
,
slot
);
if
(
next
)
free_extent_buffer
(
next
);
if
(
path
->
reada
)
reada_for_search
(
root
,
path
,
level
,
slot
,
0
);
next
=
read_tree_block
(
root
,
bytenr
,
btrfs_level_size
(
root
,
level
-
1
));
next
=
read_node_slot
(
root
,
c
,
slot
);
break
;
}
path
->
slots
[
level
]
=
slot
;
...
...
@@ -2836,8 +2824,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
break
;
if
(
path
->
reada
)
reada_for_search
(
root
,
path
,
level
,
0
,
0
);
next
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
next
,
0
),
btrfs_level_size
(
root
,
level
-
1
));
next
=
read_node_slot
(
root
,
next
,
0
);
}
return
0
;
}
...
...
fs/btrfs/disk-io.c
View file @
ca7a79ad
...
...
@@ -207,7 +207,7 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
static
int
btree_read_extent_buffer_pages
(
struct
btrfs_root
*
root
,
struct
extent_buffer
*
eb
,
u64
start
)
u64
start
,
u64
parent_transid
)
{
struct
extent_io_tree
*
io_tree
;
int
ret
;
...
...
@@ -254,7 +254,8 @@ int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
WARN_ON
(
1
);
}
eb
=
alloc_extent_buffer
(
tree
,
start
,
len
,
page
,
GFP_NOFS
);
ret
=
btree_read_extent_buffer_pages
(
root
,
eb
,
start
+
PAGE_CACHE_SIZE
);
ret
=
btree_read_extent_buffer_pages
(
root
,
eb
,
start
+
PAGE_CACHE_SIZE
,
btrfs_header_generation
(
eb
));
BUG_ON
(
ret
);
btrfs_clear_buffer_defrag
(
eb
);
found_start
=
btrfs_header_bytenr
(
eb
);
...
...
@@ -562,7 +563,8 @@ static struct address_space_operations btree_aops = {
.
sync_page
=
block_sync_page
,
};
int
readahead_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
)
int
readahead_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
,
u64
parent_transid
)
{
struct
extent_buffer
*
buf
=
NULL
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
...
...
@@ -592,12 +594,6 @@ static int close_all_devices(struct btrfs_fs_info *fs_info)
return
0
;
}
int
btrfs_verify_block_csum
(
struct
btrfs_root
*
root
,
struct
extent_buffer
*
buf
)
{
return
btrfs_buffer_uptodate
(
buf
);
}
struct
extent_buffer
*
btrfs_find_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
)
{
...
...
@@ -621,7 +617,7 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
struct
extent_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
)
u32
blocksize
,
u64
parent_transid
)
{
struct
extent_buffer
*
buf
=
NULL
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
...
...
@@ -634,7 +630,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
if
(
!
buf
)
return
NULL
;
ret
=
btree_read_extent_buffer_pages
(
root
,
buf
,
0
);
ret
=
btree_read_extent_buffer_pages
(
root
,
buf
,
0
,
parent_transid
);
if
(
ret
==
0
)
{
buf
->
flags
|=
EXTENT_UPTODATE
;
...
...
@@ -715,7 +711,7 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
blocksize
=
btrfs_level_size
(
root
,
btrfs_root_level
(
&
root
->
root_item
));
root
->
node
=
read_tree_block
(
root
,
btrfs_root_bytenr
(
&
root
->
root_item
),
blocksize
);
blocksize
,
0
);
BUG_ON
(
!
root
->
node
);
return
0
;
}
...
...
@@ -771,7 +767,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
}
blocksize
=
btrfs_level_size
(
root
,
btrfs_root_level
(
&
root
->
root_item
));
root
->
node
=
read_tree_block
(
root
,
btrfs_root_bytenr
(
&
root
->
root_item
),
blocksize
);
blocksize
,
0
);
BUG_ON
(
!
root
->
node
);
insert:
root
->
ref_cows
=
1
;
...
...
@@ -1288,7 +1284,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
chunk_root
->
node
=
read_tree_block
(
chunk_root
,
btrfs_super_chunk_root
(
disk_super
),
blocksize
);
blocksize
,
0
);
BUG_ON
(
!
chunk_root
->
node
);
read_extent_buffer
(
chunk_root
->
node
,
fs_info
->
chunk_tree_uuid
,
...
...
@@ -1304,7 +1300,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
tree_root
->
node
=
read_tree_block
(
tree_root
,
btrfs_super_root
(
disk_super
),
blocksize
);
blocksize
,
0
);
if
(
!
tree_root
->
node
)
goto
fail_sb_buffer
;
...
...
@@ -1732,11 +1728,11 @@ int btrfs_clear_buffer_defrag(struct extent_buffer *buf)
EXTENT_DEFRAG
,
GFP_NOFS
);
}
int
btrfs_read_buffer
(
struct
extent_buffer
*
buf
)
int
btrfs_read_buffer
(
struct
extent_buffer
*
buf
,
u64
parent_transid
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
buf
->
first_page
->
mapping
->
host
)
->
root
;
int
ret
;
ret
=
btree_read_extent_buffer_pages
(
root
,
buf
,
0
);
ret
=
btree_read_extent_buffer_pages
(
root
,
buf
,
0
,
parent_transid
);
if
(
ret
==
0
)
{
buf
->
flags
|=
EXTENT_UPTODATE
;
}
...
...
fs/btrfs/disk-io.h
View file @
ca7a79ad
...
...
@@ -25,8 +25,9 @@ struct btrfs_device;
struct
btrfs_fs_devices
;
struct
extent_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
);
int
readahead_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
);
u32
blocksize
,
u64
parent_transid
);
int
readahead_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
,
u64
parent_transid
);
struct
extent_buffer
*
btrfs_find_create_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
);
int
clean_tree_block
(
struct
btrfs_trans_handle
*
trans
,
...
...
@@ -65,7 +66,7 @@ int btrfs_buffer_defrag(struct extent_buffer *buf);
int
btrfs_buffer_defrag_done
(
struct
extent_buffer
*
buf
);
int
btrfs_clear_buffer_defrag
(
struct
extent_buffer
*
buf
);
int
btrfs_clear_buffer_defrag_done
(
struct
extent_buffer
*
buf
);
int
btrfs_read_buffer
(
struct
extent_buffer
*
buf
);
int
btrfs_read_buffer
(
struct
extent_buffer
*
buf
,
u64
parent_transid
);
u32
btrfs_csum_data
(
struct
btrfs_root
*
root
,
char
*
data
,
u32
seed
,
size_t
len
);
void
btrfs_csum_final
(
u32
crc
,
char
*
result
);
void
btrfs_throttle
(
struct
btrfs_root
*
root
);
...
...
fs/btrfs/extent-tree.c
View file @
ca7a79ad
...
...
@@ -1338,7 +1338,8 @@ static int finish_current_insert(struct btrfs_trans_handle *trans,
&
extent_item
,
sizeof
(
extent_item
));
clear_extent_bits
(
&
info
->
extent_ins
,
start
,
end
,
EXTENT_LOCKED
,
GFP_NOFS
);
eb
=
read_tree_block
(
extent_root
,
ins
.
objectid
,
ins
.
offset
);
eb
=
read_tree_block
(
extent_root
,
ins
.
objectid
,
ins
.
offset
,
trans
->
transid
);
level
=
btrfs_header_level
(
eb
);
if
(
level
==
0
)
{
btrfs_item_key
(
eb
,
&
first
,
0
);
...
...
@@ -2076,7 +2077,8 @@ static void noinline reada_walk_down(struct btrfs_root *root,
}
}
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
readahead_tree_block
(
root
,
bytenr
,
blocksize
);
ret
=
readahead_tree_block
(
root
,
bytenr
,
blocksize
,
btrfs_node_ptr_generation
(
node
,
i
));
last
=
bytenr
+
blocksize
;
cond_resched
();
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
...
...
@@ -2096,6 +2098,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
u64
root_owner
;
u64
root_gen
;
u64
bytenr
;
u64
ptr_gen
;
struct
extent_buffer
*
next
;
struct
extent_buffer
*
cur
;
struct
extent_buffer
*
parent
;
...
...
@@ -2132,6 +2135,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
break
;
}
bytenr
=
btrfs_node_blockptr
(
cur
,
path
->
slots
[
*
level
]);
ptr_gen
=
btrfs_node_ptr_generation
(
cur
,
path
->
slots
[
*
level
]);
blocksize
=
btrfs_level_size
(
root
,
*
level
-
1
);
ret
=
lookup_extent_ref
(
trans
,
root
,
bytenr
,
blocksize
,
&
refs
);
BUG_ON
(
ret
);
...
...
@@ -2152,7 +2156,8 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
reada_walk_down
(
root
,
cur
,
path
->
slots
[
*
level
]);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
next
=
read_tree_block
(
root
,
bytenr
,
blocksize
);
next
=
read_tree_block
(
root
,
bytenr
,
blocksize
,
ptr_gen
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
/* we've dropped the lock, double check */
...
...
@@ -2173,8 +2178,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
BUG_ON
(
ret
);
continue
;
}
}
else
if
(
next
)
{
btrfs_verify_block_csum
(
root
,
next
);
}
WARN_ON
(
*
level
<=
0
);
if
(
path
->
nodes
[
*
level
-
1
])
...
...
@@ -2609,7 +2612,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
int
i
;
eb
=
read_tree_block
(
found_root
,
extent_key
->
objectid
,
extent_key
->
offset
);
extent_key
->
offset
,
0
);
level
=
btrfs_header_level
(
eb
);
if
(
level
==
0
)
...
...
fs/btrfs/print-tree.c
View file @
ca7a79ad
...
...
@@ -186,7 +186,8 @@ void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c)
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
struct
extent_buffer
*
next
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
c
,
i
),
btrfs_level_size
(
root
,
level
-
1
));
btrfs_level_size
(
root
,
level
-
1
),
btrfs_node_ptr_generation
(
c
,
i
));
if
(
btrfs_is_leaf
(
next
)
&&
btrfs_header_level
(
c
)
!=
1
)
BUG
();
...
...
fs/btrfs/tree-defrag.c
View file @
ca7a79ad
...
...
@@ -28,6 +28,7 @@ static void reada_defrag(struct btrfs_root *root,
int
i
;
u32
nritems
;
u64
bytenr
;
u64
gen
;
u32
blocksize
;
int
ret
;
...
...
@@ -35,7 +36,8 @@ static void reada_defrag(struct btrfs_root *root,
nritems
=
btrfs_header_nritems
(
node
);
for
(
i
=
0
;
i
<
nritems
;
i
++
)
{
bytenr
=
btrfs_node_blockptr
(
node
,
i
);
ret
=
readahead_tree_block
(
root
,
bytenr
,
blocksize
);
gen
=
btrfs_node_ptr_generation
(
node
,
i
);
ret
=
readahead_tree_block
(
root
,
bytenr
,
blocksize
,
gen
);
if
(
ret
)
break
;
}
...
...
@@ -101,10 +103,11 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
path
->
slots
[
*
level
]
++
;
continue
;
}
btrfs_verify_block_csum
(
root
,
next
);
}
else
{
next
=
read_tree_block
(
root
,
bytenr
,
btrfs_level_size
(
root
,
*
level
-
1
));
btrfs_level_size
(
root
,
*
level
-
1
),
btrfs_node_ptr_generation
(
cur
,
path
->
slots
[
*
level
]));
}
ret
=
btrfs_cow_block
(
trans
,
root
,
next
,
path
->
nodes
[
*
level
],
path
->
slots
[
*
level
],
&
next
);
...
...
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