From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RFC PATCH 2/3] raw: implement raw_get_alignment
Date: Wed, 23 Nov 2011 17:51:26 +0100 [thread overview]
Message-ID: <1322067087-16884-3-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1322067087-16884-1-git-send-email-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
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, §or_size)) {
+ return sector size;
+ }
+#endif
+#ifdef DKIOCGETBLOCKSIZE
+ if (ioctl(s->fd, DKIOCGETBLOCKSIZE, §or_size)) {
+ return sector_size;
+ }
+#endif
#ifdef DIOCGSECTORSIZE
- {
- unsigned int sectorsize = 512;
- if (!ioctl(fd, DIOCGSECTORSIZE, §orsize) &&
- sectorsize > bufsize)
- bufsize = sectorsize;
- }
+ if (ioctl(s->fd, DIOCGSECTORSIZE, §or_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, §orsPerCluster,
+ &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
next prev parent reply other threads:[~2011-11-23 16:51 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-23 16:51 [Qemu-devel] [RFC PATCH 0/3] block: add support for 4k logical blocks Paolo Bonzini
2011-11-23 16:51 ` [Qemu-devel] [RFC PATCH 1/3] block: add bdrv_get_alignment, use it Paolo Bonzini
2011-11-23 16:51 ` Paolo Bonzini [this message]
2011-11-23 16:51 ` [Qemu-devel] [RFC PATCH 3/3] block: do not rely on the buffer alignment passed to the guest Paolo Bonzini
2011-11-25 7:26 ` [Qemu-devel] [RFC PATCH 0/3] block: add support for 4k logical blocks Mark Wu
2011-11-25 8:27 ` Paolo Bonzini
2011-11-25 11:13 ` Christoph Hellwig
2011-11-28 3:05 ` Mark Wu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1322067087-16884-3-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).