Statistics
| Branch: | Revision:

root / block.c @ aa343735

History | View | Annotate | Download (34.4 kB)

1 fc01f7e7 bellard
/*
2 fc01f7e7 bellard
 * QEMU System Emulator block driver
3 5fafdf24 ths
 *
4 fc01f7e7 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 5fafdf24 ths
 *
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 90765429 bellard
typedef struct BlockDriverAIOCBSync {
39 90765429 bellard
    BlockDriverAIOCB common;
40 90765429 bellard
    QEMUBH *bh;
41 90765429 bellard
    int ret;
42 90765429 bellard
} BlockDriverAIOCBSync;
43 90765429 bellard
44 ce1a14dc pbrook
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
45 ce1a14dc pbrook
        int64_t sector_num, uint8_t *buf, int nb_sectors,
46 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque);
47 ce1a14dc pbrook
static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
48 ce1a14dc pbrook
        int64_t sector_num, const uint8_t *buf, int nb_sectors,
49 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque);
50 83f64091 bellard
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
51 5fafdf24 ths
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
52 83f64091 bellard
                        uint8_t *buf, int nb_sectors);
53 83f64091 bellard
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
54 83f64091 bellard
                         const uint8_t *buf, int nb_sectors);
55 ec530c81 bellard
56 b338082b bellard
static BlockDriverState *bdrv_first;
57 ea2384d3 bellard
static BlockDriver *first_drv;
58 ea2384d3 bellard
59 83f64091 bellard
int path_is_absolute(const char *path)
60 3b0d4f61 bellard
{
61 83f64091 bellard
    const char *p;
62 21664424 bellard
#ifdef _WIN32
63 21664424 bellard
    /* specific case for names like: "\\.\d:" */
64 21664424 bellard
    if (*path == '/' || *path == '\\')
65 21664424 bellard
        return 1;
66 21664424 bellard
#endif
67 83f64091 bellard
    p = strchr(path, ':');
68 83f64091 bellard
    if (p)
69 83f64091 bellard
        p++;
70 83f64091 bellard
    else
71 83f64091 bellard
        p = path;
72 3b9f94e1 bellard
#ifdef _WIN32
73 3b9f94e1 bellard
    return (*p == '/' || *p == '\\');
74 3b9f94e1 bellard
#else
75 3b9f94e1 bellard
    return (*p == '/');
76 3b9f94e1 bellard
#endif
77 3b0d4f61 bellard
}
78 3b0d4f61 bellard
79 83f64091 bellard
/* if filename is absolute, just copy it to dest. Otherwise, build a
80 83f64091 bellard
   path to it by considering it is relative to base_path. URL are
81 83f64091 bellard
   supported. */
82 83f64091 bellard
void path_combine(char *dest, int dest_size,
83 83f64091 bellard
                  const char *base_path,
84 83f64091 bellard
                  const char *filename)
85 3b0d4f61 bellard
{
86 83f64091 bellard
    const char *p, *p1;
87 83f64091 bellard
    int len;
88 83f64091 bellard
89 83f64091 bellard
    if (dest_size <= 0)
90 83f64091 bellard
        return;
91 83f64091 bellard
    if (path_is_absolute(filename)) {
92 83f64091 bellard
        pstrcpy(dest, dest_size, filename);
93 83f64091 bellard
    } else {
94 83f64091 bellard
        p = strchr(base_path, ':');
95 83f64091 bellard
        if (p)
96 83f64091 bellard
            p++;
97 83f64091 bellard
        else
98 83f64091 bellard
            p = base_path;
99 3b9f94e1 bellard
        p1 = strrchr(base_path, '/');
100 3b9f94e1 bellard
#ifdef _WIN32
101 3b9f94e1 bellard
        {
102 3b9f94e1 bellard
            const char *p2;
103 3b9f94e1 bellard
            p2 = strrchr(base_path, '\\');
104 3b9f94e1 bellard
            if (!p1 || p2 > p1)
105 3b9f94e1 bellard
                p1 = p2;
106 3b9f94e1 bellard
        }
107 3b9f94e1 bellard
#endif
108 83f64091 bellard
        if (p1)
109 83f64091 bellard
            p1++;
110 83f64091 bellard
        else
111 83f64091 bellard
            p1 = base_path;
112 83f64091 bellard
        if (p1 > p)
113 83f64091 bellard
            p = p1;
114 83f64091 bellard
        len = p - base_path;
115 83f64091 bellard
        if (len > dest_size - 1)
116 83f64091 bellard
            len = dest_size - 1;
117 83f64091 bellard
        memcpy(dest, base_path, len);
118 83f64091 bellard
        dest[len] = '\0';
119 83f64091 bellard
        pstrcat(dest, dest_size, filename);
120 3b0d4f61 bellard
    }
121 3b0d4f61 bellard
}
122 3b0d4f61 bellard
123 3b0d4f61 bellard
124 ea2384d3 bellard
void bdrv_register(BlockDriver *bdrv)
125 ea2384d3 bellard
{
126 ce1a14dc pbrook
    if (!bdrv->bdrv_aio_read) {
127 83f64091 bellard
        /* add AIO emulation layer */
128 83f64091 bellard
        bdrv->bdrv_aio_read = bdrv_aio_read_em;
129 83f64091 bellard
        bdrv->bdrv_aio_write = bdrv_aio_write_em;
130 83f64091 bellard
        bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
131 90765429 bellard
        bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
132 83f64091 bellard
    } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
133 83f64091 bellard
        /* add synchronous IO emulation layer */
134 83f64091 bellard
        bdrv->bdrv_read = bdrv_read_em;
135 83f64091 bellard
        bdrv->bdrv_write = bdrv_write_em;
136 83f64091 bellard
    }
137 ea2384d3 bellard
    bdrv->next = first_drv;
138 ea2384d3 bellard
    first_drv = bdrv;
139 ea2384d3 bellard
}
140 b338082b bellard
141 b338082b bellard
/* create a new block device (by default it is empty) */
142 b338082b bellard
BlockDriverState *bdrv_new(const char *device_name)
143 b338082b bellard
{
144 b338082b bellard
    BlockDriverState **pbs, *bs;
145 b338082b bellard
146 b338082b bellard
    bs = qemu_mallocz(sizeof(BlockDriverState));
147 b338082b bellard
    if(!bs)
148 b338082b bellard
        return NULL;
149 b338082b bellard
    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
150 ea2384d3 bellard
    if (device_name[0] != '\0') {
151 ea2384d3 bellard
        /* insert at the end */
152 ea2384d3 bellard
        pbs = &bdrv_first;
153 ea2384d3 bellard
        while (*pbs != NULL)
154 ea2384d3 bellard
            pbs = &(*pbs)->next;
155 ea2384d3 bellard
        *pbs = bs;
156 ea2384d3 bellard
    }
157 b338082b bellard
    return bs;
158 b338082b bellard
}
159 b338082b bellard
160 ea2384d3 bellard
BlockDriver *bdrv_find_format(const char *format_name)
161 ea2384d3 bellard
{
162 ea2384d3 bellard
    BlockDriver *drv1;
163 ea2384d3 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
164 ea2384d3 bellard
        if (!strcmp(drv1->format_name, format_name))
165 ea2384d3 bellard
            return drv1;
166 ea2384d3 bellard
    }
167 ea2384d3 bellard
    return NULL;
168 ea2384d3 bellard
}
169 ea2384d3 bellard
170 5fafdf24 ths
int bdrv_create(BlockDriver *drv,
171 ea2384d3 bellard
                const char *filename, int64_t size_in_sectors,
172 ea2384d3 bellard
                const char *backing_file, int flags)
173 ea2384d3 bellard
{
174 ea2384d3 bellard
    if (!drv->bdrv_create)
175 ea2384d3 bellard
        return -ENOTSUP;
176 ea2384d3 bellard
    return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
177 ea2384d3 bellard
}
178 ea2384d3 bellard
179 d5249393 bellard
#ifdef _WIN32
180 95389c86 bellard
void get_tmp_filename(char *filename, int size)
181 d5249393 bellard
{
182 3b9f94e1 bellard
    char temp_dir[MAX_PATH];
183 3b46e624 ths
184 3b9f94e1 bellard
    GetTempPath(MAX_PATH, temp_dir);
185 3b9f94e1 bellard
    GetTempFileName(temp_dir, "qem", 0, filename);
186 d5249393 bellard
}
187 d5249393 bellard
#else
188 95389c86 bellard
void get_tmp_filename(char *filename, int size)
189 fc01f7e7 bellard
{
190 67b915a5 bellard
    int fd;
191 d5249393 bellard
    /* XXX: race condition possible */
192 ea2384d3 bellard
    pstrcpy(filename, size, "/tmp/vl.XXXXXX");
193 ea2384d3 bellard
    fd = mkstemp(filename);
194 ea2384d3 bellard
    close(fd);
195 ea2384d3 bellard
}
196 d5249393 bellard
#endif
197 fc01f7e7 bellard
198 19cb3738 bellard
#ifdef _WIN32
199 f45512fe bellard
static int is_windows_drive_prefix(const char *filename)
200 f45512fe bellard
{
201 f45512fe bellard
    return (((filename[0] >= 'a' && filename[0] <= 'z') ||
202 f45512fe bellard
             (filename[0] >= 'A' && filename[0] <= 'Z')) &&
203 f45512fe bellard
            filename[1] == ':');
204 f45512fe bellard
}
205 3b46e624 ths
206 19cb3738 bellard
static int is_windows_drive(const char *filename)
207 19cb3738 bellard
{
208 5fafdf24 ths
    if (is_windows_drive_prefix(filename) &&
209 f45512fe bellard
        filename[2] == '\0')
210 19cb3738 bellard
        return 1;
211 19cb3738 bellard
    if (strstart(filename, "\\\\.\\", NULL) ||
212 19cb3738 bellard
        strstart(filename, "//./", NULL))
213 19cb3738 bellard
        return 1;
214 19cb3738 bellard
    return 0;
215 19cb3738 bellard
}
216 19cb3738 bellard
#endif
217 19cb3738 bellard
218 83f64091 bellard
static BlockDriver *find_protocol(const char *filename)
219 83f64091 bellard
{
220 83f64091 bellard
    BlockDriver *drv1;
221 83f64091 bellard
    char protocol[128];
222 83f64091 bellard
    int len;
223 83f64091 bellard
    const char *p;
224 19cb3738 bellard
225 19cb3738 bellard
#ifdef _WIN32
226 f45512fe bellard
    if (is_windows_drive(filename) ||
227 f45512fe bellard
        is_windows_drive_prefix(filename))
228 19cb3738 bellard
        return &bdrv_raw;
229 19cb3738 bellard
#endif
230 83f64091 bellard
    p = strchr(filename, ':');
231 83f64091 bellard
    if (!p)
232 83f64091 bellard
        return &bdrv_raw;
233 83f64091 bellard
    len = p - filename;
234 83f64091 bellard
    if (len > sizeof(protocol) - 1)
235 83f64091 bellard
        len = sizeof(protocol) - 1;
236 83f64091 bellard
    memcpy(protocol, filename, len);
237 83f64091 bellard
    protocol[len] = '\0';
238 83f64091 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
239 5fafdf24 ths
        if (drv1->protocol_name &&
240 83f64091 bellard
            !strcmp(drv1->protocol_name, protocol))
241 83f64091 bellard
            return drv1;
242 83f64091 bellard
    }
243 83f64091 bellard
    return NULL;
244 83f64091 bellard
}
245 83f64091 bellard
246 7674e7bf bellard
/* XXX: force raw format if block or character device ? It would
247 7674e7bf bellard
   simplify the BSD case */
248 ea2384d3 bellard
static BlockDriver *find_image_format(const char *filename)
249 ea2384d3 bellard
{
250 83f64091 bellard
    int ret, score, score_max;
251 ea2384d3 bellard
    BlockDriver *drv1, *drv;
252 83f64091 bellard
    uint8_t buf[2048];
253 83f64091 bellard
    BlockDriverState *bs;
254 3b46e624 ths
255 19cb3738 bellard
    /* detect host devices. By convention, /dev/cdrom[N] is always
256 19cb3738 bellard
       recognized as a host CDROM */
257 19cb3738 bellard
    if (strstart(filename, "/dev/cdrom", NULL))
258 19cb3738 bellard
        return &bdrv_host_device;
259 19cb3738 bellard
#ifdef _WIN32
260 19cb3738 bellard
    if (is_windows_drive(filename))
261 19cb3738 bellard
        return &bdrv_host_device;
262 19cb3738 bellard
#else
263 19cb3738 bellard
    {
264 19cb3738 bellard
        struct stat st;
265 5fafdf24 ths
        if (stat(filename, &st) >= 0 &&
266 19cb3738 bellard
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
267 19cb3738 bellard
            return &bdrv_host_device;
268 19cb3738 bellard
        }
269 19cb3738 bellard
    }
270 19cb3738 bellard
#endif
271 3b46e624 ths
272 83f64091 bellard
    drv = find_protocol(filename);
273 19cb3738 bellard
    /* no need to test disk image formats for vvfat */
274 83f64091 bellard
    if (drv == &bdrv_vvfat)
275 83f64091 bellard
        return drv;
276 19cb3738 bellard
277 83f64091 bellard
    ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
278 83f64091 bellard
    if (ret < 0)
279 83f64091 bellard
        return NULL;
280 83f64091 bellard
    ret = bdrv_pread(bs, 0, buf, sizeof(buf));
281 83f64091 bellard
    bdrv_delete(bs);
282 83f64091 bellard
    if (ret < 0) {
283 83f64091 bellard
        return NULL;
284 83f64091 bellard
    }
285 83f64091 bellard
286 ea2384d3 bellard
    score_max = 0;
287 ea2384d3 bellard
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
288 83f64091 bellard
        if (drv1->bdrv_probe) {
289 83f64091 bellard
            score = drv1->bdrv_probe(buf, ret, filename);
290 83f64091 bellard
            if (score > score_max) {
291 83f64091 bellard
                score_max = score;
292 83f64091 bellard
                drv = drv1;
293 83f64091 bellard
            }
294 0849bf08 bellard
        }
295 fc01f7e7 bellard
    }
296 ea2384d3 bellard
    return drv;
297 ea2384d3 bellard
}
298 ea2384d3 bellard
299 83f64091 bellard
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
300 ea2384d3 bellard
{
301 83f64091 bellard
    BlockDriverState *bs;
302 83f64091 bellard
    int ret;
303 83f64091 bellard
304 83f64091 bellard
    bs = bdrv_new("");
305 83f64091 bellard
    if (!bs)
306 83f64091 bellard
        return -ENOMEM;
307 83f64091 bellard
    ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
308 83f64091 bellard
    if (ret < 0) {
309 83f64091 bellard
        bdrv_delete(bs);
310 83f64091 bellard
        return ret;
311 3b0d4f61 bellard
    }
312 83f64091 bellard
    *pbs = bs;
313 83f64091 bellard
    return 0;
314 83f64091 bellard
}
315 83f64091 bellard
316 83f64091 bellard
int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
317 83f64091 bellard
{
318 83f64091 bellard
    return bdrv_open2(bs, filename, flags, NULL);
319 ea2384d3 bellard
}
320 ea2384d3 bellard
321 83f64091 bellard
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
322 ea2384d3 bellard
               BlockDriver *drv)
323 ea2384d3 bellard
{
324 83f64091 bellard
    int ret, open_flags;
325 eb5c851f ths
    char tmp_filename[PATH_MAX];
326 eb5c851f ths
    char backing_filename[PATH_MAX];
327 3b46e624 ths
328 ea2384d3 bellard
    bs->read_only = 0;
329 ea2384d3 bellard
    bs->is_temporary = 0;
330 ea2384d3 bellard
    bs->encrypted = 0;
331 712e7874 bellard
332 83f64091 bellard
    if (flags & BDRV_O_SNAPSHOT) {
333 ea2384d3 bellard
        BlockDriverState *bs1;
334 ea2384d3 bellard
        int64_t total_size;
335 3b46e624 ths
336 ea2384d3 bellard
        /* if snapshot, we create a temporary backing file and open it
337 ea2384d3 bellard
           instead of opening 'filename' directly */
338 33e3963e bellard
339 ea2384d3 bellard
        /* if there is a backing file, use it */
340 ea2384d3 bellard
        bs1 = bdrv_new("");
341 ea2384d3 bellard
        if (!bs1) {
342 83f64091 bellard
            return -ENOMEM;
343 ea2384d3 bellard
        }
344 ea2384d3 bellard
        if (bdrv_open(bs1, filename, 0) < 0) {
345 ea2384d3 bellard
            bdrv_delete(bs1);
346 ea2384d3 bellard
            return -1;
347 ea2384d3 bellard
        }
348 83f64091 bellard
        total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
349 ea2384d3 bellard
        bdrv_delete(bs1);
350 3b46e624 ths
351 ea2384d3 bellard
        get_tmp_filename(tmp_filename, sizeof(tmp_filename));
352 a817d936 bellard
        realpath(filename, backing_filename);
353 5fafdf24 ths
        if (bdrv_create(&bdrv_qcow2, tmp_filename,
354 a817d936 bellard
                        total_size, backing_filename, 0) < 0) {
355 ea2384d3 bellard
            return -1;
356 ea2384d3 bellard
        }
357 ea2384d3 bellard
        filename = tmp_filename;
358 ea2384d3 bellard
        bs->is_temporary = 1;
359 ea2384d3 bellard
    }
360 712e7874 bellard
361 ea2384d3 bellard
    pstrcpy(bs->filename, sizeof(bs->filename), filename);
362 83f64091 bellard
    if (flags & BDRV_O_FILE) {
363 83f64091 bellard
        drv = find_protocol(filename);
364 ea2384d3 bellard
        if (!drv)
365 83f64091 bellard
            return -ENOENT;
366 83f64091 bellard
    } else {
367 83f64091 bellard
        if (!drv) {
368 83f64091 bellard
            drv = find_image_format(filename);
369 83f64091 bellard
            if (!drv)
370 83f64091 bellard
                return -1;
371 83f64091 bellard
        }
372 ea2384d3 bellard
    }
373 ea2384d3 bellard
    bs->drv = drv;
374 ea2384d3 bellard
    bs->opaque = qemu_mallocz(drv->instance_size);
375 ea2384d3 bellard
    if (bs->opaque == NULL && drv->instance_size > 0)
376 ea2384d3 bellard
        return -1;
377 83f64091 bellard
    /* Note: for compatibility, we open disk image files as RDWR, and
378 83f64091 bellard
       RDONLY as fallback */
379 83f64091 bellard
    if (!(flags & BDRV_O_FILE))
380 83f64091 bellard
        open_flags = BDRV_O_RDWR;
381 83f64091 bellard
    else
382 83f64091 bellard
        open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
383 83f64091 bellard
    ret = drv->bdrv_open(bs, filename, open_flags);
384 83f64091 bellard
    if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
385 83f64091 bellard
        ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
386 83f64091 bellard
        bs->read_only = 1;
387 83f64091 bellard
    }
388 ea2384d3 bellard
    if (ret < 0) {
389 ea2384d3 bellard
        qemu_free(bs->opaque);
390 6b21b973 bellard
        bs->opaque = NULL;
391 6b21b973 bellard
        bs->drv = NULL;
392 83f64091 bellard
        return ret;
393 33e3963e bellard
    }
394 d15a771d bellard
    if (drv->bdrv_getlength) {
395 d15a771d bellard
        bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
396 d15a771d bellard
    }
397 67b915a5 bellard
#ifndef _WIN32
398 ea2384d3 bellard
    if (bs->is_temporary) {
399 ea2384d3 bellard
        unlink(filename);
400 ea2384d3 bellard
    }
401 ea2384d3 bellard
#endif
402 83f64091 bellard
    if (bs->backing_file[0] != '\0') {
403 ea2384d3 bellard
        /* if there is a backing file, use it */
404 ea2384d3 bellard
        bs->backing_hd = bdrv_new("");
405 ea2384d3 bellard
        if (!bs->backing_hd) {
406 ea2384d3 bellard
        fail:
407 ea2384d3 bellard
            bdrv_close(bs);
408 6b21b973 bellard
            return -ENOMEM;
409 33e3963e bellard
        }
410 83f64091 bellard
        path_combine(backing_filename, sizeof(backing_filename),
411 83f64091 bellard
                     filename, bs->backing_file);
412 83f64091 bellard
        if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
413 33e3963e bellard
            goto fail;
414 33e3963e bellard
    }
415 33e3963e bellard
416 b338082b bellard
    /* call the change callback */
417 19cb3738 bellard
    bs->media_changed = 1;
418 b338082b bellard
    if (bs->change_cb)
419 b338082b bellard
        bs->change_cb(bs->change_opaque);
420 b338082b bellard
421 b338082b bellard
    return 0;
422 fc01f7e7 bellard
}
423 fc01f7e7 bellard
424 fc01f7e7 bellard
void bdrv_close(BlockDriverState *bs)
425 fc01f7e7 bellard
{
426 19cb3738 bellard
    if (bs->drv) {
427 ea2384d3 bellard
        if (bs->backing_hd)
428 ea2384d3 bellard
            bdrv_delete(bs->backing_hd);
429 ea2384d3 bellard
        bs->drv->bdrv_close(bs);
430 ea2384d3 bellard
        qemu_free(bs->opaque);
431 ea2384d3 bellard
#ifdef _WIN32
432 ea2384d3 bellard
        if (bs->is_temporary) {
433 ea2384d3 bellard
            unlink(bs->filename);
434 ea2384d3 bellard
        }
435 67b915a5 bellard
#endif
436 ea2384d3 bellard
        bs->opaque = NULL;
437 ea2384d3 bellard
        bs->drv = NULL;
438 b338082b bellard
439 b338082b bellard
        /* call the change callback */
440 19cb3738 bellard
        bs->media_changed = 1;
441 b338082b bellard
        if (bs->change_cb)
442 b338082b bellard
            bs->change_cb(bs->change_opaque);
443 b338082b bellard
    }
444 b338082b bellard
}
445 b338082b bellard
446 b338082b bellard
void bdrv_delete(BlockDriverState *bs)
447 b338082b bellard
{
448 ea2384d3 bellard
    /* XXX: remove the driver list */
449 b338082b bellard
    bdrv_close(bs);
450 b338082b bellard
    qemu_free(bs);
451 fc01f7e7 bellard
}
452 fc01f7e7 bellard
453 33e3963e bellard
/* commit COW file into the raw image */
454 33e3963e bellard
int bdrv_commit(BlockDriverState *bs)
455 33e3963e bellard
{
456 19cb3738 bellard
    BlockDriver *drv = bs->drv;
457 83f64091 bellard
    int64_t i, total_sectors;
458 ea2384d3 bellard
    int n, j;
459 ea2384d3 bellard
    unsigned char sector[512];
460 33e3963e bellard
461 19cb3738 bellard
    if (!drv)
462 19cb3738 bellard
        return -ENOMEDIUM;
463 33e3963e bellard
464 33e3963e bellard
    if (bs->read_only) {
465 ea2384d3 bellard
        return -EACCES;
466 33e3963e bellard
    }
467 33e3963e bellard
468 ea2384d3 bellard
    if (!bs->backing_hd) {
469 ea2384d3 bellard
        return -ENOTSUP;
470 ea2384d3 bellard
    }
471 33e3963e bellard
472 83f64091 bellard
    total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
473 83f64091 bellard
    for (i = 0; i < total_sectors;) {
474 19cb3738 bellard
        if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
475 ea2384d3 bellard
            for(j = 0; j < n; j++) {
476 ea2384d3 bellard
                if (bdrv_read(bs, i, sector, 1) != 0) {
477 ea2384d3 bellard
                    return -EIO;
478 ea2384d3 bellard
                }
479 ea2384d3 bellard
480 ea2384d3 bellard
                if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
481 ea2384d3 bellard
                    return -EIO;
482 ea2384d3 bellard
                }
483 ea2384d3 bellard
                i++;
484 33e3963e bellard
            }
485 ea2384d3 bellard
        } else {
486 ea2384d3 bellard
            i += n;
487 ea2384d3 bellard
        }
488 33e3963e bellard
    }
489 95389c86 bellard
490 19cb3738 bellard
    if (drv->bdrv_make_empty)
491 19cb3738 bellard
        return drv->bdrv_make_empty(bs);
492 95389c86 bellard
493 33e3963e bellard
    return 0;
494 33e3963e bellard
}
495 33e3963e bellard
496 19cb3738 bellard
/* return < 0 if error. See bdrv_write() for the return codes */
497 5fafdf24 ths
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
498 fc01f7e7 bellard
              uint8_t *buf, int nb_sectors)
499 fc01f7e7 bellard
{
500 ea2384d3 bellard
    BlockDriver *drv = bs->drv;
501 ea2384d3 bellard
502 19cb3738 bellard
    if (!drv)
503 19cb3738 bellard
        return -ENOMEDIUM;
504 b338082b bellard
505 83f64091 bellard
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
506 cf98951b bellard
            memcpy(buf, bs->boot_sector_data, 512);
507 83f64091 bellard
        sector_num++;
508 83f64091 bellard
        nb_sectors--;
509 83f64091 bellard
        buf += 512;
510 83f64091 bellard
        if (nb_sectors == 0)
511 83f64091 bellard
            return 0;
512 83f64091 bellard
    }
513 83f64091 bellard
    if (drv->bdrv_pread) {
514 83f64091 bellard
        int ret, len;
515 83f64091 bellard
        len = nb_sectors * 512;
516 83f64091 bellard
        ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
517 83f64091 bellard
        if (ret < 0)
518 83f64091 bellard
            return ret;
519 83f64091 bellard
        else if (ret != len)
520 19cb3738 bellard
            return -EINVAL;
521 83f64091 bellard
        else
522 83f64091 bellard
            return 0;
523 83f64091 bellard
    } else {
524 83f64091 bellard
        return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
525 33e3963e bellard
    }
526 fc01f7e7 bellard
}
527 fc01f7e7 bellard
528 5fafdf24 ths
/* Return < 0 if error. Important errors are:
529 19cb3738 bellard
  -EIO         generic I/O error (may happen for all errors)
530 19cb3738 bellard
  -ENOMEDIUM   No media inserted.
531 19cb3738 bellard
  -EINVAL      Invalid sector number or nb_sectors
532 19cb3738 bellard
  -EACCES      Trying to write a read-only device
533 19cb3738 bellard
*/
534 5fafdf24 ths
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
535 fc01f7e7 bellard
               const uint8_t *buf, int nb_sectors)
536 fc01f7e7 bellard
{
537 83f64091 bellard
    BlockDriver *drv = bs->drv;
538 19cb3738 bellard
    if (!bs->drv)
539 19cb3738 bellard
        return -ENOMEDIUM;
540 0849bf08 bellard
    if (bs->read_only)
541 19cb3738 bellard
        return -EACCES;
542 79639d42 bellard
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
543 3b46e624 ths
        memcpy(bs->boot_sector_data, buf, 512);
544 79639d42 bellard
    }
545 83f64091 bellard
    if (drv->bdrv_pwrite) {
546 83f64091 bellard
        int ret, len;
547 83f64091 bellard
        len = nb_sectors * 512;
548 83f64091 bellard
        ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
549 83f64091 bellard
        if (ret < 0)
550 83f64091 bellard
            return ret;
551 83f64091 bellard
        else if (ret != len)
552 83f64091 bellard
            return -EIO;
553 83f64091 bellard
        else
554 83f64091 bellard
            return 0;
555 83f64091 bellard
    } else {
556 83f64091 bellard
        return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
557 83f64091 bellard
    }
558 83f64091 bellard
}
559 83f64091 bellard
560 5fafdf24 ths
static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
561 faea38e7 bellard
                         uint8_t *buf, int count1)
562 83f64091 bellard
{
563 83f64091 bellard
    uint8_t tmp_buf[SECTOR_SIZE];
564 83f64091 bellard
    int len, nb_sectors, count;
565 83f64091 bellard
    int64_t sector_num;
566 83f64091 bellard
567 83f64091 bellard
    count = count1;
568 83f64091 bellard
    /* first read to align to sector start */
569 83f64091 bellard
    len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
570 83f64091 bellard
    if (len > count)
571 83f64091 bellard
        len = count;
572 83f64091 bellard
    sector_num = offset >> SECTOR_BITS;
573 83f64091 bellard
    if (len > 0) {
574 83f64091 bellard
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
575 83f64091 bellard
            return -EIO;
576 83f64091 bellard
        memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
577 83f64091 bellard
        count -= len;
578 83f64091 bellard
        if (count == 0)
579 83f64091 bellard
            return count1;
580 83f64091 bellard
        sector_num++;
581 83f64091 bellard
        buf += len;
582 83f64091 bellard
    }
583 83f64091 bellard
584 83f64091 bellard
    /* read the sectors "in place" */
585 83f64091 bellard
    nb_sectors = count >> SECTOR_BITS;
586 83f64091 bellard
    if (nb_sectors > 0) {
587 83f64091 bellard
        if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
588 83f64091 bellard
            return -EIO;
589 83f64091 bellard
        sector_num += nb_sectors;
590 83f64091 bellard
        len = nb_sectors << SECTOR_BITS;
591 83f64091 bellard
        buf += len;
592 83f64091 bellard
        count -= len;
593 83f64091 bellard
    }
594 83f64091 bellard
595 83f64091 bellard
    /* add data from the last sector */
596 83f64091 bellard
    if (count > 0) {
597 83f64091 bellard
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
598 83f64091 bellard
            return -EIO;
599 83f64091 bellard
        memcpy(buf, tmp_buf, count);
600 83f64091 bellard
    }
601 83f64091 bellard
    return count1;
602 83f64091 bellard
}
603 83f64091 bellard
604 5fafdf24 ths
static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
605 faea38e7 bellard
                          const uint8_t *buf, int count1)
606 83f64091 bellard
{
607 83f64091 bellard
    uint8_t tmp_buf[SECTOR_SIZE];
608 83f64091 bellard
    int len, nb_sectors, count;
609 83f64091 bellard
    int64_t sector_num;
610 83f64091 bellard
611 83f64091 bellard
    count = count1;
612 83f64091 bellard
    /* first write to align to sector start */
613 83f64091 bellard
    len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
614 83f64091 bellard
    if (len > count)
615 83f64091 bellard
        len = count;
616 83f64091 bellard
    sector_num = offset >> SECTOR_BITS;
617 83f64091 bellard
    if (len > 0) {
618 83f64091 bellard
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
619 83f64091 bellard
            return -EIO;
620 83f64091 bellard
        memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
621 83f64091 bellard
        if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
622 83f64091 bellard
            return -EIO;
623 83f64091 bellard
        count -= len;
624 83f64091 bellard
        if (count == 0)
625 83f64091 bellard
            return count1;
626 83f64091 bellard
        sector_num++;
627 83f64091 bellard
        buf += len;
628 83f64091 bellard
    }
629 83f64091 bellard
630 83f64091 bellard
    /* write the sectors "in place" */
631 83f64091 bellard
    nb_sectors = count >> SECTOR_BITS;
632 83f64091 bellard
    if (nb_sectors > 0) {
633 83f64091 bellard
        if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
634 83f64091 bellard
            return -EIO;
635 83f64091 bellard
        sector_num += nb_sectors;
636 83f64091 bellard
        len = nb_sectors << SECTOR_BITS;
637 83f64091 bellard
        buf += len;
638 83f64091 bellard
        count -= len;
639 83f64091 bellard
    }
640 83f64091 bellard
641 83f64091 bellard
    /* add data from the last sector */
642 83f64091 bellard
    if (count > 0) {
643 83f64091 bellard
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
644 83f64091 bellard
            return -EIO;
645 83f64091 bellard
        memcpy(tmp_buf, buf, count);
646 83f64091 bellard
        if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
647 83f64091 bellard
            return -EIO;
648 83f64091 bellard
    }
649 83f64091 bellard
    return count1;
650 83f64091 bellard
}
651 83f64091 bellard
652 83f64091 bellard
/**
653 5fafdf24 ths
 * Read with byte offsets (needed only for file protocols)
654 83f64091 bellard
 */
655 5fafdf24 ths
int bdrv_pread(BlockDriverState *bs, int64_t offset,
656 83f64091 bellard
               void *buf1, int count1)
657 83f64091 bellard
{
658 83f64091 bellard
    BlockDriver *drv = bs->drv;
659 83f64091 bellard
660 83f64091 bellard
    if (!drv)
661 19cb3738 bellard
        return -ENOMEDIUM;
662 83f64091 bellard
    if (!drv->bdrv_pread)
663 faea38e7 bellard
        return bdrv_pread_em(bs, offset, buf1, count1);
664 83f64091 bellard
    return drv->bdrv_pread(bs, offset, buf1, count1);
665 83f64091 bellard
}
666 83f64091 bellard
667 5fafdf24 ths
/**
668 5fafdf24 ths
 * Write with byte offsets (needed only for file protocols)
669 83f64091 bellard
 */
670 5fafdf24 ths
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
671 83f64091 bellard
                const void *buf1, int count1)
672 83f64091 bellard
{
673 83f64091 bellard
    BlockDriver *drv = bs->drv;
674 83f64091 bellard
675 83f64091 bellard
    if (!drv)
676 19cb3738 bellard
        return -ENOMEDIUM;
677 83f64091 bellard
    if (!drv->bdrv_pwrite)
678 faea38e7 bellard
        return bdrv_pwrite_em(bs, offset, buf1, count1);
679 83f64091 bellard
    return drv->bdrv_pwrite(bs, offset, buf1, count1);
680 83f64091 bellard
}
681 83f64091 bellard
682 83f64091 bellard
/**
683 83f64091 bellard
 * Truncate file to 'offset' bytes (needed only for file protocols)
684 83f64091 bellard
 */
685 83f64091 bellard
int bdrv_truncate(BlockDriverState *bs, int64_t offset)
686 83f64091 bellard
{
687 83f64091 bellard
    BlockDriver *drv = bs->drv;
688 83f64091 bellard
    if (!drv)
689 19cb3738 bellard
        return -ENOMEDIUM;
690 83f64091 bellard
    if (!drv->bdrv_truncate)
691 83f64091 bellard
        return -ENOTSUP;
692 83f64091 bellard
    return drv->bdrv_truncate(bs, offset);
693 83f64091 bellard
}
694 83f64091 bellard
695 83f64091 bellard
/**
696 83f64091 bellard
 * Length of a file in bytes. Return < 0 if error or unknown.
697 83f64091 bellard
 */
698 83f64091 bellard
int64_t bdrv_getlength(BlockDriverState *bs)
699 83f64091 bellard
{
700 83f64091 bellard
    BlockDriver *drv = bs->drv;
701 83f64091 bellard
    if (!drv)
702 19cb3738 bellard
        return -ENOMEDIUM;
703 83f64091 bellard
    if (!drv->bdrv_getlength) {
704 83f64091 bellard
        /* legacy mode */
705 83f64091 bellard
        return bs->total_sectors * SECTOR_SIZE;
706 83f64091 bellard
    }
707 83f64091 bellard
    return drv->bdrv_getlength(bs);
708 fc01f7e7 bellard
}
709 fc01f7e7 bellard
710 19cb3738 bellard
/* return 0 as number of sectors if no device present or error */
711 fc01f7e7 bellard
void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
712 fc01f7e7 bellard
{
713 19cb3738 bellard
    int64_t length;
714 19cb3738 bellard
    length = bdrv_getlength(bs);
715 19cb3738 bellard
    if (length < 0)
716 19cb3738 bellard
        length = 0;
717 19cb3738 bellard
    else
718 19cb3738 bellard
        length = length >> SECTOR_BITS;
719 19cb3738 bellard
    *nb_sectors_ptr = length;
720 fc01f7e7 bellard
}
721 cf98951b bellard
722 cf98951b bellard
/* force a given boot sector. */
723 cf98951b bellard
void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
724 cf98951b bellard
{
725 cf98951b bellard
    bs->boot_sector_enabled = 1;
726 cf98951b bellard
    if (size > 512)
727 cf98951b bellard
        size = 512;
728 cf98951b bellard
    memcpy(bs->boot_sector_data, data, size);
729 cf98951b bellard
    memset(bs->boot_sector_data + size, 0, 512 - size);
730 cf98951b bellard
}
731 b338082b bellard
732 5fafdf24 ths
void bdrv_set_geometry_hint(BlockDriverState *bs,
733 b338082b bellard
                            int cyls, int heads, int secs)
734 b338082b bellard
{
735 b338082b bellard
    bs->cyls = cyls;
736 b338082b bellard
    bs->heads = heads;
737 b338082b bellard
    bs->secs = secs;
738 b338082b bellard
}
739 b338082b bellard
740 b338082b bellard
void bdrv_set_type_hint(BlockDriverState *bs, int type)
741 b338082b bellard
{
742 b338082b bellard
    bs->type = type;
743 b338082b bellard
    bs->removable = ((type == BDRV_TYPE_CDROM ||
744 b338082b bellard
                      type == BDRV_TYPE_FLOPPY));
745 b338082b bellard
}
746 b338082b bellard
747 46d4767d bellard
void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
748 46d4767d bellard
{
749 46d4767d bellard
    bs->translation = translation;
750 46d4767d bellard
}
751 46d4767d bellard
752 5fafdf24 ths
void bdrv_get_geometry_hint(BlockDriverState *bs,
753 b338082b bellard
                            int *pcyls, int *pheads, int *psecs)
754 b338082b bellard
{
755 b338082b bellard
    *pcyls = bs->cyls;
756 b338082b bellard
    *pheads = bs->heads;
757 b338082b bellard
    *psecs = bs->secs;
758 b338082b bellard
}
759 b338082b bellard
760 b338082b bellard
int bdrv_get_type_hint(BlockDriverState *bs)
761 b338082b bellard
{
762 b338082b bellard
    return bs->type;
763 b338082b bellard
}
764 b338082b bellard
765 46d4767d bellard
int bdrv_get_translation_hint(BlockDriverState *bs)
766 46d4767d bellard
{
767 46d4767d bellard
    return bs->translation;
768 46d4767d bellard
}
769 46d4767d bellard
770 b338082b bellard
int bdrv_is_removable(BlockDriverState *bs)
771 b338082b bellard
{
772 b338082b bellard
    return bs->removable;
773 b338082b bellard
}
774 b338082b bellard
775 b338082b bellard
int bdrv_is_read_only(BlockDriverState *bs)
776 b338082b bellard
{
777 b338082b bellard
    return bs->read_only;
778 b338082b bellard
}
779 b338082b bellard
780 19cb3738 bellard
/* XXX: no longer used */
781 5fafdf24 ths
void bdrv_set_change_cb(BlockDriverState *bs,
782 b338082b bellard
                        void (*change_cb)(void *opaque), void *opaque)
783 b338082b bellard
{
784 b338082b bellard
    bs->change_cb = change_cb;
785 b338082b bellard
    bs->change_opaque = opaque;
786 b338082b bellard
}
787 b338082b bellard
788 ea2384d3 bellard
int bdrv_is_encrypted(BlockDriverState *bs)
789 ea2384d3 bellard
{
790 ea2384d3 bellard
    if (bs->backing_hd && bs->backing_hd->encrypted)
791 ea2384d3 bellard
        return 1;
792 ea2384d3 bellard
    return bs->encrypted;
793 ea2384d3 bellard
}
794 ea2384d3 bellard
795 ea2384d3 bellard
int bdrv_set_key(BlockDriverState *bs, const char *key)
796 ea2384d3 bellard
{
797 ea2384d3 bellard
    int ret;
798 ea2384d3 bellard
    if (bs->backing_hd && bs->backing_hd->encrypted) {
799 ea2384d3 bellard
        ret = bdrv_set_key(bs->backing_hd, key);
800 ea2384d3 bellard
        if (ret < 0)
801 ea2384d3 bellard
            return ret;
802 ea2384d3 bellard
        if (!bs->encrypted)
803 ea2384d3 bellard
            return 0;
804 ea2384d3 bellard
    }
805 ea2384d3 bellard
    if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
806 ea2384d3 bellard
        return -1;
807 ea2384d3 bellard
    return bs->drv->bdrv_set_key(bs, key);
808 ea2384d3 bellard
}
809 ea2384d3 bellard
810 ea2384d3 bellard
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
811 ea2384d3 bellard
{
812 19cb3738 bellard
    if (!bs->drv) {
813 ea2384d3 bellard
        buf[0] = '\0';
814 ea2384d3 bellard
    } else {
815 ea2384d3 bellard
        pstrcpy(buf, buf_size, bs->drv->format_name);
816 ea2384d3 bellard
    }
817 ea2384d3 bellard
}
818 ea2384d3 bellard
819 5fafdf24 ths
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
820 ea2384d3 bellard
                         void *opaque)
821 ea2384d3 bellard
{
822 ea2384d3 bellard
    BlockDriver *drv;
823 ea2384d3 bellard
824 ea2384d3 bellard
    for (drv = first_drv; drv != NULL; drv = drv->next) {
825 ea2384d3 bellard
        it(opaque, drv->format_name);
826 ea2384d3 bellard
    }
827 ea2384d3 bellard
}
828 ea2384d3 bellard
829 b338082b bellard
BlockDriverState *bdrv_find(const char *name)
830 b338082b bellard
{
831 b338082b bellard
    BlockDriverState *bs;
832 b338082b bellard
833 b338082b bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
834 b338082b bellard
        if (!strcmp(name, bs->device_name))
835 b338082b bellard
            return bs;
836 b338082b bellard
    }
837 b338082b bellard
    return NULL;
838 b338082b bellard
}
839 b338082b bellard
840 81d0912d bellard
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
841 81d0912d bellard
{
842 81d0912d bellard
    BlockDriverState *bs;
843 81d0912d bellard
844 81d0912d bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
845 81d0912d bellard
        it(opaque, bs->device_name);
846 81d0912d bellard
    }
847 81d0912d bellard
}
848 81d0912d bellard
849 ea2384d3 bellard
const char *bdrv_get_device_name(BlockDriverState *bs)
850 ea2384d3 bellard
{
851 ea2384d3 bellard
    return bs->device_name;
852 ea2384d3 bellard
}
853 ea2384d3 bellard
854 7a6cba61 pbrook
void bdrv_flush(BlockDriverState *bs)
855 7a6cba61 pbrook
{
856 7a6cba61 pbrook
    if (bs->drv->bdrv_flush)
857 7a6cba61 pbrook
        bs->drv->bdrv_flush(bs);
858 7a6cba61 pbrook
    if (bs->backing_hd)
859 7a6cba61 pbrook
        bdrv_flush(bs->backing_hd);
860 7a6cba61 pbrook
}
861 7a6cba61 pbrook
862 b338082b bellard
void bdrv_info(void)
863 b338082b bellard
{
864 b338082b bellard
    BlockDriverState *bs;
865 b338082b bellard
866 b338082b bellard
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
867 b338082b bellard
        term_printf("%s:", bs->device_name);
868 b338082b bellard
        term_printf(" type=");
869 b338082b bellard
        switch(bs->type) {
870 b338082b bellard
        case BDRV_TYPE_HD:
871 b338082b bellard
            term_printf("hd");
872 b338082b bellard
            break;
873 b338082b bellard
        case BDRV_TYPE_CDROM:
874 b338082b bellard
            term_printf("cdrom");
875 b338082b bellard
            break;
876 b338082b bellard
        case BDRV_TYPE_FLOPPY:
877 b338082b bellard
            term_printf("floppy");
878 b338082b bellard
            break;
879 b338082b bellard
        }
880 b338082b bellard
        term_printf(" removable=%d", bs->removable);
881 b338082b bellard
        if (bs->removable) {
882 b338082b bellard
            term_printf(" locked=%d", bs->locked);
883 b338082b bellard
        }
884 19cb3738 bellard
        if (bs->drv) {
885 fef30743 ths
            term_printf(" file=");
886 fef30743 ths
            term_print_filename(bs->filename);
887 fef30743 ths
            if (bs->backing_file[0] != '\0') {
888 fef30743 ths
                term_printf(" backing_file=");
889 fef30743 ths
                term_print_filename(bs->backing_file);
890 fef30743 ths
            }
891 b338082b bellard
            term_printf(" ro=%d", bs->read_only);
892 ea2384d3 bellard
            term_printf(" drv=%s", bs->drv->format_name);
893 ea2384d3 bellard
            if (bs->encrypted)
894 ea2384d3 bellard
                term_printf(" encrypted");
895 b338082b bellard
        } else {
896 b338082b bellard
            term_printf(" [not inserted]");
897 b338082b bellard
        }
898 b338082b bellard
        term_printf("\n");
899 b338082b bellard
    }
900 b338082b bellard
}
901 ea2384d3 bellard
902 5fafdf24 ths
void bdrv_get_backing_filename(BlockDriverState *bs,
903 83f64091 bellard
                               char *filename, int filename_size)
904 83f64091 bellard
{
905 83f64091 bellard
    if (!bs->backing_hd) {
906 83f64091 bellard
        pstrcpy(filename, filename_size, "");
907 83f64091 bellard
    } else {
908 83f64091 bellard
        pstrcpy(filename, filename_size, bs->backing_file);
909 83f64091 bellard
    }
910 83f64091 bellard
}
911 83f64091 bellard
912 5fafdf24 ths
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
913 faea38e7 bellard
                          const uint8_t *buf, int nb_sectors)
914 faea38e7 bellard
{
915 faea38e7 bellard
    BlockDriver *drv = bs->drv;
916 faea38e7 bellard
    if (!drv)
917 19cb3738 bellard
        return -ENOMEDIUM;
918 faea38e7 bellard
    if (!drv->bdrv_write_compressed)
919 faea38e7 bellard
        return -ENOTSUP;
920 faea38e7 bellard
    return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
921 faea38e7 bellard
}
922 3b46e624 ths
923 faea38e7 bellard
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
924 faea38e7 bellard
{
925 faea38e7 bellard
    BlockDriver *drv = bs->drv;
926 faea38e7 bellard
    if (!drv)
927 19cb3738 bellard
        return -ENOMEDIUM;
928 faea38e7 bellard
    if (!drv->bdrv_get_info)
929 faea38e7 bellard
        return -ENOTSUP;
930 faea38e7 bellard
    memset(bdi, 0, sizeof(*bdi));
931 faea38e7 bellard
    return drv->bdrv_get_info(bs, bdi);
932 faea38e7 bellard
}
933 faea38e7 bellard
934 faea38e7 bellard
/**************************************************************/
935 faea38e7 bellard
/* handling of snapshots */
936 faea38e7 bellard
937 5fafdf24 ths
int bdrv_snapshot_create(BlockDriverState *bs,
938 faea38e7 bellard
                         QEMUSnapshotInfo *sn_info)
939 faea38e7 bellard
{
940 faea38e7 bellard
    BlockDriver *drv = bs->drv;
941 faea38e7 bellard
    if (!drv)
942 19cb3738 bellard
        return -ENOMEDIUM;
943 faea38e7 bellard
    if (!drv->bdrv_snapshot_create)
944 faea38e7 bellard
        return -ENOTSUP;
945 faea38e7 bellard
    return drv->bdrv_snapshot_create(bs, sn_info);
946 faea38e7 bellard
}
947 faea38e7 bellard
948 5fafdf24 ths
int bdrv_snapshot_goto(BlockDriverState *bs,
949 faea38e7 bellard
                       const char *snapshot_id)
950 faea38e7 bellard
{
951 faea38e7 bellard
    BlockDriver *drv = bs->drv;
952 faea38e7 bellard
    if (!drv)
953 19cb3738 bellard
        return -ENOMEDIUM;
954 faea38e7 bellard
    if (!drv->bdrv_snapshot_goto)
955 faea38e7 bellard
        return -ENOTSUP;
956 faea38e7 bellard
    return drv->bdrv_snapshot_goto(bs, snapshot_id);
957 faea38e7 bellard
}
958 faea38e7 bellard
959 faea38e7 bellard
int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
960 faea38e7 bellard
{
961 faea38e7 bellard
    BlockDriver *drv = bs->drv;
962 faea38e7 bellard
    if (!drv)
963 19cb3738 bellard
        return -ENOMEDIUM;
964 faea38e7 bellard
    if (!drv->bdrv_snapshot_delete)
965 faea38e7 bellard
        return -ENOTSUP;
966 faea38e7 bellard
    return drv->bdrv_snapshot_delete(bs, snapshot_id);
967 faea38e7 bellard
}
968 faea38e7 bellard
969 5fafdf24 ths
int bdrv_snapshot_list(BlockDriverState *bs,
970 faea38e7 bellard
                       QEMUSnapshotInfo **psn_info)
971 faea38e7 bellard
{
972 faea38e7 bellard
    BlockDriver *drv = bs->drv;
973 faea38e7 bellard
    if (!drv)
974 19cb3738 bellard
        return -ENOMEDIUM;
975 faea38e7 bellard
    if (!drv->bdrv_snapshot_list)
976 faea38e7 bellard
        return -ENOTSUP;
977 faea38e7 bellard
    return drv->bdrv_snapshot_list(bs, psn_info);
978 faea38e7 bellard
}
979 faea38e7 bellard
980 faea38e7 bellard
#define NB_SUFFIXES 4
981 faea38e7 bellard
982 faea38e7 bellard
char *get_human_readable_size(char *buf, int buf_size, int64_t size)
983 faea38e7 bellard
{
984 faea38e7 bellard
    static const char suffixes[NB_SUFFIXES] = "KMGT";
985 faea38e7 bellard
    int64_t base;
986 faea38e7 bellard
    int i;
987 faea38e7 bellard
988 faea38e7 bellard
    if (size <= 999) {
989 faea38e7 bellard
        snprintf(buf, buf_size, "%" PRId64, size);
990 faea38e7 bellard
    } else {
991 faea38e7 bellard
        base = 1024;
992 faea38e7 bellard
        for(i = 0; i < NB_SUFFIXES; i++) {
993 faea38e7 bellard
            if (size < (10 * base)) {
994 5fafdf24 ths
                snprintf(buf, buf_size, "%0.1f%c",
995 faea38e7 bellard
                         (double)size / base,
996 faea38e7 bellard
                         suffixes[i]);
997 faea38e7 bellard
                break;
998 faea38e7 bellard
            } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
999 5fafdf24 ths
                snprintf(buf, buf_size, "%" PRId64 "%c",
1000 faea38e7 bellard
                         ((size + (base >> 1)) / base),
1001 faea38e7 bellard
                         suffixes[i]);
1002 faea38e7 bellard
                break;
1003 faea38e7 bellard
            }
1004 faea38e7 bellard
            base = base * 1024;
1005 faea38e7 bellard
        }
1006 faea38e7 bellard
    }
1007 faea38e7 bellard
    return buf;
1008 faea38e7 bellard
}
1009 faea38e7 bellard
1010 faea38e7 bellard
char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
1011 faea38e7 bellard
{
1012 faea38e7 bellard
    char buf1[128], date_buf[128], clock_buf[128];
1013 3b9f94e1 bellard
#ifdef _WIN32
1014 3b9f94e1 bellard
    struct tm *ptm;
1015 3b9f94e1 bellard
#else
1016 faea38e7 bellard
    struct tm tm;
1017 3b9f94e1 bellard
#endif
1018 faea38e7 bellard
    time_t ti;
1019 faea38e7 bellard
    int64_t secs;
1020 faea38e7 bellard
1021 faea38e7 bellard
    if (!sn) {
1022 5fafdf24 ths
        snprintf(buf, buf_size,
1023 5fafdf24 ths
                 "%-10s%-20s%7s%20s%15s",
1024 faea38e7 bellard
                 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
1025 faea38e7 bellard
    } else {
1026 faea38e7 bellard
        ti = sn->date_sec;
1027 3b9f94e1 bellard
#ifdef _WIN32
1028 3b9f94e1 bellard
        ptm = localtime(&ti);
1029 3b9f94e1 bellard
        strftime(date_buf, sizeof(date_buf),
1030 3b9f94e1 bellard
                 "%Y-%m-%d %H:%M:%S", ptm);
1031 3b9f94e1 bellard
#else
1032 faea38e7 bellard
        localtime_r(&ti, &tm);
1033 faea38e7 bellard
        strftime(date_buf, sizeof(date_buf),
1034 faea38e7 bellard
                 "%Y-%m-%d %H:%M:%S", &tm);
1035 3b9f94e1 bellard
#endif
1036 faea38e7 bellard
        secs = sn->vm_clock_nsec / 1000000000;
1037 faea38e7 bellard
        snprintf(clock_buf, sizeof(clock_buf),
1038 faea38e7 bellard
                 "%02d:%02d:%02d.%03d",
1039 faea38e7 bellard
                 (int)(secs / 3600),
1040 faea38e7 bellard
                 (int)((secs / 60) % 60),
1041 5fafdf24 ths
                 (int)(secs % 60),
1042 faea38e7 bellard
                 (int)((sn->vm_clock_nsec / 1000000) % 1000));
1043 faea38e7 bellard
        snprintf(buf, buf_size,
1044 5fafdf24 ths
                 "%-10s%-20s%7s%20s%15s",
1045 faea38e7 bellard
                 sn->id_str, sn->name,
1046 faea38e7 bellard
                 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
1047 faea38e7 bellard
                 date_buf,
1048 faea38e7 bellard
                 clock_buf);
1049 faea38e7 bellard
    }
1050 faea38e7 bellard
    return buf;
1051 faea38e7 bellard
}
1052 faea38e7 bellard
1053 83f64091 bellard
1054 ea2384d3 bellard
/**************************************************************/
1055 83f64091 bellard
/* async I/Os */
1056 ea2384d3 bellard
1057 ce1a14dc pbrook
BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
1058 ce1a14dc pbrook
                                uint8_t *buf, int nb_sectors,
1059 ce1a14dc pbrook
                                BlockDriverCompletionFunc *cb, void *opaque)
1060 83f64091 bellard
{
1061 83f64091 bellard
    BlockDriver *drv = bs->drv;
1062 83f64091 bellard
1063 19cb3738 bellard
    if (!drv)
1064 ce1a14dc pbrook
        return NULL;
1065 3b46e624 ths
1066 83f64091 bellard
    /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
1067 83f64091 bellard
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1068 83f64091 bellard
        memcpy(buf, bs->boot_sector_data, 512);
1069 83f64091 bellard
        sector_num++;
1070 83f64091 bellard
        nb_sectors--;
1071 83f64091 bellard
        buf += 512;
1072 83f64091 bellard
    }
1073 83f64091 bellard
1074 ce1a14dc pbrook
    return drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
1075 ea2384d3 bellard
}
1076 ea2384d3 bellard
1077 ce1a14dc pbrook
BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
1078 ce1a14dc pbrook
                                 const uint8_t *buf, int nb_sectors,
1079 ce1a14dc pbrook
                                 BlockDriverCompletionFunc *cb, void *opaque)
1080 ea2384d3 bellard
{
1081 83f64091 bellard
    BlockDriver *drv = bs->drv;
1082 ea2384d3 bellard
1083 19cb3738 bellard
    if (!drv)
1084 ce1a14dc pbrook
        return NULL;
1085 83f64091 bellard
    if (bs->read_only)
1086 ce1a14dc pbrook
        return NULL;
1087 83f64091 bellard
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1088 3b46e624 ths
        memcpy(bs->boot_sector_data, buf, 512);
1089 ea2384d3 bellard
    }
1090 83f64091 bellard
1091 ce1a14dc pbrook
    return drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
1092 83f64091 bellard
}
1093 83f64091 bellard
1094 83f64091 bellard
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1095 83f64091 bellard
{
1096 ce1a14dc pbrook
    BlockDriver *drv = acb->bs->drv;
1097 83f64091 bellard
1098 ce1a14dc pbrook
    drv->bdrv_aio_cancel(acb);
1099 83f64091 bellard
}
1100 83f64091 bellard
1101 ce1a14dc pbrook
1102 83f64091 bellard
/**************************************************************/
1103 83f64091 bellard
/* async block device emulation */
1104 83f64091 bellard
1105 83f64091 bellard
#ifdef QEMU_TOOL
1106 ce1a14dc pbrook
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1107 ce1a14dc pbrook
        int64_t sector_num, uint8_t *buf, int nb_sectors,
1108 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque)
1109 ea2384d3 bellard
{
1110 ea2384d3 bellard
    int ret;
1111 ce1a14dc pbrook
    ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1112 ce1a14dc pbrook
    cb(opaque, ret);
1113 ce1a14dc pbrook
    return NULL;
1114 ea2384d3 bellard
}
1115 ea2384d3 bellard
1116 ce1a14dc pbrook
static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1117 ce1a14dc pbrook
        int64_t sector_num, const uint8_t *buf, int nb_sectors,
1118 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque)
1119 ea2384d3 bellard
{
1120 ea2384d3 bellard
    int ret;
1121 ce1a14dc pbrook
    ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1122 ce1a14dc pbrook
    cb(opaque, ret);
1123 ce1a14dc pbrook
    return NULL;
1124 ea2384d3 bellard
}
1125 ea2384d3 bellard
1126 83f64091 bellard
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
1127 ea2384d3 bellard
{
1128 ea2384d3 bellard
}
1129 83f64091 bellard
#else
1130 ce1a14dc pbrook
static void bdrv_aio_bh_cb(void *opaque)
1131 83f64091 bellard
{
1132 ce1a14dc pbrook
    BlockDriverAIOCBSync *acb = opaque;
1133 ce1a14dc pbrook
    acb->common.cb(acb->common.opaque, acb->ret);
1134 ce1a14dc pbrook
    qemu_aio_release(acb);
1135 83f64091 bellard
}
1136 beac80cd bellard
1137 ce1a14dc pbrook
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1138 ce1a14dc pbrook
        int64_t sector_num, uint8_t *buf, int nb_sectors,
1139 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque)
1140 83f64091 bellard
{
1141 ce1a14dc pbrook
    BlockDriverAIOCBSync *acb;
1142 83f64091 bellard
    int ret;
1143 ce1a14dc pbrook
1144 ce1a14dc pbrook
    acb = qemu_aio_get(bs, cb, opaque);
1145 ce1a14dc pbrook
    if (!acb->bh)
1146 ce1a14dc pbrook
        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1147 ce1a14dc pbrook
    ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1148 ce1a14dc pbrook
    acb->ret = ret;
1149 ce1a14dc pbrook
    qemu_bh_schedule(acb->bh);
1150 ce1a14dc pbrook
    return &acb->common;
1151 beac80cd bellard
}
1152 beac80cd bellard
1153 ce1a14dc pbrook
static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1154 ce1a14dc pbrook
        int64_t sector_num, const uint8_t *buf, int nb_sectors,
1155 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque)
1156 beac80cd bellard
{
1157 ce1a14dc pbrook
    BlockDriverAIOCBSync *acb;
1158 83f64091 bellard
    int ret;
1159 83f64091 bellard
1160 ce1a14dc pbrook
    acb = qemu_aio_get(bs, cb, opaque);
1161 ce1a14dc pbrook
    if (!acb->bh)
1162 ce1a14dc pbrook
        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1163 ce1a14dc pbrook
    ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1164 ce1a14dc pbrook
    acb->ret = ret;
1165 ce1a14dc pbrook
    qemu_bh_schedule(acb->bh);
1166 ce1a14dc pbrook
    return &acb->common;
1167 beac80cd bellard
}
1168 beac80cd bellard
1169 ce1a14dc pbrook
static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
1170 ea2384d3 bellard
{
1171 ce1a14dc pbrook
    BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
1172 ce1a14dc pbrook
    qemu_bh_cancel(acb->bh);
1173 ce1a14dc pbrook
    qemu_aio_release(acb);
1174 83f64091 bellard
}
1175 83f64091 bellard
#endif /* !QEMU_TOOL */
1176 ea2384d3 bellard
1177 83f64091 bellard
/**************************************************************/
1178 83f64091 bellard
/* sync block device emulation */
1179 ea2384d3 bellard
1180 83f64091 bellard
static void bdrv_rw_em_cb(void *opaque, int ret)
1181 83f64091 bellard
{
1182 83f64091 bellard
    *(int *)opaque = ret;
1183 ea2384d3 bellard
}
1184 ea2384d3 bellard
1185 83f64091 bellard
#define NOT_DONE 0x7fffffff
1186 83f64091 bellard
1187 5fafdf24 ths
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1188 83f64091 bellard
                        uint8_t *buf, int nb_sectors)
1189 7a6cba61 pbrook
{
1190 ce1a14dc pbrook
    int async_ret;
1191 ce1a14dc pbrook
    BlockDriverAIOCB *acb;
1192 83f64091 bellard
1193 83f64091 bellard
    async_ret = NOT_DONE;
1194 83f64091 bellard
    qemu_aio_wait_start();
1195 5fafdf24 ths
    acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
1196 83f64091 bellard
                        bdrv_rw_em_cb, &async_ret);
1197 ce1a14dc pbrook
    if (acb == NULL) {
1198 83f64091 bellard
        qemu_aio_wait_end();
1199 ce1a14dc pbrook
        return -1;
1200 83f64091 bellard
    }
1201 83f64091 bellard
    while (async_ret == NOT_DONE) {
1202 83f64091 bellard
        qemu_aio_wait();
1203 83f64091 bellard
    }
1204 83f64091 bellard
    qemu_aio_wait_end();
1205 83f64091 bellard
    return async_ret;
1206 7a6cba61 pbrook
}
1207 7a6cba61 pbrook
1208 83f64091 bellard
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
1209 83f64091 bellard
                         const uint8_t *buf, int nb_sectors)
1210 83f64091 bellard
{
1211 ce1a14dc pbrook
    int async_ret;
1212 ce1a14dc pbrook
    BlockDriverAIOCB *acb;
1213 83f64091 bellard
1214 83f64091 bellard
    async_ret = NOT_DONE;
1215 83f64091 bellard
    qemu_aio_wait_start();
1216 5fafdf24 ths
    acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
1217 83f64091 bellard
                         bdrv_rw_em_cb, &async_ret);
1218 ce1a14dc pbrook
    if (acb == NULL) {
1219 83f64091 bellard
        qemu_aio_wait_end();
1220 ce1a14dc pbrook
        return -1;
1221 83f64091 bellard
    }
1222 83f64091 bellard
    while (async_ret == NOT_DONE) {
1223 83f64091 bellard
        qemu_aio_wait();
1224 83f64091 bellard
    }
1225 83f64091 bellard
    qemu_aio_wait_end();
1226 83f64091 bellard
    return async_ret;
1227 83f64091 bellard
}
1228 ea2384d3 bellard
1229 ea2384d3 bellard
void bdrv_init(void)
1230 ea2384d3 bellard
{
1231 ea2384d3 bellard
    bdrv_register(&bdrv_raw);
1232 19cb3738 bellard
    bdrv_register(&bdrv_host_device);
1233 ea2384d3 bellard
#ifndef _WIN32
1234 ea2384d3 bellard
    bdrv_register(&bdrv_cow);
1235 ea2384d3 bellard
#endif
1236 ea2384d3 bellard
    bdrv_register(&bdrv_qcow);
1237 ea2384d3 bellard
    bdrv_register(&bdrv_vmdk);
1238 3c56521b bellard
    bdrv_register(&bdrv_cloop);
1239 585d0ed9 bellard
    bdrv_register(&bdrv_dmg);
1240 a8753c34 bellard
    bdrv_register(&bdrv_bochs);
1241 6a0f9e82 bellard
    bdrv_register(&bdrv_vpc);
1242 712e7874 bellard
    bdrv_register(&bdrv_vvfat);
1243 faea38e7 bellard
    bdrv_register(&bdrv_qcow2);
1244 6ada7453 ths
    bdrv_register(&bdrv_parallels);
1245 ea2384d3 bellard
}
1246 ce1a14dc pbrook
1247 ce1a14dc pbrook
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
1248 ce1a14dc pbrook
                   void *opaque)
1249 ce1a14dc pbrook
{
1250 ce1a14dc pbrook
    BlockDriver *drv;
1251 ce1a14dc pbrook
    BlockDriverAIOCB *acb;
1252 ce1a14dc pbrook
1253 ce1a14dc pbrook
    drv = bs->drv;
1254 ce1a14dc pbrook
    if (drv->free_aiocb) {
1255 ce1a14dc pbrook
        acb = drv->free_aiocb;
1256 ce1a14dc pbrook
        drv->free_aiocb = acb->next;
1257 ce1a14dc pbrook
    } else {
1258 ce1a14dc pbrook
        acb = qemu_mallocz(drv->aiocb_size);
1259 ce1a14dc pbrook
        if (!acb)
1260 ce1a14dc pbrook
            return NULL;
1261 ce1a14dc pbrook
    }
1262 ce1a14dc pbrook
    acb->bs = bs;
1263 ce1a14dc pbrook
    acb->cb = cb;
1264 ce1a14dc pbrook
    acb->opaque = opaque;
1265 ce1a14dc pbrook
    return acb;
1266 ce1a14dc pbrook
}
1267 ce1a14dc pbrook
1268 ce1a14dc pbrook
void qemu_aio_release(void *p)
1269 ce1a14dc pbrook
{
1270 ce1a14dc pbrook
    BlockDriverAIOCB *acb = p;
1271 ce1a14dc pbrook
    BlockDriver *drv = acb->bs->drv;
1272 ce1a14dc pbrook
    acb->next = drv->free_aiocb;
1273 ce1a14dc pbrook
    drv->free_aiocb = acb;
1274 ce1a14dc pbrook
}
1275 19cb3738 bellard
1276 19cb3738 bellard
/**************************************************************/
1277 19cb3738 bellard
/* removable device support */
1278 19cb3738 bellard
1279 19cb3738 bellard
/**
1280 19cb3738 bellard
 * Return TRUE if the media is present
1281 19cb3738 bellard
 */
1282 19cb3738 bellard
int bdrv_is_inserted(BlockDriverState *bs)
1283 19cb3738 bellard
{
1284 19cb3738 bellard
    BlockDriver *drv = bs->drv;
1285 19cb3738 bellard
    int ret;
1286 19cb3738 bellard
    if (!drv)
1287 19cb3738 bellard
        return 0;
1288 19cb3738 bellard
    if (!drv->bdrv_is_inserted)
1289 19cb3738 bellard
        return 1;
1290 19cb3738 bellard
    ret = drv->bdrv_is_inserted(bs);
1291 19cb3738 bellard
    return ret;
1292 19cb3738 bellard
}
1293 19cb3738 bellard
1294 19cb3738 bellard
/**
1295 19cb3738 bellard
 * Return TRUE if the media changed since the last call to this
1296 5fafdf24 ths
 * function. It is currently only used for floppy disks
1297 19cb3738 bellard
 */
1298 19cb3738 bellard
int bdrv_media_changed(BlockDriverState *bs)
1299 19cb3738 bellard
{
1300 19cb3738 bellard
    BlockDriver *drv = bs->drv;
1301 19cb3738 bellard
    int ret;
1302 19cb3738 bellard
1303 19cb3738 bellard
    if (!drv || !drv->bdrv_media_changed)
1304 19cb3738 bellard
        ret = -ENOTSUP;
1305 19cb3738 bellard
    else
1306 19cb3738 bellard
        ret = drv->bdrv_media_changed(bs);
1307 19cb3738 bellard
    if (ret == -ENOTSUP)
1308 19cb3738 bellard
        ret = bs->media_changed;
1309 19cb3738 bellard
    bs->media_changed = 0;
1310 19cb3738 bellard
    return ret;
1311 19cb3738 bellard
}
1312 19cb3738 bellard
1313 19cb3738 bellard
/**
1314 19cb3738 bellard
 * If eject_flag is TRUE, eject the media. Otherwise, close the tray
1315 19cb3738 bellard
 */
1316 19cb3738 bellard
void bdrv_eject(BlockDriverState *bs, int eject_flag)
1317 19cb3738 bellard
{
1318 19cb3738 bellard
    BlockDriver *drv = bs->drv;
1319 19cb3738 bellard
    int ret;
1320 19cb3738 bellard
1321 19cb3738 bellard
    if (!drv || !drv->bdrv_eject) {
1322 19cb3738 bellard
        ret = -ENOTSUP;
1323 19cb3738 bellard
    } else {
1324 19cb3738 bellard
        ret = drv->bdrv_eject(bs, eject_flag);
1325 19cb3738 bellard
    }
1326 19cb3738 bellard
    if (ret == -ENOTSUP) {
1327 19cb3738 bellard
        if (eject_flag)
1328 19cb3738 bellard
            bdrv_close(bs);
1329 19cb3738 bellard
    }
1330 19cb3738 bellard
}
1331 19cb3738 bellard
1332 19cb3738 bellard
int bdrv_is_locked(BlockDriverState *bs)
1333 19cb3738 bellard
{
1334 19cb3738 bellard
    return bs->locked;
1335 19cb3738 bellard
}
1336 19cb3738 bellard
1337 19cb3738 bellard
/**
1338 19cb3738 bellard
 * Lock or unlock the media (if it is locked, the user won't be able
1339 19cb3738 bellard
 * to eject it manually).
1340 19cb3738 bellard
 */
1341 19cb3738 bellard
void bdrv_set_locked(BlockDriverState *bs, int locked)
1342 19cb3738 bellard
{
1343 19cb3738 bellard
    BlockDriver *drv = bs->drv;
1344 19cb3738 bellard
1345 19cb3738 bellard
    bs->locked = locked;
1346 19cb3738 bellard
    if (drv && drv->bdrv_set_locked) {
1347 19cb3738 bellard
        drv->bdrv_set_locked(bs, locked);
1348 19cb3738 bellard
    }
1349 19cb3738 bellard
}