Statistics
| Branch: | Revision:

root / block-raw-posix.c @ 55616505

History | View | Annotate | Download (36.4 kB)

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 "block_int.h"
28
#ifdef CONFIG_AIO
29
#include "posix-aio-compat.h"
30
#endif
31

    
32
#ifdef CONFIG_COCOA
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 <signal.h>
47
#include <sys/dkio.h>
48
#endif
49
#ifdef __linux__
50
#include <sys/ioctl.h>
51
#include <linux/cdrom.h>
52
#include <linux/fd.h>
53
#endif
54
#ifdef __FreeBSD__
55
#include <signal.h>
56
#include <sys/disk.h>
57
#include <sys/cdio.h>
58
#endif
59

    
60
#ifdef __OpenBSD__
61
#include <sys/ioctl.h>
62
#include <sys/disklabel.h>
63
#include <sys/dkio.h>
64
#endif
65

    
66
#ifdef __DragonFly__
67
#include <sys/ioctl.h>
68
#include <sys/diskslice.h>
69
#endif
70

    
71
//#define DEBUG_FLOPPY
72

    
73
//#define DEBUG_BLOCK
74
#if defined(DEBUG_BLOCK)
75
#define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
76
    { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
77
#else
78
#define DEBUG_BLOCK_PRINT(formatCstr, ...)
79
#endif
80

    
81
/* OS X does not have O_DSYNC */
82
#ifndef O_DSYNC
83
#define O_DSYNC O_SYNC
84
#endif
85

    
86
/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
87
#ifndef O_DIRECT
88
#define O_DIRECT O_DSYNC
89
#endif
90

    
91
#define FTYPE_FILE   0
92
#define FTYPE_CD     1
93
#define FTYPE_FD     2
94

    
95
#define ALIGNED_BUFFER_SIZE (32 * 512)
96

    
97
/* if the FD is not accessed during that time (in ms), we try to
98
   reopen it to see if the disk has been changed */
99
#define FD_OPEN_TIMEOUT 1000
100

    
101
typedef struct BDRVRawState {
102
    int fd;
103
    int type;
104
    unsigned int lseek_err_cnt;
105
#if defined(__linux__)
106
    /* linux floppy specific */
107
    int fd_open_flags;
108
    int64_t fd_open_time;
109
    int64_t fd_error_time;
110
    int fd_got_error;
111
    int fd_media_changed;
112
#endif
113
#if defined(__FreeBSD__)
114
    int cd_open_flags;
115
#endif
116
    uint8_t* aligned_buf;
117
} BDRVRawState;
118

    
119
static int posix_aio_init(void);
120

    
121
static int fd_open(BlockDriverState *bs);
122

    
123
#if defined(__FreeBSD__)
124
static int cd_open(BlockDriverState *bs);
125
#endif
126

    
127
static int raw_is_inserted(BlockDriverState *bs);
128

    
129
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
130
{
131
    BDRVRawState *s = bs->opaque;
132
    int fd, open_flags, ret;
133

    
134
    posix_aio_init();
135

    
136
    s->lseek_err_cnt = 0;
137

    
138
    open_flags = O_BINARY;
139
    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
140
        open_flags |= O_RDWR;
141
    } else {
142
        open_flags |= O_RDONLY;
143
        bs->read_only = 1;
144
    }
145
    if (flags & BDRV_O_CREAT)
146
        open_flags |= O_CREAT | O_TRUNC;
147

    
148
    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
149
     * and O_DIRECT for no caching. */
150
    if ((flags & BDRV_O_NOCACHE))
151
        open_flags |= O_DIRECT;
152
    else if (!(flags & BDRV_O_CACHE_WB))
153
        open_flags |= O_DSYNC;
154

    
155
    s->type = FTYPE_FILE;
156

    
157
    fd = open(filename, open_flags, 0644);
158
    if (fd < 0) {
159
        ret = -errno;
160
        if (ret == -EROFS)
161
            ret = -EACCES;
162
        return ret;
163
    }
164
    s->fd = fd;
165
    s->aligned_buf = NULL;
166
    if ((flags & BDRV_O_NOCACHE)) {
167
        s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE);
168
        if (s->aligned_buf == NULL) {
169
            ret = -errno;
170
            close(fd);
171
            return ret;
172
        }
173
    }
174
    return 0;
175
}
176

    
177
/* XXX: use host sector size if necessary with:
178
#ifdef DIOCGSECTORSIZE
179
        {
180
            unsigned int sectorsize = 512;
181
            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
182
                sectorsize > bufsize)
183
                bufsize = sectorsize;
184
        }
185
#endif
186
#ifdef CONFIG_COCOA
187
        u_int32_t   blockSize = 512;
188
        if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
189
            bufsize = blockSize;
190
        }
191
#endif
192
*/
193

    
194
/*
195
 * offset and count are in bytes, but must be multiples of 512 for files
196
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
197
 *
198
 * This function may be called without alignment if the caller ensures
199
 * that O_DIRECT is not in effect.
200
 */
201
static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
202
                     uint8_t *buf, int count)
203
{
204
    BDRVRawState *s = bs->opaque;
205
    int ret;
206

    
207
    ret = fd_open(bs);
208
    if (ret < 0)
209
        return ret;
210

    
211
    if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
212
        ++(s->lseek_err_cnt);
213
        if(s->lseek_err_cnt <= 10) {
214
            DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
215
                              "] lseek failed : %d = %s\n",
216
                              s->fd, bs->filename, offset, buf, count,
217
                              bs->total_sectors, errno, strerror(errno));
218
        }
219
        return -1;
220
    }
221
    s->lseek_err_cnt=0;
222

    
223
    ret = read(s->fd, buf, count);
224
    if (ret == count)
225
        goto label__raw_read__success;
226

    
227
    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
228
                      "] read failed %d : %d = %s\n",
229
                      s->fd, bs->filename, offset, buf, count,
230
                      bs->total_sectors, ret, errno, strerror(errno));
231

    
232
    /* Try harder for CDrom. */
233
    if (bs->type == BDRV_TYPE_CDROM) {
234
        lseek(s->fd, offset, SEEK_SET);
235
        ret = read(s->fd, buf, count);
236
        if (ret == count)
237
            goto label__raw_read__success;
238
        lseek(s->fd, offset, SEEK_SET);
239
        ret = read(s->fd, buf, count);
240
        if (ret == count)
241
            goto label__raw_read__success;
242

    
243
        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
244
                          "] retry read failed %d : %d = %s\n",
245
                          s->fd, bs->filename, offset, buf, count,
246
                          bs->total_sectors, ret, errno, strerror(errno));
247
    }
248

    
249
label__raw_read__success:
250

    
251
    return ret;
252
}
253

    
254
/*
255
 * offset and count are in bytes, but must be multiples of 512 for files
256
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
257
 *
258
 * This function may be called without alignment if the caller ensures
259
 * that O_DIRECT is not in effect.
260
 */
261
static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
262
                      const uint8_t *buf, int count)
263
{
264
    BDRVRawState *s = bs->opaque;
265
    int ret;
266

    
267
    ret = fd_open(bs);
268
    if (ret < 0)
269
        return -errno;
270

    
271
    if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
272
        ++(s->lseek_err_cnt);
273
        if(s->lseek_err_cnt) {
274
            DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
275
                              PRId64 "] lseek failed : %d = %s\n",
276
                              s->fd, bs->filename, offset, buf, count,
277
                              bs->total_sectors, errno, strerror(errno));
278
        }
279
        return -EIO;
280
    }
281
    s->lseek_err_cnt = 0;
282

    
283
    ret = write(s->fd, buf, count);
284
    if (ret == count)
285
        goto label__raw_write__success;
286

    
287
    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
288
                      "] write failed %d : %d = %s\n",
289
                      s->fd, bs->filename, offset, buf, count,
290
                      bs->total_sectors, ret, errno, strerror(errno));
291

    
292
label__raw_write__success:
293

    
294
    return  (ret < 0) ? -errno : ret;
295
}
296

    
297

    
298
/*
299
 * offset and count are in bytes and possibly not aligned. For files opened
300
 * with O_DIRECT, necessary alignments are ensured before calling
301
 * raw_pread_aligned to do the actual read.
302
 */
303
static int raw_pread(BlockDriverState *bs, int64_t offset,
304
                     uint8_t *buf, int count)
305
{
306
    BDRVRawState *s = bs->opaque;
307
    int size, ret, shift, sum;
308

    
309
    sum = 0;
310

    
311
    if (s->aligned_buf != NULL)  {
312

    
313
        if (offset & 0x1ff) {
314
            /* align offset on a 512 bytes boundary */
315

    
316
            shift = offset & 0x1ff;
317
            size = (shift + count + 0x1ff) & ~0x1ff;
318
            if (size > ALIGNED_BUFFER_SIZE)
319
                size = ALIGNED_BUFFER_SIZE;
320
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
321
            if (ret < 0)
322
                return ret;
323

    
324
            size = 512 - shift;
325
            if (size > count)
326
                size = count;
327
            memcpy(buf, s->aligned_buf + shift, size);
328

    
329
            buf += size;
330
            offset += size;
331
            count -= size;
332
            sum += size;
333

    
334
            if (count == 0)
335
                return sum;
336
        }
337
        if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
338

    
339
            /* read on aligned buffer */
340

    
341
            while (count) {
342

    
343
                size = (count + 0x1ff) & ~0x1ff;
344
                if (size > ALIGNED_BUFFER_SIZE)
345
                    size = ALIGNED_BUFFER_SIZE;
346

    
347
                ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
348
                if (ret < 0)
349
                    return ret;
350

    
351
                size = ret;
352
                if (size > count)
353
                    size = count;
354

    
355
                memcpy(buf, s->aligned_buf, size);
356

    
357
                buf += size;
358
                offset += size;
359
                count -= size;
360
                sum += size;
361
            }
362

    
363
            return sum;
364
        }
365
    }
366

    
367
    return raw_pread_aligned(bs, offset, buf, count) + sum;
368
}
369

    
370
static int raw_read(BlockDriverState *bs, int64_t sector_num,
371
                    uint8_t *buf, int nb_sectors)
372
{
373
    int ret;
374

    
375
    ret = raw_pread(bs, sector_num * 512, buf, nb_sectors * 512);
376
    if (ret == (nb_sectors * 512))
377
        ret = 0;
378
    return ret;
379
}
380

    
381
/*
382
 * offset and count are in bytes and possibly not aligned. For files opened
383
 * with O_DIRECT, necessary alignments are ensured before calling
384
 * raw_pwrite_aligned to do the actual write.
385
 */
386
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
387
                      const uint8_t *buf, int count)
388
{
389
    BDRVRawState *s = bs->opaque;
390
    int size, ret, shift, sum;
391

    
392
    sum = 0;
393

    
394
    if (s->aligned_buf != NULL) {
395

    
396
        if (offset & 0x1ff) {
397
            /* align offset on a 512 bytes boundary */
398
            shift = offset & 0x1ff;
399
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
400
            if (ret < 0)
401
                return ret;
402

    
403
            size = 512 - shift;
404
            if (size > count)
405
                size = count;
406
            memcpy(s->aligned_buf + shift, buf, size);
407

    
408
            ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
409
            if (ret < 0)
410
                return ret;
411

    
412
            buf += size;
413
            offset += size;
414
            count -= size;
415
            sum += size;
416

    
417
            if (count == 0)
418
                return sum;
419
        }
420
        if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
421

    
422
            while ((size = (count & ~0x1ff)) != 0) {
423

    
424
                if (size > ALIGNED_BUFFER_SIZE)
425
                    size = ALIGNED_BUFFER_SIZE;
426

    
427
                memcpy(s->aligned_buf, buf, size);
428

    
429
                ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
430
                if (ret < 0)
431
                    return ret;
432

    
433
                buf += ret;
434
                offset += ret;
435
                count -= ret;
436
                sum += ret;
437
            }
438
            /* here, count < 512 because (count & ~0x1ff) == 0 */
439
            if (count) {
440
                ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
441
                if (ret < 0)
442
                    return ret;
443
                 memcpy(s->aligned_buf, buf, count);
444

    
445
                 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
446
                 if (ret < 0)
447
                     return ret;
448
                 if (count < ret)
449
                     ret = count;
450

    
451
                 sum += ret;
452
            }
453
            return sum;
454
        }
455
    }
456
    return raw_pwrite_aligned(bs, offset, buf, count) + sum;
457
}
458

    
459
static int raw_write(BlockDriverState *bs, int64_t sector_num,
460
                     const uint8_t *buf, int nb_sectors)
461
{
462
    int ret;
463
    ret = raw_pwrite(bs, sector_num * 512, buf, nb_sectors * 512);
464
    if (ret == (nb_sectors * 512))
465
        ret = 0;
466
    return ret;
467
}
468

    
469
#ifdef CONFIG_AIO
470
/***********************************************************/
471
/* Unix AIO using POSIX AIO */
472

    
473
typedef struct RawAIOCB {
474
    BlockDriverAIOCB common;
475
    struct qemu_paiocb aiocb;
476
    struct RawAIOCB *next;
477
    int ret;
478
} RawAIOCB;
479

    
480
typedef struct PosixAioState
481
{
482
    int rfd, wfd;
483
    RawAIOCB *first_aio;
484
} PosixAioState;
485

    
486
static void posix_aio_read(void *opaque)
487
{
488
    PosixAioState *s = opaque;
489
    RawAIOCB *acb, **pacb;
490
    int ret;
491
    ssize_t len;
492

    
493
    /* read all bytes from signal pipe */
494
    for (;;) {
495
        char bytes[16];
496

    
497
        len = read(s->rfd, bytes, sizeof(bytes));
498
        if (len == -1 && errno == EINTR)
499
            continue; /* try again */
500
        if (len == sizeof(bytes))
501
            continue; /* more to read */
502
        break;
503
    }
504

    
505
    for(;;) {
506
        pacb = &s->first_aio;
507
        for(;;) {
508
            acb = *pacb;
509
            if (!acb)
510
                goto the_end;
511
            ret = qemu_paio_error(&acb->aiocb);
512
            if (ret == ECANCELED) {
513
                /* remove the request */
514
                *pacb = acb->next;
515
                qemu_aio_release(acb);
516
            } else if (ret != EINPROGRESS) {
517
                /* end of aio */
518
                if (ret == 0) {
519
                    ret = qemu_paio_return(&acb->aiocb);
520
                    if (ret == acb->aiocb.aio_nbytes)
521
                        ret = 0;
522
                    else
523
                        ret = -EINVAL;
524
                } else {
525
                    ret = -ret;
526
                }
527
                /* remove the request */
528
                *pacb = acb->next;
529
                /* call the callback */
530
                acb->common.cb(acb->common.opaque, ret);
531
                qemu_aio_release(acb);
532
                break;
533
            } else {
534
                pacb = &acb->next;
535
            }
536
        }
537
    }
538
 the_end: ;
539
}
540

    
541
static int posix_aio_flush(void *opaque)
542
{
543
    PosixAioState *s = opaque;
544
    return !!s->first_aio;
545
}
546

    
547
static PosixAioState *posix_aio_state;
548

    
549
static void aio_signal_handler(int signum)
550
{
551
    if (posix_aio_state) {
552
        char byte = 0;
553

    
554
        write(posix_aio_state->wfd, &byte, sizeof(byte));
555
    }
556

    
557
    qemu_service_io();
558
}
559

    
560
static int posix_aio_init(void)
561
{
562
    struct sigaction act;
563
    PosixAioState *s;
564
    int fds[2];
565
    struct qemu_paioinit ai;
566
  
567
    if (posix_aio_state)
568
        return 0;
569

    
570
    s = qemu_malloc(sizeof(PosixAioState));
571

    
572
    sigfillset(&act.sa_mask);
573
    act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
574
    act.sa_handler = aio_signal_handler;
575
    sigaction(SIGUSR2, &act, NULL);
576

    
577
    s->first_aio = NULL;
578
    if (pipe(fds) == -1) {
579
        fprintf(stderr, "failed to create pipe\n");
580
        return -errno;
581
    }
582

    
583
    s->rfd = fds[0];
584
    s->wfd = fds[1];
585

    
586
    fcntl(s->rfd, F_SETFL, O_NONBLOCK);
587
    fcntl(s->wfd, F_SETFL, O_NONBLOCK);
588

    
589
    qemu_aio_set_fd_handler(s->rfd, posix_aio_read, NULL, posix_aio_flush, s);
590

    
591
    memset(&ai, 0, sizeof(ai));
592
    ai.aio_threads = 64;
593
    ai.aio_num = 64;
594
    qemu_paio_init(&ai);
595

    
596
    posix_aio_state = s;
597

    
598
    return 0;
599
}
600

    
601
static RawAIOCB *raw_aio_setup(BlockDriverState *bs, int64_t sector_num,
602
        QEMUIOVector *qiov, int nb_sectors,
603
        BlockDriverCompletionFunc *cb, void *opaque)
604
{
605
    BDRVRawState *s = bs->opaque;
606
    RawAIOCB *acb;
607

    
608
    if (fd_open(bs) < 0)
609
        return NULL;
610

    
611
    acb = qemu_aio_get(bs, cb, opaque);
612
    if (!acb)
613
        return NULL;
614
    acb->aiocb.aio_fildes = s->fd;
615
    acb->aiocb.ev_signo = SIGUSR2;
616
    acb->aiocb.aio_iov = qiov->iov;
617
    acb->aiocb.aio_niov = qiov->niov;
618
    acb->aiocb.aio_nbytes = nb_sectors * 512;
619
    acb->aiocb.aio_offset = sector_num * 512;
620
    acb->aiocb.aio_flags = 0;
621

    
622
    /*
623
     * If O_DIRECT is used the buffer needs to be aligned on a sector
624
     * boundary. Tell the low level code to ensure that in case it's
625
     * not done yet.
626
     */
627
    if (s->aligned_buf)
628
        acb->aiocb.aio_flags |= QEMU_AIO_SECTOR_ALIGNED;
629

    
630
    acb->next = posix_aio_state->first_aio;
631
    posix_aio_state->first_aio = acb;
632
    return acb;
633
}
634

    
635
static void raw_aio_remove(RawAIOCB *acb)
636
{
637
    RawAIOCB **pacb;
638

    
639
    /* remove the callback from the queue */
640
    pacb = &posix_aio_state->first_aio;
641
    for(;;) {
642
        if (*pacb == NULL) {
643
            fprintf(stderr, "raw_aio_remove: aio request not found!\n");
644
            break;
645
        } else if (*pacb == acb) {
646
            *pacb = acb->next;
647
            qemu_aio_release(acb);
648
            break;
649
        }
650
        pacb = &(*pacb)->next;
651
    }
652
}
653

    
654
static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
655
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
656
        BlockDriverCompletionFunc *cb, void *opaque)
657
{
658
    RawAIOCB *acb;
659

    
660
    acb = raw_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque);
661
    if (!acb)
662
        return NULL;
663
    if (qemu_paio_read(&acb->aiocb) < 0) {
664
        raw_aio_remove(acb);
665
        return NULL;
666
    }
667
    return &acb->common;
668
}
669

    
670
static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
671
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
672
        BlockDriverCompletionFunc *cb, void *opaque)
673
{
674
    RawAIOCB *acb;
675

    
676
    acb = raw_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque);
677
    if (!acb)
678
        return NULL;
679
    if (qemu_paio_write(&acb->aiocb) < 0) {
680
        raw_aio_remove(acb);
681
        return NULL;
682
    }
683
    return &acb->common;
684
}
685

    
686
static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
687
{
688
    int ret;
689
    RawAIOCB *acb = (RawAIOCB *)blockacb;
690

    
691
    ret = qemu_paio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
692
    if (ret == QEMU_PAIO_NOTCANCELED) {
693
        /* fail safe: if the aio could not be canceled, we wait for
694
           it */
695
        while (qemu_paio_error(&acb->aiocb) == EINPROGRESS);
696
    }
697

    
698
    raw_aio_remove(acb);
699
}
700
#else /* CONFIG_AIO */
701
static int posix_aio_init(void)
702
{
703
    return 0;
704
}
705
#endif /* CONFIG_AIO */
706

    
707

    
708
static void raw_close(BlockDriverState *bs)
709
{
710
    BDRVRawState *s = bs->opaque;
711
    if (s->fd >= 0) {
712
        close(s->fd);
713
        s->fd = -1;
714
        if (s->aligned_buf != NULL)
715
            qemu_free(s->aligned_buf);
716
    }
717
}
718

    
719
static int raw_truncate(BlockDriverState *bs, int64_t offset)
720
{
721
    BDRVRawState *s = bs->opaque;
722
    if (s->type != FTYPE_FILE)
723
        return -ENOTSUP;
724
    if (ftruncate(s->fd, offset) < 0)
725
        return -errno;
726
    return 0;
727
}
728

    
729
#ifdef __OpenBSD__
730
static int64_t raw_getlength(BlockDriverState *bs)
731
{
732
    BDRVRawState *s = bs->opaque;
733
    int fd = s->fd;
734
    struct stat st;
735

    
736
    if (fstat(fd, &st))
737
        return -1;
738
    if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
739
        struct disklabel dl;
740

    
741
        if (ioctl(fd, DIOCGDINFO, &dl))
742
            return -1;
743
        return (uint64_t)dl.d_secsize *
744
            dl.d_partitions[DISKPART(st.st_rdev)].p_size;
745
    } else
746
        return st.st_size;
747
}
748
#else /* !__OpenBSD__ */
749
static int64_t  raw_getlength(BlockDriverState *bs)
750
{
751
    BDRVRawState *s = bs->opaque;
752
    int fd = s->fd;
753
    int64_t size;
754
#ifdef HOST_BSD
755
    struct stat sb;
756
#ifdef __FreeBSD__
757
    int reopened = 0;
758
#endif
759
#endif
760
#ifdef __sun__
761
    struct dk_minfo minfo;
762
    int rv;
763
#endif
764
    int ret;
765

    
766
    ret = fd_open(bs);
767
    if (ret < 0)
768
        return ret;
769

    
770
#ifdef HOST_BSD
771
#ifdef __FreeBSD__
772
again:
773
#endif
774
    if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
775
#ifdef DIOCGMEDIASIZE
776
        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
777
#elif defined(DIOCGPART)
778
        {
779
                struct partinfo pi;
780
                if (ioctl(fd, DIOCGPART, &pi) == 0)
781
                        size = pi.media_size;
782
                else
783
                        size = 0;
784
        }
785
        if (size == 0)
786
#endif
787
#ifdef CONFIG_COCOA
788
        size = LONG_LONG_MAX;
789
#else
790
        size = lseek(fd, 0LL, SEEK_END);
791
#endif
792
#ifdef __FreeBSD__
793
        switch(s->type) {
794
        case FTYPE_CD:
795
            /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
796
            if (size == 2048LL * (unsigned)-1)
797
                size = 0;
798
            /* XXX no disc?  maybe we need to reopen... */
799
            if (size <= 0 && !reopened && cd_open(bs) >= 0) {
800
                reopened = 1;
801
                goto again;
802
            }
803
        }
804
#endif
805
    } else
806
#endif
807
#ifdef __sun__
808
    /*
809
     * use the DKIOCGMEDIAINFO ioctl to read the size.
810
     */
811
    rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
812
    if ( rv != -1 ) {
813
        size = minfo.dki_lbsize * minfo.dki_capacity;
814
    } else /* there are reports that lseek on some devices
815
              fails, but irc discussion said that contingency
816
              on contingency was overkill */
817
#endif
818
    {
819
        size = lseek(fd, 0, SEEK_END);
820
    }
821
    return size;
822
}
823
#endif
824

    
825
static int raw_create(const char *filename, int64_t total_size,
826
                      const char *backing_file, int flags)
827
{
828
    int fd;
829

    
830
    if (flags || backing_file)
831
        return -ENOTSUP;
832

    
833
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
834
              0644);
835
    if (fd < 0)
836
        return -EIO;
837
    ftruncate(fd, total_size * 512);
838
    close(fd);
839
    return 0;
840
}
841

    
842
static void raw_flush(BlockDriverState *bs)
843
{
844
    BDRVRawState *s = bs->opaque;
845
    fsync(s->fd);
846
}
847

    
848
BlockDriver bdrv_raw = {
849
    .format_name = "raw",
850
    .instance_size = sizeof(BDRVRawState),
851
    .bdrv_probe = NULL, /* no probe for protocols */
852
    .bdrv_open = raw_open,
853
    .bdrv_read = raw_read,
854
    .bdrv_write = raw_write,
855
    .bdrv_close = raw_close,
856
    .bdrv_create = raw_create,
857
    .bdrv_flush = raw_flush,
858

    
859
#ifdef CONFIG_AIO
860
    .bdrv_aio_readv = raw_aio_readv,
861
    .bdrv_aio_writev = raw_aio_writev,
862
    .bdrv_aio_cancel = raw_aio_cancel,
863
    .aiocb_size = sizeof(RawAIOCB),
864
#endif
865

    
866
    .bdrv_truncate = raw_truncate,
867
    .bdrv_getlength = raw_getlength,
868
};
869

    
870
/***********************************************/
871
/* host device */
872

    
873
#ifdef CONFIG_COCOA
874
static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
875
static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
876

    
877
kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
878
{
879
    kern_return_t       kernResult;
880
    mach_port_t     masterPort;
881
    CFMutableDictionaryRef  classesToMatch;
882

    
883
    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
884
    if ( KERN_SUCCESS != kernResult ) {
885
        printf( "IOMasterPort returned %d\n", kernResult );
886
    }
887

    
888
    classesToMatch = IOServiceMatching( kIOCDMediaClass );
889
    if ( classesToMatch == NULL ) {
890
        printf( "IOServiceMatching returned a NULL dictionary.\n" );
891
    } else {
892
    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
893
    }
894
    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
895
    if ( KERN_SUCCESS != kernResult )
896
    {
897
        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
898
    }
899

    
900
    return kernResult;
901
}
902

    
903
kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
904
{
905
    io_object_t     nextMedia;
906
    kern_return_t   kernResult = KERN_FAILURE;
907
    *bsdPath = '\0';
908
    nextMedia = IOIteratorNext( mediaIterator );
909
    if ( nextMedia )
910
    {
911
        CFTypeRef   bsdPathAsCFString;
912
    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
913
        if ( bsdPathAsCFString ) {
914
            size_t devPathLength;
915
            strcpy( bsdPath, _PATH_DEV );
916
            strcat( bsdPath, "r" );
917
            devPathLength = strlen( bsdPath );
918
            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
919
                kernResult = KERN_SUCCESS;
920
            }
921
            CFRelease( bsdPathAsCFString );
922
        }
923
        IOObjectRelease( nextMedia );
924
    }
925

    
926
    return kernResult;
927
}
928

    
929
#endif
930

    
931
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
932
{
933
    BDRVRawState *s = bs->opaque;
934
    int fd, open_flags, ret;
935

    
936
    posix_aio_init();
937

    
938
#ifdef CONFIG_COCOA
939
    if (strstart(filename, "/dev/cdrom", NULL)) {
940
        kern_return_t kernResult;
941
        io_iterator_t mediaIterator;
942
        char bsdPath[ MAXPATHLEN ];
943
        int fd;
944

    
945
        kernResult = FindEjectableCDMedia( &mediaIterator );
946
        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
947

    
948
        if ( bsdPath[ 0 ] != '\0' ) {
949
            strcat(bsdPath,"s0");
950
            /* some CDs don't have a partition 0 */
951
            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
952
            if (fd < 0) {
953
                bsdPath[strlen(bsdPath)-1] = '1';
954
            } else {
955
                close(fd);
956
            }
957
            filename = bsdPath;
958
        }
959

    
960
        if ( mediaIterator )
961
            IOObjectRelease( mediaIterator );
962
    }
963
#endif
964
    open_flags = O_BINARY;
965
    if ((flags & BDRV_O_ACCESS) == O_RDWR) {
966
        open_flags |= O_RDWR;
967
    } else {
968
        open_flags |= O_RDONLY;
969
        bs->read_only = 1;
970
    }
971
    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
972
     * and O_DIRECT for no caching. */
973
    if ((flags & BDRV_O_NOCACHE))
974
        open_flags |= O_DIRECT;
975
    else if (!(flags & BDRV_O_CACHE_WB))
976
        open_flags |= O_DSYNC;
977

    
978
    s->type = FTYPE_FILE;
979
#if defined(__linux__)
980
    if (strstart(filename, "/dev/cd", NULL)) {
981
        /* open will not fail even if no CD is inserted */
982
        open_flags |= O_NONBLOCK;
983
        s->type = FTYPE_CD;
984
    } else if (strstart(filename, "/dev/fd", NULL)) {
985
        s->type = FTYPE_FD;
986
        s->fd_open_flags = open_flags;
987
        /* open will not fail even if no floppy is inserted */
988
        open_flags |= O_NONBLOCK;
989
#ifdef CONFIG_AIO
990
    } else if (strstart(filename, "/dev/sg", NULL)) {
991
        bs->sg = 1;
992
#endif
993
    }
994
#endif
995
#if defined(__FreeBSD__)
996
    if (strstart(filename, "/dev/cd", NULL) ||
997
        strstart(filename, "/dev/acd", NULL)) {
998
        s->type = FTYPE_CD;
999
        s->cd_open_flags = open_flags;
1000
    }
1001
#endif
1002
    s->fd = -1;
1003
    fd = open(filename, open_flags, 0644);
1004
    if (fd < 0) {
1005
        ret = -errno;
1006
        if (ret == -EROFS)
1007
            ret = -EACCES;
1008
        return ret;
1009
    }
1010
    s->fd = fd;
1011
#if defined(__FreeBSD__)
1012
    /* make sure the door isnt locked at this time */
1013
    if (s->type == FTYPE_CD)
1014
        ioctl (s->fd, CDIOCALLOW);
1015
#endif
1016
#if defined(__linux__)
1017
    /* close fd so that we can reopen it as needed */
1018
    if (s->type == FTYPE_FD) {
1019
        close(s->fd);
1020
        s->fd = -1;
1021
        s->fd_media_changed = 1;
1022
    }
1023
#endif
1024
    return 0;
1025
}
1026

    
1027
#if defined(__linux__)
1028
/* Note: we do not have a reliable method to detect if the floppy is
1029
   present. The current method is to try to open the floppy at every
1030
   I/O and to keep it opened during a few hundreds of ms. */
1031
static int fd_open(BlockDriverState *bs)
1032
{
1033
    BDRVRawState *s = bs->opaque;
1034
    int last_media_present;
1035

    
1036
    if (s->type != FTYPE_FD)
1037
        return 0;
1038
    last_media_present = (s->fd >= 0);
1039
    if (s->fd >= 0 &&
1040
        (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
1041
        close(s->fd);
1042
        s->fd = -1;
1043
#ifdef DEBUG_FLOPPY
1044
        printf("Floppy closed\n");
1045
#endif
1046
    }
1047
    if (s->fd < 0) {
1048
        if (s->fd_got_error &&
1049
            (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
1050
#ifdef DEBUG_FLOPPY
1051
            printf("No floppy (open delayed)\n");
1052
#endif
1053
            return -EIO;
1054
        }
1055
        s->fd = open(bs->filename, s->fd_open_flags);
1056
        if (s->fd < 0) {
1057
            s->fd_error_time = qemu_get_clock(rt_clock);
1058
            s->fd_got_error = 1;
1059
            if (last_media_present)
1060
                s->fd_media_changed = 1;
1061
#ifdef DEBUG_FLOPPY
1062
            printf("No floppy\n");
1063
#endif
1064
            return -EIO;
1065
        }
1066
#ifdef DEBUG_FLOPPY
1067
        printf("Floppy opened\n");
1068
#endif
1069
    }
1070
    if (!last_media_present)
1071
        s->fd_media_changed = 1;
1072
    s->fd_open_time = qemu_get_clock(rt_clock);
1073
    s->fd_got_error = 0;
1074
    return 0;
1075
}
1076

    
1077
static int raw_is_inserted(BlockDriverState *bs)
1078
{
1079
    BDRVRawState *s = bs->opaque;
1080
    int ret;
1081

    
1082
    switch(s->type) {
1083
    case FTYPE_CD:
1084
        ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1085
        if (ret == CDS_DISC_OK)
1086
            return 1;
1087
        else
1088
            return 0;
1089
        break;
1090
    case FTYPE_FD:
1091
        ret = fd_open(bs);
1092
        return (ret >= 0);
1093
    default:
1094
        return 1;
1095
    }
1096
}
1097

    
1098
/* currently only used by fdc.c, but a CD version would be good too */
1099
static int raw_media_changed(BlockDriverState *bs)
1100
{
1101
    BDRVRawState *s = bs->opaque;
1102

    
1103
    switch(s->type) {
1104
    case FTYPE_FD:
1105
        {
1106
            int ret;
1107
            /* XXX: we do not have a true media changed indication. It
1108
               does not work if the floppy is changed without trying
1109
               to read it */
1110
            fd_open(bs);
1111
            ret = s->fd_media_changed;
1112
            s->fd_media_changed = 0;
1113
#ifdef DEBUG_FLOPPY
1114
            printf("Floppy changed=%d\n", ret);
1115
#endif
1116
            return ret;
1117
        }
1118
    default:
1119
        return -ENOTSUP;
1120
    }
1121
}
1122

    
1123
static int raw_eject(BlockDriverState *bs, int eject_flag)
1124
{
1125
    BDRVRawState *s = bs->opaque;
1126

    
1127
    switch(s->type) {
1128
    case FTYPE_CD:
1129
        if (eject_flag) {
1130
            if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
1131
                perror("CDROMEJECT");
1132
        } else {
1133
            if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
1134
                perror("CDROMEJECT");
1135
        }
1136
        break;
1137
    case FTYPE_FD:
1138
        {
1139
            int fd;
1140
            if (s->fd >= 0) {
1141
                close(s->fd);
1142
                s->fd = -1;
1143
            }
1144
            fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
1145
            if (fd >= 0) {
1146
                if (ioctl(fd, FDEJECT, 0) < 0)
1147
                    perror("FDEJECT");
1148
                close(fd);
1149
            }
1150
        }
1151
        break;
1152
    default:
1153
        return -ENOTSUP;
1154
    }
1155
    return 0;
1156
}
1157

    
1158
static int raw_set_locked(BlockDriverState *bs, int locked)
1159
{
1160
    BDRVRawState *s = bs->opaque;
1161

    
1162
    switch(s->type) {
1163
    case FTYPE_CD:
1164
        if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
1165
            /* Note: an error can happen if the distribution automatically
1166
               mounts the CD-ROM */
1167
            //        perror("CDROM_LOCKDOOR");
1168
        }
1169
        break;
1170
    default:
1171
        return -ENOTSUP;
1172
    }
1173
    return 0;
1174
}
1175

    
1176
static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1177
{
1178
    BDRVRawState *s = bs->opaque;
1179

    
1180
    return ioctl(s->fd, req, buf);
1181
}
1182

    
1183
#ifdef CONFIG_AIO
1184
static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
1185
        unsigned long int req, void *buf,
1186
        BlockDriverCompletionFunc *cb, void *opaque)
1187
{
1188
    BDRVRawState *s = bs->opaque;
1189
    RawAIOCB *acb;
1190

    
1191
    if (fd_open(bs) < 0)
1192
        return NULL;
1193

    
1194
    acb = qemu_aio_get(bs, cb, opaque);
1195
    if (!acb)
1196
        return NULL;
1197
    acb->aiocb.aio_fildes = s->fd;
1198
    acb->aiocb.ev_signo = SIGUSR2;
1199
    acb->aiocb.aio_offset = 0;
1200
    acb->aiocb.aio_flags = 0;
1201

    
1202
    acb->next = posix_aio_state->first_aio;
1203
    posix_aio_state->first_aio = acb;
1204

    
1205
    acb->aiocb.aio_ioctl_buf = buf;
1206
    acb->aiocb.aio_ioctl_cmd = req;
1207
    if (qemu_paio_ioctl(&acb->aiocb) < 0) {
1208
        raw_aio_remove(acb);
1209
        return NULL;
1210
    }
1211

    
1212
    return &acb->common;
1213
}
1214
#endif
1215

    
1216
#elif defined(__FreeBSD__)
1217

    
1218
static int fd_open(BlockDriverState *bs)
1219
{
1220
    BDRVRawState *s = bs->opaque;
1221

    
1222
    /* this is just to ensure s->fd is sane (its called by io ops) */
1223
    if (s->fd >= 0)
1224
        return 0;
1225
    return -EIO;
1226
}
1227

    
1228
static int cd_open(BlockDriverState *bs)
1229
{
1230
#if defined(__FreeBSD__)
1231
    BDRVRawState *s = bs->opaque;
1232
    int fd;
1233

    
1234
    switch(s->type) {
1235
    case FTYPE_CD:
1236
        /* XXX force reread of possibly changed/newly loaded disc,
1237
         * FreeBSD seems to not notice sometimes... */
1238
        if (s->fd >= 0)
1239
            close (s->fd);
1240
        fd = open(bs->filename, s->cd_open_flags, 0644);
1241
        if (fd < 0) {
1242
            s->fd = -1;
1243
            return -EIO;
1244
        }
1245
        s->fd = fd;
1246
        /* make sure the door isnt locked at this time */
1247
        ioctl (s->fd, CDIOCALLOW);
1248
    }
1249
#endif
1250
    return 0;
1251
}
1252

    
1253
static int raw_is_inserted(BlockDriverState *bs)
1254
{
1255
    BDRVRawState *s = bs->opaque;
1256

    
1257
    switch(s->type) {
1258
    case FTYPE_CD:
1259
        return (raw_getlength(bs) > 0);
1260
    case FTYPE_FD:
1261
        /* XXX handle this */
1262
        /* FALLTHRU */
1263
    default:
1264
        return 1;
1265
    }
1266
}
1267

    
1268
static int raw_media_changed(BlockDriverState *bs)
1269
{
1270
    return -ENOTSUP;
1271
}
1272

    
1273
static int raw_eject(BlockDriverState *bs, int eject_flag)
1274
{
1275
    BDRVRawState *s = bs->opaque;
1276

    
1277
    switch(s->type) {
1278
    case FTYPE_CD:
1279
        if (s->fd < 0)
1280
            return -ENOTSUP;
1281
        (void) ioctl (s->fd, CDIOCALLOW);
1282
        if (eject_flag) {
1283
            if (ioctl (s->fd, CDIOCEJECT) < 0)
1284
                perror("CDIOCEJECT");
1285
        } else {
1286
            if (ioctl (s->fd, CDIOCCLOSE) < 0)
1287
                perror("CDIOCCLOSE");
1288
        }
1289
        if (cd_open(bs) < 0)
1290
            return -ENOTSUP;
1291
        break;
1292
    case FTYPE_FD:
1293
        /* XXX handle this */
1294
        /* FALLTHRU */
1295
    default:
1296
        return -ENOTSUP;
1297
    }
1298
    return 0;
1299
}
1300

    
1301
static int raw_set_locked(BlockDriverState *bs, int locked)
1302
{
1303
    BDRVRawState *s = bs->opaque;
1304

    
1305
    switch(s->type) {
1306
    case FTYPE_CD:
1307
        if (s->fd < 0)
1308
            return -ENOTSUP;
1309
        if (ioctl (s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1310
            /* Note: an error can happen if the distribution automatically
1311
               mounts the CD-ROM */
1312
            //        perror("CDROM_LOCKDOOR");
1313
        }
1314
        break;
1315
    default:
1316
        return -ENOTSUP;
1317
    }
1318
    return 0;
1319
}
1320

    
1321
static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1322
{
1323
    return -ENOTSUP;
1324
}
1325
#else /* !linux && !FreeBSD */
1326

    
1327
static int fd_open(BlockDriverState *bs)
1328
{
1329
    return 0;
1330
}
1331

    
1332
static int raw_is_inserted(BlockDriverState *bs)
1333
{
1334
    return 1;
1335
}
1336

    
1337
static int raw_media_changed(BlockDriverState *bs)
1338
{
1339
    return -ENOTSUP;
1340
}
1341

    
1342
static int raw_eject(BlockDriverState *bs, int eject_flag)
1343
{
1344
    return -ENOTSUP;
1345
}
1346

    
1347
static int raw_set_locked(BlockDriverState *bs, int locked)
1348
{
1349
    return -ENOTSUP;
1350
}
1351

    
1352
static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1353
{
1354
    return -ENOTSUP;
1355
}
1356

    
1357
static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
1358
        unsigned long int req, void *buf,
1359
        BlockDriverCompletionFunc *cb, void *opaque)
1360
{
1361
    return NULL;
1362
}
1363
#endif /* !linux && !FreeBSD */
1364

    
1365
#if defined(__linux__) || defined(__FreeBSD__)
1366
static int hdev_create(const char *filename, int64_t total_size,
1367
                       const char *backing_file, int flags)
1368
{
1369
    int fd;
1370
    int ret = 0;
1371
    struct stat stat_buf;
1372

    
1373
    if (flags || backing_file)
1374
        return -ENOTSUP;
1375

    
1376
    fd = open(filename, O_WRONLY | O_BINARY);
1377
    if (fd < 0)
1378
        return -EIO;
1379

    
1380
    if (fstat(fd, &stat_buf) < 0)
1381
        ret = -EIO;
1382
    else if (!S_ISBLK(stat_buf.st_mode))
1383
        ret = -EIO;
1384
    else if (lseek(fd, 0, SEEK_END) < total_size * 512)
1385
        ret = -ENOSPC;
1386

    
1387
    close(fd);
1388
    return ret;
1389
}
1390

    
1391
#else  /* !(linux || freebsd) */
1392

    
1393
static int hdev_create(const char *filename, int64_t total_size,
1394
                       const char *backing_file, int flags)
1395
{
1396
    return -ENOTSUP;
1397
}
1398
#endif
1399

    
1400
BlockDriver bdrv_host_device = {
1401
    .format_name        = "host_device",
1402
    .instance_size        = sizeof(BDRVRawState),
1403
    .bdrv_open                = hdev_open,
1404
    .bdrv_close                = raw_close,
1405
    .bdrv_create        = hdev_create,
1406
    .bdrv_flush                = raw_flush,
1407

    
1408
#ifdef CONFIG_AIO
1409
    .bdrv_aio_readv        = raw_aio_readv,
1410
    .bdrv_aio_writev        = raw_aio_writev,
1411
    .bdrv_aio_cancel        = raw_aio_cancel,
1412
    .aiocb_size                = sizeof(RawAIOCB),
1413
#endif
1414

    
1415
    .bdrv_read          = raw_read,
1416
    .bdrv_write         = raw_write,
1417
    .bdrv_getlength        = raw_getlength,
1418

    
1419
    /* removable device support */
1420
    .bdrv_is_inserted        = raw_is_inserted,
1421
    .bdrv_media_changed        = raw_media_changed,
1422
    .bdrv_eject                = raw_eject,
1423
    .bdrv_set_locked        = raw_set_locked,
1424
    /* generic scsi device */
1425
    .bdrv_ioctl                = raw_ioctl,
1426
#ifdef CONFIG_AIO
1427
    .bdrv_aio_ioctl        = raw_aio_ioctl,
1428
#endif
1429
};