Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
db94535d
K
Kernel
项目概览
openeuler
/
Kernel
大约 1 年 前同步成功
通知
7
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看板
提交
db94535d
编写于
10月 15, 2007
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Allow tree blocks larger than the page size
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
1a5bc167
变更
15
展开全部
隐藏空白更改
内联
并排
Showing
15 changed file
with
738 addition
and
497 deletion
+738
-497
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+229
-90
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+66
-46
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+58
-34
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+5
-4
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+147
-138
fs/btrfs/extent_map.c
fs/btrfs/extent_map.c
+66
-25
fs/btrfs/extent_map.h
fs/btrfs/extent_map.h
+5
-5
fs/btrfs/file-item.c
fs/btrfs/file-item.c
+5
-5
fs/btrfs/file.c
fs/btrfs/file.c
+60
-66
fs/btrfs/inode.c
fs/btrfs/inode.c
+44
-46
fs/btrfs/print-tree.c
fs/btrfs/print-tree.c
+13
-10
fs/btrfs/super.c
fs/btrfs/super.c
+4
-2
fs/btrfs/sysfs.c
fs/btrfs/sysfs.c
+3
-2
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+22
-17
fs/btrfs/tree-defrag.c
fs/btrfs/tree-defrag.c
+11
-7
未找到文件。
fs/btrfs/ctree.c
浏览文件 @
db94535d
此差异已折叠。
点击以展开。
fs/btrfs/ctree.h
浏览文件 @
db94535d
...
...
@@ -96,7 +96,7 @@ struct btrfs_key {
struct
btrfs_header
{
u8
csum
[
BTRFS_CSUM_SIZE
];
u8
fsid
[
BTRFS_FSID_SIZE
];
/* FS specific uuid */
__le64
b
lock
nr
;
/* which block this node is supposed to live in */
__le64
b
yte
nr
;
/* which block this node is supposed to live in */
__le64
generation
;
__le64
owner
;
__le32
nritems
;
...
...
@@ -122,16 +122,17 @@ struct btrfs_super_block {
u8
csum
[
BTRFS_CSUM_SIZE
];
/* the first 3 fields must match struct btrfs_header */
u8
fsid
[
16
];
/* FS specific uuid */
__le64
b
lock
nr
;
/* this block number */
__le64
b
yte
nr
;
/* this block number */
__le64
magic
;
__le64
generation
;
__le64
root
;
__le64
total_b
lock
s
;
__le64
b
lock
s_used
;
__le64
total_b
yte
s
;
__le64
b
yte
s_used
;
__le64
root_dir_objectid
;
__le32
sectorsize
;
__le32
nodesize
;
__le32
leafsize
;
u8
root_level
;
}
__attribute__
((
__packed__
));
/*
...
...
@@ -231,13 +232,14 @@ struct btrfs_dir_item {
struct
btrfs_root_item
{
struct
btrfs_inode_item
inode
;
__le64
root_dirid
;
__le64
b
lock
nr
;
__le64
b
lock
_limit
;
__le64
b
lock
s_used
;
__le64
b
yte
nr
;
__le64
b
yte
_limit
;
__le64
b
yte
s_used
;
__le32
flags
;
__le32
refs
;
struct
btrfs_disk_key
drop_progress
;
u8
drop_level
;
u8
level
;
}
__attribute__
((
__packed__
));
#define BTRFS_FILE_EXTENT_REG 0
...
...
@@ -250,8 +252,8 @@ struct btrfs_file_extent_item {
* disk space consumed by the extent, checksum blocks are included
* in these numbers
*/
__le64
disk_b
lock
nr
;
__le64
disk_num_b
lock
s
;
__le64
disk_b
yte
nr
;
__le64
disk_num_b
yte
s
;
/*
* the logical offset in file blocks (no csums)
* this extent record is for. This allows a file extent to point
...
...
@@ -263,7 +265,7 @@ struct btrfs_file_extent_item {
/*
* the logical number of file blocks (no csums included)
*/
__le64
num_b
lock
s
;
__le64
num_b
yte
s
;
}
__attribute__
((
__packed__
));
struct
btrfs_csum_item
{
...
...
@@ -429,6 +431,7 @@ static inline u##bits btrfs_##name(struct extent_buffer *eb, \
int err; \
char *map_token; \
char *kaddr; \
int unmap_on_exit = (eb->map_token == NULL); \
unsigned long map_start; \
unsigned long map_len; \
unsigned long offset = (unsigned long)s + \
...
...
@@ -436,12 +439,13 @@ static inline u##bits btrfs_##name(struct extent_buffer *eb, \
err = map_extent_buffer(eb, offset, \
sizeof(((type *)0)->member), \
&map_token, &kaddr, \
&map_start, &map_len, KM_USER
0
); \
&map_start, &map_len, KM_USER
1
); \
if (!err) { \
__le##bits *tmp = (__le##bits *)(kaddr + offset - \
map_start); \
u##bits res = le##bits##_to_cpu(*tmp); \
unmap_extent_buffer(eb, map_token, KM_USER0); \
if (unmap_on_exit) \
unmap_extent_buffer(eb, map_token, KM_USER1); \
return res; \
} else { \
__le##bits res; \
...
...
@@ -457,17 +461,19 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, \
char *kaddr; \
unsigned long map_start; \
unsigned long map_len; \
int unmap_on_exit = (eb->map_token == NULL); \
unsigned long offset = (unsigned long)s + \
offsetof(type, member); \
err = map_extent_buffer(eb, offset, \
sizeof(((type *)0)->member), \
&map_token, &kaddr, \
&map_start, &map_len, KM_USER
0
); \
&map_start, &map_len, KM_USER
1
); \
if (!err) { \
__le##bits *tmp = (__le##bits *)(kaddr + offset - \
map_start); \
*tmp = cpu_to_le##bits(val); \
unmap_extent_buffer(eb, map_token, KM_USER0); \
if (unmap_on_exit) \
unmap_extent_buffer(eb, map_token, KM_USER1); \
} else { \
val = cpu_to_le##bits(val); \
write_eb_member(eb, s, type, member, &val); \
...
...
@@ -483,15 +489,17 @@ static inline u##bits btrfs_##name(struct extent_buffer *eb) \
unsigned long map_start; \
unsigned long map_len; \
unsigned long offset = offsetof(type, member); \
int unmap_on_exit = (eb->map_token == NULL); \
err = map_extent_buffer(eb, offset, \
sizeof(((type *)0)->member), \
&map_token, &kaddr, \
&map_start, &map_len, KM_USER
0
); \
&map_start, &map_len, KM_USER
1
); \
if (!err) { \
__le##bits *tmp = (__le##bits *)(kaddr + offset - \
map_start); \
u##bits res = le##bits##_to_cpu(*tmp); \
unmap_extent_buffer(eb, map_token, KM_USER0); \
if (unmap_on_exit) \
unmap_extent_buffer(eb, map_token, KM_USER1); \
return res; \
} else { \
__le##bits res; \
...
...
@@ -508,15 +516,17 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, \
unsigned long map_start; \
unsigned long map_len; \
unsigned long offset = offsetof(type, member); \
int unmap_on_exit = (eb->map_token == NULL); \
err = map_extent_buffer(eb, offset, \
sizeof(((type *)0)->member), \
&map_token, &kaddr, \
&map_start, &map_len, KM_USER
0
); \
&map_start, &map_len, KM_USER
1
); \
if (!err) { \
__le##bits *tmp = (__le##bits *)(kaddr + offset - \
map_start); \
*tmp = cpu_to_le##bits(val); \
unmap_extent_buffer(eb, map_token, KM_USER0); \
if (unmap_on_exit) \
unmap_extent_buffer(eb, map_token, KM_USER1); \
} else { \
val = cpu_to_le##bits(val); \
write_eb_member(eb, NULL, type, member, &val); \
...
...
@@ -769,7 +779,7 @@ static inline void btrfs_set_key_type(struct btrfs_key *key, u8 val)
}
/* struct btrfs_header */
BTRFS_SETGET_HEADER_FUNCS
(
header_b
locknr
,
struct
btrfs_header
,
block
nr
,
64
);
BTRFS_SETGET_HEADER_FUNCS
(
header_b
ytenr
,
struct
btrfs_header
,
byte
nr
,
64
);
BTRFS_SETGET_HEADER_FUNCS
(
header_generation
,
struct
btrfs_header
,
generation
,
64
);
BTRFS_SETGET_HEADER_FUNCS
(
header_owner
,
struct
btrfs_header
,
owner
,
64
);
...
...
@@ -817,24 +827,28 @@ static inline int btrfs_is_leaf(struct extent_buffer *eb)
/* struct btrfs_root_item */
BTRFS_SETGET_FUNCS
(
disk_root_refs
,
struct
btrfs_root_item
,
refs
,
32
);
BTRFS_SETGET_FUNCS
(
disk_root_blocknr
,
struct
btrfs_root_item
,
blocknr
,
64
);
BTRFS_SETGET_FUNCS
(
disk_root_bytenr
,
struct
btrfs_root_item
,
bytenr
,
64
);
BTRFS_SETGET_FUNCS
(
disk_root_level
,
struct
btrfs_root_item
,
level
,
8
);
BTRFS_SETGET_STACK_FUNCS
(
root_blocknr
,
struct
btrfs_root_item
,
blocknr
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
root_bytenr
,
struct
btrfs_root_item
,
bytenr
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
root_level
,
struct
btrfs_root_item
,
level
,
8
);
BTRFS_SETGET_STACK_FUNCS
(
root_dirid
,
struct
btrfs_root_item
,
root_dirid
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
root_refs
,
struct
btrfs_root_item
,
refs
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
root_flags
,
struct
btrfs_root_item
,
flags
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
root_used
,
struct
btrfs_root_item
,
b
lock
s_used
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
root_limit
,
struct
btrfs_root_item
,
b
lock
_limit
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
root_used
,
struct
btrfs_root_item
,
b
yte
s_used
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
root_limit
,
struct
btrfs_root_item
,
b
yte
_limit
,
64
);
/* struct btrfs_super_block */
BTRFS_SETGET_STACK_FUNCS
(
super_b
locknr
,
struct
btrfs_super_block
,
block
nr
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_b
ytenr
,
struct
btrfs_super_block
,
byte
nr
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_generation
,
struct
btrfs_super_block
,
generation
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_root
,
struct
btrfs_super_block
,
root
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_total_blocks
,
struct
btrfs_super_block
,
total_blocks
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_blocks_used
,
struct
btrfs_super_block
,
blocks_used
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_root_level
,
struct
btrfs_super_block
,
root_level
,
8
);
BTRFS_SETGET_STACK_FUNCS
(
super_total_bytes
,
struct
btrfs_super_block
,
total_bytes
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_bytes_used
,
struct
btrfs_super_block
,
bytes_used
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_sectorsize
,
struct
btrfs_super_block
,
sectorsize
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
super_nodesize
,
struct
btrfs_super_block
,
...
...
@@ -856,33 +870,33 @@ static inline unsigned long btrfs_file_extent_inline_start(struct
btrfs_file_extent_item
*
e
)
{
unsigned
long
offset
=
(
unsigned
long
)
e
;
offset
+=
offsetof
(
struct
btrfs_file_extent_item
,
disk_b
lock
nr
);
offset
+=
offsetof
(
struct
btrfs_file_extent_item
,
disk_b
yte
nr
);
return
offset
;
}
static
inline
u32
btrfs_file_extent_calc_inline_size
(
u32
datasize
)
{
return
offsetof
(
struct
btrfs_file_extent_item
,
disk_b
lock
nr
)
+
datasize
;
return
offsetof
(
struct
btrfs_file_extent_item
,
disk_b
yte
nr
)
+
datasize
;
}
static
inline
u32
btrfs_file_extent_inline_len
(
struct
extent_buffer
*
eb
,
struct
btrfs_item
*
e
)
{
unsigned
long
offset
;
offset
=
offsetof
(
struct
btrfs_file_extent_item
,
disk_b
lock
nr
);
offset
=
offsetof
(
struct
btrfs_file_extent_item
,
disk_b
yte
nr
);
return
btrfs_item_size
(
eb
,
e
)
-
offset
;
}
BTRFS_SETGET_FUNCS
(
file_extent_disk_b
lock
nr
,
struct
btrfs_file_extent_item
,
disk_b
lock
nr
,
64
);
BTRFS_SETGET_FUNCS
(
file_extent_disk_b
yte
nr
,
struct
btrfs_file_extent_item
,
disk_b
yte
nr
,
64
);
BTRFS_SETGET_FUNCS
(
file_extent_generation
,
struct
btrfs_file_extent_item
,
generation
,
64
);
BTRFS_SETGET_FUNCS
(
file_extent_disk_num_b
lock
s
,
struct
btrfs_file_extent_item
,
disk_num_b
lock
s
,
64
);
BTRFS_SETGET_FUNCS
(
file_extent_disk_num_b
yte
s
,
struct
btrfs_file_extent_item
,
disk_num_b
yte
s
,
64
);
BTRFS_SETGET_FUNCS
(
file_extent_offset
,
struct
btrfs_file_extent_item
,
offset
,
64
);
BTRFS_SETGET_FUNCS
(
file_extent_num_b
lock
s
,
struct
btrfs_file_extent_item
,
num_b
lock
s
,
64
);
BTRFS_SETGET_FUNCS
(
file_extent_num_b
yte
s
,
struct
btrfs_file_extent_item
,
num_b
yte
s
,
64
);
static
inline
struct
btrfs_root
*
btrfs_sb
(
struct
super_block
*
sb
)
{
...
...
@@ -906,6 +920,12 @@ static inline int btrfs_set_root_name(struct btrfs_root *root,
return
0
;
}
static
inline
u32
btrfs_level_size
(
struct
btrfs_root
*
root
,
int
level
)
{
if
(
level
==
0
)
return
root
->
leafsize
;
return
root
->
nodesize
;
}
/* helper function to cast into the data area of the leaf. */
#define btrfs_item_ptr(leaf, slot, type) \
((type *)(btrfs_leaf_data(leaf) + \
...
...
@@ -927,7 +947,7 @@ int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
int
btrfs_copy_pinned
(
struct
btrfs_root
*
root
,
struct
extent_map_tree
*
copy
);
struct
btrfs_block_group_cache
*
btrfs_lookup_block_group
(
struct
btrfs_fs_info
*
info
,
u64
b
lock
nr
);
u64
b
yte
nr
);
struct
btrfs_block_group_cache
*
btrfs_find_block_group
(
struct
btrfs_root
*
root
,
struct
btrfs_block_group_cache
*
hint
,
u64
search_start
,
...
...
@@ -935,22 +955,22 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
int
btrfs_inc_root_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
struct
extent_buffer
*
btrfs_alloc_free_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u
64
hint
,
u64
empty_size
);
struct
btrfs_root
*
root
,
u
32
size
,
u64
hint
,
u64
empty_size
);
int
btrfs_alloc_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
owner
,
u64
num_b
lock
s
,
u64
empty_size
,
u64
search_start
,
u64
num_b
yte
s
,
u64
empty_size
,
u64
search_start
,
u64
search_end
,
struct
btrfs_key
*
ins
,
int
data
);
int
btrfs_inc_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
extent_buffer
*
buf
);
int
btrfs_free_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
b
locknr
,
u64
num_block
s
,
int
pin
);
*
root
,
u64
b
ytenr
,
u64
num_byte
s
,
int
pin
);
int
btrfs_finish_extent_commit
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
extent_map_tree
*
unpin
);
int
btrfs_inc_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
b
locknr
,
u64
num_block
s
);
u64
b
ytenr
,
u64
num_byte
s
);
int
btrfs_write_dirty_block_groups
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
int
btrfs_free_block_groups
(
struct
btrfs_fs_info
*
info
);
...
...
@@ -1040,12 +1060,12 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
int
btrfs_insert_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
pos
,
u64
offset
,
u64
disk_num_b
lock
s
,
u64
num_b
lock
s
);
u64
disk_num_b
yte
s
,
u64
num_b
yte
s
);
int
btrfs_lookup_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
u64
b
lock
nr
,
int
mod
);
u64
b
yte
nr
,
int
mod
);
int
btrfs_csum_file_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
offset
,
...
...
fs/btrfs/disk-io.c
浏览文件 @
db94535d
...
...
@@ -28,6 +28,7 @@
#include "disk-io.h"
#include "transaction.h"
#include "btrfs_inode.h"
#include "print-tree.h"
#if 0
static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
...
...
@@ -43,26 +44,25 @@ static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
#endif
struct
extent_buffer
*
btrfs_find_tree_block
(
struct
btrfs_root
*
root
,
u64
b
locknr
)
u64
b
ytenr
,
u32
blocksize
)
{
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
struct
extent_buffer
*
eb
;
eb
=
find_extent_buffer
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
blocknr
*
root
->
sectorsize
,
root
->
sectorsize
,
GFP_NOFS
);
bytenr
,
blocksize
,
GFP_NOFS
);
if
(
eb
)
eb
->
alloc_addr
=
(
unsigned
long
)
__builtin_return_address
(
0
);
return
eb
;
}
struct
extent_buffer
*
btrfs_find_create_tree_block
(
struct
btrfs_root
*
root
,
u64
b
locknr
)
u64
b
ytenr
,
u32
blocksize
)
{
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
struct
extent_buffer
*
eb
;
eb
=
alloc_extent_buffer
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
blocknr
*
root
->
sectorsize
,
root
->
sectorsize
,
GFP_NOFS
);
bytenr
,
blocksize
,
GFP_NOFS
);
eb
->
alloc_addr
=
(
unsigned
long
)
__builtin_return_address
(
0
);
return
eb
;
}
...
...
@@ -208,13 +208,13 @@ static struct address_space_operations btree_aops = {
.
sync_page
=
block_sync_page
,
};
int
readahead_tree_block
(
struct
btrfs_root
*
root
,
u64
b
locknr
)
int
readahead_tree_block
(
struct
btrfs_root
*
root
,
u64
b
ytenr
,
u32
blocksize
)
{
struct
extent_buffer
*
buf
=
NULL
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
int
ret
=
0
;
buf
=
btrfs_find_create_tree_block
(
root
,
b
locknr
);
buf
=
btrfs_find_create_tree_block
(
root
,
b
ytenr
,
blocksize
);
if
(
!
buf
)
return
0
;
read_extent_buffer_pages
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
...
...
@@ -223,12 +223,13 @@ int readahead_tree_block(struct btrfs_root *root, u64 blocknr)
return
ret
;
}
struct
extent_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
)
struct
extent_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
)
{
struct
extent_buffer
*
buf
=
NULL
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
buf
=
btrfs_find_create_tree_block
(
root
,
b
locknr
);
buf
=
btrfs_find_create_tree_block
(
root
,
b
ytenr
,
blocksize
);
if
(
!
buf
)
return
NULL
;
read_extent_buffer_pages
(
&
BTRFS_I
(
btree_inode
)
->
extent_tree
,
...
...
@@ -261,7 +262,7 @@ int set_tree_block_dirty(struct btrfs_root *root, struct extent_buffer *buf)
return
0
;
}
static
int
__setup_root
(
int
block
size
,
static
int
__setup_root
(
u32
nodesize
,
u32
leafsize
,
u32
sector
size
,
struct
btrfs_root
*
root
,
struct
btrfs_fs_info
*
fs_info
,
u64
objectid
)
...
...
@@ -269,9 +270,9 @@ static int __setup_root(int blocksize,
root
->
node
=
NULL
;
root
->
inode
=
NULL
;
root
->
commit_root
=
NULL
;
root
->
sectorsize
=
block
size
;
root
->
nodesize
=
block
size
;
root
->
leafsize
=
block
size
;
root
->
sectorsize
=
sector
size
;
root
->
nodesize
=
node
size
;
root
->
leafsize
=
leaf
size
;
root
->
ref_cows
=
0
;
root
->
fs_info
=
fs_info
;
root
->
objectid
=
objectid
;
...
...
@@ -291,21 +292,23 @@ static int __setup_root(int blocksize,
return
0
;
}
static
int
find_and_setup_root
(
int
blocksize
,
struct
btrfs_root
*
tree_root
,
static
int
find_and_setup_root
(
struct
btrfs_root
*
tree_root
,
struct
btrfs_fs_info
*
fs_info
,
u64
objectid
,
struct
btrfs_root
*
root
)
{
int
ret
;
u32
blocksize
;
__setup_root
(
blocksize
,
root
,
fs_info
,
objectid
);
__setup_root
(
tree_root
->
nodesize
,
tree_root
->
leafsize
,
tree_root
->
sectorsize
,
root
,
fs_info
,
objectid
);
ret
=
btrfs_find_last_root
(
tree_root
,
objectid
,
&
root
->
root_item
,
&
root
->
root_key
);
BUG_ON
(
ret
);
root
->
node
=
read_tree_block
(
root
,
btrfs_root_blocknr
(
&
root
->
root_item
));
blocksize
=
btrfs_level_size
(
root
,
btrfs_root_level
(
&
root
->
root_item
));
root
->
node
=
read_tree_block
(
root
,
btrfs_root_bytenr
(
&
root
->
root_item
),
blocksize
);
BUG_ON
(
!
root
->
node
);
return
0
;
}
...
...
@@ -318,14 +321,14 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
struct
btrfs_path
*
path
;
struct
extent_buffer
*
l
;
u64
highest_inode
;
u32
blocksize
;
int
ret
=
0
;
root
=
kzalloc
(
sizeof
(
*
root
),
GFP_NOFS
);
if
(
!
root
)
return
ERR_PTR
(
-
ENOMEM
);
if
(
location
->
offset
==
(
u64
)
-
1
)
{
ret
=
find_and_setup_root
(
fs_info
->
sb
->
s_blocksize
,
fs_info
->
tree_root
,
fs_info
,
ret
=
find_and_setup_root
(
tree_root
,
fs_info
,
location
->
objectid
,
root
);
if
(
ret
)
{
kfree
(
root
);
...
...
@@ -334,7 +337,8 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
goto
insert
;
}
__setup_root
(
fs_info
->
sb
->
s_blocksize
,
root
,
fs_info
,
__setup_root
(
tree_root
->
nodesize
,
tree_root
->
leafsize
,
tree_root
->
sectorsize
,
root
,
fs_info
,
location
->
objectid
);
path
=
btrfs_alloc_path
();
...
...
@@ -357,8 +361,9 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
kfree
(
root
);
return
ERR_PTR
(
ret
);
}
root
->
node
=
read_tree_block
(
root
,
btrfs_root_blocknr
(
&
root
->
root_item
));
blocksize
=
btrfs_level_size
(
root
,
btrfs_root_level
(
&
root
->
root_item
));
root
->
node
=
read_tree_block
(
root
,
btrfs_root_bytenr
(
&
root
->
root_item
),
blocksize
);
BUG_ON
(
!
root
->
node
);
insert:
root
->
ref_cows
=
1
;
...
...
@@ -418,6 +423,10 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
struct
btrfs_root
*
open_ctree
(
struct
super_block
*
sb
)
{
u32
sectorsize
;
u32
nodesize
;
u32
leafsize
;
u32
blocksize
;
struct
btrfs_root
*
extent_root
=
kmalloc
(
sizeof
(
struct
btrfs_root
),
GFP_NOFS
);
struct
btrfs_root
*
tree_root
=
kmalloc
(
sizeof
(
struct
btrfs_root
),
...
...
@@ -474,12 +483,12 @@ struct btrfs_root *open_ctree(struct super_block *sb)
mutex_init
(
&
fs_info
->
trans_mutex
);
mutex_init
(
&
fs_info
->
fs_mutex
);
__setup_root
(
sb
->
s_blocksize
,
tree_root
,
__setup_root
(
512
,
512
,
512
,
tree_root
,
fs_info
,
BTRFS_ROOT_TREE_OBJECTID
);
fs_info
->
sb_buffer
=
read_tree_block
(
tree_root
,
BTRFS_SUPER_INFO_OFFSET
/
sb
->
s_blocksize
);
BTRFS_SUPER_INFO_OFFSET
,
512
);
if
(
!
fs_info
->
sb_buffer
)
goto
fail_iput
;
...
...
@@ -494,9 +503,15 @@ struct btrfs_root *open_ctree(struct super_block *sb)
if
(
!
btrfs_super_root
(
disk_super
))
goto
fail_sb_buffer
;
nodesize
=
btrfs_super_nodesize
(
disk_super
);
leafsize
=
btrfs_super_leafsize
(
disk_super
);
sectorsize
=
btrfs_super_sectorsize
(
disk_super
);
tree_root
->
nodesize
=
nodesize
;
tree_root
->
leafsize
=
leafsize
;
tree_root
->
sectorsize
=
sectorsize
;
i_size_write
(
fs_info
->
btree_inode
,
btrfs_super_total_blocks
(
disk_super
)
<<
fs_info
->
btree_inode
->
i_blkbits
);
btrfs_super_total_bytes
(
disk_super
));
if
(
strncmp
((
char
*
)(
&
disk_super
->
magic
),
BTRFS_MAGIC
,
...
...
@@ -504,13 +519,22 @@ struct btrfs_root *open_ctree(struct super_block *sb)
printk
(
"btrfs: valid FS not found on %s
\n
"
,
sb
->
s_id
);
goto
fail_sb_buffer
;
}
blocksize
=
btrfs_level_size
(
tree_root
,
btrfs_super_root_level
(
disk_super
));
tree_root
->
node
=
read_tree_block
(
tree_root
,
btrfs_super_root
(
disk_super
));
btrfs_super_root
(
disk_super
),
blocksize
);
if
(
!
tree_root
->
node
)
goto
fail_sb_buffer
;
#if 0
btrfs_print_leaf(tree_root, tree_root->node);
err = -EIO;
goto fail_tree_root;
#endif
mutex_lock
(
&
fs_info
->
fs_mutex
);
ret
=
find_and_setup_root
(
sb
->
s_blocksize
,
tree_root
,
fs_info
,
ret
=
find_and_setup_root
(
tree_root
,
fs_info
,
BTRFS_EXTENT_TREE_OBJECTID
,
extent_root
);
if
(
ret
)
{
mutex_unlock
(
&
fs_info
->
fs_mutex
);
...
...
@@ -611,11 +635,11 @@ int close_ctree(struct btrfs_root *root)
free_extent_buffer
(
fs_info
->
tree_root
->
node
);
free_extent_buffer
(
fs_info
->
sb_buffer
);
truncate_inode_pages
(
fs_info
->
btree_inode
->
i_mapping
,
0
);
iput
(
fs_info
->
btree_inode
);
btrfs_free_block_groups
(
root
->
fs_info
);
del_fs_roots
(
fs_info
);
truncate_inode_pages
(
fs_info
->
btree_inode
->
i_mapping
,
0
);
iput
(
fs_info
->
btree_inode
);
kfree
(
fs_info
->
extent_root
);
kfree
(
fs_info
->
tree_root
);
return
0
;
...
...
@@ -642,7 +666,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
if
(
transid
!=
root
->
fs_info
->
generation
)
{
printk
(
KERN_CRIT
"transid mismatch buffer %llu, found %Lu running %Lu
\n
"
,
(
unsigned
long
long
)
extent_buffer_blocknr
(
buf
)
,
(
unsigned
long
long
)
buf
->
start
,
transid
,
root
->
fs_info
->
generation
);
WARN_ON
(
1
);
}
...
...
fs/btrfs/disk-io.h
浏览文件 @
db94535d
...
...
@@ -21,10 +21,11 @@
#define BTRFS_SUPER_INFO_OFFSET (16 * 1024)
struct
extent_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
);
int
readahead_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
);
struct
extent_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
);
int
readahead_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
);
struct
extent_buffer
*
btrfs_find_create_tree_block
(
struct
btrfs_root
*
root
,
u64
b
locknr
);
u64
b
ytenr
,
u32
blocksize
);
int
clean_tree_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
extent_buffer
*
buf
);
struct
btrfs_root
*
open_ctree
(
struct
super_block
*
sb
);
...
...
@@ -32,7 +33,7 @@ int close_ctree(struct btrfs_root *root);
int
write_ctree_super
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
struct
extent_buffer
*
btrfs_find_tree_block
(
struct
btrfs_root
*
root
,
u64
b
locknr
);
u64
b
ytenr
,
u32
blocksize
);
struct
btrfs_root
*
btrfs_read_fs_root
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_key
*
location
,
const
char
*
name
,
int
namelen
);
...
...
fs/btrfs/extent-tree.c
浏览文件 @
db94535d
此差异已折叠。
点击以展开。
fs/btrfs/extent_map.c
浏览文件 @
db94535d
...
...
@@ -1963,18 +1963,27 @@ static inline struct page *extent_buffer_page(struct extent_buffer *eb, int i)
struct
page
*
p
;
if
(
i
==
0
)
return
eb
->
first_page
;
i
+=
eb
->
start
>>
PAGE_CACHE_SHIFT
;
if
(
eb
->
last_page
&&
eb
->
last_page
->
index
==
i
)
return
eb
->
last_page
;
p
=
find_get_page
(
eb
->
first_page
->
mapping
,
i
);
page_cache_release
(
p
);
eb
->
last_page
=
p
;
return
p
;
}
static
inline
unsigned
long
num_extent_pages
(
u64
start
,
u64
len
)
{
return
((
start
+
len
+
PAGE_CACHE_SIZE
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
(
start
>>
PAGE_CACHE_SHIFT
);
}
struct
extent_buffer
*
alloc_extent_buffer
(
struct
extent_map_tree
*
tree
,
u64
start
,
unsigned
long
len
,
gfp_t
mask
)
{
unsigned
long
num_pages
=
((
start
+
len
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
(
start
>>
PAGE_CACHE_SHIFT
)
+
1
;
unsigned
long
num_pages
=
num_extent_pages
(
start
,
len
);
unsigned
long
i
;
unsigned
long
index
=
start
>>
PAGE_CACHE_SHIFT
;
struct
extent_buffer
*
eb
;
...
...
@@ -1986,7 +1995,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree,
if
(
!
eb
||
IS_ERR
(
eb
))
return
NULL
;
eb
->
alloc_addr
=
__builtin_return_address
(
0
);
eb
->
alloc_addr
=
(
unsigned
long
)
__builtin_return_address
(
0
);
eb
->
start
=
start
;
eb
->
len
=
len
;
atomic_set
(
&
eb
->
refs
,
1
);
...
...
@@ -1994,6 +2003,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree,
for
(
i
=
0
;
i
<
num_pages
;
i
++
,
index
++
)
{
p
=
find_or_create_page
(
mapping
,
index
,
mask
|
__GFP_HIGHMEM
);
if
(
!
p
)
{
WARN_ON
(
1
);
/* make sure the free only frees the pages we've
* grabbed a reference on
*/
...
...
@@ -2021,8 +2031,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree,
u64
start
,
unsigned
long
len
,
gfp_t
mask
)
{
unsigned
long
num_pages
=
((
start
+
len
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
(
start
>>
PAGE_CACHE_SHIFT
)
+
1
;
unsigned
long
num_pages
=
num_extent_pages
(
start
,
len
);
unsigned
long
i
;
unsigned
long
index
=
start
>>
PAGE_CACHE_SHIFT
;
struct
extent_buffer
*
eb
;
...
...
@@ -2033,7 +2042,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree,
if
(
!
eb
||
IS_ERR
(
eb
))
return
NULL
;
eb
->
alloc_addr
=
__builtin_return_address
(
0
);
eb
->
alloc_addr
=
(
unsigned
long
)
__builtin_return_address
(
0
);
eb
->
start
=
start
;
eb
->
len
=
len
;
atomic_set
(
&
eb
->
refs
,
1
);
...
...
@@ -2070,8 +2079,7 @@ void free_extent_buffer(struct extent_buffer *eb)
if
(
!
atomic_dec_and_test
(
&
eb
->
refs
))
return
;
num_pages
=
((
eb
->
start
+
eb
->
len
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
(
eb
->
start
>>
PAGE_CACHE_SHIFT
)
+
1
;
num_pages
=
num_extent_pages
(
eb
->
start
,
eb
->
len
);
if
(
eb
->
first_page
)
page_cache_release
(
eb
->
first_page
);
...
...
@@ -2094,8 +2102,7 @@ int clear_extent_buffer_dirty(struct extent_map_tree *tree,
u64
end
=
start
+
eb
->
len
-
1
;
set
=
clear_extent_dirty
(
tree
,
start
,
end
,
GFP_NOFS
);
num_pages
=
((
eb
->
start
+
eb
->
len
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
(
eb
->
start
>>
PAGE_CACHE_SHIFT
)
+
1
;
num_pages
=
num_extent_pages
(
eb
->
start
,
eb
->
len
);
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
{
page
=
extent_buffer_page
(
eb
,
i
);
...
...
@@ -2145,8 +2152,7 @@ int set_extent_buffer_uptodate(struct extent_map_tree *tree,
struct
page
*
page
;
unsigned
long
num_pages
;
num_pages
=
((
eb
->
start
+
eb
->
len
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
(
eb
->
start
>>
PAGE_CACHE_SHIFT
)
+
1
;
num_pages
=
num_extent_pages
(
eb
->
start
,
eb
->
len
);
set_extent_uptodate
(
tree
,
eb
->
start
,
eb
->
start
+
eb
->
len
-
1
,
GFP_NOFS
);
...
...
@@ -2191,8 +2197,7 @@ int read_extent_buffer_pages(struct extent_map_tree *tree,
return
0
;
}
num_pages
=
((
eb
->
start
+
eb
->
len
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
(
eb
->
start
>>
PAGE_CACHE_SHIFT
)
+
1
;
num_pages
=
num_extent_pages
(
eb
->
start
,
eb
->
len
);
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
{
page
=
extent_buffer_page
(
eb
,
i
);
if
(
PageUptodate
(
page
))
{
...
...
@@ -2267,14 +2272,14 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv,
}
EXPORT_SYMBOL
(
read_extent_buffer
);
int
map_extent_buffer
(
struct
extent_buffer
*
eb
,
unsigned
long
start
,
unsigned
long
min_len
,
char
**
token
,
char
**
map
,
unsigned
long
*
map_start
,
unsigned
long
*
map_len
,
int
km
)
static
int
__map_extent_buffer
(
struct
extent_buffer
*
eb
,
unsigned
long
start
,
unsigned
long
min_len
,
char
**
token
,
char
**
map
,
unsigned
long
*
map_start
,
unsigned
long
*
map_len
,
int
km
)
{
size_t
offset
=
start
&
(
PAGE_CACHE_SIZE
-
1
);
char
*
kaddr
;
struct
page
*
p
;
size_t
start_offset
=
eb
->
start
&
((
u64
)
PAGE_CACHE_SIZE
-
1
);
unsigned
long
i
=
(
start_offset
+
start
)
>>
PAGE_CACHE_SHIFT
;
unsigned
long
end_i
=
(
start_offset
+
start
+
min_len
)
>>
...
...
@@ -2283,21 +2288,59 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start,
if
(
i
!=
end_i
)
return
-
EINVAL
;
WARN_ON
(
start
>
eb
->
len
);
if
(
start
>=
eb
->
len
)
{
printk
(
"bad start in map eb start %Lu len %lu caller start %lu min %lu
\n
"
,
eb
->
start
,
eb
->
len
,
start
,
min_len
);
WARN_ON
(
1
);
}
if
(
i
==
0
)
{
offset
=
start_offset
;
*
map_start
=
0
;
}
else
{
offset
=
0
;
*
map_start
=
(
i
<<
PAGE_CACHE_SHIFT
)
-
start_offset
;
}
kaddr
=
kmap_atomic
(
extent_buffer_page
(
eb
,
i
),
km
);
p
=
extent_buffer_page
(
eb
,
i
);
WARN_ON
(
!
PageUptodate
(
p
));
kaddr
=
kmap_atomic
(
p
,
km
);
*
token
=
kaddr
;
*
map
=
kaddr
+
offset
;
*
map_len
=
PAGE_CACHE_SIZE
-
offset
;
return
0
;
}
int
map_extent_buffer
(
struct
extent_buffer
*
eb
,
unsigned
long
start
,
unsigned
long
min_len
,
char
**
token
,
char
**
map
,
unsigned
long
*
map_start
,
unsigned
long
*
map_len
,
int
km
)
{
int
err
;
int
save
=
0
;
if
(
eb
->
map_token
)
{
if
(
start
>=
eb
->
map_start
&&
start
+
min_len
<=
eb
->
map_start
+
eb
->
map_len
)
{
*
token
=
eb
->
map_token
;
*
map
=
eb
->
kaddr
;
*
map_start
=
eb
->
map_start
;
*
map_len
=
eb
->
map_len
;
return
0
;
}
unmap_extent_buffer
(
eb
,
eb
->
map_token
,
km
);
eb
->
map_token
=
NULL
;
save
=
1
;
}
err
=
__map_extent_buffer
(
eb
,
start
,
min_len
,
token
,
map
,
map_start
,
map_len
,
km
);
if
(
!
err
&&
save
)
{
eb
->
map_token
=
*
token
;
eb
->
kaddr
=
*
map
;
eb
->
map_start
=
*
map_start
;
eb
->
map_len
=
*
map_len
;
}
return
err
;
}
EXPORT_SYMBOL
(
map_extent_buffer
);
void
unmap_extent_buffer
(
struct
extent_buffer
*
eb
,
char
*
token
,
int
km
)
...
...
@@ -2574,7 +2617,6 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
((
unsigned
long
)
PAGE_CACHE_SIZE
-
1
);
src_off_in_page
=
src_end
&
((
unsigned
long
)
PAGE_CACHE_SIZE
-
1
);
if
(
src_i
==
0
)
src_off_in_page
+=
start_offset
;
if
(
dst_i
==
0
)
...
...
@@ -2582,14 +2624,13 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
cur
=
min
(
len
,
src_off_in_page
+
1
);
cur
=
min
(
cur
,
dst_off_in_page
+
1
);
move_pages
(
extent_buffer_page
(
dst
,
dst_i
),
extent_buffer_page
(
dst
,
src_i
),
dst_off_in_page
-
cur
+
1
,
src_off_in_page
-
cur
+
1
,
cur
);
dst_end
-=
cur
-
1
;
src_end
-=
cur
-
1
;
dst_end
-=
cur
;
src_end
-=
cur
;
len
-=
cur
;
}
}
...
...
fs/btrfs/extent_map.h
浏览文件 @
db94535d
...
...
@@ -70,7 +70,12 @@ struct extent_buffer {
struct
list_head
list
;
struct
list_head
leak_list
;
struct
page
*
first_page
;
struct
page
*
last_page
;
unsigned
long
alloc_addr
;
char
*
map_token
;
char
*
kaddr
;
unsigned
long
map_start
;
unsigned
long
map_len
;
};
typedef
struct
extent_map
*
(
get_extent_t
)(
struct
inode
*
inode
,
...
...
@@ -147,11 +152,6 @@ static inline void extent_buffer_get(struct extent_buffer *eb)
atomic_inc
(
&
eb
->
refs
);
}
static
inline
u64
extent_buffer_blocknr
(
struct
extent_buffer
*
eb
)
{
return
eb
->
start
/
4096
;
}
int
memcmp_extent_buffer
(
struct
extent_buffer
*
eb
,
const
void
*
ptrv
,
unsigned
long
start
,
unsigned
long
len
);
...
...
fs/btrfs/file-item.c
浏览文件 @
db94535d
...
...
@@ -27,8 +27,8 @@
int
btrfs_insert_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
pos
,
u64
offset
,
u64
disk_num_b
lock
s
,
u64
num_b
lock
s
)
u64
offset
,
u64
disk_num_b
yte
s
,
u64
num_b
yte
s
)
{
int
ret
=
0
;
struct
btrfs_file_extent_item
*
item
;
...
...
@@ -50,10 +50,10 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
leaf
=
path
->
nodes
[
0
];
item
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
btrfs_set_file_extent_disk_b
lock
nr
(
leaf
,
item
,
offset
);
btrfs_set_file_extent_disk_num_b
locks
(
leaf
,
item
,
disk_num_block
s
);
btrfs_set_file_extent_disk_b
yte
nr
(
leaf
,
item
,
offset
);
btrfs_set_file_extent_disk_num_b
ytes
(
leaf
,
item
,
disk_num_byte
s
);
btrfs_set_file_extent_offset
(
leaf
,
item
,
0
);
btrfs_set_file_extent_num_b
locks
(
leaf
,
item
,
num_block
s
);
btrfs_set_file_extent_num_b
ytes
(
leaf
,
item
,
num_byte
s
);
btrfs_set_file_extent_generation
(
leaf
,
item
,
trans
->
transid
);
btrfs_set_file_extent_type
(
leaf
,
item
,
BTRFS_FILE_EXTENT_REG
);
btrfs_mark_buffer_dirty
(
leaf
);
...
...
fs/btrfs/file.c
浏览文件 @
db94535d
...
...
@@ -120,9 +120,9 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
btrfs_set_file_extent_type
(
leaf
,
ei
,
BTRFS_FILE_EXTENT_INLINE
);
ptr
=
btrfs_file_extent_inline_start
(
ei
);
kaddr
=
kmap_atomic
(
page
,
KM_USER
0
);
kaddr
=
kmap_atomic
(
page
,
KM_USER
1
);
write_extent_buffer
(
leaf
,
kaddr
+
page_offset
,
ptr
,
size
);
kunmap_atomic
(
kaddr
,
KM_USER
0
);
kunmap_atomic
(
kaddr
,
KM_USER
1
);
btrfs_mark_buffer_dirty
(
leaf
);
fail:
btrfs_free_path
(
path
);
...
...
@@ -142,11 +142,12 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
extent_map
*
em
;
struct
extent_map_tree
*
em_tree
=
&
BTRFS_I
(
inode
)
->
extent_tree
;
u64
hint_b
lock
;
u64
num_b
lock
s
;
u64
hint_b
yte
;
u64
num_b
yte
s
;
u64
start_pos
;
u64
end_of_last_block
;
u64
end_pos
=
pos
+
write_bytes
;
u32
inline_size
;
loff_t
isize
=
i_size_read
(
inode
);
em
=
alloc_extent_map
(
GFP_NOFS
);
...
...
@@ -156,11 +157,12 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
em
->
bdev
=
inode
->
i_sb
->
s_bdev
;
start_pos
=
pos
&
~
((
u64
)
root
->
sectorsize
-
1
);
num_b
locks
=
(
write_bytes
+
pos
-
start_pos
+
root
->
sectorsize
-
1
)
>>
inode
->
i_blkbits
;
num_b
ytes
=
(
write_bytes
+
pos
-
start_pos
+
root
->
sectorsize
-
1
)
&
~
((
u64
)
root
->
sectorsize
-
1
)
;
down_read
(
&
BTRFS_I
(
inode
)
->
root
->
snap_sem
);
end_of_last_block
=
start_pos
+
(
num_blocks
<<
inode
->
i_blkbits
)
-
1
;
end_of_last_block
=
start_pos
+
num_bytes
-
1
;
lock_extent
(
em_tree
,
start_pos
,
end_of_last_block
,
GFP_NOFS
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
...
...
@@ -169,8 +171,8 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
goto
out_unlock
;
}
btrfs_set_trans_block_group
(
trans
,
inode
);
inode
->
i_blocks
+=
num_b
locks
<<
3
;
hint_b
lock
=
0
;
inode
->
i_blocks
+=
num_b
ytes
>>
9
;
hint_b
yte
=
0
;
if
((
end_of_last_block
&
4095
)
==
0
)
{
printk
(
"strange end of last %Lu %zu %Lu
\n
"
,
start_pos
,
write_bytes
,
end_of_last_block
);
...
...
@@ -191,11 +193,10 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
err
=
btrfs_drop_extents
(
trans
,
root
,
inode
,
last_pos_in_file
,
last_pos_in_file
+
hole_size
,
&
hint_b
lock
);
&
hint_b
yte
);
if
(
err
)
goto
failed
;
hole_size
>>=
inode
->
i_blkbits
;
err
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
last_pos_in_file
,
...
...
@@ -209,8 +210,10 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
* either allocate an extent for the new bytes or setup the key
* to show we are doing inline data in the extent
*/
inline_size
=
end_pos
-
start_pos
;
if
(
isize
>=
PAGE_CACHE_SIZE
||
pos
+
write_bytes
<
inode
->
i_size
||
pos
+
write_bytes
-
start_pos
>
BTRFS_MAX_INLINE_DATA_SIZE
(
root
))
{
inline_size
>=
BTRFS_MAX_INLINE_DATA_SIZE
(
root
)
||
inline_size
>=
PAGE_CACHE_SIZE
)
{
u64
last_end
;
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
{
struct
page
*
p
=
pages
[
i
];
...
...
@@ -224,10 +227,9 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
}
else
{
struct
page
*
p
=
pages
[
0
];
/* step one, delete the existing extents in this range */
/* FIXME blocksize != pagesize */
err
=
btrfs_drop_extents
(
trans
,
root
,
inode
,
start_pos
,
(
pos
+
write_bytes
+
root
->
sectorsize
-
1
)
&
~
((
u64
)
root
->
sectorsize
-
1
),
&
hint_b
lock
);
~
((
u64
)
root
->
sectorsize
-
1
),
&
hint_b
yte
);
if
(
err
)
goto
failed
;
...
...
@@ -283,7 +285,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
*/
int
btrfs_drop_extents
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
inode
*
inode
,
u64
start
,
u64
end
,
u64
*
hint_b
lock
)
u64
start
,
u64
end
,
u64
*
hint_b
yte
)
{
int
ret
;
struct
btrfs_key
key
;
...
...
@@ -346,8 +348,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
found_type
=
btrfs_file_extent_type
(
leaf
,
extent
);
if
(
found_type
==
BTRFS_FILE_EXTENT_REG
)
{
extent_end
=
key
.
offset
+
(
btrfs_file_extent_num_blocks
(
leaf
,
extent
)
<<
inode
->
i_blkbits
);
btrfs_file_extent_num_bytes
(
leaf
,
extent
);
found_extent
=
1
;
}
else
if
(
found_type
==
BTRFS_FILE_EXTENT_INLINE
)
{
struct
btrfs_item
*
item
;
...
...
@@ -386,17 +387,17 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
if
(
end
<
extent_end
&&
end
>=
key
.
offset
)
{
if
(
found_extent
)
{
u64
disk_b
lock
nr
=
btrfs_file_extent_disk_b
locknr
(
leaf
,
extent
);
u64
disk_num_b
lock
s
=
btrfs_file_extent_disk_num_b
lock
s
(
leaf
,
u64
disk_b
yte
nr
=
btrfs_file_extent_disk_b
ytenr
(
leaf
,
extent
);
u64
disk_num_b
yte
s
=
btrfs_file_extent_disk_num_b
yte
s
(
leaf
,
extent
);
read_extent_buffer
(
leaf
,
&
old
,
(
unsigned
long
)
extent
,
sizeof
(
old
));
if
(
disk_b
lock
nr
!=
0
)
{
if
(
disk_b
yte
nr
!=
0
)
{
ret
=
btrfs_inc_extent_ref
(
trans
,
root
,
disk_b
locknr
,
disk_num_block
s
);
disk_b
ytenr
,
disk_num_byte
s
);
BUG_ON
(
ret
);
}
}
...
...
@@ -410,21 +411,19 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
keep
=
1
;
WARN_ON
(
start
&
(
root
->
sectorsize
-
1
));
if
(
found_extent
)
{
new_num
=
(
start
-
key
.
offset
)
>>
inode
->
i_blkbits
;
old_num
=
btrfs_file_extent_num_blocks
(
leaf
,
extent
);
*
hint_block
=
btrfs_file_extent_disk_blocknr
(
leaf
,
extent
);
if
(
btrfs_file_extent_disk_blocknr
(
leaf
,
extent
))
{
new_num
=
start
-
key
.
offset
;
old_num
=
btrfs_file_extent_num_bytes
(
leaf
,
extent
);
*
hint_byte
=
btrfs_file_extent_disk_bytenr
(
leaf
,
extent
);
if
(
btrfs_file_extent_disk_bytenr
(
leaf
,
extent
))
{
inode
->
i_blocks
-=
(
old_num
-
new_num
)
<<
3
;
(
old_num
-
new_num
)
>>
9
;
}
btrfs_set_file_extent_num_blocks
(
leaf
,
extent
,
new_num
);
btrfs_set_file_extent_num_bytes
(
leaf
,
extent
,
new_num
);
btrfs_mark_buffer_dirty
(
leaf
);
}
else
{
WARN_ON
(
1
);
...
...
@@ -432,33 +431,32 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
}
/* delete the entire extent */
if
(
!
keep
)
{
u64
disk_b
lock
nr
=
0
;
u64
disk_num_b
lock
s
=
0
;
u64
extent_num_b
lock
s
=
0
;
u64
disk_b
yte
nr
=
0
;
u64
disk_num_b
yte
s
=
0
;
u64
extent_num_b
yte
s
=
0
;
if
(
found_extent
)
{
disk_b
lock
nr
=
btrfs_file_extent_disk_b
lock
nr
(
leaf
,
disk_b
yte
nr
=
btrfs_file_extent_disk_b
yte
nr
(
leaf
,
extent
);
disk_num_blocks
=
btrfs_file_extent_disk_num_blocks
(
leaf
,
extent
);
extent_num_blocks
=
btrfs_file_extent_num_blocks
(
leaf
,
extent
);
*
hint_block
=
btrfs_file_extent_disk_blocknr
(
leaf
,
disk_num_bytes
=
btrfs_file_extent_disk_num_bytes
(
leaf
,
extent
);
extent_num_bytes
=
btrfs_file_extent_num_bytes
(
leaf
,
extent
);
*
hint_byte
=
btrfs_file_extent_disk_bytenr
(
leaf
,
extent
);
}
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
/* TODO update progress marker and return */
BUG_ON
(
ret
);
btrfs_release_path
(
root
,
path
);
extent
=
NULL
;
if
(
found_extent
&&
disk_b
lock
nr
!=
0
)
{
inode
->
i_blocks
-=
extent_num_b
locks
<<
3
;
if
(
found_extent
&&
disk_b
yte
nr
!=
0
)
{
inode
->
i_blocks
-=
extent_num_b
ytes
>>
9
;
ret
=
btrfs_free_extent
(
trans
,
root
,
disk_b
lock
nr
,
disk_num_b
lock
s
,
0
);
disk_b
yte
nr
,
disk_num_b
yte
s
,
0
);
}
BUG_ON
(
ret
);
...
...
@@ -491,20 +489,19 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
(
unsigned
long
)
extent
,
sizeof
(
old
));
btrfs_set_file_extent_offset
(
leaf
,
extent
,
le64_to_cpu
(
old
.
offset
)
+
((
end
-
key
.
offset
)
>>
inode
->
i_blkbits
));
WARN_ON
(
le64_to_cpu
(
old
.
num_blocks
)
<
(
extent_end
-
end
)
>>
inode
->
i_blkbits
);
btrfs_set_file_extent_num_blocks
(
leaf
,
extent
,
(
extent_end
-
end
)
>>
inode
->
i_blkbits
);
le64_to_cpu
(
old
.
offset
)
+
end
-
key
.
offset
);
WARN_ON
(
le64_to_cpu
(
old
.
num_bytes
)
<
(
extent_end
-
end
));
btrfs_set_file_extent_num_bytes
(
leaf
,
extent
,
extent_end
-
end
);
btrfs_set_file_extent_type
(
leaf
,
extent
,
BTRFS_FILE_EXTENT_REG
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
if
(
le64_to_cpu
(
old
.
disk_b
lock
nr
)
!=
0
)
{
if
(
le64_to_cpu
(
old
.
disk_b
yte
nr
)
!=
0
)
{
inode
->
i_blocks
+=
btrfs_file_extent_num_b
lock
s
(
leaf
,
extent
)
<<
3
;
btrfs_file_extent_num_b
yte
s
(
leaf
,
extent
)
>>
9
;
}
ret
=
0
;
goto
out
;
...
...
@@ -531,12 +528,9 @@ static int prepare_pages(struct btrfs_root *root,
unsigned
long
index
=
pos
>>
PAGE_CACHE_SHIFT
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
int
err
=
0
;
u64
num_blocks
;
u64
start_pos
;
start_pos
=
pos
&
~
((
u64
)
root
->
sectorsize
-
1
);
num_blocks
=
(
write_bytes
+
pos
-
start_pos
+
root
->
sectorsize
-
1
)
>>
inode
->
i_blkbits
;
memset
(
pages
,
0
,
num_pages
*
sizeof
(
struct
page
*
));
...
...
fs/btrfs/inode.c
浏览文件 @
db94535d
...
...
@@ -77,19 +77,19 @@ static int run_delalloc_range(struct inode *inode, u64 start, u64 end)
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_key
ins
;
u64
alloc_hint
=
0
;
u64
num_b
lock
s
;
u64
num_b
yte
s
;
int
ret
;
u64
blocksize
=
1
<<
inode
->
i_blkbits
;
u64
blocksize
=
root
->
sectorsize
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
inode
);
BUG_ON
(
!
trans
);
num_b
lock
s
=
(
end
-
start
+
blocksize
)
&
~
(
blocksize
-
1
);
num_b
yte
s
=
(
end
-
start
+
blocksize
)
&
~
(
blocksize
-
1
);
ret
=
btrfs_drop_extents
(
trans
,
root
,
inode
,
start
,
start
+
num_b
lock
s
,
&
alloc_hint
);
num_blocks
=
num_blocks
>>
inode
->
i_blkbits
;
ret
=
btrfs_alloc_extent
(
trans
,
root
,
inode
->
i_ino
,
num_b
lock
s
,
0
,
start
,
start
+
num_b
yte
s
,
&
alloc_hint
);
ret
=
btrfs_alloc_extent
(
trans
,
root
,
inode
->
i_ino
,
num_b
yte
s
,
0
,
alloc_hint
,
(
u64
)
-
1
,
&
ins
,
1
);
if
(
ret
)
{
WARN_ON
(
1
);
...
...
@@ -186,7 +186,8 @@ int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end)
zeroit:
printk
(
"btrfs csum failed ino %lu off %llu
\n
"
,
page
->
mapping
->
host
->
i_ino
,
(
unsigned
long
long
)
start
);
memset
(
kaddr
+
offset
,
1
,
end
-
start
+
1
);
flush_dcache_page
(
page
);
memset
(
kaddr
+
offset
,
1
,
end
-
start
+
1
);
flush_dcache_page
(
page
);
kunmap_atomic
(
kaddr
,
KM_IRQ0
);
return
0
;
}
...
...
@@ -547,7 +548,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
struct
extent_buffer
*
leaf
;
struct
btrfs_file_extent_item
*
fi
;
u64
extent_start
=
0
;
u64
extent_num_b
lock
s
=
0
;
u64
extent_num_b
yte
s
=
0
;
u64
item_end
=
0
;
int
found_extent
;
int
del_item
;
...
...
@@ -593,8 +594,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
if
(
btrfs_file_extent_type
(
leaf
,
fi
)
!=
BTRFS_FILE_EXTENT_INLINE
)
{
item_end
+=
btrfs_file_extent_num_blocks
(
leaf
,
fi
)
<<
inode
->
i_blkbits
;
btrfs_file_extent_num_bytes
(
leaf
,
fi
);
}
}
if
(
found_type
==
BTRFS_CSUM_ITEM_KEY
)
{
...
...
@@ -626,28 +626,27 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
btrfs_file_extent_type
(
leaf
,
fi
)
!=
BTRFS_FILE_EXTENT_INLINE
)
{
u64
num_dec
;
extent_start
=
btrfs_file_extent_disk_b
lock
nr
(
leaf
,
fi
);
extent_start
=
btrfs_file_extent_disk_b
yte
nr
(
leaf
,
fi
);
if
(
!
del_item
)
{
u64
orig_num_b
lock
s
=
btrfs_file_extent_num_b
lock
s
(
leaf
,
fi
);
extent_num_b
lock
s
=
inode
->
i_size
-
u64
orig_num_b
yte
s
=
btrfs_file_extent_num_b
yte
s
(
leaf
,
fi
);
extent_num_b
yte
s
=
inode
->
i_size
-
found_key
.
offset
+
root
->
sectorsize
-
1
;
extent_num_blocks
>>=
inode
->
i_blkbits
;
btrfs_set_file_extent_num_blocks
(
leaf
,
fi
,
extent_num_blocks
);
num_dec
=
(
orig_num_blocks
-
extent_num_blocks
)
<<
3
;
btrfs_set_file_extent_num_bytes
(
leaf
,
fi
,
extent_num_bytes
);
num_dec
=
(
orig_num_bytes
-
extent_num_bytes
)
>>
9
;
if
(
extent_start
!=
0
)
{
inode
->
i_blocks
-=
num_dec
;
}
btrfs_mark_buffer_dirty
(
leaf
);
}
else
{
extent_num_b
lock
s
=
btrfs_file_extent_disk_num_b
lock
s
(
leaf
,
fi
);
extent_num_b
yte
s
=
btrfs_file_extent_disk_num_b
yte
s
(
leaf
,
fi
);
/* FIXME blocksize != 4096 */
num_dec
=
btrfs_file_extent_num_b
lock
s
(
leaf
,
fi
)
<<
3
;
num_dec
=
btrfs_file_extent_num_b
yte
s
(
leaf
,
fi
)
>>
9
;
if
(
extent_start
!=
0
)
{
found_extent
=
1
;
inode
->
i_blocks
-=
num_dec
;
...
...
@@ -664,7 +663,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
btrfs_release_path
(
root
,
path
);
if
(
found_extent
)
{
ret
=
btrfs_free_extent
(
trans
,
root
,
extent_start
,
extent_num_b
lock
s
,
0
);
extent_num_b
yte
s
,
0
);
BUG_ON
(
ret
);
}
}
...
...
@@ -709,7 +708,8 @@ static int btrfs_cow_one_page(struct inode *inode, struct page *page,
static
int
btrfs_truncate_page
(
struct
address_space
*
mapping
,
loff_t
from
)
{
struct
inode
*
inode
=
mapping
->
host
;
unsigned
blocksize
=
1
<<
inode
->
i_blkbits
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
u32
blocksize
=
root
->
sectorsize
;
pgoff_t
index
=
from
>>
PAGE_CACHE_SHIFT
;
unsigned
offset
=
from
&
(
PAGE_CACHE_SIZE
-
1
);
struct
page
*
page
;
...
...
@@ -719,7 +719,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
if
((
offset
&
(
blocksize
-
1
))
==
0
)
goto
out
;
down_read
(
&
BTRFS_I
(
inode
)
->
root
->
snap_sem
);
down_read
(
&
root
->
snap_sem
);
ret
=
-
ENOMEM
;
page
=
grab_cache_page
(
mapping
,
index
);
if
(
!
page
)
...
...
@@ -778,8 +778,6 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
err
=
btrfs_drop_extents
(
trans
,
root
,
inode
,
pos
,
pos
+
hole_size
,
&
alloc_hint
);
hole_size
>>=
inode
->
i_blkbits
;
err
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
pos
,
0
,
0
,
hole_size
);
btrfs_end_transaction
(
trans
,
root
);
...
...
@@ -1490,7 +1488,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
{
int
ret
;
int
err
=
0
;
u64
b
lock
nr
;
u64
b
yte
nr
;
u64
extent_start
=
0
;
u64
extent_end
=
0
;
u64
objectid
=
inode
->
i_ino
;
...
...
@@ -1540,10 +1538,6 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
leaf
=
path
->
nodes
[
0
];
item
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
blocknr
=
btrfs_file_extent_disk_blocknr
(
leaf
,
item
);
blocknr
+=
btrfs_file_extent_offset
(
leaf
,
item
);
/* are we inside the extent that was found? */
btrfs_item_key_to_cpu
(
leaf
,
&
found_key
,
path
->
slots
[
0
]);
found_type
=
btrfs_key_type
(
&
found_key
);
...
...
@@ -1556,8 +1550,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
extent_start
=
found_key
.
offset
;
if
(
found_type
==
BTRFS_FILE_EXTENT_REG
)
{
extent_end
=
extent_start
+
(
btrfs_file_extent_num_blocks
(
leaf
,
item
)
<<
inode
->
i_blkbits
);
btrfs_file_extent_num_bytes
(
leaf
,
item
);
err
=
0
;
if
(
start
<
extent_start
||
start
>=
extent_end
)
{
em
->
start
=
start
;
...
...
@@ -1570,17 +1563,18 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
}
goto
not_found_em
;
}
if
(
btrfs_file_extent_disk_blocknr
(
leaf
,
item
)
==
0
)
{
bytenr
=
btrfs_file_extent_disk_bytenr
(
leaf
,
item
);
if
(
bytenr
==
0
)
{
em
->
start
=
extent_start
;
em
->
end
=
extent_end
-
1
;
em
->
block_start
=
EXTENT_MAP_HOLE
;
em
->
block_end
=
EXTENT_MAP_HOLE
;
goto
insert
;
}
em
->
block_start
=
blocknr
<<
inode
->
i_blkbits
;
bytenr
+=
btrfs_file_extent_offset
(
leaf
,
item
);
em
->
block_start
=
bytenr
;
em
->
block_end
=
em
->
block_start
+
(
btrfs_file_extent_num_blocks
(
leaf
,
item
)
<<
inode
->
i_blkbits
)
-
1
;
btrfs_file_extent_num_bytes
(
leaf
,
item
)
-
1
;
em
->
start
=
extent_start
;
em
->
end
=
extent_end
-
1
;
goto
insert
;
...
...
@@ -1592,7 +1586,8 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
size
=
btrfs_file_extent_inline_len
(
leaf
,
btrfs_item_nr
(
leaf
,
path
->
slots
[
0
]));
extent_end
=
extent_start
|
((
u64
)
root
->
sectorsize
-
1
);
extent_end
=
(
extent_start
+
size
)
|
((
u64
)
root
->
sectorsize
-
1
);
if
(
start
<
extent_start
||
start
>=
extent_end
)
{
em
->
start
=
start
;
if
(
start
<
extent_start
)
{
...
...
@@ -1617,8 +1612,10 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
ptr
=
btrfs_file_extent_inline_start
(
item
);
map
=
kmap
(
page
);
read_extent_buffer
(
leaf
,
map
+
page_offset
,
ptr
,
size
);
/*
memset(map + page_offset + size, 0,
root->sectorsize - (page_offset + size));
*/
flush_dcache_page
(
page
);
kunmap
(
page
);
set_extent_uptodate
(
em_tree
,
extent_start
,
...
...
@@ -1836,13 +1833,13 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
trans
=
btrfs_start_transaction
(
root
,
1
);
BUG_ON
(
!
trans
);
leaf
=
btrfs_alloc_free_block
(
trans
,
root
,
0
,
0
);
leaf
=
btrfs_alloc_free_block
(
trans
,
root
,
root
->
leafsize
,
0
,
0
);
if
(
IS_ERR
(
leaf
))
return
PTR_ERR
(
leaf
);
btrfs_set_header_nritems
(
leaf
,
0
);
btrfs_set_header_level
(
leaf
,
0
);
btrfs_set_header_b
locknr
(
leaf
,
extent_buffer_blocknr
(
leaf
)
);
btrfs_set_header_b
ytenr
(
leaf
,
leaf
->
start
);
btrfs_set_header_generation
(
leaf
,
trans
->
transid
);
btrfs_set_header_owner
(
leaf
,
root
->
root_key
.
objectid
);
write_extent_buffer
(
leaf
,
root
->
fs_info
->
fsid
,
...
...
@@ -1858,7 +1855,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
inode_item
->
nblocks
=
cpu_to_le64
(
1
);
inode_item
->
mode
=
cpu_to_le32
(
S_IFDIR
|
0755
);
btrfs_set_root_blocknr
(
&
root_item
,
extent_buffer_blocknr
(
leaf
));
btrfs_set_root_bytenr
(
&
root_item
,
leaf
->
start
);
btrfs_set_root_level
(
&
root_item
,
0
);
btrfs_set_root_refs
(
&
root_item
,
1
);
btrfs_set_root_used
(
&
root_item
,
0
);
...
...
@@ -1971,8 +1969,8 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
btrfs_set_key_type
(
&
key
,
BTRFS_ROOT_ITEM_KEY
);
btrfs_cow_block
(
trans
,
root
,
root
->
node
,
NULL
,
0
,
&
tmp
);
btrfs_set_root_b
locknr
(
&
new_root_item
,
extent_buffer_blocknr
(
root
->
node
));
btrfs_set_root_b
ytenr
(
&
new_root_item
,
root
->
node
->
start
);
btrfs_set_root_level
(
&
new_root_item
,
btrfs_header_level
(
root
->
node
));
ret
=
btrfs_insert_root
(
trans
,
root
->
fs_info
->
tree_root
,
&
key
,
&
new_root_item
);
...
...
fs/btrfs/print-tree.c
浏览文件 @
db94535d
...
...
@@ -36,7 +36,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
u32
type
;
printk
(
"leaf %llu total ptrs %d free space %d
\n
"
,
(
unsigned
long
long
)
btrfs_header_b
lock
nr
(
l
),
nr
,
(
unsigned
long
long
)
btrfs_header_b
yte
nr
(
l
),
nr
,
btrfs_leaf_free_space
(
root
,
l
));
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
item
=
btrfs_item_nr
(
l
,
i
);
...
...
@@ -65,8 +65,8 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
break
;
case
BTRFS_ROOT_ITEM_KEY
:
ri
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_root_item
);
printk
(
"
\t\t
root data b
lock
nr %llu refs %u
\n
"
,
(
unsigned
long
long
)
btrfs_disk_root_b
lock
nr
(
l
,
ri
),
printk
(
"
\t\t
root data b
yte
nr %llu refs %u
\n
"
,
(
unsigned
long
long
)
btrfs_disk_root_b
yte
nr
(
l
,
ri
),
btrfs_disk_root_refs
(
l
,
ri
));
break
;
case
BTRFS_EXTENT_ITEM_KEY
:
...
...
@@ -84,12 +84,12 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
btrfs_file_extent_inline_len
(
l
,
item
));
break
;
}
printk
(
"
\t\t
extent data disk b
lock
%llu nr %llu
\n
"
,
(
unsigned
long
long
)
btrfs_file_extent_disk_b
lock
nr
(
l
,
fi
),
(
unsigned
long
long
)
btrfs_file_extent_disk_num_b
lock
s
(
l
,
fi
));
printk
(
"
\t\t
extent data disk b
ytenr
%llu nr %llu
\n
"
,
(
unsigned
long
long
)
btrfs_file_extent_disk_b
yte
nr
(
l
,
fi
),
(
unsigned
long
long
)
btrfs_file_extent_disk_num_b
yte
s
(
l
,
fi
));
printk
(
"
\t\t
extent data offset %llu nr %llu
\n
"
,
(
unsigned
long
long
)
btrfs_file_extent_offset
(
l
,
fi
),
(
unsigned
long
long
)
btrfs_file_extent_num_b
lock
s
(
l
,
fi
));
(
unsigned
long
long
)
btrfs_file_extent_num_b
yte
s
(
l
,
fi
));
break
;
case
BTRFS_BLOCK_GROUP_ITEM_KEY
:
bi
=
btrfs_item_ptr
(
l
,
i
,
...
...
@@ -106,16 +106,18 @@ void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c)
int
i
;
u32
nr
;
struct
btrfs_key
key
;
int
level
;
if
(
!
c
)
return
;
nr
=
btrfs_header_nritems
(
c
);
if
(
btrfs_is_leaf
(
c
))
{
level
=
btrfs_header_level
(
c
);
if
(
level
==
0
)
{
btrfs_print_leaf
(
root
,
c
);
return
;
}
printk
(
"node %llu level %d total ptrs %d free spc %u
\n
"
,
(
unsigned
long
long
)
btrfs_header_b
lock
nr
(
c
),
(
unsigned
long
long
)
btrfs_header_b
yte
nr
(
c
),
btrfs_header_level
(
c
),
nr
,
(
u32
)
BTRFS_NODEPTRS_PER_BLOCK
(
root
)
-
nr
);
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
...
...
@@ -129,7 +131,8 @@ void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *c)
}
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
struct
extent_buffer
*
next
=
read_tree_block
(
root
,
btrfs_node_blockptr
(
c
,
i
));
btrfs_node_blockptr
(
c
,
i
),
btrfs_level_size
(
root
,
level
-
1
));
if
(
btrfs_is_leaf
(
next
)
&&
btrfs_header_level
(
c
)
!=
1
)
BUG
();
...
...
fs/btrfs/super.c
浏览文件 @
db94535d
...
...
@@ -303,10 +303,12 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct
btrfs_root
*
root
=
btrfs_sb
(
dentry
->
d_sb
);
struct
btrfs_super_block
*
disk_super
=
&
root
->
fs_info
->
super_copy
;
int
bits
=
dentry
->
d_sb
->
s_blocksize_bits
;
buf
->
f_namelen
=
BTRFS_NAME_LEN
;
buf
->
f_blocks
=
btrfs_super_total_blocks
(
disk_super
);
buf
->
f_bfree
=
buf
->
f_blocks
-
btrfs_super_blocks_used
(
disk_super
);
buf
->
f_blocks
=
btrfs_super_total_bytes
(
disk_super
)
>>
bits
;
buf
->
f_bfree
=
buf
->
f_blocks
-
(
btrfs_super_bytes_used
(
disk_super
)
>>
bits
);
buf
->
f_bavail
=
buf
->
f_bfree
;
buf
->
f_bsize
=
dentry
->
d_sb
->
s_blocksize
;
buf
->
f_type
=
BTRFS_SUPER_MAGIC
;
...
...
fs/btrfs/sysfs.c
浏览文件 @
db94535d
...
...
@@ -42,14 +42,15 @@ static ssize_t root_block_limit_show(struct btrfs_root *root, char *buf)
static
ssize_t
super_blocks_used_show
(
struct
btrfs_fs_info
*
fs
,
char
*
buf
)
{
return
snprintf
(
buf
,
PAGE_SIZE
,
"%llu
\n
"
,
(
unsigned
long
long
)
btrfs_super_b
lock
s_used
(
&
fs
->
super_copy
));
(
unsigned
long
long
)
btrfs_super_b
yte
s_used
(
&
fs
->
super_copy
));
}
static
ssize_t
super_total_blocks_show
(
struct
btrfs_fs_info
*
fs
,
char
*
buf
)
{
return
snprintf
(
buf
,
PAGE_SIZE
,
"%llu
\n
"
,
(
unsigned
long
long
)
btrfs_super_total_b
lock
s
(
&
fs
->
super_copy
));
(
unsigned
long
long
)
btrfs_super_total_b
yte
s
(
&
fs
->
super_copy
));
}
static
ssize_t
super_blocksize_show
(
struct
btrfs_fs_info
*
fs
,
char
*
buf
)
...
...
fs/btrfs/transaction.c
浏览文件 @
db94535d
...
...
@@ -205,12 +205,13 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
btrfs_write_dirty_block_groups
(
trans
,
extent_root
);
while
(
1
)
{
old_extent_block
=
btrfs_root_blocknr
(
&
extent_root
->
root_item
);
if
(
old_extent_block
==
extent_buffer_blocknr
(
extent_root
->
node
))
old_extent_block
=
btrfs_root_bytenr
(
&
extent_root
->
root_item
);
if
(
old_extent_block
==
extent_root
->
node
->
start
)
break
;
btrfs_set_root_blocknr
(
&
extent_root
->
root_item
,
extent_buffer_blocknr
(
extent_root
->
node
));
btrfs_set_root_bytenr
(
&
extent_root
->
root_item
,
extent_root
->
node
->
start
);
btrfs_set_root_level
(
&
extent_root
->
root_item
,
btrfs_header_level
(
extent_root
->
node
));
ret
=
btrfs_update_root
(
trans
,
tree_root
,
&
extent_root
->
root_key
,
&
extent_root
->
root_item
);
...
...
@@ -284,8 +285,8 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
(
unsigned
long
)
root
->
root_key
.
objectid
,
BTRFS_ROOT_TRANS_TAG
);
if
(
root
->
commit_root
==
root
->
node
)
{
WARN_ON
(
extent_buffer_blocknr
(
root
->
node
)
!=
btrfs_root_b
lock
nr
(
&
root
->
root_item
));
WARN_ON
(
root
->
node
->
start
!=
btrfs_root_b
yte
nr
(
&
root
->
root_item
));
free_extent_buffer
(
root
->
commit_root
);
root
->
commit_root
=
NULL
;
...
...
@@ -314,8 +315,10 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
root
->
commit_root
=
NULL
;
root
->
root_key
.
offset
=
root
->
fs_info
->
generation
;
btrfs_set_root_blocknr
(
&
root
->
root_item
,
extent_buffer_blocknr
(
root
->
node
));
btrfs_set_root_bytenr
(
&
root
->
root_item
,
root
->
node
->
start
);
btrfs_set_root_level
(
&
root
->
root_item
,
btrfs_header_level
(
root
->
node
));
err
=
btrfs_insert_root
(
trans
,
root
->
fs_info
->
tree_root
,
&
root
->
root_key
,
&
root
->
root_item
);
...
...
@@ -407,8 +410,8 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
struct
dirty_root
*
dirty
;
struct
btrfs_trans_handle
*
trans
;
unsigned
long
nr
;
u64
num_b
lock
s
;
u64
b
lock
s_used
;
u64
num_b
yte
s
;
u64
b
yte
s_used
;
int
ret
=
0
;
int
err
;
...
...
@@ -419,7 +422,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
dirty
=
list_entry
(
list
->
next
,
struct
dirty_root
,
list
);
list_del_init
(
&
dirty
->
list
);
num_b
lock
s
=
btrfs_root_used
(
&
dirty
->
root
->
root_item
);
num_b
yte
s
=
btrfs_root_used
(
&
dirty
->
root
->
root_item
);
root
=
dirty
->
latest_root
;
while
(
1
)
{
...
...
@@ -446,12 +449,12 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
}
BUG_ON
(
ret
);
num_b
lock
s
-=
btrfs_root_used
(
&
dirty
->
root
->
root_item
);
b
lock
s_used
=
btrfs_root_used
(
&
root
->
root_item
);
if
(
num_b
lock
s
)
{
num_b
yte
s
-=
btrfs_root_used
(
&
dirty
->
root
->
root_item
);
b
yte
s_used
=
btrfs_root_used
(
&
root
->
root_item
);
if
(
num_b
yte
s
)
{
record_root_in_trans
(
root
);
btrfs_set_root_used
(
&
root
->
root_item
,
blocks_used
-
num_block
s
);
bytes_used
-
num_byte
s
);
}
ret
=
btrfs_del_root
(
trans
,
tree_root
,
&
dirty
->
root
->
root_key
);
if
(
ret
)
{
...
...
@@ -560,7 +563,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
btrfs_set_super_generation
(
&
root
->
fs_info
->
super_copy
,
cur_trans
->
transid
);
btrfs_set_super_root
(
&
root
->
fs_info
->
super_copy
,
extent_buffer_blocknr
(
root
->
fs_info
->
tree_root
->
node
));
root
->
fs_info
->
tree_root
->
node
->
start
);
btrfs_set_super_root_level
(
&
root
->
fs_info
->
super_copy
,
btrfs_header_level
(
root
->
fs_info
->
tree_root
->
node
));
write_extent_buffer
(
root
->
fs_info
->
sb_buffer
,
&
root
->
fs_info
->
super_copy
,
0
,
...
...
fs/btrfs/tree-defrag.c
浏览文件 @
db94535d
...
...
@@ -27,13 +27,15 @@ static void reada_defrag(struct btrfs_root *root,
{
int
i
;
u32
nritems
;
u64
blocknr
;
u64
bytenr
;
u32
blocksize
;
int
ret
;
blocksize
=
btrfs_level_size
(
root
,
btrfs_header_level
(
node
)
-
1
);
nritems
=
btrfs_header_nritems
(
node
);
for
(
i
=
0
;
i
<
nritems
;
i
++
)
{
b
lock
nr
=
btrfs_node_blockptr
(
node
,
i
);
ret
=
readahead_tree_block
(
root
,
b
locknr
);
b
yte
nr
=
btrfs_node_blockptr
(
node
,
i
);
ret
=
readahead_tree_block
(
root
,
b
ytenr
,
blocksize
);
if
(
ret
)
break
;
}
...
...
@@ -46,7 +48,7 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
{
struct
extent_buffer
*
next
;
struct
extent_buffer
*
cur
;
u64
b
lock
nr
;
u64
b
yte
nr
;
int
ret
=
0
;
int
is_extent
=
0
;
...
...
@@ -80,10 +82,11 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
break
;
}
b
lock
nr
=
btrfs_node_blockptr
(
cur
,
path
->
slots
[
*
level
]);
b
yte
nr
=
btrfs_node_blockptr
(
cur
,
path
->
slots
[
*
level
]);
if
(
cache_only
)
{
next
=
btrfs_find_tree_block
(
root
,
blocknr
);
next
=
btrfs_find_tree_block
(
root
,
bytenr
,
btrfs_level_size
(
root
,
*
level
-
1
));
/* FIXME, test for defrag */
if
(
!
next
||
!
btrfs_buffer_uptodate
(
next
))
{
free_extent_buffer
(
next
);
...
...
@@ -91,7 +94,8 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans,
continue
;
}
}
else
{
next
=
read_tree_block
(
root
,
blocknr
);
next
=
read_tree_block
(
root
,
bytenr
,
btrfs_level_size
(
root
,
*
level
-
1
));
}
ret
=
btrfs_cow_block
(
trans
,
root
,
next
,
path
->
nodes
[
*
level
],
path
->
slots
[
*
level
],
&
next
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录