Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
2619ba1f
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
2619ba1f
编写于
4月 10, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
4月 10, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: subvolumes
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
2932f3ec
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
182 addition
and
43 deletion
+182
-43
fs/btrfs/TODO
fs/btrfs/TODO
+1
-0
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+24
-14
fs/btrfs/super.c
fs/btrfs/super.c
+152
-26
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+5
-3
未找到文件。
fs/btrfs/TODO
浏览文件 @
2619ba1f
...
...
@@ -8,6 +8,7 @@
* Check compat and incompat flags on the inode
* Add virtual filesystems, mountable snapshots
* Get rid of struct ctree_path, limiting tree levels held at one time
* EEXIST for dirs instead of hash overflow
* Release
* Do real tree locking
* Add extent mirroring (backup copies of blocks)
...
...
fs/btrfs/disk-io.c
浏览文件 @
2619ba1f
...
...
@@ -301,6 +301,12 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
int
ret
=
0
;
printk
(
"read_fs_root looking for %Lu %Lu %u
\n
"
,
location
->
objectid
,
location
->
offset
,
location
->
flags
);
root
=
radix_tree_lookup
(
&
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
location
->
objectid
);
if
(
root
)
{
printk
(
"found %p in cache
\n
"
,
root
);
return
root
;
}
root
=
kmalloc
(
sizeof
(
*
root
),
GFP_NOFS
);
if
(
!
root
)
{
printk
(
"failed1
\n
"
);
...
...
@@ -349,7 +355,8 @@ printk("internal search_slot gives us %d\n", ret);
insert:
printk
(
"inserting %p
\n
"
,
root
);
root
->
ref_cows
=
1
;
ret
=
radix_tree_insert
(
&
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
root
,
ret
=
radix_tree_insert
(
&
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
root
->
root_key
.
objectid
,
root
);
if
(
ret
)
{
printk
(
"radix_tree_insert gives us %d
\n
"
,
ret
);
...
...
@@ -460,6 +467,20 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
return
0
;
}
static
int
free_fs_root
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_root
*
root
)
{
radix_tree_delete
(
&
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
root
->
root_key
.
objectid
);
if
(
root
->
inode
)
iput
(
root
->
inode
);
if
(
root
->
node
)
brelse
(
root
->
node
);
if
(
root
->
commit_root
)
brelse
(
root
->
commit_root
);
kfree
(
root
);
return
0
;
}
int
del_fs_roots
(
struct
btrfs_fs_info
*
fs_info
)
{
int
ret
;
...
...
@@ -472,19 +493,8 @@ int del_fs_roots(struct btrfs_fs_info *fs_info)
ARRAY_SIZE
(
gang
));
if
(
!
ret
)
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
radix_tree_delete
(
&
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
gang
[
i
]);
if
(
gang
[
i
]
->
inode
)
iput
(
gang
[
i
]
->
inode
);
else
printk
(
"no inode for root %p
\n
"
,
gang
[
i
]);
if
(
gang
[
i
]
->
node
)
brelse
(
gang
[
i
]
->
node
);
if
(
gang
[
i
]
->
commit_root
)
brelse
(
gang
[
i
]
->
commit_root
);
kfree
(
gang
[
i
]);
}
for
(
i
=
0
;
i
<
ret
;
i
++
)
free_fs_root
(
fs_info
,
gang
[
i
]);
}
return
0
;
}
...
...
fs/btrfs/super.c
浏览文件 @
2619ba1f
...
...
@@ -495,10 +495,6 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
return
ERR_PTR
(
-
EACCES
);
if
(
inode
->
i_state
&
I_NEW
)
{
if
(
sub_root
!=
root
)
{
ret
=
radix_tree_insert
(
&
root
->
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
sub_root
,
sub_root
);
printk
(
"adding new root for inode %lu root %p (found %p)
\n
"
,
inode
->
i_ino
,
sub_root
,
BTRFS_I
(
inode
)
->
root
);
igrab
(
inode
);
sub_root
->
inode
=
inode
;
...
...
@@ -723,22 +719,19 @@ static int btrfs_write_inode(struct inode *inode, int wait)
}
static
struct
inode
*
btrfs_new_inode
(
struct
btrfs_trans_handle
*
trans
,
struct
inode
*
dir
,
int
mode
)
struct
btrfs_root
*
root
,
u64
objectid
,
int
mode
)
{
struct
inode
*
inode
;
struct
btrfs_inode_item
inode_item
;
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
struct
btrfs_key
*
location
;
int
ret
;
u64
objectid
;
inode
=
new_inode
(
dir
->
i_
sb
);
inode
=
new_inode
(
root
->
fs_info
->
sb
);
if
(
!
inode
)
return
ERR_PTR
(
-
ENOMEM
);
BTRFS_I
(
inode
)
->
root
=
BTRFS_I
(
dir
)
->
root
;
ret
=
btrfs_find_free_objectid
(
trans
,
root
,
dir
->
i_ino
,
&
objectid
);
BUG_ON
(
ret
);
BTRFS_I
(
inode
)
->
root
=
root
;
inode
->
i_uid
=
current
->
fsuid
;
inode
->
i_gid
=
current
->
fsgid
;
...
...
@@ -804,10 +797,18 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
struct
inode
*
inode
;
int
err
;
int
drop_inode
=
0
;
u64
objectid
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
inode
=
btrfs_new_inode
(
trans
,
dir
,
mode
);
err
=
btrfs_find_free_objectid
(
trans
,
root
,
dir
->
i_ino
,
&
objectid
);
if
(
err
)
{
err
=
-
ENOSPC
;
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
mode
);
err
=
PTR_ERR
(
inode
);
if
(
IS_ERR
(
inode
))
goto
out_unlock
;
...
...
@@ -833,9 +834,9 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
}
static
int
btrfs_make_empty_dir
(
struct
btrfs_trans_handle
*
trans
,
struct
inode
*
inode
,
struct
inode
*
dir
)
struct
btrfs_root
*
root
,
u64
objectid
,
u64
dirid
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
int
ret
;
char
buf
[
2
];
struct
btrfs_key
key
;
...
...
@@ -843,22 +844,20 @@ static int btrfs_make_empty_dir(struct btrfs_trans_handle *trans,
buf
[
0
]
=
'.'
;
buf
[
1
]
=
'.'
;
key
.
objectid
=
inode
->
i_ino
;
key
.
objectid
=
objectid
;
key
.
offset
=
0
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_INODE_ITEM_KEY
);
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
buf
,
1
,
inode
->
i_ino
,
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
buf
,
1
,
objectid
,
&
key
,
1
);
if
(
ret
)
goto
error
;
key
.
objectid
=
dir
->
i_ino
;
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
buf
,
2
,
inode
->
i_ino
,
key
.
objectid
=
dir
id
;
ret
=
btrfs_insert_dir_item
(
trans
,
root
,
buf
,
2
,
objectid
,
&
key
,
1
);
if
(
ret
)
goto
error
;
inode
->
i_size
=
6
;
ret
=
btrfs_update_inode
(
trans
,
root
,
inode
);
error:
return
ret
;
}
...
...
@@ -870,6 +869,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct
btrfs_root
*
root
=
BTRFS_I
(
dir
)
->
root
;
int
err
=
0
;
int
drop_on_err
=
0
;
u64
objectid
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
...
...
@@ -877,7 +877,14 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
err
=
PTR_ERR
(
trans
);
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
dir
,
S_IFDIR
|
mode
);
err
=
btrfs_find_free_objectid
(
trans
,
root
,
dir
->
i_ino
,
&
objectid
);
if
(
err
)
{
err
=
-
ENOSPC
;
goto
out_unlock
;
}
inode
=
btrfs_new_inode
(
trans
,
root
,
objectid
,
S_IFDIR
|
mode
);
if
(
IS_ERR
(
inode
))
{
err
=
PTR_ERR
(
inode
);
goto
out_fail
;
...
...
@@ -886,7 +893,12 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
inode
->
i_op
=
&
btrfs_dir_inode_operations
;
inode
->
i_fop
=
&
btrfs_dir_file_operations
;
err
=
btrfs_make_empty_dir
(
trans
,
inode
,
dir
);
err
=
btrfs_make_empty_dir
(
trans
,
root
,
inode
->
i_ino
,
dir
->
i_ino
);
if
(
err
)
goto
out_fail
;
inode
->
i_size
=
6
;
err
=
btrfs_update_inode
(
trans
,
root
,
inode
);
if
(
err
)
goto
out_fail
;
err
=
btrfs_add_link
(
trans
,
dentry
,
inode
);
...
...
@@ -1666,6 +1678,102 @@ static ssize_t btrfs_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
return
retval
;
}
static
int
create_subvol
(
struct
btrfs_root
*
root
,
char
*
name
,
int
namelen
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_key
key
;
struct
btrfs_root_item
root_item
;
struct
btrfs_inode_item
*
inode_item
;
struct
buffer_head
*
subvol
;
struct
btrfs_leaf
*
leaf
;
struct
btrfs_root
*
new_root
;
struct
inode
*
inode
;
int
ret
;
u64
objectid
;
u64
new_dirid
=
BTRFS_FIRST_FREE_OBJECTID
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
BUG_ON
(
!
trans
);
subvol
=
btrfs_alloc_free_block
(
trans
,
root
);
leaf
=
btrfs_buffer_leaf
(
subvol
);
btrfs_set_header_nritems
(
&
leaf
->
header
,
0
);
btrfs_set_header_level
(
&
leaf
->
header
,
0
);
btrfs_set_header_blocknr
(
&
leaf
->
header
,
subvol
->
b_blocknr
);
btrfs_set_header_generation
(
&
leaf
->
header
,
trans
->
transid
);
memcpy
(
leaf
->
header
.
fsid
,
root
->
fs_info
->
disk_super
->
fsid
,
sizeof
(
leaf
->
header
.
fsid
));
inode_item
=
&
root_item
.
inode
;
memset
(
inode_item
,
0
,
sizeof
(
*
inode_item
));
btrfs_set_inode_generation
(
inode_item
,
1
);
btrfs_set_inode_size
(
inode_item
,
3
);
btrfs_set_inode_nlink
(
inode_item
,
1
);
btrfs_set_inode_nblocks
(
inode_item
,
1
);
btrfs_set_inode_mode
(
inode_item
,
S_IFDIR
|
0755
);
btrfs_set_root_blocknr
(
&
root_item
,
subvol
->
b_blocknr
);
btrfs_set_root_refs
(
&
root_item
,
1
);
mark_buffer_dirty
(
subvol
);
brelse
(
subvol
);
subvol
=
NULL
;
ret
=
btrfs_find_free_objectid
(
trans
,
root
->
fs_info
->
tree_root
,
0
,
&
objectid
);
BUG_ON
(
ret
);
btrfs_set_root_dirid
(
&
root_item
,
new_dirid
);
key
.
objectid
=
objectid
;
key
.
offset
=
1
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_ROOT_ITEM_KEY
);
ret
=
btrfs_insert_root
(
trans
,
root
->
fs_info
->
tree_root
,
&
key
,
&
root_item
);
BUG_ON
(
ret
);
/*
* insert the directory item
*/
key
.
offset
=
(
u64
)
-
1
;
ret
=
btrfs_insert_dir_item
(
trans
,
root
->
fs_info
->
tree_root
,
name
,
namelen
,
root
->
fs_info
->
sb
->
s_root
->
d_inode
->
i_ino
,
&
key
,
0
);
BUG_ON
(
ret
);
ret
=
btrfs_commit_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
new_root
=
btrfs_read_fs_root
(
root
->
fs_info
,
&
key
);
BUG_ON
(
!
new_root
);
trans
=
btrfs_start_transaction
(
new_root
,
1
);
BUG_ON
(
!
trans
);
inode
=
btrfs_new_inode
(
trans
,
new_root
,
new_dirid
,
S_IFDIR
|
0700
);
inode
->
i_op
=
&
btrfs_dir_inode_operations
;
inode
->
i_fop
=
&
btrfs_dir_file_operations
;
ret
=
btrfs_make_empty_dir
(
trans
,
new_root
,
new_dirid
,
new_dirid
);
BUG_ON
(
ret
);
inode
->
i_nlink
=
1
;
inode
->
i_size
=
6
;
ret
=
btrfs_update_inode
(
trans
,
new_root
,
inode
);
BUG_ON
(
ret
);
ret
=
btrfs_commit_transaction
(
trans
,
new_root
);
BUG_ON
(
ret
);
iput
(
inode
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
0
;
}
static
int
create_snapshot
(
struct
btrfs_root
*
root
,
char
*
name
,
int
namelen
)
{
struct
btrfs_trans_handle
*
trans
;
...
...
@@ -1674,6 +1782,9 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
int
ret
;
u64
objectid
;
if
(
!
root
->
ref_cows
)
return
-
EINVAL
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
BUG_ON
(
!
trans
);
...
...
@@ -1685,7 +1796,6 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
0
,
&
objectid
);
BUG_ON
(
ret
);
memset
(
&
new_root_item
,
0
,
sizeof
(
new_root_item
));
memcpy
(
&
new_root_item
,
&
root
->
root_item
,
sizeof
(
new_root_item
));
...
...
@@ -1728,9 +1838,9 @@ static int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int
struct
btrfs_ioctl_vol_args
vol_args
;
int
ret
;
int
namelen
;
struct
btrfs_path
*
path
;
u64
root_dirid
;
if
(
!
root
->
ref_cows
)
return
-
EINVAL
;
switch
(
cmd
)
{
case
BTRFS_IOC_SNAP_CREATE
:
if
(
copy_from_user
(
&
vol_args
,
...
...
@@ -1740,7 +1850,23 @@ static int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int
namelen
=
strlen
(
vol_args
.
name
);
if
(
namelen
>
BTRFS_VOL_NAME_MAX
)
return
-
EINVAL
;
ret
=
create_snapshot
(
root
,
vol_args
.
name
,
namelen
);
path
=
btrfs_alloc_path
();
if
(
!
path
)
return
-
ENOMEM
;
root_dirid
=
btrfs_root_dirid
(
&
root
->
fs_info
->
tree_root
->
root_item
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
btrfs_lookup_dir_item
(
NULL
,
root
->
fs_info
->
tree_root
,
path
,
root_dirid
,
vol_args
.
name
,
namelen
,
0
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
if
(
ret
==
0
)
return
-
EEXIST
;
if
(
root
==
root
->
fs_info
->
tree_root
)
ret
=
create_subvol
(
root
,
vol_args
.
name
,
namelen
);
else
ret
=
create_snapshot
(
root
,
vol_args
.
name
,
namelen
);
WARN_ON
(
ret
);
break
;
default:
...
...
fs/btrfs/transaction.c
浏览文件 @
2619ba1f
...
...
@@ -64,7 +64,8 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
if
(
root
!=
root
->
fs_info
->
tree_root
&&
root
->
last_trans
<
running_trans_id
)
{
radix_tree_tag_set
(
&
root
->
fs_info
->
fs_roots_radix
,
(
unsigned
long
)
root
,
BTRFS_ROOT_TRANS_TAG
);
(
unsigned
long
)
root
->
root_key
.
objectid
,
BTRFS_ROOT_TRANS_TAG
);
root
->
commit_root
=
root
->
node
;
get_bh
(
root
->
node
);
}
...
...
@@ -171,8 +172,9 @@ int add_dirty_roots(struct btrfs_trans_handle *trans,
break
;
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
root
=
gang
[
i
];
radix_tree_tag_clear
(
radix
,
(
unsigned
long
)
root
,
BTRFS_ROOT_TRANS_TAG
);
radix_tree_tag_clear
(
radix
,
(
unsigned
long
)
root
->
root_key
.
objectid
,
BTRFS_ROOT_TRANS_TAG
);
if
(
root
->
commit_root
==
root
->
node
)
{
WARN_ON
(
root
->
node
->
b_blocknr
!=
btrfs_root_blocknr
(
&
root
->
root_item
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录