From patchwork Tue Oct 11 03:11:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Supriya Kannery X-Patchwork-Id: 118858 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 915DAB6F85 for ; Tue, 11 Oct 2011 14:12:29 +1100 (EST) Received: from localhost ([::1]:49698 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RDSlU-0002ik-SM for incoming@patchwork.ozlabs.org; Mon, 10 Oct 2011 23:12:24 -0400 Received: from eggs.gnu.org ([140.186.70.92]:56998) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RDSlM-0002hW-5a for qemu-devel@nongnu.org; Mon, 10 Oct 2011 23:12:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RDSlK-0001KP-Mq for qemu-devel@nongnu.org; Mon, 10 Oct 2011 23:12:16 -0400 Received: from e4.ny.us.ibm.com ([32.97.182.144]:36715) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RDSlK-0001KL-Jo for qemu-devel@nongnu.org; Mon, 10 Oct 2011 23:12:14 -0400 Received: from /spool/local by e4.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 10 Oct 2011 23:12:13 -0400 Received: from d01relay02.pok.ibm.com ([9.56.227.234]) by e4.ny.us.ibm.com ([192.168.1.104]) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 10 Oct 2011 23:12:04 -0400 Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay02.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p9B3C3LQ464312 for ; Mon, 10 Oct 2011 23:12:03 -0400 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p9B3C3NR003002 for ; Mon, 10 Oct 2011 23:12:03 -0400 Received: from skannery.in.ibm.com ([9.79.209.68]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p9B3BxfW002559; Mon, 10 Oct 2011 23:12:00 -0400 From: Supriya Kannery To: qemu-devel@nongnu.org Date: Tue, 11 Oct 2011 08:41:59 +0530 Message-Id: <20111011031159.9587.57559.sendpatchset@skannery.in.ibm.com> In-Reply-To: <20111011031046.9587.44474.sendpatchset@skannery.in.ibm.com> References: <20111011031046.9587.44474.sendpatchset@skannery.in.ibm.com> x-cbid: 11101103-3534-0000-0000-0000008E6593 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 32.97.182.144 Cc: Kevin Wolf , Stefan Hajnoczi , Christoph Hellwig Subject: [Qemu-devel] [v7 Patch 5/5]Qemu: New struct 'BDRVReopenState' for image files reopen X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Struct BDRVReopenState introduced for handling reopen state of images. This can be extended by each of the block drivers to reopen respective image files. Implementation for raw-posix is done here. Signed-off-by: Supriya Kannery --- block.c | 46 ++++++++++++++++++++++++++++++++-------- block/raw-posix.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ block_int.h | 15 +++++++++++++ 3 files changed, 114 insertions(+), 9 deletions(-) Index: qemu/block/raw-posix.c =================================================================== --- qemu.orig/block/raw-posix.c +++ qemu/block/raw-posix.c @@ -279,6 +279,66 @@ static int raw_open(BlockDriverState *bs return raw_open_common(bs, filename, flags, 0); } +static int raw_reopen_prepare(BlockDriverState *bs, BDRVReopenState **rs, + int flags) +{ + BDRVReopenState *raw_rs = g_malloc0(sizeof(BDRVReopenState)); + BDRVRawState *s = bs->opaque; + + raw_rs->bs = bs; + raw_rs->reopen_flags = flags; + raw_rs->reopen_fd = -1; + + /* If only O_DIRECT to be toggled, use fcntl */ + if (!((bs->open_flags & ~BDRV_O_NOCACHE) ^ + (flags & ~BDRV_O_NOCACHE))) { + raw_rs->reopen_fd = dup(s->fd); + if (raw_rs->reopen_fd <= 0) { + return -1; + } + } + + /* TBD: Handle O_DSYNC and other flags */ + *rs = raw_rs; + return 0; +} + +static int raw_reopen_commit(BDRVReopenState *rs) +{ + BlockDriverState *bs = rs->bs; + BDRVRawState *s = bs->opaque; + + if (!rs->reopen_fd) { + return -1; + } + + int ret = fcntl_setfl(rs->reopen_fd, rs->reopen_flags); + if (ret < 0) { + return ret; + } + + /* Set new flags, so replace old fd with new one */ + close(s->fd); + s->fd = rs->reopen_fd; + s->open_flags = bs->open_flags = rs->reopen_flags; + g_free(rs); + rs = NULL; + + return 0; +} + +static int raw_reopen_abort(BDRVReopenState *rs) +{ + if (rs->reopen_fd != -1) { + close(rs->reopen_fd); + rs->reopen_fd = -1; + rs->reopen_flags = 0; + } + g_free(rs); + rs = NULL; + return 0; +} + /* XXX: use host sector size if necessary with: #ifdef DIOCGSECTORSIZE { @@ -896,6 +956,9 @@ static BlockDriver bdrv_file = { .instance_size = sizeof(BDRVRawState), .bdrv_probe = NULL, /* no probe for protocols */ .bdrv_file_open = raw_open, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, .bdrv_read = raw_read, .bdrv_write = raw_write, .bdrv_close = raw_close, @@ -1166,6 +1229,10 @@ static BlockDriver bdrv_host_device = { .instance_size = sizeof(BDRVRawState), .bdrv_probe_device = hdev_probe_device, .bdrv_file_open = hdev_open, + .bdrv_reopen_prepare + = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, .bdrv_close = raw_close, .bdrv_create = hdev_create, .create_options = raw_create_options, Index: qemu/block.c =================================================================== --- qemu.orig/block.c +++ qemu/block.c @@ -706,6 +706,7 @@ int bdrv_reopen(BlockDriverState *bs, in { BlockDriver *drv = bs->drv; int ret = 0, open_flags; + BDRVReopenState *rs; /* Quiesce IO for the given block device */ qemu_aio_flush(); @@ -713,20 +714,48 @@ int bdrv_reopen(BlockDriverState *bs, in qerror_report(QERR_DATA_SYNC_FAILED, bs->device_name); return ret; } - open_flags = bs->open_flags; - bdrv_close(bs); - ret = bdrv_open(bs, bs->filename, bdrv_flags, drv); - if (ret < 0) { - /* Reopen failed. Try to open with original flags */ - qerror_report(QERR_REOPEN_FILE_FAILED, bs->filename); - ret = bdrv_open(bs, bs->filename, open_flags, drv); + /* Use driver specific reopen() if available */ + if (drv->bdrv_reopen_prepare) { + ret = drv->bdrv_reopen_prepare(bs, &rs, bdrv_flags); if (ret < 0) { - /* Reopen failed with orig and modified flags */ - abort(); + goto fail; } - } + if (drv->bdrv_reopen_commit) { + ret = drv->bdrv_reopen_commit(rs); + if (ret < 0) { + goto fail; + } + return 0; + } +fail: + if (drv->bdrv_reopen_abort) { + ret = drv->bdrv_reopen_abort(rs); + qerror_report(QERR_REOPEN_FILE_FAILED, bs->filename); + return ret; + } + + } else { + + /* Use reopen procedure common for all drivers */ + open_flags = bs->open_flags; + bdrv_close(bs); + ret = bdrv_open(bs, bs->filename, bdrv_flags, drv); + if (ret < 0) { + /* + * Reopen failed. Try to open with original flags + */ + qerror_report(QERR_REOPEN_FILE_FAILED, bs->filename); + ret = bdrv_open(bs, bs->filename, open_flags, drv); + if (ret < 0) { + /* + * Reopen with orig and modified flags failed + */ + abort(); + } + } + } return ret; } Index: qemu/block_int.h =================================================================== --- qemu.orig/block_int.h +++ qemu/block_int.h @@ -55,6 +55,13 @@ struct BlockDriver { int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename); int (*bdrv_probe_device)(const char *filename); int (*bdrv_open)(BlockDriverState *bs, int flags); + + /* For handling image reopen for split or non-split files */ + int (*bdrv_reopen_prepare)(BlockDriverState *bs, BDRVReopenState **rs, + int flags); + int (*bdrv_reopen_commit)(BDRVReopenState *rs); + int (*bdrv_reopen_abort)(BDRVReopenState *rs); + int (*bdrv_file_open)(BlockDriverState *bs, const char *filename, int flags); int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors); @@ -207,6 +214,14 @@ struct BlockDriverState { void *private; }; +struct BDRVReopenState { + BlockDriverState *bs; + int reopen_flags; + + /* For raw-posix */ + int reopen_fd; +}; + struct BlockDriverAIOCB { AIOPool *pool; BlockDriverState *bs; Index: qemu/qemu-common.h =================================================================== --- qemu.orig/qemu-common.h +++ qemu/qemu-common.h @@ -228,6 +228,7 @@ typedef struct NICInfo NICInfo; typedef struct HCIInfo HCIInfo; typedef struct AudioState AudioState; typedef struct BlockDriverState BlockDriverState; +typedef struct BDRVReopenState BDRVReopenState; typedef struct DriveInfo DriveInfo; typedef struct DisplayState DisplayState; typedef struct DisplayChangeListener DisplayChangeListener; Index: qemu/block/raw.c =================================================================== --- qemu.orig/block/raw.c +++ qemu/block/raw.c @@ -9,6 +9,15 @@ static int raw_open(BlockDriverState *bs return 0; } +static int raw_reopen(BlockDriverState *bs, BDRVReopenState **prs, int flags) +{ + int ret = bdrv_reopen(bs->file, flags); + if (!ret) { + bs->open_flags = bs->file->open_flags; + } + return ret; +} + static int raw_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { @@ -128,6 +137,8 @@ static BlockDriver bdrv_raw = { .instance_size = 1, .bdrv_open = raw_open, + .bdrv_reopen_prepare + = raw_reopen, .bdrv_close = raw_close, .bdrv_read = raw_read, .bdrv_write = raw_write,