block: Move error actions from DriveInfo to BlockDriverState
That's where they belong semantically (block device host part), even though the actions are actually executed by guest device code. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
2063392ae5
commit
abd7f68d08
12
block.c
12
block.c
@ -1206,6 +1206,18 @@ int bdrv_get_translation_hint(BlockDriverState *bs)
|
|||||||
return bs->translation;
|
return bs->translation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
|
||||||
|
BlockErrorAction on_write_error)
|
||||||
|
{
|
||||||
|
bs->on_read_error = on_read_error;
|
||||||
|
bs->on_write_error = on_write_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read)
|
||||||
|
{
|
||||||
|
return is_read ? bs->on_read_error : bs->on_write_error;
|
||||||
|
}
|
||||||
|
|
||||||
int bdrv_is_removable(BlockDriverState *bs)
|
int bdrv_is_removable(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
return bs->removable;
|
return bs->removable;
|
||||||
|
8
block.h
8
block.h
@ -41,6 +41,11 @@ typedef struct QEMUSnapshotInfo {
|
|||||||
#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
|
#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
|
||||||
#define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1)
|
#define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BLOCK_ERR_REPORT, BLOCK_ERR_IGNORE, BLOCK_ERR_STOP_ENOSPC,
|
||||||
|
BLOCK_ERR_STOP_ANY
|
||||||
|
} BlockErrorAction;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
|
BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
|
||||||
} BlockMonEventAction;
|
} BlockMonEventAction;
|
||||||
@ -146,6 +151,9 @@ void bdrv_get_geometry_hint(BlockDriverState *bs,
|
|||||||
int *pcyls, int *pheads, int *psecs);
|
int *pcyls, int *pheads, int *psecs);
|
||||||
int bdrv_get_type_hint(BlockDriverState *bs);
|
int bdrv_get_type_hint(BlockDriverState *bs);
|
||||||
int bdrv_get_translation_hint(BlockDriverState *bs);
|
int bdrv_get_translation_hint(BlockDriverState *bs);
|
||||||
|
void bdrv_set_on_error(BlockDriverState *bs, BlockErrorAction on_read_error,
|
||||||
|
BlockErrorAction on_write_error);
|
||||||
|
BlockErrorAction bdrv_get_on_error(BlockDriverState *bs, int is_read);
|
||||||
int bdrv_is_removable(BlockDriverState *bs);
|
int bdrv_is_removable(BlockDriverState *bs);
|
||||||
int bdrv_is_read_only(BlockDriverState *bs);
|
int bdrv_is_read_only(BlockDriverState *bs);
|
||||||
int bdrv_is_sg(BlockDriverState *bs);
|
int bdrv_is_sg(BlockDriverState *bs);
|
||||||
|
@ -182,6 +182,7 @@ struct BlockDriverState {
|
|||||||
drivers. They are not used by the block driver */
|
drivers. They are not used by the block driver */
|
||||||
int cyls, heads, secs, translation;
|
int cyls, heads, secs, translation;
|
||||||
int type;
|
int type;
|
||||||
|
BlockErrorAction on_read_error, on_write_error;
|
||||||
char device_name[32];
|
char device_name[32];
|
||||||
unsigned long *dirty_bitmap;
|
unsigned long *dirty_bitmap;
|
||||||
int64_t dirty_count;
|
int64_t dirty_count;
|
||||||
|
17
blockdev.c
17
blockdev.c
@ -90,19 +90,6 @@ const char *drive_get_serial(BlockDriverState *bdrv)
|
|||||||
return "\0";
|
return "\0";
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockInterfaceErrorAction drive_get_on_error(
|
|
||||||
BlockDriverState *bdrv, int is_read)
|
|
||||||
{
|
|
||||||
DriveInfo *dinfo;
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(dinfo, &drives, next) {
|
|
||||||
if (dinfo->bdrv == bdrv)
|
|
||||||
return is_read ? dinfo->on_read_error : dinfo->on_write_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return is_read ? BLOCK_ERR_REPORT : BLOCK_ERR_STOP_ENOSPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bdrv_format_print(void *opaque, const char *name)
|
static void bdrv_format_print(void *opaque, const char *name)
|
||||||
{
|
{
|
||||||
fprintf(stderr, " %s", name);
|
fprintf(stderr, " %s", name);
|
||||||
@ -418,13 +405,13 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)
|
|||||||
dinfo->type = type;
|
dinfo->type = type;
|
||||||
dinfo->bus = bus_id;
|
dinfo->bus = bus_id;
|
||||||
dinfo->unit = unit_id;
|
dinfo->unit = unit_id;
|
||||||
dinfo->on_read_error = on_read_error;
|
|
||||||
dinfo->on_write_error = on_write_error;
|
|
||||||
dinfo->opts = opts;
|
dinfo->opts = opts;
|
||||||
if (serial)
|
if (serial)
|
||||||
strncpy(dinfo->serial, serial, sizeof(dinfo->serial) - 1);
|
strncpy(dinfo->serial, serial, sizeof(dinfo->serial) - 1);
|
||||||
QTAILQ_INSERT_TAIL(&drives, dinfo, next);
|
QTAILQ_INSERT_TAIL(&drives, dinfo, next);
|
||||||
|
|
||||||
|
bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case IF_IDE:
|
case IF_IDE:
|
||||||
case IF_SCSI:
|
case IF_SCSI:
|
||||||
|
10
blockdev.h
10
blockdev.h
@ -19,11 +19,6 @@ typedef enum {
|
|||||||
IF_COUNT
|
IF_COUNT
|
||||||
} BlockInterfaceType;
|
} BlockInterfaceType;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BLOCK_ERR_REPORT, BLOCK_ERR_IGNORE, BLOCK_ERR_STOP_ENOSPC,
|
|
||||||
BLOCK_ERR_STOP_ANY
|
|
||||||
} BlockInterfaceErrorAction;
|
|
||||||
|
|
||||||
#define BLOCK_SERIAL_STRLEN 20
|
#define BLOCK_SERIAL_STRLEN 20
|
||||||
|
|
||||||
typedef struct DriveInfo {
|
typedef struct DriveInfo {
|
||||||
@ -34,8 +29,6 @@ typedef struct DriveInfo {
|
|||||||
int bus;
|
int bus;
|
||||||
int unit;
|
int unit;
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
BlockInterfaceErrorAction on_read_error;
|
|
||||||
BlockInterfaceErrorAction on_write_error;
|
|
||||||
char serial[BLOCK_SERIAL_STRLEN + 1];
|
char serial[BLOCK_SERIAL_STRLEN + 1];
|
||||||
QTAILQ_ENTRY(DriveInfo) next;
|
QTAILQ_ENTRY(DriveInfo) next;
|
||||||
} DriveInfo;
|
} DriveInfo;
|
||||||
@ -51,9 +44,6 @@ extern int drive_get_max_bus(BlockInterfaceType type);
|
|||||||
extern void drive_uninit(DriveInfo *dinfo);
|
extern void drive_uninit(DriveInfo *dinfo);
|
||||||
extern const char *drive_get_serial(BlockDriverState *bdrv);
|
extern const char *drive_get_serial(BlockDriverState *bdrv);
|
||||||
|
|
||||||
extern BlockInterfaceErrorAction drive_get_on_error(
|
|
||||||
BlockDriverState *bdrv, int is_read);
|
|
||||||
|
|
||||||
extern QemuOpts *drive_add(const char *file, const char *fmt, ...);
|
extern QemuOpts *drive_add(const char *file, const char *fmt, ...);
|
||||||
extern DriveInfo *drive_init(QemuOpts *arg, int default_to_scsi,
|
extern DriveInfo *drive_init(QemuOpts *arg, int default_to_scsi,
|
||||||
int *fatal_error);
|
int *fatal_error);
|
||||||
|
@ -481,7 +481,7 @@ void ide_dma_error(IDEState *s)
|
|||||||
static int ide_handle_rw_error(IDEState *s, int error, int op)
|
static int ide_handle_rw_error(IDEState *s, int error, int op)
|
||||||
{
|
{
|
||||||
int is_read = (op & BM_STATUS_RETRY_READ);
|
int is_read = (op & BM_STATUS_RETRY_READ);
|
||||||
BlockInterfaceErrorAction action = drive_get_on_error(s->bs, is_read);
|
BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
|
||||||
|
|
||||||
if (action == BLOCK_ERR_IGNORE) {
|
if (action == BLOCK_ERR_IGNORE) {
|
||||||
bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
|
bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
|
||||||
|
@ -182,7 +182,7 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag)
|
|||||||
static int scsi_handle_write_error(SCSIDiskReq *r, int error)
|
static int scsi_handle_write_error(SCSIDiskReq *r, int error)
|
||||||
{
|
{
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
BlockInterfaceErrorAction action = drive_get_on_error(s->bs, 0);
|
BlockErrorAction action = bdrv_get_on_error(s->bs, 0);
|
||||||
|
|
||||||
if (action == BLOCK_ERR_IGNORE) {
|
if (action == BLOCK_ERR_IGNORE) {
|
||||||
bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, 0);
|
bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, 0);
|
||||||
|
@ -58,8 +58,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
|
|||||||
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
|
static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
|
||||||
int is_read)
|
int is_read)
|
||||||
{
|
{
|
||||||
BlockInterfaceErrorAction action =
|
BlockErrorAction action = bdrv_get_on_error(req->dev->bs, is_read);
|
||||||
drive_get_on_error(req->dev->bs, is_read);
|
|
||||||
VirtIOBlock *s = req->dev;
|
VirtIOBlock *s = req->dev;
|
||||||
|
|
||||||
if (action == BLOCK_ERR_IGNORE) {
|
if (action == BLOCK_ERR_IGNORE) {
|
||||||
|
Loading…
Reference in New Issue
Block a user