Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Linux-御风守护者
linux
提交
5caf2a00
L
linux
项目概览
Linux-御风守护者
/
linux
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5caf2a00
编写于
4月 02, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
4月 02, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: dynamic allocation of path struct
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
2c90e5d6
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
243 addition
and
172 deletion
+243
-172
fs/btrfs/dir-item.c
fs/btrfs/dir-item.c
+10
-8
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+61
-39
fs/btrfs/file-item.c
fs/btrfs/file-item.c
+26
-17
fs/btrfs/inode-item.c
fs/btrfs/inode-item.c
+6
-3
fs/btrfs/root-tree.c
fs/btrfs/root-tree.c
+28
-19
fs/btrfs/super.c
fs/btrfs/super.c
+112
-86
未找到文件。
fs/btrfs/dir-item.c
浏览文件 @
5caf2a00
...
...
@@ -9,7 +9,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
objectid
,
u8
type
)
{
int
ret
=
0
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_dir_item
*
dir_item
;
char
*
name_ptr
;
struct
btrfs_key
key
;
...
...
@@ -20,24 +20,26 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_ITEM_KEY
);
ret
=
btrfs_name_hash
(
name
,
name_len
,
&
key
.
offset
);
BUG_ON
(
ret
);
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
btrfs_init_path
(
path
);
data_size
=
sizeof
(
*
dir_item
)
+
name_len
;
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
&
path
,
&
key
,
data_size
);
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
key
,
data_size
);
if
(
ret
)
goto
out
;
dir_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
dir_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_dir_item
);
btrfs_set_dir_objectid
(
dir_item
,
objectid
);
btrfs_set_dir_type
(
dir_item
,
type
);
btrfs_set_dir_flags
(
dir_item
,
0
);
btrfs_set_dir_name_len
(
dir_item
,
name_len
);
name_ptr
=
(
char
*
)(
dir_item
+
1
);
btrfs_memcpy
(
root
,
path
.
nodes
[
0
]
->
b_data
,
name_ptr
,
name
,
name_len
);
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
name_ptr
,
name
,
name_len
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
out:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
fs/btrfs/extent-tree.c
浏览文件 @
5caf2a00
...
...
@@ -15,7 +15,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
static
int
inc_block_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
int
ret
;
struct
btrfs_key
key
;
struct
btrfs_leaf
*
l
;
...
...
@@ -25,23 +25,26 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
find_free_extent
(
trans
,
root
->
fs_info
->
extent_root
,
0
,
0
,
(
u64
)
-
1
,
&
ins
);
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
key
.
objectid
=
blocknr
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_ITEM_KEY
);
key
.
offset
=
num_blocks
;
ret
=
btrfs_search_slot
(
trans
,
root
->
fs_info
->
extent_root
,
&
key
,
&
path
,
ret
=
btrfs_search_slot
(
trans
,
root
->
fs_info
->
extent_root
,
&
key
,
path
,
0
,
1
);
if
(
ret
!=
0
)
BUG
();
BUG_ON
(
ret
!=
0
);
l
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
item
=
btrfs_item_ptr
(
l
,
path
.
slots
[
0
],
struct
btrfs_extent_item
);
l
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
item
=
btrfs_item_ptr
(
l
,
path
->
slots
[
0
],
struct
btrfs_extent_item
);
refs
=
btrfs_extent_refs
(
item
);
btrfs_set_extent_refs
(
item
,
refs
+
1
);
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
&
path
);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
path
);
btrfs_free_path
(
path
);
finish_current_insert
(
trans
,
root
->
fs_info
->
extent_root
);
del_pending_extents
(
trans
,
root
->
fs_info
->
extent_root
);
return
0
;
...
...
@@ -50,24 +53,27 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
static
int
lookup_block_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
,
u32
*
refs
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
int
ret
;
struct
btrfs_key
key
;
struct
btrfs_leaf
*
l
;
struct
btrfs_extent_item
*
item
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
btrfs_init_path
(
path
);
key
.
objectid
=
blocknr
;
key
.
offset
=
num_blocks
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_ITEM_KEY
);
ret
=
btrfs_search_slot
(
trans
,
root
->
fs_info
->
extent_root
,
&
key
,
&
path
,
ret
=
btrfs_search_slot
(
trans
,
root
->
fs_info
->
extent_root
,
&
key
,
path
,
0
,
0
);
if
(
ret
!=
0
)
BUG
();
l
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
item
=
btrfs_item_ptr
(
l
,
path
.
slots
[
0
],
struct
btrfs_extent_item
);
l
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
item
=
btrfs_item_ptr
(
l
,
path
->
slots
[
0
],
struct
btrfs_extent_item
);
*
refs
=
btrfs_extent_refs
(
item
);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
&
path
);
btrfs_release_path
(
root
->
fs_info
->
extent_root
,
path
);
btrfs_free_path
(
path
);
return
0
;
}
...
...
@@ -200,7 +206,7 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending)
static
int
__free_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
,
int
pin
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
struct
btrfs_fs_info
*
info
=
root
->
fs_info
;
struct
btrfs_root
*
extent_root
=
info
->
extent_root
;
...
...
@@ -215,20 +221,22 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
key
.
offset
=
num_blocks
;
find_free_extent
(
trans
,
root
,
0
,
0
,
(
u64
)
-
1
,
&
ins
);
btrfs_init_path
(
&
path
);
ret
=
btrfs_search_slot
(
trans
,
extent_root
,
&
key
,
&
path
,
-
1
,
1
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_search_slot
(
trans
,
extent_root
,
&
key
,
path
,
-
1
,
1
);
if
(
ret
)
{
printk
(
"failed to find %Lu
\n
"
,
key
.
objectid
);
btrfs_print_tree
(
extent_root
,
extent_root
->
node
);
printk
(
"failed to find %Lu
\n
"
,
key
.
objectid
);
BUG
();
}
ei
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
ei
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_extent_item
);
BUG_ON
(
ei
->
refs
==
0
);
refs
=
btrfs_extent_refs
(
ei
)
-
1
;
btrfs_set_extent_refs
(
ei
,
refs
);
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
if
(
refs
==
0
)
{
u64
super_blocks_used
;
...
...
@@ -240,13 +248,14 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
super_blocks_used
=
btrfs_super_blocks_used
(
info
->
disk_super
);
btrfs_set_super_blocks_used
(
info
->
disk_super
,
super_blocks_used
-
num_blocks
);
ret
=
btrfs_del_item
(
trans
,
extent_root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
extent_root
,
path
);
if
(
extent_root
->
fs_info
->
last_insert
.
objectid
>
blocknr
)
extent_root
->
fs_info
->
last_insert
.
objectid
=
blocknr
;
if
(
ret
)
BUG
();
}
btrfs_release_path
(
extent_root
,
&
path
);
btrfs_release_path
(
extent_root
,
path
);
btrfs_free_path
(
path
);
finish_current_insert
(
trans
,
extent_root
);
return
ret
;
}
...
...
@@ -319,7 +328,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
*
orig_root
,
u64
num_blocks
,
u64
search_start
,
u64
search_end
,
struct
btrfs_key
*
ins
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
int
ret
;
u64
hole_size
=
0
;
...
...
@@ -339,24 +348,25 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
ins
->
flags
=
0
;
btrfs_set_key_type
(
ins
,
BTRFS_EXTENT_ITEM_KEY
);
path
=
btrfs_alloc_path
();
check_failed:
btrfs_init_path
(
&
path
);
btrfs_init_path
(
path
);
ins
->
objectid
=
search_start
;
ins
->
offset
=
0
;
start_found
=
0
;
ret
=
btrfs_search_slot
(
trans
,
root
,
ins
,
&
path
,
0
,
0
);
ret
=
btrfs_search_slot
(
trans
,
root
,
ins
,
path
,
0
,
0
);
if
(
ret
<
0
)
goto
error
;
if
(
path
.
slots
[
0
]
>
0
)
path
.
slots
[
0
]
--
;
if
(
path
->
slots
[
0
]
>
0
)
path
->
slots
[
0
]
--
;
while
(
1
)
{
l
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
slot
=
path
.
slots
[
0
];
l
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
slot
=
path
->
slots
[
0
];
if
(
slot
>=
btrfs_header_nritems
(
&
l
->
header
))
{
ret
=
btrfs_next_leaf
(
root
,
&
path
);
ret
=
btrfs_next_leaf
(
root
,
path
);
if
(
ret
==
0
)
continue
;
if
(
ret
<
0
)
...
...
@@ -387,14 +397,14 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
}
start_found
=
1
;
last_block
=
key
.
objectid
+
key
.
offset
;
path
.
slots
[
0
]
++
;
path
->
slots
[
0
]
++
;
}
// FIXME -ENOSPC
check_pending:
/* we have to make sure we didn't find an extent that has already
* been allocated by the map tree or the original allocation
*/
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
BUG_ON
(
ins
->
objectid
<
search_start
);
for
(
test_block
=
ins
->
objectid
;
test_block
<
ins
->
objectid
+
total_needed
;
test_block
++
)
{
...
...
@@ -410,9 +420,11 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
root
->
fs_info
->
current_insert
.
flags
=
0
;
root
->
fs_info
->
last_insert
.
objectid
=
ins
->
objectid
;
ins
->
offset
=
num_blocks
;
btrfs_free_path
(
path
);
return
0
;
error:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
@@ -533,6 +545,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
int
ret
;
u32
refs
;
WARN_ON
(
*
level
<
0
);
WARN_ON
(
*
level
>=
BTRFS_MAX_LEVEL
);
ret
=
lookup_block_ref
(
trans
,
root
,
path
->
nodes
[
*
level
]
->
b_blocknr
,
1
,
&
refs
);
BUG_ON
(
ret
);
...
...
@@ -542,6 +556,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
* walk down to the last node level and free all the leaves
*/
while
(
*
level
>=
0
)
{
WARN_ON
(
*
level
<
0
);
WARN_ON
(
*
level
>=
BTRFS_MAX_LEVEL
);
cur
=
path
->
nodes
[
*
level
];
if
(
btrfs_header_level
(
btrfs_buffer_header
(
cur
))
!=
*
level
)
WARN_ON
(
1
);
...
...
@@ -564,6 +580,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
continue
;
}
next
=
read_tree_block
(
root
,
blocknr
);
WARN_ON
(
*
level
<=
0
);
if
(
path
->
nodes
[
*
level
-
1
])
btrfs_block_release
(
root
,
path
->
nodes
[
*
level
-
1
]);
path
->
nodes
[
*
level
-
1
]
=
next
;
...
...
@@ -571,6 +588,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
path
->
slots
[
*
level
]
=
0
;
}
out:
WARN_ON
(
*
level
<
0
);
WARN_ON
(
*
level
>=
BTRFS_MAX_LEVEL
);
ret
=
btrfs_free_extent
(
trans
,
root
,
path
->
nodes
[
*
level
]
->
b_blocknr
,
1
,
1
);
btrfs_block_release
(
root
,
path
->
nodes
[
*
level
]);
...
...
@@ -622,33 +641,36 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
int
ret
=
0
;
int
wret
;
int
level
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
int
i
;
int
orig_level
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
level
=
btrfs_header_level
(
btrfs_buffer_header
(
snap
));
orig_level
=
level
;
path
.
nodes
[
level
]
=
snap
;
path
.
slots
[
level
]
=
0
;
path
->
nodes
[
level
]
=
snap
;
path
->
slots
[
level
]
=
0
;
while
(
1
)
{
wret
=
walk_down_tree
(
trans
,
root
,
&
path
,
&
level
);
wret
=
walk_down_tree
(
trans
,
root
,
path
,
&
level
);
if
(
wret
>
0
)
break
;
if
(
wret
<
0
)
ret
=
wret
;
wret
=
walk_up_tree
(
trans
,
root
,
&
path
,
&
level
);
wret
=
walk_up_tree
(
trans
,
root
,
path
,
&
level
);
if
(
wret
>
0
)
break
;
if
(
wret
<
0
)
ret
=
wret
;
}
for
(
i
=
0
;
i
<=
orig_level
;
i
++
)
{
if
(
path
.
nodes
[
i
])
{
btrfs_block_release
(
root
,
path
.
nodes
[
i
]);
if
(
path
->
nodes
[
i
])
{
btrfs_block_release
(
root
,
path
->
nodes
[
i
]);
}
}
btrfs_free_path
(
path
);
return
ret
;
}
fs/btrfs/file-item.c
浏览文件 @
5caf2a00
...
...
@@ -13,9 +13,11 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans,
int
ret
=
0
;
struct
btrfs_file_extent_item
*
item
;
struct
btrfs_key
file_key
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_alloc_extent
(
trans
,
root
,
num_blocks
,
hint_block
,
(
u64
)
-
1
,
objectid
,
&
ins
);
BUG_ON
(
ret
);
...
...
@@ -24,19 +26,20 @@ int btrfs_alloc_file_extent(struct btrfs_trans_handle *trans,
file_key
.
flags
=
0
;
btrfs_set_key_type
(
&
file_key
,
BTRFS_EXTENT_DATA_KEY
);
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
&
path
,
&
file_key
,
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
file_key
,
sizeof
(
*
item
));
BUG_ON
(
ret
);
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
btrfs_set_file_extent_disk_blocknr
(
item
,
ins
.
objectid
);
btrfs_set_file_extent_disk_num_blocks
(
item
,
ins
.
offset
);
btrfs_set_file_extent_offset
(
item
,
0
);
btrfs_set_file_extent_num_blocks
(
item
,
ins
.
offset
);
btrfs_set_file_extent_generation
(
item
,
trans
->
transid
);
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
*
result
=
ins
.
objectid
;
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
0
;
}
...
...
@@ -65,25 +68,28 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
{
int
ret
;
struct
btrfs_key
file_key
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_csum_item
*
item
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
file_key
.
objectid
=
objectid
;
file_key
.
offset
=
offset
;
file_key
.
flags
=
0
;
btrfs_set_key_type
(
&
file_key
,
BTRFS_CSUM_ITEM_KEY
);
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
&
path
,
&
file_key
,
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
file_key
,
BTRFS_CSUM_SIZE
);
if
(
ret
!=
0
&&
ret
!=
-
EEXIST
)
goto
fail
;
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_csum_item
);
ret
=
0
;
ret
=
btrfs_csum_data
(
root
,
data
,
len
,
item
->
csum
);
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
fail:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
@@ -93,19 +99,21 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root,
{
int
ret
;
struct
btrfs_key
file_key
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_csum_item
*
item
;
char
result
[
BTRFS_CSUM_SIZE
];
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
file_key
.
objectid
=
objectid
;
file_key
.
offset
=
offset
;
file_key
.
flags
=
0
;
btrfs_set_key_type
(
&
file_key
,
BTRFS_CSUM_ITEM_KEY
);
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
file_key
,
&
path
,
0
,
0
);
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
file_key
,
path
,
0
,
0
);
if
(
ret
)
goto
fail
;
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_csum_item
);
ret
=
0
;
ret
=
btrfs_csum_data
(
root
,
data
,
len
,
result
);
...
...
@@ -113,7 +121,8 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root,
if
(
memcmp
(
result
,
item
->
csum
,
BTRFS_CSUM_SIZE
))
ret
=
1
;
fail:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
fs/btrfs/inode-item.c
浏览文件 @
5caf2a00
...
...
@@ -7,7 +7,7 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root
*
root
,
u64
objectid
,
struct
btrfs_inode_item
*
inode_item
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
int
ret
;
key
.
objectid
=
objectid
;
...
...
@@ -15,10 +15,13 @@ int btrfs_insert_inode(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_key_type
(
&
key
,
BTRFS_INODE_ITEM_KEY
);
key
.
offset
=
0
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_insert_item
(
trans
,
root
,
&
key
,
inode_item
,
sizeof
(
*
inode_item
));
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
fs/btrfs/root-tree.c
浏览文件 @
5caf2a00
...
...
@@ -6,7 +6,7 @@
int
btrfs_find_last_root
(
struct
btrfs_root
*
root
,
u64
objectid
,
struct
btrfs_root_item
*
item
,
struct
btrfs_key
*
key
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_key
search_key
;
struct
btrfs_leaf
*
l
;
int
ret
;
...
...
@@ -16,14 +16,16 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
search_key
.
flags
=
(
u32
)
-
1
;
search_key
.
offset
=
(
u32
)
-
1
;
btrfs_init_path
(
&
path
);
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
search_key
,
&
path
,
0
,
0
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
search_key
,
path
,
0
,
0
);
if
(
ret
<
0
)
goto
out
;
BUG_ON
(
ret
==
0
);
l
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
BUG_ON
(
path
.
slots
[
0
]
==
0
);
slot
=
path
.
slots
[
0
]
-
1
;
l
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
BUG_ON
(
path
->
slots
[
0
]
==
0
);
slot
=
path
->
slots
[
0
]
-
1
;
if
(
btrfs_disk_key_objectid
(
&
l
->
items
[
slot
].
key
)
!=
objectid
)
{
ret
=
1
;
goto
out
;
...
...
@@ -31,9 +33,10 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
memcpy
(
item
,
btrfs_item_ptr
(
l
,
slot
,
struct
btrfs_root_item
),
sizeof
(
*
item
));
btrfs_disk_key_to_cpu
(
key
,
&
l
->
items
[
slot
].
key
);
btrfs_release_path
(
root
,
&
path
);
ret
=
0
;
out:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
@@ -41,24 +44,27 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
*
root
,
struct
btrfs_key
*
key
,
struct
btrfs_root_item
*
item
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_leaf
*
l
;
int
ret
;
int
slot
;
struct
btrfs_root_item
*
update_item
;
btrfs_init_path
(
&
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
key
,
&
path
,
0
,
1
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
key
,
path
,
0
,
1
);
if
(
ret
<
0
)
goto
out
;
BUG_ON
(
ret
!=
0
);
l
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
slot
=
path
.
slots
[
0
];
l
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
slot
=
path
->
slots
[
0
];
update_item
=
btrfs_item_ptr
(
l
,
slot
,
struct
btrfs_root_item
);
btrfs_memcpy
(
root
,
l
,
update_item
,
item
,
sizeof
(
*
item
));
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
out:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
@@ -75,16 +81,19 @@ int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
int
btrfs_del_root
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_key
*
key
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
int
ret
;
btrfs_init_path
(
&
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
key
,
&
path
,
-
1
,
1
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
key
,
path
,
-
1
,
1
);
if
(
ret
<
0
)
goto
out
;
BUG_ON
(
ret
!=
0
);
ret
=
btrfs_del_item
(
trans
,
root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
out:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
fs/btrfs/super.c
浏览文件 @
5caf2a00
...
...
@@ -35,25 +35,27 @@ static int check_inode(struct inode *inode)
static
void
btrfs_read_locked_inode
(
struct
inode
*
inode
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_inode_item
*
inode_item
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
);
int
ret
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
check_inode
(
inode
);
ret
=
btrfs_lookup_inode
(
NULL
,
root
,
&
path
,
inode
->
i_ino
,
0
);
ret
=
btrfs_lookup_inode
(
NULL
,
root
,
path
,
inode
->
i_ino
,
0
);
if
(
ret
)
{
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
make_bad_inode
(
inode
);
return
;
}
check_inode
(
inode
);
inode_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
inode_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_inode_item
);
inode
->
i_mode
=
btrfs_inode_mode
(
inode_item
);
...
...
@@ -69,7 +71,11 @@ static void btrfs_read_locked_inode(struct inode *inode)
inode
->
i_ctime
.
tv_nsec
=
btrfs_timespec_nsec
(
&
inode_item
->
ctime
);
inode
->
i_blocks
=
btrfs_inode_nblocks
(
inode_item
);
inode
->
i_generation
=
btrfs_inode_generation
(
inode_item
);
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
inode_item
=
NULL
;
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
check_inode
(
inode
);
switch
(
inode
->
i_mode
&
S_IFMT
)
{
...
...
@@ -101,15 +107,17 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
struct
inode
*
dir
,
struct
dentry
*
dentry
)
{
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
const
char
*
name
=
dentry
->
d_name
.
name
;
int
name_len
=
dentry
->
d_name
.
len
;
int
ret
;
u64
objectid
;
struct
btrfs_dir_item
*
di
;
btrfs_init_path
(
&
path
);
ret
=
btrfs_lookup_dir_item
(
trans
,
root
,
&
path
,
dir
->
i_ino
,
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_lookup_dir_item
(
trans
,
root
,
path
,
dir
->
i_ino
,
name
,
name_len
,
-
1
);
if
(
ret
<
0
)
goto
err
;
...
...
@@ -117,15 +125,16 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
ret
=
-
ENOENT
;
goto
err
;
}
di
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
di
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_dir_item
);
objectid
=
btrfs_dir_objectid
(
di
);
ret
=
btrfs_del_item
(
trans
,
root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
BUG_ON
(
ret
);
dentry
->
d_inode
->
i_ctime
=
dir
->
i_ctime
;
err:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
if
(
ret
==
0
)
inode_dec_link_count
(
dentry
->
d_inode
);
return
ret
;
...
...
@@ -152,30 +161,32 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
int
err
;
int
ret
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
);
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_disk_key
*
found_key
;
struct
btrfs_leaf
*
leaf
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
key
.
objectid
=
inode
->
i_ino
;
key
.
offset
=
(
u64
)
-
1
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_ITEM_KEY
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
&
path
,
-
1
,
1
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
-
1
,
1
);
if
(
ret
<
0
)
{
err
=
ret
;
goto
out
;
}
BUG_ON
(
ret
==
0
);
BUG_ON
(
path
.
slots
[
0
]
==
0
);
path
.
slots
[
0
]
--
;
leaf
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
found_key
=
&
leaf
->
items
[
path
.
slots
[
0
]].
key
;
BUG_ON
(
path
->
slots
[
0
]
==
0
);
path
->
slots
[
0
]
--
;
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
found_key
=
&
leaf
->
items
[
path
->
slots
[
0
]].
key
;
if
(
btrfs_disk_key_objectid
(
found_key
)
!=
inode
->
i_ino
)
{
err
=
-
ENOENT
;
goto
out
;
...
...
@@ -185,11 +196,11 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
err
=
-
ENOTEMPTY
;
goto
out
;
}
ret
=
btrfs_del_item
(
trans
,
root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
BUG_ON
(
ret
);
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
key
.
offset
=
1
;
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
&
path
,
-
1
,
1
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
-
1
,
1
);
if
(
ret
<
0
)
{
err
=
ret
;
goto
out
;
...
...
@@ -198,12 +209,13 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
err
=
-
ENOTEMPTY
;
goto
out
;
}
ret
=
btrfs_del_item
(
trans
,
root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
if
(
ret
)
{
err
=
ret
;
goto
out
;
}
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
/* now the directory is empty */
err
=
btrfs_unlink_trans
(
trans
,
root
,
dir
,
dentry
);
...
...
@@ -223,33 +235,36 @@ static int btrfs_free_inode(struct btrfs_trans_handle *trans,
struct
inode
*
inode
)
{
u64
objectid
=
inode
->
i_ino
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_inode_map_item
*
map
;
struct
btrfs_key
stat_data_key
;
int
ret
;
clear_inode
(
inode
);
btrfs_init_path
(
&
path
);
ret
=
btrfs_lookup_inode_map
(
trans
,
root
,
&
path
,
objectid
,
-
1
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_lookup_inode_map
(
trans
,
root
,
path
,
objectid
,
-
1
);
if
(
ret
)
{
if
(
ret
>
0
)
ret
=
-
ENOENT
;
btrfs_release_path
(
root
,
&
path
);
goto
error
;
}
map
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
map
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_inode_map_item
);
btrfs_disk_key_to_cpu
(
&
stat_data_key
,
&
map
->
key
);
ret
=
btrfs_del_item
(
trans
,
root
->
fs_info
->
inode_root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
root
->
fs_info
->
inode_root
,
path
);
BUG_ON
(
ret
);
btrfs_release_path
(
root
,
&
path
);
btrfs_init_path
(
&
path
);
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_lookup_inode
(
trans
,
root
,
&
path
,
objectid
,
-
1
);
ret
=
btrfs_lookup_inode
(
trans
,
root
,
path
,
objectid
,
-
1
);
BUG_ON
(
ret
);
ret
=
btrfs_del_item
(
trans
,
root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
BUG_ON
(
ret
);
btrfs_release_path
(
root
,
&
path
);
error:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
@@ -258,7 +273,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
struct
inode
*
inode
)
{
int
ret
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
struct
btrfs_disk_key
*
found_key
;
struct
btrfs_leaf
*
leaf
;
...
...
@@ -267,24 +282,25 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
u64
extent_num_blocks
=
0
;
int
found_extent
;
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
/* FIXME, add redo link to tree so we don't leak on crash */
key
.
objectid
=
inode
->
i_ino
;
key
.
offset
=
(
u64
)
-
1
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_CSUM_ITEM_KEY
);
while
(
1
)
{
btrfs_init_path
(
&
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
&
path
,
-
1
,
1
);
btrfs_init_path
(
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
-
1
,
1
);
if
(
ret
<
0
)
{
btrfs_release_path
(
root
,
&
path
);
goto
error
;
}
if
(
ret
>
0
)
{
BUG_ON
(
path
.
slots
[
0
]
==
0
);
path
.
slots
[
0
]
--
;
BUG_ON
(
path
->
slots
[
0
]
==
0
);
path
->
slots
[
0
]
--
;
}
leaf
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
found_key
=
&
leaf
->
items
[
path
.
slots
[
0
]].
key
;
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
found_key
=
&
leaf
->
items
[
path
->
slots
[
0
]].
key
;
if
(
btrfs_disk_key_objectid
(
found_key
)
!=
inode
->
i_ino
)
break
;
if
(
btrfs_disk_key_type
(
found_key
)
!=
BTRFS_CSUM_ITEM_KEY
&&
...
...
@@ -293,8 +309,8 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
if
(
btrfs_disk_key_offset
(
found_key
)
<
inode
->
i_size
)
break
;
if
(
btrfs_disk_key_type
(
found_key
)
==
BTRFS_EXTENT_DATA_KEY
)
{
fi
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
fi
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
extent_start
=
btrfs_file_extent_disk_blocknr
(
fi
);
extent_num_blocks
=
...
...
@@ -305,18 +321,19 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
}
else
{
found_extent
=
0
;
}
ret
=
btrfs_del_item
(
trans
,
root
,
&
path
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
BUG_ON
(
ret
);
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
if
(
found_extent
)
{
ret
=
btrfs_free_extent
(
trans
,
root
,
extent_start
,
extent_num_blocks
,
0
);
BUG_ON
(
ret
);
}
}
btrfs_release_path
(
root
,
&
path
);
ret
=
0
;
error:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
ret
;
}
...
...
@@ -351,23 +368,26 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
const
char
*
name
=
dentry
->
d_name
.
name
;
int
namelen
=
dentry
->
d_name
.
len
;
struct
btrfs_dir_item
*
di
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
);
int
ret
;
btrfs_init_path
(
&
path
);
ret
=
btrfs_lookup_dir_item
(
NULL
,
root
,
&
path
,
dir
->
i_ino
,
name
,
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_lookup_dir_item
(
NULL
,
root
,
path
,
dir
->
i_ino
,
name
,
namelen
,
0
);
if
(
ret
||
!
btrfs_match_dir_item_name
(
root
,
&
path
,
name
,
namelen
))
{
if
(
ret
||
!
btrfs_match_dir_item_name
(
root
,
path
,
name
,
namelen
))
{
*
ino
=
0
;
ret
=
0
;
goto
out
;
}
di
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
di
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_dir_item
);
*
ino
=
btrfs_dir_objectid
(
di
);
out:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
check_inode
(
dir
);
return
ret
;
}
...
...
@@ -405,7 +425,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
struct
btrfs_item
*
item
;
struct
btrfs_dir_item
*
di
;
struct
btrfs_key
key
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
int
ret
;
u32
nritems
;
struct
btrfs_leaf
*
leaf
;
...
...
@@ -419,27 +439,28 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_ITEM_KEY
);
key
.
offset
=
filp
->
f_pos
;
btrfs_init_path
(
&
path
);
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
key
,
&
path
,
0
,
0
);
path
=
btrfs_alloc_path
();
btrfs_init_path
(
path
);
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
key
,
path
,
0
,
0
);
if
(
ret
<
0
)
{
goto
err
;
}
advance
=
0
;
while
(
1
)
{
leaf
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
slot
=
path
.
slots
[
0
];
slot
=
path
->
slots
[
0
];
if
(
advance
||
slot
>=
nritems
)
{
if
(
slot
>=
nritems
-
1
)
{
ret
=
btrfs_next_leaf
(
root
,
&
path
);
ret
=
btrfs_next_leaf
(
root
,
path
);
if
(
ret
)
break
;
leaf
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
slot
=
path
.
slots
[
0
];
slot
=
path
->
slots
[
0
];
}
else
{
slot
++
;
path
.
slots
[
0
]
++
;
path
->
slots
[
0
]
++
;
}
}
advance
=
1
;
...
...
@@ -465,7 +486,8 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
}
ret
=
0
;
err:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
ret
;
}
...
...
@@ -548,26 +570,29 @@ static int btrfs_update_inode(struct btrfs_trans_handle *trans,
struct
inode
*
inode
)
{
struct
btrfs_inode_item
*
inode_item
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
int
ret
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
ret
=
btrfs_lookup_inode
(
trans
,
root
,
&
path
,
inode
->
i_ino
,
1
);
ret
=
btrfs_lookup_inode
(
trans
,
root
,
path
,
inode
->
i_ino
,
1
);
if
(
ret
)
{
if
(
ret
>
0
)
ret
=
-
ENOENT
;
goto
failed
;
}
inode_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
inode_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_inode_item
);
fill_inode_item
(
inode_item
,
inode
);
btrfs_mark_buffer_dirty
(
path
.
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
failed:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
check_inode
(
inode
);
return
0
;
}
...
...
@@ -799,38 +824,39 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
u64
extent_start
=
0
;
u64
extent_end
=
0
;
u64
objectid
=
inode
->
i_ino
;
struct
btrfs_path
path
;
struct
btrfs_path
*
path
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
);
struct
btrfs_trans_handle
*
trans
=
NULL
;
struct
btrfs_file_extent_item
*
item
;
struct
btrfs_leaf
*
leaf
;
struct
btrfs_disk_key
*
found_key
;
btrfs_init_path
(
&
path
);
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
if
(
create
)
trans
=
btrfs_start_transaction
(
root
,
1
);
ret
=
btrfs_lookup_file_extent
(
trans
,
root
,
&
path
,
ret
=
btrfs_lookup_file_extent
(
trans
,
root
,
path
,
inode
->
i_ino
,
iblock
<<
inode
->
i_blkbits
,
0
);
if
(
ret
<
0
)
{
btrfs_release_path
(
root
,
&
path
);
err
=
ret
;
goto
out
;
}
if
(
ret
!=
0
)
{
if
(
path
.
slots
[
0
]
==
0
)
{
btrfs_release_path
(
root
,
&
path
);
if
(
path
->
slots
[
0
]
==
0
)
{
btrfs_release_path
(
root
,
path
);
goto
allocate
;
}
path
.
slots
[
0
]
--
;
path
->
slots
[
0
]
--
;
}
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
.
nodes
[
0
]),
path
.
slots
[
0
],
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
leaf
=
btrfs_buffer_leaf
(
path
.
nodes
[
0
]);
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
blocknr
=
btrfs_file_extent_disk_blocknr
(
item
);
blocknr
+=
btrfs_file_extent_offset
(
item
);
...
...
@@ -838,25 +864,23 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
if
(
ret
==
0
)
{
err
=
0
;
map_bh
(
result
,
inode
->
i_sb
,
blocknr
);
btrfs_release_path
(
root
,
&
path
);
goto
out
;
}
/* are we inside the extent that was found? */
found_key
=
&
leaf
->
items
[
path
.
slots
[
0
]].
key
;
found_key
=
&
leaf
->
items
[
path
->
slots
[
0
]].
key
;
if
(
btrfs_disk_key_objectid
(
found_key
)
!=
objectid
||
btrfs_disk_key_type
(
found_key
)
!=
BTRFS_EXTENT_DATA_KEY
)
{
extent_end
=
0
;
extent_start
=
0
;
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
path
);
goto
allocate
;
}
extent_start
=
btrfs_disk_key_offset
(
&
leaf
->
items
[
path
.
slots
[
0
]].
key
);
extent_start
=
btrfs_disk_key_offset
(
&
leaf
->
items
[
path
->
slots
[
0
]].
key
);
extent_start
=
extent_start
>>
inode
->
i_blkbits
;
extent_start
+=
btrfs_file_extent_offset
(
item
);
extent_end
=
extent_start
+
btrfs_file_extent_num_blocks
(
item
);
btrfs_release_path
(
root
,
&
path
);
if
(
iblock
>=
extent_start
&&
iblock
<
extent_end
)
{
err
=
0
;
map_bh
(
result
,
inode
->
i_sb
,
blocknr
+
iblock
-
extent_start
);
...
...
@@ -880,6 +904,8 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
map_bh
(
result
,
inode
->
i_sb
,
blocknr
);
out:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
if
(
trans
)
btrfs_end_transaction
(
trans
,
root
);
return
err
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录