From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (mail.openvz.org [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id 160F58017D for ; Wed, 28 Oct 2026 12:43:03 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 69SCfjHj020018; Wed, 28 Oct 2026 15:41:46 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 69SCfjHj020018 Authentication-Results: mail.openvz.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="O8ii9ksS" Received: from mail-yx1-f72.google.com (mail-yx1-f72.google.com [74.125.224.72]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 69SCfhwL020014 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Wed, 28 Oct 2026 15:41:44 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 69SCfhwL020014 Received: by mail-yx1-f72.google.com with SMTP id 956f58d0204a3-6798c43a3bfso1793290d50.0 for ; Wed, 28 Oct 2026 05:41:44 -0700 (PDT) X-Forwarded-Encrypted: i=3; AKwUvBx7P8qsfIKunsFRk2fsetoTFgaUHQU47SmUWosgvZPjks2n9cyIe4q5wPnCyYl56LG7f/LmZQ==@openvz.org X-Gm-Message-State: AFq9FYKBUE5ywCEAruE38THkhbP4NevNNZ4fuJe8j6k9uHDbmO86DvOo zwyerjHtq888uboNcBPBs/EJXLHALhcUMqWOCx3bhs+j/3LE/3GGLBnjy51v4oHfpfulCNdWXDO IZP8/wl/YaizJPsPztKfxnTPepR+jTAF9WjAkI1eRyDgC2fNmsa8z9g== X-Gm-Gg: AYBFou1Y4EeAIh7iKN6FHkraecMctLmWDssC2IOh2E5b1K8b5E7syFgFARcGwS1FT7W vm3rthvhmE7cZcjkxEt6XTJAsLxlKYP6HViDF9C9gBGs2v0BeLg45aY01N96MsN/HbJ6/Wpfhlh Dq9DuthR62IpJG2YshtS93KQb0SSS73zVKl9GOcp4j6QCAVBL1gTRCnEfJSRSsQSX6IeaJB01lC HiAG2omX8ZvcAHS3l7YWX4GGM04L94tIu+qIpaVuRSRdnWC2x4IyLfscmpPrjQgyZbsjwifONJe Yq216P26u5nKhhT5YjzuuwiilXNRwS8L1cWFFnkshe16ouSNlCDKvYvpSN/ngS/kiWvxaowCEa4 FdS+QHxpnxTM0OfaQ3/Zjx0L++BW+MffdgTvku0f3R58AVr5/zEXDzEaxCKHC58f3o54x2yLZoP 2CSknnAQXjVndJLsu+7ngR87pf1Z5zK2tL X-Received: by 2002:a05:690e:4513:20b0:677:a8c0:38c6 with SMTP id 956f58d0204a3-67a7bc903ccmr966567d50.57.1793191302817; Wed, 28 Oct 2026 05:41:42 -0700 (PDT) X-Received: by 2002:a05:690e:4513:20b0:677:a8c0:38c6 with SMTP id 956f58d0204a3-67a7bc903ccmr966558d50.57.1793191302007; Wed, 28 Oct 2026 05:41:42 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1793191302; cv=pass; d=google.com; s=arc-20260327; b=qkT44CG/YzCy4bPfYLavDsj9goqe+dc0x3fUUAFwMOUctAbdGAyg8jZ9bWfVhLYLcS AF381yTLvo6w+emTT9UTd2R5kNvjCUtjnXCXyIB72Uq9R0DtXDlKSNzgB/qpZjkqMT8+ ntT7MadzZM+mCeCDoPo6hHPpYgQC3bKEKQNplfZBl26vT25Ea4FbNwJjakewJT1qAErp iv2mOf4JIwgEdq5BdfzlYHJiSXJIw0/yYz5rnV1Gs5P3wHnr3Md0VTrKe9PzTTA5sf0o MUQYtmTd4Tjaln3ti5F3jA8nw3h3kTxm7kV1o1RfWpr/EaH0Jco/8Ued2TAXuqsJLT1n MGIA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=mime-version:content-transfer-encoding:in-reply-to:from :content-language:references:cc:to:subject:user-agent:date :message-id:dkim-signature; bh=dgmliYhyyEdU4e6GlUaDZL0HOoCYPYUwfaeyKWaXP2A=; fh=asFCiatKj0KqxTdDrZobB2QMH0d8EY07vfO3ArLWY04=; b=JJDlnbGDJoMG4v1u55e04BGe/OfdG8+Fx2Ed/ZrBY7twGWrMqwOCd26sDS80dZc97e 1FT7AvISaqOwKA5LDQWtTAKAZ6XsXSV1diN31HMZxusOQNx+Gi4oCDJ2t3DoZ2pPa6lO pNy8BFF+g/u5dbZUHrhbDpFMG6yDRTQ/ouI8BKtnboarO5F+Gwpk65Ctj2I6qIBujK+w 2kBcp3wk2ZzsKYxiewhBHqeLQo3B4Zfb3aAQBzZ/VPGmqVUaYn8BAF43vSrYNSw3CWec gx8bLFCQTKQzNoZ1lLN9Z+DJAr8Q+WMr/qgXdQmj2aqj3Qd0r2Le4m5IM/7u7lHdjr+n U2NA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=selector2 header.b=O8ii9ksS; arc=pass (i=1 spf=pass spfdomain=virtuozzo.com dkim=pass dkdomain=virtuozzo.com dmarc=pass fromdomain=virtuozzo.com); spf=pass (google.com: domain of andrey.zhadchenko@virtuozzo.com designates 2a01:111:f403:c201::1 as permitted sender) smtp.mailfrom=andrey.zhadchenko@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com Received: from AM0PR83CU005.outbound.protection.outlook.com (mail-westeuropeazlp170100001.outbound.protection.outlook.com. [2a01:111:f403:c201::1]) by mx.google.com with ESMTPS id 956f58d0204a3-67a7a1069e6si2371438d50.220.2026.10.28.05.41.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Oct 2026 05:41:36 -0700 (PDT) Received-SPF: pass (google.com: domain of andrey.zhadchenko@virtuozzo.com designates 2a01:111:f403:c201::1 as permitted sender) client-ip=2a01:111:f403:c201::1; Authentication-Results: mx.google.com; dkim=pass header.i=@virtuozzo.com header.s=selector2 header.b=O8ii9ksS; arc=pass (i=1 spf=pass spfdomain=virtuozzo.com dkim=pass dkdomain=virtuozzo.com dmarc=pass fromdomain=virtuozzo.com); spf=pass (google.com: domain of andrey.zhadchenko@virtuozzo.com designates 2a01:111:f403:c201::1 as permitted sender) smtp.mailfrom=andrey.zhadchenko@virtuozzo.com; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=f4NzXD8HnnFT0sDWUtpV+wyheQ27ECNugVsfvSoZ5F44+9d0f432cQ8nE96bFjk0L+e54ZT1EDjFxtHo7XRb8VBEwyLao2Tf81VmYGwZxyt5Cft3E+Qmkz6zm8l8GnucQPVzTgV6eBLyX2UZZ+4ANthBU0nc+FAN//Re+jzv7z8j4sXxlw+vkuYePZ3ISSW89ZF8qXJdEBTd7Wob9Bx7DuOwUR6aEuxApGRBEjLrz3z8augkSUmm1MGnd2yeDukz1cYLv9eSBlw2WZbWzyg3SSE96OWRPw8Hik2xsswpj0lhvyKnuuux+p9suaDJgTUBITxI/Gpr5qu7rgG9EVO4hw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=dgmliYhyyEdU4e6GlUaDZL0HOoCYPYUwfaeyKWaXP2A=; b=RBiZ/oB9xUjSlv0/vuyBqOGU1NRgesrjTpldVC1giz4cikpotxmNqDYTgsgR+9GvRVRiJAICqVxbgnPQILAv3TMkNm1Oq75SHTR8HWWhxzSwT+DnE/HQOzFPx/k6NaU/XKz+cjslACBhiVUlfht6CmTBRdNbmHMOeerY4l+hOXU5bPbUguP2f6ag+IGhxid2jIhUDoLWm8KCUN7c6AvmHK9vbvjLAsnYazji3eAOKXA3LP0anXZpg3/QoAzVLOvOHpB0+SeP8QrRGaAwZ9kIdBQ7zJAG0xUpgGyjyhWt4Zd+L3X5tfG+AnoRM3JD1VNObW3/eJugjJaG6xoWzqu87A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=virtuozzo.com; dmarc=pass action=none header.from=virtuozzo.com; dkim=pass header.d=virtuozzo.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=dgmliYhyyEdU4e6GlUaDZL0HOoCYPYUwfaeyKWaXP2A=; b=O8ii9ksS4BOgZXuORztAq8N9EATTvyZ/fsSsbii4QngIwmX1WRAWGDrvuhUfgb85hkAjDKzlkO8wktdUY6Ffn2lUauOA7FKZlMhZC6S58SZz8lfZIGxh5EQhVZU6UjuEWUtzmcWnz5nYlFolbNqVVUIhzuZbeGt1m0eKtqXyrrC5KKa/aQfj1idhSQ+fYcu50PGwz7qKPnzbXAr3GuLZoub6RokEH+B1R8yD1qfz1VgTiguBf3TLmGYlfbQz2iswPcjegQ4CuByt40QH+13HyYnsLVPXvxKgc6q0IMle/dAD3N928Bne4JL5tCJ7G+f+hUpAzWXbkhoR4ZG4gHAnXg== Authentication-Results: mx.microsoft.com 1; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=virtuozzo.com; Received: from PA4PR08MB6061.eurprd08.prod.outlook.com (2603:10a6:102:e9::13) by AS4PR08MB7735.eurprd08.prod.outlook.com (2603:10a6:20b:512::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.546.22; Wed, 28 Oct 2026 12:41:33 +0000 Received: from PA4PR08MB6061.eurprd08.prod.outlook.com ([fe80::c3bf:e107:b1d2:6a00]) by PA4PR08MB6061.eurprd08.prod.outlook.com ([fe80::c3bf:e107:b1d2:6a00%3]) with mapi id 15.21.0569.007; Wed, 28 Oct 2026 12:41:33 +0000 Message-ID: <1cb89b5a-aad3-43c5-bc3a-7054bc3429c7@virtuozzo.com> Date: Wed, 28 Oct 2026 13:41:32 +0100 User-Agent: Mozilla Thunderbird To: Alexander Ivanov References: <20261026144223.2787145-1-alexander.ivanov@virtuozzo.com> <20261026144223.2787145-7-alexander.ivanov@virtuozzo.com> Content-Language: en-US From: Andrey Zhadchenko In-Reply-To: <20261026144223.2787145-7-alexander.ivanov@virtuozzo.com> X-ClientProxiedBy: FR4P281CA0425.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:d1::12) To PA4PR08MB6061.eurprd08.prod.outlook.com (2603:10a6:102:e9::13) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA4PR08MB6061:EE_|AS4PR08MB7735:EE_ X-MS-Office365-Filtering-Correlation-Id: e5aeeefd-ad0d-4562-edc3-08df34f0cc60 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|23010399003|1800799024|376014|366016|261026140227099003|56012099006|261021121427099003|4143699003|261022115727099003|261009221227099003|261022105027099003|261022075727099003|261021123027099003|261009223027099003|17002099007|22082099003|18002099003|261026121527099003|6133799003|10067099003; X-Microsoft-Antispam-Message-Info: Ji8/VkNjwS2Irfx1kYL5TmmkFqPZziZSVLIJdSQIWnmrN5wRMNjpjvsavbBZkeZj+bp/rsOx+2sPohiQyTX4aVnajr4bOEgaW/eOUy1vh3SSHegsDDz1N2q++18QKTXC06fFpzLQSHTSRWidFUC7vSMoibU2S8XRnfmf1RoZrFyWz2FbpIzEs6kzW4cVGygxU+LPcN2r4HX/cGnXOQ6pfAkhJCIBY4ZXAemx5FOJKaKDk/lFHM/QlyzX4HS6hCKkPB0J0XsKiTowLsS4ghA6BgS8+9cw3m1SGNxXijhGLWlqSzzel/z8PoPPCe7dm5/IcOQL9qtQJCsidzQtESwcVtuALhQQ53dDleE6XgI9xQikeIVZx+ep87LsRWdK+hLCb7+C2Gt5qkL4+MaUD2d4XkCczExpfCoUMj8tPzgxWyTJZWGlUcK9cnI1AMOl4znYY/Oun43I7FLdU07K3IwobZThWbTZhFNTz+8U5sa4t6e5ZrjH9JDmUuoJvJrYdNo/7PVpuiGaS0f+GUNyb8Sm41ZNtmJXMBZjjFOuH1oiAGpuLCwaQ9VsIwru+Wp5bfThKhaXgARyvmJp3cOpVFlf4oy7n3uuV6DmWa+he8WjGSOoGuNb88+XRXwnKhTGr+ve X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PA4PR08MB6061.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(23010399003)(1800799024)(376014)(366016)(261026140227099003)(56012099006)(261021121427099003)(4143699003)(261022115727099003)(261009221227099003)(261022105027099003)(261022075727099003)(261021123027099003)(261009223027099003)(17002099007)(22082099003)(18002099003)(261026121527099003)(6133799003)(10067099003); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?V3FKeHM4WXFHZk05WVplRUtJSHdxc1dNZW9MRFFxdWI5VWxPWlZKNXc3ZkdH?= =?utf-8?B?VXU1ek1VdXFLN0JVbnlyM3N1OTJobFRwOXNHNkljTWV5UzJwcjhQT21OSHNw?= =?utf-8?B?QTIxS21MU1pJOTNXNHpMTDdFbEhZdGttTThRSU96M1ExNmJ4Sm0rSWI4alJy?= =?utf-8?B?QTNvT0RiUGF1TE5iWFNqUVlibGZQc0xvVmdGYjQvOFpDS0YrOWQ5YWhuQUJi?= =?utf-8?B?RGxzQnRsTjh5VnJFOTJmT2VhQUpHZUY3Si9WSlJkUS9NZkRNRms1TnpPNEox?= =?utf-8?B?bFFLY3p6aG92bElmNURORit6VThIQ1RIWlpvVVRQOUVtaTZCck5wN3N3NzhK?= =?utf-8?B?MDZjNThGckRjQWdwYXpSU1U3M250VUUzaXhyKzlCaE85WE9tY002aTMwWmh5?= =?utf-8?B?RWJXK3pMRFd3S1RJQUVOS2lHV1dTRzRRL3IwcGhWWnVJcVVTSDNJSW9sVE9S?= =?utf-8?B?TlNIRE1YS0pxQ2pDOGpHMlZEaG5Ub2ZuTXBwUjN1d3g1NzI4VVdGM1dGdk0y?= =?utf-8?B?WGJ5d0pKanZEaGtCYUcrMWZPc3cvR3RSWFdWTWdCVGgrRXNmMnRkK2NXbXBQ?= =?utf-8?B?c3BZREk5bDE2S1FnNzhjdFdpL2ZwYXExOHA3SG9ncGtkVkJTQ0Z4LzFsaU13?= =?utf-8?B?Ty9iNXhQZE96NjZGc3p1TXFlU0NrRlNJSUZ0dWtLQlhmZUI1ZkxSalJTOGVI?= =?utf-8?B?NklPWFhXL3NYNVlKOE5VcTM4T0R4UVZKOHJFV2xjNDBCOC9xUTBWWVBHSmRw?= =?utf-8?B?d1VIWUZrT3dOMWlpUks5SVFTK0Z0WVplUnIyR05rcVp5b0p6UlduemFTRzIw?= =?utf-8?B?N3M4SlNta2w4QWhUUW54MHNad1pMQ3dDcEFoODhuRlNzamIzRVJWS0xzTnMz?= =?utf-8?B?V2IvK0orUTd2dWZPakd3MmRSc2pOMy81SHFKN0NnRDYrR1VxWC8vNnRRWW9K?= =?utf-8?B?cFdBVkxvU2FtYjlKUXlJR05oS1RnMzJCYjJ5bFJhVjkwK01tUjZoTFkxNUkz?= =?utf-8?B?UStJazF4YllWL09IempXMWhrc0FpUWVxV3JrbUF3WlhpdHAzQ0lIVHpDNGM3?= =?utf-8?B?THUzSktnbEUycVoxdEdyeXI3cXlWQkNPL0xuVG1uVXhobG9IMDBJNDJVZWw3?= =?utf-8?B?eDZOTmd1ckxKYTNzTlZKZml6bDRQclBkZkkya2VDL3NPUUFtWllkUjZqSzlq?= =?utf-8?B?QXRoRXJZYUQvZStqNm9naXlPVVZEQUtGMHcvaHp6a3BYQjdSVUZObXFLOUQr?= =?utf-8?B?RGJlZW1qQTB6bTFrdEZjSk0rOXlyOHJJUHJVR0wwc2Fhc2I2eXc2S0Q1TCtB?= =?utf-8?B?UXhZR295cnM4MTA3LzVsZVpVeG8xVlhkb0x2NFE0RDFkUVFzZ3lkZUNTVEVH?= =?utf-8?B?RkR4WWgwY0I2b2lyOHpJaDF6RXAwTmZ2QmVVT0t2MHg0b0h2OGFISlpXSExS?= =?utf-8?B?cFRYWFVQeSttL2w5bVdXNkNOeXkvQzAxMXIwbUVOdGZoWFFLTnBFdEFIVzYz?= =?utf-8?B?Mm9lbWs0VXNhck0wUVZ2dm5UdjRZNzNHQjdGRjNLNUJUSmU1OFFtaEgxbGRP?= =?utf-8?B?bnoyTVRoRlR6RWhPaC9EckxxQm9sK29NUUEydVdzeVFMQXkzRnYrVVkzL2Zu?= =?utf-8?B?aFU4NHBmOUJVY0xPZjNyMkJqT3l0enRncFovdXZYNUc4ZmxBN3N4bmp6UWpZ?= =?utf-8?B?Z1pFWEZZclhmeGw5d3VBMFZxb1REbWc2Rk5EYWpzcDYwOHJpaUVzaEl0aDBq?= =?utf-8?B?T0xMdkdpdmlham9uVU9wUThWRjJETUxCd25tcXYzRnZ2L0JWYUVyTFFiZjF6?= =?utf-8?B?OWc1U29yeHlNVldHTXNaaTg3MzVZTlAwcjFCVVBRdjd0K3JKNm5HblJIRStB?= =?utf-8?B?ZG45ZVlsRmNDY3lJdmNaYTZBYmJ4TXhlS1VxMGp1NnZZNzd4ZU1VS080Yko1?= =?utf-8?B?bWNGUFIrcVNNVGF3YTk0R0hNMmxNTXc0ZjhlNVJNZDJsaWV6UC9VeCtNNnc2?= =?utf-8?B?WTdZTkd4ZUtKRXNMYjNra2RLSER5U05SYkVQZkE3ZUVJUlk4WnEyUXYyUXNW?= =?utf-8?B?SFk3S01icTNZK2FVUzd3T09QRk9jQXluRWVuTDNhZkR6Z0FobkNyWUF4Wmhn?= =?utf-8?B?VjYxeVhSVnFleEIwTmphRWswWjFyajRoZTVBZ3NFRWF1dVVyVzhpK2ZiUTNW?= =?utf-8?B?RlpQSDUvYWVwV1JUdnFWaUNyeXUrbG5rVjJkRzlZblI5dDF2aTF3Y1BVSEhG?= =?utf-8?B?L25OMTQ5cFZkUE40TkliU0s1R1BSUEJieWN6WCtTaVpMSHBHaGZheXhBR24x?= =?utf-8?B?OUxvL1lZaEhXSDRGbmlQRGhtRWVUSmdkeUtGNVFNTVBoSUNkSFhPbm04eDNs?= =?utf-8?Q?exjuFJ5tZksiVmp0=3D?= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-Network-Message-Id: e5aeeefd-ad0d-4562-edc3-08df34f0cc60 X-MS-Exchange-CrossTenant-AuthSource: PA4PR08MB6061.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Oct 2026 12:41:33.7274 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 4nIdYKuHCuPNf/dS2XYeLnZ2OisVRYTxGU7yZlSRXAgHGZxB/R6sDvrcBVptrd2bIkAKb/cVeAzFLOf+vzui0nqJgQisL1DN8x+9IEnMVbc= X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS4PR08MB7735 X-OZ-Fwd: true Cc: devel@openvz.org Subject: Re: [Devel] [PATCH hci-8.1 v8 6/6] dm-qcow2: truncate unused tail of image on suspend X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org Patch should be split. l1/l2 revert tracking and relocation error are pre-existing problems and should be separated. On 10/26/26 15:42, Alexander Ivanov wrote: > Discard punches holes in place of freed clusters, so they hold no > physical extents, but it doesn't change the file size. On postsuspend > we truncate the image file only down to file_preallocated_area_start, > i.e. we drop preallocations only. So if clusters at the end of the > file are freed (refcount dropped to zero), the file size stays the > same and the image never shrinks. > > Add qcow2_calc_used_end(), which scans refcount blocks backward from > file_preallocated_area_start and returns the end of the last cluster > with non-zero refcount. Refcount ranges with no allocated refblock > are skipped at once. Metadata pages are taken from md cache or read > synchronously. This is called on suspended device after md writeback, > so R1 and R2 can't change under us. A failed relocation of the > reftable leaves file_preallocated_area_start beyond the space covered > by the reftable, so the scan starts at most from its end. If the > relocation fails after the new header is written, refcounts no longer > match the header, so set md_writeback_error there. > > Truncate the file to the used end. Fall back to the old behaviour on > scan error and after any failed md writeback. A failed R1/R2 write > leaves refcounts on disk stale. A failed L1/L2 write reverts the > refcount of a newly allocated cluster to zero, while L1/L2 on disk may > still point to it. Mark such an L1/L2 page with MD_LX_REVERTED and > clear the mark on its next successful writeback, which rewrites the > whole page, e.g. when a request delayed on ENOSPC is resubmitted. On > md writeback flush a still marked page sets a new lx_writeback_error > flag, which is reported in get_errors and logged when the scan is > skipped. The flag is lost on target reload, after which the scan would > trust the reverted refcount, so include it in wants_check like > md_writeback_error: resume is refused until the image is checked and > the target reloaded. > > Refcounts may also be below real usage after a crash, since both QEMU > with lazy_refcounts and this driver write L2 before refcounts. The scan > would then cut off clusters L2 still points to, even in a session > without guest writes. With kernel_sets_dirty_bit such an image has the > dirty bit set at open, and the disabled dirty bit check lets it be > opened RW, so skip the scan for it. Otherwise userspace sets the dirty > bit on every RW open, so the bit doesn't mean the image is > inconsistent. Userspace checks the image before opening it RW, which > find_unused_cluster() already relies on when it reuses clusters with > zero refcount. > > Close and reload to RO go through postsuspend too. On remove, > __dm_destroy() calls the presuspend and postsuspend hooks if the live > table isn't suspended yet. It neither stops the queue nor waits for > I/O, but the device is idle there, because dm_lock_for_deletion() > refuses to remove an open device. On table swap, do_resume() suspends > the old (RW) table before dm_swap_table(). So the file is shrunk in > these cases as well. > > https://virtuozzo.atlassian.net/browse/VSTOR-148171 > Feature: dm-qcow2: block device over QCOW2 files driver > > Signed-off-by: Alexander Ivanov > --- > drivers/md/dm-qcow2-cmd.c | 4 +- > drivers/md/dm-qcow2-map.c | 96 +++++++++++++++++++++++++++++++++--- > drivers/md/dm-qcow2-target.c | 38 +++++++++++--- > drivers/md/dm-qcow2.h | 6 ++- > 4 files changed, 127 insertions(+), 17 deletions(-) > > diff --git a/drivers/md/dm-qcow2-cmd.c b/drivers/md/dm-qcow2-cmd.c > index 2865940cff30..1520733c962c 100644 > --- a/drivers/md/dm-qcow2-cmd.c > +++ b/drivers/md/dm-qcow2-cmd.c > @@ -20,9 +20,9 @@ static int qcow2_get_errors(struct qcow2_target *tgt, char *result, > int ret; > > ret = DMEMIT("wants_check=%d\nmd_writeback_error=%d\ntruncate_error=%d\n" > - "merge_backward_error=%d\n", > + "merge_backward_error=%d\nlx_writeback_error=%d\n", > wants_check, tgt->md_writeback_error, tgt->truncate_error, > - tgt->backward_merge.error); > + tgt->backward_merge.error, tgt->lx_writeback_error); > > return ret ? 1 : 0; > } > diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c > index fa63bd6acfb8..c0669dc630b8 100644 > --- a/drivers/md/dm-qcow2-map.c > +++ b/drivers/md/dm-qcow2-map.c > @@ -1090,6 +1090,11 @@ static int calc_refcounters_map(struct qcow2 *qcow2, loff_t pos, > return -EIO; > } > > +static bool r1_entry_is_valid(struct qcow2 *qcow2, u64 entry) > +{ > + return !(entry & R1_RESERVED_ZERO_MASK) && CLU_OFF(qcow2, entry) == 0; > +} > + > static int calc_r2_page_id(struct qcow2 *qcow2, struct qcow2_map_item *r1, > struct qcow2_map_item *r2) > { > @@ -1097,8 +1102,7 @@ static int calc_r2_page_id(struct qcow2 *qcow2, struct qcow2_map_item *r1, > u32 bits = qcow2->refblock_bits; > loff_t pos; > > - if (WARN_ON_ONCE((entry & R1_RESERVED_ZERO_MASK) || > - (CLU_OFF(qcow2, entry) != 0))) > + if (WARN_ON_ONCE(!r1_entry_is_valid(qcow2, entry))) > return -EIO; > > /* The corresponding refcount block has not yet been allocated */ > @@ -1362,6 +1366,8 @@ static void revert_l_entries_update(struct qcow2 *qcow2, struct wb_desc *wbd) > if (cleared) > continue; /* no cluster was allocated */ > > + /* L1/L2 on disk may point to the cluster */ > + wbd->md->status |= MD_LX_REVERTED; > spin_unlock(&qcow2->md_pages_lock); > pos &= ~LX_REFCOUNT_EXACTLY_ONE; > > @@ -1385,6 +1391,8 @@ static void clear_writeback_status(struct qcow2 *qcow2, struct md_page *md, > lockdep_assert_held(&qcow2->md_pages_lock); > > md->status &= ~(MD_WRITEBACK|MD_WRITEBACK_ERROR); > + if (!ret) > + md->status &= ~MD_LX_REVERTED; > list_splice_init(&md->wait_list, wait_list); > if (ret && !md->wbd) { > /* > @@ -2201,6 +2209,74 @@ int qcow2_truncate_safe(struct file *file, loff_t new_len) > return do_ftruncate(file, new_len, 0); > } > > +/* > + * Returns the end of the last cluster, which is used according > + * to refcount table, clamped to file_preallocated_area_start since > + * the last cluster may be partial. Clusters freed by discard may > + * leave the tail of file unused. Everything at or above > + * file_preallocated_area_start is unused by construction, so the scan > + * starts below it. Failed relocate_refcount_table() leaves it beyond > + * reftable_max_file_size, so clamp the start to the reftable coverage. > + * This must be called on suspended device after md writeback, so > + * nobody changes R1 and R2. > + */ > +loff_t qcow2_calc_used_end(struct qcow2 *qcow2) > +{ > + u32 clu_size = qcow2->clu_size; > + struct qcow2_map_item r1, r2; > + struct md_page *r1_md = NULL; > + loff_t pos; > + s32 i; > + int ret; > + > + pos = min(qcow2->file_preallocated_area_start, > + qcow2->reftable_max_file_size); > + pos = round_down(pos - 1, clu_size); > + while (pos >= 0) { > + if (calc_refcounters_map(qcow2, pos, &r1, &r2) < 0) > + return -EIO; > + > + if (!r1_md || r1_md->id != r1.page_id) { > + ret = qcow2_md_page_read_sync(qcow2, r1.page_id, &r1_md); > + if (ret) > + return ret; > + } > + r1.md = r1_md; > + > + /* > + * The scan walks R1 entries normal I/O may never touch, > + * so don't let calc_r2_page_id() WARN on a corrupted one. > + */ > + if (!r1_entry_is_valid(qcow2, get_u64_from_be_page(r1_md->page, > + r1.index_in_page))) > + return -EIO; > + > + ret = calc_r2_page_id(qcow2, &r1, &r2); > + if (ret == -ENOENT) { > + /* No R2 cluster, so all clusters it covers are unused */ > + pos = (loff_t)r1.index * qcow2->refblock_entries * clu_size; > + pos -= clu_size; > + continue; > + } > + > + if (ret < 0) > + return ret; > + > + ret = qcow2_md_page_read_sync(qcow2, r2.page_id, &r2.md); > + if (ret) > + return ret; > + > + for (i = r2.index_in_page; i >= 0; i--, pos -= clu_size) { > + /* Last cluster is partial if size isn't cluster-aligned */ > + if (get_r2_entry(qcow2, r2.md, i)) > + return min_t(loff_t, pos + clu_size, > + qcow2->file_preallocated_area_start); > + } > + } > + > + return -EIO; > +} > + > static int truncate_prealloc_safe(struct qcow2 *qcow2, loff_t len, const char *func) > { > loff_t prealloc_len, max_prealloc_len = qcow2->reftable_max_file_size; > @@ -2372,21 +2448,21 @@ static int relocate_refcount_table(struct qcow2 *qcow2, struct qio **qio) > if (!WARN_ON_ONCE(!md)) > qcow2_md_make_dirty(qcow2, md, true); > if (!md) > - break; /* goto err_free_r2_pages */ > + break; /* goto err_hdr_written */ > } > spin_unlock_irq(&qcow2->md_pages_lock); > if (i != nr_pages) > - goto err_free_r2_pages; > + goto err_hdr_written; > > /* Connect new R2 to new R1 */ > for (i = end; i < r2_end; i += clu_size) { > if (calc_refcounters_map(qcow2, i, &r1, &r2) < 0) { > WARN_ON_ONCE(1); > - goto err_free_r2_pages; > + goto err_hdr_written; > } > ret = handle_md_page(qcow2, r1.page_id, NULL, &md); > if (WARN_ON_ONCE(ret <= 0)) > - goto err_free_r2_pages; > + goto err_hdr_written; > spin_lock_irq(&qcow2->md_pages_lock); > set_u64_to_be_page(md->page, r1.index_in_page, i); > qcow2_md_make_dirty(qcow2, md, true); > @@ -2397,7 +2473,7 @@ static int relocate_refcount_table(struct qcow2 *qcow2, struct qio **qio) > for (i = pos; i < r2_end; i += clu_size) { > ret = qcow2_handle_r1r2_maps(qcow2, i, NULL, &r1, &r2, false); > if (WARN_ON_ONCE(ret <= 0)) > - goto err_free_r2_pages; > + goto err_hdr_written; > mark_cluster_used(qcow2, r2.md, r2.index_in_page); > } > > @@ -2405,12 +2481,16 @@ static int relocate_refcount_table(struct qcow2 *qcow2, struct qio **qio) > for (i = old_pos; i < old_end; i += clu_size) { > ret = qcow2_handle_r1r2_maps(qcow2, i, NULL, &r1, &r2, false); > if (WARN_ON_ONCE(ret <= 0)) > - goto err_free_r2_pages; > + goto err_hdr_written; > mark_cluster_unused(qcow2, r2.md, r2.index_in_page, i); > } > > return 1; > > +err_hdr_written: > + /* Header on disk points to new R1, refcounts may be inconsistent */ > + QC_ERR(qcow2->tgt->ti, "failed to relocate refcount table"); > + qcow2->tgt->md_writeback_error = true; > err_free_r2_pages: > for (i = end; i < r2_end; i += clu_size) { > ret = handle_md_page(qcow2, i >> PAGE_SHIFT, NULL, &md); > diff --git a/drivers/md/dm-qcow2-target.c b/drivers/md/dm-qcow2-target.c > index 2d69e39a3530..7895fea531ae 100644 > --- a/drivers/md/dm-qcow2-target.c > +++ b/drivers/md/dm-qcow2-target.c > @@ -170,6 +170,7 @@ static void qcow2_free_md_pages_tree(struct rb_root *root) > void qcow2_flush_deferred_activity(struct qcow2_target *tgt, struct qcow2 *qcow2) > { > struct rb_node *node; > + bool wb_error = false; > struct md_page *md; > int i; > > @@ -191,13 +192,17 @@ void qcow2_flush_deferred_activity(struct qcow2_target *tgt, struct qcow2 *qcow2 > node; node = rb_next(node)) { > md = rb_entry(node, struct md_page, node); > /* FIXME: call md_make_dirty() and try once again? */ > - if (md->status & MD_WRITEBACK_ERROR) { > - QC_ERR(tgt->ti, "Failed to write dirty pages"); > - tgt->md_writeback_error = true; > - break; > - } > + if (md->status & MD_WRITEBACK_ERROR) > + wb_error = true; > + if (md->status & MD_LX_REVERTED) > + tgt->lx_writeback_error = true; > } > spin_unlock_irq(&qcow2->md_pages_lock); > + > + if (wb_error) { > + QC_ERR(tgt->ti, "Failed to write dirty pages"); > + tgt->md_writeback_error = true; > + } > } > > static void qcow2_flush_deferred_activity_all(struct qcow2_target *tgt) > @@ -1058,11 +1063,32 @@ static void qcow2_truncate_preallocations(struct dm_target *ti) qcow2_truncate_preallocations should be renamed. It does much more now. > { > struct qcow2_target *tgt = to_qcow2_target(ti); > struct qcow2 *qcow2 = top_qcow2_protected(ti); > - loff_t end = qcow2->file_preallocated_area_start; > + loff_t used_end, end = qcow2->file_preallocated_area_start; > int ret; > > if (!(dm_table_get_mode(ti->table) & FMODE_WRITE)) > return; > + > + /* > + * Refcounts don't match L1/L2 on disk after failed md writeback. > + * They may also be below real usage in an image opened dirty, > + * e.g. after a crash. If userspace sets the dirty bit, it is set > + * on every RW open and userspace checks the image before that. > + */ Useless comment that just repeats what code does. Why? > + if (tgt->md_writeback_error) { > + QC_INFO(ti, "Skip shrinking to used end after md writeback error"); > + } else if (tgt->lx_writeback_error) { > + QC_INFO(ti, "Skip shrinking to used end after reverted L1/L2 writeback"); > + } else if (kernel_sets_dirty_bit && qcow2->opened_dirty) { > + QC_INFO(ti, "Skip shrinking to used end of dirty image"); > + } else { > + used_end = qcow2_calc_used_end(qcow2); > + if (used_end < 0) > + QC_ERR(ti, "Can't find used end: %pe", ERR_PTR(used_end)); > + else > + end = used_end; > + } > + > if (end == qcow2->file_size) > return; > > diff --git a/drivers/md/dm-qcow2.h b/drivers/md/dm-qcow2.h > index a2d951ee5541..7db2d9301cad 100644 > --- a/drivers/md/dm-qcow2.h > +++ b/drivers/md/dm-qcow2.h > @@ -134,6 +134,7 @@ struct md_page { > #define MD_DIRTY (1U << 1) /* Page contains changes and wants writeback */ > #define MD_WRITEBACK (1U << 2) /* Writeback was submitted */ > #define MD_WRITEBACK_ERROR (1U << 3) /* Last writeback failed with error */ > +#define MD_LX_REVERTED (1U << 4) /* L1/L2 on disk may point to freed cluster */ > unsigned int status; > struct page *page; > struct list_head wait_list; > @@ -200,6 +201,7 @@ struct qcow2_target { > bool service_operations_allowed; > bool wants_suspend; > bool md_writeback_error; > + bool lx_writeback_error; > bool truncate_error; > bool event_enospc; > > @@ -413,6 +415,7 @@ void qcow2_ref_dec(struct qcow2_target *tgt, u8 ref_index); > int qcow2_inflight_ref_switch(struct qcow2_target *tgt); > void qcow2_flush_deferred_activity(struct qcow2_target *tgt, struct qcow2 *qcow2); > int qcow2_truncate_safe(struct file *file, loff_t new_len); > +loff_t qcow2_calc_used_end(struct qcow2 *qcow2); > > void qcow2_merge_backward_work(struct work_struct *work); > void qcow2_merge_backward_cancel(struct qcow2_target *tgt); > @@ -461,7 +464,8 @@ static inline bool fake_service_qio(struct qio *qio) > static inline bool qcow2_wants_check(struct qcow2_target *tgt) > { > > - return !!(tgt->md_writeback_error|tgt->truncate_error); > + return !!(tgt->md_writeback_error|tgt->lx_writeback_error| > + tgt->truncate_error); > } > > static inline bool qcow2_file_is_writable(struct qcow2 *qcow2) I would really advise againt commenting every action. The following example is the worst of the worst. /* If we have an error skip shrinking */ If (error) skip_shrinking() Please read Documentation/process/coding-style.rst section 8 (or have your agent read it). I am not planning to go on each comment in this patch, please do the pruning yourself. _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel