Statistics
| Branch: | Revision:

root / block.c @ 83f64091

History | View | Annotate | Download (27.6 kB)

1 fc01f7e7 bellard
/*
2 fc01f7e7 bellard
 * QEMU System Emulator block driver
3 fc01f7e7 bellard
 * 
4 fc01f7e7 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 fc01f7e7 bellard
 * 
6 fc01f7e7 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 fc01f7e7 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 fc01f7e7 bellard
 * in the Software without restriction, including without limitation the rights
9 fc01f7e7 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 fc01f7e7 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 fc01f7e7 bellard
 * furnished to do so, subject to the following conditions:
12 fc01f7e7 bellard
 *
13 fc01f7e7 bellard
 * The above copyright notice and this permission notice shall be included in
14 fc01f7e7 bellard
 * all copies or substantial portions of the Software.
15 fc01f7e7 bellard
 *
16 fc01f7e7 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 fc01f7e7 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 fc01f7e7 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 fc01f7e7 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 fc01f7e7 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 fc01f7e7 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 fc01f7e7 bellard
 * THE SOFTWARE.
23 fc01f7e7 bellard
 */
24 fc01f7e7 bellard
#include "vl.h"
25 ea2384d3 bellard
#include "block_int.h"
26 fc01f7e7 bellard
27 7674e7bf bellard
#ifdef _BSD
28 7674e7bf bellard
#include <sys/types.h>
29 7674e7bf bellard
#include <sys/stat.h>
30 7674e7bf bellard
#include <sys/ioctl.h>
31 7674e7bf bellard
#include <sys/queue.h>
32 7674e7bf bellard
#include <sys/disk.h>
33 7674e7bf bellard
#endif
34 7674e7bf bellard
35 83f64091 bellard
#define SECTOR_BITS 9
36 83f64091 bellard
#define SECTOR_SIZE (1 << SECTOR_BITS)
37 83f64091 bellard
38 83f64091 bellard
static int bdrv_aio_new_em(BlockDriverAIOCB *acb);
39 83f64091 bellard
static int bdrv_aio_read_em(BlockDriverAIOCB *acb, int64_t sector_num,
40 83f64091 bellard
                              uint8_t *buf, int nb_sectors);
41 83f64091 bellard
static int bdrv_aio_write_em(BlockDriverAIOCB *acb, int64_t sector_num,
42 83f64091 bellard
                               const uint8_t *buf, int nb_sectors);
43 83f64091 bellard
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
44 83f64091 bellard
static void bdrv_aio_delete_em(BlockDriverAIOCB *acb);
45 83f64091 bellard
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 
46 83f64091 bellard
                        uint8_t *buf, int nb_sectors);
47 83f64091 bellard
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
48 83f64091 bellard
                         const uint8_t *buf, int nb_sectors);
49 ec530c81 bellard
50 b338082b bellard
static BlockDriverState *bdrv_first;
51 ea2384d3 bellard
static BlockDriver *first_drv;
52 ea2384d3 bellard
53 83f64091 bellard
#ifdef _WIN32
54 83f64091 bellard
#define PATH_SEP '\\'
55 83f64091 bellard
#else
56 83f64091 bellard
#define PATH_SEP '/'
57 83f64091 bellard
#endif
58 3b0d4f61 bellard
59 83f64091 bellard
int path_is_absolute(const char *path)
60 3b0d4f61 bellard
{
61 83f64091 bellard
    const char *p;
62 83f64091 bellard
    p = strchr(path, ':');
63 83f64091 bellard
    if (p)
64 83f64091 bellard
        p++;
65 83f64091 bellard
    else
66 83f64091 bellard
        p = path;
67 83f64091 bellard
    return (*p == PATH_SEP);
68 3b0d4f61 bellard
}
69 3b0d4f61 bellard
70 83f64091 bellard
/* if filename is absolute, just copy it to dest. Otherwise, build a
71 83f64091 bellard
   path to it by considering it is relative to base_path. URL are
72 83f64091 bellard
   supported. */
73 83f64091 bellard
void path_combine(char *dest, int dest_size,
74 83f64091 bellard
                  const char *base_path,
75 83f64091 bellard
                  const char *filename)
76 3b0d4f61 bellard
{
77 83f64091 bellard
    const char *p, *p1;
78 83f64091 bellard
    int len;
79 83f64091 bellard
80 83f64091 bellard
    if (dest_size <= 0)
81 83f64091 bellard
        return;
82 83f64091 bellard
    if (path_is_absolute(filename)) {
83 83f64091 bellard
        pstrcpy(dest, dest_size, filename);
84 83f64091 bellard
    } else {
85 83f64091 bellard
        p = strchr(base_path, ':');
86 83f64091 bellard
        if (p)
87 83f64091 bellard
            p++;
88 83f64091 bellard
        else
89 83f64091 bellard
            p = base_path;
90 83f64091 bellard
        p1 = strrchr(base_path, PATH_SEP);
91 83f64091 bellard
        if (p1)
92 83f64091 bellard
            p1++;
93 83f64091 bellard
        else
94 83f64091 bellard
            p1 = base_path;
95 83f64091 bellard
        if (p1 > p)
96 83f64091 bellard
            p = p1;
97 83f64091 bellard
        len = p - base_path;
98 83f64091 bellard
        if (len > dest_size - 1)
99 83f64091 bellard
            len = dest_size - 1;
100 83f64091 bellard
        memcpy(dest, base_path, len);
101 83f64091 bellard
        dest[len] = '\0';
102 83f64091 bellard
        pstrcat(dest, dest_size, filename);
103 3b0d4f61 bellard
    }
104 3b0d4f61 bellard
}
105 3b0d4f61 bellard
106 3b0d4f61 bellard
107 ea2384d3 bellard
void bdrv_register(BlockDriver *bdrv)
108 ea2384d3 bellard
{
109 83f64091 bellard
    if (!bdrv->bdrv_aio_new) {
110 83f64091 bellard
        /* add AIO emulation layer */
111 83f64091 bellard
        bdrv->bdrv_aio_new = bdrv_aio_new_em;
112 83f64091 bellard
        bdrv->bdrv_aio_read = bdrv_aio_read_em;
113 83f64091 bellard
        bdrv->bdrv_aio_write = bdrv_aio_write_em;
114 83f64091 bellard
        bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
115 83f64091 bellard
        bdrv->bdrv_aio_delete = bdrv_aio_delete_em;
116 83f64091 bellard
    } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
117 83f64091 bellard
        /* add synchronous IO emulation layer */
118 83f64091 bellard
        bdrv->bdrv_read = bdrv_read_em;
119 83f64091 bellard
        bdrv->bdrv_write = bdrv_write_em;
120 83f64091 bellard
    }
121 ea2384d3 bellard
    bdrv->next = first_drv;
122 ea2384d3 bellard
    first_drv = bdrv;
123 ea2384d3 bellard
}
124 b338082b bellard
125 b338082b bellard
/* create a new block device (by default it is empty) */
126 b338082b bellard
BlockDriverState *bdrv_new(const char *device_name)
127 b338082b bellard
{
128 b338082b bellard
    BlockDriverState **pbs, *bs;
129 b338082b bellard
130 b338082b bellard
    bs = qemu_mallocz(sizeof(BlockDriverState));
131 b338082b bellard
    if(!bs)
132 b338082b bellard
        return NULL;
133 b338082b bellard
    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
134 ea2384d3 bellard
    if (device_name[0] != '\0') {
135 ea2384d3 bellard
        /* insert at the end */
136 ea2384d3 bellard
        pbs = &bdrv_first;
137 ea2384d3 bellard
        while (*pbs != NULL)
138 ea2384d3 bellard
            pbs = &(*pbs)->next;
139 ea2384d3 bellard
        *pbs = bs;
140 ea2384d3 bellard
    }
141 b338082b bellard
    return bs;
142 b338082b bellard
}
143 b338082b bellard
144 ea2384d3 bellard
BlockDriver *bdrv_find_format(const char *format_name)
145 ea2384d3 bellard
{
146 ea2384d3 bellard
    BlockDriver *drv1;
147 ea2384d3 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
148 ea2384d3 bellard
        if (!strcmp(drv1->format_name, format_name))
149 ea2384d3 bellard
            return drv1;
150 ea2384d3 bellard
    }
151 ea2384d3 bellard
    return NULL;
152 ea2384d3 bellard
}
153 ea2384d3 bellard
154 ea2384d3 bellard
int bdrv_create(BlockDriver *drv, 
155 ea2384d3 bellard
                const char *filename, int64_t size_in_sectors,
156 ea2384d3 bellard
                const char *backing_file, int flags)
157 ea2384d3 bellard
{
158 ea2384d3 bellard
    if (!drv->bdrv_create)
159 ea2384d3 bellard
        return -ENOTSUP;
160 ea2384d3 bellard
    return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
161 ea2384d3 bellard
}
162 ea2384d3 bellard
163 d5249393 bellard
#ifdef _WIN32
164 95389c86 bellard
void get_tmp_filename(char *filename, int size)
165 d5249393 bellard
{
166 83f64091 bellard
    tmpnam(filename);
167 d5249393 bellard
}
168 d5249393 bellard
#else
169 95389c86 bellard
void get_tmp_filename(char *filename, int size)
170 fc01f7e7 bellard
{
171 67b915a5 bellard
    int fd;
172 d5249393 bellard
    /* XXX: race condition possible */
173 ea2384d3 bellard
    pstrcpy(filename, size, "/tmp/vl.XXXXXX");
174 ea2384d3 bellard
    fd = mkstemp(filename);
175 ea2384d3 bellard
    close(fd);
176 ea2384d3 bellard
}
177 d5249393 bellard
#endif
178 fc01f7e7 bellard
179 83f64091 bellard
static BlockDriver *find_protocol(const char *filename)
180 83f64091 bellard
{
181 83f64091 bellard
    BlockDriver *drv1;
182 83f64091 bellard
    char protocol[128];
183 83f64091 bellard
    int len;
184 83f64091 bellard
    const char *p;
185 83f64091 bellard
    p = strchr(filename, ':');
186 83f64091 bellard
    if (!p)
187 83f64091 bellard
        return &bdrv_raw;
188 83f64091 bellard
    len = p - filename;
189 83f64091 bellard
    if (len > sizeof(protocol) - 1)
190 83f64091 bellard
        len = sizeof(protocol) - 1;
191 83f64091 bellard
#ifdef _WIN32
192 83f64091 bellard
    if (len == 1) {
193 83f64091 bellard
        /* specific win32 case for driver letters */
194 83f64091 bellard
        return &bdrv_raw;
195 83f64091 bellard
    }
196 83f64091 bellard
#endif   
197 83f64091 bellard
    memcpy(protocol, filename, len);
198 83f64091 bellard
    protocol[len] = '\0';
199 83f64091 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
200 83f64091 bellard
        if (drv1->protocol_name && 
201 83f64091 bellard
            !strcmp(drv1->protocol_name, protocol))
202 83f64091 bellard
            return drv1;
203 83f64091 bellard
    }
204 83f64091 bellard
    return NULL;
205 83f64091 bellard
}
206 83f64091 bellard
207 7674e7bf bellard
/* XXX: force raw format if block or character device ? It would
208 7674e7bf bellard
   simplify the BSD case */
209 ea2384d3 bellard
static BlockDriver *find_image_format(const char *filename)
210 ea2384d3 bellard
{
211 83f64091 bellard
    int ret, score, score_max;
212 ea2384d3 bellard
    BlockDriver *drv1, *drv;
213 83f64091 bellard
    uint8_t buf[2048];
214 83f64091 bellard
    BlockDriverState *bs;
215 ea2384d3 bellard
    
216 83f64091 bellard
    drv = find_protocol(filename);
217 83f64091 bellard
    /* no need to test disk image formats for vvfat or host specific
218 83f64091 bellard
       devices */
219 83f64091 bellard
    if (drv == &bdrv_vvfat)
220 83f64091 bellard
        return drv;
221 83f64091 bellard
    if (strstart(filename, "/dev/", NULL))
222 83f64091 bellard
        return &bdrv_raw;
223 83f64091 bellard
    
224 83f64091 bellard
    ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
225 83f64091 bellard
    if (ret < 0)
226 83f64091 bellard
        return NULL;
227 83f64091 bellard
    ret = bdrv_pread(bs, 0, buf, sizeof(buf));
228 83f64091 bellard
    bdrv_delete(bs);
229 83f64091 bellard
    if (ret < 0) {
230 83f64091 bellard
        return NULL;
231 83f64091 bellard
    }
232 83f64091 bellard
233 ea2384d3 bellard
    score_max = 0;
234 ea2384d3 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
235 83f64091 bellard
        if (drv1->bdrv_probe) {
236 83f64091 bellard
            score = drv1->bdrv_probe(buf, ret, filename);
237 83f64091 bellard
            if (score > score_max) {
238 83f64091 bellard
                score_max = score;
239 83f64091 bellard
                drv = drv1;
240 83f64091 bellard
            }
241 0849bf08 bellard
        }
242 fc01f7e7 bellard
    }
243 ea2384d3 bellard
    return drv;
244 ea2384d3 bellard
}
245 ea2384d3 bellard
246 83f64091 bellard
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
247 ea2384d3 bellard
{
248 83f64091 bellard
    BlockDriverState *bs;
249 83f64091 bellard
    int ret;
250 83f64091 bellard
251 83f64091 bellard
    bs = bdrv_new("");
252 83f64091 bellard
    if (!bs)
253 83f64091 bellard
        return -ENOMEM;
254 83f64091 bellard
    ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
255 83f64091 bellard
    if (ret < 0) {
256 83f64091 bellard
        bdrv_delete(bs);
257 83f64091 bellard
        return ret;
258 3b0d4f61 bellard
    }
259 83f64091 bellard
    *pbs = bs;
260 83f64091 bellard
    return 0;
261 83f64091 bellard
}
262 83f64091 bellard
263 83f64091 bellard
int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
264 83f64091 bellard
{
265 83f64091 bellard
    return bdrv_open2(bs, filename, flags, NULL);
266 ea2384d3 bellard
}
267 ea2384d3 bellard
268 83f64091 bellard
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
269 ea2384d3 bellard
               BlockDriver *drv)
270 ea2384d3 bellard
{
271 83f64091 bellard
    int ret, open_flags;
272 ea2384d3 bellard
    char tmp_filename[1024];
273 83f64091 bellard
    char backing_filename[1024];
274 ea2384d3 bellard
    
275 ea2384d3 bellard
    bs->read_only = 0;
276 ea2384d3 bellard
    bs->is_temporary = 0;
277 ea2384d3 bellard
    bs->encrypted = 0;
278 712e7874 bellard
279 83f64091 bellard
    if (flags & BDRV_O_SNAPSHOT) {
280 ea2384d3 bellard
        BlockDriverState *bs1;
281 ea2384d3 bellard
        int64_t total_size;
282 ea2384d3 bellard
        
283 ea2384d3 bellard
        /* if snapshot, we create a temporary backing file and open it
284 ea2384d3 bellard
           instead of opening 'filename' directly */
285 33e3963e bellard
286 ea2384d3 bellard
        /* if there is a backing file, use it */
287 ea2384d3 bellard
        bs1 = bdrv_new("");
288 ea2384d3 bellard
        if (!bs1) {
289 83f64091 bellard
            return -ENOMEM;
290 ea2384d3 bellard
        }
291 ea2384d3 bellard
        if (bdrv_open(bs1, filename, 0) < 0) {
292 ea2384d3 bellard
            bdrv_delete(bs1);
293 ea2384d3 bellard
            return -1;
294 ea2384d3 bellard
        }
295 83f64091 bellard
        total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
296 ea2384d3 bellard
        bdrv_delete(bs1);
297 ea2384d3 bellard
        
298 ea2384d3 bellard
        get_tmp_filename(tmp_filename, sizeof(tmp_filename));
299 ea2384d3 bellard
        if (bdrv_create(&bdrv_qcow, tmp_filename, 
300 ea2384d3 bellard
                        total_size, filename, 0) < 0) {
301 ea2384d3 bellard
            return -1;
302 ea2384d3 bellard
        }
303 ea2384d3 bellard
        filename = tmp_filename;
304 ea2384d3 bellard
        bs->is_temporary = 1;
305 ea2384d3 bellard
    }
306 712e7874 bellard
307 ea2384d3 bellard
    pstrcpy(bs->filename, sizeof(bs->filename), filename);
308 83f64091 bellard
    if (flags & BDRV_O_FILE) {
309 83f64091 bellard
        drv = find_protocol(filename);
310 ea2384d3 bellard
        if (!drv)
311 83f64091 bellard
            return -ENOENT;
312 83f64091 bellard
    } else {
313 83f64091 bellard
        if (!drv) {
314 83f64091 bellard
            drv = find_image_format(filename);
315 83f64091 bellard
            if (!drv)
316 83f64091 bellard
                return -1;
317 83f64091 bellard
        }
318 ea2384d3 bellard
    }
319 ea2384d3 bellard
    bs->drv = drv;
320 ea2384d3 bellard
    bs->opaque = qemu_mallocz(drv->instance_size);
321 ea2384d3 bellard
    if (bs->opaque == NULL && drv->instance_size > 0)
322 ea2384d3 bellard
        return -1;
323 83f64091 bellard
    /* Note: for compatibility, we open disk image files as RDWR, and
324 83f64091 bellard
       RDONLY as fallback */
325 83f64091 bellard
    if (!(flags & BDRV_O_FILE))
326 83f64091 bellard
        open_flags = BDRV_O_RDWR;
327 83f64091 bellard
    else
328 83f64091 bellard
        open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
329 83f64091 bellard
    ret = drv->bdrv_open(bs, filename, open_flags);
330 83f64091 bellard
    if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
331 83f64091 bellard
        ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
332 83f64091 bellard
        bs->read_only = 1;
333 83f64091 bellard
    }
334 ea2384d3 bellard
    if (ret < 0) {
335 ea2384d3 bellard
        qemu_free(bs->opaque);
336 83f64091 bellard
        return ret;
337 33e3963e bellard
    }
338 83f64091 bellard
339 67b915a5 bellard
#ifndef _WIN32
340 ea2384d3 bellard
    if (bs->is_temporary) {
341 ea2384d3 bellard
        unlink(filename);
342 ea2384d3 bellard
    }
343 ea2384d3 bellard
#endif
344 83f64091 bellard
    if (bs->backing_file[0] != '\0') {
345 ea2384d3 bellard
        /* if there is a backing file, use it */
346 ea2384d3 bellard
        bs->backing_hd = bdrv_new("");
347 ea2384d3 bellard
        if (!bs->backing_hd) {
348 ea2384d3 bellard
        fail:
349 ea2384d3 bellard
            bdrv_close(bs);
350 ea2384d3 bellard
            return -1;
351 33e3963e bellard
        }
352 83f64091 bellard
        path_combine(backing_filename, sizeof(backing_filename),
353 83f64091 bellard
                     filename, bs->backing_file);
354 83f64091 bellard
        if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
355 33e3963e bellard
            goto fail;
356 33e3963e bellard
    }
357 33e3963e bellard
358 b338082b bellard
    bs->inserted = 1;
359 b338082b bellard
360 b338082b bellard
    /* call the change callback */
361 b338082b bellard
    if (bs->change_cb)
362 b338082b bellard
        bs->change_cb(bs->change_opaque);
363 b338082b bellard
364 b338082b bellard
    return 0;
365 fc01f7e7 bellard
}
366 fc01f7e7 bellard
367 fc01f7e7 bellard
void bdrv_close(BlockDriverState *bs)
368 fc01f7e7 bellard
{
369 b338082b bellard
    if (bs->inserted) {
370 ea2384d3 bellard
        if (bs->backing_hd)
371 ea2384d3 bellard
            bdrv_delete(bs->backing_hd);
372 ea2384d3 bellard
        bs->drv->bdrv_close(bs);
373 ea2384d3 bellard
        qemu_free(bs->opaque);
374 ea2384d3 bellard
#ifdef _WIN32
375 ea2384d3 bellard
        if (bs->is_temporary) {
376 ea2384d3 bellard
            unlink(bs->filename);
377 ea2384d3 bellard
        }
378 67b915a5 bellard
#endif
379 ea2384d3 bellard
        bs->opaque = NULL;
380 ea2384d3 bellard
        bs->drv = NULL;
381 b338082b bellard
        bs->inserted = 0;
382 b338082b bellard
383 b338082b bellard
        /* call the change callback */
384 b338082b bellard
        if (bs->change_cb)
385 b338082b bellard
            bs->change_cb(bs->change_opaque);
386 b338082b bellard
    }
387 b338082b bellard
}
388 b338082b bellard
389 b338082b bellard
void bdrv_delete(BlockDriverState *bs)
390 b338082b bellard
{
391 ea2384d3 bellard
    /* XXX: remove the driver list */
392 b338082b bellard
    bdrv_close(bs);
393 b338082b bellard
    qemu_free(bs);
394 fc01f7e7 bellard
}
395 fc01f7e7 bellard
396 33e3963e bellard
/* commit COW file into the raw image */
397 33e3963e bellard
int bdrv_commit(BlockDriverState *bs)
398 33e3963e bellard
{
399 83f64091 bellard
    int64_t i, total_sectors;
400 ea2384d3 bellard
    int n, j;
401 ea2384d3 bellard
    unsigned char sector[512];
402 33e3963e bellard
403 b338082b bellard
    if (!bs->inserted)
404 ea2384d3 bellard
        return -ENOENT;
405 33e3963e bellard
406 33e3963e bellard
    if (bs->read_only) {
407 ea2384d3 bellard
        return -EACCES;
408 33e3963e bellard
    }
409 33e3963e bellard
410 ea2384d3 bellard
    if (!bs->backing_hd) {
411 ea2384d3 bellard
        return -ENOTSUP;
412 ea2384d3 bellard
    }
413 33e3963e bellard
414 83f64091 bellard
    total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
415 83f64091 bellard
    for (i = 0; i < total_sectors;) {
416 ea2384d3 bellard
        if (bs->drv->bdrv_is_allocated(bs, i, 65536, &n)) {
417 ea2384d3 bellard
            for(j = 0; j < n; j++) {
418 ea2384d3 bellard
                if (bdrv_read(bs, i, sector, 1) != 0) {
419 ea2384d3 bellard
                    return -EIO;
420 ea2384d3 bellard
                }
421 ea2384d3 bellard
422 ea2384d3 bellard
                if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
423 ea2384d3 bellard
                    return -EIO;
424 ea2384d3 bellard
                }
425 ea2384d3 bellard
                i++;
426 33e3963e bellard
            }
427 ea2384d3 bellard
        } else {
428 ea2384d3 bellard
            i += n;
429 ea2384d3 bellard
        }
430 33e3963e bellard
    }
431 95389c86 bellard
432 95389c86 bellard
    if (bs->drv->bdrv_make_empty)
433 95389c86 bellard
        return bs->drv->bdrv_make_empty(bs);
434 95389c86 bellard
435 33e3963e bellard
    return 0;
436 33e3963e bellard
}
437 33e3963e bellard
438 83f64091 bellard
/* return < 0 if error */
439 fc01f7e7 bellard
int bdrv_read(BlockDriverState *bs, int64_t sector_num, 
440 fc01f7e7 bellard
              uint8_t *buf, int nb_sectors)
441 fc01f7e7 bellard
{
442 ea2384d3 bellard
    BlockDriver *drv = bs->drv;
443 ea2384d3 bellard
444 b338082b bellard
    if (!bs->inserted)
445 b338082b bellard
        return -1;
446 b338082b bellard
447 83f64091 bellard
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
448 cf98951b bellard
            memcpy(buf, bs->boot_sector_data, 512);
449 83f64091 bellard
        sector_num++;
450 83f64091 bellard
        nb_sectors--;
451 83f64091 bellard
        buf += 512;
452 83f64091 bellard
        if (nb_sectors == 0)
453 83f64091 bellard
            return 0;
454 83f64091 bellard
    }
455 83f64091 bellard
    if (drv->bdrv_pread) {
456 83f64091 bellard
        int ret, len;
457 83f64091 bellard
        len = nb_sectors * 512;
458 83f64091 bellard
        ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
459 83f64091 bellard
        if (ret < 0)
460 83f64091 bellard
            return ret;
461 83f64091 bellard
        else if (ret != len)
462 83f64091 bellard
            return -EIO;
463 83f64091 bellard
        else
464 83f64091 bellard
            return 0;
465 83f64091 bellard
    } else {
466 83f64091 bellard
        return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
467 33e3963e bellard
    }
468 fc01f7e7 bellard
}
469 fc01f7e7 bellard
470 83f64091 bellard
/* return < 0 if error */
471 fc01f7e7 bellard
int bdrv_write(BlockDriverState *bs, int64_t sector_num, 
472 fc01f7e7 bellard
               const uint8_t *buf, int nb_sectors)
473 fc01f7e7 bellard
{
474 83f64091 bellard
    BlockDriver *drv = bs->drv;
475 b338082b bellard
    if (!bs->inserted)
476 b338082b bellard
        return -1;
477 0849bf08 bellard
    if (bs->read_only)
478 0849bf08 bellard
        return -1;
479 79639d42 bellard
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
480 79639d42 bellard
        memcpy(bs->boot_sector_data, buf, 512);   
481 79639d42 bellard
    }
482 83f64091 bellard
    if (drv->bdrv_pwrite) {
483 83f64091 bellard
        int ret, len;
484 83f64091 bellard
        len = nb_sectors * 512;
485 83f64091 bellard
        ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
486 83f64091 bellard
        if (ret < 0)
487 83f64091 bellard
            return ret;
488 83f64091 bellard
        else if (ret != len)
489 83f64091 bellard
            return -EIO;
490 83f64091 bellard
        else
491 83f64091 bellard
            return 0;
492 83f64091 bellard
    } else {
493 83f64091 bellard
        return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
494 83f64091 bellard
    }
495 83f64091 bellard
}
496 83f64091 bellard
497 83f64091 bellard
#if 0
498 83f64091 bellard
/* not necessary now */
499 83f64091 bellard
static int bdrv_pread_em(BlockDriverState *bs, int64_t offset, 
500 83f64091 bellard
                         void *buf1, int count1)
501 83f64091 bellard
{
502 83f64091 bellard
    uint8_t *buf = buf1;
503 83f64091 bellard
    uint8_t tmp_buf[SECTOR_SIZE];
504 83f64091 bellard
    int len, nb_sectors, count;
505 83f64091 bellard
    int64_t sector_num;
506 83f64091 bellard

507 83f64091 bellard
    count = count1;
508 83f64091 bellard
    /* first read to align to sector start */
509 83f64091 bellard
    len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
510 83f64091 bellard
    if (len > count)
511 83f64091 bellard
        len = count;
512 83f64091 bellard
    sector_num = offset >> SECTOR_BITS;
513 83f64091 bellard
    if (len > 0) {
514 83f64091 bellard
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
515 83f64091 bellard
            return -EIO;
516 83f64091 bellard
        memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
517 83f64091 bellard
        count -= len;
518 83f64091 bellard
        if (count == 0)
519 83f64091 bellard
            return count1;
520 83f64091 bellard
        sector_num++;
521 83f64091 bellard
        buf += len;
522 83f64091 bellard
    }
523 83f64091 bellard

524 83f64091 bellard
    /* read the sectors "in place" */
525 83f64091 bellard
    nb_sectors = count >> SECTOR_BITS;
526 83f64091 bellard
    if (nb_sectors > 0) {
527 83f64091 bellard
        if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
528 83f64091 bellard
            return -EIO;
529 83f64091 bellard
        sector_num += nb_sectors;
530 83f64091 bellard
        len = nb_sectors << SECTOR_BITS;
531 83f64091 bellard
        buf += len;
532 83f64091 bellard
        count -= len;
533 83f64091 bellard
    }
534 83f64091 bellard

535 83f64091 bellard
    /* add data from the last sector */
536 83f64091 bellard
    if (count > 0) {
537 83f64091 bellard
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
538 83f64091 bellard
            return -EIO;
539 83f64091 bellard
        memcpy(buf, tmp_buf, count);
540 83f64091 bellard
    }
541 83f64091 bellard
    return count1;
542 83f64091 bellard
}
543 83f64091 bellard

544 83f64091 bellard
static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset, 
545 83f64091 bellard
                          const void *buf1, int count1)
546 83f64091 bellard
{
547 83f64091 bellard
    const uint8_t *buf = buf1;
548 83f64091 bellard
    uint8_t tmp_buf[SECTOR_SIZE];
549 83f64091 bellard
    int len, nb_sectors, count;
550 83f64091 bellard
    int64_t sector_num;
551 83f64091 bellard

552 83f64091 bellard
    count = count1;
553 83f64091 bellard
    /* first write to align to sector start */
554 83f64091 bellard
    len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
555 83f64091 bellard
    if (len > count)
556 83f64091 bellard
        len = count;
557 83f64091 bellard
    sector_num = offset >> SECTOR_BITS;
558 83f64091 bellard
    if (len > 0) {
559 83f64091 bellard
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
560 83f64091 bellard
            return -EIO;
561 83f64091 bellard
        memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
562 83f64091 bellard
        if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
563 83f64091 bellard
            return -EIO;
564 83f64091 bellard
        count -= len;
565 83f64091 bellard
        if (count == 0)
566 83f64091 bellard
            return count1;
567 83f64091 bellard
        sector_num++;
568 83f64091 bellard
        buf += len;
569 83f64091 bellard
    }
570 83f64091 bellard

571 83f64091 bellard
    /* write the sectors "in place" */
572 83f64091 bellard
    nb_sectors = count >> SECTOR_BITS;
573 83f64091 bellard
    if (nb_sectors > 0) {
574 83f64091 bellard
        if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
575 83f64091 bellard
            return -EIO;
576 83f64091 bellard
        sector_num += nb_sectors;
577 83f64091 bellard
        len = nb_sectors << SECTOR_BITS;
578 83f64091 bellard
        buf += len;
579 83f64091 bellard
        count -= len;
580 83f64091 bellard
    }
581 83f64091 bellard

582 83f64091 bellard
    /* add data from the last sector */
583 83f64091 bellard
    if (count > 0) {
584 83f64091 bellard
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
585 83f64091 bellard
            return -EIO;
586 83f64091 bellard
        memcpy(tmp_buf, buf, count);
587 83f64091 bellard
        if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
588 83f64091 bellard
            return -EIO;
589 83f64091 bellard
    }
590 83f64091 bellard
    return count1;
591 83f64091 bellard
}
592 83f64091 bellard
#endif
593 83f64091 bellard
594 83f64091 bellard
/**
595 83f64091 bellard
 * Read with byte offsets (needed only for file protocols) 
596 83f64091 bellard
 */
597 83f64091 bellard
int bdrv_pread(BlockDriverState *bs, int64_t offset, 
598 83f64091 bellard
               void *buf1, int count1)
599 83f64091 bellard
{
600 83f64091 bellard
    BlockDriver *drv = bs->drv;
601 83f64091 bellard
602 83f64091 bellard
    if (!drv)
603 83f64091 bellard
        return -ENOENT;
604 83f64091 bellard
    if (!drv->bdrv_pread)
605 83f64091 bellard
        return -ENOTSUP;
606 83f64091 bellard
    return drv->bdrv_pread(bs, offset, buf1, count1);
607 83f64091 bellard
}
608 83f64091 bellard
609 83f64091 bellard
/** 
610 83f64091 bellard
 * Write with byte offsets (needed only for file protocols) 
611 83f64091 bellard
 */
612 83f64091 bellard
int bdrv_pwrite(BlockDriverState *bs, int64_t offset, 
613 83f64091 bellard
                const void *buf1, int count1)
614 83f64091 bellard
{
615 83f64091 bellard
    BlockDriver *drv = bs->drv;
616 83f64091 bellard
617 83f64091 bellard
    if (!drv)
618 83f64091 bellard
        return -ENOENT;
619 83f64091 bellard
    if (!drv->bdrv_pwrite)
620 83f64091 bellard
        return -ENOTSUP;
621 83f64091 bellard
    return drv->bdrv_pwrite(bs, offset, buf1, count1);
622 83f64091 bellard
}
623 83f64091 bellard
624 83f64091 bellard
/**
625 83f64091 bellard
 * Truncate file to 'offset' bytes (needed only for file protocols)
626 83f64091 bellard
 */
627 83f64091 bellard
int bdrv_truncate(BlockDriverState *bs, int64_t offset)
628 83f64091 bellard
{
629 83f64091 bellard
    BlockDriver *drv = bs->drv;
630 83f64091 bellard
    if (!drv)
631 83f64091 bellard
        return -ENOENT;
632 83f64091 bellard
    if (!drv->bdrv_truncate)
633 83f64091 bellard
        return -ENOTSUP;
634 83f64091 bellard
    return drv->bdrv_truncate(bs, offset);
635 83f64091 bellard
}
636 83f64091 bellard
637 83f64091 bellard
/**
638 83f64091 bellard
 * Length of a file in bytes. Return < 0 if error or unknown.
639 83f64091 bellard
 */
640 83f64091 bellard
int64_t bdrv_getlength(BlockDriverState *bs)
641 83f64091 bellard
{
642 83f64091 bellard
    BlockDriver *drv = bs->drv;
643 83f64091 bellard
    if (!drv)
644 83f64091 bellard
        return -ENOENT;
645 83f64091 bellard
    if (!drv->bdrv_getlength) {
646 83f64091 bellard
        /* legacy mode */
647 83f64091 bellard
        return bs->total_sectors * SECTOR_SIZE;
648 83f64091 bellard
    }
649 83f64091 bellard
    return drv->bdrv_getlength(bs);
650 fc01f7e7 bellard
}
651 fc01f7e7 bellard
652 fc01f7e7 bellard
void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
653 fc01f7e7 bellard
{
654 83f64091 bellard
    int64_t size;
655 83f64091 bellard
    size = bdrv_getlength(bs);
656 83f64091 bellard
    if (size < 0)
657 83f64091 bellard
        size = 0;
658 83f64091 bellard
    *nb_sectors_ptr = size >> SECTOR_BITS;
659 fc01f7e7 bellard
}
660 cf98951b bellard
661 cf98951b bellard
/* force a given boot sector. */
662 cf98951b bellard
void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
663 cf98951b bellard
{
664 cf98951b bellard
    bs->boot_sector_enabled = 1;
665 cf98951b bellard
    if (size > 512)
666 cf98951b bellard
        size = 512;
667 cf98951b bellard
    memcpy(bs->boot_sector_data, data, size);
668 cf98951b bellard
    memset(bs->boot_sector_data + size, 0, 512 - size);
669 cf98951b bellard
}
670 b338082b bellard
671 b338082b bellard
void bdrv_set_geometry_hint(BlockDriverState *bs, 
672 b338082b bellard
                            int cyls, int heads, int secs)
673 b338082b bellard
{
674 b338082b bellard
    bs->cyls = cyls;
675 b338082b bellard
    bs->heads = heads;
676 b338082b bellard
    bs->secs = secs;
677 b338082b bellard
}
678 b338082b bellard
679 b338082b bellard
void bdrv_set_type_hint(BlockDriverState *bs, int type)
680 b338082b bellard
{
681 b338082b bellard
    bs->type = type;
682 b338082b bellard
    bs->removable = ((type == BDRV_TYPE_CDROM ||
683 b338082b bellard
                      type == BDRV_TYPE_FLOPPY));
684 b338082b bellard
}
685 b338082b bellard
686 46d4767d bellard
void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
687 46d4767d bellard
{
688 46d4767d bellard
    bs->translation = translation;
689 46d4767d bellard
}
690 46d4767d bellard
691 b338082b bellard
void bdrv_get_geometry_hint(BlockDriverState *bs, 
692 b338082b bellard
                            int *pcyls, int *pheads, int *psecs)
693 b338082b bellard
{
694 b338082b bellard
    *pcyls = bs->cyls;
695 b338082b bellard
    *pheads = bs->heads;
696 b338082b bellard
    *psecs = bs->secs;
697 b338082b bellard
}
698 b338082b bellard
699 b338082b bellard
int bdrv_get_type_hint(BlockDriverState *bs)
700 b338082b bellard
{
701 b338082b bellard
    return bs->type;
702 b338082b bellard
}
703 b338082b bellard
704 46d4767d bellard
int bdrv_get_translation_hint(BlockDriverState *bs)
705 46d4767d bellard
{
706 46d4767d bellard
    return bs->translation;
707 46d4767d bellard
}
708 46d4767d bellard
709 b338082b bellard
int bdrv_is_removable(BlockDriverState *bs)
710 b338082b bellard
{
711 b338082b bellard
    return bs->removable;
712 b338082b bellard
}
713 b338082b bellard
714 b338082b bellard
int bdrv_is_read_only(BlockDriverState *bs)
715 b338082b bellard
{
716 b338082b bellard
    return bs->read_only;
717 b338082b bellard
}
718 b338082b bellard
719 b338082b bellard
int bdrv_is_inserted(BlockDriverState *bs)
720 b338082b bellard
{
721 b338082b bellard
    return bs->inserted;
722 b338082b bellard
}
723 b338082b bellard
724 b338082b bellard
int bdrv_is_locked(BlockDriverState *bs)
725 b338082b bellard
{
726 b338082b bellard
    return bs->locked;
727 b338082b bellard
}
728 b338082b bellard
729 b338082b bellard
void bdrv_set_locked(BlockDriverState *bs, int locked)
730 b338082b bellard
{
731 b338082b bellard
    bs->locked = locked;
732 b338082b bellard
}
733 b338082b bellard
734 b338082b bellard
void bdrv_set_change_cb(BlockDriverState *bs, 
735 b338082b bellard
                        void (*change_cb)(void *opaque), void *opaque)
736 b338082b bellard
{
737 b338082b bellard
    bs->change_cb = change_cb;
738 b338082b bellard
    bs->change_opaque = opaque;
739 b338082b bellard
}
740 b338082b bellard
741 ea2384d3 bellard
int bdrv_is_encrypted(BlockDriverState *bs)
742 ea2384d3 bellard
{
743 ea2384d3 bellard
    if (bs->backing_hd && bs->backing_hd->encrypted)
744 ea2384d3 bellard
        return 1;
745 ea2384d3 bellard
    return bs->encrypted;
746 ea2384d3 bellard
}
747 ea2384d3 bellard
748 ea2384d3 bellard
int bdrv_set_key(BlockDriverState *bs, const char *key)
749 ea2384d3 bellard
{
750 ea2384d3 bellard
    int ret;
751 ea2384d3 bellard
    if (bs->backing_hd && bs->backing_hd->encrypted) {
752 ea2384d3 bellard
        ret = bdrv_set_key(bs->backing_hd, key);
753 ea2384d3 bellard
        if (ret < 0)
754 ea2384d3 bellard
            return ret;
755 ea2384d3 bellard
        if (!bs->encrypted)
756 ea2384d3 bellard
            return 0;
757 ea2384d3 bellard
    }
758 ea2384d3 bellard
    if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
759 ea2384d3 bellard
        return -1;
760 ea2384d3 bellard
    return bs->drv->bdrv_set_key(bs, key);
761 ea2384d3 bellard
}
762 ea2384d3 bellard
763 ea2384d3 bellard
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
764 ea2384d3 bellard
{
765 ea2384d3 bellard
    if (!bs->inserted || !bs->drv) {
766 ea2384d3 bellard
        buf[0] = '\0';
767 ea2384d3 bellard
    } else {
768 ea2384d3 bellard
        pstrcpy(buf, buf_size, bs->drv->format_name);
769 ea2384d3 bellard
    }
770 ea2384d3 bellard
}
771 ea2384d3 bellard
772 ea2384d3 bellard
void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 
773 ea2384d3 bellard
                         void *opaque)
774 ea2384d3 bellard
{
775 ea2384d3 bellard
    BlockDriver *drv;
776 ea2384d3 bellard
777 ea2384d3 bellard
    for (drv = first_drv; drv != NULL; drv = drv->next) {
778 ea2384d3 bellard
        it(opaque, drv->format_name);
779 ea2384d3 bellard
    }
780 ea2384d3 bellard
}
781 ea2384d3 bellard
782 b338082b bellard
BlockDriverState *bdrv_find(const char *name)
783 b338082b bellard
{
784 b338082b bellard
    BlockDriverState *bs;
785 b338082b bellard
786 b338082b bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
787 b338082b bellard
        if (!strcmp(name, bs->device_name))
788 b338082b bellard
            return bs;
789 b338082b bellard
    }
790 b338082b bellard
    return NULL;
791 b338082b bellard
}
792 b338082b bellard
793 81d0912d bellard
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
794 81d0912d bellard
{
795 81d0912d bellard
    BlockDriverState *bs;
796 81d0912d bellard
797 81d0912d bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
798 81d0912d bellard
        it(opaque, bs->device_name);
799 81d0912d bellard
    }
800 81d0912d bellard
}
801 81d0912d bellard
802 ea2384d3 bellard
const char *bdrv_get_device_name(BlockDriverState *bs)
803 ea2384d3 bellard
{
804 ea2384d3 bellard
    return bs->device_name;
805 ea2384d3 bellard
}
806 ea2384d3 bellard
807 7a6cba61 pbrook
void bdrv_flush(BlockDriverState *bs)
808 7a6cba61 pbrook
{
809 7a6cba61 pbrook
    if (bs->drv->bdrv_flush)
810 7a6cba61 pbrook
        bs->drv->bdrv_flush(bs);
811 7a6cba61 pbrook
    if (bs->backing_hd)
812 7a6cba61 pbrook
        bdrv_flush(bs->backing_hd);
813 7a6cba61 pbrook
}
814 7a6cba61 pbrook
815 b338082b bellard
void bdrv_info(void)
816 b338082b bellard
{
817 b338082b bellard
    BlockDriverState *bs;
818 b338082b bellard
819 b338082b bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
820 b338082b bellard
        term_printf("%s:", bs->device_name);
821 b338082b bellard
        term_printf(" type=");
822 b338082b bellard
        switch(bs->type) {
823 b338082b bellard
        case BDRV_TYPE_HD:
824 b338082b bellard
            term_printf("hd");
825 b338082b bellard
            break;
826 b338082b bellard
        case BDRV_TYPE_CDROM:
827 b338082b bellard
            term_printf("cdrom");
828 b338082b bellard
            break;
829 b338082b bellard
        case BDRV_TYPE_FLOPPY:
830 b338082b bellard
            term_printf("floppy");
831 b338082b bellard
            break;
832 b338082b bellard
        }
833 b338082b bellard
        term_printf(" removable=%d", bs->removable);
834 b338082b bellard
        if (bs->removable) {
835 b338082b bellard
            term_printf(" locked=%d", bs->locked);
836 b338082b bellard
        }
837 b338082b bellard
        if (bs->inserted) {
838 b338082b bellard
            term_printf(" file=%s", bs->filename);
839 ea2384d3 bellard
            if (bs->backing_file[0] != '\0')
840 ea2384d3 bellard
                term_printf(" backing_file=%s", bs->backing_file);
841 b338082b bellard
            term_printf(" ro=%d", bs->read_only);
842 ea2384d3 bellard
            term_printf(" drv=%s", bs->drv->format_name);
843 ea2384d3 bellard
            if (bs->encrypted)
844 ea2384d3 bellard
                term_printf(" encrypted");
845 b338082b bellard
        } else {
846 b338082b bellard
            term_printf(" [not inserted]");
847 b338082b bellard
        }
848 b338082b bellard
        term_printf("\n");
849 b338082b bellard
    }
850 b338082b bellard
}
851 ea2384d3 bellard
852 83f64091 bellard
void bdrv_get_backing_filename(BlockDriverState *bs, 
853 83f64091 bellard
                               char *filename, int filename_size)
854 83f64091 bellard
{
855 83f64091 bellard
    if (!bs->backing_hd) {
856 83f64091 bellard
        pstrcpy(filename, filename_size, "");
857 83f64091 bellard
    } else {
858 83f64091 bellard
        pstrcpy(filename, filename_size, bs->backing_file);
859 83f64091 bellard
    }
860 83f64091 bellard
}
861 83f64091 bellard
862 83f64091 bellard
863 ea2384d3 bellard
/**************************************************************/
864 83f64091 bellard
/* async I/Os */
865 ea2384d3 bellard
866 83f64091 bellard
BlockDriverAIOCB *bdrv_aio_new(BlockDriverState *bs)
867 83f64091 bellard
{
868 83f64091 bellard
    BlockDriver *drv = bs->drv;
869 83f64091 bellard
    BlockDriverAIOCB *acb;
870 83f64091 bellard
    acb = qemu_mallocz(sizeof(BlockDriverAIOCB));
871 83f64091 bellard
    if (!acb)
872 83f64091 bellard
        return NULL;
873 83f64091 bellard
    
874 83f64091 bellard
    acb->bs = bs;
875 83f64091 bellard
    if (drv->bdrv_aio_new(acb) < 0) {
876 83f64091 bellard
        qemu_free(acb);
877 83f64091 bellard
        return NULL;
878 83f64091 bellard
    }
879 83f64091 bellard
    return acb;
880 83f64091 bellard
}
881 ea2384d3 bellard
882 83f64091 bellard
int bdrv_aio_read(BlockDriverAIOCB *acb, int64_t sector_num,
883 83f64091 bellard
                  uint8_t *buf, int nb_sectors,
884 83f64091 bellard
                  BlockDriverCompletionFunc *cb, void *opaque)
885 ea2384d3 bellard
{
886 83f64091 bellard
    BlockDriverState *bs = acb->bs;
887 83f64091 bellard
    BlockDriver *drv = bs->drv;
888 83f64091 bellard
889 83f64091 bellard
    if (!bs->inserted)
890 83f64091 bellard
        return -1;
891 83f64091 bellard
    
892 83f64091 bellard
    /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
893 83f64091 bellard
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
894 83f64091 bellard
        memcpy(buf, bs->boot_sector_data, 512);
895 83f64091 bellard
        sector_num++;
896 83f64091 bellard
        nb_sectors--;
897 83f64091 bellard
        buf += 512;
898 83f64091 bellard
    }
899 83f64091 bellard
900 83f64091 bellard
    acb->cb = cb;
901 83f64091 bellard
    acb->cb_opaque = opaque;
902 83f64091 bellard
    return drv->bdrv_aio_read(acb, sector_num, buf, nb_sectors);
903 ea2384d3 bellard
}
904 ea2384d3 bellard
905 83f64091 bellard
int bdrv_aio_write(BlockDriverAIOCB *acb, int64_t sector_num,
906 83f64091 bellard
                   const uint8_t *buf, int nb_sectors,
907 83f64091 bellard
                   BlockDriverCompletionFunc *cb, void *opaque)
908 ea2384d3 bellard
{
909 83f64091 bellard
    BlockDriverState *bs = acb->bs;
910 83f64091 bellard
    BlockDriver *drv = bs->drv;
911 ea2384d3 bellard
912 83f64091 bellard
    if (!bs->inserted)
913 ea2384d3 bellard
            return -1;
914 83f64091 bellard
    if (bs->read_only)
915 83f64091 bellard
        return -1;
916 83f64091 bellard
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
917 83f64091 bellard
        memcpy(bs->boot_sector_data, buf, 512);   
918 ea2384d3 bellard
    }
919 83f64091 bellard
920 83f64091 bellard
    acb->cb = cb;
921 83f64091 bellard
    acb->cb_opaque = opaque;
922 83f64091 bellard
    return drv->bdrv_aio_write(acb, sector_num, buf, nb_sectors);
923 83f64091 bellard
}
924 83f64091 bellard
925 83f64091 bellard
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
926 7674e7bf bellard
    {
927 83f64091 bellard
    BlockDriverState *bs = acb->bs;
928 83f64091 bellard
    BlockDriver *drv = bs->drv;
929 83f64091 bellard
930 83f64091 bellard
    drv->bdrv_aio_cancel(acb);
931 7674e7bf bellard
    }
932 83f64091 bellard
933 83f64091 bellard
void bdrv_aio_delete(BlockDriverAIOCB *acb)
934 83f64091 bellard
{
935 83f64091 bellard
    BlockDriverState *bs = acb->bs;
936 83f64091 bellard
    BlockDriver *drv = bs->drv;
937 83f64091 bellard
938 83f64091 bellard
    drv->bdrv_aio_delete(acb);
939 83f64091 bellard
    qemu_free(acb);
940 83f64091 bellard
}
941 83f64091 bellard
942 83f64091 bellard
/**************************************************************/
943 83f64091 bellard
/* async block device emulation */
944 83f64091 bellard
945 83f64091 bellard
#ifdef QEMU_TOOL
946 83f64091 bellard
static int bdrv_aio_new_em(BlockDriverAIOCB *acb)
947 83f64091 bellard
{
948 ea2384d3 bellard
    return 0;
949 ea2384d3 bellard
}
950 ea2384d3 bellard
951 83f64091 bellard
static int bdrv_aio_read_em(BlockDriverAIOCB *acb, int64_t sector_num,
952 ea2384d3 bellard
                    uint8_t *buf, int nb_sectors)
953 ea2384d3 bellard
{
954 ea2384d3 bellard
    int ret;
955 83f64091 bellard
    ret = bdrv_read(acb->bs, sector_num, buf, nb_sectors);
956 83f64091 bellard
    acb->cb(acb->cb_opaque, ret);
957 ea2384d3 bellard
    return 0;
958 ea2384d3 bellard
}
959 ea2384d3 bellard
960 83f64091 bellard
static int bdrv_aio_write_em(BlockDriverAIOCB *acb, int64_t sector_num,
961 ea2384d3 bellard
                     const uint8_t *buf, int nb_sectors)
962 ea2384d3 bellard
{
963 ea2384d3 bellard
    int ret;
964 83f64091 bellard
    ret = bdrv_write(acb->bs, sector_num, buf, nb_sectors);
965 83f64091 bellard
    acb->cb(acb->cb_opaque, ret);
966 ea2384d3 bellard
    return 0;
967 ea2384d3 bellard
}
968 ea2384d3 bellard
969 83f64091 bellard
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
970 ea2384d3 bellard
{
971 ea2384d3 bellard
}
972 ea2384d3 bellard
973 83f64091 bellard
static void bdrv_aio_delete_em(BlockDriverAIOCB *acb)
974 beac80cd bellard
{
975 83f64091 bellard
}
976 83f64091 bellard
#else
977 83f64091 bellard
typedef struct BlockDriverAIOCBSync {
978 83f64091 bellard
    QEMUBH *bh;
979 83f64091 bellard
    int ret;
980 83f64091 bellard
} BlockDriverAIOCBSync;
981 beac80cd bellard
982 83f64091 bellard
static void bdrv_aio_bh_cb(void *opaque)
983 83f64091 bellard
{
984 83f64091 bellard
    BlockDriverAIOCB *acb = opaque;
985 83f64091 bellard
    BlockDriverAIOCBSync *acb1 = acb->opaque;
986 83f64091 bellard
    acb->cb(acb->cb_opaque, acb1->ret);
987 83f64091 bellard
}
988 beac80cd bellard
989 83f64091 bellard
static int bdrv_aio_new_em(BlockDriverAIOCB *acb)
990 83f64091 bellard
{
991 83f64091 bellard
    BlockDriverAIOCBSync *acb1;
992 beac80cd bellard
993 83f64091 bellard
    acb1 = qemu_mallocz(sizeof(BlockDriverAIOCBSync));
994 83f64091 bellard
    if (!acb1)
995 83f64091 bellard
        return -1;
996 83f64091 bellard
    acb->opaque = acb1;
997 83f64091 bellard
    acb1->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
998 83f64091 bellard
    return 0;
999 83f64091 bellard
}
1000 beac80cd bellard
1001 83f64091 bellard
static int bdrv_aio_read_em(BlockDriverAIOCB *acb, int64_t sector_num,
1002 83f64091 bellard
                    uint8_t *buf, int nb_sectors)
1003 83f64091 bellard
{
1004 83f64091 bellard
    BlockDriverAIOCBSync *acb1 = acb->opaque;
1005 83f64091 bellard
    int ret;
1006 83f64091 bellard
    
1007 83f64091 bellard
    ret = bdrv_read(acb->bs, sector_num, buf, nb_sectors);
1008 83f64091 bellard
    acb1->ret = ret;
1009 83f64091 bellard
    qemu_bh_schedule(acb1->bh);
1010 83f64091 bellard
    return 0;
1011 beac80cd bellard
}
1012 beac80cd bellard
1013 83f64091 bellard
static int bdrv_aio_write_em(BlockDriverAIOCB *acb, int64_t sector_num,
1014 83f64091 bellard
                     const uint8_t *buf, int nb_sectors)
1015 beac80cd bellard
{
1016 83f64091 bellard
    BlockDriverAIOCBSync *acb1 = acb->opaque;
1017 83f64091 bellard
    int ret;
1018 83f64091 bellard
    
1019 83f64091 bellard
    ret = bdrv_write(acb->bs, sector_num, buf, nb_sectors);
1020 83f64091 bellard
    acb1->ret = ret;
1021 83f64091 bellard
    qemu_bh_schedule(acb1->bh);
1022 83f64091 bellard
    return 0;
1023 beac80cd bellard
}
1024 83f64091 bellard
1025 83f64091 bellard
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
1026 beac80cd bellard
{
1027 83f64091 bellard
    BlockDriverAIOCBSync *acb1 = acb->opaque;
1028 83f64091 bellard
    qemu_bh_cancel(acb1->bh);
1029 beac80cd bellard
}
1030 beac80cd bellard
1031 83f64091 bellard
static void bdrv_aio_delete_em(BlockDriverAIOCB *acb)
1032 ea2384d3 bellard
{
1033 83f64091 bellard
    BlockDriverAIOCBSync *acb1 = acb->opaque;
1034 83f64091 bellard
    qemu_bh_delete(acb1->bh);
1035 83f64091 bellard
}
1036 83f64091 bellard
#endif /* !QEMU_TOOL */
1037 ea2384d3 bellard
1038 83f64091 bellard
/**************************************************************/
1039 83f64091 bellard
/* sync block device emulation */
1040 ea2384d3 bellard
1041 83f64091 bellard
static void bdrv_rw_em_cb(void *opaque, int ret)
1042 83f64091 bellard
{
1043 83f64091 bellard
    *(int *)opaque = ret;
1044 ea2384d3 bellard
}
1045 ea2384d3 bellard
1046 83f64091 bellard
#define NOT_DONE 0x7fffffff
1047 83f64091 bellard
1048 83f64091 bellard
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 
1049 83f64091 bellard
                        uint8_t *buf, int nb_sectors)
1050 7a6cba61 pbrook
{
1051 83f64091 bellard
    int async_ret, ret;
1052 83f64091 bellard
1053 83f64091 bellard
    if (!bs->sync_aiocb) {
1054 83f64091 bellard
        bs->sync_aiocb = bdrv_aio_new(bs);
1055 83f64091 bellard
        if (!bs->sync_aiocb)
1056 83f64091 bellard
            return -1;
1057 83f64091 bellard
    }
1058 83f64091 bellard
    async_ret = NOT_DONE;
1059 83f64091 bellard
    qemu_aio_wait_start();
1060 83f64091 bellard
    ret = bdrv_aio_read(bs->sync_aiocb, sector_num, buf, nb_sectors, 
1061 83f64091 bellard
                        bdrv_rw_em_cb, &async_ret);
1062 83f64091 bellard
    if (ret < 0) {
1063 83f64091 bellard
        qemu_aio_wait_end();
1064 83f64091 bellard
        return ret;
1065 83f64091 bellard
    }
1066 83f64091 bellard
    while (async_ret == NOT_DONE) {
1067 83f64091 bellard
        qemu_aio_wait();
1068 83f64091 bellard
    }
1069 83f64091 bellard
    qemu_aio_wait_end();
1070 83f64091 bellard
    return async_ret;
1071 7a6cba61 pbrook
}
1072 7a6cba61 pbrook
1073 83f64091 bellard
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
1074 83f64091 bellard
                         const uint8_t *buf, int nb_sectors)
1075 83f64091 bellard
{
1076 83f64091 bellard
    int async_ret, ret;
1077 83f64091 bellard
1078 83f64091 bellard
    if (!bs->sync_aiocb) {
1079 83f64091 bellard
        bs->sync_aiocb = bdrv_aio_new(bs);
1080 83f64091 bellard
        if (!bs->sync_aiocb)
1081 83f64091 bellard
            return -1;
1082 83f64091 bellard
    }
1083 83f64091 bellard
    async_ret = NOT_DONE;
1084 83f64091 bellard
    qemu_aio_wait_start();
1085 83f64091 bellard
    ret = bdrv_aio_write(bs->sync_aiocb, sector_num, buf, nb_sectors, 
1086 83f64091 bellard
                         bdrv_rw_em_cb, &async_ret);
1087 83f64091 bellard
    if (ret < 0) {
1088 83f64091 bellard
        qemu_aio_wait_end();
1089 83f64091 bellard
        return ret;
1090 83f64091 bellard
    }
1091 83f64091 bellard
    while (async_ret == NOT_DONE) {
1092 83f64091 bellard
        qemu_aio_wait();
1093 83f64091 bellard
    }
1094 83f64091 bellard
    qemu_aio_wait_end();
1095 83f64091 bellard
    return async_ret;
1096 83f64091 bellard
}
1097 ea2384d3 bellard
1098 ea2384d3 bellard
void bdrv_init(void)
1099 ea2384d3 bellard
{
1100 ea2384d3 bellard
    bdrv_register(&bdrv_raw);
1101 ea2384d3 bellard
#ifndef _WIN32
1102 ea2384d3 bellard
    bdrv_register(&bdrv_cow);
1103 ea2384d3 bellard
#endif
1104 ea2384d3 bellard
    bdrv_register(&bdrv_qcow);
1105 ea2384d3 bellard
    bdrv_register(&bdrv_vmdk);
1106 3c56521b bellard
    bdrv_register(&bdrv_cloop);
1107 585d0ed9 bellard
    bdrv_register(&bdrv_dmg);
1108 a8753c34 bellard
    bdrv_register(&bdrv_bochs);
1109 6a0f9e82 bellard
    bdrv_register(&bdrv_vpc);
1110 712e7874 bellard
    bdrv_register(&bdrv_vvfat);
1111 ea2384d3 bellard
}