Revision e076f338

b/block.c
710 710
/*
711 711
 * Run consistency checks on an image
712 712
 *
713
 * Returns the number of errors or -errno when an internal error occurs
713
 * Returns 0 if the check could be completed (it doesn't mean that the image is
714
 * free of errors) or -errno when an internal error occured. The results of the
715
 * check are stored in res.
714 716
 */
715
int bdrv_check(BlockDriverState *bs)
717
int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
716 718
{
717 719
    if (bs->drv->bdrv_check == NULL) {
718 720
        return -ENOTSUP;
719 721
    }
720 722

  
721
    return bs->drv->bdrv_check(bs);
723
    memset(res, 0, sizeof(*res));
724
    res->corruptions = bs->drv->bdrv_check(bs);
725
    return res->corruptions < 0 ? res->corruptions : 0;
722 726
}
723 727

  
724 728
/* commit COW file into the raw image */
b/block.h
74 74
int bdrv_attach(BlockDriverState *bs, DeviceState *qdev);
75 75
void bdrv_detach(BlockDriverState *bs, DeviceState *qdev);
76 76
DeviceState *bdrv_get_attached(BlockDriverState *bs);
77
int bdrv_check(BlockDriverState *bs);
78 77
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
79 78
              uint8_t *buf, int nb_sectors);
80 79
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
......
97 96
    const char *backing_file, const char *backing_fmt);
98 97
void bdrv_register(BlockDriver *bdrv);
99 98

  
99

  
100
typedef struct BdrvCheckResult {
101
    int corruptions;
102
    int leaks;
103
    int check_errors;
104
} BdrvCheckResult;
105

  
106
int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res);
107

  
100 108
/* async block I/O */
101 109
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
102 110
typedef void BlockDriverCompletionFunc(void *opaque, int ret);
b/qemu-img.c
425 425
    return 0;
426 426
}
427 427

  
428
/*
429
 * Checks an image for consistency. Exit codes:
430
 *
431
 * 0 - Check completed, image is good
432
 * 1 - Check not completed because of internal errors
433
 * 2 - Check completed, image is corrupted
434
 * 3 - Check completed, image has leaked clusters, but is good otherwise
435
 */
428 436
static int img_check(int argc, char **argv)
429 437
{
430 438
    int c, ret;
431 439
    const char *filename, *fmt;
432 440
    BlockDriverState *bs;
441
    BdrvCheckResult result;
433 442

  
434 443
    fmt = NULL;
435 444
    for(;;) {
......
453 462
    if (!bs) {
454 463
        return 1;
455 464
    }
456
    ret = bdrv_check(bs);
457
    switch(ret) {
458
    case 0:
459
        printf("No errors were found on the image.\n");
460
        break;
461
    case -ENOTSUP:
465
    ret = bdrv_check(bs, &result);
466

  
467
    if (ret == -ENOTSUP) {
462 468
        error("This image format does not support checks");
463
        break;
464
    default:
465
        if (ret < 0) {
466
            error("An error occurred during the check");
467
        } else {
468
            printf("%d errors were found on the image.\n", ret);
469
        bdrv_delete(bs);
470
        return 1;
471
    }
472

  
473
    if (!(result.corruptions || result.leaks || result.check_errors)) {
474
        printf("No errors were found on the image.\n");
475
    } else {
476
        if (result.corruptions) {
477
            printf("\n%d errors were found on the image.\n"
478
                "Data may be corrupted, or further writes to the image "
479
                "may corrupt it.\n",
480
                result.corruptions);
481
        }
482

  
483
        if (result.leaks) {
484
            printf("\n%d leaked clusters were found on the image.\n"
485
                "This means waste of disk space, but no harm to data.\n",
486
                result.leaks);
487
        }
488

  
489
        if (result.check_errors) {
490
            printf("\n%d internal errors have occurred during the check.\n",
491
                result.check_errors);
469 492
        }
470
        break;
471 493
    }
472 494

  
473 495
    bdrv_delete(bs);
474
    if (ret) {
496

  
497
    if (ret < 0 || result.check_errors) {
498
        printf("\nAn error has occurred during the check: %s\n"
499
            "The check is not complete and may have missed error.\n",
500
            strerror(-ret));
475 501
        return 1;
476 502
    }
477
    return 0;
503

  
504
    if (result.corruptions) {
505
        return 2;
506
    } else if (result.leaks) {
507
        return 3;
508
    } else {
509
        return 0;
510
    }
478 511
}
479 512

  
480 513
static int img_commit(int argc, char **argv)

Also available in: Unified diff