Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
8352d8a4
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,发现更多精彩内容 >>
提交
8352d8a4
编写于
4月 12, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
4月 12, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: add disk ioctl, mostly working
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
7eccb903
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
221 addition
and
17 deletion
+221
-17
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+121
-7
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+6
-0
fs/btrfs/ioctl.h
fs/btrfs/ioctl.h
+2
-0
fs/btrfs/super.c
fs/btrfs/super.c
+86
-10
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+6
-0
未找到文件。
fs/btrfs/disk-io.c
浏览文件 @
8352d8a4
...
...
@@ -16,6 +16,28 @@ struct dev_lookup {
struct
block_device
*
bdev
;
};
int
btrfs_insert_dev_radix
(
struct
btrfs_root
*
root
,
struct
block_device
*
bdev
,
u64
block_start
,
u64
num_blocks
)
{
struct
dev_lookup
*
lookup
;
char
b
[
BDEVNAME_SIZE
];
int
ret
;
lookup
=
kmalloc
(
sizeof
(
*
lookup
),
GFP_NOFS
);
if
(
!
lookup
)
return
-
ENOMEM
;
lookup
->
block_start
=
block_start
;
lookup
->
num_blocks
=
num_blocks
;
lookup
->
bdev
=
bdev
;
printk
(
"inserting %s into dev radix %Lu %Lu
\n
"
,
bdevname
(
bdev
,
b
),
block_start
,
num_blocks
);
ret
=
radix_tree_insert
(
&
root
->
fs_info
->
dev_radix
,
block_start
+
num_blocks
-
1
,
lookup
);
return
ret
;
}
u64
bh_blocknr
(
struct
buffer_head
*
bh
)
{
int
blkbits
=
bh
->
b_page
->
mapping
->
host
->
i_blkbits
;
...
...
@@ -34,6 +56,8 @@ static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf)
{
struct
btrfs_node
*
node
=
btrfs_buffer_node
(
buf
);
if
(
bh_blocknr
(
buf
)
!=
btrfs_header_blocknr
(
&
node
->
header
))
{
printk
(
KERN_CRIT
"bh_blocknr(buf) is %Lu, header is %Lu
\n
"
,
bh_blocknr
(
buf
),
btrfs_header_blocknr
(
&
node
->
header
));
BUG
();
}
return
0
;
...
...
@@ -76,11 +100,10 @@ struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr)
return
ret
;
}
static
int
map_bh_to_logical
(
struct
btrfs_root
*
root
,
struct
buffer_head
*
bh
,
int
btrfs_
map_bh_to_logical
(
struct
btrfs_root
*
root
,
struct
buffer_head
*
bh
,
u64
logical
)
{
struct
dev_lookup
*
lookup
[
2
];
char
b
[
BDEVNAME_SIZE
];
int
ret
;
...
...
@@ -96,7 +119,6 @@ static int map_bh_to_logical(struct btrfs_root *root, struct buffer_head *bh,
}
bh
->
b_bdev
=
lookup
[
0
]
->
bdev
;
bh
->
b_blocknr
=
logical
-
lookup
[
0
]
->
block_start
;
printk
(
"logical mapping %Lu to %lu bdev %s
\n
"
,
logical
,
bh
->
b_blocknr
,
bdevname
(
bh
->
b_bdev
,
b
));
set_buffer_mapped
(
bh
);
ret
=
0
;
out:
...
...
@@ -126,7 +148,7 @@ struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
bh
=
head
;
do
{
if
(
!
buffer_mapped
(
bh
))
{
err
=
map_bh_to_logical
(
root
,
bh
,
first_block
);
err
=
btrfs_
map_bh_to_logical
(
root
,
bh
,
first_block
);
BUG_ON
(
err
);
}
if
(
bh_blocknr
(
bh
)
==
blocknr
)
{
...
...
@@ -150,7 +172,7 @@ static int btree_get_block(struct inode *inode, sector_t iblock,
{
int
err
;
struct
btrfs_root
*
root
=
BTRFS_I
(
bh
->
b_page
->
mapping
->
host
)
->
root
;
err
=
map_bh_to_logical
(
root
,
bh
,
iblock
);
err
=
btrfs_
map_bh_to_logical
(
root
,
bh
,
iblock
);
return
err
;
}
...
...
@@ -396,6 +418,89 @@ printk("all worked\n");
return
root
;
}
int
btrfs_open_disk
(
struct
btrfs_root
*
root
,
u64
block_start
,
u64
num_blocks
,
char
*
filename
,
int
name_len
)
{
char
*
null_filename
;
struct
block_device
*
bdev
;
int
ret
;
if
(
block_start
==
0
)
{
printk
(
"skipping disk with block_start == 0
\n
"
);
return
0
;
}
null_filename
=
kmalloc
(
name_len
+
1
,
GFP_NOFS
);
if
(
!
null_filename
)
return
-
ENOMEM
;
memcpy
(
null_filename
,
filename
,
name_len
);
null_filename
[
name_len
]
=
'\0'
;
bdev
=
open_bdev_excl
(
null_filename
,
O_RDWR
,
root
->
fs_info
->
sb
);
if
(
IS_ERR
(
bdev
))
{
ret
=
PTR_ERR
(
bdev
);
goto
out
;
}
set_blocksize
(
bdev
,
root
->
fs_info
->
sb
->
s_blocksize
);
ret
=
btrfs_insert_dev_radix
(
root
,
bdev
,
block_start
,
num_blocks
);
BUG_ON
(
ret
);
ret
=
0
;
out:
kfree
(
null_filename
);
return
ret
;
}
static
int
read_device_info
(
struct
btrfs_root
*
root
)
{
struct
btrfs_path
*
path
;
int
ret
;
struct
btrfs_key
key
;
struct
btrfs_leaf
*
leaf
;
struct
btrfs_device_item
*
dev_item
;
int
nritems
;
int
slot
;
root
=
root
->
fs_info
->
dev_root
;
path
=
btrfs_alloc_path
();
if
(
!
path
)
return
-
ENOMEM
;
key
.
objectid
=
0
;
key
.
offset
=
0
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_DEV_ITEM_KEY
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
btrfs_search_slot
(
NULL
,
root
,
&
key
,
path
,
0
,
0
);
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
while
(
1
)
{
slot
=
path
->
slots
[
0
];
if
(
slot
>=
nritems
)
{
ret
=
btrfs_next_leaf
(
root
,
path
);
if
(
ret
)
break
;
leaf
=
btrfs_buffer_leaf
(
path
->
nodes
[
0
]);
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
slot
=
path
->
slots
[
0
];
}
btrfs_disk_key_to_cpu
(
&
key
,
&
leaf
->
items
[
slot
].
key
);
if
(
btrfs_key_type
(
&
key
)
!=
BTRFS_DEV_ITEM_KEY
)
{
path
->
slots
[
0
]
++
;
continue
;
}
dev_item
=
btrfs_item_ptr
(
leaf
,
slot
,
struct
btrfs_device_item
);
printk
(
"found key %Lu %Lu
\n
"
,
key
.
objectid
,
key
.
offset
);
ret
=
btrfs_open_disk
(
root
,
key
.
objectid
,
key
.
offset
,
(
char
*
)(
dev_item
+
1
),
btrfs_device_pathlen
(
dev_item
));
BUG_ON
(
ret
);
path
->
slots
[
0
]
++
;
}
btrfs_free_path
(
path
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
0
;
}
struct
btrfs_root
*
open_ctree
(
struct
super_block
*
sb
)
{
struct
btrfs_root
*
extent_root
=
kmalloc
(
sizeof
(
struct
btrfs_root
),
...
...
@@ -463,17 +568,26 @@ struct btrfs_root *open_ctree(struct super_block *sb)
if
(
!
btrfs_super_root
(
disk_super
))
return
NULL
;
i_size_write
(
fs_info
->
btree_inode
,
btrfs_super_total_blocks
(
disk_super
)
<<
fs_info
->
btree_inode
->
i_blkbits
);
radix_tree_delete
(
&
fs_info
->
dev_radix
,
(
u32
)
-
2
);
dev_lookup
->
block_start
=
btrfs_super_device_block_start
(
disk_super
);
dev_lookup
->
num_blocks
=
btrfs_super_device_num_blocks
(
disk_super
);
ret
=
radix_tree_insert
(
&
fs_info
->
dev_radix
,
dev_lookup
->
block_start
+
dev_lookup
->
num_blocks
,
dev_lookup
);
dev_lookup
->
num_blocks
-
1
,
dev_lookup
);
BUG_ON
(
ret
);
fs_info
->
disk_super
=
disk_super
;
dev_root
->
node
=
read_tree_block
(
tree_root
,
btrfs_super_device_root
(
disk_super
));
ret
=
read_device_info
(
dev_root
);
BUG_ON
(
ret
);
tree_root
->
node
=
read_tree_block
(
tree_root
,
btrfs_super_root
(
disk_super
));
BUG_ON
(
!
tree_root
->
node
);
...
...
@@ -562,7 +676,7 @@ static int free_dev_radix(struct btrfs_fs_info *fs_info)
close_bdev_excl
(
lookup
[
i
]
->
bdev
);
radix_tree_delete
(
&
fs_info
->
dev_radix
,
lookup
[
i
]
->
block_start
+
lookup
[
i
]
->
num_blocks
);
lookup
[
i
]
->
num_blocks
-
1
);
kfree
(
lookup
[
i
]);
}
}
...
...
fs/btrfs/disk-io.h
浏览文件 @
8352d8a4
...
...
@@ -42,4 +42,10 @@ int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len,
struct
btrfs_root
*
btrfs_read_fs_root
(
struct
btrfs_fs_info
*
fs_info
,
struct
btrfs_key
*
location
);
u64
bh_blocknr
(
struct
buffer_head
*
bh
);
int
btrfs_insert_dev_radix
(
struct
btrfs_root
*
root
,
struct
block_device
*
bdev
,
u64
block_start
,
u64
num_blocks
);
int
btrfs_map_bh_to_logical
(
struct
btrfs_root
*
root
,
struct
buffer_head
*
bh
,
u64
logical
);
#endif
fs/btrfs/ioctl.h
浏览文件 @
8352d8a4
...
...
@@ -10,4 +10,6 @@ struct btrfs_ioctl_vol_args {
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_ADD_DISK _IOW(BTRFS_IOCTL_MAGIC, 2, \
struct btrfs_ioctl_vol_args)
#endif
fs/btrfs/super.c
浏览文件 @
8352d8a4
...
...
@@ -1073,6 +1073,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
}
map_bh
(
result
,
inode
->
i_sb
,
blocknr
);
btrfs_map_bh_to_logical
(
root
,
result
,
blocknr
);
goto
out
;
}
...
...
@@ -1092,7 +1093,8 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
extent_end
=
extent_start
+
btrfs_file_extent_num_blocks
(
item
);
if
(
iblock
>=
extent_start
&&
iblock
<
extent_end
)
{
err
=
0
;
map_bh
(
result
,
inode
->
i_sb
,
blocknr
+
iblock
-
extent_start
);
btrfs_map_bh_to_logical
(
root
,
result
,
blocknr
+
iblock
-
extent_start
);
goto
out
;
}
allocate:
...
...
@@ -1112,6 +1114,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
set_buffer_new
(
result
);
map_bh
(
result
,
inode
->
i_sb
,
blocknr
);
btrfs_map_bh_to_logical
(
root
,
result
,
blocknr
);
out:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
...
...
@@ -1153,12 +1156,6 @@ static int btrfs_readpage(struct file *file, struct page *page)
return
mpage_readpage
(
page
,
btrfs_get_block
);
}
static
int
btrfs_readpages
(
struct
file
*
file
,
struct
address_space
*
mapping
,
struct
list_head
*
pages
,
unsigned
nr_pages
)
{
return
mpage_readpages
(
mapping
,
pages
,
nr_pages
,
btrfs_get_block
);
}
static
int
btrfs_writepage
(
struct
page
*
page
,
struct
writeback_control
*
wbc
)
{
return
nobh_writepage
(
page
,
btrfs_get_block
,
wbc
);
...
...
@@ -1831,12 +1828,81 @@ printk("adding snapshot name %.*s root %Lu %Lu %u\n", namelen, name, key.objecti
return
0
;
}
static
int
add_disk
(
struct
btrfs_root
*
root
,
char
*
name
,
int
namelen
)
{
struct
block_device
*
bdev
;
struct
btrfs_path
*
path
;
struct
super_block
*
sb
=
root
->
fs_info
->
sb
;
struct
btrfs_root
*
dev_root
=
root
->
fs_info
->
dev_root
;
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_device_item
*
dev_item
;
struct
btrfs_key
key
;
u16
item_size
;
u64
num_blocks
;
u64
new_blocks
;
int
ret
;
printk
(
"adding disk %s
\n
"
,
name
);
path
=
btrfs_alloc_path
();
if
(
!
path
)
return
-
ENOMEM
;
num_blocks
=
btrfs_super_total_blocks
(
root
->
fs_info
->
disk_super
);
bdev
=
open_bdev_excl
(
name
,
O_RDWR
,
sb
);
if
(
IS_ERR
(
bdev
))
{
ret
=
PTR_ERR
(
bdev
);
printk
(
"open bdev excl failed ret %d
\n
"
,
ret
);
goto
out_nolock
;
}
set_blocksize
(
bdev
,
sb
->
s_blocksize
);
new_blocks
=
bdev
->
bd_inode
->
i_size
>>
sb
->
s_blocksize_bits
;
key
.
objectid
=
num_blocks
;
key
.
offset
=
new_blocks
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_DEV_ITEM_KEY
);
mutex_lock
(
&
dev_root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
dev_root
,
1
);
item_size
=
sizeof
(
*
dev_item
)
+
namelen
;
printk
(
"insert empty on %Lu %Lu %u size %d
\n
"
,
num_blocks
,
new_blocks
,
key
.
flags
,
item_size
);
ret
=
btrfs_insert_empty_item
(
trans
,
dev_root
,
path
,
&
key
,
item_size
);
if
(
ret
)
{
printk
(
"insert failed %d
\n
"
,
ret
);
close_bdev_excl
(
bdev
);
if
(
ret
>
0
)
ret
=
-
EEXIST
;
goto
out
;
}
dev_item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_device_item
);
btrfs_set_device_pathlen
(
dev_item
,
namelen
);
memcpy
(
dev_item
+
1
,
name
,
namelen
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
ret
=
btrfs_insert_dev_radix
(
root
,
bdev
,
num_blocks
,
new_blocks
);
if
(
!
ret
)
{
btrfs_set_super_total_blocks
(
root
->
fs_info
->
disk_super
,
num_blocks
+
new_blocks
);
i_size_write
(
root
->
fs_info
->
btree_inode
,
(
num_blocks
+
new_blocks
)
<<
root
->
fs_info
->
btree_inode
->
i_blkbits
);
}
out:
ret
=
btrfs_commit_transaction
(
trans
,
dev_root
);
BUG_ON
(
ret
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
out_nolock:
btrfs_free_path
(
path
);
return
ret
;
}
static
int
btrfs_ioctl
(
struct
inode
*
inode
,
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
btrfs_ioctl_vol_args
vol_args
;
int
ret
;
int
ret
=
0
;
int
namelen
;
struct
btrfs_path
*
path
;
u64
root_dirid
;
...
...
@@ -1869,10 +1935,21 @@ static int btrfs_ioctl(struct inode *inode, struct file *filp, unsigned int
ret
=
create_snapshot
(
root
,
vol_args
.
name
,
namelen
);
WARN_ON
(
ret
);
break
;
case
BTRFS_IOC_ADD_DISK
:
if
(
copy_from_user
(
&
vol_args
,
(
struct
btrfs_ioctl_vol_args
__user
*
)
arg
,
sizeof
(
vol_args
)))
return
-
EFAULT
;
namelen
=
strlen
(
vol_args
.
name
);
if
(
namelen
>
BTRFS_VOL_NAME_MAX
)
return
-
EINVAL
;
vol_args
.
name
[
namelen
]
=
'\0'
;
ret
=
add_disk
(
root
,
vol_args
.
name
,
namelen
);
break
;
default:
return
-
ENOTTY
;
}
return
0
;
return
ret
;
}
static
struct
kmem_cache
*
btrfs_inode_cachep
;
...
...
@@ -2004,7 +2081,6 @@ static struct file_operations btrfs_dir_file_operations = {
static
struct
address_space_operations
btrfs_aops
=
{
.
readpage
=
btrfs_readpage
,
.
readpages
=
btrfs_readpages
,
.
writepage
=
btrfs_writepage
,
.
sync_page
=
block_sync_page
,
.
prepare_write
=
btrfs_prepare_write
,
...
...
fs/btrfs/transaction.c
浏览文件 @
8352d8a4
...
...
@@ -116,7 +116,13 @@ int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
struct
btrfs_fs_info
*
fs_info
=
root
->
fs_info
;
struct
btrfs_root
*
tree_root
=
fs_info
->
tree_root
;
struct
btrfs_root
*
extent_root
=
fs_info
->
extent_root
;
struct
btrfs_root
*
dev_root
=
fs_info
->
dev_root
;
if
(
btrfs_super_device_root
(
fs_info
->
disk_super
)
!=
bh_blocknr
(
dev_root
->
node
))
{
btrfs_set_super_device_root
(
fs_info
->
disk_super
,
bh_blocknr
(
dev_root
->
node
));
}
while
(
1
)
{
old_extent_block
=
btrfs_root_blocknr
(
&
extent_root
->
root_item
);
if
(
old_extent_block
==
bh_blocknr
(
extent_root
->
node
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录