From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from AM0PR02CU008.outbound.protection.outlook.com (mail-westeuropeazon11023103.outbound.protection.outlook.com [52.101.72.103]) by lore.virtuozzo.com (Postfix) with ESMTPS id 3CDF980474 for ; Mon, 26 Oct 2026 17:49:38 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=KBBHqpx8er4kgjyikbywPapTZQKYpRJMwPLzN6Rcbm8V0rcyktsH+oGeFaP5G31ZvdGJYM8JQ1zB+0E1Z1VLKtGGt6Q72SBRBq8nYnwz8cckZfHgWZYXO6jdgGFF9AT3gMhkvbz/QjWTyha9E+voSev6/rz0lFhRKBtZ/VDKIM2v0Ut+cEa4J6T+69xEj6lk79JflIVzB9UTJEzwS6ATiK4NHEzSeNbbcOncNe2EJGACGsu/vYuLrggBODViaG88uUNyLaoY5eOBbqh/L4jlQnc6TJXYXbOtBjOKnV70PsGjpahUzebStnhCsIDORr1jh7HKi2j2Q2RfdWsER+0mAA== 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=KTXU8asn+MdU9+q2nWHCz8TctKqInKR/1NSlKr8WbEU=; b=YKqpNNHPIbXNdwT7qdxFRg7BXRlXB6Lztv3e7JaagXsOUk6kZOtr/FPGwivYTSdTyY1dhRO7GXfb6rrZE6AfJAEk4lTNyCKNkZy5TrZbFRjrcVj3KML97gxwW4ulzywO6w2e5IvjwLeJ9lmDYcADAliyCtOiyRo0t+XF1jbe4dtTRt/NekkvvecgFBIMbRlIFwB3qWsmlAmJoYJVwlcngwuva2BSJTVtI6uu89RC37K6k55S1P2yEfgphOh/HC8k8vvLrviXQtrvGjTrfkcsnL9hxpD9BMwon07g/D4KcR9gDbn2dsqJcLwy7dRGfUQRawIK1NhB4d5vwoEx3w4UKQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 2a00:1450:4864:20::335) smtp.rcpttodomain=virtuozzo.com smtp.mailfrom=openvz.org; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=openvz.org; dkim=pass (signature was verified) header.d=openvz.org; arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.onmicrosoft.com; s=selector2-virtuozzo-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KTXU8asn+MdU9+q2nWHCz8TctKqInKR/1NSlKr8WbEU=; b=bDZowW0/AzRuH0JF8l4oYFXaOarl+dxMmCNxJfJ04AbundtX5ngQ5sN834X8rLgDdS9RBexRPthoQO+Br/EDEnUpUYw6UvCHOJqff4YxBo+cLIsH0OoZoAJxLyvScael/Pk0MYaboHH6qWoYBvO/BtnuTweNfDbQ0N67MUsOhWM= Received: from DB8PR04CA0001.eurprd04.prod.outlook.com (2603:10a6:10:110::11) by AMVPR08MB11999.eurprd08.prod.outlook.com (2603:10a6:20b:776::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.546.22; Mon, 26 Oct 2026 17:49:34 +0000 Received: from DU2PEPF00028D13.eurprd03.prod.outlook.com (2603:10a6:10:110:cafe::9b) by DB8PR04CA0001.outlook.office365.com (2603:10a6:10:110::11) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.546.22 via Frontend Transport; Mon, 26 Oct 2026 17:49:34 +0000 Authentication-Results: mx.microsoft.com 1; spf=pass (sender IP is 2a00:1450:4864:20::335) smtp.mailfrom=openvz.org; dkim=pass (signature was verified) header.d=openvz.org;dmarc=pass action=none header.from=openvz.org; Received-SPF: Pass (protection.outlook.com: domain of openvz.org designates 2a00:1450:4864:20::335 as permitted sender) receiver=protection.outlook.com; client-ip=2a00:1450:4864:20::335; helo=mail-wm1-x335.google.com; pr=C Received: from mail-wm1-x335.google.com (2a00:1450:4864:20::335) by DU2PEPF00028D13.mail.protection.outlook.com (2603:10a6:18:3::6cb) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.569.4 via Frontend Transport; Mon, 26 Oct 2026 17:49:34 +0000 Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-4a1df4c0966so1161435e9.1 for ; Mon, 26 Oct 2026 10:49:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1793036973; x=1793641773; darn=virtuozzo.com; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=KTXU8asn+MdU9+q2nWHCz8TctKqInKR/1NSlKr8WbEU=; b=OVRx2hhMj5xNP0+ha32e0EuumRTW721qIXh7WfgzRF+Z6U2VDi/utE9+HJ5qm9dsyK oPOnNnpmX2EPWLR0EGEWCNeK/JeKLg4iBnKOOp1FWZnD/Iuuhq842hDFl3eoWpjzSTWq WKMTK1PbB5MVQNbq7tLO5gscjk5QfcXL4KjkOlJIV+gaUS6jtloaG7ui4QGTCzdKxsVR AEvJ9aWzu5FZG9/3nDHDajW6FnELpsBg+lpEWI7WVS4egR2g9KiVJU/cYSqQtehg8Rfa hvgL4pyz09XR8B0aw9pXwG65rmDQUrsTLUE5uACv0Sm/1pkVV/Q1UUU38a/fjjZ4BIqy 5sjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793036973; x=1793641773; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=KTXU8asn+MdU9+q2nWHCz8TctKqInKR/1NSlKr8WbEU=; b=nUOmH+BaDZQoEvWvHVTyW5n7TAxnPKJWrLSZkdVpy7WtsFfMjLVofkW1SGym1aSDw2 hzNKvQi3g/7oDdwSVKT0cDN/qQLorv4+Do8AgwlBJY+TAtbwn/Cz5XtEGsYTgrNFjYmh lrghFN+GitK4Qxu+LwrvsughKsrIxVm2+EiKNntIMfz8HbcF2DAcBUr2QW8R4XivupPC mkOtkbGXSyOf7U5e+iWACHuyLWqDhlFNenzL9MNq/UZRKLu/kb99anxarXc0KnaHrNFY jnKJJjWrXoilxE7Vz6eQbQcrGMctxOYHKK67isWZumsLCyM5vKx0d7fKklzWofkJ9N0D fd0A== X-Gm-Message-State: AFq9FYIBumGpLRYPZOr1cu575F4aSQt+HCEFKkbBDrAQ2jfJZkI4l3pI DW3wLuLKq5J4VheXOocNiBdZT5WVcZ+8yIbpBG5r6U50UfpmGs4cWWU03pZIlLY89/g2Cg== X-Gm-Gg: AYBFou2fWFksV8eywOHXBWqX8KhN1LOJNPHLwiH+zUjb+wyvt1RcuwtfRAcoPczL7z/ 8nNAkSbubrLfR/whOyNuAyleeOI4RbCgz9iCfuVzZNeHvrpSNZYezlk9CdpbrAGDPcZcayUtmFb vnTtRE3LcuVv6lob+pKcTOYVntrjlJk3sgNzNcwdMn1mpFe4qtrz+fQhzLGkaCkbiHLnlcF6MLQ 9wM0YQ7HvnbRo3NRB8jkfJZ73JG1EFJjfmA1nlE3cjh+Fag3VvLIfVLO9dtveneH69JGF8RqlkB oSD01VjMLUeCWqmtkwCrEFGYd/aPsdR9ZUsnyrIveKaRthM3YTm17A9k8L1zLf4krOBwQivT/7X XA9NuYdv2cmfrf0AJ+XWWu9FKgssYydNb9Yda5FRurR4mzDrPNgH/rdrewJ0PPvb+3Bthz++N8F UipQGiNUA6Nxhcs6R3XDjjIITA9HCoOT2LwpZfcq3ZXDtX1CLXMBP6e7pU5M3j3zjO0huNWZOLZ 2y3nhhvlfgjj8BhhnYcBJSBHmQUFl3zZJBk9G0M5M3a1LF8kj4= X-Received: by 2002:a05:600c:4e01:b0:4a1:efbe:529c with SMTP id 5b1f17b1804b1-4a7c16c4554mr8187895e9.12.1793036973395; Mon, 26 Oct 2026 10:49:33 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:1a6:7f7f:f573:ba9e]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a35a574088sm196211485e9.9.2026.10.26.10.49.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Oct 2026 10:49:32 -0700 (PDT) From: "Denis V. Lunev" To: andrey.drobyshev@virtuozzo.com Cc: svt-core@virtuozzo.com, den@openvz.org Subject: [PATCH hci-8.1 2/5] scsi-disk: fix UNMAP racing with inactivation of block nodes #VSTOR-151532 Date: Mon, 26 Oct 2026 18:49:26 +0100 Message-ID: <20261026174929.685720-3-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261026174929.685720-1-den@openvz.org> References: <20261026174929.685720-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-EOPTenantAttributedMessage: 0bc7f26d-0264-416e-a6fc-8352af79c58f:0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU2PEPF00028D13:EE_|AMVPR08MB11999:EE_ X-MS-Office365-Filtering-Correlation-Id: dfc9be8d-a455-4f26-388f-08df33897ed9 X-LD-Processed: 0bc7f26d-0264-416e-a6fc-8352af79c58f,ExtAddr X-MS-Exchange-AtpMessageProperties: SA X-MS-Exchange-SenderADCheck: 0 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|9140799003|43022699015|82310400026|6059299003|48200799018|376014|61400799027|22082099003|18002099003|55112099003|16102099003|261026140227099003|5063699009|56012099006|5023799004|261021123027099003|261021121427099003|261022105027099003|10067099003|261022075727099003|261009223027099003|261026121527099003; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?z33afi3b4GFodP2RjDupyX8V81ybWiLvPgn2dJz0S/jwl8pSHMIb9xl/YdUq?= =?us-ascii?Q?hP3R4lCnQDxn1uSzsKT0sFgC++Pg65z6ZVMbAo3XgA+FtpVHdJGVvAQMBRFL?= =?us-ascii?Q?mJUreRjw8OpRNXngkDPtqFq870MvlWRi/omTmx/MuRXEntT1gKLDsIC2FxmF?= =?us-ascii?Q?TxbXmiioWXOz3Hlf9ab2TnZLwPiV7rgtz7BRqrsG4aA8xDke7bYTLLeFpffO?= =?us-ascii?Q?pBZLvq1qHk5IaCzGLVvSQ4bCFaqqHEW/XZYmfOsffE+adI8uu0fLhhqO6q4I?= =?us-ascii?Q?QeGTc0nYlF1/IyQCReyzrMoVG+I9WAVH+gpGoLRxFRWwQROu5wMNhdhZImQm?= =?us-ascii?Q?rwJo73zm8WRXCRNZ7zxLlgj4zlby/1mjqbl8KnVqQzjwNaLrBxhGwtVKTjeR?= =?us-ascii?Q?NgGIpc+0mdL15Bga9NzWJbbL/9j8vRYK96Qo94K5YMw61Zie6Cb+D59vLjmf?= =?us-ascii?Q?x/tcspyM7Z5735BXWDf3sHP7SHmW8YFbtaDOb/Hr2wrEXzd+sdbB7JztsC0s?= =?us-ascii?Q?/Hfo+SJspVbL8KwwtoKlgaQ7791n9L+Kza1HGrdqaHFd4Ve2ZRtebQ20GFRT?= =?us-ascii?Q?vNulFnSVTPWD2E5HWc3iOtfOxNJZDB8xfentBd1RVilvhQehUh5timnBg93J?= =?us-ascii?Q?o6dQMxvgItIgPdd+PHxx7TUHXHdrqjveVkNYljHxy+BsXvnFUEplU/+tZFm5?= =?us-ascii?Q?mtESil8YZilmi1cm88Dua7Rek4A4nxcAlygV6M4R661+gxi2pTfxIPse4y38?= =?us-ascii?Q?kMDWxUxOGlgC+16ijKbtIyNjpmbqCC+Zq61bvm7+Pz0e3sEnw0ci494uh7Bu?= =?us-ascii?Q?ZLAXf5114MK29Nv8T02ORRGcrw7u0D/ZhO/FpUYqPeDwFCFXL7H+cb0lFfoD?= =?us-ascii?Q?e6NB5GDW/vcl2LpND1ZDf47U7MEy4ShPfHSuWEaqfwtjGnknVEfDaL90kvdg?= =?us-ascii?Q?oOzgctswIhQYaNLoNE44Ifq6DnkuCc1/J3FbnRWonyg=3D?= X-Forefront-Antispam-Report: CIP:2a00:1450:4864:20::335;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail-wm1-x335.google.com;PTR:mail-wm1-x335.google.com;CAT:NONE;SFS:(13230040)(9140799003)(43022699015)(82310400026)(6059299003)(48200799018)(376014)(61400799027)(22082099003)(18002099003)(55112099003)(16102099003)(261026140227099003)(5063699009)(56012099006)(5023799004)(261021123027099003)(261021121427099003)(261022105027099003)(10067099003)(261022075727099003)(261009223027099003)(261026121527099003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: oWpdmPxcdjBLuauQyK/SPS4130iAM3fsyer6Xdfj4L5nWwVdDCW+G4PAb1ydOTBNxQ1l0J4q6EInlBVBmgWKbandscUv2QSfwWSyUhIjyeVRMhzZCWiciEnWVvn11w/pQMQTMh4jZ/kBbL859IfMAyuM45Nd+9vJ0+p6bkNIf1tU1ypLLfga7EWeVqMCHjDm+VakdV8AJ9V50Kd2LNABYLobrKUFvIooXb1eDhKYB8eU/mw2BNPxkXy8Kc5ov5blw67ithj1aXcoxtyrpIkavD2FUoJIuAFsYt/4dt7aL7FowlfZIRijX9CjtiZRdy5B02GSFj62IkC4lVwh8q4bD+va7lvh8iRm4E7kjhZB7nkadleWb6mS8OjkYh4Cj2t6dks4FCT71/SbwEsc+UODB2ENWuf6nNTnabaT9ghBoiVba0Slz25okwAP/DDlUYOV X-ExternalRecipientOutboundConnectors: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-Auto-Response-Suppress: DR, OOF, AutoReply X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Oct 2026 17:49:34.1003 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: dfc9be8d-a455-4f26-388f-08df33897ed9 X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-AuthSource: DU2PEPF00028D13.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-Transport-CrossTenantHeadersStamped: AMVPR08MB11999 List-Id: From: Denis V. Lunev scsi-disk turns a multi-descriptor UNMAP into one discard per descriptor and submits the next one from the completion callback of the previous. Nothing holds the BlockBackend in-flight counter between two descriptors, so a drain only waits for the discard currently in flight. When that discard completes inside drained_begin, the callback submits the next one, blk_wait_while_drained() queues it, and the drain returns with the UNMAP half done. bdrv_inactivate_all() drains, inactivates the nodes and ends the drain, which resumes the queued discard on an inactive node: bdrv_co_write_req_prepare: Assertion `!(bs->open_flags & BDRV_O_INACTIVE)' failed. A guest that issues UNMAP at the end of a live migration, or around blockdev-set-active, takes QEMU down this way. Handle UNMAP the way commit 095c08a7ba handles IDE TRIM: process the descriptors in a coroutine between blk_co_start_request() and blk_end_request() and submit them with BDRV_REQ_NO_QUEUE. A drain now waits for the whole command instead of a single descriptor, the same trade-off IDE makes. The coroutine is wrapped in an AIOCB that stays in r->req.aiocb, so cancellation keeps working as before. A failed descriptor ends the loop, and the completion applies the rerror/werror policy as before. werror=ignore is handled inside the loop, so the remaining descriptors are still discarded as the callback chain did. Signed-off-by: Denis V. Lunev Cc: Paolo Bonzini Cc: Kevin Wolf Cc: Hanna Reitz Cc: qemu-stable@nongnu.org --- hw/scsi/scsi-disk.c | 160 +++++++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 47 deletions(-) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index c608fc56036..8383b7cbe93 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -1742,61 +1742,135 @@ static inline bool check_lba_range(SCSIDiskState *s, sector_num + nb_sectors <= s->qdev.max_lba + 1); } -typedef struct UnmapCBData { +typedef struct SCSIDiskCoAIOCB SCSIDiskCoAIOCB; + +typedef int coroutine_fn SCSIDiskCoFunc(SCSIDiskCoAIOCB *iocb); + +struct SCSIDiskCoAIOCB { + BlockAIOCB common; SCSIDiskReq *r; - uint8_t *inbuf; - int count; -} UnmapCBData; + SCSIDiskCoFunc *fn; + int ret; + bool canceled; +}; + +static void scsi_disk_co_aio_cancel(BlockAIOCB *acb) +{ + SCSIDiskCoAIOCB *iocb = container_of(acb, SCSIDiskCoAIOCB, common); + + iocb->canceled = true; +} -static void scsi_unmap_complete(void *opaque, int ret); +static const AIOCBInfo scsi_disk_co_aiocb_info = { + .aiocb_size = sizeof(SCSIDiskCoAIOCB), + .cancel_async = scsi_disk_co_aio_cancel, +}; -static void scsi_unmap_complete_noio(UnmapCBData *data, int ret) +static void scsi_disk_co_aio_bh(void *opaque) { - SCSIDiskReq *r = data->r; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + SCSIDiskCoAIOCB *iocb = opaque; + BlockBackend *blk = iocb->r->req.dev->conf.blk; - assert(r->req.aiocb == NULL); + iocb->common.cb(iocb->common.opaque, iocb->ret); + qemu_aio_unref(iocb); - if (data->count > 0) { - uint64_t sector_num = ldq_be_p(&data->inbuf[0]); - uint32_t nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL; - r->sector = sector_num * (s->qdev.blocksize / BDRV_SECTOR_SIZE); - r->sector_count = nb_sectors * (s->qdev.blocksize / BDRV_SECTOR_SIZE); + /* Paired with blk_co_start_request in scsi_disk_co_aio_entry() */ + blk_end_request(blk); +} - block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, - r->sector_count * BDRV_SECTOR_SIZE, - BLOCK_ACCT_UNMAP); +static void coroutine_fn scsi_disk_co_aio_entry(void *opaque) +{ + SCSIDiskCoAIOCB *iocb = opaque; - r->req.aiocb = blk_aio_pdiscard(s->qdev.conf.blk, - r->sector * BDRV_SECTOR_SIZE, - r->sector_count * BDRV_SECTOR_SIZE, - scsi_unmap_complete, data); - data->count--; - data->inbuf += 16; - return; - } + /* Paired with blk_end_request in scsi_disk_co_aio_bh() */ + blk_co_start_request(iocb->r->req.dev->conf.blk); + iocb->ret = iocb->fn(iocb); + aio_bh_schedule_oneshot(qemu_get_current_aio_context(), + scsi_disk_co_aio_bh, iocb); +} - scsi_req_complete(&r->req, GOOD); +static void scsi_disk_co_aio_complete(void *opaque, int ret) +{ + SCSIDiskReq *r = opaque; + + assert(r->req.ctx == qemu_get_current_aio_context()); + assert(r->req.aiocb != NULL); + r->req.aiocb = NULL; + + if (!scsi_disk_req_check_error(r, ret, true)) { + scsi_req_complete(&r->req, GOOD); + } scsi_req_unref(&r->req); - g_free(data); } -static void scsi_unmap_complete(void *opaque, int ret) +/* fn must submit with BDRV_REQ_NO_QUEUE and stop once iocb->canceled */ +static void scsi_disk_co_aio_start(SCSIDiskReq *r, SCSIDiskCoFunc *fn) { - UnmapCBData *data = opaque; - SCSIDiskReq *r = data->r; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + SCSIDiskCoAIOCB *iocb; - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; + iocb = blk_aio_get(&scsi_disk_co_aiocb_info, s->qdev.conf.blk, + scsi_disk_co_aio_complete, r); + iocb->r = r; + iocb->fn = fn; + iocb->ret = 0; + iocb->canceled = false; - if (scsi_disk_req_check_error(r, ret, true)) { - scsi_req_unref(&r->req); - g_free(data); - } else { - block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); - scsi_unmap_complete_noio(data, ret); + /* The matching unref is in scsi_disk_co_aio_complete */ + scsi_req_ref(&r->req); + r->req.aiocb = &iocb->common; + aio_co_enter(qemu_get_current_aio_context(), + qemu_coroutine_create(scsi_disk_co_aio_entry, iocb)); +} + +/* Report like scsi_handle_rw_error(), but let werror=ignore go on */ +static bool scsi_disk_ignore_error(SCSIDiskReq *r, int ret) +{ + BlockBackend *blk = r->req.dev->conf.blk; + BlockErrorAction action = blk_get_error_action(blk, false, -ret); + + if (action != BLOCK_ERROR_ACTION_IGNORE) { + return false; + } + blk_error_action(blk, action, false, r->sector << BDRV_SECTOR_BITS, + r->sector_count << BDRV_SECTOR_BITS, -ret); + return true; +} + +static int coroutine_fn scsi_unmap_co(SCSIDiskCoAIOCB *iocb) +{ + SCSIDiskReq *r = iocb->r; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + BlockBackend *blk = s->qdev.conf.blk; + uint8_t *p = r->iov.iov_base; + int count = lduw_be_p(&p[2]) >> 4; + int i, ret; + + for (i = 0; i < count; i++) { + uint64_t sector_num = ldq_be_p(&p[8 + i * 16]); + uint32_t nb_sectors = ldl_be_p(&p[8 + i * 16 + 8]); + + if (iocb->canceled) { + return -ECANCELED; + } + + r->sector = sector_num * (s->qdev.blocksize / BDRV_SECTOR_SIZE); + r->sector_count = nb_sectors * (s->qdev.blocksize / BDRV_SECTOR_SIZE); + + block_acct_start(blk_get_stats(blk), &r->acct, + r->sector_count * BDRV_SECTOR_SIZE, + BLOCK_ACCT_UNMAP); + + ret = blk_co_pdiscard(blk, r->sector * BDRV_SECTOR_SIZE, + r->sector_count * BDRV_SECTOR_SIZE, + BDRV_REQ_NO_QUEUE); + if (ret < 0 && !scsi_disk_ignore_error(r, ret)) { + return ret; + } + block_acct_done(blk_get_stats(blk), &r->acct); } + + return 0; } static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf) @@ -1804,7 +1878,6 @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); uint8_t *p = inbuf; int len = r->req.cmd.xfer; - UnmapCBData *data; int count; int i; @@ -1843,14 +1916,7 @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf) } } - data = g_new0(UnmapCBData, 1); - data->r = r; - data->inbuf = &p[8]; - data->count = count; - - /* The matching unref is in scsi_unmap_complete, before data is freed. */ - scsi_req_ref(&r->req); - scsi_unmap_complete_noio(data, 0); + scsi_disk_co_aio_start(r, scsi_unmap_co); return; invalid_param_len: -- 2.53.0