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

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.