]> git.proxmox.com Git - qemu.git/blobdiff - block.c
fixed C0 status codes (Ralf Baechle)
[qemu.git] / block.c
diff --git a/block.c b/block.c
index 43b0188142b2994f91fbd9c7a073e83eab2b2522..18eaf46041a5543a63f1e5501692f675f263b605 100644 (file)
--- a/block.c
+++ b/block.c
 #include "vl.h"
 #include "block_int.h"
 
+#ifdef _BSD
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/queue.h>
+#include <sys/disk.h>
+#endif
+
 static BlockDriverState *bdrv_first;
 static BlockDriver *first_drv;
 
@@ -71,30 +79,56 @@ int bdrv_create(BlockDriver *drv,
     return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
 }
 
-/* XXX: race condition possible */
+#ifdef _WIN32
+static void get_tmp_filename(char *filename, int size)
+{
+    /* XXX: find a better function */
+    tmpnam(filename);
+}
+#else
 static void get_tmp_filename(char *filename, int size)
 {
     int fd;
+    /* XXX: race condition possible */
     pstrcpy(filename, size, "/tmp/vl.XXXXXX");
     fd = mkstemp(filename);
     close(fd);
 }
+#endif
 
+/* XXX: force raw format if block or character device ? It would
+   simplify the BSD case */
 static BlockDriver *find_image_format(const char *filename)
 {
     int fd, ret, score, score_max;
     BlockDriver *drv1, *drv;
-    uint8_t buf[1024];
+    uint8_t *buf;
+    size_t bufsize = 1024;
 
     fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
-    if (fd < 0)
-        return NULL;
-    ret = read(fd, buf, sizeof(buf));
-    if (ret < 0) {
+    if (fd < 0) {
+        buf = NULL;
+        ret = 0;
+    } else {
+#ifdef DIOCGSECTORSIZE
+        {
+            unsigned int sectorsize = 512;
+            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
+                sectorsize > bufsize)
+                bufsize = sectorsize;
+        }
+#endif
+        buf = qemu_malloc(bufsize);
+        if (!buf)
+            return NULL;
+        ret = read(fd, buf, bufsize);
+        if (ret < 0) {
+            close(fd);
+            qemu_free(buf);
+            return NULL;
+        }
         close(fd);
-        return NULL;
     }
-    close(fd);
     
     drv = NULL;
     score_max = 0;
@@ -105,6 +139,7 @@ static BlockDriver *find_image_format(const char *filename)
             drv = drv1;
         }
     }
+    qemu_free(buf);
     return drv;
 }
 
@@ -122,7 +157,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
     bs->read_only = 0;
     bs->is_temporary = 0;
     bs->encrypted = 0;
-    
+
     if (snapshot) {
         BlockDriverState *bs1;
         int64_t total_size;
@@ -151,7 +186,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
         filename = tmp_filename;
         bs->is_temporary = 1;
     }
-    
+
     pstrcpy(bs->filename, sizeof(bs->filename), filename);
     if (!drv) {
         drv = find_image_format(filename);
@@ -340,6 +375,11 @@ void bdrv_set_type_hint(BlockDriverState *bs, int type)
                       type == BDRV_TYPE_FLOPPY));
 }
 
+void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
+{
+    bs->translation = translation;
+}
+
 void bdrv_get_geometry_hint(BlockDriverState *bs, 
                             int *pcyls, int *pheads, int *psecs)
 {
@@ -353,6 +393,11 @@ int bdrv_get_type_hint(BlockDriverState *bs)
     return bs->type;
 }
 
+int bdrv_get_translation_hint(BlockDriverState *bs)
+{
+    return bs->translation;
+}
+
 int bdrv_is_removable(BlockDriverState *bs)
 {
     return bs->removable;
@@ -506,6 +551,9 @@ static int raw_open(BlockDriverState *bs, const char *filename)
     BDRVRawState *s = bs->opaque;
     int fd;
     int64_t size;
+#ifdef _BSD
+    struct stat sb;
+#endif
 
     fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
     if (fd < 0) {
@@ -514,7 +562,23 @@ static int raw_open(BlockDriverState *bs, const char *filename)
             return -1;
         bs->read_only = 1;
     }
-    size = lseek64(fd, 0, SEEK_END);
+#ifdef _BSD
+    if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
+#ifdef DIOCGMEDIASIZE
+       if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
+#endif
+           size = lseek(fd, 0LL, SEEK_END);
+    } else
+#endif
+    {
+        size = lseek(fd, 0, SEEK_END);
+    }
+#ifdef _WIN32
+    /* On Windows hosts it can happen that we're unable to get file size
+       for CD-ROM raw device (it's inherent limitation of the CDFS driver). */
+    if (size == -1)
+        size = LONG_LONG_MAX;
+#endif
     bs->total_sectors = size / 512;
     s->fd = fd;
     return 0;
@@ -526,7 +590,7 @@ static int raw_read(BlockDriverState *bs, int64_t sector_num,
     BDRVRawState *s = bs->opaque;
     int ret;
     
-    lseek64(s->fd, sector_num * 512, SEEK_SET);
+    lseek(s->fd, sector_num * 512, SEEK_SET);
     ret = read(s->fd, buf, nb_sectors * 512);
     if (ret != nb_sectors * 512) 
         return -1;
@@ -539,14 +603,14 @@ static int raw_write(BlockDriverState *bs, int64_t sector_num,
     BDRVRawState *s = bs->opaque;
     int ret;
     
-    lseek64(s->fd, sector_num * 512, SEEK_SET);
+    lseek(s->fd, sector_num * 512, SEEK_SET);
     ret = write(s->fd, buf, nb_sectors * 512);
     if (ret != nb_sectors * 512) 
         return -1;
     return 0;
 }
 
-static int raw_close(BlockDriverState *bs)
+static void raw_close(BlockDriverState *bs)
 {
     BDRVRawState *s = bs->opaque;
     close(s->fd);
@@ -564,7 +628,7 @@ static int raw_create(const char *filename, int64_t total_size,
               0644);
     if (fd < 0)
         return -EIO;
-    ftruncate64(fd, total_size * 512);
+    ftruncate(fd, total_size * 512);
     close(fd);
     return 0;
 }
@@ -588,4 +652,9 @@ void bdrv_init(void)
 #endif
     bdrv_register(&bdrv_qcow);
     bdrv_register(&bdrv_vmdk);
+    bdrv_register(&bdrv_cloop);
+    bdrv_register(&bdrv_dmg);
+    bdrv_register(&bdrv_bochs);
+    bdrv_register(&bdrv_vpc);
+    bdrv_register(&bdrv_vvfat);
 }