From patchwork Thu Jul 12 15:18:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Asias He X-Patchwork-Id: 1189551 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id D8613DFFFE for ; Thu, 12 Jul 2012 15:21:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161044Ab2GLPVO (ORCPT ); Thu, 12 Jul 2012 11:21:14 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:51949 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932727Ab2GLPU6 (ORCPT ); Thu, 12 Jul 2012 11:20:58 -0400 Received: by pbbrp8 with SMTP id rp8so3870981pbb.19 for ; Thu, 12 Jul 2012 08:20:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer; bh=4RR50feQWD9+3REiPE7kIbGMzx5oQPdHSmpcg0IvUqQ=; b=0SEeM5hGniyAXvjiYcJuExBVI9KsvzsfQ/yxSsCMy0bAS78lX3dMdv7K+4AUzv/2KO J6oQuf6FZ8+dNyl/KiSd7YFs3UzH1bHRYbycp6TbUvn4lyfkXv+xZEPanF+6P57uIZh4 bthzQwV5qj1V5lrwpiay/nMf9JkYVR6yy6FI9GAiQ+OwFGXtQgwk4WN3gd4n4pD+DZwA I30Be9T7SjTQOusW6i/ir3gveFV9avCqT7bOg17P+w/ODeMGefguURarFetORttjDXCV mT58Gq759QUuB7PoC+ZVcuH7hpfdmKMH5dLjvE7b6KYoFsnW0h5s/YG9tif8TgS61fIA nOcQ== Received: by 10.68.190.102 with SMTP id gp6mr6500643pbc.5.1342106458027; Thu, 12 Jul 2012 08:20:58 -0700 (PDT) Received: from hj.localdomain.com ([58.194.229.69]) by mx.google.com with ESMTPS id ru4sm4024870pbc.66.2012.07.12.08.20.54 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 12 Jul 2012 08:20:56 -0700 (PDT) From: Asias He To: Pekka Enberg Cc: Sasha Levin , Ingo Molnar , Cyrill Gorcunov , kvm@vger.kernel.org, Asias He Subject: [PATCH V2] kvm tools: Enable O_DIRECT support Date: Thu, 12 Jul 2012 23:18:43 +0800 Message-Id: <1342106323-27774-1-git-send-email-asias.hejun@gmail.com> X-Mailer: git-send-email 1.7.10.4 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 --- tools/kvm/builtin-run.c | 23 +++++++++++++++-------- tools/kvm/disk/blk.c | 4 ++-- tools/kvm/disk/core.c | 19 ++++++++++++++----- tools/kvm/include/kvm/disk-image.h | 5 +++-- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c index a120fe2..8e1627e 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -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++; 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);