Statistics
| Branch: | Revision:

root / block.c @ 83f64091

History | View | Annotate | Download (27.6 kB)

1
/*
2
 * QEMU System Emulator block driver
3
 * 
4
 * Copyright (c) 2003 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25
#include "block_int.h"
26

    
27
#ifdef _BSD
28
#include <sys/types.h>
29
#include <sys/stat.h>
30
#include <sys/ioctl.h>
31
#include <sys/queue.h>
32
#include <sys/disk.h>
33
#endif
34

    
35
#define SECTOR_BITS 9
36
#define SECTOR_SIZE (1 << SECTOR_BITS)
37

    
38
static int bdrv_aio_new_em(BlockDriverAIOCB *acb);
39
static int bdrv_aio_read_em(BlockDriverAIOCB *acb, int64_t sector_num,
40
                              uint8_t *buf, int nb_sectors);
41
static int bdrv_aio_write_em(BlockDriverAIOCB *acb, int64_t sector_num,
42
                               const uint8_t *buf, int nb_sectors);
43
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
44
static void bdrv_aio_delete_em(BlockDriverAIOCB *acb);
45
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 
46
                        uint8_t *buf, int nb_sectors);
47
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
48
                         const uint8_t *buf, int nb_sectors);
49

    
50
static BlockDriverState *bdrv_first;
51
static BlockDriver *first_drv;
52

    
53
#ifdef _WIN32
54
#define PATH_SEP '\\'
55
#else
56
#define PATH_SEP '/'
57
#endif
58

    
59
int path_is_absolute(const char *path)
60
{
61
    const char *p;
62
    p = strchr(path, ':');
63
    if (p)
64
        p++;
65
    else
66
        p = path;
67
    return (*p == PATH_SEP);
68
}
69

    
70
/* if filename is absolute, just copy it to dest. Otherwise, build a
71
   path to it by considering it is relative to base_path. URL are
72
   supported. */
73
void path_combine(char *dest, int dest_size,
74
                  const char *base_path,
75
                  const char *filename)
76
{
77
    const char *p, *p1;
78
    int len;
79

    
80
    if (dest_size <= 0)
81
        return;
82
    if (path_is_absolute(filename)) {
83
        pstrcpy(dest, dest_size, filename);
84
    } else {
85
        p = strchr(base_path, ':');
86
        if (p)
87
            p++;
88
        else
89
            p = base_path;
90
        p1 = strrchr(base_path, PATH_SEP);
91
        if (p1)
92
            p1++;
93
        else
94
            p1 = base_path;
95
        if (p1 > p)
96
            p = p1;
97
        len = p - base_path;
98
        if (len > dest_size - 1)
99
            len = dest_size - 1;
100
        memcpy(dest, base_path, len);
101
        dest[len] = '\0';
102
        pstrcat(dest, dest_size, filename);
103
    }
104
}
105

    
106

    
107
void bdrv_register(BlockDriver *bdrv)
108
{
109
    if (!bdrv->bdrv_aio_new) {
110
        /* add AIO emulation layer */
111
        bdrv->bdrv_aio_new = bdrv_aio_new_em;
112
        bdrv->bdrv_aio_read = bdrv_aio_read_em;
113
        bdrv->bdrv_aio_write = bdrv_aio_write_em;
114
        bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
115
        bdrv->bdrv_aio_delete = bdrv_aio_delete_em;
116
    } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
117
        /* add synchronous IO emulation layer */
118
        bdrv->bdrv_read = bdrv_read_em;
119
        bdrv->bdrv_write = bdrv_write_em;
120
    }
121
    bdrv->next = first_drv;
122
    first_drv = bdrv;
123
}
124

    
125
/* create a new block device (by default it is empty) */
126
BlockDriverState *bdrv_new(const char *device_name)
127
{
128
    BlockDriverState **pbs, *bs;
129

    
130
    bs = qemu_mallocz(sizeof(BlockDriverState));
131
    if(!bs)
132
        return NULL;
133
    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
134
    if (device_name[0] != '\0') {
135
        /* insert at the end */
136
        pbs = &bdrv_first;
137
        while (*pbs != NULL)
138
            pbs = &(*pbs)->next;
139
        *pbs = bs;
140
    }
141
    return bs;
142
}
143

    
144
BlockDriver *bdrv_find_format(const char *format_name)
145
{
146
    BlockDriver *drv1;
147
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
148
        if (!strcmp(drv1->format_name, format_name))
149
            return drv1;
150
    }
151
    return NULL;
152
}
153

    
154
int bdrv_create(BlockDriver *drv, 
155
                const char *filename, int64_t size_in_sectors,
156
                const char *backing_file, int flags)
157
{
158
    if (!drv->bdrv_create)
159
        return -ENOTSUP;
160
    return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
161
}
162

    
163
#ifdef _WIN32
164
void get_tmp_filename(char *filename, int size)
165
{
166
    tmpnam(filename);
167
}
168
#else
169
void get_tmp_filename(char *filename, int size)
170
{
171
    int fd;
172
    /* XXX: race condition possible */
173
    pstrcpy(filename, size, "/tmp/vl.XXXXXX");
174
    fd = mkstemp(filename);
175
    close(fd);
176
}
177
#endif
178

    
179
static BlockDriver *find_protocol(const char *filename)
180
{
181
    BlockDriver *drv1;
182
    char protocol[128];
183
    int len;
184
    const char *p;
185
    p = strchr(filename, ':');
186
    if (!p)
187
        return &bdrv_raw;
188
    len = p - filename;
189
    if (len > sizeof(protocol) - 1)
190
        len = sizeof(protocol) - 1;
191
#ifdef _WIN32
192
    if (len == 1) {
193
        /* specific win32 case for driver letters */
194
        return &bdrv_raw;
195
    }
196
#endif   
197
    memcpy(protocol, filename, len);
198
    protocol[len] = '\0';
199
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
200
        if (drv1->protocol_name && 
201
            !strcmp(drv1->protocol_name, protocol))
202
            return drv1;
203
    }
204
    return NULL;
205
}
206

    
207
/* XXX: force raw format if block or character device ? It would
208
   simplify the BSD case */
209
static BlockDriver *find_image_format(const char *filename)
210
{
211
    int ret, score, score_max;
212
    BlockDriver *drv1, *drv;
213
    uint8_t buf[2048];
214
    BlockDriverState *bs;
215
    
216
    drv = find_protocol(filename);
217
    /* no need to test disk image formats for vvfat or host specific
218
       devices */
219
    if (drv == &bdrv_vvfat)
220
        return drv;
221
    if (strstart(filename, "/dev/", NULL))
222
        return &bdrv_raw;
223
    
224
    ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
225
    if (ret < 0)
226
        return NULL;
227
    ret = bdrv_pread(bs, 0, buf, sizeof(buf));
228
    bdrv_delete(bs);
229
    if (ret < 0) {
230
        return NULL;
231
    }
232

    
233
    score_max = 0;
234
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
235
        if (drv1->bdrv_probe) {
236
            score = drv1->bdrv_probe(buf, ret, filename);
237
            if (score > score_max) {
238
                score_max = score;
239
                drv = drv1;
240
            }
241
        }
242
    }
243
    return drv;
244
}
245

    
246
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
247
{
248
    BlockDriverState *bs;
249
    int ret;
250

    
251
    bs = bdrv_new("");
252
    if (!bs)
253
        return -ENOMEM;
254
    ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
255
    if (ret < 0) {
256
        bdrv_delete(bs);
257
        return ret;
258
    }
259
    *pbs = bs;
260
    return 0;
261
}
262

    
263
int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
264
{
265
    return bdrv_open2(bs, filename, flags, NULL);
266
}
267

    
268
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
269
               BlockDriver *drv)
270
{
271
    int ret, open_flags;
272
    char tmp_filename[1024];
273
    char backing_filename[1024];
274
    
275
    bs->read_only = 0;
276
    bs->is_temporary = 0;
277
    bs->encrypted = 0;
278

    
279
    if (flags & BDRV_O_SNAPSHOT) {
280
        BlockDriverState *bs1;
281
        int64_t total_size;
282
        
283
        /* if snapshot, we create a temporary backing file and open it
284
           instead of opening 'filename' directly */
285

    
286
        /* if there is a backing file, use it */
287
        bs1 = bdrv_new("");
288
        if (!bs1) {
289
            return -ENOMEM;
290
        }
291
        if (bdrv_open(bs1, filename, 0) < 0) {
292
            bdrv_delete(bs1);
293
            return -1;
294
        }
295
        total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
296
        bdrv_delete(bs1);
297
        
298
        get_tmp_filename(tmp_filename, sizeof(tmp_filename));
299
        if (bdrv_create(&bdrv_qcow, tmp_filename, 
300
                        total_size, filename, 0) < 0) {
301
            return -1;
302
        }
303
        filename = tmp_filename;
304
        bs->is_temporary = 1;
305
    }
306

    
307
    pstrcpy(bs->filename, sizeof(bs->filename), filename);
308
    if (flags & BDRV_O_FILE) {
309
        drv = find_protocol(filename);
310
        if (!drv)
311
            return -ENOENT;
312
    } else {
313
        if (!drv) {
314
            drv = find_image_format(filename);
315
            if (!drv)
316
                return -1;
317
        }
318
    }
319
    bs->drv = drv;
320
    bs->opaque = qemu_mallocz(drv->instance_size);
321
    if (bs->opaque == NULL && drv->instance_size > 0)
322
        return -1;
323
    /* Note: for compatibility, we open disk image files as RDWR, and
324
       RDONLY as fallback */
325
    if (!(flags & BDRV_O_FILE))
326
        open_flags = BDRV_O_RDWR;
327
    else
328
        open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
329
    ret = drv->bdrv_open(bs, filename, open_flags);
330
    if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
331
        ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
332
        bs->read_only = 1;
333
    }
334
    if (ret < 0) {
335
        qemu_free(bs->opaque);
336
        return ret;
337
    }
338

    
339
#ifndef _WIN32
340
    if (bs->is_temporary) {
341
        unlink(filename);
342
    }
343
#endif
344
    if (bs->backing_file[0] != '\0') {
345
        /* if there is a backing file, use it */
346
        bs->backing_hd = bdrv_new("");
347
        if (!bs->backing_hd) {
348
        fail:
349
            bdrv_close(bs);
350
            return -1;
351
        }
352
        path_combine(backing_filename, sizeof(backing_filename),
353
                     filename, bs->backing_file);
354
        if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
355
            goto fail;
356
    }
357

    
358
    bs->inserted = 1;
359

    
360
    /* call the change callback */
361
    if (bs->change_cb)
362
        bs->change_cb(bs->change_opaque);
363

    
364
    return 0;
365
}
366

    
367
void bdrv_close(BlockDriverState *bs)
368
{
369
    if (bs->inserted) {
370
        if (bs->backing_hd)
371
            bdrv_delete(bs->backing_hd);
372
        bs->drv->bdrv_close(bs);
373
        qemu_free(bs->opaque);
374
#ifdef _WIN32
375
        if (bs->is_temporary) {
376
            unlink(bs->filename);
377
        }
378
#endif
379
        bs->opaque = NULL;
380
        bs->drv = NULL;
381
        bs->inserted = 0;
382

    
383
        /* call the change callback */
384
        if (bs->change_cb)
385
            bs->change_cb(bs->change_opaque);
386
    }
387
}
388

    
389
void bdrv_delete(BlockDriverState *bs)
390
{
391
    /* XXX: remove the driver list */
392
    bdrv_close(bs);
393
    qemu_free(bs);
394
}
395

    
396
/* commit COW file into the raw image */
397
int bdrv_commit(BlockDriverState *bs)
398
{
399
    int64_t i, total_sectors;
400
    int n, j;
401
    unsigned char sector[512];
402

    
403
    if (!bs->inserted)
404
        return -ENOENT;
405

    
406
    if (bs->read_only) {
407
        return -EACCES;
408
    }
409

    
410
    if (!bs->backing_hd) {
411
        return -ENOTSUP;
412
    }
413

    
414
    total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
415
    for (i = 0; i < total_sectors;) {
416
        if (bs->drv->bdrv_is_allocated(bs, i, 65536, &n)) {
417
            for(j = 0; j < n; j++) {
418
                if (bdrv_read(bs, i, sector, 1) != 0) {
419
                    return -EIO;
420
                }
421

    
422
                if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
423
                    return -EIO;
424
                }
425
                i++;
426
            }
427
        } else {
428
            i += n;
429
        }
430
    }
431

    
432
    if (bs->drv->bdrv_make_empty)
433
        return bs->drv->bdrv_make_empty(bs);
434

    
435
    return 0;
436
}
437

    
438
/* return < 0 if error */
439
int bdrv_read(BlockDriverState *bs, int64_t sector_num, 
440
              uint8_t *buf, int nb_sectors)
441
{
442
    BlockDriver *drv = bs->drv;
443

    
444
    if (!bs->inserted)
445
        return -1;
446

    
447
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
448
            memcpy(buf, bs->boot_sector_data, 512);
449
        sector_num++;
450
        nb_sectors--;
451
        buf += 512;
452
        if (nb_sectors == 0)
453
            return 0;
454
    }
455
    if (drv->bdrv_pread) {
456
        int ret, len;
457
        len = nb_sectors * 512;
458
        ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
459
        if (ret < 0)
460
            return ret;
461
        else if (ret != len)
462
            return -EIO;
463
        else
464
            return 0;
465
    } else {
466
        return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
467
    }
468
}
469

    
470
/* return < 0 if error */
471
int bdrv_write(BlockDriverState *bs, int64_t sector_num, 
472
               const uint8_t *buf, int nb_sectors)
473
{
474
    BlockDriver *drv = bs->drv;
475
    if (!bs->inserted)
476
        return -1;
477
    if (bs->read_only)
478
        return -1;
479
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
480
        memcpy(bs->boot_sector_data, buf, 512);   
481
    }
482
    if (drv->bdrv_pwrite) {
483
        int ret, len;
484
        len = nb_sectors * 512;
485
        ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
486
        if (ret < 0)
487
            return ret;
488
        else if (ret != len)
489
            return -EIO;
490
        else
491
            return 0;
492
    } else {
493
        return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
494
    }
495
}
496

    
497
#if 0
498
/* not necessary now */
499
static int bdrv_pread_em(BlockDriverState *bs, int64_t offset, 
500
                         void *buf1, int count1)
501
{
502
    uint8_t *buf = buf1;
503
    uint8_t tmp_buf[SECTOR_SIZE];
504
    int len, nb_sectors, count;
505
    int64_t sector_num;
506

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

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

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

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

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

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

582
    /* add data from the last sector */
583
    if (count > 0) {
584
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
585
            return -EIO;
586
        memcpy(tmp_buf, buf, count);
587
        if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
588
            return -EIO;
589
    }
590
    return count1;
591
}
592
#endif
593

    
594
/**
595
 * Read with byte offsets (needed only for file protocols) 
596
 */
597
int bdrv_pread(BlockDriverState *bs, int64_t offset, 
598
               void *buf1, int count1)
599
{
600
    BlockDriver *drv = bs->drv;
601

    
602
    if (!drv)
603
        return -ENOENT;
604
    if (!drv->bdrv_pread)
605
        return -ENOTSUP;
606
    return drv->bdrv_pread(bs, offset, buf1, count1);
607
}
608

    
609
/** 
610
 * Write with byte offsets (needed only for file protocols) 
611
 */
612
int bdrv_pwrite(BlockDriverState *bs, int64_t offset, 
613
                const void *buf1, int count1)
614
{
615
    BlockDriver *drv = bs->drv;
616

    
617
    if (!drv)
618
        return -ENOENT;
619
    if (!drv->bdrv_pwrite)
620
        return -ENOTSUP;
621
    return drv->bdrv_pwrite(bs, offset, buf1, count1);
622
}
623

    
624
/**
625
 * Truncate file to 'offset' bytes (needed only for file protocols)
626
 */
627
int bdrv_truncate(BlockDriverState *bs, int64_t offset)
628
{
629
    BlockDriver *drv = bs->drv;
630
    if (!drv)
631
        return -ENOENT;
632
    if (!drv->bdrv_truncate)
633
        return -ENOTSUP;
634
    return drv->bdrv_truncate(bs, offset);
635
}
636

    
637
/**
638
 * Length of a file in bytes. Return < 0 if error or unknown.
639
 */
640
int64_t bdrv_getlength(BlockDriverState *bs)
641
{
642
    BlockDriver *drv = bs->drv;
643
    if (!drv)
644
        return -ENOENT;
645
    if (!drv->bdrv_getlength) {
646
        /* legacy mode */
647
        return bs->total_sectors * SECTOR_SIZE;
648
    }
649
    return drv->bdrv_getlength(bs);
650
}
651

    
652
void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
653
{
654
    int64_t size;
655
    size = bdrv_getlength(bs);
656
    if (size < 0)
657
        size = 0;
658
    *nb_sectors_ptr = size >> SECTOR_BITS;
659
}
660

    
661
/* force a given boot sector. */
662
void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
663
{
664
    bs->boot_sector_enabled = 1;
665
    if (size > 512)
666
        size = 512;
667
    memcpy(bs->boot_sector_data, data, size);
668
    memset(bs->boot_sector_data + size, 0, 512 - size);
669
}
670

    
671
void bdrv_set_geometry_hint(BlockDriverState *bs, 
672
                            int cyls, int heads, int secs)
673
{
674
    bs->cyls = cyls;
675
    bs->heads = heads;
676
    bs->secs = secs;
677
}
678

    
679
void bdrv_set_type_hint(BlockDriverState *bs, int type)
680
{
681
    bs->type = type;
682
    bs->removable = ((type == BDRV_TYPE_CDROM ||
683
                      type == BDRV_TYPE_FLOPPY));
684
}
685

    
686
void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
687
{
688
    bs->translation = translation;
689
}
690

    
691
void bdrv_get_geometry_hint(BlockDriverState *bs, 
692
                            int *pcyls, int *pheads, int *psecs)
693
{
694
    *pcyls = bs->cyls;
695
    *pheads = bs->heads;
696
    *psecs = bs->secs;
697
}
698

    
699
int bdrv_get_type_hint(BlockDriverState *bs)
700
{
701
    return bs->type;
702
}
703

    
704
int bdrv_get_translation_hint(BlockDriverState *bs)
705
{
706
    return bs->translation;
707
}
708

    
709
int bdrv_is_removable(BlockDriverState *bs)
710
{
711
    return bs->removable;
712
}
713

    
714
int bdrv_is_read_only(BlockDriverState *bs)
715
{
716
    return bs->read_only;
717
}
718

    
719
int bdrv_is_inserted(BlockDriverState *bs)
720
{
721
    return bs->inserted;
722
}
723

    
724
int bdrv_is_locked(BlockDriverState *bs)
725
{
726
    return bs->locked;
727
}
728

    
729
void bdrv_set_locked(BlockDriverState *bs, int locked)
730
{
731
    bs->locked = locked;
732
}
733

    
734
void bdrv_set_change_cb(BlockDriverState *bs, 
735
                        void (*change_cb)(void *opaque), void *opaque)
736
{
737
    bs->change_cb = change_cb;
738
    bs->change_opaque = opaque;
739
}
740

    
741
int bdrv_is_encrypted(BlockDriverState *bs)
742
{
743
    if (bs->backing_hd && bs->backing_hd->encrypted)
744
        return 1;
745
    return bs->encrypted;
746
}
747

    
748
int bdrv_set_key(BlockDriverState *bs, const char *key)
749
{
750
    int ret;
751
    if (bs->backing_hd && bs->backing_hd->encrypted) {
752
        ret = bdrv_set_key(bs->backing_hd, key);
753
        if (ret < 0)
754
            return ret;
755
        if (!bs->encrypted)
756
            return 0;
757
    }
758
    if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
759
        return -1;
760
    return bs->drv->bdrv_set_key(bs, key);
761
}
762

    
763
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
764
{
765
    if (!bs->inserted || !bs->drv) {
766
        buf[0] = '\0';
767
    } else {
768
        pstrcpy(buf, buf_size, bs->drv->format_name);
769
    }
770
}
771

    
772
void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 
773
                         void *opaque)
774
{
775
    BlockDriver *drv;
776

    
777
    for (drv = first_drv; drv != NULL; drv = drv->next) {
778
        it(opaque, drv->format_name);
779
    }
780
}
781

    
782
BlockDriverState *bdrv_find(const char *name)
783
{
784
    BlockDriverState *bs;
785

    
786
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
787
        if (!strcmp(name, bs->device_name))
788
            return bs;
789
    }
790
    return NULL;
791
}
792

    
793
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
794
{
795
    BlockDriverState *bs;
796

    
797
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
798
        it(opaque, bs->device_name);
799
    }
800
}
801

    
802
const char *bdrv_get_device_name(BlockDriverState *bs)
803
{
804
    return bs->device_name;
805
}
806

    
807
void bdrv_flush(BlockDriverState *bs)
808
{
809
    if (bs->drv->bdrv_flush)
810
        bs->drv->bdrv_flush(bs);
811
    if (bs->backing_hd)
812
        bdrv_flush(bs->backing_hd);
813
}
814

    
815
void bdrv_info(void)
816
{
817
    BlockDriverState *bs;
818

    
819
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
820
        term_printf("%s:", bs->device_name);
821
        term_printf(" type=");
822
        switch(bs->type) {
823
        case BDRV_TYPE_HD:
824
            term_printf("hd");
825
            break;
826
        case BDRV_TYPE_CDROM:
827
            term_printf("cdrom");
828
            break;
829
        case BDRV_TYPE_FLOPPY:
830
            term_printf("floppy");
831
            break;
832
        }
833
        term_printf(" removable=%d", bs->removable);
834
        if (bs->removable) {
835
            term_printf(" locked=%d", bs->locked);
836
        }
837
        if (bs->inserted) {
838
            term_printf(" file=%s", bs->filename);
839
            if (bs->backing_file[0] != '\0')
840
                term_printf(" backing_file=%s", bs->backing_file);
841
            term_printf(" ro=%d", bs->read_only);
842
            term_printf(" drv=%s", bs->drv->format_name);
843
            if (bs->encrypted)
844
                term_printf(" encrypted");
845
        } else {
846
            term_printf(" [not inserted]");
847
        }
848
        term_printf("\n");
849
    }
850
}
851

    
852
void bdrv_get_backing_filename(BlockDriverState *bs, 
853
                               char *filename, int filename_size)
854
{
855
    if (!bs->backing_hd) {
856
        pstrcpy(filename, filename_size, "");
857
    } else {
858
        pstrcpy(filename, filename_size, bs->backing_file);
859
    }
860
}
861

    
862

    
863
/**************************************************************/
864
/* async I/Os */
865

    
866
BlockDriverAIOCB *bdrv_aio_new(BlockDriverState *bs)
867
{
868
    BlockDriver *drv = bs->drv;
869
    BlockDriverAIOCB *acb;
870
    acb = qemu_mallocz(sizeof(BlockDriverAIOCB));
871
    if (!acb)
872
        return NULL;
873
    
874
    acb->bs = bs;
875
    if (drv->bdrv_aio_new(acb) < 0) {
876
        qemu_free(acb);
877
        return NULL;
878
    }
879
    return acb;
880
}
881

    
882
int bdrv_aio_read(BlockDriverAIOCB *acb, int64_t sector_num,
883
                  uint8_t *buf, int nb_sectors,
884
                  BlockDriverCompletionFunc *cb, void *opaque)
885
{
886
    BlockDriverState *bs = acb->bs;
887
    BlockDriver *drv = bs->drv;
888

    
889
    if (!bs->inserted)
890
        return -1;
891
    
892
    /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
893
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
894
        memcpy(buf, bs->boot_sector_data, 512);
895
        sector_num++;
896
        nb_sectors--;
897
        buf += 512;
898
    }
899

    
900
    acb->cb = cb;
901
    acb->cb_opaque = opaque;
902
    return drv->bdrv_aio_read(acb, sector_num, buf, nb_sectors);
903
}
904

    
905
int bdrv_aio_write(BlockDriverAIOCB *acb, int64_t sector_num,
906
                   const uint8_t *buf, int nb_sectors,
907
                   BlockDriverCompletionFunc *cb, void *opaque)
908
{
909
    BlockDriverState *bs = acb->bs;
910
    BlockDriver *drv = bs->drv;
911

    
912
    if (!bs->inserted)
913
            return -1;
914
    if (bs->read_only)
915
        return -1;
916
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
917
        memcpy(bs->boot_sector_data, buf, 512);   
918
    }
919

    
920
    acb->cb = cb;
921
    acb->cb_opaque = opaque;
922
    return drv->bdrv_aio_write(acb, sector_num, buf, nb_sectors);
923
}
924

    
925
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
926
    {
927
    BlockDriverState *bs = acb->bs;
928
    BlockDriver *drv = bs->drv;
929

    
930
    drv->bdrv_aio_cancel(acb);
931
    }
932

    
933
void bdrv_aio_delete(BlockDriverAIOCB *acb)
934
{
935
    BlockDriverState *bs = acb->bs;
936
    BlockDriver *drv = bs->drv;
937

    
938
    drv->bdrv_aio_delete(acb);
939
    qemu_free(acb);
940
}
941

    
942
/**************************************************************/
943
/* async block device emulation */
944

    
945
#ifdef QEMU_TOOL
946
static int bdrv_aio_new_em(BlockDriverAIOCB *acb)
947
{
948
    return 0;
949
}
950

    
951
static int bdrv_aio_read_em(BlockDriverAIOCB *acb, int64_t sector_num,
952
                    uint8_t *buf, int nb_sectors)
953
{
954
    int ret;
955
    ret = bdrv_read(acb->bs, sector_num, buf, nb_sectors);
956
    acb->cb(acb->cb_opaque, ret);
957
    return 0;
958
}
959

    
960
static int bdrv_aio_write_em(BlockDriverAIOCB *acb, int64_t sector_num,
961
                     const uint8_t *buf, int nb_sectors)
962
{
963
    int ret;
964
    ret = bdrv_write(acb->bs, sector_num, buf, nb_sectors);
965
    acb->cb(acb->cb_opaque, ret);
966
    return 0;
967
}
968

    
969
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
970
{
971
}
972

    
973
static void bdrv_aio_delete_em(BlockDriverAIOCB *acb)
974
{
975
}
976
#else
977
typedef struct BlockDriverAIOCBSync {
978
    QEMUBH *bh;
979
    int ret;
980
} BlockDriverAIOCBSync;
981

    
982
static void bdrv_aio_bh_cb(void *opaque)
983
{
984
    BlockDriverAIOCB *acb = opaque;
985
    BlockDriverAIOCBSync *acb1 = acb->opaque;
986
    acb->cb(acb->cb_opaque, acb1->ret);
987
}
988

    
989
static int bdrv_aio_new_em(BlockDriverAIOCB *acb)
990
{
991
    BlockDriverAIOCBSync *acb1;
992

    
993
    acb1 = qemu_mallocz(sizeof(BlockDriverAIOCBSync));
994
    if (!acb1)
995
        return -1;
996
    acb->opaque = acb1;
997
    acb1->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
998
    return 0;
999
}
1000

    
1001
static int bdrv_aio_read_em(BlockDriverAIOCB *acb, int64_t sector_num,
1002
                    uint8_t *buf, int nb_sectors)
1003
{
1004
    BlockDriverAIOCBSync *acb1 = acb->opaque;
1005
    int ret;
1006
    
1007
    ret = bdrv_read(acb->bs, sector_num, buf, nb_sectors);
1008
    acb1->ret = ret;
1009
    qemu_bh_schedule(acb1->bh);
1010
    return 0;
1011
}
1012

    
1013
static int bdrv_aio_write_em(BlockDriverAIOCB *acb, int64_t sector_num,
1014
                     const uint8_t *buf, int nb_sectors)
1015
{
1016
    BlockDriverAIOCBSync *acb1 = acb->opaque;
1017
    int ret;
1018
    
1019
    ret = bdrv_write(acb->bs, sector_num, buf, nb_sectors);
1020
    acb1->ret = ret;
1021
    qemu_bh_schedule(acb1->bh);
1022
    return 0;
1023
}
1024

    
1025
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb)
1026
{
1027
    BlockDriverAIOCBSync *acb1 = acb->opaque;
1028
    qemu_bh_cancel(acb1->bh);
1029
}
1030

    
1031
static void bdrv_aio_delete_em(BlockDriverAIOCB *acb)
1032
{
1033
    BlockDriverAIOCBSync *acb1 = acb->opaque;
1034
    qemu_bh_delete(acb1->bh);
1035
}
1036
#endif /* !QEMU_TOOL */
1037

    
1038
/**************************************************************/
1039
/* sync block device emulation */
1040

    
1041
static void bdrv_rw_em_cb(void *opaque, int ret)
1042
{
1043
    *(int *)opaque = ret;
1044
}
1045

    
1046
#define NOT_DONE 0x7fffffff
1047

    
1048
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, 
1049
                        uint8_t *buf, int nb_sectors)
1050
{
1051
    int async_ret, ret;
1052

    
1053
    if (!bs->sync_aiocb) {
1054
        bs->sync_aiocb = bdrv_aio_new(bs);
1055
        if (!bs->sync_aiocb)
1056
            return -1;
1057
    }
1058
    async_ret = NOT_DONE;
1059
    qemu_aio_wait_start();
1060
    ret = bdrv_aio_read(bs->sync_aiocb, sector_num, buf, nb_sectors, 
1061
                        bdrv_rw_em_cb, &async_ret);
1062
    if (ret < 0) {
1063
        qemu_aio_wait_end();
1064
        return ret;
1065
    }
1066
    while (async_ret == NOT_DONE) {
1067
        qemu_aio_wait();
1068
    }
1069
    qemu_aio_wait_end();
1070
    return async_ret;
1071
}
1072

    
1073
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
1074
                         const uint8_t *buf, int nb_sectors)
1075
{
1076
    int async_ret, ret;
1077

    
1078
    if (!bs->sync_aiocb) {
1079
        bs->sync_aiocb = bdrv_aio_new(bs);
1080
        if (!bs->sync_aiocb)
1081
            return -1;
1082
    }
1083
    async_ret = NOT_DONE;
1084
    qemu_aio_wait_start();
1085
    ret = bdrv_aio_write(bs->sync_aiocb, sector_num, buf, nb_sectors, 
1086
                         bdrv_rw_em_cb, &async_ret);
1087
    if (ret < 0) {
1088
        qemu_aio_wait_end();
1089
        return ret;
1090
    }
1091
    while (async_ret == NOT_DONE) {
1092
        qemu_aio_wait();
1093
    }
1094
    qemu_aio_wait_end();
1095
    return async_ret;
1096
}
1097

    
1098
void bdrv_init(void)
1099
{
1100
    bdrv_register(&bdrv_raw);
1101
#ifndef _WIN32
1102
    bdrv_register(&bdrv_cow);
1103
#endif
1104
    bdrv_register(&bdrv_qcow);
1105
    bdrv_register(&bdrv_vmdk);
1106
    bdrv_register(&bdrv_cloop);
1107
    bdrv_register(&bdrv_dmg);
1108
    bdrv_register(&bdrv_bochs);
1109
    bdrv_register(&bdrv_vpc);
1110
    bdrv_register(&bdrv_vvfat);
1111
}