Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
593060d7
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
593060d7
编写于
3月 25, 2008
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Implement raid0 when multiple devices are present
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
8a4b83cc
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
173 addition
and
66 deletion
+173
-66
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+3
-0
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+2
-0
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+68
-34
fs/btrfs/inode.c
fs/btrfs/inode.c
+0
-2
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+100
-30
未找到文件。
fs/btrfs/ctree.h
浏览文件 @
593060d7
...
...
@@ -413,6 +413,7 @@ struct btrfs_csum_item {
#define BTRFS_BLOCK_GROUP_DATA (1 << 0)
#define BTRFS_BLOCK_GROUP_SYSTEM (1 << 1)
#define BTRFS_BLOCK_GROUP_METADATA (1 << 2)
#define BTRFS_BLOCK_GROUP_RAID0 (1 << 3)
struct
btrfs_block_group_item
{
...
...
@@ -498,6 +499,8 @@ struct btrfs_fs_info {
u64
delalloc_bytes
;
u64
last_alloc
;
u64
last_data_alloc
;
int
extra_data_alloc_bits
;
int
extra_alloc_bits
;
};
/*
...
...
fs/btrfs/disk-io.c
浏览文件 @
593060d7
...
...
@@ -736,6 +736,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
fs_info
->
total_pinned
=
0
;
fs_info
->
last_alloc
=
0
;
fs_info
->
last_data_alloc
=
0
;
fs_info
->
extra_alloc_bits
=
0
;
fs_info
->
extra_data_alloc_bits
=
0
;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
INIT_WORK
(
&
fs_info
->
trans_work
,
btrfs_transaction_cleaner
,
fs_info
);
...
...
fs/btrfs/extent-tree.c
浏览文件 @
593060d7
...
...
@@ -172,7 +172,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
static
int
block_group_bits
(
struct
btrfs_block_group_cache
*
cache
,
u64
bits
)
{
return
(
cache
->
flags
&
bits
);
return
(
cache
->
flags
&
bits
)
==
bits
;
}
static
int
noinline
find_search_start
(
struct
btrfs_root
*
root
,
...
...
@@ -1010,6 +1010,35 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
}
static
int
update_space_info
(
struct
btrfs_fs_info
*
info
,
u64
flags
,
u64
total_bytes
,
u64
bytes_used
,
struct
btrfs_space_info
**
space_info
)
{
struct
btrfs_space_info
*
found
;
found
=
__find_space_info
(
info
,
flags
);
if
(
found
)
{
found
->
total_bytes
+=
total_bytes
;
found
->
bytes_used
+=
bytes_used
;
WARN_ON
(
found
->
total_bytes
<
found
->
bytes_used
);
*
space_info
=
found
;
return
0
;
}
found
=
kmalloc
(
sizeof
(
*
found
),
GFP_NOFS
);
if
(
!
found
)
return
-
ENOMEM
;
list_add
(
&
found
->
list
,
&
info
->
space_info
);
found
->
flags
=
flags
;
found
->
total_bytes
=
total_bytes
;
found
->
bytes_used
=
bytes_used
;
found
->
bytes_pinned
=
0
;
found
->
full
=
0
;
*
space_info
=
found
;
return
0
;
}
static
int
do_chunk_alloc
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
extent_root
,
u64
alloc_bytes
,
u64
flags
)
...
...
@@ -1021,6 +1050,11 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
int
ret
;
space_info
=
__find_space_info
(
extent_root
->
fs_info
,
flags
);
if
(
!
space_info
)
{
ret
=
update_space_info
(
extent_root
->
fs_info
,
flags
,
0
,
0
,
&
space_info
);
BUG_ON
(
ret
);
}
BUG_ON
(
!
space_info
);
if
(
space_info
->
full
)
...
...
@@ -1044,6 +1078,17 @@ printk("space info full %Lu\n", flags);
extent_root
->
fs_info
->
chunk_root
->
root_key
.
objectid
,
start
,
num_bytes
);
BUG_ON
(
ret
);
if
(
flags
&
BTRFS_BLOCK_GROUP_RAID0
)
{
if
(
flags
&
BTRFS_BLOCK_GROUP_DATA
)
{
extent_root
->
fs_info
->
extra_data_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
}
if
(
flags
&
BTRFS_BLOCK_GROUP_METADATA
)
{
extent_root
->
fs_info
->
extra_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
}
}
return
0
;
}
...
...
@@ -1655,24 +1700,31 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
struct
btrfs_extent_ref
*
ref
;
struct
btrfs_path
*
path
;
struct
btrfs_key
keys
[
2
];
int
extra_chunk_alloc_bits
=
0
;
if
(
data
)
{
data
=
BTRFS_BLOCK_GROUP_DATA
;
data
=
BTRFS_BLOCK_GROUP_DATA
|
info
->
extra_data_alloc_bits
;
}
else
if
(
root
==
root
->
fs_info
->
chunk_root
)
{
data
=
BTRFS_BLOCK_GROUP_SYSTEM
;
}
else
{
data
=
BTRFS_BLOCK_GROUP_METADATA
;
data
=
BTRFS_BLOCK_GROUP_METADATA
|
info
->
extra_alloc_bits
;
}
if
(
btrfs_super_num_devices
(
&
info
->
super_copy
)
>
1
&&
!
(
data
&
BTRFS_BLOCK_GROUP_SYSTEM
))
extra_chunk_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
if
(
root
->
ref_cows
)
{
if
(
data
!=
BTRFS_BLOCK_GROUP_METADATA
)
{
if
(
!
(
data
&
BTRFS_BLOCK_GROUP_METADATA
)
)
{
ret
=
do_chunk_alloc
(
trans
,
root
->
fs_info
->
extent_root
,
2
*
1024
*
1024
,
BTRFS_BLOCK_GROUP_METADATA
);
BTRFS_BLOCK_GROUP_METADATA
|
info
->
extra_alloc_bits
|
extra_chunk_alloc_bits
);
BUG_ON
(
ret
);
}
ret
=
do_chunk_alloc
(
trans
,
root
->
fs_info
->
extent_root
,
num_bytes
+
2
*
1024
*
1024
,
data
);
num_bytes
+
2
*
1024
*
1024
,
data
|
extra_chunk_alloc_bits
);
BUG_ON
(
ret
);
}
...
...
@@ -2627,34 +2679,6 @@ int find_first_block_group(struct btrfs_root *root, struct btrfs_path *path,
return
ret
;
}
static
int
update_space_info
(
struct
btrfs_fs_info
*
info
,
u64
flags
,
u64
total_bytes
,
u64
bytes_used
,
struct
btrfs_space_info
**
space_info
)
{
struct
btrfs_space_info
*
found
;
found
=
__find_space_info
(
info
,
flags
);
if
(
found
)
{
found
->
total_bytes
+=
total_bytes
;
found
->
bytes_used
+=
bytes_used
;
WARN_ON
(
found
->
total_bytes
<
found
->
bytes_used
);
*
space_info
=
found
;
return
0
;
}
found
=
kmalloc
(
sizeof
(
*
found
),
GFP_NOFS
);
if
(
!
found
)
return
-
ENOMEM
;
list_add
(
&
found
->
list
,
&
info
->
space_info
);
found
->
flags
=
flags
;
found
->
total_bytes
=
total_bytes
;
found
->
bytes_used
=
bytes_used
;
found
->
bytes_pinned
=
0
;
found
->
full
=
0
;
*
space_info
=
found
;
return
0
;
}
int
btrfs_read_block_groups
(
struct
btrfs_root
*
root
)
{
struct
btrfs_path
*
path
;
...
...
@@ -2712,6 +2736,16 @@ int btrfs_read_block_groups(struct btrfs_root *root)
}
else
if
(
cache
->
flags
&
BTRFS_BLOCK_GROUP_METADATA
)
{
bit
=
BLOCK_GROUP_METADATA
;
}
if
(
cache
->
flags
&
BTRFS_BLOCK_GROUP_RAID0
)
{
if
(
cache
->
flags
&
BTRFS_BLOCK_GROUP_DATA
)
{
info
->
extra_data_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
}
if
(
cache
->
flags
&
BTRFS_BLOCK_GROUP_METADATA
)
{
info
->
extra_alloc_bits
=
BTRFS_BLOCK_GROUP_RAID0
;
}
}
ret
=
update_space_info
(
info
,
cache
->
flags
,
found_key
.
offset
,
btrfs_block_group_used
(
&
cache
->
item
),
...
...
fs/btrfs/inode.c
浏览文件 @
593060d7
...
...
@@ -317,8 +317,6 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
map_length
=
length
;
ret
=
btrfs_map_block
(
map_tree
,
logical
,
&
physical
,
&
map_length
,
&
dev
);
if
(
map_length
<
length
+
size
)
{
printk
(
"merge bio hook logical %Lu bio len %Lu physical %Lu "
"len %Lu
\n
"
,
logical
,
length
,
physical
,
map_length
);
return
1
;
}
return
0
;
...
...
fs/btrfs/volumes.c
浏览文件 @
593060d7
...
...
@@ -18,6 +18,7 @@
#include <linux/sched.h>
#include <linux/bio.h>
#include <linux/buffer_head.h>
#include <asm/div64.h>
#include "ctree.h"
#include "extent_map.h"
#include "disk-io.h"
...
...
@@ -25,10 +26,24 @@
#include "print-tree.h"
#include "volumes.h"
struct
map_lookup
{
struct
stripe
{
struct
btrfs_device
*
dev
;
u64
physical
;
};
struct
map_lookup
{
u64
type
;
int
io_align
;
int
io_width
;
int
stripe_len
;
int
sector_size
;
int
num_stripes
;
struct
stripe
stripes
[];
};
#define map_lookup_size(n) (sizeof(struct map_lookup) + \
(sizeof(struct stripe) * (n)))
static
DEFINE_MUTEX
(
uuid_mutex
);
static
LIST_HEAD
(
fs_uuids
);
...
...
@@ -592,6 +607,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
u64
*
num_bytes
,
u64
type
)
{
u64
dev_offset
;
struct
btrfs_fs_info
*
info
=
extent_root
->
fs_info
;
struct
btrfs_root
*
chunk_root
=
extent_root
->
fs_info
->
chunk_root
;
struct
btrfs_stripe
*
stripes
;
struct
btrfs_device
*
device
=
NULL
;
...
...
@@ -610,10 +626,18 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
int
looped
=
0
;
int
ret
;
int
index
;
int
stripe_len
=
64
*
1024
;
struct
btrfs_key
key
;
if
(
list_empty
(
dev_list
))
return
-
ENOSPC
;
if
(
type
&
BTRFS_BLOCK_GROUP_RAID0
)
num_stripes
=
btrfs_super_num_devices
(
&
info
->
super_copy
);
if
(
type
&
BTRFS_BLOCK_GROUP_DATA
)
stripe_len
=
64
*
1024
;
if
(
type
&
(
BTRFS_BLOCK_GROUP_METADATA
|
BTRFS_BLOCK_GROUP_SYSTEM
))
stripe_len
=
32
*
1024
;
again:
INIT_LIST_HEAD
(
&
private_devs
);
cur
=
dev_list
->
next
;
...
...
@@ -650,9 +674,15 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
if
(
!
chunk
)
return
-
ENOMEM
;
map
=
kmalloc
(
map_lookup_size
(
num_stripes
),
GFP_NOFS
);
if
(
!
map
)
{
kfree
(
chunk
);
return
-
ENOMEM
;
}
stripes
=
&
chunk
->
stripe
;
*
num_bytes
=
calc_size
;
*
num_bytes
=
calc_size
*
num_stripes
;
index
=
0
;
while
(
index
<
num_stripes
)
{
BUG_ON
(
list_empty
(
&
private_devs
));
...
...
@@ -669,6 +699,8 @@ printk("alloc chunk size %Lu from dev %Lu\n", calc_size, device->devid);
ret
=
btrfs_update_device
(
trans
,
device
);
BUG_ON
(
ret
);
map
->
stripes
[
index
].
dev
=
device
;
map
->
stripes
[
index
].
physical
=
dev_offset
;
btrfs_set_stack_stripe_devid
(
stripes
+
index
,
device
->
devid
);
btrfs_set_stack_stripe_offset
(
stripes
+
index
,
dev_offset
);
physical
=
dev_offset
;
...
...
@@ -680,12 +712,18 @@ printk("alloc chunk size %Lu from dev %Lu\n", calc_size, device->devid);
key
.
offset
=
*
num_bytes
;
key
.
type
=
BTRFS_CHUNK_ITEM_KEY
;
btrfs_set_stack_chunk_owner
(
chunk
,
extent_root
->
root_key
.
objectid
);
btrfs_set_stack_chunk_stripe_len
(
chunk
,
64
*
1024
);
btrfs_set_stack_chunk_stripe_len
(
chunk
,
stripe_len
);
btrfs_set_stack_chunk_type
(
chunk
,
type
);
btrfs_set_stack_chunk_num_stripes
(
chunk
,
num_stripes
);
btrfs_set_stack_chunk_io_align
(
chunk
,
extent_root
->
sectorsize
);
btrfs_set_stack_chunk_io_width
(
chunk
,
extent_root
->
sectorsize
);
btrfs_set_stack_chunk_io_align
(
chunk
,
stripe_len
);
btrfs_set_stack_chunk_io_width
(
chunk
,
stripe_len
);
btrfs_set_stack_chunk_sector_size
(
chunk
,
extent_root
->
sectorsize
);
map
->
sector_size
=
extent_root
->
sectorsize
;
map
->
stripe_len
=
stripe_len
;
map
->
io_align
=
stripe_len
;
map
->
io_width
=
stripe_len
;
map
->
type
=
type
;
map
->
num_stripes
=
num_stripes
;
ret
=
btrfs_insert_item
(
trans
,
chunk_root
,
&
key
,
chunk
,
btrfs_chunk_item_size
(
num_stripes
));
...
...
@@ -695,25 +733,11 @@ printk("alloc chunk size %Lu from dev %Lu\n", calc_size, device->devid);
em
=
alloc_extent_map
(
GFP_NOFS
);
if
(
!
em
)
return
-
ENOMEM
;
map
=
kmalloc
(
sizeof
(
*
map
),
GFP_NOFS
);
if
(
!
map
)
{
free_extent_map
(
em
);
return
-
ENOMEM
;
}
em
->
bdev
=
(
struct
block_device
*
)
map
;
em
->
start
=
key
.
objectid
;
em
->
len
=
key
.
offset
;
em
->
block_start
=
0
;
map
->
physical
=
physical
;
map
->
dev
=
device
;
if
(
!
map
->
dev
)
{
kfree
(
map
);
free_extent_map
(
em
);
return
-
EIO
;
}
kfree
(
chunk
);
em_tree
=
&
extent_root
->
fs_info
->
mapping_tree
.
map_tree
;
...
...
@@ -758,6 +782,9 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree,
struct
map_lookup
*
map
;
struct
extent_map_tree
*
em_tree
=
&
map_tree
->
map_tree
;
u64
offset
;
u64
stripe_offset
;
u64
stripe_nr
;
int
stripe_index
;
spin_lock
(
&
em_tree
->
lock
);
...
...
@@ -767,9 +794,40 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree,
BUG_ON
(
em
->
start
>
logical
||
em
->
start
+
em
->
len
<
logical
);
map
=
(
struct
map_lookup
*
)
em
->
bdev
;
offset
=
logical
-
em
->
start
;
*
phys
=
map
->
physical
+
offset
;
*
length
=
em
->
len
-
offset
;
*
dev
=
map
->
dev
;
stripe_nr
=
offset
;
/*
* stripe_nr counts the total number of stripes we have to stride
* to get to this block
*/
do_div
(
stripe_nr
,
map
->
stripe_len
);
stripe_offset
=
stripe_nr
*
map
->
stripe_len
;
BUG_ON
(
offset
<
stripe_offset
);
/* stripe_offset is the offset of this block in its stripe*/
stripe_offset
=
offset
-
stripe_offset
;
/*
* after this do_div call, stripe_nr is the number of stripes
* on this device we have to walk to find the data, and
* stripe_index is the number of our device in the stripe array
*/
stripe_index
=
do_div
(
stripe_nr
,
map
->
num_stripes
);
BUG_ON
(
stripe_index
>=
map
->
num_stripes
);
*
phys
=
map
->
stripes
[
stripe_index
].
physical
+
stripe_offset
+
stripe_nr
*
map
->
stripe_len
;
if
(
map
->
type
&
BTRFS_BLOCK_GROUP_RAID0
)
{
/* we limit the length of each bio to what fits in a stripe */
*
length
=
min_t
(
u64
,
em
->
len
-
offset
,
map
->
stripe_len
-
stripe_offset
);
}
else
{
*
length
=
em
->
len
-
offset
;
}
*
dev
=
map
->
stripes
[
stripe_index
].
dev
;
free_extent_map
(
em
);
spin_unlock
(
&
em_tree
->
lock
);
return
0
;
...
...
@@ -822,7 +880,9 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
u64
logical
;
u64
length
;
u64
devid
;
int
num_stripes
;
int
ret
;
int
i
;
logical
=
key
->
objectid
;
length
=
key
->
offset
;
...
...
@@ -846,7 +906,8 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
em
=
alloc_extent_map
(
GFP_NOFS
);
if
(
!
em
)
return
-
ENOMEM
;
map
=
kmalloc
(
sizeof
(
*
map
),
GFP_NOFS
);
num_stripes
=
btrfs_chunk_num_stripes
(
leaf
,
chunk
);
map
=
kmalloc
(
map_lookup_size
(
num_stripes
),
GFP_NOFS
);
if
(
!
map
)
{
free_extent_map
(
em
);
return
-
ENOMEM
;
...
...
@@ -857,13 +918,22 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
em
->
len
=
length
;
em
->
block_start
=
0
;
map
->
physical
=
btrfs_stripe_offset_nr
(
leaf
,
chunk
,
0
);
devid
=
btrfs_stripe_devid_nr
(
leaf
,
chunk
,
0
);
map
->
dev
=
btrfs_find_device
(
root
,
devid
);
if
(
!
map
->
dev
)
{
kfree
(
map
);
free_extent_map
(
em
);
return
-
EIO
;
map
->
num_stripes
=
num_stripes
;
map
->
io_width
=
btrfs_chunk_io_width
(
leaf
,
chunk
);
map
->
io_align
=
btrfs_chunk_io_align
(
leaf
,
chunk
);
map
->
sector_size
=
btrfs_chunk_sector_size
(
leaf
,
chunk
);
map
->
stripe_len
=
btrfs_chunk_stripe_len
(
leaf
,
chunk
);
map
->
type
=
btrfs_chunk_type
(
leaf
,
chunk
);
for
(
i
=
0
;
i
<
num_stripes
;
i
++
)
{
map
->
stripes
[
i
].
physical
=
btrfs_stripe_offset_nr
(
leaf
,
chunk
,
i
);
devid
=
btrfs_stripe_devid_nr
(
leaf
,
chunk
,
i
);
map
->
stripes
[
i
].
dev
=
btrfs_find_device
(
root
,
devid
);
if
(
!
map
->
stripes
[
i
].
dev
)
{
kfree
(
map
);
free_extent_map
(
em
);
return
-
EIO
;
}
}
spin_lock
(
&
map_tree
->
map_tree
.
lock
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录