Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
ccd467d6
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
ccd467d6
编写于
6月 28, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
6月 28, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: crash recovery fixes
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
f2654de4
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
112 addition
and
48 deletion
+112
-48
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+12
-1
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+4
-8
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+14
-8
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+1
-0
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+33
-4
fs/btrfs/file.c
fs/btrfs/file.c
+11
-4
fs/btrfs/inode.c
fs/btrfs/inode.c
+3
-3
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+34
-20
未找到文件。
fs/btrfs/ctree.c
浏览文件 @
ccd467d6
...
@@ -75,6 +75,17 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -75,6 +75,17 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
struct
btrfs_node
*
cow_node
;
struct
btrfs_node
*
cow_node
;
int
ret
;
int
ret
;
WARN_ON
(
!
buffer_uptodate
(
buf
));
if
(
trans
->
transaction
!=
root
->
fs_info
->
running_transaction
)
{
printk
(
KERN_CRIT
"trans %Lu running %Lu
\n
"
,
trans
->
transid
,
root
->
fs_info
->
running_transaction
->
transid
);
WARN_ON
(
1
);
}
if
(
trans
->
transid
!=
root
->
fs_info
->
generation
)
{
printk
(
KERN_CRIT
"trans %Lu running %Lu
\n
"
,
trans
->
transid
,
root
->
fs_info
->
generation
);
WARN_ON
(
1
);
}
if
(
btrfs_header_generation
(
btrfs_buffer_header
(
buf
))
==
if
(
btrfs_header_generation
(
btrfs_buffer_header
(
buf
))
==
trans
->
transid
)
{
trans
->
transid
)
{
*
cow_ret
=
buf
;
*
cow_ret
=
buf
;
...
@@ -107,7 +118,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -107,7 +118,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_free_extent
(
trans
,
root
,
bh_blocknr
(
buf
),
1
,
1
);
btrfs_free_extent
(
trans
,
root
,
bh_blocknr
(
buf
),
1
,
1
);
}
}
btrfs_block_release
(
root
,
buf
);
btrfs_block_release
(
root
,
buf
);
mark_buffer_dirty
(
cow
);
btrfs_
mark_buffer_dirty
(
cow
);
*
cow_ret
=
cow
;
*
cow_ret
=
cow
;
return
0
;
return
0
;
}
}
...
...
fs/btrfs/ctree.h
浏览文件 @
ccd467d6
...
@@ -1013,18 +1013,13 @@ static inline void btrfs_memmove(struct btrfs_root *root,
...
@@ -1013,18 +1013,13 @@ static inline void btrfs_memmove(struct btrfs_root *root,
memmove
(
dst
,
src
,
nr
);
memmove
(
dst
,
src
,
nr
);
}
}
static
inline
void
btrfs_mark_buffer_dirty
(
struct
buffer_head
*
bh
)
{
WARN_ON
(
!
atomic_read
(
&
bh
->
b_count
));
mark_buffer_dirty
(
bh
);
}
/* 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) + \
btrfs_item_offset((leaf)->items + (slot))))
btrfs_item_offset((leaf)->items + (slot))))
/* extent-tree.c */
/* extent-tree.c */
int
btrfs_copy_pinned
(
struct
btrfs_root
*
root
,
struct
radix_tree_root
*
copy
);
struct
btrfs_block_group_cache
*
btrfs_lookup_block_group
(
struct
struct
btrfs_block_group_cache
*
btrfs_lookup_block_group
(
struct
btrfs_fs_info
*
info
,
btrfs_fs_info
*
info
,
u64
blocknr
);
u64
blocknr
);
...
@@ -1044,8 +1039,9 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
...
@@ -1044,8 +1039,9 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct
buffer_head
*
buf
);
struct
buffer_head
*
buf
);
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
);
int
btrfs_finish_extent_commit
(
struct
btrfs_trans_handle
*
trans
,
struct
int
btrfs_finish_extent_commit
(
struct
btrfs_trans_handle
*
trans
,
btrfs_root
*
root
);
struct
btrfs_root
*
root
,
struct
radix_tree_root
*
unpin_radix
);
int
btrfs_inc_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_inc_extent_ref
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_root
*
root
,
u64
blocknr
,
u64
num_blocks
);
u64
blocknr
,
u64
num_blocks
);
...
...
fs/btrfs/disk-io.c
浏览文件 @
ccd467d6
...
@@ -270,14 +270,6 @@ struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
...
@@ -270,14 +270,6 @@ struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
return
NULL
;
return
NULL
;
}
}
int
dirty_tree_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
{
WARN_ON
(
atomic_read
(
&
buf
->
b_count
)
==
0
);
mark_buffer_dirty
(
buf
);
return
0
;
}
int
clean_tree_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
int
clean_tree_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
struct
buffer_head
*
buf
)
{
{
...
@@ -621,6 +613,20 @@ int close_ctree(struct btrfs_root *root)
...
@@ -621,6 +613,20 @@ int close_ctree(struct btrfs_root *root)
return
0
;
return
0
;
}
}
void
btrfs_mark_buffer_dirty
(
struct
buffer_head
*
bh
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
bh
->
b_page
->
mapping
->
host
)
->
root
;
u64
transid
=
btrfs_header_generation
(
btrfs_buffer_header
(
bh
));
WARN_ON
(
!
atomic_read
(
&
bh
->
b_count
));
if
(
transid
!=
root
->
fs_info
->
generation
)
{
printk
(
KERN_CRIT
"transid mismatch buffer %llu, found %Lu running %Lu
\n
"
,
(
unsigned
long
long
)
bh
->
b_blocknr
,
transid
,
root
->
fs_info
->
generation
);
WARN_ON
(
1
);
}
mark_buffer_dirty
(
bh
);
}
void
btrfs_block_release
(
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
void
btrfs_block_release
(
struct
btrfs_root
*
root
,
struct
buffer_head
*
buf
)
{
{
brelse
(
buf
);
brelse
(
buf
);
...
...
fs/btrfs/disk-io.h
浏览文件 @
ccd467d6
...
@@ -78,4 +78,5 @@ int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh,
...
@@ -78,4 +78,5 @@ int btrfs_map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh,
int
btrfs_releasepage
(
struct
page
*
page
,
gfp_t
flags
);
int
btrfs_releasepage
(
struct
page
*
page
,
gfp_t
flags
);
void
btrfs_btree_balance_dirty
(
struct
btrfs_root
*
root
);
void
btrfs_btree_balance_dirty
(
struct
btrfs_root
*
root
);
int
btrfs_free_fs_root
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_root
*
root
);
int
btrfs_free_fs_root
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_root
*
root
);
void
btrfs_mark_buffer_dirty
(
struct
buffer_head
*
bh
);
#endif
#endif
fs/btrfs/extent-tree.c
浏览文件 @
ccd467d6
...
@@ -523,6 +523,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
...
@@ -523,6 +523,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
}
}
return
0
;
return
0
;
fail:
fail:
WARN_ON
(
1
);
for
(
i
=
0
;
i
<
faili
;
i
++
)
{
for
(
i
=
0
;
i
<
faili
;
i
++
)
{
if
(
leaf
)
{
if
(
leaf
)
{
u64
disk_blocknr
;
u64
disk_blocknr
;
...
@@ -572,7 +573,7 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
...
@@ -572,7 +573,7 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
bi
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
bi
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_block_group_item
);
struct
btrfs_block_group_item
);
memcpy
(
bi
,
&
cache
->
item
,
sizeof
(
*
bi
));
memcpy
(
bi
,
&
cache
->
item
,
sizeof
(
*
bi
));
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_release_path
(
extent_root
,
path
);
btrfs_release_path
(
extent_root
,
path
);
fail:
fail:
finish_current_insert
(
trans
,
extent_root
);
finish_current_insert
(
trans
,
extent_root
);
...
@@ -739,8 +740,30 @@ static int try_remove_page(struct address_space *mapping, unsigned long index)
...
@@ -739,8 +740,30 @@ static int try_remove_page(struct address_space *mapping, unsigned long index)
return
ret
;
return
ret
;
}
}
int
btrfs_finish_extent_commit
(
struct
btrfs_trans_handle
*
trans
,
struct
int
btrfs_copy_pinned
(
struct
btrfs_root
*
root
,
struct
radix_tree_root
*
copy
)
btrfs_root
*
root
)
{
unsigned
long
gang
[
8
];
u64
last
=
0
;
struct
radix_tree_root
*
pinned_radix
=
&
root
->
fs_info
->
pinned_radix
;
int
ret
;
int
i
;
while
(
1
)
{
ret
=
find_first_radix_bit
(
pinned_radix
,
gang
,
last
,
ARRAY_SIZE
(
gang
));
if
(
!
ret
)
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
set_radix_bit
(
copy
,
gang
[
i
]);
last
=
gang
[
i
]
+
1
;
}
}
return
0
;
}
int
btrfs_finish_extent_commit
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
radix_tree_root
*
unpin_radix
)
{
{
unsigned
long
gang
[
8
];
unsigned
long
gang
[
8
];
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
...
@@ -752,7 +775,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
...
@@ -752,7 +775,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
struct
radix_tree_root
*
extent_radix
=
&
root
->
fs_info
->
extent_map_radix
;
struct
radix_tree_root
*
extent_radix
=
&
root
->
fs_info
->
extent_map_radix
;
while
(
1
)
{
while
(
1
)
{
ret
=
find_first_radix_bit
(
pinned
_radix
,
gang
,
0
,
ret
=
find_first_radix_bit
(
unpin
_radix
,
gang
,
0
,
ARRAY_SIZE
(
gang
));
ARRAY_SIZE
(
gang
));
if
(
!
ret
)
if
(
!
ret
)
break
;
break
;
...
@@ -760,6 +783,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
...
@@ -760,6 +783,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
first
=
gang
[
0
];
first
=
gang
[
0
];
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
clear_radix_bit
(
pinned_radix
,
gang
[
i
]);
clear_radix_bit
(
pinned_radix
,
gang
[
i
]);
clear_radix_bit
(
unpin_radix
,
gang
[
i
]);
block_group
=
btrfs_lookup_block_group
(
root
->
fs_info
,
block_group
=
btrfs_lookup_block_group
(
root
->
fs_info
,
gang
[
i
]);
gang
[
i
]);
if
(
block_group
)
{
if
(
block_group
)
{
...
@@ -1309,6 +1333,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
...
@@ -1309,6 +1333,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
if
(
data
)
{
if
(
data
)
{
ret
=
find_free_extent
(
trans
,
root
,
0
,
0
,
ret
=
find_free_extent
(
trans
,
root
,
0
,
0
,
search_end
,
0
,
&
prealloc_key
,
0
,
0
,
0
);
search_end
,
0
,
&
prealloc_key
,
0
,
0
,
0
);
BUG_ON
(
ret
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
exclude_nr
=
info
->
extent_tree_prealloc_nr
;
exclude_nr
=
info
->
extent_tree_prealloc_nr
;
...
@@ -1319,6 +1344,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
...
@@ -1319,6 +1344,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
ret
=
find_free_extent
(
trans
,
root
,
num_blocks
,
search_start
,
ret
=
find_free_extent
(
trans
,
root
,
num_blocks
,
search_start
,
search_end
,
hint_block
,
ins
,
search_end
,
hint_block
,
ins
,
exclude_start
,
exclude_nr
,
data
);
exclude_start
,
exclude_nr
,
data
);
BUG_ON
(
ret
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
...
@@ -1334,10 +1360,12 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
...
@@ -1334,10 +1360,12 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
if
(
!
data
)
{
if
(
!
data
)
{
exclude_start
=
ins
->
objectid
;
exclude_start
=
ins
->
objectid
;
exclude_nr
=
ins
->
offset
;
exclude_nr
=
ins
->
offset
;
hint_block
=
exclude_start
+
exclude_nr
;
ret
=
find_free_extent
(
trans
,
root
,
0
,
search_start
,
ret
=
find_free_extent
(
trans
,
root
,
0
,
search_start
,
search_end
,
hint_block
,
search_end
,
hint_block
,
&
prealloc_key
,
exclude_start
,
&
prealloc_key
,
exclude_start
,
exclude_nr
,
0
);
exclude_nr
,
0
);
BUG_ON
(
ret
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
}
}
...
@@ -1348,6 +1376,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
...
@@ -1348,6 +1376,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
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
);
finish_current_insert
(
trans
,
extent_root
);
finish_current_insert
(
trans
,
extent_root
);
pending_ret
=
del_pending_extents
(
trans
,
extent_root
);
pending_ret
=
del_pending_extents
(
trans
,
extent_root
);
if
(
ret
)
{
if
(
ret
)
{
...
...
fs/btrfs/file.c
浏览文件 @
ccd467d6
...
@@ -127,7 +127,7 @@ static int insert_inline_extent(struct btrfs_root *root, struct inode *inode,
...
@@ -127,7 +127,7 @@ static int insert_inline_extent(struct btrfs_root *root, struct inode *inode,
ptr
,
kaddr
+
bh_offset
(
bh
),
ptr
,
kaddr
+
bh_offset
(
bh
),
size
);
size
);
kunmap_atomic
(
kaddr
,
KM_USER0
);
kunmap_atomic
(
kaddr
,
KM_USER0
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
->
nodes
[
0
]);
fail:
fail:
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
ret
=
btrfs_end_transaction
(
trans
,
root
);
ret
=
btrfs_end_transaction
(
trans
,
root
);
...
@@ -211,11 +211,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
...
@@ -211,11 +211,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
int
found_type
;
int
found_type
;
int
found_extent
;
int
found_extent
;
int
found_inline
;
int
found_inline
;
int
recow
;
path
=
btrfs_alloc_path
();
path
=
btrfs_alloc_path
();
if
(
!
path
)
if
(
!
path
)
return
-
ENOMEM
;
return
-
ENOMEM
;
while
(
1
)
{
while
(
1
)
{
recow
=
0
;
btrfs_release_path
(
root
,
path
);
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_lookup_file_extent
(
trans
,
root
,
path
,
inode
->
i_ino
,
ret
=
btrfs_lookup_file_extent
(
trans
,
root
,
path
,
inode
->
i_ino
,
search_start
,
-
1
);
search_start
,
-
1
);
...
@@ -244,6 +246,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
...
@@ -244,6 +246,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
if
(
btrfs_key_type
(
&
key
)
>
BTRFS_EXTENT_DATA_KEY
)
{
if
(
btrfs_key_type
(
&
key
)
>
BTRFS_EXTENT_DATA_KEY
)
{
goto
out
;
goto
out
;
}
}
if
(
recow
)
{
search_start
=
key
.
offset
;
continue
;
}
if
(
btrfs_key_type
(
&
key
)
==
BTRFS_EXTENT_DATA_KEY
)
{
if
(
btrfs_key_type
(
&
key
)
==
BTRFS_EXTENT_DATA_KEY
)
{
extent
=
btrfs_item_ptr
(
leaf
,
slot
,
extent
=
btrfs_item_ptr
(
leaf
,
slot
,
struct
btrfs_file_extent_item
);
struct
btrfs_file_extent_item
);
...
@@ -274,6 +280,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
...
@@ -274,6 +280,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
nextret
=
btrfs_next_leaf
(
root
,
path
);
nextret
=
btrfs_next_leaf
(
root
,
path
);
if
(
nextret
)
if
(
nextret
)
goto
out
;
goto
out
;
recow
=
1
;
}
else
{
}
else
{
path
->
slots
[
0
]
++
;
path
->
slots
[
0
]
++
;
}
}
...
@@ -321,7 +328,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
...
@@ -321,7 +328,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
}
}
btrfs_set_file_extent_num_blocks
(
extent
,
btrfs_set_file_extent_num_blocks
(
extent
,
new_num
);
new_num
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
->
nodes
[
0
]);
}
else
{
}
else
{
WARN_ON
(
1
);
WARN_ON
(
1
);
}
}
...
@@ -452,6 +459,8 @@ static int prepare_pages(struct btrfs_root *root,
...
@@ -452,6 +459,8 @@ static int prepare_pages(struct btrfs_root *root,
err
=
-
ENOMEM
;
err
=
-
ENOMEM
;
goto
failed_release
;
goto
failed_release
;
}
}
cancel_dirty_page
(
pages
[
i
],
PAGE_CACHE_SIZE
);
wait_on_page_writeback
(
pages
[
i
]);
}
}
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
...
@@ -522,8 +531,6 @@ static int prepare_pages(struct btrfs_root *root,
...
@@ -522,8 +531,6 @@ static int prepare_pages(struct btrfs_root *root,
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
{
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
{
cancel_dirty_page
(
pages
[
i
],
PAGE_CACHE_SIZE
);
wait_on_page_writeback
(
pages
[
i
]);
offset
=
pos
&
(
PAGE_CACHE_SIZE
-
1
);
offset
=
pos
&
(
PAGE_CACHE_SIZE
-
1
);
this_write
=
min
((
size_t
)
PAGE_CACHE_SIZE
-
offset
,
write_bytes
);
this_write
=
min
((
size_t
)
PAGE_CACHE_SIZE
-
offset
,
write_bytes
);
if
(
!
page_has_buffers
(
pages
[
i
]))
{
if
(
!
page_has_buffers
(
pages
[
i
]))
{
...
...
fs/btrfs/inode.c
浏览文件 @
ccd467d6
...
@@ -506,7 +506,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
...
@@ -506,7 +506,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
extent_num_blocks
);
extent_num_blocks
);
inode
->
i_blocks
-=
(
orig_num_blocks
-
inode
->
i_blocks
-=
(
orig_num_blocks
-
extent_num_blocks
)
<<
3
;
extent_num_blocks
)
<<
3
;
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
->
nodes
[
0
]);
}
else
{
}
else
{
extent_start
=
extent_start
=
btrfs_file_extent_disk_blocknr
(
fi
);
btrfs_file_extent_disk_blocknr
(
fi
);
...
@@ -2020,7 +2020,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
...
@@ -2020,7 +2020,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
btrfs_set_header_owner
(
&
leaf
->
header
,
root
->
root_key
.
objectid
);
btrfs_set_header_owner
(
&
leaf
->
header
,
root
->
root_key
.
objectid
);
memcpy
(
leaf
->
header
.
fsid
,
root
->
fs_info
->
disk_super
->
fsid
,
memcpy
(
leaf
->
header
.
fsid
,
root
->
fs_info
->
disk_super
->
fsid
,
sizeof
(
leaf
->
header
.
fsid
));
sizeof
(
leaf
->
header
.
fsid
));
mark_buffer_dirty
(
subvol
);
btrfs_
mark_buffer_dirty
(
subvol
);
inode_item
=
&
root_item
.
inode
;
inode_item
=
&
root_item
.
inode
;
memset
(
inode_item
,
0
,
sizeof
(
*
inode_item
));
memset
(
inode_item
,
0
,
sizeof
(
*
inode_item
));
...
@@ -2497,7 +2497,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
...
@@ -2497,7 +2497,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
ptr
=
btrfs_file_extent_inline_start
(
ei
);
ptr
=
btrfs_file_extent_inline_start
(
ei
);
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
ptr
,
symname
,
name_len
);
ptr
,
symname
,
name_len
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
inode
->
i_op
=
&
btrfs_symlink_inode_operations
;
inode
->
i_op
=
&
btrfs_symlink_inode_operations
;
inode
->
i_mapping
->
a_ops
=
&
btrfs_symlink_aops
;
inode
->
i_mapping
->
a_ops
=
&
btrfs_symlink_aops
;
...
...
fs/btrfs/transaction.c
浏览文件 @
ccd467d6
...
@@ -85,6 +85,8 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
...
@@ -85,6 +85,8 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
if
(
root
!=
root
->
fs_info
->
tree_root
&&
root
->
last_trans
<
if
(
root
!=
root
->
fs_info
->
tree_root
&&
root
->
last_trans
<
running_trans_id
)
{
running_trans_id
)
{
WARN_ON
(
root
==
root
->
fs_info
->
extent_root
);
WARN_ON
(
root
->
ref_cows
!=
1
);
if
(
root
->
root_item
.
refs
!=
0
)
{
if
(
root
->
root_item
.
refs
!=
0
)
{
radix_tree_tag_set
(
&
root
->
fs_info
->
fs_roots_radix
,
radix_tree_tag_set
(
&
root
->
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
root
->
root_key
.
objectid
,
(
unsigned
long
)
root
->
root_key
.
objectid
,
...
@@ -113,10 +115,11 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
...
@@ -113,10 +115,11 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
cur_trans
=
root
->
fs_info
->
running_transaction
;
cur_trans
=
root
->
fs_info
->
running_transaction
;
WARN_ON
(
cur_trans
!=
trans
->
transaction
);
WARN_ON
(
cur_trans
->
num_writers
<
1
);
WARN_ON
(
cur_trans
->
num_writers
<
1
);
cur_trans
->
num_writers
--
;
if
(
waitqueue_active
(
&
cur_trans
->
writer_wait
))
if
(
waitqueue_active
(
&
cur_trans
->
writer_wait
))
wake_up
(
&
cur_trans
->
writer_wait
);
wake_up
(
&
cur_trans
->
writer_wait
);
cur_trans
->
num_writers
--
;
put_transaction
(
cur_trans
);
put_transaction
(
cur_trans
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
memset
(
trans
,
0
,
sizeof
(
*
trans
));
memset
(
trans
,
0
,
sizeof
(
*
trans
));
...
@@ -194,6 +197,7 @@ static int wait_for_commit(struct btrfs_root *root,
...
@@ -194,6 +197,7 @@ static int wait_for_commit(struct btrfs_root *root,
struct
btrfs_transaction
*
commit
)
struct
btrfs_transaction
*
commit
)
{
{
DEFINE_WAIT
(
wait
);
DEFINE_WAIT
(
wait
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
while
(
!
commit
->
commit_done
)
{
while
(
!
commit
->
commit_done
)
{
prepare_to_wait
(
&
commit
->
commit_wait
,
&
wait
,
prepare_to_wait
(
&
commit
->
commit_wait
,
&
wait
,
TASK_UNINTERRUPTIBLE
);
TASK_UNINTERRUPTIBLE
);
...
@@ -203,6 +207,7 @@ static int wait_for_commit(struct btrfs_root *root,
...
@@ -203,6 +207,7 @@ static int wait_for_commit(struct btrfs_root *root,
schedule
();
schedule
();
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
}
}
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
finish_wait
(
&
commit
->
commit_wait
,
&
wait
);
finish_wait
(
&
commit
->
commit_wait
,
&
wait
);
return
0
;
return
0
;
}
}
...
@@ -279,7 +284,6 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
...
@@ -279,7 +284,6 @@ static int add_dirty_roots(struct btrfs_trans_handle *trans,
&
root
->
root_item
);
&
root
->
root_item
);
if
(
err
)
if
(
err
)
break
;
break
;
refs
=
btrfs_root_refs
(
&
tmp_item
);
refs
=
btrfs_root_refs
(
&
tmp_item
);
btrfs_set_root_refs
(
&
tmp_item
,
refs
-
1
);
btrfs_set_root_refs
(
&
tmp_item
,
refs
-
1
);
err
=
btrfs_update_root
(
trans
,
root
->
fs_info
->
tree_root
,
err
=
btrfs_update_root
(
trans
,
root
->
fs_info
->
tree_root
,
...
@@ -333,31 +337,53 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
...
@@ -333,31 +337,53 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
struct
btrfs_transaction
*
cur_trans
;
struct
btrfs_transaction
*
cur_trans
;
struct
btrfs_transaction
*
prev_trans
=
NULL
;
struct
btrfs_transaction
*
prev_trans
=
NULL
;
struct
list_head
dirty_fs_roots
;
struct
list_head
dirty_fs_roots
;
struct
radix_tree_root
pinned_copy
;
DEFINE_WAIT
(
wait
);
DEFINE_WAIT
(
wait
);
init_bit_radix
(
&
pinned_copy
);
INIT_LIST_HEAD
(
&
dirty_fs_roots
);
INIT_LIST_HEAD
(
&
dirty_fs_roots
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
if
(
trans
->
transaction
->
in_commit
)
{
if
(
trans
->
transaction
->
in_commit
)
{
cur_trans
=
trans
->
transaction
;
cur_trans
=
trans
->
transaction
;
trans
->
transaction
->
use_count
++
;
trans
->
transaction
->
use_count
++
;
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
btrfs_end_transaction
(
trans
,
root
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
wait_for_commit
(
root
,
cur_trans
);
ret
=
wait_for_commit
(
root
,
cur_trans
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
put_transaction
(
cur_trans
);
put_transaction
(
cur_trans
);
mutex_
unlock
(
&
root
->
fs_info
->
tran
s_mutex
);
mutex_
lock
(
&
root
->
fs_info
->
f
s_mutex
);
return
0
;
return
0
;
}
}
cur_trans
=
trans
->
transaction
;
trans
->
transaction
->
in_commit
=
1
;
trans
->
transaction
->
in_commit
=
1
;
cur_trans
=
trans
->
transaction
;
if
(
cur_trans
->
list
.
prev
!=
&
root
->
fs_info
->
trans_list
)
{
prev_trans
=
list_entry
(
cur_trans
->
list
.
prev
,
struct
btrfs_transaction
,
list
);
if
(
!
prev_trans
->
commit_done
)
{
prev_trans
->
use_count
++
;
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
wait_for_commit
(
root
,
prev_trans
);
put_transaction
(
prev_trans
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
}
}
while
(
trans
->
transaction
->
num_writers
>
1
)
{
while
(
trans
->
transaction
->
num_writers
>
1
)
{
WARN_ON
(
cur_trans
!=
trans
->
transaction
);
WARN_ON
(
cur_trans
!=
trans
->
transaction
);
prepare_to_wait
(
&
trans
->
transaction
->
writer_wait
,
&
wait
,
prepare_to_wait
(
&
trans
->
transaction
->
writer_wait
,
&
wait
,
TASK_UNINTERRUPTIBLE
);
TASK_UNINTERRUPTIBLE
);
if
(
trans
->
transaction
->
num_writers
<=
1
)
if
(
trans
->
transaction
->
num_writers
<=
1
)
break
;
break
;
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
schedule
();
schedule
();
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
finish_wait
(
&
trans
->
transaction
->
writer_wait
,
&
wait
);
finish_wait
(
&
trans
->
transaction
->
writer_wait
,
&
wait
);
}
}
...
@@ -372,34 +398,22 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
...
@@ -372,34 +398,22 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
cur_trans
=
root
->
fs_info
->
running_transaction
;
cur_trans
=
root
->
fs_info
->
running_transaction
;
root
->
fs_info
->
running_transaction
=
NULL
;
root
->
fs_info
->
running_transaction
=
NULL
;
if
(
cur_trans
->
list
.
prev
!=
&
root
->
fs_info
->
trans_list
)
{
prev_trans
=
list_entry
(
cur_trans
->
list
.
prev
,
struct
btrfs_transaction
,
list
);
if
(
prev_trans
->
commit_done
)
prev_trans
=
NULL
;
else
prev_trans
->
use_count
++
;
}
btrfs_set_super_generation
(
&
root
->
fs_info
->
super_copy
,
btrfs_set_super_generation
(
&
root
->
fs_info
->
super_copy
,
cur_trans
->
transid
);
cur_trans
->
transid
);
btrfs_set_super_root
(
&
root
->
fs_info
->
super_copy
,
btrfs_set_super_root
(
&
root
->
fs_info
->
super_copy
,
bh_blocknr
(
root
->
fs_info
->
tree_root
->
node
));
bh_blocknr
(
root
->
fs_info
->
tree_root
->
node
));
memcpy
(
root
->
fs_info
->
disk_super
,
&
root
->
fs_info
->
super_copy
,
memcpy
(
root
->
fs_info
->
disk_super
,
&
root
->
fs_info
->
super_copy
,
sizeof
(
root
->
fs_info
->
super_copy
));
sizeof
(
root
->
fs_info
->
super_copy
));
btrfs_copy_pinned
(
root
,
&
pinned_copy
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
btrfs_write_and_wait_transaction
(
trans
,
root
);
ret
=
btrfs_write_and_wait_transaction
(
trans
,
root
);
if
(
prev_trans
)
{
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
wait_for_commit
(
root
,
prev_trans
);
put_transaction
(
prev_trans
);
mutex_unlock
(
&
root
->
fs_info
->
trans_mutex
);
}
BUG_ON
(
ret
);
BUG_ON
(
ret
);
write_ctree_super
(
trans
,
root
);
write_ctree_super
(
trans
,
root
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
btrfs_finish_extent_commit
(
trans
,
root
);
btrfs_finish_extent_commit
(
trans
,
root
,
&
pinned_copy
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
mutex_lock
(
&
root
->
fs_info
->
trans_mutex
);
cur_trans
->
commit_done
=
1
;
cur_trans
->
commit_done
=
1
;
wake_up
(
&
cur_trans
->
commit_wait
);
wake_up
(
&
cur_trans
->
commit_wait
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录