?? block.c
字號:
return -ENOTSUP; } total_sectors = bdrv_getlength(bs) >> SECTOR_BITS; for (i = 0; i < total_sectors;) { if (drv->bdrv_is_allocated(bs, i, 65536, &n)) { for(j = 0; j < n; j++) { if (bdrv_read(bs, i, sector, 1) != 0) { return -EIO; } if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) { return -EIO; } i++; } } else { i += n; } } if (drv->bdrv_make_empty) return drv->bdrv_make_empty(bs); return 0;}/* return < 0 if error. See bdrv_write() for the return codes */int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { memcpy(buf, bs->boot_sector_data, 512); sector_num++; nb_sectors--; buf += 512; if (nb_sectors == 0) return 0; } if (drv->bdrv_pread) { int ret, len; len = nb_sectors * 512; ret = drv->bdrv_pread(bs, sector_num * 512, buf, len); if (ret < 0) return ret; else if (ret != len) return -EINVAL; else { bs->rd_bytes += (unsigned) len; bs->rd_ops ++; return 0; } } else { return drv->bdrv_read(bs, sector_num, buf, nb_sectors); }}/* Return < 0 if error. Important errors are: -EIO generic I/O error (may happen for all errors) -ENOMEDIUM No media inserted. -EINVAL Invalid sector number or nb_sectors -EACCES Trying to write a read-only device*/int bdrv_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors){ BlockDriver *drv = bs->drv; if (!bs->drv) return -ENOMEDIUM; if (bs->read_only) return -EACCES; if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { memcpy(bs->boot_sector_data, buf, 512); } if (drv->bdrv_pwrite) { int ret, len; len = nb_sectors * 512; ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len); if (ret < 0) return ret; else if (ret != len) return -EIO; else { bs->wr_bytes += (unsigned) len; bs->wr_ops ++; return 0; } } else { return drv->bdrv_write(bs, sector_num, buf, nb_sectors); }}static int bdrv_pread_em(BlockDriverState *bs, int64_t offset, uint8_t *buf, int count1){ uint8_t tmp_buf[SECTOR_SIZE]; int len, nb_sectors, count; int64_t sector_num; count = count1; /* first read to align to sector start */ len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); if (len > count) len = count; sector_num = offset >> SECTOR_BITS; if (len > 0) { if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) return -EIO; memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len); count -= len; if (count == 0) return count1; sector_num++; buf += len; } /* read the sectors "in place" */ nb_sectors = count >> SECTOR_BITS; if (nb_sectors > 0) { if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0) return -EIO; sector_num += nb_sectors; len = nb_sectors << SECTOR_BITS; buf += len; count -= len; } /* add data from the last sector */ if (count > 0) { if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) return -EIO; memcpy(buf, tmp_buf, count); } return count1;}static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset, const uint8_t *buf, int count1){ uint8_t tmp_buf[SECTOR_SIZE]; int len, nb_sectors, count; int64_t sector_num; count = count1; /* first write to align to sector start */ len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1); if (len > count) len = count; sector_num = offset >> SECTOR_BITS; if (len > 0) { if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) return -EIO; memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len); if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) return -EIO; count -= len; if (count == 0) return count1; sector_num++; buf += len; } /* write the sectors "in place" */ nb_sectors = count >> SECTOR_BITS; if (nb_sectors > 0) { if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0) return -EIO; sector_num += nb_sectors; len = nb_sectors << SECTOR_BITS; buf += len; count -= len; } /* add data from the last sector */ if (count > 0) { if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0) return -EIO; memcpy(tmp_buf, buf, count); if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0) return -EIO; } return count1;}/** * Read with byte offsets (needed only for file protocols) */int bdrv_pread(BlockDriverState *bs, int64_t offset, void *buf1, int count1){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_pread) return bdrv_pread_em(bs, offset, buf1, count1); return drv->bdrv_pread(bs, offset, buf1, count1);}/** * Write with byte offsets (needed only for file protocols) */int bdrv_pwrite(BlockDriverState *bs, int64_t offset, const void *buf1, int count1){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_pwrite) return bdrv_pwrite_em(bs, offset, buf1, count1); return drv->bdrv_pwrite(bs, offset, buf1, count1);}/** * Truncate file to 'offset' bytes (needed only for file protocols) */int bdrv_truncate(BlockDriverState *bs, int64_t offset){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_truncate) return -ENOTSUP; return drv->bdrv_truncate(bs, offset);}/** * Length of a file in bytes. Return < 0 if error or unknown. */int64_t bdrv_getlength(BlockDriverState *bs){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_getlength) { /* legacy mode */ return bs->total_sectors * SECTOR_SIZE; } return drv->bdrv_getlength(bs);}/* return 0 as number of sectors if no device present or error */void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr){ int64_t length; length = bdrv_getlength(bs); if (length < 0) length = 0; else length = length >> SECTOR_BITS; *nb_sectors_ptr = length;}/* force a given boot sector. */void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size){ bs->boot_sector_enabled = 1; if (size > 512) size = 512; memcpy(bs->boot_sector_data, data, size); memset(bs->boot_sector_data + size, 0, 512 - size);}void bdrv_set_geometry_hint(BlockDriverState *bs, int cyls, int heads, int secs){ bs->cyls = cyls; bs->heads = heads; bs->secs = secs;}void bdrv_set_type_hint(BlockDriverState *bs, int type){ bs->type = type; bs->removable = ((type == BDRV_TYPE_CDROM || type == BDRV_TYPE_FLOPPY));}void bdrv_set_translation_hint(BlockDriverState *bs, int translation){ bs->translation = translation;}void bdrv_get_geometry_hint(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs){ *pcyls = bs->cyls; *pheads = bs->heads; *psecs = bs->secs;}int bdrv_get_type_hint(BlockDriverState *bs){ return bs->type;}int bdrv_get_translation_hint(BlockDriverState *bs){ return bs->translation;}int bdrv_is_removable(BlockDriverState *bs){ return bs->removable;}int bdrv_is_read_only(BlockDriverState *bs){ return bs->read_only;}int bdrv_is_sg(BlockDriverState *bs){ return bs->sg;}/* XXX: no longer used */void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque){ bs->change_cb = change_cb; bs->change_opaque = opaque;}int bdrv_is_encrypted(BlockDriverState *bs){ if (bs->backing_hd && bs->backing_hd->encrypted) return 1; return bs->encrypted;}int bdrv_set_key(BlockDriverState *bs, const char *key){ int ret; if (bs->backing_hd && bs->backing_hd->encrypted) { ret = bdrv_set_key(bs->backing_hd, key); if (ret < 0) return ret; if (!bs->encrypted) return 0; } if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key) return -1; return bs->drv->bdrv_set_key(bs, key);}void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size){ if (!bs->drv) { buf[0] = '\0'; } else { pstrcpy(buf, buf_size, bs->drv->format_name); }}void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void *opaque){ BlockDriver *drv; for (drv = first_drv; drv != NULL; drv = drv->next) { it(opaque, drv->format_name); }}BlockDriverState *bdrv_find(const char *name){ BlockDriverState *bs; for (bs = bdrv_first; bs != NULL; bs = bs->next) { if (!strcmp(name, bs->device_name)) return bs; } return NULL;}void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque){ BlockDriverState *bs; for (bs = bdrv_first; bs != NULL; bs = bs->next) { it(opaque, bs->device_name); }}const char *bdrv_get_device_name(BlockDriverState *bs){ return bs->device_name;}void bdrv_flush(BlockDriverState *bs){ if (bs->drv->bdrv_flush) bs->drv->bdrv_flush(bs); if (bs->backing_hd) bdrv_flush(bs->backing_hd);}#ifndef QEMU_IMGvoid bdrv_info(void){ BlockDriverState *bs; for (bs = bdrv_first; bs != NULL; bs = bs->next) { term_printf("%s:", bs->device_name); term_printf(" type="); switch(bs->type) { case BDRV_TYPE_HD: term_printf("hd"); break; case BDRV_TYPE_CDROM: term_printf("cdrom"); break; case BDRV_TYPE_FLOPPY: term_printf("floppy"); break; } term_printf(" removable=%d", bs->removable); if (bs->removable) { term_printf(" locked=%d", bs->locked); } if (bs->drv) { term_printf(" file="); term_print_filename(bs->filename); if (bs->backing_file[0] != '\0') { term_printf(" backing_file="); term_print_filename(bs->backing_file); } term_printf(" ro=%d", bs->read_only); term_printf(" drv=%s", bs->drv->format_name); if (bs->encrypted) term_printf(" encrypted"); } else { term_printf(" [not inserted]"); } term_printf("\n"); }}/* The "info blockstats" command. */void bdrv_info_stats (void){ BlockDriverState *bs; for (bs = bdrv_first; bs != NULL; bs = bs->next) { term_printf ("%s:" " rd_bytes=%" PRIu64 " wr_bytes=%" PRIu64 " rd_operations=%" PRIu64 " wr_operations=%" PRIu64 "\n", bs->device_name, bs->rd_bytes, bs->wr_bytes, bs->rd_ops, bs->wr_ops); }}#endifvoid bdrv_get_backing_filename(BlockDriverState *bs, char *filename, int filename_size){ if (!bs->backing_hd) { pstrcpy(filename, filename_size, ""); } else { pstrcpy(filename, filename_size, bs->backing_file);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -