Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
f2eb0a24
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看板
提交
f2eb0a24
编写于
5月 02, 2008
作者:
S
Sage Weil
提交者:
Chris Mason
9月 25, 2008
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Clone file data ioctl
Add a new ioctl to clone file data Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
d6bfde87
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
179 addition
and
11 deletion
+179
-11
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+2
-2
fs/btrfs/file-item.c
fs/btrfs/file-item.c
+6
-6
fs/btrfs/file.c
fs/btrfs/file.c
+1
-1
fs/btrfs/inode.c
fs/btrfs/inode.c
+169
-2
fs/btrfs/ioctl.h
fs/btrfs/ioctl.h
+1
-0
未找到文件。
fs/btrfs/ctree.h
浏览文件 @
f2eb0a24
...
...
@@ -1516,9 +1516,9 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
/* file-item.c */
int
btrfs_insert_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
pos
,
u64
offset
,
u64
objectid
,
u64
pos
,
u64
disk_
offset
,
u64
disk_num_bytes
,
u64
num_bytes
);
u64
num_bytes
,
u64
offset
);
int
btrfs_lookup_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
u64
objectid
,
...
...
fs/btrfs/file-item.c
浏览文件 @
f2eb0a24
...
...
@@ -28,10 +28,10 @@
sizeof(struct btrfs_item) * 2) / \
BTRFS_CRC32_SIZE) - 1))
int
btrfs_insert_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
pos
,
u64
offset
,
u64
disk_num_bytes
,
u64
num_bytes
)
struct
btrfs_root
*
root
,
u64
objectid
,
u64
pos
,
u64
disk_
offset
,
u64
disk_num_bytes
,
u64
num_bytes
,
u64
offset
)
{
int
ret
=
0
;
struct
btrfs_file_extent_item
*
item
;
...
...
@@ -53,9 +53,9 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
leaf
=
path
->
nodes
[
0
];
item
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
btrfs_set_file_extent_disk_bytenr
(
leaf
,
item
,
offset
);
btrfs_set_file_extent_disk_bytenr
(
leaf
,
item
,
disk_
offset
);
btrfs_set_file_extent_disk_num_bytes
(
leaf
,
item
,
disk_num_bytes
);
btrfs_set_file_extent_offset
(
leaf
,
item
,
0
);
btrfs_set_file_extent_offset
(
leaf
,
item
,
offset
);
btrfs_set_file_extent_num_bytes
(
leaf
,
item
,
num_bytes
);
btrfs_set_file_extent_generation
(
leaf
,
item
,
trans
->
transid
);
btrfs_set_file_extent_type
(
leaf
,
item
,
BTRFS_FILE_EXTENT_REG
);
...
...
fs/btrfs/file.c
浏览文件 @
f2eb0a24
...
...
@@ -285,7 +285,7 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
err
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
last_pos_in_file
,
0
,
0
,
hole_size
);
0
,
0
,
hole_size
,
0
);
btrfs_drop_extent_cache
(
inode
,
last_pos_in_file
,
last_pos_in_file
+
hole_size
-
1
);
btrfs_check_file
(
root
,
inode
);
...
...
fs/btrfs/inode.c
浏览文件 @
f2eb0a24
...
...
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/bio.h>
#include <linux/buffer_head.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
...
...
@@ -141,7 +142,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
cur_alloc_size
=
ins
.
offset
;
ret
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
start
,
ins
.
objectid
,
ins
.
offset
,
ins
.
offset
);
ins
.
offset
,
0
);
inode
->
i_blocks
+=
ins
.
offset
>>
9
;
btrfs_check_file
(
root
,
inode
);
if
(
num_bytes
<
cur_alloc_size
)
{
...
...
@@ -1227,7 +1228,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
err
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
hole_start
,
0
,
0
,
hole_size
);
hole_size
,
0
);
btrfs_drop_extent_cache
(
inode
,
hole_start
,
(
u64
)
-
1
);
btrfs_check_file
(
root
,
inode
);
...
...
@@ -3100,6 +3101,170 @@ long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
return
ret
;
}
void
dup_item_to_inode
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
extent_buffer
*
leaf
,
int
slot
,
struct
btrfs_key
*
key
,
u64
destino
)
{
struct
btrfs_path
*
cpath
=
btrfs_alloc_path
();
int
len
=
btrfs_item_size_nr
(
leaf
,
slot
);
int
dstoff
;
struct
btrfs_key
ckey
=
*
key
;
int
ret
;
ckey
.
objectid
=
destino
;
ret
=
btrfs_insert_empty_item
(
trans
,
root
,
cpath
,
&
ckey
,
len
);
dstoff
=
btrfs_item_ptr_offset
(
cpath
->
nodes
[
0
],
cpath
->
slots
[
0
]);
copy_extent_buffer
(
cpath
->
nodes
[
0
],
leaf
,
dstoff
,
btrfs_item_ptr_offset
(
leaf
,
slot
),
len
);
btrfs_release_path
(
root
,
cpath
);
}
long
btrfs_ioctl_clone
(
struct
file
*
file
,
unsigned
long
src_fd
)
{
struct
inode
*
inode
=
fdentry
(
file
)
->
d_inode
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
file
*
src_file
;
struct
inode
*
src
;
struct
btrfs_trans_handle
*
trans
;
int
ret
;
u64
pos
;
struct
btrfs_path
*
path
;
struct
btrfs_key
key
;
struct
extent_buffer
*
leaf
;
u32
nritems
;
int
nextret
;
int
slot
;
src_file
=
fget
(
src_fd
);
if
(
!
src_file
)
return
-
EBADF
;
src
=
src_file
->
f_dentry
->
d_inode
;
ret
=
-
EXDEV
;
if
(
src
->
i_sb
!=
inode
->
i_sb
)
goto
out_fput
;
if
(
inode
<
src
)
{
mutex_lock
(
&
inode
->
i_mutex
);
mutex_lock
(
&
src
->
i_mutex
);
}
else
{
mutex_lock
(
&
src
->
i_mutex
);
mutex_lock
(
&
inode
->
i_mutex
);
}
ret
=
-
ENOTEMPTY
;
if
(
inode
->
i_size
)
goto
out_unlock
;
/* do any pending delalloc/csum calc on src, one way or
another, and lock file content */
while
(
1
)
{
filemap_write_and_wait
(
src
->
i_mapping
);
lock_extent
(
&
BTRFS_I
(
src
)
->
io_tree
,
0
,
(
u64
)
-
1
,
GFP_NOFS
);
if
(
BTRFS_I
(
src
)
->
delalloc_bytes
==
0
)
break
;
unlock_extent
(
&
BTRFS_I
(
src
)
->
io_tree
,
0
,
(
u64
)
-
1
,
GFP_NOFS
);
}
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
0
);
path
=
btrfs_alloc_path
();
pos
=
0
;
while
(
1
)
{
ret
=
btrfs_lookup_file_extent
(
trans
,
root
,
path
,
src
->
i_ino
,
pos
,
0
);
if
(
ret
<
0
)
goto
out
;
if
(
ret
>
0
)
{
if
(
path
->
slots
[
0
]
==
0
)
{
ret
=
0
;
goto
out
;
}
path
->
slots
[
0
]
--
;
}
next_slot:
leaf
=
path
->
nodes
[
0
];
slot
=
path
->
slots
[
0
];
btrfs_item_key_to_cpu
(
leaf
,
&
key
,
slot
);
nritems
=
btrfs_header_nritems
(
leaf
);
if
(
btrfs_key_type
(
&
key
)
>
BTRFS_CSUM_ITEM_KEY
||
key
.
objectid
!=
src
->
i_ino
)
goto
out
;
if
(
btrfs_key_type
(
&
key
)
==
BTRFS_EXTENT_DATA_KEY
)
{
struct
btrfs_file_extent_item
*
extent
;
int
found_type
;
pos
=
key
.
offset
;
extent
=
btrfs_item_ptr
(
leaf
,
slot
,
struct
btrfs_file_extent_item
);
found_type
=
btrfs_file_extent_type
(
leaf
,
extent
);
if
(
found_type
==
BTRFS_FILE_EXTENT_REG
)
{
u64
len
=
btrfs_file_extent_num_bytes
(
leaf
,
extent
);
u64
ds
=
btrfs_file_extent_disk_bytenr
(
leaf
,
extent
);
u64
dl
=
btrfs_file_extent_disk_num_bytes
(
leaf
,
extent
);
u64
off
=
btrfs_file_extent_offset
(
leaf
,
extent
);
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
pos
,
ds
,
dl
,
len
,
off
);
/* ds == 0 means there's a hole */
if
(
ds
!=
0
)
{
btrfs_inc_extent_ref
(
trans
,
root
,
ds
,
dl
,
root
->
root_key
.
objectid
,
trans
->
transid
,
inode
->
i_ino
,
pos
);
}
pos
=
key
.
offset
+
len
;
}
else
if
(
found_type
==
BTRFS_FILE_EXTENT_INLINE
)
{
dup_item_to_inode
(
trans
,
root
,
path
,
leaf
,
slot
,
&
key
,
inode
->
i_ino
);
pos
=
key
.
offset
+
btrfs_item_size_nr
(
leaf
,
slot
);
}
}
else
if
(
btrfs_key_type
(
&
key
)
==
BTRFS_CSUM_ITEM_KEY
)
dup_item_to_inode
(
trans
,
root
,
path
,
leaf
,
slot
,
&
key
,
inode
->
i_ino
);
if
(
slot
>=
nritems
-
1
)
{
nextret
=
btrfs_next_leaf
(
root
,
path
);
if
(
nextret
)
goto
out
;
}
else
{
path
->
slots
[
0
]
++
;
}
goto
next_slot
;
}
out:
btrfs_free_path
(
path
);
ret
=
0
;
inode
->
i_blocks
=
src
->
i_blocks
;
i_size_write
(
inode
,
src
->
i_size
);
btrfs_update_inode
(
trans
,
root
,
inode
);
unlock_extent
(
&
BTRFS_I
(
src
)
->
io_tree
,
0
,
(
u64
)
-
1
,
GFP_NOFS
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
out_unlock:
mutex_unlock
(
&
src
->
i_mutex
);
mutex_unlock
(
&
inode
->
i_mutex
);
out_fput:
fput
(
src_file
);
return
ret
;
}
long
btrfs_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
...
...
@@ -3116,6 +3281,8 @@ long btrfs_ioctl(struct file *file, unsigned int
return
btrfs_ioctl_add_dev
(
root
,
(
void
__user
*
)
arg
);
case
BTRFS_IOC_BALANCE
:
return
btrfs_balance
(
root
->
fs_info
->
dev_root
);
case
BTRFS_IOC_CLONE
:
return
btrfs_ioctl_clone
(
file
,
arg
);
}
return
-
ENOTTY
;
...
...
fs/btrfs/ioctl.h
浏览文件 @
f2eb0a24
...
...
@@ -36,6 +36,7 @@ struct btrfs_ioctl_vol_args {
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int)
#define BTRFS_IOC_ADD_DEV _IOW(BTRFS_IOCTL_MAGIC, 10, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_RM_DEV _IOW(BTRFS_IOCTL_MAGIC, 11, \
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录