From patchwork Fri Sep 4 17:01:15 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 33003 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bilbo.ozlabs.org (Postfix) with ESMTPS id 2E959B70B3 for ; Sat, 5 Sep 2009 03:04:21 +1000 (EST) Received: from localhost ([127.0.0.1]:39305 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MjcCv-0001dF-NL for incoming@patchwork.ozlabs.org; Fri, 04 Sep 2009 13:04:17 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MjcA7-0000ES-Hg for qemu-devel@nongnu.org; Fri, 04 Sep 2009 13:01:23 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MjcA2-0000BW-Of for qemu-devel@nongnu.org; Fri, 04 Sep 2009 13:01:23 -0400 Received: from [199.232.76.173] (port=39726 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MjcA2-0000B6-3p for qemu-devel@nongnu.org; Fri, 04 Sep 2009 13:01:18 -0400 Received: from verein.lst.de ([213.95.11.210]:36003) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA1:24) (Exim 4.60) (envelope-from ) id 1MjcA1-0007zh-9m for qemu-devel@nongnu.org; Fri, 04 Sep 2009 13:01:17 -0400 Received: from verein.lst.de (localhost [127.0.0.1]) by verein.lst.de (8.12.3/8.12.3/Debian-7.1) with ESMTP id n84H1FVL022989 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO) for ; Fri, 4 Sep 2009 19:01:15 +0200 Received: (from hch@localhost) by verein.lst.de (8.12.3/8.12.3/Debian-7.2) id n84H1FqR022988 for qemu-devel@nongnu.org; Fri, 4 Sep 2009 19:01:15 +0200 Date: Fri, 4 Sep 2009 19:01:15 +0200 From: Christoph Hellwig To: qemu-devel@nongnu.org Message-ID: <20090904170115.GA22964@lst.de> References: <20090904170052.GA22640@lst.de> Mime-Version: 1.0 Content-Disposition: inline In-Reply-To: <20090904170052.GA22640@lst.de> User-Agent: Mutt/1.3.28i X-Spam-Score: 0 () X-Scanned-By: MIMEDefang 2.39 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 1/5] block: add enable_write_cache flag X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add a enable_write_cache flag in the block driver state, and use it to decide if we claim to have a volatile write cache that needs controlled flushing from the guest. The flag is off if cache=writethrough is defined because O_DSYNC guarantees that every write goes to stable storage, and it is on for cache=none and cache=writeback. Both scsi-disk and ide now use the new flage, changing from their defaults of always off (ide) or always on (scsi-disk). Signed-off-by: Christoph Hellwig Index: qemu/hw/scsi-disk.c =================================================================== --- qemu.orig/hw/scsi-disk.c 2009-09-04 13:26:01.258522374 -0300 +++ qemu/hw/scsi-disk.c 2009-09-04 13:26:14.318522389 -0300 @@ -710,7 +710,9 @@ static int32_t scsi_send_command(SCSIDev memset(p,0,20); p[0] = 8; p[1] = 0x12; - p[2] = 4; /* WCE */ + if (bdrv_enable_write_cache(s->bdrv)) { + p[2] = 4; /* WCE */ + } p += 20; } if ((page == 0x3f || page == 0x2a) Index: qemu/block.c =================================================================== --- qemu.orig/block.c 2009-09-04 13:26:01.270522293 -0300 +++ qemu/block.c 2009-09-04 13:43:43.898522158 -0300 @@ -408,6 +408,16 @@ int bdrv_open2(BlockDriverState *bs, con } bs->drv = drv; bs->opaque = qemu_mallocz(drv->instance_size); + + /* + * Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a + * write cache to the guest. We do need the fdatasync to flush + * out transactions for block allocations, and we maybe have a + * volatile write cache in our backing device to deal with. + */ + if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE)) + bs->enable_write_cache = 1; + /* Note: for compatibility, we open disk image files as RDWR, and RDONLY as fallback */ if (!(flags & BDRV_O_FILE)) @@ -918,6 +928,11 @@ int bdrv_is_sg(BlockDriverState *bs) return bs->sg; } +int bdrv_enable_write_cache(BlockDriverState *bs) +{ + return bs->enable_write_cache; +} + /* XXX: no longer used */ void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque) Index: qemu/block_int.h =================================================================== --- qemu.orig/block_int.h 2009-09-04 13:26:01.310521931 -0300 +++ qemu/block_int.h 2009-09-04 13:26:14.318522389 -0300 @@ -152,6 +152,9 @@ struct BlockDriverState { /* the memory alignment required for the buffers handled by this driver */ int buffer_alignment; + /* do we need to tell the quest if we have a volatile write cache? */ + int enable_write_cache; + /* NOTE: the following infos are only hints for real hardware drivers. They are not used by the block driver */ int cyls, heads, secs, translation; Index: qemu/block.h =================================================================== --- qemu.orig/block.h 2009-09-04 13:26:01.314522160 -0300 +++ qemu/block.h 2009-09-04 13:26:14.318522389 -0300 @@ -120,6 +120,7 @@ int bdrv_get_translation_hint(BlockDrive int bdrv_is_removable(BlockDriverState *bs); int bdrv_is_read_only(BlockDriverState *bs); int bdrv_is_sg(BlockDriverState *bs); +int bdrv_enable_write_cache(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); int bdrv_is_locked(BlockDriverState *bs); Index: qemu/hw/ide/core.c =================================================================== --- qemu.orig/hw/ide/core.c 2009-09-04 13:26:01.266522204 -0300 +++ qemu/hw/ide/core.c 2009-09-04 13:32:31.046522461 -0300 @@ -148,8 +148,11 @@ static void ide_identify(IDEState *s) put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); /* 14=set to 1, 1=SMART self test, 0=SMART error logging */ put_le16(p + 84, (1 << 14) | 0); - /* 14 = NOP supported, 0=SMART feature set enabled */ - put_le16(p + 85, (1 << 14) | 1); + /* 14 = NOP supported, 5=WCACHE enabled, 0=SMART feature set enabled */ + if (bdrv_enable_write_cache(s->bs)) + put_le16(p + 85, (1 << 14) | (1 << 5) | 1); + else + put_le16(p + 85, (1 << 14) | 1); /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); /* 14=set to 1, 1=smart self test, 0=smart error logging */