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