Commit 33f002714be2ed58ed05ae3870d5ea6915df4b47
1 parent
3e98dc8e
Add "cache" parameter to "-drive" (Laurent Vivier).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3848 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
12 changed files
with
102 additions
and
32 deletions
block-raw-posix.c
| ... | ... | @@ -106,6 +106,10 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) |
| 106 | 106 | } |
| 107 | 107 | if (flags & BDRV_O_CREAT) |
| 108 | 108 | open_flags |= O_CREAT | O_TRUNC; |
| 109 | +#ifdef O_DIRECT | |
| 110 | + if (flags & BDRV_O_DIRECT) | |
| 111 | + open_flags |= O_DIRECT; | |
| 112 | +#endif | |
| 109 | 113 | |
| 110 | 114 | s->type = FTYPE_FILE; |
| 111 | 115 | |
| ... | ... | @@ -659,6 +663,10 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) |
| 659 | 663 | open_flags |= O_RDONLY; |
| 660 | 664 | bs->read_only = 1; |
| 661 | 665 | } |
| 666 | +#ifdef O_DIRECT | |
| 667 | + if (flags & BDRV_O_DIRECT) | |
| 668 | + open_flags |= O_DIRECT; | |
| 669 | +#endif | |
| 662 | 670 | |
| 663 | 671 | s->type = FTYPE_FILE; |
| 664 | 672 | #if defined(__linux__) | ... | ... |
block-raw-win32.c
| ... | ... | @@ -105,6 +105,8 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) |
| 105 | 105 | #else |
| 106 | 106 | overlapped = FILE_FLAG_OVERLAPPED; |
| 107 | 107 | #endif |
| 108 | + if (flags & BDRV_O_DIRECT) | |
| 109 | + overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; | |
| 108 | 110 | s->hfile = CreateFile(filename, access_flags, |
| 109 | 111 | FILE_SHARE_READ, NULL, |
| 110 | 112 | create_flags, overlapped, NULL); |
| ... | ... | @@ -473,6 +475,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) |
| 473 | 475 | #else |
| 474 | 476 | overlapped = FILE_FLAG_OVERLAPPED; |
| 475 | 477 | #endif |
| 478 | + if (flags & BDRV_O_DIRECT) | |
| 479 | + overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; | |
| 476 | 480 | s->hfile = CreateFile(filename, access_flags, |
| 477 | 481 | FILE_SHARE_READ, NULL, |
| 478 | 482 | create_flags, overlapped, NULL); | ... | ... |
block.c
| ... | ... | @@ -380,7 +380,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, |
| 380 | 380 | /* Note: for compatibility, we open disk image files as RDWR, and |
| 381 | 381 | RDONLY as fallback */ |
| 382 | 382 | if (!(flags & BDRV_O_FILE)) |
| 383 | - open_flags = BDRV_O_RDWR; | |
| 383 | + open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT); | |
| 384 | 384 | else |
| 385 | 385 | open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); |
| 386 | 386 | ret = drv->bdrv_open(bs, filename, open_flags); | ... | ... |
block.h
hw/fdc.c
| ... | ... | @@ -382,7 +382,7 @@ struct fdctrl_t { |
| 382 | 382 | uint8_t cur_drv; |
| 383 | 383 | uint8_t bootsel; |
| 384 | 384 | /* Command FIFO */ |
| 385 | - uint8_t fifo[FD_SECTOR_LEN]; | |
| 385 | + uint8_t *fifo; | |
| 386 | 386 | uint32_t data_pos; |
| 387 | 387 | uint32_t data_len; |
| 388 | 388 | uint8_t data_state; |
| ... | ... | @@ -598,6 +598,11 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped, |
| 598 | 598 | fdctrl = qemu_mallocz(sizeof(fdctrl_t)); |
| 599 | 599 | if (!fdctrl) |
| 600 | 600 | return NULL; |
| 601 | + fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); | |
| 602 | + if (fdctrl->fifo == NULL) { | |
| 603 | + qemu_free(fdctrl); | |
| 604 | + return NULL; | |
| 605 | + } | |
| 601 | 606 | fdctrl->result_timer = qemu_new_timer(vm_clock, |
| 602 | 607 | fdctrl_result_timer, fdctrl); |
| 603 | 608 | ... | ... |
hw/ide.c
| ... | ... | @@ -365,7 +365,7 @@ typedef struct IDEState { |
| 365 | 365 | EndTransferFunc *end_transfer_func; |
| 366 | 366 | uint8_t *data_ptr; |
| 367 | 367 | uint8_t *data_end; |
| 368 | - uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; | |
| 368 | + uint8_t *io_buffer; | |
| 369 | 369 | QEMUTimer *sector_write_timer; /* only used for win2k install hack */ |
| 370 | 370 | uint32_t irq_count; /* counts IRQs when using win2k install hack */ |
| 371 | 371 | /* CF-ATA extended error */ |
| ... | ... | @@ -2377,17 +2377,24 @@ struct partition { |
| 2377 | 2377 | static int guess_disk_lchs(IDEState *s, |
| 2378 | 2378 | int *pcylinders, int *pheads, int *psectors) |
| 2379 | 2379 | { |
| 2380 | - uint8_t buf[512]; | |
| 2380 | + uint8_t *buf; | |
| 2381 | 2381 | int ret, i, heads, sectors, cylinders; |
| 2382 | 2382 | struct partition *p; |
| 2383 | 2383 | uint32_t nr_sects; |
| 2384 | 2384 | |
| 2385 | + buf = qemu_memalign(512, 512); | |
| 2386 | + if (buf == NULL) | |
| 2387 | + return -1; | |
| 2385 | 2388 | ret = bdrv_read(s->bs, 0, buf, 1); |
| 2386 | - if (ret < 0) | |
| 2389 | + if (ret < 0) { | |
| 2390 | + qemu_free(buf); | |
| 2387 | 2391 | return -1; |
| 2392 | + } | |
| 2388 | 2393 | /* test msdos magic */ |
| 2389 | - if (buf[510] != 0x55 || buf[511] != 0xaa) | |
| 2394 | + if (buf[510] != 0x55 || buf[511] != 0xaa) { | |
| 2395 | + qemu_free(buf); | |
| 2390 | 2396 | return -1; |
| 2397 | + } | |
| 2391 | 2398 | for(i = 0; i < 4; i++) { |
| 2392 | 2399 | p = ((struct partition *)(buf + 0x1be)) + i; |
| 2393 | 2400 | nr_sects = le32_to_cpu(p->nr_sects); |
| ... | ... | @@ -2408,9 +2415,11 @@ static int guess_disk_lchs(IDEState *s, |
| 2408 | 2415 | printf("guessed geometry: LCHS=%d %d %d\n", |
| 2409 | 2416 | cylinders, heads, sectors); |
| 2410 | 2417 | #endif |
| 2418 | + qemu_free(buf); | |
| 2411 | 2419 | return 0; |
| 2412 | 2420 | } |
| 2413 | 2421 | } |
| 2422 | + qemu_free(buf); | |
| 2414 | 2423 | return -1; |
| 2415 | 2424 | } |
| 2416 | 2425 | |
| ... | ... | @@ -2425,6 +2434,7 @@ static void ide_init2(IDEState *ide_state, |
| 2425 | 2434 | |
| 2426 | 2435 | for(i = 0; i < 2; i++) { |
| 2427 | 2436 | s = ide_state + i; |
| 2437 | + s->io_buffer = qemu_memalign(512, MAX_MULT_SECTORS*512 + 4); | |
| 2428 | 2438 | if (i == 0) |
| 2429 | 2439 | s->bs = hd0; |
| 2430 | 2440 | else | ... | ... |
hw/scsi-disk.c
| ... | ... | @@ -46,7 +46,7 @@ typedef struct SCSIRequest { |
| 46 | 46 | int sector_count; |
| 47 | 47 | /* The amounnt of data in the buffer. */ |
| 48 | 48 | int buf_len; |
| 49 | - uint8_t dma_buf[SCSI_DMA_BUF_SIZE]; | |
| 49 | + uint8_t *dma_buf; | |
| 50 | 50 | BlockDriverAIOCB *aiocb; |
| 51 | 51 | struct SCSIRequest *next; |
| 52 | 52 | } SCSIRequest; |
| ... | ... | @@ -78,6 +78,7 @@ static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag) |
| 78 | 78 | free_requests = r->next; |
| 79 | 79 | } else { |
| 80 | 80 | r = qemu_malloc(sizeof(SCSIRequest)); |
| 81 | + r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE); | |
| 81 | 82 | } |
| 82 | 83 | r->dev = s; |
| 83 | 84 | r->tag = tag; | ... | ... |
hw/sd.c
| ... | ... | @@ -96,6 +96,7 @@ struct SDState { |
| 96 | 96 | qemu_irq readonly_cb; |
| 97 | 97 | qemu_irq inserted_cb; |
| 98 | 98 | BlockDriverState *bdrv; |
| 99 | + uint8_t *buf; | |
| 99 | 100 | }; |
| 100 | 101 | |
| 101 | 102 | static void sd_set_status(SDState *sd) |
| ... | ... | @@ -405,6 +406,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi) |
| 405 | 406 | SDState *sd; |
| 406 | 407 | |
| 407 | 408 | sd = (SDState *) qemu_mallocz(sizeof(SDState)); |
| 409 | + sd->buf = qemu_memalign(512, 512); | |
| 408 | 410 | sd->spi = is_spi; |
| 409 | 411 | sd_reset(sd, bs); |
| 410 | 412 | bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd); |
| ... | ... | @@ -1281,64 +1283,60 @@ int sd_do_command(SDState *sd, struct sd_request_s *req, |
| 1281 | 1283 | } |
| 1282 | 1284 | |
| 1283 | 1285 | /* No real need for 64 bit addresses here */ |
| 1284 | -static void sd_blk_read(BlockDriverState *bdrv, | |
| 1285 | - void *data, uint32_t addr, uint32_t len) | |
| 1286 | +static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len) | |
| 1286 | 1287 | { |
| 1287 | - uint8_t buf[512]; | |
| 1288 | 1288 | uint32_t end = addr + len; |
| 1289 | 1289 | |
| 1290 | - if (!bdrv || bdrv_read(bdrv, addr >> 9, buf, 1) == -1) { | |
| 1290 | + if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { | |
| 1291 | 1291 | printf("sd_blk_read: read error on host side\n"); |
| 1292 | 1292 | return; |
| 1293 | 1293 | } |
| 1294 | 1294 | |
| 1295 | 1295 | if (end > (addr & ~511) + 512) { |
| 1296 | - memcpy(data, buf + (addr & 511), 512 - (addr & 511)); | |
| 1296 | + memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511)); | |
| 1297 | 1297 | |
| 1298 | - if (bdrv_read(bdrv, end >> 9, buf, 1) == -1) { | |
| 1298 | + if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) { | |
| 1299 | 1299 | printf("sd_blk_read: read error on host side\n"); |
| 1300 | 1300 | return; |
| 1301 | 1301 | } |
| 1302 | - memcpy(data + 512 - (addr & 511), buf, end & 511); | |
| 1302 | + memcpy(sd->data + 512 - (addr & 511), sd->buf, end & 511); | |
| 1303 | 1303 | } else |
| 1304 | - memcpy(data, buf + (addr & 511), len); | |
| 1304 | + memcpy(sd->data, sd->buf + (addr & 511), len); | |
| 1305 | 1305 | } |
| 1306 | 1306 | |
| 1307 | -static void sd_blk_write(BlockDriverState *bdrv, | |
| 1308 | - void *data, uint32_t addr, uint32_t len) | |
| 1307 | +static void sd_blk_write(SDState *sd, uint32_t addr, uint32_t len) | |
| 1309 | 1308 | { |
| 1310 | - uint8_t buf[512]; | |
| 1311 | 1309 | uint32_t end = addr + len; |
| 1312 | 1310 | |
| 1313 | 1311 | if ((addr & 511) || len < 512) |
| 1314 | - if (!bdrv || bdrv_read(bdrv, addr >> 9, buf, 1) == -1) { | |
| 1312 | + if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { | |
| 1315 | 1313 | printf("sd_blk_write: read error on host side\n"); |
| 1316 | 1314 | return; |
| 1317 | 1315 | } |
| 1318 | 1316 | |
| 1319 | 1317 | if (end > (addr & ~511) + 512) { |
| 1320 | - memcpy(buf + (addr & 511), data, 512 - (addr & 511)); | |
| 1321 | - if (bdrv_write(bdrv, addr >> 9, buf, 1) == -1) { | |
| 1318 | + memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511)); | |
| 1319 | + if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { | |
| 1322 | 1320 | printf("sd_blk_write: write error on host side\n"); |
| 1323 | 1321 | return; |
| 1324 | 1322 | } |
| 1325 | 1323 | |
| 1326 | - if (bdrv_read(bdrv, end >> 9, buf, 1) == -1) { | |
| 1324 | + if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) { | |
| 1327 | 1325 | printf("sd_blk_write: read error on host side\n"); |
| 1328 | 1326 | return; |
| 1329 | 1327 | } |
| 1330 | - memcpy(buf, data + 512 - (addr & 511), end & 511); | |
| 1331 | - if (bdrv_write(bdrv, end >> 9, buf, 1) == -1) | |
| 1328 | + memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511); | |
| 1329 | + if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1) | |
| 1332 | 1330 | printf("sd_blk_write: write error on host side\n"); |
| 1333 | 1331 | } else { |
| 1334 | - memcpy(buf + (addr & 511), data, len); | |
| 1335 | - if (!bdrv || bdrv_write(bdrv, addr >> 9, buf, 1) == -1) | |
| 1332 | + memcpy(sd->buf + (addr & 511), sd->data, len); | |
| 1333 | + if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) | |
| 1336 | 1334 | printf("sd_blk_write: write error on host side\n"); |
| 1337 | 1335 | } |
| 1338 | 1336 | } |
| 1339 | 1337 | |
| 1340 | -#define BLK_READ_BLOCK(a, len) sd_blk_read(sd->bdrv, sd->data, a, len) | |
| 1341 | -#define BLK_WRITE_BLOCK(a, len) sd_blk_write(sd->bdrv, sd->data, a, len) | |
| 1338 | +#define BLK_READ_BLOCK(a, len) sd_blk_read(sd, a, len) | |
| 1339 | +#define BLK_WRITE_BLOCK(a, len) sd_blk_write(sd, a, len) | |
| 1342 | 1340 | #define APP_READ_BLOCK(a, len) memset(sd->data, 0xec, len) |
| 1343 | 1341 | #define APP_WRITE_BLOCK(a, len) |
| 1344 | 1342 | ... | ... |
osdep.c
| ... | ... | @@ -61,6 +61,10 @@ void *qemu_malloc(size_t size) |
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | #if defined(_WIN32) |
| 64 | +void *qemu_memalign(size_t alignment, size_t size) | |
| 65 | +{ | |
| 66 | + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); | |
| 67 | +} | |
| 64 | 68 | |
| 65 | 69 | void *qemu_vmalloc(size_t size) |
| 66 | 70 | { |
| ... | ... | @@ -172,6 +176,22 @@ static void kqemu_vfree(void *ptr) |
| 172 | 176 | |
| 173 | 177 | #endif |
| 174 | 178 | |
| 179 | +void *qemu_memalign(size_t alignment, size_t size) | |
| 180 | +{ | |
| 181 | +#if defined(_POSIX_C_SOURCE) | |
| 182 | + int ret; | |
| 183 | + void *ptr; | |
| 184 | + ret = posix_memalign(&ptr, alignment, size); | |
| 185 | + if (ret != 0) | |
| 186 | + return NULL; | |
| 187 | + return ptr; | |
| 188 | +#elif defined(_BSD) | |
| 189 | + return valloc(size); | |
| 190 | +#else | |
| 191 | + return memalign(alignment, size); | |
| 192 | +#endif | |
| 193 | +} | |
| 194 | + | |
| 175 | 195 | /* alloc shared memory pages */ |
| 176 | 196 | void *qemu_vmalloc(size_t size) |
| 177 | 197 | { | ... | ... |
osdep.h
qemu-doc.texi
| ... | ... | @@ -250,6 +250,8 @@ This option defines the type of the media: disk or cdrom. |
| 250 | 250 | These options have the same definition as they have in @option{-hdachs}. |
| 251 | 251 | @item snapshot=@var{snapshot} |
| 252 | 252 | @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}). |
| 253 | +@item cache=@var{cache} | |
| 254 | +@var{cache} is "on" or "off" and allows to disable host cache to access data. | |
| 253 | 255 | @end table |
| 254 | 256 | |
| 255 | 257 | Instead of @option{-cdrom} you can use: | ... | ... |
vl.c
| ... | ... | @@ -4880,8 +4880,11 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) |
| 4880 | 4880 | BlockDriverState *bdrv; |
| 4881 | 4881 | int max_devs; |
| 4882 | 4882 | int index; |
| 4883 | + int cache; | |
| 4884 | + int bdrv_flags; | |
| 4883 | 4885 | char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", |
| 4884 | - "secs", "trans", "media", "snapshot", "file", NULL }; | |
| 4886 | + "secs", "trans", "media", "snapshot", "file", | |
| 4887 | + "cache", NULL }; | |
| 4885 | 4888 | |
| 4886 | 4889 | if (check_params(buf, sizeof(buf), params, str) < 0) { |
| 4887 | 4890 | fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n", |
| ... | ... | @@ -4895,6 +4898,7 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) |
| 4895 | 4898 | unit_id = -1; |
| 4896 | 4899 | translation = BIOS_ATA_TRANSLATION_AUTO; |
| 4897 | 4900 | index = -1; |
| 4901 | + cache = 1; | |
| 4898 | 4902 | |
| 4899 | 4903 | if (!strcmp(machine->name, "realview") || |
| 4900 | 4904 | !strcmp(machine->name, "SS-5") || |
| ... | ... | @@ -5037,6 +5041,17 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) |
| 5037 | 5041 | } |
| 5038 | 5042 | } |
| 5039 | 5043 | |
| 5044 | + if (get_param_value(buf, sizeof(buf), "cache", str)) { | |
| 5045 | + if (!strcmp(buf, "off")) | |
| 5046 | + cache = 0; | |
| 5047 | + else if (!strcmp(buf, "on")) | |
| 5048 | + cache = 1; | |
| 5049 | + else { | |
| 5050 | + fprintf(stderr, "qemu: invalid cache option\n"); | |
| 5051 | + return -1; | |
| 5052 | + } | |
| 5053 | + } | |
| 5054 | + | |
| 5040 | 5055 | get_param_value(file, sizeof(file), "file", str); |
| 5041 | 5056 | |
| 5042 | 5057 | /* compute bus and unit according index */ |
| ... | ... | @@ -5131,8 +5146,12 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) |
| 5131 | 5146 | } |
| 5132 | 5147 | if (!file[0]) |
| 5133 | 5148 | return 0; |
| 5134 | - if (bdrv_open(bdrv, file, snapshot ? BDRV_O_SNAPSHOT : 0) < 0 || | |
| 5135 | - qemu_key_check(bdrv, file)) { | |
| 5149 | + bdrv_flags = 0; | |
| 5150 | + if (snapshot) | |
| 5151 | + bdrv_flags |= BDRV_O_SNAPSHOT; | |
| 5152 | + if (!cache) | |
| 5153 | + bdrv_flags |= BDRV_O_DIRECT; | |
| 5154 | + if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file)) { | |
| 5136 | 5155 | fprintf(stderr, "qemu: could not open disk image %s\n", |
| 5137 | 5156 | file); |
| 5138 | 5157 | return -1; |
| ... | ... | @@ -7480,7 +7499,8 @@ static void help(int exitcode) |
| 7480 | 7499 | "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" |
| 7481 | 7500 | "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n" |
| 7482 | 7501 | "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n" |
| 7483 | - " [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]\n" | |
| 7502 | + " [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]" | |
| 7503 | + " [,cache=on|off]\n" | |
| 7484 | 7504 | " use 'file' as a drive image\n" |
| 7485 | 7505 | "-mtdblock file use 'file' as on-board Flash memory image\n" |
| 7486 | 7506 | "-sd file use 'file' as SecureDigital card image\n" | ... | ... |