Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
8a4b83cc
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,发现更多精彩内容 >>
提交
8a4b83cc
编写于
3月 24, 2008
作者:
C
Chris Mason
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: Add support for device scanning and detection ioctls
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
239b14b3
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
333 addition
and
44 deletion
+333
-44
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+19
-2
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+15
-9
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+3
-1
fs/btrfs/ioctl.h
fs/btrfs/ioctl.h
+5
-1
fs/btrfs/super.c
fs/btrfs/super.c
+44
-17
fs/btrfs/volumes.c
fs/btrfs/volumes.c
+222
-14
fs/btrfs/volumes.h
fs/btrfs/volumes.h
+25
-0
未找到文件。
fs/btrfs/ctree.h
浏览文件 @
8a4b83cc
...
...
@@ -37,7 +37,7 @@ extern struct kmem_cache *btrfs_transaction_cachep;
extern
struct
kmem_cache
*
btrfs_bit_radix_cachep
;
extern
struct
kmem_cache
*
btrfs_path_cachep
;
#define BTRFS_MAGIC "_B
4
RfS_M"
#define BTRFS_MAGIC "_B
5
RfS_M"
#define BTRFS_MAX_LEVEL 8
...
...
@@ -238,6 +238,7 @@ struct btrfs_super_block {
__le64
total_bytes
;
__le64
bytes_used
;
__le64
root_dir_objectid
;
__le64
num_devices
;
__le32
sectorsize
;
__le32
nodesize
;
__le32
leafsize
;
...
...
@@ -440,6 +441,7 @@ struct btrfs_block_group_cache {
};
struct
btrfs_device
;
struct
btrfs_fs_devices
;
struct
btrfs_fs_info
{
u8
fsid
[
BTRFS_FSID_SIZE
];
struct
btrfs_root
*
extent_root
;
...
...
@@ -489,7 +491,7 @@ struct btrfs_fs_info {
u64
total_pinned
;
struct
list_head
dirty_cowonly_roots
;
struct
list_head
devices
;
struct
btrfs_fs_devices
*
fs_
devices
;
struct
list_head
space_info
;
spinlock_t
delalloc_lock
;
spinlock_t
new_trans_lock
;
...
...
@@ -677,6 +679,19 @@ BTRFS_SETGET_FUNCS(device_io_width, struct btrfs_dev_item, io_width, 32);
BTRFS_SETGET_FUNCS
(
device_sector_size
,
struct
btrfs_dev_item
,
sector_size
,
32
);
BTRFS_SETGET_FUNCS
(
device_id
,
struct
btrfs_dev_item
,
devid
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
stack_device_type
,
struct
btrfs_dev_item
,
type
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
stack_device_total_bytes
,
struct
btrfs_dev_item
,
total_bytes
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
stack_device_bytes_used
,
struct
btrfs_dev_item
,
bytes_used
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
stack_device_io_align
,
struct
btrfs_dev_item
,
io_align
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
stack_device_io_width
,
struct
btrfs_dev_item
,
io_width
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
stack_device_sector_size
,
struct
btrfs_dev_item
,
sector_size
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
stack_device_id
,
struct
btrfs_dev_item
,
devid
,
64
);
static
inline
char
*
btrfs_device_uuid
(
struct
btrfs_dev_item
*
d
)
{
return
(
char
*
)
d
+
offsetof
(
struct
btrfs_dev_item
,
uuid
);
...
...
@@ -1106,6 +1121,8 @@ BTRFS_SETGET_STACK_FUNCS(super_stripesize, struct btrfs_super_block,
stripesize
,
32
);
BTRFS_SETGET_STACK_FUNCS
(
super_root_dir
,
struct
btrfs_super_block
,
root_dir_objectid
,
64
);
BTRFS_SETGET_STACK_FUNCS
(
super_num_devices
,
struct
btrfs_super_block
,
num_devices
,
64
);
static
inline
unsigned
long
btrfs_leaf_data
(
struct
extent_buffer
*
l
)
{
...
...
fs/btrfs/disk-io.c
浏览文件 @
8a4b83cc
...
...
@@ -365,12 +365,12 @@ static int close_all_devices(struct btrfs_fs_info *fs_info)
struct
list_head
*
next
;
struct
btrfs_device
*
device
;
list
=
&
fs_info
->
devices
;
while
(
!
list_empty
(
list
))
{
next
=
list
->
next
;
list_del
(
next
);
list
=
&
fs_info
->
fs_devices
->
devices
;
list_for_each
(
next
,
list
)
{
device
=
list_entry
(
next
,
struct
btrfs_device
,
dev_list
);
kfree
(
device
);
if
(
device
->
bdev
&&
device
->
bdev
!=
fs_info
->
sb
->
s_bdev
)
close_bdev_excl
(
device
->
bdev
);
device
->
bdev
=
NULL
;
}
return
0
;
}
...
...
@@ -655,7 +655,8 @@ static int add_hasher(struct btrfs_fs_info *info, char *type) {
return 0;
}
#endif
struct
btrfs_root
*
open_ctree
(
struct
super_block
*
sb
)
struct
btrfs_root
*
open_ctree
(
struct
super_block
*
sb
,
struct
btrfs_fs_devices
*
fs_devices
)
{
u32
sectorsize
;
u32
nodesize
;
...
...
@@ -697,8 +698,8 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fs_info
->
extent_root
=
extent_root
;
fs_info
->
chunk_root
=
chunk_root
;
fs_info
->
dev_root
=
dev_root
;
fs_info
->
fs_devices
=
fs_devices
;
INIT_LIST_HEAD
(
&
fs_info
->
dirty_cowonly_roots
);
INIT_LIST_HEAD
(
&
fs_info
->
devices
);
INIT_LIST_HEAD
(
&
fs_info
->
space_info
);
btrfs_mapping_init
(
&
fs_info
->
mapping_tree
);
fs_info
->
sb
=
sb
;
...
...
@@ -779,6 +780,12 @@ struct btrfs_root *open_ctree(struct super_block *sb)
if
(
!
btrfs_super_root
(
disk_super
))
goto
fail_sb_buffer
;
if
(
btrfs_super_num_devices
(
disk_super
)
!=
fs_devices
->
num_devices
)
{
printk
(
"Btrfs: wanted %llu devices, but found %llu
\n
"
,
(
unsigned
long
long
)
btrfs_super_num_devices
(
disk_super
),
(
unsigned
long
long
)
fs_devices
->
num_devices
);
goto
fail_sb_buffer
;
}
nodesize
=
btrfs_super_nodesize
(
disk_super
);
leafsize
=
btrfs_super_leafsize
(
disk_super
);
sectorsize
=
btrfs_super_sectorsize
(
disk_super
);
...
...
@@ -799,8 +806,6 @@ struct btrfs_root *open_ctree(struct super_block *sb)
}
mutex_lock
(
&
fs_info
->
fs_mutex
);
ret
=
btrfs_read_super_device
(
tree_root
,
fs_info
->
sb_buffer
);
BUG_ON
(
ret
);
ret
=
btrfs_read_sys_array
(
tree_root
);
BUG_ON
(
ret
);
...
...
@@ -859,6 +864,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fail_iput:
iput
(
fs_info
->
btree_inode
);
fail:
close_all_devices
(
fs_info
);
kfree
(
extent_root
);
kfree
(
tree_root
);
kfree
(
fs_info
);
...
...
fs/btrfs/disk-io.h
浏览文件 @
8a4b83cc
...
...
@@ -21,6 +21,7 @@
#define BTRFS_SUPER_INFO_OFFSET (16 * 1024)
struct
btrfs_device
;
struct
btrfs_fs_devices
;
struct
extent_buffer
*
read_tree_block
(
struct
btrfs_root
*
root
,
u64
bytenr
,
u32
blocksize
);
...
...
@@ -29,7 +30,8 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
u64
bytenr
,
u32
blocksize
);
int
clean_tree_block
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
extent_buffer
*
buf
);
struct
btrfs_root
*
open_ctree
(
struct
super_block
*
sb
);
struct
btrfs_root
*
open_ctree
(
struct
super_block
*
sb
,
struct
btrfs_fs_devices
*
fs_devices
);
int
close_ctree
(
struct
btrfs_root
*
root
);
int
write_ctree_super
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
);
...
...
fs/btrfs/ioctl.h
浏览文件 @
8a4b83cc
...
...
@@ -22,8 +22,10 @@
#define BTRFS_IOCTL_MAGIC 0x94
#define BTRFS_VOL_NAME_MAX 255
#define BTRFS_PATH_NAME_MAX 4095
struct
btrfs_ioctl_vol_args
{
char
name
[
BTRFS_
VOL
_NAME_MAX
+
1
];
char
name
[
BTRFS_
PATH
_NAME_MAX
+
1
];
};
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
...
...
@@ -32,4 +34,6 @@ struct btrfs_ioctl_vol_args {
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_RESIZE _IOW(BTRFS_IOCTL_MAGIC, 3, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
struct btrfs_ioctl_vol_args)
#endif
fs/btrfs/super.c
浏览文件 @
8a4b83cc
...
...
@@ -44,6 +44,7 @@
#include "ioctl.h"
#include "print-tree.h"
#include "xattr.h"
#include "volumes.h"
#define BTRFS_SUPER_MAGIC 0x9123683E
...
...
@@ -216,7 +217,9 @@ static int parse_options (char * options,
return
1
;
}
static
int
btrfs_fill_super
(
struct
super_block
*
sb
,
void
*
data
,
int
silent
)
static
int
btrfs_fill_super
(
struct
super_block
*
sb
,
struct
btrfs_fs_devices
*
fs_devices
,
void
*
data
,
int
silent
)
{
struct
inode
*
inode
;
struct
dentry
*
root_dentry
;
...
...
@@ -231,7 +234,7 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
sb
->
s_xattr
=
btrfs_xattr_handlers
;
sb
->
s_time_gran
=
1
;
tree_root
=
open_ctree
(
sb
);
tree_root
=
open_ctree
(
sb
,
fs_devices
);
if
(
!
tree_root
||
IS_ERR
(
tree_root
))
{
printk
(
"btrfs: open_ctree failed
\n
"
);
...
...
@@ -334,18 +337,23 @@ static int test_bdev_super(struct super_block *s, void *data)
int
btrfs_get_sb_bdev
(
struct
file_system_type
*
fs_type
,
int
flags
,
const
char
*
dev_name
,
void
*
data
,
int
(
*
fill_super
)(
struct
super_block
*
,
void
*
,
int
),
struct
vfsmount
*
mnt
,
const
char
*
subvol
)
{
struct
block_device
*
bdev
=
NULL
;
struct
super_block
*
s
;
struct
dentry
*
root
;
struct
btrfs_fs_devices
*
fs_devices
=
NULL
;
int
error
=
0
;
bdev
=
open_bdev_excl
(
dev_name
,
flags
,
fs_type
);
if
(
IS_ERR
(
bdev
))
return
PTR_ERR
(
bdev
);
error
=
btrfs_scan_one_device
(
dev_name
,
flags
,
fs_type
,
&
fs_devices
);
if
(
error
)
return
error
;
error
=
btrfs_open_devices
(
fs_devices
,
flags
,
fs_type
);
if
(
error
)
return
error
;
bdev
=
fs_devices
->
lowest_bdev
;
/*
* once the super is inserted into the list by sget, s_umount
* will protect the lockfs code from trying to start a snapshot
...
...
@@ -372,7 +380,8 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type,
s
->
s_flags
=
flags
;
strlcpy
(
s
->
s_id
,
bdevname
(
bdev
,
b
),
sizeof
(
s
->
s_id
));
sb_set_blocksize
(
s
,
block_size
(
bdev
));
error
=
fill_super
(
s
,
data
,
flags
&
MS_SILENT
?
1
:
0
);
error
=
btrfs_fill_super
(
s
,
fs_devices
,
data
,
flags
&
MS_SILENT
?
1
:
0
);
if
(
error
)
{
up_write
(
&
s
->
s_umount
);
deactivate_super
(
s
);
...
...
@@ -408,7 +417,7 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type,
error_s:
error
=
PTR_ERR
(
s
);
error_bdev:
close_bdev_excl
(
bdev
);
btrfs_close_devices
(
fs_devices
);
error:
return
error
;
}
...
...
@@ -421,8 +430,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type,
char
*
subvol_name
=
NULL
;
parse_options
((
char
*
)
data
,
NULL
,
&
subvol_name
);
ret
=
btrfs_get_sb_bdev
(
fs_type
,
flags
,
dev_name
,
data
,
btrfs_fill_super
,
mnt
,
ret
=
btrfs_get_sb_bdev
(
fs_type
,
flags
,
dev_name
,
data
,
mnt
,
subvol_name
?
subvol_name
:
"default"
);
if
(
subvol_name
)
kfree
(
subvol_name
);
...
...
@@ -445,13 +453,6 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
return
0
;
}
static
long
btrfs_control_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
printk
(
"btrfs control ioctl %d
\n
"
,
cmd
);
return
0
;
}
static
struct
file_system_type
btrfs_fs_type
=
{
.
owner
=
THIS_MODULE
,
.
name
=
"btrfs"
,
...
...
@@ -460,6 +461,31 @@ static struct file_system_type btrfs_fs_type = {
.
fs_flags
=
FS_REQUIRES_DEV
,
};
static
long
btrfs_control_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
btrfs_ioctl_vol_args
*
vol
;
struct
btrfs_fs_devices
*
fs_devices
;
int
ret
;
int
len
;
vol
=
kmalloc
(
sizeof
(
*
vol
),
GFP_KERNEL
);
if
(
copy_from_user
(
vol
,
(
void
__user
*
)
arg
,
sizeof
(
*
vol
)))
{
ret
=
-
EFAULT
;
goto
out
;
}
len
=
strnlen
(
vol
->
name
,
BTRFS_PATH_NAME_MAX
);
switch
(
cmd
)
{
case
BTRFS_IOC_SCAN_DEV
:
ret
=
btrfs_scan_one_device
(
vol
->
name
,
MS_RDONLY
,
&
btrfs_fs_type
,
&
fs_devices
);
break
;
}
out:
kfree
(
vol
);
return
0
;
}
static
void
btrfs_write_super_lockfs
(
struct
super_block
*
sb
)
{
struct
btrfs_root
*
root
=
btrfs_sb
(
sb
);
...
...
@@ -567,6 +593,7 @@ static void __exit exit_btrfs_fs(void)
btrfs_interface_exit
();
unregister_filesystem
(
&
btrfs_fs_type
);
btrfs_exit_sysfs
();
btrfs_cleanup_fs_uuids
();
}
module_init
(
init_btrfs_fs
)
...
...
fs/btrfs/volumes.c
浏览文件 @
8a4b83cc
...
...
@@ -17,6 +17,7 @@
*/
#include <linux/sched.h>
#include <linux/bio.h>
#include <linux/buffer_head.h>
#include "ctree.h"
#include "extent_map.h"
#include "disk-io.h"
...
...
@@ -28,6 +29,215 @@ struct map_lookup {
struct
btrfs_device
*
dev
;
u64
physical
;
};
static
DEFINE_MUTEX
(
uuid_mutex
);
static
LIST_HEAD
(
fs_uuids
);
int
btrfs_cleanup_fs_uuids
(
void
)
{
struct
btrfs_fs_devices
*
fs_devices
;
struct
list_head
*
uuid_cur
;
struct
list_head
*
devices_cur
;
struct
btrfs_device
*
dev
;
list_for_each
(
uuid_cur
,
&
fs_uuids
)
{
fs_devices
=
list_entry
(
uuid_cur
,
struct
btrfs_fs_devices
,
list
);
while
(
!
list_empty
(
&
fs_devices
->
devices
))
{
devices_cur
=
fs_devices
->
devices
.
next
;
dev
=
list_entry
(
devices_cur
,
struct
btrfs_device
,
dev_list
);
printk
(
"uuid cleanup finds %s
\n
"
,
dev
->
name
);
if
(
dev
->
bdev
)
{
printk
(
"closing
\n
"
);
close_bdev_excl
(
dev
->
bdev
);
}
list_del
(
&
dev
->
dev_list
);
kfree
(
dev
);
}
}
return
0
;
}
static
struct
btrfs_device
*
__find_device
(
struct
list_head
*
head
,
u64
devid
)
{
struct
btrfs_device
*
dev
;
struct
list_head
*
cur
;
list_for_each
(
cur
,
head
)
{
dev
=
list_entry
(
cur
,
struct
btrfs_device
,
dev_list
);
if
(
dev
->
devid
==
devid
)
return
dev
;
}
return
NULL
;
}
static
struct
btrfs_fs_devices
*
find_fsid
(
u8
*
fsid
)
{
struct
list_head
*
cur
;
struct
btrfs_fs_devices
*
fs_devices
;
list_for_each
(
cur
,
&
fs_uuids
)
{
fs_devices
=
list_entry
(
cur
,
struct
btrfs_fs_devices
,
list
);
if
(
memcmp
(
fsid
,
fs_devices
->
fsid
,
BTRFS_FSID_SIZE
)
==
0
)
return
fs_devices
;
}
return
NULL
;
}
static
int
device_list_add
(
const
char
*
path
,
struct
btrfs_super_block
*
disk_super
,
u64
devid
,
struct
btrfs_fs_devices
**
fs_devices_ret
)
{
struct
btrfs_device
*
device
;
struct
btrfs_fs_devices
*
fs_devices
;
u64
found_transid
=
btrfs_super_generation
(
disk_super
);
fs_devices
=
find_fsid
(
disk_super
->
fsid
);
if
(
!
fs_devices
)
{
fs_devices
=
kmalloc
(
sizeof
(
*
fs_devices
),
GFP_NOFS
);
if
(
!
fs_devices
)
return
-
ENOMEM
;
INIT_LIST_HEAD
(
&
fs_devices
->
devices
);
list_add
(
&
fs_devices
->
list
,
&
fs_uuids
);
memcpy
(
fs_devices
->
fsid
,
disk_super
->
fsid
,
BTRFS_FSID_SIZE
);
fs_devices
->
latest_devid
=
devid
;
fs_devices
->
latest_trans
=
found_transid
;
fs_devices
->
lowest_devid
=
(
u64
)
-
1
;
fs_devices
->
num_devices
=
0
;
device
=
NULL
;
}
else
{
device
=
__find_device
(
&
fs_devices
->
devices
,
devid
);
}
if
(
!
device
)
{
device
=
kzalloc
(
sizeof
(
*
device
),
GFP_NOFS
);
if
(
!
device
)
{
/* we can safely leave the fs_devices entry around */
return
-
ENOMEM
;
}
device
->
devid
=
devid
;
device
->
name
=
kstrdup
(
path
,
GFP_NOFS
);
if
(
!
device
->
name
)
{
kfree
(
device
);
return
-
ENOMEM
;
}
list_add
(
&
device
->
dev_list
,
&
fs_devices
->
devices
);
fs_devices
->
num_devices
++
;
}
if
(
found_transid
>
fs_devices
->
latest_trans
)
{
fs_devices
->
latest_devid
=
devid
;
fs_devices
->
latest_trans
=
found_transid
;
}
if
(
fs_devices
->
lowest_devid
>
devid
)
{
fs_devices
->
lowest_devid
=
devid
;
printk
(
"lowest devid now %Lu
\n
"
,
devid
);
}
*
fs_devices_ret
=
fs_devices
;
return
0
;
}
int
btrfs_close_devices
(
struct
btrfs_fs_devices
*
fs_devices
)
{
struct
list_head
*
head
=
&
fs_devices
->
devices
;
struct
list_head
*
cur
;
struct
btrfs_device
*
device
;
mutex_lock
(
&
uuid_mutex
);
list_for_each
(
cur
,
head
)
{
device
=
list_entry
(
cur
,
struct
btrfs_device
,
dev_list
);
if
(
device
->
bdev
)
{
close_bdev_excl
(
device
->
bdev
);
printk
(
"close devices closes %s
\n
"
,
device
->
name
);
}
device
->
bdev
=
NULL
;
}
mutex_unlock
(
&
uuid_mutex
);
return
0
;
}
int
btrfs_open_devices
(
struct
btrfs_fs_devices
*
fs_devices
,
int
flags
,
void
*
holder
)
{
struct
block_device
*
bdev
;
struct
list_head
*
head
=
&
fs_devices
->
devices
;
struct
list_head
*
cur
;
struct
btrfs_device
*
device
;
int
ret
;
mutex_lock
(
&
uuid_mutex
);
list_for_each
(
cur
,
head
)
{
device
=
list_entry
(
cur
,
struct
btrfs_device
,
dev_list
);
bdev
=
open_bdev_excl
(
device
->
name
,
flags
,
holder
);
printk
(
"opening %s devid %Lu
\n
"
,
device
->
name
,
device
->
devid
);
if
(
IS_ERR
(
bdev
))
{
printk
(
"open %s failed
\n
"
,
device
->
name
);
ret
=
PTR_ERR
(
bdev
);
goto
fail
;
}
if
(
device
->
devid
==
fs_devices
->
latest_devid
)
fs_devices
->
latest_bdev
=
bdev
;
if
(
device
->
devid
==
fs_devices
->
lowest_devid
)
{
fs_devices
->
lowest_bdev
=
bdev
;
printk
(
"lowest bdev %s
\n
"
,
device
->
name
);
}
device
->
bdev
=
bdev
;
}
mutex_unlock
(
&
uuid_mutex
);
return
0
;
fail:
mutex_unlock
(
&
uuid_mutex
);
btrfs_close_devices
(
fs_devices
);
return
ret
;
}
int
btrfs_scan_one_device
(
const
char
*
path
,
int
flags
,
void
*
holder
,
struct
btrfs_fs_devices
**
fs_devices_ret
)
{
struct
btrfs_super_block
*
disk_super
;
struct
block_device
*
bdev
;
struct
buffer_head
*
bh
;
int
ret
;
u64
devid
;
mutex_lock
(
&
uuid_mutex
);
printk
(
"scan one opens %s
\n
"
,
path
);
bdev
=
open_bdev_excl
(
path
,
flags
,
holder
);
if
(
IS_ERR
(
bdev
))
{
printk
(
"open failed
\n
"
);
ret
=
PTR_ERR
(
bdev
);
goto
error
;
}
ret
=
set_blocksize
(
bdev
,
4096
);
if
(
ret
)
goto
error_close
;
bh
=
__bread
(
bdev
,
BTRFS_SUPER_INFO_OFFSET
/
4096
,
4096
);
if
(
!
bh
)
{
ret
=
-
EIO
;
goto
error_close
;
}
disk_super
=
(
struct
btrfs_super_block
*
)
bh
->
b_data
;
if
(
strncmp
((
char
*
)(
&
disk_super
->
magic
),
BTRFS_MAGIC
,
sizeof
(
disk_super
->
magic
)))
{
printk
(
"no btrfs found on %s
\n
"
,
path
);
ret
=
-
ENOENT
;
goto
error_brelse
;
}
devid
=
le64_to_cpu
(
disk_super
->
dev_item
.
devid
);
printk
(
"found device %Lu on %s
\n
"
,
devid
,
path
);
ret
=
device_list_add
(
path
,
disk_super
,
devid
,
fs_devices_ret
);
error_brelse:
brelse
(
bh
);
error_close:
close_bdev_excl
(
bdev
);
printk
(
"scan one closes bdev %s
\n
"
,
path
);
error:
mutex_unlock
(
&
uuid_mutex
);
return
ret
;
}
/*
* this uses a pretty simple search, the expectation is that it is
...
...
@@ -56,6 +266,10 @@ static int find_free_dev_extent(struct btrfs_trans_handle *trans,
/* FIXME use last free of some kind */
/* we don't want to overwrite the superblock on the drive,
* so we make sure to start at an offset of at least 1MB
*/
search_start
=
max
((
u64
)
1024
*
1024
,
search_start
);
key
.
objectid
=
device
->
devid
;
key
.
offset
=
search_start
;
key
.
type
=
BTRFS_DEV_EXTENT_KEY
;
...
...
@@ -285,6 +499,7 @@ int btrfs_add_device(struct btrfs_trans_handle *trans,
leaf
=
path
->
nodes
[
0
];
dev_item
=
btrfs_item_ptr
(
leaf
,
path
->
slots
[
0
],
struct
btrfs_dev_item
);
device
->
devid
=
free_devid
;
btrfs_set_device_id
(
leaf
,
dev_item
,
device
->
devid
);
btrfs_set_device_type
(
leaf
,
dev_item
,
device
->
type
);
btrfs_set_device_io_align
(
leaf
,
dev_item
,
device
->
io_align
);
...
...
@@ -382,7 +597,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
struct
btrfs_device
*
device
=
NULL
;
struct
btrfs_chunk
*
chunk
;
struct
list_head
private_devs
;
struct
list_head
*
dev_list
=
&
extent_root
->
fs_info
->
devices
;
struct
list_head
*
dev_list
=
&
extent_root
->
fs_info
->
fs_devices
->
devices
;
struct
list_head
*
cur
;
struct
extent_map_tree
*
em_tree
;
struct
map_lookup
*
map
;
...
...
@@ -449,7 +664,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
key
.
objectid
,
calc_size
,
&
dev_offset
);
BUG_ON
(
ret
);
printk
(
"alloc chunk size %Lu from dev %Lu
\n
"
,
calc_size
,
device
->
devid
);
device
->
bytes_used
+=
calc_size
;
ret
=
btrfs_update_device
(
trans
,
device
);
BUG_ON
(
ret
);
...
...
@@ -592,17 +807,9 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio)
struct
btrfs_device
*
btrfs_find_device
(
struct
btrfs_root
*
root
,
u64
devid
)
{
struct
btrfs_device
*
dev
;
struct
list_head
*
cur
=
root
->
fs_info
->
devices
.
next
;
struct
list_head
*
head
=
&
root
->
fs_info
->
devices
;
struct
list_head
*
head
=
&
root
->
fs_info
->
fs_devices
->
devices
;
while
(
cur
!=
head
)
{
dev
=
list_entry
(
cur
,
struct
btrfs_device
,
dev_list
);
if
(
dev
->
devid
==
devid
)
return
dev
;
cur
=
cur
->
next
;
}
return
NULL
;
return
__find_device
(
head
,
devid
);
}
static
int
read_one_chunk
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
key
,
...
...
@@ -699,15 +906,16 @@ static int read_one_dev(struct btrfs_root *root,
devid
=
btrfs_device_id
(
leaf
,
dev_item
);
device
=
btrfs_find_device
(
root
,
devid
);
if
(
!
device
)
{
printk
(
"warning devid %Lu not found already
\n
"
,
devid
);
device
=
kmalloc
(
sizeof
(
*
device
),
GFP_NOFS
);
if
(
!
device
)
return
-
ENOMEM
;
list_add
(
&
device
->
dev_list
,
&
root
->
fs_info
->
devices
);
list_add
(
&
device
->
dev_list
,
&
root
->
fs_info
->
fs_devices
->
devices
);
}
fill_device_from_item
(
leaf
,
dev_item
,
device
);
device
->
dev_root
=
root
->
fs_info
->
dev_root
;
device
->
bdev
=
root
->
fs_info
->
sb
->
s_bdev
;
ret
=
0
;
#if 0
ret = btrfs_open_device(device);
...
...
fs/btrfs/volumes.h
浏览文件 @
8a4b83cc
...
...
@@ -24,6 +24,8 @@ struct btrfs_device {
struct
block_device
*
bdev
;
char
*
name
;
/* the internal btrfs device id */
u64
devid
;
...
...
@@ -49,6 +51,20 @@ struct btrfs_device {
u8
uuid
[
BTRFS_DEV_UUID_SIZE
];
};
struct
btrfs_fs_devices
{
u8
fsid
[
BTRFS_FSID_SIZE
];
/* FS specific uuid */
/* the device with this id has the most recent coyp of the super */
u64
latest_devid
;
u64
latest_trans
;
u64
lowest_devid
;
u64
num_devices
;
struct
block_device
*
latest_bdev
;
struct
block_device
*
lowest_bdev
;
struct
list_head
devices
;
struct
list_head
list
;
};
int
btrfs_alloc_dev_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_device
*
device
,
u64
owner
,
u64
num_bytes
,
u64
*
start
);
...
...
@@ -67,4 +83,13 @@ int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf);
int
btrfs_map_block
(
struct
btrfs_mapping_tree
*
map_tree
,
u64
logical
,
u64
*
phys
,
u64
*
length
,
struct
btrfs_device
**
dev
);
int
btrfs_open_devices
(
struct
btrfs_fs_devices
*
fs_devices
,
int
flags
,
void
*
holder
);
int
btrfs_scan_one_device
(
const
char
*
path
,
int
flags
,
void
*
holder
,
struct
btrfs_fs_devices
**
fs_devices_ret
);
int
btrfs_close_devices
(
struct
btrfs_fs_devices
*
fs_devices
);
int
btrfs_add_device
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_device
*
device
);
int
btrfs_cleanup_fs_uuids
(
void
);
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录