Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
9f5fae2f
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 2 年 前同步成功
通知
173
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看板
提交
9f5fae2f
编写于
3月 20, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
3月 20, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Add inode map, and the start of file extent items
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
631d7d95
变更
11
显示空白变更内容
内联
并排
Showing
11 changed file
with
542 addition
and
173 deletion
+542
-173
fs/btrfs/Makefile
fs/btrfs/Makefile
+2
-1
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+115
-14
fs/btrfs/debug-tree.c
fs/btrfs/debug-tree.c
+7
-2
fs/btrfs/dir-test.c
fs/btrfs/dir-test.c
+75
-16
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+96
-80
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+57
-48
fs/btrfs/file-item.c
fs/btrfs/file-item.c
+6
-0
fs/btrfs/inode-map.c
fs/btrfs/inode-map.c
+136
-0
fs/btrfs/mkfs.c
fs/btrfs/mkfs.c
+37
-7
fs/btrfs/print-tree.c
fs/btrfs/print-tree.c
+9
-4
fs/btrfs/quick-test.c
fs/btrfs/quick-test.c
+2
-1
未找到文件。
fs/btrfs/Makefile
浏览文件 @
9f5fae2f
...
@@ -3,7 +3,8 @@ CFLAGS = -g -Wall -Werror
...
@@ -3,7 +3,8 @@ CFLAGS = -g -Wall -Werror
headers
=
radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h
\
headers
=
radix-tree.h ctree.h disk-io.h kerncompat.h print-tree.h list.h
\
transaction.h
transaction.h
objects
=
ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o
\
objects
=
ctree.o disk-io.o radix-tree.o mkfs.o extent-tree.o print-tree.o
\
root-tree.o dir-item.o hash.o file-item.o inode-item.o
root-tree.o dir-item.o hash.o file-item.o inode-item.o
\
inode-map.o
\
# if you don't have sparse installed, use ls instead
# if you don't have sparse installed, use ls instead
CHECKFLAGS
=
-D__linux__
-Dlinux
-D__STDC__
-Dunix
-D__unix__
-Wbitwise
\
CHECKFLAGS
=
-D__linux__
-Dlinux
-D__STDC__
-Dunix
-D__unix__
-Wbitwise
\
...
...
fs/btrfs/ctree.h
浏览文件 @
9f5fae2f
...
@@ -10,7 +10,8 @@ struct btrfs_trans_handle;
...
@@ -10,7 +10,8 @@ struct btrfs_trans_handle;
#define BTRFS_ROOT_TREE_OBJECTID 1
#define BTRFS_ROOT_TREE_OBJECTID 1
#define BTRFS_EXTENT_TREE_OBJECTID 2
#define BTRFS_EXTENT_TREE_OBJECTID 2
#define BTRFS_FS_TREE_OBJECTID 3
#define BTRFS_INODE_MAP_OBJECTID 3
#define BTRFS_FS_TREE_OBJECTID 4
/*
/*
* the key defines the order in the tree, and so it also defines (optimal)
* the key defines the order in the tree, and so it also defines (optimal)
...
@@ -178,31 +179,65 @@ struct btrfs_root_item {
...
@@ -178,31 +179,65 @@ struct btrfs_root_item {
__le64
block_limit
;
__le64
block_limit
;
__le64
blocks_used
;
__le64
blocks_used
;
__le32
refs
;
__le32
refs
;
};
}
__attribute__
((
__packed__
))
;
/*
struct
btrfs_file_extent_item
{
* in ram representation of the tree. extent_root is used for all allocations
/*
* and for the extent tree extent_root root. current_insert is us
ed
* disk space consumed by the extent, checksum blocks are includ
ed
* only for the extent tree.
* in these numbers
*/
*/
struct
btrfs_root
{
__le64
disk_blocknr
;
struct
btrfs_buffer
*
node
;
__le64
disk_num_blocks
;
struct
btrfs_buffer
*
commit_root
;
/*
* the logical offset in file bytes (no csums)
* this extent record is for. This allows a file extent to point
* into the middle of an existing extent on disk, sharing it
* between two snapshots (useful if some bytes in the middle of the
* extent have changed
*/
__le64
offset
;
/*
* the logical number of file blocks (no csums included)
*/
__le64
num_blocks
;
}
__attribute__
((
__packed__
));
struct
btrfs_inode_map_item
{
struct
btrfs_disk_key
key
;
}
__attribute__
((
__packed__
));
struct
btrfs_fs_info
{
struct
btrfs_root
*
fs_root
;
struct
btrfs_root
*
extent_root
;
struct
btrfs_root
*
extent_root
;
struct
btrfs_root
*
tree_root
;
struct
btrfs_root
*
tree_root
;
struct
btrfs_root
*
inode_root
;
struct
btrfs_key
current_insert
;
struct
btrfs_key
current_insert
;
struct
btrfs_key
last_insert
;
struct
btrfs_key
last_insert
;
int
fp
;
struct
radix_tree_root
cache_radix
;
struct
radix_tree_root
cache_radix
;
struct
radix_tree_root
pinned_radix
;
struct
radix_tree_root
pinned_radix
;
struct
list_head
trans
;
struct
list_head
trans
;
struct
list_head
cache
;
struct
list_head
cache
;
u64
last_inode_alloc
;
u64
last_inode_alloc_dirid
;
int
cache_size
;
int
cache_size
;
int
ref_cows
;
int
fp
;
struct
btrfs_trans_handle
*
running_transaction
;
};
/*
* in ram representation of the tree. extent_root is used for all allocations
* and for the extent tree extent_root root. current_insert is used
* only for the extent tree.
*/
struct
btrfs_root
{
struct
btrfs_buffer
*
node
;
struct
btrfs_buffer
*
commit_root
;
struct
btrfs_root_item
root_item
;
struct
btrfs_root_item
root_item
;
struct
btrfs_key
root_key
;
struct
btrfs_key
root_key
;
struct
btrfs_fs_info
*
fs_info
;
u32
blocksize
;
u32
blocksize
;
struct
btrfs_trans_handle
*
running_transaction
;
int
ref_cows
;
u32
type
;
};
};
/* the lower bits in the key flags defines the item type */
/* the lower bits in the key flags defines the item type */
...
@@ -240,11 +275,17 @@ struct btrfs_root {
...
@@ -240,11 +275,17 @@ struct btrfs_root {
* are used, and how many references there are to each block
* are used, and how many references there are to each block
*/
*/
#define BTRFS_EXTENT_ITEM_KEY 6
#define BTRFS_EXTENT_ITEM_KEY 6
/*
* the inode map records which inode numbers are in use and where
* they actually live on disk
*/
#define BTRFS_INODE_MAP_ITEM_KEY 7
/*
/*
* string items are for debugging. They just store a short string of
* string items are for debugging. They just store a short string of
* data in the FS
* data in the FS
*/
*/
#define BTRFS_STRING_ITEM_KEY
7
#define BTRFS_STRING_ITEM_KEY
8
static
inline
u64
btrfs_inode_generation
(
struct
btrfs_inode_item
*
i
)
static
inline
u64
btrfs_inode_generation
(
struct
btrfs_inode_item
*
i
)
{
{
...
@@ -654,6 +695,57 @@ static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l)
...
@@ -654,6 +695,57 @@ static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l)
{
{
return
(
u8
*
)
l
->
items
;
return
(
u8
*
)
l
->
items
;
}
}
static
inline
u64
btrfs_file_extent_disk_blocknr
(
struct
btrfs_file_extent_item
*
e
)
{
return
le64_to_cpu
(
e
->
disk_blocknr
);
}
static
inline
void
btrfs_set_file_extent_disk_blocknr
(
struct
btrfs_file_extent_item
*
e
,
u64
val
)
{
e
->
disk_blocknr
=
cpu_to_le64
(
val
);
}
static
inline
u64
btrfs_file_extent_disk_num_blocks
(
struct
btrfs_file_extent_item
*
e
)
{
return
le64_to_cpu
(
e
->
disk_num_blocks
);
}
static
inline
void
btrfs_set_file_extent_disk_num_blocks
(
struct
btrfs_file_extent_item
*
e
,
u64
val
)
{
e
->
disk_num_blocks
=
cpu_to_le64
(
val
);
}
static
inline
u64
btrfs_file_extent_offset
(
struct
btrfs_file_extent_item
*
e
)
{
return
le64_to_cpu
(
e
->
offset
);
}
static
inline
void
btrfs_set_file_extent_offset
(
struct
btrfs_file_extent_item
*
e
,
u64
val
)
{
e
->
offset
=
cpu_to_le64
(
val
);
}
static
inline
u64
btrfs_file_extent_num_blocks
(
struct
btrfs_file_extent_item
*
e
)
{
return
le64_to_cpu
(
e
->
num_blocks
);
}
static
inline
void
btrfs_set_file_extent_num_blocks
(
struct
btrfs_file_extent_item
*
e
,
u64
val
)
{
e
->
num_blocks
=
cpu_to_le64
(
val
);
}
/* helper function to cast into the data area of the leaf. */
/* helper function to cast into the data area of the leaf. */
#define btrfs_item_ptr(leaf, slot, type) \
#define btrfs_item_ptr(leaf, slot, type) \
((type *)(btrfs_leaf_data(leaf) + \
((type *)(btrfs_leaf_data(leaf) + \
...
@@ -701,4 +793,13 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -701,4 +793,13 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
int
name_len
,
int
mod
);
int
name_len
,
int
mod
);
int
btrfs_match_dir_item_name
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
int
btrfs_match_dir_item_name
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
char
*
name
,
int
name_len
);
char
*
name
,
int
name_len
);
int
btrfs_find_free_objectid
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
fs_root
,
u64
dirid
,
u64
*
objectid
);
int
btrfs_insert_inode_map
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
struct
btrfs_key
*
location
);
int
btrfs_lookup_inode_map
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
int
mod
);
#endif
#endif
fs/btrfs/debug-tree.c
浏览文件 @
9f5fae2f
...
@@ -15,8 +15,13 @@ int main(int ac, char **av) {
...
@@ -15,8 +15,13 @@ int main(int ac, char **av) {
printf
(
"fs tree
\n
"
);
printf
(
"fs tree
\n
"
);
btrfs_print_tree
(
root
,
root
->
node
);
btrfs_print_tree
(
root
,
root
->
node
);
printf
(
"map tree
\n
"
);
printf
(
"map tree
\n
"
);
btrfs_print_tree
(
root
->
extent_root
,
root
->
extent_root
->
node
);
btrfs_print_tree
(
root
->
fs_info
->
extent_root
,
root
->
fs_info
->
extent_root
->
node
);
printf
(
"inode tree
\n
"
);
btrfs_print_tree
(
root
->
fs_info
->
inode_root
,
root
->
fs_info
->
inode_root
->
node
);
printf
(
"root tree
\n
"
);
printf
(
"root tree
\n
"
);
btrfs_print_tree
(
root
->
tree_root
,
root
->
tree_root
->
node
);
btrfs_print_tree
(
root
->
fs_info
->
tree_root
,
root
->
fs_info
->
tree_root
->
node
);
return
0
;
return
0
;
}
}
fs/btrfs/dir-test.c
浏览文件 @
9f5fae2f
...
@@ -45,13 +45,26 @@ static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
...
@@ -45,13 +45,26 @@ static int ins_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int
ret
;
int
ret
;
char
buf
[
128
];
char
buf
[
128
];
unsigned
long
oid
;
unsigned
long
oid
;
u64
objectid
;
struct
btrfs_path
path
;
struct
btrfs_path
path
;
struct
btrfs_key
inode_map
;
find_num
(
radix
,
&
oid
,
0
);
find_num
(
radix
,
&
oid
,
0
);
sprintf
(
buf
,
"str-%lu"
,
oid
);
sprintf
(
buf
,
"str-%lu"
,
oid
);
ret
=
btrfs_find_free_objectid
(
trans
,
root
,
dir_oid
+
1
,
&
objectid
);
if
(
ret
)
goto
error
;
inode_map
.
objectid
=
objectid
;
inode_map
.
flags
=
0
;
inode_map
.
offset
=
0
;
ret
=
btrfs_insert_inode_map
(
trans
,
root
,
objectid
,
&
inode_map
);
if
(
ret
)
goto
error
;
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
buf
,
strlen
(
buf
),
dir_oid
,
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
buf
,
strlen
(
buf
),
dir_oid
,
file_o
id
,
1
);
object
id
,
1
);
if
(
ret
)
if
(
ret
)
goto
error
;
goto
error
;
...
@@ -120,6 +133,53 @@ static int insert_dup(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -120,6 +133,53 @@ static int insert_dup(struct btrfs_trans_handle *trans, struct btrfs_root
return
0
;
return
0
;
}
}
static
int
del_dir_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
radix_tree_root
*
radix
,
unsigned
long
radix_index
,
struct
btrfs_path
*
path
)
{
int
ret
;
unsigned
long
*
ptr
;
u64
file_objectid
;
struct
btrfs_dir_item
*
di
;
struct
btrfs_path
map_path
;
/* find the inode number of the file */
di
=
btrfs_item_ptr
(
&
path
->
nodes
[
0
]
->
leaf
,
path
->
slots
[
0
],
struct
btrfs_dir_item
);
file_objectid
=
btrfs_dir_objectid
(
di
);
/* delete the directory item */
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
if
(
ret
)
goto
out
;
/* delete the inode mapping */
btrfs_init_path
(
&
map_path
);
ret
=
btrfs_lookup_inode_map
(
trans
,
root
,
&
map_path
,
file_objectid
,
-
1
);
if
(
ret
)
goto
out_release
;
ret
=
btrfs_del_item
(
trans
,
root
->
fs_info
->
inode_root
,
&
map_path
);
if
(
ret
)
goto
out_release
;
if
(
root
->
fs_info
->
last_inode_alloc
>
file_objectid
)
root
->
fs_info
->
last_inode_alloc
=
file_objectid
;
btrfs_release_path
(
root
,
&
map_path
);
ptr
=
radix_tree_delete
(
radix
,
radix_index
);
if
(
!
ptr
)
{
ret
=
-
5555
;
goto
out
;
}
return
0
;
out_release:
btrfs_release_path
(
root
,
&
map_path
);
out:
printf
(
"failed to delete %lu %d
\n
"
,
radix_index
,
ret
);
return
-
1
;
}
static
int
del_one
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
static
int
del_one
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
radix_tree_root
*
radix
)
struct
radix_tree_root
*
radix
)
{
{
...
@@ -127,7 +187,6 @@ static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
...
@@ -127,7 +187,6 @@ static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
char
buf
[
128
];
char
buf
[
128
];
unsigned
long
oid
;
unsigned
long
oid
;
struct
btrfs_path
path
;
struct
btrfs_path
path
;
unsigned
long
*
ptr
;
ret
=
find_num
(
radix
,
&
oid
,
1
);
ret
=
find_num
(
radix
,
&
oid
,
1
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -138,19 +197,14 @@ static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
...
@@ -138,19 +197,14 @@ static int del_one(struct btrfs_trans_handle *trans, struct btrfs_root *root,
strlen
(
buf
),
-
1
);
strlen
(
buf
),
-
1
);
if
(
ret
)
if
(
ret
)
goto
out_release
;
goto
out_release
;
ret
=
btrfs_del_item
(
trans
,
root
,
&
path
);
ret
=
del_dir_item
(
trans
,
root
,
radix
,
oid
,
&
path
);
if
(
ret
)
if
(
ret
)
goto
out_release
;
goto
out_release
;
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
ptr
=
radix_tree_delete
(
radix
,
oid
);
return
ret
;
if
(
!
ptr
)
{
ret
=
-
5555
;
goto
out
;
}
return
0
;
out_release:
out_release:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
out:
printf
(
"failed to delete %lu %d
\n
"
,
oid
,
ret
);
printf
(
"failed to delete %lu %d
\n
"
,
oid
,
ret
);
return
-
1
;
return
-
1
;
}
}
...
@@ -162,6 +216,8 @@ static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -162,6 +216,8 @@ static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
char
buf
[
128
];
char
buf
[
128
];
int
ret
;
int
ret
;
unsigned
long
oid
;
unsigned
long
oid
;
u64
objectid
;
struct
btrfs_dir_item
*
di
;
ret
=
find_num
(
radix
,
&
oid
,
1
);
ret
=
find_num
(
radix
,
&
oid
,
1
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -170,6 +226,14 @@ static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -170,6 +226,14 @@ static int lookup_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_init_path
(
&
path
);
btrfs_init_path
(
&
path
);
ret
=
btrfs_lookup_dir_item
(
trans
,
root
,
&
path
,
dir_oid
,
buf
,
ret
=
btrfs_lookup_dir_item
(
trans
,
root
,
&
path
,
dir_oid
,
buf
,
strlen
(
buf
),
0
);
strlen
(
buf
),
0
);
if
(
!
ret
)
{
di
=
btrfs_item_ptr
(
&
path
.
nodes
[
0
]
->
leaf
,
path
.
slots
[
0
],
struct
btrfs_dir_item
);
objectid
=
btrfs_dir_objectid
(
di
);
btrfs_release_path
(
root
,
&
path
);
btrfs_init_path
(
&
path
);
ret
=
btrfs_lookup_inode_map
(
trans
,
root
,
&
path
,
objectid
,
0
);
}
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
if
(
ret
)
{
if
(
ret
)
{
printf
(
"unable to find key %lu
\n
"
,
oid
);
printf
(
"unable to find key %lu
\n
"
,
oid
);
...
@@ -210,7 +274,6 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -210,7 +274,6 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
u32
found_len
;
u32
found_len
;
int
ret
;
int
ret
;
int
slot
;
int
slot
;
int
*
ptr
;
int
count
=
0
;
int
count
=
0
;
char
buf
[
128
];
char
buf
[
128
];
struct
btrfs_dir_item
*
di
;
struct
btrfs_dir_item
*
di
;
...
@@ -241,7 +304,7 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -241,7 +304,7 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON
(
found_len
>
128
);
BUG_ON
(
found_len
>
128
);
buf
[
found_len
]
=
'\0'
;
buf
[
found_len
]
=
'\0'
;
found
=
atoi
(
buf
+
4
);
found
=
atoi
(
buf
+
4
);
ret
=
btrfs_del_item
(
trans
,
root
,
&
path
);
ret
=
del_dir_item
(
trans
,
root
,
radix
,
found
,
&
path
);
count
++
;
count
++
;
if
(
ret
)
{
if
(
ret
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
...
@@ -250,14 +313,10 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -250,14 +313,10 @@ static int empty_tree(struct btrfs_trans_handle *trans, struct btrfs_root
return
-
1
;
return
-
1
;
}
}
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
ptr
=
radix_tree_delete
(
radix
,
found
);
if
(
!
ptr
)
goto
error
;
if
(
!
keep_running
)
if
(
!
keep_running
)
break
;
break
;
}
}
return
0
;
return
0
;
error:
fprintf
(
stderr
,
"failed to delete from the radix %lu
\n
"
,
found
);
fprintf
(
stderr
,
"failed to delete from the radix %lu
\n
"
,
found
);
return
-
1
;
return
-
1
;
}
}
...
...
fs/btrfs/disk-io.c
浏览文件 @
9f5fae2f
...
@@ -28,15 +28,15 @@ static int free_some_buffers(struct btrfs_root *root)
...
@@ -28,15 +28,15 @@ static int free_some_buffers(struct btrfs_root *root)
{
{
struct
list_head
*
node
,
*
next
;
struct
list_head
*
node
,
*
next
;
struct
btrfs_buffer
*
b
;
struct
btrfs_buffer
*
b
;
if
(
root
->
cache_size
<
cache_max
)
if
(
root
->
fs_info
->
cache_size
<
cache_max
)
return
0
;
return
0
;
list_for_each_safe
(
node
,
next
,
&
root
->
cache
)
{
list_for_each_safe
(
node
,
next
,
&
root
->
fs_info
->
cache
)
{
b
=
list_entry
(
node
,
struct
btrfs_buffer
,
cache
);
b
=
list_entry
(
node
,
struct
btrfs_buffer
,
cache
);
if
(
b
->
count
==
1
)
{
if
(
b
->
count
==
1
)
{
BUG_ON
(
!
list_empty
(
&
b
->
dirty
));
BUG_ON
(
!
list_empty
(
&
b
->
dirty
));
list_del_init
(
&
b
->
cache
);
list_del_init
(
&
b
->
cache
);
btrfs_block_release
(
root
,
b
);
btrfs_block_release
(
root
,
b
);
if
(
root
->
cache_size
<
cache_max
)
if
(
root
->
fs_info
->
cache_size
<
cache_max
)
break
;
break
;
}
}
}
}
...
@@ -57,10 +57,10 @@ struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
...
@@ -57,10 +57,10 @@ struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
INIT_LIST_HEAD
(
&
buf
->
dirty
);
INIT_LIST_HEAD
(
&
buf
->
dirty
);
free_some_buffers
(
root
);
free_some_buffers
(
root
);
radix_tree_preload
(
GFP_KERNEL
);
radix_tree_preload
(
GFP_KERNEL
);
ret
=
radix_tree_insert
(
&
root
->
cache_radix
,
blocknr
,
buf
);
ret
=
radix_tree_insert
(
&
root
->
fs_info
->
cache_radix
,
blocknr
,
buf
);
radix_tree_preload_end
();
radix_tree_preload_end
();
list_add_tail
(
&
buf
->
cache
,
&
root
->
cache
);
list_add_tail
(
&
buf
->
cache
,
&
root
->
fs_info
->
cache
);
root
->
cache_size
++
;
root
->
fs_info
->
cache_size
++
;
if
(
ret
)
{
if
(
ret
)
{
free
(
buf
);
free
(
buf
);
return
NULL
;
return
NULL
;
...
@@ -71,7 +71,7 @@ struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
...
@@ -71,7 +71,7 @@ struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
struct
btrfs_buffer
*
find_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
)
struct
btrfs_buffer
*
find_tree_block
(
struct
btrfs_root
*
root
,
u64
blocknr
)
{
{
struct
btrfs_buffer
*
buf
;
struct
btrfs_buffer
*
buf
;
buf
=
radix_tree_lookup
(
&
root
->
cache_radix
,
blocknr
);
buf
=
radix_tree_lookup
(
&
root
->
fs_info
->
cache_radix
,
blocknr
);
if
(
buf
)
{
if
(
buf
)
{
buf
->
count
++
;
buf
->
count
++
;
}
else
{
}
else
{
...
@@ -90,14 +90,15 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
...
@@ -90,14 +90,15 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
struct
btrfs_buffer
*
buf
;
struct
btrfs_buffer
*
buf
;
int
ret
;
int
ret
;
buf
=
radix_tree_lookup
(
&
root
->
cache_radix
,
blocknr
);
buf
=
radix_tree_lookup
(
&
root
->
fs_info
->
cache_radix
,
blocknr
);
if
(
buf
)
{
if
(
buf
)
{
buf
->
count
++
;
buf
->
count
++
;
}
else
{
}
else
{
buf
=
alloc_tree_block
(
root
,
blocknr
);
buf
=
alloc_tree_block
(
root
,
blocknr
);
if
(
!
buf
)
if
(
!
buf
)
return
NULL
;
return
NULL
;
ret
=
pread
(
root
->
fp
,
&
buf
->
node
,
root
->
blocksize
,
offset
);
ret
=
pread
(
root
->
fs_info
->
fp
,
&
buf
->
node
,
root
->
blocksize
,
offset
);
if
(
ret
!=
root
->
blocksize
)
{
if
(
ret
!=
root
->
blocksize
)
{
free
(
buf
);
free
(
buf
);
return
NULL
;
return
NULL
;
...
@@ -113,7 +114,7 @@ int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
...
@@ -113,7 +114,7 @@ int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
{
{
if
(
!
list_empty
(
&
buf
->
dirty
))
if
(
!
list_empty
(
&
buf
->
dirty
))
return
0
;
return
0
;
list_add_tail
(
&
buf
->
dirty
,
&
root
->
trans
);
list_add_tail
(
&
buf
->
dirty
,
&
root
->
fs_info
->
trans
);
buf
->
count
++
;
buf
->
count
++
;
return
0
;
return
0
;
}
}
...
@@ -137,7 +138,7 @@ int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
...
@@ -137,7 +138,7 @@ int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if
(
buf
->
blocknr
!=
btrfs_header_blocknr
(
&
buf
->
node
.
header
))
if
(
buf
->
blocknr
!=
btrfs_header_blocknr
(
&
buf
->
node
.
header
))
BUG
();
BUG
();
ret
=
pwrite
(
root
->
fp
,
&
buf
->
node
,
root
->
blocksize
,
offset
);
ret
=
pwrite
(
root
->
f
s_info
->
f
p
,
&
buf
->
node
,
root
->
blocksize
,
offset
);
if
(
ret
!=
root
->
blocksize
)
if
(
ret
!=
root
->
blocksize
)
return
ret
;
return
ret
;
return
0
;
return
0
;
...
@@ -149,8 +150,9 @@ static int __commit_transaction(struct btrfs_trans_handle *trans, struct
...
@@ -149,8 +150,9 @@ static int __commit_transaction(struct btrfs_trans_handle *trans, struct
struct
btrfs_buffer
*
b
;
struct
btrfs_buffer
*
b
;
int
ret
=
0
;
int
ret
=
0
;
int
wret
;
int
wret
;
while
(
!
list_empty
(
&
root
->
trans
))
{
while
(
!
list_empty
(
&
root
->
fs_info
->
trans
))
{
b
=
list_entry
(
root
->
trans
.
next
,
struct
btrfs_buffer
,
dirty
);
b
=
list_entry
(
root
->
fs_info
->
trans
.
next
,
struct
btrfs_buffer
,
dirty
);
list_del_init
(
&
b
->
dirty
);
list_del_init
(
&
b
->
dirty
);
wret
=
write_tree_block
(
trans
,
root
,
b
);
wret
=
write_tree_block
(
trans
,
root
,
b
);
if
(
wret
)
if
(
wret
)
...
@@ -160,13 +162,21 @@ static int __commit_transaction(struct btrfs_trans_handle *trans, struct
...
@@ -160,13 +162,21 @@ static int __commit_transaction(struct btrfs_trans_handle *trans, struct
return
ret
;
return
ret
;
}
}
static
int
commit_extent_and_tree_roots
(
struct
btrfs_trans_handle
*
trans
,
static
int
commit_tree_roots
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
tree_root
,
struct
struct
btrfs_fs_info
*
fs_info
)
btrfs_root
*
extent_root
)
{
{
int
ret
;
int
ret
;
u64
old_extent_block
;
u64
old_extent_block
;
struct
btrfs_root
*
tree_root
=
fs_info
->
tree_root
;
struct
btrfs_root
*
extent_root
=
fs_info
->
extent_root
;
struct
btrfs_root
*
inode_root
=
fs_info
->
inode_root
;
btrfs_set_root_blocknr
(
&
inode_root
->
root_item
,
inode_root
->
node
->
blocknr
);
ret
=
btrfs_update_root
(
trans
,
tree_root
,
&
inode_root
->
root_key
,
&
inode_root
->
root_item
);
BUG_ON
(
ret
);
while
(
1
)
{
while
(
1
)
{
old_extent_block
=
btrfs_root_blocknr
(
&
extent_root
->
root_item
);
old_extent_block
=
btrfs_root_blocknr
(
&
extent_root
->
root_item
);
if
(
old_extent_block
==
extent_root
->
node
->
blocknr
)
if
(
old_extent_block
==
extent_root
->
node
->
blocknr
)
...
@@ -178,8 +188,6 @@ static int commit_extent_and_tree_roots(struct btrfs_trans_handle *trans,
...
@@ -178,8 +188,6 @@ static int commit_extent_and_tree_roots(struct btrfs_trans_handle *trans,
&
extent_root
->
root_item
);
&
extent_root
->
root_item
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
}
}
__commit_transaction
(
trans
,
extent_root
);
__commit_transaction
(
trans
,
tree_root
);
return
0
;
return
0
;
}
}
...
@@ -190,9 +198,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
...
@@ -190,9 +198,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
struct
btrfs_buffer
*
snap
=
root
->
commit_root
;
struct
btrfs_buffer
*
snap
=
root
->
commit_root
;
struct
btrfs_key
snap_key
;
struct
btrfs_key
snap_key
;
ret
=
__commit_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
if
(
root
->
commit_root
==
root
->
node
)
if
(
root
->
commit_root
==
root
->
node
)
return
0
;
return
0
;
...
@@ -200,54 +205,55 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
...
@@ -200,54 +205,55 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
root
->
root_key
.
offset
++
;
root
->
root_key
.
offset
++
;
btrfs_set_root_blocknr
(
&
root
->
root_item
,
root
->
node
->
blocknr
);
btrfs_set_root_blocknr
(
&
root
->
root_item
,
root
->
node
->
blocknr
);
ret
=
btrfs_insert_root
(
trans
,
root
->
tree_root
,
&
root
->
root_key
,
ret
=
btrfs_insert_root
(
trans
,
root
->
fs_info
->
tree_root
,
&
root
->
root_item
);
&
root
->
root_key
,
&
root
->
root_item
);
BUG_ON
(
ret
);
ret
=
commit_tree_roots
(
trans
,
root
->
fs_info
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
ret
=
commit_extent_and_tree_roots
(
trans
,
root
->
tree_root
,
ret
=
__commit_transaction
(
trans
,
root
);
root
->
extent_root
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
write_ctree_super
(
trans
,
root
,
s
);
write_ctree_super
(
trans
,
root
,
s
);
btrfs_finish_extent_commit
(
trans
,
root
->
extent_root
);
btrfs_finish_extent_commit
(
trans
,
root
->
fs_info
->
extent_root
);
btrfs_finish_extent_commit
(
trans
,
root
->
tree_root
);
btrfs_finish_extent_commit
(
trans
,
root
->
fs_info
->
tree_root
);
root
->
commit_root
=
root
->
node
;
root
->
commit_root
=
root
->
node
;
root
->
node
->
count
++
;
root
->
node
->
count
++
;
ret
=
btrfs_drop_snapshot
(
trans
,
root
,
snap
);
ret
=
btrfs_drop_snapshot
(
trans
,
root
,
snap
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
ret
=
btrfs_del_root
(
trans
,
root
->
tree_root
,
&
snap_key
);
ret
=
btrfs_del_root
(
trans
,
root
->
fs_info
->
tree_root
,
&
snap_key
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
return
ret
;
return
ret
;
}
}
static
int
__setup_root
(
struct
btrfs_super_block
*
super
,
static
int
__setup_root
(
struct
btrfs_super_block
*
super
,
struct
btrfs_root
*
root
,
u64
objectid
,
int
fp
)
struct
btrfs_root
*
root
,
struct
btrfs_fs_info
*
fs_info
,
u64
objectid
,
int
fp
)
{
{
INIT_LIST_HEAD
(
&
root
->
trans
);
INIT_LIST_HEAD
(
&
root
->
cache
);
root
->
cache_size
=
0
;
root
->
fp
=
fp
;
root
->
node
=
NULL
;
root
->
node
=
NULL
;
root
->
commit_root
=
NULL
;
root
->
commit_root
=
NULL
;
root
->
blocksize
=
btrfs_super_blocksize
(
super
);
root
->
blocksize
=
btrfs_super_blocksize
(
super
);
root
->
ref_cows
=
0
;
root
->
ref_cows
=
0
;
memset
(
&
root
->
current_insert
,
0
,
sizeof
(
root
->
current_insert
));
root
->
fs_info
=
fs_info
;
memset
(
&
root
->
last_insert
,
0
,
sizeof
(
root
->
last_insert
));
memset
(
&
root
->
root_key
,
0
,
sizeof
(
root
->
root_key
));
memset
(
&
root
->
root_key
,
0
,
sizeof
(
root
->
root_key
));
memset
(
&
root
->
root_item
,
0
,
sizeof
(
root
->
root_item
));
memset
(
&
root
->
root_item
,
0
,
sizeof
(
root
->
root_item
));
return
0
;
return
0
;
}
}
static
int
find_and_setup_root
(
struct
btrfs_super_block
*
super
,
static
int
find_and_setup_root
(
struct
btrfs_super_block
*
super
,
struct
btrfs_root
*
tree_root
,
u64
objectid
,
struct
btrfs_root
*
tree_root
,
struct
btrfs_fs_info
*
fs_info
,
u64
objectid
,
struct
btrfs_root
*
root
,
int
fp
)
struct
btrfs_root
*
root
,
int
fp
)
{
{
int
ret
;
int
ret
;
__setup_root
(
super
,
root
,
objectid
,
fp
);
__setup_root
(
super
,
root
,
fs_info
,
objectid
,
fp
);
ret
=
btrfs_find_last_root
(
tree_root
,
objectid
,
ret
=
btrfs_find_last_root
(
tree_root
,
objectid
,
&
root
->
root_item
,
&
root
->
root_key
);
&
root
->
root_item
,
&
root
->
root_key
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
...
@@ -263,29 +269,31 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
...
@@ -263,29 +269,31 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
struct
btrfs_root
*
root
=
malloc
(
sizeof
(
struct
btrfs_root
));
struct
btrfs_root
*
root
=
malloc
(
sizeof
(
struct
btrfs_root
));
struct
btrfs_root
*
extent_root
=
malloc
(
sizeof
(
struct
btrfs_root
));
struct
btrfs_root
*
extent_root
=
malloc
(
sizeof
(
struct
btrfs_root
));
struct
btrfs_root
*
tree_root
=
malloc
(
sizeof
(
struct
btrfs_root
));
struct
btrfs_root
*
tree_root
=
malloc
(
sizeof
(
struct
btrfs_root
));
struct
btrfs_root
*
inode_root
=
malloc
(
sizeof
(
struct
btrfs_root
));
struct
btrfs_fs_info
*
fs_info
=
malloc
(
sizeof
(
*
fs_info
));
int
fp
;
int
fp
;
int
ret
;
int
ret
;
root
->
extent_root
=
extent_root
;
root
->
tree_root
=
tree_root
;
extent_root
->
extent_root
=
extent_root
;
extent_root
->
tree_root
=
tree_root
;
tree_root
->
extent_root
=
extent_root
;
tree_root
->
tree_root
=
tree_root
;
fp
=
open
(
filename
,
O_CREAT
|
O_RDWR
,
0600
);
fp
=
open
(
filename
,
O_CREAT
|
O_RDWR
,
0600
);
if
(
fp
<
0
)
{
if
(
fp
<
0
)
{
free
(
root
);
free
(
root
);
return
NULL
;
return
NULL
;
}
}
INIT_RADIX_TREE
(
&
root
->
cache_radix
,
GFP_KERNEL
);
INIT_RADIX_TREE
(
&
fs_info
->
cache_radix
,
GFP_KERNEL
);
INIT_RADIX_TREE
(
&
root
->
pinned_radix
,
GFP_KERNEL
);
INIT_RADIX_TREE
(
&
fs_info
->
pinned_radix
,
GFP_KERNEL
);
INIT_RADIX_TREE
(
&
extent_root
->
pinned_radix
,
GFP_KERNEL
);
INIT_LIST_HEAD
(
&
fs_info
->
trans
);
INIT_RADIX_TREE
(
&
extent_root
->
cache_radix
,
GFP_KERNEL
);
INIT_LIST_HEAD
(
&
fs_info
->
cache
);
INIT_RADIX_TREE
(
&
tree_root
->
pinned_radix
,
GFP_KERNEL
);
fs_info
->
cache_size
=
0
;
INIT_RADIX_TREE
(
&
tree_root
->
cache_radix
,
GFP_KERNEL
);
fs_info
->
fp
=
fp
;
fs_info
->
running_transaction
=
NULL
;
fs_info
->
fs_root
=
root
;
fs_info
->
tree_root
=
tree_root
;
fs_info
->
extent_root
=
extent_root
;
fs_info
->
inode_root
=
inode_root
;
fs_info
->
last_inode_alloc
=
0
;
fs_info
->
last_inode_alloc_dirid
=
0
;
memset
(
&
fs_info
->
current_insert
,
0
,
sizeof
(
fs_info
->
current_insert
));
memset
(
&
fs_info
->
last_insert
,
0
,
sizeof
(
fs_info
->
last_insert
));
ret
=
pread
(
fp
,
super
,
sizeof
(
struct
btrfs_super_block
),
ret
=
pread
(
fp
,
super
,
sizeof
(
struct
btrfs_super_block
),
BTRFS_SUPER_INFO_OFFSET
);
BTRFS_SUPER_INFO_OFFSET
);
...
@@ -301,16 +309,20 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
...
@@ -301,16 +309,20 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
}
}
BUG_ON
(
ret
<
0
);
BUG_ON
(
ret
<
0
);
__setup_root
(
super
,
tree_root
,
BTRFS_ROOT_TREE_OBJECTID
,
fp
);
__setup_root
(
super
,
tree_root
,
fs_info
,
BTRFS_ROOT_TREE_OBJECTID
,
fp
);
tree_root
->
node
=
read_tree_block
(
tree_root
,
btrfs_super_root
(
super
));
tree_root
->
node
=
read_tree_block
(
tree_root
,
btrfs_super_root
(
super
));
BUG_ON
(
!
tree_root
->
node
);
BUG_ON
(
!
tree_root
->
node
);
ret
=
find_and_setup_root
(
super
,
tree_root
,
BTRFS_EXTENT_TREE_OBJECTID
,
ret
=
find_and_setup_root
(
super
,
tree_root
,
fs_info
,
extent_root
,
fp
);
BTRFS_EXTENT_TREE_OBJECTID
,
extent_root
,
fp
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
ret
=
find_and_setup_root
(
super
,
tree_root
,
BTRFS_FS_TREE_OBJECTID
,
ret
=
find_and_setup_root
(
super
,
tree_root
,
fs_info
,
root
,
fp
);
BTRFS_INODE_MAP_OBJECTID
,
inode_root
,
fp
);
BUG_ON
(
ret
);
ret
=
find_and_setup_root
(
super
,
tree_root
,
fs_info
,
BTRFS_FS_TREE_OBJECTID
,
root
,
fp
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
root
->
commit_root
=
root
->
node
;
root
->
commit_root
=
root
->
node
;
...
@@ -323,8 +335,8 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -323,8 +335,8 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
*
root
,
struct
btrfs_super_block
*
s
)
*
root
,
struct
btrfs_super_block
*
s
)
{
{
int
ret
;
int
ret
;
btrfs_set_super_root
(
s
,
root
->
tree_root
->
node
->
blocknr
);
btrfs_set_super_root
(
s
,
root
->
fs_info
->
tree_root
->
node
->
blocknr
);
ret
=
pwrite
(
root
->
fp
,
s
,
sizeof
(
*
s
),
ret
=
pwrite
(
root
->
f
s_info
->
f
p
,
s
,
sizeof
(
*
s
),
BTRFS_SUPER_INFO_OFFSET
);
BTRFS_SUPER_INFO_OFFSET
);
if
(
ret
!=
sizeof
(
*
s
))
{
if
(
ret
!=
sizeof
(
*
s
))
{
fprintf
(
stderr
,
"failed to write new super block err %d
\n
"
,
ret
);
fprintf
(
stderr
,
"failed to write new super block err %d
\n
"
,
ret
);
...
@@ -335,9 +347,10 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -335,9 +347,10 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
static
int
drop_cache
(
struct
btrfs_root
*
root
)
static
int
drop_cache
(
struct
btrfs_root
*
root
)
{
{
while
(
!
list_empty
(
&
root
->
cache
))
{
while
(
!
list_empty
(
&
root
->
fs_info
->
cache
))
{
struct
btrfs_buffer
*
b
=
list_entry
(
root
->
cache
.
next
,
struct
btrfs_buffer
*
b
=
list_entry
(
root
->
fs_info
->
cache
.
next
,
struct
btrfs_buffer
,
cache
);
struct
btrfs_buffer
,
cache
);
list_del_init
(
&
b
->
cache
);
list_del_init
(
&
b
->
cache
);
btrfs_block_release
(
root
,
b
);
btrfs_block_release
(
root
,
b
);
}
}
...
@@ -348,26 +361,28 @@ int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s)
...
@@ -348,26 +361,28 @@ int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s)
int
ret
;
int
ret
;
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_trans_handle
*
trans
;
trans
=
root
->
running_transaction
;
trans
=
root
->
fs_info
->
running_transaction
;
btrfs_commit_transaction
(
trans
,
root
,
s
);
btrfs_commit_transaction
(
trans
,
root
,
s
);
ret
=
commit_extent_and_tree_roots
(
trans
,
root
->
tree_root
,
ret
=
commit_tree_roots
(
trans
,
root
->
fs_info
);
root
->
extent_root
);
BUG_ON
(
ret
);
ret
=
__commit_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
write_ctree_super
(
trans
,
root
,
s
);
write_ctree_super
(
trans
,
root
,
s
);
drop_cache
(
root
->
extent_root
);
drop_cache
(
root
->
tree_root
);
drop_cache
(
root
);
drop_cache
(
root
);
BUG_ON
(
!
list_empty
(
&
root
->
trans
));
BUG_ON
(
!
list_empty
(
&
root
->
fs_info
->
trans
));
BUG_ON
(
!
list_empty
(
&
root
->
extent_root
->
trans
));
BUG_ON
(
!
list_empty
(
&
root
->
tree_root
->
trans
));
close
(
root
->
fp
);
close
(
root
->
f
s_info
->
f
p
);
if
(
root
->
node
)
if
(
root
->
node
)
btrfs_block_release
(
root
,
root
->
node
);
btrfs_block_release
(
root
,
root
->
node
);
if
(
root
->
extent_root
->
node
)
if
(
root
->
fs_info
->
extent_root
->
node
)
btrfs_block_release
(
root
->
extent_root
,
root
->
extent_root
->
node
);
btrfs_block_release
(
root
->
fs_info
->
extent_root
,
if
(
root
->
tree_root
->
node
)
root
->
fs_info
->
extent_root
->
node
);
btrfs_block_release
(
root
->
tree_root
,
root
->
tree_root
->
node
);
if
(
root
->
fs_info
->
inode_root
->
node
)
btrfs_block_release
(
root
->
fs_info
->
inode_root
,
root
->
fs_info
->
inode_root
->
node
);
if
(
root
->
fs_info
->
tree_root
->
node
)
btrfs_block_release
(
root
->
fs_info
->
tree_root
,
root
->
fs_info
->
tree_root
->
node
);
btrfs_block_release
(
root
,
root
->
commit_root
);
btrfs_block_release
(
root
,
root
->
commit_root
);
free
(
root
);
free
(
root
);
printf
(
"on close %d blocks are allocated
\n
"
,
allocated_blocks
);
printf
(
"on close %d blocks are allocated
\n
"
,
allocated_blocks
);
...
@@ -382,15 +397,16 @@ void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf)
...
@@ -382,15 +397,16 @@ void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf)
if
(
buf
->
count
==
0
)
{
if
(
buf
->
count
==
0
)
{
BUG_ON
(
!
list_empty
(
&
buf
->
cache
));
BUG_ON
(
!
list_empty
(
&
buf
->
cache
));
BUG_ON
(
!
list_empty
(
&
buf
->
dirty
));
BUG_ON
(
!
list_empty
(
&
buf
->
dirty
));
if
(
!
radix_tree_lookup
(
&
root
->
cache_radix
,
buf
->
blocknr
))
if
(
!
radix_tree_lookup
(
&
root
->
fs_info
->
cache_radix
,
buf
->
blocknr
))
BUG
();
BUG
();
radix_tree_delete
(
&
root
->
cache_radix
,
buf
->
blocknr
);
radix_tree_delete
(
&
root
->
fs_info
->
cache_radix
,
buf
->
blocknr
);
memset
(
buf
,
0
,
sizeof
(
*
buf
));
memset
(
buf
,
0
,
sizeof
(
*
buf
));
free
(
buf
);
free
(
buf
);
BUG_ON
(
allocated_blocks
==
0
);
BUG_ON
(
allocated_blocks
==
0
);
allocated_blocks
--
;
allocated_blocks
--
;
BUG_ON
(
root
->
cache_size
==
0
);
BUG_ON
(
root
->
fs_info
->
cache_size
==
0
);
root
->
cache_size
--
;
root
->
fs_info
->
cache_size
--
;
}
}
}
}
fs/btrfs/extent-tree.c
浏览文件 @
9f5fae2f
...
@@ -35,13 +35,15 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -35,13 +35,15 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
struct
btrfs_key
ins
;
struct
btrfs_key
ins
;
u32
refs
;
u32
refs
;
find_free_extent
(
trans
,
root
->
extent_root
,
0
,
0
,
(
u64
)
-
1
,
&
ins
);
find_free_extent
(
trans
,
root
->
fs_info
->
extent_root
,
0
,
0
,
(
u64
)
-
1
,
&
ins
);
btrfs_init_path
(
&
path
);
btrfs_init_path
(
&
path
);
key
.
objectid
=
blocknr
;
key
.
objectid
=
blocknr
;
key
.
flags
=
0
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_ITEM_KEY
);
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_ITEM_KEY
);
key
.
offset
=
1
;
key
.
offset
=
1
;
ret
=
btrfs_search_slot
(
trans
,
root
->
extent_root
,
&
key
,
&
path
,
0
,
1
);
ret
=
btrfs_search_slot
(
trans
,
root
->
fs_info
->
extent_root
,
&
key
,
&
path
,
0
,
1
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
BUG
();
BUG
();
BUG_ON
(
ret
!=
0
);
BUG_ON
(
ret
!=
0
);
...
@@ -51,9 +53,9 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -51,9 +53,9 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_extent_refs
(
item
,
refs
+
1
);
btrfs_set_extent_refs
(
item
,
refs
+
1
);
BUG_ON
(
list_empty
(
&
path
.
nodes
[
0
]
->
dirty
));
BUG_ON
(
list_empty
(
&
path
.
nodes
[
0
]
->
dirty
));
btrfs_release_path
(
root
->
extent_root
,
&
path
);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
&
path
);
finish_current_insert
(
trans
,
root
->
extent_root
);
finish_current_insert
(
trans
,
root
->
fs_info
->
extent_root
);
run_pending
(
trans
,
root
->
extent_root
);
run_pending
(
trans
,
root
->
fs_info
->
extent_root
);
return
0
;
return
0
;
}
}
...
@@ -70,13 +72,14 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -70,13 +72,14 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
key
.
offset
=
1
;
key
.
offset
=
1
;
key
.
flags
=
0
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_ITEM_KEY
);
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_ITEM_KEY
);
ret
=
btrfs_search_slot
(
trans
,
root
->
extent_root
,
&
key
,
&
path
,
0
,
0
);
ret
=
btrfs_search_slot
(
trans
,
root
->
fs_info
->
extent_root
,
&
key
,
&
path
,
0
,
0
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
BUG
();
BUG
();
l
=
&
path
.
nodes
[
0
]
->
leaf
;
l
=
&
path
.
nodes
[
0
]
->
leaf
;
item
=
btrfs_item_ptr
(
l
,
path
.
slots
[
0
],
struct
btrfs_extent_item
);
item
=
btrfs_item_ptr
(
l
,
path
.
slots
[
0
],
struct
btrfs_extent_item
);
*
refs
=
btrfs_extent_refs
(
item
);
*
refs
=
btrfs_extent_refs
(
item
);
btrfs_release_path
(
root
->
extent_root
,
&
path
);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
&
path
);
return
0
;
return
0
;
}
}
...
@@ -107,7 +110,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
...
@@ -107,7 +110,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
int
i
;
int
i
;
while
(
1
)
{
while
(
1
)
{
ret
=
radix_tree_gang_lookup
(
&
root
->
pinned_radix
,
ret
=
radix_tree_gang_lookup
(
&
root
->
fs_info
->
pinned_radix
,
(
void
**
)
gang
,
0
,
(
void
**
)
gang
,
0
,
ARRAY_SIZE
(
gang
));
ARRAY_SIZE
(
gang
));
if
(
!
ret
)
if
(
!
ret
)
...
@@ -115,11 +118,12 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
...
@@ -115,11 +118,12 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
if
(
!
first
)
if
(
!
first
)
first
=
gang
[
0
];
first
=
gang
[
0
];
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
radix_tree_delete
(
&
root
->
pinned_radix
,
gang
[
i
]);
radix_tree_delete
(
&
root
->
fs_info
->
pinned_radix
,
gang
[
i
]);
}
}
}
}
root
->
last_insert
.
objectid
=
first
;
root
->
fs_info
->
last_insert
.
objectid
=
first
;
root
->
last_insert
.
offset
=
0
;
root
->
fs_info
->
last_insert
.
offset
=
0
;
return
0
;
return
0
;
}
}
...
@@ -138,13 +142,14 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
...
@@ -138,13 +142,14 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
ins
.
flags
=
0
;
ins
.
flags
=
0
;
btrfs_set_key_type
(
&
ins
,
BTRFS_EXTENT_ITEM_KEY
);
btrfs_set_key_type
(
&
ins
,
BTRFS_EXTENT_ITEM_KEY
);
for
(
i
=
0
;
i
<
extent_root
->
current_insert
.
flags
;
i
++
)
{
for
(
i
=
0
;
i
<
extent_root
->
fs_info
->
current_insert
.
flags
;
i
++
)
{
ins
.
objectid
=
extent_root
->
current_insert
.
objectid
+
i
;
ins
.
objectid
=
extent_root
->
fs_info
->
current_insert
.
objectid
+
i
;
ret
=
btrfs_insert_item
(
trans
,
extent_root
,
&
ins
,
&
extent_item
,
ret
=
btrfs_insert_item
(
trans
,
extent_root
,
&
ins
,
&
extent_item
,
sizeof
(
extent_item
));
sizeof
(
extent_item
));
BUG_ON
(
ret
);
BUG_ON
(
ret
);
}
}
extent_root
->
current_insert
.
offset
=
0
;
extent_root
->
fs_info
->
current_insert
.
offset
=
0
;
return
0
;
return
0
;
}
}
...
@@ -156,7 +161,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -156,7 +161,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
{
{
struct
btrfs_path
path
;
struct
btrfs_path
path
;
struct
btrfs_key
key
;
struct
btrfs_key
key
;
struct
btrfs_root
*
extent_root
=
root
->
extent_root
;
struct
btrfs_root
*
extent_root
=
root
->
fs_info
->
extent_root
;
int
ret
;
int
ret
;
struct
btrfs_extent_item
*
ei
;
struct
btrfs_extent_item
*
ei
;
struct
btrfs_key
ins
;
struct
btrfs_key
ins
;
...
@@ -186,14 +191,16 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -186,14 +191,16 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
if
(
pin
)
{
if
(
pin
)
{
int
err
;
int
err
;
radix_tree_preload
(
GFP_KERNEL
);
radix_tree_preload
(
GFP_KERNEL
);
err
=
radix_tree_insert
(
&
extent_root
->
pinned_radix
,
err
=
radix_tree_insert
(
&
extent_root
->
fs_info
->
pinned_radix
,
blocknr
,
(
void
*
)
blocknr
);
blocknr
,
(
void
*
)
blocknr
);
BUG_ON
(
err
);
BUG_ON
(
err
);
radix_tree_preload_end
();
radix_tree_preload_end
();
}
}
ret
=
btrfs_del_item
(
trans
,
extent_root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
extent_root
,
&
path
);
if
(
!
pin
&&
extent_root
->
last_insert
.
objectid
>
blocknr
)
if
(
!
pin
&&
extent_root
->
fs_info
->
last_insert
.
objectid
>
extent_root
->
last_insert
.
objectid
=
blocknr
;
blocknr
)
extent_root
->
fs_info
->
last_insert
.
objectid
=
blocknr
;
if
(
ret
)
if
(
ret
)
BUG
();
BUG
();
}
}
...
@@ -214,7 +221,8 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
...
@@ -214,7 +221,8 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
int
i
;
int
i
;
while
(
1
)
{
while
(
1
)
{
ret
=
radix_tree_gang_lookup_tag
(
&
extent_root
->
cache_radix
,
ret
=
radix_tree_gang_lookup_tag
(
&
extent_root
->
fs_info
->
cache_radix
,
(
void
**
)
gang
,
0
,
(
void
**
)
gang
,
0
,
ARRAY_SIZE
(
gang
),
ARRAY_SIZE
(
gang
),
CTREE_EXTENT_PENDING_DEL
);
CTREE_EXTENT_PENDING_DEL
);
...
@@ -223,7 +231,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
...
@@ -223,7 +231,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
ret
=
__free_extent
(
trans
,
extent_root
,
ret
=
__free_extent
(
trans
,
extent_root
,
gang
[
i
]
->
blocknr
,
1
,
1
);
gang
[
i
]
->
blocknr
,
1
,
1
);
radix_tree_tag_clear
(
&
extent_root
->
cache_radix
,
radix_tree_tag_clear
(
&
extent_root
->
fs_info
->
cache_radix
,
gang
[
i
]
->
blocknr
,
gang
[
i
]
->
blocknr
,
CTREE_EXTENT_PENDING_DEL
);
CTREE_EXTENT_PENDING_DEL
);
btrfs_block_release
(
extent_root
,
gang
[
i
]);
btrfs_block_release
(
extent_root
,
gang
[
i
]);
...
@@ -235,7 +243,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
...
@@ -235,7 +243,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
static
int
run_pending
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
static
int
run_pending
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
extent_root
)
*
extent_root
)
{
{
while
(
radix_tree_tagged
(
&
extent_root
->
cache_radix
,
while
(
radix_tree_tagged
(
&
extent_root
->
fs_info
->
cache_radix
,
CTREE_EXTENT_PENDING_DEL
))
CTREE_EXTENT_PENDING_DEL
))
del_pending_extents
(
trans
,
extent_root
);
del_pending_extents
(
trans
,
extent_root
);
return
0
;
return
0
;
...
@@ -248,19 +256,19 @@ static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -248,19 +256,19 @@ static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
int
btrfs_free_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
int
btrfs_free_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
,
int
pin
)
*
root
,
u64
blocknr
,
u64
num_blocks
,
int
pin
)
{
{
struct
btrfs_root
*
extent_root
=
root
->
extent_root
;
struct
btrfs_root
*
extent_root
=
root
->
fs_info
->
extent_root
;
struct
btrfs_buffer
*
t
;
struct
btrfs_buffer
*
t
;
int
pending_ret
;
int
pending_ret
;
int
ret
;
int
ret
;
if
(
root
==
extent_root
)
{
if
(
root
==
extent_root
)
{
t
=
find_tree_block
(
root
,
blocknr
);
t
=
find_tree_block
(
root
,
blocknr
);
radix_tree_tag_set
(
&
root
->
cache_radix
,
blocknr
,
radix_tree_tag_set
(
&
root
->
fs_info
->
cache_radix
,
blocknr
,
CTREE_EXTENT_PENDING_DEL
);
CTREE_EXTENT_PENDING_DEL
);
return
0
;
return
0
;
}
}
ret
=
__free_extent
(
trans
,
root
,
blocknr
,
num_blocks
,
pin
);
ret
=
__free_extent
(
trans
,
root
,
blocknr
,
num_blocks
,
pin
);
pending_ret
=
run_pending
(
trans
,
root
->
extent_root
);
pending_ret
=
run_pending
(
trans
,
root
->
fs_info
->
extent_root
);
return
ret
?
ret
:
pending_ret
;
return
ret
?
ret
:
pending_ret
;
}
}
...
@@ -285,12 +293,12 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -285,12 +293,12 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
u64
test_block
;
u64
test_block
;
int
start_found
;
int
start_found
;
struct
btrfs_leaf
*
l
;
struct
btrfs_leaf
*
l
;
struct
btrfs_root
*
root
=
orig_root
->
extent_root
;
struct
btrfs_root
*
root
=
orig_root
->
fs_info
->
extent_root
;
int
total_needed
=
num_blocks
;
int
total_needed
=
num_blocks
;
total_needed
+=
(
btrfs_header_level
(
&
root
->
node
->
node
.
header
)
+
1
)
*
3
;
total_needed
+=
(
btrfs_header_level
(
&
root
->
node
->
node
.
header
)
+
1
)
*
3
;
if
(
root
->
last_insert
.
objectid
>
search_start
)
if
(
root
->
fs_info
->
last_insert
.
objectid
>
search_start
)
search_start
=
root
->
last_insert
.
objectid
;
search_start
=
root
->
fs_info
->
last_insert
.
objectid
;
ins
->
flags
=
0
;
ins
->
flags
=
0
;
btrfs_set_key_type
(
ins
,
BTRFS_EXTENT_ITEM_KEY
);
btrfs_set_key_type
(
ins
,
BTRFS_EXTENT_ITEM_KEY
);
...
@@ -353,16 +361,17 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -353,16 +361,17 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON
(
ins
->
objectid
<
search_start
);
BUG_ON
(
ins
->
objectid
<
search_start
);
for
(
test_block
=
ins
->
objectid
;
for
(
test_block
=
ins
->
objectid
;
test_block
<
ins
->
objectid
+
total_needed
;
test_block
++
)
{
test_block
<
ins
->
objectid
+
total_needed
;
test_block
++
)
{
if
(
radix_tree_lookup
(
&
root
->
pinned_radix
,
test_block
))
{
if
(
radix_tree_lookup
(
&
root
->
fs_info
->
pinned_radix
,
test_block
))
{
search_start
=
test_block
+
1
;
search_start
=
test_block
+
1
;
goto
check_failed
;
goto
check_failed
;
}
}
}
}
BUG_ON
(
root
->
current_insert
.
offset
);
BUG_ON
(
root
->
fs_info
->
current_insert
.
offset
);
root
->
current_insert
.
offset
=
total_needed
-
num_blocks
;
root
->
fs_info
->
current_insert
.
offset
=
total_needed
-
num_blocks
;
root
->
current_insert
.
objectid
=
ins
->
objectid
+
num_blocks
;
root
->
fs_info
->
current_insert
.
objectid
=
ins
->
objectid
+
num_blocks
;
root
->
current_insert
.
flags
=
0
;
root
->
fs_info
->
current_insert
.
flags
=
0
;
root
->
last_insert
.
objectid
=
ins
->
objectid
;
root
->
fs_info
->
last_insert
.
objectid
=
ins
->
objectid
;
ins
->
offset
=
num_blocks
;
ins
->
offset
=
num_blocks
;
return
0
;
return
0
;
error:
error:
...
@@ -383,20 +392,20 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -383,20 +392,20 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
{
{
int
ret
;
int
ret
;
int
pending_ret
;
int
pending_ret
;
struct
btrfs_root
*
extent_root
=
root
->
extent_root
;
struct
btrfs_root
*
extent_root
=
root
->
fs_info
->
extent_root
;
struct
btrfs_extent_item
extent_item
;
struct
btrfs_extent_item
extent_item
;
btrfs_set_extent_refs
(
&
extent_item
,
1
);
btrfs_set_extent_refs
(
&
extent_item
,
1
);
btrfs_set_extent_owner
(
&
extent_item
,
owner
);
btrfs_set_extent_owner
(
&
extent_item
,
owner
);
if
(
root
==
extent_root
)
{
if
(
root
==
extent_root
)
{
BUG_ON
(
extent_root
->
current_insert
.
offset
==
0
);
BUG_ON
(
extent_root
->
fs_info
->
current_insert
.
offset
==
0
);
BUG_ON
(
num_blocks
!=
1
);
BUG_ON
(
num_blocks
!=
1
);
BUG_ON
(
extent_root
->
current_insert
.
flags
==
BUG_ON
(
extent_root
->
fs_info
->
current_insert
.
flags
==
extent_root
->
current_insert
.
offset
);
extent_root
->
fs_info
->
current_insert
.
offset
);
ins
->
offset
=
1
;
ins
->
offset
=
1
;
ins
->
objectid
=
extent_root
->
current_insert
.
objectid
+
ins
->
objectid
=
extent_root
->
fs_info
->
current_insert
.
objectid
+
extent_root
->
current_insert
.
flags
++
;
extent_root
->
fs_info
->
current_insert
.
flags
++
;
return
0
;
return
0
;
}
}
ret
=
find_free_extent
(
trans
,
root
,
num_blocks
,
search_start
,
ret
=
find_free_extent
(
trans
,
root
,
num_blocks
,
search_start
,
...
...
fs/btrfs/file-item.c
浏览文件 @
9f5fae2f
...
@@ -4,4 +4,10 @@
...
@@ -4,4 +4,10 @@
#include "radix-tree.h"
#include "radix-tree.h"
#include "ctree.h"
#include "ctree.h"
#include "disk-io.h"
#include "disk-io.h"
#include "transaction.h"
int
btrfs_create_file
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
dirid
,
u64
*
objectid
)
{
return
0
;
}
fs/btrfs/inode-map.c
0 → 100644
浏览文件 @
9f5fae2f
#include <stdio.h>
#include <stdlib.h>
#include "kerncompat.h"
#include "radix-tree.h"
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
/*
* walks the btree of allocated inodes and find a hole.
*/
int
btrfs_find_free_objectid
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
fs_root
,
u64
dirid
,
u64
*
objectid
)
{
struct
btrfs_path
path
;
struct
btrfs_key
key
;
int
ret
;
u64
hole_size
=
0
;
int
slot
=
0
;
u64
last_ino
;
int
start_found
;
struct
btrfs_leaf
*
l
;
struct
btrfs_root
*
root
=
fs_root
->
fs_info
->
inode_root
;
struct
btrfs_key
search_key
;
u64
search_start
=
dirid
;
if
(
fs_root
->
fs_info
->
last_inode_alloc_dirid
==
dirid
)
search_start
=
fs_root
->
fs_info
->
last_inode_alloc
;
search_key
.
objectid
=
search_start
;
search_key
.
flags
=
0
;
btrfs_set_key_type
(
&
search_key
,
BTRFS_INODE_MAP_ITEM_KEY
);
search_key
.
offset
=
0
;
btrfs_init_path
(
&
path
);
start_found
=
0
;
ret
=
btrfs_search_slot
(
trans
,
root
,
&
search_key
,
&
path
,
0
,
0
);
if
(
ret
<
0
)
goto
error
;
if
(
path
.
slots
[
0
]
>
0
)
path
.
slots
[
0
]
--
;
while
(
1
)
{
l
=
&
path
.
nodes
[
0
]
->
leaf
;
slot
=
path
.
slots
[
0
];
if
(
slot
>=
btrfs_header_nritems
(
&
l
->
header
))
{
ret
=
btrfs_next_leaf
(
root
,
&
path
);
if
(
ret
==
0
)
continue
;
if
(
ret
<
0
)
goto
error
;
if
(
!
start_found
)
{
*
objectid
=
search_start
;
start_found
=
1
;
goto
found
;
}
*
objectid
=
last_ino
>
search_start
?
last_ino
:
search_start
;
goto
found
;
}
btrfs_disk_key_to_cpu
(
&
key
,
&
l
->
items
[
slot
].
key
);
if
(
key
.
objectid
>=
search_start
)
{
if
(
start_found
)
{
if
(
last_ino
<
search_start
)
last_ino
=
search_start
;
hole_size
=
key
.
objectid
-
last_ino
;
if
(
hole_size
>
0
)
{
*
objectid
=
last_ino
;
goto
found
;
}
}
}
start_found
=
1
;
last_ino
=
key
.
objectid
+
1
;
path
.
slots
[
0
]
++
;
}
// FIXME -ENOSPC
found:
root
->
fs_info
->
last_inode_alloc
=
*
objectid
;
root
->
fs_info
->
last_inode_alloc_dirid
=
dirid
;
btrfs_release_path
(
root
,
&
path
);
BUG_ON
(
*
objectid
<
search_start
);
return
0
;
error:
btrfs_release_path
(
root
,
&
path
);
return
ret
;
}
int
btrfs_insert_inode_map
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
fs_root
,
u64
objectid
,
struct
btrfs_key
*
location
)
{
int
ret
=
0
;
struct
btrfs_path
path
;
struct
btrfs_inode_map_item
*
inode_item
;
struct
btrfs_key
key
;
struct
btrfs_root
*
inode_root
=
fs_root
->
fs_info
->
inode_root
;
key
.
objectid
=
objectid
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INODE_MAP_ITEM_KEY
);
key
.
offset
=
0
;
btrfs_init_path
(
&
path
);
ret
=
btrfs_insert_empty_item
(
trans
,
inode_root
,
&
path
,
&
key
,
sizeof
(
struct
btrfs_inode_map_item
));
if
(
ret
)
goto
out
;
inode_item
=
btrfs_item_ptr
(
&
path
.
nodes
[
0
]
->
leaf
,
path
.
slots
[
0
],
struct
btrfs_inode_map_item
);
btrfs_cpu_key_to_disk
(
&
inode_item
->
key
,
location
);
out:
btrfs_release_path
(
inode_root
,
&
path
);
return
ret
;
}
int
btrfs_lookup_inode_map
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
fs_root
,
struct
btrfs_path
*
path
,
u64
objectid
,
int
mod
)
{
int
ret
;
struct
btrfs_key
key
;
int
ins_len
=
mod
<
0
?
-
1
:
0
;
int
cow
=
mod
!=
0
;
struct
btrfs_root
*
inode_root
=
fs_root
->
fs_info
->
inode_root
;
key
.
objectid
=
objectid
;
key
.
flags
=
0
;
key
.
offset
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INODE_MAP_ITEM_KEY
);
ret
=
btrfs_search_slot
(
trans
,
inode_root
,
&
key
,
path
,
ins_len
,
cow
);
return
ret
;
}
fs/btrfs/mkfs.c
浏览文件 @
9f5fae2f
...
@@ -42,7 +42,7 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
...
@@ -42,7 +42,7 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
BTRFS_ROOT_TREE_OBJECTID
);
BTRFS_ROOT_TREE_OBJECTID
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
1
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
1
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
2
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
3
);
/* create the items for the root tree */
/* create the items for the root tree */
btrfs_set_root_blocknr
(
&
root_item
,
start_block
+
2
);
btrfs_set_root_blocknr
(
&
root_item
,
start_block
+
2
);
...
@@ -61,8 +61,16 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
...
@@ -61,8 +61,16 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
btrfs_set_root_blocknr
(
&
root_item
,
start_block
+
3
);
btrfs_set_root_blocknr
(
&
root_item
,
start_block
+
3
);
itemoff
=
itemoff
-
sizeof
(
root_item
);
itemoff
=
itemoff
-
sizeof
(
root_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_disk_key_objectid
(
&
item
.
key
,
BTRFS_
FS_TREE
_OBJECTID
);
btrfs_set_disk_key_objectid
(
&
item
.
key
,
BTRFS_
INODE_MAP
_OBJECTID
);
memcpy
(
empty_leaf
->
items
+
1
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
->
items
+
1
,
&
item
,
sizeof
(
item
));
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
itemoff
,
&
root_item
,
sizeof
(
root_item
));
btrfs_set_root_blocknr
(
&
root_item
,
start_block
+
4
);
itemoff
=
itemoff
-
sizeof
(
root_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_disk_key_objectid
(
&
item
.
key
,
BTRFS_FS_TREE_OBJECTID
);
memcpy
(
empty_leaf
->
items
+
2
,
&
item
,
sizeof
(
item
));
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
itemoff
,
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
itemoff
,
&
root_item
,
sizeof
(
root_item
));
&
root_item
,
sizeof
(
root_item
));
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
1
)
*
blocksize
);
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
1
)
*
blocksize
);
...
@@ -71,7 +79,7 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
...
@@ -71,7 +79,7 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
BTRFS_EXTENT_TREE_OBJECTID
);
BTRFS_EXTENT_TREE_OBJECTID
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
2
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
2
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
4
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
5
);
/* item1, reserve blocks 0-16 */
/* item1, reserve blocks 0-16 */
btrfs_set_disk_key_objectid
(
&
item
.
key
,
0
);
btrfs_set_disk_key_objectid
(
&
item
.
key
,
0
);
...
@@ -108,12 +116,12 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
...
@@ -108,12 +116,12 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
),
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
),
&
extent_item
,
btrfs_item_size
(
&
item
));
&
extent_item
,
btrfs_item_size
(
&
item
));
/* item4, give block 19 to the
FS root
*/
/* item4, give block 19 to the
inode map
*/
btrfs_set_disk_key_objectid
(
&
item
.
key
,
start_block
+
3
);
btrfs_set_disk_key_objectid
(
&
item
.
key
,
start_block
+
3
);
btrfs_set_disk_key_offset
(
&
item
.
key
,
1
);
btrfs_set_disk_key_offset
(
&
item
.
key
,
1
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_
FS_TREE
_OBJECTID
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_
INODE_MAP
_OBJECTID
);
memcpy
(
empty_leaf
->
items
+
3
,
&
item
,
sizeof
(
item
));
memcpy
(
empty_leaf
->
items
+
3
,
&
item
,
sizeof
(
item
));
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
),
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
),
&
extent_item
,
btrfs_item_size
(
&
item
));
&
extent_item
,
btrfs_item_size
(
&
item
));
...
@@ -121,11 +129,33 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
...
@@ -121,11 +129,33 @@ int mkfs(int fd, u64 num_blocks, u32 blocksize)
if
(
ret
!=
blocksize
)
if
(
ret
!=
blocksize
)
return
-
1
;
return
-
1
;
/* finally create the FS root */
/* item5, give block 20 to the FS root */
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
BTRFS_FS_TREE_OBJECTID
);
btrfs_set_disk_key_objectid
(
&
item
.
key
,
start_block
+
4
);
btrfs_set_disk_key_offset
(
&
item
.
key
,
1
);
itemoff
=
itemoff
-
sizeof
(
struct
btrfs_extent_item
);
btrfs_set_item_offset
(
&
item
,
itemoff
);
btrfs_set_extent_owner
(
&
extent_item
,
BTRFS_FS_TREE_OBJECTID
);
memcpy
(
empty_leaf
->
items
+
4
,
&
item
,
sizeof
(
item
));
memcpy
(
btrfs_leaf_data
(
empty_leaf
)
+
btrfs_item_offset
(
&
item
),
&
extent_item
,
btrfs_item_size
(
&
item
));
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
2
)
*
blocksize
);
if
(
ret
!=
blocksize
)
return
-
1
;
/* create the inode map */
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
BTRFS_INODE_MAP_OBJECTID
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
3
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
3
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
0
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
0
);
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
3
)
*
blocksize
);
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
3
)
*
blocksize
);
if
(
ret
!=
blocksize
)
return
-
1
;
/* finally create the FS root */
btrfs_set_header_parentid
(
&
empty_leaf
->
header
,
BTRFS_FS_TREE_OBJECTID
);
btrfs_set_header_blocknr
(
&
empty_leaf
->
header
,
start_block
+
4
);
btrfs_set_header_nritems
(
&
empty_leaf
->
header
,
0
);
ret
=
pwrite
(
fd
,
empty_leaf
,
blocksize
,
(
start_block
+
4
)
*
blocksize
);
if
(
ret
!=
blocksize
)
if
(
ret
!=
blocksize
)
return
-
1
;
return
-
1
;
return
0
;
return
0
;
...
...
fs/btrfs/print-tree.c
浏览文件 @
9f5fae2f
...
@@ -13,8 +13,8 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
...
@@ -13,8 +13,8 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
struct
btrfs_extent_item
*
ei
;
struct
btrfs_extent_item
*
ei
;
struct
btrfs_root_item
*
ri
;
struct
btrfs_root_item
*
ri
;
struct
btrfs_dir_item
*
di
;
struct
btrfs_dir_item
*
di
;
struct
btrfs_inode_map_item
*
mi
;
u32
type
;
u32
type
;
u32
namelen
;
printf
(
"leaf %Lu total ptrs %d free space %d
\n
"
,
printf
(
"leaf %Lu total ptrs %d free space %d
\n
"
,
btrfs_header_blocknr
(
&
l
->
header
),
nr
,
btrfs_header_blocknr
(
&
l
->
header
),
nr
,
...
@@ -34,15 +34,13 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
...
@@ -34,15 +34,13 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
case
BTRFS_INODE_ITEM_KEY
:
case
BTRFS_INODE_ITEM_KEY
:
break
;
break
;
case
BTRFS_DIR_ITEM_KEY
:
case
BTRFS_DIR_ITEM_KEY
:
namelen
=
btrfs_item_size
(
l
->
items
+
i
)
-
sizeof
(
*
di
);
di
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_dir_item
);
di
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_dir_item
);
printf
(
"
\t\t
dir oid %Lu flags %u type %u
\n
"
,
printf
(
"
\t\t
dir oid %Lu flags %u type %u
\n
"
,
btrfs_dir_objectid
(
di
),
btrfs_dir_objectid
(
di
),
btrfs_dir_flags
(
di
),
btrfs_dir_flags
(
di
),
btrfs_dir_type
(
di
));
btrfs_dir_type
(
di
));
printf
(
"
\t\t
name %.*s
\n
"
,
printf
(
"
\t\t
name %.*s
\n
"
,
namelen
,
(
char
*
)(
di
+
1
));
btrfs_dir_name_len
(
di
),(
char
*
)(
di
+
1
));
break
;
break
;
case
BTRFS_ROOT_ITEM_KEY
:
case
BTRFS_ROOT_ITEM_KEY
:
ri
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_root_item
);
ri
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_root_item
);
...
@@ -54,6 +52,13 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
...
@@ -54,6 +52,13 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
printf
(
"
\t\t
extent data refs %u owner %Lu
\n
"
,
printf
(
"
\t\t
extent data refs %u owner %Lu
\n
"
,
btrfs_extent_refs
(
ei
),
btrfs_extent_owner
(
ei
));
btrfs_extent_refs
(
ei
),
btrfs_extent_owner
(
ei
));
break
;
break
;
case
BTRFS_INODE_MAP_ITEM_KEY
:
mi
=
btrfs_item_ptr
(
l
,
i
,
struct
btrfs_inode_map_item
);
printf
(
"
\t\t
inode map key %Lu %u %Lu
\n
"
,
btrfs_disk_key_objectid
(
&
mi
->
key
),
btrfs_disk_key_flags
(
&
mi
->
key
),
btrfs_disk_key_offset
(
&
mi
->
key
));
break
;
case
BTRFS_STRING_ITEM_KEY
:
case
BTRFS_STRING_ITEM_KEY
:
printf
(
"
\t\t
item data %.*s
\n
"
,
btrfs_item_size
(
item
),
printf
(
"
\t\t
item data %.*s
\n
"
,
btrfs_item_size
(
item
),
btrfs_leaf_data
(
l
)
+
btrfs_item_offset
(
item
));
btrfs_leaf_data
(
l
)
+
btrfs_item_offset
(
item
));
...
...
fs/btrfs/quick-test.c
浏览文件 @
9f5fae2f
...
@@ -172,7 +172,8 @@ int main(int ac, char **av) {
...
@@ -172,7 +172,8 @@ int main(int ac, char **av) {
printf
(
"tree size is now %d
\n
"
,
tree_size
);
printf
(
"tree size is now %d
\n
"
,
tree_size
);
printf
(
"root %p commit root %p
\n
"
,
root
->
node
,
root
->
commit_root
);
printf
(
"root %p commit root %p
\n
"
,
root
->
node
,
root
->
commit_root
);
printf
(
"map tree
\n
"
);
printf
(
"map tree
\n
"
);
btrfs_print_tree
(
root
->
extent_root
,
root
->
extent_root
->
node
);
btrfs_print_tree
(
root
->
fs_info
->
extent_root
,
root
->
fs_info
->
extent_root
->
node
);
close_ctree
(
root
,
&
super
);
close_ctree
(
root
,
&
super
);
return
0
;
return
0
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录