]> git.proxmox.com Git - mirror_qemu.git/commitdiff
Windows sparse file support (Frediano Ziglio)
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 26 Jun 2006 20:08:57 +0000 (20:08 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 26 Jun 2006 20:08:57 +0000 (20:08 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2027 c046a42c-6fe2-441c-8c8c-71466251a162

Changelog
block.c
vl.h

index 0b0d2a45f0348f93ddf4e76d00613739d4f81172..df487a54e6d878bd69a30a709852f7dac4c96415 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -10,6 +10,7 @@ version 0.8.2:
   - USB updates (Paul Brook)
   - UDP character devices (Jason Wessel)
   - TCP character devices
+  - Windows sparse file support (Frediano Ziglio)
 
 version 0.8.1:
 
diff --git a/block.c b/block.c
index c25c6869a6a268f8317ad367a05f948067c2f2ed..ceb0532bd0b1720c9dd29f36a031a0fce0f9b495 100644 (file)
--- a/block.c
+++ b/block.c
@@ -761,6 +761,51 @@ static void raw_close(BlockDriverState *bs)
     close(s->fd);
 }
 
+#ifdef _WIN32
+#include <windows.h>
+#include <winioctl.h>
+
+int qemu_ftruncate64(int fd, int64_t length)
+{
+    LARGE_INTEGER li;
+    LONG high;
+    HANDLE h;
+    BOOL res;
+
+    if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
+       return -1;
+
+    h = (HANDLE)_get_osfhandle(fd);
+
+    /* get current position, ftruncate do not change position */
+    li.HighPart = 0;
+    li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
+    if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
+       return -1;
+
+    high = length >> 32;
+    if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
+       return -1;
+    res = SetEndOfFile(h);
+
+    /* back to old position */
+    SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
+    return res ? 0 : -1;
+}
+
+static int set_sparse(int fd)
+{
+    DWORD returned;
+    return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
+                                NULL, 0, NULL, 0, &returned, NULL);
+}
+#else
+static inline int set_sparse(int fd)
+{
+    return 1;
+}
+#endif
+
 static int raw_create(const char *filename, int64_t total_size,
                       const char *backing_file, int flags)
 {
@@ -773,6 +818,7 @@ static int raw_create(const char *filename, int64_t total_size,
               0644);
     if (fd < 0)
         return -EIO;
+    set_sparse(fd);
     ftruncate(fd, total_size * 512);
     close(fd);
     return 0;
diff --git a/vl.h b/vl.h
index fb72dd55e7009d6917591a464c56e3f02845359a..244310fee19d1f72b45a47430d0a623081b6ea61 100644 (file)
--- a/vl.h
+++ b/vl.h
@@ -51,8 +51,9 @@
 #define fsync _commit
 #define lseek _lseeki64
 #define ENOTSUP 4096
-/* XXX: find 64 bit version */
-#define ftruncate chsize
+extern int qemu_ftruncate64(int, int64_t);
+#define ftruncate qemu_ftruncate64
+
 
 static inline char *realpath(const char *path, char *resolved_path)
 {