Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
FengXiao2002
Linux Imx
提交
96b5179d
L
Linux Imx
项目概览
FengXiao2002
/
Linux Imx
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
Linux Imx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
96b5179d
编写于
10月 15, 2007
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Stop using radix trees for the block group cache
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
f510cfec
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
171 addition
and
223 deletion
+171
-223
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+1
-5
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+2
-2
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+148
-214
fs/btrfs/extent_map.c
fs/btrfs/extent_map.c
+16
-2
fs/btrfs/extent_map.h
fs/btrfs/extent_map.h
+4
-0
未找到文件。
fs/btrfs/ctree.h
浏览文件 @
96b5179d
...
@@ -271,8 +271,6 @@ struct btrfs_csum_item {
...
@@ -271,8 +271,6 @@ struct btrfs_csum_item {
}
__attribute__
((
__packed__
));
}
__attribute__
((
__packed__
));
/* tag for the radix tree of block groups in ram */
/* tag for the radix tree of block groups in ram */
#define BTRFS_BLOCK_GROUP_DIRTY 0
#define BTRFS_BLOCK_GROUP_AVAIL 1
#define BTRFS_BLOCK_GROUP_SIZE (256 * 1024 * 1024)
#define BTRFS_BLOCK_GROUP_SIZE (256 * 1024 * 1024)
...
@@ -285,7 +283,6 @@ struct btrfs_block_group_item {
...
@@ -285,7 +283,6 @@ struct btrfs_block_group_item {
struct
btrfs_block_group_cache
{
struct
btrfs_block_group_cache
{
struct
btrfs_key
key
;
struct
btrfs_key
key
;
struct
btrfs_block_group_item
item
;
struct
btrfs_block_group_item
item
;
struct
radix_tree_root
*
radix
;
u64
first_free
;
u64
first_free
;
u64
last_alloc
;
u64
last_alloc
;
u64
pinned
;
u64
pinned
;
...
@@ -301,10 +298,9 @@ struct btrfs_fs_info {
...
@@ -301,10 +298,9 @@ struct btrfs_fs_info {
struct
radix_tree_root
fs_roots_radix
;
struct
radix_tree_root
fs_roots_radix
;
struct
radix_tree_root
pending_del_radix
;
struct
radix_tree_root
pending_del_radix
;
struct
radix_tree_root
pinned_radix
;
struct
radix_tree_root
pinned_radix
;
struct
radix_tree_root
block_group_radix
;
struct
radix_tree_root
block_group_data_radix
;
struct
radix_tree_root
extent_ins_radix
;
struct
radix_tree_root
extent_ins_radix
;
struct
extent_map_tree
free_space_cache
;
struct
extent_map_tree
free_space_cache
;
struct
extent_map_tree
block_group_cache
;
u64
generation
;
u64
generation
;
u64
last_trans_committed
;
u64
last_trans_committed
;
struct
btrfs_transaction
*
running_transaction
;
struct
btrfs_transaction
*
running_transaction
;
...
...
fs/btrfs/disk-io.c
浏览文件 @
96b5179d
...
@@ -436,8 +436,6 @@ struct btrfs_root *open_ctree(struct super_block *sb)
...
@@ -436,8 +436,6 @@ struct btrfs_root *open_ctree(struct super_block *sb)
init_bit_radix
(
&
fs_info
->
pending_del_radix
);
init_bit_radix
(
&
fs_info
->
pending_del_radix
);
init_bit_radix
(
&
fs_info
->
extent_ins_radix
);
init_bit_radix
(
&
fs_info
->
extent_ins_radix
);
INIT_RADIX_TREE
(
&
fs_info
->
fs_roots_radix
,
GFP_NOFS
);
INIT_RADIX_TREE
(
&
fs_info
->
fs_roots_radix
,
GFP_NOFS
);
INIT_RADIX_TREE
(
&
fs_info
->
block_group_radix
,
GFP_KERNEL
);
INIT_RADIX_TREE
(
&
fs_info
->
block_group_data_radix
,
GFP_KERNEL
);
INIT_LIST_HEAD
(
&
fs_info
->
trans_list
);
INIT_LIST_HEAD
(
&
fs_info
->
trans_list
);
INIT_LIST_HEAD
(
&
fs_info
->
dead_roots
);
INIT_LIST_HEAD
(
&
fs_info
->
dead_roots
);
memset
(
&
fs_info
->
super_kobj
,
0
,
sizeof
(
fs_info
->
super_kobj
));
memset
(
&
fs_info
->
super_kobj
,
0
,
sizeof
(
fs_info
->
super_kobj
));
...
@@ -458,6 +456,8 @@ struct btrfs_root *open_ctree(struct super_block *sb)
...
@@ -458,6 +456,8 @@ struct btrfs_root *open_ctree(struct super_block *sb)
GFP_NOFS
);
GFP_NOFS
);
extent_map_tree_init
(
&
fs_info
->
free_space_cache
,
extent_map_tree_init
(
&
fs_info
->
free_space_cache
,
fs_info
->
btree_inode
->
i_mapping
,
GFP_NOFS
);
fs_info
->
btree_inode
->
i_mapping
,
GFP_NOFS
);
extent_map_tree_init
(
&
fs_info
->
block_group_cache
,
fs_info
->
btree_inode
->
i_mapping
,
GFP_NOFS
);
fs_info
->
do_barriers
=
1
;
fs_info
->
do_barriers
=
1
;
fs_info
->
closing
=
0
;
fs_info
->
closing
=
0
;
...
...
fs/btrfs/extent-tree.c
浏览文件 @
96b5179d
...
@@ -22,6 +22,10 @@
...
@@ -22,6 +22,10 @@
#include "print-tree.h"
#include "print-tree.h"
#include "transaction.h"
#include "transaction.h"
#define BLOCK_GROUP_DATA EXTENT_WRITEBACK
#define BLOCK_GROUP_METADATA EXTENT_UPTODATE
#define BLOCK_GROUP_DIRTY EXTENT_DIRTY
static
int
finish_current_insert
(
struct
btrfs_trans_handle
*
trans
,
struct
static
int
finish_current_insert
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
extent_root
);
btrfs_root
*
extent_root
);
static
int
del_pending_extents
(
struct
btrfs_trans_handle
*
trans
,
struct
static
int
del_pending_extents
(
struct
btrfs_trans_handle
*
trans
,
struct
...
@@ -127,25 +131,31 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
...
@@ -127,25 +131,31 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
btrfs_fs_info
*
info
,
btrfs_fs_info
*
info
,
u64
blocknr
)
u64
blocknr
)
{
{
struct
btrfs_block_group_cache
*
block_group
;
struct
extent_map_tree
*
block_group_cache
;
struct
btrfs_block_group_cache
*
block_group
=
NULL
;
u64
ptr
;
u64
start
;
u64
end
;
int
ret
;
int
ret
;
ret
=
radix_tree_gang_lookup
(
&
info
->
block_group_radix
,
block_group_cache
=
&
info
->
block_group_cache
;
(
void
**
)
&
block_group
,
ret
=
find_first_extent_bit
(
block_group_cache
,
blocknr
,
1
);
blocknr
,
&
start
,
&
end
,
BLOCK_GROUP_DATA
|
BLOCK_GROUP_METADATA
);
if
(
ret
)
{
if
(
ret
)
{
if
(
block_group
->
key
.
objectid
<=
blocknr
&&
blocknr
<=
return
NULL
;
block_group
->
key
.
objectid
+
block_group
->
key
.
offset
)
return
block_group
;
}
ret
=
radix_tree_gang_lookup
(
&
info
->
block_group_data_radix
,
(
void
**
)
&
block_group
,
blocknr
,
1
);
if
(
ret
)
{
if
(
block_group
->
key
.
objectid
<=
blocknr
&&
blocknr
<=
block_group
->
key
.
objectid
+
block_group
->
key
.
offset
)
return
block_group
;
}
}
ret
=
get_state_private
(
block_group_cache
,
start
,
&
ptr
);
if
(
ret
)
return
NULL
;
block_group
=
(
struct
btrfs_block_group_cache
*
)
ptr
;
if
(
block_group
->
key
.
objectid
<=
blocknr
&&
blocknr
<=
block_group
->
key
.
objectid
+
block_group
->
key
.
offset
)
return
block_group
;
return
NULL
;
return
NULL
;
}
}
...
@@ -173,7 +183,7 @@ again:
...
@@ -173,7 +183,7 @@ again:
last
=
end
+
1
;
last
=
end
+
1
;
if
(
end
+
1
-
start
<
num
)
if
(
end
+
1
-
start
<
num
)
continue
;
continue
;
if
(
start
+
num
>
cache
->
key
.
objectid
+
cache
->
key
.
offset
)
if
(
start
+
num
>
=
cache
->
key
.
objectid
+
cache
->
key
.
offset
)
goto
new_group
;
goto
new_group
;
return
start
;
return
start
;
}
}
...
@@ -189,6 +199,7 @@ new_group:
...
@@ -189,6 +199,7 @@ new_group:
cache
=
btrfs_find_block_group
(
root
,
cache
,
cache
=
btrfs_find_block_group
(
root
,
cache
,
last
+
cache
->
key
.
offset
-
1
,
data
,
0
);
last
+
cache
->
key
.
offset
-
1
,
data
,
0
);
*
cache_ret
=
cache
;
*
cache_ret
=
cache
;
last
=
min
(
cache
->
key
.
objectid
,
last
);
goto
again
;
goto
again
;
}
}
...
@@ -204,30 +215,32 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
...
@@ -204,30 +215,32 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
*
hint
,
u64
search_start
,
*
hint
,
u64
search_start
,
int
data
,
int
owner
)
int
data
,
int
owner
)
{
{
struct
btrfs_block_group_cache
*
cache
[
8
];
struct
btrfs_block_group_cache
*
cache
;
struct
extent_map_tree
*
block_group_cache
;
struct
btrfs_block_group_cache
*
found_group
=
NULL
;
struct
btrfs_block_group_cache
*
found_group
=
NULL
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
radix_tree_root
*
radix
;
struct
radix_tree_root
*
swap_radix
;
u64
used
;
u64
used
;
u64
last
=
0
;
u64
last
=
0
;
u64
hint_last
;
u64
hint_last
;
int
i
;
u64
start
;
u64
end
;
u64
free_check
;
u64
ptr
;
int
bit
;
int
ret
;
int
ret
;
int
full_search
=
0
;
int
full_search
=
0
;
int
factor
=
8
;
int
factor
=
8
;
int
data_swap
=
0
;
int
data_swap
=
0
;
block_group_cache
=
&
info
->
block_group_cache
;
if
(
!
owner
)
if
(
!
owner
)
factor
=
5
;
factor
=
5
;
if
(
data
)
{
if
(
data
)
radix
=
&
info
->
block_group_data_radix
;
bit
=
BLOCK_GROUP_DATA
;
swap_radix
=
&
info
->
block_group_radix
;
else
}
else
{
bit
=
BLOCK_GROUP_METADATA
;
radix
=
&
info
->
block_group_radix
;
swap_radix
=
&
info
->
block_group_data_radix
;
}
if
(
search_start
)
{
if
(
search_start
)
{
struct
btrfs_block_group_cache
*
shint
;
struct
btrfs_block_group_cache
*
shint
;
...
@@ -246,12 +259,6 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
...
@@ -246,12 +259,6 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
div_factor
(
hint
->
key
.
offset
,
factor
))
{
div_factor
(
hint
->
key
.
offset
,
factor
))
{
return
hint
;
return
hint
;
}
}
if
(
used
>=
div_factor
(
hint
->
key
.
offset
,
8
))
{
radix_tree_tag_clear
(
radix
,
hint
->
key
.
objectid
+
hint
->
key
.
offset
-
1
,
BTRFS_BLOCK_GROUP_AVAIL
);
}
last
=
hint
->
key
.
offset
*
3
;
last
=
hint
->
key
.
offset
*
3
;
if
(
hint
->
key
.
objectid
>=
last
)
if
(
hint
->
key
.
objectid
>=
last
)
last
=
max
(
search_start
+
hint
->
key
.
offset
-
1
,
last
=
max
(
search_start
+
hint
->
key
.
offset
-
1
,
...
@@ -267,51 +274,29 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
...
@@ -267,51 +274,29 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
last
=
hint_last
;
last
=
hint_last
;
}
}
while
(
1
)
{
ret
=
radix_tree_gang_lookup_tag
(
radix
,
(
void
**
)
cache
,
last
,
ARRAY_SIZE
(
cache
),
BTRFS_BLOCK_GROUP_AVAIL
);
if
(
!
ret
)
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
last
=
cache
[
i
]
->
key
.
objectid
+
cache
[
i
]
->
key
.
offset
;
used
=
btrfs_block_group_used
(
&
cache
[
i
]
->
item
);
if
(
used
+
cache
[
i
]
->
pinned
<
div_factor
(
cache
[
i
]
->
key
.
offset
,
factor
))
{
found_group
=
cache
[
i
];
goto
found
;
}
if
(
used
>=
div_factor
(
cache
[
i
]
->
key
.
offset
,
8
))
{
radix_tree_tag_clear
(
radix
,
cache
[
i
]
->
key
.
objectid
+
cache
[
i
]
->
key
.
offset
-
1
,
BTRFS_BLOCK_GROUP_AVAIL
);
}
}
cond_resched
();
}
last
=
hint_last
;
again:
again:
while
(
1
)
{
while
(
1
)
{
ret
=
radix_tree_gang_lookup
(
radix
,
(
void
**
)
cache
,
ret
=
find_first_extent_bit
(
block_group_cache
,
last
,
last
,
ARRAY_SIZE
(
cache
)
);
&
start
,
&
end
,
bit
);
if
(
!
ret
)
if
(
ret
)
break
;
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
last
=
cache
[
i
]
->
key
.
objectid
+
ret
=
get_state_private
(
block_group_cache
,
start
,
&
ptr
);
cache
[
i
]
->
key
.
offset
;
if
(
ret
)
used
=
btrfs_block_group_used
(
&
cache
[
i
]
->
item
);
break
;
if
(
used
+
cache
[
i
]
->
pinned
<
cache
[
i
]
->
key
.
offset
)
{
found_group
=
cache
[
i
];
cache
=
(
struct
btrfs_block_group_cache
*
)
ptr
;
goto
found
;
last
=
cache
->
key
.
objectid
+
cache
->
key
.
offset
;
}
used
=
btrfs_block_group_used
(
&
cache
->
item
);
if
(
used
>=
cache
[
i
]
->
key
.
offset
)
{
radix_tree_tag_clear
(
radix
,
if
(
full_search
)
cache
[
i
]
->
key
.
objectid
+
free_check
=
cache
->
key
.
offset
;
cache
[
i
]
->
key
.
offset
-
1
,
else
BTRFS_BLOCK_GROUP_AVAIL
);
free_check
=
div_factor
(
cache
->
key
.
offset
,
factor
);
}
if
(
used
+
cache
->
pinned
<
free_check
)
{
found_group
=
cache
;
goto
found
;
}
}
cond_resched
();
cond_resched
();
}
}
...
@@ -321,23 +306,11 @@ again:
...
@@ -321,23 +306,11 @@ again:
goto
again
;
goto
again
;
}
}
if
(
!
data_swap
)
{
if
(
!
data_swap
)
{
struct
radix_tree_root
*
tmp
=
radix
;
data_swap
=
1
;
data_swap
=
1
;
radix
=
swap_radix
;
bit
=
BLOCK_GROUP_DATA
|
BLOCK_GROUP_METADATA
;
swap_radix
=
tmp
;
last
=
search_start
;
last
=
search_start
;
goto
again
;
goto
again
;
}
}
if
(
!
found_group
)
{
ret
=
radix_tree_gang_lookup
(
radix
,
(
void
**
)
&
found_group
,
0
,
1
);
if
(
ret
==
0
)
{
ret
=
radix_tree_gang_lookup
(
swap_radix
,
(
void
**
)
&
found_group
,
0
,
1
);
}
BUG_ON
(
ret
!=
1
);
}
found:
found:
return
found_group
;
return
found_group
;
}
}
...
@@ -538,68 +511,55 @@ fail:
...
@@ -538,68 +511,55 @@ fail:
}
}
static
int
write_dirty_block_radix
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_write_dirty_block_groups
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_root
*
root
)
struct
radix_tree_root
*
radix
)
{
{
struct
btrfs_block_group_cache
*
cache
[
8
];
struct
extent_map_tree
*
block_group_cache
;
struct
btrfs_block_group_cache
*
cache
;
int
ret
;
int
ret
;
int
err
=
0
;
int
err
=
0
;
int
werr
=
0
;
int
werr
=
0
;
int
i
;
struct
btrfs_path
*
path
;
struct
btrfs_path
*
path
;
unsigned
long
off
=
0
;
u64
last
=
0
;
u64
start
;
u64
end
;
u64
ptr
;
block_group_cache
=
&
root
->
fs_info
->
block_group_cache
;
path
=
btrfs_alloc_path
();
path
=
btrfs_alloc_path
();
if
(
!
path
)
if
(
!
path
)
return
-
ENOMEM
;
return
-
ENOMEM
;
while
(
1
)
{
while
(
1
)
{
ret
=
radix_tree_gang_lookup_tag
(
radix
,
(
void
**
)
cache
,
ret
=
find_first_extent_bit
(
block_group_cache
,
last
,
off
,
ARRAY_SIZE
(
cache
),
&
start
,
&
end
,
BLOCK_GROUP_DIRTY
);
BTRFS_BLOCK_GROUP_DIRTY
);
if
(
ret
)
if
(
!
ret
)
break
;
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
err
=
write_one_cache_group
(
trans
,
root
,
path
,
cache
[
i
]);
/*
* if we fail to write the cache group, we want
* to keep it marked dirty in hopes that a later
* write will work
*/
if
(
err
)
{
werr
=
err
;
off
=
cache
[
i
]
->
key
.
objectid
+
cache
[
i
]
->
key
.
offset
;
continue
;
}
radix_tree_tag_clear
(
radix
,
cache
[
i
]
->
key
.
objectid
+
last
=
end
+
1
;
cache
[
i
]
->
key
.
offset
-
1
,
ret
=
get_state_private
(
block_group_cache
,
start
,
&
ptr
);
BTRFS_BLOCK_GROUP_DIRTY
);
if
(
ret
)
break
;
cache
=
(
struct
btrfs_block_group_cache
*
)
ptr
;
err
=
write_one_cache_group
(
trans
,
root
,
path
,
cache
);
/*
* if we fail to write the cache group, we want
* to keep it marked dirty in hopes that a later
* write will work
*/
if
(
err
)
{
werr
=
err
;
continue
;
}
}
clear_extent_bits
(
block_group_cache
,
start
,
end
,
BLOCK_GROUP_DIRTY
,
GFP_NOFS
);
}
}
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
return
werr
;
return
werr
;
}
}
int
btrfs_write_dirty_block_groups
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
)
{
int
ret
;
int
ret2
;
ret
=
write_dirty_block_radix
(
trans
,
root
,
&
root
->
fs_info
->
block_group_radix
);
ret2
=
write_dirty_block_radix
(
trans
,
root
,
&
root
->
fs_info
->
block_group_data_radix
);
if
(
ret
)
return
ret
;
if
(
ret2
)
return
ret2
;
return
0
;
}
static
int
update_block_group
(
struct
btrfs_trans_handle
*
trans
,
static
int
update_block_group
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num
,
int
alloc
,
int
mark_free
,
u64
blocknr
,
u64
num
,
int
alloc
,
int
mark_free
,
...
@@ -610,7 +570,8 @@ static int update_block_group(struct btrfs_trans_handle *trans,
...
@@ -610,7 +570,8 @@ static int update_block_group(struct btrfs_trans_handle *trans,
u64
total
=
num
;
u64
total
=
num
;
u64
old_val
;
u64
old_val
;
u64
block_in_group
;
u64
block_in_group
;
int
ret
;
u64
start
;
u64
end
;
while
(
total
)
{
while
(
total
)
{
cache
=
btrfs_lookup_block_group
(
info
,
blocknr
);
cache
=
btrfs_lookup_block_group
(
info
,
blocknr
);
...
@@ -619,9 +580,10 @@ static int update_block_group(struct btrfs_trans_handle *trans,
...
@@ -619,9 +580,10 @@ static int update_block_group(struct btrfs_trans_handle *trans,
}
}
block_in_group
=
blocknr
-
cache
->
key
.
objectid
;
block_in_group
=
blocknr
-
cache
->
key
.
objectid
;
WARN_ON
(
block_in_group
>
cache
->
key
.
offset
);
WARN_ON
(
block_in_group
>
cache
->
key
.
offset
);
radix_tree_tag_set
(
cache
->
radix
,
cache
->
key
.
objectid
+
start
=
cache
->
key
.
objectid
;
cache
->
key
.
offset
-
1
,
end
=
start
+
cache
->
key
.
offset
-
1
;
BTRFS_BLOCK_GROUP_DIRTY
);
set_extent_bits
(
&
info
->
block_group_cache
,
start
,
end
,
BLOCK_GROUP_DIRTY
,
GFP_NOFS
);
old_val
=
btrfs_block_group_used
(
&
cache
->
item
);
old_val
=
btrfs_block_group_used
(
&
cache
->
item
);
num
=
min
(
total
,
cache
->
key
.
offset
-
block_in_group
);
num
=
min
(
total
,
cache
->
key
.
offset
-
block_in_group
);
...
@@ -630,25 +592,27 @@ static int update_block_group(struct btrfs_trans_handle *trans,
...
@@ -630,25 +592,27 @@ static int update_block_group(struct btrfs_trans_handle *trans,
cache
->
last_alloc
=
blocknr
;
cache
->
last_alloc
=
blocknr
;
if
(
cache
->
data
!=
data
&&
if
(
cache
->
data
!=
data
&&
old_val
<
(
cache
->
key
.
offset
>>
1
))
{
old_val
<
(
cache
->
key
.
offset
>>
1
))
{
cache
->
data
=
data
;
int
bit_to_clear
;
radix_tree_delete
(
cache
->
radix
,
int
bit_to_set
;
cache
->
key
.
objectid
+
cache
->
key
.
offset
-
1
);
cache
->
data
=
data
;
if
(
data
)
{
if
(
data
)
{
cache
->
radix
=
bit_to_clear
=
BLOCK_GROUP_DATA
;
&
info
->
block_group_data_radix
;
bit_to_set
=
BLOCK_GROUP_METADATA
;
cache
->
item
.
flags
|=
cache
->
item
.
flags
|=
BTRFS_BLOCK_GROUP_DATA
;
BTRFS_BLOCK_GROUP_DATA
;
}
else
{
}
else
{
cache
->
radix
=
&
info
->
block_group_radix
;
bit_to_clear
=
BLOCK_GROUP_METADATA
;
bit_to_set
=
BLOCK_GROUP_DATA
;
cache
->
item
.
flags
&=
cache
->
item
.
flags
&=
~
BTRFS_BLOCK_GROUP_DATA
;
~
BTRFS_BLOCK_GROUP_DATA
;
}
}
ret
=
radix_tree_insert
(
cache
->
radix
,
clear_extent_bits
(
&
info
->
block_group_cache
,
cache
->
key
.
objectid
+
start
,
end
,
bit_to_clear
,
cache
->
key
.
offset
-
1
,
GFP_NOFS
);
(
void
*
)
cache
);
set_extent_bits
(
&
info
->
block_group_cache
,
start
,
end
,
bit_to_set
,
GFP_NOFS
);
}
}
old_val
+=
num
;
old_val
+=
num
;
}
else
{
}
else
{
...
@@ -660,13 +624,6 @@ static int update_block_group(struct btrfs_trans_handle *trans,
...
@@ -660,13 +624,6 @@ static int update_block_group(struct btrfs_trans_handle *trans,
blocknr
,
blocknr
+
num
-
1
,
blocknr
,
blocknr
+
num
-
1
,
GFP_NOFS
);
GFP_NOFS
);
}
}
if
(
old_val
<
(
cache
->
key
.
offset
>>
1
)
&&
old_val
+
num
>=
(
cache
->
key
.
offset
>>
1
))
{
radix_tree_tag_set
(
cache
->
radix
,
cache
->
key
.
objectid
+
cache
->
key
.
offset
-
1
,
BTRFS_BLOCK_GROUP_AVAIL
);
}
}
}
btrfs_set_block_group_used
(
&
cache
->
item
,
old_val
);
btrfs_set_block_group_used
(
&
cache
->
item
,
old_val
);
total
-=
num
;
total
-=
num
;
...
@@ -730,11 +687,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
...
@@ -730,11 +687,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
block_group
->
pinned
--
;
block_group
->
pinned
--
;
if
(
gang
[
i
]
<
block_group
->
last_alloc
)
if
(
gang
[
i
]
<
block_group
->
last_alloc
)
block_group
->
last_alloc
=
gang
[
i
];
block_group
->
last_alloc
=
gang
[
i
];
if
(
!
block_group
->
data
)
{
set_extent_dirty
(
free_space_cache
,
set_extent_dirty
(
free_space_cache
,
gang
[
i
],
gang
[
i
],
GFP_NOFS
);
gang
[
i
],
gang
[
i
],
GFP_NOFS
);
}
}
}
}
}
}
}
...
@@ -1059,8 +1013,8 @@ check_failed:
...
@@ -1059,8 +1013,8 @@ check_failed:
ins
->
offset
=
search_end
-
ins
->
objectid
;
ins
->
offset
=
search_end
-
ins
->
objectid
;
goto
check_pending
;
goto
check_pending
;
}
}
btrfs_item_key_to_cpu
(
l
,
&
key
,
slot
);
btrfs_item_key_to_cpu
(
l
,
&
key
,
slot
);
if
(
key
.
objectid
>=
search_start
&&
key
.
objectid
>
last_block
&&
if
(
key
.
objectid
>=
search_start
&&
key
.
objectid
>
last_block
&&
start_found
)
{
start_found
)
{
if
(
last_block
<
search_start
)
if
(
last_block
<
search_start
)
...
@@ -1072,9 +1026,14 @@ check_failed:
...
@@ -1072,9 +1026,14 @@ check_failed:
goto
check_pending
;
goto
check_pending
;
}
}
}
}
if
(
btrfs_key_type
(
&
key
)
!=
BTRFS_EXTENT_ITEM_KEY
)
{
if
(
btrfs_key_type
(
&
key
)
!=
BTRFS_EXTENT_ITEM_KEY
)
if
(
!
start_found
)
{
last_block
=
key
.
objectid
;
start_found
=
1
;
}
goto
next
;
goto
next
;
}
start_found
=
1
;
start_found
=
1
;
last_block
=
key
.
objectid
+
key
.
offset
;
last_block
=
key
.
objectid
+
key
.
offset
;
...
@@ -1120,9 +1079,6 @@ check_pending:
...
@@ -1120,9 +1079,6 @@ check_pending:
}
}
ins
->
offset
=
num_blocks
;
ins
->
offset
=
num_blocks
;
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
if
(
0
&&
ins
->
objectid
!=
cached_search_start
)
{
printk
(
"
\t
cached was %Lu found %Lu
\n
"
,
cached_search_start
,
ins
->
objectid
);
}
return
0
;
return
0
;
new_group:
new_group:
...
@@ -1529,40 +1485,20 @@ out:
...
@@ -1529,40 +1485,20 @@ out:
return
ret
;
return
ret
;
}
}
static
int
free_block_group_radix
(
struct
radix_tree_root
*
radix
)
int
btrfs_free_block_groups
(
struct
btrfs_fs_info
*
info
)
{
{
u64
start
;
u64
end
;
int
ret
;
int
ret
;
struct
btrfs_block_group_cache
*
cache
[
8
];
int
i
;
while
(
1
)
{
while
(
1
)
{
ret
=
radix_tree_gang_lookup
(
radix
,
(
void
**
)
cache
,
0
,
ret
=
find_first_extent_bit
(
&
info
->
block_group_
cache
,
0
,
ARRAY_SIZE
(
cache
)
);
&
start
,
&
end
,
(
unsigned
int
)
-
1
);
if
(
!
ret
)
if
(
ret
)
break
;
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
clear_extent_bits
(
&
info
->
block_group_cache
,
start
,
radix_tree_delete
(
radix
,
cache
[
i
]
->
key
.
objectid
+
end
,
(
unsigned
int
)
-
1
,
GFP_NOFS
);
cache
[
i
]
->
key
.
offset
-
1
);
kfree
(
cache
[
i
]);
}
}
}
return
0
;
}
int
btrfs_free_block_groups
(
struct
btrfs_fs_info
*
info
)
{
int
ret
;
int
ret2
;
u64
start
;
u64
end
;
ret
=
free_block_group_radix
(
&
info
->
block_group_radix
);
ret2
=
free_block_group_radix
(
&
info
->
block_group_data_radix
);
if
(
ret
)
return
ret
;
if
(
ret2
)
return
ret2
;
while
(
1
)
{
while
(
1
)
{
ret
=
find_first_extent_bit
(
&
info
->
free_space_cache
,
0
,
ret
=
find_first_extent_bit
(
&
info
->
free_space_cache
,
0
,
&
start
,
&
end
,
EXTENT_DIRTY
);
&
start
,
&
end
,
EXTENT_DIRTY
);
...
@@ -1579,17 +1515,20 @@ int btrfs_read_block_groups(struct btrfs_root *root)
...
@@ -1579,17 +1515,20 @@ int btrfs_read_block_groups(struct btrfs_root *root)
struct
btrfs_path
*
path
;
struct
btrfs_path
*
path
;
int
ret
;
int
ret
;
int
err
=
0
;
int
err
=
0
;
int
bit
;
struct
btrfs_block_group_cache
*
cache
;
struct
btrfs_block_group_cache
*
cache
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
radix_tree_root
*
radix
;
struct
extent_map_tree
*
block_group_cache
;
struct
btrfs_key
key
;
struct
btrfs_key
key
;
struct
btrfs_key
found_key
;
struct
btrfs_key
found_key
;
struct
extent_buffer
*
leaf
;
struct
extent_buffer
*
leaf
;
u64
group_size_blocks
;
u64
group_size_blocks
;
u64
used
;
block_group_cache
=
&
info
->
block_group_cache
;
group_size_blocks
=
BTRFS_BLOCK_GROUP_SIZE
>>
group_size_blocks
=
BTRFS_BLOCK_GROUP_SIZE
>>
root
->
fs_info
->
sb
->
s_blocksize_bits
;
info
->
sb
->
s_blocksize_bits
;
root
=
info
->
extent_root
;
root
=
info
->
extent_root
;
key
.
objectid
=
0
;
key
.
objectid
=
0
;
key
.
offset
=
group_size_blocks
;
key
.
offset
=
group_size_blocks
;
...
@@ -1617,35 +1556,30 @@ int btrfs_read_block_groups(struct btrfs_root *root)
...
@@ -1617,35 +1556,30 @@ int btrfs_read_block_groups(struct btrfs_root *root)
read_extent_buffer
(
leaf
,
&
cache
->
item
,
read_extent_buffer
(
leaf
,
&
cache
->
item
,
btrfs_item_ptr_offset
(
leaf
,
path
->
slots
[
0
]),
btrfs_item_ptr_offset
(
leaf
,
path
->
slots
[
0
]),
sizeof
(
cache
->
item
));
sizeof
(
cache
->
item
));
if
(
cache
->
item
.
flags
&
BTRFS_BLOCK_GROUP_DATA
)
{
radix
=
&
info
->
block_group_data_radix
;
cache
->
data
=
1
;
}
else
{
radix
=
&
info
->
block_group_radix
;
cache
->
data
=
0
;
}
memcpy
(
&
cache
->
key
,
&
found_key
,
sizeof
(
found_key
));
memcpy
(
&
cache
->
key
,
&
found_key
,
sizeof
(
found_key
));
cache
->
last_alloc
=
cache
->
key
.
objectid
;
cache
->
last_alloc
=
cache
->
key
.
objectid
;
cache
->
first_free
=
cache
->
key
.
objectid
;
cache
->
first_free
=
cache
->
key
.
objectid
;
cache
->
pinned
=
0
;
cache
->
pinned
=
0
;
cache
->
cached
=
0
;
cache
->
cached
=
0
;
cache
->
radix
=
radix
;
key
.
objectid
=
found_key
.
objectid
+
found_key
.
offset
;
key
.
objectid
=
found_key
.
objectid
+
found_key
.
offset
;
btrfs_release_path
(
root
,
path
);
btrfs_release_path
(
root
,
path
);
ret
=
radix_tree_insert
(
radix
,
found_key
.
objectid
+
if
(
cache
->
item
.
flags
&
BTRFS_BLOCK_GROUP_DATA
)
{
found_key
.
offset
-
1
,
bit
=
BLOCK_GROUP_DATA
;
(
void
*
)
cache
);
cache
->
data
=
1
;
BUG_ON
(
ret
);
}
else
{
used
=
btrfs_block_group_used
(
&
cache
->
item
);
bit
=
BLOCK_GROUP_METADATA
;
if
(
used
<
div_factor
(
key
.
offset
,
8
))
{
cache
->
data
=
0
;
radix_tree_tag_set
(
radix
,
found_key
.
objectid
+
found_key
.
offset
-
1
,
BTRFS_BLOCK_GROUP_AVAIL
);
}
}
/* use EXTENT_LOCKED to prevent merging */
set_extent_bits
(
block_group_cache
,
found_key
.
objectid
,
found_key
.
objectid
+
found_key
.
offset
-
1
,
bit
|
EXTENT_LOCKED
,
GFP_NOFS
);
set_state_private
(
block_group_cache
,
found_key
.
objectid
,
(
u64
)
cache
);
if
(
key
.
objectid
>=
if
(
key
.
objectid
>=
btrfs_super_total_blocks
(
&
info
->
super_copy
))
btrfs_super_total_blocks
(
&
info
->
super_copy
))
break
;
break
;
...
...
fs/btrfs/extent_map.c
浏览文件 @
96b5179d
...
@@ -574,7 +574,7 @@ out:
...
@@ -574,7 +574,7 @@ out:
return
set
;
return
set
;
search_again:
search_again:
if
(
start
>
=
end
)
if
(
start
>
end
)
goto
out
;
goto
out
;
write_unlock_irqrestore
(
&
tree
->
lock
,
flags
);
write_unlock_irqrestore
(
&
tree
->
lock
,
flags
);
if
(
mask
&
__GFP_WAIT
)
if
(
mask
&
__GFP_WAIT
)
...
@@ -819,6 +819,21 @@ int set_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end,
...
@@ -819,6 +819,21 @@ int set_extent_dirty(struct extent_map_tree *tree, u64 start, u64 end,
}
}
EXPORT_SYMBOL
(
set_extent_dirty
);
EXPORT_SYMBOL
(
set_extent_dirty
);
int
set_extent_bits
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
int
bits
,
gfp_t
mask
)
{
return
set_extent_bit
(
tree
,
start
,
end
,
bits
,
0
,
NULL
,
mask
);
}
EXPORT_SYMBOL
(
set_extent_bits
);
int
clear_extent_bits
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
int
bits
,
gfp_t
mask
)
{
return
clear_extent_bit
(
tree
,
start
,
end
,
bits
,
0
,
0
,
mask
);
}
EXPORT_SYMBOL
(
clear_extent_bits
);
int
set_extent_delalloc
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
int
set_extent_delalloc
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
gfp_t
mask
)
gfp_t
mask
)
{
{
...
@@ -1138,7 +1153,6 @@ int set_state_private(struct extent_map_tree *tree, u64 start, u64 private)
...
@@ -1138,7 +1153,6 @@ int set_state_private(struct extent_map_tree *tree, u64 start, u64 private)
out:
out:
write_unlock_irq
(
&
tree
->
lock
);
write_unlock_irq
(
&
tree
->
lock
);
return
ret
;
return
ret
;
}
}
int
get_state_private
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
*
private
)
int
get_state_private
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
*
private
)
...
...
fs/btrfs/extent_map.h
浏览文件 @
96b5179d
...
@@ -96,6 +96,10 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page,
...
@@ -96,6 +96,10 @@ int extent_read_full_page(struct extent_map_tree *tree, struct page *page,
void
__init
extent_map_init
(
void
);
void
__init
extent_map_init
(
void
);
void
__exit
extent_map_exit
(
void
);
void
__exit
extent_map_exit
(
void
);
int
extent_clean_all_trees
(
struct
extent_map_tree
*
tree
);
int
extent_clean_all_trees
(
struct
extent_map_tree
*
tree
);
int
clear_extent_bits
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
int
bits
,
gfp_t
mask
);
int
set_extent_bits
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
int
bits
,
gfp_t
mask
);
int
set_extent_uptodate
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
int
set_extent_uptodate
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
gfp_t
mask
);
gfp_t
mask
);
int
set_extent_new
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
int
set_extent_new
(
struct
extent_map_tree
*
tree
,
u64
start
,
u64
end
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录