Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
72375c22
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
72375c22
编写于
5月 03, 2010
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'kwolf/for-anthony' into HEAD
上级
a6dac6a9
d748768c
变更
28
隐藏空白更改
内联
并排
Showing
28 changed file
with
843 addition
and
494 deletion
+843
-494
Makefile.objs
Makefile.objs
+1
-1
block.c
block.c
+275
-109
block.h
block.h
+2
-0
block/blkdebug.c
block/blkdebug.c
+6
-11
block/bochs.c
block/bochs.c
+1
-1
block/cloop.c
block/cloop.c
+1
-1
block/cow.c
block/cow.c
+1
-1
block/curl.c
block/curl.c
+5
-5
block/dmg.c
block/dmg.c
+1
-1
block/nbd.c
block/nbd.c
+1
-1
block/parallels.c
block/parallels.c
+1
-1
block/qcow.c
block/qcow.c
+30
-37
block/qcow2-cluster.c
block/qcow2-cluster.c
+33
-31
block/qcow2-refcount.c
block/qcow2-refcount.c
+43
-43
block/qcow2-snapshot.c
block/qcow2-snapshot.c
+11
-11
block/qcow2.c
block/qcow2.c
+69
-41
block/qcow2.h
block/qcow2.h
+7
-1
block/raw-posix.c
block/raw-posix.c
+19
-43
block/raw-win32.c
block/raw-win32.c
+9
-7
block/raw.c
block/raw.c
+144
-0
block/vdi.c
block/vdi.c
+9
-20
block/vmdk.c
block/vmdk.c
+39
-101
block/vpc.c
block/vpc.c
+12
-20
block/vvfat.c
block/vvfat.c
+1
-1
block_int.h
block_int.h
+5
-1
qemu-img-cmds.hx
qemu-img-cmds.hx
+6
-0
qemu-img.c
qemu-img.c
+99
-5
qemu-img.texi
qemu-img.texi
+12
-0
未找到文件。
Makefile.objs
浏览文件 @
72375c22
...
@@ -12,7 +12,7 @@ block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o
...
@@ -12,7 +12,7 @@ block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o
block-obj-$(CONFIG_POSIX)
+=
posix-aio-compat.o
block-obj-$(CONFIG_POSIX)
+=
posix-aio-compat.o
block-obj-$(CONFIG_LINUX_AIO)
+=
linux-aio.o
block-obj-$(CONFIG_LINUX_AIO)
+=
linux-aio.o
block-nested-y
+=
cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
block-nested-y
+=
raw.o
cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
block-nested-y
+=
qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o
block-nested-y
+=
qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o
block-nested-y
+=
parallels.o nbd.o blkdebug.o
block-nested-y
+=
parallels.o nbd.o blkdebug.o
block-nested-$(CONFIG_WIN32)
+=
raw-win32.o
block-nested-$(CONFIG_WIN32)
+=
raw-win32.o
...
...
block.c
浏览文件 @
72375c22
...
@@ -54,6 +54,7 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
...
@@ -54,6 +54,7 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
uint8_t
*
buf
,
int
nb_sectors
);
uint8_t
*
buf
,
int
nb_sectors
);
static
int
bdrv_write_em
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
static
int
bdrv_write_em
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
const
uint8_t
*
buf
,
int
nb_sectors
);
const
uint8_t
*
buf
,
int
nb_sectors
);
static
BlockDriver
*
find_protocol
(
const
char
*
filename
);
static
QTAILQ_HEAD
(,
BlockDriverState
)
bdrv_states
=
static
QTAILQ_HEAD
(,
BlockDriverState
)
bdrv_states
=
QTAILQ_HEAD_INITIALIZER
(
bdrv_states
);
QTAILQ_HEAD_INITIALIZER
(
bdrv_states
);
...
@@ -203,6 +204,18 @@ int bdrv_create(BlockDriver *drv, const char* filename,
...
@@ -203,6 +204,18 @@ int bdrv_create(BlockDriver *drv, const char* filename,
return
drv
->
bdrv_create
(
filename
,
options
);
return
drv
->
bdrv_create
(
filename
,
options
);
}
}
int
bdrv_create_file
(
const
char
*
filename
,
QEMUOptionParameter
*
options
)
{
BlockDriver
*
drv
;
drv
=
find_protocol
(
filename
);
if
(
drv
==
NULL
)
{
drv
=
bdrv_find_format
(
"file"
);
}
return
bdrv_create
(
drv
,
filename
,
options
);
}
#ifdef _WIN32
#ifdef _WIN32
void
get_tmp_filename
(
char
*
filename
,
int
size
)
void
get_tmp_filename
(
char
*
filename
,
int
size
)
{
{
...
@@ -246,6 +259,28 @@ int is_windows_drive(const char *filename)
...
@@ -246,6 +259,28 @@ int is_windows_drive(const char *filename)
}
}
#endif
#endif
/*
* Detect host devices. By convention, /dev/cdrom[N] is always
* recognized as a host CDROM.
*/
static
BlockDriver
*
find_hdev_driver
(
const
char
*
filename
)
{
int
score_max
=
0
,
score
;
BlockDriver
*
drv
=
NULL
,
*
d
;
QLIST_FOREACH
(
d
,
&
bdrv_drivers
,
list
)
{
if
(
d
->
bdrv_probe_device
)
{
score
=
d
->
bdrv_probe_device
(
filename
);
if
(
score
>
score_max
)
{
score_max
=
score
;
drv
=
d
;
}
}
}
return
drv
;
}
static
BlockDriver
*
find_protocol
(
const
char
*
filename
)
static
BlockDriver
*
find_protocol
(
const
char
*
filename
)
{
{
BlockDriver
*
drv1
;
BlockDriver
*
drv1
;
...
@@ -253,14 +288,21 @@ static BlockDriver *find_protocol(const char *filename)
...
@@ -253,14 +288,21 @@ static BlockDriver *find_protocol(const char *filename)
int
len
;
int
len
;
const
char
*
p
;
const
char
*
p
;
/* TODO Drivers without bdrv_file_open must be specified explicitly */
#ifdef _WIN32
#ifdef _WIN32
if
(
is_windows_drive
(
filename
)
||
if
(
is_windows_drive
(
filename
)
||
is_windows_drive_prefix
(
filename
))
is_windows_drive_prefix
(
filename
))
return
bdrv_find_format
(
"
raw
"
);
return
bdrv_find_format
(
"
file
"
);
#endif
#endif
p
=
strchr
(
filename
,
':'
);
p
=
strchr
(
filename
,
':'
);
if
(
!
p
)
if
(
!
p
)
{
return
bdrv_find_format
(
"raw"
);
drv1
=
find_hdev_driver
(
filename
);
if
(
!
drv1
)
{
drv1
=
bdrv_find_format
(
"file"
);
}
return
drv1
;
}
len
=
p
-
filename
;
len
=
p
-
filename
;
if
(
len
>
sizeof
(
protocol
)
-
1
)
if
(
len
>
sizeof
(
protocol
)
-
1
)
len
=
sizeof
(
protocol
)
-
1
;
len
=
sizeof
(
protocol
)
-
1
;
...
@@ -275,28 +317,6 @@ static BlockDriver *find_protocol(const char *filename)
...
@@ -275,28 +317,6 @@ static BlockDriver *find_protocol(const char *filename)
return
NULL
;
return
NULL
;
}
}
/*
* Detect host devices. By convention, /dev/cdrom[N] is always
* recognized as a host CDROM.
*/
static
BlockDriver
*
find_hdev_driver
(
const
char
*
filename
)
{
int
score_max
=
0
,
score
;
BlockDriver
*
drv
=
NULL
,
*
d
;
QLIST_FOREACH
(
d
,
&
bdrv_drivers
,
list
)
{
if
(
d
->
bdrv_probe_device
)
{
score
=
d
->
bdrv_probe_device
(
filename
);
if
(
score
>
score_max
)
{
score_max
=
score
;
drv
=
d
;
}
}
}
return
drv
;
}
static
BlockDriver
*
find_image_format
(
const
char
*
filename
)
static
BlockDriver
*
find_image_format
(
const
char
*
filename
)
{
{
int
ret
,
score
,
score_max
;
int
ret
,
score
,
score_max
;
...
@@ -319,6 +339,7 @@ static BlockDriver *find_image_format(const char *filename)
...
@@ -319,6 +339,7 @@ static BlockDriver *find_image_format(const char *filename)
}
}
score_max
=
0
;
score_max
=
0
;
drv
=
NULL
;
QLIST_FOREACH
(
drv1
,
&
bdrv_drivers
,
list
)
{
QLIST_FOREACH
(
drv1
,
&
bdrv_drivers
,
list
)
{
if
(
drv1
->
bdrv_probe
)
{
if
(
drv1
->
bdrv_probe
)
{
score
=
drv1
->
bdrv_probe
(
buf
,
ret
,
filename
);
score
=
drv1
->
bdrv_probe
(
buf
,
ret
,
filename
);
...
@@ -331,6 +352,118 @@ static BlockDriver *find_image_format(const char *filename)
...
@@ -331,6 +352,118 @@ static BlockDriver *find_image_format(const char *filename)
return
drv
;
return
drv
;
}
}
/**
* Set the current 'total_sectors' value
*/
static
int
refresh_total_sectors
(
BlockDriverState
*
bs
,
int64_t
hint
)
{
BlockDriver
*
drv
=
bs
->
drv
;
/* query actual device if possible, otherwise just trust the hint */
if
(
drv
->
bdrv_getlength
)
{
int64_t
length
=
drv
->
bdrv_getlength
(
bs
);
if
(
length
<
0
)
{
return
length
;
}
hint
=
length
>>
BDRV_SECTOR_BITS
;
}
bs
->
total_sectors
=
hint
;
return
0
;
}
/*
* Common part for opening disk images and files
*/
static
int
bdrv_open_common
(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
,
BlockDriver
*
drv
)
{
int
ret
,
open_flags
;
assert
(
drv
!=
NULL
);
bs
->
file
=
NULL
;
bs
->
total_sectors
=
0
;
bs
->
is_temporary
=
0
;
bs
->
encrypted
=
0
;
bs
->
valid_key
=
0
;
bs
->
open_flags
=
flags
;
/* buffer_alignment defaulted to 512, drivers can change this value */
bs
->
buffer_alignment
=
512
;
pstrcpy
(
bs
->
filename
,
sizeof
(
bs
->
filename
),
filename
);
if
(
use_bdrv_whitelist
&&
!
bdrv_is_whitelisted
(
drv
))
{
return
-
ENOTSUP
;
}
bs
->
drv
=
drv
;
bs
->
opaque
=
qemu_mallocz
(
drv
->
instance_size
);
/*
* Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a
* write cache to the guest. We do need the fdatasync to flush
* out transactions for block allocations, and we maybe have a
* volatile write cache in our backing device to deal with.
*/
if
(
flags
&
(
BDRV_O_CACHE_WB
|
BDRV_O_NOCACHE
))
bs
->
enable_write_cache
=
1
;
/*
* Clear flags that are internal to the block layer before opening the
* image.
*/
open_flags
=
flags
&
~
(
BDRV_O_SNAPSHOT
|
BDRV_O_NO_BACKING
);
/*
* Snapshots should be writeable.
*/
if
(
bs
->
is_temporary
)
{
open_flags
|=
BDRV_O_RDWR
;
}
/* Open the image, either directly or using a protocol */
if
(
drv
->
bdrv_file_open
)
{
ret
=
drv
->
bdrv_file_open
(
bs
,
filename
,
open_flags
);
}
else
{
ret
=
bdrv_file_open
(
&
bs
->
file
,
filename
,
open_flags
);
if
(
ret
>=
0
)
{
ret
=
drv
->
bdrv_open
(
bs
,
open_flags
);
}
}
if
(
ret
<
0
)
{
goto
free_and_fail
;
}
bs
->
keep_read_only
=
bs
->
read_only
=
!
(
open_flags
&
BDRV_O_RDWR
);
ret
=
refresh_total_sectors
(
bs
,
bs
->
total_sectors
);
if
(
ret
<
0
)
{
goto
free_and_fail
;
}
#ifndef _WIN32
if
(
bs
->
is_temporary
)
{
unlink
(
filename
);
}
#endif
return
0
;
free_and_fail:
if
(
bs
->
file
)
{
bdrv_delete
(
bs
->
file
);
bs
->
file
=
NULL
;
}
qemu_free
(
bs
->
opaque
);
bs
->
opaque
=
NULL
;
bs
->
drv
=
NULL
;
return
ret
;
}
/*
* Opens a file using a protocol (file, host_device, nbd, ...)
*/
int
bdrv_file_open
(
BlockDriverState
**
pbs
,
const
char
*
filename
,
int
flags
)
int
bdrv_file_open
(
BlockDriverState
**
pbs
,
const
char
*
filename
,
int
flags
)
{
{
BlockDriverState
*
bs
;
BlockDriverState
*
bs
;
...
@@ -343,7 +476,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
...
@@ -343,7 +476,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
}
}
bs
=
bdrv_new
(
""
);
bs
=
bdrv_new
(
""
);
ret
=
bdrv_open
(
bs
,
filename
,
flags
,
drv
);
ret
=
bdrv_open
_common
(
bs
,
filename
,
flags
,
drv
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
bdrv_delete
(
bs
);
bdrv_delete
(
bs
);
return
ret
;
return
ret
;
...
@@ -353,19 +486,13 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
...
@@ -353,19 +486,13 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
return
0
;
return
0
;
}
}
/*
* Opens a disk image (raw, qcow2, vmdk, ...)
*/
int
bdrv_open
(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
,
int
bdrv_open
(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
,
BlockDriver
*
drv
)
BlockDriver
*
drv
)
{
{
int
ret
,
open_flags
;
int
ret
;
char
tmp_filename
[
PATH_MAX
];
char
backing_filename
[
PATH_MAX
];
bs
->
is_temporary
=
0
;
bs
->
encrypted
=
0
;
bs
->
valid_key
=
0
;
bs
->
open_flags
=
flags
;
/* buffer_alignment defaulted to 512, drivers can change this value */
bs
->
buffer_alignment
=
512
;
if
(
flags
&
BDRV_O_SNAPSHOT
)
{
if
(
flags
&
BDRV_O_SNAPSHOT
)
{
BlockDriverState
*
bs1
;
BlockDriverState
*
bs1
;
...
@@ -373,6 +500,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
...
@@ -373,6 +500,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
int
is_protocol
=
0
;
int
is_protocol
=
0
;
BlockDriver
*
bdrv_qcow2
;
BlockDriver
*
bdrv_qcow2
;
QEMUOptionParameter
*
options
;
QEMUOptionParameter
*
options
;
char
tmp_filename
[
PATH_MAX
];
char
backing_filename
[
PATH_MAX
];
/* if snapshot, we create a temporary backing file and open it
/* if snapshot, we create a temporary backing file and open it
instead of opening 'filename' directly */
instead of opening 'filename' directly */
...
@@ -411,6 +540,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
...
@@ -411,6 +540,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
}
}
ret
=
bdrv_create
(
bdrv_qcow2
,
tmp_filename
,
options
);
ret
=
bdrv_create
(
bdrv_qcow2
,
tmp_filename
,
options
);
free_option_parameters
(
options
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
}
}
...
@@ -420,66 +550,28 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
...
@@ -420,66 +550,28 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
bs
->
is_temporary
=
1
;
bs
->
is_temporary
=
1
;
}
}
pstrcpy
(
bs
->
filename
,
sizeof
(
bs
->
filename
),
filename
);
/* Find the right image format driver */
if
(
!
drv
)
{
if
(
!
drv
)
{
drv
=
find_hdev_driver
(
filename
);
drv
=
find_image_format
(
filename
);
if
(
!
drv
)
{
drv
=
find_image_format
(
filename
);
}
}
}
if
(
!
drv
)
{
if
(
!
drv
)
{
ret
=
-
ENOENT
;
ret
=
-
ENOENT
;
goto
unlink_and_fail
;
goto
unlink_and_fail
;
}
}
if
(
use_bdrv_whitelist
&&
!
bdrv_is_whitelisted
(
drv
))
{
ret
=
-
ENOTSUP
;
goto
unlink_and_fail
;
}
bs
->
drv
=
drv
;
/* Open the image */
bs
->
opaque
=
qemu_mallocz
(
drv
->
instance_size
);
ret
=
bdrv_open_common
(
bs
,
filename
,
flags
,
drv
);
/*
* Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a
* write cache to the guest. We do need the fdatasync to flush
* out transactions for block allocations, and we maybe have a
* volatile write cache in our backing device to deal with.
*/
if
(
flags
&
(
BDRV_O_CACHE_WB
|
BDRV_O_NOCACHE
))
bs
->
enable_write_cache
=
1
;
/*
* Clear flags that are internal to the block layer before opening the
* image.
*/
open_flags
=
flags
&
~
(
BDRV_O_SNAPSHOT
|
BDRV_O_NO_BACKING
);
/*
* Snapshots should be writeable.
*/
if
(
bs
->
is_temporary
)
{
open_flags
|=
BDRV_O_RDWR
;
}
ret
=
drv
->
bdrv_open
(
bs
,
filename
,
open_flags
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
free
_and_fail
;
goto
unlink
_and_fail
;
}
}
bs
->
keep_read_only
=
bs
->
read_only
=
!
(
open_flags
&
BDRV_O_RDWR
);
/* If there is a backing file, use it */
if
(
drv
->
bdrv_getlength
)
{
bs
->
total_sectors
=
bdrv_getlength
(
bs
)
>>
BDRV_SECTOR_BITS
;
}
#ifndef _WIN32
if
(
bs
->
is_temporary
)
{
unlink
(
filename
);
}
#endif
if
((
flags
&
BDRV_O_NO_BACKING
)
==
0
&&
bs
->
backing_file
[
0
]
!=
'\0'
)
{
if
((
flags
&
BDRV_O_NO_BACKING
)
==
0
&&
bs
->
backing_file
[
0
]
!=
'\0'
)
{
/* if there is a backing file, use it */
char
backing_filename
[
PATH_MAX
];
int
back_flags
;
BlockDriver
*
back_drv
=
NULL
;
BlockDriver
*
back_drv
=
NULL
;
bs
->
backing_hd
=
bdrv_new
(
""
);
bs
->
backing_hd
=
bdrv_new
(
""
);
path_combine
(
backing_filename
,
sizeof
(
backing_filename
),
path_combine
(
backing_filename
,
sizeof
(
backing_filename
),
filename
,
bs
->
backing_file
);
filename
,
bs
->
backing_file
);
...
@@ -487,9 +579,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
...
@@ -487,9 +579,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
back_drv
=
bdrv_find_format
(
bs
->
backing_format
);
back_drv
=
bdrv_find_format
(
bs
->
backing_format
);
/* backing files always opened read-only */
/* backing files always opened read-only */
open_flags
&=
~
BDRV_O_RDWR
;
back_flags
=
flags
&
~
(
BDRV_O_RDWR
|
BDRV_O_SNAPSHOT
|
BDRV_O_NO_BACKING
);
ret
=
bdrv_open
(
bs
->
backing_hd
,
backing_filename
,
open
_flags
,
back_drv
);
ret
=
bdrv_open
(
bs
->
backing_hd
,
backing_filename
,
back
_flags
,
back_drv
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
bdrv_close
(
bs
);
bdrv_close
(
bs
);
return
ret
;
return
ret
;
...
@@ -508,23 +601,23 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
...
@@ -508,23 +601,23 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
if
(
bs
->
change_cb
)
if
(
bs
->
change_cb
)
bs
->
change_cb
(
bs
->
change_opaque
);
bs
->
change_cb
(
bs
->
change_opaque
);
}
}
return
0
;
return
0
;
free_and_fail:
qemu_free
(
bs
->
opaque
);
bs
->
opaque
=
NULL
;
bs
->
drv
=
NULL
;
unlink_and_fail:
unlink_and_fail:
if
(
bs
->
is_temporary
)
if
(
bs
->
is_temporary
)
{
unlink
(
filename
);
unlink
(
filename
);
}
return
ret
;
return
ret
;
}
}
void
bdrv_close
(
BlockDriverState
*
bs
)
void
bdrv_close
(
BlockDriverState
*
bs
)
{
{
if
(
bs
->
drv
)
{
if
(
bs
->
drv
)
{
if
(
bs
->
backing_hd
)
if
(
bs
->
backing_hd
)
{
bdrv_delete
(
bs
->
backing_hd
);
bdrv_delete
(
bs
->
backing_hd
);
bs
->
backing_hd
=
NULL
;
}
bs
->
drv
->
bdrv_close
(
bs
);
bs
->
drv
->
bdrv_close
(
bs
);
qemu_free
(
bs
->
opaque
);
qemu_free
(
bs
->
opaque
);
#ifdef _WIN32
#ifdef _WIN32
...
@@ -535,6 +628,10 @@ void bdrv_close(BlockDriverState *bs)
...
@@ -535,6 +628,10 @@ void bdrv_close(BlockDriverState *bs)
bs
->
opaque
=
NULL
;
bs
->
opaque
=
NULL
;
bs
->
drv
=
NULL
;
bs
->
drv
=
NULL
;
if
(
bs
->
file
!=
NULL
)
{
bdrv_close
(
bs
->
file
);
}
/* call the change callback */
/* call the change callback */
bs
->
media_changed
=
1
;
bs
->
media_changed
=
1
;
if
(
bs
->
change_cb
)
if
(
bs
->
change_cb
)
...
@@ -550,6 +647,10 @@ void bdrv_delete(BlockDriverState *bs)
...
@@ -550,6 +647,10 @@ void bdrv_delete(BlockDriverState *bs)
}
}
bdrv_close
(
bs
);
bdrv_close
(
bs
);
if
(
bs
->
file
!=
NULL
)
{
bdrv_delete
(
bs
->
file
);
}
qemu_free
(
bs
);
qemu_free
(
bs
);
}
}
...
@@ -780,6 +881,10 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
...
@@ -780,6 +881,10 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
set_dirty_bitmap
(
bs
,
sector_num
,
nb_sectors
,
1
);
set_dirty_bitmap
(
bs
,
sector_num
,
nb_sectors
,
1
);
}
}
if
(
bs
->
wr_highest_sector
<
sector_num
+
nb_sectors
-
1
)
{
bs
->
wr_highest_sector
=
sector_num
+
nb_sectors
-
1
;
}
return
drv
->
bdrv_write
(
bs
,
sector_num
,
buf
,
nb_sectors
);
return
drv
->
bdrv_write
(
bs
,
sector_num
,
buf
,
nb_sectors
);
}
}
...
@@ -883,13 +988,18 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
...
@@ -883,13 +988,18 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
int
bdrv_truncate
(
BlockDriverState
*
bs
,
int64_t
offset
)
int
bdrv_truncate
(
BlockDriverState
*
bs
,
int64_t
offset
)
{
{
BlockDriver
*
drv
=
bs
->
drv
;
BlockDriver
*
drv
=
bs
->
drv
;
int
ret
;
if
(
!
drv
)
if
(
!
drv
)
return
-
ENOMEDIUM
;
return
-
ENOMEDIUM
;
if
(
!
drv
->
bdrv_truncate
)
if
(
!
drv
->
bdrv_truncate
)
return
-
ENOTSUP
;
return
-
ENOTSUP
;
if
(
bs
->
read_only
)
if
(
bs
->
read_only
)
return
-
EACCES
;
return
-
EACCES
;
return
drv
->
bdrv_truncate
(
bs
,
offset
);
ret
=
drv
->
bdrv_truncate
(
bs
,
offset
);
if
(
ret
==
0
)
{
ret
=
refresh_total_sectors
(
bs
,
offset
>>
BDRV_SECTOR_BITS
);
}
return
ret
;
}
}
/**
/**
...
@@ -900,8 +1010,12 @@ int64_t bdrv_getlength(BlockDriverState *bs)
...
@@ -900,8 +1010,12 @@ int64_t bdrv_getlength(BlockDriverState *bs)
BlockDriver
*
drv
=
bs
->
drv
;
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
if
(
!
drv
)
return
-
ENOMEDIUM
;
return
-
ENOMEDIUM
;
if
(
!
drv
->
bdrv_getlength
)
{
/* legacy mode */
/* Fixed size devices use the total_sectors value for speed instead of
issuing a length query (like lseek) on each call. Also, legacy block
drivers don't provide a bdrv_getlength function and must use
total_sectors. */
if
(
!
bs
->
growable
||
!
drv
->
bdrv_getlength
)
{
return
bs
->
total_sectors
*
BDRV_SECTOR_SIZE
;
return
bs
->
total_sectors
*
BDRV_SECTOR_SIZE
;
}
}
return
drv
->
bdrv_getlength
(
bs
);
return
drv
->
bdrv_getlength
(
bs
);
...
@@ -1208,6 +1322,19 @@ void bdrv_flush_all(void)
...
@@ -1208,6 +1322,19 @@ void bdrv_flush_all(void)
}
}
}
}
int
bdrv_has_zero_init
(
BlockDriverState
*
bs
)
{
assert
(
bs
->
drv
);
if
(
bs
->
drv
->
no_zero_init
)
{
return
0
;
}
else
if
(
bs
->
file
)
{
return
bdrv_has_zero_init
(
bs
->
file
);
}
return
1
;
}
/*
/*
* Returns true iff the specified sector is present in the disk image. Drivers
* Returns true iff the specified sector is present in the disk image. Drivers
* not implementing the functionality are assumed to not support backing files,
* not implementing the functionality are assumed to not support backing files,
...
@@ -1408,6 +1535,35 @@ void bdrv_stats_print(Monitor *mon, const QObject *data)
...
@@ -1408,6 +1535,35 @@ void bdrv_stats_print(Monitor *mon, const QObject *data)
qlist_iter
(
qobject_to_qlist
(
data
),
bdrv_stats_iter
,
mon
);
qlist_iter
(
qobject_to_qlist
(
data
),
bdrv_stats_iter
,
mon
);
}
}
static
QObject
*
bdrv_info_stats_bs
(
BlockDriverState
*
bs
)
{
QObject
*
res
;
QDict
*
dict
;
res
=
qobject_from_jsonf
(
"{ 'stats': {"
"'rd_bytes': %"
PRId64
","
"'wr_bytes': %"
PRId64
","
"'rd_operations': %"
PRId64
","
"'wr_operations': %"
PRId64
","
"'wr_highest_offset': %"
PRId64
"} }"
,
bs
->
rd_bytes
,
bs
->
wr_bytes
,
bs
->
rd_ops
,
bs
->
wr_ops
,
bs
->
wr_highest_sector
*
512
);
dict
=
qobject_to_qdict
(
res
);
if
(
*
bs
->
device_name
)
{
qdict_put
(
dict
,
"device"
,
qstring_from_str
(
bs
->
device_name
));
}
if
(
bs
->
file
)
{
QObject
*
parent
=
bdrv_info_stats_bs
(
bs
->
file
);
qdict_put_obj
(
dict
,
"parent"
,
parent
);
}
return
res
;
}
/**
/**
* bdrv_info_stats(): show block device statistics
* bdrv_info_stats(): show block device statistics
*
*
...
@@ -1422,19 +1578,34 @@ void bdrv_stats_print(Monitor *mon, const QObject *data)
...
@@ -1422,19 +1578,34 @@ void bdrv_stats_print(Monitor *mon, const QObject *data)
* - "wr_bytes": bytes written
* - "wr_bytes": bytes written
* - "rd_operations": read operations
* - "rd_operations": read operations
* - "wr_operations": write operations
* - "wr_operations": write operations
*
* - "wr_highest_offset": Highest offset of a sector written since the
* BlockDriverState has been opened
* - "parent": Contains recursively the statistics of the underlying
* protocol (e.g. the host file for a qcow2 image). If there is no
* underlying protocol, this field is omitted.
*
* Example:
* Example:
*
*
* [ { "device": "ide0-hd0",
* [ { "device": "ide0-hd0",
* "stats": { "rd_bytes": 512,
* "stats": { "rd_bytes": 512,
* "wr_bytes": 0,
* "wr_bytes": 0,
* "rd_operations": 1,
* "rd_operations": 1,
* "wr_operations": 0 } },
* "wr_operations": 0,
* "wr_highest_offset": 0,
* "parent": {
* "stats": { "rd_bytes": 1024,
* "wr_bytes": 0,
* "rd_operations": 2,
* "wr_operations": 0,
* "wr_highest_offset": 0,
* }
* } } },
* { "device": "ide1-cd0",
* { "device": "ide1-cd0",
* "stats": { "rd_bytes": 0,
* "stats": { "rd_bytes": 0,
* "wr_bytes": 0,
* "wr_bytes": 0,
* "rd_operations": 0,
* "rd_operations": 0,
* "wr_operations": 0 } } ]
* "wr_operations": 0,
* "wr_highest_offset": 0 } },
*/
*/
void
bdrv_info_stats
(
Monitor
*
mon
,
QObject
**
ret_data
)
void
bdrv_info_stats
(
Monitor
*
mon
,
QObject
**
ret_data
)
{
{
...
@@ -1445,15 +1616,7 @@ void bdrv_info_stats(Monitor *mon, QObject **ret_data)
...
@@ -1445,15 +1616,7 @@ void bdrv_info_stats(Monitor *mon, QObject **ret_data)
devices
=
qlist_new
();
devices
=
qlist_new
();
QTAILQ_FOREACH
(
bs
,
&
bdrv_states
,
list
)
{
QTAILQ_FOREACH
(
bs
,
&
bdrv_states
,
list
)
{
obj
=
qobject_from_jsonf
(
"{ 'device': %s, 'stats': {"
obj
=
bdrv_info_stats_bs
(
bs
);
"'rd_bytes': %"
PRId64
","
"'wr_bytes': %"
PRId64
","
"'rd_operations': %"
PRId64
","
"'wr_operations': %"
PRId64
"} }"
,
bs
->
device_name
,
bs
->
rd_bytes
,
bs
->
wr_bytes
,
bs
->
rd_ops
,
bs
->
wr_ops
);
qlist_append_obj
(
devices
,
obj
);
qlist_append_obj
(
devices
,
obj
);
}
}
...
@@ -1712,9 +1875,12 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
...
@@ -1712,9 +1875,12 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
cb
,
opaque
);
cb
,
opaque
);
if
(
ret
)
{
if
(
ret
)
{
/* Update stats even though technically transfer has not happened. */
/* Update stats even though technically transfer has not happened. */
bs
->
wr_bytes
+=
(
unsigned
)
nb_sectors
*
BDRV_SECTOR_SIZE
;
bs
->
wr_bytes
+=
(
unsigned
)
nb_sectors
*
BDRV_SECTOR_SIZE
;
bs
->
wr_ops
++
;
bs
->
wr_ops
++
;
if
(
bs
->
wr_highest_sector
<
sector_num
+
nb_sectors
-
1
)
{
bs
->
wr_highest_sector
=
sector_num
+
nb_sectors
-
1
;
}
}
}
return
ret
;
return
ret
;
...
...
block.h
浏览文件 @
72375c22
...
@@ -57,6 +57,7 @@ BlockDriver *bdrv_find_format(const char *format_name);
...
@@ -57,6 +57,7 @@ BlockDriver *bdrv_find_format(const char *format_name);
BlockDriver
*
bdrv_find_whitelisted_format
(
const
char
*
format_name
);
BlockDriver
*
bdrv_find_whitelisted_format
(
const
char
*
format_name
);
int
bdrv_create
(
BlockDriver
*
drv
,
const
char
*
filename
,
int
bdrv_create
(
BlockDriver
*
drv
,
const
char
*
filename
,
QEMUOptionParameter
*
options
);
QEMUOptionParameter
*
options
);
int
bdrv_create_file
(
const
char
*
filename
,
QEMUOptionParameter
*
options
);
BlockDriverState
*
bdrv_new
(
const
char
*
device_name
);
BlockDriverState
*
bdrv_new
(
const
char
*
device_name
);
void
bdrv_delete
(
BlockDriverState
*
bs
);
void
bdrv_delete
(
BlockDriverState
*
bs
);
int
bdrv_file_open
(
BlockDriverState
**
pbs
,
const
char
*
filename
,
int
flags
);
int
bdrv_file_open
(
BlockDriverState
**
pbs
,
const
char
*
filename
,
int
flags
);
...
@@ -121,6 +122,7 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
...
@@ -121,6 +122,7 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
void
bdrv_flush
(
BlockDriverState
*
bs
);
void
bdrv_flush
(
BlockDriverState
*
bs
);
void
bdrv_flush_all
(
void
);
void
bdrv_flush_all
(
void
);
int
bdrv_has_zero_init
(
BlockDriverState
*
bs
);
int
bdrv_is_allocated
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
int
nb_sectors
,
int
bdrv_is_allocated
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
int
nb_sectors
,
int
*
pnum
);
int
*
pnum
);
...
...
block/blkdebug.c
浏览文件 @
72375c22
...
@@ -44,7 +44,6 @@ typedef struct BlkdebugVars {
...
@@ -44,7 +44,6 @@ typedef struct BlkdebugVars {
}
BlkdebugVars
;
}
BlkdebugVars
;
typedef
struct
BDRVBlkdebugState
{
typedef
struct
BDRVBlkdebugState
{
BlockDriverState
*
hd
;
BlkdebugVars
vars
;
BlkdebugVars
vars
;
QLIST_HEAD
(
list
,
BlkdebugRule
)
rules
[
BLKDBG_EVENT_MAX
];
QLIST_HEAD
(
list
,
BlkdebugRule
)
rules
[
BLKDBG_EVENT_MAX
];
}
BDRVBlkdebugState
;
}
BDRVBlkdebugState
;
...
@@ -303,7 +302,7 @@ static int blkdebug_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -303,7 +302,7 @@ static int blkdebug_open(BlockDriverState *bs, const char *filename, int flags)
filename
=
c
+
1
;
filename
=
c
+
1
;
/* Open the backing file */
/* Open the backing file */
ret
=
bdrv_file_open
(
&
s
->
hd
,
filename
,
flags
);
ret
=
bdrv_file_open
(
&
bs
->
file
,
filename
,
flags
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
}
}
...
@@ -362,7 +361,7 @@ static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs,
...
@@ -362,7 +361,7 @@ static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs,
}
}
BlockDriverAIOCB
*
acb
=
BlockDriverAIOCB
*
acb
=
bdrv_aio_readv
(
s
->
hd
,
sector_num
,
qiov
,
nb_sectors
,
cb
,
opaque
);
bdrv_aio_readv
(
bs
->
file
,
sector_num
,
qiov
,
nb_sectors
,
cb
,
opaque
);
return
acb
;
return
acb
;
}
}
...
@@ -377,7 +376,7 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
...
@@ -377,7 +376,7 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
}
}
BlockDriverAIOCB
*
acb
=
BlockDriverAIOCB
*
acb
=
bdrv_aio_writev
(
s
->
hd
,
sector_num
,
qiov
,
nb_sectors
,
cb
,
opaque
);
bdrv_aio_writev
(
bs
->
file
,
sector_num
,
qiov
,
nb_sectors
,
cb
,
opaque
);
return
acb
;
return
acb
;
}
}
...
@@ -393,21 +392,17 @@ static void blkdebug_close(BlockDriverState *bs)
...
@@ -393,21 +392,17 @@ static void blkdebug_close(BlockDriverState *bs)
qemu_free
(
rule
);
qemu_free
(
rule
);
}
}
}
}
bdrv_delete
(
s
->
hd
);
}
}
static
void
blkdebug_flush
(
BlockDriverState
*
bs
)
static
void
blkdebug_flush
(
BlockDriverState
*
bs
)
{
{
BDRVBlkdebugState
*
s
=
bs
->
opaque
;
bdrv_flush
(
bs
->
file
);
bdrv_flush
(
s
->
hd
);
}
}
static
BlockDriverAIOCB
*
blkdebug_aio_flush
(
BlockDriverState
*
bs
,
static
BlockDriverAIOCB
*
blkdebug_aio_flush
(
BlockDriverState
*
bs
,
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
{
{
BDRVBlkdebugState
*
s
=
bs
->
opaque
;
return
bdrv_aio_flush
(
bs
->
file
,
cb
,
opaque
);
return
bdrv_aio_flush
(
s
->
hd
,
cb
,
opaque
);
}
}
static
void
process_rule
(
BlockDriverState
*
bs
,
struct
BlkdebugRule
*
rule
,
static
void
process_rule
(
BlockDriverState
*
bs
,
struct
BlkdebugRule
*
rule
,
...
@@ -456,7 +451,7 @@ static BlockDriver bdrv_blkdebug = {
...
@@ -456,7 +451,7 @@ static BlockDriver bdrv_blkdebug = {
.
instance_size
=
sizeof
(
BDRVBlkdebugState
),
.
instance_size
=
sizeof
(
BDRVBlkdebugState
),
.
bdrv_
open
=
blkdebug_open
,
.
bdrv_
file_open
=
blkdebug_open
,
.
bdrv_close
=
blkdebug_close
,
.
bdrv_close
=
blkdebug_close
,
.
bdrv_flush
=
blkdebug_flush
,
.
bdrv_flush
=
blkdebug_flush
,
...
...
block/bochs.c
浏览文件 @
72375c22
...
@@ -252,7 +252,7 @@ static BlockDriver bdrv_bochs = {
...
@@ -252,7 +252,7 @@ static BlockDriver bdrv_bochs = {
.
format_name
=
"bochs"
,
.
format_name
=
"bochs"
,
.
instance_size
=
sizeof
(
BDRVBochsState
),
.
instance_size
=
sizeof
(
BDRVBochsState
),
.
bdrv_probe
=
bochs_probe
,
.
bdrv_probe
=
bochs_probe
,
.
bdrv_
open
=
bochs_open
,
.
bdrv_
file_open
=
bochs_open
,
.
bdrv_read
=
bochs_read
,
.
bdrv_read
=
bochs_read
,
.
bdrv_close
=
bochs_close
,
.
bdrv_close
=
bochs_close
,
};
};
...
...
block/cloop.c
浏览文件 @
72375c22
...
@@ -158,7 +158,7 @@ static BlockDriver bdrv_cloop = {
...
@@ -158,7 +158,7 @@ static BlockDriver bdrv_cloop = {
.
format_name
=
"cloop"
,
.
format_name
=
"cloop"
,
.
instance_size
=
sizeof
(
BDRVCloopState
),
.
instance_size
=
sizeof
(
BDRVCloopState
),
.
bdrv_probe
=
cloop_probe
,
.
bdrv_probe
=
cloop_probe
,
.
bdrv_
open
=
cloop_open
,
.
bdrv_
file_open
=
cloop_open
,
.
bdrv_read
=
cloop_read
,
.
bdrv_read
=
cloop_read
,
.
bdrv_close
=
cloop_close
,
.
bdrv_close
=
cloop_close
,
};
};
...
...
block/cow.c
浏览文件 @
72375c22
...
@@ -291,7 +291,7 @@ static BlockDriver bdrv_cow = {
...
@@ -291,7 +291,7 @@ static BlockDriver bdrv_cow = {
.
format_name
=
"cow"
,
.
format_name
=
"cow"
,
.
instance_size
=
sizeof
(
BDRVCowState
),
.
instance_size
=
sizeof
(
BDRVCowState
),
.
bdrv_probe
=
cow_probe
,
.
bdrv_probe
=
cow_probe
,
.
bdrv_
open
=
cow_open
,
.
bdrv_
file_open
=
cow_open
,
.
bdrv_read
=
cow_read
,
.
bdrv_read
=
cow_read
,
.
bdrv_write
=
cow_write
,
.
bdrv_write
=
cow_write
,
.
bdrv_close
=
cow_close
,
.
bdrv_close
=
cow_close
,
...
...
block/curl.c
浏览文件 @
72375c22
...
@@ -495,7 +495,7 @@ static BlockDriver bdrv_http = {
...
@@ -495,7 +495,7 @@ static BlockDriver bdrv_http = {
.
protocol_name
=
"http"
,
.
protocol_name
=
"http"
,
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
bdrv_
open
=
curl_open
,
.
bdrv_
file_open
=
curl_open
,
.
bdrv_close
=
curl_close
,
.
bdrv_close
=
curl_close
,
.
bdrv_getlength
=
curl_getlength
,
.
bdrv_getlength
=
curl_getlength
,
...
@@ -507,7 +507,7 @@ static BlockDriver bdrv_https = {
...
@@ -507,7 +507,7 @@ static BlockDriver bdrv_https = {
.
protocol_name
=
"https"
,
.
protocol_name
=
"https"
,
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
bdrv_
open
=
curl_open
,
.
bdrv_
file_open
=
curl_open
,
.
bdrv_close
=
curl_close
,
.
bdrv_close
=
curl_close
,
.
bdrv_getlength
=
curl_getlength
,
.
bdrv_getlength
=
curl_getlength
,
...
@@ -519,7 +519,7 @@ static BlockDriver bdrv_ftp = {
...
@@ -519,7 +519,7 @@ static BlockDriver bdrv_ftp = {
.
protocol_name
=
"ftp"
,
.
protocol_name
=
"ftp"
,
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
bdrv_
open
=
curl_open
,
.
bdrv_
file_open
=
curl_open
,
.
bdrv_close
=
curl_close
,
.
bdrv_close
=
curl_close
,
.
bdrv_getlength
=
curl_getlength
,
.
bdrv_getlength
=
curl_getlength
,
...
@@ -531,7 +531,7 @@ static BlockDriver bdrv_ftps = {
...
@@ -531,7 +531,7 @@ static BlockDriver bdrv_ftps = {
.
protocol_name
=
"ftps"
,
.
protocol_name
=
"ftps"
,
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
bdrv_
open
=
curl_open
,
.
bdrv_
file_open
=
curl_open
,
.
bdrv_close
=
curl_close
,
.
bdrv_close
=
curl_close
,
.
bdrv_getlength
=
curl_getlength
,
.
bdrv_getlength
=
curl_getlength
,
...
@@ -543,7 +543,7 @@ static BlockDriver bdrv_tftp = {
...
@@ -543,7 +543,7 @@ static BlockDriver bdrv_tftp = {
.
protocol_name
=
"tftp"
,
.
protocol_name
=
"tftp"
,
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
instance_size
=
sizeof
(
BDRVCURLState
),
.
bdrv_
open
=
curl_open
,
.
bdrv_
file_open
=
curl_open
,
.
bdrv_close
=
curl_close
,
.
bdrv_close
=
curl_close
,
.
bdrv_getlength
=
curl_getlength
,
.
bdrv_getlength
=
curl_getlength
,
...
...
block/dmg.c
浏览文件 @
72375c22
...
@@ -288,7 +288,7 @@ static BlockDriver bdrv_dmg = {
...
@@ -288,7 +288,7 @@ static BlockDriver bdrv_dmg = {
.
format_name
=
"dmg"
,
.
format_name
=
"dmg"
,
.
instance_size
=
sizeof
(
BDRVDMGState
),
.
instance_size
=
sizeof
(
BDRVDMGState
),
.
bdrv_probe
=
dmg_probe
,
.
bdrv_probe
=
dmg_probe
,
.
bdrv_
open
=
dmg_open
,
.
bdrv_
file_open
=
dmg_open
,
.
bdrv_read
=
dmg_read
,
.
bdrv_read
=
dmg_read
,
.
bdrv_close
=
dmg_close
,
.
bdrv_close
=
dmg_close
,
};
};
...
...
block/nbd.c
浏览文件 @
72375c22
...
@@ -177,7 +177,7 @@ static int64_t nbd_getlength(BlockDriverState *bs)
...
@@ -177,7 +177,7 @@ static int64_t nbd_getlength(BlockDriverState *bs)
static
BlockDriver
bdrv_nbd
=
{
static
BlockDriver
bdrv_nbd
=
{
.
format_name
=
"nbd"
,
.
format_name
=
"nbd"
,
.
instance_size
=
sizeof
(
BDRVNBDState
),
.
instance_size
=
sizeof
(
BDRVNBDState
),
.
bdrv_
open
=
nbd_open
,
.
bdrv_
file_open
=
nbd_open
,
.
bdrv_read
=
nbd_read
,
.
bdrv_read
=
nbd_read
,
.
bdrv_write
=
nbd_write
,
.
bdrv_write
=
nbd_write
,
.
bdrv_close
=
nbd_close
,
.
bdrv_close
=
nbd_close
,
...
...
block/parallels.c
浏览文件 @
72375c22
...
@@ -167,7 +167,7 @@ static BlockDriver bdrv_parallels = {
...
@@ -167,7 +167,7 @@ static BlockDriver bdrv_parallels = {
.
format_name
=
"parallels"
,
.
format_name
=
"parallels"
,
.
instance_size
=
sizeof
(
BDRVParallelsState
),
.
instance_size
=
sizeof
(
BDRVParallelsState
),
.
bdrv_probe
=
parallels_probe
,
.
bdrv_probe
=
parallels_probe
,
.
bdrv_
open
=
parallels_open
,
.
bdrv_
file_open
=
parallels_open
,
.
bdrv_read
=
parallels_read
,
.
bdrv_read
=
parallels_read
,
.
bdrv_close
=
parallels_close
,
.
bdrv_close
=
parallels_close
,
};
};
...
...
block/qcow.c
浏览文件 @
72375c22
...
@@ -76,7 +76,7 @@ typedef struct BDRVQcowState {
...
@@ -76,7 +76,7 @@ typedef struct BDRVQcowState {
AES_KEY
aes_decrypt_key
;
AES_KEY
aes_decrypt_key
;
}
BDRVQcowState
;
}
BDRVQcowState
;
static
int
decompress_cluster
(
B
DRVQcowState
*
s
,
uint64_t
cluster_offset
);
static
int
decompress_cluster
(
B
lockDriverState
*
b
s
,
uint64_t
cluster_offset
);
static
int
qcow_probe
(
const
uint8_t
*
buf
,
int
buf_size
,
const
char
*
filename
)
static
int
qcow_probe
(
const
uint8_t
*
buf
,
int
buf_size
,
const
char
*
filename
)
{
{
...
@@ -90,16 +90,13 @@ static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
...
@@ -90,16 +90,13 @@ static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
return
0
;
return
0
;
}
}
static
int
qcow_open
(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
)
static
int
qcow_open
(
BlockDriverState
*
bs
,
int
flags
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
BDRVQcowState
*
s
=
bs
->
opaque
;
int
len
,
i
,
shift
,
ret
;
int
len
,
i
,
shift
;
QCowHeader
header
;
QCowHeader
header
;
ret
=
bdrv_file_open
(
&
s
->
hd
,
filename
,
flags
);
if
(
bdrv_pread
(
bs
->
file
,
0
,
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
if
(
ret
<
0
)
return
ret
;
if
(
bdrv_pread
(
s
->
hd
,
0
,
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
goto
fail
;
goto
fail
;
be32_to_cpus
(
&
header
.
magic
);
be32_to_cpus
(
&
header
.
magic
);
be32_to_cpus
(
&
header
.
version
);
be32_to_cpus
(
&
header
.
version
);
...
@@ -135,7 +132,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -135,7 +132,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
s
->
l1_table
=
qemu_malloc
(
s
->
l1_size
*
sizeof
(
uint64_t
));
s
->
l1_table
=
qemu_malloc
(
s
->
l1_size
*
sizeof
(
uint64_t
));
if
(
!
s
->
l1_table
)
if
(
!
s
->
l1_table
)
goto
fail
;
goto
fail
;
if
(
bdrv_pread
(
s
->
hd
,
s
->
l1_table_offset
,
s
->
l1_table
,
s
->
l1_size
*
sizeof
(
uint64_t
))
!=
if
(
bdrv_pread
(
bs
->
file
,
s
->
l1_table_offset
,
s
->
l1_table
,
s
->
l1_size
*
sizeof
(
uint64_t
))
!=
s
->
l1_size
*
sizeof
(
uint64_t
))
s
->
l1_size
*
sizeof
(
uint64_t
))
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
...
@@ -158,7 +155,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -158,7 +155,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
len
=
header
.
backing_file_size
;
len
=
header
.
backing_file_size
;
if
(
len
>
1023
)
if
(
len
>
1023
)
len
=
1023
;
len
=
1023
;
if
(
bdrv_pread
(
s
->
hd
,
header
.
backing_file_offset
,
bs
->
backing_file
,
len
)
!=
len
)
if
(
bdrv_pread
(
bs
->
file
,
header
.
backing_file_offset
,
bs
->
backing_file
,
len
)
!=
len
)
goto
fail
;
goto
fail
;
bs
->
backing_file
[
len
]
=
'\0'
;
bs
->
backing_file
[
len
]
=
'\0'
;
}
}
...
@@ -169,7 +166,6 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -169,7 +166,6 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
qemu_free
(
s
->
l2_cache
);
qemu_free
(
s
->
l2_cache
);
qemu_free
(
s
->
cluster_cache
);
qemu_free
(
s
->
cluster_cache
);
qemu_free
(
s
->
cluster_data
);
qemu_free
(
s
->
cluster_data
);
bdrv_delete
(
s
->
hd
);
return
-
1
;
return
-
1
;
}
}
...
@@ -271,13 +267,13 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
...
@@ -271,13 +267,13 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
if
(
!
allocate
)
if
(
!
allocate
)
return
0
;
return
0
;
/* allocate a new l2 entry */
/* allocate a new l2 entry */
l2_offset
=
bdrv_getlength
(
s
->
hd
);
l2_offset
=
bdrv_getlength
(
bs
->
file
);
/* round to cluster size */
/* round to cluster size */
l2_offset
=
(
l2_offset
+
s
->
cluster_size
-
1
)
&
~
(
s
->
cluster_size
-
1
);
l2_offset
=
(
l2_offset
+
s
->
cluster_size
-
1
)
&
~
(
s
->
cluster_size
-
1
);
/* update the L1 entry */
/* update the L1 entry */
s
->
l1_table
[
l1_index
]
=
l2_offset
;
s
->
l1_table
[
l1_index
]
=
l2_offset
;
tmp
=
cpu_to_be64
(
l2_offset
);
tmp
=
cpu_to_be64
(
l2_offset
);
if
(
bdrv_pwrite
(
s
->
hd
,
s
->
l1_table_offset
+
l1_index
*
sizeof
(
tmp
),
if
(
bdrv_pwrite
(
bs
->
file
,
s
->
l1_table_offset
+
l1_index
*
sizeof
(
tmp
),
&
tmp
,
sizeof
(
tmp
))
!=
sizeof
(
tmp
))
&
tmp
,
sizeof
(
tmp
))
!=
sizeof
(
tmp
))
return
0
;
return
0
;
new_l2_table
=
1
;
new_l2_table
=
1
;
...
@@ -306,11 +302,11 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
...
@@ -306,11 +302,11 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
l2_table
=
s
->
l2_cache
+
(
min_index
<<
s
->
l2_bits
);
l2_table
=
s
->
l2_cache
+
(
min_index
<<
s
->
l2_bits
);
if
(
new_l2_table
)
{
if
(
new_l2_table
)
{
memset
(
l2_table
,
0
,
s
->
l2_size
*
sizeof
(
uint64_t
));
memset
(
l2_table
,
0
,
s
->
l2_size
*
sizeof
(
uint64_t
));
if
(
bdrv_pwrite
(
s
->
hd
,
l2_offset
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint64_t
))
!=
if
(
bdrv_pwrite
(
bs
->
file
,
l2_offset
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint64_t
))
!=
s
->
l2_size
*
sizeof
(
uint64_t
))
s
->
l2_size
*
sizeof
(
uint64_t
))
return
0
;
return
0
;
}
else
{
}
else
{
if
(
bdrv_pread
(
s
->
hd
,
l2_offset
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint64_t
))
!=
if
(
bdrv_pread
(
bs
->
file
,
l2_offset
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint64_t
))
!=
s
->
l2_size
*
sizeof
(
uint64_t
))
s
->
l2_size
*
sizeof
(
uint64_t
))
return
0
;
return
0
;
}
}
...
@@ -329,22 +325,22 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
...
@@ -329,22 +325,22 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
/* if the cluster is already compressed, we must
/* if the cluster is already compressed, we must
decompress it in the case it is not completely
decompress it in the case it is not completely
overwritten */
overwritten */
if
(
decompress_cluster
(
s
,
cluster_offset
)
<
0
)
if
(
decompress_cluster
(
b
s
,
cluster_offset
)
<
0
)
return
0
;
return
0
;
cluster_offset
=
bdrv_getlength
(
s
->
hd
);
cluster_offset
=
bdrv_getlength
(
bs
->
file
);
cluster_offset
=
(
cluster_offset
+
s
->
cluster_size
-
1
)
&
cluster_offset
=
(
cluster_offset
+
s
->
cluster_size
-
1
)
&
~
(
s
->
cluster_size
-
1
);
~
(
s
->
cluster_size
-
1
);
/* write the cluster content */
/* write the cluster content */
if
(
bdrv_pwrite
(
s
->
hd
,
cluster_offset
,
s
->
cluster_cache
,
s
->
cluster_size
)
!=
if
(
bdrv_pwrite
(
bs
->
file
,
cluster_offset
,
s
->
cluster_cache
,
s
->
cluster_size
)
!=
s
->
cluster_size
)
s
->
cluster_size
)
return
-
1
;
return
-
1
;
}
else
{
}
else
{
cluster_offset
=
bdrv_getlength
(
s
->
hd
);
cluster_offset
=
bdrv_getlength
(
bs
->
file
);
if
(
allocate
==
1
)
{
if
(
allocate
==
1
)
{
/* round to cluster size */
/* round to cluster size */
cluster_offset
=
(
cluster_offset
+
s
->
cluster_size
-
1
)
&
cluster_offset
=
(
cluster_offset
+
s
->
cluster_size
-
1
)
&
~
(
s
->
cluster_size
-
1
);
~
(
s
->
cluster_size
-
1
);
bdrv_truncate
(
s
->
hd
,
cluster_offset
+
s
->
cluster_size
);
bdrv_truncate
(
bs
->
file
,
cluster_offset
+
s
->
cluster_size
);
/* if encrypted, we must initialize the cluster
/* if encrypted, we must initialize the cluster
content which won't be written */
content which won't be written */
if
(
s
->
crypt_method
&&
if
(
s
->
crypt_method
&&
...
@@ -358,7 +354,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
...
@@ -358,7 +354,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
s
->
cluster_data
,
s
->
cluster_data
,
s
->
cluster_data
+
512
,
1
,
1
,
s
->
cluster_data
+
512
,
1
,
1
,
&
s
->
aes_encrypt_key
);
&
s
->
aes_encrypt_key
);
if
(
bdrv_pwrite
(
s
->
hd
,
cluster_offset
+
i
*
512
,
if
(
bdrv_pwrite
(
bs
->
file
,
cluster_offset
+
i
*
512
,
s
->
cluster_data
,
512
)
!=
512
)
s
->
cluster_data
,
512
)
!=
512
)
return
-
1
;
return
-
1
;
}
}
...
@@ -372,7 +368,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
...
@@ -372,7 +368,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
/* update L2 table */
/* update L2 table */
tmp
=
cpu_to_be64
(
cluster_offset
);
tmp
=
cpu_to_be64
(
cluster_offset
);
l2_table
[
l2_index
]
=
tmp
;
l2_table
[
l2_index
]
=
tmp
;
if
(
bdrv_pwrite
(
s
->
hd
,
if
(
bdrv_pwrite
(
bs
->
file
,
l2_offset
+
l2_index
*
sizeof
(
tmp
),
&
tmp
,
sizeof
(
tmp
))
!=
sizeof
(
tmp
))
l2_offset
+
l2_index
*
sizeof
(
tmp
),
&
tmp
,
sizeof
(
tmp
))
!=
sizeof
(
tmp
))
return
0
;
return
0
;
}
}
...
@@ -422,8 +418,9 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
...
@@ -422,8 +418,9 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
return
0
;
return
0
;
}
}
static
int
decompress_cluster
(
B
DRVQcowState
*
s
,
uint64_t
cluster_offset
)
static
int
decompress_cluster
(
B
lockDriverState
*
b
s
,
uint64_t
cluster_offset
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
int
ret
,
csize
;
int
ret
,
csize
;
uint64_t
coffset
;
uint64_t
coffset
;
...
@@ -431,7 +428,7 @@ static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
...
@@ -431,7 +428,7 @@ static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
if
(
s
->
cluster_cache_offset
!=
coffset
)
{
if
(
s
->
cluster_cache_offset
!=
coffset
)
{
csize
=
cluster_offset
>>
(
63
-
s
->
cluster_bits
);
csize
=
cluster_offset
>>
(
63
-
s
->
cluster_bits
);
csize
&=
(
s
->
cluster_size
-
1
);
csize
&=
(
s
->
cluster_size
-
1
);
ret
=
bdrv_pread
(
s
->
hd
,
coffset
,
s
->
cluster_data
,
csize
);
ret
=
bdrv_pread
(
bs
->
file
,
coffset
,
s
->
cluster_data
,
csize
);
if
(
ret
!=
csize
)
if
(
ret
!=
csize
)
return
-
1
;
return
-
1
;
if
(
decompress_buffer
(
s
->
cluster_cache
,
s
->
cluster_size
,
if
(
decompress_buffer
(
s
->
cluster_cache
,
s
->
cluster_size
,
...
@@ -468,11 +465,11 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
...
@@ -468,11 +465,11 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
memset(buf, 0, 512 * n);
memset(buf, 0, 512 * n);
}
}
} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
if (decompress_cluster(s, cluster_offset) < 0)
if (decompress_cluster(
b
s, cluster_offset) < 0)
return -1;
return -1;
memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
} else {
} else {
ret = bdrv_pread(
s->hd
, cluster_offset + index_in_cluster * 512, buf, n * 512);
ret = bdrv_pread(
bs->file
, cluster_offset + index_in_cluster * 512, buf, n * 512);
if (ret != n * 512)
if (ret != n * 512)
return -1;
return -1;
if (s->crypt_method) {
if (s->crypt_method) {
...
@@ -601,7 +598,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
...
@@ -601,7 +598,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
}
}
}
else
if
(
acb
->
cluster_offset
&
QCOW_OFLAG_COMPRESSED
)
{
}
else
if
(
acb
->
cluster_offset
&
QCOW_OFLAG_COMPRESSED
)
{
/* add AIO support for compressed blocks ? */
/* add AIO support for compressed blocks ? */
if
(
decompress_cluster
(
s
,
acb
->
cluster_offset
)
<
0
)
if
(
decompress_cluster
(
b
s
,
acb
->
cluster_offset
)
<
0
)
goto
done
;
goto
done
;
memcpy
(
acb
->
buf
,
memcpy
(
acb
->
buf
,
s
->
cluster_cache
+
index_in_cluster
*
512
,
512
*
acb
->
n
);
s
->
cluster_cache
+
index_in_cluster
*
512
,
512
*
acb
->
n
);
...
@@ -614,7 +611,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
...
@@ -614,7 +611,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_len
=
acb
->
n
*
512
;
acb
->
hd_iov
.
iov_len
=
acb
->
n
*
512
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
acb
->
hd_aiocb
=
bdrv_aio_readv
(
s
->
hd
,
acb
->
hd_aiocb
=
bdrv_aio_readv
(
bs
->
file
,
(
acb
->
cluster_offset
>>
9
)
+
index_in_cluster
,
(
acb
->
cluster_offset
>>
9
)
+
index_in_cluster
,
&
acb
->
hd_qiov
,
acb
->
n
,
qcow_aio_read_cb
,
acb
);
&
acb
->
hd_qiov
,
acb
->
n
,
qcow_aio_read_cb
,
acb
);
if
(
acb
->
hd_aiocb
==
NULL
)
if
(
acb
->
hd_aiocb
==
NULL
)
...
@@ -699,7 +696,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
...
@@ -699,7 +696,7 @@ static void qcow_aio_write_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
(
void
*
)
src_buf
;
acb
->
hd_iov
.
iov_base
=
(
void
*
)
src_buf
;
acb
->
hd_iov
.
iov_len
=
acb
->
n
*
512
;
acb
->
hd_iov
.
iov_len
=
acb
->
n
*
512
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
acb
->
hd_aiocb
=
bdrv_aio_writev
(
s
->
hd
,
acb
->
hd_aiocb
=
bdrv_aio_writev
(
bs
->
file
,
(
cluster_offset
>>
9
)
+
index_in_cluster
,
(
cluster_offset
>>
9
)
+
index_in_cluster
,
&
acb
->
hd_qiov
,
acb
->
n
,
&
acb
->
hd_qiov
,
acb
->
n
,
qcow_aio_write_cb
,
acb
);
qcow_aio_write_cb
,
acb
);
...
@@ -739,7 +736,6 @@ static void qcow_close(BlockDriverState *bs)
...
@@ -739,7 +736,6 @@ static void qcow_close(BlockDriverState *bs)
qemu_free
(
s
->
l2_cache
);
qemu_free
(
s
->
l2_cache
);
qemu_free
(
s
->
cluster_cache
);
qemu_free
(
s
->
cluster_cache
);
qemu_free
(
s
->
cluster_data
);
qemu_free
(
s
->
cluster_data
);
bdrv_delete
(
s
->
hd
);
}
}
static
int
qcow_create
(
const
char
*
filename
,
QEMUOptionParameter
*
options
)
static
int
qcow_create
(
const
char
*
filename
,
QEMUOptionParameter
*
options
)
...
@@ -839,9 +835,9 @@ static int qcow_make_empty(BlockDriverState *bs)
...
@@ -839,9 +835,9 @@ static int qcow_make_empty(BlockDriverState *bs)
int
ret
;
int
ret
;
memset
(
s
->
l1_table
,
0
,
l1_length
);
memset
(
s
->
l1_table
,
0
,
l1_length
);
if
(
bdrv_pwrite
(
s
->
hd
,
s
->
l1_table_offset
,
s
->
l1_table
,
l1_length
)
<
0
)
if
(
bdrv_pwrite
(
bs
->
file
,
s
->
l1_table_offset
,
s
->
l1_table
,
l1_length
)
<
0
)
return
-
1
;
return
-
1
;
ret
=
bdrv_truncate
(
s
->
hd
,
s
->
l1_table_offset
+
l1_length
);
ret
=
bdrv_truncate
(
bs
->
file
,
s
->
l1_table_offset
+
l1_length
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -902,7 +898,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
...
@@ -902,7 +898,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
cluster_offset
=
get_cluster_offset
(
bs
,
sector_num
<<
9
,
2
,
cluster_offset
=
get_cluster_offset
(
bs
,
sector_num
<<
9
,
2
,
out_len
,
0
,
0
);
out_len
,
0
,
0
);
cluster_offset
&=
s
->
cluster_offset_mask
;
cluster_offset
&=
s
->
cluster_offset_mask
;
if
(
bdrv_pwrite
(
s
->
hd
,
cluster_offset
,
out_buf
,
out_len
)
!=
out_len
)
{
if
(
bdrv_pwrite
(
bs
->
file
,
cluster_offset
,
out_buf
,
out_len
)
!=
out_len
)
{
qemu_free
(
out_buf
);
qemu_free
(
out_buf
);
return
-
1
;
return
-
1
;
}
}
...
@@ -914,16 +910,13 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
...
@@ -914,16 +910,13 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
static
void
qcow_flush
(
BlockDriverState
*
bs
)
static
void
qcow_flush
(
BlockDriverState
*
bs
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
bdrv_flush
(
bs
->
file
);
bdrv_flush
(
s
->
hd
);
}
}
static
BlockDriverAIOCB
*
qcow_aio_flush
(
BlockDriverState
*
bs
,
static
BlockDriverAIOCB
*
qcow_aio_flush
(
BlockDriverState
*
bs
,
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
return
bdrv_aio_flush
(
bs
->
file
,
cb
,
opaque
);
return
bdrv_aio_flush
(
s
->
hd
,
cb
,
opaque
);
}
}
static
int
qcow_get_info
(
BlockDriverState
*
bs
,
BlockDriverInfo
*
bdi
)
static
int
qcow_get_info
(
BlockDriverState
*
bs
,
BlockDriverInfo
*
bdi
)
...
...
block/qcow2-cluster.c
浏览文件 @
72375c22
...
@@ -54,27 +54,27 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
...
@@ -54,27 +54,27 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
memcpy
(
new_l1_table
,
s
->
l1_table
,
s
->
l1_size
*
sizeof
(
uint64_t
));
memcpy
(
new_l1_table
,
s
->
l1_table
,
s
->
l1_size
*
sizeof
(
uint64_t
));
/* write new table (align to cluster) */
/* write new table (align to cluster) */
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L1_GROW_ALLOC_TABLE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L1_GROW_ALLOC_TABLE
);
new_l1_table_offset
=
qcow2_alloc_clusters
(
bs
,
new_l1_size2
);
new_l1_table_offset
=
qcow2_alloc_clusters
(
bs
,
new_l1_size2
);
if
(
new_l1_table_offset
<
0
)
{
if
(
new_l1_table_offset
<
0
)
{
qemu_free
(
new_l1_table
);
qemu_free
(
new_l1_table
);
return
new_l1_table_offset
;
return
new_l1_table_offset
;
}
}
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L1_GROW_WRITE_TABLE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L1_GROW_WRITE_TABLE
);
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
new_l1_table
[
i
]
=
cpu_to_be64
(
new_l1_table
[
i
]);
new_l1_table
[
i
]
=
cpu_to_be64
(
new_l1_table
[
i
]);
ret
=
bdrv_pwrite
(
s
->
hd
,
new_l1_table_offset
,
new_l1_table
,
new_l1_size2
);
ret
=
bdrv_pwrite
(
bs
->
file
,
new_l1_table_offset
,
new_l1_table
,
new_l1_size2
);
if
(
ret
!=
new_l1_size2
)
if
(
ret
!=
new_l1_size2
)
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
new_l1_table
[
i
]
=
be64_to_cpu
(
new_l1_table
[
i
]);
new_l1_table
[
i
]
=
be64_to_cpu
(
new_l1_table
[
i
]);
/* set new table */
/* set new table */
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L1_GROW_ACTIVATE_TABLE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L1_GROW_ACTIVATE_TABLE
);
cpu_to_be32w
((
uint32_t
*
)
data
,
new_l1_size
);
cpu_to_be32w
((
uint32_t
*
)
data
,
new_l1_size
);
cpu_to_be64w
((
uint64_t
*
)(
data
+
4
),
new_l1_table_offset
);
cpu_to_be64w
((
uint64_t
*
)(
data
+
4
),
new_l1_table_offset
);
ret
=
bdrv_pwrite
(
s
->
hd
,
offsetof
(
QCowHeader
,
l1_size
),
data
,
sizeof
(
data
));
ret
=
bdrv_pwrite
(
bs
->
file
,
offsetof
(
QCowHeader
,
l1_size
),
data
,
sizeof
(
data
));
if
(
ret
!=
sizeof
(
data
))
{
if
(
ret
!=
sizeof
(
data
))
{
goto
fail
;
goto
fail
;
}
}
...
@@ -174,8 +174,8 @@ static uint64_t *l2_load(BlockDriverState *bs, uint64_t l2_offset)
...
@@ -174,8 +174,8 @@ static uint64_t *l2_load(BlockDriverState *bs, uint64_t l2_offset)
min_index
=
l2_cache_new_entry
(
bs
);
min_index
=
l2_cache_new_entry
(
bs
);
l2_table
=
s
->
l2_cache
+
(
min_index
<<
s
->
l2_bits
);
l2_table
=
s
->
l2_cache
+
(
min_index
<<
s
->
l2_bits
);
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L2_LOAD
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L2_LOAD
);
if
(
bdrv_pread
(
s
->
hd
,
l2_offset
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint64_t
))
!=
if
(
bdrv_pread
(
bs
->
file
,
l2_offset
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint64_t
))
!=
s
->
l2_size
*
sizeof
(
uint64_t
))
s
->
l2_size
*
sizeof
(
uint64_t
))
return
NULL
;
return
NULL
;
s
->
l2_cache_offsets
[
min_index
]
=
l2_offset
;
s
->
l2_cache_offsets
[
min_index
]
=
l2_offset
;
...
@@ -189,8 +189,9 @@ static uint64_t *l2_load(BlockDriverState *bs, uint64_t l2_offset)
...
@@ -189,8 +189,9 @@ static uint64_t *l2_load(BlockDriverState *bs, uint64_t l2_offset)
* and we really don't want bdrv_pread to perform a read-modify-write)
* and we really don't want bdrv_pread to perform a read-modify-write)
*/
*/
#define L1_ENTRIES_PER_SECTOR (512 / 8)
#define L1_ENTRIES_PER_SECTOR (512 / 8)
static
int
write_l1_entry
(
B
DRVQcowState
*
s
,
int
l1_index
)
static
int
write_l1_entry
(
B
lockDriverState
*
b
s
,
int
l1_index
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
uint64_t
buf
[
L1_ENTRIES_PER_SECTOR
];
uint64_t
buf
[
L1_ENTRIES_PER_SECTOR
];
int
l1_start_index
;
int
l1_start_index
;
int
i
,
ret
;
int
i
,
ret
;
...
@@ -200,8 +201,8 @@ static int write_l1_entry(BDRVQcowState *s, int l1_index)
...
@@ -200,8 +201,8 @@ static int write_l1_entry(BDRVQcowState *s, int l1_index)
buf
[
i
]
=
cpu_to_be64
(
s
->
l1_table
[
l1_start_index
+
i
]);
buf
[
i
]
=
cpu_to_be64
(
s
->
l1_table
[
l1_start_index
+
i
]);
}
}
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L1_UPDATE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L1_UPDATE
);
ret
=
bdrv_pwrite
(
s
->
hd
,
s
->
l1_table_offset
+
8
*
l1_start_index
,
ret
=
bdrv_pwrite
(
bs
->
file
,
s
->
l1_table_offset
+
8
*
l1_start_index
,
buf
,
sizeof
(
buf
));
buf
,
sizeof
(
buf
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
...
@@ -241,7 +242,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
...
@@ -241,7 +242,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
/* update the L1 entry */
/* update the L1 entry */
s
->
l1_table
[
l1_index
]
=
l2_offset
|
QCOW_OFLAG_COPIED
;
s
->
l1_table
[
l1_index
]
=
l2_offset
|
QCOW_OFLAG_COPIED
;
ret
=
write_l1_entry
(
s
,
l1_index
);
ret
=
write_l1_entry
(
b
s
,
l1_index
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
}
}
...
@@ -256,16 +257,16 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
...
@@ -256,16 +257,16 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
memset
(
l2_table
,
0
,
s
->
l2_size
*
sizeof
(
uint64_t
));
memset
(
l2_table
,
0
,
s
->
l2_size
*
sizeof
(
uint64_t
));
}
else
{
}
else
{
/* if there was an old l2 table, read it from the disk */
/* if there was an old l2 table, read it from the disk */
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L2_ALLOC_COW_READ
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L2_ALLOC_COW_READ
);
ret
=
bdrv_pread
(
s
->
hd
,
old_l2_offset
,
l2_table
,
ret
=
bdrv_pread
(
bs
->
file
,
old_l2_offset
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint64_t
));
s
->
l2_size
*
sizeof
(
uint64_t
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
}
}
}
}
/* write the l2 table to the file */
/* write the l2 table to the file */
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L2_ALLOC_WRITE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L2_ALLOC_WRITE
);
ret
=
bdrv_pwrite
(
s
->
hd
,
l2_offset
,
l2_table
,
ret
=
bdrv_pwrite
(
bs
->
file
,
l2_offset
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint64_t
));
s
->
l2_size
*
sizeof
(
uint64_t
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
...
@@ -348,7 +349,7 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
...
@@ -348,7 +349,7 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
/* read from the base image */
/* read from the base image */
n1
=
qcow2_backing_read1
(
bs
->
backing_hd
,
sector_num
,
buf
,
n
);
n1
=
qcow2_backing_read1
(
bs
->
backing_hd
,
sector_num
,
buf
,
n
);
if
(
n1
>
0
)
{
if
(
n1
>
0
)
{
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_READ_BACKING
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_READ_BACKING
);
ret
=
bdrv_read
(
bs
->
backing_hd
,
sector_num
,
buf
,
n1
);
ret
=
bdrv_read
(
bs
->
backing_hd
,
sector_num
,
buf
,
n1
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
1
;
return
-
1
;
...
@@ -357,12 +358,12 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
...
@@ -357,12 +358,12 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
memset
(
buf
,
0
,
512
*
n
);
memset
(
buf
,
0
,
512
*
n
);
}
}
}
else
if
(
cluster_offset
&
QCOW_OFLAG_COMPRESSED
)
{
}
else
if
(
cluster_offset
&
QCOW_OFLAG_COMPRESSED
)
{
if
(
qcow2_decompress_cluster
(
s
,
cluster_offset
)
<
0
)
if
(
qcow2_decompress_cluster
(
b
s
,
cluster_offset
)
<
0
)
return
-
1
;
return
-
1
;
memcpy
(
buf
,
s
->
cluster_cache
+
index_in_cluster
*
512
,
512
*
n
);
memcpy
(
buf
,
s
->
cluster_cache
+
index_in_cluster
*
512
,
512
*
n
);
}
else
{
}
else
{
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_READ
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_READ
);
ret
=
bdrv_pread
(
s
->
hd
,
cluster_offset
+
index_in_cluster
*
512
,
buf
,
n
*
512
);
ret
=
bdrv_pread
(
bs
->
file
,
cluster_offset
+
index_in_cluster
*
512
,
buf
,
n
*
512
);
if
(
ret
!=
n
*
512
)
if
(
ret
!=
n
*
512
)
return
-
1
;
return
-
1
;
if
(
s
->
crypt_method
)
{
if
(
s
->
crypt_method
)
{
...
@@ -386,7 +387,7 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
...
@@ -386,7 +387,7 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
n
=
n_end
-
n_start
;
n
=
n_end
-
n_start
;
if
(
n
<=
0
)
if
(
n
<=
0
)
return
0
;
return
0
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_COW_READ
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_COW_READ
);
ret
=
qcow_read
(
bs
,
start_sect
+
n_start
,
s
->
cluster_data
,
n
);
ret
=
qcow_read
(
bs
,
start_sect
+
n_start
,
s
->
cluster_data
,
n
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -396,8 +397,8 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
...
@@ -396,8 +397,8 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
s
->
cluster_data
,
n
,
1
,
s
->
cluster_data
,
n
,
1
,
&
s
->
aes_encrypt_key
);
&
s
->
aes_encrypt_key
);
}
}
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_COW_WRITE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_COW_WRITE
);
ret
=
bdrv_write
(
s
->
hd
,
(
cluster_offset
>>
9
)
+
n_start
,
ret
=
bdrv_write
(
bs
->
file
,
(
cluster_offset
>>
9
)
+
n_start
,
s
->
cluster_data
,
n
);
s
->
cluster_data
,
n
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -610,9 +611,9 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
...
@@ -610,9 +611,9 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
/* compressed clusters never have the copied flag */
/* compressed clusters never have the copied flag */
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L2_UPDATE_COMPRESSED
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L2_UPDATE_COMPRESSED
);
l2_table
[
l2_index
]
=
cpu_to_be64
(
cluster_offset
);
l2_table
[
l2_index
]
=
cpu_to_be64
(
cluster_offset
);
if
(
bdrv_pwrite
(
s
->
hd
,
if
(
bdrv_pwrite
(
bs
->
file
,
l2_offset
+
l2_index
*
sizeof
(
uint64_t
),
l2_offset
+
l2_index
*
sizeof
(
uint64_t
),
l2_table
+
l2_index
,
l2_table
+
l2_index
,
sizeof
(
uint64_t
))
!=
sizeof
(
uint64_t
))
sizeof
(
uint64_t
))
!=
sizeof
(
uint64_t
))
...
@@ -626,7 +627,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
...
@@ -626,7 +627,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
* read-modify-write in bdrv_pwrite
* read-modify-write in bdrv_pwrite
*/
*/
#define L2_ENTRIES_PER_SECTOR (512 / 8)
#define L2_ENTRIES_PER_SECTOR (512 / 8)
static
int
write_l2_entries
(
B
DRVQcowState
*
s
,
uint64_t
*
l2_table
,
static
int
write_l2_entries
(
B
lockDriverState
*
b
s
,
uint64_t
*
l2_table
,
uint64_t
l2_offset
,
int
l2_index
,
int
num
)
uint64_t
l2_offset
,
int
l2_index
,
int
num
)
{
{
int
l2_start_index
=
l2_index
&
~
(
L1_ENTRIES_PER_SECTOR
-
1
);
int
l2_start_index
=
l2_index
&
~
(
L1_ENTRIES_PER_SECTOR
-
1
);
...
@@ -635,8 +636,8 @@ static int write_l2_entries(BDRVQcowState *s, uint64_t *l2_table,
...
@@ -635,8 +636,8 @@ static int write_l2_entries(BDRVQcowState *s, uint64_t *l2_table,
size_t
len
=
end_offset
-
start_offset
;
size_t
len
=
end_offset
-
start_offset
;
int
ret
;
int
ret
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_L2_UPDATE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_L2_UPDATE
);
ret
=
bdrv_pwrite
(
s
->
hd
,
l2_offset
+
start_offset
,
ret
=
bdrv_pwrite
(
bs
->
file
,
l2_offset
+
start_offset
,
&
l2_table
[
l2_start_index
],
len
);
&
l2_table
[
l2_start_index
],
len
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
...
@@ -693,7 +694,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
...
@@ -693,7 +694,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
(
i
<<
s
->
cluster_bits
))
|
QCOW_OFLAG_COPIED
);
(
i
<<
s
->
cluster_bits
))
|
QCOW_OFLAG_COPIED
);
}
}
ret
=
write_l2_entries
(
s
,
l2_table
,
l2_offset
,
l2_index
,
m
->
nb_clusters
);
ret
=
write_l2_entries
(
b
s
,
l2_table
,
l2_offset
,
l2_index
,
m
->
nb_clusters
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
err
;
goto
err
;
}
}
...
@@ -877,8 +878,9 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
...
@@ -877,8 +878,9 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
return
0
;
return
0
;
}
}
int
qcow2_decompress_cluster
(
B
DRVQcowState
*
s
,
uint64_t
cluster_offset
)
int
qcow2_decompress_cluster
(
B
lockDriverState
*
b
s
,
uint64_t
cluster_offset
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
int
ret
,
csize
,
nb_csectors
,
sector_offset
;
int
ret
,
csize
,
nb_csectors
,
sector_offset
;
uint64_t
coffset
;
uint64_t
coffset
;
...
@@ -887,8 +889,8 @@ int qcow2_decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
...
@@ -887,8 +889,8 @@ int qcow2_decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
nb_csectors
=
((
cluster_offset
>>
s
->
csize_shift
)
&
s
->
csize_mask
)
+
1
;
nb_csectors
=
((
cluster_offset
>>
s
->
csize_shift
)
&
s
->
csize_mask
)
+
1
;
sector_offset
=
coffset
&
511
;
sector_offset
=
coffset
&
511
;
csize
=
nb_csectors
*
512
-
sector_offset
;
csize
=
nb_csectors
*
512
-
sector_offset
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_READ_COMPRESSED
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_READ_COMPRESSED
);
ret
=
bdrv_read
(
s
->
hd
,
coffset
>>
9
,
s
->
cluster_data
,
nb_csectors
);
ret
=
bdrv_read
(
bs
->
file
,
coffset
>>
9
,
s
->
cluster_data
,
nb_csectors
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
-
1
;
return
-
1
;
}
}
...
...
block/qcow2-refcount.c
浏览文件 @
72375c22
...
@@ -34,16 +34,17 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
...
@@ -34,16 +34,17 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
static
int
cache_refcount_updates
=
0
;
static
int
cache_refcount_updates
=
0
;
static
int
write_refcount_block
(
B
DRVQcowState
*
s
)
static
int
write_refcount_block
(
B
lockDriverState
*
b
s
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
size_t
size
=
s
->
cluster_size
;
size_t
size
=
s
->
cluster_size
;
if
(
s
->
refcount_block_cache_offset
==
0
)
{
if
(
s
->
refcount_block_cache_offset
==
0
)
{
return
0
;
return
0
;
}
}
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_UPDATE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_UPDATE
);
if
(
bdrv_pwrite
(
s
->
hd
,
s
->
refcount_block_cache_offset
,
if
(
bdrv_pwrite
(
bs
->
file
,
s
->
refcount_block_cache_offset
,
s
->
refcount_block_cache
,
size
)
!=
size
)
s
->
refcount_block_cache
,
size
)
!=
size
)
{
{
return
-
EIO
;
return
-
EIO
;
...
@@ -64,8 +65,8 @@ int qcow2_refcount_init(BlockDriverState *bs)
...
@@ -64,8 +65,8 @@ int qcow2_refcount_init(BlockDriverState *bs)
refcount_table_size2
=
s
->
refcount_table_size
*
sizeof
(
uint64_t
);
refcount_table_size2
=
s
->
refcount_table_size
*
sizeof
(
uint64_t
);
s
->
refcount_table
=
qemu_malloc
(
refcount_table_size2
);
s
->
refcount_table
=
qemu_malloc
(
refcount_table_size2
);
if
(
s
->
refcount_table_size
>
0
)
{
if
(
s
->
refcount_table_size
>
0
)
{
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFTABLE_LOAD
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFTABLE_LOAD
);
ret
=
bdrv_pread
(
s
->
hd
,
s
->
refcount_table_offset
,
ret
=
bdrv_pread
(
bs
->
file
,
s
->
refcount_table_offset
,
s
->
refcount_table
,
refcount_table_size2
);
s
->
refcount_table
,
refcount_table_size2
);
if
(
ret
!=
refcount_table_size2
)
if
(
ret
!=
refcount_table_size2
)
goto
fail
;
goto
fail
;
...
@@ -92,11 +93,11 @@ static int load_refcount_block(BlockDriverState *bs,
...
@@ -92,11 +93,11 @@ static int load_refcount_block(BlockDriverState *bs,
int
ret
;
int
ret
;
if
(
cache_refcount_updates
)
{
if
(
cache_refcount_updates
)
{
write_refcount_block
(
s
);
write_refcount_block
(
b
s
);
}
}
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_LOAD
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_LOAD
);
ret
=
bdrv_pread
(
s
->
hd
,
refcount_block_offset
,
s
->
refcount_block_cache
,
ret
=
bdrv_pread
(
bs
->
file
,
refcount_block_offset
,
s
->
refcount_block_cache
,
s
->
cluster_size
);
s
->
cluster_size
);
if
(
ret
!=
s
->
cluster_size
)
if
(
ret
!=
s
->
cluster_size
)
return
-
EIO
;
return
-
EIO
;
...
@@ -167,7 +168,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
...
@@ -167,7 +168,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
unsigned
int
refcount_table_index
;
unsigned
int
refcount_table_index
;
int
ret
;
int
ret
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_ALLOC
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_ALLOC
);
/* Find the refcount block for the given cluster */
/* Find the refcount block for the given cluster */
refcount_table_index
=
cluster_index
>>
(
s
->
cluster_bits
-
REFCOUNT_SHIFT
);
refcount_table_index
=
cluster_index
>>
(
s
->
cluster_bits
-
REFCOUNT_SHIFT
);
...
@@ -212,7 +213,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
...
@@ -212,7 +213,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
*/
*/
if
(
cache_refcount_updates
)
{
if
(
cache_refcount_updates
)
{
ret
=
write_refcount_block
(
s
);
ret
=
write_refcount_block
(
b
s
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
}
}
...
@@ -244,8 +245,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
...
@@ -244,8 +245,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
}
}
/* Now the new refcount block needs to be written to disk */
/* Now the new refcount block needs to be written to disk */
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_ALLOC_WRITE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_ALLOC_WRITE
);
ret
=
bdrv_pwrite
(
s
->
hd
,
new_block
,
s
->
refcount_block_cache
,
ret
=
bdrv_pwrite
(
bs
->
file
,
new_block
,
s
->
refcount_block_cache
,
s
->
cluster_size
);
s
->
cluster_size
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
fail_block
;
goto
fail_block
;
...
@@ -254,8 +255,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
...
@@ -254,8 +255,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
/* If the refcount table is big enough, just hook the block up there */
/* If the refcount table is big enough, just hook the block up there */
if
(
refcount_table_index
<
s
->
refcount_table_size
)
{
if
(
refcount_table_index
<
s
->
refcount_table_size
)
{
uint64_t
data64
=
cpu_to_be64
(
new_block
);
uint64_t
data64
=
cpu_to_be64
(
new_block
);
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_ALLOC_HOOKUP
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_ALLOC_HOOKUP
);
ret
=
bdrv_pwrite
(
s
->
hd
,
ret
=
bdrv_pwrite
(
bs
->
file
,
s
->
refcount_table_offset
+
refcount_table_index
*
sizeof
(
uint64_t
),
s
->
refcount_table_offset
+
refcount_table_index
*
sizeof
(
uint64_t
),
&
data64
,
sizeof
(
data64
));
&
data64
,
sizeof
(
data64
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -277,7 +278,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
...
@@ -277,7 +278,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
* refcount table at once without producing an inconsistent state in
* refcount table at once without producing an inconsistent state in
* between.
* between.
*/
*/
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFTABLE_GROW
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFTABLE_GROW
);
/* Calculate the number of refcount blocks needed so far */
/* Calculate the number of refcount blocks needed so far */
uint64_t
refcount_block_clusters
=
1
<<
(
s
->
cluster_bits
-
REFCOUNT_SHIFT
);
uint64_t
refcount_block_clusters
=
1
<<
(
s
->
cluster_bits
-
REFCOUNT_SHIFT
);
...
@@ -334,8 +335,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
...
@@ -334,8 +335,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
}
}
/* Write refcount blocks to disk */
/* Write refcount blocks to disk */
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS
);
ret
=
bdrv_pwrite
(
s
->
hd
,
meta_offset
,
new_blocks
,
ret
=
bdrv_pwrite
(
bs
->
file
,
meta_offset
,
new_blocks
,
blocks_clusters
*
s
->
cluster_size
);
blocks_clusters
*
s
->
cluster_size
);
qemu_free
(
new_blocks
);
qemu_free
(
new_blocks
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -347,8 +348,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
...
@@ -347,8 +348,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
cpu_to_be64s
(
&
new_table
[
i
]);
cpu_to_be64s
(
&
new_table
[
i
]);
}
}
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE
);
ret
=
bdrv_pwrite
(
s
->
hd
,
table_offset
,
new_table
,
ret
=
bdrv_pwrite
(
bs
->
file
,
table_offset
,
new_table
,
table_size
*
sizeof
(
uint64_t
));
table_size
*
sizeof
(
uint64_t
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
fail_table
;
goto
fail_table
;
...
@@ -362,8 +363,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
...
@@ -362,8 +363,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
uint8_t
data
[
12
];
uint8_t
data
[
12
];
cpu_to_be64w
((
uint64_t
*
)
data
,
table_offset
);
cpu_to_be64w
((
uint64_t
*
)
data
,
table_offset
);
cpu_to_be32w
((
uint32_t
*
)(
data
+
8
),
table_clusters
);
cpu_to_be32w
((
uint32_t
*
)(
data
+
8
),
table_clusters
);
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE
);
ret
=
bdrv_pwrite
(
s
->
hd
,
offsetof
(
QCowHeader
,
refcount_table_offset
),
ret
=
bdrv_pwrite
(
bs
->
file
,
offsetof
(
QCowHeader
,
refcount_table_offset
),
data
,
sizeof
(
data
));
data
,
sizeof
(
data
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
fail_table
;
goto
fail_table
;
...
@@ -398,9 +399,10 @@ fail_block:
...
@@ -398,9 +399,10 @@ fail_block:
}
}
#define REFCOUNTS_PER_SECTOR (512 >> REFCOUNT_SHIFT)
#define REFCOUNTS_PER_SECTOR (512 >> REFCOUNT_SHIFT)
static
int
write_refcount_block_entries
(
B
DRVQcowState
*
s
,
static
int
write_refcount_block_entries
(
B
lockDriverState
*
b
s
,
int64_t
refcount_block_offset
,
int
first_index
,
int
last_index
)
int64_t
refcount_block_offset
,
int
first_index
,
int
last_index
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
size_t
size
;
size_t
size
;
if
(
cache_refcount_updates
)
{
if
(
cache_refcount_updates
)
{
...
@@ -412,8 +414,8 @@ static int write_refcount_block_entries(BDRVQcowState *s,
...
@@ -412,8 +414,8 @@ static int write_refcount_block_entries(BDRVQcowState *s,
&
~
(
REFCOUNTS_PER_SECTOR
-
1
);
&
~
(
REFCOUNTS_PER_SECTOR
-
1
);
size
=
(
last_index
-
first_index
)
<<
REFCOUNT_SHIFT
;
size
=
(
last_index
-
first_index
)
<<
REFCOUNT_SHIFT
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_REFBLOCK_UPDATE_PART
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_REFBLOCK_UPDATE_PART
);
if
(
bdrv_pwrite
(
s
->
hd
,
if
(
bdrv_pwrite
(
bs
->
file
,
refcount_block_offset
+
(
first_index
<<
REFCOUNT_SHIFT
),
refcount_block_offset
+
(
first_index
<<
REFCOUNT_SHIFT
),
&
s
->
refcount_block_cache
[
first_index
],
size
)
!=
size
)
&
s
->
refcount_block_cache
[
first_index
],
size
)
!=
size
)
{
{
...
@@ -458,7 +460,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
...
@@ -458,7 +460,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
table_index
=
cluster_index
>>
(
s
->
cluster_bits
-
REFCOUNT_SHIFT
);
table_index
=
cluster_index
>>
(
s
->
cluster_bits
-
REFCOUNT_SHIFT
);
if
((
old_table_index
>=
0
)
&&
(
table_index
!=
old_table_index
))
{
if
((
old_table_index
>=
0
)
&&
(
table_index
!=
old_table_index
))
{
if
(
write_refcount_block_entries
(
s
,
refcount_block_offset
,
if
(
write_refcount_block_entries
(
b
s
,
refcount_block_offset
,
first_index
,
last_index
)
<
0
)
first_index
,
last_index
)
<
0
)
{
{
return
-
EIO
;
return
-
EIO
;
...
@@ -503,7 +505,7 @@ fail:
...
@@ -503,7 +505,7 @@ fail:
/* Write last changed block to disk */
/* Write last changed block to disk */
if
(
refcount_block_offset
!=
0
)
{
if
(
refcount_block_offset
!=
0
)
{
if
(
write_refcount_block_entries
(
s
,
refcount_block_offset
,
if
(
write_refcount_block_entries
(
b
s
,
refcount_block_offset
,
first_index
,
last_index
)
<
0
)
first_index
,
last_index
)
<
0
)
{
{
return
ret
<
0
?
ret
:
-
EIO
;
return
ret
<
0
?
ret
:
-
EIO
;
...
@@ -554,8 +556,8 @@ static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size)
...
@@ -554,8 +556,8 @@ static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size)
nb_clusters
=
size_to_clusters
(
s
,
size
);
nb_clusters
=
size_to_clusters
(
s
,
size
);
retry:
retry:
for
(
i
=
0
;
i
<
nb_clusters
;
i
++
)
{
for
(
i
=
0
;
i
<
nb_clusters
;
i
++
)
{
int64_t
i
=
s
->
free_cluster_index
++
;
int64_t
next_cluster_index
=
s
->
free_cluster_index
++
;
if
(
get_refcount
(
bs
,
i
)
!=
0
)
if
(
get_refcount
(
bs
,
next_cluster_index
)
!=
0
)
goto
retry
;
goto
retry
;
}
}
#ifdef DEBUG_ALLOC2
#ifdef DEBUG_ALLOC2
...
@@ -568,11 +570,10 @@ retry:
...
@@ -568,11 +570,10 @@ retry:
int64_t
qcow2_alloc_clusters
(
BlockDriverState
*
bs
,
int64_t
size
)
int64_t
qcow2_alloc_clusters
(
BlockDriverState
*
bs
,
int64_t
size
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
int64_t
offset
;
int64_t
offset
;
int
ret
;
int
ret
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_CLUSTER_ALLOC
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_CLUSTER_ALLOC
);
offset
=
alloc_clusters_noref
(
bs
,
size
);
offset
=
alloc_clusters_noref
(
bs
,
size
);
ret
=
update_refcount
(
bs
,
offset
,
size
,
1
);
ret
=
update_refcount
(
bs
,
offset
,
size
,
1
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -589,7 +590,7 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
...
@@ -589,7 +590,7 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
int64_t
offset
,
cluster_offset
;
int64_t
offset
,
cluster_offset
;
int
free_in_cluster
;
int
free_in_cluster
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_CLUSTER_ALLOC_BYTES
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_CLUSTER_ALLOC_BYTES
);
assert
(
size
>
0
&&
size
<=
s
->
cluster_size
);
assert
(
size
>
0
&&
size
<=
s
->
cluster_size
);
if
(
s
->
free_byte_offset
==
0
)
{
if
(
s
->
free_byte_offset
==
0
)
{
s
->
free_byte_offset
=
qcow2_alloc_clusters
(
bs
,
s
->
cluster_size
);
s
->
free_byte_offset
=
qcow2_alloc_clusters
(
bs
,
s
->
cluster_size
);
...
@@ -631,14 +632,13 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
...
@@ -631,14 +632,13 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
void
qcow2_free_clusters
(
BlockDriverState
*
bs
,
void
qcow2_free_clusters
(
BlockDriverState
*
bs
,
int64_t
offset
,
int64_t
size
)
int64_t
offset
,
int64_t
size
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
int
ret
;
int
ret
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_CLUSTER_FREE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_CLUSTER_FREE
);
ret
=
update_refcount
(
bs
,
offset
,
size
,
-
1
);
ret
=
update_refcount
(
bs
,
offset
,
size
,
-
1
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
fprintf
(
stderr
,
"qcow2_free_clusters failed: %s
\n
"
,
strerror
(
-
ret
));
fprintf
(
stderr
,
"qcow2_free_clusters failed: %s
\n
"
,
strerror
(
-
ret
));
abort
();
/* TODO Remember the clusters to free them later and avoid leaking */
}
}
}
}
...
@@ -718,7 +718,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
...
@@ -718,7 +718,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
l1_table
=
NULL
;
l1_table
=
NULL
;
}
}
l1_allocated
=
1
;
l1_allocated
=
1
;
if
(
bdrv_pread
(
s
->
hd
,
l1_table_offset
,
if
(
bdrv_pread
(
bs
->
file
,
l1_table_offset
,
l1_table
,
l1_size2
)
!=
l1_size2
)
l1_table
,
l1_size2
)
!=
l1_size2
)
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
l1_size
;
i
++
)
for
(
i
=
0
;
i
<
l1_size
;
i
++
)
...
@@ -738,7 +738,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
...
@@ -738,7 +738,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
old_l2_offset
=
l2_offset
;
old_l2_offset
=
l2_offset
;
l2_offset
&=
~
QCOW_OFLAG_COPIED
;
l2_offset
&=
~
QCOW_OFLAG_COPIED
;
l2_modified
=
0
;
l2_modified
=
0
;
if
(
bdrv_pread
(
s
->
hd
,
l2_offset
,
l2_table
,
l2_size
)
!=
l2_size
)
if
(
bdrv_pread
(
bs
->
file
,
l2_offset
,
l2_table
,
l2_size
)
!=
l2_size
)
goto
fail
;
goto
fail
;
for
(
j
=
0
;
j
<
s
->
l2_size
;
j
++
)
{
for
(
j
=
0
;
j
<
s
->
l2_size
;
j
++
)
{
offset
=
be64_to_cpu
(
l2_table
[
j
]);
offset
=
be64_to_cpu
(
l2_table
[
j
]);
...
@@ -777,7 +777,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
...
@@ -777,7 +777,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
}
}
}
}
if
(
l2_modified
)
{
if
(
l2_modified
)
{
if
(
bdrv_pwrite
(
s
->
hd
,
if
(
bdrv_pwrite
(
bs
->
file
,
l2_offset
,
l2_table
,
l2_size
)
!=
l2_size
)
l2_offset
,
l2_table
,
l2_size
)
!=
l2_size
)
goto
fail
;
goto
fail
;
}
}
...
@@ -799,7 +799,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
...
@@ -799,7 +799,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
if
(
l1_modified
)
{
if
(
l1_modified
)
{
for
(
i
=
0
;
i
<
l1_size
;
i
++
)
for
(
i
=
0
;
i
<
l1_size
;
i
++
)
cpu_to_be64s
(
&
l1_table
[
i
]);
cpu_to_be64s
(
&
l1_table
[
i
]);
if
(
bdrv_pwrite
(
s
->
hd
,
l1_table_offset
,
l1_table
,
if
(
bdrv_pwrite
(
bs
->
file
,
l1_table_offset
,
l1_table
,
l1_size2
)
!=
l1_size2
)
l1_size2
)
!=
l1_size2
)
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
l1_size
;
i
++
)
for
(
i
=
0
;
i
<
l1_size
;
i
++
)
...
@@ -809,14 +809,14 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
...
@@ -809,14 +809,14 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
qemu_free
(
l1_table
);
qemu_free
(
l1_table
);
qemu_free
(
l2_table
);
qemu_free
(
l2_table
);
cache_refcount_updates
=
0
;
cache_refcount_updates
=
0
;
write_refcount_block
(
s
);
write_refcount_block
(
b
s
);
return
0
;
return
0
;
fail:
fail:
if
(
l1_allocated
)
if
(
l1_allocated
)
qemu_free
(
l1_table
);
qemu_free
(
l1_table
);
qemu_free
(
l2_table
);
qemu_free
(
l2_table
);
cache_refcount_updates
=
0
;
cache_refcount_updates
=
0
;
write_refcount_block
(
s
);
write_refcount_block
(
b
s
);
return
-
EIO
;
return
-
EIO
;
}
}
...
@@ -890,7 +890,7 @@ static int check_refcounts_l2(BlockDriverState *bs,
...
@@ -890,7 +890,7 @@ static int check_refcounts_l2(BlockDriverState *bs,
l2_size
=
s
->
l2_size
*
sizeof
(
uint64_t
);
l2_size
=
s
->
l2_size
*
sizeof
(
uint64_t
);
l2_table
=
qemu_malloc
(
l2_size
);
l2_table
=
qemu_malloc
(
l2_size
);
if
(
bdrv_pread
(
s
->
hd
,
l2_offset
,
l2_table
,
l2_size
)
!=
l2_size
)
if
(
bdrv_pread
(
bs
->
file
,
l2_offset
,
l2_table
,
l2_size
)
!=
l2_size
)
goto
fail
;
goto
fail
;
/* Do the actual checks */
/* Do the actual checks */
...
@@ -982,7 +982,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
...
@@ -982,7 +982,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
l1_table
=
NULL
;
l1_table
=
NULL
;
}
else
{
}
else
{
l1_table
=
qemu_malloc
(
l1_size2
);
l1_table
=
qemu_malloc
(
l1_size2
);
if
(
bdrv_pread
(
s
->
hd
,
l1_table_offset
,
if
(
bdrv_pread
(
bs
->
file
,
l1_table_offset
,
l1_table
,
l1_size2
)
!=
l1_size2
)
l1_table
,
l1_size2
)
!=
l1_size2
)
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
l1_size
;
i
++
)
for
(
i
=
0
;
i
<
l1_size
;
i
++
)
...
@@ -1051,7 +1051,7 @@ int qcow2_check_refcounts(BlockDriverState *bs)
...
@@ -1051,7 +1051,7 @@ int qcow2_check_refcounts(BlockDriverState *bs)
uint16_t
*
refcount_table
;
uint16_t
*
refcount_table
;
int
ret
,
errors
=
0
;
int
ret
,
errors
=
0
;
size
=
bdrv_getlength
(
s
->
hd
);
size
=
bdrv_getlength
(
bs
->
file
);
nb_clusters
=
size_to_clusters
(
s
,
size
);
nb_clusters
=
size_to_clusters
(
s
,
size
);
refcount_table
=
qemu_mallocz
(
nb_clusters
*
sizeof
(
uint16_t
));
refcount_table
=
qemu_mallocz
(
nb_clusters
*
sizeof
(
uint16_t
));
...
...
block/qcow2-snapshot.c
浏览文件 @
72375c22
...
@@ -79,7 +79,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
...
@@ -79,7 +79,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
s
->
snapshots
=
qemu_mallocz
(
s
->
nb_snapshots
*
sizeof
(
QCowSnapshot
));
s
->
snapshots
=
qemu_mallocz
(
s
->
nb_snapshots
*
sizeof
(
QCowSnapshot
));
for
(
i
=
0
;
i
<
s
->
nb_snapshots
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
nb_snapshots
;
i
++
)
{
offset
=
align_offset
(
offset
,
8
);
offset
=
align_offset
(
offset
,
8
);
if
(
bdrv_pread
(
s
->
hd
,
offset
,
&
h
,
sizeof
(
h
))
!=
sizeof
(
h
))
if
(
bdrv_pread
(
bs
->
file
,
offset
,
&
h
,
sizeof
(
h
))
!=
sizeof
(
h
))
goto
fail
;
goto
fail
;
offset
+=
sizeof
(
h
);
offset
+=
sizeof
(
h
);
sn
=
s
->
snapshots
+
i
;
sn
=
s
->
snapshots
+
i
;
...
@@ -97,13 +97,13 @@ int qcow2_read_snapshots(BlockDriverState *bs)
...
@@ -97,13 +97,13 @@ int qcow2_read_snapshots(BlockDriverState *bs)
offset
+=
extra_data_size
;
offset
+=
extra_data_size
;
sn
->
id_str
=
qemu_malloc
(
id_str_size
+
1
);
sn
->
id_str
=
qemu_malloc
(
id_str_size
+
1
);
if
(
bdrv_pread
(
s
->
hd
,
offset
,
sn
->
id_str
,
id_str_size
)
!=
id_str_size
)
if
(
bdrv_pread
(
bs
->
file
,
offset
,
sn
->
id_str
,
id_str_size
)
!=
id_str_size
)
goto
fail
;
goto
fail
;
offset
+=
id_str_size
;
offset
+=
id_str_size
;
sn
->
id_str
[
id_str_size
]
=
'\0'
;
sn
->
id_str
[
id_str_size
]
=
'\0'
;
sn
->
name
=
qemu_malloc
(
name_size
+
1
);
sn
->
name
=
qemu_malloc
(
name_size
+
1
);
if
(
bdrv_pread
(
s
->
hd
,
offset
,
sn
->
name
,
name_size
)
!=
name_size
)
if
(
bdrv_pread
(
bs
->
file
,
offset
,
sn
->
name
,
name_size
)
!=
name_size
)
goto
fail
;
goto
fail
;
offset
+=
name_size
;
offset
+=
name_size
;
sn
->
name
[
name_size
]
=
'\0'
;
sn
->
name
[
name_size
]
=
'\0'
;
...
@@ -158,24 +158,24 @@ static int qcow_write_snapshots(BlockDriverState *bs)
...
@@ -158,24 +158,24 @@ static int qcow_write_snapshots(BlockDriverState *bs)
h
.
id_str_size
=
cpu_to_be16
(
id_str_size
);
h
.
id_str_size
=
cpu_to_be16
(
id_str_size
);
h
.
name_size
=
cpu_to_be16
(
name_size
);
h
.
name_size
=
cpu_to_be16
(
name_size
);
offset
=
align_offset
(
offset
,
8
);
offset
=
align_offset
(
offset
,
8
);
if
(
bdrv_pwrite
(
s
->
hd
,
offset
,
&
h
,
sizeof
(
h
))
!=
sizeof
(
h
))
if
(
bdrv_pwrite
(
bs
->
file
,
offset
,
&
h
,
sizeof
(
h
))
!=
sizeof
(
h
))
goto
fail
;
goto
fail
;
offset
+=
sizeof
(
h
);
offset
+=
sizeof
(
h
);
if
(
bdrv_pwrite
(
s
->
hd
,
offset
,
sn
->
id_str
,
id_str_size
)
!=
id_str_size
)
if
(
bdrv_pwrite
(
bs
->
file
,
offset
,
sn
->
id_str
,
id_str_size
)
!=
id_str_size
)
goto
fail
;
goto
fail
;
offset
+=
id_str_size
;
offset
+=
id_str_size
;
if
(
bdrv_pwrite
(
s
->
hd
,
offset
,
sn
->
name
,
name_size
)
!=
name_size
)
if
(
bdrv_pwrite
(
bs
->
file
,
offset
,
sn
->
name
,
name_size
)
!=
name_size
)
goto
fail
;
goto
fail
;
offset
+=
name_size
;
offset
+=
name_size
;
}
}
/* update the various header fields */
/* update the various header fields */
data64
=
cpu_to_be64
(
snapshots_offset
);
data64
=
cpu_to_be64
(
snapshots_offset
);
if
(
bdrv_pwrite
(
s
->
hd
,
offsetof
(
QCowHeader
,
snapshots_offset
),
if
(
bdrv_pwrite
(
bs
->
file
,
offsetof
(
QCowHeader
,
snapshots_offset
),
&
data64
,
sizeof
(
data64
))
!=
sizeof
(
data64
))
&
data64
,
sizeof
(
data64
))
!=
sizeof
(
data64
))
goto
fail
;
goto
fail
;
data32
=
cpu_to_be32
(
s
->
nb_snapshots
);
data32
=
cpu_to_be32
(
s
->
nb_snapshots
);
if
(
bdrv_pwrite
(
s
->
hd
,
offsetof
(
QCowHeader
,
nb_snapshots
),
if
(
bdrv_pwrite
(
bs
->
file
,
offsetof
(
QCowHeader
,
nb_snapshots
),
&
data32
,
sizeof
(
data32
))
!=
sizeof
(
data32
))
&
data32
,
sizeof
(
data32
))
!=
sizeof
(
data32
))
goto
fail
;
goto
fail
;
...
@@ -284,7 +284,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
...
@@ -284,7 +284,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
l1_table
[
i
]
=
cpu_to_be64
(
s
->
l1_table
[
i
]);
l1_table
[
i
]
=
cpu_to_be64
(
s
->
l1_table
[
i
]);
}
}
if
(
bdrv_pwrite
(
s
->
hd
,
sn
->
l1_table_offset
,
if
(
bdrv_pwrite
(
bs
->
file
,
sn
->
l1_table_offset
,
l1_table
,
s
->
l1_size
*
sizeof
(
uint64_t
))
!=
l1_table
,
s
->
l1_size
*
sizeof
(
uint64_t
))
!=
(
s
->
l1_size
*
sizeof
(
uint64_t
)))
(
s
->
l1_size
*
sizeof
(
uint64_t
)))
goto
fail
;
goto
fail
;
...
@@ -332,10 +332,10 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
...
@@ -332,10 +332,10 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
s
->
l1_size
=
sn
->
l1_size
;
s
->
l1_size
=
sn
->
l1_size
;
l1_size2
=
s
->
l1_size
*
sizeof
(
uint64_t
);
l1_size2
=
s
->
l1_size
*
sizeof
(
uint64_t
);
/* copy the snapshot l1 table to the current l1 table */
/* copy the snapshot l1 table to the current l1 table */
if
(
bdrv_pread
(
s
->
hd
,
sn
->
l1_table_offset
,
if
(
bdrv_pread
(
bs
->
file
,
sn
->
l1_table_offset
,
s
->
l1_table
,
l1_size2
)
!=
l1_size2
)
s
->
l1_table
,
l1_size2
)
!=
l1_size2
)
goto
fail
;
goto
fail
;
if
(
bdrv_pwrite
(
s
->
hd
,
s
->
l1_table_offset
,
if
(
bdrv_pwrite
(
bs
->
file
,
s
->
l1_table_offset
,
s
->
l1_table
,
l1_size2
)
!=
l1_size2
)
s
->
l1_table
,
l1_size2
)
!=
l1_size2
)
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
...
...
block/qcow2.c
浏览文件 @
72375c22
...
@@ -77,7 +77,6 @@ static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
...
@@ -77,7 +77,6 @@ static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
static
int
qcow_read_extensions
(
BlockDriverState
*
bs
,
uint64_t
start_offset
,
static
int
qcow_read_extensions
(
BlockDriverState
*
bs
,
uint64_t
start_offset
,
uint64_t
end_offset
)
uint64_t
end_offset
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
QCowExtension
ext
;
QCowExtension
ext
;
uint64_t
offset
;
uint64_t
offset
;
...
@@ -95,7 +94,7 @@ static int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset,
...
@@ -95,7 +94,7 @@ static int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset,
printf
(
"attemting to read extended header in offset %lu
\n
"
,
offset
);
printf
(
"attemting to read extended header in offset %lu
\n
"
,
offset
);
#endif
#endif
if
(
bdrv_pread
(
s
->
hd
,
offset
,
&
ext
,
sizeof
(
ext
))
!=
sizeof
(
ext
))
{
if
(
bdrv_pread
(
bs
->
file
,
offset
,
&
ext
,
sizeof
(
ext
))
!=
sizeof
(
ext
))
{
fprintf
(
stderr
,
"qcow_handle_extension: ERROR: pread fail from offset %llu
\n
"
,
fprintf
(
stderr
,
"qcow_handle_extension: ERROR: pread fail from offset %llu
\n
"
,
(
unsigned
long
long
)
offset
);
(
unsigned
long
long
)
offset
);
return
1
;
return
1
;
...
@@ -117,7 +116,7 @@ static int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset,
...
@@ -117,7 +116,7 @@ static int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset,
ext
.
len
,
sizeof
(
bs
->
backing_format
));
ext
.
len
,
sizeof
(
bs
->
backing_format
));
return
2
;
return
2
;
}
}
if
(
bdrv_pread
(
s
->
hd
,
offset
,
bs
->
backing_format
,
if
(
bdrv_pread
(
bs
->
file
,
offset
,
bs
->
backing_format
,
ext
.
len
)
!=
ext
.
len
)
ext
.
len
)
!=
ext
.
len
)
return
3
;
return
3
;
bs
->
backing_format
[
ext
.
len
]
=
'\0'
;
bs
->
backing_format
[
ext
.
len
]
=
'\0'
;
...
@@ -138,17 +137,14 @@ static int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset,
...
@@ -138,17 +137,14 @@ static int qcow_read_extensions(BlockDriverState *bs, uint64_t start_offset,
}
}
static
int
qcow_open
(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
)
static
int
qcow_open
(
BlockDriverState
*
bs
,
int
flags
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
BDRVQcowState
*
s
=
bs
->
opaque
;
int
len
,
i
,
shift
,
ret
;
int
len
,
i
;
QCowHeader
header
;
QCowHeader
header
;
uint64_t
ext_end
;
uint64_t
ext_end
;
ret
=
bdrv_file_open
(
&
s
->
hd
,
filename
,
flags
);
if
(
bdrv_pread
(
bs
->
file
,
0
,
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
if
(
ret
<
0
)
return
ret
;
if
(
bdrv_pread
(
s
->
hd
,
0
,
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
goto
fail
;
goto
fail
;
be32_to_cpus
(
&
header
.
magic
);
be32_to_cpus
(
&
header
.
magic
);
be32_to_cpus
(
&
header
.
version
);
be32_to_cpus
(
&
header
.
version
);
...
@@ -192,8 +188,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -192,8 +188,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
/* read the level 1 table */
/* read the level 1 table */
s
->
l1_size
=
header
.
l1_size
;
s
->
l1_size
=
header
.
l1_size
;
shift
=
s
->
cluster_bits
+
s
->
l2_bits
;
s
->
l1_vm_state_index
=
size_to_l1
(
s
,
header
.
size
);
s
->
l1_vm_state_index
=
(
header
.
size
+
(
1LL
<<
shift
)
-
1
)
>>
shift
;
/* the L1 table must contain at least enough entries to put
/* the L1 table must contain at least enough entries to put
header.size bytes */
header.size bytes */
if
(
s
->
l1_size
<
s
->
l1_vm_state_index
)
if
(
s
->
l1_size
<
s
->
l1_vm_state_index
)
...
@@ -202,7 +197,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -202,7 +197,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
if
(
s
->
l1_size
>
0
)
{
if
(
s
->
l1_size
>
0
)
{
s
->
l1_table
=
qemu_mallocz
(
s
->
l1_table
=
qemu_mallocz
(
align_offset
(
s
->
l1_size
*
sizeof
(
uint64_t
),
512
));
align_offset
(
s
->
l1_size
*
sizeof
(
uint64_t
),
512
));
if
(
bdrv_pread
(
s
->
hd
,
s
->
l1_table_offset
,
s
->
l1_table
,
s
->
l1_size
*
sizeof
(
uint64_t
))
!=
if
(
bdrv_pread
(
bs
->
file
,
s
->
l1_table_offset
,
s
->
l1_table
,
s
->
l1_size
*
sizeof
(
uint64_t
))
!=
s
->
l1_size
*
sizeof
(
uint64_t
))
s
->
l1_size
*
sizeof
(
uint64_t
))
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
...
@@ -235,7 +230,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -235,7 +230,7 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
len
=
header
.
backing_file_size
;
len
=
header
.
backing_file_size
;
if
(
len
>
1023
)
if
(
len
>
1023
)
len
=
1023
;
len
=
1023
;
if
(
bdrv_pread
(
s
->
hd
,
header
.
backing_file_offset
,
bs
->
backing_file
,
len
)
!=
len
)
if
(
bdrv_pread
(
bs
->
file
,
header
.
backing_file_offset
,
bs
->
backing_file
,
len
)
!=
len
)
goto
fail
;
goto
fail
;
bs
->
backing_file
[
len
]
=
'\0'
;
bs
->
backing_file
[
len
]
=
'\0'
;
}
}
...
@@ -254,7 +249,6 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -254,7 +249,6 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
qemu_free
(
s
->
l2_cache
);
qemu_free
(
s
->
l2_cache
);
qemu_free
(
s
->
cluster_cache
);
qemu_free
(
s
->
cluster_cache
);
qemu_free
(
s
->
cluster_data
);
qemu_free
(
s
->
cluster_data
);
bdrv_delete
(
s
->
hd
);
return
-
1
;
return
-
1
;
}
}
...
@@ -429,7 +423,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
...
@@ -429,7 +423,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_len
=
acb
->
cur_nr_sectors
*
512
;
acb
->
hd_iov
.
iov_len
=
acb
->
cur_nr_sectors
*
512
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_READ_BACKING_AIO
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_READ_BACKING_AIO
);
acb
->
hd_aiocb
=
bdrv_aio_readv
(
bs
->
backing_hd
,
acb
->
sector_num
,
acb
->
hd_aiocb
=
bdrv_aio_readv
(
bs
->
backing_hd
,
acb
->
sector_num
,
&
acb
->
hd_qiov
,
acb
->
cur_nr_sectors
,
&
acb
->
hd_qiov
,
acb
->
cur_nr_sectors
,
qcow_aio_read_cb
,
acb
);
qcow_aio_read_cb
,
acb
);
...
@@ -449,7 +443,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
...
@@ -449,7 +443,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
}
}
}
else
if
(
acb
->
cluster_offset
&
QCOW_OFLAG_COMPRESSED
)
{
}
else
if
(
acb
->
cluster_offset
&
QCOW_OFLAG_COMPRESSED
)
{
/* add AIO support for compressed blocks ? */
/* add AIO support for compressed blocks ? */
if
(
qcow2_decompress_cluster
(
s
,
acb
->
cluster_offset
)
<
0
)
if
(
qcow2_decompress_cluster
(
b
s
,
acb
->
cluster_offset
)
<
0
)
goto
done
;
goto
done
;
memcpy
(
acb
->
buf
,
s
->
cluster_cache
+
index_in_cluster
*
512
,
memcpy
(
acb
->
buf
,
s
->
cluster_cache
+
index_in_cluster
*
512
,
512
*
acb
->
cur_nr_sectors
);
512
*
acb
->
cur_nr_sectors
);
...
@@ -465,8 +459,8 @@ static void qcow_aio_read_cb(void *opaque, int ret)
...
@@ -465,8 +459,8 @@ static void qcow_aio_read_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_len
=
acb
->
cur_nr_sectors
*
512
;
acb
->
hd_iov
.
iov_len
=
acb
->
cur_nr_sectors
*
512
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_READ_AIO
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_READ_AIO
);
acb
->
hd_aiocb
=
bdrv_aio_readv
(
s
->
hd
,
acb
->
hd_aiocb
=
bdrv_aio_readv
(
bs
->
file
,
(
acb
->
cluster_offset
>>
9
)
+
index_in_cluster
,
(
acb
->
cluster_offset
>>
9
)
+
index_in_cluster
,
&
acb
->
hd_qiov
,
acb
->
cur_nr_sectors
,
&
acb
->
hd_qiov
,
acb
->
cur_nr_sectors
,
qcow_aio_read_cb
,
acb
);
qcow_aio_read_cb
,
acb
);
...
@@ -615,8 +609,8 @@ static void qcow_aio_write_cb(void *opaque, int ret)
...
@@ -615,8 +609,8 @@ static void qcow_aio_write_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
(
void
*
)
src_buf
;
acb
->
hd_iov
.
iov_base
=
(
void
*
)
src_buf
;
acb
->
hd_iov
.
iov_len
=
acb
->
cur_nr_sectors
*
512
;
acb
->
hd_iov
.
iov_len
=
acb
->
cur_nr_sectors
*
512
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_WRITE_AIO
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_WRITE_AIO
);
acb
->
hd_aiocb
=
bdrv_aio_writev
(
s
->
hd
,
acb
->
hd_aiocb
=
bdrv_aio_writev
(
bs
->
file
,
(
acb
->
cluster_offset
>>
9
)
+
index_in_cluster
,
(
acb
->
cluster_offset
>>
9
)
+
index_in_cluster
,
&
acb
->
hd_qiov
,
acb
->
cur_nr_sectors
,
&
acb
->
hd_qiov
,
acb
->
cur_nr_sectors
,
qcow_aio_write_cb
,
acb
);
qcow_aio_write_cb
,
acb
);
...
@@ -663,7 +657,6 @@ static void qcow_close(BlockDriverState *bs)
...
@@ -663,7 +657,6 @@ static void qcow_close(BlockDriverState *bs)
qemu_free
(
s
->
cluster_cache
);
qemu_free
(
s
->
cluster_cache
);
qemu_free
(
s
->
cluster_data
);
qemu_free
(
s
->
cluster_data
);
qcow2_refcount_close
(
bs
);
qcow2_refcount_close
(
bs
);
bdrv_delete
(
s
->
hd
);
}
}
/*
/*
...
@@ -733,7 +726,7 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
...
@@ -733,7 +726,7 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
backing_file_offset
=
sizeof
(
QCowHeader
)
+
offset
;
backing_file_offset
=
sizeof
(
QCowHeader
)
+
offset
;
}
}
ret
=
bdrv_pwrite
(
s
->
hd
,
sizeof
(
QCowHeader
),
buf
,
ext_size
);
ret
=
bdrv_pwrite
(
bs
->
file
,
sizeof
(
QCowHeader
),
buf
,
ext_size
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
fail
;
goto
fail
;
}
}
...
@@ -742,13 +735,13 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
...
@@ -742,13 +735,13 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
uint64_t
be_backing_file_offset
=
cpu_to_be64
(
backing_file_offset
);
uint64_t
be_backing_file_offset
=
cpu_to_be64
(
backing_file_offset
);
uint32_t
be_backing_file_size
=
cpu_to_be32
(
backing_file_len
);
uint32_t
be_backing_file_size
=
cpu_to_be32
(
backing_file_len
);
ret
=
bdrv_pwrite
(
s
->
hd
,
offsetof
(
QCowHeader
,
backing_file_offset
),
ret
=
bdrv_pwrite
(
bs
->
file
,
offsetof
(
QCowHeader
,
backing_file_offset
),
&
be_backing_file_offset
,
sizeof
(
uint64_t
));
&
be_backing_file_offset
,
sizeof
(
uint64_t
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
fail
;
goto
fail
;
}
}
ret
=
bdrv_pwrite
(
s
->
hd
,
offsetof
(
QCowHeader
,
backing_file_size
),
ret
=
bdrv_pwrite
(
bs
->
file
,
offsetof
(
QCowHeader
,
backing_file_size
),
&
be_backing_file_size
,
sizeof
(
uint32_t
));
&
be_backing_file_size
,
sizeof
(
uint32_t
));
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
fail
;
goto
fail
;
...
@@ -789,7 +782,6 @@ static int get_bits_from_size(size_t size)
...
@@ -789,7 +782,6 @@ static int get_bits_from_size(size_t size)
static
int
preallocate
(
BlockDriverState
*
bs
)
static
int
preallocate
(
BlockDriverState
*
bs
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
uint64_t
nb_sectors
;
uint64_t
nb_sectors
;
uint64_t
offset
;
uint64_t
offset
;
int
num
;
int
num
;
...
@@ -832,7 +824,7 @@ static int preallocate(BlockDriverState *bs)
...
@@ -832,7 +824,7 @@ static int preallocate(BlockDriverState *bs)
if
(
meta
.
cluster_offset
!=
0
)
{
if
(
meta
.
cluster_offset
!=
0
)
{
uint8_t
buf
[
512
];
uint8_t
buf
[
512
];
memset
(
buf
,
0
,
512
);
memset
(
buf
,
0
,
512
);
bdrv_write
(
s
->
hd
,
(
meta
.
cluster_offset
>>
9
)
+
num
-
1
,
buf
,
1
);
bdrv_write
(
bs
->
file
,
(
meta
.
cluster_offset
>>
9
)
+
num
-
1
,
buf
,
1
);
}
}
return
0
;
return
0
;
...
@@ -847,9 +839,9 @@ static int qcow_make_empty(BlockDriverState *bs)
...
@@ -847,9 +839,9 @@ static int qcow_make_empty(BlockDriverState *bs)
int ret;
int ret;
memset(s->l1_table, 0, l1_length);
memset(s->l1_table, 0, l1_length);
if (bdrv_pwrite(
s->hd
, s->l1_table_offset, s->l1_table, l1_length) < 0)
if (bdrv_pwrite(
bs->file
, s->l1_table_offset, s->l1_table, l1_length) < 0)
return -1;
return -1;
ret = bdrv_truncate(
s->hd
, s->l1_table_offset + l1_length);
ret = bdrv_truncate(
bs->file
, s->l1_table_offset + l1_length);
if (ret < 0)
if (ret < 0)
return ret;
return ret;
...
@@ -858,6 +850,43 @@ static int qcow_make_empty(BlockDriverState *bs)
...
@@ -858,6 +850,43 @@ static int qcow_make_empty(BlockDriverState *bs)
return
0
;
return
0
;
}
}
static
int
qcow2_truncate
(
BlockDriverState
*
bs
,
int64_t
offset
)
{
BDRVQcowState
*
s
=
bs
->
opaque
;
int
ret
,
new_l1_size
;
if
(
offset
&
511
)
{
return
-
EINVAL
;
}
/* cannot proceed if image has snapshots */
if
(
s
->
nb_snapshots
)
{
return
-
ENOTSUP
;
}
/* shrinking is currently not supported */
if
(
offset
<
bs
->
total_sectors
*
512
)
{
return
-
ENOTSUP
;
}
new_l1_size
=
size_to_l1
(
s
,
offset
);
ret
=
qcow2_grow_l1_table
(
bs
,
new_l1_size
);
if
(
ret
<
0
)
{
return
ret
;
}
/* write updated header.size */
offset
=
cpu_to_be64
(
offset
);
ret
=
bdrv_pwrite
(
bs
->
file
,
offsetof
(
QCowHeader
,
size
),
&
offset
,
sizeof
(
uint64_t
));
if
(
ret
<
0
)
{
return
ret
;
}
s
->
l1_vm_state_index
=
new_l1_size
;
return
0
;
}
/* XXX: put compressed sectors first, then all the cluster aligned
/* XXX: put compressed sectors first, then all the cluster aligned
tables to avoid losing bytes in alignment */
tables to avoid losing bytes in alignment */
static
int
qcow_write_compressed
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
static
int
qcow_write_compressed
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
...
@@ -872,9 +901,9 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
...
@@ -872,9 +901,9 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
if
(
nb_sectors
==
0
)
{
if
(
nb_sectors
==
0
)
{
/* align end of file to a sector boundary to ease reading with
/* align end of file to a sector boundary to ease reading with
sector based I/Os */
sector based I/Os */
cluster_offset
=
bdrv_getlength
(
s
->
hd
);
cluster_offset
=
bdrv_getlength
(
bs
->
file
);
cluster_offset
=
(
cluster_offset
+
511
)
&
~
511
;
cluster_offset
=
(
cluster_offset
+
511
)
&
~
511
;
bdrv_truncate
(
s
->
hd
,
cluster_offset
);
bdrv_truncate
(
bs
->
file
,
cluster_offset
);
return
0
;
return
0
;
}
}
...
@@ -917,8 +946,8 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
...
@@ -917,8 +946,8 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
if
(
!
cluster_offset
)
if
(
!
cluster_offset
)
return
-
1
;
return
-
1
;
cluster_offset
&=
s
->
cluster_offset_mask
;
cluster_offset
&=
s
->
cluster_offset_mask
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_WRITE_COMPRESSED
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_WRITE_COMPRESSED
);
if
(
bdrv_pwrite
(
s
->
hd
,
cluster_offset
,
out_buf
,
out_len
)
!=
out_len
)
{
if
(
bdrv_pwrite
(
bs
->
file
,
cluster_offset
,
out_buf
,
out_len
)
!=
out_len
)
{
qemu_free
(
out_buf
);
qemu_free
(
out_buf
);
return
-
1
;
return
-
1
;
}
}
...
@@ -930,16 +959,13 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
...
@@ -930,16 +959,13 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
static
void
qcow_flush
(
BlockDriverState
*
bs
)
static
void
qcow_flush
(
BlockDriverState
*
bs
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
bdrv_flush
(
bs
->
file
);
bdrv_flush
(
s
->
hd
);
}
}
static
BlockDriverAIOCB
*
qcow_aio_flush
(
BlockDriverState
*
bs
,
static
BlockDriverAIOCB
*
qcow_aio_flush
(
BlockDriverState
*
bs
,
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
return
bdrv_aio_flush
(
bs
->
file
,
cb
,
opaque
);
return
bdrv_aio_flush
(
s
->
hd
,
cb
,
opaque
);
}
}
static
int64_t
qcow_vm_state_offset
(
BDRVQcowState
*
s
)
static
int64_t
qcow_vm_state_offset
(
BDRVQcowState
*
s
)
...
@@ -968,7 +994,7 @@ static void dump_refcounts(BlockDriverState *bs)
...
@@ -968,7 +994,7 @@ static void dump_refcounts(BlockDriverState *bs)
int64_t nb_clusters, k, k1, size;
int64_t nb_clusters, k, k1, size;
int refcount;
int refcount;
size = bdrv_getlength(
s->hd
);
size = bdrv_getlength(
bs->file
);
nb_clusters = size_to_clusters(s, size);
nb_clusters = size_to_clusters(s, size);
for(k = 0; k < nb_clusters;) {
for(k = 0; k < nb_clusters;) {
k1 = k;
k1 = k;
...
@@ -988,7 +1014,7 @@ static int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
...
@@ -988,7 +1014,7 @@ static int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
int
growable
=
bs
->
growable
;
int
growable
=
bs
->
growable
;
int
ret
;
int
ret
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_VMSTATE_SAVE
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_VMSTATE_SAVE
);
bs
->
growable
=
1
;
bs
->
growable
=
1
;
ret
=
bdrv_pwrite
(
bs
,
qcow_vm_state_offset
(
s
)
+
pos
,
buf
,
size
);
ret
=
bdrv_pwrite
(
bs
,
qcow_vm_state_offset
(
s
)
+
pos
,
buf
,
size
);
bs
->
growable
=
growable
;
bs
->
growable
=
growable
;
...
@@ -1003,7 +1029,7 @@ static int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf,
...
@@ -1003,7 +1029,7 @@ static int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf,
int
growable
=
bs
->
growable
;
int
growable
=
bs
->
growable
;
int
ret
;
int
ret
;
BLKDBG_EVENT
(
s
->
hd
,
BLKDBG_VMSTATE_LOAD
);
BLKDBG_EVENT
(
bs
->
file
,
BLKDBG_VMSTATE_LOAD
);
bs
->
growable
=
1
;
bs
->
growable
=
1
;
ret
=
bdrv_pread
(
bs
,
qcow_vm_state_offset
(
s
)
+
pos
,
buf
,
size
);
ret
=
bdrv_pread
(
bs
,
qcow_vm_state_offset
(
s
)
+
pos
,
buf
,
size
);
bs
->
growable
=
growable
;
bs
->
growable
=
growable
;
...
@@ -1060,7 +1086,9 @@ static BlockDriver bdrv_qcow2 = {
...
@@ -1060,7 +1086,9 @@ static BlockDriver bdrv_qcow2 = {
.
bdrv_aio_readv
=
qcow_aio_readv
,
.
bdrv_aio_readv
=
qcow_aio_readv
,
.
bdrv_aio_writev
=
qcow_aio_writev
,
.
bdrv_aio_writev
=
qcow_aio_writev
,
.
bdrv_aio_flush
=
qcow_aio_flush
,
.
bdrv_aio_flush
=
qcow_aio_flush
,
.
bdrv_write_compressed
=
qcow_write_compressed
,
.
bdrv_truncate
=
qcow2_truncate
,
.
bdrv_write_compressed
=
qcow_write_compressed
,
.
bdrv_snapshot_create
=
qcow2_snapshot_create
,
.
bdrv_snapshot_create
=
qcow2_snapshot_create
,
.
bdrv_snapshot_goto
=
qcow2_snapshot_goto
,
.
bdrv_snapshot_goto
=
qcow2_snapshot_goto
,
...
...
block/qcow2.h
浏览文件 @
72375c22
...
@@ -150,6 +150,12 @@ static inline int size_to_clusters(BDRVQcowState *s, int64_t size)
...
@@ -150,6 +150,12 @@ static inline int size_to_clusters(BDRVQcowState *s, int64_t size)
return
(
size
+
(
s
->
cluster_size
-
1
))
>>
s
->
cluster_bits
;
return
(
size
+
(
s
->
cluster_size
-
1
))
>>
s
->
cluster_bits
;
}
}
static
inline
int
size_to_l1
(
BDRVQcowState
*
s
,
int64_t
size
)
{
int
shift
=
s
->
cluster_bits
+
s
->
l2_bits
;
return
(
size
+
(
1ULL
<<
shift
)
-
1
)
>>
shift
;
}
static
inline
int64_t
align_offset
(
int64_t
offset
,
int
n
)
static
inline
int64_t
align_offset
(
int64_t
offset
,
int
n
)
{
{
offset
=
(
offset
+
n
-
1
)
&
~
(
n
-
1
);
offset
=
(
offset
+
n
-
1
)
&
~
(
n
-
1
);
...
@@ -184,7 +190,7 @@ int qcow2_check_refcounts(BlockDriverState *bs);
...
@@ -184,7 +190,7 @@ int qcow2_check_refcounts(BlockDriverState *bs);
/* qcow2-cluster.c functions */
/* qcow2-cluster.c functions */
int
qcow2_grow_l1_table
(
BlockDriverState
*
bs
,
int
min_size
);
int
qcow2_grow_l1_table
(
BlockDriverState
*
bs
,
int
min_size
);
void
qcow2_l2_cache_reset
(
BlockDriverState
*
bs
);
void
qcow2_l2_cache_reset
(
BlockDriverState
*
bs
);
int
qcow2_decompress_cluster
(
B
DRVQcowState
*
s
,
uint64_t
cluster_offset
);
int
qcow2_decompress_cluster
(
B
lockDriverState
*
b
s
,
uint64_t
cluster_offset
);
void
qcow2_encrypt_sectors
(
BDRVQcowState
*
s
,
int64_t
sector_num
,
void
qcow2_encrypt_sectors
(
BDRVQcowState
*
s
,
int64_t
sector_num
,
uint8_t
*
out_buf
,
const
uint8_t
*
in_buf
,
uint8_t
*
out_buf
,
const
uint8_t
*
in_buf
,
int
nb_sectors
,
int
enc
,
int
nb_sectors
,
int
enc
,
...
...
block/raw-posix.c
浏览文件 @
72375c22
...
@@ -105,7 +105,6 @@
...
@@ -105,7 +105,6 @@
typedef
struct
BDRVRawState
{
typedef
struct
BDRVRawState
{
int
fd
;
int
fd
;
int
type
;
int
type
;
unsigned
int
lseek_err_cnt
;
int
open_flags
;
int
open_flags
;
#if defined(__linux__)
#if defined(__linux__)
/* linux floppy specific */
/* linux floppy specific */
...
@@ -134,8 +133,6 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
...
@@ -134,8 +133,6 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
BDRVRawState
*
s
=
bs
->
opaque
;
BDRVRawState
*
s
=
bs
->
opaque
;
int
fd
,
ret
;
int
fd
,
ret
;
s
->
lseek_err_cnt
=
0
;
s
->
open_flags
=
open_flags
|
O_BINARY
;
s
->
open_flags
=
open_flags
|
O_BINARY
;
s
->
open_flags
&=
~
O_ACCMODE
;
s
->
open_flags
&=
~
O_ACCMODE
;
if
(
bdrv_flags
&
BDRV_O_RDWR
)
{
if
(
bdrv_flags
&
BDRV_O_RDWR
)
{
...
@@ -243,19 +240,7 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
...
@@ -243,19 +240,7 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
if
(
offset
>=
0
&&
lseek
(
s
->
fd
,
offset
,
SEEK_SET
)
==
(
off_t
)
-
1
)
{
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
++
(
s
->
lseek_err_cnt
);
if
(
s
->
lseek_err_cnt
<=
10
)
{
DEBUG_BLOCK_PRINT
(
"raw_pread(%d:%s, %"
PRId64
", %p, %d) [%"
PRId64
"] lseek failed : %d = %s
\n
"
,
s
->
fd
,
bs
->
filename
,
offset
,
buf
,
count
,
bs
->
total_sectors
,
errno
,
strerror
(
errno
));
}
return
-
1
;
}
s
->
lseek_err_cnt
=
0
;
ret
=
read
(
s
->
fd
,
buf
,
count
);
if
(
ret
==
count
)
if
(
ret
==
count
)
goto
label__raw_read__success
;
goto
label__raw_read__success
;
...
@@ -276,12 +261,10 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
...
@@ -276,12 +261,10 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
/* Try harder for CDrom. */
/* Try harder for CDrom. */
if
(
bs
->
type
==
BDRV_TYPE_CDROM
)
{
if
(
bs
->
type
==
BDRV_TYPE_CDROM
)
{
lseek
(
s
->
fd
,
offset
,
SEEK_SET
);
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
ret
=
read
(
s
->
fd
,
buf
,
count
);
if
(
ret
==
count
)
if
(
ret
==
count
)
goto
label__raw_read__success
;
goto
label__raw_read__success
;
lseek
(
s
->
fd
,
offset
,
SEEK_SET
);
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
ret
=
read
(
s
->
fd
,
buf
,
count
);
if
(
ret
==
count
)
if
(
ret
==
count
)
goto
label__raw_read__success
;
goto
label__raw_read__success
;
...
@@ -313,19 +296,7 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
...
@@ -313,19 +296,7 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
errno
;
return
-
errno
;
if
(
offset
>=
0
&&
lseek
(
s
->
fd
,
offset
,
SEEK_SET
)
==
(
off_t
)
-
1
)
{
ret
=
pwrite
(
s
->
fd
,
buf
,
count
,
offset
);
++
(
s
->
lseek_err_cnt
);
if
(
s
->
lseek_err_cnt
)
{
DEBUG_BLOCK_PRINT
(
"raw_pwrite(%d:%s, %"
PRId64
", %p, %d) [%"
PRId64
"] lseek failed : %d = %s
\n
"
,
s
->
fd
,
bs
->
filename
,
offset
,
buf
,
count
,
bs
->
total_sectors
,
errno
,
strerror
(
errno
));
}
return
-
EIO
;
}
s
->
lseek_err_cnt
=
0
;
ret
=
write
(
s
->
fd
,
buf
,
count
);
if
(
ret
==
count
)
if
(
ret
==
count
)
goto
label__raw_write__success
;
goto
label__raw_write__success
;
...
@@ -768,11 +739,12 @@ static QEMUOptionParameter raw_create_options[] = {
...
@@ -768,11 +739,12 @@ static QEMUOptionParameter raw_create_options[] = {
{
NULL
}
{
NULL
}
};
};
static
BlockDriver
bdrv_raw
=
{
static
BlockDriver
bdrv_file
=
{
.
format_name
=
"raw"
,
.
format_name
=
"file"
,
.
protocol_name
=
"file"
,
.
instance_size
=
sizeof
(
BDRVRawState
),
.
instance_size
=
sizeof
(
BDRVRawState
),
.
bdrv_probe
=
NULL
,
/* no probe for protocols */
.
bdrv_probe
=
NULL
,
/* no probe for protocols */
.
bdrv_open
=
raw_open
,
.
bdrv_
file_
open
=
raw_open
,
.
bdrv_read
=
raw_read
,
.
bdrv_read
=
raw_read
,
.
bdrv_write
=
raw_write
,
.
bdrv_write
=
raw_write
,
.
bdrv_close
=
raw_close
,
.
bdrv_close
=
raw_close
,
...
@@ -1026,9 +998,10 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options)
...
@@ -1026,9 +998,10 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options)
static
BlockDriver
bdrv_host_device
=
{
static
BlockDriver
bdrv_host_device
=
{
.
format_name
=
"host_device"
,
.
format_name
=
"host_device"
,
.
protocol_name
=
"host_device"
,
.
instance_size
=
sizeof
(
BDRVRawState
),
.
instance_size
=
sizeof
(
BDRVRawState
),
.
bdrv_probe_device
=
hdev_probe_device
,
.
bdrv_probe_device
=
hdev_probe_device
,
.
bdrv_
open
=
hdev_open
,
.
bdrv_
file_open
=
hdev_open
,
.
bdrv_close
=
raw_close
,
.
bdrv_close
=
raw_close
,
.
bdrv_create
=
hdev_create
,
.
bdrv_create
=
hdev_create
,
.
create_options
=
raw_create_options
,
.
create_options
=
raw_create_options
,
...
@@ -1140,9 +1113,10 @@ static int floppy_eject(BlockDriverState *bs, int eject_flag)
...
@@ -1140,9 +1113,10 @@ static int floppy_eject(BlockDriverState *bs, int eject_flag)
static
BlockDriver
bdrv_host_floppy
=
{
static
BlockDriver
bdrv_host_floppy
=
{
.
format_name
=
"host_floppy"
,
.
format_name
=
"host_floppy"
,
.
protocol_name
=
"host_floppy"
,
.
instance_size
=
sizeof
(
BDRVRawState
),
.
instance_size
=
sizeof
(
BDRVRawState
),
.
bdrv_probe_device
=
floppy_probe_device
,
.
bdrv_probe_device
=
floppy_probe_device
,
.
bdrv_
open
=
floppy_open
,
.
bdrv_
file_open
=
floppy_open
,
.
bdrv_close
=
raw_close
,
.
bdrv_close
=
raw_close
,
.
bdrv_create
=
hdev_create
,
.
bdrv_create
=
hdev_create
,
.
create_options
=
raw_create_options
,
.
create_options
=
raw_create_options
,
...
@@ -1239,9 +1213,10 @@ static int cdrom_set_locked(BlockDriverState *bs, int locked)
...
@@ -1239,9 +1213,10 @@ static int cdrom_set_locked(BlockDriverState *bs, int locked)
static
BlockDriver
bdrv_host_cdrom
=
{
static
BlockDriver
bdrv_host_cdrom
=
{
.
format_name
=
"host_cdrom"
,
.
format_name
=
"host_cdrom"
,
.
protocol_name
=
"host_cdrom"
,
.
instance_size
=
sizeof
(
BDRVRawState
),
.
instance_size
=
sizeof
(
BDRVRawState
),
.
bdrv_probe_device
=
cdrom_probe_device
,
.
bdrv_probe_device
=
cdrom_probe_device
,
.
bdrv_
open
=
cdrom_open
,
.
bdrv_
file_open
=
cdrom_open
,
.
bdrv_close
=
raw_close
,
.
bdrv_close
=
raw_close
,
.
bdrv_create
=
hdev_create
,
.
bdrv_create
=
hdev_create
,
.
create_options
=
raw_create_options
,
.
create_options
=
raw_create_options
,
...
@@ -1361,9 +1336,10 @@ static int cdrom_set_locked(BlockDriverState *bs, int locked)
...
@@ -1361,9 +1336,10 @@ static int cdrom_set_locked(BlockDriverState *bs, int locked)
static
BlockDriver
bdrv_host_cdrom
=
{
static
BlockDriver
bdrv_host_cdrom
=
{
.
format_name
=
"host_cdrom"
,
.
format_name
=
"host_cdrom"
,
.
protocol_name
=
"host_cdrom"
,
.
instance_size
=
sizeof
(
BDRVRawState
),
.
instance_size
=
sizeof
(
BDRVRawState
),
.
bdrv_probe_device
=
cdrom_probe_device
,
.
bdrv_probe_device
=
cdrom_probe_device
,
.
bdrv_
open
=
cdrom_open
,
.
bdrv_
file_open
=
cdrom_open
,
.
bdrv_close
=
raw_close
,
.
bdrv_close
=
raw_close
,
.
bdrv_create
=
hdev_create
,
.
bdrv_create
=
hdev_create
,
.
create_options
=
raw_create_options
,
.
create_options
=
raw_create_options
,
...
@@ -1385,13 +1361,13 @@ static BlockDriver bdrv_host_cdrom = {
...
@@ -1385,13 +1361,13 @@ static BlockDriver bdrv_host_cdrom = {
};
};
#endif
/* __FreeBSD__ */
#endif
/* __FreeBSD__ */
static
void
bdrv_
raw
_init
(
void
)
static
void
bdrv_
file
_init
(
void
)
{
{
/*
/*
* Register all the drivers. Note that order is important, the driver
* Register all the drivers. Note that order is important, the driver
* registered last will get probed first.
* registered last will get probed first.
*/
*/
bdrv_register
(
&
bdrv_
raw
);
bdrv_register
(
&
bdrv_
file
);
bdrv_register
(
&
bdrv_host_device
);
bdrv_register
(
&
bdrv_host_device
);
#ifdef __linux__
#ifdef __linux__
bdrv_register
(
&
bdrv_host_floppy
);
bdrv_register
(
&
bdrv_host_floppy
);
...
@@ -1402,4 +1378,4 @@ static void bdrv_raw_init(void)
...
@@ -1402,4 +1378,4 @@ static void bdrv_raw_init(void)
#endif
#endif
}
}
block_init
(
bdrv_
raw
_init
);
block_init
(
bdrv_
file
_init
);
block/raw-win32.c
浏览文件 @
72375c22
...
@@ -238,10 +238,11 @@ static QEMUOptionParameter raw_create_options[] = {
...
@@ -238,10 +238,11 @@ static QEMUOptionParameter raw_create_options[] = {
{
NULL
}
{
NULL
}
};
};
static
BlockDriver
bdrv_raw
=
{
static
BlockDriver
bdrv_file
=
{
.
format_name
=
"raw"
,
.
format_name
=
"file"
,
.
protocol_name
=
"file"
,
.
instance_size
=
sizeof
(
BDRVRawState
),
.
instance_size
=
sizeof
(
BDRVRawState
),
.
bdrv_
open
=
raw_open
,
.
bdrv_
file_open
=
raw_open
,
.
bdrv_close
=
raw_close
,
.
bdrv_close
=
raw_close
,
.
bdrv_create
=
raw_create
,
.
bdrv_create
=
raw_create
,
.
bdrv_flush
=
raw_flush
,
.
bdrv_flush
=
raw_flush
,
...
@@ -395,9 +396,10 @@ static int raw_set_locked(BlockDriverState *bs, int locked)
...
@@ -395,9 +396,10 @@ static int raw_set_locked(BlockDriverState *bs, int locked)
static
BlockDriver
bdrv_host_device
=
{
static
BlockDriver
bdrv_host_device
=
{
.
format_name
=
"host_device"
,
.
format_name
=
"host_device"
,
.
protocol_name
=
"host_device"
,
.
instance_size
=
sizeof
(
BDRVRawState
),
.
instance_size
=
sizeof
(
BDRVRawState
),
.
bdrv_probe_device
=
hdev_probe_device
,
.
bdrv_probe_device
=
hdev_probe_device
,
.
bdrv_
open
=
hdev_open
,
.
bdrv_
file_open
=
hdev_open
,
.
bdrv_close
=
raw_close
,
.
bdrv_close
=
raw_close
,
.
bdrv_flush
=
raw_flush
,
.
bdrv_flush
=
raw_flush
,
...
@@ -406,10 +408,10 @@ static BlockDriver bdrv_host_device = {
...
@@ -406,10 +408,10 @@ static BlockDriver bdrv_host_device = {
.
bdrv_getlength
=
raw_getlength
,
.
bdrv_getlength
=
raw_getlength
,
};
};
static
void
bdrv_
raw
_init
(
void
)
static
void
bdrv_
file
_init
(
void
)
{
{
bdrv_register
(
&
bdrv_
raw
);
bdrv_register
(
&
bdrv_
file
);
bdrv_register
(
&
bdrv_host_device
);
bdrv_register
(
&
bdrv_host_device
);
}
}
block_init
(
bdrv_
raw
_init
);
block_init
(
bdrv_
file
_init
);
block/raw.c
0 → 100644
浏览文件 @
72375c22
#include "qemu-common.h"
#include "block_int.h"
#include "module.h"
static
int
raw_open
(
BlockDriverState
*
bs
,
int
flags
)
{
bs
->
sg
=
bs
->
file
->
sg
;
return
0
;
}
static
int
raw_read
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
uint8_t
*
buf
,
int
nb_sectors
)
{
return
bdrv_read
(
bs
->
file
,
sector_num
,
buf
,
nb_sectors
);
}
static
int
raw_write
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
const
uint8_t
*
buf
,
int
nb_sectors
)
{
return
bdrv_write
(
bs
->
file
,
sector_num
,
buf
,
nb_sectors
);
}
static
BlockDriverAIOCB
*
raw_aio_readv
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
QEMUIOVector
*
qiov
,
int
nb_sectors
,
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
{
return
bdrv_aio_readv
(
bs
->
file
,
sector_num
,
qiov
,
nb_sectors
,
cb
,
opaque
);
}
static
BlockDriverAIOCB
*
raw_aio_writev
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
QEMUIOVector
*
qiov
,
int
nb_sectors
,
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
{
return
bdrv_aio_writev
(
bs
->
file
,
sector_num
,
qiov
,
nb_sectors
,
cb
,
opaque
);
}
static
void
raw_close
(
BlockDriverState
*
bs
)
{
}
static
void
raw_flush
(
BlockDriverState
*
bs
)
{
bdrv_flush
(
bs
->
file
);
}
static
BlockDriverAIOCB
*
raw_aio_flush
(
BlockDriverState
*
bs
,
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
{
return
bdrv_aio_flush
(
bs
->
file
,
cb
,
opaque
);
}
static
int64_t
raw_getlength
(
BlockDriverState
*
bs
)
{
return
bdrv_getlength
(
bs
->
file
);
}
static
int
raw_truncate
(
BlockDriverState
*
bs
,
int64_t
offset
)
{
return
bdrv_truncate
(
bs
->
file
,
offset
);
}
static
int
raw_probe
(
const
uint8_t
*
buf
,
int
buf_size
,
const
char
*
filename
)
{
return
1
;
/* everything can be opened as raw image */
}
static
int
raw_is_inserted
(
BlockDriverState
*
bs
)
{
return
bdrv_is_inserted
(
bs
->
file
);
}
static
int
raw_eject
(
BlockDriverState
*
bs
,
int
eject_flag
)
{
return
bdrv_eject
(
bs
->
file
,
eject_flag
);
}
static
int
raw_set_locked
(
BlockDriverState
*
bs
,
int
locked
)
{
bdrv_set_locked
(
bs
->
file
,
locked
);
return
0
;
}
static
int
raw_ioctl
(
BlockDriverState
*
bs
,
unsigned
long
int
req
,
void
*
buf
)
{
return
bdrv_ioctl
(
bs
->
file
,
req
,
buf
);
}
static
BlockDriverAIOCB
*
raw_aio_ioctl
(
BlockDriverState
*
bs
,
unsigned
long
int
req
,
void
*
buf
,
BlockDriverCompletionFunc
*
cb
,
void
*
opaque
)
{
return
bdrv_aio_ioctl
(
bs
->
file
,
req
,
buf
,
cb
,
opaque
);
}
static
int
raw_create
(
const
char
*
filename
,
QEMUOptionParameter
*
options
)
{
return
bdrv_create_file
(
filename
,
options
);
}
static
QEMUOptionParameter
raw_create_options
[]
=
{
{
.
name
=
BLOCK_OPT_SIZE
,
.
type
=
OPT_SIZE
,
.
help
=
"Virtual disk size"
},
{
NULL
}
};
static
BlockDriver
bdrv_raw
=
{
.
format_name
=
"raw"
,
/* It's really 0, but we need to make qemu_malloc() happy */
.
instance_size
=
1
,
.
bdrv_open
=
raw_open
,
.
bdrv_close
=
raw_close
,
.
bdrv_read
=
raw_read
,
.
bdrv_write
=
raw_write
,
.
bdrv_flush
=
raw_flush
,
.
bdrv_probe
=
raw_probe
,
.
bdrv_getlength
=
raw_getlength
,
.
bdrv_truncate
=
raw_truncate
,
.
bdrv_aio_readv
=
raw_aio_readv
,
.
bdrv_aio_writev
=
raw_aio_writev
,
.
bdrv_aio_flush
=
raw_aio_flush
,
.
bdrv_is_inserted
=
raw_is_inserted
,
.
bdrv_eject
=
raw_eject
,
.
bdrv_set_locked
=
raw_set_locked
,
.
bdrv_ioctl
=
raw_ioctl
,
.
bdrv_aio_ioctl
=
raw_aio_ioctl
,
.
bdrv_create
=
raw_create
,
.
create_options
=
raw_create_options
,
};
static
void
bdrv_raw_init
(
void
)
{
bdrv_register
(
&
bdrv_raw
);
}
block_init
(
bdrv_raw_init
);
block/vdi.c
浏览文件 @
72375c22
...
@@ -376,21 +376,15 @@ static int vdi_probe(const uint8_t *buf, int buf_size, const char *filename)
...
@@ -376,21 +376,15 @@ static int vdi_probe(const uint8_t *buf, int buf_size, const char *filename)
return
result
;
return
result
;
}
}
static
int
vdi_open
(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
)
static
int
vdi_open
(
BlockDriverState
*
bs
,
int
flags
)
{
{
BDRVVdiState
*
s
=
bs
->
opaque
;
BDRVVdiState
*
s
=
bs
->
opaque
;
VdiHeader
header
;
VdiHeader
header
;
size_t
bmap_size
;
size_t
bmap_size
;
int
ret
;
logout
(
"
\n
"
);
logout
(
"
\n
"
);
ret
=
bdrv_file_open
(
&
s
->
hd
,
filename
,
flags
);
if
(
bdrv_read
(
bs
->
file
,
0
,
(
uint8_t
*
)
&
header
,
1
)
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
}
if
(
bdrv_read
(
s
->
hd
,
0
,
(
uint8_t
*
)
&
header
,
1
)
<
0
)
{
goto
fail
;
goto
fail
;
}
}
...
@@ -442,7 +436,7 @@ static int vdi_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -442,7 +436,7 @@ static int vdi_open(BlockDriverState *bs, const char *filename, int flags)
bmap_size
=
header
.
blocks_in_image
*
sizeof
(
uint32_t
);
bmap_size
=
header
.
blocks_in_image
*
sizeof
(
uint32_t
);
bmap_size
=
(
bmap_size
+
SECTOR_SIZE
-
1
)
/
SECTOR_SIZE
;
bmap_size
=
(
bmap_size
+
SECTOR_SIZE
-
1
)
/
SECTOR_SIZE
;
s
->
bmap
=
qemu_malloc
(
bmap_size
*
SECTOR_SIZE
);
s
->
bmap
=
qemu_malloc
(
bmap_size
*
SECTOR_SIZE
);
if
(
bdrv_read
(
s
->
hd
,
s
->
bmap_sector
,
(
uint8_t
*
)
s
->
bmap
,
bmap_size
)
<
0
)
{
if
(
bdrv_read
(
bs
->
file
,
s
->
bmap_sector
,
(
uint8_t
*
)
s
->
bmap
,
bmap_size
)
<
0
)
{
goto
fail_free_bmap
;
goto
fail_free_bmap
;
}
}
...
@@ -452,7 +446,6 @@ static int vdi_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -452,7 +446,6 @@ static int vdi_open(BlockDriverState *bs, const char *filename, int flags)
qemu_free
(
s
->
bmap
);
qemu_free
(
s
->
bmap
);
fail:
fail:
bdrv_delete
(
s
->
hd
);
return
-
1
;
return
-
1
;
}
}
...
@@ -607,7 +600,7 @@ static void vdi_aio_read_cb(void *opaque, int ret)
...
@@ -607,7 +600,7 @@ static void vdi_aio_read_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_len
=
n_sectors
*
SECTOR_SIZE
;
acb
->
hd_iov
.
iov_len
=
n_sectors
*
SECTOR_SIZE
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
acb
->
hd_aiocb
=
bdrv_aio_readv
(
s
->
hd
,
offset
,
&
acb
->
hd_qiov
,
acb
->
hd_aiocb
=
bdrv_aio_readv
(
bs
->
file
,
offset
,
&
acb
->
hd_qiov
,
n_sectors
,
vdi_aio_read_cb
,
acb
);
n_sectors
,
vdi_aio_read_cb
,
acb
);
if
(
acb
->
hd_aiocb
==
NULL
)
{
if
(
acb
->
hd_aiocb
==
NULL
)
{
goto
done
;
goto
done
;
...
@@ -670,7 +663,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
...
@@ -670,7 +663,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
acb
->
block_buffer
;
acb
->
hd_iov
.
iov_base
=
acb
->
block_buffer
;
acb
->
hd_iov
.
iov_len
=
SECTOR_SIZE
;
acb
->
hd_iov
.
iov_len
=
SECTOR_SIZE
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
acb
->
hd_aiocb
=
bdrv_aio_writev
(
s
->
hd
,
0
,
&
acb
->
hd_qiov
,
1
,
acb
->
hd_aiocb
=
bdrv_aio_writev
(
bs
->
file
,
0
,
&
acb
->
hd_qiov
,
1
,
vdi_aio_write_cb
,
acb
);
vdi_aio_write_cb
,
acb
);
if
(
acb
->
hd_aiocb
==
NULL
)
{
if
(
acb
->
hd_aiocb
==
NULL
)
{
goto
done
;
goto
done
;
...
@@ -699,7 +692,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
...
@@ -699,7 +692,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
logout
(
"will write %u block map sectors starting from entry %u
\n
"
,
logout
(
"will write %u block map sectors starting from entry %u
\n
"
,
n_sectors
,
bmap_first
);
n_sectors
,
bmap_first
);
acb
->
hd_aiocb
=
bdrv_aio_writev
(
s
->
hd
,
offset
,
&
acb
->
hd_qiov
,
acb
->
hd_aiocb
=
bdrv_aio_writev
(
bs
->
file
,
offset
,
&
acb
->
hd_qiov
,
n_sectors
,
vdi_aio_write_cb
,
acb
);
n_sectors
,
vdi_aio_write_cb
,
acb
);
if
(
acb
->
hd_aiocb
==
NULL
)
{
if
(
acb
->
hd_aiocb
==
NULL
)
{
goto
done
;
goto
done
;
...
@@ -748,7 +741,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
...
@@ -748,7 +741,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
(
void
*
)
block
;
acb
->
hd_iov
.
iov_base
=
(
void
*
)
block
;
acb
->
hd_iov
.
iov_len
=
s
->
block_size
;
acb
->
hd_iov
.
iov_len
=
s
->
block_size
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
acb
->
hd_aiocb
=
bdrv_aio_writev
(
s
->
hd
,
offset
,
acb
->
hd_aiocb
=
bdrv_aio_writev
(
bs
->
file
,
offset
,
&
acb
->
hd_qiov
,
s
->
block_sectors
,
&
acb
->
hd_qiov
,
s
->
block_sectors
,
vdi_aio_write_cb
,
acb
);
vdi_aio_write_cb
,
acb
);
if
(
acb
->
hd_aiocb
==
NULL
)
{
if
(
acb
->
hd_aiocb
==
NULL
)
{
...
@@ -761,7 +754,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
...
@@ -761,7 +754,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_base
=
(
void
*
)
acb
->
buf
;
acb
->
hd_iov
.
iov_len
=
n_sectors
*
SECTOR_SIZE
;
acb
->
hd_iov
.
iov_len
=
n_sectors
*
SECTOR_SIZE
;
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
qemu_iovec_init_external
(
&
acb
->
hd_qiov
,
&
acb
->
hd_iov
,
1
);
acb
->
hd_aiocb
=
bdrv_aio_writev
(
s
->
hd
,
offset
,
&
acb
->
hd_qiov
,
acb
->
hd_aiocb
=
bdrv_aio_writev
(
bs
->
file
,
offset
,
&
acb
->
hd_qiov
,
n_sectors
,
vdi_aio_write_cb
,
acb
);
n_sectors
,
vdi_aio_write_cb
,
acb
);
if
(
acb
->
hd_aiocb
==
NULL
)
{
if
(
acb
->
hd_aiocb
==
NULL
)
{
goto
done
;
goto
done
;
...
@@ -891,16 +884,12 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
...
@@ -891,16 +884,12 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
static
void
vdi_close
(
BlockDriverState
*
bs
)
static
void
vdi_close
(
BlockDriverState
*
bs
)
{
{
BDRVVdiState
*
s
=
bs
->
opaque
;
logout
(
"
\n
"
);
bdrv_delete
(
s
->
hd
);
}
}
static
void
vdi_flush
(
BlockDriverState
*
bs
)
static
void
vdi_flush
(
BlockDriverState
*
bs
)
{
{
BDRVVdiState
*
s
=
bs
->
opaque
;
logout
(
"
\n
"
);
logout
(
"
\n
"
);
bdrv_flush
(
s
->
hd
);
bdrv_flush
(
bs
->
file
);
}
}
...
...
block/vmdk.c
浏览文件 @
72375c22
...
@@ -76,7 +76,6 @@ typedef struct BDRVVmdkState {
...
@@ -76,7 +76,6 @@ typedef struct BDRVVmdkState {
unsigned
int
cluster_sectors
;
unsigned
int
cluster_sectors
;
uint32_t
parent_cid
;
uint32_t
parent_cid
;
int
is_parent
;
}
BDRVVmdkState
;
}
BDRVVmdkState
;
typedef
struct
VmdkMetaData
{
typedef
struct
VmdkMetaData
{
...
@@ -87,14 +86,6 @@ typedef struct VmdkMetaData {
...
@@ -87,14 +86,6 @@ typedef struct VmdkMetaData {
int
valid
;
int
valid
;
}
VmdkMetaData
;
}
VmdkMetaData
;
typedef
struct
ActiveBDRVState
{
BlockDriverState
*
hd
;
// active image handler
uint64_t
cluster_offset
;
// current write offset
}
ActiveBDRVState
;
static
ActiveBDRVState
activeBDRV
;
static
int
vmdk_probe
(
const
uint8_t
*
buf
,
int
buf_size
,
const
char
*
filename
)
static
int
vmdk_probe
(
const
uint8_t
*
buf
,
int
buf_size
,
const
char
*
filename
)
{
{
uint32_t
magic
;
uint32_t
magic
;
...
@@ -117,14 +108,13 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
...
@@ -117,14 +108,13 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
static
uint32_t
vmdk_read_cid
(
BlockDriverState
*
bs
,
int
parent
)
static
uint32_t
vmdk_read_cid
(
BlockDriverState
*
bs
,
int
parent
)
{
{
BDRVVmdkState
*
s
=
bs
->
opaque
;
char
desc
[
DESC_SIZE
];
char
desc
[
DESC_SIZE
];
uint32_t
cid
;
uint32_t
cid
;
const
char
*
p_name
,
*
cid_str
;
const
char
*
p_name
,
*
cid_str
;
size_t
cid_str_size
;
size_t
cid_str_size
;
/* the descriptor offset = 0x200 */
/* the descriptor offset = 0x200 */
if
(
bdrv_pread
(
s
->
hd
,
0x200
,
desc
,
DESC_SIZE
)
!=
DESC_SIZE
)
if
(
bdrv_pread
(
bs
->
file
,
0x200
,
desc
,
DESC_SIZE
)
!=
DESC_SIZE
)
return
0
;
return
0
;
if
(
parent
)
{
if
(
parent
)
{
...
@@ -145,12 +135,11 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
...
@@ -145,12 +135,11 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
static
int
vmdk_write_cid
(
BlockDriverState
*
bs
,
uint32_t
cid
)
static
int
vmdk_write_cid
(
BlockDriverState
*
bs
,
uint32_t
cid
)
{
{
BDRVVmdkState
*
s
=
bs
->
opaque
;
char
desc
[
DESC_SIZE
],
tmp_desc
[
DESC_SIZE
];
char
desc
[
DESC_SIZE
],
tmp_desc
[
DESC_SIZE
];
char
*
p_name
,
*
tmp_str
;
char
*
p_name
,
*
tmp_str
;
/* the descriptor offset = 0x200 */
/* the descriptor offset = 0x200 */
if
(
bdrv_pread
(
s
->
hd
,
0x200
,
desc
,
DESC_SIZE
)
!=
DESC_SIZE
)
if
(
bdrv_pread
(
bs
->
file
,
0x200
,
desc
,
DESC_SIZE
)
!=
DESC_SIZE
)
return
-
1
;
return
-
1
;
tmp_str
=
strstr
(
desc
,
"parentCID"
);
tmp_str
=
strstr
(
desc
,
"parentCID"
);
...
@@ -161,7 +150,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
...
@@ -161,7 +150,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
pstrcat
(
desc
,
sizeof
(
desc
),
tmp_desc
);
pstrcat
(
desc
,
sizeof
(
desc
),
tmp_desc
);
}
}
if
(
bdrv_pwrite
(
s
->
hd
,
0x200
,
desc
,
DESC_SIZE
)
!=
DESC_SIZE
)
if
(
bdrv_pwrite
(
bs
->
file
,
0x200
,
desc
,
DESC_SIZE
)
!=
DESC_SIZE
)
return
-
1
;
return
-
1
;
return
0
;
return
0
;
}
}
...
@@ -346,27 +335,17 @@ fail:
...
@@ -346,27 +335,17 @@ fail:
return
ret
;
return
ret
;
}
}
static
void
vmdk_parent_close
(
BlockDriverState
*
bs
)
static
int
vmdk_parent_open
(
BlockDriverState
*
bs
)
{
if
(
bs
->
backing_hd
)
bdrv_close
(
bs
->
backing_hd
);
}
static
int
parent_open
=
0
;
static
int
vmdk_parent_open
(
BlockDriverState
*
bs
,
const
char
*
filename
)
{
{
BDRVVmdkState
*
s
=
bs
->
opaque
;
char
*
p_name
;
char
*
p_name
;
char
desc
[
DESC_SIZE
];
char
desc
[
DESC_SIZE
];
char
parent_img_name
[
1024
];
/* the descriptor offset = 0x200 */
/* the descriptor offset = 0x200 */
if
(
bdrv_pread
(
s
->
hd
,
0x200
,
desc
,
DESC_SIZE
)
!=
DESC_SIZE
)
if
(
bdrv_pread
(
bs
->
file
,
0x200
,
desc
,
DESC_SIZE
)
!=
DESC_SIZE
)
return
-
1
;
return
-
1
;
if
((
p_name
=
strstr
(
desc
,
"parentFileNameHint"
))
!=
NULL
)
{
if
((
p_name
=
strstr
(
desc
,
"parentFileNameHint"
))
!=
NULL
)
{
char
*
end_name
;
char
*
end_name
;
struct
stat
file_buf
;
p_name
+=
sizeof
(
"parentFileNameHint"
)
+
1
;
p_name
+=
sizeof
(
"parentFileNameHint"
)
+
1
;
if
((
end_name
=
strchr
(
p_name
,
'\"'
))
==
NULL
)
if
((
end_name
=
strchr
(
p_name
,
'\"'
))
==
NULL
)
...
@@ -375,51 +354,25 @@ static int vmdk_parent_open(BlockDriverState *bs, const char * filename)
...
@@ -375,51 +354,25 @@ static int vmdk_parent_open(BlockDriverState *bs, const char * filename)
return
-
1
;
return
-
1
;
pstrcpy
(
bs
->
backing_file
,
end_name
-
p_name
+
1
,
p_name
);
pstrcpy
(
bs
->
backing_file
,
end_name
-
p_name
+
1
,
p_name
);
if
(
stat
(
bs
->
backing_file
,
&
file_buf
)
!=
0
)
{
path_combine
(
parent_img_name
,
sizeof
(
parent_img_name
),
filename
,
bs
->
backing_file
);
}
else
{
pstrcpy
(
parent_img_name
,
sizeof
(
parent_img_name
),
bs
->
backing_file
);
}
bs
->
backing_hd
=
bdrv_new
(
""
);
if
(
!
bs
->
backing_hd
)
{
failure:
bdrv_close
(
s
->
hd
);
return
-
1
;
}
parent_open
=
1
;
if
(
bdrv_open
(
bs
->
backing_hd
,
parent_img_name
,
0
,
NULL
)
<
0
)
goto
failure
;
parent_open
=
0
;
}
}
return
0
;
return
0
;
}
}
static
int
vmdk_open
(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
)
static
int
vmdk_open
(
BlockDriverState
*
bs
,
int
flags
)
{
{
BDRVVmdkState
*
s
=
bs
->
opaque
;
BDRVVmdkState
*
s
=
bs
->
opaque
;
uint32_t
magic
;
uint32_t
magic
;
int
l1_size
,
i
,
ret
;
int
l1_size
,
i
;
if
(
parent_open
)
{
if
(
bdrv_pread
(
bs
->
file
,
0
,
&
magic
,
sizeof
(
magic
))
!=
sizeof
(
magic
))
/* Parent must be opened as RO, no RDWR. */
flags
=
0
;
}
ret
=
bdrv_file_open
(
&
s
->
hd
,
filename
,
flags
);
if
(
ret
<
0
)
return
ret
;
if
(
bdrv_pread
(
s
->
hd
,
0
,
&
magic
,
sizeof
(
magic
))
!=
sizeof
(
magic
))
goto
fail
;
goto
fail
;
magic
=
be32_to_cpu
(
magic
);
magic
=
be32_to_cpu
(
magic
);
if
(
magic
==
VMDK3_MAGIC
)
{
if
(
magic
==
VMDK3_MAGIC
)
{
VMDK3Header
header
;
VMDK3Header
header
;
if
(
bdrv_pread
(
s
->
hd
,
sizeof
(
magic
),
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
if
(
bdrv_pread
(
bs
->
file
,
sizeof
(
magic
),
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
goto
fail
;
goto
fail
;
s
->
cluster_sectors
=
le32_to_cpu
(
header
.
granularity
);
s
->
cluster_sectors
=
le32_to_cpu
(
header
.
granularity
);
s
->
l2_size
=
1
<<
9
;
s
->
l2_size
=
1
<<
9
;
...
@@ -431,7 +384,7 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -431,7 +384,7 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
}
else
if
(
magic
==
VMDK4_MAGIC
)
{
}
else
if
(
magic
==
VMDK4_MAGIC
)
{
VMDK4Header
header
;
VMDK4Header
header
;
if
(
bdrv_pread
(
s
->
hd
,
sizeof
(
magic
),
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
if
(
bdrv_pread
(
bs
->
file
,
sizeof
(
magic
),
&
header
,
sizeof
(
header
))
!=
sizeof
(
header
))
goto
fail
;
goto
fail
;
bs
->
total_sectors
=
le64_to_cpu
(
header
.
capacity
);
bs
->
total_sectors
=
le64_to_cpu
(
header
.
capacity
);
s
->
cluster_sectors
=
le64_to_cpu
(
header
.
granularity
);
s
->
cluster_sectors
=
le64_to_cpu
(
header
.
granularity
);
...
@@ -444,13 +397,8 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -444,13 +397,8 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
s
->
l1_table_offset
=
le64_to_cpu
(
header
.
rgd_offset
)
<<
9
;
s
->
l1_table_offset
=
le64_to_cpu
(
header
.
rgd_offset
)
<<
9
;
s
->
l1_backup_table_offset
=
le64_to_cpu
(
header
.
gd_offset
)
<<
9
;
s
->
l1_backup_table_offset
=
le64_to_cpu
(
header
.
gd_offset
)
<<
9
;
if
(
parent_open
)
s
->
is_parent
=
1
;
else
s
->
is_parent
=
0
;
// try to open parent images, if exist
// try to open parent images, if exist
if
(
vmdk_parent_open
(
bs
,
filename
)
!=
0
)
if
(
vmdk_parent_open
(
bs
)
!=
0
)
goto
fail
;
goto
fail
;
// write the CID once after the image creation
// write the CID once after the image creation
s
->
parent_cid
=
vmdk_read_cid
(
bs
,
1
);
s
->
parent_cid
=
vmdk_read_cid
(
bs
,
1
);
...
@@ -461,7 +409,7 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -461,7 +409,7 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
/* read the L1 table */
/* read the L1 table */
l1_size
=
s
->
l1_size
*
sizeof
(
uint32_t
);
l1_size
=
s
->
l1_size
*
sizeof
(
uint32_t
);
s
->
l1_table
=
qemu_malloc
(
l1_size
);
s
->
l1_table
=
qemu_malloc
(
l1_size
);
if
(
bdrv_pread
(
s
->
hd
,
s
->
l1_table_offset
,
s
->
l1_table
,
l1_size
)
!=
l1_size
)
if
(
bdrv_pread
(
bs
->
file
,
s
->
l1_table_offset
,
s
->
l1_table
,
l1_size
)
!=
l1_size
)
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
le32_to_cpus
(
&
s
->
l1_table
[
i
]);
le32_to_cpus
(
&
s
->
l1_table
[
i
]);
...
@@ -469,7 +417,7 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -469,7 +417,7 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
if
(
s
->
l1_backup_table_offset
)
{
if
(
s
->
l1_backup_table_offset
)
{
s
->
l1_backup_table
=
qemu_malloc
(
l1_size
);
s
->
l1_backup_table
=
qemu_malloc
(
l1_size
);
if
(
bdrv_pread
(
s
->
hd
,
s
->
l1_backup_table_offset
,
s
->
l1_backup_table
,
l1_size
)
!=
l1_size
)
if
(
bdrv_pread
(
bs
->
file
,
s
->
l1_backup_table_offset
,
s
->
l1_backup_table
,
l1_size
)
!=
l1_size
)
goto
fail
;
goto
fail
;
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
l1_size
;
i
++
)
{
le32_to_cpus
(
&
s
->
l1_backup_table
[
i
]);
le32_to_cpus
(
&
s
->
l1_backup_table
[
i
]);
...
@@ -482,7 +430,6 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -482,7 +430,6 @@ static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
qemu_free
(
s
->
l1_backup_table
);
qemu_free
(
s
->
l1_backup_table
);
qemu_free
(
s
->
l1_table
);
qemu_free
(
s
->
l1_table
);
qemu_free
(
s
->
l2_cache
);
qemu_free
(
s
->
l2_cache
);
bdrv_delete
(
s
->
hd
);
return
-
1
;
return
-
1
;
}
}
...
@@ -492,30 +439,28 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
...
@@ -492,30 +439,28 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
static
int
get_whole_cluster
(
BlockDriverState
*
bs
,
uint64_t
cluster_offset
,
static
int
get_whole_cluster
(
BlockDriverState
*
bs
,
uint64_t
cluster_offset
,
uint64_t
offset
,
int
allocate
)
uint64_t
offset
,
int
allocate
)
{
{
uint64_t
parent_cluster_offset
;
BDRVVmdkState
*
s
=
bs
->
opaque
;
BDRVVmdkState
*
s
=
bs
->
opaque
;
uint8_t
whole_grain
[
s
->
cluster_sectors
*
512
];
// 128 sectors * 512 bytes each = grain size 64KB
uint8_t
whole_grain
[
s
->
cluster_sectors
*
512
];
// 128 sectors * 512 bytes each = grain size 64KB
// we will be here if it's first write on non-exist grain(cluster).
// we will be here if it's first write on non-exist grain(cluster).
// try to read from parent image, if exist
// try to read from parent image, if exist
if
(
bs
->
backing_hd
)
{
if
(
bs
->
backing_hd
)
{
BDRVVmdkState
*
ps
=
bs
->
backing_hd
->
opaque
;
int
ret
;
if
(
!
vmdk_is_cid_valid
(
bs
))
if
(
!
vmdk_is_cid_valid
(
bs
))
return
-
1
;
return
-
1
;
parent_cluster_offset
=
get_cluster_offset
(
bs
->
backing_hd
,
NULL
,
ret
=
bdrv_read
(
bs
->
backing_hd
,
offset
>>
9
,
whole_grain
,
offset
,
allocate
);
s
->
cluster_sectors
);
if
(
ret
<
0
)
{
if
(
parent_cluster_offset
)
{
return
-
1
;
BDRVVmdkState
*
act_s
=
activeBDRV
.
hd
->
opaque
;
}
if
(
bdrv_pread
(
ps
->
hd
,
parent_cluster_offset
,
whole_grain
,
ps
->
cluster_sectors
*
512
)
!=
ps
->
cluster_sectors
*
512
)
return
-
1
;
//Write grain only into the active image
//Write grain only into the active image
if
(
bdrv_pwrite
(
act_s
->
hd
,
activeBDRV
.
cluster_offset
<<
9
,
whole_grain
,
sizeof
(
whole_grain
))
!=
sizeof
(
whole_grain
))
ret
=
bdrv_write
(
bs
->
file
,
cluster_offset
,
whole_grain
,
return
-
1
;
s
->
cluster_sectors
);
if
(
ret
<
0
)
{
return
-
1
;
}
}
}
}
return
0
;
return
0
;
...
@@ -526,13 +471,13 @@ static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
...
@@ -526,13 +471,13 @@ static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
BDRVVmdkState
*
s
=
bs
->
opaque
;
BDRVVmdkState
*
s
=
bs
->
opaque
;
/* update L2 table */
/* update L2 table */
if
(
bdrv_pwrite
(
s
->
hd
,
((
int64_t
)
m_data
->
l2_offset
*
512
)
+
(
m_data
->
l2_index
*
sizeof
(
m_data
->
offset
)),
if
(
bdrv_pwrite
(
bs
->
file
,
((
int64_t
)
m_data
->
l2_offset
*
512
)
+
(
m_data
->
l2_index
*
sizeof
(
m_data
->
offset
)),
&
(
m_data
->
offset
),
sizeof
(
m_data
->
offset
))
!=
sizeof
(
m_data
->
offset
))
&
(
m_data
->
offset
),
sizeof
(
m_data
->
offset
))
!=
sizeof
(
m_data
->
offset
))
return
-
1
;
return
-
1
;
/* update backup L2 table */
/* update backup L2 table */
if
(
s
->
l1_backup_table_offset
!=
0
)
{
if
(
s
->
l1_backup_table_offset
!=
0
)
{
m_data
->
l2_offset
=
s
->
l1_backup_table
[
m_data
->
l1_index
];
m_data
->
l2_offset
=
s
->
l1_backup_table
[
m_data
->
l1_index
];
if
(
bdrv_pwrite
(
s
->
hd
,
((
int64_t
)
m_data
->
l2_offset
*
512
)
+
(
m_data
->
l2_index
*
sizeof
(
m_data
->
offset
)),
if
(
bdrv_pwrite
(
bs
->
file
,
((
int64_t
)
m_data
->
l2_offset
*
512
)
+
(
m_data
->
l2_index
*
sizeof
(
m_data
->
offset
)),
&
(
m_data
->
offset
),
sizeof
(
m_data
->
offset
))
!=
sizeof
(
m_data
->
offset
))
&
(
m_data
->
offset
),
sizeof
(
m_data
->
offset
))
!=
sizeof
(
m_data
->
offset
))
return
-
1
;
return
-
1
;
}
}
...
@@ -580,7 +525,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
...
@@ -580,7 +525,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
}
}
}
}
l2_table
=
s
->
l2_cache
+
(
min_index
*
s
->
l2_size
);
l2_table
=
s
->
l2_cache
+
(
min_index
*
s
->
l2_size
);
if
(
bdrv_pread
(
s
->
hd
,
(
int64_t
)
l2_offset
*
512
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint32_t
))
!=
if
(
bdrv_pread
(
bs
->
file
,
(
int64_t
)
l2_offset
*
512
,
l2_table
,
s
->
l2_size
*
sizeof
(
uint32_t
))
!=
s
->
l2_size
*
sizeof
(
uint32_t
))
s
->
l2_size
*
sizeof
(
uint32_t
))
return
0
;
return
0
;
...
@@ -593,18 +538,15 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
...
@@ -593,18 +538,15 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
if
(
!
cluster_offset
)
{
if
(
!
cluster_offset
)
{
if
(
!
allocate
)
if
(
!
allocate
)
return
0
;
return
0
;
// Avoid the L2 tables update for the images that have snapshots.
// Avoid the L2 tables update for the images that have snapshots.
if
(
!
s
->
is_parent
)
{
cluster_offset
=
bdrv_getlength
(
bs
->
file
);
cluster_offset
=
bdrv_getlength
(
s
->
hd
);
bdrv_truncate
(
bs
->
file
,
cluster_offset
+
(
s
->
cluster_sectors
<<
9
));
bdrv_truncate
(
s
->
hd
,
cluster_offset
+
(
s
->
cluster_sectors
<<
9
));
cluster_offset
>>=
9
;
cluster_offset
>>=
9
;
tmp
=
cpu_to_le32
(
cluster_offset
);
tmp
=
cpu_to_le32
(
cluster_offset
);
l2_table
[
l2_index
]
=
tmp
;
l2_table
[
l2_index
]
=
tmp
;
// Save the active image state
activeBDRV
.
cluster_offset
=
cluster_offset
;
activeBDRV
.
hd
=
bs
;
}
/* First of all we write grain itself, to avoid race condition
/* First of all we write grain itself, to avoid race condition
* that may to corrupt the image.
* that may to corrupt the image.
* This problem may occur because of insufficient space on host disk
* This problem may occur because of insufficient space on host disk
...
@@ -666,7 +608,7 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
...
@@ -666,7 +608,7 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
memset
(
buf
,
0
,
512
*
n
);
memset
(
buf
,
0
,
512
*
n
);
}
}
}
else
{
}
else
{
if
(
bdrv_pread
(
s
->
hd
,
cluster_offset
+
index_in_cluster
*
512
,
buf
,
n
*
512
)
!=
n
*
512
)
if
(
bdrv_pread
(
bs
->
file
,
cluster_offset
+
index_in_cluster
*
512
,
buf
,
n
*
512
)
!=
n
*
512
)
return
-
1
;
return
-
1
;
}
}
nb_sectors
-=
n
;
nb_sectors
-=
n
;
...
@@ -702,7 +644,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
...
@@ -702,7 +644,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
if
(
!
cluster_offset
)
if
(
!
cluster_offset
)
return
-
1
;
return
-
1
;
if
(
bdrv_pwrite
(
s
->
hd
,
cluster_offset
+
index_in_cluster
*
512
,
buf
,
n
*
512
)
!=
n
*
512
)
if
(
bdrv_pwrite
(
bs
->
file
,
cluster_offset
+
index_in_cluster
*
512
,
buf
,
n
*
512
)
!=
n
*
512
)
return
-
1
;
return
-
1
;
if
(
m_data
.
valid
)
{
if
(
m_data
.
valid
)
{
/* update L2 tables */
/* update L2 tables */
...
@@ -879,15 +821,11 @@ static void vmdk_close(BlockDriverState *bs)
...
@@ -879,15 +821,11 @@ static void vmdk_close(BlockDriverState *bs)
qemu_free
(
s
->
l1_table
);
qemu_free
(
s
->
l1_table
);
qemu_free
(
s
->
l2_cache
);
qemu_free
(
s
->
l2_cache
);
// try to close parent image, if exist
vmdk_parent_close
(
s
->
hd
);
bdrv_delete
(
s
->
hd
);
}
}
static
void
vmdk_flush
(
BlockDriverState
*
bs
)
static
void
vmdk_flush
(
BlockDriverState
*
bs
)
{
{
BDRVVmdkState
*
s
=
bs
->
opaque
;
bdrv_flush
(
bs
->
file
);
bdrv_flush
(
s
->
hd
);
}
}
...
@@ -914,7 +852,7 @@ static BlockDriver bdrv_vmdk = {
...
@@ -914,7 +852,7 @@ static BlockDriver bdrv_vmdk = {
.
format_name
=
"vmdk"
,
.
format_name
=
"vmdk"
,
.
instance_size
=
sizeof
(
BDRVVmdkState
),
.
instance_size
=
sizeof
(
BDRVVmdkState
),
.
bdrv_probe
=
vmdk_probe
,
.
bdrv_probe
=
vmdk_probe
,
.
bdrv_open
=
vmdk_open
,
.
bdrv_open
=
vmdk_open
,
.
bdrv_read
=
vmdk_read
,
.
bdrv_read
=
vmdk_read
,
.
bdrv_write
=
vmdk_write
,
.
bdrv_write
=
vmdk_write
,
.
bdrv_close
=
vmdk_close
,
.
bdrv_close
=
vmdk_close
,
...
...
block/vpc.c
浏览文件 @
72375c22
...
@@ -150,20 +150,16 @@ static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
...
@@ -150,20 +150,16 @@ static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
return
0
;
return
0
;
}
}
static
int
vpc_open
(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
)
static
int
vpc_open
(
BlockDriverState
*
bs
,
int
flags
)
{
{
BDRVVPCState
*
s
=
bs
->
opaque
;
BDRVVPCState
*
s
=
bs
->
opaque
;
int
ret
,
i
;
int
i
;
struct
vhd_footer
*
footer
;
struct
vhd_footer
*
footer
;
struct
vhd_dyndisk_header
*
dyndisk_header
;
struct
vhd_dyndisk_header
*
dyndisk_header
;
uint8_t
buf
[
HEADER_SIZE
];
uint8_t
buf
[
HEADER_SIZE
];
uint32_t
checksum
;
uint32_t
checksum
;
ret
=
bdrv_file_open
(
&
s
->
hd
,
filename
,
flags
);
if
(
bdrv_pread
(
bs
->
file
,
0
,
s
->
footer_buf
,
HEADER_SIZE
)
!=
HEADER_SIZE
)
if
(
ret
<
0
)
return
ret
;
if
(
bdrv_pread
(
s
->
hd
,
0
,
s
->
footer_buf
,
HEADER_SIZE
)
!=
HEADER_SIZE
)
goto
fail
;
goto
fail
;
footer
=
(
struct
vhd_footer
*
)
s
->
footer_buf
;
footer
=
(
struct
vhd_footer
*
)
s
->
footer_buf
;
...
@@ -174,7 +170,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -174,7 +170,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
footer
->
checksum
=
0
;
footer
->
checksum
=
0
;
if
(
vpc_checksum
(
s
->
footer_buf
,
HEADER_SIZE
)
!=
checksum
)
if
(
vpc_checksum
(
s
->
footer_buf
,
HEADER_SIZE
)
!=
checksum
)
fprintf
(
stderr
,
"block-vpc: The header checksum of '%s' is "
fprintf
(
stderr
,
"block-vpc: The header checksum of '%s' is "
"incorrect.
\n
"
,
filename
);
"incorrect.
\n
"
,
bs
->
filename
);
// The visible size of a image in Virtual PC depends on the geometry
// The visible size of a image in Virtual PC depends on the geometry
// rather than on the size stored in the footer (the size in the footer
// rather than on the size stored in the footer (the size in the footer
...
@@ -182,7 +178,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -182,7 +178,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
bs
->
total_sectors
=
(
int64_t
)
bs
->
total_sectors
=
(
int64_t
)
be16_to_cpu
(
footer
->
cyls
)
*
footer
->
heads
*
footer
->
secs_per_cyl
;
be16_to_cpu
(
footer
->
cyls
)
*
footer
->
heads
*
footer
->
secs_per_cyl
;
if
(
bdrv_pread
(
s
->
hd
,
be64_to_cpu
(
footer
->
data_offset
),
buf
,
HEADER_SIZE
)
if
(
bdrv_pread
(
bs
->
file
,
be64_to_cpu
(
footer
->
data_offset
),
buf
,
HEADER_SIZE
)
!=
HEADER_SIZE
)
!=
HEADER_SIZE
)
goto
fail
;
goto
fail
;
...
@@ -199,7 +195,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -199,7 +195,7 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
s
->
pagetable
=
qemu_malloc
(
s
->
max_table_entries
*
4
);
s
->
pagetable
=
qemu_malloc
(
s
->
max_table_entries
*
4
);
s
->
bat_offset
=
be64_to_cpu
(
dyndisk_header
->
table_offset
);
s
->
bat_offset
=
be64_to_cpu
(
dyndisk_header
->
table_offset
);
if
(
bdrv_pread
(
s
->
hd
,
s
->
bat_offset
,
s
->
pagetable
,
if
(
bdrv_pread
(
bs
->
file
,
s
->
bat_offset
,
s
->
pagetable
,
s
->
max_table_entries
*
4
)
!=
s
->
max_table_entries
*
4
)
s
->
max_table_entries
*
4
)
!=
s
->
max_table_entries
*
4
)
goto
fail
;
goto
fail
;
...
@@ -228,7 +224,6 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
...
@@ -228,7 +224,6 @@ static int vpc_open(BlockDriverState *bs, const char *filename, int flags)
return
0
;
return
0
;
fail:
fail:
bdrv_delete
(
s
->
hd
);
return
-
1
;
return
-
1
;
}
}
...
@@ -266,7 +261,7 @@ static inline int64_t get_sector_offset(BlockDriverState *bs,
...
@@ -266,7 +261,7 @@ static inline int64_t get_sector_offset(BlockDriverState *bs,
s
->
last_bitmap_offset
=
bitmap_offset
;
s
->
last_bitmap_offset
=
bitmap_offset
;
memset
(
bitmap
,
0xff
,
s
->
bitmap_size
);
memset
(
bitmap
,
0xff
,
s
->
bitmap_size
);
bdrv_pwrite
(
s
->
hd
,
bitmap_offset
,
bitmap
,
s
->
bitmap_size
);
bdrv_pwrite
(
bs
->
file
,
bitmap_offset
,
bitmap
,
s
->
bitmap_size
);
}
}
// printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
// printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
...
@@ -316,7 +311,7 @@ static int rewrite_footer(BlockDriverState* bs)
...
@@ -316,7 +311,7 @@ static int rewrite_footer(BlockDriverState* bs)
BDRVVPCState
*
s
=
bs
->
opaque
;
BDRVVPCState
*
s
=
bs
->
opaque
;
int64_t
offset
=
s
->
free_data_block_offset
;
int64_t
offset
=
s
->
free_data_block_offset
;
ret
=
bdrv_pwrite
(
s
->
hd
,
offset
,
s
->
footer_buf
,
HEADER_SIZE
);
ret
=
bdrv_pwrite
(
bs
->
file
,
offset
,
s
->
footer_buf
,
HEADER_SIZE
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -351,7 +346,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
...
@@ -351,7 +346,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
// Initialize the block's bitmap
// Initialize the block's bitmap
memset
(
bitmap
,
0xff
,
s
->
bitmap_size
);
memset
(
bitmap
,
0xff
,
s
->
bitmap_size
);
bdrv_pwrite
(
s
->
hd
,
s
->
free_data_block_offset
,
bitmap
,
s
->
bitmap_size
);
bdrv_pwrite
(
bs
->
file
,
s
->
free_data_block_offset
,
bitmap
,
s
->
bitmap_size
);
// Write new footer (the old one will be overwritten)
// Write new footer (the old one will be overwritten)
s
->
free_data_block_offset
+=
s
->
block_size
+
s
->
bitmap_size
;
s
->
free_data_block_offset
+=
s
->
block_size
+
s
->
bitmap_size
;
...
@@ -362,7 +357,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
...
@@ -362,7 +357,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
// Write BAT entry to disk
// Write BAT entry to disk
bat_offset
=
s
->
bat_offset
+
(
4
*
index
);
bat_offset
=
s
->
bat_offset
+
(
4
*
index
);
bat_value
=
be32_to_cpu
(
s
->
pagetable
[
index
]);
bat_value
=
be32_to_cpu
(
s
->
pagetable
[
index
]);
ret
=
bdrv_pwrite
(
s
->
hd
,
bat_offset
,
&
bat_value
,
4
);
ret
=
bdrv_pwrite
(
bs
->
file
,
bat_offset
,
&
bat_value
,
4
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
fail
;
goto
fail
;
...
@@ -376,7 +371,6 @@ fail:
...
@@ -376,7 +371,6 @@ fail:
static
int
vpc_read
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
static
int
vpc_read
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
uint8_t
*
buf
,
int
nb_sectors
)
uint8_t
*
buf
,
int
nb_sectors
)
{
{
BDRVVPCState
*
s
=
bs
->
opaque
;
int
ret
;
int
ret
;
int64_t
offset
;
int64_t
offset
;
...
@@ -386,7 +380,7 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
...
@@ -386,7 +380,7 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
if
(
offset
==
-
1
)
{
if
(
offset
==
-
1
)
{
memset
(
buf
,
0
,
512
);
memset
(
buf
,
0
,
512
);
}
else
{
}
else
{
ret
=
bdrv_pread
(
s
->
hd
,
offset
,
buf
,
512
);
ret
=
bdrv_pread
(
bs
->
file
,
offset
,
buf
,
512
);
if
(
ret
!=
512
)
if
(
ret
!=
512
)
return
-
1
;
return
-
1
;
}
}
...
@@ -401,7 +395,6 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
...
@@ -401,7 +395,6 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
static
int
vpc_write
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
static
int
vpc_write
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
const
uint8_t
*
buf
,
int
nb_sectors
)
const
uint8_t
*
buf
,
int
nb_sectors
)
{
{
BDRVVPCState
*
s
=
bs
->
opaque
;
int64_t
offset
;
int64_t
offset
;
int
ret
;
int
ret
;
...
@@ -414,7 +407,7 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
...
@@ -414,7 +407,7 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
return
-
1
;
return
-
1
;
}
}
ret
=
bdrv_pwrite
(
s
->
hd
,
offset
,
buf
,
512
);
ret
=
bdrv_pwrite
(
bs
->
file
,
offset
,
buf
,
512
);
if
(
ret
!=
512
)
if
(
ret
!=
512
)
return
-
1
;
return
-
1
;
...
@@ -590,7 +583,6 @@ static void vpc_close(BlockDriverState *bs)
...
@@ -590,7 +583,6 @@ static void vpc_close(BlockDriverState *bs)
#ifdef CACHE
#ifdef CACHE
qemu_free
(
s
->
pageentry_u8
);
qemu_free
(
s
->
pageentry_u8
);
#endif
#endif
bdrv_delete
(
s
->
hd
);
}
}
static
QEMUOptionParameter
vpc_create_options
[]
=
{
static
QEMUOptionParameter
vpc_create_options
[]
=
{
...
...
block/vvfat.c
浏览文件 @
72375c22
...
@@ -2827,7 +2827,7 @@ static void vvfat_close(BlockDriverState *bs)
...
@@ -2827,7 +2827,7 @@ static void vvfat_close(BlockDriverState *bs)
static
BlockDriver
bdrv_vvfat
=
{
static
BlockDriver
bdrv_vvfat
=
{
.
format_name
=
"vvfat"
,
.
format_name
=
"vvfat"
,
.
instance_size
=
sizeof
(
BDRVVVFATState
),
.
instance_size
=
sizeof
(
BDRVVVFATState
),
.
bdrv_
open
=
vvfat_open
,
.
bdrv_
file_open
=
vvfat_open
,
.
bdrv_read
=
vvfat_read
,
.
bdrv_read
=
vvfat_read
,
.
bdrv_write
=
vvfat_write
,
.
bdrv_write
=
vvfat_write
,
.
bdrv_close
=
vvfat_close
,
.
bdrv_close
=
vvfat_close
,
...
...
block_int.h
浏览文件 @
72375c22
...
@@ -51,7 +51,8 @@ struct BlockDriver {
...
@@ -51,7 +51,8 @@ struct BlockDriver {
int
instance_size
;
int
instance_size
;
int
(
*
bdrv_probe
)(
const
uint8_t
*
buf
,
int
buf_size
,
const
char
*
filename
);
int
(
*
bdrv_probe
)(
const
uint8_t
*
buf
,
int
buf_size
,
const
char
*
filename
);
int
(
*
bdrv_probe_device
)(
const
char
*
filename
);
int
(
*
bdrv_probe_device
)(
const
char
*
filename
);
int
(
*
bdrv_open
)(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
);
int
(
*
bdrv_open
)(
BlockDriverState
*
bs
,
int
flags
);
int
(
*
bdrv_file_open
)(
BlockDriverState
*
bs
,
const
char
*
filename
,
int
flags
);
int
(
*
bdrv_read
)(
BlockDriverState
*
bs
,
int64_t
sector_num
,
int
(
*
bdrv_read
)(
BlockDriverState
*
bs
,
int64_t
sector_num
,
uint8_t
*
buf
,
int
nb_sectors
);
uint8_t
*
buf
,
int
nb_sectors
);
int
(
*
bdrv_write
)(
BlockDriverState
*
bs
,
int64_t
sector_num
,
int
(
*
bdrv_write
)(
BlockDriverState
*
bs
,
int64_t
sector_num
,
...
@@ -155,6 +156,8 @@ struct BlockDriverState {
...
@@ -155,6 +156,8 @@ struct BlockDriverState {
int
media_changed
;
int
media_changed
;
BlockDriverState
*
backing_hd
;
BlockDriverState
*
backing_hd
;
BlockDriverState
*
file
;
/* async read/write emulation */
/* async read/write emulation */
void
*
sync_aiocb
;
void
*
sync_aiocb
;
...
@@ -164,6 +167,7 @@ struct BlockDriverState {
...
@@ -164,6 +167,7 @@ struct BlockDriverState {
uint64_t
wr_bytes
;
uint64_t
wr_bytes
;
uint64_t
rd_ops
;
uint64_t
rd_ops
;
uint64_t
wr_ops
;
uint64_t
wr_ops
;
uint64_t
wr_highest_sector
;
/* Whether the disk can expand beyond total_sectors */
/* Whether the disk can expand beyond total_sectors */
int
growable
;
int
growable
;
...
...
qemu-img-cmds.hx
浏览文件 @
72375c22
...
@@ -49,5 +49,11 @@ DEF("rebase", img_rebase,
...
@@ -49,5 +49,11 @@ DEF("rebase", img_rebase,
"rebase [-f fmt] [-u] -b backing_file [-F backing_fmt] filename"
)
"rebase [-f fmt] [-u] -b backing_file [-F backing_fmt] filename"
)
STEXI
STEXI
@item
rebase
[
-
f
@var
{
fmt
}]
[
-
u
]
-
b
@var
{
backing_file
}
[
-
F
@var
{
backing_fmt
}]
@var
{
filename
}
@item
rebase
[
-
f
@var
{
fmt
}]
[
-
u
]
-
b
@var
{
backing_file
}
[
-
F
@var
{
backing_fmt
}]
@var
{
filename
}
ETEXI
DEF
(
"resize"
,
img_resize
,
"resize filename [+ | -]size"
)
STEXI
@item
rebase
@var
{
filename
}
[
+
|
-
]
@var
{
size
}
@end
table
@end
table
ETEXI
ETEXI
qemu-img.c
浏览文件 @
72375c22
...
@@ -732,6 +732,8 @@ static int img_convert(int argc, char **argv)
...
@@ -732,6 +732,8 @@ static int img_convert(int argc, char **argv)
/* signal EOF to align */
/* signal EOF to align */
bdrv_write_compressed
(
out_bs
,
0
,
NULL
,
0
);
bdrv_write_compressed
(
out_bs
,
0
,
NULL
,
0
);
}
else
{
}
else
{
int
has_zero_init
=
bdrv_has_zero_init
(
out_bs
);
sector_num
=
0
;
// total number of sectors converted so far
sector_num
=
0
;
// total number of sectors converted so far
for
(;;)
{
for
(;;)
{
nb_sectors
=
total_sectors
-
sector_num
;
nb_sectors
=
total_sectors
-
sector_num
;
...
@@ -755,7 +757,7 @@ static int img_convert(int argc, char **argv)
...
@@ -755,7 +757,7 @@ static int img_convert(int argc, char **argv)
if
(
n
>
bs_offset
+
bs_sectors
-
sector_num
)
if
(
n
>
bs_offset
+
bs_sectors
-
sector_num
)
n
=
bs_offset
+
bs_sectors
-
sector_num
;
n
=
bs_offset
+
bs_sectors
-
sector_num
;
if
(
!
drv
->
no
_zero_init
)
{
if
(
has
_zero_init
)
{
/* If the output image is being created as a copy on write image,
/* If the output image is being created as a copy on write image,
assume that sectors which are unallocated in the input image
assume that sectors which are unallocated in the input image
are present in both the output's and input's base images (no
are present in both the output's and input's base images (no
...
@@ -788,7 +790,7 @@ static int img_convert(int argc, char **argv)
...
@@ -788,7 +790,7 @@ static int img_convert(int argc, char **argv)
If the output is to a host device, we also write out
If the output is to a host device, we also write out
sectors that are entirely 0, since whatever data was
sectors that are entirely 0, since whatever data was
already there is garbage, not 0s. */
already there is garbage, not 0s. */
if
(
drv
->
no
_zero_init
||
out_baseimg
||
if
(
!
has
_zero_init
||
out_baseimg
||
is_allocated_sectors
(
buf1
,
n
,
&
n1
))
{
is_allocated_sectors
(
buf1
,
n
,
&
n1
))
{
if
(
bdrv_write
(
out_bs
,
sector_num
,
buf1
,
n1
)
<
0
)
if
(
bdrv_write
(
out_bs
,
sector_num
,
buf1
,
n1
)
<
0
)
error
(
"error while writing"
);
error
(
"error while writing"
);
...
@@ -1134,7 +1136,7 @@ static int img_rebase(int argc, char **argv)
...
@@ -1134,7 +1136,7 @@ static int img_rebase(int argc, char **argv)
if
(
!
unsafe
)
{
if
(
!
unsafe
)
{
uint64_t
num_sectors
;
uint64_t
num_sectors
;
uint64_t
sector
;
uint64_t
sector
;
int
n
,
n1
;
int
n
;
uint8_t
*
buf_old
;
uint8_t
*
buf_old
;
uint8_t
*
buf_new
;
uint8_t
*
buf_new
;
...
@@ -1153,8 +1155,8 @@ static int img_rebase(int argc, char **argv)
...
@@ -1153,8 +1155,8 @@ static int img_rebase(int argc, char **argv)
}
}
/* If the cluster is allocated, we don't need to take action */
/* If the cluster is allocated, we don't need to take action */
if
(
bdrv_is_allocated
(
bs
,
sector
,
n
,
&
n1
))
{
ret
=
bdrv_is_allocated
(
bs
,
sector
,
n
,
&
n
);
n
=
n1
;
if
(
ret
)
{
continue
;
continue
;
}
}
...
@@ -1223,6 +1225,98 @@ static int img_rebase(int argc, char **argv)
...
@@ -1223,6 +1225,98 @@ static int img_rebase(int argc, char **argv)
return
0
;
return
0
;
}
}
static
int
img_resize
(
int
argc
,
char
**
argv
)
{
int
c
,
ret
,
relative
;
const
char
*
filename
,
*
fmt
,
*
size
;
int64_t
n
,
total_size
;
BlockDriverState
*
bs
;
QEMUOptionParameter
*
param
;
QEMUOptionParameter
resize_options
[]
=
{
{
.
name
=
BLOCK_OPT_SIZE
,
.
type
=
OPT_SIZE
,
.
help
=
"Virtual disk size"
},
{
NULL
}
};
fmt
=
NULL
;
for
(;;)
{
c
=
getopt
(
argc
,
argv
,
"f:h"
);
if
(
c
==
-
1
)
{
break
;
}
switch
(
c
)
{
case
'h'
:
help
();
break
;
case
'f'
:
fmt
=
optarg
;
break
;
}
}
if
(
optind
+
1
>=
argc
)
{
help
();
}
filename
=
argv
[
optind
++
];
size
=
argv
[
optind
++
];
/* Choose grow, shrink, or absolute resize mode */
switch
(
size
[
0
])
{
case
'+'
:
relative
=
1
;
size
++
;
break
;
case
'-'
:
relative
=
-
1
;
size
++
;
break
;
default:
relative
=
0
;
break
;
}
/* Parse size */
param
=
parse_option_parameters
(
""
,
resize_options
,
NULL
);
if
(
set_option_parameter
(
param
,
BLOCK_OPT_SIZE
,
size
))
{
/* Error message already printed when size parsing fails */
exit
(
1
);
}
n
=
get_option_parameter
(
param
,
BLOCK_OPT_SIZE
)
->
value
.
n
;
free_option_parameters
(
param
);
bs
=
bdrv_new_open
(
filename
,
fmt
,
BDRV_O_FLAGS
|
BDRV_O_RDWR
);
if
(
relative
)
{
total_size
=
bdrv_getlength
(
bs
)
+
n
*
relative
;
}
else
{
total_size
=
n
;
}
if
(
total_size
<=
0
)
{
error
(
"New image size must be positive"
);
}
ret
=
bdrv_truncate
(
bs
,
total_size
);
switch
(
ret
)
{
case
0
:
printf
(
"Image resized.
\n
"
);
break
;
case
-
ENOTSUP
:
error
(
"This image format does not support resize"
);
break
;
case
-
EACCES
:
error
(
"Image is read-only"
);
break
;
default:
error
(
"Error resizing image (%d)"
,
-
ret
);
break
;
}
bdrv_delete
(
bs
);
return
0
;
}
static
const
img_cmd_t
img_cmds
[]
=
{
static
const
img_cmd_t
img_cmds
[]
=
{
#define DEF(option, callback, arg_string) \
#define DEF(option, callback, arg_string) \
{ option, callback },
{ option, callback },
...
...
qemu-img.texi
浏览文件 @
72375c22
...
@@ -106,6 +106,18 @@ they are displayed too.
...
@@ -106,6 +106,18 @@ they are displayed too.
@item snapshot [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot} ] @var{filename}
@item snapshot [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot} ] @var{filename}
List, apply, create or delete snapshots in image @var{filename}.
List, apply, create or delete snapshots in image @var{filename}.
@item resize @var{filename} [+ | -]@var{size}
Change the disk image as if it had been created with @var{size}.
Before using this command to shrink a disk image, you MUST use file system and
partitioning tools inside the VM to reduce allocated file systems and partition
sizes accordingly. Failure to do so will result in data loss!
After using this command to grow a disk image, you must use file system and
partitioning tools inside the VM to actually begin using the new space on the
device.
@end table
@end table
Supported image file formats:
Supported image file formats:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录