From patchwork Mon Jul 30 21:35:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Supriya Kannery X-Patchwork-Id: 174100 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A24D52C008B for ; Tue, 31 Jul 2012 07:36:47 +1000 (EST) Received: from localhost ([::1]:37951 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Svxdt-0002iP-P6 for incoming@patchwork.ozlabs.org; Mon, 30 Jul 2012 17:36:45 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37908) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Svxdh-0002bF-JS for qemu-devel@nongnu.org; Mon, 30 Jul 2012 17:36:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Svxdg-000293-4x for qemu-devel@nongnu.org; Mon, 30 Jul 2012 17:36:33 -0400 Received: from e37.co.us.ibm.com ([32.97.110.158]:37311) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Svxdf-00028x-TD for qemu-devel@nongnu.org; Mon, 30 Jul 2012 17:36:32 -0400 Received: from /spool/local by e37.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 30 Jul 2012 15:36:29 -0600 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) by e37.co.us.ibm.com (192.168.1.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 30 Jul 2012 15:35:37 -0600 Received: from d03relay01.boulder.ibm.com (d03relay01.boulder.ibm.com [9.17.195.226]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id 9578619D8041 for ; Mon, 30 Jul 2012 21:35:31 +0000 (WET) Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay01.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q6ULZXUq070456 for ; Mon, 30 Jul 2012 15:35:33 -0600 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q6ULZXXj006942 for ; Mon, 30 Jul 2012 15:35:33 -0600 Received: from skannery.in.ibm.com ([9.79.207.23]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q6ULZTGp006495; Mon, 30 Jul 2012 15:35:30 -0600 From: Supriya Kannery To: qemu-devel@nongnu.org Date: Tue, 31 Jul 2012 03:05:25 +0530 Message-Id: <20120730213525.21536.9516.sendpatchset@skannery.in.ibm.com> In-Reply-To: <20120730213409.21536.7589.sendpatchset@skannery.in.ibm.com> References: <20120730213409.21536.7589.sendpatchset@skannery.in.ibm.com> X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12073021-7408-0000-0000-000007381261 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 32.97.110.158 Cc: Kevin Wolf , Shrinidhi Joshi , Stefan Hajnoczi , Jeff Cody , Luiz Capitulino , Christoph Hellwig Subject: [Qemu-devel] [v2 Patch 5/9]block: qcow2 image file 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 qcow2 driver changes for bdrv_reopen_xx functions to safely reopen image files. Reopening of image files while changing hostcache dynamically is handled here. Signed-off-by: Supriya Kannery Index: qemu/block/qcow2.c =================================================================== --- qemu.orig/block/qcow2.c +++ qemu/block/qcow2.c @@ -52,10 +52,19 @@ typedef struct { uint32_t magic; uint32_t len; } QCowExtension; + +typedef struct BDRVQcowReopenState { + BDRVReopenState reopen_state; + BDRVQcowState *stash_s; +} BDRVQcowReopenState; + #define QCOW2_EXT_MAGIC_END 0 #define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA #define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857 +static void qcow2_stash_state(BDRVQcowState *stashed_state, BDRVQcowState *s); +static void qcow2_revert_state(BDRVQcowState *s, BDRVQcowState *stashed_state); + static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename) { const QCowHeader *cow_header = (const void *)buf; @@ -434,6 +443,169 @@ static int qcow2_open(BlockDriverState * return ret; } +static int qcow2_reopen_prepare(BlockDriverState *bs, BDRVReopenState **prs, + int flags) +{ + BDRVQcowReopenState *qcow2_rs = g_malloc0(sizeof(BDRVQcowReopenState)); + int ret = 0; + BDRVQcowState *s = bs->opaque; + + qcow2_rs->reopen_state.bs = bs; + + /* save state before reopen */ + qcow2_rs->stash_s = g_malloc0(sizeof(BDRVQcowState)); + qcow2_stash_state(qcow2_rs->stash_s, s); + *prs = &(qcow2_rs->reopen_state); + + /* Reopen file with new flags */ + ret = qcow2_open(bs, flags); + return ret; +} + +static void qcow2_reopen_commit(BlockDriverState *bs, BDRVReopenState *rs) +{ + BDRVQcowReopenState *qcow2_rs; + BDRVQcowState *stashed_s; + + qcow2_rs = container_of(rs, BDRVQcowReopenState, reopen_state); + stashed_s = qcow2_rs->stash_s; + + qcow2_cache_flush(bs, stashed_s->l2_table_cache); + qcow2_cache_flush(bs, stashed_s->refcount_block_cache); + + qcow2_cache_destroy(bs, stashed_s->l2_table_cache); + qcow2_cache_destroy(bs, stashed_s->refcount_block_cache); + + g_free(stashed_s->unknown_header_fields); + cleanup_unknown_header_ext(bs); + + g_free(stashed_s->cluster_cache); + qemu_vfree(stashed_s->cluster_data); + qcow2_refcount_close(bs); + qcow2_free_snapshots(bs); + + g_free(stashed_s); + g_free(qcow2_rs); +} + +static void qcow2_reopen_abort(BlockDriverState *bs, BDRVReopenState *rs) +{ + BDRVQcowReopenState *qcow2_rs; + BDRVQcowState *s = bs->opaque; + BDRVQcowState *stashed_s; + + qcow2_rs = container_of(rs, BDRVQcowReopenState, reopen_state); + + /* Revert to stashed state */ + qcow2_revert_state(s, qcow2_rs->stash_s); + stashed_s = qcow2_rs->stash_s; + + g_free(stashed_s); + g_free(qcow2_rs); +} + +static void qcow2_stash_state(BDRVQcowState *stashed_s, BDRVQcowState *s) +{ + stashed_s->cluster_bits = s->cluster_bits; + stashed_s->cluster_size = s->cluster_size; + stashed_s->cluster_sectors = s->cluster_sectors; + stashed_s->l2_bits = s->l2_bits; + stashed_s->l2_size = s->l2_size; + stashed_s->l1_size = s->l1_size; + stashed_s->l1_vm_state_index = s->l1_vm_state_index; + stashed_s->csize_shift = s->csize_shift; + stashed_s->csize_mask = s->csize_mask; + stashed_s->cluster_offset_mask = s->cluster_offset_mask; + stashed_s->l1_table_offset = s->l1_table_offset; + stashed_s->l1_table = s->l1_table; + + stashed_s->l2_table_cache = s->l2_table_cache; + stashed_s->refcount_block_cache = s->refcount_block_cache; + + stashed_s->cluster_cache = s->cluster_cache; + stashed_s->cluster_data = s->cluster_data; + stashed_s->cluster_cache_offset = s->cluster_cache_offset; + stashed_s->cluster_allocs = s->cluster_allocs; + + stashed_s->refcount_table = s->refcount_table; + stashed_s->refcount_table_offset = s->refcount_table_offset; + stashed_s->refcount_table_size = s->refcount_table_size; + stashed_s->free_cluster_index = s->free_cluster_index; + stashed_s->free_byte_offset = s->free_byte_offset; + + stashed_s->lock = s->lock; + + stashed_s->crypt_method = s->crypt_method; + stashed_s->crypt_method_header = s->crypt_method_header; + stashed_s->aes_encrypt_key = s->aes_encrypt_key; + stashed_s->aes_decrypt_key = s->aes_decrypt_key; + stashed_s->snapshots_offset = s->snapshots_offset; + stashed_s->snapshots_size = s->snapshots_size; + stashed_s->nb_snapshots = s->nb_snapshots; + stashed_s->snapshots = s->snapshots; + + stashed_s->flags = s->flags; + stashed_s->qcow_version = s->qcow_version; + + stashed_s->incompatible_features = s->incompatible_features; + stashed_s->compatible_features = s->compatible_features; + + stashed_s->unknown_header_fields_size = s->unknown_header_fields_size; + stashed_s->unknown_header_fields = s->unknown_header_fields; + stashed_s->unknown_header_ext = s->unknown_header_ext; + +} + +static void qcow2_revert_state(BDRVQcowState *s, BDRVQcowState *stashed_s) +{ + s->cluster_bits = stashed_s->cluster_bits; + s->cluster_size = stashed_s->cluster_size; + s->cluster_sectors = stashed_s->cluster_sectors; + s->l2_bits = stashed_s->l2_bits; + s->l2_size = stashed_s->l2_size; + s->l1_size = stashed_s->l1_size; + s->l1_vm_state_index = stashed_s->l1_vm_state_index; + s->csize_shift = stashed_s->csize_shift; + s->csize_mask = stashed_s->csize_mask; + s->cluster_offset_mask = stashed_s->cluster_offset_mask; + s->l1_table_offset = stashed_s->l1_table_offset; + s->l1_table = stashed_s->l1_table; + s->l2_table_cache = stashed_s->l2_table_cache; + s->refcount_block_cache = stashed_s->refcount_block_cache; + + s->cluster_cache = stashed_s->cluster_cache; + s->cluster_data = stashed_s->cluster_data; + s->cluster_cache_offset = stashed_s->cluster_cache_offset; + s->cluster_allocs = stashed_s->cluster_allocs; + + s->refcount_table = stashed_s->refcount_table; + s->refcount_table_offset = stashed_s->refcount_table_offset; + s->refcount_table_size = stashed_s->refcount_table_size; + s->free_cluster_index = stashed_s->free_cluster_index; + s->free_byte_offset = stashed_s->free_byte_offset; + + s->lock = stashed_s->lock; + + s->crypt_method = stashed_s->crypt_method; + s->crypt_method_header = stashed_s->crypt_method_header; + s->aes_encrypt_key = stashed_s->aes_encrypt_key; + s->aes_decrypt_key = stashed_s->aes_decrypt_key; + s->snapshots_offset = stashed_s->snapshots_offset; + s->snapshots_size = stashed_s->snapshots_size; + s->nb_snapshots = stashed_s->nb_snapshots; + s->snapshots = stashed_s->snapshots; + + s->flags = stashed_s->flags; + s->qcow_version = stashed_s->qcow_version; + + s->incompatible_features = stashed_s->incompatible_features; + s->compatible_features = stashed_s->compatible_features; + + s->unknown_header_fields_size = stashed_s->unknown_header_fields_size; + s->unknown_header_fields = stashed_s->unknown_header_fields; + s->unknown_header_ext = stashed_s->unknown_header_ext; +} + static int qcow2_set_key(BlockDriverState *bs, const char *key) { BDRVQcowState *s = bs->opaque; @@ -1567,6 +1739,9 @@ static BlockDriver bdrv_qcow2 = { .instance_size = sizeof(BDRVQcowState), .bdrv_probe = qcow2_probe, .bdrv_open = qcow2_open, + .bdrv_reopen_prepare = qcow2_reopen_prepare, + .bdrv_reopen_commit = qcow2_reopen_commit, + .bdrv_reopen_abort = qcow2_reopen_abort, .bdrv_close = qcow2_close, .bdrv_create = qcow2_create, .bdrv_co_is_allocated = qcow2_co_is_allocated,