Break up vl.h.
[qemu] / block-raw.c
index e9e5027..732b4b8 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Block driver for RAW files
- * 
+ *
  * Copyright (c) 2006 Fabrice Bellard
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "vl.h"
+#include "qemu-common.h"
+#ifndef QEMU_IMG
+#include "qemu-timer.h"
+#include "exec-all.h"
+#endif
 #include "block_int.h"
 #include <assert.h>
 #ifndef _WIN32
 #include <aio.h>
 
-#ifndef QEMU_TOOL
-#include "exec-all.h"
-#endif
-
 #ifdef CONFIG_COCOA
 #include <paths.h>
 #include <sys/param.h>
 
 //#define DEBUG_FLOPPY
 
+//#define DEBUG_BLOCK
+#if defined(DEBUG_BLOCK) && !defined(QEMU_IMG)
+#define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0) \
+    { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0)
+#else
+#define DEBUG_BLOCK_PRINT(formatCstr, args...)
+#endif
+
 #define FTYPE_FILE   0
 #define FTYPE_CD     1
 #define FTYPE_FD     2
@@ -70,6 +78,7 @@
 typedef struct BDRVRawState {
     int fd;
     int type;
+    unsigned int lseek_err_cnt;
 #if defined(__linux__)
     /* linux floppy specific */
     int fd_open_flags;
@@ -87,6 +96,8 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
     BDRVRawState *s = bs->opaque;
     int fd, open_flags, ret;
 
+    s->lseek_err_cnt = 0;
+
     open_flags = O_BINARY;
     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
         open_flags |= O_RDWR;
@@ -127,33 +138,92 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
 #endif
 */
 
-static int raw_pread(BlockDriverState *bs, int64_t offset, 
+static int raw_pread(BlockDriverState *bs, int64_t offset,
                      uint8_t *buf, int count)
 {
     BDRVRawState *s = bs->opaque;
     int ret;
-    
+
     ret = fd_open(bs);
     if (ret < 0)
         return ret;
 
-    lseek(s->fd, offset, SEEK_SET);
+    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
+        ++(s->lseek_err_cnt);
+        if(s->lseek_err_cnt <= 10) {
+            DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                              "] lseek failed : %d = %s\n",
+                              s->fd, bs->filename, offset, buf, count,
+                              bs->total_sectors, errno, strerror(errno));
+        }
+        return -1;
+    }
+    s->lseek_err_cnt=0;
+
     ret = read(s->fd, buf, count);
+    if (ret == count)
+        goto label__raw_read__success;
+
+    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                      "] read failed %d : %d = %s\n",
+                      s->fd, bs->filename, offset, buf, count,
+                      bs->total_sectors, ret, errno, strerror(errno));
+
+    /* Try harder for CDrom. */
+    if (bs->type == BDRV_TYPE_CDROM) {
+        lseek(s->fd, offset, SEEK_SET);
+        ret = read(s->fd, buf, count);
+        if (ret == count)
+            goto label__raw_read__success;
+        lseek(s->fd, offset, SEEK_SET);
+        ret = read(s->fd, buf, count);
+        if (ret == count)
+            goto label__raw_read__success;
+
+        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                          "] retry read failed %d : %d = %s\n",
+                          s->fd, bs->filename, offset, buf, count,
+                          bs->total_sectors, ret, errno, strerror(errno));
+    }
+
+label__raw_read__success:
+
     return ret;
 }
 
-static int raw_pwrite(BlockDriverState *bs, int64_t offset, 
+static int raw_pwrite(BlockDriverState *bs, int64_t offset,
                       const uint8_t *buf, int count)
 {
     BDRVRawState *s = bs->opaque;
     int ret;
-    
+
     ret = fd_open(bs);
     if (ret < 0)
         return ret;
 
-    lseek(s->fd, offset, SEEK_SET);
+    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
+        ++(s->lseek_err_cnt);
+        if(s->lseek_err_cnt) {
+            DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
+                              PRId64 "] lseek failed : %d = %s\n",
+                              s->fd, bs->filename, offset, buf, count,
+                              bs->total_sectors, errno, strerror(errno));
+        }
+        return -1;
+    }
+    s->lseek_err_cnt = 0;
+
     ret = write(s->fd, buf, count);
+    if (ret == count)
+        goto label__raw_write__success;
+
+    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
+                      "] write failed %d : %d = %s\n",
+                      s->fd, bs->filename, offset, buf, count,
+                      bs->total_sectors, ret, errno, strerror(errno));
+
+label__raw_write__success:
+
     return ret;
 }
 
@@ -172,7 +242,7 @@ static int aio_initialized = 0;
 
 static void aio_signal_handler(int signum)
 {
-#ifndef QEMU_TOOL
+#ifndef QEMU_IMG
     CPUState *env = cpu_single_env;
     if (env) {
         /* stop the currently executing cpu because a timer occured */
@@ -191,7 +261,7 @@ void qemu_aio_init(void)
     struct sigaction act;
 
     aio_initialized = 1;
-    
+
     sigfillset(&act.sa_mask);
     act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
     act.sa_handler = aio_signal_handler;
@@ -282,7 +352,7 @@ void qemu_aio_wait(void)
     sigset_t set;
     int nb_sigs;
 
-#ifndef QEMU_TOOL
+#ifndef QEMU_IMG
     if (qemu_bh_poll())
         return;
 #endif
@@ -333,7 +403,7 @@ static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
     if (aio_read(&acb->aiocb) < 0) {
         qemu_aio_release(acb);
         return NULL;
-    } 
+    }
     return &acb->common;
 }
 
@@ -349,7 +419,7 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
     if (aio_write(&acb->aiocb) < 0) {
         qemu_aio_release(acb);
         return NULL;
-    } 
+    }
     return &acb->common;
 }
 
@@ -454,7 +524,7 @@ static int raw_create(const char *filename, int64_t total_size,
     if (flags || backing_file)
         return -ENOTSUP;
 
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
               0644);
     if (fd < 0)
         return -EIO;
@@ -479,7 +549,7 @@ BlockDriver bdrv_raw = {
     raw_close,
     raw_create,
     raw_flush,
-    
+
     .bdrv_aio_read = raw_aio_read,
     .bdrv_aio_write = raw_aio_write,
     .bdrv_aio_cancel = raw_aio_cancel,
@@ -500,7 +570,7 @@ static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFI
 
 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
 {
-    kern_return_t       kernResult; 
+    kern_return_t       kernResult;
     mach_port_t     masterPort;
     CFMutableDictionaryRef  classesToMatch;
 
@@ -508,8 +578,8 @@ kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
     if ( KERN_SUCCESS != kernResult ) {
         printf( "IOMasterPort returned %d\n", kernResult );
     }
-    
-    classesToMatch = IOServiceMatching( kIOCDMediaClass ); 
+
+    classesToMatch = IOServiceMatching( kIOCDMediaClass );
     if ( classesToMatch == NULL ) {
         printf( "IOServiceMatching returned a NULL dictionary.\n" );
     } else {
@@ -520,7 +590,7 @@ kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
     {
         printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
     }
-    
+
     return kernResult;
 }
 
@@ -546,7 +616,7 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma
         }
         IOObjectRelease( nextMedia );
     }
-    
+
     return kernResult;
 }
 
@@ -563,10 +633,10 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
         io_iterator_t mediaIterator;
         char bsdPath[ MAXPATHLEN ];
         int fd;
+
         kernResult = FindEjectableCDMedia( &mediaIterator );
         kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
-    
+
         if ( bsdPath[ 0 ] != '\0' ) {
             strcat(bsdPath,"s0");
             /* some CDs don't have a partition 0 */
@@ -578,7 +648,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
             }
             filename = bsdPath;
         }
-        
+
         if ( mediaIterator )
             IOObjectRelease( mediaIterator );
     }
@@ -623,7 +693,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
     return 0;
 }
 
-#if defined(__linux__) && !defined(QEMU_TOOL)
+#if defined(__linux__) && !defined(QEMU_IMG)
 
 /* Note: we do not have a reliable method to detect if the floppy is
    present. The current method is to try to open the floppy at every
@@ -636,7 +706,7 @@ static int fd_open(BlockDriverState *bs)
     if (s->type != FTYPE_FD)
         return 0;
     last_media_present = (s->fd >= 0);
-    if (s->fd >= 0 && 
+    if (s->fd >= 0 &&
         (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
         close(s->fd);
         s->fd = -1;
@@ -645,7 +715,7 @@ static int fd_open(BlockDriverState *bs)
 #endif
     }
     if (s->fd < 0) {
-        if (s->fd_got_error && 
+        if (s->fd_got_error &&
             (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
 #ifdef DEBUG_FLOPPY
             printf("No floppy (open delayed)\n");
@@ -815,7 +885,7 @@ BlockDriver bdrv_host_device = {
     raw_close,
     NULL,
     raw_flush,
-    
+
     .bdrv_aio_read = raw_aio_read,
     .bdrv_aio_write = raw_aio_write,
     .bdrv_aio_cancel = raw_aio_cancel,
@@ -906,12 +976,12 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
     } else {
         create_flags = OPEN_EXISTING;
     }
-#ifdef QEMU_TOOL
+#ifdef QEMU_IMG
     overlapped = FILE_ATTRIBUTE_NORMAL;
 #else
     overlapped = FILE_FLAG_OVERLAPPED;
 #endif
-    s->hfile = CreateFile(filename, access_flags, 
+    s->hfile = CreateFile(filename, access_flags,
                           FILE_SHARE_READ, NULL,
                           create_flags, overlapped, NULL);
     if (s->hfile == INVALID_HANDLE_VALUE) {
@@ -924,14 +994,14 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
     return 0;
 }
 
-static int raw_pread(BlockDriverState *bs, int64_t offset, 
+static int raw_pread(BlockDriverState *bs, int64_t offset,
                      uint8_t *buf, int count)
 {
     BDRVRawState *s = bs->opaque;
     OVERLAPPED ov;
     DWORD ret_count;
     int ret;
-    
+
     memset(&ov, 0, sizeof(ov));
     ov.Offset = offset;
     ov.OffsetHigh = offset >> 32;
@@ -946,14 +1016,14 @@ static int raw_pread(BlockDriverState *bs, int64_t offset,
     return ret_count;
 }
 
-static int raw_pwrite(BlockDriverState *bs, int64_t offset, 
+static int raw_pwrite(BlockDriverState *bs, int64_t offset,
                       const uint8_t *buf, int count)
 {
     BDRVRawState *s = bs->opaque;
     OVERLAPPED ov;
     DWORD ret_count;
     int ret;
-    
+
     memset(&ov, 0, sizeof(ov));
     ov.Offset = offset;
     ov.OffsetHigh = offset >> 32;
@@ -969,7 +1039,7 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
 }
 
 #if 0
-#ifndef QEMU_TOOL
+#ifndef QEMU_IMG
 static void raw_aio_cb(void *opaque)
 {
     RawAIOCB *acb = opaque;
@@ -1008,7 +1078,7 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
     acb->ov.OffsetHigh = offset >> 32;
     acb->ov.hEvent = acb->hEvent;
     acb->count = nb_sectors * 512;
-#ifndef QEMU_TOOL
+#ifndef QEMU_IMG
     qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
 #endif
     return acb;
@@ -1030,7 +1100,7 @@ static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
         qemu_aio_release(acb);
         return NULL;
     }
-#ifdef QEMU_TOOL
+#ifdef QEMU_IMG
     qemu_aio_release(acb);
 #endif
     return (BlockDriverAIOCB *)acb;
@@ -1052,7 +1122,7 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
         qemu_aio_release(acb);
         return NULL;
     }
-#ifdef QEMU_TOOL
+#ifdef QEMU_IMG
     qemu_aio_release(acb);
 #endif
     return (BlockDriverAIOCB *)acb;
@@ -1060,7 +1130,7 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
 
 static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
 {
-#ifndef QEMU_TOOL
+#ifndef QEMU_IMG
     RawAIOCB *acb = (RawAIOCB *)blockacb;
     BlockDriverState *bs = acb->common.bs;
     BDRVRawState *s = bs->opaque;
@@ -1103,8 +1173,8 @@ static int64_t raw_getlength(BlockDriverState *bs)
 {
     BDRVRawState *s = bs->opaque;
     LARGE_INTEGER l;
-    ULARGE_INTEGER available, total, total_free; 
-    DISK_GEOMETRY dg;
+    ULARGE_INTEGER available, total, total_free;
+    DISK_GEOMETRY_EX dg;
     DWORD count;
     BOOL status;
 
@@ -1120,11 +1190,10 @@ static int64_t raw_getlength(BlockDriverState *bs)
         l.QuadPart = total.QuadPart;
         break;
     case FTYPE_HARDDISK:
-        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY,
+        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
                                  NULL, 0, &dg, sizeof(dg), &count, NULL);
-        if (status != FALSE) {
-            l.QuadPart = dg.Cylinders.QuadPart * dg.TracksPerCylinder
-                * dg.SectorsPerTrack * dg.BytesPerSector;
+        if (status != 0) {
+            l = dg.DiskSize;
         }
         break;
     default:
@@ -1141,7 +1210,7 @@ static int raw_create(const char *filename, int64_t total_size,
     if (flags || backing_file)
         return -ENOTSUP;
 
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
               0644);
     if (fd < 0)
         return -EIO;
@@ -1169,7 +1238,7 @@ void qemu_aio_wait_start(void)
 
 void qemu_aio_wait(void)
 {
-#ifndef QEMU_TOOL
+#ifndef QEMU_IMG
     qemu_bh_poll();
 #endif
 }
@@ -1188,7 +1257,7 @@ BlockDriver bdrv_raw = {
     raw_close,
     raw_create,
     raw_flush,
-    
+
 #if 0
     .bdrv_aio_read = raw_aio_read,
     .bdrv_aio_write = raw_aio_write,
@@ -1267,7 +1336,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
         }
     }
     s->type = find_device_type(bs, filename);
-    
+
     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
         access_flags = GENERIC_READ | GENERIC_WRITE;
     } else {
@@ -1275,12 +1344,12 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
     }
     create_flags = OPEN_EXISTING;
 
-#ifdef QEMU_TOOL
+#ifdef QEMU_IMG
     overlapped = FILE_ATTRIBUTE_NORMAL;
 #else
     overlapped = FILE_FLAG_OVERLAPPED;
 #endif
-    s->hfile = CreateFile(filename, access_flags, 
+    s->hfile = CreateFile(filename, access_flags,
                           FILE_SHARE_READ, NULL,
                           create_flags, overlapped, NULL);
     if (s->hfile == INVALID_HANDLE_VALUE) {
@@ -1314,10 +1383,10 @@ static int raw_eject(BlockDriverState *bs, int eject_flag)
     if (s->type == FTYPE_FILE)
         return -ENOTSUP;
     if (eject_flag) {
-        DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA, 
+        DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
                         NULL, 0, NULL, 0, &lpBytesReturned, NULL);
     } else {
-        DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA, 
+        DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
                         NULL, 0, NULL, 0, &lpBytesReturned, NULL);
     }
 }
@@ -1338,7 +1407,7 @@ BlockDriver bdrv_host_device = {
     raw_close,
     NULL,
     raw_flush,
-    
+
 #if 0
     .bdrv_aio_read = raw_aio_read,
     .bdrv_aio_write = raw_aio_write,