blob: 12fc2ef456f9a24ce78b0aa480a4c12376f1d76a [file] [log] [blame]
bellardfc01f7e2003-06-30 10:03:06 +00001/*
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 */
bellardfc01f7e2003-06-30 10:03:06 +000024#include "vl.h"
bellardea2384d2004-08-01 21:59:26 +000025#include "block_int.h"
bellardfc01f7e2003-06-30 10:03:06 +000026
bellard7674e7b2005-04-26 21:59:26 +000027#ifdef _BSD
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/ioctl.h>
31#include <sys/queue.h>
32#include <sys/disk.h>
33#endif
34
bellard83f64092006-08-01 16:21:11 +000035#define SECTOR_BITS 9
36#define SECTOR_SIZE (1 << SECTOR_BITS)
bellard3b0d4f62005-10-30 18:30:10 +000037
bellard90765422006-08-07 19:10:16 +000038typedef struct BlockDriverAIOCBSync {
39 BlockDriverAIOCB common;
40 QEMUBH *bh;
41 int ret;
42} BlockDriverAIOCBSync;
43
pbrookce1a14d2006-08-07 02:38:06 +000044static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
45 int64_t sector_num, uint8_t *buf, int nb_sectors,
46 BlockDriverCompletionFunc *cb, void *opaque);
47static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
48 int64_t sector_num, const uint8_t *buf, int nb_sectors,
49 BlockDriverCompletionFunc *cb, void *opaque);
bellard83f64092006-08-01 16:21:11 +000050static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
bellard83f64092006-08-01 16:21:11 +000051static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
52 uint8_t *buf, int nb_sectors);
53static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
54 const uint8_t *buf, int nb_sectors);
bellardec530c82006-04-25 22:36:06 +000055
bellardb3380822004-03-14 21:38:54 +000056static BlockDriverState *bdrv_first;
bellardea2384d2004-08-01 21:59:26 +000057static BlockDriver *first_drv;
58
bellard83f64092006-08-01 16:21:11 +000059#ifdef _WIN32
60#define PATH_SEP '\\'
61#else
62#define PATH_SEP '/'
bellard3b0d4f62005-10-30 18:30:10 +000063#endif
64
bellard83f64092006-08-01 16:21:11 +000065int path_is_absolute(const char *path)
66{
67 const char *p;
68 p = strchr(path, ':');
69 if (p)
70 p++;
71 else
72 p = path;
73 return (*p == PATH_SEP);
74}
75
76/* if filename is absolute, just copy it to dest. Otherwise, build a
77 path to it by considering it is relative to base_path. URL are
78 supported. */
79void path_combine(char *dest, int dest_size,
80 const char *base_path,
81 const char *filename)
82{
83 const char *p, *p1;
84 int len;
85
86 if (dest_size <= 0)
87 return;
88 if (path_is_absolute(filename)) {
89 pstrcpy(dest, dest_size, filename);
90 } else {
91 p = strchr(base_path, ':');
92 if (p)
93 p++;
94 else
95 p = base_path;
96 p1 = strrchr(base_path, PATH_SEP);
97 if (p1)
98 p1++;
99 else
100 p1 = base_path;
101 if (p1 > p)
102 p = p1;
103 len = p - base_path;
104 if (len > dest_size - 1)
105 len = dest_size - 1;
106 memcpy(dest, base_path, len);
107 dest[len] = '\0';
108 pstrcat(dest, dest_size, filename);
109 }
110}
111
112
bellardea2384d2004-08-01 21:59:26 +0000113void bdrv_register(BlockDriver *bdrv)
114{
pbrookce1a14d2006-08-07 02:38:06 +0000115 if (!bdrv->bdrv_aio_read) {
bellard83f64092006-08-01 16:21:11 +0000116 /* add AIO emulation layer */
bellard83f64092006-08-01 16:21:11 +0000117 bdrv->bdrv_aio_read = bdrv_aio_read_em;
118 bdrv->bdrv_aio_write = bdrv_aio_write_em;
119 bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
bellard90765422006-08-07 19:10:16 +0000120 bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
bellard83f64092006-08-01 16:21:11 +0000121 } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
122 /* add synchronous IO emulation layer */
123 bdrv->bdrv_read = bdrv_read_em;
124 bdrv->bdrv_write = bdrv_write_em;
125 }
bellardea2384d2004-08-01 21:59:26 +0000126 bdrv->next = first_drv;
127 first_drv = bdrv;
128}
bellardb3380822004-03-14 21:38:54 +0000129
130/* create a new block device (by default it is empty) */
131BlockDriverState *bdrv_new(const char *device_name)
bellardfc01f7e2003-06-30 10:03:06 +0000132{
bellardb3380822004-03-14 21:38:54 +0000133 BlockDriverState **pbs, *bs;
134
135 bs = qemu_mallocz(sizeof(BlockDriverState));
136 if(!bs)
137 return NULL;
138 pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
bellardea2384d2004-08-01 21:59:26 +0000139 if (device_name[0] != '\0') {
140 /* insert at the end */
141 pbs = &bdrv_first;
142 while (*pbs != NULL)
143 pbs = &(*pbs)->next;
144 *pbs = bs;
145 }
bellardb3380822004-03-14 21:38:54 +0000146 return bs;
147}
148
bellardea2384d2004-08-01 21:59:26 +0000149BlockDriver *bdrv_find_format(const char *format_name)
150{
151 BlockDriver *drv1;
152 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
153 if (!strcmp(drv1->format_name, format_name))
154 return drv1;
155 }
156 return NULL;
157}
158
159int bdrv_create(BlockDriver *drv,
160 const char *filename, int64_t size_in_sectors,
161 const char *backing_file, int flags)
162{
163 if (!drv->bdrv_create)
164 return -ENOTSUP;
165 return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
166}
167
bellardd5249392004-08-03 21:14:23 +0000168#ifdef _WIN32
bellard95389c82005-12-18 18:28:15 +0000169void get_tmp_filename(char *filename, int size)
bellardd5249392004-08-03 21:14:23 +0000170{
bellard83f64092006-08-01 16:21:11 +0000171 tmpnam(filename);
bellardd5249392004-08-03 21:14:23 +0000172}
173#else
bellard95389c82005-12-18 18:28:15 +0000174void get_tmp_filename(char *filename, int size)
bellardea2384d2004-08-01 21:59:26 +0000175{
176 int fd;
bellardd5249392004-08-03 21:14:23 +0000177 /* XXX: race condition possible */
bellardea2384d2004-08-01 21:59:26 +0000178 pstrcpy(filename, size, "/tmp/vl.XXXXXX");
179 fd = mkstemp(filename);
180 close(fd);
181}
bellardd5249392004-08-03 21:14:23 +0000182#endif
bellardea2384d2004-08-01 21:59:26 +0000183
bellard19cb3732006-08-19 11:45:59 +0000184#ifdef _WIN32
bellardf45512f2006-08-23 21:40:13 +0000185static int is_windows_drive_prefix(const char *filename)
186{
187 return (((filename[0] >= 'a' && filename[0] <= 'z') ||
188 (filename[0] >= 'A' && filename[0] <= 'Z')) &&
189 filename[1] == ':');
190}
191
bellard19cb3732006-08-19 11:45:59 +0000192static int is_windows_drive(const char *filename)
193{
bellardf45512f2006-08-23 21:40:13 +0000194 if (is_windows_drive_prefix(filename) &&
195 filename[2] == '\0')
bellard19cb3732006-08-19 11:45:59 +0000196 return 1;
197 if (strstart(filename, "\\\\.\\", NULL) ||
198 strstart(filename, "//./", NULL))
199 return 1;
200 return 0;
201}
202#endif
203
bellard83f64092006-08-01 16:21:11 +0000204static BlockDriver *find_protocol(const char *filename)
205{
206 BlockDriver *drv1;
207 char protocol[128];
208 int len;
209 const char *p;
bellard19cb3732006-08-19 11:45:59 +0000210
211#ifdef _WIN32
bellardf45512f2006-08-23 21:40:13 +0000212 if (is_windows_drive(filename) ||
213 is_windows_drive_prefix(filename))
bellard19cb3732006-08-19 11:45:59 +0000214 return &bdrv_raw;
215#endif
bellard83f64092006-08-01 16:21:11 +0000216 p = strchr(filename, ':');
217 if (!p)
218 return &bdrv_raw;
219 len = p - filename;
220 if (len > sizeof(protocol) - 1)
221 len = sizeof(protocol) - 1;
bellard83f64092006-08-01 16:21:11 +0000222 memcpy(protocol, filename, len);
223 protocol[len] = '\0';
224 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
225 if (drv1->protocol_name &&
226 !strcmp(drv1->protocol_name, protocol))
227 return drv1;
228 }
229 return NULL;
230}
231
bellard7674e7b2005-04-26 21:59:26 +0000232/* XXX: force raw format if block or character device ? It would
233 simplify the BSD case */
bellardea2384d2004-08-01 21:59:26 +0000234static BlockDriver *find_image_format(const char *filename)
235{
bellard83f64092006-08-01 16:21:11 +0000236 int ret, score, score_max;
bellardea2384d2004-08-01 21:59:26 +0000237 BlockDriver *drv1, *drv;
bellard83f64092006-08-01 16:21:11 +0000238 uint8_t buf[2048];
239 BlockDriverState *bs;
bellardea2384d2004-08-01 21:59:26 +0000240
bellard19cb3732006-08-19 11:45:59 +0000241 /* detect host devices. By convention, /dev/cdrom[N] is always
242 recognized as a host CDROM */
243 if (strstart(filename, "/dev/cdrom", NULL))
244 return &bdrv_host_device;
245#ifdef _WIN32
246 if (is_windows_drive(filename))
247 return &bdrv_host_device;
248#else
249 {
250 struct stat st;
251 if (stat(filename, &st) >= 0 &&
252 (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
253 return &bdrv_host_device;
254 }
255 }
256#endif
257
bellard83f64092006-08-01 16:21:11 +0000258 drv = find_protocol(filename);
bellard19cb3732006-08-19 11:45:59 +0000259 /* no need to test disk image formats for vvfat */
bellard83f64092006-08-01 16:21:11 +0000260 if (drv == &bdrv_vvfat)
261 return drv;
bellard19cb3732006-08-19 11:45:59 +0000262
bellard83f64092006-08-01 16:21:11 +0000263 ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
264 if (ret < 0)
265 return NULL;
266 ret = bdrv_pread(bs, 0, buf, sizeof(buf));
267 bdrv_delete(bs);
268 if (ret < 0) {
269 return NULL;
270 }
271
bellardea2384d2004-08-01 21:59:26 +0000272 score_max = 0;
273 for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
bellard83f64092006-08-01 16:21:11 +0000274 if (drv1->bdrv_probe) {
275 score = drv1->bdrv_probe(buf, ret, filename);
276 if (score > score_max) {
277 score_max = score;
278 drv = drv1;
279 }
bellardea2384d2004-08-01 21:59:26 +0000280 }
281 }
282 return drv;
283}
284
bellard83f64092006-08-01 16:21:11 +0000285int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
bellardb3380822004-03-14 21:38:54 +0000286{
bellard83f64092006-08-01 16:21:11 +0000287 BlockDriverState *bs;
288 int ret;
289
290 bs = bdrv_new("");
291 if (!bs)
292 return -ENOMEM;
293 ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
294 if (ret < 0) {
295 bdrv_delete(bs);
296 return ret;
bellard3b0d4f62005-10-30 18:30:10 +0000297 }
bellard83f64092006-08-01 16:21:11 +0000298 *pbs = bs;
299 return 0;
bellardea2384d2004-08-01 21:59:26 +0000300}
bellardfc01f7e2003-06-30 10:03:06 +0000301
bellard83f64092006-08-01 16:21:11 +0000302int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
303{
304 return bdrv_open2(bs, filename, flags, NULL);
305}
306
307int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
bellardea2384d2004-08-01 21:59:26 +0000308 BlockDriver *drv)
309{
bellard83f64092006-08-01 16:21:11 +0000310 int ret, open_flags;
bellardea2384d2004-08-01 21:59:26 +0000311 char tmp_filename[1024];
bellard83f64092006-08-01 16:21:11 +0000312 char backing_filename[1024];
bellard33e39632003-07-06 17:15:21 +0000313
bellardea2384d2004-08-01 21:59:26 +0000314 bs->read_only = 0;
315 bs->is_temporary = 0;
316 bs->encrypted = 0;
bellard712e7872005-04-28 21:09:32 +0000317
bellard83f64092006-08-01 16:21:11 +0000318 if (flags & BDRV_O_SNAPSHOT) {
bellardea2384d2004-08-01 21:59:26 +0000319 BlockDriverState *bs1;
320 int64_t total_size;
321
322 /* if snapshot, we create a temporary backing file and open it
323 instead of opening 'filename' directly */
324
325 /* if there is a backing file, use it */
326 bs1 = bdrv_new("");
327 if (!bs1) {
bellard83f64092006-08-01 16:21:11 +0000328 return -ENOMEM;
bellardea2384d2004-08-01 21:59:26 +0000329 }
330 if (bdrv_open(bs1, filename, 0) < 0) {
331 bdrv_delete(bs1);
332 return -1;
333 }
bellard83f64092006-08-01 16:21:11 +0000334 total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
bellardea2384d2004-08-01 21:59:26 +0000335 bdrv_delete(bs1);
336
337 get_tmp_filename(tmp_filename, sizeof(tmp_filename));
bellardd15a7712006-08-06 13:35:09 +0000338 if (bdrv_create(&bdrv_qcow2, tmp_filename,
bellardea2384d2004-08-01 21:59:26 +0000339 total_size, filename, 0) < 0) {
340 return -1;
341 }
342 filename = tmp_filename;
343 bs->is_temporary = 1;
344 }
bellard712e7872005-04-28 21:09:32 +0000345
bellardea2384d2004-08-01 21:59:26 +0000346 pstrcpy(bs->filename, sizeof(bs->filename), filename);
bellard83f64092006-08-01 16:21:11 +0000347 if (flags & BDRV_O_FILE) {
348 drv = find_protocol(filename);
bellardea2384d2004-08-01 21:59:26 +0000349 if (!drv)
bellard83f64092006-08-01 16:21:11 +0000350 return -ENOENT;
351 } else {
352 if (!drv) {
353 drv = find_image_format(filename);
354 if (!drv)
355 return -1;
356 }
bellardea2384d2004-08-01 21:59:26 +0000357 }
358 bs->drv = drv;
359 bs->opaque = qemu_mallocz(drv->instance_size);
360 if (bs->opaque == NULL && drv->instance_size > 0)
361 return -1;
bellard83f64092006-08-01 16:21:11 +0000362 /* Note: for compatibility, we open disk image files as RDWR, and
363 RDONLY as fallback */
364 if (!(flags & BDRV_O_FILE))
365 open_flags = BDRV_O_RDWR;
366 else
367 open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
368 ret = drv->bdrv_open(bs, filename, open_flags);
369 if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
370 ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
371 bs->read_only = 1;
372 }
bellardea2384d2004-08-01 21:59:26 +0000373 if (ret < 0) {
374 qemu_free(bs->opaque);
bellard6b21b972006-08-23 21:14:37 +0000375 bs->opaque = NULL;
376 bs->drv = NULL;
bellard83f64092006-08-01 16:21:11 +0000377 return ret;
bellardea2384d2004-08-01 21:59:26 +0000378 }
bellardd15a7712006-08-06 13:35:09 +0000379 if (drv->bdrv_getlength) {
380 bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
381 }
bellardea2384d2004-08-01 21:59:26 +0000382#ifndef _WIN32
383 if (bs->is_temporary) {
384 unlink(filename);
385 }
386#endif
bellard83f64092006-08-01 16:21:11 +0000387 if (bs->backing_file[0] != '\0') {
bellardea2384d2004-08-01 21:59:26 +0000388 /* if there is a backing file, use it */
389 bs->backing_hd = bdrv_new("");
390 if (!bs->backing_hd) {
391 fail:
392 bdrv_close(bs);
bellard6b21b972006-08-23 21:14:37 +0000393 return -ENOMEM;
bellardea2384d2004-08-01 21:59:26 +0000394 }
bellard83f64092006-08-01 16:21:11 +0000395 path_combine(backing_filename, sizeof(backing_filename),
396 filename, bs->backing_file);
397 if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
bellardea2384d2004-08-01 21:59:26 +0000398 goto fail;
399 }
400
bellardb3380822004-03-14 21:38:54 +0000401 /* call the change callback */
bellard19cb3732006-08-19 11:45:59 +0000402 bs->media_changed = 1;
bellardb3380822004-03-14 21:38:54 +0000403 if (bs->change_cb)
404 bs->change_cb(bs->change_opaque);
405
406 return 0;
bellardfc01f7e2003-06-30 10:03:06 +0000407}
408
409void bdrv_close(BlockDriverState *bs)
410{
bellard19cb3732006-08-19 11:45:59 +0000411 if (bs->drv) {
bellardea2384d2004-08-01 21:59:26 +0000412 if (bs->backing_hd)
413 bdrv_delete(bs->backing_hd);
414 bs->drv->bdrv_close(bs);
415 qemu_free(bs->opaque);
416#ifdef _WIN32
417 if (bs->is_temporary) {
418 unlink(bs->filename);
419 }
bellard67b915a2004-03-31 23:37:16 +0000420#endif
bellardea2384d2004-08-01 21:59:26 +0000421 bs->opaque = NULL;
422 bs->drv = NULL;
bellardb3380822004-03-14 21:38:54 +0000423
424 /* call the change callback */
bellard19cb3732006-08-19 11:45:59 +0000425 bs->media_changed = 1;
bellardb3380822004-03-14 21:38:54 +0000426 if (bs->change_cb)
427 bs->change_cb(bs->change_opaque);
428 }
429}
430
431void bdrv_delete(BlockDriverState *bs)
432{
bellardea2384d2004-08-01 21:59:26 +0000433 /* XXX: remove the driver list */
bellardb3380822004-03-14 21:38:54 +0000434 bdrv_close(bs);
435 qemu_free(bs);
bellardfc01f7e2003-06-30 10:03:06 +0000436}
437
bellard33e39632003-07-06 17:15:21 +0000438/* commit COW file into the raw image */
439int bdrv_commit(BlockDriverState *bs)
440{
bellard19cb3732006-08-19 11:45:59 +0000441 BlockDriver *drv = bs->drv;
bellard83f64092006-08-01 16:21:11 +0000442 int64_t i, total_sectors;
bellardea2384d2004-08-01 21:59:26 +0000443 int n, j;
444 unsigned char sector[512];
bellard33e39632003-07-06 17:15:21 +0000445
bellard19cb3732006-08-19 11:45:59 +0000446 if (!drv)
447 return -ENOMEDIUM;
bellard33e39632003-07-06 17:15:21 +0000448
449 if (bs->read_only) {
bellardea2384d2004-08-01 21:59:26 +0000450 return -EACCES;
bellard33e39632003-07-06 17:15:21 +0000451 }
452
bellardea2384d2004-08-01 21:59:26 +0000453 if (!bs->backing_hd) {
454 return -ENOTSUP;
bellard33e39632003-07-06 17:15:21 +0000455 }
bellardea2384d2004-08-01 21:59:26 +0000456
bellard83f64092006-08-01 16:21:11 +0000457 total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
458 for (i = 0; i < total_sectors;) {
bellard19cb3732006-08-19 11:45:59 +0000459 if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
bellardea2384d2004-08-01 21:59:26 +0000460 for(j = 0; j < n; j++) {
461 if (bdrv_read(bs, i, sector, 1) != 0) {
462 return -EIO;
463 }
464
465 if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
466 return -EIO;
467 }
468 i++;
469 }
470 } else {
471 i += n;
472 }
473 }
bellard95389c82005-12-18 18:28:15 +0000474
bellard19cb3732006-08-19 11:45:59 +0000475 if (drv->bdrv_make_empty)
476 return drv->bdrv_make_empty(bs);
bellard95389c82005-12-18 18:28:15 +0000477
bellard33e39632003-07-06 17:15:21 +0000478 return 0;
479}
480
bellard19cb3732006-08-19 11:45:59 +0000481/* return < 0 if error. See bdrv_write() for the return codes */
bellardfc01f7e2003-06-30 10:03:06 +0000482int bdrv_read(BlockDriverState *bs, int64_t sector_num,
483 uint8_t *buf, int nb_sectors)
484{
bellardea2384d2004-08-01 21:59:26 +0000485 BlockDriver *drv = bs->drv;
486
bellard19cb3732006-08-19 11:45:59 +0000487 if (!drv)
488 return -ENOMEDIUM;
bellardb3380822004-03-14 21:38:54 +0000489
bellard83f64092006-08-01 16:21:11 +0000490 if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
bellardcf989512004-02-16 21:56:36 +0000491 memcpy(buf, bs->boot_sector_data, 512);
bellard83f64092006-08-01 16:21:11 +0000492 sector_num++;
493 nb_sectors--;
494 buf += 512;
495 if (nb_sectors == 0)
496 return 0;
bellard33e39632003-07-06 17:15:21 +0000497 }
bellard83f64092006-08-01 16:21:11 +0000498 if (drv->bdrv_pread) {
499 int ret, len;
500 len = nb_sectors * 512;
501 ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
502 if (ret < 0)
503 return ret;
504 else if (ret != len)
bellard19cb3732006-08-19 11:45:59 +0000505 return -EINVAL;
bellard83f64092006-08-01 16:21:11 +0000506 else
507 return 0;
508 } else {
509 return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
510 }
bellardfc01f7e2003-06-30 10:03:06 +0000511}
512
bellard19cb3732006-08-19 11:45:59 +0000513/* Return < 0 if error. Important errors are:
514 -EIO generic I/O error (may happen for all errors)
515 -ENOMEDIUM No media inserted.
516 -EINVAL Invalid sector number or nb_sectors
517 -EACCES Trying to write a read-only device
518*/
bellardfc01f7e2003-06-30 10:03:06 +0000519int bdrv_write(BlockDriverState *bs, int64_t sector_num,
520 const uint8_t *buf, int nb_sectors)
521{
bellard83f64092006-08-01 16:21:11 +0000522 BlockDriver *drv = bs->drv;
bellard19cb3732006-08-19 11:45:59 +0000523 if (!bs->drv)
524 return -ENOMEDIUM;
bellard0849bf02003-06-30 23:17:31 +0000525 if (bs->read_only)
bellard19cb3732006-08-19 11:45:59 +0000526 return -EACCES;
bellard79639d42005-11-26 10:58:41 +0000527 if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
528 memcpy(bs->boot_sector_data, buf, 512);
529 }
bellard83f64092006-08-01 16:21:11 +0000530 if (drv->bdrv_pwrite) {
531 int ret, len;
532 len = nb_sectors * 512;
533 ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
534 if (ret < 0)
535 return ret;
536 else if (ret != len)
537 return -EIO;
538 else
539 return 0;
540 } else {
541 return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
542 }
543}
544
bellard83f64092006-08-01 16:21:11 +0000545static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
bellardfaea38e2006-08-05 21:31:00 +0000546 uint8_t *buf, int count1)
bellard83f64092006-08-01 16:21:11 +0000547{
bellard83f64092006-08-01 16:21:11 +0000548 uint8_t tmp_buf[SECTOR_SIZE];
549 int len, nb_sectors, count;
550 int64_t sector_num;
551
552 count = count1;
553 /* first read to align to sector start */
554 len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
555 if (len > count)
556 len = count;
557 sector_num = offset >> SECTOR_BITS;
558 if (len > 0) {
559 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
560 return -EIO;
561 memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
562 count -= len;
563 if (count == 0)
564 return count1;
565 sector_num++;
566 buf += len;
567 }
568
569 /* read the sectors "in place" */
570 nb_sectors = count >> SECTOR_BITS;
571 if (nb_sectors > 0) {
572 if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
573 return -EIO;
574 sector_num += nb_sectors;
575 len = nb_sectors << SECTOR_BITS;
576 buf += len;
577 count -= len;
578 }
579
580 /* add data from the last sector */
581 if (count > 0) {
582 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
583 return -EIO;
584 memcpy(buf, tmp_buf, count);
585 }
586 return count1;
587}
588
589static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
bellardfaea38e2006-08-05 21:31:00 +0000590 const uint8_t *buf, int count1)
bellard83f64092006-08-01 16:21:11 +0000591{
bellard83f64092006-08-01 16:21:11 +0000592 uint8_t tmp_buf[SECTOR_SIZE];
593 int len, nb_sectors, count;
594 int64_t sector_num;
595
596 count = count1;
597 /* first write to align to sector start */
598 len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
599 if (len > count)
600 len = count;
601 sector_num = offset >> SECTOR_BITS;
602 if (len > 0) {
603 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
604 return -EIO;
605 memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
606 if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
607 return -EIO;
608 count -= len;
609 if (count == 0)
610 return count1;
611 sector_num++;
612 buf += len;
613 }
614
615 /* write the sectors "in place" */
616 nb_sectors = count >> SECTOR_BITS;
617 if (nb_sectors > 0) {
618 if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
619 return -EIO;
620 sector_num += nb_sectors;
621 len = nb_sectors << SECTOR_BITS;
622 buf += len;
623 count -= len;
624 }
625
626 /* add data from the last sector */
627 if (count > 0) {
628 if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
629 return -EIO;
630 memcpy(tmp_buf, buf, count);
631 if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
632 return -EIO;
633 }
634 return count1;
635}
bellard83f64092006-08-01 16:21:11 +0000636
637/**
638 * Read with byte offsets (needed only for file protocols)
639 */
640int bdrv_pread(BlockDriverState *bs, int64_t offset,
641 void *buf1, int count1)
642{
643 BlockDriver *drv = bs->drv;
644
645 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000646 return -ENOMEDIUM;
bellard83f64092006-08-01 16:21:11 +0000647 if (!drv->bdrv_pread)
bellardfaea38e2006-08-05 21:31:00 +0000648 return bdrv_pread_em(bs, offset, buf1, count1);
bellard83f64092006-08-01 16:21:11 +0000649 return drv->bdrv_pread(bs, offset, buf1, count1);
650}
651
652/**
653 * Write with byte offsets (needed only for file protocols)
654 */
655int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
656 const void *buf1, int count1)
657{
658 BlockDriver *drv = bs->drv;
659
660 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000661 return -ENOMEDIUM;
bellard83f64092006-08-01 16:21:11 +0000662 if (!drv->bdrv_pwrite)
bellardfaea38e2006-08-05 21:31:00 +0000663 return bdrv_pwrite_em(bs, offset, buf1, count1);
bellard83f64092006-08-01 16:21:11 +0000664 return drv->bdrv_pwrite(bs, offset, buf1, count1);
665}
666
667/**
668 * Truncate file to 'offset' bytes (needed only for file protocols)
669 */
670int bdrv_truncate(BlockDriverState *bs, int64_t offset)
671{
672 BlockDriver *drv = bs->drv;
673 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000674 return -ENOMEDIUM;
bellard83f64092006-08-01 16:21:11 +0000675 if (!drv->bdrv_truncate)
676 return -ENOTSUP;
677 return drv->bdrv_truncate(bs, offset);
678}
679
680/**
681 * Length of a file in bytes. Return < 0 if error or unknown.
682 */
683int64_t bdrv_getlength(BlockDriverState *bs)
684{
685 BlockDriver *drv = bs->drv;
686 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000687 return -ENOMEDIUM;
bellard83f64092006-08-01 16:21:11 +0000688 if (!drv->bdrv_getlength) {
689 /* legacy mode */
690 return bs->total_sectors * SECTOR_SIZE;
691 }
692 return drv->bdrv_getlength(bs);
bellardfc01f7e2003-06-30 10:03:06 +0000693}
694
bellard19cb3732006-08-19 11:45:59 +0000695/* return 0 as number of sectors if no device present or error */
bellardfc01f7e2003-06-30 10:03:06 +0000696void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
697{
bellard19cb3732006-08-19 11:45:59 +0000698 int64_t length;
699 length = bdrv_getlength(bs);
700 if (length < 0)
701 length = 0;
702 else
703 length = length >> SECTOR_BITS;
704 *nb_sectors_ptr = length;
bellardfc01f7e2003-06-30 10:03:06 +0000705}
bellardcf989512004-02-16 21:56:36 +0000706
707/* force a given boot sector. */
708void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
709{
710 bs->boot_sector_enabled = 1;
711 if (size > 512)
712 size = 512;
713 memcpy(bs->boot_sector_data, data, size);
714 memset(bs->boot_sector_data + size, 0, 512 - size);
715}
bellardb3380822004-03-14 21:38:54 +0000716
717void bdrv_set_geometry_hint(BlockDriverState *bs,
718 int cyls, int heads, int secs)
719{
720 bs->cyls = cyls;
721 bs->heads = heads;
722 bs->secs = secs;
723}
724
725void bdrv_set_type_hint(BlockDriverState *bs, int type)
726{
727 bs->type = type;
728 bs->removable = ((type == BDRV_TYPE_CDROM ||
729 type == BDRV_TYPE_FLOPPY));
730}
731
bellard46d47672004-11-16 01:45:27 +0000732void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
733{
734 bs->translation = translation;
735}
736
bellardb3380822004-03-14 21:38:54 +0000737void bdrv_get_geometry_hint(BlockDriverState *bs,
738 int *pcyls, int *pheads, int *psecs)
739{
740 *pcyls = bs->cyls;
741 *pheads = bs->heads;
742 *psecs = bs->secs;
743}
744
745int bdrv_get_type_hint(BlockDriverState *bs)
746{
747 return bs->type;
748}
749
bellard46d47672004-11-16 01:45:27 +0000750int bdrv_get_translation_hint(BlockDriverState *bs)
751{
752 return bs->translation;
753}
754
bellardb3380822004-03-14 21:38:54 +0000755int bdrv_is_removable(BlockDriverState *bs)
756{
757 return bs->removable;
758}
759
760int bdrv_is_read_only(BlockDriverState *bs)
761{
762 return bs->read_only;
763}
764
bellard19cb3732006-08-19 11:45:59 +0000765/* XXX: no longer used */
bellardb3380822004-03-14 21:38:54 +0000766void bdrv_set_change_cb(BlockDriverState *bs,
767 void (*change_cb)(void *opaque), void *opaque)
768{
769 bs->change_cb = change_cb;
770 bs->change_opaque = opaque;
771}
772
bellardea2384d2004-08-01 21:59:26 +0000773int bdrv_is_encrypted(BlockDriverState *bs)
774{
775 if (bs->backing_hd && bs->backing_hd->encrypted)
776 return 1;
777 return bs->encrypted;
778}
779
780int bdrv_set_key(BlockDriverState *bs, const char *key)
781{
782 int ret;
783 if (bs->backing_hd && bs->backing_hd->encrypted) {
784 ret = bdrv_set_key(bs->backing_hd, key);
785 if (ret < 0)
786 return ret;
787 if (!bs->encrypted)
788 return 0;
789 }
790 if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
791 return -1;
792 return bs->drv->bdrv_set_key(bs, key);
793}
794
795void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
796{
bellard19cb3732006-08-19 11:45:59 +0000797 if (!bs->drv) {
bellardea2384d2004-08-01 21:59:26 +0000798 buf[0] = '\0';
799 } else {
800 pstrcpy(buf, buf_size, bs->drv->format_name);
801 }
802}
803
804void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
805 void *opaque)
806{
807 BlockDriver *drv;
808
809 for (drv = first_drv; drv != NULL; drv = drv->next) {
810 it(opaque, drv->format_name);
811 }
812}
813
bellardb3380822004-03-14 21:38:54 +0000814BlockDriverState *bdrv_find(const char *name)
815{
816 BlockDriverState *bs;
817
818 for (bs = bdrv_first; bs != NULL; bs = bs->next) {
819 if (!strcmp(name, bs->device_name))
820 return bs;
821 }
822 return NULL;
823}
824
bellard81d09122004-07-14 17:21:37 +0000825void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
826{
827 BlockDriverState *bs;
828
829 for (bs = bdrv_first; bs != NULL; bs = bs->next) {
830 it(opaque, bs->device_name);
831 }
832}
833
bellardea2384d2004-08-01 21:59:26 +0000834const char *bdrv_get_device_name(BlockDriverState *bs)
835{
836 return bs->device_name;
837}
838
pbrook7a6cba62006-06-04 11:39:07 +0000839void bdrv_flush(BlockDriverState *bs)
840{
841 if (bs->drv->bdrv_flush)
842 bs->drv->bdrv_flush(bs);
843 if (bs->backing_hd)
844 bdrv_flush(bs->backing_hd);
845}
846
bellardb3380822004-03-14 21:38:54 +0000847void bdrv_info(void)
848{
849 BlockDriverState *bs;
850
851 for (bs = bdrv_first; bs != NULL; bs = bs->next) {
852 term_printf("%s:", bs->device_name);
853 term_printf(" type=");
854 switch(bs->type) {
855 case BDRV_TYPE_HD:
856 term_printf("hd");
857 break;
858 case BDRV_TYPE_CDROM:
859 term_printf("cdrom");
860 break;
861 case BDRV_TYPE_FLOPPY:
862 term_printf("floppy");
863 break;
864 }
865 term_printf(" removable=%d", bs->removable);
866 if (bs->removable) {
867 term_printf(" locked=%d", bs->locked);
868 }
bellard19cb3732006-08-19 11:45:59 +0000869 if (bs->drv) {
bellardb3380822004-03-14 21:38:54 +0000870 term_printf(" file=%s", bs->filename);
bellardea2384d2004-08-01 21:59:26 +0000871 if (bs->backing_file[0] != '\0')
872 term_printf(" backing_file=%s", bs->backing_file);
bellardb3380822004-03-14 21:38:54 +0000873 term_printf(" ro=%d", bs->read_only);
bellardea2384d2004-08-01 21:59:26 +0000874 term_printf(" drv=%s", bs->drv->format_name);
875 if (bs->encrypted)
876 term_printf(" encrypted");
bellardb3380822004-03-14 21:38:54 +0000877 } else {
878 term_printf(" [not inserted]");
879 }
880 term_printf("\n");
881 }
882}
bellardea2384d2004-08-01 21:59:26 +0000883
bellard83f64092006-08-01 16:21:11 +0000884void bdrv_get_backing_filename(BlockDriverState *bs,
885 char *filename, int filename_size)
bellardea2384d2004-08-01 21:59:26 +0000886{
bellard83f64092006-08-01 16:21:11 +0000887 if (!bs->backing_hd) {
888 pstrcpy(filename, filename_size, "");
889 } else {
890 pstrcpy(filename, filename_size, bs->backing_file);
891 }
bellardea2384d2004-08-01 21:59:26 +0000892}
893
bellardfaea38e2006-08-05 21:31:00 +0000894int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
895 const uint8_t *buf, int nb_sectors)
896{
897 BlockDriver *drv = bs->drv;
898 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000899 return -ENOMEDIUM;
bellardfaea38e2006-08-05 21:31:00 +0000900 if (!drv->bdrv_write_compressed)
901 return -ENOTSUP;
902 return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
903}
904
905int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
906{
907 BlockDriver *drv = bs->drv;
908 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000909 return -ENOMEDIUM;
bellardfaea38e2006-08-05 21:31:00 +0000910 if (!drv->bdrv_get_info)
911 return -ENOTSUP;
912 memset(bdi, 0, sizeof(*bdi));
913 return drv->bdrv_get_info(bs, bdi);
914}
915
916/**************************************************************/
917/* handling of snapshots */
918
919int bdrv_snapshot_create(BlockDriverState *bs,
920 QEMUSnapshotInfo *sn_info)
921{
922 BlockDriver *drv = bs->drv;
923 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000924 return -ENOMEDIUM;
bellardfaea38e2006-08-05 21:31:00 +0000925 if (!drv->bdrv_snapshot_create)
926 return -ENOTSUP;
927 return drv->bdrv_snapshot_create(bs, sn_info);
928}
929
930int bdrv_snapshot_goto(BlockDriverState *bs,
931 const char *snapshot_id)
932{
933 BlockDriver *drv = bs->drv;
934 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000935 return -ENOMEDIUM;
bellardfaea38e2006-08-05 21:31:00 +0000936 if (!drv->bdrv_snapshot_goto)
937 return -ENOTSUP;
938 return drv->bdrv_snapshot_goto(bs, snapshot_id);
939}
940
941int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
942{
943 BlockDriver *drv = bs->drv;
944 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000945 return -ENOMEDIUM;
bellardfaea38e2006-08-05 21:31:00 +0000946 if (!drv->bdrv_snapshot_delete)
947 return -ENOTSUP;
948 return drv->bdrv_snapshot_delete(bs, snapshot_id);
949}
950
951int bdrv_snapshot_list(BlockDriverState *bs,
952 QEMUSnapshotInfo **psn_info)
953{
954 BlockDriver *drv = bs->drv;
955 if (!drv)
bellard19cb3732006-08-19 11:45:59 +0000956 return -ENOMEDIUM;
bellardfaea38e2006-08-05 21:31:00 +0000957 if (!drv->bdrv_snapshot_list)
958 return -ENOTSUP;
959 return drv->bdrv_snapshot_list(bs, psn_info);
960}
961
962#define NB_SUFFIXES 4
963
964char *get_human_readable_size(char *buf, int buf_size, int64_t size)
965{
966 static const char suffixes[NB_SUFFIXES] = "KMGT";
967 int64_t base;
968 int i;
969
970 if (size <= 999) {
971 snprintf(buf, buf_size, "%" PRId64, size);
972 } else {
973 base = 1024;
974 for(i = 0; i < NB_SUFFIXES; i++) {
975 if (size < (10 * base)) {
976 snprintf(buf, buf_size, "%0.1f%c",
977 (double)size / base,
978 suffixes[i]);
979 break;
980 } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
981 snprintf(buf, buf_size, "%" PRId64 "%c",
982 ((size + (base >> 1)) / base),
983 suffixes[i]);
984 break;
985 }
986 base = base * 1024;
987 }
988 }
989 return buf;
990}
991
992char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
993{
994 char buf1[128], date_buf[128], clock_buf[128];
995 struct tm tm;
996 time_t ti;
997 int64_t secs;
998
999 if (!sn) {
1000 snprintf(buf, buf_size,
1001 "%-10s%-20s%7s%20s%15s",
1002 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
1003 } else {
1004 ti = sn->date_sec;
pbrookce1a14d2006-08-07 02:38:06 +00001005#ifndef _WIN32
bellardfaea38e2006-08-05 21:31:00 +00001006 localtime_r(&ti, &tm);
pbrookce1a14d2006-08-07 02:38:06 +00001007#endif
bellardfaea38e2006-08-05 21:31:00 +00001008 strftime(date_buf, sizeof(date_buf),
1009 "%Y-%m-%d %H:%M:%S", &tm);
1010 secs = sn->vm_clock_nsec / 1000000000;
1011 snprintf(clock_buf, sizeof(clock_buf),
1012 "%02d:%02d:%02d.%03d",
1013 (int)(secs / 3600),
1014 (int)((secs / 60) % 60),
1015 (int)(secs % 60),
1016 (int)((sn->vm_clock_nsec / 1000000) % 1000));
1017 snprintf(buf, buf_size,
1018 "%-10s%-20s%7s%20s%15s",
1019 sn->id_str, sn->name,
1020 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
1021 date_buf,
1022 clock_buf);
1023 }
1024 return buf;
1025}
1026
bellardea2384d2004-08-01 21:59:26 +00001027
bellard83f64092006-08-01 16:21:11 +00001028/**************************************************************/
1029/* async I/Os */
1030
pbrookce1a14d2006-08-07 02:38:06 +00001031BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
1032 uint8_t *buf, int nb_sectors,
1033 BlockDriverCompletionFunc *cb, void *opaque)
bellard83f64092006-08-01 16:21:11 +00001034{
1035 BlockDriver *drv = bs->drv;
bellard83f64092006-08-01 16:21:11 +00001036
bellard19cb3732006-08-19 11:45:59 +00001037 if (!drv)
pbrookce1a14d2006-08-07 02:38:06 +00001038 return NULL;
bellard83f64092006-08-01 16:21:11 +00001039
1040 /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
1041 if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1042 memcpy(buf, bs->boot_sector_data, 512);
1043 sector_num++;
1044 nb_sectors--;
1045 buf += 512;
1046 }
1047
pbrookce1a14d2006-08-07 02:38:06 +00001048 return drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
bellard83f64092006-08-01 16:21:11 +00001049}
1050
pbrookce1a14d2006-08-07 02:38:06 +00001051BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
1052 const uint8_t *buf, int nb_sectors,
1053 BlockDriverCompletionFunc *cb, void *opaque)
bellard83f64092006-08-01 16:21:11 +00001054{
bellard83f64092006-08-01 16:21:11 +00001055 BlockDriver *drv = bs->drv;
1056
bellard19cb3732006-08-19 11:45:59 +00001057 if (!drv)
pbrookce1a14d2006-08-07 02:38:06 +00001058 return NULL;
bellard83f64092006-08-01 16:21:11 +00001059 if (bs->read_only)
pbrookce1a14d2006-08-07 02:38:06 +00001060 return NULL;
bellard83f64092006-08-01 16:21:11 +00001061 if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1062 memcpy(bs->boot_sector_data, buf, 512);
bellardea2384d2004-08-01 21:59:26 +00001063 }
bellard83f64092006-08-01 16:21:11 +00001064
pbrookce1a14d2006-08-07 02:38:06 +00001065 return drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
bellard83f64092006-08-01 16:21:11 +00001066}
1067
1068void bdrv_aio_cancel(BlockDriverAIOCB *acb)
pbrookce1a14d2006-08-07 02:38:06 +00001069{
1070 BlockDriver *drv = acb->bs->drv;
bellard83f64092006-08-01 16:21:11 +00001071
1072 drv->bdrv_aio_cancel(acb);
bellard83f64092006-08-01 16:21:11 +00001073}
1074
pbrookce1a14d2006-08-07 02:38:06 +00001075
bellard83f64092006-08-01 16:21:11 +00001076/**************************************************************/
1077/* async block device emulation */
1078
1079#ifdef QEMU_TOOL
pbrookce1a14d2006-08-07 02:38:06 +00001080static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1081 int64_t sector_num, uint8_t *buf, int nb_sectors,
1082 BlockDriverCompletionFunc *cb, void *opaque)
bellardea2384d2004-08-01 21:59:26 +00001083{
bellardea2384d2004-08-01 21:59:26 +00001084 int ret;
pbrookce1a14d2006-08-07 02:38:06 +00001085 ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1086 cb(opaque, ret);
1087 return NULL;
bellardea2384d2004-08-01 21:59:26 +00001088}
1089
pbrookce1a14d2006-08-07 02:38:06 +00001090static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1091 int64_t sector_num, const uint8_t *buf, int nb_sectors,
1092 BlockDriverCompletionFunc *cb, void *opaque)
bellardea2384d2004-08-01 21:59:26 +00001093{
bellardea2384d2004-08-01 21:59:26 +00001094 int ret;
pbrookce1a14d2006-08-07 02:38:06 +00001095 ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1096 cb(opaque, ret);
1097 return NULL;
bellardea2384d2004-08-01 21:59:26 +00001098}
1099
bellard83f64092006-08-01 16:21:11 +00001100static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
bellardea2384d2004-08-01 21:59:26 +00001101{
bellardea2384d2004-08-01 21:59:26 +00001102}
bellardbeac80c2006-06-26 20:08:57 +00001103#else
bellard83f64092006-08-01 16:21:11 +00001104static void bdrv_aio_bh_cb(void *opaque)
bellardbeac80c2006-06-26 20:08:57 +00001105{
pbrookce1a14d2006-08-07 02:38:06 +00001106 BlockDriverAIOCBSync *acb = opaque;
1107 acb->common.cb(acb->common.opaque, acb->ret);
1108 qemu_aio_release(acb);
bellardbeac80c2006-06-26 20:08:57 +00001109}
bellardbeac80c2006-06-26 20:08:57 +00001110
pbrookce1a14d2006-08-07 02:38:06 +00001111static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1112 int64_t sector_num, uint8_t *buf, int nb_sectors,
1113 BlockDriverCompletionFunc *cb, void *opaque)
bellardea2384d2004-08-01 21:59:26 +00001114{
pbrookce1a14d2006-08-07 02:38:06 +00001115 BlockDriverAIOCBSync *acb;
bellard83f64092006-08-01 16:21:11 +00001116 int ret;
pbrookce1a14d2006-08-07 02:38:06 +00001117
1118 acb = qemu_aio_get(bs, cb, opaque);
1119 if (!acb->bh)
1120 acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1121 ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1122 acb->ret = ret;
1123 qemu_bh_schedule(acb->bh);
1124 return &acb->common;
pbrook7a6cba62006-06-04 11:39:07 +00001125}
1126
pbrookce1a14d2006-08-07 02:38:06 +00001127static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1128 int64_t sector_num, const uint8_t *buf, int nb_sectors,
1129 BlockDriverCompletionFunc *cb, void *opaque)
bellard83f64092006-08-01 16:21:11 +00001130{
pbrookce1a14d2006-08-07 02:38:06 +00001131 BlockDriverAIOCBSync *acb;
bellard83f64092006-08-01 16:21:11 +00001132 int ret;
pbrookce1a14d2006-08-07 02:38:06 +00001133
1134 acb = qemu_aio_get(bs, cb, opaque);
1135 if (!acb->bh)
1136 acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1137 ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1138 acb->ret = ret;
1139 qemu_bh_schedule(acb->bh);
1140 return &acb->common;
bellard83f64092006-08-01 16:21:11 +00001141}
1142
pbrookce1a14d2006-08-07 02:38:06 +00001143static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
bellard83f64092006-08-01 16:21:11 +00001144{
pbrookce1a14d2006-08-07 02:38:06 +00001145 BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
1146 qemu_bh_cancel(acb->bh);
1147 qemu_aio_release(acb);
bellard83f64092006-08-01 16:21:11 +00001148}
1149#endif /* !QEMU_TOOL */
1150
1151/**************************************************************/
1152/* sync block device emulation */
1153
1154static void bdrv_rw_em_cb(void *opaque, int ret)
1155{
1156 *(int *)opaque = ret;
1157}
1158
1159#define NOT_DONE 0x7fffffff
1160
1161static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1162 uint8_t *buf, int nb_sectors)
1163{
pbrookce1a14d2006-08-07 02:38:06 +00001164 int async_ret;
1165 BlockDriverAIOCB *acb;
bellard83f64092006-08-01 16:21:11 +00001166
bellard83f64092006-08-01 16:21:11 +00001167 async_ret = NOT_DONE;
1168 qemu_aio_wait_start();
pbrookce1a14d2006-08-07 02:38:06 +00001169 acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
bellard83f64092006-08-01 16:21:11 +00001170 bdrv_rw_em_cb, &async_ret);
pbrookce1a14d2006-08-07 02:38:06 +00001171 if (acb == NULL) {
bellard83f64092006-08-01 16:21:11 +00001172 qemu_aio_wait_end();
pbrookce1a14d2006-08-07 02:38:06 +00001173 return -1;
bellard83f64092006-08-01 16:21:11 +00001174 }
1175 while (async_ret == NOT_DONE) {
1176 qemu_aio_wait();
1177 }
1178 qemu_aio_wait_end();
1179 return async_ret;
1180}
1181
1182static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
1183 const uint8_t *buf, int nb_sectors)
1184{
pbrookce1a14d2006-08-07 02:38:06 +00001185 int async_ret;
1186 BlockDriverAIOCB *acb;
bellard83f64092006-08-01 16:21:11 +00001187
bellard83f64092006-08-01 16:21:11 +00001188 async_ret = NOT_DONE;
1189 qemu_aio_wait_start();
pbrookce1a14d2006-08-07 02:38:06 +00001190 acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
bellard83f64092006-08-01 16:21:11 +00001191 bdrv_rw_em_cb, &async_ret);
pbrookce1a14d2006-08-07 02:38:06 +00001192 if (acb == NULL) {
bellard83f64092006-08-01 16:21:11 +00001193 qemu_aio_wait_end();
pbrookce1a14d2006-08-07 02:38:06 +00001194 return -1;
bellard83f64092006-08-01 16:21:11 +00001195 }
1196 while (async_ret == NOT_DONE) {
1197 qemu_aio_wait();
1198 }
1199 qemu_aio_wait_end();
1200 return async_ret;
1201}
bellardea2384d2004-08-01 21:59:26 +00001202
1203void bdrv_init(void)
1204{
1205 bdrv_register(&bdrv_raw);
bellard19cb3732006-08-19 11:45:59 +00001206 bdrv_register(&bdrv_host_device);
bellardea2384d2004-08-01 21:59:26 +00001207#ifndef _WIN32
1208 bdrv_register(&bdrv_cow);
1209#endif
1210 bdrv_register(&bdrv_qcow);
1211 bdrv_register(&bdrv_vmdk);
bellard3c565212004-09-29 21:29:14 +00001212 bdrv_register(&bdrv_cloop);
bellard585d0ed2004-12-12 11:24:44 +00001213 bdrv_register(&bdrv_dmg);
bellarda8753c32005-04-26 21:34:00 +00001214 bdrv_register(&bdrv_bochs);
bellard6a0f9e82005-04-27 20:17:58 +00001215 bdrv_register(&bdrv_vpc);
bellard712e7872005-04-28 21:09:32 +00001216 bdrv_register(&bdrv_vvfat);
bellardfaea38e2006-08-05 21:31:00 +00001217 bdrv_register(&bdrv_qcow2);
bellardea2384d2004-08-01 21:59:26 +00001218}
pbrookce1a14d2006-08-07 02:38:06 +00001219
1220void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
1221 void *opaque)
1222{
1223 BlockDriver *drv;
1224 BlockDriverAIOCB *acb;
1225
1226 drv = bs->drv;
1227 if (drv->free_aiocb) {
1228 acb = drv->free_aiocb;
1229 drv->free_aiocb = acb->next;
1230 } else {
1231 acb = qemu_mallocz(drv->aiocb_size);
1232 if (!acb)
1233 return NULL;
1234 }
1235 acb->bs = bs;
1236 acb->cb = cb;
1237 acb->opaque = opaque;
1238 return acb;
1239}
1240
1241void qemu_aio_release(void *p)
1242{
1243 BlockDriverAIOCB *acb = p;
1244 BlockDriver *drv = acb->bs->drv;
1245 acb->next = drv->free_aiocb;
1246 drv->free_aiocb = acb;
1247}
bellard19cb3732006-08-19 11:45:59 +00001248
1249/**************************************************************/
1250/* removable device support */
1251
1252/**
1253 * Return TRUE if the media is present
1254 */
1255int bdrv_is_inserted(BlockDriverState *bs)
1256{
1257 BlockDriver *drv = bs->drv;
1258 int ret;
1259 if (!drv)
1260 return 0;
1261 if (!drv->bdrv_is_inserted)
1262 return 1;
1263 ret = drv->bdrv_is_inserted(bs);
1264 return ret;
1265}
1266
1267/**
1268 * Return TRUE if the media changed since the last call to this
1269 * function. It is currently only used for floppy disks
1270 */
1271int bdrv_media_changed(BlockDriverState *bs)
1272{
1273 BlockDriver *drv = bs->drv;
1274 int ret;
1275
1276 if (!drv || !drv->bdrv_media_changed)
1277 ret = -ENOTSUP;
1278 else
1279 ret = drv->bdrv_media_changed(bs);
1280 if (ret == -ENOTSUP)
1281 ret = bs->media_changed;
1282 bs->media_changed = 0;
1283 return ret;
1284}
1285
1286/**
1287 * If eject_flag is TRUE, eject the media. Otherwise, close the tray
1288 */
1289void bdrv_eject(BlockDriverState *bs, int eject_flag)
1290{
1291 BlockDriver *drv = bs->drv;
1292 int ret;
1293
1294 if (!drv || !drv->bdrv_eject) {
1295 ret = -ENOTSUP;
1296 } else {
1297 ret = drv->bdrv_eject(bs, eject_flag);
1298 }
1299 if (ret == -ENOTSUP) {
1300 if (eject_flag)
1301 bdrv_close(bs);
1302 }
1303}
1304
1305int bdrv_is_locked(BlockDriverState *bs)
1306{
1307 return bs->locked;
1308}
1309
1310/**
1311 * Lock or unlock the media (if it is locked, the user won't be able
1312 * to eject it manually).
1313 */
1314void bdrv_set_locked(BlockDriverState *bs, int locked)
1315{
1316 BlockDriver *drv = bs->drv;
1317
1318 bs->locked = locked;
1319 if (drv && drv->bdrv_set_locked) {
1320 drv->bdrv_set_locked(bs, locked);
1321 }
1322}