Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
6b80053d
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
6b80053d
编写于
10月 15, 2007
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Add back the online defragging code
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
09e71a32
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
166 addition
and
106 deletion
+166
-106
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+88
-89
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+60
-0
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+7
-0
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+1
-7
fs/btrfs/extent_map.h
fs/btrfs/extent_map.h
+2
-0
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+2
-2
fs/btrfs/tree-defrag.c
fs/btrfs/tree-defrag.c
+6
-8
未找到文件。
fs/btrfs/ctree.c
浏览文件 @
6b80053d
...
...
@@ -155,55 +155,49 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
return
ret
;
}
#if 0
static int close_blocks(u64 blocknr, u64 other)
static
int
close_blocks
(
u64
blocknr
,
u64
other
,
u32
blocksize
)
{
if (blocknr < other && other -
blocknr <
8)
if
(
blocknr
<
other
&&
other
-
(
blocknr
+
blocksize
)
<
3276
8
)
return
1
;
if (blocknr > other && blocknr -
other <
8)
if
(
blocknr
>
other
&&
blocknr
-
(
other
+
blocksize
)
<
3276
8
)
return
1
;
return
0
;
}
static int should_defrag_leaf(struct extent_buffer *
eb
)
static
int
should_defrag_leaf
(
struct
extent_buffer
*
leaf
)
{
return 0;
struct btrfs_leaf *leaf = btrfs_buffer_leaf(eb);
struct btrfs_disk_key *key;
struct
btrfs_key
key
;
u32
nritems
;
if (b
uffer_defrag(bh
))
if
(
b
trfs_buffer_defrag
(
leaf
))
return
1
;
nritems = btrfs_header_nritems(
&leaf->header
);
nritems
=
btrfs_header_nritems
(
leaf
);
if
(
nritems
==
0
)
return
0
;
key = &leaf->items[0].key
;
if (
btrfs_disk_key_type(key)
== BTRFS_DIR_ITEM_KEY)
btrfs_item_key_to_cpu
(
leaf
,
&
key
,
0
)
;
if
(
key
.
type
==
BTRFS_DIR_ITEM_KEY
)
return
1
;
key = &leaf->items[nritems-1].key;
if (btrfs_disk_key_type(key) == BTRFS_DIR_ITEM_KEY)
btrfs_item_key_to_cpu
(
leaf
,
&
key
,
nritems
-
1
);
if
(
key
.
type
==
BTRFS_DIR_ITEM_KEY
)
return
1
;
if
(
nritems
>
4
)
{
key = &leaf->items[nritems/2].key
;
if (
btrfs_disk_key_type(key)
== BTRFS_DIR_ITEM_KEY)
btrfs_item_key_to_cpu
(
leaf
,
&
key
,
nritems
/
2
)
;
if
(
key
.
type
==
BTRFS_DIR_ITEM_KEY
)
return
1
;
}
return
0
;
}
#endif
int
btrfs_realloc_node
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
extent_buffer
*
parent
,
int
cache_only
,
u64
*
last_ret
)
{
return
0
;
#if 0
struct btrfs_node *parent_node;
struct extent_buffer *cur_eb;
struct extent_buffer *tmp_eb;
struct
extent_buffer
*
cur
;
struct
extent_buffer
*
tmp
;
u64
blocknr
;
u64
search_start
=
*
last_ret
;
u64
last_block
=
0
;
...
...
@@ -214,6 +208,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
int
i
;
int
err
=
0
;
int
parent_level
;
int
uptodate
;
u32
blocksize
;
if
(
trans
->
transaction
!=
root
->
fs_info
->
running_transaction
)
{
printk
(
KERN_CRIT
"trans %Lu running %Lu
\n
"
,
trans
->
transid
,
...
...
@@ -225,12 +221,12 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
root
->
fs_info
->
generation
);
WARN_ON
(
1
);
}
if (buffer_defrag_done(parent))
if
(
b
trfs_b
uffer_defrag_done
(
parent
))
return
0
;
parent_n
ode = btrfs_buffer_node
(parent);
parent_
nritems = btrfs_header_nritems(&parent_node->header
);
parent_level = btrfs_header_level(&parent_node->header
);
parent_n
ritems
=
btrfs_header_nritems
(
parent
);
parent_
level
=
btrfs_header_level
(
parent
);
blocksize
=
btrfs_level_size
(
root
,
parent_level
-
1
);
start_slot
=
0
;
end_slot
=
parent_nritems
;
...
...
@@ -240,56 +236,60 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
for
(
i
=
start_slot
;
i
<
end_slot
;
i
++
)
{
int
close
=
1
;
blocknr = btrfs_node_blockptr(parent
_node
, i);
blocknr
=
btrfs_node_blockptr
(
parent
,
i
);
if
(
last_block
==
0
)
last_block
=
blocknr
;
if
(
i
>
0
)
{
other = btrfs_node_blockptr(parent
_node
, i - 1);
close = close_blocks(blocknr, other);
other
=
btrfs_node_blockptr
(
parent
,
i
-
1
);
close
=
close_blocks
(
blocknr
,
other
,
blocksize
);
}
if
(
close
&&
i
<
end_slot
-
1
)
{
other = btrfs_node_blockptr(parent
_node
, i + 1);
close = close_blocks(blocknr, other);
other
=
btrfs_node_blockptr
(
parent
,
i
+
1
);
close
=
close_blocks
(
blocknr
,
other
,
blocksize
);
}
if
(
close
)
{
last_block
=
blocknr
;
continue
;
}
cur_bh = btrfs_find_tree_block(root, blocknr);
if (!cur_bh || !buffer_uptodate(cur_bh) ||
buffer_locked(cur_bh) ||
(parent_level != 1 && !buffer_defrag(cur_bh)) ||
(parent_level == 1 && !should_defrag_leaf(cur_bh))) {
cur
=
btrfs_find_tree_block
(
root
,
blocknr
,
blocksize
);
if
(
cur
)
uptodate
=
btrfs_buffer_uptodate
(
cur
);
else
uptodate
=
0
;
if
(
!
cur
||
!
uptodate
||
(
parent_level
!=
1
&&
!
btrfs_buffer_defrag
(
cur
))
||
(
parent_level
==
1
&&
!
should_defrag_leaf
(
cur
)))
{
if
(
cache_only
)
{
brelse(cur_bh
);
free_extent_buffer
(
cur
);
continue
;
}
if (!cur_bh || !buffer_uptodate(cur_bh) ||
buffer_locked(cur_bh)) {
brelse(cur_bh);
cur_bh = read_tree_block(root, blocknr);
if
(
!
cur
)
{
cur
=
read_tree_block
(
root
,
blocknr
,
blocksize
);
}
else
if
(
!
uptodate
)
{
btrfs_read_buffer
(
cur
);
}
}
if
(
search_start
==
0
)
search_start = last_block
& ~((u64)65535)
;
search_start
=
last_block
;
err = __btrfs_cow_block(trans, root, cur_bh, parent, i,
&tmp_bh, search_start,
min(8, end_slot - i));
err
=
__btrfs_cow_block
(
trans
,
root
,
cur
,
parent
,
i
,
&
tmp
,
search_start
,
min
(
16
*
blocksize
,
(
end_slot
-
i
)
*
blocksize
));
if
(
err
)
{
brelse(cur_bh
);
free_extent_buffer
(
cur
);
break
;
}
search_start =
bh_blocknr(tmp_bh)
;
search_start
=
tmp
->
start
;
*
last_ret
=
search_start
;
if
(
parent_level
==
1
)
clear_buffer_defrag(tmp_bh
);
set_buffer_defrag_done(tmp_bh
);
brelse(tmp_bh
);
btrfs_clear_buffer_defrag
(
tmp
);
btrfs_set_buffer_defrag_done
(
tmp
);
free_extent_buffer
(
tmp
);
}
return
err
;
#endif
}
/*
...
...
@@ -892,22 +892,17 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
static
void
reada_for_search
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
int
level
,
int
slot
)
{
return
;
#if 0
struct
extent_buffer
*
node
;
int i;
u32
nritems
;
u64 bytenr;
u64
search
;
u64
cluster_start
;
int ret
;
int
nread = 0;
u64
lowest_read
;
u64
highest_read
;
u64
nread
=
0
;
int
direction
=
path
->
reada
;
int level;
struct radix_tree_root found;
unsigned long gang[8];
struct
extent_buffer
*
eb
;
u32
nr
;
u32
blocksize
;
u32
nscan
=
0
;
if
(
level
==
0
)
return
;
...
...
@@ -917,42 +912,46 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
node
=
path
->
nodes
[
level
];
search
=
btrfs_node_blockptr
(
node
,
slot
);
eb = btrfs_find_tree_block(root, search);
blocksize
=
btrfs_level_size
(
root
,
level
-
1
);
eb
=
btrfs_find_tree_block
(
root
,
search
,
blocksize
);
if
(
eb
)
{
free_extent_buffer
(
eb
);
return
;
}
init_bit_radix(&found);
highest_read
=
search
;
lowest_read
=
search
;
nritems
=
btrfs_header_nritems
(
node
);
level = btrfs_header_level(node) - 1;
for (i = slot; i < nritems; i++) {
bytenr = btrfs_node_blockptr(node, i);
set_radix_bit(&found, blocknr);
}
if (direction > 0) {
cluster_start = search - 4;
if (cluster_start > search)
cluster_start = 0;
} else
cluster_start = search + 4;
nr
=
slot
;
while
(
1
)
{
ret = find_first_radix_bit(&found, gang, 0, ARRAY_SIZE(gang));
if (!ret)
break;
for (i = 0; i < ret; i++) {
blocknr = gang[i];
clear_radix_bit(&found, blocknr);
if (path->reada == 1 && nread > 16)
continue;
if (close_blocks(cluster_start, blocknr)) {
readahead_tree_block(root, blocknr);
nread++;
cluster_start = blocknr;
}
if
(
direction
<
0
)
{
if
(
nr
==
0
)
break
;
nr
--
;
}
else
if
(
direction
>
0
)
{
nr
++
;
if
(
nr
>=
nritems
)
break
;
}
search
=
btrfs_node_blockptr
(
node
,
nr
);
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
);
nread
+=
blocksize
;
}
nscan
++
;
if
(
path
->
reada
<
2
&&
(
nread
>
(
256
*
1024
)
||
nscan
>
32
))
break
;
if
(
nread
>
(
1024
*
1024
)
||
nscan
>
128
)
break
;
if
(
search
<
lowest_read
)
lowest_read
=
search
;
if
(
search
>
highest_read
)
highest_read
=
search
;
}
#endif
}
/*
* look for key in the tree. path is filled in with nodes along the way
...
...
fs/btrfs/disk-io.c
浏览文件 @
6b80053d
...
...
@@ -678,3 +678,63 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
balance_dirty_pages_ratelimited_nr
(
root
->
fs_info
->
btree_inode
->
i_mapping
,
nr
);
}
void
btrfs_set_buffer_defrag
(
struct
extent_buffer
*
buf
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
buf
->
pages
[
0
]
->
mapping
->
host
)
->
root
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
set_extent_bits
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
buf
->
start
,
buf
->
start
+
buf
->
len
-
1
,
EXTENT_DEFRAG
,
GFP_NOFS
);
}
void
btrfs_set_buffer_defrag_done
(
struct
extent_buffer
*
buf
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
buf
->
pages
[
0
]
->
mapping
->
host
)
->
root
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
set_extent_bits
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
buf
->
start
,
buf
->
start
+
buf
->
len
-
1
,
EXTENT_DEFRAG_DONE
,
GFP_NOFS
);
}
int
btrfs_buffer_defrag
(
struct
extent_buffer
*
buf
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
buf
->
pages
[
0
]
->
mapping
->
host
)
->
root
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
return
test_range_bit
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
buf
->
start
,
buf
->
start
+
buf
->
len
-
1
,
EXTENT_DEFRAG
,
0
);
}
int
btrfs_buffer_defrag_done
(
struct
extent_buffer
*
buf
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
buf
->
pages
[
0
]
->
mapping
->
host
)
->
root
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
return
test_range_bit
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
buf
->
start
,
buf
->
start
+
buf
->
len
-
1
,
EXTENT_DEFRAG_DONE
,
0
);
}
int
btrfs_clear_buffer_defrag_done
(
struct
extent_buffer
*
buf
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
buf
->
pages
[
0
]
->
mapping
->
host
)
->
root
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
return
clear_extent_bits
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
buf
->
start
,
buf
->
start
+
buf
->
len
-
1
,
EXTENT_DEFRAG_DONE
,
GFP_NOFS
);
}
int
btrfs_clear_buffer_defrag
(
struct
extent_buffer
*
buf
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
buf
->
pages
[
0
]
->
mapping
->
host
)
->
root
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
return
clear_extent_bits
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
buf
->
start
,
buf
->
start
+
buf
->
len
-
1
,
EXTENT_DEFRAG
,
GFP_NOFS
);
}
int
btrfs_read_buffer
(
struct
extent_buffer
*
buf
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
buf
->
pages
[
0
]
->
mapping
->
host
)
->
root
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
return
read_extent_buffer_pages
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
buf
,
1
);
}
fs/btrfs/disk-io.h
浏览文件 @
6b80053d
...
...
@@ -51,4 +51,11 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf);
int
btrfs_set_buffer_uptodate
(
struct
extent_buffer
*
buf
);
int
wait_on_tree_block_writeback
(
struct
btrfs_root
*
root
,
struct
extent_buffer
*
buf
);
void
btrfs_set_buffer_defrag
(
struct
extent_buffer
*
buf
);
void
btrfs_set_buffer_defrag_done
(
struct
extent_buffer
*
buf
);
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
);
#endif
fs/btrfs/extent-tree.c
浏览文件 @
6b80053d
...
...
@@ -1173,13 +1173,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
buf
->
alloc_addr
=
(
unsigned
long
)
__builtin_return_address
(
0
);
set_extent_dirty
(
&
trans
->
transaction
->
dirty_pages
,
buf
->
start
,
buf
->
start
+
buf
->
len
-
1
,
GFP_NOFS
);
/*
set_buffer_checked(buf);
set_buffer_defrag(buf);
*/
/* FIXME!!!!!!!!!!!!!!!!
set_radix_bit(&trans->transaction->dirty_pages, buf->pages[0]->index);
*/
btrfs_set_buffer_defrag
(
buf
);
trans
->
blocks_used
++
;
return
buf
;
}
...
...
fs/btrfs/extent_map.h
浏览文件 @
6b80053d
...
...
@@ -14,6 +14,8 @@
#define EXTENT_LOCKED (1 << 3)
#define EXTENT_NEW (1 << 4)
#define EXTENT_DELALLOC (1 << 5)
#define EXTENT_DEFRAG (1 << 6)
#define EXTENT_DEFRAG_DONE (1 << 7)
#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
...
...
fs/btrfs/transaction.c
浏览文件 @
6b80053d
...
...
@@ -355,7 +355,7 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
return
0
;
trans
=
btrfs_start_transaction
(
root
,
1
);
while
(
0
)
{
while
(
1
)
{
root
->
defrag_running
=
1
;
ret
=
btrfs_defrag_leaves
(
trans
,
root
,
cacheonly
);
nr
=
trans
->
blocks_used
;
...
...
@@ -400,7 +400,7 @@ int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info)
btrfs_defrag_root
(
root
,
1
);
}
}
//
btrfs_defrag_root(info->extent_root, 1);
btrfs_defrag_root
(
info
->
extent_root
,
1
);
return
err
;
}
...
...
fs/btrfs/tree-defrag.c
浏览文件 @
6b80053d
...
...
@@ -116,10 +116,10 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
}
WARN_ON
(
*
level
<
0
);
WARN_ON
(
*
level
>=
BTRFS_MAX_LEVEL
);
#if 0
clear_buffer_defrag(path->nodes[*level]);
clear_buffer_defrag_done(path->nodes[*level]);
#endif
btrfs_
clear_buffer_defrag
(
path
->
nodes
[
*
level
]);
btrfs_
clear_buffer_defrag_done
(
path
->
nodes
[
*
level
]);
free_extent_buffer
(
path
->
nodes
[
*
level
]);
path
->
nodes
[
*
level
]
=
NULL
;
*
level
+=
1
;
...
...
@@ -148,10 +148,8 @@ static int defrag_walk_up(struct btrfs_trans_handle *trans,
root
->
defrag_level
=
i
;
return
0
;
}
else
{
/*
clear_buffer_defrag(path->nodes[*level]);
clear_buffer_defrag_done(path->nodes[*level]);
*/
btrfs_clear_buffer_defrag
(
path
->
nodes
[
*
level
]);
btrfs_clear_buffer_defrag_done
(
path
->
nodes
[
*
level
]);
free_extent_buffer
(
path
->
nodes
[
*
level
]);
path
->
nodes
[
*
level
]
=
NULL
;
*
level
=
i
+
1
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录