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 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);
... ...
... ... @@ -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);
... ...
... ... @@ -44,6 +44,7 @@ typedef struct QEMUSnapshotInfo {
44 44 use a disk image format on top of
45 45 it (default for
46 46 bdrv_file_open()) */
  47 +#define BDRV_O_DIRECT 0x0020
47 48  
48 49 #ifndef QEMU_IMG
49 50 void bdrv_info(void);
... ...
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;
... ...
... ... @@ -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  
... ...
... ... @@ -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 {
... ...
... ... @@ -48,6 +48,7 @@ void *qemu_mallocz(size_t size);
48 48 void qemu_free(void *ptr);
49 49 char *qemu_strdup(const char *str);
50 50  
  51 +void *qemu_memalign(size_t alignment, size_t size);
51 52 void *qemu_vmalloc(size_t size);
52 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 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:
... ...
... ... @@ -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"
... ...