Statistics
| Branch: | Revision:

root / block / raw-posix.c @ 37628f11

History | View | Annotate | Download (37.2 kB)

1 83f64091 bellard
/*
2 223d4670 ths
 * Block driver for RAW files (posix)
3 5fafdf24 ths
 *
4 83f64091 bellard
 * Copyright (c) 2006 Fabrice Bellard
5 5fafdf24 ths
 *
6 83f64091 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 83f64091 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 83f64091 bellard
 * in the Software without restriction, including without limitation the rights
9 83f64091 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 83f64091 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 83f64091 bellard
 * furnished to do so, subject to the following conditions:
12 83f64091 bellard
 *
13 83f64091 bellard
 * The above copyright notice and this permission notice shall be included in
14 83f64091 bellard
 * all copies or substantial portions of the Software.
15 83f64091 bellard
 *
16 83f64091 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 83f64091 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 83f64091 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 83f64091 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 83f64091 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 83f64091 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 83f64091 bellard
 * THE SOFTWARE.
23 83f64091 bellard
 */
24 faf07963 pbrook
#include "qemu-common.h"
25 87ecb68b pbrook
#include "qemu-timer.h"
26 baf35cb9 aliguori
#include "qemu-char.h"
27 0bf9e31a Blue Swirl
#include "qemu-log.h"
28 83f64091 bellard
#include "block_int.h"
29 5efa9d5a Anthony Liguori
#include "module.h"
30 9ef91a67 Christoph Hellwig
#include "block/raw-posix-aio.h"
31 83f64091 bellard
32 83f64091 bellard
#ifdef CONFIG_COCOA
33 83f64091 bellard
#include <paths.h>
34 83f64091 bellard
#include <sys/param.h>
35 83f64091 bellard
#include <IOKit/IOKitLib.h>
36 83f64091 bellard
#include <IOKit/IOBSD.h>
37 83f64091 bellard
#include <IOKit/storage/IOMediaBSDClient.h>
38 83f64091 bellard
#include <IOKit/storage/IOMedia.h>
39 83f64091 bellard
#include <IOKit/storage/IOCDMedia.h>
40 83f64091 bellard
//#include <IOKit/storage/IOCDTypes.h>
41 83f64091 bellard
#include <CoreFoundation/CoreFoundation.h>
42 83f64091 bellard
#endif
43 83f64091 bellard
44 83f64091 bellard
#ifdef __sun__
45 2e9671da ths
#define _POSIX_PTHREAD_SEMANTICS 1
46 2e9671da ths
#include <signal.h>
47 83f64091 bellard
#include <sys/dkio.h>
48 83f64091 bellard
#endif
49 19cb3738 bellard
#ifdef __linux__
50 19cb3738 bellard
#include <sys/ioctl.h>
51 05acda4d Bernhard Kohl
#include <sys/param.h>
52 19cb3738 bellard
#include <linux/cdrom.h>
53 19cb3738 bellard
#include <linux/fd.h>
54 19cb3738 bellard
#endif
55 a167ba50 Aurelien Jarno
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
56 543952ca blueswir1
#include <signal.h>
57 1cb6c3fd ths
#include <sys/disk.h>
58 9f23011a blueswir1
#include <sys/cdio.h>
59 1cb6c3fd ths
#endif
60 83f64091 bellard
61 128ab2ff blueswir1
#ifdef __OpenBSD__
62 128ab2ff blueswir1
#include <sys/ioctl.h>
63 128ab2ff blueswir1
#include <sys/disklabel.h>
64 128ab2ff blueswir1
#include <sys/dkio.h>
65 128ab2ff blueswir1
#endif
66 128ab2ff blueswir1
67 c5e97233 blueswir1
#ifdef __DragonFly__
68 c5e97233 blueswir1
#include <sys/ioctl.h>
69 c5e97233 blueswir1
#include <sys/diskslice.h>
70 c5e97233 blueswir1
#endif
71 c5e97233 blueswir1
72 dce512de Christoph Hellwig
#ifdef CONFIG_XFS
73 dce512de Christoph Hellwig
#include <xfs/xfs.h>
74 dce512de Christoph Hellwig
#endif
75 dce512de Christoph Hellwig
76 19cb3738 bellard
//#define DEBUG_FLOPPY
77 83f64091 bellard
78 faf07963 pbrook
//#define DEBUG_BLOCK
79 03ff3ca3 aliguori
#if defined(DEBUG_BLOCK)
80 001faf32 Blue Swirl
#define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
81 001faf32 Blue Swirl
    { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
82 8c05dbf9 ths
#else
83 001faf32 Blue Swirl
#define DEBUG_BLOCK_PRINT(formatCstr, ...)
84 8c05dbf9 ths
#endif
85 8c05dbf9 ths
86 f6465578 aliguori
/* OS X does not have O_DSYNC */
87 f6465578 aliguori
#ifndef O_DSYNC
88 1c27a8b3 G 3
#ifdef O_SYNC
89 7ab064d2 aliguori
#define O_DSYNC O_SYNC
90 1c27a8b3 G 3
#elif defined(O_FSYNC)
91 1c27a8b3 G 3
#define O_DSYNC O_FSYNC
92 1c27a8b3 G 3
#endif
93 f6465578 aliguori
#endif
94 f6465578 aliguori
95 9f7965c7 aliguori
/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
96 9f7965c7 aliguori
#ifndef O_DIRECT
97 9f7965c7 aliguori
#define O_DIRECT O_DSYNC
98 9f7965c7 aliguori
#endif
99 9f7965c7 aliguori
100 19cb3738 bellard
#define FTYPE_FILE   0
101 19cb3738 bellard
#define FTYPE_CD     1
102 19cb3738 bellard
#define FTYPE_FD     2
103 83f64091 bellard
104 c57c846a Blue Swirl
/* if the FD is not accessed during that time (in ns), we try to
105 19cb3738 bellard
   reopen it to see if the disk has been changed */
106 c57c846a Blue Swirl
#define FD_OPEN_TIMEOUT (1000000000)
107 83f64091 bellard
108 581b9e29 Christoph Hellwig
#define MAX_BLOCKSIZE        4096
109 581b9e29 Christoph Hellwig
110 19cb3738 bellard
typedef struct BDRVRawState {
111 19cb3738 bellard
    int fd;
112 19cb3738 bellard
    int type;
113 0e1d8f4c Christoph Hellwig
    int open_flags;
114 19cb3738 bellard
#if defined(__linux__)
115 19cb3738 bellard
    /* linux floppy specific */
116 19cb3738 bellard
    int64_t fd_open_time;
117 19cb3738 bellard
    int64_t fd_error_time;
118 19cb3738 bellard
    int fd_got_error;
119 19cb3738 bellard
    int fd_media_changed;
120 83f64091 bellard
#endif
121 e44bd6fc Stefan Weil
#ifdef CONFIG_LINUX_AIO
122 5c6c3a6c Christoph Hellwig
    int use_aio;
123 1e5b9d2f Kevin Wolf
    void *aio_ctx;
124 e44bd6fc Stefan Weil
#endif
125 581b9e29 Christoph Hellwig
    uint8_t *aligned_buf;
126 581b9e29 Christoph Hellwig
    unsigned aligned_buf_size;
127 dce512de Christoph Hellwig
#ifdef CONFIG_XFS
128 dce512de Christoph Hellwig
    bool is_xfs : 1;
129 dce512de Christoph Hellwig
#endif
130 19cb3738 bellard
} BDRVRawState;
131 19cb3738 bellard
132 19cb3738 bellard
static int fd_open(BlockDriverState *bs);
133 22afa7b5 Kevin Wolf
static int64_t raw_getlength(BlockDriverState *bs);
134 83f64091 bellard
135 a167ba50 Aurelien Jarno
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
136 f3a5d3f8 Christoph Hellwig
static int cdrom_reopen(BlockDriverState *bs);
137 9f23011a blueswir1
#endif
138 9f23011a blueswir1
139 90babde0 Christoph Hellwig
static int raw_open_common(BlockDriverState *bs, const char *filename,
140 19a3da7f Blue Swirl
                           int bdrv_flags, int open_flags)
141 83f64091 bellard
{
142 83f64091 bellard
    BDRVRawState *s = bs->opaque;
143 0e1d8f4c Christoph Hellwig
    int fd, ret;
144 83f64091 bellard
145 19a3da7f Blue Swirl
    s->open_flags = open_flags | O_BINARY;
146 11a1feb6 Avi Kivity
    s->open_flags &= ~O_ACCMODE;
147 f5edb014 Naphtali Sprei
    if (bdrv_flags & BDRV_O_RDWR) {
148 0e1d8f4c Christoph Hellwig
        s->open_flags |= O_RDWR;
149 83f64091 bellard
    } else {
150 0e1d8f4c Christoph Hellwig
        s->open_flags |= O_RDONLY;
151 83f64091 bellard
    }
152 9f7965c7 aliguori
153 9f7965c7 aliguori
    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
154 9f7965c7 aliguori
     * and O_DIRECT for no caching. */
155 19a3da7f Blue Swirl
    if ((bdrv_flags & BDRV_O_NOCACHE))
156 0e1d8f4c Christoph Hellwig
        s->open_flags |= O_DIRECT;
157 19a3da7f Blue Swirl
    else if (!(bdrv_flags & BDRV_O_CACHE_WB))
158 0e1d8f4c Christoph Hellwig
        s->open_flags |= O_DSYNC;
159 83f64091 bellard
160 90babde0 Christoph Hellwig
    s->fd = -1;
161 40ff6d7e Kevin Wolf
    fd = qemu_open(filename, s->open_flags, 0644);
162 19cb3738 bellard
    if (fd < 0) {
163 19cb3738 bellard
        ret = -errno;
164 19cb3738 bellard
        if (ret == -EROFS)
165 19cb3738 bellard
            ret = -EACCES;
166 19cb3738 bellard
        return ret;
167 19cb3738 bellard
    }
168 83f64091 bellard
    s->fd = fd;
169 bed5cc52 bellard
    s->aligned_buf = NULL;
170 5c6c3a6c Christoph Hellwig
171 19a3da7f Blue Swirl
    if ((bdrv_flags & BDRV_O_NOCACHE)) {
172 581b9e29 Christoph Hellwig
        /*
173 581b9e29 Christoph Hellwig
         * Allocate a buffer for read/modify/write cycles.  Chose the size
174 581b9e29 Christoph Hellwig
         * pessimistically as we don't know the block size yet.
175 581b9e29 Christoph Hellwig
         */
176 581b9e29 Christoph Hellwig
        s->aligned_buf_size = 32 * MAX_BLOCKSIZE;
177 581b9e29 Christoph Hellwig
        s->aligned_buf = qemu_memalign(MAX_BLOCKSIZE, s->aligned_buf_size);
178 bed5cc52 bellard
        if (s->aligned_buf == NULL) {
179 9ef91a67 Christoph Hellwig
            goto out_close;
180 bed5cc52 bellard
        }
181 bed5cc52 bellard
    }
182 9ef91a67 Christoph Hellwig
183 5c6c3a6c Christoph Hellwig
#ifdef CONFIG_LINUX_AIO
184 5c6c3a6c Christoph Hellwig
    if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
185 5c6c3a6c Christoph Hellwig
                      (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
186 d2e46345 Kevin Wolf
187 d2e46345 Kevin Wolf
        /* We're falling back to POSIX AIO in some cases */
188 d2e46345 Kevin Wolf
        paio_init();
189 d2e46345 Kevin Wolf
190 5c6c3a6c Christoph Hellwig
        s->aio_ctx = laio_init();
191 5c6c3a6c Christoph Hellwig
        if (!s->aio_ctx) {
192 5c6c3a6c Christoph Hellwig
            goto out_free_buf;
193 5c6c3a6c Christoph Hellwig
        }
194 5c6c3a6c Christoph Hellwig
        s->use_aio = 1;
195 5c6c3a6c Christoph Hellwig
    } else
196 5c6c3a6c Christoph Hellwig
#endif
197 5c6c3a6c Christoph Hellwig
    {
198 1e5b9d2f Kevin Wolf
        if (paio_init() < 0) {
199 5c6c3a6c Christoph Hellwig
            goto out_free_buf;
200 5c6c3a6c Christoph Hellwig
        }
201 e44bd6fc Stefan Weil
#ifdef CONFIG_LINUX_AIO
202 5c6c3a6c Christoph Hellwig
        s->use_aio = 0;
203 e44bd6fc Stefan Weil
#endif
204 9ef91a67 Christoph Hellwig
    }
205 9ef91a67 Christoph Hellwig
206 dce512de Christoph Hellwig
#ifdef CONFIG_XFS
207 dce512de Christoph Hellwig
    if (platform_test_xfs_fd(s->fd)) {
208 dce512de Christoph Hellwig
        s->is_xfs = 1;
209 dce512de Christoph Hellwig
    }
210 dce512de Christoph Hellwig
#endif
211 dce512de Christoph Hellwig
212 83f64091 bellard
    return 0;
213 9ef91a67 Christoph Hellwig
214 9ef91a67 Christoph Hellwig
out_free_buf:
215 9ef91a67 Christoph Hellwig
    qemu_vfree(s->aligned_buf);
216 9ef91a67 Christoph Hellwig
out_close:
217 9ef91a67 Christoph Hellwig
    close(fd);
218 9ef91a67 Christoph Hellwig
    return -errno;
219 83f64091 bellard
}
220 83f64091 bellard
221 90babde0 Christoph Hellwig
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
222 90babde0 Christoph Hellwig
{
223 90babde0 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
224 90babde0 Christoph Hellwig
225 90babde0 Christoph Hellwig
    s->type = FTYPE_FILE;
226 9a2d77ad Christoph Hellwig
    return raw_open_common(bs, filename, flags, 0);
227 90babde0 Christoph Hellwig
}
228 90babde0 Christoph Hellwig
229 83f64091 bellard
/* XXX: use host sector size if necessary with:
230 83f64091 bellard
#ifdef DIOCGSECTORSIZE
231 83f64091 bellard
        {
232 83f64091 bellard
            unsigned int sectorsize = 512;
233 83f64091 bellard
            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
234 83f64091 bellard
                sectorsize > bufsize)
235 83f64091 bellard
                bufsize = sectorsize;
236 83f64091 bellard
        }
237 83f64091 bellard
#endif
238 83f64091 bellard
#ifdef CONFIG_COCOA
239 2ee9fb48 Stefan Weil
        uint32_t blockSize = 512;
240 83f64091 bellard
        if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
241 83f64091 bellard
            bufsize = blockSize;
242 83f64091 bellard
        }
243 83f64091 bellard
#endif
244 83f64091 bellard
*/
245 83f64091 bellard
246 bed5cc52 bellard
/*
247 bed5cc52 bellard
 * offset and count are in bytes, but must be multiples of 512 for files
248 bed5cc52 bellard
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
249 bed5cc52 bellard
 *
250 bed5cc52 bellard
 * This function may be called without alignment if the caller ensures
251 bed5cc52 bellard
 * that O_DIRECT is not in effect.
252 bed5cc52 bellard
 */
253 bed5cc52 bellard
static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
254 83f64091 bellard
                     uint8_t *buf, int count)
255 83f64091 bellard
{
256 83f64091 bellard
    BDRVRawState *s = bs->opaque;
257 83f64091 bellard
    int ret;
258 3b46e624 ths
259 19cb3738 bellard
    ret = fd_open(bs);
260 19cb3738 bellard
    if (ret < 0)
261 19cb3738 bellard
        return ret;
262 19cb3738 bellard
263 4899d10d Stefan Hajnoczi
    ret = pread(s->fd, buf, count, offset);
264 8c05dbf9 ths
    if (ret == count)
265 65d21bc7 Markus Armbruster
        return ret;
266 8c05dbf9 ths
267 22afa7b5 Kevin Wolf
    /* Allow reads beyond the end (needed for pwrite) */
268 22afa7b5 Kevin Wolf
    if ((ret == 0) && bs->growable) {
269 22afa7b5 Kevin Wolf
        int64_t size = raw_getlength(bs);
270 22afa7b5 Kevin Wolf
        if (offset >= size) {
271 22afa7b5 Kevin Wolf
            memset(buf, 0, count);
272 65d21bc7 Markus Armbruster
            return count;
273 22afa7b5 Kevin Wolf
        }
274 22afa7b5 Kevin Wolf
    }
275 22afa7b5 Kevin Wolf
276 92868412 j_mayer
    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
277 92868412 j_mayer
                      "] read failed %d : %d = %s\n",
278 8c05dbf9 ths
                      s->fd, bs->filename, offset, buf, count,
279 8c05dbf9 ths
                      bs->total_sectors, ret, errno, strerror(errno));
280 8c05dbf9 ths
281 8c05dbf9 ths
    /* Try harder for CDrom. */
282 65d21bc7 Markus Armbruster
    if (s->type != FTYPE_FILE) {
283 4899d10d Stefan Hajnoczi
        ret = pread(s->fd, buf, count, offset);
284 8c05dbf9 ths
        if (ret == count)
285 65d21bc7 Markus Armbruster
            return ret;
286 4899d10d Stefan Hajnoczi
        ret = pread(s->fd, buf, count, offset);
287 8c05dbf9 ths
        if (ret == count)
288 65d21bc7 Markus Armbruster
            return ret;
289 8c05dbf9 ths
290 92868412 j_mayer
        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
291 92868412 j_mayer
                          "] retry read failed %d : %d = %s\n",
292 8c05dbf9 ths
                          s->fd, bs->filename, offset, buf, count,
293 8c05dbf9 ths
                          bs->total_sectors, ret, errno, strerror(errno));
294 8c05dbf9 ths
    }
295 8c05dbf9 ths
296 94c6d6d8 Christoph Hellwig
    return  (ret < 0) ? -errno : ret;
297 83f64091 bellard
}
298 83f64091 bellard
299 bed5cc52 bellard
/*
300 581b9e29 Christoph Hellwig
 * offset and count are in bytes, but must be multiples of the sector size
301 581b9e29 Christoph Hellwig
 * for files opened with O_DIRECT. buf must be aligned to sector size bytes
302 581b9e29 Christoph Hellwig
 * then.
303 bed5cc52 bellard
 *
304 bed5cc52 bellard
 * This function may be called without alignment if the caller ensures
305 bed5cc52 bellard
 * that O_DIRECT is not in effect.
306 bed5cc52 bellard
 */
307 bed5cc52 bellard
static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
308 83f64091 bellard
                      const uint8_t *buf, int count)
309 83f64091 bellard
{
310 83f64091 bellard
    BDRVRawState *s = bs->opaque;
311 83f64091 bellard
    int ret;
312 3b46e624 ths
313 19cb3738 bellard
    ret = fd_open(bs);
314 19cb3738 bellard
    if (ret < 0)
315 4141d4c2 aliguori
        return -errno;
316 19cb3738 bellard
317 4899d10d Stefan Hajnoczi
    ret = pwrite(s->fd, buf, count, offset);
318 8c05dbf9 ths
    if (ret == count)
319 65d21bc7 Markus Armbruster
        return ret;
320 8c05dbf9 ths
321 92868412 j_mayer
    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
322 92868412 j_mayer
                      "] write failed %d : %d = %s\n",
323 8c05dbf9 ths
                      s->fd, bs->filename, offset, buf, count,
324 8c05dbf9 ths
                      bs->total_sectors, ret, errno, strerror(errno));
325 8c05dbf9 ths
326 4141d4c2 aliguori
    return  (ret < 0) ? -errno : ret;
327 83f64091 bellard
}
328 83f64091 bellard
329 bed5cc52 bellard
330 bed5cc52 bellard
/*
331 bed5cc52 bellard
 * offset and count are in bytes and possibly not aligned. For files opened
332 bed5cc52 bellard
 * with O_DIRECT, necessary alignments are ensured before calling
333 bed5cc52 bellard
 * raw_pread_aligned to do the actual read.
334 bed5cc52 bellard
 */
335 bed5cc52 bellard
static int raw_pread(BlockDriverState *bs, int64_t offset,
336 bed5cc52 bellard
                     uint8_t *buf, int count)
337 bed5cc52 bellard
{
338 bed5cc52 bellard
    BDRVRawState *s = bs->opaque;
339 581b9e29 Christoph Hellwig
    unsigned sector_mask = bs->buffer_alignment - 1;
340 bed5cc52 bellard
    int size, ret, shift, sum;
341 bed5cc52 bellard
342 bed5cc52 bellard
    sum = 0;
343 bed5cc52 bellard
344 bed5cc52 bellard
    if (s->aligned_buf != NULL)  {
345 bed5cc52 bellard
346 581b9e29 Christoph Hellwig
        if (offset & sector_mask) {
347 581b9e29 Christoph Hellwig
            /* align offset on a sector size bytes boundary */
348 bed5cc52 bellard
349 581b9e29 Christoph Hellwig
            shift = offset & sector_mask;
350 581b9e29 Christoph Hellwig
            size = (shift + count + sector_mask) & ~sector_mask;
351 581b9e29 Christoph Hellwig
            if (size > s->aligned_buf_size)
352 581b9e29 Christoph Hellwig
                size = s->aligned_buf_size;
353 bed5cc52 bellard
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
354 bed5cc52 bellard
            if (ret < 0)
355 bed5cc52 bellard
                return ret;
356 bed5cc52 bellard
357 581b9e29 Christoph Hellwig
            size = bs->buffer_alignment - shift;
358 bed5cc52 bellard
            if (size > count)
359 bed5cc52 bellard
                size = count;
360 bed5cc52 bellard
            memcpy(buf, s->aligned_buf + shift, size);
361 bed5cc52 bellard
362 bed5cc52 bellard
            buf += size;
363 bed5cc52 bellard
            offset += size;
364 bed5cc52 bellard
            count -= size;
365 bed5cc52 bellard
            sum += size;
366 bed5cc52 bellard
367 bed5cc52 bellard
            if (count == 0)
368 bed5cc52 bellard
                return sum;
369 bed5cc52 bellard
        }
370 581b9e29 Christoph Hellwig
        if (count & sector_mask || (uintptr_t) buf & sector_mask) {
371 bed5cc52 bellard
372 bed5cc52 bellard
            /* read on aligned buffer */
373 bed5cc52 bellard
374 bed5cc52 bellard
            while (count) {
375 bed5cc52 bellard
376 581b9e29 Christoph Hellwig
                size = (count + sector_mask) & ~sector_mask;
377 581b9e29 Christoph Hellwig
                if (size > s->aligned_buf_size)
378 581b9e29 Christoph Hellwig
                    size = s->aligned_buf_size;
379 bed5cc52 bellard
380 bed5cc52 bellard
                ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
381 053965c7 Kevin Wolf
                if (ret < 0) {
382 bed5cc52 bellard
                    return ret;
383 053965c7 Kevin Wolf
                } else if (ret == 0) {
384 053965c7 Kevin Wolf
                    fprintf(stderr, "raw_pread: read beyond end of file\n");
385 053965c7 Kevin Wolf
                    abort();
386 053965c7 Kevin Wolf
                }
387 bed5cc52 bellard
388 bed5cc52 bellard
                size = ret;
389 bed5cc52 bellard
                if (size > count)
390 bed5cc52 bellard
                    size = count;
391 bed5cc52 bellard
392 bed5cc52 bellard
                memcpy(buf, s->aligned_buf, size);
393 bed5cc52 bellard
394 bed5cc52 bellard
                buf += size;
395 bed5cc52 bellard
                offset += size;
396 bed5cc52 bellard
                count -= size;
397 bed5cc52 bellard
                sum += size;
398 bed5cc52 bellard
            }
399 bed5cc52 bellard
400 bed5cc52 bellard
            return sum;
401 bed5cc52 bellard
        }
402 bed5cc52 bellard
    }
403 bed5cc52 bellard
404 bed5cc52 bellard
    return raw_pread_aligned(bs, offset, buf, count) + sum;
405 bed5cc52 bellard
}
406 bed5cc52 bellard
407 eda578e5 aliguori
static int raw_read(BlockDriverState *bs, int64_t sector_num,
408 eda578e5 aliguori
                    uint8_t *buf, int nb_sectors)
409 eda578e5 aliguori
{
410 537a1d4b aliguori
    int ret;
411 537a1d4b aliguori
412 9040385d Jes Sorensen
    ret = raw_pread(bs, sector_num * BDRV_SECTOR_SIZE, buf,
413 9040385d Jes Sorensen
                    nb_sectors * BDRV_SECTOR_SIZE);
414 9040385d Jes Sorensen
    if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
415 537a1d4b aliguori
        ret = 0;
416 537a1d4b aliguori
    return ret;
417 eda578e5 aliguori
}
418 eda578e5 aliguori
419 bed5cc52 bellard
/*
420 bed5cc52 bellard
 * offset and count are in bytes and possibly not aligned. For files opened
421 bed5cc52 bellard
 * with O_DIRECT, necessary alignments are ensured before calling
422 bed5cc52 bellard
 * raw_pwrite_aligned to do the actual write.
423 bed5cc52 bellard
 */
424 bed5cc52 bellard
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
425 bed5cc52 bellard
                      const uint8_t *buf, int count)
426 bed5cc52 bellard
{
427 bed5cc52 bellard
    BDRVRawState *s = bs->opaque;
428 581b9e29 Christoph Hellwig
    unsigned sector_mask = bs->buffer_alignment - 1;
429 bed5cc52 bellard
    int size, ret, shift, sum;
430 bed5cc52 bellard
431 bed5cc52 bellard
    sum = 0;
432 bed5cc52 bellard
433 bed5cc52 bellard
    if (s->aligned_buf != NULL) {
434 bed5cc52 bellard
435 581b9e29 Christoph Hellwig
        if (offset & sector_mask) {
436 581b9e29 Christoph Hellwig
            /* align offset on a sector size bytes boundary */
437 581b9e29 Christoph Hellwig
            shift = offset & sector_mask;
438 581b9e29 Christoph Hellwig
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf,
439 581b9e29 Christoph Hellwig
                                    bs->buffer_alignment);
440 bed5cc52 bellard
            if (ret < 0)
441 bed5cc52 bellard
                return ret;
442 bed5cc52 bellard
443 581b9e29 Christoph Hellwig
            size = bs->buffer_alignment - shift;
444 bed5cc52 bellard
            if (size > count)
445 bed5cc52 bellard
                size = count;
446 bed5cc52 bellard
            memcpy(s->aligned_buf + shift, buf, size);
447 bed5cc52 bellard
448 581b9e29 Christoph Hellwig
            ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf,
449 581b9e29 Christoph Hellwig
                                     bs->buffer_alignment);
450 bed5cc52 bellard
            if (ret < 0)
451 bed5cc52 bellard
                return ret;
452 bed5cc52 bellard
453 bed5cc52 bellard
            buf += size;
454 bed5cc52 bellard
            offset += size;
455 bed5cc52 bellard
            count -= size;
456 bed5cc52 bellard
            sum += size;
457 bed5cc52 bellard
458 bed5cc52 bellard
            if (count == 0)
459 bed5cc52 bellard
                return sum;
460 bed5cc52 bellard
        }
461 581b9e29 Christoph Hellwig
        if (count & sector_mask || (uintptr_t) buf & sector_mask) {
462 bed5cc52 bellard
463 581b9e29 Christoph Hellwig
            while ((size = (count & ~sector_mask)) != 0) {
464 bed5cc52 bellard
465 581b9e29 Christoph Hellwig
                if (size > s->aligned_buf_size)
466 581b9e29 Christoph Hellwig
                    size = s->aligned_buf_size;
467 bed5cc52 bellard
468 bed5cc52 bellard
                memcpy(s->aligned_buf, buf, size);
469 bed5cc52 bellard
470 bed5cc52 bellard
                ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
471 bed5cc52 bellard
                if (ret < 0)
472 bed5cc52 bellard
                    return ret;
473 bed5cc52 bellard
474 bed5cc52 bellard
                buf += ret;
475 bed5cc52 bellard
                offset += ret;
476 bed5cc52 bellard
                count -= ret;
477 bed5cc52 bellard
                sum += ret;
478 bed5cc52 bellard
            }
479 11a3cb81 Christoph Hellwig
            /* here, count < sector_size because (count & ~sector_mask) == 0 */
480 bed5cc52 bellard
            if (count) {
481 581b9e29 Christoph Hellwig
                ret = raw_pread_aligned(bs, offset, s->aligned_buf,
482 581b9e29 Christoph Hellwig
                                     bs->buffer_alignment);
483 bed5cc52 bellard
                if (ret < 0)
484 bed5cc52 bellard
                    return ret;
485 bed5cc52 bellard
                 memcpy(s->aligned_buf, buf, count);
486 bed5cc52 bellard
487 581b9e29 Christoph Hellwig
                 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf,
488 581b9e29 Christoph Hellwig
                                     bs->buffer_alignment);
489 bed5cc52 bellard
                 if (ret < 0)
490 bed5cc52 bellard
                     return ret;
491 bed5cc52 bellard
                 if (count < ret)
492 bed5cc52 bellard
                     ret = count;
493 bed5cc52 bellard
494 bed5cc52 bellard
                 sum += ret;
495 bed5cc52 bellard
            }
496 bed5cc52 bellard
            return sum;
497 bed5cc52 bellard
        }
498 bed5cc52 bellard
    }
499 bed5cc52 bellard
    return raw_pwrite_aligned(bs, offset, buf, count) + sum;
500 bed5cc52 bellard
}
501 bed5cc52 bellard
502 eda578e5 aliguori
static int raw_write(BlockDriverState *bs, int64_t sector_num,
503 eda578e5 aliguori
                     const uint8_t *buf, int nb_sectors)
504 eda578e5 aliguori
{
505 537a1d4b aliguori
    int ret;
506 9040385d Jes Sorensen
    ret = raw_pwrite(bs, sector_num * BDRV_SECTOR_SIZE, buf,
507 9040385d Jes Sorensen
                     nb_sectors * BDRV_SECTOR_SIZE);
508 9040385d Jes Sorensen
    if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
509 537a1d4b aliguori
        ret = 0;
510 537a1d4b aliguori
    return ret;
511 eda578e5 aliguori
}
512 eda578e5 aliguori
513 9ef91a67 Christoph Hellwig
/*
514 9ef91a67 Christoph Hellwig
 * Check if all memory in this vector is sector aligned.
515 9ef91a67 Christoph Hellwig
 */
516 581b9e29 Christoph Hellwig
static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
517 a76bab49 aliguori
{
518 9ef91a67 Christoph Hellwig
    int i;
519 83f64091 bellard
520 9ef91a67 Christoph Hellwig
    for (i = 0; i < qiov->niov; i++) {
521 581b9e29 Christoph Hellwig
        if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) {
522 9ef91a67 Christoph Hellwig
            return 0;
523 c16b5a2c Christoph Hellwig
        }
524 c16b5a2c Christoph Hellwig
    }
525 c16b5a2c Christoph Hellwig
526 9ef91a67 Christoph Hellwig
    return 1;
527 c16b5a2c Christoph Hellwig
}
528 c16b5a2c Christoph Hellwig
529 9ef91a67 Christoph Hellwig
static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
530 9ef91a67 Christoph Hellwig
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
531 9ef91a67 Christoph Hellwig
        BlockDriverCompletionFunc *cb, void *opaque, int type)
532 83f64091 bellard
{
533 ce1a14dc pbrook
    BDRVRawState *s = bs->opaque;
534 ce1a14dc pbrook
535 19cb3738 bellard
    if (fd_open(bs) < 0)
536 19cb3738 bellard
        return NULL;
537 19cb3738 bellard
538 f141eafe aliguori
    /*
539 f141eafe aliguori
     * If O_DIRECT is used the buffer needs to be aligned on a sector
540 9ef91a67 Christoph Hellwig
     * boundary.  Check if this is the case or telll the low-level
541 9ef91a67 Christoph Hellwig
     * driver that it needs to copy the buffer.
542 f141eafe aliguori
     */
543 5c6c3a6c Christoph Hellwig
    if (s->aligned_buf) {
544 581b9e29 Christoph Hellwig
        if (!qiov_is_aligned(bs, qiov)) {
545 5c6c3a6c Christoph Hellwig
            type |= QEMU_AIO_MISALIGNED;
546 e44bd6fc Stefan Weil
#ifdef CONFIG_LINUX_AIO
547 5c6c3a6c Christoph Hellwig
        } else if (s->use_aio) {
548 5c6c3a6c Christoph Hellwig
            return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov,
549 e44bd6fc Stefan Weil
                               nb_sectors, cb, opaque, type);
550 e44bd6fc Stefan Weil
#endif
551 5c6c3a6c Christoph Hellwig
        }
552 9ef91a67 Christoph Hellwig
    }
553 f141eafe aliguori
554 1e5b9d2f Kevin Wolf
    return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors,
555 9ef91a67 Christoph Hellwig
                       cb, opaque, type);
556 83f64091 bellard
}
557 83f64091 bellard
558 f141eafe aliguori
static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
559 f141eafe aliguori
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
560 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque)
561 83f64091 bellard
{
562 9ef91a67 Christoph Hellwig
    return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
563 9ef91a67 Christoph Hellwig
                          cb, opaque, QEMU_AIO_READ);
564 83f64091 bellard
}
565 83f64091 bellard
566 f141eafe aliguori
static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
567 f141eafe aliguori
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
568 ce1a14dc pbrook
        BlockDriverCompletionFunc *cb, void *opaque)
569 83f64091 bellard
{
570 9ef91a67 Christoph Hellwig
    return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
571 9ef91a67 Christoph Hellwig
                          cb, opaque, QEMU_AIO_WRITE);
572 83f64091 bellard
}
573 53538725 aliguori
574 b2e12bc6 Christoph Hellwig
static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
575 b2e12bc6 Christoph Hellwig
        BlockDriverCompletionFunc *cb, void *opaque)
576 b2e12bc6 Christoph Hellwig
{
577 b2e12bc6 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
578 b2e12bc6 Christoph Hellwig
579 b2e12bc6 Christoph Hellwig
    if (fd_open(bs) < 0)
580 b2e12bc6 Christoph Hellwig
        return NULL;
581 b2e12bc6 Christoph Hellwig
582 1e5b9d2f Kevin Wolf
    return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH);
583 b2e12bc6 Christoph Hellwig
}
584 b2e12bc6 Christoph Hellwig
585 83f64091 bellard
static void raw_close(BlockDriverState *bs)
586 83f64091 bellard
{
587 83f64091 bellard
    BDRVRawState *s = bs->opaque;
588 19cb3738 bellard
    if (s->fd >= 0) {
589 19cb3738 bellard
        close(s->fd);
590 19cb3738 bellard
        s->fd = -1;
591 bed5cc52 bellard
        if (s->aligned_buf != NULL)
592 f8a83245 Herve Poussineau
            qemu_vfree(s->aligned_buf);
593 19cb3738 bellard
    }
594 83f64091 bellard
}
595 83f64091 bellard
596 83f64091 bellard
static int raw_truncate(BlockDriverState *bs, int64_t offset)
597 83f64091 bellard
{
598 83f64091 bellard
    BDRVRawState *s = bs->opaque;
599 19cb3738 bellard
    if (s->type != FTYPE_FILE)
600 19cb3738 bellard
        return -ENOTSUP;
601 83f64091 bellard
    if (ftruncate(s->fd, offset) < 0)
602 83f64091 bellard
        return -errno;
603 83f64091 bellard
    return 0;
604 83f64091 bellard
}
605 83f64091 bellard
606 128ab2ff blueswir1
#ifdef __OpenBSD__
607 128ab2ff blueswir1
static int64_t raw_getlength(BlockDriverState *bs)
608 128ab2ff blueswir1
{
609 128ab2ff blueswir1
    BDRVRawState *s = bs->opaque;
610 128ab2ff blueswir1
    int fd = s->fd;
611 128ab2ff blueswir1
    struct stat st;
612 128ab2ff blueswir1
613 128ab2ff blueswir1
    if (fstat(fd, &st))
614 128ab2ff blueswir1
        return -1;
615 128ab2ff blueswir1
    if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
616 128ab2ff blueswir1
        struct disklabel dl;
617 128ab2ff blueswir1
618 128ab2ff blueswir1
        if (ioctl(fd, DIOCGDINFO, &dl))
619 128ab2ff blueswir1
            return -1;
620 128ab2ff blueswir1
        return (uint64_t)dl.d_secsize *
621 128ab2ff blueswir1
            dl.d_partitions[DISKPART(st.st_rdev)].p_size;
622 128ab2ff blueswir1
    } else
623 128ab2ff blueswir1
        return st.st_size;
624 128ab2ff blueswir1
}
625 50779cc2 Christoph Hellwig
#elif defined(__sun__)
626 50779cc2 Christoph Hellwig
static int64_t raw_getlength(BlockDriverState *bs)
627 50779cc2 Christoph Hellwig
{
628 50779cc2 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
629 50779cc2 Christoph Hellwig
    struct dk_minfo minfo;
630 50779cc2 Christoph Hellwig
    int ret;
631 50779cc2 Christoph Hellwig
632 50779cc2 Christoph Hellwig
    ret = fd_open(bs);
633 50779cc2 Christoph Hellwig
    if (ret < 0) {
634 50779cc2 Christoph Hellwig
        return ret;
635 50779cc2 Christoph Hellwig
    }
636 50779cc2 Christoph Hellwig
637 50779cc2 Christoph Hellwig
    /*
638 50779cc2 Christoph Hellwig
     * Use the DKIOCGMEDIAINFO ioctl to read the size.
639 50779cc2 Christoph Hellwig
     */
640 50779cc2 Christoph Hellwig
    ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo);
641 50779cc2 Christoph Hellwig
    if (ret != -1) {
642 50779cc2 Christoph Hellwig
        return minfo.dki_lbsize * minfo.dki_capacity;
643 50779cc2 Christoph Hellwig
    }
644 50779cc2 Christoph Hellwig
645 50779cc2 Christoph Hellwig
    /*
646 50779cc2 Christoph Hellwig
     * There are reports that lseek on some devices fails, but
647 50779cc2 Christoph Hellwig
     * irc discussion said that contingency on contingency was overkill.
648 50779cc2 Christoph Hellwig
     */
649 50779cc2 Christoph Hellwig
    return lseek(s->fd, 0, SEEK_END);
650 50779cc2 Christoph Hellwig
}
651 50779cc2 Christoph Hellwig
#elif defined(CONFIG_BSD)
652 50779cc2 Christoph Hellwig
static int64_t raw_getlength(BlockDriverState *bs)
653 83f64091 bellard
{
654 83f64091 bellard
    BDRVRawState *s = bs->opaque;
655 83f64091 bellard
    int fd = s->fd;
656 83f64091 bellard
    int64_t size;
657 83f64091 bellard
    struct stat sb;
658 a167ba50 Aurelien Jarno
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
659 9f23011a blueswir1
    int reopened = 0;
660 9f23011a blueswir1
#endif
661 19cb3738 bellard
    int ret;
662 19cb3738 bellard
663 19cb3738 bellard
    ret = fd_open(bs);
664 19cb3738 bellard
    if (ret < 0)
665 19cb3738 bellard
        return ret;
666 83f64091 bellard
667 a167ba50 Aurelien Jarno
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
668 9f23011a blueswir1
again:
669 9f23011a blueswir1
#endif
670 83f64091 bellard
    if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
671 83f64091 bellard
#ifdef DIOCGMEDIASIZE
672 83f64091 bellard
        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
673 c5e97233 blueswir1
#elif defined(DIOCGPART)
674 c5e97233 blueswir1
        {
675 c5e97233 blueswir1
                struct partinfo pi;
676 c5e97233 blueswir1
                if (ioctl(fd, DIOCGPART, &pi) == 0)
677 c5e97233 blueswir1
                        size = pi.media_size;
678 c5e97233 blueswir1
                else
679 c5e97233 blueswir1
                        size = 0;
680 c5e97233 blueswir1
        }
681 c5e97233 blueswir1
        if (size == 0)
682 83f64091 bellard
#endif
683 83f64091 bellard
#ifdef CONFIG_COCOA
684 83f64091 bellard
        size = LONG_LONG_MAX;
685 83f64091 bellard
#else
686 83f64091 bellard
        size = lseek(fd, 0LL, SEEK_END);
687 83f64091 bellard
#endif
688 a167ba50 Aurelien Jarno
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
689 9f23011a blueswir1
        switch(s->type) {
690 9f23011a blueswir1
        case FTYPE_CD:
691 9f23011a blueswir1
            /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
692 9f23011a blueswir1
            if (size == 2048LL * (unsigned)-1)
693 9f23011a blueswir1
                size = 0;
694 9f23011a blueswir1
            /* XXX no disc?  maybe we need to reopen... */
695 f3a5d3f8 Christoph Hellwig
            if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
696 9f23011a blueswir1
                reopened = 1;
697 9f23011a blueswir1
                goto again;
698 9f23011a blueswir1
            }
699 9f23011a blueswir1
        }
700 9f23011a blueswir1
#endif
701 50779cc2 Christoph Hellwig
    } else {
702 83f64091 bellard
        size = lseek(fd, 0, SEEK_END);
703 83f64091 bellard
    }
704 83f64091 bellard
    return size;
705 83f64091 bellard
}
706 50779cc2 Christoph Hellwig
#else
707 50779cc2 Christoph Hellwig
static int64_t raw_getlength(BlockDriverState *bs)
708 50779cc2 Christoph Hellwig
{
709 50779cc2 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
710 50779cc2 Christoph Hellwig
    int ret;
711 50779cc2 Christoph Hellwig
712 50779cc2 Christoph Hellwig
    ret = fd_open(bs);
713 50779cc2 Christoph Hellwig
    if (ret < 0) {
714 50779cc2 Christoph Hellwig
        return ret;
715 50779cc2 Christoph Hellwig
    }
716 50779cc2 Christoph Hellwig
717 50779cc2 Christoph Hellwig
    return lseek(s->fd, 0, SEEK_END);
718 50779cc2 Christoph Hellwig
}
719 128ab2ff blueswir1
#endif
720 83f64091 bellard
721 0e7e1989 Kevin Wolf
static int raw_create(const char *filename, QEMUOptionParameter *options)
722 83f64091 bellard
{
723 83f64091 bellard
    int fd;
724 1e37d059 Stefan Weil
    int result = 0;
725 0e7e1989 Kevin Wolf
    int64_t total_size = 0;
726 83f64091 bellard
727 0e7e1989 Kevin Wolf
    /* Read out options */
728 0e7e1989 Kevin Wolf
    while (options && options->name) {
729 0e7e1989 Kevin Wolf
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
730 9040385d Jes Sorensen
            total_size = options->value.n / BDRV_SECTOR_SIZE;
731 0e7e1989 Kevin Wolf
        }
732 0e7e1989 Kevin Wolf
        options++;
733 0e7e1989 Kevin Wolf
    }
734 83f64091 bellard
735 5fafdf24 ths
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
736 83f64091 bellard
              0644);
737 1e37d059 Stefan Weil
    if (fd < 0) {
738 1e37d059 Stefan Weil
        result = -errno;
739 1e37d059 Stefan Weil
    } else {
740 9040385d Jes Sorensen
        if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
741 1e37d059 Stefan Weil
            result = -errno;
742 1e37d059 Stefan Weil
        }
743 1e37d059 Stefan Weil
        if (close(fd) != 0) {
744 1e37d059 Stefan Weil
            result = -errno;
745 1e37d059 Stefan Weil
        }
746 1e37d059 Stefan Weil
    }
747 1e37d059 Stefan Weil
    return result;
748 83f64091 bellard
}
749 83f64091 bellard
750 205ef796 Kevin Wolf
static int raw_flush(BlockDriverState *bs)
751 83f64091 bellard
{
752 83f64091 bellard
    BDRVRawState *s = bs->opaque;
753 205ef796 Kevin Wolf
    return qemu_fdatasync(s->fd);
754 83f64091 bellard
}
755 83f64091 bellard
756 dce512de Christoph Hellwig
#ifdef CONFIG_XFS
757 dce512de Christoph Hellwig
static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
758 dce512de Christoph Hellwig
{
759 dce512de Christoph Hellwig
    struct xfs_flock64 fl;
760 dce512de Christoph Hellwig
761 dce512de Christoph Hellwig
    memset(&fl, 0, sizeof(fl));
762 dce512de Christoph Hellwig
    fl.l_whence = SEEK_SET;
763 dce512de Christoph Hellwig
    fl.l_start = sector_num << 9;
764 dce512de Christoph Hellwig
    fl.l_len = (int64_t)nb_sectors << 9;
765 dce512de Christoph Hellwig
766 dce512de Christoph Hellwig
    if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
767 dce512de Christoph Hellwig
        DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
768 dce512de Christoph Hellwig
        return -errno;
769 dce512de Christoph Hellwig
    }
770 dce512de Christoph Hellwig
771 dce512de Christoph Hellwig
    return 0;
772 dce512de Christoph Hellwig
}
773 dce512de Christoph Hellwig
#endif
774 dce512de Christoph Hellwig
775 dce512de Christoph Hellwig
static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
776 dce512de Christoph Hellwig
{
777 dce512de Christoph Hellwig
#ifdef CONFIG_XFS
778 dce512de Christoph Hellwig
    BDRVRawState *s = bs->opaque;
779 dce512de Christoph Hellwig
780 dce512de Christoph Hellwig
    if (s->is_xfs) {
781 dce512de Christoph Hellwig
        return xfs_discard(s, sector_num, nb_sectors);
782 dce512de Christoph Hellwig
    }
783 dce512de Christoph Hellwig
#endif
784 dce512de Christoph Hellwig
785 dce512de Christoph Hellwig
    return 0;
786 dce512de Christoph Hellwig
}
787 0e7e1989 Kevin Wolf
788 0e7e1989 Kevin Wolf
static QEMUOptionParameter raw_create_options[] = {
789 db08adf5 Kevin Wolf
    {
790 db08adf5 Kevin Wolf
        .name = BLOCK_OPT_SIZE,
791 db08adf5 Kevin Wolf
        .type = OPT_SIZE,
792 db08adf5 Kevin Wolf
        .help = "Virtual disk size"
793 db08adf5 Kevin Wolf
    },
794 0e7e1989 Kevin Wolf
    { NULL }
795 0e7e1989 Kevin Wolf
};
796 0e7e1989 Kevin Wolf
797 84a12e66 Christoph Hellwig
static BlockDriver bdrv_file = {
798 84a12e66 Christoph Hellwig
    .format_name = "file",
799 84a12e66 Christoph Hellwig
    .protocol_name = "file",
800 856ae5c3 blueswir1
    .instance_size = sizeof(BDRVRawState),
801 856ae5c3 blueswir1
    .bdrv_probe = NULL, /* no probe for protocols */
802 66f82cee Kevin Wolf
    .bdrv_file_open = raw_open,
803 856ae5c3 blueswir1
    .bdrv_read = raw_read,
804 856ae5c3 blueswir1
    .bdrv_write = raw_write,
805 856ae5c3 blueswir1
    .bdrv_close = raw_close,
806 856ae5c3 blueswir1
    .bdrv_create = raw_create,
807 856ae5c3 blueswir1
    .bdrv_flush = raw_flush,
808 dce512de Christoph Hellwig
    .bdrv_discard = raw_discard,
809 3b46e624 ths
810 f141eafe aliguori
    .bdrv_aio_readv = raw_aio_readv,
811 f141eafe aliguori
    .bdrv_aio_writev = raw_aio_writev,
812 b2e12bc6 Christoph Hellwig
    .bdrv_aio_flush = raw_aio_flush,
813 3c529d93 aliguori
814 83f64091 bellard
    .bdrv_truncate = raw_truncate,
815 83f64091 bellard
    .bdrv_getlength = raw_getlength,
816 0e7e1989 Kevin Wolf
817 0e7e1989 Kevin Wolf
    .create_options = raw_create_options,
818 83f64091 bellard
};
819 83f64091 bellard
820 19cb3738 bellard
/***********************************************/
821 19cb3738 bellard
/* host device */
822 19cb3738 bellard
823 19cb3738 bellard
#ifdef CONFIG_COCOA
824 19cb3738 bellard
static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
825 19cb3738 bellard
static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
826 19cb3738 bellard
827 19cb3738 bellard
kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
828 19cb3738 bellard
{
829 5fafdf24 ths
    kern_return_t       kernResult;
830 19cb3738 bellard
    mach_port_t     masterPort;
831 19cb3738 bellard
    CFMutableDictionaryRef  classesToMatch;
832 19cb3738 bellard
833 19cb3738 bellard
    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
834 19cb3738 bellard
    if ( KERN_SUCCESS != kernResult ) {
835 19cb3738 bellard
        printf( "IOMasterPort returned %d\n", kernResult );
836 19cb3738 bellard
    }
837 3b46e624 ths
838 5fafdf24 ths
    classesToMatch = IOServiceMatching( kIOCDMediaClass );
839 19cb3738 bellard
    if ( classesToMatch == NULL ) {
840 19cb3738 bellard
        printf( "IOServiceMatching returned a NULL dictionary.\n" );
841 19cb3738 bellard
    } else {
842 19cb3738 bellard
    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
843 19cb3738 bellard
    }
844 19cb3738 bellard
    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
845 19cb3738 bellard
    if ( KERN_SUCCESS != kernResult )
846 19cb3738 bellard
    {
847 19cb3738 bellard
        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
848 19cb3738 bellard
    }
849 3b46e624 ths
850 19cb3738 bellard
    return kernResult;
851 19cb3738 bellard
}
852 19cb3738 bellard
853 19cb3738 bellard
kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
854 19cb3738 bellard
{
855 19cb3738 bellard
    io_object_t     nextMedia;
856 19cb3738 bellard
    kern_return_t   kernResult = KERN_FAILURE;
857 19cb3738 bellard
    *bsdPath = '\0';
858 19cb3738 bellard
    nextMedia = IOIteratorNext( mediaIterator );
859 19cb3738 bellard
    if ( nextMedia )
860 19cb3738 bellard
    {
861 19cb3738 bellard
        CFTypeRef   bsdPathAsCFString;
862 19cb3738 bellard
    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
863 19cb3738 bellard
        if ( bsdPathAsCFString ) {
864 19cb3738 bellard
            size_t devPathLength;
865 19cb3738 bellard
            strcpy( bsdPath, _PATH_DEV );
866 19cb3738 bellard
            strcat( bsdPath, "r" );
867 19cb3738 bellard
            devPathLength = strlen( bsdPath );
868 19cb3738 bellard
            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
869 19cb3738 bellard
                kernResult = KERN_SUCCESS;
870 19cb3738 bellard
            }
871 19cb3738 bellard
            CFRelease( bsdPathAsCFString );
872 19cb3738 bellard
        }
873 19cb3738 bellard
        IOObjectRelease( nextMedia );
874 19cb3738 bellard
    }
875 3b46e624 ths
876 19cb3738 bellard
    return kernResult;
877 19cb3738 bellard
}
878 19cb3738 bellard
879 19cb3738 bellard
#endif
880 19cb3738 bellard
881 508c7cb3 Christoph Hellwig
static int hdev_probe_device(const char *filename)
882 508c7cb3 Christoph Hellwig
{
883 508c7cb3 Christoph Hellwig
    struct stat st;
884 508c7cb3 Christoph Hellwig
885 508c7cb3 Christoph Hellwig
    /* allow a dedicated CD-ROM driver to match with a higher priority */
886 508c7cb3 Christoph Hellwig
    if (strstart(filename, "/dev/cdrom", NULL))
887 508c7cb3 Christoph Hellwig
        return 50;
888 508c7cb3 Christoph Hellwig
889 508c7cb3 Christoph Hellwig
    if (stat(filename, &st) >= 0 &&
890 508c7cb3 Christoph Hellwig
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
891 508c7cb3 Christoph Hellwig
        return 100;
892 508c7cb3 Christoph Hellwig
    }
893 508c7cb3 Christoph Hellwig
894 508c7cb3 Christoph Hellwig
    return 0;
895 508c7cb3 Christoph Hellwig
}
896 508c7cb3 Christoph Hellwig
897 19cb3738 bellard
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
898 19cb3738 bellard
{
899 19cb3738 bellard
    BDRVRawState *s = bs->opaque;
900 a76bab49 aliguori
901 19cb3738 bellard
#ifdef CONFIG_COCOA
902 19cb3738 bellard
    if (strstart(filename, "/dev/cdrom", NULL)) {
903 19cb3738 bellard
        kern_return_t kernResult;
904 19cb3738 bellard
        io_iterator_t mediaIterator;
905 19cb3738 bellard
        char bsdPath[ MAXPATHLEN ];
906 19cb3738 bellard
        int fd;
907 5fafdf24 ths
908 19cb3738 bellard
        kernResult = FindEjectableCDMedia( &mediaIterator );
909 19cb3738 bellard
        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
910 3b46e624 ths
911 19cb3738 bellard
        if ( bsdPath[ 0 ] != '\0' ) {
912 19cb3738 bellard
            strcat(bsdPath,"s0");
913 19cb3738 bellard
            /* some CDs don't have a partition 0 */
914 19cb3738 bellard
            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
915 19cb3738 bellard
            if (fd < 0) {
916 19cb3738 bellard
                bsdPath[strlen(bsdPath)-1] = '1';
917 19cb3738 bellard
            } else {
918 19cb3738 bellard
                close(fd);
919 19cb3738 bellard
            }
920 19cb3738 bellard
            filename = bsdPath;
921 19cb3738 bellard
        }
922 3b46e624 ths
923 19cb3738 bellard
        if ( mediaIterator )
924 19cb3738 bellard
            IOObjectRelease( mediaIterator );
925 19cb3738 bellard
    }
926 19cb3738 bellard
#endif
927 19cb3738 bellard
928 19cb3738 bellard
    s->type = FTYPE_FILE;
929 4dd75c70 Christoph Hellwig
#if defined(__linux__)
930 05acda4d Bernhard Kohl
    {
931 05acda4d Bernhard Kohl
        char resolved_path[ MAXPATHLEN ], *temp;
932 05acda4d Bernhard Kohl
933 05acda4d Bernhard Kohl
        temp = realpath(filename, resolved_path);
934 05acda4d Bernhard Kohl
        if (temp && strstart(temp, "/dev/sg", NULL)) {
935 05acda4d Bernhard Kohl
            bs->sg = 1;
936 05acda4d Bernhard Kohl
        }
937 19cb3738 bellard
    }
938 19cb3738 bellard
#endif
939 90babde0 Christoph Hellwig
940 19a3da7f Blue Swirl
    return raw_open_common(bs, filename, flags, 0);
941 19cb3738 bellard
}
942 19cb3738 bellard
943 03ff3ca3 aliguori
#if defined(__linux__)
944 19cb3738 bellard
/* Note: we do not have a reliable method to detect if the floppy is
945 19cb3738 bellard
   present. The current method is to try to open the floppy at every
946 19cb3738 bellard
   I/O and to keep it opened during a few hundreds of ms. */
947 19cb3738 bellard
static int fd_open(BlockDriverState *bs)
948 19cb3738 bellard
{
949 19cb3738 bellard
    BDRVRawState *s = bs->opaque;
950 19cb3738 bellard
    int last_media_present;
951 19cb3738 bellard
952 19cb3738 bellard
    if (s->type != FTYPE_FD)
953 19cb3738 bellard
        return 0;
954 19cb3738 bellard
    last_media_present = (s->fd >= 0);
955 5fafdf24 ths
    if (s->fd >= 0 &&
956 c57c846a Blue Swirl
        (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
957 19cb3738 bellard
        close(s->fd);
958 19cb3738 bellard
        s->fd = -1;
959 19cb3738 bellard
#ifdef DEBUG_FLOPPY
960 19cb3738 bellard
        printf("Floppy closed\n");
961 19cb3738 bellard
#endif
962 19cb3738 bellard
    }
963 19cb3738 bellard
    if (s->fd < 0) {
964 5fafdf24 ths
        if (s->fd_got_error &&
965 c57c846a Blue Swirl
            (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
966 19cb3738 bellard
#ifdef DEBUG_FLOPPY
967 19cb3738 bellard
            printf("No floppy (open delayed)\n");
968 19cb3738 bellard
#endif
969 19cb3738 bellard
            return -EIO;
970 19cb3738 bellard
        }
971 0e1d8f4c Christoph Hellwig
        s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
972 19cb3738 bellard
        if (s->fd < 0) {
973 c57c846a Blue Swirl
            s->fd_error_time = get_clock();
974 19cb3738 bellard
            s->fd_got_error = 1;
975 19cb3738 bellard
            if (last_media_present)
976 19cb3738 bellard
                s->fd_media_changed = 1;
977 19cb3738 bellard
#ifdef DEBUG_FLOPPY
978 19cb3738 bellard
            printf("No floppy\n");
979 19cb3738 bellard
#endif
980 19cb3738 bellard
            return -EIO;
981 19cb3738 bellard
        }
982 19cb3738 bellard
#ifdef DEBUG_FLOPPY
983 19cb3738 bellard
        printf("Floppy opened\n");
984 19cb3738 bellard
#endif
985 19cb3738 bellard
    }
986 19cb3738 bellard
    if (!last_media_present)
987 19cb3738 bellard
        s->fd_media_changed = 1;
988 c57c846a Blue Swirl
    s->fd_open_time = get_clock();
989 19cb3738 bellard
    s->fd_got_error = 0;
990 19cb3738 bellard
    return 0;
991 19cb3738 bellard
}
992 19cb3738 bellard
993 63ec93db Christoph Hellwig
static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
994 985a03b0 ths
{
995 985a03b0 ths
    BDRVRawState *s = bs->opaque;
996 985a03b0 ths
997 985a03b0 ths
    return ioctl(s->fd, req, buf);
998 985a03b0 ths
}
999 221f715d aliguori
1000 63ec93db Christoph Hellwig
static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
1001 221f715d aliguori
        unsigned long int req, void *buf,
1002 221f715d aliguori
        BlockDriverCompletionFunc *cb, void *opaque)
1003 221f715d aliguori
{
1004 f141eafe aliguori
    BDRVRawState *s = bs->opaque;
1005 221f715d aliguori
1006 f141eafe aliguori
    if (fd_open(bs) < 0)
1007 f141eafe aliguori
        return NULL;
1008 9ef91a67 Christoph Hellwig
    return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
1009 221f715d aliguori
}
1010 221f715d aliguori
1011 a167ba50 Aurelien Jarno
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1012 9f23011a blueswir1
static int fd_open(BlockDriverState *bs)
1013 9f23011a blueswir1
{
1014 9f23011a blueswir1
    BDRVRawState *s = bs->opaque;
1015 9f23011a blueswir1
1016 9f23011a blueswir1
    /* this is just to ensure s->fd is sane (its called by io ops) */
1017 9f23011a blueswir1
    if (s->fd >= 0)
1018 9f23011a blueswir1
        return 0;
1019 9f23011a blueswir1
    return -EIO;
1020 9f23011a blueswir1
}
1021 9f23011a blueswir1
#else /* !linux && !FreeBSD */
1022 19cb3738 bellard
1023 08af02e2 aliguori
static int fd_open(BlockDriverState *bs)
1024 08af02e2 aliguori
{
1025 08af02e2 aliguori
    return 0;
1026 08af02e2 aliguori
}
1027 08af02e2 aliguori
1028 221f715d aliguori
#endif /* !linux && !FreeBSD */
1029 04eeb8b6 aliguori
1030 0e7e1989 Kevin Wolf
static int hdev_create(const char *filename, QEMUOptionParameter *options)
1031 93c65b47 aliguori
{
1032 93c65b47 aliguori
    int fd;
1033 93c65b47 aliguori
    int ret = 0;
1034 93c65b47 aliguori
    struct stat stat_buf;
1035 0e7e1989 Kevin Wolf
    int64_t total_size = 0;
1036 93c65b47 aliguori
1037 0e7e1989 Kevin Wolf
    /* Read out options */
1038 0e7e1989 Kevin Wolf
    while (options && options->name) {
1039 0e7e1989 Kevin Wolf
        if (!strcmp(options->name, "size")) {
1040 9040385d Jes Sorensen
            total_size = options->value.n / BDRV_SECTOR_SIZE;
1041 0e7e1989 Kevin Wolf
        }
1042 0e7e1989 Kevin Wolf
        options++;
1043 0e7e1989 Kevin Wolf
    }
1044 93c65b47 aliguori
1045 93c65b47 aliguori
    fd = open(filename, O_WRONLY | O_BINARY);
1046 93c65b47 aliguori
    if (fd < 0)
1047 57e69b7d Kevin Wolf
        return -errno;
1048 93c65b47 aliguori
1049 93c65b47 aliguori
    if (fstat(fd, &stat_buf) < 0)
1050 57e69b7d Kevin Wolf
        ret = -errno;
1051 4099df58 Christoph Hellwig
    else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1052 57e69b7d Kevin Wolf
        ret = -ENODEV;
1053 9040385d Jes Sorensen
    else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE)
1054 93c65b47 aliguori
        ret = -ENOSPC;
1055 93c65b47 aliguori
1056 93c65b47 aliguori
    close(fd);
1057 93c65b47 aliguori
    return ret;
1058 93c65b47 aliguori
}
1059 93c65b47 aliguori
1060 336c1c12 Kevin Wolf
static int hdev_has_zero_init(BlockDriverState *bs)
1061 336c1c12 Kevin Wolf
{
1062 336c1c12 Kevin Wolf
    return 0;
1063 336c1c12 Kevin Wolf
}
1064 336c1c12 Kevin Wolf
1065 5efa9d5a Anthony Liguori
static BlockDriver bdrv_host_device = {
1066 0b4ce02e Kevin Wolf
    .format_name        = "host_device",
1067 84a12e66 Christoph Hellwig
    .protocol_name        = "host_device",
1068 0b4ce02e Kevin Wolf
    .instance_size      = sizeof(BDRVRawState),
1069 0b4ce02e Kevin Wolf
    .bdrv_probe_device  = hdev_probe_device,
1070 66f82cee Kevin Wolf
    .bdrv_file_open     = hdev_open,
1071 0b4ce02e Kevin Wolf
    .bdrv_close         = raw_close,
1072 93c65b47 aliguori
    .bdrv_create        = hdev_create,
1073 0b4ce02e Kevin Wolf
    .create_options     = raw_create_options,
1074 336c1c12 Kevin Wolf
    .bdrv_has_zero_init = hdev_has_zero_init,
1075 0b4ce02e Kevin Wolf
    .bdrv_flush         = raw_flush,
1076 3b46e624 ths
1077 f141eafe aliguori
    .bdrv_aio_readv        = raw_aio_readv,
1078 f141eafe aliguori
    .bdrv_aio_writev        = raw_aio_writev,
1079 b2e12bc6 Christoph Hellwig
    .bdrv_aio_flush        = raw_aio_flush,
1080 3c529d93 aliguori
1081 eda578e5 aliguori
    .bdrv_read          = raw_read,
1082 eda578e5 aliguori
    .bdrv_write         = raw_write,
1083 e60f469c aurel32
    .bdrv_getlength        = raw_getlength,
1084 19cb3738 bellard
1085 f3a5d3f8 Christoph Hellwig
    /* generic scsi device */
1086 63ec93db Christoph Hellwig
#ifdef __linux__
1087 63ec93db Christoph Hellwig
    .bdrv_ioctl         = hdev_ioctl,
1088 63ec93db Christoph Hellwig
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1089 63ec93db Christoph Hellwig
#endif
1090 f3a5d3f8 Christoph Hellwig
};
1091 f3a5d3f8 Christoph Hellwig
1092 f3a5d3f8 Christoph Hellwig
#ifdef __linux__
1093 f3a5d3f8 Christoph Hellwig
static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
1094 f3a5d3f8 Christoph Hellwig
{
1095 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1096 f3a5d3f8 Christoph Hellwig
    int ret;
1097 f3a5d3f8 Christoph Hellwig
1098 f3a5d3f8 Christoph Hellwig
    s->type = FTYPE_FD;
1099 f3a5d3f8 Christoph Hellwig
1100 19a3da7f Blue Swirl
    /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1101 19a3da7f Blue Swirl
    ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
1102 f3a5d3f8 Christoph Hellwig
    if (ret)
1103 f3a5d3f8 Christoph Hellwig
        return ret;
1104 f3a5d3f8 Christoph Hellwig
1105 f3a5d3f8 Christoph Hellwig
    /* close fd so that we can reopen it as needed */
1106 f3a5d3f8 Christoph Hellwig
    close(s->fd);
1107 f3a5d3f8 Christoph Hellwig
    s->fd = -1;
1108 f3a5d3f8 Christoph Hellwig
    s->fd_media_changed = 1;
1109 f3a5d3f8 Christoph Hellwig
1110 f3a5d3f8 Christoph Hellwig
    return 0;
1111 f3a5d3f8 Christoph Hellwig
}
1112 f3a5d3f8 Christoph Hellwig
1113 508c7cb3 Christoph Hellwig
static int floppy_probe_device(const char *filename)
1114 508c7cb3 Christoph Hellwig
{
1115 2ebf7c4b Cole Robinson
    int fd, ret;
1116 2ebf7c4b Cole Robinson
    int prio = 0;
1117 2ebf7c4b Cole Robinson
    struct floppy_struct fdparam;
1118 2ebf7c4b Cole Robinson
1119 508c7cb3 Christoph Hellwig
    if (strstart(filename, "/dev/fd", NULL))
1120 2ebf7c4b Cole Robinson
        prio = 50;
1121 2ebf7c4b Cole Robinson
1122 2ebf7c4b Cole Robinson
    fd = open(filename, O_RDONLY | O_NONBLOCK);
1123 2ebf7c4b Cole Robinson
    if (fd < 0) {
1124 2ebf7c4b Cole Robinson
        goto out;
1125 2ebf7c4b Cole Robinson
    }
1126 2ebf7c4b Cole Robinson
1127 2ebf7c4b Cole Robinson
    /* Attempt to detect via a floppy specific ioctl */
1128 2ebf7c4b Cole Robinson
    ret = ioctl(fd, FDGETPRM, &fdparam);
1129 2ebf7c4b Cole Robinson
    if (ret >= 0)
1130 2ebf7c4b Cole Robinson
        prio = 100;
1131 2ebf7c4b Cole Robinson
1132 2ebf7c4b Cole Robinson
    close(fd);
1133 2ebf7c4b Cole Robinson
out:
1134 2ebf7c4b Cole Robinson
    return prio;
1135 508c7cb3 Christoph Hellwig
}
1136 508c7cb3 Christoph Hellwig
1137 508c7cb3 Christoph Hellwig
1138 f3a5d3f8 Christoph Hellwig
static int floppy_is_inserted(BlockDriverState *bs)
1139 f3a5d3f8 Christoph Hellwig
{
1140 f3a5d3f8 Christoph Hellwig
    return fd_open(bs) >= 0;
1141 f3a5d3f8 Christoph Hellwig
}
1142 f3a5d3f8 Christoph Hellwig
1143 f3a5d3f8 Christoph Hellwig
static int floppy_media_changed(BlockDriverState *bs)
1144 f3a5d3f8 Christoph Hellwig
{
1145 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1146 f3a5d3f8 Christoph Hellwig
    int ret;
1147 f3a5d3f8 Christoph Hellwig
1148 f3a5d3f8 Christoph Hellwig
    /*
1149 f3a5d3f8 Christoph Hellwig
     * XXX: we do not have a true media changed indication.
1150 f3a5d3f8 Christoph Hellwig
     * It does not work if the floppy is changed without trying to read it.
1151 f3a5d3f8 Christoph Hellwig
     */
1152 f3a5d3f8 Christoph Hellwig
    fd_open(bs);
1153 f3a5d3f8 Christoph Hellwig
    ret = s->fd_media_changed;
1154 f3a5d3f8 Christoph Hellwig
    s->fd_media_changed = 0;
1155 f3a5d3f8 Christoph Hellwig
#ifdef DEBUG_FLOPPY
1156 f3a5d3f8 Christoph Hellwig
    printf("Floppy changed=%d\n", ret);
1157 f3a5d3f8 Christoph Hellwig
#endif
1158 f3a5d3f8 Christoph Hellwig
    return ret;
1159 f3a5d3f8 Christoph Hellwig
}
1160 f3a5d3f8 Christoph Hellwig
1161 f3a5d3f8 Christoph Hellwig
static int floppy_eject(BlockDriverState *bs, int eject_flag)
1162 f3a5d3f8 Christoph Hellwig
{
1163 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1164 f3a5d3f8 Christoph Hellwig
    int fd;
1165 f3a5d3f8 Christoph Hellwig
1166 f3a5d3f8 Christoph Hellwig
    if (s->fd >= 0) {
1167 f3a5d3f8 Christoph Hellwig
        close(s->fd);
1168 f3a5d3f8 Christoph Hellwig
        s->fd = -1;
1169 f3a5d3f8 Christoph Hellwig
    }
1170 f3a5d3f8 Christoph Hellwig
    fd = open(bs->filename, s->open_flags | O_NONBLOCK);
1171 f3a5d3f8 Christoph Hellwig
    if (fd >= 0) {
1172 f3a5d3f8 Christoph Hellwig
        if (ioctl(fd, FDEJECT, 0) < 0)
1173 f3a5d3f8 Christoph Hellwig
            perror("FDEJECT");
1174 f3a5d3f8 Christoph Hellwig
        close(fd);
1175 f3a5d3f8 Christoph Hellwig
    }
1176 f3a5d3f8 Christoph Hellwig
1177 f3a5d3f8 Christoph Hellwig
    return 0;
1178 f3a5d3f8 Christoph Hellwig
}
1179 f3a5d3f8 Christoph Hellwig
1180 f3a5d3f8 Christoph Hellwig
static BlockDriver bdrv_host_floppy = {
1181 f3a5d3f8 Christoph Hellwig
    .format_name        = "host_floppy",
1182 84a12e66 Christoph Hellwig
    .protocol_name      = "host_floppy",
1183 f3a5d3f8 Christoph Hellwig
    .instance_size      = sizeof(BDRVRawState),
1184 508c7cb3 Christoph Hellwig
    .bdrv_probe_device        = floppy_probe_device,
1185 66f82cee Kevin Wolf
    .bdrv_file_open     = floppy_open,
1186 f3a5d3f8 Christoph Hellwig
    .bdrv_close         = raw_close,
1187 f3a5d3f8 Christoph Hellwig
    .bdrv_create        = hdev_create,
1188 0b4ce02e Kevin Wolf
    .create_options     = raw_create_options,
1189 336c1c12 Kevin Wolf
    .bdrv_has_zero_init = hdev_has_zero_init,
1190 f3a5d3f8 Christoph Hellwig
    .bdrv_flush         = raw_flush,
1191 f3a5d3f8 Christoph Hellwig
1192 f3a5d3f8 Christoph Hellwig
    .bdrv_aio_readv     = raw_aio_readv,
1193 f3a5d3f8 Christoph Hellwig
    .bdrv_aio_writev    = raw_aio_writev,
1194 b2e12bc6 Christoph Hellwig
    .bdrv_aio_flush        = raw_aio_flush,
1195 f3a5d3f8 Christoph Hellwig
1196 f3a5d3f8 Christoph Hellwig
    .bdrv_read          = raw_read,
1197 f3a5d3f8 Christoph Hellwig
    .bdrv_write         = raw_write,
1198 f3a5d3f8 Christoph Hellwig
    .bdrv_getlength        = raw_getlength,
1199 f3a5d3f8 Christoph Hellwig
1200 f3a5d3f8 Christoph Hellwig
    /* removable device support */
1201 f3a5d3f8 Christoph Hellwig
    .bdrv_is_inserted   = floppy_is_inserted,
1202 f3a5d3f8 Christoph Hellwig
    .bdrv_media_changed = floppy_media_changed,
1203 f3a5d3f8 Christoph Hellwig
    .bdrv_eject         = floppy_eject,
1204 f3a5d3f8 Christoph Hellwig
};
1205 f3a5d3f8 Christoph Hellwig
1206 f3a5d3f8 Christoph Hellwig
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1207 f3a5d3f8 Christoph Hellwig
{
1208 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1209 f3a5d3f8 Christoph Hellwig
1210 f3a5d3f8 Christoph Hellwig
    s->type = FTYPE_CD;
1211 f3a5d3f8 Christoph Hellwig
1212 19a3da7f Blue Swirl
    /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1213 19a3da7f Blue Swirl
    return raw_open_common(bs, filename, flags, O_NONBLOCK);
1214 f3a5d3f8 Christoph Hellwig
}
1215 f3a5d3f8 Christoph Hellwig
1216 508c7cb3 Christoph Hellwig
static int cdrom_probe_device(const char *filename)
1217 508c7cb3 Christoph Hellwig
{
1218 3baf720e Cole Robinson
    int fd, ret;
1219 3baf720e Cole Robinson
    int prio = 0;
1220 3baf720e Cole Robinson
1221 3baf720e Cole Robinson
    fd = open(filename, O_RDONLY | O_NONBLOCK);
1222 3baf720e Cole Robinson
    if (fd < 0) {
1223 3baf720e Cole Robinson
        goto out;
1224 3baf720e Cole Robinson
    }
1225 3baf720e Cole Robinson
1226 3baf720e Cole Robinson
    /* Attempt to detect via a CDROM specific ioctl */
1227 3baf720e Cole Robinson
    ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1228 3baf720e Cole Robinson
    if (ret >= 0)
1229 3baf720e Cole Robinson
        prio = 100;
1230 3baf720e Cole Robinson
1231 3baf720e Cole Robinson
    close(fd);
1232 3baf720e Cole Robinson
out:
1233 3baf720e Cole Robinson
    return prio;
1234 508c7cb3 Christoph Hellwig
}
1235 508c7cb3 Christoph Hellwig
1236 f3a5d3f8 Christoph Hellwig
static int cdrom_is_inserted(BlockDriverState *bs)
1237 f3a5d3f8 Christoph Hellwig
{
1238 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1239 f3a5d3f8 Christoph Hellwig
    int ret;
1240 f3a5d3f8 Christoph Hellwig
1241 f3a5d3f8 Christoph Hellwig
    ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1242 f3a5d3f8 Christoph Hellwig
    if (ret == CDS_DISC_OK)
1243 f3a5d3f8 Christoph Hellwig
        return 1;
1244 f3a5d3f8 Christoph Hellwig
    return 0;
1245 f3a5d3f8 Christoph Hellwig
}
1246 f3a5d3f8 Christoph Hellwig
1247 f3a5d3f8 Christoph Hellwig
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1248 f3a5d3f8 Christoph Hellwig
{
1249 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1250 f3a5d3f8 Christoph Hellwig
1251 f3a5d3f8 Christoph Hellwig
    if (eject_flag) {
1252 f3a5d3f8 Christoph Hellwig
        if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1253 f3a5d3f8 Christoph Hellwig
            perror("CDROMEJECT");
1254 f3a5d3f8 Christoph Hellwig
    } else {
1255 f3a5d3f8 Christoph Hellwig
        if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1256 f3a5d3f8 Christoph Hellwig
            perror("CDROMEJECT");
1257 f3a5d3f8 Christoph Hellwig
    }
1258 f3a5d3f8 Christoph Hellwig
1259 f3a5d3f8 Christoph Hellwig
    return 0;
1260 f3a5d3f8 Christoph Hellwig
}
1261 f3a5d3f8 Christoph Hellwig
1262 f3a5d3f8 Christoph Hellwig
static int cdrom_set_locked(BlockDriverState *bs, int locked)
1263 f3a5d3f8 Christoph Hellwig
{
1264 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1265 f3a5d3f8 Christoph Hellwig
1266 f3a5d3f8 Christoph Hellwig
    if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1267 f3a5d3f8 Christoph Hellwig
        /*
1268 f3a5d3f8 Christoph Hellwig
         * Note: an error can happen if the distribution automatically
1269 f3a5d3f8 Christoph Hellwig
         * mounts the CD-ROM
1270 f3a5d3f8 Christoph Hellwig
         */
1271 f3a5d3f8 Christoph Hellwig
        /* perror("CDROM_LOCKDOOR"); */
1272 f3a5d3f8 Christoph Hellwig
    }
1273 f3a5d3f8 Christoph Hellwig
1274 f3a5d3f8 Christoph Hellwig
    return 0;
1275 f3a5d3f8 Christoph Hellwig
}
1276 f3a5d3f8 Christoph Hellwig
1277 f3a5d3f8 Christoph Hellwig
static BlockDriver bdrv_host_cdrom = {
1278 f3a5d3f8 Christoph Hellwig
    .format_name        = "host_cdrom",
1279 84a12e66 Christoph Hellwig
    .protocol_name      = "host_cdrom",
1280 f3a5d3f8 Christoph Hellwig
    .instance_size      = sizeof(BDRVRawState),
1281 508c7cb3 Christoph Hellwig
    .bdrv_probe_device        = cdrom_probe_device,
1282 66f82cee Kevin Wolf
    .bdrv_file_open     = cdrom_open,
1283 f3a5d3f8 Christoph Hellwig
    .bdrv_close         = raw_close,
1284 f3a5d3f8 Christoph Hellwig
    .bdrv_create        = hdev_create,
1285 0b4ce02e Kevin Wolf
    .create_options     = raw_create_options,
1286 336c1c12 Kevin Wolf
    .bdrv_has_zero_init = hdev_has_zero_init,
1287 f3a5d3f8 Christoph Hellwig
    .bdrv_flush         = raw_flush,
1288 f3a5d3f8 Christoph Hellwig
1289 f3a5d3f8 Christoph Hellwig
    .bdrv_aio_readv     = raw_aio_readv,
1290 f3a5d3f8 Christoph Hellwig
    .bdrv_aio_writev    = raw_aio_writev,
1291 b2e12bc6 Christoph Hellwig
    .bdrv_aio_flush        = raw_aio_flush,
1292 f3a5d3f8 Christoph Hellwig
1293 f3a5d3f8 Christoph Hellwig
    .bdrv_read          = raw_read,
1294 f3a5d3f8 Christoph Hellwig
    .bdrv_write         = raw_write,
1295 f3a5d3f8 Christoph Hellwig
    .bdrv_getlength     = raw_getlength,
1296 f3a5d3f8 Christoph Hellwig
1297 f3a5d3f8 Christoph Hellwig
    /* removable device support */
1298 f3a5d3f8 Christoph Hellwig
    .bdrv_is_inserted   = cdrom_is_inserted,
1299 f3a5d3f8 Christoph Hellwig
    .bdrv_eject         = cdrom_eject,
1300 f3a5d3f8 Christoph Hellwig
    .bdrv_set_locked    = cdrom_set_locked,
1301 f3a5d3f8 Christoph Hellwig
1302 f3a5d3f8 Christoph Hellwig
    /* generic scsi device */
1303 63ec93db Christoph Hellwig
    .bdrv_ioctl         = hdev_ioctl,
1304 63ec93db Christoph Hellwig
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1305 f3a5d3f8 Christoph Hellwig
};
1306 f3a5d3f8 Christoph Hellwig
#endif /* __linux__ */
1307 f3a5d3f8 Christoph Hellwig
1308 a167ba50 Aurelien Jarno
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
1309 f3a5d3f8 Christoph Hellwig
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1310 f3a5d3f8 Christoph Hellwig
{
1311 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1312 f3a5d3f8 Christoph Hellwig
    int ret;
1313 f3a5d3f8 Christoph Hellwig
1314 f3a5d3f8 Christoph Hellwig
    s->type = FTYPE_CD;
1315 f3a5d3f8 Christoph Hellwig
1316 19a3da7f Blue Swirl
    ret = raw_open_common(bs, filename, flags, 0);
1317 f3a5d3f8 Christoph Hellwig
    if (ret)
1318 f3a5d3f8 Christoph Hellwig
        return ret;
1319 f3a5d3f8 Christoph Hellwig
1320 f3a5d3f8 Christoph Hellwig
    /* make sure the door isnt locked at this time */
1321 f3a5d3f8 Christoph Hellwig
    ioctl(s->fd, CDIOCALLOW);
1322 f3a5d3f8 Christoph Hellwig
    return 0;
1323 f3a5d3f8 Christoph Hellwig
}
1324 f3a5d3f8 Christoph Hellwig
1325 508c7cb3 Christoph Hellwig
static int cdrom_probe_device(const char *filename)
1326 508c7cb3 Christoph Hellwig
{
1327 508c7cb3 Christoph Hellwig
    if (strstart(filename, "/dev/cd", NULL) ||
1328 508c7cb3 Christoph Hellwig
            strstart(filename, "/dev/acd", NULL))
1329 508c7cb3 Christoph Hellwig
        return 100;
1330 508c7cb3 Christoph Hellwig
    return 0;
1331 508c7cb3 Christoph Hellwig
}
1332 508c7cb3 Christoph Hellwig
1333 f3a5d3f8 Christoph Hellwig
static int cdrom_reopen(BlockDriverState *bs)
1334 f3a5d3f8 Christoph Hellwig
{
1335 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1336 f3a5d3f8 Christoph Hellwig
    int fd;
1337 f3a5d3f8 Christoph Hellwig
1338 f3a5d3f8 Christoph Hellwig
    /*
1339 f3a5d3f8 Christoph Hellwig
     * Force reread of possibly changed/newly loaded disc,
1340 f3a5d3f8 Christoph Hellwig
     * FreeBSD seems to not notice sometimes...
1341 f3a5d3f8 Christoph Hellwig
     */
1342 f3a5d3f8 Christoph Hellwig
    if (s->fd >= 0)
1343 f3a5d3f8 Christoph Hellwig
        close(s->fd);
1344 f3a5d3f8 Christoph Hellwig
    fd = open(bs->filename, s->open_flags, 0644);
1345 f3a5d3f8 Christoph Hellwig
    if (fd < 0) {
1346 f3a5d3f8 Christoph Hellwig
        s->fd = -1;
1347 f3a5d3f8 Christoph Hellwig
        return -EIO;
1348 f3a5d3f8 Christoph Hellwig
    }
1349 f3a5d3f8 Christoph Hellwig
    s->fd = fd;
1350 f3a5d3f8 Christoph Hellwig
1351 f3a5d3f8 Christoph Hellwig
    /* make sure the door isnt locked at this time */
1352 f3a5d3f8 Christoph Hellwig
    ioctl(s->fd, CDIOCALLOW);
1353 f3a5d3f8 Christoph Hellwig
    return 0;
1354 f3a5d3f8 Christoph Hellwig
}
1355 f3a5d3f8 Christoph Hellwig
1356 f3a5d3f8 Christoph Hellwig
static int cdrom_is_inserted(BlockDriverState *bs)
1357 f3a5d3f8 Christoph Hellwig
{
1358 f3a5d3f8 Christoph Hellwig
    return raw_getlength(bs) > 0;
1359 f3a5d3f8 Christoph Hellwig
}
1360 f3a5d3f8 Christoph Hellwig
1361 f3a5d3f8 Christoph Hellwig
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1362 f3a5d3f8 Christoph Hellwig
{
1363 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1364 f3a5d3f8 Christoph Hellwig
1365 f3a5d3f8 Christoph Hellwig
    if (s->fd < 0)
1366 f3a5d3f8 Christoph Hellwig
        return -ENOTSUP;
1367 f3a5d3f8 Christoph Hellwig
1368 f3a5d3f8 Christoph Hellwig
    (void) ioctl(s->fd, CDIOCALLOW);
1369 f3a5d3f8 Christoph Hellwig
1370 f3a5d3f8 Christoph Hellwig
    if (eject_flag) {
1371 f3a5d3f8 Christoph Hellwig
        if (ioctl(s->fd, CDIOCEJECT) < 0)
1372 f3a5d3f8 Christoph Hellwig
            perror("CDIOCEJECT");
1373 f3a5d3f8 Christoph Hellwig
    } else {
1374 f3a5d3f8 Christoph Hellwig
        if (ioctl(s->fd, CDIOCCLOSE) < 0)
1375 f3a5d3f8 Christoph Hellwig
            perror("CDIOCCLOSE");
1376 f3a5d3f8 Christoph Hellwig
    }
1377 f3a5d3f8 Christoph Hellwig
1378 f3a5d3f8 Christoph Hellwig
    if (cdrom_reopen(bs) < 0)
1379 f3a5d3f8 Christoph Hellwig
        return -ENOTSUP;
1380 f3a5d3f8 Christoph Hellwig
    return 0;
1381 f3a5d3f8 Christoph Hellwig
}
1382 f3a5d3f8 Christoph Hellwig
1383 f3a5d3f8 Christoph Hellwig
static int cdrom_set_locked(BlockDriverState *bs, int locked)
1384 f3a5d3f8 Christoph Hellwig
{
1385 f3a5d3f8 Christoph Hellwig
    BDRVRawState *s = bs->opaque;
1386 f3a5d3f8 Christoph Hellwig
1387 f3a5d3f8 Christoph Hellwig
    if (s->fd < 0)
1388 f3a5d3f8 Christoph Hellwig
        return -ENOTSUP;
1389 f3a5d3f8 Christoph Hellwig
    if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1390 f3a5d3f8 Christoph Hellwig
        /*
1391 f3a5d3f8 Christoph Hellwig
         * Note: an error can happen if the distribution automatically
1392 f3a5d3f8 Christoph Hellwig
         * mounts the CD-ROM
1393 f3a5d3f8 Christoph Hellwig
         */
1394 f3a5d3f8 Christoph Hellwig
        /* perror("CDROM_LOCKDOOR"); */
1395 f3a5d3f8 Christoph Hellwig
    }
1396 f3a5d3f8 Christoph Hellwig
1397 f3a5d3f8 Christoph Hellwig
    return 0;
1398 f3a5d3f8 Christoph Hellwig
}
1399 f3a5d3f8 Christoph Hellwig
1400 f3a5d3f8 Christoph Hellwig
static BlockDriver bdrv_host_cdrom = {
1401 f3a5d3f8 Christoph Hellwig
    .format_name        = "host_cdrom",
1402 84a12e66 Christoph Hellwig
    .protocol_name      = "host_cdrom",
1403 f3a5d3f8 Christoph Hellwig
    .instance_size      = sizeof(BDRVRawState),
1404 508c7cb3 Christoph Hellwig
    .bdrv_probe_device        = cdrom_probe_device,
1405 66f82cee Kevin Wolf
    .bdrv_file_open     = cdrom_open,
1406 f3a5d3f8 Christoph Hellwig
    .bdrv_close         = raw_close,
1407 f3a5d3f8 Christoph Hellwig
    .bdrv_create        = hdev_create,
1408 0b4ce02e Kevin Wolf
    .create_options     = raw_create_options,
1409 336c1c12 Kevin Wolf
    .bdrv_has_zero_init = hdev_has_zero_init,
1410 f3a5d3f8 Christoph Hellwig
    .bdrv_flush         = raw_flush,
1411 f3a5d3f8 Christoph Hellwig
1412 f3a5d3f8 Christoph Hellwig
    .bdrv_aio_readv     = raw_aio_readv,
1413 f3a5d3f8 Christoph Hellwig
    .bdrv_aio_writev    = raw_aio_writev,
1414 b2e12bc6 Christoph Hellwig
    .bdrv_aio_flush        = raw_aio_flush,
1415 f3a5d3f8 Christoph Hellwig
1416 f3a5d3f8 Christoph Hellwig
    .bdrv_read          = raw_read,
1417 f3a5d3f8 Christoph Hellwig
    .bdrv_write         = raw_write,
1418 f3a5d3f8 Christoph Hellwig
    .bdrv_getlength     = raw_getlength,
1419 f3a5d3f8 Christoph Hellwig
1420 19cb3738 bellard
    /* removable device support */
1421 f3a5d3f8 Christoph Hellwig
    .bdrv_is_inserted   = cdrom_is_inserted,
1422 f3a5d3f8 Christoph Hellwig
    .bdrv_eject         = cdrom_eject,
1423 f3a5d3f8 Christoph Hellwig
    .bdrv_set_locked    = cdrom_set_locked,
1424 19cb3738 bellard
};
1425 f3a5d3f8 Christoph Hellwig
#endif /* __FreeBSD__ */
1426 5efa9d5a Anthony Liguori
1427 84a12e66 Christoph Hellwig
static void bdrv_file_init(void)
1428 5efa9d5a Anthony Liguori
{
1429 508c7cb3 Christoph Hellwig
    /*
1430 508c7cb3 Christoph Hellwig
     * Register all the drivers.  Note that order is important, the driver
1431 508c7cb3 Christoph Hellwig
     * registered last will get probed first.
1432 508c7cb3 Christoph Hellwig
     */
1433 84a12e66 Christoph Hellwig
    bdrv_register(&bdrv_file);
1434 5efa9d5a Anthony Liguori
    bdrv_register(&bdrv_host_device);
1435 f3a5d3f8 Christoph Hellwig
#ifdef __linux__
1436 f3a5d3f8 Christoph Hellwig
    bdrv_register(&bdrv_host_floppy);
1437 f3a5d3f8 Christoph Hellwig
    bdrv_register(&bdrv_host_cdrom);
1438 f3a5d3f8 Christoph Hellwig
#endif
1439 a167ba50 Aurelien Jarno
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1440 f3a5d3f8 Christoph Hellwig
    bdrv_register(&bdrv_host_cdrom);
1441 f3a5d3f8 Christoph Hellwig
#endif
1442 5efa9d5a Anthony Liguori
}
1443 5efa9d5a Anthony Liguori
1444 84a12e66 Christoph Hellwig
block_init(bdrv_file_init);