From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421698; cv=none; d=zohomail.com; s=zohoarc; b=FmsQdhFfP0XbTU/VmAVBD98/5CnQfeCEoPMJHM/bme6YNj7T6nw1RFL8zv0WODAloFFwxJPw9TKDpDPjHuLUFiir3Xorvix91y1s/bJA/ebySZT9oMNaxMhge5rkYaHT2h5aM4L1tSve/JpD6z5u4jMba5kNJEX0+8BdrJahMQo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421698; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=KIrJYrtnoXwxSw4V3NuTZZEpmlWDoM3vKo2sYuFFuvk=; b=ha9Kwzp+C7ylOs8JpzOTTV1qyyG4Oun3zLqIRsN7JCNDX7hST/3IVawF9ie/vM5x4R9uR3oyrVjULJ+4aBo7fVDBgkJdUAAi2UbVOl6Qr0SS7O4J7hwD+pW1PNftVQ0j3wz5dvxlP3HTCi59QPrmsolw0thpv9xFoBzd4RBeqvE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421698068486.7008897817593; Wed, 18 Feb 2026 05:34:58 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfb-000486-Dx; Wed, 18 Feb 2026 08:32:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfT-0003yj-OM for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:40 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfA-00052x-N6 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:37 -0500 Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-64-KFCd-gTGPL6FS4Anet0x1w-1; Wed, 18 Feb 2026 08:26:46 -0500 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-436267b01c4so4787945f8f.0 for ; Wed, 18 Feb 2026 05:26:46 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4837e565f5esm419468275e9.10.2026.02.18.05.26.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:26:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421520; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KIrJYrtnoXwxSw4V3NuTZZEpmlWDoM3vKo2sYuFFuvk=; b=iL6DYDVbeTt8yOV6GAWNwI2Jr5jJB+K0cVAn0xhJHC1Q5eLK7D8wjolMxRpOKj6AEqe7jR pl4dg7iat/25sd58maEiNwYz+CF6M8HfL5p6fwpR8PMaTOLalzgLc5zvsT6aAXVbXU+XFZ q4Ked2TghRNVifSPX18qpURYLIdICIA= X-MC-Unique: KFCd-gTGPL6FS4Anet0x1w-1 X-Mimecast-MFC-AGG-ID: KFCd-gTGPL6FS4Anet0x1w_1771421205 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421205; x=1772026005; darn=nongnu.org; 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; bh=KIrJYrtnoXwxSw4V3NuTZZEpmlWDoM3vKo2sYuFFuvk=; b=m3dskqsJNpNW1ywXhelYIoKfU9yUd4gdfbfXpFkS+mK/ePYMopLcRdGEtdXNJxjGsu /kv3p5F6SnWsydsFy3kiY4YT10gnJrv8YBTLmvimcAiCpv2yJmWkKEHsnavfENlJhrNm Y9g8kWvSY4hbAiWzUEaSlBzSRKEChzt+VlakiClYytJwmahfle4BrPDbhrB/fW5tFJ2j ainQyVTBggsMup/HRl8z/hETTaq4/TScRfbjxMGcNijM5WJ8TOwBz6vy0vVaTaXV14uM ApF68Qn7LBp30nmDF9H7N0IeQAs1d8KVnm0GXPhE+A2AFqTYHEhNz3CdE4rNgmh70bhi hIIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421205; x=1772026005; 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; bh=KIrJYrtnoXwxSw4V3NuTZZEpmlWDoM3vKo2sYuFFuvk=; b=oNOgGzDXPHELCRqDlr9CCWyUoHpNb+532dLB5Ks31OiqGH5Jr+13Qwf3J25L+ePK7q zAEqpu4cTM2N7VNPfbTOSwoVaXoPu3FZt45hSVhjH9X815LZ5yu6GALVRGgOeLqbFjI7 O5tHlwR6f+1nuKFoKF1EFL1QLv7RF8+S6qhISj0V9U0HaTAbQlmVmgACDuN5UF0sEY1V RDOgJSQkZZMn9WaDHsQuM1zi3UAJV0n+z73HRTPb1zjeDDFL/yksm303EC0kTpZ7w3nB aCJ7J+tCAiWeKl8u6kU5jQzz5ff9/APE4ydGFhfzR0N0Ydz/RC6e1cezG6aPOACnYNAV KgLA== X-Gm-Message-State: AOJu0YwNSwknT/Tca5BrPSywYWvSe8J5cMudBUDPG4MhRbQzXBp90p6B +VSwIQCT4SEewNbOj2yqIdd9Dkr6W0bx8rAMAsHya3Adud8zdRqdpAAwfYoEqc3MJmhZIphpTw8 OgWMUlt5+u2MnrC6/6iM7dku39MmdEfWrqJHc5myKPO5fIRGEn3lcn1X+ X-Gm-Gg: AZuq6aKKOFglxmgd+HvlZ2gJOTNXgnhepeRSiakKn/pncGk6NPCZhzLd+DYAw/KRXMV VZ8Yn0RJxXbr5SGoo5s3drC5PAd38zxr/FeekJsyUPRl4J8sffyqxLzjh0H0zDzQEjKgLB4DLg9 3VNY89063AlIwQ66kMnTMWqf8yZauvpTEB6ez/MLpr0ECHWG7tpNBVY2MBy7WCY/v/SIBf+SIv3 K8UGQZnFQ13niTqEhWq0PwQKLAd125vlsyKmAJ/CqgCPNEH/6/JJkfPfBHTnxop/GNHFrmg+tz3 v5eeFJE9R68EZHi6UTCubE9kdvAvn3Ls/xLerEgxkGobi/tqMEgVFwXYqOvz4OqWGDgGsyLFccV sTIiVrbS9pCuKUgCYFxAfWDcJdHvhB02SZUYLLeOghjSKEUF0XCzfAgxPyeJg2Virc8GTuHMFD0 ectmcu X-Received: by 2002:a05:600c:8219:b0:483:6bb1:117 with SMTP id 5b1f17b1804b1-48398b7d878mr31983425e9.32.1771421204962; Wed, 18 Feb 2026 05:26:44 -0800 (PST) X-Received: by 2002:a05:600c:8219:b0:483:6bb1:117 with SMTP id 5b1f17b1804b1-48398b7d878mr31982945e9.32.1771421204477; Wed, 18 Feb 2026 05:26:44 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 01/24] fuse: Copy write buffer content before polling Date: Wed, 18 Feb 2026 14:26:10 +0100 Message-ID: <20260218132633.29748-2-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421699872154100 Content-Type: text/plain; charset="utf-8" aio_poll() in I/O functions can lead to nested read_from_fuse_export() calls, overwriting the request buffer's content. The only function affected by this is fuse_write(), which therefore must use a bounce buffer or corruption may occur. Note that in addition we do not know whether libfuse-internal structures can cope with this nesting, and even if we did, we probably cannot rely on it in the future. This is the main reason why we want to remove libfuse from the I/O path. I do not have a good reproducer for this other than: $ dd if=3D/dev/urandom of=3Dimage bs=3D1M count=3D4096 $ dd if=3D/dev/zero of=3Dcopy bs=3D1M count=3D4096 $ touch fuse-export $ qemu-storage-daemon \ --blockdev file,node-name=3Dfile,filename=3Dcopy \ --export \ fuse,id=3Dexp,node-name=3Dfile,mountpoint=3Dfuse-export,writable=3Dtrue= \ & Other shell: $ qemu-img convert -p -n -f raw -O raw -t none image fuse-export $ killall -SIGINT qemu-storage-daemon $ qemu-img compare image copy Content mismatch at offset 0! (The -t none in qemu-img convert is important.) I tried reproducing this with throttle and small aio_write requests from another qemu-io instance, but for some reason all requests are perfectly serialized then. I think in theory we should get parallel writes only if we set fi->parallel_direct_writes in fuse_open(). In fact, I can confirm that if we do that, that throttle-based reproducer works (i.e. does get parallel (nested) write requests). I have no idea why we still get parallel requests with qemu-img convert anyway. Also, a later patch in this series will set fi->parallel_direct_writes and note that it makes basically no difference when running fio on the current libfuse-based version of our code. It does make a difference without libfuse. So something quite fishy is going on. I will try to investigate further what the root cause is, but I think for now let's assume that calling blk_pwrite() can invalidate the buffer contents through nested polling. Cc: qemu-stable@nongnu.org Reviewed-by: Kevin Wolf Signed-off-by: Hanna Czenczek --- block/export/fuse.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 8cf4572f78..cea9de61f1 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -301,6 +301,12 @@ static void read_from_fuse_export(void *opaque) goto out; } =20 + /* + * Note that aio_poll() in any request-processing function can lead to= a + * nested read_from_fuse_export() call, which will overwrite the conte= nts of + * exp->fuse_buf. Anything that takes a buffer needs to take care tha= t the + * content is copied before potentially polling via aio_poll(). + */ fuse_session_process_buf(exp->fuse_session, &exp->fuse_buf); =20 out: @@ -624,6 +630,7 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode= , const char *buf, size_t size, off_t offset, struct fuse_file_info *f= i) { FuseExport *exp =3D fuse_req_userdata(req); + QEMU_AUTO_VFREE void *copied =3D NULL; int64_t length; int ret; =20 @@ -638,6 +645,14 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inod= e, const char *buf, return; } =20 + /* + * Heed the note on read_from_fuse_export(): If we call aio_poll() (wh= ich + * any blk_*() I/O function may do), read_from_fuse_export() may be ne= sted, + * overwriting the request buffer content. Therefore, we must copy it= here. + */ + copied =3D blk_blockalign(exp->common.blk, size); + memcpy(copied, buf, size); + /** * Clients will expect short writes at EOF, so we have to limit * offset+size to the image length. @@ -660,7 +675,7 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode= , const char *buf, } } =20 - ret =3D blk_pwrite(exp->common.blk, offset, size, buf, 0); + ret =3D blk_pwrite(exp->common.blk, offset, size, copied, 0); if (ret >=3D 0) { fuse_reply_write(req, size); } else { --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421773; cv=none; d=zohomail.com; s=zohoarc; b=Nw7rQquUOIzKSdVMZcdwTDtbqqpcCZ6iGDxkPLclEHL+BP15lKCl6LYKtdurBxwW26Zw/hMjpCpc4DSfM4h/esI88HoHMRLzfHb+jwVm0IJfac0bLR8Yl9cV9IKEMp3vdqs0v4XoDfhCdRJN04a8afUSpvf2r2OUNUFGKws4BFI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421773; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=yWcGLprdpXgo2UanWZOxr3c/Uu5d1zE+FoOX3fFgguc=; b=iahWq9X2yFsGG1ICvdmHy8kNWH/Ds0PPIyQJ9KPPbLikT7N1kM3+MXbNfSZVX3dn93S00wEqjIz4vokfLTnpijur+KtefIyCHkbQ1paeK7U3biCAc7yURJIjPSEY8o1Qfud60dreq0P8zYC8tLfTt7SUqL9NDRNGuU2J7NnF02o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421773720968.5885646546565; Wed, 18 Feb 2026 05:36:13 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfA-0003pD-Ox; Wed, 18 Feb 2026 08:32:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshf6-0003oI-Ti for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:18 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshf2-000546-3i for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:16 -0500 Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-31-LUVopu8ZPdmRCbCTfR509w-1; Wed, 18 Feb 2026 08:26:49 -0500 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-4368060a5e5so5642639f8f.3 for ; Wed, 18 Feb 2026 05:26:48 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796a6c1bfsm43078466f8f.13.2026.02.18.05.26.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:26:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421521; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yWcGLprdpXgo2UanWZOxr3c/Uu5d1zE+FoOX3fFgguc=; b=Z/q3DZLPHhWwTJW3iiigHPCMCPOdcl43XdFKEeiS+nWqAHgxWPZASjCnLHjcprb6jFHz3q gc/doRaKCneGz/NAQOd1m7mVnMU16SnSfRKoNcLAaokDhOBbPKF5zw2Gr3WLx2Cnelym1A GNa8RN0wVKQsw4qRj7Nln4mueGCff1o= X-MC-Unique: LUVopu8ZPdmRCbCTfR509w-1 X-Mimecast-MFC-AGG-ID: LUVopu8ZPdmRCbCTfR509w_1771421208 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421208; x=1772026008; darn=nongnu.org; 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; bh=yWcGLprdpXgo2UanWZOxr3c/Uu5d1zE+FoOX3fFgguc=; b=D/SHPUPpG5gE9D+pwLeTDU4Pcbvx0/1d0c10AYgfWNSlefQi4Z9ilxgtJnFWnLFxTp Mq7r9Jc3neeX+aJmhr3a6g9svaUxihI+5PMPk6SQBX4/ASpphfYchJj042rGFzrl3Atw QuAORszsT4fPLpuOZWhuV9pHLb6sLETl+/jEsQ8Cfn/YMfJSwAQeV9qlR5fqvLQcH4vf DcWCXCcHfPcIqlifaFS44VoKybBBiMEhHHbhr1VTErrjEF0nzEm6qMvB1q2c/B4lq3bL Mg3s8j5FGWNBIo8P/B+EwpmYJ/6gtExyU1kc3QgU5/vt32pQEOBKr1LFygC71G719YUx 6C6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421208; x=1772026008; 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; bh=yWcGLprdpXgo2UanWZOxr3c/Uu5d1zE+FoOX3fFgguc=; b=bus7eGLILJtx7aW4SBZ3yHTYNkQWk/78lSMxheSB5Ir5bhX4CTEoGgi1pLV7CTOeKx +8P2zbpIpJ24Wl35YOMtRBZKBcVS8mb7h3hklLNyRBWuG6b28eja/3NB/u/gHFreRern DHD7oAF2a3kI3SEDOLIm4YpibyVWNXYoxwb1a0TQF2E1BpSD7BiXCrJb4WXNVbN9B5i2 fj55bxTXeTXIkQklS6DlqakZWmcWAcw4dhl2QM1vUmxG2NjsrQ92Wi+hMiHxF9rtrFof AF0x5UIvW5SlK2zwmq0VZbfmbFF179FSZt8+fzdRfLWvYBvtSy+xGZoqC3oUg+cM6C7/ /gnw== X-Gm-Message-State: AOJu0YyRy5tRT+aFcQyeKGdiKI0rBy6viVxUuOaYxPAlFG3kf/vlvxhx r4ItnPglI1DHPENozdq4JS/P/ha1oW6j1m0bg2EXwgZqgSI4Rfs4/TI5Og85+FXz+vplB2upKO2 1wQgE4CvyZIDU07abqMqUfJ5+NK0uqgp2jtEfW4uN5gclNCQRC9VcvyTk X-Gm-Gg: AZuq6aLXi5CiUTLOd8sJXdKCdlOrbL+oBV+p7mfNmPbsNLYIk+zeIlSSyeqbiclSr8o 2LSetFOfMYsKPjd3wZq01D1wm9XSNwyP8X0wl4P6dRkr/YOA17m0gD6Z4AQkb5EDO99A1+dsfv3 /m78nTLzO5XV2ca8/z4++nHzcq+f8ohDzulyPQKlFRiGx3a0NprAcLewEV0nHxvoK6sHAX55tnf G/4Zmu1n8oBmUrKtVVR6bcR4ve6fL6Q8yDSmYut/CR3IlsTDnlen0waA/k0fr0q1AHTmM+FI9xT olfU1WgmU4HFL7hLVg5gjWbkIFQiRg5p8clEE7EoBUJ0anxSdy/u2s4iMsbGbKJCggVl5ueo5SR ZFlJbo72sX0n0A0MfqjZhgf6eUQ6hDKB/khfvu/Ouu/CboxS3k2ufuBaB6rr1x39ASMIDYeXJOJ v8U5t4 X-Received: by 2002:a05:6000:2508:b0:435:8e14:9877 with SMTP id ffacd0b85a97d-4379dbae484mr23152421f8f.60.1771421207816; Wed, 18 Feb 2026 05:26:47 -0800 (PST) X-Received: by 2002:a05:6000:2508:b0:435:8e14:9877 with SMTP id ffacd0b85a97d-4379dbae484mr23152382f8f.60.1771421207355; Wed, 18 Feb 2026 05:26:47 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 02/24] fuse: Ensure init clean-up even with error_fatal Date: Wed, 18 Feb 2026 14:26:11 +0100 Message-ID: <20260218132633.29748-3-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421774930154100 Content-Type: text/plain; charset="utf-8" When exports are created on the command line (with the storage daemon), errp is going to point to error_fatal. Without ERRP_GUARD, we would exit immediately when *errp is set, i.e. skip the clean-up code under the `fail` label. Use ERRP_GUARD so we always run that code. As far as I know, this has no actual impact right now[1], but it is still better to make this right. [1] Not cleaning up the mount point is the only thing I can imagine would be problematic, but that is the last thing we attempt, so if it fails, it will clean itself up. Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/export/fuse.c b/block/export/fuse.c index cea9de61f1..2ed22c6b2f 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -119,6 +119,7 @@ static int fuse_export_create(BlockExport *blk_exp, BlockExportOptions *blk_exp_args, Error **errp) { + ERRP_GUARD(); /* ensure clean-up even with error_fatal */ FuseExport *exp =3D container_of(blk_exp, FuseExport, common); BlockExportOptionsFuse *args =3D &blk_exp_args->u.fuse; int ret; --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421795; cv=none; d=zohomail.com; s=zohoarc; b=Sc+XEZ/miXtHbgGcuvA/3au54Qgf4oSO5m3W6J1R1BpVnZG3lVEsi8qhL6vWjgfVF/bW9/dKwgD8c1nUDPdB5GoNQvIYGFXnHSACHMbxCN4S5vAplv/q+ShCWlmc9bcwcrt/CjzBo+eq/a6MS6TjNqGcM3TsJIULAALDmDzeO7Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421795; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=uVtrqVMsyosUaHcDZ5RGcCJIBeUjW9Ffsh9VA3rZWsw=; b=kt+nuxnSH3KZaWhix2JJqHGBcsz6si1VxuIo+M+8Z+1gojgFFzjawjEUUorMPDj+wA5bLFBCUJjEQJfrpo2SfJ7oJjGbJ4+ZE40LVtC3CKulRQU75mV730p2PhVRg0JMJHhSy/wMGh3nc0GPjW3xILBcDXotKTHbVc6tdmBlpPw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421795014654.3351202977802; Wed, 18 Feb 2026 05:36:35 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfc-0004Ag-IJ; Wed, 18 Feb 2026 08:32:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfT-0003yp-Sv for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:40 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfA-000543-Mr for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:36 -0500 Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-178-kk2Z5bLzN0SfwJNal-15ow-1; Wed, 18 Feb 2026 08:26:55 -0500 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-48071615686so47356145e9.1 for ; Wed, 18 Feb 2026 05:26:51 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-483970d447fsm36188655e9.0.2026.02.18.05.26.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:26:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421521; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uVtrqVMsyosUaHcDZ5RGcCJIBeUjW9Ffsh9VA3rZWsw=; b=AeyrBG0I8Z/gy2CHBlrsKoNkpb1OUeSHLcd3P22Jhl4S3B3xQm3lYTx3nHOBDRIqzGlJBr mpr7kcOtGaJdgSCaGYqSXNOtKmgwazHy5VlxDKQyPE804wHvpiudUAcNCHNREdmVakFyEo EJyB4evfUqU//cQATwx/PkByAOsyDQI= X-MC-Unique: kk2Z5bLzN0SfwJNal-15ow-1 X-Mimecast-MFC-AGG-ID: kk2Z5bLzN0SfwJNal-15ow_1771421211 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421211; x=1772026011; darn=nongnu.org; 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; bh=uVtrqVMsyosUaHcDZ5RGcCJIBeUjW9Ffsh9VA3rZWsw=; b=NqHrJnuUikqcOd2cbqltc5QoZYnRlYSSPG2FWQJYjbtpdm9NH+FykPXOEuqkuat756 coMiUcU/Wsmvu0ZRk57towBEO8U4bML7oIwcY/tfUveNlHxm2N5/3zx5sP0LDbd3Mfzx eqj/8NykUIId0i4ch7CocYPBQkQZWmxQvyGSpzi/0x80lKdm1EN2WWqPt8ivDe7euST1 53R5tdAGeNPhX253abSlTr1H82DhZuijAztXWKkZJ9ax9NRqAng42OBKjBrNxh7nznv/ ZTJdFg1Ha1jdr1TyPfLMHOB12druKtLF0OcJdIktC13+DweCQMEod/NsKCmJe/G1YQeE 2/Pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421211; x=1772026011; 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; bh=uVtrqVMsyosUaHcDZ5RGcCJIBeUjW9Ffsh9VA3rZWsw=; b=qzORdUBf1B+5UW/2DSWI2FWYctf+33NWZ3EPaSyZDZeV4qBKL85yP915H/9NqsLgF9 15O9C9wrJN4u3m25QhGppwiR/e2i/704XzhKd54bcYR7skkie3hT+N4JLnge2sqjbbVS 1EW+WnErPuGMjQUN7vxtiPgz4YbaXi76W00K+TidwQKevSoa8QBmK5VHZu1hGj537UKN /JrkvtNwj4cu2CcVZPrp3OsZXvUKCCuMoOQzEccsGw7Urde1Bd/1qI7aN/oQzI3bX5AB JQgoV5d6LnVGV2AFNMr7zn7QS6+eFBFuP2Il2GackN9d4E+nqpzGY9S7hk+9+SWKLpo0 7x3w== X-Gm-Message-State: AOJu0Yx/+8FjndYWP6xQHLiONFW/JCWjwo6zI1SxFbEkjhm3RGICP8R0 kGw7oeKgyRYmKo7DdpV6MQTzY7k2KeSf1v6BjTFu0TgHI948eogtUPxIfHIDDD+jT7igHckSEwB DJ7tsmRCrr4IAoIicVpEuCG2QzpVmcgxaPljiJZMqzMlixfHt9m8IVS+8 X-Gm-Gg: AZuq6aLUutCNCp5SWwVxk1AUQp54L+vnSS+ZRyIkGSOepyo+dVa0o/SuZtf0+mfGlSU dze6f8PLvfiFeg4TE7oVzWPAGqkU7oaS2yNHmheie6mEw+OtXjq03kSesdzItPuSiPDqbouYufL yA+mXHzYleKe5p//7nwZfIsMkkRXKGLNKIybrDuLfPYhs6MQUCNuaiW4Cj6LNkFzIpw8MSLPCly 5Evr1JRkdE+583RXVkggq7JwzSDC1Bl123nqM9KumxXzpPaUVWlMzDIJnz8vOIG/UL5M/rfncBz aNsnTuB06b1f+z5fr4QxIX2VhpwP5mPLv3EoGp1CgmP0EMwLhtGjOEMSGd2w4wBGuGmp1PApuf+ RbDQcrNnyNXraysXC5hM2qrkTXwywF34AHtoHKKBIMKNbeBzNMTfzDdjrYxqvldutguBwpm5z2n cG+vn0 X-Received: by 2002:a05:600c:4e42:b0:483:76b2:cacf with SMTP id 5b1f17b1804b1-48398aee83amr33458715e9.32.1771421210866; Wed, 18 Feb 2026 05:26:50 -0800 (PST) X-Received: by 2002:a05:600c:4e42:b0:483:76b2:cacf with SMTP id 5b1f17b1804b1-48398aee83amr33458325e9.32.1771421210386; Wed, 18 Feb 2026 05:26:50 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 03/24] fuse: Remove superfluous empty line Date: Wed, 18 Feb 2026 14:26:12 +0100 Message-ID: <20260218132633.29748-4-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421797291154100 Content-Type: text/plain; charset="utf-8" Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 2ed22c6b2f..4cdf527d69 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -464,7 +464,6 @@ static int fuse_do_truncate(const FuseExport *exp, int6= 4_t size, } =20 if (add_resize_perm) { - if (!qemu_in_main_thread()) { /* Changing permissions like below only works in the main thre= ad */ return -EPERM; --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421729; cv=none; d=zohomail.com; s=zohoarc; b=BI7OiVL8HGGPHnM5H430j+glcq+W5gDnCD5fx0SILB4SCrPb+IbR8fRehX8A5HgPT37priD0vwou6TSMZ2LH/zEVphhJ0G4DBvjT5/V0/I+uldVRDDURO983iOgBlmJM+9Fo1o3xKebpdvaEDaLde+6y85cnFkKXor5SNPVUPe4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421729; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=OSXZAuWYpAshM63pW80TanRP4MfbiawAfcaxsHKGA1o=; b=MpnWlTMKg5F3HqnQA20ccu5IgXPN6e/BSYOdhvlPZZmBzukHdwoQiGjhoAnlTvSPkae0ps+70/8Zw8jZXEjwJ0lNXAw56ZRlA8P+cUOaEJFtY65yiA3q54gdq2ZIfp8BKPvqUU6OLWqQuLNKiaVwGvC5n/nCS5eZ+9J82kje5gs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 177142172913491.15462604326956; Wed, 18 Feb 2026 05:35:29 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfe-0004Er-LZ; Wed, 18 Feb 2026 08:32:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfT-0003yk-O0 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:40 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfA-00053d-NF for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:37 -0500 Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-410-AcYpjjHsOu6HxrSpHx-wQw-1; Wed, 18 Feb 2026 08:26:54 -0500 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4837b7903f3so47974845e9.2 for ; Wed, 18 Feb 2026 05:26:54 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796acffcesm38829881f8f.37.2026.02.18.05.26.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:26:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421521; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OSXZAuWYpAshM63pW80TanRP4MfbiawAfcaxsHKGA1o=; b=X8Kqqtp3U+OR89948qfu3+Ic+L8i7cj1A0hfcjBU12GY88r5ocDCs8hixkKMGZmOX6xTJ7 fCdSP+LMj1hbVyz25G+JyLlONCo6JEIdIFURlcwmpQznEzDjuo1HeknV8incBs/smqzGdK ykjuYYCo2pxazFkY/eE1uWdVq2mtYss= X-MC-Unique: AcYpjjHsOu6HxrSpHx-wQw-1 X-Mimecast-MFC-AGG-ID: AcYpjjHsOu6HxrSpHx-wQw_1771421213 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421213; x=1772026013; darn=nongnu.org; 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; bh=OSXZAuWYpAshM63pW80TanRP4MfbiawAfcaxsHKGA1o=; b=H2BcJRU6SFOe03Z00NrLZcPhhjAJ61rq8D3QxIf4yA7QYXtSSTQ06sUr+0GOIWHxfg P8hSed0UgFFbIyTNeuJeeMBkVEdI+V3kh2l9nuK0VduoAtbwW0uCk3JOhnovjR7Hcge+ P6nbIyYxCqzHKKwp0mAys1t8LGa8Em2dfzT1sD83U7lgaNrTPg5/TunXFrXgY1hvklOz kagaK11axt9cWtAh+uKGwKsGZcGPbsQR/78XSq6sqPZBd4Y7ht/nOVBMrYXpNEQDYkS4 8pTnretYyhJP+O7jB7DkrTi8crJNx+gNyXfaietA/rH+gmlk9xja30f3Mx7pUaHSoyIy hsHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421213; x=1772026013; 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; bh=OSXZAuWYpAshM63pW80TanRP4MfbiawAfcaxsHKGA1o=; b=uivkX7QZExNSJ38dBQK+A/cMNYqpl+SjB3DEWbC4rN4KNPrvzmYUYEMGuZclcEKdx9 uMpsKB0wNm8P22lH86YV9cDMsveLn261aAGT1kcTTZmF9lQzI49PoNbJe+mbSjNWyHSm Kx+BKFjmua4kv4qSrnSQm0MFZNKEBpSovaLy6JfdUupkAShBB/eJ8WEkW+kXBSc6S+Lz pK8yYK1rrQsp5gz9A30KPyd5Af52dLru6il5p2ORyMjsZFapg8QDGuFiPxeYjwz5phMa wN6idSQ0YX9LMlgDJoRHeo7zaa0IgjoE4DHxAKHtn1ml2MYpD0Zmc124bJUKAf1DBX4B M55g== X-Gm-Message-State: AOJu0YzswJTshlEbQwWZHsn6eIocU9V6oPtaaKeAhOwG83Gn7dWmYbwu VDLOwVq4eD+cILvKS6EK/eKIPpF0+nRa6FubPoykq5GupJdL6r3PmjJgFxN9xj0O5I8O9nrDs4u t0rrB4F3S1Hi1K2M0sDiHYGV418vhPjte9KXpubZ/h1M77MiYUjUicXin X-Gm-Gg: AZuq6aI4Bnl5xjp+/y+naqWbexd+bHuCFYCF+YZkWGl00TYEqLmGEe9H5dGYWBN1H0K Aet4aOnuYHYa1O0KMOQwSM4YB/lTlE6LptkQpiV7f6XpLwm+VPEtsBGkpFtZOPj/URndtoRgz5t faCCFGwVRTFxQ40Uoa0YiGs4/2WijcEH93H1DP1CShqC/XFqmqEj882/YTJXDkDwSqCllfsJGhb /yXQOIOFCRKmXbVYwPRZkX6TWMvwQhY0iSs38tAqwm5h/WUppFDMIAF7+aqGefKntRRnDS/QNpN PiIWyCFs38tGZZ0QxTXugr5t/6xvCX6bOUIR9QoZUnAqVqM8RUDEeTLPUqejsulOz0RtL768Zlg e8MskazLy9Iwk9bITurZapYQBX40WRYQHX8kyLUalABbw9WSsVkpe1MqISy6+ldGFscSJa6ssCF FnIddu X-Received: by 2002:a05:600c:19c6:b0:480:3bba:1ca9 with SMTP id 5b1f17b1804b1-48398a65e5cmr33300645e9.4.1771421213161; Wed, 18 Feb 2026 05:26:53 -0800 (PST) X-Received: by 2002:a05:600c:19c6:b0:480:3bba:1ca9 with SMTP id 5b1f17b1804b1-48398a65e5cmr33300315e9.4.1771421212695; Wed, 18 Feb 2026 05:26:52 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 04/24] fuse: Explicitly set inode ID to 1 Date: Wed, 18 Feb 2026 14:26:13 +0100 Message-ID: <20260218132633.29748-5-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421730897158500 Content-Type: text/plain; charset="utf-8" Setting .st_ino to the FUSE inode ID is kind of arbitrary. While in practice it is going to be fixed (to FUSE_ROOT_ID, which is 1) because we only have the root inode, that is not obvious in fuse_getattr(). Just explicitly set it to 1 (i.e. no functional change). Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 4cdf527d69..a56f645c05 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -432,7 +432,7 @@ static void fuse_getattr(fuse_req_t req, fuse_ino_t ino= de, } =20 statbuf =3D (struct stat) { - .st_ino =3D inode, + .st_ino =3D 1, .st_mode =3D exp->st_mode, .st_nlink =3D 1, .st_uid =3D exp->st_uid, --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421591; cv=none; d=zohomail.com; s=zohoarc; b=PFM1akHvH7CFUj2Zd838ckAuL6S9l5NgiTbKAUgrtqDBN5mUXQ8+HVxUBa9c1XMEMkn/Pwtqd67WCZb3ozTYwTtVNM77ZshNfD01AP0LbEP/FWdMuvdhEuykuP0/kcRXAm15esV/uW61vhEZ1A567zn7mzTCstcr4I4Uqvn/4Wc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421591; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BOixUczgf/re8Xp6Djr53L45pCSu7AEC5w4EK2f/CNY=; b=JPzzxwINyNWDUHWMfLLrH+xJRjuIghY/gvZf0Sz3sV9Qpw8DZGUlpnZ6Mqk2fBzfFGS9iTvvq20+s6BdhLzLGScEgTsY9P2ffKOt+7bf2z1nQG+hwQ6Ek2qVoowQ17TneqID0JZo0Cfp/KJ0+T2qq+H9/TPHvGVL7NoRdCKgImY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 177142159122128.077996206139574; Wed, 18 Feb 2026 05:33:11 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfC-0003rZ-M3; Wed, 18 Feb 2026 08:32:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfB-0003pa-4L for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:21 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshf2-0005GZ-HR for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:16 -0500 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-685-MYc6KdwxPwWBjvj89X6qLw-1; Wed, 18 Feb 2026 08:26:57 -0500 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-48379489438so43583655e9.2 for ; Wed, 18 Feb 2026 05:26:56 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4834d482480sm624827305e9.0.2026.02.18.05.26.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:26:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421527; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BOixUczgf/re8Xp6Djr53L45pCSu7AEC5w4EK2f/CNY=; b=cAO5cgZRzvNYp9QZORU0O6EbC9d06zYUXCdWIxrd18bhWNJh1pY+QuNPQxBFguUoExcTE5 IsksItraou6oIRP9A9XTatwCzSL6OrzBZzh065Smq3YPAzij7FTKXUQXPPTJ1KZ0G8U95s AFSYbOdrKbRByNJ9WHYSMv+nyjCwZFE= X-MC-Unique: MYc6KdwxPwWBjvj89X6qLw-1 X-Mimecast-MFC-AGG-ID: MYc6KdwxPwWBjvj89X6qLw_1771421216 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421216; x=1772026016; darn=nongnu.org; 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; bh=BOixUczgf/re8Xp6Djr53L45pCSu7AEC5w4EK2f/CNY=; b=d07ER0GU+tvnG9/0oDjiFekc5wUhaRtQ4GEqIlma1DjV1cVxO7lFx2wJyWkUd4znUR k7CAkfLXNP6k8YUn0IrZobMnARZgJkT+0hUjjnNWNDVAcPwhYA4JOtheA/DtDeE67D+7 IAkdiHf14ATvgMWfq97BHgJHAg00QJ9tZghC2kSpuslzk7M+TS8TVGwKlLEjddtTdCrH 8JKMG5xBTiTv39BtcXj+l9gzQEQqLjcutjly6MuQAYSr4cgWuktoFWpUCCUcX0I3JNS8 82cFxlnacvbfOJNAPjc6e3t4PgdJqvxaJ6/qI/MhNRt6DUo0U623DP9Eet2T19mS9kgV bRPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421216; x=1772026016; 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; bh=BOixUczgf/re8Xp6Djr53L45pCSu7AEC5w4EK2f/CNY=; b=eAHZuyH54f1mwV4HnAdqa33+3PT+m2fb4uILfB28oX6KHUVaicuUbxSOPVxiNnmbJ/ hzGGJ8H4oLu4BFh0tRv6P8am25A/UDayBCAvnltciNDML2DKCRFqUqJ+ii+2hHCU+ynM oYcEpzTxBSULgE3hd+1XPkJo1Uax5Bo/9ZfK3aSPEnjFVu1Pw1huDmES/bp+zlN+aeaX 5AsWb6NiGFrun8vA5yNBpO6NS4/q6JTFml/W0cOvLtifYsh2VxXQrvDN3vrQJExu94P8 3+E9t0HnEpu3NPn+LbmmbWV6z+69Z7Q+NF27pFpy3tGcnDusgA4lbXIR7bOokgEz5SW0 r8Pg== X-Gm-Message-State: AOJu0YxyRwjeYK/YFZmqYaqb6/24JCOlBW+cbW5YqOHT/54hWO1CF0vv 85SqwSddyoHvGthaWCyCk4MpLNcmQlyEXtCD1fWHEwBjiHr6Jj+NoNVeTZd0uOA1N21cFN4RwqY eYhX0aphgXviXLgenQdKVklgRO80SclUt38hnTCq9VkUp6cRGPTB+RJaS X-Gm-Gg: AZuq6aJxiyoTDzKlDyHnFYNWe4MjPfauhrZ5wOs2w9uw6YNx1wKe7Af0K1WfSUYWQ/9 5WO0P5O8urO3GDsRtLEVailhBKItUcvmkiec5G1qoqBMmhA1eykWFGM2N3npgsVbTDSgyenPWWN xRMqF8k/yiDFEyHnY8dA7bwf679510cZIxVI/huhHp0envZtF0j+AN8bky97zzLGrQQUFbJXdw/ ydXPa0+iwwzHoZmsNbNzdGkH5qsfciiqgnf72/lvns0Jo24TWLHuOHB7OMzP6ygly+Wzyi/KzAB MXz6sbEXFPPAv9+lZG6EDhgHaqEiTSNWe3vGatlgr2q4tfuS1EyvkJ+1s5c76c+Kx+h+aHw3VpD 5S2Iu8doocsD/XgJiKPMrmOI1cm9wA3fLi9wXvniKZ9iTik5f4zjA7XrJCgJD+QC8P5AaS22rPz VeYLM1 X-Received: by 2002:a05:600c:5295:b0:483:9139:4c29 with SMTP id 5b1f17b1804b1-48398a48450mr31689685e9.2.1771421215725; Wed, 18 Feb 2026 05:26:55 -0800 (PST) X-Received: by 2002:a05:600c:5295:b0:483:9139:4c29 with SMTP id 5b1f17b1804b1-48398a48450mr31689335e9.2.1771421215201; Wed, 18 Feb 2026 05:26:55 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 05/24] fuse: Change setup_... to mount_fuse_export() Date: Wed, 18 Feb 2026 14:26:14 +0100 Message-ID: <20260218132633.29748-6-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421607906158500 Content-Type: text/plain; charset="utf-8" There is no clear separation between what should go into setup_fuse_export() and what should stay in fuse_export_create(). Make it clear that setup_fuse_export() is for mounting only. Rename it, and move everything that has nothing to do with mounting up into fuse_export_create(). Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 49 ++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index a56f645c05..00bb2ffee4 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -72,8 +72,7 @@ static void fuse_export_delete(BlockExport *exp); =20 static void init_exports_table(void); =20 -static int setup_fuse_export(FuseExport *exp, const char *mountpoint, - bool allow_other, Error **errp); +static int mount_fuse_export(FuseExport *exp, Error **errp); static void read_from_fuse_export(void *opaque); =20 static bool is_regular_file(const char *path, Error **errp); @@ -193,23 +192,32 @@ static int fuse_export_create(BlockExport *blk_exp, exp->st_gid =3D getgid(); =20 if (args->allow_other =3D=3D FUSE_EXPORT_ALLOW_OTHER_AUTO) { - /* Ignore errors on our first attempt */ - ret =3D setup_fuse_export(exp, args->mountpoint, true, NULL); - exp->allow_other =3D ret =3D=3D 0; + /* Try allow_other =3D=3D true first, ignore errors */ + exp->allow_other =3D true; + ret =3D mount_fuse_export(exp, NULL); if (ret < 0) { - ret =3D setup_fuse_export(exp, args->mountpoint, false, errp); + exp->allow_other =3D false; + ret =3D mount_fuse_export(exp, errp); } } else { exp->allow_other =3D args->allow_other =3D=3D FUSE_EXPORT_ALLOW_OT= HER_ON; - ret =3D setup_fuse_export(exp, args->mountpoint, exp->allow_other,= errp); + ret =3D mount_fuse_export(exp, errp); } if (ret < 0) { goto fail; } =20 + g_hash_table_insert(exports, g_strdup(exp->mountpoint), NULL); + + aio_set_fd_handler(exp->common.ctx, + fuse_session_fd(exp->fuse_session), + read_from_fuse_export, NULL, NULL, NULL, exp); + exp->fd_handler_set_up =3D true; + return 0; =20 fail: + fuse_export_shutdown(blk_exp); fuse_export_delete(blk_exp); return ret; } @@ -227,10 +235,10 @@ static void init_exports_table(void) } =20 /** - * Create exp->fuse_session and mount it. + * Create exp->fuse_session and mount it. Expects exp->mountpoint, + * exp->writable, and exp->allow_other to be set as intended for the mount. */ -static int setup_fuse_export(FuseExport *exp, const char *mountpoint, - bool allow_other, Error **errp) +static int mount_fuse_export(FuseExport *exp, Error **errp) { const char *fuse_argv[4]; char *mount_opts; @@ -243,7 +251,7 @@ static int setup_fuse_export(FuseExport *exp, const cha= r *mountpoint, */ mount_opts =3D g_strdup_printf("max_read=3D%zu,default_permissions%s", FUSE_MAX_BOUNCE_BYTES, - allow_other ? ",allow_other" : ""); + exp->allow_other ? ",allow_other" : ""); =20 fuse_argv[0] =3D ""; /* Dummy program name */ fuse_argv[1] =3D "-o"; @@ -256,30 +264,17 @@ static int setup_fuse_export(FuseExport *exp, const c= har *mountpoint, g_free(mount_opts); if (!exp->fuse_session) { error_setg(errp, "Failed to set up FUSE session"); - ret =3D -EIO; - goto fail; + return -EIO; } =20 - ret =3D fuse_session_mount(exp->fuse_session, mountpoint); + ret =3D fuse_session_mount(exp->fuse_session, exp->mountpoint); if (ret < 0) { error_setg(errp, "Failed to mount FUSE session to export"); - ret =3D -EIO; - goto fail; + return -EIO; } exp->mounted =3D true; =20 - g_hash_table_insert(exports, g_strdup(mountpoint), NULL); - - aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), - read_from_fuse_export, NULL, NULL, NULL, exp); - exp->fd_handler_set_up =3D true; - return 0; - -fail: - fuse_export_shutdown(&exp->common); - return ret; } =20 /** --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421679; cv=none; d=zohomail.com; s=zohoarc; b=YFao6Zy0hJdzkSauzd8ggBO/ncIv7pPX0lQQ4P5kkRf16Y3zBnSBie2Vy4SPRcVhoMa1MBwNdWpUL5vfS97ttvuyzc9ICaI7uJurnxEkfs4sZLKV1N6lyekEmp9UdNb6BEZVNVGkFnFoUrM8dxMzg83PW1Uu14cvG/JyRatT6vY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421679; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=FfndHSyArVwAQZsbpd1CUY8UJ74t3/0SFuGSjOnWRHI=; b=Y9/C+1Txs96TPKTg2mZ2HSTawIWeXFyVNEhCEjkk9xPbstBi8fzUMGnFdGdO53/h8wnRVNxyp56e/B/kvalngXl52+K4Ycg0+QMzrjLkeivq78gMk7onJSMk9PJ9PTuQPDUg/VOCDZOMsW4RBh0y9JCwuUrWuls2QfI3ulcNv7A= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421679868494.34424500171485; Wed, 18 Feb 2026 05:34:39 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfD-0003tl-Pi; Wed, 18 Feb 2026 08:32:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfB-0003po-K8 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:21 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshf4-00059P-Ir for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:21 -0500 Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-153-xlGEiBKjNoq4TlYgOF-C1Q-1; Wed, 18 Feb 2026 08:26:59 -0500 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-435af2d3144so3820864f8f.3 for ; Wed, 18 Feb 2026 05:26:59 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796abc9b2sm39075481f8f.21.2026.02.18.05.26.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:26:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421524; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FfndHSyArVwAQZsbpd1CUY8UJ74t3/0SFuGSjOnWRHI=; b=brFqyAmEuT7Nmd2vgCuqJZLWdttdgIe+6DvEb+n4t/pnmfLsd0RCoZrdLMHKr3zEWougt+ ave2rZ1I1ceC+fMdCKlyRVatD8Vti8e58zMtq6Uj+qnhXRrRB0k2JVDEv0dAKEGZgMH0xi /E1fPdLvttFncmLc4lVpoT6j5OE/9GY= X-MC-Unique: xlGEiBKjNoq4TlYgOF-C1Q-1 X-Mimecast-MFC-AGG-ID: xlGEiBKjNoq4TlYgOF-C1Q_1771421219 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421218; x=1772026018; darn=nongnu.org; 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; bh=FfndHSyArVwAQZsbpd1CUY8UJ74t3/0SFuGSjOnWRHI=; b=WaZ6f8MhkBLaE4tqIpqNUYmYBehM+x/KALuPbiZYOLhs2bkhSZpO+Uw9eDS1Gd1B6h vaGk4EBmdf/Qf9TJSSnp/jv0/NusH/yIa2mArI6ezNasZXb+GYYdGlK3Q5DwO/wjmVIG lnyjcd/3UJNqvIg5xKQTHjdr8rGhxEHt4oZMUOhmwxtp3wk4+rFxmuvISossCDS4AyLi 4/UFqCTLFzG459UxmtsYQqFGHRiuUZl9fP2KPyyV4puTVBOJ/jrpi1v2y75SEYL55YT/ NAXXy4ex4dl/it13ZwimCUVZyvIrZfHx7s1nqecNoo3//2TAt2U7Sl6o9LRqXmx7w2bE PwLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421218; x=1772026018; 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; bh=FfndHSyArVwAQZsbpd1CUY8UJ74t3/0SFuGSjOnWRHI=; b=JasgSR6HEKXUUTtbax4+6AhYT0ezaLNTBpbaGArYzSOj/9ROBcoKXJw76h6Ywff9fG ckaO0xaOX+Jmg2gRlEL+CmANcKgQaouk0V8JvK5arbvNUxCTH2fRG3TDxDUPcBTZSbH4 gXjpzla32SYUv9l9AUQ4wNqtyueRABnZFL7Cl2evzmADSnFvlMAAreXkdsZyP+tNegjh pO1SxkLPl/R2y3Zlj/5WlG+aZuV6DEw+VJ8oSHpg0GnCn9qSYmuPKa9DsLKZ0qmbDox5 1lpnNtglm2SCIhYSrOP8WObtYEKgevPTMYKSsDXcAGNYRXMlEfCwpVGM8OAjn+7w23To EDVQ== X-Gm-Message-State: AOJu0Yxpsaq1itP5+b18MshIb4Q9fHzi/SyeTaMmCHrbVdVuAjfygZpG 9ThGu+7zI7nuNU06t26A2g40YQ9wXM0RulsAdGPBDDfr9eDVytu4WN14XWpk73HcHI1ZipBf2PO B5/2JMLkKSi3M7MBOQtbspU6an19SA36Nn8ph/j8ZMQ/fUUZ8pSL6rfcG X-Gm-Gg: AZuq6aLtKpTg0h4GoZgRQ5IM5iRVjWI73sdchPM/uWgjQ1uxCcaE3W+h71IGfEi58vh zo1Bt1GuGYVWBCEkG4TSSBsjsIz/Z6f0uOQRmfqw8WMpStdmF8HhlMXxf0ZBxJeuHUb14h8lzZv d+qEY6N73akcelFxIM2pDaX8V80WgAvZ+VfnUoCX58W7VeFkj44yqnPDpVNsnRbNHH4ffSnfQzb FSgXyerOJ4wZytcoxNIg0+jUUjrGyPJ9O9NYgBl6NqqWtNW8iFaimtqmjxtzNKxzF6AF2YB+UG5 bdUKRn7PNsprQ8VvA6EtR7d1il2rx8x2e2ya3OUZ0/b5rBPn/527/VXnmkHDYkkD3vRi+7ncBZt Fly2jXFVxvYLI1kGQRkrKDMD5087eoplLCDcu9Et4uHGbpKsaLCtE6y6OUwpUAgzkaYArw42xV9 w/7JYM X-Received: by 2002:a05:6000:248a:b0:436:38a4:2423 with SMTP id ffacd0b85a97d-4379db66905mr26130217f8f.22.1771421218532; Wed, 18 Feb 2026 05:26:58 -0800 (PST) X-Received: by 2002:a05:6000:248a:b0:436:38a4:2423 with SMTP id ffacd0b85a97d-4379db66905mr26130174f8f.22.1771421218078; Wed, 18 Feb 2026 05:26:58 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 06/24] fuse: Destroy session on mount_fuse_export() fail Date: Wed, 18 Feb 2026 14:26:15 +0100 Message-ID: <20260218132633.29748-7-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421681450154100 Content-Type: text/plain; charset="utf-8" If mount_fuse_export() fails to mount the session, destroy it. Depending on the allow_other configuration, fuse_export_create() may retry this function on error, which may leak one session instance otherwise. Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 00bb2ffee4..82560ca071 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -270,11 +270,17 @@ static int mount_fuse_export(FuseExport *exp, Error *= *errp) ret =3D fuse_session_mount(exp->fuse_session, exp->mountpoint); if (ret < 0) { error_setg(errp, "Failed to mount FUSE session to export"); - return -EIO; + ret =3D -EIO; + goto fail; } exp->mounted =3D true; =20 return 0; + +fail: + fuse_session_destroy(exp->fuse_session); + exp->fuse_session =3D NULL; + return ret; } =20 /** --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421726; cv=none; d=zohomail.com; s=zohoarc; b=T/inedG6bBQJR+ZZOsN4N4nC5IJ6Sy9BYDuI1uVG5wsKzIHJ0OrS9YuYdIBGq5VopJOoJ6Ztv9iMIO35NDPBnrqtFQGe1qwW8N//cbisNaBvh3xWF41hSWKL9OdNuCKMUdacqz/i1ZVSz7zDvIh0jTezDwZe8XRwUhMRQqc30RY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421726; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=gLvuW77pQ5x9M3qdYvEThGlMMRQ1FN319y82FStW6pw=; b=QOdSjnLR+kvmRSCzZ0ZltDCDI3nTB6mFaqpzOdnSECwBNK9n83b8Yqqjg90FNh+oudmoeHz5mvdtxqMA4TIq49BPNMFFI5i/6zsMfMnbwH60P3y/fIBqgCx7LroqWu8M5vIc1XoOH51skkH72ZuuPzq8eLZ8gfmHhr2e+nxKIec= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421726626814.4737538344406; Wed, 18 Feb 2026 05:35:26 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshff-0004F3-Cv; Wed, 18 Feb 2026 08:32:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfR-0003yM-0z for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:38 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfA-0005GT-H7 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:32 -0500 Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-441-mM2CUbCqPAqmQL-72PjDug-1; Wed, 18 Feb 2026 08:27:03 -0500 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-4362456500eso5072545f8f.3 for ; Wed, 18 Feb 2026 05:27:02 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796ac8075sm40458516f8f.29.2026.02.18.05.26.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:26:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421526; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gLvuW77pQ5x9M3qdYvEThGlMMRQ1FN319y82FStW6pw=; b=IuK+oieRBPbAHZ/PdGTg3HOp3VIzRwcwpMpn+WcQLUcTALzHNTjbV4dy8VZCFIcBztjEma F7eQfOBJAzZs54OdCKL5768EXo2ZzhUnwTnLIMe2/2aoRkIUUmpr5vWrVNYBRZvNTWH5Qv 91BIoH3so7/vbaOAZ8ocUwmmM4sPUlo= X-MC-Unique: mM2CUbCqPAqmQL-72PjDug-1 X-Mimecast-MFC-AGG-ID: mM2CUbCqPAqmQL-72PjDug_1771421222 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421222; x=1772026022; darn=nongnu.org; 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; bh=gLvuW77pQ5x9M3qdYvEThGlMMRQ1FN319y82FStW6pw=; b=kZeWtETweoTM0EvS4KMJRSPB84n6SdJafqNl7hBgDfygtwwN1n3mi7JMA6InRe4Vz+ HBcMHDDvt3WzXTrSXW/JAQw6H7cXhtHI8ZGxZjRtTtmhTw4Dzdyeli0MfQ5elmrw2hhu OBB0pB3Wem/rgIme0KxLFBslPs9XYCZ5yLizQoxAhO3P1ktR4hyevjG3b4+kAzh9e0Nb Ut/Snn+uH7f5FOwdFJQH2g/BV6ywZ1nDEPRohG6ArGYsdNB2dKbvmlWduNepP1yIaq3l Rb6eiwzdsgFW6BIbx+9iAhS+DheenxesBjFGv3co/pfhOyGa6Ht8OxrL3JEPaju0meb0 VuMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421222; x=1772026022; 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; bh=gLvuW77pQ5x9M3qdYvEThGlMMRQ1FN319y82FStW6pw=; b=lerPWVB7Pu2Xx2RkzLw/2XwpW3c2R9KsVS9wzAQRhe2S9ukBfAAXMNdHV2j8qA0/aM avo2HS/+2wa+cnkJ/pYrAVKMpyuox3OUA3vOVEURv4fSR39cxYpwV6kzzIwhuDytoLiS rlvHVSRvWw8YFYgByFiC+SeDKbhbDkS7aOsB2MIe/RI2pqYp+4Z+nIm7lQQyx+hH/w+H tA0QXXG792IU/Ha9S/AGy3/QwZ5OKMcBc1UOHwEldTAkQsVsRHTb2spm12oW3r3UAOuz F5hkuym/r2EOsKDrNwHU8TEXFOhpvkMsVVhtU4oEdxe5Z+NIzk2UiJ0KpUxApTqJb8D/ liKQ== X-Gm-Message-State: AOJu0Yy+tXNgPXQ2RMpTKQDF2+bYxwwKBMk2W+nPubTea1EpNaL8gdOc 2mkWL/+jsFtxlhy8LSaB6LxrqWJ+IAwSC+M9n72/2DWblRbjuUNjd0zVEoOYCYyxjwkFo09+KwN g2viIQfX5076NYgSdSJNWUAF5AlQ2LEEEg0p1PsW4FnPIOSWTEy3kIxiT X-Gm-Gg: AZuq6aIs2fyCJnRltZRVN1tqUgGf4BQYcB0lqr5qe0lDNbOi0feOxFDGDRpspq7ULru 4hbKyOgua33j7c7voYtdCvFtU4D2ZLDnoXVqVggyfEyyyCco/czvERE8G69afGU0yQMczR7zJLH NyJT8vQ//WppU9pwxEVvKeUHjbtU9MvZAGluFMy4U3lDigWg06I40DEZnu4xZNcWLlLE893RAXy e3iWWXRC7xbgjJ/IUURNnHXEUqp0x+FUOAcnPaGEqxGmjSrmR2go93jmYFp1H6SPJICcrMsPBqa DXU6nZ8jOyVMW/6K71GnDluQxULEI0aTccbTb/d+/+QsOIUaNNtCMzxHIbExe8v+eWy8YgKns8R rSbMH5Peen9kZkPsYMVmqbhoapWFZbtQb5gaUFhqHcwP3IMhX9L5dLFt95zGwNb+zFR0MYbZ7Le pIn7KZ X-Received: by 2002:a05:6000:4387:b0:437:75c1:5777 with SMTP id ffacd0b85a97d-43958e00726mr3005882f8f.16.1771421221778; Wed, 18 Feb 2026 05:27:01 -0800 (PST) X-Received: by 2002:a05:6000:4387:b0:437:75c1:5777 with SMTP id ffacd0b85a97d-43958e00726mr3005839f8f.16.1771421221290; Wed, 18 Feb 2026 05:27:01 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 07/24] fuse: Fix mount options Date: Wed, 18 Feb 2026 14:26:16 +0100 Message-ID: <20260218132633.29748-8-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421728946158500 Content-Type: text/plain; charset="utf-8" Since I actually took a look into how mounting with libfuse works[1], I now know that the FUSE mount options are not exactly standard mount system call options. Specifically: - We should add "nosuid,nodev,noatime" because that is going to be translated into the respective MS_ mount flags; and those flags make sense for us. - We can set rw/ro to make the mount writable or not. It makes sense to set this flag to produce a better error message for read-only exports (EROFS instead of EACCES). This changes behavior as can be seen in iotest 308: It is no longer possible to modify metadata of read-only exports. In addition, in the comment, we can note that the FUSE mount() system call actually expects some more parameters that we can omit because fusermount3 (i.e. libfuse) will figure them out by itself: - fd: /dev/fuse fd - rootmode: Inode mode of the root node - user_id/group_id: Mounter's UID/GID [1] It invokes fusermount3, an SUID libfuse helper program, which parses and processes some mount options before actually invoking the mount() system call. Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 14 +++++++++++--- tests/qemu-iotests/308 | 4 ++-- tests/qemu-iotests/308.out | 3 ++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 82560ca071..0422cf4b8a 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -246,10 +246,18 @@ static int mount_fuse_export(FuseExport *exp, Error *= *errp) int ret; =20 /* - * max_read needs to match what fuse_init() sets. - * max_write need not be supplied. + * Note that these mount options differ from what we would pass to a d= irect + * mount() call: + * - nosuid, nodev, and noatime are not understood by the kernel; libf= use + * uses those options to construct the mount flags (MS_*) + * - The FUSE kernel driver requires additional options (fd, rootmode, + * user_id, group_id); these will be set by libfuse. + * Note that max_read is set here, while max_write is set via the FUSE= INIT + * operation. */ - mount_opts =3D g_strdup_printf("max_read=3D%zu,default_permissions%s", + mount_opts =3D g_strdup_printf("%s,nosuid,nodev,noatime,max_read=3D%zu= ," + "default_permissions%s", + exp->writable ? "rw" : "ro", FUSE_MAX_BOUNCE_BYTES, exp->allow_other ? ",allow_other" : ""); =20 diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308 index 6eced3aefb..033d5cbe22 100755 --- a/tests/qemu-iotests/308 +++ b/tests/qemu-iotests/308 @@ -178,7 +178,7 @@ stat -c 'Permissions pre-chmod: %a' "$EXT_MP" chmod u+w "$EXT_MP" 2>&1 | _filter_testdir | _filter_imgfmt stat -c 'Permissions post-+w: %a' "$EXT_MP" =20 -# But that we can set, say, +x (if we are so inclined) +# Same for other flags, like, say +x chmod u+x "$EXT_MP" 2>&1 | _filter_testdir | _filter_imgfmt stat -c 'Permissions post-+x: %a' "$EXT_MP" =20 @@ -236,7 +236,7 @@ output=3D$($QEMU_IO -f raw -c 'write -P 42 1M 64k' "$TE= ST_IMG" 2>&1 \ =20 # Expected reference output: Opening the file fails because it has no # write permission -reference=3D"Could not open 'TEST_DIR/t.IMGFMT': Permission denied" +reference=3D"Could not open 'TEST_DIR/t.IMGFMT': Read-only file system" =20 if echo "$output" | grep -q "$reference"; then echo "Writing to read-only export failed: OK" diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out index e5e233691d..aa96faab6d 100644 --- a/tests/qemu-iotests/308.out +++ b/tests/qemu-iotests/308.out @@ -53,7 +53,8 @@ Images are identical. Permissions pre-chmod: 400 chmod: changing permissions of 'TEST_DIR/t.IMGFMT.fuse': Read-only file sy= stem Permissions post-+w: 400 -Permissions post-+x: 500 +chmod: changing permissions of 'TEST_DIR/t.IMGFMT.fuse': Read-only file sy= stem +Permissions post-+x: 400 =20 =3D=3D=3D Mount over existing file =3D=3D=3D {'execute': 'block-export-add', --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421702; cv=none; d=zohomail.com; s=zohoarc; b=mqmiOcSdg6qdt7YwmJofwI+ogB6XKWwdK/XPFmNmMyNUOHZlnR3FNYZ2bCq7WOEpvvNhqT1taz2WWwxiUzYgQjoojQrnVJPe23I1xuhyeZdczTR3YtpZEWBMAUk/DuMksz2Il/wYeGAjvaxRYDjdHsxKJIED5LOdAJHT7dSgIjg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421702; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=KNGtHA3kcdOL2SVcnUEo+P1ksEysivVPpQTbAQYAGcw=; b=B5oNs6q6nQdPIhxI9uI3vGaRMS00X3iNAKTg8t4iqZaBIAL11HUGDxforsTBEJRCj/1fiO5g7ZfBsxMh0XdEd5c1DWz1IrNlPojoeYMuMRNk3Stl4WT/as6a4Jx6DdNAD6Y1b+gKEVmkP/ajSabYW2LrFoT5mXw+nnsRQrG47D8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421702427315.9581034987957; Wed, 18 Feb 2026 05:35:02 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfD-0003tV-Lq; Wed, 18 Feb 2026 08:32:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfB-0003pb-5R for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:21 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshf2-0005Hh-09 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:16 -0500 Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-455-hdgelCW0PjO0dimMrVNx9A-1; Wed, 18 Feb 2026 08:27:05 -0500 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-435991d4a3aso3508161f8f.1 for ; Wed, 18 Feb 2026 05:27:05 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796a5d156sm45786805f8f.5.2026.02.18.05.27.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421529; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KNGtHA3kcdOL2SVcnUEo+P1ksEysivVPpQTbAQYAGcw=; b=iFCc3302pjs/PE6hTzevM6QYVNl0sx98KM+UU42YV1HuVMGSriI/EuEQnFnpCXDy9xh/p4 1mKFI/IrXgM85ov20vIKH8Cen+R61YqfObXn/hWh66I7Rg86isJ4FGaHEIi+K4R89O+XvT GamJLEK3RGdEKY6mm2Mj724zWtY7gqc= X-MC-Unique: hdgelCW0PjO0dimMrVNx9A-1 X-Mimecast-MFC-AGG-ID: hdgelCW0PjO0dimMrVNx9A_1771421224 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421224; x=1772026024; darn=nongnu.org; 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; bh=KNGtHA3kcdOL2SVcnUEo+P1ksEysivVPpQTbAQYAGcw=; b=kfA7iLv8Pa0vvoxELeloKQr2gUp5kEEV8RraNBayCDTyOstqUAEFOQBpOMY0bHx7jV ls8b+lYqM0OSwpXakNGDsgWC9W2krP6Rh4/UVzcTppcQVN9E5SB2BhRfpo604PgoVW/b OfsqvKHvOnmC35az9IlU1FlJblH40bSJaOi6OnkVmNi/Jrs2+961hQeDifLLGTUotKeH WHaC7U9t748CIMMD8BKiJ/Yy//n/eNhZwy5F6fCQOaMlzvYb0GItEfO5ne/pG94VAr9T mXEeNKJkQNeznjlGVr/WnrTrP4+nYe/CHjLfjFIM1rcFq2W56Dc/dIMVOaoj4INe0o1Z F9hQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421224; x=1772026024; 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; bh=KNGtHA3kcdOL2SVcnUEo+P1ksEysivVPpQTbAQYAGcw=; b=MO/DDb6fM+xFf0qXBPodBv+mmgNHwhMW2wwTcdx6LrU2xvKhjWX9zJmqd3EPa8b9P3 VwEuML3a1CtV3SD6Ytca98CGhVCo1QRz2BlendrVCJrxpRX4lbKfCBOipNMSO2oXVFaE Hb+HH3dFrIVayrvHauzsf0QjlTSNaAi8ZzgF3GtIGHOFiSsrTwjYIQ91V3iX56nlFDLo 1McYcINCajWiE4y6as/zLgXIjqw84WWbXgvUfSGagUxi0B+Zr1e3671a8uz/hLWPOQOw r61GATi9iIkHTR/wftB07Q1usD70K66w2/poq0y6NULqKUvkkFEMA0aIwZk5WwX+PTdN f3mg== X-Gm-Message-State: AOJu0YxG2dolzSrAOxIGrfSG7csiJgaSz4OKupwV8mIo8qxUi0BpzkPL HV47ukGyQoB7Rn2Vm5fHo59sTLW4KPCRxTiUSYNZZjIqy2p3BlJiJ4dZrrIvu+ac5PS4Xkn/KxO vNqHboLok7Jwcs/BCftQM/Si5DtndH0c4QFBA9l4se7c6r2v+t4OH6V6t X-Gm-Gg: AZuq6aLb5wZb8pcqRa2WHLCuCkfEnBr/an8+lerIIutsAEKeFtvhUKES3FXKRwh/hhx 6aaZFhd0lFTgYrPOwOpVzIGpBHQCA85aBna5pUDi2QfIylK92VV2P7wJ9c2GTCFLdMO1pcgNFgq M/nafcgK/G1iJjbMY/nhb/2joIf/05vRLcEtPjxCMJ0XQ+ZZvWpGsdeG8V0OVhb+mSZlEYjZMIY vmI4rYld6aPIIumZ2tRBwPvqXknLT6Dq3QLpxku05k5+QdqKrl6NMeY9yDPueMRa/8EKJUT4nXU Qd5vAxmuAVJql027lUBQGxMemCTai/alvvfQqcSkhhHx1/dhvS9mD4iwAip/O1XMQiFZ1JGbRjg nsdJeWzXWG0ILiAxBUzldbpnDRERt9UaXDVhk764qWhzhS/Z4AZCx2Lw51XcUeA0s4q26froUVh SQHn83 X-Received: by 2002:a5d:5f53:0:b0:436:3536:f694 with SMTP id ffacd0b85a97d-43958e0e72amr3221025f8f.22.1771421223990; Wed, 18 Feb 2026 05:27:03 -0800 (PST) X-Received: by 2002:a5d:5f53:0:b0:436:3536:f694 with SMTP id ffacd0b85a97d-43958e0e72amr3220983f8f.22.1771421223529; Wed, 18 Feb 2026 05:27:03 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 08/24] fuse: Set direct_io and parallel_direct_writes Date: Wed, 18 Feb 2026 14:26:17 +0100 Message-ID: <20260218132633.29748-9-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421704938158500 Content-Type: text/plain; charset="utf-8" In fuse_open(), set these flags: - direct_io: We probably actually don't want to have the host page cache be used for our exports. QEMU block exports are supposed to represent the image as-is (and thus potentially changing). This causes a change in iotest 308's reference output. - parallel_direct_writes: We can (now) cope with parallel writes, so we should set this flag. For some reason, it doesn't seem to make an actual performance difference with libfuse, but it does make a difference without it, so let's set it. (See "fuse: Copy write buffer content before polling" for further discussion.) Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 2 ++ tests/qemu-iotests/308.out | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 0422cf4b8a..d0e3c6bf61 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -582,6 +582,8 @@ static void fuse_setattr(fuse_req_t req, fuse_ino_t ino= de, struct stat *statbuf, static void fuse_open(fuse_req_t req, fuse_ino_t inode, struct fuse_file_info *fi) { + fi->direct_io =3D true; + fi->parallel_direct_writes =3D true; fuse_reply_open(req, fi); } =20 diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out index aa96faab6d..2d7a38d63d 100644 --- a/tests/qemu-iotests/308.out +++ b/tests/qemu-iotests/308.out @@ -131,7 +131,7 @@ wrote 65536/65536 bytes at offset 1048576 =20 --- Try growing non-growable export --- (OK: Lengths of export and original are the same) -dd: error writing 'TEST_DIR/t.IMGFMT.fuse': Input/output error +dd: error writing 'TEST_DIR/t.IMGFMT.fuse': No space left on device 1+0 records in 0+0 records out =20 --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421708; cv=none; d=zohomail.com; s=zohoarc; b=ZHUhtmtSvUCzKM9j6W+Y2HAAhSdP2AuZYW0rWJW/+1O70if4Zyit1T7UgQ4y/UezlI0E1/A7kUqw6ZMvjE77CQFpTxYbu5fKV4rXGw41t8CXrs7ea8XBK9bwQ91xRuDb/42SLuZ6nmsY/In5aG+XOvqyhfzAzcqQpsfq9NUuGT8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421708; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=muqu2YymWMHLeGtaHW7SS1VV742IfcBS+uS47ikVE8o=; b=XIsGX+qp+P+NbMXdOTC6Yx/VPfEmI/DPELjuOOmM811be9n+Vjwe/y86Nhj6O1ued6YCK1mmVyJoKS6UZleSsOTEMjHarZ0WDuSUuCpD+Pf3u+c2Sv7mS7ZxvYGvHCbj30wVTtqFMx6dzVORhFJuflzfaSEJHIha4rTixZ1KP1c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421708557128.41263889216646; Wed, 18 Feb 2026 05:35:08 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfW-00040A-SS; Wed, 18 Feb 2026 08:32:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfQ-0003xa-9z for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:36 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfA-0005J8-Gs for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:32 -0500 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-25-BybK5eeIODuikDuU6cejDw-1; Wed, 18 Feb 2026 08:27:08 -0500 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4836bf1a920so61261805e9.3 for ; Wed, 18 Feb 2026 05:27:07 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4839839d960sm29902525e9.3.2026.02.18.05.27.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421532; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=muqu2YymWMHLeGtaHW7SS1VV742IfcBS+uS47ikVE8o=; b=e02Y8LjI2RxtKD85DIy+v56MLqQ4+ZnO7q7U0OxnB3kqUYzxe7kSO7DEPk9qi0Ygqgn3Vo xxd4SPQ4BYkwnoO7I3o4MAYhwD0MxXeYoqq/Rb07GqYIRRcfklZYQcHcW5fmcLpH0nYAAr MNltzX8cEA1FQ1ckUuAQtjziAFp3jEw= X-MC-Unique: BybK5eeIODuikDuU6cejDw-1 X-Mimecast-MFC-AGG-ID: BybK5eeIODuikDuU6cejDw_1771421227 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421226; x=1772026026; darn=nongnu.org; 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; bh=muqu2YymWMHLeGtaHW7SS1VV742IfcBS+uS47ikVE8o=; b=Z3nfce7LEJ3MDE7lLXvSOEmOAxIE8Kp0vC6j2SLx+iTSG5onfaI2YijdKMHvYfMBjI lPF2Iw0vfaDO5T/9Bh+yD4kdOGpkKthIjKT5l5hk67inTFtE2rRo6OIC44CcR9+wqWso qfCk7VrROKcFALYc2D/ZVRktsYltA3Q5TlzDuxrUOoT3HxyrE2DoEOgX1r7P3vmoL6g1 3hLIL+MpGyWqNt1d2XBJgJR9SOseoTfU4sxn4rZs8C6XfXjSeN//kFblw7MXTlDSJ+IL HVEUjmt99VdZiVgPgfXMN0CTLbrOlu4ZDg3Oe2etMLjaXu3G50PBFCSZykt3ZxZExDHN uZ2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421226; x=1772026026; 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; bh=muqu2YymWMHLeGtaHW7SS1VV742IfcBS+uS47ikVE8o=; b=TW+VAMgbdQg78oskHUDodt8gngfCmerl0id+XBqMOtFWovNWMq6GWuMa9NgcazCB2E gq0A65RmwkXkcxWt1TijJb6VuGSuRxSIBXYyiTwdNjSbr5UAJbdDiDk0LhNOzORdPfrl ol71kxlq8JbVxZULNWxsqOkUZzJUeXCbikpHFGqm3dMK547CBlm3wx0EuJnV6s4HMnRH 5ClB/bhkPTVtDbXJzGqAfzfSMWgJMyjUhzwOY91XDCEgKtekIpU5ZiBisol73bSP72wX iVGRPGJ4xP0NXDJXVFhq355CLY8OU4jc6Rxsl8g83+t2RCRgPHW+uaqmpJJSm6J3PqbP iOKQ== X-Gm-Message-State: AOJu0YyJL+s9GDpmim/NNihMw0G2X+du626k7WCjx2HezsElBmXigMFQ UikAD+yOgOKn/ttsL32qfNiHWjIxGm/xK+5M8/T1qSbfA3j/bKxXVIZLaeI45Q+kb1h8XJ5SCG9 WUJ+nFkS0EXmm5AESUQ8thi+T74y0iGMHY9nxBJjMuvbN5BElWxqj5R7A2CAHdF+k X-Gm-Gg: AZuq6aLMe43z4SBU9OA5L7a2uDA2vfxHWYQRcRLLotfJzXGhJsHO0UkuTIwFI9DKA4g o/yqfzSHeyWlYnIlrLKFq39G1JUHDeXIAqRPw6E39r30kGoj2iMbDCW3iJ4HgBPqJCWus12qOhd kWRf+BPAXJQwla7riFGgw12DBZVkC465PlFHMHcpYLmzpzPMtgKkknPCcUOiBSsCH/3qE617cIN vemcEJcgQIa9VP27XOgNXkw7AFpgmVSd/ZjNchASiWcZ007omlRANBdUfTQZUo2r1VxaaTc3WQ2 SFw4ihybjkUYZJhviwHYKa8/bhOVkORGsFm1cU53HZy7fN2FTZqmayb3WaJwi3kVH/n8sH4Qtfo mNsfYGWrdFKCecZyKeN2rGMAsZ1yW1bT7PYRJFABvVmFLn3yPAP+rjbHWajMQkuDeKslmM4bktW uH6wJf X-Received: by 2002:a05:600c:4744:b0:482:f564:d613 with SMTP id 5b1f17b1804b1-48379ba8f46mr247682125e9.15.1771421226446; Wed, 18 Feb 2026 05:27:06 -0800 (PST) X-Received: by 2002:a05:600c:4744:b0:482:f564:d613 with SMTP id 5b1f17b1804b1-48379ba8f46mr247681715e9.15.1771421226021; Wed, 18 Feb 2026 05:27:06 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 09/24] fuse: Introduce fuse_{at,de}tach_handlers() Date: Wed, 18 Feb 2026 14:26:18 +0100 Message-ID: <20260218132633.29748-10-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421709901154100 Content-Type: text/plain; charset="utf-8" Pull setting up and tearing down the AIO context handlers into two dedicated functions. Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index d0e3c6bf61..5953407f20 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -78,27 +78,34 @@ static void read_from_fuse_export(void *opaque); static bool is_regular_file(const char *path, Error **errp); =20 =20 -static void fuse_export_drained_begin(void *opaque) +static void fuse_attach_handlers(FuseExport *exp) { - FuseExport *exp =3D opaque; + aio_set_fd_handler(exp->common.ctx, + fuse_session_fd(exp->fuse_session), + read_from_fuse_export, NULL, NULL, NULL, exp); + exp->fd_handler_set_up =3D true; +} =20 +static void fuse_detach_handlers(FuseExport *exp) +{ aio_set_fd_handler(exp->common.ctx, fuse_session_fd(exp->fuse_session), NULL, NULL, NULL, NULL, NULL); exp->fd_handler_set_up =3D false; } =20 +static void fuse_export_drained_begin(void *opaque) +{ + fuse_detach_handlers(opaque); +} + static void fuse_export_drained_end(void *opaque) { FuseExport *exp =3D opaque; =20 /* Refresh AioContext in case it changed */ exp->common.ctx =3D blk_get_aio_context(exp->common.blk); - - aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), - read_from_fuse_export, NULL, NULL, NULL, exp); - exp->fd_handler_set_up =3D true; + fuse_attach_handlers(exp); } =20 static bool fuse_export_drained_poll(void *opaque) @@ -209,11 +216,7 @@ static int fuse_export_create(BlockExport *blk_exp, =20 g_hash_table_insert(exports, g_strdup(exp->mountpoint), NULL); =20 - aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), - read_from_fuse_export, NULL, NULL, NULL, exp); - exp->fd_handler_set_up =3D true; - + fuse_attach_handlers(exp); return 0; =20 fail: @@ -335,10 +338,7 @@ static void fuse_export_shutdown(BlockExport *blk_exp) fuse_session_exit(exp->fuse_session); =20 if (exp->fd_handler_set_up) { - aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), - NULL, NULL, NULL, NULL, NULL); - exp->fd_handler_set_up =3D false; + fuse_detach_handlers(exp); } } =20 --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421666; cv=none; d=zohomail.com; s=zohoarc; b=aEF605ixfwGYRo5CD8VpqDk7W6KpE63Lz0Y7RF6w6lpDAIpqPo6wbhaJ+3Wzx698cYsHDhe4qy/I9vEDGSkegf3a5Oz168eDdOYhoswr7q9096ofJrjxrkqEhp++SCQu/6vN/ZVqxIJ4imT+4ThJbWR3cE1jdvwYZEmeE0XKJzg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421666; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=H/8FdOawT4l+d49GakUVhtVVYAdyZ+VALEhrmRAkR5g=; b=b5XJDlxsqfO44XtTlw4JX4bBlcnKPDiPzwad/sww8Baf+UgnOc28f6wl1/+x/KmA4xOCPZjPCMMwyGYiyeo9i+qdLcAICROHlg4rNPeaZ2IiAi2IoocXFH8N2Vo6UR3rUs8JffwIV+t2yWQ42zS41tRBy6++IFL/66rYls4PYEs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421666452571.5688721242841; Wed, 18 Feb 2026 05:34:26 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfw-0004V7-7a; Wed, 18 Feb 2026 08:33:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfs-0004Tc-ES for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:33:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfq-0006H4-Q0 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:33:04 -0500 Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-674-cpq-_mlFNryWRWGqx9VqlQ-1; Wed, 18 Feb 2026 08:27:10 -0500 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-43766514653so3635683f8f.0 for ; Wed, 18 Feb 2026 05:27:10 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796a6b563sm41211339f8f.12.2026.02.18.05.27.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421582; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=H/8FdOawT4l+d49GakUVhtVVYAdyZ+VALEhrmRAkR5g=; b=KlftOX/Mg3eZ1lr2wiC15qIE7vhfsAu22IarvdmDrcWW7jgnOI9yR+NUp/5FJCRjYLDpwy upV9Bf/sOnoFsTJqgrFmvxzhfXzGsKtN7FR28hQRXSy+gTjxYt6UrsT97PiqkNROpfs0IH wBKEJndXk3GsE1zv0eySedgwkSG6aUo= X-MC-Unique: cpq-_mlFNryWRWGqx9VqlQ-1 X-Mimecast-MFC-AGG-ID: cpq-_mlFNryWRWGqx9VqlQ_1771421229 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421229; x=1772026029; darn=nongnu.org; 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; bh=H/8FdOawT4l+d49GakUVhtVVYAdyZ+VALEhrmRAkR5g=; b=Jlvj8D/HU6fggWyW3Ci2S191UD4qRJhGqLkOmm99BcZqUnWLBXqc5Ai9y+tu1JRSI0 rb7HLdUR+ZpGd6NmdkXXphhLRr9xzlfoWubc2Ken16az8UMsLYYgfS2qAmWJ4jOip4tg jyTQjKugD+0GdI3dj3X8j3XFQ+97WO1Hp1NEvFUqp+PW8mrGoWAGb2/6BBEsmmvkuzXW rKazaPzbc/Qp3rEH1rU2GQfZAuAFQTXjmDDSgErEJ5pzWoefs6wJAEJidKdefYWp+5nX g/bbRs1ZCQ6AL8Ky1HKaO64cuOesBaDpewbr/SwYaovdB9WgsvQXSSQhl6xaz5v/3gQ9 f8Tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421229; x=1772026029; 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; bh=H/8FdOawT4l+d49GakUVhtVVYAdyZ+VALEhrmRAkR5g=; b=UsTiAa50d/hmN0OzO4vOD0y0zwL+i19W3lzBCU+AvhbGAE1c85HBIk5ktMG91cep2t 8yXut+fDQaWLYOM2V1i8pMIXi8UPZ02pd75QbjfRR9KBE7WS1li0eibp0B3WFkOjSj3o zFClojoNIQDHbR5Ibn6wnd+mnYX5aYD/gFxtvSqvs6C+kcmbZ3FBKaytvhfZgZK02fpC bSTdYI0WuJtJcbqzt2suGT6LYy09a7f4ItrQSLhfSbdxWyC+l53zbZ2LiObSjKV2eRP9 ywTtfuUkEaXG22WXziKU7NTQFUuOeLlcNvq4IxTLtgU/5Mk2MQ7Wkx5h9/561BDFWy3J cNRA== X-Gm-Message-State: AOJu0Yw3X6a9juO/jABM820AJpGUd6b2DUVpLXtV+gJnRPbLOuHojcyY kL7IPIAvxSxS+4Gs8infZg8Ug6Oqv62Q1/p/GSpIGRtbKgklqrFgUDZI3rU0SLyWsLTBZPBsm9k 0fwoh3x62NNpf0HVmNANBgd+l+Ur6M4/0H3Bv410IKx62+kaBywgBK0F8 X-Gm-Gg: AZuq6aJXrs/DWqdzoq9veKBoQoh9R6BR9ZK2CAe/Kfo1DIr4eLzj//jdvQXJmEQOPxZ rZzw8oruWA0JAkL1d1BT/aKX9tyQ+ufne0Rslluw5vDvurWWyrDWViegpkLufiMEx2E5hAfzd+f ir8/lrRntBTmuAyDIK1yWzdcoFOySahoaKakyrWmuQlF13/KreAN/UT05HHcq9G3zooKfeh4gRr aj2dNaKHXL9XAVz38mgYmFklB+t/1H3MVUCRTfb7c4fjiKSlkLAbXYrLV9NWLXCFYSHDtaoNGgQ ujdOejmHK0ZtYkglqWPnN3k0jioY7fG25YS/85lvq4ihrbq3fmDPY+Q2ziTgb3tIfjXaLDRBqfb ALl6jeBMa3ZCdgAEMmze4DXZDw7A4xglwf93S6KMbCTJITPwPjEVsImfpkratuI3YkRdlEnQglV 70AgJR X-Received: by 2002:a05:6000:4383:b0:437:6aca:d1c3 with SMTP id ffacd0b85a97d-43958e0df1fmr3181491f8f.18.1771421228876; Wed, 18 Feb 2026 05:27:08 -0800 (PST) X-Received: by 2002:a05:6000:4383:b0:437:6aca:d1c3 with SMTP id ffacd0b85a97d-43958e0df1fmr3181443f8f.18.1771421228328; Wed, 18 Feb 2026 05:27:08 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 10/24] fuse: Introduce fuse_{inc,dec}_in_flight() Date: Wed, 18 Feb 2026 14:26:19 +0100 Message-ID: <20260218132633.29748-11-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421669400154100 Content-Type: text/plain; charset="utf-8" This is how vduse-blk.c does it, and it does seem better to have dedicated functions for it. Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 5953407f20..fc75a5e74d 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -78,6 +78,25 @@ static void read_from_fuse_export(void *opaque); static bool is_regular_file(const char *path, Error **errp); =20 =20 +static void fuse_inc_in_flight(FuseExport *exp) +{ + if (qatomic_fetch_inc(&exp->in_flight) =3D=3D 0) { + /* Prevent export from being deleted */ + blk_exp_ref(&exp->common); + } +} + +static void fuse_dec_in_flight(FuseExport *exp) +{ + if (qatomic_fetch_dec(&exp->in_flight) =3D=3D 1) { + /* Wake AIO_WAIT_WHILE() */ + aio_wait_kick(); + + /* Now the export can be deleted */ + blk_exp_unref(&exp->common); + } +} + static void fuse_attach_handlers(FuseExport *exp) { aio_set_fd_handler(exp->common.ctx, @@ -303,9 +322,7 @@ static void read_from_fuse_export(void *opaque) FuseExport *exp =3D opaque; int ret; =20 - blk_exp_ref(&exp->common); - - qatomic_inc(&exp->in_flight); + fuse_inc_in_flight(exp); =20 do { ret =3D fuse_session_receive_buf(exp->fuse_session, &exp->fuse_buf= ); @@ -323,11 +340,7 @@ static void read_from_fuse_export(void *opaque) fuse_session_process_buf(exp->fuse_session, &exp->fuse_buf); =20 out: - if (qatomic_fetch_dec(&exp->in_flight) =3D=3D 1) { - aio_wait_kick(); /* wake AIO_WAIT_WHILE() */ - } - - blk_exp_unref(&exp->common); + fuse_dec_in_flight(exp); } =20 static void fuse_export_shutdown(BlockExport *blk_exp) --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421770; cv=none; d=zohomail.com; s=zohoarc; b=BpQilyPi6XHm7HxfNxZdzXZSz13TQsJq7iDpj+AklUOzEsF6eIaaMpfmw27jZTKOTRCyIwr0yTNtrfY3bG6doCtARGFGnNqw9M5NzQb9mwByhi0VPl1RwItG6q2uXpwGiDzO+skboFWn2iKexETFPbQEazsUWbaT0Ke8w7q4r3Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421770; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=HZlCiaeoLEleGjH47/mJTlqebumMXTgkps2WXMv7tSY=; b=bOwZcXgtlvY658nWdHjOsMyw+FlpuZ/9qRXbc6y3plrKHaGi/bXxZz2G2OJhUnHe+VYbVlWxodXvA/i0+oFAdB97MaeCiDDX2KYSUth/XsdQ/MpEn7lT2CEgy5GbKzK6uEsLE8RQLwdzB3tGK/0hlop2mRYuRxaN8KVe82hzLfQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421770474845.0896969192978; Wed, 18 Feb 2026 05:36:10 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfg-0004GD-1O; Wed, 18 Feb 2026 08:32:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfR-0003yL-0h for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:37 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfA-0005Qz-IQ for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:32 -0500 Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-65-vKyX8TPaOHWtsN-7ejbBAA-1; Wed, 18 Feb 2026 08:27:13 -0500 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-4362456500eso5072697f8f.3 for ; Wed, 18 Feb 2026 05:27:12 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-483983c0766sm29540755e9.5.2026.02.18.05.27.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421538; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HZlCiaeoLEleGjH47/mJTlqebumMXTgkps2WXMv7tSY=; b=B4e19W4LDmUPnXSZ8c+X8u4tZRD0vzkKraQjCJ02ahzIrQhljRPGXj4lR+WuW5G+V9YMly Omm6zbAh6JLxI2LVZLRlU/wGnlhJ/VlU2hJ94tj4FjG3UAc//H7m8xOKwuT58irpHjZ9fL 1B4BrgcLMnnNHtLnRVYPMUKp3H01r68= X-MC-Unique: vKyX8TPaOHWtsN-7ejbBAA-1 X-Mimecast-MFC-AGG-ID: vKyX8TPaOHWtsN-7ejbBAA_1771421232 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421232; x=1772026032; darn=nongnu.org; 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; bh=HZlCiaeoLEleGjH47/mJTlqebumMXTgkps2WXMv7tSY=; b=i4VJKYB+b09pTDUbHYrKS4iaIfwWkYEfBjoS9kjRIOru6DBC/g4g7gdBZM8Ap62l9Q eCkX1pdiBoSQljWCPcqdy3UPjSbRN9BrREWdtJA/KTB0aSN84pZ3n2N07sSTeTLVaPCo y1UgJW6h3OkD3oGElgUMt0weB+iQc1CXUgBCUik657QsAF2kBoo9/Pm8s2EIWqjK95u7 FjhSfSSKyu96meENqaM8sRDuQUK2XRuj1R4K7KWu9fjohaX41FtnKqa+bFrOpPuTqAZ5 X5PAL6vPJ4FE4ZfnuHUBWxmp0r3/0viZydYGfteFxxSEeq5R7SIr9hSY64wRG76R7IzT A8FQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421232; x=1772026032; 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; bh=HZlCiaeoLEleGjH47/mJTlqebumMXTgkps2WXMv7tSY=; b=L1L+tgDinDa7fkecH/UjlQyFqWF/fAweIZgMECeMaLoOh5fNq/MxGnlhx+5GScPxTL 0bZ4FbSTTEk6tZJy0dhjEYvnJ3+e3uom8+3h26PP2WPkMIabPpSUyR3BtbyWYicE2lag hVBxcByL1B6/9w8RTDu4Ee2IquxxD/DurrbnIlaad1fN0iCQgU/chREoeG0p4cf9t3Sh 5OZppQMpdocZbv4bAq4N/Af0TDlMyQkK4NwavxG28/mfM1sS7gGy4tAiHOHe9Cr0Ce1r oJbKBg3UZm8MhGTcH+Cx7VGnSXSvt5deFG8RtksFa+kfsvTLbdt29aDJk/5O9HZGAVZp u87w== X-Gm-Message-State: AOJu0Yzn+crILb+k0uL5tzNqb3Od79sOra7ftOCq2zBkH7gnrSk53ZL8 YHNYQwuoT4FEGtkj4mPnZE4ga4XBeWIXS4Bab95Jz8Gk9lGYqwLcscmIqrUqS7csXSGkqGcgaOx TQ969366bhY8UJ665vXi6rOuN4OUTqtToFAlpkhka0wAMgPmagZRbvHTQ X-Gm-Gg: AZuq6aI2OFxs+qJ88p9+TzerzMpLhjksfUtJdyxATlflAKYY11/Co4dwyh7K8moS1aW M49v7DVyZ72DB5zPesGLb+xxX/0aQn2V5JvkeRH+NM7XS5AEkDioVqiRLPW9aZKYuUAo9f6v6OR aUN007UEXflXsnbapOaYza3xo8NVGV0A/k2qCxZfZZ8RC4aElsF13jDpqTJ8H/qVyUVEB6oTlLG u7gQr2cvuf1jBrXk/q4aKSmIkUjjR+KPEAFWDlFFbBr91t9+CTN9hia5J3bQvxjQmWp5YFElPtw JMCNvG9/LpMdIzYcEy/WWyMx8LYXX+kxoJDKtgXybiJxQYKYRXDRs7aTr/uy7IsBxIy1UJZqZSI YvaKDl+KlwqlzKnOZTxmG9mA4LYwZ7vH6FmWAZE4ERLaxlTRJ1ws3LbbJIHvRIejY/m4xbjjiGk 3MEaWF X-Received: by 2002:a05:600c:c4a5:b0:480:19ed:7efa with SMTP id 5b1f17b1804b1-48398b8522fmr25131105e9.36.1771421231753; Wed, 18 Feb 2026 05:27:11 -0800 (PST) X-Received: by 2002:a05:600c:c4a5:b0:480:19ed:7efa with SMTP id 5b1f17b1804b1-48398b8522fmr25130845e9.36.1771421231286; Wed, 18 Feb 2026 05:27:11 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 11/24] fuse: Add halted flag Date: Wed, 18 Feb 2026 14:26:20 +0100 Message-ID: <20260218132633.29748-12-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421771048158500 Content-Type: text/plain; charset="utf-8" This is a flag that we will want when processing FUSE requests ourselves: When the kernel sends us e.g. a truncated request (i.e. we receive less data than the request's indicated length), we cannot rely on subsequent data to be valid. Then, we are going to set this flag, halting all FUSE request processing. We plan to only use this flag in cases that would effectively be kernel bugs. While not necessary yet, access the flag atomically so that it will be safe to use once we introduce multi-threading. (Right now, the flag is unused because libfuse still does our request processing.) Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/block/export/fuse.c b/block/export/fuse.c index fc75a5e74d..f6a5f4fa0a 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -53,6 +53,13 @@ typedef struct FuseExport { unsigned int in_flight; /* atomic */ bool mounted, fd_handler_set_up; =20 + /* + * Set when there was an unrecoverable error and no requests should be= read + * from the device anymore (basically only in case of something we wou= ld + * consider a kernel bug). Access atomically. + */ + bool halted; + char *mountpoint; bool writable; bool growable; @@ -69,6 +76,7 @@ static const struct fuse_lowlevel_ops fuse_ops; =20 static void fuse_export_shutdown(BlockExport *exp); static void fuse_export_delete(BlockExport *exp); +static void fuse_export_halt(FuseExport *exp) G_GNUC_UNUSED; =20 static void init_exports_table(void); =20 @@ -99,6 +107,10 @@ static void fuse_dec_in_flight(FuseExport *exp) =20 static void fuse_attach_handlers(FuseExport *exp) { + if (qatomic_read(&exp->halted)) { + return; + } + aio_set_fd_handler(exp->common.ctx, fuse_session_fd(exp->fuse_session), read_from_fuse_export, NULL, NULL, NULL, exp); @@ -322,6 +334,10 @@ static void read_from_fuse_export(void *opaque) FuseExport *exp =3D opaque; int ret; =20 + if (unlikely(qatomic_read(&exp->halted))) { + return; + } + fuse_inc_in_flight(exp); =20 do { @@ -380,6 +396,20 @@ static void fuse_export_delete(BlockExport *blk_exp) g_free(exp->mountpoint); } =20 +/** + * Halt the export: Detach FD handlers, and set exp->halted to true, preve= nting + * fuse_attach_handlers() from re-attaching them, therefore stopping all f= urther + * request processing. + * + * Call this function when an unrecoverable error happens that makes proce= ssing + * all future requests unreliable. + */ +static void fuse_export_halt(FuseExport *exp) +{ + qatomic_set(&exp->halted, true); + fuse_detach_handlers(exp); +} + /** * Check whether @path points to a regular file. If not, put an * appropriate message into *errp. --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421592; cv=none; d=zohomail.com; s=zohoarc; b=X1WAD7IT++mfFMZMmo/qs+HKOCaUVTGFF8KJHIFjoAluLAj43Cl6zrspxD8xfPk26yZNwfc34DdChcMQF3vtaXd+evo684VCGFp/nNsqV4fUzoqUR9f3e6uSk6NFlhrxRIbOh7awibam6bnN4s1VIP57YEQhmCax7F8/wwY082A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421592; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/GpJAltRXiG3BftU38An+U5DT1j7yTwOzEMSCvYcGWQ=; b=SQ9dT5X11bIVdvpBROltiSSXjnlFiAsGpoTeGvvJz153P3V4mv2V3gdWZbUmaOi/1a/1pYLVgi1brmGP+nOgmgi+npWj4Ndzm97A9jtJRZTREOt/9juA9o6Cs4pmoD79jLjrH/o6xrRdU/xHUJSAINChNBxhqFKFtMfycB+SZRE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421592463821.6575437540141; Wed, 18 Feb 2026 05:33:12 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfe-0004EG-3O; Wed, 18 Feb 2026 08:32:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfQ-0003xd-Bu for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:36 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfA-0005R3-Ir for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:32 -0500 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-256-d1ClUX85OmGkIDRkebFn7A-1; Wed, 18 Feb 2026 08:27:15 -0500 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4837a718f41so18968675e9.2 for ; Wed, 18 Feb 2026 05:27:15 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4834d5ebd1bsm649071375e9.6.2026.02.18.05.27.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421538; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/GpJAltRXiG3BftU38An+U5DT1j7yTwOzEMSCvYcGWQ=; b=JBSxTCCrVo/q/ifgCc9y+ootDlamQkUVvsLVCCoi7nZe+nPJmyJgz38hOKEThLQyMYT12r pzIK582Bblq4a6gyQZGDxWLHwEGpj1wiveWuE7+jy7t4ou89qmjVAPL02/UGNzjljqCbGA Kyzb/uKaOsJ4S1GLd1UyslGVrvTOQGM= X-MC-Unique: d1ClUX85OmGkIDRkebFn7A-1 X-Mimecast-MFC-AGG-ID: d1ClUX85OmGkIDRkebFn7A_1771421234 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421234; x=1772026034; darn=nongnu.org; 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; bh=/GpJAltRXiG3BftU38An+U5DT1j7yTwOzEMSCvYcGWQ=; b=Wuz/EEoZpsw6f46BaBB0BUZf+40AiNMuzJtdMoL07+bCAWWhQrUtznU39/nUvp13ZY KFkg65FEAQa0DzK9+delkGTZhKmYPVQDI+eF4G/PU5o5ciR8M121SmSXar4hqgYEgN5j 4d9uVUdLvVAxYyGaXpME9mEXIEY6hcdMONh8A+GWLhiL5GqxTEOOaNnn2WII95R9wRFI L76bSSpbKykqgItj7TF/Cb4+n7n9Sn95z0JcUzadeIpdAsy9U3be7bBouEXB+7T86N8r Jdw22nHN7k0dznmth/zUAn3v5flDrKFp6bu9uHq6pS9pQEbV0x2ImyKwrvnqiWTRzB7t MbRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421234; x=1772026034; 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; bh=/GpJAltRXiG3BftU38An+U5DT1j7yTwOzEMSCvYcGWQ=; b=iRSDHP030Z/hfnUTJGweod4nLDUYKMKCKD0Ym3cneBYYz6y5+WC5uwZsvMdcP5eowB skfdlOeUgg1EspsgsyWQVgKYROC1f0JYOyyHskk0pdQwEyPj7wGGPNBYyiv+Epzl26nj K4D5cOWrUZz0x6T7d6uc/63Lm6oJOjvA649m3UtBa0PRc+9zDO6Ed2qEF8y/x0dyqz95 ZON9TrBcZ70+8+quZUUf5VjGK4Ls6lBhRxw7zbIrRnK/tzRb9PI5I77yG9bdyBxSA++6 spENe9KU/I6YigkfQaVg+Nd6ifFXJiAizeISLxaSUAcGXc+oBzN9oTjNQp66IC0dn1sD pcCw== X-Gm-Message-State: AOJu0Yw4F/1HVNvvtfFUmthVakkWzgMeMazsiMkkiOUusMur36esiLCb N30v6Lo7HBiWKry5/MzvCgPYisVKTREusCAa1MWhRzHMB6J9/hAgzrprMaqAGoDYpAnSOpBO/fx sg/U8831zpLZBiDdeFCBpuFtQQwmfejhBQRENffcnuXFgAB0pMka2uCiQeqpD9XV/ X-Gm-Gg: AZuq6aJL7ZzoEA+Xx0dI667HRclxYtA7zt4x/L4V1PREtxELYPn/oGv2HUe+1vHMUk9 cNoE657EUodEjSiqOQ+K6hG3p8035FlZA0GY72Ht7QB2e+2dZkE7aq7fvijpJHK3NXaqipRiLVc 0fFjiPdrBp1617UwnQHxlcWZ+CcoEKGm8ip36DzJZPhtEoiiDOKOqeiMATZr89qxud0yYmTuMAZ EJRWV+V4REfmbwmMzG98lI7b0LKFrSO0peGLvUSEimPPm2ohiZpNuhqxz1mNEnb+U0mpwUVZ1oX O6yzfS2CttDt2caYTwGFFUwC9/GHrwPXUQXp+az1WHRV8pe7gc3pfRnqSLkplXuutigS16BUKYx BNkNsOPo6RCUJ28UwW416mrSIMShAlS0apRCVrWhzGC8Grg+2u0EDgnreT3zmq7MquJ+yuebGxo z6WFEw X-Received: by 2002:a05:600c:1c08:b0:47a:8cce:2940 with SMTP id 5b1f17b1804b1-48379b991c6mr243244885e9.14.1771421233838; Wed, 18 Feb 2026 05:27:13 -0800 (PST) X-Received: by 2002:a05:600c:1c08:b0:47a:8cce:2940 with SMTP id 5b1f17b1804b1-48379b991c6mr243244465e9.14.1771421233400; Wed, 18 Feb 2026 05:27:13 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 12/24] fuse: fuse_{read,write}: Rename length to blk_len Date: Wed, 18 Feb 2026 14:26:21 +0100 Message-ID: <20260218132633.29748-13-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421594679158500 Content-Type: text/plain; charset="utf-8" The term "length" is ambiguous, use "blk_len" instead to be clear. Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index f6a5f4fa0a..d45c6b814f 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -637,7 +637,7 @@ static void fuse_read(fuse_req_t req, fuse_ino_t inode, size_t size, off_t offset, struct fuse_file_info *fi) { FuseExport *exp =3D fuse_req_userdata(req); - int64_t length; + int64_t blk_len; void *buf; int ret; =20 @@ -651,14 +651,14 @@ static void fuse_read(fuse_req_t req, fuse_ino_t inod= e, * Clients will expect short reads at EOF, so we have to limit * offset+size to the image length. */ - length =3D blk_getlength(exp->common.blk); - if (length < 0) { - fuse_reply_err(req, -length); + blk_len =3D blk_getlength(exp->common.blk); + if (blk_len < 0) { + fuse_reply_err(req, -blk_len); return; } =20 - if (offset + size > length) { - size =3D length - offset; + if (offset + size > blk_len) { + size =3D blk_len - offset; } =20 buf =3D qemu_try_blockalign(blk_bs(exp->common.blk), size); @@ -685,7 +685,7 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode= , const char *buf, { FuseExport *exp =3D fuse_req_userdata(req); QEMU_AUTO_VFREE void *copied =3D NULL; - int64_t length; + int64_t blk_len; int ret; =20 /* Limited by max_write, should not happen */ @@ -711,13 +711,13 @@ static void fuse_write(fuse_req_t req, fuse_ino_t ino= de, const char *buf, * Clients will expect short writes at EOF, so we have to limit * offset+size to the image length. */ - length =3D blk_getlength(exp->common.blk); - if (length < 0) { - fuse_reply_err(req, -length); + blk_len =3D blk_getlength(exp->common.blk); + if (blk_len < 0) { + fuse_reply_err(req, -blk_len); return; } =20 - if (offset + size > length) { + if (offset + size > blk_len) { if (exp->growable) { ret =3D fuse_do_truncate(exp, offset + size, true, PREALLOC_MO= DE_OFF); if (ret < 0) { @@ -725,7 +725,7 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode= , const char *buf, return; } } else { - size =3D length - offset; + size =3D blk_len - offset; } } =20 --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421674; cv=none; d=zohomail.com; s=zohoarc; b=SRRIb8be3ggGER84UFsTbLgPC/xtU7E8tFH2KgKUifrOfkB+VxpE+mIJc4V/lJeuRrdc7LWYXLYl2KTY6KhorpKBilBqPiuXgh8gkM6vjoTpkPDI6MMnIzw+6fc2fP5b1UI4tGdPG46xuty/i3stPOABx6aXr+mVvIYrFOsKosQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421674; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ua8eW642KP2nisR1pAUnxlQGxBu2aVkwwsqHEm2Vzkk=; b=VjPyy6NlpasTIfPRwznSpi7QRPZJFZEANFqI8ELQGx9w+iDmTRL3Y9cQtnpmLXe9RrR5ONqqgOT59ma2ZLQVVRb+kWv/6OPBDByUPgMLWtR6ABJ6OfBG7BL8ufNUceL6DZL4mLcYmpzkKr+5AoAdR4Dtp/n929IAQrOfJWXNphQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421674897407.55677931169; Wed, 18 Feb 2026 05:34:34 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfk-0004Kr-3t; Wed, 18 Feb 2026 08:32:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfY-00045f-EE for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:46 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfF-0005UZ-5K for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:43 -0500 Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-489-9IfrJ_4SN8ejQo2y3m62dw-1; Wed, 18 Feb 2026 08:27:17 -0500 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-4806b12ad3fso63611365e9.0 for ; Wed, 18 Feb 2026 05:27:17 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-483983b7149sm39307845e9.4.2026.02.18.05.27.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421544; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ua8eW642KP2nisR1pAUnxlQGxBu2aVkwwsqHEm2Vzkk=; b=JWUSo/tPlZyt2a1HiBdDvOqHndnxXiNlg/cl5uCiGSaPbeG5zeoS9jZItbwcxnyPftTzrD nx/6OtSirYH1rTdCFDvpL9ljlFCljvl1cJqRSpkvd4Jzl/QIrqz36VCTGV9gvz11ZvJKY9 m/HYlREgjQYnhtCkiA0xD46lcpDhov4= X-MC-Unique: 9IfrJ_4SN8ejQo2y3m62dw-1 X-Mimecast-MFC-AGG-ID: 9IfrJ_4SN8ejQo2y3m62dw_1771421236 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421236; x=1772026036; darn=nongnu.org; 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; bh=Ua8eW642KP2nisR1pAUnxlQGxBu2aVkwwsqHEm2Vzkk=; b=jrki9SCTDRswe6WyJoFsVqp7DLjH8WqBb32aA2a/oeXBUbnNwucFSz6iDe0chwHHyR FVR35eTtgLH9avMu7sfOwbqN7SEoG6FNKs7jSg1hJhJmJfFdBX1wxQWHHN/AE6jR/JL0 IEgnbHiMPcd6bklKrX0oKyGf1mkAyQM2ad1/qf2nkBGwPuEZnuvhK2AntlcxcVNBQhO8 jmmKo2MhOQ1Q7g2eMcg6SYhA8EGF6A9Xj774grDQ0vaP3JQLTfCNFa+/w6Jw2NratTEt PRXfU2Qay4EhMfjHXn9jKc5YrO+B1XYuljmScC2vFGjiVmyvm5DXysTgBwvNZQ7IMPVR iEvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421236; x=1772026036; 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; bh=Ua8eW642KP2nisR1pAUnxlQGxBu2aVkwwsqHEm2Vzkk=; b=K4XXo2NqBOplWLeY4iBgNvXlI4CuSY5gHs7hu7nG4lqwoWpJHb5fT8CfZVqmGdL5cq wmTkQZjmUOcExXrEv3GEFIC3zCq+plZ8tqqn84CvG5teFm7sH7CbODplvnSbqqSGtx8m Hex+dCTg1zAFU71U793gt3DoJbLI2OXgGX4tavKagfKTZwIZNaNvrnVTJ4lRcT+qP/81 iBGUqzoGrCyFD7/Eg28GsI5MWDIsAP1KnsKMH15AbUzq6hz3aFbczVcdrNxfVBGbOsdY jU7Vn1Cv5elAToGNGjA9sExo33/4uOM6rfbuxakQQ8qqc0uFnxwQ8jnGsMHsvV+OT6JI gEBQ== X-Gm-Message-State: AOJu0YzeeGoOex5dKX0mKLeRZfrJsACbOAvo7Vc2K0LNSGTYGOARKI9x mglqXceJMO9opjQ4b4yrEb8cRk5VHJTUcPDiQ7lfJKxPBMsV1Q9SzPuRa1g2+it4zdOCPEm+WvA E4Stj6Y2fCn6D/QVx1b0yFhB5KXwyrDYEvUzKk6B1iqOHRxUBIj5Sdscy X-Gm-Gg: AZuq6aLnEiU/4b6jzosQT8lQagvTnTXXOi9j9rfdDk8TcQtATkaZ3J2kGWEm6AbhuxP aYOUDSksq1JFSYXFb4qydo7bRcAcu4ULG6T0v11hMFifhfnpq7kqeofKXpL2uQtYC9g0f6ztHpS ntOzuL1vv1uMdv/BxFE9eRFqDBYhHAE6mNc+b/bSVRCCDADRIjMMWvTzVCCizcioJ/cIoXurXQg hMGaoV533gYKqpejiGP1JrJruNUo2NeMfKYycOUEcYYwCp49cm7khqWF4EKOrYF9zOOkhx/zFT9 ix748d4UILilhFowSgDaVRWRpPXgRh0dB1fyAfcS9iol19qF0yj3ZtfKWZsgK5ZuykZnQrOQvq5 ZhRdlzJjNMjjZwrQT0D3zdjKGNxJE6q0L/YI/c2CUqIqcpxhdvCJnA6lpwp7c+tN1mTwds9X9wY DiPSot X-Received: by 2002:a05:600c:3f1b:b0:480:68ed:1e70 with SMTP id 5b1f17b1804b1-48371096d3amr298392045e9.35.1771421236143; Wed, 18 Feb 2026 05:27:16 -0800 (PST) X-Received: by 2002:a05:600c:3f1b:b0:480:68ed:1e70 with SMTP id 5b1f17b1804b1-48371096d3amr298391535e9.35.1771421235710; Wed, 18 Feb 2026 05:27:15 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 13/24] iotests/308: Use conv=notrunc to test growability Date: Wed, 18 Feb 2026 14:26:22 +0100 Message-ID: <20260218132633.29748-14-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421676651158500 Content-Type: text/plain; charset="utf-8" Without conv=3Dnotrunc, dd will automatically truncate the output file to the @seek value at least. We want to test post-EOF I/O, not truncate, so pass conv=3Dnotrunc. (It does not make a difference in practice because we only seek to the EOF, so the truncate effectively does nothing, but this is still cleaner.) Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- tests/qemu-iotests/308 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308 index 033d5cbe22..6ecb275555 100755 --- a/tests/qemu-iotests/308 +++ b/tests/qemu-iotests/308 @@ -296,7 +296,8 @@ orig_disk_usage=3D$(disk_usage "$TEST_IMG") # Should fail (exports are non-growable by default) # (Note that qemu-io can never write beyond the EOF, so we have to use # dd here) -dd if=3D/dev/zero of=3D"$EXT_MP" bs=3D1 count=3D64k seek=3D$orig_len 2>&1 \ +dd if=3D/dev/zero of=3D"$EXT_MP" bs=3D1 count=3D64k seek=3D$orig_len \ + conv=3Dnotrunc 2>&1 \ | _filter_testdir | _filter_imgfmt =20 echo @@ -333,7 +334,7 @@ fuse_export_add \ 'node-protocol' =20 # Now we should be able to write beyond the EOF -dd if=3D/dev/zero of=3D"$EXT_MP" bs=3D1 count=3D64k seek=3D$new_len 2>&1 \ +dd if=3D/dev/zero of=3D"$EXT_MP" bs=3D1 count=3D64k seek=3D$new_len conv= =3Dnotrunc 2>&1 \ | _filter_testdir | _filter_imgfmt =20 new_len=3D$(get_proto_len "$EXT_MP" "$TEST_IMG") --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421701; cv=none; d=zohomail.com; s=zohoarc; b=feOQB/h66MDK76ck/GFiiYN6grwW8JHrYCywTUdDckkPjqlyOhguzh735Rh6PNShqC5XSHMJX39/a+iABfsOcg8Vxu28Rj6pxQe37NnEOliTKy6dKEdYAskzZhjsRUvhTcT5MJpjcSnOSusag4wRp+1KCgfEmuThlvY2/4tnhOM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421701; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/6wY9hvfJ1eIlvKpdImFzHfK6DZcwfCljnWmU410eEo=; b=hljF9BruvtFpADX+bqiKe525J7TmKxFvkBIorL2eVxu1KD9tfx6jrTVnDeubJ52kiSBvBXwcy6sye5LWNRaEOZd6DgCcxxiPnTjK9bIQx77vR45JCiIwBRFoKDijvjBpXMWaJjsPd7nI9JIXkJASyv0TziC3nHdQ0GTlZMa0OpE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421701125350.7953079955196; Wed, 18 Feb 2026 05:35:01 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfk-0004NE-VH; Wed, 18 Feb 2026 08:32:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfc-0004An-C1 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:48 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfT-0005lZ-7j for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:48 -0500 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-212-TaHz-W2QOxa_4eWltVvVwA-1; Wed, 18 Feb 2026 08:27:20 -0500 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4836cc0b38eso37897185e9.2 for ; Wed, 18 Feb 2026 05:27:20 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796abc85csm41619785f8f.22.2026.02.18.05.27.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421555; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/6wY9hvfJ1eIlvKpdImFzHfK6DZcwfCljnWmU410eEo=; b=TkoyQ7MMKMc/Z8Hth3a5ilkp5LOmV+g0A/ob7ghqovZ70/D6+xO6oCUJXvIeY4MC812B35 YgERPkVokdMW4AHsBUBraE99uGDakbVsg2WbIOKk7SPqZHGss2qS5fY7I5xwJWjI56azJs 1ZSxdZu5T6pP40ArTIVTElIT87CVrQE= X-MC-Unique: TaHz-W2QOxa_4eWltVvVwA-1 X-Mimecast-MFC-AGG-ID: TaHz-W2QOxa_4eWltVvVwA_1771421239 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421239; x=1772026039; darn=nongnu.org; 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; bh=/6wY9hvfJ1eIlvKpdImFzHfK6DZcwfCljnWmU410eEo=; b=TRm1va/OQyke6Olh1Wym7Cpp1wftOdbNXLiYHk1/qVuwzxBCGqV3Gy15N8nhqkUHXA WvscdX2vXzyR0KWasuYxjtnOzQlasO+YLhUeY4wLlCMIcwRyoqbg6TAQAMThZCxmyprW gq0oB+xc8lWYNA/wes9GUQmIhfIAXDYvIQp5WX1h8pD3Rs1x9CCoU3xcGZjKt2Xr7/Ld Wc6Gg/V2DQfRzXyRs6lco8AL3EfJKPnYw07O6DSSSTTA6s79eRP8TdkSkHZPqF2GrYTS Zrcwsz1qtcjJeTM1WlzvrcXvkDkM/wEr0CNFsjoSJXrelI/hUyw8IfhzDndxUIQeoE6K fXSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421239; x=1772026039; 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; bh=/6wY9hvfJ1eIlvKpdImFzHfK6DZcwfCljnWmU410eEo=; b=CWGk3P8SQQbiIoBY1laUwH9TFGDl8Q8vloBrvvR5DwVj4zhtjybkwzzl8iSCt8fCoD Y9wL26ajUQTkko3B7IPztBmNmdUYkuLYhqC5Z5tqS2rlT6i3rhxLyNCozMBCd/5OxAbw pbRxLlee7IXu97nvdL6Sw+riFJ+sNtgjXh2R8gLDrASwIPq0YtO8PhNm//7t25e8TN60 f1JxU/W6LyftwzNEcDkymPBifsFChiOwJzVPE9+eBT/3E9wh5v8empzvEsa5L4xRlSHC 9csPtoFFMKaLNzSkPRmA15fvQn/ogH3IUyxkLlBSCo08so/59+osvVEmnDkB4yDXnb+i pUQg== X-Gm-Message-State: AOJu0Ywbzb9rssK2ZNtvwEe1rSgifg/Qw3l5ttSjG4/eyY5XW5YuY9ST moKq4v6WZVdcEykXyiXI9wkhKs9I7fFv+MB5DdcF6i9PIRt4u0JmC1Rn3OIxpIlISkJDbEIboRb cu4L7p/OHhU1RQ+NhTmQyvPp+jx33KiucDZ+dBzBJKVgFr8R0Se319mAo X-Gm-Gg: AZuq6aJWPIBL2B/YrlMHD7O1INdu2ychNmHRht5mfBjrr72HTC9sC14m/I5FtGgNK/r izWmoKs602XkU27E5j0263JB4ORPsSIZz03fMzsbC/dBFfeu2vx+RRiAjGCfuAJiDqD6koiUGya ryTmvef6wxAEYILVw24+LYh643vQZhg/t5k8aJI+v8+DzKX+PKQ0K4QmQnxISSRiaFtVgEIJ+Xy RyBd0SQJTpz/WEP89lzZ5DfhLQ9cH/J4r3vKCBXh2ZpU2tDTX9vK/T86XZS25TfzW0UlKCCWYtN pXp05ig4ZY395gxQCOkPiqDynFzid2NBOegSbWCCqqcnNs/h6udLAoJxLSJ1La+HdmKx9/WxXAP EbiGGQMLRQ4hlYRVHucuqKHoeUAb1f8qfytYzosaZcdsGvH1JkCBjeeihAyRDYKtsP6MyTL1M6C EaDJ+j X-Received: by 2002:a05:600c:871b:b0:483:7783:5382 with SMTP id 5b1f17b1804b1-48398ae5e18mr33799315e9.27.1771421239358; Wed, 18 Feb 2026 05:27:19 -0800 (PST) X-Received: by 2002:a05:600c:871b:b0:483:7783:5382 with SMTP id 5b1f17b1804b1-48398ae5e18mr33798785e9.27.1771421238797; Wed, 18 Feb 2026 05:27:18 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 14/24] fuse: Explicitly handle non-grow post-EOF accesses Date: Wed, 18 Feb 2026 14:26:23 +0100 Message-ID: <20260218132633.29748-15-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421702895158500 Content-Type: text/plain; charset="utf-8" When reading to / writing from non-growable exports, we cap the I/O size by `offset - blk_len`. This will underflow for accesses that are completely past the disk end. Check and handle that case explicitly. This is also enough to ensure that `offset + size` will not overflow; blk_len is int64_t, offset is uint32_t, `offset < blk_len`, so from `INT64_MAX + UINT32_MAX < UINT64_MAX` it follows that `offset + size` cannot overflow. Just one catch: We have to allow write accesses to growable exports past the EOF, so then we cannot rely on `offset < blk_len`, but have to verify explicitly that `offset + size` does not overflow. The negative consequences of not having this commit are luckily limited because blk_pread() and blk_pwrite() will reject post-EOF requests anyway, so a `size` underflow post-EOF will just result in an I/O error. So: - Post-EOF reads will incorrectly result in I/O errors instead of just 0-length reads. We will also attempt to allocate a very large buffer, which is wrong and not good, but not terrible. - Post-EOF writes on non-growable exports will result in I/O errors instead of 0-length writes (which generally indicate ENOSPC). - Post-EOF writes on growable exports can theoretically overflow on EOF and truncate the export down to a much too small size, but in practice, FUSE will never send an offset greater than signed INT_MAX, preventing a uint64_t overflow. (fuse_write_args_fill() in the kernel uses loff_t for the offset, which is signed.) Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 20 +++++++++++++++++++- tests/qemu-iotests/308 | 35 ++++++++++++++++++++++++++++++----- tests/qemu-iotests/308.out | 10 ++++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index d45c6b814f..af0a8de17b 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -657,6 +657,16 @@ static void fuse_read(fuse_req_t req, fuse_ino_t inode, return; } =20 + if (offset >=3D blk_len) { + /* + * Technically libfuse does not allow returning a zero error code = for + * read requests, but in practice this is a 0-length read (and a f= uture + * commit will change this code anyway) + */ + fuse_reply_err(req, 0); + return; + } + if (offset + size > blk_len) { size =3D blk_len - offset; } @@ -717,7 +727,15 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inod= e, const char *buf, return; } =20 - if (offset + size > blk_len) { + if (offset >=3D blk_len && !exp->growable) { + fuse_reply_write(req, 0); + return; + } + + if (offset + size < offset) { + fuse_reply_err(req, EINVAL); + return; + } else if (offset + size > blk_len) { if (exp->growable) { ret =3D fuse_do_truncate(exp, offset + size, true, PREALLOC_MO= DE_OFF); if (ret < 0) { diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308 index 6ecb275555..a83c6fc01f 100755 --- a/tests/qemu-iotests/308 +++ b/tests/qemu-iotests/308 @@ -300,16 +300,34 @@ dd if=3D/dev/zero of=3D"$EXT_MP" bs=3D1 count=3D64k s= eek=3D$orig_len \ conv=3Dnotrunc 2>&1 \ | _filter_testdir | _filter_imgfmt =20 +# And one really squarely post-EOF write +dd if=3D/dev/zero of=3D"$EXT_MP" bs=3D1 count=3D1 seek=3D$((orig_len + 32 = * 1024)) \ + conv=3Dnotrunc 2>&1 \ + | _filter_testdir | _filter_imgfmt + +# Half-post-EOF reads +dd if=3D"$EXT_MP" of=3D/dev/null bs=3D1 count=3D64k skip=3D$((orig_len - 3= 2 * 1024)) \ + 2>&1 | _filter_testdir | _filter_imgfmt + +# And one really squarely post-EOF read +dd if=3D"$EXT_MP" of=3D/dev/null bs=3D1 count=3D1 skip=3D$((orig_len + 32 = * 1024)) \ + 2>&1 | _filter_testdir | _filter_imgfmt + echo echo '--- Resize export ---' =20 # But we can truncate it explicitly; even with fallocate -fallocate -o "$orig_len" -l 64k "$EXT_MP" +# (Make sure we extend it to a length not divisible by 128k, we need that = below) +bs=3D$((128 * 1024)) +extend_to=3D$(((orig_len + bs - 1) / bs * bs + bs / 2)) +extend_by=3D$((extend_to - orig_len)) + +fallocate -o "$orig_len" -l $extend_by "$EXT_MP" =20 new_len=3D$(get_proto_len "$EXT_MP" "$TEST_IMG") -if [ "$new_len" !=3D "$((orig_len + 65536))" ]; then +if [ "$new_len" !=3D "$extend_to" ]; then echo 'ERROR: Unexpected post-truncate image size:' - echo "$new_len !=3D $((orig_len + 65536))" + echo "$new_len !=3D $extend_to" else echo 'OK: Post-truncate image size is as expected' fi @@ -322,6 +340,13 @@ else echo "$orig_disk_usage =3D> $new_disk_usage" fi =20 +# Use this opportunity to test a read access across the (now no longer so = much +# aligned) EOF. dd can only do requests with a length of its block size, = and +# all of its seek/skip values are in bs units, so it is hard to do a reque= st +# across the EOF if the EOF is at a power of two (64M). +dd if=3D"$EXT_MP" of=3D/dev/null bs=3D$bs count=3D2 skip=3D$((extend_to / = bs)) \ + 2>&1 | _filter_testdir | _filter_imgfmt + echo echo '--- Try growing growable export ---' =20 @@ -338,9 +363,9 @@ dd if=3D/dev/zero of=3D"$EXT_MP" bs=3D1 count=3D64k see= k=3D$new_len conv=3Dnotrunc 2>&1 \ | _filter_testdir | _filter_imgfmt =20 new_len=3D$(get_proto_len "$EXT_MP" "$TEST_IMG") -if [ "$new_len" !=3D "$((orig_len + 131072))" ]; then +if [ "$new_len" !=3D "$((extend_to + 65536))" ]; then echo 'ERROR: Unexpected post-grow image size:' - echo "$new_len !=3D $((orig_len + 131072))" + echo "$new_len !=3D $((extend_to + 65536))" else echo 'OK: Post-grow image size is as expected' fi diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out index 2d7a38d63d..ebeaf64b48 100644 --- a/tests/qemu-iotests/308.out +++ b/tests/qemu-iotests/308.out @@ -134,11 +134,21 @@ wrote 65536/65536 bytes at offset 1048576 dd: error writing 'TEST_DIR/t.IMGFMT.fuse': No space left on device 1+0 records in 0+0 records out +dd: error writing 'TEST_DIR/t.IMGFMT.fuse': No space left on device +1+0 records in +0+0 records out +32768+0 records in +32768+0 records out +dd: TEST_DIR/t.IMGFMT.fuse: cannot skip to specified offset +0+0 records in +0+0 records out =20 --- Resize export --- (OK: Lengths of export and original are the same) OK: Post-truncate image size is as expected OK: Disk usage grew with fallocate +0+1 records in +0+1 records out =20 --- Try growing growable export --- {'execute': 'block-export-del', --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421789; cv=none; d=zohomail.com; s=zohoarc; b=loi18fpuIq0KYw/Yl5YGyie4vOGvqZB6iYZgczDPwLl+Q2+dgZmL/phatgWPhVyujKGs7lMEVaR5v/aiuFjThAtMp/kZweXKv7dS5xseV7oBL1+5YfsrY7i8mn0fL9IvOJANj5gpC2OadThJ8KUwIMKiKS91cChMER+zWmOmtzk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421789; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=8xXGf9wQuXiSKLxPb3FYIBG/K87QsiFd36ndnCqGkII=; b=OO+O7j91BN8IiJIB2uf5MZZsnn5OAfHaiDTYVU6+60kAm/j4VL4BC5MwGJLK+3HgDGvTyR9CezJNCdk3kGFNHjpxXiXD+ebgQ7He8CzoLms55YHr1fN74DLfOxXsXFd3LWdcax4pf5y2JhVUz0hI2UOlZXSd82dRWPIqfLMoPXI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17714217894961014.9939620617462; Wed, 18 Feb 2026 05:36:29 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfg-0004HK-KN; Wed, 18 Feb 2026 08:32:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfZ-000465-Fi for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:46 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfL-0005eo-7y for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:45 -0500 Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-250-6VMkZD4ZOeuX7w_UEyMf9g-1; Wed, 18 Feb 2026 08:27:22 -0500 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4806cfffca6so59699385e9.2 for ; Wed, 18 Feb 2026 05:27:22 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48387ab1974sm207441865e9.3.2026.02.18.05.27.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421550; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8xXGf9wQuXiSKLxPb3FYIBG/K87QsiFd36ndnCqGkII=; b=NIgSMuTfWBwOHSm+OI3lXnF7gfZ/gVy+USj69XECvqFltayaAS34yyAIAD0AeT1/ERUE4z m+WGmFxqfRgUOWX4/80SKcI+MtVqflFo53aLpbhJfOo8ZF7YBf3+YeWCsYe6fGhj4arXYx W91cBcwT/zPkmfTcCGeLhGFnFdVjkSQ= X-MC-Unique: 6VMkZD4ZOeuX7w_UEyMf9g-1 X-Mimecast-MFC-AGG-ID: 6VMkZD4ZOeuX7w_UEyMf9g_1771421242 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421241; x=1772026041; darn=nongnu.org; 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; bh=8xXGf9wQuXiSKLxPb3FYIBG/K87QsiFd36ndnCqGkII=; b=Qdk6/Xq3YbV9wEOTk9iRs6ZRws1ySI+DzBuDN31fixqmL/uuEygtbxJqjnjDUKNVhn UPvnNoK29mG0Ptva0deMWrGlJWCUEpBqVIdT0VBd2pEi9udEYlOmrNHp0WRzV4REnHLZ EIykGYM1fRFrHZW/xMslxXcISCqkAF6z/jru19rbnom0dQdCU/8tUnEYXGLU1vrx/gUZ NzS/gqYLWFxoN04kO6IHb30dKdFpDE61ifM4HH4c9YlWsHvDNAH8UnqanOsRTDSgXwpt lpSfkpdbCjTsbdoJ+oPsi1O1tAVh6/iN3R97VFuRjfPfQhs4vQ3BrYL3WCMrbBTo79x6 iSSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421241; x=1772026041; 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; bh=8xXGf9wQuXiSKLxPb3FYIBG/K87QsiFd36ndnCqGkII=; b=DKiudhNuaFgmmcJ6sJJss8j9sw+xaOC1ecdDFuij8Cne70tbL43jAL4U0awEy+EGEa OfXYQ7ecRrkdJR+g5TqKStBUzHaY/LPrxO/mrtBsEoOFFzT2UECvibi+u3Fc+LMzEf49 9qpslpYEAZS9HZNmXHLW1p6zLxfNHQIe6so7CqOcwQ6Nvg3qEt8TAWSYsPYNzpwg4neR bTm7L4qT5b4w7R+yaydOSkAw3dvYEYSqotRDDbZ/SSVlLZWJKXHGlQ/6IB5fZlMy85II zxqGPpnKM70e1TpSY/LzA+1pDWzmqwVsecJ02SSdM4vn3c+XchDgOLRw4NWAU/XIy55s Kt+Q== X-Gm-Message-State: AOJu0Yy/QciD5a7wUl5jgXnz1+S9KbFzXHjEIqiT8fb68JxxkwpOMCXZ wyjilA8B+FpnPgI2PRwUfjhzRsr87pR5vIHdQScq9zcuTWlXXGk6eCoARKktdmTC6Bk2mw1mSUx YfFWISL98pxP3bYuXrOr8AOfFge0HORWjZClb4MePc2Zi4LSS0fXva6LM X-Gm-Gg: AZuq6aICf+0FDJ6nVviPyFVeTZizsP8w8LAXysbNVmBX3tfiXqaQem1ISDBEwElLDUQ AfaQmkbytfTAGmlmqSLbBm4yvT9oemjhLZLTb22bx87m3W2EfFuSoDR16rqtGsSDRxQ1HddS+15 qaBq93BrT/4BDyWsLWP2sCQzYGkM3nqtk3ZsdEfWPvzneSfkUp3u2H84TQQ9YwpM+rHzJSMm2oA k7U5iNo+aB6k/Yb3K76txDtCX4F7HQ88u290p+MYbML35qPIHO7M6XaMrIHOW9JrKNI9cQhWhIG hVj6dCS9coOvoHEAsjOXLYvLps1uUvH4ihdesX+rlOEBo/LKZPFrtrqM4Xo5eekhBq+5xQ248yg trfjP8yiEzheYs1S4OoksfNVZnT7WA5HJWbSjA5o/8C/3TTJaJXc5hCTlpzRlUDM5ux2U0h3Eio MSkIZu X-Received: by 2002:a05:600c:148f:b0:483:7f7c:ad89 with SMTP id 5b1f17b1804b1-4837f7cb108mr162399005e9.37.1771421241476; Wed, 18 Feb 2026 05:27:21 -0800 (PST) X-Received: by 2002:a05:600c:148f:b0:483:7f7c:ad89 with SMTP id 5b1f17b1804b1-4837f7cb108mr162398695e9.37.1771421241028; Wed, 18 Feb 2026 05:27:21 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 15/24] block: Move qemu_fcntl_addfl() into osdep.c Date: Wed, 18 Feb 2026 14:26:24 +0100 Message-ID: <20260218132633.29748-16-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421791095158500 Content-Type: text/plain; charset="utf-8" Move file-posix's helper to add a flag (or a set of flags) to an FD's existing set of flags into osdep.c for other places to use. Suggested-by: Eric Blake Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- include/qemu/osdep.h | 1 + block/file-posix.c | 17 +---------------- util/osdep.c | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index b384b5b506..f151578b5c 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -633,6 +633,7 @@ int qemu_lock_fd(int fd, int64_t start, int64_t len, bo= ol exclusive); int qemu_unlock_fd(int fd, int64_t start, int64_t len); int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive); bool qemu_has_ofd_lock(void); +int qemu_fcntl_addfl(int fd, int flag); #endif =20 bool qemu_has_direct_io(void); diff --git a/block/file-posix.c b/block/file-posix.c index 6265d2e248..e49b13d6ab 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1056,21 +1056,6 @@ static int raw_handle_perm_lock(BlockDriverState *bs, return ret; } =20 -/* Sets a specific flag */ -static int fcntl_setfl(int fd, int flag) -{ - int flags; - - flags =3D fcntl(fd, F_GETFL); - if (flags =3D=3D -1) { - return -errno; - } - if (fcntl(fd, F_SETFL, flags | flag) =3D=3D -1) { - return -errno; - } - return 0; -} - static int raw_reconfigure_getfd(BlockDriverState *bs, int flags, int *open_flags, uint64_t perm, Error **e= rrp) { @@ -1109,7 +1094,7 @@ static int raw_reconfigure_getfd(BlockDriverState *bs= , int flags, /* dup the original fd */ fd =3D qemu_dup(s->fd); if (fd >=3D 0) { - ret =3D fcntl_setfl(fd, *open_flags); + ret =3D qemu_fcntl_addfl(fd, *open_flags); if (ret) { qemu_close(fd); fd =3D -1; diff --git a/util/osdep.c b/util/osdep.c index 770369831b..000e7daac8 100644 --- a/util/osdep.c +++ b/util/osdep.c @@ -280,6 +280,24 @@ int qemu_lock_fd_test(int fd, int64_t start, int64_t l= en, bool exclusive) return fl.l_type =3D=3D F_UNLCK ? 0 : -EAGAIN; } } + +/** + * Set the given flag(s) (fcntl GETFL/SETFL) on the given FD, while retain= ing + * other flags. + */ +int qemu_fcntl_addfl(int fd, int flag) +{ + int flags; + + flags =3D fcntl(fd, F_GETFL); + if (flags =3D=3D -1) { + return -errno; + } + if (fcntl(fd, F_SETFL, flags | flag) =3D=3D -1) { + return -errno; + } + return 0; +} #endif =20 bool qemu_has_direct_io(void) --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421761; cv=none; d=zohomail.com; s=zohoarc; b=Z8bFfudynSyCwTnEIK7CJwRv2tT631yegIeVJ8hFEB4nxt15votL07iEygfWtKwLBZ5lyqbXFRGNyX1znakE9YuJV50+uYuBrdvuU627YYAKPCO6+O4rVRP5J1lf74kcX/nQ+r+wAtxlBhtOh3oNbETlirT+s/2LrCB/gZHG8HE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421761; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=UQRl9meOJuWdYVedpi7sUqHpEjV3sJFFswUPTEReFew=; b=eX3VBOYY1HrabLKTZ80PyaeUQL0KDbDGYB6wuv/aatvaMxeGTNdXCydU+sW5n4BpN/2qgYpjC1lMYa1PZGsZBZmuhHMFCYg3BJLe0nfbPrnPpX/n0bo7ee5R+kLt+Ig2dYCl7TGtgM7wrYk5ENuMLeARCM937lfcUkNIlcjUKQI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421761312881.2490921193447; Wed, 18 Feb 2026 05:36:01 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfj-0004JM-9T; Wed, 18 Feb 2026 08:32:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfg-0004Go-9n for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:52 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfT-0005hQ-81 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:51 -0500 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-617-In_BYx9ZMlO7iX1shLFmQA-1; Wed, 18 Feb 2026 08:27:26 -0500 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4803e8b6007so45186055e9.0 for ; Wed, 18 Feb 2026 05:27:26 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4839840f0a1sm17986285e9.32.2026.02.18.05.27.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421553; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UQRl9meOJuWdYVedpi7sUqHpEjV3sJFFswUPTEReFew=; b=ZKr8KnFjeE/ugpLzd3uTBToKUGKja3ovLKlMZVpt+OiZNdVfbRezbyk6rYYXgiIN+P8M/V Zyj7B8bK+klnoSU8vHSNzj1IP4Ng57WqC5hKMe7MWfQkB3wLTh3WhYr1oxA9sdlnSP+Rvt ecT/OA67c4Oza6WOAb32ySyrGe9PjF8= X-MC-Unique: In_BYx9ZMlO7iX1shLFmQA-1 X-Mimecast-MFC-AGG-ID: In_BYx9ZMlO7iX1shLFmQA_1771421245 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421245; x=1772026045; darn=nongnu.org; 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; bh=UQRl9meOJuWdYVedpi7sUqHpEjV3sJFFswUPTEReFew=; b=Xar+vHFLUeHZu95nkhdCE/N70TptnrhVRNJ0fOAejPGJ4tp7FJ+jIBBExdqGjEabOl eSGDhnyQtq52gkAXAnvM1EXRj1XuiBPAFvKBuyzfYjlPvW4tboS0eQbZOg2aevlktafC TtKPP9qPtjgL9uaqYDcmTtAE7iP1SsEu3DfWdZ3ExhycBM4q1+1WrgbS9RBdTnKI+EwK WjhsTJcPGOexQ80YrU5NY9QPqGefIyfUPeqO+05217ugUhbfyaCuBgzNF42JdvyDRmZp yIOU2DhpD/FN0mlrdtYuwoMuCX8yfe0lEFGa+LrxL7a6Y2tVHmlxXGL2CNLDjm2zcqQE 6b9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421245; x=1772026045; 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; bh=UQRl9meOJuWdYVedpi7sUqHpEjV3sJFFswUPTEReFew=; b=JETF7HCFCGVD2YjJeNsuKzwvOvK8pNmFXFT9+loau+7HobjiDe68tRIX4G2OAP+OcU Fh0HBQYRPNOwbF6HgJJtJbHgyGu5NjZ+PPQqcyhKIYB+r6QgXy4159hi1dkfMYpmMjCn BFQ3WWnx7xvP1MAONjOW3uMgkhVOxRH0lY62EvQwqu2/IcpnpMXODezCVHT0zZlBqQ5j lzQmasZ3UXGanFJ94KTeZ9i8VGUXuCvhCPvp3kp/j+FM7ayX9HIZ4GKma493Dc4x28RM RqL/JKg9rts24EBPYo1Gvof2HQYLkt5pKr9/Jfd2y5soMykvitZHRIR5EjY9pozI9/Ti hdNA== X-Gm-Message-State: AOJu0YzoFzZC/vnAmziYyF5N8tWW4RcGpi/XaQixI9v2G+m8IxRiwia2 JVtdv2sBeeTQ6HEahkz57V3d9QWnHSxV9d5GyUBYlxKXf3ZiVyXRvE9TQBSWMzwNfI2s7nxBpzG DbnddAn2sTT5RScpDLXOazdWGWuXPRlxt2xDJ3ixUZg2KR5HJA2Pb6zEv X-Gm-Gg: AZuq6aLgfDOJPOwyUPQq4IuiYlWC4eqSp5nhmeo/KsJaja0N0HZPW0SW2IvXE82fUS9 /p4lEkK1diW3uf2PilZCC8+eXEA229LqltMEt1NuUQfr3DocRviCw5SUoUUXWgKRnv22R9th7BB tSyDbj/YcEnlrBKaTnPOGfYRcOXrsR8dxE3eqh5cIci7zlLGJ75GJgdENsc0vnIBSXFFRgZK1gv RtpxkQZcOFfiv/MHGKS9uBBTLO8+vyh3gSXMdB+nG1nWUhzaVa4usoKZiiKet93Wln1aU+yOUDg zcJt/R0D0SDembAYK5PXPhOmQ0LsbL9+eixdDYHeLsCmN06PtKS8/vVdBh+orbUSj73K4wVOa5t j09GF86kT0V3QdMrpGIQAaTbcK5PyOw9WRlHogang2GN1mJgX0Z7J0IZuCvQRgSS8nEv3Y5FffC 6Z1+Eb X-Received: by 2002:a05:600c:3f14:b0:483:78e1:784 with SMTP id 5b1f17b1804b1-48398a433abmr33612855e9.4.1771421244565; Wed, 18 Feb 2026 05:27:24 -0800 (PST) X-Received: by 2002:a05:600c:3f14:b0:483:78e1:784 with SMTP id 5b1f17b1804b1-48398a433abmr33612205e9.4.1771421243781; Wed, 18 Feb 2026 05:27:23 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 16/24] fuse: Manually process requests (without libfuse) Date: Wed, 18 Feb 2026 14:26:25 +0100 Message-ID: <20260218132633.29748-17-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421763122158500 Manually read requests from the /dev/fuse FD and process them, without using libfuse. This allows us to safely add parallel request processing in coroutines later, without having to worry about libfuse internals. (Technically, we already have exactly that problem with read_from_fuse_export()/read_from_fuse_fd() nesting.) We will continue to use libfuse for mounting the filesystem; fusermount3 is a effectively a helper program of libfuse, so it should know best how to interact with it. (Doing it manually without libfuse, while doable, is a bit of a pain, and it is not clear to me how stable the "protocol" actually is.) Take this opportunity of quite a major rewrite to update the Copyright line with corrected information that has surfaced in the meantime. Here are some benchmarks from before this patch (4k, iodepth=3D16, libaio; except 'sync', which are iodepth=3D1 and pvsync2): file: read: seq aio: 99.8k =C2=B11.5k IOPS rand aio: 50.5k =C2=B11.0k seq sync: 36.1k =C2=B11.1k rand sync: 10.0k =C2=B10.1k write: seq aio: 72.0k =C2=B19.3k rand aio: 70.6k =C2=B12.5k seq sync: 30.6k =C2=B10.8k rand sync: 30.1k=C2=A0=C2=B11.0k null: read: seq aio: 157.9k =C2=B14.7k rand aio: 158.7k =C2=B14.8k seq sync: 80.2k =C2=B12.8k rand sync: 77.5k =C2=B13.8k write: seq aio: 154.3k =C2=B13.6k rand aio: 154.3k =C2=B14.2k seq sync: 76.1k =C2=B15.2k rand sync: 72.9k =C2=B14.0k And with this patch applied: file: read: seq aio: 106.8k =C2=B11.9k (+7%) rand aio: 48.3k =C2=B18.8k (-4%) seq sync: 35.5k =C2=B11.4k (-2%) rand sync: 10.0k =C2=B10.2k (=C2=B10%) write: seq aio: 76.3k =C2=B16.6k (+6%) rand aio: 76.4k =C2=B11.5k (+8%) seq sync: 31.6k =C2=B10.6k (+3%) rand sync: 30.9k =C2=B10.8k (+3%) null: read: seq aio: 161.7k =C2=B16.0k (+2%) rand aio: 165.6k =C2=B17.1k (+4%) seq sync: 80.5k =C2=B13.0k (=C2=B10%) rand sync: 78.5k =C2=B13.1k (+1%) write: seq aio: 185.1k =C2=B13.3k (+20%) rand aio: 186.7k =C2=B14.8k (+21%) seq sync: 82.5k =C2=B14.2k (+8%) rand sync: 78.7k =C2=B13.2k (+8%) So not much difference, aside from write AIO to a null-co export getting a bit better. Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 944 +++++++++++++++++++++++++++++++++----------- 1 file changed, 720 insertions(+), 224 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index af0a8de17b..c481fb72a2 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -1,7 +1,7 @@ /* * Present a block device as a raw image through FUSE * - * Copyright (c) 2020 Max Reitz + * Copyright (c) 2020, 2025 Hanna Czenczek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,12 +27,15 @@ #include "block/qapi.h" #include "qapi/error.h" #include "qapi/qapi-commands-block.h" +#include "qemu/error-report.h" #include "qemu/main-loop.h" #include "system/block-backend.h" =20 #include #include =20 +#include "standard-headers/linux/fuse.h" + #if defined(CONFIG_FALLOCATE_ZERO_RANGE) #include #endif @@ -42,17 +45,102 @@ #endif =20 /* Prevent overly long bounce buffer allocations */ -#define FUSE_MAX_BOUNCE_BYTES (MIN(BDRV_REQUEST_MAX_BYTES, 64 * 1024 * 102= 4)) +#define FUSE_MAX_READ_BYTES (MIN(BDRV_REQUEST_MAX_BYTES, 64 * 1024 * 1024)) +/* Small enough to fit in the request buffer */ +#define FUSE_MAX_WRITE_BYTES (64 * 1024) =20 +/* + * fuse_init_in structure before 7.36. We don't need the flags2 field add= ed + * there, so we can work with the smaller older structure to stay compatib= le + * with older kernels. + */ +struct fuse_init_in_compat { + uint32_t major; + uint32_t minor; + uint32_t max_readahead; + uint32_t flags; +}; + +typedef struct FuseRequestInHeader { + struct fuse_in_header common; + /* All supported requests */ + union { + struct fuse_init_in_compat init; + struct fuse_open_in open; + struct fuse_setattr_in setattr; + struct fuse_read_in read; + struct fuse_write_in write; + struct fuse_fallocate_in fallocate; +#ifdef CONFIG_FUSE_LSEEK + struct fuse_lseek_in lseek; +#endif + }; +} FuseRequestInHeader; + +typedef struct FuseRequestOutHeader { + struct fuse_out_header common; + /* All supported requests */ + union { + struct fuse_init_out init; + struct fuse_statfs_out statfs; + struct fuse_open_out open; + struct fuse_attr_out attr; + struct fuse_write_out write; +#ifdef CONFIG_FUSE_LSEEK + struct fuse_lseek_out lseek; +#endif + }; +} FuseRequestOutHeader; + +typedef union FuseRequestInHeaderBuf { + struct FuseRequestInHeader structured; + struct { + /* + * Part of the request header that is filled for write requests + * (Needed because we want the data to go into a different buffer,= to + * avoid having to use a bounce buffer) + */ + char head[sizeof(struct fuse_in_header) + + sizeof(struct fuse_write_in)]; + /* + * Rest of the request header for requests that have a longer head= er + * than write requests + */ + char tail[sizeof(FuseRequestInHeader) - + (sizeof(struct fuse_in_header) + + sizeof(struct fuse_write_in))]; + }; +} FuseRequestInHeaderBuf; + +QEMU_BUILD_BUG_ON(sizeof(FuseRequestInHeaderBuf) !=3D + sizeof(FuseRequestInHeader)); +QEMU_BUILD_BUG_ON(sizeof(((FuseRequestInHeaderBuf *)0)->head) + + sizeof(((FuseRequestInHeaderBuf *)0)->tail) !=3D + sizeof(FuseRequestInHeader)); =20 typedef struct FuseExport { BlockExport common; =20 struct fuse_session *fuse_session; - struct fuse_buf fuse_buf; unsigned int in_flight; /* atomic */ bool mounted, fd_handler_set_up; =20 + /* + * Cached buffer to receive the data of WRITE requests. Cached becaus= e: + * To read requests, we put a FuseRequestInHeaderBuf (FRIHB) object on= the + * stack, and a (WRITE data) buffer on the heap. We pass FRIHB.head a= nd the + * data buffer to readv(). This way, for WRITE requests, we get exact= ly + * their data in the data buffer and can avoid bounce buffering. + * However, for non-WRITE requests, some of the header may end up in t= he + * data buffer, so we will need to copy that back into the FRIHB objec= t, and + * then we don't need the heap buffer anymore. That is why we cache i= t, so + * we can trivially reuse it between non-WRITE requests. + * + * Note that these data buffers and thus req_write_data_cached are all= ocated + * via blk_blockalign() and thus need to be freed via qemu_vfree(). + */ + void *req_write_data_cached; + /* * Set when there was an unrecoverable error and no requests should be= read * from the device anymore (basically only in case of something we wou= ld @@ -60,6 +148,8 @@ typedef struct FuseExport { */ bool halted; =20 + int fuse_fd; + char *mountpoint; bool writable; bool growable; @@ -71,20 +161,31 @@ typedef struct FuseExport { gid_t st_gid; } FuseExport; =20 +/* + * Verify that the size of FuseRequestInHeaderBuf.head plus the data + * buffer are big enough to be accepted by the FUSE kernel driver. + */ +QEMU_BUILD_BUG_ON(sizeof(((FuseRequestInHeaderBuf *)0)->head) + + FUSE_MAX_WRITE_BYTES < + FUSE_MIN_READ_BUFFER); + static GHashTable *exports; -static const struct fuse_lowlevel_ops fuse_ops; =20 static void fuse_export_shutdown(BlockExport *exp); static void fuse_export_delete(BlockExport *exp); -static void fuse_export_halt(FuseExport *exp) G_GNUC_UNUSED; +static void fuse_export_halt(FuseExport *exp); =20 static void init_exports_table(void); =20 static int mount_fuse_export(FuseExport *exp, Error **errp); -static void read_from_fuse_export(void *opaque); =20 static bool is_regular_file(const char *path, Error **errp); =20 +static void read_from_fuse_fd(void *opaque); +static void fuse_process_request(FuseExport *exp, + const FuseRequestInHeader *in_hdr, + const void *data_buffer); +static int fuse_write_err(int fd, const struct fuse_in_header *in_hdr, int= err); =20 static void fuse_inc_in_flight(FuseExport *exp) { @@ -105,22 +206,26 @@ static void fuse_dec_in_flight(FuseExport *exp) } } =20 +/** + * Attach FUSE FD read handler. + */ static void fuse_attach_handlers(FuseExport *exp) { if (qatomic_read(&exp->halted)) { return; } =20 - aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), - read_from_fuse_export, NULL, NULL, NULL, exp); + aio_set_fd_handler(exp->common.ctx, exp->fuse_fd, + read_from_fuse_fd, NULL, NULL, NULL, exp); exp->fd_handler_set_up =3D true; } =20 +/** + * Detach FUSE FD read handler. + */ static void fuse_detach_handlers(FuseExport *exp) { - aio_set_fd_handler(exp->common.ctx, - fuse_session_fd(exp->fuse_session), + aio_set_fd_handler(exp->common.ctx, exp->fuse_fd, NULL, NULL, NULL, NULL, NULL); exp->fd_handler_set_up =3D false; } @@ -247,6 +352,13 @@ static int fuse_export_create(BlockExport *blk_exp, =20 g_hash_table_insert(exports, g_strdup(exp->mountpoint), NULL); =20 + exp->fuse_fd =3D fuse_session_fd(exp->fuse_session); + ret =3D qemu_fcntl_addfl(exp->fuse_fd, O_NONBLOCK); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to make FUSE FD non-blocking"= ); + goto fail; + } + fuse_attach_handlers(exp); return 0; =20 @@ -278,6 +390,17 @@ static int mount_fuse_export(FuseExport *exp, Error **= errp) char *mount_opts; struct fuse_args fuse_args; int ret; + /* + * We just create the session for mounting/unmounting, no need to prov= ide + * any operations. However, since libfuse commit 52a633a5d, we have to + * provide some op struct and cannot just pass NULL (even though the c= ommit + * message ("allow passing ops as NULL") seems to imply the exact oppo= site, + * as does the comment added to fuse_session_new_fn() ("To create a no= -op + * session just for mounting pass op as NULL."). + * This is how said libfuse commit implements a no-op session internal= ly, so + * do it the same way. + */ + static const struct fuse_lowlevel_ops null_ops =3D { 0 }; =20 /* * Note that these mount options differ from what we would pass to a d= irect @@ -292,7 +415,7 @@ static int mount_fuse_export(FuseExport *exp, Error **e= rrp) mount_opts =3D g_strdup_printf("%s,nosuid,nodev,noatime,max_read=3D%zu= ," "default_permissions%s", exp->writable ? "rw" : "ro", - FUSE_MAX_BOUNCE_BYTES, + FUSE_MAX_READ_BYTES, exp->allow_other ? ",allow_other" : ""); =20 fuse_argv[0] =3D ""; /* Dummy program name */ @@ -301,8 +424,8 @@ static int mount_fuse_export(FuseExport *exp, Error **e= rrp) fuse_argv[3] =3D NULL; fuse_args =3D (struct fuse_args)FUSE_ARGS_INIT(3, (char **)fuse_argv); =20 - exp->fuse_session =3D fuse_session_new(&fuse_args, &fuse_ops, - sizeof(fuse_ops), exp); + exp->fuse_session =3D fuse_session_new(&fuse_args, &null_ops, + sizeof(null_ops), NULL); g_free(mount_opts); if (!exp->fuse_session) { error_setg(errp, "Failed to set up FUSE session"); @@ -326,36 +449,163 @@ fail: } =20 /** - * Callback to be invoked when the FUSE session FD can be read from. - * (This is basically the FUSE event loop.) + * Allocate a buffer to receive WRITE data, or take the cached one. */ -static void read_from_fuse_export(void *opaque) +static void *get_write_data_buffer(FuseExport *exp) { - FuseExport *exp =3D opaque; - int ret; + if (exp->req_write_data_cached) { + void *cached =3D exp->req_write_data_cached; + exp->req_write_data_cached =3D NULL; + return cached; + } else { + return blk_blockalign(exp->common.blk, FUSE_MAX_WRITE_BYTES); + } +} =20 - if (unlikely(qatomic_read(&exp->halted))) { +/** + * Release a WRITE data buffer, possibly reusing it for a subsequent reque= st. + */ +static void release_write_data_buffer(FuseExport *exp, void **buffer) +{ + if (!*buffer) { return; } =20 + if (!exp->req_write_data_cached) { + exp->req_write_data_cached =3D *buffer; + } else { + qemu_vfree(*buffer); + } + *buffer =3D NULL; +} + +/** + * Return the length of the specific operation's own in_header. + * Return -ENOSYS if the operation is not supported. + */ +static ssize_t req_op_hdr_len(const FuseRequestInHeader *in_hdr) +{ + switch (in_hdr->common.opcode) { + case FUSE_INIT: + return sizeof(in_hdr->init); + case FUSE_OPEN: + return sizeof(in_hdr->open); + case FUSE_SETATTR: + return sizeof(in_hdr->setattr); + case FUSE_READ: + return sizeof(in_hdr->read); + case FUSE_WRITE: + return sizeof(in_hdr->write); + case FUSE_FALLOCATE: + return sizeof(in_hdr->fallocate); +#ifdef CONFIG_FUSE_LSEEK + case FUSE_LSEEK: + return sizeof(in_hdr->lseek); +#endif + case FUSE_DESTROY: + case FUSE_STATFS: + case FUSE_RELEASE: + case FUSE_LOOKUP: + case FUSE_FORGET: + case FUSE_BATCH_FORGET: + case FUSE_GETATTR: + case FUSE_FSYNC: + case FUSE_FLUSH: + /* These requests don't have their own header or we don't care */ + return 0; + default: + return -ENOSYS; + } +} + +/** + * Try to read and process a single request from the FUSE FD. + */ +static void read_from_fuse_fd(void *opaque) +{ + FuseExport *exp =3D opaque; + int fuse_fd =3D exp->fuse_fd; + ssize_t ret; + FuseRequestInHeaderBuf in_hdr_buf; + const FuseRequestInHeader *in_hdr; + void *data_buffer =3D NULL; + struct iovec iov[2]; + ssize_t op_hdr_len; + fuse_inc_in_flight(exp); =20 - do { - ret =3D fuse_session_receive_buf(exp->fuse_session, &exp->fuse_buf= ); - } while (ret =3D=3D -EINTR); - if (ret < 0) { - goto out; + if (unlikely(qatomic_read(&exp->halted))) { + goto no_request; + } + + data_buffer =3D get_write_data_buffer(exp); + + /* Construct the I/O vector to hold the FUSE request */ + iov[0] =3D (struct iovec) { &in_hdr_buf.head, sizeof(in_hdr_buf.head) = }; + iov[1] =3D (struct iovec) { data_buffer, FUSE_MAX_WRITE_BYTES }; + ret =3D RETRY_ON_EINTR(readv(fuse_fd, iov, ARRAY_SIZE(iov))); + if (ret < 0 && errno =3D=3D EAGAIN) { + /* No request available */ + goto no_request; + } else if (unlikely(ret < 0)) { + error_report("Failed to read from FUSE device: %s", strerror(errno= )); + goto no_request; + } + + if (unlikely(ret < sizeof(in_hdr->common))) { + error_report("Incomplete read from FUSE device, expected at least = %zu " + "bytes, read %zi bytes; cannot trust subsequent " + "requests, halting the export", + sizeof(in_hdr->common), ret); + fuse_export_halt(exp); + goto no_request; + } + in_hdr =3D &in_hdr_buf.structured; + + if (unlikely(ret !=3D in_hdr->common.len)) { + error_report("Number of bytes read from FUSE device does not match= " + "request size, expected %" PRIu32 " bytes, read %zi " + "bytes; cannot trust subsequent requests, halting the= " + "export", + in_hdr->common.len, ret); + fuse_export_halt(exp); + goto no_request; + } + + op_hdr_len =3D req_op_hdr_len(in_hdr); + if (op_hdr_len < 0) { + fuse_write_err(fuse_fd, &in_hdr->common, op_hdr_len); + goto no_request; + } + + if (unlikely(ret < sizeof(in_hdr->common) + op_hdr_len)) { + error_report("FUSE request truncated, expected %zu bytes, read %zi= " + "bytes", + sizeof(in_hdr->common) + op_hdr_len, ret); + fuse_write_err(fuse_fd, &in_hdr->common, -EINVAL); + goto no_request; } =20 /* - * Note that aio_poll() in any request-processing function can lead to= a - * nested read_from_fuse_export() call, which will overwrite the conte= nts of - * exp->fuse_buf. Anything that takes a buffer needs to take care tha= t the - * content is copied before potentially polling via aio_poll(). + * Only WRITE uses the write data buffer, so for non-WRITE requests lo= nger + * than .head, we need to copy any data that spilled into data_buffer = into + * .tail. Then we can release the write data buffer. */ - fuse_session_process_buf(exp->fuse_session, &exp->fuse_buf); + if (in_hdr->common.opcode !=3D FUSE_WRITE) { + if (ret > sizeof(in_hdr_buf.head)) { + size_t len; + /* Limit size to prevent overflow */ + len =3D MIN(ret - sizeof(in_hdr_buf.head), sizeof(in_hdr_buf.t= ail)); + memcpy(in_hdr_buf.tail, data_buffer, len); + } =20 -out: + release_write_data_buffer(exp, &data_buffer); + } + + fuse_process_request(exp, in_hdr, data_buffer); + +no_request: + release_write_data_buffer(exp, &data_buffer); fuse_dec_in_flight(exp); } =20 @@ -363,18 +613,14 @@ static void fuse_export_shutdown(BlockExport *blk_exp) { FuseExport *exp =3D container_of(blk_exp, FuseExport, common); =20 - if (exp->fuse_session) { - fuse_session_exit(exp->fuse_session); - - if (exp->fd_handler_set_up) { - fuse_detach_handlers(exp); - } + if (exp->fd_handler_set_up) { + fuse_detach_handlers(exp); } =20 if (exp->mountpoint) { /* - * Safe to drop now, because we will not handle any requests - * for this export anymore anyway. + * Safe to drop now, because we will not handle any requests for t= his + * export anymore anyway (at least not from the main thread). */ g_hash_table_remove(exports, exp->mountpoint); } @@ -392,7 +638,7 @@ static void fuse_export_delete(BlockExport *blk_exp) fuse_session_destroy(exp->fuse_session); } =20 - free(exp->fuse_buf.mem); + qemu_vfree(exp->req_write_data_cached); g_free(exp->mountpoint); } =20 @@ -434,46 +680,101 @@ static bool is_regular_file(const char *path, Error = **errp) } =20 /** - * A chance to set change some parameters supplied to FUSE_INIT. + * Process FUSE INIT. + * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static void fuse_init(void *userdata, struct fuse_conn_info *conn) +static ssize_t fuse_init(FuseExport *exp, struct fuse_init_out *out, + const struct fuse_init_in_compat *in) { + const uint32_t supported_flags =3D FUSE_ASYNC_READ | FUSE_ASYNC_DIO; + + if (in->major !=3D 7) { + error_report("FUSE major version mismatch: We have 7, but kernel h= as %" + PRIu32, in->major); + return -EINVAL; + } + + /* 2007's 7.9 added fuse_attr.blksize; working around that would be ha= rd */ + if (in->minor < 9) { + error_report("FUSE minor version too old: 9 required, but kernel h= as %" + PRIu32, in->minor); + return -EINVAL; + } + + *out =3D (struct fuse_init_out) { + .major =3D 7, + .minor =3D MIN(FUSE_KERNEL_MINOR_VERSION, in->minor), + .max_readahead =3D in->max_readahead, + .max_write =3D FUSE_MAX_WRITE_BYTES, + .flags =3D in->flags & supported_flags, + .flags2 =3D 0, + + /* libfuse maximum: 2^16 - 1 */ + .max_background =3D UINT16_MAX, + + /* libfuse default: max_background * 3 / 4 */ + .congestion_threshold =3D (int)UINT16_MAX * 3 / 4, + + /* libfuse default: 1 */ + .time_gran =3D 1, + + /* + * probably unneeded without FUSE_MAX_PAGES, but this would be the + * libfuse default + */ + .max_pages =3D DIV_ROUND_UP(FUSE_MAX_WRITE_BYTES, + qemu_real_host_page_size()), + + /* Only needed for mappings (i.e. DAX) */ + .map_alignment =3D 0, + }; + /* - * MIN_NON_ZERO() would not be wrong here, but what we set here - * must equal what has been passed to fuse_session_new(). - * Therefore, as long as max_read must be passed as a mount option - * (which libfuse claims will be changed at some point), we have - * to set max_read to a fixed value here. + * Before 7.23, fuse_init_out is shorter. + * Drop the tail (time_gran, max_pages, map_alignment). */ - conn->max_read =3D FUSE_MAX_BOUNCE_BYTES; - - conn->max_write =3D MIN_NON_ZERO(BDRV_REQUEST_MAX_BYTES, conn->max_wri= te); + return out->minor >=3D 23 ? sizeof(*out) : FUSE_COMPAT_22_INIT_OUT_SIZ= E; } =20 /** - * Let clients look up files. Always return ENOENT because we only - * care about the mountpoint itself. + * Return some filesystem information, just to not break e.g. `df`. */ -static void fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char *nam= e) +static ssize_t fuse_statfs(FuseExport *exp, struct fuse_statfs_out *out) { - fuse_reply_err(req, ENOENT); + BlockDriverState *root_bs; + uint32_t opt_transfer =3D 512; + + root_bs =3D blk_bs(exp->common.blk); + if (root_bs) { + opt_transfer =3D root_bs->bl.opt_transfer; + if (!opt_transfer) { + opt_transfer =3D root_bs->bl.request_alignment; + } + opt_transfer =3D MAX(opt_transfer, 512); + } + + *out =3D (struct fuse_statfs_out) { + /* These are the fields libfuse sets by default */ + .st =3D { + .namelen =3D 255, + .bsize =3D opt_transfer, + }, + }; + return sizeof(*out); } =20 /** * Let clients get file attributes (i.e., stat() the file). + * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static void fuse_getattr(fuse_req_t req, fuse_ino_t inode, - struct fuse_file_info *fi) +static ssize_t fuse_getattr(FuseExport *exp, struct fuse_attr_out *out) { - struct stat statbuf; int64_t length, allocated_blocks; time_t now =3D time(NULL); - FuseExport *exp =3D fuse_req_userdata(req); =20 length =3D blk_getlength(exp->common.blk); if (length < 0) { - fuse_reply_err(req, -length); - return; + return length; } =20 allocated_blocks =3D bdrv_get_allocated_file_size(blk_bs(exp->common.b= lk)); @@ -483,21 +784,24 @@ static void fuse_getattr(fuse_req_t req, fuse_ino_t i= node, allocated_blocks =3D DIV_ROUND_UP(allocated_blocks, 512); } =20 - statbuf =3D (struct stat) { - .st_ino =3D 1, - .st_mode =3D exp->st_mode, - .st_nlink =3D 1, - .st_uid =3D exp->st_uid, - .st_gid =3D exp->st_gid, - .st_size =3D length, - .st_blksize =3D blk_bs(exp->common.blk)->bl.request_alignment, - .st_blocks =3D allocated_blocks, - .st_atime =3D now, - .st_mtime =3D now, - .st_ctime =3D now, + *out =3D (struct fuse_attr_out) { + .attr_valid =3D 1, + .attr =3D { + .ino =3D 1, + .mode =3D exp->st_mode, + .nlink =3D 1, + .uid =3D exp->st_uid, + .gid =3D exp->st_gid, + .size =3D length, + .blksize =3D blk_bs(exp->common.blk)->bl.request_alignment, + .blocks =3D allocated_blocks, + .atime =3D now, + .mtime =3D now, + .ctime =3D now, + }, }; =20 - fuse_reply_attr(req, &statbuf, 1.); + return sizeof(*out); } =20 static int fuse_do_truncate(const FuseExport *exp, int64_t size, @@ -550,101 +854,98 @@ static int fuse_do_truncate(const FuseExport *exp, i= nt64_t size, * permit access: Read-only exports cannot be given +w, and exports * without allow_other cannot be given a different UID or GID, and * they cannot be given non-owner access. + * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static void fuse_setattr(fuse_req_t req, fuse_ino_t inode, struct stat *st= atbuf, - int to_set, struct fuse_file_info *fi) +static ssize_t fuse_setattr(FuseExport *exp, struct fuse_attr_out *out, + uint32_t to_set, uint64_t size, uint32_t mode, + uint32_t uid, uint32_t gid) { - FuseExport *exp =3D fuse_req_userdata(req); int supported_attrs; int ret; =20 - supported_attrs =3D FUSE_SET_ATTR_SIZE | FUSE_SET_ATTR_MODE; + /* SIZE and MODE are actually supported, the others can be safely igno= red */ + supported_attrs =3D FATTR_SIZE | FATTR_MODE | + FATTR_FH | FATTR_LOCKOWNER | FATTR_KILL_SUIDGID; if (exp->allow_other) { - supported_attrs |=3D FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID; + supported_attrs |=3D FATTR_UID | FATTR_GID; } =20 if (to_set & ~supported_attrs) { - fuse_reply_err(req, ENOTSUP); - return; + return -ENOTSUP; } =20 /* Do some argument checks first before committing to anything */ - if (to_set & FUSE_SET_ATTR_MODE) { + if (to_set & FATTR_MODE) { /* * Without allow_other, non-owners can never access the export, so= do * not allow setting permissions for them */ - if (!exp->allow_other && - (statbuf->st_mode & (S_IRWXG | S_IRWXO)) !=3D 0) - { - fuse_reply_err(req, EPERM); - return; + if (!exp->allow_other && (mode & (S_IRWXG | S_IRWXO)) !=3D 0) { + return -EPERM; } =20 /* +w for read-only exports makes no sense, disallow it */ - if (!exp->writable && - (statbuf->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) !=3D 0) - { - fuse_reply_err(req, EROFS); - return; + if (!exp->writable && (mode & (S_IWUSR | S_IWGRP | S_IWOTH)) !=3D = 0) { + return -EROFS; } } =20 - if (to_set & FUSE_SET_ATTR_SIZE) { + if (to_set & FATTR_SIZE) { if (!exp->writable) { - fuse_reply_err(req, EACCES); - return; + return -EACCES; } =20 - ret =3D fuse_do_truncate(exp, statbuf->st_size, true, PREALLOC_MOD= E_OFF); + ret =3D fuse_do_truncate(exp, size, true, PREALLOC_MODE_OFF); if (ret < 0) { - fuse_reply_err(req, -ret); - return; + return ret; } } =20 - if (to_set & FUSE_SET_ATTR_MODE) { + if (to_set & FATTR_MODE) { /* Ignore FUSE-supplied file type, only change the mode */ - exp->st_mode =3D (statbuf->st_mode & 07777) | S_IFREG; + exp->st_mode =3D (mode & 07777) | S_IFREG; } =20 - if (to_set & FUSE_SET_ATTR_UID) { - exp->st_uid =3D statbuf->st_uid; + if (to_set & FATTR_UID) { + exp->st_uid =3D uid; } =20 - if (to_set & FUSE_SET_ATTR_GID) { - exp->st_gid =3D statbuf->st_gid; + if (to_set & FATTR_GID) { + exp->st_gid =3D gid; } =20 - fuse_getattr(req, inode, fi); + return fuse_getattr(exp, out); } =20 /** - * Let clients open a file (i.e., the exported image). + * Open an inode. We only have a single inode in our exported filesystem,= so we + * just acknowledge the request. + * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static void fuse_open(fuse_req_t req, fuse_ino_t inode, - struct fuse_file_info *fi) +static ssize_t fuse_open(FuseExport *exp, struct fuse_open_out *out) { - fi->direct_io =3D true; - fi->parallel_direct_writes =3D true; - fuse_reply_open(req, fi); + *out =3D (struct fuse_open_out) { + .open_flags =3D FOPEN_DIRECT_IO | FOPEN_PARALLEL_DIRECT_WRITES, + }; + return sizeof(*out); } =20 /** - * Handle client reads from the exported image. + * Handle client reads from the exported image. Allocates *bufptr and rea= ds + * data from the block device into that buffer. + * Returns the buffer (read) size on success, and -errno on error. + * After use, *bufptr must be freed via qemu_vfree(). */ -static void fuse_read(fuse_req_t req, fuse_ino_t inode, - size_t size, off_t offset, struct fuse_file_info *fi) +static ssize_t fuse_read(FuseExport *exp, void **bufptr, + uint64_t offset, uint32_t size) { - FuseExport *exp =3D fuse_req_userdata(req); int64_t blk_len; void *buf; int ret; =20 /* Limited by max_read, should not happen */ - if (size > FUSE_MAX_BOUNCE_BYTES) { - fuse_reply_err(req, EINVAL); - return; + if (size > FUSE_MAX_READ_BYTES) { + return -EINVAL; } =20 /** @@ -653,18 +954,12 @@ static void fuse_read(fuse_req_t req, fuse_ino_t inod= e, */ blk_len =3D blk_getlength(exp->common.blk); if (blk_len < 0) { - fuse_reply_err(req, -blk_len); - return; + return blk_len; } =20 if (offset >=3D blk_len) { - /* - * Technically libfuse does not allow returning a zero error code = for - * read requests, but in practice this is a 0-length read (and a f= uture - * commit will change this code anyway) - */ - fuse_reply_err(req, 0); - return; + *bufptr =3D NULL; + return 0; } =20 if (offset + size > blk_len) { @@ -673,108 +968,96 @@ static void fuse_read(fuse_req_t req, fuse_ino_t ino= de, =20 buf =3D qemu_try_blockalign(blk_bs(exp->common.blk), size); if (!buf) { - fuse_reply_err(req, ENOMEM); - return; + return -ENOMEM; } =20 ret =3D blk_pread(exp->common.blk, offset, size, buf, 0); - if (ret >=3D 0) { - fuse_reply_buf(req, buf, size); - } else { - fuse_reply_err(req, -ret); + if (ret < 0) { + qemu_vfree(buf); + return ret; } =20 - qemu_vfree(buf); + *bufptr =3D buf; + return size; } =20 /** - * Handle client writes to the exported image. + * Handle client writes to the exported image. @buf has the data to be wr= itten. + * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf, - size_t size, off_t offset, struct fuse_file_info *f= i) +static ssize_t fuse_write(FuseExport *exp, struct fuse_write_out *out, + uint64_t offset, uint32_t size, const void *buf) { - FuseExport *exp =3D fuse_req_userdata(req); - QEMU_AUTO_VFREE void *copied =3D NULL; int64_t blk_len; int ret; =20 + QEMU_BUILD_BUG_ON(FUSE_MAX_WRITE_BYTES > BDRV_REQUEST_MAX_BYTES); /* Limited by max_write, should not happen */ - if (size > BDRV_REQUEST_MAX_BYTES) { - fuse_reply_err(req, EINVAL); - return; + if (size > FUSE_MAX_WRITE_BYTES) { + return -EINVAL; } =20 if (!exp->writable) { - fuse_reply_err(req, EACCES); - return; + return -EACCES; } =20 - /* - * Heed the note on read_from_fuse_export(): If we call aio_poll() (wh= ich - * any blk_*() I/O function may do), read_from_fuse_export() may be ne= sted, - * overwriting the request buffer content. Therefore, we must copy it= here. - */ - copied =3D blk_blockalign(exp->common.blk, size); - memcpy(copied, buf, size); - /** * Clients will expect short writes at EOF, so we have to limit * offset+size to the image length. */ blk_len =3D blk_getlength(exp->common.blk); if (blk_len < 0) { - fuse_reply_err(req, -blk_len); - return; + return blk_len; } =20 if (offset >=3D blk_len && !exp->growable) { - fuse_reply_write(req, 0); - return; + *out =3D (struct fuse_write_out) { + .size =3D 0, + }; + return sizeof(*out); } =20 if (offset + size < offset) { - fuse_reply_err(req, EINVAL); - return; + return -EINVAL; } else if (offset + size > blk_len) { if (exp->growable) { ret =3D fuse_do_truncate(exp, offset + size, true, PREALLOC_MO= DE_OFF); if (ret < 0) { - fuse_reply_err(req, -ret); - return; + return ret; } } else { size =3D blk_len - offset; } } =20 - ret =3D blk_pwrite(exp->common.blk, offset, size, copied, 0); - if (ret >=3D 0) { - fuse_reply_write(req, size); - } else { - fuse_reply_err(req, -ret); + ret =3D blk_pwrite(exp->common.blk, offset, size, buf, 0); + if (ret < 0) { + return ret; } + + *out =3D (struct fuse_write_out) { + .size =3D size, + }; + return sizeof(*out); } =20 /** * Let clients perform various fallocate() operations. + * Return 0 on success (no 'out' object), and -errno on error. */ -static void fuse_fallocate(fuse_req_t req, fuse_ino_t inode, int mode, - off_t offset, off_t length, - struct fuse_file_info *fi) +static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t l= ength, + uint32_t mode) { - FuseExport *exp =3D fuse_req_userdata(req); int64_t blk_len; int ret; =20 if (!exp->writable) { - fuse_reply_err(req, EACCES); - return; + return -EACCES; } =20 blk_len =3D blk_getlength(exp->common.blk); if (blk_len < 0) { - fuse_reply_err(req, -blk_len); - return; + return blk_len; } =20 #ifdef CONFIG_FALLOCATE_PUNCH_HOLE @@ -786,16 +1069,14 @@ static void fuse_fallocate(fuse_req_t req, fuse_ino_= t inode, int mode, if (!mode) { /* We can only fallocate at the EOF with a truncate */ if (offset < blk_len) { - fuse_reply_err(req, EOPNOTSUPP); - return; + return -EOPNOTSUPP; } =20 if (offset > blk_len) { /* No preallocation needed here */ ret =3D fuse_do_truncate(exp, offset, true, PREALLOC_MODE_OFF); if (ret < 0) { - fuse_reply_err(req, -ret); - return; + return ret; } } =20 @@ -805,8 +1086,7 @@ static void fuse_fallocate(fuse_req_t req, fuse_ino_t = inode, int mode, #ifdef CONFIG_FALLOCATE_PUNCH_HOLE else if (mode & FALLOC_FL_PUNCH_HOLE) { if (!(mode & FALLOC_FL_KEEP_SIZE)) { - fuse_reply_err(req, EINVAL); - return; + return -EINVAL; } =20 do { @@ -834,8 +1114,7 @@ static void fuse_fallocate(fuse_req_t req, fuse_ino_t = inode, int mode, ret =3D fuse_do_truncate(exp, offset + length, false, PREALLOC_MODE_OFF); if (ret < 0) { - fuse_reply_err(req, -ret); - return; + return ret; } } =20 @@ -853,44 +1132,38 @@ static void fuse_fallocate(fuse_req_t req, fuse_ino_= t inode, int mode, ret =3D -EOPNOTSUPP; } =20 - fuse_reply_err(req, ret < 0 ? -ret : 0); + return ret < 0 ? ret : 0; } =20 /** * Let clients fsync the exported image. + * Return 0 on success (no 'out' object), and -errno on error. */ -static void fuse_fsync(fuse_req_t req, fuse_ino_t inode, int datasync, - struct fuse_file_info *fi) +static ssize_t fuse_fsync(FuseExport *exp) { - FuseExport *exp =3D fuse_req_userdata(req); - int ret; - - ret =3D blk_flush(exp->common.blk); - fuse_reply_err(req, ret < 0 ? -ret : 0); + return blk_flush(exp->common.blk); } =20 /** * Called before an FD to the exported image is closed. (libfuse * notes this to be a way to return last-minute errors.) + * Return 0 on success (no 'out' object), and -errno on error. */ -static void fuse_flush(fuse_req_t req, fuse_ino_t inode, - struct fuse_file_info *fi) +static ssize_t fuse_flush(FuseExport *exp) { - fuse_fsync(req, inode, 1, fi); + return blk_flush(exp->common.blk); } =20 #ifdef CONFIG_FUSE_LSEEK /** * Let clients inquire allocation status. + * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static void fuse_lseek(fuse_req_t req, fuse_ino_t inode, off_t offset, - int whence, struct fuse_file_info *fi) +static ssize_t fuse_lseek(FuseExport *exp, struct fuse_lseek_out *out, + uint64_t offset, uint32_t whence) { - FuseExport *exp =3D fuse_req_userdata(req); - if (whence !=3D SEEK_HOLE && whence !=3D SEEK_DATA) { - fuse_reply_err(req, EINVAL); - return; + return -EINVAL; } =20 while (true) { @@ -900,8 +1173,7 @@ static void fuse_lseek(fuse_req_t req, fuse_ino_t inod= e, off_t offset, ret =3D bdrv_block_status_above(blk_bs(exp->common.blk), NULL, offset, INT64_MAX, &pnum, NULL, NULL= ); if (ret < 0) { - fuse_reply_err(req, -ret); - return; + return ret; } =20 if (!pnum && (ret & BDRV_BLOCK_EOF)) { @@ -918,34 +1190,38 @@ static void fuse_lseek(fuse_req_t req, fuse_ino_t in= ode, off_t offset, =20 blk_len =3D blk_getlength(exp->common.blk); if (blk_len < 0) { - fuse_reply_err(req, -blk_len); - return; + return blk_len; } =20 if (offset > blk_len || whence =3D=3D SEEK_DATA) { - fuse_reply_err(req, ENXIO); - } else { - fuse_reply_lseek(req, offset); + return -ENXIO; } - return; + + *out =3D (struct fuse_lseek_out) { + .offset =3D offset, + }; + return sizeof(*out); } =20 if (ret & BDRV_BLOCK_DATA) { if (whence =3D=3D SEEK_DATA) { - fuse_reply_lseek(req, offset); - return; + *out =3D (struct fuse_lseek_out) { + .offset =3D offset, + }; + return sizeof(*out); } } else { if (whence =3D=3D SEEK_HOLE) { - fuse_reply_lseek(req, offset); - return; + *out =3D (struct fuse_lseek_out) { + .offset =3D offset, + }; + return sizeof(*out); } } =20 /* Safety check against infinite loops */ if (!pnum) { - fuse_reply_err(req, ENXIO); - return; + return -ENXIO; } =20 offset +=3D pnum; @@ -953,21 +1229,241 @@ static void fuse_lseek(fuse_req_t req, fuse_ino_t i= node, off_t offset, } #endif =20 -static const struct fuse_lowlevel_ops fuse_ops =3D { - .init =3D fuse_init, - .lookup =3D fuse_lookup, - .getattr =3D fuse_getattr, - .setattr =3D fuse_setattr, - .open =3D fuse_open, - .read =3D fuse_read, - .write =3D fuse_write, - .fallocate =3D fuse_fallocate, - .flush =3D fuse_flush, - .fsync =3D fuse_fsync, +/** + * Write a FUSE response to the given @fd. + * + * Effectively, writes out_hdr->common.len bytes of the buffer that is *ou= t_hdr. + * + * @fd: FUSE file descriptor + * @out_hdr: Request response header and request-specific response data + */ +static int fuse_write_response(int fd, FuseRequestOutHeader *out_hdr) +{ + size_t to_write =3D out_hdr->common.len; + ssize_t ret; + + /* Must at least write fuse_out_header */ + assert(to_write >=3D sizeof(out_hdr->common)); + + ret =3D RETRY_ON_EINTR(write(fd, out_hdr, to_write)); + if (ret < 0) { + ret =3D -errno; + error_report("Failed to write to FUSE device: %s", strerror(-ret)); + return ret; + } + + /* Short writes are unexpected, treat them as errors */ + if (ret !=3D to_write) { + error_report("Short write to FUSE device, wrote %zi of %zu bytes", + ret, to_write); + return -EIO; + } + + return 0; +} + +/** + * Write a FUSE error response to @fd. + * + * @fd: FUSE file descriptor + * @in_hdr: Incoming request header to which to respond + * @err: Error code (-errno, must be negative!) + */ +static int fuse_write_err(int fd, const struct fuse_in_header *in_hdr, int= err) +{ + FuseRequestOutHeader out_hdr =3D { + .common =3D { + .len =3D sizeof(out_hdr.common), + /* FUSE expects negative error values */ + .error =3D err, + .unique =3D in_hdr->unique, + }, + }; + + return fuse_write_response(fd, &out_hdr); +} + +/** + * Write a FUSE response to the given @fd, using separate buffers for the + * response header and data. + * + * In contrast to fuse_write_response(), this function cannot return a full + * FuseRequestOutHeader (i.e. including request-specific response structs), + * but only FuseRequestOutHeader.common. The remaining data must be in + * *buf. + * + * (Total length must be set in out_hdr->len.) + * + * @fd: FUSE file descriptor + * @out_hdr: Request response header + * @buf: Pointer to response data + */ +static int fuse_write_buf_response(int fd, + const struct fuse_out_header *out_hdr, + const void *buf) +{ + size_t to_write =3D out_hdr->len; + struct iovec iov[2] =3D { + { (void *)out_hdr, sizeof(*out_hdr) }, + { (void *)buf, to_write - sizeof(*out_hdr) }, + }; + ssize_t ret; + + /* *buf length must not be negative */ + assert(to_write >=3D sizeof(*out_hdr)); + + ret =3D RETRY_ON_EINTR(writev(fd, iov, ARRAY_SIZE(iov))); + if (ret < 0) { + ret =3D -errno; + error_report("Failed to write to FUSE device: %s", strerror(-ret)); + return ret; + } + + /* Short writes are unexpected, treat them as errors */ + if (ret !=3D to_write) { + error_report("Short write to FUSE device, wrote %zi of %zu bytes", + ret, to_write); + return -EIO; + } + + return 0; +} + +/** + * Process a FUSE request, incl. writing the response. + */ +static void fuse_process_request(FuseExport *exp, + const FuseRequestInHeader *in_hdr, + const void *data_buffer) +{ + FuseRequestOutHeader out_hdr; + /* For read requests: Data to be returned */ + void *out_data_buffer =3D NULL; + ssize_t ret; + + switch (in_hdr->common.opcode) { + case FUSE_INIT: + ret =3D fuse_init(exp, &out_hdr.init, &in_hdr->init); + break; + + case FUSE_DESTROY: + ret =3D 0; + break; + + case FUSE_STATFS: + ret =3D fuse_statfs(exp, &out_hdr.statfs); + break; + + case FUSE_OPEN: + ret =3D fuse_open(exp, &out_hdr.open); + break; + + case FUSE_RELEASE: + ret =3D 0; + break; + + case FUSE_LOOKUP: + ret =3D -ENOENT; /* There is no node but the root node */ + break; + + case FUSE_FORGET: + case FUSE_BATCH_FORGET: + /* These have no response, and there is nothing we need to do */ + return; + + case FUSE_GETATTR: + ret =3D fuse_getattr(exp, &out_hdr.attr); + break; + + case FUSE_SETATTR: { + const struct fuse_setattr_in *in =3D &in_hdr->setattr; + ret =3D fuse_setattr(exp, &out_hdr.attr, + in->valid, in->size, in->mode, in->uid, in->gid= ); + break; + } + + case FUSE_READ: { + const struct fuse_read_in *in =3D &in_hdr->read; + ret =3D fuse_read(exp, &out_data_buffer, in->offset, in->size); + break; + } + + case FUSE_WRITE: { + const struct fuse_write_in *in =3D &in_hdr->write; + uint32_t req_len =3D in_hdr->common.len; + + if (unlikely(req_len < sizeof(in_hdr->common) + sizeof(*in) + + in->size)) { + warn_report("FUSE WRITE truncated; received %zu bytes of %" PR= Iu32, + req_len - sizeof(in_hdr->common) - sizeof(*in), + in->size); + ret =3D -EINVAL; + break; + } + + /* + * read_from_fuse_fd() has checked that in_hdr->len matches the nu= mber + * of bytes read, which cannot exceed the max_write value we set + * (FUSE_MAX_WRITE_BYTES). So we know that FUSE_MAX_WRITE_BYTES >= =3D + * in_hdr->len >=3D in->size + X, so this assertion must hold. + */ + assert(in->size <=3D FUSE_MAX_WRITE_BYTES); + + ret =3D fuse_write(exp, &out_hdr.write, + in->offset, in->size, data_buffer); + break; + } + + case FUSE_FALLOCATE: { + const struct fuse_fallocate_in *in =3D &in_hdr->fallocate; + ret =3D fuse_fallocate(exp, in->offset, in->length, in->mode); + break; + } + + case FUSE_FSYNC: + ret =3D fuse_fsync(exp); + break; + + case FUSE_FLUSH: + ret =3D fuse_flush(exp); + break; + #ifdef CONFIG_FUSE_LSEEK - .lseek =3D fuse_lseek, + case FUSE_LSEEK: { + const struct fuse_lseek_in *in =3D &in_hdr->lseek; + ret =3D fuse_lseek(exp, &out_hdr.lseek, in->offset, in->whence); + break; + } #endif -}; + + default: + ret =3D -ENOSYS; + } + + if (ret >=3D 0) { + out_hdr.common =3D (struct fuse_out_header) { + .len =3D sizeof(out_hdr.common) + ret, + .unique =3D in_hdr->common.unique, + }; + } else { + /* fuse_read() must not return a buffer in case of error */ + assert(out_data_buffer =3D=3D NULL); + + out_hdr.common =3D (struct fuse_out_header) { + .len =3D sizeof(out_hdr.common), + /* FUSE expects negative errno values */ + .error =3D ret, + .unique =3D in_hdr->common.unique, + }; + } + + if (out_data_buffer) { + fuse_write_buf_response(exp->fuse_fd, &out_hdr.common, out_data_bu= ffer); + qemu_vfree(out_data_buffer); + } else { + fuse_write_response(exp->fuse_fd, &out_hdr); + } +} =20 const BlockExportDriver blk_exp_fuse =3D { .type =3D BLOCK_EXPORT_TYPE_FUSE, --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421810; cv=none; d=zohomail.com; s=zohoarc; b=nEmFIjc8JHDXcsRWXVapQUxowu3zOPDesswWXNjt1pqM3HchBlVij+FtqMKVxkE89yiZgcpV162OSiI+ujhwgRw4KOCqRSv1a+CNKAUGkVSKxRYtgfluKzo5kGoGbrlazLpXnTxJkJ3n3bizzeJK099RJGnxIHZznMoS33Xknk4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421810; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=LiGqoSdYSKFAOkGzSKy1bBHdWLKT+JAo0Uk73BDkFRI=; b=WVsjHWgWW7DGwTVkFXDqQcsn/h6RP/lbYsnuBkXHWNZ6DNJNhyqWuUjUpJxRCyEYHgXsa08pYmRrRC/oVbZTPdb2TfPKLrHA9FdSFMwfuO38bYfYoT2FCkV+yZwZBRwe05R1HXhnOB9jtKcsmqyPBCP1BJ4SbL00ouJNNX9QYGo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421810065933.0622800233228; Wed, 18 Feb 2026 05:36:50 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfj-0004Jf-Cb; Wed, 18 Feb 2026 08:32:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfa-000468-G2 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:46 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfO-0005hJ-V4 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:46 -0500 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-625-wrp-KNkgOli8WrcqDEXgtw-1; Wed, 18 Feb 2026 08:27:27 -0500 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-48372facfedso10050585e9.0 for ; Wed, 18 Feb 2026 05:27:27 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4835dcfb28dsm544576195e9.11.2026.02.18.05.27.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421553; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LiGqoSdYSKFAOkGzSKy1bBHdWLKT+JAo0Uk73BDkFRI=; b=SKb+jCPc6CFTYY2VKpp/N2K/KCAf7s24f8WjBcwjmS+RO1VcEuBiVj8giP0qDW8wcapfdh hNPbIeAO7UGFTg1dagWNJysyCTuFjUuDPRQzHfXxxvjdyPcdNTan8QPsIHFQbyhxMgicZv JUSfrniWWSR2U10EIk7aLkp0w41V7oM= X-MC-Unique: wrp-KNkgOli8WrcqDEXgtw-1 X-Mimecast-MFC-AGG-ID: wrp-KNkgOli8WrcqDEXgtw_1771421247 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421246; x=1772026046; darn=nongnu.org; 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; bh=LiGqoSdYSKFAOkGzSKy1bBHdWLKT+JAo0Uk73BDkFRI=; b=pE3g0qySRdepVxULysg34YlAYSC8zYTT/nE2m4NQstoLNLNtr0nNHA9wykQjvKvifP 3+djHMAHGMVq6gwoTXUl63+xuPh56SSicRZG04OnTzA9Rtc5/HJwDGbKL/yO9u1qF4Gz redYrcEGZro3qhAC+A7y2DBJhQ1bvFC8hqqbDTgbqaqBRj0XrfzqjSG30mvza/xJ6r7h QshzKRMfDYVWZvAmrKAqIL0DfT6BzbYn8LcTqjoXiHepzpG63Twbe6hd/NqWnDIQ0wH4 0ih5Mhi+AhWlc2xtLDA1wNHE0qNNCqwZPjnHxQ67yNnUN0accwGRG64l4IvwngwGADiJ luWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421246; x=1772026046; 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; bh=LiGqoSdYSKFAOkGzSKy1bBHdWLKT+JAo0Uk73BDkFRI=; b=OCacfcwqCxif8KnguNkD6ik0w+GQ4KdJu9SI3EvE9kYuAzsM81MQzOeNZo9wySjwbc XIZW8yVzNtOrgaz9+FodeOzTWADyODI74hyQRWTO+xjpjuvle5gHo+8HiKThNeJsUw/n 5l5h60rKp3orWfIF3UJ5I0HjdI9RHCkIekabSgBVXKK0tvCaxNywiV/o2E5bZX9raPuS n1pMLQEJD5WwExGb1sH7LyNEWoLynJNNASmUyxmeWhqwFhVPWp8CnM+uJD89aqbmz+EL CGILBVwde1kwe6H0qJHx4l9bkRmVrSveU2Sj4eme1gFRlfmvyfD4eZwxXHk0+OeLS8sH kg7w== X-Gm-Message-State: AOJu0YzjHDMYpX2mr/xFUWLeCzo0MQ9MpvxvZ8hU41mTeoE6d1o/di8r VcZvpq0la4Q886tHUlSZd553LK8vrmnl6QgeCTEp5m/mACpuCtvDVXnEZtKvH6P5RGn4/Dsrq0v WzvIO9ctmUt4FhUGCZbL3VgiLOi9kkUydA14UPVz0hXdnm3302Oa/TCJO X-Gm-Gg: AZuq6aIeBIkGxZeAAQKnRfy4bcjkrhJtnRw2Dz3tzimryP3tI+8mhOZRPRwN73G+yGA eszk0I+AIBimu5z5+cvl5jzUxNrt/jS3kKarYmCoFrzh94La5LJhbxg2aaIpuvD6uOPbzo//TW5 XNiugI3EyM9JpMA5twolI8vXstCuy7RB9pZrVkaI2X2qFHFOTLPZHjKbgnTQ3yeCPA0Onn7oLtv TiPX3OhTNGTB8CO7I33Ipr2GnpDaf/ZyzCZEmrXFVqNusIZlNXUsUgOypS7g6RosgNyl+WmZRD4 0O4GghYx9tlUDHDh1BiVknOi+FRCUhta5fzdWxB5yN3nQlZOaJ5zd/qjaq7Qv3+e2EVjLZSNVoQ TNoLQuaR6wdFioU5R3mlykgtquXYR/dMzjSjHKpCzQMZ74EsTFO8BPm5RSv0St6l0IAmfgX5SDN jCTUQT X-Received: by 2002:a05:600c:22cc:b0:483:6cf0:5d8b with SMTP id 5b1f17b1804b1-48398ca3d13mr23483285e9.9.1771421246452; Wed, 18 Feb 2026 05:27:26 -0800 (PST) X-Received: by 2002:a05:600c:22cc:b0:483:6cf0:5d8b with SMTP id 5b1f17b1804b1-48398ca3d13mr23482835e9.9.1771421245863; Wed, 18 Feb 2026 05:27:25 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 17/24] fuse: Reduce max read size Date: Wed, 18 Feb 2026 14:26:26 +0100 Message-ID: <20260218132633.29748-18-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421811120158500 Content-Type: text/plain; charset="utf-8" We are going to introduce parallel processing via coroutines, a maximum read size of 64 MB may be problematic, allowing users of the export to force us to allocate quite large amounts of memory with just a few requests. At least tone it down to 1 MB, which is still probably far more than enough. (Larger requests are split automatically by the FUSE kernel driver anyway.) (Yes, we inadvertently already had parallel request processing due to nested polling before. Better to fix this late than never.) Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index c481fb72a2..8c5a1d397d 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -45,7 +45,7 @@ #endif =20 /* Prevent overly long bounce buffer allocations */ -#define FUSE_MAX_READ_BYTES (MIN(BDRV_REQUEST_MAX_BYTES, 64 * 1024 * 1024)) +#define FUSE_MAX_READ_BYTES (MIN(BDRV_REQUEST_MAX_BYTES, 1 * 1024 * 1024)) /* Small enough to fit in the request buffer */ #define FUSE_MAX_WRITE_BYTES (64 * 1024) =20 --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421700; cv=none; d=zohomail.com; s=zohoarc; b=ahJptdFCqKOFc3mxwJcvxodtcF7MEpSlc34OERL2fw66yrXBMt3qaiFgNGUVsR3PcctTGajQ92lE1dONM2HuJwf75XyBKn4x6JcH7CFSvDA4Z1RX5pzFU7v6Vv4yEO82ILEuOCG4W7Fa+wtm8rumpXs9t5zDnXakgrRDkuAnT00= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421700; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=hC0XQ436Lp4KW+507FjuStJRdl+9Hpi0tG50/F5Xsmg=; b=U/bJKYH1vijnMlXACR0ON/onZ6LOKbqShfTWuIeSesF+aRLS6lI7zMHiWGGwVA1AiSKeSVCi6zC+Ke+lGwCq/MYzXsvXg7qLXP52xs4GJV9M8qQUCga/U4ttTFPYR8DyFRQixSLVaTA+N/3v2HJ8LpLeUKWN0is2d4YHXADVsQ8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421700446260.0393369769722; Wed, 18 Feb 2026 05:35:00 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfh-0004IF-M2; Wed, 18 Feb 2026 08:32:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfe-0004Ev-Tk for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:50 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfT-0005pY-8W for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:50 -0500 Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-544-5hH5UpFdOxymyHA70RAEEQ-1; Wed, 18 Feb 2026 08:27:30 -0500 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-437681ecd32so4394591f8f.1 for ; Wed, 18 Feb 2026 05:27:30 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796a74918sm41909165f8f.17.2026.02.18.05.27.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421557; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hC0XQ436Lp4KW+507FjuStJRdl+9Hpi0tG50/F5Xsmg=; b=KddgW/6Av0EVYYNdORWdgeNZTRDkBCWt0/4l7CWuuuyF9gPOPybIs+sj4xso0RWELFonDq ZP9DWlxHcLxuEU8xeCBWJ64/Etby2nFCVOau/nP1my/R/4Kzb/PEb+YfVD5PDfRINAWckM tlxxe4/9XCqUMnNrt8A7THu+hi5biOQ= X-MC-Unique: 5hH5UpFdOxymyHA70RAEEQ-1 X-Mimecast-MFC-AGG-ID: 5hH5UpFdOxymyHA70RAEEQ_1771421250 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421249; x=1772026049; darn=nongnu.org; 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; bh=hC0XQ436Lp4KW+507FjuStJRdl+9Hpi0tG50/F5Xsmg=; b=mkjzVpXLLrmsUtYIC1saRf7lYO76GNhqNixeamT1ktFA2VrO61xfZ5c4Ap9uH/beOj jss514UoNGBRRsiR4aOxRBTC+85hPOG3x6rwf5O4VaDl0gCS/xVOyzFxXBH/tjcyaqXg OBefCqis+jtWoN2dcvdEzBRoPZoVfP3cXtM88A+CHV1aQO/SZoTmoyxN4Jhbr47xwx/g l97QUlOq2APegnu+2iDlojax0lRjBrMMkGqPzY11N23rFqaHBeJneguP8dnbxiJKaX92 N1e1S7eXL//eO+MHQaZBz/uCb9wiqeDnIRmRJuALPFbAV7I8TbRzXJp8Ew0XPNjQfUF5 E+JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421249; x=1772026049; 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; bh=hC0XQ436Lp4KW+507FjuStJRdl+9Hpi0tG50/F5Xsmg=; b=MeQ6QUQl6e9cFTXb5Yp7i1dfy4NokAxobuBp5L3NEcK4zqNRvqCsk1753/Qsb7FuqO fzmno4eFmYZIfqZvnmPRO4HDnG9YDnCDMxfHqJ2vyGXG6cJL1cD3N0EpmtCV9ONhBkVo 0q4kS8MwwglV+Js64RxVLCjrDJ283WJS7FzEQ53ZLzigApTeOxKG3svP+3Yod9s94rBj 5LC/HCDCANe0mJQbxFBRELjYrZe8RlXVILvI5Fzag/NGfkOrrv4T73g/fyssH9Yb9msj j6bWW+FYCHSTAIK/dqkIPlzkCvJZwX7tw2e7VLGToQeBoQPzLNyTKnUAf5iPZoqmigXH eVYQ== X-Gm-Message-State: AOJu0Yxl/EPT57QCWZr2URFQ5kJNnAZpdiqttNHHYNwSSGCMEyUtHfMI ODDbpwt9gWbS2whibTcf9nqdg0fHVAXmo+Nrt+/n369U0lsxhSDCUhRTDy/1rMKRV3EoiRmn1sD zKi1ifRDm8s/NCRYATuVWvUacOXT1+Q63WJIMkW9Uhy4TIvK5qqSuM+zf X-Gm-Gg: AZuq6aIedWPFO7oVVxnZYxJyKbnyZ3M8yp06j/kiZ18BWb80FNEx56zI/PZfgFwjH1x ggJoGvAvSaKrkKiIYWCTiKwFniXp3HruPfEb73XerVDEZDAUnpsj1zZdm+aAq/xzOZaQRqQhAXa 1JFjwyvrPcZFUTaFEg5zBlbGysFpkR8RfJuHbr98duln3ajfQ7z0BHMc+d7rkdi/Y0qW1w4AwEg 6CvurhuRd/VjxqDYw11tLAwGfDgSDwOBYhC9eQI+5KjHESgGSOTSRYHe4n0nCefZug2aap37V5p Pgo3N7cFJWXA2dUio79eUwsPLm6M62iYGFyrOK5ro1p2wSWVQWnRVfs8tBMcxjWf4yPuu84a3v5 N6xWavQz5v6Hk1oko3iez2Uo9o6dxCzG21w7okvKXaoPB1LgiwFpfuSZR2bX22+lQaDCgtzwfUt JiAk6a X-Received: by 2002:a05:6000:2c01:b0:437:6d8c:c07f with SMTP id ffacd0b85a97d-4379dba4416mr24878176f8f.52.1771421249092; Wed, 18 Feb 2026 05:27:29 -0800 (PST) X-Received: by 2002:a05:6000:2c01:b0:437:6d8c:c07f with SMTP id ffacd0b85a97d-4379dba4416mr24878113f8f.52.1771421248407; Wed, 18 Feb 2026 05:27:28 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 18/24] fuse: Process requests in coroutines Date: Wed, 18 Feb 2026 14:26:27 +0100 Message-ID: <20260218132633.29748-19-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421701887154100 Make fuse_process_request() a coroutine_fn (fuse_co_process_request()) and have read_from_fuse_fd() launch it inside of a newly created coroutine instead of running it synchronously. This way, we can process requests in parallel. These are the benchmark results, compared to (a) the original results with libfuse, and (b) the results after switching away from libfuse (i.e. before this patch): file: (vs. libfuse / vs. no libfuse) read: seq aio: 97.8k =C2=B11.5k (-2% / -8%) rand aio: 95.8k =C2=B13.4k (+90% / +98%) seq sync: 34.5k =C2=B11.0k (-4% / -3%) rand sync: 9.9k =C2=B10.1k (-1% / -1%) write: seq aio: 68.7k =C2=B11.3k (-5% / -10%) rand aio: 68.9k =C2=B11.1k (-2% / -10%) seq sync: 30.6k =C2=B10.9k (=C2=B10% / -3%) rand sync: 30.6k =C2=B10.6k (+1% / -1%) null: read: seq aio: 174.5k =C2=B16.8k (+11% / +8%) rand aio: 170.9k =C2=B15.7k (+8% / +3%) seq sync: 82.0k =C2=B13.3k (+2% / +2%) rand sync: 78.0k =C2=B14.0k (+1% / -1%) write: seq aio: 196.0k =C2=B12.8k (+27% / +6%) rand aio: 191.2k =C2=B17.9k (+24% / +2%) seq sync: 83.3k =C2=B14.4k (+9% / +1%) rand sync: 79.5k =C2=B14.4k (+9% / +1%) So there is not much difference, especially when compared to how it was with libfuse, except for the randread AIO case with an actual file. That improves greatly. Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 174 ++++++++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 72 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 8c5a1d397d..b60affe86b 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -27,6 +27,7 @@ #include "block/qapi.h" #include "qapi/error.h" #include "qapi/qapi-commands-block.h" +#include "qemu/coroutine.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "system/block-backend.h" @@ -182,9 +183,9 @@ static int mount_fuse_export(FuseExport *exp, Error **e= rrp); static bool is_regular_file(const char *path, Error **errp); =20 static void read_from_fuse_fd(void *opaque); -static void fuse_process_request(FuseExport *exp, - const FuseRequestInHeader *in_hdr, - const void *data_buffer); +static void coroutine_fn +fuse_co_process_request(FuseExport *exp, const FuseRequestInHeader *in_hdr, + const void *data_buffer); static int fuse_write_err(int fd, const struct fuse_in_header *in_hdr, int= err); =20 static void fuse_inc_in_flight(FuseExport *exp) @@ -519,9 +520,14 @@ static ssize_t req_op_hdr_len(const FuseRequestInHeade= r *in_hdr) } =20 /** - * Try to read and process a single request from the FUSE FD. + * Try to read a single request from the FUSE FD. + * Takes a FuseExport pointer in `opaque`. + * + * Assumes the export's in-flight counter has already been incremented. + * + * If a request is available, process it. */ -static void read_from_fuse_fd(void *opaque) +static void coroutine_fn co_read_from_fuse_fd(void *opaque) { FuseExport *exp =3D opaque; int fuse_fd =3D exp->fuse_fd; @@ -532,8 +538,6 @@ static void read_from_fuse_fd(void *opaque) struct iovec iov[2]; ssize_t op_hdr_len; =20 - fuse_inc_in_flight(exp); - if (unlikely(qatomic_read(&exp->halted))) { goto no_request; } @@ -602,13 +606,29 @@ static void read_from_fuse_fd(void *opaque) release_write_data_buffer(exp, &data_buffer); } =20 - fuse_process_request(exp, in_hdr, data_buffer); + fuse_co_process_request(exp, in_hdr, data_buffer); =20 no_request: release_write_data_buffer(exp, &data_buffer); fuse_dec_in_flight(exp); } =20 +/** + * Try to read and process a single request from the FUSE FD. + * (To be used as a handler for when the FUSE FD becomes readable.) + * Takes a FuseExport pointer in `opaque`. + */ +static void read_from_fuse_fd(void *opaque) +{ + FuseExport *exp =3D opaque; + Coroutine *co; + + co =3D qemu_coroutine_create(co_read_from_fuse_fd, exp); + /* Decremented by co_read_from_fuse_fd() */ + fuse_inc_in_flight(exp); + qemu_coroutine_enter(co); +} + static void fuse_export_shutdown(BlockExport *blk_exp) { FuseExport *exp =3D container_of(blk_exp, FuseExport, common); @@ -683,8 +703,9 @@ static bool is_regular_file(const char *path, Error **e= rrp) * Process FUSE INIT. * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static ssize_t fuse_init(FuseExport *exp, struct fuse_init_out *out, - const struct fuse_init_in_compat *in) +static ssize_t coroutine_fn +fuse_co_init(FuseExport *exp, struct fuse_init_out *out, + const struct fuse_init_in_compat *in) { const uint32_t supported_flags =3D FUSE_ASYNC_READ | FUSE_ASYNC_DIO; =20 @@ -739,7 +760,8 @@ static ssize_t fuse_init(FuseExport *exp, struct fuse_i= nit_out *out, /** * Return some filesystem information, just to not break e.g. `df`. */ -static ssize_t fuse_statfs(FuseExport *exp, struct fuse_statfs_out *out) +static ssize_t coroutine_fn +fuse_co_statfs(FuseExport *exp, struct fuse_statfs_out *out) { BlockDriverState *root_bs; uint32_t opt_transfer =3D 512; @@ -767,17 +789,18 @@ static ssize_t fuse_statfs(FuseExport *exp, struct fu= se_statfs_out *out) * Let clients get file attributes (i.e., stat() the file). * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static ssize_t fuse_getattr(FuseExport *exp, struct fuse_attr_out *out) +static ssize_t coroutine_fn +fuse_co_getattr(FuseExport *exp, struct fuse_attr_out *out) { int64_t length, allocated_blocks; time_t now =3D time(NULL); =20 - length =3D blk_getlength(exp->common.blk); + length =3D blk_co_getlength(exp->common.blk); if (length < 0) { return length; } =20 - allocated_blocks =3D bdrv_get_allocated_file_size(blk_bs(exp->common.b= lk)); + allocated_blocks =3D bdrv_co_get_allocated_file_size(blk_bs(exp->commo= n.blk)); if (allocated_blocks <=3D 0) { allocated_blocks =3D DIV_ROUND_UP(length, 512); } else { @@ -804,8 +827,9 @@ static ssize_t fuse_getattr(FuseExport *exp, struct fus= e_attr_out *out) return sizeof(*out); } =20 -static int fuse_do_truncate(const FuseExport *exp, int64_t size, - bool req_zero_write, PreallocMode prealloc) +static int coroutine_fn +fuse_co_do_truncate(const FuseExport *exp, int64_t size, bool req_zero_wri= te, + PreallocMode prealloc) { uint64_t blk_perm, blk_shared_perm; BdrvRequestFlags truncate_flags =3D 0; @@ -834,8 +858,8 @@ static int fuse_do_truncate(const FuseExport *exp, int6= 4_t size, } } =20 - ret =3D blk_truncate(exp->common.blk, size, true, prealloc, - truncate_flags, NULL); + ret =3D blk_co_truncate(exp->common.blk, size, true, prealloc, + truncate_flags, NULL); =20 if (add_resize_perm) { /* Must succeed, because we are only giving up the RESIZE permissi= on */ @@ -856,9 +880,9 @@ static int fuse_do_truncate(const FuseExport *exp, int6= 4_t size, * they cannot be given non-owner access. * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static ssize_t fuse_setattr(FuseExport *exp, struct fuse_attr_out *out, - uint32_t to_set, uint64_t size, uint32_t mode, - uint32_t uid, uint32_t gid) +static ssize_t coroutine_fn +fuse_co_setattr(FuseExport *exp, struct fuse_attr_out *out, uint32_t to_se= t, + uint64_t size, uint32_t mode, uint32_t uid, uint32_t gid) { int supported_attrs; int ret; @@ -895,7 +919,7 @@ static ssize_t fuse_setattr(FuseExport *exp, struct fus= e_attr_out *out, return -EACCES; } =20 - ret =3D fuse_do_truncate(exp, size, true, PREALLOC_MODE_OFF); + ret =3D fuse_co_do_truncate(exp, size, true, PREALLOC_MODE_OFF); if (ret < 0) { return ret; } @@ -914,7 +938,7 @@ static ssize_t fuse_setattr(FuseExport *exp, struct fus= e_attr_out *out, exp->st_gid =3D gid; } =20 - return fuse_getattr(exp, out); + return fuse_co_getattr(exp, out); } =20 /** @@ -922,7 +946,8 @@ static ssize_t fuse_setattr(FuseExport *exp, struct fus= e_attr_out *out, * just acknowledge the request. * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static ssize_t fuse_open(FuseExport *exp, struct fuse_open_out *out) +static ssize_t coroutine_fn +fuse_co_open(FuseExport *exp, struct fuse_open_out *out) { *out =3D (struct fuse_open_out) { .open_flags =3D FOPEN_DIRECT_IO | FOPEN_PARALLEL_DIRECT_WRITES, @@ -936,8 +961,8 @@ static ssize_t fuse_open(FuseExport *exp, struct fuse_o= pen_out *out) * Returns the buffer (read) size on success, and -errno on error. * After use, *bufptr must be freed via qemu_vfree(). */ -static ssize_t fuse_read(FuseExport *exp, void **bufptr, - uint64_t offset, uint32_t size) +static ssize_t coroutine_fn +fuse_co_read(FuseExport *exp, void **bufptr, uint64_t offset, uint32_t siz= e) { int64_t blk_len; void *buf; @@ -952,7 +977,7 @@ static ssize_t fuse_read(FuseExport *exp, void **bufptr, * Clients will expect short reads at EOF, so we have to limit * offset+size to the image length. */ - blk_len =3D blk_getlength(exp->common.blk); + blk_len =3D blk_co_getlength(exp->common.blk); if (blk_len < 0) { return blk_len; } @@ -971,7 +996,7 @@ static ssize_t fuse_read(FuseExport *exp, void **bufptr, return -ENOMEM; } =20 - ret =3D blk_pread(exp->common.blk, offset, size, buf, 0); + ret =3D blk_co_pread(exp->common.blk, offset, size, buf, 0); if (ret < 0) { qemu_vfree(buf); return ret; @@ -985,8 +1010,9 @@ static ssize_t fuse_read(FuseExport *exp, void **bufpt= r, * Handle client writes to the exported image. @buf has the data to be wr= itten. * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static ssize_t fuse_write(FuseExport *exp, struct fuse_write_out *out, - uint64_t offset, uint32_t size, const void *buf) +static ssize_t coroutine_fn +fuse_co_write(FuseExport *exp, struct fuse_write_out *out, + uint64_t offset, uint32_t size, const void *buf) { int64_t blk_len; int ret; @@ -1005,7 +1031,7 @@ static ssize_t fuse_write(FuseExport *exp, struct fus= e_write_out *out, * Clients will expect short writes at EOF, so we have to limit * offset+size to the image length. */ - blk_len =3D blk_getlength(exp->common.blk); + blk_len =3D blk_co_getlength(exp->common.blk); if (blk_len < 0) { return blk_len; } @@ -1021,7 +1047,8 @@ static ssize_t fuse_write(FuseExport *exp, struct fus= e_write_out *out, return -EINVAL; } else if (offset + size > blk_len) { if (exp->growable) { - ret =3D fuse_do_truncate(exp, offset + size, true, PREALLOC_MO= DE_OFF); + ret =3D fuse_co_do_truncate(exp, offset + size, true, + PREALLOC_MODE_OFF); if (ret < 0) { return ret; } @@ -1030,7 +1057,7 @@ static ssize_t fuse_write(FuseExport *exp, struct fus= e_write_out *out, } } =20 - ret =3D blk_pwrite(exp->common.blk, offset, size, buf, 0); + ret =3D blk_co_pwrite(exp->common.blk, offset, size, buf, 0); if (ret < 0) { return ret; } @@ -1045,8 +1072,9 @@ static ssize_t fuse_write(FuseExport *exp, struct fus= e_write_out *out, * Let clients perform various fallocate() operations. * Return 0 on success (no 'out' object), and -errno on error. */ -static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t l= ength, - uint32_t mode) +static ssize_t coroutine_fn +fuse_co_fallocate(FuseExport *exp, + uint64_t offset, uint64_t length, uint32_t mode) { int64_t blk_len; int ret; @@ -1055,7 +1083,7 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64= _t offset, uint64_t length, return -EACCES; } =20 - blk_len =3D blk_getlength(exp->common.blk); + blk_len =3D blk_co_getlength(exp->common.blk); if (blk_len < 0) { return blk_len; } @@ -1074,14 +1102,14 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint= 64_t offset, uint64_t length, =20 if (offset > blk_len) { /* No preallocation needed here */ - ret =3D fuse_do_truncate(exp, offset, true, PREALLOC_MODE_OFF); + ret =3D fuse_co_do_truncate(exp, offset, true, PREALLOC_MODE_O= FF); if (ret < 0) { return ret; } } =20 - ret =3D fuse_do_truncate(exp, offset + length, true, - PREALLOC_MODE_FALLOC); + ret =3D fuse_co_do_truncate(exp, offset + length, true, + PREALLOC_MODE_FALLOC); } #ifdef CONFIG_FALLOCATE_PUNCH_HOLE else if (mode & FALLOC_FL_PUNCH_HOLE) { @@ -1092,8 +1120,9 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64= _t offset, uint64_t length, do { int size =3D MIN(length, BDRV_REQUEST_MAX_BYTES); =20 - ret =3D blk_pwrite_zeroes(exp->common.blk, offset, size, - BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLB= ACK); + ret =3D blk_co_pwrite_zeroes(exp->common.blk, offset, size, + BDRV_REQ_MAY_UNMAP | + BDRV_REQ_NO_FALLBACK); if (ret =3D=3D -ENOTSUP) { /* * fallocate() specifies to return EOPNOTSUPP for unsuppor= ted @@ -1111,8 +1140,8 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64= _t offset, uint64_t length, else if (mode & FALLOC_FL_ZERO_RANGE) { if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + length > blk_len) { /* No need for zeroes, we are going to write them ourselves */ - ret =3D fuse_do_truncate(exp, offset + length, false, - PREALLOC_MODE_OFF); + ret =3D fuse_co_do_truncate(exp, offset + length, false, + PREALLOC_MODE_OFF); if (ret < 0) { return ret; } @@ -1121,8 +1150,8 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64= _t offset, uint64_t length, do { int size =3D MIN(length, BDRV_REQUEST_MAX_BYTES); =20 - ret =3D blk_pwrite_zeroes(exp->common.blk, - offset, size, 0); + ret =3D blk_co_pwrite_zeroes(exp->common.blk, + offset, size, 0); offset +=3D size; length -=3D size; } while (ret =3D=3D 0 && length > 0); @@ -1139,9 +1168,9 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64= _t offset, uint64_t length, * Let clients fsync the exported image. * Return 0 on success (no 'out' object), and -errno on error. */ -static ssize_t fuse_fsync(FuseExport *exp) +static ssize_t coroutine_fn fuse_co_fsync(FuseExport *exp) { - return blk_flush(exp->common.blk); + return blk_co_flush(exp->common.blk); } =20 /** @@ -1149,9 +1178,9 @@ static ssize_t fuse_fsync(FuseExport *exp) * notes this to be a way to return last-minute errors.) * Return 0 on success (no 'out' object), and -errno on error. */ -static ssize_t fuse_flush(FuseExport *exp) +static ssize_t coroutine_fn fuse_co_flush(FuseExport *exp) { - return blk_flush(exp->common.blk); + return blk_co_flush(exp->common.blk); } =20 #ifdef CONFIG_FUSE_LSEEK @@ -1159,8 +1188,9 @@ static ssize_t fuse_flush(FuseExport *exp) * Let clients inquire allocation status. * Return the number of bytes written to *out on success, and -errno on er= ror. */ -static ssize_t fuse_lseek(FuseExport *exp, struct fuse_lseek_out *out, - uint64_t offset, uint32_t whence) +static ssize_t coroutine_fn +fuse_co_lseek(FuseExport *exp, struct fuse_lseek_out *out, + uint64_t offset, uint32_t whence) { if (whence !=3D SEEK_HOLE && whence !=3D SEEK_DATA) { return -EINVAL; @@ -1170,8 +1200,8 @@ static ssize_t fuse_lseek(FuseExport *exp, struct fus= e_lseek_out *out, int64_t pnum; int ret; =20 - ret =3D bdrv_block_status_above(blk_bs(exp->common.blk), NULL, - offset, INT64_MAX, &pnum, NULL, NULL= ); + ret =3D bdrv_co_block_status_above(blk_bs(exp->common.blk), NULL, + offset, INT64_MAX, &pnum, NULL, N= ULL); if (ret < 0) { return ret; } @@ -1188,7 +1218,7 @@ static ssize_t fuse_lseek(FuseExport *exp, struct fus= e_lseek_out *out, * and @blk_len (the client-visible EOF). */ =20 - blk_len =3D blk_getlength(exp->common.blk); + blk_len =3D blk_co_getlength(exp->common.blk); if (blk_len < 0) { return blk_len; } @@ -1332,9 +1362,9 @@ static int fuse_write_buf_response(int fd, /** * Process a FUSE request, incl. writing the response. */ -static void fuse_process_request(FuseExport *exp, - const FuseRequestInHeader *in_hdr, - const void *data_buffer) +static void coroutine_fn +fuse_co_process_request(FuseExport *exp, const FuseRequestInHeader *in_hdr, + const void *data_buffer) { FuseRequestOutHeader out_hdr; /* For read requests: Data to be returned */ @@ -1343,7 +1373,7 @@ static void fuse_process_request(FuseExport *exp, =20 switch (in_hdr->common.opcode) { case FUSE_INIT: - ret =3D fuse_init(exp, &out_hdr.init, &in_hdr->init); + ret =3D fuse_co_init(exp, &out_hdr.init, &in_hdr->init); break; =20 case FUSE_DESTROY: @@ -1351,11 +1381,11 @@ static void fuse_process_request(FuseExport *exp, break; =20 case FUSE_STATFS: - ret =3D fuse_statfs(exp, &out_hdr.statfs); + ret =3D fuse_co_statfs(exp, &out_hdr.statfs); break; =20 case FUSE_OPEN: - ret =3D fuse_open(exp, &out_hdr.open); + ret =3D fuse_co_open(exp, &out_hdr.open); break; =20 case FUSE_RELEASE: @@ -1372,19 +1402,19 @@ static void fuse_process_request(FuseExport *exp, return; =20 case FUSE_GETATTR: - ret =3D fuse_getattr(exp, &out_hdr.attr); + ret =3D fuse_co_getattr(exp, &out_hdr.attr); break; =20 case FUSE_SETATTR: { const struct fuse_setattr_in *in =3D &in_hdr->setattr; - ret =3D fuse_setattr(exp, &out_hdr.attr, - in->valid, in->size, in->mode, in->uid, in->gid= ); + ret =3D fuse_co_setattr(exp, &out_hdr.attr, + in->valid, in->size, in->mode, in->uid, in->= gid); break; } =20 case FUSE_READ: { const struct fuse_read_in *in =3D &in_hdr->read; - ret =3D fuse_read(exp, &out_data_buffer, in->offset, in->size); + ret =3D fuse_co_read(exp, &out_data_buffer, in->offset, in->size); break; } =20 @@ -1402,36 +1432,36 @@ static void fuse_process_request(FuseExport *exp, } =20 /* - * read_from_fuse_fd() has checked that in_hdr->len matches the nu= mber - * of bytes read, which cannot exceed the max_write value we set + * co_read_from_fuse_fd() has checked that in_hdr->len matches the + * number of bytes read, which cannot exceed the max_write value w= e set * (FUSE_MAX_WRITE_BYTES). So we know that FUSE_MAX_WRITE_BYTES >= =3D * in_hdr->len >=3D in->size + X, so this assertion must hold. */ assert(in->size <=3D FUSE_MAX_WRITE_BYTES); =20 - ret =3D fuse_write(exp, &out_hdr.write, - in->offset, in->size, data_buffer); + ret =3D fuse_co_write(exp, &out_hdr.write, + in->offset, in->size, data_buffer); break; } =20 case FUSE_FALLOCATE: { const struct fuse_fallocate_in *in =3D &in_hdr->fallocate; - ret =3D fuse_fallocate(exp, in->offset, in->length, in->mode); + ret =3D fuse_co_fallocate(exp, in->offset, in->length, in->mode); break; } =20 case FUSE_FSYNC: - ret =3D fuse_fsync(exp); + ret =3D fuse_co_fsync(exp); break; =20 case FUSE_FLUSH: - ret =3D fuse_flush(exp); + ret =3D fuse_co_flush(exp); break; =20 #ifdef CONFIG_FUSE_LSEEK case FUSE_LSEEK: { const struct fuse_lseek_in *in =3D &in_hdr->lseek; - ret =3D fuse_lseek(exp, &out_hdr.lseek, in->offset, in->whence); + ret =3D fuse_co_lseek(exp, &out_hdr.lseek, in->offset, in->whence); break; } #endif --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421636; cv=none; d=zohomail.com; s=zohoarc; b=PTA+n4KUFEcHnVT7v7ap+oJw5Fu6XL74XZn7vnEc37XuWClWP/wsAJMp/74lX9jXk7IFedny/zK6OpFQ++fjyMCkeX1240xIqOebou/vV6D/ztf51fhHv2HF9gBdUAt+7dzmwLFq4rAeR80MfVIdF9IG6yKslbh7NGnhk6fkrF4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421636; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BO4JPf4lZk0oOeAlnCpzdI34YuiTPFRED7Rq/jcZllk=; b=Kq5PwiULd7QL5BSVjis0tRdqPV5j97nuNulk8C2j+MSB8CyE2ihlrgIO1Z1p5xii0QXVlQa+snwiO6MnEUgqLtOagK10TLRTsjjBnLYla8VTs1te5FEVzrZq7u4oT3jG2hgXOY8RCyWcUK8CMJBjtFe13tnYZov3/D3GC1Tgm0k= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421636524470.97446334394294; Wed, 18 Feb 2026 05:33:56 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfi-0004IV-HI; Wed, 18 Feb 2026 08:32:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfg-0004GX-39 for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:52 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfX-0005yD-7f for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:51 -0500 Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-284-IklIBxe4NWuvxZDpbI83VQ-1; Wed, 18 Feb 2026 08:27:33 -0500 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-435db9425ebso4763455f8f.1 for ; Wed, 18 Feb 2026 05:27:33 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796abc21dsm43672633f8f.20.2026.02.18.05.27.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421562; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BO4JPf4lZk0oOeAlnCpzdI34YuiTPFRED7Rq/jcZllk=; b=bqb5Hx3IhRcafUfyT61M8QBn3sirdarlWrahIB6toUOa0JEMBZqgESHeC/FeMUnTCJtQz2 szQnDAxh21CO1J1BnWcJpZnLIuaW/UWRkH2Tcyxe/W1X74v0ZC3oiKOIEwuT3UVab6CaTQ 8SSKnB7KBNTkh8Kln3xku7k8qlcStWY= X-MC-Unique: IklIBxe4NWuvxZDpbI83VQ-1 X-Mimecast-MFC-AGG-ID: IklIBxe4NWuvxZDpbI83VQ_1771421252 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421252; x=1772026052; darn=nongnu.org; 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; bh=BO4JPf4lZk0oOeAlnCpzdI34YuiTPFRED7Rq/jcZllk=; b=Kz8lGsjc9PryG1QqP2ewJkZSfJS9nK+gdAyqvSO6LOY++aZz89l4woBTv1ajJq1b2k Bfx8GkEQWkiUnP1y1ChCzcMqcetCOLwVKvr0XFIR4M5v+2R6TkC6GqhnO7to5szhNuWr x6TwBRp61CLKquyncXqk+qal2RqPwmKvLJuTyZNEpTVfkzhPaO4Y/qXRnSHONl8y8Mt8 BsH8lXOKLVc/QdKJQxtc5aS+kq2hjK4QsL2AyHeH8Jtx3+szDJ8HUIwW3stW87gU6nFr eQEBpHdglMZwvGWWdf37pbCFpUS50pVpw3MOm1k2bYUtQZ3LX3Tigc8M2Sge+WkgvCqX 9zkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421252; x=1772026052; 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; bh=BO4JPf4lZk0oOeAlnCpzdI34YuiTPFRED7Rq/jcZllk=; b=vvhXuAuIqbgWnuwxKczhAkDt8U/BE8fC5mdOt81Xm67YLvtieyLOBgTW8WLZf9gWmA TpxyVTZydmr53oIs1kqTWs3CAJeDP/mCDJIkNsWKyQTdVgNQ2CtoJGIzaOIC6gbgkDyk u7OJPdQ4Z0NLvg5KtS7+FVaI7b+YvyeY2khG2drAO9WLI6hZZn4YGKmaz9WEcg1bipkI rrsMn6jcoeCRMNiuB+tVZTz+9uWxoum/k/WcVI0YIKouB8daqfYeLQiO4RMJWPvFBKaO 54VwXh+4v/VIu79l6I3wuWCTvOnOEcdEU/VUMWuRU1476dQvINGtUuTwm/5P8eAQ2NYU rPng== X-Gm-Message-State: AOJu0YwmMNn9NGJUyQ7CMyStJnVxHf3+rnmVTWkzA1cSWx1OsZ6aXj26 Mw7MitrB4IuBZTvD1d5BuqeJ2yJl5tM3aGy+IDcXyyp5y9k5gYgkzBPaHk18xfR+Gkm7eJOZksR bP22/FyBtLJJUoKHP7E/KmbN/8Ywrxl/o1Uw5JZuBbEpi89vtw7Wzy6bObin3mOIx X-Gm-Gg: AZuq6aIaiUz3kfolTENLIv0/cMbPOUXkRmoDZCVgtZMicINWnSa5oUTY4tBJ2PPbfKK c6/yh2xfEjDyIh/WydebevWukYZeXgN829A1i15DsATrLRS5Lo3u0f2Kv78oO2NGl2kkh9lZwld 5hMUwofJAbXdo3E46APJ+IrpLObBK3z5v83H1h1+2lysl6AIOVZRQYegOQtqyFOnAz7s44OI7nJ iV8JfQcZaounoUWZLDE6x+aACmd+weuJ9/oN8Nrqg/jJxf7WN62jb4FBkHUtJQ1dkxRw5PblC67 /HMDhPMxHZUmj6xHpINIa801A9lNlPl0CE5alPmEKJJr3y5St/aCtykKwv5lQKwCE09Xgu8FLeb WGvBFys1N9ZA6j3xiBvo2v0Hig2C4QKbb47PD+a/1Ri0erw60X+S4csiea9l7bQxlE+AEgUkSCP h1Yobq X-Received: by 2002:a05:6000:2911:b0:437:6b2e:a262 with SMTP id ffacd0b85a97d-43958df1428mr3408186f8f.3.1771421251627; Wed, 18 Feb 2026 05:27:31 -0800 (PST) X-Received: by 2002:a05:6000:2911:b0:437:6b2e:a262 with SMTP id ffacd0b85a97d-43958df1428mr3408110f8f.3.1771421250891; Wed, 18 Feb 2026 05:27:30 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 19/24] block/export: Add multi-threading interface Date: Wed, 18 Feb 2026 14:26:28 +0100 Message-ID: <20260218132633.29748-20-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421639184154100 Content-Type: text/plain; charset="utf-8" Make BlockExportType.iothread an alternate between a single-thread variant 'str' and a multi-threading variant '[str]'. In contrast to the single-thread setting, the multi-threading setting will not change the BDS's context (and so is incompatible with the fixed-iothread setting), but instead just pass a list to the export driver, with which it can do whatever it wants. Currently no export driver supports multi-threading, so they all return an error when receiving such a list. Suggested-by: Kevin Wolf Acked-by: Markus Armbruster Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- qapi/block-export.json | 36 ++++++++++++++++++--- include/block/export.h | 12 +++++-- block/export/export.c | 48 +++++++++++++++++++++++++--- block/export/fuse.c | 7 ++++ block/export/vduse-blk.c | 7 ++++ block/export/vhost-user-blk-server.c | 8 +++++ nbd/server.c | 6 ++++ 7 files changed, 113 insertions(+), 11 deletions(-) diff --git a/qapi/block-export.json b/qapi/block-export.json index 076954ef1a..160cd2e3ca 100644 --- a/qapi/block-export.json +++ b/qapi/block-export.json @@ -363,14 +363,16 @@ # to the export before completion is signalled. (since: 5.2; # default: false) # -# @iothread: The name of the iothread object where the export will -# run. The default is to use the thread currently associated with -# the block node. (since: 5.2) +# @iothread: The name(s) of one or more iothread object(s) where the +# export will run. The default is to use the thread currently +# associated with the block node. (since: 5.2; multi-threading +# since 10.1) # # @fixed-iothread: True prevents the block node from being moved to # another thread while the export is active. If true and # @iothread is given, export creation fails if the block node -# cannot be moved to the iothread. The default is false. +# cannot be moved to the iothread. Must not be true when giving +# multiple iothreads for @iothread. The default is false. # (since: 5.2) # # @allow-inactive: If true, the export allows the exported node to be @@ -387,7 +389,7 @@ 'base': { 'type': 'BlockExportType', 'id': 'str', '*fixed-iothread': 'bool', - '*iothread': 'str', + '*iothread': 'BlockExportIothreads', 'node-name': 'str', '*writable': 'bool', '*writethrough': 'bool', @@ -403,6 +405,30 @@ 'if': 'CONFIG_VDUSE_BLK_EXPORT' } } } =20 +## +# @BlockExportIothreads: +# +# Specify a single or multiple I/O threads in which to run a block +# export's I/O. +# +# @single: Run the export's I/O in the given single I/O thread. +# +# @multi: Use multi-threading across the given set of I/O threads, +# which must not be empty. Note: Passing a single I/O thread via +# this variant is still treated as multi-threading, which is +# different from using the @single variant. In particular, even +# if there only is a single I/O thread in the set, export types +# that do not support multi-threading will generally reject this +# variant, and BlockExportOptions.fixed-iothread is always +# incompatible with it. +# +# Since: 10.1 +## +{ 'alternate': 'BlockExportIothreads', + 'data': { + 'single': 'str', + 'multi': ['str'] } } + ## # @block-export-add: # diff --git a/include/block/export.h b/include/block/export.h index 4bd9531d4d..ca45da928c 100644 --- a/include/block/export.h +++ b/include/block/export.h @@ -32,8 +32,16 @@ typedef struct BlockExportDriver { /* True if the export type supports running on an inactive node */ bool supports_inactive; =20 - /* Creates and starts a new block export */ - int (*create)(BlockExport *, BlockExportOptions *, Error **); + /* + * Creates and starts a new block export. + * + * If the user passed a set of I/O threads for multi-threading, @multi= thread + * is a list of the @multithread_count corresponding contexts (freed b= y the + * caller). Note that @exp->ctx has no relation to that list. + */ + int (*create)(BlockExport *exp, BlockExportOptions *opts, + AioContext *const *multithread, size_t multithread_count, + Error **errp); =20 /* * Frees a removed block export. This function is only called after all diff --git a/block/export/export.c b/block/export/export.c index f3bbf11070..b733f269f3 100644 --- a/block/export/export.c +++ b/block/export/export.c @@ -76,16 +76,26 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Er= ror **errp) { bool fixed_iothread =3D export->has_fixed_iothread && export->fixed_io= thread; bool allow_inactive =3D export->has_allow_inactive && export->allow_in= active; + bool multithread =3D export->iothread && + export->iothread->type =3D=3D QTYPE_QLIST; const BlockExportDriver *drv; BlockExport *exp =3D NULL; BlockDriverState *bs; BlockBackend *blk =3D NULL; AioContext *ctx; + AioContext **multithread_ctxs =3D NULL; + size_t multithread_count =3D 0; uint64_t perm; int ret; =20 GLOBAL_STATE_CODE(); =20 + if (fixed_iothread && multithread) { + error_setg(errp, + "Cannot use fixed-iothread for a multi-threaded export"= ); + return NULL; + } + if (!id_wellformed(export->id)) { error_setg(errp, "Invalid block export id"); return NULL; @@ -116,14 +126,16 @@ BlockExport *blk_exp_add(BlockExportOptions *export, = Error **errp) =20 ctx =3D bdrv_get_aio_context(bs); =20 - if (export->iothread) { + /* Move the BDS to the target I/O thread, if it is a single one */ + if (export->iothread && !multithread) { + const char *iothread_id =3D export->iothread->u.single; IOThread *iothread; AioContext *new_ctx; Error **set_context_errp; =20 - iothread =3D iothread_by_id(export->iothread); + iothread =3D iothread_by_id(iothread_id); if (!iothread) { - error_setg(errp, "iothread \"%s\" not found", export->iothread= ); + error_setg(errp, "iothread \"%s\" not found", iothread_id); goto fail; } =20 @@ -137,6 +149,32 @@ BlockExport *blk_exp_add(BlockExportOptions *export, E= rror **errp) } else if (fixed_iothread) { goto fail; } + } else if (multithread) { + strList *iothread_list =3D export->iothread->u.multi; + size_t i; + + multithread_count =3D 0; + for (strList *e =3D iothread_list; e; e =3D e->next) { + multithread_count++; + } + + if (multithread_count =3D=3D 0) { + error_setg(errp, "The set of I/O threads must not be empty"); + return NULL; + } + + multithread_ctxs =3D g_new(AioContext *, multithread_count); + i =3D 0; + for (strList *e =3D iothread_list; e; e =3D e->next) { + IOThread *iothread =3D iothread_by_id(e->value); + + if (!iothread) { + error_setg(errp, "iothread \"%s\" not found", e->value); + goto fail; + } + multithread_ctxs[i++] =3D iothread_get_aio_context(iothread); + } + assert(i =3D=3D multithread_count); } =20 bdrv_graph_rdlock_main_loop(); @@ -195,7 +233,7 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Er= ror **errp) .blk =3D blk, }; =20 - ret =3D drv->create(exp, export, errp); + ret =3D drv->create(exp, export, multithread_ctxs, multithread_count, = errp); if (ret < 0) { goto fail; } @@ -203,6 +241,7 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Er= ror **errp) assert(exp->blk !=3D NULL); =20 QLIST_INSERT_HEAD(&block_exports, exp, next); + g_free(multithread_ctxs); return exp; =20 fail: @@ -214,6 +253,7 @@ fail: g_free(exp->id); g_free(exp); } + g_free(multithread_ctxs); return NULL; } =20 diff --git a/block/export/fuse.c b/block/export/fuse.c index b60affe86b..aa4f1c0307 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -260,6 +260,8 @@ static const BlockDevOps fuse_export_blk_dev_ops =3D { =20 static int fuse_export_create(BlockExport *blk_exp, BlockExportOptions *blk_exp_args, + AioContext *const *multithread, + size_t mt_count, Error **errp) { ERRP_GUARD(); /* ensure clean-up even with error_fatal */ @@ -269,6 +271,11 @@ static int fuse_export_create(BlockExport *blk_exp, =20 assert(blk_exp_args->type =3D=3D BLOCK_EXPORT_TYPE_FUSE); =20 + if (multithread) { + error_setg(errp, "FUSE export does not support multi-threading"); + return -EINVAL; + } + /* For growable and writable exports, take the RESIZE permission */ if (args->growable || blk_exp_args->writable) { uint64_t blk_perm, blk_shared_perm; diff --git a/block/export/vduse-blk.c b/block/export/vduse-blk.c index 8af13b7f0b..10dc673c56 100644 --- a/block/export/vduse-blk.c +++ b/block/export/vduse-blk.c @@ -267,6 +267,7 @@ static const BlockDevOps vduse_block_ops =3D { }; =20 static int vduse_blk_exp_create(BlockExport *exp, BlockExportOptions *opts, + AioContext *const *multithread, size_t mt_= count, Error **errp) { VduseBlkExport *vblk_exp =3D container_of(exp, VduseBlkExport, export); @@ -302,6 +303,12 @@ static int vduse_blk_exp_create(BlockExport *exp, Bloc= kExportOptions *opts, return -EINVAL; } } + + if (multithread) { + error_setg(errp, "vduse-blk export does not support multi-threadin= g"); + return -EINVAL; + } + vblk_exp->num_queues =3D num_queues; vblk_exp->handler.blk =3D exp->blk; vblk_exp->handler.serial =3D g_strdup(vblk_opts->serial ?: ""); diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user= -blk-server.c index a4d54e824f..e89422bb85 100644 --- a/block/export/vhost-user-blk-server.c +++ b/block/export/vhost-user-blk-server.c @@ -316,6 +316,7 @@ static const BlockDevOps vu_blk_dev_ops =3D { }; =20 static int vu_blk_exp_create(BlockExport *exp, BlockExportOptions *opts, + AioContext *const *multithread, size_t mt_cou= nt, Error **errp) { VuBlkExport *vexp =3D container_of(exp, VuBlkExport, export); @@ -341,6 +342,13 @@ static int vu_blk_exp_create(BlockExport *exp, BlockEx= portOptions *opts, error_setg(errp, "num-queues must be greater than 0"); return -EINVAL; } + + if (multithread) { + error_setg(errp, + "vhost-user-blk export does not support multi-threading= "); + return -EINVAL; + } + vexp->handler.blk =3D exp->blk; vexp->handler.serial =3D g_strdup("vhost_user_blk"); vexp->handler.logical_block_size =3D logical_block_size; diff --git a/nbd/server.c b/nbd/server.c index acec0487a8..620097c58c 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1795,6 +1795,7 @@ static const BlockDevOps nbd_block_ops =3D { }; =20 static int nbd_export_create(BlockExport *blk_exp, BlockExportOptions *exp= _args, + AioContext *const *multithread, size_t mt_cou= nt, Error **errp) { NBDExport *exp =3D container_of(blk_exp, NBDExport, common); @@ -1831,6 +1832,11 @@ static int nbd_export_create(BlockExport *blk_exp, B= lockExportOptions *exp_args, return -EEXIST; } =20 + if (multithread) { + error_setg(errp, "NBD export does not support multi-threading"); + return -EINVAL; + } + size =3D blk_getlength(blk); if (size < 0) { error_setg_errno(errp, -size, --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421656; cv=none; d=zohomail.com; s=zohoarc; b=XVHKGjn+Vw/nMO8MhHd85K5VXx4jvnXFDH/NfXdoSf/mqnfiwn99CD0XF82sk878/h5II0rq4b3R2/yihhrrIiWxmgP60oBxhKPntFWe3wCmGxE8ZOn35iZATG9H0lGVOYn11Y2v2KkEKFf3AdUWZukIdw/s8VvL+uGU2/HSIuo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421656; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=sNvEZCKQBML5r/dspX+6G5O18jEO5qroU9rPnlPzYk8=; b=Qkc2bCVJtIxkMPAYdABt43kLji7tBZiWL4o1ZfVtquDlWmZpsRYmTW/VpOkdTWbGkgg2fPegQmxj8X4EKHfdRbcFMVy5oac0eggXw4QT96NPJPLsbtzQC+yYQ0sOs9OhbVjTMh+Kn3BqgQuM8CHogxri6+/zZHK5SvgmRklBJik= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421656272706.7767154673605; Wed, 18 Feb 2026 05:34:16 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfv-0004Uv-8y; Wed, 18 Feb 2026 08:33:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfs-0004Tg-IU for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:33:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfq-0006Gr-6F for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:33:04 -0500 Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-190-W5f0M2MqPl-0YwikU6JvrQ-1; Wed, 18 Feb 2026 08:27:35 -0500 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-437812b8bb0so3427380f8f.3 for ; Wed, 18 Feb 2026 05:27:35 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796ac8d46sm42800451f8f.32.2026.02.18.05.27.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421581; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sNvEZCKQBML5r/dspX+6G5O18jEO5qroU9rPnlPzYk8=; b=fv90111kYsykrqv7n38ENW24g+LNcZHmK4DoHmCe5b8N6pzsAkgZQam9JDxzPFu3q2VjBL ejVTd1kzzQfT0ohk+zDpES8/6AZwrHvveAezRjYz3AcHXhHtnRgO0PtBcQcwjXI9aOdqbf irVsML3RwG5Lxwbjv9V65IzB/AGjQR0= X-MC-Unique: W5f0M2MqPl-0YwikU6JvrQ-1 X-Mimecast-MFC-AGG-ID: W5f0M2MqPl-0YwikU6JvrQ_1771421254 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421254; x=1772026054; darn=nongnu.org; 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; bh=sNvEZCKQBML5r/dspX+6G5O18jEO5qroU9rPnlPzYk8=; b=URyUR9rx3NzPOkIT1chhZgt1JJn1AEuXlgJaUUW3mTHEharwQfEmGNt3UiKKhC+FEU QAxguTq3qjVYcv94223krUYFqMbZE7ivDnIqO4v15/NvVnln6bJSkAR26PogGbdUnLrU MQtuhsE7XVtga6aBJa/evyS/Ylkvjd7nEYs4On1Ufivx1UIbVL/PzelKHWePNpT3U/DL 3eT7NfvzSlbQn075eqsPp1WTXq/VrbwKMwrbhNLg3A0WpVTSo+1Yyextw3bFkbE1biby 4SVsudHOwagtXnNgQQiTYwmtf4u4qwGy6WcW2QYp/aenXfCCQ5m8bCW60aH270mihrsq jVlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421254; x=1772026054; 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; bh=sNvEZCKQBML5r/dspX+6G5O18jEO5qroU9rPnlPzYk8=; b=cZhqr7wobwMBnx/nG6BP3UJO2VPm97SsseIlc3E6hq45GejYOynti8H6h5mZQM+1G4 XsF74GJFnR+I1kpqR/kKmZUx8a+neMffAOExa6K1aIddZCEA4JT13UOzGv2f3TUi32Cb r+YLxQMJTSsw0/e+MNlEfNwOtGBME7JmsHBgFpYUWiDysMMYdy4S9lTkHl3+GoIsouTx 5ykAdsMDn2EkjO4kqJAacykpIVqer/k0RAqaFvRFrA9/Mcx9xYq55kTBV2B+CeehSZny 02VV//9SyHQzi+O+/RMKpTu7jsQj+RQESXwxf3nxfmJx+kkLytziWzer67HNekxbv1Tr DF3Q== X-Gm-Message-State: AOJu0YykRvrz2ryPXh5TEBHjhuOP3s3O7huX3SLfcKOmWYEPRCiGlhKo /YfzSM5cCLBOlfB3fFitiGqecvM0qUnyIjLrpp+8eXpCmTFtmMsSDrGxrZ9NuQ0pU7PRmOUYDDI zZwn7v58Ga7UK8008AfkAUgxMD+XXDig9/nh+uM8j48Bq2noCXNAeoZ8k X-Gm-Gg: AZuq6aLXjOUeMAPILBqyhI0IRaY6bvE8DYAZvAO3lDP0Fy+j/2v6zmA+/I8yMKbSb3L WXpuV0YiE3f9L+cLjBOR4oChZvrsAL9CXbgzQ35LvglovlrEht9wAeF+EMmDyW/FnTzfyuoWS2z BI8dnLCS6OuQ1AWJintnmXR7CoTLmPXZjkAHvJ5AEKhT5u00fbvG8kzRqY+hWz0f4uhWEWz4nQD +YSCXN6gdf/7xWu0SSYGp3oICAE0fhIEnNJL2hk7w0M/BrFxezuU+FXoKEyEEIc12TqiSzI1zlH YGChuAba6/mlJZ1g9UzeS1fMK9fNpmj/R2xQbJX0EFBhGIMHJ6jpv5e2YEuoFNiKyI5xIkedI4i E/OQAgP+XPxGyOCiY5Rb0SEA5tLQD+qTkJZPl75prrIynUOoX6GWQzNhYRjGZcUHVAt9bcgM81p MHiHQC X-Received: by 2002:a05:6000:2482:b0:432:586f:2a9d with SMTP id ffacd0b85a97d-43958e3bdffmr3519284f8f.32.1771421254216; Wed, 18 Feb 2026 05:27:34 -0800 (PST) X-Received: by 2002:a05:6000:2482:b0:432:586f:2a9d with SMTP id ffacd0b85a97d-43958e3bdffmr3519217f8f.32.1771421253744; Wed, 18 Feb 2026 05:27:33 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 20/24] iotests/307: Test multi-thread export interface Date: Wed, 18 Feb 2026 14:26:29 +0100 Message-ID: <20260218132633.29748-21-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421662614158500 Content-Type: text/plain; charset="utf-8" Test the QAPI interface for multi-threaded exports. None of our exports currently support multi-threading, so it's always an error in the end, but we can still test the specific errors. Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- tests/qemu-iotests/307 | 47 ++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/307.out | 18 +++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/tests/qemu-iotests/307 b/tests/qemu-iotests/307 index b429b5aa50..f6ee3ebec0 100755 --- a/tests/qemu-iotests/307 +++ b/tests/qemu-iotests/307 @@ -142,5 +142,52 @@ with iotests.FilePath('image') as img, \ vm.qmp_log('query-block-exports') iotests.qemu_nbd_list_log('-k', socket) =20 + iotests.log('\n=3D=3D=3D Using multi-thread with NBD =3D=3D=3D') + + # Actual multi-threading; (currently) not supported by NBD + vm.qmp_log('block-export-add', + id=3D'export0', + type=3D'nbd', + node_name=3D'fmt', + iothread=3D['iothread0', 'iothread1']) + + # Should be treated the same way as actual multi-threading, even if th= ere's + # only a single thread + vm.qmp_log('block-export-add', + id=3D'export0', + type=3D'nbd', + node_name=3D'fmt', + iothread=3D['iothread0']) + + iotests.log('\n=3D=3D=3D Empty thread list') + + # Simply not allowed + vm.qmp_log('block-export-add', + id=3D'export0', + type=3D'nbd', + node_name=3D'fmt', + iothread=3D[]) + + iotests.log('\n=3D=3D=3D Non-existent thread name in list') + + # Expect an error, even if NBD does not support multi-threading, becau= se the + # list is parsed before being passed to NBD + vm.qmp_log('block-export-add', + id=3D'export0', + type=3D'nbd', + node_name=3D'fmt', + iothread=3D['iothread0', 'nothread', 'iothread1']) + + iotests.log('\n=3D=3D=3D Multi-thread with fixed-iothread') + + # With multi-threading, there is no single context to give the BDS, so= it is + # just left where it is. fixed-iothread does not make sense then. + vm.qmp_log('block-export-add', + id=3D'export0', + type=3D'nbd', + node_name=3D'fmt', + iothread=3D['iothread0', 'iothread1'], + fixed_iothread=3DTrue) + iotests.log('\n=3D=3D=3D Shut down QEMU =3D=3D=3D') vm.shutdown() diff --git a/tests/qemu-iotests/307.out b/tests/qemu-iotests/307.out index f645f3315f..a9b37d3ac1 100644 --- a/tests/qemu-iotests/307.out +++ b/tests/qemu-iotests/307.out @@ -134,4 +134,22 @@ read failed: Input/output error exports available: 0 =20 =20 +=3D=3D=3D Using multi-thread with NBD =3D=3D=3D +{"execute": "block-export-add", "arguments": {"id": "export0", "iothread":= ["iothread0", "iothread1"], "node-name": "fmt", "type": "nbd"}} +{"error": {"class": "GenericError", "desc": "NBD export does not support m= ulti-threading"}} +{"execute": "block-export-add", "arguments": {"id": "export0", "iothread":= ["iothread0"], "node-name": "fmt", "type": "nbd"}} +{"error": {"class": "GenericError", "desc": "NBD export does not support m= ulti-threading"}} + +=3D=3D=3D Empty thread list +{"execute": "block-export-add", "arguments": {"id": "export0", "iothread":= [], "node-name": "fmt", "type": "nbd"}} +{"error": {"class": "GenericError", "desc": "The set of I/O threads must n= ot be empty"}} + +=3D=3D=3D Non-existent thread name in list +{"execute": "block-export-add", "arguments": {"id": "export0", "iothread":= ["iothread0", "nothread", "iothread1"], "node-name": "fmt", "type": "nbd"}} +{"error": {"class": "GenericError", "desc": "iothread \"nothread\" not fou= nd"}} + +=3D=3D=3D Multi-thread with fixed-iothread +{"execute": "block-export-add", "arguments": {"fixed-iothread": true, "id"= : "export0", "iothread": ["iothread0", "iothread1"], "node-name": "fmt", "t= ype": "nbd"}} +{"error": {"class": "GenericError", "desc": "Cannot use fixed-iothread for= a multi-threaded export"}} + =3D=3D=3D Shut down QEMU =3D=3D=3D --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421726; cv=none; d=zohomail.com; s=zohoarc; b=NpQf1vEaE/e4hgCh1JSILecrKzaJUMxRnq4kAxPP5FV1B+oGQKnv2qyY9wK/vayrg9/rj/6WeR7wCor/YMn24/4wzlLUMVL67SkAxkci0qc0Rsdptapu4gTFtykYLuaog7oZfB0w4P7daeexYeIsGHsXj9BBFYx2YcoMpPreBLw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421726; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=eC1GpsxsI4aDAAkTkGGQOGTuPmmj07fAx5eTswWosPE=; b=fe42MIb97mZlqy8GBIWLUFKUDkFciOKc6rg4zatwEJcihtIT1eNZ3qx1NrbwZFP0Z5V4vZDkVn//uiY9XSMC4wFxUydAusYNZOErQsj6RK54UzPl8xn71nefp7IvwdMEyO1wDfxLSZoJe4H8GuRZUw4nrjm++RA3Mnq+mKOKHPg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421726909237.94043098470001; Wed, 18 Feb 2026 05:35:26 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfl-0004Od-Kx; Wed, 18 Feb 2026 08:32:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfh-0004Hw-3E for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:53 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfa-00064w-0p for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:52 -0500 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-590-A9ZZAotrOOORghMIuIAPWA-1; Wed, 18 Feb 2026 08:27:38 -0500 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4837f288194so42109955e9.2 for ; Wed, 18 Feb 2026 05:27:37 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48370ac3564sm362444415e9.5.2026.02.18.05.27.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421565; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eC1GpsxsI4aDAAkTkGGQOGTuPmmj07fAx5eTswWosPE=; b=OlGT7XtUsRNEtvKfd2F/5rDRX1GO+rdKGkh/q9p2VesNCjAMc8wiBMcZQQQn/gRsnHZRVH TO9OaW5ozcS1FcjwLatoPUn06bgJQOxouoT4gIDSZDmUWMDTVyiHv5H7XKUfxaWbQIGTqR ELNZHakvs2XXRX+1KylXBFG2zwmZkiw= X-MC-Unique: A9ZZAotrOOORghMIuIAPWA-1 X-Mimecast-MFC-AGG-ID: A9ZZAotrOOORghMIuIAPWA_1771421257 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421257; x=1772026057; darn=nongnu.org; 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; bh=eC1GpsxsI4aDAAkTkGGQOGTuPmmj07fAx5eTswWosPE=; b=stytBGEO65PwvMt2foNCp+nVnTiADfmkjdav+su3jB0OdCqoumzr0/u7KeDaMvMHwf 3l2+FitUfbDdrsjewzkmqPjs7/YdffnP9Ao76YcQSBpXeAa0BaWTCZDi+n8AzFa9NKYA YmhGq/OxhUnc2phke2h5MwwdVirRCi1Q2KcIRLTkqXcbBE7d+H6N6enVrqa0GEGx8C5U kWsFiFhqC75ys9k47qJeuSbagHdnDdkIIiiJHG/UA6IgazGBA1uhojIlR39bbxvtBcp5 GCUYQyCT86SGE0txYuOIgW9WdfWkOMS3wuiSr3airaOy0vtStoKwZeC3BwV6OFQSXOf9 R6oA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421257; x=1772026057; 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; bh=eC1GpsxsI4aDAAkTkGGQOGTuPmmj07fAx5eTswWosPE=; b=LUkSGu3wYBknwMF6g79GpfVeFZCG9uky/ha1CDN1XrgI7wSsYX8ofpxQl9mzw96SRC sVZXaokm3L4cdl8Du4ktOUaiE7QRAH6FQJGD+TGnaxNaa+7ZotFD/WKP3l9TN/7ovjaz MiEoVimrrS1JV/HumXrlGHASEeYiKohnIN/HhGYL95dTXnm4gQ3dKf5HBmq/YEjmHB/f IGqS8xccs0Uq1Vaa+BjVUB/bbc9UIHzpqGmvuvWjnaSKSjfuQ7KlqLTMKQRflo2Bqz+q 3c6TOZ5o2oZObQUheXuoxJkVmZt7jxh3LDvAGt3IYCrtRjrlNgEeW2bqgR1+wIJQWVep EX3g== X-Gm-Message-State: AOJu0YxtjjTfp8g87JsK4/tNW4/Nr9E7j5YT3UOmaV/Cd+O8vYT8ZPjF Ghnf7MaD9jLIOv27NFqwY8XlT0sCmVfsTebrttaGBs8aC0AbRTWL38pWDfnwRYIiuYwvbJxPlYa zMULVwx99MQE3923v7OQh4kO5WZJICeeWEzGV2UzQVaAIJqtCY8TbmNiS X-Gm-Gg: AZuq6aKyGW8g+crMaCSXj1uLih6jwhGNjYTHCHwiITjdzaN1hVXSBvaK4hseMYo6oVT rQbRPfYP1C5gkjlwIza9Jemd0p4g06JHzFdguqx1ORdfqFLWqaFS6VQFk/1uhfNKA81EQvpqvB6 wQ0TbjNe2LgmsJADgJL8tGVW17qNqwB3Nax+a12vix3wTKPluxly2HbxP1VoQnGfwOs5B9BKWI5 SDkEfIYw/WnsoN02v8NN7obuLnTwyU9J1W8ilwz7WG8vzhebdXe0IeceuXBEuRshsDDbtxeZiQX EVuZH/1kBDQG08JL6ILX1umnUTSELbvezjfeRswr15JjpgHKtdkYOZcKzqZk5Q4jmUIZpTMNkb+ xdK6wzbfOhHb+9k0SQcCjPSUrl0rxndMPvLMw1xWIAk9whmkBt7L41mSq1W8B07rr9eVJVVG1Ao ZaKG7N X-Received: by 2002:a05:600c:620d:b0:480:3bba:1cac with SMTP id 5b1f17b1804b1-48371043046mr263552445e9.6.1771421256833; Wed, 18 Feb 2026 05:27:36 -0800 (PST) X-Received: by 2002:a05:600c:620d:b0:480:3bba:1cac with SMTP id 5b1f17b1804b1-48371043046mr263552055e9.6.1771421256341; Wed, 18 Feb 2026 05:27:36 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 21/24] fuse: Make shared export state atomic Date: Wed, 18 Feb 2026 14:26:30 +0100 Message-ID: <20260218132633.29748-22-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421728862158500 Content-Type: text/plain; charset="utf-8" The next commit is going to allow multi-threaded access to a FUSE export. In order to allow safe concurrent SETATTR operations that can modify the shared st_mode, st_uid, and st_gid, make any access to those fields atomic operations. Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index aa4f1c0307..162cbdacfc 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -157,6 +157,7 @@ typedef struct FuseExport { /* Whether allow_other was used as a mount option or not */ bool allow_other; =20 + /* All atomic */ mode_t st_mode; uid_t st_uid; gid_t st_gid; @@ -267,6 +268,7 @@ static int fuse_export_create(BlockExport *blk_exp, ERRP_GUARD(); /* ensure clean-up even with error_fatal */ FuseExport *exp =3D container_of(blk_exp, FuseExport, common); BlockExportOptionsFuse *args =3D &blk_exp_args->u.fuse; + uint32_t st_mode; int ret; =20 assert(blk_exp_args->type =3D=3D BLOCK_EXPORT_TYPE_FUSE); @@ -335,12 +337,13 @@ static int fuse_export_create(BlockExport *blk_exp, args->allow_other =3D FUSE_EXPORT_ALLOW_OTHER_AUTO; } =20 - exp->st_mode =3D S_IFREG | S_IRUSR; + st_mode =3D S_IFREG | S_IRUSR; if (exp->writable) { - exp->st_mode |=3D S_IWUSR; + st_mode |=3D S_IWUSR; } - exp->st_uid =3D getuid(); - exp->st_gid =3D getgid(); + qatomic_set(&exp->st_mode, st_mode); + qatomic_set(&exp->st_uid, getuid()); + qatomic_set(&exp->st_gid, getgid()); =20 if (args->allow_other =3D=3D FUSE_EXPORT_ALLOW_OTHER_AUTO) { /* Try allow_other =3D=3D true first, ignore errors */ @@ -818,10 +821,10 @@ fuse_co_getattr(FuseExport *exp, struct fuse_attr_out= *out) .attr_valid =3D 1, .attr =3D { .ino =3D 1, - .mode =3D exp->st_mode, + .mode =3D qatomic_read(&exp->st_mode), .nlink =3D 1, - .uid =3D exp->st_uid, - .gid =3D exp->st_gid, + .uid =3D qatomic_read(&exp->st_uid), + .gid =3D qatomic_read(&exp->st_gid), .size =3D length, .blksize =3D blk_bs(exp->common.blk)->bl.request_alignment, .blocks =3D allocated_blocks, @@ -934,15 +937,15 @@ fuse_co_setattr(FuseExport *exp, struct fuse_attr_out= *out, uint32_t to_set, =20 if (to_set & FATTR_MODE) { /* Ignore FUSE-supplied file type, only change the mode */ - exp->st_mode =3D (mode & 07777) | S_IFREG; + qatomic_set(&exp->st_mode, (mode & 07777) | S_IFREG); } =20 if (to_set & FATTR_UID) { - exp->st_uid =3D uid; + qatomic_set(&exp->st_uid, uid); } =20 if (to_set & FATTR_GID) { - exp->st_gid =3D gid; + qatomic_set(&exp->st_gid, gid); } =20 return fuse_co_getattr(exp, out); --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421704; cv=none; d=zohomail.com; s=zohoarc; b=JGF1L3T8vkwzHsARlYjp832FQdKqMI5ManGK6K89zgHMrWgIxdav3kBP/AEy2yfNIqN1YPnD5IM3ApbVa7NDWLw4fvAVHRwe29xgED3AxhBOs1X4c6QUwBUSvenFWL7RrbyJYG6V8VXfTCR7GN6xwJnr6ASR86v5DF7xAIjG330= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421704; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=IxNqYftpopQBXsxGyECaF4EaTK+LIZo8y+vscZHFzIE=; b=l/+E0Xu/gjNR8BtW3W75v8KOfYLuyUA//KOYEBU1CQVGvT3pUtsR3st+CiH77zfzX/cp9L6/evPN93sSEdbZb/NZv/5EH9gQ5rQNnQSxaO5pfkit1XZ5GWJpm/j3K6jd+qjfW7JNvjCuSlVxxyx0g5Jv+ejQechgglWD8t5GTLk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421704710463.56832602453346; Wed, 18 Feb 2026 05:35:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshgK-0004to-Ne; Wed, 18 Feb 2026 08:33:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshft-0004U2-Ai for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:33:06 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfp-0006Gl-PS for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:33:05 -0500 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-263-HN-KJNKLOa64_eZtGyg8fw-1; Wed, 18 Feb 2026 08:27:40 -0500 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4837bfcfe0dso30014165e9.1 for ; Wed, 18 Feb 2026 05:27:40 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-483801ff9b3sm303123835e9.13.2026.02.18.05.27.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421581; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IxNqYftpopQBXsxGyECaF4EaTK+LIZo8y+vscZHFzIE=; b=JUDLrBPMT6GLHgxiqGG6TC/lURdmPkfx/19Jk8AjHPQqayEXVhJ4JptI6dkqylZ7u9dTbf YNj9ZmD0zNg9PdkGHEMEyw2YE220VBkdx1EHoz7BbAq3D1fYrjrZDd/0Qt7ekAtTTO19Ov /HvOyrQeYITYF0zV5sFDsNxVkbSWY7Q= X-MC-Unique: HN-KJNKLOa64_eZtGyg8fw-1 X-Mimecast-MFC-AGG-ID: HN-KJNKLOa64_eZtGyg8fw_1771421260 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421259; x=1772026059; darn=nongnu.org; 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; bh=IxNqYftpopQBXsxGyECaF4EaTK+LIZo8y+vscZHFzIE=; b=tlZhqthQYBiijLh535hMEm9HsrD+UBxHZ5qTRhgEjQgIJO1f1i9tX62g9vv3okS/AK q4cwt9aBleXQvG42M6OJtfCKFvVHouKs50bCSvZ7VzWj/Y94zO0guhB0awXyWAUN0wGR acvVfYFbPrONUy2MEzRWpOp15zt5IvpauaS02+MGrf9M0RaP1Se3mwnL7PFO30svckBl gjJvdJgF/mTolPAMU/jirxNhxROf7m0DEHVErz5z6dkUf3LDE0BNvl0dDiKbTDO6IvGF PZPIm0xilI0399NBv5+m1qZnMkqIsW7SedngC09owlJQZrGcFhpKoe1zktrc4GLF46lf T/gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421259; x=1772026059; 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; bh=IxNqYftpopQBXsxGyECaF4EaTK+LIZo8y+vscZHFzIE=; b=r37SnunEqXraDHm5s3ZDs8ztJdfLXeuxsXL7hJghbXQkyTiFugNVd/XHgoCbPNLQ/L nOnn0S0bF5ZHA1P0Z1zCv4tKy3V09WFKgf79G3zBmnjLsU0xt3eWnbg4Io618xk+dRvE 25bYvUNrV3CCmdRN6h7f8ltypyK7TpwP9KAN86Jj0rPd+pOEA32MpTWWGm76COcVhtY9 FPfnbrIaPzRVzgAwSoz/dZRyGAGIJVzbB67quzuDfFQ+UKNaiB1Bgihd9CAn3BIL8fGy dyDHeBSckvb6wI6LCXzrnFbuTouAR+E3fZD0nFKKmd3scNJK6EMaELYORog1Y/d6YMtA Woeg== X-Gm-Message-State: AOJu0Yyl7IdFHwxd5gGcgdL8F7ZCYCtkTMliOE85svXyC1q0sWhCUin/ 7SF1YbFn0GIMPiDHYINeGiNGsLC5P4gXWKLunhqCkB4owvWMHF/ax+ea3VZamU9FiP4XyfleHUe xGXvPwU7nWHxALgvruOcf0vHVbZqiox1XDGrINevgjbUeslZ7bzxx+CPu X-Gm-Gg: AZuq6aK3y3cXrGxWYblmWNB1R5/2fb22vd2dF4IMsKAX8/eAtAJKIS4E+YMO0YkRIxZ 8kvHKUUY7KX51gGrJhERWc8CZAsIW+R1MVQYC49ucmhulsbcO5no84WiTk3GL/lK0BhQDfW22KW pAh6aF7HD8W2q1TvcU5ezB9xI3UuLyOWS6ZqA1F0Tw9xnsC8z4SY8BLn9ZDLYeqjw2O2m6YkFL1 Ui8Sia4QbYwYKToExXeknSxKMJRWMKYcpfn8//WyixSjaGJ5v1VCKUqtQvgPIWB8FemfeNbEcS+ NDi0OVXITvsZAgGTBBDd3vhuWoOjaXdZmKvvJm/KA/iXJFyUZwpaoMAyKz9YJ3+JZvdT6c8braA sbHbEDIXIProl1sDxkAPqblQCqswLNdR4ILErQbEgqnldCPoR92B1OfNfHwDuNqGCYav2eSlid2 08BtdT X-Received: by 2002:a05:600c:820d:b0:47d:403e:4eaf with SMTP id 5b1f17b1804b1-48379b9f278mr267766085e9.10.1771421259331; Wed, 18 Feb 2026 05:27:39 -0800 (PST) X-Received: by 2002:a05:600c:820d:b0:47d:403e:4eaf with SMTP id 5b1f17b1804b1-48379b9f278mr267765525e9.10.1771421258675; Wed, 18 Feb 2026 05:27:38 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 22/24] fuse: Implement multi-threading Date: Wed, 18 Feb 2026 14:26:31 +0100 Message-ID: <20260218132633.29748-23-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421705970154100 FUSE allows creating multiple request queues by "cloning" /dev/fuse FDs (via open("/dev/fuse") + ioctl(FUSE_DEV_IOC_CLONE)). We can use this to implement multi-threading. For configuration, we don't need any more information beyond the simple array provided by the core block export interface: The FUSE kernel driver feeds these FDs in a round-robin fashion, so all of them are equivalent and we want to have exactly one per thread. These are the benchmark results when using four threads (compared to a single thread); note that fio still only uses a single job, but performance can still be improved because of said round-robin usage for the queues. (Not in the sync case, though, in which case I guess it just adds overhead.) file: read: seq aio: 261.7k =C2=B11.7k (+168%) rand aio: 129.2k =C2=B114.3k (+35%) seq sync: 36.6k =C2=B10.6k (+6%) rand sync: 10.1k =C2=B10.1k (+2%) write: seq aio: 235.7k =C2=B12.8k (+243%) rand aio: 232.0k =C2=B16.7k (+237%) seq sync: 31.7k =C2=B10.6k (+4%) rand sync: 31.8k =C2=B10.5k (+4%) null: read: seq aio: 253.8k =C2=B112.3k (+45%) rand aio: 248.2k =C2=B112.0k (+45%) seq sync: 91.6k =C2=B12.4k (+12%) rand sync: 91.3k =C2=B12.1k (+17%) write: seq aio: 208.2k =C2=B19.8k (+6%) rand aio: 207.0k =C2=B17.4k (+8%) seq sync: 91.2k =C2=B11.9k (+9%) rand sync: 90.4k =C2=B12.5k (+14%) So moderate improvements in most cases, but quite improved AIO performance with an actual underlying file. Here's results for numjobs=3D4: "Before", i.e. without multithreading in QSD/FUSE (results compared to numjobs=3D1): file: read: seq aio: 85.5k =C2=B10.4k (-13%) rand aio: 92.5k =C2=B10.5k (-3%) seq sync: 54.5k =C2=B19.1k (+58%) rand sync: 38.0k =C2=B10.2k (+283%) write: seq aio: 67.3k =C2=B10.3k (-2%) rand aio: 67.6k =C2=B10.3k (-2%) seq sync: 69.3k =C2=B10.5k (+126%) rand sync: 69.3k =C2=B10.3k (+126%) null: read: seq aio: 170.6k =C2=B10.8k (-2%) rand aio: 170.9k =C2=B10.9k (=C2=B10%) seq sync: 187.6k =C2=B11.3k (+129%) rand sync: 188.9k =C2=B10.9k (+142%) write: seq aio: 191.5k =C2=B11.2k (-2%) rand aio: 193.8k =C2=B11.4k (-1%) seq sync: 206.1k =C2=B11.3k (+147%) rand sync: 206.1k =C2=B11.2k (+159%) As probably expected, little difference in the AIO case, but great improvements in the sync cases because it kind of gives it an artificial iodepth of 4. "After", i.e. with four threads in QSD/FUSE (now results compared to the above): file: read: seq aio: 198.7k =C2=B12.7k (+132%) rand aio: 317.3k =C2=B10.6k (+243%) seq sync: 55.9k =C2=B18.9k (+3%) rand sync: 39.1k =C2=B10.0k (+3%) write: seq aio: 229.0k =C2=B10.8k (+240%) rand aio: 227.0k =C2=B11.3k (+235%) seq sync: 102.5k =C2=B10.2k (+48%) rand sync: 101.7k =C2=B10.2k (+47%) null: read: seq aio: 584.0k =C2=B11.5k (+242%) rand aio: 581.9k =C2=B11.9k (+240%) seq sync: 270.6k =C2=B10.9k (+44%) rand sync: 270.4k =C2=B10.7k (+43%) write: seq aio: 598.4k =C2=B12.0k (+212%) rand aio: 605.2k =C2=B12.0k (+212%) seq sync: 274.0k =C2=B10.8k (+33%) rand sync: 275.0k =C2=B10.7k (+33%) So this helps mainly for the AIO cases, but also in the null sync cases, because null is always CPU-bound, so more threads help. One unsolved mystery: When using a multithreaded export, running fio with 1 job (benchmark at the top of this commit) yields better seqread performance than doing so with 4 jobs. Actually, with 4 jobs, it's significantly than randread, which is quite strange. Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- block/export/fuse.c | 193 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 153 insertions(+), 40 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index 162cbdacfc..6777a7651b 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -31,11 +31,13 @@ #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "system/block-backend.h" +#include "system/iothread.h" =20 #include #include =20 #include "standard-headers/linux/fuse.h" +#include =20 #if defined(CONFIG_FALLOCATE_ZERO_RANGE) #include @@ -119,12 +121,17 @@ QEMU_BUILD_BUG_ON(sizeof(((FuseRequestInHeaderBuf *)0= )->head) + sizeof(((FuseRequestInHeaderBuf *)0)->tail) !=3D sizeof(FuseRequestInHeader)); =20 -typedef struct FuseExport { - BlockExport common; +typedef struct FuseExport FuseExport; =20 - struct fuse_session *fuse_session; - unsigned int in_flight; /* atomic */ - bool mounted, fd_handler_set_up; +/* + * One FUSE "queue", representing one FUSE FD from which requests are fetc= hed + * and processed. Each queue is tied to an AioContext. + */ +typedef struct FuseQueue { + FuseExport *exp; + + AioContext *ctx; + int fuse_fd; =20 /* * Cached buffer to receive the data of WRITE requests. Cached becaus= e: @@ -141,6 +148,14 @@ typedef struct FuseExport { * via blk_blockalign() and thus need to be freed via qemu_vfree(). */ void *req_write_data_cached; +} FuseQueue; + +struct FuseExport { + BlockExport common; + + struct fuse_session *fuse_session; + unsigned int in_flight; /* atomic */ + bool mounted, fd_handler_set_up; =20 /* * Set when there was an unrecoverable error and no requests should be= read @@ -149,7 +164,15 @@ typedef struct FuseExport { */ bool halted; =20 - int fuse_fd; + int num_queues; + FuseQueue *queues; + /* + * True if this export should follow the generic export's AioContext. + * Will be false if the queues' AioContexts have been explicitly set b= y the + * user, i.e. are expected to stay in those contexts. + * (I.e. is always false if there is more than one queue.) + */ + bool follow_aio_context; =20 char *mountpoint; bool writable; @@ -161,7 +184,7 @@ typedef struct FuseExport { mode_t st_mode; uid_t st_uid; gid_t st_gid; -} FuseExport; +}; =20 /* * Verify that the size of FuseRequestInHeaderBuf.head plus the data @@ -180,12 +203,13 @@ static void fuse_export_halt(FuseExport *exp); static void init_exports_table(void); =20 static int mount_fuse_export(FuseExport *exp, Error **errp); +static int clone_fuse_fd(int fd, Error **errp); =20 static bool is_regular_file(const char *path, Error **errp); =20 static void read_from_fuse_fd(void *opaque); static void coroutine_fn -fuse_co_process_request(FuseExport *exp, const FuseRequestInHeader *in_hdr, +fuse_co_process_request(FuseQueue *q, const FuseRequestInHeader *in_hdr, const void *data_buffer); static int fuse_write_err(int fd, const struct fuse_in_header *in_hdr, int= err); =20 @@ -217,8 +241,11 @@ static void fuse_attach_handlers(FuseExport *exp) return; } =20 - aio_set_fd_handler(exp->common.ctx, exp->fuse_fd, - read_from_fuse_fd, NULL, NULL, NULL, exp); + for (int i =3D 0; i < exp->num_queues; i++) { + aio_set_fd_handler(exp->queues[i].ctx, exp->queues[i].fuse_fd, + read_from_fuse_fd, NULL, NULL, NULL, + &exp->queues[i]); + } exp->fd_handler_set_up =3D true; } =20 @@ -227,8 +254,10 @@ static void fuse_attach_handlers(FuseExport *exp) */ static void fuse_detach_handlers(FuseExport *exp) { - aio_set_fd_handler(exp->common.ctx, exp->fuse_fd, - NULL, NULL, NULL, NULL, NULL); + for (int i =3D 0; i < exp->num_queues; i++) { + aio_set_fd_handler(exp->queues[i].ctx, exp->queues[i].fuse_fd, + NULL, NULL, NULL, NULL, NULL); + } exp->fd_handler_set_up =3D false; } =20 @@ -243,6 +272,11 @@ static void fuse_export_drained_end(void *opaque) =20 /* Refresh AioContext in case it changed */ exp->common.ctx =3D blk_get_aio_context(exp->common.blk); + if (exp->follow_aio_context) { + assert(exp->num_queues =3D=3D 1); + exp->queues[0].ctx =3D exp->common.ctx; + } + fuse_attach_handlers(exp); } =20 @@ -274,8 +308,32 @@ static int fuse_export_create(BlockExport *blk_exp, assert(blk_exp_args->type =3D=3D BLOCK_EXPORT_TYPE_FUSE); =20 if (multithread) { - error_setg(errp, "FUSE export does not support multi-threading"); - return -EINVAL; + /* Guaranteed by common export code */ + assert(mt_count >=3D 1); + + exp->follow_aio_context =3D false; + exp->num_queues =3D mt_count; + exp->queues =3D g_new(FuseQueue, mt_count); + + for (size_t i =3D 0; i < mt_count; i++) { + exp->queues[i] =3D (FuseQueue) { + .exp =3D exp, + .ctx =3D multithread[i], + .fuse_fd =3D -1, + }; + } + } else { + /* Guaranteed by common export code */ + assert(mt_count =3D=3D 0); + + exp->follow_aio_context =3D true; + exp->num_queues =3D 1; + exp->queues =3D g_new(FuseQueue, 1); + exp->queues[0] =3D (FuseQueue) { + .exp =3D exp, + .ctx =3D exp->common.ctx, + .fuse_fd =3D -1, + }; } =20 /* For growable and writable exports, take the RESIZE permission */ @@ -287,7 +345,7 @@ static int fuse_export_create(BlockExport *blk_exp, ret =3D blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE, blk_shared_perm, errp); if (ret < 0) { - return ret; + goto fail; } } =20 @@ -363,13 +421,23 @@ static int fuse_export_create(BlockExport *blk_exp, =20 g_hash_table_insert(exports, g_strdup(exp->mountpoint), NULL); =20 - exp->fuse_fd =3D fuse_session_fd(exp->fuse_session); - ret =3D qemu_fcntl_addfl(exp->fuse_fd, O_NONBLOCK); + assert(exp->num_queues >=3D 1); + exp->queues[0].fuse_fd =3D fuse_session_fd(exp->fuse_session); + ret =3D qemu_fcntl_addfl(exp->queues[0].fuse_fd, O_NONBLOCK); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to make FUSE FD non-blocking"= ); goto fail; } =20 + for (int i =3D 1; i < exp->num_queues; i++) { + int fd =3D clone_fuse_fd(exp->queues[0].fuse_fd, errp); + if (fd < 0) { + ret =3D fd; + goto fail; + } + exp->queues[i].fuse_fd =3D fd; + } + fuse_attach_handlers(exp); return 0; =20 @@ -462,28 +530,28 @@ fail: /** * Allocate a buffer to receive WRITE data, or take the cached one. */ -static void *get_write_data_buffer(FuseExport *exp) +static void *get_write_data_buffer(FuseQueue *q) { - if (exp->req_write_data_cached) { - void *cached =3D exp->req_write_data_cached; - exp->req_write_data_cached =3D NULL; + if (q->req_write_data_cached) { + void *cached =3D q->req_write_data_cached; + q->req_write_data_cached =3D NULL; return cached; } else { - return blk_blockalign(exp->common.blk, FUSE_MAX_WRITE_BYTES); + return blk_blockalign(q->exp->common.blk, FUSE_MAX_WRITE_BYTES); } } =20 /** * Release a WRITE data buffer, possibly reusing it for a subsequent reque= st. */ -static void release_write_data_buffer(FuseExport *exp, void **buffer) +static void release_write_data_buffer(FuseQueue *q, void **buffer) { if (!*buffer) { return; } =20 - if (!exp->req_write_data_cached) { - exp->req_write_data_cached =3D *buffer; + if (!q->req_write_data_cached) { + q->req_write_data_cached =3D *buffer; } else { qemu_vfree(*buffer); } @@ -529,9 +597,42 @@ static ssize_t req_op_hdr_len(const FuseRequestInHeade= r *in_hdr) } } =20 +/** + * Clone the given /dev/fuse file descriptor, yielding a second FD from wh= ich + * requests can be pulled for the associated filesystem. Returns an FD on + * success, and -errno on error. + */ +static int clone_fuse_fd(int fd, Error **errp) +{ + uint32_t src_fd =3D fd; + int new_fd; + int ret; + + /* + * The name "/dev/fuse" is fixed, see libfuse's lib/fuse_loop_mt.c + * (fuse_clone_chan()). + */ + new_fd =3D open("/dev/fuse", O_RDWR | O_CLOEXEC | O_NONBLOCK); + if (new_fd < 0) { + ret =3D -errno; + error_setg_errno(errp, errno, "Failed to open /dev/fuse"); + return ret; + } + + ret =3D ioctl(new_fd, FUSE_DEV_IOC_CLONE, &src_fd); + if (ret < 0) { + ret =3D -errno; + error_setg_errno(errp, errno, "Failed to clone FUSE FD"); + close(new_fd); + return ret; + } + + return new_fd; +} + /** * Try to read a single request from the FUSE FD. - * Takes a FuseExport pointer in `opaque`. + * Takes a FuseQueue pointer in `opaque`. * * Assumes the export's in-flight counter has already been incremented. * @@ -539,8 +640,9 @@ static ssize_t req_op_hdr_len(const FuseRequestInHeader= *in_hdr) */ static void coroutine_fn co_read_from_fuse_fd(void *opaque) { - FuseExport *exp =3D opaque; - int fuse_fd =3D exp->fuse_fd; + FuseQueue *q =3D opaque; + int fuse_fd =3D q->fuse_fd; + FuseExport *exp =3D q->exp; ssize_t ret; FuseRequestInHeaderBuf in_hdr_buf; const FuseRequestInHeader *in_hdr; @@ -552,7 +654,7 @@ static void coroutine_fn co_read_from_fuse_fd(void *opa= que) goto no_request; } =20 - data_buffer =3D get_write_data_buffer(exp); + data_buffer =3D get_write_data_buffer(q); =20 /* Construct the I/O vector to hold the FUSE request */ iov[0] =3D (struct iovec) { &in_hdr_buf.head, sizeof(in_hdr_buf.head) = }; @@ -613,29 +715,29 @@ static void coroutine_fn co_read_from_fuse_fd(void *o= paque) memcpy(in_hdr_buf.tail, data_buffer, len); } =20 - release_write_data_buffer(exp, &data_buffer); + release_write_data_buffer(q, &data_buffer); } =20 - fuse_co_process_request(exp, in_hdr, data_buffer); + fuse_co_process_request(q, in_hdr, data_buffer); =20 no_request: - release_write_data_buffer(exp, &data_buffer); + release_write_data_buffer(q, &data_buffer); fuse_dec_in_flight(exp); } =20 /** * Try to read and process a single request from the FUSE FD. * (To be used as a handler for when the FUSE FD becomes readable.) - * Takes a FuseExport pointer in `opaque`. + * Takes a FuseQueue pointer in `opaque`. */ static void read_from_fuse_fd(void *opaque) { - FuseExport *exp =3D opaque; + FuseQueue *q =3D opaque; Coroutine *co; =20 - co =3D qemu_coroutine_create(co_read_from_fuse_fd, exp); + co =3D qemu_coroutine_create(co_read_from_fuse_fd, q); /* Decremented by co_read_from_fuse_fd() */ - fuse_inc_in_flight(exp); + fuse_inc_in_flight(q->exp); qemu_coroutine_enter(co); } =20 @@ -660,6 +762,17 @@ static void fuse_export_delete(BlockExport *blk_exp) { FuseExport *exp =3D container_of(blk_exp, FuseExport, common); =20 + for (int i =3D 0; i < exp->num_queues; i++) { + FuseQueue *q =3D &exp->queues[i]; + + /* Queue 0's FD belongs to the FUSE session */ + if (i > 0 && q->fuse_fd >=3D 0) { + close(q->fuse_fd); + } + qemu_vfree(q->req_write_data_cached); + } + g_free(exp->queues); + if (exp->fuse_session) { if (exp->mounted) { fuse_session_unmount(exp->fuse_session); @@ -668,7 +781,6 @@ static void fuse_export_delete(BlockExport *blk_exp) fuse_session_destroy(exp->fuse_session); } =20 - qemu_vfree(exp->req_write_data_cached); g_free(exp->mountpoint); } =20 @@ -1373,10 +1485,11 @@ static int fuse_write_buf_response(int fd, * Process a FUSE request, incl. writing the response. */ static void coroutine_fn -fuse_co_process_request(FuseExport *exp, const FuseRequestInHeader *in_hdr, +fuse_co_process_request(FuseQueue *q, const FuseRequestInHeader *in_hdr, const void *data_buffer) { FuseRequestOutHeader out_hdr; + FuseExport *exp =3D q->exp; /* For read requests: Data to be returned */ void *out_data_buffer =3D NULL; ssize_t ret; @@ -1498,10 +1611,10 @@ fuse_co_process_request(FuseExport *exp, const Fuse= RequestInHeader *in_hdr, } =20 if (out_data_buffer) { - fuse_write_buf_response(exp->fuse_fd, &out_hdr.common, out_data_bu= ffer); + fuse_write_buf_response(q->fuse_fd, &out_hdr.common, out_data_buff= er); qemu_vfree(out_data_buffer); } else { - fuse_write_response(exp->fuse_fd, &out_hdr); + fuse_write_response(q->fuse_fd, &out_hdr); } } =20 --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421813; cv=none; d=zohomail.com; s=zohoarc; b=UMGei+JYSvbLeA90Dzni4dKRnRgNs5Gs5ucU38DsyvIfD+wGkM5twPvlXVumUFxBma1czW2+ZQrb/N62tY+DiJlEFHYvW9tSaNAR2UxdxcXZq5IBj+SezyK0nZFf1EdVQJOMkZrLtMIMCIdK97jkRHMVXDMLOuFdDV4Yjjvh8d4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421813; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/nvY+FQXOEd7mADtviTKG5X4XDtAjCV+MockVMSjqaI=; b=fLw1NxWGQjpHGwk7sszyDgJ05ALoMACAOp2QO5gdgKWRXXxuhDekA4SLhjQ6GpGSrC6I9gspVG96dSYMe+5/aReiLOacJJia6A5azDEHanQH4P3MOcP7iLTWZs6g0T3Vq2zi07/WfV6XLEDTyttacUJDjJbUHUWLaXmnapxdXGg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421813777683.2118268164435; Wed, 18 Feb 2026 05:36:53 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshgc-0005E4-AG; Wed, 18 Feb 2026 08:33:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshft-0004U7-ND for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:33:06 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfq-0006H5-QB for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:33:05 -0500 Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-624-WXunfzg6M0C4f8zHL_79rg-1; Wed, 18 Feb 2026 08:27:43 -0500 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-435a11575ecso5278815f8f.2 for ; Wed, 18 Feb 2026 05:27:42 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4836cd7af87sm461122755e9.1.2026.02.18.05.27.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421582; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/nvY+FQXOEd7mADtviTKG5X4XDtAjCV+MockVMSjqaI=; b=Kl8V4gA4OjTWa6G4kTPK+SqYhkRyTouhOwW6L30X17eOaVKxYtcmLMQBq66fwyWIQ8nWtd t9HYGcEFQlEnWBwPwCBnDlUfvojCBAOAX5zFOswvHIKnw2sFD/NRw1ulVhpwfm4cAKtxsD Ph2ssED9FiySQo5H6mHUk4SRd4uY7yY= X-MC-Unique: WXunfzg6M0C4f8zHL_79rg-1 X-Mimecast-MFC-AGG-ID: WXunfzg6M0C4f8zHL_79rg_1771421262 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421262; x=1772026062; darn=nongnu.org; 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; bh=/nvY+FQXOEd7mADtviTKG5X4XDtAjCV+MockVMSjqaI=; b=gGiBSUPaOBLnNRkKy3NlbR+893KG9NguU5f5bN5JNdyIfYFbfZno4ZLQB+p0rWOXII WHXg1DcRXilDykCDs4uBkLfRPotKR3dnl/0I8XNM/NNl6RMRZrhdeseYhOaHnZ71szd1 tI9l602TkAinBUCS33fAjUetGcFLubVBFAAltD0xOok74qbv6imckGBHyguaL0ST9xjp EA5aaTGLykwsa2IOAA727sRTrRPeXNUQ6bdRym14zu0qojTCU8vrvGK3ffYuso6XFwxd 6WFUtE30kPdsqyHcXs9DieeYOUZrH6AJy2x5kjhz4P93Cj+Ts86p3wZzEqJ2A3vWqHpU ipPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421262; x=1772026062; 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; bh=/nvY+FQXOEd7mADtviTKG5X4XDtAjCV+MockVMSjqaI=; b=kh1cG5qONPAvgk7yQu1dAzX62SY75F+EQy8UPwJYLmgZVYKXRMdE+w5LApVY1YQFAf MXd26B7hu/DNQkDbOmVPJbrYi3ByrSYzN3Qx0vQnmpgqasQRvCY2xerSrOf6ZB+jDEOd C2WgTdMc+Wtu8LdbEcJMFsxXlASrATg8VfAR62RP6DwxfwMtxuUip/KhSSq7SWJUtwDy 5UBemodAH3VONGfkml6bRsqrBGKa+4xND53EbQJHrr605aUQvRaYE+j6taGbuFiV94j9 QxB7kyzoVK7npbpPF2YZpXLgoVKZYC+gWjExw0pBYi7sOqkcomkBH7nzRbYMfEcZ2pQS 9+vg== X-Gm-Message-State: AOJu0YyjKkIk+pJYYCm6bbRNj83i+zFLoFLCYGYdBpDo9kgRZ/MxSXcs 78Q3W7Rpr2bRevQtnBauFD5Ny8jc22aABPeF9HdAlsw3tyRYJRSfTBaPNlbkfCOfSD/zNcDK0zT DzjYxZT/Y/JOoWivMd3YP64aSGu96vreldzTN998oMF4TQryare/YJ7aI X-Gm-Gg: AZuq6aLd6GB8O1Ezw1aDeeoAfTeGUU2/3/aZ/KcIiNbxTHO9/MlSgbL5oxoCoJF59h4 JuRrk9mTbIcg5YC9dsBq7YEHonWGlozCMtlhwquotZmSKTeKwbrJG7Hw43Tvl9EefUKcGtwPOlh xKXpY2bZZuSPX1O4gMVEogAxBYB3yA6yBoBEqk4NxtiPtfhgqZMU84jTQmedgVsEZn5dh5qEx+k 8HawRaY5BvdLPGKnSwKgmGgAtKHgdEA99ngsFFHvC0h95qm2KLGexog0kr6o4+/iW3mJwXrvmw+ C32fxg+s9iLZQpzQBMoa1ielNUaqjUesGzvZNm1Ulv4SdkmK/+SsJpzp1WW/seS+BvC+VPzbUQ0 ZsTc3PngOirLeiedJNRcwsEnpiIWoKA0m9O+EuSiQU5lU/B0KbmmwWzYl64QJ6CG7e5HQA0c79E x9/AsS X-Received: by 2002:a5d:584d:0:b0:437:8f37:887 with SMTP id ffacd0b85a97d-43958e40404mr3159047f8f.36.1771421261774; Wed, 18 Feb 2026 05:27:41 -0800 (PST) X-Received: by 2002:a5d:584d:0:b0:437:8f37:887 with SMTP id ffacd0b85a97d-43958e40404mr3158983f8f.36.1771421261190; Wed, 18 Feb 2026 05:27:41 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 23/24] qapi/block-export: Document FUSE's multi-threading Date: Wed, 18 Feb 2026 14:26:32 +0100 Message-ID: <20260218132633.29748-24-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421815133158500 Content-Type: text/plain; charset="utf-8" Document for users that FUSE's multi-threading implementation distributes requests in a round-robin manner, regardless of where they originate from. As noted by Stefan, this will probably change with a FUSE-over-io_uring implementation (which is supposed to have CPU affinity), but documenting that is left for once that is done. Suggested-by: Stefan Hajnoczi Acked-by: Markus Armbruster Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- qapi/block-export.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qapi/block-export.json b/qapi/block-export.json index 160cd2e3ca..dd724acf1c 100644 --- a/qapi/block-export.json +++ b/qapi/block-export.json @@ -164,6 +164,11 @@ # Options for exporting a block graph node on some (file) mountpoint # as a raw image. # +# Multi-threading note: The FUSE export supports multi-threading. +# Currently, requests are distributed across these threads in a +# round-robin fashion, i.e. independently of the CPU core from which a +# request originates. +# # @mountpoint: Path on which to export the block device via FUSE. # This must point to an existing regular file. # --=20 2.53.0 From nobody Sun Apr 12 05:51:27 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1771421698; cv=none; d=zohomail.com; s=zohoarc; b=SsKifzJZ20F23LypABpiiy3Phu8PiCPF5DrjNvYnrlbSgLwkEUDyCxt0ouGAnMMFJQWRVetqu+nsvfThV/7zzJ+MQgzgsYqZ6o1gWZvTLBfDq1+OWEbapLQ4Sogi8KDCqIHLAEdX5sr8eorCyXeKHj8C8WKMrY5x1HiAdy183/0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771421698; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=V9XxWeIBv2c1tdmnmag9Jzf/vBSh0dtlPyj8GrQc20M=; b=jKsy5CSOyqVkZaIcQ0Ce7KLuU6lhTvAE9UIFgp/7UUjmkRYAsBHXe1weZUKl9KbC3xSC2pvECUCxJaPs0S2sKh31nc6ZUK0i591LR449yz1BlDH0CaI4iXkKUUSFWgnk6OOk9xFq2Bkj5+fOvuvY3uRsqkO9uv1+hzGyTtMELjg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1771421698811106.63265854485167; Wed, 18 Feb 2026 05:34:58 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vshfl-0004Or-TD; Wed, 18 Feb 2026 08:32:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfi-0004IY-Gg for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:54 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vshfg-0006FD-Pl for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:54 -0500 Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-626-UZEsV54wMe-N1uNB_beKNA-1; Wed, 18 Feb 2026 08:27:45 -0500 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-4376ecafb7fso3352010f8f.2 for ; Wed, 18 Feb 2026 05:27:45 -0800 (PST) Received: from localhost (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de. [2003:cf:d737:d029:edef:7b8d:a744:1ac2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43796acf5b9sm40227691f8f.34.2026.02.18.05.27.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 05:27:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771421572; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=V9XxWeIBv2c1tdmnmag9Jzf/vBSh0dtlPyj8GrQc20M=; b=MptuV2QkR/JnP5YfGsLv/5V4AElPD/GGJvGeXP9D5UBnKK3AALM1Iakg+MZswK+xBo6guc WvzuqCQb6CSnZuR/xfGHJ7d0rGa+16pdL20pd5BcPyqH0EDRq0Mw1aq0gTuul8vubilhbP Fqh6wX8n3nlCYegziq2k2g/F21X8AbM= X-MC-Unique: UZEsV54wMe-N1uNB_beKNA-1 X-Mimecast-MFC-AGG-ID: UZEsV54wMe-N1uNB_beKNA_1771421264 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1771421264; x=1772026064; darn=nongnu.org; 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; bh=V9XxWeIBv2c1tdmnmag9Jzf/vBSh0dtlPyj8GrQc20M=; b=FUHAJtutqMyqNDBEnE+UdP88BMDRukkR7ZC7dDnXssZnVVVenqfnld0EIdQbxTL9kE uPPzkvgl5DexmX2a89/+/MUiONQldLtDsYVKSwsU+NZjbWVxAWodfSZQBjf7l48CZpYZ hLtp7QN/OxYmedXnv0/iWUok9qt96bEPYpDxCsa87s2Ahz8/36CQRbrFgceH5mT26V9J RQs86JMpCqEhCE5dhZG3yJcu5ZI0GRrsTSkXYmsz8uqr0IqjTL9RFhBBtOgGTkpucWtS BBTC/NFSx3YpKgygkDRHdGssjOA6lMxRSQnxtBo1BwZA9hStKFO6nx6LXZfIeS5c9qp7 LoxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771421264; x=1772026064; 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; bh=V9XxWeIBv2c1tdmnmag9Jzf/vBSh0dtlPyj8GrQc20M=; b=bIAhNZRF7BOLXIQG0SNohkfj+qRs5toRW40MVGVhGAfzvEoR+ksneO3mHEyqVTI8xM LO/QIuzzWa267eYpYE6ICQYQs4YcJyfpcwtHE4JtqIYIWMiddAX2tj6GXYK5RC/DGvba SE++MM4a4Yb+pfmhoL6ypKmWPHeJDVca5JCasQenXza7z4Dx4a9ZbRacHBN3yS679hGz GpFxqa3S8LSHlflMyk62aRc8aPa6N7ddnSngreogpj18lA7rq7dQw5ObpY0MT9tqlC1J kO3CP+UomRbe9WV6JsSQbwBQ+D2O+rLc7aLjpDgg9Jv6LPCc0WEiSt2U7cGT/3ho6kci TtBw== X-Gm-Message-State: AOJu0Ywa+oo77N3RDC1B+ruQFjVG+2SmX8lIgS52I9KSGkNqxawTfH7v b8ZC2L1RJjI+tAsDg79X20r2jCIFoghQP2V+ZHr3yHLPZWhOaajDVwioe0myq2WlI8okzC0GGti g/nbdIXpkxsHXxJTCWFQotyt+W5rxfKs7dEY7u9/ANZlF3ahdLty5Uhly X-Gm-Gg: AZuq6aJWb2qcgdo04yDomEymcsD0vyoNCwzyXg7/8oIVosWW5Ck+Oz13opO9SpneL5F I1KFpyW17Pn/D6aeRcDf3S3j0UaCsrSjSBeA01EicNuff7tO+BW3i8C3ztJ7ToK+QM4v6vwEbcq 0QF5rHtvjX6tQk5pxR0f6CTvBsF5oC7LfVuJRecNog47lXqrCjhTJfgU6DkHGL+DoKX4vcTDVaS +z8zxM3+H0qXI4bcUKqO5zosDUiiZuDzV0O0ARb25PXWUs57atHX93PRRetYUX3oJeMUjUAT/BB lVB6K79bQyVD0zEStyQeprY9G7FyTMI09OQNglaL2268L9OaNz9OkCpEp/y67vc07g1b/rKK83D NU79VdYmTNn2m/psZRqoe4ef/FIMGzUX1fVLiGj1Q4TENfqi1RVR2jcd+3ssZEF53IqY4g0SBE6 Y3X0eN X-Received: by 2002:a5d:5f82:0:b0:437:6aca:d1c6 with SMTP id ffacd0b85a97d-43958e3bed1mr3347703f8f.33.1771421263921; Wed, 18 Feb 2026 05:27:43 -0800 (PST) X-Received: by 2002:a5d:5f82:0:b0:437:6aca:d1c6 with SMTP id ffacd0b85a97d-43958e3bed1mr3347644f8f.33.1771421263180; Wed, 18 Feb 2026 05:27:43 -0800 (PST) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v4 24/24] iotests/308: Add multi-threading sanity test Date: Wed, 18 Feb 2026 14:26:33 +0100 Message-ID: <20260218132633.29748-25-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260218132633.29748-1-hreitz@redhat.com> References: <20260218132633.29748-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1771421699970154100 Content-Type: text/plain; charset="utf-8" Run qemu-img bench on a simple multi-threaded FUSE export to test that it works. Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek Reviewed-by: Kevin Wolf --- tests/qemu-iotests/308 | 51 ++++++++++++++++++++++++++++++++++ tests/qemu-iotests/308.out | 56 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308 index a83c6fc01f..f4a06a522e 100755 --- a/tests/qemu-iotests/308 +++ b/tests/qemu-iotests/308 @@ -441,6 +441,57 @@ $QEMU_IO -c 'read -P 0 0 64M' "$TEST_IMG" | _filter_qe= mu_io =20 _cleanup_test_img =20 +echo +echo '=3D=3D=3D Multi-threading =3D=3D=3D' + +# Just set up a null block device, export it (with multi-threading), and r= un +# qemu-img bench on it (to get parallel requests) + +_launch_qemu +_send_qemu_cmd $QEMU_HANDLE \ + "{'execute': 'qmp_capabilities'}" \ + 'return' + +_send_qemu_cmd $QEMU_HANDLE \ + "{'execute': 'blockdev-add', + 'arguments': { + 'driver': 'null-co', + 'node-name': 'null' + } }" \ + 'return' + +for id in iothread{0,1,2,3}; do + _send_qemu_cmd $QEMU_HANDLE \ + "{'execute': 'object-add', + 'arguments': { + 'qom-type': 'iothread', + 'id': '$id' + } }" \ + 'return' +done + +echo + +iothreads=3D"['iothread0', 'iothread1', 'iothread2', 'iothread3']" +fuse_export_add \ + 'export' \ + "'mountpoint': '$EXT_MP', 'iothread': $iothreads" \ + 'return' \ + 'null' + +echo +$QEMU_IMG bench -f raw "$EXT_MP" | + sed -e 's/[0-9.]\+ seconds/X.XXX seconds/' +echo + +fuse_export_del 'export' + +_send_qemu_cmd $QEMU_HANDLE \ + "{'execute': 'quit'}" \ + 'return' + +wait=3Dyes _cleanup_qemu + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out index ebeaf64b48..580cc94e92 100644 --- a/tests/qemu-iotests/308.out +++ b/tests/qemu-iotests/308.out @@ -217,4 +217,60 @@ read 67108864/67108864 bytes at offset 0 {"return": {}} read 67108864/67108864 bytes at offset 0 64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=3D=3D=3D Multi-threading =3D=3D=3D +{'execute': 'qmp_capabilities'} +{"return": {}} +{'execute': 'blockdev-add', + 'arguments': { + 'driver': 'null-co', + 'node-name': 'null' + } } +{"return": {}} +{'execute': 'object-add', + 'arguments': { + 'qom-type': 'iothread', + 'id': 'iothread0' + } } +{"return": {}} +{'execute': 'object-add', + 'arguments': { + 'qom-type': 'iothread', + 'id': 'iothread1' + } } +{"return": {}} +{'execute': 'object-add', + 'arguments': { + 'qom-type': 'iothread', + 'id': 'iothread2' + } } +{"return": {}} +{'execute': 'object-add', + 'arguments': { + 'qom-type': 'iothread', + 'id': 'iothread3' + } } +{"return": {}} + +{'execute': 'block-export-add', + 'arguments': { + 'type': 'fuse', + 'id': 'export', + 'node-name': 'null', + 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'iothread': ['iothre= ad0', 'iothread1', 'iothread2', 'iothread3'] + } } +{"return": {}} + +Sending 75000 read requests, 4096 bytes each, 64 in parallel (starting at = offset 0, step size 4096) +Run completed in X.XXX seconds. + +{'execute': 'block-export-del', + 'arguments': { + 'id': 'export' + } } +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "BLOCK_EXPORT_DELETED", "data": {"id": "export"}} +{'execute': 'quit'} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} +{"return": {}} *** done --=20 2.53.0