qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH 2/3] raw: implement raw_get_alignment


From: Paolo Bonzini
Subject: [Qemu-devel] [RFC PATCH 2/3] raw: implement raw_get_alignment
Date: Wed, 23 Nov 2011 17:51:26 +0100

Signed-off-by: Paolo Bonzini <address@hidden>
---
 block/raw-posix.c |   65 ++++++++++++++++++++++++++++++++++++++++++----------
 block/raw-win32.c |   45 ++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 13 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 3482fc8..f6747ad 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -279,22 +279,56 @@ static int raw_open(BlockDriverState *bs, const char 
*filename, int flags)
     return raw_open_common(bs, filename, flags, 0);
 }
 
-/* XXX: use host sector size if necessary with:
+static int raw_get_alignment(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    unsigned int sector_size;
+    int ret;
+
+    ret = fd_open(bs);
+    if (ret < 0) {
+        return ret;
+    }
+
+    /* For block devices, try to get the actual sector size even if we
+     * do not need it, so that it can be passed down to the guest.
+     */
+#ifdef BLKSSZGET
+    if (ioctl(s->fd, BLKSSZGET, &sector_size)) {
+        return sector size;
+    }
+#endif
+#ifdef DKIOCGETBLOCKSIZE
+    if (ioctl(s->fd, DKIOCGETBLOCKSIZE, &sector_size)) {
+        return sector_size;
+    }
+#endif
 #ifdef DIOCGSECTORSIZE
-        {
-            unsigned int sectorsize = 512;
-            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
-                sectorsize > bufsize)
-                bufsize = sectorsize;
-        }
+    if (ioctl(s->fd, DIOCGSECTORSIZE, &sector_size)) {
+        return sector_size;
+    }
 #endif
-#ifdef CONFIG_COCOA
-        uint32_t blockSize = 512;
-        if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > 
bufsize) {
-            bufsize = blockSize;
+
+    /* If we could not get the size so far, we can only guess it if
+     * the file was opened with O_DIRECT.  If not, just return the
+     * minimal size.
+     *
+     * For /dev/sg devices the alignment is not really used, so return
+     * a dummy value for them too.
+     */
+    if (bs->sg || !s->aligned_buf) {
+        return 512;
+    }
+
+    for (sector_size = 512; sector_size < MAX_BLOCKSIZE; sector_size <<= 1) {
+        /* The buffer must be aligned to sector_size, but not sector_size*2.  
*/
+        if (pread(s->fd, s->aligned_buf + sector_size, sector_size, 0) >= 0) {
+            break;
         }
-#endif
-*/
+    }
+    return sector_size;
+}
+
 
 /*
  * Check if all memory in this vector is sector aligned.
@@ -642,6 +676,7 @@ static BlockDriver bdrv_file = {
 
     .bdrv_truncate = raw_truncate,
     .bdrv_getlength = raw_getlength,
+    .bdrv_get_alignment = raw_get_alignment,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
@@ -910,6 +945,7 @@ static BlockDriver bdrv_host_device = {
 
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength    = raw_getlength,
+    .bdrv_get_alignment = raw_get_alignment,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
@@ -1029,6 +1065,7 @@ static BlockDriver bdrv_host_floppy = {
 
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength    = raw_getlength,
+    .bdrv_get_alignment = raw_get_alignment,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
@@ -1128,6 +1165,7 @@ static BlockDriver bdrv_host_cdrom = {
 
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength     = raw_getlength,
+    .bdrv_get_alignment = raw_get_alignment,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
@@ -1247,6 +1285,7 @@ static BlockDriver bdrv_host_cdrom = {
 
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength     = raw_getlength,
+    .bdrv_get_alignment = raw_get_alignment,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
diff --git a/block/raw-win32.c b/block/raw-win32.c
index e4b0b75..f033037 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -96,6 +96,18 @@ static int raw_open(BlockDriverState *bs, const char 
*filename, int flags)
         overlapped |= FILE_FLAG_NO_BUFFERING;
     if (!(flags & BDRV_O_CACHE_WB))
         overlapped |= FILE_FLAG_WRITE_THROUGH;
+
+    if (filename[0] && filename[1] == ':') {
+        snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", filename[0]);
+    } else if (filename[0] == '\\' && filename[1] == '\\') {
+        s->drive_path[0] = 0;
+    } else {
+        /* Relative path.  */
+        char buf[MAX_PATH];
+        GetCurrentDirectory(MAX_PATH, buf);
+        snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", buf[0]);
+    }
+
     s->hfile = CreateFile(filename, access_flags,
                           FILE_SHARE_READ, NULL,
                           OPEN_EXISTING, overlapped, NULL);
@@ -184,6 +196,37 @@ static int raw_truncate(BlockDriverState *bs, int64_t 
offset)
     return 0;
 }
 
+static int raw_get_alignment(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    DWORD sectorsPerCluster, freeClusters, totalClusters, count;
+    DISK_GEOMETRY_EX dg;
+    BOOL status;
+
+    dg.Geometry.BytesPerSector = 512;
+    switch(s->type) {
+    case FTYPE_CD:
+        return 2048;
+    case FTYPE_HARDDISK:
+        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
+                                 NULL, 0, &dg, sizeof(dg), &count, NULL);
+        if (status != 0) {
+            break;
+        }
+        /* fall through */
+    case FTYPE_FILE:
+        if (s->drive_path[0]) {
+            GetDiskFreeSpace(s->drive_path, &sectorsPerCluster,
+                             &dg.Geometry.BytesPerSector,
+                             &freeClusters, &totalClusters);
+        }
+        break;
+    default:
+        return -EIO;
+    }
+    return dg.Geometry.BytesPerSector;
+}
+
 static int64_t raw_getlength(BlockDriverState *bs)
 {
     BDRVRawState *s = bs->opaque;
@@ -288,6 +331,7 @@ static BlockDriver bdrv_file = {
 
     .bdrv_truncate     = raw_truncate,
     .bdrv_getlength    = raw_getlength,
+    .bdrv_get_alignment        = raw_get_alignment,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 
@@ -418,6 +462,7 @@ static BlockDriver bdrv_host_device = {
     .bdrv_co_flush_to_disk  = raw_flush,
 
     .bdrv_getlength    = raw_getlength,
+    .bdrv_get_alignment        = raw_get_alignment,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
 };
-- 
1.7.7.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]