Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
d8d5f3e1
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
d8d5f3e1
编写于
12月 11, 2007
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Add lowest key information to back refs for extent tree blocks as well.
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
7bb86316
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
110 addition
and
19 deletion
+110
-19
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+1
-1
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+101
-1
fs/btrfs/file.c
fs/btrfs/file.c
+4
-7
fs/btrfs/inode.c
fs/btrfs/inode.c
+4
-10
未找到文件。
fs/btrfs/disk-io.c
浏览文件 @
d8d5f3e1
...
@@ -210,7 +210,7 @@ static int btree_writepages(struct address_space *mapping,
...
@@ -210,7 +210,7 @@ static int btree_writepages(struct address_space *mapping,
{
{
struct
extent_map_tree
*
tree
;
struct
extent_map_tree
*
tree
;
tree
=
&
BTRFS_I
(
mapping
->
host
)
->
extent_tree
;
tree
=
&
BTRFS_I
(
mapping
->
host
)
->
extent_tree
;
if
(
0
&&
wbc
->
sync_mode
==
WB_SYNC_NONE
)
{
if
(
wbc
->
sync_mode
==
WB_SYNC_NONE
)
{
u64
num_dirty
;
u64
num_dirty
;
u64
start
=
0
;
u64
start
=
0
;
unsigned
long
thresh
=
96
*
1024
*
1024
;
unsigned
long
thresh
=
96
*
1024
*
1024
;
...
...
fs/btrfs/extent-tree.c
浏览文件 @
d8d5f3e1
...
@@ -457,6 +457,94 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans,
...
@@ -457,6 +457,94 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans,
return
ret
;
return
ret
;
}
}
/*
* Back reference rules. Back refs have three main goals:
*
* 1) differentiate between all holders of references to an extent so that
* when a reference is dropped we can make sure it was a valid reference
* before freeing the extent.
*
* 2) Provide enough information to quickly find the holders of an extent
* if we notice a given block is corrupted or bad.
*
* 3) Make it easy to migrate blocks for FS shrinking or storage pool
* maintenance. This is actually the same as #2, but with a slightly
* different use case.
*
* File extents can be referenced by:
*
* - multiple snapshots, subvolumes, or different generations in one subvol
* - different files inside a single subvolume (in theory, not implemented yet)
* - different offsets inside a file (bookend extents in file.c)
*
* The extent ref structure has fields for:
*
* - Objectid of the subvolume root
* - Generation number of the tree holding the reference
* - objectid of the file holding the reference
* - offset in the file corresponding to the key holding the reference
*
* When a file extent is allocated the fields are filled in:
* (root_key.objectid, trans->transid, inode objectid, offset in file)
*
* When a leaf is cow'd new references are added for every file extent found
* in the leaf. It looks the same as the create case, but trans->transid
* will be different when the block is cow'd.
*
* (root_key.objectid, trans->transid, inode objectid, offset in file)
*
* When a file extent is removed either during snapshot deletion or file
* truncation, the corresponding back reference is found
* by searching for:
*
* (btrfs_header_owner(leaf), btrfs_header_generation(leaf),
* inode objectid, offset in file)
*
* Btree extents can be referenced by:
*
* - Different subvolumes
* - Different generations of the same subvolume
*
* Storing sufficient information for a full reverse mapping of a btree
* block would require storing the lowest key of the block in the backref,
* and it would require updating that lowest key either before write out or
* every time it changed. Instead, the objectid of the lowest key is stored
* along with the level of the tree block. This provides a hint
* about where in the btree the block can be found. Searches through the
* btree only need to look for a pointer to that block, so they stop one
* level higher than the level recorded in the backref.
*
* Some btrees do not do reference counting on their extents. These
* include the extent tree and the tree of tree roots. Backrefs for these
* trees always have a generation of zero.
*
* When a tree block is created, back references are inserted:
*
* (root->root_key.objectid, trans->transid or zero, lowest_key_objectid, level)
*
* When a tree block is cow'd in a reference counted root,
* new back references are added for all the blocks it points to.
* These are of the form (trans->transid will have increased since creation):
*
* (root->root_key.objectid, trans->transid, lowest_key_objectid, level)
*
* Because the lowest_key_objectid and the level are just hints
* they are not used when backrefs are deleted. When a backref is deleted:
*
* if backref was for a tree root:
* root_objectid = root->root_key.objectid
* else
* root_objectid = btrfs_header_owner(parent)
*
* (root_objectid, btrfs_header_generation(parent) or zero, 0, 0)
*
* Back Reference Key hashing:
*
* Back references have four fields, each 64 bits long. Unfortunately,
* This is hashed into a single 64 bit number and placed into the key offset.
* The key objectid corresponds to the first byte in the extent, and the
* key type is set to BTRFS_EXTENT_REF_KEY
*/
int
btrfs_insert_extent_backref
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_insert_extent_backref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
bytenr
,
struct
btrfs_path
*
path
,
u64
bytenr
,
...
@@ -939,10 +1027,13 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
...
@@ -939,10 +1027,13 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
u64
start
;
u64
start
;
u64
end
;
u64
end
;
struct
btrfs_fs_info
*
info
=
extent_root
->
fs_info
;
struct
btrfs_fs_info
*
info
=
extent_root
->
fs_info
;
struct
extent_buffer
*
eb
;
struct
btrfs_path
*
path
;
struct
btrfs_path
*
path
;
struct
btrfs_key
ins
;
struct
btrfs_key
ins
;
struct
btrfs_disk_key
first
;
struct
btrfs_extent_item
extent_item
;
struct
btrfs_extent_item
extent_item
;
int
ret
;
int
ret
;
int
level
;
int
err
=
0
;
int
err
=
0
;
btrfs_set_stack_extent_refs
(
&
extent_item
,
1
);
btrfs_set_stack_extent_refs
(
&
extent_item
,
1
);
...
@@ -961,10 +1052,19 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
...
@@ -961,10 +1052,19 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
&
extent_item
,
sizeof
(
extent_item
));
&
extent_item
,
sizeof
(
extent_item
));
clear_extent_bits
(
&
info
->
extent_ins
,
start
,
end
,
EXTENT_LOCKED
,
clear_extent_bits
(
&
info
->
extent_ins
,
start
,
end
,
EXTENT_LOCKED
,
GFP_NOFS
);
GFP_NOFS
);
eb
=
read_tree_block
(
extent_root
,
ins
.
objectid
,
ins
.
offset
);
level
=
btrfs_header_level
(
eb
);
if
(
level
==
0
)
{
btrfs_item_key
(
eb
,
&
first
,
0
);
}
else
{
btrfs_node_key
(
eb
,
&
first
,
0
);
}
err
=
btrfs_insert_extent_backref
(
trans
,
extent_root
,
path
,
err
=
btrfs_insert_extent_backref
(
trans
,
extent_root
,
path
,
start
,
extent_root
->
root_key
.
objectid
,
start
,
extent_root
->
root_key
.
objectid
,
0
,
0
,
0
);
0
,
btrfs_disk_key_objectid
(
&
first
),
level
);
BUG_ON
(
err
);
BUG_ON
(
err
);
free_extent_buffer
(
eb
);
}
}
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
return
0
;
return
0
;
...
...
fs/btrfs/file.c
浏览文件 @
d8d5f3e1
...
@@ -545,13 +545,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
...
@@ -545,13 +545,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
u64
disk_num_bytes
=
0
;
u64
disk_num_bytes
=
0
;
u64
extent_num_bytes
=
0
;
u64
extent_num_bytes
=
0
;
u64
root_gen
;
u64
root_gen
;
u64
root_owner
;
if
(
leaf
!=
root
->
node
)
{
root_gen
=
btrfs_header_generation
(
leaf
);
root_gen
=
root_owner
=
btrfs_header_owner
(
leaf
);
btrfs_header_generation
(
path
->
nodes
[
1
]);
}
else
{
root_gen
=
btrfs_header_generation
(
leaf
);
}
if
(
found_extent
)
{
if
(
found_extent
)
{
disk_bytenr
=
disk_bytenr
=
btrfs_file_extent_disk_bytenr
(
leaf
,
btrfs_file_extent_disk_bytenr
(
leaf
,
...
@@ -575,7 +572,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
...
@@ -575,7 +572,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
ret
=
btrfs_free_extent
(
trans
,
root
,
ret
=
btrfs_free_extent
(
trans
,
root
,
disk_bytenr
,
disk_bytenr
,
disk_num_bytes
,
disk_num_bytes
,
root
->
root_key
.
objectid
,
root
_owner
,
root_gen
,
inode
->
i_ino
,
root_gen
,
inode
->
i_ino
,
key
.
offset
,
0
);
key
.
offset
,
0
);
}
}
...
...
fs/btrfs/inode.c
浏览文件 @
d8d5f3e1
...
@@ -563,6 +563,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
...
@@ -563,6 +563,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
u64
extent_num_bytes
=
0
;
u64
extent_num_bytes
=
0
;
u64
item_end
=
0
;
u64
item_end
=
0
;
u64
root_gen
=
0
;
u64
root_gen
=
0
;
u64
root_owner
=
0
;
int
found_extent
;
int
found_extent
;
int
del_item
;
int
del_item
;
int
extent_type
=
-
1
;
int
extent_type
=
-
1
;
...
@@ -673,15 +674,8 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
...
@@ -673,15 +674,8 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
found_extent
=
1
;
found_extent
=
1
;
inode
->
i_blocks
-=
num_dec
;
inode
->
i_blocks
-=
num_dec
;
}
}
if
(
leaf
==
root
->
node
)
{
root_gen
=
btrfs_header_generation
(
leaf
);
root_gen
=
root_owner
=
btrfs_header_owner
(
leaf
);
btrfs_header_generation
(
leaf
);
}
else
{
struct
extent_buffer
*
parent
;
parent
=
path
->
nodes
[
1
];
root_gen
=
btrfs_header_generation
(
parent
);
}
}
}
}
else
if
(
extent_type
==
BTRFS_FILE_EXTENT_INLINE
&&
}
else
if
(
extent_type
==
BTRFS_FILE_EXTENT_INLINE
&&
!
del_item
)
{
!
del_item
)
{
...
@@ -703,7 +697,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
...
@@ -703,7 +697,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
if
(
found_extent
)
{
if
(
found_extent
)
{
ret
=
btrfs_free_extent
(
trans
,
root
,
extent_start
,
ret
=
btrfs_free_extent
(
trans
,
root
,
extent_start
,
extent_num_bytes
,
extent_num_bytes
,
root
->
root_key
.
objectid
,
root
_owner
,
root_gen
,
inode
->
i_ino
,
root_gen
,
inode
->
i_ino
,
found_key
.
offset
,
0
);
found_key
.
offset
,
0
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录