From patchwork Thu Aug 25 13:44:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Butsykin X-Patchwork-Id: 9299417 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 45E8A60757 for ; Thu, 25 Aug 2016 14:03:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 362382930C for ; Thu, 25 Aug 2016 14:03:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2A7CA2933B; Thu, 25 Aug 2016 14:03:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 51DFD29334 for ; Thu, 25 Aug 2016 14:03:47 +0000 (UTC) Received: from localhost ([::1]:56462 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcvFy-0003Vx-4C for patchwork-qemu-devel@patchwork.kernel.org; Thu, 25 Aug 2016 10:03:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47222) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcuyg-0004QN-5Y for qemu-devel@nongnu.org; Thu, 25 Aug 2016 09:45:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bcuyb-0002HA-GB for qemu-devel@nongnu.org; Thu, 25 Aug 2016 09:45:54 -0400 Received: from mail-db5eur01on0136.outbound.protection.outlook.com ([104.47.2.136]:2656 helo=EUR01-DB5-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcuyT-0002D6-Hi; Thu, 25 Aug 2016 09:45:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=VAHwZwCDS11sGd7cUOkn8GEfayKDYgvZohgkwBUNFMs=; b=bfNSGzvlLpqe6TVj+7fhyebYYEHDYUiAKc7ZAhles+Z5L9ZX+2yuMuHqaxh7KOzd6KVBGLl1wshc6jVI5Mc5oLl6sgQSj5ztVoLipETD1FViX0Y22V/kueXvKQ5FTvtKvpM+c3mRJG10FW8NtWoXbLP/7BTIAVkbA7hz6Jw4PaQ= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pbutsykin@virtuozzo.com; Received: from pavelb-Z68P-DS3.sw.ru (195.214.232.10) by DB6PR0802MB2549.eurprd08.prod.outlook.com (10.172.251.147) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.587.9; Thu, 25 Aug 2016 13:45:38 +0000 From: Pavel Butsykin To: , Date: Thu, 25 Aug 2016 16:44:11 +0300 Message-ID: <20160825134421.20231-13-pbutsykin@virtuozzo.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160825134421.20231-1-pbutsykin@virtuozzo.com> References: <20160825134421.20231-1-pbutsykin@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.10] X-ClientProxiedBy: AMSPR02CA0013.eurprd02.prod.outlook.com (10.242.225.141) To DB6PR0802MB2549.eurprd08.prod.outlook.com (10.172.251.147) X-MS-Office365-Filtering-Correlation-Id: 8413c32b-3949-47db-92fe-08d3ccee19bc X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 2:+uZ4TNg1b0UTibg1ingdsBYqql6oVUuEvbpq29vzgP4qhUKQyWk6zGkm+EHCeh57RieN8kHdoFuLAvz0VZZKPtrw7SYUeW/JurR3J/e6PWg9sCU8TKwYIlCmOSETUflQo/qOMMsQSccJk89ENtGlDJ7j3hc4i0FNfk73KDwiJ5txXFigpSSmWTsbHEiOqoCj; 3:D812N3tfWaNWUrSmhg1Dwu+nFU1EJv/NXfesOv4NcDWz44uUnwn2buVwLNePNtm7tYslq2+4c/Efd1VnOxWBun0Ojxk3ISOoG+9QasSV/H1HLX2naXPHyC2YUZFt0zUR X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DB6PR0802MB2549; X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 25:sl9+ARgNJlAQ4tZCHeH+iHpqFudo5CBEsVC72dSF2Xr7H4fNeQfTEhhoJISLeN8wO/itVhDDwBoOPPLFynrqSJDYFWtuW3UqvuM6k6dq5NTflfRwLi+a22yX/QECzDmc8S+9UGuWTdc5HdHx4VWNCdYgfrADfP9xV0yyljQgV5pukrslm6POzfwgOaQ5/fDDbHUNdREmuKbBT7KGbDJA+wXITmCERh+O2ufKf9t/py0WgQAw4EDT8gLrYN/wA0XxgMQhuSI2RI1DYe2seUuThh+C57hSgo2X3/Yqi3w6NRs79C6Zv5wc6qYeRl9xATvHXlGdQOIi62prxS7ab0IJucR7FlnCTgBtUHBeMmyRT6FcUkjAEvqPmAx6UdejGT3jsGlh8tfwlHA6gsjqxiMnWnsQUAluc9BVZMqmdvl1MKOZNo0g4eIOpZ7fkjFpZtaLqOOQLHVFckHdtzPUdGhyomkTcuR4SRkfCj4qcy/J2EQOBNjp9wBaUu8AALouvrzTnYvFxzqe9fqWOT803je+o+h6Awsyz9tDBv9gBW2QDlYvmE4Z/fYrPW1Vi9Vj2uVHrDWiEMrSWoo2yzLxMTVyiFgUDKLX4p2v0X9Ize9SZpAJaO1BV/+QLPj+FyWWJmX8r0KXZSpYMtQl8ZShVD7Gdod6mGPcS9nN3OzGZ3dC+lMGwpURkadzUM18soj2H9KOi3ODzKPwhRTEzDlCUv1IIw==; 31:ro0uC6wGwjZQzEhh4hGJQm846uMn0pDPtVH8GHxjfstfXgZFBFdhTjmteIbpaf66cKwgC4dx8O3JOwFwyR6BOj2YnB6o2Eti1x4aC46quCgP82WhbYl077EYO/Zc7Km2IYXPpDFZDzwJeySKiqVYr6trzL4DWoFHF19PZYRRcxQw2YB4mPeaScafTCJTb3wmXiykW55ee8PgVj7ypq/JuGReI06YdRbBCcVHHWWB6K8= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6043046)(6042046); SRVR:DB6PR0802MB2549; BCL:0; PCL:0; RULEID:; SRVR:DB6PR0802MB2549; X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 4:TKMA21FJ8h3X2QlZyVWpF16Q2F2Hvv55fiDwHmDa4koOZLhyIzMmNl2muImJTNohfIpBxIux5dPQPz25jeS/W9dV9w7u3k+MIB2y401k43HvX12xZih8MWE+SLwKSGWIe7Zz8dn5esvvgGrXiiLKTwiLyep1nQyI/LUoY9ktC5OHF/o7TimiFg6gb5IIcPKzmHfyRMY7rcfvK5MLe/gOM+G3FlPEq6k2xz1DI4pBzU7cpn5l0NvYLB6+Rm+MKhFgSkRo8+8hV44/677mROBQUluTLNUSpumT+8o6MZmrhglSc2MSwEIp9wvV4HLjh6FcnQ50OYpmztw8TWyP4I30mamxytgdPkVGdqIcaZlFJleFCK+ZxS5I7UIZUcOXwpMlJhkbb9RW+peq6G9CX4dMtultoU2mDDgLf+LFMWQXof8= X-Forefront-PRVS: 0045236D47 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(86362001)(33646002)(1076002)(69596002)(5003940100001)(42186005)(68736007)(189998001)(92566002)(66066001)(106356001)(47776003)(6116002)(3846002)(586003)(36756003)(5001770100001)(97736004)(2906002)(4326007)(2950100001)(5660300001)(76176999)(48376002)(53416004)(105586002)(50466002)(81156014)(8676002)(50226002)(77096005)(81166006)(19580405001)(50986999)(229853001)(101416001)(7846002)(7736002)(305945005)(19580395003)(21314002)(217873001); DIR:OUT; SFP:1102; SCL:1; SRVR:DB6PR0802MB2549; H:pavelb-Z68P-DS3.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DB6PR0802MB2549; 23:0WengEZBrUj1i3of4xQklrx3yPUiZoj1bJDiNjN?= =?us-ascii?Q?bkRCF4ffsvGU1rDtOOOkymtGPYSQDfzLnE9Yrv37DWxjzyuXGbxWWtIOQjpr?= =?us-ascii?Q?+AQ+ED2x6siWgdHIB9oKvPS7bxpxp17OuvOp6M2NW/YV/IIw2e8vR4V15V9T?= =?us-ascii?Q?5DLToyYS6sugZj0mQvbM5+zPuRm9rdhL+4B4HbQjyY1phWd8H+WCERhGmIwH?= =?us-ascii?Q?c/dwIN/QX6Za6Ax7alroZ9cw1NIl3SZQCkHXIVv4TrLc8qc3vGsmVMnUDqRo?= =?us-ascii?Q?jlKqD5gxcLvIEQWVofid8/mmlF4gdftkL6P2+vhiv4HTCNOjsf+fOKOvlK5h?= =?us-ascii?Q?lhpMyNeWg3FYXDPMDX3tj1Tf1vZ2o1+VP0jhQN0ld6gEMrj1BWQbmp6bdTtD?= =?us-ascii?Q?j8ozyPlV+fUnKfXJ3Zl/WKDIgIeoc/Zhc1aXxOPCMxEoLGh0T8FWscCMrITl?= =?us-ascii?Q?Qk1EzKUO/tvjz+Xd+hE4pGKoqQr6VSip66Qlu5Gdi88zCMYGquCfEWibqcyq?= =?us-ascii?Q?WUFmk55jVBsEz2ivMO/hDNu4URm/Ji3We/ThBiiSedgBZ8QKURPB0hLwl5J9?= =?us-ascii?Q?ofRIytKvJ1Kfadn2kmhYnb6xeGt/7eREoxSNqCJl4NRPh4BQrd5Fb0rZd4dN?= =?us-ascii?Q?kYvTvBlQ5F4Zo7/hQlM5wwzbLAC8NQzIKCWRAH3rE4xaZJMZ8YCoevpaVzqX?= =?us-ascii?Q?7k94SY/JhxoJe+lSpoChiiLluE+mBJ1D7x1gOqC2RhWyiWFjXjzzGW0RK8gp?= =?us-ascii?Q?jSfTsLJiASoJchTkVBXsUgv1r97gOM6iwgsckstVhUflydl+WvLusCkmCJaC?= =?us-ascii?Q?R6cO7ogfq5R+uknkHJG5DxLte0ddtkeXGA2/ijQwjWUcWfMzuEHFBx0dg3U5?= =?us-ascii?Q?+pYj8qNKHHpSzlBRJ+cQFg8/iN8N/Y2/CSRiruMkH08n5v1BFf6VvyeeQ3kL?= =?us-ascii?Q?vxOH1D7SgviM228TnxATiYA+/5/WoMZAfp8RPbyE2yh7ioh63q6Kz5u8hTWA?= =?us-ascii?Q?96H2mXUWI4HXEIBVMKhp5Pl5Yb74u1rSWFzWrr8ZZUbnDNeuWI0cicvsndYx?= =?us-ascii?Q?ccMPbgOJN3fBsdmNFrKBbwxTQpFyQ3FnvxVJneGG33LM5RIsrcwGj3m2XJf7?= =?us-ascii?Q?Yw8/APkdPQHUESh1XuTilkA6XlXojyRnKMzmHBcL+1U3EP2UDR/aeZ2NoZHk?= =?us-ascii?Q?mO6beuFtC/rm2AKQ=3D?= X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 6:2ODjLpYHjRYDLVi5db6/Cm7uM9qyf1ACh/sHt14Sb8Pfe1XtNdKTDt7FeJl8kMi0wIeUQ1+q7lfQO4d5eKNx8FnSdx/HhZ6bTQ2jAGr/F9yeu9YCCjyqf97HoZHAfXNfq3H1bmWi+W+ykGXUkoROJymgom8Q4O4crgkUoNPlpxW5WpIQQ8q7WtHyRlGiZ50rMB7pwXSy40NUp09JUvl4TlP5s3y8pzI5QW2cW5MJ7Y3p+Ht+NOJGeRXXIEygxD4+S7sYMzNx3/VgCvfH2sBfwbC4BZzUZK9LFiMrwMM94Y1OWRhfi3iA4BGmSKFhSuKM; 5:83roh402rjt/K58U25V9yrAcRf5KZoEBeZZct4qG6+HsZ2fLK/0OYPbbi00pCpAebml+m/OmZo8HpxDIav4Erq3C24ip2gIH86BFz3NZHsQoCJF/vpzCTMLZWeHZQ6IbzFs+HMxaa1Ho5yZMvFSl2Q==; 24:VxgQoSBU6+/nesRzcoWXgIPb9loJYVXTNM++bdSS6uw97yta8K5S29OD3pi6rDZHouAxMfNO5JUWsE6mQga5ViGyy9C1N5I+fN7b8sl2JYE=; 7:90L4XlPeEMkliIAFhWAHTCwBk8cWdpdk2YZp85JkQvjhLncJqNvrdctiksZdaVl/1CLgkAwmHtVm1oAd3iA7NqiLGdBO7eQTWosh3WAWaQ/VzTAO0PokTNSajgr/EUWT6rabYZVgWuoJFPw7/GxLlWebVL6DbsfeBXDvMcRkCB75pLyCQIIdobUk8raFGDpbGAU3VlxLiN55vvcKe/AJXMdyl2jHj9rPz/huAx2UjGGLad0eXv5DbsQFMe7Ddbr2 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 20:tDk25AfzAk2a5AMfVx8jBpFzZYsRuwZ6tQfB2EUsibTlIUCrQulY7MasHSdfya1dA+s4hb23Tz6hnTRhCfqehUB2AjSmKtx2BgoJFmY4PtNu3qfYYtDqW6ulRpdLmgC8bCU38dGX6pUZJKuyESghjJt9/599I2Un0Ol9XTug0vk= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Aug 2016 13:45:38.6946 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0802MB2549 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.2.136 Subject: [Qemu-devel] [PATCH RFC 12/22] block/pcache: implement read cache to qiov and drop node during aio write X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, den@openvz.org, jsnow@redhat.com, stefanha@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP After applying this patch aio read can pick up data from the pcache. for correct driver work added 3 things: 1. Filling the qiov out of the cache. 2. Request completes. This is necessary to inform the upper level, that the data for the request has already been obtained. 3. Cache Invalidation in the aio write requests. This is a simple way to keep the cache up-to-date. Signed-off-by: Pavel Butsykin --- block/pcache.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 118 insertions(+), 8 deletions(-) diff --git a/block/pcache.c b/block/pcache.c index a8a57e3..435f2b4 100644 --- a/block/pcache.c +++ b/block/pcache.c @@ -103,7 +103,9 @@ typedef struct PrefCacheAIOCB { struct { QTAILQ_HEAD(req_head, PrefCachePartReq) list; CoMutex lock; + uint32_t cnt; } requests; + QEMUBH *bh; int ret; } PrefCacheAIOCB; @@ -217,6 +219,27 @@ static BlockNode *pcache_node_prev(BlockNode* node, RbNodeKey *key) return node; } +static void *node_search(struct RbRoot *root, RbNodeKey *key) +{ + struct RbNode *rb_node = root->rb_node; + + while (rb_node) { + BlockNode *node = container_of(rb_node, BlockNode, rb_node); + int32_t result = pcache_key_cmp(key, &node->key); + if (result == 0) { + return pcache_node_prev(node, key); + } + rb_node = result < 0 ? rb_node->rb_left : rb_node->rb_right; + } + return NULL; +} + +static PCNode *pcache_node_search(struct RbRoot *root, RbNodeKey *key) +{ + PCNode *node = node_search(root, key); + return node == NULL ? NULL : pcache_node_ref(node); +} + static void *node_insert(struct RbRoot *root, BlockNode *node) { struct RbNode **new = &(root->rb_node), *parent = NULL; @@ -320,6 +343,8 @@ static inline void push_node_request(PrefCacheAIOCB *acb, PCNode *node) { PrefCachePartReq *req = pcache_req_get(acb, node); + acb->requests.cnt++; + QTAILQ_INSERT_HEAD(&acb->requests.list, req, entry); } @@ -360,6 +385,38 @@ static bool pcache_node_find_and_create(PrefCacheAIOCB *acb, RbNodeKey *key, return true; } +static uint64_t ranges_overlap_size(uint64_t node1, uint32_t size1, + uint64_t node2, uint32_t size2) +{ + return MIN(node1 + size1, node2 + size2) - MAX(node1, node2); +} + +static void pcache_node_read(PrefCacheAIOCB *acb, PCNode* node) +{ + uint64_t qiov_offs = 0, node_offs = 0; + uint32_t size; + uint32_t copy; + + if (acb->sector_num < node->cm.sector_num) { + qiov_offs = (node->cm.sector_num - acb->sector_num) << BDRV_SECTOR_BITS; + } else { + node_offs = (acb->sector_num - node->cm.sector_num) << BDRV_SECTOR_BITS; + } + size = ranges_overlap_size(acb->sector_num, acb->nb_sectors, + node->cm.sector_num, node->cm.nb_sectors) + << BDRV_SECTOR_BITS; + + assert(node->status == NODE_SUCCESS_STATUS || + node->status == NODE_REMOVE_STATUS); + assert(node->data != NULL); + + qemu_co_mutex_lock(&node->lock); + copy = \ + qemu_iovec_from_buf(acb->qiov, qiov_offs, node->data + node_offs, size); + assert(copy == size); + qemu_co_mutex_unlock(&node->lock); +} + static inline void prefetch_init_key(PrefCacheAIOCB *acb, RbNodeKey* key) { key->num = acb->sector_num; @@ -388,7 +445,7 @@ static void pcache_pickup_parts_of_cache(PrefCacheAIOCB *acb, PCNode *node, size -= up_size; num += up_size; } - /* XXX: node read */ + pcache_node_read(acb, node); up_size = MIN(node->cm.sector_num + node->cm.nb_sectors - num, size); pcache_node_unref(acb->s, node); @@ -429,13 +486,28 @@ static int32_t pcache_prefetch(PrefCacheAIOCB *acb) node->cm.sector_num + node->cm.nb_sectors >= acb->sector_num + acb->nb_sectors) { - /* XXX: node read */ + pcache_node_read(acb, node); pcache_node_unref(acb->s, node); return PREFETCH_FULL_UP; } pcache_pickup_parts_of_cache(acb, node, key.num, key.size); - return PREFETCH_PART_UP; + return acb->requests.cnt == 0 ? PREFETCH_FULL_UP : PREFETCH_PART_UP; +} + +static void pcache_aio_bh(void *opaque) +{ + PrefCacheAIOCB *acb = opaque; + qemu_bh_delete(acb->bh); + acb->common.cb(acb->common.opaque, 0); + qemu_aio_unref(acb); +} + +static void complete_aio_request(PrefCacheAIOCB *acb) +{ + acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs), + pcache_aio_bh, acb); + qemu_bh_schedule(acb->bh); } static void pcache_node_submit(PrefCachePartReq *req) @@ -471,7 +543,7 @@ static void pcache_merge_requests(PrefCacheAIOCB *acb) pcache_node_submit(req); - /* XXX: pcache read */ + pcache_node_read(acb, req->node); pcache_node_unref(acb->s, req->node); @@ -480,11 +552,36 @@ static void pcache_merge_requests(PrefCacheAIOCB *acb) qemu_co_mutex_unlock(&acb->requests.lock); } +static void pcache_try_node_drop(PrefCacheAIOCB *acb) +{ + BDRVPCacheState *s = acb->s; + RbNodeKey key; + + prefetch_init_key(acb, &key); + + do { + PCNode *node; + qemu_co_mutex_lock(&s->pcache.tree.lock); + node = pcache_node_search(&s->pcache.tree.root, &key); + qemu_co_mutex_unlock(&s->pcache.tree.lock); + if (node == NULL) { + break; + } + + pcache_node_drop(s, node); + + pcache_node_unref(s, node); + } while (true); +} + static void pcache_aio_cb(void *opaque, int ret) { PrefCacheAIOCB *acb = opaque; if (acb->aio_type & QEMU_AIO_READ) { + if (atomic_dec_fetch(&acb->requests.cnt) > 0) { + return; + } pcache_merge_requests(acb); } @@ -503,6 +600,7 @@ static PrefCacheAIOCB *pcache_aio_get(BlockDriverState *bs, int64_t sector_num, acb->s = bs->opaque; acb->sector_num = sector_num; acb->nb_sectors = nb_sectors; + acb->requests.cnt = 0; acb->qiov = qiov; acb->aio_type = type; acb->ret = 0; @@ -522,10 +620,21 @@ static BlockAIOCB *pcache_aio_readv(BlockDriverState *bs, { PrefCacheAIOCB *acb = pcache_aio_get(bs, sector_num, qiov, nb_sectors, cb, opaque, QEMU_AIO_READ); - pcache_prefetch(acb); - - bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, - pcache_aio_cb, acb); + int32_t status = pcache_prefetch(acb); + if (status == PREFETCH_FULL_UP) { + assert(acb->requests.cnt == 0); + complete_aio_request(acb); + } else { + PrefCachePartReq *req; + assert(acb->requests.cnt != 0); + + qemu_co_mutex_lock(&acb->requests.lock); + QTAILQ_FOREACH(req, &acb->requests.list, entry) { + bdrv_aio_readv(bs->file, req->sector_num, &req->qiov, + req->nb_sectors, pcache_aio_cb, acb); + } + qemu_co_mutex_unlock(&acb->requests.lock); + } return &acb->common; } @@ -538,6 +647,7 @@ static BlockAIOCB *pcache_aio_writev(BlockDriverState *bs, { PrefCacheAIOCB *acb = pcache_aio_get(bs, sector_num, qiov, nb_sectors, cb, opaque, QEMU_AIO_WRITE); + pcache_try_node_drop(acb); /* XXX: use write through */ bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, pcache_aio_cb, acb);