Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
df24a2b9
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,发现更多精彩内容 >>
提交
df24a2b9
编写于
4月 04, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
4月 04, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: early inline file data code
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
9d64272c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
248 addition
and
10 deletion
+248
-10
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+12
-6
fs/btrfs/super.c
fs/btrfs/super.c
+236
-4
未找到文件。
fs/btrfs/ctree.c
浏览文件 @
df24a2b9
...
...
@@ -16,19 +16,24 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct
static
int
del_ptr
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
int
level
,
int
slot
);
struct
btrfs_path
*
btrfs_alloc_path
(
void
)
inline
void
btrfs_init_path
(
struct
btrfs_path
*
p
)
{
return
kmem_cache_alloc
(
btrfs_path_cachep
,
GFP_NOFS
);
memset
(
p
,
0
,
sizeof
(
*
p
)
);
}
void
btrfs_free_path
(
struct
btrfs_path
*
p
)
struct
btrfs_path
*
btrfs_alloc_path
(
void
)
{
kmem_cache_free
(
btrfs_path_cachep
,
p
);
struct
btrfs_path
*
path
;
path
=
kmem_cache_alloc
(
btrfs_path_cachep
,
GFP_NOFS
);
if
(
path
)
btrfs_init_path
(
path
);
return
path
;
}
inline
void
btrfs_init
_path
(
struct
btrfs_path
*
p
)
void
btrfs_free
_path
(
struct
btrfs_path
*
p
)
{
memset
(
p
,
0
,
sizeof
(
*
p
));
btrfs_release_path
(
NULL
,
p
);
kmem_cache_free
(
btrfs_path_cachep
,
p
);
}
void
btrfs_release_path
(
struct
btrfs_root
*
root
,
struct
btrfs_path
*
p
)
...
...
@@ -77,6 +82,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_free_extent
(
trans
,
root
,
buf
->
b_blocknr
,
1
,
1
);
}
btrfs_block_release
(
root
,
buf
);
mark_buffer_dirty
(
cow
);
*
cow_ret
=
cow
;
return
0
;
}
...
...
fs/btrfs/super.c
浏览文件 @
df24a2b9
...
...
@@ -816,6 +816,73 @@ printk("btrfs sync_fs\n");
return
0
;
}
static
int
btrfs_get_block_inline
(
struct
inode
*
inode
,
sector_t
iblock
,
struct
buffer_head
*
result
,
int
create
)
{
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
);
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
struct
btrfs_leaf
*
leaf
;
int
num_bytes
=
result
->
b_size
;
int
item_size
;
int
ret
;
u64
pos
;
char
*
ptr
;
int
copy_size
;
int
err
=
0
;
char
*
safe_ptr
;
char
*
data_ptr
;
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
WARN_ON
(
create
);
if
(
create
)
{
return
0
;
}
pos
=
iblock
<<
inode
->
i_blkbits
;
key
.
objectid
=
inode
->
i_ino
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INLINE_DATA_KEY
);
ptr
=
kmap
(
result
->
b_page
);
safe_ptr
=
ptr
;
ptr
+=
(
pos
&
(
PAGE_CACHE_SIZE
-
1
));
again:
key
.
offset
=
pos
;
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
key
,
path
,
0
,
0
);
if
(
ret
)
{
if
(
ret
<
0
)
err
=
ret
;
else
err
=
0
;
goto
out
;
}
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
item_size
=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
]);
copy_size
=
min
(
num_bytes
,
item_size
);
data_ptr
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
char
);
WARN_ON
(
safe_ptr
+
PAGE_CACHE_SIZE
<
ptr
+
copy_size
);
memcpy
(
ptr
,
data_ptr
,
copy_size
);
pos
+=
copy_size
;
num_bytes
-=
copy_size
;
WARN_ON
(
num_bytes
<
0
);
ptr
+=
copy_size
;
btrfs_release_path
(
root
,
path
);
if
(
num_bytes
!=
0
)
{
if
(
pos
>=
i_size_read
(
inode
))
memset
(
ptr
,
0
,
num_bytes
);
else
goto
again
;
}
set_buffer_uptodate
(
result
);
map_bh
(
result
,
inode
->
i_sb
,
0
);
err
=
0
;
out:
btrfs_free_path
(
path
);
kunmap
(
result
->
b_page
);
return
err
;
}
static
int
btrfs_get_block_lock
(
struct
inode
*
inode
,
sector_t
iblock
,
struct
buffer_head
*
result
,
int
create
)
{
...
...
@@ -918,7 +985,8 @@ static int btrfs_get_block(struct inode *inode, sector_t iblock,
int
err
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
err
=
btrfs_get_block_lock
(
inode
,
iblock
,
result
,
create
);
// err = btrfs_get_block_lock(inode, iblock, result, create);
err
=
btrfs_get_block_inline
(
inode
,
iblock
,
result
,
create
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
err
;
}
...
...
@@ -1177,6 +1245,170 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
return
num_written
?
num_written
:
err
;
}
static
ssize_t
inline_one_page
(
struct
btrfs_root
*
root
,
struct
inode
*
inode
,
struct
page
*
page
,
loff_t
pos
,
size_t
offset
,
size_t
write_bytes
)
{
struct
btrfs_path
*
path
;
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_key
key
;
struct
btrfs_leaf
*
leaf
;
struct
btrfs_key
found_key
;
int
ret
;
size_t
copy_size
=
0
;
char
*
dst
=
NULL
;
int
err
=
0
;
size_t
num_written
=
0
;
path
=
btrfs_alloc_path
();
BUG_ON
(
!
path
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
key
.
objectid
=
inode
->
i_ino
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INLINE_DATA_KEY
);
again:
key
.
offset
=
pos
;
ret
=
btrfs_search_slot
(
trans
,
root
,
&
key
,
path
,
0
,
1
);
if
(
ret
<
0
)
{
err
=
ret
;
goto
out
;
}
if
(
ret
==
0
)
{
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
btrfs_disk_key_to_cpu
(
&
found_key
,
&
leaf
->
items
[
path
->
slots
[
0
]].
key
);
copy_size
=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
]);
dst
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
char
);
copy_size
=
min
(
write_bytes
,
copy_size
);
goto
copyit
;
}
else
{
int
slot
=
path
->
slots
[
0
];
if
(
slot
>
0
)
{
slot
--
;
}
// FIXME find max key
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
btrfs_disk_key_to_cpu
(
&
found_key
,
&
leaf
->
items
[
slot
].
key
);
if
(
found_key
.
objectid
!=
inode
->
i_ino
)
goto
insert
;
if
(
btrfs_key_type
(
&
found_key
)
!=
BTRFS_INLINE_DATA_KEY
)
goto
insert
;
copy_size
=
btrfs_item_size
(
leaf
->
items
+
slot
);
if
(
found_key
.
offset
+
copy_size
<=
pos
)
goto
insert
;
dst
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
char
);
dst
+=
pos
-
found_key
.
offset
;
copy_size
=
copy_size
-
(
pos
-
found_key
.
offset
);
BUG_ON
(
copy_size
<
0
);
copy_size
=
min
(
write_bytes
,
copy_size
);
WARN_ON
(
copy_size
==
0
);
goto
copyit
;
}
insert:
btrfs_release_path
(
root
,
path
);
copy_size
=
min
(
write_bytes
,
(
size_t
)
512
);
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
path
,
&
key
,
copy_size
);
BUG_ON
(
ret
);
dst
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
char
);
copyit:
WARN_ON
(
copy_size
==
0
);
WARN_ON
(
dst
+
copy_size
>
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
char
)
+
btrfs_item_size
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
])
->
items
+
path
->
slots
[
0
]));
btrfs_memcpy
(
root
,
path
->
nodes
[
0
]
->
b_data
,
dst
,
page_address
(
page
)
+
offset
,
copy_size
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_release_path
(
root
,
path
);
pos
+=
copy_size
;
offset
+=
copy_size
;
num_written
+=
copy_size
;
write_bytes
-=
copy_size
;
if
(
write_bytes
)
goto
again
;
out:
btrfs_free_path
(
path
);
ret
=
btrfs_end_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
num_written
?
num_written
:
err
;
}
static
ssize_t
btrfs_file_inline_write
(
struct
file
*
file
,
const
char
__user
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
loff_t
pos
;
size_t
num_written
=
0
;
int
err
=
0
;
int
ret
=
0
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
btrfs_root
*
root
=
btrfs_sb
(
inode
->
i_sb
);
unsigned
long
page_index
;
if
(
file
->
f_flags
&
O_DIRECT
)
return
-
EINVAL
;
pos
=
*
ppos
;
vfs_check_frozen
(
inode
->
i_sb
,
SB_FREEZE_WRITE
);
current
->
backing_dev_info
=
inode
->
i_mapping
->
backing_dev_info
;
err
=
generic_write_checks
(
file
,
&
pos
,
&
count
,
S_ISBLK
(
inode
->
i_mode
));
if
(
err
)
goto
out
;
if
(
count
==
0
)
goto
out
;
err
=
remove_suid
(
file
->
f_path
.
dentry
);
if
(
err
)
goto
out
;
file_update_time
(
file
);
mutex_lock
(
&
inode
->
i_mutex
);
while
(
count
>
0
)
{
size_t
offset
=
pos
&
(
PAGE_CACHE_SIZE
-
1
);
size_t
write_bytes
=
min
(
count
,
PAGE_CACHE_SIZE
-
offset
);
struct
page
*
page
;
page_index
=
pos
>>
PAGE_CACHE_SHIFT
;
page
=
grab_cache_page
(
inode
->
i_mapping
,
page_index
);
if
(
!
PageUptodate
(
page
))
{
ret
=
mpage_readpage
(
page
,
btrfs_get_block
);
BUG_ON
(
ret
);
lock_page
(
page
);
}
ret
=
btrfs_copy_from_user
(
pos
,
1
,
write_bytes
,
&
page
,
buf
);
BUG_ON
(
ret
);
write_bytes
=
inline_one_page
(
root
,
inode
,
page
,
pos
,
offset
,
write_bytes
);
SetPageUptodate
(
page
);
if
(
write_bytes
>
0
&&
pos
+
write_bytes
>
inode
->
i_size
)
{
i_size_write
(
inode
,
pos
+
write_bytes
);
mark_inode_dirty
(
inode
);
}
page_cache_release
(
page
);
unlock_page
(
page
);
if
(
write_bytes
<
0
)
goto
out_unlock
;
buf
+=
write_bytes
;
count
-=
write_bytes
;
pos
+=
write_bytes
;
num_written
+=
write_bytes
;
balance_dirty_pages_ratelimited
(
inode
->
i_mapping
);
cond_resched
();
}
out_unlock:
mutex_unlock
(
&
inode
->
i_mutex
);
out:
*
ppos
=
pos
;
current
->
backing_dev_info
=
NULL
;
return
num_written
?
num_written
:
err
;
}
static
int
btrfs_read_actor
(
read_descriptor_t
*
desc
,
struct
page
*
page
,
unsigned
long
offset
,
unsigned
long
size
)
{
...
...
@@ -1420,7 +1652,7 @@ static struct file_operations btrfs_dir_file_operations = {
static
struct
address_space_operations
btrfs_aops
=
{
.
readpage
=
btrfs_readpage
,
.
readpages
=
btrfs_readpages
,
//
.readpages = btrfs_readpages,
.
writepage
=
btrfs_writepage
,
.
sync_page
=
block_sync_page
,
.
prepare_write
=
btrfs_prepare_write
,
...
...
@@ -1434,8 +1666,8 @@ static struct inode_operations btrfs_file_inode_operations = {
static
struct
file_operations
btrfs_file_operations
=
{
.
llseek
=
generic_file_llseek
,
.
read
=
do_sync_read
,
.
aio_read
=
btrfs
_file_aio_read
,
.
write
=
btrfs_file_write
,
.
aio_read
=
generic
_file_aio_read
,
.
write
=
btrfs_file_
inline_
write
,
.
mmap
=
generic_file_mmap
,
.
open
=
generic_file_open
,
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录