]> Git Repo - qemu.git/blob - block/raw-posix.c
Merge remote-tracking branch 'kwolf/for-anthony' into staging
[qemu.git] / block / raw-posix.c
1 /*
2  * Block driver for RAW files (posix)
3  *
4  * Copyright (c) 2006 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 "qemu-timer.h"
26 #include "qemu-char.h"
27 #include "qemu-log.h"
28 #include "block_int.h"
29 #include "module.h"
30 #include "block/raw-posix-aio.h"
31
32 #if defined(__APPLE__) && (__MACH__)
33 #include <paths.h>
34 #include <sys/param.h>
35 #include <IOKit/IOKitLib.h>
36 #include <IOKit/IOBSD.h>
37 #include <IOKit/storage/IOMediaBSDClient.h>
38 #include <IOKit/storage/IOMedia.h>
39 #include <IOKit/storage/IOCDMedia.h>
40 //#include <IOKit/storage/IOCDTypes.h>
41 #include <CoreFoundation/CoreFoundation.h>
42 #endif
43
44 #ifdef __sun__
45 #define _POSIX_PTHREAD_SEMANTICS 1
46 #include <sys/dkio.h>
47 #endif
48 #ifdef __linux__
49 #include <sys/types.h>
50 #include <sys/stat.h>
51 #include <sys/ioctl.h>
52 #include <sys/param.h>
53 #include <linux/cdrom.h>
54 #include <linux/fd.h>
55 #include <linux/fs.h>
56 #endif
57 #ifdef CONFIG_FIEMAP
58 #include <linux/fiemap.h>
59 #endif
60 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
61 #include <sys/disk.h>
62 #include <sys/cdio.h>
63 #endif
64
65 #ifdef __OpenBSD__
66 #include <sys/ioctl.h>
67 #include <sys/disklabel.h>
68 #include <sys/dkio.h>
69 #endif
70
71 #ifdef __NetBSD__
72 #include <sys/ioctl.h>
73 #include <sys/disklabel.h>
74 #include <sys/dkio.h>
75 #include <sys/disk.h>
76 #endif
77
78 #ifdef __DragonFly__
79 #include <sys/ioctl.h>
80 #include <sys/diskslice.h>
81 #endif
82
83 #ifdef CONFIG_XFS
84 #include <xfs/xfs.h>
85 #endif
86
87 //#define DEBUG_FLOPPY
88
89 //#define DEBUG_BLOCK
90 #if defined(DEBUG_BLOCK)
91 #define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
92     { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
93 #else
94 #define DEBUG_BLOCK_PRINT(formatCstr, ...)
95 #endif
96
97 /* OS X does not have O_DSYNC */
98 #ifndef O_DSYNC
99 #ifdef O_SYNC
100 #define O_DSYNC O_SYNC
101 #elif defined(O_FSYNC)
102 #define O_DSYNC O_FSYNC
103 #endif
104 #endif
105
106 /* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
107 #ifndef O_DIRECT
108 #define O_DIRECT O_DSYNC
109 #endif
110
111 #define FTYPE_FILE   0
112 #define FTYPE_CD     1
113 #define FTYPE_FD     2
114
115 /* if the FD is not accessed during that time (in ns), we try to
116    reopen it to see if the disk has been changed */
117 #define FD_OPEN_TIMEOUT (1000000000)
118
119 #define MAX_BLOCKSIZE   4096
120
121 typedef struct BDRVRawState {
122     int fd;
123     int type;
124     int open_flags;
125 #if defined(__linux__)
126     /* linux floppy specific */
127     int64_t fd_open_time;
128     int64_t fd_error_time;
129     int fd_got_error;
130     int fd_media_changed;
131 #endif
132 #ifdef CONFIG_LINUX_AIO
133     int use_aio;
134     void *aio_ctx;
135 #endif
136 #ifdef CONFIG_XFS
137     bool is_xfs : 1;
138 #endif
139 } BDRVRawState;
140
141 typedef struct BDRVRawReopenState {
142     int fd;
143     int open_flags;
144 #ifdef CONFIG_LINUX_AIO
145     int use_aio;
146 #endif
147 } BDRVRawReopenState;
148
149 static int fd_open(BlockDriverState *bs);
150 static int64_t raw_getlength(BlockDriverState *bs);
151
152 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
153 static int cdrom_reopen(BlockDriverState *bs);
154 #endif
155
156 #if defined(__NetBSD__)
157 static int raw_normalize_devicepath(const char **filename)
158 {
159     static char namebuf[PATH_MAX];
160     const char *dp, *fname;
161     struct stat sb;
162
163     fname = *filename;
164     dp = strrchr(fname, '/');
165     if (lstat(fname, &sb) < 0) {
166         fprintf(stderr, "%s: stat failed: %s\n",
167             fname, strerror(errno));
168         return -errno;
169     }
170
171     if (!S_ISBLK(sb.st_mode)) {
172         return 0;
173     }
174
175     if (dp == NULL) {
176         snprintf(namebuf, PATH_MAX, "r%s", fname);
177     } else {
178         snprintf(namebuf, PATH_MAX, "%.*s/r%s",
179             (int)(dp - fname), fname, dp + 1);
180     }
181     fprintf(stderr, "%s is a block device", fname);
182     *filename = namebuf;
183     fprintf(stderr, ", using %s\n", *filename);
184
185     return 0;
186 }
187 #else
188 static int raw_normalize_devicepath(const char **filename)
189 {
190     return 0;
191 }
192 #endif
193
194 static void raw_parse_flags(int bdrv_flags, int *open_flags)
195 {
196     assert(open_flags != NULL);
197
198     *open_flags |= O_BINARY;
199     *open_flags &= ~O_ACCMODE;
200     if (bdrv_flags & BDRV_O_RDWR) {
201         *open_flags |= O_RDWR;
202     } else {
203         *open_flags |= O_RDONLY;
204     }
205
206     /* Use O_DSYNC for write-through caching, no flags for write-back caching,
207      * and O_DIRECT for no caching. */
208     if ((bdrv_flags & BDRV_O_NOCACHE)) {
209         *open_flags |= O_DIRECT;
210     }
211 }
212
213 #ifdef CONFIG_LINUX_AIO
214 static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags)
215 {
216     int ret = -1;
217     assert(aio_ctx != NULL);
218     assert(use_aio != NULL);
219     /*
220      * Currently Linux do AIO only for files opened with O_DIRECT
221      * specified so check NOCACHE flag too
222      */
223     if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
224                       (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
225
226         /* if non-NULL, laio_init() has already been run */
227         if (*aio_ctx == NULL) {
228             *aio_ctx = laio_init();
229             if (!*aio_ctx) {
230                 goto error;
231             }
232         }
233         *use_aio = 1;
234     } else {
235         *use_aio = 0;
236     }
237
238     ret = 0;
239
240 error:
241     return ret;
242 }
243 #endif
244
245 static int raw_open_common(BlockDriverState *bs, const char *filename,
246                            int bdrv_flags, int open_flags)
247 {
248     BDRVRawState *s = bs->opaque;
249     int fd, ret;
250
251     ret = raw_normalize_devicepath(&filename);
252     if (ret != 0) {
253         return ret;
254     }
255
256     s->open_flags = open_flags;
257     raw_parse_flags(bdrv_flags, &s->open_flags);
258
259     s->fd = -1;
260     fd = qemu_open(filename, s->open_flags, 0644);
261     if (fd < 0) {
262         ret = -errno;
263         if (ret == -EROFS)
264             ret = -EACCES;
265         return ret;
266     }
267     s->fd = fd;
268
269     /* We're falling back to POSIX AIO in some cases so init always */
270     if (paio_init() < 0) {
271         goto out_close;
272     }
273
274 #ifdef CONFIG_LINUX_AIO
275     if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) {
276         goto out_close;
277     }
278 #endif
279
280 #ifdef CONFIG_XFS
281     if (platform_test_xfs_fd(s->fd)) {
282         s->is_xfs = 1;
283     }
284 #endif
285
286     return 0;
287
288 out_close:
289     qemu_close(fd);
290     return -errno;
291 }
292
293 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
294 {
295     BDRVRawState *s = bs->opaque;
296
297     s->type = FTYPE_FILE;
298     return raw_open_common(bs, filename, flags, 0);
299 }
300
301 static int raw_reopen_prepare(BDRVReopenState *state,
302                               BlockReopenQueue *queue, Error **errp)
303 {
304     BDRVRawState *s;
305     BDRVRawReopenState *raw_s;
306     int ret = 0;
307
308     assert(state != NULL);
309     assert(state->bs != NULL);
310
311     s = state->bs->opaque;
312
313     state->opaque = g_malloc0(sizeof(BDRVRawReopenState));
314     raw_s = state->opaque;
315
316 #ifdef CONFIG_LINUX_AIO
317     raw_s->use_aio = s->use_aio;
318
319     /* we can use s->aio_ctx instead of a copy, because the use_aio flag is
320      * valid in the 'false' condition even if aio_ctx is set, and raw_set_aio()
321      * won't override aio_ctx if aio_ctx is non-NULL */
322     if (raw_set_aio(&s->aio_ctx, &raw_s->use_aio, state->flags)) {
323         return -1;
324     }
325 #endif
326
327     raw_parse_flags(state->flags, &raw_s->open_flags);
328
329     raw_s->fd = -1;
330
331     int fcntl_flags = O_APPEND | O_ASYNC | O_NONBLOCK;
332 #ifdef O_NOATIME
333     fcntl_flags |= O_NOATIME;
334 #endif
335
336     if ((raw_s->open_flags & ~fcntl_flags) == (s->open_flags & ~fcntl_flags)) {
337         /* dup the original fd */
338         /* TODO: use qemu fcntl wrapper */
339 #ifdef F_DUPFD_CLOEXEC
340         raw_s->fd = fcntl(s->fd, F_DUPFD_CLOEXEC, 0);
341 #else
342         raw_s->fd = dup(s->fd);
343         if (raw_s->fd != -1) {
344             qemu_set_cloexec(raw_s->fd);
345         }
346 #endif
347         if (raw_s->fd >= 0) {
348             ret = fcntl_setfl(raw_s->fd, raw_s->open_flags);
349             if (ret) {
350                 qemu_close(raw_s->fd);
351                 raw_s->fd = -1;
352             }
353         }
354     }
355
356     /* If we cannot use fcntl, or fcntl failed, fall back to qemu_open() */
357     if (raw_s->fd == -1) {
358         assert(!(raw_s->open_flags & O_CREAT));
359         raw_s->fd = qemu_open(state->bs->filename, raw_s->open_flags);
360         if (raw_s->fd == -1) {
361             ret = -1;
362         }
363     }
364     return ret;
365 }
366
367
368 static void raw_reopen_commit(BDRVReopenState *state)
369 {
370     BDRVRawReopenState *raw_s = state->opaque;
371     BDRVRawState *s = state->bs->opaque;
372
373     s->open_flags = raw_s->open_flags;
374
375     qemu_close(s->fd);
376     s->fd = raw_s->fd;
377 #ifdef CONFIG_LINUX_AIO
378     s->use_aio = raw_s->use_aio;
379 #endif
380
381     g_free(state->opaque);
382     state->opaque = NULL;
383 }
384
385
386 static void raw_reopen_abort(BDRVReopenState *state)
387 {
388     BDRVRawReopenState *raw_s = state->opaque;
389
390      /* nothing to do if NULL, we didn't get far enough */
391     if (raw_s == NULL) {
392         return;
393     }
394
395     if (raw_s->fd >= 0) {
396         qemu_close(raw_s->fd);
397         raw_s->fd = -1;
398     }
399     g_free(state->opaque);
400     state->opaque = NULL;
401 }
402
403
404 /* XXX: use host sector size if necessary with:
405 #ifdef DIOCGSECTORSIZE
406         {
407             unsigned int sectorsize = 512;
408             if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
409                 sectorsize > bufsize)
410                 bufsize = sectorsize;
411         }
412 #endif
413 #ifdef CONFIG_COCOA
414         uint32_t blockSize = 512;
415         if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
416             bufsize = blockSize;
417         }
418 #endif
419 */
420
421 /*
422  * Check if all memory in this vector is sector aligned.
423  */
424 static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
425 {
426     int i;
427
428     for (i = 0; i < qiov->niov; i++) {
429         if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) {
430             return 0;
431         }
432     }
433
434     return 1;
435 }
436
437 static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
438         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
439         BlockDriverCompletionFunc *cb, void *opaque, int type)
440 {
441     BDRVRawState *s = bs->opaque;
442
443     if (fd_open(bs) < 0)
444         return NULL;
445
446     /*
447      * If O_DIRECT is used the buffer needs to be aligned on a sector
448      * boundary.  Check if this is the case or tell the low-level
449      * driver that it needs to copy the buffer.
450      */
451     if ((bs->open_flags & BDRV_O_NOCACHE)) {
452         if (!qiov_is_aligned(bs, qiov)) {
453             type |= QEMU_AIO_MISALIGNED;
454 #ifdef CONFIG_LINUX_AIO
455         } else if (s->use_aio) {
456             return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov,
457                                nb_sectors, cb, opaque, type);
458 #endif
459         }
460     }
461
462     return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors,
463                        cb, opaque, type);
464 }
465
466 static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
467         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
468         BlockDriverCompletionFunc *cb, void *opaque)
469 {
470     return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
471                           cb, opaque, QEMU_AIO_READ);
472 }
473
474 static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
475         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
476         BlockDriverCompletionFunc *cb, void *opaque)
477 {
478     return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
479                           cb, opaque, QEMU_AIO_WRITE);
480 }
481
482 static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
483         BlockDriverCompletionFunc *cb, void *opaque)
484 {
485     BDRVRawState *s = bs->opaque;
486
487     if (fd_open(bs) < 0)
488         return NULL;
489
490     return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH);
491 }
492
493 static void raw_close(BlockDriverState *bs)
494 {
495     BDRVRawState *s = bs->opaque;
496     if (s->fd >= 0) {
497         qemu_close(s->fd);
498         s->fd = -1;
499     }
500 }
501
502 static int raw_truncate(BlockDriverState *bs, int64_t offset)
503 {
504     BDRVRawState *s = bs->opaque;
505     struct stat st;
506
507     if (fstat(s->fd, &st)) {
508         return -errno;
509     }
510
511     if (S_ISREG(st.st_mode)) {
512         if (ftruncate(s->fd, offset) < 0) {
513             return -errno;
514         }
515     } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
516        if (offset > raw_getlength(bs)) {
517            return -EINVAL;
518        }
519     } else {
520         return -ENOTSUP;
521     }
522
523     return 0;
524 }
525
526 #ifdef __OpenBSD__
527 static int64_t raw_getlength(BlockDriverState *bs)
528 {
529     BDRVRawState *s = bs->opaque;
530     int fd = s->fd;
531     struct stat st;
532
533     if (fstat(fd, &st))
534         return -1;
535     if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
536         struct disklabel dl;
537
538         if (ioctl(fd, DIOCGDINFO, &dl))
539             return -1;
540         return (uint64_t)dl.d_secsize *
541             dl.d_partitions[DISKPART(st.st_rdev)].p_size;
542     } else
543         return st.st_size;
544 }
545 #elif defined(__NetBSD__)
546 static int64_t raw_getlength(BlockDriverState *bs)
547 {
548     BDRVRawState *s = bs->opaque;
549     int fd = s->fd;
550     struct stat st;
551
552     if (fstat(fd, &st))
553         return -1;
554     if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
555         struct dkwedge_info dkw;
556
557         if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) {
558             return dkw.dkw_size * 512;
559         } else {
560             struct disklabel dl;
561
562             if (ioctl(fd, DIOCGDINFO, &dl))
563                 return -1;
564             return (uint64_t)dl.d_secsize *
565                 dl.d_partitions[DISKPART(st.st_rdev)].p_size;
566         }
567     } else
568         return st.st_size;
569 }
570 #elif defined(__sun__)
571 static int64_t raw_getlength(BlockDriverState *bs)
572 {
573     BDRVRawState *s = bs->opaque;
574     struct dk_minfo minfo;
575     int ret;
576
577     ret = fd_open(bs);
578     if (ret < 0) {
579         return ret;
580     }
581
582     /*
583      * Use the DKIOCGMEDIAINFO ioctl to read the size.
584      */
585     ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo);
586     if (ret != -1) {
587         return minfo.dki_lbsize * minfo.dki_capacity;
588     }
589
590     /*
591      * There are reports that lseek on some devices fails, but
592      * irc discussion said that contingency on contingency was overkill.
593      */
594     return lseek(s->fd, 0, SEEK_END);
595 }
596 #elif defined(CONFIG_BSD)
597 static int64_t raw_getlength(BlockDriverState *bs)
598 {
599     BDRVRawState *s = bs->opaque;
600     int fd = s->fd;
601     int64_t size;
602     struct stat sb;
603 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
604     int reopened = 0;
605 #endif
606     int ret;
607
608     ret = fd_open(bs);
609     if (ret < 0)
610         return ret;
611
612 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
613 again:
614 #endif
615     if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
616 #ifdef DIOCGMEDIASIZE
617         if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
618 #elif defined(DIOCGPART)
619         {
620                 struct partinfo pi;
621                 if (ioctl(fd, DIOCGPART, &pi) == 0)
622                         size = pi.media_size;
623                 else
624                         size = 0;
625         }
626         if (size == 0)
627 #endif
628 #if defined(__APPLE__) && defined(__MACH__)
629         size = LONG_LONG_MAX;
630 #else
631         size = lseek(fd, 0LL, SEEK_END);
632 #endif
633 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
634         switch(s->type) {
635         case FTYPE_CD:
636             /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
637             if (size == 2048LL * (unsigned)-1)
638                 size = 0;
639             /* XXX no disc?  maybe we need to reopen... */
640             if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
641                 reopened = 1;
642                 goto again;
643             }
644         }
645 #endif
646     } else {
647         size = lseek(fd, 0, SEEK_END);
648     }
649     return size;
650 }
651 #else
652 static int64_t raw_getlength(BlockDriverState *bs)
653 {
654     BDRVRawState *s = bs->opaque;
655     int ret;
656
657     ret = fd_open(bs);
658     if (ret < 0) {
659         return ret;
660     }
661
662     return lseek(s->fd, 0, SEEK_END);
663 }
664 #endif
665
666 static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
667 {
668     struct stat st;
669     BDRVRawState *s = bs->opaque;
670
671     if (fstat(s->fd, &st) < 0) {
672         return -errno;
673     }
674     return (int64_t)st.st_blocks * 512;
675 }
676
677 static int raw_create(const char *filename, QEMUOptionParameter *options)
678 {
679     int fd;
680     int result = 0;
681     int64_t total_size = 0;
682
683     /* Read out options */
684     while (options && options->name) {
685         if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
686             total_size = options->value.n / BDRV_SECTOR_SIZE;
687         }
688         options++;
689     }
690
691     fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
692                    0644);
693     if (fd < 0) {
694         result = -errno;
695     } else {
696         if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
697             result = -errno;
698         }
699         if (qemu_close(fd) != 0) {
700             result = -errno;
701         }
702     }
703     return result;
704 }
705
706 /*
707  * Returns true iff the specified sector is present in the disk image. Drivers
708  * not implementing the functionality are assumed to not support backing files,
709  * hence all their sectors are reported as allocated.
710  *
711  * If 'sector_num' is beyond the end of the disk image the return value is 0
712  * and 'pnum' is set to 0.
713  *
714  * 'pnum' is set to the number of sectors (including and immediately following
715  * the specified sector) that are known to be in the same
716  * allocated/unallocated state.
717  *
718  * 'nb_sectors' is the max value 'pnum' should be set to.  If nb_sectors goes
719  * beyond the end of the disk image it will be clamped.
720  */
721 static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
722                                             int64_t sector_num,
723                                             int nb_sectors, int *pnum)
724 {
725     off_t start, data, hole;
726     int ret;
727
728     ret = fd_open(bs);
729     if (ret < 0) {
730         return ret;
731     }
732
733     start = sector_num * BDRV_SECTOR_SIZE;
734
735 #ifdef CONFIG_FIEMAP
736
737     BDRVRawState *s = bs->opaque;
738     struct {
739         struct fiemap fm;
740         struct fiemap_extent fe;
741     } f;
742
743     f.fm.fm_start = start;
744     f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE;
745     f.fm.fm_flags = 0;
746     f.fm.fm_extent_count = 1;
747     f.fm.fm_reserved = 0;
748     if (ioctl(s->fd, FS_IOC_FIEMAP, &f) == -1) {
749         /* Assume everything is allocated.  */
750         *pnum = nb_sectors;
751         return 1;
752     }
753
754     if (f.fm.fm_mapped_extents == 0) {
755         /* No extents found, data is beyond f.fm.fm_start + f.fm.fm_length.
756          * f.fm.fm_start + f.fm.fm_length must be clamped to the file size!
757          */
758         off_t length = lseek(s->fd, 0, SEEK_END);
759         hole = f.fm.fm_start;
760         data = MIN(f.fm.fm_start + f.fm.fm_length, length);
761     } else {
762         data = f.fe.fe_logical;
763         hole = f.fe.fe_logical + f.fe.fe_length;
764     }
765
766 #elif defined SEEK_HOLE && defined SEEK_DATA
767
768     BDRVRawState *s = bs->opaque;
769
770     hole = lseek(s->fd, start, SEEK_HOLE);
771     if (hole == -1) {
772         /* -ENXIO indicates that sector_num was past the end of the file.
773          * There is a virtual hole there.  */
774         assert(errno != -ENXIO);
775
776         /* Most likely EINVAL.  Assume everything is allocated.  */
777         *pnum = nb_sectors;
778         return 1;
779     }
780
781     if (hole > start) {
782         data = start;
783     } else {
784         /* On a hole.  We need another syscall to find its end.  */
785         data = lseek(s->fd, start, SEEK_DATA);
786         if (data == -1) {
787             data = lseek(s->fd, 0, SEEK_END);
788         }
789     }
790 #else
791     *pnum = nb_sectors;
792     return 1;
793 #endif
794
795     if (data <= start) {
796         /* On a data extent, compute sectors to the end of the extent.  */
797         *pnum = MIN(nb_sectors, (hole - start) / BDRV_SECTOR_SIZE);
798         return 1;
799     } else {
800         /* On a hole, compute sectors to the beginning of the next extent.  */
801         *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
802         return 0;
803     }
804 }
805
806 #ifdef CONFIG_XFS
807 static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
808 {
809     struct xfs_flock64 fl;
810
811     memset(&fl, 0, sizeof(fl));
812     fl.l_whence = SEEK_SET;
813     fl.l_start = sector_num << 9;
814     fl.l_len = (int64_t)nb_sectors << 9;
815
816     if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
817         DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
818         return -errno;
819     }
820
821     return 0;
822 }
823 #endif
824
825 static coroutine_fn int raw_co_discard(BlockDriverState *bs,
826     int64_t sector_num, int nb_sectors)
827 {
828 #ifdef CONFIG_XFS
829     BDRVRawState *s = bs->opaque;
830
831     if (s->is_xfs) {
832         return xfs_discard(s, sector_num, nb_sectors);
833     }
834 #endif
835
836     return 0;
837 }
838
839 static QEMUOptionParameter raw_create_options[] = {
840     {
841         .name = BLOCK_OPT_SIZE,
842         .type = OPT_SIZE,
843         .help = "Virtual disk size"
844     },
845     { NULL }
846 };
847
848 static BlockDriver bdrv_file = {
849     .format_name = "file",
850     .protocol_name = "file",
851     .instance_size = sizeof(BDRVRawState),
852     .bdrv_probe = NULL, /* no probe for protocols */
853     .bdrv_file_open = raw_open,
854     .bdrv_reopen_prepare = raw_reopen_prepare,
855     .bdrv_reopen_commit = raw_reopen_commit,
856     .bdrv_reopen_abort = raw_reopen_abort,
857     .bdrv_close = raw_close,
858     .bdrv_create = raw_create,
859     .bdrv_co_discard = raw_co_discard,
860     .bdrv_co_is_allocated = raw_co_is_allocated,
861
862     .bdrv_aio_readv = raw_aio_readv,
863     .bdrv_aio_writev = raw_aio_writev,
864     .bdrv_aio_flush = raw_aio_flush,
865
866     .bdrv_truncate = raw_truncate,
867     .bdrv_getlength = raw_getlength,
868     .bdrv_get_allocated_file_size
869                         = raw_get_allocated_file_size,
870
871     .create_options = raw_create_options,
872 };
873
874 /***********************************************/
875 /* host device */
876
877 #if defined(__APPLE__) && defined(__MACH__)
878 static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
879 static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
880
881 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
882 {
883     kern_return_t       kernResult;
884     mach_port_t     masterPort;
885     CFMutableDictionaryRef  classesToMatch;
886
887     kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
888     if ( KERN_SUCCESS != kernResult ) {
889         printf( "IOMasterPort returned %d\n", kernResult );
890     }
891
892     classesToMatch = IOServiceMatching( kIOCDMediaClass );
893     if ( classesToMatch == NULL ) {
894         printf( "IOServiceMatching returned a NULL dictionary.\n" );
895     } else {
896     CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
897     }
898     kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
899     if ( KERN_SUCCESS != kernResult )
900     {
901         printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
902     }
903
904     return kernResult;
905 }
906
907 kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
908 {
909     io_object_t     nextMedia;
910     kern_return_t   kernResult = KERN_FAILURE;
911     *bsdPath = '\0';
912     nextMedia = IOIteratorNext( mediaIterator );
913     if ( nextMedia )
914     {
915         CFTypeRef   bsdPathAsCFString;
916     bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
917         if ( bsdPathAsCFString ) {
918             size_t devPathLength;
919             strcpy( bsdPath, _PATH_DEV );
920             strcat( bsdPath, "r" );
921             devPathLength = strlen( bsdPath );
922             if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
923                 kernResult = KERN_SUCCESS;
924             }
925             CFRelease( bsdPathAsCFString );
926         }
927         IOObjectRelease( nextMedia );
928     }
929
930     return kernResult;
931 }
932
933 #endif
934
935 static int hdev_probe_device(const char *filename)
936 {
937     struct stat st;
938
939     /* allow a dedicated CD-ROM driver to match with a higher priority */
940     if (strstart(filename, "/dev/cdrom", NULL))
941         return 50;
942
943     if (stat(filename, &st) >= 0 &&
944             (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
945         return 100;
946     }
947
948     return 0;
949 }
950
951 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
952 {
953     BDRVRawState *s = bs->opaque;
954
955 #if defined(__APPLE__) && defined(__MACH__)
956     if (strstart(filename, "/dev/cdrom", NULL)) {
957         kern_return_t kernResult;
958         io_iterator_t mediaIterator;
959         char bsdPath[ MAXPATHLEN ];
960         int fd;
961
962         kernResult = FindEjectableCDMedia( &mediaIterator );
963         kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
964
965         if ( bsdPath[ 0 ] != '\0' ) {
966             strcat(bsdPath,"s0");
967             /* some CDs don't have a partition 0 */
968             fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
969             if (fd < 0) {
970                 bsdPath[strlen(bsdPath)-1] = '1';
971             } else {
972                 qemu_close(fd);
973             }
974             filename = bsdPath;
975         }
976
977         if ( mediaIterator )
978             IOObjectRelease( mediaIterator );
979     }
980 #endif
981
982     s->type = FTYPE_FILE;
983 #if defined(__linux__)
984     {
985         char resolved_path[ MAXPATHLEN ], *temp;
986
987         temp = realpath(filename, resolved_path);
988         if (temp && strstart(temp, "/dev/sg", NULL)) {
989             bs->sg = 1;
990         }
991     }
992 #endif
993
994     return raw_open_common(bs, filename, flags, 0);
995 }
996
997 #if defined(__linux__)
998 /* Note: we do not have a reliable method to detect if the floppy is
999    present. The current method is to try to open the floppy at every
1000    I/O and to keep it opened during a few hundreds of ms. */
1001 static int fd_open(BlockDriverState *bs)
1002 {
1003     BDRVRawState *s = bs->opaque;
1004     int last_media_present;
1005
1006     if (s->type != FTYPE_FD)
1007         return 0;
1008     last_media_present = (s->fd >= 0);
1009     if (s->fd >= 0 &&
1010         (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
1011         qemu_close(s->fd);
1012         s->fd = -1;
1013 #ifdef DEBUG_FLOPPY
1014         printf("Floppy closed\n");
1015 #endif
1016     }
1017     if (s->fd < 0) {
1018         if (s->fd_got_error &&
1019             (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
1020 #ifdef DEBUG_FLOPPY
1021             printf("No floppy (open delayed)\n");
1022 #endif
1023             return -EIO;
1024         }
1025         s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK);
1026         if (s->fd < 0) {
1027             s->fd_error_time = get_clock();
1028             s->fd_got_error = 1;
1029             if (last_media_present)
1030                 s->fd_media_changed = 1;
1031 #ifdef DEBUG_FLOPPY
1032             printf("No floppy\n");
1033 #endif
1034             return -EIO;
1035         }
1036 #ifdef DEBUG_FLOPPY
1037         printf("Floppy opened\n");
1038 #endif
1039     }
1040     if (!last_media_present)
1041         s->fd_media_changed = 1;
1042     s->fd_open_time = get_clock();
1043     s->fd_got_error = 0;
1044     return 0;
1045 }
1046
1047 static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1048 {
1049     BDRVRawState *s = bs->opaque;
1050
1051     return ioctl(s->fd, req, buf);
1052 }
1053
1054 static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
1055         unsigned long int req, void *buf,
1056         BlockDriverCompletionFunc *cb, void *opaque)
1057 {
1058     BDRVRawState *s = bs->opaque;
1059
1060     if (fd_open(bs) < 0)
1061         return NULL;
1062     return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
1063 }
1064
1065 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1066 static int fd_open(BlockDriverState *bs)
1067 {
1068     BDRVRawState *s = bs->opaque;
1069
1070     /* this is just to ensure s->fd is sane (its called by io ops) */
1071     if (s->fd >= 0)
1072         return 0;
1073     return -EIO;
1074 }
1075 #else /* !linux && !FreeBSD */
1076
1077 static int fd_open(BlockDriverState *bs)
1078 {
1079     return 0;
1080 }
1081
1082 #endif /* !linux && !FreeBSD */
1083
1084 static int hdev_create(const char *filename, QEMUOptionParameter *options)
1085 {
1086     int fd;
1087     int ret = 0;
1088     struct stat stat_buf;
1089     int64_t total_size = 0;
1090
1091     /* Read out options */
1092     while (options && options->name) {
1093         if (!strcmp(options->name, "size")) {
1094             total_size = options->value.n / BDRV_SECTOR_SIZE;
1095         }
1096         options++;
1097     }
1098
1099     fd = qemu_open(filename, O_WRONLY | O_BINARY);
1100     if (fd < 0)
1101         return -errno;
1102
1103     if (fstat(fd, &stat_buf) < 0)
1104         ret = -errno;
1105     else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1106         ret = -ENODEV;
1107     else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE)
1108         ret = -ENOSPC;
1109
1110     qemu_close(fd);
1111     return ret;
1112 }
1113
1114 static int hdev_has_zero_init(BlockDriverState *bs)
1115 {
1116     return 0;
1117 }
1118
1119 static BlockDriver bdrv_host_device = {
1120     .format_name        = "host_device",
1121     .protocol_name        = "host_device",
1122     .instance_size      = sizeof(BDRVRawState),
1123     .bdrv_probe_device  = hdev_probe_device,
1124     .bdrv_file_open     = hdev_open,
1125     .bdrv_close         = raw_close,
1126     .bdrv_create        = hdev_create,
1127     .create_options     = raw_create_options,
1128     .bdrv_has_zero_init = hdev_has_zero_init,
1129
1130     .bdrv_aio_readv     = raw_aio_readv,
1131     .bdrv_aio_writev    = raw_aio_writev,
1132     .bdrv_aio_flush     = raw_aio_flush,
1133
1134     .bdrv_truncate      = raw_truncate,
1135     .bdrv_getlength     = raw_getlength,
1136     .bdrv_get_allocated_file_size
1137                         = raw_get_allocated_file_size,
1138
1139     /* generic scsi device */
1140 #ifdef __linux__
1141     .bdrv_ioctl         = hdev_ioctl,
1142     .bdrv_aio_ioctl     = hdev_aio_ioctl,
1143 #endif
1144 };
1145
1146 #ifdef __linux__
1147 static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
1148 {
1149     BDRVRawState *s = bs->opaque;
1150     int ret;
1151
1152     s->type = FTYPE_FD;
1153
1154     /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1155     ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
1156     if (ret)
1157         return ret;
1158
1159     /* close fd so that we can reopen it as needed */
1160     qemu_close(s->fd);
1161     s->fd = -1;
1162     s->fd_media_changed = 1;
1163
1164     return 0;
1165 }
1166
1167 static int floppy_probe_device(const char *filename)
1168 {
1169     int fd, ret;
1170     int prio = 0;
1171     struct floppy_struct fdparam;
1172     struct stat st;
1173
1174     if (strstart(filename, "/dev/fd", NULL) &&
1175         !strstart(filename, "/dev/fdset/", NULL)) {
1176         prio = 50;
1177     }
1178
1179     fd = qemu_open(filename, O_RDONLY | O_NONBLOCK);
1180     if (fd < 0) {
1181         goto out;
1182     }
1183     ret = fstat(fd, &st);
1184     if (ret == -1 || !S_ISBLK(st.st_mode)) {
1185         goto outc;
1186     }
1187
1188     /* Attempt to detect via a floppy specific ioctl */
1189     ret = ioctl(fd, FDGETPRM, &fdparam);
1190     if (ret >= 0)
1191         prio = 100;
1192
1193 outc:
1194     qemu_close(fd);
1195 out:
1196     return prio;
1197 }
1198
1199
1200 static int floppy_is_inserted(BlockDriverState *bs)
1201 {
1202     return fd_open(bs) >= 0;
1203 }
1204
1205 static int floppy_media_changed(BlockDriverState *bs)
1206 {
1207     BDRVRawState *s = bs->opaque;
1208     int ret;
1209
1210     /*
1211      * XXX: we do not have a true media changed indication.
1212      * It does not work if the floppy is changed without trying to read it.
1213      */
1214     fd_open(bs);
1215     ret = s->fd_media_changed;
1216     s->fd_media_changed = 0;
1217 #ifdef DEBUG_FLOPPY
1218     printf("Floppy changed=%d\n", ret);
1219 #endif
1220     return ret;
1221 }
1222
1223 static void floppy_eject(BlockDriverState *bs, bool eject_flag)
1224 {
1225     BDRVRawState *s = bs->opaque;
1226     int fd;
1227
1228     if (s->fd >= 0) {
1229         qemu_close(s->fd);
1230         s->fd = -1;
1231     }
1232     fd = qemu_open(bs->filename, s->open_flags | O_NONBLOCK);
1233     if (fd >= 0) {
1234         if (ioctl(fd, FDEJECT, 0) < 0)
1235             perror("FDEJECT");
1236         qemu_close(fd);
1237     }
1238 }
1239
1240 static BlockDriver bdrv_host_floppy = {
1241     .format_name        = "host_floppy",
1242     .protocol_name      = "host_floppy",
1243     .instance_size      = sizeof(BDRVRawState),
1244     .bdrv_probe_device  = floppy_probe_device,
1245     .bdrv_file_open     = floppy_open,
1246     .bdrv_close         = raw_close,
1247     .bdrv_create        = hdev_create,
1248     .create_options     = raw_create_options,
1249     .bdrv_has_zero_init = hdev_has_zero_init,
1250
1251     .bdrv_aio_readv     = raw_aio_readv,
1252     .bdrv_aio_writev    = raw_aio_writev,
1253     .bdrv_aio_flush     = raw_aio_flush,
1254
1255     .bdrv_truncate      = raw_truncate,
1256     .bdrv_getlength     = raw_getlength,
1257     .bdrv_get_allocated_file_size
1258                         = raw_get_allocated_file_size,
1259
1260     /* removable device support */
1261     .bdrv_is_inserted   = floppy_is_inserted,
1262     .bdrv_media_changed = floppy_media_changed,
1263     .bdrv_eject         = floppy_eject,
1264 };
1265
1266 static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1267 {
1268     BDRVRawState *s = bs->opaque;
1269
1270     s->type = FTYPE_CD;
1271
1272     /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1273     return raw_open_common(bs, filename, flags, O_NONBLOCK);
1274 }
1275
1276 static int cdrom_probe_device(const char *filename)
1277 {
1278     int fd, ret;
1279     int prio = 0;
1280     struct stat st;
1281
1282     fd = qemu_open(filename, O_RDONLY | O_NONBLOCK);
1283     if (fd < 0) {
1284         goto out;
1285     }
1286     ret = fstat(fd, &st);
1287     if (ret == -1 || !S_ISBLK(st.st_mode)) {
1288         goto outc;
1289     }
1290
1291     /* Attempt to detect via a CDROM specific ioctl */
1292     ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1293     if (ret >= 0)
1294         prio = 100;
1295
1296 outc:
1297     qemu_close(fd);
1298 out:
1299     return prio;
1300 }
1301
1302 static int cdrom_is_inserted(BlockDriverState *bs)
1303 {
1304     BDRVRawState *s = bs->opaque;
1305     int ret;
1306
1307     ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1308     if (ret == CDS_DISC_OK)
1309         return 1;
1310     return 0;
1311 }
1312
1313 static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
1314 {
1315     BDRVRawState *s = bs->opaque;
1316
1317     if (eject_flag) {
1318         if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1319             perror("CDROMEJECT");
1320     } else {
1321         if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1322             perror("CDROMEJECT");
1323     }
1324 }
1325
1326 static void cdrom_lock_medium(BlockDriverState *bs, bool locked)
1327 {
1328     BDRVRawState *s = bs->opaque;
1329
1330     if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1331         /*
1332          * Note: an error can happen if the distribution automatically
1333          * mounts the CD-ROM
1334          */
1335         /* perror("CDROM_LOCKDOOR"); */
1336     }
1337 }
1338
1339 static BlockDriver bdrv_host_cdrom = {
1340     .format_name        = "host_cdrom",
1341     .protocol_name      = "host_cdrom",
1342     .instance_size      = sizeof(BDRVRawState),
1343     .bdrv_probe_device  = cdrom_probe_device,
1344     .bdrv_file_open     = cdrom_open,
1345     .bdrv_close         = raw_close,
1346     .bdrv_create        = hdev_create,
1347     .create_options     = raw_create_options,
1348     .bdrv_has_zero_init = hdev_has_zero_init,
1349
1350     .bdrv_aio_readv     = raw_aio_readv,
1351     .bdrv_aio_writev    = raw_aio_writev,
1352     .bdrv_aio_flush     = raw_aio_flush,
1353
1354     .bdrv_truncate      = raw_truncate,
1355     .bdrv_getlength     = raw_getlength,
1356     .bdrv_get_allocated_file_size
1357                         = raw_get_allocated_file_size,
1358
1359     /* removable device support */
1360     .bdrv_is_inserted   = cdrom_is_inserted,
1361     .bdrv_eject         = cdrom_eject,
1362     .bdrv_lock_medium   = cdrom_lock_medium,
1363
1364     /* generic scsi device */
1365     .bdrv_ioctl         = hdev_ioctl,
1366     .bdrv_aio_ioctl     = hdev_aio_ioctl,
1367 };
1368 #endif /* __linux__ */
1369
1370 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
1371 static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1372 {
1373     BDRVRawState *s = bs->opaque;
1374     int ret;
1375
1376     s->type = FTYPE_CD;
1377
1378     ret = raw_open_common(bs, filename, flags, 0);
1379     if (ret)
1380         return ret;
1381
1382     /* make sure the door isn't locked at this time */
1383     ioctl(s->fd, CDIOCALLOW);
1384     return 0;
1385 }
1386
1387 static int cdrom_probe_device(const char *filename)
1388 {
1389     if (strstart(filename, "/dev/cd", NULL) ||
1390             strstart(filename, "/dev/acd", NULL))
1391         return 100;
1392     return 0;
1393 }
1394
1395 static int cdrom_reopen(BlockDriverState *bs)
1396 {
1397     BDRVRawState *s = bs->opaque;
1398     int fd;
1399
1400     /*
1401      * Force reread of possibly changed/newly loaded disc,
1402      * FreeBSD seems to not notice sometimes...
1403      */
1404     if (s->fd >= 0)
1405         qemu_close(s->fd);
1406     fd = qemu_open(bs->filename, s->open_flags, 0644);
1407     if (fd < 0) {
1408         s->fd = -1;
1409         return -EIO;
1410     }
1411     s->fd = fd;
1412
1413     /* make sure the door isn't locked at this time */
1414     ioctl(s->fd, CDIOCALLOW);
1415     return 0;
1416 }
1417
1418 static int cdrom_is_inserted(BlockDriverState *bs)
1419 {
1420     return raw_getlength(bs) > 0;
1421 }
1422
1423 static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
1424 {
1425     BDRVRawState *s = bs->opaque;
1426
1427     if (s->fd < 0)
1428         return;
1429
1430     (void) ioctl(s->fd, CDIOCALLOW);
1431
1432     if (eject_flag) {
1433         if (ioctl(s->fd, CDIOCEJECT) < 0)
1434             perror("CDIOCEJECT");
1435     } else {
1436         if (ioctl(s->fd, CDIOCCLOSE) < 0)
1437             perror("CDIOCCLOSE");
1438     }
1439
1440     cdrom_reopen(bs);
1441 }
1442
1443 static void cdrom_lock_medium(BlockDriverState *bs, bool locked)
1444 {
1445     BDRVRawState *s = bs->opaque;
1446
1447     if (s->fd < 0)
1448         return;
1449     if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1450         /*
1451          * Note: an error can happen if the distribution automatically
1452          * mounts the CD-ROM
1453          */
1454         /* perror("CDROM_LOCKDOOR"); */
1455     }
1456 }
1457
1458 static BlockDriver bdrv_host_cdrom = {
1459     .format_name        = "host_cdrom",
1460     .protocol_name      = "host_cdrom",
1461     .instance_size      = sizeof(BDRVRawState),
1462     .bdrv_probe_device  = cdrom_probe_device,
1463     .bdrv_file_open     = cdrom_open,
1464     .bdrv_close         = raw_close,
1465     .bdrv_create        = hdev_create,
1466     .create_options     = raw_create_options,
1467     .bdrv_has_zero_init = hdev_has_zero_init,
1468
1469     .bdrv_aio_readv     = raw_aio_readv,
1470     .bdrv_aio_writev    = raw_aio_writev,
1471     .bdrv_aio_flush     = raw_aio_flush,
1472
1473     .bdrv_truncate      = raw_truncate,
1474     .bdrv_getlength     = raw_getlength,
1475     .bdrv_get_allocated_file_size
1476                         = raw_get_allocated_file_size,
1477
1478     /* removable device support */
1479     .bdrv_is_inserted   = cdrom_is_inserted,
1480     .bdrv_eject         = cdrom_eject,
1481     .bdrv_lock_medium   = cdrom_lock_medium,
1482 };
1483 #endif /* __FreeBSD__ */
1484
1485 static void bdrv_file_init(void)
1486 {
1487     /*
1488      * Register all the drivers.  Note that order is important, the driver
1489      * registered last will get probed first.
1490      */
1491     bdrv_register(&bdrv_file);
1492     bdrv_register(&bdrv_host_device);
1493 #ifdef __linux__
1494     bdrv_register(&bdrv_host_floppy);
1495     bdrv_register(&bdrv_host_cdrom);
1496 #endif
1497 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1498     bdrv_register(&bdrv_host_cdrom);
1499 #endif
1500 }
1501
1502 block_init(bdrv_file_init);
This page took 0.101962 seconds and 4 git commands to generate.