]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Enable O_DIRECT support
authorAsias He <asias.hejun@gmail.com>
Fri, 3 Aug 2012 09:19:51 +0000 (17:19 +0800)
committerPekka Enberg <penberg@kernel.org>
Sat, 4 Aug 2012 09:05:36 +0000 (12:05 +0300)
With Direct I/O, file reads and writes go directly from the applications
to the storage device, bypassing the operating system read and write
caches. This is useful for applications that manage their own caches.

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>
Acked-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/builtin-run.c
tools/kvm/disk/blk.c
tools/kvm/disk/core.c
tools/kvm/include/kvm/disk-image.h

index 21d5f341f5d00ba22132e221b564f1f53f3ea34f..952534141f553b8c1dd76c857f22306f3c6aaa0f 100644 (file)
@@ -127,9 +127,10 @@ void kvm_run_set_wrapper_sandbox(void)
 
 static int img_name_parser(const struct option *opt, const char *arg, int unset)
 {
-       char *sep;
-       struct stat st;
        char path[PATH_MAX];
+       const char *cur;
+       struct stat st;
+       char *sep;
 
        if (stat(arg, &st) == 0 &&
            S_ISDIR(st.st_mode)) {
@@ -169,12 +170,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++;
 
index cf853c172c5370c1f1ca37fadbe1516c7759cf2d..37581d33136ba532f3b1c6cfa850eaec213ad190 100644 (file)
@@ -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);
 
index 5542d42919679985285666846d23124360db8ba2..621c940525118d2b5fec31fd2de75669f0064a9f 100644 (file)
@@ -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];
index 5d098757bd9897677725ce55b7f75443ddf7f057..7ae17f894f330573d0638c522685bd74fa6e35c8 100644 (file)
@@ -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);