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" | ... | ... |