Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
3326d1b0
L
linux
项目概览
xiphi1978
/
linux
通知
2
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,发现更多精彩内容 >>
提交
3326d1b0
编写于
10月 15, 2007
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Allow tails larger than one page
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
4dc11904
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
156 addition
and
56 deletion
+156
-56
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+19
-5
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+1
-1
fs/btrfs/file.c
fs/btrfs/file.c
+116
-36
fs/btrfs/inode.c
fs/btrfs/inode.c
+20
-12
fs/btrfs/super.c
fs/btrfs/super.c
+0
-2
未找到文件。
fs/btrfs/ctree.c
浏览文件 @
3326d1b0
...
...
@@ -1766,8 +1766,9 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
/* first try to make some room by pushing left and right */
wret
=
push_leaf_left
(
trans
,
root
,
path
,
data_size
);
if
(
wret
<
0
)
if
(
wret
<
0
)
{
return
wret
;
}
if
(
wret
)
{
wret
=
push_leaf_right
(
trans
,
root
,
path
,
data_size
);
if
(
wret
<
0
)
...
...
@@ -1777,8 +1778,9 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
/* did the pushes work? */
if
(
btrfs_leaf_free_space
(
root
,
l
)
>=
sizeof
(
struct
btrfs_item
)
+
data_size
)
sizeof
(
struct
btrfs_item
)
+
data_size
)
{
return
0
;
}
if
(
!
path
->
nodes
[
1
])
{
ret
=
insert_new_root
(
trans
,
root
,
path
,
1
);
...
...
@@ -1822,8 +1824,12 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
return
ret
;
}
mid
=
slot
;
if
(
mid
!=
nritems
&&
leaf_space_used
(
l
,
mid
,
nritems
-
mid
)
+
space_needed
>
BTRFS_LEAF_DATA_SIZE
(
root
))
{
double_split
=
1
;
}
}
}
else
{
if
(
leaf_space_used
(
l
,
0
,
mid
+
1
)
+
space_needed
>
BTRFS_LEAF_DATA_SIZE
(
root
))
{
...
...
@@ -1910,8 +1916,9 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
BUG_ON
(
path
->
slots
[
0
]
<
0
);
if
(
!
double_split
)
if
(
!
double_split
)
{
return
ret
;
}
right
=
btrfs_alloc_free_block
(
trans
,
root
,
root
->
leafsize
,
l
->
start
,
0
);
...
...
@@ -2048,7 +2055,11 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
old_data
=
btrfs_item_end_nr
(
leaf
,
slot
);
BUG_ON
(
slot
<
0
);
BUG_ON
(
slot
>=
nritems
);
if
(
slot
>=
nritems
)
{
btrfs_print_leaf
(
root
,
leaf
);
printk
(
"slot %d too large, nritems %d
\n
"
,
slot
,
nritems
);
BUG_ON
(
1
);
}
/*
* item0..itemN ... dataN.offset..dataN.size .. data0.size
...
...
@@ -2132,6 +2143,9 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
if
(
btrfs_leaf_free_space
(
root
,
leaf
)
<
sizeof
(
struct
btrfs_item
)
+
data_size
)
{
btrfs_print_leaf
(
root
,
leaf
);
printk
(
"not enough freespace need %u have %d
\n
"
,
data_size
,
btrfs_leaf_free_space
(
root
,
leaf
));
BUG
();
}
...
...
fs/btrfs/ctree.h
浏览文件 @
3326d1b0
...
...
@@ -1137,7 +1137,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end);
extern
struct
file_operations
btrfs_file_operations
;
int
btrfs_drop_extents
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
inode
*
inode
,
u64
start
,
u64
end
,
u64
*
hint_block
);
u64
start
,
u64
end
,
u64
inline_end
,
u64
*
hint_block
);
/* tree-defrag.c */
int
btrfs_defrag_leaves
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
int
cache_only
);
...
...
fs/btrfs/file.c
浏览文件 @
3326d1b0
...
...
@@ -82,8 +82,9 @@ static void btrfs_drop_pages(struct page **pages, size_t num_pages)
static
int
insert_inline_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
inode
*
inode
,
u64
offset
,
ssize_t
size
,
struct
page
*
page
,
size_t
page_offset
)
u64
offset
,
size_t
size
,
struct
page
**
pages
,
size_t
page_offset
,
int
num_pages
)
{
struct
btrfs_key
key
;
struct
btrfs_path
*
path
;
...
...
@@ -91,9 +92,12 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
char
*
kaddr
;
unsigned
long
ptr
;
struct
btrfs_file_extent_item
*
ei
;
struct
page
*
page
;
u32
datasize
;
int
err
=
0
;
int
ret
;
int
i
;
ssize_t
cur_size
;
path
=
btrfs_alloc_path
();
if
(
!
path
)
...
...
@@ -104,13 +108,71 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
key
.
objectid
=
inode
->
i_ino
;
key
.
offset
=
offset
;
btrfs_set_key_type
(
&
key
,
BTRFS_EXTENT_DATA_KEY
);
BUG_ON
(
size
>=
PAGE_CACHE_SIZE
);
datasize
=
btrfs_file_extent_calc_inline_size
(
size
);
datasize
=
btrfs_file_extent_calc_inline_size
(
offset
+
size
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
0
,
1
);
if
(
ret
<
0
)
{
err
=
ret
;
goto
fail
;
}
if
(
ret
==
1
)
{
path
->
slots
[
0
]
--
;
leaf
=
path
->
nodes
[
0
];
ei
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
if
(
btrfs_file_extent_type
(
leaf
,
ei
)
!=
BTRFS_FILE_EXTENT_INLINE
)
{
goto
insert
;
}
btrfs_item_key_to_cpu
(
leaf
,
&
key
,
path
->
slots
[
0
]);
ret
=
0
;
}
if
(
ret
==
0
)
{
u32
found_size
;
u64
found_start
;
leaf
=
path
->
nodes
[
0
];
ei
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
if
(
btrfs_file_extent_type
(
leaf
,
ei
)
!=
BTRFS_FILE_EXTENT_INLINE
)
{
err
=
ret
;
btrfs_print_leaf
(
root
,
leaf
);
printk
(
"found wasn't inline offset %Lu inode %lu
\n
"
,
offset
,
inode
->
i_ino
);
goto
fail
;
}
found_start
=
key
.
offset
;
found_size
=
btrfs_file_extent_inline_len
(
leaf
,
btrfs_item_nr
(
leaf
,
path
->
slots
[
0
]));
if
(
found_size
<
offset
+
size
)
{
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
offset
+
size
-
found_size
-
found_start
,
1
);
BUG_ON
(
ret
!=
0
);
ret
=
btrfs_extend_item
(
trans
,
root
,
path
,
offset
+
size
-
found_size
-
found_start
);
if
(
ret
)
{
err
=
ret
;
goto
fail
;
}
leaf
=
path
->
nodes
[
0
];
ei
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
}
}
else
{
insert:
btrfs_release_path
(
root
,
path
);
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
key
,
datasize
);
if
(
ret
)
{
err
=
ret
;
printk
(
"got bad ret %d
\n
"
,
ret
);
goto
fail
;
}
leaf
=
path
->
nodes
[
0
];
...
...
@@ -118,11 +180,25 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
struct
btrfs_file_extent_item
);
btrfs_set_file_extent_generation
(
leaf
,
ei
,
trans
->
transid
);
btrfs_set_file_extent_type
(
leaf
,
ei
,
BTRFS_FILE_EXTENT_INLINE
);
ptr
=
btrfs_file_extent_inline_start
(
ei
);
}
ptr
=
btrfs_file_extent_inline_start
(
ei
)
+
offset
;
kaddr
=
kmap_atomic
(
page
,
KM_USER1
);
write_extent_buffer
(
leaf
,
kaddr
+
page_offset
,
ptr
,
size
);
kunmap_atomic
(
kaddr
,
KM_USER1
);
cur_size
=
size
;
i
=
0
;
while
(
size
>
0
)
{
page
=
pages
[
i
];
kaddr
=
kmap_atomic
(
page
,
KM_USER0
);
cur_size
=
min
(
PAGE_CACHE_SIZE
-
page_offset
,
size
);
write_extent_buffer
(
leaf
,
kaddr
+
page_offset
,
ptr
,
cur_size
);
kunmap_atomic
(
kaddr
,
KM_USER0
);
page_offset
=
0
;
ptr
+=
cur_size
;
size
-=
cur_size
;
if
(
i
>=
num_pages
)
{
printk
(
"i %d num_pages %d
\n
"
,
i
,
num_pages
);
}
i
++
;
}
btrfs_mark_buffer_dirty
(
leaf
);
fail:
btrfs_free_path
(
path
);
...
...
@@ -193,6 +269,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
err
=
btrfs_drop_extents
(
trans
,
root
,
inode
,
last_pos_in_file
,
last_pos_in_file
+
hole_size
,
last_pos_in_file
,
&
hint_byte
);
if
(
err
)
goto
failed
;
...
...
@@ -210,11 +287,12 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
* either allocate an extent for the new bytes or setup the key
* to show we are doing inline data in the extent
*/
inline_size
=
end_pos
-
start_pos
;
if
(
isize
>=
PAGE_CACHE_SIZE
||
pos
+
write_bytes
<
inode
->
i_size
||
inline_size
>
=
BTRFS_MAX_INLINE_DATA_SIZE
(
root
)
||
inline_size
>=
PAGE_CACHE_SIZE
)
{
inline_size
=
end_pos
;
if
(
isize
>=
BTRFS_MAX_INLINE_DATA_SIZE
(
root
)
||
inline_size
>
16384
||
inline_size
>=
BTRFS_MAX_INLINE_DATA_SIZE
(
root
)
)
{
u64
last_end
;
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
{
struct
page
*
p
=
pages
[
i
];
SetPageUptodate
(
p
);
...
...
@@ -225,22 +303,18 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
set_extent_delalloc
(
em_tree
,
start_pos
,
end_of_last_block
,
GFP_NOFS
);
}
else
{
struct
page
*
p
=
pages
[
0
]
;
u64
aligned_end
;
/* step one, delete the existing extents in this range */
aligned_end
=
(
pos
+
write_bytes
+
root
->
sectorsize
-
1
)
&
~
((
u64
)
root
->
sectorsize
-
1
);
err
=
btrfs_drop_extents
(
trans
,
root
,
inode
,
start_pos
,
(
pos
+
write_bytes
+
root
->
sectorsize
-
1
)
&
~
((
u64
)
root
->
sectorsize
-
1
),
&
hint_byte
);
aligned_end
,
end_pos
,
&
hint_byte
);
if
(
err
)
goto
failed
;
err
=
insert_inline_extent
(
trans
,
root
,
inode
,
start_pos
,
end_pos
-
start_pos
,
p
,
0
);
end_pos
-
start_pos
,
pages
,
0
,
num_pages
);
BUG_ON
(
err
);
em
->
start
=
start_pos
;
em
->
end
=
end_pos
-
1
;
em
->
block_start
=
EXTENT_MAP_INLINE
;
em
->
block_end
=
EXTENT_MAP_INLINE
;
add_extent_mapping
(
em_tree
,
em
);
}
if
(
end_pos
>
isize
)
{
i_size_write
(
inode
,
end_pos
);
...
...
@@ -285,7 +359,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
*/
int
btrfs_drop_extents
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
inode
*
inode
,
u64
start
,
u64
end
,
u64
*
hint_byte
)
u64
start
,
u64
end
,
u64
inline_end
,
u64
*
hint_byte
)
{
int
ret
;
struct
btrfs_key
key
;
...
...
@@ -401,7 +475,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
BUG_ON
(
ret
);
}
}
WARN_ON
(
found_inline
);
if
(
!
found_inline
)
bookend
=
1
;
}
/* truncate existing extent */
...
...
@@ -425,8 +499,14 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
btrfs_set_file_extent_num_bytes
(
leaf
,
extent
,
new_num
);
btrfs_mark_buffer_dirty
(
leaf
);
}
else
{
WARN_ON
(
1
);
}
else
if
(
end
>
extent_end
&&
key
.
offset
<
inline_end
&&
inline_end
<
extent_end
)
{
u32
new_size
;
new_size
=
btrfs_file_extent_calc_inline_size
(
inline_end
-
key
.
offset
);
btrfs_truncate_item
(
trans
,
root
,
path
,
new_size
);
}
}
/* delete the entire extent */
...
...
fs/btrfs/inode.c
浏览文件 @
3326d1b0
...
...
@@ -87,7 +87,7 @@ static int run_delalloc_range(struct inode *inode, u64 start, u64 end)
BUG_ON
(
!
trans
);
num_bytes
=
(
end
-
start
+
blocksize
)
&
~
(
blocksize
-
1
);
ret
=
btrfs_drop_extents
(
trans
,
root
,
inode
,
start
,
start
+
num_bytes
,
&
alloc_hint
);
start
,
start
+
num_bytes
,
start
,
&
alloc_hint
);
ret
=
btrfs_alloc_extent
(
trans
,
root
,
inode
->
i_ino
,
num_bytes
,
0
,
alloc_hint
,
(
u64
)
-
1
,
&
ins
,
1
);
...
...
@@ -776,7 +776,8 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_drop_extents
(
trans
,
root
,
inode
,
pos
,
pos
+
hole_size
,
&
alloc_hint
);
pos
,
pos
+
hole_size
,
pos
,
&
alloc_hint
);
err
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
pos
,
0
,
0
,
hole_size
);
...
...
@@ -1581,7 +1582,9 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
}
else
if
(
found_type
==
BTRFS_FILE_EXTENT_INLINE
)
{
unsigned
long
ptr
;
char
*
map
;
u32
size
;
size_t
size
;
size_t
extent_offset
;
size_t
copy_size
;
size
=
btrfs_file_extent_inline_len
(
leaf
,
btrfs_item_nr
(
leaf
,
path
->
slots
[
0
]));
...
...
@@ -1600,26 +1603,31 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
goto
not_found_em
;
}
extent_offset
=
(
page
->
index
<<
PAGE_CACHE_SHIFT
)
-
extent_start
;
ptr
=
btrfs_file_extent_inline_start
(
item
)
+
extent_offset
;
map
=
kmap
(
page
);
copy_size
=
min
(
PAGE_CACHE_SIZE
-
page_offset
,
size
-
extent_offset
);
em
->
block_start
=
EXTENT_MAP_INLINE
;
em
->
block_end
=
EXTENT_MAP_INLINE
;
em
->
start
=
extent_start
;
em
->
end
=
extent_end
;
em
->
start
=
extent_start
+
extent_offset
;
em
->
end
=
(
em
->
start
+
copy_size
-
1
)
|
((
u64
)
root
->
sectorsize
-
1
);
if
(
!
page
)
{
goto
insert
;
}
ptr
=
btrfs_file_extent_inline_start
(
item
);
map
=
kmap
(
page
);
read_extent_buffer
(
leaf
,
map
+
page_offset
,
ptr
,
size
);
read_extent_buffer
(
leaf
,
map
+
page_offset
,
ptr
,
copy_size
);
/*
memset(map + page_offset + size, 0,
root->sectorsize - (page_offset + size)
);
memset(map + page_offset +
copy_
size, 0,
PAGE_CACHE_SIZE - copy_size - page_offset
);
*/
flush_dcache_page
(
page
);
kunmap
(
page
);
set_extent_uptodate
(
em_tree
,
extent_start
,
extent_end
,
GFP_NOFS
);
set_extent_uptodate
(
em_tree
,
em
->
start
,
em
->
end
,
GFP_NOFS
);
goto
insert
;
}
else
{
printk
(
"unkknown found_type %d
\n
"
,
found_type
);
...
...
fs/btrfs/super.c
浏览文件 @
3326d1b0
...
...
@@ -280,7 +280,6 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type,
error_bdev:
close_bdev_excl
(
bdev
);
error:
printk
(
"get_sb failed
\n
"
);
return
error
;
}
/* end copy & paste */
...
...
@@ -295,7 +294,6 @@ static int btrfs_get_sb(struct file_system_type *fs_type,
ret
=
btrfs_get_sb_bdev
(
fs_type
,
flags
,
dev_name
,
data
,
btrfs_fill_super
,
mnt
,
subvol_name
?
subvol_name
:
"default"
);
printk
(
"btrfs_get_sb returns %d
\n
"
,
ret
);
return
ret
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录