Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gsplhtlxg
clone-Linux
提交
a40a90a0
C
clone-Linux
项目概览
gsplhtlxg
/
clone-Linux
通知
2
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
clone-Linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a40a90a0
编写于
4月 18, 2008
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Fix chunk allocation when some devices don't have enough room for stripes
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
9b3f68b9
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
29 addition
and
16 deletion
+29
-16
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+29
-16
未找到文件。
fs/btrfs/volumes.c
浏览文件 @
a40a90a0
...
@@ -664,7 +664,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
...
@@ -664,7 +664,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
struct
extent_map_tree
*
em_tree
;
struct
extent_map_tree
*
em_tree
;
struct
map_lookup
*
map
;
struct
map_lookup
*
map
;
struct
extent_map
*
em
;
struct
extent_map
*
em
;
int
min_
chunk_size
=
8
*
1024
*
1024
;
int
min_
stripe_size
=
1
*
1024
*
1024
;
u64
physical
;
u64
physical
;
u64
calc_size
=
1024
*
1024
*
1024
;
u64
calc_size
=
1024
*
1024
*
1024
;
u64
max_chunk_size
=
calc_size
;
u64
max_chunk_size
=
calc_size
;
...
@@ -673,6 +673,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
...
@@ -673,6 +673,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
u64
max_avail
=
0
;
u64
max_avail
=
0
;
u64
percent_max
;
u64
percent_max
;
int
num_stripes
=
1
;
int
num_stripes
=
1
;
int
min_stripes
=
1
;
int
sub_stripes
=
0
;
int
sub_stripes
=
0
;
int
looped
=
0
;
int
looped
=
0
;
int
ret
;
int
ret
;
...
@@ -683,15 +684,20 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
...
@@ -683,15 +684,20 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
if
(
list_empty
(
dev_list
))
if
(
list_empty
(
dev_list
))
return
-
ENOSPC
;
return
-
ENOSPC
;
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID0
))
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID0
))
{
num_stripes
=
btrfs_super_num_devices
(
&
info
->
super_copy
);
num_stripes
=
btrfs_super_num_devices
(
&
info
->
super_copy
);
if
(
type
&
(
BTRFS_BLOCK_GROUP_DUP
))
min_stripes
=
2
;
}
if
(
type
&
(
BTRFS_BLOCK_GROUP_DUP
))
{
num_stripes
=
2
;
num_stripes
=
2
;
min_stripes
=
2
;
}
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID1
))
{
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID1
))
{
num_stripes
=
min_t
(
u64
,
2
,
num_stripes
=
min_t
(
u64
,
2
,
btrfs_super_num_devices
(
&
info
->
super_copy
));
btrfs_super_num_devices
(
&
info
->
super_copy
));
if
(
num_stripes
<
2
)
if
(
num_stripes
<
2
)
return
-
ENOSPC
;
return
-
ENOSPC
;
min_stripes
=
2
;
}
}
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID10
))
{
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID10
))
{
num_stripes
=
btrfs_super_num_devices
(
&
info
->
super_copy
);
num_stripes
=
btrfs_super_num_devices
(
&
info
->
super_copy
);
...
@@ -699,22 +705,26 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
...
@@ -699,22 +705,26 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
return
-
ENOSPC
;
return
-
ENOSPC
;
num_stripes
&=
~
(
u32
)
1
;
num_stripes
&=
~
(
u32
)
1
;
sub_stripes
=
2
;
sub_stripes
=
2
;
min_stripes
=
4
;
}
}
if
(
type
&
BTRFS_BLOCK_GROUP_DATA
)
{
if
(
type
&
BTRFS_BLOCK_GROUP_DATA
)
{
max_chunk_size
=
10
*
calc_size
;
max_chunk_size
=
10
*
calc_size
;
min_
chunk_size
=
256
*
1024
*
1024
;
min_
stripe_size
=
64
*
1024
*
1024
;
}
else
if
(
type
&
BTRFS_BLOCK_GROUP_METADATA
)
{
}
else
if
(
type
&
BTRFS_BLOCK_GROUP_METADATA
)
{
max_chunk_size
=
4
*
calc_size
;
max_chunk_size
=
4
*
calc_size
;
min_chunk_size
=
64
*
1024
*
1024
;
min_stripe_size
=
32
*
1024
*
1024
;
}
else
{
}
else
if
(
type
&
BTRFS_BLOCK_GROUP_SYSTEM
)
{
min_chunk_size
=
32
*
1024
*
1024
;
calc_size
=
8
*
1024
*
1024
;
max_chunk_size
=
calc_size
*
2
;
min_stripe_size
=
1
*
1024
*
1024
;
}
}
/* we don't want a chunk larger than 10% of the FS */
/* we don't want a chunk larger than 10% of the FS */
percent_max
=
div_factor
(
btrfs_super_total_bytes
(
&
info
->
super_copy
),
1
);
percent_max
=
div_factor
(
btrfs_super_total_bytes
(
&
info
->
super_copy
),
1
);
max_chunk_size
=
min
(
percent_max
,
max_chunk_size
);
max_chunk_size
=
min
(
percent_max
,
max_chunk_size
);
again:
if
(
calc_size
*
num_stripes
>
max_chunk_size
)
{
if
(
calc_size
*
num_stripes
>
max_chunk_size
)
{
calc_size
=
max_chunk_size
;
calc_size
=
max_chunk_size
;
do_div
(
calc_size
,
num_stripes
);
do_div
(
calc_size
,
num_stripes
);
...
@@ -722,12 +732,8 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
...
@@ -722,12 +732,8 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
calc_size
*=
stripe_len
;
calc_size
*=
stripe_len
;
}
}
/* we don't want tiny stripes */
/* we don't want tiny stripes */
*
num_bytes
=
chunk_bytes_by_type
(
type
,
calc_size
,
calc_size
=
max_t
(
u64
,
min_stripe_size
,
calc_size
);
num_stripes
,
sub_stripes
);
calc_size
=
max_t
(
u64
,
chunk_bytes_by_type
(
type
,
min_chunk_size
,
num_stripes
,
sub_stripes
),
calc_size
);
again:
do_div
(
calc_size
,
stripe_len
);
do_div
(
calc_size
,
stripe_len
);
calc_size
*=
stripe_len
;
calc_size
*=
stripe_len
;
...
@@ -746,19 +752,27 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
...
@@ -746,19 +752,27 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
avail
=
device
->
total_bytes
-
device
->
bytes_used
;
avail
=
device
->
total_bytes
-
device
->
bytes_used
;
cur
=
cur
->
next
;
cur
=
cur
->
next
;
if
(
avail
>
max_avail
)
max_avail
=
avail
;
if
(
avail
>=
min_free
)
{
if
(
avail
>=
min_free
)
{
list_move_tail
(
&
device
->
dev_list
,
&
private_devs
);
list_move_tail
(
&
device
->
dev_list
,
&
private_devs
);
index
++
;
index
++
;
if
(
type
&
BTRFS_BLOCK_GROUP_DUP
)
if
(
type
&
BTRFS_BLOCK_GROUP_DUP
)
index
++
;
index
++
;
}
}
else
if
(
avail
>
max_avail
)
max_avail
=
avail
;
if
(
cur
==
dev_list
)
if
(
cur
==
dev_list
)
break
;
break
;
}
}
if
(
index
<
num_stripes
)
{
if
(
index
<
num_stripes
)
{
list_splice
(
&
private_devs
,
dev_list
);
list_splice
(
&
private_devs
,
dev_list
);
if
(
index
>=
min_stripes
)
{
num_stripes
=
index
;
if
(
type
&
(
BTRFS_BLOCK_GROUP_RAID10
))
{
num_stripes
/=
sub_stripes
;
num_stripes
*=
sub_stripes
;
}
looped
=
1
;
goto
again
;
}
if
(
!
looped
&&
max_avail
>
0
)
{
if
(
!
looped
&&
max_avail
>
0
)
{
looped
=
1
;
looped
=
1
;
calc_size
=
max_avail
;
calc_size
=
max_avail
;
...
@@ -766,7 +780,6 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
...
@@ -766,7 +780,6 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
}
}
return
-
ENOSPC
;
return
-
ENOSPC
;
}
}
key
.
objectid
=
BTRFS_FIRST_CHUNK_TREE_OBJECTID
;
key
.
objectid
=
BTRFS_FIRST_CHUNK_TREE_OBJECTID
;
key
.
type
=
BTRFS_CHUNK_ITEM_KEY
;
key
.
type
=
BTRFS_CHUNK_ITEM_KEY
;
ret
=
find_next_chunk
(
chunk_root
,
BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
ret
=
find_next_chunk
(
chunk_root
,
BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录