Annotation of qemu/block-raw-posix.c, revision 1.1.1.2

1.1       root        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"
1.1.1.2 ! root       26: #include "qemu-char.h"
1.1       root       27: #include "block_int.h"
                     28: #include <assert.h>
1.1.1.2 ! root       29: #ifdef CONFIG_AIO
        !            30: #include "posix-aio-compat.h"
        !            31: #endif
1.1       root       32: 
                     33: #ifdef CONFIG_COCOA
                     34: #include <paths.h>
                     35: #include <sys/param.h>
                     36: #include <IOKit/IOKitLib.h>
                     37: #include <IOKit/IOBSD.h>
                     38: #include <IOKit/storage/IOMediaBSDClient.h>
                     39: #include <IOKit/storage/IOMedia.h>
                     40: #include <IOKit/storage/IOCDMedia.h>
                     41: //#include <IOKit/storage/IOCDTypes.h>
                     42: #include <CoreFoundation/CoreFoundation.h>
                     43: #endif
                     44: 
                     45: #ifdef __sun__
                     46: #define _POSIX_PTHREAD_SEMANTICS 1
                     47: #include <signal.h>
                     48: #include <sys/dkio.h>
                     49: #endif
                     50: #ifdef __linux__
                     51: #include <sys/ioctl.h>
                     52: #include <linux/cdrom.h>
                     53: #include <linux/fd.h>
                     54: #endif
                     55: #ifdef __FreeBSD__
1.1.1.2 ! root       56: #include <signal.h>
1.1       root       57: #include <sys/disk.h>
                     58: #endif
                     59: 
1.1.1.2 ! root       60: #ifdef __OpenBSD__
        !            61: #include <sys/ioctl.h>
        !            62: #include <sys/disklabel.h>
        !            63: #include <sys/dkio.h>
        !            64: #endif
        !            65: 
1.1       root       66: //#define DEBUG_FLOPPY
                     67: 
                     68: //#define DEBUG_BLOCK
1.1.1.2 ! root       69: #if defined(DEBUG_BLOCK)
        !            70: #define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (qemu_log_enabled())    \
        !            71:     { qemu_log(formatCstr, ##args); qemu_log_flush(); } } while (0)
1.1       root       72: #else
                     73: #define DEBUG_BLOCK_PRINT(formatCstr, args...)
                     74: #endif
                     75: 
1.1.1.2 ! root       76: /* OS X does not have O_DSYNC */
        !            77: #ifndef O_DSYNC
        !            78: #define O_DSYNC O_SYNC
        !            79: #endif
        !            80: 
        !            81: /* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
        !            82: #ifndef O_DIRECT
        !            83: #define O_DIRECT O_DSYNC
        !            84: #endif
        !            85: 
1.1       root       86: #define FTYPE_FILE   0
                     87: #define FTYPE_CD     1
                     88: #define FTYPE_FD     2
                     89: 
1.1.1.2 ! root       90: #define ALIGNED_BUFFER_SIZE (32 * 512)
        !            91: 
1.1       root       92: /* if the FD is not accessed during that time (in ms), we try to
                     93:    reopen it to see if the disk has been changed */
                     94: #define FD_OPEN_TIMEOUT 1000
                     95: 
                     96: typedef struct BDRVRawState {
                     97:     int fd;
                     98:     int type;
                     99:     unsigned int lseek_err_cnt;
                    100: #if defined(__linux__)
                    101:     /* linux floppy specific */
                    102:     int fd_open_flags;
                    103:     int64_t fd_open_time;
                    104:     int64_t fd_error_time;
                    105:     int fd_got_error;
                    106:     int fd_media_changed;
                    107: #endif
1.1.1.2 ! root      108:     uint8_t* aligned_buf;
1.1       root      109: } BDRVRawState;
                    110: 
1.1.1.2 ! root      111: static int posix_aio_init(void);
        !           112: 
1.1       root      113: static int fd_open(BlockDriverState *bs);
                    114: 
                    115: static int raw_open(BlockDriverState *bs, const char *filename, int flags)
                    116: {
                    117:     BDRVRawState *s = bs->opaque;
                    118:     int fd, open_flags, ret;
                    119: 
1.1.1.2 ! root      120:     posix_aio_init();
        !           121: 
1.1       root      122:     s->lseek_err_cnt = 0;
                    123: 
                    124:     open_flags = O_BINARY;
                    125:     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
                    126:         open_flags |= O_RDWR;
                    127:     } else {
                    128:         open_flags |= O_RDONLY;
                    129:         bs->read_only = 1;
                    130:     }
                    131:     if (flags & BDRV_O_CREAT)
                    132:         open_flags |= O_CREAT | O_TRUNC;
1.1.1.2 ! root      133: 
        !           134:     /* Use O_DSYNC for write-through caching, no flags for write-back caching,
        !           135:      * and O_DIRECT for no caching. */
        !           136:     if ((flags & BDRV_O_NOCACHE))
1.1       root      137:         open_flags |= O_DIRECT;
1.1.1.2 ! root      138:     else if (!(flags & BDRV_O_CACHE_WB))
        !           139:         open_flags |= O_DSYNC;
1.1       root      140: 
                    141:     s->type = FTYPE_FILE;
                    142: 
                    143:     fd = open(filename, open_flags, 0644);
                    144:     if (fd < 0) {
                    145:         ret = -errno;
                    146:         if (ret == -EROFS)
                    147:             ret = -EACCES;
                    148:         return ret;
                    149:     }
                    150:     s->fd = fd;
1.1.1.2 ! root      151:     s->aligned_buf = NULL;
        !           152:     if ((flags & BDRV_O_NOCACHE)) {
        !           153:         s->aligned_buf = qemu_memalign(512, ALIGNED_BUFFER_SIZE);
        !           154:         if (s->aligned_buf == NULL) {
        !           155:             ret = -errno;
        !           156:             close(fd);
        !           157:             return ret;
        !           158:         }
        !           159:     }
1.1       root      160:     return 0;
                    161: }
                    162: 
                    163: /* XXX: use host sector size if necessary with:
                    164: #ifdef DIOCGSECTORSIZE
                    165:         {
                    166:             unsigned int sectorsize = 512;
                    167:             if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
                    168:                 sectorsize > bufsize)
                    169:                 bufsize = sectorsize;
                    170:         }
                    171: #endif
                    172: #ifdef CONFIG_COCOA
                    173:         u_int32_t   blockSize = 512;
                    174:         if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
                    175:             bufsize = blockSize;
                    176:         }
                    177: #endif
                    178: */
                    179: 
1.1.1.2 ! root      180: /*
        !           181:  * offset and count are in bytes, but must be multiples of 512 for files
        !           182:  * opened with O_DIRECT. buf must be aligned to 512 bytes then.
        !           183:  *
        !           184:  * This function may be called without alignment if the caller ensures
        !           185:  * that O_DIRECT is not in effect.
        !           186:  */
        !           187: static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
1.1       root      188:                      uint8_t *buf, int count)
                    189: {
                    190:     BDRVRawState *s = bs->opaque;
                    191:     int ret;
                    192: 
                    193:     ret = fd_open(bs);
                    194:     if (ret < 0)
                    195:         return ret;
                    196: 
                    197:     if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
                    198:         ++(s->lseek_err_cnt);
                    199:         if(s->lseek_err_cnt <= 10) {
                    200:             DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                    201:                               "] lseek failed : %d = %s\n",
                    202:                               s->fd, bs->filename, offset, buf, count,
                    203:                               bs->total_sectors, errno, strerror(errno));
                    204:         }
                    205:         return -1;
                    206:     }
                    207:     s->lseek_err_cnt=0;
                    208: 
                    209:     ret = read(s->fd, buf, count);
                    210:     if (ret == count)
                    211:         goto label__raw_read__success;
                    212: 
                    213:     DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                    214:                       "] read failed %d : %d = %s\n",
                    215:                       s->fd, bs->filename, offset, buf, count,
                    216:                       bs->total_sectors, ret, errno, strerror(errno));
                    217: 
                    218:     /* Try harder for CDrom. */
                    219:     if (bs->type == BDRV_TYPE_CDROM) {
                    220:         lseek(s->fd, offset, SEEK_SET);
                    221:         ret = read(s->fd, buf, count);
                    222:         if (ret == count)
                    223:             goto label__raw_read__success;
                    224:         lseek(s->fd, offset, SEEK_SET);
                    225:         ret = read(s->fd, buf, count);
                    226:         if (ret == count)
                    227:             goto label__raw_read__success;
                    228: 
                    229:         DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                    230:                           "] retry read failed %d : %d = %s\n",
                    231:                           s->fd, bs->filename, offset, buf, count,
                    232:                           bs->total_sectors, ret, errno, strerror(errno));
                    233:     }
                    234: 
                    235: label__raw_read__success:
                    236: 
                    237:     return ret;
                    238: }
                    239: 
1.1.1.2 ! root      240: /*
        !           241:  * offset and count are in bytes, but must be multiples of 512 for files
        !           242:  * opened with O_DIRECT. buf must be aligned to 512 bytes then.
        !           243:  *
        !           244:  * This function may be called without alignment if the caller ensures
        !           245:  * that O_DIRECT is not in effect.
        !           246:  */
        !           247: static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
1.1       root      248:                       const uint8_t *buf, int count)
                    249: {
                    250:     BDRVRawState *s = bs->opaque;
                    251:     int ret;
                    252: 
                    253:     ret = fd_open(bs);
                    254:     if (ret < 0)
1.1.1.2 ! root      255:         return -errno;
1.1       root      256: 
                    257:     if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
                    258:         ++(s->lseek_err_cnt);
                    259:         if(s->lseek_err_cnt) {
                    260:             DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
                    261:                               PRId64 "] lseek failed : %d = %s\n",
                    262:                               s->fd, bs->filename, offset, buf, count,
                    263:                               bs->total_sectors, errno, strerror(errno));
                    264:         }
1.1.1.2 ! root      265:         return -EIO;
1.1       root      266:     }
                    267:     s->lseek_err_cnt = 0;
                    268: 
                    269:     ret = write(s->fd, buf, count);
                    270:     if (ret == count)
                    271:         goto label__raw_write__success;
                    272: 
                    273:     DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                    274:                       "] write failed %d : %d = %s\n",
                    275:                       s->fd, bs->filename, offset, buf, count,
                    276:                       bs->total_sectors, ret, errno, strerror(errno));
                    277: 
                    278: label__raw_write__success:
                    279: 
1.1.1.2 ! root      280:     return  (ret < 0) ? -errno : ret;
1.1       root      281: }
                    282: 
                    283: 
1.1.1.2 ! root      284: /*
        !           285:  * offset and count are in bytes and possibly not aligned. For files opened
        !           286:  * with O_DIRECT, necessary alignments are ensured before calling
        !           287:  * raw_pread_aligned to do the actual read.
        !           288:  */
        !           289: static int raw_pread(BlockDriverState *bs, int64_t offset,
        !           290:                      uint8_t *buf, int count)
        !           291: {
        !           292:     BDRVRawState *s = bs->opaque;
        !           293:     int size, ret, shift, sum;
1.1       root      294: 
1.1.1.2 ! root      295:     sum = 0;
1.1       root      296: 
1.1.1.2 ! root      297:     if (s->aligned_buf != NULL)  {
        !           298: 
        !           299:         if (offset & 0x1ff) {
        !           300:             /* align offset on a 512 bytes boundary */
        !           301: 
        !           302:             shift = offset & 0x1ff;
        !           303:             size = (shift + count + 0x1ff) & ~0x1ff;
        !           304:             if (size > ALIGNED_BUFFER_SIZE)
        !           305:                 size = ALIGNED_BUFFER_SIZE;
        !           306:             ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
        !           307:             if (ret < 0)
        !           308:                 return ret;
        !           309: 
        !           310:             size = 512 - shift;
        !           311:             if (size > count)
        !           312:                 size = count;
        !           313:             memcpy(buf, s->aligned_buf + shift, size);
        !           314: 
        !           315:             buf += size;
        !           316:             offset += size;
        !           317:             count -= size;
        !           318:             sum += size;
        !           319: 
        !           320:             if (count == 0)
        !           321:                 return sum;
        !           322:         }
        !           323:         if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
        !           324: 
        !           325:             /* read on aligned buffer */
        !           326: 
        !           327:             while (count) {
        !           328: 
        !           329:                 size = (count + 0x1ff) & ~0x1ff;
        !           330:                 if (size > ALIGNED_BUFFER_SIZE)
        !           331:                     size = ALIGNED_BUFFER_SIZE;
        !           332: 
        !           333:                 ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
        !           334:                 if (ret < 0)
        !           335:                     return ret;
        !           336: 
        !           337:                 size = ret;
        !           338:                 if (size > count)
        !           339:                     size = count;
        !           340: 
        !           341:                 memcpy(buf, s->aligned_buf, size);
        !           342: 
        !           343:                 buf += size;
        !           344:                 offset += size;
        !           345:                 count -= size;
        !           346:                 sum += size;
        !           347:             }
        !           348: 
        !           349:             return sum;
1.1       root      350:         }
                    351:     }
1.1.1.2 ! root      352: 
        !           353:     return raw_pread_aligned(bs, offset, buf, count) + sum;
1.1       root      354: }
                    355: 
1.1.1.2 ! root      356: /*
        !           357:  * offset and count are in bytes and possibly not aligned. For files opened
        !           358:  * with O_DIRECT, necessary alignments are ensured before calling
        !           359:  * raw_pwrite_aligned to do the actual write.
        !           360:  */
        !           361: static int raw_pwrite(BlockDriverState *bs, int64_t offset,
        !           362:                       const uint8_t *buf, int count)
1.1       root      363: {
1.1.1.2 ! root      364:     BDRVRawState *s = bs->opaque;
        !           365:     int size, ret, shift, sum;
1.1       root      366: 
1.1.1.2 ! root      367:     sum = 0;
1.1       root      368: 
1.1.1.2 ! root      369:     if (s->aligned_buf != NULL) {
1.1       root      370: 
1.1.1.2 ! root      371:         if (offset & 0x1ff) {
        !           372:             /* align offset on a 512 bytes boundary */
        !           373:             shift = offset & 0x1ff;
        !           374:             ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
        !           375:             if (ret < 0)
        !           376:                 return ret;
        !           377: 
        !           378:             size = 512 - shift;
        !           379:             if (size > count)
        !           380:                 size = count;
        !           381:             memcpy(s->aligned_buf + shift, buf, size);
        !           382: 
        !           383:             ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
        !           384:             if (ret < 0)
        !           385:                 return ret;
        !           386: 
        !           387:             buf += size;
        !           388:             offset += size;
        !           389:             count -= size;
        !           390:             sum += size;
        !           391: 
        !           392:             if (count == 0)
        !           393:                 return sum;
        !           394:         }
        !           395:         if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
        !           396: 
        !           397:             while ((size = (count & ~0x1ff)) != 0) {
        !           398: 
        !           399:                 if (size > ALIGNED_BUFFER_SIZE)
        !           400:                     size = ALIGNED_BUFFER_SIZE;
        !           401: 
        !           402:                 memcpy(s->aligned_buf, buf, size);
        !           403: 
        !           404:                 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
        !           405:                 if (ret < 0)
        !           406:                     return ret;
        !           407: 
        !           408:                 buf += ret;
        !           409:                 offset += ret;
        !           410:                 count -= ret;
        !           411:                 sum += ret;
        !           412:             }
        !           413:             /* here, count < 512 because (count & ~0x1ff) == 0 */
        !           414:             if (count) {
        !           415:                 ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
        !           416:                 if (ret < 0)
        !           417:                     return ret;
        !           418:                  memcpy(s->aligned_buf, buf, count);
        !           419: 
        !           420:                  ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
        !           421:                  if (ret < 0)
        !           422:                      return ret;
        !           423:                  if (count < ret)
        !           424:                      ret = count;
        !           425: 
        !           426:                  sum += ret;
        !           427:             }
        !           428:             return sum;
        !           429:         }
1.1       root      430:     }
1.1.1.2 ! root      431:     return raw_pwrite_aligned(bs, offset, buf, count) + sum;
1.1       root      432: }
                    433: 
1.1.1.2 ! root      434: #ifdef CONFIG_AIO
        !           435: /***********************************************************/
        !           436: /* Unix AIO using POSIX AIO */
        !           437: 
        !           438: typedef struct RawAIOCB {
        !           439:     BlockDriverAIOCB common;
        !           440:     struct qemu_paiocb aiocb;
        !           441:     struct RawAIOCB *next;
        !           442:     int ret;
        !           443: } RawAIOCB;
        !           444: 
        !           445: typedef struct PosixAioState
        !           446: {
        !           447:     int rfd, wfd;
        !           448:     RawAIOCB *first_aio;
        !           449: } PosixAioState;
        !           450: 
        !           451: static void posix_aio_read(void *opaque)
1.1       root      452: {
1.1.1.2 ! root      453:     PosixAioState *s = opaque;
1.1       root      454:     RawAIOCB *acb, **pacb;
                    455:     int ret;
1.1.1.2 ! root      456:     ssize_t len;
        !           457: 
        !           458:     /* read all bytes from signal pipe */
        !           459:     for (;;) {
        !           460:         char bytes[16];
        !           461: 
        !           462:         len = read(s->rfd, bytes, sizeof(bytes));
        !           463:         if (len == -1 && errno == EINTR)
        !           464:             continue; /* try again */
        !           465:         if (len == sizeof(bytes))
        !           466:             continue; /* more to read */
        !           467:         break;
        !           468:     }
1.1       root      469: 
                    470:     for(;;) {
1.1.1.2 ! root      471:         pacb = &s->first_aio;
1.1       root      472:         for(;;) {
                    473:             acb = *pacb;
                    474:             if (!acb)
                    475:                 goto the_end;
1.1.1.2 ! root      476:             ret = qemu_paio_error(&acb->aiocb);
1.1       root      477:             if (ret == ECANCELED) {
                    478:                 /* remove the request */
                    479:                 *pacb = acb->next;
                    480:                 qemu_aio_release(acb);
                    481:             } else if (ret != EINPROGRESS) {
                    482:                 /* end of aio */
                    483:                 if (ret == 0) {
1.1.1.2 ! root      484:                     ret = qemu_paio_return(&acb->aiocb);
1.1       root      485:                     if (ret == acb->aiocb.aio_nbytes)
                    486:                         ret = 0;
                    487:                     else
                    488:                         ret = -EINVAL;
                    489:                 } else {
                    490:                     ret = -ret;
                    491:                 }
                    492:                 /* remove the request */
                    493:                 *pacb = acb->next;
                    494:                 /* call the callback */
                    495:                 acb->common.cb(acb->common.opaque, ret);
                    496:                 qemu_aio_release(acb);
                    497:                 break;
                    498:             } else {
                    499:                 pacb = &acb->next;
                    500:             }
                    501:         }
                    502:     }
                    503:  the_end: ;
                    504: }
                    505: 
1.1.1.2 ! root      506: static int posix_aio_flush(void *opaque)
1.1       root      507: {
1.1.1.2 ! root      508:     PosixAioState *s = opaque;
        !           509:     return !!s->first_aio;
1.1       root      510: }
                    511: 
1.1.1.2 ! root      512: static PosixAioState *posix_aio_state;
1.1       root      513: 
1.1.1.2 ! root      514: static void aio_signal_handler(int signum)
1.1       root      515: {
1.1.1.2 ! root      516:     if (posix_aio_state) {
        !           517:         char byte = 0;
1.1       root      518: 
1.1.1.2 ! root      519:         write(posix_aio_state->wfd, &byte, sizeof(byte));
        !           520:     }
        !           521: 
        !           522:     qemu_service_io();
1.1       root      523: }
                    524: 
1.1.1.2 ! root      525: static int posix_aio_init(void)
1.1       root      526: {
1.1.1.2 ! root      527:     struct sigaction act;
        !           528:     PosixAioState *s;
        !           529:     int fds[2];
        !           530:     struct qemu_paioinit ai;
        !           531:   
        !           532:     if (posix_aio_state)
        !           533:         return 0;
1.1       root      534: 
1.1.1.2 ! root      535:     s = qemu_malloc(sizeof(PosixAioState));
1.1       root      536: 
1.1.1.2 ! root      537:     sigfillset(&act.sa_mask);
        !           538:     act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
        !           539:     act.sa_handler = aio_signal_handler;
        !           540:     sigaction(SIGUSR2, &act, NULL);
        !           541: 
        !           542:     s->first_aio = NULL;
        !           543:     if (pipe(fds) == -1) {
        !           544:         fprintf(stderr, "failed to create pipe\n");
        !           545:         return -errno;
        !           546:     }
        !           547: 
        !           548:     s->rfd = fds[0];
        !           549:     s->wfd = fds[1];
        !           550: 
        !           551:     fcntl(s->rfd, F_SETFL, O_NONBLOCK);
        !           552:     fcntl(s->wfd, F_SETFL, O_NONBLOCK);
        !           553: 
        !           554:     qemu_aio_set_fd_handler(s->rfd, posix_aio_read, NULL, posix_aio_flush, s);
        !           555: 
        !           556:     memset(&ai, 0, sizeof(ai));
        !           557:     ai.aio_threads = 64;
        !           558:     ai.aio_num = 64;
        !           559:     qemu_paio_init(&ai);
        !           560: 
        !           561:     posix_aio_state = s;
        !           562: 
        !           563:     return 0;
1.1       root      564: }
                    565: 
                    566: static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
                    567:         int64_t sector_num, uint8_t *buf, int nb_sectors,
                    568:         BlockDriverCompletionFunc *cb, void *opaque)
                    569: {
                    570:     BDRVRawState *s = bs->opaque;
                    571:     RawAIOCB *acb;
                    572: 
                    573:     if (fd_open(bs) < 0)
                    574:         return NULL;
                    575: 
                    576:     acb = qemu_aio_get(bs, cb, opaque);
                    577:     if (!acb)
                    578:         return NULL;
                    579:     acb->aiocb.aio_fildes = s->fd;
1.1.1.2 ! root      580:     acb->aiocb.ev_signo = SIGUSR2;
1.1       root      581:     acb->aiocb.aio_buf = buf;
                    582:     if (nb_sectors < 0)
                    583:         acb->aiocb.aio_nbytes = -nb_sectors;
                    584:     else
                    585:         acb->aiocb.aio_nbytes = nb_sectors * 512;
                    586:     acb->aiocb.aio_offset = sector_num * 512;
1.1.1.2 ! root      587:     acb->next = posix_aio_state->first_aio;
        !           588:     posix_aio_state->first_aio = acb;
1.1       root      589:     return acb;
                    590: }
                    591: 
1.1.1.2 ! root      592: static void raw_aio_em_cb(void* opaque)
        !           593: {
        !           594:     RawAIOCB *acb = opaque;
        !           595:     acb->common.cb(acb->common.opaque, acb->ret);
        !           596:     qemu_aio_release(acb);
        !           597: }
        !           598: 
        !           599: static void raw_aio_remove(RawAIOCB *acb)
        !           600: {
        !           601:     RawAIOCB **pacb;
        !           602: 
        !           603:     /* remove the callback from the queue */
        !           604:     pacb = &posix_aio_state->first_aio;
        !           605:     for(;;) {
        !           606:         if (*pacb == NULL) {
        !           607:             fprintf(stderr, "raw_aio_remove: aio request not found!\n");
        !           608:             break;
        !           609:         } else if (*pacb == acb) {
        !           610:             *pacb = acb->next;
        !           611:             qemu_aio_release(acb);
        !           612:             break;
        !           613:         }
        !           614:         pacb = &(*pacb)->next;
        !           615:     }
        !           616: }
        !           617: 
1.1       root      618: static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
                    619:         int64_t sector_num, uint8_t *buf, int nb_sectors,
                    620:         BlockDriverCompletionFunc *cb, void *opaque)
                    621: {
                    622:     RawAIOCB *acb;
                    623: 
1.1.1.2 ! root      624:     /*
        !           625:      * If O_DIRECT is used and the buffer is not aligned fall back
        !           626:      * to synchronous IO.
        !           627:      */
        !           628:     BDRVRawState *s = bs->opaque;
        !           629: 
        !           630:     if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
        !           631:         QEMUBH *bh;
        !           632:         acb = qemu_aio_get(bs, cb, opaque);
        !           633:         acb->ret = raw_pread(bs, 512 * sector_num, buf, 512 * nb_sectors);
        !           634:         bh = qemu_bh_new(raw_aio_em_cb, acb);
        !           635:         qemu_bh_schedule(bh);
        !           636:         return &acb->common;
        !           637:     }
        !           638: 
1.1       root      639:     acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
                    640:     if (!acb)
                    641:         return NULL;
1.1.1.2 ! root      642:     if (qemu_paio_read(&acb->aiocb) < 0) {
        !           643:         raw_aio_remove(acb);
1.1       root      644:         return NULL;
                    645:     }
                    646:     return &acb->common;
                    647: }
                    648: 
                    649: static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
                    650:         int64_t sector_num, const uint8_t *buf, int nb_sectors,
                    651:         BlockDriverCompletionFunc *cb, void *opaque)
                    652: {
                    653:     RawAIOCB *acb;
                    654: 
1.1.1.2 ! root      655:     /*
        !           656:      * If O_DIRECT is used and the buffer is not aligned fall back
        !           657:      * to synchronous IO.
        !           658:      */
        !           659:     BDRVRawState *s = bs->opaque;
        !           660: 
        !           661:     if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
        !           662:         QEMUBH *bh;
        !           663:         acb = qemu_aio_get(bs, cb, opaque);
        !           664:         acb->ret = raw_pwrite(bs, 512 * sector_num, buf, 512 * nb_sectors);
        !           665:         bh = qemu_bh_new(raw_aio_em_cb, acb);
        !           666:         qemu_bh_schedule(bh);
        !           667:         return &acb->common;
        !           668:     }
        !           669: 
1.1       root      670:     acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
                    671:     if (!acb)
                    672:         return NULL;
1.1.1.2 ! root      673:     if (qemu_paio_write(&acb->aiocb) < 0) {
        !           674:         raw_aio_remove(acb);
1.1       root      675:         return NULL;
                    676:     }
                    677:     return &acb->common;
                    678: }
                    679: 
                    680: static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
                    681: {
                    682:     int ret;
                    683:     RawAIOCB *acb = (RawAIOCB *)blockacb;
                    684: 
1.1.1.2 ! root      685:     ret = qemu_paio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
        !           686:     if (ret == QEMU_PAIO_NOTCANCELED) {
1.1       root      687:         /* fail safe: if the aio could not be canceled, we wait for
                    688:            it */
1.1.1.2 ! root      689:         while (qemu_paio_error(&acb->aiocb) == EINPROGRESS);
1.1       root      690:     }
                    691: 
1.1.1.2 ! root      692:     raw_aio_remove(acb);
1.1       root      693: }
1.1.1.2 ! root      694: #else /* CONFIG_AIO */
        !           695: static int posix_aio_init(void)
        !           696: {
        !           697:     return 0;
        !           698: }
        !           699: #endif /* CONFIG_AIO */
        !           700: 
1.1       root      701: 
                    702: static void raw_close(BlockDriverState *bs)
                    703: {
                    704:     BDRVRawState *s = bs->opaque;
                    705:     if (s->fd >= 0) {
                    706:         close(s->fd);
                    707:         s->fd = -1;
1.1.1.2 ! root      708:         if (s->aligned_buf != NULL)
        !           709:             qemu_free(s->aligned_buf);
1.1       root      710:     }
                    711: }
                    712: 
                    713: static int raw_truncate(BlockDriverState *bs, int64_t offset)
                    714: {
                    715:     BDRVRawState *s = bs->opaque;
                    716:     if (s->type != FTYPE_FILE)
                    717:         return -ENOTSUP;
                    718:     if (ftruncate(s->fd, offset) < 0)
                    719:         return -errno;
                    720:     return 0;
                    721: }
                    722: 
1.1.1.2 ! root      723: #ifdef __OpenBSD__
        !           724: static int64_t raw_getlength(BlockDriverState *bs)
        !           725: {
        !           726:     BDRVRawState *s = bs->opaque;
        !           727:     int fd = s->fd;
        !           728:     struct stat st;
        !           729: 
        !           730:     if (fstat(fd, &st))
        !           731:         return -1;
        !           732:     if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
        !           733:         struct disklabel dl;
        !           734: 
        !           735:         if (ioctl(fd, DIOCGDINFO, &dl))
        !           736:             return -1;
        !           737:         return (uint64_t)dl.d_secsize *
        !           738:             dl.d_partitions[DISKPART(st.st_rdev)].p_size;
        !           739:     } else
        !           740:         return st.st_size;
        !           741: }
        !           742: #else /* !__OpenBSD__ */
1.1       root      743: static int64_t  raw_getlength(BlockDriverState *bs)
                    744: {
                    745:     BDRVRawState *s = bs->opaque;
                    746:     int fd = s->fd;
                    747:     int64_t size;
                    748: #ifdef _BSD
                    749:     struct stat sb;
                    750: #endif
                    751: #ifdef __sun__
                    752:     struct dk_minfo minfo;
                    753:     int rv;
                    754: #endif
                    755:     int ret;
                    756: 
                    757:     ret = fd_open(bs);
                    758:     if (ret < 0)
                    759:         return ret;
                    760: 
                    761: #ifdef _BSD
                    762:     if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
                    763: #ifdef DIOCGMEDIASIZE
                    764:        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
                    765: #endif
                    766: #ifdef CONFIG_COCOA
                    767:         size = LONG_LONG_MAX;
                    768: #else
                    769:         size = lseek(fd, 0LL, SEEK_END);
                    770: #endif
                    771:     } else
                    772: #endif
                    773: #ifdef __sun__
                    774:     /*
                    775:      * use the DKIOCGMEDIAINFO ioctl to read the size.
                    776:      */
                    777:     rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
                    778:     if ( rv != -1 ) {
                    779:         size = minfo.dki_lbsize * minfo.dki_capacity;
                    780:     } else /* there are reports that lseek on some devices
                    781:               fails, but irc discussion said that contingency
                    782:               on contingency was overkill */
                    783: #endif
                    784:     {
                    785:         size = lseek(fd, 0, SEEK_END);
                    786:     }
                    787:     return size;
                    788: }
1.1.1.2 ! root      789: #endif
1.1       root      790: 
                    791: static int raw_create(const char *filename, int64_t total_size,
                    792:                       const char *backing_file, int flags)
                    793: {
                    794:     int fd;
                    795: 
                    796:     if (flags || backing_file)
                    797:         return -ENOTSUP;
                    798: 
                    799:     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
                    800:               0644);
                    801:     if (fd < 0)
                    802:         return -EIO;
                    803:     ftruncate(fd, total_size * 512);
                    804:     close(fd);
                    805:     return 0;
                    806: }
                    807: 
                    808: static void raw_flush(BlockDriverState *bs)
                    809: {
                    810:     BDRVRawState *s = bs->opaque;
                    811:     fsync(s->fd);
                    812: }
                    813: 
                    814: BlockDriver bdrv_raw = {
                    815:     "raw",
                    816:     sizeof(BDRVRawState),
                    817:     NULL, /* no probe for protocols */
                    818:     raw_open,
                    819:     NULL,
                    820:     NULL,
                    821:     raw_close,
                    822:     raw_create,
                    823:     raw_flush,
                    824: 
1.1.1.2 ! root      825: #ifdef CONFIG_AIO
1.1       root      826:     .bdrv_aio_read = raw_aio_read,
                    827:     .bdrv_aio_write = raw_aio_write,
                    828:     .bdrv_aio_cancel = raw_aio_cancel,
                    829:     .aiocb_size = sizeof(RawAIOCB),
1.1.1.2 ! root      830: #endif
        !           831: 
1.1       root      832:     .bdrv_pread = raw_pread,
                    833:     .bdrv_pwrite = raw_pwrite,
                    834:     .bdrv_truncate = raw_truncate,
                    835:     .bdrv_getlength = raw_getlength,
                    836: };
                    837: 
                    838: /***********************************************/
                    839: /* host device */
                    840: 
                    841: #ifdef CONFIG_COCOA
                    842: static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
                    843: static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
                    844: 
                    845: kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
                    846: {
                    847:     kern_return_t       kernResult;
                    848:     mach_port_t     masterPort;
                    849:     CFMutableDictionaryRef  classesToMatch;
                    850: 
                    851:     kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
                    852:     if ( KERN_SUCCESS != kernResult ) {
                    853:         printf( "IOMasterPort returned %d\n", kernResult );
                    854:     }
                    855: 
                    856:     classesToMatch = IOServiceMatching( kIOCDMediaClass );
                    857:     if ( classesToMatch == NULL ) {
                    858:         printf( "IOServiceMatching returned a NULL dictionary.\n" );
                    859:     } else {
                    860:     CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
                    861:     }
                    862:     kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
                    863:     if ( KERN_SUCCESS != kernResult )
                    864:     {
                    865:         printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
                    866:     }
                    867: 
                    868:     return kernResult;
                    869: }
                    870: 
                    871: kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
                    872: {
                    873:     io_object_t     nextMedia;
                    874:     kern_return_t   kernResult = KERN_FAILURE;
                    875:     *bsdPath = '\0';
                    876:     nextMedia = IOIteratorNext( mediaIterator );
                    877:     if ( nextMedia )
                    878:     {
                    879:         CFTypeRef   bsdPathAsCFString;
                    880:     bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
                    881:         if ( bsdPathAsCFString ) {
                    882:             size_t devPathLength;
                    883:             strcpy( bsdPath, _PATH_DEV );
                    884:             strcat( bsdPath, "r" );
                    885:             devPathLength = strlen( bsdPath );
                    886:             if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
                    887:                 kernResult = KERN_SUCCESS;
                    888:             }
                    889:             CFRelease( bsdPathAsCFString );
                    890:         }
                    891:         IOObjectRelease( nextMedia );
                    892:     }
                    893: 
                    894:     return kernResult;
                    895: }
                    896: 
                    897: #endif
                    898: 
                    899: static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
                    900: {
                    901:     BDRVRawState *s = bs->opaque;
                    902:     int fd, open_flags, ret;
                    903: 
1.1.1.2 ! root      904:     posix_aio_init();
        !           905: 
1.1       root      906: #ifdef CONFIG_COCOA
                    907:     if (strstart(filename, "/dev/cdrom", NULL)) {
                    908:         kern_return_t kernResult;
                    909:         io_iterator_t mediaIterator;
                    910:         char bsdPath[ MAXPATHLEN ];
                    911:         int fd;
                    912: 
                    913:         kernResult = FindEjectableCDMedia( &mediaIterator );
                    914:         kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
                    915: 
                    916:         if ( bsdPath[ 0 ] != '\0' ) {
                    917:             strcat(bsdPath,"s0");
                    918:             /* some CDs don't have a partition 0 */
                    919:             fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
                    920:             if (fd < 0) {
                    921:                 bsdPath[strlen(bsdPath)-1] = '1';
                    922:             } else {
                    923:                 close(fd);
                    924:             }
                    925:             filename = bsdPath;
                    926:         }
                    927: 
                    928:         if ( mediaIterator )
                    929:             IOObjectRelease( mediaIterator );
                    930:     }
                    931: #endif
                    932:     open_flags = O_BINARY;
                    933:     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
                    934:         open_flags |= O_RDWR;
                    935:     } else {
                    936:         open_flags |= O_RDONLY;
                    937:         bs->read_only = 1;
                    938:     }
1.1.1.2 ! root      939:     /* Use O_DSYNC for write-through caching, no flags for write-back caching,
        !           940:      * and O_DIRECT for no caching. */
        !           941:     if ((flags & BDRV_O_NOCACHE))
1.1       root      942:         open_flags |= O_DIRECT;
1.1.1.2 ! root      943:     else if (!(flags & BDRV_O_CACHE_WB))
        !           944:         open_flags |= O_DSYNC;
1.1       root      945: 
                    946:     s->type = FTYPE_FILE;
                    947: #if defined(__linux__)
                    948:     if (strstart(filename, "/dev/cd", NULL)) {
                    949:         /* open will not fail even if no CD is inserted */
                    950:         open_flags |= O_NONBLOCK;
                    951:         s->type = FTYPE_CD;
                    952:     } else if (strstart(filename, "/dev/fd", NULL)) {
                    953:         s->type = FTYPE_FD;
                    954:         s->fd_open_flags = open_flags;
                    955:         /* open will not fail even if no floppy is inserted */
                    956:         open_flags |= O_NONBLOCK;
                    957:     } else if (strstart(filename, "/dev/sg", NULL)) {
                    958:         bs->sg = 1;
                    959:     }
                    960: #endif
                    961:     fd = open(filename, open_flags, 0644);
                    962:     if (fd < 0) {
                    963:         ret = -errno;
                    964:         if (ret == -EROFS)
                    965:             ret = -EACCES;
                    966:         return ret;
                    967:     }
                    968:     s->fd = fd;
                    969: #if defined(__linux__)
                    970:     /* close fd so that we can reopen it as needed */
                    971:     if (s->type == FTYPE_FD) {
                    972:         close(s->fd);
                    973:         s->fd = -1;
                    974:         s->fd_media_changed = 1;
                    975:     }
                    976: #endif
                    977:     return 0;
                    978: }
                    979: 
1.1.1.2 ! root      980: #if defined(__linux__)
1.1       root      981: /* Note: we do not have a reliable method to detect if the floppy is
                    982:    present. The current method is to try to open the floppy at every
                    983:    I/O and to keep it opened during a few hundreds of ms. */
                    984: static int fd_open(BlockDriverState *bs)
                    985: {
                    986:     BDRVRawState *s = bs->opaque;
                    987:     int last_media_present;
                    988: 
                    989:     if (s->type != FTYPE_FD)
                    990:         return 0;
                    991:     last_media_present = (s->fd >= 0);
                    992:     if (s->fd >= 0 &&
                    993:         (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
                    994:         close(s->fd);
                    995:         s->fd = -1;
                    996: #ifdef DEBUG_FLOPPY
                    997:         printf("Floppy closed\n");
                    998: #endif
                    999:     }
                   1000:     if (s->fd < 0) {
                   1001:         if (s->fd_got_error &&
                   1002:             (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
                   1003: #ifdef DEBUG_FLOPPY
                   1004:             printf("No floppy (open delayed)\n");
                   1005: #endif
                   1006:             return -EIO;
                   1007:         }
                   1008:         s->fd = open(bs->filename, s->fd_open_flags);
                   1009:         if (s->fd < 0) {
                   1010:             s->fd_error_time = qemu_get_clock(rt_clock);
                   1011:             s->fd_got_error = 1;
                   1012:             if (last_media_present)
                   1013:                 s->fd_media_changed = 1;
                   1014: #ifdef DEBUG_FLOPPY
                   1015:             printf("No floppy\n");
                   1016: #endif
                   1017:             return -EIO;
                   1018:         }
                   1019: #ifdef DEBUG_FLOPPY
                   1020:         printf("Floppy opened\n");
                   1021: #endif
                   1022:     }
                   1023:     if (!last_media_present)
                   1024:         s->fd_media_changed = 1;
                   1025:     s->fd_open_time = qemu_get_clock(rt_clock);
                   1026:     s->fd_got_error = 0;
                   1027:     return 0;
                   1028: }
                   1029: 
                   1030: static int raw_is_inserted(BlockDriverState *bs)
                   1031: {
                   1032:     BDRVRawState *s = bs->opaque;
                   1033:     int ret;
                   1034: 
                   1035:     switch(s->type) {
                   1036:     case FTYPE_CD:
                   1037:         ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
                   1038:         if (ret == CDS_DISC_OK)
                   1039:             return 1;
                   1040:         else
                   1041:             return 0;
                   1042:         break;
                   1043:     case FTYPE_FD:
                   1044:         ret = fd_open(bs);
                   1045:         return (ret >= 0);
                   1046:     default:
                   1047:         return 1;
                   1048:     }
                   1049: }
                   1050: 
                   1051: /* currently only used by fdc.c, but a CD version would be good too */
                   1052: static int raw_media_changed(BlockDriverState *bs)
                   1053: {
                   1054:     BDRVRawState *s = bs->opaque;
                   1055: 
                   1056:     switch(s->type) {
                   1057:     case FTYPE_FD:
                   1058:         {
                   1059:             int ret;
                   1060:             /* XXX: we do not have a true media changed indication. It
                   1061:                does not work if the floppy is changed without trying
                   1062:                to read it */
                   1063:             fd_open(bs);
                   1064:             ret = s->fd_media_changed;
                   1065:             s->fd_media_changed = 0;
                   1066: #ifdef DEBUG_FLOPPY
                   1067:             printf("Floppy changed=%d\n", ret);
                   1068: #endif
                   1069:             return ret;
                   1070:         }
                   1071:     default:
                   1072:         return -ENOTSUP;
                   1073:     }
                   1074: }
                   1075: 
                   1076: static int raw_eject(BlockDriverState *bs, int eject_flag)
                   1077: {
                   1078:     BDRVRawState *s = bs->opaque;
                   1079: 
                   1080:     switch(s->type) {
                   1081:     case FTYPE_CD:
                   1082:         if (eject_flag) {
                   1083:             if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
                   1084:                 perror("CDROMEJECT");
                   1085:         } else {
                   1086:             if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
                   1087:                 perror("CDROMEJECT");
                   1088:         }
                   1089:         break;
                   1090:     case FTYPE_FD:
                   1091:         {
                   1092:             int fd;
                   1093:             if (s->fd >= 0) {
                   1094:                 close(s->fd);
                   1095:                 s->fd = -1;
                   1096:             }
                   1097:             fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
                   1098:             if (fd >= 0) {
                   1099:                 if (ioctl(fd, FDEJECT, 0) < 0)
                   1100:                     perror("FDEJECT");
                   1101:                 close(fd);
                   1102:             }
                   1103:         }
                   1104:         break;
                   1105:     default:
                   1106:         return -ENOTSUP;
                   1107:     }
                   1108:     return 0;
                   1109: }
                   1110: 
                   1111: static int raw_set_locked(BlockDriverState *bs, int locked)
                   1112: {
                   1113:     BDRVRawState *s = bs->opaque;
                   1114: 
                   1115:     switch(s->type) {
                   1116:     case FTYPE_CD:
                   1117:         if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
                   1118:             /* Note: an error can happen if the distribution automatically
                   1119:                mounts the CD-ROM */
                   1120:             //        perror("CDROM_LOCKDOOR");
                   1121:         }
                   1122:         break;
                   1123:     default:
                   1124:         return -ENOTSUP;
                   1125:     }
                   1126:     return 0;
                   1127: }
                   1128: 
                   1129: static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
                   1130: {
                   1131:     BDRVRawState *s = bs->opaque;
                   1132: 
                   1133:     return ioctl(s->fd, req, buf);
                   1134: }
                   1135: #else
                   1136: 
1.1.1.2 ! root     1137: static int fd_open(BlockDriverState *bs)
        !          1138: {
        !          1139:     return 0;
        !          1140: }
        !          1141: 
1.1       root     1142: static int raw_is_inserted(BlockDriverState *bs)
                   1143: {
                   1144:     return 1;
                   1145: }
                   1146: 
                   1147: static int raw_media_changed(BlockDriverState *bs)
                   1148: {
                   1149:     return -ENOTSUP;
                   1150: }
                   1151: 
                   1152: static int raw_eject(BlockDriverState *bs, int eject_flag)
                   1153: {
                   1154:     return -ENOTSUP;
                   1155: }
                   1156: 
                   1157: static int raw_set_locked(BlockDriverState *bs, int locked)
                   1158: {
                   1159:     return -ENOTSUP;
                   1160: }
                   1161: 
                   1162: static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
                   1163: {
                   1164:     return -ENOTSUP;
                   1165: }
                   1166: #endif /* !linux */
                   1167: 
                   1168: BlockDriver bdrv_host_device = {
                   1169:     "host_device",
                   1170:     sizeof(BDRVRawState),
                   1171:     NULL, /* no probe for protocols */
                   1172:     hdev_open,
                   1173:     NULL,
                   1174:     NULL,
                   1175:     raw_close,
                   1176:     NULL,
                   1177:     raw_flush,
                   1178: 
1.1.1.2 ! root     1179: #ifdef CONFIG_AIO
1.1       root     1180:     .bdrv_aio_read = raw_aio_read,
                   1181:     .bdrv_aio_write = raw_aio_write,
                   1182:     .bdrv_aio_cancel = raw_aio_cancel,
                   1183:     .aiocb_size = sizeof(RawAIOCB),
1.1.1.2 ! root     1184: #endif
        !          1185: 
1.1       root     1186:     .bdrv_pread = raw_pread,
                   1187:     .bdrv_pwrite = raw_pwrite,
                   1188:     .bdrv_getlength = raw_getlength,
                   1189: 
                   1190:     /* removable device support */
                   1191:     .bdrv_is_inserted = raw_is_inserted,
                   1192:     .bdrv_media_changed = raw_media_changed,
                   1193:     .bdrv_eject = raw_eject,
                   1194:     .bdrv_set_locked = raw_set_locked,
                   1195:     /* generic scsi device */
                   1196:     .bdrv_ioctl = raw_ioctl,
                   1197: };

unix.superglobalmegacorp.com