Commit 33f002714be2ed58ed05ae3870d5ea6915df4b47

Authored by balrog
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
block-raw-posix.c
@@ -106,6 +106,10 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) @@ -106,6 +106,10 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
106 } 106 }
107 if (flags & BDRV_O_CREAT) 107 if (flags & BDRV_O_CREAT)
108 open_flags |= O_CREAT | O_TRUNC; 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 s->type = FTYPE_FILE; 114 s->type = FTYPE_FILE;
111 115
@@ -659,6 +663,10 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) @@ -659,6 +663,10 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
659 open_flags |= O_RDONLY; 663 open_flags |= O_RDONLY;
660 bs->read_only = 1; 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 s->type = FTYPE_FILE; 671 s->type = FTYPE_FILE;
664 #if defined(__linux__) 672 #if defined(__linux__)
block-raw-win32.c
@@ -105,6 +105,8 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) @@ -105,6 +105,8 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
105 #else 105 #else
106 overlapped = FILE_FLAG_OVERLAPPED; 106 overlapped = FILE_FLAG_OVERLAPPED;
107 #endif 107 #endif
  108 + if (flags & BDRV_O_DIRECT)
  109 + overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
108 s->hfile = CreateFile(filename, access_flags, 110 s->hfile = CreateFile(filename, access_flags,
109 FILE_SHARE_READ, NULL, 111 FILE_SHARE_READ, NULL,
110 create_flags, overlapped, NULL); 112 create_flags, overlapped, NULL);
@@ -473,6 +475,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) @@ -473,6 +475,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
473 #else 475 #else
474 overlapped = FILE_FLAG_OVERLAPPED; 476 overlapped = FILE_FLAG_OVERLAPPED;
475 #endif 477 #endif
  478 + if (flags & BDRV_O_DIRECT)
  479 + overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
476 s->hfile = CreateFile(filename, access_flags, 480 s->hfile = CreateFile(filename, access_flags,
477 FILE_SHARE_READ, NULL, 481 FILE_SHARE_READ, NULL,
478 create_flags, overlapped, NULL); 482 create_flags, overlapped, NULL);
@@ -380,7 +380,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, @@ -380,7 +380,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
380 /* Note: for compatibility, we open disk image files as RDWR, and 380 /* Note: for compatibility, we open disk image files as RDWR, and
381 RDONLY as fallback */ 381 RDONLY as fallback */
382 if (!(flags & BDRV_O_FILE)) 382 if (!(flags & BDRV_O_FILE))
383 - open_flags = BDRV_O_RDWR; 383 + open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
384 else 384 else
385 open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); 385 open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
386 ret = drv->bdrv_open(bs, filename, open_flags); 386 ret = drv->bdrv_open(bs, filename, open_flags);
@@ -44,6 +44,7 @@ typedef struct QEMUSnapshotInfo { @@ -44,6 +44,7 @@ typedef struct QEMUSnapshotInfo {
44 use a disk image format on top of 44 use a disk image format on top of
45 it (default for 45 it (default for
46 bdrv_file_open()) */ 46 bdrv_file_open()) */
  47 +#define BDRV_O_DIRECT 0x0020
47 48
48 #ifndef QEMU_IMG 49 #ifndef QEMU_IMG
49 void bdrv_info(void); 50 void bdrv_info(void);
hw/fdc.c
@@ -382,7 +382,7 @@ struct fdctrl_t { @@ -382,7 +382,7 @@ struct fdctrl_t {
382 uint8_t cur_drv; 382 uint8_t cur_drv;
383 uint8_t bootsel; 383 uint8_t bootsel;
384 /* Command FIFO */ 384 /* Command FIFO */
385 - uint8_t fifo[FD_SECTOR_LEN]; 385 + uint8_t *fifo;
386 uint32_t data_pos; 386 uint32_t data_pos;
387 uint32_t data_len; 387 uint32_t data_len;
388 uint8_t data_state; 388 uint8_t data_state;
@@ -598,6 +598,11 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped, @@ -598,6 +598,11 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
598 fdctrl = qemu_mallocz(sizeof(fdctrl_t)); 598 fdctrl = qemu_mallocz(sizeof(fdctrl_t));
599 if (!fdctrl) 599 if (!fdctrl)
600 return NULL; 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 fdctrl->result_timer = qemu_new_timer(vm_clock, 606 fdctrl->result_timer = qemu_new_timer(vm_clock,
602 fdctrl_result_timer, fdctrl); 607 fdctrl_result_timer, fdctrl);
603 608
hw/ide.c
@@ -365,7 +365,7 @@ typedef struct IDEState { @@ -365,7 +365,7 @@ typedef struct IDEState {
365 EndTransferFunc *end_transfer_func; 365 EndTransferFunc *end_transfer_func;
366 uint8_t *data_ptr; 366 uint8_t *data_ptr;
367 uint8_t *data_end; 367 uint8_t *data_end;
368 - uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; 368 + uint8_t *io_buffer;
369 QEMUTimer *sector_write_timer; /* only used for win2k install hack */ 369 QEMUTimer *sector_write_timer; /* only used for win2k install hack */
370 uint32_t irq_count; /* counts IRQs when using win2k install hack */ 370 uint32_t irq_count; /* counts IRQs when using win2k install hack */
371 /* CF-ATA extended error */ 371 /* CF-ATA extended error */
@@ -2377,17 +2377,24 @@ struct partition { @@ -2377,17 +2377,24 @@ struct partition {
2377 static int guess_disk_lchs(IDEState *s, 2377 static int guess_disk_lchs(IDEState *s,
2378 int *pcylinders, int *pheads, int *psectors) 2378 int *pcylinders, int *pheads, int *psectors)
2379 { 2379 {
2380 - uint8_t buf[512]; 2380 + uint8_t *buf;
2381 int ret, i, heads, sectors, cylinders; 2381 int ret, i, heads, sectors, cylinders;
2382 struct partition *p; 2382 struct partition *p;
2383 uint32_t nr_sects; 2383 uint32_t nr_sects;
2384 2384
  2385 + buf = qemu_memalign(512, 512);
  2386 + if (buf == NULL)
  2387 + return -1;
2385 ret = bdrv_read(s->bs, 0, buf, 1); 2388 ret = bdrv_read(s->bs, 0, buf, 1);
2386 - if (ret < 0) 2389 + if (ret < 0) {
  2390 + qemu_free(buf);
2387 return -1; 2391 return -1;
  2392 + }
2388 /* test msdos magic */ 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 return -1; 2396 return -1;
  2397 + }
2391 for(i = 0; i < 4; i++) { 2398 for(i = 0; i < 4; i++) {
2392 p = ((struct partition *)(buf + 0x1be)) + i; 2399 p = ((struct partition *)(buf + 0x1be)) + i;
2393 nr_sects = le32_to_cpu(p->nr_sects); 2400 nr_sects = le32_to_cpu(p->nr_sects);
@@ -2408,9 +2415,11 @@ static int guess_disk_lchs(IDEState *s, @@ -2408,9 +2415,11 @@ static int guess_disk_lchs(IDEState *s,
2408 printf("guessed geometry: LCHS=%d %d %d\n", 2415 printf("guessed geometry: LCHS=%d %d %d\n",
2409 cylinders, heads, sectors); 2416 cylinders, heads, sectors);
2410 #endif 2417 #endif
  2418 + qemu_free(buf);
2411 return 0; 2419 return 0;
2412 } 2420 }
2413 } 2421 }
  2422 + qemu_free(buf);
2414 return -1; 2423 return -1;
2415 } 2424 }
2416 2425
@@ -2425,6 +2434,7 @@ static void ide_init2(IDEState *ide_state, @@ -2425,6 +2434,7 @@ static void ide_init2(IDEState *ide_state,
2425 2434
2426 for(i = 0; i < 2; i++) { 2435 for(i = 0; i < 2; i++) {
2427 s = ide_state + i; 2436 s = ide_state + i;
  2437 + s->io_buffer = qemu_memalign(512, MAX_MULT_SECTORS*512 + 4);
2428 if (i == 0) 2438 if (i == 0)
2429 s->bs = hd0; 2439 s->bs = hd0;
2430 else 2440 else
hw/scsi-disk.c
@@ -46,7 +46,7 @@ typedef struct SCSIRequest { @@ -46,7 +46,7 @@ typedef struct SCSIRequest {
46 int sector_count; 46 int sector_count;
47 /* The amounnt of data in the buffer. */ 47 /* The amounnt of data in the buffer. */
48 int buf_len; 48 int buf_len;
49 - uint8_t dma_buf[SCSI_DMA_BUF_SIZE]; 49 + uint8_t *dma_buf;
50 BlockDriverAIOCB *aiocb; 50 BlockDriverAIOCB *aiocb;
51 struct SCSIRequest *next; 51 struct SCSIRequest *next;
52 } SCSIRequest; 52 } SCSIRequest;
@@ -78,6 +78,7 @@ static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag) @@ -78,6 +78,7 @@ static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
78 free_requests = r->next; 78 free_requests = r->next;
79 } else { 79 } else {
80 r = qemu_malloc(sizeof(SCSIRequest)); 80 r = qemu_malloc(sizeof(SCSIRequest));
  81 + r->dma_buf = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
81 } 82 }
82 r->dev = s; 83 r->dev = s;
83 r->tag = tag; 84 r->tag = tag;
@@ -96,6 +96,7 @@ struct SDState { @@ -96,6 +96,7 @@ struct SDState {
96 qemu_irq readonly_cb; 96 qemu_irq readonly_cb;
97 qemu_irq inserted_cb; 97 qemu_irq inserted_cb;
98 BlockDriverState *bdrv; 98 BlockDriverState *bdrv;
  99 + uint8_t *buf;
99 }; 100 };
100 101
101 static void sd_set_status(SDState *sd) 102 static void sd_set_status(SDState *sd)
@@ -405,6 +406,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi) @@ -405,6 +406,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi)
405 SDState *sd; 406 SDState *sd;
406 407
407 sd = (SDState *) qemu_mallocz(sizeof(SDState)); 408 sd = (SDState *) qemu_mallocz(sizeof(SDState));
  409 + sd->buf = qemu_memalign(512, 512);
408 sd->spi = is_spi; 410 sd->spi = is_spi;
409 sd_reset(sd, bs); 411 sd_reset(sd, bs);
410 bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd); 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,64 +1283,60 @@ int sd_do_command(SDState *sd, struct sd_request_s *req,
1281 } 1283 }
1282 1284
1283 /* No real need for 64 bit addresses here */ 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 uint32_t end = addr + len; 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 printf("sd_blk_read: read error on host side\n"); 1291 printf("sd_blk_read: read error on host side\n");
1292 return; 1292 return;
1293 } 1293 }
1294 1294
1295 if (end > (addr & ~511) + 512) { 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 printf("sd_blk_read: read error on host side\n"); 1299 printf("sd_blk_read: read error on host side\n");
1300 return; 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 } else 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 uint32_t end = addr + len; 1309 uint32_t end = addr + len;
1312 1310
1313 if ((addr & 511) || len < 512) 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 printf("sd_blk_write: read error on host side\n"); 1313 printf("sd_blk_write: read error on host side\n");
1316 return; 1314 return;
1317 } 1315 }
1318 1316
1319 if (end > (addr & ~511) + 512) { 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 printf("sd_blk_write: write error on host side\n"); 1320 printf("sd_blk_write: write error on host side\n");
1323 return; 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 printf("sd_blk_write: read error on host side\n"); 1325 printf("sd_blk_write: read error on host side\n");
1328 return; 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 printf("sd_blk_write: write error on host side\n"); 1330 printf("sd_blk_write: write error on host side\n");
1333 } else { 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 printf("sd_blk_write: write error on host side\n"); 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 #define APP_READ_BLOCK(a, len) memset(sd->data, 0xec, len) 1340 #define APP_READ_BLOCK(a, len) memset(sd->data, 0xec, len)
1343 #define APP_WRITE_BLOCK(a, len) 1341 #define APP_WRITE_BLOCK(a, len)
1344 1342
@@ -61,6 +61,10 @@ void *qemu_malloc(size_t size) @@ -61,6 +61,10 @@ void *qemu_malloc(size_t size)
61 } 61 }
62 62
63 #if defined(_WIN32) 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 void *qemu_vmalloc(size_t size) 69 void *qemu_vmalloc(size_t size)
66 { 70 {
@@ -172,6 +176,22 @@ static void kqemu_vfree(void *ptr) @@ -172,6 +176,22 @@ static void kqemu_vfree(void *ptr)
172 176
173 #endif 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 /* alloc shared memory pages */ 195 /* alloc shared memory pages */
176 void *qemu_vmalloc(size_t size) 196 void *qemu_vmalloc(size_t size)
177 { 197 {
@@ -48,6 +48,7 @@ void *qemu_mallocz(size_t size); @@ -48,6 +48,7 @@ void *qemu_mallocz(size_t size);
48 void qemu_free(void *ptr); 48 void qemu_free(void *ptr);
49 char *qemu_strdup(const char *str); 49 char *qemu_strdup(const char *str);
50 50
  51 +void *qemu_memalign(size_t alignment, size_t size);
51 void *qemu_vmalloc(size_t size); 52 void *qemu_vmalloc(size_t size);
52 void qemu_vfree(void *ptr); 53 void qemu_vfree(void *ptr);
53 54
qemu-doc.texi
@@ -250,6 +250,8 @@ This option defines the type of the media: disk or cdrom. @@ -250,6 +250,8 @@ This option defines the type of the media: disk or cdrom.
250 These options have the same definition as they have in @option{-hdachs}. 250 These options have the same definition as they have in @option{-hdachs}.
251 @item snapshot=@var{snapshot} 251 @item snapshot=@var{snapshot}
252 @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}). 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 @end table 255 @end table
254 256
255 Instead of @option{-cdrom} you can use: 257 Instead of @option{-cdrom} you can use:
@@ -4880,8 +4880,11 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) @@ -4880,8 +4880,11 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
4880 BlockDriverState *bdrv; 4880 BlockDriverState *bdrv;
4881 int max_devs; 4881 int max_devs;
4882 int index; 4882 int index;
  4883 + int cache;
  4884 + int bdrv_flags;
4883 char *params[] = { "bus", "unit", "if", "index", "cyls", "heads", 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 if (check_params(buf, sizeof(buf), params, str) < 0) { 4889 if (check_params(buf, sizeof(buf), params, str) < 0) {
4887 fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n", 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,6 +4898,7 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
4895 unit_id = -1; 4898 unit_id = -1;
4896 translation = BIOS_ATA_TRANSLATION_AUTO; 4899 translation = BIOS_ATA_TRANSLATION_AUTO;
4897 index = -1; 4900 index = -1;
  4901 + cache = 1;
4898 4902
4899 if (!strcmp(machine->name, "realview") || 4903 if (!strcmp(machine->name, "realview") ||
4900 !strcmp(machine->name, "SS-5") || 4904 !strcmp(machine->name, "SS-5") ||
@@ -5037,6 +5041,17 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) @@ -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 get_param_value(file, sizeof(file), "file", str); 5055 get_param_value(file, sizeof(file), "file", str);
5041 5056
5042 /* compute bus and unit according index */ 5057 /* compute bus and unit according index */
@@ -5131,8 +5146,12 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine) @@ -5131,8 +5146,12 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
5131 } 5146 }
5132 if (!file[0]) 5147 if (!file[0])
5133 return 0; 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 fprintf(stderr, "qemu: could not open disk image %s\n", 5155 fprintf(stderr, "qemu: could not open disk image %s\n",
5137 file); 5156 file);
5138 return -1; 5157 return -1;
@@ -7480,7 +7499,8 @@ static void help(int exitcode) @@ -7480,7 +7499,8 @@ static void help(int exitcode)
7480 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" 7499 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
7481 "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n" 7500 "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
7482 "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n" 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 " use 'file' as a drive image\n" 7504 " use 'file' as a drive image\n"
7485 "-mtdblock file use 'file' as on-board Flash memory image\n" 7505 "-mtdblock file use 'file' as on-board Flash memory image\n"
7486 "-sd file use 'file' as SecureDigital card image\n" 7506 "-sd file use 'file' as SecureDigital card image\n"