Statistics
| Branch: | Revision:

root / block.c @ 03ff3ca3

History | View | Annotate | Download (36.2 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 "qemu-common.h"
25
#include "console.h"
26
#include "block_int.h"
27

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

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

    
39
typedef struct BlockDriverAIOCBSync {
40
    BlockDriverAIOCB common;
41
    QEMUBH *bh;
42
    int ret;
43
} BlockDriverAIOCBSync;
44

    
45
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
46
        int64_t sector_num, uint8_t *buf, int nb_sectors,
47
        BlockDriverCompletionFunc *cb, void *opaque);
48
static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
49
        int64_t sector_num, const uint8_t *buf, int nb_sectors,
50
        BlockDriverCompletionFunc *cb, void *opaque);
51
static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
52
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
53
                        uint8_t *buf, int nb_sectors);
54
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
55
                         const uint8_t *buf, int nb_sectors);
56

    
57
static BlockDriver *first_drv;
58

    
59
int path_is_absolute(const char *path)
60
{
61
    const char *p;
62
#ifdef _WIN32
63
    /* specific case for names like: "\\.\d:" */
64
    if (*path == '/' || *path == '\\')
65
        return 1;
66
#endif
67
    p = strchr(path, ':');
68
    if (p)
69
        p++;
70
    else
71
        p = path;
72
#ifdef _WIN32
73
    return (*p == '/' || *p == '\\');
74
#else
75
    return (*p == '/');
76
#endif
77
}
78

    
79
/* if filename is absolute, just copy it to dest. Otherwise, build a
80
   path to it by considering it is relative to base_path. URL are
81
   supported. */
82
void path_combine(char *dest, int dest_size,
83
                  const char *base_path,
84
                  const char *filename)
85
{
86
    const char *p, *p1;
87
    int len;
88

    
89
    if (dest_size <= 0)
90
        return;
91
    if (path_is_absolute(filename)) {
92
        pstrcpy(dest, dest_size, filename);
93
    } else {
94
        p = strchr(base_path, ':');
95
        if (p)
96
            p++;
97
        else
98
            p = base_path;
99
        p1 = strrchr(base_path, '/');
100
#ifdef _WIN32
101
        {
102
            const char *p2;
103
            p2 = strrchr(base_path, '\\');
104
            if (!p1 || p2 > p1)
105
                p1 = p2;
106
        }
107
#endif
108
        if (p1)
109
            p1++;
110
        else
111
            p1 = base_path;
112
        if (p1 > p)
113
            p = p1;
114
        len = p - base_path;
115
        if (len > dest_size - 1)
116
            len = dest_size - 1;
117
        memcpy(dest, base_path, len);
118
        dest[len] = '\0';
119
        pstrcat(dest, dest_size, filename);
120
    }
121
}
122

    
123

    
124
static void bdrv_register(BlockDriver *bdrv)
125
{
126
    if (!bdrv->bdrv_aio_read) {
127
        /* add AIO emulation layer */
128
        bdrv->bdrv_aio_read = bdrv_aio_read_em;
129
        bdrv->bdrv_aio_write = bdrv_aio_write_em;
130
        bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
131
        bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
132
    } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
133
        /* add synchronous IO emulation layer */
134
        bdrv->bdrv_read = bdrv_read_em;
135
        bdrv->bdrv_write = bdrv_write_em;
136
    }
137
    bdrv->next = first_drv;
138
    first_drv = bdrv;
139
}
140

    
141
/* create a new block device (by default it is empty) */
142
BlockDriverState *bdrv_new(const char *device_name)
143
{
144
    BlockDriverState **pbs, *bs;
145

    
146
    bs = qemu_mallocz(sizeof(BlockDriverState));
147
    if(!bs)
148
        return NULL;
149
    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
150
    if (device_name[0] != '\0') {
151
        /* insert at the end */
152
        pbs = &bdrv_first;
153
        while (*pbs != NULL)
154
            pbs = &(*pbs)->next;
155
        *pbs = bs;
156
    }
157
    return bs;
158
}
159

    
160
BlockDriver *bdrv_find_format(const char *format_name)
161
{
162
    BlockDriver *drv1;
163
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
164
        if (!strcmp(drv1->format_name, format_name))
165
            return drv1;
166
    }
167
    return NULL;
168
}
169

    
170
int bdrv_create(BlockDriver *drv,
171
                const char *filename, int64_t size_in_sectors,
172
                const char *backing_file, int flags)
173
{
174
    if (!drv->bdrv_create)
175
        return -ENOTSUP;
176
    return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
177
}
178

    
179
#ifdef _WIN32
180
void get_tmp_filename(char *filename, int size)
181
{
182
    char temp_dir[MAX_PATH];
183

    
184
    GetTempPath(MAX_PATH, temp_dir);
185
    GetTempFileName(temp_dir, "qem", 0, filename);
186
}
187
#else
188
void get_tmp_filename(char *filename, int size)
189
{
190
    int fd;
191
    const char *tmpdir;
192
    /* XXX: race condition possible */
193
    tmpdir = getenv("TMPDIR");
194
    if (!tmpdir)
195
        tmpdir = "/tmp";
196
    snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
197
    fd = mkstemp(filename);
198
    close(fd);
199
}
200
#endif
201

    
202
#ifdef _WIN32
203
static int is_windows_drive_prefix(const char *filename)
204
{
205
    return (((filename[0] >= 'a' && filename[0] <= 'z') ||
206
             (filename[0] >= 'A' && filename[0] <= 'Z')) &&
207
            filename[1] == ':');
208
}
209

    
210
static int is_windows_drive(const char *filename)
211
{
212
    if (is_windows_drive_prefix(filename) &&
213
        filename[2] == '\0')
214
        return 1;
215
    if (strstart(filename, "\\\\.\\", NULL) ||
216
        strstart(filename, "//./", NULL))
217
        return 1;
218
    return 0;
219
}
220
#endif
221

    
222
static BlockDriver *find_protocol(const char *filename)
223
{
224
    BlockDriver *drv1;
225
    char protocol[128];
226
    int len;
227
    const char *p;
228

    
229
#ifdef _WIN32
230
    if (is_windows_drive(filename) ||
231
        is_windows_drive_prefix(filename))
232
        return &bdrv_raw;
233
#endif
234
    p = strchr(filename, ':');
235
    if (!p)
236
        return &bdrv_raw;
237
    len = p - filename;
238
    if (len > sizeof(protocol) - 1)
239
        len = sizeof(protocol) - 1;
240
    memcpy(protocol, filename, len);
241
    protocol[len] = '\0';
242
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
243
        if (drv1->protocol_name &&
244
            !strcmp(drv1->protocol_name, protocol))
245
            return drv1;
246
    }
247
    return NULL;
248
}
249

    
250
/* XXX: force raw format if block or character device ? It would
251
   simplify the BSD case */
252
static BlockDriver *find_image_format(const char *filename)
253
{
254
    int ret, score, score_max;
255
    BlockDriver *drv1, *drv;
256
    uint8_t buf[2048];
257
    BlockDriverState *bs;
258

    
259
    /* detect host devices. By convention, /dev/cdrom[N] is always
260
       recognized as a host CDROM */
261
    if (strstart(filename, "/dev/cdrom", NULL))
262
        return &bdrv_host_device;
263
#ifdef _WIN32
264
    if (is_windows_drive(filename))
265
        return &bdrv_host_device;
266
#else
267
    {
268
        struct stat st;
269
        if (stat(filename, &st) >= 0 &&
270
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
271
            return &bdrv_host_device;
272
        }
273
    }
274
#endif
275

    
276
    drv = find_protocol(filename);
277
    /* no need to test disk image formats for vvfat */
278
    if (drv == &bdrv_vvfat)
279
        return drv;
280

    
281
    ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
282
    if (ret < 0)
283
        return NULL;
284
    ret = bdrv_pread(bs, 0, buf, sizeof(buf));
285
    bdrv_delete(bs);
286
    if (ret < 0) {
287
        return NULL;
288
    }
289

    
290
    score_max = 0;
291
    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
292
        if (drv1->bdrv_probe) {
293
            score = drv1->bdrv_probe(buf, ret, filename);
294
            if (score > score_max) {
295
                score_max = score;
296
                drv = drv1;
297
            }
298
        }
299
    }
300
    return drv;
301
}
302

    
303
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
304
{
305
    BlockDriverState *bs;
306
    int ret;
307

    
308
    bs = bdrv_new("");
309
    if (!bs)
310
        return -ENOMEM;
311
    ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
312
    if (ret < 0) {
313
        bdrv_delete(bs);
314
        return ret;
315
    }
316
    *pbs = bs;
317
    return 0;
318
}
319

    
320
int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
321
{
322
    return bdrv_open2(bs, filename, flags, NULL);
323
}
324

    
325
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
326
               BlockDriver *drv)
327
{
328
    int ret, open_flags;
329
    char tmp_filename[PATH_MAX];
330
    char backing_filename[PATH_MAX];
331

    
332
    bs->read_only = 0;
333
    bs->is_temporary = 0;
334
    bs->encrypted = 0;
335

    
336
    if (flags & BDRV_O_SNAPSHOT) {
337
        BlockDriverState *bs1;
338
        int64_t total_size;
339
        int is_protocol = 0;
340

    
341
        /* if snapshot, we create a temporary backing file and open it
342
           instead of opening 'filename' directly */
343

    
344
        /* if there is a backing file, use it */
345
        bs1 = bdrv_new("");
346
        if (!bs1) {
347
            return -ENOMEM;
348
        }
349
        if (bdrv_open(bs1, filename, 0) < 0) {
350
            bdrv_delete(bs1);
351
            return -1;
352
        }
353
        total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
354

    
355
        if (bs1->drv && bs1->drv->protocol_name)
356
            is_protocol = 1;
357

    
358
        bdrv_delete(bs1);
359

    
360
        get_tmp_filename(tmp_filename, sizeof(tmp_filename));
361

    
362
        /* Real path is meaningless for protocols */
363
        if (is_protocol)
364
            snprintf(backing_filename, sizeof(backing_filename),
365
                     "%s", filename);
366
        else
367
            realpath(filename, backing_filename);
368

    
369
        if (bdrv_create(&bdrv_qcow2, tmp_filename,
370
                        total_size, backing_filename, 0) < 0) {
371
            return -1;
372
        }
373
        filename = tmp_filename;
374
        bs->is_temporary = 1;
375
    }
376

    
377
    pstrcpy(bs->filename, sizeof(bs->filename), filename);
378
    if (flags & BDRV_O_FILE) {
379
        drv = find_protocol(filename);
380
        if (!drv)
381
            return -ENOENT;
382
    } else {
383
        if (!drv) {
384
            drv = find_image_format(filename);
385
            if (!drv)
386
                return -1;
387
        }
388
    }
389
    bs->drv = drv;
390
    bs->opaque = qemu_mallocz(drv->instance_size);
391
    if (bs->opaque == NULL && drv->instance_size > 0)
392
        return -1;
393
    /* Note: for compatibility, we open disk image files as RDWR, and
394
       RDONLY as fallback */
395
    if (!(flags & BDRV_O_FILE))
396
        open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
397
    else
398
        open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
399
    ret = drv->bdrv_open(bs, filename, open_flags);
400
    if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
401
        ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
402
        bs->read_only = 1;
403
    }
404
    if (ret < 0) {
405
        qemu_free(bs->opaque);
406
        bs->opaque = NULL;
407
        bs->drv = NULL;
408
        return ret;
409
    }
410
    if (drv->bdrv_getlength) {
411
        bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
412
    }
413
#ifndef _WIN32
414
    if (bs->is_temporary) {
415
        unlink(filename);
416
    }
417
#endif
418
    if (bs->backing_file[0] != '\0') {
419
        /* if there is a backing file, use it */
420
        bs->backing_hd = bdrv_new("");
421
        if (!bs->backing_hd) {
422
        fail:
423
            bdrv_close(bs);
424
            return -ENOMEM;
425
        }
426
        path_combine(backing_filename, sizeof(backing_filename),
427
                     filename, bs->backing_file);
428
        if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
429
            goto fail;
430
    }
431

    
432
    /* call the change callback */
433
    bs->media_changed = 1;
434
    if (bs->change_cb)
435
        bs->change_cb(bs->change_opaque);
436

    
437
    return 0;
438
}
439

    
440
void bdrv_close(BlockDriverState *bs)
441
{
442
    if (bs->drv) {
443
        if (bs->backing_hd)
444
            bdrv_delete(bs->backing_hd);
445
        bs->drv->bdrv_close(bs);
446
        qemu_free(bs->opaque);
447
#ifdef _WIN32
448
        if (bs->is_temporary) {
449
            unlink(bs->filename);
450
        }
451
#endif
452
        bs->opaque = NULL;
453
        bs->drv = NULL;
454

    
455
        /* call the change callback */
456
        bs->media_changed = 1;
457
        if (bs->change_cb)
458
            bs->change_cb(bs->change_opaque);
459
    }
460
}
461

    
462
void bdrv_delete(BlockDriverState *bs)
463
{
464
    BlockDriverState **pbs;
465

    
466
    pbs = &bdrv_first;
467
    while (*pbs != bs && *pbs != NULL)
468
        pbs = &(*pbs)->next;
469
    if (*pbs == bs)
470
        *pbs = bs->next;
471

    
472
    bdrv_close(bs);
473
    qemu_free(bs);
474
}
475

    
476
/* commit COW file into the raw image */
477
int bdrv_commit(BlockDriverState *bs)
478
{
479
    BlockDriver *drv = bs->drv;
480
    int64_t i, total_sectors;
481
    int n, j;
482
    unsigned char sector[512];
483

    
484
    if (!drv)
485
        return -ENOMEDIUM;
486

    
487
    if (bs->read_only) {
488
        return -EACCES;
489
    }
490

    
491
    if (!bs->backing_hd) {
492
        return -ENOTSUP;
493
    }
494

    
495
    total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
496
    for (i = 0; i < total_sectors;) {
497
        if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
498
            for(j = 0; j < n; j++) {
499
                if (bdrv_read(bs, i, sector, 1) != 0) {
500
                    return -EIO;
501
                }
502

    
503
                if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
504
                    return -EIO;
505
                }
506
                i++;
507
            }
508
        } else {
509
            i += n;
510
        }
511
    }
512

    
513
    if (drv->bdrv_make_empty)
514
        return drv->bdrv_make_empty(bs);
515

    
516
    return 0;
517
}
518

    
519
/* return < 0 if error. See bdrv_write() for the return codes */
520
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
521
              uint8_t *buf, int nb_sectors)
522
{
523
    BlockDriver *drv = bs->drv;
524

    
525
    if (!drv)
526
        return -ENOMEDIUM;
527

    
528
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
529
            memcpy(buf, bs->boot_sector_data, 512);
530
        sector_num++;
531
        nb_sectors--;
532
        buf += 512;
533
        if (nb_sectors == 0)
534
            return 0;
535
    }
536
    if (drv->bdrv_pread) {
537
        int ret, len;
538
        len = nb_sectors * 512;
539
        ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
540
        if (ret < 0)
541
            return ret;
542
        else if (ret != len)
543
            return -EINVAL;
544
        else {
545
            bs->rd_bytes += (unsigned) len;
546
            bs->rd_ops ++;
547
            return 0;
548
        }
549
    } else {
550
        return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
551
    }
552
}
553

    
554
/* Return < 0 if error. Important errors are:
555
  -EIO         generic I/O error (may happen for all errors)
556
  -ENOMEDIUM   No media inserted.
557
  -EINVAL      Invalid sector number or nb_sectors
558
  -EACCES      Trying to write a read-only device
559
*/
560
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
561
               const uint8_t *buf, int nb_sectors)
562
{
563
    BlockDriver *drv = bs->drv;
564
    if (!bs->drv)
565
        return -ENOMEDIUM;
566
    if (bs->read_only)
567
        return -EACCES;
568
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
569
        memcpy(bs->boot_sector_data, buf, 512);
570
    }
571
    if (drv->bdrv_pwrite) {
572
        int ret, len;
573
        len = nb_sectors * 512;
574
        ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
575
        if (ret < 0)
576
            return ret;
577
        else if (ret != len)
578
            return -EIO;
579
        else {
580
            bs->wr_bytes += (unsigned) len;
581
            bs->wr_ops ++;
582
            return 0;
583
        }
584
    } else {
585
        return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
586
    }
587
}
588

    
589
static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
590
                         uint8_t *buf, int count1)
591
{
592
    uint8_t tmp_buf[SECTOR_SIZE];
593
    int len, nb_sectors, count;
594
    int64_t sector_num;
595

    
596
    count = count1;
597
    /* first read to align to sector start */
598
    len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
599
    if (len > count)
600
        len = count;
601
    sector_num = offset >> SECTOR_BITS;
602
    if (len > 0) {
603
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
604
            return -EIO;
605
        memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
606
        count -= len;
607
        if (count == 0)
608
            return count1;
609
        sector_num++;
610
        buf += len;
611
    }
612

    
613
    /* read the sectors "in place" */
614
    nb_sectors = count >> SECTOR_BITS;
615
    if (nb_sectors > 0) {
616
        if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
617
            return -EIO;
618
        sector_num += nb_sectors;
619
        len = nb_sectors << SECTOR_BITS;
620
        buf += len;
621
        count -= len;
622
    }
623

    
624
    /* add data from the last sector */
625
    if (count > 0) {
626
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
627
            return -EIO;
628
        memcpy(buf, tmp_buf, count);
629
    }
630
    return count1;
631
}
632

    
633
static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
634
                          const uint8_t *buf, int count1)
635
{
636
    uint8_t tmp_buf[SECTOR_SIZE];
637
    int len, nb_sectors, count;
638
    int64_t sector_num;
639

    
640
    count = count1;
641
    /* first write to align to sector start */
642
    len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
643
    if (len > count)
644
        len = count;
645
    sector_num = offset >> SECTOR_BITS;
646
    if (len > 0) {
647
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
648
            return -EIO;
649
        memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
650
        if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
651
            return -EIO;
652
        count -= len;
653
        if (count == 0)
654
            return count1;
655
        sector_num++;
656
        buf += len;
657
    }
658

    
659
    /* write the sectors "in place" */
660
    nb_sectors = count >> SECTOR_BITS;
661
    if (nb_sectors > 0) {
662
        if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
663
            return -EIO;
664
        sector_num += nb_sectors;
665
        len = nb_sectors << SECTOR_BITS;
666
        buf += len;
667
        count -= len;
668
    }
669

    
670
    /* add data from the last sector */
671
    if (count > 0) {
672
        if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
673
            return -EIO;
674
        memcpy(tmp_buf, buf, count);
675
        if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
676
            return -EIO;
677
    }
678
    return count1;
679
}
680

    
681
/**
682
 * Read with byte offsets (needed only for file protocols)
683
 */
684
int bdrv_pread(BlockDriverState *bs, int64_t offset,
685
               void *buf1, int count1)
686
{
687
    BlockDriver *drv = bs->drv;
688

    
689
    if (!drv)
690
        return -ENOMEDIUM;
691
    if (!drv->bdrv_pread)
692
        return bdrv_pread_em(bs, offset, buf1, count1);
693
    return drv->bdrv_pread(bs, offset, buf1, count1);
694
}
695

    
696
/**
697
 * Write with byte offsets (needed only for file protocols)
698
 */
699
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
700
                const void *buf1, int count1)
701
{
702
    BlockDriver *drv = bs->drv;
703

    
704
    if (!drv)
705
        return -ENOMEDIUM;
706
    if (!drv->bdrv_pwrite)
707
        return bdrv_pwrite_em(bs, offset, buf1, count1);
708
    return drv->bdrv_pwrite(bs, offset, buf1, count1);
709
}
710

    
711
/**
712
 * Truncate file to 'offset' bytes (needed only for file protocols)
713
 */
714
int bdrv_truncate(BlockDriverState *bs, int64_t offset)
715
{
716
    BlockDriver *drv = bs->drv;
717
    if (!drv)
718
        return -ENOMEDIUM;
719
    if (!drv->bdrv_truncate)
720
        return -ENOTSUP;
721
    return drv->bdrv_truncate(bs, offset);
722
}
723

    
724
/**
725
 * Length of a file in bytes. Return < 0 if error or unknown.
726
 */
727
int64_t bdrv_getlength(BlockDriverState *bs)
728
{
729
    BlockDriver *drv = bs->drv;
730
    if (!drv)
731
        return -ENOMEDIUM;
732
    if (!drv->bdrv_getlength) {
733
        /* legacy mode */
734
        return bs->total_sectors * SECTOR_SIZE;
735
    }
736
    return drv->bdrv_getlength(bs);
737
}
738

    
739
/* return 0 as number of sectors if no device present or error */
740
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
741
{
742
    int64_t length;
743
    length = bdrv_getlength(bs);
744
    if (length < 0)
745
        length = 0;
746
    else
747
        length = length >> SECTOR_BITS;
748
    *nb_sectors_ptr = length;
749
}
750

    
751
/* force a given boot sector. */
752
void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
753
{
754
    bs->boot_sector_enabled = 1;
755
    if (size > 512)
756
        size = 512;
757
    memcpy(bs->boot_sector_data, data, size);
758
    memset(bs->boot_sector_data + size, 0, 512 - size);
759
}
760

    
761
void bdrv_set_geometry_hint(BlockDriverState *bs,
762
                            int cyls, int heads, int secs)
763
{
764
    bs->cyls = cyls;
765
    bs->heads = heads;
766
    bs->secs = secs;
767
}
768

    
769
void bdrv_set_type_hint(BlockDriverState *bs, int type)
770
{
771
    bs->type = type;
772
    bs->removable = ((type == BDRV_TYPE_CDROM ||
773
                      type == BDRV_TYPE_FLOPPY));
774
}
775

    
776
void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
777
{
778
    bs->translation = translation;
779
}
780

    
781
void bdrv_get_geometry_hint(BlockDriverState *bs,
782
                            int *pcyls, int *pheads, int *psecs)
783
{
784
    *pcyls = bs->cyls;
785
    *pheads = bs->heads;
786
    *psecs = bs->secs;
787
}
788

    
789
int bdrv_get_type_hint(BlockDriverState *bs)
790
{
791
    return bs->type;
792
}
793

    
794
int bdrv_get_translation_hint(BlockDriverState *bs)
795
{
796
    return bs->translation;
797
}
798

    
799
int bdrv_is_removable(BlockDriverState *bs)
800
{
801
    return bs->removable;
802
}
803

    
804
int bdrv_is_read_only(BlockDriverState *bs)
805
{
806
    return bs->read_only;
807
}
808

    
809
int bdrv_is_sg(BlockDriverState *bs)
810
{
811
    return bs->sg;
812
}
813

    
814
/* XXX: no longer used */
815
void bdrv_set_change_cb(BlockDriverState *bs,
816
                        void (*change_cb)(void *opaque), void *opaque)
817
{
818
    bs->change_cb = change_cb;
819
    bs->change_opaque = opaque;
820
}
821

    
822
int bdrv_is_encrypted(BlockDriverState *bs)
823
{
824
    if (bs->backing_hd && bs->backing_hd->encrypted)
825
        return 1;
826
    return bs->encrypted;
827
}
828

    
829
int bdrv_set_key(BlockDriverState *bs, const char *key)
830
{
831
    int ret;
832
    if (bs->backing_hd && bs->backing_hd->encrypted) {
833
        ret = bdrv_set_key(bs->backing_hd, key);
834
        if (ret < 0)
835
            return ret;
836
        if (!bs->encrypted)
837
            return 0;
838
    }
839
    if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
840
        return -1;
841
    return bs->drv->bdrv_set_key(bs, key);
842
}
843

    
844
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
845
{
846
    if (!bs->drv) {
847
        buf[0] = '\0';
848
    } else {
849
        pstrcpy(buf, buf_size, bs->drv->format_name);
850
    }
851
}
852

    
853
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
854
                         void *opaque)
855
{
856
    BlockDriver *drv;
857

    
858
    for (drv = first_drv; drv != NULL; drv = drv->next) {
859
        it(opaque, drv->format_name);
860
    }
861
}
862

    
863
BlockDriverState *bdrv_find(const char *name)
864
{
865
    BlockDriverState *bs;
866

    
867
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
868
        if (!strcmp(name, bs->device_name))
869
            return bs;
870
    }
871
    return NULL;
872
}
873

    
874
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
875
{
876
    BlockDriverState *bs;
877

    
878
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
879
        it(opaque, bs->device_name);
880
    }
881
}
882

    
883
const char *bdrv_get_device_name(BlockDriverState *bs)
884
{
885
    return bs->device_name;
886
}
887

    
888
void bdrv_flush(BlockDriverState *bs)
889
{
890
    if (bs->drv->bdrv_flush)
891
        bs->drv->bdrv_flush(bs);
892
    if (bs->backing_hd)
893
        bdrv_flush(bs->backing_hd);
894
}
895

    
896
/*
897
 * Returns true iff the specified sector is present in the disk image. Drivers
898
 * not implementing the functionality are assumed to not support backing files,
899
 * hence all their sectors are reported as allocated.
900
 *
901
 * 'pnum' is set to the number of sectors (including and immediately following
902
 * the specified sector) that are known to be in the same
903
 * allocated/unallocated state.
904
 *
905
 * 'nb_sectors' is the max value 'pnum' should be set to.
906
 */
907
int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
908
        int *pnum)
909
{
910
    int64_t n;
911
    if (!bs->drv->bdrv_is_allocated) {
912
        if (sector_num >= bs->total_sectors) {
913
            *pnum = 0;
914
            return 0;
915
        }
916
        n = bs->total_sectors - sector_num;
917
        *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
918
        return 1;
919
    }
920
    return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
921
}
922

    
923
void bdrv_info(void)
924
{
925
    BlockDriverState *bs;
926

    
927
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
928
        term_printf("%s:", bs->device_name);
929
        term_printf(" type=");
930
        switch(bs->type) {
931
        case BDRV_TYPE_HD:
932
            term_printf("hd");
933
            break;
934
        case BDRV_TYPE_CDROM:
935
            term_printf("cdrom");
936
            break;
937
        case BDRV_TYPE_FLOPPY:
938
            term_printf("floppy");
939
            break;
940
        }
941
        term_printf(" removable=%d", bs->removable);
942
        if (bs->removable) {
943
            term_printf(" locked=%d", bs->locked);
944
        }
945
        if (bs->drv) {
946
            term_printf(" file=");
947
            term_print_filename(bs->filename);
948
            if (bs->backing_file[0] != '\0') {
949
                term_printf(" backing_file=");
950
                term_print_filename(bs->backing_file);
951
            }
952
            term_printf(" ro=%d", bs->read_only);
953
            term_printf(" drv=%s", bs->drv->format_name);
954
            if (bs->encrypted)
955
                term_printf(" encrypted");
956
        } else {
957
            term_printf(" [not inserted]");
958
        }
959
        term_printf("\n");
960
    }
961
}
962

    
963
/* The "info blockstats" command. */
964
void bdrv_info_stats (void)
965
{
966
    BlockDriverState *bs;
967

    
968
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
969
        term_printf ("%s:"
970
                     " rd_bytes=%" PRIu64
971
                     " wr_bytes=%" PRIu64
972
                     " rd_operations=%" PRIu64
973
                     " wr_operations=%" PRIu64
974
                     "\n",
975
                     bs->device_name,
976
                     bs->rd_bytes, bs->wr_bytes,
977
                     bs->rd_ops, bs->wr_ops);
978
    }
979
}
980

    
981
void bdrv_get_backing_filename(BlockDriverState *bs,
982
                               char *filename, int filename_size)
983
{
984
    if (!bs->backing_hd) {
985
        pstrcpy(filename, filename_size, "");
986
    } else {
987
        pstrcpy(filename, filename_size, bs->backing_file);
988
    }
989
}
990

    
991
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
992
                          const uint8_t *buf, int nb_sectors)
993
{
994
    BlockDriver *drv = bs->drv;
995
    if (!drv)
996
        return -ENOMEDIUM;
997
    if (!drv->bdrv_write_compressed)
998
        return -ENOTSUP;
999
    return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
1000
}
1001

    
1002
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
1003
{
1004
    BlockDriver *drv = bs->drv;
1005
    if (!drv)
1006
        return -ENOMEDIUM;
1007
    if (!drv->bdrv_get_info)
1008
        return -ENOTSUP;
1009
    memset(bdi, 0, sizeof(*bdi));
1010
    return drv->bdrv_get_info(bs, bdi);
1011
}
1012

    
1013
/**************************************************************/
1014
/* handling of snapshots */
1015

    
1016
int bdrv_snapshot_create(BlockDriverState *bs,
1017
                         QEMUSnapshotInfo *sn_info)
1018
{
1019
    BlockDriver *drv = bs->drv;
1020
    if (!drv)
1021
        return -ENOMEDIUM;
1022
    if (!drv->bdrv_snapshot_create)
1023
        return -ENOTSUP;
1024
    return drv->bdrv_snapshot_create(bs, sn_info);
1025
}
1026

    
1027
int bdrv_snapshot_goto(BlockDriverState *bs,
1028
                       const char *snapshot_id)
1029
{
1030
    BlockDriver *drv = bs->drv;
1031
    if (!drv)
1032
        return -ENOMEDIUM;
1033
    if (!drv->bdrv_snapshot_goto)
1034
        return -ENOTSUP;
1035
    return drv->bdrv_snapshot_goto(bs, snapshot_id);
1036
}
1037

    
1038
int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1039
{
1040
    BlockDriver *drv = bs->drv;
1041
    if (!drv)
1042
        return -ENOMEDIUM;
1043
    if (!drv->bdrv_snapshot_delete)
1044
        return -ENOTSUP;
1045
    return drv->bdrv_snapshot_delete(bs, snapshot_id);
1046
}
1047

    
1048
int bdrv_snapshot_list(BlockDriverState *bs,
1049
                       QEMUSnapshotInfo **psn_info)
1050
{
1051
    BlockDriver *drv = bs->drv;
1052
    if (!drv)
1053
        return -ENOMEDIUM;
1054
    if (!drv->bdrv_snapshot_list)
1055
        return -ENOTSUP;
1056
    return drv->bdrv_snapshot_list(bs, psn_info);
1057
}
1058

    
1059
#define NB_SUFFIXES 4
1060

    
1061
char *get_human_readable_size(char *buf, int buf_size, int64_t size)
1062
{
1063
    static const char suffixes[NB_SUFFIXES] = "KMGT";
1064
    int64_t base;
1065
    int i;
1066

    
1067
    if (size <= 999) {
1068
        snprintf(buf, buf_size, "%" PRId64, size);
1069
    } else {
1070
        base = 1024;
1071
        for(i = 0; i < NB_SUFFIXES; i++) {
1072
            if (size < (10 * base)) {
1073
                snprintf(buf, buf_size, "%0.1f%c",
1074
                         (double)size / base,
1075
                         suffixes[i]);
1076
                break;
1077
            } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1078
                snprintf(buf, buf_size, "%" PRId64 "%c",
1079
                         ((size + (base >> 1)) / base),
1080
                         suffixes[i]);
1081
                break;
1082
            }
1083
            base = base * 1024;
1084
        }
1085
    }
1086
    return buf;
1087
}
1088

    
1089
char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
1090
{
1091
    char buf1[128], date_buf[128], clock_buf[128];
1092
#ifdef _WIN32
1093
    struct tm *ptm;
1094
#else
1095
    struct tm tm;
1096
#endif
1097
    time_t ti;
1098
    int64_t secs;
1099

    
1100
    if (!sn) {
1101
        snprintf(buf, buf_size,
1102
                 "%-10s%-20s%7s%20s%15s",
1103
                 "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
1104
    } else {
1105
        ti = sn->date_sec;
1106
#ifdef _WIN32
1107
        ptm = localtime(&ti);
1108
        strftime(date_buf, sizeof(date_buf),
1109
                 "%Y-%m-%d %H:%M:%S", ptm);
1110
#else
1111
        localtime_r(&ti, &tm);
1112
        strftime(date_buf, sizeof(date_buf),
1113
                 "%Y-%m-%d %H:%M:%S", &tm);
1114
#endif
1115
        secs = sn->vm_clock_nsec / 1000000000;
1116
        snprintf(clock_buf, sizeof(clock_buf),
1117
                 "%02d:%02d:%02d.%03d",
1118
                 (int)(secs / 3600),
1119
                 (int)((secs / 60) % 60),
1120
                 (int)(secs % 60),
1121
                 (int)((sn->vm_clock_nsec / 1000000) % 1000));
1122
        snprintf(buf, buf_size,
1123
                 "%-10s%-20s%7s%20s%15s",
1124
                 sn->id_str, sn->name,
1125
                 get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
1126
                 date_buf,
1127
                 clock_buf);
1128
    }
1129
    return buf;
1130
}
1131

    
1132

    
1133
/**************************************************************/
1134
/* async I/Os */
1135

    
1136
BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
1137
                                uint8_t *buf, int nb_sectors,
1138
                                BlockDriverCompletionFunc *cb, void *opaque)
1139
{
1140
    BlockDriver *drv = bs->drv;
1141
    BlockDriverAIOCB *ret;
1142

    
1143
    if (!drv)
1144
        return NULL;
1145

    
1146
    /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
1147
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1148
        memcpy(buf, bs->boot_sector_data, 512);
1149
        sector_num++;
1150
        nb_sectors--;
1151
        buf += 512;
1152
    }
1153

    
1154
    ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
1155

    
1156
    if (ret) {
1157
        /* Update stats even though technically transfer has not happened. */
1158
        bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
1159
        bs->rd_ops ++;
1160
    }
1161

    
1162
    return ret;
1163
}
1164

    
1165
BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
1166
                                 const uint8_t *buf, int nb_sectors,
1167
                                 BlockDriverCompletionFunc *cb, void *opaque)
1168
{
1169
    BlockDriver *drv = bs->drv;
1170
    BlockDriverAIOCB *ret;
1171

    
1172
    if (!drv)
1173
        return NULL;
1174
    if (bs->read_only)
1175
        return NULL;
1176
    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
1177
        memcpy(bs->boot_sector_data, buf, 512);
1178
    }
1179

    
1180
    ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
1181

    
1182
    if (ret) {
1183
        /* Update stats even though technically transfer has not happened. */
1184
        bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
1185
        bs->wr_ops ++;
1186
    }
1187

    
1188
    return ret;
1189
}
1190

    
1191
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1192
{
1193
    BlockDriver *drv = acb->bs->drv;
1194

    
1195
    drv->bdrv_aio_cancel(acb);
1196
}
1197

    
1198

    
1199
/**************************************************************/
1200
/* async block device emulation */
1201

    
1202
static void bdrv_aio_bh_cb(void *opaque)
1203
{
1204
    BlockDriverAIOCBSync *acb = opaque;
1205
    acb->common.cb(acb->common.opaque, acb->ret);
1206
    qemu_aio_release(acb);
1207
}
1208

    
1209
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1210
        int64_t sector_num, uint8_t *buf, int nb_sectors,
1211
        BlockDriverCompletionFunc *cb, void *opaque)
1212
{
1213
    BlockDriverAIOCBSync *acb;
1214
    int ret;
1215

    
1216
    acb = qemu_aio_get(bs, cb, opaque);
1217
    if (!acb->bh)
1218
        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1219
    ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1220
    acb->ret = ret;
1221
    qemu_bh_schedule(acb->bh);
1222
    return &acb->common;
1223
}
1224

    
1225
static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1226
        int64_t sector_num, const uint8_t *buf, int nb_sectors,
1227
        BlockDriverCompletionFunc *cb, void *opaque)
1228
{
1229
    BlockDriverAIOCBSync *acb;
1230
    int ret;
1231

    
1232
    acb = qemu_aio_get(bs, cb, opaque);
1233
    if (!acb->bh)
1234
        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1235
    ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1236
    acb->ret = ret;
1237
    qemu_bh_schedule(acb->bh);
1238
    return &acb->common;
1239
}
1240

    
1241
static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
1242
{
1243
    BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
1244
    qemu_bh_cancel(acb->bh);
1245
    qemu_aio_release(acb);
1246
}
1247

    
1248
/**************************************************************/
1249
/* sync block device emulation */
1250

    
1251
static void bdrv_rw_em_cb(void *opaque, int ret)
1252
{
1253
    *(int *)opaque = ret;
1254
}
1255

    
1256
#define NOT_DONE 0x7fffffff
1257

    
1258
static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1259
                        uint8_t *buf, int nb_sectors)
1260
{
1261
    int async_ret;
1262
    BlockDriverAIOCB *acb;
1263

    
1264
    async_ret = NOT_DONE;
1265
    acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
1266
                        bdrv_rw_em_cb, &async_ret);
1267
    if (acb == NULL)
1268
        return -1;
1269

    
1270
    while (async_ret == NOT_DONE) {
1271
        qemu_aio_wait();
1272
    }
1273

    
1274
    return async_ret;
1275
}
1276

    
1277
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
1278
                         const uint8_t *buf, int nb_sectors)
1279
{
1280
    int async_ret;
1281
    BlockDriverAIOCB *acb;
1282

    
1283
    async_ret = NOT_DONE;
1284
    acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
1285
                         bdrv_rw_em_cb, &async_ret);
1286
    if (acb == NULL)
1287
        return -1;
1288
    while (async_ret == NOT_DONE) {
1289
        qemu_aio_wait();
1290
    }
1291
    return async_ret;
1292
}
1293

    
1294
void bdrv_init(void)
1295
{
1296
    bdrv_register(&bdrv_raw);
1297
    bdrv_register(&bdrv_host_device);
1298
#ifndef _WIN32
1299
    bdrv_register(&bdrv_cow);
1300
#endif
1301
    bdrv_register(&bdrv_qcow);
1302
    bdrv_register(&bdrv_vmdk);
1303
    bdrv_register(&bdrv_cloop);
1304
    bdrv_register(&bdrv_dmg);
1305
    bdrv_register(&bdrv_bochs);
1306
    bdrv_register(&bdrv_vpc);
1307
    bdrv_register(&bdrv_vvfat);
1308
    bdrv_register(&bdrv_qcow2);
1309
    bdrv_register(&bdrv_parallels);
1310
    bdrv_register(&bdrv_nbd);
1311

    
1312
    qemu_aio_init();
1313
}
1314

    
1315
void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
1316
                   void *opaque)
1317
{
1318
    BlockDriver *drv;
1319
    BlockDriverAIOCB *acb;
1320

    
1321
    drv = bs->drv;
1322
    if (drv->free_aiocb) {
1323
        acb = drv->free_aiocb;
1324
        drv->free_aiocb = acb->next;
1325
    } else {
1326
        acb = qemu_mallocz(drv->aiocb_size);
1327
        if (!acb)
1328
            return NULL;
1329
    }
1330
    acb->bs = bs;
1331
    acb->cb = cb;
1332
    acb->opaque = opaque;
1333
    return acb;
1334
}
1335

    
1336
void qemu_aio_release(void *p)
1337
{
1338
    BlockDriverAIOCB *acb = p;
1339
    BlockDriver *drv = acb->bs->drv;
1340
    acb->next = drv->free_aiocb;
1341
    drv->free_aiocb = acb;
1342
}
1343

    
1344
/**************************************************************/
1345
/* removable device support */
1346

    
1347
/**
1348
 * Return TRUE if the media is present
1349
 */
1350
int bdrv_is_inserted(BlockDriverState *bs)
1351
{
1352
    BlockDriver *drv = bs->drv;
1353
    int ret;
1354
    if (!drv)
1355
        return 0;
1356
    if (!drv->bdrv_is_inserted)
1357
        return 1;
1358
    ret = drv->bdrv_is_inserted(bs);
1359
    return ret;
1360
}
1361

    
1362
/**
1363
 * Return TRUE if the media changed since the last call to this
1364
 * function. It is currently only used for floppy disks
1365
 */
1366
int bdrv_media_changed(BlockDriverState *bs)
1367
{
1368
    BlockDriver *drv = bs->drv;
1369
    int ret;
1370

    
1371
    if (!drv || !drv->bdrv_media_changed)
1372
        ret = -ENOTSUP;
1373
    else
1374
        ret = drv->bdrv_media_changed(bs);
1375
    if (ret == -ENOTSUP)
1376
        ret = bs->media_changed;
1377
    bs->media_changed = 0;
1378
    return ret;
1379
}
1380

    
1381
/**
1382
 * If eject_flag is TRUE, eject the media. Otherwise, close the tray
1383
 */
1384
void bdrv_eject(BlockDriverState *bs, int eject_flag)
1385
{
1386
    BlockDriver *drv = bs->drv;
1387
    int ret;
1388

    
1389
    if (!drv || !drv->bdrv_eject) {
1390
        ret = -ENOTSUP;
1391
    } else {
1392
        ret = drv->bdrv_eject(bs, eject_flag);
1393
    }
1394
    if (ret == -ENOTSUP) {
1395
        if (eject_flag)
1396
            bdrv_close(bs);
1397
    }
1398
}
1399

    
1400
int bdrv_is_locked(BlockDriverState *bs)
1401
{
1402
    return bs->locked;
1403
}
1404

    
1405
/**
1406
 * Lock or unlock the media (if it is locked, the user won't be able
1407
 * to eject it manually).
1408
 */
1409
void bdrv_set_locked(BlockDriverState *bs, int locked)
1410
{
1411
    BlockDriver *drv = bs->drv;
1412

    
1413
    bs->locked = locked;
1414
    if (drv && drv->bdrv_set_locked) {
1415
        drv->bdrv_set_locked(bs, locked);
1416
    }
1417
}
1418

    
1419
/* needed for generic scsi interface */
1420

    
1421
int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1422
{
1423
    BlockDriver *drv = bs->drv;
1424

    
1425
    if (drv && drv->bdrv_ioctl)
1426
        return drv->bdrv_ioctl(bs, req, buf);
1427
    return -ENOTSUP;
1428
}