diff options
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | block.c | 46 | ||||
-rw-r--r-- | vl.h | 5 |
3 files changed, 50 insertions, 2 deletions
@@ -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: @@ -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; @@ -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) { |