Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
5efb397f
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5efb397f
编写于
7月 06, 2010
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'kwolf/for-anthony' into staging
上级
fb787f81
33b1db1c
变更
27
展开全部
隐藏空白更改
内联
并排
Showing
27 changed file
with
2308 addition
and
141 deletion
+2308
-141
Makefile.objs
Makefile.objs
+1
-1
block-migration.c
block-migration.c
+1
-1
block.c
block.c
+6
-3
block.h
block.h
+9
-1
block/qcow2-refcount.c
block/qcow2-refcount.c
+65
-55
block/qcow2.c
block/qcow2.c
+2
-2
block/qcow2.h
block/qcow2.h
+1
-1
block/raw-posix.c
block/raw-posix.c
+6
-11
block/sheepdog.c
block/sheepdog.c
+2036
-0
block/vdi.c
block/vdi.c
+5
-5
block_int.h
block_int.h
+5
-2
blockdev.c
blockdev.c
+1
-1
hw/fdc.c
hw/fdc.c
+16
-6
hw/ide/core.c
hw/ide/core.c
+46
-24
hw/ide/internal.h
hw/ide/internal.h
+5
-4
hw/ide/macio.c
hw/ide/macio.c
+1
-1
hw/ide/microdrive.c
hw/ide/microdrive.c
+1
-1
hw/ide/qdev.c
hw/ide/qdev.c
+8
-5
hw/qdev.c
hw/qdev.c
+4
-2
hw/scsi-bus.c
hw/scsi-bus.c
+4
-0
hw/scsi-disk.c
hw/scsi-disk.c
+5
-0
hw/scsi-generic.c
hw/scsi-generic.c
+9
-0
hw/virtio-blk.c
hw/virtio-blk.c
+14
-0
hw/virtio-blk.h
hw/virtio-blk.h
+3
-0
qemu-img.c
qemu-img.c
+48
-15
qemu-option.c
qemu-option.c
+5
-0
qemu-option.h
qemu-option.h
+1
-0
未找到文件。
Makefile.objs
浏览文件 @
5efb397f
...
@@ -14,7 +14,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
...
@@ -14,7 +14,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.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
+=
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
sheepdog.o
block-nested-$(CONFIG_WIN32)
+=
raw-win32.o
block-nested-$(CONFIG_WIN32)
+=
raw-win32.o
block-nested-$(CONFIG_POSIX)
+=
raw-posix.o
block-nested-$(CONFIG_POSIX)
+=
raw-posix.o
block-nested-$(CONFIG_CURL)
+=
curl.o
block-nested-$(CONFIG_CURL)
+=
curl.o
...
...
block-migration.c
浏览文件 @
5efb397f
...
@@ -236,7 +236,7 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
...
@@ -236,7 +236,7 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
BlkMigDevState
*
bmds
;
BlkMigDevState
*
bmds
;
int64_t
sectors
;
int64_t
sectors
;
if
(
bs
->
type
==
BDRV_TYPE_HD
)
{
if
(
!
bdrv_is_read_only
(
bs
)
)
{
sectors
=
bdrv_getlength
(
bs
)
>>
BDRV_SECTOR_BITS
;
sectors
=
bdrv_getlength
(
bs
)
>>
BDRV_SECTOR_BITS
;
if
(
sectors
==
0
)
{
if
(
sectors
==
0
)
{
return
;
return
;
...
...
block.c
浏览文件 @
5efb397f
...
@@ -710,15 +710,18 @@ DeviceState *bdrv_get_attached(BlockDriverState *bs)
...
@@ -710,15 +710,18 @@ DeviceState *bdrv_get_attached(BlockDriverState *bs)
/*
/*
* Run consistency checks on an image
* Run consistency checks on an image
*
*
* Returns the number of errors or -errno when an internal error occurs
* Returns 0 if the check could be completed (it doesn't mean that the image is
* free of errors) or -errno when an internal error occured. The results of the
* check are stored in res.
*/
*/
int
bdrv_check
(
BlockDriverState
*
bs
)
int
bdrv_check
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
res
)
{
{
if
(
bs
->
drv
->
bdrv_check
==
NULL
)
{
if
(
bs
->
drv
->
bdrv_check
==
NULL
)
{
return
-
ENOTSUP
;
return
-
ENOTSUP
;
}
}
return
bs
->
drv
->
bdrv_check
(
bs
);
memset
(
res
,
0
,
sizeof
(
*
res
));
return
bs
->
drv
->
bdrv_check
(
bs
,
res
);
}
}
/* commit COW file into the raw image */
/* commit COW file into the raw image */
...
...
block.h
浏览文件 @
5efb397f
...
@@ -74,7 +74,6 @@ void bdrv_close(BlockDriverState *bs);
...
@@ -74,7 +74,6 @@ void bdrv_close(BlockDriverState *bs);
int
bdrv_attach
(
BlockDriverState
*
bs
,
DeviceState
*
qdev
);
int
bdrv_attach
(
BlockDriverState
*
bs
,
DeviceState
*
qdev
);
void
bdrv_detach
(
BlockDriverState
*
bs
,
DeviceState
*
qdev
);
void
bdrv_detach
(
BlockDriverState
*
bs
,
DeviceState
*
qdev
);
DeviceState
*
bdrv_get_attached
(
BlockDriverState
*
bs
);
DeviceState
*
bdrv_get_attached
(
BlockDriverState
*
bs
);
int
bdrv_check
(
BlockDriverState
*
bs
);
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
,
...
@@ -97,6 +96,15 @@ int bdrv_change_backing_file(BlockDriverState *bs,
...
@@ -97,6 +96,15 @@ int bdrv_change_backing_file(BlockDriverState *bs,
const
char
*
backing_file
,
const
char
*
backing_fmt
);
const
char
*
backing_file
,
const
char
*
backing_fmt
);
void
bdrv_register
(
BlockDriver
*
bdrv
);
void
bdrv_register
(
BlockDriver
*
bdrv
);
typedef
struct
BdrvCheckResult
{
int
corruptions
;
int
leaks
;
int
check_errors
;
}
BdrvCheckResult
;
int
bdrv_check
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
res
);
/* async block I/O */
/* async block I/O */
typedef
struct
BlockDriverAIOCB
BlockDriverAIOCB
;
typedef
struct
BlockDriverAIOCB
BlockDriverAIOCB
;
typedef
void
BlockDriverCompletionFunc
(
void
*
opaque
,
int
ret
);
typedef
void
BlockDriverCompletionFunc
(
void
*
opaque
,
int
ret
);
...
...
block/qcow2-refcount.c
浏览文件 @
5efb397f
...
@@ -884,9 +884,10 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
...
@@ -884,9 +884,10 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
* This is used to construct a temporary refcount table out of L1 and L2 tables
* This is used to construct a temporary refcount table out of L1 and L2 tables
* which can be compared the the refcount table saved in the image.
* which can be compared the the refcount table saved in the image.
*
*
*
Returns the number of errors in the image that were found
*
Modifies the number of errors in res.
*/
*/
static
int
inc_refcounts
(
BlockDriverState
*
bs
,
static
void
inc_refcounts
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
res
,
uint16_t
*
refcount_table
,
uint16_t
*
refcount_table
,
int
refcount_table_size
,
int
refcount_table_size
,
int64_t
offset
,
int64_t
size
)
int64_t
offset
,
int64_t
size
)
...
@@ -894,30 +895,32 @@ static int inc_refcounts(BlockDriverState *bs,
...
@@ -894,30 +895,32 @@ static int inc_refcounts(BlockDriverState *bs,
BDRVQcowState
*
s
=
bs
->
opaque
;
BDRVQcowState
*
s
=
bs
->
opaque
;
int64_t
start
,
last
,
cluster_offset
;
int64_t
start
,
last
,
cluster_offset
;
int
k
;
int
k
;
int
errors
=
0
;
if
(
size
<=
0
)
if
(
size
<=
0
)
return
0
;
return
;
start
=
offset
&
~
(
s
->
cluster_size
-
1
);
start
=
offset
&
~
(
s
->
cluster_size
-
1
);
last
=
(
offset
+
size
-
1
)
&
~
(
s
->
cluster_size
-
1
);
last
=
(
offset
+
size
-
1
)
&
~
(
s
->
cluster_size
-
1
);
for
(
cluster_offset
=
start
;
cluster_offset
<=
last
;
for
(
cluster_offset
=
start
;
cluster_offset
<=
last
;
cluster_offset
+=
s
->
cluster_size
)
{
cluster_offset
+=
s
->
cluster_size
)
{
k
=
cluster_offset
>>
s
->
cluster_bits
;
k
=
cluster_offset
>>
s
->
cluster_bits
;
if
(
k
<
0
||
k
>=
refcount_table_size
)
{
if
(
k
<
0
)
{
fprintf
(
stderr
,
"ERROR: invalid cluster offset=0x%"
PRIx64
"
\n
"
,
fprintf
(
stderr
,
"ERROR: invalid cluster offset=0x%"
PRIx64
"
\n
"
,
cluster_offset
);
cluster_offset
);
errors
++
;
res
->
corruptions
++
;
}
else
if
(
k
>=
refcount_table_size
)
{
fprintf
(
stderr
,
"Warning: cluster offset=0x%"
PRIx64
" is after "
"the end of the image file, can't properly check refcounts.
\n
"
,
cluster_offset
);
res
->
check_errors
++
;
}
else
{
}
else
{
if
(
++
refcount_table
[
k
]
==
0
)
{
if
(
++
refcount_table
[
k
]
==
0
)
{
fprintf
(
stderr
,
"ERROR: overflow cluster offset=0x%"
PRIx64
fprintf
(
stderr
,
"ERROR: overflow cluster offset=0x%"
PRIx64
"
\n
"
,
cluster_offset
);
"
\n
"
,
cluster_offset
);
error
s
++
;
res
->
corruption
s
++
;
}
}
}
}
}
}
return
errors
;
}
}
/*
/*
...
@@ -928,14 +931,13 @@ static int inc_refcounts(BlockDriverState *bs,
...
@@ -928,14 +931,13 @@ static int inc_refcounts(BlockDriverState *bs,
* Returns the number of errors found by the checks or -errno if an internal
* Returns the number of errors found by the checks or -errno if an internal
* error occurred.
* error occurred.
*/
*/
static
int
check_refcounts_l2
(
BlockDriverState
*
bs
,
static
int
check_refcounts_l2
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
res
,
uint16_t
*
refcount_table
,
int
refcount_table_size
,
int64_t
l2_offset
,
uint16_t
*
refcount_table
,
int
refcount_table_size
,
int64_t
l2_offset
,
int
check_copied
)
int
check_copied
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
BDRVQcowState
*
s
=
bs
->
opaque
;
uint64_t
*
l2_table
,
offset
;
uint64_t
*
l2_table
,
offset
;
int
i
,
l2_size
,
nb_csectors
,
refcount
;
int
i
,
l2_size
,
nb_csectors
,
refcount
;
int
errors
=
0
;
/* Read L2 table from disk */
/* Read L2 table from disk */
l2_size
=
s
->
l2_size
*
sizeof
(
uint64_t
);
l2_size
=
s
->
l2_size
*
sizeof
(
uint64_t
);
...
@@ -955,16 +957,15 @@ static int check_refcounts_l2(BlockDriverState *bs,
...
@@ -955,16 +957,15 @@ static int check_refcounts_l2(BlockDriverState *bs,
"copied flag must never be set for compressed "
"copied flag must never be set for compressed "
"clusters
\n
"
,
offset
>>
s
->
cluster_bits
);
"clusters
\n
"
,
offset
>>
s
->
cluster_bits
);
offset
&=
~
QCOW_OFLAG_COPIED
;
offset
&=
~
QCOW_OFLAG_COPIED
;
error
s
++
;
res
->
corruption
s
++
;
}
}
/* Mark cluster as used */
/* Mark cluster as used */
nb_csectors
=
((
offset
>>
s
->
csize_shift
)
&
nb_csectors
=
((
offset
>>
s
->
csize_shift
)
&
s
->
csize_mask
)
+
1
;
s
->
csize_mask
)
+
1
;
offset
&=
s
->
cluster_offset_mask
;
offset
&=
s
->
cluster_offset_mask
;
errors
+=
inc_refcounts
(
bs
,
refcount_table
,
inc_refcounts
(
bs
,
res
,
refcount_table
,
refcount_table_size
,
refcount_table_size
,
offset
&
~
511
,
nb_csectors
*
512
);
offset
&
~
511
,
nb_csectors
*
512
);
}
else
{
}
else
{
/* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
/* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
if
(
check_copied
)
{
if
(
check_copied
)
{
...
@@ -974,35 +975,35 @@ static int check_refcounts_l2(BlockDriverState *bs,
...
@@ -974,35 +975,35 @@ static int check_refcounts_l2(BlockDriverState *bs,
if
(
refcount
<
0
)
{
if
(
refcount
<
0
)
{
fprintf
(
stderr
,
"Can't get refcount for offset %"
fprintf
(
stderr
,
"Can't get refcount for offset %"
PRIx64
": %s
\n
"
,
entry
,
strerror
(
-
refcount
));
PRIx64
": %s
\n
"
,
entry
,
strerror
(
-
refcount
));
goto
fail
;
}
}
if
((
refcount
==
1
)
!=
((
entry
&
QCOW_OFLAG_COPIED
)
!=
0
))
{
if
((
refcount
==
1
)
!=
((
entry
&
QCOW_OFLAG_COPIED
)
!=
0
))
{
fprintf
(
stderr
,
"ERROR OFLAG_COPIED: offset=%"
fprintf
(
stderr
,
"ERROR OFLAG_COPIED: offset=%"
PRIx64
" refcount=%d
\n
"
,
entry
,
refcount
);
PRIx64
" refcount=%d
\n
"
,
entry
,
refcount
);
error
s
++
;
res
->
corruption
s
++
;
}
}
}
}
/* Mark cluster as used */
/* Mark cluster as used */
offset
&=
~
QCOW_OFLAG_COPIED
;
offset
&=
~
QCOW_OFLAG_COPIED
;
errors
+=
inc_refcounts
(
bs
,
refcount_table
,
inc_refcounts
(
bs
,
res
,
refcount_table
,
refcount_table_size
,
refcount_table_size
,
offset
,
s
->
cluster_size
);
offset
,
s
->
cluster_size
);
/* Correct offsets are cluster aligned */
/* Correct offsets are cluster aligned */
if
(
offset
&
(
s
->
cluster_size
-
1
))
{
if
(
offset
&
(
s
->
cluster_size
-
1
))
{
fprintf
(
stderr
,
"ERROR offset=%"
PRIx64
": Cluster is not "
fprintf
(
stderr
,
"ERROR offset=%"
PRIx64
": Cluster is not "
"properly aligned; L2 entry corrupted.
\n
"
,
offset
);
"properly aligned; L2 entry corrupted.
\n
"
,
offset
);
error
s
++
;
res
->
corruption
s
++
;
}
}
}
}
}
}
}
}
qemu_free
(
l2_table
);
qemu_free
(
l2_table
);
return
errors
;
return
0
;
fail:
fail:
fprintf
(
stderr
,
"ERROR: I/O error in check_refcounts_l
1
\n
"
);
fprintf
(
stderr
,
"ERROR: I/O error in check_refcounts_l
2
\n
"
);
qemu_free
(
l2_table
);
qemu_free
(
l2_table
);
return
-
EIO
;
return
-
EIO
;
}
}
...
@@ -1016,6 +1017,7 @@ fail:
...
@@ -1016,6 +1017,7 @@ fail:
* error occurred.
* error occurred.
*/
*/
static
int
check_refcounts_l1
(
BlockDriverState
*
bs
,
static
int
check_refcounts_l1
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
res
,
uint16_t
*
refcount_table
,
uint16_t
*
refcount_table
,
int
refcount_table_size
,
int
refcount_table_size
,
int64_t
l1_table_offset
,
int
l1_size
,
int64_t
l1_table_offset
,
int
l1_size
,
...
@@ -1024,13 +1026,12 @@ static int check_refcounts_l1(BlockDriverState *bs,
...
@@ -1024,13 +1026,12 @@ static int check_refcounts_l1(BlockDriverState *bs,
BDRVQcowState
*
s
=
bs
->
opaque
;
BDRVQcowState
*
s
=
bs
->
opaque
;
uint64_t
*
l1_table
,
l2_offset
,
l1_size2
;
uint64_t
*
l1_table
,
l2_offset
,
l1_size2
;
int
i
,
refcount
,
ret
;
int
i
,
refcount
,
ret
;
int
errors
=
0
;
l1_size2
=
l1_size
*
sizeof
(
uint64_t
);
l1_size2
=
l1_size
*
sizeof
(
uint64_t
);
/* Mark L1 table as used */
/* Mark L1 table as used */
errors
+=
inc_refcounts
(
b
s
,
refcount_table
,
refcount_table_size
,
inc_refcounts
(
bs
,
re
s
,
refcount_table
,
refcount_table_size
,
l1_table_offset
,
l1_size2
);
l1_table_offset
,
l1_size2
);
/* Read L1 table entries from disk */
/* Read L1 table entries from disk */
if
(
l1_size2
==
0
)
{
if
(
l1_size2
==
0
)
{
...
@@ -1055,42 +1056,41 @@ static int check_refcounts_l1(BlockDriverState *bs,
...
@@ -1055,42 +1056,41 @@ static int check_refcounts_l1(BlockDriverState *bs,
if
(
refcount
<
0
)
{
if
(
refcount
<
0
)
{
fprintf
(
stderr
,
"Can't get refcount for l2_offset %"
fprintf
(
stderr
,
"Can't get refcount for l2_offset %"
PRIx64
": %s
\n
"
,
l2_offset
,
strerror
(
-
refcount
));
PRIx64
": %s
\n
"
,
l2_offset
,
strerror
(
-
refcount
));
goto
fail
;
}
}
if
((
refcount
==
1
)
!=
((
l2_offset
&
QCOW_OFLAG_COPIED
)
!=
0
))
{
if
((
refcount
==
1
)
!=
((
l2_offset
&
QCOW_OFLAG_COPIED
)
!=
0
))
{
fprintf
(
stderr
,
"ERROR OFLAG_COPIED: l2_offset=%"
PRIx64
fprintf
(
stderr
,
"ERROR OFLAG_COPIED: l2_offset=%"
PRIx64
" refcount=%d
\n
"
,
l2_offset
,
refcount
);
" refcount=%d
\n
"
,
l2_offset
,
refcount
);
error
s
++
;
res
->
corruption
s
++
;
}
}
}
}
/* Mark L2 table as used */
/* Mark L2 table as used */
l2_offset
&=
~
QCOW_OFLAG_COPIED
;
l2_offset
&=
~
QCOW_OFLAG_COPIED
;
errors
+=
inc_refcounts
(
bs
,
refcount_table
,
inc_refcounts
(
bs
,
res
,
refcount_table
,
refcount_table_size
,
refcount_table_size
,
l2_offset
,
s
->
cluster_size
);
l2_offset
,
s
->
cluster_size
);
/* L2 tables are cluster aligned */
/* L2 tables are cluster aligned */
if
(
l2_offset
&
(
s
->
cluster_size
-
1
))
{
if
(
l2_offset
&
(
s
->
cluster_size
-
1
))
{
fprintf
(
stderr
,
"ERROR l2_offset=%"
PRIx64
": Table is not "
fprintf
(
stderr
,
"ERROR l2_offset=%"
PRIx64
": Table is not "
"cluster aligned; L1 entry corrupted
\n
"
,
l2_offset
);
"cluster aligned; L1 entry corrupted
\n
"
,
l2_offset
);
error
s
++
;
res
->
corruption
s
++
;
}
}
/* Process and check L2 entries */
/* Process and check L2 entries */
ret
=
check_refcounts_l2
(
bs
,
re
fcount_table
,
refcount_table_siz
e
,
ret
=
check_refcounts_l2
(
bs
,
re
s
,
refcount_tabl
e
,
l2_offset
,
check_copied
);
refcount_table_size
,
l2_offset
,
check_copied
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
goto
fail
;
goto
fail
;
}
}
errors
+=
ret
;
}
}
}
}
qemu_free
(
l1_table
);
qemu_free
(
l1_table
);
return
errors
;
return
0
;
fail:
fail:
fprintf
(
stderr
,
"ERROR: I/O error in check_refcounts_l1
\n
"
);
fprintf
(
stderr
,
"ERROR: I/O error in check_refcounts_l1
\n
"
);
res
->
check_errors
++
;
qemu_free
(
l1_table
);
qemu_free
(
l1_table
);
return
-
EIO
;
return
-
EIO
;
}
}
...
@@ -1101,44 +1101,47 @@ fail:
...
@@ -1101,44 +1101,47 @@ fail:
* Returns 0 if no errors are found, the number of errors in case the image is
* Returns 0 if no errors are found, the number of errors in case the image is
* detected as corrupted, and -errno when an internal error occured.
* detected as corrupted, and -errno when an internal error occured.
*/
*/
int
qcow2_check_refcounts
(
BlockDriverState
*
bs
)
int
qcow2_check_refcounts
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
res
)
{
{
BDRVQcowState
*
s
=
bs
->
opaque
;
BDRVQcowState
*
s
=
bs
->
opaque
;
int64_t
size
;
int64_t
size
;
int
nb_clusters
,
refcount1
,
refcount2
,
i
;
int
nb_clusters
,
refcount1
,
refcount2
,
i
;
QCowSnapshot
*
sn
;
QCowSnapshot
*
sn
;
uint16_t
*
refcount_table
;
uint16_t
*
refcount_table
;
int
ret
,
errors
=
0
;
int
ret
;
size
=
bdrv_getlength
(
bs
->
file
);
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
));
/* header */
/* header */
errors
+=
inc_refcounts
(
b
s
,
refcount_table
,
nb_clusters
,
inc_refcounts
(
bs
,
re
s
,
refcount_table
,
nb_clusters
,
0
,
s
->
cluster_size
);
0
,
s
->
cluster_size
);
/* current L1 table */
/* current L1 table */
ret
=
check_refcounts_l1
(
bs
,
refcount_table
,
nb_clusters
,
ret
=
check_refcounts_l1
(
bs
,
re
s
,
re
fcount_table
,
nb_clusters
,
s
->
l1_table_offset
,
s
->
l1_size
,
1
);
s
->
l1_table_offset
,
s
->
l1_size
,
1
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
return
ret
;
return
ret
;
}
}
errors
+=
ret
;
/* snapshots */
/* snapshots */
for
(
i
=
0
;
i
<
s
->
nb_snapshots
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
nb_snapshots
;
i
++
)
{
sn
=
s
->
snapshots
+
i
;
sn
=
s
->
snapshots
+
i
;
check_refcounts_l1
(
bs
,
refcount_table
,
nb_clusters
,
ret
=
check_refcounts_l1
(
bs
,
res
,
refcount_table
,
nb_clusters
,
sn
->
l1_table_offset
,
sn
->
l1_size
,
0
);
sn
->
l1_table_offset
,
sn
->
l1_size
,
0
);
if
(
ret
<
0
)
{
return
ret
;
}
}
}
errors
+=
inc_refcounts
(
b
s
,
refcount_table
,
nb_clusters
,
inc_refcounts
(
bs
,
re
s
,
refcount_table
,
nb_clusters
,
s
->
snapshots_offset
,
s
->
snapshots_size
);
s
->
snapshots_offset
,
s
->
snapshots_size
);
/* refcount data */
/* refcount data */
errors
+=
inc_refcounts
(
bs
,
refcount_table
,
nb_clusters
,
inc_refcounts
(
bs
,
res
,
refcount_table
,
nb_clusters
,
s
->
refcount_table_offset
,
s
->
refcount_table_offset
,
s
->
refcount_table_size
*
sizeof
(
uint64_t
));
s
->
refcount_table_size
*
sizeof
(
uint64_t
));
for
(
i
=
0
;
i
<
s
->
refcount_table_size
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
refcount_table_size
;
i
++
)
{
uint64_t
offset
,
cluster
;
uint64_t
offset
,
cluster
;
offset
=
s
->
refcount_table
[
i
];
offset
=
s
->
refcount_table
[
i
];
...
@@ -1148,22 +1151,23 @@ int qcow2_check_refcounts(BlockDriverState *bs)
...
@@ -1148,22 +1151,23 @@ int qcow2_check_refcounts(BlockDriverState *bs)
if
(
offset
&
(
s
->
cluster_size
-
1
))
{
if
(
offset
&
(
s
->
cluster_size
-
1
))
{
fprintf
(
stderr
,
"ERROR refcount block %d is not "
fprintf
(
stderr
,
"ERROR refcount block %d is not "
"cluster aligned; refcount table entry corrupted
\n
"
,
i
);
"cluster aligned; refcount table entry corrupted
\n
"
,
i
);
error
s
++
;
res
->
corruption
s
++
;
continue
;
continue
;
}
}
if
(
cluster
>=
nb_clusters
)
{
if
(
cluster
>=
nb_clusters
)
{
fprintf
(
stderr
,
"ERROR refcount block %d is outside image
\n
"
,
i
);
fprintf
(
stderr
,
"ERROR refcount block %d is outside image
\n
"
,
i
);
error
s
++
;
res
->
corruption
s
++
;
continue
;
continue
;
}
}
if
(
offset
!=
0
)
{
if
(
offset
!=
0
)
{
errors
+=
inc_refcounts
(
b
s
,
refcount_table
,
nb_clusters
,
inc_refcounts
(
bs
,
re
s
,
refcount_table
,
nb_clusters
,
offset
,
s
->
cluster_size
);
offset
,
s
->
cluster_size
);
if
(
refcount_table
[
cluster
]
!=
1
)
{
if
(
refcount_table
[
cluster
]
!=
1
)
{
fprintf
(
stderr
,
"ERROR refcount block %d refcount=%d
\n
"
,
fprintf
(
stderr
,
"ERROR refcount block %d refcount=%d
\n
"
,
i
,
refcount_table
[
cluster
]);
i
,
refcount_table
[
cluster
]);
res
->
corruptions
++
;
}
}
}
}
}
}
...
@@ -1174,19 +1178,25 @@ int qcow2_check_refcounts(BlockDriverState *bs)
...
@@ -1174,19 +1178,25 @@ int qcow2_check_refcounts(BlockDriverState *bs)
if
(
refcount1
<
0
)
{
if
(
refcount1
<
0
)
{
fprintf
(
stderr
,
"Can't get refcount for cluster %d: %s
\n
"
,
fprintf
(
stderr
,
"Can't get refcount for cluster %d: %s
\n
"
,
i
,
strerror
(
-
refcount1
));
i
,
strerror
(
-
refcount1
));
res
->
check_errors
++
;
continue
;
continue
;
}
}
refcount2
=
refcount_table
[
i
];
refcount2
=
refcount_table
[
i
];
if
(
refcount1
!=
refcount2
)
{
if
(
refcount1
!=
refcount2
)
{
fprintf
(
stderr
,
"ERROR cluster %d refcount=%d reference=%d
\n
"
,
fprintf
(
stderr
,
"%s cluster %d refcount=%d reference=%d
\n
"
,
refcount1
<
refcount2
?
"ERROR"
:
"Leaked"
,
i
,
refcount1
,
refcount2
);
i
,
refcount1
,
refcount2
);
errors
++
;
if
(
refcount1
<
refcount2
)
{
res
->
corruptions
++
;
}
else
{
res
->
leaks
++
;
}
}
}
}
}
qemu_free
(
refcount_table
);
qemu_free
(
refcount_table
);
return
errors
;
return
0
;
}
}
block/qcow2.c
浏览文件 @
5efb397f
...
@@ -1239,9 +1239,9 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
...
@@ -1239,9 +1239,9 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
}
}
static
int
qcow_check
(
BlockDriverState
*
bs
)
static
int
qcow_check
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
result
)
{
{
return
qcow2_check_refcounts
(
bs
);
return
qcow2_check_refcounts
(
bs
,
result
);
}
}
#if 0
#if 0
...
...
block/qcow2.h
浏览文件 @
5efb397f
...
@@ -185,7 +185,7 @@ void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
...
@@ -185,7 +185,7 @@ void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
int
qcow2_update_snapshot_refcount
(
BlockDriverState
*
bs
,
int
qcow2_update_snapshot_refcount
(
BlockDriverState
*
bs
,
int64_t
l1_table_offset
,
int
l1_size
,
int
addend
);
int64_t
l1_table_offset
,
int
l1_size
,
int
addend
);
int
qcow2_check_refcounts
(
BlockDriverState
*
bs
);
int
qcow2_check_refcounts
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
res
);
/* 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
);
...
...
block/raw-posix.c
浏览文件 @
5efb397f
...
@@ -242,15 +242,14 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
...
@@ -242,15 +242,14 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
if
(
ret
==
count
)
if
(
ret
==
count
)
goto
label__raw_read__success
;
return
ret
;
/* Allow reads beyond the end (needed for pwrite) */
/* Allow reads beyond the end (needed for pwrite) */
if
((
ret
==
0
)
&&
bs
->
growable
)
{
if
((
ret
==
0
)
&&
bs
->
growable
)
{
int64_t
size
=
raw_getlength
(
bs
);
int64_t
size
=
raw_getlength
(
bs
);
if
(
offset
>=
size
)
{
if
(
offset
>=
size
)
{
memset
(
buf
,
0
,
count
);
memset
(
buf
,
0
,
count
);
ret
=
count
;
return
count
;
goto
label__raw_read__success
;
}
}
}
}
...
@@ -260,13 +259,13 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
...
@@ -260,13 +259,13 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
bs
->
total_sectors
,
ret
,
errno
,
strerror
(
errno
));
bs
->
total_sectors
,
ret
,
errno
,
strerror
(
errno
));
/* Try harder for CDrom. */
/* Try harder for CDrom. */
if
(
bs
->
type
==
BDRV_TYPE_CDROM
)
{
if
(
s
->
type
!=
FTYPE_FILE
)
{
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
if
(
ret
==
count
)
if
(
ret
==
count
)
goto
label__raw_read__success
;
return
ret
;
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
ret
=
pread
(
s
->
fd
,
buf
,
count
,
offset
);
if
(
ret
==
count
)
if
(
ret
==
count
)
goto
label__raw_read__success
;
return
ret
;
DEBUG_BLOCK_PRINT
(
"raw_pread(%d:%s, %"
PRId64
", %p, %d) [%"
PRId64
DEBUG_BLOCK_PRINT
(
"raw_pread(%d:%s, %"
PRId64
", %p, %d) [%"
PRId64
"] retry read failed %d : %d = %s
\n
"
,
"] retry read failed %d : %d = %s
\n
"
,
...
@@ -274,8 +273,6 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
...
@@ -274,8 +273,6 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
bs
->
total_sectors
,
ret
,
errno
,
strerror
(
errno
));
bs
->
total_sectors
,
ret
,
errno
,
strerror
(
errno
));
}
}
label__raw_read__success:
return
(
ret
<
0
)
?
-
errno
:
ret
;
return
(
ret
<
0
)
?
-
errno
:
ret
;
}
}
...
@@ -298,15 +295,13 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
...
@@ -298,15 +295,13 @@ static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
ret
=
pwrite
(
s
->
fd
,
buf
,
count
,
offset
);
ret
=
pwrite
(
s
->
fd
,
buf
,
count
,
offset
);
if
(
ret
==
count
)
if
(
ret
==
count
)
goto
label__raw_write__success
;
return
ret
;
DEBUG_BLOCK_PRINT
(
"raw_pwrite(%d:%s, %"
PRId64
", %p, %d) [%"
PRId64
DEBUG_BLOCK_PRINT
(
"raw_pwrite(%d:%s, %"
PRId64
", %p, %d) [%"
PRId64
"] write failed %d : %d = %s
\n
"
,
"] write failed %d : %d = %s
\n
"
,
s
->
fd
,
bs
->
filename
,
offset
,
buf
,
count
,
s
->
fd
,
bs
->
filename
,
offset
,
buf
,
count
,
bs
->
total_sectors
,
ret
,
errno
,
strerror
(
errno
));
bs
->
total_sectors
,
ret
,
errno
,
strerror
(
errno
));
label__raw_write__success:
return
(
ret
<
0
)
?
-
errno
:
ret
;
return
(
ret
<
0
)
?
-
errno
:
ret
;
}
}
...
...
block/sheepdog.c
0 → 100644
浏览文件 @
5efb397f
此差异已折叠。
点击以展开。
block/vdi.c
浏览文件 @
5efb397f
...
@@ -291,11 +291,10 @@ static void vdi_header_print(VdiHeader *header)
...
@@ -291,11 +291,10 @@ static void vdi_header_print(VdiHeader *header)
}
}
#endif
#endif
static
int
vdi_check
(
BlockDriverState
*
bs
)
static
int
vdi_check
(
BlockDriverState
*
bs
,
BdrvCheckResult
*
res
)
{
{
/* TODO: additional checks possible. */
/* TODO: additional checks possible. */
BDRVVdiState
*
s
=
(
BDRVVdiState
*
)
bs
->
opaque
;
BDRVVdiState
*
s
=
(
BDRVVdiState
*
)
bs
->
opaque
;
int
n_errors
=
0
;
uint32_t
blocks_allocated
=
0
;
uint32_t
blocks_allocated
=
0
;
uint32_t
block
;
uint32_t
block
;
uint32_t
*
bmap
;
uint32_t
*
bmap
;
...
@@ -315,11 +314,12 @@ static int vdi_check(BlockDriverState *bs)
...
@@ -315,11 +314,12 @@ static int vdi_check(BlockDriverState *bs)
}
else
{
}
else
{
fprintf
(
stderr
,
"ERROR: block index %"
PRIu32
fprintf
(
stderr
,
"ERROR: block index %"
PRIu32
" also used by %"
PRIu32
"
\n
"
,
bmap
[
bmap_entry
],
bmap_entry
);
" also used by %"
PRIu32
"
\n
"
,
bmap
[
bmap_entry
],
bmap_entry
);
res
->
corruptions
++
;
}
}
}
else
{
}
else
{
fprintf
(
stderr
,
"ERROR: block index %"
PRIu32
fprintf
(
stderr
,
"ERROR: block index %"
PRIu32
" too large, is %"
PRIu32
"
\n
"
,
block
,
bmap_entry
);
" too large, is %"
PRIu32
"
\n
"
,
block
,
bmap_entry
);
n_error
s
++
;
res
->
corruption
s
++
;
}
}
}
}
}
}
...
@@ -327,12 +327,12 @@ static int vdi_check(BlockDriverState *bs)
...
@@ -327,12 +327,12 @@ static int vdi_check(BlockDriverState *bs)
fprintf
(
stderr
,
"ERROR: allocated blocks mismatch, is %"
PRIu32
fprintf
(
stderr
,
"ERROR: allocated blocks mismatch, is %"
PRIu32
", should be %"
PRIu32
"
\n
"
,
", should be %"
PRIu32
"
\n
"
,
blocks_allocated
,
s
->
header
.
blocks_allocated
);
blocks_allocated
,
s
->
header
.
blocks_allocated
);
n_error
s
++
;
res
->
corruption
s
++
;
}
}
qemu_free
(
bmap
);
qemu_free
(
bmap
);
return
n_errors
;
return
0
;
}
}
static
int
vdi_get_info
(
BlockDriverState
*
bs
,
BlockDriverInfo
*
bdi
)
static
int
vdi_get_info
(
BlockDriverState
*
bs
,
BlockDriverInfo
*
bdi
)
...
...
block_int.h
浏览文件 @
5efb397f
...
@@ -119,8 +119,11 @@ struct BlockDriver {
...
@@ -119,8 +119,11 @@ struct BlockDriver {
QEMUOptionParameter
*
create_options
;
QEMUOptionParameter
*
create_options
;
/* Returns number of errors in image, -errno for internal errors */
/*
int
(
*
bdrv_check
)(
BlockDriverState
*
bs
);
* Returns 0 for completed check, -errno for internal errors.
* The check results are stored in result.
*/
int
(
*
bdrv_check
)(
BlockDriverState
*
bs
,
BdrvCheckResult
*
result
);
void
(
*
bdrv_debug_event
)(
BlockDriverState
*
bs
,
BlkDebugEvent
event
);
void
(
*
bdrv_debug_event
)(
BlockDriverState
*
bs
,
BlkDebugEvent
event
);
...
...
blockdev.c
浏览文件 @
5efb397f
...
@@ -589,7 +589,7 @@ int do_change_block(Monitor *mon, const char *device,
...
@@ -589,7 +589,7 @@ int do_change_block(Monitor *mon, const char *device,
if
(
eject_device
(
mon
,
bs
,
0
)
<
0
)
{
if
(
eject_device
(
mon
,
bs
,
0
)
<
0
)
{
return
-
1
;
return
-
1
;
}
}
bdrv_flags
=
bdrv_
get_type_hint
(
bs
)
==
BDRV_TYPE_CDROM
?
0
:
BDRV_O_RDWR
;
bdrv_flags
=
bdrv_
is_read_only
(
bs
)
?
0
:
BDRV_O_RDWR
;
if
(
bdrv_open
(
bs
,
filename
,
bdrv_flags
,
drv
)
<
0
)
{
if
(
bdrv_open
(
bs
,
filename
,
bdrv_flags
,
drv
)
<
0
)
{
qerror_report
(
QERR_OPEN_FILE_FAILED
,
filename
);
qerror_report
(
QERR_OPEN_FILE_FAILED
,
filename
);
return
-
1
;
return
-
1
;
...
...
hw/fdc.c
浏览文件 @
5efb397f
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#include "hw.h"
#include "hw.h"
#include "fdc.h"
#include "fdc.h"
#include "qemu-error.h"
#include "qemu-timer.h"
#include "qemu-timer.h"
#include "isa.h"
#include "isa.h"
#include "sysbus.h"
#include "sysbus.h"
...
@@ -1844,7 +1845,7 @@ static void fdctrl_result_timer(void *opaque)
...
@@ -1844,7 +1845,7 @@ static void fdctrl_result_timer(void *opaque)
}
}
/* Init functions */
/* Init functions */
static
void
fdctrl_connect_drives
(
FDCtrl
*
fdctrl
)
static
int
fdctrl_connect_drives
(
FDCtrl
*
fdctrl
)
{
{
unsigned
int
i
;
unsigned
int
i
;
FDrive
*
drive
;
FDrive
*
drive
;
...
@@ -1852,12 +1853,24 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl)
...
@@ -1852,12 +1853,24 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl)
for
(
i
=
0
;
i
<
MAX_FD
;
i
++
)
{
for
(
i
=
0
;
i
<
MAX_FD
;
i
++
)
{
drive
=
&
fdctrl
->
drives
[
i
];
drive
=
&
fdctrl
->
drives
[
i
];
if
(
drive
->
bs
)
{
if
(
bdrv_get_on_error
(
drive
->
bs
,
0
)
!=
BLOCK_ERR_STOP_ENOSPC
)
{
error_report
(
"fdc doesn't support drive option werror"
);
return
-
1
;
}
if
(
bdrv_get_on_error
(
drive
->
bs
,
1
)
!=
BLOCK_ERR_REPORT
)
{
error_report
(
"fdc doesn't support drive option rerror"
);
return
-
1
;
}
}
fd_init
(
drive
);
fd_init
(
drive
);
fd_revalidate
(
drive
);
fd_revalidate
(
drive
);
if
(
drive
->
bs
)
{
if
(
drive
->
bs
)
{
bdrv_set_removable
(
drive
->
bs
,
1
);
bdrv_set_removable
(
drive
->
bs
,
1
);
}
}
}
}
return
0
;
}
}
FDCtrl
*
fdctrl_init_isa
(
DriveInfo
**
fds
)
FDCtrl
*
fdctrl_init_isa
(
DriveInfo
**
fds
)
...
@@ -1871,8 +1884,7 @@ FDCtrl *fdctrl_init_isa(DriveInfo **fds)
...
@@ -1871,8 +1884,7 @@ FDCtrl *fdctrl_init_isa(DriveInfo **fds)
if
(
fds
[
1
])
{
if
(
fds
[
1
])
{
qdev_prop_set_drive_nofail
(
&
dev
->
qdev
,
"driveB"
,
fds
[
1
]
->
bdrv
);
qdev_prop_set_drive_nofail
(
&
dev
->
qdev
,
"driveB"
,
fds
[
1
]
->
bdrv
);
}
}
if
(
qdev_init
(
&
dev
->
qdev
)
<
0
)
qdev_init_nofail
(
&
dev
->
qdev
);
return
NULL
;
return
&
(
DO_UPCAST
(
FDCtrlISABus
,
busdev
,
dev
)
->
state
);
return
&
(
DO_UPCAST
(
FDCtrlISABus
,
busdev
,
dev
)
->
state
);
}
}
...
@@ -1950,9 +1962,7 @@ static int fdctrl_init_common(FDCtrl *fdctrl)
...
@@ -1950,9 +1962,7 @@ static int fdctrl_init_common(FDCtrl *fdctrl)
if
(
fdctrl
->
dma_chann
!=
-
1
)
if
(
fdctrl
->
dma_chann
!=
-
1
)
DMA_register_channel
(
fdctrl
->
dma_chann
,
&
fdctrl_transfer_handler
,
fdctrl
);
DMA_register_channel
(
fdctrl
->
dma_chann
,
&
fdctrl_transfer_handler
,
fdctrl
);
fdctrl_connect_drives
(
fdctrl
);
return
fdctrl_connect_drives
(
fdctrl
);
return
0
;
}
}
static
int
isabus_fdc_init1
(
ISADevice
*
dev
)
static
int
isabus_fdc_init1
(
ISADevice
*
dev
)
...
...
hw/ide/core.c
浏览文件 @
5efb397f
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include <hw/pc.h>
#include <hw/pc.h>
#include <hw/pci.h>
#include <hw/pci.h>
#include <hw/scsi.h>
#include <hw/scsi.h>
#include "qemu-error.h"
#include "qemu-timer.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "sysemu.h"
#include "dma.h"
#include "dma.h"
...
@@ -292,7 +293,7 @@ static void ide_set_signature(IDEState *s)
...
@@ -292,7 +293,7 @@ static void ide_set_signature(IDEState *s)
/* put signature */
/* put signature */
s
->
nsector
=
1
;
s
->
nsector
=
1
;
s
->
sector
=
1
;
s
->
sector
=
1
;
if
(
s
->
is_cdrom
)
{
if
(
s
->
drive_kind
==
IDE_CD
)
{
s
->
lcyl
=
0x14
;
s
->
lcyl
=
0x14
;
s
->
hcyl
=
0xeb
;
s
->
hcyl
=
0xeb
;
}
else
if
(
s
->
bs
)
{
}
else
if
(
s
->
bs
)
{
...
@@ -1827,15 +1828,15 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -1827,15 +1828,15 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
switch
(
val
)
{
switch
(
val
)
{
case
WIN_IDENTIFY
:
case
WIN_IDENTIFY
:
if
(
s
->
bs
&&
!
s
->
is_cdrom
)
{
if
(
s
->
bs
&&
s
->
drive_kind
!=
IDE_CD
)
{
if
(
!
s
->
is_cf
)
if
(
s
->
drive_kind
!=
IDE_CFATA
)
ide_identify
(
s
);
ide_identify
(
s
);
else
else
ide_cfata_identify
(
s
);
ide_cfata_identify
(
s
);
s
->
status
=
READY_STAT
|
SEEK_STAT
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
ide_transfer_start
(
s
,
s
->
io_buffer
,
512
,
ide_transfer_stop
);
ide_transfer_start
(
s
,
s
->
io_buffer
,
512
,
ide_transfer_stop
);
}
else
{
}
else
{
if
(
s
->
is_cdrom
)
{
if
(
s
->
drive_kind
==
IDE_CD
)
{
ide_set_signature
(
s
);
ide_set_signature
(
s
);
}
}
ide_abort_command
(
s
);
ide_abort_command
(
s
);
...
@@ -1849,7 +1850,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -1849,7 +1850,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
ide_set_irq
(
s
->
bus
);
ide_set_irq
(
s
->
bus
);
break
;
break
;
case
WIN_SETMULT
:
case
WIN_SETMULT
:
if
(
s
->
is_cf
&&
s
->
nsector
==
0
)
{
if
(
s
->
drive_kind
==
IDE_CFATA
&&
s
->
nsector
==
0
)
{
/* Disable Read and Write Multiple */
/* Disable Read and Write Multiple */
s
->
mult_sectors
=
0
;
s
->
mult_sectors
=
0
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
...
@@ -2033,7 +2034,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2033,7 +2034,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
ide_set_irq
(
s
->
bus
);
ide_set_irq
(
s
->
bus
);
break
;
break
;
case
WIN_SEEK
:
case
WIN_SEEK
:
if
(
s
->
is_cdrom
)
if
(
s
->
drive_kind
==
IDE_CD
)
goto
abort_cmd
;
goto
abort_cmd
;
/* XXX: Check that seek is within bounds */
/* XXX: Check that seek is within bounds */
s
->
status
=
READY_STAT
|
SEEK_STAT
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
...
@@ -2041,7 +2042,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2041,7 +2042,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
break
;
break
;
/* ATAPI commands */
/* ATAPI commands */
case
WIN_PIDENTIFY
:
case
WIN_PIDENTIFY
:
if
(
s
->
is_cdrom
)
{
if
(
s
->
drive_kind
==
IDE_CD
)
{
ide_atapi_identify
(
s
);
ide_atapi_identify
(
s
);
s
->
status
=
READY_STAT
|
SEEK_STAT
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
ide_transfer_start
(
s
,
s
->
io_buffer
,
512
,
ide_transfer_stop
);
ide_transfer_start
(
s
,
s
->
io_buffer
,
512
,
ide_transfer_stop
);
...
@@ -2052,7 +2053,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2052,7 +2053,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
break
;
break
;
case
WIN_DIAGNOSE
:
case
WIN_DIAGNOSE
:
ide_set_signature
(
s
);
ide_set_signature
(
s
);
if
(
s
->
is_cdrom
)
if
(
s
->
drive_kind
==
IDE_CD
)
s
->
status
=
0
;
/* ATAPI spec (v6) section 9.10 defines packet
s
->
status
=
0
;
/* ATAPI spec (v6) section 9.10 defines packet
* devices to return a clear status register
* devices to return a clear status register
* with READY_STAT *not* set. */
* with READY_STAT *not* set. */
...
@@ -2064,14 +2065,14 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2064,14 +2065,14 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
ide_set_irq
(
s
->
bus
);
ide_set_irq
(
s
->
bus
);
break
;
break
;
case
WIN_SRST
:
case
WIN_SRST
:
if
(
!
s
->
is_cdrom
)
if
(
s
->
drive_kind
!=
IDE_CD
)
goto
abort_cmd
;
goto
abort_cmd
;
ide_set_signature
(
s
);
ide_set_signature
(
s
);
s
->
status
=
0x00
;
/* NOTE: READY is _not_ set */
s
->
status
=
0x00
;
/* NOTE: READY is _not_ set */
s
->
error
=
0x01
;
s
->
error
=
0x01
;
break
;
break
;
case
WIN_PACKETCMD
:
case
WIN_PACKETCMD
:
if
(
!
s
->
is_cdrom
)
if
(
s
->
drive_kind
!=
IDE_CD
)
goto
abort_cmd
;
goto
abort_cmd
;
/* overlapping commands not supported */
/* overlapping commands not supported */
if
(
s
->
feature
&
0x02
)
if
(
s
->
feature
&
0x02
)
...
@@ -2084,7 +2085,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2084,7 +2085,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
break
;
break
;
/* CF-ATA commands */
/* CF-ATA commands */
case
CFA_REQ_EXT_ERROR_CODE
:
case
CFA_REQ_EXT_ERROR_CODE
:
if
(
!
s
->
is_cf
)
if
(
s
->
drive_kind
!=
IDE_CFATA
)
goto
abort_cmd
;
goto
abort_cmd
;
s
->
error
=
0x09
;
/* miscellaneous error */
s
->
error
=
0x09
;
/* miscellaneous error */
s
->
status
=
READY_STAT
|
SEEK_STAT
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
...
@@ -2092,7 +2093,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2092,7 +2093,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
break
;
break
;
case
CFA_ERASE_SECTORS
:
case
CFA_ERASE_SECTORS
:
case
CFA_WEAR_LEVEL
:
case
CFA_WEAR_LEVEL
:
if
(
!
s
->
is_cf
)
if
(
s
->
drive_kind
!=
IDE_CFATA
)
goto
abort_cmd
;
goto
abort_cmd
;
if
(
val
==
CFA_WEAR_LEVEL
)
if
(
val
==
CFA_WEAR_LEVEL
)
s
->
nsector
=
0
;
s
->
nsector
=
0
;
...
@@ -2103,7 +2104,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2103,7 +2104,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
ide_set_irq
(
s
->
bus
);
ide_set_irq
(
s
->
bus
);
break
;
break
;
case
CFA_TRANSLATE_SECTOR
:
case
CFA_TRANSLATE_SECTOR
:
if
(
!
s
->
is_cf
)
if
(
s
->
drive_kind
!=
IDE_CFATA
)
goto
abort_cmd
;
goto
abort_cmd
;
s
->
error
=
0x00
;
s
->
error
=
0x00
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
...
@@ -2123,7 +2124,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2123,7 +2124,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
ide_set_irq
(
s
->
bus
);
ide_set_irq
(
s
->
bus
);
break
;
break
;
case
CFA_ACCESS_METADATA_STORAGE
:
case
CFA_ACCESS_METADATA_STORAGE
:
if
(
!
s
->
is_cf
)
if
(
s
->
drive_kind
!=
IDE_CFATA
)
goto
abort_cmd
;
goto
abort_cmd
;
switch
(
s
->
feature
)
{
switch
(
s
->
feature
)
{
case
0x02
:
/* Inquiry Metadata Storage */
case
0x02
:
/* Inquiry Metadata Storage */
...
@@ -2143,7 +2144,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2143,7 +2144,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
ide_set_irq
(
s
->
bus
);
ide_set_irq
(
s
->
bus
);
break
;
break
;
case
IBM_SENSE_CONDITION
:
case
IBM_SENSE_CONDITION
:
if
(
!
s
->
is_cf
)
if
(
s
->
drive_kind
!=
IDE_CFATA
)
goto
abort_cmd
;
goto
abort_cmd
;
switch
(
s
->
feature
)
{
switch
(
s
->
feature
)
{
case
0x01
:
/* sense temperature in device */
case
0x01
:
/* sense temperature in device */
...
@@ -2157,7 +2158,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2157,7 +2158,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
break
;
break
;
case
WIN_SMART
:
case
WIN_SMART
:
if
(
s
->
is_cdrom
)
if
(
s
->
drive_kind
==
IDE_CD
)
goto
abort_cmd
;
goto
abort_cmd
;
if
(
s
->
hcyl
!=
0xc2
||
s
->
lcyl
!=
0x4f
)
if
(
s
->
hcyl
!=
0xc2
||
s
->
lcyl
!=
0x4f
)
goto
abort_cmd
;
goto
abort_cmd
;
...
@@ -2438,7 +2439,7 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
...
@@ -2438,7 +2439,7 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
/* high to low */
/* high to low */
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
s
=
&
bus
->
ifs
[
i
];
s
=
&
bus
->
ifs
[
i
];
if
(
s
->
is_cdrom
)
if
(
s
->
drive_kind
==
IDE_CD
)
s
->
status
=
0x00
;
/* NOTE: READY is _not_ set */
s
->
status
=
0x00
;
/* NOTE: READY is _not_ set */
else
else
s
->
status
=
READY_STAT
|
SEEK_STAT
;
s
->
status
=
READY_STAT
|
SEEK_STAT
;
...
@@ -2540,7 +2541,7 @@ static void ide_reset(IDEState *s)
...
@@ -2540,7 +2541,7 @@ static void ide_reset(IDEState *s)
#ifdef DEBUG_IDE
#ifdef DEBUG_IDE
printf
(
"ide: reset
\n
"
);
printf
(
"ide: reset
\n
"
);
#endif
#endif
if
(
s
->
is_cf
)
if
(
s
->
drive_kind
==
IDE_CFATA
)
s
->
mult_sectors
=
0
;
s
->
mult_sectors
=
0
;
else
else
s
->
mult_sectors
=
MAX_MULT_SECTORS
;
s
->
mult_sectors
=
MAX_MULT_SECTORS
;
...
@@ -2594,8 +2595,8 @@ void ide_bus_reset(IDEBus *bus)
...
@@ -2594,8 +2595,8 @@ void ide_bus_reset(IDEBus *bus)
ide_clear_hob
(
bus
);
ide_clear_hob
(
bus
);
}
}
void
ide_init_drive
(
IDEState
*
s
,
BlockDriverState
*
bs
,
int
ide_init_drive
(
IDEState
*
s
,
BlockDriverState
*
bs
,
const
char
*
version
,
const
char
*
serial
)
const
char
*
version
,
const
char
*
serial
)
{
{
int
cylinders
,
heads
,
secs
;
int
cylinders
,
heads
,
secs
;
uint64_t
nb_sectors
;
uint64_t
nb_sectors
;
...
@@ -2603,6 +2604,18 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
...
@@ -2603,6 +2604,18 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
s
->
bs
=
bs
;
s
->
bs
=
bs
;
bdrv_get_geometry
(
bs
,
&
nb_sectors
);
bdrv_get_geometry
(
bs
,
&
nb_sectors
);
bdrv_guess_geometry
(
bs
,
&
cylinders
,
&
heads
,
&
secs
);
bdrv_guess_geometry
(
bs
,
&
cylinders
,
&
heads
,
&
secs
);
if
(
cylinders
<
1
||
cylinders
>
16383
)
{
error_report
(
"cyls must be between 1 and 16383"
);
return
-
1
;
}
if
(
heads
<
1
||
heads
>
16
)
{
error_report
(
"heads must be between 1 and 16"
);
return
-
1
;
}
if
(
secs
<
1
||
secs
>
63
)
{
error_report
(
"secs must be between 1 and 63"
);
return
-
1
;
}
s
->
cylinders
=
cylinders
;
s
->
cylinders
=
cylinders
;
s
->
heads
=
heads
;
s
->
heads
=
heads
;
s
->
sectors
=
secs
;
s
->
sectors
=
secs
;
...
@@ -2614,8 +2627,13 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
...
@@ -2614,8 +2627,13 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
s
->
smart_errors
=
0
;
s
->
smart_errors
=
0
;
s
->
smart_selftest_count
=
0
;
s
->
smart_selftest_count
=
0
;
if
(
bdrv_get_type_hint
(
bs
)
==
BDRV_TYPE_CDROM
)
{
if
(
bdrv_get_type_hint
(
bs
)
==
BDRV_TYPE_CDROM
)
{
s
->
is_cdrom
=
1
;
s
->
drive_kind
=
IDE_CD
;
bdrv_set_change_cb
(
bs
,
cdrom_change_cb
,
s
);
bdrv_set_change_cb
(
bs
,
cdrom_change_cb
,
s
);
}
else
{
if
(
bdrv_is_read_only
(
bs
))
{
error_report
(
"Can't use a read-only drive"
);
return
-
1
;
}
}
}
if
(
serial
)
{
if
(
serial
)
{
strncpy
(
s
->
drive_serial_str
,
serial
,
sizeof
(
s
->
drive_serial_str
));
strncpy
(
s
->
drive_serial_str
,
serial
,
sizeof
(
s
->
drive_serial_str
));
...
@@ -2629,7 +2647,8 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
...
@@ -2629,7 +2647,8 @@ void ide_init_drive(IDEState *s, BlockDriverState *bs,
pstrcpy
(
s
->
version
,
sizeof
(
s
->
version
),
QEMU_VERSION
);
pstrcpy
(
s
->
version
,
sizeof
(
s
->
version
),
QEMU_VERSION
);
}
}
ide_reset
(
s
);
ide_reset
(
s
);
bdrv_set_removable
(
bs
,
s
->
is_cdrom
);
bdrv_set_removable
(
bs
,
s
->
drive_kind
==
IDE_CD
);
return
0
;
}
}
static
void
ide_init1
(
IDEBus
*
bus
,
int
unit
)
static
void
ide_init1
(
IDEBus
*
bus
,
int
unit
)
...
@@ -2669,8 +2688,11 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
...
@@ -2669,8 +2688,11 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
dinfo
=
i
==
0
?
hd0
:
hd1
;
dinfo
=
i
==
0
?
hd0
:
hd1
;
ide_init1
(
bus
,
i
);
ide_init1
(
bus
,
i
);
if
(
dinfo
)
{
if
(
dinfo
)
{
ide_init_drive
(
&
bus
->
ifs
[
i
],
dinfo
->
bdrv
,
NULL
,
if
(
ide_init_drive
(
&
bus
->
ifs
[
i
],
dinfo
->
bdrv
,
NULL
,
*
dinfo
->
serial
?
dinfo
->
serial
:
NULL
);
*
dinfo
->
serial
?
dinfo
->
serial
:
NULL
)
<
0
)
{
error_report
(
"Can't set up IDE drive %s"
,
dinfo
->
id
);
exit
(
1
);
}
}
else
{
}
else
{
ide_reset
(
&
bus
->
ifs
[
i
]);
ide_reset
(
&
bus
->
ifs
[
i
]);
}
}
...
...
hw/ide/internal.h
浏览文件 @
5efb397f
...
@@ -362,6 +362,8 @@ typedef struct BMDMAState BMDMAState;
...
@@ -362,6 +362,8 @@ typedef struct BMDMAState BMDMAState;
#define SMART_DISABLE 0xd9
#define SMART_DISABLE 0xd9
#define SMART_STATUS 0xda
#define SMART_STATUS 0xda
typedef
enum
{
IDE_HD
,
IDE_CD
,
IDE_CFATA
}
IDEDriveKind
;
typedef
void
EndTransferFunc
(
IDEState
*
);
typedef
void
EndTransferFunc
(
IDEState
*
);
/* NOTE: IDEState represents in fact one drive */
/* NOTE: IDEState represents in fact one drive */
...
@@ -369,8 +371,7 @@ struct IDEState {
...
@@ -369,8 +371,7 @@ struct IDEState {
IDEBus
*
bus
;
IDEBus
*
bus
;
uint8_t
unit
;
uint8_t
unit
;
/* ide config */
/* ide config */
int
is_cdrom
;
IDEDriveKind
drive_kind
;
int
is_cf
;
int
cylinders
,
heads
,
sectors
;
int
cylinders
,
heads
,
sectors
;
int64_t
nb_sectors
;
int64_t
nb_sectors
;
int
mult_sectors
;
int
mult_sectors
;
...
@@ -555,8 +556,8 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
...
@@ -555,8 +556,8 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
void
ide_data_writel
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
);
void
ide_data_writel
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
);
uint32_t
ide_data_readl
(
void
*
opaque
,
uint32_t
addr
);
uint32_t
ide_data_readl
(
void
*
opaque
,
uint32_t
addr
);
void
ide_init_drive
(
IDEState
*
s
,
BlockDriverState
*
bs
,
int
ide_init_drive
(
IDEState
*
s
,
BlockDriverState
*
bs
,
const
char
*
version
,
const
char
*
serial
);
const
char
*
version
,
const
char
*
serial
);
void
ide_init2
(
IDEBus
*
bus
,
qemu_irq
irq
);
void
ide_init2
(
IDEBus
*
bus
,
qemu_irq
irq
);
void
ide_init2_with_non_qdev_drives
(
IDEBus
*
bus
,
DriveInfo
*
hd0
,
void
ide_init2_with_non_qdev_drives
(
IDEBus
*
bus
,
DriveInfo
*
hd0
,
DriveInfo
*
hd1
,
qemu_irq
irq
);
DriveInfo
*
hd1
,
qemu_irq
irq
);
...
...
hw/ide/macio.c
浏览文件 @
5efb397f
...
@@ -162,7 +162,7 @@ static void pmac_ide_transfer(DBDMA_io *io)
...
@@ -162,7 +162,7 @@ static void pmac_ide_transfer(DBDMA_io *io)
IDEState
*
s
=
idebus_active_if
(
&
m
->
bus
);
IDEState
*
s
=
idebus_active_if
(
&
m
->
bus
);
s
->
io_buffer_size
=
0
;
s
->
io_buffer_size
=
0
;
if
(
s
->
is_cdrom
)
{
if
(
s
->
drive_kind
==
IDE_CD
)
{
pmac_ide_atapi_transfer_cb
(
io
,
0
);
pmac_ide_atapi_transfer_cb
(
io
,
0
);
return
;
return
;
}
}
...
...
hw/ide/microdrive.c
浏览文件 @
5efb397f
...
@@ -541,7 +541,7 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
...
@@ -541,7 +541,7 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
ide_init2_with_non_qdev_drives
(
&
md
->
bus
,
bdrv
,
NULL
,
ide_init2_with_non_qdev_drives
(
&
md
->
bus
,
bdrv
,
NULL
,
qemu_allocate_irqs
(
md_set_irq
,
md
,
1
)[
0
]);
qemu_allocate_irqs
(
md_set_irq
,
md
,
1
)[
0
]);
md
->
bus
.
ifs
[
0
].
is_cf
=
1
;
md
->
bus
.
ifs
[
0
].
drive_kind
=
IDE_CFATA
;
md
->
bus
.
ifs
[
0
].
mdata_size
=
METADATA_SIZE
;
md
->
bus
.
ifs
[
0
].
mdata_size
=
METADATA_SIZE
;
md
->
bus
.
ifs
[
0
].
mdata_storage
=
(
uint8_t
*
)
qemu_mallocz
(
METADATA_SIZE
);
md
->
bus
.
ifs
[
0
].
mdata_storage
=
(
uint8_t
*
)
qemu_mallocz
(
METADATA_SIZE
);
...
...
hw/ide/qdev.c
浏览文件 @
5efb397f
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
*/
*/
#include <hw/hw.h>
#include <hw/hw.h>
#include "dma.h"
#include "dma.h"
#include "qemu-error.h"
#include <hw/ide/internal.h>
#include <hw/ide/internal.h>
/* --------------------------------- */
/* --------------------------------- */
...
@@ -40,7 +40,7 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
...
@@ -40,7 +40,7 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
IDEBus
*
bus
=
DO_UPCAST
(
IDEBus
,
qbus
,
qdev
->
parent_bus
);
IDEBus
*
bus
=
DO_UPCAST
(
IDEBus
,
qbus
,
qdev
->
parent_bus
);
if
(
!
dev
->
conf
.
bs
)
{
if
(
!
dev
->
conf
.
bs
)
{
fprintf
(
stderr
,
"%s: no drive specified
\n
"
,
qdev
->
info
->
name
);
error_report
(
"No drive specified"
);
goto
err
;
goto
err
;
}
}
if
(
dev
->
unit
==
-
1
)
{
if
(
dev
->
unit
==
-
1
)
{
...
@@ -49,19 +49,20 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
...
@@ -49,19 +49,20 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
switch
(
dev
->
unit
)
{
switch
(
dev
->
unit
)
{
case
0
:
case
0
:
if
(
bus
->
master
)
{
if
(
bus
->
master
)
{
fprintf
(
stderr
,
"ide: tried to assign master twice
\n
"
);
error_report
(
"IDE unit %d is in use"
,
dev
->
unit
);
goto
err
;
goto
err
;
}
}
bus
->
master
=
dev
;
bus
->
master
=
dev
;
break
;
break
;
case
1
:
case
1
:
if
(
bus
->
slave
)
{
if
(
bus
->
slave
)
{
fprintf
(
stderr
,
"ide: tried to assign slave twice
\n
"
);
error_report
(
"IDE unit %d is in use"
,
dev
->
unit
);
goto
err
;
goto
err
;
}
}
bus
->
slave
=
dev
;
bus
->
slave
=
dev
;
break
;
break
;
default:
default:
error_report
(
"Invalid IDE unit %d"
,
dev
->
unit
);
goto
err
;
goto
err
;
}
}
return
info
->
init
(
dev
);
return
info
->
init
(
dev
);
...
@@ -117,7 +118,9 @@ static int ide_drive_initfn(IDEDevice *dev)
...
@@ -117,7 +118,9 @@ static int ide_drive_initfn(IDEDevice *dev)
}
}
}
}
ide_init_drive
(
s
,
dev
->
conf
.
bs
,
dev
->
version
,
serial
);
if
(
ide_init_drive
(
s
,
dev
->
conf
.
bs
,
dev
->
version
,
serial
)
<
0
)
{
return
-
1
;
}
if
(
!
dev
->
version
)
{
if
(
!
dev
->
version
)
{
dev
->
version
=
qemu_strdup
(
s
->
version
);
dev
->
version
=
qemu_strdup
(
s
->
version
);
...
...
hw/qdev.c
浏览文件 @
5efb397f
...
@@ -326,8 +326,10 @@ void qdev_init_nofail(DeviceState *dev)
...
@@ -326,8 +326,10 @@ void qdev_init_nofail(DeviceState *dev)
{
{
DeviceInfo
*
info
=
dev
->
info
;
DeviceInfo
*
info
=
dev
->
info
;
if
(
qdev_init
(
dev
)
<
0
)
if
(
qdev_init
(
dev
)
<
0
)
{
hw_error
(
"Initialization of device %s failed
\n
"
,
info
->
name
);
error_report
(
"Initialization of device %s failed
\n
"
,
info
->
name
);
exit
(
1
);
}
}
}
/* Unlink device from bus and free the structure. */
/* Unlink device from bus and free the structure. */
...
...
hw/scsi-bus.c
浏览文件 @
5efb397f
...
@@ -102,19 +102,23 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, int
...
@@ -102,19 +102,23 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, int
int
scsi_bus_legacy_handle_cmdline
(
SCSIBus
*
bus
)
int
scsi_bus_legacy_handle_cmdline
(
SCSIBus
*
bus
)
{
{
Location
loc
;
DriveInfo
*
dinfo
;
DriveInfo
*
dinfo
;
int
res
=
0
,
unit
;
int
res
=
0
,
unit
;
loc_push_none
(
&
loc
);
for
(
unit
=
0
;
unit
<
MAX_SCSI_DEVS
;
unit
++
)
{
for
(
unit
=
0
;
unit
<
MAX_SCSI_DEVS
;
unit
++
)
{
dinfo
=
drive_get
(
IF_SCSI
,
bus
->
busnr
,
unit
);
dinfo
=
drive_get
(
IF_SCSI
,
bus
->
busnr
,
unit
);
if
(
dinfo
==
NULL
)
{
if
(
dinfo
==
NULL
)
{
continue
;
continue
;
}
}
qemu_opts_loc_restore
(
dinfo
->
opts
);
if
(
!
scsi_bus_legacy_add_drive
(
bus
,
dinfo
->
bdrv
,
unit
))
{
if
(
!
scsi_bus_legacy_add_drive
(
bus
,
dinfo
->
bdrv
,
unit
))
{
res
=
-
1
;
res
=
-
1
;
break
;
break
;
}
}
}
}
loc_pop
(
&
loc
);
return
res
;
return
res
;
}
}
...
...
hw/scsi-disk.c
浏览文件 @
5efb397f
...
@@ -1059,6 +1059,11 @@ static int scsi_disk_initfn(SCSIDevice *dev)
...
@@ -1059,6 +1059,11 @@ static int scsi_disk_initfn(SCSIDevice *dev)
s
->
bs
=
s
->
qdev
.
conf
.
bs
;
s
->
bs
=
s
->
qdev
.
conf
.
bs
;
is_cd
=
bdrv_get_type_hint
(
s
->
bs
)
==
BDRV_TYPE_CDROM
;
is_cd
=
bdrv_get_type_hint
(
s
->
bs
)
==
BDRV_TYPE_CDROM
;
if
(
bdrv_get_on_error
(
s
->
bs
,
1
)
!=
BLOCK_ERR_REPORT
)
{
error_report
(
"Device doesn't support drive option rerror"
);
return
-
1
;
}
if
(
!
s
->
serial
)
{
if
(
!
s
->
serial
)
{
/* try to fall back to value set with legacy -drive serial=... */
/* try to fall back to value set with legacy -drive serial=... */
dinfo
=
drive_get_by_blockdev
(
s
->
bs
);
dinfo
=
drive_get_by_blockdev
(
s
->
bs
);
...
...
hw/scsi-generic.c
浏览文件 @
5efb397f
...
@@ -474,6 +474,15 @@ static int scsi_generic_initfn(SCSIDevice *dev)
...
@@ -474,6 +474,15 @@ static int scsi_generic_initfn(SCSIDevice *dev)
return
-
1
;
return
-
1
;
}
}
if
(
bdrv_get_on_error
(
s
->
bs
,
0
)
!=
BLOCK_ERR_STOP_ENOSPC
)
{
error_report
(
"Device doesn't support drive option werror"
);
return
-
1
;
}
if
(
bdrv_get_on_error
(
s
->
bs
,
1
)
!=
BLOCK_ERR_REPORT
)
{
error_report
(
"Device doesn't support drive option rerror"
);
return
-
1
;
}
/* check we are using a driver managing SG_IO (version 3 and after */
/* check we are using a driver managing SG_IO (version 3 and after */
if
(
bdrv_ioctl
(
s
->
bs
,
SG_GET_VERSION_NUM
,
&
sg_version
)
<
0
||
if
(
bdrv_ioctl
(
s
->
bs
,
SG_GET_VERSION_NUM
,
&
sg_version
)
<
0
||
sg_version
<
30000
)
{
sg_version
<
30000
)
{
...
...
hw/virtio-blk.c
浏览文件 @
5efb397f
...
@@ -26,6 +26,7 @@ typedef struct VirtIOBlock
...
@@ -26,6 +26,7 @@ typedef struct VirtIOBlock
QEMUBH
*
bh
;
QEMUBH
*
bh
;
BlockConf
*
conf
;
BlockConf
*
conf
;
unsigned
short
sector_mask
;
unsigned
short
sector_mask
;
char
sn
[
BLOCK_SERIAL_STRLEN
];
}
VirtIOBlock
;
}
VirtIOBlock
;
static
VirtIOBlock
*
to_virtio_blk
(
VirtIODevice
*
vdev
)
static
VirtIOBlock
*
to_virtio_blk
(
VirtIODevice
*
vdev
)
...
@@ -324,6 +325,12 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
...
@@ -324,6 +325,12 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
virtio_blk_handle_flush
(
req
,
mrb
);
virtio_blk_handle_flush
(
req
,
mrb
);
}
else
if
(
req
->
out
->
type
&
VIRTIO_BLK_T_SCSI_CMD
)
{
}
else
if
(
req
->
out
->
type
&
VIRTIO_BLK_T_SCSI_CMD
)
{
virtio_blk_handle_scsi
(
req
);
virtio_blk_handle_scsi
(
req
);
}
else
if
(
req
->
out
->
type
&
VIRTIO_BLK_T_GET_ID
)
{
VirtIOBlock
*
s
=
req
->
dev
;
memcpy
(
req
->
elem
.
in_sg
[
0
].
iov_base
,
s
->
sn
,
MIN
(
req
->
elem
.
in_sg
[
0
].
iov_len
,
sizeof
(
s
->
sn
)));
virtio_blk_req_complete
(
req
,
VIRTIO_BLK_S_OK
);
}
else
if
(
req
->
out
->
type
&
VIRTIO_BLK_T_OUT
)
{
}
else
if
(
req
->
out
->
type
&
VIRTIO_BLK_T_OUT
)
{
qemu_iovec_init_external
(
&
req
->
qiov
,
&
req
->
elem
.
out_sg
[
1
],
qemu_iovec_init_external
(
&
req
->
qiov
,
&
req
->
elem
.
out_sg
[
1
],
req
->
elem
.
out_num
-
1
);
req
->
elem
.
out_num
-
1
);
...
@@ -481,6 +488,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
...
@@ -481,6 +488,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
VirtIOBlock
*
s
;
VirtIOBlock
*
s
;
int
cylinders
,
heads
,
secs
;
int
cylinders
,
heads
,
secs
;
static
int
virtio_blk_id
;
static
int
virtio_blk_id
;
DriveInfo
*
dinfo
;
s
=
(
VirtIOBlock
*
)
virtio_common_init
(
"virtio-blk"
,
VIRTIO_ID_BLOCK
,
s
=
(
VirtIOBlock
*
)
virtio_common_init
(
"virtio-blk"
,
VIRTIO_ID_BLOCK
,
sizeof
(
struct
virtio_blk_config
),
sizeof
(
struct
virtio_blk_config
),
...
@@ -495,6 +503,12 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
...
@@ -495,6 +503,12 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
s
->
sector_mask
=
(
s
->
conf
->
logical_block_size
/
BDRV_SECTOR_SIZE
)
-
1
;
s
->
sector_mask
=
(
s
->
conf
->
logical_block_size
/
BDRV_SECTOR_SIZE
)
-
1
;
bdrv_guess_geometry
(
s
->
bs
,
&
cylinders
,
&
heads
,
&
secs
);
bdrv_guess_geometry
(
s
->
bs
,
&
cylinders
,
&
heads
,
&
secs
);
/* NB: per existing s/n string convention the string is terminated
* by '\0' only when less than sizeof (s->sn)
*/
dinfo
=
drive_get_by_blockdev
(
s
->
bs
);
strncpy
(
s
->
sn
,
dinfo
->
serial
,
sizeof
(
s
->
sn
));
s
->
vq
=
virtio_add_queue
(
&
s
->
vdev
,
128
,
virtio_blk_handle_output
);
s
->
vq
=
virtio_add_queue
(
&
s
->
vdev
,
128
,
virtio_blk_handle_output
);
qemu_add_vm_change_state_handler
(
virtio_blk_dma_restart_cb
,
s
);
qemu_add_vm_change_state_handler
(
virtio_blk_dma_restart_cb
,
s
);
...
...
hw/virtio-blk.h
浏览文件 @
5efb397f
...
@@ -59,6 +59,9 @@ struct virtio_blk_config
...
@@ -59,6 +59,9 @@ struct virtio_blk_config
/* Flush the volatile write cache */
/* Flush the volatile write cache */
#define VIRTIO_BLK_T_FLUSH 4
#define VIRTIO_BLK_T_FLUSH 4
/* return the device ID string */
#define VIRTIO_BLK_T_GET_ID 8
/* Barrier before this op. */
/* Barrier before this op. */
#define VIRTIO_BLK_T_BARRIER 0x80000000
#define VIRTIO_BLK_T_BARRIER 0x80000000
...
...
qemu-img.c
浏览文件 @
5efb397f
...
@@ -425,11 +425,20 @@ out:
...
@@ -425,11 +425,20 @@ out:
return
0
;
return
0
;
}
}
/*
* Checks an image for consistency. Exit codes:
*
* 0 - Check completed, image is good
* 1 - Check not completed because of internal errors
* 2 - Check completed, image is corrupted
* 3 - Check completed, image has leaked clusters, but is good otherwise
*/
static
int
img_check
(
int
argc
,
char
**
argv
)
static
int
img_check
(
int
argc
,
char
**
argv
)
{
{
int
c
,
ret
;
int
c
,
ret
;
const
char
*
filename
,
*
fmt
;
const
char
*
filename
,
*
fmt
;
BlockDriverState
*
bs
;
BlockDriverState
*
bs
;
BdrvCheckResult
result
;
fmt
=
NULL
;
fmt
=
NULL
;
for
(;;)
{
for
(;;)
{
...
@@ -453,28 +462,52 @@ static int img_check(int argc, char **argv)
...
@@ -453,28 +462,52 @@ static int img_check(int argc, char **argv)
if
(
!
bs
)
{
if
(
!
bs
)
{
return
1
;
return
1
;
}
}
ret
=
bdrv_check
(
bs
);
ret
=
bdrv_check
(
bs
,
&
result
);
switch
(
ret
)
{
case
0
:
if
(
ret
==
-
ENOTSUP
)
{
printf
(
"No errors were found on the image.
\n
"
);
break
;
case
-
ENOTSUP
:
error
(
"This image format does not support checks"
);
error
(
"This image format does not support checks"
);
break
;
bdrv_delete
(
bs
);
default:
return
1
;
if
(
ret
<
0
)
{
}
error
(
"An error occurred during the check"
);
}
else
{
if
(
!
(
result
.
corruptions
||
result
.
leaks
||
result
.
check_errors
))
{
printf
(
"%d errors were found on the image.
\n
"
,
ret
);
printf
(
"No errors were found on the image.
\n
"
);
}
else
{
if
(
result
.
corruptions
)
{
printf
(
"
\n
%d errors were found on the image.
\n
"
"Data may be corrupted, or further writes to the image "
"may corrupt it.
\n
"
,
result
.
corruptions
);
}
if
(
result
.
leaks
)
{
printf
(
"
\n
%d leaked clusters were found on the image.
\n
"
"This means waste of disk space, but no harm to data.
\n
"
,
result
.
leaks
);
}
if
(
result
.
check_errors
)
{
printf
(
"
\n
%d internal errors have occurred during the check.
\n
"
,
result
.
check_errors
);
}
}
break
;
}
}
bdrv_delete
(
bs
);
bdrv_delete
(
bs
);
if
(
ret
)
{
if
(
ret
<
0
||
result
.
check_errors
)
{
printf
(
"
\n
An error has occurred during the check: %s
\n
"
"The check is not complete and may have missed error.
\n
"
,
strerror
(
-
ret
));
return
1
;
return
1
;
}
}
return
0
;
if
(
result
.
corruptions
)
{
return
2
;
}
else
if
(
result
.
leaks
)
{
return
3
;
}
else
{
return
0
;
}
}
}
static
int
img_commit
(
int
argc
,
char
**
argv
)
static
int
img_commit
(
int
argc
,
char
**
argv
)
...
...
qemu-option.c
浏览文件 @
5efb397f
...
@@ -728,6 +728,11 @@ void qemu_opts_reset(QemuOptsList *list)
...
@@ -728,6 +728,11 @@ void qemu_opts_reset(QemuOptsList *list)
}
}
}
}
void
qemu_opts_loc_restore
(
QemuOpts
*
opts
)
{
loc_restore
(
&
opts
->
loc
);
}
int
qemu_opts_set
(
QemuOptsList
*
list
,
const
char
*
id
,
int
qemu_opts_set
(
QemuOptsList
*
list
,
const
char
*
id
,
const
char
*
name
,
const
char
*
value
)
const
char
*
name
,
const
char
*
value
)
{
{
...
...
qemu-option.h
浏览文件 @
5efb397f
...
@@ -116,6 +116,7 @@ int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
...
@@ -116,6 +116,7 @@ int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
QemuOpts
*
qemu_opts_find
(
QemuOptsList
*
list
,
const
char
*
id
);
QemuOpts
*
qemu_opts_find
(
QemuOptsList
*
list
,
const
char
*
id
);
QemuOpts
*
qemu_opts_create
(
QemuOptsList
*
list
,
const
char
*
id
,
int
fail_if_exists
);
QemuOpts
*
qemu_opts_create
(
QemuOptsList
*
list
,
const
char
*
id
,
int
fail_if_exists
);
void
qemu_opts_reset
(
QemuOptsList
*
list
);
void
qemu_opts_reset
(
QemuOptsList
*
list
);
void
qemu_opts_loc_restore
(
QemuOpts
*
opts
);
int
qemu_opts_set
(
QemuOptsList
*
list
,
const
char
*
id
,
int
qemu_opts_set
(
QemuOptsList
*
list
,
const
char
*
id
,
const
char
*
name
,
const
char
*
value
);
const
char
*
name
,
const
char
*
value
);
const
char
*
qemu_opts_id
(
QemuOpts
*
opts
);
const
char
*
qemu_opts_id
(
QemuOpts
*
opts
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录