diff mbox

[1/1] kvm tools: Enable O_DIRECT support

Message ID 1342089258-14794-1-git-send-email-asias.hejun@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Asias He July 12, 2012, 10:34 a.m. UTC
Open a disk image with O_DIRECT:
   $ lkvm run -d ~/img/test.img,direct

The original readonly flag is still supported.
Open a disk image with O_DIRECT and readonly:
   $ lkvm run -d ~/img/test.img,direct,ro

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/builtin-run.c            |   20 +++++++++++++-------
 tools/kvm/disk/blk.c               |    4 ++--
 tools/kvm/disk/core.c              |   19 ++++++++++++++-----
 tools/kvm/include/kvm/disk-image.h |    5 +++--
 4 files changed, 32 insertions(+), 16 deletions(-)

Comments

Pekka Enberg July 12, 2012, 1:50 p.m. UTC | #1
Hi Asias,

On Thu, Jul 12, 2012 at 1:34 PM, Asias He <asias.hejun@gmail.com> wrote:
> Open a disk image with O_DIRECT:
>    $ lkvm run -d ~/img/test.img,direct
>
> The original readonly flag is still supported.
> Open a disk image with O_DIRECT and readonly:
>    $ lkvm run -d ~/img/test.img,direct,ro
>
> Signed-off-by: Asias He <asias.hejun@gmail.com>

So why do we want to support O_DIRECT i.e. what problem is this patch
trying to address? Why don't we do it unconditionally if it's helpful?

                        Pekka
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index a120fe2..10b716c 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -127,7 +127,7 @@  void kvm_run_set_wrapper_sandbox(void)
 
 static int img_name_parser(const struct option *opt, const char *arg, int unset)
 {
-	char *sep;
+	char *sep, *cur;
 	struct stat st;
 	char path[PATH_MAX];
 
@@ -169,12 +169,18 @@  static int img_name_parser(const struct option *opt, const char *arg, int unset)
 		die("Currently only 4 images are supported");
 
 	disk_image[image_count].filename = arg;
-	sep = strstr(arg, ",");
-	if (sep) {
-		if (strcmp(sep + 1, "ro") == 0)
-			disk_image[image_count].readonly = true;
-		*sep = 0;
-	}
+	cur = arg;
+	do {
+		sep = strstr(cur, ",");
+		if (sep) {
+			if (strncmp(sep + 1, "ro", 2) == 0)
+				disk_image[image_count].readonly = true;
+			else if (strncmp(sep + 1, "direct", 6) == 0)
+				disk_image[image_count].direct = true;
+			*sep = 0;
+			cur = sep + 1;
+		}
+	} while (sep);
 
 	image_count++;
 
diff --git a/tools/kvm/disk/blk.c b/tools/kvm/disk/blk.c
index cf853c1..37581d3 100644
--- a/tools/kvm/disk/blk.c
+++ b/tools/kvm/disk/blk.c
@@ -33,7 +33,7 @@  static bool is_mounted(struct stat *st)
 	return false;
 }
 
-struct disk_image *blkdev__probe(const char *filename, struct stat *st)
+struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st)
 {
 	struct disk_image *disk;
 	int fd, r;
@@ -52,7 +52,7 @@  struct disk_image *blkdev__probe(const char *filename, struct stat *st)
 	 * Be careful! We are opening host block device!
 	 * Open it readonly since we do not want to break user's data on disk.
 	 */
-	fd = open(filename, O_RDWR);
+	fd = open(filename, flags);
 	if (fd < 0)
 		return ERR_PTR(fd);
 
diff --git a/tools/kvm/disk/core.c b/tools/kvm/disk/core.c
index 5542d42..621c940 100644
--- a/tools/kvm/disk/core.c
+++ b/tools/kvm/disk/core.c
@@ -75,21 +75,28 @@  struct disk_image *disk_image__new(int fd, u64 size,
 	return disk;
 }
 
-struct disk_image *disk_image__open(const char *filename, bool readonly)
+struct disk_image *disk_image__open(const char *filename, bool readonly, bool direct)
 {
 	struct disk_image *disk;
 	struct stat st;
-	int fd;
+	int fd, flags;
+
+	if (readonly)
+		flags = O_RDONLY;
+	else
+		flags = O_RDWR;
+	if (direct)
+		flags |= O_DIRECT;
 
 	if (stat(filename, &st) < 0)
 		return ERR_PTR(-errno);
 
 	/* blk device ?*/
-	disk = blkdev__probe(filename, &st);
+	disk = blkdev__probe(filename, flags, &st);
 	if (!IS_ERR_OR_NULL(disk))
 		return disk;
 
-	fd = open(filename, readonly ? O_RDONLY : O_RDWR);
+	fd = open(filename, flags);
 	if (fd < 0)
 		return ERR_PTR(fd);
 
@@ -116,6 +123,7 @@  struct disk_image **disk_image__open_all(struct disk_image_params *params, int c
 	struct disk_image **disks;
 	const char *filename;
 	bool readonly;
+	bool direct;
 	void *err;
 	int i;
 
@@ -131,10 +139,11 @@  struct disk_image **disk_image__open_all(struct disk_image_params *params, int c
 	for (i = 0; i < count; i++) {
 		filename = params[i].filename;
 		readonly = params[i].readonly;
+		direct = params[i].direct;
 		if (!filename)
 			continue;
 
-		disks[i] = disk_image__open(filename, readonly);
+		disks[i] = disk_image__open(filename, readonly, direct);
 		if (IS_ERR_OR_NULL(disks[i])) {
 			pr_err("Loading disk image '%s' failed", filename);
 			err = disks[i];
diff --git a/tools/kvm/include/kvm/disk-image.h b/tools/kvm/include/kvm/disk-image.h
index 5d09875..7ae17f8 100644
--- a/tools/kvm/include/kvm/disk-image.h
+++ b/tools/kvm/include/kvm/disk-image.h
@@ -42,6 +42,7 @@  struct disk_image_operations {
 struct disk_image_params {
 	const char *filename;
 	bool readonly;
+	bool direct;
 };
 
 struct disk_image {
@@ -58,7 +59,7 @@  struct disk_image {
 #endif
 };
 
-struct disk_image *disk_image__open(const char *filename, bool readonly);
+struct disk_image *disk_image__open(const char *filename, bool readonly, bool direct);
 struct disk_image **disk_image__open_all(struct disk_image_params *params, int count);
 struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int mmap);
 int disk_image__close(struct disk_image *disk);
@@ -71,7 +72,7 @@  ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iove
 ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *len);
 
 struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly);
-struct disk_image *blkdev__probe(const char *filename, struct stat *st);
+struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st);
 
 ssize_t raw_image__read(struct disk_image *disk, u64 sector,
 				const struct iovec *iov, int iovcount, void *param);