Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
a429e513
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看板
提交
a429e513
编写于
4月 18, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
4月 18, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: working file_write, reorganized key flags
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
70b2befd
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
167 addition
and
175 deletion
+167
-175
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+27
-3
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+26
-26
fs/btrfs/dir-item.c
fs/btrfs/dir-item.c
+0
-70
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+3
-1
fs/btrfs/file-item.c
fs/btrfs/file-item.c
+47
-19
fs/btrfs/print-tree.c
fs/btrfs/print-tree.c
+1
-1
fs/btrfs/super.c
fs/btrfs/super.c
+63
-55
未找到文件。
fs/btrfs/ctree.c
浏览文件 @
a429e513
...
@@ -893,7 +893,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -893,7 +893,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
}
}
left_nritems
=
btrfs_header_nritems
(
&
left
->
header
);
left_nritems
=
btrfs_header_nritems
(
&
left
->
header
);
for
(
i
=
left_nritems
-
1
;
i
>=
0
;
i
--
)
{
if
(
left_nritems
==
0
)
{
btrfs_block_release
(
root
,
right_buf
);
return
1
;
}
for
(
i
=
left_nritems
-
1
;
i
>=
1
;
i
--
)
{
item
=
left
->
items
+
i
;
item
=
left
->
items
+
i
;
if
(
path
->
slots
[
0
]
==
i
)
if
(
path
->
slots
[
0
]
==
i
)
push_space
+=
data_size
+
sizeof
(
*
item
);
push_space
+=
data_size
+
sizeof
(
*
item
);
...
@@ -907,6 +911,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -907,6 +911,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_block_release
(
root
,
right_buf
);
btrfs_block_release
(
root
,
right_buf
);
return
1
;
return
1
;
}
}
if
(
push_items
==
left_nritems
)
WARN_ON
(
1
);
right_nritems
=
btrfs_header_nritems
(
&
right
->
header
);
right_nritems
=
btrfs_header_nritems
(
&
right
->
header
);
/* push left to right */
/* push left to right */
push_space
=
btrfs_item_end
(
left
->
items
+
left_nritems
-
push_items
);
push_space
=
btrfs_item_end
(
left
->
items
+
left_nritems
-
push_items
);
...
@@ -943,6 +949,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -943,6 +949,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_mark_buffer_dirty
(
left_buf
);
btrfs_mark_buffer_dirty
(
left_buf
);
btrfs_mark_buffer_dirty
(
right_buf
);
btrfs_mark_buffer_dirty
(
right_buf
);
btrfs_memcpy
(
root
,
upper_node
,
&
upper_node
->
ptrs
[
slot
+
1
].
key
,
btrfs_memcpy
(
root
,
upper_node
,
&
upper_node
->
ptrs
[
slot
+
1
].
key
,
&
right
->
items
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
&
right
->
items
[
0
].
key
,
sizeof
(
struct
btrfs_disk_key
));
btrfs_mark_buffer_dirty
(
upper
);
btrfs_mark_buffer_dirty
(
upper
);
...
@@ -1004,7 +1011,12 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -1004,7 +1011,12 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
return
1
;
return
1
;
}
}
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
);
i
++
)
{
if
(
btrfs_header_nritems
(
&
right
->
header
)
==
0
)
{
btrfs_block_release
(
root
,
t
);
return
1
;
}
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
right
->
header
)
-
1
;
i
++
)
{
item
=
right
->
items
+
i
;
item
=
right
->
items
+
i
;
if
(
path
->
slots
[
0
]
==
i
)
if
(
path
->
slots
[
0
]
==
i
)
push_space
+=
data_size
+
sizeof
(
*
item
);
push_space
+=
data_size
+
sizeof
(
*
item
);
...
@@ -1018,6 +1030,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -1018,6 +1030,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_block_release
(
root
,
t
);
btrfs_block_release
(
root
,
t
);
return
1
;
return
1
;
}
}
if
(
push_items
==
btrfs_header_nritems
(
&
right
->
header
))
WARN_ON
(
1
);
/* push data from right to left */
/* push data from right to left */
btrfs_memcpy
(
root
,
left
,
left
->
items
+
btrfs_memcpy
(
root
,
left
,
left
->
items
+
btrfs_header_nritems
(
&
left
->
header
),
btrfs_header_nritems
(
&
left
->
header
),
...
@@ -1064,7 +1078,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -1064,7 +1078,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_mark_buffer_dirty
(
t
);
btrfs_mark_buffer_dirty
(
t
);
btrfs_mark_buffer_dirty
(
right_buf
);
btrfs_mark_buffer_dirty
(
right_buf
);
wret
=
fixup_low_keys
(
trans
,
root
,
path
,
&
right
->
items
[
0
].
key
,
1
);
wret
=
fixup_low_keys
(
trans
,
root
,
path
,
&
right
->
items
[
0
].
key
,
1
);
if
(
wret
)
if
(
wret
)
ret
=
wret
;
ret
=
wret
;
...
@@ -1181,6 +1194,12 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -1181,6 +1194,12 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
path
->
nodes
[
0
]
=
right_buffer
;
path
->
nodes
[
0
]
=
right_buffer
;
path
->
slots
[
0
]
=
0
;
path
->
slots
[
0
]
=
0
;
path
->
slots
[
1
]
-=
1
;
path
->
slots
[
1
]
-=
1
;
if
(
path
->
slots
[
1
]
==
0
)
{
wret
=
fixup_low_keys
(
trans
,
root
,
path
,
&
disk_key
,
1
);
if
(
wret
)
ret
=
wret
;
}
return
ret
;
return
ret
;
}
}
mid
=
slot
;
mid
=
slot
;
...
@@ -1241,6 +1260,11 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -1241,6 +1260,11 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
path
->
slots
[
1
],
1
);
path
->
slots
[
1
],
1
);
if
(
wret
)
if
(
wret
)
ret
=
wret
;
ret
=
wret
;
if
(
path
->
slots
[
1
]
==
0
)
{
wret
=
fixup_low_keys
(
trans
,
root
,
path
,
&
disk_key
,
1
);
if
(
wret
)
ret
=
wret
;
}
btrfs_block_release
(
root
,
path
->
nodes
[
0
]);
btrfs_block_release
(
root
,
path
->
nodes
[
0
]);
path
->
nodes
[
0
]
=
right_buffer
;
path
->
nodes
[
0
]
=
right_buffer
;
path
->
slots
[
0
]
=
0
;
path
->
slots
[
0
]
=
0
;
...
...
fs/btrfs/ctree.h
浏览文件 @
a429e513
...
@@ -282,11 +282,12 @@ struct btrfs_root {
...
@@ -282,11 +282,12 @@ struct btrfs_root {
/* the lower bits in the key flags defines the item type */
/* the lower bits in the key flags defines the item type */
#define BTRFS_KEY_TYPE_MAX 256
#define BTRFS_KEY_TYPE_MAX 256
#define BTRFS_KEY_TYPE_MASK (BTRFS_KEY_TYPE_MAX - 1)
#define BTRFS_KEY_TYPE_SHIFT 24
#define BTRFS_KEY_TYPE_MASK (((u32)BTRFS_KEY_TYPE_MAX - 1) << \
BTRFS_KEY_TYPE_SHIFT)
#define BTRFS_KEY_OVERFLOW_MAX 128
#define BTRFS_KEY_OVERFLOW_MAX 128
#define BTRFS_KEY_OVERFLOW_SHIFT 8
#define BTRFS_KEY_OVERFLOW_MASK ((u32)BTRFS_KEY_OVERFLOW_MAX - 1)
#define BTRFS_KEY_OVERFLOW_MASK (0x7FULL << BTRFS_KEY_OVERFLOW_SHIFT)
/*
/*
* inode items have the data typically returned from stat and store other
* inode items have the data typically returned from stat and store other
...
@@ -586,56 +587,55 @@ static inline void btrfs_set_disk_key_flags(struct btrfs_disk_key *disk,
...
@@ -586,56 +587,55 @@ static inline void btrfs_set_disk_key_flags(struct btrfs_disk_key *disk,
disk
->
flags
=
cpu_to_le32
(
val
);
disk
->
flags
=
cpu_to_le32
(
val
);
}
}
static
inline
u32
btrfs_
key_overflow
(
struct
btrfs
_key
*
key
)
static
inline
u32
btrfs_
disk_key_type
(
struct
btrfs_disk
_key
*
key
)
{
{
u32
over
=
key
->
flags
&
BTRFS_KEY_OVERFLOW_MASK
;
return
le32_to_cpu
(
key
->
flags
)
>>
BTRFS_KEY_TYPE_SHIFT
;
return
over
>>
BTRFS_KEY_OVERFLOW_SHIFT
;
}
}
static
inline
void
btrfs_set_key_overflow
(
struct
btrfs_key
*
key
,
u32
over
)
static
inline
void
btrfs_set_disk_key_type
(
struct
btrfs_disk_key
*
key
,
u32
val
)
{
{
BUG_ON
(
over
>=
BTRFS_KEY_OVERFLOW_MAX
);
u32
flags
=
btrfs_disk_key_flags
(
key
);
over
=
over
<<
BTRFS_KEY_OVERFLOW_SHIFT
;
BUG_ON
(
val
>=
BTRFS_KEY_TYPE_MAX
);
key
->
flags
=
(
key
->
flags
&
~
((
u64
)
BTRFS_KEY_OVERFLOW_MASK
))
|
over
;
val
=
val
<<
BTRFS_KEY_TYPE_SHIFT
;
flags
=
(
flags
&
~
BTRFS_KEY_TYPE_MASK
)
|
val
;
btrfs_set_disk_key_flags
(
key
,
flags
);
}
}
static
inline
u32
btrfs_key_type
(
struct
btrfs_key
*
key
)
static
inline
u32
btrfs_key_type
(
struct
btrfs_key
*
key
)
{
{
return
key
->
flags
&
BTRFS_KEY_TYPE_MASK
;
return
key
->
flags
>>
BTRFS_KEY_TYPE_SHIFT
;
}
}
static
inline
u32
btrfs_disk_key_type
(
struct
btrfs_disk_key
*
key
)
static
inline
void
btrfs_set_key_type
(
struct
btrfs_key
*
key
,
u32
val
)
{
{
return
le32_to_cpu
(
key
->
flags
)
&
BTRFS_KEY_TYPE_MASK
;
BUG_ON
(
val
>=
BTRFS_KEY_TYPE_MAX
);
val
=
val
<<
BTRFS_KEY_TYPE_SHIFT
;
key
->
flags
=
(
key
->
flags
&
~
(
BTRFS_KEY_TYPE_MASK
))
|
val
;
}
}
static
inline
void
btrfs_set_key_type
(
struct
btrfs_key
*
key
,
u32
type
)
static
inline
u32
btrfs_key_overflow
(
struct
btrfs_key
*
key
)
{
{
BUG_ON
(
type
>=
BTRFS_KEY_TYPE_MAX
);
return
key
->
flags
&
BTRFS_KEY_OVERFLOW_MASK
;
key
->
flags
=
(
key
->
flags
&
~
((
u64
)
BTRFS_KEY_TYPE_MASK
))
|
type
;
}
}
static
inline
void
btrfs_set_
disk_key_type
(
struct
btrfs_disk_key
*
key
,
u32
type
)
static
inline
void
btrfs_set_
key_overflow
(
struct
btrfs_key
*
key
,
u32
over
)
{
{
u32
flags
=
btrfs_disk_key_flags
(
key
);
BUG_ON
(
over
>=
BTRFS_KEY_OVERFLOW_MAX
);
BUG_ON
(
type
>=
BTRFS_KEY_TYPE_MAX
);
key
->
flags
=
(
key
->
flags
&
~
BTRFS_KEY_OVERFLOW_MASK
)
|
over
;
flags
=
(
flags
&
~
((
u64
)
BTRFS_KEY_TYPE_MASK
))
|
type
;
btrfs_set_disk_key_flags
(
key
,
flags
);
}
}
static
inline
u32
btrfs_disk_key_overflow
(
struct
btrfs_disk_key
*
key
)
static
inline
u32
btrfs_disk_key_overflow
(
struct
btrfs_disk_key
*
key
)
{
{
u32
over
=
le32_to_cpu
(
key
->
flags
)
&
BTRFS_KEY_OVERFLOW_MASK
;
return
le32_to_cpu
(
key
->
flags
)
&
BTRFS_KEY_OVERFLOW_MASK
;
return
over
>>
BTRFS_KEY_OVERFLOW_SHIFT
;
}
}
static
inline
void
btrfs_set_dis
K
_key_overflow
(
struct
btrfs_disk_key
*
key
,
static
inline
void
btrfs_set_dis
k
_key_overflow
(
struct
btrfs_disk_key
*
key
,
u32
over
)
u32
over
)
{
{
u32
flags
=
btrfs_disk_key_flags
(
key
);
u32
flags
=
btrfs_disk_key_flags
(
key
);
BUG_ON
(
over
>=
BTRFS_KEY_OVERFLOW_MAX
);
BUG_ON
(
over
>=
BTRFS_KEY_OVERFLOW_MAX
);
over
=
over
<<
BTRFS_KEY_OVERFLOW_SHIFT
;
flags
=
(
flags
&
~
BTRFS_KEY_OVERFLOW_MASK
)
|
over
;
flags
=
(
flags
&
~
((
u64
)
BTRFS_KEY_OVERFLOW_MASK
))
|
over
;
btrfs_set_disk_key_flags
(
key
,
flags
);
btrfs_set_disk_key_flags
(
key
,
flags
);
}
}
...
...
fs/btrfs/dir-item.c
浏览文件 @
a429e513
...
@@ -58,30 +58,6 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -58,30 +58,6 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
name_ptr
,
name
,
name_len
);
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
name_ptr
,
name
,
name_len
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
/* FIXME, use some real flag for selecting the extra index */
if
(
root
==
root
->
fs_info
->
tree_root
)
goto
out
;
btrfs_release_path
(
root
,
path
);
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_INDEX_KEY
);
key
.
offset
=
location
->
objectid
;
ret
=
insert_with_overflow
(
trans
,
root
,
path
,
&
key
,
data_size
);
// FIXME clear the dirindex bit
if
(
ret
)
goto
out
;
dir_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_dir_item
);
btrfs_cpu_key_to_disk
(
&
dir_item
->
location
,
location
);
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
]);
out:
out:
btrfs_release_path
(
root
,
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
...
@@ -135,52 +111,6 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -135,52 +111,6 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
return
1
;
return
1
;
}
}
int
btrfs_lookup_dir_index_item
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
dir
,
u64
objectid
,
int
mod
)
{
int
ret
;
struct
btrfs_key
key
;
int
ins_len
=
mod
<
0
?
-
1
:
0
;
int
cow
=
mod
!=
0
;
struct
btrfs_disk_key
*
found_key
;
struct
btrfs_leaf
*
leaf
;
int
overflow
=
0
;
key
.
objectid
=
dir
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_INDEX_KEY
);
key
.
offset
=
objectid
;
while
(
1
)
{
btrfs_set_key_overflow
(
&
key
,
overflow
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
ins_len
,
cow
);
if
(
ret
<
0
)
return
ret
;
if
(
ret
>
0
)
{
if
(
overflow
>=
BTRFS_KEY_OVERFLOW_MAX
)
return
1
;
overflow
++
;
btrfs_set_key_overflow
(
&
key
,
overflow
);
btrfs_release_path
(
root
,
path
);
continue
;
}
else
{
/* found */
break
;
}
}
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
found_key
=
&
leaf
->
items
[
path
->
slots
[
0
]].
key
;
if
(
btrfs_disk_key_objectid
(
found_key
)
!=
dir
||
btrfs_disk_key_type
(
found_key
)
!=
BTRFS_DIR_INDEX_KEY
)
return
1
;
if
(
btrfs_disk_key_offset
(
found_key
)
==
objectid
)
return
0
;
return
1
;
}
int
btrfs_match_dir_item_name
(
struct
btrfs_root
*
root
,
int
btrfs_match_dir_item_name
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_path
*
path
,
const
char
*
name
,
int
name_len
)
const
char
*
name
,
int
name_len
)
...
...
fs/btrfs/extent-tree.c
浏览文件 @
a429e513
...
@@ -35,8 +35,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
...
@@ -35,8 +35,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
key
.
offset
=
num_blocks
;
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
);
0
,
1
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
{
printk
(
"can't find block %Lu %Lu
\n
"
,
blocknr
,
num_blocks
);
BUG
();
BUG
();
}
BUG_ON
(
ret
!=
0
);
BUG_ON
(
ret
!=
0
);
l
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
l
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
item
=
btrfs_item_ptr
(
l
,
path
->
slots
[
0
],
struct
btrfs_extent_item
);
item
=
btrfs_item_ptr
(
l
,
path
->
slots
[
0
],
struct
btrfs_extent_item
);
...
...
fs/btrfs/file-item.c
浏览文件 @
a429e513
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
#include "transaction.h"
#include "transaction.h"
#define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \
#define MAX_CSUM_ITEMS(r) ((((BTRFS_LEAF_DATA_SIZE(r) - \
sizeof(struct btrfs_item)) / \
sizeof(struct btrfs_item)
* 2
) / \
sizeof(struct btrfs_csum_item)) - 1))
sizeof(struct btrfs_csum_item)) - 1))
int
btrfs_insert_file_extent
(
struct
btrfs_trans_handle
*
trans
,
int
btrfs_insert_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_root
*
root
,
...
@@ -19,11 +19,6 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
...
@@ -19,11 +19,6 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
path
=
btrfs_alloc_path
();
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
btrfs_init_path
(
path
);
/*
ret = btrfs_alloc_extent(trans, root, num_blocks, hint_block,
(u64)-1, &ins);
*/
BUG_ON
(
ret
);
file_key
.
objectid
=
objectid
;
file_key
.
objectid
=
objectid
;
file_key
.
offset
=
pos
;
file_key
.
offset
=
pos
;
file_key
.
flags
=
0
;
file_key
.
flags
=
0
;
...
@@ -40,6 +35,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
...
@@ -40,6 +35,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
btrfs_set_file_extent_num_blocks
(
item
,
num_blocks
);
btrfs_set_file_extent_num_blocks
(
item
,
num_blocks
);
btrfs_set_file_extent_generation
(
item
,
trans
->
transid
);
btrfs_set_file_extent_generation
(
item
,
trans
->
transid
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_release_path
(
root
,
path
);
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
return
0
;
return
0
;
...
@@ -57,6 +53,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
...
@@ -57,6 +53,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
struct
btrfs_csum_item
*
item
;
struct
btrfs_csum_item
*
item
;
struct
btrfs_leaf
*
leaf
;
struct
btrfs_leaf
*
leaf
;
u64
csum_offset
=
0
;
u64
csum_offset
=
0
;
int
csums_in_item
;
file_key
.
objectid
=
objectid
;
file_key
.
objectid
=
objectid
;
file_key
.
offset
=
offset
;
file_key
.
offset
=
offset
;
...
@@ -79,9 +76,11 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
...
@@ -79,9 +76,11 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
}
}
csum_offset
=
(
offset
-
found_key
.
offset
)
>>
csum_offset
=
(
offset
-
found_key
.
offset
)
>>
root
->
fs_info
->
sb
->
s_blocksize_bits
;
root
->
fs_info
->
sb
->
s_blocksize_bits
;
if
(
csum_offset
>=
csums_in_item
=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
]);
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
])
/
csums_in_item
/=
sizeof
(
struct
btrfs_csum_item
);
sizeof
(
struct
btrfs_csum_item
))
{
if
(
csum_offset
>=
csums_in_item
)
{
ret
=
-
EFBIG
;
goto
fail
;
goto
fail
;
}
}
}
}
...
@@ -128,16 +127,36 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
...
@@ -128,16 +127,36 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
path
=
btrfs_alloc_path
();
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
BUG_ON
(
!
path
);
btrfs_init_path
(
path
);
item
=
btrfs_lookup_csum
(
trans
,
root
,
path
,
objectid
,
offset
,
0
);
if
(
!
IS_ERR
(
item
))
goto
found
;
btrfs_release_path
(
root
,
path
);
file_key
.
objectid
=
objectid
;
file_key
.
objectid
=
objectid
;
file_key
.
offset
=
offset
;
file_key
.
offset
=
offset
;
file_key
.
flags
=
0
;
file_key
.
flags
=
0
;
btrfs_set_key_type
(
&
file_key
,
BTRFS_CSUM_ITEM_KEY
);
btrfs_set_key_type
(
&
file_key
,
BTRFS_CSUM_ITEM_KEY
);
item
=
btrfs_lookup_csum
(
trans
,
root
,
path
,
objectid
,
offset
,
1
);
if
(
!
IS_ERR
(
item
))
goto
found
;
ret
=
PTR_ERR
(
item
);
if
(
ret
==
-
EFBIG
)
{
u32
item_size
;
/* we found one, but it isn't big enough yet */
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
item_size
=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
]);
if
((
item_size
/
sizeof
(
struct
btrfs_csum_item
))
>=
MAX_CSUM_ITEMS
(
root
))
{
/* already at max size, make a new one */
goto
insert
;
}
}
else
{
/* we didn't find a csum item, insert one */
goto
insert
;
}
/*
* at this point, we know the tree has an item, but it isn't big
* enough yet to put our csum in. Grow it
*/
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
file_key
,
path
,
ret
=
btrfs_search_slot
(
trans
,
root
,
&
file_key
,
path
,
sizeof
(
struct
btrfs_csum_item
),
1
);
sizeof
(
struct
btrfs_csum_item
),
1
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -146,7 +165,6 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
...
@@ -146,7 +165,6 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
BUG
();
BUG
();
}
}
if
(
path
->
slots
[
0
]
==
0
)
{
if
(
path
->
slots
[
0
]
==
0
)
{
btrfs_release_path
(
root
,
path
);
goto
insert
;
goto
insert
;
}
}
path
->
slots
[
0
]
--
;
path
->
slots
[
0
]
--
;
...
@@ -157,29 +175,36 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
...
@@ -157,29 +175,36 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
if
(
btrfs_key_type
(
&
found_key
)
!=
BTRFS_CSUM_ITEM_KEY
||
if
(
btrfs_key_type
(
&
found_key
)
!=
BTRFS_CSUM_ITEM_KEY
||
found_key
.
objectid
!=
objectid
||
found_key
.
objectid
!=
objectid
||
csum_offset
>=
MAX_CSUM_ITEMS
(
root
))
{
csum_offset
>=
MAX_CSUM_ITEMS
(
root
))
{
btrfs_release_path
(
root
,
path
);
WARN_ON
(
1
);
goto
insert
;
goto
insert
;
}
}
if
(
csum_offset
>=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
])
/
if
(
csum_offset
>=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
])
/
sizeof
(
struct
btrfs_csum_item
))
{
sizeof
(
struct
btrfs_csum_item
))
{
ret
=
btrfs_extend_item
(
trans
,
root
,
path
,
u32
diff
=
(
csum_offset
+
1
)
*
sizeof
(
struct
btrfs_csum_item
);
sizeof
(
struct
btrfs_csum_item
));
diff
=
diff
-
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
]);
WARN_ON
(
diff
!=
sizeof
(
struct
btrfs_csum_item
));
ret
=
btrfs_extend_item
(
trans
,
root
,
path
,
diff
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
goto
csum
;
goto
csum
;
}
}
insert:
insert:
btrfs_release_path
(
root
,
path
);
csum_offset
=
0
;
csum_offset
=
0
;
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
file_key
,
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
file_key
,
sizeof
(
struct
btrfs_csum_item
));
sizeof
(
struct
btrfs_csum_item
));
if
(
ret
!=
0
&&
ret
!=
-
EEXIST
)
if
(
ret
!=
0
)
{
printk
(
"at insert for %Lu %u %Lu ret is %d
\n
"
,
file_key
.
objectid
,
file_key
.
flags
,
file_key
.
offset
,
ret
);
WARN_ON
(
1
);
goto
fail
;
goto
fail
;
}
csum:
csum:
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
);
struct
btrfs_csum_item
);
ret
=
0
;
ret
=
0
;
item
+=
csum_offset
;
item
+=
csum_offset
;
found:
found:
btrfs_check_bounds
(
item
->
csum
,
BTRFS_CSUM_SIZE
,
path
->
nodes
[
0
]
->
b_data
,
root
->
fs_info
->
sb
->
s_blocksize
);
ret
=
btrfs_csum_data
(
root
,
data
,
len
,
item
->
csum
);
ret
=
btrfs_csum_data
(
root
,
data
,
len
,
item
->
csum
);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
fail:
fail:
...
@@ -210,6 +235,9 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root,
...
@@ -210,6 +235,9 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root,
item
=
btrfs_lookup_csum
(
NULL
,
root
,
path
,
objectid
,
offset
,
0
);
item
=
btrfs_lookup_csum
(
NULL
,
root
,
path
,
objectid
,
offset
,
0
);
if
(
IS_ERR
(
item
))
{
if
(
IS_ERR
(
item
))
{
ret
=
PTR_ERR
(
item
);
ret
=
PTR_ERR
(
item
);
/* a csum that isn't present is a preallocated region. */
if
(
ret
==
-
ENOENT
||
ret
==
-
EFBIG
)
ret
=
1
;
goto
fail
;
goto
fail
;
}
}
...
...
fs/btrfs/print-tree.c
浏览文件 @
a429e513
...
@@ -19,7 +19,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
...
@@ -19,7 +19,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
item
=
l
->
items
+
i
;
item
=
l
->
items
+
i
;
type
=
btrfs_disk_key_type
(
&
item
->
key
);
type
=
btrfs_disk_key_type
(
&
item
->
key
);
printk
(
"
\t
item %d key (%Lu %
u
%Lu) itemoff %d itemsize %d
\n
"
,
printk
(
"
\t
item %d key (%Lu %
x
%Lu) itemoff %d itemsize %d
\n
"
,
i
,
i
,
btrfs_disk_key_objectid
(
&
item
->
key
),
btrfs_disk_key_objectid
(
&
item
->
key
),
btrfs_disk_key_flags
(
&
item
->
key
),
btrfs_disk_key_flags
(
&
item
->
key
),
...
...
fs/btrfs/super.c
浏览文件 @
a429e513
...
@@ -150,11 +150,6 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
...
@@ -150,11 +150,6 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
BUG_ON
(
ret
);
BUG_ON
(
ret
);
btrfs_release_path
(
root
,
path
);
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_lookup_dir_index_item
(
trans
,
root
,
path
,
dir
->
i_ino
,
objectid
,
-
1
);
BUG_ON
(
ret
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
BUG_ON
(
ret
);
dentry
->
d_inode
->
i_ctime
=
dir
->
i_ctime
;
dentry
->
d_inode
->
i_ctime
=
dir
->
i_ctime
;
err:
err:
btrfs_release_path
(
root
,
path
);
btrfs_release_path
(
root
,
path
);
...
@@ -329,8 +324,9 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
...
@@ -329,8 +324,9 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
extent_start
=
btrfs_file_extent_disk_blocknr
(
fi
);
extent_start
=
btrfs_file_extent_disk_blocknr
(
fi
);
extent_num_blocks
=
extent_num_blocks
=
btrfs_file_extent_disk_num_blocks
(
fi
);
btrfs_file_extent_disk_num_blocks
(
fi
);
/* FIXME blocksize != 4096 */
inode
->
i_blocks
-=
inode
->
i_blocks
-=
btrfs_file_extent_num_blocks
(
fi
)
>>
9
;
btrfs_file_extent_num_blocks
(
fi
)
<<
3
;
found_extent
=
1
;
found_extent
=
1
;
}
else
{
}
else
{
found_extent
=
0
;
found_extent
=
0
;
...
@@ -562,7 +558,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
...
@@ -562,7 +558,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if
(
btrfs_disk_key_objectid
(
&
item
->
key
)
!=
key
.
objectid
)
if
(
btrfs_disk_key_objectid
(
&
item
->
key
)
!=
key
.
objectid
)
break
;
break
;
if
(
btrfs_disk_key_type
(
&
item
->
key
)
!=
key_type
)
if
(
btrfs_disk_key_type
(
&
item
->
key
)
!=
key_type
)
continue
;
break
;
if
(
btrfs_disk_key_offset
(
&
item
->
key
)
<
filp
->
f_pos
)
if
(
btrfs_disk_key_offset
(
&
item
->
key
)
<
filp
->
f_pos
)
continue
;
continue
;
filp
->
f_pos
=
btrfs_disk_key_offset
(
&
item
->
key
);
filp
->
f_pos
=
btrfs_disk_key_offset
(
&
item
->
key
);
...
@@ -1285,29 +1281,27 @@ static int drop_extents(struct btrfs_trans_handle *trans,
...
@@ -1285,29 +1281,27 @@ static int drop_extents(struct btrfs_trans_handle *trans,
struct
btrfs_path
*
path
;
struct
btrfs_path
*
path
;
u64
search_start
=
start
;
u64
search_start
=
start
;
int
bookend
;
int
bookend
;
path
=
btrfs_alloc_path
();
path
=
btrfs_alloc_path
();
if
(
!
path
)
if
(
!
path
)
return
-
ENOMEM
;
return
-
ENOMEM
;
search_again:
while
(
1
)
{
ret
=
btrfs_lookup_file_extent
(
trans
,
root
,
path
,
inode
->
i_ino
,
btrfs_release_path
(
root
,
path
);
search_start
,
-
1
);
ret
=
btrfs_lookup_file_extent
(
trans
,
root
,
path
,
inode
->
i_ino
,
if
(
ret
<
0
)
search_start
,
-
1
);
goto
out
;
if
(
ret
<
0
)
if
(
ret
>
0
)
{
if
(
path
->
slots
[
0
]
==
0
)
{
ret
=
-
ENOENT
;
goto
out
;
goto
out
;
if
(
ret
>
0
)
{
if
(
path
->
slots
[
0
]
==
0
)
{
ret
=
-
ENOENT
;
goto
out
;
}
path
->
slots
[
0
]
--
;
}
}
path
->
slots
[
0
]
--
;
}
while
(
1
)
{
keep
=
0
;
keep
=
0
;
bookend
=
0
;
bookend
=
0
;
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
slot
=
path
->
slots
[
0
];
slot
=
path
->
slots
[
0
];
btrfs_disk_key_to_cpu
(
&
key
,
&
leaf
->
items
[
slot
].
key
);
btrfs_disk_key_to_cpu
(
&
key
,
&
leaf
->
items
[
slot
].
key
);
extent
=
btrfs_item_ptr
(
leaf
,
slot
,
extent
=
btrfs_item_ptr
(
leaf
,
slot
,
struct
btrfs_file_extent_item
);
struct
btrfs_file_extent_item
);
extent_end
=
key
.
offset
+
extent_end
=
key
.
offset
+
...
@@ -1318,7 +1312,10 @@ static int drop_extents(struct btrfs_trans_handle *trans,
...
@@ -1318,7 +1312,10 @@ static int drop_extents(struct btrfs_trans_handle *trans,
goto
out
;
goto
out
;
}
}
if
(
btrfs_key_type
(
&
key
)
!=
BTRFS_EXTENT_DATA_KEY
)
if
(
btrfs_key_type
(
&
key
)
!=
BTRFS_EXTENT_DATA_KEY
)
goto
next_leaf
;
goto
out
;
if
(
search_start
>=
extent_end
)
goto
out
;
search_start
=
extent_end
;
if
(
end
<
extent_end
&&
end
>=
key
.
offset
)
{
if
(
end
<
extent_end
&&
end
>=
key
.
offset
)
{
memcpy
(
&
old
,
extent
,
sizeof
(
old
));
memcpy
(
&
old
,
extent
,
sizeof
(
old
));
...
@@ -1331,10 +1328,13 @@ static int drop_extents(struct btrfs_trans_handle *trans,
...
@@ -1331,10 +1328,13 @@ static int drop_extents(struct btrfs_trans_handle *trans,
if
(
start
>
key
.
offset
)
{
if
(
start
>
key
.
offset
)
{
u64
new_num
;
u64
new_num
;
u64
old_num
;
/* truncate existing extent */
/* truncate existing extent */
keep
=
1
;
keep
=
1
;
WARN_ON
(
start
&
(
root
->
blocksize
-
1
));
WARN_ON
(
start
&
(
root
->
blocksize
-
1
));
new_num
=
(
start
-
key
.
offset
)
>>
inode
->
i_blkbits
;
new_num
=
(
start
-
key
.
offset
)
>>
inode
->
i_blkbits
;
old_num
=
btrfs_file_extent_num_blocks
(
extent
);
inode
->
i_blocks
-=
(
old_num
-
new_num
)
<<
3
;
btrfs_set_file_extent_num_blocks
(
extent
,
new_num
);
btrfs_set_file_extent_num_blocks
(
extent
,
new_num
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
}
}
...
@@ -1344,13 +1344,11 @@ static int drop_extents(struct btrfs_trans_handle *trans,
...
@@ -1344,13 +1344,11 @@ static int drop_extents(struct btrfs_trans_handle *trans,
disk_blocknr
=
btrfs_file_extent_disk_blocknr
(
extent
);
disk_blocknr
=
btrfs_file_extent_disk_blocknr
(
extent
);
disk_num_blocks
=
disk_num_blocks
=
btrfs_file_extent_disk_num_blocks
(
extent
);
btrfs_file_extent_disk_num_blocks
(
extent
);
search_start
=
key
.
offset
+
(
btrfs_file_extent_num_blocks
(
extent
)
<<
inode
->
i_blkbits
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
inode
->
i_blocks
-=
btrfs_file_extent_num_blocks
(
extent
)
<<
3
;
btrfs_release_path
(
root
,
path
);
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_free_extent
(
trans
,
root
,
disk_blocknr
,
ret
=
btrfs_free_extent
(
trans
,
root
,
disk_blocknr
,
disk_num_blocks
,
0
);
disk_num_blocks
,
0
);
...
@@ -1360,7 +1358,7 @@ static int drop_extents(struct btrfs_trans_handle *trans,
...
@@ -1360,7 +1358,7 @@ static int drop_extents(struct btrfs_trans_handle *trans,
goto
out
;
goto
out
;
}
}
if
(
!
bookend
)
if
(
!
bookend
)
goto
search_again
;
continue
;
}
}
if
(
bookend
)
{
if
(
bookend
)
{
/* create bookend */
/* create bookend */
...
@@ -1395,21 +1393,12 @@ static int drop_extents(struct btrfs_trans_handle *trans,
...
@@ -1395,21 +1393,12 @@ static int drop_extents(struct btrfs_trans_handle *trans,
btrfs_set_file_extent_generation
(
extent
,
btrfs_set_file_extent_generation
(
extent
,
btrfs_file_extent_generation
(
&
old
));
btrfs_file_extent_generation
(
&
old
));
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
inode
->
i_blocks
+=
btrfs_file_extent_num_blocks
(
extent
)
<<
3
;
ret
=
0
;
ret
=
0
;
goto
out
;
goto
out
;
}
}
next_leaf:
if
(
slot
>=
btrfs_header_nritems
(
&
leaf
->
header
)
-
1
)
{
ret
=
btrfs_next_leaf
(
root
,
path
);
if
(
ret
)
{
ret
=
0
;
goto
out
;
}
}
else
{
path
->
slots
[
0
]
++
;
}
}
}
out:
out:
btrfs_free_path
(
path
);
btrfs_free_path
(
path
);
return
ret
;
return
ret
;
...
@@ -1445,15 +1434,6 @@ static int prepare_pages(struct btrfs_root *root,
...
@@ -1445,15 +1434,6 @@ static int prepare_pages(struct btrfs_root *root,
}
}
offset
=
pos
&
(
PAGE_CACHE_SIZE
-
1
);
offset
=
pos
&
(
PAGE_CACHE_SIZE
-
1
);
this_write
=
min
(
PAGE_CACHE_SIZE
-
offset
,
write_bytes
);
this_write
=
min
(
PAGE_CACHE_SIZE
-
offset
,
write_bytes
);
#if 0
if ((pages[i]->index == first_index ||
pages[i]->index == last_index) && pos < isize &&
!PageUptodate(pages[i])) {
ret = mpage_readpage(pages[i], btrfs_get_block);
BUG_ON(ret);
lock_page(pages[i]);
}
#endif
create_empty_buffers
(
pages
[
i
],
root
->
fs_info
->
sb
->
s_blocksize
,
create_empty_buffers
(
pages
[
i
],
root
->
fs_info
->
sb
->
s_blocksize
,
(
1
<<
BH_Uptodate
));
(
1
<<
BH_Uptodate
));
head
=
page_buffers
(
pages
[
i
]);
head
=
page_buffers
(
pages
[
i
]);
...
@@ -1494,6 +1474,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
...
@@ -1494,6 +1474,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
page
*
pages
[
8
];
struct
page
*
pages
[
8
];
struct
page
*
pinned
[
2
]
=
{
NULL
,
NULL
};
unsigned
long
first_index
;
unsigned
long
first_index
;
unsigned
long
last_index
;
unsigned
long
last_index
;
u64
start_pos
;
u64
start_pos
;
...
@@ -1505,14 +1486,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
...
@@ -1505,14 +1486,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
if
(
file
->
f_flags
&
O_DIRECT
)
if
(
file
->
f_flags
&
O_DIRECT
)
return
-
EINVAL
;
return
-
EINVAL
;
pos
=
*
ppos
;
pos
=
*
ppos
;
start_pos
=
pos
&
~
(
root
->
blocksize
-
1
);
/* FIXME */
if
(
start_pos
!=
pos
)
return
-
EINVAL
;
num_blocks
=
(
count
+
pos
-
start_pos
+
root
->
blocksize
-
1
)
>>
inode
->
i_blkbits
;
vfs_check_frozen
(
inode
->
i_sb
,
SB_FREEZE_WRITE
);
vfs_check_frozen
(
inode
->
i_sb
,
SB_FREEZE_WRITE
);
current
->
backing_dev_info
=
inode
->
i_mapping
->
backing_dev_info
;
current
->
backing_dev_info
=
inode
->
i_mapping
->
backing_dev_info
;
err
=
generic_write_checks
(
file
,
&
pos
,
&
count
,
S_ISBLK
(
inode
->
i_mode
));
err
=
generic_write_checks
(
file
,
&
pos
,
&
count
,
S_ISBLK
(
inode
->
i_mode
));
...
@@ -1524,10 +1497,37 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
...
@@ -1524,10 +1497,37 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
if
(
err
)
if
(
err
)
goto
out
;
goto
out
;
file_update_time
(
file
);
file_update_time
(
file
);
start_pos
=
pos
&
~
((
u64
)
PAGE_CACHE_SIZE
-
1
);
num_blocks
=
(
count
+
pos
-
start_pos
+
root
->
blocksize
-
1
)
>>
inode
->
i_blkbits
;
mutex_lock
(
&
inode
->
i_mutex
);
mutex_lock
(
&
inode
->
i_mutex
);
first_index
=
pos
>>
PAGE_CACHE_SHIFT
;
first_index
=
pos
>>
PAGE_CACHE_SHIFT
;
last_index
=
(
pos
+
count
)
>>
PAGE_CACHE_SHIFT
;
last_index
=
(
pos
+
count
)
>>
PAGE_CACHE_SHIFT
;
if
((
first_index
<<
PAGE_CACHE_SHIFT
)
<
inode
->
i_size
&&
(
pos
&
(
PAGE_CACHE_SIZE
-
1
)))
{
pinned
[
0
]
=
grab_cache_page
(
inode
->
i_mapping
,
first_index
);
if
(
!
PageUptodate
(
pinned
[
0
]))
{
ret
=
mpage_readpage
(
pinned
[
0
],
btrfs_get_block
);
BUG_ON
(
ret
);
}
else
{
unlock_page
(
pinned
[
0
]);
}
}
if
(
first_index
!=
last_index
&&
(
last_index
<<
PAGE_CACHE_SHIFT
)
<
inode
->
i_size
&&
(
count
&
(
PAGE_CACHE_SIZE
-
1
)))
{
pinned
[
1
]
=
grab_cache_page
(
inode
->
i_mapping
,
last_index
);
if
(
!
PageUptodate
(
pinned
[
1
]))
{
ret
=
mpage_readpage
(
pinned
[
1
],
btrfs_get_block
);
BUG_ON
(
ret
);
}
else
{
unlock_page
(
pinned
[
1
]);
}
}
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
trans
=
btrfs_start_transaction
(
root
,
1
);
if
(
!
trans
)
{
if
(
!
trans
)
{
...
@@ -1535,11 +1535,14 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
...
@@ -1535,11 +1535,14 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
goto
out_unlock
;
goto
out_unlock
;
}
}
/* FIXME blocksize != 4096 */
inode
->
i_blocks
+=
num_blocks
<<
3
;
if
(
start_pos
<
inode
->
i_size
)
{
if
(
start_pos
<
inode
->
i_size
)
{
/* FIXME blocksize != pagesize */
ret
=
drop_extents
(
trans
,
root
,
inode
,
ret
=
drop_extents
(
trans
,
root
,
inode
,
start_pos
,
start_pos
,
(
pos
+
count
+
root
->
blocksize
-
1
)
&
(
pos
+
count
+
root
->
blocksize
-
1
)
&
~
(
root
->
blocksize
-
1
));
~
(
(
u64
)
root
->
blocksize
-
1
));
}
}
ret
=
btrfs_alloc_extent
(
trans
,
root
,
num_blocks
,
1
,
ret
=
btrfs_alloc_extent
(
trans
,
root
,
num_blocks
,
1
,
(
u64
)
-
1
,
&
ins
);
(
u64
)
-
1
,
&
ins
);
...
@@ -1585,8 +1588,13 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
...
@@ -1585,8 +1588,13 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
out_unlock:
out_unlock:
mutex_unlock
(
&
inode
->
i_mutex
);
mutex_unlock
(
&
inode
->
i_mutex
);
out:
out:
if
(
pinned
[
0
])
page_cache_release
(
pinned
[
0
]);
if
(
pinned
[
1
])
page_cache_release
(
pinned
[
1
]);
*
ppos
=
pos
;
*
ppos
=
pos
;
current
->
backing_dev_info
=
NULL
;
current
->
backing_dev_info
=
NULL
;
mark_inode_dirty
(
inode
);
return
num_written
?
num_written
:
err
;
return
num_written
?
num_written
:
err
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录