📄 block.c
字号:
} i++; } } else { i += n; } } if (bs->drv->bdrv_make_empty) return bs->drv->bdrv_make_empty(bs); return 0;}/* return -1 if error */int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors){ int ret, n; BlockDriver *drv = bs->drv; if (!bs->inserted) return -1; while (nb_sectors > 0) { if (sector_num == 0 && bs->boot_sector_enabled) { memcpy(buf, bs->boot_sector_data, 512); n = 1; } else if (bs->backing_hd) { if (drv->bdrv_is_allocated(bs, sector_num, nb_sectors, &n)) { ret = drv->bdrv_read(bs, sector_num, buf, n); if (ret < 0) return -1; } else { /* read from the base image */ ret = bdrv_read(bs->backing_hd, sector_num, buf, n); if (ret < 0) return -1; } } else { ret = drv->bdrv_read(bs, sector_num, buf, nb_sectors); if (ret < 0) return -1; /* no need to loop */ break; } nb_sectors -= n; sector_num += n; buf += n * 512; } return 0;}/* return -1 if error */int bdrv_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors){ if (!bs->inserted) return -1; if (bs->read_only) return -1; if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) { memcpy(bs->boot_sector_data, buf, 512); } return bs->drv->bdrv_write(bs, sector_num, buf, nb_sectors);}void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr){ *nb_sectors_ptr = bs->total_sectors;}/* 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_inserted(BlockDriverState *bs){ return bs->inserted;}int bdrv_is_locked(BlockDriverState *bs){ return bs->locked;}void bdrv_set_locked(BlockDriverState *bs, int locked){ bs->locked = locked;}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->inserted || !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_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->inserted) { term_printf(" file=%s", bs->filename); if (bs->backing_file[0] != '\0') term_printf(" backing_file=%s", 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"); }}/**************************************************************//* RAW block driver */typedef struct BDRVRawState { int fd;} BDRVRawState;static int raw_probe(const uint8_t *buf, int buf_size, const char *filename){ return 1; /* maybe */}static int raw_open(BlockDriverState *bs, const char *filename){ BDRVRawState *s = bs->opaque; int fd; int64_t size;#ifdef _BSD struct stat sb;#endif#ifdef __sun__ struct dk_minfo minfo; int rv;#endif fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE); if (fd < 0) { fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE); if (fd < 0) return -1; bs->read_only = 1; }#ifdef _BSD if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {#ifdef DIOCGMEDIASIZE if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))#endif#ifdef CONFIG_COCOA size = LONG_LONG_MAX;#else size = lseek(fd, 0LL, SEEK_END);#endif } else#endif#ifdef __sun__ /* * use the DKIOCGMEDIAINFO ioctl to read the size. */ rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo ); if ( rv != -1 ) { size = minfo.dki_lbsize * minfo.dki_capacity; } else /* there are reports that lseek on some devices fails, but irc discussion said that contingency on contingency was overkill */#endif { size = lseek(fd, 0, SEEK_END); }#ifdef _WIN32 /* On Windows hosts it can happen that we're unable to get file size for CD-ROM raw device (it's inherent limitation of the CDFS driver). */ if (size == -1) size = LONG_LONG_MAX;#endif bs->total_sectors = size / 512; s->fd = fd; return 0;}static int raw_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors){ BDRVRawState *s = bs->opaque; int ret; lseek(s->fd, sector_num * 512, SEEK_SET); ret = read(s->fd, buf, nb_sectors * 512); if (ret != nb_sectors * 512) return -1; return 0;}static int raw_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors){ BDRVRawState *s = bs->opaque; int ret; lseek(s->fd, sector_num * 512, SEEK_SET); ret = write(s->fd, buf, nb_sectors * 512); if (ret != nb_sectors * 512) return -1; return 0;}static void raw_close(BlockDriverState *bs){ BDRVRawState *s = bs->opaque; close(s->fd);}static int raw_create(const char *filename, int64_t total_size, const char *backing_file, int flags){ int fd; if (flags || backing_file) return -ENOTSUP; fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644); if (fd < 0) return -EIO; ftruncate(fd, total_size * 512); close(fd); return 0;}BlockDriver bdrv_raw = { "raw", sizeof(BDRVRawState), raw_probe, raw_open, raw_read, raw_write, raw_close, raw_create,};void bdrv_init(void){ bdrv_register(&bdrv_raw);#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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -