Merge remote-tracking branch 'kwolf/for-anthony' into staging
This commit is contained in:
commit
2963e65a4e
117
block/cloop.c
117
block/cloop.c
@ -30,7 +30,7 @@ typedef struct BDRVCloopState {
|
||||
CoMutex lock;
|
||||
uint32_t block_size;
|
||||
uint32_t n_blocks;
|
||||
uint64_t* offsets;
|
||||
uint64_t *offsets;
|
||||
uint32_t sectors_per_block;
|
||||
uint32_t current_block;
|
||||
uint8_t *compressed_block;
|
||||
@ -40,21 +40,23 @@ typedef struct BDRVCloopState {
|
||||
|
||||
static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
|
||||
{
|
||||
const char* magic_version_2_0="#!/bin/sh\n"
|
||||
"#V2.0 Format\n"
|
||||
"modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
|
||||
int length=strlen(magic_version_2_0);
|
||||
if(length>buf_size)
|
||||
length=buf_size;
|
||||
if(!memcmp(magic_version_2_0,buf,length))
|
||||
return 2;
|
||||
const char *magic_version_2_0 = "#!/bin/sh\n"
|
||||
"#V2.0 Format\n"
|
||||
"modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
|
||||
int length = strlen(magic_version_2_0);
|
||||
if (length > buf_size) {
|
||||
length = buf_size;
|
||||
}
|
||||
if (!memcmp(magic_version_2_0, buf, length)) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cloop_open(BlockDriverState *bs, int flags)
|
||||
{
|
||||
BDRVCloopState *s = bs->opaque;
|
||||
uint32_t offsets_size,max_compressed_block_size=1,i;
|
||||
uint32_t offsets_size, max_compressed_block_size = 1, i;
|
||||
|
||||
bs->read_only = 1;
|
||||
|
||||
@ -74,26 +76,28 @@ static int cloop_open(BlockDriverState *bs, int flags)
|
||||
s->offsets = g_malloc(offsets_size);
|
||||
if (bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size) <
|
||||
offsets_size) {
|
||||
goto cloop_close;
|
||||
goto cloop_close;
|
||||
}
|
||||
for(i=0;i<s->n_blocks;i++) {
|
||||
s->offsets[i]=be64_to_cpu(s->offsets[i]);
|
||||
if(i>0) {
|
||||
uint32_t size=s->offsets[i]-s->offsets[i-1];
|
||||
if(size>max_compressed_block_size)
|
||||
max_compressed_block_size=size;
|
||||
}
|
||||
s->offsets[i] = be64_to_cpu(s->offsets[i]);
|
||||
if (i > 0) {
|
||||
uint32_t size = s->offsets[i] - s->offsets[i - 1];
|
||||
if (size > max_compressed_block_size) {
|
||||
max_compressed_block_size = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize zlib engine */
|
||||
s->compressed_block = g_malloc(max_compressed_block_size+1);
|
||||
s->compressed_block = g_malloc(max_compressed_block_size + 1);
|
||||
s->uncompressed_block = g_malloc(s->block_size);
|
||||
if(inflateInit(&s->zstream) != Z_OK)
|
||||
goto cloop_close;
|
||||
s->current_block=s->n_blocks;
|
||||
if (inflateInit(&s->zstream) != Z_OK) {
|
||||
goto cloop_close;
|
||||
}
|
||||
s->current_block = s->n_blocks;
|
||||
|
||||
s->sectors_per_block = s->block_size/512;
|
||||
bs->total_sectors = s->n_blocks*s->sectors_per_block;
|
||||
bs->total_sectors = s->n_blocks * s->sectors_per_block;
|
||||
qemu_co_mutex_init(&s->lock);
|
||||
return 0;
|
||||
|
||||
@ -105,27 +109,30 @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num)
|
||||
{
|
||||
BDRVCloopState *s = bs->opaque;
|
||||
|
||||
if(s->current_block != block_num) {
|
||||
int ret;
|
||||
uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
|
||||
if (s->current_block != block_num) {
|
||||
int ret;
|
||||
uint32_t bytes = s->offsets[block_num + 1] - s->offsets[block_num];
|
||||
|
||||
ret = bdrv_pread(bs->file, s->offsets[block_num], s->compressed_block,
|
||||
bytes);
|
||||
if (ret != bytes)
|
||||
if (ret != bytes) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->zstream.next_in = s->compressed_block;
|
||||
s->zstream.avail_in = bytes;
|
||||
s->zstream.next_out = s->uncompressed_block;
|
||||
s->zstream.avail_out = s->block_size;
|
||||
ret = inflateReset(&s->zstream);
|
||||
if(ret != Z_OK)
|
||||
return -1;
|
||||
ret = inflate(&s->zstream, Z_FINISH);
|
||||
if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
|
||||
return -1;
|
||||
s->zstream.next_in = s->compressed_block;
|
||||
s->zstream.avail_in = bytes;
|
||||
s->zstream.next_out = s->uncompressed_block;
|
||||
s->zstream.avail_out = s->block_size;
|
||||
ret = inflateReset(&s->zstream);
|
||||
if (ret != Z_OK) {
|
||||
return -1;
|
||||
}
|
||||
ret = inflate(&s->zstream, Z_FINISH);
|
||||
if (ret != Z_STREAM_END || s->zstream.total_out != s->block_size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->current_block = block_num;
|
||||
s->current_block = block_num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -136,12 +143,15 @@ static int cloop_read(BlockDriverState *bs, int64_t sector_num,
|
||||
BDRVCloopState *s = bs->opaque;
|
||||
int i;
|
||||
|
||||
for(i=0;i<nb_sectors;i++) {
|
||||
uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block),
|
||||
block_num=(sector_num+i)/s->sectors_per_block;
|
||||
if(cloop_read_block(bs, block_num) != 0)
|
||||
return -1;
|
||||
memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512);
|
||||
for (i = 0; i < nb_sectors; i++) {
|
||||
uint32_t sector_offset_in_block =
|
||||
((sector_num + i) % s->sectors_per_block),
|
||||
block_num = (sector_num + i) / s->sectors_per_block;
|
||||
if (cloop_read_block(bs, block_num) != 0) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(buf + i * 512,
|
||||
s->uncompressed_block + sector_offset_in_block * 512, 512);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -160,20 +170,21 @@ static coroutine_fn int cloop_co_read(BlockDriverState *bs, int64_t sector_num,
|
||||
static void cloop_close(BlockDriverState *bs)
|
||||
{
|
||||
BDRVCloopState *s = bs->opaque;
|
||||
if(s->n_blocks>0)
|
||||
free(s->offsets);
|
||||
free(s->compressed_block);
|
||||
free(s->uncompressed_block);
|
||||
if (s->n_blocks > 0) {
|
||||
g_free(s->offsets);
|
||||
}
|
||||
g_free(s->compressed_block);
|
||||
g_free(s->uncompressed_block);
|
||||
inflateEnd(&s->zstream);
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_cloop = {
|
||||
.format_name = "cloop",
|
||||
.instance_size = sizeof(BDRVCloopState),
|
||||
.bdrv_probe = cloop_probe,
|
||||
.bdrv_open = cloop_open,
|
||||
.bdrv_read = cloop_co_read,
|
||||
.bdrv_close = cloop_close,
|
||||
.format_name = "cloop",
|
||||
.instance_size = sizeof(BDRVCloopState),
|
||||
.bdrv_probe = cloop_probe,
|
||||
.bdrv_open = cloop_open,
|
||||
.bdrv_read = cloop_co_read,
|
||||
.bdrv_close = cloop_close,
|
||||
};
|
||||
|
||||
static void bdrv_cloop_init(void)
|
||||
|
@ -799,6 +799,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
|
||||
/* root directory */
|
||||
int cur = s->directory.next;
|
||||
array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
|
||||
s->directory.next = ROOT_ENTRIES;
|
||||
memset(array_get(&(s->directory), cur), 0,
|
||||
(ROOT_ENTRIES - cur) * sizeof(direntry_t));
|
||||
}
|
||||
@ -915,11 +916,8 @@ static int init_directories(BDRVVVFATState* s,
|
||||
cluster = mapping->end;
|
||||
|
||||
if(cluster > s->cluster_count) {
|
||||
fprintf(stderr,"Directory does not fit in FAT%d (capacity %s)\n",
|
||||
s->fat_type,
|
||||
s->fat_type == 12 ? s->sector_count == 2880 ? "1.44 MB"
|
||||
: "2.88 MB"
|
||||
: "504MB");
|
||||
fprintf(stderr,"Directory does not fit in FAT%d (capacity %.2f MB)\n",
|
||||
s->fat_type, s->sector_count / 2000.0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -953,7 +951,7 @@ static int init_directories(BDRVVVFATState* s,
|
||||
bootsector->number_of_fats=0x2; /* number of FATs */
|
||||
bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
|
||||
bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
|
||||
bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */
|
||||
bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/
|
||||
s->fat.pointer[0] = bootsector->media_type;
|
||||
bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
|
||||
bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);
|
||||
@ -962,7 +960,7 @@ static int init_directories(BDRVVVFATState* s,
|
||||
bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
|
||||
|
||||
/* LATER TODO: if FAT32, this is wrong */
|
||||
bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */
|
||||
bootsector->u.fat16.drive_number=s->first_sectors_number==1?0:0x80; /* fda=0, hda=0x80 */
|
||||
bootsector->u.fat16.current_head=0;
|
||||
bootsector->u.fat16.signature=0x29;
|
||||
bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
|
||||
@ -984,7 +982,6 @@ static int is_consistent(BDRVVVFATState *s);
|
||||
static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)
|
||||
{
|
||||
BDRVVVFATState *s = bs->opaque;
|
||||
int floppy = 0;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -998,11 +995,8 @@ DLOG(if (stderr == NULL) {
|
||||
|
||||
s->bs = bs;
|
||||
|
||||
s->fat_type=16;
|
||||
/* LATER TODO: if FAT32, adjust */
|
||||
s->sectors_per_cluster=0x10;
|
||||
/* 504MB disk*/
|
||||
bs->cyls=1024; bs->heads=16; bs->secs=63;
|
||||
|
||||
s->current_cluster=0xffffffff;
|
||||
|
||||
@ -1017,16 +1011,6 @@ DLOG(if (stderr == NULL) {
|
||||
if (!strstart(dirname, "fat:", NULL))
|
||||
return -1;
|
||||
|
||||
if (strstr(dirname, ":floppy:")) {
|
||||
floppy = 1;
|
||||
s->fat_type = 12;
|
||||
s->first_sectors_number = 1;
|
||||
s->sectors_per_cluster=2;
|
||||
bs->cyls = 80; bs->heads = 2; bs->secs = 36;
|
||||
}
|
||||
|
||||
s->sector_count=bs->cyls*bs->heads*bs->secs;
|
||||
|
||||
if (strstr(dirname, ":32:")) {
|
||||
fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
|
||||
s->fat_type = 32;
|
||||
@ -1034,9 +1018,31 @@ DLOG(if (stderr == NULL) {
|
||||
s->fat_type = 16;
|
||||
} else if (strstr(dirname, ":12:")) {
|
||||
s->fat_type = 12;
|
||||
s->sector_count=2880;
|
||||
}
|
||||
|
||||
if (strstr(dirname, ":floppy:")) {
|
||||
/* 1.44MB or 2.88MB floppy. 2.88MB can be FAT12 (default) or FAT16. */
|
||||
if (!s->fat_type) {
|
||||
s->fat_type = 12;
|
||||
bs->secs = 36;
|
||||
s->sectors_per_cluster=2;
|
||||
} else {
|
||||
bs->secs=(s->fat_type == 12 ? 18 : 36);
|
||||
s->sectors_per_cluster=1;
|
||||
}
|
||||
s->first_sectors_number = 1;
|
||||
bs->cyls=80; bs->heads=2;
|
||||
} else {
|
||||
/* 32MB or 504MB disk*/
|
||||
if (!s->fat_type) {
|
||||
s->fat_type = 16;
|
||||
}
|
||||
bs->cyls=(s->fat_type == 12 ? 64 : 1024);
|
||||
bs->heads=16; bs->secs=63;
|
||||
}
|
||||
|
||||
s->sector_count=bs->cyls*bs->heads*bs->secs-(s->first_sectors_number-1);
|
||||
|
||||
if (strstr(dirname, ":rw:")) {
|
||||
if (enable_write_target(s))
|
||||
return -1;
|
||||
@ -1060,10 +1066,10 @@ DLOG(if (stderr == NULL) {
|
||||
|
||||
if(s->first_sectors_number==0x40)
|
||||
init_mbr(s);
|
||||
|
||||
/* for some reason or other, MS-DOS does not like to know about CHS... */
|
||||
if (floppy)
|
||||
else {
|
||||
/* MS-DOS does not like to know about CHS (?). */
|
||||
bs->heads = bs->cyls = bs->secs = 0;
|
||||
}
|
||||
|
||||
// assert(is_consistent(s));
|
||||
qemu_co_mutex_init(&s->lock);
|
||||
@ -1244,7 +1250,7 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
|
||||
int i;
|
||||
|
||||
for(i=0;i<nb_sectors;i++,sector_num++) {
|
||||
if (sector_num >= s->sector_count)
|
||||
if (sector_num >= bs->total_sectors)
|
||||
return -1;
|
||||
if (s->qcow) {
|
||||
int n;
|
||||
@ -1270,7 +1276,7 @@ DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
|
||||
uint32_t sector=sector_num-s->faked_sectors,
|
||||
sector_offset_in_cluster=(sector%s->sectors_per_cluster),
|
||||
cluster_num=sector/s->sectors_per_cluster;
|
||||
if(read_cluster(s, cluster_num) != 0) {
|
||||
if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
|
||||
/* LATER TODO: strict: return -1; */
|
||||
memset(buf+i*0x200,0,0x200);
|
||||
continue;
|
||||
|
10
hw/dma.c
10
hw/dma.c
@ -358,6 +358,14 @@ static void DMA_run (void)
|
||||
struct dma_cont *d;
|
||||
int icont, ichan;
|
||||
int rearm = 0;
|
||||
static int running = 0;
|
||||
|
||||
if (running) {
|
||||
rearm = 1;
|
||||
goto out;
|
||||
} else {
|
||||
running = 1;
|
||||
}
|
||||
|
||||
d = dma_controllers;
|
||||
|
||||
@ -374,6 +382,8 @@ static void DMA_run (void)
|
||||
}
|
||||
}
|
||||
|
||||
running = 0;
|
||||
out:
|
||||
if (rearm)
|
||||
qemu_bh_schedule_idle(dma_bh);
|
||||
}
|
||||
|
37
qemu-io.c
37
qemu-io.c
@ -596,6 +596,9 @@ static int readv_f(int argc, char **argv)
|
||||
|
||||
nr_iov = argc - optind;
|
||||
buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
|
||||
if (buf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
gettimeofday(&t1, NULL);
|
||||
cnt = do_aio_readv(&qiov, offset, &total);
|
||||
@ -850,6 +853,9 @@ static int writev_f(int argc, char **argv)
|
||||
|
||||
nr_iov = argc - optind;
|
||||
buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
|
||||
if (buf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
gettimeofday(&t1, NULL);
|
||||
cnt = do_aio_writev(&qiov, offset, &total);
|
||||
@ -950,25 +956,25 @@ static int multiwrite_f(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
reqs = g_malloc(nr_reqs * sizeof(*reqs));
|
||||
buf = g_malloc(nr_reqs * sizeof(*buf));
|
||||
reqs = g_malloc0(nr_reqs * sizeof(*reqs));
|
||||
buf = g_malloc0(nr_reqs * sizeof(*buf));
|
||||
qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
|
||||
|
||||
for (i = 0; i < nr_reqs; i++) {
|
||||
for (i = 0; i < nr_reqs && optind < argc; i++) {
|
||||
int j;
|
||||
|
||||
/* Read the offset of the request */
|
||||
offset = cvtnum(argv[optind]);
|
||||
if (offset < 0) {
|
||||
printf("non-numeric offset argument -- %s\n", argv[optind]);
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
optind++;
|
||||
|
||||
if (offset & 0x1ff) {
|
||||
printf("offset %lld is not sector aligned\n",
|
||||
(long long)offset);
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
@ -985,8 +991,12 @@ static int multiwrite_f(int argc, char **argv)
|
||||
nr_iov = j - optind;
|
||||
|
||||
/* Build request */
|
||||
buf[i] = create_iovec(&qiovs[i], &argv[optind], nr_iov, pattern);
|
||||
if (buf[i] == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
reqs[i].qiov = &qiovs[i];
|
||||
buf[i] = create_iovec(reqs[i].qiov, &argv[optind], nr_iov, pattern);
|
||||
reqs[i].sector = offset >> 9;
|
||||
reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
|
||||
|
||||
@ -995,6 +1005,9 @@ static int multiwrite_f(int argc, char **argv)
|
||||
pattern++;
|
||||
}
|
||||
|
||||
/* If there were empty requests at the end, ignore them */
|
||||
nr_reqs = i;
|
||||
|
||||
gettimeofday(&t1, NULL);
|
||||
cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
|
||||
gettimeofday(&t2, NULL);
|
||||
@ -1014,7 +1027,9 @@ static int multiwrite_f(int argc, char **argv)
|
||||
out:
|
||||
for (i = 0; i < nr_reqs; i++) {
|
||||
qemu_io_free(buf[i]);
|
||||
qemu_iovec_destroy(&qiovs[i]);
|
||||
if (reqs[i].qiov != NULL) {
|
||||
qemu_iovec_destroy(&qiovs[i]);
|
||||
}
|
||||
}
|
||||
g_free(buf);
|
||||
g_free(reqs);
|
||||
@ -1185,6 +1200,10 @@ static int aio_read_f(int argc, char **argv)
|
||||
|
||||
nr_iov = argc - optind;
|
||||
ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
|
||||
if (ctx->buf == NULL) {
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gettimeofday(&ctx->t1, NULL);
|
||||
acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
|
||||
@ -1280,6 +1299,10 @@ static int aio_write_f(int argc, char **argv)
|
||||
|
||||
nr_iov = argc - optind;
|
||||
ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
|
||||
if (ctx->buf == NULL) {
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gettimeofday(&ctx->t1, NULL);
|
||||
acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
|
||||
|
Loading…
Reference in New Issue
Block a user