Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
bf4ef679
L
linux
项目概览
xiphi1978
/
linux
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bf4ef679
编写于
5月 08, 2008
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Properly find the root for snapshotted blocks during chunk relocation
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
a061fc8d
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
156 addition
and
12 deletion
+156
-12
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+2
-0
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+109
-11
fs/btrfs/root-tree.c
fs/btrfs/root-tree.c
+45
-1
未找到文件。
fs/btrfs/ctree.h
浏览文件 @
bf4ef679
...
...
@@ -1459,6 +1459,8 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
*
item
);
int
btrfs_find_last_root
(
struct
btrfs_root
*
root
,
u64
objectid
,
struct
btrfs_root_item
*
item
,
struct
btrfs_key
*
key
);
int
btrfs_search_root
(
struct
btrfs_root
*
root
,
u64
search_start
,
u64
*
found_objectid
);
int
btrfs_find_dead_roots
(
struct
btrfs_root
*
root
,
u64
objectid
,
struct
btrfs_root
*
latest_root
);
/* dir-item.c */
...
...
fs/btrfs/extent-tree.c
浏览文件 @
bf4ef679
...
...
@@ -2421,6 +2421,85 @@ static int noinline relocate_inode_pages(struct inode *inode, u64 start,
goto
out_unlock
;
}
/*
* The back references tell us which tree holds a ref on a block,
* but it is possible for the tree root field in the reference to
* reflect the original root before a snapshot was made. In this
* case we should search through all the children of a given root
* to find potential holders of references on a block.
*
* Instead, we do something a little less fancy and just search
* all the roots for a given key/block combination.
*/
static
int
find_root_for_ref
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
key0
,
int
level
,
int
file_key
,
struct
btrfs_root
**
found_root
,
u64
bytenr
)
{
struct
btrfs_key
root_location
;
struct
btrfs_root
*
cur_root
=
*
found_root
;
struct
btrfs_file_extent_item
*
file_extent
;
u64
root_search_start
=
BTRFS_FS_TREE_OBJECTID
;
u64
found_bytenr
;
int
ret
;
int
i
;
root_location
.
offset
=
(
u64
)
-
1
;
root_location
.
type
=
BTRFS_ROOT_ITEM_KEY
;
path
->
lowest_level
=
level
;
path
->
reada
=
0
;
while
(
1
)
{
ret
=
btrfs_search_slot
(
NULL
,
cur_root
,
key0
,
path
,
0
,
0
);
found_bytenr
=
0
;
if
(
ret
==
0
&&
file_key
)
{
struct
extent_buffer
*
leaf
=
path
->
nodes
[
0
];
file_extent
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
if
(
btrfs_file_extent_type
(
leaf
,
file_extent
)
==
BTRFS_FILE_EXTENT_REG
)
{
found_bytenr
=
btrfs_file_extent_disk_bytenr
(
leaf
,
file_extent
);
}
}
else
if
(
ret
==
0
)
{
if
(
path
->
nodes
[
level
])
found_bytenr
=
path
->
nodes
[
level
]
->
start
;
}
for
(
i
=
level
;
i
<
BTRFS_MAX_LEVEL
;
i
++
)
{
if
(
!
path
->
nodes
[
i
])
break
;
free_extent_buffer
(
path
->
nodes
[
i
]);
path
->
nodes
[
i
]
=
NULL
;
}
btrfs_release_path
(
cur_root
,
path
);
if
(
found_bytenr
==
bytenr
)
{
*
found_root
=
cur_root
;
ret
=
0
;
goto
out
;
}
ret
=
btrfs_search_root
(
root
->
fs_info
->
tree_root
,
root_search_start
,
&
root_search_start
);
if
(
ret
)
break
;
root_location
.
objectid
=
root_search_start
;
cur_root
=
btrfs_read_fs_root_no_name
(
root
->
fs_info
,
&
root_location
);
if
(
!
cur_root
)
{
ret
=
1
;
break
;
}
}
out:
path
->
lowest_level
=
0
;
return
ret
;
}
/*
* note, this releases the path
*/
...
...
@@ -2430,13 +2509,15 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
{
struct
inode
*
inode
;
struct
btrfs_root
*
found_root
;
struct
btrfs_key
*
root_location
;
struct
btrfs_key
root_location
;
struct
btrfs_key
found_key
;
struct
btrfs_extent_ref
*
ref
;
u64
ref_root
;
u64
ref_gen
;
u64
ref_objectid
;
u64
ref_offset
;
int
ret
;
int
level
;
ref
=
btrfs_item_ptr
(
path
->
nodes
[
0
],
path
->
slots
[
0
],
struct
btrfs_extent_ref
);
...
...
@@ -2446,20 +2527,30 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
ref_offset
=
btrfs_ref_offset
(
path
->
nodes
[
0
],
ref
);
btrfs_release_path
(
extent_root
,
path
);
root_location
=
kmalloc
(
sizeof
(
*
root_location
),
GFP_NOFS
);
root_location
->
objectid
=
ref_root
;
root_location
.
objectid
=
ref_root
;
if
(
ref_gen
==
0
)
root_location
->
offset
=
0
;
root_location
.
offset
=
0
;
else
root_location
->
offset
=
(
u64
)
-
1
;
root_location
->
type
=
BTRFS_ROOT_ITEM_KEY
;
root_location
.
offset
=
(
u64
)
-
1
;
root_location
.
type
=
BTRFS_ROOT_ITEM_KEY
;
found_root
=
btrfs_read_fs_root_no_name
(
extent_root
->
fs_info
,
root_location
);
&
root_location
);
BUG_ON
(
!
found_root
);
kfree
(
root_location
);
if
(
ref_objectid
>=
BTRFS_FIRST_FREE_OBJECTID
)
{
found_key
.
objectid
=
ref_objectid
;
found_key
.
type
=
BTRFS_EXTENT_DATA_KEY
;
found_key
.
offset
=
ref_offset
;
level
=
0
;
ret
=
find_root_for_ref
(
extent_root
,
path
,
&
found_key
,
level
,
1
,
&
found_root
,
extent_key
->
objectid
);
if
(
ret
)
goto
out
;
mutex_unlock
(
&
extent_root
->
fs_info
->
fs_mutex
);
inode
=
btrfs_iget_locked
(
extent_root
->
fs_info
->
sb
,
ref_objectid
,
found_root
);
...
...
@@ -2485,12 +2576,9 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
mutex_lock
(
&
extent_root
->
fs_info
->
fs_mutex
);
}
else
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_key
found_key
;
struct
extent_buffer
*
eb
;
int
level
;
int
i
;
trans
=
btrfs_start_transaction
(
found_root
,
1
);
eb
=
read_tree_block
(
found_root
,
extent_key
->
objectid
,
extent_key
->
offset
);
level
=
btrfs_header_level
(
eb
);
...
...
@@ -2502,6 +2590,15 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
free_extent_buffer
(
eb
);
ret
=
find_root_for_ref
(
extent_root
,
path
,
&
found_key
,
level
,
0
,
&
found_root
,
extent_key
->
objectid
);
if
(
ret
)
goto
out
;
trans
=
btrfs_start_transaction
(
found_root
,
1
);
path
->
lowest_level
=
level
;
path
->
reada
=
2
;
ret
=
btrfs_search_slot
(
trans
,
found_root
,
&
found_key
,
path
,
...
...
@@ -2578,6 +2675,7 @@ static int noinline relocate_one_extent(struct btrfs_root *extent_root,
}
if
(
ret
<
0
)
goto
out
;
leaf
=
path
->
nodes
[
0
];
}
btrfs_item_key_to_cpu
(
leaf
,
&
found_key
,
path
->
slots
[
0
]);
...
...
fs/btrfs/root-tree.c
浏览文件 @
bf4ef679
...
...
@@ -21,6 +21,51 @@
#include "disk-io.h"
#include "print-tree.h"
/*
* returns 0 on finding something, 1 if no more roots are there
* and < 0 on error
*/
int
btrfs_search_root
(
struct
btrfs_root
*
root
,
u64
search_start
,
u64
*
found_objectid
)
{
struct
btrfs_path
*
path
;
struct
btrfs_key
search_key
;
int
ret
;
root
=
root
->
fs_info
->
tree_root
;
search_key
.
objectid
=
search_start
;
search_key
.
type
=
(
u8
)
-
1
;
search_key
.
offset
=
(
u64
)
-
1
;
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
again:
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
search_key
,
path
,
0
,
0
);
if
(
ret
<
0
)
goto
out
;
if
(
ret
==
0
)
{
ret
=
1
;
goto
out
;
}
if
(
path
->
slots
[
0
]
>=
btrfs_header_nritems
(
path
->
nodes
[
0
]))
{
ret
=
btrfs_next_leaf
(
root
,
path
);
if
(
ret
)
goto
out
;
}
btrfs_item_key_to_cpu
(
path
->
nodes
[
0
],
&
search_key
,
path
->
slots
[
0
]);
if
(
search_key
.
type
!=
BTRFS_ROOT_ITEM_KEY
)
{
search_key
.
offset
++
;
btrfs_release_path
(
root
,
path
);
goto
again
;
}
ret
=
0
;
*
found_objectid
=
search_key
.
objectid
;
out:
btrfs_free_path
(
path
);
return
ret
;
}
int
btrfs_find_last_root
(
struct
btrfs_root
*
root
,
u64
objectid
,
struct
btrfs_root_item
*
item
,
struct
btrfs_key
*
key
)
{
...
...
@@ -55,7 +100,6 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
memcpy
(
key
,
&
found_key
,
sizeof
(
found_key
));
ret
=
0
;
out:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录