?? block.c
字號:
}}int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_write_compressed) return -ENOTSUP; return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);}int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_get_info) return -ENOTSUP; memset(bdi, 0, sizeof(*bdi)); return drv->bdrv_get_info(bs, bdi);}/**************************************************************//* handling of snapshots */int bdrv_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_snapshot_create) return -ENOTSUP; return drv->bdrv_snapshot_create(bs, sn_info);}int bdrv_snapshot_goto(BlockDriverState *bs, const char *snapshot_id){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_snapshot_goto) return -ENOTSUP; return drv->bdrv_snapshot_goto(bs, snapshot_id);}int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_snapshot_delete) return -ENOTSUP; return drv->bdrv_snapshot_delete(bs, snapshot_id);}int bdrv_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_info){ BlockDriver *drv = bs->drv; if (!drv) return -ENOMEDIUM; if (!drv->bdrv_snapshot_list) return -ENOTSUP; return drv->bdrv_snapshot_list(bs, psn_info);}#define NB_SUFFIXES 4char *get_human_readable_size(char *buf, int buf_size, int64_t size){ static const char suffixes[NB_SUFFIXES] = "KMGT"; int64_t base; int i; if (size <= 999) { snprintf(buf, buf_size, "%" PRId64, size); } else { base = 1024; for(i = 0; i < NB_SUFFIXES; i++) { if (size < (10 * base)) { snprintf(buf, buf_size, "%0.1f%c", (double)size / base, suffixes[i]); break; } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { snprintf(buf, buf_size, "%" PRId64 "%c", ((size + (base >> 1)) / base), suffixes[i]); break; } base = base * 1024; } } return buf;}char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn){ char buf1[128], date_buf[128], clock_buf[128];#ifdef _WIN32 struct tm *ptm;#else struct tm tm;#endif time_t ti; int64_t secs; if (!sn) { snprintf(buf, buf_size, "%-10s%-20s%7s%20s%15s", "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); } else { ti = sn->date_sec;#ifdef _WIN32 ptm = localtime(&ti); strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", ptm);#else localtime_r(&ti, &tm); strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm);#endif secs = sn->vm_clock_nsec / 1000000000; snprintf(clock_buf, sizeof(clock_buf), "%02d:%02d:%02d.%03d", (int)(secs / 3600), (int)((secs / 60) % 60), (int)(secs % 60), (int)((sn->vm_clock_nsec / 1000000) % 1000)); snprintf(buf, buf_size, "%-10s%-20s%7s%20s%15s", sn->id_str, sn->name, get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size), date_buf, clock_buf); } return buf;}/**************************************************************//* async I/Os */BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque){ BlockDriver *drv = bs->drv; BlockDriverAIOCB *ret; if (!drv) return NULL; /* XXX: we assume that nb_sectors == 0 is suppored by the async read */ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { memcpy(buf, bs->boot_sector_data, 512); sector_num++; nb_sectors--; buf += 512; } ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque); if (ret) { /* Update stats even though technically transfer has not happened. */ bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE; bs->rd_ops ++; } return ret;}BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque){ BlockDriver *drv = bs->drv; BlockDriverAIOCB *ret; if (!drv) return NULL; if (bs->read_only) return NULL; if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { memcpy(bs->boot_sector_data, buf, 512); } ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque); if (ret) { /* Update stats even though technically transfer has not happened. */ bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE; bs->wr_ops ++; } return ret;}void bdrv_aio_cancel(BlockDriverAIOCB *acb){ BlockDriver *drv = acb->bs->drv; drv->bdrv_aio_cancel(acb);}/**************************************************************//* async block device emulation */#ifdef QEMU_IMGstatic BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque){ int ret; ret = bdrv_read(bs, sector_num, buf, nb_sectors); cb(opaque, ret); return NULL;}static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque){ int ret; ret = bdrv_write(bs, sector_num, buf, nb_sectors); cb(opaque, ret); return NULL;}static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb){}#elsestatic void bdrv_aio_bh_cb(void *opaque){ BlockDriverAIOCBSync *acb = opaque; acb->common.cb(acb->common.opaque, acb->ret); qemu_aio_release(acb);}static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque){ BlockDriverAIOCBSync *acb; int ret; acb = qemu_aio_get(bs, cb, opaque); if (!acb->bh) acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); ret = bdrv_read(bs, sector_num, buf, nb_sectors); acb->ret = ret; qemu_bh_schedule(acb->bh); return &acb->common;}static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque){ BlockDriverAIOCBSync *acb; int ret; acb = qemu_aio_get(bs, cb, opaque); if (!acb->bh) acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); ret = bdrv_write(bs, sector_num, buf, nb_sectors); acb->ret = ret; qemu_bh_schedule(acb->bh); return &acb->common;}static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb){ BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb; qemu_bh_cancel(acb->bh); qemu_aio_release(acb);}#endif /* !QEMU_IMG *//**************************************************************//* sync block device emulation */static void bdrv_rw_em_cb(void *opaque, int ret){ *(int *)opaque = ret;}#define NOT_DONE 0x7fffffffstatic int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors){ int async_ret; BlockDriverAIOCB *acb; async_ret = NOT_DONE; qemu_aio_wait_start(); acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors, bdrv_rw_em_cb, &async_ret); if (acb == NULL) { qemu_aio_wait_end(); return -1; } while (async_ret == NOT_DONE) { qemu_aio_wait(); } qemu_aio_wait_end(); return async_ret;}static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors){ int async_ret; BlockDriverAIOCB *acb; async_ret = NOT_DONE; qemu_aio_wait_start(); acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors, bdrv_rw_em_cb, &async_ret); if (acb == NULL) { qemu_aio_wait_end(); return -1; } while (async_ret == NOT_DONE) { qemu_aio_wait(); } qemu_aio_wait_end(); return async_ret;}void bdrv_init(void){ bdrv_register(&bdrv_raw); bdrv_register(&bdrv_host_device);#ifndef _WIN32 bdrv_register(&bdrv_cow);#endif bdrv_register(&bdrv_qcow); bdrv_register(&bdrv_vmdk); bdrv_register(&bdrv_cloop); bdrv_register(&bdrv_dmg); bdrv_register(&bdrv_bochs); bdrv_register(&bdrv_vpc); bdrv_register(&bdrv_vvfat); bdrv_register(&bdrv_qcow2); bdrv_register(&bdrv_parallels);}void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque){ BlockDriver *drv; BlockDriverAIOCB *acb; drv = bs->drv; if (drv->free_aiocb) { acb = drv->free_aiocb; drv->free_aiocb = acb->next; } else { acb = qemu_mallocz(drv->aiocb_size); if (!acb) return NULL; } acb->bs = bs; acb->cb = cb; acb->opaque = opaque; return acb;}void qemu_aio_release(void *p){ BlockDriverAIOCB *acb = p; BlockDriver *drv = acb->bs->drv; acb->next = drv->free_aiocb; drv->free_aiocb = acb;}/**************************************************************//* removable device support *//** * Return TRUE if the media is present */int bdrv_is_inserted(BlockDriverState *bs){ BlockDriver *drv = bs->drv; int ret; if (!drv) return 0; if (!drv->bdrv_is_inserted) return 1; ret = drv->bdrv_is_inserted(bs); return ret;}/** * Return TRUE if the media changed since the last call to this * function. It is currently only used for floppy disks */int bdrv_media_changed(BlockDriverState *bs){ BlockDriver *drv = bs->drv; int ret; if (!drv || !drv->bdrv_media_changed) ret = -ENOTSUP; else ret = drv->bdrv_media_changed(bs); if (ret == -ENOTSUP) ret = bs->media_changed; bs->media_changed = 0; return ret;}/** * If eject_flag is TRUE, eject the media. Otherwise, close the tray */void bdrv_eject(BlockDriverState *bs, int eject_flag){ BlockDriver *drv = bs->drv; int ret; if (!drv || !drv->bdrv_eject) { ret = -ENOTSUP; } else { ret = drv->bdrv_eject(bs, eject_flag); } if (ret == -ENOTSUP) { if (eject_flag) bdrv_close(bs); }}int bdrv_is_locked(BlockDriverState *bs){ return bs->locked;}/** * Lock or unlock the media (if it is locked, the user won't be able * to eject it manually). */void bdrv_set_locked(BlockDriverState *bs, int locked){ BlockDriver *drv = bs->drv; bs->locked = locked; if (drv && drv->bdrv_set_locked) { drv->bdrv_set_locked(bs, locked); }}/* needed for generic scsi interface */int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf){ BlockDriver *drv = bs->drv; if (drv && drv->bdrv_ioctl) return drv->bdrv_ioctl(bs, req, buf); return -ENOTSUP;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -