1: /*
2: * QEMU System Emulator block driver
3: *
4: * Copyright (c) 2003 Fabrice Bellard
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy
7: * of this software and associated documentation files (the "Software"), to deal
8: * in the Software without restriction, including without limitation the rights
9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10: * copies of the Software, and to permit persons to whom the Software is
11: * furnished to do so, subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in
14: * all copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22: * THE SOFTWARE.
23: */
24: #include "config-host.h"
25: #ifdef _BSD
26: /* include native header before sys-queue.h */
27: #include <sys/queue.h>
28: #endif
29:
30: #include "qemu-common.h"
31: #include "console.h"
32: #include "block_int.h"
33:
34: #ifdef _BSD
35: #include <sys/types.h>
36: #include <sys/stat.h>
37: #include <sys/ioctl.h>
38: #include <sys/disk.h>
39: #endif
40:
41: #define SECTOR_BITS 9
42: #define SECTOR_SIZE (1 << SECTOR_BITS)
43:
44: static AIOPool vectored_aio_pool;
45:
46: typedef struct BlockDriverAIOCBSync {
47: BlockDriverAIOCB common;
48: QEMUBH *bh;
49: int ret;
50: } BlockDriverAIOCBSync;
51:
52: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
53: int64_t sector_num, uint8_t *buf, int nb_sectors,
54: BlockDriverCompletionFunc *cb, void *opaque);
55: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
56: int64_t sector_num, const uint8_t *buf, int nb_sectors,
57: BlockDriverCompletionFunc *cb, void *opaque);
58: static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
59: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
60: uint8_t *buf, int nb_sectors);
61: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
62: const uint8_t *buf, int nb_sectors);
63:
64: BlockDriverState *bdrv_first;
65:
66: static BlockDriver *first_drv;
67:
68: int path_is_absolute(const char *path)
69: {
70: const char *p;
71: #ifdef _WIN32
72: /* specific case for names like: "\\.\d:" */
73: if (*path == '/' || *path == '\\')
74: return 1;
75: #endif
76: p = strchr(path, ':');
77: if (p)
78: p++;
79: else
80: p = path;
81: #ifdef _WIN32
82: return (*p == '/' || *p == '\\');
83: #else
84: return (*p == '/');
85: #endif
86: }
87:
88: /* if filename is absolute, just copy it to dest. Otherwise, build a
89: path to it by considering it is relative to base_path. URL are
90: supported. */
91: void path_combine(char *dest, int dest_size,
92: const char *base_path,
93: const char *filename)
94: {
95: const char *p, *p1;
96: int len;
97:
98: if (dest_size <= 0)
99: return;
100: if (path_is_absolute(filename)) {
101: pstrcpy(dest, dest_size, filename);
102: } else {
103: p = strchr(base_path, ':');
104: if (p)
105: p++;
106: else
107: p = base_path;
108: p1 = strrchr(base_path, '/');
109: #ifdef _WIN32
110: {
111: const char *p2;
112: p2 = strrchr(base_path, '\\');
113: if (!p1 || p2 > p1)
114: p1 = p2;
115: }
116: #endif
117: if (p1)
118: p1++;
119: else
120: p1 = base_path;
121: if (p1 > p)
122: p = p1;
123: len = p - base_path;
124: if (len > dest_size - 1)
125: len = dest_size - 1;
126: memcpy(dest, base_path, len);
127: dest[len] = '\0';
128: pstrcat(dest, dest_size, filename);
129: }
130: }
131:
132:
133: static void bdrv_register(BlockDriver *bdrv)
134: {
135: if (!bdrv->bdrv_aio_read) {
136: /* add AIO emulation layer */
137: bdrv->bdrv_aio_read = bdrv_aio_read_em;
138: bdrv->bdrv_aio_write = bdrv_aio_write_em;
139: bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
140: bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
141: } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
142: /* add synchronous IO emulation layer */
143: bdrv->bdrv_read = bdrv_read_em;
144: bdrv->bdrv_write = bdrv_write_em;
145: }
146: aio_pool_init(&bdrv->aio_pool, bdrv->aiocb_size, bdrv->bdrv_aio_cancel);
147: bdrv->next = first_drv;
148: first_drv = bdrv;
149: }
150:
151: /* create a new block device (by default it is empty) */
152: BlockDriverState *bdrv_new(const char *device_name)
153: {
154: BlockDriverState **pbs, *bs;
155:
156: bs = qemu_mallocz(sizeof(BlockDriverState));
157: pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
158: if (device_name[0] != '\0') {
159: /* insert at the end */
160: pbs = &bdrv_first;
161: while (*pbs != NULL)
162: pbs = &(*pbs)->next;
163: *pbs = bs;
164: }
165: return bs;
166: }
167:
168: BlockDriver *bdrv_find_format(const char *format_name)
169: {
170: BlockDriver *drv1;
171: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
172: if (!strcmp(drv1->format_name, format_name))
173: return drv1;
174: }
175: return NULL;
176: }
177:
178: int bdrv_create(BlockDriver *drv,
179: const char *filename, int64_t size_in_sectors,
180: const char *backing_file, int flags)
181: {
182: if (!drv->bdrv_create)
183: return -ENOTSUP;
184: return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
185: }
186:
187: #ifdef _WIN32
188: void get_tmp_filename(char *filename, int size)
189: {
190: char temp_dir[MAX_PATH];
191:
192: GetTempPath(MAX_PATH, temp_dir);
193: GetTempFileName(temp_dir, "qem", 0, filename);
194: }
195: #else
196: void get_tmp_filename(char *filename, int size)
197: {
198: int fd;
199: const char *tmpdir;
200: /* XXX: race condition possible */
201: tmpdir = getenv("TMPDIR");
202: if (!tmpdir)
203: tmpdir = "/tmp";
204: snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
205: fd = mkstemp(filename);
206: close(fd);
207: }
208: #endif
209:
210: #ifdef _WIN32
211: static int is_windows_drive_prefix(const char *filename)
212: {
213: return (((filename[0] >= 'a' && filename[0] <= 'z') ||
214: (filename[0] >= 'A' && filename[0] <= 'Z')) &&
215: filename[1] == ':');
216: }
217:
218: static int is_windows_drive(const char *filename)
219: {
220: if (is_windows_drive_prefix(filename) &&
221: filename[2] == '\0')
222: return 1;
223: if (strstart(filename, "\\\\.\\", NULL) ||
224: strstart(filename, "//./", NULL))
225: return 1;
226: return 0;
227: }
228: #endif
229:
230: static BlockDriver *find_protocol(const char *filename)
231: {
232: BlockDriver *drv1;
233: char protocol[128];
234: int len;
235: const char *p;
236:
237: #ifdef _WIN32
238: if (is_windows_drive(filename) ||
239: is_windows_drive_prefix(filename))
240: return &bdrv_raw;
241: #endif
242: p = strchr(filename, ':');
243: if (!p)
244: return &bdrv_raw;
245: len = p - filename;
246: if (len > sizeof(protocol) - 1)
247: len = sizeof(protocol) - 1;
248: memcpy(protocol, filename, len);
249: protocol[len] = '\0';
250: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
251: if (drv1->protocol_name &&
252: !strcmp(drv1->protocol_name, protocol))
253: return drv1;
254: }
255: return NULL;
256: }
257:
258: /* XXX: force raw format if block or character device ? It would
259: simplify the BSD case */
260: static BlockDriver *find_image_format(const char *filename)
261: {
262: int ret, score, score_max;
263: BlockDriver *drv1, *drv;
264: uint8_t buf[2048];
265: BlockDriverState *bs;
266:
267: /* detect host devices. By convention, /dev/cdrom[N] is always
268: recognized as a host CDROM */
269: if (strstart(filename, "/dev/cdrom", NULL))
270: return &bdrv_host_device;
271: #ifdef _WIN32
272: if (is_windows_drive(filename))
273: return &bdrv_host_device;
274: #else
275: {
276: struct stat st;
277: if (stat(filename, &st) >= 0 &&
278: (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
279: return &bdrv_host_device;
280: }
281: }
282: #endif
283:
284: drv = find_protocol(filename);
285: /* no need to test disk image formats for vvfat */
286: if (drv == &bdrv_vvfat)
287: return drv;
288:
289: ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
290: if (ret < 0)
291: return NULL;
292: ret = bdrv_pread(bs, 0, buf, sizeof(buf));
293: bdrv_delete(bs);
294: if (ret < 0) {
295: return NULL;
296: }
297:
298: score_max = 0;
299: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
300: if (drv1->bdrv_probe) {
301: score = drv1->bdrv_probe(buf, ret, filename);
302: if (score > score_max) {
303: score_max = score;
304: drv = drv1;
305: }
306: }
307: }
308: return drv;
309: }
310:
311: int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
312: {
313: BlockDriverState *bs;
314: int ret;
315:
316: bs = bdrv_new("");
317: ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
318: if (ret < 0) {
319: bdrv_delete(bs);
320: return ret;
321: }
322: bs->growable = 1;
323: *pbs = bs;
324: return 0;
325: }
326:
327: int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
328: {
329: return bdrv_open2(bs, filename, flags, NULL);
330: }
331:
332: int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
333: BlockDriver *drv)
334: {
335: int ret, open_flags;
336: char tmp_filename[PATH_MAX];
337: char backing_filename[PATH_MAX];
338:
339: bs->read_only = 0;
340: bs->is_temporary = 0;
341: bs->encrypted = 0;
342: bs->valid_key = 0;
343:
344: if (flags & BDRV_O_SNAPSHOT) {
345: BlockDriverState *bs1;
346: int64_t total_size;
347: int is_protocol = 0;
348:
349: /* if snapshot, we create a temporary backing file and open it
350: instead of opening 'filename' directly */
351:
352: /* if there is a backing file, use it */
353: bs1 = bdrv_new("");
354: ret = bdrv_open(bs1, filename, 0);
355: if (ret < 0) {
356: bdrv_delete(bs1);
357: return ret;
358: }
359: total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
360:
361: if (bs1->drv && bs1->drv->protocol_name)
362: is_protocol = 1;
363:
364: bdrv_delete(bs1);
365:
366: get_tmp_filename(tmp_filename, sizeof(tmp_filename));
367:
368: /* Real path is meaningless for protocols */
369: if (is_protocol)
370: snprintf(backing_filename, sizeof(backing_filename),
371: "%s", filename);
372: else
373: realpath(filename, backing_filename);
374:
375: ret = bdrv_create(&bdrv_qcow2, tmp_filename,
376: total_size, backing_filename, 0);
377: if (ret < 0) {
378: return ret;
379: }
380: filename = tmp_filename;
381: bs->is_temporary = 1;
382: }
383:
384: pstrcpy(bs->filename, sizeof(bs->filename), filename);
385: if (flags & BDRV_O_FILE) {
386: drv = find_protocol(filename);
387: } else if (!drv) {
388: drv = find_image_format(filename);
389: }
390: if (!drv) {
391: ret = -ENOENT;
392: goto unlink_and_fail;
393: }
394: bs->drv = drv;
395: bs->opaque = qemu_mallocz(drv->instance_size);
396: /* Note: for compatibility, we open disk image files as RDWR, and
397: RDONLY as fallback */
398: if (!(flags & BDRV_O_FILE))
399: open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK);
400: else
401: open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
402: ret = drv->bdrv_open(bs, filename, open_flags);
403: if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
404: ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
405: bs->read_only = 1;
406: }
407: if (ret < 0) {
408: qemu_free(bs->opaque);
409: bs->opaque = NULL;
410: bs->drv = NULL;
411: unlink_and_fail:
412: if (bs->is_temporary)
413: unlink(filename);
414: return ret;
415: }
416: if (drv->bdrv_getlength) {
417: bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
418: }
419: #ifndef _WIN32
420: if (bs->is_temporary) {
421: unlink(filename);
422: }
423: #endif
424: if (bs->backing_file[0] != '\0') {
425: /* if there is a backing file, use it */
426: bs->backing_hd = bdrv_new("");
427: path_combine(backing_filename, sizeof(backing_filename),
428: filename, bs->backing_file);
429: ret = bdrv_open(bs->backing_hd, backing_filename, open_flags);
430: if (ret < 0) {
431: bdrv_close(bs);
432: return ret;
433: }
434: }
435:
436: /* call the change callback */
437: bs->media_changed = 1;
438: if (bs->change_cb)
439: bs->change_cb(bs->change_opaque);
440:
441: return 0;
442: }
443:
444: void bdrv_close(BlockDriverState *bs)
445: {
446: if (bs->drv) {
447: if (bs->backing_hd)
448: bdrv_delete(bs->backing_hd);
449: bs->drv->bdrv_close(bs);
450: qemu_free(bs->opaque);
451: #ifdef _WIN32
452: if (bs->is_temporary) {
453: unlink(bs->filename);
454: }
455: #endif
456: bs->opaque = NULL;
457: bs->drv = NULL;
458:
459: /* call the change callback */
460: bs->media_changed = 1;
461: if (bs->change_cb)
462: bs->change_cb(bs->change_opaque);
463: }
464: }
465:
466: void bdrv_delete(BlockDriverState *bs)
467: {
468: BlockDriverState **pbs;
469:
470: pbs = &bdrv_first;
471: while (*pbs != bs && *pbs != NULL)
472: pbs = &(*pbs)->next;
473: if (*pbs == bs)
474: *pbs = bs->next;
475:
476: bdrv_close(bs);
477: qemu_free(bs);
478: }
479:
480: /* commit COW file into the raw image */
481: int bdrv_commit(BlockDriverState *bs)
482: {
483: BlockDriver *drv = bs->drv;
484: int64_t i, total_sectors;
485: int n, j;
486: unsigned char sector[512];
487:
488: if (!drv)
489: return -ENOMEDIUM;
490:
491: if (bs->read_only) {
492: return -EACCES;
493: }
494:
495: if (!bs->backing_hd) {
496: return -ENOTSUP;
497: }
498:
499: total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
500: for (i = 0; i < total_sectors;) {
501: if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
502: for(j = 0; j < n; j++) {
503: if (bdrv_read(bs, i, sector, 1) != 0) {
504: return -EIO;
505: }
506:
507: if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
508: return -EIO;
509: }
510: i++;
511: }
512: } else {
513: i += n;
514: }
515: }
516:
517: if (drv->bdrv_make_empty)
518: return drv->bdrv_make_empty(bs);
519:
520: return 0;
521: }
522:
523: static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
524: size_t size)
525: {
526: int64_t len;
527:
528: if (!bdrv_is_inserted(bs))
529: return -ENOMEDIUM;
530:
531: if (bs->growable)
532: return 0;
533:
534: len = bdrv_getlength(bs);
535:
536: if (offset < 0)
537: return -EIO;
538:
539: if ((offset > len) || (len - offset < size))
540: return -EIO;
541:
542: return 0;
543: }
544:
545: static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
546: int nb_sectors)
547: {
548: int64_t offset;
549:
550: /* Deal with byte accesses */
551: if (sector_num < 0)
552: offset = -sector_num;
553: else
554: offset = sector_num * 512;
555:
556: return bdrv_check_byte_request(bs, offset, nb_sectors * 512);
557: }
558:
559: /* return < 0 if error. See bdrv_write() for the return codes */
560: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
561: uint8_t *buf, int nb_sectors)
562: {
563: BlockDriver *drv = bs->drv;
564:
565: if (!drv)
566: return -ENOMEDIUM;
567: if (bdrv_check_request(bs, sector_num, nb_sectors))
568: return -EIO;
569:
570: if (drv->bdrv_pread) {
571: int ret, len;
572: len = nb_sectors * 512;
573: ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
574: if (ret < 0)
575: return ret;
576: else if (ret != len)
577: return -EINVAL;
578: else {
579: bs->rd_bytes += (unsigned) len;
580: bs->rd_ops ++;
581: return 0;
582: }
583: } else {
584: return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
585: }
586: }
587:
588: /* Return < 0 if error. Important errors are:
589: -EIO generic I/O error (may happen for all errors)
590: -ENOMEDIUM No media inserted.
591: -EINVAL Invalid sector number or nb_sectors
592: -EACCES Trying to write a read-only device
593: */
594: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
595: const uint8_t *buf, int nb_sectors)
596: {
597: BlockDriver *drv = bs->drv;
598: if (!bs->drv)
599: return -ENOMEDIUM;
600: if (bs->read_only)
601: return -EACCES;
602: if (bdrv_check_request(bs, sector_num, nb_sectors))
603: return -EIO;
604:
605: if (drv->bdrv_pwrite) {
606: int ret, len, count = 0;
607: len = nb_sectors * 512;
608: do {
609: ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len - count);
610: if (ret < 0) {
611: printf("bdrv_write ret=%d\n", ret);
612: return ret;
613: }
614: count += ret;
615: buf += ret;
616: } while (count != len);
617: bs->wr_bytes += (unsigned) len;
618: bs->wr_ops ++;
619: return 0;
620: }
621: return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
622: }
623:
624: static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
625: uint8_t *buf, int count1)
626: {
627: uint8_t tmp_buf[SECTOR_SIZE];
628: int len, nb_sectors, count;
629: int64_t sector_num;
630:
631: count = count1;
632: /* first read to align to sector start */
633: len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
634: if (len > count)
635: len = count;
636: sector_num = offset >> SECTOR_BITS;
637: if (len > 0) {
638: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
639: return -EIO;
640: memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
641: count -= len;
642: if (count == 0)
643: return count1;
644: sector_num++;
645: buf += len;
646: }
647:
648: /* read the sectors "in place" */
649: nb_sectors = count >> SECTOR_BITS;
650: if (nb_sectors > 0) {
651: if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
652: return -EIO;
653: sector_num += nb_sectors;
654: len = nb_sectors << SECTOR_BITS;
655: buf += len;
656: count -= len;
657: }
658:
659: /* add data from the last sector */
660: if (count > 0) {
661: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
662: return -EIO;
663: memcpy(buf, tmp_buf, count);
664: }
665: return count1;
666: }
667:
668: static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
669: const uint8_t *buf, int count1)
670: {
671: uint8_t tmp_buf[SECTOR_SIZE];
672: int len, nb_sectors, count;
673: int64_t sector_num;
674:
675: count = count1;
676: /* first write to align to sector start */
677: len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
678: if (len > count)
679: len = count;
680: sector_num = offset >> SECTOR_BITS;
681: if (len > 0) {
682: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
683: return -EIO;
684: memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
685: if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
686: return -EIO;
687: count -= len;
688: if (count == 0)
689: return count1;
690: sector_num++;
691: buf += len;
692: }
693:
694: /* write the sectors "in place" */
695: nb_sectors = count >> SECTOR_BITS;
696: if (nb_sectors > 0) {
697: if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
698: return -EIO;
699: sector_num += nb_sectors;
700: len = nb_sectors << SECTOR_BITS;
701: buf += len;
702: count -= len;
703: }
704:
705: /* add data from the last sector */
706: if (count > 0) {
707: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
708: return -EIO;
709: memcpy(tmp_buf, buf, count);
710: if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
711: return -EIO;
712: }
713: return count1;
714: }
715:
716: /**
717: * Read with byte offsets (needed only for file protocols)
718: */
719: int bdrv_pread(BlockDriverState *bs, int64_t offset,
720: void *buf1, int count1)
721: {
722: BlockDriver *drv = bs->drv;
723:
724: if (!drv)
725: return -ENOMEDIUM;
726: if (bdrv_check_byte_request(bs, offset, count1))
727: return -EIO;
728:
729: if (!drv->bdrv_pread)
730: return bdrv_pread_em(bs, offset, buf1, count1);
731: return drv->bdrv_pread(bs, offset, buf1, count1);
732: }
733:
734: /**
735: * Write with byte offsets (needed only for file protocols)
736: */
737: int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
738: const void *buf1, int count1)
739: {
740: BlockDriver *drv = bs->drv;
741:
742: if (!drv)
743: return -ENOMEDIUM;
744: if (bdrv_check_byte_request(bs, offset, count1))
745: return -EIO;
746:
747: if (!drv->bdrv_pwrite)
748: return bdrv_pwrite_em(bs, offset, buf1, count1);
749: return drv->bdrv_pwrite(bs, offset, buf1, count1);
750: }
751:
752: /**
753: * Truncate file to 'offset' bytes (needed only for file protocols)
754: */
755: int bdrv_truncate(BlockDriverState *bs, int64_t offset)
756: {
757: BlockDriver *drv = bs->drv;
758: if (!drv)
759: return -ENOMEDIUM;
760: if (!drv->bdrv_truncate)
761: return -ENOTSUP;
762: return drv->bdrv_truncate(bs, offset);
763: }
764:
765: /**
766: * Length of a file in bytes. Return < 0 if error or unknown.
767: */
768: int64_t bdrv_getlength(BlockDriverState *bs)
769: {
770: BlockDriver *drv = bs->drv;
771: if (!drv)
772: return -ENOMEDIUM;
773: if (!drv->bdrv_getlength) {
774: /* legacy mode */
775: return bs->total_sectors * SECTOR_SIZE;
776: }
777: return drv->bdrv_getlength(bs);
778: }
779:
780: /* return 0 as number of sectors if no device present or error */
781: void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
782: {
783: int64_t length;
784: length = bdrv_getlength(bs);
785: if (length < 0)
786: length = 0;
787: else
788: length = length >> SECTOR_BITS;
789: *nb_sectors_ptr = length;
790: }
791:
792: struct partition {
793: uint8_t boot_ind; /* 0x80 - active */
794: uint8_t head; /* starting head */
795: uint8_t sector; /* starting sector */
796: uint8_t cyl; /* starting cylinder */
797: uint8_t sys_ind; /* What partition type */
798: uint8_t end_head; /* end head */
799: uint8_t end_sector; /* end sector */
800: uint8_t end_cyl; /* end cylinder */
801: uint32_t start_sect; /* starting sector counting from 0 */
802: uint32_t nr_sects; /* nr of sectors in partition */
803: } __attribute__((packed));
804:
805: /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
806: static int guess_disk_lchs(BlockDriverState *bs,
807: int *pcylinders, int *pheads, int *psectors)
808: {
809: uint8_t buf[512];
810: int ret, i, heads, sectors, cylinders;
811: struct partition *p;
812: uint32_t nr_sects;
813: uint64_t nb_sectors;
814:
815: bdrv_get_geometry(bs, &nb_sectors);
816:
817: ret = bdrv_read(bs, 0, buf, 1);
818: if (ret < 0)
819: return -1;
820: /* test msdos magic */
821: if (buf[510] != 0x55 || buf[511] != 0xaa)
822: return -1;
823: for(i = 0; i < 4; i++) {
824: p = ((struct partition *)(buf + 0x1be)) + i;
825: nr_sects = le32_to_cpu(p->nr_sects);
826: if (nr_sects && p->end_head) {
827: /* We make the assumption that the partition terminates on
828: a cylinder boundary */
829: heads = p->end_head + 1;
830: sectors = p->end_sector & 63;
831: if (sectors == 0)
832: continue;
833: cylinders = nb_sectors / (heads * sectors);
834: if (cylinders < 1 || cylinders > 16383)
835: continue;
836: *pheads = heads;
837: *psectors = sectors;
838: *pcylinders = cylinders;
839: #if 0
840: printf("guessed geometry: LCHS=%d %d %d\n",
841: cylinders, heads, sectors);
842: #endif
843: return 0;
844: }
845: }
846: return -1;
847: }
848:
849: void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
850: {
851: int translation, lba_detected = 0;
852: int cylinders, heads, secs;
853: uint64_t nb_sectors;
854:
855: /* if a geometry hint is available, use it */
856: bdrv_get_geometry(bs, &nb_sectors);
857: bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
858: translation = bdrv_get_translation_hint(bs);
859: if (cylinders != 0) {
860: *pcyls = cylinders;
861: *pheads = heads;
862: *psecs = secs;
863: } else {
864: if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
865: if (heads > 16) {
866: /* if heads > 16, it means that a BIOS LBA
867: translation was active, so the default
868: hardware geometry is OK */
869: lba_detected = 1;
870: goto default_geometry;
871: } else {
872: *pcyls = cylinders;
873: *pheads = heads;
874: *psecs = secs;
875: /* disable any translation to be in sync with
876: the logical geometry */
877: if (translation == BIOS_ATA_TRANSLATION_AUTO) {
878: bdrv_set_translation_hint(bs,
879: BIOS_ATA_TRANSLATION_NONE);
880: }
881: }
882: } else {
883: default_geometry:
884: /* if no geometry, use a standard physical disk geometry */
885: cylinders = nb_sectors / (16 * 63);
886:
887: if (cylinders > 16383)
888: cylinders = 16383;
889: else if (cylinders < 2)
890: cylinders = 2;
891: *pcyls = cylinders;
892: *pheads = 16;
893: *psecs = 63;
894: if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
895: if ((*pcyls * *pheads) <= 131072) {
896: bdrv_set_translation_hint(bs,
897: BIOS_ATA_TRANSLATION_LARGE);
898: } else {
899: bdrv_set_translation_hint(bs,
900: BIOS_ATA_TRANSLATION_LBA);
901: }
902: }
903: }
904: bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
905: }
906: }
907:
908: void bdrv_set_geometry_hint(BlockDriverState *bs,
909: int cyls, int heads, int secs)
910: {
911: bs->cyls = cyls;
912: bs->heads = heads;
913: bs->secs = secs;
914: }
915:
916: void bdrv_set_type_hint(BlockDriverState *bs, int type)
917: {
918: bs->type = type;
919: bs->removable = ((type == BDRV_TYPE_CDROM ||
920: type == BDRV_TYPE_FLOPPY));
921: }
922:
923: void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
924: {
925: bs->translation = translation;
926: }
927:
928: void bdrv_get_geometry_hint(BlockDriverState *bs,
929: int *pcyls, int *pheads, int *psecs)
930: {
931: *pcyls = bs->cyls;
932: *pheads = bs->heads;
933: *psecs = bs->secs;
934: }
935:
936: int bdrv_get_type_hint(BlockDriverState *bs)
937: {
938: return bs->type;
939: }
940:
941: int bdrv_get_translation_hint(BlockDriverState *bs)
942: {
943: return bs->translation;
944: }
945:
946: int bdrv_is_removable(BlockDriverState *bs)
947: {
948: return bs->removable;
949: }
950:
951: int bdrv_is_read_only(BlockDriverState *bs)
952: {
953: return bs->read_only;
954: }
955:
956: int bdrv_is_sg(BlockDriverState *bs)
957: {
958: return bs->sg;
959: }
960:
961: /* XXX: no longer used */
962: void bdrv_set_change_cb(BlockDriverState *bs,
963: void (*change_cb)(void *opaque), void *opaque)
964: {
965: bs->change_cb = change_cb;
966: bs->change_opaque = opaque;
967: }
968:
969: int bdrv_is_encrypted(BlockDriverState *bs)
970: {
971: if (bs->backing_hd && bs->backing_hd->encrypted)
972: return 1;
973: return bs->encrypted;
974: }
975:
976: int bdrv_key_required(BlockDriverState *bs)
977: {
978: BlockDriverState *backing_hd = bs->backing_hd;
979:
980: if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
981: return 1;
982: return (bs->encrypted && !bs->valid_key);
983: }
984:
985: int bdrv_set_key(BlockDriverState *bs, const char *key)
986: {
987: int ret;
988: if (bs->backing_hd && bs->backing_hd->encrypted) {
989: ret = bdrv_set_key(bs->backing_hd, key);
990: if (ret < 0)
991: return ret;
992: if (!bs->encrypted)
993: return 0;
994: }
995: if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
996: return -1;
997: ret = bs->drv->bdrv_set_key(bs, key);
998: bs->valid_key = (ret == 0);
999: return ret;
1000: }
1001:
1002: void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1003: {
1004: if (!bs->drv) {
1005: buf[0] = '\0';
1006: } else {
1007: pstrcpy(buf, buf_size, bs->drv->format_name);
1008: }
1009: }
1010:
1011: void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1012: void *opaque)
1013: {
1014: BlockDriver *drv;
1015:
1016: for (drv = first_drv; drv != NULL; drv = drv->next) {
1017: it(opaque, drv->format_name);
1018: }
1019: }
1020:
1021: BlockDriverState *bdrv_find(const char *name)
1022: {
1023: BlockDriverState *bs;
1024:
1025: for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1026: if (!strcmp(name, bs->device_name))
1027: return bs;
1028: }
1029: return NULL;
1030: }
1031:
1032: void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
1033: {
1034: BlockDriverState *bs;
1035:
1036: for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1037: it(opaque, bs);
1038: }
1039: }
1040:
1041: const char *bdrv_get_device_name(BlockDriverState *bs)
1042: {
1043: return bs->device_name;
1044: }
1045:
1046: void bdrv_flush(BlockDriverState *bs)
1047: {
1048: if (bs->drv->bdrv_flush)
1049: bs->drv->bdrv_flush(bs);
1050: if (bs->backing_hd)
1051: bdrv_flush(bs->backing_hd);
1052: }
1053:
1054: void bdrv_flush_all(void)
1055: {
1056: BlockDriverState *bs;
1057:
1058: for (bs = bdrv_first; bs != NULL; bs = bs->next)
1059: if (bs->drv && !bdrv_is_read_only(bs) &&
1060: (!bdrv_is_removable(bs) || bdrv_is_inserted(bs)))
1061: bdrv_flush(bs);
1062: }
1063:
1064: /*
1065: * Returns true iff the specified sector is present in the disk image. Drivers
1066: * not implementing the functionality are assumed to not support backing files,
1067: * hence all their sectors are reported as allocated.
1068: *
1069: * 'pnum' is set to the number of sectors (including and immediately following
1070: * the specified sector) that are known to be in the same
1071: * allocated/unallocated state.
1072: *
1073: * 'nb_sectors' is the max value 'pnum' should be set to.
1074: */
1075: int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1076: int *pnum)
1077: {
1078: int64_t n;
1079: if (!bs->drv->bdrv_is_allocated) {
1080: if (sector_num >= bs->total_sectors) {
1081: *pnum = 0;
1082: return 0;
1083: }
1084: n = bs->total_sectors - sector_num;
1085: *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1086: return 1;
1087: }
1088: return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1089: }
1090:
1091: void bdrv_info(void)
1092: {
1093: BlockDriverState *bs;
1094:
1095: for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1096: term_printf("%s:", bs->device_name);
1097: term_printf(" type=");
1098: switch(bs->type) {
1099: case BDRV_TYPE_HD:
1100: term_printf("hd");
1101: break;
1102: case BDRV_TYPE_CDROM:
1103: term_printf("cdrom");
1104: break;
1105: case BDRV_TYPE_FLOPPY:
1106: term_printf("floppy");
1107: break;
1108: }
1109: term_printf(" removable=%d", bs->removable);
1110: if (bs->removable) {
1111: term_printf(" locked=%d", bs->locked);
1112: }
1113: if (bs->drv) {
1114: term_printf(" file=");
1115: term_print_filename(bs->filename);
1116: if (bs->backing_file[0] != '\0') {
1117: term_printf(" backing_file=");
1118: term_print_filename(bs->backing_file);
1119: }
1120: term_printf(" ro=%d", bs->read_only);
1121: term_printf(" drv=%s", bs->drv->format_name);
1122: term_printf(" encrypted=%d", bdrv_is_encrypted(bs));
1123: } else {
1124: term_printf(" [not inserted]");
1125: }
1126: term_printf("\n");
1127: }
1128: }
1129:
1130: /* The "info blockstats" command. */
1131: void bdrv_info_stats (void)
1132: {
1133: BlockDriverState *bs;
1134:
1135: for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1136: term_printf ("%s:"
1137: " rd_bytes=%" PRIu64
1138: " wr_bytes=%" PRIu64
1139: " rd_operations=%" PRIu64
1140: " wr_operations=%" PRIu64
1141: "\n",
1142: bs->device_name,
1143: bs->rd_bytes, bs->wr_bytes,
1144: bs->rd_ops, bs->wr_ops);
1145: }
1146: }
1147:
1148: const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
1149: {
1150: if (bs->backing_hd && bs->backing_hd->encrypted)
1151: return bs->backing_file;
1152: else if (bs->encrypted)
1153: return bs->filename;
1154: else
1155: return NULL;
1156: }
1157:
1158: void bdrv_get_backing_filename(BlockDriverState *bs,
1159: char *filename, int filename_size)
1160: {
1161: if (!bs->backing_hd) {
1162: pstrcpy(filename, filename_size, "");
1163: } else {
1164: pstrcpy(filename, filename_size, bs->backing_file);
1165: }
1166: }
1167:
1168: int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1169: const uint8_t *buf, int nb_sectors)
1170: {
1171: BlockDriver *drv = bs->drv;
1172: if (!drv)
1173: return -ENOMEDIUM;
1174: if (!drv->bdrv_write_compressed)
1175: return -ENOTSUP;
1176: if (bdrv_check_request(bs, sector_num, nb_sectors))
1177: return -EIO;
1178: return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
1179: }
1180:
1181: int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
1182: {
1183: BlockDriver *drv = bs->drv;
1184: if (!drv)
1185: return -ENOMEDIUM;
1186: if (!drv->bdrv_get_info)
1187: return -ENOTSUP;
1188: memset(bdi, 0, sizeof(*bdi));
1189: return drv->bdrv_get_info(bs, bdi);
1190: }
1191:
1192: int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
1193: {
1194: BlockDriver *drv = bs->drv;
1195: if (!drv)
1196: return -ENOMEDIUM;
1197: if (!drv->bdrv_put_buffer)
1198: return -ENOTSUP;
1199: return drv->bdrv_put_buffer(bs, buf, pos, size);
1200: }
1201:
1202: int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
1203: {
1204: BlockDriver *drv = bs->drv;
1205: if (!drv)
1206: return -ENOMEDIUM;
1207: if (!drv->bdrv_get_buffer)
1208: return -ENOTSUP;
1209: return drv->bdrv_get_buffer(bs, buf, pos, size);
1210: }
1211:
1212: /**************************************************************/
1213: /* handling of snapshots */
1214:
1215: int bdrv_snapshot_create(BlockDriverState *bs,
1216: QEMUSnapshotInfo *sn_info)
1217: {
1218: BlockDriver *drv = bs->drv;
1219: if (!drv)
1220: return -ENOMEDIUM;
1221: if (!drv->bdrv_snapshot_create)
1222: return -ENOTSUP;
1223: return drv->bdrv_snapshot_create(bs, sn_info);
1224: }
1225:
1226: int bdrv_snapshot_goto(BlockDriverState *bs,
1227: const char *snapshot_id)
1228: {
1229: BlockDriver *drv = bs->drv;
1230: if (!drv)
1231: return -ENOMEDIUM;
1232: if (!drv->bdrv_snapshot_goto)
1233: return -ENOTSUP;
1234: return drv->bdrv_snapshot_goto(bs, snapshot_id);
1235: }
1236:
1237: int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1238: {
1239: BlockDriver *drv = bs->drv;
1240: if (!drv)
1241: return -ENOMEDIUM;
1242: if (!drv->bdrv_snapshot_delete)
1243: return -ENOTSUP;
1244: return drv->bdrv_snapshot_delete(bs, snapshot_id);
1245: }
1246:
1247: int bdrv_snapshot_list(BlockDriverState *bs,
1248: QEMUSnapshotInfo **psn_info)
1249: {
1250: BlockDriver *drv = bs->drv;
1251: if (!drv)
1252: return -ENOMEDIUM;
1253: if (!drv->bdrv_snapshot_list)
1254: return -ENOTSUP;
1255: return drv->bdrv_snapshot_list(bs, psn_info);
1256: }
1257:
1258: #define NB_SUFFIXES 4
1259:
1260: char *get_human_readable_size(char *buf, int buf_size, int64_t size)
1261: {
1262: static const char suffixes[NB_SUFFIXES] = "KMGT";
1263: int64_t base;
1264: int i;
1265:
1266: if (size <= 999) {
1267: snprintf(buf, buf_size, "%" PRId64, size);
1268: } else {
1269: base = 1024;
1270: for(i = 0; i < NB_SUFFIXES; i++) {
1271: if (size < (10 * base)) {
1272: snprintf(buf, buf_size, "%0.1f%c",
1273: (double)size / base,
1274: suffixes[i]);
1275: break;
1276: } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1277: snprintf(buf, buf_size, "%" PRId64 "%c",
1278: ((size + (base >> 1)) / base),
1279: suffixes[i]);
1280: break;
1281: }
1282: base = base * 1024;
1283: }
1284: }
1285: return buf;
1286: }
1287:
1288: char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
1289: {
1290: char buf1[128], date_buf[128], clock_buf[128];
1291: #ifdef _WIN32
1292: struct tm *ptm;
1293: #else
1294: struct tm tm;
1295: #endif
1296: time_t ti;
1297: int64_t secs;
1298:
1299: if (!sn) {
1300: snprintf(buf, buf_size,
1301: "%-10s%-20s%7s%20s%15s",
1302: "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
1303: } else {
1304: ti = sn->date_sec;
1305: #ifdef _WIN32
1306: ptm = localtime(&ti);
1307: strftime(date_buf, sizeof(date_buf),
1308: "%Y-%m-%d %H:%M:%S", ptm);
1309: #else
1310: localtime_r(&ti, &tm);
1311: strftime(date_buf, sizeof(date_buf),
1312: "%Y-%m-%d %H:%M:%S", &tm);
1313: #endif
1314: secs = sn->vm_clock_nsec / 1000000000;
1315: snprintf(clock_buf, sizeof(clock_buf),
1316: "%02d:%02d:%02d.%03d",
1317: (int)(secs / 3600),
1318: (int)((secs / 60) % 60),
1319: (int)(secs % 60),
1320: (int)((sn->vm_clock_nsec / 1000000) % 1000));
1321: snprintf(buf, buf_size,
1322: "%-10s%-20s%7s%20s%15s",
1323: sn->id_str, sn->name,
1324: get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
1325: date_buf,
1326: clock_buf);
1327: }
1328: return buf;
1329: }
1330:
1331:
1332: /**************************************************************/
1333: /* async I/Os */
1334:
1335: typedef struct VectorTranslationAIOCB {
1336: BlockDriverAIOCB common;
1337: QEMUIOVector *iov;
1338: uint8_t *bounce;
1339: int is_write;
1340: BlockDriverAIOCB *aiocb;
1341: } VectorTranslationAIOCB;
1342:
1343: static void bdrv_aio_cancel_vector(BlockDriverAIOCB *_acb)
1344: {
1345: VectorTranslationAIOCB *acb
1346: = container_of(_acb, VectorTranslationAIOCB, common);
1347:
1348: bdrv_aio_cancel(acb->aiocb);
1349: }
1350:
1351: static void bdrv_aio_rw_vector_cb(void *opaque, int ret)
1352: {
1353: VectorTranslationAIOCB *s = (VectorTranslationAIOCB *)opaque;
1354:
1355: if (!s->is_write) {
1356: qemu_iovec_from_buffer(s->iov, s->bounce, s->iov->size);
1357: }
1358: qemu_vfree(s->bounce);
1359: s->common.cb(s->common.opaque, ret);
1360: qemu_aio_release(s);
1361: }
1362:
1363: static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
1364: int64_t sector_num,
1365: QEMUIOVector *iov,
1366: int nb_sectors,
1367: BlockDriverCompletionFunc *cb,
1368: void *opaque,
1369: int is_write)
1370:
1371: {
1372: VectorTranslationAIOCB *s = qemu_aio_get_pool(&vectored_aio_pool, bs,
1373: cb, opaque);
1374:
1375: s->iov = iov;
1376: s->bounce = qemu_memalign(512, nb_sectors * 512);
1377: s->is_write = is_write;
1378: if (is_write) {
1379: qemu_iovec_to_buffer(s->iov, s->bounce);
1380: s->aiocb = bdrv_aio_write(bs, sector_num, s->bounce, nb_sectors,
1381: bdrv_aio_rw_vector_cb, s);
1382: } else {
1383: s->aiocb = bdrv_aio_read(bs, sector_num, s->bounce, nb_sectors,
1384: bdrv_aio_rw_vector_cb, s);
1385: }
1386: if (!s->aiocb) {
1387: qemu_vfree(s->bounce);
1388: qemu_aio_release(s);
1389: return NULL;
1390: }
1391: return &s->common;
1392: }
1393:
1394: BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
1395: QEMUIOVector *iov, int nb_sectors,
1396: BlockDriverCompletionFunc *cb, void *opaque)
1397: {
1398: if (bdrv_check_request(bs, sector_num, nb_sectors))
1399: return NULL;
1400:
1401: return bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
1402: cb, opaque, 0);
1403: }
1404:
1405: BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
1406: QEMUIOVector *iov, int nb_sectors,
1407: BlockDriverCompletionFunc *cb, void *opaque)
1408: {
1409: if (bdrv_check_request(bs, sector_num, nb_sectors))
1410: return NULL;
1411:
1412: return bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
1413: cb, opaque, 1);
1414: }
1415:
1416: BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
1417: uint8_t *buf, int nb_sectors,
1418: BlockDriverCompletionFunc *cb, void *opaque)
1419: {
1420: BlockDriver *drv = bs->drv;
1421: BlockDriverAIOCB *ret;
1422:
1423: if (!drv)
1424: return NULL;
1425: if (bdrv_check_request(bs, sector_num, nb_sectors))
1426: return NULL;
1427:
1428: ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
1429:
1430: if (ret) {
1431: /* Update stats even though technically transfer has not happened. */
1432: bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
1433: bs->rd_ops ++;
1434: }
1435:
1436: return ret;
1437: }
1438:
1439: BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
1440: const uint8_t *buf, int nb_sectors,
1441: BlockDriverCompletionFunc *cb, void *opaque)
1442: {
1443: BlockDriver *drv = bs->drv;
1444: BlockDriverAIOCB *ret;
1445:
1446: if (!drv)
1447: return NULL;
1448: if (bs->read_only)
1449: return NULL;
1450: if (bdrv_check_request(bs, sector_num, nb_sectors))
1451: return NULL;
1452:
1453: ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
1454:
1455: if (ret) {
1456: /* Update stats even though technically transfer has not happened. */
1457: bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
1458: bs->wr_ops ++;
1459: }
1460:
1461: return ret;
1462: }
1463:
1464: void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1465: {
1466: acb->pool->cancel(acb);
1467: }
1468:
1469:
1470: /**************************************************************/
1471: /* async block device emulation */
1472:
1473: static void bdrv_aio_bh_cb(void *opaque)
1474: {
1475: BlockDriverAIOCBSync *acb = opaque;
1476: acb->common.cb(acb->common.opaque, acb->ret);
1477: qemu_aio_release(acb);
1478: }
1479:
1480: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1481: int64_t sector_num, uint8_t *buf, int nb_sectors,
1482: BlockDriverCompletionFunc *cb, void *opaque)
1483: {
1484: BlockDriverAIOCBSync *acb;
1485: int ret;
1486:
1487: acb = qemu_aio_get(bs, cb, opaque);
1488: if (!acb->bh)
1489: acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1490: ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1491: acb->ret = ret;
1492: qemu_bh_schedule(acb->bh);
1493: return &acb->common;
1494: }
1495:
1496: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1497: int64_t sector_num, const uint8_t *buf, int nb_sectors,
1498: BlockDriverCompletionFunc *cb, void *opaque)
1499: {
1500: BlockDriverAIOCBSync *acb;
1501: int ret;
1502:
1503: acb = qemu_aio_get(bs, cb, opaque);
1504: if (!acb->bh)
1505: acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1506: ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1507: acb->ret = ret;
1508: qemu_bh_schedule(acb->bh);
1509: return &acb->common;
1510: }
1511:
1512: static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
1513: {
1514: BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
1515: qemu_bh_cancel(acb->bh);
1516: qemu_aio_release(acb);
1517: }
1518:
1519: /**************************************************************/
1520: /* sync block device emulation */
1521:
1522: static void bdrv_rw_em_cb(void *opaque, int ret)
1523: {
1524: *(int *)opaque = ret;
1525: }
1526:
1527: #define NOT_DONE 0x7fffffff
1528:
1529: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1530: uint8_t *buf, int nb_sectors)
1531: {
1532: int async_ret;
1533: BlockDriverAIOCB *acb;
1534:
1535: async_ret = NOT_DONE;
1536: acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
1537: bdrv_rw_em_cb, &async_ret);
1538: if (acb == NULL)
1539: return -1;
1540:
1541: while (async_ret == NOT_DONE) {
1542: qemu_aio_wait();
1543: }
1544:
1545: return async_ret;
1546: }
1547:
1548: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
1549: const uint8_t *buf, int nb_sectors)
1550: {
1551: int async_ret;
1552: BlockDriverAIOCB *acb;
1553:
1554: async_ret = NOT_DONE;
1555: acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
1556: bdrv_rw_em_cb, &async_ret);
1557: if (acb == NULL)
1558: return -1;
1559: while (async_ret == NOT_DONE) {
1560: qemu_aio_wait();
1561: }
1562: return async_ret;
1563: }
1564:
1565: void bdrv_init(void)
1566: {
1567: aio_pool_init(&vectored_aio_pool, sizeof(VectorTranslationAIOCB),
1568: bdrv_aio_cancel_vector);
1569:
1570: bdrv_register(&bdrv_raw);
1571: bdrv_register(&bdrv_host_device);
1572: #ifndef _WIN32
1573: bdrv_register(&bdrv_cow);
1574: #endif
1575: bdrv_register(&bdrv_qcow);
1576: bdrv_register(&bdrv_vmdk);
1577: bdrv_register(&bdrv_cloop);
1578: bdrv_register(&bdrv_dmg);
1579: bdrv_register(&bdrv_bochs);
1580: bdrv_register(&bdrv_vpc);
1581: bdrv_register(&bdrv_vvfat);
1582: bdrv_register(&bdrv_qcow2);
1583: bdrv_register(&bdrv_parallels);
1584: bdrv_register(&bdrv_nbd);
1585: }
1586:
1587: void aio_pool_init(AIOPool *pool, int aiocb_size,
1588: void (*cancel)(BlockDriverAIOCB *acb))
1589: {
1590: pool->aiocb_size = aiocb_size;
1591: pool->cancel = cancel;
1592: pool->free_aiocb = NULL;
1593: }
1594:
1595: void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs,
1596: BlockDriverCompletionFunc *cb, void *opaque)
1597: {
1598: BlockDriverAIOCB *acb;
1599:
1600: if (pool->free_aiocb) {
1601: acb = pool->free_aiocb;
1602: pool->free_aiocb = acb->next;
1603: } else {
1604: acb = qemu_mallocz(pool->aiocb_size);
1605: acb->pool = pool;
1606: }
1607: acb->bs = bs;
1608: acb->cb = cb;
1609: acb->opaque = opaque;
1610: return acb;
1611: }
1612:
1613: void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
1614: void *opaque)
1615: {
1616: return qemu_aio_get_pool(&bs->drv->aio_pool, bs, cb, opaque);
1617: }
1618:
1619: void qemu_aio_release(void *p)
1620: {
1621: BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
1622: AIOPool *pool = acb->pool;
1623: acb->next = pool->free_aiocb;
1624: pool->free_aiocb = acb;
1625: }
1626:
1627: /**************************************************************/
1628: /* removable device support */
1629:
1630: /**
1631: * Return TRUE if the media is present
1632: */
1633: int bdrv_is_inserted(BlockDriverState *bs)
1634: {
1635: BlockDriver *drv = bs->drv;
1636: int ret;
1637: if (!drv)
1638: return 0;
1639: if (!drv->bdrv_is_inserted)
1640: return 1;
1641: ret = drv->bdrv_is_inserted(bs);
1642: return ret;
1643: }
1644:
1645: /**
1646: * Return TRUE if the media changed since the last call to this
1647: * function. It is currently only used for floppy disks
1648: */
1649: int bdrv_media_changed(BlockDriverState *bs)
1650: {
1651: BlockDriver *drv = bs->drv;
1652: int ret;
1653:
1654: if (!drv || !drv->bdrv_media_changed)
1655: ret = -ENOTSUP;
1656: else
1657: ret = drv->bdrv_media_changed(bs);
1658: if (ret == -ENOTSUP)
1659: ret = bs->media_changed;
1660: bs->media_changed = 0;
1661: return ret;
1662: }
1663:
1664: /**
1665: * If eject_flag is TRUE, eject the media. Otherwise, close the tray
1666: */
1667: void bdrv_eject(BlockDriverState *bs, int eject_flag)
1668: {
1669: BlockDriver *drv = bs->drv;
1670: int ret;
1671:
1672: if (!drv || !drv->bdrv_eject) {
1673: ret = -ENOTSUP;
1674: } else {
1675: ret = drv->bdrv_eject(bs, eject_flag);
1676: }
1677: if (ret == -ENOTSUP) {
1678: if (eject_flag)
1679: bdrv_close(bs);
1680: }
1681: }
1682:
1683: int bdrv_is_locked(BlockDriverState *bs)
1684: {
1685: return bs->locked;
1686: }
1687:
1688: /**
1689: * Lock or unlock the media (if it is locked, the user won't be able
1690: * to eject it manually).
1691: */
1692: void bdrv_set_locked(BlockDriverState *bs, int locked)
1693: {
1694: BlockDriver *drv = bs->drv;
1695:
1696: bs->locked = locked;
1697: if (drv && drv->bdrv_set_locked) {
1698: drv->bdrv_set_locked(bs, locked);
1699: }
1700: }
1701:
1702: /* needed for generic scsi interface */
1703:
1704: int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1705: {
1706: BlockDriver *drv = bs->drv;
1707:
1708: if (drv && drv->bdrv_ioctl)
1709: return drv->bdrv_ioctl(bs, req, buf);
1710: return -ENOTSUP;
1711: }
unix.superglobalmegacorp.com