From patchwork Wed Jul 12 11:46:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Butsykin X-Patchwork-Id: 9836553 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 557C660363 for ; Wed, 12 Jul 2017 11:52:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 44455285F3 for ; Wed, 12 Jul 2017 11:52:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 38A9C285F5; Wed, 12 Jul 2017 11:52:54 +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 390C5285F1 for ; Wed, 12 Jul 2017 11:52:53 +0000 (UTC) Received: from localhost ([::1]:52023 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dVGCK-0006e3-EB for patchwork-qemu-devel@patchwork.kernel.org; Wed, 12 Jul 2017 07:52:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49423) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dVG79-00035D-4p for qemu-devel@nongnu.org; Wed, 12 Jul 2017 07:47:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dVG77-0003kF-FZ for qemu-devel@nongnu.org; Wed, 12 Jul 2017 07:47:31 -0400 Received: from mail-ve1eur01on0107.outbound.protection.outlook.com ([104.47.1.107]:46733 helo=EUR01-VE1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dVG73-0003eJ-7P; Wed, 12 Jul 2017 07:47:25 -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=QfEkLViFYyC6XQl9SzIf1phyumqOuzkrejeii+bxxbU=; b=bEOOj4c/Xl1PgRTcAruBf/8VTRMTdzHYewYnzrLRHIKQS7IwAfFJgq9JxWQgiPq5V7CYMFoBT9vqzY5dvyllCqwNxY6ZhDHv+aHR04uEjGB01DY5W+kme8jdKvWX+0tw26iVNjAu2qn/K61BhYZUvg8zhHuPyOoYVGeUnvbMQsI= Authentication-Results: nongnu.org; dkim=none (message not signed) header.d=none; nongnu.org; dmarc=none action=none header.from=virtuozzo.com; Received: from pavelb-Z68P-DS3.sw.ru (195.214.232.6) by DB6PR0802MB2551.eurprd08.prod.outlook.com (2603:10a6:4:a1::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1261.13; Wed, 12 Jul 2017 11:47:19 +0000 From: Pavel Butsykin To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Wed, 12 Jul 2017 14:46:59 +0300 Message-Id: <20170712114700.20008-4-pbutsykin@virtuozzo.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170712114700.20008-1-pbutsykin@virtuozzo.com> References: <20170712114700.20008-1-pbutsykin@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: AM5PR0201CA0023.eurprd02.prod.outlook.com (2603:10a6:203:3d::33) To DB6PR0802MB2551.eurprd08.prod.outlook.com (2603:10a6:4:a1::21) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 961cb7ad-1b8f-47c5-0328-08d4c91bc103 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(300000503095)(300135400095)(201703131423075)(201703031133081)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:DB6PR0802MB2551; X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 3:Q6RtIhiospbL/vRXEXMiHvEoKFA3K6aeCvsOw83isk1v6sPXprELPf9LJCeQaExrafDzgCnS5zQwRMjWdiFiw/9HRHIGuYhTdtYODyPoPcfxF6MYFiNzv+eJgBmeopyXqqCkDPmLY3EFEjN0+0L7gZ5XkuucJah/rXnQQNBIq7Li6a84LGKPqxXUg/LZbyMV2W6c3GThx9ovh0XgauT9jwXoeZr63n68/Y/e2ut42JSAH+mspsm80Pf/mZqN8KIKZ8NOw94O/bQhPuu78DhYAS0SfC+VHuZqkvH3oJxm+KvH7HiwNrLMqCpseNrD+XOlNzlZA3VMHp55dANhV95xZ9y1KEEHdu5Z4/wFGkaMjA6uqstYe6ymeyfSei1S3VtXpf0zyaYEyjENdGd+DimWe+JPXeArd5NA3m+6sh+e4kvbvQTr+TI03Q6ey/RxXqXgRteKH69Xce6f2WymwJeHYONVbZsuotjMY24je4phc00ObY5fZb0sxbSFmD6ShCNcg68nZDjJ4UZQbcyyLiFRz5UPzaLFMAGPTkOXOlqN7si7L8q0XMojGXJRL6Sgd5sY0EV50tB3TFxC8p38fgEi4FR6t+qsubuIiyqyzcnUE7U9nAIgtWXqOXQgyNqJrgV8yEozEnVlMbSO8R9Z6oe+e3gYAg9E/Vz8k5WqQvO8udMaIlbxuaiepFRWJsqYW0wboss7HUvjdGx1c+wDw4ce/6OEEeXWIqRThkMTDmmY8qc= X-MS-TrafficTypeDiagnostic: DB6PR0802MB2551: X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 25:QYuA9IcZAqO5H7QzIhjWe1UL9VEq/BtiG+7yvkuOS3MBEc7TTdhzRZyh7h6QUL8IrSfcrM3Yx70fhIKNxlwawPCBzXFD67aB4N8uTUnK9tYnJavcD1l6fJMaFhIU4huirYX33r7eUlOSqlYxOpqMqpyR9mJ6S0zXd9jHadx/XapqdrcFgigMW0k2Puhu80qXKGuPZ83Zh83DrJON3v4iRYAyJbpHarletZYz/iK9GeA3lzHAzTk6gVOtKS3S+fJbEOkBPhjfvCAVOAgVgbbdwkY2l0N8ISXey118g1hiCOhB4SQZlpHyjoB0fgFgTxejFWRsZXv9zMOIiM9s1yJ7L3ddL8cv2X0f05PJPcBY9FTlC8Y1hEL5G8y3b8yBBdyQ6dd8bVDIWV+92fn+PkpbrCcgS30nuVd03Fefy9T4LLkOTBTOQ13Eo5ROzGi0O2C4rDeFbVBwp6cRqCpgmNA+skoZIpIbSmXstfw6mI08tabi4qcHbvAfSCG+4OP0t79jxcZyAAYfGxTYrd27qnNjfa0Jaiick6CeH3lLUA7+9kdjnkqLC+xko6XqGNo7gBuhi52fUlgHi4+SkZnBEn0pEGr7fCCva60eLzT676wiGoyZm1eczgi5gj3Z6uPLGE8N+FNNWHvzNtf3zrc8c6QEIk+BShNhFzeEKCMSqjw0xtpLyx3ggfo08rDdeZuCCoASwubxuYTBwVhdEVn5BEBPPWISAe2Q75paDPQPN/TWXpYH31IPUbQARnlc5arHPsYuO2Jbh5hS5twyWTs0KP8vPXlgrWoWr3yTqhPYbRTHFg/B27tyj5Wt/DPpwaK7465ioDG02TifEdW1j56OLQMMnaExJIkgZqvqKhRLmy1vW9BomGZ7rhNkzAUWV5nIi/U3UONSdgF2HM3IQyUKHA02CngSx65+tGSHwuo+peGAqXw= X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 31:ufA95KEjzf5mXxnDIpqNbsLXUP6gSMbajrkVAr/3H/TmNwBbY8tFGdhEFNmKmmrpblHjGapUk3LDUqfH3lYjOqFztcRvTZzCdbpmj+gNCnkty5QTibSAX3ID9fuWLrh2PFpt+cEZC2ixlRvsRFcqnmgxwtQ6uOvvWb4Ztwf7Q8+ThBJPqSMJ3D7ek4uiYg+ve8fTTZWWYWLXgYxzqb327UUuMkhP0UhTo4cPd2ev0xo/iQ967bowOR7VMHDk33nLUT5tluAMaEPOp02N0CBTXkRpzW7bmnj6HaywUPdB4EiiMqSuyzYDTtNRvMeN5pl1p/CuEqM4hz2MjGB4qtFMGYZ37eeQl6uZsvVmIRu+N/KFyW7oYduVrtbROLfVMeQePv6WEtcyL9wbfyJJAXASwqiRw9MytnmMhHUCQwrRxgdBcNuf2aFYNzC+Ht6ZSbv+crNcy9xyy9FB8pWXFC1vEGVuoJLkZuZVHlCdOBEHJ3jG4Z+JVHTKi/h0jqboq27lMO0R9spP/dRFy8nXpRRLjr123pIrYM/0eOA6l5SNlDSiCbpE/xz/wYCdn39VbbV2j6YDTJL69VVttB/3BmlnxcU3duDva1Kjf2eMEI/q3En16kB8ri4umWVL6dhydRHDXQVUlOuJFi8QQE6wedJEA3PEUkJKA4dKCD7eeMDNa7I= X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 20:F7hWLqpfl0WCcb0D8/j8UNwc2NBcXv9ULb7OAizpOiS93vtaEH7itEcpwKZkPZ60bFb7JvfzTttnVClGHjwp3qYgo9+lHUDac4lAiDQH5xWmvIDKkfcPCDpilHQgLAnL+NQPmVp5oLqp1mCQQ+icXBomWJHl97sUhQyjXm51XBVAQg8GwR9gw4ORykBmSQ11xLmEsA9wPCIlPzfc6CelaByJ8w13TjZBxyL8F8wE0uVMdDun3n8Ox5sNDXqthuHJbVRKwG7J8RD3F8HoVPij5b/epDIjs3JcexhIJ7kNl3uCc3Rez59msPzVypU8sQS3zPvVZ83gGgRYUQd7AVQdtn+zTdzT3f2PmiejFDjI8HBaYMYA3VMQWSZWV6eUs1o3++tPhzIx6iTyT42SySzpUVoOiUXGhjg9cEG0wEBXAm0= X-Exchange-Antispam-Report-Test: UriScan:(133145235818549)(236129657087228)(148574349560750)(167848164394848); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(2017060910075)(5005006)(8121501046)(3002001)(10201501046)(100000703101)(100105400095)(93006095)(93001095)(6041248)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123562025)(20161123555025)(20161123564025)(6072148)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:DB6PR0802MB2551; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:DB6PR0802MB2551; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DB6PR0802MB2551; 4:IweZngWRHVwN10UrPju4ZGnkXpJTnlMNSzxmbNiD?= =?us-ascii?Q?JJeTcoFNbwKCw4qz1vAg9gKAjqSjnvonAamjdDNZuQqsBja1w2Ilf5ykuAzc?= =?us-ascii?Q?8xMiXAejybn42ZXVqSiOb0sp00N75SyBNGp0jruBhNvdxU/CgjlaOISTiNWc?= =?us-ascii?Q?0YJi0boTBErHcYYCAw7va9bOLukztAPVQ6iGRjklAXbH/q3TG5XP4jqnXcJu?= =?us-ascii?Q?VkI+wpEzbXs7AAbeLFvIdNRzPlThNGmBBifNvDcen7QUVlrmZMs1rt3FqcZR?= =?us-ascii?Q?G4pCym0BJ0fwmUBKW8vknH8YD+H0SGot/OPLw+1QuQ9mEcBG1Up9B06MrEt8?= =?us-ascii?Q?K+0S6XxIUbXQgo0k8THkRt5YikWX7otCrVePnZED4PUN4ZfIy+TJKRqTdzpF?= =?us-ascii?Q?oyavaDfg1fYKtlsJqWGIO1TvOg5q/kcZNNheHNRK1drfgIGKu9cJ4zz5o3Ur?= =?us-ascii?Q?ihBvRIniyA31Z8IJT66SPtEVtg0QbSlZ4dEZ2viqhjQQ7cRXEyTF/FGRntnF?= =?us-ascii?Q?jNbMA0Sogi0mHM4kCtn5FQ5+FA7G5/xiYyMpmafTGC5xL46cNyA9H+Tf3+yE?= =?us-ascii?Q?0xDn5ke6RD8Wf1zs3WQ4la7Lv0MmkQV+oAjUPwzju43A+Aoukn6PiFHSKTVV?= =?us-ascii?Q?AIHUsGen0IhE59xUtgXnoWzwALaFbD9zMF7K1RqRmpFdXdNzwXfLgtRMucjn?= =?us-ascii?Q?lvE2H8K5LZkg1uUL+DJQx6xYXkyq0LBmgrYgOdX7pkdiSVxwI2aaTKLA4bFy?= =?us-ascii?Q?+05V+IhiP7Xrd5p4GW62q+YoyxcYO1pS3u+iU52StZ0h4N7acvZdzqaXb8kv?= =?us-ascii?Q?/IUGuFkYS3+XVkko4TpL3EK0dbWEPPKfKDSeldSt1wMIoovWE0ST2lJSTKzj?= =?us-ascii?Q?fj6J+paXOMEuIjNRk3JWToL0zxPwKbMmqLMTP1UYne5UmQ5c/BYAqW+gYRAI?= =?us-ascii?Q?GlF1rw2DDn33Fy5p7M271s7wytUwQkvtc5Dxea2Xy3T++gnFTsVJ9TiJbKaS?= =?us-ascii?Q?trcVj/O10eR4ph2GomzdwHk0JtehqK8PeUPNNWGqziQzprULSYiZZm8BZisd?= =?us-ascii?Q?4PfSqQ4viI6sSivDgOX5VzKw/5tk3Uo0w8Q3+Eq52kJqp4kZgPyg518LLEb3?= =?us-ascii?Q?QnHTFF4W0OJzye0TywVJFPuSD66tmv1zP0GXRnzptVt2MGcBI9eX+ruPiYrQ?= =?us-ascii?Q?E/tkBm2mzpnv2lZ7bNe40tIXgO+hHe/NHYVqm72OiTgF6YIcInqSv1NwEAc+?= =?us-ascii?Q?mAnEOYehS5vco8geVjyS7N6hDolQT0W+c+9uGrKucah34bzj3//uo4UADJAJ?= =?us-ascii?Q?tGMHFc7xMXdPC5Xk18IfN+mhcTUhYtv0xFvhPeTR/wBB?= X-Forefront-PRVS: 036614DD9C X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(7370300001)(4630300001)(6009001)(39410400002)(39400400002)(39830400002)(39450400003)(6486002)(66066001)(478600001)(6512007)(81166006)(7736002)(4326008)(8676002)(3846002)(5660300001)(42186005)(86362001)(53416004)(1076002)(110136004)(33646002)(6116002)(53936002)(76176999)(50986999)(2906002)(38730400002)(107886003)(5003940100001)(36756003)(25786009)(6506006)(189998001)(50226002)(305945005)(50466002)(6666003)(47776003)(48376002)(2950100002)(7350300001); DIR:OUT; SFP:1102; SCL:1; SRVR:DB6PR0802MB2551; H:pavelb-Z68P-DS3.sw.ru; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DB6PR0802MB2551; 23:aB8PglrIy2Qhe6n+upKRDm27UfXE/HwlATcKOVq?= =?us-ascii?Q?KhHzbJcHvrinnsdt6TWppzKOHYHV2PHJCx2J7ryL8gB8nDnJ6i55XLmG5Opx?= =?us-ascii?Q?yNYXUiaoOkguxkVjWuL8P1g+C3MQGEzws7S0MFNpMab4OPz+kSi+660r8JIW?= =?us-ascii?Q?nTlRLvieTjDNVEqp/O27bs0VEemYLvniTnQKAuGapxteSKJM3e5EiraCy90r?= =?us-ascii?Q?yJfXrIP/8ZNpYnAjcXMCPC3O8gCnK35xurZAEQZZ1kpWuGWjLEJY/cc3T6Fc?= =?us-ascii?Q?MhpT+Ipkvk2cn6BnTP1NkA4naK5MbksBlCqZ/Xbj2jvcPGmW7lkMDKa/Rnw+?= =?us-ascii?Q?ZgbyzAQSYqJAe2ZQmR7nuvddkAZVBWgsY7AGrlDfhD4WOX0fvDfJYHz13Sbq?= =?us-ascii?Q?s5mN/gl90iFWJBTL9gFftkBsCeKwXiAcJVSFV3z6PhlXfKXtJTle4bztr7J/?= =?us-ascii?Q?xggFiedVJ170BQ2HoSntWi/GrUQ8FOd7/1PiMaGW7Jn9MsW3bH+Fnw05tpnu?= =?us-ascii?Q?qwl0y9QV3c4sYd0vbGXmaL+O5NHjycAq+UPDfLy1FyFdI7Ml5mwf6fC+QZ4N?= =?us-ascii?Q?1DBPNYP4FQaGikyeRLsR/v8s6K6deJyvPzkcxcP1nxWqYfC5s6czX/FiSQGh?= =?us-ascii?Q?JB45Qda+ih+KGBp6xMoZHRqPfTzUC2tE7sFSnFufGeynmd5caK0qyOOGPkFP?= =?us-ascii?Q?ETH6lYK4d5kW0e7vhA0D5XEKgqs7CQ2piQyb2re5AiJet5punD0qtvSCe7Qf?= =?us-ascii?Q?MiRPlQyXxYZAmprq7uXIn/dCI0THPDHCA+AQozuLJXuQ+jLPVJtIfIKOOzOB?= =?us-ascii?Q?jeRyWVSlmL0GACTeZv8b4WuEZct+yz7IhWQVSLn/SnaZSBceFvgSmY/n6iTb?= =?us-ascii?Q?yJYvR5X+mHsoRtB8JMIlmdLyiA2Ew10H10qzvY+jgkcZAWNQ473/EN0tcGHm?= =?us-ascii?Q?bra5mtkBaRTgJ1FbYHt7I6eIJTm/xMF0UUtJIB0P7lWDqyAVgCXittW7uTbR?= =?us-ascii?Q?lf8UmeztOjOuOPMKbD82lH1BfIJwTen2Av1e8EXaZIZ0DVvu3Z/lEECFBKip?= =?us-ascii?Q?DxZ/QI4+PgAG0cHDJnRYRVX+AeFxTAPTGzxjwQWPGl739sx6VLg=3D=3D?= X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DB6PR0802MB2551; 6:t8bWXSlal95ukOL4US4bl3mYEziNiWGtrBjL1Voq?= =?us-ascii?Q?AvQvLwrhVtnXXw0gfcmkXFJw31i6+923ZPiu+4lgRL0MAB38G+2ql8wnwptj?= =?us-ascii?Q?UCSyg5n2GNxcmN9ToN77qPyXlR+rY1RAxyb2N9nFtlyakjcJ972Jh/e55ubs?= =?us-ascii?Q?/bdPvdMxSEnDZUFJ05jiJfyUzpGsTHeG0rxPqEMr3gZHrvELn0pTpKJXy0Ee?= =?us-ascii?Q?m0DLXH0S+2kAHI6JiufQablrfeJ8Fv4KpTdhfQURXc99mCHSxeGoCwCOU4jE?= =?us-ascii?Q?rpRgJ1JJB76IR/GbAeevGgK3PkgsaaNbVoU3MVbFnhhteanihcA+ulTcxpcz?= =?us-ascii?Q?pG7VDQhALFaKHl+LJYq2QOREd/+znEyEHxe5sraIRA88qp7C4L2dZOmijeJj?= =?us-ascii?Q?KIlvp8ELjMyE/pponssbJVSBlC6JonYp2vvqZPQZbKAMdgt4xsXSciE6iKeV?= =?us-ascii?Q?FlV8//ADIQ6ITITmngXMJEVV0pz5Y61H/m2abiUq1Jh4k5fcrAH+77ygHlXc?= =?us-ascii?Q?tfuLb/vaTE5dyuVHpc3yh9AhB1eFCmRlON3JbpPJ5ESoZ72s+Xsv1l25lXZs?= =?us-ascii?Q?miRUQ40qhxVT3L1RXLB3A+JdbwegnZ0LXHpc2OnB6nJRFVr7IN/AuPfKWkh1?= =?us-ascii?Q?vYZPi1bchM+DdW4rba0wJqlAVPK2jemZzFA47KC6eiE+YH/v54k5zYX7lqSG?= =?us-ascii?Q?tA+V+DDOy149KlnXsvdJWYfSm7HVO/V2k1jaFrLQ/q8iW1T6d+Tms0tnZfr8?= =?us-ascii?Q?9e8uCVWcFYluSXdk7sIWTb32vHNkIdzG+OMDpv1hSILgT3TDVij8zZOxuEvo?= =?us-ascii?Q?+sqWP0gcjrTnI2ITZpQ0ALVvP+P9Iz4kbHvCB4DlE5p/mJ0MutJ/MebLX4hg?= =?us-ascii?Q?8vm73SL3COPm4JeApdNyc6g+vtdKe1LcFRIgL1U/57AO6YBEg/YWVG1LIx+O?= =?us-ascii?Q?ZnAGc/RqgmPoDhYl5fKmV18fn9JTcgEJbeW8wSdpUCYeo1JzZVpQbaEBPh+h?= =?us-ascii?Q?J8A=3D?= X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 5:oS7VwpgzTCWfMgQ8LML3+P04z7YKADDSsaj1PmQZSdv1nnt4tTBEaygoEND1ZGdQyjl/rsp+ubynMgel4CWYZMWgvrYJ7EEQdeuIfGBzZ84rMoe2AC/tGIl/MoJbAtSOdSmvhTz4oc5hmqSBPo9YM8eacF1gduAvdm4DxBwWCl8XCsVu0ZZDS6ycqS6CVJYZctiwYHZb5mZSQqPmX7Av/fsmC7MRe2mA0b4sIivanAC2xJpb0pE4767CiPYjNEyaCfsfwwF//nypIig4VMrysAKoL02furIG+iQLhPScxN6M2SBrHG2iWDKHQxGMJys4lm2n0LG8ZbYfu6pATu1sJXdLmj46A9xiK+Nq1rXM1aCQS6cHXd3TMn2kW9QytRdS+P7KsIzgshF+n2UWIAtt9C2xJpRhvOcaz0lOJBbvxE8jMfPUveJmRwPp1spOKnvbgKYoDhB+CR+6aWoWIj9kqNyoiAiLuxRvVZ9RwPZowtz39kP9Pxe5lKvN19EusM6g; 24:qnxJ35UuwRX6jpKWBSSgDJLQgFPTbdfl2pqEhno8yRNO2beNZYFPY5nOCTrtS5mp5jGbRFCODVt5VzoLZMCeDRDPB1aRsJqVxpzpfv1pGIM= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 7:rPUdx5WdeZqLctjEblAYDt0fTA4P/s7r0bAk5S2aTbS9534wQwn62Jg1uZqm5eJE+KxdPWNrueSCQjITJetmFg4P7KIfwQdE2J+LwTmL28/2LCZOX3Z14rRDJvMKx/06EoW3qZVNzAyJqJ5ETBeHPaaMoPTXYb1J+KDVDxIvHa8+wEwykxL51jRuut3WdS0L4eLUPiixJ9FxuP08J2LrVye4aT4/H02YyQRtJ98+x5u351IrL9aMv3nxg8joyuUXRYbbgJ4FcJW1qwAb7EDWuIW2hSdrnF1awSnyWnHGZTRpYk69i3+W5CYdz9ilyLx0R8zQxr6BrwCgZfeVW27mKqs2JCziH6JuyQoJ8dhnjYAEiGktg0KnGuf6r/kK2Bdhe70hDWouCCLlkUekufKtF2nOZHKfWQc/zYohQPFOD4FZBf1XKdBot7JLOUuaQVgpewbftganekl5ruuc9a4vJyMB1Ybt+5a9SVoAjrt1c/BjIZGAyHzokx6U1y2w49lCOIQ4OB2ad7etmPeuvKrRKPIOjcnrfY//Scoz7kVE1DZoUKsrJd2c1Qw4yARnH5pUVGTErBUz5jA1OI8sc1Thox0idrbSLZcfrKe1Fgfe4HxC0kaYtNR0HSHai7wB35pLdc9WS1yJCWmB+S6Y+/t5Zj9A+jI8zx8YgtL7/xbLFxxP7Ry69KgGl3ERDQfhWuf+e0JCvVlCNTayBQj4J55uOfz5+dYn4xP1n7m5kXgZOzG9ATVl1i6fWxqRD5aXxRw/ZciGZ96spvDVOZ2VAuuO5GknzIpgJdhfW95aYQxbKV4= X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2551; 20:ph5uS5EyppSKuvpTJhQsQBmAObVFOBqtZzNIwejcdH0lt9+C+oDsvAOnDNeNcsoTNqB6vmraooKSTU5/AghUdP2H6521K4JdmrFIaYJnbLvTLqPdjKwnqIQABVdZ9h2yqYlRhXMQ1bAX2LYQhhf6iAZ8R/FByx8EASctTRMVGLE= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jul 2017 11:47:19.8551 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0802MB2551 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.1.107 Subject: [Qemu-devel] [PATCH v5 3/4] qcow2: add shrink image support 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, pbutsykin@virtuozzo.com, armbru@redhat.com, mreitz@redhat.com, den@openvz.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch add shrinking of the image file for qcow2. As a result, this allows us to reduce the virtual image size and free up space on the disk without copying the image. Image can be fragmented and shrink is done by punching holes in the image file. Signed-off-by: Pavel Butsykin Reviewed-by: Max Reitz --- block/qcow2-cluster.c | 40 ++++++++++++++++++ block/qcow2-refcount.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++ block/qcow2.c | 43 +++++++++++++++---- block/qcow2.h | 14 +++++++ qapi/block-core.json | 3 +- 5 files changed, 200 insertions(+), 10 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index f06c08f64c..518429c64b 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -32,6 +32,46 @@ #include "qemu/bswap.h" #include "trace.h" +int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t exact_size) +{ + BDRVQcow2State *s = bs->opaque; + int new_l1_size, i, ret; + + if (exact_size >= s->l1_size) { + return 0; + } + + new_l1_size = exact_size; + +#ifdef DEBUG_ALLOC2 + fprintf(stderr, "shrink l1_table from %d to %d\n", s->l1_size, new_l1_size); +#endif + + BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_WRITE_TABLE); + ret = bdrv_pwrite_zeroes(bs->file, s->l1_table_offset + + sizeof(uint64_t) * new_l1_size, + (s->l1_size - new_l1_size) * sizeof(uint64_t), 0); + if (ret < 0) { + return ret; + } + + ret = bdrv_flush(bs->file->bs); + if (ret < 0) { + return ret; + } + + BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_FREE_L2_CLUSTERS); + for (i = s->l1_size - 1; i > new_l1_size - 1; i--) { + if ((s->l1_table[i] & L1E_OFFSET_MASK) == 0) { + continue; + } + qcow2_free_clusters(bs, s->l1_table[i] & L1E_OFFSET_MASK, + s->cluster_size, QCOW2_DISCARD_ALWAYS); + s->l1_table[i] = 0; + } + return 0; +} + int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, bool exact_size) { diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 8050db4544..5c8d606d29 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -29,6 +29,7 @@ #include "block/qcow2.h" #include "qemu/range.h" #include "qemu/bswap.h" +#include "qemu/cutils.h" static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size); static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, @@ -3059,3 +3060,112 @@ done: qemu_vfree(new_refblock); return ret; } + +int qcow2_shrink_reftable(BlockDriverState *bs) +{ + BDRVQcow2State *s = bs->opaque; + uint64_t *reftable_tmp = + g_try_malloc(sizeof(uint64_t) * s->refcount_table_size); + int i, ret; + + if (s->refcount_table_size && reftable_tmp == NULL) { + return -ENOMEM; + } + + for (i = 0; i < s->refcount_table_size; i++) { + int64_t refblock_offs = s->refcount_table[i] & REFT_OFFSET_MASK; + void *refblock; + bool unused_block; + + if (refblock_offs == 0) { + reftable_tmp[i] = 0; + continue; + } + ret = qcow2_cache_get(bs, s->refcount_block_cache, refblock_offs, + &refblock); + if (ret < 0) { + goto out; + } + + /* the refblock has own reference */ + if (i == offset_to_reftable_index(s, refblock_offs)) { + uint64_t block_index = (refblock_offs >> s->cluster_bits) & + (s->refcount_block_size - 1); + uint64_t refcount = s->get_refcount(refblock, block_index); + + s->set_refcount(refblock, block_index, 0); + + unused_block = buffer_is_zero(refblock, s->cluster_size); + + s->set_refcount(refblock, block_index, refcount); + } else { + unused_block = buffer_is_zero(refblock, s->cluster_size); + } + qcow2_cache_put(bs, s->refcount_block_cache, &refblock); + + reftable_tmp[i] = unused_block ? 0 : cpu_to_be64(s->refcount_table[i]); + } + + ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset, reftable_tmp, + sizeof(uint64_t) * s->refcount_table_size); + if (ret < 0) { + goto out; + } + + for (i = 0; i < s->refcount_table_size; i++) { + if (s->refcount_table[i] && !reftable_tmp[i]) { + uint64_t discard_offs = s->refcount_table[i] & REFT_OFFSET_MASK; + uint64_t refblock_offs = get_refblock_offset(s, discard_offs); + uint64_t cluster_index = discard_offs >> s->cluster_bits; + uint32_t block_index = cluster_index & (s->refcount_block_size - 1); + void *refblock; + + assert(discard_offs != 0); + + ret = qcow2_cache_get(bs, s->refcount_block_cache, refblock_offs, + &refblock); + if (ret < 0) { + goto out; + } + + if (s->get_refcount(refblock, block_index) != 1) { + qcow2_signal_corruption(bs, true, -1, -1, "Invalid refcount:" + " refblock offset %#" PRIx64 + ", reftable index %d" + ", block offset %#" PRIx64 + ", refcount %#" PRIx64, + refblock_offs, i, discard_offs, + s->get_refcount(refblock, block_index)); + qcow2_cache_put(bs, s->refcount_block_cache, &refblock); + ret = -EINVAL; + goto out; + } + s->set_refcount(refblock, block_index, 0); + + qcow2_cache_entry_mark_dirty(bs, s->refcount_block_cache, refblock); + + qcow2_cache_put(bs, s->refcount_block_cache, &refblock); + + if (cluster_index < s->free_cluster_index) { + s->free_cluster_index = cluster_index; + } + + refblock = qcow2_cache_is_table_offset(bs, s->refcount_block_cache, + discard_offs); + if (refblock) { + /* discard refblock from the cache if refblock is cached */ + qcow2_cache_discard(bs, s->refcount_block_cache, refblock); + } + update_refcount_discard(bs, discard_offs, s->cluster_size); + s->refcount_table[i] = 0; + } + } + + if (!s->cache_discards) { + qcow2_process_discards(bs, ret); + } + +out: + g_free(reftable_tmp); + return ret; +} diff --git a/block/qcow2.c b/block/qcow2.c index c144ea5620..bd281fdd04 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3120,18 +3120,43 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, } old_length = bs->total_sectors * 512; + new_l1_size = size_to_l1(s, offset); - /* shrinking is currently not supported */ if (offset < old_length) { - error_setg(errp, "qcow2 doesn't support shrinking images yet"); - return -ENOTSUP; - } + if (prealloc != PREALLOC_MODE_OFF) { + error_setg(errp, + "Preallocation can't be used for shrinking an image"); + return -EINVAL; + } - new_l1_size = size_to_l1(s, offset); - ret = qcow2_grow_l1_table(bs, new_l1_size, true); - if (ret < 0) { - error_setg_errno(errp, -ret, "Failed to grow the L1 table"); - return ret; + ret = qcow2_cluster_discard(bs, ROUND_UP(offset, s->cluster_size), + old_length - ROUND_UP(offset, + s->cluster_size), + QCOW2_DISCARD_ALWAYS, true); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to discard cropped clusters"); + return ret; + } + + ret = qcow2_shrink_l1_table(bs, new_l1_size); + if (ret < 0) { + error_setg_errno(errp, -ret, + "Failed to reduce the number of L2 tables"); + return ret; + } + + ret = qcow2_shrink_reftable(bs); + if (ret < 0) { + error_setg_errno(errp, -ret, + "Failed to discard unused refblocks"); + return ret; + } + } else { + ret = qcow2_grow_l1_table(bs, new_l1_size, true); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to grow the L1 table"); + return ret; + } } switch (prealloc) { diff --git a/block/qcow2.h b/block/qcow2.h index 52c374e9ed..5a289a81e2 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -521,6 +521,18 @@ static inline uint64_t refcount_diff(uint64_t r1, uint64_t r2) return r1 > r2 ? r1 - r2 : r2 - r1; } +static inline +uint32_t offset_to_reftable_index(BDRVQcow2State *s, uint64_t offset) +{ + return offset >> (s->refcount_block_bits + s->cluster_bits); +} + +static inline uint64_t get_refblock_offset(BDRVQcow2State *s, uint64_t offset) +{ + uint32_t index = offset_to_reftable_index(s, offset); + return s->refcount_table[index] & REFT_OFFSET_MASK; +} + /* qcow2.c functions */ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, int64_t sector_num, int nb_sectors); @@ -584,10 +596,12 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res, int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order, BlockDriverAmendStatusCB *status_cb, void *cb_opaque, Error **errp); +int qcow2_shrink_reftable(BlockDriverState *bs); /* qcow2-cluster.c functions */ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, bool exact_size); +int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size); int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index); int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, diff --git a/qapi/block-core.json b/qapi/block-core.json index c437aa50ef..99cef55b7c 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2487,7 +2487,8 @@ 'cluster_alloc_bytes', 'cluster_free', 'flush_to_os', 'flush_to_disk', 'pwritev_rmw_head', 'pwritev_rmw_after_head', 'pwritev_rmw_tail', 'pwritev_rmw_after_tail', 'pwritev', - 'pwritev_zero', 'pwritev_done', 'empty_image_prepare' ] } + 'pwritev_zero', 'pwritev_done', 'empty_image_prepare', + 'l1_shrink_write_table', 'l1_shrink_free_l2_clusters' ] } ## # @BlkdebugInjectErrorOptions: